X-Git-Url: https://git.openstreetmap.org./rails.git/blobdiff_plain/aa78da82fe9a30dfa77e2d503701787aafc6cf55..f0c52e8baa95537dfbc12153ebae5d140e7803c6:/vendor/assets/iD/iD.js?ds=inline diff --git a/vendor/assets/iD/iD.js b/vendor/assets/iD/iD.js index 5c78af379..d25b3398b 100644 --- a/vendor/assets/iD/iD.js +++ b/vendor/assets/iD/iD.js @@ -21,6 +21,10 @@ return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); @@ -457,6 +461,7 @@ [69216, 69247], [126064, 126143], [126464, 126719] + // Mathematical Alphabetic symbols https://www.unicode.org/charts/PDF/U1EE00.pdf ]; function isArabic(char) { if (char.length > 1) { @@ -3114,19 +3119,19 @@ all: function() { return this._all(this.data, []); }, - search: function(bbox) { + search: function(bbox2) { var node = this.data, result = [], toBBox = this.toBBox; - if (!intersects(bbox, node)) + if (!intersects(bbox2, node)) return result; var nodesToSearch = [], i2, len, child, childBBox; while (node) { for (i2 = 0, len = node.children.length; i2 < len; i2++) { child = node.children[i2]; childBBox = node.leaf ? toBBox(child) : child; - if (intersects(bbox, childBBox)) { + if (intersects(bbox2, childBBox)) { if (node.leaf) result.push(child); - else if (contains(bbox, childBBox)) + else if (contains(bbox2, childBBox)) this._all(child, result); else nodesToSearch.push(child); @@ -3136,17 +3141,17 @@ } return result; }, - collides: function(bbox) { + collides: function(bbox2) { var node = this.data, toBBox = this.toBBox; - if (!intersects(bbox, node)) + if (!intersects(bbox2, node)) return false; var nodesToSearch = [], i2, len, child, childBBox; while (node) { for (i2 = 0, len = node.children.length; i2 < len; i2++) { child = node.children[i2]; childBBox = node.leaf ? toBBox(child) : child; - if (intersects(bbox, childBBox)) { - if (node.leaf || contains(bbox, childBBox)) + if (intersects(bbox2, childBBox)) { + if (node.leaf || contains(bbox2, childBBox)) return true; nodesToSearch.push(child); } @@ -3191,7 +3196,7 @@ remove: function(item, equalsFn) { if (!item) return this; - var node = this.data, bbox = this.toBBox(item), path = [], indexes = [], i2, parent, index, goingUp; + var node = this.data, bbox2 = this.toBBox(item), path = [], indexes = [], i2, parent, index, goingUp; while (node || path.length) { if (!node) { node = path.pop(); @@ -3208,7 +3213,7 @@ return this; } } - if (!goingUp && !node.leaf && contains(node, bbox)) { + if (!goingUp && !node.leaf && contains(node, bbox2)) { path.push(node); indexes.push(i2); i2 = 0; @@ -3273,7 +3278,7 @@ calcBBox(node, this.toBBox); return node; }, - _chooseSubtree: function(bbox, node, level, path) { + _chooseSubtree: function(bbox2, node, level, path) { var i2, len, child, targetNode, area, enlargement, minArea, minEnlargement; while (true) { path.push(node); @@ -3283,7 +3288,7 @@ for (i2 = 0, len = node.children.length; i2 < len; i2++) { child = node.children[i2]; area = bboxArea(child); - enlargement = enlargedArea(bbox, child) - area; + enlargement = enlargedArea(bbox2, child) - area; if (enlargement < minEnlargement) { minEnlargement = enlargement; minArea = area < minArea ? area : minArea; @@ -3300,10 +3305,10 @@ return node; }, _insert: function(item, level, isNode) { - var toBBox = this.toBBox, bbox = isNode ? item : toBBox(item), insertPath = []; - var node = this._chooseSubtree(bbox, this.data, level, insertPath); + var toBBox = this.toBBox, bbox2 = isNode ? item : toBBox(item), insertPath = []; + var node = this._chooseSubtree(bbox2, this.data, level, insertPath); node.children.push(item); - extend2(node, bbox); + extend2(node, bbox2); while (level >= 0) { if (insertPath[level].children.length > this._maxEntries) { this._split(insertPath, level); @@ -3311,8 +3316,9 @@ } else break; } - this._adjustParentBBoxes(bbox, insertPath, level); + this._adjustParentBBoxes(bbox2, insertPath, level); }, + // split overflowed node into two _split: function(insertPath, level) { var node = insertPath[level], M = node.children.length, m = this._minEntries; this._chooseSplitAxis(node, m, M); @@ -3354,11 +3360,13 @@ } return index; }, + // sorts node children by the best axis for split _chooseSplitAxis: function(node, m, M) { var compareMinX = node.leaf ? this.compareMinX : compareNodeMinX, compareMinY = node.leaf ? this.compareMinY : compareNodeMinY, xMargin = this._allDistMargin(node, m, M, compareMinX), yMargin = this._allDistMargin(node, m, M, compareMinY); if (xMargin < yMargin) node.children.sort(compareMinX); }, + // total margin of all possible split distributions where each node is at least m full _allDistMargin: function(node, m, M, compare) { node.children.sort(compare); var toBBox = this.toBBox, leftBBox = distBBox(node, 0, m, toBBox), rightBBox = distBBox(node, M - m, M, toBBox), margin = bboxMargin(leftBBox) + bboxMargin(rightBBox), i2, child; @@ -3374,9 +3382,9 @@ } return margin; }, - _adjustParentBBoxes: function(bbox, path, level) { + _adjustParentBBoxes: function(bbox2, path, level) { for (var i2 = level; i2 >= 0; i2--) { - extend2(path[i2], bbox); + extend2(path[i2], bbox2); } }, _condense: function(path) { @@ -3491,14 +3499,14 @@ module2.exports = lineclip2; lineclip2.polyline = lineclip2; lineclip2.polygon = polygonclip2; - function lineclip2(points, bbox, result) { - var len = points.length, codeA = bitCode2(points[0], bbox), part = [], i2, a, b, codeB, lastCode; + function lineclip2(points, bbox2, result) { + var len = points.length, codeA = bitCode2(points[0], bbox2), part = [], i2, a, b, codeB, lastCode; if (!result) result = []; for (i2 = 1; i2 < len; i2++) { a = points[i2 - 1]; b = points[i2]; - codeB = lastCode = bitCode2(b, bbox); + codeB = lastCode = bitCode2(b, bbox2); while (true) { if (!(codeA | codeB)) { part.push(a); @@ -3515,11 +3523,11 @@ } else if (codeA & codeB) { break; } else if (codeA) { - a = intersect2(a, b, codeA, bbox); - codeA = bitCode2(a, bbox); + a = intersect2(a, b, codeA, bbox2); + codeA = bitCode2(a, bbox2); } else { - b = intersect2(a, b, codeB, bbox); - codeB = bitCode2(b, bbox); + b = intersect2(a, b, codeB, bbox2); + codeB = bitCode2(b, bbox2); } } codeA = lastCode; @@ -3528,17 +3536,17 @@ result.push(part); return result; } - function polygonclip2(points, bbox) { + function polygonclip2(points, bbox2) { var result, edge, prev, prevInside, i2, p, inside; for (edge = 1; edge <= 8; edge *= 2) { result = []; prev = points[points.length - 1]; - prevInside = !(bitCode2(prev, bbox) & edge); + prevInside = !(bitCode2(prev, bbox2) & edge); for (i2 = 0; i2 < points.length; i2++) { p = points[i2]; - inside = !(bitCode2(p, bbox) & edge); + inside = !(bitCode2(p, bbox2) & edge); if (inside !== prevInside) - result.push(intersect2(prev, p, edge, bbox)); + result.push(intersect2(prev, p, edge, bbox2)); if (inside) result.push(p); prev = p; @@ -3550,18 +3558,30 @@ } return result; } - function intersect2(a, b, edge, bbox) { - return edge & 8 ? [a[0] + (b[0] - a[0]) * (bbox[3] - a[1]) / (b[1] - a[1]), bbox[3]] : edge & 4 ? [a[0] + (b[0] - a[0]) * (bbox[1] - a[1]) / (b[1] - a[1]), bbox[1]] : edge & 2 ? [bbox[2], a[1] + (b[1] - a[1]) * (bbox[2] - a[0]) / (b[0] - a[0])] : edge & 1 ? [bbox[0], a[1] + (b[1] - a[1]) * (bbox[0] - a[0]) / (b[0] - a[0])] : null; + function intersect2(a, b, edge, bbox2) { + return edge & 8 ? [a[0] + (b[0] - a[0]) * (bbox2[3] - a[1]) / (b[1] - a[1]), bbox2[3]] : ( + // top + edge & 4 ? [a[0] + (b[0] - a[0]) * (bbox2[1] - a[1]) / (b[1] - a[1]), bbox2[1]] : ( + // bottom + edge & 2 ? [bbox2[2], a[1] + (b[1] - a[1]) * (bbox2[2] - a[0]) / (b[0] - a[0])] : ( + // right + edge & 1 ? [bbox2[0], a[1] + (b[1] - a[1]) * (bbox2[0] - a[0]) / (b[0] - a[0])] : ( + // left + null + ) + ) + ) + ); } - function bitCode2(p, bbox) { + function bitCode2(p, bbox2) { var code = 0; - if (p[0] < bbox[0]) + if (p[0] < bbox2[0]) code |= 1; - else if (p[0] > bbox[2]) + else if (p[0] > bbox2[2]) code |= 2; - if (p[1] < bbox[1]) + if (p[1] < bbox2[1]) code |= 4; - else if (p[1] > bbox[3]) + else if (p[1] > bbox2[3]) code |= 8; return code; } @@ -3579,6 +3599,8 @@ var bboxes = []; for (var i2 = 0; i2 < data.features.length; i2++) { var feature3 = data.features[i2]; + if (!feature3.geometry) + continue; var coords = feature3.geometry.coordinates; if (feature3.geometry.type === "Polygon") { bboxes.push(treeItem(coords, feature3.properties)); @@ -3607,16 +3629,16 @@ return multi && output.length ? output : null; } query.tree = tree; - query.bbox = function queryBBox(bbox) { + query.bbox = function queryBBox(bbox2) { var output = []; var result = tree.search({ - minX: bbox[0], - minY: bbox[1], - maxX: bbox[2], - maxY: bbox[3] + minX: bbox2[0], + minY: bbox2[1], + maxX: bbox2[2], + maxY: bbox2[3] }); for (var i3 = 0; i3 < result.length; i3++) { - if (polygonIntersectsBBox(result[i3].coords, bbox)) { + if (polygonIntersectsBBox(result[i3].coords, bbox2)) { output.push(result[i3].props); } } @@ -3624,15 +3646,15 @@ }; return query; } - function polygonIntersectsBBox(polygon2, bbox) { + function polygonIntersectsBBox(polygon2, bbox2) { var bboxCenter = [ - (bbox[0] + bbox[2]) / 2, - (bbox[1] + bbox[3]) / 2 + (bbox2[0] + bbox2[2]) / 2, + (bbox2[1] + bbox2[3]) / 2 ]; if (insidePolygon(polygon2, bboxCenter)) return true; for (var i2 = 0; i2 < polygon2.length; i2++) { - if (lineclip2(polygon2[i2], bbox).length > 0) + if (lineclip2(polygon2[i2], bbox2).length > 0) return true; } return false; @@ -3975,16 +3997,19 @@ _defineProperties(Constructor, staticProps); return Constructor; } - var Node = function() { - function Node2(key, data) { - this.next = null; - this.key = key; - this.data = data; - this.left = null; - this.right = null; - } - return Node2; - }(); + var Node = ( + /** @class */ + function() { + function Node2(key, data) { + this.next = null; + this.key = key; + this.data = data; + this.left = null; + this.right = null; + } + return Node2; + }() + ); function DEFAULT_COMPARE(a, b) { return a > b ? 1 : a < b ? -1 : 0; } @@ -4074,7 +4099,7 @@ right }; } - function merge3(left, right, comparator) { + function merge2(left, right, comparator) { if (right === null) return left; if (left === null) @@ -4093,368 +4118,371 @@ printRow(root3.right, indent2, true, out, printNode); } } - var Tree = function() { - function Tree2(comparator) { - if (comparator === void 0) { - comparator = DEFAULT_COMPARE; - } - this._root = null; - this._size = 0; - this._comparator = comparator; - } - Tree2.prototype.insert = function(key, data) { - this._size++; - return this._root = insert(key, data, this._root, this._comparator); - }; - Tree2.prototype.add = function(key, data) { - var node = new Node(key, data); - if (this._root === null) { - node.left = node.right = null; - this._size++; - this._root = node; - } - var comparator = this._comparator; - var t = splay(key, this._root, comparator); - var cmp2 = comparator(key, t.key); - if (cmp2 === 0) - this._root = t; - else { - if (cmp2 < 0) { - node.left = t.left; - node.right = t; - t.left = null; - } else if (cmp2 > 0) { - node.right = t.right; - node.left = t; - t.right = null; + var Tree = ( + /** @class */ + function() { + function Tree2(comparator) { + if (comparator === void 0) { + comparator = DEFAULT_COMPARE; } - this._size++; - this._root = node; + this._root = null; + this._size = 0; + this._comparator = comparator; } - return this._root; - }; - Tree2.prototype.remove = function(key) { - this._root = this._remove(key, this._root, this._comparator); - }; - Tree2.prototype._remove = function(i2, t, comparator) { - var x; - if (t === null) - return null; - t = splay(i2, t, comparator); - var cmp2 = comparator(i2, t.key); - if (cmp2 === 0) { - if (t.left === null) { - x = t.right; - } else { - x = splay(i2, t.left, comparator); - x.right = t.right; - } - this._size--; - return x; - } - return t; - }; - Tree2.prototype.pop = function() { - var node = this._root; - if (node) { - while (node.left) { - node = node.left; + Tree2.prototype.insert = function(key, data) { + this._size++; + return this._root = insert(key, data, this._root, this._comparator); + }; + Tree2.prototype.add = function(key, data) { + var node = new Node(key, data); + if (this._root === null) { + node.left = node.right = null; + this._size++; + this._root = node; } - this._root = splay(node.key, this._root, this._comparator); - this._root = this._remove(node.key, this._root, this._comparator); - return { - key: node.key, - data: node.data - }; - } - return null; - }; - Tree2.prototype.findStatic = function(key) { - var current = this._root; - var compare = this._comparator; - while (current) { - var cmp2 = compare(key, current.key); + var comparator = this._comparator; + var t = splay(key, this._root, comparator); + var cmp2 = comparator(key, t.key); if (cmp2 === 0) - return current; - else if (cmp2 < 0) - current = current.left; - else - current = current.right; - } - return null; - }; - Tree2.prototype.find = function(key) { - if (this._root) { - this._root = splay(key, this._root, this._comparator); - if (this._comparator(key, this._root.key) !== 0) + this._root = t; + else { + if (cmp2 < 0) { + node.left = t.left; + node.right = t; + t.left = null; + } else if (cmp2 > 0) { + node.right = t.right; + node.left = t; + t.right = null; + } + this._size++; + this._root = node; + } + return this._root; + }; + Tree2.prototype.remove = function(key) { + this._root = this._remove(key, this._root, this._comparator); + }; + Tree2.prototype._remove = function(i2, t, comparator) { + var x; + if (t === null) return null; - } - return this._root; - }; - Tree2.prototype.contains = function(key) { - var current = this._root; - var compare = this._comparator; - while (current) { - var cmp2 = compare(key, current.key); - if (cmp2 === 0) - return true; - else if (cmp2 < 0) - current = current.left; - else - current = current.right; - } - return false; - }; - Tree2.prototype.forEach = function(visitor, ctx) { - var current = this._root; - var Q = []; - var done = false; - while (!done) { - if (current !== null) { - Q.push(current); - current = current.left; - } else { - if (Q.length !== 0) { - current = Q.pop(); - visitor.call(ctx, current); - current = current.right; - } else - done = true; + t = splay(i2, t, comparator); + var cmp2 = comparator(i2, t.key); + if (cmp2 === 0) { + if (t.left === null) { + x = t.right; + } else { + x = splay(i2, t.left, comparator); + x.right = t.right; + } + this._size--; + return x; } - } - return this; - }; - Tree2.prototype.range = function(low, high, fn, ctx) { - var Q = []; - var compare = this._comparator; - var node = this._root; - var cmp2; - while (Q.length !== 0 || node) { + return t; + }; + Tree2.prototype.pop = function() { + var node = this._root; if (node) { - Q.push(node); - node = node.left; - } else { - node = Q.pop(); - cmp2 = compare(node.key, high); - if (cmp2 > 0) { - break; - } else if (compare(node.key, low) >= 0) { - if (fn.call(ctx, node)) - return this; + while (node.left) { + node = node.left; } - node = node.right; + this._root = splay(node.key, this._root, this._comparator); + this._root = this._remove(node.key, this._root, this._comparator); + return { + key: node.key, + data: node.data + }; } - } - return this; - }; - Tree2.prototype.keys = function() { - var keys = []; - this.forEach(function(_a) { - var key = _a.key; - return keys.push(key); - }); - return keys; - }; - Tree2.prototype.values = function() { - var values = []; - this.forEach(function(_a) { - var data = _a.data; - return values.push(data); - }); - return values; - }; - Tree2.prototype.min = function() { - if (this._root) - return this.minNode(this._root).key; - return null; - }; - Tree2.prototype.max = function() { - if (this._root) - return this.maxNode(this._root).key; - return null; - }; - Tree2.prototype.minNode = function(t) { - if (t === void 0) { - t = this._root; - } - if (t) - while (t.left) { - t = t.left; + return null; + }; + Tree2.prototype.findStatic = function(key) { + var current = this._root; + var compare = this._comparator; + while (current) { + var cmp2 = compare(key, current.key); + if (cmp2 === 0) + return current; + else if (cmp2 < 0) + current = current.left; + else + current = current.right; } - return t; - }; - Tree2.prototype.maxNode = function(t) { - if (t === void 0) { - t = this._root; - } - if (t) - while (t.right) { - t = t.right; + return null; + }; + Tree2.prototype.find = function(key) { + if (this._root) { + this._root = splay(key, this._root, this._comparator); + if (this._comparator(key, this._root.key) !== 0) + return null; } - return t; - }; - Tree2.prototype.at = function(index2) { - var current = this._root; - var done = false; - var i2 = 0; - var Q = []; - while (!done) { - if (current) { - Q.push(current); - current = current.left; - } else { - if (Q.length > 0) { - current = Q.pop(); - if (i2 === index2) - return current; - i2++; + return this._root; + }; + Tree2.prototype.contains = function(key) { + var current = this._root; + var compare = this._comparator; + while (current) { + var cmp2 = compare(key, current.key); + if (cmp2 === 0) + return true; + else if (cmp2 < 0) + current = current.left; + else current = current.right; - } else - done = true; } - } - return null; - }; - Tree2.prototype.next = function(d) { - var root3 = this._root; - var successor = null; - if (d.right) { - successor = d.right; - while (successor.left) { - successor = successor.left; + return false; + }; + Tree2.prototype.forEach = function(visitor, ctx) { + var current = this._root; + var Q = []; + var done = false; + while (!done) { + if (current !== null) { + Q.push(current); + current = current.left; + } else { + if (Q.length !== 0) { + current = Q.pop(); + visitor.call(ctx, current); + current = current.right; + } else + done = true; + } + } + return this; + }; + Tree2.prototype.range = function(low, high, fn, ctx) { + var Q = []; + var compare = this._comparator; + var node = this._root; + var cmp2; + while (Q.length !== 0 || node) { + if (node) { + Q.push(node); + node = node.left; + } else { + node = Q.pop(); + cmp2 = compare(node.key, high); + if (cmp2 > 0) { + break; + } else if (compare(node.key, low) >= 0) { + if (fn.call(ctx, node)) + return this; + } + node = node.right; + } + } + return this; + }; + Tree2.prototype.keys = function() { + var keys2 = []; + this.forEach(function(_a) { + var key = _a.key; + return keys2.push(key); + }); + return keys2; + }; + Tree2.prototype.values = function() { + var values = []; + this.forEach(function(_a) { + var data = _a.data; + return values.push(data); + }); + return values; + }; + Tree2.prototype.min = function() { + if (this._root) + return this.minNode(this._root).key; + return null; + }; + Tree2.prototype.max = function() { + if (this._root) + return this.maxNode(this._root).key; + return null; + }; + Tree2.prototype.minNode = function(t) { + if (t === void 0) { + t = this._root; + } + if (t) + while (t.left) { + t = t.left; + } + return t; + }; + Tree2.prototype.maxNode = function(t) { + if (t === void 0) { + t = this._root; + } + if (t) + while (t.right) { + t = t.right; + } + return t; + }; + Tree2.prototype.at = function(index2) { + var current = this._root; + var done = false; + var i2 = 0; + var Q = []; + while (!done) { + if (current) { + Q.push(current); + current = current.left; + } else { + if (Q.length > 0) { + current = Q.pop(); + if (i2 === index2) + return current; + i2++; + current = current.right; + } else + done = true; + } + } + return null; + }; + Tree2.prototype.next = function(d) { + var root3 = this._root; + var successor = null; + if (d.right) { + successor = d.right; + while (successor.left) { + successor = successor.left; + } + return successor; + } + var comparator = this._comparator; + while (root3) { + var cmp2 = comparator(d.key, root3.key); + if (cmp2 === 0) + break; + else if (cmp2 < 0) { + successor = root3; + root3 = root3.left; + } else + root3 = root3.right; } return successor; - } - var comparator = this._comparator; - while (root3) { - var cmp2 = comparator(d.key, root3.key); - if (cmp2 === 0) - break; - else if (cmp2 < 0) { - successor = root3; - root3 = root3.left; - } else - root3 = root3.right; - } - return successor; - }; - Tree2.prototype.prev = function(d) { - var root3 = this._root; - var predecessor = null; - if (d.left !== null) { - predecessor = d.left; - while (predecessor.right) { - predecessor = predecessor.right; + }; + Tree2.prototype.prev = function(d) { + var root3 = this._root; + var predecessor = null; + if (d.left !== null) { + predecessor = d.left; + while (predecessor.right) { + predecessor = predecessor.right; + } + return predecessor; + } + var comparator = this._comparator; + while (root3) { + var cmp2 = comparator(d.key, root3.key); + if (cmp2 === 0) + break; + else if (cmp2 < 0) + root3 = root3.left; + else { + predecessor = root3; + root3 = root3.right; + } } return predecessor; - } - var comparator = this._comparator; - while (root3) { - var cmp2 = comparator(d.key, root3.key); - if (cmp2 === 0) - break; - else if (cmp2 < 0) - root3 = root3.left; - else { - predecessor = root3; - root3 = root3.right; + }; + Tree2.prototype.clear = function() { + this._root = null; + this._size = 0; + return this; + }; + Tree2.prototype.toList = function() { + return toList(this._root); + }; + Tree2.prototype.load = function(keys2, values, presort) { + if (values === void 0) { + values = []; } - } - return predecessor; - }; - Tree2.prototype.clear = function() { - this._root = null; - this._size = 0; - return this; - }; - Tree2.prototype.toList = function() { - return toList(this._root); - }; - Tree2.prototype.load = function(keys, values, presort) { - if (values === void 0) { - values = []; - } - if (presort === void 0) { - presort = false; - } - var size = keys.length; - var comparator = this._comparator; - if (presort) - sort(keys, values, 0, size - 1, comparator); - if (this._root === null) { - this._root = loadRecursive(keys, values, 0, size); - this._size = size; - } else { - var mergedList = mergeLists(this.toList(), createList(keys, values), comparator); - size = this._size + size; - this._root = sortedListToBST({ - head: mergedList - }, 0, size); - } - return this; - }; - Tree2.prototype.isEmpty = function() { - return this._root === null; - }; - Object.defineProperty(Tree2.prototype, "size", { - get: function get4() { - return this._size; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Tree2.prototype, "root", { - get: function get4() { - return this._root; - }, - enumerable: true, - configurable: true - }); - Tree2.prototype.toString = function(printNode) { - if (printNode === void 0) { - printNode = function printNode2(n2) { - return String(n2.key); - }; - } - var out = []; - printRow(this._root, "", true, function(v) { - return out.push(v); - }, printNode); - return out.join(""); - }; - Tree2.prototype.update = function(key, newKey, newData) { - var comparator = this._comparator; - var _a = split(key, this._root, comparator), left = _a.left, right = _a.right; - if (comparator(key, newKey) < 0) { - right = insert(newKey, newData, right, comparator); - } else { - left = insert(newKey, newData, left, comparator); - } - this._root = merge3(left, right, comparator); - }; - Tree2.prototype.split = function(key) { - return split(key, this._root, this._comparator); - }; - return Tree2; - }(); - function loadRecursive(keys, values, start2, end) { + if (presort === void 0) { + presort = false; + } + var size = keys2.length; + var comparator = this._comparator; + if (presort) + sort(keys2, values, 0, size - 1, comparator); + if (this._root === null) { + this._root = loadRecursive(keys2, values, 0, size); + this._size = size; + } else { + var mergedList = mergeLists(this.toList(), createList(keys2, values), comparator); + size = this._size + size; + this._root = sortedListToBST({ + head: mergedList + }, 0, size); + } + return this; + }; + Tree2.prototype.isEmpty = function() { + return this._root === null; + }; + Object.defineProperty(Tree2.prototype, "size", { + get: function get4() { + return this._size; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Tree2.prototype, "root", { + get: function get4() { + return this._root; + }, + enumerable: true, + configurable: true + }); + Tree2.prototype.toString = function(printNode) { + if (printNode === void 0) { + printNode = function printNode2(n2) { + return String(n2.key); + }; + } + var out = []; + printRow(this._root, "", true, function(v) { + return out.push(v); + }, printNode); + return out.join(""); + }; + Tree2.prototype.update = function(key, newKey, newData) { + var comparator = this._comparator; + var _a = split(key, this._root, comparator), left = _a.left, right = _a.right; + if (comparator(key, newKey) < 0) { + right = insert(newKey, newData, right, comparator); + } else { + left = insert(newKey, newData, left, comparator); + } + this._root = merge2(left, right, comparator); + }; + Tree2.prototype.split = function(key) { + return split(key, this._root, this._comparator); + }; + return Tree2; + }() + ); + function loadRecursive(keys2, values, start2, end) { var size = end - start2; if (size > 0) { var middle = start2 + Math.floor(size / 2); - var key = keys[middle]; + var key = keys2[middle]; var data = values[middle]; var node = new Node(key, data); - node.left = loadRecursive(keys, values, start2, middle); - node.right = loadRecursive(keys, values, middle + 1, end); + node.left = loadRecursive(keys2, values, start2, middle); + node.right = loadRecursive(keys2, values, middle + 1, end); return node; } return null; } - function createList(keys, values) { + function createList(keys2, values) { var head = new Node(null, null); var p = head; - for (var i2 = 0; i2 < keys.length; i2++) { - p = p.next = new Node(keys[i2], values[i2]); + for (var i2 = 0; i2 < keys2.length; i2++) { + p = p.next = new Node(keys2[i2], values[i2]); } p.next = null; return head.next; @@ -4515,33 +4543,33 @@ } return head.next; } - function sort(keys, values, left, right, compare) { + function sort(keys2, values, left, right, compare) { if (left >= right) return; - var pivot = keys[left + right >> 1]; + var pivot = keys2[left + right >> 1]; var i2 = left - 1; var j2 = right + 1; while (true) { do { i2++; - } while (compare(keys[i2], pivot) < 0); + } while (compare(keys2[i2], pivot) < 0); do { j2--; - } while (compare(keys[j2], pivot) > 0); + } while (compare(keys2[j2], pivot) > 0); if (i2 >= j2) break; - var tmp = keys[i2]; - keys[i2] = keys[j2]; - keys[j2] = tmp; + var tmp = keys2[i2]; + keys2[i2] = keys2[j2]; + keys2[j2] = tmp; tmp = values[i2]; values[i2] = values[j2]; values[j2] = tmp; } - sort(keys, values, left, j2, compare); - sort(keys, values, j2 + 1, right, compare); + sort(keys2, values, left, j2, compare); + sort(keys2, values, j2 + 1, right, compare); } - var isInBbox = function isInBbox2(bbox, point) { - return bbox.ll.x <= point.x && point.x <= bbox.ur.x && bbox.ll.y <= point.y && point.y <= bbox.ur.y; + var isInBbox = function isInBbox2(bbox2, point2) { + return bbox2.ll.x <= point2.x && point2.x <= bbox2.ur.x && bbox2.ll.y <= point2.y && point2.y <= bbox2.ur.y; }; var getBboxOverlap = function getBboxOverlap2(b1, b2) { if (b2.ur.x < b1.ll.x || b1.ur.x < b2.ll.x || b2.ur.y < b1.ll.y || b1.ur.y < b2.ll.y) @@ -4714,6 +4742,7 @@ var SweepEvent = /* @__PURE__ */ function() { _createClass(SweepEvent2, null, [{ key: "compare", + // for ordering sweep events in the sweep event queue value: function compare(a, b) { var ptCmp = SweepEvent2.comparePoints(a.point, b.point); if (ptCmp !== 0) @@ -4724,6 +4753,7 @@ return a.isLeft ? 1 : -1; return Segment.compare(a.segment, b.segment); } + // for ordering points in sweep line order }, { key: "comparePoints", value: function comparePoints(aPt, bPt) { @@ -4737,14 +4767,15 @@ return 1; return 0; } + // Warning: 'point' input will be modified and re-used (for performance) }]); - function SweepEvent2(point, isLeft) { + function SweepEvent2(point2, isLeft) { _classCallCheck(this, SweepEvent2); - if (point.events === void 0) - point.events = [this]; + if (point2.events === void 0) + point2.events = [this]; else - point.events.push(this); - this.point = point; + point2.events.push(this); + this.point = point2; this.isLeft = isLeft; } _createClass(SweepEvent2, [{ @@ -4761,6 +4792,8 @@ } this.checkForConsuming(); } + /* Do a pass over our linked events and check to see if any pair + * of segments match, and should be consumed. */ }, { key: "checkForConsuming", value: function checkForConsuming() { @@ -4791,6 +4824,16 @@ } return events; } + /** + * Returns a comparator function for sorting linked events that will + * favor the event that will give us the smallest left-side angle. + * All ring construction starts as low as possible heading to the right, + * so by always turning left as sharp as possible we'll get polygons + * without uncessary loops & holes. + * + * The comparator function has a compute cache such that it avoids + * re-computing already-computed values. + */ }, { key: "getLeftmostComparator", value: function getLeftmostComparator(baseEvent) { @@ -4838,6 +4881,19 @@ var Segment = /* @__PURE__ */ function() { _createClass(Segment2, null, [{ key: "compare", + /* This compare() function is for ordering segments in the sweep + * line tree, and does so according to the following criteria: + * + * Consider the vertical line that lies an infinestimal step to the + * right of the right-more of the two left endpoints of the input + * segments. Imagine slowly moving a point up from negative infinity + * in the increasing y direction. Which of the two segments will that + * point intersect first? That segment comes 'before' the other one. + * + * If neither segment would be intersected by such a line, (if one + * or more of the segments are vertical) then the line to be considered + * is directly on the right-more of the two left inputs. + */ value: function compare(a, b) { var alx = a.leftSE.point.x; var blx = b.leftSE.point.x; @@ -4921,6 +4977,8 @@ return 1; return 0; } + /* Warning: a reference to ringWindings input will be stored, + * and possibly will be later modified */ }]); function Segment2(leftSE, rightSE, rings, windings) { _classCallCheck(this, Segment2); @@ -4936,6 +4994,7 @@ } _createClass(Segment2, [{ key: "replaceRightSE", + /* When a segment is split, the rightSE is replaced with a new sweep event */ value: function replaceRightSE(newRightSE) { this.rightSE = newRightSE; this.rightSE.segment = this; @@ -4944,7 +5003,7 @@ } }, { key: "bbox", - value: function bbox() { + value: function bbox2() { var y12 = this.leftSE.point.y; var y2 = this.rightSE.point.y; return { @@ -4958,6 +5017,7 @@ } }; } + /* A vector from the left point to the right */ }, { key: "vector", value: function vector() { @@ -4971,29 +5031,57 @@ value: function isAnEndpoint(pt) { return pt.x === this.leftSE.point.x && pt.y === this.leftSE.point.y || pt.x === this.rightSE.point.x && pt.y === this.rightSE.point.y; } + /* Compare this segment with a point. + * + * A point P is considered to be colinear to a segment if there + * exists a distance D such that if we travel along the segment + * from one * endpoint towards the other a distance D, we find + * ourselves at point P. + * + * Return value indicates: + * + * 1: point lies above the segment (to the left of vertical) + * 0: point is colinear to segment + * -1: point lies below the segment (to the right of vertical) + */ }, { key: "comparePoint", - value: function comparePoint(point) { - if (this.isAnEndpoint(point)) + value: function comparePoint(point2) { + if (this.isAnEndpoint(point2)) return 0; var lPt = this.leftSE.point; var rPt = this.rightSE.point; var v = this.vector(); if (lPt.x === rPt.x) { - if (point.x === lPt.x) + if (point2.x === lPt.x) return 0; - return point.x < lPt.x ? 1 : -1; + return point2.x < lPt.x ? 1 : -1; } - var yDist = (point.y - lPt.y) / v.y; + var yDist = (point2.y - lPt.y) / v.y; var xFromYDist = lPt.x + yDist * v.x; - if (point.x === xFromYDist) + if (point2.x === xFromYDist) return 0; - var xDist = (point.x - lPt.x) / v.x; + var xDist = (point2.x - lPt.x) / v.x; var yFromXDist = lPt.y + xDist * v.y; - if (point.y === yFromXDist) + if (point2.y === yFromXDist) return 0; - return point.y < yFromXDist ? -1 : 1; - } + return point2.y < yFromXDist ? -1 : 1; + } + /** + * Given another segment, returns the first non-trivial intersection + * between the two segments (in terms of sweep line ordering), if it exists. + * + * A 'non-trivial' intersection is one that will cause one or both of the + * segments to be split(). As such, 'trivial' vs. 'non-trivial' intersection: + * + * * endpoint of segA with endpoint of segB --> trivial + * * endpoint of segA with point along segB --> non-trivial + * * endpoint of segB with point along segA --> non-trivial + * * point along segA with point along segB --> non-trivial + * + * If no non-trivial intersection exists, return null + * Else, return null. + */ }, { key: "getIntersection", value: function getIntersection(other) { @@ -5044,13 +5132,25 @@ return null; return rounder.round(pt.x, pt.y); } + /** + * Split the given segment into multiple segments on the given points. + * * Each existing segment will retain its leftSE and a new rightSE will be + * generated for it. + * * A new segment will be generated which will adopt the original segment's + * rightSE, and a new leftSE will be generated for it. + * * If there are more than two points given to split on, new segments + * in the middle will be generated with new leftSE and rightSE's. + * * An array of the newly generated SweepEvents will be returned. + * + * Warning: input array of points is modified + */ }, { key: "split", - value: function split2(point) { + value: function split2(point2) { var newEvents = []; - var alreadyLinked = point.events !== void 0; - var newLeftSE = new SweepEvent(point, true); - var newRightSE = new SweepEvent(point, false); + var alreadyLinked = point2.events !== void 0; + var newLeftSE = new SweepEvent(point2, true); + var newRightSE = new SweepEvent(point2, false); var oldRightSE = this.rightSE; this.replaceRightSE(newRightSE); newEvents.push(newRightSE); @@ -5068,6 +5168,7 @@ } return newEvents; } + /* Swap which event is left and right */ }, { key: "swapEvents", value: function swapEvents() { @@ -5080,6 +5181,8 @@ this.windings[i2] *= -1; } } + /* Consume another segment. We take their rings under our wing + * and mark them as consumed. Use for perfectly overlapping segments */ }, { key: "consume", value: function consume(other) { @@ -5120,6 +5223,7 @@ consumee.leftSE.consumedBy = consumer.leftSE; consumee.rightSE.consumedBy = consumer.rightSE; } + /* The first segment previous segment chain that is in the result */ }, { key: "prevInResult", value: function prevInResult() { @@ -5200,6 +5304,7 @@ } return this._afterState; } + /* Is this segment part of the final result? */ }, { key: "isInResult", value: function isInResult() { @@ -5296,19 +5401,19 @@ if (typeof geomRing[i2][0] !== "number" || typeof geomRing[i2][1] !== "number") { throw new Error("Input geometry is not a valid Polygon or MultiPolygon"); } - var point = rounder.round(geomRing[i2][0], geomRing[i2][1]); - if (point.x === prevPoint.x && point.y === prevPoint.y) + var point2 = rounder.round(geomRing[i2][0], geomRing[i2][1]); + if (point2.x === prevPoint.x && point2.y === prevPoint.y) continue; - this.segments.push(Segment.fromRing(prevPoint, point, this)); - if (point.x < this.bbox.ll.x) - this.bbox.ll.x = point.x; - if (point.y < this.bbox.ll.y) - this.bbox.ll.y = point.y; - if (point.x > this.bbox.ur.x) - this.bbox.ur.x = point.x; - if (point.y > this.bbox.ur.y) - this.bbox.ur.y = point.y; - prevPoint = point; + this.segments.push(Segment.fromRing(prevPoint, point2, this)); + if (point2.x < this.bbox.ll.x) + this.bbox.ll.x = point2.x; + if (point2.y < this.bbox.ll.y) + this.bbox.ll.y = point2.y; + if (point2.x > this.bbox.ur.x) + this.bbox.ur.x = point2.x; + if (point2.y > this.bbox.ur.y) + this.bbox.ur.y = point2.y; + prevPoint = point2; } if (firstPoint.x !== prevPoint.x || firstPoint.y !== prevPoint.y) { this.segments.push(Segment.fromRing(prevPoint, firstPoint, this)); @@ -5429,6 +5534,8 @@ var RingOut = /* @__PURE__ */ function() { _createClass(RingOut2, null, [{ key: "factory", + /* Given the segments from the sweep line pass, compute & return a series + * of closed rings from all the segments marked to be part of the result */ value: function factory(allSegments) { var ringsOut = []; for (var i2 = 0, iMax = allSegments.length; i2 < iMax; i2++) { @@ -5540,6 +5647,7 @@ } return this._enclosingRing; } + /* Returns the ring that encloses this one, if any */ }, { key: "_calcEnclosingRing", value: function _calcEnclosingRing() { @@ -5755,6 +5863,8 @@ } return newEvents; } + /* Safely split a segment that is currently in the datastructures + * IE - a segment other than the one that is currently being processed. */ }, { key: "_splitSafely", value: function _splitSafely(seg, pt) { @@ -5778,8 +5888,8 @@ } _createClass(Operation2, [{ key: "run", - value: function run(type3, geom, moreGeoms) { - operation.type = type3; + value: function run(type2, geom, moreGeoms) { + operation.type = type2; rounder.reset(); var multipolys = [new MultiPolyIn(geom, true)]; for (var i2 = 0, iMax = moreGeoms.length; i2 < iMax; i2++) { @@ -5888,7 +5998,7 @@ "node_modules/geojson-precision/index.js"(exports2, module2) { (function() { function parse(t, coordinatePrecision, extrasPrecision) { - function point(p) { + function point2(p) { return p.map(function(e, index) { if (index < 2) { return 1 * e.toFixed(coordinatePrecision); @@ -5898,7 +6008,7 @@ }); } function multi(l) { - return l.map(point); + return l.map(point2); } function poly(p) { return p.map(multi); @@ -5912,7 +6022,7 @@ } switch (obj.type) { case "Point": - obj.coordinates = point(obj.coordinates); + obj.coordinates = point2(obj.coordinates); return obj; case "LineString": case "MultiPoint": @@ -5974,13 +6084,13 @@ // node_modules/@aitodotai/json-stringify-pretty-compact/index.js var require_json_stringify_pretty_compact = __commonJS({ "node_modules/@aitodotai/json-stringify-pretty-compact/index.js"(exports2, module2) { - function isObject2(obj) { + function isObject3(obj) { return typeof obj === "object" && obj !== null; } function forEach(obj, cb) { if (Array.isArray(obj)) { obj.forEach(cb); - } else if (isObject2(obj)) { + } else if (isObject3(obj)) { Object.keys(obj).forEach(function(key) { var val = obj[key]; cb(val, key); @@ -5989,9 +6099,9 @@ } function getTreeDepth(obj) { var depth = 0; - if (Array.isArray(obj) || isObject2(obj)) { + if (Array.isArray(obj) || isObject3(obj)) { forEach(obj, function(val) { - if (Array.isArray(val) || isObject2(val)) { + if (Array.isArray(val) || isObject3(val)) { var tmpDepth = getTreeDepth(val); if (tmpDepth > depth) { depth = tmpDepth; @@ -6030,7 +6140,7 @@ return prettified; } } - if (isObject2(obj2)) { + if (isObject3(obj2)) { var nextIndent = currentIndent + indent2; var items = []; var delimiters; @@ -6656,69 +6766,24 @@ } }); - // node_modules/fast-deep-equal/index.js - var require_fast_deep_equal = __commonJS({ - "node_modules/fast-deep-equal/index.js"(exports2, module2) { - "use strict"; - module2.exports = function equal(a, b) { - if (a === b) - return true; - if (a && b && typeof a == "object" && typeof b == "object") { - if (a.constructor !== b.constructor) - return false; - var length, i2, keys; - if (Array.isArray(a)) { - length = a.length; - if (length != b.length) - return false; - for (i2 = length; i2-- !== 0; ) - if (!equal(a[i2], b[i2])) - return false; - return true; - } - if (a.constructor === RegExp) - return a.source === b.source && a.flags === b.flags; - if (a.valueOf !== Object.prototype.valueOf) - return a.valueOf() === b.valueOf(); - if (a.toString !== Object.prototype.toString) - return a.toString() === b.toString(); - keys = Object.keys(a); - length = keys.length; - if (length !== Object.keys(b).length) - return false; - for (i2 = length; i2-- !== 0; ) - if (!Object.prototype.hasOwnProperty.call(b, keys[i2])) - return false; - for (i2 = length; i2-- !== 0; ) { - var key = keys[i2]; - if (!equal(a[key], b[key])) - return false; - } - return true; - } - return a !== a && b !== b; - }; - } - }); - // node_modules/lodash/lodash.js var require_lodash = __commonJS({ "node_modules/lodash/lodash.js"(exports2, module2) { (function() { var undefined2; var VERSION = "4.17.21"; - var LARGE_ARRAY_SIZE = 200; + var LARGE_ARRAY_SIZE2 = 200; var CORE_ERROR_TEXT = "Unsupported core-js use. Try https://npms.io/search?q=ponyfill.", FUNC_ERROR_TEXT3 = "Expected a function", INVALID_TEMPL_VAR_ERROR_TEXT = "Invalid `variable` option passed into `_.template`"; - var HASH_UNDEFINED = "__lodash_hash_undefined__"; + var HASH_UNDEFINED4 = "__lodash_hash_undefined__"; var MAX_MEMOIZE_SIZE = 500; var PLACEHOLDER = "__lodash_placeholder__"; var CLONE_DEEP_FLAG = 1, CLONE_FLAT_FLAG = 2, CLONE_SYMBOLS_FLAG = 4; - var COMPARE_PARTIAL_FLAG = 1, COMPARE_UNORDERED_FLAG = 2; + var COMPARE_PARTIAL_FLAG5 = 1, COMPARE_UNORDERED_FLAG3 = 2; var WRAP_BIND_FLAG = 1, WRAP_BIND_KEY_FLAG = 2, WRAP_CURRY_BOUND_FLAG = 4, WRAP_CURRY_FLAG = 8, WRAP_CURRY_RIGHT_FLAG = 16, WRAP_PARTIAL_FLAG = 32, WRAP_PARTIAL_RIGHT_FLAG = 64, WRAP_ARY_FLAG = 128, WRAP_REARG_FLAG = 256, WRAP_FLIP_FLAG = 512; var DEFAULT_TRUNC_LENGTH = 30, DEFAULT_TRUNC_OMISSION = "..."; var HOT_COUNT = 800, HOT_SPAN = 16; var LAZY_FILTER_FLAG = 1, LAZY_MAP_FLAG = 2, LAZY_WHILE_FLAG = 3; - var INFINITY2 = 1 / 0, MAX_SAFE_INTEGER = 9007199254740991, MAX_INTEGER = 17976931348623157e292, NAN2 = 0 / 0; + var INFINITY2 = 1 / 0, MAX_SAFE_INTEGER3 = 9007199254740991, MAX_INTEGER = 17976931348623157e292, NAN2 = 0 / 0; var MAX_ARRAY_LENGTH = 4294967295, MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1, HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1; var wrapFlags = [ ["ary", WRAP_ARY_FLAG], @@ -6731,13 +6796,13 @@ ["partialRight", WRAP_PARTIAL_RIGHT_FLAG], ["rearg", WRAP_REARG_FLAG] ]; - var argsTag = "[object Arguments]", arrayTag = "[object Array]", asyncTag = "[object AsyncFunction]", boolTag = "[object Boolean]", dateTag = "[object Date]", domExcTag = "[object DOMException]", errorTag = "[object Error]", funcTag = "[object Function]", genTag = "[object GeneratorFunction]", mapTag = "[object Map]", numberTag = "[object Number]", nullTag2 = "[object Null]", objectTag = "[object Object]", promiseTag = "[object Promise]", proxyTag = "[object Proxy]", regexpTag = "[object RegExp]", setTag = "[object Set]", stringTag = "[object String]", symbolTag2 = "[object Symbol]", undefinedTag2 = "[object Undefined]", weakMapTag = "[object WeakMap]", weakSetTag = "[object WeakSet]"; - var arrayBufferTag = "[object ArrayBuffer]", dataViewTag = "[object DataView]", float32Tag = "[object Float32Array]", float64Tag = "[object Float64Array]", int8Tag = "[object Int8Array]", int16Tag = "[object Int16Array]", int32Tag = "[object Int32Array]", uint8Tag = "[object Uint8Array]", uint8ClampedTag = "[object Uint8ClampedArray]", uint16Tag = "[object Uint16Array]", uint32Tag = "[object Uint32Array]"; + var argsTag4 = "[object Arguments]", arrayTag3 = "[object Array]", asyncTag2 = "[object AsyncFunction]", boolTag3 = "[object Boolean]", dateTag3 = "[object Date]", domExcTag = "[object DOMException]", errorTag3 = "[object Error]", funcTag3 = "[object Function]", genTag2 = "[object GeneratorFunction]", mapTag4 = "[object Map]", numberTag3 = "[object Number]", nullTag2 = "[object Null]", objectTag4 = "[object Object]", promiseTag2 = "[object Promise]", proxyTag2 = "[object Proxy]", regexpTag3 = "[object RegExp]", setTag4 = "[object Set]", stringTag3 = "[object String]", symbolTag3 = "[object Symbol]", undefinedTag2 = "[object Undefined]", weakMapTag3 = "[object WeakMap]", weakSetTag = "[object WeakSet]"; + var arrayBufferTag3 = "[object ArrayBuffer]", dataViewTag4 = "[object DataView]", float32Tag2 = "[object Float32Array]", float64Tag2 = "[object Float64Array]", int8Tag2 = "[object Int8Array]", int16Tag2 = "[object Int16Array]", int32Tag2 = "[object Int32Array]", uint8Tag2 = "[object Uint8Array]", uint8ClampedTag2 = "[object Uint8ClampedArray]", uint16Tag2 = "[object Uint16Array]", uint32Tag2 = "[object Uint32Array]"; var reEmptyStringLeading = /\b__p \+= '';/g, reEmptyStringMiddle = /\b(__p \+=) '' \+/g, reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g; var reEscapedHtml2 = /&(?:amp|lt|gt|quot|#39);/g, reUnescapedHtml2 = /[&<>"']/g, reHasEscapedHtml2 = RegExp(reEscapedHtml2.source), reHasUnescapedHtml2 = RegExp(reUnescapedHtml2.source); var reEscape = /<%-([\s\S]+?)%>/g, reEvaluate = /<%([\s\S]+?)%>/g, reInterpolate = /<%=([\s\S]+?)%>/g; var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, reIsPlainProp = /^\w*$/, rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; - var reRegExpChar = /[\\^$.*+?()[\]{}|]/g, reHasRegExpChar = RegExp(reRegExpChar.source); + var reRegExpChar2 = /[\\^$.*+?()[\]{}|]/g, reHasRegExpChar = RegExp(reRegExpChar2.source); var reTrimStart2 = /^\s+/; var reWhitespace2 = /\s/; var reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/, reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/, reSplitDetails = /,? & /; @@ -6748,9 +6813,9 @@ var reFlags = /\w*$/; var reIsBadHex2 = /^[-+]0x[0-9a-f]+$/i; var reIsBinary2 = /^0b[01]+$/i; - var reIsHostCtor = /^\[object .+?Constructor\]$/; + var reIsHostCtor2 = /^\[object .+?Constructor\]$/; var reIsOctal2 = /^0o[0-7]+$/i; - var reIsUint = /^(?:0|[1-9]\d*)$/; + var reIsUint2 = /^(?:0|[1-9]\d*)$/; var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g; var reNoMatch = /($^)/; var reUnescapedString = /['\n\r\u2028\u2029\\]/g; @@ -6805,13 +6870,14 @@ "setTimeout" ]; var templateCounter = -1; - var typedArrayTags = {}; - typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = typedArrayTags[uint32Tag] = true; - typedArrayTags[argsTag] = typedArrayTags[arrayTag] = typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = typedArrayTags[dataViewTag] = typedArrayTags[dateTag] = typedArrayTags[errorTag] = typedArrayTags[funcTag] = typedArrayTags[mapTag] = typedArrayTags[numberTag] = typedArrayTags[objectTag] = typedArrayTags[regexpTag] = typedArrayTags[setTag] = typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false; + var typedArrayTags2 = {}; + typedArrayTags2[float32Tag2] = typedArrayTags2[float64Tag2] = typedArrayTags2[int8Tag2] = typedArrayTags2[int16Tag2] = typedArrayTags2[int32Tag2] = typedArrayTags2[uint8Tag2] = typedArrayTags2[uint8ClampedTag2] = typedArrayTags2[uint16Tag2] = typedArrayTags2[uint32Tag2] = true; + typedArrayTags2[argsTag4] = typedArrayTags2[arrayTag3] = typedArrayTags2[arrayBufferTag3] = typedArrayTags2[boolTag3] = typedArrayTags2[dataViewTag4] = typedArrayTags2[dateTag3] = typedArrayTags2[errorTag3] = typedArrayTags2[funcTag3] = typedArrayTags2[mapTag4] = typedArrayTags2[numberTag3] = typedArrayTags2[objectTag4] = typedArrayTags2[regexpTag3] = typedArrayTags2[setTag4] = typedArrayTags2[stringTag3] = typedArrayTags2[weakMapTag3] = false; var cloneableTags = {}; - cloneableTags[argsTag] = cloneableTags[arrayTag] = cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] = cloneableTags[boolTag] = cloneableTags[dateTag] = cloneableTags[float32Tag] = cloneableTags[float64Tag] = cloneableTags[int8Tag] = cloneableTags[int16Tag] = cloneableTags[int32Tag] = cloneableTags[mapTag] = cloneableTags[numberTag] = cloneableTags[objectTag] = cloneableTags[regexpTag] = cloneableTags[setTag] = cloneableTags[stringTag] = cloneableTags[symbolTag2] = cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; - cloneableTags[errorTag] = cloneableTags[funcTag] = cloneableTags[weakMapTag] = false; + cloneableTags[argsTag4] = cloneableTags[arrayTag3] = cloneableTags[arrayBufferTag3] = cloneableTags[dataViewTag4] = cloneableTags[boolTag3] = cloneableTags[dateTag3] = cloneableTags[float32Tag2] = cloneableTags[float64Tag2] = cloneableTags[int8Tag2] = cloneableTags[int16Tag2] = cloneableTags[int32Tag2] = cloneableTags[mapTag4] = cloneableTags[numberTag3] = cloneableTags[objectTag4] = cloneableTags[regexpTag3] = cloneableTags[setTag4] = cloneableTags[stringTag3] = cloneableTags[symbolTag3] = cloneableTags[uint8Tag2] = cloneableTags[uint8ClampedTag2] = cloneableTags[uint16Tag2] = cloneableTags[uint32Tag2] = true; + cloneableTags[errorTag3] = cloneableTags[funcTag3] = cloneableTags[weakMapTag3] = false; var deburredLetters = { + // Latin-1 Supplement block. "\xC0": "A", "\xC1": "A", "\xC2": "A", @@ -6874,6 +6940,7 @@ "\xDE": "Th", "\xFE": "th", "\xDF": "ss", + // Latin Extended-A block. "\u0100": "A", "\u0102": "A", "\u0104": "A", @@ -7029,21 +7096,21 @@ var freeGlobal2 = typeof global == "object" && global && global.Object === Object && global; var freeSelf2 = typeof self == "object" && self && self.Object === Object && self; var root3 = freeGlobal2 || freeSelf2 || Function("return this")(); - var freeExports = typeof exports2 == "object" && exports2 && !exports2.nodeType && exports2; - var freeModule = freeExports && typeof module2 == "object" && module2 && !module2.nodeType && module2; - var moduleExports = freeModule && freeModule.exports === freeExports; - var freeProcess = moduleExports && freeGlobal2.process; - var nodeUtil = function() { + var freeExports3 = typeof exports2 == "object" && exports2 && !exports2.nodeType && exports2; + var freeModule3 = freeExports3 && typeof module2 == "object" && module2 && !module2.nodeType && module2; + var moduleExports3 = freeModule3 && freeModule3.exports === freeExports3; + var freeProcess2 = moduleExports3 && freeGlobal2.process; + var nodeUtil2 = function() { try { - var types = freeModule && freeModule.require && freeModule.require("util").types; + var types = freeModule3 && freeModule3.require && freeModule3.require("util").types; if (types) { return types; } - return freeProcess && freeProcess.binding && freeProcess.binding("util"); + return freeProcess2 && freeProcess2.binding && freeProcess2.binding("util"); } catch (e) { } }(); - var nodeIsArrayBuffer = nodeUtil && nodeUtil.isArrayBuffer, nodeIsDate = nodeUtil && nodeUtil.isDate, nodeIsMap = nodeUtil && nodeUtil.isMap, nodeIsRegExp = nodeUtil && nodeUtil.isRegExp, nodeIsSet = nodeUtil && nodeUtil.isSet, nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray; + var nodeIsArrayBuffer = nodeUtil2 && nodeUtil2.isArrayBuffer, nodeIsDate = nodeUtil2 && nodeUtil2.isDate, nodeIsMap = nodeUtil2 && nodeUtil2.isMap, nodeIsRegExp = nodeUtil2 && nodeUtil2.isRegExp, nodeIsSet = nodeUtil2 && nodeUtil2.isSet, nodeIsTypedArray2 = nodeUtil2 && nodeUtil2.isTypedArray; function apply(func, thisArg, args) { switch (args.length) { case 0: @@ -7092,7 +7159,7 @@ } return true; } - function arrayFilter(array2, predicate) { + function arrayFilter2(array2, predicate) { var index = -1, length = array2 == null ? 0 : array2.length, resIndex = 0, result = []; while (++index < length) { var value = array2[index]; @@ -7122,7 +7189,7 @@ } return result; } - function arrayPush(array2, values) { + function arrayPush2(array2, values) { var index = -1, length = values.length, offset = array2.length; while (++index < length) { array2[offset + index] = values[index]; @@ -7149,7 +7216,7 @@ } return accumulator; } - function arraySome(array2, predicate) { + function arraySome2(array2, predicate) { var index = -1, length = array2 == null ? 0 : array2.length; while (++index < length) { if (predicate(array2[index], index, array2)) { @@ -7237,7 +7304,7 @@ } return result; } - function baseTimes(n2, iteratee) { + function baseTimes2(n2, iteratee) { var index = -1, result = Array(n2); while (++index < n2) { result[index] = iteratee(index); @@ -7252,7 +7319,7 @@ function baseTrim2(string) { return string ? string.slice(0, trimmedEndIndex2(string) + 1).replace(reTrimStart2, "") : string; } - function baseUnary(func) { + function baseUnary2(func) { return function(value) { return func(value); }; @@ -7262,7 +7329,7 @@ return object[key]; }); } - function cacheHas(cache, key) { + function cacheHas2(cache, key) { return cache.has(key); } function charsStartIndex(strSymbols, chrSymbols) { @@ -7291,7 +7358,7 @@ function escapeStringChar(chr) { return "\\" + stringEscapes[chr]; } - function getValue(object, key) { + function getValue2(object, key) { return object == null ? undefined2 : object[key]; } function hasUnicode(string) { @@ -7307,14 +7374,14 @@ } return result; } - function mapToArray(map2) { + function mapToArray2(map2) { var index = -1, result = Array(map2.size); map2.forEach(function(value, key) { result[++index] = [key, value]; }); return result; } - function overArg(func, transform2) { + function overArg2(func, transform2) { return function(arg) { return func(transform2(arg)); }; @@ -7330,7 +7397,7 @@ } return result; } - function setToArray(set3) { + function setToArray2(set3) { var index = -1, result = Array(set3.size); set3.forEach(function(value) { result[++index] = value; @@ -7391,43 +7458,43 @@ var runInContext = function runInContext2(context) { context = context == null ? root3 : _.defaults(root3.Object(), context, _.pick(root3, contextProps)); var Array2 = context.Array, Date2 = context.Date, Error2 = context.Error, Function2 = context.Function, Math2 = context.Math, Object2 = context.Object, RegExp2 = context.RegExp, String2 = context.String, TypeError2 = context.TypeError; - var arrayProto = Array2.prototype, funcProto = Function2.prototype, objectProto3 = Object2.prototype; - var coreJsData = context["__core-js_shared__"]; - var funcToString = funcProto.toString; - var hasOwnProperty2 = objectProto3.hasOwnProperty; + var arrayProto2 = Array2.prototype, funcProto3 = Function2.prototype, objectProto13 = Object2.prototype; + var coreJsData2 = context["__core-js_shared__"]; + var funcToString3 = funcProto3.toString; + var hasOwnProperty10 = objectProto13.hasOwnProperty; var idCounter = 0; - var maskSrcKey = function() { - var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ""); + var maskSrcKey2 = function() { + var uid = /[^.]+$/.exec(coreJsData2 && coreJsData2.keys && coreJsData2.keys.IE_PROTO || ""); return uid ? "Symbol(src)_1." + uid : ""; }(); - var nativeObjectToString3 = objectProto3.toString; - var objectCtorString = funcToString.call(Object2); + var nativeObjectToString3 = objectProto13.toString; + var objectCtorString = funcToString3.call(Object2); var oldDash = root3._; - var reIsNative = RegExp2( - "^" + funcToString.call(hasOwnProperty2).replace(reRegExpChar, "\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, "$1.*?") + "$" + var reIsNative2 = RegExp2( + "^" + funcToString3.call(hasOwnProperty10).replace(reRegExpChar2, "\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, "$1.*?") + "$" ); - var Buffer2 = moduleExports ? context.Buffer : undefined2, Symbol3 = context.Symbol, Uint8Array2 = context.Uint8Array, allocUnsafe = Buffer2 ? Buffer2.allocUnsafe : undefined2, getPrototype = overArg(Object2.getPrototypeOf, Object2), objectCreate = Object2.create, propertyIsEnumerable = objectProto3.propertyIsEnumerable, splice = arrayProto.splice, spreadableSymbol = Symbol3 ? Symbol3.isConcatSpreadable : undefined2, symIterator = Symbol3 ? Symbol3.iterator : undefined2, symToStringTag3 = Symbol3 ? Symbol3.toStringTag : undefined2; + var Buffer3 = moduleExports3 ? context.Buffer : undefined2, Symbol3 = context.Symbol, Uint8Array3 = context.Uint8Array, allocUnsafe = Buffer3 ? Buffer3.allocUnsafe : undefined2, getPrototype = overArg2(Object2.getPrototypeOf, Object2), objectCreate = Object2.create, propertyIsEnumerable3 = objectProto13.propertyIsEnumerable, splice2 = arrayProto2.splice, spreadableSymbol = Symbol3 ? Symbol3.isConcatSpreadable : undefined2, symIterator = Symbol3 ? Symbol3.iterator : undefined2, symToStringTag3 = Symbol3 ? Symbol3.toStringTag : undefined2; var defineProperty = function() { try { - var func = getNative(Object2, "defineProperty"); + var func = getNative2(Object2, "defineProperty"); func({}, "", {}); return func; } catch (e) { } }(); var ctxClearTimeout = context.clearTimeout !== root3.clearTimeout && context.clearTimeout, ctxNow = Date2 && Date2.now !== root3.Date.now && Date2.now, ctxSetTimeout = context.setTimeout !== root3.setTimeout && context.setTimeout; - var nativeCeil = Math2.ceil, nativeFloor = Math2.floor, nativeGetSymbols = Object2.getOwnPropertySymbols, nativeIsBuffer = Buffer2 ? Buffer2.isBuffer : undefined2, nativeIsFinite = context.isFinite, nativeJoin = arrayProto.join, nativeKeys = overArg(Object2.keys, Object2), nativeMax2 = Math2.max, nativeMin2 = Math2.min, nativeNow = Date2.now, nativeParseInt = context.parseInt, nativeRandom = Math2.random, nativeReverse = arrayProto.reverse; - var DataView2 = getNative(context, "DataView"), Map2 = getNative(context, "Map"), Promise2 = getNative(context, "Promise"), Set2 = getNative(context, "Set"), WeakMap = getNative(context, "WeakMap"), nativeCreate = getNative(Object2, "create"); - var metaMap = WeakMap && new WeakMap(); + var nativeCeil = Math2.ceil, nativeFloor = Math2.floor, nativeGetSymbols2 = Object2.getOwnPropertySymbols, nativeIsBuffer2 = Buffer3 ? Buffer3.isBuffer : undefined2, nativeIsFinite = context.isFinite, nativeJoin = arrayProto2.join, nativeKeys2 = overArg2(Object2.keys, Object2), nativeMax2 = Math2.max, nativeMin2 = Math2.min, nativeNow = Date2.now, nativeParseInt = context.parseInt, nativeRandom = Math2.random, nativeReverse = arrayProto2.reverse; + var DataView3 = getNative2(context, "DataView"), Map3 = getNative2(context, "Map"), Promise3 = getNative2(context, "Promise"), Set3 = getNative2(context, "Set"), WeakMap2 = getNative2(context, "WeakMap"), nativeCreate2 = getNative2(Object2, "create"); + var metaMap = WeakMap2 && new WeakMap2(); var realNames = {}; - var dataViewCtorString = toSource(DataView2), mapCtorString = toSource(Map2), promiseCtorString = toSource(Promise2), setCtorString = toSource(Set2), weakMapCtorString = toSource(WeakMap); - var symbolProto2 = Symbol3 ? Symbol3.prototype : undefined2, symbolValueOf = symbolProto2 ? symbolProto2.valueOf : undefined2, symbolToString2 = symbolProto2 ? symbolProto2.toString : undefined2; + var dataViewCtorString2 = toSource2(DataView3), mapCtorString2 = toSource2(Map3), promiseCtorString2 = toSource2(Promise3), setCtorString2 = toSource2(Set3), weakMapCtorString2 = toSource2(WeakMap2); + var symbolProto3 = Symbol3 ? Symbol3.prototype : undefined2, symbolValueOf2 = symbolProto3 ? symbolProto3.valueOf : undefined2, symbolToString2 = symbolProto3 ? symbolProto3.toString : undefined2; function lodash(value) { if (isObjectLike2(value) && !isArray2(value) && !(value instanceof LazyWrapper)) { if (value instanceof LodashWrapper) { return value; } - if (hasOwnProperty2.call(value, "__wrapped__")) { + if (hasOwnProperty10.call(value, "__wrapped__")) { return wrapperClone(value); } } @@ -7437,7 +7504,7 @@ function object() { } return function(proto) { - if (!isObject2(proto)) { + if (!isObject3(proto)) { return {}; } if (objectCreate) { @@ -7459,11 +7526,47 @@ this.__values__ = undefined2; } lodash.templateSettings = { + /** + * Used to detect `data` property values to be HTML-escaped. + * + * @memberOf _.templateSettings + * @type {RegExp} + */ "escape": reEscape, + /** + * Used to detect code to be evaluated. + * + * @memberOf _.templateSettings + * @type {RegExp} + */ "evaluate": reEvaluate, + /** + * Used to detect `data` property values to inject. + * + * @memberOf _.templateSettings + * @type {RegExp} + */ "interpolate": reInterpolate, + /** + * Used to reference the data object in the template text. + * + * @memberOf _.templateSettings + * @type {string} + */ "variable": "", + /** + * Used to import variables into the compiled template. + * + * @memberOf _.templateSettings + * @type {Object} + */ "imports": { + /** + * A reference to the `lodash` function. + * + * @memberOf _.templateSettings.imports + * @type {Function} + */ "_": lodash } }; @@ -7512,11 +7615,11 @@ index += dir; var iterIndex = -1, value = array2[index]; while (++iterIndex < iterLength) { - var data = iteratees[iterIndex], iteratee2 = data.iteratee, type3 = data.type, computed = iteratee2(value); - if (type3 == LAZY_MAP_FLAG) { + var data = iteratees[iterIndex], iteratee2 = data.iteratee, type2 = data.type, computed = iteratee2(value); + if (type2 == LAZY_MAP_FLAG) { value = computed; } else if (!computed) { - if (type3 == LAZY_FILTER_FLAG) { + if (type2 == LAZY_FILTER_FLAG) { continue outer; } else { break outer; @@ -7529,7 +7632,7 @@ } LazyWrapper.prototype = baseCreate(baseLodash.prototype); LazyWrapper.prototype.constructor = LazyWrapper; - function Hash(entries) { + function Hash2(entries) { var index = -1, length = entries == null ? 0 : entries.length; this.clear(); while (++index < length) { @@ -7537,39 +7640,39 @@ this.set(entry[0], entry[1]); } } - function hashClear() { - this.__data__ = nativeCreate ? nativeCreate(null) : {}; + function hashClear2() { + this.__data__ = nativeCreate2 ? nativeCreate2(null) : {}; this.size = 0; } - function hashDelete(key) { + function hashDelete2(key) { var result2 = this.has(key) && delete this.__data__[key]; this.size -= result2 ? 1 : 0; return result2; } - function hashGet(key) { + function hashGet2(key) { var data = this.__data__; - if (nativeCreate) { + if (nativeCreate2) { var result2 = data[key]; - return result2 === HASH_UNDEFINED ? undefined2 : result2; + return result2 === HASH_UNDEFINED4 ? undefined2 : result2; } - return hasOwnProperty2.call(data, key) ? data[key] : undefined2; + return hasOwnProperty10.call(data, key) ? data[key] : undefined2; } - function hashHas(key) { + function hashHas2(key) { var data = this.__data__; - return nativeCreate ? data[key] !== undefined2 : hasOwnProperty2.call(data, key); + return nativeCreate2 ? data[key] !== undefined2 : hasOwnProperty10.call(data, key); } - function hashSet(key, value) { + function hashSet2(key, value) { var data = this.__data__; this.size += this.has(key) ? 0 : 1; - data[key] = nativeCreate && value === undefined2 ? HASH_UNDEFINED : value; + data[key] = nativeCreate2 && value === undefined2 ? HASH_UNDEFINED4 : value; return this; } - Hash.prototype.clear = hashClear; - Hash.prototype["delete"] = hashDelete; - Hash.prototype.get = hashGet; - Hash.prototype.has = hashHas; - Hash.prototype.set = hashSet; - function ListCache(entries) { + Hash2.prototype.clear = hashClear2; + Hash2.prototype["delete"] = hashDelete2; + Hash2.prototype.get = hashGet2; + Hash2.prototype.has = hashHas2; + Hash2.prototype.set = hashSet2; + function ListCache2(entries) { var index = -1, length = entries == null ? 0 : entries.length; this.clear(); while (++index < length) { @@ -7577,12 +7680,12 @@ this.set(entry[0], entry[1]); } } - function listCacheClear() { + function listCacheClear2() { this.__data__ = []; this.size = 0; } - function listCacheDelete(key) { - var data = this.__data__, index = assocIndexOf(data, key); + function listCacheDelete2(key) { + var data = this.__data__, index = assocIndexOf2(data, key); if (index < 0) { return false; } @@ -7590,20 +7693,20 @@ if (index == lastIndex) { data.pop(); } else { - splice.call(data, index, 1); + splice2.call(data, index, 1); } --this.size; return true; } - function listCacheGet(key) { - var data = this.__data__, index = assocIndexOf(data, key); + function listCacheGet2(key) { + var data = this.__data__, index = assocIndexOf2(data, key); return index < 0 ? undefined2 : data[index][1]; } - function listCacheHas(key) { - return assocIndexOf(this.__data__, key) > -1; + function listCacheHas2(key) { + return assocIndexOf2(this.__data__, key) > -1; } - function listCacheSet(key, value) { - var data = this.__data__, index = assocIndexOf(data, key); + function listCacheSet2(key, value) { + var data = this.__data__, index = assocIndexOf2(data, key); if (index < 0) { ++this.size; data.push([key, value]); @@ -7612,12 +7715,12 @@ } return this; } - ListCache.prototype.clear = listCacheClear; - ListCache.prototype["delete"] = listCacheDelete; - ListCache.prototype.get = listCacheGet; - ListCache.prototype.has = listCacheHas; - ListCache.prototype.set = listCacheSet; - function MapCache(entries) { + ListCache2.prototype.clear = listCacheClear2; + ListCache2.prototype["delete"] = listCacheDelete2; + ListCache2.prototype.get = listCacheGet2; + ListCache2.prototype.has = listCacheHas2; + ListCache2.prototype.set = listCacheSet2; + function MapCache2(entries) { var index = -1, length = entries == null ? 0 : entries.length; this.clear(); while (++index < length) { @@ -7625,95 +7728,99 @@ this.set(entry[0], entry[1]); } } - function mapCacheClear() { + function mapCacheClear2() { this.size = 0; this.__data__ = { - "hash": new Hash(), - "map": new (Map2 || ListCache)(), - "string": new Hash() + "hash": new Hash2(), + "map": new (Map3 || ListCache2)(), + "string": new Hash2() }; } - function mapCacheDelete(key) { - var result2 = getMapData(this, key)["delete"](key); + function mapCacheDelete2(key) { + var result2 = getMapData2(this, key)["delete"](key); this.size -= result2 ? 1 : 0; return result2; } - function mapCacheGet(key) { - return getMapData(this, key).get(key); + function mapCacheGet2(key) { + return getMapData2(this, key).get(key); } - function mapCacheHas(key) { - return getMapData(this, key).has(key); + function mapCacheHas2(key) { + return getMapData2(this, key).has(key); } - function mapCacheSet(key, value) { - var data = getMapData(this, key), size2 = data.size; + function mapCacheSet2(key, value) { + var data = getMapData2(this, key), size2 = data.size; data.set(key, value); this.size += data.size == size2 ? 0 : 1; return this; } - MapCache.prototype.clear = mapCacheClear; - MapCache.prototype["delete"] = mapCacheDelete; - MapCache.prototype.get = mapCacheGet; - MapCache.prototype.has = mapCacheHas; - MapCache.prototype.set = mapCacheSet; - function SetCache(values2) { + MapCache2.prototype.clear = mapCacheClear2; + MapCache2.prototype["delete"] = mapCacheDelete2; + MapCache2.prototype.get = mapCacheGet2; + MapCache2.prototype.has = mapCacheHas2; + MapCache2.prototype.set = mapCacheSet2; + function SetCache2(values2) { var index = -1, length = values2 == null ? 0 : values2.length; - this.__data__ = new MapCache(); + this.__data__ = new MapCache2(); while (++index < length) { this.add(values2[index]); } } - function setCacheAdd(value) { - this.__data__.set(value, HASH_UNDEFINED); + function setCacheAdd2(value) { + this.__data__.set(value, HASH_UNDEFINED4); return this; } - function setCacheHas(value) { + function setCacheHas2(value) { return this.__data__.has(value); } - SetCache.prototype.add = SetCache.prototype.push = setCacheAdd; - SetCache.prototype.has = setCacheHas; - function Stack(entries) { - var data = this.__data__ = new ListCache(entries); + SetCache2.prototype.add = SetCache2.prototype.push = setCacheAdd2; + SetCache2.prototype.has = setCacheHas2; + function Stack2(entries) { + var data = this.__data__ = new ListCache2(entries); this.size = data.size; } - function stackClear() { - this.__data__ = new ListCache(); + function stackClear2() { + this.__data__ = new ListCache2(); this.size = 0; } - function stackDelete(key) { + function stackDelete2(key) { var data = this.__data__, result2 = data["delete"](key); this.size = data.size; return result2; } - function stackGet(key) { + function stackGet2(key) { return this.__data__.get(key); } - function stackHas(key) { + function stackHas2(key) { return this.__data__.has(key); } - function stackSet(key, value) { + function stackSet2(key, value) { var data = this.__data__; - if (data instanceof ListCache) { + if (data instanceof ListCache2) { var pairs = data.__data__; - if (!Map2 || pairs.length < LARGE_ARRAY_SIZE - 1) { + if (!Map3 || pairs.length < LARGE_ARRAY_SIZE2 - 1) { pairs.push([key, value]); this.size = ++data.size; return this; } - data = this.__data__ = new MapCache(pairs); + data = this.__data__ = new MapCache2(pairs); } data.set(key, value); this.size = data.size; return this; } - Stack.prototype.clear = stackClear; - Stack.prototype["delete"] = stackDelete; - Stack.prototype.get = stackGet; - Stack.prototype.has = stackHas; - Stack.prototype.set = stackSet; - function arrayLikeKeys(value, inherited) { - var isArr = isArray2(value), isArg = !isArr && isArguments(value), isBuff = !isArr && !isArg && isBuffer(value), isType = !isArr && !isArg && !isBuff && isTypedArray(value), skipIndexes = isArr || isArg || isBuff || isType, result2 = skipIndexes ? baseTimes(value.length, String2) : [], length = result2.length; + Stack2.prototype.clear = stackClear2; + Stack2.prototype["delete"] = stackDelete2; + Stack2.prototype.get = stackGet2; + Stack2.prototype.has = stackHas2; + Stack2.prototype.set = stackSet2; + function arrayLikeKeys2(value, inherited) { + var isArr = isArray2(value), isArg = !isArr && isArguments2(value), isBuff = !isArr && !isArg && isBuffer2(value), isType = !isArr && !isArg && !isBuff && isTypedArray2(value), skipIndexes = isArr || isArg || isBuff || isType, result2 = skipIndexes ? baseTimes2(value.length, String2) : [], length = result2.length; for (var key in value) { - if ((inherited || hasOwnProperty2.call(value, key)) && !(skipIndexes && (key == "length" || isBuff && (key == "offset" || key == "parent") || isType && (key == "buffer" || key == "byteLength" || key == "byteOffset") || isIndex(key, length)))) { + if ((inherited || hasOwnProperty10.call(value, key)) && !(skipIndexes && // Safari 9 has enumerable `arguments.length` in strict mode. + (key == "length" || // Node.js 0.10 has enumerable non-index properties on buffers. + isBuff && (key == "offset" || key == "parent") || // PhantomJS 2 has enumerable non-index properties on typed arrays. + isType && (key == "buffer" || key == "byteLength" || key == "byteOffset") || // Skip index properties. + isIndex2(key, length)))) { result2.push(key); } } @@ -7730,20 +7837,20 @@ return shuffleSelf(copyArray(array2)); } function assignMergeValue(object, key, value) { - if (value !== undefined2 && !eq(object[key], value) || value === undefined2 && !(key in object)) { + if (value !== undefined2 && !eq2(object[key], value) || value === undefined2 && !(key in object)) { baseAssignValue(object, key, value); } } function assignValue(object, key, value) { var objValue = object[key]; - if (!(hasOwnProperty2.call(object, key) && eq(objValue, value)) || value === undefined2 && !(key in object)) { + if (!(hasOwnProperty10.call(object, key) && eq2(objValue, value)) || value === undefined2 && !(key in object)) { baseAssignValue(object, key, value); } } - function assocIndexOf(array2, key) { + function assocIndexOf2(array2, key) { var length = array2.length; while (length--) { - if (eq(array2[length][0], key)) { + if (eq2(array2[length][0], key)) { return length; } } @@ -7756,7 +7863,7 @@ return accumulator; } function baseAssign(object, source) { - return object && copyObject(source, keys(source), object); + return object && copyObject(source, keys2(source), object); } function baseAssignIn(object, source) { return object && copyObject(source, keysIn(source), object); @@ -7799,7 +7906,7 @@ if (result2 !== undefined2) { return result2; } - if (!isObject2(value)) { + if (!isObject3(value)) { return value; } var isArr = isArray2(value); @@ -7809,11 +7916,11 @@ return copyArray(value, result2); } } else { - var tag = getTag(value), isFunc = tag == funcTag || tag == genTag; - if (isBuffer(value)) { + var tag = getTag2(value), isFunc = tag == funcTag3 || tag == genTag2; + if (isBuffer2(value)) { return cloneBuffer(value, isDeep); } - if (tag == objectTag || tag == argsTag || isFunc && !object) { + if (tag == objectTag4 || tag == argsTag4 || isFunc && !object) { result2 = isFlat || isFunc ? {} : initCloneObject(value); if (!isDeep) { return isFlat ? copySymbolsIn(value, baseAssignIn(result2, value)) : copySymbols(value, baseAssign(result2, value)); @@ -7825,7 +7932,7 @@ result2 = initCloneByTag(value, tag, isDeep); } } - stack || (stack = new Stack()); + stack || (stack = new Stack2()); var stacked = stack.get(value); if (stacked) { return stacked; @@ -7840,7 +7947,7 @@ result2.set(key2, baseClone(subValue, bitmask, customizer, key2, value, stack)); }); } - var keysFunc = isFull ? isFlat ? getAllKeysIn : getAllKeys : isFlat ? keysIn : keys; + var keysFunc = isFull ? isFlat ? getAllKeysIn : getAllKeys2 : isFlat ? keysIn : keys2; var props = isArr ? undefined2 : keysFunc(value); arrayEach(props || value, function(subValue, key2) { if (props) { @@ -7852,7 +7959,7 @@ return result2; } function baseConforms(source) { - var props = keys(source); + var props = keys2(source); return function(object) { return baseConformsTo(object, source, props); }; @@ -7885,15 +7992,15 @@ return result2; } if (iteratee2) { - values2 = arrayMap2(values2, baseUnary(iteratee2)); + values2 = arrayMap2(values2, baseUnary2(iteratee2)); } if (comparator) { includes2 = arrayIncludesWith; isCommon = false; - } else if (values2.length >= LARGE_ARRAY_SIZE) { - includes2 = cacheHas; + } else if (values2.length >= LARGE_ARRAY_SIZE2) { + includes2 = cacheHas2; isCommon = false; - values2 = new SetCache(values2); + values2 = new SetCache2(values2); } outer: while (++index < length) { @@ -7968,7 +8075,7 @@ if (depth > 1) { baseFlatten(value, depth - 1, predicate, isStrict, result2); } else { - arrayPush(result2, value); + arrayPush2(result2, value); } } else if (!isStrict) { result2[result2.length] = value; @@ -7979,14 +8086,14 @@ var baseFor = createBaseFor(); var baseForRight = createBaseFor(true); function baseForOwn(object, iteratee2) { - return object && baseFor(object, iteratee2, keys); + return object && baseFor(object, iteratee2, keys2); } function baseForOwnRight(object, iteratee2) { - return object && baseForRight(object, iteratee2, keys); + return object && baseForRight(object, iteratee2, keys2); } function baseFunctions(object, props) { - return arrayFilter(props, function(key) { - return isFunction(object[key]); + return arrayFilter2(props, function(key) { + return isFunction2(object[key]); }); } function baseGet(object, path) { @@ -7997,9 +8104,9 @@ } return index && index == length ? object : undefined2; } - function baseGetAllKeys(object, keysFunc, symbolsFunc) { + function baseGetAllKeys2(object, keysFunc, symbolsFunc) { var result2 = keysFunc(object); - return isArray2(object) ? result2 : arrayPush(result2, symbolsFunc(object)); + return isArray2(object) ? result2 : arrayPush2(result2, symbolsFunc(object)); } function baseGetTag2(value) { if (value == null) { @@ -8011,7 +8118,7 @@ return value > other; } function baseHas(object, key) { - return object != null && hasOwnProperty2.call(object, key); + return object != null && hasOwnProperty10.call(object, key); } function baseHasIn(object, key) { return object != null && key in Object2(object); @@ -8024,10 +8131,10 @@ while (othIndex--) { var array2 = arrays[othIndex]; if (othIndex && iteratee2) { - array2 = arrayMap2(array2, baseUnary(iteratee2)); + array2 = arrayMap2(array2, baseUnary2(iteratee2)); } maxLength = nativeMin2(array2.length, maxLength); - caches[othIndex] = !comparator && (iteratee2 || length >= 120 && array2.length >= 120) ? new SetCache(othIndex && array2) : undefined2; + caches[othIndex] = !comparator && (iteratee2 || length >= 120 && array2.length >= 120) ? new SetCache2(othIndex && array2) : undefined2; } array2 = arrays[0]; var index = -1, seen = caches[0]; @@ -8035,11 +8142,11 @@ while (++index < length && result2.length < maxLength) { var value = array2[index], computed = iteratee2 ? iteratee2(value) : value; value = comparator || value !== 0 ? value : 0; - if (!(seen ? cacheHas(seen, computed) : includes2(result2, computed, comparator))) { + if (!(seen ? cacheHas2(seen, computed) : includes2(result2, computed, comparator))) { othIndex = othLength; while (--othIndex) { var cache = caches[othIndex]; - if (!(cache ? cacheHas(cache, computed) : includes2(arrays[othIndex], computed, comparator))) { + if (!(cache ? cacheHas2(cache, computed) : includes2(arrays[othIndex], computed, comparator))) { continue outer; } } @@ -8063,56 +8170,56 @@ var func = object == null ? object : object[toKey(last(path))]; return func == null ? undefined2 : apply(func, object, args); } - function baseIsArguments(value) { - return isObjectLike2(value) && baseGetTag2(value) == argsTag; + function baseIsArguments2(value) { + return isObjectLike2(value) && baseGetTag2(value) == argsTag4; } function baseIsArrayBuffer(value) { - return isObjectLike2(value) && baseGetTag2(value) == arrayBufferTag; + return isObjectLike2(value) && baseGetTag2(value) == arrayBufferTag3; } function baseIsDate(value) { - return isObjectLike2(value) && baseGetTag2(value) == dateTag; + return isObjectLike2(value) && baseGetTag2(value) == dateTag3; } - function baseIsEqual(value, other, bitmask, customizer, stack) { + function baseIsEqual2(value, other, bitmask, customizer, stack) { if (value === other) { return true; } if (value == null || other == null || !isObjectLike2(value) && !isObjectLike2(other)) { return value !== value && other !== other; } - return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); + return baseIsEqualDeep2(value, other, bitmask, customizer, baseIsEqual2, stack); } - function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { - var objIsArr = isArray2(object), othIsArr = isArray2(other), objTag = objIsArr ? arrayTag : getTag(object), othTag = othIsArr ? arrayTag : getTag(other); - objTag = objTag == argsTag ? objectTag : objTag; - othTag = othTag == argsTag ? objectTag : othTag; - var objIsObj = objTag == objectTag, othIsObj = othTag == objectTag, isSameTag = objTag == othTag; - if (isSameTag && isBuffer(object)) { - if (!isBuffer(other)) { + function baseIsEqualDeep2(object, other, bitmask, customizer, equalFunc, stack) { + var objIsArr = isArray2(object), othIsArr = isArray2(other), objTag = objIsArr ? arrayTag3 : getTag2(object), othTag = othIsArr ? arrayTag3 : getTag2(other); + objTag = objTag == argsTag4 ? objectTag4 : objTag; + othTag = othTag == argsTag4 ? objectTag4 : othTag; + var objIsObj = objTag == objectTag4, othIsObj = othTag == objectTag4, isSameTag = objTag == othTag; + if (isSameTag && isBuffer2(object)) { + if (!isBuffer2(other)) { return false; } objIsArr = true; objIsObj = false; } if (isSameTag && !objIsObj) { - stack || (stack = new Stack()); - return objIsArr || isTypedArray(object) ? equalArrays(object, other, bitmask, customizer, equalFunc, stack) : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack); + stack || (stack = new Stack2()); + return objIsArr || isTypedArray2(object) ? equalArrays2(object, other, bitmask, customizer, equalFunc, stack) : equalByTag2(object, other, objTag, bitmask, customizer, equalFunc, stack); } - if (!(bitmask & COMPARE_PARTIAL_FLAG)) { - var objIsWrapped = objIsObj && hasOwnProperty2.call(object, "__wrapped__"), othIsWrapped = othIsObj && hasOwnProperty2.call(other, "__wrapped__"); + if (!(bitmask & COMPARE_PARTIAL_FLAG5)) { + var objIsWrapped = objIsObj && hasOwnProperty10.call(object, "__wrapped__"), othIsWrapped = othIsObj && hasOwnProperty10.call(other, "__wrapped__"); if (objIsWrapped || othIsWrapped) { var objUnwrapped = objIsWrapped ? object.value() : object, othUnwrapped = othIsWrapped ? other.value() : other; - stack || (stack = new Stack()); + stack || (stack = new Stack2()); return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack); } } if (!isSameTag) { return false; } - stack || (stack = new Stack()); - return equalObjects(object, other, bitmask, customizer, equalFunc, stack); + stack || (stack = new Stack2()); + return equalObjects2(object, other, bitmask, customizer, equalFunc, stack); } function baseIsMap(value) { - return isObjectLike2(value) && getTag(value) == mapTag; + return isObjectLike2(value) && getTag2(value) == mapTag4; } function baseIsMatch(object, source, matchData, customizer) { var index = matchData.length, length = index, noCustomizer = !customizer; @@ -8134,32 +8241,32 @@ return false; } } else { - var stack = new Stack(); + var stack = new Stack2(); if (customizer) { var result2 = customizer(objValue, srcValue, key, object, source, stack); } - if (!(result2 === undefined2 ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack) : result2)) { + if (!(result2 === undefined2 ? baseIsEqual2(srcValue, objValue, COMPARE_PARTIAL_FLAG5 | COMPARE_UNORDERED_FLAG3, customizer, stack) : result2)) { return false; } } } return true; } - function baseIsNative(value) { - if (!isObject2(value) || isMasked(value)) { + function baseIsNative2(value) { + if (!isObject3(value) || isMasked2(value)) { return false; } - var pattern = isFunction(value) ? reIsNative : reIsHostCtor; - return pattern.test(toSource(value)); + var pattern = isFunction2(value) ? reIsNative2 : reIsHostCtor2; + return pattern.test(toSource2(value)); } function baseIsRegExp(value) { - return isObjectLike2(value) && baseGetTag2(value) == regexpTag; + return isObjectLike2(value) && baseGetTag2(value) == regexpTag3; } function baseIsSet(value) { - return isObjectLike2(value) && getTag(value) == setTag; + return isObjectLike2(value) && getTag2(value) == setTag4; } - function baseIsTypedArray(value) { - return isObjectLike2(value) && isLength(value.length) && !!typedArrayTags[baseGetTag2(value)]; + function baseIsTypedArray2(value) { + return isObjectLike2(value) && isLength2(value.length) && !!typedArrayTags2[baseGetTag2(value)]; } function baseIteratee(value) { if (typeof value == "function") { @@ -8173,25 +8280,25 @@ } return property(value); } - function baseKeys(object) { - if (!isPrototype(object)) { - return nativeKeys(object); + function baseKeys2(object) { + if (!isPrototype2(object)) { + return nativeKeys2(object); } var result2 = []; for (var key in Object2(object)) { - if (hasOwnProperty2.call(object, key) && key != "constructor") { + if (hasOwnProperty10.call(object, key) && key != "constructor") { result2.push(key); } } return result2; } function baseKeysIn(object) { - if (!isObject2(object)) { + if (!isObject3(object)) { return nativeKeysIn(object); } - var isProto = isPrototype(object), result2 = []; + var isProto = isPrototype2(object), result2 = []; for (var key in object) { - if (!(key == "constructor" && (isProto || !hasOwnProperty2.call(object, key)))) { + if (!(key == "constructor" && (isProto || !hasOwnProperty10.call(object, key)))) { result2.push(key); } } @@ -8201,7 +8308,7 @@ return value < other; } function baseMap(collection, iteratee2) { - var index = -1, result2 = isArrayLike(collection) ? Array2(collection.length) : []; + var index = -1, result2 = isArrayLike2(collection) ? Array2(collection.length) : []; baseEach(collection, function(value, key, collection2) { result2[++index] = iteratee2(value, key, collection2); }); @@ -8222,7 +8329,7 @@ } return function(object) { var objValue = get4(object, path); - return objValue === undefined2 && objValue === srcValue ? hasIn(object, path) : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG); + return objValue === undefined2 && objValue === srcValue ? hasIn(object, path) : baseIsEqual2(srcValue, objValue, COMPARE_PARTIAL_FLAG5 | COMPARE_UNORDERED_FLAG3); }; } function baseMerge(object, source, srcIndex, customizer, stack) { @@ -8230,8 +8337,8 @@ return; } baseFor(source, function(srcValue, key) { - stack || (stack = new Stack()); - if (isObject2(srcValue)) { + stack || (stack = new Stack2()); + if (isObject3(srcValue)) { baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack); } else { var newValue = customizer ? customizer(safeGet(object, key), srcValue, key + "", object, source, stack) : undefined2; @@ -8251,7 +8358,7 @@ var newValue = customizer ? customizer(objValue, srcValue, key + "", object, source, stack) : undefined2; var isCommon = newValue === undefined2; if (isCommon) { - var isArr = isArray2(srcValue), isBuff = !isArr && isBuffer(srcValue), isTyped = !isArr && !isBuff && isTypedArray(srcValue); + var isArr = isArray2(srcValue), isBuff = !isArr && isBuffer2(srcValue), isTyped = !isArr && !isBuff && isTypedArray2(srcValue); newValue = srcValue; if (isArr || isBuff || isTyped) { if (isArray2(objValue)) { @@ -8267,11 +8374,11 @@ } else { newValue = []; } - } else if (isPlainObject(srcValue) || isArguments(srcValue)) { + } else if (isPlainObject(srcValue) || isArguments2(srcValue)) { newValue = objValue; - if (isArguments(objValue)) { + if (isArguments2(objValue)) { newValue = toPlainObject(objValue); - } else if (!isObject2(objValue) || isFunction(objValue)) { + } else if (!isObject3(objValue) || isFunction2(objValue)) { newValue = initCloneObject(srcValue); } } else { @@ -8291,7 +8398,7 @@ return; } n2 += n2 < 0 ? length : 0; - return isIndex(n2, length) ? array2[n2] : undefined2; + return isIndex2(n2, length) ? array2[n2] : undefined2; } function baseOrderBy(collection, iteratees, orders) { if (iteratees.length) { @@ -8307,7 +8414,7 @@ iteratees = [identity4]; } var index = -1; - iteratees = arrayMap2(iteratees, baseUnary(getIteratee())); + iteratees = arrayMap2(iteratees, baseUnary2(getIteratee())); var result2 = baseMap(collection, function(value, key, collection2) { var criteria = arrayMap2(iteratees, function(iteratee2) { return iteratee2(value); @@ -8344,15 +8451,15 @@ values2 = copyArray(values2); } if (iteratee2) { - seen = arrayMap2(array2, baseUnary(iteratee2)); + seen = arrayMap2(array2, baseUnary2(iteratee2)); } while (++index < length) { var fromIndex = 0, value = values2[index], computed = iteratee2 ? iteratee2(value) : value; while ((fromIndex = indexOf2(seen, computed, fromIndex, comparator)) > -1) { if (seen !== array2) { - splice.call(seen, fromIndex, 1); + splice2.call(seen, fromIndex, 1); } - splice.call(array2, fromIndex, 1); + splice2.call(array2, fromIndex, 1); } } return array2; @@ -8363,8 +8470,8 @@ var index = indexes[length]; if (length == lastIndex || index !== previous) { var previous = index; - if (isIndex(index)) { - splice.call(array2, index, 1); + if (isIndex2(index)) { + splice2.call(array2, index, 1); } else { baseUnset(array2, index); } @@ -8385,7 +8492,7 @@ } function baseRepeat(string, n2) { var result2 = ""; - if (!string || n2 < 1 || n2 > MAX_SAFE_INTEGER) { + if (!string || n2 < 1 || n2 > MAX_SAFE_INTEGER3) { return result2; } do { @@ -8410,7 +8517,7 @@ return shuffleSelf(array2, baseClamp(n2, 0, array2.length)); } function baseSet(object, path, value, customizer) { - if (!isObject2(object)) { + if (!isObject3(object)) { return object; } path = castPath(path, object); @@ -8424,7 +8531,7 @@ var objValue = nested[key]; newValue = customizer ? customizer(objValue, key, nested) : undefined2; if (newValue === undefined2) { - newValue = isObject2(objValue) ? objValue : isIndex(path[index + 1]) ? [] : {}; + newValue = isObject3(objValue) ? objValue : isIndex2(path[index + 1]) ? [] : {}; } } assignValue(nested, key, newValue); @@ -8521,7 +8628,7 @@ var index = -1, length = array2.length, resIndex = 0, result2 = []; while (++index < length) { var value = array2[index], computed = iteratee2 ? iteratee2(value) : value; - if (!index || !eq(computed, seen)) { + if (!index || !eq2(computed, seen)) { var seen = computed; result2[resIndex++] = value === 0 ? 0 : value; } @@ -8555,14 +8662,14 @@ if (comparator) { isCommon = false; includes2 = arrayIncludesWith; - } else if (length >= LARGE_ARRAY_SIZE) { + } else if (length >= LARGE_ARRAY_SIZE2) { var set4 = iteratee2 ? null : createSet(array2); if (set4) { - return setToArray(set4); + return setToArray2(set4); } isCommon = false; - includes2 = cacheHas; - seen = new SetCache(); + includes2 = cacheHas2; + seen = new SetCache2(); } else { seen = iteratee2 ? [] : result2; } @@ -8610,7 +8717,7 @@ result2 = result2.value(); } return arrayReduce(actions, function(result3, action) { - return action.func.apply(action.thisArg, arrayPush([result3], action.args)); + return action.func.apply(action.thisArg, arrayPush2([result3], action.args)); }, result2); } function baseXor(arrays, iteratee2, comparator) { @@ -8668,7 +8775,7 @@ } function cloneArrayBuffer(arrayBuffer) { var result2 = new arrayBuffer.constructor(arrayBuffer.byteLength); - new Uint8Array2(result2).set(new Uint8Array2(arrayBuffer)); + new Uint8Array3(result2).set(new Uint8Array3(arrayBuffer)); return result2; } function cloneDataView(dataView, isDeep) { @@ -8681,7 +8788,7 @@ return result2; } function cloneSymbol(symbol) { - return symbolValueOf ? Object2(symbolValueOf.call(symbol)) : {}; + return symbolValueOf2 ? Object2(symbolValueOf2.call(symbol)) : {}; } function cloneTypedArray(typedArray, isDeep) { var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; @@ -8772,7 +8879,7 @@ return object; } function copySymbols(source, object) { - return copyObject(source, getSymbols(source), object); + return copyObject(source, getSymbols2(source), object); } function copySymbolsIn(source, object) { return copyObject(source, getSymbolsIn(source), object); @@ -8806,7 +8913,7 @@ if (collection == null) { return collection; } - if (!isArrayLike(collection)) { + if (!isArrayLike2(collection)) { return eachFunc(collection, iteratee2); } var length = collection.length, index = fromRight ? length : -1, iterable = Object2(collection); @@ -8874,7 +8981,7 @@ return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); } var thisBinding = baseCreate(Ctor.prototype), result2 = Ctor.apply(thisBinding, args); - return isObject2(result2) ? result2 : thisBinding; + return isObject3(result2) ? result2 : thisBinding; }; } function createCurry(func, bitmask, arity) { @@ -8908,9 +9015,9 @@ function createFind(findIndexFunc) { return function(collection, predicate, fromIndex) { var iterable = Object2(collection); - if (!isArrayLike(collection)) { + if (!isArrayLike2(collection)) { var iteratee2 = getIteratee(predicate, 3); - collection = keys(collection); + collection = keys2(collection); predicate = function(key) { return iteratee2(iterable[key], key, iterable); }; @@ -9038,7 +9145,7 @@ } function createOver(arrayFunc) { return flatRest(function(iteratees) { - iteratees = arrayMap2(iteratees, baseUnary(getIteratee())); + iteratees = arrayMap2(iteratees, baseUnary2(getIteratee())); return baseRest(function(args) { var thisArg = this; return arrayFunc(iteratees, function(iteratee2) { @@ -9089,8 +9196,8 @@ function createRelationalOperation(operator) { return function(value, other) { if (!(typeof value == "string" && typeof other == "string")) { - value = toNumber2(value); - other = toNumber2(other); + value = toNumber3(value); + other = toNumber3(other); } return operator(value, other); }; @@ -9124,7 +9231,7 @@ function createRound(methodName) { var func = Math2[methodName]; return function(number3, precision2) { - number3 = toNumber2(number3); + number3 = toNumber3(number3); precision2 = precision2 == null ? 0 : nativeMin2(toInteger(precision2), 292); if (precision2 && nativeIsFinite(number3)) { var pair2 = (toString2(number3) + "e").split("e"), value = func(pair2[0] + "e" + (+pair2[1] + precision2)); @@ -9134,16 +9241,16 @@ return func(number3); }; } - var createSet = !(Set2 && 1 / setToArray(new Set2([, -0]))[1] == INFINITY2) ? noop3 : function(values2) { - return new Set2(values2); + var createSet = !(Set3 && 1 / setToArray2(new Set3([, -0]))[1] == INFINITY2) ? noop3 : function(values2) { + return new Set3(values2); }; function createToPairs(keysFunc) { return function(object) { - var tag = getTag(object); - if (tag == mapTag) { - return mapToArray(object); + var tag = getTag2(object); + if (tag == mapTag4) { + return mapToArray2(object); } - if (tag == setTag) { + if (tag == setTag4) { return setToPairs(object); } return baseToPairs(object, keysFunc(object)); @@ -9204,13 +9311,13 @@ return setWrapToString(setter(result2, newData), func, bitmask); } function customDefaultsAssignIn(objValue, srcValue, key, object) { - if (objValue === undefined2 || eq(objValue, objectProto3[key]) && !hasOwnProperty2.call(object, key)) { + if (objValue === undefined2 || eq2(objValue, objectProto13[key]) && !hasOwnProperty10.call(object, key)) { return srcValue; } return objValue; } function customDefaultsMerge(objValue, srcValue, key, object, source, stack) { - if (isObject2(objValue) && isObject2(srcValue)) { + if (isObject3(objValue) && isObject3(srcValue)) { stack.set(srcValue, objValue); baseMerge(objValue, srcValue, undefined2, customDefaultsMerge, stack); stack["delete"](srcValue); @@ -9220,8 +9327,8 @@ function customOmitClone(value) { return isPlainObject(value) ? undefined2 : value; } - function equalArrays(array2, other, bitmask, customizer, equalFunc, stack) { - var isPartial = bitmask & COMPARE_PARTIAL_FLAG, arrLength = array2.length, othLength = other.length; + function equalArrays2(array2, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG5, arrLength = array2.length, othLength = other.length; if (arrLength != othLength && !(isPartial && othLength > arrLength)) { return false; } @@ -9230,7 +9337,7 @@ if (arrStacked && othStacked) { return arrStacked == other && othStacked == array2; } - var index = -1, result2 = true, seen = bitmask & COMPARE_UNORDERED_FLAG ? new SetCache() : undefined2; + var index = -1, result2 = true, seen = bitmask & COMPARE_UNORDERED_FLAG3 ? new SetCache2() : undefined2; stack.set(array2, other); stack.set(other, array2); while (++index < arrLength) { @@ -9246,8 +9353,8 @@ break; } if (seen) { - if (!arraySome(other, function(othValue2, othIndex) { - if (!cacheHas(seen, othIndex) && (arrValue === othValue2 || equalFunc(arrValue, othValue2, bitmask, customizer, stack))) { + if (!arraySome2(other, function(othValue2, othIndex) { + if (!cacheHas2(seen, othIndex) && (arrValue === othValue2 || equalFunc(arrValue, othValue2, bitmask, customizer, stack))) { return seen.push(othIndex); } })) { @@ -9263,33 +9370,33 @@ stack["delete"](other); return result2; } - function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { + function equalByTag2(object, other, tag, bitmask, customizer, equalFunc, stack) { switch (tag) { - case dataViewTag: + case dataViewTag4: if (object.byteLength != other.byteLength || object.byteOffset != other.byteOffset) { return false; } object = object.buffer; other = other.buffer; - case arrayBufferTag: - if (object.byteLength != other.byteLength || !equalFunc(new Uint8Array2(object), new Uint8Array2(other))) { + case arrayBufferTag3: + if (object.byteLength != other.byteLength || !equalFunc(new Uint8Array3(object), new Uint8Array3(other))) { return false; } return true; - case boolTag: - case dateTag: - case numberTag: - return eq(+object, +other); - case errorTag: + case boolTag3: + case dateTag3: + case numberTag3: + return eq2(+object, +other); + case errorTag3: return object.name == other.name && object.message == other.message; - case regexpTag: - case stringTag: + case regexpTag3: + case stringTag3: return object == other + ""; - case mapTag: - var convert = mapToArray; - case setTag: - var isPartial = bitmask & COMPARE_PARTIAL_FLAG; - convert || (convert = setToArray); + case mapTag4: + var convert = mapToArray2; + case setTag4: + var isPartial = bitmask & COMPARE_PARTIAL_FLAG5; + convert || (convert = setToArray2); if (object.size != other.size && !isPartial) { return false; } @@ -9297,27 +9404,27 @@ if (stacked) { return stacked == other; } - bitmask |= COMPARE_UNORDERED_FLAG; + bitmask |= COMPARE_UNORDERED_FLAG3; stack.set(object, other); - var result2 = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack); + var result2 = equalArrays2(convert(object), convert(other), bitmask, customizer, equalFunc, stack); stack["delete"](object); return result2; - case symbolTag2: - if (symbolValueOf) { - return symbolValueOf.call(object) == symbolValueOf.call(other); + case symbolTag3: + if (symbolValueOf2) { + return symbolValueOf2.call(object) == symbolValueOf2.call(other); } } return false; } - function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { - var isPartial = bitmask & COMPARE_PARTIAL_FLAG, objProps = getAllKeys(object), objLength = objProps.length, othProps = getAllKeys(other), othLength = othProps.length; + function equalObjects2(object, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG5, objProps = getAllKeys2(object), objLength = objProps.length, othProps = getAllKeys2(other), othLength = othProps.length; if (objLength != othLength && !isPartial) { return false; } var index = objLength; while (index--) { var key = objProps[index]; - if (!(isPartial ? key in other : hasOwnProperty2.call(other, key))) { + if (!(isPartial ? key in other : hasOwnProperty10.call(other, key))) { return false; } } @@ -9355,17 +9462,17 @@ function flatRest(func) { return setToString(overRest(func, undefined2, flatten2), func + ""); } - function getAllKeys(object) { - return baseGetAllKeys(object, keys, getSymbols); + function getAllKeys2(object) { + return baseGetAllKeys2(object, keys2, getSymbols2); } function getAllKeysIn(object) { - return baseGetAllKeys(object, keysIn, getSymbolsIn); + return baseGetAllKeys2(object, keysIn, getSymbolsIn); } var getData = !metaMap ? noop3 : function(func) { return metaMap.get(func); }; function getFuncName(func) { - var result2 = func.name + "", array2 = realNames[result2], length = hasOwnProperty2.call(realNames, result2) ? array2.length : 0; + var result2 = func.name + "", array2 = realNames[result2], length = hasOwnProperty10.call(realNames, result2) ? array2.length : 0; while (length--) { var data = array2[length], otherFunc = data.func; if (otherFunc == null || otherFunc == func) { @@ -9375,7 +9482,7 @@ return result2; } function getHolder(func) { - var object = hasOwnProperty2.call(lodash, "placeholder") ? lodash : func; + var object = hasOwnProperty10.call(lodash, "placeholder") ? lodash : func; return object.placeholder; } function getIteratee() { @@ -9383,24 +9490,24 @@ result2 = result2 === iteratee ? baseIteratee : result2; return arguments.length ? result2(arguments[0], arguments[1]) : result2; } - function getMapData(map3, key) { + function getMapData2(map3, key) { var data = map3.__data__; - return isKeyable(key) ? data[typeof key == "string" ? "string" : "hash"] : data.map; + return isKeyable2(key) ? data[typeof key == "string" ? "string" : "hash"] : data.map; } function getMatchData(object) { - var result2 = keys(object), length = result2.length; + var result2 = keys2(object), length = result2.length; while (length--) { var key = result2[length], value = object[key]; result2[length] = [key, value, isStrictComparable(value)]; } return result2; } - function getNative(object, key) { - var value = getValue(object, key); - return baseIsNative(value) ? value : undefined2; + function getNative2(object, key) { + var value = getValue2(object, key); + return baseIsNative2(value) ? value : undefined2; } function getRawTag2(value) { - var isOwn = hasOwnProperty2.call(value, symToStringTag3), tag = value[symToStringTag3]; + var isOwn = hasOwnProperty10.call(value, symToStringTag3), tag = value[symToStringTag3]; try { value[symToStringTag3] = undefined2; var unmasked = true; @@ -9416,39 +9523,39 @@ } return result2; } - var getSymbols = !nativeGetSymbols ? stubArray : function(object) { + var getSymbols2 = !nativeGetSymbols2 ? stubArray2 : function(object) { if (object == null) { return []; } object = Object2(object); - return arrayFilter(nativeGetSymbols(object), function(symbol) { - return propertyIsEnumerable.call(object, symbol); + return arrayFilter2(nativeGetSymbols2(object), function(symbol) { + return propertyIsEnumerable3.call(object, symbol); }); }; - var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) { + var getSymbolsIn = !nativeGetSymbols2 ? stubArray2 : function(object) { var result2 = []; while (object) { - arrayPush(result2, getSymbols(object)); + arrayPush2(result2, getSymbols2(object)); object = getPrototype(object); } return result2; }; - var getTag = baseGetTag2; - if (DataView2 && getTag(new DataView2(new ArrayBuffer(1))) != dataViewTag || Map2 && getTag(new Map2()) != mapTag || Promise2 && getTag(Promise2.resolve()) != promiseTag || Set2 && getTag(new Set2()) != setTag || WeakMap && getTag(new WeakMap()) != weakMapTag) { - getTag = function(value) { - var result2 = baseGetTag2(value), Ctor = result2 == objectTag ? value.constructor : undefined2, ctorString = Ctor ? toSource(Ctor) : ""; + var getTag2 = baseGetTag2; + if (DataView3 && getTag2(new DataView3(new ArrayBuffer(1))) != dataViewTag4 || Map3 && getTag2(new Map3()) != mapTag4 || Promise3 && getTag2(Promise3.resolve()) != promiseTag2 || Set3 && getTag2(new Set3()) != setTag4 || WeakMap2 && getTag2(new WeakMap2()) != weakMapTag3) { + getTag2 = function(value) { + var result2 = baseGetTag2(value), Ctor = result2 == objectTag4 ? value.constructor : undefined2, ctorString = Ctor ? toSource2(Ctor) : ""; if (ctorString) { switch (ctorString) { - case dataViewCtorString: - return dataViewTag; - case mapCtorString: - return mapTag; - case promiseCtorString: - return promiseTag; - case setCtorString: - return setTag; - case weakMapCtorString: - return weakMapTag; + case dataViewCtorString2: + return dataViewTag4; + case mapCtorString2: + return mapTag4; + case promiseCtorString2: + return promiseTag2; + case setCtorString2: + return setTag4; + case weakMapCtorString2: + return weakMapTag3; } } return result2; @@ -9493,49 +9600,49 @@ return result2; } length = object == null ? 0 : object.length; - return !!length && isLength(length) && isIndex(key, length) && (isArray2(object) || isArguments(object)); + return !!length && isLength2(length) && isIndex2(key, length) && (isArray2(object) || isArguments2(object)); } function initCloneArray(array2) { var length = array2.length, result2 = new array2.constructor(length); - if (length && typeof array2[0] == "string" && hasOwnProperty2.call(array2, "index")) { + if (length && typeof array2[0] == "string" && hasOwnProperty10.call(array2, "index")) { result2.index = array2.index; result2.input = array2.input; } return result2; } function initCloneObject(object) { - return typeof object.constructor == "function" && !isPrototype(object) ? baseCreate(getPrototype(object)) : {}; + return typeof object.constructor == "function" && !isPrototype2(object) ? baseCreate(getPrototype(object)) : {}; } function initCloneByTag(object, tag, isDeep) { var Ctor = object.constructor; switch (tag) { - case arrayBufferTag: + case arrayBufferTag3: return cloneArrayBuffer(object); - case boolTag: - case dateTag: + case boolTag3: + case dateTag3: return new Ctor(+object); - case dataViewTag: + case dataViewTag4: return cloneDataView(object, isDeep); - case float32Tag: - case float64Tag: - case int8Tag: - case int16Tag: - case int32Tag: - case uint8Tag: - case uint8ClampedTag: - case uint16Tag: - case uint32Tag: + case float32Tag2: + case float64Tag2: + case int8Tag2: + case int16Tag2: + case int32Tag2: + case uint8Tag2: + case uint8ClampedTag2: + case uint16Tag2: + case uint32Tag2: return cloneTypedArray(object, isDeep); - case mapTag: + case mapTag4: return new Ctor(); - case numberTag: - case stringTag: + case numberTag3: + case stringTag3: return new Ctor(object); - case regexpTag: + case regexpTag3: return cloneRegExp(object); - case setTag: + case setTag4: return new Ctor(); - case symbolTag2: + case symbolTag3: return cloneSymbol(object); } } @@ -9550,20 +9657,20 @@ return source.replace(reWrapComment, "{\n/* [wrapped with " + details + "] */\n"); } function isFlattenable(value) { - return isArray2(value) || isArguments(value) || !!(spreadableSymbol && value && value[spreadableSymbol]); + return isArray2(value) || isArguments2(value) || !!(spreadableSymbol && value && value[spreadableSymbol]); } - function isIndex(value, length) { - var type3 = typeof value; - length = length == null ? MAX_SAFE_INTEGER : length; - return !!length && (type3 == "number" || type3 != "symbol" && reIsUint.test(value)) && (value > -1 && value % 1 == 0 && value < length); + function isIndex2(value, length) { + var type2 = typeof value; + length = length == null ? MAX_SAFE_INTEGER3 : length; + return !!length && (type2 == "number" || type2 != "symbol" && reIsUint2.test(value)) && (value > -1 && value % 1 == 0 && value < length); } function isIterateeCall(value, index, object) { - if (!isObject2(object)) { + if (!isObject3(object)) { return false; } - var type3 = typeof index; - if (type3 == "number" ? isArrayLike(object) && isIndex(index, object.length) : type3 == "string" && index in object) { - return eq(object[index], value); + var type2 = typeof index; + if (type2 == "number" ? isArrayLike2(object) && isIndex2(index, object.length) : type2 == "string" && index in object) { + return eq2(object[index], value); } return false; } @@ -9571,15 +9678,15 @@ if (isArray2(value)) { return false; } - var type3 = typeof value; - if (type3 == "number" || type3 == "symbol" || type3 == "boolean" || value == null || isSymbol2(value)) { + var type2 = typeof value; + if (type2 == "number" || type2 == "symbol" || type2 == "boolean" || value == null || isSymbol2(value)) { return true; } return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || object != null && value in Object2(object); } - function isKeyable(value) { - var type3 = typeof value; - return type3 == "string" || type3 == "number" || type3 == "symbol" || type3 == "boolean" ? value !== "__proto__" : value === null; + function isKeyable2(value) { + var type2 = typeof value; + return type2 == "string" || type2 == "number" || type2 == "symbol" || type2 == "boolean" ? value !== "__proto__" : value === null; } function isLaziable(func) { var funcName = getFuncName(func), other = lodash[funcName]; @@ -9592,16 +9699,16 @@ var data = getData(other); return !!data && func === data[0]; } - function isMasked(func) { - return !!maskSrcKey && maskSrcKey in func; + function isMasked2(func) { + return !!maskSrcKey2 && maskSrcKey2 in func; } - var isMaskable = coreJsData ? isFunction : stubFalse; - function isPrototype(value) { - var Ctor = value && value.constructor, proto = typeof Ctor == "function" && Ctor.prototype || objectProto3; + var isMaskable = coreJsData2 ? isFunction2 : stubFalse2; + function isPrototype2(value) { + var Ctor = value && value.constructor, proto = typeof Ctor == "function" && Ctor.prototype || objectProto13; return value === proto; } function isStrictComparable(value) { - return value === value && !isObject2(value); + return value === value && !isObject3(value); } function matchesStrictComparable(key, srcValue) { return function(object) { @@ -9692,7 +9799,7 @@ var arrLength = array2.length, length = nativeMin2(indexes.length, arrLength), oldArray = copyArray(array2); while (length--) { var index = indexes[length]; - array2[length] = isIndex(index, arrLength) ? oldArray[index] : undefined2; + array2[length] = isIndex2(index, arrLength) ? oldArray[index] : undefined2; } return array2; } @@ -9757,10 +9864,10 @@ var result2 = value + ""; return result2 == "0" && 1 / value == -INFINITY2 ? "-0" : result2; } - function toSource(func) { + function toSource2(func) { if (func != null) { try { - return funcToString.call(func); + return funcToString3.call(func); } catch (e) { } try { @@ -9824,7 +9931,7 @@ while (index--) { args[index - 1] = arguments[index]; } - return arrayPush(isArray2(array2) ? copyArray(array2) : [array2], baseFlatten(args, 1)); + return arrayPush2(isArray2(array2) ? copyArray(array2) : [array2], baseFlatten(args, 1)); } var difference = baseRest(function(array2, values2) { return isArrayLikeObject(array2) ? baseDifference(array2, baseFlatten(values2, 1, isArrayLikeObject, true)) : []; @@ -9998,7 +10105,7 @@ var pullAt = flatRest(function(array2, indexes) { var length = array2 == null ? 0 : array2.length, result2 = baseAt(array2, indexes); basePullAt(array2, arrayMap2(indexes, function(index) { - return isIndex(index, length) ? +index : index; + return isIndex2(index, length) ? +index : index; }).sort(compareAscending)); return result2; }); @@ -10046,7 +10153,7 @@ var length = array2 == null ? 0 : array2.length; if (length) { var index = baseSortedIndex(array2, value); - if (index < length && eq(array2[index], value)) { + if (index < length && eq2(array2[index], value)) { return index; } } @@ -10062,7 +10169,7 @@ var length = array2 == null ? 0 : array2.length; if (length) { var index = baseSortedIndex(array2, value, true) - 1; - if (eq(array2[index], value)) { + if (eq2(array2[index], value)) { return index; } } @@ -10130,13 +10237,13 @@ return []; } var length = 0; - array2 = arrayFilter(array2, function(group) { + array2 = arrayFilter2(array2, function(group) { if (isArrayLikeObject(group)) { length = nativeMax2(group.length, length); return true; } }); - return baseTimes(length, function(index) { + return baseTimes2(length, function(index) { return arrayMap2(array2, baseProperty(index)); }); } @@ -10156,19 +10263,19 @@ return isArrayLikeObject(array2) ? baseDifference(array2, values2) : []; }); var xor = baseRest(function(arrays) { - return baseXor(arrayFilter(arrays, isArrayLikeObject)); + return baseXor(arrayFilter2(arrays, isArrayLikeObject)); }); var xorBy = baseRest(function(arrays) { var iteratee2 = last(arrays); if (isArrayLikeObject(iteratee2)) { iteratee2 = undefined2; } - return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee2, 2)); + return baseXor(arrayFilter2(arrays, isArrayLikeObject), getIteratee(iteratee2, 2)); }); var xorWith = baseRest(function(arrays) { var comparator = last(arrays); comparator = typeof comparator == "function" ? comparator : undefined2; - return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined2, comparator); + return baseXor(arrayFilter2(arrays, isArrayLikeObject), undefined2, comparator); }); var zip = baseRest(unzip); function zipObject(props, values2) { @@ -10198,7 +10305,7 @@ var length = paths.length, start2 = length ? paths[0] : 0, value = this.__wrapped__, interceptor = function(object) { return baseAt(object, paths); }; - if (length > 1 || this.__actions__.length || !(value instanceof LazyWrapper) || !isIndex(start2)) { + if (length > 1 || this.__actions__.length || !(value instanceof LazyWrapper) || !isIndex2(start2)) { return this.thru(interceptor); } value = value.slice(start2, +start2 + (length ? 1 : 0)); @@ -10268,7 +10375,7 @@ return baseWrapperValue(this.__wrapped__, this.__actions__); } var countBy = createAggregator(function(result2, value, key) { - if (hasOwnProperty2.call(result2, key)) { + if (hasOwnProperty10.call(result2, key)) { ++result2[key]; } else { baseAssignValue(result2, key, 1); @@ -10282,7 +10389,7 @@ return func(collection, getIteratee(predicate, 3)); } function filter2(collection, predicate) { - var func = isArray2(collection) ? arrayFilter : baseFilter; + var func = isArray2(collection) ? arrayFilter2 : baseFilter; return func(collection, getIteratee(predicate, 3)); } var find2 = createFind(findIndex); @@ -10306,14 +10413,14 @@ return func(collection, getIteratee(iteratee2, 3)); } var groupBy = createAggregator(function(result2, value, key) { - if (hasOwnProperty2.call(result2, key)) { + if (hasOwnProperty10.call(result2, key)) { result2[key].push(value); } else { baseAssignValue(result2, key, [value]); } }); function includes(collection, value, fromIndex, guard) { - collection = isArrayLike(collection) ? collection : values(collection); + collection = isArrayLike2(collection) ? collection : values(collection); fromIndex = fromIndex && !guard ? toInteger(fromIndex) : 0; var length = collection.length; if (fromIndex < 0) { @@ -10322,7 +10429,7 @@ return isString(collection) ? fromIndex <= length && collection.indexOf(value, fromIndex) > -1 : !!length && baseIndexOf(collection, value, fromIndex) > -1; } var invokeMap = baseRest(function(collection, path, args) { - var index = -1, isFunc = typeof path == "function", result2 = isArrayLike(collection) ? Array2(collection.length) : []; + var index = -1, isFunc = typeof path == "function", result2 = isArrayLike2(collection) ? Array2(collection.length) : []; baseEach(collection, function(value) { result2[++index] = isFunc ? apply(path, value, args) : baseInvoke(value, path, args); }); @@ -10362,7 +10469,7 @@ return func(collection, getIteratee(iteratee2, 4), accumulator, initAccum, baseEachRight); } function reject(collection, predicate) { - var func = isArray2(collection) ? arrayFilter : baseFilter; + var func = isArray2(collection) ? arrayFilter2 : baseFilter; return func(collection, negate(getIteratee(predicate, 3))); } function sample(collection) { @@ -10386,17 +10493,17 @@ if (collection == null) { return 0; } - if (isArrayLike(collection)) { + if (isArrayLike2(collection)) { return isString(collection) ? stringSize(collection) : collection.length; } - var tag = getTag(collection); - if (tag == mapTag || tag == setTag) { + var tag = getTag2(collection); + if (tag == mapTag4 || tag == setTag4) { return collection.size; } - return baseKeys(collection).length; + return baseKeys2(collection).length; } function some(collection, predicate, guard) { - var func = isArray2(collection) ? arraySome : baseSome; + var func = isArray2(collection) ? arraySome2 : baseSome; if (guard && isIterateeCall(collection, predicate, guard)) { predicate = undefined2; } @@ -10482,11 +10589,11 @@ if (typeof func != "function") { throw new TypeError2(FUNC_ERROR_TEXT3); } - wait = toNumber2(wait) || 0; - if (isObject2(options2)) { + wait = toNumber3(wait) || 0; + if (isObject3(options2)) { leading = !!options2.leading; maxing = "maxWait" in options2; - maxWait = maxing ? nativeMax2(toNumber2(options2.maxWait) || 0, wait) : maxWait; + maxWait = maxing ? nativeMax2(toNumber3(options2.maxWait) || 0, wait) : maxWait; trailing = "trailing" in options2 ? !!options2.trailing : trailing; } function invokeFunc(time) { @@ -10562,7 +10669,7 @@ return baseDelay(func, 1, args); }); var delay = baseRest(function(func, wait, args) { - return baseDelay(func, toNumber2(wait) || 0, args); + return baseDelay(func, toNumber3(wait) || 0, args); }); function flip(func) { return createWrap(func, WRAP_FLIP_FLAG); @@ -10580,10 +10687,10 @@ memoized.cache = cache.set(key, result2) || cache; return result2; }; - memoized.cache = new (memoize.Cache || MapCache)(); + memoized.cache = new (memoize.Cache || MapCache2)(); return memoized; } - memoize.Cache = MapCache; + memoize.Cache = MapCache2; function negate(predicate) { if (typeof predicate != "function") { throw new TypeError2(FUNC_ERROR_TEXT3); @@ -10607,7 +10714,7 @@ return before(2, func); } var overArgs = castRest(function(func, transforms) { - transforms = transforms.length == 1 && isArray2(transforms[0]) ? arrayMap2(transforms[0], baseUnary(getIteratee())) : arrayMap2(baseFlatten(transforms, 1), baseUnary(getIteratee())); + transforms = transforms.length == 1 && isArray2(transforms[0]) ? arrayMap2(transforms[0], baseUnary2(getIteratee())) : arrayMap2(baseFlatten(transforms, 1), baseUnary2(getIteratee())); var funcsLength = transforms.length; return baseRest(function(args) { var index = -1, length = nativeMin2(args.length, funcsLength); @@ -10643,7 +10750,7 @@ return baseRest(function(args) { var array2 = args[start2], otherArgs = castSlice(args, 0, start2); if (array2) { - arrayPush(otherArgs, array2); + arrayPush2(otherArgs, array2); } return apply(func, this, otherArgs); }); @@ -10653,7 +10760,7 @@ if (typeof func != "function") { throw new TypeError2(FUNC_ERROR_TEXT3); } - if (isObject2(options2)) { + if (isObject3(options2)) { leading = "leading" in options2 ? !!options2.leading : leading; trailing = "trailing" in options2 ? !!options2.trailing : trailing; } @@ -10691,33 +10798,33 @@ return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG, customizer); } function conformsTo(object, source) { - return source == null || baseConformsTo(object, source, keys(source)); + return source == null || baseConformsTo(object, source, keys2(source)); } - function eq(value, other) { + function eq2(value, other) { return value === other || value !== value && other !== other; } var gt = createRelationalOperation(baseGt); var gte = createRelationalOperation(function(value, other) { return value >= other; }); - var isArguments = baseIsArguments(function() { + var isArguments2 = baseIsArguments2(function() { return arguments; - }()) ? baseIsArguments : function(value) { - return isObjectLike2(value) && hasOwnProperty2.call(value, "callee") && !propertyIsEnumerable.call(value, "callee"); + }()) ? baseIsArguments2 : function(value) { + return isObjectLike2(value) && hasOwnProperty10.call(value, "callee") && !propertyIsEnumerable3.call(value, "callee"); }; var isArray2 = Array2.isArray; - var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer; - function isArrayLike(value) { - return value != null && isLength(value.length) && !isFunction(value); + var isArrayBuffer = nodeIsArrayBuffer ? baseUnary2(nodeIsArrayBuffer) : baseIsArrayBuffer; + function isArrayLike2(value) { + return value != null && isLength2(value.length) && !isFunction2(value); } function isArrayLikeObject(value) { - return isObjectLike2(value) && isArrayLike(value); + return isObjectLike2(value) && isArrayLike2(value); } function isBoolean(value) { - return value === true || value === false || isObjectLike2(value) && baseGetTag2(value) == boolTag; + return value === true || value === false || isObjectLike2(value) && baseGetTag2(value) == boolTag3; } - var isBuffer = nativeIsBuffer || stubFalse; - var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate; + var isBuffer2 = nativeIsBuffer2 || stubFalse2; + var isDate = nodeIsDate ? baseUnary2(nodeIsDate) : baseIsDate; function isElement2(value) { return isObjectLike2(value) && value.nodeType === 1 && !isPlainObject(value); } @@ -10725,62 +10832,62 @@ if (value == null) { return true; } - if (isArrayLike(value) && (isArray2(value) || typeof value == "string" || typeof value.splice == "function" || isBuffer(value) || isTypedArray(value) || isArguments(value))) { + if (isArrayLike2(value) && (isArray2(value) || typeof value == "string" || typeof value.splice == "function" || isBuffer2(value) || isTypedArray2(value) || isArguments2(value))) { return !value.length; } - var tag = getTag(value); - if (tag == mapTag || tag == setTag) { + var tag = getTag2(value); + if (tag == mapTag4 || tag == setTag4) { return !value.size; } - if (isPrototype(value)) { - return !baseKeys(value).length; + if (isPrototype2(value)) { + return !baseKeys2(value).length; } for (var key in value) { - if (hasOwnProperty2.call(value, key)) { + if (hasOwnProperty10.call(value, key)) { return false; } } return true; } - function isEqual(value, other) { - return baseIsEqual(value, other); + function isEqual4(value, other) { + return baseIsEqual2(value, other); } function isEqualWith(value, other, customizer) { customizer = typeof customizer == "function" ? customizer : undefined2; var result2 = customizer ? customizer(value, other) : undefined2; - return result2 === undefined2 ? baseIsEqual(value, other, undefined2, customizer) : !!result2; + return result2 === undefined2 ? baseIsEqual2(value, other, undefined2, customizer) : !!result2; } function isError(value) { if (!isObjectLike2(value)) { return false; } var tag = baseGetTag2(value); - return tag == errorTag || tag == domExcTag || typeof value.message == "string" && typeof value.name == "string" && !isPlainObject(value); + return tag == errorTag3 || tag == domExcTag || typeof value.message == "string" && typeof value.name == "string" && !isPlainObject(value); } function isFinite2(value) { return typeof value == "number" && nativeIsFinite(value); } - function isFunction(value) { - if (!isObject2(value)) { + function isFunction2(value) { + if (!isObject3(value)) { return false; } var tag = baseGetTag2(value); - return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; + return tag == funcTag3 || tag == genTag2 || tag == asyncTag2 || tag == proxyTag2; } function isInteger(value) { return typeof value == "number" && value == toInteger(value); } - function isLength(value) { - return typeof value == "number" && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; + function isLength2(value) { + return typeof value == "number" && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER3; } - function isObject2(value) { - var type3 = typeof value; - return value != null && (type3 == "object" || type3 == "function"); + function isObject3(value) { + var type2 = typeof value; + return value != null && (type2 == "object" || type2 == "function"); } function isObjectLike2(value) { return value != null && typeof value == "object"; } - var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap; + var isMap = nodeIsMap ? baseUnary2(nodeIsMap) : baseIsMap; function isMatch(object, source) { return object === source || baseIsMatch(object, source, getMatchData(source)); } @@ -10795,7 +10902,7 @@ if (isMaskable(value)) { throw new Error2(CORE_ERROR_TEXT); } - return baseIsNative(value); + return baseIsNative2(value); } function isNull(value) { return value === null; @@ -10804,36 +10911,36 @@ return value == null; } function isNumber2(value) { - return typeof value == "number" || isObjectLike2(value) && baseGetTag2(value) == numberTag; + return typeof value == "number" || isObjectLike2(value) && baseGetTag2(value) == numberTag3; } function isPlainObject(value) { - if (!isObjectLike2(value) || baseGetTag2(value) != objectTag) { + if (!isObjectLike2(value) || baseGetTag2(value) != objectTag4) { return false; } var proto = getPrototype(value); if (proto === null) { return true; } - var Ctor = hasOwnProperty2.call(proto, "constructor") && proto.constructor; - return typeof Ctor == "function" && Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString; + var Ctor = hasOwnProperty10.call(proto, "constructor") && proto.constructor; + return typeof Ctor == "function" && Ctor instanceof Ctor && funcToString3.call(Ctor) == objectCtorString; } - var isRegExp = nodeIsRegExp ? baseUnary(nodeIsRegExp) : baseIsRegExp; + var isRegExp = nodeIsRegExp ? baseUnary2(nodeIsRegExp) : baseIsRegExp; function isSafeInteger(value) { - return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER; + return isInteger(value) && value >= -MAX_SAFE_INTEGER3 && value <= MAX_SAFE_INTEGER3; } - var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet; + var isSet = nodeIsSet ? baseUnary2(nodeIsSet) : baseIsSet; function isString(value) { - return typeof value == "string" || !isArray2(value) && isObjectLike2(value) && baseGetTag2(value) == stringTag; + return typeof value == "string" || !isArray2(value) && isObjectLike2(value) && baseGetTag2(value) == stringTag3; } function isSymbol2(value) { - return typeof value == "symbol" || isObjectLike2(value) && baseGetTag2(value) == symbolTag2; + return typeof value == "symbol" || isObjectLike2(value) && baseGetTag2(value) == symbolTag3; } - var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray; + var isTypedArray2 = nodeIsTypedArray2 ? baseUnary2(nodeIsTypedArray2) : baseIsTypedArray2; function isUndefined(value) { return value === undefined2; } function isWeakMap(value) { - return isObjectLike2(value) && getTag(value) == weakMapTag; + return isObjectLike2(value) && getTag2(value) == weakMapTag3; } function isWeakSet(value) { return isObjectLike2(value) && baseGetTag2(value) == weakSetTag; @@ -10846,20 +10953,20 @@ if (!value) { return []; } - if (isArrayLike(value)) { + if (isArrayLike2(value)) { return isString(value) ? stringToArray(value) : copyArray(value); } if (symIterator && value[symIterator]) { return iteratorToArray(value[symIterator]()); } - var tag = getTag(value), func = tag == mapTag ? mapToArray : tag == setTag ? setToArray : values; + var tag = getTag2(value), func = tag == mapTag4 ? mapToArray2 : tag == setTag4 ? setToArray2 : values; return func(value); } function toFinite(value) { if (!value) { return value === 0 ? value : 0; } - value = toNumber2(value); + value = toNumber3(value); if (value === INFINITY2 || value === -INFINITY2) { var sign2 = value < 0 ? -1 : 1; return sign2 * MAX_INTEGER; @@ -10873,16 +10980,16 @@ function toLength(value) { return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0; } - function toNumber2(value) { + function toNumber3(value) { if (typeof value == "number") { return value; } if (isSymbol2(value)) { return NAN2; } - if (isObject2(value)) { + if (isObject3(value)) { var other = typeof value.valueOf == "function" ? value.valueOf() : value; - value = isObject2(other) ? other + "" : other; + value = isObject3(other) ? other + "" : other; } if (typeof value != "string") { return value === 0 ? value : +value; @@ -10895,18 +11002,18 @@ return copyObject(value, keysIn(value)); } function toSafeInteger(value) { - return value ? baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER) : value === 0 ? value : 0; + return value ? baseClamp(toInteger(value), -MAX_SAFE_INTEGER3, MAX_SAFE_INTEGER3) : value === 0 ? value : 0; } function toString2(value) { return value == null ? "" : baseToString2(value); } var assign = createAssigner(function(object, source) { - if (isPrototype(source) || isArrayLike(source)) { - copyObject(source, keys(source), object); + if (isPrototype2(source) || isArrayLike2(source)) { + copyObject(source, keys2(source), object); return; } for (var key in source) { - if (hasOwnProperty2.call(source, key)) { + if (hasOwnProperty10.call(source, key)) { assignValue(object, key, source[key]); } } @@ -10918,7 +11025,7 @@ copyObject(source, keysIn(source), object, customizer); }); var assignWith = createAssigner(function(object, source, srcIndex, customizer) { - copyObject(source, keys(source), object, customizer); + copyObject(source, keys2(source), object, customizer); }); var at = flatRest(baseAt); function create2(prototype, properties) { @@ -10941,7 +11048,7 @@ while (++propsIndex < propsLength) { var key = props[propsIndex]; var value = object[key]; - if (value === undefined2 || eq(value, objectProto3[key]) && !hasOwnProperty2.call(object, key)) { + if (value === undefined2 || eq2(value, objectProto13[key]) && !hasOwnProperty10.call(object, key)) { object[key] = source[key]; } } @@ -10971,7 +11078,7 @@ return object && baseForOwnRight(object, getIteratee(iteratee2, 3)); } function functions(object) { - return object == null ? [] : baseFunctions(object, keys(object)); + return object == null ? [] : baseFunctions(object, keys2(object)); } function functionsIn(object) { return object == null ? [] : baseFunctions(object, keysIn(object)); @@ -10996,18 +11103,18 @@ if (value != null && typeof value.toString != "function") { value = nativeObjectToString3.call(value); } - if (hasOwnProperty2.call(result2, value)) { + if (hasOwnProperty10.call(result2, value)) { result2[value].push(key); } else { result2[value] = [key]; } }, getIteratee); var invoke = baseRest(baseInvoke); - function keys(object) { - return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); + function keys2(object) { + return isArrayLike2(object) ? arrayLikeKeys2(object) : baseKeys2(object); } function keysIn(object) { - return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object); + return isArrayLike2(object) ? arrayLikeKeys2(object, true) : baseKeysIn(object); } function mapKeys(object, iteratee2) { var result2 = {}; @@ -11025,7 +11132,7 @@ }); return result2; } - var merge3 = createAssigner(function(object, source, srcIndex) { + var merge2 = createAssigner(function(object, source, srcIndex) { baseMerge(object, source, srcIndex); }); var mergeWith = createAssigner(function(object, source, srcIndex, customizer) { @@ -11083,7 +11190,7 @@ index = length; value = defaultValue; } - object = isFunction(value) ? value.call(object) : value; + object = isFunction2(value) ? value.call(object) : value; } return object; } @@ -11094,17 +11201,17 @@ customizer = typeof customizer == "function" ? customizer : undefined2; return object == null ? object : baseSet(object, path, value, customizer); } - var toPairs = createToPairs(keys); + var toPairs = createToPairs(keys2); var toPairsIn = createToPairs(keysIn); function transform2(object, iteratee2, accumulator) { - var isArr = isArray2(object), isArrLike = isArr || isBuffer(object) || isTypedArray(object); + var isArr = isArray2(object), isArrLike = isArr || isBuffer2(object) || isTypedArray2(object); iteratee2 = getIteratee(iteratee2, 4); if (accumulator == null) { var Ctor = object && object.constructor; if (isArrLike) { accumulator = isArr ? new Ctor() : []; - } else if (isObject2(object)) { - accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {}; + } else if (isObject3(object)) { + accumulator = isFunction2(Ctor) ? baseCreate(getPrototype(object)) : {}; } else { accumulator = {}; } @@ -11125,7 +11232,7 @@ return object == null ? object : baseUpdate(object, path, castFunction(updater), customizer); } function values(object) { - return object == null ? [] : baseValues(object, keys(object)); + return object == null ? [] : baseValues(object, keys2(object)); } function valuesIn(object) { return object == null ? [] : baseValues(object, keysIn(object)); @@ -11136,14 +11243,14 @@ lower2 = undefined2; } if (upper !== undefined2) { - upper = toNumber2(upper); + upper = toNumber3(upper); upper = upper === upper ? upper : 0; } if (lower2 !== undefined2) { - lower2 = toNumber2(lower2); + lower2 = toNumber3(lower2); lower2 = lower2 === lower2 ? lower2 : 0; } - return baseClamp(toNumber2(number3), lower2, upper); + return baseClamp(toNumber3(number3), lower2, upper); } function inRange(number3, start2, end) { start2 = toFinite(start2); @@ -11153,7 +11260,7 @@ } else { end = toFinite(end); } - number3 = toNumber2(number3); + number3 = toNumber3(number3); return baseInRange(number3, start2, end); } function random(lower2, upper, floating) { @@ -11218,7 +11325,7 @@ } function escapeRegExp(string) { string = toString2(string); - return string && reHasRegExpChar.test(string) ? string.replace(reRegExpChar, "\\$&") : string; + return string && reHasRegExpChar.test(string) ? string.replace(reRegExpChar2, "\\$&") : string; } var kebabCase = createCompounder(function(result2, word, index) { return result2 + (index ? "-" : "") + word.toLowerCase(); @@ -11305,13 +11412,13 @@ } string = toString2(string); options2 = assignInWith({}, options2, settings, customDefaultsAssignIn); - var imports = assignInWith({}, options2.imports, settings.imports, customDefaultsAssignIn), importsKeys = keys(imports), importsValues = baseValues(imports, importsKeys); + var imports = assignInWith({}, options2.imports, settings.imports, customDefaultsAssignIn), importsKeys = keys2(imports), importsValues = baseValues(imports, importsKeys); var isEscaping, isEvaluating, index = 0, interpolate = options2.interpolate || reNoMatch, source = "__p += '"; var reDelimiters = RegExp2( (options2.escape || reNoMatch).source + "|" + interpolate.source + "|" + (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + "|" + (options2.evaluate || reNoMatch).source + "|$", "g" ); - var sourceURL = "//# sourceURL=" + (hasOwnProperty2.call(options2, "sourceURL") ? (options2.sourceURL + "").replace(/\s/g, " ") : "lodash.templateSources[" + ++templateCounter + "]") + "\n"; + var sourceURL = "//# sourceURL=" + (hasOwnProperty10.call(options2, "sourceURL") ? (options2.sourceURL + "").replace(/\s/g, " ") : "lodash.templateSources[" + ++templateCounter + "]") + "\n"; string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) { interpolateValue || (interpolateValue = esTemplateValue); source += string.slice(index, offset).replace(reUnescapedString, escapeStringChar); @@ -11330,7 +11437,7 @@ return match; }); source += "';\n"; - var variable = hasOwnProperty2.call(options2, "variable") && options2.variable; + var variable = hasOwnProperty10.call(options2, "variable") && options2.variable; if (!variable) { source = "with (obj) {\n" + source + "\n}\n"; } else if (reForbiddenIdentifierChars.test(variable)) { @@ -11388,7 +11495,7 @@ } function truncate(string, options2) { var length = DEFAULT_TRUNC_LENGTH, omission = DEFAULT_TRUNC_OMISSION; - if (isObject2(options2)) { + if (isObject3(options2)) { var separator = "separator" in options2 ? options2.separator : separator; length = "length" in options2 ? toInteger(options2.length) : length; omission = "omission" in options2 ? baseToString2(options2.omission) : omission; @@ -11517,14 +11624,14 @@ }; }); function mixin(object, source, options2) { - var props = keys(source), methodNames = baseFunctions(source, props); - if (options2 == null && !(isObject2(source) && (methodNames.length || !props.length))) { + var props = keys2(source), methodNames = baseFunctions(source, props); + if (options2 == null && !(isObject3(source) && (methodNames.length || !props.length))) { options2 = source; source = object; object = this; - methodNames = baseFunctions(source, keys(source)); + methodNames = baseFunctions(source, keys2(source)); } - var chain2 = !(isObject2(options2) && "chain" in options2) || !!options2.chain, isFunc = isFunction(object); + var chain2 = !(isObject3(options2) && "chain" in options2) || !!options2.chain, isFunc = isFunction2(object); arrayEach(methodNames, function(methodName) { var func = source[methodName]; object[methodName] = func; @@ -11537,7 +11644,7 @@ result2.__chain__ = chainAll; return result2; } - return func.apply(object, arrayPush([this.value()], arguments)); + return func.apply(object, arrayPush2([this.value()], arguments)); }; } }); @@ -11559,7 +11666,7 @@ } var over = createOver(arrayMap2); var overEvery = createOver(arrayEvery); - var overSome = createOver(arraySome); + var overSome = createOver(arraySome2); function property(path) { return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path); } @@ -11570,10 +11677,10 @@ } var range3 = createRange(); var rangeRight = createRange(true); - function stubArray() { + function stubArray2() { return []; } - function stubFalse() { + function stubFalse2() { return false; } function stubObject() { @@ -11587,13 +11694,13 @@ } function times(n2, iteratee2) { n2 = toInteger(n2); - if (n2 < 1 || n2 > MAX_SAFE_INTEGER) { + if (n2 < 1 || n2 > MAX_SAFE_INTEGER3) { return []; } var index = MAX_ARRAY_LENGTH, length = nativeMin2(n2, MAX_ARRAY_LENGTH); iteratee2 = getIteratee(iteratee2); n2 -= MAX_ARRAY_LENGTH; - var result2 = baseTimes(length, iteratee2); + var result2 = baseTimes2(length, iteratee2); while (++index < n2) { iteratee2(index); } @@ -11707,7 +11814,7 @@ lodash.invokeMap = invokeMap; lodash.iteratee = iteratee; lodash.keyBy = keyBy; - lodash.keys = keys; + lodash.keys = keys2; lodash.keysIn = keysIn; lodash.map = map2; lodash.mapKeys = mapKeys; @@ -11715,7 +11822,7 @@ lodash.matches = matches; lodash.matchesProperty = matchesProperty; lodash.memoize = memoize; - lodash.merge = merge3; + lodash.merge = merge2; lodash.mergeWith = mergeWith; lodash.method = method; lodash.methodOf = methodOf; @@ -11817,7 +11924,7 @@ lodash.defaultTo = defaultTo; lodash.divide = divide; lodash.endsWith = endsWith; - lodash.eq = eq; + lodash.eq = eq2; lodash.escape = escape6; lodash.escapeRegExp = escapeRegExp; lodash.every = every; @@ -11845,23 +11952,23 @@ lodash.indexOf = indexOf; lodash.inRange = inRange; lodash.invoke = invoke; - lodash.isArguments = isArguments; + lodash.isArguments = isArguments2; lodash.isArray = isArray2; lodash.isArrayBuffer = isArrayBuffer; - lodash.isArrayLike = isArrayLike; + lodash.isArrayLike = isArrayLike2; lodash.isArrayLikeObject = isArrayLikeObject; lodash.isBoolean = isBoolean; - lodash.isBuffer = isBuffer; + lodash.isBuffer = isBuffer2; lodash.isDate = isDate; lodash.isElement = isElement2; lodash.isEmpty = isEmpty; - lodash.isEqual = isEqual; + lodash.isEqual = isEqual4; lodash.isEqualWith = isEqualWith; lodash.isError = isError; lodash.isFinite = isFinite2; - lodash.isFunction = isFunction; + lodash.isFunction = isFunction2; lodash.isInteger = isInteger; - lodash.isLength = isLength; + lodash.isLength = isLength2; lodash.isMap = isMap; lodash.isMatch = isMatch; lodash.isMatchWith = isMatchWith; @@ -11870,7 +11977,7 @@ lodash.isNil = isNil; lodash.isNull = isNull; lodash.isNumber = isNumber2; - lodash.isObject = isObject2; + lodash.isObject = isObject3; lodash.isObjectLike = isObjectLike2; lodash.isPlainObject = isPlainObject; lodash.isRegExp = isRegExp; @@ -11878,7 +11985,7 @@ lodash.isSet = isSet; lodash.isString = isString; lodash.isSymbol = isSymbol2; - lodash.isTypedArray = isTypedArray; + lodash.isTypedArray = isTypedArray2; lodash.isUndefined = isUndefined; lodash.isWeakMap = isWeakMap; lodash.isWeakSet = isWeakSet; @@ -11896,8 +12003,8 @@ lodash.meanBy = meanBy; lodash.min = min3; lodash.minBy = minBy; - lodash.stubArray = stubArray; - lodash.stubFalse = stubFalse; + lodash.stubArray = stubArray2; + lodash.stubFalse = stubFalse2; lodash.stubObject = stubObject; lodash.stubString = stubString; lodash.stubTrue = stubTrue; @@ -11939,7 +12046,7 @@ lodash.toInteger = toInteger; lodash.toLength = toLength; lodash.toLower = toLower; - lodash.toNumber = toNumber2; + lodash.toNumber = toNumber3; lodash.toSafeInteger = toSafeInteger; lodash.toString = toString2; lodash.toUpper = toUpper; @@ -11957,7 +12064,7 @@ mixin(lodash, function() { var source = {}; baseForOwn(lodash, function(func, methodName) { - if (!hasOwnProperty2.call(lodash.prototype, methodName)) { + if (!hasOwnProperty10.call(lodash.prototype, methodName)) { source[methodName] = func; } }); @@ -11986,12 +12093,12 @@ }; }); arrayEach(["filter", "map", "takeWhile"], function(methodName, index) { - var type3 = index + 1, isFilter = type3 == LAZY_FILTER_FLAG || type3 == LAZY_WHILE_FLAG; + var type2 = index + 1, isFilter = type2 == LAZY_FILTER_FLAG || type2 == LAZY_WHILE_FLAG; LazyWrapper.prototype[methodName] = function(iteratee2) { var result2 = this.clone(); result2.__iteratees__.push({ "iteratee": getIteratee(iteratee2, 3), - "type": type3 + "type": type2 }); result2.__filtered__ = result2.__filtered__ || isFilter; return result2; @@ -12060,7 +12167,7 @@ lodash.prototype[methodName] = function() { var value = this.__wrapped__, args = isTaker ? [1] : arguments, isLazy = value instanceof LazyWrapper, iteratee2 = args[0], useLazy = isLazy || isArray2(value); var interceptor = function(value2) { - var result3 = lodashFunc.apply(lodash, arrayPush([value2], args)); + var result3 = lodashFunc.apply(lodash, arrayPush2([value2], args)); return isTaker && chainAll ? result3[0] : result3; }; if (useLazy && checkIteratee && typeof iteratee2 == "function" && iteratee2.length != 1) { @@ -12081,7 +12188,7 @@ }; }); arrayEach(["pop", "push", "shift", "sort", "splice", "unshift"], function(methodName) { - var func = arrayProto[methodName], chainName = /^(?:push|sort|unshift)$/.test(methodName) ? "tap" : "thru", retUnwrapped = /^(?:pop|shift)$/.test(methodName); + var func = arrayProto2[methodName], chainName = /^(?:push|sort|unshift)$/.test(methodName) ? "tap" : "thru", retUnwrapped = /^(?:pop|shift)$/.test(methodName); lodash.prototype[methodName] = function() { var args = arguments; if (retUnwrapped && !this.__chain__) { @@ -12097,7 +12204,7 @@ var lodashFunc = lodash[methodName]; if (lodashFunc) { var key = lodashFunc.name + ""; - if (!hasOwnProperty2.call(realNames, key)) { + if (!hasOwnProperty10.call(realNames, key)) { realNames[key] = []; } realNames[key].push({ "name": methodName, "func": lodashFunc }); @@ -12129,9 +12236,9 @@ define(function() { return _; }); - } else if (freeModule) { - (freeModule.exports = _)._ = _; - freeExports._ = _; + } else if (freeModule3) { + (freeModule3.exports = _)._ = _; + freeExports3._ = _; } else { root3._ = _; } @@ -12139,6 +12246,51 @@ } }); + // node_modules/fast-deep-equal/index.js + var require_fast_deep_equal = __commonJS({ + "node_modules/fast-deep-equal/index.js"(exports2, module2) { + "use strict"; + module2.exports = function equal(a, b) { + if (a === b) + return true; + if (a && b && typeof a == "object" && typeof b == "object") { + if (a.constructor !== b.constructor) + return false; + var length, i2, keys2; + if (Array.isArray(a)) { + length = a.length; + if (length != b.length) + return false; + for (i2 = length; i2-- !== 0; ) + if (!equal(a[i2], b[i2])) + return false; + return true; + } + if (a.constructor === RegExp) + return a.source === b.source && a.flags === b.flags; + if (a.valueOf !== Object.prototype.valueOf) + return a.valueOf() === b.valueOf(); + if (a.toString !== Object.prototype.toString) + return a.toString() === b.toString(); + keys2 = Object.keys(a); + length = keys2.length; + if (length !== Object.keys(b).length) + return false; + for (i2 = length; i2-- !== 0; ) + if (!Object.prototype.hasOwnProperty.call(b, keys2[i2])) + return false; + for (i2 = length; i2-- !== 0; ) { + var key = keys2[i2]; + if (!equal(a[key], b[key])) + return false; + } + return true; + } + return a !== a && b !== b; + }; + } + }); + // node_modules/rbush/rbush.min.js var require_rbush_min = __commonJS({ "node_modules/rbush/rbush.min.js"(exports2, module2) { @@ -12482,6 +12634,7 @@ destroy: function() { this.buf = null; }, + // === READING ================================================================= readFields: function(readField, result, end) { end = end || this.length; while (this.pos < end) { @@ -12506,6 +12659,7 @@ this.pos += 4; return val; }, + // 64-bit int handling is based on github.com/dpw/node-buffer-more-ints (MIT-licensed) readFixed64: function() { var val = readUInt32(this.buf, this.pos) + readUInt32(this.buf, this.pos + 4) * SHIFT_LEFT_32; this.pos += 8; @@ -12572,6 +12726,7 @@ this.pos = end; return buffer; }, + // verbose for performance reasons; doesn't affect gzipped size readPackedVarint: function(arr, isSigned) { if (this.type !== Pbf.Bytes) return arr.push(this.readVarint(isSigned)); @@ -12654,21 +12809,22 @@ return arr; }, skip: function(val) { - var type3 = val & 7; - if (type3 === Pbf.Varint) + var type2 = val & 7; + if (type2 === Pbf.Varint) while (this.buf[this.pos++] > 127) { } - else if (type3 === Pbf.Bytes) + else if (type2 === Pbf.Bytes) this.pos = this.readVarint() + this.pos; - else if (type3 === Pbf.Fixed32) + else if (type2 === Pbf.Fixed32) this.pos += 4; - else if (type3 === Pbf.Fixed64) + else if (type2 === Pbf.Fixed64) this.pos += 8; else - throw new Error("Unimplemented type: " + type3); + throw new Error("Unimplemented type: " + type2); }, - writeTag: function(tag, type3) { - this.writeVarint(tag << 3 | type3); + // === WRITING ================================================================= + writeTag: function(tag, type2) { + this.writeVarint(tag << 3 | type2); }, realloc: function(min3) { var length = this.length || 16; @@ -13121,67 +13277,190 @@ this.y = y; } Point.prototype = { + /** + * Clone this point, returning a new point that can be modified + * without affecting the old one. + * @return {Point} the clone + */ clone: function() { return new Point(this.x, this.y); }, + /** + * Add this point's x & y coordinates to another point, + * yielding a new point. + * @param {Point} p the other point + * @return {Point} output point + */ add: function(p) { return this.clone()._add(p); }, + /** + * Subtract this point's x & y coordinates to from point, + * yielding a new point. + * @param {Point} p the other point + * @return {Point} output point + */ sub: function(p) { return this.clone()._sub(p); }, + /** + * Multiply this point's x & y coordinates by point, + * yielding a new point. + * @param {Point} p the other point + * @return {Point} output point + */ multByPoint: function(p) { return this.clone()._multByPoint(p); }, + /** + * Divide this point's x & y coordinates by point, + * yielding a new point. + * @param {Point} p the other point + * @return {Point} output point + */ divByPoint: function(p) { return this.clone()._divByPoint(p); }, + /** + * Multiply this point's x & y coordinates by a factor, + * yielding a new point. + * @param {Point} k factor + * @return {Point} output point + */ mult: function(k) { return this.clone()._mult(k); }, + /** + * Divide this point's x & y coordinates by a factor, + * yielding a new point. + * @param {Point} k factor + * @return {Point} output point + */ div: function(k) { return this.clone()._div(k); }, + /** + * Rotate this point around the 0, 0 origin by an angle a, + * given in radians + * @param {Number} a angle to rotate around, in radians + * @return {Point} output point + */ rotate: function(a) { return this.clone()._rotate(a); }, + /** + * Rotate this point around p point by an angle a, + * given in radians + * @param {Number} a angle to rotate around, in radians + * @param {Point} p Point to rotate around + * @return {Point} output point + */ rotateAround: function(a, p) { return this.clone()._rotateAround(a, p); }, + /** + * Multiply this point by a 4x1 transformation matrix + * @param {Array} m transformation matrix + * @return {Point} output point + */ matMult: function(m) { return this.clone()._matMult(m); }, + /** + * Calculate this point but as a unit vector from 0, 0, meaning + * that the distance from the resulting point to the 0, 0 + * coordinate will be equal to 1 and the angle from the resulting + * point to the 0, 0 coordinate will be the same as before. + * @return {Point} unit vector point + */ unit: function() { return this.clone()._unit(); }, + /** + * Compute a perpendicular point, where the new y coordinate + * is the old x coordinate and the new x coordinate is the old y + * coordinate multiplied by -1 + * @return {Point} perpendicular point + */ perp: function() { return this.clone()._perp(); }, + /** + * Return a version of this point with the x & y coordinates + * rounded to integers. + * @return {Point} rounded point + */ round: function() { return this.clone()._round(); }, + /** + * Return the magitude of this point: this is the Euclidean + * distance from the 0, 0 coordinate to this point's x and y + * coordinates. + * @return {Number} magnitude + */ mag: function() { return Math.sqrt(this.x * this.x + this.y * this.y); }, + /** + * Judge whether this point is equal to another point, returning + * true or false. + * @param {Point} other the other point + * @return {boolean} whether the points are equal + */ equals: function(other) { return this.x === other.x && this.y === other.y; }, + /** + * Calculate the distance from this point to another point + * @param {Point} p the other point + * @return {Number} distance + */ dist: function(p) { return Math.sqrt(this.distSqr(p)); }, + /** + * Calculate the distance from this point to another point, + * without the square root step. Useful if you're comparing + * relative distances. + * @param {Point} p the other point + * @return {Number} distance + */ distSqr: function(p) { var dx = p.x - this.x, dy = p.y - this.y; return dx * dx + dy * dy; }, + /** + * Get the angle from the 0, 0 coordinate to this point, in radians + * coordinates. + * @return {Number} angle + */ angle: function() { return Math.atan2(this.y, this.x); }, + /** + * Get the angle from this point to another point, in radians + * @param {Point} b the other point + * @return {Number} angle + */ angleTo: function(b) { return Math.atan2(this.y - b.y, this.x - b.x); }, + /** + * Get the angle between this point and another point, in radians + * @param {Point} b the other point + * @return {Number} angle + */ angleWith: function(b) { return this.angleWithSep(b.x, b.y); }, + /* + * Find the angle of the two vectors, solving the formula for + * the cross product a x b = |a||b|sin(θ) for θ. + * @param {Number} x the x-coordinate + * @param {Number} y the y-coordinate + * @return {Number} the angle in radians + */ angleWithSep: function(x, y) { return Math.atan2( this.x * y - this.y * x, @@ -13270,13 +13549,13 @@ "use strict"; var Point = require_point_geometry(); module2.exports = VectorTileFeature; - function VectorTileFeature(pbf, end, extent, keys, values) { + function VectorTileFeature(pbf, end, extent, keys2, values) { this.properties = {}; this.extent = extent; this.type = 0; this._pbf = pbf; this._geometry = -1; - this._keys = keys; + this._keys = keys2; this._values = values; pbf.readFields(readFeature, this, end); } @@ -13359,7 +13638,7 @@ return [x12, y12, x2, y2]; }; VectorTileFeature.prototype.toGeoJSON = function(x, y, z) { - var size = this.extent * Math.pow(2, z), x05 = this.extent * x, y05 = this.extent * y, coords = this.loadGeometry(), type3 = VectorTileFeature.types[this.type], i2, j2; + var size = this.extent * Math.pow(2, z), x05 = this.extent * x, y05 = this.extent * y, coords = this.loadGeometry(), type2 = VectorTileFeature.types[this.type], i2, j2; function project(line) { for (var j3 = 0; j3 < line.length; j3++) { var p = line[j3], y2 = 180 - (p.y + y05) * 360 / size; @@ -13395,12 +13674,12 @@ if (coords.length === 1) { coords = coords[0]; } else { - type3 = "Multi" + type3; + type2 = "Multi" + type2; } var result = { type: "Feature", geometry: { - type: type3, + type: type2, coordinates: coords }, properties: this.properties @@ -13571,10 +13850,10 @@ throw new TypeError("Converting circular structure to JSON"); } var seenIndex = seen.push(node) - 1; - var keys = Object.keys(node).sort(cmp && cmp(node)); + var keys2 = Object.keys(node).sort(cmp && cmp(node)); out = ""; - for (i2 = 0; i2 < keys.length; i2++) { - var key = keys[i2]; + for (i2 = 0; i2 < keys2.length; i2++) { + var key = keys2[i2]; var value = stringify3(node[key]); if (!value) continue; @@ -13698,8 +13977,8 @@ map: map2, pluck, isList, - isFunction, - isObject: isObject2, + isFunction: isFunction2, + isObject: isObject3, Global }; function make_assign() { @@ -13786,10 +14065,10 @@ function isList(val) { return val != null && typeof val != "function" && typeof val.length == "number"; } - function isFunction(val) { + function isFunction2(val) { return val && {}.toString.call(val) === "[object Function]"; } - function isObject2(val) { + function isObject3(val) { return val && {}.toString.call(val) === "[object Object]"; } } @@ -13805,18 +14084,22 @@ var bind = util.bind; var create2 = util.create; var isList = util.isList; - var isFunction = util.isFunction; - var isObject2 = util.isObject; + var isFunction2 = util.isFunction; + var isObject3 = util.isObject; module2.exports = { createStore }; var storeAPI = { version: "2.0.12", enabled: false, + // get returns the value of the given key. If that value + // is undefined, it returns optionalDefaultValue instead. get: function(key, optionalDefaultValue) { var data = this.storage.read(this._namespacePrefix + key); return this._deserialize(data, optionalDefaultValue); }, + // set will store the given value at key and returns value. + // Calling set with value === undefined is equivalent to calling remove. set: function(key, value) { if (value === void 0) { return this.remove(key); @@ -13824,21 +14107,31 @@ this.storage.write(this._namespacePrefix + key, this._serialize(value)); return value; }, + // remove deletes the key and value stored at the given key. remove: function(key) { this.storage.remove(this._namespacePrefix + key); }, + // each will call the given callback once for each key-value pair + // in this store. each: function(callback) { var self2 = this; this.storage.each(function(val, namespacedKey) { callback.call(self2, self2._deserialize(val), (namespacedKey || "").replace(self2._namespaceRegexp, "")); }); }, + // clearAll will remove all the stored key-value pairs in this store. clearAll: function() { this.storage.clearAll(); }, + // additional functionality that can't live in plugins + // --------------------------------------------------- + // hasNamespace returns true if this store instance has the given namespace. hasNamespace: function(namespace) { return this._namespacePrefix == "__storejs_" + namespace + "_"; }, + // createStore creates a store.js instance with the first + // functioning storage in the list of storage candidates, + // and applies the the given mixins to the instance. createStore: function() { return createStore.apply(this, arguments); }, @@ -13944,20 +14237,23 @@ return; } this.plugins.push(plugin); - if (!isFunction(plugin)) { + if (!isFunction2(plugin)) { throw new Error("Plugins must be function values that return objects"); } var pluginProperties = plugin.call(this); - if (!isObject2(pluginProperties)) { + if (!isObject3(pluginProperties)) { throw new Error("Plugins must return an object of function properties"); } each(pluginProperties, function(pluginFnProp, propName) { - if (!isFunction(pluginFnProp)) { + if (!isFunction2(pluginFnProp)) { throw new Error("Bad plugin property: " + propName + " from plugin " + plugin.name + ". Plugins should only return functions."); } self2._assignPluginFnProp(pluginFnProp, propName); }); }, + // Put deprecated properties in the private API, so as to not expose it to accidential + // discovery through inspection of the store object. + // Deprecated: addStorage addStorage: function(storage) { _warn("store.addStorage(storage) is deprecated. Use createStore([storages])"); this._addStorage(storage); @@ -13968,7 +14264,7 @@ }); store2.raw = {}; each(store2, function(prop, propName) { - if (isFunction(prop)) { + if (isFunction2(prop)) { store2.raw[propName] = bind(store2, prop); } }); @@ -14287,6 +14583,7 @@ var require_all = __commonJS({ "node_modules/store/storages/all.js"(exports2, module2) { module2.exports = [ + // Listed in order of usage preference require_localStorage(), require_oldFF_globalStorage(), require_oldIE_userDataStorage(), @@ -14401,6 +14698,7 @@ } if (typeof JSON.stringify !== "function") { meta = { + // table of character substitutions "\b": "\\b", " ": "\\t", "\n": "\\n", @@ -14807,10 +15105,10 @@ if (options2.cache === "no-store" || options2.cache === "no-cache") { var reParamSearch = /([?&])_=[^&]*/; if (reParamSearch.test(this.url)) { - this.url = this.url.replace(reParamSearch, "$1_=" + new Date().getTime()); + this.url = this.url.replace(reParamSearch, "$1_=" + (/* @__PURE__ */ new Date()).getTime()); } else { var reQueryString = /\?/; - this.url += (reQueryString.test(this.url) ? "&" : "?") + "_=" + new Date().getTime(); + this.url += (reQueryString.test(this.url) ? "&" : "?") + "_=" + (/* @__PURE__ */ new Date()).getTime(); } } } @@ -15005,6 +15303,9 @@ _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); + Object.defineProperty(Constructor, "prototype", { + writable: false + }); return Constructor; } function _inherits(subClass, superClass) { @@ -15018,17 +15319,20 @@ configurable: true } }); + Object.defineProperty(subClass, "prototype", { + writable: false + }); if (superClass) _setPrototypeOf(subClass, superClass); } function _getPrototypeOf(o) { - _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf2(o2) { + _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf2(o2) { return o2.__proto__ || Object.getPrototypeOf(o2); }; return _getPrototypeOf(o); } function _setPrototypeOf(o, p) { - _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf2(o2, p2) { + _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf2(o2, p2) { o2.__proto__ = p2; return o2; }; @@ -15058,6 +15362,8 @@ function _possibleConstructorReturn(self2, call) { if (call && (typeof call === "object" || typeof call === "function")) { return call; + } else if (call !== void 0) { + throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self2); } @@ -15082,22 +15388,22 @@ } return object; } - function _get(target, property, receiver) { + function _get() { if (typeof Reflect !== "undefined" && Reflect.get) { - _get = Reflect.get; + _get = Reflect.get.bind(); } else { - _get = function _get2(target2, property2, receiver2) { - var base = _superPropBase(target2, property2); + _get = function _get2(target, property, receiver) { + var base = _superPropBase(target, property); if (!base) return; - var desc = Object.getOwnPropertyDescriptor(base, property2); + var desc = Object.getOwnPropertyDescriptor(base, property); if (desc.get) { - return desc.get.call(receiver2); + return desc.get.call(arguments.length < 3 ? target : receiver); } return desc.value; }; } - return _get(target, property, receiver || target); + return _get.apply(this, arguments); } var Emitter = /* @__PURE__ */ function() { function Emitter2() { @@ -15110,22 +15416,22 @@ } _createClass(Emitter2, [{ key: "addEventListener", - value: function addEventListener(type3, callback, options2) { - if (!(type3 in this.listeners)) { - this.listeners[type3] = []; + value: function addEventListener(type2, callback, options2) { + if (!(type2 in this.listeners)) { + this.listeners[type2] = []; } - this.listeners[type3].push({ + this.listeners[type2].push({ callback, options: options2 }); } }, { key: "removeEventListener", - value: function removeEventListener(type3, callback) { - if (!(type3 in this.listeners)) { + value: function removeEventListener(type2, callback) { + if (!(type2 in this.listeners)) { return; } - var stack = this.listeners[type3]; + var stack = this.listeners[type2]; for (var i2 = 0, l = stack.length; i2 < l; i2++) { if (stack[i2].callback === callback) { stack.splice(i2, 1); @@ -15179,6 +15485,11 @@ writable: true, configurable: true }); + Object.defineProperty(_assertThisInitialized(_this), "reason", { + value: void 0, + writable: true, + configurable: true + }); return _this; } _createClass(AbortSignal2, [{ @@ -15211,7 +15522,7 @@ } _createClass(AbortController3, [{ key: "abort", - value: function abort() { + value: function abort(reason) { var event; try { event = new Event("abort"); @@ -15232,6 +15543,21 @@ }; } } + var signalReason = reason; + if (signalReason === void 0) { + if (typeof document === "undefined") { + signalReason = new Error("This operation was aborted"); + signalReason.name = "AbortError"; + } else { + try { + signalReason = new DOMException("signal is aborted without reason"); + } catch (err) { + signalReason = new Error("This operation was aborted"); + signalReason.name = "AbortError"; + } + } + } + this.signal.reason = signalReason; this.signal.dispatchEvent(event); } }, { @@ -15354,6 +15680,7 @@ // modules/index.js var modules_exports = {}; __export(modules_exports, { + LocationManager: () => LocationManager, QAItem: () => QAItem, actionAddEntity: () => actionAddEntity, actionAddMember: () => actionAddMember, @@ -15412,7 +15739,6 @@ coreGraph: () => coreGraph, coreHistory: () => coreHistory, coreLocalizer: () => coreLocalizer, - coreLocations: () => coreLocations, coreTree: () => coreTree, coreUploader: () => coreUploader, coreValidator: () => coreValidator, @@ -15464,8 +15790,9 @@ geoVecSubtract: () => geoVecSubtract, geoViewportEdge: () => geoViewportEdge, geoZoomToScale: () => geoZoomToScale, + likelyRawNumberFormat: () => likelyRawNumberFormat, localizer: () => _mainLocalizer, - locationManager: () => _mainLocations, + locationManager: () => _sharedLocationManager, modeAddArea: () => modeAddArea, modeAddLine: () => modeAddLine, modeAddNote: () => modeAddNote, @@ -15610,9 +15937,10 @@ uiFieldAccess: () => uiFieldAccess, uiFieldAddress: () => uiFieldAddress, uiFieldCheck: () => uiFieldCheck, + uiFieldColour: () => uiFieldText, uiFieldCombo: () => uiFieldCombo, - uiFieldCycleway: () => uiFieldCycleway, uiFieldDefaultCheck: () => uiFieldCheck, + uiFieldDirectionalCombo: () => uiFieldDirectionalCombo, uiFieldEmail: () => uiFieldText, uiFieldHelp: () => uiFieldHelp, uiFieldIdentifier: () => uiFieldText, @@ -15655,6 +15983,7 @@ uiKeepRightEditor: () => uiKeepRightEditor, uiKeepRightHeader: () => uiKeepRightHeader, uiLasso: () => uiLasso, + uiLengthIndicator: () => uiLengthIndicator, uiLoading: () => uiLoading, uiMapInMap: () => uiMapInMap, uiModal: () => uiModal, @@ -15725,6 +16054,7 @@ utilArrayUniq: () => utilArrayUniq, utilArrayUniqBy: () => utilArrayUniqBy, utilAsyncMap: () => utilAsyncMap, + utilCleanOsmString: () => utilCleanOsmString, utilCleanTags: () => utilCleanTags, utilCombinedTags: () => utilCombinedTags, utilCompareIDs: () => utilCompareIDs, @@ -15868,17 +16198,21 @@ } else if (options2 && options2.reverseOneway && key === "oneway") { return onewayReplacements[value] || value; } else if (includeAbsolute && directionKey.test(key)) { - if (compassReplacements[value]) - return compassReplacements[value]; - var degrees3 = parseFloat(value); - if (typeof degrees3 === "number" && !isNaN(degrees3)) { - if (degrees3 < 180) { - degrees3 += 180; + return value.split(";").map((value2) => { + if (compassReplacements[value2]) + return compassReplacements[value2]; + var degrees3 = Number(value2); + if (isFinite(degrees3)) { + if (degrees3 < 180) { + degrees3 += 180; + } else { + degrees3 -= 180; + } + return degrees3.toString(); } else { - degrees3 -= 180; + return valueReplacements[value2] || value2; } - return degrees3.toString(); - } + }).join(";"); } return valueReplacements[value] || value; } @@ -15939,21 +16273,28 @@ // modules/osm/tags.js function osmIsInterestingTag(key) { - return key !== "attribution" && key !== "created_by" && key !== "source" && key !== "odbl" && key.indexOf("source:") !== 0 && key.indexOf("source_ref") !== 0 && key.indexOf("tiger:") !== 0; + return key !== "attribution" && key !== "created_by" && key !== "source" && key !== "odbl" && key.indexOf("source:") !== 0 && key.indexOf("source_ref") !== 0 && // purposely exclude colon + key.indexOf("tiger:") !== 0; } var osmLifecyclePrefixes = { + // nonexistent, might be built proposed: true, planned: true, + // under maintentance or between groundbreaking and opening construction: true, + // existent but not functional disused: true, + // dilapidated to nonexistent abandoned: true, was: true, + // nonexistent, still may appear in imagery dismantled: true, razed: true, demolished: true, destroyed: true, removed: true, obliterated: true, + // existent occasionally, e.g. stormwater drainage basin intermittent: true }; function osmRemoveLifecyclePrefix(key) { @@ -15986,6 +16327,9 @@ turntable: true, wash: true }, + traffic_calming: { + island: true + }, waterway: { dam: true } @@ -15998,17 +16342,21 @@ var returnTags = {}; for (var realKey in tags) { const key = osmRemoveLifecyclePrefix(realKey); - if (key in osmAreaKeys && !(tags[key] in osmAreaKeys[key])) { + if (key in osmAreaKeys && !(tags[realKey] in osmAreaKeys[key])) { returnTags[realKey] = tags[realKey]; return returnTags; } - if (key in osmAreaKeysExceptions && tags[key] in osmAreaKeysExceptions[key]) { + if (key in osmAreaKeysExceptions && tags[realKey] in osmAreaKeysExceptions[key]) { returnTags[realKey] = tags[realKey]; return returnTags; } } return null; } + var osmLineTags = {}; + function osmSetLineTags(value) { + osmLineTags = value; + } var osmPointTags = {}; function osmSetPointTags(value) { osmPointTags = value; @@ -16060,6 +16408,8 @@ "yes": true }, "seamark:type": { + "two-way_route": true, + "recommended_traffic_lane": true, "separation_lane": true, "separation_roundabout": true }, @@ -16068,7 +16418,9 @@ "ditch": true, "drain": true, "fish_pass": true, + "pressurised": true, "river": true, + "spillway": true, "stream": true, "tidal_channel": true } @@ -16109,7 +16461,8 @@ "city_wall": true }, "man_made": { - "embankment": true + "embankment": true, + "quay": true }, "waterway": { "weir": true @@ -16171,6 +16524,7 @@ stream: true, tidal_channel: true }; + var allowUpperCaseTagValues = /network|taxon|genus|species|brand|grape_variety|royal_cypher|listed_status|booth|rating|stars|:output|_hours|_times|_ref|manufacturer|country|target|brewery|cai_scale|traffic_sign/; // node_modules/d3-array/src/ascending.js function ascending(a, b) { @@ -16537,9 +16891,9 @@ streamGeometry(object.geometry, stream); }, FeatureCollection: function(object, stream) { - var features2 = object.features, i2 = -1, n2 = features2.length; + var features = object.features, i2 = -1, n2 = features.length; while (++i2 < n2) - streamGeometry(features2[i2].geometry, stream); + streamGeometry(features[i2].geometry, stream); } }; var streamGeometryType = { @@ -16917,16 +17271,16 @@ if (direction > 0 ? t0 < t1 : t0 > t1) t0 += direction * tau; } - for (var point, t = t0; direction > 0 ? t > t1 : t < t1; t -= step) { - point = spherical([cosRadius, -sinRadius * cos(t), -sinRadius * sin(t)]); - stream.point(point[0], point[1]); + for (var point2, t = t0; direction > 0 ? t > t1 : t < t1; t -= step) { + point2 = spherical([cosRadius, -sinRadius * cos(t), -sinRadius * sin(t)]); + stream.point(point2[0], point2[1]); } } - function circleRadius(cosRadius, point) { - point = cartesian(point), point[0] -= cosRadius; - cartesianNormalizeInPlace(point); - var radius = acos(-point[1]); - return ((-point[2] < 0 ? -radius : radius) + tau - epsilon) % tau; + function circleRadius(cosRadius, point2) { + point2 = cartesian(point2), point2[0] -= cosRadius; + cartesianNormalizeInPlace(point2); + var radius = acos(-point2[1]); + return ((-point2[2] < 0 ? -radius : radius) + tau - epsilon) % tau; } // node_modules/d3-geo/src/clip/buffer.js @@ -16959,8 +17313,8 @@ } // node_modules/d3-geo/src/clip/rejoin.js - function Intersection(point, points, other, entry) { - this.x = point; + function Intersection(point2, points, other, entry) { + this.x = point2; this.z = points; this.o = other; this.e = entry; @@ -16996,7 +17350,7 @@ for (i2 = 0, n2 = clip.length; i2 < n2; ++i2) { clip[i2].e = startInside = !startInside; } - var start2 = subject[0], points, point; + var start2 = subject[0], points, point2; while (1) { var current = start2, isSubject = true; while (current.v) @@ -17009,7 +17363,7 @@ if (current.e) { if (isSubject) { for (i2 = 0, n2 = points.length; i2 < n2; ++i2) - stream.point((point = points[i2])[0], point[1]); + stream.point((point2 = points[i2])[0], point2[1]); } else { interpolate(current.x, current.n.x, 1, stream); } @@ -17018,7 +17372,7 @@ if (isSubject) { points = current.p.z; for (i2 = points.length - 1; i2 >= 0; --i2) - stream.point((point = points[i2])[0], point[1]); + stream.point((point2 = points[i2])[0], point2[1]); } else { interpolate(current.x, current.p.x, -1, stream); } @@ -17045,11 +17399,11 @@ } // node_modules/d3-geo/src/polygonContains.js - function longitude(point) { - return abs(point[0]) <= pi ? point[0] : sign(point[0]) * ((abs(point[0]) + pi) % tau - pi); + function longitude(point2) { + return abs(point2[0]) <= pi ? point2[0] : sign(point2[0]) * ((abs(point2[0]) + pi) % tau - pi); } - function polygonContains_default(polygon2, point) { - var lambda = longitude(point), phi = point[1], sinPhi = sin(phi), normal = [sin(lambda), -cos(lambda), 0], angle2 = 0, winding = 0; + function polygonContains_default(polygon2, point2) { + var lambda = longitude(point2), phi = point2[1], sinPhi = sin(phi), normal = [sin(lambda), -cos(lambda), 0], angle2 = 0, winding = 0; var sum = new Adder(); if (sinPhi === 1) phi = halfPi + epsilon; @@ -17083,7 +17437,7 @@ return function(sink) { var line = clipLine(sink), ringBuffer = buffer_default(), ringSink = clipLine(ringBuffer), polygonStarted = false, polygon2, segments, ring; var clip = { - point, + point: point2, lineStart, lineEnd, polygonStart: function() { @@ -17094,7 +17448,7 @@ polygon2 = []; }, polygonEnd: function() { - clip.point = point; + clip.point = point2; clip.lineStart = lineStart; clip.lineEnd = lineEnd; segments = merge(segments); @@ -17122,7 +17476,7 @@ sink.polygonEnd(); } }; - function point(lambda, phi) { + function point2(lambda, phi) { if (pointVisible(lambda, phi)) sink.point(lambda, phi); } @@ -17134,7 +17488,7 @@ line.lineStart(); } function lineEnd() { - clip.point = point; + clip.point = point2; line.lineEnd(); } function pointRing(lambda, phi) { @@ -17148,7 +17502,7 @@ function ringEnd() { pointRing(ring[0][0], ring[0][1]); ringSink.lineEnd(); - var clean2 = ringSink.clean(), ringSegments = ringBuffer.result(), i2, n2 = ringSegments.length, m, segment, point2; + var clean2 = ringSink.clean(), ringSegments = ringBuffer.result(), i2, n2 = ringSegments.length, m, segment, point3; ring.pop(); polygon2.push(ring); ring = null; @@ -17161,7 +17515,7 @@ sink.polygonStart(), polygonStarted = true; sink.lineStart(); for (i2 = 0; i2 < m; ++i2) - sink.point((point2 = segment[i2])[0], point2[1]); + sink.point((point3 = segment[i2])[0], point3[1]); sink.lineEnd(); } return; @@ -17322,6 +17676,8 @@ stream.lineEnd(); point0 = null; }, + // Rejoin first and last segments if there were intersections and the first + // and last points were visible. clean: function() { return clean2 | (v00 && v0) << 1; } @@ -17469,21 +17825,21 @@ return function(stream) { var activeStream = stream, bufferStream = buffer_default(), segments, polygon2, ring, x__, y__, v__, x_, y_, v_, first, clean2; var clipStream = { - point, + point: point2, lineStart, lineEnd, polygonStart, polygonEnd }; - function point(x, y) { + function point2(x, y) { if (visible(x, y)) activeStream.point(x, y); } function polygonInside() { var winding = 0; for (var i2 = 0, n2 = polygon2.length; i2 < n2; ++i2) { - for (var ring2 = polygon2[i2], j2 = 1, m = ring2.length, point2 = ring2[0], a0, a1, b0 = point2[0], b1 = point2[1]; j2 < m; ++j2) { - a0 = b0, a1 = b1, point2 = ring2[j2], b0 = point2[0], b1 = point2[1]; + for (var ring2 = polygon2[i2], j2 = 1, m = ring2.length, point3 = ring2[0], a0, a1, b0 = point3[0], b1 = point3[1]; j2 < m; ++j2) { + a0 = b0, a1 = b1, point3 = ring2[j2], b0 = point3[0], b1 = point3[1]; if (a1 <= y12) { if (b1 > y12 && (b0 - a0) * (y12 - a1) > (b1 - a1) * (x05 - a0)) ++winding; @@ -17529,7 +17885,7 @@ bufferStream.rejoin(); segments.push(bufferStream.result()); } - clipStream.point = point; + clipStream.point = point2; if (v_) activeStream.lineEnd(); } @@ -18052,7 +18408,7 @@ return function(stream) { var lambda003, x004, y004, a00, b00, c00, lambda04, x05, y05, a0, b0, c0; var resampleStream = { - point, + point: point2, lineStart, lineEnd, polygonStart: function() { @@ -18064,7 +18420,7 @@ resampleStream.lineStart = lineStart; } }; - function point(x, y) { + function point2(x, y) { x = project(x, y); stream.point(x[0], x[1]); } @@ -18079,7 +18435,7 @@ stream.point(x05, y05); } function lineEnd() { - resampleStream.point = point; + resampleStream.point = point2; stream.lineEnd(); } function ringStart() { @@ -18146,12 +18502,12 @@ } function projectionMutator(projectAt) { var project, k = 150, x = 480, y = 250, lambda = 0, phi = 0, deltaLambda = 0, deltaPhi = 0, deltaGamma = 0, rotate, alpha = 0, sx = 1, sy = 1, theta = null, preclip = antimeridian_default, x05 = null, y05, x12, y12, postclip = identity_default, delta2 = 0.5, projectResample, projectTransform, projectRotateTransform, cache, cacheStream; - function projection2(point) { - return projectRotateTransform(point[0] * radians, point[1] * radians); + function projection2(point2) { + return projectRotateTransform(point2[0] * radians, point2[1] * radians); } - function invert(point) { - point = projectRotateTransform.invert(point[0], point[1]); - return point && [point[0] * degrees, point[1] * degrees]; + function invert(point2) { + point2 = projectRotateTransform.invert(point2[0], point2[1]); + return point2 && [point2[0] * degrees, point2[1] * degrees]; } projection2.stream = function(stream) { return cache && cacheStream === stream ? cache : cache = transformRadians(transformRotate(rotate)(preclip(projectResample(postclip(cacheStream = stream))))); @@ -18369,11 +18725,11 @@ tileSize = tileSize || 256; return tileSize * Math.pow(2, z) / TAU; } - function geoSphericalClosestNode(nodes, point) { + function geoSphericalClosestNode(nodes, point2) { var minDistance = Infinity, distance; var indexOfMin; for (var i2 in nodes) { - distance = geoSphericalDistance(nodes[i2].loc, point); + distance = geoSphericalDistance(nodes[i2].loc, point2); if (distance < minDistance) { minDistance = distance; indexOfMin = i2; @@ -18650,15 +19006,15 @@ return a[0] === b[0] && a[1] === b[1] || a[0] === b[1] && a[1] === b[0]; } function geoRotate(points, angle2, around) { - return points.map(function(point) { - var radial = geoVecSubtract(point, around); + return points.map(function(point2) { + var radial = geoVecSubtract(point2, around); return [ radial[0] * Math.cos(angle2) - radial[1] * Math.sin(angle2) + around[0], radial[0] * Math.sin(angle2) + radial[1] * Math.cos(angle2) + around[1] ]; }); } - function geoChooseEdge(nodes, point, projection2, activeID) { + function geoChooseEdge(nodes, point2, projection2, activeID) { var dist = geoVecLength; var points = nodes.map(function(n2) { return projection2(n2.loc); @@ -18674,7 +19030,7 @@ continue; var o = points[i2]; var s = geoVecSubtract(points[i2 + 1], o); - var v = geoVecSubtract(point, o); + var v = geoVecSubtract(point2, o); var proj = geoVecDot(v, s) / geoVecDot(s, s); var p; if (proj < 0) { @@ -18684,7 +19040,7 @@ } else { p = [o[0] + proj * s[0], o[1] + proj * s[1]]; } - var d = dist(p, point); + var d = dist(p, point2); if (d < min3) { min3 = d; idx = i2 + 1; @@ -18806,9 +19162,9 @@ } return false; } - function geoPointInPolygon(point, polygon2) { - var x = point[0]; - var y = point[1]; + function geoPointInPolygon(point2, polygon2) { + var x = point2[0]; + var y = point2[1]; var inside = false; for (var i2 = 0, j2 = polygon2.length - 1; i2 < polygon2.length; j2 = i2++) { var xi = polygon2[i2][0]; @@ -18822,14 +19178,14 @@ return inside; } function geoPolygonContainsPolygon(outer, inner) { - return inner.every(function(point) { - return geoPointInPolygon(point, outer); + return inner.every(function(point2) { + return geoPointInPolygon(point2, outer); }); } function geoPolygonIntersectsPolygon(outer, inner, checkSegments) { function testPoints(outer2, inner2) { - return inner2.some(function(point) { - return geoPointInPolygon(point, outer2); + return inner2.some(function(point2) { + return geoPointInPolygon(point2, outer2); }); } return testPoints(outer, inner) || !!checkSegments && geoPathHasIntersections(outer, inner); @@ -18845,8 +19201,8 @@ var c2 = i2 === hull.length - 1 ? hull[0] : hull[i2 + 1]; var angle2 = Math.atan2(c2[1] - c1[1], c2[0] - c1[0]); var poly = geoRotate(hull, -angle2, centroid); - var extent = poly.reduce(function(extent2, point) { - return extent2.extend(geoExtent(point)); + var extent = poly.reduce(function(extent2, point2) { + return extent2.extend(geoExtent(point2)); }, geoExtent()); var area = extent.area(); if (area < minArea) { @@ -18868,20 +19224,20 @@ } return length; } - function geoViewportEdge(point, dimensions) { + function geoViewportEdge(point2, dimensions) { var pad2 = [80, 20, 50, 20]; var x = 0; var y = 0; - if (point[0] > dimensions[0] - pad2[1]) { + if (point2[0] > dimensions[0] - pad2[1]) { x = -10; } - if (point[0] < pad2[3]) { + if (point2[0] < pad2[3]) { x = 10; } - if (point[1] > dimensions[1] - pad2[2]) { + if (point2[1] > dimensions[1] - pad2[2]) { y = -10; } - if (point[1] < pad2[0]) { + if (point2[1] < pad2[0]) { y = 10; } if (x || y) { @@ -18942,39 +19298,39 @@ copy2[t] = _[t].slice(); return new Dispatch(copy2); }, - call: function(type3, that) { + call: function(type2, that) { if ((n2 = arguments.length - 2) > 0) for (var args = new Array(n2), i2 = 0, n2, t; i2 < n2; ++i2) args[i2] = arguments[i2 + 2]; - if (!this._.hasOwnProperty(type3)) - throw new Error("unknown type: " + type3); - for (t = this._[type3], i2 = 0, n2 = t.length; i2 < n2; ++i2) + if (!this._.hasOwnProperty(type2)) + throw new Error("unknown type: " + type2); + for (t = this._[type2], i2 = 0, n2 = t.length; i2 < n2; ++i2) t[i2].value.apply(that, args); }, - apply: function(type3, that, args) { - if (!this._.hasOwnProperty(type3)) - throw new Error("unknown type: " + type3); - for (var t = this._[type3], i2 = 0, n2 = t.length; i2 < n2; ++i2) + apply: function(type2, that, args) { + if (!this._.hasOwnProperty(type2)) + throw new Error("unknown type: " + type2); + for (var t = this._[type2], i2 = 0, n2 = t.length; i2 < n2; ++i2) t[i2].value.apply(that, args); } }; - function get(type3, name) { - for (var i2 = 0, n2 = type3.length, c; i2 < n2; ++i2) { - if ((c = type3[i2]).name === name) { + function get(type2, name) { + for (var i2 = 0, n2 = type2.length, c; i2 < n2; ++i2) { + if ((c = type2[i2]).name === name) { return c.value; } } } - function set(type3, name, callback) { - for (var i2 = 0, n2 = type3.length; i2 < n2; ++i2) { - if (type3[i2].name === name) { - type3[i2] = noop2, type3 = type3.slice(0, i2).concat(type3.slice(i2 + 1)); + function set(type2, name, callback) { + for (var i2 = 0, n2 = type2.length; i2 < n2; ++i2) { + if (type2[i2].name === name) { + type2[i2] = noop2, type2 = type2.slice(0, i2).concat(type2.slice(i2 + 1)); break; } } if (callback != null) - type3.push({ name, value: callback }); - return type3; + type2.push({ name, value: callback }); + return type2; } var dispatch_default = dispatch; @@ -19275,9 +19631,9 @@ function merge_default(context) { var selection2 = context.selection ? context.selection() : context; for (var groups0 = this._groups, groups1 = selection2._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j2 = 0; j2 < m; ++j2) { - for (var group0 = groups0[j2], group1 = groups1[j2], n2 = group0.length, merge3 = merges[j2] = new Array(n2), node, i2 = 0; i2 < n2; ++i2) { + for (var group0 = groups0[j2], group1 = groups1[j2], n2 = group0.length, merge2 = merges[j2] = new Array(n2), node, i2 = 0; i2 < n2; ++i2) { if (node = group0[i2] || group1[i2]) { - merge3[i2] = node; + merge2[i2] = node; } } } @@ -19718,31 +20074,31 @@ } // node_modules/d3-selection/src/selection/dispatch.js - function dispatchEvent(node, type3, params) { + function dispatchEvent(node, type2, params) { var window2 = window_default(node), event = window2.CustomEvent; if (typeof event === "function") { - event = new event(type3, params); + event = new event(type2, params); } else { event = window2.document.createEvent("Event"); if (params) - event.initEvent(type3, params.bubbles, params.cancelable), event.detail = params.detail; + event.initEvent(type2, params.bubbles, params.cancelable), event.detail = params.detail; else - event.initEvent(type3, false, false); + event.initEvent(type2, false, false); } node.dispatchEvent(event); } - function dispatchConstant(type3, params) { + function dispatchConstant(type2, params) { return function() { - return dispatchEvent(this, type3, params); + return dispatchEvent(this, type2, params); }; } - function dispatchFunction(type3, params) { + function dispatchFunction(type2, params) { return function() { - return dispatchEvent(this, type3, params.apply(this, arguments)); + return dispatchEvent(this, type2, params.apply(this, arguments)); }; } - function dispatch_default2(type3, params) { - return this.each((typeof params === "function" ? dispatchFunction : dispatchConstant)(type3, params)); + function dispatch_default2(type2, params) { + return this.each((typeof params === "function" ? dispatchFunction : dispatchConstant)(type2, params)); } // node_modules/d3-selection/src/selection/iterator.js @@ -19828,10 +20184,10 @@ if (node) { var svg2 = node.ownerSVGElement || node; if (svg2.createSVGPoint) { - var point = svg2.createSVGPoint(); - point.x = event.clientX, point.y = event.clientY; - point = point.matrixTransform(node.getScreenCTM().inverse()); - return [point.x, point.y]; + var point2 = svg2.createSVGPoint(); + point2.x = event.clientX, point2.y = event.clientY; + point2 = point2.matrixTransform(node.getScreenCTM().inverse()); + return [point2.x, point2.y]; } if (node.getBoundingClientRect) { var rect = node.getBoundingClientRect(); @@ -19887,7 +20243,7 @@ var constant_default2 = (x) => () => x; // node_modules/d3-drag/src/event.js - function DragEvent(type3, { + function DragEvent(type2, { sourceEvent, subject, target, @@ -19900,7 +20256,7 @@ dispatch: dispatch10 }) { Object.defineProperties(this, { - type: { value: type3, enumerable: true, configurable: true }, + type: { value: type2, enumerable: true, configurable: true }, sourceEvent: { value: sourceEvent, enumerable: true, configurable: true }, subject: { value: subject, enumerable: true, configurable: true }, target: { value: target, enumerable: true, configurable: true }, @@ -20014,9 +20370,9 @@ return; dx = s.x - p[0] || 0; dy = s.y - p[1] || 0; - return function gesture(type3, event2, touch2) { + return function gesture(type2, event2, touch2) { var p02 = p, n2; - switch (type3) { + switch (type2) { case "start": gestures[identifier] = gesture, n2 = active++; break; @@ -20027,9 +20383,9 @@ break; } dispatch10.call( - type3, + type2, that, - new DragEvent(type3, { + new DragEvent(type2, { sourceEvent: event2, subject: s, target: drag, @@ -20252,6 +20608,7 @@ return this.rgb().displayable(); }, hex: color_formatHex, + // Deprecated! Use color.formatHex. formatHex: color_formatHex, formatHex8: color_formatHex8, formatHsl: color_formatHsl, @@ -20319,6 +20676,7 @@ return -0.5 <= this.r && this.r < 255.5 && (-0.5 <= this.g && this.g < 255.5) && (-0.5 <= this.b && this.b < 255.5) && (0 <= this.opacity && this.opacity <= 1); }, hex: rgb_formatHex, + // Deprecated! Use color.formatHex. formatHex: rgb_formatHex, formatHex8: rgb_formatHex8, formatRgb: rgb_formatRgb, @@ -20544,7 +20902,7 @@ // node_modules/d3-interpolate/src/date.js function date_default(a, b) { - var d = new Date(); + var d = /* @__PURE__ */ new Date(); return a = +a, b = +b, function(t) { return d.setTime(a * (1 - t) + b * t), d; }; @@ -20942,7 +21300,9 @@ create(node, id2, { name, index, + // For context during callback. group, + // For context during callback. on: emptyOn, tween: emptyTween, time: timing.time, @@ -21316,9 +21676,9 @@ if (transition2._id !== this._id) throw new Error(); for (var groups0 = this._groups, groups1 = transition2._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j2 = 0; j2 < m; ++j2) { - for (var group0 = groups0[j2], group1 = groups1[j2], n2 = group0.length, merge3 = merges[j2] = new Array(n2), node, i2 = 0; i2 < n2; ++i2) { + for (var group0 = groups0[j2], group1 = groups1[j2], n2 = group0.length, merge2 = merges[j2] = new Array(n2), node, i2 = 0; i2 < n2; ++i2) { if (node = group0[i2] || group1[i2]) { - merge3[i2] = node; + merge2[i2] = node; } } } @@ -21627,6 +21987,7 @@ // node_modules/d3-transition/src/selection/transition.js var defaultTiming = { time: null, + // Set on use. delay: 0, duration: 250, ease: cubicInOut @@ -21665,14 +22026,14 @@ var constant_default4 = (x) => () => x; // node_modules/d3-zoom/src/event.js - function ZoomEvent(type3, { + function ZoomEvent(type2, { sourceEvent, target, transform: transform2, dispatch: dispatch10 }) { Object.defineProperties(this, { - type: { value: type3, enumerable: true, configurable: true }, + type: { value: type2, enumerable: true, configurable: true }, sourceEvent: { value: sourceEvent, enumerable: true, configurable: true }, target: { value: target, enumerable: true, configurable: true }, transform: { value: transform2, enumerable: true, configurable: true }, @@ -21694,8 +22055,8 @@ translate: function(x, y) { return x === 0 & y === 0 ? this : new Transform(this.k, this.x + this.k * x, this.y + this.k * y); }, - apply: function(point) { - return [point[0] * this.k + this.x, point[1] * this.k + this.y]; + apply: function(point2) { + return [point2[0] * this.k + this.x, point2[1] * this.k + this.y]; }, applyX: function(x) { return x * this.k + this.x; @@ -21777,11 +22138,11 @@ function zoom(selection2) { selection2.property("__zoom", defaultTransform).on("wheel.zoom", wheeled, { passive: false }).on("mousedown.zoom", mousedowned).on("dblclick.zoom", dblclicked).filter(touchable).on("touchstart.zoom", touchstarted).on("touchmove.zoom", touchmoved).on("touchend.zoom touchcancel.zoom", touchended).style("-webkit-tap-highlight-color", "rgba(0,0,0,0)"); } - zoom.transform = function(collection, transform2, point, event) { + zoom.transform = function(collection, transform2, point2, event) { var selection2 = collection.selection ? collection.selection() : collection; selection2.property("__zoom", defaultTransform); if (collection !== selection2) { - schedule(collection, transform2, point, event); + schedule(collection, transform2, point2, event); } else { selection2.interrupt().each(function() { gesture(this, arguments).event(event).start().zoom(null, typeof transform2 === "function" ? transform2.apply(this, arguments) : transform2).end(); @@ -21828,13 +22189,13 @@ function centroid(extent2) { return [(+extent2[0][0] + +extent2[1][0]) / 2, (+extent2[0][1] + +extent2[1][1]) / 2]; } - function schedule(transition2, transform2, point, event) { + function schedule(transition2, transform2, point2, event) { transition2.on("start.zoom", function() { gesture(this, arguments).event(event).start(); }).on("interrupt.zoom end.zoom", function() { gesture(this, arguments).event(event).end(); }).tween("zoom", function() { - var that = this, args = arguments, g = gesture(that, args).event(event), e = extent.apply(that, args), p = point == null ? centroid(e) : typeof point === "function" ? point.apply(that, args) : point, w = Math.max(e[1][0] - e[0][0], e[1][1] - e[0][1]), a = that.__zoom, b = typeof transform2 === "function" ? transform2.apply(that, args) : transform2, i2 = interpolate(a.invert(p).concat(w / a.k), b.invert(p).concat(w / b.k)); + var that = this, args = arguments, g = gesture(that, args).event(event), e = extent.apply(that, args), p = point2 == null ? centroid(e) : typeof point2 === "function" ? point2.apply(that, args) : point2, w = Math.max(e[1][0] - e[0][0], e[1][1] - e[0][1]), a = that.__zoom, b = typeof transform2 === "function" ? transform2.apply(that, args) : transform2, i2 = interpolate(a.invert(p).concat(w / a.k), b.invert(p).concat(w / b.k)); return function(t) { if (t === 1) t = b; @@ -21888,15 +22249,15 @@ } return this; }, - emit: function(type3) { + emit: function(type2) { var d = select_default2(this.that).datum(); listeners.call( - type3, + type2, this.that, - new ZoomEvent(type3, { + new ZoomEvent(type2, { sourceEvent: this.sourceEvent, target: zoom, - type: type3, + type: type2, transform: this.that.__zoom, dispatch: listeners }), @@ -22090,13 +22451,13 @@ var x = 0; var y = 0; var clipExtent = [[0, 0], [0, 0]]; - function projection2(point) { - point = project(point[0] * Math.PI / 180, point[1] * Math.PI / 180); - return [point[0] * k + x, y - point[1] * k]; + function projection2(point2) { + point2 = project(point2[0] * Math.PI / 180, point2[1] * Math.PI / 180); + return [point2[0] * k + x, y - point2[1] * k]; } - projection2.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]; + projection2.invert = function(point2) { + point2 = project.invert((point2[0] - x) / k, (y - point2[1]) / k); + return point2 && [point2[0] * 180 / Math.PI, point2[1] * 180 / Math.PI]; }; projection2.scale = function(_) { if (!arguments.length) @@ -22365,10 +22726,43 @@ // modules/core/file_fetcher.js var import_vparse = __toESM(require_vparse()); + // config/id.js + var presetsCdnUrl = "https://cdn.jsdelivr.net/npm/@openstreetmap/id-tagging-schema@{presets_version}/"; + var ociCdnUrl = "https://cdn.jsdelivr.net/npm/osm-community-index@{version}/"; + var wmfSitematrixCdnUrl = "https://cdn.jsdelivr.net/npm/wmf-sitematrix@{version}/"; + var nsiCdnUrl = "https://cdn.jsdelivr.net/npm/name-suggestion-index@{version}/"; + var defaultOsmApiConnections = { + live: { + url: "https://www.openstreetmap.org", + client_id: "0tmNTmd0Jo1dQp4AUmMBLtGiD9YpMuXzHefitcuVStc", + client_secret: "BTlNrNxIPitHdL4sP2clHw5KLoee9aKkA7dQbc0Bj7Q" + }, + dev: { + url: "https://api06.dev.openstreetmap.org", + client_id: "Ee1wWJ6UlpERbF6BfTNOpwn0R8k_06mvMXdDUkeHMgw", + client_secret: "OnfWFC-JkZNHyYdr_viNn_h_RTZXRslKcUxllOXqf5g" + } + }; + var osmApiConnections = []; + if (false) { + osmApiConnections.push({ + url: null, + client_id: null, + client_secret: null + }); + } else if (false) { + osmApiConnections.push(defaultOsmApiConnections[null]); + } else { + osmApiConnections.push(defaultOsmApiConnections.live); + osmApiConnections.push(defaultOsmApiConnections.dev); + } + var taginfoApiUrl = "https://taginfo.openstreetmap.org/api/4/"; + var nominatimApiUrl = "https://nominatim.openstreetmap.org/"; + // package.json var package_default = { name: "iD", - version: "2.22.0", + version: "2.26.1", description: "A friendly editor for OpenStreetMap", main: "dist/iD.min.js", repository: "github:openstreetmap/iD", @@ -22384,7 +22778,7 @@ build: "run-s build:css build:data build:js", "build:css": "node scripts/build_css.js", "build:data": "shx mkdir -p dist/data && node scripts/build_data.js", - "build:stats": "esbuild-visualizer --metadata dist/esbuild.json --exclude *.png --filename docs/statistics.html", + "build:stats": "node config/esbuild.config.mjs --stats && esbuild-visualizer --metadata dist/esbuild.json --exclude *.png --filename docs/statistics.html && shx rm dist/esbuild.json", "build:js": "node config/esbuild.config.mjs", "build:js:watch": "node config/esbuild.config.mjs --watch", clean: "shx rm -f dist/esbuild.json dist/*.js dist/*.map dist/*.css dist/img/*.svg", @@ -22398,82 +22792,87 @@ "dist:svg:maki": 'svg-sprite --symbol --symbol-dest . --shape-id-generator "maki-%s" --symbol-sprite dist/img/maki-sprite.svg node_modules/@mapbox/maki/icons/*.svg', "dist:svg:mapillary:signs": "svg-sprite --symbol --symbol-dest . --symbol-sprite dist/img/mapillary-sprite.svg node_modules/mapillary_sprite_source/package_signs/*.svg", "dist:svg:mapillary:objects": "svg-sprite --symbol --symbol-dest . --symbol-sprite dist/img/mapillary-object-sprite.svg node_modules/mapillary_sprite_source/package_objects/*.svg", - "dist:svg:temaki": 'svg-sprite --symbol --symbol-dest . --shape-id-generator "temaki-%s" --symbol-sprite dist/img/temaki-sprite.svg node_modules/@ideditor/temaki/icons/*.svg', + "dist:svg:roentgen": 'svg-sprite --shape-id-generator "roentgen-%s" --shape-dim-width 16 --shape-dim-height 16 --symbol --symbol-dest . --symbol-sprite dist/img/roentgen-sprite.svg svg/roentgen/*.svg', + "dist:svg:temaki": 'svg-sprite --symbol --symbol-dest . --shape-id-generator "temaki-%s" --symbol-sprite dist/img/temaki-sprite.svg node_modules/@rapideditor/temaki/icons/*.svg', imagery: "node scripts/update_imagery.js", - lint: "eslint scripts test/spec modules", + lint: "eslint config scripts test/spec modules --ext js,mjs", "lint:fix": "eslint scripts test/spec modules --fix", - start: "run-s build:js start:server", + start: "run-s start:watch", + "start:single-build": "run-p build:js start:server", "start:watch": "run-p build:js:watch start:server", "start:server": "node scripts/server.js", test: "npm-run-all -s lint build test:spec", - "test:spec": "karma start karma.conf.js", + "test:spec": "karma start config/karma.conf.js", translations: "node scripts/update_locales.js" }, dependencies: { - "@ideditor/country-coder": "~5.0.3", - "@ideditor/location-conflation": "~1.0.2", + "@rapideditor/country-coder": "~5.2.0", + "@rapideditor/location-conflation": "~1.2.0", "@mapbox/geojson-area": "^0.2.2", "@mapbox/sexagesimal": "1.2.0", "@mapbox/vector-tile": "^1.3.1", - "@tmcw/togeojson": "^5.2.1", + "@tmcw/togeojson": "^5.6.2", + "@turf/bbox": "^6.0.0", "@turf/bbox-clip": "^6.0.0", - "abortcontroller-polyfill": "^1.4.0", + "abortcontroller-polyfill": "^1.7.5", "aes-js": "^3.1.2", "alif-toolkit": "^1.2.9", - "core-js-bundle": "^3.19.0", + "core-js-bundle": "^3.31.1", diacritics: "1.3.0", "fast-deep-equal": "~3.1.1", "fast-json-stable-stringify": "2.1.0", "lodash-es": "~4.17.15", - marked: "~4.1.0", + marked: "~5.1.1", "node-diff3": "~3.1.0", - "osm-auth": "~2.0.0", + "osm-auth": "~2.1.0", pannellum: "2.5.6", pbf: "^3.2.1", "polygon-clipping": "~0.15.1", rbush: "3.0.1", "whatwg-fetch": "^3.4.1", - "which-polygon": "2.2.0" + "which-polygon": "2.2.1" }, devDependencies: { - "@fortawesome/fontawesome-svg-core": "~6.2.0", - "@fortawesome/free-brands-svg-icons": "~6.2.0", - "@fortawesome/free-regular-svg-icons": "~6.2.0", - "@fortawesome/free-solid-svg-icons": "~6.2.0", - "@ideditor/temaki": "~5.1.0", - "@mapbox/maki": "^8.0.0", - autoprefixer: "^10.0.1", - btoa: "^1.2.1", - chai: "^4.3.4", + "@fortawesome/fontawesome-svg-core": "~6.4.0", + "@fortawesome/free-brands-svg-icons": "~6.4.0", + "@fortawesome/free-regular-svg-icons": "~6.4.0", + "@fortawesome/free-solid-svg-icons": "~6.4.0", + "@rapideditor/temaki": "~5.4.0", + "@mapbox/maki": "^8.0.1", + "@openstreetmap/id-tagging-schema": "^6.3.0", + "@transifex/api": "^5.4.0", + autoprefixer: "^10.4.14", + chai: "^4.3.7", chalk: "^4.1.2", - "cldr-core": "^41.0.0", - "cldr-localenames-full": "^41.0.0", + "cldr-core": "^43.0.0", + "cldr-localenames-full": "^43.1.0", "concat-files": "^0.1.1", - d3: "~7.6.1", + d3: "~7.8.5", + dotenv: "^16.3.1", "editor-layer-index": "github:osmlab/editor-layer-index#gh-pages", - esbuild: "^0.15.7", - "esbuild-visualizer": "^0.3.1", - eslint: "^8.8.0", + esbuild: "^0.18.11", + "esbuild-visualizer": "^0.4.1", + eslint: "^8.44.0", "fetch-mock": "^9.11.0", gaze: "^1.1.3", - glob: "^8.0.3", + glob: "^10.3.3", happen: "^0.3.2", "js-yaml": "^4.0.0", "json-stringify-pretty-compact": "^3.0.0", - karma: "^6.3.5", - "karma-chrome-launcher": "^3.1.0", + karma: "^6.4.2", + "karma-chrome-launcher": "^3.2.0", "karma-coverage": "2.1.1", "karma-mocha": "^2.0.1", "karma-remap-istanbul": "^0.6.0", mapillary_sprite_source: "^1.8.0", "mapillary-js": "4.1.1", - minimist: "^1.2.3", - mocha: "^10.0.0", + minimist: "^1.2.8", + mocha: "^10.2.0", "name-suggestion-index": "~6.0", - "node-fetch": "^2.6.1", + "node-fetch": "^2.6.11", "npm-run-all": "^4.0.0", - "osm-community-index": "~5.2.0", - postcss: "^8.1.1", + "osm-community-index": "~5.5.3", + postcss: "^8.4.25", "postcss-selector-prepend": "^0.5.0", shelljs: "^0.8.0", shx: "^0.3.0", @@ -22481,7 +22880,7 @@ "sinon-chai": "^3.7.0", smash: "0.0", "static-server": "^2.2.1", - "svg-sprite": "1.5.4", + "svg-sprite": "2.0.2", vparse: "~1.1.0" }, engines: { @@ -22497,30 +22896,32 @@ function coreFileFetcher() { const ociVersion = package_default.dependencies["osm-community-index"] || package_default.devDependencies["osm-community-index"]; const v = (0, import_vparse.default)(ociVersion); - const vMinor = `${v.major}.${v.minor}`; + const ociVersionMinor = `${v.major}.${v.minor}`; + const presetsVersion = package_default.devDependencies["@openstreetmap/id-tagging-schema"]; let _this = {}; let _inflight4 = {}; let _fileMap = { "address_formats": "data/address_formats.min.json", - "deprecated": "https://cdn.jsdelivr.net/npm/@openstreetmap/id-tagging-schema@3/dist/deprecated.min.json", - "discarded": "https://cdn.jsdelivr.net/npm/@openstreetmap/id-tagging-schema@3/dist/discarded.min.json", "imagery": "data/imagery.min.json", "intro_graph": "data/intro_graph.min.json", "keepRight": "data/keepRight.min.json", "languages": "data/languages.min.json", "locales": "locales/index.min.json", - "oci_defaults": `https://cdn.jsdelivr.net/npm/osm-community-index@${vMinor}/dist/defaults.min.json`, - "oci_features": `https://cdn.jsdelivr.net/npm/osm-community-index@${vMinor}/dist/featureCollection.min.json`, - "oci_resources": `https://cdn.jsdelivr.net/npm/osm-community-index@${vMinor}/dist/resources.min.json`, - "preset_categories": "https://cdn.jsdelivr.net/npm/@openstreetmap/id-tagging-schema@3/dist/preset_categories.min.json", - "preset_defaults": "https://cdn.jsdelivr.net/npm/@openstreetmap/id-tagging-schema@3/dist/preset_defaults.min.json", - "preset_fields": "https://cdn.jsdelivr.net/npm/@openstreetmap/id-tagging-schema@3/dist/fields.min.json", - "preset_presets": "https://cdn.jsdelivr.net/npm/@openstreetmap/id-tagging-schema@3/dist/presets.min.json", "phone_formats": "data/phone_formats.min.json", "qa_data": "data/qa_data.min.json", "shortcuts": "data/shortcuts.min.json", "territory_languages": "data/territory_languages.min.json", - "wmf_sitematrix": "https://cdn.jsdelivr.net/npm/wmf-sitematrix@0.1/wikipedia.min.json" + "oci_defaults": ociCdnUrl.replace("{version}", ociVersionMinor) + "dist/defaults.min.json", + "oci_features": ociCdnUrl.replace("{version}", ociVersionMinor) + "dist/featureCollection.min.json", + "oci_resources": ociCdnUrl.replace("{version}", ociVersionMinor) + "dist/resources.min.json", + "presets_package": presetsCdnUrl.replace("{presets_version}", presetsVersion) + "package.json", + "deprecated": presetsCdnUrl + "dist/deprecated.min.json", + "discarded": presetsCdnUrl + "dist/discarded.min.json", + "preset_categories": presetsCdnUrl + "dist/preset_categories.min.json", + "preset_defaults": presetsCdnUrl + "dist/preset_defaults.min.json", + "preset_fields": presetsCdnUrl + "dist/fields.min.json", + "preset_presets": presetsCdnUrl + "dist/presets.min.json", + "wmf_sitematrix": wmfSitematrixCdnUrl.replace("{version}", "0.1") + "wikipedia.min.json" }; let _cachedData = {}; _this.cache = () => _cachedData; @@ -22533,6 +22934,16 @@ if (!url) { return Promise.reject(`Unknown data file for "${which}"`); } + if (url.includes("{presets_version}")) { + return _this.get("presets_package").then((result) => { + const presetsVersion2 = result.version; + return getUrl(url.replace("{presets_version}", presetsVersion2), which); + }); + } else { + return getUrl(url); + } + }; + function getUrl(url, which) { let prom = _inflight4[url]; if (!prom) { _inflight4[url] = prom = fetch(url).then((response) => { @@ -22555,7 +22966,7 @@ }); } return prom; - }; + } _this.fileMap = function(val) { if (!arguments.length) return _fileMap; @@ -22585,10 +22996,9 @@ return _this; } - // node_modules/@ideditor/country-coder/dist/country-coder.mjs + // node_modules/@rapideditor/country-coder/dist/country-coder.mjs var import_which_polygon = __toESM(require_which_polygon(), 1); - var type = "FeatureCollection"; - var features = [ + var borders_default = { type: "FeatureCollection", features: [ { type: "Feature", properties: { wikidata: "Q21", nameEn: "England", aliases: ["GB-ENG"], country: "GB", groups: ["Q23666", "Q3336843", "154", "150", "UN"], driveSide: "left", roadSpeedUnit: "mph", roadHeightUnit: "ft", callingCodes: ["44"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-6.03913, 51.13217], [-7.74976, 48.64773], [1.17405, 50.74239], [2.18458, 51.52087], [2.56575, 51.85301], [0.792, 57.56437], [-2.30613, 55.62698], [-2.17058, 55.45916], [-2.6095, 55.28488], [-2.63532, 55.19452], [-3.02906, 55.04606], [-3.09361, 54.94924], [-3.38407, 54.94278], [-4.1819, 54.57861], [-3.5082, 53.54318], [-3.08228, 53.25526], [-3.03675, 53.25092], [-2.92329, 53.19383], [-2.92022, 53.17685], [-2.98598, 53.15589], [-2.90649, 53.10964], [-2.87469, 53.12337], [-2.89131, 53.09374], [-2.83133, 52.99184], [-2.7251, 52.98389], [-2.72221, 52.92969], [-2.80549, 52.89428], [-2.85897, 52.94487], [-2.92401, 52.93836], [-2.97243, 52.9651], [-3.13576, 52.895], [-3.15744, 52.84947], [-3.16105, 52.79599], [-3.08734, 52.77504], [-3.01001, 52.76636], [-2.95581, 52.71794], [-3.01724, 52.72083], [-3.04398, 52.65435], [-3.13648, 52.58208], [-3.12926, 52.5286], [-3.09746, 52.53077], [-3.08662, 52.54811], [-3.00929, 52.57774], [-2.99701, 52.551], [-3.03603, 52.49969], [-3.13359, 52.49174], [-3.22971, 52.45344], [-3.22754, 52.42526], [-3.04687, 52.34504], [-2.95364, 52.3501], [-2.99701, 52.323], [-3.00785, 52.2753], [-3.09289, 52.20546], [-3.12638, 52.08114], [-2.97111, 51.90456], [-2.8818, 51.93196], [-2.78742, 51.88833], [-2.74277, 51.84367], [-2.66234, 51.83555], [-2.66336, 51.59504], [-3.20563, 51.31615], [-6.03913, 51.13217]]]] } }, { type: "Feature", properties: { wikidata: "Q22", nameEn: "Scotland", aliases: ["GB-SCT"], country: "GB", groups: ["Q23666", "Q3336843", "154", "150", "UN"], driveSide: "left", roadSpeedUnit: "mph", roadHeightUnit: "ft", callingCodes: ["44"] }, geometry: { type: "MultiPolygon", coordinates: [[[[0.792, 57.56437], [-0.3751, 61.32236], [-14.78497, 57.60709], [-6.82333, 55.83103], [-4.69044, 54.3629], [-3.38407, 54.94278], [-3.09361, 54.94924], [-3.02906, 55.04606], [-2.63532, 55.19452], [-2.6095, 55.28488], [-2.17058, 55.45916], [-2.30613, 55.62698], [0.792, 57.56437]]]] } }, { type: "Feature", properties: { wikidata: "Q25", nameEn: "Wales", aliases: ["GB-WLS"], country: "GB", groups: ["Q23666", "Q3336843", "154", "150", "UN"], driveSide: "left", roadSpeedUnit: "mph", roadHeightUnit: "ft", callingCodes: ["44"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-3.5082, 53.54318], [-5.37267, 53.63269], [-6.03913, 51.13217], [-3.20563, 51.31615], [-2.66336, 51.59504], [-2.66234, 51.83555], [-2.74277, 51.84367], [-2.78742, 51.88833], [-2.8818, 51.93196], [-2.97111, 51.90456], [-3.12638, 52.08114], [-3.09289, 52.20546], [-3.00785, 52.2753], [-2.99701, 52.323], [-2.95364, 52.3501], [-3.04687, 52.34504], [-3.22754, 52.42526], [-3.22971, 52.45344], [-3.13359, 52.49174], [-3.03603, 52.49969], [-2.99701, 52.551], [-3.00929, 52.57774], [-3.08662, 52.54811], [-3.09746, 52.53077], [-3.12926, 52.5286], [-3.13648, 52.58208], [-3.04398, 52.65435], [-3.01724, 52.72083], [-2.95581, 52.71794], [-3.01001, 52.76636], [-3.08734, 52.77504], [-3.16105, 52.79599], [-3.15744, 52.84947], [-3.13576, 52.895], [-2.97243, 52.9651], [-2.92401, 52.93836], [-2.85897, 52.94487], [-2.80549, 52.89428], [-2.72221, 52.92969], [-2.7251, 52.98389], [-2.83133, 52.99184], [-2.89131, 53.09374], [-2.87469, 53.12337], [-2.90649, 53.10964], [-2.98598, 53.15589], [-2.92022, 53.17685], [-2.92329, 53.19383], [-3.03675, 53.25092], [-3.08228, 53.25526], [-3.5082, 53.54318]]]] } }, @@ -22765,7 +23175,7 @@ { type: "Feature", properties: { iso1A2: "CD", iso1A3: "COD", iso1N3: "180", wikidata: "Q974", nameEn: "Democratic Republic of the Congo", aliases: ["ZR"], groups: ["017", "202", "002", "UN"], callingCodes: ["243"] }, geometry: { type: "MultiPolygon", coordinates: [[[[27.44012, 5.07349], [27.09575, 5.22305], [26.93064, 5.13535], [26.85579, 5.03887], [26.74572, 5.10685], [26.48595, 5.04984], [26.13371, 5.25594], [25.86073, 5.19455], [25.53271, 5.37431], [25.34558, 5.29101], [25.31256, 5.03668], [24.71816, 4.90509], [24.46719, 5.0915], [23.38847, 4.60013], [22.94817, 4.82392], [22.89094, 4.79321], [22.84691, 4.69887], [22.78526, 4.71423], [22.6928, 4.47285], [22.60915, 4.48821], [22.5431, 4.22041], [22.45504, 4.13039], [22.27682, 4.11347], [22.10721, 4.20723], [21.6405, 4.317], [21.55904, 4.25553], [21.25744, 4.33676], [21.21341, 4.29285], [21.11214, 4.33895], [21.08793, 4.39603], [20.90383, 4.44877], [20.60184, 4.42394], [18.62755, 3.47564], [18.63857, 3.19342], [18.10683, 2.26876], [18.08034, 1.58553], [17.85887, 1.04327], [17.86989, 0.58873], [17.95255, 0.48128], [17.93877, 0.32424], [17.81204, 0.23884], [17.66051, -0.26535], [17.72112, -0.52707], [17.32438, -0.99265], [16.97999, -1.12762], [16.70724, -1.45815], [16.50336, -1.8795], [16.16173, -2.16586], [16.22785, -2.59528], [16.1755, -3.25014], [16.21407, -3.2969], [15.89448, -3.9513], [15.53081, -4.042], [15.48121, -4.22062], [15.41785, -4.28381], [15.32693, -4.27282], [15.25411, -4.31121], [15.1978, -4.32388], [14.83101, -4.80838], [14.67948, -4.92093], [14.5059, -4.84956], [14.41499, -4.8825], [14.37366, -4.56125], [14.47284, -4.42941], [14.3957, -4.36623], [14.40672, -4.28381], [13.9108, -4.50906], [13.81162, -4.41842], [13.71794, -4.44864], [13.70417, -4.72601], [13.50305, -4.77818], [13.41764, -4.89897], [13.11182, -4.5942], [13.09648, -4.63739], [13.11195, -4.67745], [12.8733, -4.74346], [12.70868, -4.95505], [12.63465, -4.94632], [12.60251, -5.01715], [12.46297, -5.09408], [12.49815, -5.14058], [12.51589, -5.1332], [12.53586, -5.14658], [12.53599, -5.1618], [12.52301, -5.17481], [12.52318, -5.74353], [12.26557, -5.74031], [12.20376, -5.76338], [11.95767, -5.94705], [12.42245, -6.07585], [13.04371, -5.87078], [16.55507, -5.85631], [16.96282, -7.21787], [17.5828, -8.13784], [18.33635, -8.00126], [19.33698, -7.99743], [19.5469, -7.00195], [20.30218, -6.98955], [20.31846, -6.91953], [20.61689, -6.90876], [20.56263, -7.28566], [21.79824, -7.29628], [21.84856, -9.59871], [22.19039, -9.94628], [22.32604, -10.76291], [22.17954, -10.85884], [22.25951, -11.24911], [22.54205, -11.05784], [23.16602, -11.10577], [23.45631, -10.946], [23.86868, -11.02856], [24.00027, -10.89356], [24.34528, -11.06816], [24.42612, -11.44975], [25.34069, -11.19707], [25.33058, -11.65767], [26.01777, -11.91488], [26.88687, -12.01868], [27.04351, -11.61312], [27.22541, -11.60323], [27.21025, -11.76157], [27.59932, -12.22123], [28.33199, -12.41375], [29.01918, -13.41353], [29.60531, -13.21685], [29.65078, -13.41844], [29.81551, -13.44683], [29.8139, -12.14898], [29.48404, -12.23604], [29.4992, -12.43843], [29.18592, -12.37921], [28.48357, -11.87532], [28.37241, -11.57848], [28.65032, -10.65133], [28.62795, -9.92942], [28.68532, -9.78], [28.56208, -9.49122], [28.51627, -9.44726], [28.52636, -9.35379], [28.36562, -9.30091], [28.38526, -9.23393], [28.9711, -8.66935], [28.88917, -8.4831], [30.79243, -8.27382], [30.2567, -7.14121], [29.52552, -6.2731], [29.43673, -4.44845], [29.23708, -3.75856], [29.21463, -3.3514], [29.25633, -3.05471], [29.17258, -2.99385], [29.16037, -2.95457], [29.09797, -2.91935], [29.09119, -2.87871], [29.0505, -2.81774], [29.00404, -2.81978], [29.00167, -2.78523], [29.04081, -2.7416], [29.00357, -2.70596], [28.94346, -2.69124], [28.89793, -2.66111], [28.90226, -2.62385], [28.89288, -2.55848], [28.87943, -2.55165], [28.86193, -2.53185], [28.86209, -2.5231], [28.87497, -2.50887], [28.88846, -2.50493], [28.89342, -2.49017], [28.89132, -2.47557], [28.86846, -2.44866], [28.86826, -2.41888], [28.89601, -2.37321], [28.95642, -2.37321], [29.00051, -2.29001], [29.105, -2.27043], [29.17562, -2.12278], [29.11847, -1.90576], [29.24458, -1.69663], [29.24323, -1.66826], [29.36322, -1.50887], [29.45038, -1.5054], [29.53062, -1.40499], [29.59061, -1.39016], [29.58388, -0.89821], [29.63006, -0.8997], [29.62708, -0.71055], [29.67176, -0.55714], [29.67474, -0.47969], [29.65091, -0.46777], [29.72687, -0.08051], [29.7224, 0.07291], [29.77454, 0.16675], [29.81922, 0.16824], [29.87284, 0.39166], [29.97413, 0.52124], [29.95477, 0.64486], [29.98307, 0.84295], [30.1484, 0.89805], [30.22139, 0.99635], [30.24671, 1.14974], [30.48503, 1.21675], [31.30127, 2.11006], [31.28042, 2.17853], [31.20148, 2.2217], [31.1985, 2.29462], [31.12104, 2.27676], [31.07934, 2.30207], [31.06593, 2.35862], [30.96911, 2.41071], [30.91102, 2.33332], [30.83059, 2.42559], [30.74271, 2.43601], [30.75612, 2.5863], [30.8857, 2.83923], [30.8574, 2.9508], [30.77101, 3.04897], [30.84251, 3.26908], [30.93486, 3.40737], [30.94081, 3.50847], [30.85153, 3.48867], [30.85997, 3.5743], [30.80713, 3.60506], [30.78512, 3.67097], [30.56277, 3.62703], [30.57378, 3.74567], [30.55396, 3.84451], [30.47691, 3.83353], [30.27658, 3.95653], [30.22374, 3.93896], [30.1621, 4.10586], [30.06964, 4.13221], [29.79666, 4.37809], [29.82087, 4.56246], [29.49726, 4.7007], [29.43341, 4.50101], [29.22207, 4.34297], [29.03054, 4.48784], [28.8126, 4.48784], [28.6651, 4.42638], [28.20719, 4.35614], [27.79551, 4.59976], [27.76469, 4.79284], [27.65462, 4.89375], [27.56656, 4.89375], [27.44012, 5.07349]]]] } }, { type: "Feature", properties: { iso1A2: "CF", iso1A3: "CAF", iso1N3: "140", wikidata: "Q929", nameEn: "Central African Republic", groups: ["017", "202", "002", "UN"], callingCodes: ["236"] }, geometry: { type: "MultiPolygon", coordinates: [[[[22.87758, 10.91915], [22.45889, 11.00246], [21.72139, 10.64136], [21.71479, 10.29932], [21.63553, 10.217], [21.52766, 10.2105], [21.34934, 9.95907], [21.26348, 9.97642], [20.82979, 9.44696], [20.36748, 9.11019], [19.06421, 9.00367], [18.86388, 8.87971], [19.11044, 8.68172], [18.79783, 8.25929], [18.67455, 8.22226], [18.62612, 8.14163], [18.64153, 8.08714], [18.6085, 8.05009], [18.02731, 8.01085], [17.93926, 7.95853], [17.67288, 7.98905], [16.8143, 7.53971], [16.6668, 7.67281], [16.658, 7.75353], [16.59415, 7.76444], [16.58315, 7.88657], [16.41583, 7.77971], [16.40703, 7.68809], [15.79942, 7.44149], [15.73118, 7.52006], [15.49743, 7.52179], [15.23397, 7.25135], [15.04717, 6.77085], [14.96311, 6.75693], [14.79966, 6.39043], [14.80122, 6.34866], [14.74206, 6.26356], [14.56149, 6.18928], [14.43073, 6.08867], [14.42917, 6.00508], [14.49455, 5.91683], [14.60974, 5.91838], [14.62375, 5.70466], [14.58951, 5.59777], [14.62531, 5.51411], [14.52724, 5.28319], [14.57083, 5.23979], [14.65489, 5.21343], [14.73383, 4.6135], [15.00825, 4.41458], [15.08609, 4.30282], [15.10644, 4.1362], [15.17482, 4.05131], [15.07686, 4.01805], [15.73522, 3.24348], [15.77725, 3.26835], [16.05449, 3.02306], [16.08252, 2.45708], [16.19357, 2.21537], [16.50126, 2.84739], [16.46701, 2.92512], [16.57598, 3.47999], [16.68283, 3.54257], [17.01746, 3.55136], [17.35649, 3.63045], [17.46876, 3.70515], [17.60966, 3.63705], [17.83421, 3.61068], [17.85842, 3.53378], [18.05656, 3.56893], [18.14902, 3.54476], [18.17323, 3.47665], [18.24148, 3.50302], [18.2723, 3.57992], [18.39558, 3.58212], [18.49245, 3.63924], [18.58711, 3.49423], [18.62755, 3.47564], [20.60184, 4.42394], [20.90383, 4.44877], [21.08793, 4.39603], [21.11214, 4.33895], [21.21341, 4.29285], [21.25744, 4.33676], [21.55904, 4.25553], [21.6405, 4.317], [22.10721, 4.20723], [22.27682, 4.11347], [22.45504, 4.13039], [22.5431, 4.22041], [22.60915, 4.48821], [22.6928, 4.47285], [22.78526, 4.71423], [22.84691, 4.69887], [22.89094, 4.79321], [22.94817, 4.82392], [23.38847, 4.60013], [24.46719, 5.0915], [24.71816, 4.90509], [25.31256, 5.03668], [25.34558, 5.29101], [25.53271, 5.37431], [25.86073, 5.19455], [26.13371, 5.25594], [26.48595, 5.04984], [26.74572, 5.10685], [26.85579, 5.03887], [26.93064, 5.13535], [27.09575, 5.22305], [27.44012, 5.07349], [27.26886, 5.25876], [27.23017, 5.37167], [27.28621, 5.56382], [27.22705, 5.62889], [27.22705, 5.71254], [26.51721, 6.09655], [26.58259, 6.1987], [26.32729, 6.36272], [26.38022, 6.63493], [25.90076, 7.09549], [25.37461, 7.33024], [25.35281, 7.42595], [25.20337, 7.50312], [25.20649, 7.61115], [25.29214, 7.66675], [25.25319, 7.8487], [24.98855, 7.96588], [24.85156, 8.16933], [24.35965, 8.26177], [24.13238, 8.36959], [24.25691, 8.69288], [23.51905, 8.71749], [23.59065, 8.99743], [23.44744, 8.99128], [23.4848, 9.16959], [23.56263, 9.19418], [23.64358, 9.28637], [23.64981, 9.44303], [23.62179, 9.53823], [23.69155, 9.67566], [23.67164, 9.86923], [23.3128, 10.45214], [23.02221, 10.69235], [22.87758, 10.91915]]]] } }, { type: "Feature", properties: { iso1A2: "CG", iso1A3: "COG", iso1N3: "178", wikidata: "Q971", nameEn: "Republic of the Congo", groups: ["017", "202", "002", "UN"], callingCodes: ["242"] }, geometry: { type: "MultiPolygon", coordinates: [[[[18.62755, 3.47564], [18.58711, 3.49423], [18.49245, 3.63924], [18.39558, 3.58212], [18.2723, 3.57992], [18.24148, 3.50302], [18.17323, 3.47665], [18.14902, 3.54476], [18.05656, 3.56893], [17.85842, 3.53378], [17.83421, 3.61068], [17.60966, 3.63705], [17.46876, 3.70515], [17.35649, 3.63045], [17.01746, 3.55136], [16.68283, 3.54257], [16.57598, 3.47999], [16.46701, 2.92512], [16.50126, 2.84739], [16.19357, 2.21537], [16.15568, 2.18955], [16.08563, 2.19733], [16.05294, 1.9811], [16.14634, 1.70259], [16.02647, 1.65591], [16.02959, 1.76483], [15.48942, 1.98265], [15.34776, 1.91264], [15.22634, 2.03243], [15.00996, 1.98887], [14.61145, 2.17866], [13.29457, 2.16106], [13.13461, 1.57238], [13.25447, 1.32339], [13.15519, 1.23368], [13.89582, 1.4261], [14.25186, 1.39842], [14.48179, 0.9152], [14.26066, 0.57255], [14.10909, 0.58563], [13.88648, 0.26652], [13.90632, -0.2287], [14.06862, -0.20826], [14.2165, -0.38261], [14.41887, -0.44799], [14.52569, -0.57818], [14.41838, -1.89412], [14.25932, -1.97624], [14.23518, -2.15671], [14.16202, -2.23916], [14.23829, -2.33715], [14.10442, -2.49268], [13.85846, -2.46935], [13.92073, -2.35581], [13.75884, -2.09293], [13.47977, -2.43224], [13.02759, -2.33098], [12.82172, -1.91091], [12.61312, -1.8129], [12.44656, -1.92025], [12.47925, -2.32626], [12.04895, -2.41704], [11.96866, -2.33559], [11.74605, -2.39936], [11.57637, -2.33379], [11.64487, -2.61865], [11.5359, -2.85654], [11.64798, -2.81146], [11.80365, -3.00424], [11.70558, -3.0773], [11.70227, -3.17465], [11.96554, -3.30267], [11.8318, -3.5812], [11.92719, -3.62768], [11.87083, -3.71571], [11.68608, -3.68942], [11.57949, -3.52798], [11.48764, -3.51089], [11.22301, -3.69888], [11.12647, -3.94169], [10.75913, -4.39519], [11.50888, -5.33417], [12.00924, -5.02627], [12.16068, -4.90089], [12.20901, -4.75642], [12.25587, -4.79437], [12.32324, -4.78415], [12.40964, -4.60609], [12.64835, -4.55937], [12.76844, -4.38709], [12.87096, -4.40315], [12.91489, -4.47907], [13.09648, -4.63739], [13.11182, -4.5942], [13.41764, -4.89897], [13.50305, -4.77818], [13.70417, -4.72601], [13.71794, -4.44864], [13.81162, -4.41842], [13.9108, -4.50906], [14.40672, -4.28381], [14.3957, -4.36623], [14.47284, -4.42941], [14.37366, -4.56125], [14.41499, -4.8825], [14.5059, -4.84956], [14.67948, -4.92093], [14.83101, -4.80838], [15.1978, -4.32388], [15.25411, -4.31121], [15.32693, -4.27282], [15.41785, -4.28381], [15.48121, -4.22062], [15.53081, -4.042], [15.89448, -3.9513], [16.21407, -3.2969], [16.1755, -3.25014], [16.22785, -2.59528], [16.16173, -2.16586], [16.50336, -1.8795], [16.70724, -1.45815], [16.97999, -1.12762], [17.32438, -0.99265], [17.72112, -0.52707], [17.66051, -0.26535], [17.81204, 0.23884], [17.93877, 0.32424], [17.95255, 0.48128], [17.86989, 0.58873], [17.85887, 1.04327], [18.08034, 1.58553], [18.10683, 2.26876], [18.63857, 3.19342], [18.62755, 3.47564]]]] } }, - { type: "Feature", properties: { iso1A2: "CH", iso1A3: "CHE", iso1N3: "756", wikidata: "Q39", nameEn: "Switzerland", groups: ["155", "150", "UN"], callingCodes: ["41"] }, geometry: { type: "MultiPolygon", coordinates: [[[[8.72809, 47.69282], [8.72617, 47.69651], [8.73671, 47.7169], [8.70543, 47.73121], [8.74251, 47.75168], [8.71778, 47.76571], [8.68985, 47.75686], [8.68022, 47.78599], [8.65292, 47.80066], [8.64425, 47.76398], [8.62408, 47.7626], [8.61657, 47.79998], [8.56415, 47.80633], [8.56814, 47.78001], [8.48868, 47.77215], [8.45771, 47.7493], [8.44807, 47.72426], [8.40569, 47.69855], [8.4211, 47.68407], [8.40473, 47.67499], [8.41346, 47.66676], [8.42264, 47.66667], [8.44711, 47.65379], [8.4667, 47.65747], [8.46605, 47.64103], [8.49656, 47.64709], [8.5322, 47.64687], [8.52801, 47.66059], [8.56141, 47.67088], [8.57683, 47.66158], [8.6052, 47.67258], [8.61113, 47.66332], [8.62884, 47.65098], [8.62049, 47.63757], [8.60412, 47.63735], [8.61471, 47.64514], [8.60701, 47.65271], [8.59545, 47.64298], [8.60348, 47.61204], [8.57586, 47.59537], [8.55756, 47.62394], [8.51686, 47.63476], [8.50747, 47.61897], [8.45578, 47.60121], [8.46637, 47.58389], [8.48949, 47.588], [8.49431, 47.58107], [8.43235, 47.56617], [8.39477, 47.57826], [8.38273, 47.56608], [8.32735, 47.57133], [8.30277, 47.58607], [8.29524, 47.5919], [8.29722, 47.60603], [8.2824, 47.61225], [8.26313, 47.6103], [8.25863, 47.61571], [8.23809, 47.61204], [8.22577, 47.60385], [8.22011, 47.6181], [8.20617, 47.62141], [8.19378, 47.61636], [8.1652, 47.5945], [8.14947, 47.59558], [8.13823, 47.59147], [8.13662, 47.58432], [8.11543, 47.5841], [8.10395, 47.57918], [8.10002, 47.56504], [8.08557, 47.55768], [8.06663, 47.56374], [8.04383, 47.55443], [8.02136, 47.55096], [8.00113, 47.55616], [7.97581, 47.55493], [7.95682, 47.55789], [7.94494, 47.54511], [7.91251, 47.55031], [7.90673, 47.57674], [7.88664, 47.58854], [7.84412, 47.5841], [7.81901, 47.58798], [7.79486, 47.55691], [7.75261, 47.54599], [7.71961, 47.54219], [7.69642, 47.53297], [7.68101, 47.53232], [7.6656, 47.53752], [7.66174, 47.54554], [7.65083, 47.54662], [7.63338, 47.56256], [7.67655, 47.56435], [7.68904, 47.57133], [7.67115, 47.5871], [7.68486, 47.59601], [7.69385, 47.60099], [7.68229, 47.59905], [7.67395, 47.59212], [7.64599, 47.59695], [7.64213, 47.5944], [7.64309, 47.59151], [7.61929, 47.57683], [7.60459, 47.57869], [7.60523, 47.58519], [7.58945, 47.59017], [7.58386, 47.57536], [7.56684, 47.57785], [7.56548, 47.57617], [7.55689, 47.57232], [7.55652, 47.56779], [7.53634, 47.55553], [7.52831, 47.55347], [7.51723, 47.54578], [7.50873, 47.54546], [7.49691, 47.53821], [7.50588, 47.52856], [7.51904, 47.53515], [7.53199, 47.5284], [7.5229, 47.51644], [7.49804, 47.51798], [7.51076, 47.49651], [7.47534, 47.47932], [7.43356, 47.49712], [7.42923, 47.48628], [7.4583, 47.47216], [7.4462, 47.46264], [7.43088, 47.45846], [7.40308, 47.43638], [7.35603, 47.43432], [7.33526, 47.44186], [7.24669, 47.4205], [7.17026, 47.44312], [7.19583, 47.49455], [7.16249, 47.49025], [7.12781, 47.50371], [7.07425, 47.48863], [7.0231, 47.50522], [6.98425, 47.49432], [7.0024, 47.45264], [6.93953, 47.43388], [6.93744, 47.40714], [6.88542, 47.37262], [6.87959, 47.35335], [7.03125, 47.36996], [7.0564, 47.35134], [7.05305, 47.33304], [6.94316, 47.28747], [6.95108, 47.26428], [6.9508, 47.24338], [6.8489, 47.15933], [6.76788, 47.1208], [6.68823, 47.06616], [6.71531, 47.0494], [6.43341, 46.92703], [6.46456, 46.88865], [6.43216, 46.80336], [6.45209, 46.77502], [6.38351, 46.73171], [6.27135, 46.68251], [6.11084, 46.57649], [6.1567, 46.54402], [6.07269, 46.46244], [6.08427, 46.44305], [6.06407, 46.41676], [6.09926, 46.40768], [6.15016, 46.3778], [6.15985, 46.37721], [6.16987, 46.36759], [6.15738, 46.3491], [6.13876, 46.33844], [6.1198, 46.31157], [6.11697, 46.29547], [6.1013, 46.28512], [6.11926, 46.2634], [6.12446, 46.25059], [6.10071, 46.23772], [6.08563, 46.24651], [6.07072, 46.24085], [6.0633, 46.24583], [6.05029, 46.23518], [6.04602, 46.23127], [6.03342, 46.2383], [6.02461, 46.23313], [5.97542, 46.21525], [5.96515, 46.19638], [5.99573, 46.18587], [5.98846, 46.17046], [5.98188, 46.17392], [5.97508, 46.15863], [5.9641, 46.14412], [5.95781, 46.12925], [5.97893, 46.13303], [5.9871, 46.14499], [6.01791, 46.14228], [6.03614, 46.13712], [6.04564, 46.14031], [6.05203, 46.15191], [6.07491, 46.14879], [6.09199, 46.15191], [6.09926, 46.14373], [6.13397, 46.1406], [6.15305, 46.15194], [6.18116, 46.16187], [6.18871, 46.16644], [6.18707, 46.17999], [6.19552, 46.18401], [6.19807, 46.18369], [6.20539, 46.19163], [6.21114, 46.1927], [6.21273, 46.19409], [6.21603, 46.19507], [6.21844, 46.19837], [6.22222, 46.19888], [6.22175, 46.20045], [6.23544, 46.20714], [6.23913, 46.20511], [6.24821, 46.20531], [6.26007, 46.21165], [6.27694, 46.21566], [6.29663, 46.22688], [6.31041, 46.24417], [6.29474, 46.26221], [6.26749, 46.24745], [6.24952, 46.26255], [6.23775, 46.27822], [6.25137, 46.29014], [6.24826, 46.30175], [6.21981, 46.31304], [6.25432, 46.3632], [6.53358, 46.45431], [6.82312, 46.42661], [6.8024, 46.39171], [6.77152, 46.34784], [6.86052, 46.28512], [6.78968, 46.14058], [6.89321, 46.12548], [6.87868, 46.03855], [6.93862, 46.06502], [7.00946, 45.9944], [7.04151, 45.92435], [7.10685, 45.85653], [7.56343, 45.97421], [7.85949, 45.91485], [7.9049, 45.99945], [7.98881, 45.99867], [8.02906, 46.10331], [8.11383, 46.11577], [8.16866, 46.17817], [8.08814, 46.26692], [8.31162, 46.38044], [8.30648, 46.41587], [8.42464, 46.46367], [8.46317, 46.43712], [8.45032, 46.26869], [8.62242, 46.12112], [8.75697, 46.10395], [8.80778, 46.10085], [8.85617, 46.0748], [8.79414, 46.00913], [8.78585, 45.98973], [8.79362, 45.99207], [8.8319, 45.9879], [8.85121, 45.97239], [8.86688, 45.96135], [8.88904, 45.95465], [8.93649, 45.86775], [8.94372, 45.86587], [8.93504, 45.86245], [8.91129, 45.8388], [8.94737, 45.84285], [8.9621, 45.83707], [8.99663, 45.83466], [9.00324, 45.82055], [9.0298, 45.82127], [9.03279, 45.82865], [9.03793, 45.83548], [9.03505, 45.83976], [9.04059, 45.8464], [9.04546, 45.84968], [9.06642, 45.8761], [9.09065, 45.89906], [8.99257, 45.9698], [9.01618, 46.04928], [9.24503, 46.23616], [9.29226, 46.32717], [9.25502, 46.43743], [9.28136, 46.49685], [9.36128, 46.5081], [9.40487, 46.46621], [9.45936, 46.50873], [9.46117, 46.37481], [9.57015, 46.2958], [9.71273, 46.29266], [9.73086, 46.35071], [9.95249, 46.38045], [10.07055, 46.21668], [10.14439, 46.22992], [10.17862, 46.25626], [10.10506, 46.3372], [10.165, 46.41051], [10.03715, 46.44479], [10.10307, 46.61003], [10.23674, 46.63484], [10.25309, 46.57432], [10.46136, 46.53164], [10.49375, 46.62049], [10.44686, 46.64162], [10.40475, 46.63671], [10.38659, 46.67847], [10.47197, 46.85698], [10.48376, 46.93891], [10.36933, 47.00212], [10.30031, 46.92093], [10.24128, 46.93147], [10.22675, 46.86942], [10.10715, 46.84296], [9.98058, 46.91434], [9.88266, 46.93343], [9.87935, 47.01337], [9.60717, 47.06091], [9.55721, 47.04762], [9.54041, 47.06495], [9.47548, 47.05257], [9.47139, 47.06402], [9.51362, 47.08505], [9.52089, 47.10019], [9.51044, 47.13727], [9.48774, 47.17402], [9.4891, 47.19346], [9.50318, 47.22153], [9.52406, 47.24959], [9.53116, 47.27029], [9.54773, 47.2809], [9.55857, 47.29919], [9.58513, 47.31334], [9.59978, 47.34671], [9.62476, 47.36639], [9.65427, 47.36824], [9.66243, 47.37136], [9.6711, 47.37824], [9.67445, 47.38429], [9.67334, 47.39191], [9.6629, 47.39591], [9.65136, 47.40504], [9.65043, 47.41937], [9.6446, 47.43233], [9.64483, 47.43842], [9.65863, 47.44847], [9.65728, 47.45383], [9.6423, 47.45599], [9.62475, 47.45685], [9.62158, 47.45858], [9.60841, 47.47178], [9.60484, 47.46358], [9.60205, 47.46165], [9.59482, 47.46305], [9.58208, 47.48344], [9.56312, 47.49495], [9.55125, 47.53629], [9.25619, 47.65939], [9.18203, 47.65598], [9.17593, 47.65399], [9.1755, 47.65584], [9.1705, 47.65513], [9.15181, 47.66904], [9.13845, 47.66389], [9.09891, 47.67801], [9.02093, 47.6868], [8.94093, 47.65596], [8.89946, 47.64769], [8.87625, 47.65441], [8.87383, 47.67045], [8.85065, 47.68209], [8.86989, 47.70504], [8.82002, 47.71458], [8.80663, 47.73821], [8.77309, 47.72059], [8.76965, 47.7075], [8.79966, 47.70222], [8.79511, 47.67462], [8.75856, 47.68969], [8.72809, 47.69282]], [[8.95861, 45.96485], [8.96668, 45.98436], [8.97741, 45.98317], [8.97604, 45.96151], [8.95861, 45.96485]], [[8.70847, 47.68904], [8.68985, 47.69552], [8.66837, 47.68437], [8.65769, 47.68928], [8.67508, 47.6979], [8.66416, 47.71367], [8.70237, 47.71453], [8.71773, 47.69088], [8.70847, 47.68904]]]] } }, + { type: "Feature", geometry: { type: "MultiPolygon", coordinates: [[[[8.72809, 47.69282], [8.72617, 47.69651], [8.73671, 47.7169], [8.70543, 47.73121], [8.74251, 47.75168], [8.71778, 47.76571], [8.68985, 47.75686], [8.68022, 47.78599], [8.65292, 47.80066], [8.64425, 47.76398], [8.62408, 47.7626], [8.61657, 47.79998], [8.56415, 47.80633], [8.56814, 47.78001], [8.48868, 47.77215], [8.45771, 47.7493], [8.44807, 47.72426], [8.40569, 47.69855], [8.4211, 47.68407], [8.40473, 47.67499], [8.41346, 47.66676], [8.42264, 47.66667], [8.44711, 47.65379], [8.4667, 47.65747], [8.46605, 47.64103], [8.49656, 47.64709], [8.5322, 47.64687], [8.52801, 47.66059], [8.56141, 47.67088], [8.57683, 47.66158], [8.6052, 47.67258], [8.61113, 47.66332], [8.62884, 47.65098], [8.62049, 47.63757], [8.60412, 47.63735], [8.61471, 47.64514], [8.60701, 47.65271], [8.59545, 47.64298], [8.60348, 47.61204], [8.57586, 47.59537], [8.55756, 47.62394], [8.51686, 47.63476], [8.50747, 47.61897], [8.45578, 47.60121], [8.46637, 47.58389], [8.48949, 47.588], [8.49431, 47.58107], [8.43235, 47.56617], [8.39477, 47.57826], [8.38273, 47.56608], [8.35512, 47.57014], [8.32735, 47.57133], [8.30277, 47.58607], [8.29524, 47.5919], [8.29722, 47.60603], [8.2824, 47.61225], [8.26313, 47.6103], [8.25863, 47.61571], [8.23809, 47.61204], [8.22577, 47.60385], [8.22011, 47.6181], [8.20617, 47.62141], [8.19378, 47.61636], [8.1652, 47.5945], [8.14947, 47.59558], [8.13823, 47.59147], [8.13662, 47.58432], [8.11543, 47.5841], [8.10395, 47.57918], [8.10002, 47.56504], [8.08557, 47.55768], [8.06663, 47.56374], [8.04383, 47.55443], [8.02136, 47.55096], [8.00113, 47.55616], [7.97581, 47.55493], [7.95682, 47.55789], [7.94494, 47.54511], [7.91251, 47.55031], [7.90673, 47.57674], [7.88664, 47.58854], [7.84412, 47.5841], [7.81901, 47.58798], [7.79486, 47.55691], [7.75261, 47.54599], [7.71961, 47.54219], [7.69642, 47.53297], [7.68101, 47.53232], [7.6656, 47.53752], [7.66174, 47.54554], [7.65083, 47.54662], [7.63338, 47.56256], [7.67655, 47.56435], [7.68904, 47.57133], [7.67115, 47.5871], [7.68486, 47.59601], [7.69385, 47.60099], [7.68229, 47.59905], [7.67395, 47.59212], [7.64599, 47.59695], [7.64213, 47.5944], [7.64309, 47.59151], [7.61929, 47.57683], [7.60459, 47.57869], [7.60523, 47.58519], [7.58945, 47.59017], [7.58386, 47.57536], [7.56684, 47.57785], [7.56548, 47.57617], [7.55689, 47.57232], [7.55652, 47.56779], [7.53634, 47.55553], [7.52831, 47.55347], [7.51723, 47.54578], [7.50873, 47.54546], [7.49691, 47.53821], [7.50588, 47.52856], [7.51904, 47.53515], [7.53199, 47.5284], [7.5229, 47.51644], [7.49804, 47.51798], [7.51076, 47.49651], [7.47534, 47.47932], [7.43356, 47.49712], [7.42923, 47.48628], [7.4583, 47.47216], [7.4462, 47.46264], [7.43088, 47.45846], [7.40308, 47.43638], [7.35603, 47.43432], [7.33526, 47.44186], [7.24669, 47.4205], [7.17026, 47.44312], [7.19583, 47.49455], [7.16249, 47.49025], [7.12781, 47.50371], [7.07425, 47.48863], [7.0231, 47.50522], [6.98425, 47.49432], [7.0024, 47.45264], [6.93953, 47.43388], [6.93744, 47.40714], [6.88542, 47.37262], [6.87959, 47.35335], [7.03125, 47.36996], [7.0564, 47.35134], [7.05305, 47.33304], [6.94316, 47.28747], [6.95108, 47.26428], [6.9508, 47.24338], [6.8489, 47.15933], [6.76788, 47.1208], [6.68823, 47.06616], [6.71531, 47.0494], [6.43341, 46.92703], [6.46456, 46.88865], [6.43216, 46.80336], [6.45209, 46.77502], [6.38351, 46.73171], [6.27135, 46.68251], [6.11084, 46.57649], [6.1567, 46.54402], [6.07269, 46.46244], [6.08427, 46.44305], [6.06407, 46.41676], [6.09926, 46.40768], [6.15016, 46.3778], [6.15985, 46.37721], [6.16987, 46.36759], [6.15738, 46.3491], [6.13876, 46.33844], [6.1198, 46.31157], [6.11697, 46.29547], [6.1013, 46.28512], [6.11926, 46.2634], [6.12446, 46.25059], [6.10071, 46.23772], [6.08563, 46.24651], [6.07072, 46.24085], [6.0633, 46.24583], [6.05029, 46.23518], [6.04602, 46.23127], [6.03342, 46.2383], [6.02461, 46.23313], [5.97542, 46.21525], [5.96515, 46.19638], [5.99573, 46.18587], [5.98846, 46.17046], [5.98188, 46.17392], [5.97508, 46.15863], [5.9641, 46.14412], [5.95781, 46.12925], [5.97893, 46.13303], [5.9871, 46.14499], [6.01791, 46.14228], [6.03614, 46.13712], [6.04564, 46.14031], [6.05203, 46.15191], [6.07491, 46.14879], [6.09199, 46.15191], [6.09926, 46.14373], [6.13397, 46.1406], [6.15305, 46.15194], [6.18116, 46.16187], [6.18871, 46.16644], [6.18707, 46.17999], [6.19552, 46.18401], [6.19807, 46.18369], [6.20539, 46.19163], [6.21114, 46.1927], [6.21273, 46.19409], [6.21603, 46.19507], [6.21844, 46.19837], [6.22222, 46.19888], [6.22175, 46.20045], [6.23544, 46.20714], [6.23913, 46.20511], [6.24821, 46.20531], [6.26007, 46.21165], [6.27694, 46.21566], [6.29663, 46.22688], [6.31041, 46.24417], [6.29474, 46.26221], [6.26749, 46.24745], [6.24952, 46.26255], [6.23775, 46.27822], [6.25137, 46.29014], [6.24826, 46.30175], [6.21981, 46.31304], [6.25432, 46.3632], [6.53358, 46.45431], [6.82312, 46.42661], [6.8024, 46.39171], [6.77152, 46.34784], [6.86052, 46.28512], [6.78968, 46.14058], [6.89321, 46.12548], [6.87868, 46.03855], [6.93862, 46.06502], [7.00946, 45.9944], [7.04151, 45.92435], [7.10685, 45.85653], [7.56343, 45.97421], [7.85949, 45.91485], [7.9049, 45.99945], [7.98881, 45.99867], [8.02906, 46.10331], [8.11383, 46.11577], [8.16866, 46.17817], [8.08814, 46.26692], [8.31162, 46.38044], [8.30648, 46.41587], [8.42464, 46.46367], [8.46317, 46.43712], [8.45032, 46.26869], [8.62242, 46.12112], [8.75697, 46.10395], [8.80778, 46.10085], [8.85617, 46.0748], [8.79414, 46.00913], [8.78585, 45.98973], [8.79362, 45.99207], [8.8319, 45.9879], [8.85121, 45.97239], [8.86688, 45.96135], [8.88904, 45.95465], [8.93649, 45.86775], [8.94372, 45.86587], [8.93504, 45.86245], [8.91129, 45.8388], [8.94737, 45.84285], [8.9621, 45.83707], [8.99663, 45.83466], [9.00324, 45.82055], [9.0298, 45.82127], [9.03279, 45.82865], [9.03793, 45.83548], [9.03505, 45.83976], [9.04059, 45.8464], [9.04546, 45.84968], [9.06642, 45.8761], [9.09065, 45.89906], [8.99257, 45.9698], [9.01618, 46.04928], [9.24503, 46.23616], [9.29226, 46.32717], [9.25502, 46.43743], [9.28136, 46.49685], [9.36128, 46.5081], [9.40487, 46.46621], [9.45936, 46.50873], [9.46117, 46.37481], [9.57015, 46.2958], [9.71273, 46.29266], [9.73086, 46.35071], [9.95249, 46.38045], [10.07055, 46.21668], [10.14439, 46.22992], [10.17862, 46.25626], [10.10506, 46.3372], [10.165, 46.41051], [10.03715, 46.44479], [10.10307, 46.61003], [10.23674, 46.63484], [10.25309, 46.57432], [10.46136, 46.53164], [10.49375, 46.62049], [10.44686, 46.64162], [10.40475, 46.63671], [10.38659, 46.67847], [10.47197, 46.85698], [10.48376, 46.93891], [10.36933, 47.00212], [10.30031, 46.92093], [10.24128, 46.93147], [10.22675, 46.86942], [10.10715, 46.84296], [9.98058, 46.91434], [9.88266, 46.93343], [9.87935, 47.01337], [9.60717, 47.06091], [9.55721, 47.04762], [9.54041, 47.06495], [9.47548, 47.05257], [9.47139, 47.06402], [9.51362, 47.08505], [9.52089, 47.10019], [9.51044, 47.13727], [9.48774, 47.17402], [9.4891, 47.19346], [9.50318, 47.22153], [9.52406, 47.24959], [9.53116, 47.27029], [9.54773, 47.2809], [9.55857, 47.29919], [9.58513, 47.31334], [9.59978, 47.34671], [9.62476, 47.36639], [9.65427, 47.36824], [9.66243, 47.37136], [9.6711, 47.37824], [9.67445, 47.38429], [9.67334, 47.39191], [9.6629, 47.39591], [9.65136, 47.40504], [9.65043, 47.41937], [9.6446, 47.43233], [9.64483, 47.43842], [9.65863, 47.44847], [9.65728, 47.45383], [9.6423, 47.45599], [9.62475, 47.45685], [9.62158, 47.45858], [9.60841, 47.47178], [9.60484, 47.46358], [9.60205, 47.46165], [9.59482, 47.46305], [9.58208, 47.48344], [9.56312, 47.49495], [9.55125, 47.53629], [9.25619, 47.65939], [9.18203, 47.65598], [9.17593, 47.65399], [9.1755, 47.65584], [9.1705, 47.65513], [9.15181, 47.66904], [9.13845, 47.66389], [9.09891, 47.67801], [9.02093, 47.6868], [8.94093, 47.65596], [8.89946, 47.64769], [8.87625, 47.65441], [8.87383, 47.67045], [8.85065, 47.68209], [8.86989, 47.70504], [8.82002, 47.71458], [8.80663, 47.73821], [8.77309, 47.72059], [8.76965, 47.7075], [8.79966, 47.70222], [8.79511, 47.67462], [8.75856, 47.68969], [8.72809, 47.69282]], [[8.95861, 45.96485], [8.96668, 45.98436], [8.97741, 45.98317], [8.97604, 45.96151], [8.95861, 45.96485]], [[8.70847, 47.68904], [8.68985, 47.69552], [8.66837, 47.68437], [8.65769, 47.68928], [8.67508, 47.6979], [8.66416, 47.71367], [8.70237, 47.71453], [8.71773, 47.69088], [8.70847, 47.68904]]]] }, properties: { iso1A2: "CH", iso1A3: "CHE", iso1N3: "756", wikidata: "Q39", nameEn: "Switzerland", groups: ["155", "150", "UN"], callingCodes: ["41"] } }, { type: "Feature", properties: { iso1A2: "CI", iso1A3: "CIV", iso1N3: "384", wikidata: "Q1008", nameEn: "C\xF4te d'Ivoire", groups: ["011", "202", "002", "UN"], callingCodes: ["225"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-7.52774, 3.7105], [-3.34019, 4.17519], [-3.10675, 5.08515], [-3.11073, 5.12675], [-3.063, 5.13665], [-2.96554, 5.10397], [-2.95261, 5.12477], [-2.75502, 5.10657], [-2.73074, 5.1364], [-2.77625, 5.34621], [-2.72737, 5.34789], [-2.76614, 5.60963], [-2.85378, 5.65156], [-2.93132, 5.62137], [-2.96671, 5.6415], [-2.95323, 5.71865], [-3.01896, 5.71697], [-3.25999, 6.62521], [-3.21954, 6.74407], [-3.23327, 6.81744], [-2.95438, 7.23737], [-2.97822, 7.27165], [-2.92339, 7.60847], [-2.79467, 7.86002], [-2.78395, 7.94974], [-2.74819, 7.92613], [-2.67787, 8.02055], [-2.61232, 8.02645], [-2.62901, 8.11495], [-2.49037, 8.20872], [-2.58243, 8.7789], [-2.66357, 9.01771], [-2.77799, 9.04949], [-2.69814, 9.22717], [-2.68802, 9.49343], [-2.76494, 9.40778], [-2.93012, 9.57403], [-3.00765, 9.74019], [-3.16609, 9.85147], [-3.19306, 9.93781], [-3.27228, 9.84981], [-3.31779, 9.91125], [-3.69703, 9.94279], [-4.25999, 9.76012], [-4.31392, 9.60062], [-4.6426, 9.70696], [-4.96621, 9.89132], [-4.96453, 9.99923], [-5.12465, 10.29788], [-5.39602, 10.2929], [-5.51058, 10.43177], [-5.65135, 10.46767], [-5.78124, 10.43952], [-5.99478, 10.19694], [-6.18851, 10.24244], [-6.1731, 10.46983], [-6.24795, 10.74248], [-6.325, 10.68624], [-6.40646, 10.69922], [-6.42847, 10.5694], [-6.52974, 10.59104], [-6.63541, 10.66893], [-6.68164, 10.35074], [-6.93921, 10.35291], [-7.01186, 10.25111], [-6.97444, 10.21644], [-7.00966, 10.15794], [-7.0603, 10.14711], [-7.13331, 10.24877], [-7.3707, 10.24677], [-7.44555, 10.44602], [-7.52261, 10.4655], [-7.54462, 10.40921], [-7.63048, 10.46334], [-7.92107, 10.15577], [-7.97971, 10.17117], [-8.01225, 10.1021], [-8.11921, 10.04577], [-8.15652, 9.94288], [-8.09434, 9.86936], [-8.14657, 9.55062], [-8.03463, 9.39604], [-7.85056, 9.41812], [-7.90777, 9.20456], [-7.73862, 9.08422], [-7.92518, 8.99332], [-7.95503, 8.81146], [-7.69882, 8.66148], [-7.65653, 8.36873], [-7.92518, 8.50652], [-8.22991, 8.48438], [-8.2411, 8.24196], [-8.062, 8.16071], [-7.98675, 8.20134], [-7.99919, 8.11023], [-7.94695, 8.00925], [-8.06449, 8.04989], [-8.13414, 7.87991], [-8.09931, 7.78626], [-8.21374, 7.54466], [-8.4003, 7.6285], [-8.47114, 7.55676], [-8.41935, 7.51203], [-8.37458, 7.25794], [-8.29249, 7.1691], [-8.31736, 6.82837], [-8.59456, 6.50612], [-8.48652, 6.43797], [-8.45666, 6.49977], [-8.38453, 6.35887], [-8.3298, 6.36381], [-8.17557, 6.28222], [-8.00642, 6.31684], [-7.90692, 6.27728], [-7.83478, 6.20309], [-7.8497, 6.08932], [-7.79747, 6.07696], [-7.78254, 5.99037], [-7.70294, 5.90625], [-7.67309, 5.94337], [-7.48155, 5.80974], [-7.46165, 5.84934], [-7.43677, 5.84687], [-7.43926, 5.74787], [-7.37209, 5.61173], [-7.43428, 5.42355], [-7.36463, 5.32944], [-7.46165, 5.26256], [-7.48901, 5.14118], [-7.55369, 5.08667], [-7.53876, 4.94294], [-7.59349, 4.8909], [-7.53259, 4.35145], [-7.52774, 3.7105]]]] } }, { type: "Feature", properties: { iso1A2: "CK", iso1A3: "COK", iso1N3: "184", wikidata: "Q26988", nameEn: "Cook Islands", country: "NZ", groups: ["061", "009", "UN"], driveSide: "left", callingCodes: ["682"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-168.15106, -10.26955], [-156.45576, -31.75456], [-156.48634, -15.52824], [-156.50903, -7.4975], [-168.15106, -10.26955]]]] } }, { type: "Feature", properties: { iso1A2: "CL", iso1A3: "CHL", iso1N3: "152", wikidata: "Q298", nameEn: "Chile", groups: ["005", "419", "019", "UN"], callingCodes: ["56"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-68.60702, -52.65781], [-68.41683, -52.33516], [-69.97824, -52.00845], [-71.99889, -51.98018], [-72.33873, -51.59954], [-72.31343, -50.58411], [-73.15765, -50.78337], [-73.55259, -49.92488], [-73.45156, -49.79461], [-73.09655, -49.14342], [-72.56894, -48.81116], [-72.54042, -48.52392], [-72.27662, -48.28727], [-72.50478, -47.80586], [-71.94152, -47.13595], [-71.68577, -46.55385], [-71.75614, -45.61611], [-71.35687, -45.22075], [-72.06985, -44.81756], [-71.26418, -44.75684], [-71.16436, -44.46244], [-71.81318, -44.38097], [-71.64206, -43.64774], [-72.14828, -42.85321], [-72.15541, -42.15941], [-71.74901, -42.11711], [-71.92726, -40.72714], [-71.37826, -38.91474], [-70.89532, -38.6923], [-71.24279, -37.20264], [-70.95047, -36.4321], [-70.38008, -36.02375], [-70.49416, -35.24145], [-69.87386, -34.13344], [-69.88099, -33.34489], [-70.55832, -31.51559], [-70.14479, -30.36595], [-69.8596, -30.26131], [-69.99507, -29.28351], [-69.80969, -29.07185], [-69.66709, -28.44055], [-69.22504, -27.95042], [-68.77586, -27.16029], [-68.43363, -27.08414], [-68.27677, -26.90626], [-68.59048, -26.49861], [-68.56909, -26.28146], [-68.38372, -26.15353], [-68.57622, -25.32505], [-68.38372, -25.08636], [-68.56909, -24.69831], [-68.24825, -24.42596], [-67.33563, -24.04237], [-66.99632, -22.99839], [-67.18382, -22.81525], [-67.54284, -22.89771], [-67.85114, -22.87076], [-68.18816, -21.28614], [-68.40403, -20.94562], [-68.53957, -20.91542], [-68.55383, -20.7355], [-68.44023, -20.62701], [-68.7276, -20.46178], [-68.74273, -20.08817], [-68.57132, -20.03134], [-68.54611, -19.84651], [-68.66761, -19.72118], [-68.41218, -19.40499], [-68.61989, -19.27584], [-68.80602, -19.08355], [-68.87082, -19.06003], [-68.94987, -18.93302], [-69.07432, -18.28259], [-69.14807, -18.16893], [-69.07496, -18.03715], [-69.28671, -17.94844], [-69.34126, -17.72753], [-69.46623, -17.60518], [-69.46897, -17.4988], [-69.66483, -17.65083], [-69.79087, -17.65563], [-69.82868, -17.72048], [-69.75305, -17.94605], [-69.81607, -18.12582], [-69.96732, -18.25992], [-70.16394, -18.31737], [-70.31267, -18.31258], [-70.378, -18.3495], [-70.59118, -18.35072], [-113.52687, -26.52828], [-68.11646, -58.14883], [-66.07313, -55.19618], [-67.11046, -54.94199], [-67.46182, -54.92205], [-68.01394, -54.8753], [-68.60733, -54.9125], [-68.60702, -52.65781]]]] } }, @@ -22830,7 +23240,7 @@ { type: "Feature", properties: { iso1A2: "HU", iso1A3: "HUN", iso1N3: "348", wikidata: "Q28", nameEn: "Hungary", groups: ["EU", "151", "150", "UN"], callingCodes: ["36"] }, geometry: { type: "MultiPolygon", coordinates: [[[[21.72525, 48.34628], [21.67134, 48.3989], [21.6068, 48.50365], [21.44063, 48.58456], [21.11516, 48.49546], [20.83248, 48.5824], [20.5215, 48.53336], [20.29943, 48.26104], [20.24312, 48.2784], [19.92452, 48.1283], [19.63338, 48.25006], [19.52489, 48.19791], [19.47957, 48.09437], [19.28182, 48.08336], [19.23924, 48.0595], [19.01952, 48.07052], [18.82176, 48.04206], [18.76134, 47.97499], [18.76821, 47.87469], [18.8506, 47.82308], [18.74074, 47.8157], [18.66521, 47.76772], [18.56496, 47.76588], [18.29305, 47.73541], [18.02938, 47.75665], [17.71215, 47.7548], [17.23699, 48.02094], [17.16001, 48.00636], [17.09786, 47.97336], [17.11022, 47.92461], [17.08275, 47.87719], [17.00997, 47.86245], [17.07039, 47.81129], [17.05048, 47.79377], [17.08893, 47.70928], [16.87538, 47.68895], [16.86509, 47.72268], [16.82938, 47.68432], [16.7511, 47.67878], [16.72089, 47.73469], [16.65679, 47.74197], [16.61183, 47.76171], [16.54779, 47.75074], [16.53514, 47.73837], [16.55129, 47.72268], [16.4222, 47.66537], [16.58699, 47.61772], [16.64193, 47.63114], [16.71059, 47.52692], [16.64821, 47.50155], [16.6718, 47.46139], [16.57152, 47.40868], [16.52414, 47.41007], [16.49908, 47.39416], [16.45104, 47.41181], [16.47782, 47.25918], [16.44142, 47.25079], [16.43663, 47.21127], [16.41739, 47.20649], [16.42801, 47.18422], [16.4523, 47.18812], [16.46442, 47.16845], [16.44932, 47.14418], [16.52863, 47.13974], [16.46134, 47.09395], [16.52176, 47.05747], [16.43936, 47.03548], [16.51369, 47.00084], [16.28202, 47.00159], [16.27594, 46.9643], [16.22403, 46.939], [16.19904, 46.94134], [16.10983, 46.867], [16.14365, 46.8547], [16.15711, 46.85434], [16.21892, 46.86961], [16.2365, 46.87775], [16.2941, 46.87137], [16.34547, 46.83836], [16.3408, 46.80641], [16.31303, 46.79838], [16.30966, 46.7787], [16.37816, 46.69975], [16.42641, 46.69228], [16.41863, 46.66238], [16.38594, 46.6549], [16.39217, 46.63673], [16.50139, 46.56684], [16.52885, 46.53303], [16.52604, 46.5051], [16.59527, 46.47524], [16.6639, 46.45203], [16.7154, 46.39523], [16.8541, 46.36255], [16.8903, 46.28122], [17.14592, 46.16697], [17.35672, 45.95209], [17.56821, 45.93728], [17.66545, 45.84207], [17.87377, 45.78522], [17.99805, 45.79671], [18.08869, 45.76511], [18.12439, 45.78905], [18.44368, 45.73972], [18.57483, 45.80772], [18.6792, 45.92057], [18.80211, 45.87995], [18.81394, 45.91329], [18.99712, 45.93537], [19.01284, 45.96529], [19.0791, 45.96458], [19.10388, 46.04015], [19.14543, 45.9998], [19.28826, 45.99694], [19.52473, 46.1171], [19.56113, 46.16824], [19.66007, 46.19005], [19.81491, 46.1313], [19.93508, 46.17553], [20.01816, 46.17696], [20.03533, 46.14509], [20.09713, 46.17315], [20.26068, 46.12332], [20.28324, 46.1438], [20.35573, 46.16629], [20.45377, 46.14405], [20.49718, 46.18721], [20.63863, 46.12728], [20.76085, 46.21002], [20.74574, 46.25467], [20.86797, 46.28884], [21.06572, 46.24897], [21.16872, 46.30118], [21.28061, 46.44941], [21.26929, 46.4993], [21.33214, 46.63035], [21.43926, 46.65109], [21.5151, 46.72147], [21.48935, 46.7577], [21.52028, 46.84118], [21.59307, 46.86935], [21.59581, 46.91628], [21.68645, 46.99595], [21.648, 47.03902], [21.78395, 47.11104], [21.94463, 47.38046], [22.01055, 47.37767], [22.03389, 47.42508], [22.00917, 47.50492], [22.31816, 47.76126], [22.41979, 47.7391], [22.46559, 47.76583], [22.67247, 47.7871], [22.76617, 47.8417], [22.77991, 47.87211], [22.89849, 47.95851], [22.84276, 47.98602], [22.87847, 48.04665], [22.81804, 48.11363], [22.73427, 48.12005], [22.66835, 48.09162], [22.58733, 48.10813], [22.59007, 48.15121], [22.49806, 48.25189], [22.38133, 48.23726], [22.2083, 48.42534], [22.14689, 48.4005], [21.83339, 48.36242], [21.8279, 48.33321], [21.72525, 48.34628]]]] } }, { type: "Feature", properties: { iso1A2: "IC", wikidata: "Q5813", nameEn: "Canary Islands", country: "ES", groups: ["Q3320166", "Q105472", "EU", "039", "150", "UN"], isoStatus: "excRes", callingCodes: ["34"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-12.00985, 30.24121], [-25.3475, 27.87574], [-14.43883, 27.02969], [-12.00985, 30.24121]]]] } }, { type: "Feature", properties: { iso1A2: "ID", iso1A3: "IDN", iso1N3: "360", wikidata: "Q252", nameEn: "Indonesia", aliases: ["RI"] }, geometry: null }, - { type: "Feature", properties: { iso1A2: "IE", iso1A3: "IRL", iso1N3: "372", wikidata: "Q27", nameEn: "Republic of Ireland", groups: ["EU", "Q22890", "154", "150", "UN"], driveSide: "left", callingCodes: ["353"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-6.26218, 54.09785], [-6.29003, 54.11278], [-6.32694, 54.09337], [-6.36279, 54.11248], [-6.36605, 54.07234], [-6.47849, 54.06947], [-6.62842, 54.03503], [-6.66264, 54.0666], [-6.6382, 54.17071], [-6.70175, 54.20218], [-6.74575, 54.18788], [-6.81583, 54.22791], [-6.85179, 54.29176], [-6.87775, 54.34682], [-7.02034, 54.4212], [-7.19145, 54.31296], [-7.14908, 54.22732], [-7.25012, 54.20063], [-7.26316, 54.13863], [-7.29493, 54.12013], [-7.29687, 54.1354], [-7.28017, 54.16714], [-7.29157, 54.17191], [-7.34005, 54.14698], [-7.30553, 54.11869], [-7.32834, 54.11475], [-7.44567, 54.1539], [-7.4799, 54.12239], [-7.55812, 54.12239], [-7.69501, 54.20731], [-7.81397, 54.20159], [-7.8596, 54.21779], [-7.87101, 54.29299], [-8.04555, 54.36292], [-8.179, 54.46763], [-8.04538, 54.48941], [-7.99812, 54.54427], [-7.8596, 54.53671], [-7.70315, 54.62077], [-7.93293, 54.66603], [-7.83352, 54.73854], [-7.75041, 54.7103], [-7.64449, 54.75265], [-7.54671, 54.74606], [-7.54508, 54.79401], [-7.47626, 54.83084], [-7.4473, 54.87003], [-7.44404, 54.9403], [-7.40004, 54.94498], [-7.4033, 55.00391], [-7.34464, 55.04688], [-7.2471, 55.06933], [-6.34755, 55.49206], [-7.75229, 55.93854], [-22.01468, 48.19557], [-6.03913, 51.13217], [-5.37267, 53.63269], [-6.26218, 54.09785]]]] } }, + { type: "Feature", geometry: { type: "MultiPolygon", coordinates: [[[[-6.26218, 54.09785], [-6.29003, 54.11278], [-6.32694, 54.09337], [-6.36279, 54.11248], [-6.36605, 54.07234], [-6.47849, 54.06947], [-6.62842, 54.03503], [-6.66264, 54.0666], [-6.6382, 54.17071], [-6.70175, 54.20218], [-6.74575, 54.18788], [-6.81583, 54.22791], [-6.85179, 54.29176], [-6.87775, 54.34682], [-7.02034, 54.4212], [-7.19145, 54.31296], [-7.14908, 54.22732], [-7.25012, 54.20063], [-7.26316, 54.13863], [-7.29493, 54.12013], [-7.29687, 54.1354], [-7.28017, 54.16714], [-7.29157, 54.17191], [-7.34005, 54.14698], [-7.30553, 54.11869], [-7.32834, 54.11475], [-7.44567, 54.1539], [-7.4799, 54.12239], [-7.55812, 54.12239], [-7.69501, 54.20731], [-7.81397, 54.20159], [-7.8596, 54.21779], [-7.87101, 54.29299], [-8.04555, 54.36292], [-8.179, 54.46763], [-8.04538, 54.48941], [-7.99812, 54.54427], [-7.8596, 54.53671], [-7.70315, 54.62077], [-7.93293, 54.66603], [-7.83352, 54.73854], [-7.75041, 54.7103], [-7.64449, 54.75265], [-7.54671, 54.74606], [-7.54508, 54.79401], [-7.47626, 54.83084], [-7.4473, 54.87003], [-7.44404, 54.9403], [-7.40004, 54.94498], [-7.4033, 55.00391], [-7.34464, 55.04688], [-7.2471, 55.06933], [-6.34755, 55.49206], [-7.75229, 55.93854], [-11.75, 54], [-11, 51], [-6.03913, 51.13217], [-5.37267, 53.63269], [-6.26218, 54.09785]]]] }, properties: { iso1A2: "IE", iso1A3: "IRL", iso1N3: "372", wikidata: "Q27", nameEn: "Republic of Ireland", groups: ["EU", "Q22890", "154", "150", "UN"], driveSide: "left", callingCodes: ["353"] } }, { type: "Feature", properties: { iso1A2: "IL", iso1A3: "ISR", iso1N3: "376", wikidata: "Q801", nameEn: "Israel", groups: ["145", "142", "UN"], callingCodes: ["972"] }, geometry: { type: "MultiPolygon", coordinates: [[[[34.052, 31.46619], [34.29262, 31.70393], [34.48681, 31.59711], [34.56797, 31.54197], [34.48892, 31.48365], [34.40077, 31.40926], [34.36505, 31.36404], [34.37381, 31.30598], [34.36523, 31.28963], [34.29417, 31.24194], [34.26742, 31.21998], [34.92298, 29.45305], [34.97718, 29.54294], [34.98207, 29.58147], [35.02147, 29.66343], [35.14108, 30.07374], [35.19183, 30.34636], [35.16218, 30.43535], [35.19595, 30.50297], [35.21379, 30.60401], [35.29311, 30.71365], [35.33456, 30.81224], [35.33984, 30.8802], [35.41371, 30.95565], [35.43658, 31.12444], [35.40316, 31.25535], [35.47672, 31.49578], [35.39675, 31.49572], [35.22921, 31.37445], [35.13033, 31.3551], [35.02459, 31.35979], [34.92571, 31.34337], [34.88932, 31.37093], [34.87833, 31.39321], [34.89756, 31.43891], [34.93258, 31.47816], [34.94356, 31.50743], [34.9415, 31.55601], [34.95249, 31.59813], [35.00879, 31.65426], [35.08226, 31.69107], [35.10782, 31.71594], [35.11895, 31.71454], [35.12933, 31.7325], [35.13931, 31.73012], [35.15119, 31.73634], [35.15474, 31.73352], [35.16478, 31.73242], [35.18023, 31.72067], [35.20538, 31.72388], [35.21937, 31.71578], [35.22392, 31.71899], [35.23972, 31.70896], [35.24315, 31.71244], [35.2438, 31.7201], [35.24981, 31.72543], [35.25182, 31.73945], [35.26319, 31.74846], [35.25225, 31.7678], [35.26058, 31.79064], [35.25573, 31.81362], [35.26404, 31.82567], [35.251, 31.83085], [35.25753, 31.8387], [35.24816, 31.8458], [35.2304, 31.84222], [35.2249, 31.85433], [35.22817, 31.8638], [35.22567, 31.86745], [35.22294, 31.87889], [35.22014, 31.88264], [35.2136, 31.88241], [35.21276, 31.88153], [35.21016, 31.88237], [35.20945, 31.8815], [35.20791, 31.8821], [35.20673, 31.88151], [35.20381, 31.86716], [35.21128, 31.863], [35.216, 31.83894], [35.21469, 31.81835], [35.19461, 31.82687], [35.18169, 31.82542], [35.18603, 31.80901], [35.14174, 31.81325], [35.07677, 31.85627], [35.05617, 31.85685], [35.01978, 31.82944], [34.9724, 31.83352], [34.99712, 31.85569], [35.03489, 31.85919], [35.03978, 31.89276], [35.03489, 31.92448], [35.00124, 31.93264], [34.98682, 31.96935], [35.00261, 32.027], [34.9863, 32.09551], [34.99437, 32.10962], [34.98507, 32.12606], [34.99039, 32.14626], [34.96009, 32.17503], [34.95703, 32.19522], [34.98885, 32.20758], [35.01841, 32.23981], [35.02939, 32.2671], [35.01119, 32.28684], [35.01772, 32.33863], [35.04243, 32.35008], [35.05142, 32.3667], [35.0421, 32.38242], [35.05311, 32.4024], [35.05423, 32.41754], [35.07059, 32.4585], [35.08564, 32.46948], [35.09236, 32.47614], [35.10024, 32.47856], [35.10882, 32.4757], [35.15937, 32.50466], [35.2244, 32.55289], [35.25049, 32.52453], [35.29306, 32.50947], [35.30685, 32.51024], [35.35212, 32.52047], [35.40224, 32.50136], [35.42034, 32.46009], [35.41598, 32.45593], [35.41048, 32.43706], [35.42078, 32.41562], [35.55807, 32.38674], [35.55494, 32.42687], [35.57485, 32.48669], [35.56614, 32.64393], [35.59813, 32.65159], [35.61669, 32.67999], [35.66527, 32.681], [35.68467, 32.70715], [35.75983, 32.74803], [35.78745, 32.77938], [35.83758, 32.82817], [35.84021, 32.8725], [35.87012, 32.91976], [35.89298, 32.9456], [35.87188, 32.98028], [35.84802, 33.1031], [35.81911, 33.11077], [35.81911, 33.1336], [35.84285, 33.16673], [35.83846, 33.19397], [35.81647, 33.2028], [35.81295, 33.24841], [35.77513, 33.27342], [35.813, 33.3172], [35.77477, 33.33609], [35.62019, 33.27278], [35.62283, 33.24226], [35.58502, 33.26653], [35.58326, 33.28381], [35.56523, 33.28969], [35.55555, 33.25844], [35.54544, 33.25513], [35.54808, 33.236], [35.5362, 33.23196], [35.54228, 33.19865], [35.52573, 33.11921], [35.50335, 33.114], [35.50272, 33.09056], [35.448, 33.09264], [35.43059, 33.06659], [35.35223, 33.05617], [35.31429, 33.10515], [35.1924, 33.08743], [35.10645, 33.09318], [34.78515, 33.20368], [33.62659, 31.82938], [34.052, 31.46619]]]] } }, { type: "Feature", properties: { iso1A2: "IM", iso1A3: "IMN", iso1N3: "833", wikidata: "Q9676", nameEn: "Isle of Man", country: "GB", groups: ["Q185086", "154", "150", "UN"], driveSide: "left", roadSpeedUnit: "mph", roadHeightUnit: "ft", callingCodes: ["44 01624", "44 07624", "44 07524", "44 07924"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-3.98763, 54.07351], [-4.1819, 54.57861], [-5.6384, 53.81157], [-3.98763, 54.07351]]]] } }, { type: "Feature", properties: { iso1A2: "IN", iso1A3: "IND", iso1N3: "356", wikidata: "Q668", nameEn: "India" }, geometry: null }, @@ -22981,8 +23391,7 @@ { type: "Feature", properties: { iso1A2: "ZA", iso1A3: "ZAF", iso1N3: "710", wikidata: "Q258", nameEn: "South Africa", groups: ["018", "202", "002", "UN"], driveSide: "left", callingCodes: ["27"] }, geometry: { type: "MultiPolygon", coordinates: [[[[31.30611, -22.422], [31.16344, -22.32599], [31.08932, -22.34884], [30.86696, -22.28907], [30.6294, -22.32599], [30.48686, -22.31368], [30.38614, -22.34533], [30.28351, -22.35587], [30.2265, -22.2961], [30.13147, -22.30841], [29.92242, -22.19408], [29.76848, -22.14128], [29.64609, -22.12917], [29.37703, -22.19581], [29.21955, -22.17771], [29.18974, -22.18599], [29.15268, -22.21399], [29.10881, -22.21202], [29.0151, -22.22907], [28.91889, -22.44299], [28.63287, -22.55887], [28.34874, -22.5694], [28.04562, -22.8394], [28.04752, -22.90243], [27.93729, -22.96194], [27.93539, -23.04941], [27.74154, -23.2137], [27.6066, -23.21894], [27.52393, -23.37952], [27.33768, -23.40917], [26.99749, -23.65486], [26.84165, -24.24885], [26.51667, -24.47219], [26.46346, -24.60358], [26.39409, -24.63468], [25.8515, -24.75727], [25.84295, -24.78661], [25.88571, -24.87802], [25.72702, -25.25503], [25.69661, -25.29284], [25.6643, -25.4491], [25.58543, -25.6343], [25.33076, -25.76616], [25.12266, -25.75931], [25.01718, -25.72507], [24.8946, -25.80723], [24.67319, -25.81749], [24.44703, -25.73021], [24.36531, -25.773], [24.18287, -25.62916], [23.9244, -25.64286], [23.47588, -25.29971], [23.03497, -25.29971], [22.86012, -25.50572], [22.70808, -25.99186], [22.56365, -26.19668], [22.41921, -26.23078], [22.21206, -26.3773], [22.06192, -26.61882], [21.90703, -26.66808], [21.83291, -26.65959], [21.77114, -26.69015], [21.7854, -26.79199], [21.69322, -26.86152], [21.37869, -26.82083], [21.13353, -26.86661], [20.87031, -26.80047], [20.68596, -26.9039], [20.63275, -26.78181], [20.61754, -26.4692], [20.86081, -26.14892], [20.64795, -25.47827], [20.29826, -24.94869], [20.03678, -24.81004], [20.02809, -24.78725], [19.99817, -24.76768], [19.99882, -28.42622], [18.99885, -28.89165], [17.4579, -28.68718], [17.15405, -28.08573], [16.90446, -28.057], [16.59922, -28.53246], [16.46592, -28.57126], [16.45332, -28.63117], [12.51595, -32.27486], [38.88176, -48.03306], [34.51034, -26.91792], [32.35222, -26.86027], [32.29584, -26.852], [32.22302, -26.84136], [32.19409, -26.84032], [32.13315, -26.84345], [32.09664, -26.80721], [32.00893, -26.8096], [31.97463, -27.11057], [31.97592, -27.31675], [31.49834, -27.31549], [31.15027, -27.20151], [30.96088, -27.0245], [30.97757, -26.92706], [30.88826, -26.79622], [30.81101, -26.84722], [30.78927, -26.48271], [30.95819, -26.26303], [31.13073, -25.91558], [31.31237, -25.7431], [31.4175, -25.71886], [31.86881, -25.99973], [31.974, -25.95387], [31.92649, -25.84216], [32.00631, -25.65044], [31.97875, -25.46356], [32.01676, -25.38117], [32.03196, -25.10785], [31.9835, -24.29983], [31.90368, -24.18892], [31.87707, -23.95293], [31.77445, -23.90082], [31.70223, -23.72695], [31.67942, -23.60858], [31.56539, -23.47268], [31.55779, -23.176], [31.30611, -22.422]], [[29.33204, -29.45598], [29.28545, -29.58456], [29.12553, -29.76266], [29.16548, -29.91706], [28.9338, -30.05072], [28.80222, -30.10579], [28.68627, -30.12885], [28.399, -30.1592], [28.2319, -30.28476], [28.12073, -30.68072], [27.74814, -30.60635], [27.69467, -30.55862], [27.67819, -30.53437], [27.6521, -30.51707], [27.62137, -30.50509], [27.56781, -30.44562], [27.56901, -30.42504], [27.45452, -30.32239], [27.38108, -30.33456], [27.36649, -30.27246], [27.37293, -30.19401], [27.40778, -30.14577], [27.32555, -30.14785], [27.29603, -30.05473], [27.22719, -30.00718], [27.09489, -29.72796], [27.01016, -29.65439], [27.33464, -29.48161], [27.4358, -29.33465], [27.47254, -29.31968], [27.45125, -29.29708], [27.48679, -29.29349], [27.54258, -29.25575], [27.5158, -29.2261], [27.55974, -29.18954], [27.75458, -28.89839], [27.8907, -28.91612], [27.88933, -28.88156], [27.9392, -28.84864], [27.98675, -28.8787], [28.02503, -28.85991], [28.1317, -28.7293], [28.2348, -28.69471], [28.30518, -28.69531], [28.40612, -28.6215], [28.65091, -28.57025], [28.68043, -28.58744], [29.40524, -29.21246], [29.44883, -29.3772], [29.33204, -29.45598]]]] } }, { type: "Feature", properties: { iso1A2: "ZM", iso1A3: "ZMB", iso1N3: "894", wikidata: "Q953", nameEn: "Zambia", groups: ["014", "202", "002", "UN"], driveSide: "left", callingCodes: ["260"] }, geometry: { type: "MultiPolygon", coordinates: [[[[32.95389, -9.40138], [32.76233, -9.31963], [32.75611, -9.28583], [32.53661, -9.24281], [32.49147, -9.14754], [32.43543, -9.11988], [32.25486, -9.13371], [32.16146, -9.05993], [32.08206, -9.04609], [31.98866, -9.07069], [31.94196, -9.02303], [31.94663, -8.93846], [31.81587, -8.88618], [31.71158, -8.91386], [31.57147, -8.81388], [31.57147, -8.70619], [31.37533, -8.60769], [31.00796, -8.58615], [30.79243, -8.27382], [28.88917, -8.4831], [28.9711, -8.66935], [28.38526, -9.23393], [28.36562, -9.30091], [28.52636, -9.35379], [28.51627, -9.44726], [28.56208, -9.49122], [28.68532, -9.78], [28.62795, -9.92942], [28.65032, -10.65133], [28.37241, -11.57848], [28.48357, -11.87532], [29.18592, -12.37921], [29.4992, -12.43843], [29.48404, -12.23604], [29.8139, -12.14898], [29.81551, -13.44683], [29.65078, -13.41844], [29.60531, -13.21685], [29.01918, -13.41353], [28.33199, -12.41375], [27.59932, -12.22123], [27.21025, -11.76157], [27.22541, -11.60323], [27.04351, -11.61312], [26.88687, -12.01868], [26.01777, -11.91488], [25.33058, -11.65767], [25.34069, -11.19707], [24.42612, -11.44975], [24.34528, -11.06816], [24.00027, -10.89356], [24.02603, -11.15368], [23.98804, -12.13149], [24.06672, -12.29058], [23.90937, -12.844], [24.03339, -12.99091], [21.97988, -13.00148], [22.00323, -16.18028], [22.17217, -16.50269], [23.20038, -17.47563], [23.47474, -17.62877], [24.23619, -17.47489], [24.32811, -17.49082], [24.38712, -17.46818], [24.5621, -17.52963], [24.70864, -17.49501], [25.00198, -17.58221], [25.26433, -17.79571], [25.51646, -17.86232], [25.6827, -17.81987], [25.85738, -17.91403], [25.85892, -17.97726], [26.08925, -17.98168], [26.0908, -17.93021], [26.21601, -17.88608], [26.55918, -17.99638], [26.68403, -18.07411], [26.74314, -18.0199], [26.89926, -17.98756], [27.14196, -17.81398], [27.30736, -17.60487], [27.61377, -17.34378], [27.62795, -17.24365], [27.83141, -16.96274], [28.73725, -16.5528], [28.76199, -16.51575], [28.81454, -16.48611], [28.8501, -16.04537], [28.9243, -15.93987], [29.01298, -15.93805], [29.21955, -15.76589], [29.4437, -15.68702], [29.8317, -15.6126], [30.35574, -15.6513], [30.41902, -15.62269], [30.22098, -14.99447], [33.24249, -14.00019], [33.16749, -13.93992], [33.07568, -13.98447], [33.02977, -14.05022], [32.99042, -13.95689], [32.88985, -13.82956], [32.79015, -13.80755], [32.76962, -13.77224], [32.84528, -13.71576], [32.7828, -13.64805], [32.68654, -13.64268], [32.66468, -13.60019], [32.68436, -13.55769], [32.73683, -13.57682], [32.84176, -13.52794], [32.86113, -13.47292], [33.0078, -13.19492], [32.98289, -13.12671], [33.02181, -12.88707], [32.96733, -12.88251], [32.94397, -12.76868], [33.05917, -12.59554], [33.18837, -12.61377], [33.28177, -12.54692], [33.37517, -12.54085], [33.54485, -12.35996], [33.47636, -12.32498], [33.3705, -12.34931], [33.25998, -12.14242], [33.33937, -11.91252], [33.32692, -11.59248], [33.24252, -11.59302], [33.23663, -11.40637], [33.29267, -11.43536], [33.29267, -11.3789], [33.39697, -11.15296], [33.25998, -10.88862], [33.28022, -10.84428], [33.47636, -10.78465], [33.70675, -10.56896], [33.54797, -10.36077], [33.53863, -10.20148], [33.31297, -10.05133], [33.37902, -9.9104], [33.36581, -9.81063], [33.31517, -9.82364], [33.2095, -9.61099], [33.12144, -9.58929], [33.10163, -9.66525], [33.05485, -9.61316], [33.00256, -9.63053], [33.00476, -9.5133], [32.95389, -9.40138]]]] } }, { type: "Feature", properties: { iso1A2: "ZW", iso1A3: "ZWE", iso1N3: "716", wikidata: "Q954", nameEn: "Zimbabwe", groups: ["014", "202", "002", "UN"], driveSide: "left", callingCodes: ["263"] }, geometry: { type: "MultiPolygon", coordinates: [[[[30.41902, -15.62269], [30.35574, -15.6513], [29.8317, -15.6126], [29.4437, -15.68702], [29.21955, -15.76589], [29.01298, -15.93805], [28.9243, -15.93987], [28.8501, -16.04537], [28.81454, -16.48611], [28.76199, -16.51575], [28.73725, -16.5528], [27.83141, -16.96274], [27.62795, -17.24365], [27.61377, -17.34378], [27.30736, -17.60487], [27.14196, -17.81398], [26.89926, -17.98756], [26.74314, -18.0199], [26.68403, -18.07411], [26.55918, -17.99638], [26.21601, -17.88608], [26.0908, -17.93021], [26.08925, -17.98168], [25.85892, -17.97726], [25.85738, -17.91403], [25.6827, -17.81987], [25.51646, -17.86232], [25.26433, -17.79571], [25.23909, -17.90832], [25.31799, -18.07091], [25.39972, -18.12691], [25.53465, -18.39041], [25.68859, -18.56165], [25.79217, -18.6355], [25.82353, -18.82808], [25.94326, -18.90362], [25.99837, -19.02943], [25.96226, -19.08152], [26.17227, -19.53709], [26.72246, -19.92707], [27.21278, -20.08244], [27.29831, -20.28935], [27.28865, -20.49873], [27.69361, -20.48531], [27.72972, -20.51735], [27.69171, -21.08409], [27.91407, -21.31621], [28.01669, -21.57624], [28.29416, -21.59037], [28.49942, -21.66634], [28.58114, -21.63455], [29.07763, -21.81877], [29.04023, -21.85864], [29.02191, -21.90647], [29.02191, -21.95665], [29.04108, -22.00563], [29.08495, -22.04867], [29.14501, -22.07275], [29.1974, -22.07472], [29.24648, -22.05967], [29.3533, -22.18363], [29.37703, -22.19581], [29.64609, -22.12917], [29.76848, -22.14128], [29.92242, -22.19408], [30.13147, -22.30841], [30.2265, -22.2961], [30.28351, -22.35587], [30.38614, -22.34533], [30.48686, -22.31368], [30.6294, -22.32599], [30.86696, -22.28907], [31.08932, -22.34884], [31.16344, -22.32599], [31.30611, -22.422], [31.38336, -22.36919], [32.41234, -21.31246], [32.48236, -21.32873], [32.37115, -21.133], [32.51644, -20.91929], [32.48122, -20.63319], [32.55167, -20.56312], [32.66174, -20.56106], [32.85987, -20.27841], [32.85987, -20.16686], [32.93032, -20.03868], [33.01178, -20.02007], [33.06461, -19.77787], [32.95013, -19.67219], [32.84666, -19.68462], [32.84446, -19.48343], [32.78282, -19.47513], [32.77966, -19.36098], [32.85107, -19.29238], [32.87088, -19.09279], [32.84006, -19.0262], [32.72118, -19.02204], [32.69917, -18.94293], [32.73439, -18.92628], [32.70137, -18.84712], [32.82465, -18.77419], [32.9017, -18.7992], [32.95013, -18.69079], [32.88629, -18.58023], [32.88629, -18.51344], [33.02278, -18.4696], [33.03159, -18.35054], [32.94133, -17.99705], [33.0492, -17.60298], [32.98536, -17.55891], [32.96554, -17.48964], [33.0426, -17.3468], [33.00517, -17.30477], [32.96554, -17.11971], [32.84113, -16.92259], [32.91051, -16.89446], [32.97655, -16.70689], [32.78943, -16.70267], [32.69917, -16.66893], [32.71017, -16.59932], [32.42838, -16.4727], [32.28529, -16.43892], [32.02772, -16.43892], [31.91324, -16.41569], [31.90223, -16.34388], [31.67988, -16.19595], [31.42451, -16.15154], [31.30563, -16.01193], [31.13171, -15.98019], [30.97761, -16.05848], [30.91597, -15.99924], [30.42568, -15.9962], [30.41902, -15.62269]]]] } } - ]; - var borders_default = { type, features }; + ] }; var borders = borders_default; var whichPolygonGetter = {}; var featuresByCode = {}; @@ -23117,7 +23526,9 @@ sharedGroups = sharedGroups.filter((groupID) => memberGroups.indexOf(groupID) !== -1); } }); - props.groups = props.groups.concat(sharedGroups.filter((groupID) => props.groups.indexOf(groupID) === -1)); + props.groups = props.groups.concat( + sharedGroups.filter((groupID) => props.groups.indexOf(groupID) === -1) + ); sharedGroups.forEach((groupID) => { const groupFeature = featuresByCode[groupID]; if (groupFeature.properties.members.indexOf(props.id) === -1) { @@ -23131,11 +23542,15 @@ if (!props.roadSpeedUnit) props.roadSpeedUnit = "km/h"; } else if (props.members) { - const vals = Array.from(new Set(props.members.map((id2) => { - const member = featuresByCode[id2]; - if (member.geometry) - return member.properties.roadSpeedUnit || "km/h"; - }).filter(Boolean))); + const vals = Array.from( + new Set( + props.members.map((id2) => { + const member = featuresByCode[id2]; + if (member.geometry) + return member.properties.roadSpeedUnit || "km/h"; + }).filter(Boolean) + ) + ); if (vals.length === 1) props.roadSpeedUnit = vals[0]; } @@ -23146,11 +23561,15 @@ if (!props.roadHeightUnit) props.roadHeightUnit = "m"; } else if (props.members) { - const vals = Array.from(new Set(props.members.map((id2) => { - const member = featuresByCode[id2]; - if (member.geometry) - return member.properties.roadHeightUnit || "m"; - }).filter(Boolean))); + const vals = Array.from( + new Set( + props.members.map((id2) => { + const member = featuresByCode[id2]; + if (member.geometry) + return member.properties.roadHeightUnit || "m"; + }).filter(Boolean) + ) + ); if (vals.length === 1) props.roadHeightUnit = vals[0]; } @@ -23161,11 +23580,15 @@ if (!props.driveSide) props.driveSide = "right"; } else if (props.members) { - const vals = Array.from(new Set(props.members.map((id2) => { - const member = featuresByCode[id2]; - if (member.geometry) - return member.properties.driveSide || "right"; - }).filter(Boolean))); + const vals = Array.from( + new Set( + props.members.map((id2) => { + const member = featuresByCode[id2]; + if (member.geometry) + return member.properties.driveSide || "right"; + }).filter(Boolean) + ) + ); if (vals.length === 1) props.driveSide = vals[0]; } @@ -23173,13 +23596,17 @@ function loadCallingCodes(feature22) { const props = feature22.properties; if (!feature22.geometry && props.members) { - props.callingCodes = Array.from(new Set(props.members.reduce((array2, id2) => { - const member = featuresByCode[id2]; - if (member.geometry && member.properties.callingCodes) { - return array2.concat(member.properties.callingCodes); - } - return array2; - }, []))); + props.callingCodes = Array.from( + new Set( + props.members.reduce((array2, id2) => { + const member = featuresByCode[id2]; + if (member.geometry && member.properties.callingCodes) { + return array2.concat(member.properties.callingCodes); + } + return array2; + }, []) + ) + ); } } function loadFlag(feature22) { @@ -23262,10 +23689,11 @@ } } } - const features2 = featuresContaining(loc); - const match = features2.find((feature22) => { + const features = featuresContaining(loc); + const match = features.find((feature22) => { let levelIndex = levels.indexOf(feature22.properties.level); - if (feature22.properties.level === targetLevel || levelIndex > targetLevelIndex && levelIndex <= maxLevelIndex) { + if (feature22.properties.level === targetLevel || // if no feature exists at the target level, return the first feature at the next level up + levelIndex > targetLevelIndex && levelIndex <= maxLevelIndex) { if (!withProp || feature22.properties[withProp]) { return feature22; } @@ -23288,8 +23716,8 @@ } return featuresByCode[stringID] || null; } - function smallestFeaturesForBbox(bbox) { - return whichPolygonGetter.bbox(bbox).map((props) => featuresByCode[props.id]); + function smallestFeaturesForBbox(bbox2) { + return whichPolygonGetter.bbox(bbox2).map((props) => featuresByCode[props.id]); } function smallestOrMatchingFeature(query) { if (typeof query === "object") { @@ -23341,29 +23769,29 @@ const feature22 = featureForID(id2); if (!feature22) return []; - let features2 = []; + let features = []; if (!strict) { - features2.push(feature22); + features.push(feature22); } const properties = feature22.properties; (properties.members || []).forEach((memberID) => { - features2.push(featuresByCode[memberID]); + features.push(featuresByCode[memberID]); }); - return features2; + return features; } function aggregateFeature(id2) { - const features2 = featuresIn(id2, false); - if (features2.length === 0) + const features = featuresIn(id2, false); + if (features.length === 0) return null; let aggregateCoordinates = []; - features2.forEach((feature22) => { + features.forEach((feature22) => { if (feature22.geometry && feature22.geometry.type === "MultiPolygon" && feature22.geometry.coordinates) { aggregateCoordinates = aggregateCoordinates.concat(feature22.geometry.coordinates); } }); return { type: "Feature", - properties: features2[0].properties, + properties: features[0].properties, geometry: { type: "MultiPolygon", coordinates: aggregateCoordinates @@ -23379,13 +23807,31 @@ return feature22 && feature22.properties.roadHeightUnit || null; } - // node_modules/@ideditor/location-conflation/index.mjs + // node_modules/@rapideditor/location-conflation/index.mjs var import_geojson_area = __toESM(require_geojson_area(), 1); var import_circle_to_polygon = __toESM(require_circle_to_polygon(), 1); var import_polygon_clipping = __toESM(require_polygon_clipping_umd(), 1); var import_geojson_precision = __toESM(require_geojson_precision(), 1); var import_json_stringify_pretty_compact = __toESM(require_json_stringify_pretty_compact(), 1); var location_conflation_default = class { + // constructor + // + // `fc` Optional FeatureCollection of known features + // + // Optionally pass a GeoJSON FeatureCollection of known features which we can refer to later. + // Each feature must have a filename-like `id`, for example: `something.geojson` + // + // { + // "type": "FeatureCollection" + // "features": [ + // { + // "type": "Feature", + // "id": "philly_metro.geojson", + // "properties": { … }, + // "geometry": { … } + // } + // ] + // } constructor(fc) { this._cache = {}; this._strict = true; @@ -23416,6 +23862,19 @@ world.properties.area = import_geojson_area.default.geometry(world.geometry) / 1e6; this._cache.Q2 = world; } + // validateLocation + // `location` The location to validate + // + // Pass a `location` value to validate + // + // Returns a result like: + // { + // type: 'point', 'geojson', or 'countrycoder' + // location: the queried location + // id: the stable identifier for the feature + // } + // or `null` if the location is invalid + // validateLocation(location) { if (Array.isArray(location) && (location.length === 2 || location.length === 3)) { const lon = location[0]; @@ -23443,6 +23902,20 @@ return null; } } + // resolveLocation + // `location` The location to resolve + // + // Pass a `location` value to resolve + // + // Returns a result like: + // { + // type: 'point', 'geojson', or 'countrycoder' + // location: the queried location + // id: a stable identifier for the feature + // feature: the resolved GeoJSON feature + // } + // or `null` if the location is invalid + // resolveLocation(location) { const valid = this.validateLocation(location); if (!valid) @@ -23463,6 +23936,7 @@ id: id2, properties: { id: id2, area: Number(area.toFixed(2)) }, geometry: (0, import_circle_to_polygon.default)([lon, lat], radius * 1e3, EDGES) + // km to m }, PRECISION); return Object.assign(valid, { feature: feature3 }); } else if (valid.type === "geojson") { @@ -23489,6 +23963,23 @@ return null; } } + // validateLocationSet + // `locationSet` the locationSet to validate + // + // Pass a locationSet Object to validate like: + // { + // include: [ Array of locations ], + // exclude: [ Array of locations ] + // } + // + // Returns a result like: + // { + // type: 'locationset' + // locationSet: the queried locationSet + // id: the stable identifier for the feature + // } + // or `null` if the locationSet is invalid + // validateLocationSet(locationSet) { locationSet = locationSet || {}; const validator = this.validateLocation.bind(this); @@ -23510,6 +24001,24 @@ } return { type: "locationset", locationSet, id: id2 }; } + // resolveLocationSet + // `locationSet` the locationSet to resolve + // + // Pass a locationSet Object to validate like: + // { + // include: [ Array of locations ], + // exclude: [ Array of locations ] + // } + // + // Returns a result like: + // { + // type: 'locationset' + // locationSet: the queried locationSet + // id: the stable identifier for the feature + // feature: the resolved GeoJSON feature + // } + // or `null` if the locationSet is invalid + // resolveLocationSet(locationSet) { locationSet = locationSet || {}; const valid = this.validateLocationSet(locationSet); @@ -23534,6 +24043,8 @@ this._cache[id2] = resultGeoJSON; return Object.assign(valid, { feature: resultGeoJSON }); } + // strict + // strict(val) { if (val === void 0) { return this._strict; @@ -23542,18 +24053,22 @@ return this; } } + // cache + // convenience method to access the internal cache cache() { return this._cache; } + // stringify + // convenience method to prettyStringify the given object stringify(obj, options2) { return (0, import_json_stringify_pretty_compact.default)(obj, options2); } }; - function _clip(features2, which) { - if (!Array.isArray(features2) || !features2.length) + function _clip(features, which) { + if (!Array.isArray(features) || !features.length) return null; const fn = { UNION: import_polygon_clipping.default.union, DIFFERENCE: import_polygon_clipping.default.difference }[which]; - const args = features2.map((feature3) => feature3.geometry.coordinates); + const args = features.map((feature3) => feature3.geometry.coordinates); const coords = fn.apply(null, args); return { type: "Feature", @@ -23581,1049 +24096,1387 @@ return aRank > bRank ? 1 : aRank < bRank ? -1 : a.id.localeCompare(b.id); } - // modules/core/locations.js + // modules/core/LocationManager.js var import_which_polygon2 = __toESM(require_which_polygon()); var import_geojson_area2 = __toESM(require_geojson_area()); - - // modules/util/aes.js - var import_aes_js = __toESM(require_aes_js()); - var DEFAULT_128 = [250, 157, 60, 79, 142, 134, 229, 129, 138, 126, 210, 129, 29, 71, 160, 208]; - function utilAesEncrypt(text2, key) { - key = key || DEFAULT_128; - const textBytes = import_aes_js.default.utils.utf8.toBytes(text2); - const aesCtr = new import_aes_js.default.ModeOfOperation.ctr(key); - const encryptedBytes = aesCtr.encrypt(textBytes); - const encryptedHex = import_aes_js.default.utils.hex.fromBytes(encryptedBytes); - return encryptedHex; - } - function utilAesDecrypt(encryptedHex, key) { - key = key || DEFAULT_128; - const encryptedBytes = import_aes_js.default.utils.hex.toBytes(encryptedHex); - const aesCtr = new import_aes_js.default.ModeOfOperation.ctr(key); - const decryptedBytes = aesCtr.decrypt(encryptedBytes); - const text2 = import_aes_js.default.utils.utf8.fromBytes(decryptedBytes); - return text2; - } - - // modules/util/clean_tags.js - function utilCleanTags(tags) { - var out = {}; - for (var k in tags) { - if (!k) - continue; - var v = tags[k]; - if (v !== void 0) { - out[k] = cleanValue(k, v); + var _loco = new location_conflation_default(); + var LocationManager = class { + /** + * @constructor + */ + constructor() { + this._wp = null; + this._resolved = /* @__PURE__ */ new Map(); + this._knownLocationSets = /* @__PURE__ */ new Map(); + this._locationIncludedIn = /* @__PURE__ */ new Map(); + this._locationExcludedIn = /* @__PURE__ */ new Map(); + const world = { locationSet: { include: ["Q2"] } }; + this._resolveLocationSet(world); + this._rebuildIndex(); + } + /** + * _validateLocationSet + * Pass an Object with a `locationSet` property. + * Validates the `locationSet` and sets a `locationSetID` property on the object. + * To avoid so much computation we only resolve the include and exclude regions, but not the locationSet itself. + * + * Use `_resolveLocationSet()` instead if you need to resolve geojson of locationSet, for example to render it. + * Note: You need to call `_rebuildIndex()` after you're all finished validating the locationSets. + * + * @param `obj` Object to check, it should have `locationSet` property + */ + _validateLocationSet(obj) { + if (obj.locationSetID) + return; + try { + let locationSet = obj.locationSet; + if (!locationSet) { + throw new Error("object missing locationSet property"); + } + if (!locationSet.include) { + locationSet.include = ["Q2"]; + } + const locationSetID = _loco.validateLocationSet(locationSet).id; + obj.locationSetID = locationSetID; + if (this._knownLocationSets.has(locationSetID)) + return; + let area = 0; + (locationSet.include || []).forEach((location) => { + const locationID = _loco.validateLocation(location).id; + let geojson = this._resolved.get(locationID); + if (!geojson) { + geojson = _loco.resolveLocation(location).feature; + this._resolved.set(locationID, geojson); + } + area += geojson.properties.area; + let s = this._locationIncludedIn.get(locationID); + if (!s) { + s = /* @__PURE__ */ new Set(); + this._locationIncludedIn.set(locationID, s); + } + s.add(locationSetID); + }); + (locationSet.exclude || []).forEach((location) => { + const locationID = _loco.validateLocation(location).id; + let geojson = this._resolved.get(locationID); + if (!geojson) { + geojson = _loco.resolveLocation(location).feature; + this._resolved.set(locationID, geojson); + } + area -= geojson.properties.area; + let s = this._locationExcludedIn.get(locationID); + if (!s) { + s = /* @__PURE__ */ new Set(); + this._locationExcludedIn.set(locationID, s); + } + s.add(locationSetID); + }); + this._knownLocationSets.set(locationSetID, area); + } catch (err) { + obj.locationSet = { include: ["Q2"] }; + obj.locationSetID = "+[Q2]"; } } - return out; - function cleanValue(k2, v2) { - function keepSpaces(k3) { - return /_hours|_times|:conditional$/.test(k3); + /** + * _resolveLocationSet + * Does everything that `_validateLocationSet()` does, but then "resolves" the locationSet into GeoJSON. + * This step is a bit more computationally expensive, so really only needed if you intend to render the shape. + * + * Note: You need to call `_rebuildIndex()` after you're all finished validating the locationSets. + * + * @param `obj` Object to check, it should have `locationSet` property + */ + _resolveLocationSet(obj) { + this._validateLocationSet(obj); + if (this._resolved.has(obj.locationSetID)) + return; + try { + const result = _loco.resolveLocationSet(obj.locationSet); + const locationSetID = result.id; + obj.locationSetID = locationSetID; + if (!result.feature.geometry.coordinates.length || !result.feature.properties.area) { + throw new Error(`locationSet ${locationSetID} resolves to an empty feature.`); + } + let geojson = JSON.parse(JSON.stringify(result.feature)); + geojson.id = locationSetID; + geojson.properties.id = locationSetID; + this._resolved.set(locationSetID, geojson); + } catch (err) { + obj.locationSet = { include: ["Q2"] }; + obj.locationSetID = "+[Q2]"; } - function skip(k3) { - return /^(description|note|fixme)$/.test(k3); + } + /** + * _rebuildIndex + * Rebuilds the whichPolygon index with whatever features have been resolved into GeoJSON. + */ + _rebuildIndex() { + this._wp = (0, import_which_polygon2.default)({ features: [...this._resolved.values()] }); + } + /** + * mergeCustomGeoJSON + * Accepts a FeatureCollection-like object containing custom locations + * Each feature must have a filename-like `id`, for example: `something.geojson` + * { + * "type": "FeatureCollection" + * "features": [ + * { + * "type": "Feature", + * "id": "philly_metro.geojson", + * "properties": { … }, + * "geometry": { … } + * } + * ] + * } + * + * @param `fc` FeatureCollection-like Object containing custom locations + */ + mergeCustomGeoJSON(fc) { + if (!fc || fc.type !== "FeatureCollection" || !Array.isArray(fc.features)) + return; + fc.features.forEach((feature3) => { + feature3.properties = feature3.properties || {}; + let props = feature3.properties; + let id2 = feature3.id || props.id; + if (!id2 || !/^\S+\.geojson$/i.test(id2)) + return; + id2 = id2.toLowerCase(); + feature3.id = id2; + props.id = id2; + if (!props.area) { + const area = import_geojson_area2.default.geometry(feature3.geometry) / 1e6; + props.area = Number(area.toFixed(2)); + } + _loco._cache[id2] = feature3; + }); + } + /** + * mergeLocationSets + * Accepts an Array of Objects containing `locationSet` properties: + * [ + * { id: 'preset1', locationSet: {…} }, + * { id: 'preset2', locationSet: {…} }, + * … + * ] + * After validating, the Objects will be decorated with a `locationSetID` property: + * [ + * { id: 'preset1', locationSet: {…}, locationSetID: '+[Q2]' }, + * { id: 'preset2', locationSet: {…}, locationSetID: '+[Q30]' }, + * … + * ] + * + * @param `objects` Objects to check - they should have `locationSet` property + * @return Promise resolved true (this function used to be slow/async, now it's faster and sync) + */ + mergeLocationSets(objects) { + if (!Array.isArray(objects)) + return Promise.reject("nothing to do"); + objects.forEach((obj) => this._validateLocationSet(obj)); + this._rebuildIndex(); + return Promise.resolve(objects); + } + /** + * locationSetID + * Returns a locationSetID for a given locationSet (fallback to `+[Q2]`, world) + * (The locationSet doesn't necessarily need to be resolved to compute its `id`) + * + * @param `locationSet` A locationSet Object, e.g. `{ include: ['us'] }` + * @return String locationSetID, e.g. `+[Q30]` + */ + locationSetID(locationSet) { + let locationSetID; + try { + locationSetID = _loco.validateLocationSet(locationSet).id; + } catch (err) { + locationSetID = "+[Q2]"; } - if (skip(k2)) - return v2; - var cleaned = v2.split(";").map(function(s) { - return s.trim(); - }).join(keepSpaces(k2) ? "; " : ";"); - if (k2.indexOf("website") !== -1 || k2.indexOf("email") !== -1 || cleaned.indexOf("http") === 0) { - cleaned = cleaned.replace(/[\u200B-\u200F\uFEFF]/g, ""); + return locationSetID; + } + /** + * feature + * Returns the resolved GeoJSON feature for a given locationSetID (fallback to 'world') + * A GeoJSON feature: + * { + * type: 'Feature', + * id: '+[Q30]', + * properties: { id: '+[Q30]', area: 21817019.17, … }, + * geometry: { … } + * } + * + * @param `locationSetID` String identifier, e.g. `+[Q30]` + * @return GeoJSON object (fallback to world) + */ + feature(locationSetID = "+[Q2]") { + const feature3 = this._resolved.get(locationSetID); + return feature3 || this._resolved.get("+[Q2]"); + } + /** + * locationSetsAt + * Find all the locationSets valid at the given location. + * Results include the area (in km²) to facilitate sorting. + * + * Object of locationSetIDs to areas (in km²) + * { + * "+[Q2]": 511207893.3958111, + * "+[Q30]": 21817019.17, + * "+[new_jersey.geojson]": 22390.77, + * … + * } + * + * @param `loc` `[lon,lat]` location to query, e.g. `[-74.4813, 40.7967]` + * @return Object of locationSetIDs valid at given location + */ + locationSetsAt(loc) { + let result = {}; + const hits = this._wp(loc, true) || []; + const thiz = this; + hits.forEach((prop) => { + if (prop.id[0] !== "+") + return; + const locationSetID = prop.id; + const area = thiz._knownLocationSets.get(locationSetID); + if (area) { + result[locationSetID] = area; + } + }); + hits.forEach((prop) => { + if (prop.id[0] === "+") + return; + const locationID = prop.id; + const included = thiz._locationIncludedIn.get(locationID); + (included || []).forEach((locationSetID) => { + const area = thiz._knownLocationSets.get(locationSetID); + if (area) { + result[locationSetID] = area; + } + }); + }); + hits.forEach((prop) => { + if (prop.id[0] === "+") + return; + const locationID = prop.id; + const excluded = thiz._locationExcludedIn.get(locationID); + (excluded || []).forEach((locationSetID) => { + delete result[locationSetID]; + }); + }); + return result; + } + // Direct access to the location-conflation resolver + loco() { + return _loco; + } + }; + var _sharedLocationManager = new LocationManager(); + + // node_modules/lodash-es/_freeGlobal.js + var freeGlobal = typeof global == "object" && global && global.Object === Object && global; + var freeGlobal_default = freeGlobal; + + // node_modules/lodash-es/_root.js + var freeSelf = typeof self == "object" && self && self.Object === Object && self; + var root2 = freeGlobal_default || freeSelf || Function("return this")(); + var root_default = root2; + + // node_modules/lodash-es/_Symbol.js + var Symbol2 = root_default.Symbol; + var Symbol_default = Symbol2; + + // node_modules/lodash-es/_getRawTag.js + var objectProto = Object.prototype; + var hasOwnProperty = objectProto.hasOwnProperty; + var nativeObjectToString = objectProto.toString; + var symToStringTag = Symbol_default ? Symbol_default.toStringTag : void 0; + function getRawTag(value) { + var isOwn = hasOwnProperty.call(value, symToStringTag), tag = value[symToStringTag]; + try { + value[symToStringTag] = void 0; + var unmasked = true; + } catch (e) { + } + var result = nativeObjectToString.call(value); + if (unmasked) { + if (isOwn) { + value[symToStringTag] = tag; + } else { + delete value[symToStringTag]; } - return cleaned; } + return result; } + var getRawTag_default = getRawTag; - // modules/util/detect.js - var _detected; - function utilDetect(refresh2) { - if (_detected && !refresh2) - return _detected; - _detected = {}; - const ua = navigator.userAgent; - let m = null; - m = ua.match(/(edge)\/?\s*(\.?\d+(\.\d+)*)/i); - if (m !== null) { - _detected.browser = m[1]; - _detected.version = m[2]; + // node_modules/lodash-es/_objectToString.js + var objectProto2 = Object.prototype; + var nativeObjectToString2 = objectProto2.toString; + function objectToString(value) { + return nativeObjectToString2.call(value); + } + var objectToString_default = objectToString; + + // node_modules/lodash-es/_baseGetTag.js + var nullTag = "[object Null]"; + var undefinedTag = "[object Undefined]"; + var symToStringTag2 = Symbol_default ? Symbol_default.toStringTag : void 0; + function baseGetTag(value) { + if (value == null) { + return value === void 0 ? undefinedTag : nullTag; } - if (!_detected.browser) { - m = ua.match(/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/i); - if (m !== null) { - _detected.browser = "msie"; - _detected.version = m[1]; - } + return symToStringTag2 && symToStringTag2 in Object(value) ? getRawTag_default(value) : objectToString_default(value); + } + var baseGetTag_default = baseGetTag; + + // node_modules/lodash-es/isObjectLike.js + function isObjectLike(value) { + return value != null && typeof value == "object"; + } + var isObjectLike_default = isObjectLike; + + // node_modules/lodash-es/isSymbol.js + var symbolTag = "[object Symbol]"; + function isSymbol(value) { + return typeof value == "symbol" || isObjectLike_default(value) && baseGetTag_default(value) == symbolTag; + } + var isSymbol_default = isSymbol; + + // node_modules/lodash-es/_arrayMap.js + function arrayMap(array2, iteratee) { + var index = -1, length = array2 == null ? 0 : array2.length, result = Array(length); + while (++index < length) { + result[index] = iteratee(array2[index], index, array2); } - if (!_detected.browser) { - m = ua.match(/(opr)\/?\s*(\.?\d+(\.\d+)*)/i); - if (m !== null) { - _detected.browser = "Opera"; - _detected.version = m[2]; - } + return result; + } + var arrayMap_default = arrayMap; + + // node_modules/lodash-es/isArray.js + var isArray = Array.isArray; + var isArray_default = isArray; + + // node_modules/lodash-es/_baseToString.js + var INFINITY = 1 / 0; + var symbolProto = Symbol_default ? Symbol_default.prototype : void 0; + var symbolToString = symbolProto ? symbolProto.toString : void 0; + function baseToString(value) { + if (typeof value == "string") { + return value; } - if (!_detected.browser) { - m = ua.match(/(opera|chrome|safari|firefox|msie)\/?\s*(\.?\d+(\.\d+)*)/i); - if (m !== null) { - _detected.browser = m[1]; - _detected.version = m[2]; - m = ua.match(/version\/([\.\d]+)/i); - if (m !== null) - _detected.version = m[1]; - } + if (isArray_default(value)) { + return arrayMap_default(value, baseToString) + ""; } - if (!_detected.browser) { - _detected.browser = navigator.appName; - _detected.version = navigator.appVersion; + if (isSymbol_default(value)) { + return symbolToString ? symbolToString.call(value) : ""; } - _detected.version = _detected.version.split(/\W/).slice(0, 2).join("."); - _detected.opera = _detected.browser.toLowerCase() === "opera" && parseFloat(_detected.version) < 15; - if (_detected.browser.toLowerCase() === "msie") { - _detected.ie = true; - _detected.browser = "Internet Explorer"; - _detected.support = false; - } else { - _detected.ie = false; - _detected.support = true; + var result = value + ""; + return result == "0" && 1 / value == -INFINITY ? "-0" : result; + } + var baseToString_default = baseToString; + + // node_modules/lodash-es/_trimmedEndIndex.js + var reWhitespace = /\s/; + function trimmedEndIndex(string) { + var index = string.length; + while (index-- && reWhitespace.test(string.charAt(index))) { } - _detected.filedrop = window.FileReader && "ondrop" in window; - if (/Win/.test(ua)) { - _detected.os = "win"; - _detected.platform = "Windows"; - } else if (/Mac/.test(ua)) { - _detected.os = "mac"; - _detected.platform = "Macintosh"; - } else if (/X11/.test(ua) || /Linux/.test(ua)) { - _detected.os = "linux"; - _detected.platform = "Linux"; - } else { - _detected.os = "win"; - _detected.platform = "Unknown"; + return index; + } + var trimmedEndIndex_default = trimmedEndIndex; + + // node_modules/lodash-es/_baseTrim.js + var reTrimStart = /^\s+/; + function baseTrim(string) { + return string ? string.slice(0, trimmedEndIndex_default(string) + 1).replace(reTrimStart, "") : string; + } + var baseTrim_default = baseTrim; + + // node_modules/lodash-es/isObject.js + function isObject(value) { + var type2 = typeof value; + return value != null && (type2 == "object" || type2 == "function"); + } + var isObject_default = isObject; + + // node_modules/lodash-es/toNumber.js + var NAN = 0 / 0; + var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; + var reIsBinary = /^0b[01]+$/i; + var reIsOctal = /^0o[0-7]+$/i; + var freeParseInt = parseInt; + function toNumber(value) { + if (typeof value == "number") { + return value; } - _detected.isMobileWebKit = (/\b(iPad|iPhone|iPod)\b/.test(ua) || navigator.platform === "MacIntel" && "maxTouchPoints" in navigator && navigator.maxTouchPoints > 1) && /WebKit/.test(ua) && !/Edge/.test(ua) && !window.MSStream; - _detected.browserLocales = Array.from(new Set( - [navigator.language].concat(navigator.languages || []).concat([ - navigator.userLanguage - ]).filter(Boolean) - )); - const loc = window.top.location; - let origin = loc.origin; - if (!origin) { - origin = loc.protocol + "//" + loc.hostname + (loc.port ? ":" + loc.port : ""); + if (isSymbol_default(value)) { + return NAN; } - _detected.host = origin + loc.pathname; - return _detected; + if (isObject_default(value)) { + var other = typeof value.valueOf == "function" ? value.valueOf() : value; + value = isObject_default(other) ? other + "" : other; + } + if (typeof value != "string") { + return value === 0 ? value : +value; + } + value = baseTrim_default(value); + var isBinary = reIsBinary.test(value); + return isBinary || reIsOctal.test(value) ? freeParseInt(value.slice(2), isBinary ? 2 : 8) : reIsBadHex.test(value) ? NAN : +value; } + var toNumber_default = toNumber; - // modules/util/get_set_value.js - function utilGetSetValue(selection2, value) { - function d3_selection_value(value2) { - function valueNull() { - delete this.value; - } - function valueConstant() { - if (this.value !== value2) { - this.value = value2; - } + // node_modules/lodash-es/isFunction.js + var asyncTag = "[object AsyncFunction]"; + var funcTag = "[object Function]"; + var genTag = "[object GeneratorFunction]"; + var proxyTag = "[object Proxy]"; + function isFunction(value) { + if (!isObject_default(value)) { + return false; + } + var tag = baseGetTag_default(value); + return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; + } + var isFunction_default = isFunction; + + // node_modules/lodash-es/_coreJsData.js + var coreJsData = root_default["__core-js_shared__"]; + var coreJsData_default = coreJsData; + + // node_modules/lodash-es/_isMasked.js + var maskSrcKey = function() { + var uid = /[^.]+$/.exec(coreJsData_default && coreJsData_default.keys && coreJsData_default.keys.IE_PROTO || ""); + return uid ? "Symbol(src)_1." + uid : ""; + }(); + function isMasked(func) { + return !!maskSrcKey && maskSrcKey in func; + } + var isMasked_default = isMasked; + + // node_modules/lodash-es/_toSource.js + var funcProto = Function.prototype; + var funcToString = funcProto.toString; + function toSource(func) { + if (func != null) { + try { + return funcToString.call(func); + } catch (e) { } - function valueFunction() { - var x = value2.apply(this, arguments); - if (x === null || x === void 0) { - delete this.value; - } else if (this.value !== x) { - this.value = x; - } + try { + return func + ""; + } catch (e) { } - return value2 === null || value2 === void 0 ? valueNull : typeof value2 === "function" ? valueFunction : valueConstant; } - if (arguments.length === 1) { - return selection2.property("value"); + return ""; + } + var toSource_default = toSource; + + // node_modules/lodash-es/_baseIsNative.js + var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; + var reIsHostCtor = /^\[object .+?Constructor\]$/; + var funcProto2 = Function.prototype; + var objectProto3 = Object.prototype; + var funcToString2 = funcProto2.toString; + var hasOwnProperty2 = objectProto3.hasOwnProperty; + var reIsNative = RegExp( + "^" + funcToString2.call(hasOwnProperty2).replace(reRegExpChar, "\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, "$1.*?") + "$" + ); + function baseIsNative(value) { + if (!isObject_default(value) || isMasked_default(value)) { + return false; } - return selection2.each(d3_selection_value(value)); + var pattern = isFunction_default(value) ? reIsNative : reIsHostCtor; + return pattern.test(toSource_default(value)); } + var baseIsNative_default = baseIsNative; - // modules/util/keybinding.js - function utilKeybinding(namespace) { - var _keybindings = {}; - function testBindings(d3_event, isCapturing) { - var didMatch = false; - var bindings = Object.keys(_keybindings).map(function(id2) { - return _keybindings[id2]; - }); - var i2, binding; - for (i2 = 0; i2 < bindings.length; i2++) { - binding = bindings[i2]; - if (!binding.event.modifiers.shiftKey) - continue; - if (!!binding.capture !== isCapturing) - continue; - if (matches(d3_event, binding, true)) { - binding.callback(d3_event); - didMatch = true; - break; - } - } - if (didMatch) - return; - for (i2 = 0; i2 < bindings.length; i2++) { - binding = bindings[i2]; - if (binding.event.modifiers.shiftKey) - continue; - if (!!binding.capture !== isCapturing) - continue; - if (matches(d3_event, binding, false)) { - binding.callback(d3_event); - break; - } + // node_modules/lodash-es/_getValue.js + function getValue(object, key) { + return object == null ? void 0 : object[key]; + } + var getValue_default = getValue; + + // node_modules/lodash-es/_getNative.js + function getNative(object, key) { + var value = getValue_default(object, key); + return baseIsNative_default(value) ? value : void 0; + } + var getNative_default = getNative; + + // node_modules/lodash-es/_WeakMap.js + var WeakMap = getNative_default(root_default, "WeakMap"); + var WeakMap_default = WeakMap; + + // node_modules/lodash-es/_isIndex.js + var MAX_SAFE_INTEGER = 9007199254740991; + var reIsUint = /^(?:0|[1-9]\d*)$/; + function isIndex(value, length) { + var type2 = typeof value; + length = length == null ? MAX_SAFE_INTEGER : length; + return !!length && (type2 == "number" || type2 != "symbol" && reIsUint.test(value)) && (value > -1 && value % 1 == 0 && value < length); + } + var isIndex_default = isIndex; + + // node_modules/lodash-es/eq.js + function eq(value, other) { + return value === other || value !== value && other !== other; + } + var eq_default = eq; + + // node_modules/lodash-es/isLength.js + var MAX_SAFE_INTEGER2 = 9007199254740991; + function isLength(value) { + return typeof value == "number" && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER2; + } + var isLength_default = isLength; + + // node_modules/lodash-es/isArrayLike.js + function isArrayLike(value) { + return value != null && isLength_default(value.length) && !isFunction_default(value); + } + var isArrayLike_default = isArrayLike; + + // node_modules/lodash-es/_isPrototype.js + var objectProto4 = Object.prototype; + function isPrototype(value) { + var Ctor = value && value.constructor, proto = typeof Ctor == "function" && Ctor.prototype || objectProto4; + return value === proto; + } + var isPrototype_default = isPrototype; + + // node_modules/lodash-es/_baseTimes.js + function baseTimes(n2, iteratee) { + var index = -1, result = Array(n2); + while (++index < n2) { + result[index] = iteratee(index); + } + return result; + } + var baseTimes_default = baseTimes; + + // node_modules/lodash-es/_baseIsArguments.js + var argsTag = "[object Arguments]"; + function baseIsArguments(value) { + return isObjectLike_default(value) && baseGetTag_default(value) == argsTag; + } + var baseIsArguments_default = baseIsArguments; + + // node_modules/lodash-es/isArguments.js + var objectProto5 = Object.prototype; + var hasOwnProperty3 = objectProto5.hasOwnProperty; + var propertyIsEnumerable = objectProto5.propertyIsEnumerable; + var isArguments = baseIsArguments_default(function() { + return arguments; + }()) ? baseIsArguments_default : function(value) { + return isObjectLike_default(value) && hasOwnProperty3.call(value, "callee") && !propertyIsEnumerable.call(value, "callee"); + }; + var isArguments_default = isArguments; + + // node_modules/lodash-es/stubFalse.js + function stubFalse() { + return false; + } + var stubFalse_default = stubFalse; + + // node_modules/lodash-es/isBuffer.js + var freeExports = typeof exports == "object" && exports && !exports.nodeType && exports; + var freeModule = freeExports && typeof module == "object" && module && !module.nodeType && module; + var moduleExports = freeModule && freeModule.exports === freeExports; + var Buffer2 = moduleExports ? root_default.Buffer : void 0; + var nativeIsBuffer = Buffer2 ? Buffer2.isBuffer : void 0; + var isBuffer = nativeIsBuffer || stubFalse_default; + var isBuffer_default = isBuffer; + + // node_modules/lodash-es/_baseIsTypedArray.js + var argsTag2 = "[object Arguments]"; + var arrayTag = "[object Array]"; + var boolTag = "[object Boolean]"; + var dateTag = "[object Date]"; + var errorTag = "[object Error]"; + var funcTag2 = "[object Function]"; + var mapTag = "[object Map]"; + var numberTag = "[object Number]"; + var objectTag = "[object Object]"; + var regexpTag = "[object RegExp]"; + var setTag = "[object Set]"; + var stringTag = "[object String]"; + var weakMapTag = "[object WeakMap]"; + var arrayBufferTag = "[object ArrayBuffer]"; + var dataViewTag = "[object DataView]"; + var float32Tag = "[object Float32Array]"; + var float64Tag = "[object Float64Array]"; + var int8Tag = "[object Int8Array]"; + var int16Tag = "[object Int16Array]"; + var int32Tag = "[object Int32Array]"; + var uint8Tag = "[object Uint8Array]"; + var uint8ClampedTag = "[object Uint8ClampedArray]"; + var uint16Tag = "[object Uint16Array]"; + var uint32Tag = "[object Uint32Array]"; + var typedArrayTags = {}; + typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = typedArrayTags[uint32Tag] = true; + typedArrayTags[argsTag2] = typedArrayTags[arrayTag] = typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = typedArrayTags[dataViewTag] = typedArrayTags[dateTag] = typedArrayTags[errorTag] = typedArrayTags[funcTag2] = typedArrayTags[mapTag] = typedArrayTags[numberTag] = typedArrayTags[objectTag] = typedArrayTags[regexpTag] = typedArrayTags[setTag] = typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false; + function baseIsTypedArray(value) { + return isObjectLike_default(value) && isLength_default(value.length) && !!typedArrayTags[baseGetTag_default(value)]; + } + var baseIsTypedArray_default = baseIsTypedArray; + + // node_modules/lodash-es/_baseUnary.js + function baseUnary(func) { + return function(value) { + return func(value); + }; + } + var baseUnary_default = baseUnary; + + // node_modules/lodash-es/_nodeUtil.js + var freeExports2 = typeof exports == "object" && exports && !exports.nodeType && exports; + var freeModule2 = freeExports2 && typeof module == "object" && module && !module.nodeType && module; + var moduleExports2 = freeModule2 && freeModule2.exports === freeExports2; + var freeProcess = moduleExports2 && freeGlobal_default.process; + var nodeUtil = function() { + try { + var types = freeModule2 && freeModule2.require && freeModule2.require("util").types; + if (types) { + return types; } - function matches(d3_event2, binding2, testShift) { - var event = d3_event2; - var isMatch = false; - var tryKeyCode = true; - if (event.key !== void 0) { - tryKeyCode = event.key.charCodeAt(0) > 127; - isMatch = true; - if (binding2.event.key === void 0) { - isMatch = false; - } else if (Array.isArray(binding2.event.key)) { - if (binding2.event.key.map(function(s) { - return s.toLowerCase(); - }).indexOf(event.key.toLowerCase()) === -1) { - isMatch = false; - } - } else { - if (event.key.toLowerCase() !== binding2.event.key.toLowerCase()) { - isMatch = false; - } - } - } - if (!isMatch && (tryKeyCode || binding2.event.modifiers.altKey)) { - isMatch = event.keyCode === binding2.event.keyCode; - } - if (!isMatch) - return false; - if (!(event.ctrlKey && event.altKey)) { - if (event.ctrlKey !== binding2.event.modifiers.ctrlKey) - return false; - if (event.altKey !== binding2.event.modifiers.altKey) - return false; - } - if (event.metaKey !== binding2.event.modifiers.metaKey) - return false; - if (testShift && event.shiftKey !== binding2.event.modifiers.shiftKey) - return false; - return true; + return freeProcess && freeProcess.binding && freeProcess.binding("util"); + } catch (e) { + } + }(); + var nodeUtil_default = nodeUtil; + + // node_modules/lodash-es/isTypedArray.js + var nodeIsTypedArray = nodeUtil_default && nodeUtil_default.isTypedArray; + var isTypedArray = nodeIsTypedArray ? baseUnary_default(nodeIsTypedArray) : baseIsTypedArray_default; + var isTypedArray_default = isTypedArray; + + // node_modules/lodash-es/_arrayLikeKeys.js + var objectProto6 = Object.prototype; + var hasOwnProperty4 = objectProto6.hasOwnProperty; + function arrayLikeKeys(value, inherited) { + var isArr = isArray_default(value), isArg = !isArr && isArguments_default(value), isBuff = !isArr && !isArg && isBuffer_default(value), isType = !isArr && !isArg && !isBuff && isTypedArray_default(value), skipIndexes = isArr || isArg || isBuff || isType, result = skipIndexes ? baseTimes_default(value.length, String) : [], length = result.length; + for (var key in value) { + if ((inherited || hasOwnProperty4.call(value, key)) && !(skipIndexes && // Safari 9 has enumerable `arguments.length` in strict mode. + (key == "length" || // Node.js 0.10 has enumerable non-index properties on buffers. + isBuff && (key == "offset" || key == "parent") || // PhantomJS 2 has enumerable non-index properties on typed arrays. + isType && (key == "buffer" || key == "byteLength" || key == "byteOffset") || // Skip index properties. + isIndex_default(key, length)))) { + result.push(key); } } - function capture(d3_event) { - testBindings(d3_event, true); + return result; + } + var arrayLikeKeys_default = arrayLikeKeys; + + // node_modules/lodash-es/_overArg.js + function overArg(func, transform2) { + return function(arg) { + return func(transform2(arg)); + }; + } + var overArg_default = overArg; + + // node_modules/lodash-es/_nativeKeys.js + var nativeKeys = overArg_default(Object.keys, Object); + var nativeKeys_default = nativeKeys; + + // node_modules/lodash-es/_baseKeys.js + var objectProto7 = Object.prototype; + var hasOwnProperty5 = objectProto7.hasOwnProperty; + function baseKeys(object) { + if (!isPrototype_default(object)) { + return nativeKeys_default(object); } - function bubble(d3_event) { - var tagName = select_default2(d3_event.target).node().tagName; - if (tagName === "INPUT" || tagName === "SELECT" || tagName === "TEXTAREA") { - return; + var result = []; + for (var key in Object(object)) { + if (hasOwnProperty5.call(object, key) && key != "constructor") { + result.push(key); } - testBindings(d3_event, false); - } - function keybinding(selection2) { - selection2 = selection2 || select_default2(document); - selection2.on("keydown.capture." + namespace, capture, true); - selection2.on("keydown.bubble." + namespace, bubble, false); - return keybinding; } - keybinding.unbind = function(selection2) { - _keybindings = []; - selection2 = selection2 || select_default2(document); - selection2.on("keydown.capture." + namespace, null); - selection2.on("keydown.bubble." + namespace, null); - return keybinding; - }; - keybinding.clear = function() { - _keybindings = {}; - return keybinding; - }; - keybinding.off = function(codes, capture2) { - var arr = utilArrayUniq([].concat(codes)); - for (var i2 = 0; i2 < arr.length; i2++) { - var id2 = arr[i2] + (capture2 ? "-capture" : "-bubble"); - delete _keybindings[id2]; + return result; + } + var baseKeys_default = baseKeys; + + // node_modules/lodash-es/keys.js + function keys(object) { + return isArrayLike_default(object) ? arrayLikeKeys_default(object) : baseKeys_default(object); + } + var keys_default = keys; + + // node_modules/lodash-es/_nativeCreate.js + var nativeCreate = getNative_default(Object, "create"); + var nativeCreate_default = nativeCreate; + + // node_modules/lodash-es/_hashClear.js + function hashClear() { + this.__data__ = nativeCreate_default ? nativeCreate_default(null) : {}; + this.size = 0; + } + var hashClear_default = hashClear; + + // node_modules/lodash-es/_hashDelete.js + function hashDelete(key) { + var result = this.has(key) && delete this.__data__[key]; + this.size -= result ? 1 : 0; + return result; + } + var hashDelete_default = hashDelete; + + // node_modules/lodash-es/_hashGet.js + var HASH_UNDEFINED = "__lodash_hash_undefined__"; + var objectProto8 = Object.prototype; + var hasOwnProperty6 = objectProto8.hasOwnProperty; + function hashGet(key) { + var data = this.__data__; + if (nativeCreate_default) { + var result = data[key]; + return result === HASH_UNDEFINED ? void 0 : result; + } + return hasOwnProperty6.call(data, key) ? data[key] : void 0; + } + var hashGet_default = hashGet; + + // node_modules/lodash-es/_hashHas.js + var objectProto9 = Object.prototype; + var hasOwnProperty7 = objectProto9.hasOwnProperty; + function hashHas(key) { + var data = this.__data__; + return nativeCreate_default ? data[key] !== void 0 : hasOwnProperty7.call(data, key); + } + var hashHas_default = hashHas; + + // node_modules/lodash-es/_hashSet.js + var HASH_UNDEFINED2 = "__lodash_hash_undefined__"; + function hashSet(key, value) { + var data = this.__data__; + this.size += this.has(key) ? 0 : 1; + data[key] = nativeCreate_default && value === void 0 ? HASH_UNDEFINED2 : value; + return this; + } + var hashSet_default = hashSet; + + // node_modules/lodash-es/_Hash.js + function Hash(entries) { + var index = -1, length = entries == null ? 0 : entries.length; + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + Hash.prototype.clear = hashClear_default; + Hash.prototype["delete"] = hashDelete_default; + Hash.prototype.get = hashGet_default; + Hash.prototype.has = hashHas_default; + Hash.prototype.set = hashSet_default; + var Hash_default = Hash; + + // node_modules/lodash-es/_listCacheClear.js + function listCacheClear() { + this.__data__ = []; + this.size = 0; + } + var listCacheClear_default = listCacheClear; + + // node_modules/lodash-es/_assocIndexOf.js + function assocIndexOf(array2, key) { + var length = array2.length; + while (length--) { + if (eq_default(array2[length][0], key)) { + return length; } - return keybinding; + } + return -1; + } + var assocIndexOf_default = assocIndexOf; + + // node_modules/lodash-es/_listCacheDelete.js + var arrayProto = Array.prototype; + var splice = arrayProto.splice; + function listCacheDelete(key) { + var data = this.__data__, index = assocIndexOf_default(data, key); + if (index < 0) { + return false; + } + var lastIndex = data.length - 1; + if (index == lastIndex) { + data.pop(); + } else { + splice.call(data, index, 1); + } + --this.size; + return true; + } + var listCacheDelete_default = listCacheDelete; + + // node_modules/lodash-es/_listCacheGet.js + function listCacheGet(key) { + var data = this.__data__, index = assocIndexOf_default(data, key); + return index < 0 ? void 0 : data[index][1]; + } + var listCacheGet_default = listCacheGet; + + // node_modules/lodash-es/_listCacheHas.js + function listCacheHas(key) { + return assocIndexOf_default(this.__data__, key) > -1; + } + var listCacheHas_default = listCacheHas; + + // node_modules/lodash-es/_listCacheSet.js + function listCacheSet(key, value) { + var data = this.__data__, index = assocIndexOf_default(data, key); + if (index < 0) { + ++this.size; + data.push([key, value]); + } else { + data[index][1] = value; + } + return this; + } + var listCacheSet_default = listCacheSet; + + // node_modules/lodash-es/_ListCache.js + function ListCache(entries) { + var index = -1, length = entries == null ? 0 : entries.length; + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + ListCache.prototype.clear = listCacheClear_default; + ListCache.prototype["delete"] = listCacheDelete_default; + ListCache.prototype.get = listCacheGet_default; + ListCache.prototype.has = listCacheHas_default; + ListCache.prototype.set = listCacheSet_default; + var ListCache_default = ListCache; + + // node_modules/lodash-es/_Map.js + var Map2 = getNative_default(root_default, "Map"); + var Map_default = Map2; + + // node_modules/lodash-es/_mapCacheClear.js + function mapCacheClear() { + this.size = 0; + this.__data__ = { + "hash": new Hash_default(), + "map": new (Map_default || ListCache_default)(), + "string": new Hash_default() }; - keybinding.on = function(codes, callback, capture2) { - if (typeof callback !== "function") { - return keybinding.off(codes, capture2); - } - var arr = utilArrayUniq([].concat(codes)); - for (var i2 = 0; i2 < arr.length; i2++) { - var id2 = arr[i2] + (capture2 ? "-capture" : "-bubble"); - var binding = { - id: id2, - capture: capture2, - callback, - event: { - key: void 0, - keyCode: 0, - modifiers: { - shiftKey: false, - ctrlKey: false, - altKey: false, - metaKey: false - } - } - }; - if (_keybindings[id2]) { - console.warn('warning: duplicate keybinding for "' + id2 + '"'); - } - _keybindings[id2] = binding; - var matches = arr[i2].toLowerCase().match(/(?:(?:[^+⇧⌃⌥⌘])+|[⇧⌃⌥⌘]|\+\+|^\+$)/g); - for (var j2 = 0; j2 < matches.length; j2++) { - if (matches[j2] === "++") - matches[j2] = "+"; - if (matches[j2] in utilKeybinding.modifierCodes) { - var prop = utilKeybinding.modifierProperties[utilKeybinding.modifierCodes[matches[j2]]]; - binding.event.modifiers[prop] = true; - } else { - binding.event.key = utilKeybinding.keys[matches[j2]] || matches[j2]; - if (matches[j2] in utilKeybinding.keyCodes) { - binding.event.keyCode = utilKeybinding.keyCodes[matches[j2]]; - } - } - } - } - return keybinding; + } + var mapCacheClear_default = mapCacheClear; + + // node_modules/lodash-es/_isKeyable.js + function isKeyable(value) { + var type2 = typeof value; + return type2 == "string" || type2 == "number" || type2 == "symbol" || type2 == "boolean" ? value !== "__proto__" : value === null; + } + var isKeyable_default = isKeyable; + + // node_modules/lodash-es/_getMapData.js + function getMapData(map2, key) { + var data = map2.__data__; + return isKeyable_default(key) ? data[typeof key == "string" ? "string" : "hash"] : data.map; + } + var getMapData_default = getMapData; + + // node_modules/lodash-es/_mapCacheDelete.js + function mapCacheDelete(key) { + var result = getMapData_default(this, key)["delete"](key); + this.size -= result ? 1 : 0; + return result; + } + var mapCacheDelete_default = mapCacheDelete; + + // node_modules/lodash-es/_mapCacheGet.js + function mapCacheGet(key) { + return getMapData_default(this, key).get(key); + } + var mapCacheGet_default = mapCacheGet; + + // node_modules/lodash-es/_mapCacheHas.js + function mapCacheHas(key) { + return getMapData_default(this, key).has(key); + } + var mapCacheHas_default = mapCacheHas; + + // node_modules/lodash-es/_mapCacheSet.js + function mapCacheSet(key, value) { + var data = getMapData_default(this, key), size = data.size; + data.set(key, value); + this.size += data.size == size ? 0 : 1; + return this; + } + var mapCacheSet_default = mapCacheSet; + + // node_modules/lodash-es/_MapCache.js + function MapCache(entries) { + var index = -1, length = entries == null ? 0 : entries.length; + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + MapCache.prototype.clear = mapCacheClear_default; + MapCache.prototype["delete"] = mapCacheDelete_default; + MapCache.prototype.get = mapCacheGet_default; + MapCache.prototype.has = mapCacheHas_default; + MapCache.prototype.set = mapCacheSet_default; + var MapCache_default = MapCache; + + // node_modules/lodash-es/toString.js + function toString(value) { + return value == null ? "" : baseToString_default(value); + } + var toString_default = toString; + + // node_modules/lodash-es/_arrayPush.js + function arrayPush(array2, values) { + var index = -1, length = values.length, offset = array2.length; + while (++index < length) { + array2[offset + index] = values[index]; + } + return array2; + } + var arrayPush_default = arrayPush; + + // node_modules/lodash-es/_basePropertyOf.js + function basePropertyOf(object) { + return function(key) { + return object == null ? void 0 : object[key]; }; - return keybinding; } - utilKeybinding.modifierCodes = { - "\u21E7": 16, - shift: 16, - "\u2303": 17, - ctrl: 17, - "\u2325": 18, - alt: 18, - option: 18, - "\u2318": 91, - meta: 91, - cmd: 91, - "super": 91, - win: 91 - }; - utilKeybinding.modifierProperties = { - 16: "shiftKey", - 17: "ctrlKey", - 18: "altKey", - 91: "metaKey" - }; - utilKeybinding.plusKeys = ["plus", "ffplus", "=", "ffequals", "\u2260", "\xB1"]; - utilKeybinding.minusKeys = ["_", "-", "ffminus", "dash", "\u2013", "\u2014"]; - utilKeybinding.keys = { - "\u232B": "Backspace", - backspace: "Backspace", - "\u21E5": "Tab", - "\u21C6": "Tab", - tab: "Tab", - "\u21A9": "Enter", - "\u21B5": "Enter", - "\u23CE": "Enter", - "return": "Enter", - enter: "Enter", - "\u2305": "Enter", - "pause": "Pause", - "pause-break": "Pause", - "\u21EA": "CapsLock", - caps: "CapsLock", - "caps-lock": "CapsLock", - "\u238B": ["Escape", "Esc"], - escape: ["Escape", "Esc"], - esc: ["Escape", "Esc"], - space: [" ", "Spacebar"], - "\u2196": "PageUp", - pgup: "PageUp", - "page-up": "PageUp", - "\u2198": "PageDown", - pgdown: "PageDown", - "page-down": "PageDown", - "\u21DF": "End", - end: "End", - "\u21DE": "Home", - home: "Home", - ins: "Insert", - insert: "Insert", - "\u2326": ["Delete", "Del"], - del: ["Delete", "Del"], - "delete": ["Delete", "Del"], - "\u2190": ["ArrowLeft", "Left"], - left: ["ArrowLeft", "Left"], - "arrow-left": ["ArrowLeft", "Left"], - "\u2191": ["ArrowUp", "Up"], - up: ["ArrowUp", "Up"], - "arrow-up": ["ArrowUp", "Up"], - "\u2192": ["ArrowRight", "Right"], - right: ["ArrowRight", "Right"], - "arrow-right": ["ArrowRight", "Right"], - "\u2193": ["ArrowDown", "Down"], - down: ["ArrowDown", "Down"], - "arrow-down": ["ArrowDown", "Down"], - "*": ["*", "Multiply"], - star: ["*", "Multiply"], - asterisk: ["*", "Multiply"], - multiply: ["*", "Multiply"], - "+": ["+", "Add"], - "plus": ["+", "Add"], - "-": ["-", "Subtract"], - subtract: ["-", "Subtract"], - "dash": ["-", "Subtract"], - semicolon: ";", - equals: "=", - comma: ",", - period: ".", - "full-stop": ".", - slash: "/", - "forward-slash": "/", - tick: "`", - "back-quote": "`", - "open-bracket": "[", - "back-slash": "\\", - "close-bracket": "]", - quote: "'", - apostrophe: "'", - "num-0": "0", - "num-1": "1", - "num-2": "2", - "num-3": "3", - "num-4": "4", - "num-5": "5", - "num-6": "6", - "num-7": "7", - "num-8": "8", - "num-9": "9", - f1: "F1", - f2: "F2", - f3: "F3", - f4: "F4", - f5: "F5", - f6: "F6", - f7: "F7", - f8: "F8", - f9: "F9", - f10: "F10", - f11: "F11", - f12: "F12", - f13: "F13", - f14: "F14", - f15: "F15", - f16: "F16", - f17: "F17", - f18: "F18", - f19: "F19", - f20: "F20", - f21: "F21", - f22: "F22", - f23: "F23", - f24: "F24", - f25: "F25" - }; - utilKeybinding.keyCodes = { - "\u232B": 8, - backspace: 8, - "\u21E5": 9, - "\u21C6": 9, - tab: 9, - "\u21A9": 13, - "\u21B5": 13, - "\u23CE": 13, - "return": 13, - enter: 13, - "\u2305": 13, - "pause": 19, - "pause-break": 19, - "\u21EA": 20, - caps: 20, - "caps-lock": 20, - "\u238B": 27, - escape: 27, - esc: 27, - space: 32, - "\u2196": 33, - pgup: 33, - "page-up": 33, - "\u2198": 34, - pgdown: 34, - "page-down": 34, - "\u21DF": 35, - end: 35, - "\u21DE": 36, - home: 36, - ins: 45, - insert: 45, - "\u2326": 46, - del: 46, - "delete": 46, - "\u2190": 37, - left: 37, - "arrow-left": 37, - "\u2191": 38, - up: 38, - "arrow-up": 38, - "\u2192": 39, - right: 39, - "arrow-right": 39, - "\u2193": 40, - down: 40, - "arrow-down": 40, - "ffequals": 61, - "*": 106, - star: 106, - asterisk: 106, - multiply: 106, - "+": 107, - "plus": 107, - "-": 109, - subtract: 109, - "|": 124, - "ffplus": 171, - "ffminus": 173, - ";": 186, - semicolon: 186, - "=": 187, - "equals": 187, - ",": 188, - comma: 188, - "dash": 189, - ".": 190, - period: 190, - "full-stop": 190, - "/": 191, - slash: 191, - "forward-slash": 191, - "`": 192, - tick: 192, - "back-quote": 192, - "[": 219, - "open-bracket": 219, - "\\": 220, - "back-slash": 220, - "]": 221, - "close-bracket": 221, - "'": 222, - quote: 222, - apostrophe: 222 - }; - var i = 95; - var n = 0; - while (++i < 106) { - utilKeybinding.keyCodes["num-" + n] = i; - ++n; + var basePropertyOf_default = basePropertyOf; + + // node_modules/lodash-es/_stackClear.js + function stackClear() { + this.__data__ = new ListCache_default(); + this.size = 0; } - i = 47; - n = 0; - while (++i < 58) { - utilKeybinding.keyCodes[n] = i; - ++n; + var stackClear_default = stackClear; + + // node_modules/lodash-es/_stackDelete.js + function stackDelete(key) { + var data = this.__data__, result = data["delete"](key); + this.size = data.size; + return result; } - i = 111; - n = 1; - while (++i < 136) { - utilKeybinding.keyCodes["f" + n] = i; - ++n; + var stackDelete_default = stackDelete; + + // node_modules/lodash-es/_stackGet.js + function stackGet(key) { + return this.__data__.get(key); } - i = 64; - while (++i < 91) { - utilKeybinding.keyCodes[String.fromCharCode(i).toLowerCase()] = i; + var stackGet_default = stackGet; + + // node_modules/lodash-es/_stackHas.js + function stackHas(key) { + return this.__data__.has(key); } + var stackHas_default = stackHas; - // modules/util/object.js - function utilObjectOmit(obj, omitKeys) { - return Object.keys(obj).reduce(function(result, key) { - if (omitKeys.indexOf(key) === -1) { - result[key] = obj[key]; + // node_modules/lodash-es/_stackSet.js + var LARGE_ARRAY_SIZE = 200; + function stackSet(key, value) { + var data = this.__data__; + if (data instanceof ListCache_default) { + var pairs = data.__data__; + if (!Map_default || pairs.length < LARGE_ARRAY_SIZE - 1) { + pairs.push([key, value]); + this.size = ++data.size; + return this; } - return result; - }, {}); + data = this.__data__ = new MapCache_default(pairs); + } + data.set(key, value); + this.size = data.size; + return this; } + var stackSet_default = stackSet; - // modules/util/rebind.js - function utilRebind(target, source) { - var i2 = 1, n2 = arguments.length, method; - while (++i2 < n2) { - target[method = arguments[i2]] = d3_rebind(target, source, source[method]); + // node_modules/lodash-es/_Stack.js + function Stack(entries) { + var data = this.__data__ = new ListCache_default(entries); + this.size = data.size; + } + Stack.prototype.clear = stackClear_default; + Stack.prototype["delete"] = stackDelete_default; + Stack.prototype.get = stackGet_default; + Stack.prototype.has = stackHas_default; + Stack.prototype.set = stackSet_default; + var Stack_default = Stack; + + // node_modules/lodash-es/_arrayFilter.js + function arrayFilter(array2, predicate) { + var index = -1, length = array2 == null ? 0 : array2.length, resIndex = 0, result = []; + while (++index < length) { + var value = array2[index]; + if (predicate(value, index, array2)) { + result[resIndex++] = value; + } } - return target; + return result; } - function d3_rebind(target, source, method) { - return function() { - var value = method.apply(source, arguments); - return value === source ? target : value; - }; + var arrayFilter_default = arrayFilter; + + // node_modules/lodash-es/stubArray.js + function stubArray() { + return []; } + var stubArray_default = stubArray; - // modules/util/session_mutex.js - function utilSessionMutex(name) { - var mutex = {}; - var intervalID; - function renew() { - var expires = new Date(); - expires.setSeconds(expires.getSeconds() + 5); - document.cookie = name + "=1; expires=" + expires.toUTCString() + "; sameSite=strict"; + // node_modules/lodash-es/_getSymbols.js + var objectProto10 = Object.prototype; + var propertyIsEnumerable2 = objectProto10.propertyIsEnumerable; + var nativeGetSymbols = Object.getOwnPropertySymbols; + var getSymbols = !nativeGetSymbols ? stubArray_default : function(object) { + if (object == null) { + return []; } - 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, 4e3); - return true; - }; - mutex.unlock = function() { - if (!intervalID) - return; - document.cookie = name + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT; sameSite=strict"; - clearInterval(intervalID); - intervalID = null; - }; - mutex.locked = function() { - return !!intervalID; + object = Object(object); + return arrayFilter_default(nativeGetSymbols(object), function(symbol) { + return propertyIsEnumerable2.call(object, symbol); + }); + }; + var getSymbols_default = getSymbols; + + // node_modules/lodash-es/_baseGetAllKeys.js + function baseGetAllKeys(object, keysFunc, symbolsFunc) { + var result = keysFunc(object); + return isArray_default(object) ? result : arrayPush_default(result, symbolsFunc(object)); + } + var baseGetAllKeys_default = baseGetAllKeys; + + // node_modules/lodash-es/_getAllKeys.js + function getAllKeys(object) { + return baseGetAllKeys_default(object, keys_default, getSymbols_default); + } + var getAllKeys_default = getAllKeys; + + // node_modules/lodash-es/_DataView.js + var DataView2 = getNative_default(root_default, "DataView"); + var DataView_default = DataView2; + + // node_modules/lodash-es/_Promise.js + var Promise2 = getNative_default(root_default, "Promise"); + var Promise_default = Promise2; + + // node_modules/lodash-es/_Set.js + var Set2 = getNative_default(root_default, "Set"); + var Set_default = Set2; + + // node_modules/lodash-es/_getTag.js + var mapTag2 = "[object Map]"; + var objectTag2 = "[object Object]"; + var promiseTag = "[object Promise]"; + var setTag2 = "[object Set]"; + var weakMapTag2 = "[object WeakMap]"; + var dataViewTag2 = "[object DataView]"; + var dataViewCtorString = toSource_default(DataView_default); + var mapCtorString = toSource_default(Map_default); + var promiseCtorString = toSource_default(Promise_default); + var setCtorString = toSource_default(Set_default); + var weakMapCtorString = toSource_default(WeakMap_default); + var getTag = baseGetTag_default; + if (DataView_default && getTag(new DataView_default(new ArrayBuffer(1))) != dataViewTag2 || Map_default && getTag(new Map_default()) != mapTag2 || Promise_default && getTag(Promise_default.resolve()) != promiseTag || Set_default && getTag(new Set_default()) != setTag2 || WeakMap_default && getTag(new WeakMap_default()) != weakMapTag2) { + getTag = function(value) { + var result = baseGetTag_default(value), Ctor = result == objectTag2 ? value.constructor : void 0, ctorString = Ctor ? toSource_default(Ctor) : ""; + if (ctorString) { + switch (ctorString) { + case dataViewCtorString: + return dataViewTag2; + case mapCtorString: + return mapTag2; + case promiseCtorString: + return promiseTag; + case setCtorString: + return setTag2; + case weakMapCtorString: + return weakMapTag2; + } + } + return result; }; - return mutex; } + var getTag_default = getTag; - // modules/util/tiler.js - function utilTiler() { - var _size = [256, 256]; - var _scale = 256; - var _tileSize = 256; - var _zoomExtent = [0, 20]; - var _translate = [_size[0] / 2, _size[1] / 2]; - var _margin = 0; - var _skipNullIsland = false; - function clamp3(num, min3, max3) { - return Math.max(min3, Math.min(num, max3)); + // node_modules/lodash-es/_Uint8Array.js + var Uint8Array2 = root_default.Uint8Array; + var Uint8Array_default = Uint8Array2; + + // node_modules/lodash-es/_setCacheAdd.js + var HASH_UNDEFINED3 = "__lodash_hash_undefined__"; + function setCacheAdd(value) { + this.__data__.set(value, HASH_UNDEFINED3); + return this; + } + var setCacheAdd_default = setCacheAdd; + + // node_modules/lodash-es/_setCacheHas.js + function setCacheHas(value) { + return this.__data__.has(value); + } + var setCacheHas_default = setCacheHas; + + // node_modules/lodash-es/_SetCache.js + function SetCache(values) { + var index = -1, length = values == null ? 0 : values.length; + this.__data__ = new MapCache_default(); + while (++index < length) { + this.add(values[index]); } - function nearNullIsland(tile) { - var x = tile[0]; - var y = tile[1]; - var z = tile[2]; - if (z >= 7) { - var center = Math.pow(2, z - 1); - var width = Math.pow(2, z - 6); - var min3 = center - width / 2; - var max3 = center + width / 2 - 1; - return x >= min3 && x <= max3 && y >= min3 && y <= max3; + } + SetCache.prototype.add = SetCache.prototype.push = setCacheAdd_default; + SetCache.prototype.has = setCacheHas_default; + var SetCache_default = SetCache; + + // node_modules/lodash-es/_arraySome.js + function arraySome(array2, predicate) { + var index = -1, length = array2 == null ? 0 : array2.length; + while (++index < length) { + if (predicate(array2[index], index, array2)) { + return true; } + } + return false; + } + var arraySome_default = arraySome; + + // node_modules/lodash-es/_cacheHas.js + function cacheHas(cache, key) { + return cache.has(key); + } + var cacheHas_default = cacheHas; + + // node_modules/lodash-es/_equalArrays.js + var COMPARE_PARTIAL_FLAG = 1; + var COMPARE_UNORDERED_FLAG = 2; + function equalArrays(array2, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG, arrLength = array2.length, othLength = other.length; + if (arrLength != othLength && !(isPartial && othLength > arrLength)) { return false; } - function tiler8() { - var z = geoScaleToZoom(_scale / (2 * Math.PI), _tileSize); - var z0 = clamp3(Math.round(z), _zoomExtent[0], _zoomExtent[1]); - var tileMin = 0; - var tileMax = Math.pow(2, z0) - 1; - var log2ts = Math.log(_tileSize) * Math.LOG2E; - var k = Math.pow(2, z - z0 + log2ts); - var origin = [ - (_translate[0] - _scale / 2) / k, - (_translate[1] - _scale / 2) / k - ]; - var cols = range( - clamp3(Math.floor(-origin[0]) - _margin, tileMin, tileMax + 1), - clamp3(Math.ceil(_size[0] / k - origin[0]) + _margin, tileMin, tileMax + 1) - ); - var rows = range( - clamp3(Math.floor(-origin[1]) - _margin, tileMin, tileMax + 1), - clamp3(Math.ceil(_size[1] / k - origin[1]) + _margin, tileMin, tileMax + 1) - ); - var tiles = []; - for (var i2 = 0; i2 < rows.length; i2++) { - var y = rows[i2]; - for (var j2 = 0; j2 < cols.length; j2++) { - var x = cols[j2]; - if (i2 >= _margin && i2 <= rows.length - _margin && j2 >= _margin && j2 <= cols.length - _margin) { - tiles.unshift([x, y, z0]); - } else { - tiles.push([x, y, z0]); + var arrStacked = stack.get(array2); + var othStacked = stack.get(other); + if (arrStacked && othStacked) { + return arrStacked == other && othStacked == array2; + } + var index = -1, result = true, seen = bitmask & COMPARE_UNORDERED_FLAG ? new SetCache_default() : void 0; + stack.set(array2, other); + stack.set(other, array2); + while (++index < arrLength) { + var arrValue = array2[index], othValue = other[index]; + if (customizer) { + var compared = isPartial ? customizer(othValue, arrValue, index, other, array2, stack) : customizer(arrValue, othValue, index, array2, other, stack); + } + if (compared !== void 0) { + if (compared) { + continue; + } + result = false; + break; + } + if (seen) { + if (!arraySome_default(other, function(othValue2, othIndex) { + if (!cacheHas_default(seen, othIndex) && (arrValue === othValue2 || equalFunc(arrValue, othValue2, bitmask, customizer, stack))) { + return seen.push(othIndex); } + })) { + result = false; + break; } + } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { + result = false; + break; } - tiles.translate = origin; - tiles.scale = k; - return tiles; } - tiler8.getTiles = function(projection2) { - var origin = [ - projection2.scale() * Math.PI - projection2.translate()[0], - projection2.scale() * Math.PI - projection2.translate()[1] - ]; - this.size(projection2.clipExtent()[1]).scale(projection2.scale() * 2 * Math.PI).translate(projection2.translate()); - var tiles = tiler8(); - var ts = tiles.scale; - return tiles.map(function(tile) { - if (_skipNullIsland && nearNullIsland(tile)) { - return false; - } - var x = tile[0] * ts - origin[0]; - var y = tile[1] * ts - origin[1]; - return { - id: tile.toString(), - xyz: tile, - extent: geoExtent( - projection2.invert([x, y + ts]), - projection2.invert([x + ts, y]) - ) - }; - }).filter(Boolean); - }; - tiler8.getGeoJSON = function(projection2) { - var features2 = tiler8.getTiles(projection2).map(function(tile) { - return { - type: "Feature", - properties: { - id: tile.id, - name: tile.id - }, - geometry: { - type: "Polygon", - coordinates: [tile.extent.polygon()] - } - }; - }); - return { - type: "FeatureCollection", - features: features2 - }; - }; - tiler8.tileSize = function(val) { - if (!arguments.length) - return _tileSize; - _tileSize = val; - return tiler8; - }; - tiler8.zoomExtent = function(val) { - if (!arguments.length) - return _zoomExtent; - _zoomExtent = val; - return tiler8; - }; - tiler8.size = function(val) { - if (!arguments.length) - return _size; - _size = val; - return tiler8; - }; - tiler8.scale = function(val) { - if (!arguments.length) - return _scale; - _scale = val; - return tiler8; - }; - tiler8.translate = function(val) { - if (!arguments.length) - return _translate; - _translate = val; - return tiler8; - }; - tiler8.margin = function(val) { - if (!arguments.length) - return _margin; - _margin = +val; - return tiler8; - }; - tiler8.skipNullIsland = function(val) { - if (!arguments.length) - return _skipNullIsland; - _skipNullIsland = val; - return tiler8; - }; - return tiler8; + stack["delete"](array2); + stack["delete"](other); + return result; } + var equalArrays_default = equalArrays; - // modules/util/trigger_event.js - function utilTriggerEvent(target, type3) { - target.each(function() { - var evt = document.createEvent("HTMLEvents"); - evt.initEvent(type3, true, true); - this.dispatchEvent(evt); + // node_modules/lodash-es/_mapToArray.js + function mapToArray(map2) { + var index = -1, result = Array(map2.size); + map2.forEach(function(value, key) { + result[++index] = [key, value]; }); + return result; } + var mapToArray_default = mapToArray; - // modules/core/locations.js - var _mainLocations = coreLocations(); - function coreLocations() { - let _this = {}; - let _resolvedFeatures = {}; - let _loco = new location_conflation_default(); - let _wp; - const world = { locationSet: { include: ["Q2"] } }; - resolveLocationSet(world); - rebuildIndex(); - let _queue = []; - let _deferred2 = /* @__PURE__ */ new Set(); - let _inProcess; - function processQueue() { - if (!_queue.length) - return Promise.resolve(); - const chunk = _queue.pop(); - return new Promise((resolvePromise) => { - const handle = window.requestIdleCallback(() => { - _deferred2.delete(handle); - chunk.forEach(resolveLocationSet); - resolvePromise(); - }); - _deferred2.add(handle); - }).then(() => processQueue()); - } - function resolveLocationSet(obj) { - if (obj.locationSetID) - return; - try { - let locationSet = obj.locationSet; - if (!locationSet) { - throw new Error("object missing locationSet property"); + // node_modules/lodash-es/_setToArray.js + function setToArray(set3) { + var index = -1, result = Array(set3.size); + set3.forEach(function(value) { + result[++index] = value; + }); + return result; + } + var setToArray_default = setToArray; + + // node_modules/lodash-es/_equalByTag.js + var COMPARE_PARTIAL_FLAG2 = 1; + var COMPARE_UNORDERED_FLAG2 = 2; + var boolTag2 = "[object Boolean]"; + var dateTag2 = "[object Date]"; + var errorTag2 = "[object Error]"; + var mapTag3 = "[object Map]"; + var numberTag2 = "[object Number]"; + var regexpTag2 = "[object RegExp]"; + var setTag3 = "[object Set]"; + var stringTag2 = "[object String]"; + var symbolTag2 = "[object Symbol]"; + var arrayBufferTag2 = "[object ArrayBuffer]"; + var dataViewTag3 = "[object DataView]"; + var symbolProto2 = Symbol_default ? Symbol_default.prototype : void 0; + var symbolValueOf = symbolProto2 ? symbolProto2.valueOf : void 0; + function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { + switch (tag) { + case dataViewTag3: + if (object.byteLength != other.byteLength || object.byteOffset != other.byteOffset) { + return false; } - if (!locationSet.include) { - locationSet.include = ["Q2"]; + object = object.buffer; + other = other.buffer; + case arrayBufferTag2: + if (object.byteLength != other.byteLength || !equalFunc(new Uint8Array_default(object), new Uint8Array_default(other))) { + return false; } - const resolved = _loco.resolveLocationSet(locationSet); - const locationSetID = resolved.id; - obj.locationSetID = locationSetID; - if (!resolved.feature.geometry.coordinates.length || !resolved.feature.properties.area) { - throw new Error(`locationSet ${locationSetID} resolves to an empty feature.`); + return true; + case boolTag2: + case dateTag2: + case numberTag2: + return eq_default(+object, +other); + case errorTag2: + return object.name == other.name && object.message == other.message; + case regexpTag2: + case stringTag2: + return object == other + ""; + case mapTag3: + var convert = mapToArray_default; + case setTag3: + var isPartial = bitmask & COMPARE_PARTIAL_FLAG2; + convert || (convert = setToArray_default); + if (object.size != other.size && !isPartial) { + return false; } - if (!_resolvedFeatures[locationSetID]) { - let feature3 = JSON.parse(JSON.stringify(resolved.feature)); - feature3.id = locationSetID; - feature3.properties.id = locationSetID; - _resolvedFeatures[locationSetID] = feature3; + var stacked = stack.get(object); + if (stacked) { + return stacked == other; + } + bitmask |= COMPARE_UNORDERED_FLAG2; + stack.set(object, other); + var result = equalArrays_default(convert(object), convert(other), bitmask, customizer, equalFunc, stack); + stack["delete"](object); + return result; + case symbolTag2: + if (symbolValueOf) { + return symbolValueOf.call(object) == symbolValueOf.call(other); } - } catch (err) { - obj.locationSet = { include: ["Q2"] }; - obj.locationSetID = "+[Q2]"; - } - } - function rebuildIndex() { - _wp = (0, import_which_polygon2.default)({ features: Object.values(_resolvedFeatures) }); } - _this.mergeCustomGeoJSON = (fc) => { - if (fc && fc.type === "FeatureCollection" && Array.isArray(fc.features)) { - fc.features.forEach((feature3) => { - feature3.properties = feature3.properties || {}; - let props = feature3.properties; - let id2 = feature3.id || props.id; - if (!id2 || !/^\S+\.geojson$/i.test(id2)) - return; - id2 = id2.toLowerCase(); - feature3.id = id2; - props.id = id2; - if (!props.area) { - const area = import_geojson_area2.default.geometry(feature3.geometry) / 1e6; - props.area = Number(area.toFixed(2)); - } - _loco._cache[id2] = feature3; - }); - } - }; - _this.mergeLocationSets = (objects) => { - if (!Array.isArray(objects)) - return Promise.reject("nothing to do"); - _queue = _queue.concat(utilArrayChunk(objects, 200)); - if (!_inProcess) { - _inProcess = processQueue().then(() => { - rebuildIndex(); - _inProcess = null; - return objects; - }); - } - return _inProcess; - }; - _this.locationSetID = (locationSet) => { - let locationSetID; - try { - locationSetID = _loco.validateLocationSet(locationSet).id; - } catch (err) { - locationSetID = "+[Q2]"; - } - return locationSetID; - }; - _this.feature = (locationSetID) => _resolvedFeatures[locationSetID] || _resolvedFeatures["+[Q2]"]; - _this.locationsAt = (loc) => { - let result = {}; - (_wp(loc, true) || []).forEach((prop) => result[prop.id] = prop.area); - return result; - }; - _this.query = (loc, multi) => _wp(loc, multi); - _this.loco = () => _loco; - _this.wp = () => _wp; - return _this; + return false; } + var equalByTag_default = equalByTag; - // node_modules/lodash-es/_freeGlobal.js - var freeGlobal = typeof global == "object" && global && global.Object === Object && global; - var freeGlobal_default = freeGlobal; - - // node_modules/lodash-es/_root.js - var freeSelf = typeof self == "object" && self && self.Object === Object && self; - var root2 = freeGlobal_default || freeSelf || Function("return this")(); - var root_default = root2; - - // node_modules/lodash-es/_Symbol.js - var Symbol2 = root_default.Symbol; - var Symbol_default = Symbol2; - - // node_modules/lodash-es/_getRawTag.js - var objectProto = Object.prototype; - var hasOwnProperty = objectProto.hasOwnProperty; - var nativeObjectToString = objectProto.toString; - var symToStringTag = Symbol_default ? Symbol_default.toStringTag : void 0; - function getRawTag(value) { - var isOwn = hasOwnProperty.call(value, symToStringTag), tag = value[symToStringTag]; - try { - value[symToStringTag] = void 0; - var unmasked = true; - } catch (e) { + // node_modules/lodash-es/_equalObjects.js + var COMPARE_PARTIAL_FLAG3 = 1; + var objectProto11 = Object.prototype; + var hasOwnProperty8 = objectProto11.hasOwnProperty; + function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG3, objProps = getAllKeys_default(object), objLength = objProps.length, othProps = getAllKeys_default(other), othLength = othProps.length; + if (objLength != othLength && !isPartial) { + return false; } - var result = nativeObjectToString.call(value); - if (unmasked) { - if (isOwn) { - value[symToStringTag] = tag; - } else { - delete value[symToStringTag]; + var index = objLength; + while (index--) { + var key = objProps[index]; + if (!(isPartial ? key in other : hasOwnProperty8.call(other, key))) { + return false; } } - return result; - } - var getRawTag_default = getRawTag; - - // node_modules/lodash-es/_objectToString.js - var objectProto2 = Object.prototype; - var nativeObjectToString2 = objectProto2.toString; - function objectToString(value) { - return nativeObjectToString2.call(value); - } - var objectToString_default = objectToString; - - // node_modules/lodash-es/_baseGetTag.js - var nullTag = "[object Null]"; - var undefinedTag = "[object Undefined]"; - var symToStringTag2 = Symbol_default ? Symbol_default.toStringTag : void 0; - function baseGetTag(value) { - if (value == null) { - return value === void 0 ? undefinedTag : nullTag; + var objStacked = stack.get(object); + var othStacked = stack.get(other); + if (objStacked && othStacked) { + return objStacked == other && othStacked == object; } - return symToStringTag2 && symToStringTag2 in Object(value) ? getRawTag_default(value) : objectToString_default(value); - } - var baseGetTag_default = baseGetTag; - - // node_modules/lodash-es/isObjectLike.js - function isObjectLike(value) { - return value != null && typeof value == "object"; - } - var isObjectLike_default = isObjectLike; - - // node_modules/lodash-es/isSymbol.js - var symbolTag = "[object Symbol]"; - function isSymbol(value) { - return typeof value == "symbol" || isObjectLike_default(value) && baseGetTag_default(value) == symbolTag; - } - var isSymbol_default = isSymbol; - - // node_modules/lodash-es/_arrayMap.js - function arrayMap(array2, iteratee) { - var index = -1, length = array2 == null ? 0 : array2.length, result = Array(length); - while (++index < length) { - result[index] = iteratee(array2[index], index, array2); + var result = true; + stack.set(object, other); + stack.set(other, object); + var skipCtor = isPartial; + while (++index < objLength) { + key = objProps[index]; + var objValue = object[key], othValue = other[key]; + if (customizer) { + var compared = isPartial ? customizer(othValue, objValue, key, other, object, stack) : customizer(objValue, othValue, key, object, other, stack); + } + if (!(compared === void 0 ? objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack) : compared)) { + result = false; + break; + } + skipCtor || (skipCtor = key == "constructor"); + } + if (result && !skipCtor) { + var objCtor = object.constructor, othCtor = other.constructor; + if (objCtor != othCtor && ("constructor" in object && "constructor" in other) && !(typeof objCtor == "function" && objCtor instanceof objCtor && typeof othCtor == "function" && othCtor instanceof othCtor)) { + result = false; + } } + stack["delete"](object); + stack["delete"](other); return result; } - var arrayMap_default = arrayMap; - - // node_modules/lodash-es/isArray.js - var isArray = Array.isArray; - var isArray_default = isArray; - - // node_modules/lodash-es/_baseToString.js - var INFINITY = 1 / 0; - var symbolProto = Symbol_default ? Symbol_default.prototype : void 0; - var symbolToString = symbolProto ? symbolProto.toString : void 0; - function baseToString(value) { - if (typeof value == "string") { - return value; + var equalObjects_default = equalObjects; + + // node_modules/lodash-es/_baseIsEqualDeep.js + var COMPARE_PARTIAL_FLAG4 = 1; + var argsTag3 = "[object Arguments]"; + var arrayTag2 = "[object Array]"; + var objectTag3 = "[object Object]"; + var objectProto12 = Object.prototype; + var hasOwnProperty9 = objectProto12.hasOwnProperty; + function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { + var objIsArr = isArray_default(object), othIsArr = isArray_default(other), objTag = objIsArr ? arrayTag2 : getTag_default(object), othTag = othIsArr ? arrayTag2 : getTag_default(other); + objTag = objTag == argsTag3 ? objectTag3 : objTag; + othTag = othTag == argsTag3 ? objectTag3 : othTag; + var objIsObj = objTag == objectTag3, othIsObj = othTag == objectTag3, isSameTag = objTag == othTag; + if (isSameTag && isBuffer_default(object)) { + if (!isBuffer_default(other)) { + return false; + } + objIsArr = true; + objIsObj = false; } - if (isArray_default(value)) { - return arrayMap_default(value, baseToString) + ""; + if (isSameTag && !objIsObj) { + stack || (stack = new Stack_default()); + return objIsArr || isTypedArray_default(object) ? equalArrays_default(object, other, bitmask, customizer, equalFunc, stack) : equalByTag_default(object, other, objTag, bitmask, customizer, equalFunc, stack); } - if (isSymbol_default(value)) { - return symbolToString ? symbolToString.call(value) : ""; + if (!(bitmask & COMPARE_PARTIAL_FLAG4)) { + var objIsWrapped = objIsObj && hasOwnProperty9.call(object, "__wrapped__"), othIsWrapped = othIsObj && hasOwnProperty9.call(other, "__wrapped__"); + if (objIsWrapped || othIsWrapped) { + var objUnwrapped = objIsWrapped ? object.value() : object, othUnwrapped = othIsWrapped ? other.value() : other; + stack || (stack = new Stack_default()); + return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack); + } } - var result = value + ""; - return result == "0" && 1 / value == -INFINITY ? "-0" : result; - } - var baseToString_default = baseToString; - - // node_modules/lodash-es/_trimmedEndIndex.js - var reWhitespace = /\s/; - function trimmedEndIndex(string) { - var index = string.length; - while (index-- && reWhitespace.test(string.charAt(index))) { + if (!isSameTag) { + return false; } - return index; - } - var trimmedEndIndex_default = trimmedEndIndex; - - // node_modules/lodash-es/_baseTrim.js - var reTrimStart = /^\s+/; - function baseTrim(string) { - return string ? string.slice(0, trimmedEndIndex_default(string) + 1).replace(reTrimStart, "") : string; - } - var baseTrim_default = baseTrim; - - // node_modules/lodash-es/isObject.js - function isObject(value) { - var type3 = typeof value; - return value != null && (type3 == "object" || type3 == "function"); + stack || (stack = new Stack_default()); + return equalObjects_default(object, other, bitmask, customizer, equalFunc, stack); } - var isObject_default = isObject; + var baseIsEqualDeep_default = baseIsEqualDeep; - // node_modules/lodash-es/toNumber.js - var NAN = 0 / 0; - var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; - var reIsBinary = /^0b[01]+$/i; - var reIsOctal = /^0o[0-7]+$/i; - var freeParseInt = parseInt; - function toNumber(value) { - if (typeof value == "number") { - return value; - } - if (isSymbol_default(value)) { - return NAN; - } - if (isObject_default(value)) { - var other = typeof value.valueOf == "function" ? value.valueOf() : value; - value = isObject_default(other) ? other + "" : other; + // node_modules/lodash-es/_baseIsEqual.js + function baseIsEqual(value, other, bitmask, customizer, stack) { + if (value === other) { + return true; } - if (typeof value != "string") { - return value === 0 ? value : +value; + if (value == null || other == null || !isObjectLike_default(value) && !isObjectLike_default(other)) { + return value !== value && other !== other; } - value = baseTrim_default(value); - var isBinary = reIsBinary.test(value); - return isBinary || reIsOctal.test(value) ? freeParseInt(value.slice(2), isBinary ? 2 : 8) : reIsBadHex.test(value) ? NAN : +value; - } - var toNumber_default = toNumber; - - // node_modules/lodash-es/toString.js - function toString(value) { - return value == null ? "" : baseToString_default(value); - } - var toString_default = toString; - - // node_modules/lodash-es/_basePropertyOf.js - function basePropertyOf(object) { - return function(key) { - return object == null ? void 0 : object[key]; - }; + return baseIsEqualDeep_default(value, other, bitmask, customizer, baseIsEqual, stack); } - var basePropertyOf_default = basePropertyOf; + var baseIsEqual_default = baseIsEqual; // node_modules/lodash-es/now.js var now2 = function() { @@ -24738,6 +25591,12 @@ } var escape_default = escape2; + // node_modules/lodash-es/isEqual.js + function isEqual(value, other) { + return baseIsEqual_default(value, other); + } + var isEqual_default = isEqual; + // node_modules/lodash-es/throttle.js var FUNC_ERROR_TEXT2 = "Expected a function"; function throttle(func, wait, options2) { @@ -24777,14391 +25636,15042 @@ } var unescape_default = unescape2; - // modules/core/localizer.js - var _mainLocalizer = coreLocalizer(); - var _t = _mainLocalizer.t; - function coreLocalizer() { - let localizer = {}; - let _dataLanguages = {}; - let _dataLocales = {}; - let _localeStrings = {}; - let _localeCode = "en-US"; - let _localeCodes = ["en-US", "en"]; - let _languageCode = "en"; - let _textDirection = "ltr"; - let _usesMetric = false; - let _languageNames = {}; - let _scriptNames = {}; - localizer.localeCode = () => _localeCode; - localizer.localeCodes = () => _localeCodes; - localizer.languageCode = () => _languageCode; - localizer.textDirection = () => _textDirection; - localizer.usesMetric = () => _usesMetric; - localizer.languageNames = () => _languageNames; - localizer.scriptNames = () => _scriptNames; - let _preferredLocaleCodes = []; - localizer.preferredLocaleCodes = function(codes) { - if (!arguments.length) - return _preferredLocaleCodes; - if (typeof codes === "string") { - _preferredLocaleCodes = codes.split(/,|;| /gi).filter(Boolean); - } else { - _preferredLocaleCodes = codes; - } - return localizer; - }; - var _loadPromise; - localizer.ensureLoaded = () => { - if (_loadPromise) - return _loadPromise; - let filesToFetch = [ - "languages", - "locales" - ]; - const localeDirs = { - general: "locales", - tagging: "https://cdn.jsdelivr.net/npm/@openstreetmap/id-tagging-schema@3/dist/translations" - }; - let fileMap = _mainFileFetcher.fileMap(); - for (let scopeId in localeDirs) { - const key = `locales_index_${scopeId}`; - if (!fileMap[key]) { - fileMap[key] = localeDirs[scopeId] + "/index.min.json"; - } - filesToFetch.push(key); - } - return _loadPromise = Promise.all(filesToFetch.map((key) => _mainFileFetcher.get(key))).then((results) => { - _dataLanguages = results[0]; - _dataLocales = results[1]; - let indexes = results.slice(2); - let requestedLocales = (_preferredLocaleCodes || []).concat(utilDetect().browserLocales).concat(["en"]); - _localeCodes = localesToUseFrom(requestedLocales); - _localeCode = _localeCodes[0]; - let loadStringsPromises = []; - indexes.forEach((index, i2) => { - const fullCoverageIndex = _localeCodes.findIndex(function(locale2) { - return index[locale2] && index[locale2].pct === 1; - }); - _localeCodes.slice(0, fullCoverageIndex + 1).forEach(function(code) { - let scopeId = Object.keys(localeDirs)[i2]; - let directory = Object.values(localeDirs)[i2]; - if (index[code]) - loadStringsPromises.push(localizer.loadLocale(code, scopeId, directory)); - }); - }); - return Promise.all(loadStringsPromises); - }).then(() => { - updateForCurrentLocale(); - }).catch((err) => console.error(err)); - }; - function localesToUseFrom(requestedLocales) { - let supportedLocales = _dataLocales; - let toUse = []; - for (let i2 in requestedLocales) { - let locale2 = requestedLocales[i2]; - if (supportedLocales[locale2]) - toUse.push(locale2); - if (locale2.includes("-")) { - let langPart = locale2.split("-")[0]; - if (supportedLocales[langPart]) - toUse.push(langPart); - } - } - return utilArrayUniq(toUse); + // modules/util/detect.js + var _detected; + function utilDetect(refresh2) { + if (_detected && !refresh2) + return _detected; + _detected = {}; + const ua = navigator.userAgent; + let m = null; + m = ua.match(/(edge)\/?\s*(\.?\d+(\.\d+)*)/i); + if (m !== null) { + _detected.browser = m[1]; + _detected.version = m[2]; } - function updateForCurrentLocale() { - if (!_localeCode) - return; - _languageCode = _localeCode.split("-")[0]; - const currentData = _dataLocales[_localeCode] || _dataLocales[_languageCode]; - const hash = utilStringQs(window.location.hash); - if (hash.rtl === "true") { - _textDirection = "rtl"; - } else if (hash.rtl === "false") { - _textDirection = "ltr"; - } else { - _textDirection = currentData && currentData.rtl ? "rtl" : "ltr"; + if (!_detected.browser) { + m = ua.match(/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/i); + if (m !== null) { + _detected.browser = "msie"; + _detected.version = m[1]; } - let locale2 = _localeCode; - if (locale2.toLowerCase() === "en-us") - locale2 = "en"; - _languageNames = _localeStrings.general[locale2].languageNames; - _scriptNames = _localeStrings.general[locale2].scriptNames; - _usesMetric = _localeCode.slice(-3).toLowerCase() !== "-us"; } - localizer.loadLocale = (locale2, scopeId, directory) => { - if (locale2.toLowerCase() === "en-us") - locale2 = "en"; - if (_localeStrings[scopeId] && _localeStrings[scopeId][locale2]) { - return Promise.resolve(locale2); - } - let fileMap = _mainFileFetcher.fileMap(); - const key = `locale_${scopeId}_${locale2}`; - if (!fileMap[key]) { - fileMap[key] = `${directory}/${locale2}.min.json`; - } - return _mainFileFetcher.get(key).then((d) => { - if (!_localeStrings[scopeId]) - _localeStrings[scopeId] = {}; - _localeStrings[scopeId][locale2] = d[locale2]; - return locale2; - }); - }; - localizer.pluralRule = function(number3) { - return pluralRule(number3, _localeCode); - }; - function pluralRule(number3, localeCode) { - const rules = "Intl" in window && Intl.PluralRules && new Intl.PluralRules(localeCode); - if (rules) { - return rules.select(number3); + if (!_detected.browser) { + m = ua.match(/(opr)\/?\s*(\.?\d+(\.\d+)*)/i); + if (m !== null) { + _detected.browser = "Opera"; + _detected.version = m[2]; } - if (number3 === 1) - return "one"; - return "other"; } - localizer.tInfo = function(origStringId, replacements, locale2) { - let stringId = origStringId.trim(); - let scopeId = "general"; - if (stringId[0] === "_") { - let split = stringId.split("."); - scopeId = split[0].slice(1); - stringId = split.slice(1).join("."); - } - locale2 = locale2 || _localeCode; - let path = stringId.split(".").map((s) => s.replace(//g, ".")).reverse(); - let stringsKey = locale2; - if (stringsKey.toLowerCase() === "en-us") - stringsKey = "en"; - let result = _localeStrings && _localeStrings[scopeId] && _localeStrings[scopeId][stringsKey]; - while (result !== void 0 && path.length) { - result = result[path.pop()]; + if (!_detected.browser) { + m = ua.match(/(opera|chrome|safari|firefox|msie)\/?\s*(\.?\d+(\.\d+)*)/i); + if (m !== null) { + _detected.browser = m[1]; + _detected.version = m[2]; + m = ua.match(/version\/([\.\d]+)/i); + if (m !== null) + _detected.version = m[1]; } - if (result !== void 0) { - if (replacements) { - if (typeof result === "object" && Object.keys(result).length) { - const number3 = Object.values(replacements).find(function(value) { - return typeof value === "number"; - }); - if (number3 !== void 0) { - const rule = pluralRule(number3, locale2); - if (result[rule]) { - result = result[rule]; - } else { - result = Object.values(result)[0]; - } - } - } - if (typeof result === "string") { - for (let key in replacements) { - let value = replacements[key]; - if (typeof value === "number") { - if (value.toLocaleString) { - value = value.toLocaleString(locale2, { - style: "decimal", - useGrouping: true, - minimumFractionDigits: 0 - }); - } else { - value = value.toString(); - } - } - const token = `{${key}}`; - const regex = new RegExp(token, "g"); - result = result.replace(regex, value); - } - } - } - if (typeof result === "string") { - return { - text: result, - locale: locale2 - }; - } + } + if (!_detected.browser) { + _detected.browser = navigator.appName; + _detected.version = navigator.appVersion; + } + _detected.version = _detected.version.split(/\W/).slice(0, 2).join("."); + _detected.opera = _detected.browser.toLowerCase() === "opera" && Number(_detected.version) < 15; + if (_detected.browser.toLowerCase() === "msie") { + _detected.ie = true; + _detected.browser = "Internet Explorer"; + _detected.support = false; + } else { + _detected.ie = false; + _detected.support = true; + } + _detected.filedrop = window.FileReader && "ondrop" in window; + if (/Win/.test(ua)) { + _detected.os = "win"; + _detected.platform = "Windows"; + } else if (/Mac/.test(ua)) { + _detected.os = "mac"; + _detected.platform = "Macintosh"; + } else if (/X11/.test(ua) || /Linux/.test(ua)) { + _detected.os = "linux"; + _detected.platform = "Linux"; + } else { + _detected.os = "win"; + _detected.platform = "Unknown"; + } + _detected.isMobileWebKit = (/\b(iPad|iPhone|iPod)\b/.test(ua) || // HACK: iPadOS 13+ requests desktop sites by default by using a Mac user agent, + // so assume any "mac" with multitouch is actually iOS + navigator.platform === "MacIntel" && "maxTouchPoints" in navigator && navigator.maxTouchPoints > 1) && /WebKit/.test(ua) && !/Edge/.test(ua) && !window.MSStream; + _detected.browserLocales = Array.from(new Set( + // remove duplicates + [navigator.language].concat(navigator.languages || []).concat([ + // old property for backwards compatibility + navigator.userLanguage + ]).filter(Boolean) + )); + const loc = window.top.location; + let origin = loc.origin; + if (!origin) { + origin = loc.protocol + "//" + loc.hostname + (loc.port ? ":" + loc.port : ""); + } + _detected.host = origin + loc.pathname; + return _detected; + } + + // modules/util/aes.js + var import_aes_js = __toESM(require_aes_js()); + var DEFAULT_128 = [250, 157, 60, 79, 142, 134, 229, 129, 138, 126, 210, 129, 29, 71, 160, 208]; + function utilAesEncrypt(text2, key) { + key = key || DEFAULT_128; + const textBytes = import_aes_js.default.utils.utf8.toBytes(text2); + const aesCtr = new import_aes_js.default.ModeOfOperation.ctr(key); + const encryptedBytes = aesCtr.encrypt(textBytes); + const encryptedHex = import_aes_js.default.utils.hex.fromBytes(encryptedBytes); + return encryptedHex; + } + function utilAesDecrypt(encryptedHex, key) { + key = key || DEFAULT_128; + const encryptedBytes = import_aes_js.default.utils.hex.toBytes(encryptedHex); + const aesCtr = new import_aes_js.default.ModeOfOperation.ctr(key); + const decryptedBytes = aesCtr.decrypt(encryptedBytes); + const text2 = import_aes_js.default.utils.utf8.fromBytes(decryptedBytes); + return text2; + } + + // modules/util/clean_tags.js + function utilCleanTags(tags) { + var out = {}; + for (var k in tags) { + if (!k) + continue; + var v = tags[k]; + if (v !== void 0) { + out[k] = cleanValue(k, v); } - let index = _localeCodes.indexOf(locale2); - if (index >= 0 && index < _localeCodes.length - 1) { - let fallback = _localeCodes[index + 1]; - return localizer.tInfo(origStringId, replacements, fallback); + } + return out; + function cleanValue(k2, v2) { + function keepSpaces(k3) { + return /_hours|_times|:conditional$/.test(k3); } - if (replacements && "default" in replacements) { - return { - text: replacements.default, - locale: null - }; + function skip(k3) { + return /^(description|note|fixme)$/.test(k3); } - const missing = `Missing ${locale2} translation: ${origStringId}`; - if (typeof console !== "undefined") - console.error(missing); - return { - text: missing, - locale: "en" - }; - }; - localizer.hasTextForStringId = function(stringId) { - return !!localizer.tInfo(stringId, { default: "nothing found" }).locale; - }; - localizer.t = function(stringId, replacements, locale2) { - return localizer.tInfo(stringId, replacements, locale2).text; - }; - localizer.t.html = function(stringId, replacements, locale2) { - replacements = Object.assign({}, replacements); - for (var k in replacements) { - if (typeof replacements[k] === "string") { - replacements[k] = escape_default(replacements[k]); - } - if (typeof replacements[k] === "object" && typeof replacements[k].html === "string") { - replacements[k] = replacements[k].html; - } + if (skip(k2)) + return v2; + var cleaned = v2.split(";").map(function(s) { + return s.trim(); + }).join(keepSpaces(k2) ? "; " : ";"); + if (k2.indexOf("website") !== -1 || k2.indexOf("email") !== -1 || cleaned.indexOf("http") === 0) { + cleaned = cleaned.replace(/[\u200B-\u200F\uFEFF]/g, ""); } - const info = localizer.tInfo(stringId, replacements, locale2); - if (info.text) { - return `${info.text}`; - } else { - return ""; + return cleaned; + } + } + + // modules/util/get_set_value.js + function utilGetSetValue(selection2, value, shouldUpdate) { + function setValue(value2, shouldUpdate2) { + function valueNull() { + delete this.value; } - }; - localizer.t.append = function(stringId, replacements, locale2) { - const ret = function(selection2) { - const info = localizer.tInfo(stringId, replacements, locale2); - return selection2.append("span").attr("class", "localized-text").attr("lang", info.locale || "und").text((replacements && replacements.prefix || "") + info.text + (replacements && replacements.suffix || "")); - }; - ret.stringId = stringId; - return ret; - }; - localizer.languageName = (code, options2) => { - if (_languageNames[code]) { - return _languageNames[code]; + function valueConstant() { + if (shouldUpdate2(this.value, value2)) { + this.value = value2; + } } - if (options2 && options2.localOnly) - return null; - const langInfo = _dataLanguages[code]; - if (langInfo) { - if (langInfo.nativeName) { - return localizer.t("translate.language_and_code", { language: langInfo.nativeName, code }); - } else if (langInfo.base && langInfo.script) { - const base = langInfo.base; - if (_languageNames[base]) { - const scriptCode = langInfo.script; - const script = _scriptNames[scriptCode] || scriptCode; - return localizer.t("translate.language_and_code", { language: _languageNames[base], code: script }); - } else if (_dataLanguages[base] && _dataLanguages[base].nativeName) { - return localizer.t("translate.language_and_code", { language: _dataLanguages[base].nativeName, code }); - } + function valueFunction() { + var x = value2.apply(this, arguments); + if (x === null || x === void 0) { + delete this.value; + } else if (shouldUpdate2(this.value, x)) { + this.value = x; } } - return code; - }; - return localizer; + return value2 === null || value2 === void 0 ? valueNull : typeof value2 === "function" ? valueFunction : valueConstant; + } + function stickyCursor(func) { + const supportedTypes = ["text", "search", "url", "tel", "password"]; + return function() { + if (!supportedTypes.includes(this.type)) { + return; + } + const cursor = { start: this.selectionStart, end: this.selectionEnd }; + func.apply(this, arguments); + this.setSelectionRange(cursor.start, cursor.end); + }; + } + if (arguments.length === 1) { + return selection2.property("value"); + } + if (shouldUpdate === void 0) { + shouldUpdate = (a, b) => a !== b; + } + return selection2.each(stickyCursor(setValue(value, shouldUpdate))); } - // modules/presets/collection.js - function presetCollection(collection) { - const MAXRESULTS = 50; - let _this = {}; - let _memo = {}; - _this.collection = collection; - _this.item = (id2) => { - if (_memo[id2]) - return _memo[id2]; - const found = _this.collection.find((d) => d.id === id2); - if (found) - _memo[id2] = found; - return found; - }; - _this.index = (id2) => _this.collection.findIndex((d) => d.id === id2); - _this.matchGeometry = (geometry) => { - return presetCollection( - _this.collection.filter((d) => d.matchGeometry(geometry)) - ); - }; - _this.matchAllGeometry = (geometries) => { - return presetCollection( - _this.collection.filter((d) => d && d.matchAllGeometry(geometries)) - ); - }; - _this.matchAnyGeometry = (geometries) => { - return presetCollection( - _this.collection.filter((d) => geometries.some((geom) => d.matchGeometry(geom))) - ); - }; - _this.fallback = (geometry) => { - let id2 = geometry; - if (id2 === "vertex") - id2 = "point"; - return _this.item(id2); - }; - _this.search = (value, geometry, loc) => { - if (!value) - return _this; - value = value.toLowerCase().trim(); - function leading(a) { - const index = a.indexOf(value); - return index === 0 || a[index - 1] === " "; - } - function leadingStrict(a) { - const index = a.indexOf(value); - return index === 0; - } - function sortPresets(nameProp, aliasesProp) { - return function sortNames(a, b) { - let aCompare = a[nameProp](); - let bCompare = b[nameProp](); - if (aliasesProp) { - const findMatchingAlias = (strings) => { - if (strings.some((s) => s === value)) { - return strings.find((s) => s === value); - } else { - return strings.find((s) => s.includes(value)); - } - }; - aCompare = findMatchingAlias([aCompare].concat(a[aliasesProp]())); - bCompare = findMatchingAlias([bCompare].concat(b[aliasesProp]())); - } - if (value === aCompare) - return -1; - if (value === bCompare) - return 1; - let i2 = b.originalScore - a.originalScore; - if (i2 !== 0) - return i2; - i2 = aCompare.indexOf(value) - bCompare.indexOf(value); - if (i2 !== 0) - return i2; - return aCompare.length - bCompare.length; - }; - } - let pool = _this.collection; - if (Array.isArray(loc)) { - const validLocations = _mainLocations.locationsAt(loc); - pool = pool.filter((a) => !a.locationSetID || validLocations[a.locationSetID]); - } - const searchable = pool.filter((a) => a.searchable !== false && a.suggestion !== true); - const suggestions = pool.filter((a) => a.suggestion === true); - const leadingNames = searchable.filter((a) => leading(a.searchName()) || a.searchAliases().some(leading)).sort(sortPresets("searchName", "searchAliases")); - const leadingSuggestions = suggestions.filter((a) => leadingStrict(a.searchName())).sort(sortPresets("searchName")); - const leadingNamesStripped = searchable.filter((a) => leading(a.searchNameStripped()) || a.searchAliasesStripped().some(leading)).sort(sortPresets("searchNameStripped", "searchAliasesStripped")); - const leadingSuggestionsStripped = suggestions.filter((a) => leadingStrict(a.searchNameStripped())).sort(sortPresets("searchNameStripped")); - const leadingTerms = searchable.filter((a) => (a.terms() || []).some(leading)); - const leadingSuggestionTerms = suggestions.filter((a) => (a.terms() || []).some(leading)); - const leadingTagValues = searchable.filter((a) => Object.values(a.tags || {}).filter((val) => val !== "*").some(leading)); - const similarName = searchable.map((a) => ({ preset: a, dist: utilEditDistance(value, a.searchName()) })).filter((a) => a.dist + Math.min(value.length - a.preset.searchName().length, 0) < 3).sort((a, b) => a.dist - b.dist).map((a) => a.preset); - const similarSuggestions = suggestions.map((a) => ({ preset: a, dist: utilEditDistance(value, a.searchName()) })).filter((a) => a.dist + Math.min(value.length - a.preset.searchName().length, 0) < 1).sort((a, b) => a.dist - b.dist).map((a) => a.preset); - const similarTerms = searchable.filter((a) => { - return (a.terms() || []).some((b) => { - return utilEditDistance(value, b) + Math.min(value.length - b.length, 0) < 3; - }); + // modules/util/keybinding.js + function utilKeybinding(namespace) { + var _keybindings = {}; + function testBindings(d3_event, isCapturing) { + var didMatch = false; + var bindings = Object.keys(_keybindings).map(function(id2) { + return _keybindings[id2]; }); - let leadingTagKeyValues = []; - if (value.includes("=")) { - leadingTagKeyValues = searchable.filter((a) => a.tags && Object.keys(a.tags).some((key) => key + "=" + a.tags[key] === value)).concat(searchable.filter((a) => a.tags && Object.keys(a.tags).some((key) => leading(key + "=" + a.tags[key])))); + var i2, binding; + for (i2 = 0; i2 < bindings.length; i2++) { + binding = bindings[i2]; + if (!binding.event.modifiers.shiftKey) + continue; + if (!!binding.capture !== isCapturing) + continue; + if (matches(d3_event, binding, true)) { + binding.callback(d3_event); + didMatch = true; + break; + } } - let results = leadingNames.concat( - leadingSuggestions, - leadingNamesStripped, - leadingSuggestionsStripped, - leadingTerms, - leadingSuggestionTerms, - leadingTagValues, - similarName, - similarSuggestions, - similarTerms, - leadingTagKeyValues - ).slice(0, MAXRESULTS - 1); - if (geometry) { - if (typeof geometry === "string") { - results.push(_this.fallback(geometry)); - } else { - geometry.forEach((geom) => results.push(_this.fallback(geom))); + if (didMatch) + return; + for (i2 = 0; i2 < bindings.length; i2++) { + binding = bindings[i2]; + if (binding.event.modifiers.shiftKey) + continue; + if (!!binding.capture !== isCapturing) + continue; + if (matches(d3_event, binding, false)) { + binding.callback(d3_event); + break; } } - return presetCollection(utilArrayUniq(results)); - }; - return _this; - } - - // modules/presets/category.js - function presetCategory(categoryID, category, allPresets) { - let _this = Object.assign({}, category); - let _searchName; - let _searchNameStripped; - _this.id = categoryID; - _this.members = presetCollection( - (category.members || []).map((presetID) => allPresets[presetID]).filter(Boolean) - ); - _this.geometry = _this.members.collection.reduce((acc, preset) => { - for (let i2 in preset.geometry) { - const geometry = preset.geometry[i2]; - if (acc.indexOf(geometry) === -1) { - acc.push(geometry); + function matches(d3_event2, binding2, testShift) { + var event = d3_event2; + var isMatch = false; + var tryKeyCode = true; + if (event.key !== void 0) { + tryKeyCode = event.key.charCodeAt(0) > 127; + isMatch = true; + if (binding2.event.key === void 0) { + isMatch = false; + } else if (Array.isArray(binding2.event.key)) { + if (binding2.event.key.map(function(s) { + return s.toLowerCase(); + }).indexOf(event.key.toLowerCase()) === -1) { + isMatch = false; + } + } else { + if (event.key.toLowerCase() !== binding2.event.key.toLowerCase()) { + isMatch = false; + } + } + } + if (!isMatch && (tryKeyCode || binding2.event.modifiers.altKey)) { + isMatch = event.keyCode === binding2.event.keyCode; + } + if (!isMatch) + return false; + if (!(event.ctrlKey && event.altKey)) { + if (event.ctrlKey !== binding2.event.modifiers.ctrlKey) + return false; + if (event.altKey !== binding2.event.modifiers.altKey) + return false; } + if (event.metaKey !== binding2.event.modifiers.metaKey) + return false; + if (testShift && event.shiftKey !== binding2.event.modifiers.shiftKey) + return false; + return true; } - return acc; - }, []); - _this.matchGeometry = (geom) => _this.geometry.indexOf(geom) >= 0; - _this.matchAllGeometry = (geometries) => _this.members.collection.some((preset) => preset.matchAllGeometry(geometries)); - _this.matchScore = () => -1; - _this.name = () => _t(`_tagging.presets.categories.${categoryID}.name`, { "default": categoryID }); - _this.nameLabel = () => _t.append(`_tagging.presets.categories.${categoryID}.name`, { "default": categoryID }); - _this.terms = () => []; - _this.searchName = () => { - if (!_searchName) { - _searchName = (_this.suggestion ? _this.originalName : _this.name()).toLowerCase(); + } + function capture(d3_event) { + testBindings(d3_event, true); + } + function bubble(d3_event) { + var tagName = select_default2(d3_event.target).node().tagName; + if (tagName === "INPUT" || tagName === "SELECT" || tagName === "TEXTAREA") { + return; } - return _searchName; + testBindings(d3_event, false); + } + function keybinding(selection2) { + selection2 = selection2 || select_default2(document); + selection2.on("keydown.capture." + namespace, capture, true); + selection2.on("keydown.bubble." + namespace, bubble, false); + return keybinding; + } + keybinding.unbind = function(selection2) { + _keybindings = []; + selection2 = selection2 || select_default2(document); + selection2.on("keydown.capture." + namespace, null); + selection2.on("keydown.bubble." + namespace, null); + return keybinding; }; - _this.searchNameStripped = () => { - if (!_searchNameStripped) { - _searchNameStripped = _this.searchName(); - if (_searchNameStripped.normalize) - _searchNameStripped = _searchNameStripped.normalize("NFD"); - _searchNameStripped = _searchNameStripped.replace(/[\u0300-\u036f]/g, ""); + keybinding.clear = function() { + _keybindings = {}; + return keybinding; + }; + keybinding.off = function(codes, capture2) { + var arr = utilArrayUniq([].concat(codes)); + for (var i2 = 0; i2 < arr.length; i2++) { + var id2 = arr[i2] + (capture2 ? "-capture" : "-bubble"); + delete _keybindings[id2]; } - return _searchNameStripped; + return keybinding; }; - _this.searchAliases = () => []; - _this.searchAliasesStripped = () => []; - return _this; - } - - // modules/presets/field.js - function presetField(fieldID, field) { - let _this = Object.assign({}, field); - _this.id = fieldID; - _this.safeid = utilSafeClassName(fieldID); - _this.matchGeometry = (geom) => !_this.geometry || _this.geometry.indexOf(geom) !== -1; - _this.matchAllGeometry = (geometries) => { - return !_this.geometry || geometries.every((geom) => _this.geometry.indexOf(geom) !== -1); + keybinding.on = function(codes, callback, capture2) { + if (typeof callback !== "function") { + return keybinding.off(codes, capture2); + } + var arr = utilArrayUniq([].concat(codes)); + for (var i2 = 0; i2 < arr.length; i2++) { + var id2 = arr[i2] + (capture2 ? "-capture" : "-bubble"); + var binding = { + id: id2, + capture: capture2, + callback, + event: { + key: void 0, + // preferred + keyCode: 0, + // fallback + modifiers: { + shiftKey: false, + ctrlKey: false, + altKey: false, + metaKey: false + } + } + }; + if (_keybindings[id2]) { + console.warn('warning: duplicate keybinding for "' + id2 + '"'); + } + _keybindings[id2] = binding; + var matches = arr[i2].toLowerCase().match(/(?:(?:[^+⇧⌃⌥⌘])+|[⇧⌃⌥⌘]|\+\+|^\+$)/g); + for (var j2 = 0; j2 < matches.length; j2++) { + if (matches[j2] === "++") + matches[j2] = "+"; + if (matches[j2] in utilKeybinding.modifierCodes) { + var prop = utilKeybinding.modifierProperties[utilKeybinding.modifierCodes[matches[j2]]]; + binding.event.modifiers[prop] = true; + } else { + binding.event.key = utilKeybinding.keys[matches[j2]] || matches[j2]; + if (matches[j2] in utilKeybinding.keyCodes) { + binding.event.keyCode = utilKeybinding.keyCodes[matches[j2]]; + } + } + } + } + return keybinding; }; - _this.t = (scope, options2) => _t(`_tagging.presets.fields.${fieldID}.${scope}`, options2); - _this.t.html = (scope, options2) => _t.html(`_tagging.presets.fields.${fieldID}.${scope}`, options2); - _this.t.append = (scope, options2) => _t.append(`_tagging.presets.fields.${fieldID}.${scope}`, options2); - _this.hasTextForStringId = (scope) => _mainLocalizer.hasTextForStringId(`_tagging.presets.fields.${fieldID}.${scope}`); - _this.title = () => _this.overrideLabel || _this.t("label", { "default": fieldID }); - _this.label = () => _this.overrideLabel ? (selection2) => selection2.text(_this.overrideLabel) : _this.t.append("label", { "default": fieldID }); - const _placeholder = _this.placeholder; - _this.placeholder = () => _this.t("placeholder", { "default": _placeholder }); - _this.originalTerms = (_this.terms || []).join(); - _this.terms = () => _this.t("terms", { "default": _this.originalTerms }).toLowerCase().trim().split(/\s*,+\s*/); - _this.increment = _this.type === "number" ? _this.increment || 1 : void 0; - return _this; + return keybinding; } - - // modules/presets/preset.js - function presetPreset(presetID, preset, addable, allFields, allPresets) { - allFields = allFields || {}; - allPresets = allPresets || {}; - let _this = Object.assign({}, preset); - let _addable = addable || false; - let _resolvedFields; - let _resolvedMoreFields; - let _searchName; - let _searchNameStripped; - let _searchAliases; - let _searchAliasesStripped; - _this.id = presetID; - _this.safeid = utilSafeClassName(presetID); - _this.originalTerms = (_this.terms || []).join(); - _this.originalName = _this.name || ""; - _this.originalAliases = (_this.aliases || []).join("\n"); - _this.originalScore = _this.matchScore || 1; - _this.originalReference = _this.reference || {}; - _this.originalFields = _this.fields || []; - _this.originalMoreFields = _this.moreFields || []; - _this.fields = () => _resolvedFields || (_resolvedFields = resolve("fields")); - _this.moreFields = () => _resolvedMoreFields || (_resolvedMoreFields = resolve("moreFields")); - _this.resetFields = () => _resolvedFields = _resolvedMoreFields = null; - _this.tags = _this.tags || {}; - _this.addTags = _this.addTags || _this.tags; - _this.removeTags = _this.removeTags || _this.addTags; - _this.geometry = _this.geometry || []; - _this.matchGeometry = (geom) => _this.geometry.indexOf(geom) >= 0; - _this.matchAllGeometry = (geoms) => geoms.every(_this.matchGeometry); - _this.matchScore = (entityTags) => { - const tags = _this.tags; - let seen = {}; - let score = 0; - for (let k in tags) { - seen[k] = true; - if (entityTags[k] === tags[k]) { - score += _this.originalScore; - } else if (tags[k] === "*" && k in entityTags) { - score += _this.originalScore / 2; - } else { - return -1; - } - } - const addTags = _this.addTags; - for (let k in addTags) { - if (!seen[k] && entityTags[k] === addTags[k]) { - score += _this.originalScore; - } - } - if (_this.searchable === false) { - score *= 0.999; + utilKeybinding.modifierCodes = { + // Shift key, ⇧ + "\u21E7": 16, + shift: 16, + // CTRL key, on Mac: ⌃ + "\u2303": 17, + ctrl: 17, + // ALT key, on Mac: ⌥ (Alt) + "\u2325": 18, + alt: 18, + option: 18, + // META, on Mac: ⌘ (CMD), on Windows (Win), on Linux (Super) + "\u2318": 91, + meta: 91, + cmd: 91, + "super": 91, + win: 91 + }; + utilKeybinding.modifierProperties = { + 16: "shiftKey", + 17: "ctrlKey", + 18: "altKey", + 91: "metaKey" + }; + utilKeybinding.plusKeys = ["plus", "ffplus", "=", "ffequals", "\u2260", "\xB1"]; + utilKeybinding.minusKeys = ["_", "-", "ffminus", "dash", "\u2013", "\u2014"]; + utilKeybinding.keys = { + // Backspace key, on Mac: ⌫ (Backspace) + "\u232B": "Backspace", + backspace: "Backspace", + // Tab Key, on Mac: ⇥ (Tab), on Windows ⇥⇥ + "\u21E5": "Tab", + "\u21C6": "Tab", + tab: "Tab", + // Return key, ↩ + "\u21A9": "Enter", + "\u21B5": "Enter", + "\u23CE": "Enter", + "return": "Enter", + enter: "Enter", + "\u2305": "Enter", + // Pause/Break key + "pause": "Pause", + "pause-break": "Pause", + // Caps Lock key, ⇪ + "\u21EA": "CapsLock", + caps: "CapsLock", + "caps-lock": "CapsLock", + // Escape key, on Mac: ⎋, on Windows: Esc + "\u238B": ["Escape", "Esc"], + escape: ["Escape", "Esc"], + esc: ["Escape", "Esc"], + // Space key + space: [" ", "Spacebar"], + // Page-Up key, or pgup, on Mac: ↖ + "\u2196": "PageUp", + pgup: "PageUp", + "page-up": "PageUp", + // Page-Down key, or pgdown, on Mac: ↘ + "\u2198": "PageDown", + pgdown: "PageDown", + "page-down": "PageDown", + // END key, on Mac: ⇟ + "\u21DF": "End", + end: "End", + // HOME key, on Mac: ⇞ + "\u21DE": "Home", + home: "Home", + // Insert key, or ins + ins: "Insert", + insert: "Insert", + // Delete key, on Mac: ⌦ (Delete) + "\u2326": ["Delete", "Del"], + del: ["Delete", "Del"], + "delete": ["Delete", "Del"], + // Left Arrow Key, or ← + "\u2190": ["ArrowLeft", "Left"], + left: ["ArrowLeft", "Left"], + "arrow-left": ["ArrowLeft", "Left"], + // Up Arrow Key, or ↑ + "\u2191": ["ArrowUp", "Up"], + up: ["ArrowUp", "Up"], + "arrow-up": ["ArrowUp", "Up"], + // Right Arrow Key, or → + "\u2192": ["ArrowRight", "Right"], + right: ["ArrowRight", "Right"], + "arrow-right": ["ArrowRight", "Right"], + // Up Arrow Key, or ↓ + "\u2193": ["ArrowDown", "Down"], + down: ["ArrowDown", "Down"], + "arrow-down": ["ArrowDown", "Down"], + // odities, stuff for backward compatibility (browsers and code): + // Num-Multiply, or * + "*": ["*", "Multiply"], + star: ["*", "Multiply"], + asterisk: ["*", "Multiply"], + multiply: ["*", "Multiply"], + // Num-Plus or + + "+": ["+", "Add"], + "plus": ["+", "Add"], + // Num-Subtract, or - + "-": ["-", "Subtract"], + subtract: ["-", "Subtract"], + "dash": ["-", "Subtract"], + // Semicolon + semicolon: ";", + // = or equals + equals: "=", + // Comma, or , + comma: ",", + // Period, or ., or full-stop + period: ".", + "full-stop": ".", + // Slash, or /, or forward-slash + slash: "/", + "forward-slash": "/", + // Tick, or `, or back-quote + tick: "`", + "back-quote": "`", + // Open bracket, or [ + "open-bracket": "[", + // Back slash, or \ + "back-slash": "\\", + // Close backet, or ] + "close-bracket": "]", + // Apostrophe, or Quote, or ' + quote: "'", + apostrophe: "'", + // NUMPAD 0-9 + "num-0": "0", + "num-1": "1", + "num-2": "2", + "num-3": "3", + "num-4": "4", + "num-5": "5", + "num-6": "6", + "num-7": "7", + "num-8": "8", + "num-9": "9", + // F1-F25 + f1: "F1", + f2: "F2", + f3: "F3", + f4: "F4", + f5: "F5", + f6: "F6", + f7: "F7", + f8: "F8", + f9: "F9", + f10: "F10", + f11: "F11", + f12: "F12", + f13: "F13", + f14: "F14", + f15: "F15", + f16: "F16", + f17: "F17", + f18: "F18", + f19: "F19", + f20: "F20", + f21: "F21", + f22: "F22", + f23: "F23", + f24: "F24", + f25: "F25" + }; + utilKeybinding.keyCodes = { + // Backspace key, on Mac: ⌫ (Backspace) + "\u232B": 8, + backspace: 8, + // Tab Key, on Mac: ⇥ (Tab), on Windows ⇥⇥ + "\u21E5": 9, + "\u21C6": 9, + tab: 9, + // Return key, ↩ + "\u21A9": 13, + "\u21B5": 13, + "\u23CE": 13, + "return": 13, + enter: 13, + "\u2305": 13, + // Pause/Break key + "pause": 19, + "pause-break": 19, + // Caps Lock key, ⇪ + "\u21EA": 20, + caps: 20, + "caps-lock": 20, + // Escape key, on Mac: ⎋, on Windows: Esc + "\u238B": 27, + escape: 27, + esc: 27, + // Space key + space: 32, + // Page-Up key, or pgup, on Mac: ↖ + "\u2196": 33, + pgup: 33, + "page-up": 33, + // Page-Down key, or pgdown, on Mac: ↘ + "\u2198": 34, + pgdown: 34, + "page-down": 34, + // END key, on Mac: ⇟ + "\u21DF": 35, + end: 35, + // HOME key, on Mac: ⇞ + "\u21DE": 36, + home: 36, + // Insert key, or ins + ins: 45, + insert: 45, + // Delete key, on Mac: ⌦ (Delete) + "\u2326": 46, + del: 46, + "delete": 46, + // Left Arrow Key, or ← + "\u2190": 37, + left: 37, + "arrow-left": 37, + // Up Arrow Key, or ↑ + "\u2191": 38, + up: 38, + "arrow-up": 38, + // Right Arrow Key, or → + "\u2192": 39, + right: 39, + "arrow-right": 39, + // Up Arrow Key, or ↓ + "\u2193": 40, + down: 40, + "arrow-down": 40, + // odities, printing characters that come out wrong: + // Firefox Equals + "ffequals": 61, + // Num-Multiply, or * + "*": 106, + star: 106, + asterisk: 106, + multiply: 106, + // Num-Plus or + + "+": 107, + "plus": 107, + // Num-Subtract, or - + "-": 109, + subtract: 109, + // Vertical Bar / Pipe + "|": 124, + // Firefox Plus + "ffplus": 171, + // Firefox Minus + "ffminus": 173, + // Semicolon + ";": 186, + semicolon: 186, + // = or equals + "=": 187, + "equals": 187, + // Comma, or , + ",": 188, + comma: 188, + // Dash / Underscore key + "dash": 189, + // Period, or ., or full-stop + ".": 190, + period: 190, + "full-stop": 190, + // Slash, or /, or forward-slash + "/": 191, + slash: 191, + "forward-slash": 191, + // Tick, or `, or back-quote + "`": 192, + tick: 192, + "back-quote": 192, + // Open bracket, or [ + "[": 219, + "open-bracket": 219, + // Back slash, or \ + "\\": 220, + "back-slash": 220, + // Close backet, or ] + "]": 221, + "close-bracket": 221, + // Apostrophe, or Quote, or ' + "'": 222, + quote: 222, + apostrophe: 222 + }; + var i = 95; + var n = 0; + while (++i < 106) { + utilKeybinding.keyCodes["num-" + n] = i; + ++n; + } + i = 47; + n = 0; + while (++i < 58) { + utilKeybinding.keyCodes[n] = i; + ++n; + } + i = 111; + n = 1; + while (++i < 136) { + utilKeybinding.keyCodes["f" + n] = i; + ++n; + } + i = 64; + while (++i < 91) { + utilKeybinding.keyCodes[String.fromCharCode(i).toLowerCase()] = i; + } + + // modules/util/object.js + function utilObjectOmit(obj, omitKeys) { + return Object.keys(obj).reduce(function(result, key) { + if (omitKeys.indexOf(key) === -1) { + result[key] = obj[key]; } - return score; + return result; + }, {}); + } + + // modules/util/rebind.js + function utilRebind(target, source) { + var i2 = 1, n2 = arguments.length, method; + while (++i2 < n2) { + target[method = arguments[i2]] = d3_rebind(target, source, source[method]); + } + return target; + } + function d3_rebind(target, source, method) { + return function() { + var value = method.apply(source, arguments); + return value === source ? target : value; }; - _this.t = (scope, options2) => { - const textID = `_tagging.presets.presets.${presetID}.${scope}`; - return _t(textID, options2); + } + + // modules/util/session_mutex.js + function utilSessionMutex(name) { + var mutex = {}; + var intervalID; + function renew() { + var expires = /* @__PURE__ */ new Date(); + expires.setSeconds(expires.getSeconds() + 5); + document.cookie = name + "=1; expires=" + expires.toUTCString() + "; sameSite=strict"; + } + 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, 4e3); + return true; }; - _this.t.append = (scope, options2) => { - const textID = `_tagging.presets.presets.${presetID}.${scope}`; - return _t.append(textID, options2); + mutex.unlock = function() { + if (!intervalID) + return; + document.cookie = name + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT; sameSite=strict"; + clearInterval(intervalID); + intervalID = null; }; - _this.name = () => { - return _this.t("name", { "default": _this.originalName }); + mutex.locked = function() { + return !!intervalID; }; - _this.nameLabel = () => _this.t.append("name", { "default": _this.originalName }); - _this.subtitle = () => { - if (_this.suggestion) { - let path = presetID.split("/"); - path.pop(); - return _t("_tagging.presets.presets." + path.join("/") + ".name"); + return mutex; + } + + // modules/util/tiler.js + function utilTiler() { + var _size = [256, 256]; + var _scale = 256; + var _tileSize = 256; + var _zoomExtent = [0, 20]; + var _translate = [_size[0] / 2, _size[1] / 2]; + var _margin = 0; + var _skipNullIsland = false; + function clamp3(num, min3, max3) { + return Math.max(min3, Math.min(num, max3)); + } + function nearNullIsland(tile) { + var x = tile[0]; + var y = tile[1]; + var z = tile[2]; + if (z >= 7) { + var center = Math.pow(2, z - 1); + var width = Math.pow(2, z - 6); + var min3 = center - width / 2; + var max3 = center + width / 2 - 1; + return x >= min3 && x <= max3 && y >= min3 && y <= max3; } - return null; - }; - _this.subtitleLabel = () => { - if (_this.suggestion) { - let path = presetID.split("/"); - path.pop(); - return _t.append("_tagging.presets.presets." + path.join("/") + ".name"); + return false; + } + function tiler8() { + var z = geoScaleToZoom(_scale / (2 * Math.PI), _tileSize); + var z0 = clamp3(Math.round(z), _zoomExtent[0], _zoomExtent[1]); + var tileMin = 0; + var tileMax = Math.pow(2, z0) - 1; + var log2ts = Math.log(_tileSize) * Math.LOG2E; + var k = Math.pow(2, z - z0 + log2ts); + var origin = [ + (_translate[0] - _scale / 2) / k, + (_translate[1] - _scale / 2) / k + ]; + var cols = range( + clamp3(Math.floor(-origin[0]) - _margin, tileMin, tileMax + 1), + clamp3(Math.ceil(_size[0] / k - origin[0]) + _margin, tileMin, tileMax + 1) + ); + var rows = range( + clamp3(Math.floor(-origin[1]) - _margin, tileMin, tileMax + 1), + clamp3(Math.ceil(_size[1] / k - origin[1]) + _margin, tileMin, tileMax + 1) + ); + var tiles = []; + for (var i2 = 0; i2 < rows.length; i2++) { + var y = rows[i2]; + for (var j2 = 0; j2 < cols.length; j2++) { + var x = cols[j2]; + if (i2 >= _margin && i2 <= rows.length - _margin && j2 >= _margin && j2 <= cols.length - _margin) { + tiles.unshift([x, y, z0]); + } else { + tiles.push([x, y, z0]); + } + } } - return null; + tiles.translate = origin; + tiles.scale = k; + return tiles; + } + tiler8.getTiles = function(projection2) { + var origin = [ + projection2.scale() * Math.PI - projection2.translate()[0], + projection2.scale() * Math.PI - projection2.translate()[1] + ]; + this.size(projection2.clipExtent()[1]).scale(projection2.scale() * 2 * Math.PI).translate(projection2.translate()); + var tiles = tiler8(); + var ts = tiles.scale; + return tiles.map(function(tile) { + if (_skipNullIsland && nearNullIsland(tile)) { + return false; + } + var x = tile[0] * ts - origin[0]; + var y = tile[1] * ts - origin[1]; + return { + id: tile.toString(), + xyz: tile, + extent: geoExtent( + projection2.invert([x, y + ts]), + projection2.invert([x + ts, y]) + ) + }; + }).filter(Boolean); }; - _this.aliases = () => { - return _this.t("aliases", { "default": _this.originalAliases }).trim().split(/\s*[\r\n]+\s*/); + tiler8.getGeoJSON = function(projection2) { + var features = tiler8.getTiles(projection2).map(function(tile) { + return { + type: "Feature", + properties: { + id: tile.id, + name: tile.id + }, + geometry: { + type: "Polygon", + coordinates: [tile.extent.polygon()] + } + }; + }); + return { + type: "FeatureCollection", + features + }; }; - _this.terms = () => _this.t("terms", { "default": _this.originalTerms }).toLowerCase().trim().split(/\s*,+\s*/); - _this.searchName = () => { - if (!_searchName) { - _searchName = (_this.suggestion ? _this.originalName : _this.name()).toLowerCase(); - } - return _searchName; + tiler8.tileSize = function(val) { + if (!arguments.length) + return _tileSize; + _tileSize = val; + return tiler8; }; - _this.searchNameStripped = () => { - if (!_searchNameStripped) { - _searchNameStripped = stripDiacritics(_this.searchName()); - } - return _searchNameStripped; + tiler8.zoomExtent = function(val) { + if (!arguments.length) + return _zoomExtent; + _zoomExtent = val; + return tiler8; }; - _this.searchAliases = () => { - if (!_searchAliases) { - _searchAliases = _this.aliases().map((alias) => alias.toLowerCase()); - } - return _searchAliases; + tiler8.size = function(val) { + if (!arguments.length) + return _size; + _size = val; + return tiler8; }; - _this.searchAliasesStripped = () => { - if (!_searchAliasesStripped) { - _searchAliasesStripped = _this.searchAliases(); - _searchAliasesStripped = _searchAliasesStripped.map(stripDiacritics); - } - return _searchAliasesStripped; + tiler8.scale = function(val) { + if (!arguments.length) + return _scale; + _scale = val; + return tiler8; }; - _this.isFallback = () => { - const tagCount = Object.keys(_this.tags).length; - return tagCount === 0 || tagCount === 1 && _this.tags.hasOwnProperty("area"); + tiler8.translate = function(val) { + if (!arguments.length) + return _translate; + _translate = val; + return tiler8; }; - _this.addable = function(val) { + tiler8.margin = function(val) { if (!arguments.length) - return _addable; - _addable = val; - return _this; + return _margin; + _margin = +val; + return tiler8; }; - _this.reference = () => { - const qid = _this.tags.wikidata || _this.tags["flag:wikidata"] || _this.tags["brand:wikidata"] || _this.tags["network:wikidata"] || _this.tags["operator:wikidata"]; - if (qid) { - return { qid }; - } - let key = _this.originalReference.key || Object.keys(utilObjectOmit(_this.tags, "name"))[0]; - let value = _this.originalReference.value || _this.tags[key]; - if (value === "*") { - return { key }; - } else { - return { key, value }; - } + tiler8.skipNullIsland = function(val) { + if (!arguments.length) + return _skipNullIsland; + _skipNullIsland = val; + return tiler8; }; - _this.unsetTags = (tags, geometry, ignoringKeys, skipFieldDefaults) => { - let removeTags = ignoringKeys ? utilObjectOmit(_this.removeTags, ignoringKeys) : _this.removeTags; - tags = utilObjectOmit(tags, Object.keys(removeTags)); - if (geometry && !skipFieldDefaults) { - _this.fields().forEach((field) => { - if (field.matchGeometry(geometry) && field.key && field.default === tags[field.key]) { - delete tags[field.key]; - } - }); + return tiler8; + } + + // modules/util/trigger_event.js + function utilTriggerEvent(target, type2) { + target.each(function() { + var evt = document.createEvent("HTMLEvents"); + evt.initEvent(type2, true, true); + this.dispatchEvent(evt); + }); + } + + // modules/core/localizer.js + var _mainLocalizer = coreLocalizer(); + var _t = _mainLocalizer.t; + function coreLocalizer() { + let localizer = {}; + let _dataLanguages = {}; + let _dataLocales = {}; + let _localeStrings = {}; + let _localeCode = "en-US"; + let _localeCodes = ["en-US", "en"]; + let _languageCode = "en"; + let _textDirection = "ltr"; + let _usesMetric = false; + let _languageNames = {}; + let _scriptNames = {}; + localizer.localeCode = () => _localeCode; + localizer.localeCodes = () => _localeCodes; + localizer.languageCode = () => _languageCode; + localizer.textDirection = () => _textDirection; + localizer.usesMetric = () => _usesMetric; + localizer.languageNames = () => _languageNames; + localizer.scriptNames = () => _scriptNames; + let _preferredLocaleCodes = []; + localizer.preferredLocaleCodes = function(codes) { + if (!arguments.length) + return _preferredLocaleCodes; + if (typeof codes === "string") { + _preferredLocaleCodes = codes.split(/,|;| /gi).filter(Boolean); + } else { + _preferredLocaleCodes = codes; } - delete tags.area; - return tags; + return localizer; }; - _this.setTags = (tags, geometry, skipFieldDefaults) => { - const addTags = _this.addTags; - tags = Object.assign({}, tags); - for (let k in addTags) { - if (addTags[k] === "*") { - if (_this.tags[k] || !tags[k]) { - tags[k] = "yes"; - } - } else { - tags[k] = addTags[k]; - } - } - if (!addTags.hasOwnProperty("area")) { - delete tags.area; - if (geometry === "area") { - let needsAreaTag = true; - for (let k in addTags) { - if (_this.geometry.indexOf("line") === -1 && k in osmAreaKeys || k in osmAreaKeysExceptions && addTags[k] in osmAreaKeysExceptions[k]) { - needsAreaTag = false; - break; - } - } - if (needsAreaTag) { - tags.area = "yes"; - } + var _loadPromise; + localizer.ensureLoaded = () => { + if (_loadPromise) + return _loadPromise; + let filesToFetch = [ + "languages", + // load the list of languages + "locales" + // load the list of supported locales + ]; + const localeDirs = { + general: "locales", + tagging: presetsCdnUrl + "dist/translations" + }; + let fileMap = _mainFileFetcher.fileMap(); + for (let scopeId in localeDirs) { + const key = `locales_index_${scopeId}`; + if (!fileMap[key]) { + fileMap[key] = localeDirs[scopeId] + "/index.min.json"; } + filesToFetch.push(key); } - if (geometry && !skipFieldDefaults) { - _this.fields().forEach((field) => { - if (field.matchGeometry(geometry) && field.key && !tags[field.key] && field.default) { - tags[field.key] = field.default; - } + return _loadPromise = Promise.all(filesToFetch.map((key) => _mainFileFetcher.get(key))).then((results) => { + _dataLanguages = results[0]; + _dataLocales = results[1]; + let indexes = results.slice(2); + let requestedLocales = (_preferredLocaleCodes || []).concat(utilDetect().browserLocales).concat(["en"]); + _localeCodes = localesToUseFrom(requestedLocales); + _localeCode = _localeCodes[0]; + let loadStringsPromises = []; + indexes.forEach((index, i2) => { + const fullCoverageIndex = _localeCodes.findIndex(function(locale2) { + return index[locale2] && index[locale2].pct === 1; + }); + _localeCodes.slice(0, fullCoverageIndex + 1).forEach(function(code) { + let scopeId = Object.keys(localeDirs)[i2]; + let directory = Object.values(localeDirs)[i2]; + if (index[code]) + loadStringsPromises.push(localizer.loadLocale(code, scopeId, directory)); + }); }); - } - return tags; + return Promise.all(loadStringsPromises); + }).then(() => { + updateForCurrentLocale(); + }).catch((err) => console.error(err)); }; - function resolve(which) { - const fieldIDs = which === "fields" ? _this.originalFields : _this.originalMoreFields; - let resolved = []; - fieldIDs.forEach((fieldID) => { - const match = fieldID.match(/\{(.*)\}/); - if (match !== null) { - resolved = resolved.concat(inheritFields(match[1], which)); - } else if (allFields[fieldID]) { - resolved.push(allFields[fieldID]); - } else { - console.log(`Cannot resolve "${fieldID}" found in ${_this.id}.${which}`); - } - }); - if (!resolved.length) { - const endIndex = _this.id.lastIndexOf("/"); - const parentID = endIndex && _this.id.substring(0, endIndex); - if (parentID) { - resolved = inheritFields(parentID, which); - } - } - return utilArrayUniq(resolved); - function inheritFields(presetID2, which2) { - const parent = allPresets[presetID2]; - if (!parent) - return []; - if (which2 === "fields") { - return parent.fields().filter(shouldInherit); - } else if (which2 === "moreFields") { - return parent.moreFields(); - } else { - return []; + function localesToUseFrom(requestedLocales) { + let supportedLocales = _dataLocales; + let toUse = []; + for (let i2 in requestedLocales) { + let locale2 = requestedLocales[i2]; + if (supportedLocales[locale2]) + toUse.push(locale2); + if (locale2.includes("-")) { + let langPart = locale2.split("-")[0]; + if (supportedLocales[langPart]) + toUse.push(langPart); } } - function shouldInherit(f2) { - if (f2.key && _this.tags[f2.key] !== void 0 && f2.type !== "multiCombo" && f2.type !== "semiCombo" && f2.type !== "manyCombo" && f2.type !== "check") - return false; - return true; - } + return utilArrayUniq(toUse); } - function stripDiacritics(s) { - if (s.normalize) - s = s.normalize("NFD"); - s = s.replace(/[\u0300-\u036f]/g, ""); - return s; + function updateForCurrentLocale() { + if (!_localeCode) + return; + _languageCode = _localeCode.split("-")[0]; + const currentData = _dataLocales[_localeCode] || _dataLocales[_languageCode]; + const hash = utilStringQs(window.location.hash); + if (hash.rtl === "true") { + _textDirection = "rtl"; + } else if (hash.rtl === "false") { + _textDirection = "ltr"; + } else { + _textDirection = currentData && currentData.rtl ? "rtl" : "ltr"; + } + let locale2 = _localeCode; + if (locale2.toLowerCase() === "en-us") + locale2 = "en"; + _languageNames = _localeStrings.general[locale2].languageNames || _localeStrings.general[_languageCode].languageNames; + _scriptNames = _localeStrings.general[locale2].scriptNames || _localeStrings.general[_languageCode].scriptNames; + _usesMetric = _localeCode.slice(-3).toLowerCase() !== "-us"; } - return _this; - } - - // modules/presets/index.js - var _mainPresetIndex = presetIndex(); - function presetIndex() { - const dispatch10 = dispatch_default("favoritePreset", "recentsChange"); - const MAXRECENTS = 30; - const POINT = presetPreset("point", { name: "Point", tags: {}, geometry: ["point", "vertex"], matchScore: 0.1 }); - const LINE = presetPreset("line", { name: "Line", tags: {}, geometry: ["line"], matchScore: 0.1 }); - const AREA = presetPreset("area", { name: "Area", tags: { area: "yes" }, geometry: ["area"], matchScore: 0.1 }); - const RELATION = presetPreset("relation", { name: "Relation", tags: {}, geometry: ["relation"], matchScore: 0.1 }); - let _this = presetCollection([POINT, LINE, AREA, RELATION]); - let _presets = { point: POINT, line: LINE, area: AREA, relation: RELATION }; - let _defaults = { - point: presetCollection([POINT]), - vertex: presetCollection([POINT]), - line: presetCollection([LINE]), - area: presetCollection([AREA]), - relation: presetCollection([RELATION]) - }; - let _fields = {}; - let _categories = {}; - let _universal = []; - let _addablePresetIDs = null; - let _recents; - let _favorites; - let _geometryIndex = { point: {}, vertex: {}, line: {}, area: {}, relation: {} }; - let _loadPromise; - _this.ensureLoaded = () => { - if (_loadPromise) - return _loadPromise; - return _loadPromise = Promise.all([ - _mainFileFetcher.get("preset_categories"), - _mainFileFetcher.get("preset_defaults"), - _mainFileFetcher.get("preset_presets"), - _mainFileFetcher.get("preset_fields") - ]).then((vals) => { - _this.merge({ - categories: vals[0], - defaults: vals[1], - presets: vals[2], - fields: vals[3] - }); - osmSetAreaKeys(_this.areaKeys()); - osmSetPointTags(_this.pointTags()); - osmSetVertexTags(_this.vertexTags()); + localizer.loadLocale = (locale2, scopeId, directory) => { + if (locale2.toLowerCase() === "en-us") + locale2 = "en"; + if (_localeStrings[scopeId] && _localeStrings[scopeId][locale2]) { + return Promise.resolve(locale2); + } + let fileMap = _mainFileFetcher.fileMap(); + const key = `locale_${scopeId}_${locale2}`; + if (!fileMap[key]) { + fileMap[key] = `${directory}/${locale2}.min.json`; + } + return _mainFileFetcher.get(key).then((d) => { + if (!_localeStrings[scopeId]) + _localeStrings[scopeId] = {}; + _localeStrings[scopeId][locale2] = d[locale2]; + return locale2; }); }; - _this.merge = (d) => { - let newLocationSets = []; - if (d.fields) { - Object.keys(d.fields).forEach((fieldID) => { - let f2 = d.fields[fieldID]; - if (f2) { - f2 = presetField(fieldID, f2); - if (f2.locationSet) - newLocationSets.push(f2); - _fields[fieldID] = f2; - } else { - delete _fields[fieldID]; - } - }); + localizer.pluralRule = function(number3) { + return pluralRule(number3, _localeCode); + }; + function pluralRule(number3, localeCode) { + const rules = "Intl" in window && Intl.PluralRules && new Intl.PluralRules(localeCode); + if (rules) { + return rules.select(number3); } - if (d.presets) { - Object.keys(d.presets).forEach((presetID) => { - let p = d.presets[presetID]; - if (p) { - const isAddable = !_addablePresetIDs || _addablePresetIDs.has(presetID); - p = presetPreset(presetID, p, isAddable, _fields, _presets); - if (p.locationSet) - newLocationSets.push(p); - _presets[presetID] = p; - } else { - const existing = _presets[presetID]; - if (existing && !existing.isFallback()) { - delete _presets[presetID]; - } - } - }); + if (number3 === 1) + return "one"; + return "other"; + } + localizer.tInfo = function(origStringId, replacements, locale2) { + let stringId = origStringId.trim(); + let scopeId = "general"; + if (stringId[0] === "_") { + let split = stringId.split("."); + scopeId = split[0].slice(1); + stringId = split.slice(1).join("."); } - if (d.categories) { - Object.keys(d.categories).forEach((categoryID) => { - let c = d.categories[categoryID]; - if (c) { - c = presetCategory(categoryID, c, _presets); - if (c.locationSet) - newLocationSets.push(c); - _categories[categoryID] = c; - } else { - delete _categories[categoryID]; - } - }); + locale2 = locale2 || _localeCode; + let path = stringId.split(".").map((s) => s.replace(//g, ".")).reverse(); + let stringsKey = locale2; + if (stringsKey.toLowerCase() === "en-us") + stringsKey = "en"; + let result = _localeStrings && _localeStrings[scopeId] && _localeStrings[scopeId][stringsKey]; + while (result !== void 0 && path.length) { + result = result[path.pop()]; } - _this.collection = Object.values(_presets).concat(Object.values(_categories)); - if (d.defaults) { - Object.keys(d.defaults).forEach((geometry) => { - const def = d.defaults[geometry]; - if (Array.isArray(def)) { - _defaults[geometry] = presetCollection( - def.map((id2) => _presets[id2] || _categories[id2]).filter(Boolean) - ); - } else { - delete _defaults[geometry]; + if (result !== void 0) { + if (replacements) { + if (typeof result === "object" && Object.keys(result).length) { + const number3 = Object.values(replacements).find(function(value) { + return typeof value === "number"; + }); + if (number3 !== void 0) { + const rule = pluralRule(number3, locale2); + if (result[rule]) { + result = result[rule]; + } else { + result = Object.values(result)[0]; + } + } } - }); - } - _universal = Object.values(_fields).filter((field) => field.universal); - Object.values(_presets).forEach((preset) => preset.resetFields()); - _geometryIndex = { point: {}, vertex: {}, line: {}, area: {}, relation: {} }; - _this.collection.forEach((preset) => { - (preset.geometry || []).forEach((geometry) => { - let g = _geometryIndex[geometry]; - for (let key in preset.tags) { - g[key] = g[key] || {}; - let value = preset.tags[key]; - (g[key][value] = g[key][value] || []).push(preset); + if (typeof result === "string") { + for (let key in replacements) { + let value = replacements[key]; + if (typeof value === "number") { + if (value.toLocaleString) { + value = value.toLocaleString(locale2, { + style: "decimal", + useGrouping: true, + minimumFractionDigits: 0 + }); + } else { + value = value.toString(); + } + } + const token = `{${key}}`; + const regex = new RegExp(token, "g"); + result = result.replace(regex, value); + } } - }); - }); - if (d.featureCollection && Array.isArray(d.featureCollection.features)) { - _mainLocations.mergeCustomGeoJSON(d.featureCollection); + } + if (typeof result === "string") { + return { + text: result, + locale: locale2 + }; + } } - if (newLocationSets.length) { - _mainLocations.mergeLocationSets(newLocationSets); + let index = _localeCodes.indexOf(locale2); + if (index >= 0 && index < _localeCodes.length - 1) { + let fallback = _localeCodes[index + 1]; + return localizer.tInfo(origStringId, replacements, fallback); } - return _this; + if (replacements && "default" in replacements) { + return { + text: replacements.default, + locale: null + }; + } + const missing = `Missing ${locale2} translation: ${origStringId}`; + if (typeof console !== "undefined") + console.error(missing); + return { + text: missing, + locale: "en" + }; }; - _this.match = (entity, resolver) => { - return resolver.transient(entity, "presetMatch", () => { - let geometry = entity.geometry(resolver); - if (geometry === "vertex" && entity.isOnAddressLine(resolver)) { - geometry = "point"; - } - const entityExtent = entity.extent(resolver); - return _this.matchTags(entity.tags, geometry, entityExtent.center()); - }); + localizer.hasTextForStringId = function(stringId) { + return !!localizer.tInfo(stringId, { default: "nothing found" }).locale; }; - _this.matchTags = (tags, geometry, loc) => { - const keyIndex = _geometryIndex[geometry]; - let bestScore = -1; - let bestMatch; - let matchCandidates = []; - for (let k in tags) { - let indexMatches = []; - let valueIndex = keyIndex[k]; - if (!valueIndex) - continue; - let keyValueMatches = valueIndex[tags[k]]; - if (keyValueMatches) - indexMatches.push(...keyValueMatches); - let keyStarMatches = valueIndex["*"]; - if (keyStarMatches) - indexMatches.push(...keyStarMatches); - if (indexMatches.length === 0) - continue; - for (let i2 = 0; i2 < indexMatches.length; i2++) { - const candidate = indexMatches[i2]; - const score = candidate.matchScore(tags); - if (score === -1) { - continue; - } - matchCandidates.push({ score, candidate }); - if (score > bestScore) { - bestScore = score; - bestMatch = candidate; - } + localizer.t = function(stringId, replacements, locale2) { + return localizer.tInfo(stringId, replacements, locale2).text; + }; + localizer.t.html = function(stringId, replacements, locale2) { + replacements = Object.assign({}, replacements); + for (var k in replacements) { + if (typeof replacements[k] === "string") { + replacements[k] = escape_default(replacements[k]); } - } - if (bestMatch && bestMatch.locationSetID && bestMatch.locationSetID !== "+[Q2]" && Array.isArray(loc)) { - let validLocations = _mainLocations.locationsAt(loc); - if (!validLocations[bestMatch.locationSetID]) { - matchCandidates.sort((a, b) => a.score < b.score ? 1 : -1); - for (let i2 = 0; i2 < matchCandidates.length; i2++) { - const candidateScore = matchCandidates[i2]; - if (!candidateScore.candidate.locationSetID || validLocations[candidateScore.candidate.locationSetID]) { - bestMatch = candidateScore.candidate; - bestScore = candidateScore.score; - break; - } - } + if (typeof replacements[k] === "object" && typeof replacements[k].html === "string") { + replacements[k] = replacements[k].html; } } - if (!bestMatch || bestMatch.isFallback()) { - for (let k in tags) { - if (/^addr:/.test(k) && keyIndex["addr:*"] && keyIndex["addr:*"]["*"]) { - bestMatch = keyIndex["addr:*"]["*"][0]; - break; + const info = localizer.tInfo(stringId, replacements, locale2); + if (info.text) { + return `${info.text}`; + } else { + return ""; + } + }; + localizer.t.append = function(stringId, replacements, locale2) { + const ret = function(selection2) { + const info = localizer.tInfo(stringId, replacements, locale2); + return selection2.append("span").attr("class", "localized-text").attr("lang", info.locale || "und").text((replacements && replacements.prefix || "") + info.text + (replacements && replacements.suffix || "")); + }; + ret.stringId = stringId; + return ret; + }; + localizer.languageName = (code, options2) => { + if (_languageNames && _languageNames[code]) { + return _languageNames[code]; + } + if (options2 && options2.localOnly) + return null; + const langInfo = _dataLanguages[code]; + if (langInfo) { + if (langInfo.nativeName) { + return localizer.t("translate.language_and_code", { language: langInfo.nativeName, code }); + } else if (langInfo.base && langInfo.script) { + const base = langInfo.base; + if (_languageNames && _languageNames[base]) { + const scriptCode = langInfo.script; + const script = _scriptNames && _scriptNames[scriptCode] || scriptCode; + return localizer.t("translate.language_and_code", { language: _languageNames[base], code: script }); + } else if (_dataLanguages[base] && _dataLanguages[base].nativeName) { + return localizer.t("translate.language_and_code", { language: _dataLanguages[base].nativeName, code }); } } } - return bestMatch || _this.fallback(geometry); + return code; }; - _this.allowsVertex = (entity, resolver) => { - if (entity.type !== "node") - return false; - if (Object.keys(entity.tags).length === 0) - return true; - return resolver.transient(entity, "vertexMatch", () => { - if (entity.isOnAddressLine(resolver)) - return true; - const geometries = osmNodeGeometriesForTags(entity.tags); - if (geometries.vertex) - return true; - if (geometries.point) - return false; - return true; - }); + localizer.floatFormatter = (locale2) => { + if (!("Intl" in window && "NumberFormat" in Intl && "formatToParts" in Intl.NumberFormat.prototype)) { + return (number3, fractionDigits) => { + return fractionDigits === void 0 ? number3.toString() : number3.toFixed(fractionDigits); + }; + } else { + return (number3, fractionDigits) => number3.toLocaleString(locale2, { + minimumFractionDigits: fractionDigits, + maximumFractionDigits: fractionDigits === void 0 ? 20 : fractionDigits + }); + } }; - _this.areaKeys = () => { - const ignore = { - barrier: true, - highway: true, - footway: true, - railway: true, - junction: true, - type: true + localizer.floatParser = (locale2) => { + const polyfill = (string) => +string.trim(); + if (!("Intl" in window && "NumberFormat" in Intl)) + return polyfill; + const format2 = new Intl.NumberFormat(locale2, { maximumFractionDigits: 20 }); + if (!("formatToParts" in format2)) + return polyfill; + const parts = format2.formatToParts(-12345.6); + const numerals = Array.from({ length: 10 }).map((_, i2) => format2.format(i2)); + const index = new Map(numerals.map((d, i2) => [d, i2])); + const literalPart = parts.find((d) => d.type === "literal"); + const literal = literalPart && new RegExp(`[${literalPart.value}]`, "g"); + const groupPart = parts.find((d) => d.type === "group"); + const group = groupPart && new RegExp(`[${groupPart.value}]`, "g"); + const decimalPart = parts.find((d) => d.type === "decimal"); + const decimal = decimalPart && new RegExp(`[${decimalPart.value}]`); + const numeral = new RegExp(`[${numerals.join("")}]`, "g"); + const getIndex = (d) => index.get(d); + return (string) => { + string = string.trim(); + if (literal) + string = string.replace(literal, ""); + if (group) + string = string.replace(group, ""); + if (decimal) + string = string.replace(decimal, "."); + string = string.replace(numeral, getIndex); + return string ? +string : NaN; }; - let areaKeys = {}; - const presets = _this.collection.filter((p) => !p.suggestion && !p.replacement); - presets.forEach((p) => { - const keys = p.tags && Object.keys(p.tags); - const key = keys && keys.length && keys[0]; - if (!key) - return; - if (ignore[key]) - return; - if (p.geometry.indexOf("area") !== -1) { - areaKeys[key] = areaKeys[key] || {}; - } - }); - presets.forEach((p) => { - let key; - for (key in p.addTags) { - const value = p.addTags[key]; - if (key in areaKeys && p.geometry.indexOf("line") !== -1 && value !== "*") { - areaKeys[key][value] = true; - } - } - }); - return areaKeys; }; - _this.pointTags = () => { - return _this.collection.reduce((pointTags, d) => { - if (d.suggestion || d.replacement || d.searchable === false) - return pointTags; - const keys = d.tags && Object.keys(d.tags); - const key = keys && keys.length && keys[0]; - if (!key) - return pointTags; - if (d.geometry.indexOf("point") !== -1) { - pointTags[key] = pointTags[key] || {}; - pointTags[key][d.tags[key]] = true; - } - return pointTags; - }, {}); + localizer.decimalPlaceCounter = (locale2) => { + var literal, group, decimal; + if ("Intl" in window && "NumberFormat" in Intl) { + const format2 = new Intl.NumberFormat(locale2, { maximumFractionDigits: 20 }); + if ("formatToParts" in format2) { + const parts = format2.formatToParts(-12345.6); + const literalPart = parts.find((d) => d.type === "literal"); + literal = literalPart && new RegExp(`[${literalPart.value}]`, "g"); + const groupPart = parts.find((d) => d.type === "group"); + group = groupPart && new RegExp(`[${groupPart.value}]`, "g"); + const decimalPart = parts.find((d) => d.type === "decimal"); + decimal = decimalPart && new RegExp(`[${decimalPart.value}]`); + } + } + return (string) => { + string = string.trim(); + if (literal) + string = string.replace(literal, ""); + if (group) + string = string.replace(group, ""); + const parts = string.split(decimal || "."); + return parts && parts[1] && parts[1].length || 0; + }; }; - _this.vertexTags = () => { - return _this.collection.reduce((vertexTags, d) => { - if (d.suggestion || d.replacement || d.searchable === false) - return vertexTags; - const keys = d.tags && Object.keys(d.tags); - const key = keys && keys.length && keys[0]; - if (!key) - return vertexTags; - if (d.geometry.indexOf("vertex") !== -1) { - vertexTags[key] = vertexTags[key] || {}; - vertexTags[key][d.tags[key]] = true; - } - return vertexTags; - }, {}); + return localizer; + } + + // modules/presets/collection.js + function presetCollection(collection) { + const MAXRESULTS = 50; + let _this = {}; + let _memo = {}; + _this.collection = collection; + _this.item = (id2) => { + if (_memo[id2]) + return _memo[id2]; + const found = _this.collection.find((d) => d.id === id2); + if (found) + _memo[id2] = found; + return found; }; - _this.field = (id2) => _fields[id2]; - _this.universal = () => _universal; - _this.defaults = (geometry, n2, startWithRecents, loc, extraPresets) => { - let recents = []; - if (startWithRecents) { - recents = _this.recent().matchGeometry(geometry).collection.slice(0, 4); - } - let defaults2; - if (_addablePresetIDs) { - defaults2 = Array.from(_addablePresetIDs).map(function(id2) { - var preset = _this.item(id2); - if (preset && preset.matchGeometry(geometry)) - return preset; - return null; - }).filter(Boolean); - } else { - defaults2 = _defaults[geometry].collection.concat(_this.fallback(geometry)); - } - let result = presetCollection( - utilArrayUniq(recents.concat(defaults2).concat(extraPresets || [])).slice(0, n2 - 1) + _this.index = (id2) => _this.collection.findIndex((d) => d.id === id2); + _this.matchGeometry = (geometry) => { + return presetCollection( + _this.collection.filter((d) => d.matchGeometry(geometry)) ); - if (Array.isArray(loc)) { - const validLocations = _mainLocations.locationsAt(loc); - result.collection = result.collection.filter((a) => !a.locationSetID || validLocations[a.locationSetID]); - } - return result; }; - _this.addablePresetIDs = function(val) { - if (!arguments.length) - return _addablePresetIDs; - if (Array.isArray(val)) - val = new Set(val); - _addablePresetIDs = val; - if (_addablePresetIDs) { - _this.collection.forEach((p) => { - if (p.addable) - p.addable(_addablePresetIDs.has(p.id)); - }); - } else { - _this.collection.forEach((p) => { - if (p.addable) - p.addable(true); - }); - } - return _this; + _this.matchAllGeometry = (geometries) => { + return presetCollection( + _this.collection.filter((d) => d && d.matchAllGeometry(geometries)) + ); }; - _this.recent = () => { + _this.matchAnyGeometry = (geometries) => { return presetCollection( - utilArrayUniq(_this.getRecents().map((d) => d.preset).filter((d) => d.searchable !== false)) + _this.collection.filter((d) => geometries.some((geom) => d.matchGeometry(geom))) ); }; - function RibbonItem(preset, source) { - let item = {}; - item.preset = preset; - item.source = source; - item.isFavorite = () => item.source === "favorite"; - item.isRecent = () => item.source === "recent"; - item.matches = (preset2) => item.preset.id === preset2.id; - item.minified = () => ({ pID: item.preset.id }); - return item; - } - function ribbonItemForMinified(d, source) { - if (d && d.pID) { - const preset = _this.item(d.pID); - if (!preset) - return null; - return RibbonItem(preset, source); + _this.fallback = (geometry) => { + let id2 = geometry; + if (id2 === "vertex") + id2 = "point"; + return _this.item(id2); + }; + _this.search = (value, geometry, loc) => { + if (!value) + return _this; + value = value.toLowerCase().trim(); + function leading(a) { + const index = a.indexOf(value); + return index === 0 || a[index - 1] === " "; } - return null; - } - _this.getGenericRibbonItems = () => { - return ["point", "line", "area"].map((id2) => RibbonItem(_this.item(id2), "generic")); + function leadingStrict(a) { + const index = a.indexOf(value); + return index === 0; + } + function sortPresets(nameProp, aliasesProp) { + return function sortNames(a, b) { + let aCompare = a[nameProp](); + let bCompare = b[nameProp](); + if (aliasesProp) { + const findMatchingAlias = (strings) => { + if (strings.some((s) => s === value)) { + return strings.find((s) => s === value); + } else { + return strings.filter((s) => s.includes(value)).sort((a2, b2) => a2.length - b2.length)[0]; + } + }; + aCompare = findMatchingAlias([aCompare].concat(a[aliasesProp]())); + bCompare = findMatchingAlias([bCompare].concat(b[aliasesProp]())); + } + if (value === aCompare) + return -1; + if (value === bCompare) + return 1; + let i2 = b.originalScore - a.originalScore; + if (i2 !== 0) + return i2; + i2 = aCompare.indexOf(value) - bCompare.indexOf(value); + if (i2 !== 0) + return i2; + return aCompare.length - bCompare.length; + }; + } + let pool = _this.collection; + if (Array.isArray(loc)) { + const validHere = _sharedLocationManager.locationSetsAt(loc); + pool = pool.filter((a) => !a.locationSetID || validHere[a.locationSetID]); + } + const searchable = pool.filter((a) => a.searchable !== false && a.suggestion !== true); + const suggestions = pool.filter((a) => a.suggestion === true); + const leadingNames = searchable.filter((a) => leading(a.searchName()) || a.searchAliases().some(leading)).sort(sortPresets("searchName", "searchAliases")); + const leadingSuggestions = suggestions.filter((a) => leadingStrict(a.searchName())).sort(sortPresets("searchName")); + const leadingNamesStripped = searchable.filter((a) => leading(a.searchNameStripped()) || a.searchAliasesStripped().some(leading)).sort(sortPresets("searchNameStripped", "searchAliasesStripped")); + const leadingSuggestionsStripped = suggestions.filter((a) => leadingStrict(a.searchNameStripped())).sort(sortPresets("searchNameStripped")); + const leadingTerms = searchable.filter((a) => (a.terms() || []).some(leading)); + const leadingSuggestionTerms = suggestions.filter((a) => (a.terms() || []).some(leading)); + const leadingTagValues = searchable.filter((a) => Object.values(a.tags || {}).filter((val) => val !== "*").some(leading)); + const similarName = searchable.map((a) => ({ preset: a, dist: utilEditDistance(value, a.searchName()) })).filter((a) => a.dist + Math.min(value.length - a.preset.searchName().length, 0) < 3).sort((a, b) => a.dist - b.dist).map((a) => a.preset); + const similarSuggestions = suggestions.map((a) => ({ preset: a, dist: utilEditDistance(value, a.searchName()) })).filter((a) => a.dist + Math.min(value.length - a.preset.searchName().length, 0) < 1).sort((a, b) => a.dist - b.dist).map((a) => a.preset); + const similarTerms = searchable.filter((a) => { + return (a.terms() || []).some((b) => { + return utilEditDistance(value, b) + Math.min(value.length - b.length, 0) < 3; + }); + }); + let leadingTagKeyValues = []; + if (value.includes("=")) { + leadingTagKeyValues = searchable.filter((a) => a.tags && Object.keys(a.tags).some((key) => key + "=" + a.tags[key] === value)).concat(searchable.filter((a) => a.tags && Object.keys(a.tags).some((key) => leading(key + "=" + a.tags[key])))); + } + let results = leadingNames.concat( + leadingSuggestions, + leadingNamesStripped, + leadingSuggestionsStripped, + leadingTerms, + leadingSuggestionTerms, + leadingTagValues, + similarName, + similarSuggestions, + similarTerms, + leadingTagKeyValues + ).slice(0, MAXRESULTS - 1); + if (geometry) { + if (typeof geometry === "string") { + results.push(_this.fallback(geometry)); + } else { + geometry.forEach((geom) => results.push(_this.fallback(geom))); + } + } + return presetCollection(utilArrayUniq(results)); }; - _this.getAddable = () => { - if (!_addablePresetIDs) - return []; - return _addablePresetIDs.map((id2) => { - const preset = _this.item(id2); - if (preset) - return RibbonItem(preset, "addable"); - return null; - }).filter(Boolean); + return _this; + } + + // modules/presets/category.js + function presetCategory(categoryID, category, allPresets) { + let _this = Object.assign({}, category); + let _searchName; + let _searchNameStripped; + _this.id = categoryID; + _this.members = presetCollection( + (category.members || []).map((presetID) => allPresets[presetID]).filter(Boolean) + ); + _this.geometry = _this.members.collection.reduce((acc, preset) => { + for (let i2 in preset.geometry) { + const geometry = preset.geometry[i2]; + if (acc.indexOf(geometry) === -1) { + acc.push(geometry); + } + } + return acc; + }, []); + _this.matchGeometry = (geom) => _this.geometry.indexOf(geom) >= 0; + _this.matchAllGeometry = (geometries) => _this.members.collection.some((preset) => preset.matchAllGeometry(geometries)); + _this.matchScore = () => -1; + _this.name = () => _t(`_tagging.presets.categories.${categoryID}.name`, { "default": categoryID }); + _this.nameLabel = () => _t.append(`_tagging.presets.categories.${categoryID}.name`, { "default": categoryID }); + _this.terms = () => []; + _this.searchName = () => { + if (!_searchName) { + _searchName = (_this.suggestion ? _this.originalName : _this.name()).toLowerCase(); + } + return _searchName; }; - function setRecents(items) { - _recents = items; - const minifiedItems = items.map((d) => d.minified()); - corePreferences("preset_recents", JSON.stringify(minifiedItems)); - dispatch10.call("recentsChange"); - } - _this.getRecents = () => { - if (!_recents) { - _recents = (JSON.parse(corePreferences("preset_recents")) || []).reduce((acc, d) => { - let item = ribbonItemForMinified(d, "recent"); - if (item && item.preset.addable()) - acc.push(item); - return acc; - }, []); + _this.searchNameStripped = () => { + if (!_searchNameStripped) { + _searchNameStripped = _this.searchName(); + if (_searchNameStripped.normalize) + _searchNameStripped = _searchNameStripped.normalize("NFD"); + _searchNameStripped = _searchNameStripped.replace(/[\u0300-\u036f]/g, ""); } - return _recents; + return _searchNameStripped; }; - _this.addRecent = (preset, besidePreset, after) => { - const recents = _this.getRecents(); - const beforeItem = _this.recentMatching(besidePreset); - let toIndex = recents.indexOf(beforeItem); - if (after) - toIndex += 1; - const newItem = RibbonItem(preset, "recent"); - recents.splice(toIndex, 0, newItem); - setRecents(recents); + _this.searchAliases = () => []; + _this.searchAliasesStripped = () => []; + return _this; + } + + // modules/presets/field.js + function presetField(fieldID, field, allFields) { + allFields = allFields || {}; + let _this = Object.assign({}, field); + _this.id = fieldID; + _this.safeid = utilSafeClassName(fieldID); + _this.matchGeometry = (geom) => !_this.geometry || _this.geometry.indexOf(geom) !== -1; + _this.matchAllGeometry = (geometries) => { + return !_this.geometry || geometries.every((geom) => _this.geometry.indexOf(geom) !== -1); }; - _this.removeRecent = (preset) => { - const item = _this.recentMatching(preset); - if (item) { - let items = _this.getRecents(); - items.splice(items.indexOf(item), 1); - setRecents(items); + _this.t = (scope, options2) => _t(`_tagging.presets.fields.${fieldID}.${scope}`, options2); + _this.t.html = (scope, options2) => _t.html(`_tagging.presets.fields.${fieldID}.${scope}`, options2); + _this.t.append = (scope, options2) => _t.append(`_tagging.presets.fields.${fieldID}.${scope}`, options2); + _this.hasTextForStringId = (scope) => _mainLocalizer.hasTextForStringId(`_tagging.presets.fields.${fieldID}.${scope}`); + _this.resolveReference = (which) => { + const referenceRegex = /^\{(.*)\}$/; + const match = (field[which] || "").match(referenceRegex); + if (match) { + const field2 = allFields[match[1]]; + if (field2) { + return field2; + } + console.error(`Unable to resolve referenced field: ${match[1]}`); } + return _this; }; - _this.recentMatching = (preset) => { - const items = _this.getRecents(); - for (let i2 in items) { - if (items[i2].matches(preset)) { - return items[i2]; + _this.title = () => _this.overrideLabel || _this.resolveReference("label").t("label", { "default": fieldID }); + _this.label = () => _this.overrideLabel ? (selection2) => selection2.text(_this.overrideLabel) : _this.resolveReference("label").t.append("label", { "default": fieldID }); + _this.placeholder = () => _this.resolveReference("placeholder").t("placeholder", { "default": "" }); + _this.originalTerms = (_this.terms || []).join(); + _this.terms = () => _this.resolveReference("label").t("terms", { "default": _this.originalTerms }).toLowerCase().trim().split(/\s*,+\s*/); + _this.increment = _this.type === "number" ? _this.increment || 1 : void 0; + return _this; + } + + // modules/presets/preset.js + var import_lodash = __toESM(require_lodash()); + function presetPreset(presetID, preset, addable, allFields, allPresets) { + allFields = allFields || {}; + allPresets = allPresets || {}; + let _this = Object.assign({}, preset); + let _addable = addable || false; + let _searchName; + let _searchNameStripped; + let _searchAliases; + let _searchAliasesStripped; + const referenceRegex = /^\{(.*)\}$/; + _this.id = presetID; + _this.safeid = utilSafeClassName(presetID); + _this.originalTerms = (_this.terms || []).join(); + _this.originalName = _this.name || ""; + _this.originalAliases = (_this.aliases || []).join("\n"); + _this.originalScore = _this.matchScore || 1; + _this.originalReference = _this.reference || {}; + _this.originalFields = _this.fields || []; + _this.originalMoreFields = _this.moreFields || []; + _this.fields = (loc) => resolveFields("fields", loc); + _this.moreFields = (loc) => resolveFields("moreFields", loc); + _this.tags = _this.tags || {}; + _this.addTags = _this.addTags || _this.tags; + _this.removeTags = _this.removeTags || _this.addTags; + _this.geometry = _this.geometry || []; + _this.matchGeometry = (geom) => _this.geometry.indexOf(geom) >= 0; + _this.matchAllGeometry = (geoms) => geoms.every(_this.matchGeometry); + _this.matchScore = (entityTags) => { + const tags = _this.tags; + let seen = {}; + let score = 0; + for (let k in tags) { + seen[k] = true; + if (entityTags[k] === tags[k]) { + score += _this.originalScore; + } else if (tags[k] === "*" && k in entityTags) { + score += _this.originalScore / 2; + } else { + return -1; } } - return null; + const addTags = _this.addTags; + for (let k in addTags) { + if (!seen[k] && entityTags[k] === addTags[k]) { + score += _this.originalScore; + } + } + if (_this.searchable === false) { + score *= 0.999; + } + return score; }; - _this.moveItem = (items, fromIndex, toIndex) => { - if (fromIndex === toIndex || fromIndex < 0 || toIndex < 0 || fromIndex >= items.length || toIndex >= items.length) - return null; - items.splice(toIndex, 0, items.splice(fromIndex, 1)[0]); - return items; + _this.t = (scope, options2) => { + const textID = `_tagging.presets.presets.${presetID}.${scope}`; + return _t(textID, options2); }; - _this.moveRecent = (item, beforeItem) => { - const recents = _this.getRecents(); - const fromIndex = recents.indexOf(item); - const toIndex = recents.indexOf(beforeItem); - const items = _this.moveItem(recents, fromIndex, toIndex); - if (items) - setRecents(items); + _this.t.append = (scope, options2) => { + const textID = `_tagging.presets.presets.${presetID}.${scope}`; + return _t.append(textID, options2); }; - _this.setMostRecent = (preset) => { - if (preset.searchable === false) - return; - let items = _this.getRecents(); - let item = _this.recentMatching(preset); - if (item) { - items.splice(items.indexOf(item), 1); - } else { - item = RibbonItem(preset, "recent"); - } - while (items.length >= MAXRECENTS) { - items.pop(); + function resolveReference(which) { + const match = (_this[which] || "").match(referenceRegex); + if (match) { + const preset2 = allPresets[match[1]]; + if (preset2) { + return preset2; + } + console.error(`Unable to resolve referenced preset: ${match[1]}`); } - items.unshift(item); - setRecents(items); - }; - function setFavorites(items) { - _favorites = items; - const minifiedItems = items.map((d) => d.minified()); - corePreferences("preset_favorites", JSON.stringify(minifiedItems)); - dispatch10.call("favoritePreset"); + return _this; } - _this.addFavorite = (preset, besidePreset, after) => { - const favorites = _this.getFavorites(); - const beforeItem = _this.favoriteMatching(besidePreset); - let toIndex = favorites.indexOf(beforeItem); - if (after) - toIndex += 1; - const newItem = RibbonItem(preset, "favorite"); - favorites.splice(toIndex, 0, newItem); - setFavorites(favorites); + _this.name = () => { + return resolveReference("originalName").t("name", { "default": _this.originalName || presetID }); }; - _this.toggleFavorite = (preset) => { - const favs = _this.getFavorites(); - const favorite = _this.favoriteMatching(preset); - if (favorite) { - favs.splice(favs.indexOf(favorite), 1); - } else { - if (favs.length === 10) { - favs.pop(); - } - favs.push(RibbonItem(preset, "favorite")); + _this.nameLabel = () => { + return resolveReference("originalName").t.append("name", { "default": _this.originalName || presetID }); + }; + _this.subtitle = () => { + if (_this.suggestion) { + let path = presetID.split("/"); + path.pop(); + return _t("_tagging.presets.presets." + path.join("/") + ".name"); } - setFavorites(favs); + return null; }; - _this.removeFavorite = (preset) => { - const item = _this.favoriteMatching(preset); - if (item) { - const items = _this.getFavorites(); - items.splice(items.indexOf(item), 1); - setFavorites(items); + _this.subtitleLabel = () => { + if (_this.suggestion) { + let path = presetID.split("/"); + path.pop(); + return _t.append("_tagging.presets.presets." + path.join("/") + ".name"); } + return null; }; - _this.getFavorites = () => { - if (!_favorites) { - let rawFavorites = JSON.parse(corePreferences("preset_favorites")); - if (!rawFavorites) { - rawFavorites = []; - corePreferences("preset_favorites", JSON.stringify(rawFavorites)); - } - _favorites = rawFavorites.reduce((output, d) => { - const item = ribbonItemForMinified(d, "favorite"); - if (item && item.preset.addable()) - output.push(item); - return output; - }, []); + _this.aliases = () => { + return resolveReference("originalName").t("aliases", { "default": _this.originalAliases }).trim().split(/\s*[\r\n]+\s*/); + }; + _this.terms = () => { + return resolveReference("originalName").t("terms", { "default": _this.originalTerms }).toLowerCase().trim().split(/\s*,+\s*/); + }; + _this.searchName = () => { + if (!_searchName) { + _searchName = (_this.suggestion ? _this.originalName : _this.name()).toLowerCase(); } - return _favorites; + return _searchName; }; - _this.favoriteMatching = (preset) => { - const favs = _this.getFavorites(); - for (let index in favs) { - if (favs[index].matches(preset)) { - return favs[index]; - } + _this.searchNameStripped = () => { + if (!_searchNameStripped) { + _searchNameStripped = stripDiacritics(_this.searchName()); } - return null; + return _searchNameStripped; }; - return utilRebind(_this, dispatch10, "on"); - } - - // modules/util/util.js - function utilTagText(entity) { - var obj = entity && entity.tags || {}; - return Object.keys(obj).map(function(k) { - return k + "=" + obj[k]; - }).join(", "); - } - function utilTotalExtent(array2, graph) { - var extent = geoExtent(); - var val, entity; - for (var i2 = 0; i2 < array2.length; i2++) { - val = array2[i2]; - entity = typeof val === "string" ? graph.hasEntity(val) : val; - if (entity) { - extent._extend(entity.extent(graph)); - } - } - return extent; - } - function utilTagDiff(oldTags, newTags) { - var tagDiff = []; - var keys = utilArrayUnion(Object.keys(oldTags), Object.keys(newTags)).sort(); - keys.forEach(function(k) { - var oldVal = oldTags[k]; - var newVal = newTags[k]; - if ((oldVal || oldVal === "") && (newVal === void 0 || newVal !== oldVal)) { - tagDiff.push({ - type: "-", - key: k, - oldVal, - newVal, - display: "- " + k + "=" + oldVal - }); + _this.searchAliases = () => { + if (!_searchAliases) { + _searchAliases = _this.aliases().map((alias) => alias.toLowerCase()); } - if ((newVal || newVal === "") && (oldVal === void 0 || newVal !== oldVal)) { - tagDiff.push({ - type: "+", - key: k, - oldVal, - newVal, - display: "+ " + k + "=" + newVal - }); + return _searchAliases; + }; + _this.searchAliasesStripped = () => { + if (!_searchAliasesStripped) { + _searchAliasesStripped = _this.searchAliases(); + _searchAliasesStripped = _searchAliasesStripped.map(stripDiacritics); } - }); - return tagDiff; - } - function utilEntitySelector(ids) { - return ids.length ? "." + ids.join(",.") : "nothing"; - } - function utilEntityOrMemberSelector(ids, graph) { - var seen = new Set(ids); - ids.forEach(collectShallowDescendants); - return utilEntitySelector(Array.from(seen)); - function collectShallowDescendants(id2) { - var entity = graph.hasEntity(id2); - if (!entity || entity.type !== "relation") - return; - entity.members.map(function(member) { - return member.id; - }).forEach(function(id3) { - seen.add(id3); - }); - } - } - function utilEntityOrDeepMemberSelector(ids, graph) { - return utilEntitySelector(utilEntityAndDeepMemberIDs(ids, graph)); - } - function utilEntityAndDeepMemberIDs(ids, graph) { - var seen = /* @__PURE__ */ new Set(); - ids.forEach(collectDeepDescendants); - return Array.from(seen); - function collectDeepDescendants(id2) { - if (seen.has(id2)) - return; - seen.add(id2); - var entity = graph.hasEntity(id2); - if (!entity || entity.type !== "relation") - return; - entity.members.map(function(member) { - return member.id; - }).forEach(collectDeepDescendants); - } - } - function utilDeepMemberSelector(ids, graph, skipMultipolgonMembers) { - var idsSet = new Set(ids); - var seen = /* @__PURE__ */ new Set(); - var returners = /* @__PURE__ */ new Set(); - ids.forEach(collectDeepDescendants); - return utilEntitySelector(Array.from(returners)); - function collectDeepDescendants(id2) { - if (seen.has(id2)) - return; - seen.add(id2); - if (!idsSet.has(id2)) { - returners.add(id2); + return _searchAliasesStripped; + }; + _this.isFallback = () => { + const tagCount = Object.keys(_this.tags).length; + return tagCount === 0 || tagCount === 1 && _this.tags.hasOwnProperty("area"); + }; + _this.addable = function(val) { + if (!arguments.length) + return _addable; + _addable = val; + return _this; + }; + _this.reference = () => { + const qid = _this.tags.wikidata || _this.tags["flag:wikidata"] || _this.tags["brand:wikidata"] || _this.tags["network:wikidata"] || _this.tags["operator:wikidata"]; + if (qid) { + return { qid }; } - var entity = graph.hasEntity(id2); - if (!entity || entity.type !== "relation") - return; - if (skipMultipolgonMembers && entity.isMultipolygon()) - return; - entity.members.map(function(member) { - return member.id; - }).forEach(collectDeepDescendants); - } - } - function utilHighlightEntities(ids, highlighted, context) { - context.surface().selectAll(utilEntityOrDeepMemberSelector(ids, context.graph())).classed("highlighted", highlighted); - } - function utilGetAllNodes(ids, graph) { - var seen = /* @__PURE__ */ new Set(); - var nodes = /* @__PURE__ */ new Set(); - ids.forEach(collectNodes); - return Array.from(nodes); - function collectNodes(id2) { - if (seen.has(id2)) - return; - seen.add(id2); - var entity = graph.hasEntity(id2); - if (!entity) - return; - if (entity.type === "node") { - nodes.add(entity); - } else if (entity.type === "way") { - entity.nodes.forEach(collectNodes); + let key = _this.originalReference.key || Object.keys(utilObjectOmit(_this.tags, "name"))[0]; + let value = _this.originalReference.value || _this.tags[key]; + if (value === "*") { + return { key }; } else { - entity.members.map(function(member) { - return member.id; - }).forEach(collectNodes); + return { key, value }; } - } - } - function utilDisplayName(entity) { - var localizedNameKey = "name:" + _mainLocalizer.languageCode().toLowerCase(); - var name = entity.tags[localizedNameKey] || entity.tags.name || ""; - if (name) - return name; - var tags = { - direction: entity.tags.direction, - from: entity.tags.from, - network: entity.tags.cycle_network || entity.tags.network, - ref: entity.tags.ref, - to: entity.tags.to, - via: entity.tags.via }; - var keyComponents = []; - if (tags.network) { - keyComponents.push("network"); - } - if (tags.ref) { - keyComponents.push("ref"); - } - if (entity.tags.route) { - if (tags.direction) { - keyComponents.push("direction"); - } else if (tags.from && tags.to) { - keyComponents.push("from"); - keyComponents.push("to"); - if (tags.via) { - keyComponents.push("via"); - } + _this.unsetTags = (tags, geometry, ignoringKeys, skipFieldDefaults, loc) => { + let removeTags = ignoringKeys ? utilObjectOmit(_this.removeTags, ignoringKeys) : _this.removeTags; + tags = utilObjectOmit(tags, Object.keys(removeTags)); + if (geometry && !skipFieldDefaults) { + _this.fields(loc).forEach((field) => { + if (field.matchGeometry(geometry) && field.key && field.default === tags[field.key] && (!ignoringKeys || ignoringKeys.indexOf(field.key) === -1)) { + delete tags[field.key]; + } + }); } - } - if (keyComponents.length) { - name = _t("inspector.display_name." + keyComponents.join("_"), tags); - } - return name; - } - function utilDisplayNameForPath(entity) { - var name = utilDisplayName(entity); - var isFirefox = utilDetect().browser.toLowerCase().indexOf("firefox") > -1; - var isNewChromium = Number(utilDetect().version.split(".")[0]) >= 96; - if (!isFirefox && !isNewChromium && name && rtlRegex.test(name)) { - name = fixRTLTextForSvg(name); - } - return name; - } - function utilDisplayType(id2) { - return { - n: _t("inspector.node"), - w: _t("inspector.way"), - r: _t("inspector.relation") - }[id2.charAt(0)]; - } - function utilDisplayLabel(entity, graphOrGeometry, verbose) { - var result; - var displayName = utilDisplayName(entity); - var preset = typeof graphOrGeometry === "string" ? _mainPresetIndex.matchTags(entity.tags, graphOrGeometry) : _mainPresetIndex.match(entity, graphOrGeometry); - var presetName = preset && (preset.suggestion ? preset.subtitle() : preset.name()); - if (verbose) { - result = [presetName, displayName].filter(Boolean).join(" "); - } else { - result = displayName || presetName; - } - return result || utilDisplayType(entity.id); - } - function utilEntityRoot(entityType) { - return { - node: "n", - way: "w", - relation: "r" - }[entityType]; - } - function utilCombinedTags(entityIDs, graph) { - var tags = {}; - var tagCounts = {}; - var allKeys = /* @__PURE__ */ new Set(); - var entities = entityIDs.map(function(entityID) { - return graph.hasEntity(entityID); - }).filter(Boolean); - entities.forEach(function(entity) { - var keys = Object.keys(entity.tags).filter(Boolean); - keys.forEach(function(key2) { - allKeys.add(key2); - }); - }); - entities.forEach(function(entity) { - allKeys.forEach(function(key2) { - var value = entity.tags[key2]; - if (!tags.hasOwnProperty(key2)) { - tags[key2] = value; + delete tags.area; + return tags; + }; + _this.setTags = (tags, geometry, skipFieldDefaults, loc) => { + const addTags = _this.addTags; + tags = Object.assign({}, tags); + for (let k in addTags) { + if (addTags[k] === "*") { + if (_this.tags[k] || !tags[k]) { + tags[k] = "yes"; + } } else { - if (!Array.isArray(tags[key2])) { - if (tags[key2] !== value) { - tags[key2] = [tags[key2], value]; - } - } else { - if (tags[key2].indexOf(value) === -1) { - tags[key2].push(value); + tags[k] = addTags[k]; + } + } + if (!addTags.hasOwnProperty("area")) { + delete tags.area; + if (geometry === "area") { + let needsAreaTag = true; + for (let k in addTags) { + if (_this.geometry.indexOf("line") === -1 && k in osmAreaKeys || k in osmAreaKeysExceptions && addTags[k] in osmAreaKeysExceptions[k]) { + needsAreaTag = false; + break; } } + if (needsAreaTag) { + tags.area = "yes"; + } } - var tagHash = key2 + "=" + value; - if (!tagCounts[tagHash]) - tagCounts[tagHash] = 0; - tagCounts[tagHash] += 1; - }); - }); - for (var key in tags) { - if (!Array.isArray(tags[key])) - continue; - tags[key] = tags[key].sort(function(val12, val2) { - var key2 = key2; - var count2 = tagCounts[key2 + "=" + val2]; - var count1 = tagCounts[key2 + "=" + val12]; - if (count2 !== count1) { - return count2 - count1; - } - if (val2 && val12) { - return val12.localeCompare(val2); - } - return val12 ? 1 : -1; - }); - } - return tags; - } - function utilStringQs(str2) { - var i2 = 0; - while (i2 < str2.length && (str2[i2] === "?" || str2[i2] === "#")) - i2++; - str2 = str2.slice(i2); - return str2.split("&").reduce(function(obj, pair2) { - var parts = pair2.split("="); - if (parts.length === 2) { - obj[parts[0]] = null === parts[1] ? "" : decodeURIComponent(parts[1]); } - return obj; - }, {}); - } - function utilQsString(obj, noencode) { - function softEncode(s) { - return encodeURIComponent(s).replace(/(%2F|%3A|%2C|%7B|%7D)/g, decodeURIComponent); - } - return Object.keys(obj).sort().map(function(key) { - return encodeURIComponent(key) + "=" + (noencode ? softEncode(obj[key]) : encodeURIComponent(obj[key])); - }).join("&"); - } - function utilPrefixDOMProperty(property) { - var prefixes2 = ["webkit", "ms", "moz", "o"]; - var i2 = -1; - var n2 = prefixes2.length; - var s = document.body; - if (property in s) - return property; - property = property.slice(0, 1).toUpperCase() + property.slice(1); - while (++i2 < n2) { - if (prefixes2[i2] + property in s) { - return prefixes2[i2] + property; + if (geometry && !skipFieldDefaults) { + _this.fields(loc).forEach((field) => { + if (field.matchGeometry(geometry) && field.key && !tags[field.key] && field.default) { + tags[field.key] = field.default; + } + }); } - } - return false; - } - function utilPrefixCSSProperty(property) { - var prefixes2 = ["webkit", "ms", "Moz", "O"]; - var i2 = -1; - var n2 = prefixes2.length; - var s = document.body.style; - if (property.toLowerCase() in s) { - return property.toLowerCase(); - } - while (++i2 < n2) { - if (prefixes2[i2] + property in s) { - return "-" + prefixes2[i2].toLowerCase() + property.replace(/([A-Z])/g, "-$1").toLowerCase(); + return tags; + }; + function resolveFields(which, loc) { + const fieldIDs = which === "fields" ? _this.originalFields : _this.originalMoreFields; + let resolved = []; + fieldIDs.forEach((fieldID) => { + const match = fieldID.match(referenceRegex); + if (match !== null) { + resolved = resolved.concat(inheritFields(allPresets[match[1]], which)); + } else if (allFields[fieldID]) { + resolved.push(allFields[fieldID]); + } else { + console.log(`Cannot resolve "${fieldID}" found in ${_this.id}.${which}`); + } + }); + if (!resolved.length) { + const endIndex = _this.id.lastIndexOf("/"); + const parentID = endIndex && _this.id.substring(0, endIndex); + if (parentID) { + let parent = allPresets[parentID]; + if (loc) { + const validHere = _sharedLocationManager.locationSetsAt(loc); + if (parent?.locationSetID && !validHere[parent.locationSetID]) { + const candidateIDs = Object.keys(allPresets).filter((k) => k.startsWith(parentID)); + parent = allPresets[candidateIDs.find((candidateID) => { + const candidate = allPresets[candidateID]; + return validHere[candidate.locationSetID] && (0, import_lodash.isEqual)(candidate.tags, parent.tags); + })]; + } + } + resolved = inheritFields(parent, which); + } } - } - return false; - } - var transformProperty; - function utilSetTransform(el, x, y, scale) { - var prop = transformProperty = transformProperty || utilPrefixCSSProperty("Transform"); - var translate = utilDetect().opera ? "translate(" + x + "px," + y + "px)" : "translate3d(" + x + "px," + y + "px,0)"; - return el.style(prop, translate + (scale ? " scale(" + scale + ")" : "")); - } - function utilEditDistance(a, b) { - a = (0, import_diacritics.remove)(a.toLowerCase()); - b = (0, import_diacritics.remove)(b.toLowerCase()); - if (a.length === 0) - return b.length; - if (b.length === 0) - return a.length; - var matrix = []; - var i2, j2; - for (i2 = 0; i2 <= b.length; i2++) { - matrix[i2] = [i2]; - } - for (j2 = 0; j2 <= a.length; j2++) { - matrix[0][j2] = j2; - } - for (i2 = 1; i2 <= b.length; i2++) { - for (j2 = 1; j2 <= a.length; j2++) { - if (b.charAt(i2 - 1) === a.charAt(j2 - 1)) { - matrix[i2][j2] = matrix[i2 - 1][j2 - 1]; + return utilArrayUniq(resolved); + function inheritFields(parent, which2) { + if (!parent) + return []; + if (which2 === "fields") { + return parent.fields().filter(shouldInherit); + } else if (which2 === "moreFields") { + return parent.moreFields(); } else { - matrix[i2][j2] = Math.min( - matrix[i2 - 1][j2 - 1] + 1, - Math.min( - matrix[i2][j2 - 1] + 1, - matrix[i2 - 1][j2] + 1 - ) - ); + return []; } } + function shouldInherit(f2) { + if (f2.key && _this.tags[f2.key] !== void 0 && // inherit anyway if multiple values are allowed or just a checkbox + f2.type !== "multiCombo" && f2.type !== "semiCombo" && f2.type !== "manyCombo" && f2.type !== "check") + return false; + return true; + } } - return matrix[b.length][a.length]; + function stripDiacritics(s) { + if (s.normalize) + s = s.normalize("NFD"); + s = s.replace(/[\u0300-\u036f]/g, ""); + return s; + } + return _this; } - function utilFastMouse(container) { - var rect = container.getBoundingClientRect(); - var rectLeft = rect.left; - var rectTop = rect.top; - var clientLeft = +container.clientLeft; - var clientTop = +container.clientTop; - return function(e) { - return [ - e.clientX - rectLeft - clientLeft, - e.clientY - rectTop - clientTop - ]; + + // modules/presets/index.js + var _mainPresetIndex = presetIndex(); + function presetIndex() { + const dispatch10 = dispatch_default("favoritePreset", "recentsChange"); + const MAXRECENTS = 30; + const POINT = presetPreset("point", { name: "Point", tags: {}, geometry: ["point", "vertex"], matchScore: 0.1 }); + const LINE = presetPreset("line", { name: "Line", tags: {}, geometry: ["line"], matchScore: 0.1 }); + const AREA = presetPreset("area", { name: "Area", tags: { area: "yes" }, geometry: ["area"], matchScore: 0.1 }); + const RELATION = presetPreset("relation", { name: "Relation", tags: {}, geometry: ["relation"], matchScore: 0.1 }); + let _this = presetCollection([POINT, LINE, AREA, RELATION]); + let _presets = { point: POINT, line: LINE, area: AREA, relation: RELATION }; + let _defaults = { + point: presetCollection([POINT]), + vertex: presetCollection([POINT]), + line: presetCollection([LINE]), + area: presetCollection([AREA]), + relation: presetCollection([RELATION]) }; - } - function utilAsyncMap(inputs, func, callback) { - var remaining = inputs.length; - var results = []; - var errors = []; - inputs.forEach(function(d, i2) { - func(d, function done(err, data) { - errors[i2] = err; - results[i2] = data; - remaining--; - if (!remaining) - callback(errors, results); + let _fields = {}; + let _categories = {}; + let _universal = []; + let _addablePresetIDs = null; + let _recents; + let _favorites; + let _geometryIndex = { point: {}, vertex: {}, line: {}, area: {}, relation: {} }; + let _loadPromise; + _this.ensureLoaded = () => { + if (_loadPromise) + return _loadPromise; + return _loadPromise = Promise.all([ + _mainFileFetcher.get("preset_categories"), + _mainFileFetcher.get("preset_defaults"), + _mainFileFetcher.get("preset_presets"), + _mainFileFetcher.get("preset_fields") + ]).then((vals) => { + _this.merge({ + categories: vals[0], + defaults: vals[1], + presets: vals[2], + fields: vals[3] + }); + osmSetAreaKeys(_this.areaKeys()); + osmSetLineTags(_this.lineTags()); + osmSetPointTags(_this.pointTags()); + osmSetVertexTags(_this.vertexTags()); }); - }); - } - function utilWrap(index, length) { - if (index < 0) { - index += Math.ceil(-index / length) * length; - } - return index % length; - } - function utilFunctor(value) { - if (typeof value === "function") - return value; - return function() { - return value; }; - } - function utilNoAuto(selection2) { - var isText = selection2.size() && selection2.node().tagName.toLowerCase() === "textarea"; - return selection2.attr("autocomplete", "new-password").attr("autocorrect", "off").attr("autocapitalize", "off").attr("spellcheck", isText ? "true" : "false"); - } - function utilHashcode(str2) { - var hash = 0; - if (str2.length === 0) { - return hash; - } - for (var i2 = 0; i2 < str2.length; i2++) { - var char = str2.charCodeAt(i2); - hash = (hash << 5) - hash + char; - hash = hash & hash; - } - return hash; - } - function utilSafeClassName(str2) { - return str2.toLowerCase().replace(/[^a-z0-9]+/g, "_"); - } - function utilUniqueDomId(val) { - return "ideditor-" + utilSafeClassName(val.toString()) + "-" + new Date().getTime().toString(); - } - function utilUnicodeCharsCount(str2) { - return Array.from(str2).length; - } - function utilUnicodeCharsTruncated(str2, limit) { - return Array.from(str2).slice(0, limit).join(""); - } - function toNumericID(id2) { - var match = id2.match(/^[cnwr](-?\d+)$/); - if (match) { - return parseInt(match[1], 10); - } - return NaN; - } - function compareNumericIDs(left, right) { - if (isNaN(left) && isNaN(right)) - return -1; - if (isNaN(left)) - return 1; - if (isNaN(right)) - return -1; - if (Math.sign(left) !== Math.sign(right)) - return -Math.sign(left); - if (Math.sign(left) < 0) - return Math.sign(right - left); - return Math.sign(left - right); - } - function utilCompareIDs(left, right) { - return compareNumericIDs(toNumericID(left), toNumericID(right)); - } - function utilOldestID(ids) { - if (ids.length === 0) { - return void 0; - } - var oldestIDIndex = 0; - var oldestID = toNumericID(ids[0]); - for (var i2 = 1; i2 < ids.length; i2++) { - var num = toNumericID(ids[i2]); - if (compareNumericIDs(oldestID, num) === 1) { - oldestIDIndex = i2; - oldestID = num; + _this.merge = (d) => { + let newLocationSets = []; + if (d.fields) { + Object.keys(d.fields).forEach((fieldID) => { + let f2 = d.fields[fieldID]; + if (f2) { + f2 = presetField(fieldID, f2, _fields); + if (f2.locationSet) + newLocationSets.push(f2); + _fields[fieldID] = f2; + } else { + delete _fields[fieldID]; + } + }); } - } - return ids[oldestIDIndex]; - } - - // modules/osm/entity.js - function osmEntity(attrs) { - if (this instanceof osmEntity) - return; - if (attrs && attrs.type) { - return osmEntity[attrs.type].apply(this, arguments); - } else if (attrs && attrs.id) { - return osmEntity[osmEntity.id.type(attrs.id)].apply(this, arguments); - } - return new osmEntity().initialize(arguments); - } - osmEntity.id = function(type3) { - return osmEntity.id.fromOSM(type3, osmEntity.id.next[type3]--); - }; - osmEntity.id.next = { - changeset: -1, - node: -1, - way: -1, - relation: -1 - }; - osmEntity.id.fromOSM = function(type3, id2) { - return type3[0] + id2; - }; - osmEntity.id.toOSM = function(id2) { - var match = id2.match(/^[cnwr](-?\d+)$/); - if (match) { - return match[1]; - } - return ""; - }; - osmEntity.id.type = function(id2) { - return { "c": "changeset", "n": "node", "w": "way", "r": "relation" }[id2[0]]; - }; - osmEntity.key = function(entity) { - return entity.id + "v" + (entity.v || 0); - }; - var _deprecatedTagValuesByKey; - osmEntity.deprecatedTagValuesByKey = function(dataDeprecated) { - if (!_deprecatedTagValuesByKey) { - _deprecatedTagValuesByKey = {}; - dataDeprecated.forEach(function(d) { - var oldKeys = Object.keys(d.old); - if (oldKeys.length === 1) { - var oldKey = oldKeys[0]; - var oldValue = d.old[oldKey]; - if (oldValue !== "*") { - if (!_deprecatedTagValuesByKey[oldKey]) { - _deprecatedTagValuesByKey[oldKey] = [oldValue]; - } else { - _deprecatedTagValuesByKey[oldKey].push(oldValue); + if (d.presets) { + Object.keys(d.presets).forEach((presetID) => { + let p = d.presets[presetID]; + if (p) { + const isAddable = !_addablePresetIDs || _addablePresetIDs.has(presetID); + p = presetPreset(presetID, p, isAddable, _fields, _presets); + if (p.locationSet) + newLocationSets.push(p); + _presets[presetID] = p; + } else { + const existing = _presets[presetID]; + if (existing && !existing.isFallback()) { + delete _presets[presetID]; } } - } - }); - } - return _deprecatedTagValuesByKey; - }; - osmEntity.prototype = { - tags: {}, - initialize: function(sources) { - for (var i2 = 0; i2 < sources.length; ++i2) { - var source = sources[i2]; - for (var prop in source) { - if (Object.prototype.hasOwnProperty.call(source, prop)) { - if (source[prop] === void 0) { - delete this[prop]; - } else { - this[prop] = source[prop]; - } + }); + } + if (d.categories) { + Object.keys(d.categories).forEach((categoryID) => { + let c = d.categories[categoryID]; + if (c) { + c = presetCategory(categoryID, c, _presets); + if (c.locationSet) + newLocationSets.push(c); + _categories[categoryID] = c; + } else { + delete _categories[categoryID]; } - } + }); } - if (!this.id && this.type) { - this.id = osmEntity.id(this.type); + _this.collection = Object.values(_presets).concat(Object.values(_categories)); + if (d.defaults) { + Object.keys(d.defaults).forEach((geometry) => { + const def = d.defaults[geometry]; + if (Array.isArray(def)) { + _defaults[geometry] = presetCollection( + def.map((id2) => _presets[id2] || _categories[id2]).filter(Boolean) + ); + } else { + delete _defaults[geometry]; + } + }); } - if (!this.hasOwnProperty("visible")) { - this.visible = true; + _universal = Object.values(_fields).filter((field) => field.universal); + _geometryIndex = { point: {}, vertex: {}, line: {}, area: {}, relation: {} }; + _this.collection.forEach((preset) => { + (preset.geometry || []).forEach((geometry) => { + let g = _geometryIndex[geometry]; + for (let key in preset.tags) { + g[key] = g[key] || {}; + let value = preset.tags[key]; + (g[key][value] = g[key][value] || []).push(preset); + } + }); + }); + if (d.featureCollection && Array.isArray(d.featureCollection.features)) { + _sharedLocationManager.mergeCustomGeoJSON(d.featureCollection); } - if (debug) { - Object.freeze(this); - Object.freeze(this.tags); - if (this.loc) - Object.freeze(this.loc); - if (this.nodes) - Object.freeze(this.nodes); - if (this.members) - Object.freeze(this.members); + if (newLocationSets.length) { + _sharedLocationManager.mergeLocationSets(newLocationSets); } - return this; - }, - copy: function(resolver, copies) { - if (copies[this.id]) - return copies[this.id]; - var copy2 = osmEntity(this, { id: void 0, user: void 0, version: void 0 }); - copies[this.id] = copy2; - return copy2; - }, - osmId: function() { - return osmEntity.id.toOSM(this.id); - }, - isNew: function() { - var osmId = osmEntity.id.toOSM(this.id); - return osmId.length === 0 || osmId[0] === "-"; - }, - update: function(attrs) { - return osmEntity(this, attrs, { v: 1 + (this.v || 0) }); - }, - mergeTags: function(tags) { - var merged = Object.assign({}, this.tags); - var changed = false; - for (var k in tags) { - var t1 = merged[k]; - var t2 = tags[k]; - if (!t1) { - changed = true; - merged[k] = t2; - } else if (t1 !== t2) { - changed = true; - merged[k] = utilUnicodeCharsTruncated( - utilArrayUnion(t1.split(/;\s*/), t2.split(/;\s*/)).join(";"), - 255 - ); + return _this; + }; + _this.match = (entity, resolver) => { + return resolver.transient(entity, "presetMatch", () => { + let geometry = entity.geometry(resolver); + if (geometry === "vertex" && entity.isOnAddressLine(resolver)) { + geometry = "point"; } - } - return changed ? this.update({ tags: merged }) : this; - }, - intersects: function(extent, resolver) { - return this.extent(resolver).intersects(extent); - }, - hasNonGeometryTags: function() { - return Object.keys(this.tags).some(function(k) { - return k !== "area"; + const entityExtent = entity.extent(resolver); + return _this.matchTags(entity.tags, geometry, entityExtent.center()); }); - }, - hasParentRelations: function(resolver) { - return resolver.parentRelations(this).length > 0; - }, - hasInterestingTags: function() { - return Object.keys(this.tags).some(osmIsInterestingTag); - }, - isHighwayIntersection: function() { - return false; - }, - isDegenerate: function() { - return true; - }, - deprecatedTags: function(dataDeprecated) { - var tags = this.tags; - if (Object.keys(tags).length === 0) - return []; - var deprecated = []; - dataDeprecated.forEach(function(d) { - var oldKeys = Object.keys(d.old); - if (d.replace) { - var hasExistingValues = Object.keys(d.replace).some(function(replaceKey) { - if (!tags[replaceKey] || d.old[replaceKey]) - return false; - var replaceValue = d.replace[replaceKey]; - if (replaceValue === "*") - return false; - if (replaceValue === tags[replaceKey]) - return false; - return true; - }); - if (hasExistingValues) - return; + }; + _this.matchTags = (tags, geometry, loc) => { + const keyIndex = _geometryIndex[geometry]; + let bestScore = -1; + let bestMatch; + let matchCandidates = []; + for (let k in tags) { + let indexMatches = []; + let valueIndex = keyIndex[k]; + if (!valueIndex) + continue; + let keyValueMatches = valueIndex[tags[k]]; + if (keyValueMatches) + indexMatches.push(...keyValueMatches); + let keyStarMatches = valueIndex["*"]; + if (keyStarMatches) + indexMatches.push(...keyStarMatches); + if (indexMatches.length === 0) + continue; + for (let i2 = 0; i2 < indexMatches.length; i2++) { + const candidate = indexMatches[i2]; + const score = candidate.matchScore(tags); + if (score === -1) { + continue; + } + matchCandidates.push({ score, candidate }); + if (score > bestScore) { + bestScore = score; + bestMatch = candidate; + } } - var matchesDeprecatedTags = oldKeys.every(function(oldKey) { - if (!tags[oldKey]) - return false; - if (d.old[oldKey] === "*") - return true; - if (d.old[oldKey] === tags[oldKey]) - return true; - var vals = tags[oldKey].split(";").filter(Boolean); - if (vals.length === 0) { - return false; - } else if (vals.length > 1) { - return vals.indexOf(d.old[oldKey]) !== -1; - } else { - if (tags[oldKey] === d.old[oldKey]) { - if (d.replace && d.old[oldKey] === d.replace[oldKey]) { - var replaceKeys = Object.keys(d.replace); - return !replaceKeys.every(function(replaceKey) { - return tags[replaceKey] === d.replace[replaceKey]; - }); - } else { - return true; - } + } + if (bestMatch && bestMatch.locationSetID && bestMatch.locationSetID !== "+[Q2]" && Array.isArray(loc)) { + const validHere = _sharedLocationManager.locationSetsAt(loc); + if (!validHere[bestMatch.locationSetID]) { + matchCandidates.sort((a, b) => a.score < b.score ? 1 : -1); + for (let i2 = 0; i2 < matchCandidates.length; i2++) { + const candidateScore = matchCandidates[i2]; + if (!candidateScore.candidate.locationSetID || validHere[candidateScore.candidate.locationSetID]) { + bestMatch = candidateScore.candidate; + bestScore = candidateScore.score; + break; } } + } + } + if (!bestMatch || bestMatch.isFallback()) { + for (let k in tags) { + if (/^addr:/.test(k) && keyIndex["addr:*"] && keyIndex["addr:*"]["*"]) { + bestMatch = keyIndex["addr:*"]["*"][0]; + break; + } + } + } + return bestMatch || _this.fallback(geometry); + }; + _this.allowsVertex = (entity, resolver) => { + if (entity.type !== "node") + return false; + if (Object.keys(entity.tags).length === 0) + return true; + return resolver.transient(entity, "vertexMatch", () => { + if (entity.isOnAddressLine(resolver)) + return true; + const geometries = osmNodeGeometriesForTags(entity.tags); + if (geometries.vertex) + return true; + if (geometries.point) return false; - }); - if (matchesDeprecatedTags) { - deprecated.push(d); + return true; + }); + }; + _this.areaKeys = () => { + const ignore = { + barrier: true, + highway: true, + footway: true, + railway: true, + junction: true, + traffic_calming: true, + type: true + }; + let areaKeys = {}; + const presets = _this.collection.filter((p) => !p.suggestion && !p.replacement); + presets.forEach((p) => { + const keys2 = p.tags && Object.keys(p.tags); + const key = keys2 && keys2.length && keys2[0]; + if (!key) + return; + if (ignore[key]) + return; + if (p.geometry.indexOf("area") !== -1) { + areaKeys[key] = areaKeys[key] || {}; } }); - return deprecated; - } - }; - - // modules/osm/lanes.js - function osmLanes(entity) { - if (entity.type !== "way") - return null; - if (!entity.tags.highway) - return null; - var tags = entity.tags; - var isOneWay = entity.isOneWay(); - var laneCount = getLaneCount(tags, isOneWay); - var maxspeed = parseMaxspeed(tags); - var laneDirections = parseLaneDirections(tags, isOneWay, laneCount); - var forward = laneDirections.forward; - var backward = laneDirections.backward; - var bothways = laneDirections.bothways; - var turnLanes = {}; - turnLanes.unspecified = parseTurnLanes(tags["turn:lanes"]); - turnLanes.forward = parseTurnLanes(tags["turn:lanes:forward"]); - turnLanes.backward = parseTurnLanes(tags["turn:lanes:backward"]); - var maxspeedLanes = {}; - maxspeedLanes.unspecified = parseMaxspeedLanes(tags["maxspeed:lanes"], maxspeed); - maxspeedLanes.forward = parseMaxspeedLanes(tags["maxspeed:lanes:forward"], maxspeed); - maxspeedLanes.backward = parseMaxspeedLanes(tags["maxspeed:lanes:backward"], maxspeed); - var psvLanes = {}; - psvLanes.unspecified = parseMiscLanes(tags["psv:lanes"]); - psvLanes.forward = parseMiscLanes(tags["psv:lanes:forward"]); - psvLanes.backward = parseMiscLanes(tags["psv:lanes:backward"]); - var busLanes = {}; - busLanes.unspecified = parseMiscLanes(tags["bus:lanes"]); - busLanes.forward = parseMiscLanes(tags["bus:lanes:forward"]); - busLanes.backward = parseMiscLanes(tags["bus:lanes:backward"]); - var taxiLanes = {}; - taxiLanes.unspecified = parseMiscLanes(tags["taxi:lanes"]); - taxiLanes.forward = parseMiscLanes(tags["taxi:lanes:forward"]); - taxiLanes.backward = parseMiscLanes(tags["taxi:lanes:backward"]); - var hovLanes = {}; - hovLanes.unspecified = parseMiscLanes(tags["hov:lanes"]); - hovLanes.forward = parseMiscLanes(tags["hov:lanes:forward"]); - hovLanes.backward = parseMiscLanes(tags["hov:lanes:backward"]); - var hgvLanes = {}; - hgvLanes.unspecified = parseMiscLanes(tags["hgv:lanes"]); - hgvLanes.forward = parseMiscLanes(tags["hgv:lanes:forward"]); - hgvLanes.backward = parseMiscLanes(tags["hgv:lanes:backward"]); - var bicyclewayLanes = {}; - bicyclewayLanes.unspecified = parseBicycleWay(tags["bicycleway:lanes"]); - bicyclewayLanes.forward = parseBicycleWay(tags["bicycleway:lanes:forward"]); - bicyclewayLanes.backward = parseBicycleWay(tags["bicycleway:lanes:backward"]); - var lanesObj = { - forward: [], - backward: [], - unspecified: [] + presets.forEach((p) => { + let key; + for (key in p.addTags) { + const value = p.addTags[key]; + if (key in areaKeys && // probably an area... + p.geometry.indexOf("line") !== -1 && // but sometimes a line + value !== "*") { + areaKeys[key][value] = true; + } + } + }); + return areaKeys; }; - mapToLanesObj(lanesObj, turnLanes, "turnLane"); - mapToLanesObj(lanesObj, maxspeedLanes, "maxspeed"); - mapToLanesObj(lanesObj, psvLanes, "psv"); - mapToLanesObj(lanesObj, busLanes, "bus"); - mapToLanesObj(lanesObj, taxiLanes, "taxi"); - mapToLanesObj(lanesObj, hovLanes, "hov"); - mapToLanesObj(lanesObj, hgvLanes, "hgv"); - mapToLanesObj(lanesObj, bicyclewayLanes, "bicycleway"); - return { - metadata: { - count: laneCount, - oneway: isOneWay, - forward, - backward, - bothways, - turnLanes, - maxspeed, - maxspeedLanes, - psvLanes, - busLanes, - taxiLanes, - hovLanes, - hgvLanes, - bicyclewayLanes - }, - lanes: lanesObj + _this.lineTags = () => { + return _this.collection.filter((lineTags, d) => { + if (d.suggestion || d.replacement || d.searchable === false) + return lineTags; + const keys2 = d.tags && Object.keys(d.tags); + const key = keys2 && keys2.length && keys2[0]; + if (!key) + return lineTags; + if (d.geometry.indexOf("line") !== -1) { + lineTags[key] = lineTags[key] || []; + lineTags[key].push(d.tags); + } + return lineTags; + }, {}); }; - } - function getLaneCount(tags, isOneWay) { - var count; - if (tags.lanes) { - count = parseInt(tags.lanes, 10); - if (count > 0) { - return count; - } - } - switch (tags.highway) { - case "trunk": - case "motorway": - count = isOneWay ? 2 : 4; - break; - default: - count = isOneWay ? 1 : 2; - break; - } - return count; - } - function parseMaxspeed(tags) { - var maxspeed = tags.maxspeed; - if (!maxspeed) - return; - var maxspeedRegex = /^([0-9][\.0-9]+?)(?:[ ]?(?:km\/h|kmh|kph|mph|knots))?$/; - if (!maxspeedRegex.test(maxspeed)) - return; - return parseInt(maxspeed, 10); - } - function parseLaneDirections(tags, isOneWay, laneCount) { - var forward = parseInt(tags["lanes:forward"], 10); - var backward = parseInt(tags["lanes:backward"], 10); - var bothways = parseInt(tags["lanes:both_ways"], 10) > 0 ? 1 : 0; - if (parseInt(tags.oneway, 10) === -1) { - forward = 0; - bothways = 0; - backward = laneCount; - } else if (isOneWay) { - forward = laneCount; - bothways = 0; - backward = 0; - } else if (isNaN(forward) && isNaN(backward)) { - backward = Math.floor((laneCount - bothways) / 2); - forward = laneCount - bothways - backward; - } else if (isNaN(forward)) { - if (backward > laneCount - bothways) { - backward = laneCount - bothways; + _this.pointTags = () => { + return _this.collection.reduce((pointTags, d) => { + if (d.suggestion || d.replacement || d.searchable === false) + return pointTags; + const keys2 = d.tags && Object.keys(d.tags); + const key = keys2 && keys2.length && keys2[0]; + if (!key) + return pointTags; + if (d.geometry.indexOf("point") !== -1) { + pointTags[key] = pointTags[key] || {}; + pointTags[key][d.tags[key]] = true; + } + return pointTags; + }, {}); + }; + _this.vertexTags = () => { + return _this.collection.reduce((vertexTags, d) => { + if (d.suggestion || d.replacement || d.searchable === false) + return vertexTags; + const keys2 = d.tags && Object.keys(d.tags); + const key = keys2 && keys2.length && keys2[0]; + if (!key) + return vertexTags; + if (d.geometry.indexOf("vertex") !== -1) { + vertexTags[key] = vertexTags[key] || {}; + vertexTags[key][d.tags[key]] = true; + } + return vertexTags; + }, {}); + }; + _this.field = (id2) => _fields[id2]; + _this.universal = () => _universal; + _this.defaults = (geometry, n2, startWithRecents, loc, extraPresets) => { + let recents = []; + if (startWithRecents) { + recents = _this.recent().matchGeometry(geometry).collection.slice(0, 4); } - forward = laneCount - bothways - backward; - } else if (isNaN(backward)) { - if (forward > laneCount - bothways) { - forward = laneCount - bothways; + let defaults2; + if (_addablePresetIDs) { + defaults2 = Array.from(_addablePresetIDs).map(function(id2) { + var preset = _this.item(id2); + if (preset && preset.matchGeometry(geometry)) + return preset; + return null; + }).filter(Boolean); + } else { + defaults2 = _defaults[geometry].collection.concat(_this.fallback(geometry)); } - backward = laneCount - bothways - forward; + let result = presetCollection( + utilArrayUniq(recents.concat(defaults2).concat(extraPresets || [])).slice(0, n2 - 1) + ); + if (Array.isArray(loc)) { + const validHere = _sharedLocationManager.locationSetsAt(loc); + result.collection = result.collection.filter((a) => !a.locationSetID || validHere[a.locationSetID]); + } + return result; + }; + _this.addablePresetIDs = function(val) { + if (!arguments.length) + return _addablePresetIDs; + if (Array.isArray(val)) + val = new Set(val); + _addablePresetIDs = val; + if (_addablePresetIDs) { + _this.collection.forEach((p) => { + if (p.addable) + p.addable(_addablePresetIDs.has(p.id)); + }); + } else { + _this.collection.forEach((p) => { + if (p.addable) + p.addable(true); + }); + } + return _this; + }; + _this.recent = () => { + return presetCollection( + utilArrayUniq(_this.getRecents().map((d) => d.preset).filter((d) => d.searchable !== false)) + ); + }; + function RibbonItem(preset, source) { + let item = {}; + item.preset = preset; + item.source = source; + item.isFavorite = () => item.source === "favorite"; + item.isRecent = () => item.source === "recent"; + item.matches = (preset2) => item.preset.id === preset2.id; + item.minified = () => ({ pID: item.preset.id }); + return item; } - return { - forward, - backward, - bothways + function ribbonItemForMinified(d, source) { + if (d && d.pID) { + const preset = _this.item(d.pID); + if (!preset) + return null; + return RibbonItem(preset, source); + } + return null; + } + _this.getGenericRibbonItems = () => { + return ["point", "line", "area"].map((id2) => RibbonItem(_this.item(id2), "generic")); + }; + _this.getAddable = () => { + if (!_addablePresetIDs) + return []; + return _addablePresetIDs.map((id2) => { + const preset = _this.item(id2); + if (preset) + return RibbonItem(preset, "addable"); + return null; + }).filter(Boolean); + }; + function setRecents(items) { + _recents = items; + const minifiedItems = items.map((d) => d.minified()); + corePreferences("preset_recents", JSON.stringify(minifiedItems)); + dispatch10.call("recentsChange"); + } + _this.getRecents = () => { + if (!_recents) { + _recents = (JSON.parse(corePreferences("preset_recents")) || []).reduce((acc, d) => { + let item = ribbonItemForMinified(d, "recent"); + if (item && item.preset.addable()) + acc.push(item); + return acc; + }, []); + } + return _recents; + }; + _this.addRecent = (preset, besidePreset, after) => { + const recents = _this.getRecents(); + const beforeItem = _this.recentMatching(besidePreset); + let toIndex = recents.indexOf(beforeItem); + if (after) + toIndex += 1; + const newItem = RibbonItem(preset, "recent"); + recents.splice(toIndex, 0, newItem); + setRecents(recents); + }; + _this.removeRecent = (preset) => { + const item = _this.recentMatching(preset); + if (item) { + let items = _this.getRecents(); + items.splice(items.indexOf(item), 1); + setRecents(items); + } + }; + _this.recentMatching = (preset) => { + const items = _this.getRecents(); + for (let i2 in items) { + if (items[i2].matches(preset)) { + return items[i2]; + } + } + return null; + }; + _this.moveItem = (items, fromIndex, toIndex) => { + if (fromIndex === toIndex || fromIndex < 0 || toIndex < 0 || fromIndex >= items.length || toIndex >= items.length) + return null; + items.splice(toIndex, 0, items.splice(fromIndex, 1)[0]); + return items; + }; + _this.moveRecent = (item, beforeItem) => { + const recents = _this.getRecents(); + const fromIndex = recents.indexOf(item); + const toIndex = recents.indexOf(beforeItem); + const items = _this.moveItem(recents, fromIndex, toIndex); + if (items) + setRecents(items); + }; + _this.setMostRecent = (preset) => { + if (preset.searchable === false) + return; + let items = _this.getRecents(); + let item = _this.recentMatching(preset); + if (item) { + items.splice(items.indexOf(item), 1); + } else { + item = RibbonItem(preset, "recent"); + } + while (items.length >= MAXRECENTS) { + items.pop(); + } + items.unshift(item); + setRecents(items); + }; + function setFavorites(items) { + _favorites = items; + const minifiedItems = items.map((d) => d.minified()); + corePreferences("preset_favorites", JSON.stringify(minifiedItems)); + dispatch10.call("favoritePreset"); + } + _this.addFavorite = (preset, besidePreset, after) => { + const favorites = _this.getFavorites(); + const beforeItem = _this.favoriteMatching(besidePreset); + let toIndex = favorites.indexOf(beforeItem); + if (after) + toIndex += 1; + const newItem = RibbonItem(preset, "favorite"); + favorites.splice(toIndex, 0, newItem); + setFavorites(favorites); + }; + _this.toggleFavorite = (preset) => { + const favs = _this.getFavorites(); + const favorite = _this.favoriteMatching(preset); + if (favorite) { + favs.splice(favs.indexOf(favorite), 1); + } else { + if (favs.length === 10) { + favs.pop(); + } + favs.push(RibbonItem(preset, "favorite")); + } + setFavorites(favs); + }; + _this.removeFavorite = (preset) => { + const item = _this.favoriteMatching(preset); + if (item) { + const items = _this.getFavorites(); + items.splice(items.indexOf(item), 1); + setFavorites(items); + } + }; + _this.getFavorites = () => { + if (!_favorites) { + let rawFavorites = JSON.parse(corePreferences("preset_favorites")); + if (!rawFavorites) { + rawFavorites = []; + corePreferences("preset_favorites", JSON.stringify(rawFavorites)); + } + _favorites = rawFavorites.reduce((output, d) => { + const item = ribbonItemForMinified(d, "favorite"); + if (item && item.preset.addable()) + output.push(item); + return output; + }, []); + } + return _favorites; + }; + _this.favoriteMatching = (preset) => { + const favs = _this.getFavorites(); + for (let index in favs) { + if (favs[index].matches(preset)) { + return favs[index]; + } + } + return null; }; + return utilRebind(_this, dispatch10, "on"); } - function parseTurnLanes(tag) { - if (!tag) - return; - var validValues = [ - "left", - "slight_left", - "sharp_left", - "through", - "right", - "slight_right", - "sharp_right", - "reverse", - "merge_to_left", - "merge_to_right", - "none" - ]; - return tag.split("|").map(function(s) { - if (s === "") - s = "none"; - return s.split(";").map(function(d) { - return validValues.indexOf(d) === -1 ? "unknown" : d; - }); - }); + + // modules/util/util.js + function utilTagText(entity) { + var obj = entity && entity.tags || {}; + return Object.keys(obj).map(function(k) { + return k + "=" + obj[k]; + }).join(", "); } - function parseMaxspeedLanes(tag, maxspeed) { - if (!tag) - return; - return tag.split("|").map(function(s) { - if (s === "none") - return s; - var m = parseInt(s, 10); - if (s === "" || m === maxspeed) - return null; - return isNaN(m) ? "unknown" : m; - }); + function utilTotalExtent(array2, graph) { + var extent = geoExtent(); + var val, entity; + for (var i2 = 0; i2 < array2.length; i2++) { + val = array2[i2]; + entity = typeof val === "string" ? graph.hasEntity(val) : val; + if (entity) { + extent._extend(entity.extent(graph)); + } + } + return extent; } - function parseMiscLanes(tag) { - if (!tag) - return; - var validValues = [ - "yes", - "no", - "designated" - ]; - return tag.split("|").map(function(s) { - if (s === "") - s = "no"; - return validValues.indexOf(s) === -1 ? "unknown" : s; + function utilTagDiff(oldTags, newTags) { + var tagDiff = []; + var keys2 = utilArrayUnion(Object.keys(oldTags), Object.keys(newTags)).sort(); + keys2.forEach(function(k) { + var oldVal = oldTags[k]; + var newVal = newTags[k]; + if ((oldVal || oldVal === "") && (newVal === void 0 || newVal !== oldVal)) { + tagDiff.push({ + type: "-", + key: k, + oldVal, + newVal, + display: "- " + k + "=" + oldVal + }); + } + if ((newVal || newVal === "") && (oldVal === void 0 || newVal !== oldVal)) { + tagDiff.push({ + type: "+", + key: k, + oldVal, + newVal, + display: "+ " + k + "=" + newVal + }); + } }); + return tagDiff; } - function parseBicycleWay(tag) { - if (!tag) - return; - var validValues = [ - "yes", - "no", - "designated", - "lane" - ]; - return tag.split("|").map(function(s) { - if (s === "") - s = "no"; - return validValues.indexOf(s) === -1 ? "unknown" : s; - }); + function utilEntitySelector(ids) { + return ids.length ? "." + ids.join(",.") : "nothing"; } - function mapToLanesObj(lanesObj, data, key) { - if (data.forward) { - data.forward.forEach(function(l, i2) { - if (!lanesObj.forward[i2]) - lanesObj.forward[i2] = {}; - lanesObj.forward[i2][key] = l; + function utilEntityOrMemberSelector(ids, graph) { + var seen = new Set(ids); + ids.forEach(collectShallowDescendants); + return utilEntitySelector(Array.from(seen)); + function collectShallowDescendants(id2) { + var entity = graph.hasEntity(id2); + if (!entity || entity.type !== "relation") + return; + entity.members.map(function(member) { + return member.id; + }).forEach(function(id3) { + seen.add(id3); }); } - if (data.backward) { - data.backward.forEach(function(l, i2) { - if (!lanesObj.backward[i2]) - lanesObj.backward[i2] = {}; - lanesObj.backward[i2][key] = l; - }); + } + function utilEntityOrDeepMemberSelector(ids, graph) { + return utilEntitySelector(utilEntityAndDeepMemberIDs(ids, graph)); + } + function utilEntityAndDeepMemberIDs(ids, graph) { + var seen = /* @__PURE__ */ new Set(); + ids.forEach(collectDeepDescendants); + return Array.from(seen); + function collectDeepDescendants(id2) { + if (seen.has(id2)) + return; + seen.add(id2); + var entity = graph.hasEntity(id2); + if (!entity || entity.type !== "relation") + return; + entity.members.map(function(member) { + return member.id; + }).forEach(collectDeepDescendants); } - if (data.unspecified) { - data.unspecified.forEach(function(l, i2) { - if (!lanesObj.unspecified[i2]) - lanesObj.unspecified[i2] = {}; - lanesObj.unspecified[i2][key] = l; - }); + } + function utilDeepMemberSelector(ids, graph, skipMultipolgonMembers) { + var idsSet = new Set(ids); + var seen = /* @__PURE__ */ new Set(); + var returners = /* @__PURE__ */ new Set(); + ids.forEach(collectDeepDescendants); + return utilEntitySelector(Array.from(returners)); + function collectDeepDescendants(id2) { + if (seen.has(id2)) + return; + seen.add(id2); + if (!idsSet.has(id2)) { + returners.add(id2); + } + var entity = graph.hasEntity(id2); + if (!entity || entity.type !== "relation") + return; + if (skipMultipolgonMembers && entity.isMultipolygon()) + return; + entity.members.map(function(member) { + return member.id; + }).forEach(collectDeepDescendants); } } - - // modules/osm/way.js - function osmWay() { - if (!(this instanceof osmWay)) { - return new osmWay().initialize(arguments); - } else if (arguments.length) { - this.initialize(arguments); + function utilHighlightEntities(ids, highlighted, context) { + context.surface().selectAll(utilEntityOrDeepMemberSelector(ids, context.graph())).classed("highlighted", highlighted); + } + function utilGetAllNodes(ids, graph) { + var seen = /* @__PURE__ */ new Set(); + var nodes = /* @__PURE__ */ new Set(); + ids.forEach(collectNodes); + return Array.from(nodes); + function collectNodes(id2) { + if (seen.has(id2)) + return; + seen.add(id2); + var entity = graph.hasEntity(id2); + if (!entity) + return; + if (entity.type === "node") { + nodes.add(entity); + } else if (entity.type === "way") { + entity.nodes.forEach(collectNodes); + } else { + entity.members.map(function(member) { + return member.id; + }).forEach(collectNodes); + } } } - osmEntity.way = osmWay; - osmWay.prototype = Object.create(osmEntity.prototype); - Object.assign(osmWay.prototype, { - type: "way", - nodes: [], - copy: function(resolver, copies) { - if (copies[this.id]) - return copies[this.id]; - var copy2 = osmEntity.prototype.copy.call(this, resolver, copies); - var nodes = this.nodes.map(function(id2) { - return resolver.entity(id2).copy(resolver, copies).id; - }); - copy2 = copy2.update({ nodes }); - copies[this.id] = copy2; - return copy2; - }, - extent: function(resolver) { - return resolver.transient(this, "extent", function() { - var extent = geoExtent(); - for (var i2 = 0; i2 < this.nodes.length; i2++) { - var node = resolver.hasEntity(this.nodes[i2]); - if (node) { - extent._extend(node.extent()); - } - } - return extent; - }); - }, - first: function() { - return this.nodes[0]; - }, - last: function() { - return this.nodes[this.nodes.length - 1]; - }, - contains: function(node) { - return this.nodes.indexOf(node) >= 0; - }, - affix: function(node) { - if (this.nodes[0] === node) - return "prefix"; - if (this.nodes[this.nodes.length - 1] === node) - return "suffix"; - }, - layer: function() { - if (isFinite(this.tags.layer)) { - return Math.max(-10, Math.min(+this.tags.layer, 10)); - } - if (this.tags.covered === "yes") - return -1; - if (this.tags.location === "overground") - return 1; - if (this.tags.location === "underground") - return -1; - if (this.tags.location === "underwater") - return -10; - if (this.tags.power === "line") - return 10; - if (this.tags.power === "minor_line") - return 10; - if (this.tags.aerialway) - return 10; - if (this.tags.bridge) - return 1; - if (this.tags.cutting) - return -1; - if (this.tags.tunnel) - return -1; - if (this.tags.waterway) - return -1; - if (this.tags.man_made === "pipeline") - return -10; - if (this.tags.boundary) - return -10; - return 0; - }, - impliedLineWidthMeters: function() { - var averageWidths = { - highway: { - motorway: 5, - motorway_link: 5, - trunk: 4.5, - trunk_link: 4.5, - primary: 4, - secondary: 4, - tertiary: 4, - primary_link: 4, - secondary_link: 4, - tertiary_link: 4, - unclassified: 4, - road: 4, - living_street: 4, - bus_guideway: 4, - pedestrian: 4, - residential: 3.5, - service: 3.5, - track: 3, - cycleway: 2.5, - bridleway: 2, - corridor: 2, - steps: 2, - path: 1.5, - footway: 1.5 - }, - railway: { - rail: 2.5, - light_rail: 2.5, - tram: 2.5, - subway: 2.5, - monorail: 2.5, - funicular: 2.5, - disused: 2.5, - preserved: 2.5, - miniature: 1.5, - narrow_gauge: 1.5 - }, - waterway: { - river: 50, - canal: 25, - stream: 5, - tidal_channel: 5, - fish_pass: 2.5, - drain: 2.5, - ditch: 1.5 - } - }; - for (var key in averageWidths) { - if (this.tags[key] && averageWidths[key][this.tags[key]]) { - var width = averageWidths[key][this.tags[key]]; - if (key === "highway") { - var laneCount = this.tags.lanes && parseInt(this.tags.lanes, 10); - if (!laneCount) - laneCount = this.isOneWay() ? 1 : 2; - return width * laneCount; - } - return width; - } - } - return null; - }, - isOneWay: function() { - var values = { - "yes": true, - "1": true, - "-1": true, - "reversible": true, - "alternating": true, - "no": false, - "0": false - }; - if (values[this.tags.oneway] !== void 0) { - return values[this.tags.oneway]; - } - for (var key in this.tags) { - if (key in osmOneWayTags && this.tags[key] in osmOneWayTags[key]) { - return true; + function utilDisplayName(entity) { + var localizedNameKey = "name:" + _mainLocalizer.languageCode().toLowerCase(); + var name = entity.tags[localizedNameKey] || entity.tags.name || ""; + if (name) + return name; + var tags = { + direction: entity.tags.direction, + from: entity.tags.from, + network: entity.tags.cycle_network || entity.tags.network, + ref: entity.tags.ref, + to: entity.tags.to, + via: entity.tags.via + }; + var keyComponents = []; + if (tags.network) { + keyComponents.push("network"); + } + if (tags.ref) { + keyComponents.push("ref"); + } + if (entity.tags.route) { + if (tags.direction) { + keyComponents.push("direction"); + } else if (tags.from && tags.to) { + keyComponents.push("from"); + keyComponents.push("to"); + if (tags.via) { + keyComponents.push("via"); } } - return false; - }, - sidednessIdentifier: function() { - for (var key in this.tags) { - var value = this.tags[key]; - if (key in osmRightSideIsInsideTags && value in osmRightSideIsInsideTags[key]) { - if (osmRightSideIsInsideTags[key][value] === true) { - return key; + } + if (keyComponents.length) { + name = _t("inspector.display_name." + keyComponents.join("_"), tags); + } + return name; + } + function utilDisplayNameForPath(entity) { + var name = utilDisplayName(entity); + var isFirefox = utilDetect().browser.toLowerCase().indexOf("firefox") > -1; + var isNewChromium = Number(utilDetect().version.split(".")[0]) >= 96; + if (!isFirefox && !isNewChromium && name && rtlRegex.test(name)) { + name = fixRTLTextForSvg(name); + } + return name; + } + function utilDisplayType(id2) { + return { + n: _t("inspector.node"), + w: _t("inspector.way"), + r: _t("inspector.relation") + }[id2.charAt(0)]; + } + function utilDisplayLabel(entity, graphOrGeometry, verbose) { + var result; + var displayName = utilDisplayName(entity); + var preset = typeof graphOrGeometry === "string" ? _mainPresetIndex.matchTags(entity.tags, graphOrGeometry) : _mainPresetIndex.match(entity, graphOrGeometry); + var presetName = preset && (preset.suggestion ? preset.subtitle() : preset.name()); + if (verbose) { + result = [presetName, displayName].filter(Boolean).join(" "); + } else { + result = displayName || presetName; + } + return result || utilDisplayType(entity.id); + } + function utilEntityRoot(entityType) { + return { + node: "n", + way: "w", + relation: "r" + }[entityType]; + } + function utilCombinedTags(entityIDs, graph) { + var tags = {}; + var tagCounts = {}; + var allKeys = /* @__PURE__ */ new Set(); + var entities = entityIDs.map(function(entityID) { + return graph.hasEntity(entityID); + }).filter(Boolean); + entities.forEach(function(entity) { + var keys2 = Object.keys(entity.tags).filter(Boolean); + keys2.forEach(function(key2) { + allKeys.add(key2); + }); + }); + entities.forEach(function(entity) { + allKeys.forEach(function(key2) { + var value = entity.tags[key2]; + if (!tags.hasOwnProperty(key2)) { + tags[key2] = value; + } else { + if (!Array.isArray(tags[key2])) { + if (tags[key2] !== value) { + tags[key2] = [tags[key2], value]; + } } else { - return osmRightSideIsInsideTags[key][value]; + if (tags[key2].indexOf(value) === -1) { + tags[key2].push(value); + } } } - } - return null; - }, - isSided: function() { - if (this.tags.two_sided === "yes") { - return false; - } - return this.sidednessIdentifier() !== null; - }, - lanes: function() { - return osmLanes(this); - }, - isClosed: function() { - return this.nodes.length > 1 && this.first() === this.last(); - }, - isConvex: function(resolver) { - if (!this.isClosed() || this.isDegenerate()) - return null; - var nodes = utilArrayUniq(resolver.childNodes(this)); - var coords = nodes.map(function(n2) { - return n2.loc; + var tagHash = key2 + "=" + value; + if (!tagCounts[tagHash]) + tagCounts[tagHash] = 0; + tagCounts[tagHash] += 1; }); - var curr = 0; - var prev = 0; - for (var i2 = 0; i2 < coords.length; i2++) { - var o = coords[(i2 + 1) % coords.length]; - var a = coords[i2]; - var b = coords[(i2 + 2) % coords.length]; - var res = geoVecCross(a, b, o); - curr = res > 0 ? 1 : res < 0 ? -1 : 0; - if (curr === 0) { - continue; - } else if (prev && curr !== prev) { - return false; - } - prev = curr; - } - return true; - }, - tagSuggestingArea: function() { - return osmTagSuggestingArea(this.tags); - }, - isArea: function() { - if (this.tags.area === "yes") - return true; - if (!this.isClosed() || this.tags.area === "no") - return false; - return this.tagSuggestingArea() !== null; - }, - isDegenerate: function() { - return new Set(this.nodes).size < (this.isArea() ? 3 : 2); - }, - areAdjacent: function(n1, n2) { - for (var i2 = 0; i2 < this.nodes.length; i2++) { - if (this.nodes[i2] === n1) { - if (this.nodes[i2 - 1] === n2) - return true; - if (this.nodes[i2 + 1] === n2) - return true; + }); + for (var key in tags) { + if (!Array.isArray(tags[key])) + continue; + tags[key] = tags[key].sort(function(val12, val2) { + var key2 = key2; + var count2 = tagCounts[key2 + "=" + val2]; + var count1 = tagCounts[key2 + "=" + val12]; + if (count2 !== count1) { + return count2 - count1; } - } - return false; - }, - geometry: function(graph) { - return graph.transient(this, "geometry", function() { - return this.isArea() ? "area" : "line"; - }); - }, - segments: function(graph) { - function segmentExtent(graph2) { - var n1 = graph2.hasEntity(this.nodes[0]); - var n2 = graph2.hasEntity(this.nodes[1]); - return n1 && n2 && geoExtent([ - [ - Math.min(n1.loc[0], n2.loc[0]), - Math.min(n1.loc[1], n2.loc[1]) - ], - [ - Math.max(n1.loc[0], n2.loc[0]), - Math.max(n1.loc[1], n2.loc[1]) - ] - ]); - } - return graph.transient(this, "segments", function() { - var segments = []; - for (var i2 = 0; i2 < this.nodes.length - 1; i2++) { - segments.push({ - id: this.id + "-" + i2, - wayId: this.id, - index: i2, - nodes: [this.nodes[i2], this.nodes[i2 + 1]], - extent: segmentExtent - }); + if (val2 && val12) { + return val12.localeCompare(val2); } - return segments; + return val12 ? 1 : -1; }); - }, - close: function() { - if (this.isClosed() || !this.nodes.length) - return this; - var nodes = this.nodes.slice(); - nodes = nodes.filter(noRepeatNodes); - nodes.push(nodes[0]); - return this.update({ nodes }); - }, - unclose: function() { - if (!this.isClosed()) - return this; - var nodes = this.nodes.slice(); - var connector = this.first(); - var i2 = nodes.length - 1; - while (i2 > 0 && nodes.length > 1 && nodes[i2] === connector) { - nodes.splice(i2, 1); - i2 = nodes.length - 1; - } - nodes = nodes.filter(noRepeatNodes); - return this.update({ nodes }); - }, - addNode: function(id2, index) { - var nodes = this.nodes.slice(); - var isClosed = this.isClosed(); - var max3 = isClosed ? nodes.length - 1 : nodes.length; - if (index === void 0) { - index = max3; - } - if (index < 0 || index > max3) { - throw new RangeError("index " + index + " out of range 0.." + max3); - } - if (isClosed) { - var connector = this.first(); - var i2 = 1; - while (i2 < nodes.length && nodes.length > 2 && nodes[i2] === connector) { - nodes.splice(i2, 1); - if (index > i2) - index--; - } - i2 = nodes.length - 1; - while (i2 > 0 && nodes.length > 1 && nodes[i2] === connector) { - nodes.splice(i2, 1); - if (index > i2) - index--; - i2 = nodes.length - 1; - } - } - nodes.splice(index, 0, id2); - nodes = nodes.filter(noRepeatNodes); - if (isClosed && (nodes.length === 1 || nodes[0] !== nodes[nodes.length - 1])) { - nodes.push(nodes[0]); - } - return this.update({ nodes }); - }, - updateNode: function(id2, index) { - var nodes = this.nodes.slice(); - var isClosed = this.isClosed(); - var max3 = nodes.length - 1; - if (index === void 0 || index < 0 || index > max3) { - throw new RangeError("index " + index + " out of range 0.." + max3); + } + return tags; + } + function utilStringQs(str2) { + var i2 = 0; + while (i2 < str2.length && (str2[i2] === "?" || str2[i2] === "#")) + i2++; + str2 = str2.slice(i2); + return str2.split("&").reduce(function(obj, pair2) { + var parts = pair2.split("="); + if (parts.length === 2) { + obj[parts[0]] = null === parts[1] ? "" : decodeURIComponent(parts[1]); } - if (isClosed) { - var connector = this.first(); - var i2 = 1; - while (i2 < nodes.length && nodes.length > 2 && nodes[i2] === connector) { - nodes.splice(i2, 1); - if (index > i2) - index--; - } - i2 = nodes.length - 1; - while (i2 > 0 && nodes.length > 1 && nodes[i2] === connector) { - nodes.splice(i2, 1); - if (index === i2) - index = 0; - i2 = nodes.length - 1; - } + return obj; + }, {}); + } + function utilQsString(obj, noencode) { + function softEncode(s) { + return encodeURIComponent(s).replace(/(%2F|%3A|%2C|%7B|%7D)/g, decodeURIComponent); + } + return Object.keys(obj).sort().map(function(key) { + return encodeURIComponent(key) + "=" + (noencode ? softEncode(obj[key]) : encodeURIComponent(obj[key])); + }).join("&"); + } + function utilPrefixDOMProperty(property) { + var prefixes2 = ["webkit", "ms", "moz", "o"]; + var i2 = -1; + var n2 = prefixes2.length; + var s = document.body; + if (property in s) + return property; + property = property.slice(0, 1).toUpperCase() + property.slice(1); + while (++i2 < n2) { + if (prefixes2[i2] + property in s) { + return prefixes2[i2] + property; } - nodes.splice(index, 1, id2); - nodes = nodes.filter(noRepeatNodes); - if (isClosed && (nodes.length === 1 || nodes[0] !== nodes[nodes.length - 1])) { - nodes.push(nodes[0]); + } + return false; + } + function utilPrefixCSSProperty(property) { + var prefixes2 = ["webkit", "ms", "Moz", "O"]; + var i2 = -1; + var n2 = prefixes2.length; + var s = document.body.style; + if (property.toLowerCase() in s) { + return property.toLowerCase(); + } + while (++i2 < n2) { + if (prefixes2[i2] + property in s) { + return "-" + prefixes2[i2].toLowerCase() + property.replace(/([A-Z])/g, "-$1").toLowerCase(); } - return this.update({ nodes }); - }, - replaceNode: function(needleID, replacementID) { - var nodes = this.nodes.slice(); - var isClosed = this.isClosed(); - for (var i2 = 0; i2 < nodes.length; i2++) { - if (nodes[i2] === needleID) { - nodes[i2] = replacementID; + } + return false; + } + var transformProperty; + function utilSetTransform(el, x, y, scale) { + var prop = transformProperty = transformProperty || utilPrefixCSSProperty("Transform"); + var translate = utilDetect().opera ? "translate(" + x + "px," + y + "px)" : "translate3d(" + x + "px," + y + "px,0)"; + return el.style(prop, translate + (scale ? " scale(" + scale + ")" : "")); + } + function utilEditDistance(a, b) { + a = (0, import_diacritics.remove)(a.toLowerCase()); + b = (0, import_diacritics.remove)(b.toLowerCase()); + if (a.length === 0) + return b.length; + if (b.length === 0) + return a.length; + var matrix = []; + var i2, j2; + for (i2 = 0; i2 <= b.length; i2++) { + matrix[i2] = [i2]; + } + for (j2 = 0; j2 <= a.length; j2++) { + matrix[0][j2] = j2; + } + for (i2 = 1; i2 <= b.length; i2++) { + for (j2 = 1; j2 <= a.length; j2++) { + if (b.charAt(i2 - 1) === a.charAt(j2 - 1)) { + matrix[i2][j2] = matrix[i2 - 1][j2 - 1]; + } else { + matrix[i2][j2] = Math.min( + matrix[i2 - 1][j2 - 1] + 1, + // substitution + Math.min( + matrix[i2][j2 - 1] + 1, + // insertion + matrix[i2 - 1][j2] + 1 + ) + ); } } - nodes = nodes.filter(noRepeatNodes); - if (isClosed && (nodes.length === 1 || nodes[0] !== nodes[nodes.length - 1])) { - nodes.push(nodes[0]); - } - return this.update({ nodes }); - }, - removeNode: function(id2) { - var nodes = this.nodes.slice(); - var isClosed = this.isClosed(); - nodes = nodes.filter(function(node) { - return node !== id2; - }).filter(noRepeatNodes); - if (isClosed && (nodes.length === 1 || nodes[0] !== nodes[nodes.length - 1])) { - nodes.push(nodes[0]); - } - return this.update({ nodes }); - }, - asJXON: function(changeset_id) { - var r = { - way: { - "@id": this.osmId(), - "@version": this.version || 0, - nd: this.nodes.map(function(id2) { - return { keyAttributes: { ref: osmEntity.id.toOSM(id2) } }; - }, this), - tag: Object.keys(this.tags).map(function(k) { - return { keyAttributes: { k, v: this.tags[k] } }; - }, this) - } - }; - if (changeset_id) { - r.way["@changeset"] = changeset_id; - } - return r; - }, - asGeoJSON: function(resolver) { - return resolver.transient(this, "GeoJSON", function() { - var coordinates = resolver.childNodes(this).map(function(n2) { - return n2.loc; - }); - if (this.isArea() && this.isClosed()) { - return { - type: "Polygon", - coordinates: [coordinates] - }; - } else { - return { - type: "LineString", - coordinates - }; - } - }); - }, - area: function(resolver) { - return resolver.transient(this, "area", function() { - var nodes = resolver.childNodes(this); - var json = { - type: "Polygon", - coordinates: [nodes.map(function(n2) { - return n2.loc; - })] - }; - if (!this.isClosed() && nodes.length) { - json.coordinates[0].push(nodes[0].loc); - } - var area = area_default(json); - if (area > 2 * Math.PI) { - json.coordinates[0] = json.coordinates[0].reverse(); - area = area_default(json); - } - return isNaN(area) ? 0 : area; - }); } - }); - function noRepeatNodes(node, i2, arr) { - return i2 === 0 || node !== arr[i2 - 1]; + return matrix[b.length][a.length]; } - - // modules/osm/multipolygon.js - function osmOldMultipolygonOuterMemberOfRelation(entity, graph) { - if (entity.type !== "relation" || !entity.isMultipolygon() || Object.keys(entity.tags).filter(osmIsInterestingTag).length > 1) { - return false; - } - var outerMember; - for (var memberIndex in entity.members) { - var member = entity.members[memberIndex]; - if (!member.role || member.role === "outer") { - if (outerMember) - return false; - if (member.type !== "way") - return false; - if (!graph.hasEntity(member.id)) - return false; - outerMember = graph.entity(member.id); - if (Object.keys(outerMember.tags).filter(osmIsInterestingTag).length === 0) { - return false; - } - } + function utilFastMouse(container) { + var rect = container.getBoundingClientRect(); + var rectLeft = rect.left; + var rectTop = rect.top; + var clientLeft = +container.clientLeft; + var clientTop = +container.clientTop; + return function(e) { + return [ + e.clientX - rectLeft - clientLeft, + e.clientY - rectTop - clientTop + ]; + }; + } + function utilAsyncMap(inputs, func, callback) { + var remaining = inputs.length; + var results = []; + var errors = []; + inputs.forEach(function(d, i2) { + func(d, function done(err, data) { + errors[i2] = err; + results[i2] = data; + remaining--; + if (!remaining) + callback(errors, results); + }); + }); + } + function utilWrap(index, length) { + if (index < 0) { + index += Math.ceil(-index / length) * length; } - return outerMember; + return index % length; } - function osmIsOldMultipolygonOuterMember(entity, graph) { - if (entity.type !== "way" || Object.keys(entity.tags).filter(osmIsInterestingTag).length === 0) { - return false; + function utilFunctor(value) { + if (typeof value === "function") + return value; + return function() { + return value; + }; + } + function utilNoAuto(selection2) { + var isText = selection2.size() && selection2.node().tagName.toLowerCase() === "textarea"; + return selection2.attr("autocomplete", "new-password").attr("autocorrect", "off").attr("autocapitalize", "off").attr("spellcheck", isText ? "true" : "false"); + } + function utilHashcode(str2) { + var hash = 0; + if (str2.length === 0) { + return hash; } - var parents = graph.parentRelations(entity); - if (parents.length !== 1) - return false; - var parent = parents[0]; - if (!parent.isMultipolygon() || Object.keys(parent.tags).filter(osmIsInterestingTag).length > 1) { - return false; + for (var i2 = 0; i2 < str2.length; i2++) { + var char = str2.charCodeAt(i2); + hash = (hash << 5) - hash + char; + hash = hash & hash; } - var members = parent.members, member; - for (var i2 = 0; i2 < members.length; i2++) { - member = members[i2]; - if (member.id === entity.id && member.role && member.role !== "outer") { - return false; - } - if (member.id !== entity.id && (!member.role || member.role === "outer")) { - return false; - } + return hash; + } + function utilSafeClassName(str2) { + return str2.toLowerCase().replace(/[^a-z0-9]+/g, "_"); + } + function utilUniqueDomId(val) { + return "ideditor-" + utilSafeClassName(val.toString()) + "-" + (/* @__PURE__ */ new Date()).getTime().toString(); + } + function utilUnicodeCharsCount(str2) { + return Array.from(str2).length; + } + function utilUnicodeCharsTruncated(str2, limit) { + return Array.from(str2).slice(0, limit).join(""); + } + function toNumericID(id2) { + var match = id2.match(/^[cnwr](-?\d+)$/); + if (match) { + return parseInt(match[1], 10); } - return parent; + return NaN; } - function osmOldMultipolygonOuterMember(entity, graph) { - if (entity.type !== "way") - return false; - var parents = graph.parentRelations(entity); - if (parents.length !== 1) - return false; - var parent = parents[0]; - if (!parent.isMultipolygon() || Object.keys(parent.tags).filter(osmIsInterestingTag).length > 1) { - return false; + function compareNumericIDs(left, right) { + if (isNaN(left) && isNaN(right)) + return -1; + if (isNaN(left)) + return 1; + if (isNaN(right)) + return -1; + if (Math.sign(left) !== Math.sign(right)) + return -Math.sign(left); + if (Math.sign(left) < 0) + return Math.sign(right - left); + return Math.sign(left - right); + } + function utilCompareIDs(left, right) { + return compareNumericIDs(toNumericID(left), toNumericID(right)); + } + function utilOldestID(ids) { + if (ids.length === 0) { + return void 0; } - var members = parent.members, member, outerMember; - for (var i2 = 0; i2 < members.length; i2++) { - member = members[i2]; - if (!member.role || member.role === "outer") { - if (outerMember) - return false; - outerMember = member; + var oldestIDIndex = 0; + var oldestID = toNumericID(ids[0]); + for (var i2 = 1; i2 < ids.length; i2++) { + var num = toNumericID(ids[i2]); + if (compareNumericIDs(oldestID, num) === 1) { + oldestIDIndex = i2; + oldestID = num; } } - if (!outerMember) - return false; - var outerEntity = graph.hasEntity(outerMember.id); - if (!outerEntity || !Object.keys(outerEntity.tags).filter(osmIsInterestingTag).length) { - return false; - } - return outerEntity; + return ids[oldestIDIndex]; } - function osmJoinWays(toJoin, graph) { - function resolve(member) { - return graph.childNodes(graph.entity(member.id)); + function utilCleanOsmString(val, maxChars) { + if (val === void 0 || val === null) { + val = ""; + } else { + val = val.toString(); } - function reverse(item2) { - var action = actionReverse(item2.id, { reverseOneway: true }); - sequences.actions.push(action); - return item2 instanceof osmWay ? action(graph).entity(item2.id) : item2; + val = val.trim(); + if (val.normalize) + val = val.normalize("NFC"); + return utilUnicodeCharsTruncated(val, maxChars); + } + + // modules/osm/entity.js + function osmEntity(attrs) { + if (this instanceof osmEntity) + return; + if (attrs && attrs.type) { + return osmEntity[attrs.type].apply(this, arguments); + } else if (attrs && attrs.id) { + return osmEntity[osmEntity.id.type(attrs.id)].apply(this, arguments); } - toJoin = toJoin.filter(function(member) { - return member.type === "way" && graph.hasEntity(member.id); - }); - var i2; - var joinAsMembers = true; - for (i2 = 0; i2 < toJoin.length; i2++) { - if (toJoin[i2] instanceof osmWay) { - joinAsMembers = false; - break; - } + return new osmEntity().initialize(arguments); + } + osmEntity.id = function(type2) { + return osmEntity.id.fromOSM(type2, osmEntity.id.next[type2]--); + }; + osmEntity.id.next = { + changeset: -1, + node: -1, + way: -1, + relation: -1 + }; + osmEntity.id.fromOSM = function(type2, id2) { + return type2[0] + id2; + }; + osmEntity.id.toOSM = function(id2) { + var match = id2.match(/^[cnwr](-?\d+)$/); + if (match) { + return match[1]; } - var sequences = []; - sequences.actions = []; - while (toJoin.length) { - var item = toJoin.shift(); - var currWays = [item]; - var currNodes = resolve(item).slice(); - while (toJoin.length) { - var start2 = currNodes[0]; - var end = currNodes[currNodes.length - 1]; - var fn = null; - var nodes = null; - for (i2 = 0; i2 < toJoin.length; i2++) { - item = toJoin[i2]; - nodes = resolve(item); - if (joinAsMembers && currWays.length === 1 && nodes[0] !== end && nodes[nodes.length - 1] !== end && (nodes[nodes.length - 1] === start2 || nodes[0] === start2)) { - currWays[0] = reverse(currWays[0]); - currNodes.reverse(); - start2 = currNodes[0]; - end = currNodes[currNodes.length - 1]; - } - if (nodes[0] === end) { - fn = currNodes.push; - nodes = nodes.slice(1); - break; - } else if (nodes[nodes.length - 1] === end) { - fn = currNodes.push; - nodes = nodes.slice(0, -1).reverse(); - item = reverse(item); - break; - } else if (nodes[nodes.length - 1] === start2) { - fn = currNodes.unshift; - nodes = nodes.slice(0, -1); - break; - } else if (nodes[0] === start2) { - fn = currNodes.unshift; - nodes = nodes.slice(1).reverse(); - item = reverse(item); - break; - } else { - fn = nodes = null; + return ""; + }; + osmEntity.id.type = function(id2) { + return { "c": "changeset", "n": "node", "w": "way", "r": "relation" }[id2[0]]; + }; + osmEntity.key = function(entity) { + return entity.id + "v" + (entity.v || 0); + }; + var _deprecatedTagValuesByKey; + osmEntity.deprecatedTagValuesByKey = function(dataDeprecated) { + if (!_deprecatedTagValuesByKey) { + _deprecatedTagValuesByKey = {}; + dataDeprecated.forEach(function(d) { + var oldKeys = Object.keys(d.old); + if (oldKeys.length === 1) { + var oldKey = oldKeys[0]; + var oldValue = d.old[oldKey]; + if (oldValue !== "*") { + if (!_deprecatedTagValuesByKey[oldKey]) { + _deprecatedTagValuesByKey[oldKey] = [oldValue]; + } else { + _deprecatedTagValuesByKey[oldKey].push(oldValue); + } } } - if (!nodes) { - break; - } - fn.apply(currWays, [item]); - fn.apply(currNodes, nodes); - toJoin.splice(i2, 1); - } - currWays.nodes = currNodes; - sequences.push(currWays); + }); } - return sequences; - } - - // modules/actions/add_member.js - function actionAddMember(relationId, member, memberIndex, insertPair) { - return function action(graph) { - var relation = graph.entity(relationId); - var isPTv2 = /stop|platform/.test(member.role); - if ((isNaN(memberIndex) || insertPair) && member.type === "way" && !isPTv2) { - graph = addWayMember(relation, graph); - } else { - if (isPTv2 && isNaN(memberIndex)) { - memberIndex = 0; - } - graph = graph.replace(relation.addMember(member, memberIndex)); - } - return graph; - }; - function addWayMember(relation, graph) { - var groups, tempWay, insertPairIsReversed, item, i2, j2, k; - var PTv2members = []; - var members = []; - for (i2 = 0; i2 < relation.members.length; i2++) { - var m = relation.members[i2]; - if (/stop|platform/.test(m.role)) { - PTv2members.push(m); - } else { - members.push(m); - } - } - relation = relation.update({ members }); - if (insertPair) { - tempWay = osmWay({ id: "wTemp", nodes: insertPair.nodes }); - graph = graph.replace(tempWay); - var tempMember = { id: tempWay.id, type: "way", role: member.role }; - var tempRelation = relation.replaceMember({ id: insertPair.originalID }, tempMember, true); - groups = utilArrayGroupBy(tempRelation.members, "type"); - groups.way = groups.way || []; - var originalWay = graph.entity(insertPair.originalID); - var insertedWay = graph.entity(insertPair.insertedID); - insertPairIsReversed = originalWay.nodes.length > 0 && insertedWay.nodes.length > 0 && insertedWay.nodes[insertedWay.nodes.length - 1] === originalWay.nodes[0] && originalWay.nodes[originalWay.nodes.length - 1] !== insertedWay.nodes[0]; - } else { - groups = utilArrayGroupBy(relation.members, "type"); - groups.way = groups.way || []; - groups.way.push(member); - } - members = withIndex(groups.way); - var joined = osmJoinWays(members, graph); - for (i2 = 0; i2 < joined.length; i2++) { - var segment = joined[i2]; - var nodes = segment.nodes.slice(); - var startIndex = segment[0].index; - for (j2 = 0; j2 < members.length; j2++) { - if (members[j2].index === startIndex) { - break; - } - } - for (k = 0; k < segment.length; k++) { - item = segment[k]; - var way = graph.entity(item.id); - if (tempWay && item.id === tempWay.id) { - var reverse = nodes[0].id !== insertPair.nodes[0] ^ insertPairIsReversed; - if (reverse) { - item.pair = [ - { id: insertPair.insertedID, type: "way", role: item.role }, - { id: insertPair.originalID, type: "way", role: item.role } - ]; + return _deprecatedTagValuesByKey; + }; + osmEntity.prototype = { + tags: {}, + initialize: function(sources) { + for (var i2 = 0; i2 < sources.length; ++i2) { + var source = sources[i2]; + for (var prop in source) { + if (Object.prototype.hasOwnProperty.call(source, prop)) { + if (source[prop] === void 0) { + delete this[prop]; } else { - item.pair = [ - { id: insertPair.originalID, type: "way", role: item.role }, - { id: insertPair.insertedID, type: "way", role: item.role } - ]; - } - } - if (k > 0) { - if (j2 + k >= members.length || item.index !== members[j2 + k].index) { - moveMember(members, item.index, j2 + k); + this[prop] = source[prop]; } } - nodes.splice(0, way.nodes.length - 1); } } - if (tempWay) { - graph = graph.remove(tempWay); + if (!this.id && this.type) { + this.id = osmEntity.id(this.type); } - var wayMembers = []; - for (i2 = 0; i2 < members.length; i2++) { - item = members[i2]; - if (item.index === -1) - continue; - if (item.pair) { - wayMembers.push(item.pair[0]); - wayMembers.push(item.pair[1]); - } else { - wayMembers.push(utilObjectOmit(item, ["index"])); - } + if (!this.hasOwnProperty("visible")) { + this.visible = true; } - var newMembers = PTv2members.concat(groups.node || [], wayMembers, groups.relation || []); - return graph.replace(relation.update({ members: newMembers })); - function moveMember(arr, findIndex, toIndex) { - var i3; - for (i3 = 0; i3 < arr.length; i3++) { - if (arr[i3].index === findIndex) { - break; - } - } - var item2 = Object.assign({}, arr[i3]); - arr[i3].index = -1; - item2.index = toIndex; - arr.splice(toIndex, 0, item2); + if (debug) { + Object.freeze(this); + Object.freeze(this.tags); + if (this.loc) + Object.freeze(this.loc); + if (this.nodes) + Object.freeze(this.nodes); + if (this.members) + Object.freeze(this.members); } - function withIndex(arr) { - var result = new Array(arr.length); - for (var i3 = 0; i3 < arr.length; i3++) { - result[i3] = Object.assign({}, arr[i3]); - result[i3].index = i3; + return this; + }, + copy: function(resolver, copies) { + if (copies[this.id]) + return copies[this.id]; + var copy2 = osmEntity(this, { id: void 0, user: void 0, version: void 0 }); + copies[this.id] = copy2; + return copy2; + }, + osmId: function() { + return osmEntity.id.toOSM(this.id); + }, + isNew: function() { + var osmId = osmEntity.id.toOSM(this.id); + return osmId.length === 0 || osmId[0] === "-"; + }, + update: function(attrs) { + return osmEntity(this, attrs, { v: 1 + (this.v || 0) }); + }, + mergeTags: function(tags) { + var merged = Object.assign({}, this.tags); + var changed = false; + for (var k in tags) { + var t1 = merged[k]; + var t2 = tags[k]; + if (!t1) { + changed = true; + merged[k] = t2; + } else if (t1 !== t2) { + changed = true; + merged[k] = utilUnicodeCharsTruncated( + utilArrayUnion(t1.split(/;\s*/), t2.split(/;\s*/)).join(";"), + 255 + // avoid exceeding character limit; see also context.maxCharsForTagValue() + ); } - return result; } - } - } - - // modules/actions/add_midpoint.js - function actionAddMidpoint(midpoint, node) { - return function(graph) { - graph = graph.replace(node.move(midpoint.loc)); - var parents = utilArrayIntersection( - graph.parentWays(graph.entity(midpoint.edge[0])), - graph.parentWays(graph.entity(midpoint.edge[1])) - ); - parents.forEach(function(way) { - for (var i2 = 0; i2 < way.nodes.length - 1; i2++) { - if (geoEdgeEqual([way.nodes[i2], way.nodes[i2 + 1]], midpoint.edge)) { - graph = graph.replace(graph.entity(way.id).addNode(node.id, i2 + 1)); + return changed ? this.update({ tags: merged }) : this; + }, + intersects: function(extent, resolver) { + return this.extent(resolver).intersects(extent); + }, + hasNonGeometryTags: function() { + return Object.keys(this.tags).some(function(k) { + return k !== "area"; + }); + }, + hasParentRelations: function(resolver) { + return resolver.parentRelations(this).length > 0; + }, + hasInterestingTags: function() { + return Object.keys(this.tags).some(osmIsInterestingTag); + }, + isHighwayIntersection: function() { + return false; + }, + isDegenerate: function() { + return true; + }, + deprecatedTags: function(dataDeprecated) { + var tags = this.tags; + if (Object.keys(tags).length === 0) + return []; + var deprecated = []; + dataDeprecated.forEach(function(d) { + var oldKeys = Object.keys(d.old); + if (d.replace) { + var hasExistingValues = Object.keys(d.replace).some(function(replaceKey) { + if (!tags[replaceKey] || d.old[replaceKey]) + return false; + var replaceValue = d.replace[replaceKey]; + if (replaceValue === "*") + return false; + if (replaceValue === tags[replaceKey]) + return false; + return true; + }); + if (hasExistingValues) return; + } + var matchesDeprecatedTags = oldKeys.every(function(oldKey) { + if (!tags[oldKey]) + return false; + if (d.old[oldKey] === "*") + return true; + if (d.old[oldKey] === tags[oldKey]) + return true; + var vals = tags[oldKey].split(";").filter(Boolean); + if (vals.length === 0) { + return false; + } else if (vals.length > 1) { + return vals.indexOf(d.old[oldKey]) !== -1; + } else { + if (tags[oldKey] === d.old[oldKey]) { + if (d.replace && d.old[oldKey] === d.replace[oldKey]) { + var replaceKeys = Object.keys(d.replace); + return !replaceKeys.every(function(replaceKey) { + return tags[replaceKey] === d.replace[replaceKey]; + }); + } else { + return true; + } + } } + return false; + }); + if (matchesDeprecatedTags) { + deprecated.push(d); } }); - return graph; - }; - } + return deprecated; + } + }; - // modules/actions/add_vertex.js - function actionAddVertex(wayId, nodeId, index) { - return function(graph) { - return graph.replace(graph.entity(wayId).addNode(nodeId, index)); + // modules/osm/lanes.js + function osmLanes(entity) { + if (entity.type !== "way") + return null; + if (!entity.tags.highway) + return null; + var tags = entity.tags; + var isOneWay = entity.isOneWay(); + var laneCount = getLaneCount(tags, isOneWay); + var maxspeed = parseMaxspeed(tags); + var laneDirections = parseLaneDirections(tags, isOneWay, laneCount); + var forward = laneDirections.forward; + var backward = laneDirections.backward; + var bothways = laneDirections.bothways; + var turnLanes = {}; + turnLanes.unspecified = parseTurnLanes(tags["turn:lanes"]); + turnLanes.forward = parseTurnLanes(tags["turn:lanes:forward"]); + turnLanes.backward = parseTurnLanes(tags["turn:lanes:backward"]); + var maxspeedLanes = {}; + maxspeedLanes.unspecified = parseMaxspeedLanes(tags["maxspeed:lanes"], maxspeed); + maxspeedLanes.forward = parseMaxspeedLanes(tags["maxspeed:lanes:forward"], maxspeed); + maxspeedLanes.backward = parseMaxspeedLanes(tags["maxspeed:lanes:backward"], maxspeed); + var psvLanes = {}; + psvLanes.unspecified = parseMiscLanes(tags["psv:lanes"]); + psvLanes.forward = parseMiscLanes(tags["psv:lanes:forward"]); + psvLanes.backward = parseMiscLanes(tags["psv:lanes:backward"]); + var busLanes = {}; + busLanes.unspecified = parseMiscLanes(tags["bus:lanes"]); + busLanes.forward = parseMiscLanes(tags["bus:lanes:forward"]); + busLanes.backward = parseMiscLanes(tags["bus:lanes:backward"]); + var taxiLanes = {}; + taxiLanes.unspecified = parseMiscLanes(tags["taxi:lanes"]); + taxiLanes.forward = parseMiscLanes(tags["taxi:lanes:forward"]); + taxiLanes.backward = parseMiscLanes(tags["taxi:lanes:backward"]); + var hovLanes = {}; + hovLanes.unspecified = parseMiscLanes(tags["hov:lanes"]); + hovLanes.forward = parseMiscLanes(tags["hov:lanes:forward"]); + hovLanes.backward = parseMiscLanes(tags["hov:lanes:backward"]); + var hgvLanes = {}; + hgvLanes.unspecified = parseMiscLanes(tags["hgv:lanes"]); + hgvLanes.forward = parseMiscLanes(tags["hgv:lanes:forward"]); + hgvLanes.backward = parseMiscLanes(tags["hgv:lanes:backward"]); + var bicyclewayLanes = {}; + bicyclewayLanes.unspecified = parseBicycleWay(tags["bicycleway:lanes"]); + bicyclewayLanes.forward = parseBicycleWay(tags["bicycleway:lanes:forward"]); + bicyclewayLanes.backward = parseBicycleWay(tags["bicycleway:lanes:backward"]); + var lanesObj = { + forward: [], + backward: [], + unspecified: [] }; - } - - // modules/actions/change_member.js - function actionChangeMember(relationId, member, memberIndex) { - return function(graph) { - return graph.replace(graph.entity(relationId).updateMember(member, memberIndex)); + mapToLanesObj(lanesObj, turnLanes, "turnLane"); + mapToLanesObj(lanesObj, maxspeedLanes, "maxspeed"); + mapToLanesObj(lanesObj, psvLanes, "psv"); + mapToLanesObj(lanesObj, busLanes, "bus"); + mapToLanesObj(lanesObj, taxiLanes, "taxi"); + mapToLanesObj(lanesObj, hovLanes, "hov"); + mapToLanesObj(lanesObj, hgvLanes, "hgv"); + mapToLanesObj(lanesObj, bicyclewayLanes, "bicycleway"); + return { + metadata: { + count: laneCount, + oneway: isOneWay, + forward, + backward, + bothways, + turnLanes, + maxspeed, + maxspeedLanes, + psvLanes, + busLanes, + taxiLanes, + hovLanes, + hgvLanes, + bicyclewayLanes + }, + lanes: lanesObj }; } - - // modules/actions/change_preset.js - function actionChangePreset(entityID, oldPreset, newPreset, skipFieldDefaults) { - return function action(graph) { - var entity = graph.entity(entityID); - var geometry = entity.geometry(graph); - var tags = entity.tags; - if (oldPreset) - tags = oldPreset.unsetTags(tags, geometry, newPreset && newPreset.addTags ? Object.keys(newPreset.addTags) : null); - if (newPreset) - tags = newPreset.setTags(tags, geometry, skipFieldDefaults); - return graph.replace(entity.update({ tags })); - }; + function getLaneCount(tags, isOneWay) { + var count; + if (tags.lanes) { + count = parseInt(tags.lanes, 10); + if (count > 0) { + return count; + } + } + switch (tags.highway) { + case "trunk": + case "motorway": + count = isOneWay ? 2 : 4; + break; + default: + count = isOneWay ? 1 : 2; + break; + } + return count; } - - // modules/actions/change_tags.js - function actionChangeTags(entityId, tags) { - return function(graph) { - var entity = graph.entity(entityId); - return graph.replace(entity.update({ tags })); + function parseMaxspeed(tags) { + var maxspeed = tags.maxspeed; + if (!maxspeed) + return; + var maxspeedRegex = /^([0-9][\.0-9]+?)(?:[ ]?(?:km\/h|kmh|kph|mph|knots))?$/; + if (!maxspeedRegex.test(maxspeed)) + return; + return parseInt(maxspeed, 10); + } + function parseLaneDirections(tags, isOneWay, laneCount) { + var forward = parseInt(tags["lanes:forward"], 10); + var backward = parseInt(tags["lanes:backward"], 10); + var bothways = parseInt(tags["lanes:both_ways"], 10) > 0 ? 1 : 0; + if (parseInt(tags.oneway, 10) === -1) { + forward = 0; + bothways = 0; + backward = laneCount; + } else if (isOneWay) { + forward = laneCount; + bothways = 0; + backward = 0; + } else if (isNaN(forward) && isNaN(backward)) { + backward = Math.floor((laneCount - bothways) / 2); + forward = laneCount - bothways - backward; + } else if (isNaN(forward)) { + if (backward > laneCount - bothways) { + backward = laneCount - bothways; + } + forward = laneCount - bothways - backward; + } else if (isNaN(backward)) { + if (forward > laneCount - bothways) { + forward = laneCount - bothways; + } + backward = laneCount - bothways - forward; + } + return { + forward, + backward, + bothways }; } + function parseTurnLanes(tag) { + if (!tag) + return; + var validValues = [ + "left", + "slight_left", + "sharp_left", + "through", + "right", + "slight_right", + "sharp_right", + "reverse", + "merge_to_left", + "merge_to_right", + "none" + ]; + return tag.split("|").map(function(s) { + if (s === "") + s = "none"; + return s.split(";").map(function(d) { + return validValues.indexOf(d) === -1 ? "unknown" : d; + }); + }); + } + function parseMaxspeedLanes(tag, maxspeed) { + if (!tag) + return; + return tag.split("|").map(function(s) { + if (s === "none") + return s; + var m = parseInt(s, 10); + if (s === "" || m === maxspeed) + return null; + return isNaN(m) ? "unknown" : m; + }); + } + function parseMiscLanes(tag) { + if (!tag) + return; + var validValues = [ + "yes", + "no", + "designated" + ]; + return tag.split("|").map(function(s) { + if (s === "") + s = "no"; + return validValues.indexOf(s) === -1 ? "unknown" : s; + }); + } + function parseBicycleWay(tag) { + if (!tag) + return; + var validValues = [ + "yes", + "no", + "designated", + "lane" + ]; + return tag.split("|").map(function(s) { + if (s === "") + s = "no"; + return validValues.indexOf(s) === -1 ? "unknown" : s; + }); + } + function mapToLanesObj(lanesObj, data, key) { + if (data.forward) { + data.forward.forEach(function(l, i2) { + if (!lanesObj.forward[i2]) + lanesObj.forward[i2] = {}; + lanesObj.forward[i2][key] = l; + }); + } + if (data.backward) { + data.backward.forEach(function(l, i2) { + if (!lanesObj.backward[i2]) + lanesObj.backward[i2] = {}; + lanesObj.backward[i2][key] = l; + }); + } + if (data.unspecified) { + data.unspecified.forEach(function(l, i2) { + if (!lanesObj.unspecified[i2]) + lanesObj.unspecified[i2] = {}; + lanesObj.unspecified[i2][key] = l; + }); + } + } - // modules/osm/node.js - var cardinal = { - north: 0, - n: 0, - northnortheast: 22, - nne: 22, - northeast: 45, - ne: 45, - eastnortheast: 67, - ene: 67, - east: 90, - e: 90, - eastsoutheast: 112, - ese: 112, - southeast: 135, - se: 135, - southsoutheast: 157, - sse: 157, - south: 180, - s: 180, - southsouthwest: 202, - ssw: 202, - southwest: 225, - sw: 225, - westsouthwest: 247, - wsw: 247, - west: 270, - w: 270, - westnorthwest: 292, - wnw: 292, - northwest: 315, - nw: 315, - northnorthwest: 337, - nnw: 337 - }; - function osmNode() { - if (!(this instanceof osmNode)) { - return new osmNode().initialize(arguments); + // modules/osm/way.js + function osmWay() { + if (!(this instanceof osmWay)) { + return new osmWay().initialize(arguments); } else if (arguments.length) { this.initialize(arguments); } } - osmEntity.node = osmNode; - osmNode.prototype = Object.create(osmEntity.prototype); - Object.assign(osmNode.prototype, { - type: "node", - loc: [9999, 9999], - extent: function() { - return new geoExtent(this.loc); - }, - geometry: function(graph) { - return graph.transient(this, "geometry", function() { - return graph.isPoi(this) ? "point" : "vertex"; - }); - }, - move: function(loc) { - return this.update({ loc }); - }, - isDegenerate: function() { - return !(Array.isArray(this.loc) && this.loc.length === 2 && this.loc[0] >= -180 && this.loc[0] <= 180 && this.loc[1] >= -90 && this.loc[1] <= 90); - }, - directions: function(resolver, projection2) { - var val; - var i2; - if (this.isHighwayIntersection(resolver) && (this.tags.stop || "").toLowerCase() === "all") { - val = "all"; - } else { - val = (this.tags.direction || "").toLowerCase(); - var re2 = /:direction$/i; - var keys = Object.keys(this.tags); - for (i2 = 0; i2 < keys.length; i2++) { - if (re2.test(keys[i2])) { - val = this.tags[keys[i2]].toLowerCase(); - break; - } - } - } - if (val === "") - return []; - var values = val.split(";"); - var results = []; - values.forEach(function(v) { - if (cardinal[v] !== void 0) { - v = cardinal[v]; - } - if (v !== "" && !isNaN(+v)) { - results.push(+v); - return; - } - var lookBackward = this.tags["traffic_sign:backward"] || v === "backward" || v === "both" || v === "all"; - var lookForward = this.tags["traffic_sign:forward"] || v === "forward" || v === "both" || v === "all"; - if (!lookForward && !lookBackward) - return; - var nodeIds = {}; - resolver.parentWays(this).forEach(function(parent) { - var nodes = parent.nodes; - for (i2 = 0; i2 < nodes.length; i2++) { - if (nodes[i2] === this.id) { - if (lookForward && i2 > 0) { - nodeIds[nodes[i2 - 1]] = true; - } - if (lookBackward && i2 < nodes.length - 1) { - nodeIds[nodes[i2 + 1]] = true; - } - } - } - }, this); - Object.keys(nodeIds).forEach(function(nodeId) { - results.push( - geoAngle(this, resolver.entity(nodeId), projection2) * (180 / Math.PI) + 90 - ); - }, this); - }, this); - return utilArrayUniq(results); - }, - isCrossing: function() { - return this.tags.highway === "crossing" || this.tags.railway && this.tags.railway.indexOf("crossing") !== -1; - }, - isEndpoint: function(resolver) { - return resolver.transient(this, "isEndpoint", function() { - var id2 = this.id; - return resolver.parentWays(this).filter(function(parent) { - return !parent.isClosed() && !!parent.affix(id2); - }).length > 0; + osmEntity.way = osmWay; + osmWay.prototype = Object.create(osmEntity.prototype); + Object.assign(osmWay.prototype, { + type: "way", + nodes: [], + copy: function(resolver, copies) { + if (copies[this.id]) + return copies[this.id]; + var copy2 = osmEntity.prototype.copy.call(this, resolver, copies); + var nodes = this.nodes.map(function(id2) { + return resolver.entity(id2).copy(resolver, copies).id; }); + copy2 = copy2.update({ nodes }); + copies[this.id] = copy2; + return copy2; }, - isConnected: function(resolver) { - return resolver.transient(this, "isConnected", function() { - var parents = resolver.parentWays(this); - if (parents.length > 1) { - for (var i2 in parents) { - if (parents[i2].geometry(resolver) === "line" && parents[i2].hasInterestingTags()) - return true; - } - } else if (parents.length === 1) { - var way = parents[0]; - var nodes = way.nodes.slice(); - if (way.isClosed()) { - nodes.pop(); + extent: function(resolver) { + return resolver.transient(this, "extent", function() { + var extent = geoExtent(); + for (var i2 = 0; i2 < this.nodes.length; i2++) { + var node = resolver.hasEntity(this.nodes[i2]); + if (node) { + extent._extend(node.extent()); } - return nodes.indexOf(this.id) !== nodes.lastIndexOf(this.id); } - return false; + return extent; }); }, - parentIntersectionWays: function(resolver) { - return resolver.transient(this, "parentIntersectionWays", function() { - return resolver.parentWays(this).filter(function(parent) { - return (parent.tags.highway || parent.tags.waterway || parent.tags.railway || parent.tags.aeroway) && parent.geometry(resolver) === "line"; - }); - }); + first: function() { + return this.nodes[0]; }, - isIntersection: function(resolver) { - return this.parentIntersectionWays(resolver).length > 1; + last: function() { + return this.nodes[this.nodes.length - 1]; }, - isHighwayIntersection: function(resolver) { - return resolver.transient(this, "isHighwayIntersection", function() { - return resolver.parentWays(this).filter(function(parent) { - return parent.tags.highway && parent.geometry(resolver) === "line"; - }).length > 1; - }); + contains: function(node) { + return this.nodes.indexOf(node) >= 0; }, - isOnAddressLine: function(resolver) { - return resolver.transient(this, "isOnAddressLine", function() { - return resolver.parentWays(this).filter(function(parent) { - return parent.tags.hasOwnProperty("addr:interpolation") && parent.geometry(resolver) === "line"; - }).length > 0; - }); + affix: function(node) { + if (this.nodes[0] === node) + return "prefix"; + if (this.nodes[this.nodes.length - 1] === node) + return "suffix"; }, - asJXON: function(changeset_id) { - var r = { - node: { - "@id": this.osmId(), - "@lon": this.loc[0], - "@lat": this.loc[1], - "@version": this.version || 0, - tag: Object.keys(this.tags).map(function(k) { - return { keyAttributes: { k, v: this.tags[k] } }; - }, this) + layer: function() { + if (isFinite(this.tags.layer)) { + return Math.max(-10, Math.min(+this.tags.layer, 10)); + } + if (this.tags.covered === "yes") + return -1; + if (this.tags.location === "overground") + return 1; + if (this.tags.location === "underground") + return -1; + if (this.tags.location === "underwater") + return -10; + if (this.tags.power === "line") + return 10; + if (this.tags.power === "minor_line") + return 10; + if (this.tags.aerialway) + return 10; + if (this.tags.bridge) + return 1; + if (this.tags.cutting) + return -1; + if (this.tags.tunnel) + return -1; + if (this.tags.waterway) + return -1; + if (this.tags.man_made === "pipeline") + return -10; + if (this.tags.boundary) + return -10; + return 0; + }, + // the approximate width of the line based on its tags except its `width` tag + impliedLineWidthMeters: function() { + var averageWidths = { + highway: { + // width is for single lane + motorway: 5, + motorway_link: 5, + trunk: 4.5, + trunk_link: 4.5, + primary: 4, + secondary: 4, + tertiary: 4, + primary_link: 4, + secondary_link: 4, + tertiary_link: 4, + unclassified: 4, + road: 4, + living_street: 4, + bus_guideway: 4, + pedestrian: 4, + residential: 3.5, + service: 3.5, + track: 3, + cycleway: 2.5, + bridleway: 2, + corridor: 2, + steps: 2, + path: 1.5, + footway: 1.5 + }, + railway: { + // width includes ties and rail bed, not just track gauge + rail: 2.5, + light_rail: 2.5, + tram: 2.5, + subway: 2.5, + monorail: 2.5, + funicular: 2.5, + disused: 2.5, + preserved: 2.5, + miniature: 1.5, + narrow_gauge: 1.5 + }, + waterway: { + river: 50, + canal: 25, + stream: 5, + tidal_channel: 5, + fish_pass: 2.5, + drain: 2.5, + ditch: 1.5 } }; - if (changeset_id) - r.node["@changeset"] = changeset_id; - return r; + for (var key in averageWidths) { + if (this.tags[key] && averageWidths[key][this.tags[key]]) { + var width = averageWidths[key][this.tags[key]]; + if (key === "highway") { + var laneCount = this.tags.lanes && parseInt(this.tags.lanes, 10); + if (!laneCount) + laneCount = this.isOneWay() ? 1 : 2; + return width * laneCount; + } + return width; + } + } + return null; }, - asGeoJSON: function() { - return { - type: "Point", - coordinates: this.loc + isOneWay: function() { + var values = { + "yes": true, + "1": true, + "-1": true, + "reversible": true, + "alternating": true, + "no": false, + "0": false }; - } - }); - - // modules/actions/circularize.js - function actionCircularize(wayId, projection2, maxAngle) { - maxAngle = (maxAngle || 20) * Math.PI / 180; - var action = function(graph, t) { - if (t === null || !isFinite(t)) - t = 1; - t = Math.min(Math.max(+t, 0), 1); - var way = graph.entity(wayId); - var origNodes = {}; - graph.childNodes(way).forEach(function(node2) { - if (!origNodes[node2.id]) - origNodes[node2.id] = node2; - }); - if (!way.isConvex(graph)) { - graph = action.makeConvex(graph); - } - var nodes = utilArrayUniq(graph.childNodes(way)); - var keyNodes = nodes.filter(function(n2) { - return graph.parentWays(n2).length !== 1; - }); - var points = nodes.map(function(n2) { - return projection2(n2.loc); - }); - var keyPoints = keyNodes.map(function(n2) { - return projection2(n2.loc); - }); - var centroid = points.length === 2 ? geoVecInterp(points[0], points[1], 0.5) : centroid_default2(points); - var radius = median(points, function(p) { - return geoVecLength(centroid, p); - }); - var sign2 = area_default3(points) > 0 ? 1 : -1; - var ids, i2, j2, k; - if (!keyNodes.length) { - keyNodes = [nodes[0]]; - keyPoints = [points[0]]; - } - if (keyNodes.length === 1) { - var index = nodes.indexOf(keyNodes[0]); - var oppositeIndex = Math.floor((index + nodes.length / 2) % nodes.length); - keyNodes.push(nodes[oppositeIndex]); - keyPoints.push(points[oppositeIndex]); + if (values[this.tags.oneway] !== void 0) { + return values[this.tags.oneway]; } - for (i2 = 0; i2 < keyPoints.length; i2++) { - var nextKeyNodeIndex = (i2 + 1) % keyNodes.length; - var startNode = keyNodes[i2]; - var endNode = keyNodes[nextKeyNodeIndex]; - var startNodeIndex = nodes.indexOf(startNode); - var endNodeIndex = nodes.indexOf(endNode); - var numberNewPoints = -1; - var indexRange = endNodeIndex - startNodeIndex; - var nearNodes = {}; - var inBetweenNodes = []; - var startAngle, endAngle, totalAngle, eachAngle; - var angle2, loc, node, origNode; - if (indexRange < 0) { - indexRange += nodes.length; - } - var distance = geoVecLength(centroid, keyPoints[i2]) || 1e-4; - keyPoints[i2] = [ - centroid[0] + (keyPoints[i2][0] - centroid[0]) / distance * radius, - centroid[1] + (keyPoints[i2][1] - centroid[1]) / distance * radius - ]; - loc = projection2.invert(keyPoints[i2]); - node = keyNodes[i2]; - origNode = origNodes[node.id]; - node = node.move(geoVecInterp(origNode.loc, loc, t)); - graph = graph.replace(node); - startAngle = Math.atan2(keyPoints[i2][1] - centroid[1], keyPoints[i2][0] - centroid[0]); - endAngle = Math.atan2(keyPoints[nextKeyNodeIndex][1] - centroid[1], keyPoints[nextKeyNodeIndex][0] - centroid[0]); - totalAngle = endAngle - startAngle; - if (totalAngle * sign2 > 0) { - totalAngle = -sign2 * (2 * Math.PI - Math.abs(totalAngle)); - } - do { - numberNewPoints++; - eachAngle = totalAngle / (indexRange + numberNewPoints); - } while (Math.abs(eachAngle) > maxAngle); - for (j2 = 1; j2 < indexRange; j2++) { - angle2 = startAngle + j2 * eachAngle; - loc = projection2.invert([ - centroid[0] + Math.cos(angle2) * radius, - centroid[1] + Math.sin(angle2) * radius - ]); - node = nodes[(j2 + startNodeIndex) % nodes.length]; - origNode = origNodes[node.id]; - nearNodes[node.id] = angle2; - node = node.move(geoVecInterp(origNode.loc, loc, t)); - graph = graph.replace(node); - } - for (j2 = 0; j2 < numberNewPoints; j2++) { - angle2 = startAngle + (indexRange + j2) * eachAngle; - loc = projection2.invert([ - centroid[0] + Math.cos(angle2) * radius, - centroid[1] + Math.sin(angle2) * radius - ]); - var min3 = Infinity; - for (var nodeId in nearNodes) { - var nearAngle = nearNodes[nodeId]; - var dist = Math.abs(nearAngle - angle2); - if (dist < min3) { - min3 = dist; - origNode = origNodes[nodeId]; - } - } - node = osmNode({ loc: geoVecInterp(origNode.loc, loc, t) }); - graph = graph.replace(node); - nodes.splice(endNodeIndex + j2, 0, node); - inBetweenNodes.push(node.id); + for (var key in this.tags) { + if (key in osmOneWayTags && this.tags[key] in osmOneWayTags[key]) { + return true; } - if (indexRange === 1 && inBetweenNodes.length) { - var startIndex1 = way.nodes.lastIndexOf(startNode.id); - var endIndex1 = way.nodes.lastIndexOf(endNode.id); - var wayDirection1 = endIndex1 - startIndex1; - if (wayDirection1 < -1) { - wayDirection1 = 1; - } - var parentWays = graph.parentWays(keyNodes[i2]); - for (j2 = 0; j2 < parentWays.length; j2++) { - var sharedWay = parentWays[j2]; - if (sharedWay === way) - continue; - if (sharedWay.areAdjacent(startNode.id, endNode.id)) { - var startIndex2 = sharedWay.nodes.lastIndexOf(startNode.id); - var endIndex2 = sharedWay.nodes.lastIndexOf(endNode.id); - var wayDirection2 = endIndex2 - startIndex2; - var insertAt = endIndex2; - if (wayDirection2 < -1) { - wayDirection2 = 1; - } - if (wayDirection1 !== wayDirection2) { - inBetweenNodes.reverse(); - insertAt = startIndex2; - } - for (k = 0; k < inBetweenNodes.length; k++) { - sharedWay = sharedWay.addNode(inBetweenNodes[k], insertAt + k); - } - graph = graph.replace(sharedWay); - } + } + return false; + }, + // Some identifier for tag that implies that this way is "sided", + // i.e. the right side is the 'inside' (e.g. the right side of a + // natural=cliff is lower). + sidednessIdentifier: function() { + for (const realKey in this.tags) { + const value = this.tags[realKey]; + const key = osmRemoveLifecyclePrefix(realKey); + if (key in osmRightSideIsInsideTags && value in osmRightSideIsInsideTags[key]) { + if (osmRightSideIsInsideTags[key][value] === true) { + return key; + } else { + return osmRightSideIsInsideTags[key][value]; } } } - ids = nodes.map(function(n2) { - return n2.id; - }); - ids.push(ids[0]); - way = way.update({ nodes: ids }); - graph = graph.replace(way); - return graph; - }; - action.makeConvex = function(graph) { - var way = graph.entity(wayId); - var nodes = utilArrayUniq(graph.childNodes(way)); - var points = nodes.map(function(n2) { - return projection2(n2.loc); - }); - var sign2 = area_default3(points) > 0 ? 1 : -1; - var hull = hull_default(points); - var i2, j2; - if (sign2 === -1) { - nodes.reverse(); - points.reverse(); + return null; + }, + isSided: function() { + if (this.tags.two_sided === "yes") { + return false; } - for (i2 = 0; i2 < hull.length - 1; i2++) { - var startIndex = points.indexOf(hull[i2]); - var endIndex = points.indexOf(hull[i2 + 1]); - var indexRange = endIndex - startIndex; - if (indexRange < 0) { - indexRange += nodes.length; - } - for (j2 = 1; j2 < indexRange; j2++) { - var point = geoVecInterp(hull[i2], hull[i2 + 1], j2 / indexRange); - var node = nodes[(j2 + startIndex) % nodes.length].move(projection2.invert(point)); - graph = graph.replace(node); + return this.sidednessIdentifier() !== null; + }, + lanes: function() { + return osmLanes(this); + }, + isClosed: function() { + return this.nodes.length > 1 && this.first() === this.last(); + }, + isConvex: function(resolver) { + if (!this.isClosed() || this.isDegenerate()) + return null; + var nodes = utilArrayUniq(resolver.childNodes(this)); + var coords = nodes.map(function(n2) { + return n2.loc; + }); + var curr = 0; + var prev = 0; + for (var i2 = 0; i2 < coords.length; i2++) { + var o = coords[(i2 + 1) % coords.length]; + var a = coords[i2]; + var b = coords[(i2 + 2) % coords.length]; + var res = geoVecCross(a, b, o); + curr = res > 0 ? 1 : res < 0 ? -1 : 0; + if (curr === 0) { + continue; + } else if (prev && curr !== prev) { + return false; } + prev = curr; } - return graph; - }; - action.disabled = function(graph) { - if (!graph.entity(wayId).isClosed()) { - return "not_closed"; + return true; + }, + // returns an object with the tag that implies this is an area, if any + tagSuggestingArea: function() { + return osmTagSuggestingArea(this.tags); + }, + isArea: function() { + if (this.tags.area === "yes") + return true; + if (!this.isClosed() || this.tags.area === "no") + return false; + return this.tagSuggestingArea() !== null; + }, + isDegenerate: function() { + return new Set(this.nodes).size < (this.isArea() ? 3 : 2); + }, + areAdjacent: function(n1, n2) { + for (var i2 = 0; i2 < this.nodes.length; i2++) { + if (this.nodes[i2] === n1) { + if (this.nodes[i2 - 1] === n2) + return true; + if (this.nodes[i2 + 1] === n2) + return true; + } } - var way = graph.entity(wayId); - var nodes = utilArrayUniq(graph.childNodes(way)); - var points = nodes.map(function(n2) { - return projection2(n2.loc); + return false; + }, + geometry: function(graph) { + return graph.transient(this, "geometry", function() { + return this.isArea() ? "area" : "line"; }); - var hull = hull_default(points); - var epsilonAngle = Math.PI / 180; - if (hull.length !== points.length || hull.length < 3) { - return false; + }, + // returns an array of objects representing the segments between the nodes in this way + segments: function(graph) { + function segmentExtent(graph2) { + var n1 = graph2.hasEntity(this.nodes[0]); + var n2 = graph2.hasEntity(this.nodes[1]); + return n1 && n2 && geoExtent([ + [ + Math.min(n1.loc[0], n2.loc[0]), + Math.min(n1.loc[1], n2.loc[1]) + ], + [ + Math.max(n1.loc[0], n2.loc[0]), + Math.max(n1.loc[1], n2.loc[1]) + ] + ]); } - var centroid = centroid_default2(points); - var radius = geoVecLengthSquare(centroid, points[0]); - var i2, actualPoint; - for (i2 = 0; i2 < hull.length; i2++) { - actualPoint = hull[i2]; - var actualDist = geoVecLengthSquare(actualPoint, centroid); - var diff = Math.abs(actualDist - radius); - if (diff > 0.05 * radius) { - return false; + return graph.transient(this, "segments", function() { + var segments = []; + for (var i2 = 0; i2 < this.nodes.length - 1; i2++) { + segments.push({ + id: this.id + "-" + i2, + wayId: this.id, + index: i2, + nodes: [this.nodes[i2], this.nodes[i2 + 1]], + extent: segmentExtent + }); } + return segments; + }); + }, + // If this way is not closed, append the beginning node to the end of the nodelist to close it. + close: function() { + if (this.isClosed() || !this.nodes.length) + return this; + var nodes = this.nodes.slice(); + nodes = nodes.filter(noRepeatNodes); + nodes.push(nodes[0]); + return this.update({ nodes }); + }, + // If this way is closed, remove any connector nodes from the end of the nodelist to unclose it. + unclose: function() { + if (!this.isClosed()) + return this; + var nodes = this.nodes.slice(); + var connector = this.first(); + var i2 = nodes.length - 1; + while (i2 > 0 && nodes.length > 1 && nodes[i2] === connector) { + nodes.splice(i2, 1); + i2 = nodes.length - 1; } - for (i2 = 0; i2 < hull.length; i2++) { - actualPoint = hull[i2]; - var nextPoint = hull[(i2 + 1) % hull.length]; - var startAngle = Math.atan2(actualPoint[1] - centroid[1], actualPoint[0] - centroid[0]); - var endAngle = Math.atan2(nextPoint[1] - centroid[1], nextPoint[0] - centroid[0]); - var angle2 = endAngle - startAngle; - if (angle2 < 0) { - angle2 = -angle2; + nodes = nodes.filter(noRepeatNodes); + return this.update({ nodes }); + }, + // Adds a node (id) in front of the node which is currently at position index. + // If index is undefined, the node will be added to the end of the way for linear ways, + // or just before the final connecting node for circular ways. + // Consecutive duplicates are eliminated including existing ones. + // Circularity is always preserved when adding a node. + addNode: function(id2, index) { + var nodes = this.nodes.slice(); + var isClosed = this.isClosed(); + var max3 = isClosed ? nodes.length - 1 : nodes.length; + if (index === void 0) { + index = max3; + } + if (index < 0 || index > max3) { + throw new RangeError("index " + index + " out of range 0.." + max3); + } + if (isClosed) { + var connector = this.first(); + var i2 = 1; + while (i2 < nodes.length && nodes.length > 2 && nodes[i2] === connector) { + nodes.splice(i2, 1); + if (index > i2) + index--; } - if (angle2 > Math.PI) { - angle2 = 2 * Math.PI - angle2; + i2 = nodes.length - 1; + while (i2 > 0 && nodes.length > 1 && nodes[i2] === connector) { + nodes.splice(i2, 1); + if (index > i2) + index--; + i2 = nodes.length - 1; } - if (angle2 > maxAngle + epsilonAngle) { - return false; + } + nodes.splice(index, 0, id2); + nodes = nodes.filter(noRepeatNodes); + if (isClosed && (nodes.length === 1 || nodes[0] !== nodes[nodes.length - 1])) { + nodes.push(nodes[0]); + } + return this.update({ nodes }); + }, + // Replaces the node which is currently at position index with the given node (id). + // Consecutive duplicates are eliminated including existing ones. + // Circularity is preserved when updating a node. + updateNode: function(id2, index) { + var nodes = this.nodes.slice(); + var isClosed = this.isClosed(); + var max3 = nodes.length - 1; + if (index === void 0 || index < 0 || index > max3) { + throw new RangeError("index " + index + " out of range 0.." + max3); + } + if (isClosed) { + var connector = this.first(); + var i2 = 1; + while (i2 < nodes.length && nodes.length > 2 && nodes[i2] === connector) { + nodes.splice(i2, 1); + if (index > i2) + index--; + } + i2 = nodes.length - 1; + while (i2 > 0 && nodes.length > 1 && nodes[i2] === connector) { + nodes.splice(i2, 1); + if (index === i2) + index = 0; + i2 = nodes.length - 1; } } - return "already_circular"; - }; - action.transitionable = true; - return action; - } - - // modules/actions/delete_way.js - function actionDeleteWay(wayID) { - function canDeleteNode(node, graph) { - if (graph.parentWays(node).length || graph.parentRelations(node).length) - return false; - var geometries = osmNodeGeometriesForTags(node.tags); - if (geometries.point) - return false; - if (geometries.vertex) - return true; - return !node.hasInterestingTags(); - } - var action = function(graph) { - var way = graph.entity(wayID); - graph.parentRelations(way).forEach(function(parent) { - parent = parent.removeMembersWithID(wayID); - graph = graph.replace(parent); - if (parent.isDegenerate()) { - graph = actionDeleteRelation(parent.id)(graph); + nodes.splice(index, 1, id2); + nodes = nodes.filter(noRepeatNodes); + if (isClosed && (nodes.length === 1 || nodes[0] !== nodes[nodes.length - 1])) { + nodes.push(nodes[0]); + } + return this.update({ nodes }); + }, + // Replaces each occurrence of node id needle with replacement. + // Consecutive duplicates are eliminated including existing ones. + // Circularity is preserved. + replaceNode: function(needleID, replacementID) { + var nodes = this.nodes.slice(); + var isClosed = this.isClosed(); + for (var i2 = 0; i2 < nodes.length; i2++) { + if (nodes[i2] === needleID) { + nodes[i2] = replacementID; } - }); - new Set(way.nodes).forEach(function(nodeID) { - graph = graph.replace(way.removeNode(nodeID)); - var node = graph.entity(nodeID); - if (canDeleteNode(node, graph)) { - graph = graph.remove(node); + } + nodes = nodes.filter(noRepeatNodes); + if (isClosed && (nodes.length === 1 || nodes[0] !== nodes[nodes.length - 1])) { + nodes.push(nodes[0]); + } + return this.update({ nodes }); + }, + // Removes each occurrence of node id. + // Consecutive duplicates are eliminated including existing ones. + // Circularity is preserved. + removeNode: function(id2) { + var nodes = this.nodes.slice(); + var isClosed = this.isClosed(); + nodes = nodes.filter(function(node) { + return node !== id2; + }).filter(noRepeatNodes); + if (isClosed && (nodes.length === 1 || nodes[0] !== nodes[nodes.length - 1])) { + nodes.push(nodes[0]); + } + return this.update({ nodes }); + }, + asJXON: function(changeset_id) { + var r = { + way: { + "@id": this.osmId(), + "@version": this.version || 0, + nd: this.nodes.map(function(id2) { + return { keyAttributes: { ref: osmEntity.id.toOSM(id2) } }; + }, this), + tag: Object.keys(this.tags).map(function(k) { + return { keyAttributes: { k, v: this.tags[k] } }; + }, this) } - }); - return graph.remove(way); - }; - return action; - } - - // modules/actions/delete_multiple.js - function actionDeleteMultiple(ids) { - var actions = { - way: actionDeleteWay, - node: actionDeleteNode, - relation: actionDeleteRelation - }; - var action = function(graph) { - ids.forEach(function(id2) { - if (graph.hasEntity(id2)) { - graph = actions[graph.entity(id2).type](id2)(graph); + }; + if (changeset_id) { + r.way["@changeset"] = changeset_id; + } + return r; + }, + asGeoJSON: function(resolver) { + return resolver.transient(this, "GeoJSON", function() { + var coordinates = resolver.childNodes(this).map(function(n2) { + return n2.loc; + }); + if (this.isArea() && this.isClosed()) { + return { + type: "Polygon", + coordinates: [coordinates] + }; + } else { + return { + type: "LineString", + coordinates + }; } }); - return graph; - }; - return action; - } - - // modules/actions/delete_relation.js - function actionDeleteRelation(relationID, allowUntaggedMembers) { - function canDeleteEntity(entity, graph) { - return !graph.parentWays(entity).length && !graph.parentRelations(entity).length && (!entity.hasInterestingTags() && !allowUntaggedMembers); - } - var action = function(graph) { - var relation = graph.entity(relationID); - graph.parentRelations(relation).forEach(function(parent) { - parent = parent.removeMembersWithID(relationID); - graph = graph.replace(parent); - if (parent.isDegenerate()) { - graph = actionDeleteRelation(parent.id)(graph); + }, + area: function(resolver) { + return resolver.transient(this, "area", function() { + var nodes = resolver.childNodes(this); + var json = { + type: "Polygon", + coordinates: [nodes.map(function(n2) { + return n2.loc; + })] + }; + if (!this.isClosed() && nodes.length) { + json.coordinates[0].push(nodes[0].loc); } - }); - var memberIDs = utilArrayUniq(relation.members.map(function(m) { - return m.id; - })); - memberIDs.forEach(function(memberID) { - graph = graph.replace(relation.removeMembersWithID(memberID)); - var entity = graph.entity(memberID); - if (canDeleteEntity(entity, graph)) { - graph = actionDeleteMultiple([memberID])(graph); + var area = area_default(json); + if (area > 2 * Math.PI) { + json.coordinates[0] = json.coordinates[0].reverse(); + area = area_default(json); } + return isNaN(area) ? 0 : area; }); - return graph.remove(relation); - }; - return action; + } + }); + function noRepeatNodes(node, i2, arr) { + return i2 === 0 || node !== arr[i2 - 1]; } - // modules/actions/delete_node.js - function actionDeleteNode(nodeId) { - var action = function(graph) { - var node = graph.entity(nodeId); - graph.parentWays(node).forEach(function(parent) { - parent = parent.removeNode(nodeId); - graph = graph.replace(parent); - if (parent.isDegenerate()) { - graph = actionDeleteWay(parent.id)(graph); - } - }); - graph.parentRelations(node).forEach(function(parent) { - parent = parent.removeMembersWithID(nodeId); - graph = graph.replace(parent); - if (parent.isDegenerate()) { - graph = actionDeleteRelation(parent.id)(graph); + // modules/osm/multipolygon.js + function osmOldMultipolygonOuterMemberOfRelation(entity, graph) { + if (entity.type !== "relation" || !entity.isMultipolygon() || Object.keys(entity.tags).filter(osmIsInterestingTag).length > 1) { + return false; + } + var outerMember; + for (var memberIndex in entity.members) { + var member = entity.members[memberIndex]; + if (!member.role || member.role === "outer") { + if (outerMember) + return false; + if (member.type !== "way") + return false; + if (!graph.hasEntity(member.id)) + return false; + outerMember = graph.entity(member.id); + if (Object.keys(outerMember.tags).filter(osmIsInterestingTag).length === 0) { + return false; } - }); - return graph.remove(node); - }; - return action; + } + } + return outerMember; } - - // modules/actions/connect.js - function actionConnect(nodeIDs) { - var action = function(graph) { - var survivor; - var node; - var parents; - var i2, j2; - nodeIDs.reverse(); - var interestingIDs = []; - for (i2 = 0; i2 < nodeIDs.length; i2++) { - node = graph.entity(nodeIDs[i2]); - if (node.hasInterestingTags()) { - if (!node.isNew()) { - interestingIDs.push(node.id); - } - } + function osmIsOldMultipolygonOuterMember(entity, graph) { + if (entity.type !== "way" || Object.keys(entity.tags).filter(osmIsInterestingTag).length === 0) { + return false; + } + var parents = graph.parentRelations(entity); + if (parents.length !== 1) + return false; + var parent = parents[0]; + if (!parent.isMultipolygon() || Object.keys(parent.tags).filter(osmIsInterestingTag).length > 1) { + return false; + } + var members = parent.members, member; + for (var i2 = 0; i2 < members.length; i2++) { + member = members[i2]; + if (member.id === entity.id && member.role && member.role !== "outer") { + return false; } - survivor = graph.entity(utilOldestID(interestingIDs.length > 0 ? interestingIDs : nodeIDs)); - for (i2 = 0; i2 < nodeIDs.length; i2++) { - node = graph.entity(nodeIDs[i2]); - if (node.id === survivor.id) - continue; - parents = graph.parentWays(node); - for (j2 = 0; j2 < parents.length; j2++) { - graph = graph.replace(parents[j2].replaceNode(node.id, survivor.id)); + if (member.id !== entity.id && (!member.role || member.role === "outer")) { + return false; + } + } + return parent; + } + function osmOldMultipolygonOuterMember(entity, graph) { + if (entity.type !== "way") + return false; + var parents = graph.parentRelations(entity); + if (parents.length !== 1) + return false; + var parent = parents[0]; + if (!parent.isMultipolygon() || Object.keys(parent.tags).filter(osmIsInterestingTag).length > 1) { + return false; + } + var members = parent.members, member, outerMember; + for (var i2 = 0; i2 < members.length; i2++) { + member = members[i2]; + if (!member.role || member.role === "outer") { + if (outerMember) + return false; + outerMember = member; + } + } + if (!outerMember) + return false; + var outerEntity = graph.hasEntity(outerMember.id); + if (!outerEntity || !Object.keys(outerEntity.tags).filter(osmIsInterestingTag).length) { + return false; + } + return outerEntity; + } + function osmJoinWays(toJoin, graph) { + function resolve(member) { + return graph.childNodes(graph.entity(member.id)); + } + function reverse(item2) { + var action = actionReverse(item2.id, { reverseOneway: true }); + sequences.actions.push(action); + return item2 instanceof osmWay ? action(graph).entity(item2.id) : item2; + } + toJoin = toJoin.filter(function(member) { + return member.type === "way" && graph.hasEntity(member.id); + }); + var i2; + var joinAsMembers = true; + for (i2 = 0; i2 < toJoin.length; i2++) { + if (toJoin[i2] instanceof osmWay) { + joinAsMembers = false; + break; + } + } + var sequences = []; + sequences.actions = []; + while (toJoin.length) { + var item = toJoin.shift(); + var currWays = [item]; + var currNodes = resolve(item).slice(); + while (toJoin.length) { + var start2 = currNodes[0]; + var end = currNodes[currNodes.length - 1]; + var fn = null; + var nodes = null; + for (i2 = 0; i2 < toJoin.length; i2++) { + item = toJoin[i2]; + nodes = resolve(item); + if (joinAsMembers && currWays.length === 1 && nodes[0] !== end && nodes[nodes.length - 1] !== end && (nodes[nodes.length - 1] === start2 || nodes[0] === start2)) { + currWays[0] = reverse(currWays[0]); + currNodes.reverse(); + start2 = currNodes[0]; + end = currNodes[currNodes.length - 1]; + } + if (nodes[0] === end) { + fn = currNodes.push; + nodes = nodes.slice(1); + break; + } else if (nodes[nodes.length - 1] === end) { + fn = currNodes.push; + nodes = nodes.slice(0, -1).reverse(); + item = reverse(item); + break; + } else if (nodes[nodes.length - 1] === start2) { + fn = currNodes.unshift; + nodes = nodes.slice(0, -1); + break; + } else if (nodes[0] === start2) { + fn = currNodes.unshift; + nodes = nodes.slice(1).reverse(); + item = reverse(item); + break; + } else { + fn = nodes = null; + } } - parents = graph.parentRelations(node); - for (j2 = 0; j2 < parents.length; j2++) { - graph = graph.replace(parents[j2].replaceMember(node, survivor)); + if (!nodes) { + break; } - survivor = survivor.mergeTags(node.tags); - graph = actionDeleteNode(node.id)(graph); + fn.apply(currWays, [item]); + fn.apply(currNodes, nodes); + toJoin.splice(i2, 1); } - graph = graph.replace(survivor); - parents = graph.parentWays(survivor); - for (i2 = 0; i2 < parents.length; i2++) { - if (parents[i2].isDegenerate()) { - graph = actionDeleteWay(parents[i2].id)(graph); + currWays.nodes = currNodes; + sequences.push(currWays); + } + return sequences; + } + + // modules/actions/add_member.js + function actionAddMember(relationId, member, memberIndex, insertPair) { + return function action(graph) { + var relation = graph.entity(relationId); + var isPTv2 = /stop|platform/.test(member.role); + if ((isNaN(memberIndex) || insertPair) && member.type === "way" && !isPTv2) { + graph = addWayMember(relation, graph); + } else { + if (isPTv2 && isNaN(memberIndex)) { + memberIndex = 0; } + graph = graph.replace(relation.addMember(member, memberIndex)); } return graph; }; - action.disabled = function(graph) { - var seen = {}; - var restrictionIDs = []; - var survivor; - var node, way; - var relations, relation, role; - var i2, j2, k; - survivor = graph.entity(utilOldestID(nodeIDs)); - for (i2 = 0; i2 < nodeIDs.length; i2++) { - node = graph.entity(nodeIDs[i2]); - relations = graph.parentRelations(node); - for (j2 = 0; j2 < relations.length; j2++) { - relation = relations[j2]; - role = relation.memberById(node.id).role || ""; - if (relation.hasFromViaTo()) { - restrictionIDs.push(relation.id); - } - if (seen[relation.id] !== void 0 && seen[relation.id] !== role) { - return "relation"; - } else { - seen[relation.id] = role; - } + function addWayMember(relation, graph) { + var groups, tempWay, insertPairIsReversed, item, i2, j2, k; + var PTv2members = []; + var members = []; + for (i2 = 0; i2 < relation.members.length; i2++) { + var m = relation.members[i2]; + if (/stop|platform/.test(m.role)) { + PTv2members.push(m); + } else { + members.push(m); } } - for (i2 = 0; i2 < nodeIDs.length; i2++) { - node = graph.entity(nodeIDs[i2]); - var parents = graph.parentWays(node); - for (j2 = 0; j2 < parents.length; j2++) { - var parent = parents[j2]; - relations = graph.parentRelations(parent); - for (k = 0; k < relations.length; k++) { - relation = relations[k]; - if (relation.hasFromViaTo()) { - restrictionIDs.push(relation.id); + relation = relation.update({ members }); + if (insertPair) { + tempWay = osmWay({ id: "wTemp", nodes: insertPair.nodes }); + graph = graph.replace(tempWay); + var tempMember = { id: tempWay.id, type: "way", role: member.role }; + var tempRelation = relation.replaceMember({ id: insertPair.originalID }, tempMember, true); + groups = utilArrayGroupBy(tempRelation.members, "type"); + groups.way = groups.way || []; + var originalWay = graph.entity(insertPair.originalID); + var insertedWay = graph.entity(insertPair.insertedID); + insertPairIsReversed = originalWay.nodes.length > 0 && insertedWay.nodes.length > 0 && insertedWay.nodes[insertedWay.nodes.length - 1] === originalWay.nodes[0] && originalWay.nodes[originalWay.nodes.length - 1] !== insertedWay.nodes[0]; + } else { + groups = utilArrayGroupBy(relation.members, "type"); + groups.way = groups.way || []; + groups.way.push(member); + } + members = withIndex(groups.way); + var joined = osmJoinWays(members, graph); + for (i2 = 0; i2 < joined.length; i2++) { + var segment = joined[i2]; + var nodes = segment.nodes.slice(); + var startIndex = segment[0].index; + for (j2 = 0; j2 < members.length; j2++) { + if (members[j2].index === startIndex) { + break; + } + } + for (k = 0; k < segment.length; k++) { + item = segment[k]; + var way = graph.entity(item.id); + if (tempWay && item.id === tempWay.id) { + var reverse = nodes[0].id !== insertPair.nodes[0] ^ insertPairIsReversed; + if (reverse) { + item.pair = [ + { id: insertPair.insertedID, type: "way", role: item.role }, + { id: insertPair.originalID, type: "way", role: item.role } + ]; + } else { + item.pair = [ + { id: insertPair.originalID, type: "way", role: item.role }, + { id: insertPair.insertedID, type: "way", role: item.role } + ]; + } + } + if (k > 0) { + if (j2 + k >= members.length || item.index !== members[j2 + k].index) { + moveMember(members, item.index, j2 + k); } } + nodes.splice(0, way.nodes.length - 1); } } - restrictionIDs = utilArrayUniq(restrictionIDs); - for (i2 = 0; i2 < restrictionIDs.length; i2++) { - relation = graph.entity(restrictionIDs[i2]); - if (!relation.isComplete(graph)) + if (tempWay) { + graph = graph.remove(tempWay); + } + var wayMembers = []; + for (i2 = 0; i2 < members.length; i2++) { + item = members[i2]; + if (item.index === -1) continue; - var memberWays = relation.members.filter(function(m) { - return m.type === "way"; - }).map(function(m) { - return graph.entity(m.id); - }); - memberWays = utilArrayUniq(memberWays); - var f2 = relation.memberByRole("from"); - var t = relation.memberByRole("to"); - var isUturn = f2.id === t.id; - var nodes = { from: [], via: [], to: [], keyfrom: [], keyto: [] }; - for (j2 = 0; j2 < relation.members.length; j2++) { - collectNodes(relation.members[j2], nodes); + if (item.pair) { + wayMembers.push(item.pair[0]); + wayMembers.push(item.pair[1]); + } else { + wayMembers.push(utilObjectOmit(item, ["index"])); } - nodes.keyfrom = utilArrayUniq(nodes.keyfrom.filter(hasDuplicates)); - nodes.keyto = utilArrayUniq(nodes.keyto.filter(hasDuplicates)); - var filter2 = keyNodeFilter(nodes.keyfrom, nodes.keyto); - nodes.from = nodes.from.filter(filter2); - nodes.via = nodes.via.filter(filter2); - nodes.to = nodes.to.filter(filter2); - var connectFrom = false; - var connectVia = false; - var connectTo = false; - var connectKeyFrom = false; - var connectKeyTo = false; - for (j2 = 0; j2 < nodeIDs.length; j2++) { - var n2 = nodeIDs[j2]; - if (nodes.from.indexOf(n2) !== -1) { - connectFrom = true; - } - if (nodes.via.indexOf(n2) !== -1) { - connectVia = true; - } - if (nodes.to.indexOf(n2) !== -1) { - connectTo = true; - } - if (nodes.keyfrom.indexOf(n2) !== -1) { - connectKeyFrom = true; - } - if (nodes.keyto.indexOf(n2) !== -1) { - connectKeyTo = true; - } - } - if (connectFrom && connectTo && !isUturn) { - return "restriction"; - } - if (connectFrom && connectVia) { - return "restriction"; - } - if (connectTo && connectVia) { - return "restriction"; - } - if (connectKeyFrom || connectKeyTo) { - if (nodeIDs.length !== 2) { - return "restriction"; - } - var n0 = null; - var n1 = null; - for (j2 = 0; j2 < memberWays.length; j2++) { - way = memberWays[j2]; - if (way.contains(nodeIDs[0])) { - n0 = nodeIDs[0]; - } - if (way.contains(nodeIDs[1])) { - n1 = nodeIDs[1]; - } - } - if (n0 && n1) { - var ok = false; - for (j2 = 0; j2 < memberWays.length; j2++) { - way = memberWays[j2]; - if (way.areAdjacent(n0, n1)) { - ok = true; - break; - } - } - if (!ok) { - return "restriction"; - } - } - } - for (j2 = 0; j2 < memberWays.length; j2++) { - way = memberWays[j2].update({}); - for (k = 0; k < nodeIDs.length; k++) { - if (nodeIDs[k] === survivor.id) - continue; - if (way.areAdjacent(nodeIDs[k], survivor.id)) { - way = way.removeNode(nodeIDs[k]); - } else { - way = way.replaceNode(nodeIDs[k], survivor.id); - } - } - if (way.isDegenerate()) { - return "restriction"; + } + var newMembers = PTv2members.concat(groups.node || [], wayMembers, groups.relation || []); + return graph.replace(relation.update({ members: newMembers })); + function moveMember(arr, findIndex, toIndex) { + var i3; + for (i3 = 0; i3 < arr.length; i3++) { + if (arr[i3].index === findIndex) { + break; } } + var item2 = Object.assign({}, arr[i3]); + arr[i3].index = -1; + item2.index = toIndex; + arr.splice(toIndex, 0, item2); } - return false; - function hasDuplicates(n3, i3, arr) { - return arr.indexOf(n3) !== arr.lastIndexOf(n3); - } - function keyNodeFilter(froms, tos) { - return function(n3) { - return froms.indexOf(n3) === -1 && tos.indexOf(n3) === -1; - }; - } - function collectNodes(member, collection) { - var entity = graph.hasEntity(member.id); - if (!entity) - return; - var role2 = member.role || ""; - if (!collection[role2]) { - collection[role2] = []; - } - if (member.type === "node") { - collection[role2].push(member.id); - if (role2 === "via") { - collection.keyfrom.push(member.id); - collection.keyto.push(member.id); - } - } else if (member.type === "way") { - collection[role2].push.apply(collection[role2], entity.nodes); - if (role2 === "from" || role2 === "via") { - collection.keyfrom.push(entity.first()); - collection.keyfrom.push(entity.last()); - } - if (role2 === "to" || role2 === "via") { - collection.keyto.push(entity.first()); - collection.keyto.push(entity.last()); - } + function withIndex(arr) { + var result = new Array(arr.length); + for (var i3 = 0; i3 < arr.length; i3++) { + result[i3] = Object.assign({}, arr[i3]); + result[i3].index = i3; } + return result; } - }; - return action; + } } - // modules/actions/copy_entities.js - function actionCopyEntities(ids, fromGraph) { - var _copies = {}; - var action = function(graph) { - ids.forEach(function(id3) { - fromGraph.entity(id3).copy(fromGraph, _copies); + // modules/actions/add_midpoint.js + function actionAddMidpoint(midpoint, node) { + return function(graph) { + graph = graph.replace(node.move(midpoint.loc)); + var parents = utilArrayIntersection( + graph.parentWays(graph.entity(midpoint.edge[0])), + graph.parentWays(graph.entity(midpoint.edge[1])) + ); + parents.forEach(function(way) { + for (var i2 = 0; i2 < way.nodes.length - 1; i2++) { + if (geoEdgeEqual([way.nodes[i2], way.nodes[i2 + 1]], midpoint.edge)) { + graph = graph.replace(graph.entity(way.id).addNode(node.id, i2 + 1)); + return; + } + } }); - for (var id2 in _copies) { - graph = graph.replace(_copies[id2]); - } return graph; }; - action.copies = function() { - return _copies; + } + + // modules/actions/add_vertex.js + function actionAddVertex(wayId, nodeId, index) { + return function(graph) { + return graph.replace(graph.entity(wayId).addNode(nodeId, index)); }; - return action; } - // modules/actions/delete_member.js - function actionDeleteMember(relationId, memberIndex) { + // modules/actions/change_member.js + function actionChangeMember(relationId, member, memberIndex) { return function(graph) { - var relation = graph.entity(relationId).removeMember(memberIndex); - graph = graph.replace(relation); - if (relation.isDegenerate()) { - graph = actionDeleteRelation(relation.id)(graph); - } - return graph; + return graph.replace(graph.entity(relationId).updateMember(member, memberIndex)); }; } - // modules/actions/discard_tags.js - function actionDiscardTags(difference, discardTags) { - discardTags = discardTags || {}; - return (graph) => { - difference.modified().forEach(checkTags); - difference.created().forEach(checkTags); - return graph; - function checkTags(entity) { - const keys = Object.keys(entity.tags); - let didDiscard = false; - let tags = {}; - for (let i2 = 0; i2 < keys.length; i2++) { - const k = keys[i2]; - if (discardTags[k] || !entity.tags[k]) { - didDiscard = true; - } else { - tags[k] = entity.tags[k]; - } + // modules/actions/change_preset.js + function actionChangePreset(entityID, oldPreset, newPreset, skipFieldDefaults) { + return function action(graph) { + var entity = graph.entity(entityID); + var geometry = entity.geometry(graph); + var tags = entity.tags; + const loc = entity.extent(graph).center(); + var preserveKeys; + if (newPreset) { + preserveKeys = []; + if (newPreset.addTags) { + preserveKeys = preserveKeys.concat(Object.keys(newPreset.addTags)); } - if (didDiscard) { - graph = graph.replace(entity.update({ tags })); + if (oldPreset && !oldPreset.id.startsWith(newPreset.id)) { + newPreset.fields(loc).concat(newPreset.moreFields(loc)).filter((f2) => f2.matchGeometry(geometry)).map((f2) => f2.key).filter(Boolean).forEach((key) => preserveKeys.push(key)); } } + if (oldPreset) + tags = oldPreset.unsetTags(tags, geometry, preserveKeys, false, loc); + if (newPreset) + tags = newPreset.setTags(tags, geometry, skipFieldDefaults, loc); + return graph.replace(entity.update({ tags })); }; } - // modules/actions/disconnect.js - function actionDisconnect(nodeId, newNodeId) { - var wayIds; - var disconnectableRelationTypes = { - "associatedStreet": true, - "enforcement": true, - "site": true + // modules/actions/change_tags.js + function actionChangeTags(entityId, tags) { + return function(graph) { + var entity = graph.entity(entityId); + return graph.replace(entity.update({ tags })); }; - var action = function(graph) { - var node = graph.entity(nodeId); - var connections = action.connections(graph); - connections.forEach(function(connection) { - var way = graph.entity(connection.wayID); - var newNode = osmNode({ id: newNodeId, loc: node.loc, tags: node.tags }); - graph = graph.replace(newNode); - if (connection.index === 0 && way.isArea()) { - graph = graph.replace(way.replaceNode(way.nodes[0], newNode.id)); - } else if (way.isClosed() && connection.index === way.nodes.length - 1) { - graph = graph.replace(way.unclose().addNode(newNode.id)); - } else { - graph = graph.replace(way.updateNode(newNode.id, connection.index)); - } + } + + // modules/osm/node.js + var cardinal = { + north: 0, + n: 0, + northnortheast: 22, + nne: 22, + northeast: 45, + ne: 45, + eastnortheast: 67, + ene: 67, + east: 90, + e: 90, + eastsoutheast: 112, + ese: 112, + southeast: 135, + se: 135, + southsoutheast: 157, + sse: 157, + south: 180, + s: 180, + southsouthwest: 202, + ssw: 202, + southwest: 225, + sw: 225, + westsouthwest: 247, + wsw: 247, + west: 270, + w: 270, + westnorthwest: 292, + wnw: 292, + northwest: 315, + nw: 315, + northnorthwest: 337, + nnw: 337 + }; + function osmNode() { + if (!(this instanceof osmNode)) { + return new osmNode().initialize(arguments); + } else if (arguments.length) { + this.initialize(arguments); + } + } + osmEntity.node = osmNode; + osmNode.prototype = Object.create(osmEntity.prototype); + Object.assign(osmNode.prototype, { + type: "node", + loc: [9999, 9999], + extent: function() { + return new geoExtent(this.loc); + }, + geometry: function(graph) { + return graph.transient(this, "geometry", function() { + return graph.isPoi(this) ? "point" : "vertex"; }); - return graph; - }; - action.connections = function(graph) { - var candidates = []; - var keeping = false; - var parentWays = graph.parentWays(graph.entity(nodeId)); - var way, waynode; - for (var i2 = 0; i2 < parentWays.length; i2++) { - way = parentWays[i2]; - if (wayIds && wayIds.indexOf(way.id) === -1) { - keeping = true; - continue; - } - if (way.isArea() && way.nodes[0] === nodeId) { - candidates.push({ wayID: way.id, index: 0 }); - } else { - for (var j2 = 0; j2 < way.nodes.length; j2++) { - waynode = way.nodes[j2]; - if (waynode === nodeId) { - if (way.isClosed() && parentWays.length > 1 && wayIds && wayIds.indexOf(way.id) !== -1 && j2 === way.nodes.length - 1) { - continue; - } - candidates.push({ wayID: way.id, index: j2 }); - } + }, + move: function(loc) { + return this.update({ loc }); + }, + isDegenerate: function() { + return !(Array.isArray(this.loc) && this.loc.length === 2 && this.loc[0] >= -180 && this.loc[0] <= 180 && this.loc[1] >= -90 && this.loc[1] <= 90); + }, + // Inspect tags and geometry to determine which direction(s) this node/vertex points + directions: function(resolver, projection2) { + var val; + var i2; + if (this.isHighwayIntersection(resolver) && (this.tags.stop || "").toLowerCase() === "all") { + val = "all"; + } else { + val = (this.tags.direction || "").toLowerCase(); + var re2 = /:direction$/i; + var keys2 = Object.keys(this.tags); + for (i2 = 0; i2 < keys2.length; i2++) { + if (re2.test(keys2[i2])) { + val = this.tags[keys2[i2]].toLowerCase(); + break; } } } - return keeping ? candidates : candidates.slice(1); - }; - action.disabled = function(graph) { - var connections = action.connections(graph); - if (connections.length === 0) - return "not_connected"; - var parentWays = graph.parentWays(graph.entity(nodeId)); - var seenRelationIds = {}; - var sharedRelation; - parentWays.forEach(function(way) { - var relations = graph.parentRelations(way); - relations.filter((relation) => !disconnectableRelationTypes[relation.tags.type]).forEach(function(relation) { - if (relation.id in seenRelationIds) { - if (wayIds) { - if (wayIds.indexOf(way.id) !== -1 || wayIds.indexOf(seenRelationIds[relation.id]) !== -1) { - sharedRelation = relation; + if (val === "") + return []; + var values = val.split(";"); + var results = []; + values.forEach(function(v) { + if (cardinal[v] !== void 0) { + v = cardinal[v]; + } + if (v !== "" && !isNaN(+v)) { + results.push(+v); + return; + } + var lookBackward = this.tags["traffic_sign:backward"] || v === "backward" || v === "both" || v === "all"; + var lookForward = this.tags["traffic_sign:forward"] || v === "forward" || v === "both" || v === "all"; + if (!lookForward && !lookBackward) + return; + var nodeIds = {}; + resolver.parentWays(this).forEach(function(parent) { + var nodes = parent.nodes; + for (i2 = 0; i2 < nodes.length; i2++) { + if (nodes[i2] === this.id) { + if (lookForward && i2 > 0) { + nodeIds[nodes[i2 - 1]] = true; + } + if (lookBackward && i2 < nodes.length - 1) { + nodeIds[nodes[i2 + 1]] = true; } - } else { - sharedRelation = relation; } - } else { - seenRelationIds[relation.id] = way.id; } - }); + }, this); + Object.keys(nodeIds).forEach(function(nodeId) { + results.push( + geoAngle(this, resolver.entity(nodeId), projection2) * (180 / Math.PI) + 90 + ); + }, this); + }, this); + return utilArrayUniq(results); + }, + isCrossing: function() { + return this.tags.highway === "crossing" || this.tags.railway && this.tags.railway.indexOf("crossing") !== -1; + }, + isEndpoint: function(resolver) { + return resolver.transient(this, "isEndpoint", function() { + var id2 = this.id; + return resolver.parentWays(this).filter(function(parent) { + return !parent.isClosed() && !!parent.affix(id2); + }).length > 0; }); - if (sharedRelation) - return "relation"; - }; - action.limitWays = function(val) { - if (!arguments.length) - return wayIds; - wayIds = val; - return action; - }; - return action; - } - - // modules/actions/extract.js - function actionExtract(entityID, projection2) { - var extractedNodeID; - var action = function(graph) { - var entity = graph.entity(entityID); - if (entity.type === "node") { - return extractFromNode(entity, graph); - } - return extractFromWayOrRelation(entity, graph); - }; - function extractFromNode(node, graph) { - extractedNodeID = node.id; - var replacement = osmNode({ loc: node.loc }); - graph = graph.replace(replacement); - graph = graph.parentWays(node).reduce(function(accGraph, parentWay) { - return accGraph.replace(parentWay.replaceNode(entityID, replacement.id)); - }, graph); - return graph.parentRelations(node).reduce(function(accGraph, parentRel) { - return accGraph.replace(parentRel.replaceMember(node, replacement)); - }, graph); - } - function extractFromWayOrRelation(entity, graph) { - var fromGeometry = entity.geometry(graph); - var keysToCopyAndRetain = ["source", "wheelchair"]; - var keysToRetain = ["area"]; - var buildingKeysToRetain = ["architect", "building", "height", "layer"]; - var extractedLoc = path_default(projection2).centroid(entity.asGeoJSON(graph)); - extractedLoc = extractedLoc && projection2.invert(extractedLoc); - if (!extractedLoc || !isFinite(extractedLoc[0]) || !isFinite(extractedLoc[1])) { - extractedLoc = entity.extent(graph).center(); - } - var indoorAreaValues = { - area: true, - corridor: true, - elevator: true, - level: true, - room: true - }; - var isBuilding = entity.tags.building && entity.tags.building !== "no" || entity.tags["building:part"] && entity.tags["building:part"] !== "no"; - var isIndoorArea = fromGeometry === "area" && entity.tags.indoor && indoorAreaValues[entity.tags.indoor]; - var entityTags = Object.assign({}, entity.tags); - var pointTags = {}; - for (var key in entityTags) { - if (entity.type === "relation" && key === "type") { - continue; - } - if (keysToRetain.indexOf(key) !== -1) { - continue; - } - if (isBuilding) { - if (buildingKeysToRetain.indexOf(key) !== -1 || key.match(/^building:.{1,}/) || key.match(/^roof:.{1,}/)) - continue; - } - if (isIndoorArea && key === "indoor") { - continue; - } - pointTags[key] = entityTags[key]; - if (keysToCopyAndRetain.indexOf(key) !== -1 || key.match(/^addr:.{1,}/)) { - continue; - } else if (isIndoorArea && key === "level") { - continue; + }, + isConnected: function(resolver) { + return resolver.transient(this, "isConnected", function() { + var parents = resolver.parentWays(this); + if (parents.length > 1) { + for (var i2 in parents) { + if (parents[i2].geometry(resolver) === "line" && parents[i2].hasInterestingTags()) + return true; + } + } else if (parents.length === 1) { + var way = parents[0]; + var nodes = way.nodes.slice(); + if (way.isClosed()) { + nodes.pop(); + } + return nodes.indexOf(this.id) !== nodes.lastIndexOf(this.id); } - delete entityTags[key]; - } - if (!isBuilding && !isIndoorArea && fromGeometry === "area") { - entityTags.area = "yes"; - } - var replacement = osmNode({ loc: extractedLoc, tags: pointTags }); - graph = graph.replace(replacement); - extractedNodeID = replacement.id; - return graph.replace(entity.update({ tags: entityTags })); - } - action.getExtractedNodeID = function() { - return extractedNodeID; - }; - return action; - } - - // modules/actions/join.js - function actionJoin(ids) { - function groupEntitiesByGeometry(graph) { - var entities = ids.map(function(id2) { - return graph.entity(id2); - }); - return Object.assign( - { line: [] }, - utilArrayGroupBy(entities, function(entity) { - return entity.geometry(graph); - }) - ); - } - var action = function(graph) { - var ways = ids.map(graph.entity, graph); - var survivorID = utilOldestID(ways.map((way) => way.id)); - ways.sort(function(a, b) { - var aSided = a.isSided(); - var bSided = b.isSided(); - return aSided && !bSided ? -1 : bSided && !aSided ? 1 : 0; + return false; }); - var sequences = osmJoinWays(ways, graph); - var joined = sequences[0]; - graph = sequences.actions.reduce(function(g, action2) { - return action2(g); - }, graph); - var survivor = graph.entity(survivorID); - survivor = survivor.update({ nodes: joined.nodes.map(function(n2) { - return n2.id; - }) }); - graph = graph.replace(survivor); - joined.forEach(function(way) { - if (way.id === survivorID) - return; - graph.parentRelations(way).forEach(function(parent) { - graph = graph.replace(parent.replaceMember(way, survivor)); + }, + parentIntersectionWays: function(resolver) { + return resolver.transient(this, "parentIntersectionWays", function() { + return resolver.parentWays(this).filter(function(parent) { + return (parent.tags.highway || parent.tags.waterway || parent.tags.railway || parent.tags.aeroway) && parent.geometry(resolver) === "line"; }); - survivor = survivor.mergeTags(way.tags); - graph = graph.replace(survivor); - graph = actionDeleteWay(way.id)(graph); }); - function checkForSimpleMultipolygon() { - if (!survivor.isClosed()) - return; - var multipolygons = graph.parentMultipolygons(survivor).filter(function(multipolygon2) { - return multipolygon2.members.length === 1; - }); - if (multipolygons.length !== 1) - return; - var multipolygon = multipolygons[0]; - for (var key in survivor.tags) { - if (multipolygon.tags[key] && multipolygon.tags[key] !== survivor.tags[key]) - return; - } - survivor = survivor.mergeTags(multipolygon.tags); - graph = graph.replace(survivor); - graph = actionDeleteRelation(multipolygon.id, true)(graph); - var tags = Object.assign({}, survivor.tags); - if (survivor.geometry(graph) !== "area") { - tags.area = "yes"; + }, + isIntersection: function(resolver) { + return this.parentIntersectionWays(resolver).length > 1; + }, + isHighwayIntersection: function(resolver) { + return resolver.transient(this, "isHighwayIntersection", function() { + return resolver.parentWays(this).filter(function(parent) { + return parent.tags.highway && parent.geometry(resolver) === "line"; + }).length > 1; + }); + }, + isOnAddressLine: function(resolver) { + return resolver.transient(this, "isOnAddressLine", function() { + return resolver.parentWays(this).filter(function(parent) { + return parent.tags.hasOwnProperty("addr:interpolation") && parent.geometry(resolver) === "line"; + }).length > 0; + }); + }, + asJXON: function(changeset_id) { + var r = { + node: { + "@id": this.osmId(), + "@lon": this.loc[0], + "@lat": this.loc[1], + "@version": this.version || 0, + tag: Object.keys(this.tags).map(function(k) { + return { keyAttributes: { k, v: this.tags[k] } }; + }, this) } - delete tags.type; - survivor = survivor.update({ tags }); - graph = graph.replace(survivor); + }; + if (changeset_id) + r.node["@changeset"] = changeset_id; + return r; + }, + asGeoJSON: function() { + return { + type: "Point", + coordinates: this.loc + }; + } + }); + + // modules/actions/circularize.js + function actionCircularize(wayId, projection2, maxAngle) { + maxAngle = (maxAngle || 20) * Math.PI / 180; + var action = function(graph, t) { + if (t === null || !isFinite(t)) + t = 1; + t = Math.min(Math.max(+t, 0), 1); + var way = graph.entity(wayId); + var origNodes = {}; + graph.childNodes(way).forEach(function(node2) { + if (!origNodes[node2.id]) + origNodes[node2.id] = node2; + }); + if (!way.isConvex(graph)) { + graph = action.makeConvex(graph); } - checkForSimpleMultipolygon(); - return graph; - }; - action.resultingWayNodesLength = function(graph) { - return ids.reduce(function(count, id2) { - return count + graph.entity(id2).nodes.length; - }, 0) - ids.length - 1; - }; - action.disabled = function(graph) { - var geometries = groupEntitiesByGeometry(graph); - if (ids.length < 2 || ids.length !== geometries.line.length) { - return "not_eligible"; + var nodes = utilArrayUniq(graph.childNodes(way)); + var keyNodes = nodes.filter(function(n2) { + return graph.parentWays(n2).length !== 1; + }); + var points = nodes.map(function(n2) { + return projection2(n2.loc); + }); + var keyPoints = keyNodes.map(function(n2) { + return projection2(n2.loc); + }); + var centroid = points.length === 2 ? geoVecInterp(points[0], points[1], 0.5) : centroid_default2(points); + var radius = median(points, function(p) { + return geoVecLength(centroid, p); + }); + var sign2 = area_default3(points) > 0 ? 1 : -1; + var ids, i2, j2, k; + if (!keyNodes.length) { + keyNodes = [nodes[0]]; + keyPoints = [points[0]]; } - var joined = osmJoinWays(ids.map(graph.entity, graph), graph); - if (joined.length > 1) { - return "not_adjacent"; + if (keyNodes.length === 1) { + var index = nodes.indexOf(keyNodes[0]); + var oppositeIndex = Math.floor((index + nodes.length / 2) % nodes.length); + keyNodes.push(nodes[oppositeIndex]); + keyPoints.push(points[oppositeIndex]); } - var i2; - var sortedParentRelations = function(id2) { - return graph.parentRelations(graph.entity(id2)).filter((rel) => !rel.isRestriction() && !rel.isConnectivity()).sort((a, b) => a.id - b.id); - }; - var relsA = sortedParentRelations(ids[0]); - for (i2 = 1; i2 < ids.length; i2++) { - var relsB = sortedParentRelations(ids[i2]); - if (!utilArrayIdentical(relsA, relsB)) { - return "conflicting_relations"; + for (i2 = 0; i2 < keyPoints.length; i2++) { + var nextKeyNodeIndex = (i2 + 1) % keyNodes.length; + var startNode = keyNodes[i2]; + var endNode = keyNodes[nextKeyNodeIndex]; + var startNodeIndex = nodes.indexOf(startNode); + var endNodeIndex = nodes.indexOf(endNode); + var numberNewPoints = -1; + var indexRange = endNodeIndex - startNodeIndex; + var nearNodes = {}; + var inBetweenNodes = []; + var startAngle, endAngle, totalAngle, eachAngle; + var angle2, loc, node, origNode; + if (indexRange < 0) { + indexRange += nodes.length; } - } - for (i2 = 0; i2 < ids.length - 1; i2++) { - for (var j2 = i2 + 1; j2 < ids.length; j2++) { - var path1 = graph.childNodes(graph.entity(ids[i2])).map(function(e) { - return e.loc; - }); - var path2 = graph.childNodes(graph.entity(ids[j2])).map(function(e) { - return e.loc; - }); - var intersections = geoPathIntersections(path1, path2); - var common = utilArrayIntersection( - joined[0].nodes.map(function(n2) { - return n2.loc.toString(); - }), - intersections.map(function(n2) { - return n2.toString(); - }) - ); - if (common.length !== intersections.length) { - return "paths_intersect"; - } + var distance = geoVecLength(centroid, keyPoints[i2]) || 1e-4; + keyPoints[i2] = [ + centroid[0] + (keyPoints[i2][0] - centroid[0]) / distance * radius, + centroid[1] + (keyPoints[i2][1] - centroid[1]) / distance * radius + ]; + loc = projection2.invert(keyPoints[i2]); + node = keyNodes[i2]; + origNode = origNodes[node.id]; + node = node.move(geoVecInterp(origNode.loc, loc, t)); + graph = graph.replace(node); + startAngle = Math.atan2(keyPoints[i2][1] - centroid[1], keyPoints[i2][0] - centroid[0]); + endAngle = Math.atan2(keyPoints[nextKeyNodeIndex][1] - centroid[1], keyPoints[nextKeyNodeIndex][0] - centroid[0]); + totalAngle = endAngle - startAngle; + if (totalAngle * sign2 > 0) { + totalAngle = -sign2 * (2 * Math.PI - Math.abs(totalAngle)); } - } - var nodeIds = joined[0].nodes.map(function(n2) { - return n2.id; - }).slice(1, -1); - var relation; - var tags = {}; - var conflicting = false; - joined[0].forEach(function(way) { - var parents = graph.parentRelations(way); - parents.forEach(function(parent) { - if ((parent.isRestriction() || parent.isConnectivity()) && parent.members.some(function(m) { - return nodeIds.indexOf(m.id) >= 0; - })) { - relation = parent; - } - }); - for (var k in way.tags) { - if (!(k in tags)) { - tags[k] = way.tags[k]; - } else if (tags[k] && osmIsInterestingTag(k) && tags[k] !== way.tags[k]) { - conflicting = true; - } + do { + numberNewPoints++; + eachAngle = totalAngle / (indexRange + numberNewPoints); + } while (Math.abs(eachAngle) > maxAngle); + for (j2 = 1; j2 < indexRange; j2++) { + angle2 = startAngle + j2 * eachAngle; + loc = projection2.invert([ + centroid[0] + Math.cos(angle2) * radius, + centroid[1] + Math.sin(angle2) * radius + ]); + node = nodes[(j2 + startNodeIndex) % nodes.length]; + origNode = origNodes[node.id]; + nearNodes[node.id] = angle2; + node = node.move(geoVecInterp(origNode.loc, loc, t)); + graph = graph.replace(node); } - }); - if (relation) { - return relation.isRestriction() ? "restriction" : "connectivity"; - } - if (conflicting) { - return "conflicting_tags"; - } - }; - return action; - } - - // modules/actions/merge.js - function actionMerge(ids) { - function groupEntitiesByGeometry(graph) { - var entities = ids.map(function(id2) { - return graph.entity(id2); - }); - return Object.assign( - { point: [], area: [], line: [], relation: [] }, - utilArrayGroupBy(entities, function(entity) { - return entity.geometry(graph); - }) - ); - } - var action = function(graph) { - var geometries = groupEntitiesByGeometry(graph); - var target = geometries.area[0] || geometries.line[0]; - var points = geometries.point; - points.forEach(function(point) { - target = target.mergeTags(point.tags); - graph = graph.replace(target); - graph.parentRelations(point).forEach(function(parent) { - graph = graph.replace(parent.replaceMember(point, target)); - }); - var nodes = utilArrayUniq(graph.childNodes(target)); - var removeNode = point; - if (!point.isNew()) { - var inserted = false; - var canBeReplaced = function(node2) { - return !(graph.parentWays(node2).length > 1 || graph.parentRelations(node2).length); - }; - var replaceNode = function(node2) { - graph = graph.replace(point.update({ tags: node2.tags, loc: node2.loc })); - target = target.replaceNode(node2.id, point.id); - graph = graph.replace(target); - removeNode = node2; - inserted = true; - }; - var i2; - var node; - for (i2 = 0; i2 < nodes.length; i2++) { - node = nodes[i2]; - if (canBeReplaced(node) && node.isNew()) { - replaceNode(node); - break; + for (j2 = 0; j2 < numberNewPoints; j2++) { + angle2 = startAngle + (indexRange + j2) * eachAngle; + loc = projection2.invert([ + centroid[0] + Math.cos(angle2) * radius, + centroid[1] + Math.sin(angle2) * radius + ]); + var min3 = Infinity; + for (var nodeId in nearNodes) { + var nearAngle = nearNodes[nodeId]; + var dist = Math.abs(nearAngle - angle2); + if (dist < min3) { + min3 = dist; + origNode = origNodes[nodeId]; } } - if (!inserted && point.hasInterestingTags()) { - for (i2 = 0; i2 < nodes.length; i2++) { - node = nodes[i2]; - if (canBeReplaced(node) && !node.hasInterestingTags()) { - replaceNode(node); - break; + node = osmNode({ loc: geoVecInterp(origNode.loc, loc, t) }); + graph = graph.replace(node); + nodes.splice(endNodeIndex + j2, 0, node); + inBetweenNodes.push(node.id); + } + if (indexRange === 1 && inBetweenNodes.length) { + var startIndex1 = way.nodes.lastIndexOf(startNode.id); + var endIndex1 = way.nodes.lastIndexOf(endNode.id); + var wayDirection1 = endIndex1 - startIndex1; + if (wayDirection1 < -1) { + wayDirection1 = 1; + } + var parentWays = graph.parentWays(keyNodes[i2]); + for (j2 = 0; j2 < parentWays.length; j2++) { + var sharedWay = parentWays[j2]; + if (sharedWay === way) + continue; + if (sharedWay.areAdjacent(startNode.id, endNode.id)) { + var startIndex2 = sharedWay.nodes.lastIndexOf(startNode.id); + var endIndex2 = sharedWay.nodes.lastIndexOf(endNode.id); + var wayDirection2 = endIndex2 - startIndex2; + var insertAt = endIndex2; + if (wayDirection2 < -1) { + wayDirection2 = 1; } - } - if (!inserted) { - for (i2 = 0; i2 < nodes.length; i2++) { - node = nodes[i2]; - if (canBeReplaced(node) && utilCompareIDs(point.id, node.id) < 0) { - replaceNode(node); - break; - } + if (wayDirection1 !== wayDirection2) { + inBetweenNodes.reverse(); + insertAt = startIndex2; + } + for (k = 0; k < inBetweenNodes.length; k++) { + sharedWay = sharedWay.addNode(inBetweenNodes[k], insertAt + k); } + graph = graph.replace(sharedWay); } } } - graph = graph.remove(removeNode); + } + ids = nodes.map(function(n2) { + return n2.id; }); - if (target.tags.area === "yes") { - var tags = Object.assign({}, target.tags); - delete tags.area; - if (osmTagSuggestingArea(tags)) { - target = target.update({ tags }); - graph = graph.replace(target); + ids.push(ids[0]); + way = way.update({ nodes: ids }); + graph = graph.replace(way); + return graph; + }; + action.makeConvex = function(graph) { + var way = graph.entity(wayId); + var nodes = utilArrayUniq(graph.childNodes(way)); + var points = nodes.map(function(n2) { + return projection2(n2.loc); + }); + var sign2 = area_default3(points) > 0 ? 1 : -1; + var hull = hull_default(points); + var i2, j2; + if (sign2 === -1) { + nodes.reverse(); + points.reverse(); + } + for (i2 = 0; i2 < hull.length - 1; i2++) { + var startIndex = points.indexOf(hull[i2]); + var endIndex = points.indexOf(hull[i2 + 1]); + var indexRange = endIndex - startIndex; + if (indexRange < 0) { + indexRange += nodes.length; + } + for (j2 = 1; j2 < indexRange; j2++) { + var point2 = geoVecInterp(hull[i2], hull[i2 + 1], j2 / indexRange); + var node = nodes[(j2 + startIndex) % nodes.length].move(projection2.invert(point2)); + graph = graph.replace(node); } } return graph; }; action.disabled = function(graph) { - var geometries = groupEntitiesByGeometry(graph); - if (geometries.point.length === 0 || geometries.area.length + geometries.line.length !== 1 || geometries.relation.length !== 0) { - return "not_eligible"; + if (!graph.entity(wayId).isClosed()) { + return "not_closed"; + } + var way = graph.entity(wayId); + var nodes = utilArrayUniq(graph.childNodes(way)); + var points = nodes.map(function(n2) { + return projection2(n2.loc); + }); + var hull = hull_default(points); + var epsilonAngle = Math.PI / 180; + if (hull.length !== points.length || hull.length < 3) { + return false; + } + var centroid = centroid_default2(points); + var radius = geoVecLengthSquare(centroid, points[0]); + var i2, actualPoint; + for (i2 = 0; i2 < hull.length; i2++) { + actualPoint = hull[i2]; + var actualDist = geoVecLengthSquare(actualPoint, centroid); + var diff = Math.abs(actualDist - radius); + if (diff > 0.05 * radius) { + return false; + } + } + for (i2 = 0; i2 < hull.length; i2++) { + actualPoint = hull[i2]; + var nextPoint = hull[(i2 + 1) % hull.length]; + var startAngle = Math.atan2(actualPoint[1] - centroid[1], actualPoint[0] - centroid[0]); + var endAngle = Math.atan2(nextPoint[1] - centroid[1], nextPoint[0] - centroid[0]); + var angle2 = endAngle - startAngle; + if (angle2 < 0) { + angle2 = -angle2; + } + if (angle2 > Math.PI) { + angle2 = 2 * Math.PI - angle2; + } + if (angle2 > maxAngle + epsilonAngle) { + return false; + } } + return "already_circular"; }; + action.transitionable = true; return action; } - // modules/actions/merge_nodes.js - function actionMergeNodes(nodeIDs, loc) { - function chooseLoc(graph) { - if (!nodeIDs.length) - return null; - var sum = [0, 0]; - var interestingCount = 0; - var interestingLoc; - for (var i2 = 0; i2 < nodeIDs.length; i2++) { - var node = graph.entity(nodeIDs[i2]); - if (node.hasInterestingTags()) { - interestingLoc = ++interestingCount === 1 ? node.loc : null; - } - sum = geoVecAdd(sum, node.loc); - } - return interestingLoc || geoVecScale(sum, 1 / nodeIDs.length); + // modules/actions/delete_way.js + function actionDeleteWay(wayID) { + function canDeleteNode(node, graph) { + if (graph.parentWays(node).length || graph.parentRelations(node).length) + return false; + var geometries = osmNodeGeometriesForTags(node.tags); + if (geometries.point) + return false; + if (geometries.vertex) + return true; + return !node.hasInterestingTags(); } var action = function(graph) { - if (nodeIDs.length < 2) - return graph; - var toLoc = loc; - if (!toLoc) { - toLoc = chooseLoc(graph); - } - for (var i2 = 0; i2 < nodeIDs.length; i2++) { - var node = graph.entity(nodeIDs[i2]); - if (node.loc !== toLoc) { - graph = graph.replace(node.move(toLoc)); + var way = graph.entity(wayID); + graph.parentRelations(way).forEach(function(parent) { + parent = parent.removeMembersWithID(wayID); + graph = graph.replace(parent); + if (parent.isDegenerate()) { + graph = actionDeleteRelation(parent.id)(graph); } - } - return actionConnect(nodeIDs)(graph); + }); + new Set(way.nodes).forEach(function(nodeID) { + graph = graph.replace(way.removeNode(nodeID)); + var node = graph.entity(nodeID); + if (canDeleteNode(node, graph)) { + graph = graph.remove(node); + } + }); + return graph.remove(way); }; - action.disabled = function(graph) { - if (nodeIDs.length < 2) - return "not_eligible"; - for (var i2 = 0; i2 < nodeIDs.length; i2++) { - var entity = graph.entity(nodeIDs[i2]); - if (entity.type !== "node") - return "not_eligible"; - } - return actionConnect(nodeIDs).disabled(graph); + return action; + } + + // modules/actions/delete_multiple.js + function actionDeleteMultiple(ids) { + var actions = { + way: actionDeleteWay, + node: actionDeleteNode, + relation: actionDeleteRelation + }; + var action = function(graph) { + ids.forEach(function(id2) { + if (graph.hasEntity(id2)) { + graph = actions[graph.entity(id2).type](id2)(graph); + } + }); + return graph; }; return action; } - // modules/osm/changeset.js - function osmChangeset() { - if (!(this instanceof osmChangeset)) { - return new osmChangeset().initialize(arguments); - } else if (arguments.length) { - this.initialize(arguments); + // modules/actions/delete_relation.js + function actionDeleteRelation(relationID, allowUntaggedMembers) { + function canDeleteEntity(entity, graph) { + return !graph.parentWays(entity).length && !graph.parentRelations(entity).length && (!entity.hasInterestingTags() && !allowUntaggedMembers); } - } - osmEntity.changeset = osmChangeset; - osmChangeset.prototype = Object.create(osmEntity.prototype); - Object.assign(osmChangeset.prototype, { - type: "changeset", - extent: function() { - return new geoExtent(); - }, - geometry: function() { - return "changeset"; - }, - asJXON: function() { - return { - osm: { - changeset: { - tag: Object.keys(this.tags).map(function(k) { - return { "@k": k, "@v": this.tags[k] }; - }, this), - "@version": 0.6, - "@generator": "iD" - } + var action = function(graph) { + var relation = graph.entity(relationID); + graph.parentRelations(relation).forEach(function(parent) { + parent = parent.removeMembersWithID(relationID); + graph = graph.replace(parent); + if (parent.isDegenerate()) { + graph = actionDeleteRelation(parent.id)(graph); } - }; - }, - osmChangeJXON: function(changes) { - var changeset_id = this.id; - function nest(x, order) { - var groups = {}; - for (var i2 = 0; i2 < x.length; i2++) { - var tagName = Object.keys(x[i2])[0]; - if (!groups[tagName]) - groups[tagName] = []; - groups[tagName].push(x[i2][tagName]); + }); + var memberIDs = utilArrayUniq(relation.members.map(function(m) { + return m.id; + })); + memberIDs.forEach(function(memberID) { + graph = graph.replace(relation.removeMembersWithID(memberID)); + var entity = graph.entity(memberID); + if (canDeleteEntity(entity, graph)) { + graph = actionDeleteMultiple([memberID])(graph); + } + }); + return graph.remove(relation); + }; + return action; + } + + // modules/actions/delete_node.js + function actionDeleteNode(nodeId) { + var action = function(graph) { + var node = graph.entity(nodeId); + graph.parentWays(node).forEach(function(parent) { + parent = parent.removeNode(nodeId); + graph = graph.replace(parent); + if (parent.isDegenerate()) { + graph = actionDeleteWay(parent.id)(graph); + } + }); + graph.parentRelations(node).forEach(function(parent) { + parent = parent.removeMembersWithID(nodeId); + graph = graph.replace(parent); + if (parent.isDegenerate()) { + graph = actionDeleteRelation(parent.id)(graph); + } + }); + return graph.remove(node); + }; + return action; + } + + // modules/actions/connect.js + function actionConnect(nodeIDs) { + var action = function(graph) { + var survivor; + var node; + var parents; + var i2, j2; + nodeIDs.reverse(); + var interestingIDs = []; + for (i2 = 0; i2 < nodeIDs.length; i2++) { + node = graph.entity(nodeIDs[i2]); + if (node.hasInterestingTags()) { + if (!node.isNew()) { + interestingIDs.push(node.id); + } } - var ordered = {}; - order.forEach(function(o) { - if (groups[o]) - ordered[o] = groups[o]; - }); - return ordered; } - function sort(changes2) { - function resolve(item) { - return relations.find(function(relation2) { - return item.keyAttributes.type === "relation" && item.keyAttributes.ref === relation2["@id"]; - }); + survivor = graph.entity(utilOldestID(interestingIDs.length > 0 ? interestingIDs : nodeIDs)); + for (i2 = 0; i2 < nodeIDs.length; i2++) { + node = graph.entity(nodeIDs[i2]); + if (node.id === survivor.id) + continue; + parents = graph.parentWays(node); + for (j2 = 0; j2 < parents.length; j2++) { + graph = graph.replace(parents[j2].replaceNode(node.id, survivor.id)); } - function isNew(item) { - return !sorted[item["@id"]] && !processing.find(function(proc) { - return proc["@id"] === item["@id"]; - }); + parents = graph.parentRelations(node); + for (j2 = 0; j2 < parents.length; j2++) { + graph = graph.replace(parents[j2].replaceMember(node, survivor)); } - var processing = []; - var sorted = {}; - var relations = changes2.relation; - if (!relations) - return changes2; - for (var i2 = 0; i2 < relations.length; i2++) { - var relation = relations[i2]; - if (!sorted[relation["@id"]]) { - processing.push(relation); + survivor = survivor.mergeTags(node.tags); + graph = actionDeleteNode(node.id)(graph); + } + graph = graph.replace(survivor); + parents = graph.parentWays(survivor); + for (i2 = 0; i2 < parents.length; i2++) { + if (parents[i2].isDegenerate()) { + graph = actionDeleteWay(parents[i2].id)(graph); + } + } + return graph; + }; + action.disabled = function(graph) { + var seen = {}; + var restrictionIDs = []; + var survivor; + var node, way; + var relations, relation, role; + var i2, j2, k; + survivor = graph.entity(utilOldestID(nodeIDs)); + for (i2 = 0; i2 < nodeIDs.length; i2++) { + node = graph.entity(nodeIDs[i2]); + relations = graph.parentRelations(node); + for (j2 = 0; j2 < relations.length; j2++) { + relation = relations[j2]; + role = relation.memberById(node.id).role || ""; + if (relation.hasFromViaTo()) { + restrictionIDs.push(relation.id); } - while (processing.length > 0) { - var next = processing[0], deps = next.member.map(resolve).filter(Boolean).filter(isNew); - if (deps.length === 0) { - sorted[next["@id"]] = next; - processing.shift(); - } else { - processing = deps.concat(processing); - } + if (seen[relation.id] !== void 0 && seen[relation.id] !== role) { + return "relation"; + } else { + seen[relation.id] = role; } } - changes2.relation = Object.values(sorted); - return changes2; } - function rep2(entity) { - return entity.asJXON(changeset_id); + for (i2 = 0; i2 < nodeIDs.length; i2++) { + node = graph.entity(nodeIDs[i2]); + var parents = graph.parentWays(node); + for (j2 = 0; j2 < parents.length; j2++) { + var parent = parents[j2]; + relations = graph.parentRelations(parent); + for (k = 0; k < relations.length; k++) { + relation = relations[k]; + if (relation.hasFromViaTo()) { + restrictionIDs.push(relation.id); + } + } + } } - return { - osmChange: { - "@version": 0.6, - "@generator": "iD", - "create": sort(nest(changes.created.map(rep2), ["node", "way", "relation"])), - "modify": nest(changes.modified.map(rep2), ["node", "way", "relation"]), - "delete": Object.assign(nest(changes.deleted.map(rep2), ["relation", "way", "node"]), { "@if-unused": true }) + restrictionIDs = utilArrayUniq(restrictionIDs); + for (i2 = 0; i2 < restrictionIDs.length; i2++) { + relation = graph.entity(restrictionIDs[i2]); + if (!relation.isComplete(graph)) + continue; + var memberWays = relation.members.filter(function(m) { + return m.type === "way"; + }).map(function(m) { + return graph.entity(m.id); + }); + memberWays = utilArrayUniq(memberWays); + var f2 = relation.memberByRole("from"); + var t = relation.memberByRole("to"); + var isUturn = f2.id === t.id; + var nodes = { from: [], via: [], to: [], keyfrom: [], keyto: [] }; + for (j2 = 0; j2 < relation.members.length; j2++) { + collectNodes(relation.members[j2], nodes); } - }; - }, - asGeoJSON: function() { - return {}; - } - }); - - // modules/osm/note.js - function osmNote() { - if (!(this instanceof osmNote)) { - return new osmNote().initialize(arguments); - } else if (arguments.length) { - this.initialize(arguments); - } - } - osmNote.id = function() { - return osmNote.id.next--; - }; - osmNote.id.next = -1; - Object.assign(osmNote.prototype, { - type: "note", - initialize: function(sources) { - for (var i2 = 0; i2 < sources.length; ++i2) { - var source = sources[i2]; - for (var prop in source) { - if (Object.prototype.hasOwnProperty.call(source, prop)) { - if (source[prop] === void 0) { - delete this[prop]; + nodes.keyfrom = utilArrayUniq(nodes.keyfrom.filter(hasDuplicates)); + nodes.keyto = utilArrayUniq(nodes.keyto.filter(hasDuplicates)); + var filter2 = keyNodeFilter(nodes.keyfrom, nodes.keyto); + nodes.from = nodes.from.filter(filter2); + nodes.via = nodes.via.filter(filter2); + nodes.to = nodes.to.filter(filter2); + var connectFrom = false; + var connectVia = false; + var connectTo = false; + var connectKeyFrom = false; + var connectKeyTo = false; + for (j2 = 0; j2 < nodeIDs.length; j2++) { + var n2 = nodeIDs[j2]; + if (nodes.from.indexOf(n2) !== -1) { + connectFrom = true; + } + if (nodes.via.indexOf(n2) !== -1) { + connectVia = true; + } + if (nodes.to.indexOf(n2) !== -1) { + connectTo = true; + } + if (nodes.keyfrom.indexOf(n2) !== -1) { + connectKeyFrom = true; + } + if (nodes.keyto.indexOf(n2) !== -1) { + connectKeyTo = true; + } + } + if (connectFrom && connectTo && !isUturn) { + return "restriction"; + } + if (connectFrom && connectVia) { + return "restriction"; + } + if (connectTo && connectVia) { + return "restriction"; + } + if (connectKeyFrom || connectKeyTo) { + if (nodeIDs.length !== 2) { + return "restriction"; + } + var n0 = null; + var n1 = null; + for (j2 = 0; j2 < memberWays.length; j2++) { + way = memberWays[j2]; + if (way.contains(nodeIDs[0])) { + n0 = nodeIDs[0]; + } + if (way.contains(nodeIDs[1])) { + n1 = nodeIDs[1]; + } + } + if (n0 && n1) { + var ok = false; + for (j2 = 0; j2 < memberWays.length; j2++) { + way = memberWays[j2]; + if (way.areAdjacent(n0, n1)) { + ok = true; + break; + } + } + if (!ok) { + return "restriction"; + } + } + } + for (j2 = 0; j2 < memberWays.length; j2++) { + way = memberWays[j2].update({}); + for (k = 0; k < nodeIDs.length; k++) { + if (nodeIDs[k] === survivor.id) + continue; + if (way.areAdjacent(nodeIDs[k], survivor.id)) { + way = way.removeNode(nodeIDs[k]); } else { - this[prop] = source[prop]; + way = way.replaceNode(nodeIDs[k], survivor.id); } } + if (way.isDegenerate()) { + return "restriction"; + } } } - if (!this.id) { - this.id = osmNote.id().toString(); + return false; + function hasDuplicates(n3, i3, arr) { + return arr.indexOf(n3) !== arr.lastIndexOf(n3); } - return this; - }, - extent: function() { - return new geoExtent(this.loc); - }, - update: function(attrs) { - return osmNote(this, attrs); - }, - isNew: function() { - return this.id < 0; - }, - move: function(loc) { - return this.update({ loc }); - } - }); - - // modules/osm/relation.js - function osmRelation() { - if (!(this instanceof osmRelation)) { - return new osmRelation().initialize(arguments); - } else if (arguments.length) { - this.initialize(arguments); - } - } - osmEntity.relation = osmRelation; - osmRelation.prototype = Object.create(osmEntity.prototype); - osmRelation.creationOrder = function(a, b) { - var aId = parseInt(osmEntity.id.toOSM(a.id), 10); - var bId = parseInt(osmEntity.id.toOSM(b.id), 10); - if (aId < 0 || bId < 0) - return aId - bId; - return bId - aId; - }; - Object.assign(osmRelation.prototype, { - type: "relation", - members: [], - copy: function(resolver, copies) { - if (copies[this.id]) - return copies[this.id]; - var copy2 = osmEntity.prototype.copy.call(this, resolver, copies); - var members = this.members.map(function(member) { - return Object.assign({}, member, { id: resolver.entity(member.id).copy(resolver, copies).id }); - }); - copy2 = copy2.update({ members }); - copies[this.id] = copy2; - return copy2; - }, - extent: function(resolver, memo) { - return resolver.transient(this, "extent", function() { - if (memo && memo[this.id]) - return geoExtent(); - memo = memo || {}; - memo[this.id] = true; - var extent = geoExtent(); - for (var i2 = 0; i2 < this.members.length; i2++) { - var member = resolver.hasEntity(this.members[i2].id); - if (member) { - extent._extend(member.extent(resolver, memo)); + function keyNodeFilter(froms, tos) { + return function(n3) { + return froms.indexOf(n3) === -1 && tos.indexOf(n3) === -1; + }; + } + function collectNodes(member, collection) { + var entity = graph.hasEntity(member.id); + if (!entity) + return; + var role2 = member.role || ""; + if (!collection[role2]) { + collection[role2] = []; + } + if (member.type === "node") { + collection[role2].push(member.id); + if (role2 === "via") { + collection.keyfrom.push(member.id); + collection.keyto.push(member.id); + } + } else if (member.type === "way") { + collection[role2].push.apply(collection[role2], entity.nodes); + if (role2 === "from" || role2 === "via") { + collection.keyfrom.push(entity.first()); + collection.keyfrom.push(entity.last()); + } + if (role2 === "to" || role2 === "via") { + collection.keyto.push(entity.first()); + collection.keyto.push(entity.last()); } } - return extent; - }); - }, - geometry: function(graph) { - return graph.transient(this, "geometry", function() { - return this.isMultipolygon() ? "area" : "relation"; + } + }; + return action; + } + + // modules/actions/copy_entities.js + function actionCopyEntities(ids, fromGraph) { + var _copies = {}; + var action = function(graph) { + ids.forEach(function(id3) { + fromGraph.entity(id3).copy(fromGraph, _copies); }); - }, - isDegenerate: function() { - return this.members.length === 0; - }, - indexedMembers: function() { - var result = new Array(this.members.length); - for (var i2 = 0; i2 < this.members.length; i2++) { - result[i2] = Object.assign({}, this.members[i2], { index: i2 }); + for (var id2 in _copies) { + graph = graph.replace(_copies[id2]); } - return result; - }, - memberByRole: function(role) { - for (var i2 = 0; i2 < this.members.length; i2++) { - if (this.members[i2].role === role) { - return Object.assign({}, this.members[i2], { index: i2 }); - } + return graph; + }; + action.copies = function() { + return _copies; + }; + return action; + } + + // modules/actions/delete_member.js + function actionDeleteMember(relationId, memberIndex) { + return function(graph) { + var relation = graph.entity(relationId).removeMember(memberIndex); + graph = graph.replace(relation); + if (relation.isDegenerate()) { + graph = actionDeleteRelation(relation.id)(graph); } - }, - membersByRole: function(role) { - var result = []; - for (var i2 = 0; i2 < this.members.length; i2++) { - if (this.members[i2].role === role) { - result.push(Object.assign({}, this.members[i2], { index: i2 })); + return graph; + }; + } + + // modules/actions/discard_tags.js + function actionDiscardTags(difference, discardTags) { + discardTags = discardTags || {}; + return (graph) => { + difference.modified().forEach(checkTags); + difference.created().forEach(checkTags); + return graph; + function checkTags(entity) { + const keys2 = Object.keys(entity.tags); + let didDiscard = false; + let tags = {}; + for (let i2 = 0; i2 < keys2.length; i2++) { + const k = keys2[i2]; + if (discardTags[k] || !entity.tags[k]) { + didDiscard = true; + } else { + tags[k] = entity.tags[k]; + } } - } - return result; - }, - memberById: function(id2) { - for (var i2 = 0; i2 < this.members.length; i2++) { - if (this.members[i2].id === id2) { - return Object.assign({}, this.members[i2], { index: i2 }); + if (didDiscard) { + graph = graph.replace(entity.update({ tags })); } } - }, - memberByIdAndRole: function(id2, role) { - for (var i2 = 0; i2 < this.members.length; i2++) { - if (this.members[i2].id === id2 && this.members[i2].role === role) { - return Object.assign({}, this.members[i2], { index: i2 }); + }; + } + + // modules/actions/disconnect.js + function actionDisconnect(nodeId, newNodeId) { + var wayIds; + var disconnectableRelationTypes = { + "associatedStreet": true, + "enforcement": true, + "site": true + }; + var action = function(graph) { + var node = graph.entity(nodeId); + var connections = action.connections(graph); + connections.forEach(function(connection) { + var way = graph.entity(connection.wayID); + var newNode = osmNode({ id: newNodeId, loc: node.loc, tags: node.tags }); + graph = graph.replace(newNode); + if (connection.index === 0 && way.isArea()) { + graph = graph.replace(way.replaceNode(way.nodes[0], newNode.id)); + } else if (way.isClosed() && connection.index === way.nodes.length - 1) { + graph = graph.replace(way.unclose().addNode(newNode.id)); + } else { + graph = graph.replace(way.updateNode(newNode.id, connection.index)); } - } - }, - addMember: function(member, index) { - var members = this.members.slice(); - members.splice(index === void 0 ? members.length : index, 0, member); - return this.update({ members }); - }, - updateMember: function(member, index) { - var members = this.members.slice(); - members.splice(index, 1, Object.assign({}, members[index], member)); - return this.update({ members }); - }, - removeMember: function(index) { - var members = this.members.slice(); - members.splice(index, 1); - return this.update({ members }); - }, - removeMembersWithID: function(id2) { - var members = this.members.filter(function(m) { - return m.id !== id2; }); - return this.update({ members }); - }, - moveMember: function(fromIndex, toIndex) { - var members = this.members.slice(); - members.splice(toIndex, 0, members.splice(fromIndex, 1)[0]); - return this.update({ members }); - }, - replaceMember: function(needle, replacement, keepDuplicates) { - if (!this.memberById(needle.id)) - return this; - var members = []; - for (var i2 = 0; i2 < this.members.length; i2++) { - var member = this.members[i2]; - if (member.id !== needle.id) { - members.push(member); - } else if (keepDuplicates || !this.memberByIdAndRole(replacement.id, member.role)) { - members.push({ id: replacement.id, type: replacement.type, role: member.role }); + return graph; + }; + action.connections = function(graph) { + var candidates = []; + var keeping = false; + var parentWays = graph.parentWays(graph.entity(nodeId)); + var way, waynode; + for (var i2 = 0; i2 < parentWays.length; i2++) { + way = parentWays[i2]; + if (wayIds && wayIds.indexOf(way.id) === -1) { + keeping = true; + continue; } - } - return this.update({ members }); - }, - asJXON: function(changeset_id) { - var r = { - relation: { - "@id": this.osmId(), - "@version": this.version || 0, - member: this.members.map(function(member) { - return { - keyAttributes: { - type: member.type, - role: member.role, - ref: osmEntity.id.toOSM(member.id) + if (way.isArea() && way.nodes[0] === nodeId) { + candidates.push({ wayID: way.id, index: 0 }); + } else { + for (var j2 = 0; j2 < way.nodes.length; j2++) { + waynode = way.nodes[j2]; + if (waynode === nodeId) { + if (way.isClosed() && parentWays.length > 1 && wayIds && wayIds.indexOf(way.id) !== -1 && j2 === way.nodes.length - 1) { + continue; } - }; - }, this), - tag: Object.keys(this.tags).map(function(k) { - return { keyAttributes: { k, v: this.tags[k] } }; - }, this) + candidates.push({ wayID: way.id, index: j2 }); + } + } } - }; - if (changeset_id) { - r.relation["@changeset"] = changeset_id; } - return r; - }, - asGeoJSON: function(resolver) { - return resolver.transient(this, "GeoJSON", function() { - if (this.isMultipolygon()) { - return { - type: "MultiPolygon", - coordinates: this.multipolygon(resolver) - }; - } else { - return { - type: "FeatureCollection", - properties: this.tags, - features: this.members.map(function(member) { - return Object.assign({ role: member.role }, resolver.entity(member.id).asGeoJSON(resolver)); - }) - }; - } - }); - }, - area: function(resolver) { - return resolver.transient(this, "area", function() { - return area_default(this.asGeoJSON(resolver)); + return keeping ? candidates : candidates.slice(1); + }; + action.disabled = function(graph) { + var connections = action.connections(graph); + if (connections.length === 0) + return "not_connected"; + var parentWays = graph.parentWays(graph.entity(nodeId)); + var seenRelationIds = {}; + var sharedRelation; + parentWays.forEach(function(way) { + var relations = graph.parentRelations(way); + relations.filter((relation) => !disconnectableRelationTypes[relation.tags.type]).forEach(function(relation) { + if (relation.id in seenRelationIds) { + if (wayIds) { + if (wayIds.indexOf(way.id) !== -1 || wayIds.indexOf(seenRelationIds[relation.id]) !== -1) { + sharedRelation = relation; + } + } else { + sharedRelation = relation; + } + } else { + seenRelationIds[relation.id] = way.id; + } + }); }); - }, - isMultipolygon: function() { - return this.tags.type === "multipolygon"; - }, - isComplete: function(resolver) { - for (var i2 = 0; i2 < this.members.length; i2++) { - if (!resolver.hasEntity(this.members[i2].id)) { - return false; - } + if (sharedRelation) + return "relation"; + }; + action.limitWays = function(val) { + if (!arguments.length) + return wayIds; + wayIds = val; + return action; + }; + return action; + } + + // modules/actions/extract.js + function actionExtract(entityID, projection2) { + var extractedNodeID; + var action = function(graph) { + var entity = graph.entity(entityID); + if (entity.type === "node") { + return extractFromNode(entity, graph); } - return true; - }, - hasFromViaTo: function() { - return this.members.some(function(m) { - return m.role === "from"; - }) && this.members.some(function(m) { - return m.role === "via"; - }) && this.members.some(function(m) { - return m.role === "to"; - }); - }, - isRestriction: function() { - return !!(this.tags.type && this.tags.type.match(/^restriction:?/)); - }, - isValidRestriction: function() { - if (!this.isRestriction()) - return false; - var froms = this.members.filter(function(m) { - return m.role === "from"; - }); - var vias = this.members.filter(function(m) { - return m.role === "via"; - }); - var tos = this.members.filter(function(m) { - return m.role === "to"; - }); - if (froms.length !== 1 && this.tags.restriction !== "no_entry") - return false; - if (froms.some(function(m) { - return m.type !== "way"; - })) - return false; - if (tos.length !== 1 && this.tags.restriction !== "no_exit") - return false; - if (tos.some(function(m) { - return m.type !== "way"; - })) - return false; - if (vias.length === 0) - return false; - if (vias.length > 1 && vias.some(function(m) { - return m.type !== "way"; - })) - return false; - return true; - }, - isConnectivity: function() { - return !!(this.tags.type && this.tags.type.match(/^connectivity:?/)); - }, - multipolygon: function(resolver) { - var outers = this.members.filter(function(m) { - return "outer" === (m.role || "outer"); - }); - var inners = this.members.filter(function(m) { - return "inner" === m.role; - }); - outers = osmJoinWays(outers, resolver); - inners = osmJoinWays(inners, resolver); - var sequenceToLineString = function(sequence) { - if (sequence.nodes.length > 2 && sequence.nodes[0] !== sequence.nodes[sequence.nodes.length - 1]) { - sequence.nodes.push(sequence.nodes[0]); - } - return sequence.nodes.map(function(node) { - return node.loc; - }); + return extractFromWayOrRelation(entity, graph); + }; + function extractFromNode(node, graph) { + extractedNodeID = node.id; + var replacement = osmNode({ loc: node.loc }); + graph = graph.replace(replacement); + graph = graph.parentWays(node).reduce(function(accGraph, parentWay) { + return accGraph.replace(parentWay.replaceNode(entityID, replacement.id)); + }, graph); + return graph.parentRelations(node).reduce(function(accGraph, parentRel) { + return accGraph.replace(parentRel.replaceMember(node, replacement)); + }, graph); + } + function extractFromWayOrRelation(entity, graph) { + var fromGeometry = entity.geometry(graph); + var keysToCopyAndRetain = ["source", "wheelchair"]; + var keysToRetain = ["area"]; + var buildingKeysToRetain = ["architect", "building", "height", "layer"]; + var extractedLoc = path_default(projection2).centroid(entity.asGeoJSON(graph)); + extractedLoc = extractedLoc && projection2.invert(extractedLoc); + if (!extractedLoc || !isFinite(extractedLoc[0]) || !isFinite(extractedLoc[1])) { + extractedLoc = entity.extent(graph).center(); + } + var indoorAreaValues = { + area: true, + corridor: true, + elevator: true, + level: true, + room: true }; - outers = outers.map(sequenceToLineString); - inners = inners.map(sequenceToLineString); - var result = outers.map(function(o2) { - return [area_default({ type: "Polygon", coordinates: [o2] }) > 2 * Math.PI ? o2.reverse() : o2]; - }); - function findOuter(inner2) { - var o2, outer; - for (o2 = 0; o2 < outers.length; o2++) { - outer = outers[o2]; - if (geoPolygonContainsPolygon(outer, inner2)) { - return o2; - } + var isBuilding = entity.tags.building && entity.tags.building !== "no" || entity.tags["building:part"] && entity.tags["building:part"] !== "no"; + var isIndoorArea = fromGeometry === "area" && entity.tags.indoor && indoorAreaValues[entity.tags.indoor]; + var entityTags = Object.assign({}, entity.tags); + var pointTags = {}; + for (var key in entityTags) { + if (entity.type === "relation" && key === "type") { + continue; } - for (o2 = 0; o2 < outers.length; o2++) { - outer = outers[o2]; - if (geoPolygonIntersectsPolygon(outer, inner2, false)) { - return o2; - } + if (keysToRetain.indexOf(key) !== -1) { + continue; } - } - for (var i2 = 0; i2 < inners.length; i2++) { - var inner = inners[i2]; - if (area_default({ type: "Polygon", coordinates: [inner] }) < 2 * Math.PI) { - inner = inner.reverse(); + if (isBuilding) { + if (buildingKeysToRetain.indexOf(key) !== -1 || key.match(/^building:.{1,}/) || key.match(/^roof:.{1,}/)) + continue; } - var o = findOuter(inners[i2]); - if (o !== void 0) { - result[o].push(inners[i2]); - } else { - result.push([inners[i2]]); + if (isIndoorArea && key === "indoor") { + continue; + } + pointTags[key] = entityTags[key]; + if (keysToCopyAndRetain.indexOf(key) !== -1 || key.match(/^addr:.{1,}/)) { + continue; + } else if (isIndoorArea && key === "level") { + continue; } + delete entityTags[key]; } - return result; - } - }); - - // modules/osm/qa_item.js - var QAItem = class { - constructor(loc, service, itemType, id2, props) { - this.loc = loc; - this.service = service.title; - this.itemType = itemType; - this.id = id2 ? id2 : `${QAItem.id()}`; - this.update(props); - if (service && typeof service.getIcon === "function") { - this.icon = service.getIcon(itemType); + if (!isBuilding && !isIndoorArea && fromGeometry === "area") { + entityTags.area = "yes"; } + var replacement = osmNode({ loc: extractedLoc, tags: pointTags }); + graph = graph.replace(replacement); + extractedNodeID = replacement.id; + return graph.replace(entity.update({ tags: entityTags })); } - update(props) { - const { loc, service, itemType, id: id2 } = this; - Object.keys(props).forEach((prop) => this[prop] = props[prop]); - this.loc = loc; - this.service = service; - this.itemType = itemType; - this.id = id2; - return this; - } - static id() { - return this.nextId--; - } - }; - QAItem.nextId = -1; + action.getExtractedNodeID = function() { + return extractedNodeID; + }; + return action; + } - // modules/actions/split.js - function actionSplit(nodeIds, newWayIds) { - if (typeof nodeIds === "string") - nodeIds = [nodeIds]; - var _wayIDs; - var _keepHistoryOn = "longest"; - var _createdWayIDs = []; - function dist(graph, nA, nB) { - var locA = graph.entity(nA).loc; - var locB = graph.entity(nB).loc; - var epsilon3 = 1e-6; - return locA && locB ? geoSphericalDistance(locA, locB) : epsilon3; + // modules/actions/join.js + function actionJoin(ids) { + function groupEntitiesByGeometry(graph) { + var entities = ids.map(function(id2) { + return graph.entity(id2); + }); + return Object.assign( + { line: [] }, + utilArrayGroupBy(entities, function(entity) { + return entity.geometry(graph); + }) + ); } - function splitArea(nodes, idxA, graph) { - var lengths = new Array(nodes.length); - var length; - var i2; - var best = 0; - var idxB; - function wrap2(index) { - return utilWrap(index, nodes.length); - } - length = 0; - for (i2 = wrap2(idxA + 1); i2 !== idxA; i2 = wrap2(i2 + 1)) { - length += dist(graph, nodes[i2], nodes[wrap2(i2 - 1)]); - lengths[i2] = length; - } - length = 0; - for (i2 = wrap2(idxA - 1); i2 !== idxA; i2 = wrap2(i2 - 1)) { - length += dist(graph, nodes[i2], nodes[wrap2(i2 + 1)]); - if (length < lengths[i2]) { - lengths[i2] = length; + var action = function(graph) { + var ways = ids.map(graph.entity, graph); + var survivorID = utilOldestID(ways.map((way) => way.id)); + ways.sort(function(a, b) { + var aSided = a.isSided(); + var bSided = b.isSided(); + return aSided && !bSided ? -1 : bSided && !aSided ? 1 : 0; + }); + var sequences = osmJoinWays(ways, graph); + var joined = sequences[0]; + graph = sequences.actions.reduce(function(g, action2) { + return action2(g); + }, graph); + var survivor = graph.entity(survivorID); + survivor = survivor.update({ nodes: joined.nodes.map(function(n2) { + return n2.id; + }) }); + graph = graph.replace(survivor); + joined.forEach(function(way) { + if (way.id === survivorID) + return; + graph.parentRelations(way).forEach(function(parent) { + graph = graph.replace(parent.replaceMember(way, survivor)); + }); + survivor = survivor.mergeTags(way.tags); + graph = graph.replace(survivor); + graph = actionDeleteWay(way.id)(graph); + }); + function checkForSimpleMultipolygon() { + if (!survivor.isClosed()) + return; + var multipolygons = graph.parentMultipolygons(survivor).filter(function(multipolygon2) { + return multipolygon2.members.length === 1; + }); + if (multipolygons.length !== 1) + return; + var multipolygon = multipolygons[0]; + for (var key in survivor.tags) { + if (multipolygon.tags[key] && // don't collapse if tags cannot be cleanly merged + multipolygon.tags[key] !== survivor.tags[key]) + return; } - } - for (i2 = 0; i2 < nodes.length; i2++) { - var cost = lengths[i2] / dist(graph, nodes[idxA], nodes[i2]); - if (cost > best) { - idxB = i2; - best = cost; + survivor = survivor.mergeTags(multipolygon.tags); + graph = graph.replace(survivor); + graph = actionDeleteRelation( + multipolygon.id, + true + /* allow untagged members */ + )(graph); + var tags = Object.assign({}, survivor.tags); + if (survivor.geometry(graph) !== "area") { + tags.area = "yes"; } + delete tags.type; + survivor = survivor.update({ tags }); + graph = graph.replace(survivor); } - return idxB; - } - function totalLengthBetweenNodes(graph, nodes) { - var totalLength = 0; - for (var i2 = 0; i2 < nodes.length - 1; i2++) { - totalLength += dist(graph, nodes[i2], nodes[i2 + 1]); + checkForSimpleMultipolygon(); + return graph; + }; + action.resultingWayNodesLength = function(graph) { + return ids.reduce(function(count, id2) { + return count + graph.entity(id2).nodes.length; + }, 0) - ids.length - 1; + }; + action.disabled = function(graph) { + var geometries = groupEntitiesByGeometry(graph); + if (ids.length < 2 || ids.length !== geometries.line.length) { + return "not_eligible"; } - return totalLength; - } - function split(graph, nodeId, wayA, newWayId) { - var wayB = osmWay({ id: newWayId, tags: wayA.tags }); - var origNodes = wayA.nodes.slice(); - var nodesA; - var nodesB; - var isArea = wayA.isArea(); - var isOuter = osmIsOldMultipolygonOuterMember(wayA, graph); - if (wayA.isClosed()) { - var nodes = wayA.nodes.slice(0, -1); - var idxA = nodes.indexOf(nodeId); - var idxB = splitArea(nodes, idxA, graph); - if (idxB < idxA) { - nodesA = nodes.slice(idxA).concat(nodes.slice(0, idxB + 1)); - nodesB = nodes.slice(idxB, idxA + 1); - } else { - nodesA = nodes.slice(idxA, idxB + 1); - nodesB = nodes.slice(idxB).concat(nodes.slice(0, idxA + 1)); - } - } else { - var idx = wayA.nodes.indexOf(nodeId, 1); - nodesA = wayA.nodes.slice(0, idx + 1); - nodesB = wayA.nodes.slice(idx); + var joined = osmJoinWays(ids.map(graph.entity, graph), graph); + if (joined.length > 1) { + return "not_adjacent"; } - var lengthA = totalLengthBetweenNodes(graph, nodesA); - var lengthB = totalLengthBetweenNodes(graph, nodesB); - if (_keepHistoryOn === "longest" && lengthB > lengthA) { - wayA = wayA.update({ nodes: nodesB }); - wayB = wayB.update({ nodes: nodesA }); - var temp = lengthA; - lengthA = lengthB; - lengthB = temp; - } else { - wayA = wayA.update({ nodes: nodesA }); - wayB = wayB.update({ nodes: nodesB }); + var i2; + var sortedParentRelations = function(id2) { + return graph.parentRelations(graph.entity(id2)).filter((rel) => !rel.isRestriction() && !rel.isConnectivity()).sort((a, b) => a.id - b.id); + }; + var relsA = sortedParentRelations(ids[0]); + for (i2 = 1; i2 < ids.length; i2++) { + var relsB = sortedParentRelations(ids[i2]); + if (!utilArrayIdentical(relsA, relsB)) { + return "conflicting_relations"; + } } - if (wayA.tags.step_count) { - var stepCount = parseFloat(wayA.tags.step_count); - if (stepCount && isFinite(stepCount) && stepCount > 0 && Math.round(stepCount) === stepCount) { - var tagsA = Object.assign({}, wayA.tags); - var tagsB = Object.assign({}, wayB.tags); - var ratioA = lengthA / (lengthA + lengthB); - var countA = Math.round(stepCount * ratioA); - tagsA.step_count = countA.toString(); - tagsB.step_count = (stepCount - countA).toString(); - wayA = wayA.update({ tags: tagsA }); - wayB = wayB.update({ tags: tagsB }); + for (i2 = 0; i2 < ids.length - 1; i2++) { + for (var j2 = i2 + 1; j2 < ids.length; j2++) { + var path1 = graph.childNodes(graph.entity(ids[i2])).map(function(e) { + return e.loc; + }); + var path2 = graph.childNodes(graph.entity(ids[j2])).map(function(e) { + return e.loc; + }); + var intersections = geoPathIntersections(path1, path2); + var common = utilArrayIntersection( + joined[0].nodes.map(function(n2) { + return n2.loc.toString(); + }), + intersections.map(function(n2) { + return n2.toString(); + }) + ); + if (common.length !== intersections.length) { + return "paths_intersect"; + } } } - graph = graph.replace(wayA); - graph = graph.replace(wayB); - graph.parentRelations(wayA).forEach(function(relation) { - var member; - if (relation.hasFromViaTo()) { - var f2 = relation.memberByRole("from"); - var v = relation.membersByRole("via"); - var t = relation.memberByRole("to"); - var i2; - if (f2.id === wayA.id || t.id === wayA.id) { - var keepB = false; - if (v.length === 1 && v[0].type === "node") { - keepB = wayB.contains(v[0].id); - } else { - for (i2 = 0; i2 < v.length; i2++) { - if (v[i2].type === "way") { - var wayVia = graph.hasEntity(v[i2].id); - if (wayVia && utilArrayIntersection(wayB.nodes, wayVia.nodes).length) { - keepB = true; - break; - } - } - } - } - if (keepB) { - relation = relation.replaceMember(wayA, wayB); - graph = graph.replace(relation); - } - } else { - for (i2 = 0; i2 < v.length; i2++) { - if (v[i2].type === "way" && v[i2].id === wayA.id) { - member = { - id: wayB.id, - type: "way", - role: "via" - }; - graph = actionAddMember(relation.id, member, v[i2].index + 1)(graph); - break; - } - } + var nodeIds = joined[0].nodes.map(function(n2) { + return n2.id; + }).slice(1, -1); + var relation; + var tags = {}; + var conflicting = false; + joined[0].forEach(function(way) { + var parents = graph.parentRelations(way); + parents.forEach(function(parent) { + if ((parent.isRestriction() || parent.isConnectivity()) && parent.members.some(function(m) { + return nodeIds.indexOf(m.id) >= 0; + })) { + relation = parent; } - } else { - if (relation === isOuter) { - graph = graph.replace(relation.mergeTags(wayA.tags)); - graph = graph.replace(wayA.update({ tags: {} })); - graph = graph.replace(wayB.update({ tags: {} })); + }); + for (var k in way.tags) { + if (!(k in tags)) { + tags[k] = way.tags[k]; + } else if (tags[k] && osmIsInterestingTag(k) && tags[k] !== way.tags[k]) { + conflicting = true; } - member = { - id: wayB.id, - type: "way", - role: relation.memberById(wayA.id).role - }; - var insertPair = { - originalID: wayA.id, - insertedID: wayB.id, - nodes: origNodes - }; - graph = actionAddMember(relation.id, member, void 0, insertPair)(graph); } }); - if (!isOuter && isArea) { - var multipolygon = osmRelation({ - tags: Object.assign({}, wayA.tags, { type: "multipolygon" }), - members: [ - { id: wayA.id, role: "outer", type: "way" }, - { id: wayB.id, role: "outer", type: "way" } - ] - }); - graph = graph.replace(multipolygon); - graph = graph.replace(wayA.update({ tags: {} })); - graph = graph.replace(wayB.update({ tags: {} })); + if (relation) { + return relation.isRestriction() ? "restriction" : "connectivity"; } - _createdWayIDs.push(wayB.id); - return graph; + if (conflicting) { + return "conflicting_tags"; + } + }; + return action; + } + + // modules/actions/merge.js + function actionMerge(ids) { + function groupEntitiesByGeometry(graph) { + var entities = ids.map(function(id2) { + return graph.entity(id2); + }); + return Object.assign( + { point: [], area: [], line: [], relation: [] }, + utilArrayGroupBy(entities, function(entity) { + return entity.geometry(graph); + }) + ); } var action = function(graph) { - _createdWayIDs = []; - var newWayIndex = 0; - for (var i2 = 0; i2 < nodeIds.length; i2++) { - var nodeId = nodeIds[i2]; - var candidates = action.waysForNode(nodeId, graph); - for (var j2 = 0; j2 < candidates.length; j2++) { - graph = split(graph, nodeId, candidates[j2], newWayIds && newWayIds[newWayIndex]); - newWayIndex += 1; + var geometries = groupEntitiesByGeometry(graph); + var target = geometries.area[0] || geometries.line[0]; + var points = geometries.point; + points.forEach(function(point2) { + target = target.mergeTags(point2.tags); + graph = graph.replace(target); + graph.parentRelations(point2).forEach(function(parent) { + graph = graph.replace(parent.replaceMember(point2, target)); + }); + var nodes = utilArrayUniq(graph.childNodes(target)); + var removeNode = point2; + if (!point2.isNew()) { + var inserted = false; + var canBeReplaced = function(node2) { + return !(graph.parentWays(node2).length > 1 || graph.parentRelations(node2).length); + }; + var replaceNode = function(node2) { + graph = graph.replace(point2.update({ tags: node2.tags, loc: node2.loc })); + target = target.replaceNode(node2.id, point2.id); + graph = graph.replace(target); + removeNode = node2; + inserted = true; + }; + var i2; + var node; + for (i2 = 0; i2 < nodes.length; i2++) { + node = nodes[i2]; + if (canBeReplaced(node) && node.isNew()) { + replaceNode(node); + break; + } + } + if (!inserted && point2.hasInterestingTags()) { + for (i2 = 0; i2 < nodes.length; i2++) { + node = nodes[i2]; + if (canBeReplaced(node) && !node.hasInterestingTags()) { + replaceNode(node); + break; + } + } + if (!inserted) { + for (i2 = 0; i2 < nodes.length; i2++) { + node = nodes[i2]; + if (canBeReplaced(node) && utilCompareIDs(point2.id, node.id) < 0) { + replaceNode(node); + break; + } + } + } + } + } + graph = graph.remove(removeNode); + }); + if (target.tags.area === "yes") { + var tags = Object.assign({}, target.tags); + delete tags.area; + if (osmTagSuggestingArea(tags)) { + target = target.update({ tags }); + graph = graph.replace(target); } } return graph; }; - action.getCreatedWayIDs = function() { - return _createdWayIDs; + action.disabled = function(graph) { + var geometries = groupEntitiesByGeometry(graph); + if (geometries.point.length === 0 || geometries.area.length + geometries.line.length !== 1 || geometries.relation.length !== 0) { + return "not_eligible"; + } }; - action.waysForNode = function(nodeId, graph) { - var node = graph.entity(nodeId); - var splittableParents = graph.parentWays(node).filter(isSplittable); - if (!_wayIDs) { - var hasLine = splittableParents.some(function(parent) { - return parent.geometry(graph) === "line"; - }); - if (hasLine) { - return splittableParents.filter(function(parent) { - return parent.geometry(graph) === "line"; - }); + return action; + } + + // modules/actions/merge_nodes.js + function actionMergeNodes(nodeIDs, loc) { + function chooseLoc(graph) { + if (!nodeIDs.length) + return null; + var sum = [0, 0]; + var interestingCount = 0; + var interestingLoc; + for (var i2 = 0; i2 < nodeIDs.length; i2++) { + var node = graph.entity(nodeIDs[i2]); + if (node.hasInterestingTags()) { + interestingLoc = ++interestingCount === 1 ? node.loc : null; } + sum = geoVecAdd(sum, node.loc); } - return splittableParents; - function isSplittable(parent) { - if (_wayIDs && _wayIDs.indexOf(parent.id) === -1) - return false; - if (parent.isClosed()) - return true; - for (var i2 = 1; i2 < parent.nodes.length - 1; i2++) { - if (parent.nodes[i2] === nodeId) - return true; + return interestingLoc || geoVecScale(sum, 1 / nodeIDs.length); + } + var action = function(graph) { + if (nodeIDs.length < 2) + return graph; + var toLoc = loc; + if (!toLoc) { + toLoc = chooseLoc(graph); + } + for (var i2 = 0; i2 < nodeIDs.length; i2++) { + var node = graph.entity(nodeIDs[i2]); + if (node.loc !== toLoc) { + graph = graph.replace(node.move(toLoc)); } - return false; } - }; - action.ways = function(graph) { - return utilArrayUniq([].concat.apply([], nodeIds.map(function(nodeId) { - return action.waysForNode(nodeId, graph); - }))); + return actionConnect(nodeIDs)(graph); }; action.disabled = function(graph) { - for (var i2 = 0; i2 < nodeIds.length; i2++) { - var nodeId = nodeIds[i2]; - var candidates = action.waysForNode(nodeId, graph); - if (candidates.length === 0 || _wayIDs && _wayIDs.length !== candidates.length) { + if (nodeIDs.length < 2) + return "not_eligible"; + for (var i2 = 0; i2 < nodeIDs.length; i2++) { + var entity = graph.entity(nodeIDs[i2]); + if (entity.type !== "node") return "not_eligible"; - } } - }; - action.limitWays = function(val) { - if (!arguments.length) - return _wayIDs; - _wayIDs = val; - return action; - }; - action.keepHistoryOn = function(val) { - if (!arguments.length) - return _keepHistoryOn; - _keepHistoryOn = val; - return action; + return actionConnect(nodeIDs).disabled(graph); }; return action; } - // modules/core/graph.js - function coreGraph(other, mutable) { - if (!(this instanceof coreGraph)) - return new coreGraph(other, mutable); - if (other instanceof coreGraph) { - var base = other.base(); - this.entities = Object.assign(Object.create(base.entities), other.entities); - this._parentWays = Object.assign(Object.create(base.parentWays), other._parentWays); - this._parentRels = Object.assign(Object.create(base.parentRels), other._parentRels); - } else { - this.entities = /* @__PURE__ */ Object.create({}); - this._parentWays = /* @__PURE__ */ Object.create({}); - this._parentRels = /* @__PURE__ */ Object.create({}); - this.rebase(other || [], [this]); + // modules/osm/changeset.js + function osmChangeset() { + if (!(this instanceof osmChangeset)) { + return new osmChangeset().initialize(arguments); + } else if (arguments.length) { + this.initialize(arguments); } - this.transients = {}; - this._childNodes = {}; - this.frozen = !mutable; } - coreGraph.prototype = { - hasEntity: function(id2) { - return this.entities[id2]; - }, - entity: function(id2) { - var entity = this.entities[id2]; - if (!entity) { - entity = this.entities.__proto__[id2]; - } - if (!entity) { - throw new Error("entity " + id2 + " not found"); - } - return entity; + osmEntity.changeset = osmChangeset; + osmChangeset.prototype = Object.create(osmEntity.prototype); + Object.assign(osmChangeset.prototype, { + type: "changeset", + extent: function() { + return new geoExtent(); }, - geometry: function(id2) { - return this.entity(id2).geometry(this); + geometry: function() { + return "changeset"; }, - transient: function(entity, key, fn) { - var id2 = entity.id; - var transients = this.transients[id2] || (this.transients[id2] = {}); - if (transients[key] !== void 0) { - return transients[key]; - } - transients[key] = fn.call(entity); - return transients[key]; + asJXON: function() { + return { + osm: { + changeset: { + tag: Object.keys(this.tags).map(function(k) { + return { "@k": k, "@v": this.tags[k] }; + }, this), + "@version": 0.6, + "@generator": "iD" + } + } + }; }, - parentWays: function(entity) { - var parents = this._parentWays[entity.id]; - var result = []; - if (parents) { - parents.forEach(function(id2) { - result.push(this.entity(id2)); - }, this); + // Generate [osmChange](http://wiki.openstreetmap.org/wiki/OsmChange) + // XML. Returns a string. + osmChangeJXON: function(changes) { + var changeset_id = this.id; + function nest(x, order) { + var groups = {}; + for (var i2 = 0; i2 < x.length; i2++) { + var tagName = Object.keys(x[i2])[0]; + if (!groups[tagName]) + groups[tagName] = []; + groups[tagName].push(x[i2][tagName]); + } + var ordered = {}; + order.forEach(function(o) { + if (groups[o]) + ordered[o] = groups[o]; + }); + return ordered; } - return result; - }, - isPoi: function(entity) { - var parents = this._parentWays[entity.id]; - return !parents || parents.size === 0; - }, - isShared: function(entity) { - var parents = this._parentWays[entity.id]; - return parents && parents.size > 1; - }, - parentRelations: function(entity) { - var parents = this._parentRels[entity.id]; - var result = []; - if (parents) { - parents.forEach(function(id2) { - result.push(this.entity(id2)); - }, this); + function sort(changes2) { + function resolve(item) { + return relations.find(function(relation2) { + return item.keyAttributes.type === "relation" && item.keyAttributes.ref === relation2["@id"]; + }); + } + function isNew(item) { + return !sorted[item["@id"]] && !processing.find(function(proc) { + return proc["@id"] === item["@id"]; + }); + } + var processing = []; + var sorted = {}; + var relations = changes2.relation; + if (!relations) + return changes2; + for (var i2 = 0; i2 < relations.length; i2++) { + var relation = relations[i2]; + if (!sorted[relation["@id"]]) { + processing.push(relation); + } + while (processing.length > 0) { + var next = processing[0], deps = next.member.map(resolve).filter(Boolean).filter(isNew); + if (deps.length === 0) { + sorted[next["@id"]] = next; + processing.shift(); + } else { + processing = deps.concat(processing); + } + } + } + changes2.relation = Object.values(sorted); + return changes2; } - return result; - }, - parentMultipolygons: function(entity) { - return this.parentRelations(entity).filter(function(relation) { - return relation.isMultipolygon(); - }); - }, - childNodes: function(entity) { - if (this._childNodes[entity.id]) - return this._childNodes[entity.id]; - if (!entity.nodes) - return []; - var nodes = []; - for (var i2 = 0; i2 < entity.nodes.length; i2++) { - nodes[i2] = this.entity(entity.nodes[i2]); + function rep2(entity) { + return entity.asJXON(changeset_id); } - if (debug) - Object.freeze(nodes); - this._childNodes[entity.id] = nodes; - return this._childNodes[entity.id]; - }, - base: function() { return { - "entities": Object.getPrototypeOf(this.entities), - "parentWays": Object.getPrototypeOf(this._parentWays), - "parentRels": Object.getPrototypeOf(this._parentRels) + osmChange: { + "@version": 0.6, + "@generator": "iD", + "create": sort(nest(changes.created.map(rep2), ["node", "way", "relation"])), + "modify": nest(changes.modified.map(rep2), ["node", "way", "relation"]), + "delete": Object.assign(nest(changes.deleted.map(rep2), ["relation", "way", "node"]), { "@if-unused": true }) + } }; }, - rebase: function(entities, stack, force) { - var base = this.base(); - var i2, j2, k, id2; - for (i2 = 0; i2 < entities.length; i2++) { - var entity = entities[i2]; - if (!entity.visible || !force && base.entities[entity.id]) - continue; - base.entities[entity.id] = entity; - this._updateCalculated(void 0, entity, base.parentWays, base.parentRels); - if (entity.type === "way") { - for (j2 = 0; j2 < entity.nodes.length; j2++) { - id2 = entity.nodes[j2]; - for (k = 1; k < stack.length; k++) { - var ents = stack[k].entities; - if (ents.hasOwnProperty(id2) && ents[id2] === void 0) { - delete ents[id2]; - } + asGeoJSON: function() { + return {}; + } + }); + + // modules/osm/note.js + function osmNote() { + if (!(this instanceof osmNote)) { + return new osmNote().initialize(arguments); + } else if (arguments.length) { + this.initialize(arguments); + } + } + osmNote.id = function() { + return osmNote.id.next--; + }; + osmNote.id.next = -1; + Object.assign(osmNote.prototype, { + type: "note", + initialize: function(sources) { + for (var i2 = 0; i2 < sources.length; ++i2) { + var source = sources[i2]; + for (var prop in source) { + if (Object.prototype.hasOwnProperty.call(source, prop)) { + if (source[prop] === void 0) { + delete this[prop]; + } else { + this[prop] = source[prop]; } } } } - for (i2 = 0; i2 < stack.length; i2++) { - stack[i2]._updateRebased(); + if (!this.id) { + this.id = osmNote.id().toString(); } + return this; }, - _updateRebased: function() { - var base = this.base(); - Object.keys(this._parentWays).forEach(function(child) { - if (base.parentWays[child]) { - base.parentWays[child].forEach(function(id2) { - if (!this.entities.hasOwnProperty(id2)) { - this._parentWays[child].add(id2); - } - }, this); - } - }, this); - Object.keys(this._parentRels).forEach(function(child) { - if (base.parentRels[child]) { - base.parentRels[child].forEach(function(id2) { - if (!this.entities.hasOwnProperty(id2)) { - this._parentRels[child].add(id2); - } - }, this); - } - }, this); - this.transients = {}; + extent: function() { + return new geoExtent(this.loc); }, - _updateCalculated: function(oldentity, entity, parentWays, parentRels) { - parentWays = parentWays || this._parentWays; - parentRels = parentRels || this._parentRels; - var type3 = entity && entity.type || oldentity && oldentity.type; - var removed, added, i2; - if (type3 === "way") { - if (oldentity && entity) { - removed = utilArrayDifference(oldentity.nodes, entity.nodes); - added = utilArrayDifference(entity.nodes, oldentity.nodes); - } else if (oldentity) { - removed = oldentity.nodes; - added = []; - } else if (entity) { - removed = []; - added = entity.nodes; - } - for (i2 = 0; i2 < removed.length; i2++) { - parentWays[removed[i2]] = new Set(parentWays[removed[i2]]); - parentWays[removed[i2]].delete(oldentity.id); - } - for (i2 = 0; i2 < added.length; i2++) { - parentWays[added[i2]] = new Set(parentWays[added[i2]]); - parentWays[added[i2]].add(entity.id); - } - } else if (type3 === "relation") { - var oldentityMemberIDs = oldentity ? oldentity.members.map(function(m) { - return m.id; - }) : []; - var entityMemberIDs = entity ? entity.members.map(function(m) { - return m.id; - }) : []; - if (oldentity && entity) { - removed = utilArrayDifference(oldentityMemberIDs, entityMemberIDs); - added = utilArrayDifference(entityMemberIDs, oldentityMemberIDs); - } else if (oldentity) { - removed = oldentityMemberIDs; - added = []; - } else if (entity) { - removed = []; - added = entityMemberIDs; + update: function(attrs) { + return osmNote(this, attrs); + }, + isNew: function() { + return this.id < 0; + }, + move: function(loc) { + return this.update({ loc }); + } + }); + + // modules/osm/relation.js + function osmRelation() { + if (!(this instanceof osmRelation)) { + return new osmRelation().initialize(arguments); + } else if (arguments.length) { + this.initialize(arguments); + } + } + osmEntity.relation = osmRelation; + osmRelation.prototype = Object.create(osmEntity.prototype); + osmRelation.creationOrder = function(a, b) { + var aId = parseInt(osmEntity.id.toOSM(a.id), 10); + var bId = parseInt(osmEntity.id.toOSM(b.id), 10); + if (aId < 0 || bId < 0) + return aId - bId; + return bId - aId; + }; + Object.assign(osmRelation.prototype, { + type: "relation", + members: [], + copy: function(resolver, copies) { + if (copies[this.id]) + return copies[this.id]; + var copy2 = osmEntity.prototype.copy.call(this, resolver, copies); + var members = this.members.map(function(member) { + return Object.assign({}, member, { id: resolver.entity(member.id).copy(resolver, copies).id }); + }); + copy2 = copy2.update({ members }); + copies[this.id] = copy2; + return copy2; + }, + extent: function(resolver, memo) { + return resolver.transient(this, "extent", function() { + if (memo && memo[this.id]) + return geoExtent(); + memo = memo || {}; + memo[this.id] = true; + var extent = geoExtent(); + for (var i2 = 0; i2 < this.members.length; i2++) { + var member = resolver.hasEntity(this.members[i2].id); + if (member) { + extent._extend(member.extent(resolver, memo)); + } } - for (i2 = 0; i2 < removed.length; i2++) { - parentRels[removed[i2]] = new Set(parentRels[removed[i2]]); - parentRels[removed[i2]].delete(oldentity.id); + return extent; + }); + }, + geometry: function(graph) { + return graph.transient(this, "geometry", function() { + return this.isMultipolygon() ? "area" : "relation"; + }); + }, + isDegenerate: function() { + return this.members.length === 0; + }, + // Return an array of members, each extended with an 'index' property whose value + // is the member index. + indexedMembers: function() { + var result = new Array(this.members.length); + for (var i2 = 0; i2 < this.members.length; i2++) { + result[i2] = Object.assign({}, this.members[i2], { index: i2 }); + } + return result; + }, + // Return the first member with the given role. A copy of the member object + // is returned, extended with an 'index' property whose value is the member index. + memberByRole: function(role) { + for (var i2 = 0; i2 < this.members.length; i2++) { + if (this.members[i2].role === role) { + return Object.assign({}, this.members[i2], { index: i2 }); } - for (i2 = 0; i2 < added.length; i2++) { - parentRels[added[i2]] = new Set(parentRels[added[i2]]); - parentRels[added[i2]].add(entity.id); + } + }, + // Same as memberByRole, but returns all members with the given role + membersByRole: function(role) { + var result = []; + for (var i2 = 0; i2 < this.members.length; i2++) { + if (this.members[i2].role === role) { + result.push(Object.assign({}, this.members[i2], { index: i2 })); } } + return result; }, - replace: function(entity) { - if (this.entities[entity.id] === entity) - return this; - return this.update(function() { - this._updateCalculated(this.entities[entity.id], entity); - this.entities[entity.id] = entity; - }); + // Return the first member with the given id. A copy of the member object + // is returned, extended with an 'index' property whose value is the member index. + memberById: function(id2) { + for (var i2 = 0; i2 < this.members.length; i2++) { + if (this.members[i2].id === id2) { + return Object.assign({}, this.members[i2], { index: i2 }); + } + } }, - remove: function(entity) { - return this.update(function() { - this._updateCalculated(entity, void 0); - this.entities[entity.id] = void 0; + // Return the first member with the given id and role. A copy of the member object + // is returned, extended with an 'index' property whose value is the member index. + memberByIdAndRole: function(id2, role) { + for (var i2 = 0; i2 < this.members.length; i2++) { + if (this.members[i2].id === id2 && this.members[i2].role === role) { + return Object.assign({}, this.members[i2], { index: i2 }); + } + } + }, + addMember: function(member, index) { + var members = this.members.slice(); + members.splice(index === void 0 ? members.length : index, 0, member); + return this.update({ members }); + }, + updateMember: function(member, index) { + var members = this.members.slice(); + members.splice(index, 1, Object.assign({}, members[index], member)); + return this.update({ members }); + }, + removeMember: function(index) { + var members = this.members.slice(); + members.splice(index, 1); + return this.update({ members }); + }, + removeMembersWithID: function(id2) { + var members = this.members.filter(function(m) { + return m.id !== id2; }); + return this.update({ members }); }, - revert: function(id2) { - var baseEntity = this.base().entities[id2]; - var headEntity = this.entities[id2]; - if (headEntity === baseEntity) + moveMember: function(fromIndex, toIndex) { + var members = this.members.slice(); + members.splice(toIndex, 0, members.splice(fromIndex, 1)[0]); + return this.update({ members }); + }, + // Wherever a member appears with id `needle.id`, replace it with a member + // with id `replacement.id`, type `replacement.type`, and the original role, + // By default, adding a duplicate member (by id and role) is prevented. + // Return an updated relation. + replaceMember: function(needle, replacement, keepDuplicates) { + if (!this.memberById(needle.id)) return this; - return this.update(function() { - this._updateCalculated(headEntity, baseEntity); - delete this.entities[id2]; - }); + var members = []; + for (var i2 = 0; i2 < this.members.length; i2++) { + var member = this.members[i2]; + if (member.id !== needle.id) { + members.push(member); + } else if (keepDuplicates || !this.memberByIdAndRole(replacement.id, member.role)) { + members.push({ id: replacement.id, type: replacement.type, role: member.role }); + } + } + return this.update({ members }); }, - update: function() { - var graph = this.frozen ? coreGraph(this, true) : this; - for (var i2 = 0; i2 < arguments.length; i2++) { - arguments[i2].call(graph, graph); + asJXON: function(changeset_id) { + var r = { + relation: { + "@id": this.osmId(), + "@version": this.version || 0, + member: this.members.map(function(member) { + return { + keyAttributes: { + type: member.type, + role: member.role, + ref: osmEntity.id.toOSM(member.id) + } + }; + }, this), + tag: Object.keys(this.tags).map(function(k) { + return { keyAttributes: { k, v: this.tags[k] } }; + }, this) + } + }; + if (changeset_id) { + r.relation["@changeset"] = changeset_id; } - if (this.frozen) - graph.frozen = true; - return graph; + return r; }, - load: function(entities) { - var base = this.base(); - this.entities = Object.create(base.entities); - for (var i2 in entities) { - this.entities[i2] = entities[i2]; - this._updateCalculated(base.entities[i2], this.entities[i2]); + asGeoJSON: function(resolver) { + return resolver.transient(this, "GeoJSON", function() { + if (this.isMultipolygon()) { + return { + type: "MultiPolygon", + coordinates: this.multipolygon(resolver) + }; + } else { + return { + type: "FeatureCollection", + properties: this.tags, + features: this.members.map(function(member) { + return Object.assign({ role: member.role }, resolver.entity(member.id).asGeoJSON(resolver)); + }) + }; + } + }); + }, + area: function(resolver) { + return resolver.transient(this, "area", function() { + return area_default(this.asGeoJSON(resolver)); + }); + }, + isMultipolygon: function() { + return this.tags.type === "multipolygon"; + }, + isComplete: function(resolver) { + for (var i2 = 0; i2 < this.members.length; i2++) { + if (!resolver.hasEntity(this.members[i2].id)) { + return false; + } } - return this; - } - }; - - // modules/osm/intersection.js - function osmTurn(turn) { - if (!(this instanceof osmTurn)) { - return new osmTurn(turn); - } - Object.assign(this, turn); - } - function osmIntersection(graph, startVertexId, maxDistance) { - maxDistance = maxDistance || 30; - var vgraph = coreGraph(); - var i2, j2, k; - function memberOfRestriction(entity) { - return graph.parentRelations(entity).some(function(r) { - return r.isRestriction(); + return true; + }, + hasFromViaTo: function() { + return this.members.some(function(m) { + return m.role === "from"; + }) && this.members.some(function(m) { + return m.role === "via"; + }) && this.members.some(function(m) { + return m.role === "to"; }); - } - function isRoad(way2) { - if (way2.isArea() || way2.isDegenerate()) + }, + isRestriction: function() { + return !!(this.tags.type && this.tags.type.match(/^restriction:?/)); + }, + isValidRestriction: function() { + if (!this.isRestriction()) return false; - var roads = { - "motorway": true, - "motorway_link": true, - "trunk": true, - "trunk_link": true, - "primary": true, - "primary_link": true, - "secondary": true, - "secondary_link": true, - "tertiary": true, - "tertiary_link": true, - "residential": true, - "unclassified": true, - "living_street": true, - "service": true, - "road": true, - "track": true + var froms = this.members.filter(function(m) { + return m.role === "from"; + }); + var vias = this.members.filter(function(m) { + return m.role === "via"; + }); + var tos = this.members.filter(function(m) { + return m.role === "to"; + }); + if (froms.length !== 1 && this.tags.restriction !== "no_entry") + return false; + if (froms.some(function(m) { + return m.type !== "way"; + })) + return false; + if (tos.length !== 1 && this.tags.restriction !== "no_exit") + return false; + if (tos.some(function(m) { + return m.type !== "way"; + })) + return false; + if (vias.length === 0) + return false; + if (vias.length > 1 && vias.some(function(m) { + return m.type !== "way"; + })) + return false; + return true; + }, + isConnectivity: function() { + return !!(this.tags.type && this.tags.type.match(/^connectivity:?/)); + }, + // Returns an array [A0, ... An], each Ai being an array of node arrays [Nds0, ... Ndsm], + // where Nds0 is an outer ring and subsequent Ndsi's (if any i > 0) being inner rings. + // + // This corresponds to the structure needed for rendering a multipolygon path using a + // `evenodd` fill rule, as well as the structure of a GeoJSON MultiPolygon geometry. + // + // In the case of invalid geometries, this function will still return a result which + // includes the nodes of all way members, but some Nds may be unclosed and some inner + // rings not matched with the intended outer ring. + // + multipolygon: function(resolver) { + var outers = this.members.filter(function(m) { + return "outer" === (m.role || "outer"); + }); + var inners = this.members.filter(function(m) { + return "inner" === m.role; + }); + outers = osmJoinWays(outers, resolver); + inners = osmJoinWays(inners, resolver); + var sequenceToLineString = function(sequence) { + if (sequence.nodes.length > 2 && sequence.nodes[0] !== sequence.nodes[sequence.nodes.length - 1]) { + sequence.nodes.push(sequence.nodes[0]); + } + return sequence.nodes.map(function(node) { + return node.loc; + }); }; - return roads[way2.tags.highway]; - } - var startNode = graph.entity(startVertexId); - var checkVertices = [startNode]; - var checkWays; - var vertices = []; - var vertexIds = []; - var vertex; - var ways = []; - var wayIds = []; - var way; - var nodes = []; - var node; - var parents = []; - var parent; - var actions = []; - while (checkVertices.length) { - vertex = checkVertices.pop(); - checkWays = graph.parentWays(vertex); - var hasWays = false; - for (i2 = 0; i2 < checkWays.length; i2++) { - way = checkWays[i2]; - if (!isRoad(way) && !memberOfRestriction(way)) - continue; - ways.push(way); - hasWays = true; - nodes = utilArrayUniq(graph.childNodes(way)); - for (j2 = 0; j2 < nodes.length; j2++) { - node = nodes[j2]; - if (node === vertex) - continue; - if (vertices.indexOf(node) !== -1) - continue; - if (geoSphericalDistance(node.loc, startNode.loc) > maxDistance) - continue; - var hasParents = false; - parents = graph.parentWays(node); - for (k = 0; k < parents.length; k++) { - parent = parents[k]; - if (parent === way) - continue; - if (ways.indexOf(parent) !== -1) - continue; - if (!isRoad(parent)) - continue; - hasParents = true; - break; + outers = outers.map(sequenceToLineString); + inners = inners.map(sequenceToLineString); + var result = outers.map(function(o2) { + return [area_default({ type: "Polygon", coordinates: [o2] }) > 2 * Math.PI ? o2.reverse() : o2]; + }); + function findOuter(inner2) { + var o2, outer; + for (o2 = 0; o2 < outers.length; o2++) { + outer = outers[o2]; + if (geoPolygonContainsPolygon(outer, inner2)) { + return o2; } - if (hasParents) { - checkVertices.push(node); + } + for (o2 = 0; o2 < outers.length; o2++) { + outer = outers[o2]; + if (geoPolygonIntersectsPolygon(outer, inner2, false)) { + return o2; } } } - if (hasWays) { - vertices.push(vertex); - } - } - vertices = utilArrayUniq(vertices); - ways = utilArrayUniq(ways); - ways.forEach(function(way2) { - graph.childNodes(way2).forEach(function(node2) { - vgraph = vgraph.replace(node2); - }); - vgraph = vgraph.replace(way2); - graph.parentRelations(way2).forEach(function(relation) { - if (relation.isRestriction()) { - if (relation.isValidRestriction(graph)) { - vgraph = vgraph.replace(relation); - } else if (relation.isComplete(graph)) { - actions.push(actionDeleteRelation(relation.id)); - } + for (var i2 = 0; i2 < inners.length; i2++) { + var inner = inners[i2]; + if (area_default({ type: "Polygon", coordinates: [inner] }) < 2 * Math.PI) { + inner = inner.reverse(); + } + var o = findOuter(inners[i2]); + if (o !== void 0) { + result[o].push(inners[i2]); + } else { + result.push([inners[i2]]); } - }); - }); - ways.forEach(function(w) { - var way2 = vgraph.entity(w.id); - if (way2.tags.oneway === "-1") { - var action = actionReverse(way2.id, { reverseOneway: true }); - actions.push(action); - vgraph = action(vgraph); } - }); - var origCount = osmEntity.id.next.way; - vertices.forEach(function(v) { - var splitAll = actionSplit([v.id]).keepHistoryOn("first"); - if (!splitAll.disabled(vgraph)) { - splitAll.ways(vgraph).forEach(function(way2) { - var splitOne = actionSplit([v.id]).limitWays([way2.id]).keepHistoryOn("first"); - actions.push(splitOne); - vgraph = splitOne(vgraph); - }); + return result; + } + }); + + // modules/osm/qa_item.js + var QAItem = class _QAItem { + constructor(loc, service, itemType, id2, props) { + this.loc = loc; + this.service = service.title; + this.itemType = itemType; + this.id = id2 ? id2 : `${_QAItem.id()}`; + this.update(props); + if (service && typeof service.getIcon === "function") { + this.icon = service.getIcon(itemType); } - }); - osmEntity.id.next.way = origCount; - vertexIds = vertices.map(function(v) { - return v.id; - }); - vertices = []; - ways = []; - vertexIds.forEach(function(id2) { - var vertex2 = vgraph.entity(id2); - var parents2 = vgraph.parentWays(vertex2); - vertices.push(vertex2); - ways = ways.concat(parents2); - }); - vertices = utilArrayUniq(vertices); - ways = utilArrayUniq(ways); - vertexIds = vertices.map(function(v) { - return v.id; - }); - wayIds = ways.map(function(w) { - return w.id; - }); - function withMetadata(way2, vertexIds2) { - var __oneWay = way2.isOneWay(); - var __first = vertexIds2.indexOf(way2.first()) !== -1; - var __last = vertexIds2.indexOf(way2.last()) !== -1; - var __via = __first && __last; - var __from = __first && !__oneWay || __last; - var __to = __first || __last && !__oneWay; - return way2.update({ - __first, - __last, - __from, - __via, - __to, - __oneWay - }); } - ways = []; - wayIds.forEach(function(id2) { - var way2 = withMetadata(vgraph.entity(id2), vertexIds); - vgraph = vgraph.replace(way2); - ways.push(way2); - }); - var keepGoing; - var removeWayIds = []; - var removeVertexIds = []; - do { - keepGoing = false; - checkVertices = vertexIds.slice(); - for (i2 = 0; i2 < checkVertices.length; i2++) { - var vertexId = checkVertices[i2]; - vertex = vgraph.hasEntity(vertexId); - if (!vertex) { - if (vertexIds.indexOf(vertexId) !== -1) { - vertexIds.splice(vertexIds.indexOf(vertexId), 1); - } - removeVertexIds.push(vertexId); - continue; - } - parents = vgraph.parentWays(vertex); - if (parents.length < 3) { - if (vertexIds.indexOf(vertexId) !== -1) { - vertexIds.splice(vertexIds.indexOf(vertexId), 1); - } + update(props) { + const { loc, service, itemType, id: id2 } = this; + Object.keys(props).forEach((prop) => this[prop] = props[prop]); + this.loc = loc; + this.service = service; + this.itemType = itemType; + this.id = id2; + return this; + } + // Generic handling for newly created QAItems + static id() { + return this.nextId--; + } + }; + QAItem.nextId = -1; + + // modules/actions/split.js + function actionSplit(nodeIds, newWayIds) { + if (typeof nodeIds === "string") + nodeIds = [nodeIds]; + var _wayIDs; + var _keepHistoryOn = "longest"; + var _createdWayIDs = []; + function dist(graph, nA, nB) { + var locA = graph.entity(nA).loc; + var locB = graph.entity(nB).loc; + var epsilon3 = 1e-6; + return locA && locB ? geoSphericalDistance(locA, locB) : epsilon3; + } + function splitArea(nodes, idxA, graph) { + var lengths = new Array(nodes.length); + var length; + var i2; + var best = 0; + var idxB; + function wrap2(index) { + return utilWrap(index, nodes.length); + } + length = 0; + for (i2 = wrap2(idxA + 1); i2 !== idxA; i2 = wrap2(i2 + 1)) { + length += dist(graph, nodes[i2], nodes[wrap2(i2 - 1)]); + lengths[i2] = length; + } + length = 0; + for (i2 = wrap2(idxA - 1); i2 !== idxA; i2 = wrap2(i2 - 1)) { + length += dist(graph, nodes[i2], nodes[wrap2(i2 + 1)]); + if (length < lengths[i2]) { + lengths[i2] = length; } - if (parents.length === 2) { - var a = parents[0]; - var b = parents[1]; - var aIsLeaf = a && !a.__via; - var bIsLeaf = b && !b.__via; - var leaf, survivor; - if (aIsLeaf && !bIsLeaf) { - leaf = a; - survivor = b; - } else if (!aIsLeaf && bIsLeaf) { - leaf = b; - survivor = a; - } - if (leaf && survivor) { - survivor = withMetadata(survivor, vertexIds); - vgraph = vgraph.replace(survivor).remove(leaf); - removeWayIds.push(leaf.id); - keepGoing = true; - } + } + for (i2 = 0; i2 < nodes.length; i2++) { + var cost = lengths[i2] / dist(graph, nodes[idxA], nodes[i2]); + if (cost > best) { + idxB = i2; + best = cost; } - parents = vgraph.parentWays(vertex); - if (parents.length < 2) { - if (vertexIds.indexOf(vertexId) !== -1) { - vertexIds.splice(vertexIds.indexOf(vertexId), 1); - } - removeVertexIds.push(vertexId); - keepGoing = true; + } + return idxB; + } + function totalLengthBetweenNodes(graph, nodes) { + var totalLength = 0; + for (var i2 = 0; i2 < nodes.length - 1; i2++) { + totalLength += dist(graph, nodes[i2], nodes[i2 + 1]); + } + return totalLength; + } + function split(graph, nodeId, wayA, newWayId) { + var wayB = osmWay({ id: newWayId, tags: wayA.tags }); + var origNodes = wayA.nodes.slice(); + var nodesA; + var nodesB; + var isArea = wayA.isArea(); + var isOuter = osmIsOldMultipolygonOuterMember(wayA, graph); + if (wayA.isClosed()) { + var nodes = wayA.nodes.slice(0, -1); + var idxA = nodes.indexOf(nodeId); + var idxB = splitArea(nodes, idxA, graph); + if (idxB < idxA) { + nodesA = nodes.slice(idxA).concat(nodes.slice(0, idxB + 1)); + nodesB = nodes.slice(idxB, idxA + 1); + } else { + nodesA = nodes.slice(idxA, idxB + 1); + nodesB = nodes.slice(idxB).concat(nodes.slice(0, idxA + 1)); } - if (parents.length < 1) { - vgraph = vgraph.remove(vertex); + } else { + var idx = wayA.nodes.indexOf(nodeId, 1); + nodesA = wayA.nodes.slice(0, idx + 1); + nodesB = wayA.nodes.slice(idx); + } + var lengthA = totalLengthBetweenNodes(graph, nodesA); + var lengthB = totalLengthBetweenNodes(graph, nodesB); + if (_keepHistoryOn === "longest" && lengthB > lengthA) { + wayA = wayA.update({ nodes: nodesB }); + wayB = wayB.update({ nodes: nodesA }); + var temp = lengthA; + lengthA = lengthB; + lengthB = temp; + } else { + wayA = wayA.update({ nodes: nodesA }); + wayB = wayB.update({ nodes: nodesB }); + } + if (wayA.tags.step_count) { + var stepCount = Number(wayA.tags.step_count); + if (stepCount && // ensure a number + isFinite(stepCount) && // ensure positive + stepCount > 0 && // ensure integer + Math.round(stepCount) === stepCount) { + var tagsA = Object.assign({}, wayA.tags); + var tagsB = Object.assign({}, wayB.tags); + var ratioA = lengthA / (lengthA + lengthB); + var countA = Math.round(stepCount * ratioA); + tagsA.step_count = countA.toString(); + tagsB.step_count = (stepCount - countA).toString(); + wayA = wayA.update({ tags: tagsA }); + wayB = wayB.update({ tags: tagsB }); } } - } while (keepGoing); - vertices = vertices.filter(function(vertex2) { - return removeVertexIds.indexOf(vertex2.id) === -1; - }).map(function(vertex2) { - return vgraph.entity(vertex2.id); - }); - ways = ways.filter(function(way2) { - return removeWayIds.indexOf(way2.id) === -1; - }).map(function(way2) { - return vgraph.entity(way2.id); - }); - var intersection = { - graph: vgraph, - actions, - vertices, - ways - }; - intersection.turns = function(fromWayId, maxViaWay) { - if (!fromWayId) - return []; - if (!maxViaWay) - maxViaWay = 0; - var vgraph2 = intersection.graph; - var keyVertexIds = intersection.vertices.map(function(v) { - return v.id; - }); - var start2 = vgraph2.entity(fromWayId); - if (!start2 || !(start2.__from || start2.__via)) - return []; - var maxPathLength = maxViaWay * 2 + 3; - var turns = []; - step(start2); - return turns; - function step(entity, currPath, currRestrictions, matchedRestriction) { - currPath = (currPath || []).slice(); - if (currPath.length >= maxPathLength) - return; - currPath.push(entity.id); - currRestrictions = (currRestrictions || []).slice(); - var i3, j3; - if (entity.type === "node") { - var parents2 = vgraph2.parentWays(entity); - var nextWays = []; - for (i3 = 0; i3 < parents2.length; i3++) { - var way2 = parents2[i3]; - if (way2.__oneWay && way2.nodes[0] !== entity.id) - continue; - if (currPath.indexOf(way2.id) !== -1 && currPath.length >= 3) - continue; - var restrict = null; - for (j3 = 0; j3 < currRestrictions.length; j3++) { - var restriction = currRestrictions[j3]; - var f2 = restriction.memberByRole("from"); - var v = restriction.membersByRole("via"); - var t = restriction.memberByRole("to"); - var isOnly = /^only_/.test(restriction.tags.restriction); - var matchesFrom = f2.id === fromWayId; - var matchesViaTo = false; - var isAlongOnlyPath = false; - if (t.id === way2.id) { - if (v.length === 1 && v[0].type === "node") { - matchesViaTo = v[0].id === entity.id && (matchesFrom && currPath.length === 2 || !matchesFrom && currPath.length > 2); - } else { - var pathVias = []; - for (k = 2; k < currPath.length; k += 2) { - pathVias.push(currPath[k]); - } - var restrictionVias = []; - for (k = 0; k < v.length; k++) { - if (v[k].type === "way") { - restrictionVias.push(v[k].id); - } - } - var diff = utilArrayDifference(pathVias, restrictionVias); - matchesViaTo = !diff.length; - } - } else if (isOnly) { - for (k = 0; k < v.length; k++) { - if (v[k].type === "way" && v[k].id === way2.id) { - isAlongOnlyPath = true; + graph = graph.replace(wayA); + graph = graph.replace(wayB); + graph.parentRelations(wayA).forEach(function(relation) { + var member; + if (relation.hasFromViaTo()) { + var f2 = relation.memberByRole("from"); + var v = relation.membersByRole("via"); + var t = relation.memberByRole("to"); + var i2; + if (f2.id === wayA.id || t.id === wayA.id) { + var keepB = false; + if (v.length === 1 && v[0].type === "node") { + keepB = wayB.contains(v[0].id); + } else { + for (i2 = 0; i2 < v.length; i2++) { + if (v[i2].type === "way") { + var wayVia = graph.hasEntity(v[i2].id); + if (wayVia && utilArrayIntersection(wayB.nodes, wayVia.nodes).length) { + keepB = true; break; } } } - if (matchesViaTo) { - if (isOnly) { - restrict = { id: restriction.id, direct: matchesFrom, from: f2.id, only: true, end: true }; - } else { - restrict = { id: restriction.id, direct: matchesFrom, from: f2.id, no: true, end: true }; - } - } else { - if (isAlongOnlyPath) { - restrict = { id: restriction.id, direct: false, from: f2.id, only: true, end: false }; - } else if (isOnly) { - restrict = { id: restriction.id, direct: false, from: f2.id, no: true, end: true }; - } - } - if (restrict && restrict.direct) - break; } - nextWays.push({ way: way2, restrict }); - } - nextWays.forEach(function(nextWay) { - step(nextWay.way, currPath, currRestrictions, nextWay.restrict); - }); - } else { - if (currPath.length >= 3) { - var turnPath = currPath.slice(); - if (matchedRestriction && matchedRestriction.direct === false) { - for (i3 = 0; i3 < turnPath.length; i3++) { - if (turnPath[i3] === matchedRestriction.from) { - turnPath = turnPath.slice(i3); - break; - } - } + if (keepB) { + relation = relation.replaceMember(wayA, wayB); + graph = graph.replace(relation); } - var turn = pathToTurn(turnPath); - if (turn) { - if (matchedRestriction) { - turn.restrictionID = matchedRestriction.id; - turn.no = matchedRestriction.no; - turn.only = matchedRestriction.only; - turn.direct = matchedRestriction.direct; + } else { + for (i2 = 0; i2 < v.length; i2++) { + if (v[i2].type === "way" && v[i2].id === wayA.id) { + member = { + id: wayB.id, + type: "way", + role: "via" + }; + graph = actionAddMember(relation.id, member, v[i2].index + 1)(graph); + break; } - turns.push(osmTurn(turn)); } - if (currPath[0] === currPath[2]) - return; - } - if (matchedRestriction && matchedRestriction.end) - return; - var n1 = vgraph2.entity(entity.first()); - var n2 = vgraph2.entity(entity.last()); - var dist = geoSphericalDistance(n1.loc, n2.loc); - var nextNodes = []; - if (currPath.length > 1) { - if (dist > maxDistance) - return; - if (!entity.__via) - return; - } - if (!entity.__oneWay && keyVertexIds.indexOf(n1.id) !== -1 && currPath.indexOf(n1.id) === -1) { - nextNodes.push(n1); } - if (keyVertexIds.indexOf(n2.id) !== -1 && currPath.indexOf(n2.id) === -1) { - nextNodes.push(n2); - } - nextNodes.forEach(function(nextNode) { - var fromRestrictions = vgraph2.parentRelations(entity).filter(function(r) { - if (!r.isRestriction()) - return false; - var f3 = r.memberByRole("from"); - if (!f3 || f3.id !== entity.id) - return false; - var isOnly2 = /^only_/.test(r.tags.restriction); - if (!isOnly2) - return true; - var isOnlyVia = false; - var v2 = r.membersByRole("via"); - if (v2.length === 1 && v2[0].type === "node") { - isOnlyVia = v2[0].id === nextNode.id; - } else { - for (var i4 = 0; i4 < v2.length; i4++) { - if (v2[i4].type !== "way") - continue; - var viaWay = vgraph2.entity(v2[i4].id); - if (viaWay.first() === nextNode.id || viaWay.last() === nextNode.id) { - isOnlyVia = true; - break; - } - } - } - return isOnlyVia; - }); - step(nextNode, currPath, currRestrictions.concat(fromRestrictions), false); - }); - } - } - function pathToTurn(path) { - if (path.length < 3) - return; - var fromWayId2, fromNodeId, fromVertexId; - var toWayId, toNodeId, toVertexId; - var viaWayIds, viaNodeId, isUturn; - fromWayId2 = path[0]; - toWayId = path[path.length - 1]; - if (path.length === 3 && fromWayId2 === toWayId) { - var way2 = vgraph2.entity(fromWayId2); - if (way2.__oneWay) - return null; - isUturn = true; - viaNodeId = fromVertexId = toVertexId = path[1]; - fromNodeId = toNodeId = adjacentNode(fromWayId2, viaNodeId); } else { - isUturn = false; - fromVertexId = path[1]; - fromNodeId = adjacentNode(fromWayId2, fromVertexId); - toVertexId = path[path.length - 2]; - toNodeId = adjacentNode(toWayId, toVertexId); - if (path.length === 3) { - viaNodeId = path[1]; - } else { - viaWayIds = path.filter(function(entityId) { - return entityId[0] === "w"; - }); - viaWayIds = viaWayIds.slice(1, viaWayIds.length - 1); + if (relation === isOuter) { + graph = graph.replace(relation.mergeTags(wayA.tags)); + graph = graph.replace(wayA.update({ tags: {} })); + graph = graph.replace(wayB.update({ tags: {} })); } + member = { + id: wayB.id, + type: "way", + role: relation.memberById(wayA.id).role + }; + var insertPair = { + originalID: wayA.id, + insertedID: wayB.id, + nodes: origNodes + }; + graph = actionAddMember(relation.id, member, void 0, insertPair)(graph); } - return { - key: path.join("_"), - path, - from: { node: fromNodeId, way: fromWayId2, vertex: fromVertexId }, - via: { node: viaNodeId, ways: viaWayIds }, - to: { node: toNodeId, way: toWayId, vertex: toVertexId }, - u: isUturn - }; - function adjacentNode(wayId, affixId) { - var nodes2 = vgraph2.entity(wayId).nodes; - return affixId === nodes2[0] ? nodes2[1] : nodes2[nodes2.length - 2]; - } - } - }; - return intersection; - } - function osmInferRestriction(graph, turn, projection2) { - var fromWay = graph.entity(turn.from.way); - var fromNode = graph.entity(turn.from.node); - var fromVertex = graph.entity(turn.from.vertex); - var toWay = graph.entity(turn.to.way); - var toNode = graph.entity(turn.to.node); - var toVertex = graph.entity(turn.to.vertex); - var fromOneWay = fromWay.tags.oneway === "yes"; - var toOneWay = toWay.tags.oneway === "yes"; - var angle2 = (geoAngle(fromVertex, fromNode, projection2) - geoAngle(toVertex, toNode, projection2)) * 180 / Math.PI; - while (angle2 < 0) { - angle2 += 360; - } - if (fromNode === toNode) { - return "no_u_turn"; - } - if ((angle2 < 23 || angle2 > 336) && fromOneWay && toOneWay) { - return "no_u_turn"; - } - if ((angle2 < 40 || angle2 > 319) && fromOneWay && toOneWay && turn.from.vertex !== turn.to.vertex) { - return "no_u_turn"; - } - if (angle2 < 158) { - return "no_right_turn"; - } - if (angle2 > 202) { - return "no_left_turn"; - } - return "no_straight_on"; - } - - // modules/actions/merge_polygon.js - function actionMergePolygon(ids, newRelationId) { - function groupEntities(graph) { - var entities = ids.map(function(id2) { - return graph.entity(id2); - }); - var geometryGroups = utilArrayGroupBy(entities, function(entity) { - if (entity.type === "way" && entity.isClosed()) { - return "closedWay"; - } else if (entity.type === "relation" && entity.isMultipolygon()) { - return "multipolygon"; - } else { - return "other"; - } - }); - return Object.assign( - { closedWay: [], multipolygon: [], other: [] }, - geometryGroups - ); - } - var action = function(graph) { - var entities = groupEntities(graph); - var polygons = entities.multipolygon.reduce(function(polygons2, m) { - return polygons2.concat(osmJoinWays(m.members, graph)); - }, []).concat(entities.closedWay.map(function(d) { - var member = [{ id: d.id }]; - member.nodes = graph.childNodes(d); - return member; - })); - var contained = polygons.map(function(w, i2) { - return polygons.map(function(d, n2) { - if (i2 === n2) - return null; - return geoPolygonContainsPolygon( - d.nodes.map(function(n3) { - return n3.loc; - }), - w.nodes.map(function(n3) { - return n3.loc; - }) - ); - }); }); - var members = []; - var outer = true; - while (polygons.length) { - extractUncontained(polygons); - polygons = polygons.filter(isContained); - contained = contained.filter(isContained).map(filterContained); - } - function isContained(d, i2) { - return contained[i2].some(function(val) { - return val; + if (!isOuter && isArea) { + var multipolygon = osmRelation({ + tags: Object.assign({}, wayA.tags, { type: "multipolygon" }), + members: [ + { id: wayA.id, role: "outer", type: "way" }, + { id: wayB.id, role: "outer", type: "way" } + ] }); + graph = graph.replace(multipolygon); + graph = graph.replace(wayA.update({ tags: {} })); + graph = graph.replace(wayB.update({ tags: {} })); } - function filterContained(d) { - return d.filter(isContained); + _createdWayIDs.push(wayB.id); + return graph; + } + var action = function(graph) { + _createdWayIDs = []; + var newWayIndex = 0; + for (var i2 = 0; i2 < nodeIds.length; i2++) { + var nodeId = nodeIds[i2]; + var candidates = action.waysForNode(nodeId, graph); + for (var j2 = 0; j2 < candidates.length; j2++) { + graph = split(graph, nodeId, candidates[j2], newWayIds && newWayIds[newWayIndex]); + newWayIndex += 1; + } } - function extractUncontained(polygons2) { - polygons2.forEach(function(d, i2) { - if (!isContained(d, i2)) { - d.forEach(function(member) { - members.push({ - type: "way", - id: member.id, - role: outer ? "outer" : "inner" - }); - }); - } + return graph; + }; + action.getCreatedWayIDs = function() { + return _createdWayIDs; + }; + action.waysForNode = function(nodeId, graph) { + var node = graph.entity(nodeId); + var splittableParents = graph.parentWays(node).filter(isSplittable); + if (!_wayIDs) { + var hasLine = splittableParents.some(function(parent) { + return parent.geometry(graph) === "line"; }); - outer = !outer; - } - var relation; - if (entities.multipolygon.length > 0) { - var oldestID = utilOldestID(entities.multipolygon.map((entity) => entity.id)); - relation = entities.multipolygon.find((entity) => entity.id === oldestID); - } else { - relation = osmRelation({ id: newRelationId, tags: { type: "multipolygon" } }); - } - entities.multipolygon.forEach(function(m) { - if (m.id !== relation.id) { - relation = relation.mergeTags(m.tags); - graph = graph.remove(m); - } - }); - entities.closedWay.forEach(function(way) { - function isThisOuter(m) { - return m.id === way.id && m.role !== "inner"; + if (hasLine) { + return splittableParents.filter(function(parent) { + return parent.geometry(graph) === "line"; + }); } - if (members.some(isThisOuter)) { - relation = relation.mergeTags(way.tags); - graph = graph.replace(way.update({ tags: {} })); + } + return splittableParents; + function isSplittable(parent) { + if (_wayIDs && _wayIDs.indexOf(parent.id) === -1) + return false; + if (parent.isClosed()) + return true; + for (var i2 = 1; i2 < parent.nodes.length - 1; i2++) { + if (parent.nodes[i2] === nodeId) + return true; } - }); - return graph.replace(relation.update({ - members, - tags: utilObjectOmit(relation.tags, ["area"]) - })); + return false; + } + }; + action.ways = function(graph) { + return utilArrayUniq([].concat.apply([], nodeIds.map(function(nodeId) { + return action.waysForNode(nodeId, graph); + }))); }; action.disabled = function(graph) { - var entities = groupEntities(graph); - if (entities.other.length > 0 || entities.closedWay.length + entities.multipolygon.length < 2) { - return "not_eligible"; - } - if (!entities.multipolygon.every(function(r) { - return r.isComplete(graph); - })) { - return "incomplete_relation"; - } - if (!entities.multipolygon.length) { - var sharedMultipolygons = []; - entities.closedWay.forEach(function(way, i2) { - if (i2 === 0) { - sharedMultipolygons = graph.parentMultipolygons(way); - } else { - sharedMultipolygons = utilArrayIntersection(sharedMultipolygons, graph.parentMultipolygons(way)); - } - }); - sharedMultipolygons = sharedMultipolygons.filter(function(relation) { - return relation.members.length === entities.closedWay.length; - }); - if (sharedMultipolygons.length) { - return "not_eligible"; - } - } else if (entities.closedWay.some(function(way) { - return utilArrayIntersection(graph.parentMultipolygons(way), entities.multipolygon).length; - })) { - return "not_eligible"; + for (var i2 = 0; i2 < nodeIds.length; i2++) { + var nodeId = nodeIds[i2]; + var candidates = action.waysForNode(nodeId, graph); + if (candidates.length === 0 || _wayIDs && _wayIDs.length !== candidates.length) { + return "not_eligible"; + } } }; + action.limitWays = function(val) { + if (!arguments.length) + return _wayIDs; + _wayIDs = val; + return action; + }; + action.keepHistoryOn = function(val) { + if (!arguments.length) + return _keepHistoryOn; + _keepHistoryOn = val; + return action; + }; return action; } - // modules/actions/merge_remote_changes.js - var import_fast_deep_equal = __toESM(require_fast_deep_equal()); - - // node_modules/node-diff3/index.mjs - function LCS(buffer1, buffer2) { - let equivalenceClasses = {}; - for (let j2 = 0; j2 < buffer2.length; j2++) { - const item = buffer2[j2]; - if (equivalenceClasses[item]) { - equivalenceClasses[item].push(j2); - } else { - equivalenceClasses[item] = [j2]; - } - } - const NULLRESULT = { buffer1index: -1, buffer2index: -1, chain: null }; - let candidates = [NULLRESULT]; - for (let i2 = 0; i2 < buffer1.length; i2++) { - const item = buffer1[i2]; - const buffer2indices = equivalenceClasses[item] || []; - let r = 0; - let c = candidates[0]; - for (let jx = 0; jx < buffer2indices.length; jx++) { - const j2 = buffer2indices[jx]; - let s; - for (s = r; s < candidates.length; s++) { - if (candidates[s].buffer2index < j2 && (s === candidates.length - 1 || candidates[s + 1].buffer2index > j2)) { - break; - } - } - if (s < candidates.length) { - const newCandidate = { buffer1index: i2, buffer2index: j2, chain: candidates[s] }; - if (r === candidates.length) { - candidates.push(c); - } else { - candidates[r] = c; - } - r = s + 1; - c = newCandidate; - if (r === candidates.length) { - break; - } - } - } - candidates[r] = c; - } - return candidates[candidates.length - 1]; - } - function diffIndices(buffer1, buffer2) { - const lcs = LCS(buffer1, buffer2); - let result = []; - let tail1 = buffer1.length; - let tail2 = buffer2.length; - for (let candidate = lcs; candidate !== null; candidate = candidate.chain) { - const mismatchLength1 = tail1 - candidate.buffer1index - 1; - const mismatchLength2 = tail2 - candidate.buffer2index - 1; - tail1 = candidate.buffer1index; - tail2 = candidate.buffer2index; - if (mismatchLength1 || mismatchLength2) { - result.push({ - buffer1: [tail1 + 1, mismatchLength1], - buffer1Content: buffer1.slice(tail1 + 1, tail1 + 1 + mismatchLength1), - buffer2: [tail2 + 1, mismatchLength2], - buffer2Content: buffer2.slice(tail2 + 1, tail2 + 1 + mismatchLength2) - }); - } - } - result.reverse(); - return result; - } - function diff3MergeRegions(a, o, b) { - let hunks = []; - function addHunk(h, ab) { - hunks.push({ - ab, - oStart: h.buffer1[0], - oLength: h.buffer1[1], - abStart: h.buffer2[0], - abLength: h.buffer2[1] - }); - } - diffIndices(o, a).forEach((item) => addHunk(item, "a")); - diffIndices(o, b).forEach((item) => addHunk(item, "b")); - hunks.sort((x, y) => x.oStart - y.oStart); - let results = []; - let currOffset = 0; - function advanceTo(endOffset) { - if (endOffset > currOffset) { - results.push({ - stable: true, - buffer: "o", - bufferStart: currOffset, - bufferLength: endOffset - currOffset, - bufferContent: o.slice(currOffset, endOffset) - }); - currOffset = endOffset; - } - } - while (hunks.length) { - let hunk = hunks.shift(); - let regionStart = hunk.oStart; - let regionEnd = hunk.oStart + hunk.oLength; - let regionHunks = [hunk]; - advanceTo(regionStart); - while (hunks.length) { - const nextHunk = hunks[0]; - const nextHunkStart = nextHunk.oStart; - if (nextHunkStart > regionEnd) - break; - regionEnd = Math.max(regionEnd, nextHunkStart + nextHunk.oLength); - regionHunks.push(hunks.shift()); - } - if (regionHunks.length === 1) { - if (hunk.abLength > 0) { - const buffer = hunk.ab === "a" ? a : b; - results.push({ - stable: true, - buffer: hunk.ab, - bufferStart: hunk.abStart, - bufferLength: hunk.abLength, - bufferContent: buffer.slice(hunk.abStart, hunk.abStart + hunk.abLength) - }); - } - } else { - let bounds = { - a: [a.length, -1, o.length, -1], - b: [b.length, -1, o.length, -1] - }; - while (regionHunks.length) { - hunk = regionHunks.shift(); - const oStart = hunk.oStart; - const oEnd = oStart + hunk.oLength; - const abStart = hunk.abStart; - const abEnd = abStart + hunk.abLength; - let b2 = bounds[hunk.ab]; - b2[0] = Math.min(abStart, b2[0]); - b2[1] = Math.max(abEnd, b2[1]); - b2[2] = Math.min(oStart, b2[2]); - b2[3] = Math.max(oEnd, b2[3]); - } - const aStart = bounds.a[0] + (regionStart - bounds.a[2]); - const aEnd = bounds.a[1] + (regionEnd - bounds.a[3]); - const bStart = bounds.b[0] + (regionStart - bounds.b[2]); - const bEnd = bounds.b[1] + (regionEnd - bounds.b[3]); - let result = { - stable: false, - aStart, - aLength: aEnd - aStart, - aContent: a.slice(aStart, aEnd), - oStart: regionStart, - oLength: regionEnd - regionStart, - oContent: o.slice(regionStart, regionEnd), - bStart, - bLength: bEnd - bStart, - bContent: b.slice(bStart, bEnd) - }; - results.push(result); - } - currOffset = regionEnd; - } - advanceTo(o.length); - return results; - } - function diff3Merge(a, o, b, options2) { - let defaults2 = { - excludeFalseConflicts: true, - stringSeparator: /\s+/ - }; - options2 = Object.assign(defaults2, options2); - if (typeof a === "string") - a = a.split(options2.stringSeparator); - if (typeof o === "string") - o = o.split(options2.stringSeparator); - if (typeof b === "string") - b = b.split(options2.stringSeparator); - let results = []; - const regions = diff3MergeRegions(a, o, b); - let okBuffer = []; - function flushOk() { - if (okBuffer.length) { - results.push({ ok: okBuffer }); - } - okBuffer = []; - } - function isFalseConflict(a2, b2) { - if (a2.length !== b2.length) - return false; - for (let i2 = 0; i2 < a2.length; i2++) { - if (a2[i2] !== b2[i2]) - return false; - } - return true; + // modules/core/graph.js + function coreGraph(other, mutable) { + if (!(this instanceof coreGraph)) + return new coreGraph(other, mutable); + if (other instanceof coreGraph) { + var base = other.base(); + this.entities = Object.assign(Object.create(base.entities), other.entities); + this._parentWays = Object.assign(Object.create(base.parentWays), other._parentWays); + this._parentRels = Object.assign(Object.create(base.parentRels), other._parentRels); + } else { + this.entities = /* @__PURE__ */ Object.create({}); + this._parentWays = /* @__PURE__ */ Object.create({}); + this._parentRels = /* @__PURE__ */ Object.create({}); + this.rebase(other || [], [this]); } - regions.forEach((region) => { - if (region.stable) { - okBuffer.push(...region.bufferContent); - } else { - if (options2.excludeFalseConflicts && isFalseConflict(region.aContent, region.bContent)) { - okBuffer.push(...region.aContent); - } else { - flushOk(); - results.push({ - conflict: { - a: region.aContent, - aIndex: region.aStart, - o: region.oContent, - oIndex: region.oStart, - b: region.bContent, - bIndex: region.bStart - } - }); - } - } - }); - flushOk(); - return results; + this.transients = {}; + this._childNodes = {}; + this.frozen = !mutable; } - - // modules/actions/merge_remote_changes.js - var import_lodash = __toESM(require_lodash()); - function actionMergeRemoteChanges(id2, localGraph, remoteGraph, discardTags, formatUser) { - discardTags = discardTags || {}; - var _option = "safe"; - var _conflicts = []; - function user(d) { - return typeof formatUser === "function" ? formatUser(d) : (0, import_lodash.escape)(d); - } - function mergeLocation(remote, target) { - function pointEqual(a, b) { - var epsilon3 = 1e-6; - return Math.abs(a[0] - b[0]) < epsilon3 && Math.abs(a[1] - b[1]) < epsilon3; + coreGraph.prototype = { + hasEntity: function(id2) { + return this.entities[id2]; + }, + entity: function(id2) { + var entity = this.entities[id2]; + if (!entity) { + entity = this.entities.__proto__[id2]; } - if (_option === "force_local" || pointEqual(target.loc, remote.loc)) { - return target; + if (!entity) { + throw new Error("entity " + id2 + " not found"); } - if (_option === "force_remote") { - return target.update({ loc: remote.loc }); + return entity; + }, + geometry: function(id2) { + return this.entity(id2).geometry(this); + }, + transient: function(entity, key, fn) { + var id2 = entity.id; + var transients = this.transients[id2] || (this.transients[id2] = {}); + if (transients[key] !== void 0) { + return transients[key]; } - _conflicts.push(_t.html("merge_remote_changes.conflict.location", { user: { html: user(remote.user) } })); - return target; - } - function mergeNodes(base, remote, target) { - if (_option === "force_local" || (0, import_fast_deep_equal.default)(target.nodes, remote.nodes)) { - return target; + transients[key] = fn.call(entity); + return transients[key]; + }, + parentWays: function(entity) { + var parents = this._parentWays[entity.id]; + var result = []; + if (parents) { + parents.forEach(function(id2) { + result.push(this.entity(id2)); + }, this); } - if (_option === "force_remote") { - return target.update({ nodes: remote.nodes }); + return result; + }, + isPoi: function(entity) { + var parents = this._parentWays[entity.id]; + return !parents || parents.size === 0; + }, + isShared: function(entity) { + var parents = this._parentWays[entity.id]; + return parents && parents.size > 1; + }, + parentRelations: function(entity) { + var parents = this._parentRels[entity.id]; + var result = []; + if (parents) { + parents.forEach(function(id2) { + result.push(this.entity(id2)); + }, this); } - var ccount = _conflicts.length; - var o = base.nodes || []; - var a = target.nodes || []; - var b = remote.nodes || []; + return result; + }, + parentMultipolygons: function(entity) { + return this.parentRelations(entity).filter(function(relation) { + return relation.isMultipolygon(); + }); + }, + childNodes: function(entity) { + if (this._childNodes[entity.id]) + return this._childNodes[entity.id]; + if (!entity.nodes) + return []; var nodes = []; - var hunks = diff3Merge(a, o, b, { excludeFalseConflicts: true }); - for (var i2 = 0; i2 < hunks.length; i2++) { - var hunk = hunks[i2]; - if (hunk.ok) { - nodes.push.apply(nodes, hunk.ok); - } else { - var c = hunk.conflict; - if ((0, import_fast_deep_equal.default)(c.o, c.a)) { - nodes.push.apply(nodes, c.b); - } else if ((0, import_fast_deep_equal.default)(c.o, c.b)) { - nodes.push.apply(nodes, c.a); - } else { - _conflicts.push(_t.html("merge_remote_changes.conflict.nodelist", { user: { html: user(remote.user) } })); - break; - } - } - } - return _conflicts.length === ccount ? target.update({ nodes }) : target; - } - function mergeChildren(targetWay, children2, updates, graph) { - function isUsed(node2, targetWay2) { - var hasInterestingParent = graph.parentWays(node2).some(function(way) { - return way.id !== targetWay2.id; - }); - return node2.hasInterestingTags() || hasInterestingParent || graph.parentRelations(node2).length > 0; + for (var i2 = 0; i2 < entity.nodes.length; i2++) { + nodes[i2] = this.entity(entity.nodes[i2]); } - var ccount = _conflicts.length; - for (var i2 = 0; i2 < children2.length; i2++) { - var id3 = children2[i2]; - var node = graph.hasEntity(id3); - if (targetWay.nodes.indexOf(id3) === -1) { - if (node && !isUsed(node, targetWay)) { - updates.removeIds.push(id3); - } + if (debug) + Object.freeze(nodes); + this._childNodes[entity.id] = nodes; + return this._childNodes[entity.id]; + }, + base: function() { + return { + "entities": Object.getPrototypeOf(this.entities), + "parentWays": Object.getPrototypeOf(this._parentWays), + "parentRels": Object.getPrototypeOf(this._parentRels) + }; + }, + // Unlike other graph methods, rebase mutates in place. This is because it + // is used only during the history operation that merges newly downloaded + // data into each state. To external consumers, it should appear as if the + // graph always contained the newly downloaded data. + rebase: function(entities, stack, force) { + var base = this.base(); + var i2, j2, k, id2; + for (i2 = 0; i2 < entities.length; i2++) { + var entity = entities[i2]; + if (!entity.visible || !force && base.entities[entity.id]) continue; - } - var local = localGraph.hasEntity(id3); - var remote = remoteGraph.hasEntity(id3); - var target; - if (_option === "force_remote" && remote && remote.visible) { - updates.replacements.push(remote); - } else if (_option === "force_local" && local) { - target = osmEntity(local); - if (remote) { - target = target.update({ version: remote.version }); - } - updates.replacements.push(target); - } else if (_option === "safe" && local && remote && local.version !== remote.version) { - target = osmEntity(local, { version: remote.version }); - if (remote.visible) { - target = mergeLocation(remote, target); - } else { - _conflicts.push(_t.html("merge_remote_changes.conflict.deleted", { user: { html: user(remote.user) } })); + base.entities[entity.id] = entity; + this._updateCalculated(void 0, entity, base.parentWays, base.parentRels); + if (entity.type === "way") { + for (j2 = 0; j2 < entity.nodes.length; j2++) { + id2 = entity.nodes[j2]; + for (k = 1; k < stack.length; k++) { + var ents = stack[k].entities; + if (ents.hasOwnProperty(id2) && ents[id2] === void 0) { + delete ents[id2]; + } + } } - if (_conflicts.length !== ccount) - break; - updates.replacements.push(target); } } - return targetWay; - } - function updateChildren(updates, graph) { - for (var i2 = 0; i2 < updates.replacements.length; i2++) { - graph = graph.replace(updates.replacements[i2]); - } - if (updates.removeIds.length) { - graph = actionDeleteMultiple(updates.removeIds)(graph); - } - return graph; - } - function mergeMembers(remote, target) { - if (_option === "force_local" || (0, import_fast_deep_equal.default)(target.members, remote.members)) { - return target; - } - if (_option === "force_remote") { - return target.update({ members: remote.members }); - } - _conflicts.push(_t.html("merge_remote_changes.conflict.memberlist", { user: { html: user(remote.user) } })); - return target; - } - function mergeTags(base, remote, target) { - if (_option === "force_local" || (0, import_fast_deep_equal.default)(target.tags, remote.tags)) { - return target; - } - if (_option === "force_remote") { - return target.update({ tags: remote.tags }); + for (i2 = 0; i2 < stack.length; i2++) { + stack[i2]._updateRebased(); } - var ccount = _conflicts.length; - var o = base.tags || {}; - var a = target.tags || {}; - var b = remote.tags || {}; - var keys = utilArrayUnion(utilArrayUnion(Object.keys(o), Object.keys(a)), Object.keys(b)).filter(function(k2) { - return !discardTags[k2]; - }); - var tags = Object.assign({}, a); - var changed = false; - for (var i2 = 0; i2 < keys.length; i2++) { - var k = keys[i2]; - if (o[k] !== b[k] && a[k] !== b[k]) { - if (o[k] !== a[k]) { - _conflicts.push(_t.html( - "merge_remote_changes.conflict.tags", - { tag: k, local: a[k], remote: b[k], user: { html: user(remote.user) } } - )); - } else { - if (b.hasOwnProperty(k)) { - tags[k] = b[k]; - } else { - delete tags[k]; + }, + _updateRebased: function() { + var base = this.base(); + Object.keys(this._parentWays).forEach(function(child) { + if (base.parentWays[child]) { + base.parentWays[child].forEach(function(id2) { + if (!this.entities.hasOwnProperty(id2)) { + this._parentWays[child].add(id2); } - changed = true; - } + }, this); } - } - return changed && _conflicts.length === ccount ? target.update({ tags }) : target; - } - var action = function(graph) { - var updates = { replacements: [], removeIds: [] }; - var base = graph.base().entities[id2]; - var local = localGraph.entity(id2); - var remote = remoteGraph.entity(id2); - var target = osmEntity(local, { version: remote.version }); - if (!remote.visible) { - if (_option === "force_remote") { - return actionDeleteMultiple([id2])(graph); - } else if (_option === "force_local") { - if (target.type === "way") { - target = mergeChildren(target, utilArrayUniq(local.nodes), updates, graph); - graph = updateChildren(updates, graph); - } - return graph.replace(target); - } else { - _conflicts.push(_t.html("merge_remote_changes.conflict.deleted", { user: { html: user(remote.user) } })); - return graph; + }, this); + Object.keys(this._parentRels).forEach(function(child) { + if (base.parentRels[child]) { + base.parentRels[child].forEach(function(id2) { + if (!this.entities.hasOwnProperty(id2)) { + this._parentRels[child].add(id2); + } + }, this); + } + }, this); + this.transients = {}; + }, + // Updates calculated properties (parentWays, parentRels) for the specified change + _updateCalculated: function(oldentity, entity, parentWays, parentRels) { + parentWays = parentWays || this._parentWays; + parentRels = parentRels || this._parentRels; + var type2 = entity && entity.type || oldentity && oldentity.type; + var removed, added, i2; + if (type2 === "way") { + if (oldentity && entity) { + removed = utilArrayDifference(oldentity.nodes, entity.nodes); + added = utilArrayDifference(entity.nodes, oldentity.nodes); + } else if (oldentity) { + removed = oldentity.nodes; + added = []; + } else if (entity) { + removed = []; + added = entity.nodes; + } + for (i2 = 0; i2 < removed.length; i2++) { + parentWays[removed[i2]] = new Set(parentWays[removed[i2]]); + parentWays[removed[i2]].delete(oldentity.id); + } + for (i2 = 0; i2 < added.length; i2++) { + parentWays[added[i2]] = new Set(parentWays[added[i2]]); + parentWays[added[i2]].add(entity.id); + } + } else if (type2 === "relation") { + var oldentityMemberIDs = oldentity ? oldentity.members.map(function(m) { + return m.id; + }) : []; + var entityMemberIDs = entity ? entity.members.map(function(m) { + return m.id; + }) : []; + if (oldentity && entity) { + removed = utilArrayDifference(oldentityMemberIDs, entityMemberIDs); + added = utilArrayDifference(entityMemberIDs, oldentityMemberIDs); + } else if (oldentity) { + removed = oldentityMemberIDs; + added = []; + } else if (entity) { + removed = []; + added = entityMemberIDs; + } + for (i2 = 0; i2 < removed.length; i2++) { + parentRels[removed[i2]] = new Set(parentRels[removed[i2]]); + parentRels[removed[i2]].delete(oldentity.id); + } + for (i2 = 0; i2 < added.length; i2++) { + parentRels[added[i2]] = new Set(parentRels[added[i2]]); + parentRels[added[i2]].add(entity.id); } } - if (target.type === "node") { - target = mergeLocation(remote, target); - } else if (target.type === "way") { - graph.rebase(remoteGraph.childNodes(remote), [graph], false); - target = mergeNodes(base, remote, target); - target = mergeChildren(target, utilArrayUnion(local.nodes, remote.nodes), updates, graph); - } else if (target.type === "relation") { - target = mergeMembers(remote, target); - } - target = mergeTags(base, remote, target); - if (!_conflicts.length) { - graph = updateChildren(updates, graph).replace(target); + }, + replace: function(entity) { + if (this.entities[entity.id] === entity) + return this; + return this.update(function() { + this._updateCalculated(this.entities[entity.id], entity); + this.entities[entity.id] = entity; + }); + }, + remove: function(entity) { + return this.update(function() { + this._updateCalculated(entity, void 0); + this.entities[entity.id] = void 0; + }); + }, + revert: function(id2) { + var baseEntity = this.base().entities[id2]; + var headEntity = this.entities[id2]; + if (headEntity === baseEntity) + return this; + return this.update(function() { + this._updateCalculated(headEntity, baseEntity); + delete this.entities[id2]; + }); + }, + update: function() { + var graph = this.frozen ? coreGraph(this, true) : this; + for (var i2 = 0; i2 < arguments.length; i2++) { + arguments[i2].call(graph, graph); } + if (this.frozen) + graph.frozen = true; return graph; - }; - action.withOption = function(opt) { - _option = opt; - return action; - }; - action.conflicts = function() { - return _conflicts; - }; - return action; - } - - // modules/actions/move.js - function actionMove(moveIDs, tryDelta, projection2, cache) { - var _delta = tryDelta; - function setupCache(graph) { - function canMove(nodeID) { - if (moveIDs.indexOf(nodeID) !== -1) - return true; - var parents = graph.parentWays(graph.entity(nodeID)); - if (parents.length < 3) - return true; - var parentsMoving = parents.every(function(way) { - return cache.moving[way.id]; - }); - if (!parentsMoving) - delete cache.moving[nodeID]; - return parentsMoving; + }, + // Obliterates any existing entities + load: function(entities) { + var base = this.base(); + this.entities = Object.create(base.entities); + for (var i2 in entities) { + this.entities[i2] = entities[i2]; + this._updateCalculated(base.entities[i2], this.entities[i2]); } - function cacheEntities(ids) { - for (var i2 = 0; i2 < ids.length; i2++) { - var id2 = ids[i2]; - if (cache.moving[id2]) + return this; + } + }; + + // modules/osm/intersection.js + function osmTurn(turn) { + if (!(this instanceof osmTurn)) { + return new osmTurn(turn); + } + Object.assign(this, turn); + } + function osmIntersection(graph, startVertexId, maxDistance) { + maxDistance = maxDistance || 30; + var vgraph = coreGraph(); + var i2, j2, k; + function memberOfRestriction(entity) { + return graph.parentRelations(entity).some(function(r) { + return r.isRestriction(); + }); + } + function isRoad(way2) { + if (way2.isArea() || way2.isDegenerate()) + return false; + var roads = { + "motorway": true, + "motorway_link": true, + "trunk": true, + "trunk_link": true, + "primary": true, + "primary_link": true, + "secondary": true, + "secondary_link": true, + "tertiary": true, + "tertiary_link": true, + "residential": true, + "unclassified": true, + "living_street": true, + "service": true, + "road": true, + "track": true + }; + return roads[way2.tags.highway]; + } + var startNode = graph.entity(startVertexId); + var checkVertices = [startNode]; + var checkWays; + var vertices = []; + var vertexIds = []; + var vertex; + var ways = []; + var wayIds = []; + var way; + var nodes = []; + var node; + var parents = []; + var parent; + var actions = []; + while (checkVertices.length) { + vertex = checkVertices.pop(); + checkWays = graph.parentWays(vertex); + var hasWays = false; + for (i2 = 0; i2 < checkWays.length; i2++) { + way = checkWays[i2]; + if (!isRoad(way) && !memberOfRestriction(way)) + continue; + ways.push(way); + hasWays = true; + nodes = utilArrayUniq(graph.childNodes(way)); + for (j2 = 0; j2 < nodes.length; j2++) { + node = nodes[j2]; + if (node === vertex) continue; - cache.moving[id2] = true; - var entity = graph.hasEntity(id2); - if (!entity) + if (vertices.indexOf(node) !== -1) continue; - if (entity.type === "node") { - cache.nodes.push(id2); - cache.startLoc[id2] = entity.loc; - } else if (entity.type === "way") { - cache.ways.push(id2); - cacheEntities(entity.nodes); - } else { - cacheEntities(entity.members.map(function(member) { - return member.id; - })); - } - } - } - function cacheIntersections(ids) { - function isEndpoint(way2, id3) { - return !way2.isClosed() && !!way2.affix(id3); - } - for (var i2 = 0; i2 < ids.length; i2++) { - var id2 = ids[i2]; - var childNodes = graph.childNodes(graph.entity(id2)); - for (var j2 = 0; j2 < childNodes.length; j2++) { - var node = childNodes[j2]; - var parents = graph.parentWays(node); - if (parents.length !== 2) - continue; - var moved = graph.entity(id2); - var unmoved = null; - for (var k = 0; k < parents.length; k++) { - var way = parents[k]; - if (!cache.moving[way.id]) { - unmoved = way; - break; - } - } - if (!unmoved) + if (geoSphericalDistance(node.loc, startNode.loc) > maxDistance) + continue; + var hasParents = false; + parents = graph.parentWays(node); + for (k = 0; k < parents.length; k++) { + parent = parents[k]; + if (parent === way) continue; - if (utilArrayIntersection(moved.nodes, unmoved.nodes).length > 2) + if (ways.indexOf(parent) !== -1) continue; - if (moved.isArea() || unmoved.isArea()) + if (!isRoad(parent)) continue; - cache.intersections.push({ - nodeId: node.id, - movedId: moved.id, - unmovedId: unmoved.id, - movedIsEP: isEndpoint(moved, node.id), - unmovedIsEP: isEndpoint(unmoved, node.id) - }); + hasParents = true; + break; + } + if (hasParents) { + checkVertices.push(node); } } } - if (!cache) { - cache = {}; - } - if (!cache.ok) { - cache.moving = {}; - cache.intersections = []; - cache.replacedVertex = {}; - cache.startLoc = {}; - cache.nodes = []; - cache.ways = []; - cacheEntities(moveIDs); - cacheIntersections(cache.ways); - cache.nodes = cache.nodes.filter(canMove); - cache.ok = true; - } - } - function replaceMovedVertex(nodeId, wayId, graph, delta) { - var way = graph.entity(wayId); - var moved = graph.entity(nodeId); - var movedIndex = way.nodes.indexOf(nodeId); - var len, prevIndex, nextIndex; - if (way.isClosed()) { - len = way.nodes.length - 1; - prevIndex = (movedIndex + len - 1) % len; - nextIndex = (movedIndex + len + 1) % len; - } else { - len = way.nodes.length; - prevIndex = movedIndex - 1; - nextIndex = movedIndex + 1; - } - var prev = graph.hasEntity(way.nodes[prevIndex]); - var next = graph.hasEntity(way.nodes[nextIndex]); - if (!prev || !next) - return graph; - var key = wayId + "_" + nodeId; - var orig = cache.replacedVertex[key]; - if (!orig) { - orig = osmNode(); - cache.replacedVertex[key] = orig; - cache.startLoc[orig.id] = cache.startLoc[nodeId]; - } - var start2, end; - if (delta) { - start2 = projection2(cache.startLoc[nodeId]); - end = projection2.invert(geoVecAdd(start2, delta)); - } else { - end = cache.startLoc[nodeId]; + if (hasWays) { + vertices.push(vertex); } - orig = orig.move(end); - var angle2 = Math.abs(geoAngle(orig, prev, projection2) - geoAngle(orig, next, projection2)) * 180 / Math.PI; - if (angle2 > 175 && angle2 < 185) - return graph; - var p1 = [prev.loc, orig.loc, moved.loc, next.loc].map(projection2); - var p2 = [prev.loc, moved.loc, orig.loc, next.loc].map(projection2); - var d1 = geoPathLength(p1); - var d2 = geoPathLength(p2); - var insertAt = d1 <= d2 ? movedIndex : nextIndex; - if (way.isClosed() && insertAt === 0) - insertAt = len; - way = way.addNode(orig.id, insertAt); - return graph.replace(orig).replace(way); } - function removeDuplicateVertices(wayId, graph) { - var way = graph.entity(wayId); - var epsilon3 = 1e-6; - var prev, curr; - function isInteresting(node, graph2) { - return graph2.parentWays(node).length > 1 || graph2.parentRelations(node).length || node.hasInterestingTags(); - } - for (var i2 = 0; i2 < way.nodes.length; i2++) { - curr = graph.entity(way.nodes[i2]); - if (prev && curr && geoVecEqual(prev.loc, curr.loc, epsilon3)) { - if (!isInteresting(prev, graph)) { - way = way.removeNode(prev.id); - graph = graph.replace(way).remove(prev); - } else if (!isInteresting(curr, graph)) { - way = way.removeNode(curr.id); - graph = graph.replace(way).remove(curr); + vertices = utilArrayUniq(vertices); + ways = utilArrayUniq(ways); + ways.forEach(function(way2) { + graph.childNodes(way2).forEach(function(node2) { + vgraph = vgraph.replace(node2); + }); + vgraph = vgraph.replace(way2); + graph.parentRelations(way2).forEach(function(relation) { + if (relation.isRestriction()) { + if (relation.isValidRestriction(graph)) { + vgraph = vgraph.replace(relation); + } else if (relation.isComplete(graph)) { + actions.push(actionDeleteRelation(relation.id)); } } - prev = curr; - } - return graph; - } - function unZorroIntersection(intersection, graph) { - var vertex = graph.entity(intersection.nodeId); - var way1 = graph.entity(intersection.movedId); - var way2 = graph.entity(intersection.unmovedId); - var isEP1 = intersection.movedIsEP; - var isEP2 = intersection.unmovedIsEP; - if (isEP1 && isEP2) - return graph; - var nodes1 = graph.childNodes(way1).filter(function(n2) { - return n2 !== vertex; - }); - var nodes2 = graph.childNodes(way2).filter(function(n2) { - return n2 !== vertex; }); - if (way1.isClosed() && way1.first() === vertex.id) - nodes1.push(nodes1[0]); - if (way2.isClosed() && way2.first() === vertex.id) - nodes2.push(nodes2[0]); - var edge1 = !isEP1 && geoChooseEdge(nodes1, projection2(vertex.loc), projection2); - var edge2 = !isEP2 && geoChooseEdge(nodes2, projection2(vertex.loc), projection2); - var loc; - if (!isEP1 && !isEP2) { - var epsilon3 = 1e-6, maxIter = 10; - for (var i2 = 0; i2 < maxIter; i2++) { - loc = geoVecInterp(edge1.loc, edge2.loc, 0.5); - edge1 = geoChooseEdge(nodes1, projection2(loc), projection2); - edge2 = geoChooseEdge(nodes2, projection2(loc), projection2); - if (Math.abs(edge1.distance - edge2.distance) < epsilon3) - break; - } - } else if (!isEP1) { - loc = edge1.loc; - } else { - loc = edge2.loc; - } - graph = graph.replace(vertex.move(loc)); - if (!isEP1 && edge1.index !== way1.nodes.indexOf(vertex.id)) { - way1 = way1.removeNode(vertex.id).addNode(vertex.id, edge1.index); - graph = graph.replace(way1); - } - if (!isEP2 && edge2.index !== way2.nodes.indexOf(vertex.id)) { - way2 = way2.removeNode(vertex.id).addNode(vertex.id, edge2.index); - graph = graph.replace(way2); - } - return graph; - } - function cleanupIntersections(graph) { - for (var i2 = 0; i2 < cache.intersections.length; i2++) { - var obj = cache.intersections[i2]; - graph = replaceMovedVertex(obj.nodeId, obj.movedId, graph, _delta); - graph = replaceMovedVertex(obj.nodeId, obj.unmovedId, graph, null); - graph = unZorroIntersection(obj, graph); - graph = removeDuplicateVertices(obj.movedId, graph); - graph = removeDuplicateVertices(obj.unmovedId, graph); - } - return graph; - } - function limitDelta(graph) { - function moveNode(loc) { - return geoVecAdd(projection2(loc), _delta); + }); + ways.forEach(function(w) { + var way2 = vgraph.entity(w.id); + if (way2.tags.oneway === "-1") { + var action = actionReverse(way2.id, { reverseOneway: true }); + actions.push(action); + vgraph = action(vgraph); } - for (var i2 = 0; i2 < cache.intersections.length; i2++) { - var obj = cache.intersections[i2]; - if (obj.movedIsEP && obj.unmovedIsEP) - continue; - if (!obj.movedIsEP) - continue; - var node = graph.entity(obj.nodeId); - var start2 = projection2(node.loc); - var end = geoVecAdd(start2, _delta); - var movedNodes = graph.childNodes(graph.entity(obj.movedId)); - var movedPath = movedNodes.map(function(n2) { - return moveNode(n2.loc); - }); - var unmovedNodes = graph.childNodes(graph.entity(obj.unmovedId)); - var unmovedPath = unmovedNodes.map(function(n2) { - return projection2(n2.loc); + }); + var origCount = osmEntity.id.next.way; + vertices.forEach(function(v) { + var splitAll = actionSplit([v.id]).keepHistoryOn("first"); + if (!splitAll.disabled(vgraph)) { + splitAll.ways(vgraph).forEach(function(way2) { + var splitOne = actionSplit([v.id]).limitWays([way2.id]).keepHistoryOn("first"); + actions.push(splitOne); + vgraph = splitOne(vgraph); }); - var hits = geoPathIntersections(movedPath, unmovedPath); - for (var j2 = 0; i2 < hits.length; i2++) { - if (geoVecEqual(hits[j2], end)) - continue; - var edge = geoChooseEdge(unmovedNodes, end, projection2); - _delta = geoVecSubtract(projection2(edge.loc), start2); - } } + }); + osmEntity.id.next.way = origCount; + vertexIds = vertices.map(function(v) { + return v.id; + }); + vertices = []; + ways = []; + vertexIds.forEach(function(id2) { + var vertex2 = vgraph.entity(id2); + var parents2 = vgraph.parentWays(vertex2); + vertices.push(vertex2); + ways = ways.concat(parents2); + }); + vertices = utilArrayUniq(vertices); + ways = utilArrayUniq(ways); + vertexIds = vertices.map(function(v) { + return v.id; + }); + wayIds = ways.map(function(w) { + return w.id; + }); + function withMetadata(way2, vertexIds2) { + var __oneWay = way2.isOneWay(); + var __first = vertexIds2.indexOf(way2.first()) !== -1; + var __last = vertexIds2.indexOf(way2.last()) !== -1; + var __via = __first && __last; + var __from = __first && !__oneWay || __last; + var __to = __first || __last && !__oneWay; + return way2.update({ + __first, + __last, + __from, + __via, + __to, + __oneWay + }); } - var action = function(graph) { - if (_delta[0] === 0 && _delta[1] === 0) - return graph; - setupCache(graph); - if (cache.intersections.length) { - limitDelta(graph); - } - for (var i2 = 0; i2 < cache.nodes.length; i2++) { - var node = graph.entity(cache.nodes[i2]); - var start2 = projection2(node.loc); - var end = geoVecAdd(start2, _delta); - graph = graph.replace(node.move(projection2.invert(end))); - } - if (cache.intersections.length) { - graph = cleanupIntersections(graph); - } - return graph; - }; - action.delta = function() { - return _delta; - }; - return action; - } - - // modules/actions/move_member.js - function actionMoveMember(relationId, fromIndex, toIndex) { - return function(graph) { - return graph.replace(graph.entity(relationId).moveMember(fromIndex, toIndex)); - }; - } - - // modules/actions/move_node.js - function actionMoveNode(nodeID, toLoc) { - var action = function(graph, t) { - if (t === null || !isFinite(t)) - t = 1; - t = Math.min(Math.max(+t, 0), 1); - var node = graph.entity(nodeID); - return graph.replace( - node.move(geoVecInterp(node.loc, toLoc, t)) - ); - }; - action.transitionable = true; - return action; - } - - // modules/actions/noop.js - function actionNoop() { - return function(graph) { - return graph; - }; - } - - // modules/actions/orthogonalize.js - function actionOrthogonalize(wayID, projection2, vertexID, degThresh, ep) { - var epsilon3 = ep || 1e-4; - var threshold = degThresh || 13; - var lowerThreshold = Math.cos((90 - threshold) * Math.PI / 180); - var upperThreshold = Math.cos(threshold * Math.PI / 180); - var action = function(graph, t) { - if (t === null || !isFinite(t)) - t = 1; - t = Math.min(Math.max(+t, 0), 1); - var way = graph.entity(wayID); - way = way.removeNode(""); - if (way.tags.nonsquare) { - var tags = Object.assign({}, way.tags); - delete tags.nonsquare; - way = way.update({ tags }); - } - graph = graph.replace(way); - var isClosed = way.isClosed(); - var nodes = graph.childNodes(way).slice(); - if (isClosed) - nodes.pop(); - if (vertexID !== void 0) { - nodes = nodeSubset(nodes, vertexID, isClosed); - if (nodes.length !== 3) - return graph; - } - var nodeCount = {}; - var points = []; - var corner = { i: 0, dotp: 1 }; - var node, point, loc, score, motions, i2, j2; - for (i2 = 0; i2 < nodes.length; i2++) { - node = nodes[i2]; - nodeCount[node.id] = (nodeCount[node.id] || 0) + 1; - points.push({ id: node.id, coord: projection2(node.loc) }); - } - if (points.length === 3) { - for (i2 = 0; i2 < 1e3; i2++) { - motions = points.map(calcMotion); - points[corner.i].coord = geoVecAdd(points[corner.i].coord, motions[corner.i]); - score = corner.dotp; - if (score < epsilon3) { - break; + ways = []; + wayIds.forEach(function(id2) { + var way2 = withMetadata(vgraph.entity(id2), vertexIds); + vgraph = vgraph.replace(way2); + ways.push(way2); + }); + var keepGoing; + var removeWayIds = []; + var removeVertexIds = []; + do { + keepGoing = false; + checkVertices = vertexIds.slice(); + for (i2 = 0; i2 < checkVertices.length; i2++) { + var vertexId = checkVertices[i2]; + vertex = vgraph.hasEntity(vertexId); + if (!vertex) { + if (vertexIds.indexOf(vertexId) !== -1) { + vertexIds.splice(vertexIds.indexOf(vertexId), 1); } + removeVertexIds.push(vertexId); + continue; } - node = graph.entity(nodes[corner.i].id); - loc = projection2.invert(points[corner.i].coord); - graph = graph.replace(node.move(geoVecInterp(node.loc, loc, t))); - } else { - var straights = []; - var simplified = []; - for (i2 = 0; i2 < points.length; i2++) { - point = points[i2]; - var dotp = 0; - if (isClosed || i2 > 0 && i2 < points.length - 1) { - var a = points[(i2 - 1 + points.length) % points.length]; - var b = points[(i2 + 1) % points.length]; - dotp = Math.abs(geoOrthoNormalizedDotProduct(a.coord, b.coord, point.coord)); - } - if (dotp > upperThreshold) { - straights.push(point); - } else { - simplified.push(point); + parents = vgraph.parentWays(vertex); + if (parents.length < 3) { + if (vertexIds.indexOf(vertexId) !== -1) { + vertexIds.splice(vertexIds.indexOf(vertexId), 1); } } - var bestPoints = clonePoints(simplified); - var originalPoints = clonePoints(simplified); - score = Infinity; - for (i2 = 0; i2 < 1e3; i2++) { - motions = simplified.map(calcMotion); - for (j2 = 0; j2 < motions.length; j2++) { - simplified[j2].coord = geoVecAdd(simplified[j2].coord, motions[j2]); - } - var newScore = geoOrthoCalcScore(simplified, isClosed, epsilon3, threshold); - if (newScore < score) { - bestPoints = clonePoints(simplified); - score = newScore; + if (parents.length === 2) { + var a = parents[0]; + var b = parents[1]; + var aIsLeaf = a && !a.__via; + var bIsLeaf = b && !b.__via; + var leaf, survivor; + if (aIsLeaf && !bIsLeaf) { + leaf = a; + survivor = b; + } else if (!aIsLeaf && bIsLeaf) { + leaf = b; + survivor = a; } - if (score < epsilon3) { - break; + if (leaf && survivor) { + survivor = withMetadata(survivor, vertexIds); + vgraph = vgraph.replace(survivor).remove(leaf); + removeWayIds.push(leaf.id); + keepGoing = true; } } - var bestCoords = bestPoints.map(function(p) { - return p.coord; - }); - if (isClosed) - bestCoords.push(bestCoords[0]); - for (i2 = 0; i2 < bestPoints.length; i2++) { - point = bestPoints[i2]; - if (!geoVecEqual(originalPoints[i2].coord, point.coord)) { - node = graph.entity(point.id); - loc = projection2.invert(point.coord); - graph = graph.replace(node.move(geoVecInterp(node.loc, loc, t))); + parents = vgraph.parentWays(vertex); + if (parents.length < 2) { + if (vertexIds.indexOf(vertexId) !== -1) { + vertexIds.splice(vertexIds.indexOf(vertexId), 1); } + removeVertexIds.push(vertexId); + keepGoing = true; } - for (i2 = 0; i2 < straights.length; i2++) { - point = straights[i2]; - if (nodeCount[point.id] > 1) + if (parents.length < 1) { + vgraph = vgraph.remove(vertex); + } + } + } while (keepGoing); + vertices = vertices.filter(function(vertex2) { + return removeVertexIds.indexOf(vertex2.id) === -1; + }).map(function(vertex2) { + return vgraph.entity(vertex2.id); + }); + ways = ways.filter(function(way2) { + return removeWayIds.indexOf(way2.id) === -1; + }).map(function(way2) { + return vgraph.entity(way2.id); + }); + var intersection = { + graph: vgraph, + actions, + vertices, + ways + }; + intersection.turns = function(fromWayId, maxViaWay) { + if (!fromWayId) + return []; + if (!maxViaWay) + maxViaWay = 0; + var vgraph2 = intersection.graph; + var keyVertexIds = intersection.vertices.map(function(v) { + return v.id; + }); + var start2 = vgraph2.entity(fromWayId); + if (!start2 || !(start2.__from || start2.__via)) + return []; + var maxPathLength = maxViaWay * 2 + 3; + var turns = []; + step(start2); + return turns; + function step(entity, currPath, currRestrictions, matchedRestriction) { + currPath = (currPath || []).slice(); + if (currPath.length >= maxPathLength) + return; + currPath.push(entity.id); + currRestrictions = (currRestrictions || []).slice(); + if (entity.type === "node") { + stepNode(entity, currPath, currRestrictions); + } else { + stepWay(entity, currPath, currRestrictions, matchedRestriction); + } + } + function stepNode(entity, currPath, currRestrictions) { + var i3, j3; + var parents2 = vgraph2.parentWays(entity); + var nextWays = []; + for (i3 = 0; i3 < parents2.length; i3++) { + var way2 = parents2[i3]; + if (way2.__oneWay && way2.nodes[0] !== entity.id) continue; - node = graph.entity(point.id); - if (t === 1 && graph.parentWays(node).length === 1 && graph.parentRelations(node).length === 0 && !node.hasInterestingTags()) { - graph = actionDeleteNode(node.id)(graph); - } else { - var choice = geoVecProject(point.coord, bestCoords); - if (choice) { - loc = projection2.invert(choice.target); - graph = graph.replace(node.move(geoVecInterp(node.loc, loc, t))); + if (currPath.indexOf(way2.id) !== -1 && currPath.length >= 3) + continue; + var restrict = null; + for (j3 = 0; j3 < currRestrictions.length; j3++) { + var restriction = currRestrictions[j3]; + var f2 = restriction.memberByRole("from"); + var v = restriction.membersByRole("via"); + var t = restriction.memberByRole("to"); + var isNo = /^no_/.test(restriction.tags.restriction); + var isOnly = /^only_/.test(restriction.tags.restriction); + if (!(isNo || isOnly)) { + continue; + } + var matchesFrom = f2.id === fromWayId; + var matchesViaTo = false; + var isAlongOnlyPath = false; + if (t.id === way2.id) { + if (v.length === 1 && v[0].type === "node") { + matchesViaTo = v[0].id === entity.id && (matchesFrom && currPath.length === 2 || !matchesFrom && currPath.length > 2); + } else { + var pathVias = []; + for (k = 2; k < currPath.length; k += 2) { + pathVias.push(currPath[k]); + } + var restrictionVias = []; + for (k = 0; k < v.length; k++) { + if (v[k].type === "way") { + restrictionVias.push(v[k].id); + } + } + var diff = utilArrayDifference(pathVias, restrictionVias); + matchesViaTo = !diff.length; + } + } else if (isOnly) { + for (k = 0; k < v.length; k++) { + if (v[k].type === "way" && v[k].id === way2.id) { + isAlongOnlyPath = true; + break; + } + } + } + if (matchesViaTo) { + if (isOnly) { + restrict = { id: restriction.id, direct: matchesFrom, from: f2.id, only: true, end: true }; + } else { + restrict = { id: restriction.id, direct: matchesFrom, from: f2.id, no: true, end: true }; + } + } else { + if (isAlongOnlyPath) { + restrict = { id: restriction.id, direct: false, from: f2.id, only: true, end: false }; + } else if (isOnly) { + restrict = { id: restriction.id, direct: false, from: f2.id, no: true, end: true }; + } } + if (restrict && restrict.direct) + break; } + nextWays.push({ way: way2, restrict }); } - } - return graph; - function clonePoints(array2) { - return array2.map(function(p) { - return { id: p.id, coord: [p.coord[0], p.coord[1]] }; + nextWays.forEach(function(nextWay) { + step(nextWay.way, currPath, currRestrictions, nextWay.restrict); }); } - function calcMotion(point2, i3, array2) { - if (!isClosed && (i3 === 0 || i3 === array2.length - 1)) - return [0, 0]; - if (nodeCount[array2[i3].id] > 1) - return [0, 0]; - var a2 = array2[(i3 - 1 + array2.length) % array2.length].coord; - var origin = point2.coord; - var b2 = array2[(i3 + 1) % array2.length].coord; - var p = geoVecSubtract(a2, origin); - var q = geoVecSubtract(b2, origin); - var scale = 2 * Math.min(geoVecLength(p), geoVecLength(q)); - p = geoVecNormalize(p); - q = geoVecNormalize(q); - var dotp2 = p[0] * q[0] + p[1] * q[1]; - var val = Math.abs(dotp2); - if (val < lowerThreshold) { - corner.i = i3; - corner.dotp = val; - var vec = geoVecNormalize(geoVecAdd(p, q)); - return geoVecScale(vec, 0.1 * dotp2 * scale); + function stepWay(entity, currPath, currRestrictions, matchedRestriction) { + var i3; + if (currPath.length >= 3) { + var turnPath = currPath.slice(); + if (matchedRestriction && matchedRestriction.direct === false) { + for (i3 = 0; i3 < turnPath.length; i3++) { + if (turnPath[i3] === matchedRestriction.from) { + turnPath = turnPath.slice(i3); + break; + } + } + } + var turn = pathToTurn(turnPath); + if (turn) { + if (matchedRestriction) { + turn.restrictionID = matchedRestriction.id; + turn.no = matchedRestriction.no; + turn.only = matchedRestriction.only; + turn.direct = matchedRestriction.direct; + } + turns.push(osmTurn(turn)); + } + if (currPath[0] === currPath[2]) + return; } - return [0, 0]; - } - }; - function nodeSubset(nodes, vertexID2, isClosed) { - var first = isClosed ? 0 : 1; - var last = isClosed ? nodes.length : nodes.length - 1; - for (var i2 = first; i2 < last; i2++) { - if (nodes[i2].id === vertexID2) { - return [ - nodes[(i2 - 1 + nodes.length) % nodes.length], - nodes[i2], - nodes[(i2 + 1) % nodes.length] - ]; + if (matchedRestriction && matchedRestriction.end) + return; + var n1 = vgraph2.entity(entity.first()); + var n2 = vgraph2.entity(entity.last()); + var dist = geoSphericalDistance(n1.loc, n2.loc); + var nextNodes = []; + if (currPath.length > 1) { + if (dist > maxDistance) + return; + if (!entity.__via) + return; } + if (!entity.__oneWay && // bidirectional.. + keyVertexIds.indexOf(n1.id) !== -1 && // key vertex.. + currPath.indexOf(n1.id) === -1) { + nextNodes.push(n1); + } + if (keyVertexIds.indexOf(n2.id) !== -1 && // key vertex.. + currPath.indexOf(n2.id) === -1) { + nextNodes.push(n2); + } + nextNodes.forEach(function(nextNode) { + var fromRestrictions = vgraph2.parentRelations(entity).filter(function(r) { + if (!r.isRestriction()) + return false; + var f2 = r.memberByRole("from"); + if (!f2 || f2.id !== entity.id) + return false; + var isOnly = /^only_/.test(r.tags.restriction); + if (!isOnly) + return true; + var isOnlyVia = false; + var v = r.membersByRole("via"); + if (v.length === 1 && v[0].type === "node") { + isOnlyVia = v[0].id === nextNode.id; + } else { + for (var i4 = 0; i4 < v.length; i4++) { + if (v[i4].type !== "way") + continue; + var viaWay = vgraph2.entity(v[i4].id); + if (viaWay.first() === nextNode.id || viaWay.last() === nextNode.id) { + isOnlyVia = true; + break; + } + } + } + return isOnlyVia; + }); + step(nextNode, currPath, currRestrictions.concat(fromRestrictions), false); + }); } - return []; - } - action.disabled = function(graph) { - var way = graph.entity(wayID); - way = way.removeNode(""); - graph = graph.replace(way); - var isClosed = way.isClosed(); - var nodes = graph.childNodes(way).slice(); - if (isClosed) - nodes.pop(); - var allowStraightAngles = false; - if (vertexID !== void 0) { - allowStraightAngles = true; - nodes = nodeSubset(nodes, vertexID, isClosed); - if (nodes.length !== 3) - return "end_vertex"; - } - var coords = nodes.map(function(n2) { - return projection2(n2.loc); - }); - var score = geoOrthoCanOrthogonalize(coords, isClosed, epsilon3, threshold, allowStraightAngles); - if (score === null) { - return "not_squarish"; - } else if (score === 0) { - return "square_enough"; - } else { - return false; + function pathToTurn(path) { + if (path.length < 3) + return; + var fromWayId2, fromNodeId, fromVertexId; + var toWayId, toNodeId, toVertexId; + var viaWayIds, viaNodeId, isUturn; + fromWayId2 = path[0]; + toWayId = path[path.length - 1]; + if (path.length === 3 && fromWayId2 === toWayId) { + var way2 = vgraph2.entity(fromWayId2); + if (way2.__oneWay) + return null; + isUturn = true; + viaNodeId = fromVertexId = toVertexId = path[1]; + fromNodeId = toNodeId = adjacentNode(fromWayId2, viaNodeId); + } else { + isUturn = false; + fromVertexId = path[1]; + fromNodeId = adjacentNode(fromWayId2, fromVertexId); + toVertexId = path[path.length - 2]; + toNodeId = adjacentNode(toWayId, toVertexId); + if (path.length === 3) { + viaNodeId = path[1]; + } else { + viaWayIds = path.filter(function(entityId) { + return entityId[0] === "w"; + }); + viaWayIds = viaWayIds.slice(1, viaWayIds.length - 1); + } + } + return { + key: path.join("_"), + path, + from: { node: fromNodeId, way: fromWayId2, vertex: fromVertexId }, + via: { node: viaNodeId, ways: viaWayIds }, + to: { node: toNodeId, way: toWayId, vertex: toVertexId }, + u: isUturn + }; + function adjacentNode(wayId, affixId) { + var nodes2 = vgraph2.entity(wayId).nodes; + return affixId === nodes2[0] ? nodes2[1] : nodes2[nodes2.length - 2]; + } } }; - action.transitionable = true; - return action; + return intersection; + } + function osmInferRestriction(graph, turn, projection2) { + var fromWay = graph.entity(turn.from.way); + var fromNode = graph.entity(turn.from.node); + var fromVertex = graph.entity(turn.from.vertex); + var toWay = graph.entity(turn.to.way); + var toNode = graph.entity(turn.to.node); + var toVertex = graph.entity(turn.to.vertex); + var fromOneWay = fromWay.tags.oneway === "yes"; + var toOneWay = toWay.tags.oneway === "yes"; + var angle2 = (geoAngle(fromVertex, fromNode, projection2) - geoAngle(toVertex, toNode, projection2)) * 180 / Math.PI; + while (angle2 < 0) { + angle2 += 360; + } + if (fromNode === toNode) { + return "no_u_turn"; + } + if ((angle2 < 23 || angle2 > 336) && fromOneWay && toOneWay) { + return "no_u_turn"; + } + if ((angle2 < 40 || angle2 > 319) && fromOneWay && toOneWay && turn.from.vertex !== turn.to.vertex) { + return "no_u_turn"; + } + if (angle2 < 158) { + return "no_right_turn"; + } + if (angle2 > 202) { + return "no_left_turn"; + } + return "no_straight_on"; } - // modules/actions/restrict_turn.js - function actionRestrictTurn(turn, restrictionType, restrictionID) { - return function(graph) { - var fromWay = graph.entity(turn.from.way); - var toWay = graph.entity(turn.to.way); - var viaNode = turn.via.node && graph.entity(turn.via.node); - var viaWays = turn.via.ways && turn.via.ways.map(function(id2) { + // modules/actions/merge_polygon.js + function actionMergePolygon(ids, newRelationId) { + function groupEntities(graph) { + var entities = ids.map(function(id2) { return graph.entity(id2); }); + var geometryGroups = utilArrayGroupBy(entities, function(entity) { + if (entity.type === "way" && entity.isClosed()) { + return "closedWay"; + } else if (entity.type === "relation" && entity.isMultipolygon()) { + return "multipolygon"; + } else { + return "other"; + } + }); + return Object.assign( + { closedWay: [], multipolygon: [], other: [] }, + geometryGroups + ); + } + var action = function(graph) { + var entities = groupEntities(graph); + var polygons = entities.multipolygon.reduce(function(polygons2, m) { + return polygons2.concat(osmJoinWays(m.members, graph)); + }, []).concat(entities.closedWay.map(function(d) { + var member = [{ id: d.id }]; + member.nodes = graph.childNodes(d); + return member; + })); + var contained = polygons.map(function(w, i2) { + return polygons.map(function(d, n2) { + if (i2 === n2) + return null; + return geoPolygonContainsPolygon( + d.nodes.map(function(n3) { + return n3.loc; + }), + w.nodes.map(function(n3) { + return n3.loc; + }) + ); + }); + }); var members = []; - members.push({ id: fromWay.id, type: "way", role: "from" }); - if (viaNode) { - members.push({ id: viaNode.id, type: "node", role: "via" }); - } else if (viaWays) { - viaWays.forEach(function(viaWay) { - members.push({ id: viaWay.id, type: "way", role: "via" }); + var outer = true; + while (polygons.length) { + extractUncontained(polygons); + polygons = polygons.filter(isContained); + contained = contained.filter(isContained).map(filterContained); + } + function isContained(d, i2) { + return contained[i2].some(function(val) { + return val; }); } - members.push({ id: toWay.id, type: "way", role: "to" }); - return graph.replace(osmRelation({ - id: restrictionID, - tags: { - type: "restriction", - restriction: restrictionType - }, - members - })); - }; - } - - // modules/actions/revert.js - function actionRevert(id2) { - var action = function(graph) { - var entity = graph.hasEntity(id2), base = graph.base().entities[id2]; - if (entity && !base) { - if (entity.type === "node") { - graph.parentWays(entity).forEach(function(parent) { - parent = parent.removeNode(id2); - graph = graph.replace(parent); - if (parent.isDegenerate()) { - graph = actionDeleteWay(parent.id)(graph); - } - }); - } - graph.parentRelations(entity).forEach(function(parent) { - parent = parent.removeMembersWithID(id2); - graph = graph.replace(parent); - if (parent.isDegenerate()) { - graph = actionDeleteRelation(parent.id)(graph); + function filterContained(d) { + return d.filter(isContained); + } + function extractUncontained(polygons2) { + polygons2.forEach(function(d, i2) { + if (!isContained(d, i2)) { + d.forEach(function(member) { + members.push({ + type: "way", + id: member.id, + role: outer ? "outer" : "inner" + }); + }); } }); + outer = !outer; } - return graph.revert(id2); - }; - return action; - } - - // modules/actions/rotate.js - function actionRotate(rotateIds, pivot, angle2, projection2) { - var action = function(graph) { - return graph.update(function(graph2) { - utilGetAllNodes(rotateIds, graph2).forEach(function(node) { - var point = geoRotate([projection2(node.loc)], angle2, pivot)[0]; - graph2 = graph2.replace(node.move(projection2.invert(point))); - }); - }); - }; - return action; - } - - // modules/actions/scale.js - function actionScale(ids, pivotLoc, scaleFactor, projection2) { - return function(graph) { - return graph.update(function(graph2) { - let point, radial; - utilGetAllNodes(ids, graph2).forEach(function(node) { - point = projection2(node.loc); - radial = [ - point[0] - pivotLoc[0], - point[1] - pivotLoc[1] - ]; - point = [ - pivotLoc[0] + scaleFactor * radial[0], - pivotLoc[1] + scaleFactor * radial[1] - ]; - graph2 = graph2.replace(node.move(projection2.invert(point))); - }); - }); - }; - } - - // modules/actions/straighten_nodes.js - function actionStraightenNodes(nodeIDs, projection2) { - function positionAlongWay(a, o, b) { - return geoVecDot(a, b, o) / geoVecDot(b, b, o); - } - function getEndpoints(points) { - var ssr = geoGetSmallestSurroundingRectangle(points); - var p1 = [(ssr.poly[0][0] + ssr.poly[1][0]) / 2, (ssr.poly[0][1] + ssr.poly[1][1]) / 2]; - var q1 = [(ssr.poly[2][0] + ssr.poly[3][0]) / 2, (ssr.poly[2][1] + ssr.poly[3][1]) / 2]; - var p2 = [(ssr.poly[3][0] + ssr.poly[4][0]) / 2, (ssr.poly[3][1] + ssr.poly[4][1]) / 2]; - var q2 = [(ssr.poly[1][0] + ssr.poly[2][0]) / 2, (ssr.poly[1][1] + ssr.poly[2][1]) / 2]; - var isLong = geoVecLength(p1, q1) > geoVecLength(p2, q2); - if (isLong) { - return [p1, q1]; - } - return [p2, q2]; - } - var action = function(graph, t) { - if (t === null || !isFinite(t)) - t = 1; - t = Math.min(Math.max(+t, 0), 1); - var nodes = nodeIDs.map(function(id2) { - return graph.entity(id2); - }); - var points = nodes.map(function(n2) { - return projection2(n2.loc); - }); - var endpoints = getEndpoints(points); - var startPoint = endpoints[0]; - var endPoint = endpoints[1]; - for (var i2 = 0; i2 < points.length; i2++) { - var node = nodes[i2]; - var point = points[i2]; - var u = positionAlongWay(point, startPoint, endPoint); - var point2 = geoVecInterp(startPoint, endPoint, u); - var loc2 = projection2.invert(point2); - graph = graph.replace(node.move(geoVecInterp(node.loc, loc2, t))); + var relation; + if (entities.multipolygon.length > 0) { + var oldestID = utilOldestID(entities.multipolygon.map((entity) => entity.id)); + relation = entities.multipolygon.find((entity) => entity.id === oldestID); + } else { + relation = osmRelation({ id: newRelationId, tags: { type: "multipolygon" } }); } - return graph; - }; - action.disabled = function(graph) { - var nodes = nodeIDs.map(function(id2) { - return graph.entity(id2); - }); - var points = nodes.map(function(n2) { - return projection2(n2.loc); - }); - var endpoints = getEndpoints(points); - var startPoint = endpoints[0]; - var endPoint = endpoints[1]; - var maxDistance = 0; - for (var i2 = 0; i2 < points.length; i2++) { - var point = points[i2]; - var u = positionAlongWay(point, startPoint, endPoint); - var p = geoVecInterp(startPoint, endPoint, u); - var dist = geoVecLength(p, point); - if (!isNaN(dist) && dist > maxDistance) { - maxDistance = dist; + entities.multipolygon.forEach(function(m) { + if (m.id !== relation.id) { + relation = relation.mergeTags(m.tags); + graph = graph.remove(m); } - } - if (maxDistance < 1e-4) { - return "straight_enough"; - } - }; - action.transitionable = true; - return action; - } - - // modules/actions/straighten_way.js - function actionStraightenWay(selectedIDs, projection2) { - function positionAlongWay(a, o, b) { - return geoVecDot(a, b, o) / geoVecDot(b, b, o); - } - function allNodes(graph) { - var nodes = []; - var startNodes = []; - var endNodes = []; - var remainingWays = []; - var selectedWays = selectedIDs.filter(function(w) { - return graph.entity(w).type === "way"; - }); - var selectedNodes = selectedIDs.filter(function(n2) { - return graph.entity(n2).type === "node"; - }); - for (var i2 = 0; i2 < selectedWays.length; i2++) { - var way = graph.entity(selectedWays[i2]); - nodes = way.nodes.slice(0); - remainingWays.push(nodes); - startNodes.push(nodes[0]); - endNodes.push(nodes[nodes.length - 1]); - } - startNodes = startNodes.filter(function(n2) { - return startNodes.indexOf(n2) === startNodes.lastIndexOf(n2); }); - endNodes = endNodes.filter(function(n2) { - return endNodes.indexOf(n2) === endNodes.lastIndexOf(n2); - }); - var currNode = utilArrayDifference(startNodes, endNodes).concat(utilArrayDifference(endNodes, startNodes))[0]; - var nextWay = []; - nodes = []; - var getNextWay = function(currNode2, remainingWays2) { - return remainingWays2.filter(function(way2) { - return way2[0] === currNode2 || way2[way2.length - 1] === currNode2; - })[0]; - }; - while (remainingWays.length) { - nextWay = getNextWay(currNode, remainingWays); - remainingWays = utilArrayDifference(remainingWays, [nextWay]); - if (nextWay[0] !== currNode) { - nextWay.reverse(); + entities.closedWay.forEach(function(way) { + function isThisOuter(m) { + return m.id === way.id && m.role !== "inner"; } - nodes = nodes.concat(nextWay); - currNode = nodes[nodes.length - 1]; - } - if (selectedNodes.length === 2) { - var startNodeIdx = nodes.indexOf(selectedNodes[0]); - var endNodeIdx = nodes.indexOf(selectedNodes[1]); - var sortedStartEnd = [startNodeIdx, endNodeIdx]; - sortedStartEnd.sort(function(a, b) { - return a - b; - }); - nodes = nodes.slice(sortedStartEnd[0], sortedStartEnd[1] + 1); - } - return nodes.map(function(n2) { - return graph.entity(n2); - }); - } - function shouldKeepNode(node, graph) { - return graph.parentWays(node).length > 1 || graph.parentRelations(node).length || node.hasInterestingTags(); - } - var action = function(graph, t) { - if (t === null || !isFinite(t)) - t = 1; - t = Math.min(Math.max(+t, 0), 1); - var nodes = allNodes(graph); - var points = nodes.map(function(n2) { - return projection2(n2.loc); - }); - var startPoint = points[0]; - var endPoint = points[points.length - 1]; - var toDelete = []; - var i2; - for (i2 = 1; i2 < points.length - 1; i2++) { - var node = nodes[i2]; - var point = points[i2]; - if (t < 1 || shouldKeepNode(node, graph)) { - var u = positionAlongWay(point, startPoint, endPoint); - var p = geoVecInterp(startPoint, endPoint, u); - var loc2 = projection2.invert(p); - graph = graph.replace(node.move(geoVecInterp(node.loc, loc2, t))); - } else { - if (toDelete.indexOf(node) === -1) { - toDelete.push(node); - } + if (members.some(isThisOuter)) { + relation = relation.mergeTags(way.tags); + graph = graph.replace(way.update({ tags: {} })); } - } - for (i2 = 0; i2 < toDelete.length; i2++) { - graph = actionDeleteNode(toDelete[i2].id)(graph); - } - return graph; + }); + return graph.replace(relation.update({ + members, + tags: utilObjectOmit(relation.tags, ["area"]) + })); }; action.disabled = function(graph) { - var nodes = allNodes(graph); - var points = nodes.map(function(n2) { - return projection2(n2.loc); - }); - var startPoint = points[0]; - var endPoint = points[points.length - 1]; - var threshold = 0.2 * geoVecLength(startPoint, endPoint); - var i2; - if (threshold === 0) { - return "too_bendy"; + var entities = groupEntities(graph); + if (entities.other.length > 0 || entities.closedWay.length + entities.multipolygon.length < 2) { + return "not_eligible"; } - var maxDistance = 0; - for (i2 = 1; i2 < points.length - 1; i2++) { - var point = points[i2]; - var u = positionAlongWay(point, startPoint, endPoint); - var p = geoVecInterp(startPoint, endPoint, u); - var dist = geoVecLength(p, point); - if (isNaN(dist) || dist > threshold) { - return "too_bendy"; - } else if (dist > maxDistance) { - maxDistance = dist; - } + if (!entities.multipolygon.every(function(r) { + return r.isComplete(graph); + })) { + return "incomplete_relation"; } - var keepingAllNodes = nodes.every(function(node, i3) { - return i3 === 0 || i3 === nodes.length - 1 || shouldKeepNode(node, graph); - }); - if (maxDistance < 1e-4 && keepingAllNodes) { - return "straight_enough"; + if (!entities.multipolygon.length) { + var sharedMultipolygons = []; + entities.closedWay.forEach(function(way, i2) { + if (i2 === 0) { + sharedMultipolygons = graph.parentMultipolygons(way); + } else { + sharedMultipolygons = utilArrayIntersection(sharedMultipolygons, graph.parentMultipolygons(way)); + } + }); + sharedMultipolygons = sharedMultipolygons.filter(function(relation) { + return relation.members.length === entities.closedWay.length; + }); + if (sharedMultipolygons.length) { + return "not_eligible"; + } + } else if (entities.closedWay.some(function(way) { + return utilArrayIntersection(graph.parentMultipolygons(way), entities.multipolygon).length; + })) { + return "not_eligible"; } }; - action.transitionable = true; return action; } - // modules/actions/unrestrict_turn.js - function actionUnrestrictTurn(turn) { - return function(graph) { - return actionDeleteRelation(turn.restrictionID)(graph); - }; - } + // modules/actions/merge_remote_changes.js + var import_fast_deep_equal = __toESM(require_fast_deep_equal()); - // modules/actions/reflect.js - function actionReflect(reflectIds, projection2) { - var _useLongAxis = true; - var action = function(graph, t) { - if (t === null || !isFinite(t)) - t = 1; - t = Math.min(Math.max(+t, 0), 1); - var nodes = utilGetAllNodes(reflectIds, graph); - var points = nodes.map(function(n2) { - return projection2(n2.loc); - }); - var ssr = geoGetSmallestSurroundingRectangle(points); - var p1 = [(ssr.poly[0][0] + ssr.poly[1][0]) / 2, (ssr.poly[0][1] + ssr.poly[1][1]) / 2]; - var q1 = [(ssr.poly[2][0] + ssr.poly[3][0]) / 2, (ssr.poly[2][1] + ssr.poly[3][1]) / 2]; - var p2 = [(ssr.poly[3][0] + ssr.poly[4][0]) / 2, (ssr.poly[3][1] + ssr.poly[4][1]) / 2]; - var q2 = [(ssr.poly[1][0] + ssr.poly[2][0]) / 2, (ssr.poly[1][1] + ssr.poly[2][1]) / 2]; - var p, q; - var isLong = geoVecLength(p1, q1) > geoVecLength(p2, q2); - if (_useLongAxis && isLong || !_useLongAxis && !isLong) { - p = p1; - q = q1; + // node_modules/node-diff3/index.mjs + function LCS(buffer1, buffer2) { + let equivalenceClasses = {}; + for (let j2 = 0; j2 < buffer2.length; j2++) { + const item = buffer2[j2]; + if (equivalenceClasses[item]) { + equivalenceClasses[item].push(j2); } else { - p = p2; - q = q2; - } - var dx = q[0] - p[0]; - var dy = q[1] - p[1]; - var a = (dx * dx - dy * dy) / (dx * dx + dy * dy); - var b = 2 * dx * dy / (dx * dx + dy * dy); - for (var i2 = 0; i2 < nodes.length; i2++) { - var node = nodes[i2]; - var c = projection2(node.loc); - var c2 = [ - a * (c[0] - p[0]) + b * (c[1] - p[1]) + p[0], - b * (c[0] - p[0]) - a * (c[1] - p[1]) + p[1] - ]; - var loc2 = projection2.invert(c2); - node = node.move(geoVecInterp(node.loc, loc2, t)); - graph = graph.replace(node); + equivalenceClasses[item] = [j2]; } - return graph; - }; - action.useLongAxis = function(val) { - if (!arguments.length) - return _useLongAxis; - _useLongAxis = val; - return action; - }; - action.transitionable = true; - return action; - } - - // modules/actions/upgrade_tags.js - function actionUpgradeTags(entityId, oldTags, replaceTags) { - return function(graph) { - var entity = graph.entity(entityId); - var tags = Object.assign({}, entity.tags); - var transferValue; - var semiIndex; - for (var oldTagKey in oldTags) { - if (!(oldTagKey in tags)) - continue; - if (oldTags[oldTagKey] === "*") { - transferValue = tags[oldTagKey]; - delete tags[oldTagKey]; - } else if (oldTags[oldTagKey] === tags[oldTagKey]) { - delete tags[oldTagKey]; - } else { - var vals = tags[oldTagKey].split(";").filter(Boolean); - var oldIndex = vals.indexOf(oldTags[oldTagKey]); - if (vals.length === 1 || oldIndex === -1) { - delete tags[oldTagKey]; - } else { - if (replaceTags && replaceTags[oldTagKey]) { - semiIndex = oldIndex; - } - vals.splice(oldIndex, 1); - tags[oldTagKey] = vals.join(";"); + } + const NULLRESULT = { buffer1index: -1, buffer2index: -1, chain: null }; + let candidates = [NULLRESULT]; + for (let i2 = 0; i2 < buffer1.length; i2++) { + const item = buffer1[i2]; + const buffer2indices = equivalenceClasses[item] || []; + let r = 0; + let c = candidates[0]; + for (let jx = 0; jx < buffer2indices.length; jx++) { + const j2 = buffer2indices[jx]; + let s; + for (s = r; s < candidates.length; s++) { + if (candidates[s].buffer2index < j2 && (s === candidates.length - 1 || candidates[s + 1].buffer2index > j2)) { + break; } } - } - if (replaceTags) { - for (var replaceKey in replaceTags) { - var replaceValue = replaceTags[replaceKey]; - if (replaceValue === "*") { - if (tags[replaceKey] && tags[replaceKey] !== "no") { - continue; - } else { - tags[replaceKey] = "yes"; - } - } else if (replaceValue === "$1") { - tags[replaceKey] = transferValue; + if (s < candidates.length) { + const newCandidate = { buffer1index: i2, buffer2index: j2, chain: candidates[s] }; + if (r === candidates.length) { + candidates.push(c); } else { - if (tags[replaceKey] && oldTags[replaceKey] && semiIndex !== void 0) { - var existingVals = tags[replaceKey].split(";").filter(Boolean); - if (existingVals.indexOf(replaceValue) === -1) { - existingVals.splice(semiIndex, 0, replaceValue); - tags[replaceKey] = existingVals.join(";"); - } - } else { - tags[replaceKey] = replaceValue; - } + candidates[r] = c; + } + r = s + 1; + c = newCandidate; + if (r === candidates.length) { + break; } } } - return graph.replace(entity.update({ tags })); - }; - } - - // modules/behavior/edit.js - function behaviorEdit(context) { - function behavior() { - context.map().minzoom(context.minEditableZoom()); + candidates[r] = c; } - behavior.off = function() { - context.map().minzoom(0); - }; - return behavior; + return candidates[candidates.length - 1]; } - - // modules/behavior/hover.js - function behaviorHover(context) { - var dispatch10 = dispatch_default("hover"); - var _selection = select_default2(null); - var _newNodeId = null; - var _initialNodeID = null; - var _altDisables; - var _ignoreVertex; - var _targets = []; - var _pointerPrefix = "PointerEvent" in window ? "pointer" : "mouse"; - function keydown(d3_event) { - if (_altDisables && d3_event.keyCode === utilKeybinding.modifierCodes.alt) { - _selection.selectAll(".hover").classed("hover-suppressed", true).classed("hover", false); - _selection.classed("hover-disabled", true); - dispatch10.call("hover", this, null); + function diffIndices(buffer1, buffer2) { + const lcs = LCS(buffer1, buffer2); + let result = []; + let tail1 = buffer1.length; + let tail2 = buffer2.length; + for (let candidate = lcs; candidate !== null; candidate = candidate.chain) { + const mismatchLength1 = tail1 - candidate.buffer1index - 1; + const mismatchLength2 = tail2 - candidate.buffer2index - 1; + tail1 = candidate.buffer1index; + tail2 = candidate.buffer2index; + if (mismatchLength1 || mismatchLength2) { + result.push({ + buffer1: [tail1 + 1, mismatchLength1], + buffer1Content: buffer1.slice(tail1 + 1, tail1 + 1 + mismatchLength1), + buffer2: [tail2 + 1, mismatchLength2], + buffer2Content: buffer2.slice(tail2 + 1, tail2 + 1 + mismatchLength2) + }); } } - function keyup(d3_event) { - if (_altDisables && d3_event.keyCode === utilKeybinding.modifierCodes.alt) { - _selection.selectAll(".hover-suppressed").classed("hover-suppressed", false).classed("hover", true); - _selection.classed("hover-disabled", false); - dispatch10.call("hover", this, _targets); + result.reverse(); + return result; + } + function diff3MergeRegions(a, o, b) { + let hunks = []; + function addHunk(h, ab) { + hunks.push({ + ab, + oStart: h.buffer1[0], + oLength: h.buffer1[1], + // length of o to remove + abStart: h.buffer2[0], + abLength: h.buffer2[1] + // length of a/b to insert + // abContent: (ab === 'a' ? a : b).slice(h.buffer2[0], h.buffer2[0] + h.buffer2[1]) + }); + } + diffIndices(o, a).forEach((item) => addHunk(item, "a")); + diffIndices(o, b).forEach((item) => addHunk(item, "b")); + hunks.sort((x, y) => x.oStart - y.oStart); + let results = []; + let currOffset = 0; + function advanceTo(endOffset) { + if (endOffset > currOffset) { + results.push({ + stable: true, + buffer: "o", + bufferStart: currOffset, + bufferLength: endOffset - currOffset, + bufferContent: o.slice(currOffset, endOffset) + }); + currOffset = endOffset; } } - function behavior(selection2) { - _selection = selection2; - _targets = []; - if (_initialNodeID) { - _newNodeId = _initialNodeID; - _initialNodeID = null; - } else { - _newNodeId = null; + while (hunks.length) { + let hunk = hunks.shift(); + let regionStart = hunk.oStart; + let regionEnd = hunk.oStart + hunk.oLength; + let regionHunks = [hunk]; + advanceTo(regionStart); + while (hunks.length) { + const nextHunk = hunks[0]; + const nextHunkStart = nextHunk.oStart; + if (nextHunkStart > regionEnd) + break; + regionEnd = Math.max(regionEnd, nextHunkStart + nextHunk.oLength); + regionHunks.push(hunks.shift()); } - _selection.on(_pointerPrefix + "over.hover", pointerover).on(_pointerPrefix + "out.hover", pointerout).on(_pointerPrefix + "down.hover", pointerover); - select_default2(window).on(_pointerPrefix + "up.hover pointercancel.hover", pointerout, true).on("keydown.hover", keydown).on("keyup.hover", keyup); - function eventTarget(d3_event) { - var datum2 = d3_event.target && d3_event.target.__data__; - if (typeof datum2 !== "object") - return null; - if (!(datum2 instanceof osmEntity) && datum2.properties && datum2.properties.entity instanceof osmEntity) { - return datum2.properties.entity; + if (regionHunks.length === 1) { + if (hunk.abLength > 0) { + const buffer = hunk.ab === "a" ? a : b; + results.push({ + stable: true, + buffer: hunk.ab, + bufferStart: hunk.abStart, + bufferLength: hunk.abLength, + bufferContent: buffer.slice(hunk.abStart, hunk.abStart + hunk.abLength) + }); } - return datum2; - } - function pointerover(d3_event) { - if (context.mode().id.indexOf("drag") === -1 && (!d3_event.pointerType || d3_event.pointerType === "mouse") && d3_event.buttons) - return; - var target = eventTarget(d3_event); - if (target && _targets.indexOf(target) === -1) { - _targets.push(target); - updateHover(d3_event, _targets); - } - } - function pointerout(d3_event) { - var target = eventTarget(d3_event); - var index = _targets.indexOf(target); - if (index !== -1) { - _targets.splice(index); - updateHover(d3_event, _targets); + } else { + let bounds = { + a: [a.length, -1, o.length, -1], + b: [b.length, -1, o.length, -1] + }; + while (regionHunks.length) { + hunk = regionHunks.shift(); + const oStart = hunk.oStart; + const oEnd = oStart + hunk.oLength; + const abStart = hunk.abStart; + const abEnd = abStart + hunk.abLength; + let b2 = bounds[hunk.ab]; + b2[0] = Math.min(abStart, b2[0]); + b2[1] = Math.max(abEnd, b2[1]); + b2[2] = Math.min(oStart, b2[2]); + b2[3] = Math.max(oEnd, b2[3]); } + const aStart = bounds.a[0] + (regionStart - bounds.a[2]); + const aEnd = bounds.a[1] + (regionEnd - bounds.a[3]); + const bStart = bounds.b[0] + (regionStart - bounds.b[2]); + const bEnd = bounds.b[1] + (regionEnd - bounds.b[3]); + let result = { + stable: false, + aStart, + aLength: aEnd - aStart, + aContent: a.slice(aStart, aEnd), + oStart: regionStart, + oLength: regionEnd - regionStart, + oContent: o.slice(regionStart, regionEnd), + bStart, + bLength: bEnd - bStart, + bContent: b.slice(bStart, bEnd) + }; + results.push(result); } - function allowsVertex(d) { - return d.geometry(context.graph()) === "vertex" || _mainPresetIndex.allowsVertex(d, context.graph()); + currOffset = regionEnd; + } + advanceTo(o.length); + return results; + } + function diff3Merge(a, o, b, options2) { + let defaults2 = { + excludeFalseConflicts: true, + stringSeparator: /\s+/ + }; + options2 = Object.assign(defaults2, options2); + if (typeof a === "string") + a = a.split(options2.stringSeparator); + if (typeof o === "string") + o = o.split(options2.stringSeparator); + if (typeof b === "string") + b = b.split(options2.stringSeparator); + let results = []; + const regions = diff3MergeRegions(a, o, b); + let okBuffer = []; + function flushOk() { + if (okBuffer.length) { + results.push({ ok: okBuffer }); } - function modeAllowsHover(target) { - var mode = context.mode(); - if (mode.id === "add-point") { - return mode.preset.matchGeometry("vertex") || target.type !== "way" && target.geometry(context.graph()) !== "vertex"; - } - return true; + okBuffer = []; + } + function isFalseConflict(a2, b2) { + if (a2.length !== b2.length) + return false; + for (let i2 = 0; i2 < a2.length; i2++) { + if (a2[i2] !== b2[i2]) + return false; } - function updateHover(d3_event, targets) { - _selection.selectAll(".hover").classed("hover", false); - _selection.selectAll(".hover-suppressed").classed("hover-suppressed", false); - var mode = context.mode(); - if (!_newNodeId && (mode.id === "draw-line" || mode.id === "draw-area")) { - var node = targets.find(function(target) { - return target instanceof osmEntity && target.type === "node"; - }); - _newNodeId = node && node.id; - } - targets = targets.filter(function(datum3) { - if (datum3 instanceof osmEntity) { - return datum3.id !== _newNodeId && (datum3.type !== "node" || !_ignoreVertex || allowsVertex(datum3)) && modeAllowsHover(datum3); - } - return true; - }); - var selector = ""; - for (var i2 in targets) { - var datum2 = targets[i2]; - if (datum2.__featurehash__) { - selector += ", .data" + datum2.__featurehash__; - } else if (datum2 instanceof QAItem) { - selector += ", ." + datum2.service + ".itemId-" + datum2.id; - } else if (datum2 instanceof osmNote) { - selector += ", .note-" + datum2.id; - } else if (datum2 instanceof osmEntity) { - selector += ", ." + datum2.id; - if (datum2.type === "relation") { - for (var j2 in datum2.members) { - selector += ", ." + datum2.members[j2].id; - } + return true; + } + regions.forEach((region) => { + if (region.stable) { + okBuffer.push(...region.bufferContent); + } else { + if (options2.excludeFalseConflicts && isFalseConflict(region.aContent, region.bContent)) { + okBuffer.push(...region.aContent); + } else { + flushOk(); + results.push({ + conflict: { + a: region.aContent, + aIndex: region.aStart, + o: region.oContent, + oIndex: region.oStart, + b: region.bContent, + bIndex: region.bStart } - } - } - var suppressed = _altDisables && d3_event && d3_event.altKey; - if (selector.trim().length) { - selector = selector.slice(1); - _selection.selectAll(selector).classed(suppressed ? "hover-suppressed" : "hover", true); + }); } - dispatch10.call("hover", this, !suppressed && targets); } - } - behavior.off = function(selection2) { - selection2.selectAll(".hover").classed("hover", false); - selection2.selectAll(".hover-suppressed").classed("hover-suppressed", false); - selection2.classed("hover-disabled", false); - selection2.on(_pointerPrefix + "over.hover", null).on(_pointerPrefix + "out.hover", null).on(_pointerPrefix + "down.hover", null); - select_default2(window).on(_pointerPrefix + "up.hover pointercancel.hover", null, true).on("keydown.hover", null).on("keyup.hover", null); - }; - behavior.altDisables = function(val) { - if (!arguments.length) - return _altDisables; - _altDisables = val; - return behavior; - }; - behavior.ignoreVertex = function(val) { - if (!arguments.length) - return _ignoreVertex; - _ignoreVertex = val; - return behavior; - }; - behavior.initialNodeID = function(nodeId) { - _initialNodeID = nodeId; - return behavior; - }; - return utilRebind(behavior, dispatch10, "on"); + }); + flushOk(); + return results; } - // modules/behavior/draw.js - var _disableSpace = false; - var _lastSpace = null; - function behaviorDraw(context) { - var dispatch10 = dispatch_default( - "move", - "down", - "downcancel", - "click", - "clickWay", - "clickNode", - "undo", - "cancel", - "finish" - ); - var keybinding = utilKeybinding("draw"); - var _hover = behaviorHover(context).altDisables(true).ignoreVertex(true).on("hover", context.ui().sidebar.hover); - var _edit = behaviorEdit(context); - var _closeTolerance = 4; - var _tolerance = 12; - var _mouseLeave = false; - var _lastMouse = null; - var _lastPointerUpEvent; - var _downPointer; - var _pointerPrefix = "PointerEvent" in window ? "pointer" : "mouse"; - function datum2(d3_event) { - var mode = context.mode(); - var isNote = mode && mode.id.indexOf("note") !== -1; - if (d3_event.altKey || isNote) - return {}; - var element; - if (d3_event.type === "keydown") { - element = _lastMouse && _lastMouse.target; - } else { - element = d3_event.target; - } - var d = element.__data__; - return d && d.properties && d.properties.target ? d : {}; - } - function pointerdown(d3_event) { - if (_downPointer) - return; - var pointerLocGetter = utilFastMouse(this); - _downPointer = { - id: d3_event.pointerId || "mouse", - pointerLocGetter, - downTime: +new Date(), - downLoc: pointerLocGetter(d3_event) - }; - dispatch10.call("down", this, d3_event, datum2(d3_event)); + // modules/actions/merge_remote_changes.js + var import_lodash2 = __toESM(require_lodash()); + function actionMergeRemoteChanges(id2, localGraph, remoteGraph, discardTags, formatUser) { + discardTags = discardTags || {}; + var _option = "safe"; + var _conflicts = []; + function user(d) { + return typeof formatUser === "function" ? formatUser(d) : (0, import_lodash2.escape)(d); } - function pointerup(d3_event) { - if (!_downPointer || _downPointer.id !== (d3_event.pointerId || "mouse")) - return; - var downPointer = _downPointer; - _downPointer = null; - _lastPointerUpEvent = d3_event; - if (downPointer.isCancelled) - return; - var t2 = +new Date(); - var p2 = downPointer.pointerLocGetter(d3_event); - var dist = geoVecLength(downPointer.downLoc, p2); - if (dist < _closeTolerance || dist < _tolerance && t2 - downPointer.downTime < 500) { - select_default2(window).on("click.draw-block", function() { - d3_event.stopPropagation(); - }, true); - context.map().dblclickZoomEnable(false); - window.setTimeout(function() { - context.map().dblclickZoomEnable(true); - select_default2(window).on("click.draw-block", null); - }, 500); - click(d3_event, p2); + function mergeLocation(remote, target) { + function pointEqual(a, b) { + var epsilon3 = 1e-6; + return Math.abs(a[0] - b[0]) < epsilon3 && Math.abs(a[1] - b[1]) < epsilon3; + } + if (_option === "force_local" || pointEqual(target.loc, remote.loc)) { + return target; } + if (_option === "force_remote") { + return target.update({ loc: remote.loc }); + } + _conflicts.push(_t.html("merge_remote_changes.conflict.location", { user: { html: user(remote.user) } })); + return target; } - function pointermove(d3_event) { - if (_downPointer && _downPointer.id === (d3_event.pointerId || "mouse") && !_downPointer.isCancelled) { - var p2 = _downPointer.pointerLocGetter(d3_event); - var dist = geoVecLength(_downPointer.downLoc, p2); - if (dist >= _closeTolerance) { - _downPointer.isCancelled = true; - dispatch10.call("downcancel", this); + function mergeNodes(base, remote, target) { + if (_option === "force_local" || (0, import_fast_deep_equal.default)(target.nodes, remote.nodes)) { + return target; + } + if (_option === "force_remote") { + return target.update({ nodes: remote.nodes }); + } + var ccount = _conflicts.length; + var o = base.nodes || []; + var a = target.nodes || []; + var b = remote.nodes || []; + var nodes = []; + var hunks = diff3Merge(a, o, b, { excludeFalseConflicts: true }); + for (var i2 = 0; i2 < hunks.length; i2++) { + var hunk = hunks[i2]; + if (hunk.ok) { + nodes.push.apply(nodes, hunk.ok); + } else { + var c = hunk.conflict; + if ((0, import_fast_deep_equal.default)(c.o, c.a)) { + nodes.push.apply(nodes, c.b); + } else if ((0, import_fast_deep_equal.default)(c.o, c.b)) { + nodes.push.apply(nodes, c.a); + } else { + _conflicts.push(_t.html("merge_remote_changes.conflict.nodelist", { user: { html: user(remote.user) } })); + break; + } } } - if (d3_event.pointerType && d3_event.pointerType !== "mouse" || d3_event.buttons || _downPointer) - return; - if (_lastPointerUpEvent && _lastPointerUpEvent.pointerType !== "mouse" && d3_event.timeStamp - _lastPointerUpEvent.timeStamp < 100) - return; - _lastMouse = d3_event; - dispatch10.call("move", this, d3_event, datum2(d3_event)); + return _conflicts.length === ccount ? target.update({ nodes }) : target; } - function pointercancel(d3_event) { - if (_downPointer && _downPointer.id === (d3_event.pointerId || "mouse")) { - if (!_downPointer.isCancelled) { - dispatch10.call("downcancel", this); + function mergeChildren(targetWay, children2, updates, graph) { + function isUsed(node2, targetWay2) { + var hasInterestingParent = graph.parentWays(node2).some(function(way) { + return way.id !== targetWay2.id; + }); + return node2.hasInterestingTags() || hasInterestingParent || graph.parentRelations(node2).length > 0; + } + var ccount = _conflicts.length; + for (var i2 = 0; i2 < children2.length; i2++) { + var id3 = children2[i2]; + var node = graph.hasEntity(id3); + if (targetWay.nodes.indexOf(id3) === -1) { + if (node && !isUsed(node, targetWay)) { + updates.removeIds.push(id3); + } + continue; + } + var local = localGraph.hasEntity(id3); + var remote = remoteGraph.hasEntity(id3); + var target; + if (_option === "force_remote" && remote && remote.visible) { + updates.replacements.push(remote); + } else if (_option === "force_local" && local) { + target = osmEntity(local); + if (remote) { + target = target.update({ version: remote.version }); + } + updates.replacements.push(target); + } else if (_option === "safe" && local && remote && local.version !== remote.version) { + target = osmEntity(local, { version: remote.version }); + if (remote.visible) { + target = mergeLocation(remote, target); + } else { + _conflicts.push(_t.html("merge_remote_changes.conflict.deleted", { user: { html: user(remote.user) } })); + } + if (_conflicts.length !== ccount) + break; + updates.replacements.push(target); } - _downPointer = null; } + return targetWay; } - function mouseenter() { - _mouseLeave = false; - } - function mouseleave() { - _mouseLeave = true; + function updateChildren(updates, graph) { + for (var i2 = 0; i2 < updates.replacements.length; i2++) { + graph = graph.replace(updates.replacements[i2]); + } + if (updates.removeIds.length) { + graph = actionDeleteMultiple(updates.removeIds)(graph); + } + return graph; } - function allowsVertex(d) { - return d.geometry(context.graph()) === "vertex" || _mainPresetIndex.allowsVertex(d, context.graph()); + function mergeMembers(remote, target) { + if (_option === "force_local" || (0, import_fast_deep_equal.default)(target.members, remote.members)) { + return target; + } + if (_option === "force_remote") { + return target.update({ members: remote.members }); + } + _conflicts.push(_t.html("merge_remote_changes.conflict.memberlist", { user: { html: user(remote.user) } })); + return target; } - function click(d3_event, loc) { - var d = datum2(d3_event); - var target = d && d.properties && d.properties.entity; - var mode = context.mode(); - if (target && target.type === "node" && allowsVertex(target)) { - dispatch10.call("clickNode", this, target, d); - return; - } else if (target && target.type === "way" && (mode.id !== "add-point" || mode.preset.matchGeometry("vertex"))) { - var choice = geoChooseEdge( - context.graph().childNodes(target), - loc, - context.projection, - context.activeID() - ); - if (choice) { - var edge = [target.nodes[choice.index - 1], target.nodes[choice.index]]; - dispatch10.call("clickWay", this, choice.loc, edge, d); - return; + function mergeTags(base, remote, target) { + if (_option === "force_local" || (0, import_fast_deep_equal.default)(target.tags, remote.tags)) { + return target; + } + if (_option === "force_remote") { + return target.update({ tags: remote.tags }); + } + var ccount = _conflicts.length; + var o = base.tags || {}; + var a = target.tags || {}; + var b = remote.tags || {}; + var keys2 = utilArrayUnion(utilArrayUnion(Object.keys(o), Object.keys(a)), Object.keys(b)).filter(function(k2) { + return !discardTags[k2]; + }); + var tags = Object.assign({}, a); + var changed = false; + for (var i2 = 0; i2 < keys2.length; i2++) { + var k = keys2[i2]; + if (o[k] !== b[k] && a[k] !== b[k]) { + if (o[k] !== a[k]) { + _conflicts.push(_t.html( + "merge_remote_changes.conflict.tags", + { tag: k, local: a[k], remote: b[k], user: { html: user(remote.user) } } + )); + } else { + if (b.hasOwnProperty(k)) { + tags[k] = b[k]; + } else { + delete tags[k]; + } + changed = true; + } } - } else if (mode.id !== "add-point" || mode.preset.matchGeometry("point")) { - var locLatLng = context.projection.invert(loc); - dispatch10.call("click", this, locLatLng, d); } + return changed && _conflicts.length === ccount ? target.update({ tags }) : target; } - function space(d3_event) { - d3_event.preventDefault(); - d3_event.stopPropagation(); - var currSpace = context.map().mouse(); - if (_disableSpace && _lastSpace) { - var dist = geoVecLength(_lastSpace, currSpace); - if (dist > _tolerance) { - _disableSpace = false; + var action = function(graph) { + var updates = { replacements: [], removeIds: [] }; + var base = graph.base().entities[id2]; + var local = localGraph.entity(id2); + var remote = remoteGraph.entity(id2); + var target = osmEntity(local, { version: remote.version }); + if (!remote.visible) { + if (_option === "force_remote") { + return actionDeleteMultiple([id2])(graph); + } else if (_option === "force_local") { + if (target.type === "way") { + target = mergeChildren(target, utilArrayUniq(local.nodes), updates, graph); + graph = updateChildren(updates, graph); + } + return graph.replace(target); + } else { + _conflicts.push(_t.html("merge_remote_changes.conflict.deleted", { user: { html: user(remote.user) } })); + return graph; } } - if (_disableSpace || _mouseLeave || !_lastMouse) - return; - _lastSpace = currSpace; - _disableSpace = true; - select_default2(window).on("keyup.space-block", function() { - d3_event.preventDefault(); - d3_event.stopPropagation(); - _disableSpace = false; - select_default2(window).on("keyup.space-block", null); - }); - var loc = context.map().mouse() || context.projection(context.map().center()); - click(d3_event, loc); - } - function backspace(d3_event) { - d3_event.preventDefault(); - dispatch10.call("undo"); - } - function del(d3_event) { - d3_event.preventDefault(); - dispatch10.call("cancel"); - } - function ret(d3_event) { - d3_event.preventDefault(); - dispatch10.call("finish"); - } - function behavior(selection2) { - context.install(_hover); - context.install(_edit); - _downPointer = null; - keybinding.on("\u232B", backspace).on("\u2326", del).on("\u238B", ret).on("\u21A9", ret).on("space", space).on("\u2325space", space); - selection2.on("mouseenter.draw", mouseenter).on("mouseleave.draw", mouseleave).on(_pointerPrefix + "down.draw", pointerdown).on(_pointerPrefix + "move.draw", pointermove); - select_default2(window).on(_pointerPrefix + "up.draw", pointerup, true).on("pointercancel.draw", pointercancel, true); - select_default2(document).call(keybinding); - return behavior; - } - behavior.off = function(selection2) { - context.ui().sidebar.hover.cancel(); - context.uninstall(_hover); - context.uninstall(_edit); - selection2.on("mouseenter.draw", null).on("mouseleave.draw", null).on(_pointerPrefix + "down.draw", null).on(_pointerPrefix + "move.draw", null); - select_default2(window).on(_pointerPrefix + "up.draw", null).on("pointercancel.draw", null); - select_default2(document).call(keybinding.unbind); + if (target.type === "node") { + target = mergeLocation(remote, target); + } else if (target.type === "way") { + graph.rebase(remoteGraph.childNodes(remote), [graph], false); + target = mergeNodes(base, remote, target); + target = mergeChildren(target, utilArrayUnion(local.nodes, remote.nodes), updates, graph); + } else if (target.type === "relation") { + target = mergeMembers(remote, target); + } + target = mergeTags(base, remote, target); + if (!_conflicts.length) { + graph = updateChildren(updates, graph).replace(target); + } + return graph; }; - behavior.hover = function() { - return _hover; + action.withOption = function(opt) { + _option = opt; + return action; }; - return utilRebind(behavior, dispatch10, "on"); + action.conflicts = function() { + return _conflicts; + }; + return action; } - // modules/behavior/breathe.js - var import_fast_deep_equal2 = __toESM(require_fast_deep_equal()); - - // node_modules/d3-scale/src/init.js - function initRange(domain2, range3) { - switch (arguments.length) { - case 0: - break; - case 1: - this.range(domain2); - break; - default: - this.range(range3).domain(domain2); - break; + // modules/actions/move.js + function actionMove(moveIDs, tryDelta, projection2, cache) { + var _delta = tryDelta; + function setupCache(graph) { + function canMove(nodeID) { + if (moveIDs.indexOf(nodeID) !== -1) + return true; + var parents = graph.parentWays(graph.entity(nodeID)); + if (parents.length < 3) + return true; + var parentsMoving = parents.every(function(way) { + return cache.moving[way.id]; + }); + if (!parentsMoving) + delete cache.moving[nodeID]; + return parentsMoving; + } + function cacheEntities(ids) { + for (var i2 = 0; i2 < ids.length; i2++) { + var id2 = ids[i2]; + if (cache.moving[id2]) + continue; + cache.moving[id2] = true; + var entity = graph.hasEntity(id2); + if (!entity) + continue; + if (entity.type === "node") { + cache.nodes.push(id2); + cache.startLoc[id2] = entity.loc; + } else if (entity.type === "way") { + cache.ways.push(id2); + cacheEntities(entity.nodes); + } else { + cacheEntities(entity.members.map(function(member) { + return member.id; + })); + } + } + } + function cacheIntersections(ids) { + function isEndpoint(way2, id3) { + return !way2.isClosed() && !!way2.affix(id3); + } + for (var i2 = 0; i2 < ids.length; i2++) { + var id2 = ids[i2]; + var childNodes = graph.childNodes(graph.entity(id2)); + for (var j2 = 0; j2 < childNodes.length; j2++) { + var node = childNodes[j2]; + var parents = graph.parentWays(node); + if (parents.length !== 2) + continue; + var moved = graph.entity(id2); + var unmoved = null; + for (var k = 0; k < parents.length; k++) { + var way = parents[k]; + if (!cache.moving[way.id]) { + unmoved = way; + break; + } + } + if (!unmoved) + continue; + if (utilArrayIntersection(moved.nodes, unmoved.nodes).length > 2) + continue; + if (moved.isArea() || unmoved.isArea()) + continue; + cache.intersections.push({ + nodeId: node.id, + movedId: moved.id, + unmovedId: unmoved.id, + movedIsEP: isEndpoint(moved, node.id), + unmovedIsEP: isEndpoint(unmoved, node.id) + }); + } + } + } + if (!cache) { + cache = {}; + } + if (!cache.ok) { + cache.moving = {}; + cache.intersections = []; + cache.replacedVertex = {}; + cache.startLoc = {}; + cache.nodes = []; + cache.ways = []; + cacheEntities(moveIDs); + cacheIntersections(cache.ways); + cache.nodes = cache.nodes.filter(canMove); + cache.ok = true; + } } - return this; - } - - // node_modules/d3-scale/src/constant.js - function constants(x) { - return function() { - return x; - }; - } - - // node_modules/d3-scale/src/number.js - function number2(x) { - return +x; - } - - // node_modules/d3-scale/src/continuous.js - var unit = [0, 1]; - function identity3(x) { - return x; - } - function normalize(a, b) { - return (b -= a = +a) ? function(x) { - return (x - a) / b; - } : constants(isNaN(b) ? NaN : 0.5); - } - function clamper(a, b) { - var t; - if (a > b) - t = a, a = b, b = t; - return function(x) { - return Math.max(a, Math.min(b, x)); - }; - } - function bimap(domain2, range3, interpolate) { - var d0 = domain2[0], d1 = domain2[1], r0 = range3[0], r1 = range3[1]; - if (d1 < d0) - d0 = normalize(d1, d0), r0 = interpolate(r1, r0); - else - d0 = normalize(d0, d1), r0 = interpolate(r0, r1); - return function(x) { - return r0(d0(x)); - }; - } - function polymap(domain2, range3, interpolate) { - var j2 = Math.min(domain2.length, range3.length) - 1, d = new Array(j2), r = new Array(j2), i2 = -1; - if (domain2[j2] < domain2[0]) { - domain2 = domain2.slice().reverse(); - range3 = range3.slice().reverse(); + function replaceMovedVertex(nodeId, wayId, graph, delta) { + var way = graph.entity(wayId); + var moved = graph.entity(nodeId); + var movedIndex = way.nodes.indexOf(nodeId); + var len, prevIndex, nextIndex; + if (way.isClosed()) { + len = way.nodes.length - 1; + prevIndex = (movedIndex + len - 1) % len; + nextIndex = (movedIndex + len + 1) % len; + } else { + len = way.nodes.length; + prevIndex = movedIndex - 1; + nextIndex = movedIndex + 1; + } + var prev = graph.hasEntity(way.nodes[prevIndex]); + var next = graph.hasEntity(way.nodes[nextIndex]); + if (!prev || !next) + return graph; + var key = wayId + "_" + nodeId; + var orig = cache.replacedVertex[key]; + if (!orig) { + orig = osmNode(); + cache.replacedVertex[key] = orig; + cache.startLoc[orig.id] = cache.startLoc[nodeId]; + } + var start2, end; + if (delta) { + start2 = projection2(cache.startLoc[nodeId]); + end = projection2.invert(geoVecAdd(start2, delta)); + } else { + end = cache.startLoc[nodeId]; + } + orig = orig.move(end); + var angle2 = Math.abs(geoAngle(orig, prev, projection2) - geoAngle(orig, next, projection2)) * 180 / Math.PI; + if (angle2 > 175 && angle2 < 185) + return graph; + var p1 = [prev.loc, orig.loc, moved.loc, next.loc].map(projection2); + var p2 = [prev.loc, moved.loc, orig.loc, next.loc].map(projection2); + var d1 = geoPathLength(p1); + var d2 = geoPathLength(p2); + var insertAt = d1 <= d2 ? movedIndex : nextIndex; + if (way.isClosed() && insertAt === 0) + insertAt = len; + way = way.addNode(orig.id, insertAt); + return graph.replace(orig).replace(way); } - while (++i2 < j2) { - d[i2] = normalize(domain2[i2], domain2[i2 + 1]); - r[i2] = interpolate(range3[i2], range3[i2 + 1]); + function removeDuplicateVertices(wayId, graph) { + var way = graph.entity(wayId); + var epsilon3 = 1e-6; + var prev, curr; + function isInteresting(node, graph2) { + return graph2.parentWays(node).length > 1 || graph2.parentRelations(node).length || node.hasInterestingTags(); + } + for (var i2 = 0; i2 < way.nodes.length; i2++) { + curr = graph.entity(way.nodes[i2]); + if (prev && curr && geoVecEqual(prev.loc, curr.loc, epsilon3)) { + if (!isInteresting(prev, graph)) { + way = way.removeNode(prev.id); + graph = graph.replace(way).remove(prev); + } else if (!isInteresting(curr, graph)) { + way = way.removeNode(curr.id); + graph = graph.replace(way).remove(curr); + } + } + prev = curr; + } + return graph; } - return function(x) { - var i3 = bisect_default(domain2, x, 1, j2) - 1; - return r[i3](d[i3](x)); - }; - } - function copy(source, target) { - return target.domain(source.domain()).range(source.range()).interpolate(source.interpolate()).clamp(source.clamp()).unknown(source.unknown()); - } - function transformer2() { - var domain2 = unit, range3 = unit, interpolate = value_default, transform2, untransform, unknown, clamp3 = identity3, piecewise, output, input; - function rescale() { - var n2 = Math.min(domain2.length, range3.length); - if (clamp3 !== identity3) - clamp3 = clamper(domain2[0], domain2[n2 - 1]); - piecewise = n2 > 2 ? polymap : bimap; - output = input = null; - return scale; + function unZorroIntersection(intersection, graph) { + var vertex = graph.entity(intersection.nodeId); + var way1 = graph.entity(intersection.movedId); + var way2 = graph.entity(intersection.unmovedId); + var isEP1 = intersection.movedIsEP; + var isEP2 = intersection.unmovedIsEP; + if (isEP1 && isEP2) + return graph; + var nodes1 = graph.childNodes(way1).filter(function(n2) { + return n2 !== vertex; + }); + var nodes2 = graph.childNodes(way2).filter(function(n2) { + return n2 !== vertex; + }); + if (way1.isClosed() && way1.first() === vertex.id) + nodes1.push(nodes1[0]); + if (way2.isClosed() && way2.first() === vertex.id) + nodes2.push(nodes2[0]); + var edge1 = !isEP1 && geoChooseEdge(nodes1, projection2(vertex.loc), projection2); + var edge2 = !isEP2 && geoChooseEdge(nodes2, projection2(vertex.loc), projection2); + var loc; + if (!isEP1 && !isEP2) { + var epsilon3 = 1e-6, maxIter = 10; + for (var i2 = 0; i2 < maxIter; i2++) { + loc = geoVecInterp(edge1.loc, edge2.loc, 0.5); + edge1 = geoChooseEdge(nodes1, projection2(loc), projection2); + edge2 = geoChooseEdge(nodes2, projection2(loc), projection2); + if (Math.abs(edge1.distance - edge2.distance) < epsilon3) + break; + } + } else if (!isEP1) { + loc = edge1.loc; + } else { + loc = edge2.loc; + } + graph = graph.replace(vertex.move(loc)); + if (!isEP1 && edge1.index !== way1.nodes.indexOf(vertex.id)) { + way1 = way1.removeNode(vertex.id).addNode(vertex.id, edge1.index); + graph = graph.replace(way1); + } + if (!isEP2 && edge2.index !== way2.nodes.indexOf(vertex.id)) { + way2 = way2.removeNode(vertex.id).addNode(vertex.id, edge2.index); + graph = graph.replace(way2); + } + return graph; } - function scale(x) { - return x == null || isNaN(x = +x) ? unknown : (output || (output = piecewise(domain2.map(transform2), range3, interpolate)))(transform2(clamp3(x))); + function cleanupIntersections(graph) { + for (var i2 = 0; i2 < cache.intersections.length; i2++) { + var obj = cache.intersections[i2]; + graph = replaceMovedVertex(obj.nodeId, obj.movedId, graph, _delta); + graph = replaceMovedVertex(obj.nodeId, obj.unmovedId, graph, null); + graph = unZorroIntersection(obj, graph); + graph = removeDuplicateVertices(obj.movedId, graph); + graph = removeDuplicateVertices(obj.unmovedId, graph); + } + return graph; } - scale.invert = function(y) { - return clamp3(untransform((input || (input = piecewise(range3, domain2.map(transform2), number_default)))(y))); - }; - scale.domain = function(_) { - return arguments.length ? (domain2 = Array.from(_, number2), rescale()) : domain2.slice(); - }; - scale.range = function(_) { - return arguments.length ? (range3 = Array.from(_), rescale()) : range3.slice(); - }; - scale.rangeRound = function(_) { - return range3 = Array.from(_), interpolate = round_default, rescale(); - }; - scale.clamp = function(_) { - return arguments.length ? (clamp3 = _ ? true : identity3, rescale()) : clamp3 !== identity3; - }; - scale.interpolate = function(_) { - return arguments.length ? (interpolate = _, rescale()) : interpolate; - }; - scale.unknown = function(_) { - return arguments.length ? (unknown = _, scale) : unknown; + function limitDelta(graph) { + function moveNode(loc) { + return geoVecAdd(projection2(loc), _delta); + } + for (var i2 = 0; i2 < cache.intersections.length; i2++) { + var obj = cache.intersections[i2]; + if (obj.movedIsEP && obj.unmovedIsEP) + continue; + if (!obj.movedIsEP) + continue; + var node = graph.entity(obj.nodeId); + var start2 = projection2(node.loc); + var end = geoVecAdd(start2, _delta); + var movedNodes = graph.childNodes(graph.entity(obj.movedId)); + var movedPath = movedNodes.map(function(n2) { + return moveNode(n2.loc); + }); + var unmovedNodes = graph.childNodes(graph.entity(obj.unmovedId)); + var unmovedPath = unmovedNodes.map(function(n2) { + return projection2(n2.loc); + }); + var hits = geoPathIntersections(movedPath, unmovedPath); + for (var j2 = 0; i2 < hits.length; i2++) { + if (geoVecEqual(hits[j2], end)) + continue; + var edge = geoChooseEdge(unmovedNodes, end, projection2); + _delta = geoVecSubtract(projection2(edge.loc), start2); + } + } + } + var action = function(graph) { + if (_delta[0] === 0 && _delta[1] === 0) + return graph; + setupCache(graph); + if (cache.intersections.length) { + limitDelta(graph); + } + for (var i2 = 0; i2 < cache.nodes.length; i2++) { + var node = graph.entity(cache.nodes[i2]); + var start2 = projection2(node.loc); + var end = geoVecAdd(start2, _delta); + graph = graph.replace(node.move(projection2.invert(end))); + } + if (cache.intersections.length) { + graph = cleanupIntersections(graph); + } + return graph; }; - return function(t, u) { - transform2 = t, untransform = u; - return rescale(); + action.delta = function() { + return _delta; }; - } - function continuous() { - return transformer2()(identity3, identity3); - } - - // node_modules/d3-format/src/formatDecimal.js - function formatDecimal_default(x) { - return Math.abs(x = Math.round(x)) >= 1e21 ? x.toLocaleString("en").replace(/,/g, "") : x.toString(10); - } - function formatDecimalParts(x, p) { - if ((i2 = (x = p ? x.toExponential(p - 1) : x.toExponential()).indexOf("e")) < 0) - return null; - var i2, coefficient = x.slice(0, i2); - return [ - coefficient.length > 1 ? coefficient[0] + coefficient.slice(2) : coefficient, - +x.slice(i2 + 1) - ]; - } - - // node_modules/d3-format/src/exponent.js - function exponent_default(x) { - return x = formatDecimalParts(Math.abs(x)), x ? x[1] : NaN; + return action; } - // node_modules/d3-format/src/formatGroup.js - function formatGroup_default(grouping, thousands) { - return function(value, width) { - var i2 = value.length, t = [], j2 = 0, g = grouping[0], length = 0; - while (i2 > 0 && g > 0) { - if (length + g + 1 > width) - g = Math.max(1, width - length); - t.push(value.substring(i2 -= g, i2 + g)); - if ((length += g + 1) > width) - break; - g = grouping[j2 = (j2 + 1) % grouping.length]; - } - return t.reverse().join(thousands); + // modules/actions/move_member.js + function actionMoveMember(relationId, fromIndex, toIndex) { + return function(graph) { + return graph.replace(graph.entity(relationId).moveMember(fromIndex, toIndex)); }; } - // node_modules/d3-format/src/formatNumerals.js - function formatNumerals_default(numerals) { - return function(value) { - return value.replace(/[0-9]/g, function(i2) { - return numerals[+i2]; - }); + // modules/actions/move_node.js + function actionMoveNode(nodeID, toLoc) { + var action = function(graph, t) { + if (t === null || !isFinite(t)) + t = 1; + t = Math.min(Math.max(+t, 0), 1); + var node = graph.entity(nodeID); + return graph.replace( + node.move(geoVecInterp(node.loc, toLoc, t)) + ); }; + action.transitionable = true; + return action; } - // node_modules/d3-format/src/formatSpecifier.js - var re = /^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i; - function formatSpecifier(specifier) { - if (!(match = re.exec(specifier))) - throw new Error("invalid format: " + specifier); - var match; - return new FormatSpecifier({ - fill: match[1], - align: match[2], - sign: match[3], - symbol: match[4], - zero: match[5], - width: match[6], - comma: match[7], - precision: match[8] && match[8].slice(1), - trim: match[9], - type: match[10] - }); - } - formatSpecifier.prototype = FormatSpecifier.prototype; - function FormatSpecifier(specifier) { - this.fill = specifier.fill === void 0 ? " " : specifier.fill + ""; - this.align = specifier.align === void 0 ? ">" : specifier.align + ""; - this.sign = specifier.sign === void 0 ? "-" : specifier.sign + ""; - this.symbol = specifier.symbol === void 0 ? "" : specifier.symbol + ""; - this.zero = !!specifier.zero; - this.width = specifier.width === void 0 ? void 0 : +specifier.width; - this.comma = !!specifier.comma; - this.precision = specifier.precision === void 0 ? void 0 : +specifier.precision; - this.trim = !!specifier.trim; - this.type = specifier.type === void 0 ? "" : specifier.type + ""; + // modules/actions/noop.js + function actionNoop() { + return function(graph) { + return graph; + }; } - FormatSpecifier.prototype.toString = function() { - return this.fill + this.align + this.sign + this.symbol + (this.zero ? "0" : "") + (this.width === void 0 ? "" : Math.max(1, this.width | 0)) + (this.comma ? "," : "") + (this.precision === void 0 ? "" : "." + Math.max(0, this.precision | 0)) + (this.trim ? "~" : "") + this.type; - }; - // node_modules/d3-format/src/formatTrim.js - function formatTrim_default(s) { - out: - for (var n2 = s.length, i2 = 1, i0 = -1, i1; i2 < n2; ++i2) { - switch (s[i2]) { - case ".": - i0 = i1 = i2; - break; - case "0": - if (i0 === 0) - i0 = i2; - i1 = i2; - break; - default: - if (!+s[i2]) - break out; - if (i0 > 0) - i0 = 0; - break; - } + // modules/actions/orthogonalize.js + function actionOrthogonalize(wayID, projection2, vertexID, degThresh, ep) { + var epsilon3 = ep || 1e-4; + var threshold = degThresh || 13; + var lowerThreshold = Math.cos((90 - threshold) * Math.PI / 180); + var upperThreshold = Math.cos(threshold * Math.PI / 180); + var action = function(graph, t) { + if (t === null || !isFinite(t)) + t = 1; + t = Math.min(Math.max(+t, 0), 1); + var way = graph.entity(wayID); + way = way.removeNode(""); + if (way.tags.nonsquare) { + var tags = Object.assign({}, way.tags); + delete tags.nonsquare; + way = way.update({ tags }); } - return i0 > 0 ? s.slice(0, i0) + s.slice(i1 + 1) : s; - } - - // node_modules/d3-format/src/formatPrefixAuto.js - var prefixExponent; - function formatPrefixAuto_default(x, p) { - var d = formatDecimalParts(x, p); - if (!d) - return x + ""; - var coefficient = d[0], exponent = d[1], i2 = exponent - (prefixExponent = Math.max(-8, Math.min(8, Math.floor(exponent / 3))) * 3) + 1, n2 = coefficient.length; - return i2 === n2 ? coefficient : i2 > n2 ? coefficient + new Array(i2 - n2 + 1).join("0") : i2 > 0 ? coefficient.slice(0, i2) + "." + coefficient.slice(i2) : "0." + new Array(1 - i2).join("0") + formatDecimalParts(x, Math.max(0, p + i2 - 1))[0]; - } - - // node_modules/d3-format/src/formatRounded.js - function formatRounded_default(x, p) { - var d = formatDecimalParts(x, p); - if (!d) - return x + ""; - var coefficient = d[0], exponent = d[1]; - return exponent < 0 ? "0." + new Array(-exponent).join("0") + coefficient : coefficient.length > exponent + 1 ? coefficient.slice(0, exponent + 1) + "." + coefficient.slice(exponent + 1) : coefficient + new Array(exponent - coefficient.length + 2).join("0"); - } - - // node_modules/d3-format/src/formatTypes.js - var formatTypes_default = { - "%": (x, p) => (x * 100).toFixed(p), - "b": (x) => Math.round(x).toString(2), - "c": (x) => x + "", - "d": formatDecimal_default, - "e": (x, p) => x.toExponential(p), - "f": (x, p) => x.toFixed(p), - "g": (x, p) => x.toPrecision(p), - "o": (x) => Math.round(x).toString(8), - "p": (x, p) => formatRounded_default(x * 100, p), - "r": formatRounded_default, - "s": formatPrefixAuto_default, - "X": (x) => Math.round(x).toString(16).toUpperCase(), - "x": (x) => Math.round(x).toString(16) - }; - - // node_modules/d3-format/src/identity.js - function identity_default3(x) { - return x; - } - - // node_modules/d3-format/src/locale.js - var map = Array.prototype.map; - var prefixes = ["y", "z", "a", "f", "p", "n", "\xB5", "m", "", "k", "M", "G", "T", "P", "E", "Z", "Y"]; - function locale_default(locale2) { - var group = locale2.grouping === void 0 || locale2.thousands === void 0 ? identity_default3 : formatGroup_default(map.call(locale2.grouping, Number), locale2.thousands + ""), currencyPrefix = locale2.currency === void 0 ? "" : locale2.currency[0] + "", currencySuffix = locale2.currency === void 0 ? "" : locale2.currency[1] + "", decimal = locale2.decimal === void 0 ? "." : locale2.decimal + "", numerals = locale2.numerals === void 0 ? identity_default3 : formatNumerals_default(map.call(locale2.numerals, String)), percent = locale2.percent === void 0 ? "%" : locale2.percent + "", minus = locale2.minus === void 0 ? "\u2212" : locale2.minus + "", nan = locale2.nan === void 0 ? "NaN" : locale2.nan + ""; - function newFormat(specifier) { - specifier = formatSpecifier(specifier); - var fill = specifier.fill, align = specifier.align, sign2 = specifier.sign, symbol = specifier.symbol, zero3 = specifier.zero, width = specifier.width, comma = specifier.comma, precision2 = specifier.precision, trim = specifier.trim, type3 = specifier.type; - if (type3 === "n") - comma = true, type3 = "g"; - else if (!formatTypes_default[type3]) - precision2 === void 0 && (precision2 = 12), trim = true, type3 = "g"; - if (zero3 || fill === "0" && align === "=") - zero3 = true, fill = "0", align = "="; - var prefix = symbol === "$" ? currencyPrefix : symbol === "#" && /[boxX]/.test(type3) ? "0" + type3.toLowerCase() : "", suffix = symbol === "$" ? currencySuffix : /[%p]/.test(type3) ? percent : ""; - var formatType = formatTypes_default[type3], maybeSuffix = /[defgprs%]/.test(type3); - precision2 = precision2 === void 0 ? 6 : /[gprs]/.test(type3) ? Math.max(1, Math.min(21, precision2)) : Math.max(0, Math.min(20, precision2)); - function format2(value) { - var valuePrefix = prefix, valueSuffix = suffix, i2, n2, c; - if (type3 === "c") { - valueSuffix = formatType(value) + valueSuffix; - value = ""; - } else { - value = +value; - var valueNegative = value < 0 || 1 / value < 0; - value = isNaN(value) ? nan : formatType(Math.abs(value), precision2); - if (trim) - value = formatTrim_default(value); - if (valueNegative && +value === 0 && sign2 !== "+") - valueNegative = false; - valuePrefix = (valueNegative ? sign2 === "(" ? sign2 : minus : sign2 === "-" || sign2 === "(" ? "" : sign2) + valuePrefix; - valueSuffix = (type3 === "s" ? prefixes[8 + prefixExponent / 3] : "") + valueSuffix + (valueNegative && sign2 === "(" ? ")" : ""); - if (maybeSuffix) { - i2 = -1, n2 = value.length; - while (++i2 < n2) { - if (c = value.charCodeAt(i2), 48 > c || c > 57) { - valueSuffix = (c === 46 ? decimal + value.slice(i2 + 1) : value.slice(i2)) + valueSuffix; - value = value.slice(0, i2); - break; - } - } + graph = graph.replace(way); + var isClosed = way.isClosed(); + var nodes = graph.childNodes(way).slice(); + if (isClosed) + nodes.pop(); + if (vertexID !== void 0) { + nodes = nodeSubset(nodes, vertexID, isClosed); + if (nodes.length !== 3) + return graph; + } + var nodeCount = {}; + var points = []; + var corner = { i: 0, dotp: 1 }; + var node, point2, loc, score, motions, i2, j2; + for (i2 = 0; i2 < nodes.length; i2++) { + node = nodes[i2]; + nodeCount[node.id] = (nodeCount[node.id] || 0) + 1; + points.push({ id: node.id, coord: projection2(node.loc) }); + } + if (points.length === 3) { + for (i2 = 0; i2 < 1e3; i2++) { + motions = points.map(calcMotion); + points[corner.i].coord = geoVecAdd(points[corner.i].coord, motions[corner.i]); + score = corner.dotp; + if (score < epsilon3) { + break; } } - if (comma && !zero3) - value = group(value, Infinity); - var length = valuePrefix.length + value.length + valueSuffix.length, padding = length < width ? new Array(width - length + 1).join(fill) : ""; - if (comma && zero3) - value = group(padding + value, padding.length ? width - valueSuffix.length : Infinity), padding = ""; - switch (align) { - case "<": - value = valuePrefix + value + valueSuffix + padding; - break; - case "=": - value = valuePrefix + padding + value + valueSuffix; - break; - case "^": - value = padding.slice(0, length = padding.length >> 1) + valuePrefix + value + valueSuffix + padding.slice(length); - break; - default: - value = padding + valuePrefix + value + valueSuffix; + node = graph.entity(nodes[corner.i].id); + loc = projection2.invert(points[corner.i].coord); + graph = graph.replace(node.move(geoVecInterp(node.loc, loc, t))); + } else { + var straights = []; + var simplified = []; + for (i2 = 0; i2 < points.length; i2++) { + point2 = points[i2]; + var dotp = 0; + if (isClosed || i2 > 0 && i2 < points.length - 1) { + var a = points[(i2 - 1 + points.length) % points.length]; + var b = points[(i2 + 1) % points.length]; + dotp = Math.abs(geoOrthoNormalizedDotProduct(a.coord, b.coord, point2.coord)); + } + if (dotp > upperThreshold) { + straights.push(point2); + } else { + simplified.push(point2); + } + } + var bestPoints = clonePoints(simplified); + var originalPoints = clonePoints(simplified); + score = Infinity; + for (i2 = 0; i2 < 1e3; i2++) { + motions = simplified.map(calcMotion); + for (j2 = 0; j2 < motions.length; j2++) { + simplified[j2].coord = geoVecAdd(simplified[j2].coord, motions[j2]); + } + var newScore = geoOrthoCalcScore(simplified, isClosed, epsilon3, threshold); + if (newScore < score) { + bestPoints = clonePoints(simplified); + score = newScore; + } + if (score < epsilon3) { break; + } + } + var bestCoords = bestPoints.map(function(p) { + return p.coord; + }); + if (isClosed) + bestCoords.push(bestCoords[0]); + for (i2 = 0; i2 < bestPoints.length; i2++) { + point2 = bestPoints[i2]; + if (!geoVecEqual(originalPoints[i2].coord, point2.coord)) { + node = graph.entity(point2.id); + loc = projection2.invert(point2.coord); + graph = graph.replace(node.move(geoVecInterp(node.loc, loc, t))); + } + } + for (i2 = 0; i2 < straights.length; i2++) { + point2 = straights[i2]; + if (nodeCount[point2.id] > 1) + continue; + node = graph.entity(point2.id); + if (t === 1 && graph.parentWays(node).length === 1 && graph.parentRelations(node).length === 0 && !node.hasInterestingTags()) { + graph = actionDeleteNode(node.id)(graph); + } else { + var choice = geoVecProject(point2.coord, bestCoords); + if (choice) { + loc = projection2.invert(choice.target); + graph = graph.replace(node.move(geoVecInterp(node.loc, loc, t))); + } + } } - return numerals(value); } - format2.toString = function() { - return specifier + ""; - }; - return format2; - } - function formatPrefix2(specifier, value) { - var f2 = newFormat((specifier = formatSpecifier(specifier), specifier.type = "f", specifier)), e = Math.max(-8, Math.min(8, Math.floor(exponent_default(value) / 3))) * 3, k = Math.pow(10, -e), prefix = prefixes[8 + e / 3]; - return function(value2) { - return f2(k * value2) + prefix; - }; + return graph; + function clonePoints(array2) { + return array2.map(function(p) { + return { id: p.id, coord: [p.coord[0], p.coord[1]] }; + }); + } + function calcMotion(point3, i3, array2) { + if (!isClosed && (i3 === 0 || i3 === array2.length - 1)) + return [0, 0]; + if (nodeCount[array2[i3].id] > 1) + return [0, 0]; + var a2 = array2[(i3 - 1 + array2.length) % array2.length].coord; + var origin = point3.coord; + var b2 = array2[(i3 + 1) % array2.length].coord; + var p = geoVecSubtract(a2, origin); + var q = geoVecSubtract(b2, origin); + var scale = 2 * Math.min(geoVecLength(p), geoVecLength(q)); + p = geoVecNormalize(p); + q = geoVecNormalize(q); + var dotp2 = p[0] * q[0] + p[1] * q[1]; + var val = Math.abs(dotp2); + if (val < lowerThreshold) { + corner.i = i3; + corner.dotp = val; + var vec = geoVecNormalize(geoVecAdd(p, q)); + return geoVecScale(vec, 0.1 * dotp2 * scale); + } + return [0, 0]; + } + }; + function nodeSubset(nodes, vertexID2, isClosed) { + var first = isClosed ? 0 : 1; + var last = isClosed ? nodes.length : nodes.length - 1; + for (var i2 = first; i2 < last; i2++) { + if (nodes[i2].id === vertexID2) { + return [ + nodes[(i2 - 1 + nodes.length) % nodes.length], + nodes[i2], + nodes[(i2 + 1) % nodes.length] + ]; + } + } + return []; } - return { - format: newFormat, - formatPrefix: formatPrefix2 + action.disabled = function(graph) { + var way = graph.entity(wayID); + way = way.removeNode(""); + graph = graph.replace(way); + var isClosed = way.isClosed(); + var nodes = graph.childNodes(way).slice(); + if (isClosed) + nodes.pop(); + var allowStraightAngles = false; + if (vertexID !== void 0) { + allowStraightAngles = true; + nodes = nodeSubset(nodes, vertexID, isClosed); + if (nodes.length !== 3) + return "end_vertex"; + } + var coords = nodes.map(function(n2) { + return projection2(n2.loc); + }); + var score = geoOrthoCanOrthogonalize(coords, isClosed, epsilon3, threshold, allowStraightAngles); + if (score === null) { + return "not_squarish"; + } else if (score === 0) { + return "square_enough"; + } else { + return false; + } }; + action.transitionable = true; + return action; } - // node_modules/d3-format/src/defaultLocale.js - var locale; - var format; - var formatPrefix; - defaultLocale({ - thousands: ",", - grouping: [3], - currency: ["$", ""] - }); - function defaultLocale(definition) { - locale = locale_default(definition); - format = locale.format; - formatPrefix = locale.formatPrefix; - return locale; + // modules/actions/restrict_turn.js + function actionRestrictTurn(turn, restrictionType, restrictionID) { + return function(graph) { + var fromWay = graph.entity(turn.from.way); + var toWay = graph.entity(turn.to.way); + var viaNode = turn.via.node && graph.entity(turn.via.node); + var viaWays = turn.via.ways && turn.via.ways.map(function(id2) { + return graph.entity(id2); + }); + var members = []; + members.push({ id: fromWay.id, type: "way", role: "from" }); + if (viaNode) { + members.push({ id: viaNode.id, type: "node", role: "via" }); + } else if (viaWays) { + viaWays.forEach(function(viaWay) { + members.push({ id: viaWay.id, type: "way", role: "via" }); + }); + } + members.push({ id: toWay.id, type: "way", role: "to" }); + return graph.replace(osmRelation({ + id: restrictionID, + tags: { + type: "restriction", + restriction: restrictionType + }, + members + })); + }; } - // node_modules/d3-format/src/precisionFixed.js - function precisionFixed_default(step) { - return Math.max(0, -exponent_default(Math.abs(step))); + // modules/actions/revert.js + function actionRevert(id2) { + var action = function(graph) { + var entity = graph.hasEntity(id2), base = graph.base().entities[id2]; + if (entity && !base) { + if (entity.type === "node") { + graph.parentWays(entity).forEach(function(parent) { + parent = parent.removeNode(id2); + graph = graph.replace(parent); + if (parent.isDegenerate()) { + graph = actionDeleteWay(parent.id)(graph); + } + }); + } + graph.parentRelations(entity).forEach(function(parent) { + parent = parent.removeMembersWithID(id2); + graph = graph.replace(parent); + if (parent.isDegenerate()) { + graph = actionDeleteRelation(parent.id)(graph); + } + }); + } + return graph.revert(id2); + }; + return action; } - // node_modules/d3-format/src/precisionPrefix.js - function precisionPrefix_default(step, value) { - return Math.max(0, Math.max(-8, Math.min(8, Math.floor(exponent_default(value) / 3))) * 3 - exponent_default(Math.abs(step))); + // modules/actions/rotate.js + function actionRotate(rotateIds, pivot, angle2, projection2) { + var action = function(graph) { + return graph.update(function(graph2) { + utilGetAllNodes(rotateIds, graph2).forEach(function(node) { + var point2 = geoRotate([projection2(node.loc)], angle2, pivot)[0]; + graph2 = graph2.replace(node.move(projection2.invert(point2))); + }); + }); + }; + return action; } - // node_modules/d3-format/src/precisionRound.js - function precisionRound_default(step, max3) { - step = Math.abs(step), max3 = Math.abs(max3) - step; - return Math.max(0, exponent_default(max3) - exponent_default(step)) + 1; + // modules/actions/scale.js + function actionScale(ids, pivotLoc, scaleFactor, projection2) { + return function(graph) { + return graph.update(function(graph2) { + let point2, radial; + utilGetAllNodes(ids, graph2).forEach(function(node) { + point2 = projection2(node.loc); + radial = [ + point2[0] - pivotLoc[0], + point2[1] - pivotLoc[1] + ]; + point2 = [ + pivotLoc[0] + scaleFactor * radial[0], + pivotLoc[1] + scaleFactor * radial[1] + ]; + graph2 = graph2.replace(node.move(projection2.invert(point2))); + }); + }); + }; } - // node_modules/d3-scale/src/tickFormat.js - function tickFormat(start2, stop, count, specifier) { - var step = tickStep(start2, stop, count), precision2; - specifier = formatSpecifier(specifier == null ? ",f" : specifier); - switch (specifier.type) { - case "s": { - var value = Math.max(Math.abs(start2), Math.abs(stop)); - if (specifier.precision == null && !isNaN(precision2 = precisionPrefix_default(step, value))) - specifier.precision = precision2; - return formatPrefix(specifier, value); - } - case "": - case "e": - case "g": - case "p": - case "r": { - if (specifier.precision == null && !isNaN(precision2 = precisionRound_default(step, Math.max(Math.abs(start2), Math.abs(stop))))) - specifier.precision = precision2 - (specifier.type === "e"); - break; - } - case "f": - case "%": { - if (specifier.precision == null && !isNaN(precision2 = precisionFixed_default(step))) - specifier.precision = precision2 - (specifier.type === "%") * 2; - break; + // modules/actions/straighten_nodes.js + function actionStraightenNodes(nodeIDs, projection2) { + function positionAlongWay(a, o, b) { + return geoVecDot(a, b, o) / geoVecDot(b, b, o); + } + function getEndpoints(points) { + var ssr = geoGetSmallestSurroundingRectangle(points); + var p1 = [(ssr.poly[0][0] + ssr.poly[1][0]) / 2, (ssr.poly[0][1] + ssr.poly[1][1]) / 2]; + var q1 = [(ssr.poly[2][0] + ssr.poly[3][0]) / 2, (ssr.poly[2][1] + ssr.poly[3][1]) / 2]; + var p2 = [(ssr.poly[3][0] + ssr.poly[4][0]) / 2, (ssr.poly[3][1] + ssr.poly[4][1]) / 2]; + var q2 = [(ssr.poly[1][0] + ssr.poly[2][0]) / 2, (ssr.poly[1][1] + ssr.poly[2][1]) / 2]; + var isLong = geoVecLength(p1, q1) > geoVecLength(p2, q2); + if (isLong) { + return [p1, q1]; } + return [p2, q2]; } - return format(specifier); - } - - // node_modules/d3-scale/src/linear.js - function linearish(scale) { - var domain2 = scale.domain; - scale.ticks = function(count) { - var d = domain2(); - return ticks(d[0], d[d.length - 1], count == null ? 10 : count); - }; - scale.tickFormat = function(count, specifier) { - var d = domain2(); - return tickFormat(d[0], d[d.length - 1], count == null ? 10 : count, specifier); - }; - scale.nice = function(count) { - if (count == null) - count = 10; - var d = domain2(); - var i0 = 0; - var i1 = d.length - 1; - var start2 = d[i0]; - var stop = d[i1]; - var prestep; - var step; - var maxIter = 10; - if (stop < start2) { - step = start2, start2 = stop, stop = step; - step = i0, i0 = i1, i1 = step; + var action = function(graph, t) { + if (t === null || !isFinite(t)) + t = 1; + t = Math.min(Math.max(+t, 0), 1); + var nodes = nodeIDs.map(function(id2) { + return graph.entity(id2); + }); + var points = nodes.map(function(n2) { + return projection2(n2.loc); + }); + var endpoints = getEndpoints(points); + var startPoint = endpoints[0]; + var endPoint = endpoints[1]; + for (var i2 = 0; i2 < points.length; i2++) { + var node = nodes[i2]; + var point2 = points[i2]; + var u = positionAlongWay(point2, startPoint, endPoint); + var point22 = geoVecInterp(startPoint, endPoint, u); + var loc2 = projection2.invert(point22); + graph = graph.replace(node.move(geoVecInterp(node.loc, loc2, t))); } - while (maxIter-- > 0) { - step = tickIncrement(start2, stop, count); - if (step === prestep) { - d[i0] = start2; - d[i1] = stop; - return domain2(d); - } else if (step > 0) { - start2 = Math.floor(start2 / step) * step; - stop = Math.ceil(stop / step) * step; - } else if (step < 0) { - start2 = Math.ceil(start2 * step) / step; - stop = Math.floor(stop * step) / step; - } else { - break; + return graph; + }; + action.disabled = function(graph) { + var nodes = nodeIDs.map(function(id2) { + return graph.entity(id2); + }); + var points = nodes.map(function(n2) { + return projection2(n2.loc); + }); + var endpoints = getEndpoints(points); + var startPoint = endpoints[0]; + var endPoint = endpoints[1]; + var maxDistance = 0; + for (var i2 = 0; i2 < points.length; i2++) { + var point2 = points[i2]; + var u = positionAlongWay(point2, startPoint, endPoint); + var p = geoVecInterp(startPoint, endPoint, u); + var dist = geoVecLength(p, point2); + if (!isNaN(dist) && dist > maxDistance) { + maxDistance = dist; } - prestep = step; } - return scale; - }; - return scale; - } - function linear3() { - var scale = continuous(); - scale.copy = function() { - return copy(scale, linear3()); + if (maxDistance < 1e-4) { + return "straight_enough"; + } }; - initRange.apply(scale, arguments); - return linearish(scale); + action.transitionable = true; + return action; } - // node_modules/d3-scale/src/quantize.js - function quantize() { - var x05 = 0, x12 = 1, n2 = 1, domain2 = [0.5], range3 = [0, 1], unknown; - function scale(x) { - return x != null && x <= x ? range3[bisect_default(domain2, x, 0, n2)] : unknown; - } - function rescale() { - var i2 = -1; - domain2 = new Array(n2); - while (++i2 < n2) - domain2[i2] = ((i2 + 1) * x12 - (i2 - n2) * x05) / (n2 + 1); - return scale; + // modules/actions/straighten_way.js + function actionStraightenWay(selectedIDs, projection2) { + function positionAlongWay(a, o, b) { + return geoVecDot(a, b, o) / geoVecDot(b, b, o); } - scale.domain = function(_) { - return arguments.length ? ([x05, x12] = _, x05 = +x05, x12 = +x12, rescale()) : [x05, x12]; - }; - scale.range = function(_) { - return arguments.length ? (n2 = (range3 = Array.from(_)).length - 1, rescale()) : range3.slice(); - }; - scale.invertExtent = function(y) { - var i2 = range3.indexOf(y); - return i2 < 0 ? [NaN, NaN] : i2 < 1 ? [x05, domain2[0]] : i2 >= n2 ? [domain2[n2 - 1], x12] : [domain2[i2 - 1], domain2[i2]]; - }; - scale.unknown = function(_) { - return arguments.length ? (unknown = _, scale) : scale; - }; - scale.thresholds = function() { - return domain2.slice(); - }; - scale.copy = function() { - return quantize().domain([x05, x12]).range(range3).unknown(unknown); - }; - return initRange.apply(linearish(scale), arguments); - } - - // modules/behavior/breathe.js - function behaviorBreathe() { - var duration = 800; - var steps = 4; - var selector = ".selected.shadow, .selected .shadow"; - var _selected = select_default2(null); - var _classed = ""; - var _params = {}; - var _done = false; - var _timer; - function ratchetyInterpolator(a, b, steps2, units) { - a = parseFloat(a); - b = parseFloat(b); - var sample = quantize().domain([0, 1]).range(quantize_default(number_default(a, b), steps2)); - return function(t) { - return String(sample(t)) + (units || ""); + function allNodes(graph) { + var nodes = []; + var startNodes = []; + var endNodes = []; + var remainingWays = []; + var selectedWays = selectedIDs.filter(function(w) { + return graph.entity(w).type === "way"; + }); + var selectedNodes = selectedIDs.filter(function(n2) { + return graph.entity(n2).type === "node"; + }); + for (var i2 = 0; i2 < selectedWays.length; i2++) { + var way = graph.entity(selectedWays[i2]); + nodes = way.nodes.slice(0); + remainingWays.push(nodes); + startNodes.push(nodes[0]); + endNodes.push(nodes[nodes.length - 1]); + } + startNodes = startNodes.filter(function(n2) { + return startNodes.indexOf(n2) === startNodes.lastIndexOf(n2); + }); + endNodes = endNodes.filter(function(n2) { + return endNodes.indexOf(n2) === endNodes.lastIndexOf(n2); + }); + var currNode = utilArrayDifference(startNodes, endNodes).concat(utilArrayDifference(endNodes, startNodes))[0]; + var nextWay = []; + nodes = []; + var getNextWay = function(currNode2, remainingWays2) { + return remainingWays2.filter(function(way2) { + return way2[0] === currNode2 || way2[way2.length - 1] === currNode2; + })[0]; }; + while (remainingWays.length) { + nextWay = getNextWay(currNode, remainingWays); + remainingWays = utilArrayDifference(remainingWays, [nextWay]); + if (nextWay[0] !== currNode) { + nextWay.reverse(); + } + nodes = nodes.concat(nextWay); + currNode = nodes[nodes.length - 1]; + } + if (selectedNodes.length === 2) { + var startNodeIdx = nodes.indexOf(selectedNodes[0]); + var endNodeIdx = nodes.indexOf(selectedNodes[1]); + var sortedStartEnd = [startNodeIdx, endNodeIdx]; + sortedStartEnd.sort(function(a, b) { + return a - b; + }); + nodes = nodes.slice(sortedStartEnd[0], sortedStartEnd[1] + 1); + } + return nodes.map(function(n2) { + return graph.entity(n2); + }); } - function reset(selection2) { - selection2.style("stroke-opacity", null).style("stroke-width", null).style("fill-opacity", null).style("r", null); + function shouldKeepNode(node, graph) { + return graph.parentWays(node).length > 1 || graph.parentRelations(node).length || node.hasInterestingTags(); } - function setAnimationParams(transition2, fromTo) { - var toFrom = fromTo === "from" ? "to" : "from"; - transition2.styleTween("stroke-opacity", function(d) { - return ratchetyInterpolator( - _params[d.id][toFrom].opacity, - _params[d.id][fromTo].opacity, - steps - ); - }).styleTween("stroke-width", function(d) { - return ratchetyInterpolator( - _params[d.id][toFrom].width, - _params[d.id][fromTo].width, - steps, - "px" - ); - }).styleTween("fill-opacity", function(d) { - return ratchetyInterpolator( - _params[d.id][toFrom].opacity, - _params[d.id][fromTo].opacity, - steps - ); - }).styleTween("r", function(d) { - return ratchetyInterpolator( - _params[d.id][toFrom].width, - _params[d.id][fromTo].width, - steps, - "px" - ); + var action = function(graph, t) { + if (t === null || !isFinite(t)) + t = 1; + t = Math.min(Math.max(+t, 0), 1); + var nodes = allNodes(graph); + var points = nodes.map(function(n2) { + return projection2(n2.loc); }); - } - function calcAnimationParams(selection2) { - selection2.call(reset).each(function(d) { - var s = select_default2(this); - var tag = s.node().tagName; - var p = { "from": {}, "to": {} }; - var opacity; - var width; - if (tag === "circle") { - opacity = parseFloat(s.style("fill-opacity") || 0.5); - width = parseFloat(s.style("r") || 15.5); + var startPoint = points[0]; + var endPoint = points[points.length - 1]; + var toDelete = []; + var i2; + for (i2 = 1; i2 < points.length - 1; i2++) { + var node = nodes[i2]; + var point2 = points[i2]; + if (t < 1 || shouldKeepNode(node, graph)) { + var u = positionAlongWay(point2, startPoint, endPoint); + var p = geoVecInterp(startPoint, endPoint, u); + var loc2 = projection2.invert(p); + graph = graph.replace(node.move(geoVecInterp(node.loc, loc2, t))); } else { - opacity = parseFloat(s.style("stroke-opacity") || 0.7); - width = parseFloat(s.style("stroke-width") || 10); + if (toDelete.indexOf(node) === -1) { + toDelete.push(node); + } } - p.tag = tag; - p.from.opacity = opacity * 0.6; - p.to.opacity = opacity * 1.25; - p.from.width = width * 0.7; - p.to.width = width * (tag === "circle" ? 1.5 : 1); - _params[d.id] = p; - }); - } - function run(surface, fromTo) { - var toFrom = fromTo === "from" ? "to" : "from"; - var currSelected = surface.selectAll(selector); - var currClassed = surface.attr("class"); - if (_done || currSelected.empty()) { - _selected.call(reset); - _selected = select_default2(null); - return; } - if (!(0, import_fast_deep_equal2.default)(currSelected.data(), _selected.data()) || currClassed !== _classed) { - _selected.call(reset); - _classed = currClassed; - _selected = currSelected.call(calcAnimationParams); + for (i2 = 0; i2 < toDelete.length; i2++) { + graph = actionDeleteNode(toDelete[i2].id)(graph); } - var didCallNextRun = false; - _selected.transition().duration(duration).call(setAnimationParams, fromTo).on("end", function() { - if (!didCallNextRun) { - surface.call(run, toFrom); - didCallNextRun = true; - } - if (!select_default2(this).classed("selected")) { - reset(select_default2(this)); - } + return graph; + }; + action.disabled = function(graph) { + var nodes = allNodes(graph); + var points = nodes.map(function(n2) { + return projection2(n2.loc); }); - } - function behavior(surface) { - _done = false; - _timer = timer(function() { - if (surface.selectAll(selector).empty()) { - return false; - } - surface.call(run, "from"); - _timer.stop(); - return true; - }, 20); - } - behavior.restartIfNeeded = function(surface) { - if (_selected.empty()) { - surface.call(run, "from"); - if (_timer) { - _timer.stop(); + var startPoint = points[0]; + var endPoint = points[points.length - 1]; + var threshold = 0.2 * geoVecLength(startPoint, endPoint); + var i2; + if (threshold === 0) { + return "too_bendy"; + } + var maxDistance = 0; + for (i2 = 1; i2 < points.length - 1; i2++) { + var point2 = points[i2]; + var u = positionAlongWay(point2, startPoint, endPoint); + var p = geoVecInterp(startPoint, endPoint, u); + var dist = geoVecLength(p, point2); + if (isNaN(dist) || dist > threshold) { + return "too_bendy"; + } else if (dist > maxDistance) { + maxDistance = dist; } } - }; - behavior.off = function() { - _done = true; - if (_timer) { - _timer.stop(); + var keepingAllNodes = nodes.every(function(node, i3) { + return i3 === 0 || i3 === nodes.length - 1 || shouldKeepNode(node, graph); + }); + if (maxDistance < 1e-4 && // Allow straightening even if already straight in order to remove extraneous nodes + keepingAllNodes) { + return "straight_enough"; } - _selected.interrupt().call(reset); }; - return behavior; + action.transitionable = true; + return action; } - // modules/behavior/operation.js - function behaviorOperation(context) { - var _operation; - function keypress(d3_event) { - if (!context.map().withinEditableZoom()) - return; - if (_operation.availableForKeypress && !_operation.availableForKeypress()) - return; - d3_event.preventDefault(); - var disabled = _operation.disabled(); - if (disabled) { - context.ui().flash.duration(4e3).iconName("#iD-operation-" + _operation.id).iconClass("operation disabled").label(_operation.tooltip())(); + // modules/actions/unrestrict_turn.js + function actionUnrestrictTurn(turn) { + return function(graph) { + return actionDeleteRelation(turn.restrictionID)(graph); + }; + } + + // modules/actions/reflect.js + function actionReflect(reflectIds, projection2) { + var _useLongAxis = true; + var action = function(graph, t) { + if (t === null || !isFinite(t)) + t = 1; + t = Math.min(Math.max(+t, 0), 1); + var nodes = utilGetAllNodes(reflectIds, graph); + var points = nodes.map(function(n2) { + return projection2(n2.loc); + }); + var ssr = geoGetSmallestSurroundingRectangle(points); + var p1 = [(ssr.poly[0][0] + ssr.poly[1][0]) / 2, (ssr.poly[0][1] + ssr.poly[1][1]) / 2]; + var q1 = [(ssr.poly[2][0] + ssr.poly[3][0]) / 2, (ssr.poly[2][1] + ssr.poly[3][1]) / 2]; + var p2 = [(ssr.poly[3][0] + ssr.poly[4][0]) / 2, (ssr.poly[3][1] + ssr.poly[4][1]) / 2]; + var q2 = [(ssr.poly[1][0] + ssr.poly[2][0]) / 2, (ssr.poly[1][1] + ssr.poly[2][1]) / 2]; + var p, q; + var isLong = geoVecLength(p1, q1) > geoVecLength(p2, q2); + if (_useLongAxis && isLong || !_useLongAxis && !isLong) { + p = p1; + q = q1; } else { - context.ui().flash.duration(2e3).iconName("#iD-operation-" + _operation.id).iconClass("operation").label(_operation.annotation() || _operation.title)(); - if (_operation.point) - _operation.point(null); - _operation(); + p = p2; + q = q2; } - } - function behavior() { - if (_operation && _operation.available()) { - context.keybinding().on(_operation.keys, keypress); + var dx = q[0] - p[0]; + var dy = q[1] - p[1]; + var a = (dx * dx - dy * dy) / (dx * dx + dy * dy); + var b = 2 * dx * dy / (dx * dx + dy * dy); + for (var i2 = 0; i2 < nodes.length; i2++) { + var node = nodes[i2]; + var c = projection2(node.loc); + var c2 = [ + a * (c[0] - p[0]) + b * (c[1] - p[1]) + p[0], + b * (c[0] - p[0]) - a * (c[1] - p[1]) + p[1] + ]; + var loc2 = projection2.invert(c2); + node = node.move(geoVecInterp(node.loc, loc2, t)); + graph = graph.replace(node); } - return behavior; - } - behavior.off = function() { - context.keybinding().off(_operation.keys); + return graph; }; - behavior.which = function(_) { + action.useLongAxis = function(val) { if (!arguments.length) - return _operation; - _operation = _; - return behavior; + return _useLongAxis; + _useLongAxis = val; + return action; }; - return behavior; + action.transitionable = true; + return action; } - // modules/operations/circularize.js - function operationCircularize(context, selectedIDs) { - var _extent; - var _actions = selectedIDs.map(getAction).filter(Boolean); - var _amount = _actions.length === 1 ? "single" : "multiple"; - var _coords = utilGetAllNodes(selectedIDs, context.graph()).map(function(n2) { - return n2.loc; - }); - function getAction(entityID) { - var entity = context.entity(entityID); - if (entity.type !== "way" || new Set(entity.nodes).size <= 1) - return null; - if (!_extent) { - _extent = entity.extent(context.graph()); - } else { - _extent = _extent.extend(entity.extent(context.graph())); - } - return actionCircularize(entityID, context.projection); - } - var operation = function() { - if (!_actions.length) - return; - var combinedAction = function(graph, t) { - _actions.forEach(function(action) { - if (!action.disabled(graph)) { - graph = action(graph, t); + // modules/actions/upgrade_tags.js + function actionUpgradeTags(entityId, oldTags, replaceTags) { + return function(graph) { + var entity = graph.entity(entityId); + var tags = Object.assign({}, entity.tags); + var transferValue; + var semiIndex; + for (var oldTagKey in oldTags) { + if (!(oldTagKey in tags)) + continue; + if (oldTags[oldTagKey] === "*") { + transferValue = tags[oldTagKey]; + delete tags[oldTagKey]; + } else if (oldTags[oldTagKey] === tags[oldTagKey]) { + delete tags[oldTagKey]; + } else { + var vals = tags[oldTagKey].split(";").filter(Boolean); + var oldIndex = vals.indexOf(oldTags[oldTagKey]); + if (vals.length === 1 || oldIndex === -1) { + delete tags[oldTagKey]; + } else { + if (replaceTags && replaceTags[oldTagKey]) { + semiIndex = oldIndex; + } + vals.splice(oldIndex, 1); + tags[oldTagKey] = vals.join(";"); } - }); - return graph; - }; - combinedAction.transitionable = true; - context.perform(combinedAction, operation.annotation()); - window.setTimeout(function() { - context.validator().validate(); - }, 300); - }; - operation.available = function() { - return _actions.length && selectedIDs.length === _actions.length; - }; - operation.disabled = function() { - if (!_actions.length) - return ""; - var actionDisableds = _actions.map(function(action) { - return action.disabled(context.graph()); - }).filter(Boolean); - if (actionDisableds.length === _actions.length) { - if (new Set(actionDisableds).size > 1) { - return "multiple_blockers"; } - return actionDisableds[0]; - } else if (_extent.percentContainedIn(context.map().extent()) < 0.8) { - return "too_large"; - } else if (someMissing()) { - return "not_downloaded"; - } else if (selectedIDs.some(context.hasHiddenConnections)) { - return "connected_to_hidden"; } - return false; - function someMissing() { - if (context.inIntro()) - return false; - var osm = context.connection(); - if (osm) { - var missing = _coords.filter(function(loc) { - return !osm.isDataLoaded(loc); - }); - if (missing.length) { - missing.forEach(function(loc) { - context.loadTileAtLoc(loc); - }); - return true; + if (replaceTags) { + for (var replaceKey in replaceTags) { + var replaceValue = replaceTags[replaceKey]; + if (replaceValue === "*") { + if (tags[replaceKey] && tags[replaceKey] !== "no") { + continue; + } else { + tags[replaceKey] = "yes"; + } + } else if (replaceValue === "$1") { + tags[replaceKey] = transferValue; + } else { + if (tags[replaceKey] && oldTags[replaceKey] && semiIndex !== void 0) { + var existingVals = tags[replaceKey].split(";").filter(Boolean); + if (existingVals.indexOf(replaceValue) === -1) { + existingVals.splice(semiIndex, 0, replaceValue); + tags[replaceKey] = existingVals.join(";"); + } + } else { + tags[replaceKey] = replaceValue; + } } } - return false; } + return graph.replace(entity.update({ tags })); }; - operation.tooltip = function() { - var disable = operation.disabled(); - return disable ? _t.append("operations.circularize." + disable + "." + _amount) : _t.append("operations.circularize.description." + _amount); - }; - operation.annotation = function() { - return _t("operations.circularize.annotation.feature", { n: _actions.length }); - }; - operation.id = "circularize"; - operation.keys = [_t("operations.circularize.key")]; - operation.title = _t.append("operations.circularize.title"); - operation.behavior = behaviorOperation(context).which(operation); - return operation; } - // modules/ui/cmd.js - var uiCmd = function(code) { - var detected = utilDetect(); - if (detected.os === "mac") { - return code; - } - if (detected.os === "win") { - if (code === "\u2318\u21E7Z") - return "Ctrl+Y"; + // modules/behavior/edit.js + function behaviorEdit(context) { + function behavior() { + context.map().minzoom(context.minEditableZoom()); } - var result = "", replacements = { - "\u2318": "Ctrl", - "\u21E7": "Shift", - "\u2325": "Alt", - "\u232B": "Backspace", - "\u2326": "Delete" + behavior.off = function() { + context.map().minzoom(0); }; - for (var i2 = 0; i2 < code.length; i2++) { - if (code[i2] in replacements) { - result += replacements[code[i2]] + (i2 < code.length - 1 ? "+" : ""); - } else { - result += code[i2]; + return behavior; + } + + // modules/behavior/hover.js + function behaviorHover(context) { + var dispatch10 = dispatch_default("hover"); + var _selection = select_default2(null); + var _newNodeId = null; + var _initialNodeID = null; + var _altDisables; + var _ignoreVertex; + var _targets = []; + var _pointerPrefix = "PointerEvent" in window ? "pointer" : "mouse"; + function keydown(d3_event) { + if (_altDisables && d3_event.keyCode === utilKeybinding.modifierCodes.alt) { + _selection.selectAll(".hover").classed("hover-suppressed", true).classed("hover", false); + _selection.classed("hover-disabled", true); + dispatch10.call("hover", this, null); } } - return result; - }; - uiCmd.display = function(code) { - if (code.length !== 1) - return code; - var detected = utilDetect(); - var mac = detected.os === "mac"; - var replacements = { - "\u2318": mac ? "\u2318 " + _t("shortcuts.key.cmd") : _t("shortcuts.key.ctrl"), - "\u21E7": mac ? "\u21E7 " + _t("shortcuts.key.shift") : _t("shortcuts.key.shift"), - "\u2325": mac ? "\u2325 " + _t("shortcuts.key.option") : _t("shortcuts.key.alt"), - "\u2303": mac ? "\u2303 " + _t("shortcuts.key.ctrl") : _t("shortcuts.key.ctrl"), - "\u232B": mac ? "\u232B " + _t("shortcuts.key.delete") : _t("shortcuts.key.backspace"), - "\u2326": mac ? "\u2326 " + _t("shortcuts.key.del") : _t("shortcuts.key.del"), - "\u2196": mac ? "\u2196 " + _t("shortcuts.key.pgup") : _t("shortcuts.key.pgup"), - "\u2198": mac ? "\u2198 " + _t("shortcuts.key.pgdn") : _t("shortcuts.key.pgdn"), - "\u21DE": mac ? "\u21DE " + _t("shortcuts.key.home") : _t("shortcuts.key.home"), - "\u21DF": mac ? "\u21DF " + _t("shortcuts.key.end") : _t("shortcuts.key.end"), - "\u21B5": mac ? "\u23CE " + _t("shortcuts.key.return") : _t("shortcuts.key.enter"), - "\u238B": mac ? "\u238B " + _t("shortcuts.key.esc") : _t("shortcuts.key.esc"), - "\u2630": mac ? "\u2630 " + _t("shortcuts.key.menu") : _t("shortcuts.key.menu") - }; - return replacements[code] || code; - }; - - // modules/operations/delete.js - function operationDelete(context, selectedIDs) { - var multi = selectedIDs.length === 1 ? "single" : "multiple"; - var action = actionDeleteMultiple(selectedIDs); - var nodes = utilGetAllNodes(selectedIDs, context.graph()); - var coords = nodes.map(function(n2) { - return n2.loc; - }); - var extent = utilTotalExtent(selectedIDs, context.graph()); - var operation = function() { - var nextSelectedID; - var nextSelectedLoc; - if (selectedIDs.length === 1) { - var id2 = selectedIDs[0]; - var entity = context.entity(id2); - var geometry = entity.geometry(context.graph()); - var parents = context.graph().parentWays(entity); - var parent = parents[0]; - if (geometry === "vertex") { - var nodes2 = parent.nodes; - var i2 = nodes2.indexOf(id2); - if (i2 === 0) { - i2++; - } else if (i2 === nodes2.length - 1) { - i2--; - } else { - var a = geoSphericalDistance(entity.loc, context.entity(nodes2[i2 - 1]).loc); - var b = geoSphericalDistance(entity.loc, context.entity(nodes2[i2 + 1]).loc); - i2 = a < b ? i2 - 1 : i2 + 1; - } - nextSelectedID = nodes2[i2]; - nextSelectedLoc = context.entity(nextSelectedID).loc; - } + function keyup(d3_event) { + if (_altDisables && d3_event.keyCode === utilKeybinding.modifierCodes.alt) { + _selection.selectAll(".hover-suppressed").classed("hover-suppressed", false).classed("hover", true); + _selection.classed("hover-disabled", false); + dispatch10.call("hover", this, _targets); } - context.perform(action, operation.annotation()); - context.validator().validate(); - if (nextSelectedID && nextSelectedLoc) { - if (context.hasEntity(nextSelectedID)) { - context.enter(modeSelect(context, [nextSelectedID]).follow(true)); - } else { - context.map().centerEase(nextSelectedLoc); - context.enter(modeBrowse(context)); - } + } + function behavior(selection2) { + _selection = selection2; + _targets = []; + if (_initialNodeID) { + _newNodeId = _initialNodeID; + _initialNodeID = null; } else { - context.enter(modeBrowse(context)); + _newNodeId = null; } - }; - operation.available = function() { - return true; - }; - operation.disabled = function() { - if (extent.percentContainedIn(context.map().extent()) < 0.8) { - return "too_large"; - } else if (someMissing()) { - return "not_downloaded"; - } else if (selectedIDs.some(context.hasHiddenConnections)) { - return "connected_to_hidden"; - } else if (selectedIDs.some(protectedMember)) { - return "part_of_relation"; - } else if (selectedIDs.some(incompleteRelation)) { - return "incomplete_relation"; - } else if (selectedIDs.some(hasWikidataTag)) { - return "has_wikidata_tag"; + _selection.on(_pointerPrefix + "over.hover", pointerover).on(_pointerPrefix + "out.hover", pointerout).on(_pointerPrefix + "down.hover", pointerover); + select_default2(window).on(_pointerPrefix + "up.hover pointercancel.hover", pointerout, true).on("keydown.hover", keydown).on("keyup.hover", keyup); + function eventTarget(d3_event) { + var datum2 = d3_event.target && d3_event.target.__data__; + if (typeof datum2 !== "object") + return null; + if (!(datum2 instanceof osmEntity) && datum2.properties && datum2.properties.entity instanceof osmEntity) { + return datum2.properties.entity; + } + return datum2; } - return false; - function someMissing() { - if (context.inIntro()) - return false; - var osm = context.connection(); - if (osm) { - var missing = coords.filter(function(loc) { - return !osm.isDataLoaded(loc); - }); - if (missing.length) { - missing.forEach(function(loc) { - context.loadTileAtLoc(loc); - }); - return true; - } + function pointerover(d3_event) { + if (context.mode().id.indexOf("drag") === -1 && (!d3_event.pointerType || d3_event.pointerType === "mouse") && d3_event.buttons) + return; + var target = eventTarget(d3_event); + if (target && _targets.indexOf(target) === -1) { + _targets.push(target); + updateHover(d3_event, _targets); } - return false; } - function hasWikidataTag(id2) { - var entity = context.entity(id2); - return entity.tags.wikidata && entity.tags.wikidata.trim().length > 0; + function pointerout(d3_event) { + var target = eventTarget(d3_event); + var index = _targets.indexOf(target); + if (index !== -1) { + _targets.splice(index); + updateHover(d3_event, _targets); + } } - function incompleteRelation(id2) { - var entity = context.entity(id2); - return entity.type === "relation" && !entity.isComplete(context.graph()); + function allowsVertex(d) { + return d.geometry(context.graph()) === "vertex" || _mainPresetIndex.allowsVertex(d, context.graph()); } - function protectedMember(id2) { - var entity = context.entity(id2); - if (entity.type !== "way") - return false; - var parents = context.graph().parentRelations(entity); - for (var i2 = 0; i2 < parents.length; i2++) { - var parent = parents[i2]; - var type3 = parent.tags.type; - var role = parent.memberById(id2).role || "outer"; - if (type3 === "route" || type3 === "boundary" || type3 === "multipolygon" && role === "outer") { - return true; + function modeAllowsHover(target) { + var mode = context.mode(); + if (mode.id === "add-point") { + return mode.preset.matchGeometry("vertex") || target.type !== "way" && target.geometry(context.graph()) !== "vertex"; + } + return true; + } + function updateHover(d3_event, targets) { + _selection.selectAll(".hover").classed("hover", false); + _selection.selectAll(".hover-suppressed").classed("hover-suppressed", false); + var mode = context.mode(); + if (!_newNodeId && (mode.id === "draw-line" || mode.id === "draw-area")) { + var node = targets.find(function(target) { + return target instanceof osmEntity && target.type === "node"; + }); + _newNodeId = node && node.id; + } + targets = targets.filter(function(datum3) { + if (datum3 instanceof osmEntity) { + return datum3.id !== _newNodeId && (datum3.type !== "node" || !_ignoreVertex || allowsVertex(datum3)) && modeAllowsHover(datum3); + } + return true; + }); + var selector = ""; + for (var i2 in targets) { + var datum2 = targets[i2]; + if (datum2.__featurehash__) { + selector += ", .data" + datum2.__featurehash__; + } else if (datum2 instanceof QAItem) { + selector += ", ." + datum2.service + ".itemId-" + datum2.id; + } else if (datum2 instanceof osmNote) { + selector += ", .note-" + datum2.id; + } else if (datum2 instanceof osmEntity) { + selector += ", ." + datum2.id; + if (datum2.type === "relation") { + for (var j2 in datum2.members) { + selector += ", ." + datum2.members[j2].id; + } + } } } - return false; + var suppressed = _altDisables && d3_event && d3_event.altKey; + if (selector.trim().length) { + selector = selector.slice(1); + _selection.selectAll(selector).classed(suppressed ? "hover-suppressed" : "hover", true); + } + dispatch10.call("hover", this, !suppressed && targets); } + } + behavior.off = function(selection2) { + selection2.selectAll(".hover").classed("hover", false); + selection2.selectAll(".hover-suppressed").classed("hover-suppressed", false); + selection2.classed("hover-disabled", false); + selection2.on(_pointerPrefix + "over.hover", null).on(_pointerPrefix + "out.hover", null).on(_pointerPrefix + "down.hover", null); + select_default2(window).on(_pointerPrefix + "up.hover pointercancel.hover", null, true).on("keydown.hover", null).on("keyup.hover", null); }; - operation.tooltip = function() { - var disable = operation.disabled(); - return disable ? _t.append("operations.delete." + disable + "." + multi) : _t.append("operations.delete.description." + multi); + behavior.altDisables = function(val) { + if (!arguments.length) + return _altDisables; + _altDisables = val; + return behavior; }; - operation.annotation = function() { - return selectedIDs.length === 1 ? _t("operations.delete.annotation." + context.graph().geometry(selectedIDs[0])) : _t("operations.delete.annotation.feature", { n: selectedIDs.length }); + behavior.ignoreVertex = function(val) { + if (!arguments.length) + return _ignoreVertex; + _ignoreVertex = val; + return behavior; }; - operation.id = "delete"; - operation.keys = [uiCmd("\u2318\u232B"), uiCmd("\u2318\u2326"), uiCmd("\u2326")]; - operation.title = _t.append("operations.delete.title"); - operation.behavior = behaviorOperation(context).which(operation); - return operation; + behavior.initialNodeID = function(nodeId) { + _initialNodeID = nodeId; + return behavior; + }; + return utilRebind(behavior, dispatch10, "on"); } - // modules/operations/orthogonalize.js - function operationOrthogonalize(context, selectedIDs) { - var _extent; - var _type; - var _actions = selectedIDs.map(chooseAction).filter(Boolean); - var _amount = _actions.length === 1 ? "single" : "multiple"; - var _coords = utilGetAllNodes(selectedIDs, context.graph()).map(function(n2) { - return n2.loc; - }); - function chooseAction(entityID) { - var entity = context.entity(entityID); - var geometry = entity.geometry(context.graph()); - if (!_extent) { - _extent = entity.extent(context.graph()); + // modules/behavior/draw.js + var _disableSpace = false; + var _lastSpace = null; + function behaviorDraw(context) { + var dispatch10 = dispatch_default( + "move", + "down", + "downcancel", + "click", + "clickWay", + "clickNode", + "undo", + "cancel", + "finish" + ); + var keybinding = utilKeybinding("draw"); + var _hover = behaviorHover(context).altDisables(true).ignoreVertex(true).on("hover", context.ui().sidebar.hover); + var _edit = behaviorEdit(context); + var _closeTolerance = 4; + var _tolerance = 12; + var _mouseLeave = false; + var _lastMouse = null; + var _lastPointerUpEvent; + var _downPointer; + var _pointerPrefix = "PointerEvent" in window ? "pointer" : "mouse"; + function datum2(d3_event) { + var mode = context.mode(); + var isNote = mode && mode.id.indexOf("note") !== -1; + if (d3_event.altKey || isNote) + return {}; + var element; + if (d3_event.type === "keydown") { + element = _lastMouse && _lastMouse.target; } else { - _extent = _extent.extend(entity.extent(context.graph())); + element = d3_event.target; } - if (entity.type === "way" && new Set(entity.nodes).size > 2) { - if (_type && _type !== "feature") - return null; - _type = "feature"; - return actionOrthogonalize(entityID, context.projection); - } else if (geometry === "vertex") { - if (_type && _type !== "corner") - return null; - _type = "corner"; - var graph = context.graph(); - var parents = graph.parentWays(entity); - if (parents.length === 1) { - var way = parents[0]; - if (way.nodes.indexOf(entityID) !== -1) { - return actionOrthogonalize(way.id, context.projection, entityID); - } + var d = element.__data__; + return d && d.properties && d.properties.target ? d : {}; + } + function pointerdown(d3_event) { + if (_downPointer) + return; + var pointerLocGetter = utilFastMouse(this); + _downPointer = { + id: d3_event.pointerId || "mouse", + pointerLocGetter, + downTime: +/* @__PURE__ */ new Date(), + downLoc: pointerLocGetter(d3_event) + }; + dispatch10.call("down", this, d3_event, datum2(d3_event)); + } + function pointerup(d3_event) { + if (!_downPointer || _downPointer.id !== (d3_event.pointerId || "mouse")) + return; + var downPointer = _downPointer; + _downPointer = null; + _lastPointerUpEvent = d3_event; + if (downPointer.isCancelled) + return; + var t2 = +/* @__PURE__ */ new Date(); + var p2 = downPointer.pointerLocGetter(d3_event); + var dist = geoVecLength(downPointer.downLoc, p2); + if (dist < _closeTolerance || dist < _tolerance && t2 - downPointer.downTime < 500) { + select_default2(window).on("click.draw-block", function() { + d3_event.stopPropagation(); + }, true); + context.map().dblclickZoomEnable(false); + window.setTimeout(function() { + context.map().dblclickZoomEnable(true); + select_default2(window).on("click.draw-block", null); + }, 500); + click(d3_event, p2); + } + } + function pointermove(d3_event) { + if (_downPointer && _downPointer.id === (d3_event.pointerId || "mouse") && !_downPointer.isCancelled) { + var p2 = _downPointer.pointerLocGetter(d3_event); + var dist = geoVecLength(_downPointer.downLoc, p2); + if (dist >= _closeTolerance) { + _downPointer.isCancelled = true; + dispatch10.call("downcancel", this); } } - return null; + if (d3_event.pointerType && d3_event.pointerType !== "mouse" || d3_event.buttons || _downPointer) + return; + if (_lastPointerUpEvent && _lastPointerUpEvent.pointerType !== "mouse" && d3_event.timeStamp - _lastPointerUpEvent.timeStamp < 100) + return; + _lastMouse = d3_event; + dispatch10.call("move", this, d3_event, datum2(d3_event)); } - var operation = function() { - if (!_actions.length) + function pointercancel(d3_event) { + if (_downPointer && _downPointer.id === (d3_event.pointerId || "mouse")) { + if (!_downPointer.isCancelled) { + dispatch10.call("downcancel", this); + } + _downPointer = null; + } + } + function mouseenter() { + _mouseLeave = false; + } + function mouseleave() { + _mouseLeave = true; + } + function allowsVertex(d) { + return d.geometry(context.graph()) === "vertex" || _mainPresetIndex.allowsVertex(d, context.graph()); + } + function click(d3_event, loc) { + var d = datum2(d3_event); + var target = d && d.properties && d.properties.entity; + var mode = context.mode(); + if (target && target.type === "node" && allowsVertex(target)) { + dispatch10.call("clickNode", this, target, d); return; - var combinedAction = function(graph, t) { - _actions.forEach(function(action) { - if (!action.disabled(graph)) { - graph = action(graph, t); - } - }); - return graph; - }; - combinedAction.transitionable = true; - context.perform(combinedAction, operation.annotation()); - window.setTimeout(function() { - context.validator().validate(); - }, 300); - }; - operation.available = function() { - return _actions.length && selectedIDs.length === _actions.length; - }; - operation.disabled = function() { - if (!_actions.length) - return ""; - var actionDisableds = _actions.map(function(action) { - return action.disabled(context.graph()); - }).filter(Boolean); - if (actionDisableds.length === _actions.length) { - if (new Set(actionDisableds).size > 1) { - return "multiple_blockers"; + } else if (target && target.type === "way" && (mode.id !== "add-point" || mode.preset.matchGeometry("vertex"))) { + var choice = geoChooseEdge( + context.graph().childNodes(target), + loc, + context.projection, + context.activeID() + ); + if (choice) { + var edge = [target.nodes[choice.index - 1], target.nodes[choice.index]]; + dispatch10.call("clickWay", this, choice.loc, edge, d); + return; } - return actionDisableds[0]; - } else if (_extent && _extent.percentContainedIn(context.map().extent()) < 0.8) { - return "too_large"; - } else if (someMissing()) { - return "not_downloaded"; - } else if (selectedIDs.some(context.hasHiddenConnections)) { - return "connected_to_hidden"; + } else if (mode.id !== "add-point" || mode.preset.matchGeometry("point")) { + var locLatLng = context.projection.invert(loc); + dispatch10.call("click", this, locLatLng, d); } - return false; - function someMissing() { - if (context.inIntro()) - return false; - var osm = context.connection(); - if (osm) { - var missing = _coords.filter(function(loc) { - return !osm.isDataLoaded(loc); - }); - if (missing.length) { - missing.forEach(function(loc) { - context.loadTileAtLoc(loc); - }); - return true; - } + } + function space(d3_event) { + d3_event.preventDefault(); + d3_event.stopPropagation(); + var currSpace = context.map().mouse(); + if (_disableSpace && _lastSpace) { + var dist = geoVecLength(_lastSpace, currSpace); + if (dist > _tolerance) { + _disableSpace = false; } - return false; } + if (_disableSpace || _mouseLeave || !_lastMouse) + return; + _lastSpace = currSpace; + _disableSpace = true; + select_default2(window).on("keyup.space-block", function() { + d3_event.preventDefault(); + d3_event.stopPropagation(); + _disableSpace = false; + select_default2(window).on("keyup.space-block", null); + }); + var loc = context.map().mouse() || // or the map center if the mouse has never entered the map + context.projection(context.map().center()); + click(d3_event, loc); + } + function backspace(d3_event) { + d3_event.preventDefault(); + dispatch10.call("undo"); + } + function del(d3_event) { + d3_event.preventDefault(); + dispatch10.call("cancel"); + } + function ret(d3_event) { + d3_event.preventDefault(); + dispatch10.call("finish"); + } + function behavior(selection2) { + context.install(_hover); + context.install(_edit); + _downPointer = null; + keybinding.on("\u232B", backspace).on("\u2326", del).on("\u238B", ret).on("\u21A9", ret).on("space", space).on("\u2325space", space); + selection2.on("mouseenter.draw", mouseenter).on("mouseleave.draw", mouseleave).on(_pointerPrefix + "down.draw", pointerdown).on(_pointerPrefix + "move.draw", pointermove); + select_default2(window).on(_pointerPrefix + "up.draw", pointerup, true).on("pointercancel.draw", pointercancel, true); + select_default2(document).call(keybinding); + return behavior; + } + behavior.off = function(selection2) { + context.ui().sidebar.hover.cancel(); + context.uninstall(_hover); + context.uninstall(_edit); + selection2.on("mouseenter.draw", null).on("mouseleave.draw", null).on(_pointerPrefix + "down.draw", null).on(_pointerPrefix + "move.draw", null); + select_default2(window).on(_pointerPrefix + "up.draw", null).on("pointercancel.draw", null); + select_default2(document).call(keybinding.unbind); }; - operation.tooltip = function() { - var disable = operation.disabled(); - return disable ? _t.append("operations.orthogonalize." + disable + "." + _amount) : _t.append("operations.orthogonalize.description." + _type + "." + _amount); + behavior.hover = function() { + return _hover; }; - operation.annotation = function() { - return _t("operations.orthogonalize.annotation." + _type, { n: _actions.length }); + return utilRebind(behavior, dispatch10, "on"); + } + + // modules/behavior/breathe.js + var import_fast_deep_equal2 = __toESM(require_fast_deep_equal()); + + // node_modules/d3-scale/src/init.js + function initRange(domain2, range3) { + switch (arguments.length) { + case 0: + break; + case 1: + this.range(domain2); + break; + default: + this.range(range3).domain(domain2); + break; + } + return this; + } + + // node_modules/d3-scale/src/constant.js + function constants(x) { + return function() { + return x; }; - operation.id = "orthogonalize"; - operation.keys = [_t("operations.orthogonalize.key")]; - operation.title = _t.append("operations.orthogonalize.title"); - operation.behavior = behaviorOperation(context).which(operation); - return operation; } - // modules/operations/reflect.js - function operationReflectShort(context, selectedIDs) { - return operationReflect(context, selectedIDs, "short"); + // node_modules/d3-scale/src/number.js + function number2(x) { + return +x; } - function operationReflectLong(context, selectedIDs) { - return operationReflect(context, selectedIDs, "long"); + + // node_modules/d3-scale/src/continuous.js + var unit = [0, 1]; + function identity3(x) { + return x; } - function operationReflect(context, selectedIDs, axis) { - axis = axis || "long"; - var multi = selectedIDs.length === 1 ? "single" : "multiple"; - var nodes = utilGetAllNodes(selectedIDs, context.graph()); - var coords = nodes.map(function(n2) { - return n2.loc; - }); - var extent = utilTotalExtent(selectedIDs, context.graph()); - var operation = function() { - var action = actionReflect(selectedIDs, context.projection).useLongAxis(Boolean(axis === "long")); - context.perform(action, operation.annotation()); - window.setTimeout(function() { - context.validator().validate(); - }, 300); + function normalize(a, b) { + return (b -= a = +a) ? function(x) { + return (x - a) / b; + } : constants(isNaN(b) ? NaN : 0.5); + } + function clamper(a, b) { + var t; + if (a > b) + t = a, a = b, b = t; + return function(x) { + return Math.max(a, Math.min(b, x)); }; - operation.available = function() { - return nodes.length >= 3; + } + function bimap(domain2, range3, interpolate) { + var d0 = domain2[0], d1 = domain2[1], r0 = range3[0], r1 = range3[1]; + if (d1 < d0) + d0 = normalize(d1, d0), r0 = interpolate(r1, r0); + else + d0 = normalize(d0, d1), r0 = interpolate(r0, r1); + return function(x) { + return r0(d0(x)); }; - operation.disabled = function() { - if (extent.percentContainedIn(context.map().extent()) < 0.8) { - return "too_large"; - } else if (someMissing()) { - return "not_downloaded"; - } else if (selectedIDs.some(context.hasHiddenConnections)) { - return "connected_to_hidden"; - } else if (selectedIDs.some(incompleteRelation)) { - return "incomplete_relation"; - } - return false; - function someMissing() { - if (context.inIntro()) - return false; - var osm = context.connection(); - if (osm) { - var missing = coords.filter(function(loc) { - return !osm.isDataLoaded(loc); - }); - if (missing.length) { - missing.forEach(function(loc) { - context.loadTileAtLoc(loc); - }); - return true; - } - } - return false; - } - function incompleteRelation(id2) { - var entity = context.entity(id2); - return entity.type === "relation" && !entity.isComplete(context.graph()); - } - }; - operation.tooltip = function() { - var disable = operation.disabled(); - return disable ? _t.append("operations.reflect." + disable + "." + multi) : _t.append("operations.reflect.description." + axis + "." + multi); - }; - operation.annotation = function() { - return _t("operations.reflect.annotation." + axis + ".feature", { n: selectedIDs.length }); - }; - operation.id = "reflect-" + axis; - operation.keys = [_t("operations.reflect.key." + axis)]; - operation.title = _t.append("operations.reflect.title." + axis); - operation.behavior = behaviorOperation(context).which(operation); - return operation; - } - - // modules/operations/move.js - function operationMove(context, selectedIDs) { - var multi = selectedIDs.length === 1 ? "single" : "multiple"; - var nodes = utilGetAllNodes(selectedIDs, context.graph()); - var coords = nodes.map(function(n2) { - return n2.loc; - }); - var extent = utilTotalExtent(selectedIDs, context.graph()); - var operation = function() { - context.enter(modeMove(context, selectedIDs)); - }; - operation.available = function() { - return selectedIDs.length > 0; - }; - operation.disabled = function() { - if (extent.percentContainedIn(context.map().extent()) < 0.8) { - return "too_large"; - } else if (someMissing()) { - return "not_downloaded"; - } else if (selectedIDs.some(context.hasHiddenConnections)) { - return "connected_to_hidden"; - } else if (selectedIDs.some(incompleteRelation)) { - return "incomplete_relation"; - } - return false; - function someMissing() { - if (context.inIntro()) - return false; - var osm = context.connection(); - if (osm) { - var missing = coords.filter(function(loc) { - return !osm.isDataLoaded(loc); - }); - if (missing.length) { - missing.forEach(function(loc) { - context.loadTileAtLoc(loc); - }); - return true; - } - } - return false; - } - function incompleteRelation(id2) { - var entity = context.entity(id2); - return entity.type === "relation" && !entity.isComplete(context.graph()); - } - }; - operation.tooltip = function() { - var disable = operation.disabled(); - return disable ? _t.append("operations.move." + disable + "." + multi) : _t.append("operations.move.description." + multi); - }; - operation.annotation = function() { - return selectedIDs.length === 1 ? _t("operations.move.annotation." + context.graph().geometry(selectedIDs[0])) : _t("operations.move.annotation.feature", { n: selectedIDs.length }); - }; - operation.id = "move"; - operation.keys = [_t("operations.move.key")]; - operation.title = _t.append("operations.move.title"); - operation.behavior = behaviorOperation(context).which(operation); - operation.mouseOnly = true; - return operation; } - - // modules/modes/rotate.js - function modeRotate(context, entityIDs) { - var _tolerancePx = 4; - var mode = { - id: "rotate", - button: "browse" - }; - var keybinding = utilKeybinding("rotate"); - var behaviors = [ - behaviorEdit(context), - operationCircularize(context, entityIDs).behavior, - operationDelete(context, entityIDs).behavior, - operationMove(context, entityIDs).behavior, - operationOrthogonalize(context, entityIDs).behavior, - operationReflectLong(context, entityIDs).behavior, - operationReflectShort(context, entityIDs).behavior - ]; - var annotation = entityIDs.length === 1 ? _t("operations.rotate.annotation." + context.graph().geometry(entityIDs[0])) : _t("operations.rotate.annotation.feature", { n: entityIDs.length }); - var _prevGraph; - var _prevAngle; - var _prevTransform; - var _pivot; - var _pointerPrefix = "PointerEvent" in window ? "pointer" : "mouse"; - function doRotate(d3_event) { - var fn; - if (context.graph() !== _prevGraph) { - fn = context.perform; - } else { - fn = context.replace; - } - var projection2 = context.projection; - var currTransform = projection2.transform(); - if (!_prevTransform || currTransform.k !== _prevTransform.k || currTransform.x !== _prevTransform.x || currTransform.y !== _prevTransform.y) { - var nodes = utilGetAllNodes(entityIDs, context.graph()); - var points = nodes.map(function(n2) { - return projection2(n2.loc); - }); - _pivot = getPivot(points); - _prevAngle = void 0; - } - var currMouse = context.map().mouse(d3_event); - var currAngle = Math.atan2(currMouse[1] - _pivot[1], currMouse[0] - _pivot[0]); - if (typeof _prevAngle === "undefined") - _prevAngle = currAngle; - var delta = currAngle - _prevAngle; - fn(actionRotate(entityIDs, _pivot, delta, projection2)); - _prevTransform = currTransform; - _prevAngle = currAngle; - _prevGraph = context.graph(); - } - function getPivot(points) { - var _pivot2; - if (points.length === 1) { - _pivot2 = points[0]; - } else if (points.length === 2) { - _pivot2 = geoVecInterp(points[0], points[1], 0.5); - } else { - var polygonHull = hull_default(points); - if (polygonHull.length === 2) { - _pivot2 = geoVecInterp(points[0], points[1], 0.5); - } else { - _pivot2 = centroid_default2(hull_default(points)); - } - } - return _pivot2; + function polymap(domain2, range3, interpolate) { + var j2 = Math.min(domain2.length, range3.length) - 1, d = new Array(j2), r = new Array(j2), i2 = -1; + if (domain2[j2] < domain2[0]) { + domain2 = domain2.slice().reverse(); + range3 = range3.slice().reverse(); } - function finish(d3_event) { - d3_event.stopPropagation(); - context.replace(actionNoop(), annotation); - context.enter(modeSelect(context, entityIDs)); + while (++i2 < j2) { + d[i2] = normalize(domain2[i2], domain2[i2 + 1]); + r[i2] = interpolate(range3[i2], range3[i2 + 1]); } - function cancel() { - if (_prevGraph) - context.pop(); - context.enter(modeSelect(context, entityIDs)); + return function(x) { + var i3 = bisect_default(domain2, x, 1, j2) - 1; + return r[i3](d[i3](x)); + }; + } + function copy(source, target) { + return target.domain(source.domain()).range(source.range()).interpolate(source.interpolate()).clamp(source.clamp()).unknown(source.unknown()); + } + function transformer2() { + var domain2 = unit, range3 = unit, interpolate = value_default, transform2, untransform, unknown, clamp3 = identity3, piecewise, output, input; + function rescale() { + var n2 = Math.min(domain2.length, range3.length); + if (clamp3 !== identity3) + clamp3 = clamper(domain2[0], domain2[n2 - 1]); + piecewise = n2 > 2 ? polymap : bimap; + output = input = null; + return scale; } - function undone() { - context.enter(modeBrowse(context)); + function scale(x) { + return x == null || isNaN(x = +x) ? unknown : (output || (output = piecewise(domain2.map(transform2), range3, interpolate)))(transform2(clamp3(x))); } - mode.enter = function() { - _prevGraph = null; - context.features().forceVisible(entityIDs); - behaviors.forEach(context.install); - var downEvent; - context.surface().on(_pointerPrefix + "down.modeRotate", function(d3_event) { - downEvent = d3_event; - }); - select_default2(window).on(_pointerPrefix + "move.modeRotate", doRotate, true).on(_pointerPrefix + "up.modeRotate", function(d3_event) { - if (!downEvent) - return; - var mapNode = context.container().select(".main-map").node(); - var pointGetter = utilFastMouse(mapNode); - var p1 = pointGetter(downEvent); - var p2 = pointGetter(d3_event); - var dist = geoVecLength(p1, p2); - if (dist <= _tolerancePx) - finish(d3_event); - downEvent = null; - }, true); - context.history().on("undone.modeRotate", undone); - keybinding.on("\u238B", cancel).on("\u21A9", finish); - select_default2(document).call(keybinding); + scale.invert = function(y) { + return clamp3(untransform((input || (input = piecewise(range3, domain2.map(transform2), number_default)))(y))); }; - mode.exit = function() { - behaviors.forEach(context.uninstall); - context.surface().on(_pointerPrefix + "down.modeRotate", null); - select_default2(window).on(_pointerPrefix + "move.modeRotate", null, true).on(_pointerPrefix + "up.modeRotate", null, true); - context.history().on("undone.modeRotate", null); - select_default2(document).call(keybinding.unbind); - context.features().forceVisible([]); + scale.domain = function(_) { + return arguments.length ? (domain2 = Array.from(_, number2), rescale()) : domain2.slice(); }; - mode.selectedIDs = function() { - if (!arguments.length) - return entityIDs; - return mode; + scale.range = function(_) { + return arguments.length ? (range3 = Array.from(_), rescale()) : range3.slice(); }; - return mode; - } - - // modules/operations/rotate.js - function operationRotate(context, selectedIDs) { - var multi = selectedIDs.length === 1 ? "single" : "multiple"; - var nodes = utilGetAllNodes(selectedIDs, context.graph()); - var coords = nodes.map(function(n2) { - return n2.loc; - }); - var extent = utilTotalExtent(selectedIDs, context.graph()); - var operation = function() { - context.enter(modeRotate(context, selectedIDs)); + scale.rangeRound = function(_) { + return range3 = Array.from(_), interpolate = round_default, rescale(); }; - operation.available = function() { - return nodes.length >= 2; + scale.clamp = function(_) { + return arguments.length ? (clamp3 = _ ? true : identity3, rescale()) : clamp3 !== identity3; }; - operation.disabled = function() { - if (extent.percentContainedIn(context.map().extent()) < 0.8) { - return "too_large"; - } else if (someMissing()) { - return "not_downloaded"; - } else if (selectedIDs.some(context.hasHiddenConnections)) { - return "connected_to_hidden"; - } else if (selectedIDs.some(incompleteRelation)) { - return "incomplete_relation"; - } - return false; - function someMissing() { - if (context.inIntro()) - return false; - var osm = context.connection(); - if (osm) { - var missing = coords.filter(function(loc) { - return !osm.isDataLoaded(loc); - }); - if (missing.length) { - missing.forEach(function(loc) { - context.loadTileAtLoc(loc); - }); - return true; - } - } - return false; - } - function incompleteRelation(id2) { - var entity = context.entity(id2); - return entity.type === "relation" && !entity.isComplete(context.graph()); - } + scale.interpolate = function(_) { + return arguments.length ? (interpolate = _, rescale()) : interpolate; }; - operation.tooltip = function() { - var disable = operation.disabled(); - return disable ? _t.append("operations.rotate." + disable + "." + multi) : _t.append("operations.rotate.description." + multi); + scale.unknown = function(_) { + return arguments.length ? (unknown = _, scale) : unknown; }; - operation.annotation = function() { - return selectedIDs.length === 1 ? _t("operations.rotate.annotation." + context.graph().geometry(selectedIDs[0])) : _t("operations.rotate.annotation.feature", { n: selectedIDs.length }); + return function(t, u) { + transform2 = t, untransform = u; + return rescale(); }; - operation.id = "rotate"; - operation.keys = [_t("operations.rotate.key")]; - operation.title = _t.append("operations.rotate.title"); - operation.behavior = behaviorOperation(context).which(operation); - operation.mouseOnly = true; - return operation; + } + function continuous() { + return transformer2()(identity3, identity3); } - // modules/modes/move.js - function modeMove(context, entityIDs, baseGraph) { - var _tolerancePx = 4; - var mode = { - id: "move", - button: "browse" - }; - var keybinding = utilKeybinding("move"); - var behaviors = [ - behaviorEdit(context), - operationCircularize(context, entityIDs).behavior, - operationDelete(context, entityIDs).behavior, - operationOrthogonalize(context, entityIDs).behavior, - operationReflectLong(context, entityIDs).behavior, - operationReflectShort(context, entityIDs).behavior, - operationRotate(context, entityIDs).behavior + // node_modules/d3-format/src/formatDecimal.js + function formatDecimal_default(x) { + return Math.abs(x = Math.round(x)) >= 1e21 ? x.toLocaleString("en").replace(/,/g, "") : x.toString(10); + } + function formatDecimalParts(x, p) { + if ((i2 = (x = p ? x.toExponential(p - 1) : x.toExponential()).indexOf("e")) < 0) + return null; + var i2, coefficient = x.slice(0, i2); + return [ + coefficient.length > 1 ? coefficient[0] + coefficient.slice(2) : coefficient, + +x.slice(i2 + 1) ]; - var annotation = entityIDs.length === 1 ? _t("operations.move.annotation." + context.graph().geometry(entityIDs[0])) : _t("operations.move.annotation.feature", { n: entityIDs.length }); - var _prevGraph; - var _cache4; - var _origin; - var _nudgeInterval; - var _pointerPrefix = "PointerEvent" in window ? "pointer" : "mouse"; - function doMove(nudge) { - nudge = nudge || [0, 0]; - var fn; - if (_prevGraph !== context.graph()) { - _cache4 = {}; - _origin = context.map().mouseCoordinates(); - fn = context.perform; - } else { - fn = context.overwrite; - } - var currMouse = context.map().mouse(); - var origMouse = context.projection(_origin); - var delta = geoVecSubtract(geoVecSubtract(currMouse, origMouse), nudge); - fn(actionMove(entityIDs, delta, context.projection, _cache4)); - _prevGraph = context.graph(); - } - function startNudge(nudge) { - if (_nudgeInterval) - window.clearInterval(_nudgeInterval); - _nudgeInterval = window.setInterval(function() { - context.map().pan(nudge); - doMove(nudge); - }, 50); - } - function stopNudge() { - if (_nudgeInterval) { - window.clearInterval(_nudgeInterval); - _nudgeInterval = null; - } - } - function move() { - doMove(); - var nudge = geoViewportEdge(context.map().mouse(), context.map().dimensions()); - if (nudge) { - startNudge(nudge); - } else { - stopNudge(); - } - } - function finish(d3_event) { - d3_event.stopPropagation(); - context.replace(actionNoop(), annotation); - context.enter(modeSelect(context, entityIDs)); - stopNudge(); - } - function cancel() { - if (baseGraph) { - while (context.graph() !== baseGraph) - context.pop(); - context.enter(modeBrowse(context)); - } else { - if (_prevGraph) - context.pop(); - context.enter(modeSelect(context, entityIDs)); + } + + // node_modules/d3-format/src/exponent.js + function exponent_default(x) { + return x = formatDecimalParts(Math.abs(x)), x ? x[1] : NaN; + } + + // node_modules/d3-format/src/formatGroup.js + function formatGroup_default(grouping, thousands) { + return function(value, width) { + var i2 = value.length, t = [], j2 = 0, g = grouping[0], length = 0; + while (i2 > 0 && g > 0) { + if (length + g + 1 > width) + g = Math.max(1, width - length); + t.push(value.substring(i2 -= g, i2 + g)); + if ((length += g + 1) > width) + break; + g = grouping[j2 = (j2 + 1) % grouping.length]; } - stopNudge(); - } - function undone() { - context.enter(modeBrowse(context)); - } - mode.enter = function() { - _origin = context.map().mouseCoordinates(); - _prevGraph = null; - _cache4 = {}; - context.features().forceVisible(entityIDs); - behaviors.forEach(context.install); - var downEvent; - context.surface().on(_pointerPrefix + "down.modeMove", function(d3_event) { - downEvent = d3_event; - }); - select_default2(window).on(_pointerPrefix + "move.modeMove", move, true).on(_pointerPrefix + "up.modeMove", function(d3_event) { - if (!downEvent) - return; - var mapNode = context.container().select(".main-map").node(); - var pointGetter = utilFastMouse(mapNode); - var p1 = pointGetter(downEvent); - var p2 = pointGetter(d3_event); - var dist = geoVecLength(p1, p2); - if (dist <= _tolerancePx) - finish(d3_event); - downEvent = null; - }, true); - context.history().on("undone.modeMove", undone); - keybinding.on("\u238B", cancel).on("\u21A9", finish); - select_default2(document).call(keybinding); + return t.reverse().join(thousands); }; - mode.exit = function() { - stopNudge(); - behaviors.forEach(function(behavior) { - context.uninstall(behavior); + } + + // node_modules/d3-format/src/formatNumerals.js + function formatNumerals_default(numerals) { + return function(value) { + return value.replace(/[0-9]/g, function(i2) { + return numerals[+i2]; }); - context.surface().on(_pointerPrefix + "down.modeMove", null); - select_default2(window).on(_pointerPrefix + "move.modeMove", null, true).on(_pointerPrefix + "up.modeMove", null, true); - context.history().on("undone.modeMove", null); - select_default2(document).call(keybinding.unbind); - context.features().forceVisible([]); - }; - mode.selectedIDs = function() { - if (!arguments.length) - return entityIDs; - return mode; }; - return mode; } - // modules/behavior/paste.js - function behaviorPaste(context) { - function doPaste(d3_event) { - if (!context.map().withinEditableZoom()) - return; - d3_event.preventDefault(); - var baseGraph = context.graph(); - var mouse = context.map().mouse(); - var projection2 = context.projection; - var viewport = geoExtent(projection2.clipExtent()).polygon(); - if (!geoPointInPolygon(mouse, viewport)) - return; - var oldIDs = context.copyIDs(); - if (!oldIDs.length) - return; - var extent = geoExtent(); - var oldGraph = context.copyGraph(); - var newIDs = []; - var action = actionCopyEntities(oldIDs, oldGraph); - context.perform(action); - var copies = action.copies(); - var originals = /* @__PURE__ */ new Set(); - Object.values(copies).forEach(function(entity) { - originals.add(entity.id); - }); - for (var id2 in copies) { - var oldEntity = oldGraph.entity(id2); - var newEntity = copies[id2]; - extent._extend(oldEntity.extent(oldGraph)); - var parents = context.graph().parentWays(newEntity); - var parentCopied = parents.some(function(parent) { - return originals.has(parent.id); - }); - if (!parentCopied) { - newIDs.push(newEntity.id); + // node_modules/d3-format/src/formatSpecifier.js + var re = /^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i; + function formatSpecifier(specifier) { + if (!(match = re.exec(specifier))) + throw new Error("invalid format: " + specifier); + var match; + return new FormatSpecifier({ + fill: match[1], + align: match[2], + sign: match[3], + symbol: match[4], + zero: match[5], + width: match[6], + comma: match[7], + precision: match[8] && match[8].slice(1), + trim: match[9], + type: match[10] + }); + } + formatSpecifier.prototype = FormatSpecifier.prototype; + function FormatSpecifier(specifier) { + this.fill = specifier.fill === void 0 ? " " : specifier.fill + ""; + this.align = specifier.align === void 0 ? ">" : specifier.align + ""; + this.sign = specifier.sign === void 0 ? "-" : specifier.sign + ""; + this.symbol = specifier.symbol === void 0 ? "" : specifier.symbol + ""; + this.zero = !!specifier.zero; + this.width = specifier.width === void 0 ? void 0 : +specifier.width; + this.comma = !!specifier.comma; + this.precision = specifier.precision === void 0 ? void 0 : +specifier.precision; + this.trim = !!specifier.trim; + this.type = specifier.type === void 0 ? "" : specifier.type + ""; + } + FormatSpecifier.prototype.toString = function() { + return this.fill + this.align + this.sign + this.symbol + (this.zero ? "0" : "") + (this.width === void 0 ? "" : Math.max(1, this.width | 0)) + (this.comma ? "," : "") + (this.precision === void 0 ? "" : "." + Math.max(0, this.precision | 0)) + (this.trim ? "~" : "") + this.type; + }; + + // node_modules/d3-format/src/formatTrim.js + function formatTrim_default(s) { + out: + for (var n2 = s.length, i2 = 1, i0 = -1, i1; i2 < n2; ++i2) { + switch (s[i2]) { + case ".": + i0 = i1 = i2; + break; + case "0": + if (i0 === 0) + i0 = i2; + i1 = i2; + break; + default: + if (!+s[i2]) + break out; + if (i0 > 0) + i0 = 0; + break; } } - var copyPoint = context.copyLonLat() && projection2(context.copyLonLat()) || projection2(extent.center()); - var delta = geoVecSubtract(mouse, copyPoint); - context.perform(actionMove(newIDs, delta, projection2)); - context.enter(modeMove(context, newIDs, baseGraph)); + return i0 > 0 ? s.slice(0, i0) + s.slice(i1 + 1) : s; + } + + // node_modules/d3-format/src/formatPrefixAuto.js + var prefixExponent; + function formatPrefixAuto_default(x, p) { + var d = formatDecimalParts(x, p); + if (!d) + return x + ""; + var coefficient = d[0], exponent = d[1], i2 = exponent - (prefixExponent = Math.max(-8, Math.min(8, Math.floor(exponent / 3))) * 3) + 1, n2 = coefficient.length; + return i2 === n2 ? coefficient : i2 > n2 ? coefficient + new Array(i2 - n2 + 1).join("0") : i2 > 0 ? coefficient.slice(0, i2) + "." + coefficient.slice(i2) : "0." + new Array(1 - i2).join("0") + formatDecimalParts(x, Math.max(0, p + i2 - 1))[0]; + } + + // node_modules/d3-format/src/formatRounded.js + function formatRounded_default(x, p) { + var d = formatDecimalParts(x, p); + if (!d) + return x + ""; + var coefficient = d[0], exponent = d[1]; + return exponent < 0 ? "0." + new Array(-exponent).join("0") + coefficient : coefficient.length > exponent + 1 ? coefficient.slice(0, exponent + 1) + "." + coefficient.slice(exponent + 1) : coefficient + new Array(exponent - coefficient.length + 2).join("0"); + } + + // node_modules/d3-format/src/formatTypes.js + var formatTypes_default = { + "%": (x, p) => (x * 100).toFixed(p), + "b": (x) => Math.round(x).toString(2), + "c": (x) => x + "", + "d": formatDecimal_default, + "e": (x, p) => x.toExponential(p), + "f": (x, p) => x.toFixed(p), + "g": (x, p) => x.toPrecision(p), + "o": (x) => Math.round(x).toString(8), + "p": (x, p) => formatRounded_default(x * 100, p), + "r": formatRounded_default, + "s": formatPrefixAuto_default, + "X": (x) => Math.round(x).toString(16).toUpperCase(), + "x": (x) => Math.round(x).toString(16) + }; + + // node_modules/d3-format/src/identity.js + function identity_default3(x) { + return x; + } + + // node_modules/d3-format/src/locale.js + var map = Array.prototype.map; + var prefixes = ["y", "z", "a", "f", "p", "n", "\xB5", "m", "", "k", "M", "G", "T", "P", "E", "Z", "Y"]; + function locale_default(locale2) { + var group = locale2.grouping === void 0 || locale2.thousands === void 0 ? identity_default3 : formatGroup_default(map.call(locale2.grouping, Number), locale2.thousands + ""), currencyPrefix = locale2.currency === void 0 ? "" : locale2.currency[0] + "", currencySuffix = locale2.currency === void 0 ? "" : locale2.currency[1] + "", decimal = locale2.decimal === void 0 ? "." : locale2.decimal + "", numerals = locale2.numerals === void 0 ? identity_default3 : formatNumerals_default(map.call(locale2.numerals, String)), percent = locale2.percent === void 0 ? "%" : locale2.percent + "", minus = locale2.minus === void 0 ? "\u2212" : locale2.minus + "", nan = locale2.nan === void 0 ? "NaN" : locale2.nan + ""; + function newFormat(specifier) { + specifier = formatSpecifier(specifier); + var fill = specifier.fill, align = specifier.align, sign2 = specifier.sign, symbol = specifier.symbol, zero3 = specifier.zero, width = specifier.width, comma = specifier.comma, precision2 = specifier.precision, trim = specifier.trim, type2 = specifier.type; + if (type2 === "n") + comma = true, type2 = "g"; + else if (!formatTypes_default[type2]) + precision2 === void 0 && (precision2 = 12), trim = true, type2 = "g"; + if (zero3 || fill === "0" && align === "=") + zero3 = true, fill = "0", align = "="; + var prefix = symbol === "$" ? currencyPrefix : symbol === "#" && /[boxX]/.test(type2) ? "0" + type2.toLowerCase() : "", suffix = symbol === "$" ? currencySuffix : /[%p]/.test(type2) ? percent : ""; + var formatType = formatTypes_default[type2], maybeSuffix = /[defgprs%]/.test(type2); + precision2 = precision2 === void 0 ? 6 : /[gprs]/.test(type2) ? Math.max(1, Math.min(21, precision2)) : Math.max(0, Math.min(20, precision2)); + function format2(value) { + var valuePrefix = prefix, valueSuffix = suffix, i2, n2, c; + if (type2 === "c") { + valueSuffix = formatType(value) + valueSuffix; + value = ""; + } else { + value = +value; + var valueNegative = value < 0 || 1 / value < 0; + value = isNaN(value) ? nan : formatType(Math.abs(value), precision2); + if (trim) + value = formatTrim_default(value); + if (valueNegative && +value === 0 && sign2 !== "+") + valueNegative = false; + valuePrefix = (valueNegative ? sign2 === "(" ? sign2 : minus : sign2 === "-" || sign2 === "(" ? "" : sign2) + valuePrefix; + valueSuffix = (type2 === "s" ? prefixes[8 + prefixExponent / 3] : "") + valueSuffix + (valueNegative && sign2 === "(" ? ")" : ""); + if (maybeSuffix) { + i2 = -1, n2 = value.length; + while (++i2 < n2) { + if (c = value.charCodeAt(i2), 48 > c || c > 57) { + valueSuffix = (c === 46 ? decimal + value.slice(i2 + 1) : value.slice(i2)) + valueSuffix; + value = value.slice(0, i2); + break; + } + } + } + } + if (comma && !zero3) + value = group(value, Infinity); + var length = valuePrefix.length + value.length + valueSuffix.length, padding = length < width ? new Array(width - length + 1).join(fill) : ""; + if (comma && zero3) + value = group(padding + value, padding.length ? width - valueSuffix.length : Infinity), padding = ""; + switch (align) { + case "<": + value = valuePrefix + value + valueSuffix + padding; + break; + case "=": + value = valuePrefix + padding + value + valueSuffix; + break; + case "^": + value = padding.slice(0, length = padding.length >> 1) + valuePrefix + value + valueSuffix + padding.slice(length); + break; + default: + value = padding + valuePrefix + value + valueSuffix; + break; + } + return numerals(value); + } + format2.toString = function() { + return specifier + ""; + }; + return format2; } - function behavior() { - context.keybinding().on(uiCmd("\u2318V"), doPaste); - return behavior; + function formatPrefix2(specifier, value) { + var f2 = newFormat((specifier = formatSpecifier(specifier), specifier.type = "f", specifier)), e = Math.max(-8, Math.min(8, Math.floor(exponent_default(value) / 3))) * 3, k = Math.pow(10, -e), prefix = prefixes[8 + e / 3]; + return function(value2) { + return f2(k * value2) + prefix; + }; } - behavior.off = function() { - context.keybinding().off(uiCmd("\u2318V")); + return { + format: newFormat, + formatPrefix: formatPrefix2 }; - return behavior; } - // modules/behavior/drag.js - function behaviorDrag() { - var dispatch10 = dispatch_default("start", "move", "end"); - var _tolerancePx = 1; - var _penTolerancePx = 4; - var _origin = null; - var _selector = ""; - var _targetNode; - var _targetEntity; - var _surface; - var _pointerId; - var _pointerPrefix = "PointerEvent" in window ? "pointer" : "mouse"; - var d3_event_userSelectProperty = utilPrefixCSSProperty("UserSelect"); - var d3_event_userSelectSuppress = function() { - var selection2 = selection_default(); - var select = selection2.style(d3_event_userSelectProperty); - selection2.style(d3_event_userSelectProperty, "none"); - return function() { - selection2.style(d3_event_userSelectProperty, select); - }; + // node_modules/d3-format/src/defaultLocale.js + var locale; + var format; + var formatPrefix; + defaultLocale({ + thousands: ",", + grouping: [3], + currency: ["$", ""] + }); + function defaultLocale(definition) { + locale = locale_default(definition); + format = locale.format; + formatPrefix = locale.formatPrefix; + return locale; + } + + // node_modules/d3-format/src/precisionFixed.js + function precisionFixed_default(step) { + return Math.max(0, -exponent_default(Math.abs(step))); + } + + // node_modules/d3-format/src/precisionPrefix.js + function precisionPrefix_default(step, value) { + return Math.max(0, Math.max(-8, Math.min(8, Math.floor(exponent_default(value) / 3))) * 3 - exponent_default(Math.abs(step))); + } + + // node_modules/d3-format/src/precisionRound.js + function precisionRound_default(step, max3) { + step = Math.abs(step), max3 = Math.abs(max3) - step; + return Math.max(0, exponent_default(max3) - exponent_default(step)) + 1; + } + + // node_modules/d3-scale/src/tickFormat.js + function tickFormat(start2, stop, count, specifier) { + var step = tickStep(start2, stop, count), precision2; + specifier = formatSpecifier(specifier == null ? ",f" : specifier); + switch (specifier.type) { + case "s": { + var value = Math.max(Math.abs(start2), Math.abs(stop)); + if (specifier.precision == null && !isNaN(precision2 = precisionPrefix_default(step, value))) + specifier.precision = precision2; + return formatPrefix(specifier, value); + } + case "": + case "e": + case "g": + case "p": + case "r": { + if (specifier.precision == null && !isNaN(precision2 = precisionRound_default(step, Math.max(Math.abs(start2), Math.abs(stop))))) + specifier.precision = precision2 - (specifier.type === "e"); + break; + } + case "f": + case "%": { + if (specifier.precision == null && !isNaN(precision2 = precisionFixed_default(step))) + specifier.precision = precision2 - (specifier.type === "%") * 2; + break; + } + } + return format(specifier); + } + + // node_modules/d3-scale/src/linear.js + function linearish(scale) { + var domain2 = scale.domain; + scale.ticks = function(count) { + var d = domain2(); + return ticks(d[0], d[d.length - 1], count == null ? 10 : count); }; - function pointerdown(d3_event) { - if (_pointerId) - return; - _pointerId = d3_event.pointerId || "mouse"; - _targetNode = this; - var pointerLocGetter = utilFastMouse(_surface || _targetNode.parentNode); - var offset; - var startOrigin = pointerLocGetter(d3_event); - var started = false; - var selectEnable = d3_event_userSelectSuppress(); - select_default2(window).on(_pointerPrefix + "move.drag", pointermove).on(_pointerPrefix + "up.drag pointercancel.drag", pointerup, true); - if (_origin) { - offset = _origin.call(_targetNode, _targetEntity); - offset = [offset[0] - startOrigin[0], offset[1] - startOrigin[1]]; - } else { - offset = [0, 0]; + scale.tickFormat = function(count, specifier) { + var d = domain2(); + return tickFormat(d[0], d[d.length - 1], count == null ? 10 : count, specifier); + }; + scale.nice = function(count) { + if (count == null) + count = 10; + var d = domain2(); + var i0 = 0; + var i1 = d.length - 1; + var start2 = d[i0]; + var stop = d[i1]; + var prestep; + var step; + var maxIter = 10; + if (stop < start2) { + step = start2, start2 = stop, stop = step; + step = i0, i0 = i1, i1 = step; } - d3_event.stopPropagation(); - function pointermove(d3_event2) { - if (_pointerId !== (d3_event2.pointerId || "mouse")) - return; - var p = pointerLocGetter(d3_event2); - if (!started) { - var dist = geoVecLength(startOrigin, p); - var tolerance = d3_event2.pointerType === "pen" ? _penTolerancePx : _tolerancePx; - if (dist < tolerance) - return; - started = true; - dispatch10.call("start", this, d3_event2, _targetEntity); + while (maxIter-- > 0) { + step = tickIncrement(start2, stop, count); + if (step === prestep) { + d[i0] = start2; + d[i1] = stop; + return domain2(d); + } else if (step > 0) { + start2 = Math.floor(start2 / step) * step; + stop = Math.ceil(stop / step) * step; + } else if (step < 0) { + start2 = Math.ceil(start2 * step) / step; + stop = Math.floor(stop * step) / step; } else { - startOrigin = p; - d3_event2.stopPropagation(); - d3_event2.preventDefault(); - var dx = p[0] - startOrigin[0]; - var dy = p[1] - startOrigin[1]; - dispatch10.call("move", this, d3_event2, _targetEntity, [p[0] + offset[0], p[1] + offset[1]], [dx, dy]); - } - } - function pointerup(d3_event2) { - if (_pointerId !== (d3_event2.pointerId || "mouse")) - return; - _pointerId = null; - if (started) { - dispatch10.call("end", this, d3_event2, _targetEntity); - d3_event2.preventDefault(); + break; } - select_default2(window).on(_pointerPrefix + "move.drag", null).on(_pointerPrefix + "up.drag pointercancel.drag", null); - selectEnable(); + prestep = step; } + return scale; + }; + return scale; + } + function linear3() { + var scale = continuous(); + scale.copy = function() { + return copy(scale, linear3()); + }; + initRange.apply(scale, arguments); + return linearish(scale); + } + + // node_modules/d3-scale/src/quantize.js + function quantize() { + var x05 = 0, x12 = 1, n2 = 1, domain2 = [0.5], range3 = [0, 1], unknown; + function scale(x) { + return x != null && x <= x ? range3[bisect_default(domain2, x, 0, n2)] : unknown; } - function behavior(selection2) { - var matchesSelector = utilPrefixDOMProperty("matchesSelector"); - var delegate = pointerdown; - if (_selector) { - delegate = function(d3_event) { - var root3 = this; - var target = d3_event.target; - for (; target && target !== root3; target = target.parentNode) { - var datum2 = target.__data__; - _targetEntity = datum2 instanceof osmNote ? datum2 : datum2 && datum2.properties && datum2.properties.entity; - if (_targetEntity && target[matchesSelector](_selector)) { - return pointerdown.call(target, d3_event); - } - } - }; - } - selection2.on(_pointerPrefix + "down.drag" + _selector, delegate); + function rescale() { + var i2 = -1; + domain2 = new Array(n2); + while (++i2 < n2) + domain2[i2] = ((i2 + 1) * x12 - (i2 - n2) * x05) / (n2 + 1); + return scale; } - behavior.off = function(selection2) { - selection2.on(_pointerPrefix + "down.drag" + _selector, null); - }; - behavior.selector = function(_) { - if (!arguments.length) - return _selector; - _selector = _; - return behavior; + scale.domain = function(_) { + return arguments.length ? ([x05, x12] = _, x05 = +x05, x12 = +x12, rescale()) : [x05, x12]; }; - behavior.origin = function(_) { - if (!arguments.length) - return _origin; - _origin = _; - return behavior; + scale.range = function(_) { + return arguments.length ? (n2 = (range3 = Array.from(_)).length - 1, rescale()) : range3.slice(); }; - behavior.cancel = function() { - select_default2(window).on(_pointerPrefix + "move.drag", null).on(_pointerPrefix + "up.drag pointercancel.drag", null); - return behavior; + scale.invertExtent = function(y) { + var i2 = range3.indexOf(y); + return i2 < 0 ? [NaN, NaN] : i2 < 1 ? [x05, domain2[0]] : i2 >= n2 ? [domain2[n2 - 1], x12] : [domain2[i2 - 1], domain2[i2]]; }; - behavior.targetNode = function(_) { - if (!arguments.length) - return _targetNode; - _targetNode = _; - return behavior; + scale.unknown = function(_) { + return arguments.length ? (unknown = _, scale) : scale; }; - behavior.targetEntity = function(_) { - if (!arguments.length) - return _targetEntity; - _targetEntity = _; - return behavior; + scale.thresholds = function() { + return domain2.slice(); }; - behavior.surface = function(_) { - if (!arguments.length) - return _surface; - _surface = _; - return behavior; + scale.copy = function() { + return quantize().domain([x05, x12]).range(range3).unknown(unknown); }; - return utilRebind(behavior, dispatch10, "on"); + return initRange.apply(linearish(scale), arguments); } - // modules/modes/drag_node.js - function modeDragNode(context) { - var mode = { - id: "drag-node", - button: "browse" - }; - var hover = behaviorHover(context).altDisables(true).on("hover", context.ui().sidebar.hover); - var edit2 = behaviorEdit(context); - var _nudgeInterval; - var _restoreSelectedIDs = []; - var _wasMidpoint = false; - var _isCancelled = false; - var _activeEntity; - var _startLoc; - var _lastLoc; - function startNudge(d3_event, entity, nudge) { - if (_nudgeInterval) - window.clearInterval(_nudgeInterval); - _nudgeInterval = window.setInterval(function() { - context.map().pan(nudge); - doMove(d3_event, entity, nudge); - }, 50); + // modules/behavior/breathe.js + function behaviorBreathe() { + var duration = 800; + var steps = 4; + var selector = ".selected.shadow, .selected .shadow"; + var _selected = select_default2(null); + var _classed = ""; + var _params = {}; + var _done = false; + var _timer; + function ratchetyInterpolator(a, b, steps2, units) { + a = Number(a); + b = Number(b); + var sample = quantize().domain([0, 1]).range(quantize_default(number_default(a, b), steps2)); + return function(t) { + return String(sample(t)) + (units || ""); + }; } - function stopNudge() { - if (_nudgeInterval) { - window.clearInterval(_nudgeInterval); - _nudgeInterval = null; - } + function reset(selection2) { + selection2.style("stroke-opacity", null).style("stroke-width", null).style("fill-opacity", null).style("r", null); } - function moveAnnotation(entity) { - return _t("operations.move.annotation." + entity.geometry(context.graph())); + function setAnimationParams(transition2, fromTo) { + var toFrom = fromTo === "from" ? "to" : "from"; + transition2.styleTween("stroke-opacity", function(d) { + return ratchetyInterpolator( + _params[d.id][toFrom].opacity, + _params[d.id][fromTo].opacity, + steps + ); + }).styleTween("stroke-width", function(d) { + return ratchetyInterpolator( + _params[d.id][toFrom].width, + _params[d.id][fromTo].width, + steps, + "px" + ); + }).styleTween("fill-opacity", function(d) { + return ratchetyInterpolator( + _params[d.id][toFrom].opacity, + _params[d.id][fromTo].opacity, + steps + ); + }).styleTween("r", function(d) { + return ratchetyInterpolator( + _params[d.id][toFrom].width, + _params[d.id][fromTo].width, + steps, + "px" + ); + }); } - function connectAnnotation(nodeEntity, targetEntity) { - var nodeGeometry = nodeEntity.geometry(context.graph()); - var targetGeometry = targetEntity.geometry(context.graph()); - if (nodeGeometry === "vertex" && targetGeometry === "vertex") { - var nodeParentWayIDs = context.graph().parentWays(nodeEntity); - var targetParentWayIDs = context.graph().parentWays(targetEntity); - var sharedParentWays = utilArrayIntersection(nodeParentWayIDs, targetParentWayIDs); - if (sharedParentWays.length !== 0) { - if (sharedParentWays[0].areAdjacent(nodeEntity.id, targetEntity.id)) { - return _t("operations.connect.annotation.from_vertex.to_adjacent_vertex"); - } - return _t("operations.connect.annotation.from_vertex.to_sibling_vertex"); + function calcAnimationParams(selection2) { + selection2.call(reset).each(function(d) { + var s = select_default2(this); + var tag = s.node().tagName; + var p = { "from": {}, "to": {} }; + var opacity; + var width; + if (tag === "circle") { + opacity = Number(s.style("fill-opacity") || 0.5); + width = Number(s.style("r") || 15.5); + } else { + opacity = Number(s.style("stroke-opacity") || 0.7); + width = Number(s.style("stroke-width") || 10); } - } - return _t("operations.connect.annotation.from_" + nodeGeometry + ".to_" + targetGeometry); - } - function shouldSnapToNode(target) { - if (!_activeEntity) - return false; - return _activeEntity.geometry(context.graph()) !== "vertex" || (target.geometry(context.graph()) === "vertex" || _mainPresetIndex.allowsVertex(target, context.graph())); - } - function origin(entity) { - return context.projection(entity.loc); + p.tag = tag; + p.from.opacity = opacity * 0.6; + p.to.opacity = opacity * 1.25; + p.from.width = width * 0.7; + p.to.width = width * (tag === "circle" ? 1.5 : 1); + _params[d.id] = p; + }); } - function keydown(d3_event) { - if (d3_event.keyCode === utilKeybinding.modifierCodes.alt) { - if (context.surface().classed("nope")) { - context.surface().classed("nope-suppressed", true); - } - context.surface().classed("nope", false).classed("nope-disabled", true); + function run(surface, fromTo) { + var toFrom = fromTo === "from" ? "to" : "from"; + var currSelected = surface.selectAll(selector); + var currClassed = surface.attr("class"); + if (_done || currSelected.empty()) { + _selected.call(reset); + _selected = select_default2(null); + return; } - } - function keyup(d3_event) { - if (d3_event.keyCode === utilKeybinding.modifierCodes.alt) { - if (context.surface().classed("nope-suppressed")) { - context.surface().classed("nope", true); - } - context.surface().classed("nope-suppressed", false).classed("nope-disabled", false); + if (!(0, import_fast_deep_equal2.default)(currSelected.data(), _selected.data()) || currClassed !== _classed) { + _selected.call(reset); + _classed = currClassed; + _selected = currSelected.call(calcAnimationParams); } - } - function start2(d3_event, entity) { - _wasMidpoint = entity.type === "midpoint"; - var hasHidden = context.features().hasHiddenConnections(entity, context.graph()); - _isCancelled = !context.editable() || d3_event.shiftKey || hasHidden; - if (_isCancelled) { - if (hasHidden) { - context.ui().flash.duration(4e3).iconName("#iD-icon-no").label(_t.append("modes.drag_node.connected_to_hidden"))(); + var didCallNextRun = false; + _selected.transition().duration(duration).call(setAnimationParams, fromTo).on("end", function() { + if (!didCallNextRun) { + surface.call(run, toFrom); + didCallNextRun = true; } - return drag.cancel(); - } - if (_wasMidpoint) { - var midpoint = entity; - entity = osmNode(); - context.perform(actionAddMidpoint(midpoint, entity)); - entity = context.entity(entity.id); - var vertex = context.surface().selectAll("." + entity.id); - drag.targetNode(vertex.node()).targetEntity(entity); - } else { - context.perform(actionNoop()); - } - _activeEntity = entity; - _startLoc = entity.loc; - hover.ignoreVertex(entity.geometry(context.graph()) === "vertex"); - context.surface().selectAll("." + _activeEntity.id).classed("active", true); - context.enter(mode); + if (!select_default2(this).classed("selected")) { + reset(select_default2(this)); + } + }); } - function datum2(d3_event) { - if (!d3_event || d3_event.altKey) { - return {}; - } else { - var d = d3_event.target.__data__; - return d && d.properties && d.properties.target ? d : {}; - } + function behavior(surface) { + _done = false; + _timer = timer(function() { + if (surface.selectAll(selector).empty()) { + return false; + } + surface.call(run, "from"); + _timer.stop(); + return true; + }, 20); } - function doMove(d3_event, entity, nudge) { - nudge = nudge || [0, 0]; - var currPoint = d3_event && d3_event.point || context.projection(_lastLoc); - var currMouse = geoVecSubtract(currPoint, nudge); - var loc = context.projection.invert(currMouse); - var target, edge; - if (!_nudgeInterval) { - var d = datum2(d3_event); - target = d && d.properties && d.properties.entity; - var targetLoc = target && target.loc; - var targetNodes = d && d.properties && d.properties.nodes; - if (targetLoc) { - if (shouldSnapToNode(target)) { - loc = targetLoc; - } - } else if (targetNodes) { - edge = geoChooseEdge(targetNodes, context.map().mouse(), context.projection, end.id); - if (edge) { - loc = edge.loc; - } + behavior.restartIfNeeded = function(surface) { + if (_selected.empty()) { + surface.call(run, "from"); + if (_timer) { + _timer.stop(); } } - context.replace( - actionMoveNode(entity.id, loc) - ); - var isInvalid = false; - if (target) { - isInvalid = hasRelationConflict(entity, target, edge, context.graph()); - } - if (!isInvalid) { - isInvalid = hasInvalidGeometry(entity, context.graph()); + }; + behavior.off = function() { + _done = true; + if (_timer) { + _timer.stop(); } - var nope = context.surface().classed("nope"); - if (isInvalid === "relation" || isInvalid === "restriction") { - if (!nope) { - context.ui().flash.duration(4e3).iconName("#iD-icon-no").label(_t.append( - "operations.connect." + isInvalid, - { relation: _mainPresetIndex.item("type/restriction").name() } - ))(); - } - } else if (isInvalid) { - var errorID = isInvalid === "line" ? "lines" : "areas"; - context.ui().flash.duration(3e3).iconName("#iD-icon-no").label(_t.append("self_intersection.error." + errorID))(); + _selected.interrupt().call(reset); + }; + return behavior; + } + + // modules/behavior/operation.js + function behaviorOperation(context) { + var _operation; + function keypress(d3_event) { + if (!context.map().withinEditableZoom()) + return; + if (_operation.availableForKeypress && !_operation.availableForKeypress()) + return; + d3_event.preventDefault(); + var disabled = _operation.disabled(); + if (disabled) { + context.ui().flash.duration(4e3).iconName("#iD-operation-" + _operation.id).iconClass("operation disabled").label(_operation.tooltip())(); } else { - if (nope) { - context.ui().flash.duration(1).label("")(); - } + context.ui().flash.duration(2e3).iconName("#iD-operation-" + _operation.id).iconClass("operation").label(_operation.annotation() || _operation.title)(); + if (_operation.point) + _operation.point(null); + _operation(); } - var nopeDisabled = context.surface().classed("nope-disabled"); - if (nopeDisabled) { - context.surface().classed("nope", false).classed("nope-suppressed", isInvalid); - } else { - context.surface().classed("nope", isInvalid).classed("nope-suppressed", false); + } + function behavior() { + if (_operation && _operation.available()) { + context.keybinding().on(_operation.keys, keypress); } - _lastLoc = loc; + return behavior; } - function hasRelationConflict(entity, target, edge, graph) { - var testGraph = graph.update(); - if (edge) { - var midpoint = osmNode(); - var action = actionAddMidpoint({ - loc: edge.loc, - edge: [target.nodes[edge.index - 1], target.nodes[edge.index]] - }, midpoint); - testGraph = action(testGraph); - target = midpoint; + behavior.off = function() { + context.keybinding().off(_operation.keys); + }; + behavior.which = function(_) { + if (!arguments.length) + return _operation; + _operation = _; + return behavior; + }; + return behavior; + } + + // modules/operations/circularize.js + function operationCircularize(context, selectedIDs) { + var _extent; + var _actions = selectedIDs.map(getAction).filter(Boolean); + var _amount = _actions.length === 1 ? "single" : "multiple"; + var _coords = utilGetAllNodes(selectedIDs, context.graph()).map(function(n2) { + return n2.loc; + }); + function getAction(entityID) { + var entity = context.entity(entityID); + if (entity.type !== "way" || new Set(entity.nodes).size <= 1) + return null; + if (!_extent) { + _extent = entity.extent(context.graph()); + } else { + _extent = _extent.extend(entity.extent(context.graph())); } - var ids = [entity.id, target.id]; - return actionConnect(ids).disabled(testGraph); + return actionCircularize(entityID, context.projection); } - function hasInvalidGeometry(entity, graph) { - var parents = graph.parentWays(entity); - var i2, j2, k; - for (i2 = 0; i2 < parents.length; i2++) { - var parent = parents[i2]; - var nodes = []; - var activeIndex = null; - var relations = graph.parentRelations(parent); - for (j2 = 0; j2 < relations.length; j2++) { - if (!relations[j2].isMultipolygon()) - continue; - var rings = osmJoinWays(relations[j2].members, graph); - for (k = 0; k < rings.length; k++) { - nodes = rings[k].nodes; - if (nodes.find(function(n2) { - return n2.id === entity.id; - })) { - activeIndex = k; - if (geoHasSelfIntersections(nodes, entity.id)) { - return "multipolygonMember"; - } - } - rings[k].coords = nodes.map(function(n2) { - return n2.loc; - }); - } - for (k = 0; k < rings.length; k++) { - if (k === activeIndex) - continue; - if (geoHasLineIntersections(rings[activeIndex].nodes, rings[k].nodes, entity.id)) { - return "multipolygonRing"; - } + var operation = function() { + if (!_actions.length) + return; + var combinedAction = function(graph, t) { + _actions.forEach(function(action) { + if (!action.disabled(graph)) { + graph = action(graph, t); } + }); + return graph; + }; + combinedAction.transitionable = true; + context.perform(combinedAction, operation.annotation()); + window.setTimeout(function() { + context.validator().validate(); + }, 300); + }; + operation.available = function() { + return _actions.length && selectedIDs.length === _actions.length; + }; + operation.disabled = function() { + if (!_actions.length) + return ""; + var actionDisableds = _actions.map(function(action) { + return action.disabled(context.graph()); + }).filter(Boolean); + if (actionDisableds.length === _actions.length) { + if (new Set(actionDisableds).size > 1) { + return "multiple_blockers"; } - if (activeIndex === null) { - nodes = parent.nodes.map(function(nodeID) { - return graph.entity(nodeID); + return actionDisableds[0]; + } else if (_extent.percentContainedIn(context.map().extent()) < 0.8) { + return "too_large"; + } else if (someMissing()) { + return "not_downloaded"; + } else if (selectedIDs.some(context.hasHiddenConnections)) { + return "connected_to_hidden"; + } + return false; + function someMissing() { + if (context.inIntro()) + return false; + var osm = context.connection(); + if (osm) { + var missing = _coords.filter(function(loc) { + return !osm.isDataLoaded(loc); }); - if (nodes.length && geoHasSelfIntersections(nodes, entity.id)) { - return parent.geometry(graph); + if (missing.length) { + missing.forEach(function(loc) { + context.loadTileAtLoc(loc); + }); + return true; } } + return false; } - return false; + }; + operation.tooltip = function() { + var disable = operation.disabled(); + return disable ? _t.append("operations.circularize." + disable + "." + _amount) : _t.append("operations.circularize.description." + _amount); + }; + operation.annotation = function() { + return _t("operations.circularize.annotation.feature", { n: _actions.length }); + }; + operation.id = "circularize"; + operation.keys = [_t("operations.circularize.key")]; + operation.title = _t.append("operations.circularize.title"); + operation.behavior = behaviorOperation(context).which(operation); + return operation; + } + + // modules/ui/cmd.js + var uiCmd = function(code) { + var detected = utilDetect(); + if (detected.os === "mac") { + return code; } - function move(d3_event, entity, point) { - if (_isCancelled) - return; - d3_event.stopPropagation(); - context.surface().classed("nope-disabled", d3_event.altKey); - _lastLoc = context.projection.invert(point); - doMove(d3_event, entity); - var nudge = geoViewportEdge(point, context.map().dimensions()); - if (nudge) { - startNudge(d3_event, entity, nudge); + if (detected.os === "win") { + if (code === "\u2318\u21E7Z") + return "Ctrl+Y"; + } + var result = "", replacements = { + "\u2318": "Ctrl", + "\u21E7": "Shift", + "\u2325": "Alt", + "\u232B": "Backspace", + "\u2326": "Delete" + }; + for (var i2 = 0; i2 < code.length; i2++) { + if (code[i2] in replacements) { + result += replacements[code[i2]] + (i2 < code.length - 1 ? "+" : ""); } else { - stopNudge(); + result += code[i2]; } } - function end(d3_event, entity) { - if (_isCancelled) - return; - var wasPoint = entity.geometry(context.graph()) === "point"; - var d = datum2(d3_event); - var nope = d && d.properties && d.properties.nope || context.surface().classed("nope"); - var target = d && d.properties && d.properties.entity; - if (nope) { - context.perform( - _actionBounceBack(entity.id, _startLoc) - ); - } else if (target && target.type === "way") { - var choice = geoChooseEdge(context.graph().childNodes(target), context.map().mouse(), context.projection, entity.id); - context.replace( - actionAddMidpoint({ - loc: choice.loc, - edge: [target.nodes[choice.index - 1], target.nodes[choice.index]] - }, entity), - connectAnnotation(entity, target) - ); - } else if (target && target.type === "node" && shouldSnapToNode(target)) { - context.replace( - actionConnect([target.id, entity.id]), - connectAnnotation(entity, target) - ); - } else if (_wasMidpoint) { - context.replace( - actionNoop(), - _t("operations.add.annotation.vertex") - ); - } else { - context.replace( - actionNoop(), - moveAnnotation(entity) - ); + return result; + }; + uiCmd.display = function(code) { + if (code.length !== 1) + return code; + var detected = utilDetect(); + var mac = detected.os === "mac"; + var replacements = { + "\u2318": mac ? "\u2318 " + _t("shortcuts.key.cmd") : _t("shortcuts.key.ctrl"), + "\u21E7": mac ? "\u21E7 " + _t("shortcuts.key.shift") : _t("shortcuts.key.shift"), + "\u2325": mac ? "\u2325 " + _t("shortcuts.key.option") : _t("shortcuts.key.alt"), + "\u2303": mac ? "\u2303 " + _t("shortcuts.key.ctrl") : _t("shortcuts.key.ctrl"), + "\u232B": mac ? "\u232B " + _t("shortcuts.key.delete") : _t("shortcuts.key.backspace"), + "\u2326": mac ? "\u2326 " + _t("shortcuts.key.del") : _t("shortcuts.key.del"), + "\u2196": mac ? "\u2196 " + _t("shortcuts.key.pgup") : _t("shortcuts.key.pgup"), + "\u2198": mac ? "\u2198 " + _t("shortcuts.key.pgdn") : _t("shortcuts.key.pgdn"), + "\u21DE": mac ? "\u21DE " + _t("shortcuts.key.home") : _t("shortcuts.key.home"), + "\u21DF": mac ? "\u21DF " + _t("shortcuts.key.end") : _t("shortcuts.key.end"), + "\u21B5": mac ? "\u23CE " + _t("shortcuts.key.return") : _t("shortcuts.key.enter"), + "\u238B": mac ? "\u238B " + _t("shortcuts.key.esc") : _t("shortcuts.key.esc"), + "\u2630": mac ? "\u2630 " + _t("shortcuts.key.menu") : _t("shortcuts.key.menu") + }; + return replacements[code] || code; + }; + + // modules/operations/delete.js + function operationDelete(context, selectedIDs) { + var multi = selectedIDs.length === 1 ? "single" : "multiple"; + var action = actionDeleteMultiple(selectedIDs); + var nodes = utilGetAllNodes(selectedIDs, context.graph()); + var coords = nodes.map(function(n2) { + return n2.loc; + }); + var extent = utilTotalExtent(selectedIDs, context.graph()); + var operation = function() { + var nextSelectedID; + var nextSelectedLoc; + if (selectedIDs.length === 1) { + var id2 = selectedIDs[0]; + var entity = context.entity(id2); + var geometry = entity.geometry(context.graph()); + var parents = context.graph().parentWays(entity); + var parent = parents[0]; + if (geometry === "vertex") { + var nodes2 = parent.nodes; + var i2 = nodes2.indexOf(id2); + if (i2 === 0) { + i2++; + } else if (i2 === nodes2.length - 1) { + i2--; + } else { + var a = geoSphericalDistance(entity.loc, context.entity(nodes2[i2 - 1]).loc); + var b = geoSphericalDistance(entity.loc, context.entity(nodes2[i2 + 1]).loc); + i2 = a < b ? i2 - 1 : i2 + 1; + } + nextSelectedID = nodes2[i2]; + nextSelectedLoc = context.entity(nextSelectedID).loc; + } } - if (wasPoint) { - context.enter(modeSelect(context, [entity.id])); - } else { - var reselection = _restoreSelectedIDs.filter(function(id2) { - return context.graph().hasEntity(id2); - }); - if (reselection.length) { - context.enter(modeSelect(context, reselection)); + context.perform(action, operation.annotation()); + context.validator().validate(); + if (nextSelectedID && nextSelectedLoc) { + if (context.hasEntity(nextSelectedID)) { + context.enter(modeSelect(context, [nextSelectedID]).follow(true)); } else { + context.map().centerEase(nextSelectedLoc); context.enter(modeBrowse(context)); } + } else { + context.enter(modeBrowse(context)); } - } - function _actionBounceBack(nodeID, toLoc) { - var moveNode = actionMoveNode(nodeID, toLoc); - var action = function(graph, t) { - if (t === 1) - context.pop(); - return moveNode(graph, t); - }; - action.transitionable = true; - return action; - } - function cancel() { - drag.cancel(); - context.enter(modeBrowse(context)); - } - var drag = behaviorDrag().selector(".layer-touch.points .target").surface(context.container().select(".main-map").node()).origin(origin).on("start", start2).on("move", move).on("end", end); - mode.enter = function() { - context.install(hover); - context.install(edit2); - select_default2(window).on("keydown.dragNode", keydown).on("keyup.dragNode", keyup); - context.history().on("undone.drag-node", cancel); - }; - mode.exit = function() { - context.ui().sidebar.hover.cancel(); - context.uninstall(hover); - context.uninstall(edit2); - select_default2(window).on("keydown.dragNode", null).on("keyup.dragNode", null); - context.history().on("undone.drag-node", null); - _activeEntity = null; - context.surface().classed("nope", false).classed("nope-suppressed", false).classed("nope-disabled", false).selectAll(".active").classed("active", false); - stopNudge(); - }; - mode.selectedIDs = function() { - if (!arguments.length) - return _activeEntity ? [_activeEntity.id] : []; - return mode; }; - mode.activeID = function() { - if (!arguments.length) - return _activeEntity && _activeEntity.id; - return mode; + operation.available = function() { + return true; }; - mode.restoreSelectedIDs = function(_) { - if (!arguments.length) - return _restoreSelectedIDs; - _restoreSelectedIDs = _; - return mode; + operation.disabled = function() { + if (extent.percentContainedIn(context.map().extent()) < 0.8) { + return "too_large"; + } else if (someMissing()) { + return "not_downloaded"; + } else if (selectedIDs.some(context.hasHiddenConnections)) { + return "connected_to_hidden"; + } else if (selectedIDs.some(protectedMember)) { + return "part_of_relation"; + } else if (selectedIDs.some(incompleteRelation)) { + return "incomplete_relation"; + } else if (selectedIDs.some(hasWikidataTag)) { + return "has_wikidata_tag"; + } + return false; + function someMissing() { + if (context.inIntro()) + return false; + var osm = context.connection(); + if (osm) { + var missing = coords.filter(function(loc) { + return !osm.isDataLoaded(loc); + }); + if (missing.length) { + missing.forEach(function(loc) { + context.loadTileAtLoc(loc); + }); + return true; + } + } + return false; + } + function hasWikidataTag(id2) { + var entity = context.entity(id2); + return entity.tags.wikidata && entity.tags.wikidata.trim().length > 0; + } + function incompleteRelation(id2) { + var entity = context.entity(id2); + return entity.type === "relation" && !entity.isComplete(context.graph()); + } + function protectedMember(id2) { + var entity = context.entity(id2); + if (entity.type !== "way") + return false; + var parents = context.graph().parentRelations(entity); + for (var i2 = 0; i2 < parents.length; i2++) { + var parent = parents[i2]; + var type2 = parent.tags.type; + var role = parent.memberById(id2).role || "outer"; + if (type2 === "route" || type2 === "boundary" || type2 === "multipolygon" && role === "outer") { + return true; + } + } + return false; + } }; - mode.behavior = drag; - return mode; + operation.tooltip = function() { + var disable = operation.disabled(); + return disable ? _t.append("operations.delete." + disable + "." + multi) : _t.append("operations.delete.description." + multi); + }; + operation.annotation = function() { + return selectedIDs.length === 1 ? _t("operations.delete.annotation." + context.graph().geometry(selectedIDs[0])) : _t("operations.delete.annotation.feature", { n: selectedIDs.length }); + }; + operation.id = "delete"; + operation.keys = [uiCmd("\u2318\u232B"), uiCmd("\u2318\u2326"), uiCmd("\u2326")]; + operation.title = _t.append("operations.delete.title"); + operation.behavior = behaviorOperation(context).which(operation); + return operation; } - // modules/services/keepRight.js - var import_rbush = __toESM(require_rbush_min()); - - // node_modules/d3-fetch/src/text.js - function responseText(response) { - if (!response.ok) - throw new Error(response.status + " " + response.statusText); - return response.text(); - } - function text_default3(input, init2) { - return fetch(input, init2).then(responseText); + // modules/operations/orthogonalize.js + function operationOrthogonalize(context, selectedIDs) { + var _extent; + var _type; + var _actions = selectedIDs.map(chooseAction).filter(Boolean); + var _amount = _actions.length === 1 ? "single" : "multiple"; + var _coords = utilGetAllNodes(selectedIDs, context.graph()).map(function(n2) { + return n2.loc; + }); + function chooseAction(entityID) { + var entity = context.entity(entityID); + var geometry = entity.geometry(context.graph()); + if (!_extent) { + _extent = entity.extent(context.graph()); + } else { + _extent = _extent.extend(entity.extent(context.graph())); + } + if (entity.type === "way" && new Set(entity.nodes).size > 2) { + if (_type && _type !== "feature") + return null; + _type = "feature"; + return actionOrthogonalize(entityID, context.projection); + } else if (geometry === "vertex") { + if (_type && _type !== "corner") + return null; + _type = "corner"; + var graph = context.graph(); + var parents = graph.parentWays(entity); + if (parents.length === 1) { + var way = parents[0]; + if (way.nodes.indexOf(entityID) !== -1) { + return actionOrthogonalize(way.id, context.projection, entityID); + } + } + } + return null; + } + var operation = function() { + if (!_actions.length) + return; + var combinedAction = function(graph, t) { + _actions.forEach(function(action) { + if (!action.disabled(graph)) { + graph = action(graph, t); + } + }); + return graph; + }; + combinedAction.transitionable = true; + context.perform(combinedAction, operation.annotation()); + window.setTimeout(function() { + context.validator().validate(); + }, 300); + }; + operation.available = function() { + return _actions.length && selectedIDs.length === _actions.length; + }; + operation.disabled = function() { + if (!_actions.length) + return ""; + var actionDisableds = _actions.map(function(action) { + return action.disabled(context.graph()); + }).filter(Boolean); + if (actionDisableds.length === _actions.length) { + if (new Set(actionDisableds).size > 1) { + return "multiple_blockers"; + } + return actionDisableds[0]; + } else if (_extent && _extent.percentContainedIn(context.map().extent()) < 0.8) { + return "too_large"; + } else if (someMissing()) { + return "not_downloaded"; + } else if (selectedIDs.some(context.hasHiddenConnections)) { + return "connected_to_hidden"; + } + return false; + function someMissing() { + if (context.inIntro()) + return false; + var osm = context.connection(); + if (osm) { + var missing = _coords.filter(function(loc) { + return !osm.isDataLoaded(loc); + }); + if (missing.length) { + missing.forEach(function(loc) { + context.loadTileAtLoc(loc); + }); + return true; + } + } + return false; + } + }; + operation.tooltip = function() { + var disable = operation.disabled(); + return disable ? _t.append("operations.orthogonalize." + disable + "." + _amount) : _t.append("operations.orthogonalize.description." + _type + "." + _amount); + }; + operation.annotation = function() { + return _t("operations.orthogonalize.annotation." + _type, { n: _actions.length }); + }; + operation.id = "orthogonalize"; + operation.keys = [_t("operations.orthogonalize.key")]; + operation.title = _t.append("operations.orthogonalize.title"); + operation.behavior = behaviorOperation(context).which(operation); + return operation; } - // node_modules/d3-fetch/src/json.js - function responseJson(response) { - if (!response.ok) - throw new Error(response.status + " " + response.statusText); - if (response.status === 204 || response.status === 205) - return; - return response.json(); + // modules/operations/reflect.js + function operationReflectShort(context, selectedIDs) { + return operationReflect(context, selectedIDs, "short"); } - function json_default(input, init2) { - return fetch(input, init2).then(responseJson); + function operationReflectLong(context, selectedIDs) { + return operationReflect(context, selectedIDs, "long"); } - - // node_modules/d3-fetch/src/xml.js - function parser(type3) { - return (input, init2) => text_default3(input, init2).then((text2) => new DOMParser().parseFromString(text2, type3)); + function operationReflect(context, selectedIDs, axis) { + axis = axis || "long"; + var multi = selectedIDs.length === 1 ? "single" : "multiple"; + var nodes = utilGetAllNodes(selectedIDs, context.graph()); + var coords = nodes.map(function(n2) { + return n2.loc; + }); + var extent = utilTotalExtent(selectedIDs, context.graph()); + var operation = function() { + var action = actionReflect(selectedIDs, context.projection).useLongAxis(Boolean(axis === "long")); + context.perform(action, operation.annotation()); + window.setTimeout(function() { + context.validator().validate(); + }, 300); + }; + operation.available = function() { + return nodes.length >= 3; + }; + operation.disabled = function() { + if (extent.percentContainedIn(context.map().extent()) < 0.8) { + return "too_large"; + } else if (someMissing()) { + return "not_downloaded"; + } else if (selectedIDs.some(context.hasHiddenConnections)) { + return "connected_to_hidden"; + } else if (selectedIDs.some(incompleteRelation)) { + return "incomplete_relation"; + } + return false; + function someMissing() { + if (context.inIntro()) + return false; + var osm = context.connection(); + if (osm) { + var missing = coords.filter(function(loc) { + return !osm.isDataLoaded(loc); + }); + if (missing.length) { + missing.forEach(function(loc) { + context.loadTileAtLoc(loc); + }); + return true; + } + } + return false; + } + function incompleteRelation(id2) { + var entity = context.entity(id2); + return entity.type === "relation" && !entity.isComplete(context.graph()); + } + }; + operation.tooltip = function() { + var disable = operation.disabled(); + return disable ? _t.append("operations.reflect." + disable + "." + multi) : _t.append("operations.reflect.description." + axis + "." + multi); + }; + operation.annotation = function() { + return _t("operations.reflect.annotation." + axis + ".feature", { n: selectedIDs.length }); + }; + operation.id = "reflect-" + axis; + operation.keys = [_t("operations.reflect.key." + axis)]; + operation.title = _t.append("operations.reflect.title." + axis); + operation.behavior = behaviorOperation(context).which(operation); + return operation; } - var xml_default = parser("application/xml"); - var html = parser("text/html"); - var svg = parser("image/svg+xml"); - // modules/services/keepRight.js - var tiler = utilTiler(); - var dispatch2 = dispatch_default("loaded"); - var _tileZoom = 14; - var _krUrlRoot = "https://www.keepright.at"; - var _krData = { errorTypes: {}, localizeStrings: {} }; - var _cache; - var _krRuleset = [ - 30, - 40, - 50, - 60, - 70, - 90, - 100, - 110, - 120, - 130, - 150, - 160, - 170, - 180, - 190, - 191, - 192, - 193, - 194, - 195, - 196, - 197, - 198, - 200, - 201, - 202, - 203, - 204, - 205, - 206, - 207, - 208, - 210, - 220, - 230, - 231, - 232, - 270, - 280, - 281, - 282, - 283, - 284, - 285, - 290, - 291, - 292, - 293, - 294, - 295, - 296, - 297, - 298, - 300, - 310, - 311, - 312, - 313, - 320, - 350, - 360, - 370, - 380, - 390, - 400, - 401, - 402, - 410, - 411, - 412, - 413 - ]; - function abortRequest(controller) { - if (controller) { - controller.abort(); - } - } - function abortUnwantedRequests(cache, tiles) { - Object.keys(cache.inflightTile).forEach((k) => { - const wanted = tiles.find((tile) => k === tile.id); - if (!wanted) { - abortRequest(cache.inflightTile[k]); - delete cache.inflightTile[k]; - } + // modules/operations/move.js + function operationMove(context, selectedIDs) { + var multi = selectedIDs.length === 1 ? "single" : "multiple"; + var nodes = utilGetAllNodes(selectedIDs, context.graph()); + var coords = nodes.map(function(n2) { + return n2.loc; }); + var extent = utilTotalExtent(selectedIDs, context.graph()); + var operation = function() { + context.enter(modeMove(context, selectedIDs)); + }; + operation.available = function() { + return selectedIDs.length > 0; + }; + operation.disabled = function() { + if (extent.percentContainedIn(context.map().extent()) < 0.8) { + return "too_large"; + } else if (someMissing()) { + return "not_downloaded"; + } else if (selectedIDs.some(context.hasHiddenConnections)) { + return "connected_to_hidden"; + } else if (selectedIDs.some(incompleteRelation)) { + return "incomplete_relation"; + } + return false; + function someMissing() { + if (context.inIntro()) + return false; + var osm = context.connection(); + if (osm) { + var missing = coords.filter(function(loc) { + return !osm.isDataLoaded(loc); + }); + if (missing.length) { + missing.forEach(function(loc) { + context.loadTileAtLoc(loc); + }); + return true; + } + } + return false; + } + function incompleteRelation(id2) { + var entity = context.entity(id2); + return entity.type === "relation" && !entity.isComplete(context.graph()); + } + }; + operation.tooltip = function() { + var disable = operation.disabled(); + return disable ? _t.append("operations.move." + disable + "." + multi) : _t.append("operations.move.description." + multi); + }; + operation.annotation = function() { + return selectedIDs.length === 1 ? _t("operations.move.annotation." + context.graph().geometry(selectedIDs[0])) : _t("operations.move.annotation.feature", { n: selectedIDs.length }); + }; + operation.id = "move"; + operation.keys = [_t("operations.move.key")]; + operation.title = _t.append("operations.move.title"); + operation.behavior = behaviorOperation(context).which(operation); + operation.mouseOnly = true; + return operation; } - function encodeIssueRtree(d) { - return { minX: d.loc[0], minY: d.loc[1], maxX: d.loc[0], maxY: d.loc[1], data: d }; - } - function updateRtree(item, replace) { - _cache.rtree.remove(item, (a, b) => a.data.id === b.data.id); - if (replace) { - _cache.rtree.insert(item); - } - } - function tokenReplacements(d) { - if (!(d instanceof QAItem)) - return; - const replacements = {}; - const issueTemplate = _krData.errorTypes[d.whichType]; - if (!issueTemplate) { - console.log("No Template: ", d.whichType); - console.log(" ", d.description); - return; - } - if (!issueTemplate.regex) - return; - const errorRegex = new RegExp(issueTemplate.regex, "i"); - const errorMatch = errorRegex.exec(d.description); - if (!errorMatch) { - console.log("Unmatched: ", d.whichType); - console.log(" ", d.description); - console.log(" ", errorRegex); - return; - } - for (let i2 = 1; i2 < errorMatch.length; i2++) { - let capture = errorMatch[i2]; - let idType; - idType = "IDs" in issueTemplate ? issueTemplate.IDs[i2 - 1] : ""; - if (idType && capture) { - capture = parseError(capture, idType); + + // modules/modes/rotate.js + function modeRotate(context, entityIDs) { + var _tolerancePx = 4; + var mode = { + id: "rotate", + button: "browse" + }; + var keybinding = utilKeybinding("rotate"); + var behaviors = [ + behaviorEdit(context), + operationCircularize(context, entityIDs).behavior, + operationDelete(context, entityIDs).behavior, + operationMove(context, entityIDs).behavior, + operationOrthogonalize(context, entityIDs).behavior, + operationReflectLong(context, entityIDs).behavior, + operationReflectShort(context, entityIDs).behavior + ]; + var annotation = entityIDs.length === 1 ? _t("operations.rotate.annotation." + context.graph().geometry(entityIDs[0])) : _t("operations.rotate.annotation.feature", { n: entityIDs.length }); + var _prevGraph; + var _prevAngle; + var _prevTransform; + var _pivot; + var _pointerPrefix = "PointerEvent" in window ? "pointer" : "mouse"; + function doRotate(d3_event) { + var fn; + if (context.graph() !== _prevGraph) { + fn = context.perform; } else { - const compare = capture.toLowerCase(); - if (_krData.localizeStrings[compare]) { - capture = _t("QA.keepRight.error_parts." + _krData.localizeStrings[compare]); - } else { - capture = unescape_default(capture); - } + fn = context.replace; } - replacements["var" + i2] = capture; + var projection2 = context.projection; + var currTransform = projection2.transform(); + if (!_prevTransform || currTransform.k !== _prevTransform.k || currTransform.x !== _prevTransform.x || currTransform.y !== _prevTransform.y) { + var nodes = utilGetAllNodes(entityIDs, context.graph()); + var points = nodes.map(function(n2) { + return projection2(n2.loc); + }); + _pivot = getPivot(points); + _prevAngle = void 0; + } + var currMouse = context.map().mouse(d3_event); + var currAngle = Math.atan2(currMouse[1] - _pivot[1], currMouse[0] - _pivot[0]); + if (typeof _prevAngle === "undefined") + _prevAngle = currAngle; + var delta = currAngle - _prevAngle; + fn(actionRotate(entityIDs, _pivot, delta, projection2)); + _prevTransform = currTransform; + _prevAngle = currAngle; + _prevGraph = context.graph(); } - return replacements; - } - function parseError(capture, idType) { - const compare = capture.toLowerCase(); - if (_krData.localizeStrings[compare]) { - capture = _t("QA.keepRight.error_parts." + _krData.localizeStrings[compare]); - } - switch (idType) { - case "this": - capture = linkErrorObject2(capture); - break; - case "url": - capture = linkURL(capture); - break; - case "n": - case "w": - case "r": - capture = linkEntity2(idType + capture); - break; - case "20": - capture = parse20(capture); - break; - case "211": - capture = parse211(capture); - break; - case "231": - capture = parse231(capture); - break; - case "294": - capture = parse294(capture); - break; - case "370": - capture = parse370(capture); - break; - } - return capture; - function linkErrorObject2(d) { - return { html: `${d}` }; - } - function linkEntity2(d) { - return { html: `${d}` }; - } - function linkURL(d) { - return { html: `${d}` }; - } - function parse211(capture2) { - let newList = []; - const items = capture2.split(", "); - items.forEach((item) => { - let id2 = linkEntity2("n" + item.slice(1)); - newList.push(id2); - }); - return newList.join(", "); - } - function parse231(capture2) { - let newList = []; - const items = capture2.split("),"); - items.forEach((item) => { - const match = item.match(/\#(\d+)\((.+)\)?/); - if (match !== null && match.length > 2) { - newList.push( - linkEntity2("w" + match[1]) + " " + _t("QA.keepRight.errorTypes.231.layer", { layer: match[2] }) - ); + function getPivot(points) { + var _pivot2; + if (points.length === 1) { + _pivot2 = points[0]; + } else if (points.length === 2) { + _pivot2 = geoVecInterp(points[0], points[1], 0.5); + } else { + var polygonHull = hull_default(points); + if (polygonHull.length === 2) { + _pivot2 = geoVecInterp(points[0], points[1], 0.5); + } else { + _pivot2 = centroid_default2(hull_default(points)); } - }); - return newList.join(", "); + } + return _pivot2; } - function parse294(capture2) { - let newList = []; - const items = capture2.split(","); - items.forEach((item) => { - item = item.split(" "); - const role = `"${item[0]}"`; - const idType2 = item[1].slice(0, 1); - let id2 = item[2].slice(1); - id2 = linkEntity2(idType2 + id2); - newList.push(`${role} ${item[1]} ${id2}`); - }); - return newList.join(", "); + function finish(d3_event) { + d3_event.stopPropagation(); + context.replace(actionNoop(), annotation); + context.enter(modeSelect(context, entityIDs)); } - function parse370(capture2) { - if (!capture2) - return ""; - const match = capture2.match(/\(including the name (\'.+\')\)/); - if (match && match.length) { - return _t("QA.keepRight.errorTypes.370.including_the_name", { name: match[1] }); - } - return ""; + function cancel() { + if (_prevGraph) + context.pop(); + context.enter(modeSelect(context, entityIDs)); } - function parse20(capture2) { - let newList = []; - const items = capture2.split(","); - items.forEach((item) => { - const id2 = linkEntity2("n" + item.slice(1)); - newList.push(id2); - }); - return newList.join(", "); + function undone() { + context.enter(modeBrowse(context)); } + mode.enter = function() { + _prevGraph = null; + context.features().forceVisible(entityIDs); + behaviors.forEach(context.install); + var downEvent; + context.surface().on(_pointerPrefix + "down.modeRotate", function(d3_event) { + downEvent = d3_event; + }); + select_default2(window).on(_pointerPrefix + "move.modeRotate", doRotate, true).on(_pointerPrefix + "up.modeRotate", function(d3_event) { + if (!downEvent) + return; + var mapNode = context.container().select(".main-map").node(); + var pointGetter = utilFastMouse(mapNode); + var p1 = pointGetter(downEvent); + var p2 = pointGetter(d3_event); + var dist = geoVecLength(p1, p2); + if (dist <= _tolerancePx) + finish(d3_event); + downEvent = null; + }, true); + context.history().on("undone.modeRotate", undone); + keybinding.on("\u238B", cancel).on("\u21A9", finish); + select_default2(document).call(keybinding); + }; + mode.exit = function() { + behaviors.forEach(context.uninstall); + context.surface().on(_pointerPrefix + "down.modeRotate", null); + select_default2(window).on(_pointerPrefix + "move.modeRotate", null, true).on(_pointerPrefix + "up.modeRotate", null, true); + context.history().on("undone.modeRotate", null); + select_default2(document).call(keybinding.unbind); + context.features().forceVisible([]); + }; + mode.selectedIDs = function() { + if (!arguments.length) + return entityIDs; + return mode; + }; + return mode; } - var keepRight_default = { - title: "keepRight", - init() { - _mainFileFetcher.get("keepRight").then((d) => _krData = d); - if (!_cache) { - this.reset(); - } - this.event = utilRebind(this, dispatch2, "on"); - }, - reset() { - if (_cache) { - Object.values(_cache.inflightTile).forEach(abortRequest); + + // modules/operations/rotate.js + function operationRotate(context, selectedIDs) { + var multi = selectedIDs.length === 1 ? "single" : "multiple"; + var nodes = utilGetAllNodes(selectedIDs, context.graph()); + var coords = nodes.map(function(n2) { + return n2.loc; + }); + var extent = utilTotalExtent(selectedIDs, context.graph()); + var operation = function() { + context.enter(modeRotate(context, selectedIDs)); + }; + operation.available = function() { + return nodes.length >= 2; + }; + operation.disabled = function() { + if (extent.percentContainedIn(context.map().extent()) < 0.8) { + return "too_large"; + } else if (someMissing()) { + return "not_downloaded"; + } else if (selectedIDs.some(context.hasHiddenConnections)) { + return "connected_to_hidden"; + } else if (selectedIDs.some(incompleteRelation)) { + return "incomplete_relation"; } - _cache = { - data: {}, - loadedTile: {}, - inflightTile: {}, - inflightPost: {}, - closed: {}, - rtree: new import_rbush.default() - }; - }, - loadIssues(projection2) { - const options2 = { - format: "geojson", - ch: _krRuleset - }; - const tiles = tiler.zoomExtent([_tileZoom, _tileZoom]).getTiles(projection2); - abortUnwantedRequests(_cache, tiles); - tiles.forEach((tile) => { - if (_cache.loadedTile[tile.id] || _cache.inflightTile[tile.id]) - return; - const [left, top, right, bottom] = tile.extent.rectangle(); - const params = Object.assign({}, options2, { left, bottom, right, top }); - const url = `${_krUrlRoot}/export.php?` + utilQsString(params); - const controller = new AbortController(); - _cache.inflightTile[tile.id] = controller; - json_default(url, { signal: controller.signal }).then((data) => { - delete _cache.inflightTile[tile.id]; - _cache.loadedTile[tile.id] = true; - if (!data || !data.features || !data.features.length) { - throw new Error("No Data"); - } - data.features.forEach((feature3) => { - const { - properties: { - error_type: itemType, - error_id: id2, - comment = null, - object_id: objectId, - object_type: objectType, - schema, - title - } - } = feature3; - let { - geometry: { coordinates: loc }, - properties: { description = "" } - } = feature3; - const issueTemplate = _krData.errorTypes[itemType]; - const parentIssueType = (Math.floor(itemType / 10) * 10).toString(); - const whichType = issueTemplate ? itemType : parentIssueType; - const whichTemplate = _krData.errorTypes[whichType]; - switch (whichType) { - case "170": - description = `This feature has a FIXME tag: ${description}`; - break; - case "292": - case "293": - description = description.replace("A turn-", "This turn-"); - break; - case "294": - case "295": - case "296": - case "297": - case "298": - description = `This turn-restriction~${description}`; - break; - case "300": - description = "This highway is missing a maxspeed tag"; - break; - case "411": - case "412": - case "413": - description = `This feature~${description}`; - break; - } - let coincident = false; - do { - let delta = coincident ? [1e-5, 0] : [0, 1e-5]; - loc = geoVecAdd(loc, delta); - let bbox = geoExtent(loc).bbox(); - coincident = _cache.rtree.search(bbox).length; - } while (coincident); - let d = new QAItem(loc, this, itemType, id2, { - comment, - description, - whichType, - parentIssueType, - severity: whichTemplate.severity || "error", - objectId, - objectType, - schema, - title - }); - d.replacements = tokenReplacements(d); - _cache.data[id2] = d; - _cache.rtree.insert(encodeIssueRtree(d)); + return false; + function someMissing() { + if (context.inIntro()) + return false; + var osm = context.connection(); + if (osm) { + var missing = coords.filter(function(loc) { + return !osm.isDataLoaded(loc); }); - dispatch2.call("loaded"); - }).catch(() => { - delete _cache.inflightTile[tile.id]; - _cache.loadedTile[tile.id] = true; - }); - }); - }, - postUpdate(d, callback) { - if (_cache.inflightPost[d.id]) { - return callback({ message: "Error update already inflight", status: -2 }, d); + if (missing.length) { + missing.forEach(function(loc) { + context.loadTileAtLoc(loc); + }); + return true; + } + } + return false; } - const params = { schema: d.schema, id: d.id }; - if (d.newStatus) { - params.st = d.newStatus; + function incompleteRelation(id2) { + var entity = context.entity(id2); + return entity.type === "relation" && !entity.isComplete(context.graph()); } - if (d.newComment !== void 0) { - params.co = d.newComment; + }; + operation.tooltip = function() { + var disable = operation.disabled(); + return disable ? _t.append("operations.rotate." + disable + "." + multi) : _t.append("operations.rotate.description." + multi); + }; + operation.annotation = function() { + return selectedIDs.length === 1 ? _t("operations.rotate.annotation." + context.graph().geometry(selectedIDs[0])) : _t("operations.rotate.annotation.feature", { n: selectedIDs.length }); + }; + operation.id = "rotate"; + operation.keys = [_t("operations.rotate.key")]; + operation.title = _t.append("operations.rotate.title"); + operation.behavior = behaviorOperation(context).which(operation); + operation.mouseOnly = true; + return operation; + } + + // modules/modes/move.js + function modeMove(context, entityIDs, baseGraph) { + var _tolerancePx = 4; + var mode = { + id: "move", + button: "browse" + }; + var keybinding = utilKeybinding("move"); + var behaviors = [ + behaviorEdit(context), + operationCircularize(context, entityIDs).behavior, + operationDelete(context, entityIDs).behavior, + operationOrthogonalize(context, entityIDs).behavior, + operationReflectLong(context, entityIDs).behavior, + operationReflectShort(context, entityIDs).behavior, + operationRotate(context, entityIDs).behavior + ]; + var annotation = entityIDs.length === 1 ? _t("operations.move.annotation." + context.graph().geometry(entityIDs[0])) : _t("operations.move.annotation.feature", { n: entityIDs.length }); + var _prevGraph; + var _cache4; + var _origin; + var _nudgeInterval; + var _pointerPrefix = "PointerEvent" in window ? "pointer" : "mouse"; + function doMove(nudge) { + nudge = nudge || [0, 0]; + var fn; + if (_prevGraph !== context.graph()) { + _cache4 = {}; + _origin = context.map().mouseCoordinates(); + fn = context.perform; + } else { + fn = context.overwrite; } - const url = `${_krUrlRoot}/comment.php?` + utilQsString(params); - const controller = new AbortController(); - _cache.inflightPost[d.id] = controller; - json_default(url, { signal: controller.signal }).finally(() => { - delete _cache.inflightPost[d.id]; - if (d.newStatus === "ignore") { - this.removeItem(d); - } else if (d.newStatus === "ignore_t") { - this.removeItem(d); - _cache.closed[`${d.schema}:${d.id}`] = true; - } else { - d = this.replaceItem(d.update({ - comment: d.newComment, - newComment: void 0, - newState: void 0 - })); - } - if (callback) - callback(null, d); - }); - }, - getItems(projection2) { - const viewport = projection2.clipExtent(); - const min3 = [viewport[0][0], viewport[1][1]]; - const max3 = [viewport[1][0], viewport[0][1]]; - const bbox = geoExtent(projection2.invert(min3), projection2.invert(max3)).bbox(); - return _cache.rtree.search(bbox).map((d) => d.data); - }, - getError(id2) { - return _cache.data[id2]; - }, - replaceItem(item) { - if (!(item instanceof QAItem) || !item.id) - return; - _cache.data[item.id] = item; - updateRtree(encodeIssueRtree(item), true); - return item; - }, - removeItem(item) { - if (!(item instanceof QAItem) || !item.id) - return; - delete _cache.data[item.id]; - updateRtree(encodeIssueRtree(item), false); - }, - issueURL(item) { - return `${_krUrlRoot}/report_map.php?schema=${item.schema}&error=${item.id}`; - }, - getClosedIDs() { - return Object.keys(_cache.closed).sort(); + var currMouse = context.map().mouse(); + var origMouse = context.projection(_origin); + var delta = geoVecSubtract(geoVecSubtract(currMouse, origMouse), nudge); + fn(actionMove(entityIDs, delta, context.projection, _cache4)); + _prevGraph = context.graph(); } - }; - - // modules/services/improveOSM.js - var import_rbush2 = __toESM(require_rbush_min()); - var tiler2 = utilTiler(); - var dispatch3 = dispatch_default("loaded"); - var _tileZoom2 = 14; - var _impOsmUrls = { - ow: "https://grab.community.improve-osm.org/directionOfFlowService", - mr: "https://grab.community.improve-osm.org/missingGeoService", - tr: "https://grab.community.improve-osm.org/turnRestrictionService" - }; - var _impOsmData = { icons: {} }; - var _cache2; - function abortRequest2(i2) { - Object.values(i2).forEach((controller) => { - if (controller) { - controller.abort(); + function startNudge(nudge) { + if (_nudgeInterval) + window.clearInterval(_nudgeInterval); + _nudgeInterval = window.setInterval(function() { + context.map().pan(nudge); + doMove(nudge); + }, 50); + } + function stopNudge() { + if (_nudgeInterval) { + window.clearInterval(_nudgeInterval); + _nudgeInterval = null; } - }); - } - function abortUnwantedRequests2(cache, tiles) { - Object.keys(cache.inflightTile).forEach((k) => { - const wanted = tiles.find((tile) => k === tile.id); - if (!wanted) { - abortRequest2(cache.inflightTile[k]); - delete cache.inflightTile[k]; + } + function move() { + doMove(); + var nudge = geoViewportEdge(context.map().mouse(), context.map().dimensions()); + if (nudge) { + startNudge(nudge); + } else { + stopNudge(); } - }); - } - function encodeIssueRtree2(d) { - return { minX: d.loc[0], minY: d.loc[1], maxX: d.loc[0], maxY: d.loc[1], data: d }; - } - function updateRtree2(item, replace) { - _cache2.rtree.remove(item, (a, b) => a.data.id === b.data.id); - if (replace) { - _cache2.rtree.insert(item); } - } - function linkErrorObject(d) { - return { html: `${d}` }; - } - function linkEntity(d) { - return { html: `${d}` }; - } - function pointAverage(points) { - if (points.length) { - const sum = points.reduce( - (acc, point) => geoVecAdd(acc, [point.lon, point.lat]), - [0, 0] - ); - return geoVecScale(sum, 1 / points.length); - } else { - return [0, 0]; + function finish(d3_event) { + d3_event.stopPropagation(); + context.replace(actionNoop(), annotation); + context.enter(modeSelect(context, entityIDs)); + stopNudge(); } - } - function relativeBearing(p1, p2) { - let angle2 = Math.atan2(p2.lon - p1.lon, p2.lat - p1.lat); - if (angle2 < 0) { - angle2 += 2 * Math.PI; + function cancel() { + if (baseGraph) { + while (context.graph() !== baseGraph) + context.pop(); + context.enter(modeBrowse(context)); + } else { + if (_prevGraph) + context.pop(); + context.enter(modeSelect(context, entityIDs)); + } + stopNudge(); } - return angle2 * 180 / Math.PI; - } - function cardinalDirection(bearing) { - const dir = 45 * Math.round(bearing / 45); - const compass = { - 0: "north", - 45: "northeast", - 90: "east", - 135: "southeast", - 180: "south", - 225: "southwest", - 270: "west", - 315: "northwest", - 360: "north" + function undone() { + context.enter(modeBrowse(context)); + } + mode.enter = function() { + _origin = context.map().mouseCoordinates(); + _prevGraph = null; + _cache4 = {}; + context.features().forceVisible(entityIDs); + behaviors.forEach(context.install); + var downEvent; + context.surface().on(_pointerPrefix + "down.modeMove", function(d3_event) { + downEvent = d3_event; + }); + select_default2(window).on(_pointerPrefix + "move.modeMove", move, true).on(_pointerPrefix + "up.modeMove", function(d3_event) { + if (!downEvent) + return; + var mapNode = context.container().select(".main-map").node(); + var pointGetter = utilFastMouse(mapNode); + var p1 = pointGetter(downEvent); + var p2 = pointGetter(d3_event); + var dist = geoVecLength(p1, p2); + if (dist <= _tolerancePx) + finish(d3_event); + downEvent = null; + }, true); + context.history().on("undone.modeMove", undone); + keybinding.on("\u238B", cancel).on("\u21A9", finish); + select_default2(document).call(keybinding); }; - return _t(`QA.improveOSM.directions.${compass[dir]}`); - } - function preventCoincident(loc, bumpUp) { - let coincident = false; - do { - let delta = coincident ? [1e-5, 0] : bumpUp ? [0, 1e-5] : [0, 0]; - loc = geoVecAdd(loc, delta); - let bbox = geoExtent(loc).bbox(); - coincident = _cache2.rtree.search(bbox).length; - } while (coincident); - return loc; + mode.exit = function() { + stopNudge(); + behaviors.forEach(function(behavior) { + context.uninstall(behavior); + }); + context.surface().on(_pointerPrefix + "down.modeMove", null); + select_default2(window).on(_pointerPrefix + "move.modeMove", null, true).on(_pointerPrefix + "up.modeMove", null, true); + context.history().on("undone.modeMove", null); + select_default2(document).call(keybinding.unbind); + context.features().forceVisible([]); + }; + mode.selectedIDs = function() { + if (!arguments.length) + return entityIDs; + return mode; + }; + return mode; } - var improveOSM_default = { - title: "improveOSM", - init() { - _mainFileFetcher.get("qa_data").then((d) => _impOsmData = d.improveOSM); - if (!_cache2) { - this.reset(); - } - this.event = utilRebind(this, dispatch3, "on"); - }, - reset() { - if (_cache2) { - Object.values(_cache2.inflightTile).forEach(abortRequest2); - } - _cache2 = { - data: {}, - loadedTile: {}, - inflightTile: {}, - inflightPost: {}, - closed: {}, - rtree: new import_rbush2.default() - }; - }, - loadIssues(projection2) { - const options2 = { - client: "iD", - status: "OPEN", - zoom: "19" - }; - const tiles = tiler2.zoomExtent([_tileZoom2, _tileZoom2]).getTiles(projection2); - abortUnwantedRequests2(_cache2, tiles); - tiles.forEach((tile) => { - if (_cache2.loadedTile[tile.id] || _cache2.inflightTile[tile.id]) - return; - const [east, north, west, south] = tile.extent.rectangle(); - const params = Object.assign({}, options2, { east, south, west, north }); - const requests = {}; - Object.keys(_impOsmUrls).forEach((k) => { - const kParams = Object.assign( - {}, - params, - k === "mr" ? { type: "PARKING,ROAD,BOTH,PATH" } : { confidenceLevel: "C1" } - ); - const url = `${_impOsmUrls[k]}/search?` + utilQsString(kParams); - const controller = new AbortController(); - requests[k] = controller; - json_default(url, { signal: controller.signal }).then((data) => { - delete _cache2.inflightTile[tile.id][k]; - if (!Object.keys(_cache2.inflightTile[tile.id]).length) { - delete _cache2.inflightTile[tile.id]; - _cache2.loadedTile[tile.id] = true; - } - if (data.roadSegments) { - data.roadSegments.forEach((feature3) => { - const { points, wayId, fromNodeId, toNodeId } = feature3; - const itemId = `${wayId}${fromNodeId}${toNodeId}`; - let mid = points.length / 2; - let loc; - if (mid % 1 === 0) { - loc = pointAverage([points[mid - 1], points[mid]]); - } else { - mid = points[Math.floor(mid)]; - loc = [mid.lon, mid.lat]; - } - loc = preventCoincident(loc, false); - let d = new QAItem(loc, this, k, itemId, { - issueKey: k, - identifier: { - wayId, - fromNodeId, - toNodeId - }, - objectId: wayId, - objectType: "way" - }); - d.replacements = { - percentage: feature3.percentOfTrips, - num_trips: feature3.numberOfTrips, - highway: linkErrorObject(_t("QA.keepRight.error_parts.highway")), - from_node: linkEntity("n" + feature3.fromNodeId), - to_node: linkEntity("n" + feature3.toNodeId) - }; - _cache2.data[d.id] = d; - _cache2.rtree.insert(encodeIssueRtree2(d)); - }); - } - if (data.tiles) { - data.tiles.forEach((feature3) => { - const { type: type3, x, y, numberOfTrips } = feature3; - const geoType = type3.toLowerCase(); - const itemId = `${geoType}${x}${y}${numberOfTrips}`; - let loc = pointAverage(feature3.points); - loc = preventCoincident(loc, false); - let d = new QAItem(loc, this, `${k}-${geoType}`, itemId, { - issueKey: k, - identifier: { x, y } - }); - d.replacements = { - num_trips: numberOfTrips, - geometry_type: _t(`QA.improveOSM.geometry_types.${geoType}`) - }; - if (numberOfTrips === -1) { - d.desc = _t("QA.improveOSM.error_types.mr.description_alt", d.replacements); - } - _cache2.data[d.id] = d; - _cache2.rtree.insert(encodeIssueRtree2(d)); - }); - } - if (data.entities) { - data.entities.forEach((feature3) => { - const { point, id: id2, segments, numberOfPasses, turnType } = feature3; - const itemId = `${id2.replace(/[,:+#]/g, "_")}`; - const loc = preventCoincident([point.lon, point.lat], true); - const ids = id2.split(","); - const from_way = ids[0]; - const via_node = ids[3]; - const to_way = ids[2].split(":")[1]; - let d = new QAItem(loc, this, k, itemId, { - issueKey: k, - identifier: id2, - objectId: via_node, - objectType: "node" - }); - const [p1, p2] = segments[0].points; - const dir_of_travel = cardinalDirection(relativeBearing(p1, p2)); - d.replacements = { - num_passed: numberOfPasses, - num_trips: segments[0].numberOfTrips, - turn_restriction: turnType.toLowerCase(), - from_way: linkEntity("w" + from_way), - to_way: linkEntity("w" + to_way), - travel_direction: dir_of_travel, - junction: linkErrorObject(_t("QA.keepRight.error_parts.this_node")) - }; - _cache2.data[d.id] = d; - _cache2.rtree.insert(encodeIssueRtree2(d)); - dispatch3.call("loaded"); - }); - } - }).catch(() => { - delete _cache2.inflightTile[tile.id][k]; - if (!Object.keys(_cache2.inflightTile[tile.id]).length) { - delete _cache2.inflightTile[tile.id]; - _cache2.loadedTile[tile.id] = true; - } - }); - }); - _cache2.inflightTile[tile.id] = requests; + + // modules/behavior/paste.js + function behaviorPaste(context) { + function doPaste(d3_event) { + if (!context.map().withinEditableZoom()) + return; + d3_event.preventDefault(); + var baseGraph = context.graph(); + var mouse = context.map().mouse(); + var projection2 = context.projection; + var viewport = geoExtent(projection2.clipExtent()).polygon(); + if (!geoPointInPolygon(mouse, viewport)) + return; + var oldIDs = context.copyIDs(); + if (!oldIDs.length) + return; + var extent = geoExtent(); + var oldGraph = context.copyGraph(); + var newIDs = []; + var action = actionCopyEntities(oldIDs, oldGraph); + context.perform(action); + var copies = action.copies(); + var originals = /* @__PURE__ */ new Set(); + Object.values(copies).forEach(function(entity) { + originals.add(entity.id); }); - }, - getComments(item) { - if (item.comments) { - return Promise.resolve(item); - } - const key = item.issueKey; - let qParams = {}; - if (key === "ow") { - qParams = item.identifier; - } else if (key === "mr") { - qParams.tileX = item.identifier.x; - qParams.tileY = item.identifier.y; - } else if (key === "tr") { - qParams.targetId = item.identifier; + for (var id2 in copies) { + var oldEntity = oldGraph.entity(id2); + var newEntity = copies[id2]; + extent._extend(oldEntity.extent(oldGraph)); + var parents = context.graph().parentWays(newEntity); + var parentCopied = parents.some(function(parent) { + return originals.has(parent.id); + }); + if (!parentCopied) { + newIDs.push(newEntity.id); + } } - const url = `${_impOsmUrls[key]}/retrieveComments?` + utilQsString(qParams); - const cacheComments = (data) => { - item.comments = data.comments ? data.comments.reverse() : []; - this.replaceItem(item); + var copyPoint = context.copyLonLat() && projection2(context.copyLonLat()) || projection2(extent.center()); + var delta = geoVecSubtract(mouse, copyPoint); + context.perform(actionMove(newIDs, delta, projection2)); + context.enter(modeMove(context, newIDs, baseGraph)); + } + function behavior() { + context.keybinding().on(uiCmd("\u2318V"), doPaste); + return behavior; + } + behavior.off = function() { + context.keybinding().off(uiCmd("\u2318V")); + }; + return behavior; + } + + // modules/behavior/drag.js + function behaviorDrag() { + var dispatch10 = dispatch_default("start", "move", "end"); + var _tolerancePx = 1; + var _penTolerancePx = 4; + var _origin = null; + var _selector = ""; + var _targetNode; + var _targetEntity; + var _surface; + var _pointerId; + var _pointerPrefix = "PointerEvent" in window ? "pointer" : "mouse"; + var d3_event_userSelectProperty = utilPrefixCSSProperty("UserSelect"); + var d3_event_userSelectSuppress = function() { + var selection2 = selection_default(); + var select = selection2.style(d3_event_userSelectProperty); + selection2.style(d3_event_userSelectProperty, "none"); + return function() { + selection2.style(d3_event_userSelectProperty, select); }; - return json_default(url).then(cacheComments).then(() => item); - }, - postUpdate(d, callback) { - if (!osm_default.authenticated()) { - return callback({ message: "Not Authenticated", status: -3 }, d); - } - if (_cache2.inflightPost[d.id]) { - return callback({ message: "Error update already inflight", status: -2 }, d); + }; + function pointerdown(d3_event) { + if (_pointerId) + return; + _pointerId = d3_event.pointerId || "mouse"; + _targetNode = this; + var pointerLocGetter = utilFastMouse(_surface || _targetNode.parentNode); + var offset; + var startOrigin = pointerLocGetter(d3_event); + var started = false; + var selectEnable = d3_event_userSelectSuppress(); + select_default2(window).on(_pointerPrefix + "move.drag", pointermove).on(_pointerPrefix + "up.drag pointercancel.drag", pointerup, true); + if (_origin) { + offset = _origin.call(_targetNode, _targetEntity); + offset = [offset[0] - startOrigin[0], offset[1] - startOrigin[1]]; + } else { + offset = [0, 0]; } - osm_default.userDetails(sendPayload.bind(this)); - function sendPayload(err, user) { - if (err) { - return callback(err, d); - } - const key = d.issueKey; - const url = `${_impOsmUrls[key]}/comment`; - const payload = { - username: user.display_name, - targetIds: [d.identifier] - }; - if (d.newStatus) { - payload.status = d.newStatus; - payload.text = "status changed"; + d3_event.stopPropagation(); + function pointermove(d3_event2) { + if (_pointerId !== (d3_event2.pointerId || "mouse")) + return; + var p = pointerLocGetter(d3_event2); + if (!started) { + var dist = geoVecLength(startOrigin, p); + var tolerance = d3_event2.pointerType === "pen" ? _penTolerancePx : _tolerancePx; + if (dist < tolerance) + return; + started = true; + dispatch10.call("start", this, d3_event2, _targetEntity); + } else { + startOrigin = p; + d3_event2.stopPropagation(); + d3_event2.preventDefault(); + var dx = p[0] - startOrigin[0]; + var dy = p[1] - startOrigin[1]; + dispatch10.call("move", this, d3_event2, _targetEntity, [p[0] + offset[0], p[1] + offset[1]], [dx, dy]); } - if (d.newComment) { - payload.text = d.newComment; + } + function pointerup(d3_event2) { + if (_pointerId !== (d3_event2.pointerId || "mouse")) + return; + _pointerId = null; + if (started) { + dispatch10.call("end", this, d3_event2, _targetEntity); + d3_event2.preventDefault(); } - const controller = new AbortController(); - _cache2.inflightPost[d.id] = controller; - const options2 = { - method: "POST", - signal: controller.signal, - body: JSON.stringify(payload) - }; - json_default(url, options2).then(() => { - delete _cache2.inflightPost[d.id]; - if (!d.newStatus) { - const now3 = new Date(); - let comments = d.comments ? d.comments : []; - comments.push({ - username: payload.username, - text: payload.text, - timestamp: now3.getTime() / 1e3 - }); - this.replaceItem(d.update({ - comments, - newComment: void 0 - })); - } else { - this.removeItem(d); - if (d.newStatus === "SOLVED") { - if (!(d.issueKey in _cache2.closed)) { - _cache2.closed[d.issueKey] = 0; - } - _cache2.closed[d.issueKey] += 1; + select_default2(window).on(_pointerPrefix + "move.drag", null).on(_pointerPrefix + "up.drag pointercancel.drag", null); + selectEnable(); + } + } + function behavior(selection2) { + var matchesSelector = utilPrefixDOMProperty("matchesSelector"); + var delegate = pointerdown; + if (_selector) { + delegate = function(d3_event) { + var root3 = this; + var target = d3_event.target; + for (; target && target !== root3; target = target.parentNode) { + var datum2 = target.__data__; + _targetEntity = datum2 instanceof osmNote ? datum2 : datum2 && datum2.properties && datum2.properties.entity; + if (_targetEntity && target[matchesSelector](_selector)) { + return pointerdown.call(target, d3_event); } } - if (callback) - callback(null, d); - }).catch((err2) => { - delete _cache2.inflightPost[d.id]; - if (callback) - callback(err2.message); - }); + }; } - }, - getItems(projection2) { - const viewport = projection2.clipExtent(); - const min3 = [viewport[0][0], viewport[1][1]]; - const max3 = [viewport[1][0], viewport[0][1]]; - const bbox = geoExtent(projection2.invert(min3), projection2.invert(max3)).bbox(); - return _cache2.rtree.search(bbox).map((d) => d.data); - }, - getError(id2) { - return _cache2.data[id2]; - }, - getIcon(itemType) { - return _impOsmData.icons[itemType]; - }, - replaceItem(issue) { - if (!(issue instanceof QAItem) || !issue.id) - return; - _cache2.data[issue.id] = issue; - updateRtree2(encodeIssueRtree2(issue), true); - return issue; - }, - removeItem(issue) { - if (!(issue instanceof QAItem) || !issue.id) - return; - delete _cache2.data[issue.id]; - updateRtree2(encodeIssueRtree2(issue), false); - }, - getClosedCounts() { - return _cache2.closed; + selection2.on(_pointerPrefix + "down.drag" + _selector, delegate); } - }; - - // modules/services/osmose.js - var import_rbush3 = __toESM(require_rbush_min()); - - // node_modules/marked/lib/marked.esm.js - function getDefaults() { - return { - async: false, - baseUrl: null, - breaks: false, - extensions: null, - gfm: true, - headerIds: true, - headerPrefix: "", - highlight: null, - langPrefix: "language-", - mangle: true, - pedantic: false, - renderer: null, - sanitize: false, - sanitizer: null, - silent: false, - smartLists: false, - smartypants: false, - tokenizer: null, - walkTokens: null, - xhtml: false + behavior.off = function(selection2) { + selection2.on(_pointerPrefix + "down.drag" + _selector, null); }; + behavior.selector = function(_) { + if (!arguments.length) + return _selector; + _selector = _; + return behavior; + }; + behavior.origin = function(_) { + if (!arguments.length) + return _origin; + _origin = _; + return behavior; + }; + behavior.cancel = function() { + select_default2(window).on(_pointerPrefix + "move.drag", null).on(_pointerPrefix + "up.drag pointercancel.drag", null); + return behavior; + }; + behavior.targetNode = function(_) { + if (!arguments.length) + return _targetNode; + _targetNode = _; + return behavior; + }; + behavior.targetEntity = function(_) { + if (!arguments.length) + return _targetEntity; + _targetEntity = _; + return behavior; + }; + behavior.surface = function(_) { + if (!arguments.length) + return _surface; + _surface = _; + return behavior; + }; + return utilRebind(behavior, dispatch10, "on"); } - var defaults = getDefaults(); - function changeDefaults(newDefaults) { - defaults = newDefaults; - } - var escapeTest = /[&<>"']/; - var escapeReplace = /[&<>"']/g; - var escapeTestNoEncode = /[<>"']|&(?!#?\w+;)/; - var escapeReplaceNoEncode = /[<>"']|&(?!#?\w+;)/g; - var escapeReplacements = { - "&": "&", - "<": "<", - ">": ">", - '"': """, - "'": "'" - }; - var getEscapeReplacement = (ch) => escapeReplacements[ch]; - function escape4(html2, encode) { - if (encode) { - if (escapeTest.test(html2)) { - return html2.replace(escapeReplace, getEscapeReplacement); - } - } else { - if (escapeTestNoEncode.test(html2)) { - return html2.replace(escapeReplaceNoEncode, getEscapeReplacement); - } - } - return html2; - } - var unescapeTest = /&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig; - function unescape3(html2) { - return html2.replace(unescapeTest, (_, n2) => { - n2 = n2.toLowerCase(); - if (n2 === "colon") - return ":"; - if (n2.charAt(0) === "#") { - return n2.charAt(1) === "x" ? String.fromCharCode(parseInt(n2.substring(2), 16)) : String.fromCharCode(+n2.substring(1)); - } - return ""; - }); - } - var caret = /(^|[^\[])\^/g; - function edit(regex, opt) { - regex = typeof regex === "string" ? regex : regex.source; - opt = opt || ""; - const obj = { - replace: (name, val) => { - val = val.source || val; - val = val.replace(caret, "$1"); - regex = regex.replace(name, val); - return obj; - }, - getRegex: () => { - return new RegExp(regex, opt); - } + + // modules/modes/drag_node.js + function modeDragNode(context) { + var mode = { + id: "drag-node", + button: "browse" }; - return obj; - } - var nonWordAndColonTest = /[^\w:]/g; - var originIndependentUrl = /^$|^[a-z][a-z0-9+.-]*:|^[?#]/i; - function cleanUrl(sanitize, base, href) { - if (sanitize) { - let prot; - try { - prot = decodeURIComponent(unescape3(href)).replace(nonWordAndColonTest, "").toLowerCase(); - } catch (e) { - return null; + var hover = behaviorHover(context).altDisables(true).on("hover", context.ui().sidebar.hover); + var edit2 = behaviorEdit(context); + var _nudgeInterval; + var _restoreSelectedIDs = []; + var _wasMidpoint = false; + var _isCancelled = false; + var _activeEntity; + var _startLoc; + var _lastLoc; + function startNudge(d3_event, entity, nudge) { + if (_nudgeInterval) + window.clearInterval(_nudgeInterval); + _nudgeInterval = window.setInterval(function() { + context.map().pan(nudge); + doMove(d3_event, entity, nudge); + }, 50); + } + function stopNudge() { + if (_nudgeInterval) { + window.clearInterval(_nudgeInterval); + _nudgeInterval = null; } - if (prot.indexOf("javascript:") === 0 || prot.indexOf("vbscript:") === 0 || prot.indexOf("data:") === 0) { - return null; + } + function moveAnnotation(entity) { + return _t("operations.move.annotation." + entity.geometry(context.graph())); + } + function connectAnnotation(nodeEntity, targetEntity) { + var nodeGeometry = nodeEntity.geometry(context.graph()); + var targetGeometry = targetEntity.geometry(context.graph()); + if (nodeGeometry === "vertex" && targetGeometry === "vertex") { + var nodeParentWayIDs = context.graph().parentWays(nodeEntity); + var targetParentWayIDs = context.graph().parentWays(targetEntity); + var sharedParentWays = utilArrayIntersection(nodeParentWayIDs, targetParentWayIDs); + if (sharedParentWays.length !== 0) { + if (sharedParentWays[0].areAdjacent(nodeEntity.id, targetEntity.id)) { + return _t("operations.connect.annotation.from_vertex.to_adjacent_vertex"); + } + return _t("operations.connect.annotation.from_vertex.to_sibling_vertex"); + } } + return _t("operations.connect.annotation.from_" + nodeGeometry + ".to_" + targetGeometry); } - if (base && !originIndependentUrl.test(href)) { - href = resolveUrl(base, href); + function shouldSnapToNode(target) { + if (!_activeEntity) + return false; + return _activeEntity.geometry(context.graph()) !== "vertex" || (target.geometry(context.graph()) === "vertex" || _mainPresetIndex.allowsVertex(target, context.graph())); } - try { - href = encodeURI(href).replace(/%25/g, "%"); - } catch (e) { - return null; + function origin(entity) { + return context.projection(entity.loc); } - return href; - } - var baseUrls = {}; - var justDomain = /^[^:]+:\/*[^/]*$/; - var protocol = /^([^:]+:)[\s\S]*$/; - var domain = /^([^:]+:\/*[^/]*)[\s\S]*$/; - function resolveUrl(base, href) { - if (!baseUrls[" " + base]) { - if (justDomain.test(base)) { - baseUrls[" " + base] = base + "/"; - } else { - baseUrls[" " + base] = rtrim(base, "/", true); + function keydown(d3_event) { + if (d3_event.keyCode === utilKeybinding.modifierCodes.alt) { + if (context.surface().classed("nope")) { + context.surface().classed("nope-suppressed", true); + } + context.surface().classed("nope", false).classed("nope-disabled", true); } } - base = baseUrls[" " + base]; - const relativeBase = base.indexOf(":") === -1; - if (href.substring(0, 2) === "//") { - if (relativeBase) { - return href; - } - return base.replace(protocol, "$1") + href; - } else if (href.charAt(0) === "/") { - if (relativeBase) { - return href; + function keyup(d3_event) { + if (d3_event.keyCode === utilKeybinding.modifierCodes.alt) { + if (context.surface().classed("nope-suppressed")) { + context.surface().classed("nope", true); + } + context.surface().classed("nope-suppressed", false).classed("nope-disabled", false); } - return base.replace(domain, "$1") + href; - } else { - return base + href; } - } - var noopTest = { exec: function noopTest2() { - } }; - function merge2(obj) { - let i2 = 1, target, key; - for (; i2 < arguments.length; i2++) { - target = arguments[i2]; - for (key in target) { - if (Object.prototype.hasOwnProperty.call(target, key)) { - obj[key] = target[key]; + function start2(d3_event, entity) { + _wasMidpoint = entity.type === "midpoint"; + var hasHidden = context.features().hasHiddenConnections(entity, context.graph()); + _isCancelled = !context.editable() || d3_event.shiftKey || hasHidden; + if (_isCancelled) { + if (hasHidden) { + context.ui().flash.duration(4e3).iconName("#iD-icon-no").label(_t.append("modes.drag_node.connected_to_hidden"))(); } + return drag.cancel(); } - } - return obj; - } - function splitCells(tableRow, count) { - const row = tableRow.replace(/\|/g, (match, offset, str2) => { - let escaped = false, curr = offset; - while (--curr >= 0 && str2[curr] === "\\") - escaped = !escaped; - if (escaped) { - return "|"; + if (_wasMidpoint) { + var midpoint = entity; + entity = osmNode(); + context.perform(actionAddMidpoint(midpoint, entity)); + entity = context.entity(entity.id); + var vertex = context.surface().selectAll("." + entity.id); + drag.targetNode(vertex.node()).targetEntity(entity); } else { - return " |"; + context.perform(actionNoop()); } - }), cells = row.split(/ \|/); - let i2 = 0; - if (!cells[0].trim()) { - cells.shift(); - } - if (cells.length > 0 && !cells[cells.length - 1].trim()) { - cells.pop(); - } - if (cells.length > count) { - cells.splice(count); - } else { - while (cells.length < count) - cells.push(""); - } - for (; i2 < cells.length; i2++) { - cells[i2] = cells[i2].trim().replace(/\\\|/g, "|"); - } - return cells; - } - function rtrim(str2, c, invert) { - const l = str2.length; - if (l === 0) { - return ""; + _activeEntity = entity; + _startLoc = entity.loc; + hover.ignoreVertex(entity.geometry(context.graph()) === "vertex"); + context.surface().selectAll("." + _activeEntity.id).classed("active", true); + context.enter(mode); } - let suffLen = 0; - while (suffLen < l) { - const currChar = str2.charAt(l - suffLen - 1); - if (currChar === c && !invert) { - suffLen++; - } else if (currChar !== c && invert) { - suffLen++; + function datum2(d3_event) { + if (!d3_event || d3_event.altKey) { + return {}; } else { - break; + var d = d3_event.target.__data__; + return d && d.properties && d.properties.target ? d : {}; } } - return str2.slice(0, l - suffLen); - } - function findClosingBracket(str2, b) { - if (str2.indexOf(b[1]) === -1) { - return -1; - } - const l = str2.length; - let level = 0, i2 = 0; - for (; i2 < l; i2++) { - if (str2[i2] === "\\") { - i2++; - } else if (str2[i2] === b[0]) { - level++; - } else if (str2[i2] === b[1]) { - level--; - if (level < 0) { - return i2; + function doMove(d3_event, entity, nudge) { + nudge = nudge || [0, 0]; + var currPoint = d3_event && d3_event.point || context.projection(_lastLoc); + var currMouse = geoVecSubtract(currPoint, nudge); + var loc = context.projection.invert(currMouse); + var target, edge; + if (!_nudgeInterval) { + var d = datum2(d3_event); + target = d && d.properties && d.properties.entity; + var targetLoc = target && target.loc; + var targetNodes = d && d.properties && d.properties.nodes; + if (targetLoc) { + if (shouldSnapToNode(target)) { + loc = targetLoc; + } + } else if (targetNodes) { + edge = geoChooseEdge(targetNodes, context.map().mouse(), context.projection, end.id); + if (edge) { + loc = edge.loc; + } } } - } - return -1; - } - function checkSanitizeDeprecation(opt) { - if (opt && opt.sanitize && !opt.silent) { - console.warn("marked(): sanitize and sanitizer parameters are deprecated since version 0.7.0, should not be used and will be removed in the future. Read more here: https://marked.js.org/#/USING_ADVANCED.md#options"); - } - } - function repeatString(pattern, count) { - if (count < 1) { - return ""; - } - let result = ""; - while (count > 1) { - if (count & 1) { - result += pattern; - } - count >>= 1; - pattern += pattern; - } - return result + pattern; - } - function outputLink(cap, link2, raw, lexer2) { - const href = link2.href; - const title = link2.title ? escape4(link2.title) : null; - const text2 = cap[1].replace(/\\([\[\]])/g, "$1"); - if (cap[0].charAt(0) !== "!") { - lexer2.state.inLink = true; - const token = { - type: "link", - raw, - href, - title, - text: text2, - tokens: lexer2.inlineTokens(text2) - }; - lexer2.state.inLink = false; - return token; - } - return { - type: "image", - raw, - href, - title, - text: escape4(text2) - }; - } - function indentCodeCompensation(raw, text2) { - const matchIndentToCode = raw.match(/^(\s+)(?:```)/); - if (matchIndentToCode === null) { - return text2; - } - const indentToCode = matchIndentToCode[1]; - return text2.split("\n").map((node) => { - const matchIndentInNode = node.match(/^\s+/); - if (matchIndentInNode === null) { - return node; + context.replace( + actionMoveNode(entity.id, loc) + ); + var isInvalid = false; + if (target) { + isInvalid = hasRelationConflict(entity, target, edge, context.graph()); } - const [indentInNode] = matchIndentInNode; - if (indentInNode.length >= indentToCode.length) { - return node.slice(indentToCode.length); + if (!isInvalid) { + isInvalid = hasInvalidGeometry(entity, context.graph()); } - return node; - }).join("\n"); - } - var Tokenizer = class { - constructor(options2) { - this.options = options2 || defaults; - } - space(src) { - const cap = this.rules.block.newline.exec(src); - if (cap && cap[0].length > 0) { - return { - type: "space", - raw: cap[0] - }; + var nope = context.surface().classed("nope"); + if (isInvalid === "relation" || isInvalid === "restriction") { + if (!nope) { + context.ui().flash.duration(4e3).iconName("#iD-icon-no").label(_t.append( + "operations.connect." + isInvalid, + { relation: _mainPresetIndex.item("type/restriction").name() } + ))(); + } + } else if (isInvalid) { + var errorID = isInvalid === "line" ? "lines" : "areas"; + context.ui().flash.duration(3e3).iconName("#iD-icon-no").label(_t.append("self_intersection.error." + errorID))(); + } else { + if (nope) { + context.ui().flash.duration(1).label("")(); + } } - } - code(src) { - const cap = this.rules.block.code.exec(src); - if (cap) { - const text2 = cap[0].replace(/^ {1,4}/gm, ""); - return { - type: "code", - raw: cap[0], - codeBlockStyle: "indented", - text: !this.options.pedantic ? rtrim(text2, "\n") : text2 - }; + var nopeDisabled = context.surface().classed("nope-disabled"); + if (nopeDisabled) { + context.surface().classed("nope", false).classed("nope-suppressed", isInvalid); + } else { + context.surface().classed("nope", isInvalid).classed("nope-suppressed", false); } + _lastLoc = loc; } - fences(src) { - const cap = this.rules.block.fences.exec(src); - if (cap) { - const raw = cap[0]; - const text2 = indentCodeCompensation(raw, cap[3] || ""); - return { - type: "code", - raw, - lang: cap[2] ? cap[2].trim() : cap[2], - text: text2 - }; + function hasRelationConflict(entity, target, edge, graph) { + var testGraph = graph.update(); + if (edge) { + var midpoint = osmNode(); + var action = actionAddMidpoint({ + loc: edge.loc, + edge: [target.nodes[edge.index - 1], target.nodes[edge.index]] + }, midpoint); + testGraph = action(testGraph); + target = midpoint; } + var ids = [entity.id, target.id]; + return actionConnect(ids).disabled(testGraph); } - heading(src) { - const cap = this.rules.block.heading.exec(src); - if (cap) { - let text2 = cap[2].trim(); - if (/#$/.test(text2)) { - const trimmed = rtrim(text2, "#"); - if (this.options.pedantic) { - text2 = trimmed.trim(); - } else if (!trimmed || / $/.test(trimmed)) { - text2 = trimmed.trim(); + function hasInvalidGeometry(entity, graph) { + var parents = graph.parentWays(entity); + var i2, j2, k; + for (i2 = 0; i2 < parents.length; i2++) { + var parent = parents[i2]; + var nodes = []; + var activeIndex = null; + var relations = graph.parentRelations(parent); + for (j2 = 0; j2 < relations.length; j2++) { + if (!relations[j2].isMultipolygon()) + continue; + var rings = osmJoinWays(relations[j2].members, graph); + for (k = 0; k < rings.length; k++) { + nodes = rings[k].nodes; + if (nodes.find(function(n2) { + return n2.id === entity.id; + })) { + activeIndex = k; + if (geoHasSelfIntersections(nodes, entity.id)) { + return "multipolygonMember"; + } + } + rings[k].coords = nodes.map(function(n2) { + return n2.loc; + }); + } + for (k = 0; k < rings.length; k++) { + if (k === activeIndex) + continue; + if (geoHasLineIntersections(rings[activeIndex].nodes, rings[k].nodes, entity.id)) { + return "multipolygonRing"; + } + } + } + if (activeIndex === null) { + nodes = parent.nodes.map(function(nodeID) { + return graph.entity(nodeID); + }); + if (nodes.length && geoHasSelfIntersections(nodes, entity.id)) { + return parent.geometry(graph); } } - return { - type: "heading", - raw: cap[0], - depth: cap[1].length, - text: text2, - tokens: this.lexer.inline(text2) - }; } + return false; } - hr(src) { - const cap = this.rules.block.hr.exec(src); - if (cap) { - return { - type: "hr", - raw: cap[0] - }; + function move(d3_event, entity, point2) { + if (_isCancelled) + return; + d3_event.stopPropagation(); + context.surface().classed("nope-disabled", d3_event.altKey); + _lastLoc = context.projection.invert(point2); + doMove(d3_event, entity); + var nudge = geoViewportEdge(point2, context.map().dimensions()); + if (nudge) { + startNudge(d3_event, entity, nudge); + } else { + stopNudge(); } } - blockquote(src) { - const cap = this.rules.block.blockquote.exec(src); - if (cap) { - const text2 = cap[0].replace(/^ *>[ \t]?/gm, ""); - return { - type: "blockquote", - raw: cap[0], - tokens: this.lexer.blockTokens(text2, []), - text: text2 - }; + function end(d3_event, entity) { + if (_isCancelled) + return; + var wasPoint = entity.geometry(context.graph()) === "point"; + var d = datum2(d3_event); + var nope = d && d.properties && d.properties.nope || context.surface().classed("nope"); + var target = d && d.properties && d.properties.entity; + if (nope) { + context.perform( + _actionBounceBack(entity.id, _startLoc) + ); + } else if (target && target.type === "way") { + var choice = geoChooseEdge(context.graph().childNodes(target), context.map().mouse(), context.projection, entity.id); + context.replace( + actionAddMidpoint({ + loc: choice.loc, + edge: [target.nodes[choice.index - 1], target.nodes[choice.index]] + }, entity), + connectAnnotation(entity, target) + ); + } else if (target && target.type === "node" && shouldSnapToNode(target)) { + context.replace( + actionConnect([target.id, entity.id]), + connectAnnotation(entity, target) + ); + } else if (_wasMidpoint) { + context.replace( + actionNoop(), + _t("operations.add.annotation.vertex") + ); + } else { + context.replace( + actionNoop(), + moveAnnotation(entity) + ); } - } - list(src) { - let cap = this.rules.block.list.exec(src); - if (cap) { - let raw, istask, ischecked, indent2, i2, blankLine, endsWithBlankLine, line, nextLine, rawLine, itemContents, endEarly; - let bull = cap[1].trim(); - const isordered = bull.length > 1; - const list = { - type: "list", - raw: "", - ordered: isordered, - start: isordered ? +bull.slice(0, -1) : "", - loose: false, - items: [] - }; - bull = isordered ? `\\d{1,9}\\${bull.slice(-1)}` : `\\${bull}`; - if (this.options.pedantic) { - bull = isordered ? bull : "[*+-]"; - } - const itemRegex = new RegExp(`^( {0,3}${bull})((?:[ ][^\\n]*)?(?:\\n|$))`); - while (src) { - endEarly = false; - if (!(cap = itemRegex.exec(src))) { - break; - } - if (this.rules.block.hr.test(src)) { - break; - } - raw = cap[0]; - src = src.substring(raw.length); - line = cap[2].split("\n", 1)[0]; - nextLine = src.split("\n", 1)[0]; - if (this.options.pedantic) { - indent2 = 2; - itemContents = line.trimLeft(); - } else { - indent2 = cap[2].search(/[^ ]/); - indent2 = indent2 > 4 ? 1 : indent2; - itemContents = line.slice(indent2); - indent2 += cap[1].length; - } - blankLine = false; - if (!line && /^ *$/.test(nextLine)) { - raw += nextLine + "\n"; - src = src.substring(nextLine.length + 1); - endEarly = true; - } - if (!endEarly) { - const nextBulletRegex = new RegExp(`^ {0,${Math.min(3, indent2 - 1)}}(?:[*+-]|\\d{1,9}[.)])((?: [^\\n]*)?(?:\\n|$))`); - const hrRegex = new RegExp(`^ {0,${Math.min(3, indent2 - 1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`); - const fencesBeginRegex = new RegExp(`^ {0,${Math.min(3, indent2 - 1)}}(?:\`\`\`|~~~)`); - const headingBeginRegex = new RegExp(`^ {0,${Math.min(3, indent2 - 1)}}#`); - while (src) { - rawLine = src.split("\n", 1)[0]; - line = rawLine; - if (this.options.pedantic) { - line = line.replace(/^ {1,4}(?=( {4})*[^ ])/g, " "); - } - if (fencesBeginRegex.test(line)) { - break; - } - if (headingBeginRegex.test(line)) { - break; - } - if (nextBulletRegex.test(line)) { - break; - } - if (hrRegex.test(src)) { - break; - } - if (line.search(/[^ ]/) >= indent2 || !line.trim()) { - itemContents += "\n" + line.slice(indent2); - } else if (!blankLine) { - itemContents += "\n" + line; - } else { - break; - } - if (!blankLine && !line.trim()) { - blankLine = true; - } - raw += rawLine + "\n"; - src = src.substring(rawLine.length + 1); - } - } - if (!list.loose) { - if (endsWithBlankLine) { - list.loose = true; - } else if (/\n *\n *$/.test(raw)) { - endsWithBlankLine = true; - } - } - if (this.options.gfm) { - istask = /^\[[ xX]\] /.exec(itemContents); - if (istask) { - ischecked = istask[0] !== "[ ] "; - itemContents = itemContents.replace(/^\[[ xX]\] +/, ""); - } - } - list.items.push({ - type: "list_item", - raw, - task: !!istask, - checked: ischecked, - loose: false, - text: itemContents - }); - list.raw += raw; - } - list.items[list.items.length - 1].raw = raw.trimRight(); - list.items[list.items.length - 1].text = itemContents.trimRight(); - list.raw = list.raw.trimRight(); - const l = list.items.length; - for (i2 = 0; i2 < l; i2++) { - this.lexer.state.top = false; - list.items[i2].tokens = this.lexer.blockTokens(list.items[i2].text, []); - const spacers = list.items[i2].tokens.filter((t) => t.type === "space"); - const hasMultipleLineBreaks = spacers.every((t) => { - const chars = t.raw.split(""); - let lineBreaks = 0; - for (const char of chars) { - if (char === "\n") { - lineBreaks += 1; - } - if (lineBreaks > 1) { - return true; - } - } - return false; - }); - if (!list.loose && spacers.length && hasMultipleLineBreaks) { - list.loose = true; - list.items[i2].loose = true; - } - } - return list; - } - } - html(src) { - const cap = this.rules.block.html.exec(src); - if (cap) { - const token = { - type: "html", - raw: cap[0], - pre: !this.options.sanitizer && (cap[1] === "pre" || cap[1] === "script" || cap[1] === "style"), - text: cap[0] - }; - if (this.options.sanitize) { - const text2 = this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape4(cap[0]); - token.type = "paragraph"; - token.text = text2; - token.tokens = this.lexer.inline(text2); + if (wasPoint) { + context.enter(modeSelect(context, [entity.id])); + } else { + var reselection = _restoreSelectedIDs.filter(function(id2) { + return context.graph().hasEntity(id2); + }); + if (reselection.length) { + context.enter(modeSelect(context, reselection)); + } else { + context.enter(modeBrowse(context)); } - return token; - } - } - def(src) { - const cap = this.rules.block.def.exec(src); - if (cap) { - if (cap[3]) - cap[3] = cap[3].substring(1, cap[3].length - 1); - const tag = cap[1].toLowerCase().replace(/\s+/g, " "); - return { - type: "def", - tag, - raw: cap[0], - href: cap[2], - title: cap[3] - }; } } - table(src) { - const cap = this.rules.block.table.exec(src); - if (cap) { - const item = { - type: "table", - header: splitCells(cap[1]).map((c) => { - return { text: c }; - }), - align: cap[2].replace(/^ *|\| *$/g, "").split(/ *\| */), - rows: cap[3] && cap[3].trim() ? cap[3].replace(/\n[ \t]*$/, "").split("\n") : [] - }; - if (item.header.length === item.align.length) { - item.raw = cap[0]; - let l = item.align.length; - let i2, j2, k, row; - for (i2 = 0; i2 < l; i2++) { - if (/^ *-+: *$/.test(item.align[i2])) { - item.align[i2] = "right"; - } else if (/^ *:-+: *$/.test(item.align[i2])) { - item.align[i2] = "center"; - } else if (/^ *:-+ *$/.test(item.align[i2])) { - item.align[i2] = "left"; - } else { - item.align[i2] = null; - } - } - l = item.rows.length; - for (i2 = 0; i2 < l; i2++) { - item.rows[i2] = splitCells(item.rows[i2], item.header.length).map((c) => { - return { text: c }; - }); - } - l = item.header.length; - for (j2 = 0; j2 < l; j2++) { - item.header[j2].tokens = this.lexer.inline(item.header[j2].text); - } - l = item.rows.length; - for (j2 = 0; j2 < l; j2++) { - row = item.rows[j2]; - for (k = 0; k < row.length; k++) { - row[k].tokens = this.lexer.inline(row[k].text); - } - } - return item; - } - } + function _actionBounceBack(nodeID, toLoc) { + var moveNode = actionMoveNode(nodeID, toLoc); + var action = function(graph, t) { + if (t === 1) + context.pop(); + return moveNode(graph, t); + }; + action.transitionable = true; + return action; } - lheading(src) { - const cap = this.rules.block.lheading.exec(src); - if (cap) { - return { - type: "heading", - raw: cap[0], - depth: cap[2].charAt(0) === "=" ? 1 : 2, - text: cap[1], - tokens: this.lexer.inline(cap[1]) - }; - } + function cancel() { + drag.cancel(); + context.enter(modeBrowse(context)); } - paragraph(src) { - const cap = this.rules.block.paragraph.exec(src); - if (cap) { - const text2 = cap[1].charAt(cap[1].length - 1) === "\n" ? cap[1].slice(0, -1) : cap[1]; - return { - type: "paragraph", - raw: cap[0], - text: text2, - tokens: this.lexer.inline(text2) - }; - } + var drag = behaviorDrag().selector(".layer-touch.points .target").surface(context.container().select(".main-map").node()).origin(origin).on("start", start2).on("move", move).on("end", end); + mode.enter = function() { + context.install(hover); + context.install(edit2); + select_default2(window).on("keydown.dragNode", keydown).on("keyup.dragNode", keyup); + context.history().on("undone.drag-node", cancel); + }; + mode.exit = function() { + context.ui().sidebar.hover.cancel(); + context.uninstall(hover); + context.uninstall(edit2); + select_default2(window).on("keydown.dragNode", null).on("keyup.dragNode", null); + context.history().on("undone.drag-node", null); + _activeEntity = null; + context.surface().classed("nope", false).classed("nope-suppressed", false).classed("nope-disabled", false).selectAll(".active").classed("active", false); + stopNudge(); + }; + mode.selectedIDs = function() { + if (!arguments.length) + return _activeEntity ? [_activeEntity.id] : []; + return mode; + }; + mode.activeID = function() { + if (!arguments.length) + return _activeEntity && _activeEntity.id; + return mode; + }; + mode.restoreSelectedIDs = function(_) { + if (!arguments.length) + return _restoreSelectedIDs; + _restoreSelectedIDs = _; + return mode; + }; + mode.behavior = drag; + return mode; + } + + // modules/services/keepRight.js + var import_rbush = __toESM(require_rbush_min()); + + // node_modules/d3-fetch/src/text.js + function responseText(response) { + if (!response.ok) + throw new Error(response.status + " " + response.statusText); + return response.text(); + } + function text_default3(input, init2) { + return fetch(input, init2).then(responseText); + } + + // node_modules/d3-fetch/src/json.js + function responseJson(response) { + if (!response.ok) + throw new Error(response.status + " " + response.statusText); + if (response.status === 204 || response.status === 205) + return; + return response.json(); + } + function json_default(input, init2) { + return fetch(input, init2).then(responseJson); + } + + // node_modules/d3-fetch/src/xml.js + function parser(type2) { + return (input, init2) => text_default3(input, init2).then((text2) => new DOMParser().parseFromString(text2, type2)); + } + var xml_default = parser("application/xml"); + var html = parser("text/html"); + var svg = parser("image/svg+xml"); + + // modules/services/keepRight.js + var tiler = utilTiler(); + var dispatch2 = dispatch_default("loaded"); + var _tileZoom = 14; + var _krUrlRoot = "https://www.keepright.at"; + var _krData = { errorTypes: {}, localizeStrings: {} }; + var _cache; + var _krRuleset = [ + // no 20 - multiple node on same spot - these are mostly boundaries overlapping roads + 30, + 40, + 50, + 60, + 70, + 90, + 100, + 110, + 120, + 130, + 150, + 160, + 170, + 180, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 210, + 220, + 230, + 231, + 232, + 270, + 280, + 281, + 282, + 283, + 284, + 285, + 290, + 291, + 292, + 293, + 294, + 295, + 296, + 297, + 298, + 300, + 310, + 311, + 312, + 313, + 320, + 350, + 360, + 370, + 380, + 390, + 400, + 401, + 402, + 410, + 411, + 412, + 413 + ]; + function abortRequest(controller) { + if (controller) { + controller.abort(); } - text(src) { - const cap = this.rules.block.text.exec(src); - if (cap) { - return { - type: "text", - raw: cap[0], - text: cap[0], - tokens: this.lexer.inline(cap[0]) - }; + } + function abortUnwantedRequests(cache, tiles) { + Object.keys(cache.inflightTile).forEach((k) => { + const wanted = tiles.find((tile) => k === tile.id); + if (!wanted) { + abortRequest(cache.inflightTile[k]); + delete cache.inflightTile[k]; } + }); + } + function encodeIssueRtree(d) { + return { minX: d.loc[0], minY: d.loc[1], maxX: d.loc[0], maxY: d.loc[1], data: d }; + } + function updateRtree(item, replace) { + _cache.rtree.remove(item, (a, b) => a.data.id === b.data.id); + if (replace) { + _cache.rtree.insert(item); } - escape(src) { - const cap = this.rules.inline.escape.exec(src); - if (cap) { - return { - type: "escape", - raw: cap[0], - text: escape4(cap[1]) - }; - } + } + function tokenReplacements(d) { + if (!(d instanceof QAItem)) + return; + const replacements = {}; + const issueTemplate = _krData.errorTypes[d.whichType]; + if (!issueTemplate) { + console.log("No Template: ", d.whichType); + console.log(" ", d.description); + return; } - tag(src) { - const cap = this.rules.inline.tag.exec(src); - if (cap) { - if (!this.lexer.state.inLink && /^/i.test(cap[0])) { - this.lexer.state.inLink = false; - } - if (!this.lexer.state.inRawBlock && /^<(pre|code|kbd|script)(\s|>)/i.test(cap[0])) { - this.lexer.state.inRawBlock = true; - } else if (this.lexer.state.inRawBlock && /^<\/(pre|code|kbd|script)(\s|>)/i.test(cap[0])) { - this.lexer.state.inRawBlock = false; - } - return { - type: this.options.sanitize ? "text" : "html", - raw: cap[0], - inLink: this.lexer.state.inLink, - inRawBlock: this.lexer.state.inRawBlock, - text: this.options.sanitize ? this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape4(cap[0]) : cap[0] - }; - } + if (!issueTemplate.regex) + return; + const errorRegex = new RegExp(issueTemplate.regex, "i"); + const errorMatch = errorRegex.exec(d.description); + if (!errorMatch) { + console.log("Unmatched: ", d.whichType); + console.log(" ", d.description); + console.log(" ", errorRegex); + return; } - link(src) { - const cap = this.rules.inline.link.exec(src); - if (cap) { - const trimmedUrl = cap[2].trim(); - if (!this.options.pedantic && /^$/.test(trimmedUrl)) { - return; - } - const rtrimSlash = rtrim(trimmedUrl.slice(0, -1), "\\"); - if ((trimmedUrl.length - rtrimSlash.length) % 2 === 0) { - return; - } - } else { - const lastParenIndex = findClosingBracket(cap[2], "()"); - if (lastParenIndex > -1) { - const start2 = cap[0].indexOf("!") === 0 ? 5 : 4; - const linkLen = start2 + cap[1].length + lastParenIndex; - cap[2] = cap[2].substring(0, lastParenIndex); - cap[0] = cap[0].substring(0, linkLen).trim(); - cap[3] = ""; - } - } - let href = cap[2]; - let title = ""; - if (this.options.pedantic) { - const link2 = /^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(href); - if (link2) { - href = link2[1]; - title = link2[3]; - } + for (let i2 = 1; i2 < errorMatch.length; i2++) { + let capture = errorMatch[i2]; + let idType; + idType = "IDs" in issueTemplate ? issueTemplate.IDs[i2 - 1] : ""; + if (idType && capture) { + capture = parseError(capture, idType); + } else { + const compare = capture.toLowerCase(); + if (_krData.localizeStrings[compare]) { + capture = _t("QA.keepRight.error_parts." + _krData.localizeStrings[compare]); } else { - title = cap[3] ? cap[3].slice(1, -1) : ""; - } - href = href.trim(); - if (/^$/.test(trimmedUrl)) { - href = href.slice(1); - } else { - href = href.slice(1, -1); - } + capture = unescape_default(capture); } - return outputLink(cap, { - href: href ? href.replace(this.rules.inline._escapes, "$1") : href, - title: title ? title.replace(this.rules.inline._escapes, "$1") : title - }, cap[0], this.lexer); } + replacements["var" + i2] = capture; } - reflink(src, links) { - let cap; - if ((cap = this.rules.inline.reflink.exec(src)) || (cap = this.rules.inline.nolink.exec(src))) { - let link2 = (cap[2] || cap[1]).replace(/\s+/g, " "); - link2 = links[link2.toLowerCase()]; - if (!link2 || !link2.href) { - const text2 = cap[0].charAt(0); - return { - type: "text", - raw: text2, - text: text2 - }; - } - return outputLink(cap, link2, cap[0], this.lexer); - } + return replacements; + } + function parseError(capture, idType) { + const compare = capture.toLowerCase(); + if (_krData.localizeStrings[compare]) { + capture = _t("QA.keepRight.error_parts." + _krData.localizeStrings[compare]); } - emStrong(src, maskedSrc, prevChar = "") { - let match = this.rules.inline.emStrong.lDelim.exec(src); - if (!match) - return; - if (match[3] && prevChar.match(/[\p{L}\p{N}]/u)) - return; - const nextChar = match[1] || match[2] || ""; - if (!nextChar || nextChar && (prevChar === "" || this.rules.inline.punctuation.exec(prevChar))) { - const lLength = match[0].length - 1; - let rDelim, rLength, delimTotal = lLength, midDelimTotal = 0; - const endReg = match[0][0] === "*" ? this.rules.inline.emStrong.rDelimAst : this.rules.inline.emStrong.rDelimUnd; - endReg.lastIndex = 0; - maskedSrc = maskedSrc.slice(-1 * src.length + lLength); - while ((match = endReg.exec(maskedSrc)) != null) { - rDelim = match[1] || match[2] || match[3] || match[4] || match[5] || match[6]; - if (!rDelim) - continue; - rLength = rDelim.length; - if (match[3] || match[4]) { - delimTotal += rLength; - continue; - } else if (match[5] || match[6]) { - if (lLength % 3 && !((lLength + rLength) % 3)) { - midDelimTotal += rLength; - continue; - } - } - delimTotal -= rLength; - if (delimTotal > 0) - continue; - rLength = Math.min(rLength, rLength + delimTotal + midDelimTotal); - if (Math.min(lLength, rLength) % 2) { - const text3 = src.slice(1, lLength + match.index + rLength); - return { - type: "em", - raw: src.slice(0, lLength + match.index + rLength + 1), - text: text3, - tokens: this.lexer.inlineTokens(text3) - }; - } - const text2 = src.slice(2, lLength + match.index + rLength - 1); - return { - type: "strong", - raw: src.slice(0, lLength + match.index + rLength + 1), - text: text2, - tokens: this.lexer.inlineTokens(text2) - }; - } - } + switch (idType) { + case "this": + capture = linkErrorObject2(capture); + break; + case "url": + capture = linkURL(capture); + break; + case "n": + case "w": + case "r": + capture = linkEntity2(idType + capture); + break; + case "20": + capture = parse20(capture); + break; + case "211": + capture = parse211(capture); + break; + case "231": + capture = parse231(capture); + break; + case "294": + capture = parse294(capture); + break; + case "370": + capture = parse370(capture); + break; } - codespan(src) { - const cap = this.rules.inline.code.exec(src); - if (cap) { - let text2 = cap[2].replace(/\n/g, " "); - const hasNonSpaceChars = /[^ ]/.test(text2); - const hasSpaceCharsOnBothEnds = /^ /.test(text2) && / $/.test(text2); - if (hasNonSpaceChars && hasSpaceCharsOnBothEnds) { - text2 = text2.substring(1, text2.length - 1); - } - text2 = escape4(text2, true); - return { - type: "codespan", - raw: cap[0], - text: text2 - }; - } + return capture; + function linkErrorObject2(d) { + return { html: `${d}` }; } - br(src) { - const cap = this.rules.inline.br.exec(src); - if (cap) { - return { - type: "br", - raw: cap[0] - }; - } + function linkEntity2(d) { + return { html: `${d}` }; } - del(src) { - const cap = this.rules.inline.del.exec(src); - if (cap) { - return { - type: "del", - raw: cap[0], - text: cap[2], - tokens: this.lexer.inlineTokens(cap[2]) - }; - } + function linkURL(d) { + return { html: `${d}` }; } - autolink(src, mangle2) { - const cap = this.rules.inline.autolink.exec(src); - if (cap) { - let text2, href; - if (cap[2] === "@") { - text2 = escape4(this.options.mangle ? mangle2(cap[1]) : cap[1]); - href = "mailto:" + text2; - } else { - text2 = escape4(cap[1]); - href = text2; + function parse211(capture2) { + let newList = []; + const items = capture2.split(", "); + items.forEach((item) => { + let id2 = linkEntity2("n" + item.slice(1)); + newList.push(id2); + }); + return newList.join(", "); + } + function parse231(capture2) { + let newList = []; + const items = capture2.split("),"); + items.forEach((item) => { + const match = item.match(/\#(\d+)\((.+)\)?/); + if (match !== null && match.length > 2) { + newList.push( + linkEntity2("w" + match[1]) + " " + _t("QA.keepRight.errorTypes.231.layer", { layer: match[2] }) + ); } - return { - type: "link", - raw: cap[0], - text: text2, - href, - tokens: [ - { - type: "text", - raw: text2, - text: text2 - } - ] - }; + }); + return newList.join(", "); + } + function parse294(capture2) { + let newList = []; + const items = capture2.split(","); + items.forEach((item) => { + item = item.split(" "); + const role = `"${item[0]}"`; + const idType2 = item[1].slice(0, 1); + let id2 = item[2].slice(1); + id2 = linkEntity2(idType2 + id2); + newList.push(`${role} ${item[1]} ${id2}`); + }); + return newList.join(", "); + } + function parse370(capture2) { + if (!capture2) + return ""; + const match = capture2.match(/\(including the name (\'.+\')\)/); + if (match && match.length) { + return _t("QA.keepRight.errorTypes.370.including_the_name", { name: match[1] }); } + return ""; } - url(src, mangle2) { - let cap; - if (cap = this.rules.inline.url.exec(src)) { - let text2, href; - if (cap[2] === "@") { - text2 = escape4(this.options.mangle ? mangle2(cap[0]) : cap[0]); - href = "mailto:" + text2; - } else { - let prevCapZero; - do { - prevCapZero = cap[0]; - cap[0] = this.rules.inline._backpedal.exec(cap[0])[0]; - } while (prevCapZero !== cap[0]); - text2 = escape4(cap[0]); - if (cap[1] === "www.") { - href = "http://" + text2; - } else { - href = text2; + function parse20(capture2) { + let newList = []; + const items = capture2.split(","); + items.forEach((item) => { + const id2 = linkEntity2("n" + item.slice(1)); + newList.push(id2); + }); + return newList.join(", "); + } + } + var keepRight_default = { + title: "keepRight", + init() { + _mainFileFetcher.get("keepRight").then((d) => _krData = d); + if (!_cache) { + this.reset(); + } + this.event = utilRebind(this, dispatch2, "on"); + }, + reset() { + if (_cache) { + Object.values(_cache.inflightTile).forEach(abortRequest); + } + _cache = { + data: {}, + loadedTile: {}, + inflightTile: {}, + inflightPost: {}, + closed: {}, + rtree: new import_rbush.default() + }; + }, + // KeepRight API: http://osm.mueschelsoft.de/keepright/interfacing.php + loadIssues(projection2) { + const options2 = { + format: "geojson", + ch: _krRuleset + }; + const tiles = tiler.zoomExtent([_tileZoom, _tileZoom]).getTiles(projection2); + abortUnwantedRequests(_cache, tiles); + tiles.forEach((tile) => { + if (_cache.loadedTile[tile.id] || _cache.inflightTile[tile.id]) + return; + const [left, top, right, bottom] = tile.extent.rectangle(); + const params = Object.assign({}, options2, { left, bottom, right, top }); + const url = `${_krUrlRoot}/export.php?` + utilQsString(params); + const controller = new AbortController(); + _cache.inflightTile[tile.id] = controller; + json_default(url, { signal: controller.signal }).then((data) => { + delete _cache.inflightTile[tile.id]; + _cache.loadedTile[tile.id] = true; + if (!data || !data.features || !data.features.length) { + throw new Error("No Data"); } - } - return { - type: "link", - raw: cap[0], - text: text2, - href, - tokens: [ - { - type: "text", - raw: text2, - text: text2 + data.features.forEach((feature3) => { + const { + properties: { + error_type: itemType, + error_id: id2, + comment = null, + object_id: objectId, + object_type: objectType, + schema, + title + } + } = feature3; + let { + geometry: { coordinates: loc }, + properties: { description = "" } + } = feature3; + const issueTemplate = _krData.errorTypes[itemType]; + const parentIssueType = (Math.floor(itemType / 10) * 10).toString(); + const whichType = issueTemplate ? itemType : parentIssueType; + const whichTemplate = _krData.errorTypes[whichType]; + switch (whichType) { + case "170": + description = `This feature has a FIXME tag: ${description}`; + break; + case "292": + case "293": + description = description.replace("A turn-", "This turn-"); + break; + case "294": + case "295": + case "296": + case "297": + case "298": + description = `This turn-restriction~${description}`; + break; + case "300": + description = "This highway is missing a maxspeed tag"; + break; + case "411": + case "412": + case "413": + description = `This feature~${description}`; + break; } - ] - }; + let coincident = false; + do { + let delta = coincident ? [1e-5, 0] : [0, 1e-5]; + loc = geoVecAdd(loc, delta); + let bbox2 = geoExtent(loc).bbox(); + coincident = _cache.rtree.search(bbox2).length; + } while (coincident); + let d = new QAItem(loc, this, itemType, id2, { + comment, + description, + whichType, + parentIssueType, + severity: whichTemplate.severity || "error", + objectId, + objectType, + schema, + title + }); + d.replacements = tokenReplacements(d); + _cache.data[id2] = d; + _cache.rtree.insert(encodeIssueRtree(d)); + }); + dispatch2.call("loaded"); + }).catch(() => { + delete _cache.inflightTile[tile.id]; + _cache.loadedTile[tile.id] = true; + }); + }); + }, + postUpdate(d, callback) { + if (_cache.inflightPost[d.id]) { + return callback({ message: "Error update already inflight", status: -2 }, d); } - } - inlineText(src, smartypants2) { - const cap = this.rules.inline.text.exec(src); - if (cap) { - let text2; - if (this.lexer.state.inRawBlock) { - text2 = this.options.sanitize ? this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape4(cap[0]) : cap[0]; + const params = { schema: d.schema, id: d.id }; + if (d.newStatus) { + params.st = d.newStatus; + } + if (d.newComment !== void 0) { + params.co = d.newComment; + } + const url = `${_krUrlRoot}/comment.php?` + utilQsString(params); + const controller = new AbortController(); + _cache.inflightPost[d.id] = controller; + json_default(url, { signal: controller.signal }).finally(() => { + delete _cache.inflightPost[d.id]; + if (d.newStatus === "ignore") { + this.removeItem(d); + } else if (d.newStatus === "ignore_t") { + this.removeItem(d); + _cache.closed[`${d.schema}:${d.id}`] = true; } else { - text2 = escape4(this.options.smartypants ? smartypants2(cap[0]) : cap[0]); + d = this.replaceItem(d.update({ + comment: d.newComment, + newComment: void 0, + newState: void 0 + })); } - return { - type: "text", - raw: cap[0], - text: text2 - }; - } - } - }; - var block = { - newline: /^(?: *(?:\n|$))+/, - code: /^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/, - fences: /^ {0,3}(`{3,}(?=[^`\n]*\n)|~{3,})([^\n]*)\n(?:|([\s\S]*?)\n)(?: {0,3}\1[~`]* *(?=\n|$)|$)/, - hr: /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/, - heading: /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/, - blockquote: /^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/, - list: /^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/, - html: "^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|\\n*|$)|\\n*|$)|)[\\s\\S]*?(?:(?:\\n *)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)|(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$))", - def: /^ {0,3}\[(label)\]: *(?:\n *)?]+)>?(?:(?: +(?:\n *)?| *\n *)(title))? *(?:\n+|$)/, - table: noopTest, - lheading: /^([^\n]+)\n {0,3}(=+|-+) *(?:\n+|$)/, - _paragraph: /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/, - text: /^[^\n]+/ - }; - block._label = /(?!\s*\])(?:\\.|[^\[\]\\])+/; - block._title = /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/; - block.def = edit(block.def).replace("label", block._label).replace("title", block._title).getRegex(); - block.bullet = /(?:[*+-]|\d{1,9}[.)])/; - block.listItemStart = edit(/^( *)(bull) */).replace("bull", block.bullet).getRegex(); - block.list = edit(block.list).replace(/bull/g, block.bullet).replace("hr", "\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))").replace("def", "\\n+(?=" + block.def.source + ")").getRegex(); - block._tag = "address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul"; - block._comment = /|$)/; - block.html = edit(block.html, "i").replace("comment", block._comment).replace("tag", block._tag).replace("attribute", / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(); - block.paragraph = edit(block._paragraph).replace("hr", block.hr).replace("heading", " {0,3}#{1,6} ").replace("|lheading", "").replace("|table", "").replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", ")|<(?:script|pre|style|textarea|!--)").replace("tag", block._tag).getRegex(); - block.blockquote = edit(block.blockquote).replace("paragraph", block.paragraph).getRegex(); - block.normal = merge2({}, block); - block.gfm = merge2({}, block.normal, { - table: "^ *([^\\n ].*\\|.*)\\n {0,3}(?:\\| *)?(:?-+:? *(?:\\| *:?-+:? *)*)(?:\\| *)?(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)" - }); - block.gfm.table = edit(block.gfm.table).replace("hr", block.hr).replace("heading", " {0,3}#{1,6} ").replace("blockquote", " {0,3}>").replace("code", " {4}[^\\n]").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", ")|<(?:script|pre|style|textarea|!--)").replace("tag", block._tag).getRegex(); - block.gfm.paragraph = edit(block._paragraph).replace("hr", block.hr).replace("heading", " {0,3}#{1,6} ").replace("|lheading", "").replace("table", block.gfm.table).replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", ")|<(?:script|pre|style|textarea|!--)").replace("tag", block._tag).getRegex(); - block.pedantic = merge2({}, block.normal, { - html: edit( - `^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+? *(?:\\n{2,}|\\s*$)|\\s]*)*?/?> *(?:\\n{2,}|\\s*$))` - ).replace("comment", block._comment).replace(/tag/g, "(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(), - def: /^ *\[([^\]]+)\]: *]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/, - heading: /^(#{1,6})(.*)(?:\n+|$)/, - fences: noopTest, - paragraph: edit(block.normal._paragraph).replace("hr", block.hr).replace("heading", " *#{1,6} *[^\n]").replace("lheading", block.lheading).replace("blockquote", " {0,3}>").replace("|fences", "").replace("|list", "").replace("|html", "").getRegex() - }); - var inline = { - escape: /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/, - autolink: /^<(scheme:[^\s\x00-\x1f<>]*|email)>/, - url: noopTest, - tag: "^comment|^|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^|^", - link: /^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/, - reflink: /^!?\[(label)\]\[(ref)\]/, - nolink: /^!?\[(ref)\](?:\[\])?/, - reflinkSearch: "reflink|nolink(?!\\()", - emStrong: { - lDelim: /^(?:\*+(?:([punct_])|[^\s*]))|^_+(?:([punct*])|([^\s_]))/, - rDelimAst: /^[^_*]*?\_\_[^_*]*?\*[^_*]*?(?=\_\_)|[^*]+(?=[^*])|[punct_](\*+)(?=[\s]|$)|[^punct*_\s](\*+)(?=[punct_\s]|$)|[punct_\s](\*+)(?=[^punct*_\s])|[\s](\*+)(?=[punct_])|[punct_](\*+)(?=[punct_])|[^punct*_\s](\*+)(?=[^punct*_\s])/, - rDelimUnd: /^[^_*]*?\*\*[^_*]*?\_[^_*]*?(?=\*\*)|[^_]+(?=[^_])|[punct*](\_+)(?=[\s]|$)|[^punct*_\s](\_+)(?=[punct*\s]|$)|[punct*\s](\_+)(?=[^punct*_\s])|[\s](\_+)(?=[punct*])|[punct*](\_+)(?=[punct*])/ + if (callback) + callback(null, d); + }); }, - code: /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/, - br: /^( {2,}|\\)\n(?!\s*$)/, - del: noopTest, - text: /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\?@\\[\\]`^{|}~"; - inline.punctuation = edit(inline.punctuation).replace(/punctuation/g, inline._punctuation).getRegex(); - inline.blockSkip = /\[[^\]]*?\]\([^\)]*?\)|`[^`]*?`|<[^>]*?>/g; - inline.escapedEmSt = /\\\*|\\_/g; - inline._comment = edit(block._comment).replace("(?:-->|$)", "-->").getRegex(); - inline.emStrong.lDelim = edit(inline.emStrong.lDelim).replace(/punct/g, inline._punctuation).getRegex(); - inline.emStrong.rDelimAst = edit(inline.emStrong.rDelimAst, "g").replace(/punct/g, inline._punctuation).getRegex(); - inline.emStrong.rDelimUnd = edit(inline.emStrong.rDelimUnd, "g").replace(/punct/g, inline._punctuation).getRegex(); - inline._escapes = /\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/g; - inline._scheme = /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/; - inline._email = /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/; - inline.autolink = edit(inline.autolink).replace("scheme", inline._scheme).replace("email", inline._email).getRegex(); - inline._attribute = /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/; - inline.tag = edit(inline.tag).replace("comment", inline._comment).replace("attribute", inline._attribute).getRegex(); - inline._label = /(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/; - inline._href = /<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/; - inline._title = /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/; - inline.link = edit(inline.link).replace("label", inline._label).replace("href", inline._href).replace("title", inline._title).getRegex(); - inline.reflink = edit(inline.reflink).replace("label", inline._label).replace("ref", block._label).getRegex(); - inline.nolink = edit(inline.nolink).replace("ref", block._label).getRegex(); - inline.reflinkSearch = edit(inline.reflinkSearch, "g").replace("reflink", inline.reflink).replace("nolink", inline.nolink).getRegex(); - inline.normal = merge2({}, inline); - inline.pedantic = merge2({}, inline.normal, { - strong: { - start: /^__|\*\*/, - middle: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/, - endAst: /\*\*(?!\*)/g, - endUnd: /__(?!_)/g + // Get all cached QAItems covering the viewport + getItems(projection2) { + const viewport = projection2.clipExtent(); + const min3 = [viewport[0][0], viewport[1][1]]; + const max3 = [viewport[1][0], viewport[0][1]]; + const bbox2 = geoExtent(projection2.invert(min3), projection2.invert(max3)).bbox(); + return _cache.rtree.search(bbox2).map((d) => d.data); }, - em: { - start: /^_|\*/, - middle: /^()\*(?=\S)([\s\S]*?\S)\*(?!\*)|^_(?=\S)([\s\S]*?\S)_(?!_)/, - endAst: /\*(?!\*)/g, - endUnd: /_(?!_)/g + // Get a QAItem from cache + // NOTE: Don't change method name until UI v3 is merged + getError(id2) { + return _cache.data[id2]; }, - link: edit(/^!?\[(label)\]\((.*?)\)/).replace("label", inline._label).getRegex(), - reflink: edit(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label", inline._label).getRegex() - }); - inline.gfm = merge2({}, inline.normal, { - escape: edit(inline.escape).replace("])", "~|])").getRegex(), - _extended_email: /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/, - url: /^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/, - _backpedal: /(?:[^?!.,:;*_~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_~)]+(?!$))+/, - del: /^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/, - text: /^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\ 0.5) { - ch = "x" + ch.toString(16); - } - out += "&#" + ch + ";"; + // Replace a single QAItem in the cache + replaceItem(item) { + if (!(item instanceof QAItem) || !item.id) + return; + _cache.data[item.id] = item; + updateRtree(encodeIssueRtree(item), true); + return item; + }, + // Remove a single QAItem from the cache + removeItem(item) { + if (!(item instanceof QAItem) || !item.id) + return; + delete _cache.data[item.id]; + updateRtree(encodeIssueRtree(item), false); + }, + issueURL(item) { + return `${_krUrlRoot}/report_map.php?schema=${item.schema}&error=${item.id}`; + }, + // Get an array of issues closed during this session. + // Used to populate `closed:keepright` changeset tag + getClosedIDs() { + return Object.keys(_cache.closed).sort(); } - return out; - } - var Lexer = class { - constructor(options2) { - this.tokens = []; - this.tokens.links = /* @__PURE__ */ Object.create(null); - this.options = options2 || defaults; - this.options.tokenizer = this.options.tokenizer || new Tokenizer(); - this.tokenizer = this.options.tokenizer; - this.tokenizer.options = this.options; - this.tokenizer.lexer = this; - this.inlineQueue = []; - this.state = { - inLink: false, - inRawBlock: false, - top: true - }; - const rules = { - block: block.normal, - inline: inline.normal - }; - if (this.options.pedantic) { - rules.block = block.pedantic; - rules.inline = inline.pedantic; - } else if (this.options.gfm) { - rules.block = block.gfm; - if (this.options.breaks) { - rules.inline = inline.breaks; - } else { - rules.inline = inline.gfm; - } + }; + + // modules/services/improveOSM.js + var import_rbush2 = __toESM(require_rbush_min()); + var tiler2 = utilTiler(); + var dispatch3 = dispatch_default("loaded"); + var _tileZoom2 = 14; + var _impOsmUrls = { + ow: "https://grab.community.improve-osm.org/directionOfFlowService", + mr: "https://grab.community.improve-osm.org/missingGeoService", + tr: "https://grab.community.improve-osm.org/turnRestrictionService" + }; + var _impOsmData = { icons: {} }; + var _cache2; + function abortRequest2(i2) { + Object.values(i2).forEach((controller) => { + if (controller) { + controller.abort(); } - this.tokenizer.rules = rules; - } - static get rules() { - return { - block, - inline - }; + }); + } + function abortUnwantedRequests2(cache, tiles) { + Object.keys(cache.inflightTile).forEach((k) => { + const wanted = tiles.find((tile) => k === tile.id); + if (!wanted) { + abortRequest2(cache.inflightTile[k]); + delete cache.inflightTile[k]; + } + }); + } + function encodeIssueRtree2(d) { + return { minX: d.loc[0], minY: d.loc[1], maxX: d.loc[0], maxY: d.loc[1], data: d }; + } + function updateRtree2(item, replace) { + _cache2.rtree.remove(item, (a, b) => a.data.id === b.data.id); + if (replace) { + _cache2.rtree.insert(item); } - static lex(src, options2) { - const lexer2 = new Lexer(options2); - return lexer2.lex(src); + } + function linkErrorObject(d) { + return { html: `${d}` }; + } + function linkEntity(d) { + return { html: `${d}` }; + } + function pointAverage(points) { + if (points.length) { + const sum = points.reduce( + (acc, point2) => geoVecAdd(acc, [point2.lon, point2.lat]), + [0, 0] + ); + return geoVecScale(sum, 1 / points.length); + } else { + return [0, 0]; } - static lexInline(src, options2) { - const lexer2 = new Lexer(options2); - return lexer2.inlineTokens(src); + } + function relativeBearing(p1, p2) { + let angle2 = Math.atan2(p2.lon - p1.lon, p2.lat - p1.lat); + if (angle2 < 0) { + angle2 += 2 * Math.PI; } - lex(src) { - src = src.replace(/\r\n|\r/g, "\n"); - this.blockTokens(src, this.tokens); - let next; - while (next = this.inlineQueue.shift()) { - this.inlineTokens(next.src, next.tokens); + return angle2 * 180 / Math.PI; + } + function cardinalDirection(bearing) { + const dir = 45 * Math.round(bearing / 45); + const compass = { + 0: "north", + 45: "northeast", + 90: "east", + 135: "southeast", + 180: "south", + 225: "southwest", + 270: "west", + 315: "northwest", + 360: "north" + }; + return _t(`QA.improveOSM.directions.${compass[dir]}`); + } + function preventCoincident(loc, bumpUp) { + let coincident = false; + do { + let delta = coincident ? [1e-5, 0] : bumpUp ? [0, 1e-5] : [0, 0]; + loc = geoVecAdd(loc, delta); + let bbox2 = geoExtent(loc).bbox(); + coincident = _cache2.rtree.search(bbox2).length; + } while (coincident); + return loc; + } + var improveOSM_default = { + title: "improveOSM", + init() { + _mainFileFetcher.get("qa_data").then((d) => _impOsmData = d.improveOSM); + if (!_cache2) { + this.reset(); } - return this.tokens; - } - blockTokens(src, tokens = []) { - if (this.options.pedantic) { - src = src.replace(/\t/g, " ").replace(/^ +$/gm, ""); - } else { - src = src.replace(/^( *)(\t+)/gm, (_, leading, tabs) => { - return leading + " ".repeat(tabs.length); - }); + this.event = utilRebind(this, dispatch3, "on"); + }, + reset() { + if (_cache2) { + Object.values(_cache2.inflightTile).forEach(abortRequest2); } - let token, lastToken, cutSrc, lastParagraphClipped; - while (src) { - if (this.options.extensions && this.options.extensions.block && this.options.extensions.block.some((extTokenizer) => { - if (token = extTokenizer.call({ lexer: this }, src, tokens)) { - src = src.substring(token.raw.length); - tokens.push(token); - return true; - } - return false; - })) { - continue; - } - if (token = this.tokenizer.space(src)) { - src = src.substring(token.raw.length); - if (token.raw.length === 1 && tokens.length > 0) { - tokens[tokens.length - 1].raw += "\n"; - } else { - tokens.push(token); - } - continue; - } - if (token = this.tokenizer.code(src)) { - src = src.substring(token.raw.length); - lastToken = tokens[tokens.length - 1]; - if (lastToken && (lastToken.type === "paragraph" || lastToken.type === "text")) { - lastToken.raw += "\n" + token.raw; - lastToken.text += "\n" + token.text; - this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text; - } else { - tokens.push(token); - } - continue; - } - if (token = this.tokenizer.fences(src)) { - src = src.substring(token.raw.length); - tokens.push(token); - continue; - } - if (token = this.tokenizer.heading(src)) { - src = src.substring(token.raw.length); - tokens.push(token); - continue; - } - if (token = this.tokenizer.hr(src)) { - src = src.substring(token.raw.length); - tokens.push(token); - continue; - } - if (token = this.tokenizer.blockquote(src)) { - src = src.substring(token.raw.length); - tokens.push(token); - continue; - } - if (token = this.tokenizer.list(src)) { - src = src.substring(token.raw.length); - tokens.push(token); - continue; - } - if (token = this.tokenizer.html(src)) { - src = src.substring(token.raw.length); - tokens.push(token); - continue; - } - if (token = this.tokenizer.def(src)) { - src = src.substring(token.raw.length); - lastToken = tokens[tokens.length - 1]; - if (lastToken && (lastToken.type === "paragraph" || lastToken.type === "text")) { - lastToken.raw += "\n" + token.raw; - lastToken.text += "\n" + token.raw; - this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text; - } else if (!this.tokens.links[token.tag]) { - this.tokens.links[token.tag] = { - href: token.href, - title: token.title - }; - } - continue; - } - if (token = this.tokenizer.table(src)) { - src = src.substring(token.raw.length); - tokens.push(token); - continue; - } - if (token = this.tokenizer.lheading(src)) { - src = src.substring(token.raw.length); - tokens.push(token); - continue; - } - cutSrc = src; - if (this.options.extensions && this.options.extensions.startBlock) { - let startIndex = Infinity; - const tempSrc = src.slice(1); - let tempStart; - this.options.extensions.startBlock.forEach(function(getStartIndex) { - tempStart = getStartIndex.call({ lexer: this }, tempSrc); - if (typeof tempStart === "number" && tempStart >= 0) { - startIndex = Math.min(startIndex, tempStart); + _cache2 = { + data: {}, + loadedTile: {}, + inflightTile: {}, + inflightPost: {}, + closed: {}, + rtree: new import_rbush2.default() + }; + }, + loadIssues(projection2) { + const options2 = { + client: "iD", + status: "OPEN", + zoom: "19" + // Use a high zoom so that clusters aren't returned + }; + const tiles = tiler2.zoomExtent([_tileZoom2, _tileZoom2]).getTiles(projection2); + abortUnwantedRequests2(_cache2, tiles); + tiles.forEach((tile) => { + if (_cache2.loadedTile[tile.id] || _cache2.inflightTile[tile.id]) + return; + const [east, north, west, south] = tile.extent.rectangle(); + const params = Object.assign({}, options2, { east, south, west, north }); + const requests = {}; + Object.keys(_impOsmUrls).forEach((k) => { + const kParams = Object.assign( + {}, + params, + k === "mr" ? { type: "PARKING,ROAD,BOTH,PATH" } : { confidenceLevel: "C1" } + ); + const url = `${_impOsmUrls[k]}/search?` + utilQsString(kParams); + const controller = new AbortController(); + requests[k] = controller; + json_default(url, { signal: controller.signal }).then((data) => { + delete _cache2.inflightTile[tile.id][k]; + if (!Object.keys(_cache2.inflightTile[tile.id]).length) { + delete _cache2.inflightTile[tile.id]; + _cache2.loadedTile[tile.id] = true; + } + if (data.roadSegments) { + data.roadSegments.forEach((feature3) => { + const { points, wayId, fromNodeId, toNodeId } = feature3; + const itemId = `${wayId}${fromNodeId}${toNodeId}`; + let mid = points.length / 2; + let loc; + if (mid % 1 === 0) { + loc = pointAverage([points[mid - 1], points[mid]]); + } else { + mid = points[Math.floor(mid)]; + loc = [mid.lon, mid.lat]; + } + loc = preventCoincident(loc, false); + let d = new QAItem(loc, this, k, itemId, { + issueKey: k, + // used as a category + identifier: { + // used to post changes + wayId, + fromNodeId, + toNodeId + }, + objectId: wayId, + objectType: "way" + }); + d.replacements = { + percentage: feature3.percentOfTrips, + num_trips: feature3.numberOfTrips, + highway: linkErrorObject(_t("QA.keepRight.error_parts.highway")), + from_node: linkEntity("n" + feature3.fromNodeId), + to_node: linkEntity("n" + feature3.toNodeId) + }; + _cache2.data[d.id] = d; + _cache2.rtree.insert(encodeIssueRtree2(d)); + }); + } + if (data.tiles) { + data.tiles.forEach((feature3) => { + const { type: type2, x, y, numberOfTrips } = feature3; + const geoType = type2.toLowerCase(); + const itemId = `${geoType}${x}${y}${numberOfTrips}`; + let loc = pointAverage(feature3.points); + loc = preventCoincident(loc, false); + let d = new QAItem(loc, this, `${k}-${geoType}`, itemId, { + issueKey: k, + identifier: { x, y } + }); + d.replacements = { + num_trips: numberOfTrips, + geometry_type: _t(`QA.improveOSM.geometry_types.${geoType}`) + }; + if (numberOfTrips === -1) { + d.desc = _t("QA.improveOSM.error_types.mr.description_alt", d.replacements); + } + _cache2.data[d.id] = d; + _cache2.rtree.insert(encodeIssueRtree2(d)); + }); + } + if (data.entities) { + data.entities.forEach((feature3) => { + const { point: point2, id: id2, segments, numberOfPasses, turnType } = feature3; + const itemId = `${id2.replace(/[,:+#]/g, "_")}`; + const loc = preventCoincident([point2.lon, point2.lat], true); + const ids = id2.split(","); + const from_way = ids[0]; + const via_node = ids[3]; + const to_way = ids[2].split(":")[1]; + let d = new QAItem(loc, this, k, itemId, { + issueKey: k, + identifier: id2, + objectId: via_node, + objectType: "node" + }); + const [p1, p2] = segments[0].points; + const dir_of_travel = cardinalDirection(relativeBearing(p1, p2)); + d.replacements = { + num_passed: numberOfPasses, + num_trips: segments[0].numberOfTrips, + turn_restriction: turnType.toLowerCase(), + from_way: linkEntity("w" + from_way), + to_way: linkEntity("w" + to_way), + travel_direction: dir_of_travel, + junction: linkErrorObject(_t("QA.keepRight.error_parts.this_node")) + }; + _cache2.data[d.id] = d; + _cache2.rtree.insert(encodeIssueRtree2(d)); + dispatch3.call("loaded"); + }); + } + }).catch(() => { + delete _cache2.inflightTile[tile.id][k]; + if (!Object.keys(_cache2.inflightTile[tile.id]).length) { + delete _cache2.inflightTile[tile.id]; + _cache2.loadedTile[tile.id] = true; } }); - if (startIndex < Infinity && startIndex >= 0) { - cutSrc = src.substring(0, startIndex + 1); - } - } - if (this.state.top && (token = this.tokenizer.paragraph(cutSrc))) { - lastToken = tokens[tokens.length - 1]; - if (lastParagraphClipped && lastToken.type === "paragraph") { - lastToken.raw += "\n" + token.raw; - lastToken.text += "\n" + token.text; - this.inlineQueue.pop(); - this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text; - } else { - tokens.push(token); - } - lastParagraphClipped = cutSrc.length !== src.length; - src = src.substring(token.raw.length); - continue; - } - if (token = this.tokenizer.text(src)) { - src = src.substring(token.raw.length); - lastToken = tokens[tokens.length - 1]; - if (lastToken && lastToken.type === "text") { - lastToken.raw += "\n" + token.raw; - lastToken.text += "\n" + token.text; - this.inlineQueue.pop(); - this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text; - } else { - tokens.push(token); - } - continue; - } - if (src) { - const errMsg = "Infinite loop on byte: " + src.charCodeAt(0); - if (this.options.silent) { - console.error(errMsg); - break; - } else { - throw new Error(errMsg); - } - } + }); + _cache2.inflightTile[tile.id] = requests; + }); + }, + getComments(item) { + if (item.comments) { + return Promise.resolve(item); } - this.state.top = true; - return tokens; - } - inline(src, tokens = []) { - this.inlineQueue.push({ src, tokens }); - return tokens; - } - inlineTokens(src, tokens = []) { - let token, lastToken, cutSrc; - let maskedSrc = src; - let match; - let keepPrevChar, prevChar; - if (this.tokens.links) { - const links = Object.keys(this.tokens.links); - if (links.length > 0) { - while ((match = this.tokenizer.rules.inline.reflinkSearch.exec(maskedSrc)) != null) { - if (links.includes(match[0].slice(match[0].lastIndexOf("[") + 1, -1))) { - maskedSrc = maskedSrc.slice(0, match.index) + "[" + repeatString("a", match[0].length - 2) + "]" + maskedSrc.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex); - } - } - } + const key = item.issueKey; + let qParams = {}; + if (key === "ow") { + qParams = item.identifier; + } else if (key === "mr") { + qParams.tileX = item.identifier.x; + qParams.tileY = item.identifier.y; + } else if (key === "tr") { + qParams.targetId = item.identifier; } - while ((match = this.tokenizer.rules.inline.blockSkip.exec(maskedSrc)) != null) { - maskedSrc = maskedSrc.slice(0, match.index) + "[" + repeatString("a", match[0].length - 2) + "]" + maskedSrc.slice(this.tokenizer.rules.inline.blockSkip.lastIndex); + const url = `${_impOsmUrls[key]}/retrieveComments?` + utilQsString(qParams); + const cacheComments = (data) => { + item.comments = data.comments ? data.comments.reverse() : []; + this.replaceItem(item); + }; + return json_default(url).then(cacheComments).then(() => item); + }, + postUpdate(d, callback) { + if (!osm_default.authenticated()) { + return callback({ message: "Not Authenticated", status: -3 }, d); } - while ((match = this.tokenizer.rules.inline.escapedEmSt.exec(maskedSrc)) != null) { - maskedSrc = maskedSrc.slice(0, match.index) + "++" + maskedSrc.slice(this.tokenizer.rules.inline.escapedEmSt.lastIndex); + if (_cache2.inflightPost[d.id]) { + return callback({ message: "Error update already inflight", status: -2 }, d); } - while (src) { - if (!keepPrevChar) { - prevChar = ""; + osm_default.userDetails(sendPayload.bind(this)); + function sendPayload(err, user) { + if (err) { + return callback(err, d); } - keepPrevChar = false; - if (this.options.extensions && this.options.extensions.inline && this.options.extensions.inline.some((extTokenizer) => { - if (token = extTokenizer.call({ lexer: this }, src, tokens)) { - src = src.substring(token.raw.length); - tokens.push(token); - return true; - } - return false; - })) { - continue; + const key = d.issueKey; + const url = `${_impOsmUrls[key]}/comment`; + const payload = { + username: user.display_name, + targetIds: [d.identifier] + }; + if (d.newStatus) { + payload.status = d.newStatus; + payload.text = "status changed"; } - if (token = this.tokenizer.escape(src)) { - src = src.substring(token.raw.length); - tokens.push(token); - continue; + if (d.newComment) { + payload.text = d.newComment; } - if (token = this.tokenizer.tag(src)) { - src = src.substring(token.raw.length); - lastToken = tokens[tokens.length - 1]; - if (lastToken && token.type === "text" && lastToken.type === "text") { - lastToken.raw += token.raw; - lastToken.text += token.text; + const controller = new AbortController(); + _cache2.inflightPost[d.id] = controller; + const options2 = { + method: "POST", + signal: controller.signal, + body: JSON.stringify(payload) + }; + json_default(url, options2).then(() => { + delete _cache2.inflightPost[d.id]; + if (!d.newStatus) { + const now3 = /* @__PURE__ */ new Date(); + let comments = d.comments ? d.comments : []; + comments.push({ + username: payload.username, + text: payload.text, + timestamp: now3.getTime() / 1e3 + }); + this.replaceItem(d.update({ + comments, + newComment: void 0 + })); } else { - tokens.push(token); - } - continue; - } - if (token = this.tokenizer.link(src)) { - src = src.substring(token.raw.length); - tokens.push(token); - continue; - } - if (token = this.tokenizer.reflink(src, this.tokens.links)) { - src = src.substring(token.raw.length); - lastToken = tokens[tokens.length - 1]; - if (lastToken && token.type === "text" && lastToken.type === "text") { - lastToken.raw += token.raw; - lastToken.text += token.text; - } else { - tokens.push(token); - } - continue; - } - if (token = this.tokenizer.emStrong(src, maskedSrc, prevChar)) { - src = src.substring(token.raw.length); - tokens.push(token); - continue; - } - if (token = this.tokenizer.codespan(src)) { - src = src.substring(token.raw.length); - tokens.push(token); - continue; - } - if (token = this.tokenizer.br(src)) { - src = src.substring(token.raw.length); - tokens.push(token); - continue; - } - if (token = this.tokenizer.del(src)) { - src = src.substring(token.raw.length); - tokens.push(token); - continue; - } - if (token = this.tokenizer.autolink(src, mangle)) { - src = src.substring(token.raw.length); - tokens.push(token); - continue; - } - if (!this.state.inLink && (token = this.tokenizer.url(src, mangle))) { - src = src.substring(token.raw.length); - tokens.push(token); - continue; - } - cutSrc = src; - if (this.options.extensions && this.options.extensions.startInline) { - let startIndex = Infinity; - const tempSrc = src.slice(1); - let tempStart; - this.options.extensions.startInline.forEach(function(getStartIndex) { - tempStart = getStartIndex.call({ lexer: this }, tempSrc); - if (typeof tempStart === "number" && tempStart >= 0) { - startIndex = Math.min(startIndex, tempStart); + this.removeItem(d); + if (d.newStatus === "SOLVED") { + if (!(d.issueKey in _cache2.closed)) { + _cache2.closed[d.issueKey] = 0; + } + _cache2.closed[d.issueKey] += 1; } - }); - if (startIndex < Infinity && startIndex >= 0) { - cutSrc = src.substring(0, startIndex + 1); - } - } - if (token = this.tokenizer.inlineText(cutSrc, smartypants)) { - src = src.substring(token.raw.length); - if (token.raw.slice(-1) !== "_") { - prevChar = token.raw.slice(-1); - } - keepPrevChar = true; - lastToken = tokens[tokens.length - 1]; - if (lastToken && lastToken.type === "text") { - lastToken.raw += token.raw; - lastToken.text += token.text; - } else { - tokens.push(token); } - continue; - } - if (src) { - const errMsg = "Infinite loop on byte: " + src.charCodeAt(0); - if (this.options.silent) { - console.error(errMsg); - break; - } else { - throw new Error(errMsg); - } - } + if (callback) + callback(null, d); + }).catch((err2) => { + delete _cache2.inflightPost[d.id]; + if (callback) + callback(err2.message); + }); } - return tokens; + }, + // Get all cached QAItems covering the viewport + getItems(projection2) { + const viewport = projection2.clipExtent(); + const min3 = [viewport[0][0], viewport[1][1]]; + const max3 = [viewport[1][0], viewport[0][1]]; + const bbox2 = geoExtent(projection2.invert(min3), projection2.invert(max3)).bbox(); + return _cache2.rtree.search(bbox2).map((d) => d.data); + }, + // Get a QAItem from cache + // NOTE: Don't change method name until UI v3 is merged + getError(id2) { + return _cache2.data[id2]; + }, + // get the name of the icon to display for this item + getIcon(itemType) { + return _impOsmData.icons[itemType]; + }, + // Replace a single QAItem in the cache + replaceItem(issue) { + if (!(issue instanceof QAItem) || !issue.id) + return; + _cache2.data[issue.id] = issue; + updateRtree2(encodeIssueRtree2(issue), true); + return issue; + }, + // Remove a single QAItem from the cache + removeItem(issue) { + if (!(issue instanceof QAItem) || !issue.id) + return; + delete _cache2.data[issue.id]; + updateRtree2(encodeIssueRtree2(issue), false); + }, + // Used to populate `closed:improveosm:*` changeset tags + getClosedCounts() { + return _cache2.closed; } }; - var Renderer = class { - constructor(options2) { - this.options = options2 || defaults; - } - code(code, infostring, escaped) { - const lang = (infostring || "").match(/\S*/)[0]; - if (this.options.highlight) { - const out = this.options.highlight(code, lang); - if (out != null && out !== code) { - escaped = true; - code = out; - } + + // modules/services/osmose.js + var import_rbush3 = __toESM(require_rbush_min()); + + // node_modules/marked/lib/marked.esm.js + function getDefaults() { + return { + async: false, + baseUrl: null, + breaks: false, + extensions: null, + gfm: true, + headerIds: true, + headerPrefix: "", + highlight: null, + hooks: null, + langPrefix: "language-", + mangle: true, + pedantic: false, + renderer: null, + sanitize: false, + sanitizer: null, + silent: false, + smartypants: false, + tokenizer: null, + walkTokens: null, + xhtml: false + }; + } + var defaults = getDefaults(); + function changeDefaults(newDefaults) { + defaults = newDefaults; + } + var escapeTest = /[&<>"']/; + var escapeReplace = new RegExp(escapeTest.source, "g"); + var escapeTestNoEncode = /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/; + var escapeReplaceNoEncode = new RegExp(escapeTestNoEncode.source, "g"); + var escapeReplacements = { + "&": "&", + "<": "<", + ">": ">", + '"': """, + "'": "'" + }; + var getEscapeReplacement = (ch) => escapeReplacements[ch]; + function escape4(html2, encode) { + if (encode) { + if (escapeTest.test(html2)) { + return html2.replace(escapeReplace, getEscapeReplacement); } - code = code.replace(/\n$/, "") + "\n"; - if (!lang) { - return "
" + (escaped ? code : escape4(code, true)) + "
\n"; + } else { + if (escapeTestNoEncode.test(html2)) { + return html2.replace(escapeReplaceNoEncode, getEscapeReplacement); } - return '
' + (escaped ? code : escape4(code, true)) + "
\n"; - } - blockquote(quote2) { - return `
-${quote2}
-`; - } - html(html2) { - return html2; } - heading(text2, level, raw, slugger) { - if (this.options.headerIds) { - const id2 = this.options.headerPrefix + slugger.slug(raw); - return `${text2} -`; + return html2; + } + var unescapeTest = /&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig; + function unescape3(html2) { + return html2.replace(unescapeTest, (_, n2) => { + n2 = n2.toLowerCase(); + if (n2 === "colon") + return ":"; + if (n2.charAt(0) === "#") { + return n2.charAt(1) === "x" ? String.fromCharCode(parseInt(n2.substring(2), 16)) : String.fromCharCode(+n2.substring(1)); + } + return ""; + }); + } + var caret = /(^|[^\[])\^/g; + function edit(regex, opt) { + regex = typeof regex === "string" ? regex : regex.source; + opt = opt || ""; + const obj = { + replace: (name, val) => { + val = val.source || val; + val = val.replace(caret, "$1"); + regex = regex.replace(name, val); + return obj; + }, + getRegex: () => { + return new RegExp(regex, opt); + } + }; + return obj; + } + var nonWordAndColonTest = /[^\w:]/g; + var originIndependentUrl = /^$|^[a-z][a-z0-9+.-]*:|^[?#]/i; + function cleanUrl(sanitize, base, href) { + if (sanitize) { + let prot; + try { + prot = decodeURIComponent(unescape3(href)).replace(nonWordAndColonTest, "").toLowerCase(); + } catch (e) { + return null; + } + if (prot.indexOf("javascript:") === 0 || prot.indexOf("vbscript:") === 0 || prot.indexOf("data:") === 0) { + return null; } - return `${text2} -`; - } - hr() { - return this.options.xhtml ? "
\n" : "
\n"; - } - list(body, ordered, start2) { - const type3 = ordered ? "ol" : "ul", startatt = ordered && start2 !== 1 ? ' start="' + start2 + '"' : ""; - return "<" + type3 + startatt + ">\n" + body + "\n"; - } - listitem(text2) { - return `
  • ${text2}
  • -`; - } - checkbox(checked) { - return " "; } - paragraph(text2) { - return `

    ${text2}

    -`; + if (base && !originIndependentUrl.test(href)) { + href = resolveUrl(base, href); } - table(header, body) { - if (body) - body = `${body}`; - return "\n\n" + header + "\n" + body + "
    \n"; + try { + href = encodeURI(href).replace(/%25/g, "%"); + } catch (e) { + return null; } - tablerow(content) { - return ` -${content} -`; + return href; + } + var baseUrls = {}; + var justDomain = /^[^:]+:\/*[^/]*$/; + var protocol = /^([^:]+:)[\s\S]*$/; + var domain = /^([^:]+:\/*[^/]*)[\s\S]*$/; + function resolveUrl(base, href) { + if (!baseUrls[" " + base]) { + if (justDomain.test(base)) { + baseUrls[" " + base] = base + "/"; + } else { + baseUrls[" " + base] = rtrim(base, "/", true); + } } - tablecell(content, flags) { - const type3 = flags.header ? "th" : "td"; - const tag = flags.align ? `<${type3} align="${flags.align}">` : `<${type3}>`; - return tag + content + ` -`; + base = baseUrls[" " + base]; + const relativeBase = base.indexOf(":") === -1; + if (href.substring(0, 2) === "//") { + if (relativeBase) { + return href; + } + return base.replace(protocol, "$1") + href; + } else if (href.charAt(0) === "/") { + if (relativeBase) { + return href; + } + return base.replace(domain, "$1") + href; + } else { + return base + href; } - strong(text2) { - return `${text2}`; + } + var noopTest = { exec: function noopTest2() { + } }; + function splitCells(tableRow, count) { + const row = tableRow.replace(/\|/g, (match, offset, str2) => { + let escaped = false, curr = offset; + while (--curr >= 0 && str2[curr] === "\\") + escaped = !escaped; + if (escaped) { + return "|"; + } else { + return " |"; + } + }), cells = row.split(/ \|/); + let i2 = 0; + if (!cells[0].trim()) { + cells.shift(); } - em(text2) { - return `${text2}`; + if (cells.length > 0 && !cells[cells.length - 1].trim()) { + cells.pop(); } - codespan(text2) { - return `${text2}`; + if (cells.length > count) { + cells.splice(count); + } else { + while (cells.length < count) + cells.push(""); } - br() { - return this.options.xhtml ? "
    " : "
    "; + for (; i2 < cells.length; i2++) { + cells[i2] = cells[i2].trim().replace(/\\\|/g, "|"); } - del(text2) { - return `${text2}`; + return cells; + } + function rtrim(str2, c, invert) { + const l = str2.length; + if (l === 0) { + return ""; } - link(href, title, text2) { - href = cleanUrl(this.options.sanitize, this.options.baseUrl, href); - if (href === null) { - return text2; - } - let out = '"; - return out; } - image(href, title, text2) { - href = cleanUrl(this.options.sanitize, this.options.baseUrl, href); - if (href === null) { - return text2; - } - let out = `${text2}" : ">"; - return out; + return str2.slice(0, l - suffLen); + } + function findClosingBracket(str2, b) { + if (str2.indexOf(b[1]) === -1) { + return -1; } - text(text2) { - return text2; + const l = str2.length; + let level = 0, i2 = 0; + for (; i2 < l; i2++) { + if (str2[i2] === "\\") { + i2++; + } else if (str2[i2] === b[0]) { + level++; + } else if (str2[i2] === b[1]) { + level--; + if (level < 0) { + return i2; + } + } } - }; - var TextRenderer = class { - strong(text2) { - return text2; + return -1; + } + function checkDeprecations(opt, callback) { + if (!opt || opt.silent) { + return; } - em(text2) { - return text2; + if (callback) { + console.warn("marked(): callback is deprecated since version 5.0.0, should not be used and will be removed in the future. Read more here: https://marked.js.org/using_pro#async"); } - codespan(text2) { - return text2; + if (opt.sanitize || opt.sanitizer) { + console.warn("marked(): sanitize and sanitizer parameters are deprecated since version 0.7.0, should not be used and will be removed in the future. Read more here: https://marked.js.org/#/USING_ADVANCED.md#options"); } - del(text2) { - return text2; + if (opt.highlight || opt.langPrefix !== "language-") { + console.warn("marked(): highlight and langPrefix parameters are deprecated since version 5.0.0, should not be used and will be removed in the future. Instead use https://www.npmjs.com/package/marked-highlight."); } - html(text2) { - return text2; + if (opt.mangle) { + console.warn("marked(): mangle parameter is enabled by default, but is deprecated since version 5.0.0, and will be removed in the future. To clear this warning, install https://www.npmjs.com/package/marked-mangle, or disable by setting `{mangle: false}`."); } - text(text2) { - return text2; + if (opt.baseUrl) { + console.warn("marked(): baseUrl parameter is deprecated since version 5.0.0, should not be used and will be removed in the future. Instead use https://www.npmjs.com/package/marked-base-url."); } - link(href, title, text2) { - return "" + text2; + if (opt.smartypants) { + console.warn("marked(): smartypants parameter is deprecated since version 5.0.0, should not be used and will be removed in the future. Instead use https://www.npmjs.com/package/marked-smartypants."); } - image(href, title, text2) { - return "" + text2; + if (opt.xhtml) { + console.warn("marked(): xhtml parameter is deprecated since version 5.0.0, should not be used and will be removed in the future. Instead use https://www.npmjs.com/package/marked-xhtml."); } - br() { - return ""; + if (opt.headerIds || opt.headerPrefix) { + console.warn("marked(): headerIds and headerPrefix parameters enabled by default, but are deprecated since version 5.0.0, and will be removed in the future. To clear this warning, install https://www.npmjs.com/package/marked-gfm-heading-id, or disable by setting `{headerIds: false}`."); } - }; - var Slugger = class { - constructor() { - this.seen = {}; + } + function outputLink(cap, link2, raw, lexer2) { + const href = link2.href; + const title = link2.title ? escape4(link2.title) : null; + const text2 = cap[1].replace(/\\([\[\]])/g, "$1"); + if (cap[0].charAt(0) !== "!") { + lexer2.state.inLink = true; + const token = { + type: "link", + raw, + href, + title, + text: text2, + tokens: lexer2.inlineTokens(text2) + }; + lexer2.state.inLink = false; + return token; } - serialize(value) { - return value.toLowerCase().trim().replace(/<[!\/a-z].*?>/ig, "").replace(/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g, "").replace(/\s/g, "-"); + return { + type: "image", + raw, + href, + title, + text: escape4(text2) + }; + } + function indentCodeCompensation(raw, text2) { + const matchIndentToCode = raw.match(/^(\s+)(?:```)/); + if (matchIndentToCode === null) { + return text2; } - getNextSafeSlug(originalSlug, isDryRun) { - let slug = originalSlug; - let occurenceAccumulator = 0; - if (this.seen.hasOwnProperty(slug)) { - occurenceAccumulator = this.seen[originalSlug]; - do { - occurenceAccumulator++; - slug = originalSlug + "-" + occurenceAccumulator; - } while (this.seen.hasOwnProperty(slug)); + const indentToCode = matchIndentToCode[1]; + return text2.split("\n").map((node) => { + const matchIndentInNode = node.match(/^\s+/); + if (matchIndentInNode === null) { + return node; } - if (!isDryRun) { - this.seen[originalSlug] = occurenceAccumulator; - this.seen[slug] = 0; + const [indentInNode] = matchIndentInNode; + if (indentInNode.length >= indentToCode.length) { + return node.slice(indentToCode.length); } - return slug; - } - slug(value, options2 = {}) { - const slug = this.serialize(value); - return this.getNextSafeSlug(slug, options2.dryrun); - } - }; - var Parser = class { + return node; + }).join("\n"); + } + var Tokenizer = class { constructor(options2) { this.options = options2 || defaults; - this.options.renderer = this.options.renderer || new Renderer(); - this.renderer = this.options.renderer; - this.renderer.options = this.options; - this.textRenderer = new TextRenderer(); - this.slugger = new Slugger(); - } - static parse(tokens, options2) { - const parser3 = new Parser(options2); - return parser3.parse(tokens); } - static parseInline(tokens, options2) { - const parser3 = new Parser(options2); - return parser3.parseInline(tokens); + space(src) { + const cap = this.rules.block.newline.exec(src); + if (cap && cap[0].length > 0) { + return { + type: "space", + raw: cap[0] + }; + } } - parse(tokens, top = true) { - let out = "", i2, j2, k, l2, l3, row, cell, header, body, token, ordered, start2, loose, itemBody, item, checked, task, checkbox, ret; - const l = tokens.length; - for (i2 = 0; i2 < l; i2++) { - token = tokens[i2]; - if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) { - ret = this.options.extensions.renderers[token.type].call({ parser: this }, token); - if (ret !== false || !["space", "hr", "heading", "code", "table", "blockquote", "list", "html", "paragraph", "text"].includes(token.type)) { - out += ret || ""; - continue; + code(src) { + const cap = this.rules.block.code.exec(src); + if (cap) { + const text2 = cap[0].replace(/^ {1,4}/gm, ""); + return { + type: "code", + raw: cap[0], + codeBlockStyle: "indented", + text: !this.options.pedantic ? rtrim(text2, "\n") : text2 + }; + } + } + fences(src) { + const cap = this.rules.block.fences.exec(src); + if (cap) { + const raw = cap[0]; + const text2 = indentCodeCompensation(raw, cap[3] || ""); + return { + type: "code", + raw, + lang: cap[2] ? cap[2].trim().replace(this.rules.inline._escapes, "$1") : cap[2], + text: text2 + }; + } + } + heading(src) { + const cap = this.rules.block.heading.exec(src); + if (cap) { + let text2 = cap[2].trim(); + if (/#$/.test(text2)) { + const trimmed = rtrim(text2, "#"); + if (this.options.pedantic) { + text2 = trimmed.trim(); + } else if (!trimmed || / $/.test(trimmed)) { + text2 = trimmed.trim(); } } - switch (token.type) { - case "space": { - continue; + return { + type: "heading", + raw: cap[0], + depth: cap[1].length, + text: text2, + tokens: this.lexer.inline(text2) + }; + } + } + hr(src) { + const cap = this.rules.block.hr.exec(src); + if (cap) { + return { + type: "hr", + raw: cap[0] + }; + } + } + blockquote(src) { + const cap = this.rules.block.blockquote.exec(src); + if (cap) { + const text2 = cap[0].replace(/^ *>[ \t]?/gm, ""); + const top = this.lexer.state.top; + this.lexer.state.top = true; + const tokens = this.lexer.blockTokens(text2); + this.lexer.state.top = top; + return { + type: "blockquote", + raw: cap[0], + tokens, + text: text2 + }; + } + } + list(src) { + let cap = this.rules.block.list.exec(src); + if (cap) { + let raw, istask, ischecked, indent2, i2, blankLine, endsWithBlankLine, line, nextLine, rawLine, itemContents, endEarly; + let bull = cap[1].trim(); + const isordered = bull.length > 1; + const list = { + type: "list", + raw: "", + ordered: isordered, + start: isordered ? +bull.slice(0, -1) : "", + loose: false, + items: [] + }; + bull = isordered ? `\\d{1,9}\\${bull.slice(-1)}` : `\\${bull}`; + if (this.options.pedantic) { + bull = isordered ? bull : "[*+-]"; + } + const itemRegex = new RegExp(`^( {0,3}${bull})((?:[ ][^\\n]*)?(?:\\n|$))`); + while (src) { + endEarly = false; + if (!(cap = itemRegex.exec(src))) { + break; } - case "hr": { - out += this.renderer.hr(); - continue; + if (this.rules.block.hr.test(src)) { + break; } - case "heading": { - out += this.renderer.heading( - this.parseInline(token.tokens), - token.depth, - unescape3(this.parseInline(token.tokens, this.textRenderer)), - this.slugger - ); - continue; + raw = cap[0]; + src = src.substring(raw.length); + line = cap[2].split("\n", 1)[0].replace(/^\t+/, (t) => " ".repeat(3 * t.length)); + nextLine = src.split("\n", 1)[0]; + if (this.options.pedantic) { + indent2 = 2; + itemContents = line.trimLeft(); + } else { + indent2 = cap[2].search(/[^ ]/); + indent2 = indent2 > 4 ? 1 : indent2; + itemContents = line.slice(indent2); + indent2 += cap[1].length; } - case "code": { - out += this.renderer.code( - token.text, - token.lang, - token.escaped - ); - continue; + blankLine = false; + if (!line && /^ *$/.test(nextLine)) { + raw += nextLine + "\n"; + src = src.substring(nextLine.length + 1); + endEarly = true; } - case "table": { - header = ""; - cell = ""; - l2 = token.header.length; - for (j2 = 0; j2 < l2; j2++) { - cell += this.renderer.tablecell( - this.parseInline(token.header[j2].tokens), - { header: true, align: token.align[j2] } - ); - } - header += this.renderer.tablerow(cell); - body = ""; - l2 = token.rows.length; - for (j2 = 0; j2 < l2; j2++) { - row = token.rows[j2]; - cell = ""; - l3 = row.length; - for (k = 0; k < l3; k++) { - cell += this.renderer.tablecell( - this.parseInline(row[k].tokens), - { header: false, align: token.align[k] } - ); + if (!endEarly) { + const nextBulletRegex = new RegExp(`^ {0,${Math.min(3, indent2 - 1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ ][^\\n]*)?(?:\\n|$))`); + const hrRegex = new RegExp(`^ {0,${Math.min(3, indent2 - 1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`); + const fencesBeginRegex = new RegExp(`^ {0,${Math.min(3, indent2 - 1)}}(?:\`\`\`|~~~)`); + const headingBeginRegex = new RegExp(`^ {0,${Math.min(3, indent2 - 1)}}#`); + while (src) { + rawLine = src.split("\n", 1)[0]; + nextLine = rawLine; + if (this.options.pedantic) { + nextLine = nextLine.replace(/^ {1,4}(?=( {4})*[^ ])/g, " "); } - body += this.renderer.tablerow(cell); - } - out += this.renderer.table(header, body); - continue; - } - case "blockquote": { - body = this.parse(token.tokens); - out += this.renderer.blockquote(body); - continue; - } - case "list": { - ordered = token.ordered; - start2 = token.start; - loose = token.loose; - l2 = token.items.length; - body = ""; - for (j2 = 0; j2 < l2; j2++) { - item = token.items[j2]; - checked = item.checked; - task = item.task; - itemBody = ""; - if (item.task) { - checkbox = this.renderer.checkbox(checked); - if (loose) { - if (item.tokens.length > 0 && item.tokens[0].type === "paragraph") { - item.tokens[0].text = checkbox + " " + item.tokens[0].text; - if (item.tokens[0].tokens && item.tokens[0].tokens.length > 0 && item.tokens[0].tokens[0].type === "text") { - item.tokens[0].tokens[0].text = checkbox + " " + item.tokens[0].tokens[0].text; - } - } else { - item.tokens.unshift({ - type: "text", - text: checkbox - }); - } - } else { - itemBody += checkbox; + if (fencesBeginRegex.test(nextLine)) { + break; + } + if (headingBeginRegex.test(nextLine)) { + break; + } + if (nextBulletRegex.test(nextLine)) { + break; + } + if (hrRegex.test(src)) { + break; + } + if (nextLine.search(/[^ ]/) >= indent2 || !nextLine.trim()) { + itemContents += "\n" + nextLine.slice(indent2); + } else { + if (blankLine) { + break; + } + if (line.search(/[^ ]/) >= 4) { + break; + } + if (fencesBeginRegex.test(line)) { + break; } + if (headingBeginRegex.test(line)) { + break; + } + if (hrRegex.test(line)) { + break; + } + itemContents += "\n" + nextLine; } - itemBody += this.parse(item.tokens, loose); - body += this.renderer.listitem(itemBody, task, checked); + if (!blankLine && !nextLine.trim()) { + blankLine = true; + } + raw += rawLine + "\n"; + src = src.substring(rawLine.length + 1); + line = nextLine.slice(indent2); } - out += this.renderer.list(body, ordered, start2); - continue; - } - case "html": { - out += this.renderer.html(token.text); - continue; - } - case "paragraph": { - out += this.renderer.paragraph(this.parseInline(token.tokens)); - continue; } - case "text": { - body = token.tokens ? this.parseInline(token.tokens) : token.text; - while (i2 + 1 < l && tokens[i2 + 1].type === "text") { - token = tokens[++i2]; - body += "\n" + (token.tokens ? this.parseInline(token.tokens) : token.text); + if (!list.loose) { + if (endsWithBlankLine) { + list.loose = true; + } else if (/\n *\n *$/.test(raw)) { + endsWithBlankLine = true; } - out += top ? this.renderer.paragraph(body) : body; - continue; } - default: { - const errMsg = 'Token with "' + token.type + '" type was not found.'; - if (this.options.silent) { - console.error(errMsg); - return; - } else { - throw new Error(errMsg); + if (this.options.gfm) { + istask = /^\[[ xX]\] /.exec(itemContents); + if (istask) { + ischecked = istask[0] !== "[ ] "; + itemContents = itemContents.replace(/^\[[ xX]\] +/, ""); } } + list.items.push({ + type: "list_item", + raw, + task: !!istask, + checked: ischecked, + loose: false, + text: itemContents + }); + list.raw += raw; } - } - return out; - } - parseInline(tokens, renderer) { - renderer = renderer || this.renderer; - let out = "", i2, token, ret; - const l = tokens.length; - for (i2 = 0; i2 < l; i2++) { - token = tokens[i2]; - if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) { - ret = this.options.extensions.renderers[token.type].call({ parser: this }, token); - if (ret !== false || !["escape", "html", "link", "image", "strong", "em", "codespan", "br", "del", "text"].includes(token.type)) { - out += ret || ""; - continue; + list.items[list.items.length - 1].raw = raw.trimRight(); + list.items[list.items.length - 1].text = itemContents.trimRight(); + list.raw = list.raw.trimRight(); + const l = list.items.length; + for (i2 = 0; i2 < l; i2++) { + this.lexer.state.top = false; + list.items[i2].tokens = this.lexer.blockTokens(list.items[i2].text, []); + if (!list.loose) { + const spacers = list.items[i2].tokens.filter((t) => t.type === "space"); + const hasMultipleLineBreaks = spacers.length > 0 && spacers.some((t) => /\n.*\n/.test(t.raw)); + list.loose = hasMultipleLineBreaks; } } - switch (token.type) { - case "escape": { - out += renderer.text(token.text); - break; - } - case "html": { - out += renderer.html(token.text); - break; - } - case "link": { - out += renderer.link(token.href, token.title, this.parseInline(token.tokens, renderer)); - break; - } - case "image": { - out += renderer.image(token.href, token.title, token.text); - break; - } - case "strong": { - out += renderer.strong(this.parseInline(token.tokens, renderer)); - break; - } - case "em": { - out += renderer.em(this.parseInline(token.tokens, renderer)); - break; - } - case "codespan": { - out += renderer.codespan(token.text); - break; - } - case "br": { - out += renderer.br(); - break; - } - case "del": { - out += renderer.del(this.parseInline(token.tokens, renderer)); - break; - } - case "text": { - out += renderer.text(token.text); - break; - } - default: { - const errMsg = 'Token with "' + token.type + '" type was not found.'; - if (this.options.silent) { - console.error(errMsg); - return; - } else { - throw new Error(errMsg); - } + if (list.loose) { + for (i2 = 0; i2 < l; i2++) { + list.items[i2].loose = true; } } + return list; } - return out; - } - }; - function marked(src, opt, callback) { - if (typeof src === "undefined" || src === null) { - throw new Error("marked(): input parameter is undefined or null"); - } - if (typeof src !== "string") { - throw new Error("marked(): input parameter is of type " + Object.prototype.toString.call(src) + ", string expected"); - } - if (typeof opt === "function") { - callback = opt; - opt = null; } - opt = merge2({}, marked.defaults, opt || {}); - checkSanitizeDeprecation(opt); - if (callback) { - const highlight = opt.highlight; - let tokens; - try { - tokens = Lexer.lex(src, opt); - } catch (e) { - return callback(e); - } - const done = function(err) { - let out; - if (!err) { - try { - if (opt.walkTokens) { - marked.walkTokens(tokens, opt.walkTokens); - } - out = Parser.parse(tokens, opt); - } catch (e) { - err = e; - } - } - opt.highlight = highlight; - return err ? callback(err) : callback(null, out); - }; - if (!highlight || highlight.length < 3) { - return done(); - } - delete opt.highlight; - if (!tokens.length) - return done(); - let pending = 0; - marked.walkTokens(tokens, function(token) { - if (token.type === "code") { - pending++; - setTimeout(() => { - highlight(token.text, token.lang, function(err, code) { - if (err) { - return done(err); - } - if (code != null && code !== token.text) { - token.text = code; - token.escaped = true; - } - pending--; - if (pending === 0) { - done(); - } - }); - }, 0); + html(src) { + const cap = this.rules.block.html.exec(src); + if (cap) { + const token = { + type: "html", + block: true, + raw: cap[0], + pre: !this.options.sanitizer && (cap[1] === "pre" || cap[1] === "script" || cap[1] === "style"), + text: cap[0] + }; + if (this.options.sanitize) { + const text2 = this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape4(cap[0]); + token.type = "paragraph"; + token.text = text2; + token.tokens = this.lexer.inline(text2); } - }); - if (pending === 0) { - done(); - } - return; - } - function onError(e) { - e.message += "\nPlease report this to https://github.com/markedjs/marked."; - if (opt.silent) { - return "

    An error occurred:

    " + escape4(e.message + "", true) + "
    "; + return token; } - throw e; } - try { - const tokens = Lexer.lex(src, opt); - if (opt.walkTokens) { - if (opt.async) { - return Promise.all(marked.walkTokens(tokens, opt.walkTokens)).then(() => { - return Parser.parse(tokens, opt); - }).catch(onError); - } - marked.walkTokens(tokens, opt.walkTokens); + def(src) { + const cap = this.rules.block.def.exec(src); + if (cap) { + const tag = cap[1].toLowerCase().replace(/\s+/g, " "); + const href = cap[2] ? cap[2].replace(/^<(.*)>$/, "$1").replace(this.rules.inline._escapes, "$1") : ""; + const title = cap[3] ? cap[3].substring(1, cap[3].length - 1).replace(this.rules.inline._escapes, "$1") : cap[3]; + return { + type: "def", + tag, + raw: cap[0], + href, + title + }; } - return Parser.parse(tokens, opt); - } catch (e) { - onError(e); } - } - marked.options = marked.setOptions = function(opt) { - merge2(marked.defaults, opt); - changeDefaults(marked.defaults); - return marked; - }; - marked.getDefaults = getDefaults; - marked.defaults = defaults; - marked.use = function(...args) { - const opts = merge2({}, ...args); - const extensions = marked.defaults.extensions || { renderers: {}, childTokens: {} }; - let hasExtensions; - args.forEach((pack) => { - if (pack.extensions) { - hasExtensions = true; - pack.extensions.forEach((ext) => { - if (!ext.name) { - throw new Error("extension name required"); - } - if (ext.renderer) { - const prevRenderer = extensions.renderers ? extensions.renderers[ext.name] : null; - if (prevRenderer) { - extensions.renderers[ext.name] = function(...args2) { - let ret = ext.renderer.apply(this, args2); - if (ret === false) { - ret = prevRenderer.apply(this, args2); - } - return ret; - }; - } else { - extensions.renderers[ext.name] = ext.renderer; - } - } - if (ext.tokenizer) { - if (!ext.level || ext.level !== "block" && ext.level !== "inline") { - throw new Error("extension level must be 'block' or 'inline'"); - } - if (extensions[ext.level]) { - extensions[ext.level].unshift(ext.tokenizer); + table(src) { + const cap = this.rules.block.table.exec(src); + if (cap) { + const item = { + type: "table", + header: splitCells(cap[1]).map((c) => { + return { text: c }; + }), + align: cap[2].replace(/^ *|\| *$/g, "").split(/ *\| */), + rows: cap[3] && cap[3].trim() ? cap[3].replace(/\n[ \t]*$/, "").split("\n") : [] + }; + if (item.header.length === item.align.length) { + item.raw = cap[0]; + let l = item.align.length; + let i2, j2, k, row; + for (i2 = 0; i2 < l; i2++) { + if (/^ *-+: *$/.test(item.align[i2])) { + item.align[i2] = "right"; + } else if (/^ *:-+: *$/.test(item.align[i2])) { + item.align[i2] = "center"; + } else if (/^ *:-+ *$/.test(item.align[i2])) { + item.align[i2] = "left"; } else { - extensions[ext.level] = [ext.tokenizer]; - } - if (ext.start) { - if (ext.level === "block") { - if (extensions.startBlock) { - extensions.startBlock.push(ext.start); - } else { - extensions.startBlock = [ext.start]; - } - } else if (ext.level === "inline") { - if (extensions.startInline) { - extensions.startInline.push(ext.start); - } else { - extensions.startInline = [ext.start]; - } - } + item.align[i2] = null; } } - if (ext.childTokens) { - extensions.childTokens[ext.name] = ext.childTokens; - } - }); - } - if (pack.renderer) { - const renderer = marked.defaults.renderer || new Renderer(); - for (const prop in pack.renderer) { - const prevRenderer = renderer[prop]; - renderer[prop] = (...args2) => { - let ret = pack.renderer[prop].apply(renderer, args2); - if (ret === false) { - ret = prevRenderer.apply(renderer, args2); - } - return ret; - }; - } - opts.renderer = renderer; - } - if (pack.tokenizer) { - const tokenizer = marked.defaults.tokenizer || new Tokenizer(); - for (const prop in pack.tokenizer) { - const prevTokenizer = tokenizer[prop]; - tokenizer[prop] = (...args2) => { - let ret = pack.tokenizer[prop].apply(tokenizer, args2); - if (ret === false) { - ret = prevTokenizer.apply(tokenizer, args2); - } - return ret; - }; - } - opts.tokenizer = tokenizer; - } - if (pack.walkTokens) { - const walkTokens2 = marked.defaults.walkTokens; - opts.walkTokens = function(token) { - let values = []; - values.push(pack.walkTokens.call(this, token)); - if (walkTokens2) { - values = values.concat(walkTokens2.call(this, token)); + l = item.rows.length; + for (i2 = 0; i2 < l; i2++) { + item.rows[i2] = splitCells(item.rows[i2], item.header.length).map((c) => { + return { text: c }; + }); } - return values; - }; - } - if (hasExtensions) { - opts.extensions = extensions; - } - marked.setOptions(opts); - }); - }; - marked.walkTokens = function(tokens, callback) { - let values = []; - for (const token of tokens) { - values = values.concat(callback.call(marked, token)); - switch (token.type) { - case "table": { - for (const cell of token.header) { - values = values.concat(marked.walkTokens(cell.tokens, callback)); + l = item.header.length; + for (j2 = 0; j2 < l; j2++) { + item.header[j2].tokens = this.lexer.inline(item.header[j2].text); } - for (const row of token.rows) { - for (const cell of row) { - values = values.concat(marked.walkTokens(cell.tokens, callback)); + l = item.rows.length; + for (j2 = 0; j2 < l; j2++) { + row = item.rows[j2]; + for (k = 0; k < row.length; k++) { + row[k].tokens = this.lexer.inline(row[k].text); } } - break; - } - case "list": { - values = values.concat(marked.walkTokens(token.items, callback)); - break; - } - default: { - if (marked.defaults.extensions && marked.defaults.extensions.childTokens && marked.defaults.extensions.childTokens[token.type]) { - marked.defaults.extensions.childTokens[token.type].forEach(function(childTokens) { - values = values.concat(marked.walkTokens(token[childTokens], callback)); - }); - } else if (token.tokens) { - values = values.concat(marked.walkTokens(token.tokens, callback)); - } + return item; } } } - return values; - }; - marked.parseInline = function(src, opt) { - if (typeof src === "undefined" || src === null) { - throw new Error("marked.parseInline(): input parameter is undefined or null"); - } - if (typeof src !== "string") { - throw new Error("marked.parseInline(): input parameter is of type " + Object.prototype.toString.call(src) + ", string expected"); + lheading(src) { + const cap = this.rules.block.lheading.exec(src); + if (cap) { + return { + type: "heading", + raw: cap[0], + depth: cap[2].charAt(0) === "=" ? 1 : 2, + text: cap[1], + tokens: this.lexer.inline(cap[1]) + }; + } } - opt = merge2({}, marked.defaults, opt || {}); - checkSanitizeDeprecation(opt); - try { - const tokens = Lexer.lexInline(src, opt); - if (opt.walkTokens) { - marked.walkTokens(tokens, opt.walkTokens); + paragraph(src) { + const cap = this.rules.block.paragraph.exec(src); + if (cap) { + const text2 = cap[1].charAt(cap[1].length - 1) === "\n" ? cap[1].slice(0, -1) : cap[1]; + return { + type: "paragraph", + raw: cap[0], + text: text2, + tokens: this.lexer.inline(text2) + }; } - return Parser.parseInline(tokens, opt); - } catch (e) { - e.message += "\nPlease report this to https://github.com/markedjs/marked."; - if (opt.silent) { - return "

    An error occurred:

    " + escape4(e.message + "", true) + "
    "; + } + text(src) { + const cap = this.rules.block.text.exec(src); + if (cap) { + return { + type: "text", + raw: cap[0], + text: cap[0], + tokens: this.lexer.inline(cap[0]) + }; } - throw e; } - }; - marked.Parser = Parser; - marked.parser = Parser.parse; - marked.Renderer = Renderer; - marked.TextRenderer = TextRenderer; - marked.Lexer = Lexer; - marked.lexer = Lexer.lex; - marked.Tokenizer = Tokenizer; - marked.Slugger = Slugger; - marked.parse = marked; - var options = marked.options; - var setOptions = marked.setOptions; - var use = marked.use; - var walkTokens = marked.walkTokens; - var parseInline = marked.parseInline; - var parser2 = Parser.parse; - var lexer = Lexer.lex; - - // modules/services/osmose.js - var tiler3 = utilTiler(); - var dispatch4 = dispatch_default("loaded"); - var _tileZoom3 = 14; - var _osmoseUrlRoot = "https://osmose.openstreetmap.fr/api/0.3"; - var _osmoseData = { icons: {}, items: [] }; - var _cache3; - function abortRequest3(controller) { - if (controller) { - controller.abort(); - } - } - function abortUnwantedRequests3(cache, tiles) { - Object.keys(cache.inflightTile).forEach((k) => { - let wanted = tiles.find((tile) => k === tile.id); - if (!wanted) { - abortRequest3(cache.inflightTile[k]); - delete cache.inflightTile[k]; + escape(src) { + const cap = this.rules.inline.escape.exec(src); + if (cap) { + return { + type: "escape", + raw: cap[0], + text: escape4(cap[1]) + }; } - }); - } - function encodeIssueRtree3(d) { - return { minX: d.loc[0], minY: d.loc[1], maxX: d.loc[0], maxY: d.loc[1], data: d }; - } - function updateRtree3(item, replace) { - _cache3.rtree.remove(item, (a, b) => a.data.id === b.data.id); - if (replace) { - _cache3.rtree.insert(item); } - } - function preventCoincident2(loc) { - let coincident = false; - do { - let delta = coincident ? [1e-5, 0] : [0, 1e-5]; - loc = geoVecAdd(loc, delta); - let bbox = geoExtent(loc).bbox(); - coincident = _cache3.rtree.search(bbox).length; - } while (coincident); - return loc; - } - var osmose_default = { - title: "osmose", - init() { - _mainFileFetcher.get("qa_data").then((d) => { - _osmoseData = d.osmose; - _osmoseData.items = Object.keys(d.osmose.icons).map((s) => s.split("-")[0]).reduce((unique, item) => unique.indexOf(item) !== -1 ? unique : [...unique, item], []); - }); - if (!_cache3) { - this.reset(); - } - this.event = utilRebind(this, dispatch4, "on"); - }, - reset() { - let _strings = {}; - let _colors = {}; - if (_cache3) { - Object.values(_cache3.inflightTile).forEach(abortRequest3); - _strings = _cache3.strings; - _colors = _cache3.colors; + tag(src) { + const cap = this.rules.inline.tag.exec(src); + if (cap) { + if (!this.lexer.state.inLink && /^
    /i.test(cap[0])) { + this.lexer.state.inLink = false; + } + if (!this.lexer.state.inRawBlock && /^<(pre|code|kbd|script)(\s|>)/i.test(cap[0])) { + this.lexer.state.inRawBlock = true; + } else if (this.lexer.state.inRawBlock && /^<\/(pre|code|kbd|script)(\s|>)/i.test(cap[0])) { + this.lexer.state.inRawBlock = false; + } + return { + type: this.options.sanitize ? "text" : "html", + raw: cap[0], + inLink: this.lexer.state.inLink, + inRawBlock: this.lexer.state.inRawBlock, + block: false, + text: this.options.sanitize ? this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape4(cap[0]) : cap[0] + }; } - _cache3 = { - data: {}, - loadedTile: {}, - inflightTile: {}, - inflightPost: {}, - closed: {}, - rtree: new import_rbush3.default(), - strings: _strings, - colors: _colors - }; - }, - loadIssues(projection2) { - let params = { - item: _osmoseData.items - }; - let tiles = tiler3.zoomExtent([_tileZoom3, _tileZoom3]).getTiles(projection2); - abortUnwantedRequests3(_cache3, tiles); - tiles.forEach((tile) => { - if (_cache3.loadedTile[tile.id] || _cache3.inflightTile[tile.id]) - return; - let [x, y, z] = tile.xyz; - let url = `${_osmoseUrlRoot}/issues/${z}/${x}/${y}.geojson?` + utilQsString(params); - let controller = new AbortController(); - _cache3.inflightTile[tile.id] = controller; - json_default(url, { signal: controller.signal }).then((data) => { - delete _cache3.inflightTile[tile.id]; - _cache3.loadedTile[tile.id] = true; - if (data.features) { - data.features.forEach((issue) => { - const { item, class: cl, uuid: id2 } = issue.properties; - const itemType = `${item}-${cl}`; - if (itemType in _osmoseData.icons) { - let loc = issue.geometry.coordinates; - loc = preventCoincident2(loc); - let d = new QAItem(loc, this, itemType, id2, { item }); - if (item === 8300 || item === 8360) { - d.elems = []; - } - _cache3.data[d.id] = d; - _cache3.rtree.insert(encodeIssueRtree3(d)); - } - }); + } + link(src) { + const cap = this.rules.inline.link.exec(src); + if (cap) { + const trimmedUrl = cap[2].trim(); + if (!this.options.pedantic && /^$/.test(trimmedUrl)) { + return; } - dispatch4.call("loaded"); - }).catch(() => { - delete _cache3.inflightTile[tile.id]; - _cache3.loadedTile[tile.id] = true; - }); - }); - }, - loadIssueDetail(issue) { - if (issue.elems !== void 0) { - return Promise.resolve(issue); - } - const url = `${_osmoseUrlRoot}/issue/${issue.id}?langs=${_mainLocalizer.localeCode()}`; - const cacheDetails = (data) => { - issue.elems = data.elems.map((e) => e.type.substring(0, 1) + e.id); - issue.detail = data.subtitle ? marked(data.subtitle.auto) : ""; - this.replaceItem(issue); - }; - return json_default(url).then(cacheDetails).then(() => issue); - }, - loadStrings(locale2 = _mainLocalizer.localeCode()) { - const items = Object.keys(_osmoseData.icons); - if (locale2 in _cache3.strings && Object.keys(_cache3.strings[locale2]).length === items.length) { - return Promise.resolve(_cache3.strings[locale2]); - } - if (!(locale2 in _cache3.strings)) { - _cache3.strings[locale2] = {}; - } - const allRequests = items.map((itemType) => { - if (itemType in _cache3.strings[locale2]) - return null; - const cacheData = (data) => { - const [cat = { items: [] }] = data.categories; - const [item2 = { class: [] }] = cat.items; - const [cl2 = null] = item2.class; - if (!cl2) { - console.log(`Osmose strings request (${itemType}) had unexpected data`); + const rtrimSlash = rtrim(trimmedUrl.slice(0, -1), "\\"); + if ((trimmedUrl.length - rtrimSlash.length) % 2 === 0) { return; } - const { item: itemInt, color: color2 } = item2; - if (/^#[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3}/.test(color2)) { - _cache3.colors[itemInt] = color2; + } else { + const lastParenIndex = findClosingBracket(cap[2], "()"); + if (lastParenIndex > -1) { + const start2 = cap[0].indexOf("!") === 0 ? 5 : 4; + const linkLen = start2 + cap[1].length + lastParenIndex; + cap[2] = cap[2].substring(0, lastParenIndex); + cap[0] = cap[0].substring(0, linkLen).trim(); + cap[3] = ""; } - const { title, detail, fix, trap } = cl2; - let issueStrings = {}; - if (title) - issueStrings.title = title.auto; - if (detail) - issueStrings.detail = marked(detail.auto); - if (trap) - issueStrings.trap = marked(trap.auto); - if (fix) - issueStrings.fix = marked(fix.auto); - _cache3.strings[locale2][itemType] = issueStrings; - }; - const [item, cl] = itemType.split("-"); - const url = `${_osmoseUrlRoot}/items/${item}/class/${cl}?langs=${locale2}`; - return json_default(url).then(cacheData); - }).filter(Boolean); - return Promise.all(allRequests).then(() => _cache3.strings[locale2]); - }, - getStrings(itemType, locale2 = _mainLocalizer.localeCode()) { - return locale2 in _cache3.strings ? _cache3.strings[locale2][itemType] : {}; - }, - getColor(itemType) { - return itemType in _cache3.colors ? _cache3.colors[itemType] : "#FFFFFF"; - }, - postUpdate(issue, callback) { - if (_cache3.inflightPost[issue.id]) { - return callback({ message: "Issue update already inflight", status: -2 }, issue); - } - const url = `${_osmoseUrlRoot}/issue/${issue.id}/${issue.newStatus}`; - const controller = new AbortController(); - const after = () => { - delete _cache3.inflightPost[issue.id]; - this.removeItem(issue); - if (issue.newStatus === "done") { - if (!(issue.item in _cache3.closed)) { - _cache3.closed[issue.item] = 0; + } + let href = cap[2]; + let title = ""; + if (this.options.pedantic) { + const link2 = /^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(href); + if (link2) { + href = link2[1]; + title = link2[3]; } - _cache3.closed[issue.item] += 1; + } else { + title = cap[3] ? cap[3].slice(1, -1) : ""; } - if (callback) - callback(null, issue); - }; - _cache3.inflightPost[issue.id] = controller; - fetch(url, { signal: controller.signal }).then(after).catch((err) => { - delete _cache3.inflightPost[issue.id]; - if (callback) - callback(err.message); - }); - }, - getItems(projection2) { - const viewport = projection2.clipExtent(); - const min3 = [viewport[0][0], viewport[1][1]]; - const max3 = [viewport[1][0], viewport[0][1]]; - const bbox = geoExtent(projection2.invert(min3), projection2.invert(max3)).bbox(); - return _cache3.rtree.search(bbox).map((d) => d.data); - }, - getError(id2) { - return _cache3.data[id2]; - }, - getIcon(itemType) { - return _osmoseData.icons[itemType]; - }, - replaceItem(item) { - if (!(item instanceof QAItem) || !item.id) - return; - _cache3.data[item.id] = item; - updateRtree3(encodeIssueRtree3(item), true); - return item; - }, - removeItem(item) { - if (!(item instanceof QAItem) || !item.id) - return; - delete _cache3.data[item.id]; - updateRtree3(encodeIssueRtree3(item), false); - }, - getClosedCounts() { - return _cache3.closed; - }, - itemURL(item) { - return `https://osmose.openstreetmap.fr/en/error/${item.id}`; - } - }; - - // modules/services/mapillary.js - var import_pbf = __toESM(require_pbf()); - var import_rbush4 = __toESM(require_rbush_min()); - var import_vector_tile = __toESM(require_vector_tile()); - var accessToken = "MLY|4100327730013843|5bb78b81720791946a9a7b956c57b7cf"; - var apiUrl = "https://graph.mapillary.com/"; - var baseTileUrl = "https://tiles.mapillary.com/maps/vtp"; - var mapFeatureTileUrl = `${baseTileUrl}/mly_map_feature_point/2/{z}/{x}/{y}?access_token=${accessToken}`; - var tileUrl = `${baseTileUrl}/mly1_public/2/{z}/{x}/{y}?access_token=${accessToken}`; - var trafficSignTileUrl = `${baseTileUrl}/mly_map_feature_traffic_sign/2/{z}/{x}/{y}?access_token=${accessToken}`; - var viewercss = "mapillary-js/mapillary.css"; - var viewerjs = "mapillary-js/mapillary.js"; - var minZoom = 14; - var dispatch5 = dispatch_default("change", "loadedImages", "loadedSigns", "loadedMapFeatures", "bearingChanged", "imageChanged"); - var _loadViewerPromise; - var _mlyActiveImage; - var _mlyCache; - var _mlyFallback = false; - var _mlyHighlightedDetection; - var _mlyShowFeatureDetections = false; - var _mlyShowSignDetections = false; - var _mlyViewer; - var _mlyViewerFilter = ["all"]; - function loadTiles(which, url, maxZoom2, projection2) { - const tiler8 = utilTiler().zoomExtent([minZoom, maxZoom2]).skipNullIsland(true); - const tiles = tiler8.getTiles(projection2); - tiles.forEach(function(tile) { - loadTile(which, url, tile); - }); - } - function loadTile(which, url, tile) { - const cache = _mlyCache.requests; - const tileId = `${tile.id}-${which}`; - if (cache.loaded[tileId] || cache.inflight[tileId]) - return; - const controller = new AbortController(); - cache.inflight[tileId] = controller; - const requestUrl = url.replace("{x}", tile.xyz[0]).replace("{y}", tile.xyz[1]).replace("{z}", tile.xyz[2]); - fetch(requestUrl, { signal: controller.signal }).then(function(response) { - if (!response.ok) { - throw new Error(response.status + " " + response.statusText); - } - cache.loaded[tileId] = true; - delete cache.inflight[tileId]; - return response.arrayBuffer(); - }).then(function(data) { - if (!data) { - throw new Error("No Data"); - } - loadTileDataToCache(data, tile, which); - if (which === "images") { - dispatch5.call("loadedImages"); - } else if (which === "signs") { - dispatch5.call("loadedSigns"); - } else if (which === "points") { - dispatch5.call("loadedMapFeatures"); - } - }).catch(function() { - cache.loaded[tileId] = true; - delete cache.inflight[tileId]; - }); - } - function loadTileDataToCache(data, tile, which) { - const vectorTile = new import_vector_tile.VectorTile(new import_pbf.default(data)); - let features2, cache, layer, i2, feature3, loc, d; - if (vectorTile.layers.hasOwnProperty("image")) { - features2 = []; - cache = _mlyCache.images; - layer = vectorTile.layers.image; - for (i2 = 0; i2 < layer.length; i2++) { - feature3 = layer.feature(i2).toGeoJSON(tile.xyz[0], tile.xyz[1], tile.xyz[2]); - loc = feature3.geometry.coordinates; - d = { - loc, - captured_at: feature3.properties.captured_at, - ca: feature3.properties.compass_angle, - id: feature3.properties.id, - is_pano: feature3.properties.is_pano, - sequence_id: feature3.properties.sequence_id - }; - cache.forImageId[d.id] = d; - features2.push({ - minX: loc[0], - minY: loc[1], - maxX: loc[0], - maxY: loc[1], - data: d - }); + href = href.trim(); + if (/^$/.test(trimmedUrl)) { + href = href.slice(1); + } else { + href = href.slice(1, -1); + } + } + return outputLink(cap, { + href: href ? href.replace(this.rules.inline._escapes, "$1") : href, + title: title ? title.replace(this.rules.inline._escapes, "$1") : title + }, cap[0], this.lexer); } - if (cache.rtree) { - cache.rtree.load(features2); + } + reflink(src, links) { + let cap; + if ((cap = this.rules.inline.reflink.exec(src)) || (cap = this.rules.inline.nolink.exec(src))) { + let link2 = (cap[2] || cap[1]).replace(/\s+/g, " "); + link2 = links[link2.toLowerCase()]; + if (!link2) { + const text2 = cap[0].charAt(0); + return { + type: "text", + raw: text2, + text: text2 + }; + } + return outputLink(cap, link2, cap[0], this.lexer); } } - if (vectorTile.layers.hasOwnProperty("sequence")) { - features2 = []; - cache = _mlyCache.sequences; - layer = vectorTile.layers.sequence; - for (i2 = 0; i2 < layer.length; i2++) { - feature3 = layer.feature(i2).toGeoJSON(tile.xyz[0], tile.xyz[1], tile.xyz[2]); - if (cache.lineString[feature3.properties.id]) { - cache.lineString[feature3.properties.id].push(feature3); - } else { - cache.lineString[feature3.properties.id] = [feature3]; + emStrong(src, maskedSrc, prevChar = "") { + let match = this.rules.inline.emStrong.lDelim.exec(src); + if (!match) + return; + if (match[3] && prevChar.match(/[\p{L}\p{N}]/u)) + return; + const nextChar = match[1] || match[2] || ""; + if (!nextChar || !prevChar || this.rules.inline.punctuation.exec(prevChar)) { + const lLength = match[0].length - 1; + let rDelim, rLength, delimTotal = lLength, midDelimTotal = 0; + const endReg = match[0][0] === "*" ? this.rules.inline.emStrong.rDelimAst : this.rules.inline.emStrong.rDelimUnd; + endReg.lastIndex = 0; + maskedSrc = maskedSrc.slice(-1 * src.length + lLength); + while ((match = endReg.exec(maskedSrc)) != null) { + rDelim = match[1] || match[2] || match[3] || match[4] || match[5] || match[6]; + if (!rDelim) + continue; + rLength = rDelim.length; + if (match[3] || match[4]) { + delimTotal += rLength; + continue; + } else if (match[5] || match[6]) { + if (lLength % 3 && !((lLength + rLength) % 3)) { + midDelimTotal += rLength; + continue; + } + } + delimTotal -= rLength; + if (delimTotal > 0) + continue; + rLength = Math.min(rLength, rLength + delimTotal + midDelimTotal); + const raw = src.slice(0, lLength + match.index + rLength + 1); + if (Math.min(lLength, rLength) % 2) { + const text3 = raw.slice(1, -1); + return { + type: "em", + raw, + text: text3, + tokens: this.lexer.inlineTokens(text3) + }; + } + const text2 = raw.slice(2, -2); + return { + type: "strong", + raw, + text: text2, + tokens: this.lexer.inlineTokens(text2) + }; } } } - if (vectorTile.layers.hasOwnProperty("point")) { - features2 = []; - cache = _mlyCache[which]; - layer = vectorTile.layers.point; - for (i2 = 0; i2 < layer.length; i2++) { - feature3 = layer.feature(i2).toGeoJSON(tile.xyz[0], tile.xyz[1], tile.xyz[2]); - loc = feature3.geometry.coordinates; - d = { - loc, - id: feature3.properties.id, - first_seen_at: feature3.properties.first_seen_at, - last_seen_at: feature3.properties.last_seen_at, - value: feature3.properties.value + codespan(src) { + const cap = this.rules.inline.code.exec(src); + if (cap) { + let text2 = cap[2].replace(/\n/g, " "); + const hasNonSpaceChars = /[^ ]/.test(text2); + const hasSpaceCharsOnBothEnds = /^ /.test(text2) && / $/.test(text2); + if (hasNonSpaceChars && hasSpaceCharsOnBothEnds) { + text2 = text2.substring(1, text2.length - 1); + } + text2 = escape4(text2, true); + return { + type: "codespan", + raw: cap[0], + text: text2 }; - features2.push({ - minX: loc[0], - minY: loc[1], - maxX: loc[0], - maxY: loc[1], - data: d - }); - } - if (cache.rtree) { - cache.rtree.load(features2); } } - if (vectorTile.layers.hasOwnProperty("traffic_sign")) { - features2 = []; - cache = _mlyCache[which]; - layer = vectorTile.layers.traffic_sign; - for (i2 = 0; i2 < layer.length; i2++) { - feature3 = layer.feature(i2).toGeoJSON(tile.xyz[0], tile.xyz[1], tile.xyz[2]); - loc = feature3.geometry.coordinates; - d = { - loc, - id: feature3.properties.id, - first_seen_at: feature3.properties.first_seen_at, - last_seen_at: feature3.properties.last_seen_at, - value: feature3.properties.value + br(src) { + const cap = this.rules.inline.br.exec(src); + if (cap) { + return { + type: "br", + raw: cap[0] }; - features2.push({ - minX: loc[0], - minY: loc[1], - maxX: loc[0], - maxY: loc[1], - data: d - }); - } - if (cache.rtree) { - cache.rtree.load(features2); } } - } - function loadData(url) { - return fetch(url).then(function(response) { - if (!response.ok) { - throw new Error(response.status + " " + response.statusText); - } - return response.json(); - }).then(function(result) { - if (!result) { - return []; - } - return result.data || []; - }); - } - function partitionViewport(projection2) { - const z = geoScaleToZoom(projection2.scale()); - const z2 = Math.ceil(z * 2) / 2 + 2.5; - const tiler8 = utilTiler().zoomExtent([z2, z2]); - return tiler8.getTiles(projection2).map(function(tile) { - return tile.extent; - }); - } - function searchLimited(limit, projection2, rtree) { - limit = limit || 5; - return partitionViewport(projection2).reduce(function(result, extent) { - const found = rtree.search(extent.bbox()).slice(0, limit).map(function(d) { - return d.data; - }); - return found.length ? result.concat(found) : result; - }, []); - } - var mapillary_default = { - init: function() { - if (!_mlyCache) { - this.reset(); - } - this.event = utilRebind(this, dispatch5, "on"); - }, - reset: function() { - if (_mlyCache) { - Object.values(_mlyCache.requests.inflight).forEach(function(request3) { - request3.abort(); - }); + del(src) { + const cap = this.rules.inline.del.exec(src); + if (cap) { + return { + type: "del", + raw: cap[0], + text: cap[2], + tokens: this.lexer.inlineTokens(cap[2]) + }; } - _mlyCache = { - images: { rtree: new import_rbush4.default(), forImageId: {} }, - image_detections: { forImageId: {} }, - signs: { rtree: new import_rbush4.default() }, - points: { rtree: new import_rbush4.default() }, - sequences: { rtree: new import_rbush4.default(), lineString: {} }, - requests: { loaded: {}, inflight: {} } - }; - _mlyActiveImage = null; - }, - images: function(projection2) { - const limit = 5; - return searchLimited(limit, projection2, _mlyCache.images.rtree); - }, - signs: function(projection2) { - const limit = 5; - return searchLimited(limit, projection2, _mlyCache.signs.rtree); - }, - mapFeatures: function(projection2) { - const limit = 5; - return searchLimited(limit, projection2, _mlyCache.points.rtree); - }, - cachedImage: function(imageId) { - return _mlyCache.images.forImageId[imageId]; - }, - sequences: function(projection2) { - const viewport = projection2.clipExtent(); - const min3 = [viewport[0][0], viewport[1][1]]; - const max3 = [viewport[1][0], viewport[0][1]]; - const bbox = geoExtent(projection2.invert(min3), projection2.invert(max3)).bbox(); - const sequenceIds = {}; - let lineStrings = []; - _mlyCache.images.rtree.search(bbox).forEach(function(d) { - if (d.data.sequence_id) { - sequenceIds[d.data.sequence_id] = true; - } - }); - Object.keys(sequenceIds).forEach(function(sequenceId) { - if (_mlyCache.sequences.lineString[sequenceId]) { - lineStrings = lineStrings.concat(_mlyCache.sequences.lineString[sequenceId]); - } - }); - return lineStrings; - }, - loadImages: function(projection2) { - loadTiles("images", tileUrl, 14, projection2); - }, - loadSigns: function(projection2) { - loadTiles("signs", trafficSignTileUrl, 14, projection2); - }, - loadMapFeatures: function(projection2) { - loadTiles("points", mapFeatureTileUrl, 14, projection2); - }, - ensureViewerLoaded: function(context) { - if (_loadViewerPromise) - return _loadViewerPromise; - const wrap2 = context.container().select(".photoviewer").selectAll(".mly-wrapper").data([0]); - wrap2.enter().append("div").attr("id", "ideditor-mly").attr("class", "photo-wrapper mly-wrapper").classed("hide", true); - const that = this; - _loadViewerPromise = new Promise((resolve, reject) => { - let loadedCount = 0; - function loaded() { - loadedCount += 1; - if (loadedCount === 2) - resolve(); + } + autolink(src, mangle2) { + const cap = this.rules.inline.autolink.exec(src); + if (cap) { + let text2, href; + if (cap[2] === "@") { + text2 = escape4(this.options.mangle ? mangle2(cap[1]) : cap[1]); + href = "mailto:" + text2; + } else { + text2 = escape4(cap[1]); + href = text2; } - const head = select_default2("head"); - head.selectAll("#ideditor-mapillary-viewercss").data([0]).enter().append("link").attr("id", "ideditor-mapillary-viewercss").attr("rel", "stylesheet").attr("crossorigin", "anonymous").attr("href", context.asset(viewercss)).on("load.serviceMapillary", loaded).on("error.serviceMapillary", function() { - reject(); - }); - head.selectAll("#ideditor-mapillary-viewerjs").data([0]).enter().append("script").attr("id", "ideditor-mapillary-viewerjs").attr("crossorigin", "anonymous").attr("src", context.asset(viewerjs)).on("load.serviceMapillary", loaded).on("error.serviceMapillary", function() { - reject(); - }); - }).catch(function() { - _loadViewerPromise = null; - }).then(function() { - that.initViewer(context); - }); - return _loadViewerPromise; - }, - loadSignResources: function(context) { - context.ui().svgDefs.addSprites(["mapillary-sprite"], false); - return this; - }, - loadObjectResources: function(context) { - context.ui().svgDefs.addSprites(["mapillary-object-sprite"], false); - return this; - }, - resetTags: function() { - if (_mlyViewer && !_mlyFallback) { - _mlyViewer.getComponent("tag").removeAll(); + return { + type: "link", + raw: cap[0], + text: text2, + href, + tokens: [ + { + type: "text", + raw: text2, + text: text2 + } + ] + }; } - }, - showFeatureDetections: function(value) { - _mlyShowFeatureDetections = value; - if (!_mlyShowFeatureDetections && !_mlyShowSignDetections) { - this.resetTags(); + } + url(src, mangle2) { + let cap; + if (cap = this.rules.inline.url.exec(src)) { + let text2, href; + if (cap[2] === "@") { + text2 = escape4(this.options.mangle ? mangle2(cap[0]) : cap[0]); + href = "mailto:" + text2; + } else { + let prevCapZero; + do { + prevCapZero = cap[0]; + cap[0] = this.rules.inline._backpedal.exec(cap[0])[0]; + } while (prevCapZero !== cap[0]); + text2 = escape4(cap[0]); + if (cap[1] === "www.") { + href = "http://" + cap[0]; + } else { + href = cap[0]; + } + } + return { + type: "link", + raw: cap[0], + text: text2, + href, + tokens: [ + { + type: "text", + raw: text2, + text: text2 + } + ] + }; } - }, - showSignDetections: function(value) { - _mlyShowSignDetections = value; - if (!_mlyShowFeatureDetections && !_mlyShowSignDetections) { - this.resetTags(); + } + inlineText(src, smartypants2) { + const cap = this.rules.inline.text.exec(src); + if (cap) { + let text2; + if (this.lexer.state.inRawBlock) { + text2 = this.options.sanitize ? this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape4(cap[0]) : cap[0]; + } else { + text2 = escape4(this.options.smartypants ? smartypants2(cap[0]) : cap[0]); + } + return { + type: "text", + raw: cap[0], + text: text2 + }; } + } + }; + var block = { + newline: /^(?: *(?:\n|$))+/, + code: /^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/, + fences: /^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/, + hr: /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/, + heading: /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/, + blockquote: /^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/, + list: /^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/, + html: "^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|\\n*|$)|\\n*|$)|)[\\s\\S]*?(?:(?:\\n *)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)|(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$))", + def: /^ {0,3}\[(label)\]: *(?:\n *)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n *)?| *\n *)(title))? *(?:\n+|$)/, + table: noopTest, + lheading: /^((?:(?!^bull ).|\n(?!\n|bull ))+?)\n {0,3}(=+|-+) *(?:\n+|$)/, + // regex template, placeholders will be replaced according to different paragraph + // interruption rules of commonmark and the original markdown spec: + _paragraph: /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/, + text: /^[^\n]+/ + }; + block._label = /(?!\s*\])(?:\\.|[^\[\]\\])+/; + block._title = /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/; + block.def = edit(block.def).replace("label", block._label).replace("title", block._title).getRegex(); + block.bullet = /(?:[*+-]|\d{1,9}[.)])/; + block.listItemStart = edit(/^( *)(bull) */).replace("bull", block.bullet).getRegex(); + block.list = edit(block.list).replace(/bull/g, block.bullet).replace("hr", "\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))").replace("def", "\\n+(?=" + block.def.source + ")").getRegex(); + block._tag = "address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul"; + block._comment = /|$)/; + block.html = edit(block.html, "i").replace("comment", block._comment).replace("tag", block._tag).replace("attribute", / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(); + block.lheading = edit(block.lheading).replace(/bull/g, block.bullet).getRegex(); + block.paragraph = edit(block._paragraph).replace("hr", block.hr).replace("heading", " {0,3}#{1,6} ").replace("|lheading", "").replace("|table", "").replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", ")|<(?:script|pre|style|textarea|!--)").replace("tag", block._tag).getRegex(); + block.blockquote = edit(block.blockquote).replace("paragraph", block.paragraph).getRegex(); + block.normal = { ...block }; + block.gfm = { + ...block.normal, + table: "^ *([^\\n ].*\\|.*)\\n {0,3}(?:\\| *)?(:?-+:? *(?:\\| *:?-+:? *)*)(?:\\| *)?(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)" + // Cells + }; + block.gfm.table = edit(block.gfm.table).replace("hr", block.hr).replace("heading", " {0,3}#{1,6} ").replace("blockquote", " {0,3}>").replace("code", " {4}[^\\n]").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", ")|<(?:script|pre|style|textarea|!--)").replace("tag", block._tag).getRegex(); + block.gfm.paragraph = edit(block._paragraph).replace("hr", block.hr).replace("heading", " {0,3}#{1,6} ").replace("|lheading", "").replace("table", block.gfm.table).replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", ")|<(?:script|pre|style|textarea|!--)").replace("tag", block._tag).getRegex(); + block.pedantic = { + ...block.normal, + html: edit( + `^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+? *(?:\\n{2,}|\\s*$)|\\s]*)*?/?> *(?:\\n{2,}|\\s*$))` + ).replace("comment", block._comment).replace(/tag/g, "(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(), + def: /^ *\[([^\]]+)\]: *]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/, + heading: /^(#{1,6})(.*)(?:\n+|$)/, + fences: noopTest, + // fences not supported + lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/, + paragraph: edit(block.normal._paragraph).replace("hr", block.hr).replace("heading", " *#{1,6} *[^\n]").replace("lheading", block.lheading).replace("blockquote", " {0,3}>").replace("|fences", "").replace("|list", "").replace("|html", "").getRegex() + }; + var inline = { + escape: /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/, + autolink: /^<(scheme:[^\s\x00-\x1f<>]*|email)>/, + url: noopTest, + tag: "^comment|^|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^|^", + // CDATA section + link: /^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/, + reflink: /^!?\[(label)\]\[(ref)\]/, + nolink: /^!?\[(ref)\](?:\[\])?/, + reflinkSearch: "reflink|nolink(?!\\()", + emStrong: { + lDelim: /^(?:\*+(?:((?!\*)[punct])|[^\s*]))|^_+(?:((?!_)[punct])|([^\s_]))/, + // (1) and (2) can only be a Right Delimiter. (3) and (4) can only be Left. (5) and (6) can be either Left or Right. + // | Skip orphan inside strong | Consume to delim | (1) #*** | (2) a***#, a*** | (3) #***a, ***a | (4) ***# | (5) #***# | (6) a***a + rDelimAst: /^[^_*]*?__[^_*]*?\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\*)[punct](\*+)(?=[\s]|$)|[^punct\s](\*+)(?!\*)(?=[punct\s]|$)|(?!\*)[punct\s](\*+)(?=[^punct\s])|[\s](\*+)(?!\*)(?=[punct])|(?!\*)[punct](\*+)(?!\*)(?=[punct])|[^punct\s](\*+)(?=[^punct\s])/, + rDelimUnd: /^[^_*]*?\*\*[^_*]*?_[^_*]*?(?=\*\*)|[^_]+(?=[^_])|(?!_)[punct](_+)(?=[\s]|$)|[^punct\s](_+)(?!_)(?=[punct\s]|$)|(?!_)[punct\s](_+)(?=[^punct\s])|[\s](_+)(?!_)(?=[punct])|(?!_)[punct](_+)(?!_)(?=[punct])/ + // ^- Not allowed for _ }, - filterViewer: function(context) { - const showsPano = context.photos().showsPanoramic(); - const showsFlat = context.photos().showsFlat(); - const fromDate = context.photos().fromDate(); - const toDate = context.photos().toDate(); - const filter2 = ["all"]; - if (!showsPano) - filter2.push(["!=", "cameraType", "spherical"]); - if (!showsFlat && showsPano) - filter2.push(["==", "pano", true]); - if (fromDate) { - filter2.push([">=", "capturedAt", new Date(fromDate).getTime()]); - } - if (toDate) { - filter2.push([">=", "capturedAt", new Date(toDate).getTime()]); - } - if (_mlyViewer) { - _mlyViewer.setFilter(filter2); - } - _mlyViewerFilter = filter2; - return filter2; + code: /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/, + br: /^( {2,}|\\)\n(?!\s*$)/, + del: noopTest, + text: /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\`^|~"; + inline.punctuation = edit(inline.punctuation, "u").replace(/punctuation/g, inline._punctuation).getRegex(); + inline.blockSkip = /\[[^[\]]*?\]\([^\(\)]*?\)|`[^`]*?`|<[^<>]*?>/g; + inline.anyPunctuation = /\\[punct]/g; + inline._escapes = /\\([punct])/g; + inline._comment = edit(block._comment).replace("(?:-->|$)", "-->").getRegex(); + inline.emStrong.lDelim = edit(inline.emStrong.lDelim, "u").replace(/punct/g, inline._punctuation).getRegex(); + inline.emStrong.rDelimAst = edit(inline.emStrong.rDelimAst, "gu").replace(/punct/g, inline._punctuation).getRegex(); + inline.emStrong.rDelimUnd = edit(inline.emStrong.rDelimUnd, "gu").replace(/punct/g, inline._punctuation).getRegex(); + inline.anyPunctuation = edit(inline.anyPunctuation, "gu").replace(/punct/g, inline._punctuation).getRegex(); + inline._escapes = edit(inline._escapes, "gu").replace(/punct/g, inline._punctuation).getRegex(); + inline._scheme = /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/; + inline._email = /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/; + inline.autolink = edit(inline.autolink).replace("scheme", inline._scheme).replace("email", inline._email).getRegex(); + inline._attribute = /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/; + inline.tag = edit(inline.tag).replace("comment", inline._comment).replace("attribute", inline._attribute).getRegex(); + inline._label = /(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/; + inline._href = /<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/; + inline._title = /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/; + inline.link = edit(inline.link).replace("label", inline._label).replace("href", inline._href).replace("title", inline._title).getRegex(); + inline.reflink = edit(inline.reflink).replace("label", inline._label).replace("ref", block._label).getRegex(); + inline.nolink = edit(inline.nolink).replace("ref", block._label).getRegex(); + inline.reflinkSearch = edit(inline.reflinkSearch, "g").replace("reflink", inline.reflink).replace("nolink", inline.nolink).getRegex(); + inline.normal = { ...inline }; + inline.pedantic = { + ...inline.normal, + strong: { + start: /^__|\*\*/, + middle: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/, + endAst: /\*\*(?!\*)/g, + endUnd: /__(?!_)/g }, - showViewer: function(context) { - const wrap2 = context.container().select(".photoviewer").classed("hide", false); - const isHidden = wrap2.selectAll(".photo-wrapper.mly-wrapper.hide").size(); - if (isHidden && _mlyViewer) { - wrap2.selectAll(".photo-wrapper:not(.mly-wrapper)").classed("hide", true); - wrap2.selectAll(".photo-wrapper.mly-wrapper").classed("hide", false); - _mlyViewer.resize(); - } - return this; + em: { + start: /^_|\*/, + middle: /^()\*(?=\S)([\s\S]*?\S)\*(?!\*)|^_(?=\S)([\s\S]*?\S)_(?!_)/, + endAst: /\*(?!\*)/g, + endUnd: /_(?!_)/g }, - hideViewer: function(context) { - _mlyActiveImage = null; - if (!_mlyFallback && _mlyViewer) { - _mlyViewer.getComponent("sequence").stop(); + link: edit(/^!?\[(label)\]\((.*?)\)/).replace("label", inline._label).getRegex(), + reflink: edit(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label", inline._label).getRegex() + }; + inline.gfm = { + ...inline.normal, + escape: edit(inline.escape).replace("])", "~|])").getRegex(), + _extended_email: /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/, + url: /^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/, + _backpedal: /(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/, + del: /^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/, + text: /^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\ 0.5) { + ch = "x" + ch.toString(16); } - const viewer = context.container().select(".photoviewer"); - if (!viewer.empty()) - viewer.datum(null); - viewer.classed("hide", true).selectAll(".photo-wrapper").classed("hide", true); - this.updateUrlImage(null); - dispatch5.call("imageChanged"); - dispatch5.call("loadedMapFeatures"); - dispatch5.call("loadedSigns"); - return this.setStyles(context, null); - }, - updateUrlImage: function(imageId) { - if (!window.mocha) { - const hash = utilStringQs(window.location.hash); - if (imageId) { - hash.photo = "mapillary/" + imageId; + out += "&#" + ch + ";"; + } + return out; + } + var Lexer = class _Lexer { + constructor(options2) { + this.tokens = []; + this.tokens.links = /* @__PURE__ */ Object.create(null); + this.options = options2 || defaults; + this.options.tokenizer = this.options.tokenizer || new Tokenizer(); + this.tokenizer = this.options.tokenizer; + this.tokenizer.options = this.options; + this.tokenizer.lexer = this; + this.inlineQueue = []; + this.state = { + inLink: false, + inRawBlock: false, + top: true + }; + const rules = { + block: block.normal, + inline: inline.normal + }; + if (this.options.pedantic) { + rules.block = block.pedantic; + rules.inline = inline.pedantic; + } else if (this.options.gfm) { + rules.block = block.gfm; + if (this.options.breaks) { + rules.inline = inline.breaks; } else { - delete hash.photo; + rules.inline = inline.gfm; } - window.location.replace("#" + utilQsString(hash, true)); - } - }, - highlightDetection: function(detection) { - if (detection) { - _mlyHighlightedDetection = detection.id; } - return this; - }, - initViewer: function(context) { - const that = this; - if (!window.mapillary) - return; - const opts = { - accessToken, - component: { - cover: false, - keyboard: false, - tag: true - }, - container: "ideditor-mly" + this.tokenizer.rules = rules; + } + /** + * Expose Rules + */ + static get rules() { + return { + block, + inline }; - if (!mapillary.isSupported() && mapillary.isFallbackSupported()) { - _mlyFallback = true; - opts.component = { - cover: false, - direction: false, - imagePlane: false, - keyboard: false, - mouse: false, - sequence: false, - tag: false, - image: true, - navigation: true - }; - } - _mlyViewer = new mapillary.Viewer(opts); - _mlyViewer.on("image", imageChanged); - _mlyViewer.on("bearing", bearingChanged); - if (_mlyViewerFilter) { - _mlyViewer.setFilter(_mlyViewerFilter); - } - context.ui().photoviewer.on("resize.mapillary", function() { - if (_mlyViewer) - _mlyViewer.resize(); - }); - function imageChanged(node) { - that.resetTags(); - const image = node.image; - that.setActiveImage(image); - that.setStyles(context, null); - const loc = [image.originalLngLat.lng, image.originalLngLat.lat]; - context.map().centerEase(loc); - that.updateUrlImage(image.id); - if (_mlyShowFeatureDetections || _mlyShowSignDetections) { - that.updateDetections(image.id, `${apiUrl}/${image.id}/detections?access_token=${accessToken}&fields=id,image,geometry,value`); - } - dispatch5.call("imageChanged"); - } - function bearingChanged(e) { - dispatch5.call("bearingChanged", void 0, e); - } - }, - selectImage: function(context, imageId) { - if (_mlyViewer && imageId) { - _mlyViewer.moveTo(imageId).catch(function(e) { - console.error("mly3", e); - }); + } + /** + * Static Lex Method + */ + static lex(src, options2) { + const lexer2 = new _Lexer(options2); + return lexer2.lex(src); + } + /** + * Static Lex Inline Method + */ + static lexInline(src, options2) { + const lexer2 = new _Lexer(options2); + return lexer2.inlineTokens(src); + } + /** + * Preprocessing + */ + lex(src) { + src = src.replace(/\r\n|\r/g, "\n"); + this.blockTokens(src, this.tokens); + let next; + while (next = this.inlineQueue.shift()) { + this.inlineTokens(next.src, next.tokens); } - return this; - }, - getActiveImage: function() { - return _mlyActiveImage; - }, - getDetections: function(id2) { - return loadData(`${apiUrl}/${id2}/detections?access_token=${accessToken}&fields=id,value,image`); - }, - setActiveImage: function(image) { - if (image) { - _mlyActiveImage = { - ca: image.originalCompassAngle, - id: image.id, - loc: [image.originalLngLat.lng, image.originalLngLat.lat], - is_pano: image.cameraType === "spherical", - sequence_id: image.sequenceId - }; + return this.tokens; + } + /** + * Lexing + */ + blockTokens(src, tokens = []) { + if (this.options.pedantic) { + src = src.replace(/\t/g, " ").replace(/^ +$/gm, ""); } else { - _mlyActiveImage = null; + src = src.replace(/^( *)(\t+)/gm, (_, leading, tabs) => { + return leading + " ".repeat(tabs.length); + }); } - }, - setStyles: function(context, hovered) { - const hoveredImageId = hovered && hovered.id; - const hoveredSequenceId = hovered && hovered.sequence_id; - const selectedSequenceId = _mlyActiveImage && _mlyActiveImage.sequence_id; - context.container().selectAll(".layer-mapillary .viewfield-group").classed("highlighted", function(d) { - return d.sequence_id === selectedSequenceId || d.id === hoveredImageId; - }).classed("hovered", function(d) { - return d.id === hoveredImageId; - }); - context.container().selectAll(".layer-mapillary .sequence").classed("highlighted", function(d) { - return d.properties.id === hoveredSequenceId; - }).classed("currentView", function(d) { - return d.properties.id === selectedSequenceId; - }); - return this; - }, - updateDetections: function(imageId, url) { - if (!_mlyViewer || _mlyFallback) - return; - if (!imageId) - return; - const cache = _mlyCache.image_detections; - if (cache.forImageId[imageId]) { - showDetections(_mlyCache.image_detections.forImageId[imageId]); - } else { - loadData(url).then((detections) => { - detections.forEach(function(detection) { - if (!cache.forImageId[imageId]) { - cache.forImageId[imageId] = []; + let token, lastToken, cutSrc, lastParagraphClipped; + while (src) { + if (this.options.extensions && this.options.extensions.block && this.options.extensions.block.some((extTokenizer) => { + if (token = extTokenizer.call({ lexer: this }, src, tokens)) { + src = src.substring(token.raw.length); + tokens.push(token); + return true; + } + return false; + })) { + continue; + } + if (token = this.tokenizer.space(src)) { + src = src.substring(token.raw.length); + if (token.raw.length === 1 && tokens.length > 0) { + tokens[tokens.length - 1].raw += "\n"; + } else { + tokens.push(token); + } + continue; + } + if (token = this.tokenizer.code(src)) { + src = src.substring(token.raw.length); + lastToken = tokens[tokens.length - 1]; + if (lastToken && (lastToken.type === "paragraph" || lastToken.type === "text")) { + lastToken.raw += "\n" + token.raw; + lastToken.text += "\n" + token.text; + this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text; + } else { + tokens.push(token); + } + continue; + } + if (token = this.tokenizer.fences(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + if (token = this.tokenizer.heading(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + if (token = this.tokenizer.hr(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + if (token = this.tokenizer.blockquote(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + if (token = this.tokenizer.list(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + if (token = this.tokenizer.html(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + if (token = this.tokenizer.def(src)) { + src = src.substring(token.raw.length); + lastToken = tokens[tokens.length - 1]; + if (lastToken && (lastToken.type === "paragraph" || lastToken.type === "text")) { + lastToken.raw += "\n" + token.raw; + lastToken.text += "\n" + token.raw; + this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text; + } else if (!this.tokens.links[token.tag]) { + this.tokens.links[token.tag] = { + href: token.href, + title: token.title + }; + } + continue; + } + if (token = this.tokenizer.table(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + if (token = this.tokenizer.lheading(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; + } + cutSrc = src; + if (this.options.extensions && this.options.extensions.startBlock) { + let startIndex = Infinity; + const tempSrc = src.slice(1); + let tempStart; + this.options.extensions.startBlock.forEach(function(getStartIndex) { + tempStart = getStartIndex.call({ lexer: this }, tempSrc); + if (typeof tempStart === "number" && tempStart >= 0) { + startIndex = Math.min(startIndex, tempStart); } - cache.forImageId[imageId].push({ - geometry: detection.geometry, - id: detection.id, - image_id: imageId, - value: detection.value - }); }); - showDetections(_mlyCache.image_detections.forImageId[imageId] || []); - }); - } - function showDetections(detections) { - const tagComponent = _mlyViewer.getComponent("tag"); - detections.forEach(function(data) { - const tag = makeTag(data); - if (tag) { - tagComponent.add([tag]); + if (startIndex < Infinity && startIndex >= 0) { + cutSrc = src.substring(0, startIndex + 1); } - }); - } - function makeTag(data) { - const valueParts = data.value.split("--"); - if (!valueParts.length) - return; - let tag; - let text2; - let color2 = 16777215; - if (_mlyHighlightedDetection === data.id) { - color2 = 16776960; - text2 = valueParts[1]; - if (text2 === "flat" || text2 === "discrete" || text2 === "sign") { - text2 = valueParts[2]; + } + if (this.state.top && (token = this.tokenizer.paragraph(cutSrc))) { + lastToken = tokens[tokens.length - 1]; + if (lastParagraphClipped && lastToken.type === "paragraph") { + lastToken.raw += "\n" + token.raw; + lastToken.text += "\n" + token.text; + this.inlineQueue.pop(); + this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text; + } else { + tokens.push(token); } - text2 = text2.replace(/-/g, " "); - text2 = text2.charAt(0).toUpperCase() + text2.slice(1); - _mlyHighlightedDetection = null; + lastParagraphClipped = cutSrc.length !== src.length; + src = src.substring(token.raw.length); + continue; } - var decodedGeometry = window.atob(data.geometry); - var uintArray = new Uint8Array(decodedGeometry.length); - for (var i2 = 0; i2 < decodedGeometry.length; i2++) { - uintArray[i2] = decodedGeometry.charCodeAt(i2); + if (token = this.tokenizer.text(src)) { + src = src.substring(token.raw.length); + lastToken = tokens[tokens.length - 1]; + if (lastToken && lastToken.type === "text") { + lastToken.raw += "\n" + token.raw; + lastToken.text += "\n" + token.text; + this.inlineQueue.pop(); + this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text; + } else { + tokens.push(token); + } + continue; } - const tile = new import_vector_tile.VectorTile(new import_pbf.default(uintArray.buffer)); - const layer = tile.layers["mpy-or"]; - const geometries = layer.feature(0).loadGeometry(); - const polygon2 = geometries.map((ring) => ring.map((point) => [point.x / layer.extent, point.y / layer.extent])); - tag = new mapillary.OutlineTag( - data.id, - new mapillary.PolygonGeometry(polygon2[0]), - { - text: text2, - textColor: color2, - lineColor: color2, - lineWidth: 2, - fillColor: color2, - fillOpacity: 0.3 + if (src) { + const errMsg = "Infinite loop on byte: " + src.charCodeAt(0); + if (this.options.silent) { + console.error(errMsg); + break; + } else { + throw new Error(errMsg); } - ); - return tag; - } - }, - cache: function() { - return _mlyCache; - } - }; - - // modules/core/validation/models.js - function validationIssue(attrs) { - this.type = attrs.type; - this.subtype = attrs.subtype; - this.severity = attrs.severity; - this.message = attrs.message; - this.reference = attrs.reference; - this.entityIds = attrs.entityIds; - this.loc = attrs.loc; - this.data = attrs.data; - this.dynamicFixes = attrs.dynamicFixes; - this.hash = attrs.hash; - this.id = generateID.apply(this); - this.key = generateKey.apply(this); - this.autoFix = null; - function generateID() { - var parts = [this.type]; - if (this.hash) { - parts.push(this.hash); - } - if (this.subtype) { - parts.push(this.subtype); - } - if (this.entityIds) { - var entityKeys = this.entityIds.slice().sort(); - parts.push.apply(parts, entityKeys); + } } - return parts.join(":"); + this.state.top = true; + return tokens; } - function generateKey() { - return this.id + ":" + Date.now().toString(); + inline(src, tokens = []) { + this.inlineQueue.push({ src, tokens }); + return tokens; } - this.extent = function(resolver) { - if (this.loc) { - return geoExtent(this.loc); - } - if (this.entityIds && this.entityIds.length) { - return this.entityIds.reduce(function(extent, entityId) { - return extent.extend(resolver.entity(entityId).extent(resolver)); - }, geoExtent()); - } - return null; - }; - this.fixes = function(context) { - var fixes = this.dynamicFixes ? this.dynamicFixes(context) : []; - var issue = this; - if (issue.severity === "warning") { - fixes.push(new validationIssueFix({ - title: _t.append("issues.fix.ignore_issue.title"), - icon: "iD-icon-close", - onClick: function() { - context.validator().ignoreIssue(this.issue.id); + /** + * Lexing/Compiling + */ + inlineTokens(src, tokens = []) { + let token, lastToken, cutSrc; + let maskedSrc = src; + let match; + let keepPrevChar, prevChar; + if (this.tokens.links) { + const links = Object.keys(this.tokens.links); + if (links.length > 0) { + while ((match = this.tokenizer.rules.inline.reflinkSearch.exec(maskedSrc)) != null) { + if (links.includes(match[0].slice(match[0].lastIndexOf("[") + 1, -1))) { + maskedSrc = maskedSrc.slice(0, match.index) + "[" + "a".repeat(match[0].length - 2) + "]" + maskedSrc.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex); + } } - })); - } - fixes.forEach(function(fix) { - fix.id = fix.title.stringId; - fix.issue = issue; - if (fix.autoArgs) { - issue.autoFix = fix; } - }); - return fixes; - }; - } - function validationIssueFix(attrs) { - this.title = attrs.title; - this.onClick = attrs.onClick; - this.disabledReason = attrs.disabledReason; - this.icon = attrs.icon; - this.entityIds = attrs.entityIds || []; - this.autoArgs = attrs.autoArgs; - this.issue = null; - } - - // modules/services/maprules.js - var buildRuleChecks = function() { - return { - equals: function(equals) { - return function(tags) { - return Object.keys(equals).every(function(k) { - return equals[k] === tags[k]; - }); - }; - }, - notEquals: function(notEquals) { - return function(tags) { - return Object.keys(notEquals).some(function(k) { - return notEquals[k] !== tags[k]; - }); - }; - }, - absence: function(absence) { - return function(tags) { - return Object.keys(tags).indexOf(absence) === -1; - }; - }, - presence: function(presence) { - return function(tags) { - return Object.keys(tags).indexOf(presence) > -1; - }; - }, - greaterThan: function(greaterThan) { - var key = Object.keys(greaterThan)[0]; - var value = greaterThan[key]; - return function(tags) { - return tags[key] > value; - }; - }, - greaterThanEqual: function(greaterThanEqual) { - var key = Object.keys(greaterThanEqual)[0]; - var value = greaterThanEqual[key]; - return function(tags) { - return tags[key] >= value; - }; - }, - lessThan: function(lessThan) { - var key = Object.keys(lessThan)[0]; - var value = lessThan[key]; - return function(tags) { - return tags[key] < value; - }; - }, - lessThanEqual: function(lessThanEqual) { - var key = Object.keys(lessThanEqual)[0]; - var value = lessThanEqual[key]; - return function(tags) { - return tags[key] <= value; - }; - }, - positiveRegex: function(positiveRegex) { - var tagKey = Object.keys(positiveRegex)[0]; - var expression = positiveRegex[tagKey].join("|"); - var regex = new RegExp(expression); - return function(tags) { - return regex.test(tags[tagKey]); - }; - }, - negativeRegex: function(negativeRegex) { - var tagKey = Object.keys(negativeRegex)[0]; - var expression = negativeRegex[tagKey].join("|"); - var regex = new RegExp(expression); - return function(tags) { - return !regex.test(tags[tagKey]); - }; } - }; - }; - var buildLineKeys = function() { - return { - highway: { - rest_area: true, - services: true - }, - railway: { - roundhouse: true, - station: true, - traverser: true, - turntable: true, - wash: true + while ((match = this.tokenizer.rules.inline.blockSkip.exec(maskedSrc)) != null) { + maskedSrc = maskedSrc.slice(0, match.index) + "[" + "a".repeat(match[0].length - 2) + "]" + maskedSrc.slice(this.tokenizer.rules.inline.blockSkip.lastIndex); } - }; - }; - var maprules_default = { - init: function() { - this._ruleChecks = buildRuleChecks(); - this._validationRules = []; - this._areaKeys = osmAreaKeys; - this._lineKeys = buildLineKeys(); - }, - filterRuleChecks: function(selector) { - var _ruleChecks = this._ruleChecks; - return Object.keys(selector).reduce(function(rules, key) { - if (["geometry", "error", "warning"].indexOf(key) === -1) { - rules.push(_ruleChecks[key](selector[key])); + while ((match = this.tokenizer.rules.inline.anyPunctuation.exec(maskedSrc)) != null) { + maskedSrc = maskedSrc.slice(0, match.index) + "++" + maskedSrc.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex); + } + while (src) { + if (!keepPrevChar) { + prevChar = ""; } - return rules; - }, []); - }, - buildTagMap: function(selector) { - var getRegexValues = function(regexes) { - return regexes.map(function(regex) { - return regex.replace(/\$|\^/g, ""); - }); - }; - var tagMap = Object.keys(selector).reduce(function(expectedTags, key) { - var values; - var isRegex = /regex/gi.test(key); - var isEqual = /equals/gi.test(key); - if (isRegex || isEqual) { - Object.keys(selector[key]).forEach(function(selectorKey) { - values = isEqual ? [selector[key][selectorKey]] : getRegexValues(selector[key][selectorKey]); - if (expectedTags.hasOwnProperty(selectorKey)) { - values = values.concat(expectedTags[selectorKey]); - } - expectedTags[selectorKey] = values; - }); - } else if (/(greater|less)Than(Equal)?|presence/g.test(key)) { - var tagKey = /presence/.test(key) ? selector[key] : Object.keys(selector[key])[0]; - values = [selector[key][tagKey]]; - if (expectedTags.hasOwnProperty(tagKey)) { - values = values.concat(expectedTags[tagKey]); + keepPrevChar = false; + if (this.options.extensions && this.options.extensions.inline && this.options.extensions.inline.some((extTokenizer) => { + if (token = extTokenizer.call({ lexer: this }, src, tokens)) { + src = src.substring(token.raw.length); + tokens.push(token); + return true; } - expectedTags[tagKey] = values; - } - return expectedTags; - }, {}); - return tagMap; - }, - inferGeometry: function(tagMap) { - var _lineKeys = this._lineKeys; - var _areaKeys = this._areaKeys; - var keyValueDoesNotImplyArea = function(key2) { - return utilArrayIntersection(tagMap[key2], Object.keys(_areaKeys[key2])).length > 0; - }; - var keyValueImpliesLine = function(key2) { - return utilArrayIntersection(tagMap[key2], Object.keys(_lineKeys[key2])).length > 0; - }; - if (tagMap.hasOwnProperty("area")) { - if (tagMap.area.indexOf("yes") > -1) { - return "area"; + return false; + })) { + continue; } - if (tagMap.area.indexOf("no") > -1) { - return "line"; + if (token = this.tokenizer.escape(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; } - } - for (var key in tagMap) { - if (key in _areaKeys && !keyValueDoesNotImplyArea(key)) { - return "area"; + if (token = this.tokenizer.tag(src)) { + src = src.substring(token.raw.length); + lastToken = tokens[tokens.length - 1]; + if (lastToken && token.type === "text" && lastToken.type === "text") { + lastToken.raw += token.raw; + lastToken.text += token.text; + } else { + tokens.push(token); + } + continue; } - if (key in _lineKeys && keyValueImpliesLine(key)) { - return "area"; + if (token = this.tokenizer.link(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; } - } - return "line"; - }, - addRule: function(selector) { - var rule = { - checks: this.filterRuleChecks(selector), - matches: function(entity) { - return this.checks.every(function(check) { - return check(entity.tags); - }); - }, - inferredGeometry: this.inferGeometry(this.buildTagMap(selector), this._areaKeys), - geometryMatches: function(entity, graph) { - if (entity.type === "node" || entity.type === "relation") { - return selector.geometry === entity.type; - } else if (entity.type === "way") { - return this.inferredGeometry === entity.geometry(graph); - } - }, - findIssues: function(entity, graph, issues) { - if (this.geometryMatches(entity, graph) && this.matches(entity)) { - var severity = Object.keys(selector).indexOf("error") > -1 ? "error" : "warning"; - var message = selector[severity]; - issues.push(new validationIssue({ - type: "maprules", - severity, - message: function() { - return message; - }, - entityIds: [entity.id] - })); + if (token = this.tokenizer.reflink(src, this.tokens.links)) { + src = src.substring(token.raw.length); + lastToken = tokens[tokens.length - 1]; + if (lastToken && token.type === "text" && lastToken.type === "text") { + lastToken.raw += token.raw; + lastToken.text += token.text; + } else { + tokens.push(token); } + continue; } - }; - this._validationRules.push(rule); - }, - clearRules: function() { - this._validationRules = []; - }, - validationRules: function() { - return this._validationRules; - }, - ruleChecks: function() { - return this._ruleChecks; - } - }; - - // modules/services/nominatim.js - var import_rbush5 = __toESM(require_rbush_min()); - var apibase = "https://nominatim.openstreetmap.org/"; - var _inflight = {}; - var _nominatimCache; - var nominatim_default = { - init: function() { - _inflight = {}; - _nominatimCache = new import_rbush5.default(); - }, - reset: function() { - Object.values(_inflight).forEach(function(controller) { - controller.abort(); - }); - _inflight = {}; - _nominatimCache = new import_rbush5.default(); - }, - countryCode: function(location, callback) { - this.reverse(location, function(err, result) { - if (err) { - return callback(err); - } else if (result.address) { - return callback(null, result.address.country_code); - } else { - return callback("Unable to geocode", null); + if (token = this.tokenizer.emStrong(src, maskedSrc, prevChar)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; } - }); - }, - reverse: function(loc, callback) { - var cached = _nominatimCache.search( - { minX: loc[0], minY: loc[1], maxX: loc[0], maxY: loc[1] } - ); - if (cached.length > 0) { - if (callback) - callback(null, cached[0].data); - return; - } - var params = { zoom: 13, format: "json", addressdetails: 1, lat: loc[1], lon: loc[0] }; - var url = apibase + "reverse?" + utilQsString(params); - if (_inflight[url]) - return; - var controller = new AbortController(); - _inflight[url] = controller; - json_default(url, { signal: controller.signal }).then(function(result) { - delete _inflight[url]; - if (result && result.error) { - throw new Error(result.error); + if (token = this.tokenizer.codespan(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; } - var extent = geoExtent(loc).padByMeters(200); - _nominatimCache.insert(Object.assign(extent.bbox(), { data: result })); - if (callback) - callback(null, result); - }).catch(function(err) { - delete _inflight[url]; - if (err.name === "AbortError") - return; - if (callback) - callback(err.message); - }); - }, - search: function(val, callback) { - var searchVal = encodeURIComponent(val); - var url = apibase + "search/" + searchVal + "?limit=10&format=json"; - if (_inflight[url]) - return; - var controller = new AbortController(); - _inflight[url] = controller; - json_default(url, { signal: controller.signal }).then(function(result) { - delete _inflight[url]; - if (result && result.error) { - throw new Error(result.error); + if (token = this.tokenizer.br(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; } - if (callback) - callback(null, result); - }).catch(function(err) { - delete _inflight[url]; - if (err.name === "AbortError") - return; - if (callback) - callback(err.message); - }); - } - }; - - // node_modules/name-suggestion-index/lib/matcher.js - var import_which_polygon3 = __toESM(require_which_polygon(), 1); - - // node_modules/name-suggestion-index/lib/simplify.js - var import_diacritics2 = __toESM(require_diacritics(), 1); - function simplify(str2) { - if (typeof str2 !== "string") - return ""; - return import_diacritics2.default.remove( - str2.replace(/&/g, "and").replace(/İ/ig, "i").replace(/[\s\-=_!"#%'*{},.\/:;?\(\)\[\]@\\$\^*+<>«»~`’\u00a1\u00a7\u00b6\u00b7\u00bf\u037e\u0387\u055a-\u055f\u0589\u05c0\u05c3\u05c6\u05f3\u05f4\u0609\u060a\u060c\u060d\u061b\u061e\u061f\u066a-\u066d\u06d4\u0700-\u070d\u07f7-\u07f9\u0830-\u083e\u085e\u0964\u0965\u0970\u0af0\u0df4\u0e4f\u0e5a\u0e5b\u0f04-\u0f12\u0f14\u0f85\u0fd0-\u0fd4\u0fd9\u0fda\u104a-\u104f\u10fb\u1360-\u1368\u166d\u166e\u16eb-\u16ed\u1735\u1736\u17d4-\u17d6\u17d8-\u17da\u1800-\u1805\u1807-\u180a\u1944\u1945\u1a1e\u1a1f\u1aa0-\u1aa6\u1aa8-\u1aad\u1b5a-\u1b60\u1bfc-\u1bff\u1c3b-\u1c3f\u1c7e\u1c7f\u1cc0-\u1cc7\u1cd3\u2000-\u206f\u2cf9-\u2cfc\u2cfe\u2cff\u2d70\u2e00-\u2e7f\u3001-\u3003\u303d\u30fb\ua4fe\ua4ff\ua60d-\ua60f\ua673\ua67e\ua6f2-\ua6f7\ua874-\ua877\ua8ce\ua8cf\ua8f8-\ua8fa\ua92e\ua92f\ua95f\ua9c1-\ua9cd\ua9de\ua9df\uaa5c-\uaa5f\uaade\uaadf\uaaf0\uaaf1\uabeb\ufe10-\ufe16\ufe19\ufe30\ufe45\ufe46\ufe49-\ufe4c\ufe50-\ufe52\ufe54-\ufe57\ufe5f-\ufe61\ufe68\ufe6a\ufe6b\ufeff\uff01-\uff03\uff05-\uff07\uff0a\uff0c\uff0e\uff0f\uff1a\uff1b\uff1f\uff20\uff3c\uff61\uff64\uff65]+/g, "").toLowerCase() - ); - } - - // node_modules/name-suggestion-index/config/matchGroups.json - var matchGroups_default = { - matchGroups: { - adult_gaming_centre: [ - "amenity/casino", - "amenity/gambling", - "leisure/adult_gaming_centre" - ], - beauty: [ - "shop/beauty", - "shop/hairdresser_supply" - ], - bed: [ - "shop/bed", - "shop/furniture" - ], - beverages: [ - "shop/alcohol", - "shop/beer", - "shop/beverages", - "shop/kiosk", - "shop/wine" - ], - camping: [ - "tourism/camp_site", - "tourism/caravan_site" - ], - car_parts: [ - "shop/car_parts", - "shop/car_repair", - "shop/tires", - "shop/tyres" - ], - clinic: [ - "amenity/clinic", - "amenity/doctors", - "healthcare/clinic", - "healthcare/laboratory", - "healthcare/physiotherapist", - "healthcare/sample_collection", - "healthcare/dialysis" - ], - convenience: [ - "shop/beauty", - "shop/chemist", - "shop/convenience", - "shop/cosmetics", - "shop/grocery", - "shop/kiosk", - "shop/newsagent", - "shop/perfumery" - ], - coworking: [ - "amenity/coworking_space", - "office/coworking", - "office/coworking_space" - ], - dentist: [ - "amenity/dentist", - "amenity/doctors", - "healthcare/dentist" - ], - electronics: [ - "office/telecommunication", - "shop/computer", - "shop/electronics", - "shop/hifi", - "shop/kiosk", - "shop/mobile", - "shop/mobile_phone", - "shop/telecommunication" - ], - fabric: [ - "shop/fabric", - "shop/haberdashery", - "shop/sewing" - ], - fashion: [ - "shop/accessories", - "shop/bag", - "shop/boutique", - "shop/clothes", - "shop/department_store", - "shop/fashion", - "shop/fashion_accessories", - "shop/sports", - "shop/shoes" - ], - financial: [ - "amenity/bank", - "office/accountant", - "office/financial", - "office/financial_advisor", - "office/tax_advisor", - "shop/tax" - ], - fitness: [ - "leisure/fitness_centre", - "leisure/fitness_center", - "leisure/sports_centre", - "leisure/sports_center" - ], - food: [ - "amenity/bar", - "amenity/cafe", - "amenity/fast_food", - "amenity/ice_cream", - "amenity/pub", - "amenity/restaurant", - "shop/bakery", - "shop/candy", - "shop/chocolate", - "shop/coffee", - "shop/confectionary", - "shop/confectionery", - "shop/food", - "shop/kiosk", - "shop/ice_cream", - "shop/pastry", - "shop/tea" - ], - fuel: [ - "amenity/fuel", - "shop/gas", - "shop/convenience;gas", - "shop/gas;convenience" - ], - gift: [ - "shop/gift", - "shop/card", - "shop/cards", - "shop/kiosk", - "shop/stationery" - ], - hardware: [ - "shop/bathroom_furnishing", - "shop/carpet", - "shop/diy", - "shop/doityourself", - "shop/doors", - "shop/electrical", - "shop/flooring", - "shop/hardware", - "shop/hardware_store", - "shop/power_tools", - "shop/tool_hire", - "shop/tools", - "shop/trade" - ], - health_food: [ - "shop/health", - "shop/health_food", - "shop/herbalist", - "shop/nutrition_supplements" - ], - hobby: [ - "shop/electronics", - "shop/hobby", - "shop/books", - "shop/games", - "shop/collector", - "shop/toys", - "shop/model", - "shop/video_games", - "shop/anime" - ], - hospital: [ - "amenity/doctors", - "amenity/hospital", - "healthcare/hospital" - ], - houseware: [ - "shop/houseware", - "shop/interior_decoration" - ], - lifeboat_station: [ - "amenity/lifeboat_station", - "emergency/lifeboat_station", - "emergency/marine_rescue" - ], - lodging: [ - "tourism/hotel", - "tourism/motel" - ], - money_transfer: [ - "amenity/money_transfer", - "shop/money_transfer" - ], - office_supplies: [ - "shop/office_supplies", - "shop/stationary", - "shop/stationery" - ], - outdoor: [ - "shop/clothes", - "shop/outdoor", - "shop/sports" - ], - parcel_locker: [ - "amenity/parcel_locker", - "amenity/vending_machine" - ], - pharmacy: [ - "amenity/doctors", - "amenity/pharmacy", - "healthcare/pharmacy" - ], - playground: [ - "amenity/theme_park", - "leisure/amusement_arcade", - "leisure/playground" - ], - rental: [ - "amenity/bicycle_rental", - "amenity/boat_rental", - "amenity/car_rental", - "amenity/truck_rental", - "amenity/vehicle_rental", - "shop/kiosk", - "shop/rental" - ], - school: [ - "amenity/childcare", - "amenity/college", - "amenity/kindergarten", - "amenity/language_school", - "amenity/prep_school", - "amenity/school", - "amenity/university" - ], - storage: [ - "shop/storage_units", - "shop/storage_rental" - ], - substation: [ - "power/station", - "power/substation", - "power/sub_station" - ], - supermarket: [ - "shop/food", - "shop/frozen_food", - "shop/greengrocer", - "shop/grocery", - "shop/supermarket", - "shop/wholesale" - ], - variety_store: [ - "shop/variety_store", - "shop/discount", - "shop/convenience" - ], - vending: [ - "amenity/vending_machine", - "shop/kiosk", - "shop/vending_machine" - ], - weight_loss: [ - "amenity/clinic", - "amenity/doctors", - "amenity/weight_clinic", - "healthcare/counselling", - "leisure/fitness_centre", - "office/therapist", - "shop/beauty", - "shop/diet", - "shop/food", - "shop/health_food", - "shop/herbalist", - "shop/nutrition", - "shop/nutrition_supplements", - "shop/weight_loss" - ], - wholesale: [ - "shop/wholesale", - "shop/supermarket", - "shop/department_store" - ] - } - }; - - // node_modules/name-suggestion-index/config/genericWords.json - var genericWords_default = { - genericWords: [ - "^(barn|bazaa?r|bench|bou?tique|building|casa|church)$", - "^(baseball|basketball|football|soccer|softball|tennis(halle)?)\\s?(field|court)?$", - "^(club|green|out|ware)\\s?house$", - "^(driveway|el \xE1rbol|fountain|generic|golf|government|graveyard)$", - "^(fixme|n\\s?\\/?\\s?a|name|no\\s?name|none|null|temporary|test|unknown)$", - "^(hofladen|librairie|magazine?|maison)$", - "^(mobile home|skate)?\\s?park$", - "^(obuwie|pond|pool|sale|shops?|sklep|stores?)$", - "^\\?+$", - "^private$", - "^tattoo( studio)?$", - "^windmill$", - "^\u0446\u0435\u0440\u043A\u043E\u0432\u043D\u0430\u044F( \u043B\u0430\u0432\u043A\u0430)?$" - ] - }; - - // node_modules/name-suggestion-index/config/trees.json - var trees_default = { - trees: { - brands: { - emoji: "\u{1F354}", - mainTag: "brand:wikidata", - sourceTags: ["brand", "name"], - nameTags: { - primary: "^(name|name:\\w+)$", - alternate: "^(brand|brand:\\w+|operator|operator:\\w+|\\w+_name|\\w+_name:\\w+)$" + if (token = this.tokenizer.del(src)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; } - }, - flags: { - emoji: "\u{1F6A9}", - mainTag: "flag:wikidata", - nameTags: { - primary: "^(flag:name|flag:name:\\w+)$", - alternate: "^(country|country:\\w+|flag|flag:\\w+|subject|subject:\\w+)$" + if (token = this.tokenizer.autolink(src, mangle)) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; } - }, - operators: { - emoji: "\u{1F4BC}", - mainTag: "operator:wikidata", - sourceTags: ["operator"], - nameTags: { - primary: "^(name|name:\\w+|operator|operator:\\w+)$", - alternate: "^(brand|brand:\\w+|\\w+_name|\\w+_name:\\w+)$" + if (!this.state.inLink && (token = this.tokenizer.url(src, mangle))) { + src = src.substring(token.raw.length); + tokens.push(token); + continue; } - }, - transit: { - emoji: "\u{1F687}", - mainTag: "network:wikidata", - sourceTags: ["network"], - nameTags: { - primary: "^network$", - alternate: "^(operator|operator:\\w+|network:\\w+|\\w+_name|\\w+_name:\\w+)$" + cutSrc = src; + if (this.options.extensions && this.options.extensions.startInline) { + let startIndex = Infinity; + const tempSrc = src.slice(1); + let tempStart; + this.options.extensions.startInline.forEach(function(getStartIndex) { + tempStart = getStartIndex.call({ lexer: this }, tempSrc); + if (typeof tempStart === "number" && tempStart >= 0) { + startIndex = Math.min(startIndex, tempStart); + } + }); + if (startIndex < Infinity && startIndex >= 0) { + cutSrc = src.substring(0, startIndex + 1); + } + } + if (token = this.tokenizer.inlineText(cutSrc, smartypants)) { + src = src.substring(token.raw.length); + if (token.raw.slice(-1) !== "_") { + prevChar = token.raw.slice(-1); + } + keepPrevChar = true; + lastToken = tokens[tokens.length - 1]; + if (lastToken && lastToken.type === "text") { + lastToken.raw += token.raw; + lastToken.text += token.text; + } else { + tokens.push(token); + } + continue; + } + if (src) { + const errMsg = "Infinite loop on byte: " + src.charCodeAt(0); + if (this.options.silent) { + console.error(errMsg); + break; + } else { + throw new Error(errMsg); + } } } + return tokens; } }; - - // node_modules/name-suggestion-index/lib/matcher.js - var matchGroups = matchGroups_default.matchGroups; - var trees = trees_default.trees; - var Matcher = class { - constructor() { - this.matchIndex = void 0; - this.genericWords = /* @__PURE__ */ new Map(); - (genericWords_default.genericWords || []).forEach((s) => this.genericWords.set(s, new RegExp(s, "i"))); - this.itemLocation = void 0; - this.locationSets = void 0; - this.locationIndex = void 0; - this.warnings = []; + var Renderer = class { + constructor(options2) { + this.options = options2 || defaults; } - buildMatchIndex(data) { - const that = this; - if (that.matchIndex) - return; - that.matchIndex = /* @__PURE__ */ new Map(); - const seenTree = /* @__PURE__ */ new Map(); - Object.keys(data).forEach((tkv) => { - const category = data[tkv]; - const parts = tkv.split("/", 3); - const t = parts[0]; - const k = parts[1]; - const v = parts[2]; - const thiskv = `${k}/${v}`; - const tree = trees[t]; - let branch = that.matchIndex.get(thiskv); - if (!branch) { - branch = { - primary: /* @__PURE__ */ new Map(), - alternate: /* @__PURE__ */ new Map(), - excludeGeneric: /* @__PURE__ */ new Map(), - excludeNamed: /* @__PURE__ */ new Map() - }; - that.matchIndex.set(thiskv, branch); - } - const properties = category.properties || {}; - const exclude = properties.exclude || {}; - (exclude.generic || []).forEach((s) => branch.excludeGeneric.set(s, new RegExp(s, "i"))); - (exclude.named || []).forEach((s) => branch.excludeNamed.set(s, new RegExp(s, "i"))); - const excludeRegexes = [...branch.excludeGeneric.values(), ...branch.excludeNamed.values()]; - let items = category.items; - if (!Array.isArray(items) || !items.length) - return; - const primaryName = new RegExp(tree.nameTags.primary, "i"); - const alternateName = new RegExp(tree.nameTags.alternate, "i"); - const notName = /:(colou?r|type|forward|backward|left|right|etymology|pronunciation|wikipedia)$/i; - const skipGenericKV = skipGenericKVMatches(t, k, v); - const genericKV = /* @__PURE__ */ new Set([`${k}/yes`, `building/yes`]); - const matchGroupKV = /* @__PURE__ */ new Set(); - Object.values(matchGroups).forEach((matchGroup) => { - const inGroup = matchGroup.some((otherkv) => otherkv === thiskv); - if (!inGroup) - return; - matchGroup.forEach((otherkv) => { - if (otherkv === thiskv) - return; - matchGroupKV.add(otherkv); - const otherk = otherkv.split("/", 2)[0]; - genericKV.add(`${otherk}/yes`); - }); - }); - items.forEach((item) => { - if (!item.id) - return; - if (Array.isArray(item.matchTags) && item.matchTags.length) { - item.matchTags = item.matchTags.filter((matchTag) => !matchGroupKV.has(matchTag) && !genericKV.has(matchTag)); - if (!item.matchTags.length) - delete item.matchTags; - } - let kvTags = [`${thiskv}`].concat(item.matchTags || []); - if (!skipGenericKV) { - kvTags = kvTags.concat(Array.from(genericKV)); - } - Object.keys(item.tags).forEach((osmkey) => { - if (notName.test(osmkey)) - return; - const osmvalue = item.tags[osmkey]; - if (!osmvalue || excludeRegexes.some((regex) => regex.test(osmvalue))) - return; - if (primaryName.test(osmkey)) { - kvTags.forEach((kv) => insertName("primary", t, kv, simplify(osmvalue), item.id)); - } else if (alternateName.test(osmkey)) { - kvTags.forEach((kv) => insertName("alternate", t, kv, simplify(osmvalue), item.id)); - } - }); - let keepMatchNames = /* @__PURE__ */ new Set(); - (item.matchNames || []).forEach((matchName) => { - const nsimple = simplify(matchName); - kvTags.forEach((kv) => { - const branch2 = that.matchIndex.get(kv); - const primaryLeaf = branch2 && branch2.primary.get(nsimple); - const alternateLeaf = branch2 && branch2.alternate.get(nsimple); - const inPrimary = primaryLeaf && primaryLeaf.has(item.id); - const inAlternate = alternateLeaf && alternateLeaf.has(item.id); - if (!inPrimary && !inAlternate) { - insertName("alternate", t, kv, nsimple, item.id); - keepMatchNames.add(matchName); - } - }); - }); - if (keepMatchNames.size) { - item.matchNames = Array.from(keepMatchNames); - } else { - delete item.matchNames; - } - }); - }); - function insertName(which, t, kv, nsimple, itemID) { - if (!nsimple) { - that.warnings.push(`Warning: skipping empty ${which} name for item ${t}/${kv}: ${itemID}`); - return; - } - let branch = that.matchIndex.get(kv); - if (!branch) { - branch = { - primary: /* @__PURE__ */ new Map(), - alternate: /* @__PURE__ */ new Map(), - excludeGeneric: /* @__PURE__ */ new Map(), - excludeNamed: /* @__PURE__ */ new Map() - }; - that.matchIndex.set(kv, branch); - } - let leaf = branch[which].get(nsimple); - if (!leaf) { - leaf = /* @__PURE__ */ new Set(); - branch[which].set(nsimple, leaf); - } - leaf.add(itemID); - if (!/yes$/.test(kv)) { - const kvnsimple = `${kv}/${nsimple}`; - const existing = seenTree.get(kvnsimple); - if (existing && existing !== t) { - const items = Array.from(leaf); - that.warnings.push(`Duplicate cache key "${kvnsimple}" in trees "${t}" and "${existing}", check items: ${items}`); - return; - } - seenTree.set(kvnsimple, t); + code(code, infostring, escaped) { + const lang = (infostring || "").match(/\S*/)[0]; + if (this.options.highlight) { + const out = this.options.highlight(code, lang); + if (out != null && out !== code) { + escaped = true; + code = out; } } - function skipGenericKVMatches(t, k, v) { - return t === "flags" || t === "transit" || k === "landuse" || v === "atm" || v === "bicycle_parking" || v === "car_sharing" || v === "caravan_site" || v === "charging_station" || v === "dog_park" || v === "parking" || v === "phone" || v === "playground" || v === "post_box" || v === "public_bookcase" || v === "recycling" || v === "vending_machine"; + code = code.replace(/\n$/, "") + "\n"; + if (!lang) { + return "
    " + (escaped ? code : escape4(code, true)) + "
    \n"; } + return '
    ' + (escaped ? code : escape4(code, true)) + "
    \n"; } - buildLocationIndex(data, loco) { - const that = this; - if (that.locationIndex) - return; - that.itemLocation = /* @__PURE__ */ new Map(); - that.locationSets = /* @__PURE__ */ new Map(); - Object.keys(data).forEach((tkv) => { - const items = data[tkv].items; - if (!Array.isArray(items) || !items.length) - return; - items.forEach((item) => { - if (that.itemLocation.has(item.id)) - return; - let resolved; - try { - resolved = loco.resolveLocationSet(item.locationSet); - } catch (err) { - console.warn(`buildLocationIndex: ${err.message}`); - } - if (!resolved || !resolved.id) - return; - that.itemLocation.set(item.id, resolved.id); - if (that.locationSets.has(resolved.id)) - return; - let feature3 = _cloneDeep2(resolved.feature); - feature3.id = resolved.id; - feature3.properties.id = resolved.id; - if (!feature3.geometry.coordinates.length || !feature3.properties.area) { - console.warn(`buildLocationIndex: locationSet ${resolved.id} for ${item.id} resolves to an empty feature:`); - console.warn(JSON.stringify(feature3)); - return; - } - that.locationSets.set(resolved.id, feature3); - }); - }); - that.locationIndex = (0, import_which_polygon3.default)({ type: "FeatureCollection", features: [...that.locationSets.values()] }); - function _cloneDeep2(obj) { - return JSON.parse(JSON.stringify(obj)); + /** + * @param {string} quote + */ + blockquote(quote2) { + return `
    +${quote2}
    +`; + } + html(html2, block2) { + return html2; + } + /** + * @param {string} text + * @param {string} level + * @param {string} raw + * @param {any} slugger + */ + heading(text2, level, raw, slugger) { + if (this.options.headerIds) { + const id2 = this.options.headerPrefix + slugger.slug(raw); + return `${text2} +`; } + return `${text2} +`; } - match(k, v, n2, loc) { - const that = this; - if (!that.matchIndex) { - throw new Error("match: matchIndex not built."); + hr() { + return this.options.xhtml ? "
    \n" : "
    \n"; + } + list(body, ordered, start2) { + const type2 = ordered ? "ol" : "ul", startatt = ordered && start2 !== 1 ? ' start="' + start2 + '"' : ""; + return "<" + type2 + startatt + ">\n" + body + "\n"; + } + /** + * @param {string} text + */ + listitem(text2) { + return `
  • ${text2}
  • +`; + } + checkbox(checked) { + return " "; + } + /** + * @param {string} text + */ + paragraph(text2) { + return `

    ${text2}

    +`; + } + /** + * @param {string} header + * @param {string} body + */ + table(header, body) { + if (body) + body = `${body}`; + return "\n\n" + header + "\n" + body + "
    \n"; + } + /** + * @param {string} content + */ + tablerow(content) { + return ` +${content} +`; + } + tablecell(content, flags) { + const type2 = flags.header ? "th" : "td"; + const tag = flags.align ? `<${type2} align="${flags.align}">` : `<${type2}>`; + return tag + content + ` +`; + } + /** + * span level renderer + * @param {string} text + */ + strong(text2) { + return `${text2}`; + } + /** + * @param {string} text + */ + em(text2) { + return `${text2}`; + } + /** + * @param {string} text + */ + codespan(text2) { + return `${text2}`; + } + br() { + return this.options.xhtml ? "
    " : "
    "; + } + /** + * @param {string} text + */ + del(text2) { + return `${text2}`; + } + /** + * @param {string} href + * @param {string} title + * @param {string} text + */ + link(href, title, text2) { + href = cleanUrl(this.options.sanitize, this.options.baseUrl, href); + if (href === null) { + return text2; } - let matchLocations; - if (Array.isArray(loc) && that.locationIndex) { - matchLocations = that.locationIndex([loc[0], loc[1], loc[0], loc[1]], true); + let out = '
    otherkv === kv); - if (!inGroup) - continue; - for (let i2 = 0; i2 < matchGroup.length; i2++) { - const otherkv = matchGroup[i2]; - if (otherkv === kv) - continue; - didMatch = tryMatch(which, otherkv); - if (didMatch) - return; - } - } - if (which === "exclude") { - const regex = [...that.genericWords.values()].find((regex2) => regex2.test(n2)); - if (regex) { - results.push({ match: "excludeGeneric", pattern: String(regex) }); - return; - } - } + out += ">" + text2 + ""; + return out; + } + /** + * @param {string} href + * @param {string} title + * @param {string} text + */ + image(href, title, text2) { + href = cleanUrl(this.options.sanitize, this.options.baseUrl, href); + if (href === null) { + return text2; } - function tryMatch(which, kv) { - const branch = that.matchIndex.get(kv); - if (!branch) - return; - if (which === "exclude") { - let regex = [...branch.excludeNamed.values()].find((regex2) => regex2.test(n2)); - if (regex) { - results.push({ match: "excludeNamed", pattern: String(regex), kv }); - return; - } - regex = [...branch.excludeGeneric.values()].find((regex2) => regex2.test(n2)); - if (regex) { - results.push({ match: "excludeGeneric", pattern: String(regex), kv }); - return; - } - return; - } - const leaf = branch[which].get(nsimple); - if (!leaf || !leaf.size) - return; - let hits = Array.from(leaf).map((itemID) => { - let area = Infinity; - if (that.itemLocation && that.locationSets) { - const location = that.locationSets.get(that.itemLocation.get(itemID)); - area = location && location.properties.area || Infinity; - } - return { match: which, itemID, area, kv, nsimple }; - }); - let sortFn = byAreaDescending; - if (matchLocations) { - hits = hits.filter(isValidLocation); - sortFn = byAreaAscending; - } - if (!hits.length) - return; - hits.sort(sortFn).forEach((hit) => { - if (seen.has(hit.itemID)) - return; - seen.add(hit.itemID); - results.push(hit); - }); - return true; - function isValidLocation(hit) { - if (!that.itemLocation) - return true; - return matchLocations.find((props) => props.id === that.itemLocation.get(hit.itemID)); - } - function byAreaAscending(hitA, hitB) { - return hitA.area - hitB.area; - } - function byAreaDescending(hitA, hitB) { - return hitB.area - hitA.area; - } + let out = `${text2}" : ">"; + return out; } - getWarnings() { - return this.warnings; + text(text2) { + return text2; } }; - - // modules/services/nsi.js - var import_vparse2 = __toESM(require_vparse()); - - // modules/core/difference.js - var import_fast_deep_equal3 = __toESM(require_fast_deep_equal()); - function coreDifference(base, head) { - var _changes = {}; - var _didChange = {}; - var _diff = {}; - function checkEntityID(id2) { - var h = head.entities[id2]; - var b = base.entities[id2]; - if (h === b) - return; - if (_changes[id2]) - return; - if (!h && b) { - _changes[id2] = { base: b, head: h }; - _didChange.deletion = true; - return; - } - if (h && !b) { - _changes[id2] = { base: b, head: h }; - _didChange.addition = true; - return; + var TextRenderer = class { + // no need for block level renderers + strong(text2) { + return text2; + } + em(text2) { + return text2; + } + codespan(text2) { + return text2; + } + del(text2) { + return text2; + } + html(text2) { + return text2; + } + text(text2) { + return text2; + } + link(href, title, text2) { + return "" + text2; + } + image(href, title, text2) { + return "" + text2; + } + br() { + return ""; + } + }; + var Slugger = class { + constructor() { + this.seen = {}; + } + /** + * @param {string} value + */ + serialize(value) { + return value.toLowerCase().trim().replace(/<[!\/a-z].*?>/ig, "").replace(/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g, "").replace(/\s/g, "-"); + } + /** + * Finds the next safe (unique) slug to use + * @param {string} originalSlug + * @param {boolean} isDryRun + */ + getNextSafeSlug(originalSlug, isDryRun) { + let slug = originalSlug; + let occurenceAccumulator = 0; + if (this.seen.hasOwnProperty(slug)) { + occurenceAccumulator = this.seen[originalSlug]; + do { + occurenceAccumulator++; + slug = originalSlug + "-" + occurenceAccumulator; + } while (this.seen.hasOwnProperty(slug)); } - if (h && b) { - if (h.members && b.members && !(0, import_fast_deep_equal3.default)(h.members, b.members)) { - _changes[id2] = { base: b, head: h }; - _didChange.geometry = true; - _didChange.properties = true; - return; - } - if (h.loc && b.loc && !geoVecEqual(h.loc, b.loc)) { - _changes[id2] = { base: b, head: h }; - _didChange.geometry = true; - } - if (h.nodes && b.nodes && !(0, import_fast_deep_equal3.default)(h.nodes, b.nodes)) { - _changes[id2] = { base: b, head: h }; - _didChange.geometry = true; - } - if (h.tags && b.tags && !(0, import_fast_deep_equal3.default)(h.tags, b.tags)) { - _changes[id2] = { base: b, head: h }; - _didChange.properties = true; - } + if (!isDryRun) { + this.seen[originalSlug] = occurenceAccumulator; + this.seen[slug] = 0; } + return slug; } - function load() { - var ids = utilArrayUniq(Object.keys(head.entities).concat(Object.keys(base.entities))); - for (var i2 = 0; i2 < ids.length; i2++) { - checkEntityID(ids[i2]); - } + /** + * Convert string to unique id + * @param {object} [options] + * @param {boolean} [options.dryrun] Generates the next unique slug without + * updating the internal accumulator. + */ + slug(value, options2 = {}) { + const slug = this.serialize(value); + return this.getNextSafeSlug(slug, options2.dryrun); } - load(); - _diff.length = function length() { - return Object.keys(_changes).length; - }; - _diff.changes = function changes() { - return _changes; - }; - _diff.didChange = _didChange; - _diff.extantIDs = function extantIDs(includeRelMembers) { - var result = /* @__PURE__ */ new Set(); - Object.keys(_changes).forEach(function(id2) { - if (_changes[id2].head) { - result.add(id2); + }; + var Parser = class _Parser { + constructor(options2) { + this.options = options2 || defaults; + this.options.renderer = this.options.renderer || new Renderer(); + this.renderer = this.options.renderer; + this.renderer.options = this.options; + this.textRenderer = new TextRenderer(); + this.slugger = new Slugger(); + } + /** + * Static Parse Method + */ + static parse(tokens, options2) { + const parser3 = new _Parser(options2); + return parser3.parse(tokens); + } + /** + * Static Parse Inline Method + */ + static parseInline(tokens, options2) { + const parser3 = new _Parser(options2); + return parser3.parseInline(tokens); + } + /** + * Parse Loop + */ + parse(tokens, top = true) { + let out = "", i2, j2, k, l2, l3, row, cell, header, body, token, ordered, start2, loose, itemBody, item, checked, task, checkbox, ret; + const l = tokens.length; + for (i2 = 0; i2 < l; i2++) { + token = tokens[i2]; + if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) { + ret = this.options.extensions.renderers[token.type].call({ parser: this }, token); + if (ret !== false || !["space", "hr", "heading", "code", "table", "blockquote", "list", "html", "paragraph", "text"].includes(token.type)) { + out += ret || ""; + continue; + } } - var h = _changes[id2].head; - var b = _changes[id2].base; - var entity = h || b; - if (includeRelMembers && entity.type === "relation") { - var mh = h ? h.members.map(function(m) { - return m.id; - }) : []; - var mb = b ? b.members.map(function(m) { - return m.id; - }) : []; - utilArrayUnion(mh, mb).forEach(function(memberID) { - if (head.hasEntity(memberID)) { - result.add(memberID); - } - }); - } - }); - return Array.from(result); - }; - _diff.modified = function modified() { - var result = []; - Object.values(_changes).forEach(function(change) { - if (change.base && change.head) { - result.push(change.head); - } - }); - return result; - }; - _diff.created = function created() { - var result = []; - Object.values(_changes).forEach(function(change) { - if (!change.base && change.head) { - result.push(change.head); - } - }); - return result; - }; - _diff.deleted = function deleted() { - var result = []; - Object.values(_changes).forEach(function(change) { - if (change.base && !change.head) { - result.push(change.base); - } - }); - return result; - }; - _diff.summary = function summary() { - var relevant = {}; - var keys = Object.keys(_changes); - for (var i2 = 0; i2 < keys.length; i2++) { - var change = _changes[keys[i2]]; - 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) { - var moved = !(0, import_fast_deep_equal3.default)(change.base.loc, change.head.loc); - var retagged = !(0, import_fast_deep_equal3.default)(change.base.tags, change.head.tags); - if (moved) { - addParents(change.head); + switch (token.type) { + case "space": { + continue; } - if (retagged || moved && change.head.hasInterestingTags()) { - addEntity(change.head, head, "modified"); + case "hr": { + out += this.renderer.hr(); + continue; } - } else if (change.head && change.head.hasInterestingTags()) { - addEntity(change.head, head, "created"); - } else if (change.base && change.base.hasInterestingTags()) { - addEntity(change.base, base, "deleted"); - } - } - return Object.values(relevant); - function addEntity(entity, graph, changeType) { - relevant[entity.id] = { - entity, - graph, - changeType - }; - } - function addParents(entity) { - var parents = head.parentWays(entity); - for (var j2 = parents.length - 1; j2 >= 0; j2--) { - var parent = parents[j2]; - if (!(parent.id in relevant)) { - addEntity(parent, head, "modified"); + case "heading": { + out += this.renderer.heading( + this.parseInline(token.tokens), + token.depth, + unescape3(this.parseInline(token.tokens, this.textRenderer)), + this.slugger + ); + continue; } - } - } - }; - _diff.complete = function complete(extent) { - var result = {}; - var id2, change; - for (id2 in _changes) { - change = _changes[id2]; - var h = change.head; - var b = change.base; - var entity = h || b; - var i2; - if (extent && (!h || !h.intersects(extent, head)) && (!b || !b.intersects(extent, base))) { - continue; - } - result[id2] = h; - if (entity.type === "way") { - var nh = h ? h.nodes : []; - var nb = b ? b.nodes : []; - var diff; - diff = utilArrayDifference(nh, nb); - for (i2 = 0; i2 < diff.length; i2++) { - result[diff[i2]] = head.hasEntity(diff[i2]); + case "code": { + out += this.renderer.code( + token.text, + token.lang, + token.escaped + ); + continue; } - diff = utilArrayDifference(nb, nh); - for (i2 = 0; i2 < diff.length; i2++) { - result[diff[i2]] = head.hasEntity(diff[i2]); + case "table": { + header = ""; + cell = ""; + l2 = token.header.length; + for (j2 = 0; j2 < l2; j2++) { + cell += this.renderer.tablecell( + this.parseInline(token.header[j2].tokens), + { header: true, align: token.align[j2] } + ); + } + header += this.renderer.tablerow(cell); + body = ""; + l2 = token.rows.length; + for (j2 = 0; j2 < l2; j2++) { + row = token.rows[j2]; + cell = ""; + l3 = row.length; + for (k = 0; k < l3; k++) { + cell += this.renderer.tablecell( + this.parseInline(row[k].tokens), + { header: false, align: token.align[k] } + ); + } + body += this.renderer.tablerow(cell); + } + out += this.renderer.table(header, body); + continue; } - } - if (entity.type === "relation" && entity.isMultipolygon()) { - var mh = h ? h.members.map(function(m) { - return m.id; - }) : []; - var mb = b ? b.members.map(function(m) { - return m.id; - }) : []; - var ids = utilArrayUnion(mh, mb); - for (i2 = 0; i2 < ids.length; i2++) { - var member = head.hasEntity(ids[i2]); - if (!member) - continue; - if (extent && !member.intersects(extent, head)) - continue; - result[ids[i2]] = member; + case "blockquote": { + body = this.parse(token.tokens); + out += this.renderer.blockquote(body); + continue; + } + case "list": { + ordered = token.ordered; + start2 = token.start; + loose = token.loose; + l2 = token.items.length; + body = ""; + for (j2 = 0; j2 < l2; j2++) { + item = token.items[j2]; + checked = item.checked; + task = item.task; + itemBody = ""; + if (item.task) { + checkbox = this.renderer.checkbox(checked); + if (loose) { + if (item.tokens.length > 0 && item.tokens[0].type === "paragraph") { + item.tokens[0].text = checkbox + " " + item.tokens[0].text; + if (item.tokens[0].tokens && item.tokens[0].tokens.length > 0 && item.tokens[0].tokens[0].type === "text") { + item.tokens[0].tokens[0].text = checkbox + " " + item.tokens[0].tokens[0].text; + } + } else { + item.tokens.unshift({ + type: "text", + text: checkbox + }); + } + } else { + itemBody += checkbox; + } + } + itemBody += this.parse(item.tokens, loose); + body += this.renderer.listitem(itemBody, task, checked); + } + out += this.renderer.list(body, ordered, start2); + continue; + } + case "html": { + out += this.renderer.html(token.text, token.block); + continue; + } + case "paragraph": { + out += this.renderer.paragraph(this.parseInline(token.tokens)); + continue; + } + case "text": { + body = token.tokens ? this.parseInline(token.tokens) : token.text; + while (i2 + 1 < l && tokens[i2 + 1].type === "text") { + token = tokens[++i2]; + body += "\n" + (token.tokens ? this.parseInline(token.tokens) : token.text); + } + out += top ? this.renderer.paragraph(body) : body; + continue; + } + default: { + const errMsg = 'Token with "' + token.type + '" type was not found.'; + if (this.options.silent) { + console.error(errMsg); + return; + } else { + throw new Error(errMsg); + } } } - addParents(head.parentWays(entity), result); - addParents(head.parentRelations(entity), result); } - return result; - function addParents(parents, result2) { - for (var i3 = 0; i3 < parents.length; i3++) { - var parent = parents[i3]; - if (parent.id in result2) + return out; + } + /** + * Parse Inline Tokens + */ + parseInline(tokens, renderer) { + renderer = renderer || this.renderer; + let out = "", i2, token, ret; + const l = tokens.length; + for (i2 = 0; i2 < l; i2++) { + token = tokens[i2]; + if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) { + ret = this.options.extensions.renderers[token.type].call({ parser: this }, token); + if (ret !== false || !["escape", "html", "link", "image", "strong", "em", "codespan", "br", "del", "text"].includes(token.type)) { + out += ret || ""; continue; - result2[parent.id] = parent; - addParents(head.parentRelations(parent), result2); + } + } + switch (token.type) { + case "escape": { + out += renderer.text(token.text); + break; + } + case "html": { + out += renderer.html(token.text); + break; + } + case "link": { + out += renderer.link(token.href, token.title, this.parseInline(token.tokens, renderer)); + break; + } + case "image": { + out += renderer.image(token.href, token.title, token.text); + break; + } + case "strong": { + out += renderer.strong(this.parseInline(token.tokens, renderer)); + break; + } + case "em": { + out += renderer.em(this.parseInline(token.tokens, renderer)); + break; + } + case "codespan": { + out += renderer.codespan(token.text); + break; + } + case "br": { + out += renderer.br(); + break; + } + case "del": { + out += renderer.del(this.parseInline(token.tokens, renderer)); + break; + } + case "text": { + out += renderer.text(token.text); + break; + } + default: { + const errMsg = 'Token with "' + token.type + '" type was not found.'; + if (this.options.silent) { + console.error(errMsg); + return; + } else { + throw new Error(errMsg); + } + } } } - }; - return _diff; - } - - // modules/core/tree.js - var import_rbush6 = __toESM(require_rbush_min()); - function coreTree(head) { - var _rtree = new import_rbush6.default(); - var _bboxes = {}; - var _segmentsRTree = new import_rbush6.default(); - var _segmentsBBoxes = {}; - var _segmentsByWayId = {}; - var tree = {}; - function entityBBox(entity) { - var bbox = entity.extent(head).bbox(); - bbox.id = entity.id; - _bboxes[entity.id] = bbox; - return bbox; + return out; } - function segmentBBox(segment) { - var extent = segment.extent(head); - if (!extent) - return null; - var bbox = extent.bbox(); - bbox.segment = segment; - _segmentsBBoxes[segment.id] = bbox; - return bbox; + }; + var Hooks = class { + constructor(options2) { + this.options = options2 || defaults; } - function removeEntity(entity) { - _rtree.remove(_bboxes[entity.id]); - delete _bboxes[entity.id]; - if (_segmentsByWayId[entity.id]) { - _segmentsByWayId[entity.id].forEach(function(segment) { - _segmentsRTree.remove(_segmentsBBoxes[segment.id]); - delete _segmentsBBoxes[segment.id]; - }); - delete _segmentsByWayId[entity.id]; + static passThroughHooks = /* @__PURE__ */ new Set([ + "preprocess", + "postprocess" + ]); + /** + * Process markdown before marked + */ + preprocess(markdown) { + return markdown; + } + /** + * Process HTML after marked is finished + */ + postprocess(html2) { + return html2; + } + }; + var Marked = class { + defaults = getDefaults(); + options = this.setOptions; + parse = this.#parseMarkdown(Lexer.lex, Parser.parse); + parseInline = this.#parseMarkdown(Lexer.lexInline, Parser.parseInline); + Parser = Parser; + parser = Parser.parse; + Renderer = Renderer; + TextRenderer = TextRenderer; + Lexer = Lexer; + lexer = Lexer.lex; + Tokenizer = Tokenizer; + Slugger = Slugger; + Hooks = Hooks; + constructor(...args) { + this.use(...args); + } + walkTokens(tokens, callback) { + let values = []; + for (const token of tokens) { + values = values.concat(callback.call(this, token)); + switch (token.type) { + case "table": { + for (const cell of token.header) { + values = values.concat(this.walkTokens(cell.tokens, callback)); + } + for (const row of token.rows) { + for (const cell of row) { + values = values.concat(this.walkTokens(cell.tokens, callback)); + } + } + break; + } + case "list": { + values = values.concat(this.walkTokens(token.items, callback)); + break; + } + default: { + if (this.defaults.extensions && this.defaults.extensions.childTokens && this.defaults.extensions.childTokens[token.type]) { + this.defaults.extensions.childTokens[token.type].forEach((childTokens) => { + values = values.concat(this.walkTokens(token[childTokens], callback)); + }); + } else if (token.tokens) { + values = values.concat(this.walkTokens(token.tokens, callback)); + } + } + } } + return values; } - function loadEntities(entities) { - _rtree.load(entities.map(entityBBox)); - var segments = []; - entities.forEach(function(entity) { - if (entity.segments) { - var entitySegments = entity.segments(head); - _segmentsByWayId[entity.id] = entitySegments; - segments = segments.concat(entitySegments); + use(...args) { + const extensions = this.defaults.extensions || { renderers: {}, childTokens: {} }; + args.forEach((pack) => { + const opts = { ...pack }; + opts.async = this.defaults.async || opts.async || false; + if (pack.extensions) { + pack.extensions.forEach((ext) => { + if (!ext.name) { + throw new Error("extension name required"); + } + if (ext.renderer) { + const prevRenderer = extensions.renderers[ext.name]; + if (prevRenderer) { + extensions.renderers[ext.name] = function(...args2) { + let ret = ext.renderer.apply(this, args2); + if (ret === false) { + ret = prevRenderer.apply(this, args2); + } + return ret; + }; + } else { + extensions.renderers[ext.name] = ext.renderer; + } + } + if (ext.tokenizer) { + if (!ext.level || ext.level !== "block" && ext.level !== "inline") { + throw new Error("extension level must be 'block' or 'inline'"); + } + if (extensions[ext.level]) { + extensions[ext.level].unshift(ext.tokenizer); + } else { + extensions[ext.level] = [ext.tokenizer]; + } + if (ext.start) { + if (ext.level === "block") { + if (extensions.startBlock) { + extensions.startBlock.push(ext.start); + } else { + extensions.startBlock = [ext.start]; + } + } else if (ext.level === "inline") { + if (extensions.startInline) { + extensions.startInline.push(ext.start); + } else { + extensions.startInline = [ext.start]; + } + } + } + } + if (ext.childTokens) { + extensions.childTokens[ext.name] = ext.childTokens; + } + }); + opts.extensions = extensions; + } + if (pack.renderer) { + const renderer = this.defaults.renderer || new Renderer(this.defaults); + for (const prop in pack.renderer) { + const prevRenderer = renderer[prop]; + renderer[prop] = (...args2) => { + let ret = pack.renderer[prop].apply(renderer, args2); + if (ret === false) { + ret = prevRenderer.apply(renderer, args2); + } + return ret; + }; + } + opts.renderer = renderer; + } + if (pack.tokenizer) { + const tokenizer = this.defaults.tokenizer || new Tokenizer(this.defaults); + for (const prop in pack.tokenizer) { + const prevTokenizer = tokenizer[prop]; + tokenizer[prop] = (...args2) => { + let ret = pack.tokenizer[prop].apply(tokenizer, args2); + if (ret === false) { + ret = prevTokenizer.apply(tokenizer, args2); + } + return ret; + }; + } + opts.tokenizer = tokenizer; + } + if (pack.hooks) { + const hooks = this.defaults.hooks || new Hooks(); + for (const prop in pack.hooks) { + const prevHook = hooks[prop]; + if (Hooks.passThroughHooks.has(prop)) { + hooks[prop] = (arg) => { + if (this.defaults.async) { + return Promise.resolve(pack.hooks[prop].call(hooks, arg)).then((ret2) => { + return prevHook.call(hooks, ret2); + }); + } + const ret = pack.hooks[prop].call(hooks, arg); + return prevHook.call(hooks, ret); + }; + } else { + hooks[prop] = (...args2) => { + let ret = pack.hooks[prop].apply(hooks, args2); + if (ret === false) { + ret = prevHook.apply(hooks, args2); + } + return ret; + }; + } + } + opts.hooks = hooks; + } + if (pack.walkTokens) { + const walkTokens2 = this.defaults.walkTokens; + opts.walkTokens = function(token) { + let values = []; + values.push(pack.walkTokens.call(this, token)); + if (walkTokens2) { + values = values.concat(walkTokens2.call(this, token)); + } + return values; + }; } + this.defaults = { ...this.defaults, ...opts }; }); - if (segments.length) - _segmentsRTree.load(segments.map(segmentBBox).filter(Boolean)); + return this; } - function updateParents(entity, insertions, memo) { - head.parentWays(entity).forEach(function(way) { - if (_bboxes[way.id]) { - removeEntity(way); - insertions[way.id] = way; + setOptions(opt) { + this.defaults = { ...this.defaults, ...opt }; + return this; + } + #parseMarkdown(lexer2, parser3) { + return (src, opt, callback) => { + if (typeof opt === "function") { + callback = opt; + opt = null; } - updateParents(way, insertions, memo); - }); - head.parentRelations(entity).forEach(function(relation) { - if (memo[entity.id]) + const origOpt = { ...opt }; + opt = { ...this.defaults, ...origOpt }; + const throwError = this.#onError(opt.silent, opt.async, callback); + if (typeof src === "undefined" || src === null) { + return throwError(new Error("marked(): input parameter is undefined or null")); + } + if (typeof src !== "string") { + return throwError(new Error("marked(): input parameter is of type " + Object.prototype.toString.call(src) + ", string expected")); + } + checkDeprecations(opt, callback); + if (opt.hooks) { + opt.hooks.options = opt; + } + if (callback) { + const highlight = opt.highlight; + let tokens; + try { + if (opt.hooks) { + src = opt.hooks.preprocess(src); + } + tokens = lexer2(src, opt); + } catch (e) { + return throwError(e); + } + const done = (err) => { + let out; + if (!err) { + try { + if (opt.walkTokens) { + this.walkTokens(tokens, opt.walkTokens); + } + out = parser3(tokens, opt); + if (opt.hooks) { + out = opt.hooks.postprocess(out); + } + } catch (e) { + err = e; + } + } + opt.highlight = highlight; + return err ? throwError(err) : callback(null, out); + }; + if (!highlight || highlight.length < 3) { + return done(); + } + delete opt.highlight; + if (!tokens.length) + return done(); + let pending = 0; + this.walkTokens(tokens, (token) => { + if (token.type === "code") { + pending++; + setTimeout(() => { + highlight(token.text, token.lang, (err, code) => { + if (err) { + return done(err); + } + if (code != null && code !== token.text) { + token.text = code; + token.escaped = true; + } + pending--; + if (pending === 0) { + done(); + } + }); + }, 0); + } + }); + if (pending === 0) { + done(); + } return; - memo[entity.id] = true; - if (_bboxes[relation.id]) { - removeEntity(relation); - insertions[relation.id] = relation; } - updateParents(relation, insertions, memo); - }); + if (opt.async) { + return Promise.resolve(opt.hooks ? opt.hooks.preprocess(src) : src).then((src2) => lexer2(src2, opt)).then((tokens) => opt.walkTokens ? Promise.all(this.walkTokens(tokens, opt.walkTokens)).then(() => tokens) : tokens).then((tokens) => parser3(tokens, opt)).then((html2) => opt.hooks ? opt.hooks.postprocess(html2) : html2).catch(throwError); + } + try { + if (opt.hooks) { + src = opt.hooks.preprocess(src); + } + const tokens = lexer2(src, opt); + if (opt.walkTokens) { + this.walkTokens(tokens, opt.walkTokens); + } + let html2 = parser3(tokens, opt); + if (opt.hooks) { + html2 = opt.hooks.postprocess(html2); + } + return html2; + } catch (e) { + return throwError(e); + } + }; } - tree.rebase = function(entities, force) { - var insertions = {}; - for (var i2 = 0; i2 < entities.length; i2++) { - var entity = entities[i2]; - if (!entity.visible) - continue; - if (head.entities.hasOwnProperty(entity.id) || _bboxes[entity.id]) { - if (!force) { - continue; - } else if (_bboxes[entity.id]) { - removeEntity(entity); + #onError(silent, async, callback) { + return (e) => { + e.message += "\nPlease report this to https://github.com/markedjs/marked."; + if (silent) { + const msg = "

    An error occurred:

    " + escape4(e.message + "", true) + "
    "; + if (async) { + return Promise.resolve(msg); + } + if (callback) { + callback(null, msg); + return; } + return msg; } - insertions[entity.id] = entity; - updateParents(entity, insertions, {}); - } - loadEntities(Object.values(insertions)); - return tree; - }; - function updateToGraph(graph) { - if (graph === head) - return; - var diff = coreDifference(head, graph); - head = graph; - var changed = diff.didChange; - if (!changed.addition && !changed.deletion && !changed.geometry) - return; - var insertions = {}; - if (changed.deletion) { - diff.deleted().forEach(function(entity) { - removeEntity(entity); - }); - } - if (changed.geometry) { - diff.modified().forEach(function(entity) { - removeEntity(entity); - insertions[entity.id] = entity; - updateParents(entity, insertions, {}); - }); - } - if (changed.addition) { - diff.created().forEach(function(entity) { - insertions[entity.id] = entity; - }); - } - loadEntities(Object.values(insertions)); + if (async) { + return Promise.reject(e); + } + if (callback) { + callback(e); + return; + } + throw e; + }; } - tree.intersects = function(extent, graph) { - updateToGraph(graph); - return _rtree.search(extent.bbox()).map(function(bbox) { - return graph.entity(bbox.id); - }); - }; - tree.waySegments = function(extent, graph) { - updateToGraph(graph); - return _segmentsRTree.search(extent.bbox()).map(function(bbox) { - return bbox.segment; - }); - }; - return tree; - } - - // modules/svg/icon.js - function svgIcon(name, svgklass, useklass) { - return function drawIcon(selection2) { - selection2.selectAll("svg.icon" + (svgklass ? "." + svgklass.split(" ")[0] : "")).data([0]).enter().append("svg").attr("class", "icon " + (svgklass || "")).append("use").attr("xlink:href", name).attr("class", useklass); - }; + }; + var markedInstance = new Marked(defaults); + function marked(src, opt, callback) { + return markedInstance.parse(src, opt, callback); } - - // modules/ui/modal.js - function uiModal(selection2, blocking) { - let keybinding = utilKeybinding("modal"); - let previous = selection2.select("div.modal"); - let animate = previous.empty(); - previous.transition().duration(200).style("opacity", 0).remove(); - let shaded = selection2.append("div").attr("class", "shaded").style("opacity", 0); - shaded.close = () => { - shaded.transition().duration(200).style("opacity", 0).remove(); - modal.transition().duration(200).style("top", "0px"); - select_default2(document).call(keybinding.unbind); - }; - let modal = shaded.append("div").attr("class", "modal fillL"); - modal.append("input").attr("class", "keytrap keytrap-first").on("focus.keytrap", moveFocusToLast); - if (!blocking) { - shaded.on("click.remove-modal", (d3_event) => { - if (d3_event.target === this) { - shaded.close(); - } - }); - modal.append("button").attr("class", "close").attr("title", _t("icons.close")).on("click", shaded.close).call(svgIcon("#iD-icon-close")); - keybinding.on("\u232B", shaded.close).on("\u238B", shaded.close); - select_default2(document).call(keybinding); - } - modal.append("div").attr("class", "content"); - modal.append("input").attr("class", "keytrap keytrap-last").on("focus.keytrap", moveFocusToFirst); - if (animate) { - shaded.transition().style("opacity", 1); - } else { - shaded.style("opacity", 1); - } - return shaded; - function moveFocusToFirst() { - let node = modal.select("a, button, input:not(.keytrap), select, textarea").node(); - if (node) { - node.focus(); - } else { - select_default2(this).node().blur(); - } + marked.options = marked.setOptions = function(opt) { + markedInstance.setOptions(opt); + marked.defaults = markedInstance.defaults; + changeDefaults(marked.defaults); + return marked; + }; + marked.getDefaults = getDefaults; + marked.defaults = defaults; + marked.use = function(...args) { + markedInstance.use(...args); + marked.defaults = markedInstance.defaults; + changeDefaults(marked.defaults); + return marked; + }; + marked.walkTokens = function(tokens, callback) { + return markedInstance.walkTokens(tokens, callback); + }; + marked.parseInline = markedInstance.parseInline; + marked.Parser = Parser; + marked.parser = Parser.parse; + marked.Renderer = Renderer; + marked.TextRenderer = TextRenderer; + marked.Lexer = Lexer; + marked.lexer = Lexer.lex; + marked.Tokenizer = Tokenizer; + marked.Slugger = Slugger; + marked.Hooks = Hooks; + marked.parse = marked; + var options = marked.options; + var setOptions = marked.setOptions; + var use = marked.use; + var walkTokens = marked.walkTokens; + var parseInline = marked.parseInline; + var parser2 = Parser.parse; + var lexer = Lexer.lex; + + // modules/services/osmose.js + var tiler3 = utilTiler(); + var dispatch4 = dispatch_default("loaded"); + var _tileZoom3 = 14; + var _osmoseUrlRoot = "https://osmose.openstreetmap.fr/api/0.3"; + var _osmoseData = { icons: {}, items: [] }; + var _cache3; + function abortRequest3(controller) { + if (controller) { + controller.abort(); } - function moveFocusToLast() { - let nodes = modal.selectAll("a, button, input:not(.keytrap), select, textarea").nodes(); - if (nodes.length) { - nodes[nodes.length - 1].focus(); - } else { - select_default2(this).node().blur(); + } + function abortUnwantedRequests3(cache, tiles) { + Object.keys(cache.inflightTile).forEach((k) => { + let wanted = tiles.find((tile) => k === tile.id); + if (!wanted) { + abortRequest3(cache.inflightTile[k]); + delete cache.inflightTile[k]; } + }); + } + function encodeIssueRtree3(d) { + return { minX: d.loc[0], minY: d.loc[1], maxX: d.loc[0], maxY: d.loc[1], data: d }; + } + function updateRtree3(item, replace) { + _cache3.rtree.remove(item, (a, b) => a.data.id === b.data.id); + if (replace) { + _cache3.rtree.insert(item); } } - - // modules/ui/loading.js - function uiLoading(context) { - let _modalSelection = select_default2(null); - let _message = ""; - let _blocking = false; - let loading = (selection2) => { - _modalSelection = uiModal(selection2, _blocking); - let loadertext = _modalSelection.select(".content").classed("loading-modal", true).append("div").attr("class", "modal-section fillL"); - loadertext.append("img").attr("class", "loader").attr("src", context.imagePath("loader-white.gif")); - loadertext.append("h3").html(_message); - _modalSelection.select("button.close").attr("class", "hide"); - return loading; - }; - loading.message = function(val) { - if (!arguments.length) - return _message; - _message = val; - return loading; - }; - loading.blocking = function(val) { - if (!arguments.length) - return _blocking; - _blocking = val; - return loading; - }; - loading.close = () => { - _modalSelection.remove(); - }; - loading.isShown = () => { - return _modalSelection && !_modalSelection.empty() && _modalSelection.node().parentNode; - }; - return loading; + function preventCoincident2(loc) { + let coincident = false; + do { + let delta = coincident ? [1e-5, 0] : [0, 1e-5]; + loc = geoVecAdd(loc, delta); + let bbox2 = geoExtent(loc).bbox(); + coincident = _cache3.rtree.search(bbox2).length; + } while (coincident); + return loc; } - - // modules/core/history.js - function coreHistory(context) { - var dispatch10 = dispatch_default("reset", "change", "merge", "restore", "undone", "redone", "storage_error"); - var lock = utilSessionMutex("lock"); - var _hasUnresolvedRestorableChanges = lock.lock() && !!corePreferences(getKey("saved_history")); - var duration = 150; - var _imageryUsed = []; - var _photoOverlaysUsed = []; - var _checkpoints = {}; - var _pausedGraph; - var _stack; - var _index; - var _tree; - function _act(actions, t) { - actions = Array.prototype.slice.call(actions); - var annotation; - if (typeof actions[actions.length - 1] !== "function") { - annotation = actions.pop(); + var osmose_default = { + title: "osmose", + init() { + _mainFileFetcher.get("qa_data").then((d) => { + _osmoseData = d.osmose; + _osmoseData.items = Object.keys(d.osmose.icons).map((s) => s.split("-")[0]).reduce((unique, item) => unique.indexOf(item) !== -1 ? unique : [...unique, item], []); + }); + if (!_cache3) { + this.reset(); } - var graph = _stack[_index].graph; - for (var i2 = 0; i2 < actions.length; i2++) { - graph = actions[i2](graph, t); + this.event = utilRebind(this, dispatch4, "on"); + }, + reset() { + let _strings = {}; + let _colors = {}; + if (_cache3) { + Object.values(_cache3.inflightTile).forEach(abortRequest3); + _strings = _cache3.strings; + _colors = _cache3.colors; } - return { - graph, - annotation, - imageryUsed: _imageryUsed, - photoOverlaysUsed: _photoOverlaysUsed, - transform: context.projection.transform(), - selectedIDs: context.selectedIDs() + _cache3 = { + data: {}, + loadedTile: {}, + inflightTile: {}, + inflightPost: {}, + closed: {}, + rtree: new import_rbush3.default(), + strings: _strings, + colors: _colors }; - } - function _perform(args, t) { - var previous = _stack[_index].graph; - _stack = _stack.slice(0, _index + 1); - var actionResult = _act(args, t); - _stack.push(actionResult); - _index++; - return change(previous); - } - function _replace(args, t) { - var previous = _stack[_index].graph; - var actionResult = _act(args, t); - _stack[_index] = actionResult; - return change(previous); - } - function _overwrite(args, t) { - var previous = _stack[_index].graph; - if (_index > 0) { - _index--; - _stack.pop(); + }, + loadIssues(projection2) { + let params = { + // Tiles return a maximum # of issues + // So we want to filter our request for only types iD supports + item: _osmoseData.items + }; + let tiles = tiler3.zoomExtent([_tileZoom3, _tileZoom3]).getTiles(projection2); + abortUnwantedRequests3(_cache3, tiles); + tiles.forEach((tile) => { + if (_cache3.loadedTile[tile.id] || _cache3.inflightTile[tile.id]) + return; + let [x, y, z] = tile.xyz; + let url = `${_osmoseUrlRoot}/issues/${z}/${x}/${y}.geojson?` + utilQsString(params); + let controller = new AbortController(); + _cache3.inflightTile[tile.id] = controller; + json_default(url, { signal: controller.signal }).then((data) => { + delete _cache3.inflightTile[tile.id]; + _cache3.loadedTile[tile.id] = true; + if (data.features) { + data.features.forEach((issue) => { + const { item, class: cl, uuid: id2 } = issue.properties; + const itemType = `${item}-${cl}`; + if (itemType in _osmoseData.icons) { + let loc = issue.geometry.coordinates; + loc = preventCoincident2(loc); + let d = new QAItem(loc, this, itemType, id2, { item }); + if (item === 8300 || item === 8360) { + d.elems = []; + } + _cache3.data[d.id] = d; + _cache3.rtree.insert(encodeIssueRtree3(d)); + } + }); + } + dispatch4.call("loaded"); + }).catch(() => { + delete _cache3.inflightTile[tile.id]; + _cache3.loadedTile[tile.id] = true; + }); + }); + }, + loadIssueDetail(issue) { + if (issue.elems !== void 0) { + return Promise.resolve(issue); } - _stack = _stack.slice(0, _index + 1); - var actionResult = _act(args, t); - _stack.push(actionResult); - _index++; - return change(previous); + const url = `${_osmoseUrlRoot}/issue/${issue.id}?langs=${_mainLocalizer.localeCode()}`; + const cacheDetails = (data) => { + issue.elems = data.elems.map((e) => e.type.substring(0, 1) + e.id); + issue.detail = data.subtitle ? marked(data.subtitle.auto) : ""; + this.replaceItem(issue); + }; + return json_default(url).then(cacheDetails).then(() => issue); + }, + loadStrings(locale2 = _mainLocalizer.localeCode()) { + const items = Object.keys(_osmoseData.icons); + if (locale2 in _cache3.strings && Object.keys(_cache3.strings[locale2]).length === items.length) { + return Promise.resolve(_cache3.strings[locale2]); + } + if (!(locale2 in _cache3.strings)) { + _cache3.strings[locale2] = {}; + } + const allRequests = items.map((itemType) => { + if (itemType in _cache3.strings[locale2]) + return null; + const cacheData = (data) => { + const [cat = { items: [] }] = data.categories; + const [item2 = { class: [] }] = cat.items; + const [cl2 = null] = item2.class; + if (!cl2) { + console.log(`Osmose strings request (${itemType}) had unexpected data`); + return; + } + const { item: itemInt, color: color2 } = item2; + if (/^#[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3}/.test(color2)) { + _cache3.colors[itemInt] = color2; + } + const { title, detail, fix, trap } = cl2; + let issueStrings = {}; + if (title) + issueStrings.title = title.auto; + if (detail) + issueStrings.detail = marked(detail.auto); + if (trap) + issueStrings.trap = marked(trap.auto); + if (fix) + issueStrings.fix = marked(fix.auto); + _cache3.strings[locale2][itemType] = issueStrings; + }; + const [item, cl] = itemType.split("-"); + const url = `${_osmoseUrlRoot}/items/${item}/class/${cl}?langs=${locale2}`; + return json_default(url).then(cacheData); + }).filter(Boolean); + return Promise.all(allRequests).then(() => _cache3.strings[locale2]); + }, + getStrings(itemType, locale2 = _mainLocalizer.localeCode()) { + return locale2 in _cache3.strings ? _cache3.strings[locale2][itemType] : {}; + }, + getColor(itemType) { + return itemType in _cache3.colors ? _cache3.colors[itemType] : "#FFFFFF"; + }, + postUpdate(issue, callback) { + if (_cache3.inflightPost[issue.id]) { + return callback({ message: "Issue update already inflight", status: -2 }, issue); + } + const url = `${_osmoseUrlRoot}/issue/${issue.id}/${issue.newStatus}`; + const controller = new AbortController(); + const after = () => { + delete _cache3.inflightPost[issue.id]; + this.removeItem(issue); + if (issue.newStatus === "done") { + if (!(issue.item in _cache3.closed)) { + _cache3.closed[issue.item] = 0; + } + _cache3.closed[issue.item] += 1; + } + if (callback) + callback(null, issue); + }; + _cache3.inflightPost[issue.id] = controller; + fetch(url, { signal: controller.signal }).then(after).catch((err) => { + delete _cache3.inflightPost[issue.id]; + if (callback) + callback(err.message); + }); + }, + // Get all cached QAItems covering the viewport + getItems(projection2) { + const viewport = projection2.clipExtent(); + const min3 = [viewport[0][0], viewport[1][1]]; + const max3 = [viewport[1][0], viewport[0][1]]; + const bbox2 = geoExtent(projection2.invert(min3), projection2.invert(max3)).bbox(); + return _cache3.rtree.search(bbox2).map((d) => d.data); + }, + // Get a QAItem from cache + // NOTE: Don't change method name until UI v3 is merged + getError(id2) { + return _cache3.data[id2]; + }, + // get the name of the icon to display for this item + getIcon(itemType) { + return _osmoseData.icons[itemType]; + }, + // Replace a single QAItem in the cache + replaceItem(item) { + if (!(item instanceof QAItem) || !item.id) + return; + _cache3.data[item.id] = item; + updateRtree3(encodeIssueRtree3(item), true); + return item; + }, + // Remove a single QAItem from the cache + removeItem(item) { + if (!(item instanceof QAItem) || !item.id) + return; + delete _cache3.data[item.id]; + updateRtree3(encodeIssueRtree3(item), false); + }, + // Used to populate `closed:osmose:*` changeset tags + getClosedCounts() { + return _cache3.closed; + }, + itemURL(item) { + return `https://osmose.openstreetmap.fr/en/error/${item.id}`; } - function change(previous) { - var difference = coreDifference(previous, history.graph()); - if (!_pausedGraph) { - dispatch10.call("change", this, difference); + }; + + // modules/services/mapillary.js + var import_pbf = __toESM(require_pbf()); + var import_rbush4 = __toESM(require_rbush_min()); + var import_vector_tile = __toESM(require_vector_tile()); + var accessToken = "MLY|4100327730013843|5bb78b81720791946a9a7b956c57b7cf"; + var apiUrl = "https://graph.mapillary.com/"; + var baseTileUrl = "https://tiles.mapillary.com/maps/vtp"; + var mapFeatureTileUrl = `${baseTileUrl}/mly_map_feature_point/2/{z}/{x}/{y}?access_token=${accessToken}`; + var tileUrl = `${baseTileUrl}/mly1_public/2/{z}/{x}/{y}?access_token=${accessToken}`; + var trafficSignTileUrl = `${baseTileUrl}/mly_map_feature_traffic_sign/2/{z}/{x}/{y}?access_token=${accessToken}`; + var viewercss = "mapillary-js/mapillary.css"; + var viewerjs = "mapillary-js/mapillary.js"; + var minZoom = 14; + var dispatch5 = dispatch_default("change", "loadedImages", "loadedSigns", "loadedMapFeatures", "bearingChanged", "imageChanged"); + var _loadViewerPromise; + var _mlyActiveImage; + var _mlyCache; + var _mlyFallback = false; + var _mlyHighlightedDetection; + var _mlyShowFeatureDetections = false; + var _mlyShowSignDetections = false; + var _mlyViewer; + var _mlyViewerFilter = ["all"]; + function loadTiles(which, url, maxZoom2, projection2) { + const tiler8 = utilTiler().zoomExtent([minZoom, maxZoom2]).skipNullIsland(true); + const tiles = tiler8.getTiles(projection2); + tiles.forEach(function(tile) { + loadTile(which, url, tile); + }); + } + function loadTile(which, url, tile) { + const cache = _mlyCache.requests; + const tileId = `${tile.id}-${which}`; + if (cache.loaded[tileId] || cache.inflight[tileId]) + return; + const controller = new AbortController(); + cache.inflight[tileId] = controller; + const requestUrl = url.replace("{x}", tile.xyz[0]).replace("{y}", tile.xyz[1]).replace("{z}", tile.xyz[2]); + fetch(requestUrl, { signal: controller.signal }).then(function(response) { + if (!response.ok) { + throw new Error(response.status + " " + response.statusText); + } + cache.loaded[tileId] = true; + delete cache.inflight[tileId]; + return response.arrayBuffer(); + }).then(function(data) { + if (!data) { + throw new Error("No Data"); + } + loadTileDataToCache(data, tile, which); + if (which === "images") { + dispatch5.call("loadedImages"); + } else if (which === "signs") { + dispatch5.call("loadedSigns"); + } else if (which === "points") { + dispatch5.call("loadedMapFeatures"); + } + }).catch(function() { + cache.loaded[tileId] = true; + delete cache.inflight[tileId]; + }); + } + function loadTileDataToCache(data, tile, which) { + const vectorTile = new import_vector_tile.VectorTile(new import_pbf.default(data)); + let features, cache, layer, i2, feature3, loc, d; + if (vectorTile.layers.hasOwnProperty("image")) { + features = []; + cache = _mlyCache.images; + layer = vectorTile.layers.image; + for (i2 = 0; i2 < layer.length; i2++) { + feature3 = layer.feature(i2).toGeoJSON(tile.xyz[0], tile.xyz[1], tile.xyz[2]); + loc = feature3.geometry.coordinates; + d = { + loc, + captured_at: feature3.properties.captured_at, + ca: feature3.properties.compass_angle, + id: feature3.properties.id, + is_pano: feature3.properties.is_pano, + sequence_id: feature3.properties.sequence_id + }; + cache.forImageId[d.id] = d; + features.push({ + minX: loc[0], + minY: loc[1], + maxX: loc[0], + maxY: loc[1], + data: d + }); + } + if (cache.rtree) { + cache.rtree.load(features); } - return difference; } - function getKey(n2) { - return "iD_" + window.location.origin + "_" + n2; + if (vectorTile.layers.hasOwnProperty("sequence")) { + features = []; + cache = _mlyCache.sequences; + layer = vectorTile.layers.sequence; + for (i2 = 0; i2 < layer.length; i2++) { + feature3 = layer.feature(i2).toGeoJSON(tile.xyz[0], tile.xyz[1], tile.xyz[2]); + if (cache.lineString[feature3.properties.id]) { + cache.lineString[feature3.properties.id].push(feature3); + } else { + cache.lineString[feature3.properties.id] = [feature3]; + } + } } - var history = { - graph: function() { - return _stack[_index].graph; - }, - tree: function() { - return _tree; - }, - base: function() { - return _stack[0].graph; - }, - merge: function(entities) { - var stack = _stack.map(function(state) { - return state.graph; + if (vectorTile.layers.hasOwnProperty("point")) { + features = []; + cache = _mlyCache[which]; + layer = vectorTile.layers.point; + for (i2 = 0; i2 < layer.length; i2++) { + feature3 = layer.feature(i2).toGeoJSON(tile.xyz[0], tile.xyz[1], tile.xyz[2]); + loc = feature3.geometry.coordinates; + d = { + loc, + id: feature3.properties.id, + first_seen_at: feature3.properties.first_seen_at, + last_seen_at: feature3.properties.last_seen_at, + value: feature3.properties.value + }; + features.push({ + minX: loc[0], + minY: loc[1], + maxX: loc[0], + maxY: loc[1], + data: d }); - _stack[0].graph.rebase(entities, stack, false); - _tree.rebase(entities, false); - dispatch10.call("merge", this, entities); + } + if (cache.rtree) { + cache.rtree.load(features); + } + } + if (vectorTile.layers.hasOwnProperty("traffic_sign")) { + features = []; + cache = _mlyCache[which]; + layer = vectorTile.layers.traffic_sign; + for (i2 = 0; i2 < layer.length; i2++) { + feature3 = layer.feature(i2).toGeoJSON(tile.xyz[0], tile.xyz[1], tile.xyz[2]); + loc = feature3.geometry.coordinates; + d = { + loc, + id: feature3.properties.id, + first_seen_at: feature3.properties.first_seen_at, + last_seen_at: feature3.properties.last_seen_at, + value: feature3.properties.value + }; + features.push({ + minX: loc[0], + minY: loc[1], + maxX: loc[0], + maxY: loc[1], + data: d + }); + } + if (cache.rtree) { + cache.rtree.load(features); + } + } + } + function loadData(url) { + return fetch(url).then(function(response) { + if (!response.ok) { + throw new Error(response.status + " " + response.statusText); + } + return response.json(); + }).then(function(result) { + if (!result) { + return []; + } + return result.data || []; + }); + } + function partitionViewport(projection2) { + const z = geoScaleToZoom(projection2.scale()); + const z2 = Math.ceil(z * 2) / 2 + 2.5; + const tiler8 = utilTiler().zoomExtent([z2, z2]); + return tiler8.getTiles(projection2).map(function(tile) { + return tile.extent; + }); + } + function searchLimited(limit, projection2, rtree) { + limit = limit || 5; + return partitionViewport(projection2).reduce(function(result, extent) { + const found = rtree.search(extent.bbox()).slice(0, limit).map(function(d) { + return d.data; + }); + return found.length ? result.concat(found) : result; + }, []); + } + var mapillary_default = { + // Initialize Mapillary + init: function() { + if (!_mlyCache) { + this.reset(); + } + this.event = utilRebind(this, dispatch5, "on"); + }, + // Reset cache and state + reset: function() { + if (_mlyCache) { + Object.values(_mlyCache.requests.inflight).forEach(function(request3) { + request3.abort(); + }); + } + _mlyCache = { + images: { rtree: new import_rbush4.default(), forImageId: {} }, + image_detections: { forImageId: {} }, + signs: { rtree: new import_rbush4.default() }, + points: { rtree: new import_rbush4.default() }, + sequences: { rtree: new import_rbush4.default(), lineString: {} }, + requests: { loaded: {}, inflight: {} } + }; + _mlyActiveImage = null; + }, + // Get visible images + images: function(projection2) { + const limit = 5; + return searchLimited(limit, projection2, _mlyCache.images.rtree); + }, + // Get visible traffic signs + signs: function(projection2) { + const limit = 5; + return searchLimited(limit, projection2, _mlyCache.signs.rtree); + }, + // Get visible map (point) features + mapFeatures: function(projection2) { + const limit = 5; + return searchLimited(limit, projection2, _mlyCache.points.rtree); + }, + // Get cached image by id + cachedImage: function(imageId) { + return _mlyCache.images.forImageId[imageId]; + }, + // Get visible sequences + sequences: function(projection2) { + const viewport = projection2.clipExtent(); + const min3 = [viewport[0][0], viewport[1][1]]; + const max3 = [viewport[1][0], viewport[0][1]]; + const bbox2 = geoExtent(projection2.invert(min3), projection2.invert(max3)).bbox(); + const sequenceIds = {}; + let lineStrings = []; + _mlyCache.images.rtree.search(bbox2).forEach(function(d) { + if (d.data.sequence_id) { + sequenceIds[d.data.sequence_id] = true; + } + }); + Object.keys(sequenceIds).forEach(function(sequenceId) { + if (_mlyCache.sequences.lineString[sequenceId]) { + lineStrings = lineStrings.concat(_mlyCache.sequences.lineString[sequenceId]); + } + }); + return lineStrings; + }, + // Load images in the visible area + loadImages: function(projection2) { + loadTiles("images", tileUrl, 14, projection2); + }, + // Load traffic signs in the visible area + loadSigns: function(projection2) { + loadTiles("signs", trafficSignTileUrl, 14, projection2); + }, + // Load map (point) features in the visible area + loadMapFeatures: function(projection2) { + loadTiles("points", mapFeatureTileUrl, 14, projection2); + }, + // Return a promise that resolves when the image viewer (Mapillary JS) library has finished loading + ensureViewerLoaded: function(context) { + if (_loadViewerPromise) + return _loadViewerPromise; + const wrap2 = context.container().select(".photoviewer").selectAll(".mly-wrapper").data([0]); + wrap2.enter().append("div").attr("id", "ideditor-mly").attr("class", "photo-wrapper mly-wrapper").classed("hide", true); + const that = this; + _loadViewerPromise = new Promise((resolve, reject) => { + let loadedCount = 0; + function loaded() { + loadedCount += 1; + if (loadedCount === 2) + resolve(); + } + const head = select_default2("head"); + head.selectAll("#ideditor-mapillary-viewercss").data([0]).enter().append("link").attr("id", "ideditor-mapillary-viewercss").attr("rel", "stylesheet").attr("crossorigin", "anonymous").attr("href", context.asset(viewercss)).on("load.serviceMapillary", loaded).on("error.serviceMapillary", function() { + reject(); + }); + head.selectAll("#ideditor-mapillary-viewerjs").data([0]).enter().append("script").attr("id", "ideditor-mapillary-viewerjs").attr("crossorigin", "anonymous").attr("src", context.asset(viewerjs)).on("load.serviceMapillary", loaded).on("error.serviceMapillary", function() { + reject(); + }); + }).catch(function() { + _loadViewerPromise = null; + }).then(function() { + that.initViewer(context); + }); + return _loadViewerPromise; + }, + // Load traffic sign image sprites + loadSignResources: function(context) { + context.ui().svgDefs.addSprites( + ["mapillary-sprite"], + false + /* don't override colors */ + ); + return this; + }, + // Load map (point) feature image sprites + loadObjectResources: function(context) { + context.ui().svgDefs.addSprites( + ["mapillary-object-sprite"], + false + /* don't override colors */ + ); + return this; + }, + // Remove previous detections in image viewer + resetTags: function() { + if (_mlyViewer && !_mlyFallback) { + _mlyViewer.getComponent("tag").removeAll(); + } + }, + // Show map feature detections in image viewer + showFeatureDetections: function(value) { + _mlyShowFeatureDetections = value; + if (!_mlyShowFeatureDetections && !_mlyShowSignDetections) { + this.resetTags(); + } + }, + // Show traffic sign detections in image viewer + showSignDetections: function(value) { + _mlyShowSignDetections = value; + if (!_mlyShowFeatureDetections && !_mlyShowSignDetections) { + this.resetTags(); + } + }, + // Apply filter to image viewer + filterViewer: function(context) { + const showsPano = context.photos().showsPanoramic(); + const showsFlat = context.photos().showsFlat(); + const fromDate = context.photos().fromDate(); + const toDate = context.photos().toDate(); + const filter2 = ["all"]; + if (!showsPano) + filter2.push(["!=", "cameraType", "spherical"]); + if (!showsFlat && showsPano) + filter2.push(["==", "pano", true]); + if (fromDate) { + filter2.push([">=", "capturedAt", new Date(fromDate).getTime()]); + } + if (toDate) { + filter2.push([">=", "capturedAt", new Date(toDate).getTime()]); + } + if (_mlyViewer) { + _mlyViewer.setFilter(filter2); + } + _mlyViewerFilter = filter2; + return filter2; + }, + // Make the image viewer visible + showViewer: function(context) { + const wrap2 = context.container().select(".photoviewer").classed("hide", false); + const isHidden = wrap2.selectAll(".photo-wrapper.mly-wrapper.hide").size(); + if (isHidden && _mlyViewer) { + wrap2.selectAll(".photo-wrapper:not(.mly-wrapper)").classed("hide", true); + wrap2.selectAll(".photo-wrapper.mly-wrapper").classed("hide", false); + _mlyViewer.resize(); + } + return this; + }, + // Hide the image viewer and resets map markers + hideViewer: function(context) { + _mlyActiveImage = null; + if (!_mlyFallback && _mlyViewer) { + _mlyViewer.getComponent("sequence").stop(); + } + const viewer = context.container().select(".photoviewer"); + if (!viewer.empty()) + viewer.datum(null); + viewer.classed("hide", true).selectAll(".photo-wrapper").classed("hide", true); + this.updateUrlImage(null); + dispatch5.call("imageChanged"); + dispatch5.call("loadedMapFeatures"); + dispatch5.call("loadedSigns"); + return this.setStyles(context, null); + }, + // Update the URL with current image id + updateUrlImage: function(imageId) { + if (!window.mocha) { + const hash = utilStringQs(window.location.hash); + if (imageId) { + hash.photo = "mapillary/" + imageId; + } else { + delete hash.photo; + } + window.location.replace("#" + utilQsString(hash, true)); + } + }, + // Highlight the detection in the viewer that is related to the clicked map feature + highlightDetection: function(detection) { + if (detection) { + _mlyHighlightedDetection = detection.id; + } + return this; + }, + // Initialize image viewer (Mapillar JS) + initViewer: function(context) { + const that = this; + if (!window.mapillary) + return; + const opts = { + accessToken, + component: { + cover: false, + keyboard: false, + tag: true + }, + container: "ideditor-mly" + }; + if (!mapillary.isSupported() && mapillary.isFallbackSupported()) { + _mlyFallback = true; + opts.component = { + cover: false, + direction: false, + imagePlane: false, + keyboard: false, + mouse: false, + sequence: false, + tag: false, + image: true, + // fallback + navigation: true + // fallback + }; + } + _mlyViewer = new mapillary.Viewer(opts); + _mlyViewer.on("image", imageChanged); + _mlyViewer.on("bearing", bearingChanged); + if (_mlyViewerFilter) { + _mlyViewer.setFilter(_mlyViewerFilter); + } + context.ui().photoviewer.on("resize.mapillary", function() { + if (_mlyViewer) + _mlyViewer.resize(); + }); + function imageChanged(node) { + that.resetTags(); + const image = node.image; + that.setActiveImage(image); + that.setStyles(context, null); + const loc = [image.originalLngLat.lng, image.originalLngLat.lat]; + context.map().centerEase(loc); + that.updateUrlImage(image.id); + if (_mlyShowFeatureDetections || _mlyShowSignDetections) { + that.updateDetections(image.id, `${apiUrl}/${image.id}/detections?access_token=${accessToken}&fields=id,image,geometry,value`); + } + dispatch5.call("imageChanged"); + } + function bearingChanged(e) { + dispatch5.call("bearingChanged", void 0, e); + } + }, + // Move to an image + selectImage: function(context, imageId) { + if (_mlyViewer && imageId) { + _mlyViewer.moveTo(imageId).catch(function(e) { + console.error("mly3", e); + }); + } + return this; + }, + // Return the currently displayed image + getActiveImage: function() { + return _mlyActiveImage; + }, + // Return a list of detection objects for the given id + getDetections: function(id2) { + return loadData(`${apiUrl}/${id2}/detections?access_token=${accessToken}&fields=id,value,image`); + }, + // Set the currently visible image + setActiveImage: function(image) { + if (image) { + _mlyActiveImage = { + ca: image.originalCompassAngle, + id: image.id, + loc: [image.originalLngLat.lng, image.originalLngLat.lat], + is_pano: image.cameraType === "spherical", + sequence_id: image.sequenceId + }; + } else { + _mlyActiveImage = null; + } + }, + // Update the currently highlighted sequence and selected bubble. + setStyles: function(context, hovered) { + const hoveredImageId = hovered && hovered.id; + const hoveredSequenceId = hovered && hovered.sequence_id; + const selectedSequenceId = _mlyActiveImage && _mlyActiveImage.sequence_id; + context.container().selectAll(".layer-mapillary .viewfield-group").classed("highlighted", function(d) { + return d.sequence_id === selectedSequenceId || d.id === hoveredImageId; + }).classed("hovered", function(d) { + return d.id === hoveredImageId; + }); + context.container().selectAll(".layer-mapillary .sequence").classed("highlighted", function(d) { + return d.properties.id === hoveredSequenceId; + }).classed("currentView", function(d) { + return d.properties.id === selectedSequenceId; + }); + return this; + }, + // Get detections for the current image and shows them in the image viewer + updateDetections: function(imageId, url) { + if (!_mlyViewer || _mlyFallback) + return; + if (!imageId) + return; + const cache = _mlyCache.image_detections; + if (cache.forImageId[imageId]) { + showDetections(_mlyCache.image_detections.forImageId[imageId]); + } else { + loadData(url).then((detections) => { + detections.forEach(function(detection) { + if (!cache.forImageId[imageId]) { + cache.forImageId[imageId] = []; + } + cache.forImageId[imageId].push({ + geometry: detection.geometry, + id: detection.id, + image_id: imageId, + value: detection.value + }); + }); + showDetections(_mlyCache.image_detections.forImageId[imageId] || []); + }); + } + function showDetections(detections) { + const tagComponent = _mlyViewer.getComponent("tag"); + detections.forEach(function(data) { + const tag = makeTag(data); + if (tag) { + tagComponent.add([tag]); + } + }); + } + function makeTag(data) { + const valueParts = data.value.split("--"); + if (!valueParts.length) + return; + let tag; + let text2; + let color2 = 16777215; + if (_mlyHighlightedDetection === data.id) { + color2 = 16776960; + text2 = valueParts[1]; + if (text2 === "flat" || text2 === "discrete" || text2 === "sign") { + text2 = valueParts[2]; + } + text2 = text2.replace(/-/g, " "); + text2 = text2.charAt(0).toUpperCase() + text2.slice(1); + _mlyHighlightedDetection = null; + } + var decodedGeometry = window.atob(data.geometry); + var uintArray = new Uint8Array(decodedGeometry.length); + for (var i2 = 0; i2 < decodedGeometry.length; i2++) { + uintArray[i2] = decodedGeometry.charCodeAt(i2); + } + const tile = new import_vector_tile.VectorTile(new import_pbf.default(uintArray.buffer)); + const layer = tile.layers["mpy-or"]; + const geometries = layer.feature(0).loadGeometry(); + const polygon2 = geometries.map((ring) => ring.map((point2) => [point2.x / layer.extent, point2.y / layer.extent])); + tag = new mapillary.OutlineTag( + data.id, + new mapillary.PolygonGeometry(polygon2[0]), + { + text: text2, + textColor: color2, + lineColor: color2, + lineWidth: 2, + fillColor: color2, + fillOpacity: 0.3 + } + ); + return tag; + } + }, + // Return the current cache + cache: function() { + return _mlyCache; + } + }; + + // modules/core/validation/models.js + function validationIssue(attrs) { + this.type = attrs.type; + this.subtype = attrs.subtype; + this.severity = attrs.severity; + this.message = attrs.message; + this.reference = attrs.reference; + this.entityIds = attrs.entityIds; + this.loc = attrs.loc; + this.data = attrs.data; + this.dynamicFixes = attrs.dynamicFixes; + this.hash = attrs.hash; + this.id = generateID.apply(this); + this.key = generateKey.apply(this); + this.autoFix = null; + function generateID() { + var parts = [this.type]; + if (this.hash) { + parts.push(this.hash); + } + if (this.subtype) { + parts.push(this.subtype); + } + if (this.entityIds) { + var entityKeys = this.entityIds.slice().sort(); + parts.push.apply(parts, entityKeys); + } + return parts.join(":"); + } + function generateKey() { + return this.id + ":" + Date.now().toString(); + } + this.extent = function(resolver) { + if (this.loc) { + return geoExtent(this.loc); + } + if (this.entityIds && this.entityIds.length) { + return this.entityIds.reduce(function(extent, entityId) { + return extent.extend(resolver.entity(entityId).extent(resolver)); + }, geoExtent()); + } + return null; + }; + this.fixes = function(context) { + var fixes = this.dynamicFixes ? this.dynamicFixes(context) : []; + var issue = this; + if (issue.severity === "warning") { + fixes.push(new validationIssueFix({ + title: _t.append("issues.fix.ignore_issue.title"), + icon: "iD-icon-close", + onClick: function() { + context.validator().ignoreIssue(this.issue.id); + } + })); + } + fixes.forEach(function(fix) { + fix.id = fix.title.stringId; + fix.issue = issue; + if (fix.autoArgs) { + issue.autoFix = fix; + } + }); + return fixes; + }; + } + function validationIssueFix(attrs) { + this.title = attrs.title; + this.onClick = attrs.onClick; + this.disabledReason = attrs.disabledReason; + this.icon = attrs.icon; + this.entityIds = attrs.entityIds || []; + this.autoArgs = attrs.autoArgs; + this.issue = null; + } + + // modules/services/maprules.js + var buildRuleChecks = function() { + return { + equals: function(equals) { + return function(tags) { + return Object.keys(equals).every(function(k) { + return equals[k] === tags[k]; + }); + }; + }, + notEquals: function(notEquals) { + return function(tags) { + return Object.keys(notEquals).some(function(k) { + return notEquals[k] !== tags[k]; + }); + }; + }, + absence: function(absence) { + return function(tags) { + return Object.keys(tags).indexOf(absence) === -1; + }; + }, + presence: function(presence) { + return function(tags) { + return Object.keys(tags).indexOf(presence) > -1; + }; + }, + greaterThan: function(greaterThan) { + var key = Object.keys(greaterThan)[0]; + var value = greaterThan[key]; + return function(tags) { + return tags[key] > value; + }; + }, + greaterThanEqual: function(greaterThanEqual) { + var key = Object.keys(greaterThanEqual)[0]; + var value = greaterThanEqual[key]; + return function(tags) { + return tags[key] >= value; + }; + }, + lessThan: function(lessThan) { + var key = Object.keys(lessThan)[0]; + var value = lessThan[key]; + return function(tags) { + return tags[key] < value; + }; + }, + lessThanEqual: function(lessThanEqual) { + var key = Object.keys(lessThanEqual)[0]; + var value = lessThanEqual[key]; + return function(tags) { + return tags[key] <= value; + }; + }, + positiveRegex: function(positiveRegex) { + var tagKey = Object.keys(positiveRegex)[0]; + var expression = positiveRegex[tagKey].join("|"); + var regex = new RegExp(expression); + return function(tags) { + return regex.test(tags[tagKey]); + }; + }, + negativeRegex: function(negativeRegex) { + var tagKey = Object.keys(negativeRegex)[0]; + var expression = negativeRegex[tagKey].join("|"); + var regex = new RegExp(expression); + return function(tags) { + return !regex.test(tags[tagKey]); + }; + } + }; + }; + var buildLineKeys = function() { + return { + highway: { + rest_area: true, + services: true + }, + railway: { + roundhouse: true, + station: true, + traverser: true, + turntable: true, + wash: true + } + }; + }; + var maprules_default = { + init: function() { + this._ruleChecks = buildRuleChecks(); + this._validationRules = []; + this._areaKeys = osmAreaKeys; + this._lineKeys = buildLineKeys(); + }, + // list of rules only relevant to tag checks... + filterRuleChecks: function(selector) { + var _ruleChecks = this._ruleChecks; + return Object.keys(selector).reduce(function(rules, key) { + if (["geometry", "error", "warning"].indexOf(key) === -1) { + rules.push(_ruleChecks[key](selector[key])); + } + return rules; + }, []); + }, + // builds tagMap from mapcss-parse selector object... + buildTagMap: function(selector) { + var getRegexValues = function(regexes) { + return regexes.map(function(regex) { + return regex.replace(/\$|\^/g, ""); + }); + }; + var tagMap = Object.keys(selector).reduce(function(expectedTags, key) { + var values; + var isRegex = /regex/gi.test(key); + var isEqual4 = /equals/gi.test(key); + if (isRegex || isEqual4) { + Object.keys(selector[key]).forEach(function(selectorKey) { + values = isEqual4 ? [selector[key][selectorKey]] : getRegexValues(selector[key][selectorKey]); + if (expectedTags.hasOwnProperty(selectorKey)) { + values = values.concat(expectedTags[selectorKey]); + } + expectedTags[selectorKey] = values; + }); + } else if (/(greater|less)Than(Equal)?|presence/g.test(key)) { + var tagKey = /presence/.test(key) ? selector[key] : Object.keys(selector[key])[0]; + values = [selector[key][tagKey]]; + if (expectedTags.hasOwnProperty(tagKey)) { + values = values.concat(expectedTags[tagKey]); + } + expectedTags[tagKey] = values; + } + return expectedTags; + }, {}); + return tagMap; + }, + // inspired by osmWay#isArea() + inferGeometry: function(tagMap) { + var _lineKeys = this._lineKeys; + var _areaKeys = this._areaKeys; + var keyValueDoesNotImplyArea = function(key2) { + return utilArrayIntersection(tagMap[key2], Object.keys(_areaKeys[key2])).length > 0; + }; + var keyValueImpliesLine = function(key2) { + return utilArrayIntersection(tagMap[key2], Object.keys(_lineKeys[key2])).length > 0; + }; + if (tagMap.hasOwnProperty("area")) { + if (tagMap.area.indexOf("yes") > -1) { + return "area"; + } + if (tagMap.area.indexOf("no") > -1) { + return "line"; + } + } + for (var key in tagMap) { + if (key in _areaKeys && !keyValueDoesNotImplyArea(key)) { + return "area"; + } + if (key in _lineKeys && keyValueImpliesLine(key)) { + return "area"; + } + } + return "line"; + }, + // adds from mapcss-parse selector check... + addRule: function(selector) { + var rule = { + // checks relevant to mapcss-selector + checks: this.filterRuleChecks(selector), + // true if all conditions for a tag error are true.. + matches: function(entity) { + return this.checks.every(function(check) { + return check(entity.tags); + }); + }, + // borrowed from Way#isArea() + inferredGeometry: this.inferGeometry(this.buildTagMap(selector), this._areaKeys), + geometryMatches: function(entity, graph) { + if (entity.type === "node" || entity.type === "relation") { + return selector.geometry === entity.type; + } else if (entity.type === "way") { + return this.inferredGeometry === entity.geometry(graph); + } + }, + // when geometries match and tag matches are present, return a warning... + findIssues: function(entity, graph, issues) { + if (this.geometryMatches(entity, graph) && this.matches(entity)) { + var severity = Object.keys(selector).indexOf("error") > -1 ? "error" : "warning"; + var message = selector[severity]; + issues.push(new validationIssue({ + type: "maprules", + severity, + message: function() { + return message; + }, + entityIds: [entity.id] + })); + } + } + }; + this._validationRules.push(rule); + }, + clearRules: function() { + this._validationRules = []; + }, + // returns validationRules... + validationRules: function() { + return this._validationRules; + }, + // returns ruleChecks + ruleChecks: function() { + return this._ruleChecks; + } + }; + + // modules/services/nominatim.js + var import_rbush7 = __toESM(require_rbush_min()); + + // modules/core/difference.js + var import_fast_deep_equal3 = __toESM(require_fast_deep_equal()); + function coreDifference(base, head) { + var _changes = {}; + var _didChange = {}; + var _diff = {}; + function checkEntityID(id2) { + var h = head.entities[id2]; + var b = base.entities[id2]; + if (h === b) + return; + if (_changes[id2]) + return; + if (!h && b) { + _changes[id2] = { base: b, head: h }; + _didChange.deletion = true; + return; + } + if (h && !b) { + _changes[id2] = { base: b, head: h }; + _didChange.addition = true; + return; + } + if (h && b) { + if (h.members && b.members && !(0, import_fast_deep_equal3.default)(h.members, b.members)) { + _changes[id2] = { base: b, head: h }; + _didChange.geometry = true; + _didChange.properties = true; + return; + } + if (h.loc && b.loc && !geoVecEqual(h.loc, b.loc)) { + _changes[id2] = { base: b, head: h }; + _didChange.geometry = true; + } + if (h.nodes && b.nodes && !(0, import_fast_deep_equal3.default)(h.nodes, b.nodes)) { + _changes[id2] = { base: b, head: h }; + _didChange.geometry = true; + } + if (h.tags && b.tags && !(0, import_fast_deep_equal3.default)(h.tags, b.tags)) { + _changes[id2] = { base: b, head: h }; + _didChange.properties = true; + } + } + } + function load() { + var ids = utilArrayUniq(Object.keys(head.entities).concat(Object.keys(base.entities))); + for (var i2 = 0; i2 < ids.length; i2++) { + checkEntityID(ids[i2]); + } + } + load(); + _diff.length = function length() { + return Object.keys(_changes).length; + }; + _diff.changes = function changes() { + return _changes; + }; + _diff.didChange = _didChange; + _diff.extantIDs = function extantIDs(includeRelMembers) { + var result = /* @__PURE__ */ new Set(); + Object.keys(_changes).forEach(function(id2) { + if (_changes[id2].head) { + result.add(id2); + } + var h = _changes[id2].head; + var b = _changes[id2].base; + var entity = h || b; + if (includeRelMembers && entity.type === "relation") { + var mh = h ? h.members.map(function(m) { + return m.id; + }) : []; + var mb = b ? b.members.map(function(m) { + return m.id; + }) : []; + utilArrayUnion(mh, mb).forEach(function(memberID) { + if (head.hasEntity(memberID)) { + result.add(memberID); + } + }); + } + }); + return Array.from(result); + }; + _diff.modified = function modified() { + var result = []; + Object.values(_changes).forEach(function(change) { + if (change.base && change.head) { + result.push(change.head); + } + }); + return result; + }; + _diff.created = function created() { + var result = []; + Object.values(_changes).forEach(function(change) { + if (!change.base && change.head) { + result.push(change.head); + } + }); + return result; + }; + _diff.deleted = function deleted() { + var result = []; + Object.values(_changes).forEach(function(change) { + if (change.base && !change.head) { + result.push(change.base); + } + }); + return result; + }; + _diff.summary = function summary() { + var relevant = {}; + var keys2 = Object.keys(_changes); + for (var i2 = 0; i2 < keys2.length; i2++) { + var change = _changes[keys2[i2]]; + 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) { + var moved = !(0, import_fast_deep_equal3.default)(change.base.loc, change.head.loc); + var retagged = !(0, import_fast_deep_equal3.default)(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()) { + addEntity(change.head, head, "created"); + } else if (change.base && change.base.hasInterestingTags()) { + addEntity(change.base, base, "deleted"); + } + } + return Object.values(relevant); + function addEntity(entity, graph, changeType) { + relevant[entity.id] = { + entity, + graph, + changeType + }; + } + function addParents(entity) { + var parents = head.parentWays(entity); + for (var j2 = parents.length - 1; j2 >= 0; j2--) { + var parent = parents[j2]; + if (!(parent.id in relevant)) { + addEntity(parent, head, "modified"); + } + } + } + }; + _diff.complete = function complete(extent) { + var result = {}; + var id2, change; + for (id2 in _changes) { + change = _changes[id2]; + var h = change.head; + var b = change.base; + var entity = h || b; + var i2; + if (extent && (!h || !h.intersects(extent, head)) && (!b || !b.intersects(extent, base))) { + continue; + } + result[id2] = h; + if (entity.type === "way") { + var nh = h ? h.nodes : []; + var nb = b ? b.nodes : []; + var diff; + diff = utilArrayDifference(nh, nb); + for (i2 = 0; i2 < diff.length; i2++) { + result[diff[i2]] = head.hasEntity(diff[i2]); + } + diff = utilArrayDifference(nb, nh); + for (i2 = 0; i2 < diff.length; i2++) { + result[diff[i2]] = head.hasEntity(diff[i2]); + } + } + if (entity.type === "relation" && entity.isMultipolygon()) { + var mh = h ? h.members.map(function(m) { + return m.id; + }) : []; + var mb = b ? b.members.map(function(m) { + return m.id; + }) : []; + var ids = utilArrayUnion(mh, mb); + for (i2 = 0; i2 < ids.length; i2++) { + var member = head.hasEntity(ids[i2]); + if (!member) + continue; + if (extent && !member.intersects(extent, head)) + continue; + result[ids[i2]] = member; + } + } + addParents(head.parentWays(entity), result); + addParents(head.parentRelations(entity), result); + } + return result; + function addParents(parents, result2) { + for (var i3 = 0; i3 < parents.length; i3++) { + var parent = parents[i3]; + if (parent.id in result2) + continue; + result2[parent.id] = parent; + addParents(head.parentRelations(parent), result2); + } + } + }; + return _diff; + } + + // modules/core/tree.js + var import_rbush5 = __toESM(require_rbush_min()); + function coreTree(head) { + var _rtree = new import_rbush5.default(); + var _bboxes = {}; + var _segmentsRTree = new import_rbush5.default(); + var _segmentsBBoxes = {}; + var _segmentsByWayId = {}; + var tree = {}; + function entityBBox(entity) { + var bbox2 = entity.extent(head).bbox(); + bbox2.id = entity.id; + _bboxes[entity.id] = bbox2; + return bbox2; + } + function segmentBBox(segment) { + var extent = segment.extent(head); + if (!extent) + return null; + var bbox2 = extent.bbox(); + bbox2.segment = segment; + _segmentsBBoxes[segment.id] = bbox2; + return bbox2; + } + function removeEntity(entity) { + _rtree.remove(_bboxes[entity.id]); + delete _bboxes[entity.id]; + if (_segmentsByWayId[entity.id]) { + _segmentsByWayId[entity.id].forEach(function(segment) { + _segmentsRTree.remove(_segmentsBBoxes[segment.id]); + delete _segmentsBBoxes[segment.id]; + }); + delete _segmentsByWayId[entity.id]; + } + } + function loadEntities(entities) { + _rtree.load(entities.map(entityBBox)); + var segments = []; + entities.forEach(function(entity) { + if (entity.segments) { + var entitySegments = entity.segments(head); + _segmentsByWayId[entity.id] = entitySegments; + segments = segments.concat(entitySegments); + } + }); + if (segments.length) + _segmentsRTree.load(segments.map(segmentBBox).filter(Boolean)); + } + function updateParents(entity, insertions, memo) { + head.parentWays(entity).forEach(function(way) { + if (_bboxes[way.id]) { + removeEntity(way); + insertions[way.id] = way; + } + updateParents(way, insertions, memo); + }); + head.parentRelations(entity).forEach(function(relation) { + if (memo[entity.id]) + return; + memo[entity.id] = true; + if (_bboxes[relation.id]) { + removeEntity(relation); + insertions[relation.id] = relation; + } + updateParents(relation, insertions, memo); + }); + } + tree.rebase = function(entities, force) { + var insertions = {}; + for (var i2 = 0; i2 < entities.length; i2++) { + var entity = entities[i2]; + if (!entity.visible) + continue; + if (head.entities.hasOwnProperty(entity.id) || _bboxes[entity.id]) { + if (!force) { + continue; + } else if (_bboxes[entity.id]) { + removeEntity(entity); + } + } + insertions[entity.id] = entity; + updateParents(entity, insertions, {}); + } + loadEntities(Object.values(insertions)); + return tree; + }; + function updateToGraph(graph) { + if (graph === head) + return; + var diff = coreDifference(head, graph); + head = graph; + var changed = diff.didChange; + if (!changed.addition && !changed.deletion && !changed.geometry) + return; + var insertions = {}; + if (changed.deletion) { + diff.deleted().forEach(function(entity) { + removeEntity(entity); + }); + } + if (changed.geometry) { + diff.modified().forEach(function(entity) { + removeEntity(entity); + insertions[entity.id] = entity; + updateParents(entity, insertions, {}); + }); + } + if (changed.addition) { + diff.created().forEach(function(entity) { + insertions[entity.id] = entity; + }); + } + loadEntities(Object.values(insertions)); + } + tree.intersects = function(extent, graph) { + updateToGraph(graph); + return _rtree.search(extent.bbox()).map(function(bbox2) { + return graph.entity(bbox2.id); + }); + }; + tree.waySegments = function(extent, graph) { + updateToGraph(graph); + return _segmentsRTree.search(extent.bbox()).map(function(bbox2) { + return bbox2.segment; + }); + }; + return tree; + } + + // modules/svg/icon.js + function svgIcon(name, svgklass, useklass) { + return function drawIcon(selection2) { + selection2.selectAll("svg.icon" + (svgklass ? "." + svgklass.split(" ")[0] : "")).data([0]).enter().append("svg").attr("class", "icon " + (svgklass || "")).append("use").attr("xlink:href", name).attr("class", useklass); + }; + } + + // modules/ui/modal.js + function uiModal(selection2, blocking) { + let keybinding = utilKeybinding("modal"); + let previous = selection2.select("div.modal"); + let animate = previous.empty(); + previous.transition().duration(200).style("opacity", 0).remove(); + let shaded = selection2.append("div").attr("class", "shaded").style("opacity", 0); + shaded.close = () => { + shaded.transition().duration(200).style("opacity", 0).remove(); + modal.transition().duration(200).style("top", "0px"); + select_default2(document).call(keybinding.unbind); + }; + let modal = shaded.append("div").attr("class", "modal fillL"); + modal.append("input").attr("class", "keytrap keytrap-first").on("focus.keytrap", moveFocusToLast); + if (!blocking) { + shaded.on("click.remove-modal", (d3_event) => { + if (d3_event.target === this) { + shaded.close(); + } + }); + modal.append("button").attr("class", "close").attr("title", _t("icons.close")).on("click", shaded.close).call(svgIcon("#iD-icon-close")); + keybinding.on("\u232B", shaded.close).on("\u238B", shaded.close); + select_default2(document).call(keybinding); + } + modal.append("div").attr("class", "content"); + modal.append("input").attr("class", "keytrap keytrap-last").on("focus.keytrap", moveFocusToFirst); + if (animate) { + shaded.transition().style("opacity", 1); + } else { + shaded.style("opacity", 1); + } + return shaded; + function moveFocusToFirst() { + let node = modal.select("a, button, input:not(.keytrap), select, textarea").node(); + if (node) { + node.focus(); + } else { + select_default2(this).node().blur(); + } + } + function moveFocusToLast() { + let nodes = modal.selectAll("a, button, input:not(.keytrap), select, textarea").nodes(); + if (nodes.length) { + nodes[nodes.length - 1].focus(); + } else { + select_default2(this).node().blur(); + } + } + } + + // modules/ui/loading.js + function uiLoading(context) { + let _modalSelection = select_default2(null); + let _message = ""; + let _blocking = false; + let loading = (selection2) => { + _modalSelection = uiModal(selection2, _blocking); + let loadertext = _modalSelection.select(".content").classed("loading-modal", true).append("div").attr("class", "modal-section fillL"); + loadertext.append("img").attr("class", "loader").attr("src", context.imagePath("loader-white.gif")); + loadertext.append("h3").html(_message); + _modalSelection.select("button.close").attr("class", "hide"); + return loading; + }; + loading.message = function(val) { + if (!arguments.length) + return _message; + _message = val; + return loading; + }; + loading.blocking = function(val) { + if (!arguments.length) + return _blocking; + _blocking = val; + return loading; + }; + loading.close = () => { + _modalSelection.remove(); + }; + loading.isShown = () => { + return _modalSelection && !_modalSelection.empty() && _modalSelection.node().parentNode; + }; + return loading; + } + + // modules/core/history.js + function coreHistory(context) { + var dispatch10 = dispatch_default("reset", "change", "merge", "restore", "undone", "redone", "storage_error"); + var lock = utilSessionMutex("lock"); + var _hasUnresolvedRestorableChanges = lock.lock() && !!corePreferences(getKey("saved_history")); + var duration = 150; + var _imageryUsed = []; + var _photoOverlaysUsed = []; + var _checkpoints = {}; + var _pausedGraph; + var _stack; + var _index; + var _tree; + function _act(actions, t) { + actions = Array.prototype.slice.call(actions); + var annotation; + if (typeof actions[actions.length - 1] !== "function") { + annotation = actions.pop(); + } + var graph = _stack[_index].graph; + for (var i2 = 0; i2 < actions.length; i2++) { + graph = actions[i2](graph, t); + } + return { + graph, + annotation, + imageryUsed: _imageryUsed, + photoOverlaysUsed: _photoOverlaysUsed, + transform: context.projection.transform(), + selectedIDs: context.selectedIDs() + }; + } + function _perform(args, t) { + var previous = _stack[_index].graph; + _stack = _stack.slice(0, _index + 1); + var actionResult = _act(args, t); + _stack.push(actionResult); + _index++; + return change(previous); + } + function _replace(args, t) { + var previous = _stack[_index].graph; + var actionResult = _act(args, t); + _stack[_index] = actionResult; + return change(previous); + } + function _overwrite(args, t) { + var previous = _stack[_index].graph; + if (_index > 0) { + _index--; + _stack.pop(); + } + _stack = _stack.slice(0, _index + 1); + var actionResult = _act(args, t); + _stack.push(actionResult); + _index++; + return change(previous); + } + function change(previous) { + var difference = coreDifference(previous, history.graph()); + if (!_pausedGraph) { + dispatch10.call("change", this, difference); + } + return difference; + } + function getKey(n2) { + return "iD_" + window.location.origin + "_" + n2; + } + var history = { + graph: function() { + return _stack[_index].graph; + }, + tree: function() { + return _tree; + }, + base: function() { + return _stack[0].graph; + }, + merge: function(entities) { + var stack = _stack.map(function(state) { + return state.graph; + }); + _stack[0].graph.rebase(entities, stack, false); + _tree.rebase(entities, false); + dispatch10.call("merge", this, entities); }, perform: function() { select_default2(document).interrupt("history.perform"); @@ -39190,6 +40700,7 @@ ${content} select_default2(document).interrupt("history.perform"); return _replace(arguments, 1); }, + // Same as calling pop and then perform overwrite: function() { select_default2(document).interrupt("history.perform"); return _overwrite(arguments, 1); @@ -39206,6 +40717,7 @@ ${content} } return change(previous); }, + // Back to the previous annotated state or _index = 0. undo: function() { select_default2(document).interrupt("history.perform"); var previousStack = _stack[_index]; @@ -39218,6 +40730,7 @@ ${content} dispatch10.call("undone", this, _stack[_index], previousStack); return change(previous); }, + // Forward to the next annotated state. redo: function() { select_default2(document).interrupt("history.perform"); var previousStack = _stack[_index]; @@ -39261,6 +40774,8 @@ ${content} i2++; } }, + // Returns the entities from the active graph with bounding boxes + // overlapping the given `extent`. intersects: function(extent) { return _tree.intersects(extent, _stack[_index].graph); }, @@ -39317,6 +40832,7 @@ ${content} return Array.from(s); } }, + // save the current history state checkpoint: function(key) { _checkpoints[key] = { stack: _stack, @@ -39324,6 +40840,7 @@ ${content} }; return history; }, + // restore history state to a given checkpoint or reset completely reset: function(key) { if (key !== void 0 && _checkpoints.hasOwnProperty(key)) { _stack = _checkpoints[key].stack; @@ -39338,6 +40855,16 @@ ${content} dispatch10.call("change"); return history; }, + // `toIntroGraph()` is used to export the intro graph used by the walkthrough. + // + // To use it: + // 1. Start the walkthrough. + // 2. Get to a "free editing" tutorial step + // 3. Make your edits to the walkthrough map + // 4. In your browser dev console run: + // `id.history().toIntroGraph()` + // 5. This outputs stringified JSON to the browser console + // 6. Copy it to `data/intro_graph.json` and prettify it in your code editor toIntroGraph: function() { var nextID = { n: 0, r: 0, w: 0 }; var permIDs = {}; @@ -39452,7 +40979,8 @@ ${content} stack: s, nextIDs: osmEntity.id.next, index: _index, - timestamp: new Date().getTime() + // note the time the changes were saved + timestamp: (/* @__PURE__ */ new Date()).getTime() }); }, fromJSON: function(json, loadChildNodes) { @@ -39571,13 +41099,15 @@ ${content} lock.unlock(); }, save: function() { - if (lock.locked() && !_hasUnresolvedRestorableChanges) { + if (lock.locked() && // don't overwrite existing, unresolved changes + !_hasUnresolvedRestorableChanges) { const success = corePreferences(getKey("saved_history"), history.toJSON() || null); if (!success) dispatch10.call("storage_error"); } return history; }, + // delete the history version saved in localStorage clearSaved: function() { context.debouncedSave.cancel(); if (lock.locked()) { @@ -39595,6 +41125,7 @@ ${content} hasRestorableChanges: function() { return _hasUnresolvedRestorableChanges; }, + // load history from a version stored in localStorage restore: function() { if (lock.locked()) { _hasUnresolvedRestorableChanges = false; @@ -39632,7 +41163,7 @@ ${content} // modules/validations/almost_junction.js function validationAlmostJunction(context) { - const type3 = "almost_junction"; + const type2 = "almost_junction"; const EXTEND_TH_METERS = 5; const WELD_TH_METERS = 0.75; const CLOSE_NODE_TH = EXTEND_TH_METERS - WELD_TH_METERS; @@ -39653,7 +41184,7 @@ ${content} let issues = []; extendableNodeInfos.forEach((extendableNodeInfo) => { issues.push(new validationIssue({ - type: type3, + type: type2, subtype: "highway-highway", severity: "warning", message: function(context2) { @@ -39871,13 +41402,13 @@ ${content} return null; } }; - validation.type = type3; + validation.type = type2; return validation; } // modules/validations/close_nodes.js function validationCloseNodes(context) { - var type3 = "close_nodes"; + var type2 = "close_nodes"; var pointThresholdMeters = 0.2; var validation = function(entity, graph) { if (entity.type === "node") { @@ -39920,8 +41451,8 @@ ${content} function shouldCheckWay(way) { if (way.nodes.length <= 2 || way.isClosed() && way.nodes.length <= 4) return false; - var bbox = way.extent(graph).bbox(); - var hypotenuseMeters = geoSphericalDistance([bbox.minX, bbox.minY], [bbox.maxX, bbox.maxY]); + var bbox2 = way.extent(graph).bbox(); + var hypotenuseMeters = geoSphericalDistance([bbox2.minX, bbox2.minY], [bbox2.maxX, bbox2.maxY]); if (hypotenuseMeters < 1.5) return false; return true; @@ -40015,7 +41546,7 @@ ${content} if (zAxisDifferentiates) continue; issues.push(new validationIssue({ - type: type3, + type: type2, subtype: "detached", severity: "warning", message: function(context2) { @@ -40067,7 +41598,7 @@ ${content} return null; } return new validationIssue({ - type: type3, + type: type2, subtype: "vertices", severity: "warning", message: function(context2) { @@ -40101,13 +41632,14 @@ ${content} } } }; - validation.type = type3; + validation.type = type2; return validation; } // modules/validations/crossing_ways.js + var import_lodash3 = __toESM(require_lodash()); function validationCrossingWays(context) { - var type3 = "crossing_ways"; + var type2 = "crossing_ways"; function getFeatureWithFeatureTypeTagsForWay(way, graph) { if (getFeatureType(way, graph) === null) { var parentRels = graph.parentRelations(way); @@ -40205,8 +41737,7 @@ ${content} secondary: true, secondary_link: true }; - var nonCrossingHighways = { track: true }; - function tagsForConnectionNodeIfAllowed(entity1, entity2, graph) { + function tagsForConnectionNodeIfAllowed(entity1, entity2, graph, lessLikelyTags) { var featureType1 = getFeatureType(entity1, graph); var featureType2 = getFeatureType(entity2, graph); var geometry1 = entity1.geometry(graph); @@ -40218,11 +41749,14 @@ ${content} var entity2IsPath = osmPathHighwayTagValues[entity2.tags.highway]; if ((entity1IsPath || entity2IsPath) && entity1IsPath !== entity2IsPath) { var roadFeature = entity1IsPath ? entity2 : entity1; - if (nonCrossingHighways[roadFeature.tags.highway]) { + var pathFeature = entity1IsPath ? entity1 : entity2; + if (roadFeature.tags.highway === "track") { return {}; } - var pathFeature = entity1IsPath ? entity1 : entity2; - if (["marked", "unmarked", "traffic_signals"].indexOf(pathFeature.tags.crossing) !== -1) { + if (!lessLikelyTags && roadFeature.tags.highway === "service" && pathFeature.tags.highway === "footway" && pathFeature.tags.footway === "sidewalk") { + return {}; + } + if (["marked", "unmarked", "traffic_signals", "uncontrolled"].indexOf(pathFeature.tags.crossing) !== -1) { return bothLines ? { highway: "crossing", crossing: pathFeature.tags.crossing } : {}; } return bothLines ? { highway: "crossing" } : {}; @@ -40324,8 +41858,8 @@ ${content} continue; segment1 = [n1.loc, n2.loc]; segment2 = [nA.loc, nB.loc]; - var point = geoLineIntersection(segment1, segment2); - if (point) { + var point2 = geoLineIntersection(segment1, segment2); + if (point2) { edgeCrossInfos.push({ wayInfos: [ { @@ -40339,7 +41873,7 @@ ${content} edge: [nA.id, nB.id] } ], - crossPoint: point + crossPoint: point2 }); if (oneOnly) { checkedSingleCrossingWays[way2.id] = true; @@ -40358,7 +41892,8 @@ ${content} return [entity]; } else if (entity.type === "relation") { return entity.members.reduce(function(array2, member) { - if (member.type === "way" && (!member.role || member.role === "outer" || member.role === "inner")) { + if (member.type === "way" && // only look at geometry ways + (!member.role || member.role === "outer" || member.role === "inner")) { var entity2 = graph.hasEntity(member.id); if (entity2 && array2.indexOf(entity2) === -1) { array2.push(entity2); @@ -40420,7 +41955,7 @@ ${content} } var uniqueID = crossing.crossPoint[0].toFixed(4) + "," + crossing.crossPoint[1].toFixed(4); return new validationIssue({ - type: type3, + type: type2, subtype, severity: "warning", message: function(context2) { @@ -40452,6 +41987,10 @@ ${content} var fixes = []; if (connectionTags) { fixes.push(makeConnectWaysFix(this.data.connectionTags)); + let lessLikelyConnectionTags = tagsForConnectionNodeIfAllowed(entities[0], entities[1], graph, true); + if (lessLikelyConnectionTags && !(0, import_lodash3.isEqual)(connectionTags, lessLikelyConnectionTags)) { + fixes.push(makeConnectWaysFix(lessLikelyConnectionTags)); + } } if (isCrossingIndoors) { fixes.push(new validationIssueFix({ @@ -40511,7 +42050,7 @@ ${content} var action = function actionAddStructure(graph) { var edgeNodes = [graph.entity(edge[0]), graph.entity(edge[1])]; var crossedWay = graph.hasEntity(crossedWayID); - var structLengthMeters = crossedWay && crossedWay.tags.width && parseFloat(crossedWay.tags.width); + var structLengthMeters = crossedWay && isFinite(crossedWay.tags.width) && Number(crossedWay.tags.width); if (!structLengthMeters) { structLengthMeters = crossedWay && crossedWay.impliedLineWidthMeters(); } @@ -40630,19 +42169,24 @@ ${content} } function makeConnectWaysFix(connectionTags) { var fixTitleID = "connect_features"; + var fixIcon = "iD-icon-crossing"; + if (connectionTags.highway === "crossing") { + fixTitleID = "connect_using_crossing"; + fixIcon = "temaki-pedestrian"; + } if (connectionTags.ford) { fixTitleID = "connect_using_ford"; + fixIcon = "roentgen-ford"; } - return new validationIssueFix({ - icon: "iD-icon-crossing", + const fix = new validationIssueFix({ + icon: fixIcon, title: _t.append("issues.fix." + fixTitleID + ".title"), onClick: function(context2) { var loc = this.issue.loc; - var connectionTags2 = this.issue.data.connectionTags; var edges = this.issue.data.edges; context2.perform( function actionConnectCrossingWays(graph) { - var node = osmNode({ loc, tags: connectionTags2 }); + var node = osmNode({ loc, tags: connectionTags }); graph = graph.replace(node); var nodesToMerge = [node.id]; var mergeThresholdInMeters = 0.75; @@ -40664,6 +42208,8 @@ ${content} ); } }); + fix._connectionTags = connectionTags; + return fix; } function makeChangeLayerFix(higherOrLower) { return new validationIssueFix({ @@ -40707,7 +42253,7 @@ ${content} } }); } - validation.type = type3; + validation.type = type2; return validation; } @@ -40782,7 +42328,10 @@ ${content} } context.replace(actionMoveNode(_drawNode.id, loc), _annotation); _drawNode = context.entity(_drawNode.id); - checkGeometry(true); + checkGeometry( + true + /* includeDrawNode */ + ); } function checkGeometry(includeDrawNode) { var nopeDisabled = context.surface().classed("nope-disabled"); @@ -40895,7 +42444,10 @@ ${content} } else { createDrawNode(loc); } - checkGeometry(true); + checkGeometry( + true + /* includeDrawNode */ + ); if (d && d.properties && d.properties.nope || context.surface().classed("nope")) { if (!_pointerHasMoved) { removeDrawNode(); @@ -40922,7 +42474,8 @@ ${content} }); }; drawWay.addNode = function(node, d) { - if (node.id === _headNodeID || _origWay.isClosed() && node.id === _origWay.first()) { + if (node.id === _headNodeID || // or the first node when drawing an area + _origWay.isClosed() && node.id === _origWay.first()) { drawWay.finish(); return; } @@ -40985,7 +42538,10 @@ ${content} keybinding.on(_t("operations.follow.key"), followMode); select_default2(document).call(keybinding); drawWay.finish = function() { - checkGeometry(false); + checkGeometry( + false + /* includeDrawNode */ + ); if (context.surface().classed("nope")) { dispatch10.call("rejectedSelfIntersection", this); return; @@ -41058,7 +42614,7 @@ ${content} // modules/validations/disconnected_way.js function validationDisconnectedWay() { - var type3 = "disconnected_way"; + var type2 = "disconnected_way"; function isTaggedAsHighway(entity) { return osmRoutableHighwayTagValues[entity.tags.highway]; } @@ -41067,7 +42623,7 @@ ${content} if (!routingIslandWays) return []; return [new validationIssue({ - type: type3, + type: type2, subtype: "highway", severity: "warning", message: function(context) { @@ -41126,7 +42682,8 @@ ${content} var waysToCheck = []; function queueParentWays(node) { graph.parentWays(node).forEach(function(parentWay) { - if (!routingIsland.has(parentWay) && isRoutableWay(parentWay, false)) { + if (!routingIsland.has(parentWay) && // only check each feature once + isRoutableWay(parentWay, false)) { routingIsland.add(parentWay); waysToCheck.push(parentWay); } @@ -41210,13 +42767,13 @@ ${content} }); } }; - validation.type = type3; + validation.type = type2; return validation; } // modules/validations/invalid_format.js function validationFormatting() { - var type3 = "invalid_format"; + var type2 = "invalid_format"; var validation = function(entity) { var issues = []; function isValidEmail(email) { @@ -41234,7 +42791,7 @@ ${content} }); if (emails.length) { issues.push(new validationIssue({ - type: type3, + type: type2, subtype: "email", severity: "warning", message: function(context) { @@ -41253,13 +42810,13 @@ ${content} } return issues; }; - validation.type = type3; + validation.type = type2; return validation; } // modules/validations/help_request.js function validationHelpRequest(context) { - var type3 = "help_request"; + var type2 = "help_request"; var validation = function checkFixmeTag(entity) { if (!entity.tags.fixme) return []; @@ -41271,13 +42828,18 @@ ${content} return []; } return [new validationIssue({ - type: type3, + type: type2, subtype: "fixme_tag", severity: "warning", message: function(context2) { var entity2 = context2.hasEntity(this.entityIds[0]); return entity2 ? _t.append("issues.fixme_tag.message", { - feature: utilDisplayLabel(entity2, context2.graph(), true) + feature: utilDisplayLabel( + entity2, + context2.graph(), + true + /* verbose */ + ) }) : ""; }, dynamicFixes: function() { @@ -41294,13 +42856,13 @@ ${content} selection2.selectAll(".issue-reference").data([0]).enter().append("div").attr("class", "issue-reference").call(_t.append("issues.fixme_tag.reference")); } }; - validation.type = type3; + validation.type = type2; return validation; } // modules/validations/impossible_oneway.js function validationImpossibleOneway() { - var type3 = "impossible_oneway"; + var type2 = "impossible_oneway"; var validation = function checkImpossibleOneway(entity, graph) { if (entity.type !== "way" || entity.geometry(graph) !== "line") return []; @@ -41426,7 +42988,7 @@ ${content} referenceID += placement; } return [new validationIssue({ - type: type3, + type: type2, subtype: wayType, severity: "warning", message: function(context) { @@ -41485,13 +43047,13 @@ ${content} modeDrawLine(context, way.id, context.graph(), "line", way.affix(vertex.id), true) ); } - validation.type = type3; + validation.type = type2; return validation; } // modules/validations/incompatible_source.js function validationIncompatibleSource() { - const type3 = "incompatible_source"; + const type2 = "incompatible_source"; const incompatibleRules = [ { id: "amap", @@ -41523,12 +43085,17 @@ ${content} if (!matchRule) return null; return new validationIssue({ - type: type3, + type: type2, severity: "warning", message: (context) => { const entity2 = context.hasEntity(entityID); return entity2 ? _t.append("issues.incompatible_source.feature.message", { - feature: utilDisplayLabel(entity2, context.graph(), true), + feature: utilDisplayLabel( + entity2, + context.graph(), + true + /* verbose */ + ), value: source }) : ""; }, @@ -41548,13 +43115,13 @@ ${content} }; } }; - validation.type = type3; + validation.type = type2; return validation; } // modules/validations/maprules.js function validationMaprules() { - var type3 = "maprules"; + var type2 = "maprules"; var validation = function checkMaprules(entity, graph) { if (!services.maprules) return []; @@ -41566,14 +43133,14 @@ ${content} } return issues; }; - validation.type = type3; + validation.type = type2; return validation; } // modules/validations/mismatched_geometry.js var import_fast_deep_equal4 = __toESM(require_fast_deep_equal()); function validationMismatchedGeometry() { - var type3 = "mismatched_geometry"; + var type2 = "mismatched_geometry"; function tagSuggestingLineIsArea(entity) { if (entity.type !== "way" || entity.isClosed()) return null; @@ -41626,14 +43193,31 @@ ${content} var tagSuggestingArea = tagSuggestingLineIsArea(entity); if (!tagSuggestingArea) return null; + var validAsLine = false; + var presetAsLine = _mainPresetIndex.matchTags(entity.tags, "line"); + if (presetAsLine) { + validAsLine = true; + var key = Object.keys(tagSuggestingArea)[0]; + if (presetAsLine.tags[key] && presetAsLine.tags[key] === "*") { + validAsLine = false; + } + if (Object.keys(presetAsLine.tags).length === 0) { + validAsLine = false; + } + } return new validationIssue({ - type: type3, + type: type2, subtype: "area_as_line", severity: "warning", message: function(context) { var entity2 = context.hasEntity(this.entityIds[0]); return entity2 ? _t.append("issues.tag_suggests_area.message", { - feature: utilDisplayLabel(entity2, "area", true), + feature: utilDisplayLabel( + entity2, + "area", + true + /* verbose */ + ), tag: utilTagText({ tags: tagSuggestingArea }) }) : ""; }, @@ -41644,10 +43228,12 @@ ${content} var fixes = []; var entity2 = context.entity(this.entityIds[0]); var connectEndsOnClick = makeConnectEndpointsFixOnClick(entity2, context.graph()); - fixes.push(new validationIssueFix({ - title: _t.append("issues.fix.connect_endpoints.title"), - onClick: connectEndsOnClick - })); + if (!validAsLine) { + fixes.push(new validationIssueFix({ + title: _t.append("issues.fix.connect_endpoints.title"), + onClick: connectEndsOnClick + })); + } fixes.push(new validationIssueFix({ icon: "iD-operation-delete", title: _t.append("issues.fix.remove_tag.title"), @@ -41655,8 +43241,8 @@ ${content} var entityId = this.issue.entityIds[0]; var entity3 = context2.entity(entityId); var tags = Object.assign({}, entity3.tags); - for (var key in tagSuggestingArea) { - delete tags[key]; + for (var key2 in tagSuggestingArea) { + delete tags[key2]; } context2.perform( actionChangeTags(entityId, tags), @@ -41682,13 +43268,18 @@ ${content} var allowedGeometries = osmNodeGeometriesForTags(entity.tags); if (geometry === "point" && !allowedGeometries.point && allowedGeometries.vertex) { return new validationIssue({ - type: type3, + type: type2, subtype: "vertex_as_point", severity: "warning", message: function(context) { var entity2 = context.hasEntity(this.entityIds[0]); return entity2 ? _t.append("issues.vertex_as_point.message", { - feature: utilDisplayLabel(entity2, "vertex", true) + feature: utilDisplayLabel( + entity2, + "vertex", + true + /* verbose */ + ) }) : ""; }, reference: function showReference(selection2) { @@ -41698,13 +43289,18 @@ ${content} }); } else if (geometry === "vertex" && !allowedGeometries.vertex && allowedGeometries.point) { return new validationIssue({ - type: type3, + type: type2, subtype: "point_as_vertex", severity: "warning", message: function(context) { var entity2 = context.hasEntity(this.entityIds[0]); return entity2 ? _t.append("issues.point_as_vertex.message", { - feature: utilDisplayLabel(entity2, "point", true) + feature: utilDisplayLabel( + entity2, + "point", + true + /* verbose */ + ) }) : ""; }, reference: function showReference(selection2) { @@ -41730,7 +43326,8 @@ ${content} var asSource = _mainPresetIndex.match(entity, graph); var targetGeom = targetGeoms.find((nodeGeom) => { var asTarget = _mainPresetIndex.matchTags(entity.tags, nodeGeom); - if (!asSource || !asTarget || asSource === asTarget || (0, import_fast_deep_equal4.default)(asSource.tags, asTarget.tags)) + if (!asSource || !asTarget || asSource === asTarget || // sometimes there are two presets with the same tags for different geometries + (0, import_fast_deep_equal4.default)(asSource.tags, asTarget.tags)) return false; if (asTarget.isFallback()) return false; @@ -41756,13 +43353,18 @@ ${content} dynamicFixes = lineToAreaDynamicFixes; } return new validationIssue({ - type: type3, + type: type2, subtype, severity: "warning", message: function(context) { var entity2 = context.hasEntity(this.entityIds[0]); return entity2 ? _t.append("issues." + referenceId + ".message", { - feature: utilDisplayLabel(entity2, targetGeom, true) + feature: utilDisplayLabel( + entity2, + targetGeom, + true + /* verbose */ + ) }) : ""; }, reference: function showReference(selection2) { @@ -41823,7 +43425,8 @@ ${content} ]; } function unclosedMultipolygonPartIssues(entity, graph) { - if (entity.type !== "relation" || !entity.isMultipolygon() || entity.isDegenerate() || !entity.isComplete(graph)) + if (entity.type !== "relation" || !entity.isMultipolygon() || entity.isDegenerate() || // cannot determine issues for incompletely-downloaded relations + !entity.isComplete(graph)) return []; var sequences = osmJoinWays(entity.members, graph); var issues = []; @@ -41836,13 +43439,18 @@ ${content} if (firstNode === lastNode) continue; var issue = new validationIssue({ - type: type3, + type: type2, subtype: "unclosed_multipolygon_part", severity: "warning", message: function(context) { var entity2 = context.hasEntity(this.entityIds[0]); return entity2 ? _t.append("issues.unclosed_multipolygon_part.message", { - feature: utilDisplayLabel(entity2, context.graph(), true) + feature: utilDisplayLabel( + entity2, + context.graph(), + true + /* verbose */ + ) }) : ""; }, reference: showReference, @@ -41871,13 +43479,13 @@ ${content} return [mismatch]; return unclosedMultipolygonPartIssues(entity, graph); }; - validation.type = type3; + validation.type = type2; return validation; } // modules/validations/missing_role.js function validationMissingRole() { - var type3 = "missing_role"; + var type2 = "missing_role"; var validation = function checkMissingRole(entity, graph) { var issues = []; if (entity.type === "way") { @@ -41904,7 +43512,7 @@ ${content} } function makeIssue(way, relation, member) { return new validationIssue({ - type: type3, + type: type2, severity: "warning", message: function(context) { var member2 = context.hasEntity(this.entityIds[1]), relation2 = context.hasEntity(this.entityIds[0]); @@ -41957,13 +43565,13 @@ ${content} } }); } - validation.type = type3; + validation.type = type2; return validation; } // modules/validations/missing_tag.js function validationMissingTag(context) { - var type3 = "missing_tag"; + var type2 = "missing_tag"; function hasDescriptiveTags(entity, graph) { var onlyAttributeKeys = ["description", "name", "note", "start_date"]; var entityDescriptiveKeys = Object.keys(entity.tags).filter(function(k) { @@ -41988,7 +43596,9 @@ ${content} var subtype; var osm = context.connection(); var isUnloadedNode = entity.type === "node" && osm && !osm.isDataLoaded(entity.loc); - if (!isUnloadedNode && entity.geometry(graph) !== "vertex" && !entity.hasParentRelations(graph)) { + if (!isUnloadedNode && // allow untagged nodes that are part of ways + entity.geometry(graph) !== "vertex" && // allow untagged entities that are part of relations + !entity.hasParentRelations(graph)) { if (Object.keys(entity.tags).length === 0) { subtype = "any"; } else if (!hasDescriptiveTags(entity, graph)) { @@ -42007,7 +43617,7 @@ ${content} var canDelete = entity.version === void 0 || entity.v !== void 0; var severity = canDelete && subtype !== "highway_classification" ? "error" : "warning"; return [new validationIssue({ - type: type3, + type: type2, subtype, severity, message: function(context2) { @@ -42056,28 +43666,34 @@ ${content} selection2.selectAll(".issue-reference").data([0]).enter().append("div").attr("class", "issue-reference").call(_t.append("issues." + referenceID + ".reference")); } }; - validation.type = type3; + validation.type = type2; return validation; } // modules/validations/outdated_tags.js function validationOutdatedTags() { - const type3 = "outdated_tags"; + const type2 = "outdated_tags"; let _waitingForDeprecated = true; let _dataDeprecated; _mainFileFetcher.get("deprecated").then((d) => _dataDeprecated = d).catch(() => { }).finally(() => _waitingForDeprecated = false); function oldTagIssues(entity, graph) { - const oldTags = Object.assign({}, entity.tags); + if (!entity.hasInterestingTags()) + return []; let preset = _mainPresetIndex.match(entity, graph); - let subtype = "deprecated_tags"; if (!preset) return []; - if (!entity.hasInterestingTags()) - return []; + const oldTags = Object.assign({}, entity.tags); + let subtype = "deprecated_tags"; if (preset.replacement) { const newPreset = _mainPresetIndex.item(preset.replacement); - graph = actionChangePreset(entity.id, preset, newPreset, true)(graph); + graph = actionChangePreset( + entity.id, + preset, + newPreset, + true + /* skip field defaults */ + )(graph); entity = graph.entity(entity.id); preset = newPreset; } @@ -42131,7 +43747,7 @@ ${content} } let autoArgs = subtype !== "noncanonical_brand" ? [doUpgrade, _t("issues.fix.upgrade_tags.annotation")] : null; issues.push(new validationIssue({ - type: type3, + type: type2, subtype, severity: "warning", message: showMessage, @@ -42205,7 +43821,12 @@ ${content} messageID += "_incomplete"; } return _t.append(messageID, { - feature: utilDisplayLabel(currEntity, context.graph(), true) + feature: utilDisplayLabel( + currEntity, + context.graph(), + true + /* verbose */ + ) }); } function showReference(selection2) { @@ -42232,7 +43853,7 @@ ${content} if (!multipolygon || !outerWay) return []; return [new validationIssue({ - type: type3, + type: type2, subtype: "old_multipolygon", severity: "warning", message: showMessage, @@ -42265,7 +43886,12 @@ ${content} return ""; return _t.append( "issues.old_multipolygon.message", - { multipolygon: utilDisplayLabel(currMultipolygon, context.graph(), true) } + { multipolygon: utilDisplayLabel( + currMultipolygon, + context.graph(), + true + /* verbose */ + ) } ); } function showReference(selection2) { @@ -42278,13 +43904,13 @@ ${content} issues = oldTagIssues(entity, graph); return issues; }; - validation.type = type3; + validation.type = type2; return validation; } // modules/validations/private_data.js function validationPrivateData() { - var type3 = "private_data"; + var type2 = "private_data"; var privateBuildingValues = { detached: true, farm: true, @@ -42328,7 +43954,7 @@ ${content} return []; var fixID = tagDiff.length === 1 ? "remove_tag" : "remove_tags"; return [new validationIssue({ - type: type3, + type: type2, severity: "warning", message: showMessage, reference: showReference, @@ -42380,13 +44006,13 @@ ${content} }); } }; - validation.type = type3; + validation.type = type2; return validation; } // modules/validations/suspicious_name.js function validationSuspiciousName() { - const type3 = "suspicious_name"; + const type2 = "suspicious_name"; const keysToTestForGenericValues = [ "aerialway", "aeroway", @@ -42432,7 +44058,7 @@ ${content} } function makeGenericNameIssue(entityId, nameKey, genericName, langCode) { return new validationIssue({ - type: type3, + type: type2, subtype: "generic_name", severity: "warning", message: function(context) { @@ -42474,7 +44100,7 @@ ${content} } function makeIncorrectNameIssue(entityId, nameKey, incorrectName, langCode) { return new validationIssue({ - type: type3, + type: type2, subtype: "not_name", severity: "warning", message: function(context) { @@ -42543,13 +44169,13 @@ ${content} } return issues; }; - validation.type = type3; + validation.type = type2; return validation; } // modules/validations/unsquare_way.js function validationUnsquareWay(context) { - var type3 = "unsquare_way"; + var type2 = "unsquare_way"; var DEFAULT_DEG_THRESHOLD = 5; var epsilon3 = 0.05; var nodeThreshold = 10; @@ -42588,7 +44214,7 @@ ${content} if (hasConnectedSquarableWays) return []; var storedDegreeThreshold = corePreferences("validate-square-degrees"); - var degreeThreshold = isNaN(storedDegreeThreshold) ? DEFAULT_DEG_THRESHOLD : parseFloat(storedDegreeThreshold); + var degreeThreshold = isFinite(storedDegreeThreshold) ? Number(storedDegreeThreshold) : DEFAULT_DEG_THRESHOLD; var points = nodes.map(function(node) { return context.projection(node.loc); }); @@ -42601,7 +44227,7 @@ ${content} autoArgs = [autoAction, _t("operations.orthogonalize.annotation.feature", { n: 1 })]; } return [new validationIssue({ - type: type3, + type: type2, subtype: "building", severity: "warning", message: function(context2) { @@ -42630,6 +44256,21 @@ ${content} }, 175); } }) + /* + new validationIssueFix({ + title: t.append('issues.fix.tag_as_unsquare.title'), + onClick: function(context) { + var entityId = this.issue.entityIds[0]; + var entity = context.entity(entityId); + var tags = Object.assign({}, entity.tags); // shallow copy + tags.nonsquare = 'yes'; + context.perform( + actionChangeTags(entityId, tags), + t('issues.fix.tag_as_unsquare.annotation') + ); + } + }) + */ ]; } })]; @@ -42637,7 +44278,7 @@ ${content} selection2.selectAll(".issue-reference").data([0]).enter().append("div").attr("class", "issue-reference").call(_t.append("issues.unsquare_way.buildings.reference")); } }; - validation.type = type3; + validation.type = type2; return validation; } @@ -42666,11 +44307,11 @@ ${content} rules.forEach((rule) => { rule = rule.trim(); const parts = rule.split("/", 2); - const type3 = parts[0]; + const type2 = parts[0]; const subtype = parts[1] || "*"; - if (!type3 || !subtype) + if (!type2 || !subtype) return; - result.push({ type: makeRegExp(type3), subtype: makeRegExp(subtype) }); + result.push({ type: makeRegExp(type2), subtype: makeRegExp(subtype) }); }); return result; function makeRegExp(str2) { @@ -42830,14 +44471,19 @@ ${content} }; validator.getSharedEntityIssues = (entityIDs, options2) => { const orderedIssueTypes = [ + // Show some issue types in a particular order: "missing_tag", "missing_role", + // - missing data first "outdated_tags", "mismatched_geometry", + // - identity issues "crossing_ways", "almost_junction", + // - geometry issues where fixing them might solve connectivity issues "disconnected_way", "impossible_oneway" + // - finally connectivity issues ]; const allIssues = validator.getIssues(options2); const forEntityIDs = new Set(entityIDs); @@ -42874,9 +44520,9 @@ ${content} corePreferences("validate-disabledRules", Object.keys(_disabledRules).join(",")); validator.validate(); }; - validator.disableRules = (keys) => { + validator.disableRules = (keys2) => { _disabledRules = {}; - keys.forEach((k) => _disabledRules[k] = true); + keys2.forEach((k) => _disabledRules[k] = true); corePreferences("validate-disabledRules", Object.keys(_disabledRules).join(",")); validator.validate(); }; @@ -42952,23 +44598,23 @@ ${content} detected = detected.filter(applySeverityOverrides); result.issues = result.issues.concat(detected); function applySeverityOverrides(issue) { - const type3 = issue.type; + const type2 = issue.type; const subtype = issue.subtype || ""; let i2; for (i2 = 0; i2 < _errorOverrides.length; i2++) { - if (_errorOverrides[i2].type.test(type3) && _errorOverrides[i2].subtype.test(subtype)) { + if (_errorOverrides[i2].type.test(type2) && _errorOverrides[i2].subtype.test(subtype)) { issue.severity = "error"; return true; } } for (i2 = 0; i2 < _warningOverrides.length; i2++) { - if (_warningOverrides[i2].type.test(type3) && _warningOverrides[i2].subtype.test(subtype)) { + if (_warningOverrides[i2].type.test(type2) && _warningOverrides[i2].subtype.test(subtype)) { issue.severity = "warning"; return true; } } for (i2 = 0; i2 < _disableOverrides.length; i2++) { - if (_disableOverrides[i2].type.test(type3) && _disableOverrides[i2].subtype.test(subtype)) { + if (_disableOverrides[i2].type.test(type2) && _disableOverrides[i2].subtype.test(subtype)) { return false; } } @@ -43058,7 +44704,9 @@ ${content} queuedEntityIDs: /* @__PURE__ */ new Set(), provisionalEntityIDs: /* @__PURE__ */ new Set(), issuesByIssueID: {}, + // issue.id -> issue issuesByEntityID: {} + // entity.id -> Set(issue.id) }; cache.cacheIssue = (issue) => { (issue.entityIds || []).forEach((entityID) => { @@ -43083,8 +44731,8 @@ ${content} cache.uncacheIssues = (issues) => { issues.forEach(cache.uncacheIssue); }; - cache.uncacheIssuesOfType = (type3) => { - const issuesOfType = Object.values(cache.issuesByIssueID).filter((issue) => issue.type === type3); + cache.uncacheIssuesOfType = (type2) => { + const issuesOfType = Object.values(cache.issuesByIssueID).filter((issue) => issue.type === type2); cache.uncacheIssues(issuesOfType); }; cache.uncacheEntityID = (entityID) => { @@ -43126,14 +44774,23 @@ ${content} // modules/core/uploader.js function coreUploader(context) { var dispatch10 = dispatch_default( + // Start and end events are dispatched exactly once each per legitimate outside call to `save` "saveStarted", + // dispatched as soon as a call to `save` has been deemed legitimate "saveEnded", + // dispatched after the result event has been dispatched "willAttemptUpload", + // dispatched before the actual upload call occurs, if it will "progressChanged", + // Each save results in one of these outcomes: "resultNoChanges", + // upload wasn't attempted since there were no edits "resultErrors", + // upload failed due to errors "resultConflicts", + // upload failed due to data conflicts "resultSuccess" + // upload completed without errors ); var _isSaving = false; var _conflicts = []; @@ -43309,9 +44966,9 @@ ${content} var remote = remoteGraph.entity(id2); if (sameVersions(local, remote)) return; - var merge3 = actionMergeRemoteChanges(id2, localGraph, remoteGraph, _discardTags, formatUser); - history.replace(merge3); - var mergeConflicts = merge3.conflicts(); + var merge2 = actionMergeRemoteChanges(id2, localGraph, remoteGraph, _discardTags, formatUser); + history.replace(merge2); + var mergeConflicts = merge2.conflicts(); if (!mergeConflicts.length) return; var forceLocal = actionMergeRemoteChanges(id2, localGraph, remoteGraph, _discardTags).withOption("force_local"); @@ -43420,10 +45077,16 @@ ${content} } // modules/renderer/background_source.js - var import_lodash2 = __toESM(require_lodash()); + var import_lodash4 = __toESM(require_lodash()); // modules/util/IntervalTasksQueue.js var IntervalTasksQueue = class { + /** + * Interval in milliseconds inside which only 1 task can execute. + * e.g. if interval is 200ms, and 5 async tasks are unqueued, + * they will complete in ~1s if not cleared + * @param {number} intervalInMs + */ constructor(intervalInMs) { this.intervalInMs = intervalInMs; this.pendingHandles = []; @@ -43497,15 +45160,20 @@ ${content} }; source.name = function() { var id_safe = source.id.replace(/\./g, ""); - return _t("imagery." + id_safe + ".name", { default: (0, import_lodash2.escape)(_name) }); + return _t("imagery." + id_safe + ".name", { default: (0, import_lodash4.escape)(_name) }); }; source.label = function() { var id_safe = source.id.replace(/\./g, ""); - return _t.append("imagery." + id_safe + ".name", { default: (0, import_lodash2.escape)(_name) }); + return _t.append("imagery." + id_safe + ".name", { default: (0, import_lodash4.escape)(_name) }); + }; + source.hasDescription = function() { + var id_safe = source.id.replace(/\./g, ""); + var descriptionText = _mainLocalizer.tInfo("imagery." + id_safe + ".description", { default: (0, import_lodash4.escape)(_description) }).text; + return descriptionText !== ""; }; source.description = function() { var id_safe = source.id.replace(/\./g, ""); - return _t.append("imagery." + id_safe + ".description", { default: (0, import_lodash2.escape)(_description) }); + return _t.append("imagery." + id_safe + ".description", { default: (0, import_lodash4.escape)(_description) }); }; source.best = function() { return _best; @@ -43574,7 +45242,8 @@ ${content} case "wkid": return projection2.replace(/^EPSG:/, ""); case "bbox": - if (projection2 === "EPSG:4326" && /VERSION=1.3|CRS={proj}/.test(source.template().toUpperCase())) { + if (projection2 === "EPSG:4326" && // The CRS parameter implies version 1.3 (prior versions use SRS) + /VERSION=1.3|CRS={proj}/.test(source.template().toUpperCase())) { return maxXminY.y + "," + minXmaxY.x + "," + minXmaxY.y + "," + maxXminY.x; } else { return minXmaxY.x + "," + maxXminY.y + "," + maxXminY.x + "," + minXmaxY.y; @@ -43799,8 +45468,8 @@ ${content} vintage, source: clean2(result.NICE_NAME), description: clean2(result.NICE_DESC), - resolution: clean2(+parseFloat(result.SRC_RES).toFixed(4)), - accuracy: clean2(+parseFloat(result.SRC_ACC).toFixed(4)) + resolution: clean2(+Number(result.SRC_RES).toFixed(4)), + accuracy: clean2(+Number(result.SRC_ACC).toFixed(4)) }; if (isFinite(metadata.resolution)) { metadata.resolution += " m"; @@ -43867,8 +45536,375 @@ ${content} return source; }; + // node_modules/@turf/helpers/dist/es/index.js + var earthRadius = 63710088e-1; + var factors = { + centimeters: earthRadius * 100, + centimetres: earthRadius * 100, + degrees: earthRadius / 111325, + feet: earthRadius * 3.28084, + inches: earthRadius * 39.37, + kilometers: earthRadius / 1e3, + kilometres: earthRadius / 1e3, + meters: earthRadius, + metres: earthRadius, + miles: earthRadius / 1609.344, + millimeters: earthRadius * 1e3, + millimetres: earthRadius * 1e3, + nauticalmiles: earthRadius / 1852, + radians: 1, + yards: earthRadius * 1.0936 + }; + var unitsFactors = { + centimeters: 100, + centimetres: 100, + degrees: 1 / 111325, + feet: 3.28084, + inches: 39.37, + kilometers: 1 / 1e3, + kilometres: 1 / 1e3, + meters: 1, + metres: 1, + miles: 1 / 1609.344, + millimeters: 1e3, + millimetres: 1e3, + nauticalmiles: 1 / 1852, + radians: 1 / earthRadius, + yards: 1.0936133 + }; + function feature2(geom, properties, options2) { + if (options2 === void 0) { + options2 = {}; + } + var feat = { type: "Feature" }; + if (options2.id === 0 || options2.id) { + feat.id = options2.id; + } + if (options2.bbox) { + feat.bbox = options2.bbox; + } + feat.properties = properties || {}; + feat.geometry = geom; + return feat; + } + function polygon(coordinates, properties, options2) { + if (options2 === void 0) { + options2 = {}; + } + for (var _i = 0, coordinates_1 = coordinates; _i < coordinates_1.length; _i++) { + var ring = coordinates_1[_i]; + if (ring.length < 4) { + throw new Error("Each LinearRing of a Polygon must have 4 or more Positions."); + } + for (var j2 = 0; j2 < ring[ring.length - 1].length; j2++) { + if (ring[ring.length - 1][j2] !== ring[0][j2]) { + throw new Error("First and last Position are not equivalent."); + } + } + } + var geom = { + type: "Polygon", + coordinates + }; + return feature2(geom, properties, options2); + } + function lineString(coordinates, properties, options2) { + if (options2 === void 0) { + options2 = {}; + } + if (coordinates.length < 2) { + throw new Error("coordinates must be an array of two or more positions"); + } + var geom = { + type: "LineString", + coordinates + }; + return feature2(geom, properties, options2); + } + function multiLineString(coordinates, properties, options2) { + if (options2 === void 0) { + options2 = {}; + } + var geom = { + type: "MultiLineString", + coordinates + }; + return feature2(geom, properties, options2); + } + function multiPolygon(coordinates, properties, options2) { + if (options2 === void 0) { + options2 = {}; + } + var geom = { + type: "MultiPolygon", + coordinates + }; + return feature2(geom, properties, options2); + } + + // node_modules/@turf/invariant/dist/es/index.js + function getGeom(geojson) { + if (geojson.type === "Feature") { + return geojson.geometry; + } + return geojson; + } + + // node_modules/@turf/bbox-clip/dist/es/lib/lineclip.js + function lineclip(points, bbox2, result) { + var len = points.length, codeA = bitCode(points[0], bbox2), part = [], i2, codeB, lastCode; + var a; + var b; + if (!result) + result = []; + for (i2 = 1; i2 < len; i2++) { + a = points[i2 - 1]; + b = points[i2]; + codeB = lastCode = bitCode(b, bbox2); + while (true) { + if (!(codeA | codeB)) { + part.push(a); + if (codeB !== lastCode) { + part.push(b); + if (i2 < len - 1) { + result.push(part); + part = []; + } + } else if (i2 === len - 1) { + part.push(b); + } + break; + } else if (codeA & codeB) { + break; + } else if (codeA) { + a = intersect(a, b, codeA, bbox2); + codeA = bitCode(a, bbox2); + } else { + b = intersect(a, b, codeB, bbox2); + codeB = bitCode(b, bbox2); + } + } + codeA = lastCode; + } + if (part.length) + result.push(part); + return result; + } + function polygonclip(points, bbox2) { + var result, edge, prev, prevInside, i2, p, inside; + for (edge = 1; edge <= 8; edge *= 2) { + result = []; + prev = points[points.length - 1]; + prevInside = !(bitCode(prev, bbox2) & edge); + for (i2 = 0; i2 < points.length; i2++) { + p = points[i2]; + inside = !(bitCode(p, bbox2) & edge); + if (inside !== prevInside) + result.push(intersect(prev, p, edge, bbox2)); + if (inside) + result.push(p); + prev = p; + prevInside = inside; + } + points = result; + if (!points.length) + break; + } + return result; + } + function intersect(a, b, edge, bbox2) { + return edge & 8 ? [a[0] + (b[0] - a[0]) * (bbox2[3] - a[1]) / (b[1] - a[1]), bbox2[3]] : edge & 4 ? [a[0] + (b[0] - a[0]) * (bbox2[1] - a[1]) / (b[1] - a[1]), bbox2[1]] : edge & 2 ? [bbox2[2], a[1] + (b[1] - a[1]) * (bbox2[2] - a[0]) / (b[0] - a[0])] : edge & 1 ? [bbox2[0], a[1] + (b[1] - a[1]) * (bbox2[0] - a[0]) / (b[0] - a[0])] : null; + } + function bitCode(p, bbox2) { + var code = 0; + if (p[0] < bbox2[0]) + code |= 1; + else if (p[0] > bbox2[2]) + code |= 2; + if (p[1] < bbox2[1]) + code |= 4; + else if (p[1] > bbox2[3]) + code |= 8; + return code; + } + + // node_modules/@turf/bbox-clip/dist/es/index.js + function bboxClip(feature3, bbox2) { + var geom = getGeom(feature3); + var type2 = geom.type; + var properties = feature3.type === "Feature" ? feature3.properties : {}; + var coords = geom.coordinates; + switch (type2) { + case "LineString": + case "MultiLineString": { + var lines_1 = []; + if (type2 === "LineString") { + coords = [coords]; + } + coords.forEach(function(line) { + lineclip(line, bbox2, lines_1); + }); + if (lines_1.length === 1) { + return lineString(lines_1[0], properties); + } + return multiLineString(lines_1, properties); + } + case "Polygon": + return polygon(clipPolygon(coords, bbox2), properties); + case "MultiPolygon": + return multiPolygon(coords.map(function(poly) { + return clipPolygon(poly, bbox2); + }), properties); + default: + throw new Error("geometry " + type2 + " not supported"); + } + } + function clipPolygon(rings, bbox2) { + var outRings = []; + for (var _i = 0, rings_1 = rings; _i < rings_1.length; _i++) { + var ring = rings_1[_i]; + var clipped = polygonclip(ring, bbox2); + if (clipped.length > 0) { + if (clipped[0][0] !== clipped[clipped.length - 1][0] || clipped[0][1] !== clipped[clipped.length - 1][1]) { + clipped.push(clipped[0]); + } + if (clipped.length >= 4) { + outRings.push(clipped); + } + } + } + return outRings; + } + + // node_modules/@turf/meta/dist/es/index.js + function coordEach(geojson, callback, excludeWrapCoord) { + if (geojson === null) + return; + var j2, k, l, geometry, stopG, coords, geometryMaybeCollection, wrapShrink = 0, coordIndex = 0, isGeometryCollection, type2 = geojson.type, isFeatureCollection = type2 === "FeatureCollection", isFeature = type2 === "Feature", stop = isFeatureCollection ? geojson.features.length : 1; + for (var featureIndex = 0; featureIndex < stop; featureIndex++) { + geometryMaybeCollection = isFeatureCollection ? geojson.features[featureIndex].geometry : isFeature ? geojson.geometry : geojson; + isGeometryCollection = geometryMaybeCollection ? geometryMaybeCollection.type === "GeometryCollection" : false; + stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1; + for (var geomIndex = 0; geomIndex < stopG; geomIndex++) { + var multiFeatureIndex = 0; + var geometryIndex = 0; + geometry = isGeometryCollection ? geometryMaybeCollection.geometries[geomIndex] : geometryMaybeCollection; + if (geometry === null) + continue; + coords = geometry.coordinates; + var geomType = geometry.type; + wrapShrink = excludeWrapCoord && (geomType === "Polygon" || geomType === "MultiPolygon") ? 1 : 0; + switch (geomType) { + case null: + break; + case "Point": + if (callback( + coords, + coordIndex, + featureIndex, + multiFeatureIndex, + geometryIndex + ) === false) + return false; + coordIndex++; + multiFeatureIndex++; + break; + case "LineString": + case "MultiPoint": + for (j2 = 0; j2 < coords.length; j2++) { + if (callback( + coords[j2], + coordIndex, + featureIndex, + multiFeatureIndex, + geometryIndex + ) === false) + return false; + coordIndex++; + if (geomType === "MultiPoint") + multiFeatureIndex++; + } + if (geomType === "LineString") + multiFeatureIndex++; + break; + case "Polygon": + case "MultiLineString": + for (j2 = 0; j2 < coords.length; j2++) { + for (k = 0; k < coords[j2].length - wrapShrink; k++) { + if (callback( + coords[j2][k], + coordIndex, + featureIndex, + multiFeatureIndex, + geometryIndex + ) === false) + return false; + coordIndex++; + } + if (geomType === "MultiLineString") + multiFeatureIndex++; + if (geomType === "Polygon") + geometryIndex++; + } + if (geomType === "Polygon") + multiFeatureIndex++; + break; + case "MultiPolygon": + for (j2 = 0; j2 < coords.length; j2++) { + geometryIndex = 0; + for (k = 0; k < coords[j2].length; k++) { + for (l = 0; l < coords[j2][k].length - wrapShrink; l++) { + if (callback( + coords[j2][k][l], + coordIndex, + featureIndex, + multiFeatureIndex, + geometryIndex + ) === false) + return false; + coordIndex++; + } + geometryIndex++; + } + multiFeatureIndex++; + } + break; + case "GeometryCollection": + for (j2 = 0; j2 < geometry.geometries.length; j2++) + if (coordEach(geometry.geometries[j2], callback, excludeWrapCoord) === false) + return false; + break; + default: + throw new Error("Unknown Geometry Type"); + } + } + } + } + + // node_modules/@turf/bbox/dist/es/index.js + function bbox(geojson) { + var result = [Infinity, Infinity, -Infinity, -Infinity]; + coordEach(geojson, function(coord2) { + if (result[0] > coord2[0]) { + result[0] = coord2[0]; + } + if (result[1] > coord2[1]) { + result[1] = coord2[1]; + } + if (result[2] < coord2[0]) { + result[2] = coord2[0]; + } + if (result[3] < coord2[1]) { + result[3] = coord2[1]; + } + }); + return result; + } + bbox["default"] = bbox; + var es_default = bbox; + // modules/renderer/background.js - var import_which_polygon4 = __toESM(require_which_polygon()); + var import_which_polygon3 = __toESM(require_which_polygon()); // modules/renderer/tile_layer.js function rendererTileLayer(context) { @@ -44033,6 +46069,7 @@ ${content} if (result && result.vintage && result.vintage.range) { span.text(result.vintage.range); } else { + span.text(""); span.call(_t.append("info_panels.background.vintage")); span.append("span").text(": "); span.call(_t.append("info_panels.background.unknown")); @@ -44085,7 +46122,7 @@ ${content} imagery: sources, features: {} }; - const features2 = sources.map((source) => { + const features = sources.map((source) => { if (!source.polygon) return null; const rings = source.polygon.map((ring) => [ring]); @@ -44097,7 +46134,7 @@ ${content} _imageryIndex.features[source.id] = feature3; return feature3; }).filter(Boolean); - _imageryIndex.query = (0, import_which_polygon4.default)({ type: "FeatureCollection", features: features2 }); + _imageryIndex.query = (0, import_which_polygon3.default)({ type: "FeatureCollection", features }); _imageryIndex.backgrounds = sources.map((source) => { if (source.type === "bing") { return rendererBackgroundSource.Bing(source, dispatch10); @@ -44390,7 +46427,17 @@ ${content} const isLastUsedValid = !!validBackgrounds.find((d) => d.id && d.id === lastUsedBackground); let best; if (!requestedBackground && extent) { - best = validBackgrounds.find((s) => s.best()); + const viewArea = extent.area(); + best = validBackgrounds.find((s) => { + if (!s.best() || s.overlay) + return false; + let bbox2 = es_default(bboxClip( + { type: "MultiPolygon", coordinates: [s.polygon || [extent.polygon()]] }, + extent.rectangle() + )); + let area = geoExtent(bbox2.slice(0, 2), bbox2.slice(2, 4)).area(); + return area / viewArea > 0.5; + }); } if (requestedBackground && requestedBackground.indexOf("custom:") === 0) { const template = requestedBackground.replace(/^custom:/, ""); @@ -44435,7 +46482,7 @@ ${content} // modules/renderer/features.js function rendererFeatures(context) { var dispatch10 = dispatch_default("change", "redraw"); - var features2 = utilRebind({}, dispatch10, "on"); + var features = utilRebind({}, dispatch10, "on"); var _deferred2 = /* @__PURE__ */ new Set(); var traffic_roads = { "motorway": true, @@ -44450,7 +46497,8 @@ ${content} "tertiary_link": true, "residential": true, "unclassified": true, - "living_street": true + "living_street": true, + "busway": true }; var service_roads = { "service": true, @@ -44475,7 +46523,7 @@ ${content} function update() { if (!window.mocha) { var hash = utilStringQs(window.location.hash); - var disabled = features2.disabled(); + var disabled = features.disabled(); if (disabled.length) { hash.disable_features = disabled.join(","); } else { @@ -44484,7 +46532,7 @@ ${content} window.location.replace("#" + utilQsString(hash, true)); corePreferences("disabled-features", disabled.join(",")); } - _hidden = features2.hidden(); + _hidden = features.hidden(); dispatch10.call("change"); dispatch10.call("redraw"); } @@ -44494,6 +46542,7 @@ ${content} _rules[k] = { filter: filter2, enabled: isEnabled, + // whether the user wants it enabled.. count: 0, currentMax: max3 || Infinity, defaultMax: max3 || Infinity, @@ -44570,13 +46619,13 @@ ${content} defineRule("others", function isOther(tags, geometry) { return geometry === "line" || geometry === "area"; }); - features2.features = function() { + features.features = function() { return _rules; }; - features2.keys = function() { + features.keys = function() { return _keys; }; - features2.enabled = function(k) { + features.enabled = function(k) { if (!arguments.length) { return _keys.filter(function(k2) { return _rules[k2].enabled; @@ -44584,7 +46633,7 @@ ${content} } return _rules[k] && _rules[k].enabled; }; - features2.disabled = function(k) { + features.disabled = function(k) { if (!arguments.length) { return _keys.filter(function(k2) { return !_rules[k2].enabled; @@ -44592,7 +46641,7 @@ ${content} } return _rules[k] && !_rules[k].enabled; }; - features2.hidden = function(k) { + features.hidden = function(k) { if (!arguments.length) { return _keys.filter(function(k2) { return _rules[k2].hidden(); @@ -44600,7 +46649,7 @@ ${content} } return _rules[k] && _rules[k].hidden(); }; - features2.autoHidden = function(k) { + features.autoHidden = function(k) { if (!arguments.length) { return _keys.filter(function(k2) { return _rules[k2].autoHidden(); @@ -44608,13 +46657,13 @@ ${content} } return _rules[k] && _rules[k].autoHidden(); }; - features2.enable = function(k) { + features.enable = function(k) { if (_rules[k] && !_rules[k].enabled) { _rules[k].enable(); update(); } }; - features2.enableAll = function() { + features.enableAll = function() { var didEnable = false; for (var k in _rules) { if (!_rules[k].enabled) { @@ -44625,13 +46674,13 @@ ${content} if (didEnable) update(); }; - features2.disable = function(k) { + features.disable = function(k) { if (_rules[k] && _rules[k].enabled) { _rules[k].disable(); update(); } }; - features2.disableAll = function() { + features.disableAll = function() { var didDisable = false; for (var k in _rules) { if (_rules[k].enabled) { @@ -44642,7 +46691,7 @@ ${content} if (didDisable) update(); }; - features2.toggle = function(k) { + features.toggle = function(k) { if (_rules[k]) { (function(f2) { return f2.enabled ? f2.disable() : f2.enable(); @@ -44650,13 +46699,13 @@ ${content} update(); } }; - features2.resetStats = function() { + features.resetStats = function() { for (var i2 = 0; i2 < _keys.length; i2++) { _rules[_keys[i2]].count = 0; } dispatch10.call("change"); }; - features2.gatherStats = function(d, resolver, dimensions) { + features.gatherStats = function(d, resolver, dimensions) { var needsRedraw = false; var types = utilArrayGroupBy(d, "type"); var entities = [].concat(types.relation || [], types.way || [], types.node || []); @@ -44667,12 +46716,12 @@ ${content} _cullFactor = dimensions[0] * dimensions[1] / 1e6; for (i2 = 0; i2 < entities.length; i2++) { geometry = entities[i2].geometry(resolver); - matches = Object.keys(features2.getMatches(entities[i2], resolver, geometry)); + matches = Object.keys(features.getMatches(entities[i2], resolver, geometry)); for (j2 = 0; j2 < matches.length; j2++) { _rules[matches[j2]].count++; } } - currHidden = features2.hidden(); + currHidden = features.hidden(); if (currHidden !== _hidden) { _hidden = currHidden; needsRedraw = true; @@ -44680,21 +46729,21 @@ ${content} } return needsRedraw; }; - features2.stats = function() { + features.stats = function() { for (var i2 = 0; i2 < _keys.length; i2++) { _stats[_keys[i2]] = _rules[_keys[i2]].count; } return _stats; }; - features2.clear = function(d) { + features.clear = function(d) { for (var i2 = 0; i2 < d.length; i2++) { - features2.clearEntity(d[i2]); + features.clearEntity(d[i2]); } }; - features2.clearEntity = function(entity) { + features.clearEntity = function(entity) { delete _cache4[osmEntity.key(entity)]; }; - features2.reset = function() { + features.reset = function() { Array.from(_deferred2).forEach(function(handle) { window.cancelIdleCallback(handle); _deferred2.delete(handle); @@ -44704,7 +46753,7 @@ ${content} function relationShouldBeChecked(relation) { return relation.tags.type === "boundary"; } - features2.getMatches = function(entity, resolver, geometry) { + features.getMatches = function(entity, resolver, geometry) { if (geometry === "vertex" || geometry === "relation" && !relationShouldBeChecked(entity)) return {}; var ent = osmEntity.key(entity); @@ -44719,8 +46768,9 @@ ${content} if (hasMatch) continue; if (entity.type === "way") { - var parents = features2.getParents(entity, resolver, geometry); - if (parents.length === 1 && parents[0].isMultipolygon() || parents.length > 0 && parents.every(function(parent) { + var parents = features.getParents(entity, resolver, geometry); + if (parents.length === 1 && parents[0].isMultipolygon() || // 2b. or belongs only to boundary relations + parents.length > 0 && parents.every(function(parent) { return parent.tags.type === "boundary"; })) { var pkey = osmEntity.key(parents[0]); @@ -44739,7 +46789,7 @@ ${content} } return _cache4[ent].matches; }; - features2.getParents = function(entity, resolver, geometry) { + features.getParents = function(entity, resolver, geometry) { if (geometry === "point") return []; var ent = osmEntity.key(entity); @@ -44757,7 +46807,7 @@ ${content} } return _cache4[ent].parents; }; - features2.isHiddenPreset = function(preset, geometry) { + features.isHiddenPreset = function(preset, geometry) { if (!_hidden.length) return false; if (!preset.tags) @@ -44773,36 +46823,36 @@ ${content} } return false; }; - features2.isHiddenFeature = function(entity, resolver, geometry) { + features.isHiddenFeature = function(entity, resolver, geometry) { if (!_hidden.length) return false; if (!entity.version) return false; if (_forceVisible[entity.id]) return false; - var matches = Object.keys(features2.getMatches(entity, resolver, geometry)); + var matches = Object.keys(features.getMatches(entity, resolver, geometry)); return matches.length && matches.every(function(k) { - return features2.hidden(k); + return features.hidden(k); }); }; - features2.isHiddenChild = function(entity, resolver, geometry) { + features.isHiddenChild = function(entity, resolver, geometry) { if (!_hidden.length) return false; if (!entity.version || geometry === "point") return false; if (_forceVisible[entity.id]) return false; - var parents = features2.getParents(entity, resolver, geometry); + var parents = features.getParents(entity, resolver, geometry); if (!parents.length) return false; for (var i2 = 0; i2 < parents.length; i2++) { - if (!features2.isHidden(parents[i2], resolver, parents[i2].geometry(resolver))) { + if (!features.isHidden(parents[i2], resolver, parents[i2].geometry(resolver))) { return false; } } return true; }; - features2.hasHiddenConnections = function(entity, resolver) { + features.hasHiddenConnections = function(entity, resolver) { if (!_hidden.length) return false; var childNodes, connections; @@ -44811,36 +46861,36 @@ ${content} connections = []; } else { childNodes = entity.nodes ? resolver.childNodes(entity) : []; - connections = features2.getParents(entity, resolver, entity.geometry(resolver)); + connections = features.getParents(entity, resolver, entity.geometry(resolver)); } connections = childNodes.reduce(function(result, e) { return resolver.isShared(e) ? utilArrayUnion(result, resolver.parentWays(e)) : result; }, connections); return connections.some(function(e) { - return features2.isHidden(e, resolver, e.geometry(resolver)); + return features.isHidden(e, resolver, e.geometry(resolver)); }); }; - features2.isHidden = function(entity, resolver, geometry) { + features.isHidden = function(entity, resolver, geometry) { if (!_hidden.length) return false; if (!entity.version) return false; - var fn = geometry === "vertex" ? features2.isHiddenChild : features2.isHiddenFeature; + var fn = geometry === "vertex" ? features.isHiddenChild : features.isHiddenFeature; return fn(entity, resolver, geometry); }; - features2.filter = function(d, resolver) { + features.filter = function(d, resolver) { if (!_hidden.length) return d; var result = []; for (var i2 = 0; i2 < d.length; i2++) { var entity = d[i2]; - if (!features2.isHidden(entity, resolver, entity.geometry(resolver))) { + if (!features.isHidden(entity, resolver, entity.geometry(resolver))) { result.push(entity); } } return result; }; - features2.forceVisible = function(entityIDs) { + features.forceVisible = function(entityIDs) { if (!arguments.length) return Object.keys(_forceVisible); _forceVisible = {}; @@ -44853,18 +46903,18 @@ ${content} } } } - return features2; + return features; }; - features2.init = function() { + features.init = function() { var storage = corePreferences("disabled-features"); if (storage) { var storageDisabled = storage.replace(/;/g, ",").split(","); - storageDisabled.forEach(features2.disable); + storageDisabled.forEach(features.disable); } var hash = utilStringQs(window.location.hash); if (hash.disable_features) { var hashDisabled = hash.disable_features.replace(/;/g, ",").split(","); - hashDisabled.forEach(features2.disable); + hashDisabled.forEach(features.disable); } }; context.history().on("merge.features", function(newEntities) { @@ -44876,12 +46926,12 @@ ${content} var entities = [].concat(types.relation || [], types.way || [], types.node || []); for (var i2 = 0; i2 < entities.length; i2++) { var geometry = entities[i2].geometry(graph); - features2.getMatches(entities[i2], graph, geometry); + features.getMatches(entities[i2], graph, geometry); } }); _deferred2.add(handle); }); - return features2; + return features; } // modules/svg/areas.js @@ -45040,8 +47090,8 @@ ${content} var tags = entity.tags; var shouldCopyMultipolygonTags = !entity.hasInterestingTags(); graph.parentRelations(entity).forEach(function(relation) { - var type3 = relation.tags.type; - if (type3 === "multipolygon" && shouldCopyMultipolygonTags || type3 === "boundary") { + var type2 = relation.tags.type; + if (type2 === "multipolygon" && shouldCopyMultipolygonTags || type2 === "boundary") { tags = Object.assign({}, relation.tags, tags); } }); @@ -45056,14 +47106,14 @@ ${content} } function getWaySegments() { var isActiveWay = way.nodes.indexOf(activeID) !== -1; - var features2 = { passive: [], active: [] }; + var features = { passive: [], active: [] }; var start2 = {}; var end = {}; - var node, type3; + var node, type2; for (var i2 = 0; i2 < way.nodes.length; i2++) { node = graph.entity(way.nodes[i2]); - type3 = svgPassiveVertex(node, graph, activeID); - end = { node, type: type3 }; + type2 = svgPassiveVertex(node, graph, activeID); + end = { node, type: type2 }; if (start2.type !== void 0) { if (start2.node.id === activeID || end.node.id === activeID) { } else if (isActiveWay && (start2.type === 2 || end.type === 2)) { @@ -45076,9 +47126,9 @@ ${content} } start2 = end; } - return features2; + return features; function pushActive(start3, end2, index) { - features2.active.push({ + features.active.push({ type: "Feature", id: way.id + "-" + index + "-nope", properties: { @@ -45095,7 +47145,7 @@ ${content} }); } function pushPassive(start3, end2, index) { - features2.passive.push({ + features.passive.push({ type: "Feature", id: way.id + "-" + index, properties: { @@ -45272,7 +47322,7 @@ ${content} if (qid) { classes.push("tag-wikidata"); } - return classes.join(" ").trim(); + return classes.filter((klass) => /^[-_a-z0-9]+$/.test(klass)).join(" ").trim(); }; tagClasses.tags = function(val) { if (!arguments.length) @@ -45285,6 +47335,12 @@ ${content} // modules/svg/tag_pattern.js var patterns = { + // tag - pattern name + // -or- + // tag - value - pattern name + // -or- + // tag - value - rules (optional tag-values, pattern name) + // (matches earlier rules first, so fallback should be last entry) amenity: { grave_yard: "cemetery", fountain: "water_standing" @@ -45305,6 +47361,7 @@ ${content} { leaf_type: "needleleaved", pattern: "forest_needleleaved" }, { leaf_type: "leafless", pattern: "forest_leafless" }, { pattern: "forest" } + // same as 'leaf_type:mixed' ], grave_yard: "cemetery", grass: "grass", @@ -45340,6 +47397,7 @@ ${content} { leaf_type: "needleleaved", pattern: "forest_needleleaved" }, { leaf_type: "leafless", pattern: "forest_leafless" }, { pattern: "forest" } + // same as 'leaf_type:mixed' ] }, golf: { @@ -45411,9 +47469,9 @@ ${content} var base = context.history().base(); var data = { targets: [], nopes: [] }; entities.forEach(function(way) { - var features2 = svgSegmentWay(way, graph, activeID); - data.targets.push.apply(data.targets, features2.passive); - data.nopes.push.apply(data.nopes, features2.active); + var features = svgSegmentWay(way, graph, activeID); + data.targets.push.apply(data.targets, features.passive); + data.nopes.push.apply(data.nopes, features.active); }); var targetData = data.targets.filter(getPath); var targets = selection2.selectAll(".area.target-allowed").filter(function(d) { @@ -45583,7 +47641,7 @@ ${content} const val = parseFloat(nodeVal(get1(node, tagName))); if (isNaN(val)) return void 0; - if (val && callback) + if (callback) callback(val); return val; } @@ -45794,9 +47852,9 @@ ${content} yield feature3; } for (const waypoint of $(node, "wpt")) { - const point = getPoint(waypoint); - if (point) - yield point; + const point2 = getPoint(waypoint); + if (point2) + yield point2; } } function gpx(node) { @@ -45829,6 +47887,14 @@ ${content} function getColor(node, output) { return get3(node, "color", (elem) => fixColor(nodeVal(elem), output)); } + function extractIconHref(node) { + return get3(node, "Icon", (icon2, properties) => { + val1(icon2, "href", (href) => { + properties.icon = href; + }); + return properties; + }); + } function extractIcon(node) { return get3(node, "IconStyle", (iconStyle) => { return Object.assign(getColor(iconStyle, "icon"), numericProperty(iconStyle, "scale", "icon-scale"), numericProperty(iconStyle, "heading", "icon-heading"), get3(iconStyle, "hotSpot", (hotspot) => { @@ -45842,12 +47908,7 @@ ${content} "icon-offset-units": [xunits, yunits] }; return {}; - }), get3(iconStyle, "Icon", (icon2, properties) => { - val1(icon2, "href", (href) => { - properties.icon = href; - }); - return properties; - })); + }), extractIconHref(iconStyle)); }); } function extractLabel(node) { @@ -45874,6 +47935,68 @@ ${content} function extractStyle(node) { return Object.assign({}, extractPoly(node), extractLine(node), extractLabel(node), extractIcon(node)); } + var toNumber2 = (x) => Number(x); + var typeConverters = { + string: (x) => x, + int: toNumber2, + uint: toNumber2, + short: toNumber2, + ushort: toNumber2, + float: toNumber2, + double: toNumber2, + bool: (x) => Boolean(x) + }; + function extractExtendedData(node, schema) { + return get3(node, "ExtendedData", (extendedData, properties) => { + for (const data of $(extendedData, "Data")) { + properties[data.getAttribute("name") || ""] = nodeVal(get1(data, "value")); + } + for (const simpleData of $(extendedData, "SimpleData")) { + const name = simpleData.getAttribute("name") || ""; + const typeConverter = schema[name] || typeConverters.string; + properties[name] = typeConverter(nodeVal(simpleData)); + } + return properties; + }); + } + function getMaybeHTMLDescription(node) { + const descriptionNode = get1(node, "description"); + for (const c of Array.from(descriptionNode?.childNodes || [])) { + if (c.nodeType === 4) { + return { + description: { + "@type": "html", + value: nodeVal(c) + } + }; + } + } + return {}; + } + function extractTimeSpan(node) { + return get3(node, "TimeSpan", (timeSpan) => { + return { + timespan: { + begin: nodeVal(get1(timeSpan, "begin")), + end: nodeVal(get1(timeSpan, "end")) + } + }; + }); + } + function extractTimeStamp(node) { + return get3(node, "TimeStamp", (timeStamp) => { + return { timestamp: nodeVal(get1(timeStamp, "when")) }; + }); + } + function extractCascadedStyle(node, styleMap) { + return val1(node, "styleUrl", (styleUrl) => { + styleUrl = normalizeId(styleUrl); + if (styleMap[styleUrl]) { + return Object.assign({ styleUrl }, styleMap[styleUrl]); + } + return { styleUrl }; + }); + } var removeSpace = /\s*/g; var trimSpace = /^\s*|\s*$/g; var splitSpace = /\s+/; @@ -45924,30 +48047,26 @@ ${content} } return ring; } - var GEO_TYPES = [ - "Polygon", - "LineString", - "Point", - "Track", - "gx:Track" - ]; function getCoordinates(node) { return nodeVal(get1(node, "coordinates")); } function getGeometry(node) { - const geometries = []; - const coordTimes = []; - for (const t of ["MultiGeometry", "MultiTrack", "gx:MultiTrack"]) { - const elem = get1(node, t); - if (elem) { - return getGeometry(elem); - } - } - for (const geoType of GEO_TYPES) { - for (const geomNode of $(node, geoType)) { - switch (geoType) { + let geometries = []; + let coordTimes = []; + for (let i2 = 0; i2 < node.childNodes.length; i2++) { + const child = node.childNodes.item(i2); + if (isElement(child)) { + switch (child.tagName) { + case "MultiGeometry": + case "MultiTrack": + case "gx:MultiTrack": { + const childGeometries = getGeometry(child); + geometries = geometries.concat(childGeometries.geometries); + coordTimes = coordTimes.concat(childGeometries.coordTimes); + break; + } case "Point": { - const coordinates = coord1(getCoordinates(geomNode)); + const coordinates = coord1(getCoordinates(child)); if (coordinates.length >= 2) { geometries.push({ type: "Point", @@ -45956,8 +48075,9 @@ ${content} } break; } + case "LinearRing": case "LineString": { - const coordinates = coord(getCoordinates(geomNode)); + const coordinates = coord(getCoordinates(child)); if (coordinates.length >= 2) { geometries.push({ type: "LineString", @@ -45968,7 +48088,7 @@ ${content} } case "Polygon": { const coords = []; - for (const linearRing of $(geomNode, "LinearRing")) { + for (const linearRing of $(child, "LinearRing")) { const ring = fixRing(coord(getCoordinates(linearRing))); if (ring.length >= 4) { coords.push(ring); @@ -45984,7 +48104,7 @@ ${content} } case "Track": case "gx:Track": { - const gx = gxCoords(geomNode); + const gx = gxCoords(child); if (!gx) break; const { times, geometry } = gx; @@ -46001,62 +48121,13 @@ ${content} coordTimes }; } - function extractExtendedData(node) { - return get3(node, "ExtendedData", (extendedData, properties) => { - for (const data of $(extendedData, "Data")) { - properties[data.getAttribute("name") || ""] = nodeVal(get1(data, "value")); - } - for (const simpleData of $(extendedData, "SimpleData")) { - properties[simpleData.getAttribute("name") || ""] = nodeVal(simpleData); - } - return properties; - }); - } function geometryListToGeometry(geometries) { return geometries.length === 0 ? null : geometries.length === 1 ? geometries[0] : { type: "GeometryCollection", geometries }; } - function extractTimeSpan(node) { - return get3(node, "TimeSpan", (timeSpan) => { - return { - timespan: { - begin: nodeVal(get1(timeSpan, "begin")), - end: nodeVal(get1(timeSpan, "end")) - } - }; - }); - } - function extractTimeStamp(node) { - return get3(node, "TimeStamp", (timeStamp) => { - return { timestamp: nodeVal(get1(timeStamp, "when")) }; - }); - } - function extractCascadedStyle(node, styleMap) { - return val1(node, "styleUrl", (styleUrl) => { - styleUrl = normalizeId(styleUrl); - if (styleMap[styleUrl]) { - return Object.assign({ styleUrl }, styleMap[styleUrl]); - } - return { styleUrl }; - }); - } - function getMaybeHTMLDescription(node) { - const descriptionNode = get1(node, "description"); - for (const c of Array.from(descriptionNode?.childNodes || [])) { - if (c.nodeType === 4) { - return { - description: { - "@type": "html", - value: nodeVal(c) - } - }; - } - } - return {}; - } - function getPlacemark(node, styleMap) { + function getPlacemark(node, styleMap, schema) { const { coordTimes, geometries } = getGeometry(node); const feature3 = { type: "Feature", @@ -46068,7 +48139,7 @@ ${content} "open", "phoneNumber", "description" - ]), getMaybeHTMLDescription(node), extractCascadedStyle(node, styleMap), extractStyle(node), extractExtendedData(node), extractTimeSpan(node), extractTimeStamp(node), coordTimes.length ? { + ]), getMaybeHTMLDescription(node), extractCascadedStyle(node, styleMap), extractStyle(node), extractExtendedData(node, schema), extractTimeSpan(node), extractTimeStamp(node), coordTimes.length ? { coordinateProperties: { times: coordTimes.length === 1 ? coordTimes[0] : coordTimes } @@ -46082,6 +48153,100 @@ ${content} feature3.id = id2; return feature3; } + function getGroundOverlayBox(node) { + const latLonQuad = get1(node, "gx:LatLonQuad"); + if (latLonQuad) { + const ring = fixRing(coord(getCoordinates(node))); + return { + type: "Polygon", + coordinates: [ring] + }; + } + return getLatLonBox(node); + } + var DEGREES_TO_RADIANS = Math.PI / 180; + function rotateBox(bbox2, coordinates, rotation) { + const center = [(bbox2[0] + bbox2[2]) / 2, (bbox2[1] + bbox2[3]) / 2]; + return [ + coordinates[0].map((coordinate) => { + const dy = coordinate[1] - center[1]; + const dx = coordinate[0] - center[0]; + const distance = Math.sqrt(Math.pow(dy, 2) + Math.pow(dx, 2)); + const angle2 = Math.atan2(dy, dx) - rotation * DEGREES_TO_RADIANS; + return [ + center[0] + Math.cos(angle2) * distance, + center[1] + Math.sin(angle2) * distance + ]; + }) + ]; + } + function getLatLonBox(node) { + const latLonBox = get1(node, "LatLonBox"); + if (latLonBox) { + const north = num1(latLonBox, "north"); + const west = num1(latLonBox, "west"); + const east = num1(latLonBox, "east"); + const south = num1(latLonBox, "south"); + const rotation = num1(latLonBox, "rotation"); + if (typeof north === "number" && typeof south === "number" && typeof west === "number" && typeof east === "number") { + const bbox2 = [west, south, east, north]; + let coordinates = [ + [ + [west, north], + [east, north], + [east, south], + [west, south], + [west, north] + // top left (again) + ] + ]; + if (typeof rotation === "number") { + coordinates = rotateBox(bbox2, coordinates, rotation); + } + return { + type: "Polygon", + coordinates + }; + } + } + return null; + } + function getGroundOverlay(node, styleMap, schema) { + const geometry = getGroundOverlayBox(node); + const feature3 = { + type: "Feature", + geometry, + properties: Object.assign( + /** + * Related to + * https://gist.github.com/tmcw/037a1cb6660d74a392e9da7446540f46 + */ + { "@geometry-type": "groundoverlay" }, + getMulti(node, [ + "name", + "address", + "visibility", + "open", + "phoneNumber", + "description" + ]), + getMaybeHTMLDescription(node), + extractCascadedStyle(node, styleMap), + extractStyle(node), + extractIconHref(node), + extractExtendedData(node, schema), + extractTimeSpan(node), + extractTimeStamp(node) + ) + }; + if (feature3.properties?.visibility !== void 0) { + feature3.properties.visibility = feature3.properties.visibility !== "0"; + } + const id2 = node.getAttribute("id"); + if (id2 !== null && id2 !== "") + feature3.id = id2; + return feature3; + } function getStyleId(style) { let id2 = style.getAttribute("id"); const parentNode = style.parentNode; @@ -46106,10 +48271,23 @@ ${content} } return styleMap; } + function buildSchema(node) { + const schema = {}; + for (const field of $(node, "SimpleField")) { + schema[field.getAttribute("name") || ""] = typeConverters[field.getAttribute("type") || ""] || typeConverters["string"]; + } + return schema; + } function* kmlGen(node) { const styleMap = buildStyleMap(node); + const schema = buildSchema(node); for (const placemark of $(node, "Placemark")) { - const feature3 = getPlacemark(placemark, styleMap); + const feature3 = getPlacemark(placemark, styleMap, schema); + if (feature3) + yield feature3; + } + for (const groundOverlay of $(node, "GroundOverlay")) { + const feature3 = getGroundOverlay(groundOverlay, styleMap, schema); if (feature3) yield feature3; } @@ -46457,12 +48635,12 @@ ${content} return _src || ""; }; drawData.fitZoom = function() { - var features2 = getFeatures(_geojson); - if (!features2.length) + var features = getFeatures(_geojson); + if (!features.length) return; var map2 = context.map(); var viewport = map2.trimmedExtent().polygon(); - var coords = features2.reduce(function(coords2, feature3) { + var coords = features.reduce(function(coords2, feature3) { var geom = feature3.geometry; if (!geom) return coords2; @@ -46528,8 +48706,8 @@ ${content} const extent = context.map().extent(); _mainFileFetcher.get("imagery").then((d) => { const hits = showImagery && d.query.bbox(extent.rectangle(), true) || []; - const features2 = hits.map((d2) => d2.features[d2.id]); - let imagery = layer.selectAll("path.debug-imagery").data(features2); + const features = hits.map((d2) => d2.features[d2.id]); + let imagery = layer.selectAll("path.debug-imagery").data(features); imagery.exit().remove(); imagery.enter().append("path").attr("class", "debug-imagery debug orange"); }).catch(() => { @@ -46538,18 +48716,18 @@ ${content} let dataDownloaded = []; if (osm && showDownloaded) { const rtree = osm.caches("get").tile.rtree; - dataDownloaded = rtree.all().map((bbox) => { + dataDownloaded = rtree.all().map((bbox2) => { return { type: "Feature", - properties: { id: bbox.id }, + properties: { id: bbox2.id }, geometry: { type: "Polygon", coordinates: [[ - [bbox.minX, bbox.minY], - [bbox.minX, bbox.maxY], - [bbox.maxX, bbox.maxY], - [bbox.maxX, bbox.minY], - [bbox.minX, bbox.minY] + [bbox2.minX, bbox2.minY], + [bbox2.minX, bbox2.maxY], + [bbox2.maxX, bbox2.maxY], + [bbox2.maxX, bbox2.minY], + [bbox2.minX, bbox2.minY] ]] } }; @@ -46578,6 +48756,7 @@ ${content} "maki-sprite", "temaki-sprite", "fa-sprite", + "roentgen-sprite", "community-sprite" ]; function drawDefs(selection2) { @@ -46594,6 +48773,7 @@ ${content} _defsSelection.append("marker").attr("id", "ideditor-viewfield-marker").attr("viewBox", "0 0 16 16").attr("refX", 8).attr("refY", 16).attr("markerWidth", 4).attr("markerHeight", 4).attr("markerUnits", "strokeWidth").attr("orient", "auto").append("path").attr("class", "viewfield-marker-path").attr("d", "M 6,14 C 8,13.4 8,13.4 10,14 L 16,3 C 12,0 4,0 0,3 z").attr("fill", "#333").attr("fill-opacity", "0.75").attr("stroke", "#fff").attr("stroke-width", "0.5px").attr("stroke-opacity", "0.75"); _defsSelection.append("marker").attr("id", "ideditor-viewfield-marker-wireframe").attr("viewBox", "0 0 16 16").attr("refX", 8).attr("refY", 16).attr("markerWidth", 4).attr("markerHeight", 4).attr("markerUnits", "strokeWidth").attr("orient", "auto").append("path").attr("class", "viewfield-marker-path").attr("d", "M 6,14 C 8,13.4 8,13.4 10,14 L 16,3 C 12,0 4,0 0,3 z").attr("fill", "none").attr("stroke", "#fff").attr("stroke-width", "0.5px").attr("stroke-opacity", "0.75"); var patterns2 = _defsSelection.selectAll("pattern").data([ + // pattern name, pattern image name ["beach", "dots"], ["construction", "construction"], ["cemetery", "cemetery"], @@ -46845,13 +49025,13 @@ ${content} } // modules/svg/labels.js - var import_rbush7 = __toESM(require_rbush_min()); + var import_rbush6 = __toESM(require_rbush_min()); function svgLabels(projection2, context) { var path = path_default(projection2); var detected = utilDetect(); var baselineHack = detected.ie || detected.browser.toLowerCase() === "edge" || detected.browser.toLowerCase() === "firefox" && detected.version >= 70; - var _rdrawn = new import_rbush7.default(); - var _rskipped = new import_rbush7.default(); + var _rdrawn = new import_rbush6.default(); + var _rskipped = new import_rbush6.default(); var _textWidthCache = {}; var _entitybboxes = {}; var labelStack = [ @@ -47019,13 +49199,13 @@ ${content} } var coord2 = projection2(entity.loc); var nodePadding = 10; - var bbox = { + var bbox2 = { minX: coord2[0] - nodePadding, minY: coord2[1] - nodePadding - markerPadding, maxX: coord2[0] + nodePadding, maxY: coord2[1] + nodePadding }; - doInsert(bbox, entity.id + "P"); + doInsert(bbox2, entity.id + "P"); } if (geometry === "vertex") { geometry = "point"; @@ -47109,23 +49289,23 @@ ${content} y: coord3[1] + offset[1], textAnchor: offset[2] }; - var bbox2; + var bbox3; if (textDirection === "rtl") { - bbox2 = { + bbox3 = { minX: p2.x - width2 - textPadding, minY: p2.y - height / 2 - textPadding, maxX: p2.x + textPadding, maxY: p2.y + height / 2 + textPadding }; } else { - bbox2 = { + bbox3 = { minX: p2.x - textPadding, minY: p2.y - height / 2 - textPadding, maxX: p2.x + width2 + textPadding, maxY: p2.y + height / 2 + textPadding }; } - if (tryInsert([bbox2], entity2.id, true)) { + if (tryInsert([bbox3], entity2.id, true)) { return p2; } } @@ -47264,13 +49444,13 @@ ${content} function addIcon() { var iconX = centroid[0] - iconSize / 2; var iconY = centroid[1] - iconSize / 2; - var bbox2 = { + var bbox3 = { minX: iconX, minY: iconY, maxX: iconX + iconSize, maxY: iconY + iconSize }; - if (tryInsert([bbox2], entity2.id + "I", true)) { + if (tryInsert([bbox3], entity2.id + "I", true)) { p2.transform = "translate(" + iconX + "," + iconY + ")"; return true; } @@ -47280,13 +49460,13 @@ ${content} if (width2 && areaWidth >= width2 + 20) { var labelX = centroid[0]; var labelY = centroid[1] + yOffset; - var bbox2 = { + var bbox3 = { minX: labelX - width2 / 2 - padding, minY: labelY - height / 2 - padding, maxX: labelX + width2 / 2 + padding, maxY: labelY + height / 2 + padding }; - if (tryInsert([bbox2], entity2.id, true)) { + if (tryInsert([bbox3], entity2.id, true)) { p2.x = labelX; p2.y = labelY; p2.textAnchor = "middle"; @@ -47297,25 +49477,25 @@ ${content} return false; } } - function doInsert(bbox2, id2) { - bbox2.id = id2; + function doInsert(bbox3, id2) { + bbox3.id = id2; var oldbox = _entitybboxes[id2]; if (oldbox) { _rdrawn.remove(oldbox); } - _entitybboxes[id2] = bbox2; - _rdrawn.insert(bbox2); + _entitybboxes[id2] = bbox3; + _rdrawn.insert(bbox3); } function tryInsert(bboxes, id2, saveSkipped) { var skipped = false; for (var i3 = 0; i3 < bboxes.length; i3++) { - var bbox2 = bboxes[i3]; - bbox2.id = id2; - if (bbox2.minX < 0 || bbox2.minY < 0 || bbox2.maxX > dimensions[0] || bbox2.maxY > dimensions[1]) { + var bbox3 = bboxes[i3]; + bbox3.id = id2; + if (bbox3.minX < 0 || bbox3.minY < 0 || bbox3.maxX > dimensions[0] || bbox3.maxY > dimensions[1]) { skipped = true; break; } - if (_rdrawn.collides(bbox2)) { + if (_rdrawn.collides(bbox3)) { skipped = true; break; } @@ -47358,11 +49538,11 @@ ${content} var graph = context.graph(); var selectedIDs = context.selectedIDs(); var ids = []; - var pad2, bbox; + var pad2, bbox2; if (mouse) { pad2 = 20; - bbox = { minX: mouse[0] - pad2, minY: mouse[1] - pad2, maxX: mouse[0] + pad2, maxY: mouse[1] + pad2 }; - var nearMouse = _rdrawn.search(bbox).map(function(entity2) { + bbox2 = { minX: mouse[0] - pad2, minY: mouse[1] - pad2, maxX: mouse[0] + pad2, maxY: mouse[1] + pad2 }; + var nearMouse = _rdrawn.search(bbox2).map(function(entity2) { return entity2.id; }); ids.push.apply(ids, nearMouse); @@ -47377,14 +49557,14 @@ ${content} var debug2 = selection2.selectAll(".labels-group.debug"); var gj = []; if (context.getDebug("collision")) { - gj = bbox ? [{ + gj = bbox2 ? [{ type: "Polygon", coordinates: [[ - [bbox.minX, bbox.minY], - [bbox.maxX, bbox.minY], - [bbox.maxX, bbox.maxY], - [bbox.minX, bbox.maxY], - [bbox.minX, bbox.minY] + [bbox2.minX, bbox2.minY], + [bbox2.maxX, bbox2.minY], + [bbox2.maxX, bbox2.maxY], + [bbox2.minX, bbox2.maxY], + [bbox2.minX, bbox2.minY] ]] }] : []; } @@ -48927,9 +51107,9 @@ ${content} var base = context.history().base(); var data = { targets: [], nopes: [] }; entities.forEach(function(way) { - var features2 = svgSegmentWay(way, graph, activeID); - data.targets.push.apply(data.targets, features2.passive); - data.nopes.push.apply(data.nopes, features2.active); + var features = svgSegmentWay(way, graph, activeID); + data.targets.push.apply(data.targets, features.passive); + data.nopes.push.apply(data.nopes, features.active); }); var targetData = data.targets.filter(getPath); var targets = selection2.selectAll(".line.target-allowed").filter(function(d) { @@ -48988,7 +51168,8 @@ ${content} var parentMultipolygons = parentRelations.filter(function(relation) { return relation.isMultipolygon(); }); - if (parentMultipolygons.length > 0 && parentRelations.length === parentMultipolygons.length) { + if (parentMultipolygons.length > 0 && // and only multipolygon relations + parentRelations.length === parentMultipolygons.length) { prefix = "relation area"; } } @@ -49181,15 +51362,15 @@ ${content} if (midpoints[id2]) { midpoints[id2].parents.push(entity); } else if (geoVecLength(projection2(a.loc), projection2(b.loc)) > 40) { - var point = geoVecInterp(a.loc, b.loc, 0.5); + var point2 = geoVecInterp(a.loc, b.loc, 0.5); var loc = null; - if (extent.intersects(point)) { - loc = point; + if (extent.intersects(point2)) { + loc = point2; } else { for (var k = 0; k < 4; k++) { - point = geoLineIntersection([a.loc, b.loc], [poly[k], poly[k + 1]]); - if (point && geoVecLength(projection2(a.loc), projection2(point)) > 20 && geoVecLength(projection2(b.loc), projection2(point)) > 20) { - loc = point; + point2 = geoLineIntersection([a.loc, b.loc], [poly[k], poly[k + 1]]); + if (point2 && geoVecLength(projection2(a.loc), projection2(point2)) > 20 && geoVecLength(projection2(b.loc), projection2(point2)) > 20) { + loc = point2; break; } } @@ -49401,6 +51582,7 @@ ${content} var import_fast_deep_equal8 = __toESM(require_fast_deep_equal()); function svgVertices(projection2, context) { var radiuses = { + // z16-, z17, z18+, w/icon shadow: [6, 7.5, 7.5, 12], stroke: [2.5, 3.5, 3.5, 8], fill: [1, 1.5, 1.5, 1.5] @@ -49645,8 +51827,11 @@ ${content} } var sets2 = { persistent: _currPersistent, + // persistent = important vertices (render always) selected: _currSelected, + // selected + siblings of selected (render always) hovered: _currHover + // hovered + siblings of hovered (render only in draw modes) }; var all = Object.assign({}, isMoving ? _currHover : {}, _currSelected, _currPersistent); var filterRendered = function(d) { @@ -49709,8 +51894,8 @@ ${content} } // modules/util/bind_once.js - function utilBindOnce(target, type3, listener, capture) { - var typeOnce = type3 + ".once"; + function utilBindOnce(target, type2, listener, capture) { + var typeOnce = type2 + ".once"; function one2() { target.on(typeOnce, null); listener.apply(this, arguments); @@ -49751,10 +51936,10 @@ ${content} selection2.on("pointerdown.zoom", pointerdown).on("wheel.zoom", wheeled).style("touch-action", "none").style("-webkit-tap-highlight-color", "rgba(0,0,0,0)"); select_default2(window).on("pointermove.zoompan", pointermove).on("pointerup.zoompan pointercancel.zoompan", pointerup); } - zoom.transform = function(collection, transform2, point) { + zoom.transform = function(collection, transform2, point2) { var selection2 = collection.selection ? collection.selection() : collection; if (collection !== selection2) { - schedule(collection, transform2, point); + schedule(collection, transform2, point2); } else { selection2.interrupt().each(function() { gesture(this, arguments).start(null).zoom(null, null, typeof transform2 === "function" ? transform2.apply(this, arguments) : transform2).end(null); @@ -49801,13 +51986,13 @@ ${content} function centroid(extent2) { return [(+extent2[0][0] + +extent2[1][0]) / 2, (+extent2[0][1] + +extent2[1][1]) / 2]; } - function schedule(transition2, transform2, point) { + function schedule(transition2, transform2, point2) { transition2.on("start.zoom", function() { gesture(this, arguments).start(null); }).on("interrupt.zoom end.zoom", function() { gesture(this, arguments).end(null); }).tween("zoom", function() { - var that = this, args = arguments, g = gesture(that, args), e = extent.apply(that, args), p = !point ? centroid(e) : typeof point === "function" ? point.apply(that, args) : point, w = Math.max(e[1][0] - e[0][0], e[1][1] - e[0][1]), a = _transform, b = typeof transform2 === "function" ? transform2.apply(that, args) : transform2, i2 = interpolate(a.invert(p).concat(w / a.k), b.invert(p).concat(w / b.k)); + var that = this, args = arguments, g = gesture(that, args), e = extent.apply(that, args), p = !point2 ? centroid(e) : typeof point2 === "function" ? point2.apply(that, args) : point2, w = Math.max(e[1][0] - e[0][0], e[1][1] - e[0][1]), a = _transform, b = typeof transform2 === "function" ? transform2.apply(that, args) : transform2, i2 = interpolate(a.invert(p).concat(w / a.k), b.invert(p).concat(w / b.k)); return function(t) { if (t === 1) { t = b; @@ -49996,7 +52181,8 @@ ${content} var _maxDistance = 20; var _pointer; function pointerIsValidFor(loc) { - return new Date().getTime() - _pointer.startTime <= _maxTimespan && geoVecLength(_pointer.startLoc, loc) <= _maxDistance; + return (/* @__PURE__ */ new Date()).getTime() - _pointer.startTime <= _maxTimespan && // all pointer events must occur within a small distance of the first pointerdown + geoVecLength(_pointer.startLoc, loc) <= _maxDistance; } function pointerdown(d3_event) { if (d3_event.ctrlKey || d3_event.button === 2) @@ -50008,7 +52194,7 @@ ${content} if (!_pointer) { _pointer = { startLoc: loc, - startTime: new Date().getTime(), + startTime: (/* @__PURE__ */ new Date()).getTime(), upCount: 0, pointerId: d3_event.pointerId }; @@ -50161,7 +52347,9 @@ ${content} } }); var detected = utilDetect(); - if ("GestureEvent" in window && !detected.isMobileWebKit) { + if ("GestureEvent" in window && // Listening for gesture events on iOS 13.4+ breaks double-tapping, + // but we only need to do this on desktop Safari anyway. – #7694 + !detected.isMobileWebKit) { surface.on("gesturestart.surface", function(d3_event) { d3_event.preventDefault(); _gestureTransformStart = projection2.transform(); @@ -50171,7 +52359,8 @@ ${content} _doubleUpHandler.on("doubleUp.map", function(d3_event, p02) { if (!_dblClickZoomEnabled) return; - if (typeof d3_event.target.__data__ === "object" && !select_default2(d3_event.target).classed("fill")) + if (typeof d3_event.target.__data__ === "object" && // or area fills + !select_default2(d3_event.target).classed("fill")) return; var zoomOut2 = d3_event.shiftKey; var t = projection2.transform(); @@ -50182,7 +52371,10 @@ ${content} map2.transformEase(t); }); context.on("enter.map", function() { - if (!map2.editableDataEnabled(true)) + if (!map2.editableDataEnabled( + true + /* skip zoom check */ + )) return; if (_isTransformed) return; @@ -50241,7 +52433,7 @@ ${content} function drawEditable(difference, extent) { var mode = context.mode(); var graph = context.graph(); - var features2 = context.features(); + var features = context.features(); var all = context.history().intersects(map2.extent()); var fullRedraw = false; var data; @@ -50265,9 +52457,9 @@ ${content} filter2 = function(d) { return set3.has(d.id); }; - features2.clear(data); + features.clear(data); } else { - if (features2.gatherStats(all, graph, _dimensions)) { + if (features.gatherStats(all, graph, _dimensions)) { extent = void 0; } if (extent) { @@ -50285,7 +52477,7 @@ ${content} } } if (applyFeatureLayerFilters) { - data = features2.filter(data, graph); + data = features.filter(data, graph); } else { context.features().resetStats(); } @@ -50326,7 +52518,9 @@ ${content} e.preventDefault(); var props = { deltaMode: 0, + // dummy values to ignore in zoomPan deltaY: 1, + // dummy values to ignore in zoomPan clientX: e.clientX, clientY: e.clientY, screenX: e.screenX, @@ -50361,7 +52555,9 @@ ${content} dY = sign2 * clamp( Math.exp((lines - 1) * 0.75) * 4.000244140625, 4.000244140625, + // min 350.000244140625 + // max ); if (detected.os !== "mac") { dY *= 5; @@ -50557,10 +52753,10 @@ ${content} var k2 = clamp(geoZoomToScale(z2, TILESIZE), kMin, kMax); proj.scale(k2); var t = proj.translate(); - var point = proj(loc2); + var point2 = proj(loc2); var center = pxCenter(); - t[0] += center[0] - point[0]; - t[1] += center[1] - point[1]; + t[0] += center[0] - point2[0]; + t[1] += center[1] - point2[1]; return setTransform(identity2.translate(t[0], t[1]).scale(k2), duration, force); } map2.pan = function(delta, duration) { @@ -50688,7 +52884,12 @@ ${content} }; map2.transformEase = function(t2, duration) { duration = duration || 250; - setTransform(t2, duration, false); + setTransform( + t2, + duration, + false + /* don't force */ + ); return map2; }; map2.zoomToEase = function(obj, duration) { @@ -50868,20 +53069,20 @@ ${content} photos.dateFilterValue = function(val) { return val === _dateFilters[0] ? _fromDate : _toDate; }; - photos.setDateFilter = function(type3, val, updateUrl) { + photos.setDateFilter = function(type2, val, updateUrl) { var date = val && new Date(val); if (date && !isNaN(date)) { val = date.toISOString().slice(0, 10); } else { val = null; } - if (type3 === _dateFilters[0]) { + if (type2 === _dateFilters[0]) { _fromDate = val; if (_fromDate && _toDate && new Date(_toDate) < new Date(_fromDate)) { _toDate = _fromDate; } } - if (type3 === _dateFilters[1]) { + if (type2 === _dateFilters[1]) { _toDate = val; if (_fromDate && _toDate && new Date(_toDate) < new Date(_fromDate)) { _fromDate = _toDate; @@ -51482,7 +53683,7 @@ ${content} tooltip.content(function() { var heading = _heading.apply(this, arguments); var text2 = _title.apply(this, arguments); - var keys = _keys.apply(this, arguments); + var keys2 = _keys.apply(this, arguments); var headingCallback = typeof heading === "function" ? heading : (s) => s.text(heading); var textCallback = typeof text2 === "function" ? text2 : (s) => s.text(text2); return function(selection2) { @@ -51492,12 +53693,12 @@ ${content} var textSelect = selection2.selectAll(".tooltip-text").data(text2 ? [text2] : []); textSelect.exit().remove(); textSelect.enter().append("div").attr("class", "tooltip-text").merge(textSelect).text("").call(textCallback); - var keyhintWrap = selection2.selectAll(".keyhint-wrap").data(keys && keys.length ? [0] : []); + var keyhintWrap = selection2.selectAll(".keyhint-wrap").data(keys2 && keys2.length ? [0] : []); keyhintWrap.exit().remove(); var keyhintWrapEnter = keyhintWrap.enter().append("div").attr("class", "keyhint-wrap"); keyhintWrapEnter.append("span").call(_t.append("tooltip_keyhint")); keyhintWrap = keyhintWrapEnter.merge(keyhintWrap); - keyhintWrap.selectAll("kbd.shortcut").data(keys && keys.length ? keys : []).enter().append("kbd").attr("class", "shortcut").text(function(d) { + keyhintWrap.selectAll("kbd.shortcut").data(keys2 && keys2.length ? keys2 : []).enter().append("kbd").attr("class", "shortcut").text(function(d) { return d; }); }; @@ -51563,8 +53764,8 @@ ${content} select_default2(this).call(tooltip).append("div").attr("class", "icon-wrap").call(svgIcon(d.icon && d.icon() || "#iD-operation-" + d.id, "operation")); }); if (showLabels) { - buttonsEnter.append("span").attr("class", "label").html(function(d) { - return d.title; + buttonsEnter.append("span").attr("class", "label").each(function(d) { + select_default2(this).call(d.title); }); } buttonsEnter.merge(buttons).classed("disabled", function(d) { @@ -51699,10 +53900,10 @@ ${content} // modules/ui/feature_info.js function uiFeatureInfo(context) { function update(selection2) { - var features2 = context.features(); - var stats = features2.stats(); + var features = context.features(); + var stats = features.stats(); var count = 0; - var hiddenList = features2.hidden().map(function(k) { + var hiddenList = features.hidden().map(function(k) { if (stats[k]) { count += stats[k]; return _t.append("inspector.title_count", { @@ -51841,16 +54042,19 @@ ${content} if (!isSupported()) return; var detected = utilDetect(); - var keys = detected.os === "mac" ? [uiCmd("\u2303\u2318F"), "f11"] : ["f11"]; - context.keybinding().on(keys, fullScreen); + var keys2 = detected.os === "mac" ? [uiCmd("\u2303\u2318F"), "f11"] : ["f11"]; + context.keybinding().on(keys2, fullScreen); }; } // modules/ui/geolocate.js function uiGeolocate(context) { var _geolocationOptions = { + // prioritize speed and power usage over precision enableHighAccuracy: false, + // don't hang indefinitely getting the location timeout: 6e3 + // 6sec }; var _locating = uiLoading(context).message(_t.html("geolocate.locating")).blocking(true); var _layer = context.layers().layer("geolocate"); @@ -51862,7 +54066,11 @@ ${content} if (context.inIntro()) return; if (!_layer.enabled() && !_locating.isShown()) { - _timeoutID = setTimeout(error, 1e4); + _timeoutID = setTimeout( + error, + 1e4 + /* 10sec */ + ); context.container().call(_locating); navigator.geolocation.getCurrentPosition(success, error, _geolocationOptions); } else { @@ -52557,10 +54765,10 @@ ${content} // modules/ui/intro/helper.js function pointBox(loc, context) { var rect = context.surfaceRect(); - var point = context.curtainProjection(loc); + var point2 = context.curtainProjection(loc); return { - left: point[0] + rect.left - 40, - top: point[1] + rect.top - 60, + left: point2[0] + rect.left - 40, + top: point2[1] + rect.top - 60, width: 80, height: 90 }; @@ -52569,10 +54777,10 @@ ${content} var box; if (locOrBox instanceof Array) { var rect = context.surfaceRect(); - var point = context.curtainProjection(locOrBox); + var point2 = context.curtainProjection(locOrBox); box = { - left: point[0] + rect.left, - top: point[1] + rect.top + left: point2[0] + rect.left, + top: point2[1] + rect.top }; } else { box = locOrBox; @@ -52591,6 +54799,7 @@ ${content} function helpHtml(id2, replacements) { if (!helpStringReplacements) { helpStringReplacements = { + // insert icons corresponding to various UI elements point_icon: icon("#iD-icon-point", "inline"), line_icon: icon("#iD-icon-line", "inline"), area_icon: icon("#iD-icon-area", "inline"), @@ -52604,6 +54813,7 @@ ${content} undo_icon: icon(_mainLocalizer.textDirection() === "rtl" ? "#iD-icon-redo" : "#iD-icon-undo", "inline"), redo_icon: icon(_mainLocalizer.textDirection() === "rtl" ? "#iD-icon-undo" : "#iD-icon-redo", "inline"), save_icon: icon("#iD-icon-save", "inline"), + // operation icons circularize_icon: icon("#iD-operation-circularize", "inline operation"), continue_icon: icon("#iD-operation-continue", "inline operation"), copy_icon: icon("#iD-operation-copy", "inline operation"), @@ -52621,6 +54831,7 @@ ${content} rotate_icon: icon("#iD-operation-rotate", "inline operation"), split_icon: icon("#iD-operation-split", "inline operation"), straighten_icon: icon("#iD-operation-straighten", "inline operation"), + // interaction icons leftclick: icon("#iD-walkthrough-mouse-left", "inline operation"), rightclick: icon("#iD-walkthrough-mouse-right", "inline operation"), mousewheel_icon: icon("#iD-walkthrough-mousewheel", "inline operation"), @@ -52629,6 +54840,7 @@ ${content} longpress_icon: icon("#iD-walkthrough-longpress", "inline operation"), touchdrag_icon: icon("#iD-walkthrough-touchdrag", "inline operation"), pinch_icon: icon("#iD-walkthrough-pinch-apart", "inline operation"), + // insert keys; may be localized and platform-dependent shift: uiCmd.display("\u21E7"), alt: uiCmd.display("\u2325"), return: uiCmd.display("\u21B5"), @@ -52637,6 +54849,7 @@ ${content} add_note_key: _t.html("modes.add_note.key"), help_key: _t.html("help.key"), shortcuts_key: _t.html("shortcuts.toggle.key"), + // reference localized UI labels directly so that they'll always match save: _t.html("save.title"), undo: _t.html("undo.title"), redo: _t.html("redo.title"), @@ -53067,7 +55280,7 @@ ${content} if (context.map().zoom() !== zoomStart) { context.map().on("move.intro", null); timeout2(function() { - continueTo(features2); + continueTo(features); }, 3e3); } }); @@ -53076,7 +55289,7 @@ ${content} nextStep(); } } - function features2() { + function features() { var onClick = function() { continueTo(pointsLinesAreas); }; @@ -56153,10 +58366,10 @@ ${content} var zMini = Math.max(zMain - _zDiff, 0.5); var kMini = geoZoomToScale(zMini); projection2.translate([tMain.x, tMain.y]).scale(kMini); - var point = projection2(loc); + var point2 = projection2(loc); var mouse = _gesture === "pan" ? geoVecSubtract([_tCurr.x, _tCurr.y], [_tStart.x, _tStart.y]) : [0, 0]; - var xMini = _cMini[0] - point[0] + tMain.x + mouse[0]; - var yMini = _cMini[1] - point[1] + tMain.y + mouse[1]; + var xMini = _cMini[0] - point2[0] + tMain.x + mouse[0]; + var yMini = _cMini[1] - point2[1] + tMain.y + mouse[1]; projection2.translate([xMini, yMini]).clipExtent([[0, 0], _dMini]); _tCurr = projection2.transform(); if (_isTransformed) { @@ -56203,10 +58416,10 @@ ${content} dataLayers = dataLayers.enter().append("svg").attr("class", "map-in-map-data").merge(dataLayers).call(dataLayer).call(debugLayer); if (_gesture !== "pan") { var getPath = path_default(projection2); - var bbox = { type: "Polygon", coordinates: [context.map().extent().polygon()] }; + var bbox2 = { type: "Polygon", coordinates: [context.map().extent().polygon()] }; viewport = wrap2.selectAll(".map-in-map-viewport").data([0]); viewport = viewport.enter().append("svg").attr("class", "map-in-map-viewport").merge(viewport); - var path = viewport.selectAll(".map-in-map-bbox").data([bbox]); + var path = viewport.selectAll(".map-in-map-bbox").data([bbox2]); path.enter().append("path").attr("class", "map-in-map-bbox").merge(path).attr("d", getPath).classed("thick", function(d) { return getPath.area(d) < 30; }); @@ -56621,7 +58834,7 @@ ${content} // modules/ui/combobox.js var _comboHideTimerID; function uiCombobox(context, klass) { - var dispatch10 = dispatch_default("accept", "cancel"); + var dispatch10 = dispatch_default("accept", "cancel", "update"); var container = context.container(); var _suggestions = []; var _data = []; @@ -56637,6 +58850,9 @@ ${content} cb(_data.filter(function(d) { var terms = d.terms || []; terms.push(d.value); + if (d.key) { + terms.push(d.key); + } return terms.some(function(term) { return term.toString().toLowerCase().indexOf(val.toLowerCase()) !== -1; }); @@ -56666,7 +58882,7 @@ ${content} return; if (input.classed("disabled")) return; - _tDown = +new Date(); + _tDown = +/* @__PURE__ */ new Date(); var start2 = input.property("selectionStart"); var end = input.property("selectionEnd"); if (start2 !== end) { @@ -56737,6 +58953,7 @@ ${content} var start2 = input.property("selectionStart"); input.node().setSelectionRange(start2, start2); input.on("input.combo-input", change); + change(false); }); break; case 9: @@ -56745,6 +58962,7 @@ ${content} case 13: d3_event.preventDefault(); d3_event.stopPropagation(); + accept(d3_event); break; case 38: if (tagName === "textarea" && !shown) @@ -56771,17 +58989,16 @@ ${content} case 27: cancel(); break; - case 13: - accept(d3_event); - break; } } - function change() { + function change(doAutoComplete) { + if (doAutoComplete === void 0) + doAutoComplete = true; fetchComboData(value(), function() { _selected = null; var val = input.property("value"); if (_suggestions.length) { - if (input.property("selectionEnd") === val.length) { + if (doAutoComplete && input.property("selectionEnd") === val.length) { _selected = tryAutocomplete(); } if (!_selected) { @@ -56810,7 +59027,8 @@ ${content} } index = Math.max(Math.min(index + dir, _suggestions.length - 1), 0); _selected = _suggestions[index].value; - input.property("value", _selected); + utilGetSetValue(input, _selected); + dispatch10.call("update"); } render(); ensureVisible(); @@ -56860,11 +59078,18 @@ ${content} var val = _caseSensitive ? value() : value().toLowerCase(); if (!val) return; - if (!isNaN(parseFloat(val)) && isFinite(val)) + if (isFinite(val)) return; + const suggestionValues = []; + _suggestions.forEach((s) => { + suggestionValues.push(s.value); + if (s.key && s.key !== s.value) { + suggestionValues.push(s.key); + } + }); var bestIndex = -1; - for (var i2 = 0; i2 < _suggestions.length; i2++) { - var suggestion = _suggestions[i2].value; + for (var i2 = 0; i2 < suggestionValues.length; i2++) { + var suggestion = suggestionValues[i2]; var compare = _caseSensitive ? suggestion : suggestion.toLowerCase(); if (compare === val) { bestIndex = i2; @@ -56874,9 +59099,10 @@ ${content} } } if (bestIndex !== -1) { - var bestVal = _suggestions[bestIndex].value; + var bestVal = suggestionValues[bestIndex]; input.property("value", bestVal); input.node().setSelectionRange(val.length, bestVal.length); + dispatch10.call("update"); return bestVal; } } @@ -56904,7 +59130,7 @@ ${content} select_default2(this).text(d.value); } }).on("mouseenter", _mouseEnterHandler).on("mouseleave", _mouseLeaveHandler).merge(options2).classed("selected", function(d) { - return d.value === _selected; + return d.value === _selected || d.key === _selected; }).on("click.combo-option", accept).order(); var node = attachTo ? attachTo.node() : input.node(); var containerRect = container.node().getBoundingClientRect(); @@ -57427,11 +59653,15 @@ ${content} var _impliedYes; var _entityIDs = []; var _value; + var stringsField = field.resolveReference("stringsCrossReference"); + if (!options2 && stringsField.options) { + options2 = stringsField.options; + } if (options2) { for (var i2 in options2) { var v = options2[i2]; values.push(v === "undefined" ? void 0 : v); - texts.push(field.t.html("options." + v, { "default": v })); + texts.push(stringsField.t.html("options." + v, { "default": v })); } } else { values = [void 0, "yes"]; @@ -57554,20 +59784,55 @@ ${content} return utilRebind(check, dispatch10, "on"); } + // modules/ui/length_indicator.js + function uiLengthIndicator(maxChars) { + var _wrap = select_default2(null); + var _tooltip = uiPopover("tooltip max-length-warning").placement("bottom").hasArrow(true).content(() => (selection2) => { + selection2.text(""); + selection2.call(svgIcon("#iD-icon-alert", "inline")); + selection2.call(_t.append("inspector.max_length_reached", { maxChars })); + }); + var _silent = false; + var lengthIndicator = function(selection2) { + _wrap = selection2.selectAll("span.length-indicator-wrap").data([0]); + _wrap = _wrap.enter().append("span").merge(_wrap).classed("length-indicator-wrap", true); + selection2.call(_tooltip); + }; + lengthIndicator.update = function(val) { + const strLen = utilUnicodeCharsCount(utilCleanOsmString(val, Number.POSITIVE_INFINITY)); + let indicator = _wrap.selectAll("span.length-indicator").data([strLen]); + indicator.enter().append("span").merge(indicator).classed("length-indicator", true).classed("limit-reached", (d) => d > maxChars).style("border-right-width", (d) => `${Math.abs(maxChars - d) * 2}px`).style("margin-right", (d) => d > maxChars ? `${(maxChars - d) * 2}px` : 0).style("opacity", (d) => d > maxChars * 0.8 ? Math.min(1, (d / maxChars - 0.8) / (1 - 0.8)) : 0).style("pointer-events", (d) => d > maxChars * 0.8 ? null : "none"); + if (_silent) + return; + if (strLen > maxChars) { + _tooltip.show(); + } else { + _tooltip.hide(); + } + }; + lengthIndicator.silent = function(val) { + if (!arguments.length) + return _silent; + _silent = val; + return lengthIndicator; + }; + return lengthIndicator; + } + // modules/ui/fields/combo.js function uiFieldCombo(field, context) { var dispatch10 = dispatch_default("change"); var _isMulti = field.type === "multiCombo" || field.type === "manyCombo"; var _isNetwork = field.type === "networkCombo"; var _isSemi = field.type === "semiCombo"; - var _optarray = field.options; var _showTagInfoSuggestions = field.type !== "manyCombo" && field.autoSuggestions !== false; var _allowCustomValues = field.type !== "manyCombo" && field.customValues !== false; var _snake_case = field.snake_case || field.snake_case === void 0; - var _combobox = uiCombobox(context, "combo-" + field.safeid).caseSensitive(field.caseSensitive).minItems(_isMulti || _isSemi ? 1 : 2); + var _combobox = uiCombobox(context, "combo-" + field.safeid).caseSensitive(field.caseSensitive).minItems(1); var _container = select_default2(null); var _inputWrap = select_default2(null); var _input = select_default2(null); + var _lengthIndicator = uiLengthIndicator(context.maxCharsForTagValue()); var _comboData = []; var _multiData = []; var _entityIDs = []; @@ -57583,7 +59848,7 @@ ${content} field.key += ":"; } function snake(s) { - return s.replace(/\s+/g, "_").toLowerCase(); + return s.replace(/\s+/g, "_"); } function clean2(s) { return s.split(";").map(function(s2) { @@ -57592,7 +59857,7 @@ ${content} } function tagValue(dval) { dval = clean2(dval || ""); - var found = _comboData.find(function(o) { + var found = getOptions(true).find(function(o) { return o.key && clean2(o.value) === dval; }); if (found) @@ -57600,12 +59865,26 @@ ${content} if (field.type === "typeCombo" && !dval) { return "yes"; } - return (_snake_case ? snake(dval) : dval) || void 0; + return restrictTagValueSpelling(dval) || void 0; + } + function restrictTagValueSpelling(dval) { + if (_snake_case) { + dval = snake(dval); + } + if (!field.caseSensitive) { + dval = dval.toLowerCase(); + } + return dval; + } + function getLabelId(field2, v) { + return field2.hasTextForStringId(`options.${v}.title`) ? `options.${v}.title` : `options.${v}`; } function displayValue(tval) { tval = tval || ""; - if (field.hasTextForStringId("options." + tval)) { - return field.t("options." + tval, { default: tval }); + var stringsField = field.resolveReference("stringsCrossReference"); + const labelId = getLabelId(stringsField, tval); + if (stringsField.hasTextForStringId(labelId)) { + return stringsField.t(labelId, { default: tval }); } if (field.type === "typeCombo" && tval.toLowerCase() === "yes") { return ""; @@ -57614,8 +59893,10 @@ ${content} } function renderValue(tval) { tval = tval || ""; - if (field.hasTextForStringId("options." + tval)) { - return field.t.append("options." + tval, { default: tval }); + var stringsField = field.resolveReference("stringsCrossReference"); + const labelId = getLabelId(stringsField, tval); + if (stringsField.hasTextForStringId(labelId)) { + return stringsField.t.append(labelId, { default: tval }); } if (field.type === "typeCombo" && tval.toLowerCase() === "yes") { tval = ""; @@ -57625,7 +59906,7 @@ ${content} function objectDifference(a, b) { return a.filter(function(d1) { return !b.some(function(d2) { - return !d2.isMixed && d1.value === d2.value; + return d1.value === d2.value; }); }); } @@ -57638,26 +59919,44 @@ ${content} setTaginfoValues("", setPlaceholder); } else { selection2.call(_combobox, attachTo); - setStaticValues(setPlaceholder); + setTimeout(() => setStaticValues(setPlaceholder), 0); } } - function setStaticValues(callback) { - if (!_optarray) - return; - _comboData = _optarray.map(function(v) { + function getOptions(allOptions) { + var stringsField = field.resolveReference("stringsCrossReference"); + if (!(field.options || stringsField.options)) + return []; + let options2; + if (allOptions !== true) { + options2 = field.options || stringsField.options; + } else { + options2 = [].concat(field.options, stringsField.options).filter(Boolean); + } + return options2.map(function(v) { + const labelId = getLabelId(stringsField, v); return { key: v, - value: field.t("options." + v, { default: v }), - title: v, - display: field.t.append("options." + v, { default: v }), - klass: field.hasTextForStringId("options." + v) ? "" : "raw-option" + value: stringsField.t(labelId, { default: v }), + title: stringsField.t(`options.${v}.description`, { default: v }), + display: addComboboxIcons(stringsField.t.append(labelId, { default: v }), v), + klass: stringsField.hasTextForStringId(labelId) ? "" : "raw-option" }; }); - _combobox.data(objectDifference(_comboData, _multiData)); + } + function setStaticValues(callback, filter2) { + _comboData = getOptions(); + if (filter2 !== void 0) { + _comboData = _comboData.filter(filter2); + } + _comboData = objectDifference(_comboData, _multiData); + _combobox.data(_comboData); if (callback) callback(_comboData); } function setTaginfoValues(q, callback) { + var queryFilter = (d) => d.value.toLowerCase().includes(q.toLowerCase()) || d.key.toLowerCase().includes(q.toLowerCase()); + setStaticValues(callback, queryFilter); + var stringsField = field.resolveReference("stringsCrossReference"); var fn = _isMulti ? "multikeys" : "values"; var query = (_isMulti ? field.key : "") + q; var hasCountryPrefix = _isNetwork && _countryCode && _countryCode.indexOf(q.toLowerCase()) === 0; @@ -57675,39 +59974,57 @@ ${content} services.taginfo[fn](params, function(err, data) { if (err) return; - data = data.filter(function(d) { - return field.type !== "typeCombo" || d.value !== "yes"; + data = data.filter((d) => field.type !== "typeCombo" || d.value !== "yes"); + data = data.filter((d) => { + var value = d.value; + if (_isMulti) { + value = value.slice(field.key.length); + } + return value === restrictTagValueSpelling(value); }); var deprecatedValues = osmEntity.deprecatedTagValuesByKey(_dataDeprecated)[field.key]; if (deprecatedValues) { - data = data.filter(function(d) { - return deprecatedValues.indexOf(d.value) === -1; - }); + data = data.filter((d) => !deprecatedValues.includes(d.value)); } if (hasCountryPrefix) { - data = data.filter(function(d) { - return d.value.toLowerCase().indexOf(_countryCode + ":") === 0; - }); + data = data.filter((d) => d.value.toLowerCase().indexOf(_countryCode + ":") === 0); } + const additionalOptions = (field.options || stringsField.options || []).filter((v) => !data.some((dv) => dv.value === (_isMulti ? field.key + v : v))).map((v) => ({ value: v })); _container.classed("empty-combobox", data.length === 0); - _comboData = data.map(function(d) { - var k = d.value; + _comboData = data.concat(additionalOptions).map(function(d) { + var v = d.value; if (_isMulti) - k = k.replace(field.key, ""); - var label = field.t("options." + k, { default: k }); + v = v.replace(field.key, ""); + const labelId = getLabelId(stringsField, v); + var isLocalizable = stringsField.hasTextForStringId(labelId); + var label = stringsField.t(labelId, { default: v }); return { - key: k, - value: _isMulti ? k : label, - display: field.t.append("options." + k, { default: k }), - title: d.title || label, - klass: field.hasTextForStringId("options." + k) ? "" : "raw-option" + key: v, + value: label, + title: stringsField.t(`options.${v}.description`, { default: isLocalizable ? v : d.title !== label ? d.title : "" }), + display: addComboboxIcons(stringsField.t.append(labelId, { default: v }), v), + klass: isLocalizable ? "" : "raw-option" }; }); + _comboData = _comboData.filter(queryFilter); _comboData = objectDifference(_comboData, _multiData); if (callback) callback(_comboData); }); } + function addComboboxIcons(disp, value) { + const iconsField = field.resolveReference("iconsCrossReference"); + if (iconsField.icons) { + return function(selection2) { + var span = selection2.insert("span", ":first-child").attr("class", "tag-value-icon"); + if (iconsField.icons[value]) { + span.call(svgIcon(`#${iconsField.icons[value]}`)); + } + disp.call(this, selection2); + }; + } + return disp; + } function setPlaceholder(values) { if (_isMulti || _isSemi) { _staticPlaceholder = field.placeholder() || _t("inspector.add"); @@ -57732,17 +60049,26 @@ ${content} ph = _staticPlaceholder; } _container.selectAll("input").attr("placeholder", ph); + var hideAdd = !_allowCustomValues && !values.length; + _container.selectAll(".chiplist .input-wrap").style("display", hideAdd ? "none" : null); } function change() { var t = {}; var val; if (_isMulti || _isSemi) { - val = tagValue(utilGetSetValue(_input).replace(/,/g, ";")) || ""; - _container.classed("active", false); - utilGetSetValue(_input, ""); - var vals = val.split(";").filter(Boolean); + var vals; + if (_isMulti) { + vals = [tagValue(utilGetSetValue(_input))]; + } else if (_isSemi) { + val = tagValue(utilGetSetValue(_input)) || ""; + val = val.replace(/,/g, ";"); + vals = val.split(";"); + } + vals = vals.filter(Boolean); if (!vals.length) return; + _container.classed("active", false); + utilGetSetValue(_input, ""); if (_isMulti) { utilArrayUniq(vals).forEach(function(v) { var key = (field.key || "") + v; @@ -57786,13 +60112,23 @@ ${content} }).filter(Boolean); arr = utilArrayUniq(arr); t[field.key] = arr.length ? arr.join(";") : void 0; + _lengthIndicator.update(t[field.key]); + } + dispatch10.call("change", this, t); + } + function invertMultikey(d3_event, d) { + d3_event.preventDefault(); + d3_event.stopPropagation(); + var t = {}; + if (_isMulti) { + t[d.key] = _tags[d.key] === "yes" ? "no" : "yes"; } dispatch10.call("change", this, t); } function combo(selection2) { _container = selection2.selectAll(".form-field-input-wrap").data([0]); - var type3 = _isMulti || _isSemi ? "multicombo" : "combo"; - _container = _container.enter().append("div").attr("class", "form-field-input-wrap form-field-input-" + type3).merge(_container); + var type2 = _isMulti || _isSemi ? "multicombo" : "combo"; + _container = _container.enter().append("div").attr("class", "form-field-input-wrap form-field-input-" + type2).merge(_container); if (_isMulti || _isSemi) { _container = _container.selectAll(".chiplist").data([0]); var listClass = "chiplist"; @@ -57806,17 +60142,31 @@ ${content} }).merge(_container); _inputWrap = _container.selectAll(".input-wrap").data([0]); _inputWrap = _inputWrap.enter().append("li").attr("class", "input-wrap").merge(_inputWrap); + var hideAdd = !_allowCustomValues && !_comboData.length; + _inputWrap.style("display", hideAdd ? "none" : null); _input = _inputWrap.selectAll("input").data([0]); } else { _input = _container.selectAll("input").data([0]); } _input = _input.enter().append("input").attr("type", "text").attr("id", field.domId).call(utilNoAuto).call(initCombo, selection2).merge(_input); + if (_isSemi) { + _inputWrap.call(_lengthIndicator); + } else if (!_isMulti) { + _container.call(_lengthIndicator); + } if (_isNetwork) { var extent = combinedEntityExtent(); var countryCode = extent && iso1A2Code(extent.center()); _countryCode = countryCode && countryCode.toLowerCase(); } - _input.on("change", change).on("blur", change); + _input.on("change", change).on("blur", change).on("input", function() { + let val = utilGetSetValue(_input); + updateIcon(val); + if (_isSemi && _tags[field.key]) { + val += ";" + _tags[field.key]; + } + _lengthIndicator.update(val); + }); _input.on("keydown.field", function(d3_event) { switch (d3_event.keyCode) { case 13: @@ -57834,9 +60184,34 @@ ${content} _container.classed("active", true); }); } + _combobox.on("cancel", function() { + _input.node().blur(); + }).on("update", function() { + updateIcon(utilGetSetValue(_input)); + }); + } + function updateIcon(value) { + value = tagValue(value); + let container = _container; + if (field.type === "multiCombo" || field.type === "semiCombo") { + container = _container.select(".input-wrap"); + } + const iconsField = field.resolveReference("iconsCrossReference"); + if (iconsField.icons) { + container.selectAll(".tag-value-icon").remove(); + if (iconsField.icons[value]) { + container.selectAll(".tag-value-icon").data([value]).enter().insert("div", "input").attr("class", "tag-value-icon").call(svgIcon(`#${iconsField.icons[value]}`)); + } + } } combo.tags = function(tags) { _tags = tags; + var stringsField = field.resolveReference("stringsCrossReference"); + var isMixed = Array.isArray(tags[field.key]); + var showsValue = (value) => !isMixed && value && !(field.type === "typeCombo" && value === "yes"); + var isRawValue = (value) => showsValue(value) && !stringsField.hasTextForStringId(`options.${value}`) && !stringsField.hasTextForStringId(`options.${value}.title`); + var isKnownValue = (value) => showsValue(value) && !isRawValue(value); + var isReadOnly = !_allowCustomValues; if (_isMulti || _isSemi) { _multiData = []; var maxLength; @@ -57847,13 +60222,12 @@ ${content} if (!field.key && field.keys.indexOf(k) === -1) continue; var v = tags[k]; - if (!v || typeof v === "string" && v.toLowerCase() === "no") - continue; var suffix = field.key ? k.slice(field.key.length) : k; _multiData.push({ key: k, value: displayValue(suffix), - display: renderValue(suffix), + display: addComboboxIcons(renderValue(suffix), suffix), + state: typeof v === "string" ? v.toLowerCase() : "", isMixed: Array.isArray(v) }); } @@ -57887,7 +60261,7 @@ ${content} return { key: v2, value: displayValue(v2), - display: renderValue(v2), + display: addComboboxIcons(renderValue(v2), v2), isMixed: !commonValues.includes(v2) }; }); @@ -57898,11 +60272,9 @@ ${content} } } maxLength = Math.max(0, maxLength); - var allowDragAndDrop = _isSemi && !Array.isArray(tags[field.key]); - var available = objectDifference(_comboData, _multiData); - _combobox.data(available); - var hideAdd = !_allowCustomValues && !available.length || maxLength <= 0; + var hideAdd = maxLength <= 0 || !_allowCustomValues && !_comboData.length; _container.selectAll(".chiplist .input-wrap").style("display", hideAdd ? "none" : null); + var allowDragAndDrop = _isSemi && !Array.isArray(tags[field.key]); var chips = _container.selectAll(".chip").data(_multiData); chips.exit().remove(); var enter = chips.enter().insert("li", ".input-wrap").attr("class", "chip"); @@ -57912,12 +60284,22 @@ ${content} var k2 = d.key; if (_isMulti) k2 = k2.replace(field.key, ""); - return !field.hasTextForStringId("options." + k2); + return !stringsField.hasTextForStringId("options." + k2); }).classed("draggable", allowDragAndDrop).classed("mixed", function(d) { return d.isMixed; }).attr("title", function(d) { - return d.isMixed ? _t("inspector.unshared_value_tooltip") : null; - }); + if (d.isMixed) { + return _t("inspector.unshared_value_tooltip"); + } + if (!["yes", "no"].includes(d.state)) { + return d.state; + } + return null; + }).classed("negated", (d) => d.state === "no"); + if (!_isSemi) { + chips.selectAll("input[type=checkbox]").remove(); + chips.insert("input", "span").attr("type", "checkbox").property("checked", (d) => d.state === "yes").property("indeterminate", (d) => d.isMixed || !["yes", "no"].includes(d.state)).on("click", invertMultikey); + } if (allowDragAndDrop) { registerDragAndDrop(chips); } @@ -57931,17 +60313,13 @@ ${content} } }); chips.select("a").attr("href", "#").on("click", removeMultikey).attr("class", "remove").text("\xD7"); + updateIcon(""); } else { - var isMixed = Array.isArray(tags[field.key]); var mixedValues = isMixed && tags[field.key].map(function(val) { return displayValue(val); }).filter(Boolean); - var showsValue = !isMixed && tags[field.key] && !(field.type === "typeCombo" && tags[field.key] === "yes"); - var isRawValue = showsValue && !field.hasTextForStringId("options." + tags[field.key]); - var isKnownValue = showsValue && !isRawValue; - var isReadOnly = !_allowCustomValues || isKnownValue; - utilGetSetValue(_input, !isMixed ? displayValue(tags[field.key]) : "").classed("raw-value", isRawValue).classed("known-value", isKnownValue).attr("readonly", isReadOnly ? "readonly" : void 0).attr("title", isMixed ? mixedValues.join("\n") : void 0).attr("placeholder", isMixed ? _t("inspector.multiple_values") : _staticPlaceholder || "").classed("mixed", isMixed).on("keydown.deleteCapture", function(d3_event) { - if (isReadOnly && isKnownValue && (d3_event.keyCode === utilKeybinding.keyCodes["\u232B"] || d3_event.keyCode === utilKeybinding.keyCodes["\u2326"])) { + utilGetSetValue(_input, !isMixed ? displayValue(tags[field.key]) : "").data([tags[field.key]]).classed("raw-value", isRawValue).classed("known-value", isKnownValue).attr("readonly", isReadOnly ? "readonly" : void 0).attr("title", isMixed ? mixedValues.join("\n") : void 0).attr("placeholder", isMixed ? _t("inspector.multiple_values") : _staticPlaceholder || "").classed("mixed", isMixed).on("keydown.deleteCapture", function(d3_event) { + if (isReadOnly && isKnownValue(tags[field.key]) && (d3_event.keyCode === utilKeybinding.keyCodes["\u232B"] || d3_event.keyCode === utilKeybinding.keyCodes["\u2326"])) { d3_event.preventDefault(); d3_event.stopPropagation(); var t = {}; @@ -57949,7 +60327,19 @@ ${content} dispatch10.call("change", this, t); } }); + if (!Array.isArray(tags[field.key])) { + updateIcon(tags[field.key]); + } + if (!isMixed) { + _lengthIndicator.update(tags[field.key]); + } } + const refreshStyles = () => { + _input.data([tagValue(utilGetSetValue(_input))]).classed("raw-value", isRawValue).classed("known-value", isKnownValue); + }; + _input.on("input.refreshStyles", refreshStyles); + _combobox.on("update.refreshStyles", refreshStyles); + refreshStyles(); }; function registerDragAndDrop(selection2) { var dragOrigin, targetIndex; @@ -57962,7 +60352,8 @@ ${content} targetIndex = null; }).on("drag", function(d3_event) { var x = d3_event.x - dragOrigin.x, y = d3_event.y - dragOrigin.y; - if (!select_default2(this).classed("dragging") && Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)) <= 5) + if (!select_default2(this).classed("dragging") && // don't display drag until dragging beyond a distance threshold + Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)) <= 5) return; var index = selection2.nodes().indexOf(this); select_default2(this).classed("dragging", true); @@ -58051,14 +60442,20 @@ ${content} } // modules/ui/fields/input.js + var likelyRawNumberFormat = /^-?(0\.\d*|\d*\.\d{0,2}(\d{4,})?|\d{4,}\.\d{3})$/; function uiFieldText(field, context) { var dispatch10 = dispatch_default("change"); var input = select_default2(null); var outlinkButton = select_default2(null); var wrap2 = select_default2(null); + var _lengthIndicator = uiLengthIndicator(context.maxCharsForTagValue()); var _entityIDs = []; var _tags; var _phoneFormats = {}; + const isDirectionField = field.key.split(":").some((keyPart) => keyPart === "direction"); + const formatFloat = _mainLocalizer.floatFormatter(_mainLocalizer.languageCode()); + const parseLocaleFloat = _mainLocalizer.floatParser(_mainLocalizer.languageCode()); + const countDecimalPlaces = _mainLocalizer.decimalPlaceCounter(_mainLocalizer.languageCode()); if (field.type === "tel") { _mainFileFetcher.get("phone_formats").then(function(d) { _phoneFormats = d; @@ -58088,6 +60485,7 @@ ${content} input = wrap2.selectAll("input").data([0]); input = input.enter().append("input").attr("type", field.type === "identifier" ? "text" : field.type).attr("id", field.domId).classed(field.type, true).call(utilNoAuto).merge(input); input.classed("disabled", !!isLocked).attr("readonly", isLocked || null).on("input", change(true)).on("blur", change()).on("change", change()); + wrap2.call(_lengthIndicator); if (field.type === "tel") { updatePhonePlaceholder(); } else if (field.type === "number") { @@ -58103,16 +60501,31 @@ ${content} return _t(`inspector.${which}`); }).merge(buttons).on("click", function(d3_event, d) { d3_event.preventDefault(); + var isMixed = Array.isArray(_tags[field.key]); + if (isMixed) + return; var raw_vals = input.node().value || "0"; var vals = raw_vals.split(";"); vals = vals.map(function(v) { - var num = parseFloat(v.trim(), 10); - if (isFinite(num)) - return clamped(num + d); - const compassDir = cardinal[v.trim().toLowerCase()]; - if (compassDir !== void 0) - return clamped(compassDir + d); - return v.trim(); + v = v.trim(); + const isRawNumber = likelyRawNumberFormat.test(v); + var num = isRawNumber ? parseFloat(v) : parseLocaleFloat(v); + if (isDirectionField) { + const compassDir = cardinal[v.toLowerCase()]; + if (compassDir !== void 0) { + num = compassDir; + } + } + if (!isFinite(num)) + return v; + num = parseFloat(num); + if (!isFinite(num)) + return v; + num += d; + if (isDirectionField) { + num = (num % 360 + 360) % 360; + } + return formatFloat(clamped(num), isRawNumber ? v.includes(".") ? v.split(".")[1].length : 0 : countDecimalPlaces(v)); }); input.node().value = vals.join(";"); change()(); @@ -58144,27 +60557,32 @@ ${content} if (value) window.open(value, "_blank"); }).merge(outlinkButton); - } else if (field.key.split(":").includes("colour")) { + } else if (field.type === "colour") { input.attr("type", "text"); updateColourPreview(); + } else if (field.type === "date") { + input.attr("type", "text"); + updateDateField(); } } - function isColourValid(colour) { - if (!colour.match(/^(#([0-9a-fA-F]{3}){1,2}|\w+)$/)) { - return false; - } else if (!CSS.supports("color", colour) || ["unset", "inherit", "initial", "revert"].includes(colour)) { - return false; - } - return true; - } function updateColourPreview() { + function isColourValid(colour2) { + if (!colour2.match(/^(#([0-9a-fA-F]{3}){1,2}|\w+)$/)) { + return false; + } else if (!CSS.supports("color", colour2) || ["unset", "inherit", "initial", "revert"].includes(colour2)) { + return false; + } + return true; + } wrap2.selectAll(".colour-preview").remove(); const colour = utilGetSetValue(input); - if (!isColourValid(colour) && colour !== "") + if (!isColourValid(colour) && colour !== "") { + wrap2.selectAll("input.colour-selector").remove(); + wrap2.selectAll(".form-field-button").remove(); return; + } var colourSelector = wrap2.selectAll(".colour-selector").data([0]); - outlinkButton = wrap2.selectAll(".colour-preview").data([colour]); - colourSelector.enter().append("input").attr("type", "color").attr("class", "form-field-button colour-selector").attr("value", colour).on("input", debounce_default(function(d3_event) { + colourSelector.enter().append("input").attr("type", "color").attr("class", "colour-selector").on("input", debounce_default(function(d3_event) { d3_event.preventDefault(); var colour2 = this.value; if (!isColourValid(colour2)) @@ -58173,11 +60591,51 @@ ${content} change()(); updateColourPreview(); }, 100)); - outlinkButton = outlinkButton.enter().append("div").attr("class", "form-field-button colour-preview").append("div").style("background-color", (d) => d).attr("class", "colour-box"); + wrap2.selectAll("input.colour-selector").attr("value", colour); + var chooserButton = wrap2.selectAll(".colour-preview").data([colour]); + chooserButton = chooserButton.enter().append("div").attr("class", "form-field-button colour-preview").append("div").style("background-color", (d) => d).attr("class", "colour-box"); if (colour === "") { - outlinkButton = outlinkButton.call(svgIcon("#iD-icon-edit")); + chooserButton = chooserButton.call(svgIcon("#iD-icon-edit")); + } + chooserButton.on("click", () => wrap2.select(".colour-selector").node().showPicker()); + } + function updateDateField() { + function isDateValid(date2) { + return date2.match(/^[0-9]{4}(-[0-9]{2}(-[0-9]{2})?)?$/); + } + const date = utilGetSetValue(input); + const now3 = /* @__PURE__ */ new Date(); + const today = new Date(now3.getTime() - now3.getTimezoneOffset() * 6e4).toISOString().split("T")[0]; + if ((field.key === "check_date" || field.key === "survey:date") && date !== today) { + wrap2.selectAll(".date-set-today").data([0]).enter().append("button").attr("class", "form-field-button date-set-today").call(svgIcon("#fas-rotate")).call(uiTooltip().title(() => _t.append("inspector.set_today"))).on("click", () => { + utilGetSetValue(input, today); + change()(); + updateDateField(); + }); + } else { + wrap2.selectAll(".date-set-today").remove(); + } + if (!isDateValid(date) && date !== "") { + wrap2.selectAll("input.date-selector").remove(); + wrap2.selectAll(".date-calendar").remove(); + return; + } + if (utilDetect().browser !== "Safari") { + var dateSelector = wrap2.selectAll(".date-selector").data([0]); + dateSelector.enter().append("input").attr("type", "date").attr("class", "date-selector").on("input", debounce_default(function(d3_event) { + d3_event.preventDefault(); + var date2 = this.value; + if (!isDateValid(date2)) + return; + utilGetSetValue(input, this.value); + change()(); + updateDateField(); + }, 100)); + wrap2.selectAll("input.date-selector").attr("value", date); + var calendarButton = wrap2.selectAll(".date-calendar").data([date]); + calendarButton = calendarButton.enter().append("button").attr("class", "form-field-button date-calendar").call(svgIcon("#fas-calendar-days")); + calendarButton.on("click", () => wrap2.select(".date-selector").node().showPicker()); } - outlinkButton.on("click", () => wrap2.select(".colour-selector").node().click()).merge(outlinkButton); } function updatePhonePlaceholder() { if (input.empty() || !Object.keys(_phoneFormats).length) @@ -58211,27 +60669,53 @@ ${content} } return num; } + function getVals(tags) { + if (field.keys) { + const multiSelection = context.selectedIDs(); + tags = multiSelection.length > 1 ? context.selectedIDs().map((id2) => context.graph().entity(id2)).map((entity) => entity.tags) : [tags]; + return tags.map((tags2) => new Set(field.keys.reduce((acc, key) => acc.concat(tags2[key]), []).filter(Boolean))).map((vals) => vals.size === 0 ? /* @__PURE__ */ new Set([void 0]) : vals).reduce((a, b) => /* @__PURE__ */ new Set([...a, ...b])); + } else { + return new Set([].concat(tags[field.key])); + } + } function change(onInput) { return function() { var t = {}; var val = utilGetSetValue(input); if (!onInput) val = context.cleanTagValue(val); - if (!val && Array.isArray(_tags[field.key])) + if (!val && getVals(_tags).size > 1) return; - if (!onInput) { - if (field.type === "number" && val) { - var vals = val.split(";"); - vals = vals.map(function(v) { - var num = parseFloat(v.trim(), 10); - return isFinite(num) ? clamped(num) : v.trim(); - }); - val = vals.join(";"); - } - utilGetSetValue(input, val); + var displayVal = val; + if (field.type === "number" && val) { + var numbers2 = val.split(";"); + numbers2 = numbers2.map(function(v) { + if (likelyRawNumberFormat.test(v)) { + return v; + } + var num = parseLocaleFloat(v); + const fractionDigits = countDecimalPlaces(v); + return isFinite(num) ? clamped(num).toFixed(fractionDigits) : v; + }); + val = numbers2.join(";"); } + if (!onInput) + utilGetSetValue(input, displayVal); t[field.key] = val || void 0; - dispatch10.call("change", this, t, onInput); + if (field.keys) { + dispatch10.call("change", this, (tags) => { + if (field.keys.some((key) => tags[key])) { + field.keys.filter((key) => tags[key]).forEach((key) => { + tags[key] = val || void 0; + }); + } else { + tags[field.key] = val || void 0; + } + return tags; + }, onInput); + } else { + dispatch10.call("change", this, t, onInput); + } }; } i2.entityIDs = function(val) { @@ -58242,14 +60726,56 @@ ${content} }; i2.tags = function(tags) { _tags = tags; - var isMixed = Array.isArray(tags[field.key]); - utilGetSetValue(input, !isMixed && tags[field.key] ? tags[field.key] : "").attr("title", isMixed ? tags[field.key].filter(Boolean).join("\n") : void 0).attr("placeholder", isMixed ? _t("inspector.multiple_values") : field.placeholder() || _t("inspector.unknown")).classed("mixed", isMixed); - if (field.key.split(":").includes("colour")) + const vals = getVals(tags); + const isMixed = vals.size > 1; + var val = vals.size === 1 ? [...vals][0] : ""; + var shouldUpdate; + if (field.type === "number" && val) { + var numbers2 = val.split(";"); + var oriNumbers = utilGetSetValue(input).split(";"); + if (numbers2.length !== oriNumbers.length) + shouldUpdate = true; + numbers2 = numbers2.map(function(v) { + v = v.trim(); + var num = Number(v); + if (!isFinite(num) || v === "") + return v; + const fractionDigits = v.includes(".") ? v.split(".")[1].length : 0; + return formatFloat(num, fractionDigits); + }); + val = numbers2.join(";"); + shouldUpdate = (inputValue, setValue) => { + const inputNums = inputValue.split(";").map( + (setVal) => likelyRawNumberFormat.test(setVal) ? parseFloat(setVal) : parseLocaleFloat(setVal) + ); + const setNums = setValue.split(";").map(parseLocaleFloat); + return !isEqual_default(inputNums, setNums); + }; + } + utilGetSetValue(input, val, shouldUpdate).attr("title", isMixed ? [...vals].join("\n") : void 0).attr("placeholder", isMixed ? _t("inspector.multiple_values") : field.placeholder() || _t("inspector.unknown")).classed("mixed", isMixed); + if (field.type === "number") { + const buttons = wrap2.selectAll(".increment, .decrement"); + if (isMixed) { + buttons.attr("disabled", "disabled").classed("disabled", true); + } else { + var raw_vals = tags[field.key] || "0"; + const canIncDec = raw_vals.split(";").some((val2) => isFinite(Number(val2)) || isDirectionField && cardinal[val2.trim().toLowerCase()]); + buttons.attr("disabled", canIncDec ? null : "disabled").classed("disabled", !canIncDec); + } + } + if (field.type === "tel") + updatePhonePlaceholder(); + if (field.type === "colour") updateColourPreview(); + if (field.type === "date") + updateDateField(); if (outlinkButton && !outlinkButton.empty()) { var disabled = !validIdentifierValueForLink(); outlinkButton.classed("disabled", disabled); } + if (!isMixed) { + _lengthIndicator.update(tags[field.key]); + } }; i2.focus = function() { var node = input.node(); @@ -58299,7 +60825,7 @@ ${content} tag[d] = value || void 0; dispatch10.call("change", this, tag); } - access.options = function(type3) { + access.options = function(type2) { var options2 = [ "yes", "no", @@ -58311,15 +60837,16 @@ ${content} "permit", "unknown" ]; - if (type3 === "access") { + if (type2 === "access") { options2 = options2.filter((v) => v !== "yes" && v !== "designated"); } - if (type3 === "bicycle") { + if (type2 === "bicycle") { options2.splice(options2.length - 4, 0, "dismount"); } + var stringsField = field.resolveReference("stringsCrossReference"); return options2.map(function(option) { return { - title: field.t("options." + option + ".description"), + title: stringsField.t("options." + option + ".description"), value: option }; }); @@ -58550,73 +61077,82 @@ ${content} } }).catch(function() { }); - function getNearStreets() { + function getNear(isAddressable, type2, searchRadius, resultProp) { var extent = combinedEntityExtent(); var l = extent.center(); - var box = geoExtent(l).padByMeters(200); - var streets = context.history().intersects(box).filter(isAddressable).map(function(d) { - var loc = context.projection([ - (extent[0][0] + extent[1][0]) / 2, - (extent[0][1] + extent[1][1]) / 2 - ]); - var choice = geoChooseEdge(context.graph().childNodes(d), loc, context.projection); + var box = geoExtent(l).padByMeters(searchRadius); + var features = context.history().intersects(box).filter(isAddressable).map((d) => { + let dist = geoSphericalDistance(d.extent(context.graph()).center(), l); + if (d.type === "way") { + var loc = context.projection([ + (extent[0][0] + extent[1][0]) / 2, + (extent[0][1] + extent[1][1]) / 2 + ]); + var choice = geoChooseEdge(context.graph().childNodes(d), loc, context.projection); + dist = Math.min(dist, choice.distance); + } + const value = resultProp && d.tags[resultProp] ? d.tags[resultProp] : d.tags.name; + let title = value; + if (type2 === "street") { + title = `${addrField.t("placeholders.street")}: ${title}`; + } else if (type2 === "place") { + title = `${addrField.t("placeholders.place")}: ${title}`; + } return { - title: d.tags.name, - value: d.tags.name, - dist: choice.distance + title, + value, + dist, + type: type2, + klass: `address-${type2}` }; }).sort(function(a, b) { return a.dist - b.dist; }); - return utilArrayUniqBy(streets, "value"); + return utilArrayUniqBy(features, "value"); + } + function getNearStreets() { function isAddressable(d) { return d.tags.highway && d.tags.name && d.type === "way"; } + return getNear(isAddressable, "street", 200); + } + function getNearPlaces() { + function isAddressable(d) { + if (d.tags.name) { + if (d.tags.place) + return true; + if (d.tags.boundary === "administrative" && d.tags.admin_level > 8) + return true; + } + return false; + } + return getNear(isAddressable, "place", 200); } function getNearCities() { - var extent = combinedEntityExtent(); - var l = extent.center(); - var box = geoExtent(l).padByMeters(200); - var cities = context.history().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: geoSphericalDistance(d.extent(context.graph()).center(), l) - }; - }).sort(function(a, b) { - return a.dist - b.dist; - }); - return utilArrayUniqBy(cities, "value"); function isAddressable(d) { if (d.tags.name) { - if (d.tags.admin_level === "8" && d.tags.boundary === "administrative") + if (d.tags.boundary === "administrative" && d.tags.admin_level === "8") return true; if (d.tags.border_type === "city") return true; if (d.tags.place === "city" || d.tags.place === "town" || d.tags.place === "village") return true; } - if (d.tags["addr:city"]) + if (d.tags[`${field.key}:city`]) return true; return false; } + return getNear(isAddressable, "city", 200, `${field.key}:city`); + } + function getNearPostcodes() { + return [...new Set([].concat(getNearValues("postcode")).concat(getNear((d) => d.tags.postal_code, "postcode", 200, "postal_code")))]; } function getNearValues(key) { - var extent = combinedEntityExtent(); - var l = extent.center(); - var box = geoExtent(l).padByMeters(200); - var results = context.history().intersects(box).filter(function hasTag(d) { - return _entityIDs.indexOf(d.id) === -1 && d.tags[key]; - }).map(function(d) { - return { - title: d.tags[key], - value: d.tags[key], - dist: geoSphericalDistance(d.extent(context.graph()).center(), l) - }; - }).sort(function(a, b) { - return a.dist - b.dist; - }); - return utilArrayUniqBy(results, "value"); + const tagKey = `${field.key}:${key}`; + function hasTag(d) { + return _entityIDs.indexOf(d.id) === -1 && d.tags[tagKey]; + } + return getNear(hasTag, key, 200, tagKey); } function updateForCountryCode() { if (!_countryCode) @@ -58644,12 +61180,15 @@ ${content} "quarter", "state", "street", + "street+place", "subdistrict", "suburb" ]; var widths = addressFormat.widths || { - housenumber: 1 / 3, - street: 2 / 3, + housenumber: 1 / 5, + unit: 1 / 5, + street: 1 / 2, + place: 1 / 2, city: 2 / 3, state: 1 / 4, postcode: 1 / 3 @@ -58677,10 +61216,36 @@ ${content} function addDropdown(d) { if (dropdowns.indexOf(d.id) === -1) return; - var nearValues = d.id === "street" ? getNearStreets : d.id === "city" ? getNearCities : getNearValues; + var nearValues; + switch (d.id) { + case "street": + nearValues = getNearStreets; + break; + case "place": + nearValues = getNearPlaces; + break; + case "street+place": + nearValues = () => [].concat(getNearStreets()).concat(getNearPlaces()); + d.isAutoStreetPlace = true; + d.id = _tags[`${field.key}:place`] ? "place" : "street"; + break; + case "city": + nearValues = getNearCities; + break; + case "postcode": + nearValues = getNearPostcodes; + break; + default: + nearValues = getNearValues; + } select_default2(this).call( - uiCombobox(context, "address-" + d.id).minItems(1).caseSensitive(true).fetcher(function(value, callback) { - callback(nearValues("addr:" + d.id)); + uiCombobox(context, `address-${d.isAutoStreetPlace ? "street-place" : d.id}`).minItems(1).caseSensitive(true).fetcher(function(typedValue, callback) { + typedValue = typedValue.toLowerCase(); + callback(nearValues(d.id).filter((v) => v.value.toLowerCase().indexOf(typedValue) !== -1)); + }).on("accept", function(selected) { + if (d.isAutoStreetPlace) { + d.id = selected ? selected.type : "street"; + } }) ); } @@ -58710,17 +61275,26 @@ ${content} } function change(onInput) { return function() { - var tags = {}; - _wrap.selectAll("input").each(function(subfield) { - var key = field.key + ":" + subfield.id; - var value = this.value; - if (!onInput) - value = context.cleanTagValue(value); - if (Array.isArray(_tags[key]) && !value) - return; - tags[key] = value || void 0; - }); - dispatch10.call("change", this, tags, onInput); + setTimeout(() => { + var tags = {}; + _wrap.selectAll("input").each(function(subfield) { + var key = field.key + ":" + subfield.id; + var value = this.value; + if (!onInput) + value = context.cleanTagValue(value); + if (Array.isArray(_tags[key]) && !value) + return; + if (subfield.isAutoStreetPlace) { + if (subfield.id === "street") { + tags[`${field.key}:place`] = void 0; + } else if (subfield.id === "place") { + tags[`${field.key}:street`] = void 0; + } + } + tags[key] = value || void 0; + }); + dispatch10.call("change", this, tags, onInput); + }, 0); }; } function updatePlaceholder(inputSelection) { @@ -58728,16 +61302,35 @@ ${content} if (_tags && Array.isArray(_tags[field.key + ":" + subfield.id])) { return _t("inspector.multiple_values"); } - if (_countryCode) { - var localkey = subfield.id + "!" + _countryCode; - var tkey = addrField.hasTextForStringId("placeholders." + localkey) ? localkey : subfield.id; - return addrField.t("placeholders." + tkey); + if (subfield.isAutoStreetPlace) { + return `${getLocalPlaceholder("street")} / ${getLocalPlaceholder("place")}`; } + return getLocalPlaceholder(subfield.id); }); } + function getLocalPlaceholder(key) { + if (_countryCode) { + var localkey = key + "!" + _countryCode; + var tkey = addrField.hasTextForStringId("placeholders." + localkey) ? localkey : key; + return addrField.t("placeholders." + tkey); + } + } function updateTags(tags) { - utilGetSetValue(_wrap.selectAll("input"), function(subfield) { - var val = tags[field.key + ":" + subfield.id]; + utilGetSetValue(_wrap.selectAll("input"), (subfield) => { + var val; + if (subfield.isAutoStreetPlace) { + const streetKey = `${field.key}:street`; + const placeKey = `${field.key}:place`; + if (tags[streetKey] !== void 0 || tags[placeKey] === void 0) { + val = tags[streetKey]; + subfield.id = "street"; + } else { + val = tags[placeKey]; + subfield.id = "place"; + } + } else { + val = tags[`${field.key}:${subfield.id}`]; + } return typeof val === "string" ? val : ""; }).attr("title", function(subfield) { var val = tags[field.key + ":" + subfield.id]; @@ -58767,13 +61360,21 @@ ${content} return utilRebind(address, dispatch10, "on"); } - // modules/ui/fields/cycleway.js - function uiFieldCycleway(field, context) { + // modules/ui/fields/directional_combo.js + function uiFieldDirectionalCombo(field, context) { var dispatch10 = dispatch_default("change"); var items = select_default2(null); var wrap2 = select_default2(null); var _tags; - function cycleway(selection2) { + var _combos = {}; + if (field.type === "cycleway") { + field = { + ...field, + key: field.keys[0], + keys: field.keys.slice(1) + }; + } + function directionalCombo(selection2) { function stripcolon(s) { return s.replace(":", ""); } @@ -58781,99 +61382,60 @@ ${content} wrap2 = wrap2.enter().append("div").attr("class", "form-field-input-wrap form-field-input-" + field.type).merge(wrap2); var div = wrap2.selectAll("ul").data([0]); div = div.enter().append("ul").attr("class", "rows").merge(div); - var keys = ["cycleway:left", "cycleway:right"]; - items = div.selectAll("li").data(keys); + items = div.selectAll("li").data(field.keys); var enter = items.enter().append("li").attr("class", function(d) { - return "labeled-input preset-cycleway-" + stripcolon(d); + return "labeled-input preset-directionalcombo-" + stripcolon(d); }); - enter.append("span").attr("class", "label preset-label-cycleway").attr("for", function(d) { - return "preset-input-cycleway-" + stripcolon(d); + enter.append("span").attr("class", "label preset-label-directionalcombo").attr("for", function(d) { + return "preset-input-directionalcombo-" + stripcolon(d); }).html(function(d) { return field.t.html("types." + d); }); - enter.append("div").attr("class", "preset-input-cycleway-wrap").append("input").attr("type", "text").attr("class", function(d) { - return "preset-input-cycleway preset-input-" + stripcolon(d); - }).call(utilNoAuto).each(function(d) { - select_default2(this).call( - uiCombobox(context, "cycleway-" + stripcolon(d)).data(cycleway.options(d)) - ); - }); - items = items.merge(enter); - wrap2.selectAll(".preset-input-cycleway").on("change", change).on("blur", change); - } - function change(d3_event, key) { - var newValue = context.cleanTagValue(utilGetSetValue(select_default2(this))); - if (!newValue && (Array.isArray(_tags.cycleway) || Array.isArray(_tags[key]))) - return; - if (newValue === "none" || newValue === "") { - newValue = void 0; - } - var otherKey = key === "cycleway:left" ? "cycleway:right" : "cycleway:left"; - var otherValue = typeof _tags.cycleway === "string" ? _tags.cycleway : _tags[otherKey]; - if (otherValue && Array.isArray(otherValue)) { - otherValue = otherValue[0]; - } - if (otherValue === "none" || otherValue === "") { - otherValue = void 0; - } - var tag = {}; - if (newValue === otherValue) { - tag = { - cycleway: newValue, - "cycleway:left": void 0, - "cycleway:right": void 0 - }; - } else { - tag = { - cycleway: void 0 - }; - tag[key] = newValue; - tag[otherKey] = otherValue; - } - dispatch10.call("change", this, tag); - } - cycleway.options = function() { - return field.options.map(function(option) { - return { - title: field.t("options." + option + ".description"), - value: option + enter.append("div").attr("class", "preset-input-directionalcombo-wrap form-field-input-wrap").each(function(key) { + const subField = { + ...field, + type: "combo", + key }; + const combo = uiFieldCombo(subField, context); + combo.on("change", (t) => change(key, t[key])); + _combos[key] = combo; + select_default2(this).call(combo); }); - }; - cycleway.tags = function(tags) { - _tags = tags; - var commonValue = typeof tags.cycleway === "string" && tags.cycleway; - utilGetSetValue(items.selectAll(".preset-input-cycleway"), function(d) { - if (commonValue) - return commonValue; - return !tags.cycleway && typeof tags[d] === "string" ? tags[d] : ""; - }).attr("title", function(d) { - if (Array.isArray(tags.cycleway) || Array.isArray(tags[d])) { - var vals = []; - if (Array.isArray(tags.cycleway)) { - vals = vals.concat(tags.cycleway); - } - if (Array.isArray(tags[d])) { - vals = vals.concat(tags[d]); - } - return vals.filter(Boolean).join("\n"); - } - return null; - }).attr("placeholder", function(d) { - if (Array.isArray(tags.cycleway) || Array.isArray(tags[d])) { - return _t("inspector.multiple_values"); + items = items.merge(enter); + wrap2.selectAll(".preset-input-directionalcombo").on("change", change).on("blur", change); + } + function change(key, newValue) { + const commonKey = field.key; + const otherKey = key === field.keys[0] ? field.keys[1] : field.keys[0]; + dispatch10.call("change", this, (tags) => { + const otherValue = tags[otherKey] || tags[commonKey]; + if (newValue === otherValue) { + tags[commonKey] = newValue; + delete tags[key]; + delete tags[otherKey]; + } else { + tags[key] = newValue; + delete tags[commonKey]; + tags[otherKey] = otherValue; } - return field.placeholder(); - }).classed("mixed", function(d) { - return Array.isArray(tags.cycleway) || Array.isArray(tags[d]); + return tags; }); + } + directionalCombo.tags = function(tags) { + _tags = tags; + const commonKey = field.key; + for (let key in _combos) { + const uniqueValues = [...new Set([].concat(_tags[commonKey]).concat(_tags[key]).filter(Boolean))]; + _combos[key].tags({ [key]: uniqueValues.length > 1 ? uniqueValues : uniqueValues[0] }); + } }; - cycleway.focus = function() { + directionalCombo.focus = function() { var node = wrap2.selectAll("input").node(); if (node) node.focus(); }; - return utilRebind(cycleway, dispatch10, "on"); + return utilRebind(directionalCombo, dispatch10, "on"); } // modules/ui/fields/lanes.js @@ -58940,6 +61502,7 @@ ${content} var wikipedia = services.wikipedia; var input = select_default2(null); var localizedInputs = select_default2(null); + var _lengthIndicator = uiLengthIndicator(context.maxCharsForTagValue()); var _countryCode; var _tags; _mainFileFetcher.get("languages").then(loadLanguagesArray).catch(function() { @@ -58960,7 +61523,9 @@ ${content} return; var replacements = { sr: "sr-Cyrl", + // in OSM, `sr` implies Cyrillic "sr-Cyrl": false + // `sr-Cyrl` isn't used in OSM }; for (var code in dataLanguages) { if (replacements[code] === false) @@ -58988,7 +61553,7 @@ ${content} var preset = _mainPresetIndex.match(entity, context.graph()); if (preset) { var isSuggestion = preset.suggestion; - var fields = preset.fields(); + var fields = preset.fields(entity.extent(context.graph()).center()); var showsBrandField = fields.some(function(d) { return d.id === "brand"; }); @@ -59036,6 +61601,7 @@ ${content} input = wrap2.selectAll(".localized-main").data([0]); input = input.enter().append("input").attr("type", "text").attr("id", field.domId).attr("class", "localized-main").call(utilNoAuto).merge(input); input.classed("disabled", !!isLocked).attr("readonly", isLocked || null).on("input", change(true)).on("blur", change()).on("change", change()); + wrap2.call(_lengthIndicator); var translateButton = wrap2.selectAll(".localized-add").data([0]); translateButton = translateButton.enter().append("button").attr("class", "localized-add form-field-button").attr("aria-label", _t("icons.plus")).call(svgIcon("#iD-icon-plus")).merge(translateButton); translateButton.classed("disabled", !!isLocked).call(isLocked ? _buttonTip.destroy : _buttonTip).on("click", addNew); @@ -59211,6 +61777,9 @@ ${content} utilGetSetValue(input, typeof tags[field.key] === "string" ? tags[field.key] : "").attr("title", isMixed ? tags[field.key].filter(Boolean).join("\n") : void 0).attr("placeholder", isMixed ? _t("inspector.multiple_values") : field.placeholder()).classed("mixed", isMixed); calcMultilingual(tags); _selection.call(localized); + if (!isMixed) { + _lengthIndicator.update(tags[field.key]); + } }; localized.focus = function() { input.node().focus(); @@ -59244,6 +61813,8 @@ ${content} var _entityIDs = []; var _tags; var _isImperial; + var formatFloat = _mainLocalizer.floatFormatter(_mainLocalizer.languageCode()); + var parseLocaleFloat = _mainLocalizer.floatParser(_mainLocalizer.languageCode()); var primaryUnits = [ { value: "m", @@ -59294,16 +61865,24 @@ ${content} return; if (!primaryValue && !secondaryValue) { tag[field.key] = void 0; - } else if (isNaN(primaryValue) || isNaN(secondaryValue) || !_isImperial) { - tag[field.key] = context.cleanTagValue(primaryValue); } else { - if (primaryValue !== "") { - primaryValue = context.cleanTagValue(primaryValue + "'"); - } - if (secondaryValue !== "") { - secondaryValue = context.cleanTagValue(secondaryValue + '"'); + var rawPrimaryValue = likelyRawNumberFormat.test(primaryValue) ? parseFloat(primaryValue) : parseLocaleFloat(primaryValue); + if (isNaN(rawPrimaryValue)) + rawPrimaryValue = primaryValue; + var rawSecondaryValue = likelyRawNumberFormat.test(secondaryValue) ? parseFloat(secondaryValue) : parseLocaleFloat(secondaryValue); + if (isNaN(rawSecondaryValue)) + rawSecondaryValue = secondaryValue; + if (isNaN(rawPrimaryValue) || isNaN(rawSecondaryValue) || !_isImperial) { + tag[field.key] = context.cleanTagValue(rawPrimaryValue); + } else { + if (rawPrimaryValue !== "") { + rawPrimaryValue = rawPrimaryValue + "'"; + } + if (rawSecondaryValue !== "") { + rawSecondaryValue = rawSecondaryValue + '"'; + } + tag[field.key] = context.cleanTagValue(rawPrimaryValue + rawSecondaryValue); } - tag[field.key] = primaryValue + secondaryValue; } dispatch10.call("change", this, tag); } @@ -59316,20 +61895,28 @@ ${content} if (primaryValue && (primaryValue.indexOf("'") >= 0 || primaryValue.indexOf('"') >= 0)) { secondaryValue = primaryValue.match(/(-?[\d.]+)"/); if (secondaryValue !== null) { - secondaryValue = secondaryValue[1]; + secondaryValue = formatFloat(parseFloat(secondaryValue[1])); } primaryValue = primaryValue.match(/(-?[\d.]+)'/); if (primaryValue !== null) { - primaryValue = primaryValue[1]; + primaryValue = formatFloat(parseFloat(primaryValue[1])); } _isImperial = true; } else if (primaryValue) { + var rawValue = primaryValue; + primaryValue = parseFloat(rawValue); + if (isNaN(primaryValue)) { + primaryValue = rawValue; + } else { + primaryValue = formatFloat(primaryValue); + } _isImperial = false; } } setUnitSuggestions(); + var inchesPlaceholder = formatFloat(0); utilGetSetValue(primaryInput, typeof primaryValue === "string" ? primaryValue : "").attr("title", isMixed ? primaryValue.filter(Boolean).join("\n") : null).attr("placeholder", isMixed ? _t("inspector.multiple_values") : _t("inspector.unknown")).classed("mixed", isMixed); - utilGetSetValue(secondaryInput, typeof secondaryValue === "string" ? secondaryValue : "").attr("placeholder", isMixed ? _t("inspector.multiple_values") : _isImperial ? "0" : null).classed("mixed", isMixed).classed("disabled", !_isImperial).attr("readonly", _isImperial ? null : "readonly"); + utilGetSetValue(secondaryInput, typeof secondaryValue === "string" ? secondaryValue : "").attr("placeholder", isMixed ? _t("inspector.multiple_values") : _isImperial ? inchesPlaceholder : null).classed("mixed", isMixed).classed("disabled", !_isImperial).attr("readonly", _isImperial ? null : "readonly"); secondaryUnitInput.attr("value", _isImperial ? _t("inspector.roadheight.inch") : null); }; roadheight.focus = function() { @@ -59352,6 +61939,8 @@ ${content} var _entityIDs = []; var _tags; var _isImperial; + var formatFloat = _mainLocalizer.floatFormatter(_mainLocalizer.languageCode()); + var parseLocaleFloat = _mainLocalizer.floatParser(_mainLocalizer.languageCode()); var speedCombo = uiCombobox(context, "roadspeed"); var unitCombo = uiCombobox(context, "roadspeed-unit").data(["km/h", "mph"].map(comboValues)); var metricValues = [20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120]; @@ -59385,8 +61974,8 @@ ${content} } function comboValues(d) { return { - value: d.toString(), - title: d.toString() + value: formatFloat(d), + title: formatFloat(d) }; } function change() { @@ -59396,24 +61985,35 @@ ${content} return; if (!value) { tag[field.key] = void 0; - } else if (isNaN(value) || !_isImperial) { - tag[field.key] = context.cleanTagValue(value); } else { - tag[field.key] = context.cleanTagValue(value + " mph"); + var rawValue = likelyRawNumberFormat.test(value) ? parseFloat(value) : parseLocaleFloat(value); + if (isNaN(rawValue)) + rawValue = value; + if (isNaN(rawValue) || !_isImperial) { + tag[field.key] = context.cleanTagValue(rawValue); + } else { + tag[field.key] = context.cleanTagValue(rawValue + " mph"); + } } dispatch10.call("change", this, tag); } roadspeed.tags = function(tags) { _tags = tags; - var value = tags[field.key]; + var rawValue = tags[field.key]; + var value = rawValue; var isMixed = Array.isArray(value); if (!isMixed) { - if (value && value.indexOf("mph") >= 0) { - value = parseInt(value, 10).toString(); + if (rawValue && rawValue.indexOf("mph") >= 0) { _isImperial = true; - } else if (value) { + } else if (rawValue) { _isImperial = false; } + value = parseInt(value, 10); + if (isNaN(value)) { + value = rawValue; + } else { + value = formatFloat(value); + } } setUnitSuggestions(); utilGetSetValue(input, typeof value === "string" ? value : "").attr("title", isMixed ? value.filter(Boolean).join("\n") : null).attr("placeholder", isMixed ? _t("inspector.multiple_values") : field.placeholder()).classed("mixed", isMixed); @@ -59455,18 +62055,19 @@ ${content} placeholder = wrap2.selectAll(".placeholder"); labels = wrap2.selectAll("label").data(radioData); enter = labels.enter().append("label"); + var stringsField = field.resolveReference("stringsCrossReference"); enter.append("input").attr("type", "radio").attr("name", field.id).attr("value", function(d) { - return field.t("options." + d, { "default": d }); + return stringsField.t("options." + d, { "default": d }); }).attr("checked", false); - enter.append("span").html(function(d) { - return field.t.html("options." + d, { "default": d }); + enter.append("span").each(function(d) { + stringsField.t.append("options." + d, { "default": d })(select_default2(this)); }); labels = labels.merge(enter); radios = labels.selectAll("input").on("change", changeRadio); } function structureExtras(selection2, tags) { var selected = selectedKey() || tags.layer !== void 0; - var type3 = _mainPresetIndex.field(selected); + var type2 = _mainPresetIndex.field(selected); var layer = _mainPresetIndex.field("layer"); var showLayer = selected === "bridge" || selected === "tunnel" || tags.layer !== void 0; var extrasWrap = selection2.selectAll(".structure-extras-wrap").data(selected ? [0] : []); @@ -59474,9 +62075,9 @@ ${content} extrasWrap = extrasWrap.enter().append("div").attr("class", "structure-extras-wrap").merge(extrasWrap); var list = extrasWrap.selectAll("ul").data([0]); list = list.enter().append("ul").attr("class", "rows").merge(list); - if (type3) { + if (type2) { if (!typeField || typeField.id !== selected) { - typeField = uiField(context, type3, _entityIDs, { wrap: false }).on("change", changeType); + typeField = uiField(context, type2, _entityIDs, { wrap: false }).on("change", changeType); } typeField.tags(tags); } else { @@ -59654,9 +62255,11 @@ ${content} _graph = context.graph(); _intersection = osmIntersection(_graph, _vertexID, _maxDistance); } - var isOK = _intersection && _intersection.vertices.length && _intersection.vertices.filter(function(vertex) { + var isOK = _intersection && _intersection.vertices.length && // has vertices + _intersection.vertices.filter(function(vertex) { return vertex.id === _vertexID; - }).length && _intersection.ways.length > 2 && _intersection.ways.filter(function(way) { + }).length && _intersection.ways.length > 2 && // has more than 2 ways + _intersection.ways.filter(function(way) { return way.__to; }).length > 1; select_default2(selection2.node().parentNode).classed("hide", !isOK); @@ -59958,6 +62561,7 @@ ${content} var opts; if (isImperial) { var distToFeet = { + // imprecise conversion for prettier display 20: 70, 25: 85, 30: 100, @@ -59983,8 +62587,8 @@ ${content} var entity = graph.entity(entityID); var name = utilDisplayName(entity) || ""; var matched = _mainPresetIndex.match(entity, graph); - var type3 = matched && matched.name() || utilDisplayType(entity.id); - return name || type3; + var type2 = matched && matched.name() || utilDisplayType(entity.id); + return name || type2; } restrictions.entityIDs = function(val) { _intersection = null; @@ -60010,29 +62614,34 @@ ${content} function uiFieldTextarea(field, context) { var dispatch10 = dispatch_default("change"); var input = select_default2(null); + var _lengthIndicator = uiLengthIndicator(context.maxCharsForTagValue()).silent(field.usage === "changeset" && field.key === "comment"); var _tags; function textarea(selection2) { var wrap2 = selection2.selectAll(".form-field-input-wrap").data([0]); - wrap2 = wrap2.enter().append("div").attr("class", "form-field-input-wrap form-field-input-" + field.type).merge(wrap2); + wrap2 = wrap2.enter().append("div").attr("class", "form-field-input-wrap form-field-input-" + field.type).style("position", "relative").merge(wrap2); input = wrap2.selectAll("textarea").data([0]); input = input.enter().append("textarea").attr("id", field.domId).call(utilNoAuto).on("input", change(true)).on("blur", change()).on("change", change()).merge(input); - } - function change(onInput) { - return function() { - var val = utilGetSetValue(input); - if (!onInput) - val = context.cleanTagValue(val); - if (!val && Array.isArray(_tags[field.key])) - return; - var t = {}; - t[field.key] = val || void 0; - dispatch10.call("change", this, t, onInput); - }; + wrap2.call(_lengthIndicator); + function change(onInput) { + return function() { + var val = utilGetSetValue(input); + if (!onInput) + val = context.cleanTagValue(val); + if (!val && Array.isArray(_tags[field.key])) + return; + var t = {}; + t[field.key] = val || void 0; + dispatch10.call("change", this, t, onInput); + }; + } } textarea.tags = function(tags) { _tags = tags; var isMixed = Array.isArray(tags[field.key]); utilGetSetValue(input, !isMixed && tags[field.key] ? tags[field.key] : "").attr("title", isMixed ? tags[field.key].filter(Boolean).join("\n") : void 0).attr("placeholder", isMixed ? _t("inspector.multiple_values") : field.placeholder() || _t("inspector.unknown")).classed("mixed", isMixed); + if (!isMixed) { + _lengthIndicator.update(tags[field.key]); + } }; textarea.focus = function() { input.node().focus(); @@ -60110,8 +62719,11 @@ ${content} } } wikidata.itemsForSearchQuery(q, function(err, data) { - if (err) + if (err) { + if (err !== "No query") + console.error(err); return; + } var result = data.map(function(item) { return { id: item.id, @@ -60457,7 +63069,10 @@ ${content} const defaultLangInfo = defaultLanguageInfo(); _wikiURL = `https://${defaultLangInfo[2]}.wikipedia.org/w/index.php?fulltext=1&search=${value}`; } else { - const shownOrDefaultLangInfo = language(true); + const shownOrDefaultLangInfo = language( + true + /* skipEnglishFallback */ + ); utilGetSetValue(_langInput, shownOrDefaultLangInfo[1]); _wikiURL = ""; } @@ -60481,9 +63096,12 @@ ${content} access: uiFieldAccess, address: uiFieldAddress, check: uiFieldCheck, + colour: uiFieldText, combo: uiFieldCombo, - cycleway: uiFieldCycleway, + cycleway: uiFieldDirectionalCombo, + date: uiFieldText, defaultCheck: uiFieldCheck, + directionalCombo: uiFieldDirectionalCombo, email: uiFieldText, identifier: uiFieldText, lanes: uiFieldLanes, @@ -60532,7 +63150,6 @@ ${content} } var _locked = false; var _lockedTip = uiTooltip().title(() => _t.append("inspector.lock.suggestion", { label: field.title })).placement("bottom"); - field.keys = field.keys || [field.key]; if (_show && !field.impl) { createField(); } @@ -60547,19 +63164,26 @@ ${content} } } } + function allKeys() { + let keys2 = field.keys || [field.key]; + if (field.type === "directionalCombo" && field.key) { + keys2 = keys2.concat(field.key); + } + return keys2; + } function isModified() { if (!entityIDs || !entityIDs.length) return false; return entityIDs.some(function(entityID) { var original = context.graph().base().entities[entityID]; var latest = context.graph().entity(entityID); - return field.keys.some(function(key) { + return allKeys().some(function(key) { return original ? latest.tags[key] !== original.tags[key] : latest.tags[key]; }); }); } function tagsContainFieldKey() { - return field.keys.some(function(key) { + return allKeys().some(function(key) { if (field.type === "multiCombo") { for (var tagKey in _tags) { if (tagKey.indexOf(key) === 0) { @@ -60576,7 +63200,7 @@ ${content} d3_event.preventDefault(); if (!entityIDs || _locked) return; - dispatch10.call("revert", d, d.keys); + dispatch10.call("revert", d, allKeys()); } function remove2(d3_event, d) { d3_event.stopPropagation(); @@ -60584,7 +63208,7 @@ ${content} if (_locked) return; var t = {}; - d.keys.forEach(function(key) { + allKeys().forEach(function(key) { t[key] = void 0; }); dispatch10.call("change", d, t); @@ -60694,12 +63318,13 @@ ${content} })) return false; if (entityIDs && _entityExtent && field.locationSetID) { - var validLocations = _mainLocations.locationsAt(_entityExtent.center()); - if (!validLocations[field.locationSetID]) + var validHere = _sharedLocationManager.locationSetsAt(_entityExtent.center()); + if (!validHere[field.locationSetID]) return false; } var prerequisiteTag = field.prerequisiteTag; - if (entityIDs && !tagsContainFieldKey() && prerequisiteTag) { + if (entityIDs && !tagsContainFieldKey() && // ignore tagging prerequisites if a value is already present + prerequisiteTag) { if (!entityIDs.every(function(entityID) { var entity = context.graph().entity(entityID); if (prerequisiteTag.key) { @@ -60876,12 +63501,34 @@ ${content} }); } } - var hasGoogle = _tags.comment.match(/google/i); - var commentWarning = selection2.select(".form-field-comment").selectAll(".comment-warning").data(hasGoogle ? [0] : []); + const warnings = []; + if (_tags.comment.match(/google/i)) { + warnings.push({ + id: 'contains "google"', + msg: _t.append("commit.google_warning"), + link: _t("commit.google_warning_link") + }); + } + const maxChars = context.maxCharsForTagValue(); + const strLen = utilUnicodeCharsCount(utilCleanOsmString(_tags.comment, Number.POSITIVE_INFINITY)); + if (strLen > maxChars || false) { + warnings.push({ + id: "message too long", + msg: _t.append("commit.changeset_comment_length_warning", { maxChars }) + }); + } + var commentWarning = selection2.select(".form-field-comment").selectAll(".comment-warning").data(warnings, (d) => d.id); commentWarning.exit().transition().duration(200).style("opacity", 0).remove(); - var commentEnter = commentWarning.enter().insert("div", ".tag-reference-body").attr("class", "field-warning comment-warning").style("opacity", 0); - commentEnter.append("a").attr("target", "_blank").call(svgIcon("#iD-icon-alert", "inline")).attr("href", _t("commit.google_warning_link")).append("span").call(_t.append("commit.google_warning")); + var commentEnter = commentWarning.enter().insert("div", ".comment-warning").attr("class", "comment-warning field-warning").style("opacity", 0); + commentEnter.call(svgIcon("#iD-icon-alert", "inline")).append("span"); commentEnter.transition().duration(200).style("opacity", 1); + commentWarning.merge(commentEnter).selectAll("div > span").text("").each(function(d) { + let selection3 = select_default2(this); + if (d.link) { + selection3 = selection3.append("a").attr("target", "_blank").attr("href", d.link); + } + selection3.call(d.msg); + }); } changesetEditor.tags = function(_) { if (!arguments.length) @@ -60935,7 +63582,10 @@ ${content} } function createObjTree(oParentNode, nVerb, bFreeze, bNesteAttr) { var nLevelStart = aCache.length, bChildren = oParentNode.hasChildNodes(), bAttributes = oParentNode.hasAttributes(), bHighVerb = Boolean(nVerb & 2); - var sProp, vContent, nLength = 0, sCollectedTxt = "", vResult = bHighVerb ? {} : true; + var sProp, vContent, nLength = 0, sCollectedTxt = "", vResult = bHighVerb ? {} : ( + /* put here the default value for empty nodes: */ + true + ); if (bChildren) { for (var oNode, nItem = 0; nItem < oParentNode.childNodes.length; nItem++) { oNode = oParentNode.childNodes.item(nItem); @@ -61030,7 +63680,10 @@ ${content} } } this.build = function(oXMLParent, nVerbosity, bFreeze, bNesteAttributes) { - var _nVerb = arguments.length > 1 && typeof nVerbosity === "number" ? nVerbosity & 3 : 1; + var _nVerb = arguments.length > 1 && typeof nVerbosity === "number" ? nVerbosity & 3 : ( + /* put here the default verbosity level: */ + 1 + ); return createObjTree(oXMLParent, _nVerb, bFreeze || false, arguments.length > 3 ? bNesteAttributes : _nVerb === 3); }; this.unbuild = function(oObjTree) { @@ -61624,7 +64277,7 @@ ${content} var sign2 = d === "previous" ? -1 : 1; container.selectAll(".conflict").remove(); container.call(showConflict, index + sign2); - }).call(function(d) { + }).each(function(d) { _t.append("save.conflict." + d)(select_default2(this)); }); } @@ -61813,9 +64466,9 @@ ${content} var buttons = fixesEnter.append("button").on("click", function(d3_event, d) { if (select_default2(this).attr("disabled") || !d.onClick) return; - if (d.issue.dateLastRanFix && new Date() - d.issue.dateLastRanFix < 1e3) + if (d.issue.dateLastRanFix && /* @__PURE__ */ new Date() - d.issue.dateLastRanFix < 1e3) return; - d.issue.dateLastRanFix = new Date(); + d.issue.dateLastRanFix = /* @__PURE__ */ new Date(); utilHighlightEntities(d.issue.entityIds.concat(d.entityIds), false, context); new Promise(function(resolve, reject) { d.onClick(context, resolve, reject); @@ -61928,12 +64581,12 @@ ${content} fillEnter.append("path").attr("d", `M${c1} ${c1} L${c1} ${c2} L${c2} ${c2} L${c2} ${c1} Z`).attr("class", `area ${klass}`); }); const rVertex = 2.5; - [[c1, c1], [c1, c2], [c2, c2], [c2, c1]].forEach((point) => { - fillEnter.append("circle").attr("class", "vertex").attr("cx", point[0]).attr("cy", point[1]).attr("r", rVertex); + [[c1, c1], [c1, c2], [c2, c2], [c2, c1]].forEach((point2) => { + fillEnter.append("circle").attr("class", "vertex").attr("cx", point2[0]).attr("cy", point2[1]).attr("r", rVertex); }); const rMidpoint = 1.25; - [[c1, w / 2], [c2, w / 2], [h / 2, c1], [h / 2, c2]].forEach((point) => { - fillEnter.append("circle").attr("class", "midpoint").attr("cx", point[0]).attr("cy", point[1]).attr("r", rMidpoint); + [[c1, w / 2], [c2, w / 2], [h / 2, c1], [h / 2, c2]].forEach((point2) => { + fillEnter.append("circle").attr("class", "midpoint").attr("cx", point2[0]).attr("cy", point2[1]).attr("r", rMidpoint); }); fill = fillEnter.merge(fill); fill.selectAll("path.stroke").attr("class", `area stroke ${tagClasses}`); @@ -61955,8 +64608,8 @@ ${content} ["casing", "stroke"].forEach((klass) => { lineEnter.append("path").attr("d", `M${x12} ${y} L${x2} ${y}`).attr("class", `line ${klass}`); }); - [[x12 - 1, y], [x2 + 1, y]].forEach((point) => { - lineEnter.append("circle").attr("class", "vertex").attr("cx", point[0]).attr("cy", point[1]).attr("r", r); + [[x12 - 1, y], [x2 + 1, y]].forEach((point2) => { + lineEnter.append("circle").attr("class", "vertex").attr("cx", point2[0]).attr("cy", point2[1]).attr("r", r); }); line = lineEnter.merge(line); line.selectAll("path.stroke").attr("class", `line stroke ${tagClasses}`); @@ -61983,8 +64636,8 @@ ${content} routeEnter.append("path").attr("d", `M${x2} ${y2} L${x3} ${y12}`).attr("class", `segment1 line ${klass}`); routeEnter.append("path").attr("d", `M${x3} ${y12} L${x4} ${y2}`).attr("class", `segment2 line ${klass}`); }); - [[x12, y12], [x2, y2], [x3, y12], [x4, y2]].forEach((point) => { - routeEnter.append("circle").attr("class", "vertex").attr("cx", point[0]).attr("cy", point[1]).attr("r", r); + [[x12, y12], [x2, y2], [x3, y12], [x4, y2]].forEach((point2) => { + routeEnter.append("circle").attr("class", "vertex").attr("cx", point2[0]).attr("cy", point2[1]).attr("r", r); }); route = routeEnter.merge(route); if (drawRoute) { @@ -62002,7 +64655,8 @@ ${content} const isMaki = picon && /^maki-/.test(picon); const isTemaki = picon && /^temaki-/.test(picon); const isFa = picon && /^fa[srb]-/.test(picon); - const isiDIcon = picon && !(isMaki || isTemaki || isFa); + const isR\u00F6ntgen = picon && /^roentgen-/.test(picon); + const isiDIcon = picon && !(isMaki || isTemaki || isFa || isR\u00F6ntgen); let icon2 = container.selectAll(".preset-icon").data(picon ? [0] : []); icon2.exit().remove(); icon2 = icon2.enter().append("div").attr("class", "preset-icon").call(svgIcon("")).merge(icon2); @@ -62182,13 +64836,17 @@ ${content} geoms[graph.entity(entityID).geometry(graph)] = true; return geoms; }, {})); + const loc = _entityIDs.reduce(function(extent, entityID) { + var entity = context.graph().entity(entityID); + return extent.extend(entity.extent(context.graph())); + }, geoExtent()).center(); var presetsManager = _mainPresetIndex; var allFields = []; var allMoreFields = []; var sharedTotalFields; _presets.forEach(function(preset) { - var fields = preset.fields(); - var moreFields = preset.moreFields(); + var fields = preset.fields(loc); + var moreFields = preset.moreFields(loc); allFields = utilArrayUnion(allFields, fields); allMoreFields = utilArrayUnion(allMoreFields, moreFields); if (!sharedTotalFields) { @@ -62233,8 +64891,8 @@ ${content} _fieldsArr.forEach(function(field) { field.on("change", function(t, onInput) { dispatch10.call("change", field, _entityIDs, t, onInput); - }).on("revert", function(keys) { - dispatch10.call("revert", field, keys); + }).on("revert", function(keys2) { + dispatch10.call("revert", field, keys2); }); }); } @@ -62244,11 +64902,6 @@ ${content} selection2.call( formFields.fieldsArr(_fieldsArr).state(_state).klass("grouped-items-area") ); - selection2.selectAll(".wrap-form-field input").on("keydown", function(d3_event) { - if (d3_event.keyCode === 13 && context.container().select(".combobox").empty()) { - context.enter(modeBrowse(context)); - } - }); } section.presets = function(val) { if (!arguments.length) @@ -62424,7 +65077,8 @@ ${content} targetIndex = null; }).on("drag", function(d3_event) { var x = d3_event.x - dragOrigin.x, y = d3_event.y - dragOrigin.y; - if (!select_default2(this).classed("dragging") && Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)) <= 5) + if (!select_default2(this).classed("dragging") && // don't display drag until dragging beyond a distance threshold + Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)) <= 5) return; var index = items.nodes().indexOf(this); select_default2(this).classed("dragging", true); @@ -62958,7 +65612,7 @@ ${content} var header = selection2.selectAll(".header").data([0]); var headerEnter = header.enter().append("div").attr("class", "header fillL"); var direction = _mainLocalizer.textDirection() === "rtl" ? "forward" : "backward"; - headerEnter.append("button").attr("class", "preset-reset preset-choose").attr("title", _t(`icons.${direction}`)).call(svgIcon(`#iD-icon-${direction}`)); + headerEnter.append("button").attr("class", "preset-reset preset-choose").attr("title", _t("inspector.back_tooltip")).call(svgIcon(`#iD-icon-${direction}`)); headerEnter.append("button").attr("class", "close").attr("title", _t("icons.close")).on("click", function() { context.enter(modeBrowse(context)); }).call(svgIcon(_modified ? "#iD-icon-apply" : "#iD-icon-close")); @@ -63027,14 +65681,18 @@ ${content} var entityID = entityIDs[i2]; var entity = context.entity(entityID); var tags = Object.assign({}, entity.tags); - for (var k in changed) { - if (!k) - continue; - var v = changed[k]; - if (typeof v === "object") { - tags[k] = tags[v.oldKey]; - } else if (v !== void 0 || tags.hasOwnProperty(k)) { - tags[k] = v; + if (typeof changed === "function") { + tags = changed(tags); + } else { + for (var k in changed) { + if (!k) + continue; + var v = changed[k]; + if (typeof v === "object") { + tags[k] = tags[v.oldKey]; + } else if (v !== void 0 || tags.hasOwnProperty(k)) { + tags[k] = v; + } } } if (!onInput) { @@ -63063,14 +65721,14 @@ ${content} context.validator().validate(); } } - function revertTags(keys) { + function revertTags(keys2) { var actions = []; for (var i2 in _entityIDs) { var entityID = _entityIDs[i2]; var original = context.graph().base().entities[entityID]; var changed = {}; - for (var j2 in keys) { - var key = keys[j2]; + for (var j2 in keys2) { + var key = keys2[j2]; changed[key] = original ? original.tags[key] : void 0; } var entity = context.entity(entityID); @@ -63198,7 +65856,8 @@ ${content} } function keypress(d3_event) { var q = search.property("value"), items = list.selectAll(".feature-list-item"); - if (d3_event.keyCode === 13 && q.length && items.size()) { + if (d3_event.keyCode === 13 && // ↩ Return + q.length && items.size()) { click(d3_event, items.datum()); } } @@ -63215,7 +65874,7 @@ ${content} drawList(); } } - function features2() { + function features() { var result = []; var graph = context.graph(); var visibleCenter = context.map().extent().center(); @@ -63224,7 +65883,7 @@ ${content} return result; var locationMatch = sexagesimal.pair(q.toUpperCase()) || q.match(/^(-?\d+\.?\d*)\s+(-?\d+\.?\d*)$/); if (locationMatch) { - var loc = [parseFloat(locationMatch[0]), parseFloat(locationMatch[1])]; + var loc = [Number(locationMatch[0]), Number(locationMatch[1])]; result.push({ id: -1, geometry: "point", @@ -63233,7 +65892,7 @@ ${content} location: loc }); } - var idMatch = !locationMatch && q.match(/(?:^|\W)(node|way|relation|[nwr])\W?0*([1-9]\d*)(?:\W|$)/i); + var idMatch = !locationMatch && q.match(/(?:^|\W)(node|way|relation|[nwr])\W{0,2}0*([1-9]\d*)(?:\W|$)/i); if (idMatch) { var elemType = idMatch[1].charAt(0); var elemId = idMatch[2]; @@ -63254,14 +65913,14 @@ ${content} if (name.toLowerCase().indexOf(q) < 0) continue; var matched = _mainPresetIndex.match(entity, graph); - var type3 = matched && matched.name() || utilDisplayType(entity.id); + var type2 = matched && matched.name() || utilDisplayType(entity.id); var extent = entity.extent(graph); var distance = extent ? geoSphericalDistance(visibleCenter, extent.center()) : 0; localResults.push({ id: entity.id, entity, geometry: entity.geometry(graph), - type: type3, + type: type2, name, distance }); @@ -63284,15 +65943,15 @@ ${content} var tempEntity = osmEntity(attrs); var tempGraph = coreGraph([tempEntity]); var matched2 = _mainPresetIndex.match(tempEntity, tempGraph); - var type4 = matched2 && matched2.name() || utilDisplayType(id3); + var type3 = matched2 && matched2.name() || utilDisplayType(id3); result.push({ id: tempEntity.id, geometry: tempEntity.geometry(tempGraph), - type: type4, + type: type3, name: d.display_name, extent: new geoExtent( - [parseFloat(d.boundingbox[3]), parseFloat(d.boundingbox[0])], - [parseFloat(d.boundingbox[2]), parseFloat(d.boundingbox[1])] + [Number(d.boundingbox[3]), Number(d.boundingbox[0])], + [Number(d.boundingbox[2]), Number(d.boundingbox[1])] ) }); } @@ -63321,7 +65980,7 @@ ${content} } function drawList() { var value = search.property("value"); - var results = features2(); + var results = features(); list.classed("filtered", value.length); var resultsIndicator = list.selectAll(".no-results-item").data([0]).enter().append("button").property("disabled", true).attr("class", "no-results-item").call(svgIcon("#iD-icon-alert", "pre-text")); resultsIndicator.append("span").attr("class", "entity-name"); @@ -63637,7 +66296,7 @@ ${content} var messagewrap = selection2.append("div").attr("class", "header fillL"); var message = messagewrap.append("h2").call(_t.append("inspector.choose")); var direction = _mainLocalizer.textDirection() === "rtl" ? "backward" : "forward"; - messagewrap.append("button").attr("class", "preset-choose").attr("title", direction).on("click", function() { + messagewrap.append("button").attr("class", "preset-choose").attr("title", _entityIDs.length === 1 ? _t("inspector.edit") : _t("inspector.edit_features")).on("click", function() { dispatch10.call("cancel", this); }).call(svgIcon(`#iD-icon-${direction}`)); function initialKeydown(d3_event) { @@ -63655,7 +66314,8 @@ ${content} } } function keydown(d3_event) { - if (d3_event.keyCode === utilKeybinding.keyCodes["\u2193"] && search.node().selectionStart === search.property("value").length) { + if (d3_event.keyCode === utilKeybinding.keyCodes["\u2193"] && // if insertion point is at the end of the string + search.node().selectionStart === search.property("value").length) { d3_event.preventDefault(); d3_event.stopPropagation(); var buttons = list.selectAll(".preset-list-button"); @@ -63665,7 +66325,8 @@ ${content} } function keypress(d3_event) { var value = search.property("value"); - if (d3_event.keyCode === 13 && value.length) { + if (d3_event.keyCode === 13 && // ↩ Return + value.length) { list.selectAll(".preset-list-item:first-child").each(function(d) { d.choose.call(this); }); @@ -64328,8 +66989,8 @@ ${content} } } lasso.extent = function() { - return lasso.coordinates.reduce(function(extent, point) { - return extent.extend(geoExtent(point)); + return lasso.coordinates.reduce(function(extent, point2) { + return extent.extend(geoExtent(point2)); }, geoExtent()); }; lasso.p = function(_) { @@ -64535,7 +67196,8 @@ ${content} } noteSave = noteSaveEnter.merge(noteSave).call(userDetails).call(noteSaveButtons); function keydown(d3_event) { - if (!(d3_event.keyCode === 13 && d3_event.metaKey)) + if (!(d3_event.keyCode === 13 && // ↩ Return + d3_event.metaKey)) return; var osm = services.osm; if (!osm) @@ -64682,7 +67344,7 @@ ${content} // modules/ui/source_switch.js function uiSourceSwitch(context) { - var keys; + var keys2; function click(d3_event) { d3_event.preventDefault(); var osm = context.connection(); @@ -64698,15 +67360,15 @@ ${content} context.history().clearSaved(); context.flush(); select_default2(this).html(isLive ? _t.html("source_switch.live") : _t.html("source_switch.dev")).classed("live", isLive).classed("chip", isLive); - osm.switch(isLive ? keys[0] : keys[1]); + osm.switch(isLive ? keys2[0] : keys2[1]); } var sourceSwitch = function(selection2) { selection2.append("a").attr("href", "#").call(_t.append("source_switch.live")).attr("class", "live chip").on("click", click); }; sourceSwitch.keys = function(_) { if (!arguments.length) - return keys; - keys = _; + return keys2; + keys2 = _; return sourceSwitch; }; return sourceSwitch; @@ -64840,12 +67502,12 @@ ${content} } // node_modules/osm-community-index/lib/simplify.js - var import_diacritics3 = __toESM(require_diacritics(), 1); - function simplify2(str2) { + var import_diacritics2 = __toESM(require_diacritics(), 1); + function simplify(str2) { if (typeof str2 !== "string") return ""; - return import_diacritics3.default.remove( - str2.replace(/&/g, "and").replace(/İ/ig, "i").replace(/[\s\-=_!"#%'*{},.\/:;?\(\)\[\]@\\$\^*+<>«»~`’\u00a1\u00a7\u00b6\u00b7\u00bf\u037e\u0387\u055a-\u055f\u0589\u05c0\u05c3\u05c6\u05f3\u05f4\u0609\u060a\u060c\u060d\u061b\u061e\u061f\u066a-\u066d\u06d4\u0700-\u070d\u07f7-\u07f9\u0830-\u083e\u085e\u0964\u0965\u0970\u0af0\u0df4\u0e4f\u0e5a\u0e5b\u0f04-\u0f12\u0f14\u0f85\u0fd0-\u0fd4\u0fd9\u0fda\u104a-\u104f\u10fb\u1360-\u1368\u166d\u166e\u16eb-\u16ed\u1735\u1736\u17d4-\u17d6\u17d8-\u17da\u1800-\u1805\u1807-\u180a\u1944\u1945\u1a1e\u1a1f\u1aa0-\u1aa6\u1aa8-\u1aad\u1b5a-\u1b60\u1bfc-\u1bff\u1c3b-\u1c3f\u1c7e\u1c7f\u1cc0-\u1cc7\u1cd3\u200b-\u200f\u2016\u2017\u2020-\u2027\u2030-\u2038\u203b-\u203e\u2041-\u2043\u2047-\u2051\u2053\u2055-\u205e\u2cf9-\u2cfc\u2cfe\u2cff\u2d70\u2e00\u2e01\u2e06-\u2e08\u2e0b\u2e0e-\u2e16\u2e18\u2e19\u2e1b\u2e1e\u2e1f\u2e2a-\u2e2e\u2e30-\u2e39\u3001-\u3003\u303d\u30fb\ua4fe\ua4ff\ua60d-\ua60f\ua673\ua67e\ua6f2-\ua6f7\ua874-\ua877\ua8ce\ua8cf\ua8f8-\ua8fa\ua92e\ua92f\ua95f\ua9c1-\ua9cd\ua9de\ua9df\uaa5c-\uaa5f\uaade\uaadf\uaaf0\uaaf1\uabeb\ufe10-\ufe16\ufe19\ufe30\ufe45\ufe46\ufe49-\ufe4c\ufe50-\ufe52\ufe54-\ufe57\ufe5f-\ufe61\ufe68\ufe6a\ufe6b\ufeff\uff01-\uff03\uff05-\uff07\uff0a\uff0c\uff0e\uff0f\uff1a\uff1b\uff1f\uff20\uff3c\uff61\uff64\uff65]+/g, "").toLowerCase() + return import_diacritics2.default.remove( + str2.replace(/&/g, "and").replace(/(İ|i̇)/ig, "i").replace(/[\s\-=_!"#%'*{},.\/:;?\(\)\[\]@\\$\^*+<>«»~`’\u00a1\u00a7\u00b6\u00b7\u00bf\u037e\u0387\u055a-\u055f\u0589\u05c0\u05c3\u05c6\u05f3\u05f4\u0609\u060a\u060c\u060d\u061b\u061e\u061f\u066a-\u066d\u06d4\u0700-\u070d\u07f7-\u07f9\u0830-\u083e\u085e\u0964\u0965\u0970\u0af0\u0df4\u0e4f\u0e5a\u0e5b\u0f04-\u0f12\u0f14\u0f85\u0fd0-\u0fd4\u0fd9\u0fda\u104a-\u104f\u10fb\u1360-\u1368\u166d\u166e\u16eb-\u16ed\u1735\u1736\u17d4-\u17d6\u17d8-\u17da\u1800-\u1805\u1807-\u180a\u1944\u1945\u1a1e\u1a1f\u1aa0-\u1aa6\u1aa8-\u1aad\u1b5a-\u1b60\u1bfc-\u1bff\u1c3b-\u1c3f\u1c7e\u1c7f\u1cc0-\u1cc7\u1cd3\u2000-\u206f\u2cf9-\u2cfc\u2cfe\u2cff\u2d70\u2e00-\u2e7f\u3001-\u3003\u303d\u30fb\ua4fe\ua4ff\ua60d-\ua60f\ua673\ua67e\ua6f2-\ua6f7\ua874-\ua877\ua8ce\ua8cf\ua8f8-\ua8fa\ua92e\ua92f\ua95f\ua9c1-\ua9cd\ua9de\ua9df\uaa5c-\uaa5f\uaade\uaadf\uaaf0\uaaf1\uabeb\ufe10-\ufe16\ufe19\ufe30\ufe45\ufe46\ufe49-\ufe4c\ufe50-\ufe52\ufe54-\ufe57\ufe5f-\ufe61\ufe68\ufe6a\ufe6b\ufeff\uff01-\uff03\uff05-\uff07\uff0a\uff0c\uff0e\uff0f\uff1a\uff1b\uff1f\uff20\uff3c\uff61\uff64\uff65]+/g, "").toLowerCase() ); } @@ -64856,7 +67518,7 @@ ${content} const anyToken = new RegExp(/(\{\w+\})/, "gi"); if (localizerFn) { if (itemStrings.community) { - const communityID = simplify2(itemStrings.community); + const communityID = simplify(itemStrings.community); itemStrings.community = localizerFn(`_communities.${communityID}`); } ["name", "description", "extendedDescription"].forEach((prop) => { @@ -64945,11 +67607,11 @@ ${content} if (_oci) return _oci; if (vals[0] && Array.isArray(vals[0].features)) { - _mainLocations.mergeCustomGeoJSON(vals[0]); + _sharedLocationManager.mergeCustomGeoJSON(vals[0]); } let ociResources = Object.values(vals[1].resources); if (ociResources.length) { - return _mainLocations.mergeLocationSets(ociResources).then(() => { + return _sharedLocationManager.mergeLocationSets(ociResources).then(() => { _oci = { resources: ociResources, defaults: vals[2].defaults @@ -64959,6 +67621,7 @@ ${content} } else { _oci = { resources: [], + // no resources? defaults: vals[2].defaults }; return _oci; @@ -64999,10 +67662,10 @@ ${content} })); ensureOSMCommunityIndex().then((oci) => { const loc = context.map().center(); - const validLocations = _mainLocations.locationsAt(loc); + const validHere = _sharedLocationManager.locationSetsAt(loc); let communities = []; oci.resources.forEach((resource) => { - let area = validLocations[resource.locationSetID]; + let area = validHere[resource.locationSetID]; if (!area) return; const localizer = (stringID) => _t.html(`community.${stringID}`); @@ -65043,7 +67706,7 @@ ${content} return event; }).filter((event) => { const t = event.date.getTime(); - const now3 = new Date().setHours(0, 0, 0, 0); + const now3 = (/* @__PURE__ */ new Date()).setHours(0, 0, 0, 0); return !isNaN(t) && t >= now3; }).sort((a, b) => { return a.date < b.date ? -1 : a.date > b.date ? 1 : 0; @@ -65475,9 +68138,7 @@ ${content} query: value2 }, function(err, data) { if (!err) { - var filtered = data.filter(function(d) { - return _tags[d.value] === void 0; - }); + const filtered = data.filter((d) => _tags[d.value] === void 0).filter((d) => d.value.toLowerCase().includes(value2.toLowerCase())); callback(sort(value2, filtered)); } }); @@ -65489,10 +68150,12 @@ ${content} geometry, query: value2 }, function(err, data) { - if (!err) - callback(sort(value2, data)); + if (!err) { + const filtered = data.filter((d) => d.value.toLowerCase().includes(value2.toLowerCase())); + callback(sort(value2, filtered)); + } }); - })); + }).caseSensitive(allowUpperCaseTagValues.test(utilGetSetValue(key)))); function sort(value2, data) { var sameletter = []; var other = []; @@ -65672,11 +68335,11 @@ ${content} // modules/ui/osmose_details.js function uiOsmoseDetails(context) { let _qaItem; - function issueString(d, type3) { + function issueString(d, type2) { if (!d) return ""; const s = services.osmose.getStrings(d.itemType); - return type3 in s ? s[type3] : ""; + return type2 in s ? s[type2] : ""; } function osmoseDetails(selection2) { const details = selection2.selectAll(".error-details").data( @@ -66183,9 +68846,12 @@ ${content} function modeAddArea(context, mode) { mode.id = "add-area"; var behavior = behaviorAddWay(context).on("start", start2).on("startFromWay", startFromWay).on("startFromNode", startFromNode); - var defaultTags = { area: "yes" }; - if (mode.preset) - defaultTags = mode.preset.setTags(defaultTags, "area"); + function defaultTags(loc) { + var defaultTags2 = { area: "yes" }; + if (mode.preset) + defaultTags2 = mode.preset.setTags(defaultTags2, "area", false, loc); + return defaultTags2; + } function actionClose(wayId) { return function(graph) { return graph.replace(graph.entity(wayId).close()); @@ -66194,7 +68860,7 @@ ${content} function start2(loc) { var startGraph = context.graph(); var node = osmNode({ loc }); - var way = osmWay({ tags: defaultTags }); + var way = osmWay({ tags: defaultTags(loc) }); context.perform( actionAddEntity(node), actionAddEntity(way), @@ -66206,7 +68872,7 @@ ${content} function startFromWay(loc, edge) { var startGraph = context.graph(); var node = osmNode({ loc }); - var way = osmWay({ tags: defaultTags }); + var way = osmWay({ tags: defaultTags(loc) }); context.perform( actionAddEntity(node), actionAddEntity(way), @@ -66218,7 +68884,7 @@ ${content} } function startFromNode(node) { var startGraph = context.graph(); - var way = osmWay({ tags: defaultTags }); + var way = osmWay({ tags: defaultTags(node.loc) }); context.perform( actionAddEntity(way), actionAddVertex(way.id, node.id), @@ -66239,13 +68905,16 @@ ${content} function modeAddLine(context, mode) { mode.id = "add-line"; var behavior = behaviorAddWay(context).on("start", start2).on("startFromWay", startFromWay).on("startFromNode", startFromNode); - var defaultTags = {}; - if (mode.preset) - defaultTags = mode.preset.setTags(defaultTags, "line"); + function defaultTags(loc) { + var defaultTags2 = {}; + if (mode.preset) + defaultTags2 = mode.preset.setTags(defaultTags2, "line", false, loc); + return defaultTags2; + } function start2(loc) { var startGraph = context.graph(); var node = osmNode({ loc }); - var way = osmWay({ tags: defaultTags }); + var way = osmWay({ tags: defaultTags(loc) }); context.perform( actionAddEntity(node), actionAddEntity(way), @@ -66256,7 +68925,7 @@ ${content} function startFromWay(loc, edge) { var startGraph = context.graph(); var node = osmNode({ loc }); - var way = osmWay({ tags: defaultTags }); + var way = osmWay({ tags: defaultTags(loc) }); context.perform( actionAddEntity(node), actionAddEntity(way), @@ -66267,7 +68936,7 @@ ${content} } function startFromNode(node) { var startGraph = context.graph(); - var way = osmWay({ tags: defaultTags }); + var way = osmWay({ tags: defaultTags(node.loc) }); context.perform( actionAddEntity(way), actionAddVertex(way.id, node.id) @@ -66287,11 +68956,14 @@ ${content} function modeAddPoint(context, mode) { mode.id = "add-point"; var behavior = behaviorDraw(context).on("click", add).on("clickWay", addWay).on("clickNode", addNode).on("cancel", cancel).on("finish", cancel); - var defaultTags = {}; - if (mode.preset) - defaultTags = mode.preset.setTags(defaultTags, "point"); + function defaultTags(loc) { + var defaultTags2 = {}; + if (mode.preset) + defaultTags2 = mode.preset.setTags(defaultTags2, "point", false, loc); + return defaultTags2; + } function add(loc) { - var node = osmNode({ loc, tags: defaultTags }); + var node = osmNode({ loc, tags: defaultTags(loc) }); context.perform( actionAddEntity(node), _t("operations.add.annotation.point") @@ -66299,7 +68971,7 @@ ${content} enterSelectMode(node); } function addWay(loc, edge) { - var node = osmNode({ tags: defaultTags }); + var node = osmNode({ tags: defaultTags(loc) }); context.perform( actionAddMidpoint({ loc, edge }, node), _t("operations.add.annotation.vertex") @@ -66312,13 +68984,14 @@ ${content} ); } function addNode(node) { - if (Object.keys(defaultTags).length === 0) { + const _defaultTags = defaultTags(node.loc); + if (Object.keys(_defaultTags).length === 0) { enterSelectMode(node); return; } var tags = Object.assign({}, node.tags); - for (var key in defaultTags) { - tags[key] = defaultTags[key]; + for (var key in _defaultTags) { + tags[key] = _defaultTags[key]; } context.perform( actionChangeTags(node.id, tags), @@ -67006,7 +69679,10 @@ ${content} icon: "iD-icon-" + (_mainLocalizer.textDirection() === "rtl" ? "undo" : "redo") }]; function editable() { - return context.mode() && context.mode().id !== "save" && context.map().editableDataEnabled(true); + return context.mode() && context.mode().id !== "save" && context.map().editableDataEnabled( + true + /* ignore min zoom */ + ); } tool.render = function(selection2) { var tooltipBehavior = uiTooltip().placement("bottom").title(function(d) { @@ -67433,21 +70109,21 @@ ${content} var item = select_default2(this).select("label"); var span = item.select("span"); var placement = i2 < nodes.length / 2 ? "bottom" : "top"; - var description = d.description(); + var hasDescription = d.hasDescription(); var isOverflowing = span.property("clientWidth") !== span.property("scrollWidth"); item.call(uiTooltip().destroyAny); if (d.id === previousBackgroundID()) { item.call( uiTooltip().placement(placement).title(() => _t.append("background.switch")).keys([uiCmd("\u2318" + _t("background.key"))]) ); - } else if (description || isOverflowing) { + } else if (hasDescription || isOverflowing) { item.call( - uiTooltip().placement(placement).title(() => description || d.label()) + uiTooltip().placement(placement).title(() => hasDescription ? d.description() : d.label()) ); } }); } - function drawListItems(layerList, type3, change, filter2) { + function drawListItems(layerList, type2, change, filter2) { var sources = context.background().sources(context.map().extent(), context.map().zoom(), true).filter(filter2).sort(function(a, b) { return a.best() && !b.best() ? -1 : b.best() && !a.best() ? 1 : descending(a.area(), b.area()) || ascending(a.name(), b.name()) || 0; }); @@ -67461,7 +70137,7 @@ ${content} return d.best(); }); var label = enter.append("label"); - label.append("input").attr("type", type3).attr("name", "background-layer").attr("value", function(d) { + label.append("input").attr("type", type2).attr("name", "background-layer").attr("value", function(d) { return d.id; }).on("change", change); label.append("span").each(function(d) { @@ -67650,7 +70326,7 @@ ${content} _overlayList.call(updateLayerSelections); document.activeElement.blur(); } - function drawListItems(layerList, type3, change, filter2) { + function drawListItems(layerList, type2, change, filter2) { var sources = context.background().sources(context.map().extent(), context.map().zoom(), true).filter(filter2); var layerLinks = layerList.selectAll("li").data(sources, function(d) { return d.name(); @@ -67658,7 +70334,7 @@ ${content} layerLinks.exit().remove(); var enter = layerLinks.enter().append("li"); var label = enter.append("label"); - label.append("input").attr("type", type3).attr("name", "layers").on("change", change); + label.append("input").attr("type", type2).attr("name", "layers").on("change", change); label.append("span").each(function(d) { d.label()(select_default2(this)); }); @@ -67706,6 +70382,7 @@ ${content} "before_start", "open_source_h", "open_source", + "open_source_attribution", "open_source_help" ]], ["overview", [ @@ -68141,7 +70818,9 @@ ${content} function getOptions() { return { what: corePreferences("validate-what") || "edited", + // 'all', 'edited' where: corePreferences("validate-where") || "all" + // 'all', 'visible' }; } function updateOptionValue(d3_event, d, val) { @@ -68181,7 +70860,7 @@ ${content} container = container.merge(containerEnter); container.selectAll(".issue-rules-list").call(drawListItems, _ruleKeys, "checkbox", "rule", toggleRule, isRuleEnabled); } - function drawListItems(selection2, data, type3, name, change, active) { + function drawListItems(selection2, data, type2, name, change, active) { var items = selection2.selectAll("li").data(data); items.exit().remove(); var enter = items.enter().append("li"); @@ -68193,7 +70872,7 @@ ${content} ); } var label = enter.append("label"); - label.append("input").attr("type", type3).attr("name", name).on("change", change); + label.append("input").attr("type", type2).attr("name", name).on("change", change); label.append("span").html(function(d) { var params = {}; if (d === "unsquare_way") { @@ -68223,7 +70902,7 @@ ${content} function changeSquare() { var input = select_default2(this); var degStr = utilGetSetValue(input).trim(); - var degNum = parseFloat(degStr, 10); + var degNum = Number(degStr); if (!isFinite(degNum)) { degNum = DEFAULTSQUARE; } else if (degNum > MAXSQUARE) { @@ -68288,12 +70967,12 @@ ${content} function setNoIssuesText(selection2) { var opts = getOptions(); function checkForHiddenIssues(cases) { - for (var type3 in cases) { - var hiddenOpts = cases[type3]; + for (var type2 in cases) { + var hiddenOpts = cases[type2]; var hiddenIssues = context.validator().getIssues(hiddenOpts); if (hiddenIssues.length) { selection2.select(".box .details").html("").call(_t.append( - "issues.no_issues.hidden_issues." + type3, + "issues.no_issues.hidden_issues." + type2, { count: hiddenIssues.length.toString() } )); return; @@ -68673,7 +71352,7 @@ ${content} container = container.merge(containerEnter); container.selectAll(".layer-feature-list").call(drawListItems, _features, "checkbox", "feature", clickFeature, showsFeature); } - function drawListItems(selection2, data, type3, name, change, active) { + function drawListItems(selection2, data, type2, name, change, active) { var items = selection2.selectAll("li").data(data); items.exit().remove(); var enter = items.enter().append("li").call( @@ -68690,7 +71369,7 @@ ${content} }).placement("top") ); var label = enter.append("label"); - label.append("input").attr("type", type3).attr("name", name).on("change", change); + label.append("input").attr("type", type2).attr("name", name).on("change", change); label.append("span").html(function(d) { return _t.html(name + "." + d + ".description"); }); @@ -68725,7 +71404,7 @@ ${content} return context.surface().classed("highlight-edited"); }); } - function drawListItems(selection2, data, type3, name, change, active) { + function drawListItems(selection2, data, type2, name, change, active) { var items = selection2.selectAll("li").data(data); items.exit().remove(); var enter = items.enter().append("li").call( @@ -68739,952 +71418,1765 @@ ${content} }).placement("top") ); var label = enter.append("label"); - label.append("input").attr("type", type3).attr("name", name).on("change", change); + label.append("input").attr("type", type2).attr("name", name).on("change", change); label.append("span").html(function(d) { return _t.html(name + "." + d + ".description"); }); - items = items.merge(enter); - items.classed("active", active).selectAll("input").property("checked", active).property("indeterminate", false); - } - function isActiveFill(d) { - return context.map().activeAreaFill() === d; - } - function toggleHighlightEdited(d3_event) { - d3_event.preventDefault(); - context.map().toggleHighlightEdited(); - } - function setFill(d3_event, d) { - context.map().activeAreaFill(d); - } - context.map().on("changeHighlighting.ui_style, changeAreaFill.ui_style", section.reRender); - return section; + items = items.merge(enter); + items.classed("active", active).selectAll("input").property("checked", active).property("indeterminate", false); + } + function isActiveFill(d) { + return context.map().activeAreaFill() === d; + } + function toggleHighlightEdited(d3_event) { + d3_event.preventDefault(); + context.map().toggleHighlightEdited(); + } + function setFill(d3_event, d) { + context.map().activeAreaFill(d); + } + context.map().on("changeHighlighting.ui_style, changeAreaFill.ui_style", section.reRender); + return section; + } + + // modules/ui/sections/photo_overlays.js + function uiSectionPhotoOverlays(context) { + var layers = context.layers(); + var section = uiSection("photo-overlays", context).label(() => _t.append("photo_overlays.title")).disclosureContent(renderDisclosureContent).expandedByDefault(false); + function renderDisclosureContent(selection2) { + var container = selection2.selectAll(".photo-overlay-container").data([0]); + container.enter().append("div").attr("class", "photo-overlay-container").merge(container).call(drawPhotoItems).call(drawPhotoTypeItems).call(drawDateFilter).call(drawUsernameFilter); + } + function drawPhotoItems(selection2) { + var photoKeys = context.photos().overlayLayerIDs(); + var photoLayers = layers.all().filter(function(obj) { + return photoKeys.indexOf(obj.id) !== -1; + }); + var data = photoLayers.filter(function(obj) { + return obj.layer.supported(); + }); + function layerSupported(d) { + return d.layer && d.layer.supported(); + } + function layerEnabled(d) { + return layerSupported(d) && d.layer.enabled(); + } + var ul = selection2.selectAll(".layer-list-photos").data([0]); + ul = ul.enter().append("ul").attr("class", "layer-list layer-list-photos").merge(ul); + var li = ul.selectAll(".list-item-photos").data(data); + li.exit().remove(); + var liEnter = li.enter().append("li").attr("class", function(d) { + var classes = "list-item-photos list-item-" + d.id; + if (d.id === "mapillary-signs" || d.id === "mapillary-map-features") { + classes += " indented"; + } + return classes; + }); + var labelEnter = liEnter.append("label").each(function(d) { + var titleID; + if (d.id === "mapillary-signs") + titleID = "mapillary.signs.tooltip"; + else if (d.id === "mapillary") + titleID = "mapillary_images.tooltip"; + else if (d.id === "kartaview") + titleID = "kartaview_images.tooltip"; + else + titleID = d.id.replace(/-/g, "_") + ".tooltip"; + select_default2(this).call( + uiTooltip().title(() => _t.append(titleID)).placement("top") + ); + }); + labelEnter.append("input").attr("type", "checkbox").on("change", function(d3_event, d) { + toggleLayer(d.id); + }); + labelEnter.append("span").html(function(d) { + var id2 = d.id; + if (id2 === "mapillary-signs") + id2 = "photo_overlays.traffic_signs"; + return _t.html(id2.replace(/-/g, "_") + ".title"); + }); + li.merge(liEnter).classed("active", layerEnabled).selectAll("input").property("checked", layerEnabled); + } + function drawPhotoTypeItems(selection2) { + var data = context.photos().allPhotoTypes(); + function typeEnabled(d) { + return context.photos().showsPhotoType(d); + } + var ul = selection2.selectAll(".layer-list-photo-types").data([0]); + ul.exit().remove(); + ul = ul.enter().append("ul").attr("class", "layer-list layer-list-photo-types").merge(ul); + var li = ul.selectAll(".list-item-photo-types").data(context.photos().shouldFilterByPhotoType() ? data : []); + li.exit().remove(); + var liEnter = li.enter().append("li").attr("class", function(d) { + return "list-item-photo-types list-item-" + d; + }); + var labelEnter = liEnter.append("label").each(function(d) { + select_default2(this).call( + uiTooltip().title(() => _t.append("photo_overlays.photo_type." + d + ".tooltip")).placement("top") + ); + }); + labelEnter.append("input").attr("type", "checkbox").on("change", function(d3_event, d) { + context.photos().togglePhotoType(d); + }); + labelEnter.append("span").html(function(d) { + return _t.html("photo_overlays.photo_type." + d + ".title"); + }); + li.merge(liEnter).classed("active", typeEnabled).selectAll("input").property("checked", typeEnabled); + } + function drawDateFilter(selection2) { + var data = context.photos().dateFilters(); + function filterEnabled(d) { + return context.photos().dateFilterValue(d); + } + var ul = selection2.selectAll(".layer-list-date-filter").data([0]); + ul.exit().remove(); + ul = ul.enter().append("ul").attr("class", "layer-list layer-list-date-filter").merge(ul); + var li = ul.selectAll(".list-item-date-filter").data(context.photos().shouldFilterByDate() ? data : []); + li.exit().remove(); + var liEnter = li.enter().append("li").attr("class", "list-item-date-filter"); + var labelEnter = liEnter.append("label").each(function(d) { + select_default2(this).call( + uiTooltip().title(() => _t.append("photo_overlays.date_filter." + d + ".tooltip")).placement("top") + ); + }); + labelEnter.append("span").each(function(d) { + _t.append("photo_overlays.date_filter." + d + ".title")(select_default2(this)); + }); + labelEnter.append("input").attr("type", "date").attr("class", "list-item-input").attr("placeholder", _t("units.year_month_day")).call(utilNoAuto).each(function(d) { + utilGetSetValue(select_default2(this), context.photos().dateFilterValue(d) || ""); + }).on("change", function(d3_event, d) { + var value = utilGetSetValue(select_default2(this)).trim(); + context.photos().setDateFilter(d, value, true); + li.selectAll("input").each(function(d2) { + utilGetSetValue(select_default2(this), context.photos().dateFilterValue(d2) || ""); + }); + }); + li = li.merge(liEnter).classed("active", filterEnabled); + } + function drawUsernameFilter(selection2) { + function filterEnabled() { + return context.photos().usernames(); + } + var ul = selection2.selectAll(".layer-list-username-filter").data([0]); + ul.exit().remove(); + ul = ul.enter().append("ul").attr("class", "layer-list layer-list-username-filter").merge(ul); + var li = ul.selectAll(".list-item-username-filter").data(context.photos().shouldFilterByUsername() ? ["username-filter"] : []); + li.exit().remove(); + var liEnter = li.enter().append("li").attr("class", "list-item-username-filter"); + var labelEnter = liEnter.append("label").each(function() { + select_default2(this).call( + uiTooltip().title(() => _t.append("photo_overlays.username_filter.tooltip")).placement("top") + ); + }); + labelEnter.append("span").call(_t.append("photo_overlays.username_filter.title")); + labelEnter.append("input").attr("type", "text").attr("class", "list-item-input").call(utilNoAuto).property("value", usernameValue).on("change", function() { + var value = select_default2(this).property("value"); + context.photos().setUsernameFilter(value, true); + select_default2(this).property("value", usernameValue); + }); + li.merge(liEnter).classed("active", filterEnabled); + function usernameValue() { + var usernames = context.photos().usernames(); + if (usernames) + return usernames.join("; "); + return usernames; + } + } + function toggleLayer(which) { + setLayer(which, !showsLayer(which)); + } + function showsLayer(which) { + var layer = layers.layer(which); + if (layer) { + return layer.enabled(); + } + return false; + } + function setLayer(which, enabled) { + var layer = layers.layer(which); + if (layer) { + layer.enabled(enabled); + } + } + context.layers().on("change.uiSectionPhotoOverlays", section.reRender); + context.photos().on("change.uiSectionPhotoOverlays", section.reRender); + return section; + } + + // modules/ui/panes/map_data.js + function uiPaneMapData(context) { + var mapDataPane = uiPane("map-data", context).key(_t("map_data.key")).label(_t.append("map_data.title")).description(_t.append("map_data.description")).iconName("iD-icon-data").sections([ + uiSectionDataLayers(context), + uiSectionPhotoOverlays(context), + uiSectionMapStyleOptions(context), + uiSectionMapFeatures(context) + ]); + return mapDataPane; + } + + // modules/ui/panes/preferences.js + function uiPanePreferences(context) { + let preferencesPane = uiPane("preferences", context).key(_t("preferences.key")).label(_t.append("preferences.title")).description(_t.append("preferences.description")).iconName("fas-user-cog").sections([ + uiSectionPrivacy(context) + ]); + return preferencesPane; + } + + // modules/ui/init.js + function uiInit(context) { + var _initCounter = 0; + var _needWidth = {}; + var _lastPointerType; + function render(container) { + container.on("click.ui", function(d3_event) { + if (d3_event.button !== 0) + return; + if (!d3_event.composedPath) + return; + var isOkayTarget = d3_event.composedPath().some(function(node) { + return node.nodeType === 1 && // clicking focuses it and/or changes a value + (node.nodeName === "INPUT" || // clicking