2 var __create = Object.create;
3 var __defProp = Object.defineProperty;
4 var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5 var __getOwnPropNames = Object.getOwnPropertyNames;
6 var __getProtoOf = Object.getPrototypeOf;
7 var __hasOwnProp = Object.prototype.hasOwnProperty;
8 var __commonJS = (cb, mod) => function __require() {
9 return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
11 var __export = (target, all) => {
13 __defProp(target, name, { get: all[name], enumerable: true });
15 var __copyProps = (to, from, except, desc) => {
16 if (from && typeof from === "object" || typeof from === "function") {
17 for (let key of __getOwnPropNames(from))
18 if (!__hasOwnProp.call(to, key) && key !== except)
19 __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
23 var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
24 // If the importer is in node compatibility mode or this is not an ESM
25 // file that has been converted to a CommonJS file using a Babel-
26 // compatible transform (i.e. "__esModule" has not been set), then set
27 // "default" to the CommonJS "module.exports" for node compatibility.
28 isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
32 // node_modules/diacritics/index.js
33 var require_diacritics = __commonJS({
34 "node_modules/diacritics/index.js"(exports2) {
35 exports2.remove = removeDiacritics2;
36 var replacementList = [
47 chars: "\u24B6\uFF21\xC0\xC1\xC2\u1EA6\u1EA4\u1EAA\u1EA8\xC3\u0100\u0102\u1EB0\u1EAE\u1EB4\u1EB2\u0226\u01E0\xC4\u01DE\u1EA2\xC5\u01FA\u01CD\u0200\u0202\u1EA0\u1EAC\u1EB6\u1E00\u0104\u023A\u2C6F"
55 chars: "\xC6\u01FC\u01E2"
75 chars: "\u24B7\uFF22\u1E02\u1E04\u1E06\u0243\u0181"
79 chars: "\u24B8\uFF23\uA73E\u1E08\u0106C\u0108\u010A\u010C\xC7\u0187\u023B"
83 chars: "\u24B9\uFF24\u1E0A\u010E\u1E0C\u1E10\u1E12\u1E0E\u0110\u018A\u0189\u1D05\uA779"
99 chars: "\u025B\u24BA\uFF25\xC8\xC9\xCA\u1EC0\u1EBE\u1EC4\u1EC2\u1EBC\u0112\u1E14\u1E16\u0114\u0116\xCB\u1EBA\u011A\u0204\u0206\u1EB8\u1EC6\u0228\u1E1C\u0118\u1E18\u1E1A\u0190\u018E\u1D07"
103 chars: "\uA77C\u24BB\uFF26\u1E1E\u0191\uA77B"
107 chars: "\u24BC\uFF27\u01F4\u011C\u1E20\u011E\u0120\u01E6\u0122\u01E4\u0193\uA7A0\uA77D\uA77E\u0262"
111 chars: "\u24BD\uFF28\u0124\u1E22\u1E26\u021E\u1E24\u1E28\u1E2A\u0126\u2C67\u2C75\uA78D"
115 chars: "\u24BE\uFF29\xCC\xCD\xCE\u0128\u012A\u012C\u0130\xCF\u1E2E\u1EC8\u01CF\u0208\u020A\u1ECA\u012E\u1E2C\u0197"
119 chars: "\u24BF\uFF2A\u0134\u0248\u0237"
123 chars: "\u24C0\uFF2B\u1E30\u01E8\u1E32\u0136\u1E34\u0198\u2C69\uA740\uA742\uA744\uA7A2"
127 chars: "\u24C1\uFF2C\u013F\u0139\u013D\u1E36\u1E38\u013B\u1E3C\u1E3A\u0141\u023D\u2C62\u2C60\uA748\uA746\uA780"
139 chars: "\u24C2\uFF2D\u1E3E\u1E40\u1E42\u2C6E\u019C\u03FB"
143 chars: "\uA7A4\u0220\u24C3\uFF2E\u01F8\u0143\xD1\u1E44\u0147\u1E46\u0145\u1E4A\u1E48\u019D\uA790\u1D0E"
155 chars: "\u24C4\uFF2F\xD2\xD3\xD4\u1ED2\u1ED0\u1ED6\u1ED4\xD5\u1E4C\u022C\u1E4E\u014C\u1E50\u1E52\u014E\u022E\u0230\xD6\u022A\u1ECE\u0150\u01D1\u020C\u020E\u01A0\u1EDC\u1EDA\u1EE0\u1EDE\u1EE2\u1ECC\u1ED8\u01EA\u01EC\xD8\u01FE\u0186\u019F\uA74A\uA74C"
175 chars: "\u24C5\uFF30\u1E54\u1E56\u01A4\u2C63\uA750\uA752\uA754"
179 chars: "\u24C6\uFF31\uA756\uA758\u024A"
183 chars: "\u24C7\uFF32\u0154\u1E58\u0158\u0210\u0212\u1E5A\u1E5C\u0156\u1E5E\u024C\u2C64\uA75A\uA7A6\uA782"
187 chars: "\u24C8\uFF33\u1E9E\u015A\u1E64\u015C\u1E60\u0160\u1E66\u1E62\u1E68\u0218\u015E\u2C7E\uA7A8\uA784"
191 chars: "\u24C9\uFF34\u1E6A\u0164\u1E6C\u021A\u0162\u1E70\u1E6E\u0166\u01AC\u01AE\u023E\uA786"
203 chars: "\u24CA\uFF35\xD9\xDA\xDB\u0168\u1E78\u016A\u1E7A\u016C\xDC\u01DB\u01D7\u01D5\u01D9\u1EE6\u016E\u0170\u01D3\u0214\u0216\u01AF\u1EEA\u1EE8\u1EEE\u1EEC\u1EF0\u1EE4\u1E72\u0172\u1E76\u1E74\u0244"
207 chars: "\u24CB\uFF36\u1E7C\u1E7E\u01B2\uA75E\u0245"
215 chars: "\u24CC\uFF37\u1E80\u1E82\u0174\u1E86\u1E84\u1E88\u2C72"
219 chars: "\u24CD\uFF38\u1E8A\u1E8C"
223 chars: "\u24CE\uFF39\u1EF2\xDD\u0176\u1EF8\u0232\u1E8E\u0178\u1EF6\u1EF4\u01B3\u024E\u1EFE"
227 chars: "\u24CF\uFF3A\u0179\u1E90\u017B\u017D\u1E92\u1E94\u01B5\u0224\u2C7F\u2C6B\uA762"
231 chars: "\u24D0\uFF41\u1E9A\xE0\xE1\xE2\u1EA7\u1EA5\u1EAB\u1EA9\xE3\u0101\u0103\u1EB1\u1EAF\u1EB5\u1EB3\u0227\u01E1\xE4\u01DF\u1EA3\xE5\u01FB\u01CE\u0201\u0203\u1EA1\u1EAD\u1EB7\u1E01\u0105\u2C65\u0250\u0251"
239 chars: "\xE6\u01FD\u01E3"
251 chars: "\uA739\uA73B"
259 chars: "\u24D1\uFF42\u1E03\u1E05\u1E07\u0180\u0183\u0253\u0182"
263 chars: "\uFF43\u24D2\u0107\u0109\u010B\u010D\xE7\u1E09\u0188\u023C\uA73F\u2184"
267 chars: "\u24D3\uFF44\u1E0B\u010F\u1E0D\u1E11\u1E13\u1E0F\u0111\u018C\u0256\u0257\u018B\u13E7\u0501\uA7AA"
275 chars: "\u01F3\u01C6"
279 chars: "\u24D4\uFF45\xE8\xE9\xEA\u1EC1\u1EBF\u1EC5\u1EC3\u1EBD\u0113\u1E15\u1E17\u0115\u0117\xEB\u1EBB\u011B\u0205\u0207\u1EB9\u1EC7\u0229\u1E1D\u0119\u1E19\u1E1B\u0247\u01DD"
283 chars: "\u24D5\uFF46\u1E1F\u0192"
307 chars: "\u24D6\uFF47\u01F5\u011D\u1E21\u011F\u0121\u01E7\u0123\u01E5\u0260\uA7A1\uA77F\u1D79"
311 chars: "\u24D7\uFF48\u0125\u1E23\u1E27\u021F\u1E25\u1E29\u1E2B\u1E96\u0127\u2C68\u2C76\u0265"
319 chars: "\u24D8\uFF49\xEC\xED\xEE\u0129\u012B\u012D\xEF\u1E2F\u1EC9\u01D0\u0209\u020B\u1ECB\u012F\u1E2D\u0268\u0131"
323 chars: "\u24D9\uFF4A\u0135\u01F0\u0249"
327 chars: "\u24DA\uFF4B\u1E31\u01E9\u1E33\u0137\u1E35\u0199\u2C6A\uA741\uA743\uA745\uA7A3"
331 chars: "\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u1E3D\u1E3B\u017F\u0142\u019A\u026B\u2C61\uA749\uA781\uA747\u026D"
339 chars: "\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F"
343 chars: "\u24DD\uFF4E\u01F9\u0144\xF1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5\u043B\u0509"
351 chars: "\u24DE\uFF4F\xF2\xF3\xF4\u1ED3\u1ED1\u1ED7\u1ED5\xF5\u1E4D\u022D\u1E4F\u014D\u1E51\u1E53\u014F\u022F\u0231\xF6\u022B\u1ECF\u0151\u01D2\u020D\u020F\u01A1\u1EDD\u1EDB\u1EE1\u1EDF\u1EE3\u1ECD\u1ED9\u01EB\u01ED\xF8\u01FF\uA74B\uA74D\u0275\u0254\u1D11"
371 chars: "\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755\u03C1"
375 chars: "\u24E0\uFF51\u024B\uA757\uA759"
379 chars: "\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783"
383 chars: "\u24E2\uFF53\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B\u0282"
391 chars: "\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787"
403 chars: "\u24E4\uFF55\xF9\xFA\xFB\u0169\u1E79\u016B\u1E7B\u016D\xFC\u01DC\u01D8\u01D6\u01DA\u1EE7\u016F\u0171\u01D4\u0215\u0217\u01B0\u1EEB\u1EE9\u1EEF\u1EED\u1EF1\u1EE5\u1E73\u0173\u1E77\u1E75\u0289"
407 chars: "\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C"
415 chars: "\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73"
419 chars: "\u24E7\uFF58\u1E8B\u1E8D"
423 chars: "\u24E8\uFF59\u1EF3\xFD\u0177\u1EF9\u0233\u1E8F\xFF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF"
427 chars: "\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763"
430 var diacriticsMap = {};
431 for (i2 = 0; i2 < replacementList.length; i2 += 1) {
432 chars = replacementList[i2].chars;
433 for (j2 = 0; j2 < chars.length; j2 += 1) {
434 diacriticsMap[chars[j2]] = replacementList[i2].base;
440 function removeDiacritics2(str2) {
441 return str2.replace(/[^\u0000-\u007e]/g, function(c) {
442 return diacriticsMap[c] || c;
445 exports2.replacementList = replacementList;
446 exports2.diacriticsMap = diacriticsMap;
450 // node_modules/alif-toolkit/lib/isArabic.js
451 var require_isArabic = __commonJS({
452 "node_modules/alif-toolkit/lib/isArabic.js"(exports2) {
454 Object.defineProperty(exports2, "__esModule", { value: true });
464 // Mathematical Alphabetic symbols https://www.unicode.org/charts/PDF/U1EE00.pdf
466 function isArabic(char) {
467 if (char.length > 1) {
468 throw new Error("isArabic works on only one-character strings");
470 let code = char.charCodeAt(0);
471 for (let i2 = 0; i2 < arabicBlocks.length; i2++) {
472 let block2 = arabicBlocks[i2];
473 if (code >= block2[0] && code <= block2[1]) {
479 exports2.isArabic = isArabic;
480 function isMath(char) {
481 if (char.length > 2) {
482 throw new Error("isMath works on only one-character strings");
484 let code = char.charCodeAt(0);
485 return code >= 1632 && code <= 1644 || code >= 1776 && code <= 1785;
487 exports2.isMath = isMath;
491 // node_modules/alif-toolkit/lib/unicode-arabic.js
492 var require_unicode_arabic = __commonJS({
493 "node_modules/alif-toolkit/lib/unicode-arabic.js"(exports2) {
495 Object.defineProperty(exports2, "__esModule", { value: true });
496 var arabicReference = {
506 "isolated": "\uFE81",
514 "isolated": "\uFE83",
522 "isolated": "\uFE87",
527 "isolated": "\uFB50",
530 "wavy_hamza_above": [
533 "wavy_hamza_below": [
544 "indic_three_above": [
554 "isolated": "\uFE8D",
564 "three_dots_horizontally_below": [
567 "dot_below_three_dots_above": [
570 "three_dots_pointing_upwards_below": [
573 "three_dots_pointing_upwards_below_two_dots_above": [
576 "two_dots_below_dot_above": [
579 "inverted_small_v_below": [
591 "small_meem_above": [
594 "isolated": "\uFE8F",
603 "isolated": "\uFE93",
613 "three_dots_above_downwards": [
619 "isolated": "\uFE95",
628 "isolated": "\uFE99",
640 "isolated": "\uFE9D",
652 "two_dots_vertical_above": [
655 "three_dots_above": [
661 "three_dots_pointing_upwards_below": [
667 "small_tah_two_dots": [
673 "indic_four_below": [
676 "isolated": "\uFEA1",
685 "isolated": "\uFEA5",
700 "dot_below_small_tah": [
703 "three_dots_above_downwards": [
712 "two_dots_vertically_below_small_tah": [
715 "inverted_small_v_below": [
718 "three_dots_below": [
721 "isolated": "\uFEA9",
728 "isolated": "\uFEAB",
747 "dot_below_dot_above": [
762 "two_dots_vertically_above": [
768 "small_tah_two_dots": [
774 "small_noon_above": [
777 "isolated": "\uFEAD",
784 "inverted_v_above": [
787 "isolated": "\uFEAF",
794 "dot_below_dot_above": [
797 "three_dots_below": [
800 "three_dots_below_three_dots_above": [
806 "two_dots_vertically_above": [
809 "small_tah_two_dots": [
812 "indic_four_above": [
818 "isolated": "\uFEB1",
830 "isolated": "\uFEB5",
842 "three_dots_above": [
845 "three_dots_below": [
848 "isolated": "\uFEB9",
860 "isolated": "\uFEBD",
869 "three_dots_above": [
875 "isolated": "\uFEC1",
884 "isolated": "\uFEC5",
893 "three_dots_above": [
899 "three_dots_pointing_downwards_above": [
902 "two_dots_vertically_above": [
905 "three_dots_below": [
908 "isolated": "\uFEC9",
920 "isolated": "\uFECD",
938 "three_dots_below": [
944 "three_dots_pointing_upwards_below": [
947 "dot_below_three_dots_above": [
950 "isolated": "\uFED1",
965 "three_dots_above": [
971 "isolated": "\uFED5",
989 "three_dots_below": [
998 "isolated": "\uFED9",
1000 "initial": "\uFEDB",
1013 "three_dots_above": [
1016 "three_dots_below": [
1025 "isolated": "\uFEDD",
1027 "initial": "\uFEDF",
1040 "three_dots_above": [
1043 "isolated": "\uFEE1",
1045 "initial": "\uFEE3",
1058 "three_dots_above": [
1070 "isolated": "\uFEE5",
1072 "initial": "\uFEE7",
1079 "isolated": "\uFEE9",
1081 "initial": "\uFEEB",
1093 "isolated": "\uFE85",
1109 "indic_two_above": [
1112 "indic_three_above": [
1118 "isolated": "\uFEED",
1129 "initial": "\uFBE8",
1131 "isolated": "\uFEEF",
1143 "isolated": "\uFE89",
1145 "initial": "\uFE8B",
1148 "two_dots_below_hamza_above": [
1161 "three_dots_below": [
1164 "two_dots_below_dot_above": [
1167 "two_dots_below_small_noon_above": [
1170 "isolated": "\uFEF1",
1172 "initial": "\uFEF3",
1179 "isolated": "\uFB66",
1181 "initial": "\uFB68",
1188 "isolated": "\uFB5E",
1190 "initial": "\uFB60",
1197 "isolated": "\uFB52",
1199 "initial": "\uFB54",
1206 "small_meem_above": [
1209 "isolated": "\uFB56",
1211 "initial": "\uFB58",
1218 "isolated": "\uFB62",
1220 "initial": "\uFB64",
1227 "isolated": "\uFB5A",
1229 "initial": "\uFB5C",
1236 "isolated": "\uFB76",
1238 "initial": "\uFB78",
1245 "isolated": "\uFB72",
1247 "initial": "\uFB74",
1257 "isolated": "\uFB7A",
1259 "initial": "\uFB7C",
1266 "isolated": "\uFB7E",
1268 "initial": "\uFB80",
1275 "isolated": "\uFB88",
1282 "isolated": "\uFB84",
1289 "isolated": "\uFB82",
1297 "isolated": "\uFB86",
1304 "isolated": "\uFB8C",
1311 "isolated": "\uFB8A",
1318 "isolated": "\uFB6A",
1320 "initial": "\uFB6C",
1327 "isolated": "\uFB6E",
1329 "initial": "\uFB70",
1339 "three_dots_above": [
1342 "three_dots_pointing_upwards_below": [
1345 "isolated": "\uFB8E",
1347 "initial": "\uFB90",
1354 "isolated": "\uFBD3",
1356 "initial": "\uFBD5",
1369 "three_dots_above": [
1372 "inverted_stroke": [
1375 "isolated": "\uFB92",
1377 "initial": "\uFB94",
1384 "isolated": "\uFB9A",
1386 "initial": "\uFB9C",
1393 "isolated": "\uFB96",
1395 "initial": "\uFB98",
1402 "isolated": "\uFB9E",
1409 "isolated": "\uFBA0",
1411 "initial": "\uFBA2",
1414 "heh doachashmee": {
1418 "isolated": "\uFBAA",
1420 "initial": "\uFBAC",
1431 "isolated": "\uFBA6",
1433 "initial": "\uFBA8",
1436 "teh marbuta goal": {
1445 "isolated": "\uFBE0",
1452 "isolated": "\uFBD9",
1464 "isolated": "\uFBDD"
1466 "isolated": "\uFBD7",
1473 "isolated": "\uFBDB",
1480 "isolated": "\uFBE2",
1487 "isolated": "\uFBDE",
1494 "indic_two_above": [
1497 "indic_three_above": [
1500 "indic_four_above": [
1503 "isolated": "\uFBFC",
1505 "initial": "\uFBFE",
1512 "isolated": "\uFBE4",
1514 "initial": "\uFBE6",
1526 "isolated": "\uFBB0",
1529 "indic_two_above": [
1532 "indic_three_above": [
1535 "isolated": "\uFBAE",
1542 "isolated": "\u06D5",
1549 "isolated": "\uFBA4",
1584 exports2.default = arabicReference;
1588 // node_modules/alif-toolkit/lib/unicode-ligatures.js
1589 var require_unicode_ligatures = __commonJS({
1590 "node_modules/alif-toolkit/lib/unicode-ligatures.js"(exports2) {
1592 Object.defineProperty(exports2, "__esModule", { value: true });
1593 var ligatureReference = {
1595 "isolated": "\uFBEA",
1599 "isolated": "\uFBEC",
1603 "isolated": "\uFBEE",
1607 "isolated": "\uFBF0",
1611 "isolated": "\uFBF2",
1615 "isolated": "\uFBF4",
1619 "isolated": "\uFBF6",
1625 "isolated": "\uFBF9",
1629 "isolated": "\uFC03",
1633 "isolated": "\uFC00",
1637 "isolated": "\uFC01",
1641 "isolated": "\uFC02",
1643 "initial": "\uFC9A",
1647 "isolated": "\uFC04",
1651 "isolated": "\uFC05",
1655 "isolated": "\uFC06",
1659 "isolated": "\uFC07",
1663 "isolated": "\uFC08",
1665 "initial": "\uFC9F",
1669 "isolated": "\uFC09",
1673 "isolated": "\uFC0A",
1677 "isolated": "\uFC0B",
1681 "isolated": "\uFC0C",
1685 "isolated": "\uFC0D",
1689 "isolated": "\uFC0E",
1691 "initial": "\uFCA4",
1695 "isolated": "\uFC0F",
1699 "isolated": "\uFC10",
1703 "isolated": "\uFC11"
1706 "isolated": "\uFC12",
1708 "initial": "\uFCA6",
1712 "isolated": "\uFC13",
1716 "isolated": "\uFC14"
1719 "isolated": "\uFC15",
1723 "isolated": "\uFC16",
1727 "isolated": "\uFC17",
1731 "isolated": "\uFC18",
1735 "isolated": "\uFC19",
1739 "isolated": "\uFC1A"
1742 "isolated": "\uFC1B",
1746 "isolated": "\uFC1C",
1747 "initial": "\uFCAD",
1751 "isolated": "\uFC1D",
1752 "initial": "\uFCAE",
1756 "isolated": "\uFC1E",
1757 "initial": "\uFCAF",
1761 "isolated": "\uFC1F",
1762 "initial": "\uFCB0",
1766 "isolated": "\uFC20",
1770 "isolated": "\uFC21",
1774 "isolated": "\uFC22",
1778 "isolated": "\uFC23",
1782 "isolated": "\uFC24",
1786 "isolated": "\uFC25",
1790 "isolated": "\uFC26",
1794 "isolated": "\uFC27",
1795 "initial": "\uFD33",
1799 "isolated": "\uFC28",
1800 "initial": "\uFCB9",
1804 "isolated": "\uFC29",
1808 "isolated": "\uFC2A",
1812 "isolated": "\uFC2B",
1816 "isolated": "\uFC2C",
1820 "isolated": "\uFC2D",
1824 "isolated": "\uFC2E",
1828 "isolated": "\uFC2F",
1832 "isolated": "\uFC30",
1836 "isolated": "\uFC31",
1840 "isolated": "\uFC32",
1844 "isolated": "\uFC33",
1848 "isolated": "\uFC34",
1852 "isolated": "\uFC35",
1856 "isolated": "\uFC36",
1860 "isolated": "\uFC37",
1864 "isolated": "\uFC38",
1868 "isolated": "\uFC39",
1872 "isolated": "\uFC3A",
1876 "isolated": "\uFC3B",
1878 "initial": "\uFCC7",
1882 "isolated": "\uFC3C",
1884 "initial": "\uFCC8",
1888 "isolated": "\uFC3D",
1892 "isolated": "\uFC3E",
1896 "isolated": "\uFC3F",
1900 "isolated": "\uFC40",
1904 "isolated": "\uFC41",
1908 "isolated": "\uFC42",
1910 "initial": "\uFCCC",
1914 "isolated": "\uFC43",
1918 "isolated": "\uFC44",
1922 "isolated": "\uFC45",
1926 "isolated": "\uFC46",
1930 "isolated": "\uFC47",
1934 "isolated": "\uFC48",
1939 "isolated": "\uFC49"
1942 "isolated": "\uFC4A"
1945 "isolated": "\uFC4B",
1949 "isolated": "\uFC4C",
1953 "isolated": "\uFC4D",
1957 "isolated": "\uFC4E",
1959 "initial": "\uFCD5",
1963 "isolated": "\uFC4F",
1967 "isolated": "\uFC50",
1971 "isolated": "\uFC51",
1975 "isolated": "\uFC52",
1979 "isolated": "\uFC53"
1982 "isolated": "\uFC54"
1985 "isolated": "\uFC55",
1989 "isolated": "\uFC56",
1993 "isolated": "\uFC57",
1997 "isolated": "\uFC58",
1999 "initial": "\uFCDD",
2003 "isolated": "\uFC59",
2007 "isolated": "\uFC5A",
2011 "isolated": "\uFC5B"
2014 "isolated": "\uFC5C"
2017 "isolated": "\uFC5D",
2021 "isolated": "\uFC5E"
2024 "isolated": "\uFC5F"
2027 "isolated": "\uFC60"
2030 "isolated": "\uFC61"
2033 "isolated": "\uFC62"
2036 "isolated": "\uFC63"
2102 "initial": "\uFC9B",
2106 "initial": "\uFCA0",
2110 "initial": "\uFCA5",
2120 "initial": "\uFCD6",
2127 "initial": "\uFCDE",
2139 "isolated": "\uFD0C",
2147 "\u0640\u064E\u0651": {
2150 "\u0640\u064F\u0651": {
2153 "\u0640\u0650\u0651": {
2157 "isolated": "\uFCF5",
2161 "isolated": "\uFCF6",
2165 "isolated": "\uFCF7",
2169 "isolated": "\uFCF8",
2173 "isolated": "\uFCF9",
2177 "isolated": "\uFCFA",
2181 "isolated": "\uFCFB"
2184 "isolated": "\uFCFC",
2188 "isolated": "\uFCFD",
2192 "isolated": "\uFCFE",
2196 "isolated": "\uFCFF",
2200 "isolated": "\uFD00",
2204 "isolated": "\uFD01",
2208 "isolated": "\uFD02",
2212 "isolated": "\uFD03",
2216 "isolated": "\uFD04",
2220 "isolated": "\uFD05",
2224 "isolated": "\uFD06",
2228 "isolated": "\uFD07",
2232 "isolated": "\uFD08",
2236 "isolated": "\uFD09",
2238 "initial": "\uFD2D",
2242 "isolated": "\uFD0A",
2244 "initial": "\uFD2E",
2248 "isolated": "\uFD0B",
2250 "initial": "\uFD2F",
2254 "isolated": "\uFD0D",
2258 "isolated": "\uFD0E",
2262 "isolated": "\uFD0F",
2266 "isolated": "\uFD10",
2272 "\u062A\u062C\u0645": {
2275 "\u062A\u062D\u062C": {
2279 "\u062A\u062D\u0645": {
2282 "\u062A\u062E\u0645": {
2285 "\u062A\u0645\u062C": {
2288 "\u062A\u0645\u062D": {
2291 "\u062A\u0645\u062E": {
2294 "\u062C\u0645\u062D": {
2298 "\u062D\u0645\u064A": {
2301 "\u062D\u0645\u0649": {
2304 "\u0633\u062D\u062C": {
2307 "\u0633\u062C\u062D": {
2310 "\u0633\u062C\u0649": {
2313 "\u0633\u0645\u062D": {
2317 "\u0633\u0645\u062C": {
2320 "\u0633\u0645\u0645": {
2324 "\u0635\u062D\u062D": {
2328 "\u0635\u0645\u0645": {
2332 "\u0634\u062D\u0645": {
2336 "\u0634\u062C\u064A": {
2339 "\u0634\u0645\u062E": {
2343 "\u0634\u0645\u0645": {
2347 "\u0636\u062D\u0649": {
2350 "\u0636\u062E\u0645": {
2354 "\u0636\u0645\u062D": {
2357 "\u0637\u0645\u062D": {
2360 "\u0637\u0645\u0645": {
2363 "\u0637\u0645\u064A": {
2366 "\u0639\u062C\u0645": {
2370 "\u0639\u0645\u0645": {
2374 "\u0639\u0645\u0649": {
2377 "\u063A\u0645\u0645": {
2380 "\u063A\u0645\u064A": {
2383 "\u063A\u0645\u0649": {
2386 "\u0641\u062E\u0645": {
2390 "\u0642\u0645\u062D": {
2394 "\u0642\u0645\u0645": {
2397 "\u0644\u062D\u0645": {
2401 "\u0644\u062D\u064A": {
2404 "\u0644\u062D\u0649": {
2407 "\u0644\u062C\u062C": {
2408 "initial": "\uFD83",
2411 "\u0644\u062E\u0645": {
2415 "\u0644\u0645\u062D": {
2419 "\u0645\u062D\u062C": {
2422 "\u0645\u062D\u0645": {
2425 "\u0645\u062D\u064A": {
2428 "\u0645\u062C\u062D": {
2431 "\u0645\u062C\u0645": {
2434 "\u0645\u062E\u062C": {
2437 "\u0645\u062E\u0645": {
2440 "\u0645\u062C\u062E": {
2443 "\u0647\u0645\u062C": {
2446 "\u0647\u0645\u0645": {
2449 "\u0646\u062D\u0645": {
2452 "\u0646\u062D\u0649": {
2455 "\u0646\u062C\u0645": {
2459 "\u0646\u062C\u0649": {
2462 "\u0646\u0645\u064A": {
2465 "\u0646\u0645\u0649": {
2468 "\u064A\u0645\u0645": {
2472 "\u0628\u062E\u064A": {
2475 "\u062A\u062C\u064A": {
2478 "\u062A\u062C\u0649": {
2481 "\u062A\u062E\u064A": {
2484 "\u062A\u062E\u0649": {
2487 "\u062A\u0645\u064A": {
2490 "\u062A\u0645\u0649": {
2493 "\u062C\u0645\u064A": {
2496 "\u062C\u062D\u0649": {
2499 "\u062C\u0645\u0649": {
2502 "\u0633\u062E\u0649": {
2505 "\u0635\u062D\u064A": {
2508 "\u0634\u062D\u064A": {
2511 "\u0636\u062D\u064A": {
2514 "\u0644\u062C\u064A": {
2517 "\u0644\u0645\u064A": {
2520 "\u064A\u062D\u064A": {
2523 "\u064A\u062C\u064A": {
2526 "\u064A\u0645\u064A": {
2529 "\u0645\u0645\u064A": {
2532 "\u0642\u0645\u064A": {
2535 "\u0646\u062D\u064A": {
2538 "\u0639\u0645\u064A": {
2541 "\u0643\u0645\u064A": {
2544 "\u0646\u062C\u062D": {
2545 "initial": "\uFDB8",
2548 "\u0645\u062E\u064A": {
2551 "\u0644\u062C\u0645": {
2552 "initial": "\uFDBA",
2555 "\u0643\u0645\u0645": {
2559 "\u062C\u062D\u064A": {
2562 "\u062D\u062C\u064A": {
2565 "\u0645\u062C\u064A": {
2568 "\u0641\u0645\u064A": {
2571 "\u0628\u062D\u064A": {
2574 "\u0633\u062E\u064A": {
2577 "\u0646\u062C\u064A": {
2581 "isolated": "\uFEF5",
2585 "isolated": "\uFEF7",
2589 "isolated": "\uFEF9",
2593 "isolated": "\uFEFB",
2597 "\u0635\u0644\u06D2": "\uFDF0",
2598 "\u0642\u0644\u06D2": "\uFDF1",
2599 "\u0627\u0644\u0644\u0647": "\uFDF2",
2600 "\u0627\u0643\u0628\u0631": "\uFDF3",
2601 "\u0645\u062D\u0645\u062F": "\uFDF4",
2602 "\u0635\u0644\u0639\u0645": "\uFDF5",
2603 "\u0631\u0633\u0648\u0644": "\uFDF6",
2604 "\u0639\u0644\u064A\u0647": "\uFDF7",
2605 "\u0648\u0633\u0644\u0645": "\uFDF8",
2606 "\u0635\u0644\u0649": "\uFDF9",
2607 "\u0635\u0644\u0649\u0627\u0644\u0644\u0647\u0639\u0644\u064A\u0647\u0648\u0633\u0644\u0645": "\uFDFA",
2608 "\u062C\u0644\u062C\u0644\u0627\u0644\u0647": "\uFDFB",
2609 "\u0631\u06CC\u0627\u0644": "\uFDFC"
2612 exports2.default = ligatureReference;
2616 // node_modules/alif-toolkit/lib/reference.js
2617 var require_reference = __commonJS({
2618 "node_modules/alif-toolkit/lib/reference.js"(exports2) {
2620 Object.defineProperty(exports2, "__esModule", { value: true });
2621 var unicode_arabic_1 = require_unicode_arabic();
2622 var unicode_ligatures_1 = require_unicode_ligatures();
2623 var letterList = Object.keys(unicode_arabic_1.default);
2624 exports2.letterList = letterList;
2625 var ligatureList = Object.keys(unicode_ligatures_1.default);
2626 exports2.ligatureList = ligatureList;
2627 var ligatureWordList = Object.keys(unicode_ligatures_1.default.words);
2628 exports2.ligatureWordList = ligatureWordList;
2629 var lams = "\u0644\u06B5\u06B6\u06B7\u06B8";
2630 exports2.lams = lams;
2631 var alefs = "\u0627\u0622\u0623\u0625\u0671\u0672\u0673\u0675\u0773\u0774";
2632 exports2.alefs = alefs;
2633 var tashkeel = "\u0605\u0640\u0670\u0674\u06DF\u06E7\u06E8";
2634 exports2.tashkeel = tashkeel;
2635 function addToTashkeel(start2, finish) {
2636 for (var i2 = start2; i2 <= finish; i2++) {
2637 exports2.tashkeel = tashkeel += String.fromCharCode(i2);
2640 addToTashkeel(1552, 1562);
2641 addToTashkeel(1611, 1631);
2642 addToTashkeel(1750, 1756);
2643 addToTashkeel(1760, 1764);
2644 addToTashkeel(1770, 1773);
2645 addToTashkeel(2259, 2273);
2646 addToTashkeel(2275, 2303);
2647 addToTashkeel(65136, 65151);
2648 var lineBreakers = "\u0627\u0629\u0648\u06C0\u06CF\u06FD\u06FE\u076B\u076C\u0771\u0773\u0774\u0778\u0779\u08E2\u08B1\u08B2\u08B9";
2649 exports2.lineBreakers = lineBreakers;
2650 function addToLineBreakers(start2, finish) {
2651 for (var i2 = start2; i2 <= finish; i2++) {
2652 exports2.lineBreakers = lineBreakers += String.fromCharCode(i2);
2655 addToLineBreakers(1536, 1567);
2656 addToLineBreakers(1569, 1573);
2657 addToLineBreakers(1583, 1586);
2658 addToLineBreakers(1632, 1645);
2659 addToLineBreakers(1649, 1655);
2660 addToLineBreakers(1672, 1689);
2661 addToLineBreakers(1731, 1739);
2662 addToLineBreakers(1746, 1785);
2663 addToLineBreakers(1881, 1883);
2664 addToLineBreakers(2218, 2222);
2665 addToLineBreakers(64336, 65021);
2666 addToLineBreakers(65152, 65276);
2667 addToLineBreakers(69216, 69247);
2668 addToLineBreakers(126064, 126143);
2669 addToLineBreakers(126464, 126719);
2673 // node_modules/alif-toolkit/lib/GlyphSplitter.js
2674 var require_GlyphSplitter = __commonJS({
2675 "node_modules/alif-toolkit/lib/GlyphSplitter.js"(exports2) {
2677 Object.defineProperty(exports2, "__esModule", { value: true });
2678 var isArabic_1 = require_isArabic();
2679 var reference_1 = require_reference();
2680 function GlyphSplitter(word) {
2682 let lastLetter = "";
2683 word.split("").forEach((letter) => {
2684 if (isArabic_1.isArabic(letter)) {
2685 if (reference_1.tashkeel.indexOf(letter) > -1) {
2686 letters[letters.length - 1] += letter;
2687 } else if (lastLetter.length && (reference_1.lams.indexOf(lastLetter) === 0 && reference_1.alefs.indexOf(letter) > -1 || reference_1.lams.indexOf(lastLetter) > 0 && reference_1.alefs.indexOf(letter) === 0)) {
2688 letters[letters.length - 1] += letter;
2690 letters.push(letter);
2693 letters.push(letter);
2695 if (reference_1.tashkeel.indexOf(letter) === -1) {
2696 lastLetter = letter;
2701 exports2.GlyphSplitter = GlyphSplitter;
2705 // node_modules/alif-toolkit/lib/BaselineSplitter.js
2706 var require_BaselineSplitter = __commonJS({
2707 "node_modules/alif-toolkit/lib/BaselineSplitter.js"(exports2) {
2709 Object.defineProperty(exports2, "__esModule", { value: true });
2710 var isArabic_1 = require_isArabic();
2711 var reference_1 = require_reference();
2712 function BaselineSplitter(word) {
2714 let lastLetter = "";
2715 word.split("").forEach((letter) => {
2716 if (isArabic_1.isArabic(letter) && isArabic_1.isArabic(lastLetter)) {
2717 if (lastLetter.length && reference_1.tashkeel.indexOf(letter) > -1) {
2718 letters[letters.length - 1] += letter;
2719 } else if (reference_1.lineBreakers.indexOf(lastLetter) > -1) {
2720 letters.push(letter);
2722 letters[letters.length - 1] += letter;
2725 letters.push(letter);
2727 if (reference_1.tashkeel.indexOf(letter) === -1) {
2728 lastLetter = letter;
2733 exports2.BaselineSplitter = BaselineSplitter;
2737 // node_modules/alif-toolkit/lib/Normalization.js
2738 var require_Normalization = __commonJS({
2739 "node_modules/alif-toolkit/lib/Normalization.js"(exports2) {
2741 Object.defineProperty(exports2, "__esModule", { value: true });
2742 var unicode_arabic_1 = require_unicode_arabic();
2743 var unicode_ligatures_1 = require_unicode_ligatures();
2744 var isArabic_1 = require_isArabic();
2745 var reference_1 = require_reference();
2746 function Normal(word, breakPresentationForm) {
2747 if (typeof breakPresentationForm === "undefined") {
2748 breakPresentationForm = true;
2750 let returnable = "";
2751 word.split("").forEach((letter) => {
2752 if (!isArabic_1.isArabic(letter)) {
2753 returnable += letter;
2756 for (let w = 0; w < reference_1.letterList.length; w++) {
2757 let letterForms = unicode_arabic_1.default[reference_1.letterList[w]];
2758 let versions = Object.keys(letterForms);
2759 for (let v = 0; v < versions.length; v++) {
2760 let localVersion = letterForms[versions[v]];
2761 if (typeof localVersion === "object" && typeof localVersion.indexOf === "undefined") {
2762 let embeddedForms = Object.keys(localVersion);
2763 for (let ef = 0; ef < embeddedForms.length; ef++) {
2764 let form = localVersion[embeddedForms[ef]];
2765 if (form === letter || typeof form === "object" && form.indexOf && form.indexOf(letter) > -1) {
2766 if (form === letter) {
2767 if (breakPresentationForm && localVersion["normal"] && ["isolated", "initial", "medial", "final"].indexOf(embeddedForms[ef]) > -1) {
2768 if (typeof localVersion["normal"] === "object") {
2769 returnable += localVersion["normal"][0];
2771 returnable += localVersion["normal"];
2775 returnable += letter;
2777 } else if (typeof form === "object" && form.indexOf && form.indexOf(letter) > -1) {
2778 returnable += form[0];
2783 } else if (localVersion === letter) {
2784 if (breakPresentationForm && letterForms["normal"] && ["isolated", "initial", "medial", "final"].indexOf(versions[v]) > -1) {
2785 if (typeof letterForms["normal"] === "object") {
2786 returnable += letterForms["normal"][0];
2788 returnable += letterForms["normal"];
2792 returnable += letter;
2794 } else if (typeof localVersion === "object" && localVersion.indexOf && localVersion.indexOf(letter) > -1) {
2795 returnable += localVersion[0];
2800 for (let v2 = 0; v2 < reference_1.ligatureList.length; v2++) {
2801 let normalForm = reference_1.ligatureList[v2];
2802 if (normalForm !== "words") {
2803 let ligForms = Object.keys(unicode_ligatures_1.default[normalForm]);
2804 for (let f2 = 0; f2 < ligForms.length; f2++) {
2805 if (unicode_ligatures_1.default[normalForm][ligForms[f2]] === letter) {
2806 returnable += normalForm;
2812 for (let v3 = 0; v3 < reference_1.ligatureWordList.length; v3++) {
2813 let normalForm = reference_1.ligatureWordList[v3];
2814 if (unicode_ligatures_1.default.words[normalForm] === letter) {
2815 returnable += normalForm;
2819 returnable += letter;
2823 exports2.Normal = Normal;
2827 // node_modules/alif-toolkit/lib/CharShaper.js
2828 var require_CharShaper = __commonJS({
2829 "node_modules/alif-toolkit/lib/CharShaper.js"(exports2) {
2831 Object.defineProperty(exports2, "__esModule", { value: true });
2832 var unicode_arabic_1 = require_unicode_arabic();
2833 var isArabic_1 = require_isArabic();
2834 var reference_1 = require_reference();
2835 function CharShaper(letter, form) {
2836 if (!isArabic_1.isArabic(letter)) {
2837 throw new Error("Not Arabic");
2839 if (letter === "\u0621") {
2842 for (let w = 0; w < reference_1.letterList.length; w++) {
2843 let letterForms = unicode_arabic_1.default[reference_1.letterList[w]];
2844 let versions = Object.keys(letterForms);
2845 for (let v = 0; v < versions.length; v++) {
2846 let localVersion = letterForms[versions[v]];
2847 if (localVersion === letter || typeof localVersion === "object" && localVersion.indexOf && localVersion.indexOf(letter) > -1) {
2848 if (versions.indexOf(form) > -1) {
2849 return letterForms[form];
2851 } else if (typeof localVersion === "object" && typeof localVersion.indexOf === "undefined") {
2852 let embeddedVersions = Object.keys(localVersion);
2853 for (let ev = 0; ev < embeddedVersions.length; ev++) {
2854 if (localVersion[embeddedVersions[ev]] === letter || typeof localVersion[embeddedVersions[ev]] === "object" && localVersion[embeddedVersions[ev]].indexOf && localVersion[embeddedVersions[ev]].indexOf(letter) > -1) {
2855 if (embeddedVersions.indexOf(form) > -1) {
2856 return localVersion[form];
2864 exports2.CharShaper = CharShaper;
2868 // node_modules/alif-toolkit/lib/WordShaper.js
2869 var require_WordShaper = __commonJS({
2870 "node_modules/alif-toolkit/lib/WordShaper.js"(exports2) {
2872 Object.defineProperty(exports2, "__esModule", { value: true });
2873 var isArabic_1 = require_isArabic();
2874 var reference_1 = require_reference();
2875 var CharShaper_1 = require_CharShaper();
2876 var unicode_ligatures_1 = require_unicode_ligatures();
2877 function WordShaper2(word) {
2878 let state = "initial";
2880 for (let w = 0; w < word.length; w++) {
2881 let nextLetter = " ";
2882 for (let nxw = w + 1; nxw < word.length; nxw++) {
2883 if (!isArabic_1.isArabic(word[nxw])) {
2886 if (reference_1.tashkeel.indexOf(word[nxw]) === -1) {
2887 nextLetter = word[nxw];
2891 if (!isArabic_1.isArabic(word[w]) || isArabic_1.isMath(word[w])) {
2894 } else if (reference_1.tashkeel.indexOf(word[w]) > -1) {
2896 } else if (nextLetter === " " || reference_1.lineBreakers.indexOf(word[w]) > -1) {
2897 output += CharShaper_1.CharShaper(word[w], state === "initial" ? "isolated" : "final");
2899 } else if (reference_1.lams.indexOf(word[w]) > -1 && reference_1.alefs.indexOf(nextLetter) > -1) {
2900 output += unicode_ligatures_1.default[word[w] + nextLetter][state === "initial" ? "isolated" : "final"];
2901 while (word[w] !== nextLetter) {
2906 output += CharShaper_1.CharShaper(word[w], state);
2912 exports2.WordShaper = WordShaper2;
2916 // node_modules/alif-toolkit/lib/ParentLetter.js
2917 var require_ParentLetter = __commonJS({
2918 "node_modules/alif-toolkit/lib/ParentLetter.js"(exports2) {
2920 Object.defineProperty(exports2, "__esModule", { value: true });
2921 var unicode_arabic_1 = require_unicode_arabic();
2922 var isArabic_1 = require_isArabic();
2923 var reference_1 = require_reference();
2924 function ParentLetter(letter) {
2925 if (!isArabic_1.isArabic(letter)) {
2926 throw new Error("Not an Arabic letter");
2928 for (let w = 0; w < reference_1.letterList.length; w++) {
2929 let letterForms = unicode_arabic_1.default[reference_1.letterList[w]];
2930 let versions = Object.keys(letterForms);
2931 for (let v = 0; v < versions.length; v++) {
2932 let localVersion = letterForms[versions[v]];
2933 if (typeof localVersion === "object" && typeof localVersion.indexOf === "undefined") {
2934 let embeddedForms = Object.keys(localVersion);
2935 for (let ef = 0; ef < embeddedForms.length; ef++) {
2936 let form = localVersion[embeddedForms[ef]];
2937 if (form === letter || typeof form === "object" && form.indexOf && form.indexOf(letter) > -1) {
2938 return localVersion;
2941 } else if (localVersion === letter || typeof localVersion === "object" && localVersion.indexOf && localVersion.indexOf(letter) > -1) {
2948 exports2.ParentLetter = ParentLetter;
2949 function GrandparentLetter(letter) {
2950 if (!isArabic_1.isArabic(letter)) {
2951 throw new Error("Not an Arabic letter");
2953 for (let w = 0; w < reference_1.letterList.length; w++) {
2954 let letterForms = unicode_arabic_1.default[reference_1.letterList[w]];
2955 let versions = Object.keys(letterForms);
2956 for (let v = 0; v < versions.length; v++) {
2957 let localVersion = letterForms[versions[v]];
2958 if (typeof localVersion === "object" && typeof localVersion.indexOf === "undefined") {
2959 let embeddedForms = Object.keys(localVersion);
2960 for (let ef = 0; ef < embeddedForms.length; ef++) {
2961 let form = localVersion[embeddedForms[ef]];
2962 if (form === letter || typeof form === "object" && form.indexOf && form.indexOf(letter) > -1) {
2966 } else if (localVersion === letter || typeof localVersion === "object" && localVersion.indexOf && localVersion.indexOf(letter) > -1) {
2973 exports2.GrandparentLetter = GrandparentLetter;
2977 // node_modules/alif-toolkit/lib/index.js
2978 var require_lib = __commonJS({
2979 "node_modules/alif-toolkit/lib/index.js"(exports2) {
2981 Object.defineProperty(exports2, "__esModule", { value: true });
2982 var isArabic_1 = require_isArabic();
2983 exports2.isArabic = isArabic_1.isArabic;
2984 var GlyphSplitter_1 = require_GlyphSplitter();
2985 exports2.GlyphSplitter = GlyphSplitter_1.GlyphSplitter;
2986 var BaselineSplitter_1 = require_BaselineSplitter();
2987 exports2.BaselineSplitter = BaselineSplitter_1.BaselineSplitter;
2988 var Normalization_1 = require_Normalization();
2989 exports2.Normal = Normalization_1.Normal;
2990 var CharShaper_1 = require_CharShaper();
2991 exports2.CharShaper = CharShaper_1.CharShaper;
2992 var WordShaper_1 = require_WordShaper();
2993 exports2.WordShaper = WordShaper_1.WordShaper;
2994 var ParentLetter_1 = require_ParentLetter();
2995 exports2.ParentLetter = ParentLetter_1.ParentLetter;
2996 exports2.GrandparentLetter = ParentLetter_1.GrandparentLetter;
3000 // node_modules/vparse/index.js
3001 var require_vparse = __commonJS({
3002 "node_modules/vparse/index.js"(exports2, module2) {
3003 (function(window2) {
3005 function parseVersion3(v) {
3006 var m = v.replace(/[^0-9.]/g, "").match(/[0-9]*\.|[0-9]+/g) || [];
3013 v.isEmpty = !v.major && !v.minor && !v.patch && !v.build;
3014 v.parsed = [v.major, v.minor, v.patch, v.build];
3015 v.text = v.parsed.join(".");
3016 v.compare = compare;
3019 function compare(v) {
3020 if (typeof v === "string") {
3021 v = parseVersion3(v);
3023 for (var i2 = 0; i2 < 4; i2++) {
3024 if (this.parsed[i2] !== v.parsed[i2]) {
3025 return this.parsed[i2] > v.parsed[i2] ? 1 : -1;
3030 if (typeof module2 === "object" && module2 && typeof module2.exports === "object") {
3031 module2.exports = parseVersion3;
3033 window2.parseVersion = parseVersion3;
3039 // node_modules/which-polygon/node_modules/quickselect/quickselect.js
3040 var require_quickselect = __commonJS({
3041 "node_modules/which-polygon/node_modules/quickselect/quickselect.js"(exports2, module2) {
3042 (function(global3, factory) {
3043 typeof exports2 === "object" && typeof module2 !== "undefined" ? module2.exports = factory() : typeof define === "function" && define.amd ? define(factory) : global3.quickselect = factory();
3044 })(exports2, function() {
3046 function quickselect2(arr, k, left, right, compare) {
3047 quickselectStep(arr, k, left || 0, right || arr.length - 1, compare || defaultCompare);
3049 function quickselectStep(arr, k, left, right, compare) {
3050 while (right > left) {
3051 if (right - left > 600) {
3052 var n2 = right - left + 1;
3053 var m = k - left + 1;
3054 var z = Math.log(n2);
3055 var s = 0.5 * Math.exp(2 * z / 3);
3056 var sd = 0.5 * Math.sqrt(z * s * (n2 - s) / n2) * (m - n2 / 2 < 0 ? -1 : 1);
3057 var newLeft = Math.max(left, Math.floor(k - m * s / n2 + sd));
3058 var newRight = Math.min(right, Math.floor(k + (n2 - m) * s / n2 + sd));
3059 quickselectStep(arr, k, newLeft, newRight, compare);
3064 swap2(arr, left, k);
3065 if (compare(arr[right], t) > 0)
3066 swap2(arr, left, right);
3071 while (compare(arr[i2], t) < 0)
3073 while (compare(arr[j2], t) > 0)
3076 if (compare(arr[left], t) === 0)
3077 swap2(arr, left, j2);
3080 swap2(arr, j2, right);
3088 function swap2(arr, i2, j2) {
3093 function defaultCompare(a, b) {
3094 return a < b ? -1 : a > b ? 1 : 0;
3096 return quickselect2;
3101 // node_modules/which-polygon/node_modules/rbush/index.js
3102 var require_rbush = __commonJS({
3103 "node_modules/which-polygon/node_modules/rbush/index.js"(exports2, module2) {
3105 module2.exports = rbush;
3106 module2.exports.default = rbush;
3107 var quickselect2 = require_quickselect();
3108 function rbush(maxEntries, format2) {
3109 if (!(this instanceof rbush))
3110 return new rbush(maxEntries, format2);
3111 this._maxEntries = Math.max(4, maxEntries || 9);
3112 this._minEntries = Math.max(2, Math.ceil(this._maxEntries * 0.4));
3114 this._initFormat(format2);
3120 return this._all(this.data, []);
3122 search: function(bbox2) {
3123 var node = this.data, result = [], toBBox = this.toBBox;
3124 if (!intersects(bbox2, node))
3126 var nodesToSearch = [], i2, len, child, childBBox;
3128 for (i2 = 0, len = node.children.length; i2 < len; i2++) {
3129 child = node.children[i2];
3130 childBBox = node.leaf ? toBBox(child) : child;
3131 if (intersects(bbox2, childBBox)) {
3134 else if (contains(bbox2, childBBox))
3135 this._all(child, result);
3137 nodesToSearch.push(child);
3140 node = nodesToSearch.pop();
3144 collides: function(bbox2) {
3145 var node = this.data, toBBox = this.toBBox;
3146 if (!intersects(bbox2, node))
3148 var nodesToSearch = [], i2, len, child, childBBox;
3150 for (i2 = 0, len = node.children.length; i2 < len; i2++) {
3151 child = node.children[i2];
3152 childBBox = node.leaf ? toBBox(child) : child;
3153 if (intersects(bbox2, childBBox)) {
3154 if (node.leaf || contains(bbox2, childBBox))
3156 nodesToSearch.push(child);
3159 node = nodesToSearch.pop();
3163 load: function(data) {
3164 if (!(data && data.length))
3166 if (data.length < this._minEntries) {
3167 for (var i2 = 0, len = data.length; i2 < len; i2++) {
3168 this.insert(data[i2]);
3172 var node = this._build(data.slice(), 0, data.length - 1, 0);
3173 if (!this.data.children.length) {
3175 } else if (this.data.height === node.height) {
3176 this._splitRoot(this.data, node);
3178 if (this.data.height < node.height) {
3179 var tmpNode = this.data;
3183 this._insert(node, this.data.height - node.height - 1, true);
3187 insert: function(item) {
3189 this._insert(item, this.data.height - 1);
3193 this.data = createNode([]);
3196 remove: function(item, equalsFn) {
3199 var node = this.data, bbox2 = this.toBBox(item), path = [], indexes = [], i2, parent, index, goingUp;
3200 while (node || path.length) {
3203 parent = path[path.length - 1];
3208 index = findItem(item, node.children, equalsFn);
3210 node.children.splice(index, 1);
3212 this._condense(path);
3216 if (!goingUp && !node.leaf && contains(node, bbox2)) {
3221 node = node.children[0];
3222 } else if (parent) {
3224 node = parent.children[i2];
3231 toBBox: function(item) {
3234 compareMinX: compareNodeMinX,
3235 compareMinY: compareNodeMinY,
3236 toJSON: function() {
3239 fromJSON: function(data) {
3243 _all: function(node, result) {
3244 var nodesToSearch = [];
3247 result.push.apply(result, node.children);
3249 nodesToSearch.push.apply(nodesToSearch, node.children);
3250 node = nodesToSearch.pop();
3254 _build: function(items, left, right, height) {
3255 var N = right - left + 1, M = this._maxEntries, node;
3257 node = createNode(items.slice(left, right + 1));
3258 calcBBox(node, this.toBBox);
3262 height = Math.ceil(Math.log(N) / Math.log(M));
3263 M = Math.ceil(N / Math.pow(M, height - 1));
3265 node = createNode([]);
3267 node.height = height;
3268 var N2 = Math.ceil(N / M), N1 = N2 * Math.ceil(Math.sqrt(M)), i2, j2, right2, right3;
3269 multiSelect(items, left, right, N1, this.compareMinX);
3270 for (i2 = left; i2 <= right; i2 += N1) {
3271 right2 = Math.min(i2 + N1 - 1, right);
3272 multiSelect(items, i2, right2, N2, this.compareMinY);
3273 for (j2 = i2; j2 <= right2; j2 += N2) {
3274 right3 = Math.min(j2 + N2 - 1, right2);
3275 node.children.push(this._build(items, j2, right3, height - 1));
3278 calcBBox(node, this.toBBox);
3281 _chooseSubtree: function(bbox2, node, level, path) {
3282 var i2, len, child, targetNode, area, enlargement, minArea, minEnlargement;
3285 if (node.leaf || path.length - 1 === level)
3287 minArea = minEnlargement = Infinity;
3288 for (i2 = 0, len = node.children.length; i2 < len; i2++) {
3289 child = node.children[i2];
3290 area = bboxArea(child);
3291 enlargement = enlargedArea(bbox2, child) - area;
3292 if (enlargement < minEnlargement) {
3293 minEnlargement = enlargement;
3294 minArea = area < minArea ? area : minArea;
3296 } else if (enlargement === minEnlargement) {
3297 if (area < minArea) {
3303 node = targetNode || node.children[0];
3307 _insert: function(item, level, isNode) {
3308 var toBBox = this.toBBox, bbox2 = isNode ? item : toBBox(item), insertPath = [];
3309 var node = this._chooseSubtree(bbox2, this.data, level, insertPath);
3310 node.children.push(item);
3311 extend2(node, bbox2);
3312 while (level >= 0) {
3313 if (insertPath[level].children.length > this._maxEntries) {
3314 this._split(insertPath, level);
3319 this._adjustParentBBoxes(bbox2, insertPath, level);
3321 // split overflowed node into two
3322 _split: function(insertPath, level) {
3323 var node = insertPath[level], M = node.children.length, m = this._minEntries;
3324 this._chooseSplitAxis(node, m, M);
3325 var splitIndex = this._chooseSplitIndex(node, m, M);
3326 var newNode = createNode(node.children.splice(splitIndex, node.children.length - splitIndex));
3327 newNode.height = node.height;
3328 newNode.leaf = node.leaf;
3329 calcBBox(node, this.toBBox);
3330 calcBBox(newNode, this.toBBox);
3332 insertPath[level - 1].children.push(newNode);
3334 this._splitRoot(node, newNode);
3336 _splitRoot: function(node, newNode) {
3337 this.data = createNode([node, newNode]);
3338 this.data.height = node.height + 1;
3339 this.data.leaf = false;
3340 calcBBox(this.data, this.toBBox);
3342 _chooseSplitIndex: function(node, m, M) {
3343 var i2, bbox1, bbox2, overlap, area, minOverlap, minArea, index;
3344 minOverlap = minArea = Infinity;
3345 for (i2 = m; i2 <= M - m; i2++) {
3346 bbox1 = distBBox(node, 0, i2, this.toBBox);
3347 bbox2 = distBBox(node, i2, M, this.toBBox);
3348 overlap = intersectionArea(bbox1, bbox2);
3349 area = bboxArea(bbox1) + bboxArea(bbox2);
3350 if (overlap < minOverlap) {
3351 minOverlap = overlap;
3353 minArea = area < minArea ? area : minArea;
3354 } else if (overlap === minOverlap) {
3355 if (area < minArea) {
3363 // sorts node children by the best axis for split
3364 _chooseSplitAxis: function(node, m, M) {
3365 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);
3366 if (xMargin < yMargin)
3367 node.children.sort(compareMinX);
3369 // total margin of all possible split distributions where each node is at least m full
3370 _allDistMargin: function(node, m, M, compare) {
3371 node.children.sort(compare);
3372 var toBBox = this.toBBox, leftBBox = distBBox(node, 0, m, toBBox), rightBBox = distBBox(node, M - m, M, toBBox), margin = bboxMargin(leftBBox) + bboxMargin(rightBBox), i2, child;
3373 for (i2 = m; i2 < M - m; i2++) {
3374 child = node.children[i2];
3375 extend2(leftBBox, node.leaf ? toBBox(child) : child);
3376 margin += bboxMargin(leftBBox);
3378 for (i2 = M - m - 1; i2 >= m; i2--) {
3379 child = node.children[i2];
3380 extend2(rightBBox, node.leaf ? toBBox(child) : child);
3381 margin += bboxMargin(rightBBox);
3385 _adjustParentBBoxes: function(bbox2, path, level) {
3386 for (var i2 = level; i2 >= 0; i2--) {
3387 extend2(path[i2], bbox2);
3390 _condense: function(path) {
3391 for (var i2 = path.length - 1, siblings; i2 >= 0; i2--) {
3392 if (path[i2].children.length === 0) {
3394 siblings = path[i2 - 1].children;
3395 siblings.splice(siblings.indexOf(path[i2]), 1);
3399 calcBBox(path[i2], this.toBBox);
3402 _initFormat: function(format2) {
3403 var compareArr = ["return a", " - b", ";"];
3404 this.compareMinX = new Function("a", "b", compareArr.join(format2[0]));
3405 this.compareMinY = new Function("a", "b", compareArr.join(format2[1]));
3406 this.toBBox = new Function(
3408 "return {minX: a" + format2[0] + ", minY: a" + format2[1] + ", maxX: a" + format2[2] + ", maxY: a" + format2[3] + "};"
3412 function findItem(item, items, equalsFn) {
3414 return items.indexOf(item);
3415 for (var i2 = 0; i2 < items.length; i2++) {
3416 if (equalsFn(item, items[i2]))
3421 function calcBBox(node, toBBox) {
3422 distBBox(node, 0, node.children.length, toBBox, node);
3424 function distBBox(node, k, p, toBBox, destNode) {
3426 destNode = createNode(null);
3427 destNode.minX = Infinity;
3428 destNode.minY = Infinity;
3429 destNode.maxX = -Infinity;
3430 destNode.maxY = -Infinity;
3431 for (var i2 = k, child; i2 < p; i2++) {
3432 child = node.children[i2];
3433 extend2(destNode, node.leaf ? toBBox(child) : child);
3437 function extend2(a, b) {
3438 a.minX = Math.min(a.minX, b.minX);
3439 a.minY = Math.min(a.minY, b.minY);
3440 a.maxX = Math.max(a.maxX, b.maxX);
3441 a.maxY = Math.max(a.maxY, b.maxY);
3444 function compareNodeMinX(a, b) {
3445 return a.minX - b.minX;
3447 function compareNodeMinY(a, b) {
3448 return a.minY - b.minY;
3450 function bboxArea(a) {
3451 return (a.maxX - a.minX) * (a.maxY - a.minY);
3453 function bboxMargin(a) {
3454 return a.maxX - a.minX + (a.maxY - a.minY);
3456 function enlargedArea(a, b) {
3457 return (Math.max(b.maxX, a.maxX) - Math.min(b.minX, a.minX)) * (Math.max(b.maxY, a.maxY) - Math.min(b.minY, a.minY));
3459 function intersectionArea(a, b) {
3460 var minX = Math.max(a.minX, b.minX), minY = Math.max(a.minY, b.minY), maxX = Math.min(a.maxX, b.maxX), maxY = Math.min(a.maxY, b.maxY);
3461 return Math.max(0, maxX - minX) * Math.max(0, maxY - minY);
3463 function contains(a, b) {
3464 return a.minX <= b.minX && a.minY <= b.minY && b.maxX <= a.maxX && b.maxY <= a.maxY;
3466 function intersects(a, b) {
3467 return b.minX <= a.maxX && b.minY <= a.maxY && b.maxX >= a.minX && b.maxY >= a.minY;
3469 function createNode(children2) {
3471 children: children2,
3480 function multiSelect(arr, left, right, n2, compare) {
3481 var stack = [left, right], mid;
3482 while (stack.length) {
3483 right = stack.pop();
3485 if (right - left <= n2)
3487 mid = left + Math.ceil((right - left) / n2 / 2) * n2;
3488 quickselect2(arr, mid, left, right, compare);
3489 stack.push(left, mid, mid, right);
3495 // node_modules/lineclip/index.js
3496 var require_lineclip = __commonJS({
3497 "node_modules/lineclip/index.js"(exports2, module2) {
3499 module2.exports = lineclip2;
3500 lineclip2.polyline = lineclip2;
3501 lineclip2.polygon = polygonclip2;
3502 function lineclip2(points, bbox2, result) {
3503 var len = points.length, codeA = bitCode2(points[0], bbox2), part = [], i2, a, b, codeB, lastCode;
3506 for (i2 = 1; i2 < len; i2++) {
3509 codeB = lastCode = bitCode2(b, bbox2);
3511 if (!(codeA | codeB)) {
3513 if (codeB !== lastCode) {
3519 } else if (i2 === len - 1) {
3523 } else if (codeA & codeB) {
3526 a = intersect2(a, b, codeA, bbox2);
3527 codeA = bitCode2(a, bbox2);
3529 b = intersect2(a, b, codeB, bbox2);
3530 codeB = bitCode2(b, bbox2);
3539 function polygonclip2(points, bbox2) {
3540 var result, edge, prev, prevInside, i2, p, inside;
3541 for (edge = 1; edge <= 8; edge *= 2) {
3543 prev = points[points.length - 1];
3544 prevInside = !(bitCode2(prev, bbox2) & edge);
3545 for (i2 = 0; i2 < points.length; i2++) {
3547 inside = !(bitCode2(p, bbox2) & edge);
3548 if (inside !== prevInside)
3549 result.push(intersect2(prev, p, edge, bbox2));
3553 prevInside = inside;
3561 function intersect2(a, b, edge, bbox2) {
3562 return edge & 8 ? [a[0] + (b[0] - a[0]) * (bbox2[3] - a[1]) / (b[1] - a[1]), bbox2[3]] : (
3564 edge & 4 ? [a[0] + (b[0] - a[0]) * (bbox2[1] - a[1]) / (b[1] - a[1]), bbox2[1]] : (
3566 edge & 2 ? [bbox2[2], a[1] + (b[1] - a[1]) * (bbox2[2] - a[0]) / (b[0] - a[0])] : (
3568 edge & 1 ? [bbox2[0], a[1] + (b[1] - a[1]) * (bbox2[0] - a[0]) / (b[0] - a[0])] : (
3576 function bitCode2(p, bbox2) {
3578 if (p[0] < bbox2[0])
3580 else if (p[0] > bbox2[2])
3582 if (p[1] < bbox2[1])
3584 else if (p[1] > bbox2[3])
3591 // node_modules/which-polygon/index.js
3592 var require_which_polygon = __commonJS({
3593 "node_modules/which-polygon/index.js"(exports2, module2) {
3595 var rbush = require_rbush();
3596 var lineclip2 = require_lineclip();
3597 module2.exports = whichPolygon5;
3598 function whichPolygon5(data) {
3600 for (var i2 = 0; i2 < data.features.length; i2++) {
3601 var feature3 = data.features[i2];
3602 var coords = feature3.geometry.coordinates;
3603 if (feature3.geometry.type === "Polygon") {
3604 bboxes.push(treeItem(coords, feature3.properties));
3605 } else if (feature3.geometry.type === "MultiPolygon") {
3606 for (var j2 = 0; j2 < coords.length; j2++) {
3607 bboxes.push(treeItem(coords[j2], feature3.properties));
3611 var tree = rbush().load(bboxes);
3612 function query(p, multi) {
3613 var output = [], result = tree.search({
3619 for (var i3 = 0; i3 < result.length; i3++) {
3620 if (insidePolygon(result[i3].coords, p)) {
3622 output.push(result[i3].props);
3624 return result[i3].props;
3627 return multi && output.length ? output : null;
3630 query.bbox = function queryBBox(bbox2) {
3632 var result = tree.search({
3638 for (var i3 = 0; i3 < result.length; i3++) {
3639 if (polygonIntersectsBBox(result[i3].coords, bbox2)) {
3640 output.push(result[i3].props);
3647 function polygonIntersectsBBox(polygon2, bbox2) {
3649 (bbox2[0] + bbox2[2]) / 2,
3650 (bbox2[1] + bbox2[3]) / 2
3652 if (insidePolygon(polygon2, bboxCenter))
3654 for (var i2 = 0; i2 < polygon2.length; i2++) {
3655 if (lineclip2(polygon2[i2], bbox2).length > 0)
3660 function insidePolygon(rings, p) {
3662 for (var i2 = 0, len = rings.length; i2 < len; i2++) {
3663 var ring = rings[i2];
3664 for (var j2 = 0, len2 = ring.length, k = len2 - 1; j2 < len2; k = j2++) {
3665 if (rayIntersect(p, ring[j2], ring[k]))
3671 function rayIntersect(p, p1, p2) {
3672 return p1[1] > p[1] !== p2[1] > p[1] && p[0] < (p2[0] - p1[0]) * (p[1] - p1[1]) / (p2[1] - p1[1]) + p1[0];
3674 function treeItem(coords, props) {
3683 for (var i2 = 0; i2 < coords[0].length; i2++) {
3684 var p = coords[0][i2];
3685 item.minX = Math.min(item.minX, p[0]);
3686 item.minY = Math.min(item.minY, p[1]);
3687 item.maxX = Math.max(item.maxX, p[0]);
3688 item.maxY = Math.max(item.maxY, p[1]);
3695 // node_modules/wgs84/index.js
3696 var require_wgs84 = __commonJS({
3697 "node_modules/wgs84/index.js"(exports2, module2) {
3698 module2.exports.RADIUS = 6378137;
3699 module2.exports.FLATTENING = 1 / 298.257223563;
3700 module2.exports.POLAR_RADIUS = 63567523142e-4;
3704 // node_modules/@mapbox/geojson-area/index.js
3705 var require_geojson_area = __commonJS({
3706 "node_modules/@mapbox/geojson-area/index.js"(exports2, module2) {
3707 var wgs84 = require_wgs84();
3708 module2.exports.geometry = geometry;
3709 module2.exports.ring = ringArea;
3710 function geometry(_) {
3714 return polygonArea(_.coordinates);
3715 case "MultiPolygon":
3716 for (i2 = 0; i2 < _.coordinates.length; i2++) {
3717 area += polygonArea(_.coordinates[i2]);
3723 case "MultiLineString":
3725 case "GeometryCollection":
3726 for (i2 = 0; i2 < _.geometries.length; i2++) {
3727 area += geometry(_.geometries[i2]);
3732 function polygonArea(coords) {
3734 if (coords && coords.length > 0) {
3735 area += Math.abs(ringArea(coords[0]));
3736 for (var i2 = 1; i2 < coords.length; i2++) {
3737 area -= Math.abs(ringArea(coords[i2]));
3742 function ringArea(coords) {
3743 var p1, p2, p3, lowerIndex, middleIndex, upperIndex, i2, area = 0, coordsLength = coords.length;
3744 if (coordsLength > 2) {
3745 for (i2 = 0; i2 < coordsLength; i2++) {
3746 if (i2 === coordsLength - 2) {
3747 lowerIndex = coordsLength - 2;
3748 middleIndex = coordsLength - 1;
3750 } else if (i2 === coordsLength - 1) {
3751 lowerIndex = coordsLength - 1;
3756 middleIndex = i2 + 1;
3757 upperIndex = i2 + 2;
3759 p1 = coords[lowerIndex];
3760 p2 = coords[middleIndex];
3761 p3 = coords[upperIndex];
3762 area += (rad(p3[0]) - rad(p1[0])) * Math.sin(rad(p2[1]));
3764 area = area * wgs84.RADIUS * wgs84.RADIUS / 2;
3769 return _ * Math.PI / 180;
3774 // node_modules/circle-to-polygon/input-validation/validateCenter.js
3775 var require_validateCenter = __commonJS({
3776 "node_modules/circle-to-polygon/input-validation/validateCenter.js"(exports2) {
3777 exports2.validateCenter = function validateCenter(center) {
3778 var validCenterLengths = [2, 3];
3779 if (!Array.isArray(center) || !validCenterLengths.includes(center.length)) {
3780 throw new Error("ERROR! Center has to be an array of length two or three");
3782 var [lng, lat] = center;
3783 if (typeof lng !== "number" || typeof lat !== "number") {
3785 `ERROR! Longitude and Latitude has to be numbers but where ${typeof lng} and ${typeof lat}`
3788 if (lng > 180 || lng < -180) {
3789 throw new Error(`ERROR! Longitude has to be between -180 and 180 but was ${lng}`);
3791 if (lat > 90 || lat < -90) {
3792 throw new Error(`ERROR! Latitude has to be between -90 and 90 but was ${lat}`);
3798 // node_modules/circle-to-polygon/input-validation/validateRadius.js
3799 var require_validateRadius = __commonJS({
3800 "node_modules/circle-to-polygon/input-validation/validateRadius.js"(exports2) {
3801 exports2.validateRadius = function validateRadius(radius) {
3802 if (typeof radius !== "number") {
3803 throw new Error(`ERROR! Radius has to be a positive number but was: ${typeof radius}`);
3806 throw new Error(`ERROR! Radius has to be a positive number but was: ${radius}`);
3812 // node_modules/circle-to-polygon/input-validation/validateNumberOfEdges.js
3813 var require_validateNumberOfEdges = __commonJS({
3814 "node_modules/circle-to-polygon/input-validation/validateNumberOfEdges.js"(exports2) {
3815 exports2.validateNumberOfEdges = function validateNumberOfEdges(numberOfEdges) {
3816 if (typeof numberOfEdges !== "number") {
3817 const ARGUMENT_TYPE = Array.isArray(numberOfEdges) ? "array" : typeof numberOfEdges;
3818 throw new Error(`ERROR! Number of edges has to be a number but was: ${ARGUMENT_TYPE}`);
3820 if (numberOfEdges < 3) {
3821 throw new Error(`ERROR! Number of edges has to be at least 3 but was: ${numberOfEdges}`);
3827 // node_modules/circle-to-polygon/input-validation/validateEarthRadius.js
3828 var require_validateEarthRadius = __commonJS({
3829 "node_modules/circle-to-polygon/input-validation/validateEarthRadius.js"(exports2) {
3830 exports2.validateEarthRadius = function validateEarthRadius(earthRadius2) {
3831 if (typeof earthRadius2 !== "number") {
3832 const ARGUMENT_TYPE = Array.isArray(earthRadius2) ? "array" : typeof earthRadius2;
3833 throw new Error(`ERROR! Earth radius has to be a number but was: ${ARGUMENT_TYPE}`);
3835 if (earthRadius2 <= 0) {
3836 throw new Error(`ERROR! Earth radius has to be a positive number but was: ${earthRadius2}`);
3842 // node_modules/circle-to-polygon/input-validation/validateBearing.js
3843 var require_validateBearing = __commonJS({
3844 "node_modules/circle-to-polygon/input-validation/validateBearing.js"(exports2) {
3845 exports2.validateBearing = function validateBearing(bearing) {
3846 if (typeof bearing !== "number") {
3847 const ARGUMENT_TYPE = Array.isArray(bearing) ? "array" : typeof bearing;
3848 throw new Error(`ERROR! Bearing has to be a number but was: ${ARGUMENT_TYPE}`);
3854 // node_modules/circle-to-polygon/input-validation/index.js
3855 var require_input_validation = __commonJS({
3856 "node_modules/circle-to-polygon/input-validation/index.js"(exports2) {
3857 var validateCenter = require_validateCenter().validateCenter;
3858 var validateRadius = require_validateRadius().validateRadius;
3859 var validateNumberOfEdges = require_validateNumberOfEdges().validateNumberOfEdges;
3860 var validateEarthRadius = require_validateEarthRadius().validateEarthRadius;
3861 var validateBearing = require_validateBearing().validateBearing;
3862 function validateInput({ center, radius, numberOfEdges, earthRadius: earthRadius2, bearing }) {
3863 validateCenter(center);
3864 validateRadius(radius);
3865 validateNumberOfEdges(numberOfEdges);
3866 validateEarthRadius(earthRadius2);
3867 validateBearing(bearing);
3869 exports2.validateCenter = validateCenter;
3870 exports2.validateRadius = validateRadius;
3871 exports2.validateNumberOfEdges = validateNumberOfEdges;
3872 exports2.validateEarthRadius = validateEarthRadius;
3873 exports2.validateBearing = validateBearing;
3874 exports2.validateInput = validateInput;
3878 // node_modules/circle-to-polygon/index.js
3879 var require_circle_to_polygon = __commonJS({
3880 "node_modules/circle-to-polygon/index.js"(exports2, module2) {
3882 var { validateInput } = require_input_validation();
3883 var defaultEarthRadius = 6378137;
3884 function toRadians(angleInDegrees) {
3885 return angleInDegrees * Math.PI / 180;
3887 function toDegrees(angleInRadians) {
3888 return angleInRadians * 180 / Math.PI;
3890 function offset(c1, distance, earthRadius2, bearing) {
3891 var lat1 = toRadians(c1[1]);
3892 var lon1 = toRadians(c1[0]);
3893 var dByR = distance / earthRadius2;
3894 var lat = Math.asin(
3895 Math.sin(lat1) * Math.cos(dByR) + Math.cos(lat1) * Math.sin(dByR) * Math.cos(bearing)
3897 var lon = lon1 + Math.atan2(
3898 Math.sin(bearing) * Math.sin(dByR) * Math.cos(lat1),
3899 Math.cos(dByR) - Math.sin(lat1) * Math.sin(lat)
3901 return [toDegrees(lon), toDegrees(lat)];
3903 module2.exports = function circleToPolygon2(center, radius, options2) {
3904 var n2 = getNumberOfEdges(options2);
3905 var earthRadius2 = getEarthRadius(options2);
3906 var bearing = getBearing(options2);
3907 var direction = getDirection(options2);
3908 validateInput({ center, radius, numberOfEdges: n2, earthRadius: earthRadius2, bearing });
3909 var start2 = toRadians(bearing);
3910 var coordinates = [];
3911 for (var i2 = 0; i2 < n2; ++i2) {
3917 start2 + direction * 2 * Math.PI * -i2 / n2
3921 coordinates.push(coordinates[0]);
3924 coordinates: [coordinates]
3927 function getNumberOfEdges(options2) {
3928 if (isUndefinedOrNull(options2)) {
3930 } else if (isObjectNotArray(options2)) {
3931 var numberOfEdges = options2.numberOfEdges;
3932 return numberOfEdges === void 0 ? 32 : numberOfEdges;
3936 function getEarthRadius(options2) {
3937 if (isUndefinedOrNull(options2)) {
3938 return defaultEarthRadius;
3939 } else if (isObjectNotArray(options2)) {
3940 var earthRadius2 = options2.earthRadius;
3941 return earthRadius2 === void 0 ? defaultEarthRadius : earthRadius2;
3943 return defaultEarthRadius;
3945 function getDirection(options2) {
3946 if (isObjectNotArray(options2) && options2.rightHandRule) {
3951 function getBearing(options2) {
3952 if (isUndefinedOrNull(options2)) {
3954 } else if (isObjectNotArray(options2)) {
3955 var bearing = options2.bearing;
3956 return bearing === void 0 ? 0 : bearing;
3960 function isObjectNotArray(argument) {
3961 return argument !== null && typeof argument === "object" && !Array.isArray(argument);
3963 function isUndefinedOrNull(argument) {
3964 return argument === null || argument === void 0;
3969 // node_modules/polygon-clipping/dist/polygon-clipping.umd.js
3970 var require_polygon_clipping_umd = __commonJS({
3971 "node_modules/polygon-clipping/dist/polygon-clipping.umd.js"(exports2, module2) {
3972 (function(global3, factory) {
3973 typeof exports2 === "object" && typeof module2 !== "undefined" ? module2.exports = factory() : typeof define === "function" && define.amd ? define(factory) : (global3 = typeof globalThis !== "undefined" ? globalThis : global3 || self, global3.polygonClipping = factory());
3974 })(exports2, function() {
3976 function _classCallCheck(instance, Constructor) {
3977 if (!(instance instanceof Constructor)) {
3978 throw new TypeError("Cannot call a class as a function");
3981 function _defineProperties(target, props) {
3982 for (var i2 = 0; i2 < props.length; i2++) {
3983 var descriptor = props[i2];
3984 descriptor.enumerable = descriptor.enumerable || false;
3985 descriptor.configurable = true;
3986 if ("value" in descriptor)
3987 descriptor.writable = true;
3988 Object.defineProperty(target, descriptor.key, descriptor);
3991 function _createClass(Constructor, protoProps, staticProps) {
3993 _defineProperties(Constructor.prototype, protoProps);
3995 _defineProperties(Constructor, staticProps);
4001 function Node2(key, data) {
4011 function DEFAULT_COMPARE(a, b) {
4012 return a > b ? 1 : a < b ? -1 : 0;
4014 function splay(i2, t, comparator) {
4015 var N = new Node(null, null);
4019 var cmp2 = comparator(i2, t.key);
4021 if (t.left === null)
4023 if (comparator(i2, t.left.key) < 0) {
4028 if (t.left === null)
4034 } else if (cmp2 > 0) {
4035 if (t.right === null)
4037 if (comparator(i2, t.right.key) > 0) {
4042 if (t.right === null)
4057 function insert(i2, data, t, comparator) {
4058 var node = new Node(i2, data);
4060 node.left = node.right = null;
4063 t = splay(i2, t, comparator);
4064 var cmp2 = comparator(i2, t.key);
4069 } else if (cmp2 >= 0) {
4070 node.right = t.right;
4076 function split(key, v, comparator) {
4080 v = splay(key, v, comparator);
4081 var cmp2 = comparator(v.key, key);
4085 } else if (cmp2 < 0) {
4100 function merge3(left, right, comparator) {
4105 right = splay(left.key, right, comparator);
4109 function printRow(root3, prefix, isTail, out, printNode) {
4111 out("" + prefix + (isTail ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ") + printNode(root3) + "\n");
4112 var indent2 = prefix + (isTail ? " " : "\u2502 ");
4114 printRow(root3.left, indent2, false, out, printNode);
4116 printRow(root3.right, indent2, true, out, printNode);
4122 function Tree2(comparator) {
4123 if (comparator === void 0) {
4124 comparator = DEFAULT_COMPARE;
4128 this._comparator = comparator;
4130 Tree2.prototype.insert = function(key, data) {
4132 return this._root = insert(key, data, this._root, this._comparator);
4134 Tree2.prototype.add = function(key, data) {
4135 var node = new Node(key, data);
4136 if (this._root === null) {
4137 node.left = node.right = null;
4141 var comparator = this._comparator;
4142 var t = splay(key, this._root, comparator);
4143 var cmp2 = comparator(key, t.key);
4151 } else if (cmp2 > 0) {
4152 node.right = t.right;
4161 Tree2.prototype.remove = function(key) {
4162 this._root = this._remove(key, this._root, this._comparator);
4164 Tree2.prototype._remove = function(i2, t, comparator) {
4168 t = splay(i2, t, comparator);
4169 var cmp2 = comparator(i2, t.key);
4171 if (t.left === null) {
4174 x = splay(i2, t.left, comparator);
4182 Tree2.prototype.pop = function() {
4183 var node = this._root;
4188 this._root = splay(node.key, this._root, this._comparator);
4189 this._root = this._remove(node.key, this._root, this._comparator);
4197 Tree2.prototype.findStatic = function(key) {
4198 var current = this._root;
4199 var compare = this._comparator;
4201 var cmp2 = compare(key, current.key);
4205 current = current.left;
4207 current = current.right;
4211 Tree2.prototype.find = function(key) {
4213 this._root = splay(key, this._root, this._comparator);
4214 if (this._comparator(key, this._root.key) !== 0)
4219 Tree2.prototype.contains = function(key) {
4220 var current = this._root;
4221 var compare = this._comparator;
4223 var cmp2 = compare(key, current.key);
4227 current = current.left;
4229 current = current.right;
4233 Tree2.prototype.forEach = function(visitor, ctx) {
4234 var current = this._root;
4238 if (current !== null) {
4240 current = current.left;
4242 if (Q.length !== 0) {
4244 visitor.call(ctx, current);
4245 current = current.right;
4252 Tree2.prototype.range = function(low, high, fn, ctx) {
4254 var compare = this._comparator;
4255 var node = this._root;
4257 while (Q.length !== 0 || node) {
4263 cmp2 = compare(node.key, high);
4266 } else if (compare(node.key, low) >= 0) {
4267 if (fn.call(ctx, node))
4275 Tree2.prototype.keys = function() {
4277 this.forEach(function(_a) {
4279 return keys.push(key);
4283 Tree2.prototype.values = function() {
4285 this.forEach(function(_a) {
4287 return values.push(data);
4291 Tree2.prototype.min = function() {
4293 return this.minNode(this._root).key;
4296 Tree2.prototype.max = function() {
4298 return this.maxNode(this._root).key;
4301 Tree2.prototype.minNode = function(t) {
4311 Tree2.prototype.maxNode = function(t) {
4321 Tree2.prototype.at = function(index2) {
4322 var current = this._root;
4329 current = current.left;
4336 current = current.right;
4343 Tree2.prototype.next = function(d) {
4344 var root3 = this._root;
4345 var successor = null;
4347 successor = d.right;
4348 while (successor.left) {
4349 successor = successor.left;
4353 var comparator = this._comparator;
4355 var cmp2 = comparator(d.key, root3.key);
4358 else if (cmp2 < 0) {
4362 root3 = root3.right;
4366 Tree2.prototype.prev = function(d) {
4367 var root3 = this._root;
4368 var predecessor = null;
4369 if (d.left !== null) {
4370 predecessor = d.left;
4371 while (predecessor.right) {
4372 predecessor = predecessor.right;
4376 var comparator = this._comparator;
4378 var cmp2 = comparator(d.key, root3.key);
4384 predecessor = root3;
4385 root3 = root3.right;
4390 Tree2.prototype.clear = function() {
4395 Tree2.prototype.toList = function() {
4396 return toList(this._root);
4398 Tree2.prototype.load = function(keys, values, presort) {
4399 if (values === void 0) {
4402 if (presort === void 0) {
4405 var size = keys.length;
4406 var comparator = this._comparator;
4408 sort(keys, values, 0, size - 1, comparator);
4409 if (this._root === null) {
4410 this._root = loadRecursive(keys, values, 0, size);
4413 var mergedList = mergeLists(this.toList(), createList(keys, values), comparator);
4414 size = this._size + size;
4415 this._root = sortedListToBST({
4421 Tree2.prototype.isEmpty = function() {
4422 return this._root === null;
4424 Object.defineProperty(Tree2.prototype, "size", {
4425 get: function get4() {
4431 Object.defineProperty(Tree2.prototype, "root", {
4432 get: function get4() {
4438 Tree2.prototype.toString = function(printNode) {
4439 if (printNode === void 0) {
4440 printNode = function printNode2(n2) {
4441 return String(n2.key);
4445 printRow(this._root, "", true, function(v) {
4448 return out.join("");
4450 Tree2.prototype.update = function(key, newKey, newData) {
4451 var comparator = this._comparator;
4452 var _a = split(key, this._root, comparator), left = _a.left, right = _a.right;
4453 if (comparator(key, newKey) < 0) {
4454 right = insert(newKey, newData, right, comparator);
4456 left = insert(newKey, newData, left, comparator);
4458 this._root = merge3(left, right, comparator);
4460 Tree2.prototype.split = function(key) {
4461 return split(key, this._root, this._comparator);
4466 function loadRecursive(keys, values, start2, end) {
4467 var size = end - start2;
4469 var middle = start2 + Math.floor(size / 2);
4470 var key = keys[middle];
4471 var data = values[middle];
4472 var node = new Node(key, data);
4473 node.left = loadRecursive(keys, values, start2, middle);
4474 node.right = loadRecursive(keys, values, middle + 1, end);
4479 function createList(keys, values) {
4480 var head = new Node(null, null);
4482 for (var i2 = 0; i2 < keys.length; i2++) {
4483 p = p.next = new Node(keys[i2], values[i2]);
4488 function toList(root3) {
4489 var current = root3;
4492 var head = new Node(null, null);
4497 current = current.left;
4500 current = p = p.next = Q.pop();
4501 current = current.right;
4509 function sortedListToBST(list, start2, end) {
4510 var size = end - start2;
4512 var middle = start2 + Math.floor(size / 2);
4513 var left = sortedListToBST(list, start2, middle);
4514 var root3 = list.head;
4516 list.head = list.head.next;
4517 root3.right = sortedListToBST(list, middle + 1, end);
4522 function mergeLists(l1, l2, compare) {
4523 var head = new Node(null, null);
4527 while (p1 !== null && p2 !== null) {
4528 if (compare(p1.key, p2.key) < 0) {
4539 } else if (p2 !== null) {
4544 function sort(keys, values, left, right, compare) {
4547 var pivot = keys[left + right >> 1];
4553 } while (compare(keys[i2], pivot) < 0);
4556 } while (compare(keys[j2], pivot) > 0);
4560 keys[i2] = keys[j2];
4563 values[i2] = values[j2];
4566 sort(keys, values, left, j2, compare);
4567 sort(keys, values, j2 + 1, right, compare);
4569 var isInBbox = function isInBbox2(bbox2, point2) {
4570 return bbox2.ll.x <= point2.x && point2.x <= bbox2.ur.x && bbox2.ll.y <= point2.y && point2.y <= bbox2.ur.y;
4572 var getBboxOverlap = function getBboxOverlap2(b1, b2) {
4573 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)
4575 var lowerX = b1.ll.x < b2.ll.x ? b2.ll.x : b1.ll.x;
4576 var upperX = b1.ur.x < b2.ur.x ? b1.ur.x : b2.ur.x;
4577 var lowerY = b1.ll.y < b2.ll.y ? b2.ll.y : b1.ll.y;
4578 var upperY = b1.ur.y < b2.ur.y ? b1.ur.y : b2.ur.y;
4590 var epsilon3 = Number.EPSILON;
4591 if (epsilon3 === void 0)
4592 epsilon3 = Math.pow(2, -52);
4593 var EPSILON_SQ = epsilon3 * epsilon3;
4594 var cmp = function cmp2(a, b) {
4595 if (-epsilon3 < a && a < epsilon3) {
4596 if (-epsilon3 < b && b < epsilon3) {
4601 if (ab * ab < EPSILON_SQ * a * b) {
4604 return a < b ? -1 : 1;
4606 var PtRounder = /* @__PURE__ */ function() {
4607 function PtRounder2() {
4608 _classCallCheck(this, PtRounder2);
4611 _createClass(PtRounder2, [{
4613 value: function reset() {
4614 this.xRounder = new CoordRounder();
4615 this.yRounder = new CoordRounder();
4619 value: function round(x, y) {
4621 x: this.xRounder.round(x),
4622 y: this.yRounder.round(y)
4628 var CoordRounder = /* @__PURE__ */ function() {
4629 function CoordRounder2() {
4630 _classCallCheck(this, CoordRounder2);
4631 this.tree = new Tree();
4634 _createClass(CoordRounder2, [{
4636 value: function round(coord2) {
4637 var node = this.tree.add(coord2);
4638 var prevNode = this.tree.prev(node);
4639 if (prevNode !== null && cmp(node.key, prevNode.key) === 0) {
4640 this.tree.remove(coord2);
4641 return prevNode.key;
4643 var nextNode = this.tree.next(node);
4644 if (nextNode !== null && cmp(node.key, nextNode.key) === 0) {
4645 this.tree.remove(coord2);
4646 return nextNode.key;
4651 return CoordRounder2;
4653 var rounder = new PtRounder();
4654 var crossProduct = function crossProduct2(a, b) {
4655 return a.x * b.y - a.y * b.x;
4657 var dotProduct = function dotProduct2(a, b) {
4658 return a.x * b.x + a.y * b.y;
4660 var compareVectorAngles = function compareVectorAngles2(basePt, endPt1, endPt2) {
4662 x: endPt1.x - basePt.x,
4663 y: endPt1.y - basePt.y
4666 x: endPt2.x - basePt.x,
4667 y: endPt2.y - basePt.y
4669 var kross = crossProduct(v1, v2);
4670 return cmp(kross, 0);
4672 var length = function length2(v) {
4673 return Math.sqrt(dotProduct(v, v));
4675 var sineOfAngle = function sineOfAngle2(pShared, pBase, pAngle) {
4677 x: pBase.x - pShared.x,
4678 y: pBase.y - pShared.y
4681 x: pAngle.x - pShared.x,
4682 y: pAngle.y - pShared.y
4684 return crossProduct(vAngle, vBase) / length(vAngle) / length(vBase);
4686 var cosineOfAngle = function cosineOfAngle2(pShared, pBase, pAngle) {
4688 x: pBase.x - pShared.x,
4689 y: pBase.y - pShared.y
4692 x: pAngle.x - pShared.x,
4693 y: pAngle.y - pShared.y
4695 return dotProduct(vAngle, vBase) / length(vAngle) / length(vBase);
4697 var horizontalIntersection = function horizontalIntersection2(pt, v, y) {
4701 x: pt.x + v.x / v.y * (y - pt.y),
4705 var verticalIntersection = function verticalIntersection2(pt, v, x) {
4710 y: pt.y + v.y / v.x * (x - pt.x)
4713 var intersection = function intersection2(pt1, v1, pt2, v2) {
4715 return verticalIntersection(pt2, v2, pt1.x);
4717 return verticalIntersection(pt1, v1, pt2.x);
4719 return horizontalIntersection(pt2, v2, pt1.y);
4721 return horizontalIntersection(pt1, v1, pt2.y);
4722 var kross = crossProduct(v1, v2);
4729 var d1 = crossProduct(ve, v1) / kross;
4730 var d2 = crossProduct(ve, v2) / kross;
4731 var x12 = pt1.x + d2 * v1.x, x2 = pt2.x + d1 * v2.x;
4732 var y12 = pt1.y + d2 * v1.y, y2 = pt2.y + d1 * v2.y;
4733 var x = (x12 + x2) / 2;
4734 var y = (y12 + y2) / 2;
4740 var SweepEvent = /* @__PURE__ */ function() {
4741 _createClass(SweepEvent2, null, [{
4743 // for ordering sweep events in the sweep event queue
4744 value: function compare(a, b) {
4745 var ptCmp = SweepEvent2.comparePoints(a.point, b.point);
4748 if (a.point !== b.point)
4750 if (a.isLeft !== b.isLeft)
4751 return a.isLeft ? 1 : -1;
4752 return Segment.compare(a.segment, b.segment);
4754 // for ordering points in sweep line order
4756 key: "comparePoints",
4757 value: function comparePoints(aPt, bPt) {
4768 // Warning: 'point' input will be modified and re-used (for performance)
4770 function SweepEvent2(point2, isLeft) {
4771 _classCallCheck(this, SweepEvent2);
4772 if (point2.events === void 0)
4773 point2.events = [this];
4775 point2.events.push(this);
4776 this.point = point2;
4777 this.isLeft = isLeft;
4779 _createClass(SweepEvent2, [{
4781 value: function link2(other) {
4782 if (other.point === this.point) {
4783 throw new Error("Tried to link already linked events");
4785 var otherEvents = other.point.events;
4786 for (var i2 = 0, iMax = otherEvents.length; i2 < iMax; i2++) {
4787 var evt = otherEvents[i2];
4788 this.point.events.push(evt);
4789 evt.point = this.point;
4791 this.checkForConsuming();
4793 /* Do a pass over our linked events and check to see if any pair
4794 * of segments match, and should be consumed. */
4796 key: "checkForConsuming",
4797 value: function checkForConsuming() {
4798 var numEvents = this.point.events.length;
4799 for (var i2 = 0; i2 < numEvents; i2++) {
4800 var evt1 = this.point.events[i2];
4801 if (evt1.segment.consumedBy !== void 0)
4803 for (var j2 = i2 + 1; j2 < numEvents; j2++) {
4804 var evt2 = this.point.events[j2];
4805 if (evt2.consumedBy !== void 0)
4807 if (evt1.otherSE.point.events !== evt2.otherSE.point.events)
4809 evt1.segment.consume(evt2.segment);
4814 key: "getAvailableLinkedEvents",
4815 value: function getAvailableLinkedEvents() {
4817 for (var i2 = 0, iMax = this.point.events.length; i2 < iMax; i2++) {
4818 var evt = this.point.events[i2];
4819 if (evt !== this && !evt.segment.ringOut && evt.segment.isInResult()) {
4826 * Returns a comparator function for sorting linked events that will
4827 * favor the event that will give us the smallest left-side angle.
4828 * All ring construction starts as low as possible heading to the right,
4829 * so by always turning left as sharp as possible we'll get polygons
4830 * without uncessary loops & holes.
4832 * The comparator function has a compute cache such that it avoids
4833 * re-computing already-computed values.
4836 key: "getLeftmostComparator",
4837 value: function getLeftmostComparator(baseEvent) {
4839 var cache = /* @__PURE__ */ new Map();
4840 var fillCache = function fillCache2(linkedEvent) {
4841 var nextEvent = linkedEvent.otherSE;
4842 cache.set(linkedEvent, {
4843 sine: sineOfAngle(_this.point, baseEvent.point, nextEvent.point),
4844 cosine: cosineOfAngle(_this.point, baseEvent.point, nextEvent.point)
4847 return function(a, b) {
4852 var _cache$get = cache.get(a), asine = _cache$get.sine, acosine = _cache$get.cosine;
4853 var _cache$get2 = cache.get(b), bsine = _cache$get2.sine, bcosine = _cache$get2.cosine;
4854 if (asine >= 0 && bsine >= 0) {
4855 if (acosine < bcosine)
4857 if (acosine > bcosine)
4861 if (asine < 0 && bsine < 0) {
4862 if (acosine < bcosine)
4864 if (acosine > bcosine)
4879 var Segment = /* @__PURE__ */ function() {
4880 _createClass(Segment2, null, [{
4882 /* This compare() function is for ordering segments in the sweep
4883 * line tree, and does so according to the following criteria:
4885 * Consider the vertical line that lies an infinestimal step to the
4886 * right of the right-more of the two left endpoints of the input
4887 * segments. Imagine slowly moving a point up from negative infinity
4888 * in the increasing y direction. Which of the two segments will that
4889 * point intersect first? That segment comes 'before' the other one.
4891 * If neither segment would be intersected by such a line, (if one
4892 * or more of the segments are vertical) then the line to be considered
4893 * is directly on the right-more of the two left inputs.
4895 value: function compare(a, b) {
4896 var alx = a.leftSE.point.x;
4897 var blx = b.leftSE.point.x;
4898 var arx = a.rightSE.point.x;
4899 var brx = b.rightSE.point.x;
4904 var aly = a.leftSE.point.y;
4905 var bly = b.leftSE.point.y;
4906 var ary = a.rightSE.point.y;
4907 var bry = b.rightSE.point.y;
4909 if (bly < aly && bly < ary)
4911 if (bly > aly && bly > ary)
4913 var aCmpBLeft = a.comparePoint(b.leftSE.point);
4918 var bCmpARight = b.comparePoint(a.rightSE.point);
4919 if (bCmpARight !== 0)
4924 if (aly < bly && aly < bry)
4926 if (aly > bly && aly > bry)
4928 var bCmpALeft = b.comparePoint(a.leftSE.point);
4929 if (bCmpALeft !== 0)
4931 var aCmpBRight = a.comparePoint(b.rightSE.point);
4943 var _bCmpARight = b.comparePoint(a.rightSE.point);
4944 if (_bCmpARight !== 0)
4948 var _aCmpBRight = a.comparePoint(b.rightSE.point);
4949 if (_aCmpBRight < 0)
4951 if (_aCmpBRight > 0)
4959 if (ay > ax && by < bx)
4961 if (ay < ax && by > bx)
4978 /* Warning: a reference to ringWindings input will be stored,
4979 * and possibly will be later modified */
4981 function Segment2(leftSE, rightSE, rings, windings) {
4982 _classCallCheck(this, Segment2);
4983 this.id = ++segmentId;
4984 this.leftSE = leftSE;
4985 leftSE.segment = this;
4986 leftSE.otherSE = rightSE;
4987 this.rightSE = rightSE;
4988 rightSE.segment = this;
4989 rightSE.otherSE = leftSE;
4991 this.windings = windings;
4993 _createClass(Segment2, [{
4994 key: "replaceRightSE",
4995 /* When a segment is split, the rightSE is replaced with a new sweep event */
4996 value: function replaceRightSE(newRightSE) {
4997 this.rightSE = newRightSE;
4998 this.rightSE.segment = this;
4999 this.rightSE.otherSE = this.leftSE;
5000 this.leftSE.otherSE = this.rightSE;
5004 value: function bbox2() {
5005 var y12 = this.leftSE.point.y;
5006 var y2 = this.rightSE.point.y;
5009 x: this.leftSE.point.x,
5010 y: y12 < y2 ? y12 : y2
5013 x: this.rightSE.point.x,
5014 y: y12 > y2 ? y12 : y2
5018 /* A vector from the left point to the right */
5021 value: function vector() {
5023 x: this.rightSE.point.x - this.leftSE.point.x,
5024 y: this.rightSE.point.y - this.leftSE.point.y
5028 key: "isAnEndpoint",
5029 value: function isAnEndpoint(pt) {
5030 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;
5032 /* Compare this segment with a point.
5034 * A point P is considered to be colinear to a segment if there
5035 * exists a distance D such that if we travel along the segment
5036 * from one * endpoint towards the other a distance D, we find
5037 * ourselves at point P.
5039 * Return value indicates:
5041 * 1: point lies above the segment (to the left of vertical)
5042 * 0: point is colinear to segment
5043 * -1: point lies below the segment (to the right of vertical)
5046 key: "comparePoint",
5047 value: function comparePoint(point2) {
5048 if (this.isAnEndpoint(point2))
5050 var lPt = this.leftSE.point;
5051 var rPt = this.rightSE.point;
5052 var v = this.vector();
5053 if (lPt.x === rPt.x) {
5054 if (point2.x === lPt.x)
5056 return point2.x < lPt.x ? 1 : -1;
5058 var yDist = (point2.y - lPt.y) / v.y;
5059 var xFromYDist = lPt.x + yDist * v.x;
5060 if (point2.x === xFromYDist)
5062 var xDist = (point2.x - lPt.x) / v.x;
5063 var yFromXDist = lPt.y + xDist * v.y;
5064 if (point2.y === yFromXDist)
5066 return point2.y < yFromXDist ? -1 : 1;
5069 * Given another segment, returns the first non-trivial intersection
5070 * between the two segments (in terms of sweep line ordering), if it exists.
5072 * A 'non-trivial' intersection is one that will cause one or both of the
5073 * segments to be split(). As such, 'trivial' vs. 'non-trivial' intersection:
5075 * * endpoint of segA with endpoint of segB --> trivial
5076 * * endpoint of segA with point along segB --> non-trivial
5077 * * endpoint of segB with point along segA --> non-trivial
5078 * * point along segA with point along segB --> non-trivial
5080 * If no non-trivial intersection exists, return null
5081 * Else, return null.
5084 key: "getIntersection",
5085 value: function getIntersection(other) {
5086 var tBbox = this.bbox();
5087 var oBbox = other.bbox();
5088 var bboxOverlap = getBboxOverlap(tBbox, oBbox);
5089 if (bboxOverlap === null)
5091 var tlp = this.leftSE.point;
5092 var trp = this.rightSE.point;
5093 var olp = other.leftSE.point;
5094 var orp = other.rightSE.point;
5095 var touchesOtherLSE = isInBbox(tBbox, olp) && this.comparePoint(olp) === 0;
5096 var touchesThisLSE = isInBbox(oBbox, tlp) && other.comparePoint(tlp) === 0;
5097 var touchesOtherRSE = isInBbox(tBbox, orp) && this.comparePoint(orp) === 0;
5098 var touchesThisRSE = isInBbox(oBbox, trp) && other.comparePoint(trp) === 0;
5099 if (touchesThisLSE && touchesOtherLSE) {
5100 if (touchesThisRSE && !touchesOtherRSE)
5102 if (!touchesThisRSE && touchesOtherRSE)
5106 if (touchesThisLSE) {
5107 if (touchesOtherRSE) {
5108 if (tlp.x === orp.x && tlp.y === orp.y)
5113 if (touchesOtherLSE) {
5114 if (touchesThisRSE) {
5115 if (trp.x === olp.x && trp.y === olp.y)
5120 if (touchesThisRSE && touchesOtherRSE)
5124 if (touchesOtherRSE)
5126 var pt = intersection(tlp, this.vector(), olp, other.vector());
5129 if (!isInBbox(bboxOverlap, pt))
5131 return rounder.round(pt.x, pt.y);
5134 * Split the given segment into multiple segments on the given points.
5135 * * Each existing segment will retain its leftSE and a new rightSE will be
5137 * * A new segment will be generated which will adopt the original segment's
5138 * rightSE, and a new leftSE will be generated for it.
5139 * * If there are more than two points given to split on, new segments
5140 * in the middle will be generated with new leftSE and rightSE's.
5141 * * An array of the newly generated SweepEvents will be returned.
5143 * Warning: input array of points is modified
5147 value: function split2(point2) {
5149 var alreadyLinked = point2.events !== void 0;
5150 var newLeftSE = new SweepEvent(point2, true);
5151 var newRightSE = new SweepEvent(point2, false);
5152 var oldRightSE = this.rightSE;
5153 this.replaceRightSE(newRightSE);
5154 newEvents.push(newRightSE);
5155 newEvents.push(newLeftSE);
5156 var newSeg = new Segment2(newLeftSE, oldRightSE, this.rings.slice(), this.windings.slice());
5157 if (SweepEvent.comparePoints(newSeg.leftSE.point, newSeg.rightSE.point) > 0) {
5158 newSeg.swapEvents();
5160 if (SweepEvent.comparePoints(this.leftSE.point, this.rightSE.point) > 0) {
5163 if (alreadyLinked) {
5164 newLeftSE.checkForConsuming();
5165 newRightSE.checkForConsuming();
5169 /* Swap which event is left and right */
5172 value: function swapEvents() {
5173 var tmpEvt = this.rightSE;
5174 this.rightSE = this.leftSE;
5175 this.leftSE = tmpEvt;
5176 this.leftSE.isLeft = true;
5177 this.rightSE.isLeft = false;
5178 for (var i2 = 0, iMax = this.windings.length; i2 < iMax; i2++) {
5179 this.windings[i2] *= -1;
5182 /* Consume another segment. We take their rings under our wing
5183 * and mark them as consumed. Use for perfectly overlapping segments */
5186 value: function consume(other) {
5187 var consumer = this;
5188 var consumee = other;
5189 while (consumer.consumedBy) {
5190 consumer = consumer.consumedBy;
5192 while (consumee.consumedBy) {
5193 consumee = consumee.consumedBy;
5195 var cmp2 = Segment2.compare(consumer, consumee);
5200 consumer = consumee;
5203 if (consumer.prev === consumee) {
5204 var _tmp = consumer;
5205 consumer = consumee;
5208 for (var i2 = 0, iMax = consumee.rings.length; i2 < iMax; i2++) {
5209 var ring = consumee.rings[i2];
5210 var winding = consumee.windings[i2];
5211 var index2 = consumer.rings.indexOf(ring);
5212 if (index2 === -1) {
5213 consumer.rings.push(ring);
5214 consumer.windings.push(winding);
5216 consumer.windings[index2] += winding;
5218 consumee.rings = null;
5219 consumee.windings = null;
5220 consumee.consumedBy = consumer;
5221 consumee.leftSE.consumedBy = consumer.leftSE;
5222 consumee.rightSE.consumedBy = consumer.rightSE;
5224 /* The first segment previous segment chain that is in the result */
5226 key: "prevInResult",
5227 value: function prevInResult() {
5228 if (this._prevInResult !== void 0)
5229 return this._prevInResult;
5231 this._prevInResult = null;
5232 else if (this.prev.isInResult())
5233 this._prevInResult = this.prev;
5235 this._prevInResult = this.prev.prevInResult();
5236 return this._prevInResult;
5240 value: function beforeState() {
5241 if (this._beforeState !== void 0)
5242 return this._beforeState;
5244 this._beforeState = {
5250 var seg = this.prev.consumedBy || this.prev;
5251 this._beforeState = seg.afterState();
5253 return this._beforeState;
5257 value: function afterState() {
5258 if (this._afterState !== void 0)
5259 return this._afterState;
5260 var beforeState = this.beforeState();
5261 this._afterState = {
5262 rings: beforeState.rings.slice(0),
5263 windings: beforeState.windings.slice(0),
5266 var ringsAfter = this._afterState.rings;
5267 var windingsAfter = this._afterState.windings;
5268 var mpsAfter = this._afterState.multiPolys;
5269 for (var i2 = 0, iMax = this.rings.length; i2 < iMax; i2++) {
5270 var ring = this.rings[i2];
5271 var winding = this.windings[i2];
5272 var index2 = ringsAfter.indexOf(ring);
5273 if (index2 === -1) {
5274 ringsAfter.push(ring);
5275 windingsAfter.push(winding);
5277 windingsAfter[index2] += winding;
5279 var polysAfter = [];
5280 var polysExclude = [];
5281 for (var _i = 0, _iMax = ringsAfter.length; _i < _iMax; _i++) {
5282 if (windingsAfter[_i] === 0)
5284 var _ring = ringsAfter[_i];
5285 var poly = _ring.poly;
5286 if (polysExclude.indexOf(poly) !== -1)
5288 if (_ring.isExterior)
5289 polysAfter.push(poly);
5291 if (polysExclude.indexOf(poly) === -1)
5292 polysExclude.push(poly);
5293 var _index = polysAfter.indexOf(_ring.poly);
5295 polysAfter.splice(_index, 1);
5298 for (var _i2 = 0, _iMax2 = polysAfter.length; _i2 < _iMax2; _i2++) {
5299 var mp = polysAfter[_i2].multiPoly;
5300 if (mpsAfter.indexOf(mp) === -1)
5303 return this._afterState;
5305 /* Is this segment part of the final result? */
5308 value: function isInResult() {
5309 if (this.consumedBy)
5311 if (this._isInResult !== void 0)
5312 return this._isInResult;
5313 var mpsBefore = this.beforeState().multiPolys;
5314 var mpsAfter = this.afterState().multiPolys;
5315 switch (operation.type) {
5317 var noBefores = mpsBefore.length === 0;
5318 var noAfters = mpsAfter.length === 0;
5319 this._isInResult = noBefores !== noAfters;
5322 case "intersection": {
5325 if (mpsBefore.length < mpsAfter.length) {
5326 least = mpsBefore.length;
5327 most = mpsAfter.length;
5329 least = mpsAfter.length;
5330 most = mpsBefore.length;
5332 this._isInResult = most === operation.numMultiPolys && least < most;
5336 var diff = Math.abs(mpsBefore.length - mpsAfter.length);
5337 this._isInResult = diff % 2 === 1;
5340 case "difference": {
5341 var isJustSubject = function isJustSubject2(mps) {
5342 return mps.length === 1 && mps[0].isSubject;
5344 this._isInResult = isJustSubject(mpsBefore) !== isJustSubject(mpsAfter);
5348 throw new Error("Unrecognized operation type found ".concat(operation.type));
5350 return this._isInResult;
5354 value: function fromRing(pt1, pt2, ring) {
5355 var leftPt, rightPt, winding;
5356 var cmpPts = SweepEvent.comparePoints(pt1, pt2);
5361 } else if (cmpPts > 0) {
5366 throw new Error("Tried to create degenerate segment at [".concat(pt1.x, ", ").concat(pt1.y, "]"));
5367 var leftSE = new SweepEvent(leftPt, true);
5368 var rightSE = new SweepEvent(rightPt, false);
5369 return new Segment2(leftSE, rightSE, [ring], [winding]);
5374 var RingIn = /* @__PURE__ */ function() {
5375 function RingIn2(geomRing, poly, isExterior) {
5376 _classCallCheck(this, RingIn2);
5377 if (!Array.isArray(geomRing) || geomRing.length === 0) {
5378 throw new Error("Input geometry is not a valid Polygon or MultiPolygon");
5381 this.isExterior = isExterior;
5383 if (typeof geomRing[0][0] !== "number" || typeof geomRing[0][1] !== "number") {
5384 throw new Error("Input geometry is not a valid Polygon or MultiPolygon");
5386 var firstPoint = rounder.round(geomRing[0][0], geomRing[0][1]);
5397 var prevPoint = firstPoint;
5398 for (var i2 = 1, iMax = geomRing.length; i2 < iMax; i2++) {
5399 if (typeof geomRing[i2][0] !== "number" || typeof geomRing[i2][1] !== "number") {
5400 throw new Error("Input geometry is not a valid Polygon or MultiPolygon");
5402 var point2 = rounder.round(geomRing[i2][0], geomRing[i2][1]);
5403 if (point2.x === prevPoint.x && point2.y === prevPoint.y)
5405 this.segments.push(Segment.fromRing(prevPoint, point2, this));
5406 if (point2.x < this.bbox.ll.x)
5407 this.bbox.ll.x = point2.x;
5408 if (point2.y < this.bbox.ll.y)
5409 this.bbox.ll.y = point2.y;
5410 if (point2.x > this.bbox.ur.x)
5411 this.bbox.ur.x = point2.x;
5412 if (point2.y > this.bbox.ur.y)
5413 this.bbox.ur.y = point2.y;
5416 if (firstPoint.x !== prevPoint.x || firstPoint.y !== prevPoint.y) {
5417 this.segments.push(Segment.fromRing(prevPoint, firstPoint, this));
5420 _createClass(RingIn2, [{
5421 key: "getSweepEvents",
5422 value: function getSweepEvents() {
5423 var sweepEvents = [];
5424 for (var i2 = 0, iMax = this.segments.length; i2 < iMax; i2++) {
5425 var segment = this.segments[i2];
5426 sweepEvents.push(segment.leftSE);
5427 sweepEvents.push(segment.rightSE);
5434 var PolyIn = /* @__PURE__ */ function() {
5435 function PolyIn2(geomPoly, multiPoly) {
5436 _classCallCheck(this, PolyIn2);
5437 if (!Array.isArray(geomPoly)) {
5438 throw new Error("Input geometry is not a valid Polygon or MultiPolygon");
5440 this.exteriorRing = new RingIn(geomPoly[0], this, true);
5443 x: this.exteriorRing.bbox.ll.x,
5444 y: this.exteriorRing.bbox.ll.y
5447 x: this.exteriorRing.bbox.ur.x,
5448 y: this.exteriorRing.bbox.ur.y
5451 this.interiorRings = [];
5452 for (var i2 = 1, iMax = geomPoly.length; i2 < iMax; i2++) {
5453 var ring = new RingIn(geomPoly[i2], this, false);
5454 if (ring.bbox.ll.x < this.bbox.ll.x)
5455 this.bbox.ll.x = ring.bbox.ll.x;
5456 if (ring.bbox.ll.y < this.bbox.ll.y)
5457 this.bbox.ll.y = ring.bbox.ll.y;
5458 if (ring.bbox.ur.x > this.bbox.ur.x)
5459 this.bbox.ur.x = ring.bbox.ur.x;
5460 if (ring.bbox.ur.y > this.bbox.ur.y)
5461 this.bbox.ur.y = ring.bbox.ur.y;
5462 this.interiorRings.push(ring);
5464 this.multiPoly = multiPoly;
5466 _createClass(PolyIn2, [{
5467 key: "getSweepEvents",
5468 value: function getSweepEvents() {
5469 var sweepEvents = this.exteriorRing.getSweepEvents();
5470 for (var i2 = 0, iMax = this.interiorRings.length; i2 < iMax; i2++) {
5471 var ringSweepEvents = this.interiorRings[i2].getSweepEvents();
5472 for (var j2 = 0, jMax = ringSweepEvents.length; j2 < jMax; j2++) {
5473 sweepEvents.push(ringSweepEvents[j2]);
5481 var MultiPolyIn = /* @__PURE__ */ function() {
5482 function MultiPolyIn2(geom, isSubject) {
5483 _classCallCheck(this, MultiPolyIn2);
5484 if (!Array.isArray(geom)) {
5485 throw new Error("Input geometry is not a valid Polygon or MultiPolygon");
5488 if (typeof geom[0][0][0] === "number")
5495 x: Number.POSITIVE_INFINITY,
5496 y: Number.POSITIVE_INFINITY
5499 x: Number.NEGATIVE_INFINITY,
5500 y: Number.NEGATIVE_INFINITY
5503 for (var i2 = 0, iMax = geom.length; i2 < iMax; i2++) {
5504 var poly = new PolyIn(geom[i2], this);
5505 if (poly.bbox.ll.x < this.bbox.ll.x)
5506 this.bbox.ll.x = poly.bbox.ll.x;
5507 if (poly.bbox.ll.y < this.bbox.ll.y)
5508 this.bbox.ll.y = poly.bbox.ll.y;
5509 if (poly.bbox.ur.x > this.bbox.ur.x)
5510 this.bbox.ur.x = poly.bbox.ur.x;
5511 if (poly.bbox.ur.y > this.bbox.ur.y)
5512 this.bbox.ur.y = poly.bbox.ur.y;
5513 this.polys.push(poly);
5515 this.isSubject = isSubject;
5517 _createClass(MultiPolyIn2, [{
5518 key: "getSweepEvents",
5519 value: function getSweepEvents() {
5520 var sweepEvents = [];
5521 for (var i2 = 0, iMax = this.polys.length; i2 < iMax; i2++) {
5522 var polySweepEvents = this.polys[i2].getSweepEvents();
5523 for (var j2 = 0, jMax = polySweepEvents.length; j2 < jMax; j2++) {
5524 sweepEvents.push(polySweepEvents[j2]);
5530 return MultiPolyIn2;
5532 var RingOut = /* @__PURE__ */ function() {
5533 _createClass(RingOut2, null, [{
5535 /* Given the segments from the sweep line pass, compute & return a series
5536 * of closed rings from all the segments marked to be part of the result */
5537 value: function factory(allSegments) {
5539 for (var i2 = 0, iMax = allSegments.length; i2 < iMax; i2++) {
5540 var segment = allSegments[i2];
5541 if (!segment.isInResult() || segment.ringOut)
5543 var prevEvent = null;
5544 var event = segment.leftSE;
5545 var nextEvent = segment.rightSE;
5546 var events = [event];
5547 var startingPoint = event.point;
5548 var intersectionLEs = [];
5553 if (event.point === startingPoint)
5556 var availableLEs = event.getAvailableLinkedEvents();
5557 if (availableLEs.length === 0) {
5558 var firstPt = events[0].point;
5559 var lastPt = events[events.length - 1].point;
5560 throw new Error("Unable to complete output ring starting at [".concat(firstPt.x, ",") + " ".concat(firstPt.y, "]. Last matching segment found ends at") + " [".concat(lastPt.x, ", ").concat(lastPt.y, "]."));
5562 if (availableLEs.length === 1) {
5563 nextEvent = availableLEs[0].otherSE;
5567 for (var j2 = 0, jMax = intersectionLEs.length; j2 < jMax; j2++) {
5568 if (intersectionLEs[j2].point === event.point) {
5573 if (indexLE !== null) {
5574 var intersectionLE = intersectionLEs.splice(indexLE)[0];
5575 var ringEvents = events.splice(intersectionLE.index);
5576 ringEvents.unshift(ringEvents[0].otherSE);
5577 ringsOut.push(new RingOut2(ringEvents.reverse()));
5580 intersectionLEs.push({
5581 index: events.length,
5584 var comparator = event.getLeftmostComparator(prevEvent);
5585 nextEvent = availableLEs.sort(comparator)[0].otherSE;
5589 ringsOut.push(new RingOut2(events));
5594 function RingOut2(events) {
5595 _classCallCheck(this, RingOut2);
5596 this.events = events;
5597 for (var i2 = 0, iMax = events.length; i2 < iMax; i2++) {
5598 events[i2].segment.ringOut = this;
5602 _createClass(RingOut2, [{
5604 value: function getGeom2() {
5605 var prevPt = this.events[0].point;
5606 var points = [prevPt];
5607 for (var i2 = 1, iMax = this.events.length - 1; i2 < iMax; i2++) {
5608 var _pt = this.events[i2].point;
5609 var _nextPt = this.events[i2 + 1].point;
5610 if (compareVectorAngles(_pt, prevPt, _nextPt) === 0)
5615 if (points.length === 1)
5618 var nextPt = points[1];
5619 if (compareVectorAngles(pt, prevPt, nextPt) === 0)
5621 points.push(points[0]);
5622 var step = this.isExteriorRing() ? 1 : -1;
5623 var iStart = this.isExteriorRing() ? 0 : points.length - 1;
5624 var iEnd = this.isExteriorRing() ? points.length : -1;
5625 var orderedPoints = [];
5626 for (var _i = iStart; _i != iEnd; _i += step) {
5627 orderedPoints.push([points[_i].x, points[_i].y]);
5629 return orderedPoints;
5632 key: "isExteriorRing",
5633 value: function isExteriorRing() {
5634 if (this._isExteriorRing === void 0) {
5635 var enclosing = this.enclosingRing();
5636 this._isExteriorRing = enclosing ? !enclosing.isExteriorRing() : true;
5638 return this._isExteriorRing;
5641 key: "enclosingRing",
5642 value: function enclosingRing() {
5643 if (this._enclosingRing === void 0) {
5644 this._enclosingRing = this._calcEnclosingRing();
5646 return this._enclosingRing;
5648 /* Returns the ring that encloses this one, if any */
5650 key: "_calcEnclosingRing",
5651 value: function _calcEnclosingRing() {
5652 var leftMostEvt = this.events[0];
5653 for (var i2 = 1, iMax = this.events.length; i2 < iMax; i2++) {
5654 var evt = this.events[i2];
5655 if (SweepEvent.compare(leftMostEvt, evt) > 0)
5658 var prevSeg = leftMostEvt.segment.prevInResult();
5659 var prevPrevSeg = prevSeg ? prevSeg.prevInResult() : null;
5664 return prevSeg.ringOut;
5665 if (prevPrevSeg.ringOut !== prevSeg.ringOut) {
5666 if (prevPrevSeg.ringOut.enclosingRing() !== prevSeg.ringOut) {
5667 return prevSeg.ringOut;
5669 return prevSeg.ringOut.enclosingRing();
5671 prevSeg = prevPrevSeg.prevInResult();
5672 prevPrevSeg = prevSeg ? prevSeg.prevInResult() : null;
5678 var PolyOut = /* @__PURE__ */ function() {
5679 function PolyOut2(exteriorRing) {
5680 _classCallCheck(this, PolyOut2);
5681 this.exteriorRing = exteriorRing;
5682 exteriorRing.poly = this;
5683 this.interiorRings = [];
5685 _createClass(PolyOut2, [{
5687 value: function addInterior(ring) {
5688 this.interiorRings.push(ring);
5693 value: function getGeom2() {
5694 var geom = [this.exteriorRing.getGeom()];
5695 if (geom[0] === null)
5697 for (var i2 = 0, iMax = this.interiorRings.length; i2 < iMax; i2++) {
5698 var ringGeom = this.interiorRings[i2].getGeom();
5699 if (ringGeom === null)
5701 geom.push(ringGeom);
5708 var MultiPolyOut = /* @__PURE__ */ function() {
5709 function MultiPolyOut2(rings) {
5710 _classCallCheck(this, MultiPolyOut2);
5712 this.polys = this._composePolys(rings);
5714 _createClass(MultiPolyOut2, [{
5716 value: function getGeom2() {
5718 for (var i2 = 0, iMax = this.polys.length; i2 < iMax; i2++) {
5719 var polyGeom = this.polys[i2].getGeom();
5720 if (polyGeom === null)
5722 geom.push(polyGeom);
5727 key: "_composePolys",
5728 value: function _composePolys(rings) {
5730 for (var i2 = 0, iMax = rings.length; i2 < iMax; i2++) {
5731 var ring = rings[i2];
5734 if (ring.isExteriorRing())
5735 polys.push(new PolyOut(ring));
5737 var enclosingRing = ring.enclosingRing();
5738 if (!enclosingRing.poly)
5739 polys.push(new PolyOut(enclosingRing));
5740 enclosingRing.poly.addInterior(ring);
5746 return MultiPolyOut2;
5748 var SweepLine = /* @__PURE__ */ function() {
5749 function SweepLine2(queue) {
5750 var comparator = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : Segment.compare;
5751 _classCallCheck(this, SweepLine2);
5753 this.tree = new Tree(comparator);
5756 _createClass(SweepLine2, [{
5758 value: function process2(event) {
5759 var segment = event.segment;
5761 if (event.consumedBy) {
5763 this.queue.remove(event.otherSE);
5765 this.tree.remove(segment);
5768 var node = event.isLeft ? this.tree.insert(segment) : this.tree.find(segment);
5770 throw new Error("Unable to find segment #".concat(segment.id, " ") + "[".concat(segment.leftSE.point.x, ", ").concat(segment.leftSE.point.y, "] -> ") + "[".concat(segment.rightSE.point.x, ", ").concat(segment.rightSE.point.y, "] ") + "in SweepLine tree. Please submit a bug report.");
5771 var prevNode = node;
5772 var nextNode = node;
5773 var prevSeg = void 0;
5774 var nextSeg = void 0;
5775 while (prevSeg === void 0) {
5776 prevNode = this.tree.prev(prevNode);
5777 if (prevNode === null)
5779 else if (prevNode.key.consumedBy === void 0)
5780 prevSeg = prevNode.key;
5782 while (nextSeg === void 0) {
5783 nextNode = this.tree.next(nextNode);
5784 if (nextNode === null)
5786 else if (nextNode.key.consumedBy === void 0)
5787 nextSeg = nextNode.key;
5790 var prevMySplitter = null;
5792 var prevInter = prevSeg.getIntersection(segment);
5793 if (prevInter !== null) {
5794 if (!segment.isAnEndpoint(prevInter))
5795 prevMySplitter = prevInter;
5796 if (!prevSeg.isAnEndpoint(prevInter)) {
5797 var newEventsFromSplit = this._splitSafely(prevSeg, prevInter);
5798 for (var i2 = 0, iMax = newEventsFromSplit.length; i2 < iMax; i2++) {
5799 newEvents.push(newEventsFromSplit[i2]);
5804 var nextMySplitter = null;
5806 var nextInter = nextSeg.getIntersection(segment);
5807 if (nextInter !== null) {
5808 if (!segment.isAnEndpoint(nextInter))
5809 nextMySplitter = nextInter;
5810 if (!nextSeg.isAnEndpoint(nextInter)) {
5811 var _newEventsFromSplit = this._splitSafely(nextSeg, nextInter);
5812 for (var _i = 0, _iMax = _newEventsFromSplit.length; _i < _iMax; _i++) {
5813 newEvents.push(_newEventsFromSplit[_i]);
5818 if (prevMySplitter !== null || nextMySplitter !== null) {
5819 var mySplitter = null;
5820 if (prevMySplitter === null)
5821 mySplitter = nextMySplitter;
5822 else if (nextMySplitter === null)
5823 mySplitter = prevMySplitter;
5825 var cmpSplitters = SweepEvent.comparePoints(prevMySplitter, nextMySplitter);
5826 mySplitter = cmpSplitters <= 0 ? prevMySplitter : nextMySplitter;
5828 this.queue.remove(segment.rightSE);
5829 newEvents.push(segment.rightSE);
5830 var _newEventsFromSplit2 = segment.split(mySplitter);
5831 for (var _i2 = 0, _iMax2 = _newEventsFromSplit2.length; _i2 < _iMax2; _i2++) {
5832 newEvents.push(_newEventsFromSplit2[_i2]);
5835 if (newEvents.length > 0) {
5836 this.tree.remove(segment);
5837 newEvents.push(event);
5839 this.segments.push(segment);
5840 segment.prev = prevSeg;
5843 if (prevSeg && nextSeg) {
5844 var inter = prevSeg.getIntersection(nextSeg);
5845 if (inter !== null) {
5846 if (!prevSeg.isAnEndpoint(inter)) {
5847 var _newEventsFromSplit3 = this._splitSafely(prevSeg, inter);
5848 for (var _i3 = 0, _iMax3 = _newEventsFromSplit3.length; _i3 < _iMax3; _i3++) {
5849 newEvents.push(_newEventsFromSplit3[_i3]);
5852 if (!nextSeg.isAnEndpoint(inter)) {
5853 var _newEventsFromSplit4 = this._splitSafely(nextSeg, inter);
5854 for (var _i4 = 0, _iMax4 = _newEventsFromSplit4.length; _i4 < _iMax4; _i4++) {
5855 newEvents.push(_newEventsFromSplit4[_i4]);
5860 this.tree.remove(segment);
5864 /* Safely split a segment that is currently in the datastructures
5865 * IE - a segment other than the one that is currently being processed. */
5867 key: "_splitSafely",
5868 value: function _splitSafely(seg, pt) {
5869 this.tree.remove(seg);
5870 var rightSE = seg.rightSE;
5871 this.queue.remove(rightSE);
5872 var newEvents = seg.split(pt);
5873 newEvents.push(rightSE);
5874 if (seg.consumedBy === void 0)
5875 this.tree.insert(seg);
5881 var POLYGON_CLIPPING_MAX_QUEUE_SIZE = typeof process !== "undefined" && process.env.POLYGON_CLIPPING_MAX_QUEUE_SIZE || 1e6;
5882 var POLYGON_CLIPPING_MAX_SWEEPLINE_SEGMENTS = typeof process !== "undefined" && process.env.POLYGON_CLIPPING_MAX_SWEEPLINE_SEGMENTS || 1e6;
5883 var Operation = /* @__PURE__ */ function() {
5884 function Operation2() {
5885 _classCallCheck(this, Operation2);
5887 _createClass(Operation2, [{
5889 value: function run(type2, geom, moreGeoms) {
5890 operation.type = type2;
5892 var multipolys = [new MultiPolyIn(geom, true)];
5893 for (var i2 = 0, iMax = moreGeoms.length; i2 < iMax; i2++) {
5894 multipolys.push(new MultiPolyIn(moreGeoms[i2], false));
5896 operation.numMultiPolys = multipolys.length;
5897 if (operation.type === "difference") {
5898 var subject = multipolys[0];
5900 while (_i < multipolys.length) {
5901 if (getBboxOverlap(multipolys[_i].bbox, subject.bbox) !== null)
5904 multipolys.splice(_i, 1);
5907 if (operation.type === "intersection") {
5908 for (var _i2 = 0, _iMax = multipolys.length; _i2 < _iMax; _i2++) {
5909 var mpA = multipolys[_i2];
5910 for (var j2 = _i2 + 1, jMax = multipolys.length; j2 < jMax; j2++) {
5911 if (getBboxOverlap(mpA.bbox, multipolys[j2].bbox) === null)
5916 var queue = new Tree(SweepEvent.compare);
5917 for (var _i3 = 0, _iMax2 = multipolys.length; _i3 < _iMax2; _i3++) {
5918 var sweepEvents = multipolys[_i3].getSweepEvents();
5919 for (var _j = 0, _jMax = sweepEvents.length; _j < _jMax; _j++) {
5920 queue.insert(sweepEvents[_j]);
5921 if (queue.size > POLYGON_CLIPPING_MAX_QUEUE_SIZE) {
5922 throw new Error("Infinite loop when putting segment endpoints in a priority queue (queue size too big). Please file a bug report.");
5926 var sweepLine = new SweepLine(queue);
5927 var prevQueueSize = queue.size;
5928 var node = queue.pop();
5931 if (queue.size === prevQueueSize) {
5932 var seg = evt.segment;
5933 throw new Error("Unable to pop() ".concat(evt.isLeft ? "left" : "right", " SweepEvent ") + "[".concat(evt.point.x, ", ").concat(evt.point.y, "] from segment #").concat(seg.id, " ") + "[".concat(seg.leftSE.point.x, ", ").concat(seg.leftSE.point.y, "] -> ") + "[".concat(seg.rightSE.point.x, ", ").concat(seg.rightSE.point.y, "] from queue. ") + "Please file a bug report.");
5935 if (queue.size > POLYGON_CLIPPING_MAX_QUEUE_SIZE) {
5936 throw new Error("Infinite loop when passing sweep line over endpoints (queue size too big). Please file a bug report.");
5938 if (sweepLine.segments.length > POLYGON_CLIPPING_MAX_SWEEPLINE_SEGMENTS) {
5939 throw new Error("Infinite loop when passing sweep line over endpoints (too many sweep line segments). Please file a bug report.");
5941 var newEvents = sweepLine.process(evt);
5942 for (var _i4 = 0, _iMax3 = newEvents.length; _i4 < _iMax3; _i4++) {
5943 var _evt = newEvents[_i4];
5944 if (_evt.consumedBy === void 0)
5947 prevQueueSize = queue.size;
5951 var ringsOut = RingOut.factory(sweepLine.segments);
5952 var result = new MultiPolyOut(ringsOut);
5953 return result.getGeom();
5958 var operation = new Operation();
5959 var union = function union2(geom) {
5960 for (var _len = arguments.length, moreGeoms = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
5961 moreGeoms[_key - 1] = arguments[_key];
5963 return operation.run("union", geom, moreGeoms);
5965 var intersection$1 = function intersection2(geom) {
5966 for (var _len2 = arguments.length, moreGeoms = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
5967 moreGeoms[_key2 - 1] = arguments[_key2];
5969 return operation.run("intersection", geom, moreGeoms);
5971 var xor = function xor2(geom) {
5972 for (var _len3 = arguments.length, moreGeoms = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
5973 moreGeoms[_key3 - 1] = arguments[_key3];
5975 return operation.run("xor", geom, moreGeoms);
5977 var difference = function difference2(subjectGeom) {
5978 for (var _len4 = arguments.length, clippingGeoms = new Array(_len4 > 1 ? _len4 - 1 : 0), _key4 = 1; _key4 < _len4; _key4++) {
5979 clippingGeoms[_key4 - 1] = arguments[_key4];
5981 return operation.run("difference", subjectGeom, clippingGeoms);
5985 intersection: intersection$1,
5994 // node_modules/geojson-precision/index.js
5995 var require_geojson_precision = __commonJS({
5996 "node_modules/geojson-precision/index.js"(exports2, module2) {
5998 function parse(t, coordinatePrecision, extrasPrecision) {
5999 function point2(p) {
6000 return p.map(function(e, index) {
6002 return 1 * e.toFixed(coordinatePrecision);
6004 return 1 * e.toFixed(extrasPrecision);
6009 return l.map(point2);
6012 return p.map(multi);
6014 function multiPoly(m) {
6017 function geometry(obj) {
6023 obj.coordinates = point2(obj.coordinates);
6027 obj.coordinates = multi(obj.coordinates);
6030 case "MultiLineString":
6031 obj.coordinates = poly(obj.coordinates);
6033 case "MultiPolygon":
6034 obj.coordinates = multiPoly(obj.coordinates);
6036 case "GeometryCollection":
6037 obj.geometries = obj.geometries.map(geometry);
6043 function feature3(obj) {
6044 obj.geometry = geometry(obj.geometry);
6047 function featureCollection(f2) {
6048 f2.features = f2.features.map(feature3);
6051 function geometryCollection(g) {
6052 g.geometries = g.geometries.map(geometry);
6061 case "GeometryCollection":
6062 return geometryCollection(t);
6063 case "FeatureCollection":
6064 return featureCollection(t);
6069 case "MultiPolygon":
6070 case "MultiLineString":
6076 module2.exports = parse;
6077 module2.exports.parse = parse;
6082 // node_modules/@aitodotai/json-stringify-pretty-compact/index.js
6083 var require_json_stringify_pretty_compact = __commonJS({
6084 "node_modules/@aitodotai/json-stringify-pretty-compact/index.js"(exports2, module2) {
6085 function isObject3(obj) {
6086 return typeof obj === "object" && obj !== null;
6088 function forEach(obj, cb) {
6089 if (Array.isArray(obj)) {
6091 } else if (isObject3(obj)) {
6092 Object.keys(obj).forEach(function(key) {
6098 function getTreeDepth(obj) {
6100 if (Array.isArray(obj) || isObject3(obj)) {
6101 forEach(obj, function(val) {
6102 if (Array.isArray(val) || isObject3(val)) {
6103 var tmpDepth = getTreeDepth(val);
6104 if (tmpDepth > depth) {
6113 function stringify3(obj, options2) {
6114 options2 = options2 || {};
6115 var indent2 = JSON.stringify([1], null, get4(options2, "indent", 2)).slice(2, -3);
6116 var addMargin = get4(options2, "margins", false);
6117 var addArrayMargin = get4(options2, "arrayMargins", false);
6118 var addObjectMargin = get4(options2, "objectMargins", false);
6119 var maxLength = indent2 === "" ? Infinity : get4(options2, "maxLength", 80);
6120 var maxNesting = get4(options2, "maxNesting", Infinity);
6121 return function _stringify(obj2, currentIndent, reserved) {
6122 if (obj2 && typeof obj2.toJSON === "function") {
6123 obj2 = obj2.toJSON();
6125 var string = JSON.stringify(obj2);
6126 if (string === void 0) {
6129 var length = maxLength - currentIndent.length - reserved;
6130 var treeDepth = getTreeDepth(obj2);
6131 if (treeDepth <= maxNesting && string.length <= length) {
6132 var prettified = prettify(string, {
6137 if (prettified.length <= length) {
6141 if (isObject3(obj2)) {
6142 var nextIndent = currentIndent + indent2;
6145 var comma = function(array2, index2) {
6146 return index2 === array2.length - 1 ? 0 : 1;
6148 if (Array.isArray(obj2)) {
6149 for (var index = 0; index < obj2.length; index++) {
6151 _stringify(obj2[index], nextIndent, comma(obj2, index)) || "null"
6156 Object.keys(obj2).forEach(function(key, index2, array2) {
6157 var keyPart = JSON.stringify(key) + ": ";
6158 var value = _stringify(
6161 keyPart.length + comma(array2, index2)
6163 if (value !== void 0) {
6164 items.push(keyPart + value);
6169 if (items.length > 0) {
6172 indent2 + items.join(",\n" + nextIndent),
6174 ].join("\n" + currentIndent);
6180 var stringOrChar = /("(?:[^\\"]|\\.)*")|[:,\][}{]/g;
6181 function prettify(string, options2) {
6182 options2 = options2 || {};
6191 if (options2.addMargin || options2.addObjectMargin) {
6195 if (options2.addMargin || options2.addArrayMargin) {
6199 return string.replace(stringOrChar, function(match, string2) {
6200 return string2 ? match : tokens[match];
6203 function get4(options2, name, defaultValue) {
6204 return name in options2 ? options2[name] : defaultValue;
6206 module2.exports = stringify3;
6210 // node_modules/aes-js/index.js
6211 var require_aes_js = __commonJS({
6212 "node_modules/aes-js/index.js"(exports2, module2) {
6215 function checkInt(value) {
6216 return parseInt(value) === value;
6218 function checkInts(arrayish) {
6219 if (!checkInt(arrayish.length)) {
6222 for (var i2 = 0; i2 < arrayish.length; i2++) {
6223 if (!checkInt(arrayish[i2]) || arrayish[i2] < 0 || arrayish[i2] > 255) {
6229 function coerceArray(arg, copy2) {
6230 if (arg.buffer && arg.name === "Uint8Array") {
6235 arg = Array.prototype.slice.call(arg);
6240 if (Array.isArray(arg)) {
6241 if (!checkInts(arg)) {
6242 throw new Error("Array contains invalid value: " + arg);
6244 return new Uint8Array(arg);
6246 if (checkInt(arg.length) && checkInts(arg)) {
6247 return new Uint8Array(arg);
6249 throw new Error("unsupported array-like object");
6251 function createArray(length) {
6252 return new Uint8Array(length);
6254 function copyArray(sourceArray, targetArray, targetStart, sourceStart, sourceEnd) {
6255 if (sourceStart != null || sourceEnd != null) {
6256 if (sourceArray.slice) {
6257 sourceArray = sourceArray.slice(sourceStart, sourceEnd);
6259 sourceArray = Array.prototype.slice.call(sourceArray, sourceStart, sourceEnd);
6262 targetArray.set(sourceArray, targetStart);
6264 var convertUtf8 = function() {
6265 function toBytes(text2) {
6266 var result = [], i2 = 0;
6267 text2 = encodeURI(text2);
6268 while (i2 < text2.length) {
6269 var c = text2.charCodeAt(i2++);
6271 result.push(parseInt(text2.substr(i2, 2), 16));
6277 return coerceArray(result);
6279 function fromBytes(bytes) {
6280 var result = [], i2 = 0;
6281 while (i2 < bytes.length) {
6284 result.push(String.fromCharCode(c));
6286 } else if (c > 191 && c < 224) {
6287 result.push(String.fromCharCode((c & 31) << 6 | bytes[i2 + 1] & 63));
6290 result.push(String.fromCharCode((c & 15) << 12 | (bytes[i2 + 1] & 63) << 6 | bytes[i2 + 2] & 63));
6294 return result.join("");
6301 var convertHex = function() {
6302 function toBytes(text2) {
6304 for (var i2 = 0; i2 < text2.length; i2 += 2) {
6305 result.push(parseInt(text2.substr(i2, 2), 16));
6309 var Hex = "0123456789abcdef";
6310 function fromBytes(bytes) {
6312 for (var i2 = 0; i2 < bytes.length; i2++) {
6314 result.push(Hex[(v & 240) >> 4] + Hex[v & 15]);
6316 return result.join("");
6323 var numberOfRounds = { 16: 10, 24: 12, 32: 14 };
6324 var rcon = [1, 2, 4, 8, 16, 32, 64, 128, 27, 54, 108, 216, 171, 77, 154, 47, 94, 188, 99, 198, 151, 53, 106, 212, 179, 125, 250, 239, 197, 145];
6325 var S = [99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, 118, 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, 114, 192, 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, 216, 49, 21, 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, 235, 39, 178, 117, 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, 179, 41, 227, 47, 132, 83, 209, 0, 237, 32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207, 208, 239, 170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60, 159, 168, 81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255, 243, 210, 205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61, 100, 93, 25, 115, 96, 129, 79, 220, 34, 42, 144, 136, 70, 238, 184, 20, 222, 94, 11, 219, 224, 50, 58, 10, 73, 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121, 231, 200, 55, 109, 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, 186, 120, 37, 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, 112, 62, 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158, 225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223, 140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, 22];
6326 var Si = [82, 9, 106, 213, 48, 54, 165, 56, 191, 64, 163, 158, 129, 243, 215, 251, 124, 227, 57, 130, 155, 47, 255, 135, 52, 142, 67, 68, 196, 222, 233, 203, 84, 123, 148, 50, 166, 194, 35, 61, 238, 76, 149, 11, 66, 250, 195, 78, 8, 46, 161, 102, 40, 217, 36, 178, 118, 91, 162, 73, 109, 139, 209, 37, 114, 248, 246, 100, 134, 104, 152, 22, 212, 164, 92, 204, 93, 101, 182, 146, 108, 112, 72, 80, 253, 237, 185, 218, 94, 21, 70, 87, 167, 141, 157, 132, 144, 216, 171, 0, 140, 188, 211, 10, 247, 228, 88, 5, 184, 179, 69, 6, 208, 44, 30, 143, 202, 63, 15, 2, 193, 175, 189, 3, 1, 19, 138, 107, 58, 145, 17, 65, 79, 103, 220, 234, 151, 242, 207, 206, 240, 180, 230, 115, 150, 172, 116, 34, 231, 173, 53, 133, 226, 249, 55, 232, 28, 117, 223, 110, 71, 241, 26, 113, 29, 41, 197, 137, 111, 183, 98, 14, 170, 24, 190, 27, 252, 86, 62, 75, 198, 210, 121, 32, 154, 219, 192, 254, 120, 205, 90, 244, 31, 221, 168, 51, 136, 7, 199, 49, 177, 18, 16, 89, 39, 128, 236, 95, 96, 81, 127, 169, 25, 181, 74, 13, 45, 229, 122, 159, 147, 201, 156, 239, 160, 224, 59, 77, 174, 42, 245, 176, 200, 235, 187, 60, 131, 83, 153, 97, 23, 43, 4, 126, 186, 119, 214, 38, 225, 105, 20, 99, 85, 33, 12, 125];
6327 var T1 = [3328402341, 4168907908, 4000806809, 4135287693, 4294111757, 3597364157, 3731845041, 2445657428, 1613770832, 33620227, 3462883241, 1445669757, 3892248089, 3050821474, 1303096294, 3967186586, 2412431941, 528646813, 2311702848, 4202528135, 4026202645, 2992200171, 2387036105, 4226871307, 1101901292, 3017069671, 1604494077, 1169141738, 597466303, 1403299063, 3832705686, 2613100635, 1974974402, 3791519004, 1033081774, 1277568618, 1815492186, 2118074177, 4126668546, 2211236943, 1748251740, 1369810420, 3521504564, 4193382664, 3799085459, 2883115123, 1647391059, 706024767, 134480908, 2512897874, 1176707941, 2646852446, 806885416, 932615841, 168101135, 798661301, 235341577, 605164086, 461406363, 3756188221, 3454790438, 1311188841, 2142417613, 3933566367, 302582043, 495158174, 1479289972, 874125870, 907746093, 3698224818, 3025820398, 1537253627, 2756858614, 1983593293, 3084310113, 2108928974, 1378429307, 3722699582, 1580150641, 327451799, 2790478837, 3117535592, 0, 3253595436, 1075847264, 3825007647, 2041688520, 3059440621, 3563743934, 2378943302, 1740553945, 1916352843, 2487896798, 2555137236, 2958579944, 2244988746, 3151024235, 3320835882, 1336584933, 3992714006, 2252555205, 2588757463, 1714631509, 293963156, 2319795663, 3925473552, 67240454, 4269768577, 2689618160, 2017213508, 631218106, 1269344483, 2723238387, 1571005438, 2151694528, 93294474, 1066570413, 563977660, 1882732616, 4059428100, 1673313503, 2008463041, 2950355573, 1109467491, 537923632, 3858759450, 4260623118, 3218264685, 2177748300, 403442708, 638784309, 3287084079, 3193921505, 899127202, 2286175436, 773265209, 2479146071, 1437050866, 4236148354, 2050833735, 3362022572, 3126681063, 840505643, 3866325909, 3227541664, 427917720, 2655997905, 2749160575, 1143087718, 1412049534, 999329963, 193497219, 2353415882, 3354324521, 1807268051, 672404540, 2816401017, 3160301282, 369822493, 2916866934, 3688947771, 1681011286, 1949973070, 336202270, 2454276571, 201721354, 1210328172, 3093060836, 2680341085, 3184776046, 1135389935, 3294782118, 965841320, 831886756, 3554993207, 4068047243, 3588745010, 2345191491, 1849112409, 3664604599, 26054028, 2983581028, 2622377682, 1235855840, 3630984372, 2891339514, 4092916743, 3488279077, 3395642799, 4101667470, 1202630377, 268961816, 1874508501, 4034427016, 1243948399, 1546530418, 941366308, 1470539505, 1941222599, 2546386513, 3421038627, 2715671932, 3899946140, 1042226977, 2521517021, 1639824860, 227249030, 260737669, 3765465232, 2084453954, 1907733956, 3429263018, 2420656344, 100860677, 4160157185, 470683154, 3261161891, 1781871967, 2924959737, 1773779408, 394692241, 2579611992, 974986535, 664706745, 3655459128, 3958962195, 731420851, 571543859, 3530123707, 2849626480, 126783113, 865375399, 765172662, 1008606754, 361203602, 3387549984, 2278477385, 2857719295, 1344809080, 2782912378, 59542671, 1503764984, 160008576, 437062935, 1707065306, 3622233649, 2218934982, 3496503480, 2185314755, 697932208, 1512910199, 504303377, 2075177163, 2824099068, 1841019862, 739644986];
6328 var T2 = [2781242211, 2230877308, 2582542199, 2381740923, 234877682, 3184946027, 2984144751, 1418839493, 1348481072, 50462977, 2848876391, 2102799147, 434634494, 1656084439, 3863849899, 2599188086, 1167051466, 2636087938, 1082771913, 2281340285, 368048890, 3954334041, 3381544775, 201060592, 3963727277, 1739838676, 4250903202, 3930435503, 3206782108, 4149453988, 2531553906, 1536934080, 3262494647, 484572669, 2923271059, 1783375398, 1517041206, 1098792767, 49674231, 1334037708, 1550332980, 4098991525, 886171109, 150598129, 2481090929, 1940642008, 1398944049, 1059722517, 201851908, 1385547719, 1699095331, 1587397571, 674240536, 2704774806, 252314885, 3039795866, 151914247, 908333586, 2602270848, 1038082786, 651029483, 1766729511, 3447698098, 2682942837, 454166793, 2652734339, 1951935532, 775166490, 758520603, 3000790638, 4004797018, 4217086112, 4137964114, 1299594043, 1639438038, 3464344499, 2068982057, 1054729187, 1901997871, 2534638724, 4121318227, 1757008337, 0, 750906861, 1614815264, 535035132, 3363418545, 3988151131, 3201591914, 1183697867, 3647454910, 1265776953, 3734260298, 3566750796, 3903871064, 1250283471, 1807470800, 717615087, 3847203498, 384695291, 3313910595, 3617213773, 1432761139, 2484176261, 3481945413, 283769337, 100925954, 2180939647, 4037038160, 1148730428, 3123027871, 3813386408, 4087501137, 4267549603, 3229630528, 2315620239, 2906624658, 3156319645, 1215313976, 82966005, 3747855548, 3245848246, 1974459098, 1665278241, 807407632, 451280895, 251524083, 1841287890, 1283575245, 337120268, 891687699, 801369324, 3787349855, 2721421207, 3431482436, 959321879, 1469301956, 4065699751, 2197585534, 1199193405, 2898814052, 3887750493, 724703513, 2514908019, 2696962144, 2551808385, 3516813135, 2141445340, 1715741218, 2119445034, 2872807568, 2198571144, 3398190662, 700968686, 3547052216, 1009259540, 2041044702, 3803995742, 487983883, 1991105499, 1004265696, 1449407026, 1316239930, 504629770, 3683797321, 168560134, 1816667172, 3837287516, 1570751170, 1857934291, 4014189740, 2797888098, 2822345105, 2754712981, 936633572, 2347923833, 852879335, 1133234376, 1500395319, 3084545389, 2348912013, 1689376213, 3533459022, 3762923945, 3034082412, 4205598294, 133428468, 634383082, 2949277029, 2398386810, 3913789102, 403703816, 3580869306, 2297460856, 1867130149, 1918643758, 607656988, 4049053350, 3346248884, 1368901318, 600565992, 2090982877, 2632479860, 557719327, 3717614411, 3697393085, 2249034635, 2232388234, 2430627952, 1115438654, 3295786421, 2865522278, 3633334344, 84280067, 33027830, 303828494, 2747425121, 1600795957, 4188952407, 3496589753, 2434238086, 1486471617, 658119965, 3106381470, 953803233, 334231800, 3005978776, 857870609, 3151128937, 1890179545, 2298973838, 2805175444, 3056442267, 574365214, 2450884487, 550103529, 1233637070, 4289353045, 2018519080, 2057691103, 2399374476, 4166623649, 2148108681, 387583245, 3664101311, 836232934, 3330556482, 3100665960, 3280093505, 2955516313, 2002398509, 287182607, 3413881008, 4238890068, 3597515707, 975967766];
6329 var T3 = [1671808611, 2089089148, 2006576759, 2072901243, 4061003762, 1807603307, 1873927791, 3310653893, 810573872, 16974337, 1739181671, 729634347, 4263110654, 3613570519, 2883997099, 1989864566, 3393556426, 2191335298, 3376449993, 2106063485, 4195741690, 1508618841, 1204391495, 4027317232, 2917941677, 3563566036, 2734514082, 2951366063, 2629772188, 2767672228, 1922491506, 3227229120, 3082974647, 4246528509, 2477669779, 644500518, 911895606, 1061256767, 4144166391, 3427763148, 878471220, 2784252325, 3845444069, 4043897329, 1905517169, 3631459288, 827548209, 356461077, 67897348, 3344078279, 593839651, 3277757891, 405286936, 2527147926, 84871685, 2595565466, 118033927, 305538066, 2157648768, 3795705826, 3945188843, 661212711, 2999812018, 1973414517, 152769033, 2208177539, 745822252, 439235610, 455947803, 1857215598, 1525593178, 2700827552, 1391895634, 994932283, 3596728278, 3016654259, 695947817, 3812548067, 795958831, 2224493444, 1408607827, 3513301457, 0, 3979133421, 543178784, 4229948412, 2982705585, 1542305371, 1790891114, 3410398667, 3201918910, 961245753, 1256100938, 1289001036, 1491644504, 3477767631, 3496721360, 4012557807, 2867154858, 4212583931, 1137018435, 1305975373, 861234739, 2241073541, 1171229253, 4178635257, 33948674, 2139225727, 1357946960, 1011120188, 2679776671, 2833468328, 1374921297, 2751356323, 1086357568, 2408187279, 2460827538, 2646352285, 944271416, 4110742005, 3168756668, 3066132406, 3665145818, 560153121, 271589392, 4279952895, 4077846003, 3530407890, 3444343245, 202643468, 322250259, 3962553324, 1608629855, 2543990167, 1154254916, 389623319, 3294073796, 2817676711, 2122513534, 1028094525, 1689045092, 1575467613, 422261273, 1939203699, 1621147744, 2174228865, 1339137615, 3699352540, 577127458, 712922154, 2427141008, 2290289544, 1187679302, 3995715566, 3100863416, 339486740, 3732514782, 1591917662, 186455563, 3681988059, 3762019296, 844522546, 978220090, 169743370, 1239126601, 101321734, 611076132, 1558493276, 3260915650, 3547250131, 2901361580, 1655096418, 2443721105, 2510565781, 3828863972, 2039214713, 3878868455, 3359869896, 928607799, 1840765549, 2374762893, 3580146133, 1322425422, 2850048425, 1823791212, 1459268694, 4094161908, 3928346602, 1706019429, 2056189050, 2934523822, 135794696, 3134549946, 2022240376, 628050469, 779246638, 472135708, 2800834470, 3032970164, 3327236038, 3894660072, 3715932637, 1956440180, 522272287, 1272813131, 3185336765, 2340818315, 2323976074, 1888542832, 1044544574, 3049550261, 1722469478, 1222152264, 50660867, 4127324150, 236067854, 1638122081, 895445557, 1475980887, 3117443513, 2257655686, 3243809217, 489110045, 2662934430, 3778599393, 4162055160, 2561878936, 288563729, 1773916777, 3648039385, 2391345038, 2493985684, 2612407707, 505560094, 2274497927, 3911240169, 3460925390, 1442818645, 678973480, 3749357023, 2358182796, 2717407649, 2306869641, 219617805, 3218761151, 3862026214, 1120306242, 1756942440, 1103331905, 2578459033, 762796589, 252780047, 2966125488, 1425844308, 3151392187, 372911126];
6330 var T4 = [1667474886, 2088535288, 2004326894, 2071694838, 4075949567, 1802223062, 1869591006, 3318043793, 808472672, 16843522, 1734846926, 724270422, 4278065639, 3621216949, 2880169549, 1987484396, 3402253711, 2189597983, 3385409673, 2105378810, 4210693615, 1499065266, 1195886990, 4042263547, 2913856577, 3570689971, 2728590687, 2947541573, 2627518243, 2762274643, 1920112356, 3233831835, 3082273397, 4261223649, 2475929149, 640051788, 909531756, 1061110142, 4160160501, 3435941763, 875846760, 2779116625, 3857003729, 4059105529, 1903268834, 3638064043, 825316194, 353713962, 67374088, 3351728789, 589522246, 3284360861, 404236336, 2526454071, 84217610, 2593830191, 117901582, 303183396, 2155911963, 3806477791, 3958056653, 656894286, 2998062463, 1970642922, 151591698, 2206440989, 741110872, 437923380, 454765878, 1852748508, 1515908788, 2694904667, 1381168804, 993742198, 3604373943, 3014905469, 690584402, 3823320797, 791638366, 2223281939, 1398011302, 3520161977, 0, 3991743681, 538992704, 4244381667, 2981218425, 1532751286, 1785380564, 3419096717, 3200178535, 960056178, 1246420628, 1280103576, 1482221744, 3486468741, 3503319995, 4025428677, 2863326543, 4227536621, 1128514950, 1296947098, 859002214, 2240123921, 1162203018, 4193849577, 33687044, 2139062782, 1347481760, 1010582648, 2678045221, 2829640523, 1364325282, 2745433693, 1077985408, 2408548869, 2459086143, 2644360225, 943212656, 4126475505, 3166494563, 3065430391, 3671750063, 555836226, 269496352, 4294908645, 4092792573, 3537006015, 3452783745, 202118168, 320025894, 3974901699, 1600119230, 2543297077, 1145359496, 387397934, 3301201811, 2812801621, 2122220284, 1027426170, 1684319432, 1566435258, 421079858, 1936954854, 1616945344, 2172753945, 1330631070, 3705438115, 572679748, 707427924, 2425400123, 2290647819, 1179044492, 4008585671, 3099120491, 336870440, 3739122087, 1583276732, 185277718, 3688593069, 3772791771, 842159716, 976899700, 168435220, 1229577106, 101059084, 606366792, 1549591736, 3267517855, 3553849021, 2897014595, 1650632388, 2442242105, 2509612081, 3840161747, 2038008818, 3890688725, 3368567691, 926374254, 1835907034, 2374863873, 3587531953, 1313788572, 2846482505, 1819063512, 1448540844, 4109633523, 3941213647, 1701162954, 2054852340, 2930698567, 134748176, 3132806511, 2021165296, 623210314, 774795868, 471606328, 2795958615, 3031746419, 3334885783, 3907527627, 3722280097, 1953799400, 522133822, 1263263126, 3183336545, 2341176845, 2324333839, 1886425312, 1044267644, 3048588401, 1718004428, 1212733584, 50529542, 4143317495, 235803164, 1633788866, 892690282, 1465383342, 3115962473, 2256965911, 3250673817, 488449850, 2661202215, 3789633753, 4177007595, 2560144171, 286339874, 1768537042, 3654906025, 2391705863, 2492770099, 2610673197, 505291324, 2273808917, 3924369609, 3469625735, 1431699370, 673740880, 3755965093, 2358021891, 2711746649, 2307489801, 218961690, 3217021541, 3873845719, 1111672452, 1751693520, 1094828930, 2576986153, 757954394, 252645662, 2964376443, 1414855848, 3149649517, 370555436];
6331 var T5 = [1374988112, 2118214995, 437757123, 975658646, 1001089995, 530400753, 2902087851, 1273168787, 540080725, 2910219766, 2295101073, 4110568485, 1340463100, 3307916247, 641025152, 3043140495, 3736164937, 632953703, 1172967064, 1576976609, 3274667266, 2169303058, 2370213795, 1809054150, 59727847, 361929877, 3211623147, 2505202138, 3569255213, 1484005843, 1239443753, 2395588676, 1975683434, 4102977912, 2572697195, 666464733, 3202437046, 4035489047, 3374361702, 2110667444, 1675577880, 3843699074, 2538681184, 1649639237, 2976151520, 3144396420, 4269907996, 4178062228, 1883793496, 2403728665, 2497604743, 1383856311, 2876494627, 1917518562, 3810496343, 1716890410, 3001755655, 800440835, 2261089178, 3543599269, 807962610, 599762354, 33778362, 3977675356, 2328828971, 2809771154, 4077384432, 1315562145, 1708848333, 101039829, 3509871135, 3299278474, 875451293, 2733856160, 92987698, 2767645557, 193195065, 1080094634, 1584504582, 3178106961, 1042385657, 2531067453, 3711829422, 1306967366, 2438237621, 1908694277, 67556463, 1615861247, 429456164, 3602770327, 2302690252, 1742315127, 2968011453, 126454664, 3877198648, 2043211483, 2709260871, 2084704233, 4169408201, 0, 159417987, 841739592, 504459436, 1817866830, 4245618683, 260388950, 1034867998, 908933415, 168810852, 1750902305, 2606453969, 607530554, 202008497, 2472011535, 3035535058, 463180190, 2160117071, 1641816226, 1517767529, 470948374, 3801332234, 3231722213, 1008918595, 303765277, 235474187, 4069246893, 766945465, 337553864, 1475418501, 2943682380, 4003061179, 2743034109, 4144047775, 1551037884, 1147550661, 1543208500, 2336434550, 3408119516, 3069049960, 3102011747, 3610369226, 1113818384, 328671808, 2227573024, 2236228733, 3535486456, 2935566865, 3341394285, 496906059, 3702665459, 226906860, 2009195472, 733156972, 2842737049, 294930682, 1206477858, 2835123396, 2700099354, 1451044056, 573804783, 2269728455, 3644379585, 2362090238, 2564033334, 2801107407, 2776292904, 3669462566, 1068351396, 742039012, 1350078989, 1784663195, 1417561698, 4136440770, 2430122216, 775550814, 2193862645, 2673705150, 1775276924, 1876241833, 3475313331, 3366754619, 270040487, 3902563182, 3678124923, 3441850377, 1851332852, 3969562369, 2203032232, 3868552805, 2868897406, 566021896, 4011190502, 3135740889, 1248802510, 3936291284, 699432150, 832877231, 708780849, 3332740144, 899835584, 1951317047, 4236429990, 3767586992, 866637845, 4043610186, 1106041591, 2144161806, 395441711, 1984812685, 1139781709, 3433712980, 3835036895, 2664543715, 1282050075, 3240894392, 1181045119, 2640243204, 25965917, 4203181171, 4211818798, 3009879386, 2463879762, 3910161971, 1842759443, 2597806476, 933301370, 1509430414, 3943906441, 3467192302, 3076639029, 3776767469, 2051518780, 2631065433, 1441952575, 404016761, 1942435775, 1408749034, 1610459739, 3745345300, 2017778566, 3400528769, 3110650942, 941896748, 3265478751, 371049330, 3168937228, 675039627, 4279080257, 967311729, 135050206, 3635733660, 1683407248, 2076935265, 3576870512, 1215061108, 3501741890];
6332 var T6 = [1347548327, 1400783205, 3273267108, 2520393566, 3409685355, 4045380933, 2880240216, 2471224067, 1428173050, 4138563181, 2441661558, 636813900, 4233094615, 3620022987, 2149987652, 2411029155, 1239331162, 1730525723, 2554718734, 3781033664, 46346101, 310463728, 2743944855, 3328955385, 3875770207, 2501218972, 3955191162, 3667219033, 768917123, 3545789473, 692707433, 1150208456, 1786102409, 2029293177, 1805211710, 3710368113, 3065962831, 401639597, 1724457132, 3028143674, 409198410, 2196052529, 1620529459, 1164071807, 3769721975, 2226875310, 486441376, 2499348523, 1483753576, 428819965, 2274680428, 3075636216, 598438867, 3799141122, 1474502543, 711349675, 129166120, 53458370, 2592523643, 2782082824, 4063242375, 2988687269, 3120694122, 1559041666, 730517276, 2460449204, 4042459122, 2706270690, 3446004468, 3573941694, 533804130, 2328143614, 2637442643, 2695033685, 839224033, 1973745387, 957055980, 2856345839, 106852767, 1371368976, 4181598602, 1033297158, 2933734917, 1179510461, 3046200461, 91341917, 1862534868, 4284502037, 605657339, 2547432937, 3431546947, 2003294622, 3182487618, 2282195339, 954669403, 3682191598, 1201765386, 3917234703, 3388507166, 0, 2198438022, 1211247597, 2887651696, 1315723890, 4227665663, 1443857720, 507358933, 657861945, 1678381017, 560487590, 3516619604, 975451694, 2970356327, 261314535, 3535072918, 2652609425, 1333838021, 2724322336, 1767536459, 370938394, 182621114, 3854606378, 1128014560, 487725847, 185469197, 2918353863, 3106780840, 3356761769, 2237133081, 1286567175, 3152976349, 4255350624, 2683765030, 3160175349, 3309594171, 878443390, 1988838185, 3704300486, 1756818940, 1673061617, 3403100636, 272786309, 1075025698, 545572369, 2105887268, 4174560061, 296679730, 1841768865, 1260232239, 4091327024, 3960309330, 3497509347, 1814803222, 2578018489, 4195456072, 575138148, 3299409036, 446754879, 3629546796, 4011996048, 3347532110, 3252238545, 4270639778, 915985419, 3483825537, 681933534, 651868046, 2755636671, 3828103837, 223377554, 2607439820, 1649704518, 3270937875, 3901806776, 1580087799, 4118987695, 3198115200, 2087309459, 2842678573, 3016697106, 1003007129, 2802849917, 1860738147, 2077965243, 164439672, 4100872472, 32283319, 2827177882, 1709610350, 2125135846, 136428751, 3874428392, 3652904859, 3460984630, 3572145929, 3593056380, 2939266226, 824852259, 818324884, 3224740454, 930369212, 2801566410, 2967507152, 355706840, 1257309336, 4148292826, 243256656, 790073846, 2373340630, 1296297904, 1422699085, 3756299780, 3818836405, 457992840, 3099667487, 2135319889, 77422314, 1560382517, 1945798516, 788204353, 1521706781, 1385356242, 870912086, 325965383, 2358957921, 2050466060, 2388260884, 2313884476, 4006521127, 901210569, 3990953189, 1014646705, 1503449823, 1062597235, 2031621326, 3212035895, 3931371469, 1533017514, 350174575, 2256028891, 2177544179, 1052338372, 741876788, 1606591296, 1914052035, 213705253, 2334669897, 1107234197, 1899603969, 3725069491, 2631447780, 2422494913, 1635502980, 1893020342, 1950903388, 1120974935];
6333 var T7 = [2807058932, 1699970625, 2764249623, 1586903591, 1808481195, 1173430173, 1487645946, 59984867, 4199882800, 1844882806, 1989249228, 1277555970, 3623636965, 3419915562, 1149249077, 2744104290, 1514790577, 459744698, 244860394, 3235995134, 1963115311, 4027744588, 2544078150, 4190530515, 1608975247, 2627016082, 2062270317, 1507497298, 2200818878, 567498868, 1764313568, 3359936201, 2305455554, 2037970062, 1047239e3, 1910319033, 1337376481, 2904027272, 2892417312, 984907214, 1243112415, 830661914, 861968209, 2135253587, 2011214180, 2927934315, 2686254721, 731183368, 1750626376, 4246310725, 1820824798, 4172763771, 3542330227, 48394827, 2404901663, 2871682645, 671593195, 3254988725, 2073724613, 145085239, 2280796200, 2779915199, 1790575107, 2187128086, 472615631, 3029510009, 4075877127, 3802222185, 4107101658, 3201631749, 1646252340, 4270507174, 1402811438, 1436590835, 3778151818, 3950355702, 3963161475, 4020912224, 2667994737, 273792366, 2331590177, 104699613, 95345982, 3175501286, 2377486676, 1560637892, 3564045318, 369057872, 4213447064, 3919042237, 1137477952, 2658625497, 1119727848, 2340947849, 1530455833, 4007360968, 172466556, 266959938, 516552836, 0, 2256734592, 3980931627, 1890328081, 1917742170, 4294704398, 945164165, 3575528878, 958871085, 3647212047, 2787207260, 1423022939, 775562294, 1739656202, 3876557655, 2530391278, 2443058075, 3310321856, 547512796, 1265195639, 437656594, 3121275539, 719700128, 3762502690, 387781147, 218828297, 3350065803, 2830708150, 2848461854, 428169201, 122466165, 3720081049, 1627235199, 648017665, 4122762354, 1002783846, 2117360635, 695634755, 3336358691, 4234721005, 4049844452, 3704280881, 2232435299, 574624663, 287343814, 612205898, 1039717051, 840019705, 2708326185, 793451934, 821288114, 1391201670, 3822090177, 376187827, 3113855344, 1224348052, 1679968233, 2361698556, 1058709744, 752375421, 2431590963, 1321699145, 3519142200, 2734591178, 188127444, 2177869557, 3727205754, 2384911031, 3215212461, 2648976442, 2450346104, 3432737375, 1180849278, 331544205, 3102249176, 4150144569, 2952102595, 2159976285, 2474404304, 766078933, 313773861, 2570832044, 2108100632, 1668212892, 3145456443, 2013908262, 418672217, 3070356634, 2594734927, 1852171925, 3867060991, 3473416636, 3907448597, 2614737639, 919489135, 164948639, 2094410160, 2997825956, 590424639, 2486224549, 1723872674, 3157750862, 3399941250, 3501252752, 3625268135, 2555048196, 3673637356, 1343127501, 4130281361, 3599595085, 2957853679, 1297403050, 81781910, 3051593425, 2283490410, 532201772, 1367295589, 3926170974, 895287692, 1953757831, 1093597963, 492483431, 3528626907, 1446242576, 1192455638, 1636604631, 209336225, 344873464, 1015671571, 669961897, 3375740769, 3857572124, 2973530695, 3747192018, 1933530610, 3464042516, 935293895, 3454686199, 2858115069, 1863638845, 3683022916, 4085369519, 3292445032, 875313188, 1080017571, 3279033885, 621591778, 1233856572, 2504130317, 24197544, 3017672716, 3835484340, 3247465558, 2220981195, 3060847922, 1551124588, 1463996600];
6334 var T8 = [4104605777, 1097159550, 396673818, 660510266, 2875968315, 2638606623, 4200115116, 3808662347, 821712160, 1986918061, 3430322568, 38544885, 3856137295, 718002117, 893681702, 1654886325, 2975484382, 3122358053, 3926825029, 4274053469, 796197571, 1290801793, 1184342925, 3556361835, 2405426947, 2459735317, 1836772287, 1381620373, 3196267988, 1948373848, 3764988233, 3385345166, 3263785589, 2390325492, 1480485785, 3111247143, 3780097726, 2293045232, 548169417, 3459953789, 3746175075, 439452389, 1362321559, 1400849762, 1685577905, 1806599355, 2174754046, 137073913, 1214797936, 1174215055, 3731654548, 2079897426, 1943217067, 1258480242, 529487843, 1437280870, 3945269170, 3049390895, 3313212038, 923313619, 679998e3, 3215307299, 57326082, 377642221, 3474729866, 2041877159, 133361907, 1776460110, 3673476453, 96392454, 878845905, 2801699524, 777231668, 4082475170, 2330014213, 4142626212, 2213296395, 1626319424, 1906247262, 1846563261, 562755902, 3708173718, 1040559837, 3871163981, 1418573201, 3294430577, 114585348, 1343618912, 2566595609, 3186202582, 1078185097, 3651041127, 3896688048, 2307622919, 425408743, 3371096953, 2081048481, 1108339068, 2216610296, 0, 2156299017, 736970802, 292596766, 1517440620, 251657213, 2235061775, 2933202493, 758720310, 265905162, 1554391400, 1532285339, 908999204, 174567692, 1474760595, 4002861748, 2610011675, 3234156416, 3693126241, 2001430874, 303699484, 2478443234, 2687165888, 585122620, 454499602, 151849742, 2345119218, 3064510765, 514443284, 4044981591, 1963412655, 2581445614, 2137062819, 19308535, 1928707164, 1715193156, 4219352155, 1126790795, 600235211, 3992742070, 3841024952, 836553431, 1669664834, 2535604243, 3323011204, 1243905413, 3141400786, 4180808110, 698445255, 2653899549, 2989552604, 2253581325, 3252932727, 3004591147, 1891211689, 2487810577, 3915653703, 4237083816, 4030667424, 2100090966, 865136418, 1229899655, 953270745, 3399679628, 3557504664, 4118925222, 2061379749, 3079546586, 2915017791, 983426092, 2022837584, 1607244650, 2118541908, 2366882550, 3635996816, 972512814, 3283088770, 1568718495, 3499326569, 3576539503, 621982671, 2895723464, 410887952, 2623762152, 1002142683, 645401037, 1494807662, 2595684844, 1335535747, 2507040230, 4293295786, 3167684641, 367585007, 3885750714, 1865862730, 2668221674, 2960971305, 2763173681, 1059270954, 2777952454, 2724642869, 1320957812, 2194319100, 2429595872, 2815956275, 77089521, 3973773121, 3444575871, 2448830231, 1305906550, 4021308739, 2857194700, 2516901860, 3518358430, 1787304780, 740276417, 1699839814, 1592394909, 2352307457, 2272556026, 188821243, 1729977011, 3687994002, 274084841, 3594982253, 3613494426, 2701949495, 4162096729, 322734571, 2837966542, 1640576439, 484830689, 1202797690, 3537852828, 4067639125, 349075736, 3342319475, 4157467219, 4255800159, 1030690015, 1155237496, 2951971274, 1757691577, 607398968, 2738905026, 499347990, 3794078908, 1011452712, 227885567, 2818666809, 213114376, 3034881240, 1455525988, 3414450555, 850817237, 1817998408, 3092726480];
6335 var U1 = [0, 235474187, 470948374, 303765277, 941896748, 908933415, 607530554, 708780849, 1883793496, 2118214995, 1817866830, 1649639237, 1215061108, 1181045119, 1417561698, 1517767529, 3767586992, 4003061179, 4236429990, 4069246893, 3635733660, 3602770327, 3299278474, 3400528769, 2430122216, 2664543715, 2362090238, 2193862645, 2835123396, 2801107407, 3035535058, 3135740889, 3678124923, 3576870512, 3341394285, 3374361702, 3810496343, 3977675356, 4279080257, 4043610186, 2876494627, 2776292904, 3076639029, 3110650942, 2472011535, 2640243204, 2403728665, 2169303058, 1001089995, 899835584, 666464733, 699432150, 59727847, 226906860, 530400753, 294930682, 1273168787, 1172967064, 1475418501, 1509430414, 1942435775, 2110667444, 1876241833, 1641816226, 2910219766, 2743034109, 2976151520, 3211623147, 2505202138, 2606453969, 2302690252, 2269728455, 3711829422, 3543599269, 3240894392, 3475313331, 3843699074, 3943906441, 4178062228, 4144047775, 1306967366, 1139781709, 1374988112, 1610459739, 1975683434, 2076935265, 1775276924, 1742315127, 1034867998, 866637845, 566021896, 800440835, 92987698, 193195065, 429456164, 395441711, 1984812685, 2017778566, 1784663195, 1683407248, 1315562145, 1080094634, 1383856311, 1551037884, 101039829, 135050206, 437757123, 337553864, 1042385657, 807962610, 573804783, 742039012, 2531067453, 2564033334, 2328828971, 2227573024, 2935566865, 2700099354, 3001755655, 3168937228, 3868552805, 3902563182, 4203181171, 4102977912, 3736164937, 3501741890, 3265478751, 3433712980, 1106041591, 1340463100, 1576976609, 1408749034, 2043211483, 2009195472, 1708848333, 1809054150, 832877231, 1068351396, 766945465, 599762354, 159417987, 126454664, 361929877, 463180190, 2709260871, 2943682380, 3178106961, 3009879386, 2572697195, 2538681184, 2236228733, 2336434550, 3509871135, 3745345300, 3441850377, 3274667266, 3910161971, 3877198648, 4110568485, 4211818798, 2597806476, 2497604743, 2261089178, 2295101073, 2733856160, 2902087851, 3202437046, 2968011453, 3936291284, 3835036895, 4136440770, 4169408201, 3535486456, 3702665459, 3467192302, 3231722213, 2051518780, 1951317047, 1716890410, 1750902305, 1113818384, 1282050075, 1584504582, 1350078989, 168810852, 67556463, 371049330, 404016761, 841739592, 1008918595, 775550814, 540080725, 3969562369, 3801332234, 4035489047, 4269907996, 3569255213, 3669462566, 3366754619, 3332740144, 2631065433, 2463879762, 2160117071, 2395588676, 2767645557, 2868897406, 3102011747, 3069049960, 202008497, 33778362, 270040487, 504459436, 875451293, 975658646, 675039627, 641025152, 2084704233, 1917518562, 1615861247, 1851332852, 1147550661, 1248802510, 1484005843, 1451044056, 933301370, 967311729, 733156972, 632953703, 260388950, 25965917, 328671808, 496906059, 1206477858, 1239443753, 1543208500, 1441952575, 2144161806, 1908694277, 1675577880, 1842759443, 3610369226, 3644379585, 3408119516, 3307916247, 4011190502, 3776767469, 4077384432, 4245618683, 2809771154, 2842737049, 3144396420, 3043140495, 2673705150, 2438237621, 2203032232, 2370213795];
6336 var U2 = [0, 185469197, 370938394, 487725847, 741876788, 657861945, 975451694, 824852259, 1483753576, 1400783205, 1315723890, 1164071807, 1950903388, 2135319889, 1649704518, 1767536459, 2967507152, 3152976349, 2801566410, 2918353863, 2631447780, 2547432937, 2328143614, 2177544179, 3901806776, 3818836405, 4270639778, 4118987695, 3299409036, 3483825537, 3535072918, 3652904859, 2077965243, 1893020342, 1841768865, 1724457132, 1474502543, 1559041666, 1107234197, 1257309336, 598438867, 681933534, 901210569, 1052338372, 261314535, 77422314, 428819965, 310463728, 3409685355, 3224740454, 3710368113, 3593056380, 3875770207, 3960309330, 4045380933, 4195456072, 2471224067, 2554718734, 2237133081, 2388260884, 3212035895, 3028143674, 2842678573, 2724322336, 4138563181, 4255350624, 3769721975, 3955191162, 3667219033, 3516619604, 3431546947, 3347532110, 2933734917, 2782082824, 3099667487, 3016697106, 2196052529, 2313884476, 2499348523, 2683765030, 1179510461, 1296297904, 1347548327, 1533017514, 1786102409, 1635502980, 2087309459, 2003294622, 507358933, 355706840, 136428751, 53458370, 839224033, 957055980, 605657339, 790073846, 2373340630, 2256028891, 2607439820, 2422494913, 2706270690, 2856345839, 3075636216, 3160175349, 3573941694, 3725069491, 3273267108, 3356761769, 4181598602, 4063242375, 4011996048, 3828103837, 1033297158, 915985419, 730517276, 545572369, 296679730, 446754879, 129166120, 213705253, 1709610350, 1860738147, 1945798516, 2029293177, 1239331162, 1120974935, 1606591296, 1422699085, 4148292826, 4233094615, 3781033664, 3931371469, 3682191598, 3497509347, 3446004468, 3328955385, 2939266226, 2755636671, 3106780840, 2988687269, 2198438022, 2282195339, 2501218972, 2652609425, 1201765386, 1286567175, 1371368976, 1521706781, 1805211710, 1620529459, 2105887268, 1988838185, 533804130, 350174575, 164439672, 46346101, 870912086, 954669403, 636813900, 788204353, 2358957921, 2274680428, 2592523643, 2441661558, 2695033685, 2880240216, 3065962831, 3182487618, 3572145929, 3756299780, 3270937875, 3388507166, 4174560061, 4091327024, 4006521127, 3854606378, 1014646705, 930369212, 711349675, 560487590, 272786309, 457992840, 106852767, 223377554, 1678381017, 1862534868, 1914052035, 2031621326, 1211247597, 1128014560, 1580087799, 1428173050, 32283319, 182621114, 401639597, 486441376, 768917123, 651868046, 1003007129, 818324884, 1503449823, 1385356242, 1333838021, 1150208456, 1973745387, 2125135846, 1673061617, 1756818940, 2970356327, 3120694122, 2802849917, 2887651696, 2637442643, 2520393566, 2334669897, 2149987652, 3917234703, 3799141122, 4284502037, 4100872472, 3309594171, 3460984630, 3545789473, 3629546796, 2050466060, 1899603969, 1814803222, 1730525723, 1443857720, 1560382517, 1075025698, 1260232239, 575138148, 692707433, 878443390, 1062597235, 243256656, 91341917, 409198410, 325965383, 3403100636, 3252238545, 3704300486, 3620022987, 3874428392, 3990953189, 4042459122, 4227665663, 2460449204, 2578018489, 2226875310, 2411029155, 3198115200, 3046200461, 2827177882, 2743944855];
6337 var U3 = [0, 218828297, 437656594, 387781147, 875313188, 958871085, 775562294, 590424639, 1750626376, 1699970625, 1917742170, 2135253587, 1551124588, 1367295589, 1180849278, 1265195639, 3501252752, 3720081049, 3399941250, 3350065803, 3835484340, 3919042237, 4270507174, 4085369519, 3102249176, 3051593425, 2734591178, 2952102595, 2361698556, 2177869557, 2530391278, 2614737639, 3145456443, 3060847922, 2708326185, 2892417312, 2404901663, 2187128086, 2504130317, 2555048196, 3542330227, 3727205754, 3375740769, 3292445032, 3876557655, 3926170974, 4246310725, 4027744588, 1808481195, 1723872674, 1910319033, 2094410160, 1608975247, 1391201670, 1173430173, 1224348052, 59984867, 244860394, 428169201, 344873464, 935293895, 984907214, 766078933, 547512796, 1844882806, 1627235199, 2011214180, 2062270317, 1507497298, 1423022939, 1137477952, 1321699145, 95345982, 145085239, 532201772, 313773861, 830661914, 1015671571, 731183368, 648017665, 3175501286, 2957853679, 2807058932, 2858115069, 2305455554, 2220981195, 2474404304, 2658625497, 3575528878, 3625268135, 3473416636, 3254988725, 3778151818, 3963161475, 4213447064, 4130281361, 3599595085, 3683022916, 3432737375, 3247465558, 3802222185, 4020912224, 4172763771, 4122762354, 3201631749, 3017672716, 2764249623, 2848461854, 2331590177, 2280796200, 2431590963, 2648976442, 104699613, 188127444, 472615631, 287343814, 840019705, 1058709744, 671593195, 621591778, 1852171925, 1668212892, 1953757831, 2037970062, 1514790577, 1463996600, 1080017571, 1297403050, 3673637356, 3623636965, 3235995134, 3454686199, 4007360968, 3822090177, 4107101658, 4190530515, 2997825956, 3215212461, 2830708150, 2779915199, 2256734592, 2340947849, 2627016082, 2443058075, 172466556, 122466165, 273792366, 492483431, 1047239e3, 861968209, 612205898, 695634755, 1646252340, 1863638845, 2013908262, 1963115311, 1446242576, 1530455833, 1277555970, 1093597963, 1636604631, 1820824798, 2073724613, 1989249228, 1436590835, 1487645946, 1337376481, 1119727848, 164948639, 81781910, 331544205, 516552836, 1039717051, 821288114, 669961897, 719700128, 2973530695, 3157750862, 2871682645, 2787207260, 2232435299, 2283490410, 2667994737, 2450346104, 3647212047, 3564045318, 3279033885, 3464042516, 3980931627, 3762502690, 4150144569, 4199882800, 3070356634, 3121275539, 2904027272, 2686254721, 2200818878, 2384911031, 2570832044, 2486224549, 3747192018, 3528626907, 3310321856, 3359936201, 3950355702, 3867060991, 4049844452, 4234721005, 1739656202, 1790575107, 2108100632, 1890328081, 1402811438, 1586903591, 1233856572, 1149249077, 266959938, 48394827, 369057872, 418672217, 1002783846, 919489135, 567498868, 752375421, 209336225, 24197544, 376187827, 459744698, 945164165, 895287692, 574624663, 793451934, 1679968233, 1764313568, 2117360635, 1933530610, 1343127501, 1560637892, 1243112415, 1192455638, 3704280881, 3519142200, 3336358691, 3419915562, 3907448597, 3857572124, 4075877127, 4294704398, 3029510009, 3113855344, 2927934315, 2744104290, 2159976285, 2377486676, 2594734927, 2544078150];
6338 var U4 = [0, 151849742, 303699484, 454499602, 607398968, 758720310, 908999204, 1059270954, 1214797936, 1097159550, 1517440620, 1400849762, 1817998408, 1699839814, 2118541908, 2001430874, 2429595872, 2581445614, 2194319100, 2345119218, 3034881240, 3186202582, 2801699524, 2951971274, 3635996816, 3518358430, 3399679628, 3283088770, 4237083816, 4118925222, 4002861748, 3885750714, 1002142683, 850817237, 698445255, 548169417, 529487843, 377642221, 227885567, 77089521, 1943217067, 2061379749, 1640576439, 1757691577, 1474760595, 1592394909, 1174215055, 1290801793, 2875968315, 2724642869, 3111247143, 2960971305, 2405426947, 2253581325, 2638606623, 2487810577, 3808662347, 3926825029, 4044981591, 4162096729, 3342319475, 3459953789, 3576539503, 3693126241, 1986918061, 2137062819, 1685577905, 1836772287, 1381620373, 1532285339, 1078185097, 1229899655, 1040559837, 923313619, 740276417, 621982671, 439452389, 322734571, 137073913, 19308535, 3871163981, 4021308739, 4104605777, 4255800159, 3263785589, 3414450555, 3499326569, 3651041127, 2933202493, 2815956275, 3167684641, 3049390895, 2330014213, 2213296395, 2566595609, 2448830231, 1305906550, 1155237496, 1607244650, 1455525988, 1776460110, 1626319424, 2079897426, 1928707164, 96392454, 213114376, 396673818, 514443284, 562755902, 679998e3, 865136418, 983426092, 3708173718, 3557504664, 3474729866, 3323011204, 4180808110, 4030667424, 3945269170, 3794078908, 2507040230, 2623762152, 2272556026, 2390325492, 2975484382, 3092726480, 2738905026, 2857194700, 3973773121, 3856137295, 4274053469, 4157467219, 3371096953, 3252932727, 3673476453, 3556361835, 2763173681, 2915017791, 3064510765, 3215307299, 2156299017, 2307622919, 2459735317, 2610011675, 2081048481, 1963412655, 1846563261, 1729977011, 1480485785, 1362321559, 1243905413, 1126790795, 878845905, 1030690015, 645401037, 796197571, 274084841, 425408743, 38544885, 188821243, 3613494426, 3731654548, 3313212038, 3430322568, 4082475170, 4200115116, 3780097726, 3896688048, 2668221674, 2516901860, 2366882550, 2216610296, 3141400786, 2989552604, 2837966542, 2687165888, 1202797690, 1320957812, 1437280870, 1554391400, 1669664834, 1787304780, 1906247262, 2022837584, 265905162, 114585348, 499347990, 349075736, 736970802, 585122620, 972512814, 821712160, 2595684844, 2478443234, 2293045232, 2174754046, 3196267988, 3079546586, 2895723464, 2777952454, 3537852828, 3687994002, 3234156416, 3385345166, 4142626212, 4293295786, 3841024952, 3992742070, 174567692, 57326082, 410887952, 292596766, 777231668, 660510266, 1011452712, 893681702, 1108339068, 1258480242, 1343618912, 1494807662, 1715193156, 1865862730, 1948373848, 2100090966, 2701949495, 2818666809, 3004591147, 3122358053, 2235061775, 2352307457, 2535604243, 2653899549, 3915653703, 3764988233, 4219352155, 4067639125, 3444575871, 3294430577, 3746175075, 3594982253, 836553431, 953270745, 600235211, 718002117, 367585007, 484830689, 133361907, 251657213, 2041877159, 1891211689, 1806599355, 1654886325, 1568718495, 1418573201, 1335535747, 1184342925];
6339 function convertToInt32(bytes) {
6341 for (var i2 = 0; i2 < bytes.length; i2 += 4) {
6343 bytes[i2] << 24 | bytes[i2 + 1] << 16 | bytes[i2 + 2] << 8 | bytes[i2 + 3]
6348 var AES = function(key) {
6349 if (!(this instanceof AES)) {
6350 throw Error("AES must be instanitated with `new`");
6352 Object.defineProperty(this, "key", {
6353 value: coerceArray(key, true)
6357 AES.prototype._prepare = function() {
6358 var rounds = numberOfRounds[this.key.length];
6359 if (rounds == null) {
6360 throw new Error("invalid key size (must be 16, 24 or 32 bytes)");
6364 for (var i2 = 0; i2 <= rounds; i2++) {
6365 this._Ke.push([0, 0, 0, 0]);
6366 this._Kd.push([0, 0, 0, 0]);
6368 var roundKeyCount = (rounds + 1) * 4;
6369 var KC = this.key.length / 4;
6370 var tk = convertToInt32(this.key);
6372 for (var i2 = 0; i2 < KC; i2++) {
6374 this._Ke[index][i2 % 4] = tk[i2];
6375 this._Kd[rounds - index][i2 % 4] = tk[i2];
6377 var rconpointer = 0;
6379 while (t < roundKeyCount) {
6381 tk[0] ^= S[tt >> 16 & 255] << 24 ^ S[tt >> 8 & 255] << 16 ^ S[tt & 255] << 8 ^ S[tt >> 24 & 255] ^ rcon[rconpointer] << 24;
6384 for (var i2 = 1; i2 < KC; i2++) {
6385 tk[i2] ^= tk[i2 - 1];
6388 for (var i2 = 1; i2 < KC / 2; i2++) {
6389 tk[i2] ^= tk[i2 - 1];
6391 tt = tk[KC / 2 - 1];
6392 tk[KC / 2] ^= S[tt & 255] ^ S[tt >> 8 & 255] << 8 ^ S[tt >> 16 & 255] << 16 ^ S[tt >> 24 & 255] << 24;
6393 for (var i2 = KC / 2 + 1; i2 < KC; i2++) {
6394 tk[i2] ^= tk[i2 - 1];
6398 while (i2 < KC && t < roundKeyCount) {
6401 this._Ke[r][c] = tk[i2];
6402 this._Kd[rounds - r][c] = tk[i2++];
6406 for (var r = 1; r < rounds; r++) {
6407 for (var c = 0; c < 4; c++) {
6408 tt = this._Kd[r][c];
6409 this._Kd[r][c] = U1[tt >> 24 & 255] ^ U2[tt >> 16 & 255] ^ U3[tt >> 8 & 255] ^ U4[tt & 255];
6413 AES.prototype.encrypt = function(plaintext) {
6414 if (plaintext.length != 16) {
6415 throw new Error("invalid plaintext size (must be 16 bytes)");
6417 var rounds = this._Ke.length - 1;
6418 var a = [0, 0, 0, 0];
6419 var t = convertToInt32(plaintext);
6420 for (var i2 = 0; i2 < 4; i2++) {
6421 t[i2] ^= this._Ke[0][i2];
6423 for (var r = 1; r < rounds; r++) {
6424 for (var i2 = 0; i2 < 4; i2++) {
6425 a[i2] = T1[t[i2] >> 24 & 255] ^ T2[t[(i2 + 1) % 4] >> 16 & 255] ^ T3[t[(i2 + 2) % 4] >> 8 & 255] ^ T4[t[(i2 + 3) % 4] & 255] ^ this._Ke[r][i2];
6429 var result = createArray(16), tt;
6430 for (var i2 = 0; i2 < 4; i2++) {
6431 tt = this._Ke[rounds][i2];
6432 result[4 * i2] = (S[t[i2] >> 24 & 255] ^ tt >> 24) & 255;
6433 result[4 * i2 + 1] = (S[t[(i2 + 1) % 4] >> 16 & 255] ^ tt >> 16) & 255;
6434 result[4 * i2 + 2] = (S[t[(i2 + 2) % 4] >> 8 & 255] ^ tt >> 8) & 255;
6435 result[4 * i2 + 3] = (S[t[(i2 + 3) % 4] & 255] ^ tt) & 255;
6439 AES.prototype.decrypt = function(ciphertext) {
6440 if (ciphertext.length != 16) {
6441 throw new Error("invalid ciphertext size (must be 16 bytes)");
6443 var rounds = this._Kd.length - 1;
6444 var a = [0, 0, 0, 0];
6445 var t = convertToInt32(ciphertext);
6446 for (var i2 = 0; i2 < 4; i2++) {
6447 t[i2] ^= this._Kd[0][i2];
6449 for (var r = 1; r < rounds; r++) {
6450 for (var i2 = 0; i2 < 4; i2++) {
6451 a[i2] = T5[t[i2] >> 24 & 255] ^ T6[t[(i2 + 3) % 4] >> 16 & 255] ^ T7[t[(i2 + 2) % 4] >> 8 & 255] ^ T8[t[(i2 + 1) % 4] & 255] ^ this._Kd[r][i2];
6455 var result = createArray(16), tt;
6456 for (var i2 = 0; i2 < 4; i2++) {
6457 tt = this._Kd[rounds][i2];
6458 result[4 * i2] = (Si[t[i2] >> 24 & 255] ^ tt >> 24) & 255;
6459 result[4 * i2 + 1] = (Si[t[(i2 + 3) % 4] >> 16 & 255] ^ tt >> 16) & 255;
6460 result[4 * i2 + 2] = (Si[t[(i2 + 2) % 4] >> 8 & 255] ^ tt >> 8) & 255;
6461 result[4 * i2 + 3] = (Si[t[(i2 + 1) % 4] & 255] ^ tt) & 255;
6465 var ModeOfOperationECB = function(key) {
6466 if (!(this instanceof ModeOfOperationECB)) {
6467 throw Error("AES must be instanitated with `new`");
6469 this.description = "Electronic Code Block";
6471 this._aes = new AES(key);
6473 ModeOfOperationECB.prototype.encrypt = function(plaintext) {
6474 plaintext = coerceArray(plaintext);
6475 if (plaintext.length % 16 !== 0) {
6476 throw new Error("invalid plaintext size (must be multiple of 16 bytes)");
6478 var ciphertext = createArray(plaintext.length);
6479 var block2 = createArray(16);
6480 for (var i2 = 0; i2 < plaintext.length; i2 += 16) {
6481 copyArray(plaintext, block2, 0, i2, i2 + 16);
6482 block2 = this._aes.encrypt(block2);
6483 copyArray(block2, ciphertext, i2);
6487 ModeOfOperationECB.prototype.decrypt = function(ciphertext) {
6488 ciphertext = coerceArray(ciphertext);
6489 if (ciphertext.length % 16 !== 0) {
6490 throw new Error("invalid ciphertext size (must be multiple of 16 bytes)");
6492 var plaintext = createArray(ciphertext.length);
6493 var block2 = createArray(16);
6494 for (var i2 = 0; i2 < ciphertext.length; i2 += 16) {
6495 copyArray(ciphertext, block2, 0, i2, i2 + 16);
6496 block2 = this._aes.decrypt(block2);
6497 copyArray(block2, plaintext, i2);
6501 var ModeOfOperationCBC = function(key, iv) {
6502 if (!(this instanceof ModeOfOperationCBC)) {
6503 throw Error("AES must be instanitated with `new`");
6505 this.description = "Cipher Block Chaining";
6508 iv = createArray(16);
6509 } else if (iv.length != 16) {
6510 throw new Error("invalid initialation vector size (must be 16 bytes)");
6512 this._lastCipherblock = coerceArray(iv, true);
6513 this._aes = new AES(key);
6515 ModeOfOperationCBC.prototype.encrypt = function(plaintext) {
6516 plaintext = coerceArray(plaintext);
6517 if (plaintext.length % 16 !== 0) {
6518 throw new Error("invalid plaintext size (must be multiple of 16 bytes)");
6520 var ciphertext = createArray(plaintext.length);
6521 var block2 = createArray(16);
6522 for (var i2 = 0; i2 < plaintext.length; i2 += 16) {
6523 copyArray(plaintext, block2, 0, i2, i2 + 16);
6524 for (var j2 = 0; j2 < 16; j2++) {
6525 block2[j2] ^= this._lastCipherblock[j2];
6527 this._lastCipherblock = this._aes.encrypt(block2);
6528 copyArray(this._lastCipherblock, ciphertext, i2);
6532 ModeOfOperationCBC.prototype.decrypt = function(ciphertext) {
6533 ciphertext = coerceArray(ciphertext);
6534 if (ciphertext.length % 16 !== 0) {
6535 throw new Error("invalid ciphertext size (must be multiple of 16 bytes)");
6537 var plaintext = createArray(ciphertext.length);
6538 var block2 = createArray(16);
6539 for (var i2 = 0; i2 < ciphertext.length; i2 += 16) {
6540 copyArray(ciphertext, block2, 0, i2, i2 + 16);
6541 block2 = this._aes.decrypt(block2);
6542 for (var j2 = 0; j2 < 16; j2++) {
6543 plaintext[i2 + j2] = block2[j2] ^ this._lastCipherblock[j2];
6545 copyArray(ciphertext, this._lastCipherblock, 0, i2, i2 + 16);
6549 var ModeOfOperationCFB = function(key, iv, segmentSize) {
6550 if (!(this instanceof ModeOfOperationCFB)) {
6551 throw Error("AES must be instanitated with `new`");
6553 this.description = "Cipher Feedback";
6556 iv = createArray(16);
6557 } else if (iv.length != 16) {
6558 throw new Error("invalid initialation vector size (must be 16 size)");
6563 this.segmentSize = segmentSize;
6564 this._shiftRegister = coerceArray(iv, true);
6565 this._aes = new AES(key);
6567 ModeOfOperationCFB.prototype.encrypt = function(plaintext) {
6568 if (plaintext.length % this.segmentSize != 0) {
6569 throw new Error("invalid plaintext size (must be segmentSize bytes)");
6571 var encrypted = coerceArray(plaintext, true);
6573 for (var i2 = 0; i2 < encrypted.length; i2 += this.segmentSize) {
6574 xorSegment = this._aes.encrypt(this._shiftRegister);
6575 for (var j2 = 0; j2 < this.segmentSize; j2++) {
6576 encrypted[i2 + j2] ^= xorSegment[j2];
6578 copyArray(this._shiftRegister, this._shiftRegister, 0, this.segmentSize);
6579 copyArray(encrypted, this._shiftRegister, 16 - this.segmentSize, i2, i2 + this.segmentSize);
6583 ModeOfOperationCFB.prototype.decrypt = function(ciphertext) {
6584 if (ciphertext.length % this.segmentSize != 0) {
6585 throw new Error("invalid ciphertext size (must be segmentSize bytes)");
6587 var plaintext = coerceArray(ciphertext, true);
6589 for (var i2 = 0; i2 < plaintext.length; i2 += this.segmentSize) {
6590 xorSegment = this._aes.encrypt(this._shiftRegister);
6591 for (var j2 = 0; j2 < this.segmentSize; j2++) {
6592 plaintext[i2 + j2] ^= xorSegment[j2];
6594 copyArray(this._shiftRegister, this._shiftRegister, 0, this.segmentSize);
6595 copyArray(ciphertext, this._shiftRegister, 16 - this.segmentSize, i2, i2 + this.segmentSize);
6599 var ModeOfOperationOFB = function(key, iv) {
6600 if (!(this instanceof ModeOfOperationOFB)) {
6601 throw Error("AES must be instanitated with `new`");
6603 this.description = "Output Feedback";
6606 iv = createArray(16);
6607 } else if (iv.length != 16) {
6608 throw new Error("invalid initialation vector size (must be 16 bytes)");
6610 this._lastPrecipher = coerceArray(iv, true);
6611 this._lastPrecipherIndex = 16;
6612 this._aes = new AES(key);
6614 ModeOfOperationOFB.prototype.encrypt = function(plaintext) {
6615 var encrypted = coerceArray(plaintext, true);
6616 for (var i2 = 0; i2 < encrypted.length; i2++) {
6617 if (this._lastPrecipherIndex === 16) {
6618 this._lastPrecipher = this._aes.encrypt(this._lastPrecipher);
6619 this._lastPrecipherIndex = 0;
6621 encrypted[i2] ^= this._lastPrecipher[this._lastPrecipherIndex++];
6625 ModeOfOperationOFB.prototype.decrypt = ModeOfOperationOFB.prototype.encrypt;
6626 var Counter = function(initialValue) {
6627 if (!(this instanceof Counter)) {
6628 throw Error("Counter must be instanitated with `new`");
6630 if (initialValue !== 0 && !initialValue) {
6633 if (typeof initialValue === "number") {
6634 this._counter = createArray(16);
6635 this.setValue(initialValue);
6637 this.setBytes(initialValue);
6640 Counter.prototype.setValue = function(value) {
6641 if (typeof value !== "number" || parseInt(value) != value) {
6642 throw new Error("invalid counter value (must be an integer)");
6644 if (value > Number.MAX_SAFE_INTEGER) {
6645 throw new Error("integer value out of safe range");
6647 for (var index = 15; index >= 0; --index) {
6648 this._counter[index] = value % 256;
6649 value = parseInt(value / 256);
6652 Counter.prototype.setBytes = function(bytes) {
6653 bytes = coerceArray(bytes, true);
6654 if (bytes.length != 16) {
6655 throw new Error("invalid counter bytes size (must be 16 bytes)");
6657 this._counter = bytes;
6659 Counter.prototype.increment = function() {
6660 for (var i2 = 15; i2 >= 0; i2--) {
6661 if (this._counter[i2] === 255) {
6662 this._counter[i2] = 0;
6664 this._counter[i2]++;
6669 var ModeOfOperationCTR = function(key, counter) {
6670 if (!(this instanceof ModeOfOperationCTR)) {
6671 throw Error("AES must be instanitated with `new`");
6673 this.description = "Counter";
6675 if (!(counter instanceof Counter)) {
6676 counter = new Counter(counter);
6678 this._counter = counter;
6679 this._remainingCounter = null;
6680 this._remainingCounterIndex = 16;
6681 this._aes = new AES(key);
6683 ModeOfOperationCTR.prototype.encrypt = function(plaintext) {
6684 var encrypted = coerceArray(plaintext, true);
6685 for (var i2 = 0; i2 < encrypted.length; i2++) {
6686 if (this._remainingCounterIndex === 16) {
6687 this._remainingCounter = this._aes.encrypt(this._counter._counter);
6688 this._remainingCounterIndex = 0;
6689 this._counter.increment();
6691 encrypted[i2] ^= this._remainingCounter[this._remainingCounterIndex++];
6695 ModeOfOperationCTR.prototype.decrypt = ModeOfOperationCTR.prototype.encrypt;
6696 function pkcs7pad(data) {
6697 data = coerceArray(data, true);
6698 var padder = 16 - data.length % 16;
6699 var result = createArray(data.length + padder);
6700 copyArray(data, result);
6701 for (var i2 = data.length; i2 < result.length; i2++) {
6702 result[i2] = padder;
6706 function pkcs7strip(data) {
6707 data = coerceArray(data, true);
6708 if (data.length < 16) {
6709 throw new Error("PKCS#7 invalid length");
6711 var padder = data[data.length - 1];
6713 throw new Error("PKCS#7 padding byte out of range");
6715 var length = data.length - padder;
6716 for (var i2 = 0; i2 < padder; i2++) {
6717 if (data[length + i2] !== padder) {
6718 throw new Error("PKCS#7 invalid padding byte");
6721 var result = createArray(length);
6722 copyArray(data, result, 0, 0, length);
6729 ecb: ModeOfOperationECB,
6730 cbc: ModeOfOperationCBC,
6731 cfb: ModeOfOperationCFB,
6732 ofb: ModeOfOperationOFB,
6733 ctr: ModeOfOperationCTR
6751 if (typeof exports2 !== "undefined") {
6752 module2.exports = aesjs2;
6753 } else if (typeof define === "function" && define.amd) {
6754 define([], function() {
6759 aesjs2._aesjs = root3.aesjs;
6761 root3.aesjs = aesjs2;
6767 // node_modules/fast-deep-equal/index.js
6768 var require_fast_deep_equal = __commonJS({
6769 "node_modules/fast-deep-equal/index.js"(exports2, module2) {
6771 module2.exports = function equal(a, b) {
6774 if (a && b && typeof a == "object" && typeof b == "object") {
6775 if (a.constructor !== b.constructor)
6777 var length, i2, keys;
6778 if (Array.isArray(a)) {
6780 if (length != b.length)
6782 for (i2 = length; i2-- !== 0; )
6783 if (!equal(a[i2], b[i2]))
6787 if (a.constructor === RegExp)
6788 return a.source === b.source && a.flags === b.flags;
6789 if (a.valueOf !== Object.prototype.valueOf)
6790 return a.valueOf() === b.valueOf();
6791 if (a.toString !== Object.prototype.toString)
6792 return a.toString() === b.toString();
6793 keys = Object.keys(a);
6794 length = keys.length;
6795 if (length !== Object.keys(b).length)
6797 for (i2 = length; i2-- !== 0; )
6798 if (!Object.prototype.hasOwnProperty.call(b, keys[i2]))
6800 for (i2 = length; i2-- !== 0; ) {
6802 if (!equal(a[key], b[key]))
6807 return a !== a && b !== b;
6812 // node_modules/lodash/lodash.js
6813 var require_lodash = __commonJS({
6814 "node_modules/lodash/lodash.js"(exports2, module2) {
6817 var VERSION = "4.17.21";
6818 var LARGE_ARRAY_SIZE = 200;
6819 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`";
6820 var HASH_UNDEFINED = "__lodash_hash_undefined__";
6821 var MAX_MEMOIZE_SIZE = 500;
6822 var PLACEHOLDER = "__lodash_placeholder__";
6823 var CLONE_DEEP_FLAG = 1, CLONE_FLAT_FLAG = 2, CLONE_SYMBOLS_FLAG = 4;
6824 var COMPARE_PARTIAL_FLAG = 1, COMPARE_UNORDERED_FLAG = 2;
6825 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;
6826 var DEFAULT_TRUNC_LENGTH = 30, DEFAULT_TRUNC_OMISSION = "...";
6827 var HOT_COUNT = 800, HOT_SPAN = 16;
6828 var LAZY_FILTER_FLAG = 1, LAZY_MAP_FLAG = 2, LAZY_WHILE_FLAG = 3;
6829 var INFINITY2 = 1 / 0, MAX_SAFE_INTEGER = 9007199254740991, MAX_INTEGER = 17976931348623157e292, NAN2 = 0 / 0;
6830 var MAX_ARRAY_LENGTH = 4294967295, MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1, HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;
6832 ["ary", WRAP_ARY_FLAG],
6833 ["bind", WRAP_BIND_FLAG],
6834 ["bindKey", WRAP_BIND_KEY_FLAG],
6835 ["curry", WRAP_CURRY_FLAG],
6836 ["curryRight", WRAP_CURRY_RIGHT_FLAG],
6837 ["flip", WRAP_FLIP_FLAG],
6838 ["partial", WRAP_PARTIAL_FLAG],
6839 ["partialRight", WRAP_PARTIAL_RIGHT_FLAG],
6840 ["rearg", WRAP_REARG_FLAG]
6842 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]";
6843 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]";
6844 var reEmptyStringLeading = /\b__p \+= '';/g, reEmptyStringMiddle = /\b(__p \+=) '' \+/g, reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
6845 var reEscapedHtml2 = /&(?:amp|lt|gt|quot|#39);/g, reUnescapedHtml2 = /[&<>"']/g, reHasEscapedHtml2 = RegExp(reEscapedHtml2.source), reHasUnescapedHtml2 = RegExp(reUnescapedHtml2.source);
6846 var reEscape = /<%-([\s\S]+?)%>/g, reEvaluate = /<%([\s\S]+?)%>/g, reInterpolate = /<%=([\s\S]+?)%>/g;
6847 var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, reIsPlainProp = /^\w*$/, rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
6848 var reRegExpChar = /[\\^$.*+?()[\]{}|]/g, reHasRegExpChar = RegExp(reRegExpChar.source);
6849 var reTrimStart2 = /^\s+/;
6850 var reWhitespace2 = /\s/;
6851 var reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/, reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/, reSplitDetails = /,? & /;
6852 var reAsciiWord = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
6853 var reForbiddenIdentifierChars = /[()=,{}\[\]\/\s]/;
6854 var reEscapeChar = /\\(\\)?/g;
6855 var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
6856 var reFlags = /\w*$/;
6857 var reIsBadHex2 = /^[-+]0x[0-9a-f]+$/i;
6858 var reIsBinary2 = /^0b[01]+$/i;
6859 var reIsHostCtor = /^\[object .+?Constructor\]$/;
6860 var reIsOctal2 = /^0o[0-7]+$/i;
6861 var reIsUint = /^(?:0|[1-9]\d*)$/;
6862 var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g;
6863 var reNoMatch = /($^)/;
6864 var reUnescapedString = /['\n\r\u2028\u2029\\]/g;
6865 var rsAstralRange = "\\ud800-\\udfff", rsComboMarksRange = "\\u0300-\\u036f", reComboHalfMarksRange = "\\ufe20-\\ufe2f", rsComboSymbolsRange = "\\u20d0-\\u20ff", rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange, rsDingbatRange = "\\u2700-\\u27bf", rsLowerRange = "a-z\\xdf-\\xf6\\xf8-\\xff", rsMathOpRange = "\\xac\\xb1\\xd7\\xf7", rsNonCharRange = "\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf", rsPunctuationRange = "\\u2000-\\u206f", rsSpaceRange = " \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000", rsUpperRange = "A-Z\\xc0-\\xd6\\xd8-\\xde", rsVarRange = "\\ufe0e\\ufe0f", rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange;
6866 var rsApos = "['\u2019]", rsAstral = "[" + rsAstralRange + "]", rsBreak = "[" + rsBreakRange + "]", rsCombo = "[" + rsComboRange + "]", rsDigits = "\\d+", rsDingbat = "[" + rsDingbatRange + "]", rsLower = "[" + rsLowerRange + "]", rsMisc = "[^" + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + "]", rsFitz = "\\ud83c[\\udffb-\\udfff]", rsModifier = "(?:" + rsCombo + "|" + rsFitz + ")", rsNonAstral = "[^" + rsAstralRange + "]", rsRegional = "(?:\\ud83c[\\udde6-\\uddff]){2}", rsSurrPair = "[\\ud800-\\udbff][\\udc00-\\udfff]", rsUpper = "[" + rsUpperRange + "]", rsZWJ = "\\u200d";
6867 var rsMiscLower = "(?:" + rsLower + "|" + rsMisc + ")", rsMiscUpper = "(?:" + rsUpper + "|" + rsMisc + ")", rsOptContrLower = "(?:" + rsApos + "(?:d|ll|m|re|s|t|ve))?", rsOptContrUpper = "(?:" + rsApos + "(?:D|LL|M|RE|S|T|VE))?", reOptMod = rsModifier + "?", rsOptVar = "[" + rsVarRange + "]?", rsOptJoin = "(?:" + rsZWJ + "(?:" + [rsNonAstral, rsRegional, rsSurrPair].join("|") + ")" + rsOptVar + reOptMod + ")*", rsOrdLower = "\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])", rsOrdUpper = "\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])", rsSeq = rsOptVar + reOptMod + rsOptJoin, rsEmoji = "(?:" + [rsDingbat, rsRegional, rsSurrPair].join("|") + ")" + rsSeq, rsSymbol = "(?:" + [rsNonAstral + rsCombo + "?", rsCombo, rsRegional, rsSurrPair, rsAstral].join("|") + ")";
6868 var reApos = RegExp(rsApos, "g");
6869 var reComboMark = RegExp(rsCombo, "g");
6870 var reUnicode = RegExp(rsFitz + "(?=" + rsFitz + ")|" + rsSymbol + rsSeq, "g");
6871 var reUnicodeWord = RegExp([
6872 rsUpper + "?" + rsLower + "+" + rsOptContrLower + "(?=" + [rsBreak, rsUpper, "$"].join("|") + ")",
6873 rsMiscUpper + "+" + rsOptContrUpper + "(?=" + [rsBreak, rsUpper + rsMiscLower, "$"].join("|") + ")",
6874 rsUpper + "?" + rsMiscLower + "+" + rsOptContrLower,
6875 rsUpper + "+" + rsOptContrUpper,
6881 var reHasUnicode = RegExp("[" + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + "]");
6882 var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;
6883 var contextProps = [
6905 "Uint8ClampedArray",
6915 var templateCounter = -1;
6916 var typedArrayTags = {};
6917 typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = typedArrayTags[uint32Tag] = true;
6918 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;
6919 var cloneableTags = {};
6920 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;
6921 cloneableTags[errorTag] = cloneableTags[funcTag] = cloneableTags[weakMapTag] = false;
6922 var deburredLetters = {
6923 // Latin-1 Supplement block.
6986 // Latin Extended-A block.
7116 var htmlEscapes2 = {
7123 var htmlUnescapes2 = {
7130 var stringEscapes = {
7138 var freeParseFloat = parseFloat, freeParseInt2 = parseInt;
7139 var freeGlobal2 = typeof global == "object" && global && global.Object === Object && global;
7140 var freeSelf2 = typeof self == "object" && self && self.Object === Object && self;
7141 var root3 = freeGlobal2 || freeSelf2 || Function("return this")();
7142 var freeExports = typeof exports2 == "object" && exports2 && !exports2.nodeType && exports2;
7143 var freeModule = freeExports && typeof module2 == "object" && module2 && !module2.nodeType && module2;
7144 var moduleExports = freeModule && freeModule.exports === freeExports;
7145 var freeProcess = moduleExports && freeGlobal2.process;
7146 var nodeUtil = function() {
7148 var types = freeModule && freeModule.require && freeModule.require("util").types;
7152 return freeProcess && freeProcess.binding && freeProcess.binding("util");
7156 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;
7157 function apply(func, thisArg, args) {
7158 switch (args.length) {
7160 return func.call(thisArg);
7162 return func.call(thisArg, args[0]);
7164 return func.call(thisArg, args[0], args[1]);
7166 return func.call(thisArg, args[0], args[1], args[2]);
7168 return func.apply(thisArg, args);
7170 function arrayAggregator(array2, setter, iteratee, accumulator) {
7171 var index = -1, length = array2 == null ? 0 : array2.length;
7172 while (++index < length) {
7173 var value = array2[index];
7174 setter(accumulator, value, iteratee(value), array2);
7178 function arrayEach(array2, iteratee) {
7179 var index = -1, length = array2 == null ? 0 : array2.length;
7180 while (++index < length) {
7181 if (iteratee(array2[index], index, array2) === false) {
7187 function arrayEachRight(array2, iteratee) {
7188 var length = array2 == null ? 0 : array2.length;
7190 if (iteratee(array2[length], length, array2) === false) {
7196 function arrayEvery(array2, predicate) {
7197 var index = -1, length = array2 == null ? 0 : array2.length;
7198 while (++index < length) {
7199 if (!predicate(array2[index], index, array2)) {
7205 function arrayFilter(array2, predicate) {
7206 var index = -1, length = array2 == null ? 0 : array2.length, resIndex = 0, result = [];
7207 while (++index < length) {
7208 var value = array2[index];
7209 if (predicate(value, index, array2)) {
7210 result[resIndex++] = value;
7215 function arrayIncludes(array2, value) {
7216 var length = array2 == null ? 0 : array2.length;
7217 return !!length && baseIndexOf(array2, value, 0) > -1;
7219 function arrayIncludesWith(array2, value, comparator) {
7220 var index = -1, length = array2 == null ? 0 : array2.length;
7221 while (++index < length) {
7222 if (comparator(value, array2[index])) {
7228 function arrayMap2(array2, iteratee) {
7229 var index = -1, length = array2 == null ? 0 : array2.length, result = Array(length);
7230 while (++index < length) {
7231 result[index] = iteratee(array2[index], index, array2);
7235 function arrayPush(array2, values) {
7236 var index = -1, length = values.length, offset = array2.length;
7237 while (++index < length) {
7238 array2[offset + index] = values[index];
7242 function arrayReduce(array2, iteratee, accumulator, initAccum) {
7243 var index = -1, length = array2 == null ? 0 : array2.length;
7244 if (initAccum && length) {
7245 accumulator = array2[++index];
7247 while (++index < length) {
7248 accumulator = iteratee(accumulator, array2[index], index, array2);
7252 function arrayReduceRight(array2, iteratee, accumulator, initAccum) {
7253 var length = array2 == null ? 0 : array2.length;
7254 if (initAccum && length) {
7255 accumulator = array2[--length];
7258 accumulator = iteratee(accumulator, array2[length], length, array2);
7262 function arraySome(array2, predicate) {
7263 var index = -1, length = array2 == null ? 0 : array2.length;
7264 while (++index < length) {
7265 if (predicate(array2[index], index, array2)) {
7271 var asciiSize = baseProperty("length");
7272 function asciiToArray(string) {
7273 return string.split("");
7275 function asciiWords(string) {
7276 return string.match(reAsciiWord) || [];
7278 function baseFindKey(collection, predicate, eachFunc) {
7280 eachFunc(collection, function(value, key, collection2) {
7281 if (predicate(value, key, collection2)) {
7288 function baseFindIndex(array2, predicate, fromIndex, fromRight) {
7289 var length = array2.length, index = fromIndex + (fromRight ? 1 : -1);
7290 while (fromRight ? index-- : ++index < length) {
7291 if (predicate(array2[index], index, array2)) {
7297 function baseIndexOf(array2, value, fromIndex) {
7298 return value === value ? strictIndexOf(array2, value, fromIndex) : baseFindIndex(array2, baseIsNaN, fromIndex);
7300 function baseIndexOfWith(array2, value, fromIndex, comparator) {
7301 var index = fromIndex - 1, length = array2.length;
7302 while (++index < length) {
7303 if (comparator(array2[index], value)) {
7309 function baseIsNaN(value) {
7310 return value !== value;
7312 function baseMean(array2, iteratee) {
7313 var length = array2 == null ? 0 : array2.length;
7314 return length ? baseSum(array2, iteratee) / length : NAN2;
7316 function baseProperty(key) {
7317 return function(object) {
7318 return object == null ? undefined2 : object[key];
7321 function basePropertyOf2(object) {
7322 return function(key) {
7323 return object == null ? undefined2 : object[key];
7326 function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {
7327 eachFunc(collection, function(value, index, collection2) {
7328 accumulator = initAccum ? (initAccum = false, value) : iteratee(accumulator, value, index, collection2);
7332 function baseSortBy(array2, comparer) {
7333 var length = array2.length;
7334 array2.sort(comparer);
7336 array2[length] = array2[length].value;
7340 function baseSum(array2, iteratee) {
7341 var result, index = -1, length = array2.length;
7342 while (++index < length) {
7343 var current = iteratee(array2[index]);
7344 if (current !== undefined2) {
7345 result = result === undefined2 ? current : result + current;
7350 function baseTimes(n2, iteratee) {
7351 var index = -1, result = Array(n2);
7352 while (++index < n2) {
7353 result[index] = iteratee(index);
7357 function baseToPairs(object, props) {
7358 return arrayMap2(props, function(key) {
7359 return [key, object[key]];
7362 function baseTrim2(string) {
7363 return string ? string.slice(0, trimmedEndIndex2(string) + 1).replace(reTrimStart2, "") : string;
7365 function baseUnary(func) {
7366 return function(value) {
7370 function baseValues(object, props) {
7371 return arrayMap2(props, function(key) {
7375 function cacheHas(cache, key) {
7376 return cache.has(key);
7378 function charsStartIndex(strSymbols, chrSymbols) {
7379 var index = -1, length = strSymbols.length;
7380 while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {
7384 function charsEndIndex(strSymbols, chrSymbols) {
7385 var index = strSymbols.length;
7386 while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {
7390 function countHolders(array2, placeholder) {
7391 var length = array2.length, result = 0;
7393 if (array2[length] === placeholder) {
7399 var deburrLetter = basePropertyOf2(deburredLetters);
7400 var escapeHtmlChar2 = basePropertyOf2(htmlEscapes2);
7401 function escapeStringChar(chr) {
7402 return "\\" + stringEscapes[chr];
7404 function getValue(object, key) {
7405 return object == null ? undefined2 : object[key];
7407 function hasUnicode(string) {
7408 return reHasUnicode.test(string);
7410 function hasUnicodeWord(string) {
7411 return reHasUnicodeWord.test(string);
7413 function iteratorToArray(iterator) {
7414 var data, result = [];
7415 while (!(data = iterator.next()).done) {
7416 result.push(data.value);
7420 function mapToArray(map2) {
7421 var index = -1, result = Array(map2.size);
7422 map2.forEach(function(value, key) {
7423 result[++index] = [key, value];
7427 function overArg(func, transform2) {
7428 return function(arg) {
7429 return func(transform2(arg));
7432 function replaceHolders(array2, placeholder) {
7433 var index = -1, length = array2.length, resIndex = 0, result = [];
7434 while (++index < length) {
7435 var value = array2[index];
7436 if (value === placeholder || value === PLACEHOLDER) {
7437 array2[index] = PLACEHOLDER;
7438 result[resIndex++] = index;
7443 function setToArray(set3) {
7444 var index = -1, result = Array(set3.size);
7445 set3.forEach(function(value) {
7446 result[++index] = value;
7450 function setToPairs(set3) {
7451 var index = -1, result = Array(set3.size);
7452 set3.forEach(function(value) {
7453 result[++index] = [value, value];
7457 function strictIndexOf(array2, value, fromIndex) {
7458 var index = fromIndex - 1, length = array2.length;
7459 while (++index < length) {
7460 if (array2[index] === value) {
7466 function strictLastIndexOf(array2, value, fromIndex) {
7467 var index = fromIndex + 1;
7469 if (array2[index] === value) {
7475 function stringSize(string) {
7476 return hasUnicode(string) ? unicodeSize(string) : asciiSize(string);
7478 function stringToArray(string) {
7479 return hasUnicode(string) ? unicodeToArray(string) : asciiToArray(string);
7481 function trimmedEndIndex2(string) {
7482 var index = string.length;
7483 while (index-- && reWhitespace2.test(string.charAt(index))) {
7487 var unescapeHtmlChar2 = basePropertyOf2(htmlUnescapes2);
7488 function unicodeSize(string) {
7489 var result = reUnicode.lastIndex = 0;
7490 while (reUnicode.test(string)) {
7495 function unicodeToArray(string) {
7496 return string.match(reUnicode) || [];
7498 function unicodeWords(string) {
7499 return string.match(reUnicodeWord) || [];
7501 var runInContext = function runInContext2(context) {
7502 context = context == null ? root3 : _.defaults(root3.Object(), context, _.pick(root3, contextProps));
7503 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;
7504 var arrayProto = Array2.prototype, funcProto = Function2.prototype, objectProto3 = Object2.prototype;
7505 var coreJsData = context["__core-js_shared__"];
7506 var funcToString = funcProto.toString;
7507 var hasOwnProperty2 = objectProto3.hasOwnProperty;
7509 var maskSrcKey = function() {
7510 var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || "");
7511 return uid ? "Symbol(src)_1." + uid : "";
7513 var nativeObjectToString3 = objectProto3.toString;
7514 var objectCtorString = funcToString.call(Object2);
7515 var oldDash = root3._;
7516 var reIsNative = RegExp2(
7517 "^" + funcToString.call(hasOwnProperty2).replace(reRegExpChar, "\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, "$1.*?") + "$"
7519 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;
7520 var defineProperty = function() {
7522 var func = getNative(Object2, "defineProperty");
7528 var ctxClearTimeout = context.clearTimeout !== root3.clearTimeout && context.clearTimeout, ctxNow = Date2 && Date2.now !== root3.Date.now && Date2.now, ctxSetTimeout = context.setTimeout !== root3.setTimeout && context.setTimeout;
7529 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;
7530 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");
7531 var metaMap = WeakMap && new WeakMap();
7533 var dataViewCtorString = toSource(DataView2), mapCtorString = toSource(Map2), promiseCtorString = toSource(Promise2), setCtorString = toSource(Set2), weakMapCtorString = toSource(WeakMap);
7534 var symbolProto2 = Symbol3 ? Symbol3.prototype : undefined2, symbolValueOf = symbolProto2 ? symbolProto2.valueOf : undefined2, symbolToString2 = symbolProto2 ? symbolProto2.toString : undefined2;
7535 function lodash(value) {
7536 if (isObjectLike2(value) && !isArray2(value) && !(value instanceof LazyWrapper)) {
7537 if (value instanceof LodashWrapper) {
7540 if (hasOwnProperty2.call(value, "__wrapped__")) {
7541 return wrapperClone(value);
7544 return new LodashWrapper(value);
7546 var baseCreate = function() {
7549 return function(proto) {
7550 if (!isObject3(proto)) {
7554 return objectCreate(proto);
7556 object.prototype = proto;
7557 var result2 = new object();
7558 object.prototype = undefined2;
7562 function baseLodash() {
7564 function LodashWrapper(value, chainAll) {
7565 this.__wrapped__ = value;
7566 this.__actions__ = [];
7567 this.__chain__ = !!chainAll;
7569 this.__values__ = undefined2;
7571 lodash.templateSettings = {
7573 * Used to detect `data` property values to be HTML-escaped.
7575 * @memberOf _.templateSettings
7580 * Used to detect code to be evaluated.
7582 * @memberOf _.templateSettings
7585 "evaluate": reEvaluate,
7587 * Used to detect `data` property values to inject.
7589 * @memberOf _.templateSettings
7592 "interpolate": reInterpolate,
7594 * Used to reference the data object in the template text.
7596 * @memberOf _.templateSettings
7601 * Used to import variables into the compiled template.
7603 * @memberOf _.templateSettings
7608 * A reference to the `lodash` function.
7610 * @memberOf _.templateSettings.imports
7616 lodash.prototype = baseLodash.prototype;
7617 lodash.prototype.constructor = lodash;
7618 LodashWrapper.prototype = baseCreate(baseLodash.prototype);
7619 LodashWrapper.prototype.constructor = LodashWrapper;
7620 function LazyWrapper(value) {
7621 this.__wrapped__ = value;
7622 this.__actions__ = [];
7624 this.__filtered__ = false;
7625 this.__iteratees__ = [];
7626 this.__takeCount__ = MAX_ARRAY_LENGTH;
7627 this.__views__ = [];
7629 function lazyClone() {
7630 var result2 = new LazyWrapper(this.__wrapped__);
7631 result2.__actions__ = copyArray(this.__actions__);
7632 result2.__dir__ = this.__dir__;
7633 result2.__filtered__ = this.__filtered__;
7634 result2.__iteratees__ = copyArray(this.__iteratees__);
7635 result2.__takeCount__ = this.__takeCount__;
7636 result2.__views__ = copyArray(this.__views__);
7639 function lazyReverse() {
7640 if (this.__filtered__) {
7641 var result2 = new LazyWrapper(this);
7642 result2.__dir__ = -1;
7643 result2.__filtered__ = true;
7645 result2 = this.clone();
7646 result2.__dir__ *= -1;
7650 function lazyValue() {
7651 var array2 = this.__wrapped__.value(), dir = this.__dir__, isArr = isArray2(array2), isRight = dir < 0, arrLength = isArr ? array2.length : 0, view = getView(0, arrLength, this.__views__), start2 = view.start, end = view.end, length = end - start2, index = isRight ? end : start2 - 1, iteratees = this.__iteratees__, iterLength = iteratees.length, resIndex = 0, takeCount = nativeMin2(length, this.__takeCount__);
7652 if (!isArr || !isRight && arrLength == length && takeCount == length) {
7653 return baseWrapperValue(array2, this.__actions__);
7657 while (length-- && resIndex < takeCount) {
7659 var iterIndex = -1, value = array2[index];
7660 while (++iterIndex < iterLength) {
7661 var data = iteratees[iterIndex], iteratee2 = data.iteratee, type2 = data.type, computed = iteratee2(value);
7662 if (type2 == LAZY_MAP_FLAG) {
7664 } else if (!computed) {
7665 if (type2 == LAZY_FILTER_FLAG) {
7672 result2[resIndex++] = value;
7676 LazyWrapper.prototype = baseCreate(baseLodash.prototype);
7677 LazyWrapper.prototype.constructor = LazyWrapper;
7678 function Hash(entries) {
7679 var index = -1, length = entries == null ? 0 : entries.length;
7681 while (++index < length) {
7682 var entry = entries[index];
7683 this.set(entry[0], entry[1]);
7686 function hashClear() {
7687 this.__data__ = nativeCreate ? nativeCreate(null) : {};
7690 function hashDelete(key) {
7691 var result2 = this.has(key) && delete this.__data__[key];
7692 this.size -= result2 ? 1 : 0;
7695 function hashGet(key) {
7696 var data = this.__data__;
7698 var result2 = data[key];
7699 return result2 === HASH_UNDEFINED ? undefined2 : result2;
7701 return hasOwnProperty2.call(data, key) ? data[key] : undefined2;
7703 function hashHas(key) {
7704 var data = this.__data__;
7705 return nativeCreate ? data[key] !== undefined2 : hasOwnProperty2.call(data, key);
7707 function hashSet(key, value) {
7708 var data = this.__data__;
7709 this.size += this.has(key) ? 0 : 1;
7710 data[key] = nativeCreate && value === undefined2 ? HASH_UNDEFINED : value;
7713 Hash.prototype.clear = hashClear;
7714 Hash.prototype["delete"] = hashDelete;
7715 Hash.prototype.get = hashGet;
7716 Hash.prototype.has = hashHas;
7717 Hash.prototype.set = hashSet;
7718 function ListCache(entries) {
7719 var index = -1, length = entries == null ? 0 : entries.length;
7721 while (++index < length) {
7722 var entry = entries[index];
7723 this.set(entry[0], entry[1]);
7726 function listCacheClear() {
7730 function listCacheDelete(key) {
7731 var data = this.__data__, index = assocIndexOf(data, key);
7735 var lastIndex = data.length - 1;
7736 if (index == lastIndex) {
7739 splice.call(data, index, 1);
7744 function listCacheGet(key) {
7745 var data = this.__data__, index = assocIndexOf(data, key);
7746 return index < 0 ? undefined2 : data[index][1];
7748 function listCacheHas(key) {
7749 return assocIndexOf(this.__data__, key) > -1;
7751 function listCacheSet(key, value) {
7752 var data = this.__data__, index = assocIndexOf(data, key);
7755 data.push([key, value]);
7757 data[index][1] = value;
7761 ListCache.prototype.clear = listCacheClear;
7762 ListCache.prototype["delete"] = listCacheDelete;
7763 ListCache.prototype.get = listCacheGet;
7764 ListCache.prototype.has = listCacheHas;
7765 ListCache.prototype.set = listCacheSet;
7766 function MapCache(entries) {
7767 var index = -1, length = entries == null ? 0 : entries.length;
7769 while (++index < length) {
7770 var entry = entries[index];
7771 this.set(entry[0], entry[1]);
7774 function mapCacheClear() {
7778 "map": new (Map2 || ListCache)(),
7779 "string": new Hash()
7782 function mapCacheDelete(key) {
7783 var result2 = getMapData(this, key)["delete"](key);
7784 this.size -= result2 ? 1 : 0;
7787 function mapCacheGet(key) {
7788 return getMapData(this, key).get(key);
7790 function mapCacheHas(key) {
7791 return getMapData(this, key).has(key);
7793 function mapCacheSet(key, value) {
7794 var data = getMapData(this, key), size2 = data.size;
7795 data.set(key, value);
7796 this.size += data.size == size2 ? 0 : 1;
7799 MapCache.prototype.clear = mapCacheClear;
7800 MapCache.prototype["delete"] = mapCacheDelete;
7801 MapCache.prototype.get = mapCacheGet;
7802 MapCache.prototype.has = mapCacheHas;
7803 MapCache.prototype.set = mapCacheSet;
7804 function SetCache(values2) {
7805 var index = -1, length = values2 == null ? 0 : values2.length;
7806 this.__data__ = new MapCache();
7807 while (++index < length) {
7808 this.add(values2[index]);
7811 function setCacheAdd(value) {
7812 this.__data__.set(value, HASH_UNDEFINED);
7815 function setCacheHas(value) {
7816 return this.__data__.has(value);
7818 SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;
7819 SetCache.prototype.has = setCacheHas;
7820 function Stack(entries) {
7821 var data = this.__data__ = new ListCache(entries);
7822 this.size = data.size;
7824 function stackClear() {
7825 this.__data__ = new ListCache();
7828 function stackDelete(key) {
7829 var data = this.__data__, result2 = data["delete"](key);
7830 this.size = data.size;
7833 function stackGet(key) {
7834 return this.__data__.get(key);
7836 function stackHas(key) {
7837 return this.__data__.has(key);
7839 function stackSet(key, value) {
7840 var data = this.__data__;
7841 if (data instanceof ListCache) {
7842 var pairs = data.__data__;
7843 if (!Map2 || pairs.length < LARGE_ARRAY_SIZE - 1) {
7844 pairs.push([key, value]);
7845 this.size = ++data.size;
7848 data = this.__data__ = new MapCache(pairs);
7850 data.set(key, value);
7851 this.size = data.size;
7854 Stack.prototype.clear = stackClear;
7855 Stack.prototype["delete"] = stackDelete;
7856 Stack.prototype.get = stackGet;
7857 Stack.prototype.has = stackHas;
7858 Stack.prototype.set = stackSet;
7859 function arrayLikeKeys(value, inherited) {
7860 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;
7861 for (var key in value) {
7862 if ((inherited || hasOwnProperty2.call(value, key)) && !(skipIndexes && // Safari 9 has enumerable `arguments.length` in strict mode.
7863 (key == "length" || // Node.js 0.10 has enumerable non-index properties on buffers.
7864 isBuff && (key == "offset" || key == "parent") || // PhantomJS 2 has enumerable non-index properties on typed arrays.
7865 isType && (key == "buffer" || key == "byteLength" || key == "byteOffset") || // Skip index properties.
7866 isIndex(key, length)))) {
7872 function arraySample(array2) {
7873 var length = array2.length;
7874 return length ? array2[baseRandom(0, length - 1)] : undefined2;
7876 function arraySampleSize(array2, n2) {
7877 return shuffleSelf(copyArray(array2), baseClamp(n2, 0, array2.length));
7879 function arrayShuffle(array2) {
7880 return shuffleSelf(copyArray(array2));
7882 function assignMergeValue(object, key, value) {
7883 if (value !== undefined2 && !eq(object[key], value) || value === undefined2 && !(key in object)) {
7884 baseAssignValue(object, key, value);
7887 function assignValue(object, key, value) {
7888 var objValue = object[key];
7889 if (!(hasOwnProperty2.call(object, key) && eq(objValue, value)) || value === undefined2 && !(key in object)) {
7890 baseAssignValue(object, key, value);
7893 function assocIndexOf(array2, key) {
7894 var length = array2.length;
7896 if (eq(array2[length][0], key)) {
7902 function baseAggregator(collection, setter, iteratee2, accumulator) {
7903 baseEach(collection, function(value, key, collection2) {
7904 setter(accumulator, value, iteratee2(value), collection2);
7908 function baseAssign(object, source) {
7909 return object && copyObject(source, keys(source), object);
7911 function baseAssignIn(object, source) {
7912 return object && copyObject(source, keysIn(source), object);
7914 function baseAssignValue(object, key, value) {
7915 if (key == "__proto__" && defineProperty) {
7916 defineProperty(object, key, {
7917 "configurable": true,
7923 object[key] = value;
7926 function baseAt(object, paths) {
7927 var index = -1, length = paths.length, result2 = Array2(length), skip = object == null;
7928 while (++index < length) {
7929 result2[index] = skip ? undefined2 : get4(object, paths[index]);
7933 function baseClamp(number3, lower2, upper) {
7934 if (number3 === number3) {
7935 if (upper !== undefined2) {
7936 number3 = number3 <= upper ? number3 : upper;
7938 if (lower2 !== undefined2) {
7939 number3 = number3 >= lower2 ? number3 : lower2;
7944 function baseClone(value, bitmask, customizer, key, object, stack) {
7945 var result2, isDeep = bitmask & CLONE_DEEP_FLAG, isFlat = bitmask & CLONE_FLAT_FLAG, isFull = bitmask & CLONE_SYMBOLS_FLAG;
7947 result2 = object ? customizer(value, key, object, stack) : customizer(value);
7949 if (result2 !== undefined2) {
7952 if (!isObject3(value)) {
7955 var isArr = isArray2(value);
7957 result2 = initCloneArray(value);
7959 return copyArray(value, result2);
7962 var tag = getTag(value), isFunc = tag == funcTag || tag == genTag;
7963 if (isBuffer(value)) {
7964 return cloneBuffer(value, isDeep);
7966 if (tag == objectTag || tag == argsTag || isFunc && !object) {
7967 result2 = isFlat || isFunc ? {} : initCloneObject(value);
7969 return isFlat ? copySymbolsIn(value, baseAssignIn(result2, value)) : copySymbols(value, baseAssign(result2, value));
7972 if (!cloneableTags[tag]) {
7973 return object ? value : {};
7975 result2 = initCloneByTag(value, tag, isDeep);
7978 stack || (stack = new Stack());
7979 var stacked = stack.get(value);
7983 stack.set(value, result2);
7985 value.forEach(function(subValue) {
7986 result2.add(baseClone(subValue, bitmask, customizer, subValue, value, stack));
7988 } else if (isMap(value)) {
7989 value.forEach(function(subValue, key2) {
7990 result2.set(key2, baseClone(subValue, bitmask, customizer, key2, value, stack));
7993 var keysFunc = isFull ? isFlat ? getAllKeysIn : getAllKeys : isFlat ? keysIn : keys;
7994 var props = isArr ? undefined2 : keysFunc(value);
7995 arrayEach(props || value, function(subValue, key2) {
7998 subValue = value[key2];
8000 assignValue(result2, key2, baseClone(subValue, bitmask, customizer, key2, value, stack));
8004 function baseConforms(source) {
8005 var props = keys(source);
8006 return function(object) {
8007 return baseConformsTo(object, source, props);
8010 function baseConformsTo(object, source, props) {
8011 var length = props.length;
8012 if (object == null) {
8015 object = Object2(object);
8017 var key = props[length], predicate = source[key], value = object[key];
8018 if (value === undefined2 && !(key in object) || !predicate(value)) {
8024 function baseDelay(func, wait, args) {
8025 if (typeof func != "function") {
8026 throw new TypeError2(FUNC_ERROR_TEXT3);
8028 return setTimeout2(function() {
8029 func.apply(undefined2, args);
8032 function baseDifference(array2, values2, iteratee2, comparator) {
8033 var index = -1, includes2 = arrayIncludes, isCommon = true, length = array2.length, result2 = [], valuesLength = values2.length;
8038 values2 = arrayMap2(values2, baseUnary(iteratee2));
8041 includes2 = arrayIncludesWith;
8043 } else if (values2.length >= LARGE_ARRAY_SIZE) {
8044 includes2 = cacheHas;
8046 values2 = new SetCache(values2);
8049 while (++index < length) {
8050 var value = array2[index], computed = iteratee2 == null ? value : iteratee2(value);
8051 value = comparator || value !== 0 ? value : 0;
8052 if (isCommon && computed === computed) {
8053 var valuesIndex = valuesLength;
8054 while (valuesIndex--) {
8055 if (values2[valuesIndex] === computed) {
8059 result2.push(value);
8060 } else if (!includes2(values2, computed, comparator)) {
8061 result2.push(value);
8066 var baseEach = createBaseEach(baseForOwn);
8067 var baseEachRight = createBaseEach(baseForOwnRight, true);
8068 function baseEvery(collection, predicate) {
8070 baseEach(collection, function(value, index, collection2) {
8071 result2 = !!predicate(value, index, collection2);
8076 function baseExtremum(array2, iteratee2, comparator) {
8077 var index = -1, length = array2.length;
8078 while (++index < length) {
8079 var value = array2[index], current = iteratee2(value);
8080 if (current != null && (computed === undefined2 ? current === current && !isSymbol2(current) : comparator(current, computed))) {
8081 var computed = current, result2 = value;
8086 function baseFill(array2, value, start2, end) {
8087 var length = array2.length;
8088 start2 = toInteger(start2);
8090 start2 = -start2 > length ? 0 : length + start2;
8092 end = end === undefined2 || end > length ? length : toInteger(end);
8096 end = start2 > end ? 0 : toLength(end);
8097 while (start2 < end) {
8098 array2[start2++] = value;
8102 function baseFilter(collection, predicate) {
8104 baseEach(collection, function(value, index, collection2) {
8105 if (predicate(value, index, collection2)) {
8106 result2.push(value);
8111 function baseFlatten(array2, depth, predicate, isStrict, result2) {
8112 var index = -1, length = array2.length;
8113 predicate || (predicate = isFlattenable);
8114 result2 || (result2 = []);
8115 while (++index < length) {
8116 var value = array2[index];
8117 if (depth > 0 && predicate(value)) {
8119 baseFlatten(value, depth - 1, predicate, isStrict, result2);
8121 arrayPush(result2, value);
8123 } else if (!isStrict) {
8124 result2[result2.length] = value;
8129 var baseFor = createBaseFor();
8130 var baseForRight = createBaseFor(true);
8131 function baseForOwn(object, iteratee2) {
8132 return object && baseFor(object, iteratee2, keys);
8134 function baseForOwnRight(object, iteratee2) {
8135 return object && baseForRight(object, iteratee2, keys);
8137 function baseFunctions(object, props) {
8138 return arrayFilter(props, function(key) {
8139 return isFunction(object[key]);
8142 function baseGet(object, path) {
8143 path = castPath(path, object);
8144 var index = 0, length = path.length;
8145 while (object != null && index < length) {
8146 object = object[toKey(path[index++])];
8148 return index && index == length ? object : undefined2;
8150 function baseGetAllKeys(object, keysFunc, symbolsFunc) {
8151 var result2 = keysFunc(object);
8152 return isArray2(object) ? result2 : arrayPush(result2, symbolsFunc(object));
8154 function baseGetTag2(value) {
8155 if (value == null) {
8156 return value === undefined2 ? undefinedTag2 : nullTag2;
8158 return symToStringTag3 && symToStringTag3 in Object2(value) ? getRawTag2(value) : objectToString2(value);
8160 function baseGt(value, other) {
8161 return value > other;
8163 function baseHas(object, key) {
8164 return object != null && hasOwnProperty2.call(object, key);
8166 function baseHasIn(object, key) {
8167 return object != null && key in Object2(object);
8169 function baseInRange(number3, start2, end) {
8170 return number3 >= nativeMin2(start2, end) && number3 < nativeMax2(start2, end);
8172 function baseIntersection(arrays, iteratee2, comparator) {
8173 var includes2 = comparator ? arrayIncludesWith : arrayIncludes, length = arrays[0].length, othLength = arrays.length, othIndex = othLength, caches = Array2(othLength), maxLength = Infinity, result2 = [];
8174 while (othIndex--) {
8175 var array2 = arrays[othIndex];
8176 if (othIndex && iteratee2) {
8177 array2 = arrayMap2(array2, baseUnary(iteratee2));
8179 maxLength = nativeMin2(array2.length, maxLength);
8180 caches[othIndex] = !comparator && (iteratee2 || length >= 120 && array2.length >= 120) ? new SetCache(othIndex && array2) : undefined2;
8183 var index = -1, seen = caches[0];
8185 while (++index < length && result2.length < maxLength) {
8186 var value = array2[index], computed = iteratee2 ? iteratee2(value) : value;
8187 value = comparator || value !== 0 ? value : 0;
8188 if (!(seen ? cacheHas(seen, computed) : includes2(result2, computed, comparator))) {
8189 othIndex = othLength;
8190 while (--othIndex) {
8191 var cache = caches[othIndex];
8192 if (!(cache ? cacheHas(cache, computed) : includes2(arrays[othIndex], computed, comparator))) {
8197 seen.push(computed);
8199 result2.push(value);
8204 function baseInverter(object, setter, iteratee2, accumulator) {
8205 baseForOwn(object, function(value, key, object2) {
8206 setter(accumulator, iteratee2(value), key, object2);
8210 function baseInvoke(object, path, args) {
8211 path = castPath(path, object);
8212 object = parent(object, path);
8213 var func = object == null ? object : object[toKey(last(path))];
8214 return func == null ? undefined2 : apply(func, object, args);
8216 function baseIsArguments(value) {
8217 return isObjectLike2(value) && baseGetTag2(value) == argsTag;
8219 function baseIsArrayBuffer(value) {
8220 return isObjectLike2(value) && baseGetTag2(value) == arrayBufferTag;
8222 function baseIsDate(value) {
8223 return isObjectLike2(value) && baseGetTag2(value) == dateTag;
8225 function baseIsEqual(value, other, bitmask, customizer, stack) {
8226 if (value === other) {
8229 if (value == null || other == null || !isObjectLike2(value) && !isObjectLike2(other)) {
8230 return value !== value && other !== other;
8232 return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);
8234 function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {
8235 var objIsArr = isArray2(object), othIsArr = isArray2(other), objTag = objIsArr ? arrayTag : getTag(object), othTag = othIsArr ? arrayTag : getTag(other);
8236 objTag = objTag == argsTag ? objectTag : objTag;
8237 othTag = othTag == argsTag ? objectTag : othTag;
8238 var objIsObj = objTag == objectTag, othIsObj = othTag == objectTag, isSameTag = objTag == othTag;
8239 if (isSameTag && isBuffer(object)) {
8240 if (!isBuffer(other)) {
8246 if (isSameTag && !objIsObj) {
8247 stack || (stack = new Stack());
8248 return objIsArr || isTypedArray(object) ? equalArrays(object, other, bitmask, customizer, equalFunc, stack) : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);
8250 if (!(bitmask & COMPARE_PARTIAL_FLAG)) {
8251 var objIsWrapped = objIsObj && hasOwnProperty2.call(object, "__wrapped__"), othIsWrapped = othIsObj && hasOwnProperty2.call(other, "__wrapped__");
8252 if (objIsWrapped || othIsWrapped) {
8253 var objUnwrapped = objIsWrapped ? object.value() : object, othUnwrapped = othIsWrapped ? other.value() : other;
8254 stack || (stack = new Stack());
8255 return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);
8261 stack || (stack = new Stack());
8262 return equalObjects(object, other, bitmask, customizer, equalFunc, stack);
8264 function baseIsMap(value) {
8265 return isObjectLike2(value) && getTag(value) == mapTag;
8267 function baseIsMatch(object, source, matchData, customizer) {
8268 var index = matchData.length, length = index, noCustomizer = !customizer;
8269 if (object == null) {
8272 object = Object2(object);
8274 var data = matchData[index];
8275 if (noCustomizer && data[2] ? data[1] !== object[data[0]] : !(data[0] in object)) {
8279 while (++index < length) {
8280 data = matchData[index];
8281 var key = data[0], objValue = object[key], srcValue = data[1];
8282 if (noCustomizer && data[2]) {
8283 if (objValue === undefined2 && !(key in object)) {
8287 var stack = new Stack();
8289 var result2 = customizer(objValue, srcValue, key, object, source, stack);
8291 if (!(result2 === undefined2 ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack) : result2)) {
8298 function baseIsNative(value) {
8299 if (!isObject3(value) || isMasked(value)) {
8302 var pattern = isFunction(value) ? reIsNative : reIsHostCtor;
8303 return pattern.test(toSource(value));
8305 function baseIsRegExp(value) {
8306 return isObjectLike2(value) && baseGetTag2(value) == regexpTag;
8308 function baseIsSet(value) {
8309 return isObjectLike2(value) && getTag(value) == setTag;
8311 function baseIsTypedArray(value) {
8312 return isObjectLike2(value) && isLength(value.length) && !!typedArrayTags[baseGetTag2(value)];
8314 function baseIteratee(value) {
8315 if (typeof value == "function") {
8318 if (value == null) {
8321 if (typeof value == "object") {
8322 return isArray2(value) ? baseMatchesProperty(value[0], value[1]) : baseMatches(value);
8324 return property(value);
8326 function baseKeys(object) {
8327 if (!isPrototype(object)) {
8328 return nativeKeys(object);
8331 for (var key in Object2(object)) {
8332 if (hasOwnProperty2.call(object, key) && key != "constructor") {
8338 function baseKeysIn(object) {
8339 if (!isObject3(object)) {
8340 return nativeKeysIn(object);
8342 var isProto = isPrototype(object), result2 = [];
8343 for (var key in object) {
8344 if (!(key == "constructor" && (isProto || !hasOwnProperty2.call(object, key)))) {
8350 function baseLt(value, other) {
8351 return value < other;
8353 function baseMap(collection, iteratee2) {
8354 var index = -1, result2 = isArrayLike(collection) ? Array2(collection.length) : [];
8355 baseEach(collection, function(value, key, collection2) {
8356 result2[++index] = iteratee2(value, key, collection2);
8360 function baseMatches(source) {
8361 var matchData = getMatchData(source);
8362 if (matchData.length == 1 && matchData[0][2]) {
8363 return matchesStrictComparable(matchData[0][0], matchData[0][1]);
8365 return function(object) {
8366 return object === source || baseIsMatch(object, source, matchData);
8369 function baseMatchesProperty(path, srcValue) {
8370 if (isKey(path) && isStrictComparable(srcValue)) {
8371 return matchesStrictComparable(toKey(path), srcValue);
8373 return function(object) {
8374 var objValue = get4(object, path);
8375 return objValue === undefined2 && objValue === srcValue ? hasIn(object, path) : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);
8378 function baseMerge(object, source, srcIndex, customizer, stack) {
8379 if (object === source) {
8382 baseFor(source, function(srcValue, key) {
8383 stack || (stack = new Stack());
8384 if (isObject3(srcValue)) {
8385 baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
8387 var newValue = customizer ? customizer(safeGet(object, key), srcValue, key + "", object, source, stack) : undefined2;
8388 if (newValue === undefined2) {
8389 newValue = srcValue;
8391 assignMergeValue(object, key, newValue);
8395 function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
8396 var objValue = safeGet(object, key), srcValue = safeGet(source, key), stacked = stack.get(srcValue);
8398 assignMergeValue(object, key, stacked);
8401 var newValue = customizer ? customizer(objValue, srcValue, key + "", object, source, stack) : undefined2;
8402 var isCommon = newValue === undefined2;
8404 var isArr = isArray2(srcValue), isBuff = !isArr && isBuffer(srcValue), isTyped = !isArr && !isBuff && isTypedArray(srcValue);
8405 newValue = srcValue;
8406 if (isArr || isBuff || isTyped) {
8407 if (isArray2(objValue)) {
8408 newValue = objValue;
8409 } else if (isArrayLikeObject(objValue)) {
8410 newValue = copyArray(objValue);
8411 } else if (isBuff) {
8413 newValue = cloneBuffer(srcValue, true);
8414 } else if (isTyped) {
8416 newValue = cloneTypedArray(srcValue, true);
8420 } else if (isPlainObject(srcValue) || isArguments(srcValue)) {
8421 newValue = objValue;
8422 if (isArguments(objValue)) {
8423 newValue = toPlainObject(objValue);
8424 } else if (!isObject3(objValue) || isFunction(objValue)) {
8425 newValue = initCloneObject(srcValue);
8432 stack.set(srcValue, newValue);
8433 mergeFunc(newValue, srcValue, srcIndex, customizer, stack);
8434 stack["delete"](srcValue);
8436 assignMergeValue(object, key, newValue);
8438 function baseNth(array2, n2) {
8439 var length = array2.length;
8443 n2 += n2 < 0 ? length : 0;
8444 return isIndex(n2, length) ? array2[n2] : undefined2;
8446 function baseOrderBy(collection, iteratees, orders) {
8447 if (iteratees.length) {
8448 iteratees = arrayMap2(iteratees, function(iteratee2) {
8449 if (isArray2(iteratee2)) {
8450 return function(value) {
8451 return baseGet(value, iteratee2.length === 1 ? iteratee2[0] : iteratee2);
8457 iteratees = [identity4];
8460 iteratees = arrayMap2(iteratees, baseUnary(getIteratee()));
8461 var result2 = baseMap(collection, function(value, key, collection2) {
8462 var criteria = arrayMap2(iteratees, function(iteratee2) {
8463 return iteratee2(value);
8465 return { "criteria": criteria, "index": ++index, "value": value };
8467 return baseSortBy(result2, function(object, other) {
8468 return compareMultiple(object, other, orders);
8471 function basePick(object, paths) {
8472 return basePickBy(object, paths, function(value, path) {
8473 return hasIn(object, path);
8476 function basePickBy(object, paths, predicate) {
8477 var index = -1, length = paths.length, result2 = {};
8478 while (++index < length) {
8479 var path = paths[index], value = baseGet(object, path);
8480 if (predicate(value, path)) {
8481 baseSet(result2, castPath(path, object), value);
8486 function basePropertyDeep(path) {
8487 return function(object) {
8488 return baseGet(object, path);
8491 function basePullAll(array2, values2, iteratee2, comparator) {
8492 var indexOf2 = comparator ? baseIndexOfWith : baseIndexOf, index = -1, length = values2.length, seen = array2;
8493 if (array2 === values2) {
8494 values2 = copyArray(values2);
8497 seen = arrayMap2(array2, baseUnary(iteratee2));
8499 while (++index < length) {
8500 var fromIndex = 0, value = values2[index], computed = iteratee2 ? iteratee2(value) : value;
8501 while ((fromIndex = indexOf2(seen, computed, fromIndex, comparator)) > -1) {
8502 if (seen !== array2) {
8503 splice.call(seen, fromIndex, 1);
8505 splice.call(array2, fromIndex, 1);
8510 function basePullAt(array2, indexes) {
8511 var length = array2 ? indexes.length : 0, lastIndex = length - 1;
8513 var index = indexes[length];
8514 if (length == lastIndex || index !== previous) {
8515 var previous = index;
8516 if (isIndex(index)) {
8517 splice.call(array2, index, 1);
8519 baseUnset(array2, index);
8525 function baseRandom(lower2, upper) {
8526 return lower2 + nativeFloor(nativeRandom() * (upper - lower2 + 1));
8528 function baseRange(start2, end, step, fromRight) {
8529 var index = -1, length = nativeMax2(nativeCeil((end - start2) / (step || 1)), 0), result2 = Array2(length);
8531 result2[fromRight ? length : ++index] = start2;
8536 function baseRepeat(string, n2) {
8538 if (!string || n2 < 1 || n2 > MAX_SAFE_INTEGER) {
8545 n2 = nativeFloor(n2 / 2);
8552 function baseRest(func, start2) {
8553 return setToString(overRest(func, start2, identity4), func + "");
8555 function baseSample(collection) {
8556 return arraySample(values(collection));
8558 function baseSampleSize(collection, n2) {
8559 var array2 = values(collection);
8560 return shuffleSelf(array2, baseClamp(n2, 0, array2.length));
8562 function baseSet(object, path, value, customizer) {
8563 if (!isObject3(object)) {
8566 path = castPath(path, object);
8567 var index = -1, length = path.length, lastIndex = length - 1, nested = object;
8568 while (nested != null && ++index < length) {
8569 var key = toKey(path[index]), newValue = value;
8570 if (key === "__proto__" || key === "constructor" || key === "prototype") {
8573 if (index != lastIndex) {
8574 var objValue = nested[key];
8575 newValue = customizer ? customizer(objValue, key, nested) : undefined2;
8576 if (newValue === undefined2) {
8577 newValue = isObject3(objValue) ? objValue : isIndex(path[index + 1]) ? [] : {};
8580 assignValue(nested, key, newValue);
8581 nested = nested[key];
8585 var baseSetData = !metaMap ? identity4 : function(func, data) {
8586 metaMap.set(func, data);
8589 var baseSetToString = !defineProperty ? identity4 : function(func, string) {
8590 return defineProperty(func, "toString", {
8591 "configurable": true,
8592 "enumerable": false,
8593 "value": constant(string),
8597 function baseShuffle(collection) {
8598 return shuffleSelf(values(collection));
8600 function baseSlice(array2, start2, end) {
8601 var index = -1, length = array2.length;
8603 start2 = -start2 > length ? 0 : length + start2;
8605 end = end > length ? length : end;
8609 length = start2 > end ? 0 : end - start2 >>> 0;
8611 var result2 = Array2(length);
8612 while (++index < length) {
8613 result2[index] = array2[index + start2];
8617 function baseSome(collection, predicate) {
8619 baseEach(collection, function(value, index, collection2) {
8620 result2 = predicate(value, index, collection2);
8625 function baseSortedIndex(array2, value, retHighest) {
8626 var low = 0, high = array2 == null ? low : array2.length;
8627 if (typeof value == "number" && value === value && high <= HALF_MAX_ARRAY_LENGTH) {
8628 while (low < high) {
8629 var mid = low + high >>> 1, computed = array2[mid];
8630 if (computed !== null && !isSymbol2(computed) && (retHighest ? computed <= value : computed < value)) {
8638 return baseSortedIndexBy(array2, value, identity4, retHighest);
8640 function baseSortedIndexBy(array2, value, iteratee2, retHighest) {
8641 var low = 0, high = array2 == null ? 0 : array2.length;
8645 value = iteratee2(value);
8646 var valIsNaN = value !== value, valIsNull = value === null, valIsSymbol = isSymbol2(value), valIsUndefined = value === undefined2;
8647 while (low < high) {
8648 var mid = nativeFloor((low + high) / 2), computed = iteratee2(array2[mid]), othIsDefined = computed !== undefined2, othIsNull = computed === null, othIsReflexive = computed === computed, othIsSymbol = isSymbol2(computed);
8650 var setLow = retHighest || othIsReflexive;
8651 } else if (valIsUndefined) {
8652 setLow = othIsReflexive && (retHighest || othIsDefined);
8653 } else if (valIsNull) {
8654 setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull);
8655 } else if (valIsSymbol) {
8656 setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol);
8657 } else if (othIsNull || othIsSymbol) {
8660 setLow = retHighest ? computed <= value : computed < value;
8668 return nativeMin2(high, MAX_ARRAY_INDEX);
8670 function baseSortedUniq(array2, iteratee2) {
8671 var index = -1, length = array2.length, resIndex = 0, result2 = [];
8672 while (++index < length) {
8673 var value = array2[index], computed = iteratee2 ? iteratee2(value) : value;
8674 if (!index || !eq(computed, seen)) {
8675 var seen = computed;
8676 result2[resIndex++] = value === 0 ? 0 : value;
8681 function baseToNumber(value) {
8682 if (typeof value == "number") {
8685 if (isSymbol2(value)) {
8690 function baseToString2(value) {
8691 if (typeof value == "string") {
8694 if (isArray2(value)) {
8695 return arrayMap2(value, baseToString2) + "";
8697 if (isSymbol2(value)) {
8698 return symbolToString2 ? symbolToString2.call(value) : "";
8700 var result2 = value + "";
8701 return result2 == "0" && 1 / value == -INFINITY2 ? "-0" : result2;
8703 function baseUniq(array2, iteratee2, comparator) {
8704 var index = -1, includes2 = arrayIncludes, length = array2.length, isCommon = true, result2 = [], seen = result2;
8707 includes2 = arrayIncludesWith;
8708 } else if (length >= LARGE_ARRAY_SIZE) {
8709 var set4 = iteratee2 ? null : createSet(array2);
8711 return setToArray(set4);
8714 includes2 = cacheHas;
8715 seen = new SetCache();
8717 seen = iteratee2 ? [] : result2;
8720 while (++index < length) {
8721 var value = array2[index], computed = iteratee2 ? iteratee2(value) : value;
8722 value = comparator || value !== 0 ? value : 0;
8723 if (isCommon && computed === computed) {
8724 var seenIndex = seen.length;
8725 while (seenIndex--) {
8726 if (seen[seenIndex] === computed) {
8731 seen.push(computed);
8733 result2.push(value);
8734 } else if (!includes2(seen, computed, comparator)) {
8735 if (seen !== result2) {
8736 seen.push(computed);
8738 result2.push(value);
8743 function baseUnset(object, path) {
8744 path = castPath(path, object);
8745 object = parent(object, path);
8746 return object == null || delete object[toKey(last(path))];
8748 function baseUpdate(object, path, updater, customizer) {
8749 return baseSet(object, path, updater(baseGet(object, path)), customizer);
8751 function baseWhile(array2, predicate, isDrop, fromRight) {
8752 var length = array2.length, index = fromRight ? length : -1;
8753 while ((fromRight ? index-- : ++index < length) && predicate(array2[index], index, array2)) {
8755 return isDrop ? baseSlice(array2, fromRight ? 0 : index, fromRight ? index + 1 : length) : baseSlice(array2, fromRight ? index + 1 : 0, fromRight ? length : index);
8757 function baseWrapperValue(value, actions) {
8758 var result2 = value;
8759 if (result2 instanceof LazyWrapper) {
8760 result2 = result2.value();
8762 return arrayReduce(actions, function(result3, action) {
8763 return action.func.apply(action.thisArg, arrayPush([result3], action.args));
8766 function baseXor(arrays, iteratee2, comparator) {
8767 var length = arrays.length;
8769 return length ? baseUniq(arrays[0]) : [];
8771 var index = -1, result2 = Array2(length);
8772 while (++index < length) {
8773 var array2 = arrays[index], othIndex = -1;
8774 while (++othIndex < length) {
8775 if (othIndex != index) {
8776 result2[index] = baseDifference(result2[index] || array2, arrays[othIndex], iteratee2, comparator);
8780 return baseUniq(baseFlatten(result2, 1), iteratee2, comparator);
8782 function baseZipObject(props, values2, assignFunc) {
8783 var index = -1, length = props.length, valsLength = values2.length, result2 = {};
8784 while (++index < length) {
8785 var value = index < valsLength ? values2[index] : undefined2;
8786 assignFunc(result2, props[index], value);
8790 function castArrayLikeObject(value) {
8791 return isArrayLikeObject(value) ? value : [];
8793 function castFunction(value) {
8794 return typeof value == "function" ? value : identity4;
8796 function castPath(value, object) {
8797 if (isArray2(value)) {
8800 return isKey(value, object) ? [value] : stringToPath(toString2(value));
8802 var castRest = baseRest;
8803 function castSlice(array2, start2, end) {
8804 var length = array2.length;
8805 end = end === undefined2 ? length : end;
8806 return !start2 && end >= length ? array2 : baseSlice(array2, start2, end);
8808 var clearTimeout2 = ctxClearTimeout || function(id2) {
8809 return root3.clearTimeout(id2);
8811 function cloneBuffer(buffer, isDeep) {
8813 return buffer.slice();
8815 var length = buffer.length, result2 = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);
8816 buffer.copy(result2);
8819 function cloneArrayBuffer(arrayBuffer) {
8820 var result2 = new arrayBuffer.constructor(arrayBuffer.byteLength);
8821 new Uint8Array2(result2).set(new Uint8Array2(arrayBuffer));
8824 function cloneDataView(dataView, isDeep) {
8825 var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;
8826 return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);
8828 function cloneRegExp(regexp) {
8829 var result2 = new regexp.constructor(regexp.source, reFlags.exec(regexp));
8830 result2.lastIndex = regexp.lastIndex;
8833 function cloneSymbol(symbol) {
8834 return symbolValueOf ? Object2(symbolValueOf.call(symbol)) : {};
8836 function cloneTypedArray(typedArray, isDeep) {
8837 var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;
8838 return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
8840 function compareAscending(value, other) {
8841 if (value !== other) {
8842 var valIsDefined = value !== undefined2, valIsNull = value === null, valIsReflexive = value === value, valIsSymbol = isSymbol2(value);
8843 var othIsDefined = other !== undefined2, othIsNull = other === null, othIsReflexive = other === other, othIsSymbol = isSymbol2(other);
8844 if (!othIsNull && !othIsSymbol && !valIsSymbol && value > other || valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol || valIsNull && othIsDefined && othIsReflexive || !valIsDefined && othIsReflexive || !valIsReflexive) {
8847 if (!valIsNull && !valIsSymbol && !othIsSymbol && value < other || othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol || othIsNull && valIsDefined && valIsReflexive || !othIsDefined && valIsReflexive || !othIsReflexive) {
8853 function compareMultiple(object, other, orders) {
8854 var index = -1, objCriteria = object.criteria, othCriteria = other.criteria, length = objCriteria.length, ordersLength = orders.length;
8855 while (++index < length) {
8856 var result2 = compareAscending(objCriteria[index], othCriteria[index]);
8858 if (index >= ordersLength) {
8861 var order = orders[index];
8862 return result2 * (order == "desc" ? -1 : 1);
8865 return object.index - other.index;
8867 function composeArgs(args, partials, holders, isCurried) {
8868 var argsIndex = -1, argsLength = args.length, holdersLength = holders.length, leftIndex = -1, leftLength = partials.length, rangeLength = nativeMax2(argsLength - holdersLength, 0), result2 = Array2(leftLength + rangeLength), isUncurried = !isCurried;
8869 while (++leftIndex < leftLength) {
8870 result2[leftIndex] = partials[leftIndex];
8872 while (++argsIndex < holdersLength) {
8873 if (isUncurried || argsIndex < argsLength) {
8874 result2[holders[argsIndex]] = args[argsIndex];
8877 while (rangeLength--) {
8878 result2[leftIndex++] = args[argsIndex++];
8882 function composeArgsRight(args, partials, holders, isCurried) {
8883 var argsIndex = -1, argsLength = args.length, holdersIndex = -1, holdersLength = holders.length, rightIndex = -1, rightLength = partials.length, rangeLength = nativeMax2(argsLength - holdersLength, 0), result2 = Array2(rangeLength + rightLength), isUncurried = !isCurried;
8884 while (++argsIndex < rangeLength) {
8885 result2[argsIndex] = args[argsIndex];
8887 var offset = argsIndex;
8888 while (++rightIndex < rightLength) {
8889 result2[offset + rightIndex] = partials[rightIndex];
8891 while (++holdersIndex < holdersLength) {
8892 if (isUncurried || argsIndex < argsLength) {
8893 result2[offset + holders[holdersIndex]] = args[argsIndex++];
8898 function copyArray(source, array2) {
8899 var index = -1, length = source.length;
8900 array2 || (array2 = Array2(length));
8901 while (++index < length) {
8902 array2[index] = source[index];
8906 function copyObject(source, props, object, customizer) {
8907 var isNew = !object;
8908 object || (object = {});
8909 var index = -1, length = props.length;
8910 while (++index < length) {
8911 var key = props[index];
8912 var newValue = customizer ? customizer(object[key], source[key], key, object, source) : undefined2;
8913 if (newValue === undefined2) {
8914 newValue = source[key];
8917 baseAssignValue(object, key, newValue);
8919 assignValue(object, key, newValue);
8924 function copySymbols(source, object) {
8925 return copyObject(source, getSymbols(source), object);
8927 function copySymbolsIn(source, object) {
8928 return copyObject(source, getSymbolsIn(source), object);
8930 function createAggregator(setter, initializer) {
8931 return function(collection, iteratee2) {
8932 var func = isArray2(collection) ? arrayAggregator : baseAggregator, accumulator = initializer ? initializer() : {};
8933 return func(collection, setter, getIteratee(iteratee2, 2), accumulator);
8936 function createAssigner(assigner) {
8937 return baseRest(function(object, sources) {
8938 var index = -1, length = sources.length, customizer = length > 1 ? sources[length - 1] : undefined2, guard = length > 2 ? sources[2] : undefined2;
8939 customizer = assigner.length > 3 && typeof customizer == "function" ? (length--, customizer) : undefined2;
8940 if (guard && isIterateeCall(sources[0], sources[1], guard)) {
8941 customizer = length < 3 ? undefined2 : customizer;
8944 object = Object2(object);
8945 while (++index < length) {
8946 var source = sources[index];
8948 assigner(object, source, index, customizer);
8954 function createBaseEach(eachFunc, fromRight) {
8955 return function(collection, iteratee2) {
8956 if (collection == null) {
8959 if (!isArrayLike(collection)) {
8960 return eachFunc(collection, iteratee2);
8962 var length = collection.length, index = fromRight ? length : -1, iterable = Object2(collection);
8963 while (fromRight ? index-- : ++index < length) {
8964 if (iteratee2(iterable[index], index, iterable) === false) {
8971 function createBaseFor(fromRight) {
8972 return function(object, iteratee2, keysFunc) {
8973 var index = -1, iterable = Object2(object), props = keysFunc(object), length = props.length;
8975 var key = props[fromRight ? length : ++index];
8976 if (iteratee2(iterable[key], key, iterable) === false) {
8983 function createBind(func, bitmask, thisArg) {
8984 var isBind = bitmask & WRAP_BIND_FLAG, Ctor = createCtor(func);
8985 function wrapper() {
8986 var fn = this && this !== root3 && this instanceof wrapper ? Ctor : func;
8987 return fn.apply(isBind ? thisArg : this, arguments);
8991 function createCaseFirst(methodName) {
8992 return function(string) {
8993 string = toString2(string);
8994 var strSymbols = hasUnicode(string) ? stringToArray(string) : undefined2;
8995 var chr = strSymbols ? strSymbols[0] : string.charAt(0);
8996 var trailing = strSymbols ? castSlice(strSymbols, 1).join("") : string.slice(1);
8997 return chr[methodName]() + trailing;
9000 function createCompounder(callback) {
9001 return function(string) {
9002 return arrayReduce(words(deburr(string).replace(reApos, "")), callback, "");
9005 function createCtor(Ctor) {
9007 var args = arguments;
9008 switch (args.length) {
9012 return new Ctor(args[0]);
9014 return new Ctor(args[0], args[1]);
9016 return new Ctor(args[0], args[1], args[2]);
9018 return new Ctor(args[0], args[1], args[2], args[3]);
9020 return new Ctor(args[0], args[1], args[2], args[3], args[4]);
9022 return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
9024 return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
9026 var thisBinding = baseCreate(Ctor.prototype), result2 = Ctor.apply(thisBinding, args);
9027 return isObject3(result2) ? result2 : thisBinding;
9030 function createCurry(func, bitmask, arity) {
9031 var Ctor = createCtor(func);
9032 function wrapper() {
9033 var length = arguments.length, args = Array2(length), index = length, placeholder = getHolder(wrapper);
9035 args[index] = arguments[index];
9037 var holders = length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder ? [] : replaceHolders(args, placeholder);
9038 length -= holders.length;
9039 if (length < arity) {
9040 return createRecurry(
9044 wrapper.placeholder,
9053 var fn = this && this !== root3 && this instanceof wrapper ? Ctor : func;
9054 return apply(fn, this, args);
9058 function createFind(findIndexFunc) {
9059 return function(collection, predicate, fromIndex) {
9060 var iterable = Object2(collection);
9061 if (!isArrayLike(collection)) {
9062 var iteratee2 = getIteratee(predicate, 3);
9063 collection = keys(collection);
9064 predicate = function(key) {
9065 return iteratee2(iterable[key], key, iterable);
9068 var index = findIndexFunc(collection, predicate, fromIndex);
9069 return index > -1 ? iterable[iteratee2 ? collection[index] : index] : undefined2;
9072 function createFlow(fromRight) {
9073 return flatRest(function(funcs) {
9074 var length = funcs.length, index = length, prereq = LodashWrapper.prototype.thru;
9079 var func = funcs[index];
9080 if (typeof func != "function") {
9081 throw new TypeError2(FUNC_ERROR_TEXT3);
9083 if (prereq && !wrapper && getFuncName(func) == "wrapper") {
9084 var wrapper = new LodashWrapper([], true);
9087 index = wrapper ? index : length;
9088 while (++index < length) {
9089 func = funcs[index];
9090 var funcName = getFuncName(func), data = funcName == "wrapper" ? getData(func) : undefined2;
9091 if (data && isLaziable(data[0]) && data[1] == (WRAP_ARY_FLAG | WRAP_CURRY_FLAG | WRAP_PARTIAL_FLAG | WRAP_REARG_FLAG) && !data[4].length && data[9] == 1) {
9092 wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);
9094 wrapper = func.length == 1 && isLaziable(func) ? wrapper[funcName]() : wrapper.thru(func);
9098 var args = arguments, value = args[0];
9099 if (wrapper && args.length == 1 && isArray2(value)) {
9100 return wrapper.plant(value).value();
9102 var index2 = 0, result2 = length ? funcs[index2].apply(this, args) : value;
9103 while (++index2 < length) {
9104 result2 = funcs[index2].call(this, result2);
9110 function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary2, arity) {
9111 var isAry = bitmask & WRAP_ARY_FLAG, isBind = bitmask & WRAP_BIND_FLAG, isBindKey = bitmask & WRAP_BIND_KEY_FLAG, isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG), isFlip = bitmask & WRAP_FLIP_FLAG, Ctor = isBindKey ? undefined2 : createCtor(func);
9112 function wrapper() {
9113 var length = arguments.length, args = Array2(length), index = length;
9115 args[index] = arguments[index];
9118 var placeholder = getHolder(wrapper), holdersCount = countHolders(args, placeholder);
9121 args = composeArgs(args, partials, holders, isCurried);
9123 if (partialsRight) {
9124 args = composeArgsRight(args, partialsRight, holdersRight, isCurried);
9126 length -= holdersCount;
9127 if (isCurried && length < arity) {
9128 var newHolders = replaceHolders(args, placeholder);
9129 return createRecurry(
9133 wrapper.placeholder,
9142 var thisBinding = isBind ? thisArg : this, fn = isBindKey ? thisBinding[func] : func;
9143 length = args.length;
9145 args = reorder(args, argPos);
9146 } else if (isFlip && length > 1) {
9149 if (isAry && ary2 < length) {
9152 if (this && this !== root3 && this instanceof wrapper) {
9153 fn = Ctor || createCtor(fn);
9155 return fn.apply(thisBinding, args);
9159 function createInverter(setter, toIteratee) {
9160 return function(object, iteratee2) {
9161 return baseInverter(object, setter, toIteratee(iteratee2), {});
9164 function createMathOperation(operator, defaultValue) {
9165 return function(value, other) {
9167 if (value === undefined2 && other === undefined2) {
9168 return defaultValue;
9170 if (value !== undefined2) {
9173 if (other !== undefined2) {
9174 if (result2 === undefined2) {
9177 if (typeof value == "string" || typeof other == "string") {
9178 value = baseToString2(value);
9179 other = baseToString2(other);
9181 value = baseToNumber(value);
9182 other = baseToNumber(other);
9184 result2 = operator(value, other);
9189 function createOver(arrayFunc) {
9190 return flatRest(function(iteratees) {
9191 iteratees = arrayMap2(iteratees, baseUnary(getIteratee()));
9192 return baseRest(function(args) {
9194 return arrayFunc(iteratees, function(iteratee2) {
9195 return apply(iteratee2, thisArg, args);
9200 function createPadding(length, chars) {
9201 chars = chars === undefined2 ? " " : baseToString2(chars);
9202 var charsLength = chars.length;
9203 if (charsLength < 2) {
9204 return charsLength ? baseRepeat(chars, length) : chars;
9206 var result2 = baseRepeat(chars, nativeCeil(length / stringSize(chars)));
9207 return hasUnicode(chars) ? castSlice(stringToArray(result2), 0, length).join("") : result2.slice(0, length);
9209 function createPartial(func, bitmask, thisArg, partials) {
9210 var isBind = bitmask & WRAP_BIND_FLAG, Ctor = createCtor(func);
9211 function wrapper() {
9212 var argsIndex = -1, argsLength = arguments.length, leftIndex = -1, leftLength = partials.length, args = Array2(leftLength + argsLength), fn = this && this !== root3 && this instanceof wrapper ? Ctor : func;
9213 while (++leftIndex < leftLength) {
9214 args[leftIndex] = partials[leftIndex];
9216 while (argsLength--) {
9217 args[leftIndex++] = arguments[++argsIndex];
9219 return apply(fn, isBind ? thisArg : this, args);
9223 function createRange(fromRight) {
9224 return function(start2, end, step) {
9225 if (step && typeof step != "number" && isIterateeCall(start2, end, step)) {
9226 end = step = undefined2;
9228 start2 = toFinite(start2);
9229 if (end === undefined2) {
9233 end = toFinite(end);
9235 step = step === undefined2 ? start2 < end ? 1 : -1 : toFinite(step);
9236 return baseRange(start2, end, step, fromRight);
9239 function createRelationalOperation(operator) {
9240 return function(value, other) {
9241 if (!(typeof value == "string" && typeof other == "string")) {
9242 value = toNumber2(value);
9243 other = toNumber2(other);
9245 return operator(value, other);
9248 function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary2, arity) {
9249 var isCurry = bitmask & WRAP_CURRY_FLAG, newHolders = isCurry ? holders : undefined2, newHoldersRight = isCurry ? undefined2 : holders, newPartials = isCurry ? partials : undefined2, newPartialsRight = isCurry ? undefined2 : partials;
9250 bitmask |= isCurry ? WRAP_PARTIAL_FLAG : WRAP_PARTIAL_RIGHT_FLAG;
9251 bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG : WRAP_PARTIAL_FLAG);
9252 if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) {
9253 bitmask &= ~(WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG);
9267 var result2 = wrapFunc.apply(undefined2, newData);
9268 if (isLaziable(func)) {
9269 setData(result2, newData);
9271 result2.placeholder = placeholder;
9272 return setWrapToString(result2, func, bitmask);
9274 function createRound(methodName) {
9275 var func = Math2[methodName];
9276 return function(number3, precision2) {
9277 number3 = toNumber2(number3);
9278 precision2 = precision2 == null ? 0 : nativeMin2(toInteger(precision2), 292);
9279 if (precision2 && nativeIsFinite(number3)) {
9280 var pair2 = (toString2(number3) + "e").split("e"), value = func(pair2[0] + "e" + (+pair2[1] + precision2));
9281 pair2 = (toString2(value) + "e").split("e");
9282 return +(pair2[0] + "e" + (+pair2[1] - precision2));
9284 return func(number3);
9287 var createSet = !(Set2 && 1 / setToArray(new Set2([, -0]))[1] == INFINITY2) ? noop3 : function(values2) {
9288 return new Set2(values2);
9290 function createToPairs(keysFunc) {
9291 return function(object) {
9292 var tag = getTag(object);
9293 if (tag == mapTag) {
9294 return mapToArray(object);
9296 if (tag == setTag) {
9297 return setToPairs(object);
9299 return baseToPairs(object, keysFunc(object));
9302 function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary2, arity) {
9303 var isBindKey = bitmask & WRAP_BIND_KEY_FLAG;
9304 if (!isBindKey && typeof func != "function") {
9305 throw new TypeError2(FUNC_ERROR_TEXT3);
9307 var length = partials ? partials.length : 0;
9309 bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_PARTIAL_RIGHT_FLAG);
9310 partials = holders = undefined2;
9312 ary2 = ary2 === undefined2 ? ary2 : nativeMax2(toInteger(ary2), 0);
9313 arity = arity === undefined2 ? arity : toInteger(arity);
9314 length -= holders ? holders.length : 0;
9315 if (bitmask & WRAP_PARTIAL_RIGHT_FLAG) {
9316 var partialsRight = partials, holdersRight = holders;
9317 partials = holders = undefined2;
9319 var data = isBindKey ? undefined2 : getData(func);
9333 mergeData(newData, data);
9336 bitmask = newData[1];
9337 thisArg = newData[2];
9338 partials = newData[3];
9339 holders = newData[4];
9340 arity = newData[9] = newData[9] === undefined2 ? isBindKey ? 0 : func.length : nativeMax2(newData[9] - length, 0);
9341 if (!arity && bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG)) {
9342 bitmask &= ~(WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG);
9344 if (!bitmask || bitmask == WRAP_BIND_FLAG) {
9345 var result2 = createBind(func, bitmask, thisArg);
9346 } else if (bitmask == WRAP_CURRY_FLAG || bitmask == WRAP_CURRY_RIGHT_FLAG) {
9347 result2 = createCurry(func, bitmask, arity);
9348 } else if ((bitmask == WRAP_PARTIAL_FLAG || bitmask == (WRAP_BIND_FLAG | WRAP_PARTIAL_FLAG)) && !holders.length) {
9349 result2 = createPartial(func, bitmask, thisArg, partials);
9351 result2 = createHybrid.apply(undefined2, newData);
9353 var setter = data ? baseSetData : setData;
9354 return setWrapToString(setter(result2, newData), func, bitmask);
9356 function customDefaultsAssignIn(objValue, srcValue, key, object) {
9357 if (objValue === undefined2 || eq(objValue, objectProto3[key]) && !hasOwnProperty2.call(object, key)) {
9362 function customDefaultsMerge(objValue, srcValue, key, object, source, stack) {
9363 if (isObject3(objValue) && isObject3(srcValue)) {
9364 stack.set(srcValue, objValue);
9365 baseMerge(objValue, srcValue, undefined2, customDefaultsMerge, stack);
9366 stack["delete"](srcValue);
9370 function customOmitClone(value) {
9371 return isPlainObject(value) ? undefined2 : value;
9373 function equalArrays(array2, other, bitmask, customizer, equalFunc, stack) {
9374 var isPartial = bitmask & COMPARE_PARTIAL_FLAG, arrLength = array2.length, othLength = other.length;
9375 if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
9378 var arrStacked = stack.get(array2);
9379 var othStacked = stack.get(other);
9380 if (arrStacked && othStacked) {
9381 return arrStacked == other && othStacked == array2;
9383 var index = -1, result2 = true, seen = bitmask & COMPARE_UNORDERED_FLAG ? new SetCache() : undefined2;
9384 stack.set(array2, other);
9385 stack.set(other, array2);
9386 while (++index < arrLength) {
9387 var arrValue = array2[index], othValue = other[index];
9389 var compared = isPartial ? customizer(othValue, arrValue, index, other, array2, stack) : customizer(arrValue, othValue, index, array2, other, stack);
9391 if (compared !== undefined2) {
9399 if (!arraySome(other, function(othValue2, othIndex) {
9400 if (!cacheHas(seen, othIndex) && (arrValue === othValue2 || equalFunc(arrValue, othValue2, bitmask, customizer, stack))) {
9401 return seen.push(othIndex);
9407 } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {
9412 stack["delete"](array2);
9413 stack["delete"](other);
9416 function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {
9419 if (object.byteLength != other.byteLength || object.byteOffset != other.byteOffset) {
9422 object = object.buffer;
9423 other = other.buffer;
9424 case arrayBufferTag:
9425 if (object.byteLength != other.byteLength || !equalFunc(new Uint8Array2(object), new Uint8Array2(other))) {
9432 return eq(+object, +other);
9434 return object.name == other.name && object.message == other.message;
9437 return object == other + "";
9439 var convert = mapToArray;
9441 var isPartial = bitmask & COMPARE_PARTIAL_FLAG;
9442 convert || (convert = setToArray);
9443 if (object.size != other.size && !isPartial) {
9446 var stacked = stack.get(object);
9448 return stacked == other;
9450 bitmask |= COMPARE_UNORDERED_FLAG;
9451 stack.set(object, other);
9452 var result2 = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);
9453 stack["delete"](object);
9456 if (symbolValueOf) {
9457 return symbolValueOf.call(object) == symbolValueOf.call(other);
9462 function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {
9463 var isPartial = bitmask & COMPARE_PARTIAL_FLAG, objProps = getAllKeys(object), objLength = objProps.length, othProps = getAllKeys(other), othLength = othProps.length;
9464 if (objLength != othLength && !isPartial) {
9467 var index = objLength;
9469 var key = objProps[index];
9470 if (!(isPartial ? key in other : hasOwnProperty2.call(other, key))) {
9474 var objStacked = stack.get(object);
9475 var othStacked = stack.get(other);
9476 if (objStacked && othStacked) {
9477 return objStacked == other && othStacked == object;
9480 stack.set(object, other);
9481 stack.set(other, object);
9482 var skipCtor = isPartial;
9483 while (++index < objLength) {
9484 key = objProps[index];
9485 var objValue = object[key], othValue = other[key];
9487 var compared = isPartial ? customizer(othValue, objValue, key, other, object, stack) : customizer(objValue, othValue, key, object, other, stack);
9489 if (!(compared === undefined2 ? objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack) : compared)) {
9493 skipCtor || (skipCtor = key == "constructor");
9495 if (result2 && !skipCtor) {
9496 var objCtor = object.constructor, othCtor = other.constructor;
9497 if (objCtor != othCtor && ("constructor" in object && "constructor" in other) && !(typeof objCtor == "function" && objCtor instanceof objCtor && typeof othCtor == "function" && othCtor instanceof othCtor)) {
9501 stack["delete"](object);
9502 stack["delete"](other);
9505 function flatRest(func) {
9506 return setToString(overRest(func, undefined2, flatten2), func + "");
9508 function getAllKeys(object) {
9509 return baseGetAllKeys(object, keys, getSymbols);
9511 function getAllKeysIn(object) {
9512 return baseGetAllKeys(object, keysIn, getSymbolsIn);
9514 var getData = !metaMap ? noop3 : function(func) {
9515 return metaMap.get(func);
9517 function getFuncName(func) {
9518 var result2 = func.name + "", array2 = realNames[result2], length = hasOwnProperty2.call(realNames, result2) ? array2.length : 0;
9520 var data = array2[length], otherFunc = data.func;
9521 if (otherFunc == null || otherFunc == func) {
9527 function getHolder(func) {
9528 var object = hasOwnProperty2.call(lodash, "placeholder") ? lodash : func;
9529 return object.placeholder;
9531 function getIteratee() {
9532 var result2 = lodash.iteratee || iteratee;
9533 result2 = result2 === iteratee ? baseIteratee : result2;
9534 return arguments.length ? result2(arguments[0], arguments[1]) : result2;
9536 function getMapData(map3, key) {
9537 var data = map3.__data__;
9538 return isKeyable(key) ? data[typeof key == "string" ? "string" : "hash"] : data.map;
9540 function getMatchData(object) {
9541 var result2 = keys(object), length = result2.length;
9543 var key = result2[length], value = object[key];
9544 result2[length] = [key, value, isStrictComparable(value)];
9548 function getNative(object, key) {
9549 var value = getValue(object, key);
9550 return baseIsNative(value) ? value : undefined2;
9552 function getRawTag2(value) {
9553 var isOwn = hasOwnProperty2.call(value, symToStringTag3), tag = value[symToStringTag3];
9555 value[symToStringTag3] = undefined2;
9556 var unmasked = true;
9559 var result2 = nativeObjectToString3.call(value);
9562 value[symToStringTag3] = tag;
9564 delete value[symToStringTag3];
9569 var getSymbols = !nativeGetSymbols ? stubArray : function(object) {
9570 if (object == null) {
9573 object = Object2(object);
9574 return arrayFilter(nativeGetSymbols(object), function(symbol) {
9575 return propertyIsEnumerable.call(object, symbol);
9578 var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) {
9581 arrayPush(result2, getSymbols(object));
9582 object = getPrototype(object);
9586 var getTag = baseGetTag2;
9587 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) {
9588 getTag = function(value) {
9589 var result2 = baseGetTag2(value), Ctor = result2 == objectTag ? value.constructor : undefined2, ctorString = Ctor ? toSource(Ctor) : "";
9591 switch (ctorString) {
9592 case dataViewCtorString:
9596 case promiseCtorString:
9600 case weakMapCtorString:
9607 function getView(start2, end, transforms) {
9608 var index = -1, length = transforms.length;
9609 while (++index < length) {
9610 var data = transforms[index], size2 = data.size;
9611 switch (data.type) {
9619 end = nativeMin2(end, start2 + size2);
9622 start2 = nativeMax2(start2, end - size2);
9626 return { "start": start2, "end": end };
9628 function getWrapDetails(source) {
9629 var match = source.match(reWrapDetails);
9630 return match ? match[1].split(reSplitDetails) : [];
9632 function hasPath(object, path, hasFunc) {
9633 path = castPath(path, object);
9634 var index = -1, length = path.length, result2 = false;
9635 while (++index < length) {
9636 var key = toKey(path[index]);
9637 if (!(result2 = object != null && hasFunc(object, key))) {
9640 object = object[key];
9642 if (result2 || ++index != length) {
9645 length = object == null ? 0 : object.length;
9646 return !!length && isLength(length) && isIndex(key, length) && (isArray2(object) || isArguments(object));
9648 function initCloneArray(array2) {
9649 var length = array2.length, result2 = new array2.constructor(length);
9650 if (length && typeof array2[0] == "string" && hasOwnProperty2.call(array2, "index")) {
9651 result2.index = array2.index;
9652 result2.input = array2.input;
9656 function initCloneObject(object) {
9657 return typeof object.constructor == "function" && !isPrototype(object) ? baseCreate(getPrototype(object)) : {};
9659 function initCloneByTag(object, tag, isDeep) {
9660 var Ctor = object.constructor;
9662 case arrayBufferTag:
9663 return cloneArrayBuffer(object);
9666 return new Ctor(+object);
9668 return cloneDataView(object, isDeep);
9675 case uint8ClampedTag:
9678 return cloneTypedArray(object, isDeep);
9683 return new Ctor(object);
9685 return cloneRegExp(object);
9689 return cloneSymbol(object);
9692 function insertWrapDetails(source, details) {
9693 var length = details.length;
9697 var lastIndex = length - 1;
9698 details[lastIndex] = (length > 1 ? "& " : "") + details[lastIndex];
9699 details = details.join(length > 2 ? ", " : " ");
9700 return source.replace(reWrapComment, "{\n/* [wrapped with " + details + "] */\n");
9702 function isFlattenable(value) {
9703 return isArray2(value) || isArguments(value) || !!(spreadableSymbol && value && value[spreadableSymbol]);
9705 function isIndex(value, length) {
9706 var type2 = typeof value;
9707 length = length == null ? MAX_SAFE_INTEGER : length;
9708 return !!length && (type2 == "number" || type2 != "symbol" && reIsUint.test(value)) && (value > -1 && value % 1 == 0 && value < length);
9710 function isIterateeCall(value, index, object) {
9711 if (!isObject3(object)) {
9714 var type2 = typeof index;
9715 if (type2 == "number" ? isArrayLike(object) && isIndex(index, object.length) : type2 == "string" && index in object) {
9716 return eq(object[index], value);
9720 function isKey(value, object) {
9721 if (isArray2(value)) {
9724 var type2 = typeof value;
9725 if (type2 == "number" || type2 == "symbol" || type2 == "boolean" || value == null || isSymbol2(value)) {
9728 return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || object != null && value in Object2(object);
9730 function isKeyable(value) {
9731 var type2 = typeof value;
9732 return type2 == "string" || type2 == "number" || type2 == "symbol" || type2 == "boolean" ? value !== "__proto__" : value === null;
9734 function isLaziable(func) {
9735 var funcName = getFuncName(func), other = lodash[funcName];
9736 if (typeof other != "function" || !(funcName in LazyWrapper.prototype)) {
9739 if (func === other) {
9742 var data = getData(other);
9743 return !!data && func === data[0];
9745 function isMasked(func) {
9746 return !!maskSrcKey && maskSrcKey in func;
9748 var isMaskable = coreJsData ? isFunction : stubFalse;
9749 function isPrototype(value) {
9750 var Ctor = value && value.constructor, proto = typeof Ctor == "function" && Ctor.prototype || objectProto3;
9751 return value === proto;
9753 function isStrictComparable(value) {
9754 return value === value && !isObject3(value);
9756 function matchesStrictComparable(key, srcValue) {
9757 return function(object) {
9758 if (object == null) {
9761 return object[key] === srcValue && (srcValue !== undefined2 || key in Object2(object));
9764 function memoizeCapped(func) {
9765 var result2 = memoize(func, function(key) {
9766 if (cache.size === MAX_MEMOIZE_SIZE) {
9771 var cache = result2.cache;
9774 function mergeData(data, source) {
9775 var bitmask = data[1], srcBitmask = source[1], newBitmask = bitmask | srcBitmask, isCommon = newBitmask < (WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG | WRAP_ARY_FLAG);
9776 var isCombo = srcBitmask == WRAP_ARY_FLAG && bitmask == WRAP_CURRY_FLAG || srcBitmask == WRAP_ARY_FLAG && bitmask == WRAP_REARG_FLAG && data[7].length <= source[8] || srcBitmask == (WRAP_ARY_FLAG | WRAP_REARG_FLAG) && source[7].length <= source[8] && bitmask == WRAP_CURRY_FLAG;
9777 if (!(isCommon || isCombo)) {
9780 if (srcBitmask & WRAP_BIND_FLAG) {
9781 data[2] = source[2];
9782 newBitmask |= bitmask & WRAP_BIND_FLAG ? 0 : WRAP_CURRY_BOUND_FLAG;
9784 var value = source[3];
9786 var partials = data[3];
9787 data[3] = partials ? composeArgs(partials, value, source[4]) : value;
9788 data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4];
9793 data[5] = partials ? composeArgsRight(partials, value, source[6]) : value;
9794 data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6];
9800 if (srcBitmask & WRAP_ARY_FLAG) {
9801 data[8] = data[8] == null ? source[8] : nativeMin2(data[8], source[8]);
9803 if (data[9] == null) {
9804 data[9] = source[9];
9806 data[0] = source[0];
9807 data[1] = newBitmask;
9810 function nativeKeysIn(object) {
9812 if (object != null) {
9813 for (var key in Object2(object)) {
9819 function objectToString2(value) {
9820 return nativeObjectToString3.call(value);
9822 function overRest(func, start2, transform3) {
9823 start2 = nativeMax2(start2 === undefined2 ? func.length - 1 : start2, 0);
9825 var args = arguments, index = -1, length = nativeMax2(args.length - start2, 0), array2 = Array2(length);
9826 while (++index < length) {
9827 array2[index] = args[start2 + index];
9830 var otherArgs = Array2(start2 + 1);
9831 while (++index < start2) {
9832 otherArgs[index] = args[index];
9834 otherArgs[start2] = transform3(array2);
9835 return apply(func, this, otherArgs);
9838 function parent(object, path) {
9839 return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1));
9841 function reorder(array2, indexes) {
9842 var arrLength = array2.length, length = nativeMin2(indexes.length, arrLength), oldArray = copyArray(array2);
9844 var index = indexes[length];
9845 array2[length] = isIndex(index, arrLength) ? oldArray[index] : undefined2;
9849 function safeGet(object, key) {
9850 if (key === "constructor" && typeof object[key] === "function") {
9853 if (key == "__proto__") {
9858 var setData = shortOut(baseSetData);
9859 var setTimeout2 = ctxSetTimeout || function(func, wait) {
9860 return root3.setTimeout(func, wait);
9862 var setToString = shortOut(baseSetToString);
9863 function setWrapToString(wrapper, reference, bitmask) {
9864 var source = reference + "";
9865 return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask)));
9867 function shortOut(func) {
9868 var count = 0, lastCalled = 0;
9870 var stamp = nativeNow(), remaining = HOT_SPAN - (stamp - lastCalled);
9872 if (remaining > 0) {
9873 if (++count >= HOT_COUNT) {
9874 return arguments[0];
9879 return func.apply(undefined2, arguments);
9882 function shuffleSelf(array2, size2) {
9883 var index = -1, length = array2.length, lastIndex = length - 1;
9884 size2 = size2 === undefined2 ? length : size2;
9885 while (++index < size2) {
9886 var rand = baseRandom(index, lastIndex), value = array2[rand];
9887 array2[rand] = array2[index];
9888 array2[index] = value;
9890 array2.length = size2;
9893 var stringToPath = memoizeCapped(function(string) {
9895 if (string.charCodeAt(0) === 46) {
9898 string.replace(rePropName, function(match, number3, quote2, subString) {
9899 result2.push(quote2 ? subString.replace(reEscapeChar, "$1") : number3 || match);
9903 function toKey(value) {
9904 if (typeof value == "string" || isSymbol2(value)) {
9907 var result2 = value + "";
9908 return result2 == "0" && 1 / value == -INFINITY2 ? "-0" : result2;
9910 function toSource(func) {
9913 return funcToString.call(func);
9923 function updateWrapDetails(details, bitmask) {
9924 arrayEach(wrapFlags, function(pair2) {
9925 var value = "_." + pair2[0];
9926 if (bitmask & pair2[1] && !arrayIncludes(details, value)) {
9927 details.push(value);
9930 return details.sort();
9932 function wrapperClone(wrapper) {
9933 if (wrapper instanceof LazyWrapper) {
9934 return wrapper.clone();
9936 var result2 = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);
9937 result2.__actions__ = copyArray(wrapper.__actions__);
9938 result2.__index__ = wrapper.__index__;
9939 result2.__values__ = wrapper.__values__;
9942 function chunk(array2, size2, guard) {
9943 if (guard ? isIterateeCall(array2, size2, guard) : size2 === undefined2) {
9946 size2 = nativeMax2(toInteger(size2), 0);
9948 var length = array2 == null ? 0 : array2.length;
9949 if (!length || size2 < 1) {
9952 var index = 0, resIndex = 0, result2 = Array2(nativeCeil(length / size2));
9953 while (index < length) {
9954 result2[resIndex++] = baseSlice(array2, index, index += size2);
9958 function compact(array2) {
9959 var index = -1, length = array2 == null ? 0 : array2.length, resIndex = 0, result2 = [];
9960 while (++index < length) {
9961 var value = array2[index];
9963 result2[resIndex++] = value;
9969 var length = arguments.length;
9973 var args = Array2(length - 1), array2 = arguments[0], index = length;
9975 args[index - 1] = arguments[index];
9977 return arrayPush(isArray2(array2) ? copyArray(array2) : [array2], baseFlatten(args, 1));
9979 var difference = baseRest(function(array2, values2) {
9980 return isArrayLikeObject(array2) ? baseDifference(array2, baseFlatten(values2, 1, isArrayLikeObject, true)) : [];
9982 var differenceBy = baseRest(function(array2, values2) {
9983 var iteratee2 = last(values2);
9984 if (isArrayLikeObject(iteratee2)) {
9985 iteratee2 = undefined2;
9987 return isArrayLikeObject(array2) ? baseDifference(array2, baseFlatten(values2, 1, isArrayLikeObject, true), getIteratee(iteratee2, 2)) : [];
9989 var differenceWith = baseRest(function(array2, values2) {
9990 var comparator = last(values2);
9991 if (isArrayLikeObject(comparator)) {
9992 comparator = undefined2;
9994 return isArrayLikeObject(array2) ? baseDifference(array2, baseFlatten(values2, 1, isArrayLikeObject, true), undefined2, comparator) : [];
9996 function drop(array2, n2, guard) {
9997 var length = array2 == null ? 0 : array2.length;
10001 n2 = guard || n2 === undefined2 ? 1 : toInteger(n2);
10002 return baseSlice(array2, n2 < 0 ? 0 : n2, length);
10004 function dropRight(array2, n2, guard) {
10005 var length = array2 == null ? 0 : array2.length;
10009 n2 = guard || n2 === undefined2 ? 1 : toInteger(n2);
10011 return baseSlice(array2, 0, n2 < 0 ? 0 : n2);
10013 function dropRightWhile(array2, predicate) {
10014 return array2 && array2.length ? baseWhile(array2, getIteratee(predicate, 3), true, true) : [];
10016 function dropWhile(array2, predicate) {
10017 return array2 && array2.length ? baseWhile(array2, getIteratee(predicate, 3), true) : [];
10019 function fill(array2, value, start2, end) {
10020 var length = array2 == null ? 0 : array2.length;
10024 if (start2 && typeof start2 != "number" && isIterateeCall(array2, value, start2)) {
10028 return baseFill(array2, value, start2, end);
10030 function findIndex(array2, predicate, fromIndex) {
10031 var length = array2 == null ? 0 : array2.length;
10035 var index = fromIndex == null ? 0 : toInteger(fromIndex);
10037 index = nativeMax2(length + index, 0);
10039 return baseFindIndex(array2, getIteratee(predicate, 3), index);
10041 function findLastIndex(array2, predicate, fromIndex) {
10042 var length = array2 == null ? 0 : array2.length;
10046 var index = length - 1;
10047 if (fromIndex !== undefined2) {
10048 index = toInteger(fromIndex);
10049 index = fromIndex < 0 ? nativeMax2(length + index, 0) : nativeMin2(index, length - 1);
10051 return baseFindIndex(array2, getIteratee(predicate, 3), index, true);
10053 function flatten2(array2) {
10054 var length = array2 == null ? 0 : array2.length;
10055 return length ? baseFlatten(array2, 1) : [];
10057 function flattenDeep(array2) {
10058 var length = array2 == null ? 0 : array2.length;
10059 return length ? baseFlatten(array2, INFINITY2) : [];
10061 function flattenDepth(array2, depth) {
10062 var length = array2 == null ? 0 : array2.length;
10066 depth = depth === undefined2 ? 1 : toInteger(depth);
10067 return baseFlatten(array2, depth);
10069 function fromPairs(pairs) {
10070 var index = -1, length = pairs == null ? 0 : pairs.length, result2 = {};
10071 while (++index < length) {
10072 var pair2 = pairs[index];
10073 result2[pair2[0]] = pair2[1];
10077 function head(array2) {
10078 return array2 && array2.length ? array2[0] : undefined2;
10080 function indexOf(array2, value, fromIndex) {
10081 var length = array2 == null ? 0 : array2.length;
10085 var index = fromIndex == null ? 0 : toInteger(fromIndex);
10087 index = nativeMax2(length + index, 0);
10089 return baseIndexOf(array2, value, index);
10091 function initial(array2) {
10092 var length = array2 == null ? 0 : array2.length;
10093 return length ? baseSlice(array2, 0, -1) : [];
10095 var intersection = baseRest(function(arrays) {
10096 var mapped = arrayMap2(arrays, castArrayLikeObject);
10097 return mapped.length && mapped[0] === arrays[0] ? baseIntersection(mapped) : [];
10099 var intersectionBy = baseRest(function(arrays) {
10100 var iteratee2 = last(arrays), mapped = arrayMap2(arrays, castArrayLikeObject);
10101 if (iteratee2 === last(mapped)) {
10102 iteratee2 = undefined2;
10106 return mapped.length && mapped[0] === arrays[0] ? baseIntersection(mapped, getIteratee(iteratee2, 2)) : [];
10108 var intersectionWith = baseRest(function(arrays) {
10109 var comparator = last(arrays), mapped = arrayMap2(arrays, castArrayLikeObject);
10110 comparator = typeof comparator == "function" ? comparator : undefined2;
10114 return mapped.length && mapped[0] === arrays[0] ? baseIntersection(mapped, undefined2, comparator) : [];
10116 function join(array2, separator) {
10117 return array2 == null ? "" : nativeJoin.call(array2, separator);
10119 function last(array2) {
10120 var length = array2 == null ? 0 : array2.length;
10121 return length ? array2[length - 1] : undefined2;
10123 function lastIndexOf(array2, value, fromIndex) {
10124 var length = array2 == null ? 0 : array2.length;
10128 var index = length;
10129 if (fromIndex !== undefined2) {
10130 index = toInteger(fromIndex);
10131 index = index < 0 ? nativeMax2(length + index, 0) : nativeMin2(index, length - 1);
10133 return value === value ? strictLastIndexOf(array2, value, index) : baseFindIndex(array2, baseIsNaN, index, true);
10135 function nth(array2, n2) {
10136 return array2 && array2.length ? baseNth(array2, toInteger(n2)) : undefined2;
10138 var pull = baseRest(pullAll);
10139 function pullAll(array2, values2) {
10140 return array2 && array2.length && values2 && values2.length ? basePullAll(array2, values2) : array2;
10142 function pullAllBy(array2, values2, iteratee2) {
10143 return array2 && array2.length && values2 && values2.length ? basePullAll(array2, values2, getIteratee(iteratee2, 2)) : array2;
10145 function pullAllWith(array2, values2, comparator) {
10146 return array2 && array2.length && values2 && values2.length ? basePullAll(array2, values2, undefined2, comparator) : array2;
10148 var pullAt = flatRest(function(array2, indexes) {
10149 var length = array2 == null ? 0 : array2.length, result2 = baseAt(array2, indexes);
10150 basePullAt(array2, arrayMap2(indexes, function(index) {
10151 return isIndex(index, length) ? +index : index;
10152 }).sort(compareAscending));
10155 function remove2(array2, predicate) {
10157 if (!(array2 && array2.length)) {
10160 var index = -1, indexes = [], length = array2.length;
10161 predicate = getIteratee(predicate, 3);
10162 while (++index < length) {
10163 var value = array2[index];
10164 if (predicate(value, index, array2)) {
10165 result2.push(value);
10166 indexes.push(index);
10169 basePullAt(array2, indexes);
10172 function reverse(array2) {
10173 return array2 == null ? array2 : nativeReverse.call(array2);
10175 function slice(array2, start2, end) {
10176 var length = array2 == null ? 0 : array2.length;
10180 if (end && typeof end != "number" && isIterateeCall(array2, start2, end)) {
10184 start2 = start2 == null ? 0 : toInteger(start2);
10185 end = end === undefined2 ? length : toInteger(end);
10187 return baseSlice(array2, start2, end);
10189 function sortedIndex(array2, value) {
10190 return baseSortedIndex(array2, value);
10192 function sortedIndexBy(array2, value, iteratee2) {
10193 return baseSortedIndexBy(array2, value, getIteratee(iteratee2, 2));
10195 function sortedIndexOf(array2, value) {
10196 var length = array2 == null ? 0 : array2.length;
10198 var index = baseSortedIndex(array2, value);
10199 if (index < length && eq(array2[index], value)) {
10205 function sortedLastIndex(array2, value) {
10206 return baseSortedIndex(array2, value, true);
10208 function sortedLastIndexBy(array2, value, iteratee2) {
10209 return baseSortedIndexBy(array2, value, getIteratee(iteratee2, 2), true);
10211 function sortedLastIndexOf(array2, value) {
10212 var length = array2 == null ? 0 : array2.length;
10214 var index = baseSortedIndex(array2, value, true) - 1;
10215 if (eq(array2[index], value)) {
10221 function sortedUniq(array2) {
10222 return array2 && array2.length ? baseSortedUniq(array2) : [];
10224 function sortedUniqBy(array2, iteratee2) {
10225 return array2 && array2.length ? baseSortedUniq(array2, getIteratee(iteratee2, 2)) : [];
10227 function tail(array2) {
10228 var length = array2 == null ? 0 : array2.length;
10229 return length ? baseSlice(array2, 1, length) : [];
10231 function take(array2, n2, guard) {
10232 if (!(array2 && array2.length)) {
10235 n2 = guard || n2 === undefined2 ? 1 : toInteger(n2);
10236 return baseSlice(array2, 0, n2 < 0 ? 0 : n2);
10238 function takeRight(array2, n2, guard) {
10239 var length = array2 == null ? 0 : array2.length;
10243 n2 = guard || n2 === undefined2 ? 1 : toInteger(n2);
10245 return baseSlice(array2, n2 < 0 ? 0 : n2, length);
10247 function takeRightWhile(array2, predicate) {
10248 return array2 && array2.length ? baseWhile(array2, getIteratee(predicate, 3), false, true) : [];
10250 function takeWhile(array2, predicate) {
10251 return array2 && array2.length ? baseWhile(array2, getIteratee(predicate, 3)) : [];
10253 var union = baseRest(function(arrays) {
10254 return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true));
10256 var unionBy = baseRest(function(arrays) {
10257 var iteratee2 = last(arrays);
10258 if (isArrayLikeObject(iteratee2)) {
10259 iteratee2 = undefined2;
10261 return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), getIteratee(iteratee2, 2));
10263 var unionWith = baseRest(function(arrays) {
10264 var comparator = last(arrays);
10265 comparator = typeof comparator == "function" ? comparator : undefined2;
10266 return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), undefined2, comparator);
10268 function uniq(array2) {
10269 return array2 && array2.length ? baseUniq(array2) : [];
10271 function uniqBy(array2, iteratee2) {
10272 return array2 && array2.length ? baseUniq(array2, getIteratee(iteratee2, 2)) : [];
10274 function uniqWith(array2, comparator) {
10275 comparator = typeof comparator == "function" ? comparator : undefined2;
10276 return array2 && array2.length ? baseUniq(array2, undefined2, comparator) : [];
10278 function unzip(array2) {
10279 if (!(array2 && array2.length)) {
10283 array2 = arrayFilter(array2, function(group) {
10284 if (isArrayLikeObject(group)) {
10285 length = nativeMax2(group.length, length);
10289 return baseTimes(length, function(index) {
10290 return arrayMap2(array2, baseProperty(index));
10293 function unzipWith(array2, iteratee2) {
10294 if (!(array2 && array2.length)) {
10297 var result2 = unzip(array2);
10298 if (iteratee2 == null) {
10301 return arrayMap2(result2, function(group) {
10302 return apply(iteratee2, undefined2, group);
10305 var without = baseRest(function(array2, values2) {
10306 return isArrayLikeObject(array2) ? baseDifference(array2, values2) : [];
10308 var xor = baseRest(function(arrays) {
10309 return baseXor(arrayFilter(arrays, isArrayLikeObject));
10311 var xorBy = baseRest(function(arrays) {
10312 var iteratee2 = last(arrays);
10313 if (isArrayLikeObject(iteratee2)) {
10314 iteratee2 = undefined2;
10316 return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee2, 2));
10318 var xorWith = baseRest(function(arrays) {
10319 var comparator = last(arrays);
10320 comparator = typeof comparator == "function" ? comparator : undefined2;
10321 return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined2, comparator);
10323 var zip = baseRest(unzip);
10324 function zipObject(props, values2) {
10325 return baseZipObject(props || [], values2 || [], assignValue);
10327 function zipObjectDeep(props, values2) {
10328 return baseZipObject(props || [], values2 || [], baseSet);
10330 var zipWith = baseRest(function(arrays) {
10331 var length = arrays.length, iteratee2 = length > 1 ? arrays[length - 1] : undefined2;
10332 iteratee2 = typeof iteratee2 == "function" ? (arrays.pop(), iteratee2) : undefined2;
10333 return unzipWith(arrays, iteratee2);
10335 function chain(value) {
10336 var result2 = lodash(value);
10337 result2.__chain__ = true;
10340 function tap(value, interceptor) {
10341 interceptor(value);
10344 function thru(value, interceptor) {
10345 return interceptor(value);
10347 var wrapperAt = flatRest(function(paths) {
10348 var length = paths.length, start2 = length ? paths[0] : 0, value = this.__wrapped__, interceptor = function(object) {
10349 return baseAt(object, paths);
10351 if (length > 1 || this.__actions__.length || !(value instanceof LazyWrapper) || !isIndex(start2)) {
10352 return this.thru(interceptor);
10354 value = value.slice(start2, +start2 + (length ? 1 : 0));
10355 value.__actions__.push({
10357 "args": [interceptor],
10358 "thisArg": undefined2
10360 return new LodashWrapper(value, this.__chain__).thru(function(array2) {
10361 if (length && !array2.length) {
10362 array2.push(undefined2);
10367 function wrapperChain() {
10368 return chain(this);
10370 function wrapperCommit() {
10371 return new LodashWrapper(this.value(), this.__chain__);
10373 function wrapperNext() {
10374 if (this.__values__ === undefined2) {
10375 this.__values__ = toArray(this.value());
10377 var done = this.__index__ >= this.__values__.length, value = done ? undefined2 : this.__values__[this.__index__++];
10378 return { "done": done, "value": value };
10380 function wrapperToIterator() {
10383 function wrapperPlant(value) {
10384 var result2, parent2 = this;
10385 while (parent2 instanceof baseLodash) {
10386 var clone2 = wrapperClone(parent2);
10387 clone2.__index__ = 0;
10388 clone2.__values__ = undefined2;
10390 previous.__wrapped__ = clone2;
10394 var previous = clone2;
10395 parent2 = parent2.__wrapped__;
10397 previous.__wrapped__ = value;
10400 function wrapperReverse() {
10401 var value = this.__wrapped__;
10402 if (value instanceof LazyWrapper) {
10403 var wrapped = value;
10404 if (this.__actions__.length) {
10405 wrapped = new LazyWrapper(this);
10407 wrapped = wrapped.reverse();
10408 wrapped.__actions__.push({
10411 "thisArg": undefined2
10413 return new LodashWrapper(wrapped, this.__chain__);
10415 return this.thru(reverse);
10417 function wrapperValue() {
10418 return baseWrapperValue(this.__wrapped__, this.__actions__);
10420 var countBy = createAggregator(function(result2, value, key) {
10421 if (hasOwnProperty2.call(result2, key)) {
10424 baseAssignValue(result2, key, 1);
10427 function every(collection, predicate, guard) {
10428 var func = isArray2(collection) ? arrayEvery : baseEvery;
10429 if (guard && isIterateeCall(collection, predicate, guard)) {
10430 predicate = undefined2;
10432 return func(collection, getIteratee(predicate, 3));
10434 function filter2(collection, predicate) {
10435 var func = isArray2(collection) ? arrayFilter : baseFilter;
10436 return func(collection, getIteratee(predicate, 3));
10438 var find2 = createFind(findIndex);
10439 var findLast = createFind(findLastIndex);
10440 function flatMap(collection, iteratee2) {
10441 return baseFlatten(map2(collection, iteratee2), 1);
10443 function flatMapDeep(collection, iteratee2) {
10444 return baseFlatten(map2(collection, iteratee2), INFINITY2);
10446 function flatMapDepth(collection, iteratee2, depth) {
10447 depth = depth === undefined2 ? 1 : toInteger(depth);
10448 return baseFlatten(map2(collection, iteratee2), depth);
10450 function forEach(collection, iteratee2) {
10451 var func = isArray2(collection) ? arrayEach : baseEach;
10452 return func(collection, getIteratee(iteratee2, 3));
10454 function forEachRight(collection, iteratee2) {
10455 var func = isArray2(collection) ? arrayEachRight : baseEachRight;
10456 return func(collection, getIteratee(iteratee2, 3));
10458 var groupBy = createAggregator(function(result2, value, key) {
10459 if (hasOwnProperty2.call(result2, key)) {
10460 result2[key].push(value);
10462 baseAssignValue(result2, key, [value]);
10465 function includes(collection, value, fromIndex, guard) {
10466 collection = isArrayLike(collection) ? collection : values(collection);
10467 fromIndex = fromIndex && !guard ? toInteger(fromIndex) : 0;
10468 var length = collection.length;
10469 if (fromIndex < 0) {
10470 fromIndex = nativeMax2(length + fromIndex, 0);
10472 return isString(collection) ? fromIndex <= length && collection.indexOf(value, fromIndex) > -1 : !!length && baseIndexOf(collection, value, fromIndex) > -1;
10474 var invokeMap = baseRest(function(collection, path, args) {
10475 var index = -1, isFunc = typeof path == "function", result2 = isArrayLike(collection) ? Array2(collection.length) : [];
10476 baseEach(collection, function(value) {
10477 result2[++index] = isFunc ? apply(path, value, args) : baseInvoke(value, path, args);
10481 var keyBy = createAggregator(function(result2, value, key) {
10482 baseAssignValue(result2, key, value);
10484 function map2(collection, iteratee2) {
10485 var func = isArray2(collection) ? arrayMap2 : baseMap;
10486 return func(collection, getIteratee(iteratee2, 3));
10488 function orderBy(collection, iteratees, orders, guard) {
10489 if (collection == null) {
10492 if (!isArray2(iteratees)) {
10493 iteratees = iteratees == null ? [] : [iteratees];
10495 orders = guard ? undefined2 : orders;
10496 if (!isArray2(orders)) {
10497 orders = orders == null ? [] : [orders];
10499 return baseOrderBy(collection, iteratees, orders);
10501 var partition = createAggregator(function(result2, value, key) {
10502 result2[key ? 0 : 1].push(value);
10506 function reduce(collection, iteratee2, accumulator) {
10507 var func = isArray2(collection) ? arrayReduce : baseReduce, initAccum = arguments.length < 3;
10508 return func(collection, getIteratee(iteratee2, 4), accumulator, initAccum, baseEach);
10510 function reduceRight(collection, iteratee2, accumulator) {
10511 var func = isArray2(collection) ? arrayReduceRight : baseReduce, initAccum = arguments.length < 3;
10512 return func(collection, getIteratee(iteratee2, 4), accumulator, initAccum, baseEachRight);
10514 function reject(collection, predicate) {
10515 var func = isArray2(collection) ? arrayFilter : baseFilter;
10516 return func(collection, negate(getIteratee(predicate, 3)));
10518 function sample(collection) {
10519 var func = isArray2(collection) ? arraySample : baseSample;
10520 return func(collection);
10522 function sampleSize(collection, n2, guard) {
10523 if (guard ? isIterateeCall(collection, n2, guard) : n2 === undefined2) {
10526 n2 = toInteger(n2);
10528 var func = isArray2(collection) ? arraySampleSize : baseSampleSize;
10529 return func(collection, n2);
10531 function shuffle(collection) {
10532 var func = isArray2(collection) ? arrayShuffle : baseShuffle;
10533 return func(collection);
10535 function size(collection) {
10536 if (collection == null) {
10539 if (isArrayLike(collection)) {
10540 return isString(collection) ? stringSize(collection) : collection.length;
10542 var tag = getTag(collection);
10543 if (tag == mapTag || tag == setTag) {
10544 return collection.size;
10546 return baseKeys(collection).length;
10548 function some(collection, predicate, guard) {
10549 var func = isArray2(collection) ? arraySome : baseSome;
10550 if (guard && isIterateeCall(collection, predicate, guard)) {
10551 predicate = undefined2;
10553 return func(collection, getIteratee(predicate, 3));
10555 var sortBy = baseRest(function(collection, iteratees) {
10556 if (collection == null) {
10559 var length = iteratees.length;
10560 if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) {
10562 } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) {
10563 iteratees = [iteratees[0]];
10565 return baseOrderBy(collection, baseFlatten(iteratees, 1), []);
10567 var now3 = ctxNow || function() {
10568 return root3.Date.now();
10570 function after(n2, func) {
10571 if (typeof func != "function") {
10572 throw new TypeError2(FUNC_ERROR_TEXT3);
10574 n2 = toInteger(n2);
10575 return function() {
10577 return func.apply(this, arguments);
10581 function ary(func, n2, guard) {
10582 n2 = guard ? undefined2 : n2;
10583 n2 = func && n2 == null ? func.length : n2;
10584 return createWrap(func, WRAP_ARY_FLAG, undefined2, undefined2, undefined2, undefined2, n2);
10586 function before(n2, func) {
10588 if (typeof func != "function") {
10589 throw new TypeError2(FUNC_ERROR_TEXT3);
10591 n2 = toInteger(n2);
10592 return function() {
10594 result2 = func.apply(this, arguments);
10602 var bind = baseRest(function(func, thisArg, partials) {
10603 var bitmask = WRAP_BIND_FLAG;
10604 if (partials.length) {
10605 var holders = replaceHolders(partials, getHolder(bind));
10606 bitmask |= WRAP_PARTIAL_FLAG;
10608 return createWrap(func, bitmask, thisArg, partials, holders);
10610 var bindKey2 = baseRest(function(object, key, partials) {
10611 var bitmask = WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG;
10612 if (partials.length) {
10613 var holders = replaceHolders(partials, getHolder(bindKey2));
10614 bitmask |= WRAP_PARTIAL_FLAG;
10616 return createWrap(key, bitmask, object, partials, holders);
10618 function curry(func, arity, guard) {
10619 arity = guard ? undefined2 : arity;
10620 var result2 = createWrap(func, WRAP_CURRY_FLAG, undefined2, undefined2, undefined2, undefined2, undefined2, arity);
10621 result2.placeholder = curry.placeholder;
10624 function curryRight(func, arity, guard) {
10625 arity = guard ? undefined2 : arity;
10626 var result2 = createWrap(func, WRAP_CURRY_RIGHT_FLAG, undefined2, undefined2, undefined2, undefined2, undefined2, arity);
10627 result2.placeholder = curryRight.placeholder;
10630 function debounce2(func, wait, options2) {
10631 var lastArgs, lastThis, maxWait, result2, timerId, lastCallTime, lastInvokeTime = 0, leading = false, maxing = false, trailing = true;
10632 if (typeof func != "function") {
10633 throw new TypeError2(FUNC_ERROR_TEXT3);
10635 wait = toNumber2(wait) || 0;
10636 if (isObject3(options2)) {
10637 leading = !!options2.leading;
10638 maxing = "maxWait" in options2;
10639 maxWait = maxing ? nativeMax2(toNumber2(options2.maxWait) || 0, wait) : maxWait;
10640 trailing = "trailing" in options2 ? !!options2.trailing : trailing;
10642 function invokeFunc(time) {
10643 var args = lastArgs, thisArg = lastThis;
10644 lastArgs = lastThis = undefined2;
10645 lastInvokeTime = time;
10646 result2 = func.apply(thisArg, args);
10649 function leadingEdge(time) {
10650 lastInvokeTime = time;
10651 timerId = setTimeout2(timerExpired, wait);
10652 return leading ? invokeFunc(time) : result2;
10654 function remainingWait(time) {
10655 var timeSinceLastCall = time - lastCallTime, timeSinceLastInvoke = time - lastInvokeTime, timeWaiting = wait - timeSinceLastCall;
10656 return maxing ? nativeMin2(timeWaiting, maxWait - timeSinceLastInvoke) : timeWaiting;
10658 function shouldInvoke(time) {
10659 var timeSinceLastCall = time - lastCallTime, timeSinceLastInvoke = time - lastInvokeTime;
10660 return lastCallTime === undefined2 || timeSinceLastCall >= wait || timeSinceLastCall < 0 || maxing && timeSinceLastInvoke >= maxWait;
10662 function timerExpired() {
10664 if (shouldInvoke(time)) {
10665 return trailingEdge(time);
10667 timerId = setTimeout2(timerExpired, remainingWait(time));
10669 function trailingEdge(time) {
10670 timerId = undefined2;
10671 if (trailing && lastArgs) {
10672 return invokeFunc(time);
10674 lastArgs = lastThis = undefined2;
10677 function cancel() {
10678 if (timerId !== undefined2) {
10679 clearTimeout2(timerId);
10681 lastInvokeTime = 0;
10682 lastArgs = lastCallTime = lastThis = timerId = undefined2;
10685 return timerId === undefined2 ? result2 : trailingEdge(now3());
10687 function debounced() {
10688 var time = now3(), isInvoking = shouldInvoke(time);
10689 lastArgs = arguments;
10691 lastCallTime = time;
10693 if (timerId === undefined2) {
10694 return leadingEdge(lastCallTime);
10697 clearTimeout2(timerId);
10698 timerId = setTimeout2(timerExpired, wait);
10699 return invokeFunc(lastCallTime);
10702 if (timerId === undefined2) {
10703 timerId = setTimeout2(timerExpired, wait);
10707 debounced.cancel = cancel;
10708 debounced.flush = flush;
10711 var defer = baseRest(function(func, args) {
10712 return baseDelay(func, 1, args);
10714 var delay = baseRest(function(func, wait, args) {
10715 return baseDelay(func, toNumber2(wait) || 0, args);
10717 function flip(func) {
10718 return createWrap(func, WRAP_FLIP_FLAG);
10720 function memoize(func, resolver) {
10721 if (typeof func != "function" || resolver != null && typeof resolver != "function") {
10722 throw new TypeError2(FUNC_ERROR_TEXT3);
10724 var memoized = function() {
10725 var args = arguments, key = resolver ? resolver.apply(this, args) : args[0], cache = memoized.cache;
10726 if (cache.has(key)) {
10727 return cache.get(key);
10729 var result2 = func.apply(this, args);
10730 memoized.cache = cache.set(key, result2) || cache;
10733 memoized.cache = new (memoize.Cache || MapCache)();
10736 memoize.Cache = MapCache;
10737 function negate(predicate) {
10738 if (typeof predicate != "function") {
10739 throw new TypeError2(FUNC_ERROR_TEXT3);
10741 return function() {
10742 var args = arguments;
10743 switch (args.length) {
10745 return !predicate.call(this);
10747 return !predicate.call(this, args[0]);
10749 return !predicate.call(this, args[0], args[1]);
10751 return !predicate.call(this, args[0], args[1], args[2]);
10753 return !predicate.apply(this, args);
10756 function once(func) {
10757 return before(2, func);
10759 var overArgs = castRest(function(func, transforms) {
10760 transforms = transforms.length == 1 && isArray2(transforms[0]) ? arrayMap2(transforms[0], baseUnary(getIteratee())) : arrayMap2(baseFlatten(transforms, 1), baseUnary(getIteratee()));
10761 var funcsLength = transforms.length;
10762 return baseRest(function(args) {
10763 var index = -1, length = nativeMin2(args.length, funcsLength);
10764 while (++index < length) {
10765 args[index] = transforms[index].call(this, args[index]);
10767 return apply(func, this, args);
10770 var partial = baseRest(function(func, partials) {
10771 var holders = replaceHolders(partials, getHolder(partial));
10772 return createWrap(func, WRAP_PARTIAL_FLAG, undefined2, partials, holders);
10774 var partialRight = baseRest(function(func, partials) {
10775 var holders = replaceHolders(partials, getHolder(partialRight));
10776 return createWrap(func, WRAP_PARTIAL_RIGHT_FLAG, undefined2, partials, holders);
10778 var rearg = flatRest(function(func, indexes) {
10779 return createWrap(func, WRAP_REARG_FLAG, undefined2, undefined2, undefined2, indexes);
10781 function rest(func, start2) {
10782 if (typeof func != "function") {
10783 throw new TypeError2(FUNC_ERROR_TEXT3);
10785 start2 = start2 === undefined2 ? start2 : toInteger(start2);
10786 return baseRest(func, start2);
10788 function spread(func, start2) {
10789 if (typeof func != "function") {
10790 throw new TypeError2(FUNC_ERROR_TEXT3);
10792 start2 = start2 == null ? 0 : nativeMax2(toInteger(start2), 0);
10793 return baseRest(function(args) {
10794 var array2 = args[start2], otherArgs = castSlice(args, 0, start2);
10796 arrayPush(otherArgs, array2);
10798 return apply(func, this, otherArgs);
10801 function throttle2(func, wait, options2) {
10802 var leading = true, trailing = true;
10803 if (typeof func != "function") {
10804 throw new TypeError2(FUNC_ERROR_TEXT3);
10806 if (isObject3(options2)) {
10807 leading = "leading" in options2 ? !!options2.leading : leading;
10808 trailing = "trailing" in options2 ? !!options2.trailing : trailing;
10810 return debounce2(func, wait, {
10811 "leading": leading,
10813 "trailing": trailing
10816 function unary(func) {
10817 return ary(func, 1);
10819 function wrap2(value, wrapper) {
10820 return partial(castFunction(wrapper), value);
10822 function castArray() {
10823 if (!arguments.length) {
10826 var value = arguments[0];
10827 return isArray2(value) ? value : [value];
10829 function clone(value) {
10830 return baseClone(value, CLONE_SYMBOLS_FLAG);
10832 function cloneWith(value, customizer) {
10833 customizer = typeof customizer == "function" ? customizer : undefined2;
10834 return baseClone(value, CLONE_SYMBOLS_FLAG, customizer);
10836 function cloneDeep(value) {
10837 return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG);
10839 function cloneDeepWith(value, customizer) {
10840 customizer = typeof customizer == "function" ? customizer : undefined2;
10841 return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG, customizer);
10843 function conformsTo(object, source) {
10844 return source == null || baseConformsTo(object, source, keys(source));
10846 function eq(value, other) {
10847 return value === other || value !== value && other !== other;
10849 var gt = createRelationalOperation(baseGt);
10850 var gte = createRelationalOperation(function(value, other) {
10851 return value >= other;
10853 var isArguments = baseIsArguments(function() {
10855 }()) ? baseIsArguments : function(value) {
10856 return isObjectLike2(value) && hasOwnProperty2.call(value, "callee") && !propertyIsEnumerable.call(value, "callee");
10858 var isArray2 = Array2.isArray;
10859 var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer;
10860 function isArrayLike(value) {
10861 return value != null && isLength(value.length) && !isFunction(value);
10863 function isArrayLikeObject(value) {
10864 return isObjectLike2(value) && isArrayLike(value);
10866 function isBoolean(value) {
10867 return value === true || value === false || isObjectLike2(value) && baseGetTag2(value) == boolTag;
10869 var isBuffer = nativeIsBuffer || stubFalse;
10870 var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate;
10871 function isElement2(value) {
10872 return isObjectLike2(value) && value.nodeType === 1 && !isPlainObject(value);
10874 function isEmpty(value) {
10875 if (value == null) {
10878 if (isArrayLike(value) && (isArray2(value) || typeof value == "string" || typeof value.splice == "function" || isBuffer(value) || isTypedArray(value) || isArguments(value))) {
10879 return !value.length;
10881 var tag = getTag(value);
10882 if (tag == mapTag || tag == setTag) {
10883 return !value.size;
10885 if (isPrototype(value)) {
10886 return !baseKeys(value).length;
10888 for (var key in value) {
10889 if (hasOwnProperty2.call(value, key)) {
10895 function isEqual(value, other) {
10896 return baseIsEqual(value, other);
10898 function isEqualWith(value, other, customizer) {
10899 customizer = typeof customizer == "function" ? customizer : undefined2;
10900 var result2 = customizer ? customizer(value, other) : undefined2;
10901 return result2 === undefined2 ? baseIsEqual(value, other, undefined2, customizer) : !!result2;
10903 function isError(value) {
10904 if (!isObjectLike2(value)) {
10907 var tag = baseGetTag2(value);
10908 return tag == errorTag || tag == domExcTag || typeof value.message == "string" && typeof value.name == "string" && !isPlainObject(value);
10910 function isFinite2(value) {
10911 return typeof value == "number" && nativeIsFinite(value);
10913 function isFunction(value) {
10914 if (!isObject3(value)) {
10917 var tag = baseGetTag2(value);
10918 return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
10920 function isInteger(value) {
10921 return typeof value == "number" && value == toInteger(value);
10923 function isLength(value) {
10924 return typeof value == "number" && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
10926 function isObject3(value) {
10927 var type2 = typeof value;
10928 return value != null && (type2 == "object" || type2 == "function");
10930 function isObjectLike2(value) {
10931 return value != null && typeof value == "object";
10933 var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap;
10934 function isMatch(object, source) {
10935 return object === source || baseIsMatch(object, source, getMatchData(source));
10937 function isMatchWith(object, source, customizer) {
10938 customizer = typeof customizer == "function" ? customizer : undefined2;
10939 return baseIsMatch(object, source, getMatchData(source), customizer);
10941 function isNaN2(value) {
10942 return isNumber2(value) && value != +value;
10944 function isNative(value) {
10945 if (isMaskable(value)) {
10946 throw new Error2(CORE_ERROR_TEXT);
10948 return baseIsNative(value);
10950 function isNull(value) {
10951 return value === null;
10953 function isNil(value) {
10954 return value == null;
10956 function isNumber2(value) {
10957 return typeof value == "number" || isObjectLike2(value) && baseGetTag2(value) == numberTag;
10959 function isPlainObject(value) {
10960 if (!isObjectLike2(value) || baseGetTag2(value) != objectTag) {
10963 var proto = getPrototype(value);
10964 if (proto === null) {
10967 var Ctor = hasOwnProperty2.call(proto, "constructor") && proto.constructor;
10968 return typeof Ctor == "function" && Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString;
10970 var isRegExp = nodeIsRegExp ? baseUnary(nodeIsRegExp) : baseIsRegExp;
10971 function isSafeInteger(value) {
10972 return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER;
10974 var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet;
10975 function isString(value) {
10976 return typeof value == "string" || !isArray2(value) && isObjectLike2(value) && baseGetTag2(value) == stringTag;
10978 function isSymbol2(value) {
10979 return typeof value == "symbol" || isObjectLike2(value) && baseGetTag2(value) == symbolTag2;
10981 var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;
10982 function isUndefined(value) {
10983 return value === undefined2;
10985 function isWeakMap(value) {
10986 return isObjectLike2(value) && getTag(value) == weakMapTag;
10988 function isWeakSet(value) {
10989 return isObjectLike2(value) && baseGetTag2(value) == weakSetTag;
10991 var lt = createRelationalOperation(baseLt);
10992 var lte = createRelationalOperation(function(value, other) {
10993 return value <= other;
10995 function toArray(value) {
10999 if (isArrayLike(value)) {
11000 return isString(value) ? stringToArray(value) : copyArray(value);
11002 if (symIterator && value[symIterator]) {
11003 return iteratorToArray(value[symIterator]());
11005 var tag = getTag(value), func = tag == mapTag ? mapToArray : tag == setTag ? setToArray : values;
11006 return func(value);
11008 function toFinite(value) {
11010 return value === 0 ? value : 0;
11012 value = toNumber2(value);
11013 if (value === INFINITY2 || value === -INFINITY2) {
11014 var sign2 = value < 0 ? -1 : 1;
11015 return sign2 * MAX_INTEGER;
11017 return value === value ? value : 0;
11019 function toInteger(value) {
11020 var result2 = toFinite(value), remainder = result2 % 1;
11021 return result2 === result2 ? remainder ? result2 - remainder : result2 : 0;
11023 function toLength(value) {
11024 return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0;
11026 function toNumber2(value) {
11027 if (typeof value == "number") {
11030 if (isSymbol2(value)) {
11033 if (isObject3(value)) {
11034 var other = typeof value.valueOf == "function" ? value.valueOf() : value;
11035 value = isObject3(other) ? other + "" : other;
11037 if (typeof value != "string") {
11038 return value === 0 ? value : +value;
11040 value = baseTrim2(value);
11041 var isBinary = reIsBinary2.test(value);
11042 return isBinary || reIsOctal2.test(value) ? freeParseInt2(value.slice(2), isBinary ? 2 : 8) : reIsBadHex2.test(value) ? NAN2 : +value;
11044 function toPlainObject(value) {
11045 return copyObject(value, keysIn(value));
11047 function toSafeInteger(value) {
11048 return value ? baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER) : value === 0 ? value : 0;
11050 function toString2(value) {
11051 return value == null ? "" : baseToString2(value);
11053 var assign = createAssigner(function(object, source) {
11054 if (isPrototype(source) || isArrayLike(source)) {
11055 copyObject(source, keys(source), object);
11058 for (var key in source) {
11059 if (hasOwnProperty2.call(source, key)) {
11060 assignValue(object, key, source[key]);
11064 var assignIn = createAssigner(function(object, source) {
11065 copyObject(source, keysIn(source), object);
11067 var assignInWith = createAssigner(function(object, source, srcIndex, customizer) {
11068 copyObject(source, keysIn(source), object, customizer);
11070 var assignWith = createAssigner(function(object, source, srcIndex, customizer) {
11071 copyObject(source, keys(source), object, customizer);
11073 var at = flatRest(baseAt);
11074 function create2(prototype, properties) {
11075 var result2 = baseCreate(prototype);
11076 return properties == null ? result2 : baseAssign(result2, properties);
11078 var defaults2 = baseRest(function(object, sources) {
11079 object = Object2(object);
11081 var length = sources.length;
11082 var guard = length > 2 ? sources[2] : undefined2;
11083 if (guard && isIterateeCall(sources[0], sources[1], guard)) {
11086 while (++index < length) {
11087 var source = sources[index];
11088 var props = keysIn(source);
11089 var propsIndex = -1;
11090 var propsLength = props.length;
11091 while (++propsIndex < propsLength) {
11092 var key = props[propsIndex];
11093 var value = object[key];
11094 if (value === undefined2 || eq(value, objectProto3[key]) && !hasOwnProperty2.call(object, key)) {
11095 object[key] = source[key];
11101 var defaultsDeep = baseRest(function(args) {
11102 args.push(undefined2, customDefaultsMerge);
11103 return apply(mergeWith, undefined2, args);
11105 function findKey(object, predicate) {
11106 return baseFindKey(object, getIteratee(predicate, 3), baseForOwn);
11108 function findLastKey(object, predicate) {
11109 return baseFindKey(object, getIteratee(predicate, 3), baseForOwnRight);
11111 function forIn(object, iteratee2) {
11112 return object == null ? object : baseFor(object, getIteratee(iteratee2, 3), keysIn);
11114 function forInRight(object, iteratee2) {
11115 return object == null ? object : baseForRight(object, getIteratee(iteratee2, 3), keysIn);
11117 function forOwn(object, iteratee2) {
11118 return object && baseForOwn(object, getIteratee(iteratee2, 3));
11120 function forOwnRight(object, iteratee2) {
11121 return object && baseForOwnRight(object, getIteratee(iteratee2, 3));
11123 function functions(object) {
11124 return object == null ? [] : baseFunctions(object, keys(object));
11126 function functionsIn(object) {
11127 return object == null ? [] : baseFunctions(object, keysIn(object));
11129 function get4(object, path, defaultValue) {
11130 var result2 = object == null ? undefined2 : baseGet(object, path);
11131 return result2 === undefined2 ? defaultValue : result2;
11133 function has(object, path) {
11134 return object != null && hasPath(object, path, baseHas);
11136 function hasIn(object, path) {
11137 return object != null && hasPath(object, path, baseHasIn);
11139 var invert = createInverter(function(result2, value, key) {
11140 if (value != null && typeof value.toString != "function") {
11141 value = nativeObjectToString3.call(value);
11143 result2[value] = key;
11144 }, constant(identity4));
11145 var invertBy = createInverter(function(result2, value, key) {
11146 if (value != null && typeof value.toString != "function") {
11147 value = nativeObjectToString3.call(value);
11149 if (hasOwnProperty2.call(result2, value)) {
11150 result2[value].push(key);
11152 result2[value] = [key];
11155 var invoke = baseRest(baseInvoke);
11156 function keys(object) {
11157 return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);
11159 function keysIn(object) {
11160 return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);
11162 function mapKeys(object, iteratee2) {
11164 iteratee2 = getIteratee(iteratee2, 3);
11165 baseForOwn(object, function(value, key, object2) {
11166 baseAssignValue(result2, iteratee2(value, key, object2), value);
11170 function mapValues(object, iteratee2) {
11172 iteratee2 = getIteratee(iteratee2, 3);
11173 baseForOwn(object, function(value, key, object2) {
11174 baseAssignValue(result2, key, iteratee2(value, key, object2));
11178 var merge3 = createAssigner(function(object, source, srcIndex) {
11179 baseMerge(object, source, srcIndex);
11181 var mergeWith = createAssigner(function(object, source, srcIndex, customizer) {
11182 baseMerge(object, source, srcIndex, customizer);
11184 var omit = flatRest(function(object, paths) {
11186 if (object == null) {
11189 var isDeep = false;
11190 paths = arrayMap2(paths, function(path) {
11191 path = castPath(path, object);
11192 isDeep || (isDeep = path.length > 1);
11195 copyObject(object, getAllKeysIn(object), result2);
11197 result2 = baseClone(result2, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone);
11199 var length = paths.length;
11201 baseUnset(result2, paths[length]);
11205 function omitBy(object, predicate) {
11206 return pickBy(object, negate(getIteratee(predicate)));
11208 var pick = flatRest(function(object, paths) {
11209 return object == null ? {} : basePick(object, paths);
11211 function pickBy(object, predicate) {
11212 if (object == null) {
11215 var props = arrayMap2(getAllKeysIn(object), function(prop) {
11218 predicate = getIteratee(predicate);
11219 return basePickBy(object, props, function(value, path) {
11220 return predicate(value, path[0]);
11223 function result(object, path, defaultValue) {
11224 path = castPath(path, object);
11225 var index = -1, length = path.length;
11228 object = undefined2;
11230 while (++index < length) {
11231 var value = object == null ? undefined2 : object[toKey(path[index])];
11232 if (value === undefined2) {
11234 value = defaultValue;
11236 object = isFunction(value) ? value.call(object) : value;
11240 function set3(object, path, value) {
11241 return object == null ? object : baseSet(object, path, value);
11243 function setWith(object, path, value, customizer) {
11244 customizer = typeof customizer == "function" ? customizer : undefined2;
11245 return object == null ? object : baseSet(object, path, value, customizer);
11247 var toPairs = createToPairs(keys);
11248 var toPairsIn = createToPairs(keysIn);
11249 function transform2(object, iteratee2, accumulator) {
11250 var isArr = isArray2(object), isArrLike = isArr || isBuffer(object) || isTypedArray(object);
11251 iteratee2 = getIteratee(iteratee2, 4);
11252 if (accumulator == null) {
11253 var Ctor = object && object.constructor;
11255 accumulator = isArr ? new Ctor() : [];
11256 } else if (isObject3(object)) {
11257 accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {};
11262 (isArrLike ? arrayEach : baseForOwn)(object, function(value, index, object2) {
11263 return iteratee2(accumulator, value, index, object2);
11265 return accumulator;
11267 function unset(object, path) {
11268 return object == null ? true : baseUnset(object, path);
11270 function update(object, path, updater) {
11271 return object == null ? object : baseUpdate(object, path, castFunction(updater));
11273 function updateWith(object, path, updater, customizer) {
11274 customizer = typeof customizer == "function" ? customizer : undefined2;
11275 return object == null ? object : baseUpdate(object, path, castFunction(updater), customizer);
11277 function values(object) {
11278 return object == null ? [] : baseValues(object, keys(object));
11280 function valuesIn(object) {
11281 return object == null ? [] : baseValues(object, keysIn(object));
11283 function clamp3(number3, lower2, upper) {
11284 if (upper === undefined2) {
11286 lower2 = undefined2;
11288 if (upper !== undefined2) {
11289 upper = toNumber2(upper);
11290 upper = upper === upper ? upper : 0;
11292 if (lower2 !== undefined2) {
11293 lower2 = toNumber2(lower2);
11294 lower2 = lower2 === lower2 ? lower2 : 0;
11296 return baseClamp(toNumber2(number3), lower2, upper);
11298 function inRange(number3, start2, end) {
11299 start2 = toFinite(start2);
11300 if (end === undefined2) {
11304 end = toFinite(end);
11306 number3 = toNumber2(number3);
11307 return baseInRange(number3, start2, end);
11309 function random(lower2, upper, floating) {
11310 if (floating && typeof floating != "boolean" && isIterateeCall(lower2, upper, floating)) {
11311 upper = floating = undefined2;
11313 if (floating === undefined2) {
11314 if (typeof upper == "boolean") {
11316 upper = undefined2;
11317 } else if (typeof lower2 == "boolean") {
11319 lower2 = undefined2;
11322 if (lower2 === undefined2 && upper === undefined2) {
11326 lower2 = toFinite(lower2);
11327 if (upper === undefined2) {
11331 upper = toFinite(upper);
11334 if (lower2 > upper) {
11339 if (floating || lower2 % 1 || upper % 1) {
11340 var rand = nativeRandom();
11341 return nativeMin2(lower2 + rand * (upper - lower2 + freeParseFloat("1e-" + ((rand + "").length - 1))), upper);
11343 return baseRandom(lower2, upper);
11345 var camelCase = createCompounder(function(result2, word, index) {
11346 word = word.toLowerCase();
11347 return result2 + (index ? capitalize(word) : word);
11349 function capitalize(string) {
11350 return upperFirst(toString2(string).toLowerCase());
11352 function deburr(string) {
11353 string = toString2(string);
11354 return string && string.replace(reLatin, deburrLetter).replace(reComboMark, "");
11356 function endsWith(string, target, position) {
11357 string = toString2(string);
11358 target = baseToString2(target);
11359 var length = string.length;
11360 position = position === undefined2 ? length : baseClamp(toInteger(position), 0, length);
11361 var end = position;
11362 position -= target.length;
11363 return position >= 0 && string.slice(position, end) == target;
11365 function escape6(string) {
11366 string = toString2(string);
11367 return string && reHasUnescapedHtml2.test(string) ? string.replace(reUnescapedHtml2, escapeHtmlChar2) : string;
11369 function escapeRegExp(string) {
11370 string = toString2(string);
11371 return string && reHasRegExpChar.test(string) ? string.replace(reRegExpChar, "\\$&") : string;
11373 var kebabCase = createCompounder(function(result2, word, index) {
11374 return result2 + (index ? "-" : "") + word.toLowerCase();
11376 var lowerCase = createCompounder(function(result2, word, index) {
11377 return result2 + (index ? " " : "") + word.toLowerCase();
11379 var lowerFirst = createCaseFirst("toLowerCase");
11380 function pad2(string, length, chars) {
11381 string = toString2(string);
11382 length = toInteger(length);
11383 var strLength = length ? stringSize(string) : 0;
11384 if (!length || strLength >= length) {
11387 var mid = (length - strLength) / 2;
11388 return createPadding(nativeFloor(mid), chars) + string + createPadding(nativeCeil(mid), chars);
11390 function padEnd(string, length, chars) {
11391 string = toString2(string);
11392 length = toInteger(length);
11393 var strLength = length ? stringSize(string) : 0;
11394 return length && strLength < length ? string + createPadding(length - strLength, chars) : string;
11396 function padStart(string, length, chars) {
11397 string = toString2(string);
11398 length = toInteger(length);
11399 var strLength = length ? stringSize(string) : 0;
11400 return length && strLength < length ? createPadding(length - strLength, chars) + string : string;
11402 function parseInt2(string, radix, guard) {
11403 if (guard || radix == null) {
11405 } else if (radix) {
11408 return nativeParseInt(toString2(string).replace(reTrimStart2, ""), radix || 0);
11410 function repeat(string, n2, guard) {
11411 if (guard ? isIterateeCall(string, n2, guard) : n2 === undefined2) {
11414 n2 = toInteger(n2);
11416 return baseRepeat(toString2(string), n2);
11418 function replace() {
11419 var args = arguments, string = toString2(args[0]);
11420 return args.length < 3 ? string : string.replace(args[1], args[2]);
11422 var snakeCase = createCompounder(function(result2, word, index) {
11423 return result2 + (index ? "_" : "") + word.toLowerCase();
11425 function split(string, separator, limit) {
11426 if (limit && typeof limit != "number" && isIterateeCall(string, separator, limit)) {
11427 separator = limit = undefined2;
11429 limit = limit === undefined2 ? MAX_ARRAY_LENGTH : limit >>> 0;
11433 string = toString2(string);
11434 if (string && (typeof separator == "string" || separator != null && !isRegExp(separator))) {
11435 separator = baseToString2(separator);
11436 if (!separator && hasUnicode(string)) {
11437 return castSlice(stringToArray(string), 0, limit);
11440 return string.split(separator, limit);
11442 var startCase = createCompounder(function(result2, word, index) {
11443 return result2 + (index ? " " : "") + upperFirst(word);
11445 function startsWith(string, target, position) {
11446 string = toString2(string);
11447 position = position == null ? 0 : baseClamp(toInteger(position), 0, string.length);
11448 target = baseToString2(target);
11449 return string.slice(position, position + target.length) == target;
11451 function template(string, options2, guard) {
11452 var settings = lodash.templateSettings;
11453 if (guard && isIterateeCall(string, options2, guard)) {
11454 options2 = undefined2;
11456 string = toString2(string);
11457 options2 = assignInWith({}, options2, settings, customDefaultsAssignIn);
11458 var imports = assignInWith({}, options2.imports, settings.imports, customDefaultsAssignIn), importsKeys = keys(imports), importsValues = baseValues(imports, importsKeys);
11459 var isEscaping, isEvaluating, index = 0, interpolate = options2.interpolate || reNoMatch, source = "__p += '";
11460 var reDelimiters = RegExp2(
11461 (options2.escape || reNoMatch).source + "|" + interpolate.source + "|" + (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + "|" + (options2.evaluate || reNoMatch).source + "|$",
11464 var sourceURL = "//# sourceURL=" + (hasOwnProperty2.call(options2, "sourceURL") ? (options2.sourceURL + "").replace(/\s/g, " ") : "lodash.templateSources[" + ++templateCounter + "]") + "\n";
11465 string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
11466 interpolateValue || (interpolateValue = esTemplateValue);
11467 source += string.slice(index, offset).replace(reUnescapedString, escapeStringChar);
11470 source += "' +\n__e(" + escapeValue + ") +\n'";
11472 if (evaluateValue) {
11473 isEvaluating = true;
11474 source += "';\n" + evaluateValue + ";\n__p += '";
11476 if (interpolateValue) {
11477 source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
11479 index = offset + match.length;
11483 var variable = hasOwnProperty2.call(options2, "variable") && options2.variable;
11485 source = "with (obj) {\n" + source + "\n}\n";
11486 } else if (reForbiddenIdentifierChars.test(variable)) {
11487 throw new Error2(INVALID_TEMPL_VAR_ERROR_TEXT);
11489 source = (isEvaluating ? source.replace(reEmptyStringLeading, "") : source).replace(reEmptyStringMiddle, "$1").replace(reEmptyStringTrailing, "$1;");
11490 source = "function(" + (variable || "obj") + ") {\n" + (variable ? "" : "obj || (obj = {});\n") + "var __t, __p = ''" + (isEscaping ? ", __e = _.escape" : "") + (isEvaluating ? ", __j = Array.prototype.join;\nfunction print() { __p += __j.call(arguments, '') }\n" : ";\n") + source + "return __p\n}";
11491 var result2 = attempt(function() {
11492 return Function2(importsKeys, sourceURL + "return " + source).apply(undefined2, importsValues);
11494 result2.source = source;
11495 if (isError(result2)) {
11500 function toLower(value) {
11501 return toString2(value).toLowerCase();
11503 function toUpper(value) {
11504 return toString2(value).toUpperCase();
11506 function trim(string, chars, guard) {
11507 string = toString2(string);
11508 if (string && (guard || chars === undefined2)) {
11509 return baseTrim2(string);
11511 if (!string || !(chars = baseToString2(chars))) {
11514 var strSymbols = stringToArray(string), chrSymbols = stringToArray(chars), start2 = charsStartIndex(strSymbols, chrSymbols), end = charsEndIndex(strSymbols, chrSymbols) + 1;
11515 return castSlice(strSymbols, start2, end).join("");
11517 function trimEnd(string, chars, guard) {
11518 string = toString2(string);
11519 if (string && (guard || chars === undefined2)) {
11520 return string.slice(0, trimmedEndIndex2(string) + 1);
11522 if (!string || !(chars = baseToString2(chars))) {
11525 var strSymbols = stringToArray(string), end = charsEndIndex(strSymbols, stringToArray(chars)) + 1;
11526 return castSlice(strSymbols, 0, end).join("");
11528 function trimStart(string, chars, guard) {
11529 string = toString2(string);
11530 if (string && (guard || chars === undefined2)) {
11531 return string.replace(reTrimStart2, "");
11533 if (!string || !(chars = baseToString2(chars))) {
11536 var strSymbols = stringToArray(string), start2 = charsStartIndex(strSymbols, stringToArray(chars));
11537 return castSlice(strSymbols, start2).join("");
11539 function truncate(string, options2) {
11540 var length = DEFAULT_TRUNC_LENGTH, omission = DEFAULT_TRUNC_OMISSION;
11541 if (isObject3(options2)) {
11542 var separator = "separator" in options2 ? options2.separator : separator;
11543 length = "length" in options2 ? toInteger(options2.length) : length;
11544 omission = "omission" in options2 ? baseToString2(options2.omission) : omission;
11546 string = toString2(string);
11547 var strLength = string.length;
11548 if (hasUnicode(string)) {
11549 var strSymbols = stringToArray(string);
11550 strLength = strSymbols.length;
11552 if (length >= strLength) {
11555 var end = length - stringSize(omission);
11559 var result2 = strSymbols ? castSlice(strSymbols, 0, end).join("") : string.slice(0, end);
11560 if (separator === undefined2) {
11561 return result2 + omission;
11564 end += result2.length - end;
11566 if (isRegExp(separator)) {
11567 if (string.slice(end).search(separator)) {
11568 var match, substring = result2;
11569 if (!separator.global) {
11570 separator = RegExp2(separator.source, toString2(reFlags.exec(separator)) + "g");
11572 separator.lastIndex = 0;
11573 while (match = separator.exec(substring)) {
11574 var newEnd = match.index;
11576 result2 = result2.slice(0, newEnd === undefined2 ? end : newEnd);
11578 } else if (string.indexOf(baseToString2(separator), end) != end) {
11579 var index = result2.lastIndexOf(separator);
11581 result2 = result2.slice(0, index);
11584 return result2 + omission;
11586 function unescape4(string) {
11587 string = toString2(string);
11588 return string && reHasEscapedHtml2.test(string) ? string.replace(reEscapedHtml2, unescapeHtmlChar2) : string;
11590 var upperCase = createCompounder(function(result2, word, index) {
11591 return result2 + (index ? " " : "") + word.toUpperCase();
11593 var upperFirst = createCaseFirst("toUpperCase");
11594 function words(string, pattern, guard) {
11595 string = toString2(string);
11596 pattern = guard ? undefined2 : pattern;
11597 if (pattern === undefined2) {
11598 return hasUnicodeWord(string) ? unicodeWords(string) : asciiWords(string);
11600 return string.match(pattern) || [];
11602 var attempt = baseRest(function(func, args) {
11604 return apply(func, undefined2, args);
11606 return isError(e) ? e : new Error2(e);
11609 var bindAll = flatRest(function(object, methodNames) {
11610 arrayEach(methodNames, function(key) {
11612 baseAssignValue(object, key, bind(object[key], object));
11616 function cond(pairs) {
11617 var length = pairs == null ? 0 : pairs.length, toIteratee = getIteratee();
11618 pairs = !length ? [] : arrayMap2(pairs, function(pair2) {
11619 if (typeof pair2[1] != "function") {
11620 throw new TypeError2(FUNC_ERROR_TEXT3);
11622 return [toIteratee(pair2[0]), pair2[1]];
11624 return baseRest(function(args) {
11626 while (++index < length) {
11627 var pair2 = pairs[index];
11628 if (apply(pair2[0], this, args)) {
11629 return apply(pair2[1], this, args);
11634 function conforms(source) {
11635 return baseConforms(baseClone(source, CLONE_DEEP_FLAG));
11637 function constant(value) {
11638 return function() {
11642 function defaultTo(value, defaultValue) {
11643 return value == null || value !== value ? defaultValue : value;
11645 var flow = createFlow();
11646 var flowRight = createFlow(true);
11647 function identity4(value) {
11650 function iteratee(func) {
11651 return baseIteratee(typeof func == "function" ? func : baseClone(func, CLONE_DEEP_FLAG));
11653 function matches(source) {
11654 return baseMatches(baseClone(source, CLONE_DEEP_FLAG));
11656 function matchesProperty(path, srcValue) {
11657 return baseMatchesProperty(path, baseClone(srcValue, CLONE_DEEP_FLAG));
11659 var method = baseRest(function(path, args) {
11660 return function(object) {
11661 return baseInvoke(object, path, args);
11664 var methodOf = baseRest(function(object, args) {
11665 return function(path) {
11666 return baseInvoke(object, path, args);
11669 function mixin(object, source, options2) {
11670 var props = keys(source), methodNames = baseFunctions(source, props);
11671 if (options2 == null && !(isObject3(source) && (methodNames.length || !props.length))) {
11675 methodNames = baseFunctions(source, keys(source));
11677 var chain2 = !(isObject3(options2) && "chain" in options2) || !!options2.chain, isFunc = isFunction(object);
11678 arrayEach(methodNames, function(methodName) {
11679 var func = source[methodName];
11680 object[methodName] = func;
11682 object.prototype[methodName] = function() {
11683 var chainAll = this.__chain__;
11684 if (chain2 || chainAll) {
11685 var result2 = object(this.__wrapped__), actions = result2.__actions__ = copyArray(this.__actions__);
11686 actions.push({ "func": func, "args": arguments, "thisArg": object });
11687 result2.__chain__ = chainAll;
11690 return func.apply(object, arrayPush([this.value()], arguments));
11696 function noConflict() {
11697 if (root3._ === this) {
11704 function nthArg(n2) {
11705 n2 = toInteger(n2);
11706 return baseRest(function(args) {
11707 return baseNth(args, n2);
11710 var over = createOver(arrayMap2);
11711 var overEvery = createOver(arrayEvery);
11712 var overSome = createOver(arraySome);
11713 function property(path) {
11714 return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);
11716 function propertyOf(object) {
11717 return function(path) {
11718 return object == null ? undefined2 : baseGet(object, path);
11721 var range3 = createRange();
11722 var rangeRight = createRange(true);
11723 function stubArray() {
11726 function stubFalse() {
11729 function stubObject() {
11732 function stubString() {
11735 function stubTrue() {
11738 function times(n2, iteratee2) {
11739 n2 = toInteger(n2);
11740 if (n2 < 1 || n2 > MAX_SAFE_INTEGER) {
11743 var index = MAX_ARRAY_LENGTH, length = nativeMin2(n2, MAX_ARRAY_LENGTH);
11744 iteratee2 = getIteratee(iteratee2);
11745 n2 -= MAX_ARRAY_LENGTH;
11746 var result2 = baseTimes(length, iteratee2);
11747 while (++index < n2) {
11752 function toPath(value) {
11753 if (isArray2(value)) {
11754 return arrayMap2(value, toKey);
11756 return isSymbol2(value) ? [value] : copyArray(stringToPath(toString2(value)));
11758 function uniqueId(prefix) {
11759 var id2 = ++idCounter;
11760 return toString2(prefix) + id2;
11762 var add = createMathOperation(function(augend, addend) {
11763 return augend + addend;
11765 var ceil = createRound("ceil");
11766 var divide = createMathOperation(function(dividend, divisor) {
11767 return dividend / divisor;
11769 var floor = createRound("floor");
11770 function max3(array2) {
11771 return array2 && array2.length ? baseExtremum(array2, identity4, baseGt) : undefined2;
11773 function maxBy(array2, iteratee2) {
11774 return array2 && array2.length ? baseExtremum(array2, getIteratee(iteratee2, 2), baseGt) : undefined2;
11776 function mean(array2) {
11777 return baseMean(array2, identity4);
11779 function meanBy(array2, iteratee2) {
11780 return baseMean(array2, getIteratee(iteratee2, 2));
11782 function min3(array2) {
11783 return array2 && array2.length ? baseExtremum(array2, identity4, baseLt) : undefined2;
11785 function minBy(array2, iteratee2) {
11786 return array2 && array2.length ? baseExtremum(array2, getIteratee(iteratee2, 2), baseLt) : undefined2;
11788 var multiply = createMathOperation(function(multiplier, multiplicand) {
11789 return multiplier * multiplicand;
11791 var round = createRound("round");
11792 var subtract = createMathOperation(function(minuend, subtrahend) {
11793 return minuend - subtrahend;
11795 function sum(array2) {
11796 return array2 && array2.length ? baseSum(array2, identity4) : 0;
11798 function sumBy(array2, iteratee2) {
11799 return array2 && array2.length ? baseSum(array2, getIteratee(iteratee2, 2)) : 0;
11801 lodash.after = after;
11803 lodash.assign = assign;
11804 lodash.assignIn = assignIn;
11805 lodash.assignInWith = assignInWith;
11806 lodash.assignWith = assignWith;
11808 lodash.before = before;
11809 lodash.bind = bind;
11810 lodash.bindAll = bindAll;
11811 lodash.bindKey = bindKey2;
11812 lodash.castArray = castArray;
11813 lodash.chain = chain;
11814 lodash.chunk = chunk;
11815 lodash.compact = compact;
11816 lodash.concat = concat;
11817 lodash.cond = cond;
11818 lodash.conforms = conforms;
11819 lodash.constant = constant;
11820 lodash.countBy = countBy;
11821 lodash.create = create2;
11822 lodash.curry = curry;
11823 lodash.curryRight = curryRight;
11824 lodash.debounce = debounce2;
11825 lodash.defaults = defaults2;
11826 lodash.defaultsDeep = defaultsDeep;
11827 lodash.defer = defer;
11828 lodash.delay = delay;
11829 lodash.difference = difference;
11830 lodash.differenceBy = differenceBy;
11831 lodash.differenceWith = differenceWith;
11832 lodash.drop = drop;
11833 lodash.dropRight = dropRight;
11834 lodash.dropRightWhile = dropRightWhile;
11835 lodash.dropWhile = dropWhile;
11836 lodash.fill = fill;
11837 lodash.filter = filter2;
11838 lodash.flatMap = flatMap;
11839 lodash.flatMapDeep = flatMapDeep;
11840 lodash.flatMapDepth = flatMapDepth;
11841 lodash.flatten = flatten2;
11842 lodash.flattenDeep = flattenDeep;
11843 lodash.flattenDepth = flattenDepth;
11844 lodash.flip = flip;
11845 lodash.flow = flow;
11846 lodash.flowRight = flowRight;
11847 lodash.fromPairs = fromPairs;
11848 lodash.functions = functions;
11849 lodash.functionsIn = functionsIn;
11850 lodash.groupBy = groupBy;
11851 lodash.initial = initial;
11852 lodash.intersection = intersection;
11853 lodash.intersectionBy = intersectionBy;
11854 lodash.intersectionWith = intersectionWith;
11855 lodash.invert = invert;
11856 lodash.invertBy = invertBy;
11857 lodash.invokeMap = invokeMap;
11858 lodash.iteratee = iteratee;
11859 lodash.keyBy = keyBy;
11860 lodash.keys = keys;
11861 lodash.keysIn = keysIn;
11863 lodash.mapKeys = mapKeys;
11864 lodash.mapValues = mapValues;
11865 lodash.matches = matches;
11866 lodash.matchesProperty = matchesProperty;
11867 lodash.memoize = memoize;
11868 lodash.merge = merge3;
11869 lodash.mergeWith = mergeWith;
11870 lodash.method = method;
11871 lodash.methodOf = methodOf;
11872 lodash.mixin = mixin;
11873 lodash.negate = negate;
11874 lodash.nthArg = nthArg;
11875 lodash.omit = omit;
11876 lodash.omitBy = omitBy;
11877 lodash.once = once;
11878 lodash.orderBy = orderBy;
11879 lodash.over = over;
11880 lodash.overArgs = overArgs;
11881 lodash.overEvery = overEvery;
11882 lodash.overSome = overSome;
11883 lodash.partial = partial;
11884 lodash.partialRight = partialRight;
11885 lodash.partition = partition;
11886 lodash.pick = pick;
11887 lodash.pickBy = pickBy;
11888 lodash.property = property;
11889 lodash.propertyOf = propertyOf;
11890 lodash.pull = pull;
11891 lodash.pullAll = pullAll;
11892 lodash.pullAllBy = pullAllBy;
11893 lodash.pullAllWith = pullAllWith;
11894 lodash.pullAt = pullAt;
11895 lodash.range = range3;
11896 lodash.rangeRight = rangeRight;
11897 lodash.rearg = rearg;
11898 lodash.reject = reject;
11899 lodash.remove = remove2;
11900 lodash.rest = rest;
11901 lodash.reverse = reverse;
11902 lodash.sampleSize = sampleSize;
11904 lodash.setWith = setWith;
11905 lodash.shuffle = shuffle;
11906 lodash.slice = slice;
11907 lodash.sortBy = sortBy;
11908 lodash.sortedUniq = sortedUniq;
11909 lodash.sortedUniqBy = sortedUniqBy;
11910 lodash.split = split;
11911 lodash.spread = spread;
11912 lodash.tail = tail;
11913 lodash.take = take;
11914 lodash.takeRight = takeRight;
11915 lodash.takeRightWhile = takeRightWhile;
11916 lodash.takeWhile = takeWhile;
11918 lodash.throttle = throttle2;
11919 lodash.thru = thru;
11920 lodash.toArray = toArray;
11921 lodash.toPairs = toPairs;
11922 lodash.toPairsIn = toPairsIn;
11923 lodash.toPath = toPath;
11924 lodash.toPlainObject = toPlainObject;
11925 lodash.transform = transform2;
11926 lodash.unary = unary;
11927 lodash.union = union;
11928 lodash.unionBy = unionBy;
11929 lodash.unionWith = unionWith;
11930 lodash.uniq = uniq;
11931 lodash.uniqBy = uniqBy;
11932 lodash.uniqWith = uniqWith;
11933 lodash.unset = unset;
11934 lodash.unzip = unzip;
11935 lodash.unzipWith = unzipWith;
11936 lodash.update = update;
11937 lodash.updateWith = updateWith;
11938 lodash.values = values;
11939 lodash.valuesIn = valuesIn;
11940 lodash.without = without;
11941 lodash.words = words;
11942 lodash.wrap = wrap2;
11944 lodash.xorBy = xorBy;
11945 lodash.xorWith = xorWith;
11947 lodash.zipObject = zipObject;
11948 lodash.zipObjectDeep = zipObjectDeep;
11949 lodash.zipWith = zipWith;
11950 lodash.entries = toPairs;
11951 lodash.entriesIn = toPairsIn;
11952 lodash.extend = assignIn;
11953 lodash.extendWith = assignInWith;
11954 mixin(lodash, lodash);
11956 lodash.attempt = attempt;
11957 lodash.camelCase = camelCase;
11958 lodash.capitalize = capitalize;
11959 lodash.ceil = ceil;
11960 lodash.clamp = clamp3;
11961 lodash.clone = clone;
11962 lodash.cloneDeep = cloneDeep;
11963 lodash.cloneDeepWith = cloneDeepWith;
11964 lodash.cloneWith = cloneWith;
11965 lodash.conformsTo = conformsTo;
11966 lodash.deburr = deburr;
11967 lodash.defaultTo = defaultTo;
11968 lodash.divide = divide;
11969 lodash.endsWith = endsWith;
11971 lodash.escape = escape6;
11972 lodash.escapeRegExp = escapeRegExp;
11973 lodash.every = every;
11974 lodash.find = find2;
11975 lodash.findIndex = findIndex;
11976 lodash.findKey = findKey;
11977 lodash.findLast = findLast;
11978 lodash.findLastIndex = findLastIndex;
11979 lodash.findLastKey = findLastKey;
11980 lodash.floor = floor;
11981 lodash.forEach = forEach;
11982 lodash.forEachRight = forEachRight;
11983 lodash.forIn = forIn;
11984 lodash.forInRight = forInRight;
11985 lodash.forOwn = forOwn;
11986 lodash.forOwnRight = forOwnRight;
11991 lodash.hasIn = hasIn;
11992 lodash.head = head;
11993 lodash.identity = identity4;
11994 lodash.includes = includes;
11995 lodash.indexOf = indexOf;
11996 lodash.inRange = inRange;
11997 lodash.invoke = invoke;
11998 lodash.isArguments = isArguments;
11999 lodash.isArray = isArray2;
12000 lodash.isArrayBuffer = isArrayBuffer;
12001 lodash.isArrayLike = isArrayLike;
12002 lodash.isArrayLikeObject = isArrayLikeObject;
12003 lodash.isBoolean = isBoolean;
12004 lodash.isBuffer = isBuffer;
12005 lodash.isDate = isDate;
12006 lodash.isElement = isElement2;
12007 lodash.isEmpty = isEmpty;
12008 lodash.isEqual = isEqual;
12009 lodash.isEqualWith = isEqualWith;
12010 lodash.isError = isError;
12011 lodash.isFinite = isFinite2;
12012 lodash.isFunction = isFunction;
12013 lodash.isInteger = isInteger;
12014 lodash.isLength = isLength;
12015 lodash.isMap = isMap;
12016 lodash.isMatch = isMatch;
12017 lodash.isMatchWith = isMatchWith;
12018 lodash.isNaN = isNaN2;
12019 lodash.isNative = isNative;
12020 lodash.isNil = isNil;
12021 lodash.isNull = isNull;
12022 lodash.isNumber = isNumber2;
12023 lodash.isObject = isObject3;
12024 lodash.isObjectLike = isObjectLike2;
12025 lodash.isPlainObject = isPlainObject;
12026 lodash.isRegExp = isRegExp;
12027 lodash.isSafeInteger = isSafeInteger;
12028 lodash.isSet = isSet;
12029 lodash.isString = isString;
12030 lodash.isSymbol = isSymbol2;
12031 lodash.isTypedArray = isTypedArray;
12032 lodash.isUndefined = isUndefined;
12033 lodash.isWeakMap = isWeakMap;
12034 lodash.isWeakSet = isWeakSet;
12035 lodash.join = join;
12036 lodash.kebabCase = kebabCase;
12037 lodash.last = last;
12038 lodash.lastIndexOf = lastIndexOf;
12039 lodash.lowerCase = lowerCase;
12040 lodash.lowerFirst = lowerFirst;
12044 lodash.maxBy = maxBy;
12045 lodash.mean = mean;
12046 lodash.meanBy = meanBy;
12048 lodash.minBy = minBy;
12049 lodash.stubArray = stubArray;
12050 lodash.stubFalse = stubFalse;
12051 lodash.stubObject = stubObject;
12052 lodash.stubString = stubString;
12053 lodash.stubTrue = stubTrue;
12054 lodash.multiply = multiply;
12056 lodash.noConflict = noConflict;
12057 lodash.noop = noop3;
12060 lodash.padEnd = padEnd;
12061 lodash.padStart = padStart;
12062 lodash.parseInt = parseInt2;
12063 lodash.random = random;
12064 lodash.reduce = reduce;
12065 lodash.reduceRight = reduceRight;
12066 lodash.repeat = repeat;
12067 lodash.replace = replace;
12068 lodash.result = result;
12069 lodash.round = round;
12070 lodash.runInContext = runInContext2;
12071 lodash.sample = sample;
12072 lodash.size = size;
12073 lodash.snakeCase = snakeCase;
12074 lodash.some = some;
12075 lodash.sortedIndex = sortedIndex;
12076 lodash.sortedIndexBy = sortedIndexBy;
12077 lodash.sortedIndexOf = sortedIndexOf;
12078 lodash.sortedLastIndex = sortedLastIndex;
12079 lodash.sortedLastIndexBy = sortedLastIndexBy;
12080 lodash.sortedLastIndexOf = sortedLastIndexOf;
12081 lodash.startCase = startCase;
12082 lodash.startsWith = startsWith;
12083 lodash.subtract = subtract;
12085 lodash.sumBy = sumBy;
12086 lodash.template = template;
12087 lodash.times = times;
12088 lodash.toFinite = toFinite;
12089 lodash.toInteger = toInteger;
12090 lodash.toLength = toLength;
12091 lodash.toLower = toLower;
12092 lodash.toNumber = toNumber2;
12093 lodash.toSafeInteger = toSafeInteger;
12094 lodash.toString = toString2;
12095 lodash.toUpper = toUpper;
12096 lodash.trim = trim;
12097 lodash.trimEnd = trimEnd;
12098 lodash.trimStart = trimStart;
12099 lodash.truncate = truncate;
12100 lodash.unescape = unescape4;
12101 lodash.uniqueId = uniqueId;
12102 lodash.upperCase = upperCase;
12103 lodash.upperFirst = upperFirst;
12104 lodash.each = forEach;
12105 lodash.eachRight = forEachRight;
12106 lodash.first = head;
12107 mixin(lodash, function() {
12109 baseForOwn(lodash, function(func, methodName) {
12110 if (!hasOwnProperty2.call(lodash.prototype, methodName)) {
12111 source[methodName] = func;
12115 }(), { "chain": false });
12116 lodash.VERSION = VERSION;
12117 arrayEach(["bind", "bindKey", "curry", "curryRight", "partial", "partialRight"], function(methodName) {
12118 lodash[methodName].placeholder = lodash;
12120 arrayEach(["drop", "take"], function(methodName, index) {
12121 LazyWrapper.prototype[methodName] = function(n2) {
12122 n2 = n2 === undefined2 ? 1 : nativeMax2(toInteger(n2), 0);
12123 var result2 = this.__filtered__ && !index ? new LazyWrapper(this) : this.clone();
12124 if (result2.__filtered__) {
12125 result2.__takeCount__ = nativeMin2(n2, result2.__takeCount__);
12127 result2.__views__.push({
12128 "size": nativeMin2(n2, MAX_ARRAY_LENGTH),
12129 "type": methodName + (result2.__dir__ < 0 ? "Right" : "")
12134 LazyWrapper.prototype[methodName + "Right"] = function(n2) {
12135 return this.reverse()[methodName](n2).reverse();
12138 arrayEach(["filter", "map", "takeWhile"], function(methodName, index) {
12139 var type2 = index + 1, isFilter = type2 == LAZY_FILTER_FLAG || type2 == LAZY_WHILE_FLAG;
12140 LazyWrapper.prototype[methodName] = function(iteratee2) {
12141 var result2 = this.clone();
12142 result2.__iteratees__.push({
12143 "iteratee": getIteratee(iteratee2, 3),
12146 result2.__filtered__ = result2.__filtered__ || isFilter;
12150 arrayEach(["head", "last"], function(methodName, index) {
12151 var takeName = "take" + (index ? "Right" : "");
12152 LazyWrapper.prototype[methodName] = function() {
12153 return this[takeName](1).value()[0];
12156 arrayEach(["initial", "tail"], function(methodName, index) {
12157 var dropName = "drop" + (index ? "" : "Right");
12158 LazyWrapper.prototype[methodName] = function() {
12159 return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1);
12162 LazyWrapper.prototype.compact = function() {
12163 return this.filter(identity4);
12165 LazyWrapper.prototype.find = function(predicate) {
12166 return this.filter(predicate).head();
12168 LazyWrapper.prototype.findLast = function(predicate) {
12169 return this.reverse().find(predicate);
12171 LazyWrapper.prototype.invokeMap = baseRest(function(path, args) {
12172 if (typeof path == "function") {
12173 return new LazyWrapper(this);
12175 return this.map(function(value) {
12176 return baseInvoke(value, path, args);
12179 LazyWrapper.prototype.reject = function(predicate) {
12180 return this.filter(negate(getIteratee(predicate)));
12182 LazyWrapper.prototype.slice = function(start2, end) {
12183 start2 = toInteger(start2);
12184 var result2 = this;
12185 if (result2.__filtered__ && (start2 > 0 || end < 0)) {
12186 return new LazyWrapper(result2);
12189 result2 = result2.takeRight(-start2);
12190 } else if (start2) {
12191 result2 = result2.drop(start2);
12193 if (end !== undefined2) {
12194 end = toInteger(end);
12195 result2 = end < 0 ? result2.dropRight(-end) : result2.take(end - start2);
12199 LazyWrapper.prototype.takeRightWhile = function(predicate) {
12200 return this.reverse().takeWhile(predicate).reverse();
12202 LazyWrapper.prototype.toArray = function() {
12203 return this.take(MAX_ARRAY_LENGTH);
12205 baseForOwn(LazyWrapper.prototype, function(func, methodName) {
12206 var checkIteratee = /^(?:filter|find|map|reject)|While$/.test(methodName), isTaker = /^(?:head|last)$/.test(methodName), lodashFunc = lodash[isTaker ? "take" + (methodName == "last" ? "Right" : "") : methodName], retUnwrapped = isTaker || /^find/.test(methodName);
12210 lodash.prototype[methodName] = function() {
12211 var value = this.__wrapped__, args = isTaker ? [1] : arguments, isLazy = value instanceof LazyWrapper, iteratee2 = args[0], useLazy = isLazy || isArray2(value);
12212 var interceptor = function(value2) {
12213 var result3 = lodashFunc.apply(lodash, arrayPush([value2], args));
12214 return isTaker && chainAll ? result3[0] : result3;
12216 if (useLazy && checkIteratee && typeof iteratee2 == "function" && iteratee2.length != 1) {
12217 isLazy = useLazy = false;
12219 var chainAll = this.__chain__, isHybrid = !!this.__actions__.length, isUnwrapped = retUnwrapped && !chainAll, onlyLazy = isLazy && !isHybrid;
12220 if (!retUnwrapped && useLazy) {
12221 value = onlyLazy ? value : new LazyWrapper(this);
12222 var result2 = func.apply(value, args);
12223 result2.__actions__.push({ "func": thru, "args": [interceptor], "thisArg": undefined2 });
12224 return new LodashWrapper(result2, chainAll);
12226 if (isUnwrapped && onlyLazy) {
12227 return func.apply(this, args);
12229 result2 = this.thru(interceptor);
12230 return isUnwrapped ? isTaker ? result2.value()[0] : result2.value() : result2;
12233 arrayEach(["pop", "push", "shift", "sort", "splice", "unshift"], function(methodName) {
12234 var func = arrayProto[methodName], chainName = /^(?:push|sort|unshift)$/.test(methodName) ? "tap" : "thru", retUnwrapped = /^(?:pop|shift)$/.test(methodName);
12235 lodash.prototype[methodName] = function() {
12236 var args = arguments;
12237 if (retUnwrapped && !this.__chain__) {
12238 var value = this.value();
12239 return func.apply(isArray2(value) ? value : [], args);
12241 return this[chainName](function(value2) {
12242 return func.apply(isArray2(value2) ? value2 : [], args);
12246 baseForOwn(LazyWrapper.prototype, function(func, methodName) {
12247 var lodashFunc = lodash[methodName];
12249 var key = lodashFunc.name + "";
12250 if (!hasOwnProperty2.call(realNames, key)) {
12251 realNames[key] = [];
12253 realNames[key].push({ "name": methodName, "func": lodashFunc });
12256 realNames[createHybrid(undefined2, WRAP_BIND_KEY_FLAG).name] = [{
12260 LazyWrapper.prototype.clone = lazyClone;
12261 LazyWrapper.prototype.reverse = lazyReverse;
12262 LazyWrapper.prototype.value = lazyValue;
12263 lodash.prototype.at = wrapperAt;
12264 lodash.prototype.chain = wrapperChain;
12265 lodash.prototype.commit = wrapperCommit;
12266 lodash.prototype.next = wrapperNext;
12267 lodash.prototype.plant = wrapperPlant;
12268 lodash.prototype.reverse = wrapperReverse;
12269 lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue;
12270 lodash.prototype.first = lodash.prototype.head;
12272 lodash.prototype[symIterator] = wrapperToIterator;
12276 var _ = runInContext();
12277 if (typeof define == "function" && typeof define.amd == "object" && define.amd) {
12279 define(function() {
12282 } else if (freeModule) {
12283 (freeModule.exports = _)._ = _;
12292 // node_modules/rbush/rbush.min.js
12293 var require_rbush_min = __commonJS({
12294 "node_modules/rbush/rbush.min.js"(exports2, module2) {
12296 "object" == typeof exports2 && "undefined" != typeof module2 ? module2.exports = i2() : "function" == typeof define && define.amd ? define(i2) : (t = t || self).RBush = i2();
12297 }(exports2, function() {
12299 function t(t2, r2, e3, a2, h2) {
12300 !function t3(n3, r3, e4, a3, h3) {
12301 for (; a3 > e4; ) {
12302 if (a3 - e4 > 600) {
12303 var o2 = a3 - e4 + 1, s2 = r3 - e4 + 1, l2 = Math.log(o2), f3 = 0.5 * Math.exp(2 * l2 / 3), u2 = 0.5 * Math.sqrt(l2 * f3 * (o2 - f3) / o2) * (s2 - o2 / 2 < 0 ? -1 : 1), m2 = Math.max(e4, Math.floor(r3 - s2 * f3 / o2 + u2)), c2 = Math.min(a3, Math.floor(r3 + (o2 - s2) * f3 / o2 + u2));
12304 t3(n3, r3, m2, c2, h3);
12306 var p2 = n3[r3], d2 = e4, x = a3;
12307 for (i2(n3, e4, r3), h3(n3[a3], p2) > 0 && i2(n3, e4, a3); d2 < x; ) {
12308 for (i2(n3, d2, x), d2++, x--; h3(n3[d2], p2) < 0; )
12310 for (; h3(n3[x], p2) > 0; )
12313 0 === h3(n3[e4], p2) ? i2(n3, e4, x) : i2(n3, ++x, a3), x <= r3 && (e4 = x + 1), r3 <= x && (a3 = x - 1);
12315 }(t2, r2, e3 || 0, a2 || t2.length - 1, h2 || n2);
12317 function i2(t2, i3, n3) {
12319 t2[i3] = t2[n3], t2[n3] = r2;
12321 function n2(t2, i3) {
12322 return t2 < i3 ? -1 : t2 > i3 ? 1 : 0;
12324 var r = function(t2) {
12325 void 0 === t2 && (t2 = 9), this._maxEntries = Math.max(4, t2), this._minEntries = Math.max(2, Math.ceil(0.4 * this._maxEntries)), this.clear();
12327 function e(t2, i3, n3) {
12329 return i3.indexOf(t2);
12330 for (var r2 = 0; r2 < i3.length; r2++)
12331 if (n3(t2, i3[r2]))
12335 function a(t2, i3) {
12336 h(t2, 0, t2.children.length, i3, t2);
12338 function h(t2, i3, n3, r2, e3) {
12339 e3 || (e3 = p(null)), e3.minX = 1 / 0, e3.minY = 1 / 0, e3.maxX = -1 / 0, e3.maxY = -1 / 0;
12340 for (var a2 = i3; a2 < n3; a2++) {
12341 var h2 = t2.children[a2];
12342 o(e3, t2.leaf ? r2(h2) : h2);
12346 function o(t2, i3) {
12347 return t2.minX = Math.min(t2.minX, i3.minX), t2.minY = Math.min(t2.minY, i3.minY), t2.maxX = Math.max(t2.maxX, i3.maxX), t2.maxY = Math.max(t2.maxY, i3.maxY), t2;
12349 function s(t2, i3) {
12350 return t2.minX - i3.minX;
12352 function l(t2, i3) {
12353 return t2.minY - i3.minY;
12356 return (t2.maxX - t2.minX) * (t2.maxY - t2.minY);
12359 return t2.maxX - t2.minX + (t2.maxY - t2.minY);
12361 function m(t2, i3) {
12362 return t2.minX <= i3.minX && t2.minY <= i3.minY && i3.maxX <= t2.maxX && i3.maxY <= t2.maxY;
12364 function c(t2, i3) {
12365 return i3.minX <= t2.maxX && i3.minY <= t2.maxY && i3.maxX >= t2.minX && i3.maxY >= t2.minY;
12368 return { children: t2, height: 1, leaf: true, minX: 1 / 0, minY: 1 / 0, maxX: -1 / 0, maxY: -1 / 0 };
12370 function d(i3, n3, r2, e3, a2) {
12371 for (var h2 = [n3, r2]; h2.length; )
12372 if (!((r2 = h2.pop()) - (n3 = h2.pop()) <= e3)) {
12373 var o2 = n3 + Math.ceil((r2 - n3) / e3 / 2) * e3;
12374 t(i3, o2, n3, r2, a2), h2.push(n3, o2, o2, r2);
12377 return r.prototype.all = function() {
12378 return this._all(this.data, []);
12379 }, r.prototype.search = function(t2) {
12380 var i3 = this.data, n3 = [];
12383 for (var r2 = this.toBBox, e3 = []; i3; ) {
12384 for (var a2 = 0; a2 < i3.children.length; a2++) {
12385 var h2 = i3.children[a2], o2 = i3.leaf ? r2(h2) : h2;
12386 c(t2, o2) && (i3.leaf ? n3.push(h2) : m(t2, o2) ? this._all(h2, n3) : e3.push(h2));
12391 }, r.prototype.collides = function(t2) {
12392 var i3 = this.data;
12395 for (var n3 = []; i3; ) {
12396 for (var r2 = 0; r2 < i3.children.length; r2++) {
12397 var e3 = i3.children[r2], a2 = i3.leaf ? this.toBBox(e3) : e3;
12399 if (i3.leaf || m(t2, a2))
12407 }, r.prototype.load = function(t2) {
12408 if (!t2 || !t2.length)
12410 if (t2.length < this._minEntries) {
12411 for (var i3 = 0; i3 < t2.length; i3++)
12412 this.insert(t2[i3]);
12415 var n3 = this._build(t2.slice(), 0, t2.length - 1, 0);
12416 if (this.data.children.length)
12417 if (this.data.height === n3.height)
12418 this._splitRoot(this.data, n3);
12420 if (this.data.height < n3.height) {
12421 var r2 = this.data;
12422 this.data = n3, n3 = r2;
12424 this._insert(n3, this.data.height - n3.height - 1, true);
12429 }, r.prototype.insert = function(t2) {
12430 return t2 && this._insert(t2, this.data.height - 1), this;
12431 }, r.prototype.clear = function() {
12432 return this.data = p([]), this;
12433 }, r.prototype.remove = function(t2, i3) {
12436 for (var n3, r2, a2, h2 = this.data, o2 = this.toBBox(t2), s2 = [], l2 = []; h2 || s2.length; ) {
12437 if (h2 || (h2 = s2.pop(), r2 = s2[s2.length - 1], n3 = l2.pop(), a2 = true), h2.leaf) {
12438 var f3 = e(t2, h2.children, i3);
12440 return h2.children.splice(f3, 1), s2.push(h2), this._condense(s2), this;
12442 a2 || h2.leaf || !m(h2, o2) ? r2 ? (n3++, h2 = r2.children[n3], a2 = false) : h2 = null : (s2.push(h2), l2.push(n3), n3 = 0, r2 = h2, h2 = h2.children[0]);
12445 }, r.prototype.toBBox = function(t2) {
12447 }, r.prototype.compareMinX = function(t2, i3) {
12448 return t2.minX - i3.minX;
12449 }, r.prototype.compareMinY = function(t2, i3) {
12450 return t2.minY - i3.minY;
12451 }, r.prototype.toJSON = function() {
12453 }, r.prototype.fromJSON = function(t2) {
12454 return this.data = t2, this;
12455 }, r.prototype._all = function(t2, i3) {
12456 for (var n3 = []; t2; )
12457 t2.leaf ? i3.push.apply(i3, t2.children) : n3.push.apply(n3, t2.children), t2 = n3.pop();
12459 }, r.prototype._build = function(t2, i3, n3, r2) {
12460 var e3, h2 = n3 - i3 + 1, o2 = this._maxEntries;
12462 return a(e3 = p(t2.slice(i3, n3 + 1)), this.toBBox), e3;
12463 r2 || (r2 = Math.ceil(Math.log(h2) / Math.log(o2)), o2 = Math.ceil(h2 / Math.pow(o2, r2 - 1))), (e3 = p([])).leaf = false, e3.height = r2;
12464 var s2 = Math.ceil(h2 / o2), l2 = s2 * Math.ceil(Math.sqrt(o2));
12465 d(t2, i3, n3, l2, this.compareMinX);
12466 for (var f3 = i3; f3 <= n3; f3 += l2) {
12467 var u2 = Math.min(f3 + l2 - 1, n3);
12468 d(t2, f3, u2, s2, this.compareMinY);
12469 for (var m2 = f3; m2 <= u2; m2 += s2) {
12470 var c2 = Math.min(m2 + s2 - 1, u2);
12471 e3.children.push(this._build(t2, m2, c2, r2 - 1));
12474 return a(e3, this.toBBox), e3;
12475 }, r.prototype._chooseSubtree = function(t2, i3, n3, r2) {
12476 for (; r2.push(i3), !i3.leaf && r2.length - 1 !== n3; ) {
12477 for (var e3 = 1 / 0, a2 = 1 / 0, h2 = void 0, o2 = 0; o2 < i3.children.length; o2++) {
12478 var s2 = i3.children[o2], l2 = f2(s2), u2 = (m2 = t2, c2 = s2, (Math.max(c2.maxX, m2.maxX) - Math.min(c2.minX, m2.minX)) * (Math.max(c2.maxY, m2.maxY) - Math.min(c2.minY, m2.minY)) - l2);
12479 u2 < a2 ? (a2 = u2, e3 = l2 < e3 ? l2 : e3, h2 = s2) : u2 === a2 && l2 < e3 && (e3 = l2, h2 = s2);
12481 i3 = h2 || i3.children[0];
12485 }, r.prototype._insert = function(t2, i3, n3) {
12486 var r2 = n3 ? t2 : this.toBBox(t2), e3 = [], a2 = this._chooseSubtree(r2, this.data, i3, e3);
12487 for (a2.children.push(t2), o(a2, r2); i3 >= 0 && e3[i3].children.length > this._maxEntries; )
12488 this._split(e3, i3), i3--;
12489 this._adjustParentBBoxes(r2, e3, i3);
12490 }, r.prototype._split = function(t2, i3) {
12491 var n3 = t2[i3], r2 = n3.children.length, e3 = this._minEntries;
12492 this._chooseSplitAxis(n3, e3, r2);
12493 var h2 = this._chooseSplitIndex(n3, e3, r2), o2 = p(n3.children.splice(h2, n3.children.length - h2));
12494 o2.height = n3.height, o2.leaf = n3.leaf, a(n3, this.toBBox), a(o2, this.toBBox), i3 ? t2[i3 - 1].children.push(o2) : this._splitRoot(n3, o2);
12495 }, r.prototype._splitRoot = function(t2, i3) {
12496 this.data = p([t2, i3]), this.data.height = t2.height + 1, this.data.leaf = false, a(this.data, this.toBBox);
12497 }, r.prototype._chooseSplitIndex = function(t2, i3, n3) {
12498 for (var r2, e3, a2, o2, s2, l2, u2, m2 = 1 / 0, c2 = 1 / 0, p2 = i3; p2 <= n3 - i3; p2++) {
12499 var d2 = h(t2, 0, p2, this.toBBox), x = h(t2, p2, n3, this.toBBox), v = (e3 = d2, a2 = x, o2 = void 0, s2 = void 0, l2 = void 0, u2 = void 0, o2 = Math.max(e3.minX, a2.minX), s2 = Math.max(e3.minY, a2.minY), l2 = Math.min(e3.maxX, a2.maxX), u2 = Math.min(e3.maxY, a2.maxY), Math.max(0, l2 - o2) * Math.max(0, u2 - s2)), M = f2(d2) + f2(x);
12500 v < m2 ? (m2 = v, r2 = p2, c2 = M < c2 ? M : c2) : v === m2 && M < c2 && (c2 = M, r2 = p2);
12502 return r2 || n3 - i3;
12503 }, r.prototype._chooseSplitAxis = function(t2, i3, n3) {
12504 var r2 = t2.leaf ? this.compareMinX : s, e3 = t2.leaf ? this.compareMinY : l;
12505 this._allDistMargin(t2, i3, n3, r2) < this._allDistMargin(t2, i3, n3, e3) && t2.children.sort(r2);
12506 }, r.prototype._allDistMargin = function(t2, i3, n3, r2) {
12507 t2.children.sort(r2);
12508 for (var e3 = this.toBBox, a2 = h(t2, 0, i3, e3), s2 = h(t2, n3 - i3, n3, e3), l2 = u(a2) + u(s2), f3 = i3; f3 < n3 - i3; f3++) {
12509 var m2 = t2.children[f3];
12510 o(a2, t2.leaf ? e3(m2) : m2), l2 += u(a2);
12512 for (var c2 = n3 - i3 - 1; c2 >= i3; c2--) {
12513 var p2 = t2.children[c2];
12514 o(s2, t2.leaf ? e3(p2) : p2), l2 += u(s2);
12517 }, r.prototype._adjustParentBBoxes = function(t2, i3, n3) {
12518 for (var r2 = n3; r2 >= 0; r2--)
12520 }, r.prototype._condense = function(t2) {
12521 for (var i3 = t2.length - 1, n3 = void 0; i3 >= 0; i3--)
12522 0 === t2[i3].children.length ? i3 > 0 ? (n3 = t2[i3 - 1].children).splice(n3.indexOf(t2[i3]), 1) : this.clear() : a(t2[i3], this.toBBox);
12528 // node_modules/ieee754/index.js
12529 var require_ieee754 = __commonJS({
12530 "node_modules/ieee754/index.js"(exports2) {
12531 exports2.read = function(buffer, offset, isLE, mLen, nBytes) {
12533 var eLen = nBytes * 8 - mLen - 1;
12534 var eMax = (1 << eLen) - 1;
12535 var eBias = eMax >> 1;
12537 var i2 = isLE ? nBytes - 1 : 0;
12538 var d = isLE ? -1 : 1;
12539 var s = buffer[offset + i2];
12541 e = s & (1 << -nBits) - 1;
12544 for (; nBits > 0; e = e * 256 + buffer[offset + i2], i2 += d, nBits -= 8) {
12546 m = e & (1 << -nBits) - 1;
12549 for (; nBits > 0; m = m * 256 + buffer[offset + i2], i2 += d, nBits -= 8) {
12553 } else if (e === eMax) {
12554 return m ? NaN : (s ? -1 : 1) * Infinity;
12556 m = m + Math.pow(2, mLen);
12559 return (s ? -1 : 1) * m * Math.pow(2, e - mLen);
12561 exports2.write = function(buffer, value, offset, isLE, mLen, nBytes) {
12563 var eLen = nBytes * 8 - mLen - 1;
12564 var eMax = (1 << eLen) - 1;
12565 var eBias = eMax >> 1;
12566 var rt = mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0;
12567 var i2 = isLE ? 0 : nBytes - 1;
12568 var d = isLE ? 1 : -1;
12569 var s = value < 0 || value === 0 && 1 / value < 0 ? 1 : 0;
12570 value = Math.abs(value);
12571 if (isNaN(value) || value === Infinity) {
12572 m = isNaN(value) ? 1 : 0;
12575 e = Math.floor(Math.log(value) / Math.LN2);
12576 if (value * (c = Math.pow(2, -e)) < 1) {
12580 if (e + eBias >= 1) {
12583 value += rt * Math.pow(2, 1 - eBias);
12585 if (value * c >= 2) {
12589 if (e + eBias >= eMax) {
12592 } else if (e + eBias >= 1) {
12593 m = (value * c - 1) * Math.pow(2, mLen);
12596 m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen);
12600 for (; mLen >= 8; buffer[offset + i2] = m & 255, i2 += d, m /= 256, mLen -= 8) {
12604 for (; eLen > 0; buffer[offset + i2] = e & 255, i2 += d, e /= 256, eLen -= 8) {
12606 buffer[offset + i2 - d] |= s * 128;
12611 // node_modules/pbf/index.js
12612 var require_pbf = __commonJS({
12613 "node_modules/pbf/index.js"(exports2, module2) {
12615 module2.exports = Pbf;
12616 var ieee754 = require_ieee754();
12617 function Pbf(buf) {
12618 this.buf = ArrayBuffer.isView && ArrayBuffer.isView(buf) ? buf : new Uint8Array(buf || 0);
12621 this.length = this.buf.length;
12627 var SHIFT_LEFT_32 = (1 << 16) * (1 << 16);
12628 var SHIFT_RIGHT_32 = 1 / SHIFT_LEFT_32;
12629 var TEXT_DECODER_MIN_LENGTH = 12;
12630 var utf8TextDecoder = typeof TextDecoder === "undefined" ? null : new TextDecoder("utf8");
12632 destroy: function() {
12635 // === READING =================================================================
12636 readFields: function(readField, result, end) {
12637 end = end || this.length;
12638 while (this.pos < end) {
12639 var val = this.readVarint(), tag = val >> 3, startPos = this.pos;
12640 this.type = val & 7;
12641 readField(tag, result, this);
12642 if (this.pos === startPos)
12647 readMessage: function(readField, result) {
12648 return this.readFields(readField, result, this.readVarint() + this.pos);
12650 readFixed32: function() {
12651 var val = readUInt32(this.buf, this.pos);
12655 readSFixed32: function() {
12656 var val = readInt32(this.buf, this.pos);
12660 // 64-bit int handling is based on github.com/dpw/node-buffer-more-ints (MIT-licensed)
12661 readFixed64: function() {
12662 var val = readUInt32(this.buf, this.pos) + readUInt32(this.buf, this.pos + 4) * SHIFT_LEFT_32;
12666 readSFixed64: function() {
12667 var val = readUInt32(this.buf, this.pos) + readInt32(this.buf, this.pos + 4) * SHIFT_LEFT_32;
12671 readFloat: function() {
12672 var val = ieee754.read(this.buf, this.pos, true, 23, 4);
12676 readDouble: function() {
12677 var val = ieee754.read(this.buf, this.pos, true, 52, 8);
12681 readVarint: function(isSigned) {
12682 var buf = this.buf, val, b;
12683 b = buf[this.pos++];
12687 b = buf[this.pos++];
12688 val |= (b & 127) << 7;
12691 b = buf[this.pos++];
12692 val |= (b & 127) << 14;
12695 b = buf[this.pos++];
12696 val |= (b & 127) << 21;
12700 val |= (b & 15) << 28;
12701 return readVarintRemainder(val, isSigned, this);
12703 readVarint64: function() {
12704 return this.readVarint(true);
12706 readSVarint: function() {
12707 var num = this.readVarint();
12708 return num % 2 === 1 ? (num + 1) / -2 : num / 2;
12710 readBoolean: function() {
12711 return Boolean(this.readVarint());
12713 readString: function() {
12714 var end = this.readVarint() + this.pos;
12715 var pos = this.pos;
12717 if (end - pos >= TEXT_DECODER_MIN_LENGTH && utf8TextDecoder) {
12718 return readUtf8TextDecoder(this.buf, pos, end);
12720 return readUtf8(this.buf, pos, end);
12722 readBytes: function() {
12723 var end = this.readVarint() + this.pos, buffer = this.buf.subarray(this.pos, end);
12727 // verbose for performance reasons; doesn't affect gzipped size
12728 readPackedVarint: function(arr, isSigned) {
12729 if (this.type !== Pbf.Bytes)
12730 return arr.push(this.readVarint(isSigned));
12731 var end = readPackedEnd(this);
12733 while (this.pos < end)
12734 arr.push(this.readVarint(isSigned));
12737 readPackedSVarint: function(arr) {
12738 if (this.type !== Pbf.Bytes)
12739 return arr.push(this.readSVarint());
12740 var end = readPackedEnd(this);
12742 while (this.pos < end)
12743 arr.push(this.readSVarint());
12746 readPackedBoolean: function(arr) {
12747 if (this.type !== Pbf.Bytes)
12748 return arr.push(this.readBoolean());
12749 var end = readPackedEnd(this);
12751 while (this.pos < end)
12752 arr.push(this.readBoolean());
12755 readPackedFloat: function(arr) {
12756 if (this.type !== Pbf.Bytes)
12757 return arr.push(this.readFloat());
12758 var end = readPackedEnd(this);
12760 while (this.pos < end)
12761 arr.push(this.readFloat());
12764 readPackedDouble: function(arr) {
12765 if (this.type !== Pbf.Bytes)
12766 return arr.push(this.readDouble());
12767 var end = readPackedEnd(this);
12769 while (this.pos < end)
12770 arr.push(this.readDouble());
12773 readPackedFixed32: function(arr) {
12774 if (this.type !== Pbf.Bytes)
12775 return arr.push(this.readFixed32());
12776 var end = readPackedEnd(this);
12778 while (this.pos < end)
12779 arr.push(this.readFixed32());
12782 readPackedSFixed32: function(arr) {
12783 if (this.type !== Pbf.Bytes)
12784 return arr.push(this.readSFixed32());
12785 var end = readPackedEnd(this);
12787 while (this.pos < end)
12788 arr.push(this.readSFixed32());
12791 readPackedFixed64: function(arr) {
12792 if (this.type !== Pbf.Bytes)
12793 return arr.push(this.readFixed64());
12794 var end = readPackedEnd(this);
12796 while (this.pos < end)
12797 arr.push(this.readFixed64());
12800 readPackedSFixed64: function(arr) {
12801 if (this.type !== Pbf.Bytes)
12802 return arr.push(this.readSFixed64());
12803 var end = readPackedEnd(this);
12805 while (this.pos < end)
12806 arr.push(this.readSFixed64());
12809 skip: function(val) {
12810 var type2 = val & 7;
12811 if (type2 === Pbf.Varint)
12812 while (this.buf[this.pos++] > 127) {
12814 else if (type2 === Pbf.Bytes)
12815 this.pos = this.readVarint() + this.pos;
12816 else if (type2 === Pbf.Fixed32)
12818 else if (type2 === Pbf.Fixed64)
12821 throw new Error("Unimplemented type: " + type2);
12823 // === WRITING =================================================================
12824 writeTag: function(tag, type2) {
12825 this.writeVarint(tag << 3 | type2);
12827 realloc: function(min3) {
12828 var length = this.length || 16;
12829 while (length < this.pos + min3)
12831 if (length !== this.length) {
12832 var buf = new Uint8Array(length);
12835 this.length = length;
12838 finish: function() {
12839 this.length = this.pos;
12841 return this.buf.subarray(0, this.length);
12843 writeFixed32: function(val) {
12845 writeInt32(this.buf, val, this.pos);
12848 writeSFixed32: function(val) {
12850 writeInt32(this.buf, val, this.pos);
12853 writeFixed64: function(val) {
12855 writeInt32(this.buf, val & -1, this.pos);
12856 writeInt32(this.buf, Math.floor(val * SHIFT_RIGHT_32), this.pos + 4);
12859 writeSFixed64: function(val) {
12861 writeInt32(this.buf, val & -1, this.pos);
12862 writeInt32(this.buf, Math.floor(val * SHIFT_RIGHT_32), this.pos + 4);
12865 writeVarint: function(val) {
12867 if (val > 268435455 || val < 0) {
12868 writeBigVarint(val, this);
12872 this.buf[this.pos++] = val & 127 | (val > 127 ? 128 : 0);
12875 this.buf[this.pos++] = (val >>>= 7) & 127 | (val > 127 ? 128 : 0);
12878 this.buf[this.pos++] = (val >>>= 7) & 127 | (val > 127 ? 128 : 0);
12881 this.buf[this.pos++] = val >>> 7 & 127;
12883 writeSVarint: function(val) {
12884 this.writeVarint(val < 0 ? -val * 2 - 1 : val * 2);
12886 writeBoolean: function(val) {
12887 this.writeVarint(Boolean(val));
12889 writeString: function(str2) {
12890 str2 = String(str2);
12891 this.realloc(str2.length * 4);
12893 var startPos = this.pos;
12894 this.pos = writeUtf8(this.buf, str2, this.pos);
12895 var len = this.pos - startPos;
12897 makeRoomForExtraLength(startPos, len, this);
12898 this.pos = startPos - 1;
12899 this.writeVarint(len);
12902 writeFloat: function(val) {
12904 ieee754.write(this.buf, val, this.pos, true, 23, 4);
12907 writeDouble: function(val) {
12909 ieee754.write(this.buf, val, this.pos, true, 52, 8);
12912 writeBytes: function(buffer) {
12913 var len = buffer.length;
12914 this.writeVarint(len);
12916 for (var i2 = 0; i2 < len; i2++)
12917 this.buf[this.pos++] = buffer[i2];
12919 writeRawMessage: function(fn, obj) {
12921 var startPos = this.pos;
12923 var len = this.pos - startPos;
12925 makeRoomForExtraLength(startPos, len, this);
12926 this.pos = startPos - 1;
12927 this.writeVarint(len);
12930 writeMessage: function(tag, fn, obj) {
12931 this.writeTag(tag, Pbf.Bytes);
12932 this.writeRawMessage(fn, obj);
12934 writePackedVarint: function(tag, arr) {
12936 this.writeMessage(tag, writePackedVarint, arr);
12938 writePackedSVarint: function(tag, arr) {
12940 this.writeMessage(tag, writePackedSVarint, arr);
12942 writePackedBoolean: function(tag, arr) {
12944 this.writeMessage(tag, writePackedBoolean, arr);
12946 writePackedFloat: function(tag, arr) {
12948 this.writeMessage(tag, writePackedFloat, arr);
12950 writePackedDouble: function(tag, arr) {
12952 this.writeMessage(tag, writePackedDouble, arr);
12954 writePackedFixed32: function(tag, arr) {
12956 this.writeMessage(tag, writePackedFixed32, arr);
12958 writePackedSFixed32: function(tag, arr) {
12960 this.writeMessage(tag, writePackedSFixed32, arr);
12962 writePackedFixed64: function(tag, arr) {
12964 this.writeMessage(tag, writePackedFixed64, arr);
12966 writePackedSFixed64: function(tag, arr) {
12968 this.writeMessage(tag, writePackedSFixed64, arr);
12970 writeBytesField: function(tag, buffer) {
12971 this.writeTag(tag, Pbf.Bytes);
12972 this.writeBytes(buffer);
12974 writeFixed32Field: function(tag, val) {
12975 this.writeTag(tag, Pbf.Fixed32);
12976 this.writeFixed32(val);
12978 writeSFixed32Field: function(tag, val) {
12979 this.writeTag(tag, Pbf.Fixed32);
12980 this.writeSFixed32(val);
12982 writeFixed64Field: function(tag, val) {
12983 this.writeTag(tag, Pbf.Fixed64);
12984 this.writeFixed64(val);
12986 writeSFixed64Field: function(tag, val) {
12987 this.writeTag(tag, Pbf.Fixed64);
12988 this.writeSFixed64(val);
12990 writeVarintField: function(tag, val) {
12991 this.writeTag(tag, Pbf.Varint);
12992 this.writeVarint(val);
12994 writeSVarintField: function(tag, val) {
12995 this.writeTag(tag, Pbf.Varint);
12996 this.writeSVarint(val);
12998 writeStringField: function(tag, str2) {
12999 this.writeTag(tag, Pbf.Bytes);
13000 this.writeString(str2);
13002 writeFloatField: function(tag, val) {
13003 this.writeTag(tag, Pbf.Fixed32);
13004 this.writeFloat(val);
13006 writeDoubleField: function(tag, val) {
13007 this.writeTag(tag, Pbf.Fixed64);
13008 this.writeDouble(val);
13010 writeBooleanField: function(tag, val) {
13011 this.writeVarintField(tag, Boolean(val));
13014 function readVarintRemainder(l, s, p) {
13015 var buf = p.buf, h, b;
13017 h = (b & 112) >> 4;
13019 return toNum(l, h, s);
13021 h |= (b & 127) << 3;
13023 return toNum(l, h, s);
13025 h |= (b & 127) << 10;
13027 return toNum(l, h, s);
13029 h |= (b & 127) << 17;
13031 return toNum(l, h, s);
13033 h |= (b & 127) << 24;
13035 return toNum(l, h, s);
13037 h |= (b & 1) << 31;
13039 return toNum(l, h, s);
13040 throw new Error("Expected varint not more than 10 bytes");
13042 function readPackedEnd(pbf) {
13043 return pbf.type === Pbf.Bytes ? pbf.readVarint() + pbf.pos : pbf.pos + 1;
13045 function toNum(low, high, isSigned) {
13047 return high * 4294967296 + (low >>> 0);
13049 return (high >>> 0) * 4294967296 + (low >>> 0);
13051 function writeBigVarint(val, pbf) {
13054 low = val % 4294967296 | 0;
13055 high = val / 4294967296 | 0;
13057 low = ~(-val % 4294967296);
13058 high = ~(-val / 4294967296);
13059 if (low ^ 4294967295) {
13063 high = high + 1 | 0;
13066 if (val >= 18446744073709552e3 || val < -18446744073709552e3) {
13067 throw new Error("Given varint doesn't fit into 10 bytes");
13070 writeBigVarintLow(low, high, pbf);
13071 writeBigVarintHigh(high, pbf);
13073 function writeBigVarintLow(low, high, pbf) {
13074 pbf.buf[pbf.pos++] = low & 127 | 128;
13076 pbf.buf[pbf.pos++] = low & 127 | 128;
13078 pbf.buf[pbf.pos++] = low & 127 | 128;
13080 pbf.buf[pbf.pos++] = low & 127 | 128;
13082 pbf.buf[pbf.pos] = low & 127;
13084 function writeBigVarintHigh(high, pbf) {
13085 var lsb = (high & 7) << 4;
13086 pbf.buf[pbf.pos++] |= lsb | ((high >>>= 3) ? 128 : 0);
13089 pbf.buf[pbf.pos++] = high & 127 | ((high >>>= 7) ? 128 : 0);
13092 pbf.buf[pbf.pos++] = high & 127 | ((high >>>= 7) ? 128 : 0);
13095 pbf.buf[pbf.pos++] = high & 127 | ((high >>>= 7) ? 128 : 0);
13098 pbf.buf[pbf.pos++] = high & 127 | ((high >>>= 7) ? 128 : 0);
13101 pbf.buf[pbf.pos++] = high & 127;
13103 function makeRoomForExtraLength(startPos, len, pbf) {
13104 var extraLen = len <= 16383 ? 1 : len <= 2097151 ? 2 : len <= 268435455 ? 3 : Math.floor(Math.log(len) / (Math.LN2 * 7));
13105 pbf.realloc(extraLen);
13106 for (var i2 = pbf.pos - 1; i2 >= startPos; i2--)
13107 pbf.buf[i2 + extraLen] = pbf.buf[i2];
13109 function writePackedVarint(arr, pbf) {
13110 for (var i2 = 0; i2 < arr.length; i2++)
13111 pbf.writeVarint(arr[i2]);
13113 function writePackedSVarint(arr, pbf) {
13114 for (var i2 = 0; i2 < arr.length; i2++)
13115 pbf.writeSVarint(arr[i2]);
13117 function writePackedFloat(arr, pbf) {
13118 for (var i2 = 0; i2 < arr.length; i2++)
13119 pbf.writeFloat(arr[i2]);
13121 function writePackedDouble(arr, pbf) {
13122 for (var i2 = 0; i2 < arr.length; i2++)
13123 pbf.writeDouble(arr[i2]);
13125 function writePackedBoolean(arr, pbf) {
13126 for (var i2 = 0; i2 < arr.length; i2++)
13127 pbf.writeBoolean(arr[i2]);
13129 function writePackedFixed32(arr, pbf) {
13130 for (var i2 = 0; i2 < arr.length; i2++)
13131 pbf.writeFixed32(arr[i2]);
13133 function writePackedSFixed32(arr, pbf) {
13134 for (var i2 = 0; i2 < arr.length; i2++)
13135 pbf.writeSFixed32(arr[i2]);
13137 function writePackedFixed64(arr, pbf) {
13138 for (var i2 = 0; i2 < arr.length; i2++)
13139 pbf.writeFixed64(arr[i2]);
13141 function writePackedSFixed64(arr, pbf) {
13142 for (var i2 = 0; i2 < arr.length; i2++)
13143 pbf.writeSFixed64(arr[i2]);
13145 function readUInt32(buf, pos) {
13146 return (buf[pos] | buf[pos + 1] << 8 | buf[pos + 2] << 16) + buf[pos + 3] * 16777216;
13148 function writeInt32(buf, val, pos) {
13150 buf[pos + 1] = val >>> 8;
13151 buf[pos + 2] = val >>> 16;
13152 buf[pos + 3] = val >>> 24;
13154 function readInt32(buf, pos) {
13155 return (buf[pos] | buf[pos + 1] << 8 | buf[pos + 2] << 16) + (buf[pos + 3] << 24);
13157 function readUtf8(buf, pos, end) {
13163 var bytesPerSequence = b0 > 239 ? 4 : b0 > 223 ? 3 : b0 > 191 ? 2 : 1;
13164 if (i2 + bytesPerSequence > end)
13167 if (bytesPerSequence === 1) {
13171 } else if (bytesPerSequence === 2) {
13173 if ((b1 & 192) === 128) {
13174 c = (b0 & 31) << 6 | b1 & 63;
13179 } else if (bytesPerSequence === 3) {
13182 if ((b1 & 192) === 128 && (b2 & 192) === 128) {
13183 c = (b0 & 15) << 12 | (b1 & 63) << 6 | b2 & 63;
13184 if (c <= 2047 || c >= 55296 && c <= 57343) {
13188 } else if (bytesPerSequence === 4) {
13192 if ((b1 & 192) === 128 && (b2 & 192) === 128 && (b3 & 192) === 128) {
13193 c = (b0 & 15) << 18 | (b1 & 63) << 12 | (b2 & 63) << 6 | b3 & 63;
13194 if (c <= 65535 || c >= 1114112) {
13201 bytesPerSequence = 1;
13202 } else if (c > 65535) {
13204 str2 += String.fromCharCode(c >>> 10 & 1023 | 55296);
13205 c = 56320 | c & 1023;
13207 str2 += String.fromCharCode(c);
13208 i2 += bytesPerSequence;
13212 function readUtf8TextDecoder(buf, pos, end) {
13213 return utf8TextDecoder.decode(buf.subarray(pos, end));
13215 function writeUtf8(buf, str2, pos) {
13216 for (var i2 = 0, c, lead; i2 < str2.length; i2++) {
13217 c = str2.charCodeAt(i2);
13218 if (c > 55295 && c < 57344) {
13227 c = lead - 55296 << 10 | c - 56320 | 65536;
13231 if (c > 56319 || i2 + 1 === str2.length) {
13250 buf[pos++] = c >> 6 | 192;
13253 buf[pos++] = c >> 12 | 224;
13255 buf[pos++] = c >> 18 | 240;
13256 buf[pos++] = c >> 12 & 63 | 128;
13258 buf[pos++] = c >> 6 & 63 | 128;
13260 buf[pos++] = c & 63 | 128;
13268 // node_modules/@mapbox/point-geometry/index.js
13269 var require_point_geometry = __commonJS({
13270 "node_modules/@mapbox/point-geometry/index.js"(exports2, module2) {
13272 module2.exports = Point;
13273 function Point(x, y) {
13277 Point.prototype = {
13279 * Clone this point, returning a new point that can be modified
13280 * without affecting the old one.
13281 * @return {Point} the clone
13283 clone: function() {
13284 return new Point(this.x, this.y);
13287 * Add this point's x & y coordinates to another point,
13288 * yielding a new point.
13289 * @param {Point} p the other point
13290 * @return {Point} output point
13293 return this.clone()._add(p);
13296 * Subtract this point's x & y coordinates to from point,
13297 * yielding a new point.
13298 * @param {Point} p the other point
13299 * @return {Point} output point
13302 return this.clone()._sub(p);
13305 * Multiply this point's x & y coordinates by point,
13306 * yielding a new point.
13307 * @param {Point} p the other point
13308 * @return {Point} output point
13310 multByPoint: function(p) {
13311 return this.clone()._multByPoint(p);
13314 * Divide this point's x & y coordinates by point,
13315 * yielding a new point.
13316 * @param {Point} p the other point
13317 * @return {Point} output point
13319 divByPoint: function(p) {
13320 return this.clone()._divByPoint(p);
13323 * Multiply this point's x & y coordinates by a factor,
13324 * yielding a new point.
13325 * @param {Point} k factor
13326 * @return {Point} output point
13328 mult: function(k) {
13329 return this.clone()._mult(k);
13332 * Divide this point's x & y coordinates by a factor,
13333 * yielding a new point.
13334 * @param {Point} k factor
13335 * @return {Point} output point
13338 return this.clone()._div(k);
13341 * Rotate this point around the 0, 0 origin by an angle a,
13343 * @param {Number} a angle to rotate around, in radians
13344 * @return {Point} output point
13346 rotate: function(a) {
13347 return this.clone()._rotate(a);
13350 * Rotate this point around p point by an angle a,
13352 * @param {Number} a angle to rotate around, in radians
13353 * @param {Point} p Point to rotate around
13354 * @return {Point} output point
13356 rotateAround: function(a, p) {
13357 return this.clone()._rotateAround(a, p);
13360 * Multiply this point by a 4x1 transformation matrix
13361 * @param {Array<Number>} m transformation matrix
13362 * @return {Point} output point
13364 matMult: function(m) {
13365 return this.clone()._matMult(m);
13368 * Calculate this point but as a unit vector from 0, 0, meaning
13369 * that the distance from the resulting point to the 0, 0
13370 * coordinate will be equal to 1 and the angle from the resulting
13371 * point to the 0, 0 coordinate will be the same as before.
13372 * @return {Point} unit vector point
13375 return this.clone()._unit();
13378 * Compute a perpendicular point, where the new y coordinate
13379 * is the old x coordinate and the new x coordinate is the old y
13380 * coordinate multiplied by -1
13381 * @return {Point} perpendicular point
13384 return this.clone()._perp();
13387 * Return a version of this point with the x & y coordinates
13388 * rounded to integers.
13389 * @return {Point} rounded point
13391 round: function() {
13392 return this.clone()._round();
13395 * Return the magitude of this point: this is the Euclidean
13396 * distance from the 0, 0 coordinate to this point's x and y
13398 * @return {Number} magnitude
13401 return Math.sqrt(this.x * this.x + this.y * this.y);
13404 * Judge whether this point is equal to another point, returning
13406 * @param {Point} other the other point
13407 * @return {boolean} whether the points are equal
13409 equals: function(other) {
13410 return this.x === other.x && this.y === other.y;
13413 * Calculate the distance from this point to another point
13414 * @param {Point} p the other point
13415 * @return {Number} distance
13417 dist: function(p) {
13418 return Math.sqrt(this.distSqr(p));
13421 * Calculate the distance from this point to another point,
13422 * without the square root step. Useful if you're comparing
13423 * relative distances.
13424 * @param {Point} p the other point
13425 * @return {Number} distance
13427 distSqr: function(p) {
13428 var dx = p.x - this.x, dy = p.y - this.y;
13429 return dx * dx + dy * dy;
13432 * Get the angle from the 0, 0 coordinate to this point, in radians
13434 * @return {Number} angle
13436 angle: function() {
13437 return Math.atan2(this.y, this.x);
13440 * Get the angle from this point to another point, in radians
13441 * @param {Point} b the other point
13442 * @return {Number} angle
13444 angleTo: function(b) {
13445 return Math.atan2(this.y - b.y, this.x - b.x);
13448 * Get the angle between this point and another point, in radians
13449 * @param {Point} b the other point
13450 * @return {Number} angle
13452 angleWith: function(b) {
13453 return this.angleWithSep(b.x, b.y);
13456 * Find the angle of the two vectors, solving the formula for
13457 * the cross product a x b = |a||b|sin(θ) for θ.
13458 * @param {Number} x the x-coordinate
13459 * @param {Number} y the y-coordinate
13460 * @return {Number} the angle in radians
13462 angleWithSep: function(x, y) {
13464 this.x * y - this.y * x,
13465 this.x * x + this.y * y
13468 _matMult: function(m) {
13469 var x = m[0] * this.x + m[1] * this.y, y = m[2] * this.x + m[3] * this.y;
13474 _add: function(p) {
13479 _sub: function(p) {
13484 _mult: function(k) {
13489 _div: function(k) {
13494 _multByPoint: function(p) {
13499 _divByPoint: function(p) {
13504 _unit: function() {
13505 this._div(this.mag());
13508 _perp: function() {
13514 _rotate: function(angle2) {
13515 var cos2 = Math.cos(angle2), sin2 = Math.sin(angle2), x = cos2 * this.x - sin2 * this.y, y = sin2 * this.x + cos2 * this.y;
13520 _rotateAround: function(angle2, p) {
13521 var cos2 = Math.cos(angle2), sin2 = Math.sin(angle2), x = p.x + cos2 * (this.x - p.x) - sin2 * (this.y - p.y), y = p.y + sin2 * (this.x - p.x) + cos2 * (this.y - p.y);
13526 _round: function() {
13527 this.x = Math.round(this.x);
13528 this.y = Math.round(this.y);
13532 Point.convert = function(a) {
13533 if (a instanceof Point) {
13536 if (Array.isArray(a)) {
13537 return new Point(a[0], a[1]);
13544 // node_modules/@mapbox/vector-tile/lib/vectortilefeature.js
13545 var require_vectortilefeature = __commonJS({
13546 "node_modules/@mapbox/vector-tile/lib/vectortilefeature.js"(exports2, module2) {
13548 var Point = require_point_geometry();
13549 module2.exports = VectorTileFeature;
13550 function VectorTileFeature(pbf, end, extent, keys, values) {
13551 this.properties = {};
13552 this.extent = extent;
13555 this._geometry = -1;
13557 this._values = values;
13558 pbf.readFields(readFeature, this, end);
13560 function readFeature(tag, feature3, pbf) {
13562 feature3.id = pbf.readVarint();
13564 readTag(pbf, feature3);
13566 feature3.type = pbf.readVarint();
13568 feature3._geometry = pbf.pos;
13570 function readTag(pbf, feature3) {
13571 var end = pbf.readVarint() + pbf.pos;
13572 while (pbf.pos < end) {
13573 var key = feature3._keys[pbf.readVarint()], value = feature3._values[pbf.readVarint()];
13574 feature3.properties[key] = value;
13577 VectorTileFeature.types = ["Unknown", "Point", "LineString", "Polygon"];
13578 VectorTileFeature.prototype.loadGeometry = function() {
13579 var pbf = this._pbf;
13580 pbf.pos = this._geometry;
13581 var end = pbf.readVarint() + pbf.pos, cmd = 1, length = 0, x = 0, y = 0, lines = [], line;
13582 while (pbf.pos < end) {
13584 var cmdLen = pbf.readVarint();
13586 length = cmdLen >> 3;
13589 if (cmd === 1 || cmd === 2) {
13590 x += pbf.readSVarint();
13591 y += pbf.readSVarint();
13597 line.push(new Point(x, y));
13598 } else if (cmd === 7) {
13600 line.push(line[0].clone());
13603 throw new Error("unknown command " + cmd);
13610 VectorTileFeature.prototype.bbox = function() {
13611 var pbf = this._pbf;
13612 pbf.pos = this._geometry;
13613 var end = pbf.readVarint() + pbf.pos, cmd = 1, length = 0, x = 0, y = 0, x12 = Infinity, x2 = -Infinity, y12 = Infinity, y2 = -Infinity;
13614 while (pbf.pos < end) {
13616 var cmdLen = pbf.readVarint();
13618 length = cmdLen >> 3;
13621 if (cmd === 1 || cmd === 2) {
13622 x += pbf.readSVarint();
13623 y += pbf.readSVarint();
13632 } else if (cmd !== 7) {
13633 throw new Error("unknown command " + cmd);
13636 return [x12, y12, x2, y2];
13638 VectorTileFeature.prototype.toGeoJSON = function(x, y, z) {
13639 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;
13640 function project(line) {
13641 for (var j3 = 0; j3 < line.length; j3++) {
13642 var p = line[j3], y2 = 180 - (p.y + y05) * 360 / size;
13644 (p.x + x05) * 360 / size - 180,
13645 360 / Math.PI * Math.atan(Math.exp(y2 * Math.PI / 180)) - 90
13649 switch (this.type) {
13652 for (i2 = 0; i2 < coords.length; i2++) {
13653 points[i2] = coords[i2][0];
13659 for (i2 = 0; i2 < coords.length; i2++) {
13660 project(coords[i2]);
13664 coords = classifyRings(coords);
13665 for (i2 = 0; i2 < coords.length; i2++) {
13666 for (j2 = 0; j2 < coords[i2].length; j2++) {
13667 project(coords[i2][j2]);
13672 if (coords.length === 1) {
13673 coords = coords[0];
13675 type2 = "Multi" + type2;
13681 coordinates: coords
13683 properties: this.properties
13685 if ("id" in this) {
13686 result.id = this.id;
13690 function classifyRings(rings) {
13691 var len = rings.length;
13694 var polygons = [], polygon2, ccw;
13695 for (var i2 = 0; i2 < len; i2++) {
13696 var area = signedArea(rings[i2]);
13699 if (ccw === void 0)
13701 if (ccw === area < 0) {
13703 polygons.push(polygon2);
13704 polygon2 = [rings[i2]];
13706 polygon2.push(rings[i2]);
13710 polygons.push(polygon2);
13713 function signedArea(ring) {
13715 for (var i2 = 0, len = ring.length, j2 = len - 1, p1, p2; i2 < len; j2 = i2++) {
13718 sum += (p2.x - p1.x) * (p1.y + p2.y);
13725 // node_modules/@mapbox/vector-tile/lib/vectortilelayer.js
13726 var require_vectortilelayer = __commonJS({
13727 "node_modules/@mapbox/vector-tile/lib/vectortilelayer.js"(exports2, module2) {
13729 var VectorTileFeature = require_vectortilefeature();
13730 module2.exports = VectorTileLayer;
13731 function VectorTileLayer(pbf, end) {
13734 this.extent = 4096;
13739 this._features = [];
13740 pbf.readFields(readLayer, this, end);
13741 this.length = this._features.length;
13743 function readLayer(tag, layer, pbf) {
13745 layer.version = pbf.readVarint();
13746 else if (tag === 1)
13747 layer.name = pbf.readString();
13748 else if (tag === 5)
13749 layer.extent = pbf.readVarint();
13750 else if (tag === 2)
13751 layer._features.push(pbf.pos);
13752 else if (tag === 3)
13753 layer._keys.push(pbf.readString());
13754 else if (tag === 4)
13755 layer._values.push(readValueMessage(pbf));
13757 function readValueMessage(pbf) {
13758 var value = null, end = pbf.readVarint() + pbf.pos;
13759 while (pbf.pos < end) {
13760 var tag = pbf.readVarint() >> 3;
13761 value = tag === 1 ? pbf.readString() : tag === 2 ? pbf.readFloat() : tag === 3 ? pbf.readDouble() : tag === 4 ? pbf.readVarint64() : tag === 5 ? pbf.readVarint() : tag === 6 ? pbf.readSVarint() : tag === 7 ? pbf.readBoolean() : null;
13765 VectorTileLayer.prototype.feature = function(i2) {
13766 if (i2 < 0 || i2 >= this._features.length)
13767 throw new Error("feature index out of bounds");
13768 this._pbf.pos = this._features[i2];
13769 var end = this._pbf.readVarint() + this._pbf.pos;
13770 return new VectorTileFeature(this._pbf, end, this.extent, this._keys, this._values);
13775 // node_modules/@mapbox/vector-tile/lib/vectortile.js
13776 var require_vectortile = __commonJS({
13777 "node_modules/@mapbox/vector-tile/lib/vectortile.js"(exports2, module2) {
13779 var VectorTileLayer = require_vectortilelayer();
13780 module2.exports = VectorTile2;
13781 function VectorTile2(pbf, end) {
13782 this.layers = pbf.readFields(readTile, {}, end);
13784 function readTile(tag, layers, pbf) {
13786 var layer = new VectorTileLayer(pbf, pbf.readVarint() + pbf.pos);
13788 layers[layer.name] = layer;
13794 // node_modules/@mapbox/vector-tile/index.js
13795 var require_vector_tile = __commonJS({
13796 "node_modules/@mapbox/vector-tile/index.js"(exports2, module2) {
13797 module2.exports.VectorTile = require_vectortile();
13798 module2.exports.VectorTileFeature = require_vectortilefeature();
13799 module2.exports.VectorTileLayer = require_vectortilelayer();
13803 // node_modules/fast-json-stable-stringify/index.js
13804 var require_fast_json_stable_stringify = __commonJS({
13805 "node_modules/fast-json-stable-stringify/index.js"(exports2, module2) {
13807 module2.exports = function(data, opts) {
13810 if (typeof opts === "function")
13811 opts = { cmp: opts };
13812 var cycles = typeof opts.cycles === "boolean" ? opts.cycles : false;
13813 var cmp = opts.cmp && function(f2) {
13814 return function(node) {
13815 return function(a, b) {
13816 var aobj = { key: a, value: node[a] };
13817 var bobj = { key: b, value: node[b] };
13818 return f2(aobj, bobj);
13823 return function stringify3(node) {
13824 if (node && node.toJSON && typeof node.toJSON === "function") {
13825 node = node.toJSON();
13827 if (node === void 0)
13829 if (typeof node == "number")
13830 return isFinite(node) ? "" + node : "null";
13831 if (typeof node !== "object")
13832 return JSON.stringify(node);
13834 if (Array.isArray(node)) {
13836 for (i2 = 0; i2 < node.length; i2++) {
13839 out += stringify3(node[i2]) || "null";
13845 if (seen.indexOf(node) !== -1) {
13847 return JSON.stringify("__cycle__");
13848 throw new TypeError("Converting circular structure to JSON");
13850 var seenIndex = seen.push(node) - 1;
13851 var keys = Object.keys(node).sort(cmp && cmp(node));
13853 for (i2 = 0; i2 < keys.length; i2++) {
13854 var key = keys[i2];
13855 var value = stringify3(node[key]);
13860 out += JSON.stringify(key) + ":" + value;
13862 seen.splice(seenIndex, 1);
13863 return "{" + out + "}";
13869 // node_modules/@mapbox/sexagesimal/index.js
13870 var require_sexagesimal = __commonJS({
13871 "node_modules/@mapbox/sexagesimal/index.js"(exports2, module2) {
13872 module2.exports = element;
13873 module2.exports.pair = pair2;
13874 module2.exports.format = format2;
13875 module2.exports.formatPair = formatPair;
13876 module2.exports.coordToDMS = coordToDMS;
13877 function element(input, dims) {
13878 var result = search(input, dims);
13879 return result === null ? null : result.val;
13881 function formatPair(input) {
13882 return format2(input.lat, "lat") + " " + format2(input.lon, "lon");
13884 function format2(input, dim) {
13885 var dms = coordToDMS(input, dim);
13886 return dms.whole + "\xB0 " + (dms.minutes ? dms.minutes + "' " : "") + (dms.seconds ? dms.seconds + '" ' : "") + dms.dir;
13888 function coordToDMS(input, dim) {
13889 var dirs = { lat: ["N", "S"], lon: ["E", "W"] }[dim] || "";
13890 var dir = dirs[input >= 0 ? 0 : 1];
13891 var abs3 = Math.abs(input);
13892 var whole = Math.floor(abs3);
13893 var fraction = abs3 - whole;
13894 var fractionMinutes = fraction * 60;
13895 var minutes = Math.floor(fractionMinutes);
13896 var seconds = Math.floor((fractionMinutes - minutes) * 60);
13904 function search(input, dims) {
13907 if (typeof input !== "string")
13909 input = input.toUpperCase();
13910 var regex = /^[\s\,]*([NSEW])?\s*([\-|\—|\―]?[0-9.]+)[°º˚]?\s*(?:([0-9.]+)['’′‘]\s*)?(?:([0-9.]+)(?:''|"|”|″)\s*)?([NSEW])?/;
13911 var m = input.match(regex);
13914 var matched = m[0];
13916 if (m[1] && m[5]) {
13918 matched = matched.slice(0, -1);
13920 dim = m[1] || m[5];
13922 if (dim && dims.indexOf(dim) === -1)
13924 var deg = m[2] ? parseFloat(m[2]) : 0;
13925 var min3 = m[3] ? parseFloat(m[3]) / 60 : 0;
13926 var sec = m[4] ? parseFloat(m[4]) / 3600 : 0;
13927 var sign2 = deg < 0 ? -1 : 1;
13928 if (dim === "S" || dim === "W")
13931 val: (Math.abs(deg) + min3 + sec) * sign2,
13934 remain: input.slice(matched.length)
13937 function pair2(input, dims) {
13938 input = input.trim();
13939 var one2 = search(input, dims);
13942 input = one2.remain.trim();
13943 var two = search(input, dims);
13944 if (!two || two.remain)
13947 return swapdim(one2.val, two.val, one2.dim);
13949 return [one2.val, two.val];
13952 function swapdim(a, b, dim) {
13953 if (dim === "N" || dim === "S")
13955 if (dim === "W" || dim === "E")
13961 // node_modules/store/src/util.js
13962 var require_util = __commonJS({
13963 "node_modules/store/src/util.js"(exports2, module2) {
13964 var assign = make_assign();
13965 var create2 = make_create();
13966 var trim = make_trim();
13967 var Global = typeof window !== "undefined" ? window : global;
13968 module2.exports = {
13979 isObject: isObject3,
13982 function make_assign() {
13983 if (Object.assign) {
13984 return Object.assign;
13986 return function shimAssign(obj, props1, props2, etc) {
13987 for (var i2 = 1; i2 < arguments.length; i2++) {
13988 each(Object(arguments[i2]), function(val, key) {
13996 function make_create() {
13997 if (Object.create) {
13998 return function create3(obj, assignProps1, assignProps2, etc) {
13999 var assignArgsList = slice(arguments, 1);
14000 return assign.apply(this, [Object.create(obj)].concat(assignArgsList));
14003 let F2 = function() {
14006 return function create3(obj, assignProps1, assignProps2, etc) {
14007 var assignArgsList = slice(arguments, 1);
14008 F2.prototype = obj;
14009 return assign.apply(this, [new F2()].concat(assignArgsList));
14013 function make_trim() {
14014 if (String.prototype.trim) {
14015 return function trim2(str2) {
14016 return String.prototype.trim.call(str2);
14019 return function trim2(str2) {
14020 return str2.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, "");
14024 function bind(obj, fn) {
14025 return function() {
14026 return fn.apply(obj, Array.prototype.slice.call(arguments, 0));
14029 function slice(arr, index) {
14030 return Array.prototype.slice.call(arr, index || 0);
14032 function each(obj, fn) {
14033 pluck(obj, function(val, key) {
14038 function map2(obj, fn) {
14039 var res = isList(obj) ? [] : {};
14040 pluck(obj, function(v, k) {
14046 function pluck(obj, fn) {
14048 for (var i2 = 0; i2 < obj.length; i2++) {
14049 if (fn(obj[i2], i2)) {
14054 for (var key in obj) {
14055 if (obj.hasOwnProperty(key)) {
14056 if (fn(obj[key], key)) {
14063 function isList(val) {
14064 return val != null && typeof val != "function" && typeof val.length == "number";
14066 function isFunction(val) {
14067 return val && {}.toString.call(val) === "[object Function]";
14069 function isObject3(val) {
14070 return val && {}.toString.call(val) === "[object Object]";
14075 // node_modules/store/src/store-engine.js
14076 var require_store_engine = __commonJS({
14077 "node_modules/store/src/store-engine.js"(exports2, module2) {
14078 var util = require_util();
14079 var slice = util.slice;
14080 var pluck = util.pluck;
14081 var each = util.each;
14082 var bind = util.bind;
14083 var create2 = util.create;
14084 var isList = util.isList;
14085 var isFunction = util.isFunction;
14086 var isObject3 = util.isObject;
14087 module2.exports = {
14093 // get returns the value of the given key. If that value
14094 // is undefined, it returns optionalDefaultValue instead.
14095 get: function(key, optionalDefaultValue) {
14096 var data = this.storage.read(this._namespacePrefix + key);
14097 return this._deserialize(data, optionalDefaultValue);
14099 // set will store the given value at key and returns value.
14100 // Calling set with value === undefined is equivalent to calling remove.
14101 set: function(key, value) {
14102 if (value === void 0) {
14103 return this.remove(key);
14105 this.storage.write(this._namespacePrefix + key, this._serialize(value));
14108 // remove deletes the key and value stored at the given key.
14109 remove: function(key) {
14110 this.storage.remove(this._namespacePrefix + key);
14112 // each will call the given callback once for each key-value pair
14114 each: function(callback) {
14116 this.storage.each(function(val, namespacedKey) {
14117 callback.call(self2, self2._deserialize(val), (namespacedKey || "").replace(self2._namespaceRegexp, ""));
14120 // clearAll will remove all the stored key-value pairs in this store.
14121 clearAll: function() {
14122 this.storage.clearAll();
14124 // additional functionality that can't live in plugins
14125 // ---------------------------------------------------
14126 // hasNamespace returns true if this store instance has the given namespace.
14127 hasNamespace: function(namespace) {
14128 return this._namespacePrefix == "__storejs_" + namespace + "_";
14130 // createStore creates a store.js instance with the first
14131 // functioning storage in the list of storage candidates,
14132 // and applies the the given mixins to the instance.
14133 createStore: function() {
14134 return createStore.apply(this, arguments);
14136 addPlugin: function(plugin) {
14137 this._addPlugin(plugin);
14139 namespace: function(namespace) {
14140 return createStore(this.storage, this.plugins, namespace);
14144 var _console = typeof console == "undefined" ? null : console;
14148 var fn = _console.warn ? _console.warn : _console.log;
14149 fn.apply(_console, arguments);
14151 function createStore(storages, plugins, namespace) {
14155 if (storages && !isList(storages)) {
14156 storages = [storages];
14158 if (plugins && !isList(plugins)) {
14159 plugins = [plugins];
14161 var namespacePrefix = namespace ? "__storejs_" + namespace + "_" : "";
14162 var namespaceRegexp = namespace ? new RegExp("^" + namespacePrefix) : null;
14163 var legalNamespaces = /^[a-zA-Z0-9_\-]*$/;
14164 if (!legalNamespaces.test(namespace)) {
14165 throw new Error("store.js namespaces can only have alphanumerics + underscores and dashes");
14167 var _privateStoreProps = {
14168 _namespacePrefix: namespacePrefix,
14169 _namespaceRegexp: namespaceRegexp,
14170 _testStorage: function(storage) {
14172 var testStr = "__storejs__test__";
14173 storage.write(testStr, testStr);
14174 var ok = storage.read(testStr) === testStr;
14175 storage.remove(testStr);
14181 _assignPluginFnProp: function(pluginFnProp, propName) {
14182 var oldFn = this[propName];
14183 this[propName] = function pluginFn() {
14184 var args = slice(arguments, 0);
14186 function super_fn() {
14190 each(arguments, function(arg, i2) {
14193 return oldFn.apply(self2, args);
14195 var newFnArgs = [super_fn].concat(args);
14196 return pluginFnProp.apply(self2, newFnArgs);
14199 _serialize: function(obj) {
14200 return JSON.stringify(obj);
14202 _deserialize: function(strVal, defaultVal) {
14208 val = JSON.parse(strVal);
14212 return val !== void 0 ? val : defaultVal;
14214 _addStorage: function(storage) {
14215 if (this.enabled) {
14218 if (this._testStorage(storage)) {
14219 this.storage = storage;
14220 this.enabled = true;
14223 _addPlugin: function(plugin) {
14225 if (isList(plugin)) {
14226 each(plugin, function(plugin2) {
14227 self2._addPlugin(plugin2);
14231 var seenPlugin = pluck(this.plugins, function(seenPlugin2) {
14232 return plugin === seenPlugin2;
14237 this.plugins.push(plugin);
14238 if (!isFunction(plugin)) {
14239 throw new Error("Plugins must be function values that return objects");
14241 var pluginProperties = plugin.call(this);
14242 if (!isObject3(pluginProperties)) {
14243 throw new Error("Plugins must return an object of function properties");
14245 each(pluginProperties, function(pluginFnProp, propName) {
14246 if (!isFunction(pluginFnProp)) {
14247 throw new Error("Bad plugin property: " + propName + " from plugin " + plugin.name + ". Plugins should only return functions.");
14249 self2._assignPluginFnProp(pluginFnProp, propName);
14252 // Put deprecated properties in the private API, so as to not expose it to accidential
14253 // discovery through inspection of the store object.
14254 // Deprecated: addStorage
14255 addStorage: function(storage) {
14256 _warn("store.addStorage(storage) is deprecated. Use createStore([storages])");
14257 this._addStorage(storage);
14260 var store2 = create2(_privateStoreProps, storeAPI, {
14264 each(store2, function(prop, propName) {
14265 if (isFunction(prop)) {
14266 store2.raw[propName] = bind(store2, prop);
14269 each(storages, function(storage) {
14270 store2._addStorage(storage);
14272 each(plugins, function(plugin) {
14273 store2._addPlugin(plugin);
14280 // node_modules/store/storages/localStorage.js
14281 var require_localStorage = __commonJS({
14282 "node_modules/store/storages/localStorage.js"(exports2, module2) {
14283 var util = require_util();
14284 var Global = util.Global;
14285 module2.exports = {
14286 name: "localStorage",
14293 function localStorage2() {
14294 return Global.localStorage;
14296 function read(key) {
14297 return localStorage2().getItem(key);
14299 function write(key, data) {
14300 return localStorage2().setItem(key, data);
14302 function each(fn) {
14303 for (var i2 = localStorage2().length - 1; i2 >= 0; i2--) {
14304 var key = localStorage2().key(i2);
14305 fn(read(key), key);
14308 function remove2(key) {
14309 return localStorage2().removeItem(key);
14311 function clearAll() {
14312 return localStorage2().clear();
14317 // node_modules/store/storages/oldFF-globalStorage.js
14318 var require_oldFF_globalStorage = __commonJS({
14319 "node_modules/store/storages/oldFF-globalStorage.js"(exports2, module2) {
14320 var util = require_util();
14321 var Global = util.Global;
14322 module2.exports = {
14323 name: "oldFF-globalStorage",
14330 var globalStorage = Global.globalStorage;
14331 function read(key) {
14332 return globalStorage[key];
14334 function write(key, data) {
14335 globalStorage[key] = data;
14337 function each(fn) {
14338 for (var i2 = globalStorage.length - 1; i2 >= 0; i2--) {
14339 var key = globalStorage.key(i2);
14340 fn(globalStorage[key], key);
14343 function remove2(key) {
14344 return globalStorage.removeItem(key);
14346 function clearAll() {
14347 each(function(key, _) {
14348 delete globalStorage[key];
14354 // node_modules/store/storages/oldIE-userDataStorage.js
14355 var require_oldIE_userDataStorage = __commonJS({
14356 "node_modules/store/storages/oldIE-userDataStorage.js"(exports2, module2) {
14357 var util = require_util();
14358 var Global = util.Global;
14359 module2.exports = {
14360 name: "oldIE-userDataStorage",
14367 var storageName = "storejs";
14368 var doc = Global.document;
14369 var _withStorageEl = _makeIEStorageElFunction();
14370 var disable = (Global.navigator ? Global.navigator.userAgent : "").match(/ (MSIE 8|MSIE 9|MSIE 10)\./);
14371 function write(unfixedKey, data) {
14375 var fixedKey = fixKey(unfixedKey);
14376 _withStorageEl(function(storageEl) {
14377 storageEl.setAttribute(fixedKey, data);
14378 storageEl.save(storageName);
14381 function read(unfixedKey) {
14385 var fixedKey = fixKey(unfixedKey);
14387 _withStorageEl(function(storageEl) {
14388 res = storageEl.getAttribute(fixedKey);
14392 function each(callback) {
14393 _withStorageEl(function(storageEl) {
14394 var attributes = storageEl.XMLDocument.documentElement.attributes;
14395 for (var i2 = attributes.length - 1; i2 >= 0; i2--) {
14396 var attr = attributes[i2];
14397 callback(storageEl.getAttribute(attr.name), attr.name);
14401 function remove2(unfixedKey) {
14402 var fixedKey = fixKey(unfixedKey);
14403 _withStorageEl(function(storageEl) {
14404 storageEl.removeAttribute(fixedKey);
14405 storageEl.save(storageName);
14408 function clearAll() {
14409 _withStorageEl(function(storageEl) {
14410 var attributes = storageEl.XMLDocument.documentElement.attributes;
14411 storageEl.load(storageName);
14412 for (var i2 = attributes.length - 1; i2 >= 0; i2--) {
14413 storageEl.removeAttribute(attributes[i2].name);
14415 storageEl.save(storageName);
14418 var forbiddenCharsRegex = new RegExp("[!\"#$%&'()*+,/\\\\:;<=>?@[\\]^`{|}~]", "g");
14419 function fixKey(key) {
14420 return key.replace(/^\d/, "___$&").replace(forbiddenCharsRegex, "___");
14422 function _makeIEStorageElFunction() {
14423 if (!doc || !doc.documentElement || !doc.documentElement.addBehavior) {
14426 var scriptTag = "script", storageOwner, storageContainer, storageEl;
14428 storageContainer = new ActiveXObject("htmlfile");
14429 storageContainer.open();
14430 storageContainer.write("<" + scriptTag + ">document.w=window</" + scriptTag + '><iframe src="/favicon.ico"></iframe>');
14431 storageContainer.close();
14432 storageOwner = storageContainer.w.frames[0].document;
14433 storageEl = storageOwner.createElement("div");
14435 storageEl = doc.createElement("div");
14436 storageOwner = doc.body;
14438 return function(storeFunction) {
14439 var args = [].slice.call(arguments, 0);
14440 args.unshift(storageEl);
14441 storageOwner.appendChild(storageEl);
14442 storageEl.addBehavior("#default#userData");
14443 storageEl.load(storageName);
14444 storeFunction.apply(this, args);
14445 storageOwner.removeChild(storageEl);
14452 // node_modules/store/storages/cookieStorage.js
14453 var require_cookieStorage = __commonJS({
14454 "node_modules/store/storages/cookieStorage.js"(exports2, module2) {
14455 var util = require_util();
14456 var Global = util.Global;
14457 var trim = util.trim;
14458 module2.exports = {
14459 name: "cookieStorage",
14466 var doc = Global.document;
14467 function read(key) {
14468 if (!key || !_has(key)) {
14471 var regexpStr = "(?:^|.*;\\s*)" + escape(key).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*((?:[^;](?!;))*[^;]?).*";
14472 return unescape(doc.cookie.replace(new RegExp(regexpStr), "$1"));
14474 function each(callback) {
14475 var cookies = doc.cookie.split(/; ?/g);
14476 for (var i2 = cookies.length - 1; i2 >= 0; i2--) {
14477 if (!trim(cookies[i2])) {
14480 var kvp = cookies[i2].split("=");
14481 var key = unescape(kvp[0]);
14482 var val = unescape(kvp[1]);
14483 callback(val, key);
14486 function write(key, data) {
14490 doc.cookie = escape(key) + "=" + escape(data) + "; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/";
14492 function remove2(key) {
14493 if (!key || !_has(key)) {
14496 doc.cookie = escape(key) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/";
14498 function clearAll() {
14499 each(function(_, key) {
14503 function _has(key) {
14504 return new RegExp("(?:^|;\\s*)" + escape(key).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=").test(doc.cookie);
14509 // node_modules/store/storages/sessionStorage.js
14510 var require_sessionStorage = __commonJS({
14511 "node_modules/store/storages/sessionStorage.js"(exports2, module2) {
14512 var util = require_util();
14513 var Global = util.Global;
14514 module2.exports = {
14515 name: "sessionStorage",
14522 function sessionStorage() {
14523 return Global.sessionStorage;
14525 function read(key) {
14526 return sessionStorage().getItem(key);
14528 function write(key, data) {
14529 return sessionStorage().setItem(key, data);
14531 function each(fn) {
14532 for (var i2 = sessionStorage().length - 1; i2 >= 0; i2--) {
14533 var key = sessionStorage().key(i2);
14534 fn(read(key), key);
14537 function remove2(key) {
14538 return sessionStorage().removeItem(key);
14540 function clearAll() {
14541 return sessionStorage().clear();
14546 // node_modules/store/storages/memoryStorage.js
14547 var require_memoryStorage = __commonJS({
14548 "node_modules/store/storages/memoryStorage.js"(exports2, module2) {
14549 module2.exports = {
14550 name: "memoryStorage",
14557 var memoryStorage = {};
14558 function read(key) {
14559 return memoryStorage[key];
14561 function write(key, data) {
14562 memoryStorage[key] = data;
14564 function each(callback) {
14565 for (var key in memoryStorage) {
14566 if (memoryStorage.hasOwnProperty(key)) {
14567 callback(memoryStorage[key], key);
14571 function remove2(key) {
14572 delete memoryStorage[key];
14574 function clearAll(key) {
14575 memoryStorage = {};
14580 // node_modules/store/storages/all.js
14581 var require_all = __commonJS({
14582 "node_modules/store/storages/all.js"(exports2, module2) {
14583 module2.exports = [
14584 // Listed in order of usage preference
14585 require_localStorage(),
14586 require_oldFF_globalStorage(),
14587 require_oldIE_userDataStorage(),
14588 require_cookieStorage(),
14589 require_sessionStorage(),
14590 require_memoryStorage()
14595 // node_modules/store/plugins/lib/json2.js
14596 var require_json2 = __commonJS({
14597 "node_modules/store/plugins/lib/json2.js"(exports, module) {
14598 if (typeof JSON !== "object") {
14603 var rx_one = /^[\],:{}\s]*$/;
14604 var rx_two = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g;
14605 var rx_three = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g;
14606 var rx_four = /(?:^|:|,)(?:\s*\[)+/g;
14607 var rx_escapable = /[\\"\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
14608 var rx_dangerous = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
14610 return n2 < 10 ? "0" + n2 : n2;
14612 function this_value() {
14613 return this.valueOf();
14615 if (typeof Date.prototype.toJSON !== "function") {
14616 Date.prototype.toJSON = function() {
14617 return isFinite(this.valueOf()) ? this.getUTCFullYear() + "-" + f(this.getUTCMonth() + 1) + "-" + f(this.getUTCDate()) + "T" + f(this.getUTCHours()) + ":" + f(this.getUTCMinutes()) + ":" + f(this.getUTCSeconds()) + "Z" : null;
14619 Boolean.prototype.toJSON = this_value;
14620 Number.prototype.toJSON = this_value;
14621 String.prototype.toJSON = this_value;
14627 function quote(string) {
14628 rx_escapable.lastIndex = 0;
14629 return rx_escapable.test(string) ? '"' + string.replace(rx_escapable, function(a) {
14631 return typeof c === "string" ? c : "\\u" + ("0000" + a.charCodeAt(0).toString(16)).slice(-4);
14632 }) + '"' : '"' + string + '"';
14634 function str(key, holder) {
14641 var value = holder[key];
14642 if (value && typeof value === "object" && typeof value.toJSON === "function") {
14643 value = value.toJSON(key);
14645 if (typeof rep === "function") {
14646 value = rep.call(holder, key, value);
14648 switch (typeof value) {
14650 return quote(value);
14652 return isFinite(value) ? String(value) : "null";
14655 return String(value);
14662 if (Object.prototype.toString.apply(value) === "[object Array]") {
14663 length = value.length;
14664 for (i2 = 0; i2 < length; i2 += 1) {
14665 partial[i2] = str(i2, value) || "null";
14667 v = partial.length === 0 ? "[]" : gap ? "[\n" + gap + partial.join(",\n" + gap) + "\n" + mind + "]" : "[" + partial.join(",") + "]";
14671 if (rep && typeof rep === "object") {
14672 length = rep.length;
14673 for (i2 = 0; i2 < length; i2 += 1) {
14674 if (typeof rep[i2] === "string") {
14678 partial.push(quote(k) + (gap ? ": " : ":") + v);
14684 if (Object.prototype.hasOwnProperty.call(value, k)) {
14687 partial.push(quote(k) + (gap ? ": " : ":") + v);
14692 v = partial.length === 0 ? "{}" : gap ? "{\n" + gap + partial.join(",\n" + gap) + "\n" + mind + "}" : "{" + partial.join(",") + "}";
14697 if (typeof JSON.stringify !== "function") {
14699 // table of character substitutions
14708 JSON.stringify = function(value, replacer, space) {
14712 if (typeof space === "number") {
14713 for (i2 = 0; i2 < space; i2 += 1) {
14716 } else if (typeof space === "string") {
14720 if (replacer && typeof replacer !== "function" && (typeof replacer !== "object" || typeof replacer.length !== "number")) {
14721 throw new Error("JSON.stringify");
14723 return str("", { "": value });
14726 if (typeof JSON.parse !== "function") {
14727 JSON.parse = function(text, reviver) {
14729 function walk(holder, key) {
14732 var value = holder[key];
14733 if (value && typeof value === "object") {
14735 if (Object.prototype.hasOwnProperty.call(value, k)) {
14736 v = walk(value, k);
14737 if (v !== void 0) {
14745 return reviver.call(holder, key, value);
14747 text = String(text);
14748 rx_dangerous.lastIndex = 0;
14749 if (rx_dangerous.test(text)) {
14750 text = text.replace(rx_dangerous, function(a) {
14751 return "\\u" + ("0000" + a.charCodeAt(0).toString(16)).slice(-4);
14755 text.replace(rx_two, "@").replace(rx_three, "]").replace(rx_four, "")
14757 j = eval("(" + text + ")");
14758 return typeof reviver === "function" ? walk({ "": j }, "") : j;
14760 throw new SyntaxError("JSON.parse");
14767 // node_modules/store/plugins/json2.js
14768 var require_json22 = __commonJS({
14769 "node_modules/store/plugins/json2.js"(exports2, module2) {
14770 module2.exports = json2Plugin;
14771 function json2Plugin() {
14778 // node_modules/store/dist/store.legacy.js
14779 var require_store_legacy = __commonJS({
14780 "node_modules/store/dist/store.legacy.js"(exports2, module2) {
14781 var engine = require_store_engine();
14782 var storages = require_all();
14783 var plugins = [require_json22()];
14784 module2.exports = engine.createStore(storages, plugins);
14788 // node_modules/whatwg-fetch/fetch.js
14789 var global2 = typeof globalThis !== "undefined" && globalThis || typeof self !== "undefined" && self || typeof global2 !== "undefined" && global2;
14791 searchParams: "URLSearchParams" in global2,
14792 iterable: "Symbol" in global2 && "iterator" in Symbol,
14793 blob: "FileReader" in global2 && "Blob" in global2 && function() {
14801 formData: "FormData" in global2,
14802 arrayBuffer: "ArrayBuffer" in global2
14804 function isDataView(obj) {
14805 return obj && DataView.prototype.isPrototypeOf(obj);
14807 if (support.arrayBuffer) {
14809 "[object Int8Array]",
14810 "[object Uint8Array]",
14811 "[object Uint8ClampedArray]",
14812 "[object Int16Array]",
14813 "[object Uint16Array]",
14814 "[object Int32Array]",
14815 "[object Uint32Array]",
14816 "[object Float32Array]",
14817 "[object Float64Array]"
14819 isArrayBufferView = ArrayBuffer.isView || function(obj) {
14820 return obj && viewClasses.indexOf(Object.prototype.toString.call(obj)) > -1;
14824 var isArrayBufferView;
14825 function normalizeName(name) {
14826 if (typeof name !== "string") {
14827 name = String(name);
14829 if (/[^a-z0-9\-#$%&'*+.^_`|~!]/i.test(name) || name === "") {
14830 throw new TypeError('Invalid character in header field name: "' + name + '"');
14832 return name.toLowerCase();
14834 function normalizeValue(value) {
14835 if (typeof value !== "string") {
14836 value = String(value);
14840 function iteratorFor(items) {
14843 var value = items.shift();
14844 return { done: value === void 0, value };
14847 if (support.iterable) {
14848 iterator[Symbol.iterator] = function() {
14854 function Headers(headers) {
14856 if (headers instanceof Headers) {
14857 headers.forEach(function(value, name) {
14858 this.append(name, value);
14860 } else if (Array.isArray(headers)) {
14861 headers.forEach(function(header) {
14862 this.append(header[0], header[1]);
14864 } else if (headers) {
14865 Object.getOwnPropertyNames(headers).forEach(function(name) {
14866 this.append(name, headers[name]);
14870 Headers.prototype.append = function(name, value) {
14871 name = normalizeName(name);
14872 value = normalizeValue(value);
14873 var oldValue = this.map[name];
14874 this.map[name] = oldValue ? oldValue + ", " + value : value;
14876 Headers.prototype["delete"] = function(name) {
14877 delete this.map[normalizeName(name)];
14879 Headers.prototype.get = function(name) {
14880 name = normalizeName(name);
14881 return this.has(name) ? this.map[name] : null;
14883 Headers.prototype.has = function(name) {
14884 return this.map.hasOwnProperty(normalizeName(name));
14886 Headers.prototype.set = function(name, value) {
14887 this.map[normalizeName(name)] = normalizeValue(value);
14889 Headers.prototype.forEach = function(callback, thisArg) {
14890 for (var name in this.map) {
14891 if (this.map.hasOwnProperty(name)) {
14892 callback.call(thisArg, this.map[name], name, this);
14896 Headers.prototype.keys = function() {
14898 this.forEach(function(value, name) {
14901 return iteratorFor(items);
14903 Headers.prototype.values = function() {
14905 this.forEach(function(value) {
14908 return iteratorFor(items);
14910 Headers.prototype.entries = function() {
14912 this.forEach(function(value, name) {
14913 items.push([name, value]);
14915 return iteratorFor(items);
14917 if (support.iterable) {
14918 Headers.prototype[Symbol.iterator] = Headers.prototype.entries;
14920 function consumed(body) {
14921 if (body.bodyUsed) {
14922 return Promise.reject(new TypeError("Already read"));
14924 body.bodyUsed = true;
14926 function fileReaderReady(reader) {
14927 return new Promise(function(resolve, reject) {
14928 reader.onload = function() {
14929 resolve(reader.result);
14931 reader.onerror = function() {
14932 reject(reader.error);
14936 function readBlobAsArrayBuffer(blob) {
14937 var reader = new FileReader();
14938 var promise = fileReaderReady(reader);
14939 reader.readAsArrayBuffer(blob);
14942 function readBlobAsText(blob) {
14943 var reader = new FileReader();
14944 var promise = fileReaderReady(reader);
14945 reader.readAsText(blob);
14948 function readArrayBufferAsText(buf) {
14949 var view = new Uint8Array(buf);
14950 var chars = new Array(view.length);
14951 for (var i2 = 0; i2 < view.length; i2++) {
14952 chars[i2] = String.fromCharCode(view[i2]);
14954 return chars.join("");
14956 function bufferClone(buf) {
14958 return buf.slice(0);
14960 var view = new Uint8Array(buf.byteLength);
14961 view.set(new Uint8Array(buf));
14962 return view.buffer;
14966 this.bodyUsed = false;
14967 this._initBody = function(body) {
14968 this.bodyUsed = this.bodyUsed;
14969 this._bodyInit = body;
14971 this._bodyText = "";
14972 } else if (typeof body === "string") {
14973 this._bodyText = body;
14974 } else if (support.blob && Blob.prototype.isPrototypeOf(body)) {
14975 this._bodyBlob = body;
14976 } else if (support.formData && FormData.prototype.isPrototypeOf(body)) {
14977 this._bodyFormData = body;
14978 } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {
14979 this._bodyText = body.toString();
14980 } else if (support.arrayBuffer && support.blob && isDataView(body)) {
14981 this._bodyArrayBuffer = bufferClone(body.buffer);
14982 this._bodyInit = new Blob([this._bodyArrayBuffer]);
14983 } else if (support.arrayBuffer && (ArrayBuffer.prototype.isPrototypeOf(body) || isArrayBufferView(body))) {
14984 this._bodyArrayBuffer = bufferClone(body);
14986 this._bodyText = body = Object.prototype.toString.call(body);
14988 if (!this.headers.get("content-type")) {
14989 if (typeof body === "string") {
14990 this.headers.set("content-type", "text/plain;charset=UTF-8");
14991 } else if (this._bodyBlob && this._bodyBlob.type) {
14992 this.headers.set("content-type", this._bodyBlob.type);
14993 } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {
14994 this.headers.set("content-type", "application/x-www-form-urlencoded;charset=UTF-8");
14998 if (support.blob) {
14999 this.blob = function() {
15000 var rejected = consumed(this);
15004 if (this._bodyBlob) {
15005 return Promise.resolve(this._bodyBlob);
15006 } else if (this._bodyArrayBuffer) {
15007 return Promise.resolve(new Blob([this._bodyArrayBuffer]));
15008 } else if (this._bodyFormData) {
15009 throw new Error("could not read FormData body as blob");
15011 return Promise.resolve(new Blob([this._bodyText]));
15014 this.arrayBuffer = function() {
15015 if (this._bodyArrayBuffer) {
15016 var isConsumed = consumed(this);
15020 if (ArrayBuffer.isView(this._bodyArrayBuffer)) {
15021 return Promise.resolve(
15022 this._bodyArrayBuffer.buffer.slice(
15023 this._bodyArrayBuffer.byteOffset,
15024 this._bodyArrayBuffer.byteOffset + this._bodyArrayBuffer.byteLength
15028 return Promise.resolve(this._bodyArrayBuffer);
15031 return this.blob().then(readBlobAsArrayBuffer);
15035 this.text = function() {
15036 var rejected = consumed(this);
15040 if (this._bodyBlob) {
15041 return readBlobAsText(this._bodyBlob);
15042 } else if (this._bodyArrayBuffer) {
15043 return Promise.resolve(readArrayBufferAsText(this._bodyArrayBuffer));
15044 } else if (this._bodyFormData) {
15045 throw new Error("could not read FormData body as text");
15047 return Promise.resolve(this._bodyText);
15050 if (support.formData) {
15051 this.formData = function() {
15052 return this.text().then(decode);
15055 this.json = function() {
15056 return this.text().then(JSON.parse);
15060 var methods = ["DELETE", "GET", "HEAD", "OPTIONS", "POST", "PUT"];
15061 function normalizeMethod(method) {
15062 var upcased = method.toUpperCase();
15063 return methods.indexOf(upcased) > -1 ? upcased : method;
15065 function Request(input, options2) {
15066 if (!(this instanceof Request)) {
15067 throw new TypeError('Please use the "new" operator, this DOM object constructor cannot be called as a function.');
15069 options2 = options2 || {};
15070 var body = options2.body;
15071 if (input instanceof Request) {
15072 if (input.bodyUsed) {
15073 throw new TypeError("Already read");
15075 this.url = input.url;
15076 this.credentials = input.credentials;
15077 if (!options2.headers) {
15078 this.headers = new Headers(input.headers);
15080 this.method = input.method;
15081 this.mode = input.mode;
15082 this.signal = input.signal;
15083 if (!body && input._bodyInit != null) {
15084 body = input._bodyInit;
15085 input.bodyUsed = true;
15088 this.url = String(input);
15090 this.credentials = options2.credentials || this.credentials || "same-origin";
15091 if (options2.headers || !this.headers) {
15092 this.headers = new Headers(options2.headers);
15094 this.method = normalizeMethod(options2.method || this.method || "GET");
15095 this.mode = options2.mode || this.mode || null;
15096 this.signal = options2.signal || this.signal;
15097 this.referrer = null;
15098 if ((this.method === "GET" || this.method === "HEAD") && body) {
15099 throw new TypeError("Body not allowed for GET or HEAD requests");
15101 this._initBody(body);
15102 if (this.method === "GET" || this.method === "HEAD") {
15103 if (options2.cache === "no-store" || options2.cache === "no-cache") {
15104 var reParamSearch = /([?&])_=[^&]*/;
15105 if (reParamSearch.test(this.url)) {
15106 this.url = this.url.replace(reParamSearch, "$1_=" + (/* @__PURE__ */ new Date()).getTime());
15108 var reQueryString = /\?/;
15109 this.url += (reQueryString.test(this.url) ? "&" : "?") + "_=" + (/* @__PURE__ */ new Date()).getTime();
15114 Request.prototype.clone = function() {
15115 return new Request(this, { body: this._bodyInit });
15117 function decode(body) {
15118 var form = new FormData();
15119 body.trim().split("&").forEach(function(bytes) {
15121 var split = bytes.split("=");
15122 var name = split.shift().replace(/\+/g, " ");
15123 var value = split.join("=").replace(/\+/g, " ");
15124 form.append(decodeURIComponent(name), decodeURIComponent(value));
15129 function parseHeaders(rawHeaders) {
15130 var headers = new Headers();
15131 var preProcessedHeaders = rawHeaders.replace(/\r?\n[\t ]+/g, " ");
15132 preProcessedHeaders.split("\r").map(function(header) {
15133 return header.indexOf("\n") === 0 ? header.substr(1, header.length) : header;
15134 }).forEach(function(line) {
15135 var parts = line.split(":");
15136 var key = parts.shift().trim();
15138 var value = parts.join(":").trim();
15139 headers.append(key, value);
15144 Body.call(Request.prototype);
15145 function Response(bodyInit, options2) {
15146 if (!(this instanceof Response)) {
15147 throw new TypeError('Please use the "new" operator, this DOM object constructor cannot be called as a function.');
15152 this.type = "default";
15153 this.status = options2.status === void 0 ? 200 : options2.status;
15154 this.ok = this.status >= 200 && this.status < 300;
15155 this.statusText = options2.statusText === void 0 ? "" : "" + options2.statusText;
15156 this.headers = new Headers(options2.headers);
15157 this.url = options2.url || "";
15158 this._initBody(bodyInit);
15160 Body.call(Response.prototype);
15161 Response.prototype.clone = function() {
15162 return new Response(this._bodyInit, {
15163 status: this.status,
15164 statusText: this.statusText,
15165 headers: new Headers(this.headers),
15169 Response.error = function() {
15170 var response = new Response(null, { status: 0, statusText: "" });
15171 response.type = "error";
15174 var redirectStatuses = [301, 302, 303, 307, 308];
15175 Response.redirect = function(url, status) {
15176 if (redirectStatuses.indexOf(status) === -1) {
15177 throw new RangeError("Invalid status code");
15179 return new Response(null, { status, headers: { location: url } });
15181 var DOMException2 = global2.DOMException;
15183 new DOMException2();
15185 DOMException2 = function(message, name) {
15186 this.message = message;
15188 var error = Error(message);
15189 this.stack = error.stack;
15191 DOMException2.prototype = Object.create(Error.prototype);
15192 DOMException2.prototype.constructor = DOMException2;
15194 function fetch2(input, init2) {
15195 return new Promise(function(resolve, reject) {
15196 var request3 = new Request(input, init2);
15197 if (request3.signal && request3.signal.aborted) {
15198 return reject(new DOMException2("Aborted", "AbortError"));
15200 var xhr = new XMLHttpRequest();
15201 function abortXhr() {
15204 xhr.onload = function() {
15206 status: xhr.status,
15207 statusText: xhr.statusText,
15208 headers: parseHeaders(xhr.getAllResponseHeaders() || "")
15210 options2.url = "responseURL" in xhr ? xhr.responseURL : options2.headers.get("X-Request-URL");
15211 var body = "response" in xhr ? xhr.response : xhr.responseText;
15212 setTimeout(function() {
15213 resolve(new Response(body, options2));
15216 xhr.onerror = function() {
15217 setTimeout(function() {
15218 reject(new TypeError("Network request failed"));
15221 xhr.ontimeout = function() {
15222 setTimeout(function() {
15223 reject(new TypeError("Network request failed"));
15226 xhr.onabort = function() {
15227 setTimeout(function() {
15228 reject(new DOMException2("Aborted", "AbortError"));
15231 function fixUrl(url) {
15233 return url === "" && global2.location.href ? global2.location.href : url;
15238 xhr.open(request3.method, fixUrl(request3.url), true);
15239 if (request3.credentials === "include") {
15240 xhr.withCredentials = true;
15241 } else if (request3.credentials === "omit") {
15242 xhr.withCredentials = false;
15244 if ("responseType" in xhr) {
15245 if (support.blob) {
15246 xhr.responseType = "blob";
15247 } else if (support.arrayBuffer && request3.headers.get("Content-Type") && request3.headers.get("Content-Type").indexOf("application/octet-stream") !== -1) {
15248 xhr.responseType = "arraybuffer";
15251 if (init2 && typeof init2.headers === "object" && !(init2.headers instanceof Headers)) {
15252 Object.getOwnPropertyNames(init2.headers).forEach(function(name) {
15253 xhr.setRequestHeader(name, normalizeValue(init2.headers[name]));
15256 request3.headers.forEach(function(value, name) {
15257 xhr.setRequestHeader(name, value);
15260 if (request3.signal) {
15261 request3.signal.addEventListener("abort", abortXhr);
15262 xhr.onreadystatechange = function() {
15263 if (xhr.readyState === 4) {
15264 request3.signal.removeEventListener("abort", abortXhr);
15268 xhr.send(typeof request3._bodyInit === "undefined" ? null : request3._bodyInit);
15271 fetch2.polyfill = true;
15272 if (!global2.fetch) {
15273 global2.fetch = fetch2;
15274 global2.Headers = Headers;
15275 global2.Request = Request;
15276 global2.Response = Response;
15279 // node_modules/abortcontroller-polyfill/dist/polyfill-patch-fetch.js
15280 (function(factory) {
15281 typeof define === "function" && define.amd ? define(factory) : factory();
15284 function _classCallCheck(instance, Constructor) {
15285 if (!(instance instanceof Constructor)) {
15286 throw new TypeError("Cannot call a class as a function");
15289 function _defineProperties(target, props) {
15290 for (var i2 = 0; i2 < props.length; i2++) {
15291 var descriptor = props[i2];
15292 descriptor.enumerable = descriptor.enumerable || false;
15293 descriptor.configurable = true;
15294 if ("value" in descriptor)
15295 descriptor.writable = true;
15296 Object.defineProperty(target, descriptor.key, descriptor);
15299 function _createClass(Constructor, protoProps, staticProps) {
15301 _defineProperties(Constructor.prototype, protoProps);
15303 _defineProperties(Constructor, staticProps);
15304 return Constructor;
15306 function _inherits(subClass, superClass) {
15307 if (typeof superClass !== "function" && superClass !== null) {
15308 throw new TypeError("Super expression must either be null or a function");
15310 subClass.prototype = Object.create(superClass && superClass.prototype, {
15318 _setPrototypeOf(subClass, superClass);
15320 function _getPrototypeOf(o) {
15321 _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf2(o2) {
15322 return o2.__proto__ || Object.getPrototypeOf(o2);
15324 return _getPrototypeOf(o);
15326 function _setPrototypeOf(o, p) {
15327 _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf2(o2, p2) {
15331 return _setPrototypeOf(o, p);
15333 function _isNativeReflectConstruct() {
15334 if (typeof Reflect === "undefined" || !Reflect.construct)
15336 if (Reflect.construct.sham)
15338 if (typeof Proxy === "function")
15341 Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function() {
15348 function _assertThisInitialized(self2) {
15349 if (self2 === void 0) {
15350 throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
15354 function _possibleConstructorReturn(self2, call) {
15355 if (call && (typeof call === "object" || typeof call === "function")) {
15358 return _assertThisInitialized(self2);
15360 function _createSuper(Derived) {
15361 var hasNativeReflectConstruct = _isNativeReflectConstruct();
15362 return function _createSuperInternal() {
15363 var Super = _getPrototypeOf(Derived), result;
15364 if (hasNativeReflectConstruct) {
15365 var NewTarget = _getPrototypeOf(this).constructor;
15366 result = Reflect.construct(Super, arguments, NewTarget);
15368 result = Super.apply(this, arguments);
15370 return _possibleConstructorReturn(this, result);
15373 function _superPropBase(object, property) {
15374 while (!Object.prototype.hasOwnProperty.call(object, property)) {
15375 object = _getPrototypeOf(object);
15376 if (object === null)
15381 function _get(target, property, receiver) {
15382 if (typeof Reflect !== "undefined" && Reflect.get) {
15383 _get = Reflect.get;
15385 _get = function _get2(target2, property2, receiver2) {
15386 var base = _superPropBase(target2, property2);
15389 var desc = Object.getOwnPropertyDescriptor(base, property2);
15391 return desc.get.call(receiver2);
15396 return _get(target, property, receiver || target);
15398 var Emitter = /* @__PURE__ */ function() {
15399 function Emitter2() {
15400 _classCallCheck(this, Emitter2);
15401 Object.defineProperty(this, "listeners", {
15407 _createClass(Emitter2, [{
15408 key: "addEventListener",
15409 value: function addEventListener(type2, callback, options2) {
15410 if (!(type2 in this.listeners)) {
15411 this.listeners[type2] = [];
15413 this.listeners[type2].push({
15419 key: "removeEventListener",
15420 value: function removeEventListener(type2, callback) {
15421 if (!(type2 in this.listeners)) {
15424 var stack = this.listeners[type2];
15425 for (var i2 = 0, l = stack.length; i2 < l; i2++) {
15426 if (stack[i2].callback === callback) {
15427 stack.splice(i2, 1);
15433 key: "dispatchEvent",
15434 value: function dispatchEvent2(event) {
15435 if (!(event.type in this.listeners)) {
15438 var stack = this.listeners[event.type];
15439 var stackToCall = stack.slice();
15440 for (var i2 = 0, l = stackToCall.length; i2 < l; i2++) {
15441 var listener = stackToCall[i2];
15443 listener.callback.call(this, event);
15445 Promise.resolve().then(function() {
15449 if (listener.options && listener.options.once) {
15450 this.removeEventListener(event.type, listener.callback);
15453 return !event.defaultPrevented;
15458 var AbortSignal = /* @__PURE__ */ function(_Emitter) {
15459 _inherits(AbortSignal2, _Emitter);
15460 var _super = _createSuper(AbortSignal2);
15461 function AbortSignal2() {
15463 _classCallCheck(this, AbortSignal2);
15464 _this = _super.call(this);
15465 if (!_this.listeners) {
15466 Emitter.call(_assertThisInitialized(_this));
15468 Object.defineProperty(_assertThisInitialized(_this), "aborted", {
15473 Object.defineProperty(_assertThisInitialized(_this), "onabort", {
15480 _createClass(AbortSignal2, [{
15482 value: function toString2() {
15483 return "[object AbortSignal]";
15486 key: "dispatchEvent",
15487 value: function dispatchEvent2(event) {
15488 if (event.type === "abort") {
15489 this.aborted = true;
15490 if (typeof this.onabort === "function") {
15491 this.onabort.call(this, event);
15494 _get(_getPrototypeOf(AbortSignal2.prototype), "dispatchEvent", this).call(this, event);
15497 return AbortSignal2;
15499 var AbortController2 = /* @__PURE__ */ function() {
15500 function AbortController3() {
15501 _classCallCheck(this, AbortController3);
15502 Object.defineProperty(this, "signal", {
15503 value: new AbortSignal(),
15508 _createClass(AbortController3, [{
15510 value: function abort() {
15513 event = new Event("abort");
15515 if (typeof document !== "undefined") {
15516 if (!document.createEvent) {
15517 event = document.createEventObject();
15518 event.type = "abort";
15520 event = document.createEvent("Event");
15521 event.initEvent("abort", false, false);
15531 this.signal.dispatchEvent(event);
15535 value: function toString2() {
15536 return "[object AbortController]";
15539 return AbortController3;
15541 if (typeof Symbol !== "undefined" && Symbol.toStringTag) {
15542 AbortController2.prototype[Symbol.toStringTag] = "AbortController";
15543 AbortSignal.prototype[Symbol.toStringTag] = "AbortSignal";
15545 function polyfillNeeded(self2) {
15546 if (self2.__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL) {
15547 console.log("__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL=true is set, will force install polyfill");
15550 return typeof self2.Request === "function" && !self2.Request.prototype.hasOwnProperty("signal") || !self2.AbortController;
15552 function abortableFetchDecorator(patchTargets) {
15553 if ("function" === typeof patchTargets) {
15555 fetch: patchTargets
15558 var _patchTargets = patchTargets, fetch3 = _patchTargets.fetch, _patchTargets$Request = _patchTargets.Request, NativeRequest = _patchTargets$Request === void 0 ? fetch3.Request : _patchTargets$Request, NativeAbortController = _patchTargets.AbortController, _patchTargets$__FORCE = _patchTargets.__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL, __FORCE_INSTALL_ABORTCONTROLLER_POLYFILL = _patchTargets$__FORCE === void 0 ? false : _patchTargets$__FORCE;
15559 if (!polyfillNeeded({
15561 Request: NativeRequest,
15562 AbortController: NativeAbortController,
15563 __FORCE_INSTALL_ABORTCONTROLLER_POLYFILL
15570 var Request2 = NativeRequest;
15571 if (Request2 && !Request2.prototype.hasOwnProperty("signal") || __FORCE_INSTALL_ABORTCONTROLLER_POLYFILL) {
15572 Request2 = function Request3(input, init2) {
15574 if (init2 && init2.signal) {
15575 signal = init2.signal;
15576 delete init2.signal;
15578 var request3 = new NativeRequest(input, init2);
15580 Object.defineProperty(request3, "signal", {
15583 configurable: true,
15589 Request2.prototype = NativeRequest.prototype;
15591 var realFetch = fetch3;
15592 var abortableFetch = function abortableFetch2(input, init2) {
15593 var signal = Request2 && Request2.prototype.isPrototypeOf(input) ? input.signal : init2 ? init2.signal : void 0;
15597 abortError = new DOMException("Aborted", "AbortError");
15599 abortError = new Error("Aborted");
15600 abortError.name = "AbortError";
15602 if (signal.aborted) {
15603 return Promise.reject(abortError);
15605 var cancellation = new Promise(function(_, reject) {
15606 signal.addEventListener("abort", function() {
15607 return reject(abortError);
15612 if (init2 && init2.signal) {
15613 delete init2.signal;
15615 return Promise.race([cancellation, realFetch(input, init2)]);
15617 return realFetch(input, init2);
15620 fetch: abortableFetch,
15625 if (!polyfillNeeded(self2)) {
15628 if (!self2.fetch) {
15629 console.warn("fetch() is not available, cannot install abortcontroller-polyfill");
15632 var _abortableFetch = abortableFetchDecorator(self2), fetch3 = _abortableFetch.fetch, Request2 = _abortableFetch.Request;
15633 self2.fetch = fetch3;
15634 self2.Request = Request2;
15635 Object.defineProperty(self2, "AbortController", {
15638 configurable: true,
15639 value: AbortController2
15641 Object.defineProperty(self2, "AbortSignal", {
15644 configurable: true,
15647 })(typeof self !== "undefined" ? self : global);
15650 // modules/index.js
15651 var modules_exports = {};
15652 __export(modules_exports, {
15653 LocationManager: () => LocationManager,
15654 QAItem: () => QAItem,
15655 actionAddEntity: () => actionAddEntity,
15656 actionAddMember: () => actionAddMember,
15657 actionAddMidpoint: () => actionAddMidpoint,
15658 actionAddVertex: () => actionAddVertex,
15659 actionChangeMember: () => actionChangeMember,
15660 actionChangePreset: () => actionChangePreset,
15661 actionChangeTags: () => actionChangeTags,
15662 actionCircularize: () => actionCircularize,
15663 actionConnect: () => actionConnect,
15664 actionCopyEntities: () => actionCopyEntities,
15665 actionDeleteMember: () => actionDeleteMember,
15666 actionDeleteMultiple: () => actionDeleteMultiple,
15667 actionDeleteNode: () => actionDeleteNode,
15668 actionDeleteRelation: () => actionDeleteRelation,
15669 actionDeleteWay: () => actionDeleteWay,
15670 actionDiscardTags: () => actionDiscardTags,
15671 actionDisconnect: () => actionDisconnect,
15672 actionExtract: () => actionExtract,
15673 actionJoin: () => actionJoin,
15674 actionMerge: () => actionMerge,
15675 actionMergeNodes: () => actionMergeNodes,
15676 actionMergePolygon: () => actionMergePolygon,
15677 actionMergeRemoteChanges: () => actionMergeRemoteChanges,
15678 actionMove: () => actionMove,
15679 actionMoveMember: () => actionMoveMember,
15680 actionMoveNode: () => actionMoveNode,
15681 actionNoop: () => actionNoop,
15682 actionOrthogonalize: () => actionOrthogonalize,
15683 actionReflect: () => actionReflect,
15684 actionRestrictTurn: () => actionRestrictTurn,
15685 actionReverse: () => actionReverse,
15686 actionRevert: () => actionRevert,
15687 actionRotate: () => actionRotate,
15688 actionScale: () => actionScale,
15689 actionSplit: () => actionSplit,
15690 actionStraightenNodes: () => actionStraightenNodes,
15691 actionStraightenWay: () => actionStraightenWay,
15692 actionUnrestrictTurn: () => actionUnrestrictTurn,
15693 actionUpgradeTags: () => actionUpgradeTags,
15694 behaviorAddWay: () => behaviorAddWay,
15695 behaviorBreathe: () => behaviorBreathe,
15696 behaviorDrag: () => behaviorDrag,
15697 behaviorDraw: () => behaviorDraw,
15698 behaviorDrawWay: () => behaviorDrawWay,
15699 behaviorEdit: () => behaviorEdit,
15700 behaviorHash: () => behaviorHash,
15701 behaviorHover: () => behaviorHover,
15702 behaviorLasso: () => behaviorLasso,
15703 behaviorOperation: () => behaviorOperation,
15704 behaviorPaste: () => behaviorPaste,
15705 behaviorSelect: () => behaviorSelect,
15706 coreContext: () => coreContext,
15707 coreDifference: () => coreDifference,
15708 coreFileFetcher: () => coreFileFetcher,
15709 coreGraph: () => coreGraph,
15710 coreHistory: () => coreHistory,
15711 coreLocalizer: () => coreLocalizer,
15712 coreTree: () => coreTree,
15713 coreUploader: () => coreUploader,
15714 coreValidator: () => coreValidator,
15716 debug: () => debug,
15717 fileFetcher: () => _mainFileFetcher,
15718 geoAngle: () => geoAngle,
15719 geoChooseEdge: () => geoChooseEdge,
15720 geoEdgeEqual: () => geoEdgeEqual,
15721 geoExtent: () => geoExtent,
15722 geoGetSmallestSurroundingRectangle: () => geoGetSmallestSurroundingRectangle,
15723 geoHasLineIntersections: () => geoHasLineIntersections,
15724 geoHasSelfIntersections: () => geoHasSelfIntersections,
15725 geoLatToMeters: () => geoLatToMeters,
15726 geoLineIntersection: () => geoLineIntersection,
15727 geoLonToMeters: () => geoLonToMeters,
15728 geoMetersToLat: () => geoMetersToLat,
15729 geoMetersToLon: () => geoMetersToLon,
15730 geoMetersToOffset: () => geoMetersToOffset,
15731 geoOffsetToMeters: () => geoOffsetToMeters,
15732 geoOrthoCalcScore: () => geoOrthoCalcScore,
15733 geoOrthoCanOrthogonalize: () => geoOrthoCanOrthogonalize,
15734 geoOrthoMaxOffsetAngle: () => geoOrthoMaxOffsetAngle,
15735 geoOrthoNormalizedDotProduct: () => geoOrthoNormalizedDotProduct,
15736 geoPathHasIntersections: () => geoPathHasIntersections,
15737 geoPathIntersections: () => geoPathIntersections,
15738 geoPathLength: () => geoPathLength,
15739 geoPointInPolygon: () => geoPointInPolygon,
15740 geoPolygonContainsPolygon: () => geoPolygonContainsPolygon,
15741 geoPolygonIntersectsPolygon: () => geoPolygonIntersectsPolygon,
15742 geoRawMercator: () => geoRawMercator,
15743 geoRotate: () => geoRotate,
15744 geoScaleToZoom: () => geoScaleToZoom,
15745 geoSphericalClosestNode: () => geoSphericalClosestNode,
15746 geoSphericalDistance: () => geoSphericalDistance,
15747 geoVecAdd: () => geoVecAdd,
15748 geoVecAngle: () => geoVecAngle,
15749 geoVecCross: () => geoVecCross,
15750 geoVecDot: () => geoVecDot,
15751 geoVecEqual: () => geoVecEqual,
15752 geoVecFloor: () => geoVecFloor,
15753 geoVecInterp: () => geoVecInterp,
15754 geoVecLength: () => geoVecLength,
15755 geoVecLengthSquare: () => geoVecLengthSquare,
15756 geoVecNormalize: () => geoVecNormalize,
15757 geoVecNormalizedDot: () => geoVecNormalizedDot,
15758 geoVecProject: () => geoVecProject,
15759 geoVecScale: () => geoVecScale,
15760 geoVecSubtract: () => geoVecSubtract,
15761 geoViewportEdge: () => geoViewportEdge,
15762 geoZoomToScale: () => geoZoomToScale,
15763 localizer: () => _mainLocalizer,
15764 locationManager: () => _sharedLocationManager,
15765 modeAddArea: () => modeAddArea,
15766 modeAddLine: () => modeAddLine,
15767 modeAddNote: () => modeAddNote,
15768 modeAddPoint: () => modeAddPoint,
15769 modeBrowse: () => modeBrowse,
15770 modeDragNode: () => modeDragNode,
15771 modeDragNote: () => modeDragNote,
15772 modeDrawArea: () => modeDrawArea,
15773 modeDrawLine: () => modeDrawLine,
15774 modeMove: () => modeMove,
15775 modeRotate: () => modeRotate,
15776 modeSave: () => modeSave,
15777 modeSelect: () => modeSelect,
15778 modeSelectData: () => modeSelectData,
15779 modeSelectError: () => modeSelectError,
15780 modeSelectNote: () => modeSelectNote,
15781 operationCircularize: () => operationCircularize,
15782 operationContinue: () => operationContinue,
15783 operationCopy: () => operationCopy,
15784 operationDelete: () => operationDelete,
15785 operationDisconnect: () => operationDisconnect,
15786 operationDowngrade: () => operationDowngrade,
15787 operationExtract: () => operationExtract,
15788 operationMerge: () => operationMerge,
15789 operationMove: () => operationMove,
15790 operationOrthogonalize: () => operationOrthogonalize,
15791 operationPaste: () => operationPaste,
15792 operationReflectLong: () => operationReflectLong,
15793 operationReflectShort: () => operationReflectShort,
15794 operationReverse: () => operationReverse,
15795 operationRotate: () => operationRotate,
15796 operationSplit: () => operationSplit,
15797 operationStraighten: () => operationStraighten,
15798 osmAreaKeys: () => osmAreaKeys,
15799 osmChangeset: () => osmChangeset,
15800 osmEntity: () => osmEntity,
15801 osmFlowingWaterwayTagValues: () => osmFlowingWaterwayTagValues,
15802 osmInferRestriction: () => osmInferRestriction,
15803 osmIntersection: () => osmIntersection,
15804 osmIsInterestingTag: () => osmIsInterestingTag,
15805 osmIsOldMultipolygonOuterMember: () => osmIsOldMultipolygonOuterMember,
15806 osmJoinWays: () => osmJoinWays,
15807 osmLanes: () => osmLanes,
15808 osmLifecyclePrefixes: () => osmLifecyclePrefixes,
15809 osmNode: () => osmNode,
15810 osmNodeGeometriesForTags: () => osmNodeGeometriesForTags,
15811 osmNote: () => osmNote,
15812 osmOldMultipolygonOuterMember: () => osmOldMultipolygonOuterMember,
15813 osmOldMultipolygonOuterMemberOfRelation: () => osmOldMultipolygonOuterMemberOfRelation,
15814 osmOneWayTags: () => osmOneWayTags,
15815 osmPavedTags: () => osmPavedTags,
15816 osmPointTags: () => osmPointTags,
15817 osmRailwayTrackTagValues: () => osmRailwayTrackTagValues,
15818 osmRelation: () => osmRelation,
15819 osmRemoveLifecyclePrefix: () => osmRemoveLifecyclePrefix,
15820 osmRoutableHighwayTagValues: () => osmRoutableHighwayTagValues,
15821 osmSetAreaKeys: () => osmSetAreaKeys,
15822 osmSetPointTags: () => osmSetPointTags,
15823 osmSetVertexTags: () => osmSetVertexTags,
15824 osmTagSuggestingArea: () => osmTagSuggestingArea,
15825 osmTurn: () => osmTurn,
15826 osmVertexTags: () => osmVertexTags,
15827 osmWay: () => osmWay,
15828 prefs: () => corePreferences,
15829 presetCategory: () => presetCategory,
15830 presetCollection: () => presetCollection,
15831 presetField: () => presetField,
15832 presetIndex: () => presetIndex,
15833 presetManager: () => _mainPresetIndex,
15834 presetPreset: () => presetPreset,
15835 rendererBackground: () => rendererBackground,
15836 rendererBackgroundSource: () => rendererBackgroundSource,
15837 rendererFeatures: () => rendererFeatures,
15838 rendererMap: () => rendererMap,
15839 rendererPhotos: () => rendererPhotos,
15840 rendererTileLayer: () => rendererTileLayer,
15841 serviceImproveOSM: () => improveOSM_default,
15842 serviceKartaview: () => kartaview_default,
15843 serviceKeepRight: () => keepRight_default,
15844 serviceMapRules: () => maprules_default,
15845 serviceMapillary: () => mapillary_default,
15846 serviceNominatim: () => nominatim_default,
15847 serviceNsi: () => nsi_default,
15848 serviceOsm: () => osm_default,
15849 serviceOsmWikibase: () => osm_wikibase_default,
15850 serviceOsmose: () => osmose_default,
15851 serviceStreetside: () => streetside_default,
15852 serviceTaginfo: () => taginfo_default,
15853 serviceVectorTile: () => vector_tile_default,
15854 serviceWikidata: () => wikidata_default,
15855 serviceWikipedia: () => wikipedia_default,
15856 services: () => services,
15857 svgAreas: () => svgAreas,
15858 svgData: () => svgData,
15859 svgDebug: () => svgDebug,
15860 svgDefs: () => svgDefs,
15861 svgGeolocate: () => svgGeolocate,
15862 svgIcon: () => svgIcon,
15863 svgKartaviewImages: () => svgKartaviewImages,
15864 svgKeepRight: () => svgKeepRight,
15865 svgLabels: () => svgLabels,
15866 svgLayers: () => svgLayers,
15867 svgLines: () => svgLines,
15868 svgMapillaryImages: () => svgMapillaryImages,
15869 svgMapillarySigns: () => svgMapillarySigns,
15870 svgMarkerSegments: () => svgMarkerSegments,
15871 svgMidpoints: () => svgMidpoints,
15872 svgNotes: () => svgNotes,
15873 svgOsm: () => svgOsm,
15874 svgPassiveVertex: () => svgPassiveVertex,
15875 svgPath: () => svgPath,
15876 svgPointTransform: () => svgPointTransform,
15877 svgPoints: () => svgPoints,
15878 svgRelationMemberTags: () => svgRelationMemberTags,
15879 svgSegmentWay: () => svgSegmentWay,
15880 svgStreetside: () => svgStreetside,
15881 svgTagClasses: () => svgTagClasses,
15882 svgTagPattern: () => svgTagPattern,
15883 svgTouch: () => svgTouch,
15884 svgTurns: () => svgTurns,
15885 svgVertices: () => svgVertices,
15887 uiAccount: () => uiAccount,
15888 uiAttribution: () => uiAttribution,
15889 uiChangesetEditor: () => uiChangesetEditor,
15890 uiCmd: () => uiCmd,
15891 uiCombobox: () => uiCombobox,
15892 uiCommit: () => uiCommit,
15893 uiCommitWarnings: () => uiCommitWarnings,
15894 uiConfirm: () => uiConfirm,
15895 uiConflicts: () => uiConflicts,
15896 uiContributors: () => uiContributors,
15897 uiCurtain: () => uiCurtain,
15898 uiDataEditor: () => uiDataEditor,
15899 uiDataHeader: () => uiDataHeader,
15900 uiDisclosure: () => uiDisclosure,
15901 uiEditMenu: () => uiEditMenu,
15902 uiEntityEditor: () => uiEntityEditor,
15903 uiFeatureInfo: () => uiFeatureInfo,
15904 uiFeatureList: () => uiFeatureList,
15905 uiField: () => uiField,
15906 uiFieldAccess: () => uiFieldAccess,
15907 uiFieldAddress: () => uiFieldAddress,
15908 uiFieldCheck: () => uiFieldCheck,
15909 uiFieldColour: () => uiFieldText,
15910 uiFieldCombo: () => uiFieldCombo,
15911 uiFieldDefaultCheck: () => uiFieldCheck,
15912 uiFieldDirectionalCombo: () => uiFieldDirectionalCombo,
15913 uiFieldEmail: () => uiFieldText,
15914 uiFieldHelp: () => uiFieldHelp,
15915 uiFieldIdentifier: () => uiFieldText,
15916 uiFieldLanes: () => uiFieldLanes,
15917 uiFieldLocalized: () => uiFieldLocalized,
15918 uiFieldManyCombo: () => uiFieldCombo,
15919 uiFieldMultiCombo: () => uiFieldCombo,
15920 uiFieldNetworkCombo: () => uiFieldCombo,
15921 uiFieldNumber: () => uiFieldText,
15922 uiFieldOnewayCheck: () => uiFieldCheck,
15923 uiFieldRadio: () => uiFieldRadio,
15924 uiFieldRestrictions: () => uiFieldRestrictions,
15925 uiFieldRoadheight: () => uiFieldRoadheight,
15926 uiFieldRoadspeed: () => uiFieldRoadspeed,
15927 uiFieldSemiCombo: () => uiFieldCombo,
15928 uiFieldStructureRadio: () => uiFieldRadio,
15929 uiFieldTel: () => uiFieldText,
15930 uiFieldText: () => uiFieldText,
15931 uiFieldTextarea: () => uiFieldTextarea,
15932 uiFieldTypeCombo: () => uiFieldCombo,
15933 uiFieldUrl: () => uiFieldText,
15934 uiFieldWikidata: () => uiFieldWikidata,
15935 uiFieldWikipedia: () => uiFieldWikipedia,
15936 uiFields: () => uiFields,
15937 uiFlash: () => uiFlash,
15938 uiFormFields: () => uiFormFields,
15939 uiFullScreen: () => uiFullScreen,
15940 uiGeolocate: () => uiGeolocate,
15941 uiImproveOsmComments: () => uiImproveOsmComments,
15942 uiImproveOsmDetails: () => uiImproveOsmDetails,
15943 uiImproveOsmEditor: () => uiImproveOsmEditor,
15944 uiImproveOsmHeader: () => uiImproveOsmHeader,
15945 uiInfo: () => uiInfo,
15946 uiInfoPanels: () => uiInfoPanels,
15947 uiInit: () => uiInit,
15948 uiInspector: () => uiInspector,
15949 uiIntro: () => uiIntro,
15950 uiIssuesInfo: () => uiIssuesInfo,
15951 uiKeepRightDetails: () => uiKeepRightDetails,
15952 uiKeepRightEditor: () => uiKeepRightEditor,
15953 uiKeepRightHeader: () => uiKeepRightHeader,
15954 uiLasso: () => uiLasso,
15955 uiLengthIndicator: () => uiLengthIndicator,
15956 uiLoading: () => uiLoading,
15957 uiMapInMap: () => uiMapInMap,
15958 uiModal: () => uiModal,
15959 uiNoteComments: () => uiNoteComments,
15960 uiNoteEditor: () => uiNoteEditor,
15961 uiNoteHeader: () => uiNoteHeader,
15962 uiNoteReport: () => uiNoteReport,
15963 uiNotice: () => uiNotice,
15964 uiPaneBackground: () => uiPaneBackground,
15965 uiPaneHelp: () => uiPaneHelp,
15966 uiPaneIssues: () => uiPaneIssues,
15967 uiPaneMapData: () => uiPaneMapData,
15968 uiPanePreferences: () => uiPanePreferences,
15969 uiPanelBackground: () => uiPanelBackground,
15970 uiPanelHistory: () => uiPanelHistory,
15971 uiPanelLocation: () => uiPanelLocation,
15972 uiPanelMeasurement: () => uiPanelMeasurement,
15973 uiPopover: () => uiPopover,
15974 uiPresetIcon: () => uiPresetIcon,
15975 uiPresetList: () => uiPresetList,
15976 uiRestore: () => uiRestore,
15977 uiScale: () => uiScale,
15978 uiSectionBackgroundDisplayOptions: () => uiSectionBackgroundDisplayOptions,
15979 uiSectionBackgroundList: () => uiSectionBackgroundList,
15980 uiSectionBackgroundOffset: () => uiSectionBackgroundOffset,
15981 uiSectionChanges: () => uiSectionChanges,
15982 uiSectionDataLayers: () => uiSectionDataLayers,
15983 uiSectionEntityIssues: () => uiSectionEntityIssues,
15984 uiSectionFeatureType: () => uiSectionFeatureType,
15985 uiSectionMapFeatures: () => uiSectionMapFeatures,
15986 uiSectionMapStyleOptions: () => uiSectionMapStyleOptions,
15987 uiSectionOverlayList: () => uiSectionOverlayList,
15988 uiSectionPhotoOverlays: () => uiSectionPhotoOverlays,
15989 uiSectionPresetFields: () => uiSectionPresetFields,
15990 uiSectionPrivacy: () => uiSectionPrivacy,
15991 uiSectionRawMemberEditor: () => uiSectionRawMemberEditor,
15992 uiSectionRawMembershipEditor: () => uiSectionRawMembershipEditor,
15993 uiSectionRawTagEditor: () => uiSectionRawTagEditor,
15994 uiSectionSelectionList: () => uiSectionSelectionList,
15995 uiSectionValidationIssues: () => uiSectionValidationIssues,
15996 uiSectionValidationOptions: () => uiSectionValidationOptions,
15997 uiSectionValidationRules: () => uiSectionValidationRules,
15998 uiSectionValidationStatus: () => uiSectionValidationStatus,
15999 uiSettingsCustomBackground: () => uiSettingsCustomBackground,
16000 uiSettingsCustomData: () => uiSettingsCustomData,
16001 uiSidebar: () => uiSidebar,
16002 uiSourceSwitch: () => uiSourceSwitch,
16003 uiSpinner: () => uiSpinner,
16004 uiSplash: () => uiSplash,
16005 uiStatus: () => uiStatus,
16006 uiSuccess: () => uiSuccess,
16007 uiTagReference: () => uiTagReference,
16008 uiToggle: () => uiToggle,
16009 uiTooltip: () => uiTooltip,
16010 uiVersion: () => uiVersion,
16011 uiViewOnKeepRight: () => uiViewOnKeepRight,
16012 uiViewOnOSM: () => uiViewOnOSM,
16013 uiZoom: () => uiZoom,
16014 utilAesDecrypt: () => utilAesDecrypt,
16015 utilAesEncrypt: () => utilAesEncrypt,
16016 utilArrayChunk: () => utilArrayChunk,
16017 utilArrayDifference: () => utilArrayDifference,
16018 utilArrayFlatten: () => utilArrayFlatten,
16019 utilArrayGroupBy: () => utilArrayGroupBy,
16020 utilArrayIdentical: () => utilArrayIdentical,
16021 utilArrayIntersection: () => utilArrayIntersection,
16022 utilArrayUnion: () => utilArrayUnion,
16023 utilArrayUniq: () => utilArrayUniq,
16024 utilArrayUniqBy: () => utilArrayUniqBy,
16025 utilAsyncMap: () => utilAsyncMap,
16026 utilCleanOsmString: () => utilCleanOsmString,
16027 utilCleanTags: () => utilCleanTags,
16028 utilCombinedTags: () => utilCombinedTags,
16029 utilCompareIDs: () => utilCompareIDs,
16030 utilDeepMemberSelector: () => utilDeepMemberSelector,
16031 utilDetect: () => utilDetect,
16032 utilDisplayLabel: () => utilDisplayLabel,
16033 utilDisplayName: () => utilDisplayName,
16034 utilDisplayNameForPath: () => utilDisplayNameForPath,
16035 utilDisplayType: () => utilDisplayType,
16036 utilEditDistance: () => utilEditDistance,
16037 utilEntityAndDeepMemberIDs: () => utilEntityAndDeepMemberIDs,
16038 utilEntityOrDeepMemberSelector: () => utilEntityOrDeepMemberSelector,
16039 utilEntityOrMemberSelector: () => utilEntityOrMemberSelector,
16040 utilEntityRoot: () => utilEntityRoot,
16041 utilEntitySelector: () => utilEntitySelector,
16042 utilFastMouse: () => utilFastMouse,
16043 utilFunctor: () => utilFunctor,
16044 utilGetAllNodes: () => utilGetAllNodes,
16045 utilGetSetValue: () => utilGetSetValue,
16046 utilHashcode: () => utilHashcode,
16047 utilHighlightEntities: () => utilHighlightEntities,
16048 utilKeybinding: () => utilKeybinding,
16049 utilNoAuto: () => utilNoAuto,
16050 utilObjectOmit: () => utilObjectOmit,
16051 utilOldestID: () => utilOldestID,
16052 utilPrefixCSSProperty: () => utilPrefixCSSProperty,
16053 utilPrefixDOMProperty: () => utilPrefixDOMProperty,
16054 utilQsString: () => utilQsString,
16055 utilRebind: () => utilRebind,
16056 utilSafeClassName: () => utilSafeClassName,
16057 utilSessionMutex: () => utilSessionMutex,
16058 utilSetTransform: () => utilSetTransform,
16059 utilStringQs: () => utilStringQs,
16060 utilTagDiff: () => utilTagDiff,
16061 utilTagText: () => utilTagText,
16062 utilTiler: () => utilTiler,
16063 utilTotalExtent: () => utilTotalExtent,
16064 utilTriggerEvent: () => utilTriggerEvent,
16065 utilUnicodeCharsCount: () => utilUnicodeCharsCount,
16066 utilUnicodeCharsTruncated: () => utilUnicodeCharsTruncated,
16067 utilUniqueDomId: () => utilUniqueDomId,
16068 utilWrap: () => utilWrap,
16069 validationAlmostJunction: () => validationAlmostJunction,
16070 validationCloseNodes: () => validationCloseNodes,
16071 validationCrossingWays: () => validationCrossingWays,
16072 validationDisconnectedWay: () => validationDisconnectedWay,
16073 validationFormatting: () => validationFormatting,
16074 validationHelpRequest: () => validationHelpRequest,
16075 validationImpossibleOneway: () => validationImpossibleOneway,
16076 validationIncompatibleSource: () => validationIncompatibleSource,
16077 validationMaprules: () => validationMaprules,
16078 validationMismatchedGeometry: () => validationMismatchedGeometry,
16079 validationMissingRole: () => validationMissingRole,
16080 validationMissingTag: () => validationMissingTag,
16081 validationOutdatedTags: () => validationOutdatedTags,
16082 validationPrivateData: () => validationPrivateData,
16083 validationSuspiciousName: () => validationSuspiciousName,
16084 validationUnsquareWay: () => validationUnsquareWay
16087 // modules/actions/add_entity.js
16088 function actionAddEntity(way) {
16089 return function(graph) {
16090 return graph.replace(way);
16094 // modules/actions/reverse.js
16095 function actionReverse(entityID, options2) {
16096 var ignoreKey = /^.*(_|:)?(description|name|note|website|ref|source|comment|watch|attribution)(_|:)?/;
16097 var numeric = /^([+\-]?)(?=[\d.])/;
16098 var directionKey = /direction$/;
16099 var turn_lanes = /^turn:lanes:?/;
16100 var keyReplacements = [
16101 [/:right$/, ":left"],
16102 [/:left$/, ":right"],
16103 [/:forward$/, ":backward"],
16104 [/:backward$/, ":forward"],
16105 [/:right:/, ":left:"],
16106 [/:left:/, ":right:"],
16107 [/:forward:/, ":backward:"],
16108 [/:backward:/, ":forward:"]
16110 var valueReplacements = {
16115 forward: "backward",
16116 backward: "forward",
16117 forwards: "backward",
16118 backwards: "forward"
16120 var roleReplacements = {
16121 forward: "backward",
16122 backward: "forward",
16123 forwards: "backward",
16124 backwards: "forward"
16126 var onewayReplacements = {
16131 var compassReplacements = {
16149 function reverseKey(key) {
16150 for (var i2 = 0; i2 < keyReplacements.length; ++i2) {
16151 var replacement = keyReplacements[i2];
16152 if (replacement[0].test(key)) {
16153 return key.replace(replacement[0], replacement[1]);
16158 function reverseValue(key, value, includeAbsolute) {
16159 if (ignoreKey.test(key))
16161 if (turn_lanes.test(key)) {
16163 } else if (key === "incline" && numeric.test(value)) {
16164 return value.replace(numeric, function(_, sign2) {
16165 return sign2 === "-" ? "" : "-";
16167 } else if (options2 && options2.reverseOneway && key === "oneway") {
16168 return onewayReplacements[value] || value;
16169 } else if (includeAbsolute && directionKey.test(key)) {
16170 return value.split(";").map((value2) => {
16171 if (compassReplacements[value2])
16172 return compassReplacements[value2];
16173 var degrees3 = Number(value2);
16174 if (isFinite(degrees3)) {
16175 if (degrees3 < 180) {
16180 return degrees3.toString();
16182 return valueReplacements[value2] || value2;
16186 return valueReplacements[value] || value;
16188 function reverseNodeTags(graph, nodeIDs) {
16189 for (var i2 = 0; i2 < nodeIDs.length; i2++) {
16190 var node = graph.hasEntity(nodeIDs[i2]);
16191 if (!node || !Object.keys(node.tags).length)
16194 for (var key in node.tags) {
16195 tags[reverseKey(key)] = reverseValue(key, node.tags[key], node.id === entityID);
16197 graph = graph.replace(node.update({ tags }));
16201 function reverseWay(graph, way) {
16202 var nodes = way.nodes.slice().reverse();
16205 for (var key in way.tags) {
16206 tags[reverseKey(key)] = reverseValue(key, way.tags[key]);
16208 graph.parentRelations(way).forEach(function(relation) {
16209 relation.members.forEach(function(member, index) {
16210 if (member.id === way.id && (role = roleReplacements[member.role])) {
16211 relation = relation.updateMember({ role }, index);
16212 graph = graph.replace(relation);
16216 return reverseNodeTags(graph, nodes).replace(way.update({ nodes, tags }));
16218 var action = function(graph) {
16219 var entity = graph.entity(entityID);
16220 if (entity.type === "way") {
16221 return reverseWay(graph, entity);
16223 return reverseNodeTags(graph, [entityID]);
16225 action.disabled = function(graph) {
16226 var entity = graph.hasEntity(entityID);
16227 if (!entity || entity.type === "way")
16229 for (var key in entity.tags) {
16230 var value = entity.tags[key];
16231 if (reverseKey(key) !== key || reverseValue(key, value, true) !== value) {
16235 return "nondirectional_node";
16237 action.entityID = function() {
16243 // modules/osm/tags.js
16244 function osmIsInterestingTag(key) {
16245 return key !== "attribution" && key !== "created_by" && key !== "source" && key !== "odbl" && key.indexOf("source:") !== 0 && key.indexOf("source_ref") !== 0 && // purposely exclude colon
16246 key.indexOf("tiger:") !== 0;
16248 var osmLifecyclePrefixes = {
16249 // nonexistent, might be built
16252 // under maintentance or between groundbreaking and opening
16253 construction: true,
16254 // existent but not functional
16256 // dilapidated to nonexistent
16259 // nonexistent, still may appear in imagery
16266 // existent occasionally, e.g. stormwater drainage basin
16269 function osmRemoveLifecyclePrefix(key) {
16270 const keySegments = key.split(":");
16271 if (keySegments.length === 1)
16273 if (keySegments[0] in osmLifecyclePrefixes) {
16274 return key.slice(keySegments[0].length + 1);
16278 var osmAreaKeys = {};
16279 function osmSetAreaKeys(value) {
16280 osmAreaKeys = value;
16282 var osmAreaKeysExceptions = {
16288 public_transport: {
16306 function osmTagSuggestingArea(tags) {
16307 if (tags.area === "yes")
16308 return { area: "yes" };
16309 if (tags.area === "no")
16311 var returnTags = {};
16312 for (var realKey in tags) {
16313 const key = osmRemoveLifecyclePrefix(realKey);
16314 if (key in osmAreaKeys && !(tags[key] in osmAreaKeys[key])) {
16315 returnTags[realKey] = tags[realKey];
16318 if (key in osmAreaKeysExceptions && tags[key] in osmAreaKeysExceptions[key]) {
16319 returnTags[realKey] = tags[realKey];
16325 var osmLineTags = {};
16326 function osmSetLineTags(value) {
16327 osmLineTags = value;
16329 var osmPointTags = {};
16330 function osmSetPointTags(value) {
16331 osmPointTags = value;
16333 var osmVertexTags = {};
16334 function osmSetVertexTags(value) {
16335 osmVertexTags = value;
16337 function osmNodeGeometriesForTags(nodeTags) {
16338 var geometries = {};
16339 for (var key in nodeTags) {
16340 if (osmPointTags[key] && (osmPointTags[key]["*"] || osmPointTags[key][nodeTags[key]])) {
16341 geometries.point = true;
16343 if (osmVertexTags[key] && (osmVertexTags[key]["*"] || osmVertexTags[key][nodeTags[key]])) {
16344 geometries.vertex = true;
16346 if (geometries.point && geometries.vertex)
16351 var osmOneWayTags = {
16353 "chair_lift": true,
16356 "magic_carpet": true,
16357 "mixed_lift": true,
16371 "goods_conveyor": true,
16372 "piste:halfpipe": true
16380 "separation_lane": true,
16381 "separation_roundabout": true
16390 "tidal_channel": true
16393 var osmPavedTags = {
16399 "concrete:lanes": true,
16400 "concrete:plates": true
16406 var osmSemipavedTags = {
16408 "cobblestone": true,
16409 "cobblestone:flattened": true,
16410 "unhewn_cobblestone": true,
16412 "paving_stones": true,
16417 var osmRightSideIsInsideTags = {
16420 "coastline": "coastline"
16423 "retaining_wall": true,
16425 "guard_rail": true,
16435 var osmRoutableHighwayTagValues = {
16442 motorway_link: true,
16444 primary_link: true,
16445 secondary_link: true,
16446 tertiary_link: true,
16447 unclassified: true,
16451 living_street: true,
16452 bus_guideway: true,
16461 var osmPathHighwayTagValues = {
16470 var osmRailwayTrackTagValues = {
16478 narrow_gauge: true,
16482 var osmFlowingWaterwayTagValues = {
16489 tidal_channel: true
16492 // node_modules/d3-array/src/ascending.js
16493 function ascending(a, b) {
16494 return a == null || b == null ? NaN : a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
16497 // node_modules/d3-array/src/descending.js
16498 function descending(a, b) {
16499 return a == null || b == null ? NaN : b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
16502 // node_modules/d3-array/src/bisector.js
16503 function bisector(f2) {
16504 let compare1, compare2, delta;
16505 if (f2.length !== 2) {
16506 compare1 = ascending;
16507 compare2 = (d, x) => ascending(f2(d), x);
16508 delta = (d, x) => f2(d) - x;
16510 compare1 = f2 === ascending || f2 === descending ? f2 : zero;
16514 function left(a, x, lo = 0, hi = a.length) {
16516 if (compare1(x, x) !== 0)
16519 const mid = lo + hi >>> 1;
16520 if (compare2(a[mid], x) < 0)
16528 function right(a, x, lo = 0, hi = a.length) {
16530 if (compare1(x, x) !== 0)
16533 const mid = lo + hi >>> 1;
16534 if (compare2(a[mid], x) <= 0)
16542 function center(a, x, lo = 0, hi = a.length) {
16543 const i2 = left(a, x, lo, hi - 1);
16544 return i2 > lo && delta(a[i2 - 1], x) > -delta(a[i2], x) ? i2 - 1 : i2;
16546 return { left, center, right };
16552 // node_modules/d3-array/src/number.js
16553 function number(x) {
16554 return x === null ? NaN : +x;
16556 function* numbers(values, valueof) {
16557 if (valueof === void 0) {
16558 for (let value of values) {
16559 if (value != null && (value = +value) >= value) {
16565 for (let value of values) {
16566 if ((value = valueof(value, ++index, values)) != null && (value = +value) >= value) {
16573 // node_modules/d3-array/src/bisect.js
16574 var ascendingBisect = bisector(ascending);
16575 var bisectRight = ascendingBisect.right;
16576 var bisectLeft = ascendingBisect.left;
16577 var bisectCenter = bisector(number).center;
16578 var bisect_default = bisectRight;
16580 // node_modules/d3-array/src/fsum.js
16581 var Adder = class {
16583 this._partials = new Float64Array(32);
16587 const p = this._partials;
16589 for (let j2 = 0; j2 < this._n && j2 < 32; j2++) {
16590 const y = p[j2], hi = x + y, lo = Math.abs(x) < Math.abs(y) ? x - (hi - y) : y - (hi - x);
16600 const p = this._partials;
16601 let n2 = this._n, x, y, lo, hi = 0;
16612 if (n2 > 0 && (lo < 0 && p[n2 - 1] < 0 || lo > 0 && p[n2 - 1] > 0)) {
16623 // node_modules/d3-array/src/sort.js
16624 function compareDefined(compare = ascending) {
16625 if (compare === ascending)
16626 return ascendingDefined;
16627 if (typeof compare !== "function")
16628 throw new TypeError("compare is not a function");
16630 const x = compare(a, b);
16633 return (compare(b, b) === 0) - (compare(a, a) === 0);
16636 function ascendingDefined(a, b) {
16637 return (a == null || !(a >= a)) - (b == null || !(b >= b)) || (a < b ? -1 : a > b ? 1 : 0);
16640 // node_modules/d3-array/src/ticks.js
16641 var e10 = Math.sqrt(50);
16642 var e5 = Math.sqrt(10);
16643 var e2 = Math.sqrt(2);
16644 function ticks(start2, stop, count) {
16645 var reverse, i2 = -1, n2, ticks2, step;
16646 stop = +stop, start2 = +start2, count = +count;
16647 if (start2 === stop && count > 0)
16649 if (reverse = stop < start2)
16650 n2 = start2, start2 = stop, stop = n2;
16651 if ((step = tickIncrement(start2, stop, count)) === 0 || !isFinite(step))
16654 let r0 = Math.round(start2 / step), r1 = Math.round(stop / step);
16655 if (r0 * step < start2)
16657 if (r1 * step > stop)
16659 ticks2 = new Array(n2 = r1 - r0 + 1);
16661 ticks2[i2] = (r0 + i2) * step;
16664 let r0 = Math.round(start2 * step), r1 = Math.round(stop * step);
16665 if (r0 / step < start2)
16667 if (r1 / step > stop)
16669 ticks2 = new Array(n2 = r1 - r0 + 1);
16671 ticks2[i2] = (r0 + i2) / step;
16677 function tickIncrement(start2, stop, count) {
16678 var step = (stop - start2) / Math.max(0, count), power = Math.floor(Math.log(step) / Math.LN10), error = step / Math.pow(10, power);
16679 return power >= 0 ? (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1) * Math.pow(10, power) : -Math.pow(10, -power) / (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1);
16681 function tickStep(start2, stop, count) {
16682 var step0 = Math.abs(stop - start2) / Math.max(0, count), step1 = Math.pow(10, Math.floor(Math.log(step0) / Math.LN10)), error = step0 / step1;
16685 else if (error >= e5)
16687 else if (error >= e2)
16689 return stop < start2 ? -step1 : step1;
16692 // node_modules/d3-array/src/max.js
16693 function max(values, valueof) {
16695 if (valueof === void 0) {
16696 for (const value of values) {
16697 if (value != null && (max3 < value || max3 === void 0 && value >= value)) {
16703 for (let value of values) {
16704 if ((value = valueof(value, ++index, values)) != null && (max3 < value || max3 === void 0 && value >= value)) {
16712 // node_modules/d3-array/src/min.js
16713 function min(values, valueof) {
16715 if (valueof === void 0) {
16716 for (const value of values) {
16717 if (value != null && (min3 > value || min3 === void 0 && value >= value)) {
16723 for (let value of values) {
16724 if ((value = valueof(value, ++index, values)) != null && (min3 > value || min3 === void 0 && value >= value)) {
16732 // node_modules/d3-array/src/quickselect.js
16733 function quickselect(array2, k, left = 0, right = array2.length - 1, compare) {
16734 compare = compare === void 0 ? ascendingDefined : compareDefined(compare);
16735 while (right > left) {
16736 if (right - left > 600) {
16737 const n2 = right - left + 1;
16738 const m = k - left + 1;
16739 const z = Math.log(n2);
16740 const s = 0.5 * Math.exp(2 * z / 3);
16741 const sd = 0.5 * Math.sqrt(z * s * (n2 - s) / n2) * (m - n2 / 2 < 0 ? -1 : 1);
16742 const newLeft = Math.max(left, Math.floor(k - m * s / n2 + sd));
16743 const newRight = Math.min(right, Math.floor(k + (n2 - m) * s / n2 + sd));
16744 quickselect(array2, k, newLeft, newRight, compare);
16746 const t = array2[k];
16749 swap(array2, left, k);
16750 if (compare(array2[right], t) > 0)
16751 swap(array2, left, right);
16753 swap(array2, i2, j2), ++i2, --j2;
16754 while (compare(array2[i2], t) < 0)
16756 while (compare(array2[j2], t) > 0)
16759 if (compare(array2[left], t) === 0)
16760 swap(array2, left, j2);
16762 ++j2, swap(array2, j2, right);
16770 function swap(array2, i2, j2) {
16771 const t = array2[i2];
16772 array2[i2] = array2[j2];
16776 // node_modules/d3-array/src/quantile.js
16777 function quantile(values, p, valueof) {
16778 values = Float64Array.from(numbers(values, valueof));
16779 if (!(n2 = values.length))
16781 if ((p = +p) <= 0 || n2 < 2)
16782 return min(values);
16784 return max(values);
16785 var n2, i2 = (n2 - 1) * p, i0 = Math.floor(i2), value0 = max(quickselect(values, i0).subarray(0, i0 + 1)), value1 = min(values.subarray(i0 + 1));
16786 return value0 + (value1 - value0) * (i2 - i0);
16789 // node_modules/d3-array/src/median.js
16790 function median(values, valueof) {
16791 return quantile(values, 0.5, valueof);
16794 // node_modules/d3-array/src/merge.js
16795 function* flatten(arrays) {
16796 for (const array2 of arrays) {
16800 function merge(arrays) {
16801 return Array.from(flatten(arrays));
16804 // node_modules/d3-array/src/range.js
16805 function range(start2, stop, step) {
16806 start2 = +start2, stop = +stop, step = (n2 = arguments.length) < 2 ? (stop = start2, start2 = 0, 1) : n2 < 3 ? 1 : +step;
16807 var i2 = -1, n2 = Math.max(0, Math.ceil((stop - start2) / step)) | 0, range3 = new Array(n2);
16808 while (++i2 < n2) {
16809 range3[i2] = start2 + i2 * step;
16814 // node_modules/d3-geo/src/math.js
16815 var epsilon = 1e-6;
16816 var epsilon2 = 1e-12;
16818 var halfPi = pi / 2;
16819 var quarterPi = pi / 4;
16821 var degrees = 180 / pi;
16822 var radians = pi / 180;
16823 var abs = Math.abs;
16824 var atan = Math.atan;
16825 var atan2 = Math.atan2;
16826 var cos = Math.cos;
16827 var exp = Math.exp;
16828 var log = Math.log;
16829 var sin = Math.sin;
16830 var sign = Math.sign || function(x) {
16831 return x > 0 ? 1 : x < 0 ? -1 : 0;
16833 var sqrt = Math.sqrt;
16834 var tan = Math.tan;
16836 return x > 1 ? 0 : x < -1 ? pi : Math.acos(x);
16839 return x > 1 ? halfPi : x < -1 ? -halfPi : Math.asin(x);
16842 // node_modules/d3-geo/src/noop.js
16846 // node_modules/d3-geo/src/stream.js
16847 function streamGeometry(geometry, stream) {
16848 if (geometry && streamGeometryType.hasOwnProperty(geometry.type)) {
16849 streamGeometryType[geometry.type](geometry, stream);
16852 var streamObjectType = {
16853 Feature: function(object, stream) {
16854 streamGeometry(object.geometry, stream);
16856 FeatureCollection: function(object, stream) {
16857 var features = object.features, i2 = -1, n2 = features.length;
16859 streamGeometry(features[i2].geometry, stream);
16862 var streamGeometryType = {
16863 Sphere: function(object, stream) {
16866 Point: function(object, stream) {
16867 object = object.coordinates;
16868 stream.point(object[0], object[1], object[2]);
16870 MultiPoint: function(object, stream) {
16871 var coordinates = object.coordinates, i2 = -1, n2 = coordinates.length;
16873 object = coordinates[i2], stream.point(object[0], object[1], object[2]);
16875 LineString: function(object, stream) {
16876 streamLine(object.coordinates, stream, 0);
16878 MultiLineString: function(object, stream) {
16879 var coordinates = object.coordinates, i2 = -1, n2 = coordinates.length;
16881 streamLine(coordinates[i2], stream, 0);
16883 Polygon: function(object, stream) {
16884 streamPolygon(object.coordinates, stream);
16886 MultiPolygon: function(object, stream) {
16887 var coordinates = object.coordinates, i2 = -1, n2 = coordinates.length;
16889 streamPolygon(coordinates[i2], stream);
16891 GeometryCollection: function(object, stream) {
16892 var geometries = object.geometries, i2 = -1, n2 = geometries.length;
16894 streamGeometry(geometries[i2], stream);
16897 function streamLine(coordinates, stream, closed) {
16898 var i2 = -1, n2 = coordinates.length - closed, coordinate;
16899 stream.lineStart();
16901 coordinate = coordinates[i2], stream.point(coordinate[0], coordinate[1], coordinate[2]);
16904 function streamPolygon(coordinates, stream) {
16905 var i2 = -1, n2 = coordinates.length;
16906 stream.polygonStart();
16908 streamLine(coordinates[i2], stream, 1);
16909 stream.polygonEnd();
16911 function stream_default(object, stream) {
16912 if (object && streamObjectType.hasOwnProperty(object.type)) {
16913 streamObjectType[object.type](object, stream);
16915 streamGeometry(object, stream);
16919 // node_modules/d3-geo/src/area.js
16920 var areaRingSum = new Adder();
16921 var areaSum = new Adder();
16931 polygonStart: function() {
16932 areaRingSum = new Adder();
16933 areaStream.lineStart = areaRingStart;
16934 areaStream.lineEnd = areaRingEnd;
16936 polygonEnd: function() {
16937 var areaRing = +areaRingSum;
16938 areaSum.add(areaRing < 0 ? tau + areaRing : areaRing);
16939 this.lineStart = this.lineEnd = this.point = noop;
16941 sphere: function() {
16945 function areaRingStart() {
16946 areaStream.point = areaPointFirst;
16948 function areaRingEnd() {
16949 areaPoint(lambda00, phi00);
16951 function areaPointFirst(lambda, phi) {
16952 areaStream.point = areaPoint;
16953 lambda00 = lambda, phi00 = phi;
16954 lambda *= radians, phi *= radians;
16955 lambda0 = lambda, cosPhi0 = cos(phi = phi / 2 + quarterPi), sinPhi0 = sin(phi);
16957 function areaPoint(lambda, phi) {
16958 lambda *= radians, phi *= radians;
16959 phi = phi / 2 + quarterPi;
16960 var dLambda = lambda - lambda0, sdLambda = dLambda >= 0 ? 1 : -1, adLambda = sdLambda * dLambda, cosPhi = cos(phi), sinPhi = sin(phi), k = sinPhi0 * sinPhi, u = cosPhi0 * cosPhi + k * cos(adLambda), v = k * sdLambda * sin(adLambda);
16961 areaRingSum.add(atan2(v, u));
16962 lambda0 = lambda, cosPhi0 = cosPhi, sinPhi0 = sinPhi;
16964 function area_default(object) {
16965 areaSum = new Adder();
16966 stream_default(object, areaStream);
16967 return areaSum * 2;
16970 // node_modules/d3-geo/src/cartesian.js
16971 function spherical(cartesian2) {
16972 return [atan2(cartesian2[1], cartesian2[0]), asin(cartesian2[2])];
16974 function cartesian(spherical2) {
16975 var lambda = spherical2[0], phi = spherical2[1], cosPhi = cos(phi);
16976 return [cosPhi * cos(lambda), cosPhi * sin(lambda), sin(phi)];
16978 function cartesianDot(a, b) {
16979 return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
16981 function cartesianCross(a, b) {
16982 return [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]];
16984 function cartesianAddInPlace(a, b) {
16985 a[0] += b[0], a[1] += b[1], a[2] += b[2];
16987 function cartesianScale(vector, k) {
16988 return [vector[0] * k, vector[1] * k, vector[2] * k];
16990 function cartesianNormalizeInPlace(d) {
16991 var l = sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]);
16992 d[0] /= l, d[1] /= l, d[2] /= l;
16995 // node_modules/d3-geo/src/bounds.js
17007 var boundsStream = {
17008 point: boundsPoint,
17009 lineStart: boundsLineStart,
17010 lineEnd: boundsLineEnd,
17011 polygonStart: function() {
17012 boundsStream.point = boundsRingPoint;
17013 boundsStream.lineStart = boundsRingStart;
17014 boundsStream.lineEnd = boundsRingEnd;
17015 deltaSum = new Adder();
17016 areaStream.polygonStart();
17018 polygonEnd: function() {
17019 areaStream.polygonEnd();
17020 boundsStream.point = boundsPoint;
17021 boundsStream.lineStart = boundsLineStart;
17022 boundsStream.lineEnd = boundsLineEnd;
17023 if (areaRingSum < 0)
17024 lambda02 = -(lambda1 = 180), phi0 = -(phi1 = 90);
17025 else if (deltaSum > epsilon)
17027 else if (deltaSum < -epsilon)
17029 range2[0] = lambda02, range2[1] = lambda1;
17031 sphere: function() {
17032 lambda02 = -(lambda1 = 180), phi0 = -(phi1 = 90);
17035 function boundsPoint(lambda, phi) {
17036 ranges.push(range2 = [lambda02 = lambda, lambda1 = lambda]);
17042 function linePoint(lambda, phi) {
17043 var p = cartesian([lambda * radians, phi * radians]);
17045 var normal = cartesianCross(p0, p), equatorial = [normal[1], -normal[0], 0], inflection = cartesianCross(equatorial, normal);
17046 cartesianNormalizeInPlace(inflection);
17047 inflection = spherical(inflection);
17048 var delta = lambda - lambda2, sign2 = delta > 0 ? 1 : -1, lambdai = inflection[0] * degrees * sign2, phii, antimeridian = abs(delta) > 180;
17049 if (antimeridian ^ (sign2 * lambda2 < lambdai && lambdai < sign2 * lambda)) {
17050 phii = inflection[1] * degrees;
17053 } else if (lambdai = (lambdai + 360) % 360 - 180, antimeridian ^ (sign2 * lambda2 < lambdai && lambdai < sign2 * lambda)) {
17054 phii = -inflection[1] * degrees;
17063 if (antimeridian) {
17064 if (lambda < lambda2) {
17065 if (angle(lambda02, lambda) > angle(lambda02, lambda1))
17068 if (angle(lambda, lambda1) > angle(lambda02, lambda1))
17072 if (lambda1 >= lambda02) {
17073 if (lambda < lambda02)
17075 if (lambda > lambda1)
17078 if (lambda > lambda2) {
17079 if (angle(lambda02, lambda) > angle(lambda02, lambda1))
17082 if (angle(lambda, lambda1) > angle(lambda02, lambda1))
17088 ranges.push(range2 = [lambda02 = lambda, lambda1 = lambda]);
17094 p0 = p, lambda2 = lambda;
17096 function boundsLineStart() {
17097 boundsStream.point = linePoint;
17099 function boundsLineEnd() {
17100 range2[0] = lambda02, range2[1] = lambda1;
17101 boundsStream.point = boundsPoint;
17104 function boundsRingPoint(lambda, phi) {
17106 var delta = lambda - lambda2;
17107 deltaSum.add(abs(delta) > 180 ? delta + (delta > 0 ? 360 : -360) : delta);
17109 lambda002 = lambda, phi002 = phi;
17111 areaStream.point(lambda, phi);
17112 linePoint(lambda, phi);
17114 function boundsRingStart() {
17115 areaStream.lineStart();
17117 function boundsRingEnd() {
17118 boundsRingPoint(lambda002, phi002);
17119 areaStream.lineEnd();
17120 if (abs(deltaSum) > epsilon)
17121 lambda02 = -(lambda1 = 180);
17122 range2[0] = lambda02, range2[1] = lambda1;
17125 function angle(lambda04, lambda12) {
17126 return (lambda12 -= lambda04) < 0 ? lambda12 + 360 : lambda12;
17128 function rangeCompare(a, b) {
17129 return a[0] - b[0];
17131 function rangeContains(range3, x) {
17132 return range3[0] <= range3[1] ? range3[0] <= x && x <= range3[1] : x < range3[0] || range3[1] < x;
17134 function bounds_default(feature3) {
17135 var i2, n2, a, b, merged, deltaMax, delta;
17136 phi1 = lambda1 = -(lambda02 = phi0 = Infinity);
17138 stream_default(feature3, boundsStream);
17139 if (n2 = ranges.length) {
17140 ranges.sort(rangeCompare);
17141 for (i2 = 1, a = ranges[0], merged = [a]; i2 < n2; ++i2) {
17143 if (rangeContains(a, b[0]) || rangeContains(a, b[1])) {
17144 if (angle(a[0], b[1]) > angle(a[0], a[1]))
17146 if (angle(b[0], a[1]) > angle(a[0], a[1]))
17149 merged.push(a = b);
17152 for (deltaMax = -Infinity, n2 = merged.length - 1, i2 = 0, a = merged[n2]; i2 <= n2; a = b, ++i2) {
17154 if ((delta = angle(a[1], b[0])) > deltaMax)
17155 deltaMax = delta, lambda02 = b[0], lambda1 = a[1];
17158 ranges = range2 = null;
17159 return lambda02 === Infinity || phi0 === Infinity ? [[NaN, NaN], [NaN, NaN]] : [[lambda02, phi0], [lambda1, phi1]];
17162 // node_modules/d3-geo/src/compose.js
17163 function compose_default(a, b) {
17164 function compose(x, y) {
17165 return x = a(x, y), b(x[0], x[1]);
17167 if (a.invert && b.invert)
17168 compose.invert = function(x, y) {
17169 return x = b.invert(x, y), x && a.invert(x[0], x[1]);
17174 // node_modules/d3-geo/src/rotation.js
17175 function rotationIdentity(lambda, phi) {
17176 return [abs(lambda) > pi ? lambda + Math.round(-lambda / tau) * tau : lambda, phi];
17178 rotationIdentity.invert = rotationIdentity;
17179 function rotateRadians(deltaLambda, deltaPhi, deltaGamma) {
17180 return (deltaLambda %= tau) ? deltaPhi || deltaGamma ? compose_default(rotationLambda(deltaLambda), rotationPhiGamma(deltaPhi, deltaGamma)) : rotationLambda(deltaLambda) : deltaPhi || deltaGamma ? rotationPhiGamma(deltaPhi, deltaGamma) : rotationIdentity;
17182 function forwardRotationLambda(deltaLambda) {
17183 return function(lambda, phi) {
17184 return lambda += deltaLambda, [lambda > pi ? lambda - tau : lambda < -pi ? lambda + tau : lambda, phi];
17187 function rotationLambda(deltaLambda) {
17188 var rotation = forwardRotationLambda(deltaLambda);
17189 rotation.invert = forwardRotationLambda(-deltaLambda);
17192 function rotationPhiGamma(deltaPhi, deltaGamma) {
17193 var cosDeltaPhi = cos(deltaPhi), sinDeltaPhi = sin(deltaPhi), cosDeltaGamma = cos(deltaGamma), sinDeltaGamma = sin(deltaGamma);
17194 function rotation(lambda, phi) {
17195 var cosPhi = cos(phi), x = cos(lambda) * cosPhi, y = sin(lambda) * cosPhi, z = sin(phi), k = z * cosDeltaPhi + x * sinDeltaPhi;
17197 atan2(y * cosDeltaGamma - k * sinDeltaGamma, x * cosDeltaPhi - z * sinDeltaPhi),
17198 asin(k * cosDeltaGamma + y * sinDeltaGamma)
17201 rotation.invert = function(lambda, phi) {
17202 var cosPhi = cos(phi), x = cos(lambda) * cosPhi, y = sin(lambda) * cosPhi, z = sin(phi), k = z * cosDeltaGamma - y * sinDeltaGamma;
17204 atan2(y * cosDeltaGamma + z * sinDeltaGamma, x * cosDeltaPhi + k * sinDeltaPhi),
17205 asin(k * cosDeltaPhi - x * sinDeltaPhi)
17210 function rotation_default(rotate) {
17211 rotate = rotateRadians(rotate[0] * radians, rotate[1] * radians, rotate.length > 2 ? rotate[2] * radians : 0);
17212 function forward(coordinates) {
17213 coordinates = rotate(coordinates[0] * radians, coordinates[1] * radians);
17214 return coordinates[0] *= degrees, coordinates[1] *= degrees, coordinates;
17216 forward.invert = function(coordinates) {
17217 coordinates = rotate.invert(coordinates[0] * radians, coordinates[1] * radians);
17218 return coordinates[0] *= degrees, coordinates[1] *= degrees, coordinates;
17223 // node_modules/d3-geo/src/circle.js
17224 function circleStream(stream, radius, delta, direction, t0, t1) {
17227 var cosRadius = cos(radius), sinRadius = sin(radius), step = direction * delta;
17229 t0 = radius + direction * tau;
17230 t1 = radius - step / 2;
17232 t0 = circleRadius(cosRadius, t0);
17233 t1 = circleRadius(cosRadius, t1);
17234 if (direction > 0 ? t0 < t1 : t0 > t1)
17235 t0 += direction * tau;
17237 for (var point2, t = t0; direction > 0 ? t > t1 : t < t1; t -= step) {
17238 point2 = spherical([cosRadius, -sinRadius * cos(t), -sinRadius * sin(t)]);
17239 stream.point(point2[0], point2[1]);
17242 function circleRadius(cosRadius, point2) {
17243 point2 = cartesian(point2), point2[0] -= cosRadius;
17244 cartesianNormalizeInPlace(point2);
17245 var radius = acos(-point2[1]);
17246 return ((-point2[2] < 0 ? -radius : radius) + tau - epsilon) % tau;
17249 // node_modules/d3-geo/src/clip/buffer.js
17250 function buffer_default() {
17251 var lines = [], line;
17253 point: function(x, y, m) {
17254 line.push([x, y, m]);
17256 lineStart: function() {
17257 lines.push(line = []);
17260 rejoin: function() {
17261 if (lines.length > 1)
17262 lines.push(lines.pop().concat(lines.shift()));
17264 result: function() {
17265 var result = lines;
17273 // node_modules/d3-geo/src/pointEqual.js
17274 function pointEqual_default(a, b) {
17275 return abs(a[0] - b[0]) < epsilon && abs(a[1] - b[1]) < epsilon;
17278 // node_modules/d3-geo/src/clip/rejoin.js
17279 function Intersection(point2, points, other, entry) {
17285 this.n = this.p = null;
17287 function rejoin_default(segments, compareIntersection2, startInside, interpolate, stream) {
17288 var subject = [], clip = [], i2, n2;
17289 segments.forEach(function(segment) {
17290 if ((n3 = segment.length - 1) <= 0)
17292 var n3, p02 = segment[0], p1 = segment[n3], x;
17293 if (pointEqual_default(p02, p1)) {
17294 if (!p02[2] && !p1[2]) {
17295 stream.lineStart();
17296 for (i2 = 0; i2 < n3; ++i2)
17297 stream.point((p02 = segment[i2])[0], p02[1]);
17301 p1[0] += 2 * epsilon;
17303 subject.push(x = new Intersection(p02, segment, null, true));
17304 clip.push(x.o = new Intersection(p02, null, x, false));
17305 subject.push(x = new Intersection(p1, segment, null, false));
17306 clip.push(x.o = new Intersection(p1, null, x, true));
17308 if (!subject.length)
17310 clip.sort(compareIntersection2);
17313 for (i2 = 0, n2 = clip.length; i2 < n2; ++i2) {
17314 clip[i2].e = startInside = !startInside;
17316 var start2 = subject[0], points, point2;
17318 var current = start2, isSubject = true;
17320 if ((current = current.n) === start2)
17322 points = current.z;
17323 stream.lineStart();
17325 current.v = current.o.v = true;
17328 for (i2 = 0, n2 = points.length; i2 < n2; ++i2)
17329 stream.point((point2 = points[i2])[0], point2[1]);
17331 interpolate(current.x, current.n.x, 1, stream);
17333 current = current.n;
17336 points = current.p.z;
17337 for (i2 = points.length - 1; i2 >= 0; --i2)
17338 stream.point((point2 = points[i2])[0], point2[1]);
17340 interpolate(current.x, current.p.x, -1, stream);
17342 current = current.p;
17344 current = current.o;
17345 points = current.z;
17346 isSubject = !isSubject;
17347 } while (!current.v);
17351 function link(array2) {
17352 if (!(n2 = array2.length))
17354 var n2, i2 = 0, a = array2[0], b;
17355 while (++i2 < n2) {
17356 a.n = b = array2[i2];
17360 a.n = b = array2[0];
17364 // node_modules/d3-geo/src/polygonContains.js
17365 function longitude(point2) {
17366 return abs(point2[0]) <= pi ? point2[0] : sign(point2[0]) * ((abs(point2[0]) + pi) % tau - pi);
17368 function polygonContains_default(polygon2, point2) {
17369 var lambda = longitude(point2), phi = point2[1], sinPhi = sin(phi), normal = [sin(lambda), -cos(lambda), 0], angle2 = 0, winding = 0;
17370 var sum = new Adder();
17372 phi = halfPi + epsilon;
17373 else if (sinPhi === -1)
17374 phi = -halfPi - epsilon;
17375 for (var i2 = 0, n2 = polygon2.length; i2 < n2; ++i2) {
17376 if (!(m = (ring = polygon2[i2]).length))
17378 var ring, m, point0 = ring[m - 1], lambda04 = longitude(point0), phi02 = point0[1] / 2 + quarterPi, sinPhi03 = sin(phi02), cosPhi03 = cos(phi02);
17379 for (var j2 = 0; j2 < m; ++j2, lambda04 = lambda12, sinPhi03 = sinPhi1, cosPhi03 = cosPhi1, point0 = point1) {
17380 var point1 = ring[j2], lambda12 = longitude(point1), phi12 = point1[1] / 2 + quarterPi, sinPhi1 = sin(phi12), cosPhi1 = cos(phi12), delta = lambda12 - lambda04, sign2 = delta >= 0 ? 1 : -1, absDelta = sign2 * delta, antimeridian = absDelta > pi, k = sinPhi03 * sinPhi1;
17381 sum.add(atan2(k * sign2 * sin(absDelta), cosPhi03 * cosPhi1 + k * cos(absDelta)));
17382 angle2 += antimeridian ? delta + sign2 * tau : delta;
17383 if (antimeridian ^ lambda04 >= lambda ^ lambda12 >= lambda) {
17384 var arc = cartesianCross(cartesian(point0), cartesian(point1));
17385 cartesianNormalizeInPlace(arc);
17386 var intersection = cartesianCross(normal, arc);
17387 cartesianNormalizeInPlace(intersection);
17388 var phiArc = (antimeridian ^ delta >= 0 ? -1 : 1) * asin(intersection[2]);
17389 if (phi > phiArc || phi === phiArc && (arc[0] || arc[1])) {
17390 winding += antimeridian ^ delta >= 0 ? 1 : -1;
17395 return (angle2 < -epsilon || angle2 < epsilon && sum < -epsilon2) ^ winding & 1;
17398 // node_modules/d3-geo/src/clip/index.js
17399 function clip_default(pointVisible, clipLine, interpolate, start2) {
17400 return function(sink) {
17401 var line = clipLine(sink), ringBuffer = buffer_default(), ringSink = clipLine(ringBuffer), polygonStarted = false, polygon2, segments, ring;
17406 polygonStart: function() {
17407 clip.point = pointRing;
17408 clip.lineStart = ringStart;
17409 clip.lineEnd = ringEnd;
17413 polygonEnd: function() {
17414 clip.point = point2;
17415 clip.lineStart = lineStart;
17416 clip.lineEnd = lineEnd;
17417 segments = merge(segments);
17418 var startInside = polygonContains_default(polygon2, start2);
17419 if (segments.length) {
17420 if (!polygonStarted)
17421 sink.polygonStart(), polygonStarted = true;
17422 rejoin_default(segments, compareIntersection, startInside, interpolate, sink);
17423 } else if (startInside) {
17424 if (!polygonStarted)
17425 sink.polygonStart(), polygonStarted = true;
17427 interpolate(null, null, 1, sink);
17430 if (polygonStarted)
17431 sink.polygonEnd(), polygonStarted = false;
17432 segments = polygon2 = null;
17434 sphere: function() {
17435 sink.polygonStart();
17437 interpolate(null, null, 1, sink);
17442 function point2(lambda, phi) {
17443 if (pointVisible(lambda, phi))
17444 sink.point(lambda, phi);
17446 function pointLine(lambda, phi) {
17447 line.point(lambda, phi);
17449 function lineStart() {
17450 clip.point = pointLine;
17453 function lineEnd() {
17454 clip.point = point2;
17457 function pointRing(lambda, phi) {
17458 ring.push([lambda, phi]);
17459 ringSink.point(lambda, phi);
17461 function ringStart() {
17462 ringSink.lineStart();
17465 function ringEnd() {
17466 pointRing(ring[0][0], ring[0][1]);
17467 ringSink.lineEnd();
17468 var clean2 = ringSink.clean(), ringSegments = ringBuffer.result(), i2, n2 = ringSegments.length, m, segment, point3;
17470 polygon2.push(ring);
17475 segment = ringSegments[0];
17476 if ((m = segment.length - 1) > 0) {
17477 if (!polygonStarted)
17478 sink.polygonStart(), polygonStarted = true;
17480 for (i2 = 0; i2 < m; ++i2)
17481 sink.point((point3 = segment[i2])[0], point3[1]);
17486 if (n2 > 1 && clean2 & 2)
17487 ringSegments.push(ringSegments.pop().concat(ringSegments.shift()));
17488 segments.push(ringSegments.filter(validSegment));
17493 function validSegment(segment) {
17494 return segment.length > 1;
17496 function compareIntersection(a, b) {
17497 return ((a = a.x)[0] < 0 ? a[1] - halfPi - epsilon : halfPi - a[1]) - ((b = b.x)[0] < 0 ? b[1] - halfPi - epsilon : halfPi - b[1]);
17500 // node_modules/d3-geo/src/clip/antimeridian.js
17501 var antimeridian_default = clip_default(
17505 clipAntimeridianLine,
17506 clipAntimeridianInterpolate,
17509 function clipAntimeridianLine(stream) {
17510 var lambda04 = NaN, phi02 = NaN, sign0 = NaN, clean2;
17512 lineStart: function() {
17513 stream.lineStart();
17516 point: function(lambda12, phi12) {
17517 var sign1 = lambda12 > 0 ? pi : -pi, delta = abs(lambda12 - lambda04);
17518 if (abs(delta - pi) < epsilon) {
17519 stream.point(lambda04, phi02 = (phi02 + phi12) / 2 > 0 ? halfPi : -halfPi);
17520 stream.point(sign0, phi02);
17522 stream.lineStart();
17523 stream.point(sign1, phi02);
17524 stream.point(lambda12, phi02);
17526 } else if (sign0 !== sign1 && delta >= pi) {
17527 if (abs(lambda04 - sign0) < epsilon)
17528 lambda04 -= sign0 * epsilon;
17529 if (abs(lambda12 - sign1) < epsilon)
17530 lambda12 -= sign1 * epsilon;
17531 phi02 = clipAntimeridianIntersect(lambda04, phi02, lambda12, phi12);
17532 stream.point(sign0, phi02);
17534 stream.lineStart();
17535 stream.point(sign1, phi02);
17538 stream.point(lambda04 = lambda12, phi02 = phi12);
17541 lineEnd: function() {
17543 lambda04 = phi02 = NaN;
17545 clean: function() {
17550 function clipAntimeridianIntersect(lambda04, phi02, lambda12, phi12) {
17551 var cosPhi03, cosPhi1, sinLambda0Lambda1 = sin(lambda04 - lambda12);
17552 return abs(sinLambda0Lambda1) > epsilon ? atan((sin(phi02) * (cosPhi1 = cos(phi12)) * sin(lambda12) - sin(phi12) * (cosPhi03 = cos(phi02)) * sin(lambda04)) / (cosPhi03 * cosPhi1 * sinLambda0Lambda1)) : (phi02 + phi12) / 2;
17554 function clipAntimeridianInterpolate(from, to, direction, stream) {
17556 if (from == null) {
17557 phi = direction * halfPi;
17558 stream.point(-pi, phi);
17559 stream.point(0, phi);
17560 stream.point(pi, phi);
17561 stream.point(pi, 0);
17562 stream.point(pi, -phi);
17563 stream.point(0, -phi);
17564 stream.point(-pi, -phi);
17565 stream.point(-pi, 0);
17566 stream.point(-pi, phi);
17567 } else if (abs(from[0] - to[0]) > epsilon) {
17568 var lambda = from[0] < to[0] ? pi : -pi;
17569 phi = direction * lambda / 2;
17570 stream.point(-lambda, phi);
17571 stream.point(0, phi);
17572 stream.point(lambda, phi);
17574 stream.point(to[0], to[1]);
17578 // node_modules/d3-geo/src/clip/circle.js
17579 function circle_default(radius) {
17580 var cr = cos(radius), delta = 6 * radians, smallRadius = cr > 0, notHemisphere = abs(cr) > epsilon;
17581 function interpolate(from, to, direction, stream) {
17582 circleStream(stream, radius, delta, direction, from, to);
17584 function visible(lambda, phi) {
17585 return cos(lambda) * cos(phi) > cr;
17587 function clipLine(stream) {
17588 var point0, c0, v0, v00, clean2;
17590 lineStart: function() {
17594 point: function(lambda, phi) {
17595 var point1 = [lambda, phi], point2, v = visible(lambda, phi), c = smallRadius ? v ? 0 : code(lambda, phi) : v ? code(lambda + (lambda < 0 ? pi : -pi), phi) : 0;
17596 if (!point0 && (v00 = v0 = v))
17597 stream.lineStart();
17599 point2 = intersect2(point0, point1);
17600 if (!point2 || pointEqual_default(point0, point2) || pointEqual_default(point1, point2))
17606 stream.lineStart();
17607 point2 = intersect2(point1, point0);
17608 stream.point(point2[0], point2[1]);
17610 point2 = intersect2(point0, point1);
17611 stream.point(point2[0], point2[1], 2);
17615 } else if (notHemisphere && point0 && smallRadius ^ v) {
17617 if (!(c & c0) && (t = intersect2(point1, point0, true))) {
17620 stream.lineStart();
17621 stream.point(t[0][0], t[0][1]);
17622 stream.point(t[1][0], t[1][1]);
17625 stream.point(t[1][0], t[1][1]);
17627 stream.lineStart();
17628 stream.point(t[0][0], t[0][1], 3);
17632 if (v && (!point0 || !pointEqual_default(point0, point1))) {
17633 stream.point(point1[0], point1[1]);
17635 point0 = point1, v0 = v, c0 = c;
17637 lineEnd: function() {
17642 // Rejoin first and last segments if there were intersections and the first
17643 // and last points were visible.
17644 clean: function() {
17645 return clean2 | (v00 && v0) << 1;
17649 function intersect2(a, b, two) {
17650 var pa = cartesian(a), pb = cartesian(b);
17651 var n1 = [1, 0, 0], n2 = cartesianCross(pa, pb), n2n2 = cartesianDot(n2, n2), n1n2 = n2[0], determinant = n2n2 - n1n2 * n1n2;
17654 var c1 = cr * n2n2 / determinant, c2 = -cr * n1n2 / determinant, n1xn2 = cartesianCross(n1, n2), A = cartesianScale(n1, c1), B = cartesianScale(n2, c2);
17655 cartesianAddInPlace(A, B);
17656 var u = n1xn2, w = cartesianDot(A, u), uu = cartesianDot(u, u), t2 = w * w - uu * (cartesianDot(A, A) - 1);
17659 var t = sqrt(t2), q = cartesianScale(u, (-w - t) / uu);
17660 cartesianAddInPlace(q, A);
17664 var lambda04 = a[0], lambda12 = b[0], phi02 = a[1], phi12 = b[1], z;
17665 if (lambda12 < lambda04)
17666 z = lambda04, lambda04 = lambda12, lambda12 = z;
17667 var delta2 = lambda12 - lambda04, polar = abs(delta2 - pi) < epsilon, meridian = polar || delta2 < epsilon;
17668 if (!polar && phi12 < phi02)
17669 z = phi02, phi02 = phi12, phi12 = z;
17670 if (meridian ? polar ? phi02 + phi12 > 0 ^ q[1] < (abs(q[0] - lambda04) < epsilon ? phi02 : phi12) : phi02 <= q[1] && q[1] <= phi12 : delta2 > pi ^ (lambda04 <= q[0] && q[0] <= lambda12)) {
17671 var q1 = cartesianScale(u, (-w + t) / uu);
17672 cartesianAddInPlace(q1, A);
17673 return [q, spherical(q1)];
17676 function code(lambda, phi) {
17677 var r = smallRadius ? radius : pi - radius, code2 = 0;
17680 else if (lambda > r)
17688 return clip_default(visible, clipLine, interpolate, smallRadius ? [0, -radius] : [-pi, radius - pi]);
17691 // node_modules/d3-geo/src/clip/line.js
17692 function line_default(a, b, x05, y05, x12, y12) {
17693 var ax = a[0], ay = a[1], bx = b[0], by = b[1], t0 = 0, t1 = 1, dx = bx - ax, dy = by - ay, r;
17703 } else if (dx > 0) {
17718 } else if (dx > 0) {
17733 } else if (dy > 0) {
17748 } else if (dy > 0) {
17755 a[0] = ax + t0 * dx, a[1] = ay + t0 * dy;
17757 b[0] = ax + t1 * dx, b[1] = ay + t1 * dy;
17761 // node_modules/d3-geo/src/clip/rectangle.js
17763 var clipMin = -clipMax;
17764 function clipRectangle(x05, y05, x12, y12) {
17765 function visible(x, y) {
17766 return x05 <= x && x <= x12 && y05 <= y && y <= y12;
17768 function interpolate(from, to, direction, stream) {
17770 if (from == null || (a = corner(from, direction)) !== (a1 = corner(to, direction)) || comparePoint(from, to) < 0 ^ direction > 0) {
17772 stream.point(a === 0 || a === 3 ? x05 : x12, a > 1 ? y12 : y05);
17773 while ((a = (a + direction + 4) % 4) !== a1);
17775 stream.point(to[0], to[1]);
17778 function corner(p, direction) {
17779 return abs(p[0] - x05) < epsilon ? direction > 0 ? 0 : 3 : abs(p[0] - x12) < epsilon ? direction > 0 ? 2 : 1 : abs(p[1] - y05) < epsilon ? direction > 0 ? 1 : 0 : direction > 0 ? 3 : 2;
17781 function compareIntersection2(a, b) {
17782 return comparePoint(a.x, b.x);
17784 function comparePoint(a, b) {
17785 var ca = corner(a, 1), cb = corner(b, 1);
17786 return ca !== cb ? ca - cb : ca === 0 ? b[1] - a[1] : ca === 1 ? a[0] - b[0] : ca === 2 ? a[1] - b[1] : b[0] - a[0];
17788 return function(stream) {
17789 var activeStream = stream, bufferStream = buffer_default(), segments, polygon2, ring, x__, y__, v__, x_, y_, v_, first, clean2;
17797 function point2(x, y) {
17799 activeStream.point(x, y);
17801 function polygonInside() {
17803 for (var i2 = 0, n2 = polygon2.length; i2 < n2; ++i2) {
17804 for (var ring2 = polygon2[i2], j2 = 1, m = ring2.length, point3 = ring2[0], a0, a1, b0 = point3[0], b1 = point3[1]; j2 < m; ++j2) {
17805 a0 = b0, a1 = b1, point3 = ring2[j2], b0 = point3[0], b1 = point3[1];
17807 if (b1 > y12 && (b0 - a0) * (y12 - a1) > (b1 - a1) * (x05 - a0))
17810 if (b1 <= y12 && (b0 - a0) * (y12 - a1) < (b1 - a1) * (x05 - a0))
17817 function polygonStart() {
17818 activeStream = bufferStream, segments = [], polygon2 = [], clean2 = true;
17820 function polygonEnd() {
17821 var startInside = polygonInside(), cleanInside = clean2 && startInside, visible2 = (segments = merge(segments)).length;
17822 if (cleanInside || visible2) {
17823 stream.polygonStart();
17825 stream.lineStart();
17826 interpolate(null, null, 1, stream);
17830 rejoin_default(segments, compareIntersection2, startInside, interpolate, stream);
17832 stream.polygonEnd();
17834 activeStream = stream, segments = polygon2 = ring = null;
17836 function lineStart() {
17837 clipStream.point = linePoint2;
17839 polygon2.push(ring = []);
17844 function lineEnd() {
17846 linePoint2(x__, y__);
17848 bufferStream.rejoin();
17849 segments.push(bufferStream.result());
17851 clipStream.point = point2;
17853 activeStream.lineEnd();
17855 function linePoint2(x, y) {
17856 var v = visible(x, y);
17860 x__ = x, y__ = y, v__ = v;
17863 activeStream.lineStart();
17864 activeStream.point(x, y);
17868 activeStream.point(x, y);
17870 var a = [x_ = Math.max(clipMin, Math.min(clipMax, x_)), y_ = Math.max(clipMin, Math.min(clipMax, y_))], b = [x = Math.max(clipMin, Math.min(clipMax, x)), y = Math.max(clipMin, Math.min(clipMax, y))];
17871 if (line_default(a, b, x05, y05, x12, y12)) {
17873 activeStream.lineStart();
17874 activeStream.point(a[0], a[1]);
17876 activeStream.point(b[0], b[1]);
17878 activeStream.lineEnd();
17881 activeStream.lineStart();
17882 activeStream.point(x, y);
17887 x_ = x, y_ = y, v_ = v;
17893 // node_modules/d3-geo/src/length.js
17898 var lengthStream = {
17901 lineStart: lengthLineStart,
17903 polygonStart: noop,
17906 function lengthLineStart() {
17907 lengthStream.point = lengthPointFirst;
17908 lengthStream.lineEnd = lengthLineEnd;
17910 function lengthLineEnd() {
17911 lengthStream.point = lengthStream.lineEnd = noop;
17913 function lengthPointFirst(lambda, phi) {
17914 lambda *= radians, phi *= radians;
17915 lambda03 = lambda, sinPhi02 = sin(phi), cosPhi02 = cos(phi);
17916 lengthStream.point = lengthPoint;
17918 function lengthPoint(lambda, phi) {
17919 lambda *= radians, phi *= radians;
17920 var sinPhi = sin(phi), cosPhi = cos(phi), delta = abs(lambda - lambda03), cosDelta = cos(delta), sinDelta = sin(delta), x = cosPhi * sinDelta, y = cosPhi02 * sinPhi - sinPhi02 * cosPhi * cosDelta, z = sinPhi02 * sinPhi + cosPhi02 * cosPhi * cosDelta;
17921 lengthSum.add(atan2(sqrt(x * x + y * y), z));
17922 lambda03 = lambda, sinPhi02 = sinPhi, cosPhi02 = cosPhi;
17924 function length_default(object) {
17925 lengthSum = new Adder();
17926 stream_default(object, lengthStream);
17930 // node_modules/d3-geo/src/identity.js
17931 var identity_default = (x) => x;
17933 // node_modules/d3-geo/src/path/area.js
17934 var areaSum2 = new Adder();
17935 var areaRingSum2 = new Adder();
17940 var areaStream2 = {
17944 polygonStart: function() {
17945 areaStream2.lineStart = areaRingStart2;
17946 areaStream2.lineEnd = areaRingEnd2;
17948 polygonEnd: function() {
17949 areaStream2.lineStart = areaStream2.lineEnd = areaStream2.point = noop;
17950 areaSum2.add(abs(areaRingSum2));
17951 areaRingSum2 = new Adder();
17953 result: function() {
17954 var area = areaSum2 / 2;
17955 areaSum2 = new Adder();
17959 function areaRingStart2() {
17960 areaStream2.point = areaPointFirst2;
17962 function areaPointFirst2(x, y) {
17963 areaStream2.point = areaPoint2;
17964 x00 = x0 = x, y00 = y0 = y;
17966 function areaPoint2(x, y) {
17967 areaRingSum2.add(y0 * x - x0 * y);
17970 function areaRingEnd2() {
17971 areaPoint2(x00, y00);
17973 var area_default2 = areaStream2;
17975 // node_modules/d3-geo/src/path/bounds.js
17976 var x02 = Infinity;
17980 var boundsStream2 = {
17981 point: boundsPoint2,
17984 polygonStart: noop,
17986 result: function() {
17987 var bounds = [[x02, y02], [x1, y1]];
17988 x1 = y1 = -(y02 = x02 = Infinity);
17992 function boundsPoint2(x, y) {
18002 var bounds_default2 = boundsStream2;
18004 // node_modules/d3-geo/src/path/centroid.js
18018 var centroidStream = {
18019 point: centroidPoint,
18020 lineStart: centroidLineStart,
18021 lineEnd: centroidLineEnd,
18022 polygonStart: function() {
18023 centroidStream.lineStart = centroidRingStart;
18024 centroidStream.lineEnd = centroidRingEnd;
18026 polygonEnd: function() {
18027 centroidStream.point = centroidPoint;
18028 centroidStream.lineStart = centroidLineStart;
18029 centroidStream.lineEnd = centroidLineEnd;
18031 result: function() {
18032 var centroid = Z2 ? [X2 / Z2, Y2 / Z2] : Z1 ? [X1 / Z1, Y1 / Z1] : Z0 ? [X0 / Z0, Y0 / Z0] : [NaN, NaN];
18033 X0 = Y0 = Z0 = X1 = Y1 = Z1 = X2 = Y2 = Z2 = 0;
18037 function centroidPoint(x, y) {
18042 function centroidLineStart() {
18043 centroidStream.point = centroidPointFirstLine;
18045 function centroidPointFirstLine(x, y) {
18046 centroidStream.point = centroidPointLine;
18047 centroidPoint(x03 = x, y03 = y);
18049 function centroidPointLine(x, y) {
18050 var dx = x - x03, dy = y - y03, z = sqrt(dx * dx + dy * dy);
18051 X1 += z * (x03 + x) / 2;
18052 Y1 += z * (y03 + y) / 2;
18054 centroidPoint(x03 = x, y03 = y);
18056 function centroidLineEnd() {
18057 centroidStream.point = centroidPoint;
18059 function centroidRingStart() {
18060 centroidStream.point = centroidPointFirstRing;
18062 function centroidRingEnd() {
18063 centroidPointRing(x002, y002);
18065 function centroidPointFirstRing(x, y) {
18066 centroidStream.point = centroidPointRing;
18067 centroidPoint(x002 = x03 = x, y002 = y03 = y);
18069 function centroidPointRing(x, y) {
18070 var dx = x - x03, dy = y - y03, z = sqrt(dx * dx + dy * dy);
18071 X1 += z * (x03 + x) / 2;
18072 Y1 += z * (y03 + y) / 2;
18074 z = y03 * x - x03 * y;
18075 X2 += z * (x03 + x);
18076 Y2 += z * (y03 + y);
18078 centroidPoint(x03 = x, y03 = y);
18080 var centroid_default = centroidStream;
18082 // node_modules/d3-geo/src/path/context.js
18083 function PathContext(context) {
18084 this._context = context;
18086 PathContext.prototype = {
18088 pointRadius: function(_) {
18089 return this._radius = _, this;
18091 polygonStart: function() {
18094 polygonEnd: function() {
18097 lineStart: function() {
18100 lineEnd: function() {
18101 if (this._line === 0)
18102 this._context.closePath();
18105 point: function(x, y) {
18106 switch (this._point) {
18108 this._context.moveTo(x, y);
18113 this._context.lineTo(x, y);
18117 this._context.moveTo(x + this._radius, y);
18118 this._context.arc(x, y, this._radius, 0, tau);
18126 // node_modules/d3-geo/src/path/measure.js
18127 var lengthSum2 = new Adder();
18133 var lengthStream2 = {
18135 lineStart: function() {
18136 lengthStream2.point = lengthPointFirst2;
18138 lineEnd: function() {
18140 lengthPoint2(x003, y003);
18141 lengthStream2.point = noop;
18143 polygonStart: function() {
18146 polygonEnd: function() {
18149 result: function() {
18150 var length = +lengthSum2;
18151 lengthSum2 = new Adder();
18155 function lengthPointFirst2(x, y) {
18156 lengthStream2.point = lengthPoint2;
18157 x003 = x04 = x, y003 = y04 = y;
18159 function lengthPoint2(x, y) {
18160 x04 -= x, y04 -= y;
18161 lengthSum2.add(sqrt(x04 * x04 + y04 * y04));
18164 var measure_default = lengthStream2;
18166 // node_modules/d3-geo/src/path/string.js
18167 function PathString() {
18170 PathString.prototype = {
18172 _circle: circle(4.5),
18173 pointRadius: function(_) {
18174 if ((_ = +_) !== this._radius)
18175 this._radius = _, this._circle = null;
18178 polygonStart: function() {
18181 polygonEnd: function() {
18184 lineStart: function() {
18187 lineEnd: function() {
18188 if (this._line === 0)
18189 this._string.push("Z");
18192 point: function(x, y) {
18193 switch (this._point) {
18195 this._string.push("M", x, ",", y);
18200 this._string.push("L", x, ",", y);
18204 if (this._circle == null)
18205 this._circle = circle(this._radius);
18206 this._string.push("M", x, ",", y, this._circle);
18211 result: function() {
18212 if (this._string.length) {
18213 var result = this._string.join("");
18221 function circle(radius) {
18222 return "m0," + radius + "a" + radius + "," + radius + " 0 1,1 0," + -2 * radius + "a" + radius + "," + radius + " 0 1,1 0," + 2 * radius + "z";
18225 // node_modules/d3-geo/src/path/index.js
18226 function path_default(projection2, context) {
18227 var pointRadius = 4.5, projectionStream, contextStream;
18228 function path(object) {
18230 if (typeof pointRadius === "function")
18231 contextStream.pointRadius(+pointRadius.apply(this, arguments));
18232 stream_default(object, projectionStream(contextStream));
18234 return contextStream.result();
18236 path.area = function(object) {
18237 stream_default(object, projectionStream(area_default2));
18238 return area_default2.result();
18240 path.measure = function(object) {
18241 stream_default(object, projectionStream(measure_default));
18242 return measure_default.result();
18244 path.bounds = function(object) {
18245 stream_default(object, projectionStream(bounds_default2));
18246 return bounds_default2.result();
18248 path.centroid = function(object) {
18249 stream_default(object, projectionStream(centroid_default));
18250 return centroid_default.result();
18252 path.projection = function(_) {
18253 return arguments.length ? (projectionStream = _ == null ? (projection2 = null, identity_default) : (projection2 = _).stream, path) : projection2;
18255 path.context = function(_) {
18256 if (!arguments.length)
18258 contextStream = _ == null ? (context = null, new PathString()) : new PathContext(context = _);
18259 if (typeof pointRadius !== "function")
18260 contextStream.pointRadius(pointRadius);
18263 path.pointRadius = function(_) {
18264 if (!arguments.length)
18265 return pointRadius;
18266 pointRadius = typeof _ === "function" ? _ : (contextStream.pointRadius(+_), +_);
18269 return path.projection(projection2).context(context);
18272 // node_modules/d3-geo/src/transform.js
18273 function transform_default(methods2) {
18275 stream: transformer(methods2)
18278 function transformer(methods2) {
18279 return function(stream) {
18280 var s = new TransformStream();
18281 for (var key in methods2)
18282 s[key] = methods2[key];
18287 function TransformStream() {
18289 TransformStream.prototype = {
18290 constructor: TransformStream,
18291 point: function(x, y) {
18292 this.stream.point(x, y);
18294 sphere: function() {
18295 this.stream.sphere();
18297 lineStart: function() {
18298 this.stream.lineStart();
18300 lineEnd: function() {
18301 this.stream.lineEnd();
18303 polygonStart: function() {
18304 this.stream.polygonStart();
18306 polygonEnd: function() {
18307 this.stream.polygonEnd();
18311 // node_modules/d3-geo/src/projection/fit.js
18312 function fit(projection2, fitBounds, object) {
18313 var clip = projection2.clipExtent && projection2.clipExtent();
18314 projection2.scale(150).translate([0, 0]);
18316 projection2.clipExtent(null);
18317 stream_default(object, projection2.stream(bounds_default2));
18318 fitBounds(bounds_default2.result());
18320 projection2.clipExtent(clip);
18321 return projection2;
18323 function fitExtent(projection2, extent, object) {
18324 return fit(projection2, function(b) {
18325 var w = extent[1][0] - extent[0][0], h = extent[1][1] - extent[0][1], k = Math.min(w / (b[1][0] - b[0][0]), h / (b[1][1] - b[0][1])), x = +extent[0][0] + (w - k * (b[1][0] + b[0][0])) / 2, y = +extent[0][1] + (h - k * (b[1][1] + b[0][1])) / 2;
18326 projection2.scale(150 * k).translate([x, y]);
18329 function fitSize(projection2, size, object) {
18330 return fitExtent(projection2, [[0, 0], size], object);
18332 function fitWidth(projection2, width, object) {
18333 return fit(projection2, function(b) {
18334 var w = +width, k = w / (b[1][0] - b[0][0]), x = (w - k * (b[1][0] + b[0][0])) / 2, y = -k * b[0][1];
18335 projection2.scale(150 * k).translate([x, y]);
18338 function fitHeight(projection2, height, object) {
18339 return fit(projection2, function(b) {
18340 var h = +height, k = h / (b[1][1] - b[0][1]), x = -k * b[0][0], y = (h - k * (b[1][1] + b[0][1])) / 2;
18341 projection2.scale(150 * k).translate([x, y]);
18345 // node_modules/d3-geo/src/projection/resample.js
18347 var cosMinDistance = cos(30 * radians);
18348 function resample_default(project, delta2) {
18349 return +delta2 ? resample(project, delta2) : resampleNone(project);
18351 function resampleNone(project) {
18352 return transformer({
18353 point: function(x, y) {
18355 this.stream.point(x[0], x[1]);
18359 function resample(project, delta2) {
18360 function resampleLineTo(x05, y05, lambda04, a0, b0, c0, x12, y12, lambda12, a1, b1, c1, depth, stream) {
18361 var dx = x12 - x05, dy = y12 - y05, d2 = dx * dx + dy * dy;
18362 if (d2 > 4 * delta2 && depth--) {
18363 var a = a0 + a1, b = b0 + b1, c = c0 + c1, m = sqrt(a * a + b * b + c * c), phi2 = asin(c /= m), lambda22 = abs(abs(c) - 1) < epsilon || abs(lambda04 - lambda12) < epsilon ? (lambda04 + lambda12) / 2 : atan2(b, a), p = project(lambda22, phi2), x2 = p[0], y2 = p[1], dx2 = x2 - x05, dy2 = y2 - y05, dz = dy * dx2 - dx * dy2;
18364 if (dz * dz / d2 > delta2 || abs((dx * dx2 + dy * dy2) / d2 - 0.5) > 0.3 || a0 * a1 + b0 * b1 + c0 * c1 < cosMinDistance) {
18365 resampleLineTo(x05, y05, lambda04, a0, b0, c0, x2, y2, lambda22, a /= m, b /= m, c, depth, stream);
18366 stream.point(x2, y2);
18367 resampleLineTo(x2, y2, lambda22, a, b, c, x12, y12, lambda12, a1, b1, c1, depth, stream);
18371 return function(stream) {
18372 var lambda003, x004, y004, a00, b00, c00, lambda04, x05, y05, a0, b0, c0;
18373 var resampleStream = {
18377 polygonStart: function() {
18378 stream.polygonStart();
18379 resampleStream.lineStart = ringStart;
18381 polygonEnd: function() {
18382 stream.polygonEnd();
18383 resampleStream.lineStart = lineStart;
18386 function point2(x, y) {
18388 stream.point(x[0], x[1]);
18390 function lineStart() {
18392 resampleStream.point = linePoint2;
18393 stream.lineStart();
18395 function linePoint2(lambda, phi) {
18396 var c = cartesian([lambda, phi]), p = project(lambda, phi);
18397 resampleLineTo(x05, y05, lambda04, a0, b0, c0, x05 = p[0], y05 = p[1], lambda04 = lambda, a0 = c[0], b0 = c[1], c0 = c[2], maxDepth, stream);
18398 stream.point(x05, y05);
18400 function lineEnd() {
18401 resampleStream.point = point2;
18404 function ringStart() {
18406 resampleStream.point = ringPoint;
18407 resampleStream.lineEnd = ringEnd;
18409 function ringPoint(lambda, phi) {
18410 linePoint2(lambda003 = lambda, phi), x004 = x05, y004 = y05, a00 = a0, b00 = b0, c00 = c0;
18411 resampleStream.point = linePoint2;
18413 function ringEnd() {
18414 resampleLineTo(x05, y05, lambda04, a0, b0, c0, x004, y004, lambda003, a00, b00, c00, maxDepth, stream);
18415 resampleStream.lineEnd = lineEnd;
18418 return resampleStream;
18422 // node_modules/d3-geo/src/projection/index.js
18423 var transformRadians = transformer({
18424 point: function(x, y) {
18425 this.stream.point(x * radians, y * radians);
18428 function transformRotate(rotate) {
18429 return transformer({
18430 point: function(x, y) {
18431 var r = rotate(x, y);
18432 return this.stream.point(r[0], r[1]);
18436 function scaleTranslate(k, dx, dy, sx, sy) {
18437 function transform2(x, y) {
18440 return [dx + k * x, dy - k * y];
18442 transform2.invert = function(x, y) {
18443 return [(x - dx) / k * sx, (dy - y) / k * sy];
18447 function scaleTranslateRotate(k, dx, dy, sx, sy, alpha) {
18449 return scaleTranslate(k, dx, dy, sx, sy);
18450 var cosAlpha = cos(alpha), sinAlpha = sin(alpha), a = cosAlpha * k, b = sinAlpha * k, ai = cosAlpha / k, bi = sinAlpha / k, ci = (sinAlpha * dy - cosAlpha * dx) / k, fi = (sinAlpha * dx + cosAlpha * dy) / k;
18451 function transform2(x, y) {
18454 return [a * x - b * y + dx, dy - b * x - a * y];
18456 transform2.invert = function(x, y) {
18457 return [sx * (ai * x - bi * y + ci), sy * (fi - bi * x - ai * y)];
18461 function projection(project) {
18462 return projectionMutator(function() {
18466 function projectionMutator(projectAt) {
18467 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;
18468 function projection2(point2) {
18469 return projectRotateTransform(point2[0] * radians, point2[1] * radians);
18471 function invert(point2) {
18472 point2 = projectRotateTransform.invert(point2[0], point2[1]);
18473 return point2 && [point2[0] * degrees, point2[1] * degrees];
18475 projection2.stream = function(stream) {
18476 return cache && cacheStream === stream ? cache : cache = transformRadians(transformRotate(rotate)(preclip(projectResample(postclip(cacheStream = stream)))));
18478 projection2.preclip = function(_) {
18479 return arguments.length ? (preclip = _, theta = void 0, reset()) : preclip;
18481 projection2.postclip = function(_) {
18482 return arguments.length ? (postclip = _, x05 = y05 = x12 = y12 = null, reset()) : postclip;
18484 projection2.clipAngle = function(_) {
18485 return arguments.length ? (preclip = +_ ? circle_default(theta = _ * radians) : (theta = null, antimeridian_default), reset()) : theta * degrees;
18487 projection2.clipExtent = function(_) {
18488 return arguments.length ? (postclip = _ == null ? (x05 = y05 = x12 = y12 = null, identity_default) : clipRectangle(x05 = +_[0][0], y05 = +_[0][1], x12 = +_[1][0], y12 = +_[1][1]), reset()) : x05 == null ? null : [[x05, y05], [x12, y12]];
18490 projection2.scale = function(_) {
18491 return arguments.length ? (k = +_, recenter()) : k;
18493 projection2.translate = function(_) {
18494 return arguments.length ? (x = +_[0], y = +_[1], recenter()) : [x, y];
18496 projection2.center = function(_) {
18497 return arguments.length ? (lambda = _[0] % 360 * radians, phi = _[1] % 360 * radians, recenter()) : [lambda * degrees, phi * degrees];
18499 projection2.rotate = function(_) {
18500 return arguments.length ? (deltaLambda = _[0] % 360 * radians, deltaPhi = _[1] % 360 * radians, deltaGamma = _.length > 2 ? _[2] % 360 * radians : 0, recenter()) : [deltaLambda * degrees, deltaPhi * degrees, deltaGamma * degrees];
18502 projection2.angle = function(_) {
18503 return arguments.length ? (alpha = _ % 360 * radians, recenter()) : alpha * degrees;
18505 projection2.reflectX = function(_) {
18506 return arguments.length ? (sx = _ ? -1 : 1, recenter()) : sx < 0;
18508 projection2.reflectY = function(_) {
18509 return arguments.length ? (sy = _ ? -1 : 1, recenter()) : sy < 0;
18511 projection2.precision = function(_) {
18512 return arguments.length ? (projectResample = resample_default(projectTransform, delta2 = _ * _), reset()) : sqrt(delta2);
18514 projection2.fitExtent = function(extent, object) {
18515 return fitExtent(projection2, extent, object);
18517 projection2.fitSize = function(size, object) {
18518 return fitSize(projection2, size, object);
18520 projection2.fitWidth = function(width, object) {
18521 return fitWidth(projection2, width, object);
18523 projection2.fitHeight = function(height, object) {
18524 return fitHeight(projection2, height, object);
18526 function recenter() {
18527 var center = scaleTranslateRotate(k, 0, 0, sx, sy, alpha).apply(null, project(lambda, phi)), transform2 = scaleTranslateRotate(k, x - center[0], y - center[1], sx, sy, alpha);
18528 rotate = rotateRadians(deltaLambda, deltaPhi, deltaGamma);
18529 projectTransform = compose_default(project, transform2);
18530 projectRotateTransform = compose_default(rotate, projectTransform);
18531 projectResample = resample_default(projectTransform, delta2);
18535 cache = cacheStream = null;
18536 return projection2;
18538 return function() {
18539 project = projectAt.apply(this, arguments);
18540 projection2.invert = project.invert && invert;
18545 // node_modules/d3-geo/src/projection/mercator.js
18546 function mercatorRaw(lambda, phi) {
18547 return [lambda, log(tan((halfPi + phi) / 2))];
18549 mercatorRaw.invert = function(x, y) {
18550 return [x, 2 * atan(exp(y)) - halfPi];
18552 function mercator_default() {
18553 return mercatorProjection(mercatorRaw).scale(961 / tau);
18555 function mercatorProjection(project) {
18556 var m = projection(project), center = m.center, scale = m.scale, translate = m.translate, clipExtent = m.clipExtent, x05 = null, y05, x12, y12;
18557 m.scale = function(_) {
18558 return arguments.length ? (scale(_), reclip()) : scale();
18560 m.translate = function(_) {
18561 return arguments.length ? (translate(_), reclip()) : translate();
18563 m.center = function(_) {
18564 return arguments.length ? (center(_), reclip()) : center();
18566 m.clipExtent = function(_) {
18567 return arguments.length ? (_ == null ? x05 = y05 = x12 = y12 = null : (x05 = +_[0][0], y05 = +_[0][1], x12 = +_[1][0], y12 = +_[1][1]), reclip()) : x05 == null ? null : [[x05, y05], [x12, y12]];
18569 function reclip() {
18570 var k = pi * scale(), t = m(rotation_default(m.rotate()).invert([0, 0]));
18571 return clipExtent(x05 == null ? [[t[0] - k, t[1] - k], [t[0] + k, t[1] + k]] : project === mercatorRaw ? [[Math.max(t[0] - k, x05), y05], [Math.min(t[0] + k, x12), y12]] : [[x05, Math.max(t[1] - k, y05)], [x12, Math.min(t[1] + k, y12)]]);
18576 // node_modules/d3-geo/src/projection/identity.js
18577 function identity_default2() {
18578 var k = 1, tx = 0, ty = 0, sx = 1, sy = 1, alpha = 0, ca, sa, x05 = null, y05, x12, y12, kx = 1, ky = 1, transform2 = transformer({
18579 point: function(x, y) {
18580 var p = projection2([x, y]);
18581 this.stream.point(p[0], p[1]);
18583 }), postclip = identity_default, cache, cacheStream;
18587 cache = cacheStream = null;
18588 return projection2;
18590 function projection2(p) {
18591 var x = p[0] * kx, y = p[1] * ky;
18593 var t = y * ca - x * sa;
18594 x = x * ca + y * sa;
18597 return [x + tx, y + ty];
18599 projection2.invert = function(p) {
18600 var x = p[0] - tx, y = p[1] - ty;
18602 var t = y * ca + x * sa;
18603 x = x * ca - y * sa;
18606 return [x / kx, y / ky];
18608 projection2.stream = function(stream) {
18609 return cache && cacheStream === stream ? cache : cache = transform2(postclip(cacheStream = stream));
18611 projection2.postclip = function(_) {
18612 return arguments.length ? (postclip = _, x05 = y05 = x12 = y12 = null, reset()) : postclip;
18614 projection2.clipExtent = function(_) {
18615 return arguments.length ? (postclip = _ == null ? (x05 = y05 = x12 = y12 = null, identity_default) : clipRectangle(x05 = +_[0][0], y05 = +_[0][1], x12 = +_[1][0], y12 = +_[1][1]), reset()) : x05 == null ? null : [[x05, y05], [x12, y12]];
18617 projection2.scale = function(_) {
18618 return arguments.length ? (k = +_, reset()) : k;
18620 projection2.translate = function(_) {
18621 return arguments.length ? (tx = +_[0], ty = +_[1], reset()) : [tx, ty];
18623 projection2.angle = function(_) {
18624 return arguments.length ? (alpha = _ % 360 * radians, sa = sin(alpha), ca = cos(alpha), reset()) : alpha * degrees;
18626 projection2.reflectX = function(_) {
18627 return arguments.length ? (sx = _ ? -1 : 1, reset()) : sx < 0;
18629 projection2.reflectY = function(_) {
18630 return arguments.length ? (sy = _ ? -1 : 1, reset()) : sy < 0;
18632 projection2.fitExtent = function(extent, object) {
18633 return fitExtent(projection2, extent, object);
18635 projection2.fitSize = function(size, object) {
18636 return fitSize(projection2, size, object);
18638 projection2.fitWidth = function(width, object) {
18639 return fitWidth(projection2, width, object);
18641 projection2.fitHeight = function(height, object) {
18642 return fitHeight(projection2, height, object);
18644 return projection2;
18647 // modules/geo/geo.js
18648 var TAU = 2 * Math.PI;
18649 var EQUATORIAL_RADIUS = 6356752314245179e-9;
18650 var POLAR_RADIUS = 6378137;
18651 function geoLatToMeters(dLat) {
18652 return dLat * (TAU * POLAR_RADIUS / 360);
18654 function geoLonToMeters(dLon, atLat) {
18655 return Math.abs(atLat) >= 90 ? 0 : dLon * (TAU * EQUATORIAL_RADIUS / 360) * Math.abs(Math.cos(atLat * (Math.PI / 180)));
18657 function geoMetersToLat(m) {
18658 return m / (TAU * POLAR_RADIUS / 360);
18660 function geoMetersToLon(m, atLat) {
18661 return Math.abs(atLat) >= 90 ? 0 : m / (TAU * EQUATORIAL_RADIUS / 360) / Math.abs(Math.cos(atLat * (Math.PI / 180)));
18663 function geoMetersToOffset(meters, tileSize) {
18664 tileSize = tileSize || 256;
18666 meters[0] * tileSize / (TAU * EQUATORIAL_RADIUS),
18667 -meters[1] * tileSize / (TAU * POLAR_RADIUS)
18670 function geoOffsetToMeters(offset, tileSize) {
18671 tileSize = tileSize || 256;
18673 offset[0] * TAU * EQUATORIAL_RADIUS / tileSize,
18674 -offset[1] * TAU * POLAR_RADIUS / tileSize
18677 function geoSphericalDistance(a, b) {
18678 var x = geoLonToMeters(a[0] - b[0], (a[1] + b[1]) / 2);
18679 var y = geoLatToMeters(a[1] - b[1]);
18680 return Math.sqrt(x * x + y * y);
18682 function geoScaleToZoom(k, tileSize) {
18683 tileSize = tileSize || 256;
18684 var log2ts = Math.log(tileSize) * Math.LOG2E;
18685 return Math.log(k * TAU) / Math.LN2 - log2ts;
18687 function geoZoomToScale(z, tileSize) {
18688 tileSize = tileSize || 256;
18689 return tileSize * Math.pow(2, z) / TAU;
18691 function geoSphericalClosestNode(nodes, point2) {
18692 var minDistance = Infinity, distance;
18694 for (var i2 in nodes) {
18695 distance = geoSphericalDistance(nodes[i2].loc, point2);
18696 if (distance < minDistance) {
18697 minDistance = distance;
18701 if (indexOfMin !== void 0) {
18702 return { index: indexOfMin, distance: minDistance, node: nodes[indexOfMin] };
18708 // modules/geo/extent.js
18709 function geoExtent(min3, max3) {
18710 if (!(this instanceof geoExtent)) {
18711 return new geoExtent(min3, max3);
18712 } else if (min3 instanceof geoExtent) {
18714 } else if (min3 && min3.length === 2 && min3[0].length === 2 && min3[1].length === 2) {
18718 this[0] = min3 || [Infinity, Infinity];
18719 this[1] = max3 || min3 || [-Infinity, -Infinity];
18722 geoExtent.prototype = new Array(2);
18723 Object.assign(geoExtent.prototype, {
18724 equals: function(obj) {
18725 return this[0][0] === obj[0][0] && this[0][1] === obj[0][1] && this[1][0] === obj[1][0] && this[1][1] === obj[1][1];
18727 extend: function(obj) {
18728 if (!(obj instanceof geoExtent))
18729 obj = new geoExtent(obj);
18731 [Math.min(obj[0][0], this[0][0]), Math.min(obj[0][1], this[0][1])],
18732 [Math.max(obj[1][0], this[1][0]), Math.max(obj[1][1], this[1][1])]
18735 _extend: function(extent) {
18736 this[0][0] = Math.min(extent[0][0], this[0][0]);
18737 this[0][1] = Math.min(extent[0][1], this[0][1]);
18738 this[1][0] = Math.max(extent[1][0], this[1][0]);
18739 this[1][1] = Math.max(extent[1][1], this[1][1]);
18742 return Math.abs((this[1][0] - this[0][0]) * (this[1][1] - this[0][1]));
18744 center: function() {
18745 return [(this[0][0] + this[1][0]) / 2, (this[0][1] + this[1][1]) / 2];
18747 rectangle: function() {
18748 return [this[0][0], this[0][1], this[1][0], this[1][1]];
18751 return { minX: this[0][0], minY: this[0][1], maxX: this[1][0], maxY: this[1][1] };
18753 polygon: function() {
18755 [this[0][0], this[0][1]],
18756 [this[0][0], this[1][1]],
18757 [this[1][0], this[1][1]],
18758 [this[1][0], this[0][1]],
18759 [this[0][0], this[0][1]]
18762 contains: function(obj) {
18763 if (!(obj instanceof geoExtent))
18764 obj = new geoExtent(obj);
18765 return obj[0][0] >= this[0][0] && obj[0][1] >= this[0][1] && obj[1][0] <= this[1][0] && obj[1][1] <= this[1][1];
18767 intersects: function(obj) {
18768 if (!(obj instanceof geoExtent))
18769 obj = new geoExtent(obj);
18770 return obj[0][0] <= this[1][0] && obj[0][1] <= this[1][1] && obj[1][0] >= this[0][0] && obj[1][1] >= this[0][1];
18772 intersection: function(obj) {
18773 if (!this.intersects(obj))
18774 return new geoExtent();
18775 return new geoExtent(
18776 [Math.max(obj[0][0], this[0][0]), Math.max(obj[0][1], this[0][1])],
18777 [Math.min(obj[1][0], this[1][0]), Math.min(obj[1][1], this[1][1])]
18780 percentContainedIn: function(obj) {
18781 if (!(obj instanceof geoExtent))
18782 obj = new geoExtent(obj);
18783 var a1 = this.intersection(obj).area();
18784 var a2 = this.area();
18785 if (a1 === Infinity || a2 === Infinity) {
18787 } else if (a1 === 0 || a2 === 0) {
18788 if (obj.contains(this)) {
18796 padByMeters: function(meters) {
18797 var dLat = geoMetersToLat(meters);
18798 var dLon = geoMetersToLon(meters, this.center()[1]);
18800 [this[0][0] - dLon, this[0][1] - dLat],
18801 [this[1][0] + dLon, this[1][1] + dLat]
18804 toParam: function() {
18805 return this.rectangle().join(",");
18809 // node_modules/d3-polygon/src/area.js
18810 function area_default3(polygon2) {
18811 var i2 = -1, n2 = polygon2.length, a, b = polygon2[n2 - 1], area = 0;
18812 while (++i2 < n2) {
18815 area += a[1] * b[0] - a[0] * b[1];
18820 // node_modules/d3-polygon/src/centroid.js
18821 function centroid_default2(polygon2) {
18822 var i2 = -1, n2 = polygon2.length, x = 0, y = 0, a, b = polygon2[n2 - 1], c, k = 0;
18823 while (++i2 < n2) {
18826 k += c = a[0] * b[1] - b[0] * a[1];
18827 x += (a[0] + b[0]) * c;
18828 y += (a[1] + b[1]) * c;
18830 return k *= 3, [x / k, y / k];
18833 // node_modules/d3-polygon/src/cross.js
18834 function cross_default(a, b, c) {
18835 return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]);
18838 // node_modules/d3-polygon/src/hull.js
18839 function lexicographicOrder(a, b) {
18840 return a[0] - b[0] || a[1] - b[1];
18842 function computeUpperHullIndexes(points) {
18843 const n2 = points.length, indexes = [0, 1];
18845 for (i2 = 2; i2 < n2; ++i2) {
18846 while (size > 1 && cross_default(points[indexes[size - 2]], points[indexes[size - 1]], points[i2]) <= 0)
18848 indexes[size++] = i2;
18850 return indexes.slice(0, size);
18852 function hull_default(points) {
18853 if ((n2 = points.length) < 3)
18855 var i2, n2, sortedPoints = new Array(n2), flippedPoints = new Array(n2);
18856 for (i2 = 0; i2 < n2; ++i2)
18857 sortedPoints[i2] = [+points[i2][0], +points[i2][1], i2];
18858 sortedPoints.sort(lexicographicOrder);
18859 for (i2 = 0; i2 < n2; ++i2)
18860 flippedPoints[i2] = [sortedPoints[i2][0], -sortedPoints[i2][1]];
18861 var upperIndexes = computeUpperHullIndexes(sortedPoints), lowerIndexes = computeUpperHullIndexes(flippedPoints);
18862 var skipLeft = lowerIndexes[0] === upperIndexes[0], skipRight = lowerIndexes[lowerIndexes.length - 1] === upperIndexes[upperIndexes.length - 1], hull = [];
18863 for (i2 = upperIndexes.length - 1; i2 >= 0; --i2)
18864 hull.push(points[sortedPoints[upperIndexes[i2]][2]]);
18865 for (i2 = +skipLeft; i2 < lowerIndexes.length - skipRight; ++i2)
18866 hull.push(points[sortedPoints[lowerIndexes[i2]][2]]);
18870 // modules/geo/vector.js
18871 function geoVecEqual(a, b, epsilon3) {
18873 return Math.abs(a[0] - b[0]) <= epsilon3 && Math.abs(a[1] - b[1]) <= epsilon3;
18875 return a[0] === b[0] && a[1] === b[1];
18878 function geoVecAdd(a, b) {
18879 return [a[0] + b[0], a[1] + b[1]];
18881 function geoVecSubtract(a, b) {
18882 return [a[0] - b[0], a[1] - b[1]];
18884 function geoVecScale(a, mag) {
18885 return [a[0] * mag, a[1] * mag];
18887 function geoVecFloor(a) {
18888 return [Math.floor(a[0]), Math.floor(a[1])];
18890 function geoVecInterp(a, b, t) {
18892 a[0] + (b[0] - a[0]) * t,
18893 a[1] + (b[1] - a[1]) * t
18896 function geoVecLength(a, b) {
18897 return Math.sqrt(geoVecLengthSquare(a, b));
18899 function geoVecLengthSquare(a, b) {
18901 var x = a[0] - b[0];
18902 var y = a[1] - b[1];
18903 return x * x + y * y;
18905 function geoVecNormalize(a) {
18906 var length = Math.sqrt(a[0] * a[0] + a[1] * a[1]);
18907 if (length !== 0) {
18908 return geoVecScale(a, 1 / length);
18912 function geoVecAngle(a, b) {
18913 return Math.atan2(b[1] - a[1], b[0] - a[0]);
18915 function geoVecDot(a, b, origin) {
18916 origin = origin || [0, 0];
18917 var p = geoVecSubtract(a, origin);
18918 var q = geoVecSubtract(b, origin);
18919 return p[0] * q[0] + p[1] * q[1];
18921 function geoVecNormalizedDot(a, b, origin) {
18922 origin = origin || [0, 0];
18923 var p = geoVecNormalize(geoVecSubtract(a, origin));
18924 var q = geoVecNormalize(geoVecSubtract(b, origin));
18925 return geoVecDot(p, q);
18927 function geoVecCross(a, b, origin) {
18928 origin = origin || [0, 0];
18929 var p = geoVecSubtract(a, origin);
18930 var q = geoVecSubtract(b, origin);
18931 return p[0] * q[1] - p[1] * q[0];
18933 function geoVecProject(a, points) {
18934 var min3 = Infinity;
18937 for (var i2 = 0; i2 < points.length - 1; i2++) {
18938 var o = points[i2];
18939 var s = geoVecSubtract(points[i2 + 1], o);
18940 var v = geoVecSubtract(a, o);
18941 var proj = geoVecDot(v, s) / geoVecDot(s, s);
18945 } else if (proj > 1) {
18946 p = points[i2 + 1];
18948 p = [o[0] + proj * s[0], o[1] + proj * s[1]];
18950 var dist = geoVecLength(p, a);
18957 if (idx !== void 0) {
18958 return { index: idx, distance: min3, target };
18964 // modules/geo/geom.js
18965 function geoAngle(a, b, projection2) {
18966 return geoVecAngle(projection2(a.loc), projection2(b.loc));
18968 function geoEdgeEqual(a, b) {
18969 return a[0] === b[0] && a[1] === b[1] || a[0] === b[1] && a[1] === b[0];
18971 function geoRotate(points, angle2, around) {
18972 return points.map(function(point2) {
18973 var radial = geoVecSubtract(point2, around);
18975 radial[0] * Math.cos(angle2) - radial[1] * Math.sin(angle2) + around[0],
18976 radial[0] * Math.sin(angle2) + radial[1] * Math.cos(angle2) + around[1]
18980 function geoChooseEdge(nodes, point2, projection2, activeID) {
18981 var dist = geoVecLength;
18982 var points = nodes.map(function(n2) {
18983 return projection2(n2.loc);
18985 var ids = nodes.map(function(n2) {
18988 var min3 = Infinity;
18991 for (var i2 = 0; i2 < points.length - 1; i2++) {
18992 if (ids[i2] === activeID || ids[i2 + 1] === activeID)
18994 var o = points[i2];
18995 var s = geoVecSubtract(points[i2 + 1], o);
18996 var v = geoVecSubtract(point2, o);
18997 var proj = geoVecDot(v, s) / geoVecDot(s, s);
19001 } else if (proj > 1) {
19002 p = points[i2 + 1];
19004 p = [o[0] + proj * s[0], o[1] + proj * s[1]];
19006 var d = dist(p, point2);
19010 loc = projection2.invert(p);
19013 if (idx !== void 0) {
19014 return { index: idx, distance: min3, loc };
19019 function geoHasLineIntersections(activeNodes, inactiveNodes, activeID) {
19021 var inactives = [];
19022 var j2, k, n1, n2, segment;
19023 for (j2 = 0; j2 < activeNodes.length - 1; j2++) {
19024 n1 = activeNodes[j2];
19025 n2 = activeNodes[j2 + 1];
19026 segment = [n1.loc, n2.loc];
19027 if (n1.id === activeID || n2.id === activeID) {
19028 actives.push(segment);
19031 for (j2 = 0; j2 < inactiveNodes.length - 1; j2++) {
19032 n1 = inactiveNodes[j2];
19033 n2 = inactiveNodes[j2 + 1];
19034 segment = [n1.loc, n2.loc];
19035 inactives.push(segment);
19037 for (j2 = 0; j2 < actives.length; j2++) {
19038 for (k = 0; k < inactives.length; k++) {
19039 var p = actives[j2];
19040 var q = inactives[k];
19041 var hit = geoLineIntersection(p, q);
19049 function geoHasSelfIntersections(nodes, activeID) {
19051 var inactives = [];
19053 for (j2 = 0; j2 < nodes.length - 1; j2++) {
19054 var n1 = nodes[j2];
19055 var n2 = nodes[j2 + 1];
19056 var segment = [n1.loc, n2.loc];
19057 if (n1.id === activeID || n2.id === activeID) {
19058 actives.push(segment);
19060 inactives.push(segment);
19063 for (j2 = 0; j2 < actives.length; j2++) {
19064 for (k = 0; k < inactives.length; k++) {
19065 var p = actives[j2];
19066 var q = inactives[k];
19067 if (geoVecEqual(p[1], q[0]) || geoVecEqual(p[0], q[1]) || geoVecEqual(p[0], q[0]) || geoVecEqual(p[1], q[1])) {
19070 var hit = geoLineIntersection(p, q);
19072 var epsilon3 = 1e-8;
19073 if (geoVecEqual(p[1], hit, epsilon3) || geoVecEqual(p[0], hit, epsilon3) || geoVecEqual(q[1], hit, epsilon3) || geoVecEqual(q[0], hit, epsilon3)) {
19083 function geoLineIntersection(a, b) {
19084 var p = [a[0][0], a[0][1]];
19085 var p2 = [a[1][0], a[1][1]];
19086 var q = [b[0][0], b[0][1]];
19087 var q2 = [b[1][0], b[1][1]];
19088 var r = geoVecSubtract(p2, p);
19089 var s = geoVecSubtract(q2, q);
19090 var uNumerator = geoVecCross(geoVecSubtract(q, p), r);
19091 var denominator = geoVecCross(r, s);
19092 if (uNumerator && denominator) {
19093 var u = uNumerator / denominator;
19094 var t = geoVecCross(geoVecSubtract(q, p), s) / denominator;
19095 if (t >= 0 && t <= 1 && u >= 0 && u <= 1) {
19096 return geoVecInterp(p, p2, t);
19101 function geoPathIntersections(path1, path2) {
19102 var intersections = [];
19103 for (var i2 = 0; i2 < path1.length - 1; i2++) {
19104 for (var j2 = 0; j2 < path2.length - 1; j2++) {
19105 var a = [path1[i2], path1[i2 + 1]];
19106 var b = [path2[j2], path2[j2 + 1]];
19107 var hit = geoLineIntersection(a, b);
19109 intersections.push(hit);
19113 return intersections;
19115 function geoPathHasIntersections(path1, path2) {
19116 for (var i2 = 0; i2 < path1.length - 1; i2++) {
19117 for (var j2 = 0; j2 < path2.length - 1; j2++) {
19118 var a = [path1[i2], path1[i2 + 1]];
19119 var b = [path2[j2], path2[j2 + 1]];
19120 var hit = geoLineIntersection(a, b);
19128 function geoPointInPolygon(point2, polygon2) {
19131 var inside = false;
19132 for (var i2 = 0, j2 = polygon2.length - 1; i2 < polygon2.length; j2 = i2++) {
19133 var xi = polygon2[i2][0];
19134 var yi = polygon2[i2][1];
19135 var xj = polygon2[j2][0];
19136 var yj = polygon2[j2][1];
19137 var intersect2 = yi > y !== yj > y && x < (xj - xi) * (y - yi) / (yj - yi) + xi;
19143 function geoPolygonContainsPolygon(outer, inner) {
19144 return inner.every(function(point2) {
19145 return geoPointInPolygon(point2, outer);
19148 function geoPolygonIntersectsPolygon(outer, inner, checkSegments) {
19149 function testPoints(outer2, inner2) {
19150 return inner2.some(function(point2) {
19151 return geoPointInPolygon(point2, outer2);
19154 return testPoints(outer, inner) || !!checkSegments && geoPathHasIntersections(outer, inner);
19156 function geoGetSmallestSurroundingRectangle(points) {
19157 var hull = hull_default(points);
19158 var centroid = centroid_default2(hull);
19159 var minArea = Infinity;
19160 var ssrExtent = [];
19163 for (var i2 = 0; i2 <= hull.length - 1; i2++) {
19164 var c2 = i2 === hull.length - 1 ? hull[0] : hull[i2 + 1];
19165 var angle2 = Math.atan2(c2[1] - c1[1], c2[0] - c1[0]);
19166 var poly = geoRotate(hull, -angle2, centroid);
19167 var extent = poly.reduce(function(extent2, point2) {
19168 return extent2.extend(geoExtent(point2));
19170 var area = extent.area();
19171 if (area < minArea) {
19173 ssrExtent = extent;
19179 poly: geoRotate(ssrExtent.polygon(), ssrAngle, centroid),
19183 function geoPathLength(path) {
19185 for (var i2 = 0; i2 < path.length - 1; i2++) {
19186 length += geoVecLength(path[i2], path[i2 + 1]);
19190 function geoViewportEdge(point2, dimensions) {
19191 var pad2 = [80, 20, 50, 20];
19194 if (point2[0] > dimensions[0] - pad2[1]) {
19197 if (point2[0] < pad2[3]) {
19200 if (point2[1] > dimensions[1] - pad2[2]) {
19203 if (point2[1] < pad2[0]) {
19213 // node_modules/d3-dispatch/src/dispatch.js
19214 var noop2 = { value: () => {
19216 function dispatch() {
19217 for (var i2 = 0, n2 = arguments.length, _ = {}, t; i2 < n2; ++i2) {
19218 if (!(t = arguments[i2] + "") || t in _ || /[\s.]/.test(t))
19219 throw new Error("illegal type: " + t);
19222 return new Dispatch(_);
19224 function Dispatch(_) {
19227 function parseTypenames(typenames, types) {
19228 return typenames.trim().split(/^|\s+/).map(function(t) {
19229 var name = "", i2 = t.indexOf(".");
19231 name = t.slice(i2 + 1), t = t.slice(0, i2);
19232 if (t && !types.hasOwnProperty(t))
19233 throw new Error("unknown type: " + t);
19234 return { type: t, name };
19237 Dispatch.prototype = dispatch.prototype = {
19238 constructor: Dispatch,
19239 on: function(typename, callback) {
19240 var _ = this._, T = parseTypenames(typename + "", _), t, i2 = -1, n2 = T.length;
19241 if (arguments.length < 2) {
19243 if ((t = (typename = T[i2]).type) && (t = get(_[t], typename.name)))
19247 if (callback != null && typeof callback !== "function")
19248 throw new Error("invalid callback: " + callback);
19249 while (++i2 < n2) {
19250 if (t = (typename = T[i2]).type)
19251 _[t] = set(_[t], typename.name, callback);
19252 else if (callback == null)
19254 _[t] = set(_[t], typename.name, null);
19259 var copy2 = {}, _ = this._;
19261 copy2[t] = _[t].slice();
19262 return new Dispatch(copy2);
19264 call: function(type2, that) {
19265 if ((n2 = arguments.length - 2) > 0)
19266 for (var args = new Array(n2), i2 = 0, n2, t; i2 < n2; ++i2)
19267 args[i2] = arguments[i2 + 2];
19268 if (!this._.hasOwnProperty(type2))
19269 throw new Error("unknown type: " + type2);
19270 for (t = this._[type2], i2 = 0, n2 = t.length; i2 < n2; ++i2)
19271 t[i2].value.apply(that, args);
19273 apply: function(type2, that, args) {
19274 if (!this._.hasOwnProperty(type2))
19275 throw new Error("unknown type: " + type2);
19276 for (var t = this._[type2], i2 = 0, n2 = t.length; i2 < n2; ++i2)
19277 t[i2].value.apply(that, args);
19280 function get(type2, name) {
19281 for (var i2 = 0, n2 = type2.length, c; i2 < n2; ++i2) {
19282 if ((c = type2[i2]).name === name) {
19287 function set(type2, name, callback) {
19288 for (var i2 = 0, n2 = type2.length; i2 < n2; ++i2) {
19289 if (type2[i2].name === name) {
19290 type2[i2] = noop2, type2 = type2.slice(0, i2).concat(type2.slice(i2 + 1));
19294 if (callback != null)
19295 type2.push({ name, value: callback });
19298 var dispatch_default = dispatch;
19300 // node_modules/d3-selection/src/namespaces.js
19301 var xhtml = "http://www.w3.org/1999/xhtml";
19302 var namespaces_default = {
19303 svg: "http://www.w3.org/2000/svg",
19305 xlink: "http://www.w3.org/1999/xlink",
19306 xml: "http://www.w3.org/XML/1998/namespace",
19307 xmlns: "http://www.w3.org/2000/xmlns/"
19310 // node_modules/d3-selection/src/namespace.js
19311 function namespace_default(name) {
19312 var prefix = name += "", i2 = prefix.indexOf(":");
19313 if (i2 >= 0 && (prefix = name.slice(0, i2)) !== "xmlns")
19314 name = name.slice(i2 + 1);
19315 return namespaces_default.hasOwnProperty(prefix) ? { space: namespaces_default[prefix], local: name } : name;
19318 // node_modules/d3-selection/src/creator.js
19319 function creatorInherit(name) {
19320 return function() {
19321 var document2 = this.ownerDocument, uri = this.namespaceURI;
19322 return uri === xhtml && document2.documentElement.namespaceURI === xhtml ? document2.createElement(name) : document2.createElementNS(uri, name);
19325 function creatorFixed(fullname) {
19326 return function() {
19327 return this.ownerDocument.createElementNS(fullname.space, fullname.local);
19330 function creator_default(name) {
19331 var fullname = namespace_default(name);
19332 return (fullname.local ? creatorFixed : creatorInherit)(fullname);
19335 // node_modules/d3-selection/src/selector.js
19338 function selector_default(selector) {
19339 return selector == null ? none : function() {
19340 return this.querySelector(selector);
19344 // node_modules/d3-selection/src/selection/select.js
19345 function select_default(select) {
19346 if (typeof select !== "function")
19347 select = selector_default(select);
19348 for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j2 = 0; j2 < m; ++j2) {
19349 for (var group = groups[j2], n2 = group.length, subgroup = subgroups[j2] = new Array(n2), node, subnode, i2 = 0; i2 < n2; ++i2) {
19350 if ((node = group[i2]) && (subnode = select.call(node, node.__data__, i2, group))) {
19351 if ("__data__" in node)
19352 subnode.__data__ = node.__data__;
19353 subgroup[i2] = subnode;
19357 return new Selection(subgroups, this._parents);
19360 // node_modules/d3-selection/src/array.js
19361 function array(x) {
19362 return x == null ? [] : Array.isArray(x) ? x : Array.from(x);
19365 // node_modules/d3-selection/src/selectorAll.js
19369 function selectorAll_default(selector) {
19370 return selector == null ? empty : function() {
19371 return this.querySelectorAll(selector);
19375 // node_modules/d3-selection/src/selection/selectAll.js
19376 function arrayAll(select) {
19377 return function() {
19378 return array(select.apply(this, arguments));
19381 function selectAll_default(select) {
19382 if (typeof select === "function")
19383 select = arrayAll(select);
19385 select = selectorAll_default(select);
19386 for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j2 = 0; j2 < m; ++j2) {
19387 for (var group = groups[j2], n2 = group.length, node, i2 = 0; i2 < n2; ++i2) {
19388 if (node = group[i2]) {
19389 subgroups.push(select.call(node, node.__data__, i2, group));
19390 parents.push(node);
19394 return new Selection(subgroups, parents);
19397 // node_modules/d3-selection/src/matcher.js
19398 function matcher_default(selector) {
19399 return function() {
19400 return this.matches(selector);
19403 function childMatcher(selector) {
19404 return function(node) {
19405 return node.matches(selector);
19409 // node_modules/d3-selection/src/selection/selectChild.js
19410 var find = Array.prototype.find;
19411 function childFind(match) {
19412 return function() {
19413 return find.call(this.children, match);
19416 function childFirst() {
19417 return this.firstElementChild;
19419 function selectChild_default(match) {
19420 return this.select(match == null ? childFirst : childFind(typeof match === "function" ? match : childMatcher(match)));
19423 // node_modules/d3-selection/src/selection/selectChildren.js
19424 var filter = Array.prototype.filter;
19425 function children() {
19426 return Array.from(this.children);
19428 function childrenFilter(match) {
19429 return function() {
19430 return filter.call(this.children, match);
19433 function selectChildren_default(match) {
19434 return this.selectAll(match == null ? children : childrenFilter(typeof match === "function" ? match : childMatcher(match)));
19437 // node_modules/d3-selection/src/selection/filter.js
19438 function filter_default(match) {
19439 if (typeof match !== "function")
19440 match = matcher_default(match);
19441 for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j2 = 0; j2 < m; ++j2) {
19442 for (var group = groups[j2], n2 = group.length, subgroup = subgroups[j2] = [], node, i2 = 0; i2 < n2; ++i2) {
19443 if ((node = group[i2]) && match.call(node, node.__data__, i2, group)) {
19444 subgroup.push(node);
19448 return new Selection(subgroups, this._parents);
19451 // node_modules/d3-selection/src/selection/sparse.js
19452 function sparse_default(update) {
19453 return new Array(update.length);
19456 // node_modules/d3-selection/src/selection/enter.js
19457 function enter_default() {
19458 return new Selection(this._enter || this._groups.map(sparse_default), this._parents);
19460 function EnterNode(parent, datum2) {
19461 this.ownerDocument = parent.ownerDocument;
19462 this.namespaceURI = parent.namespaceURI;
19464 this._parent = parent;
19465 this.__data__ = datum2;
19467 EnterNode.prototype = {
19468 constructor: EnterNode,
19469 appendChild: function(child) {
19470 return this._parent.insertBefore(child, this._next);
19472 insertBefore: function(child, next) {
19473 return this._parent.insertBefore(child, next);
19475 querySelector: function(selector) {
19476 return this._parent.querySelector(selector);
19478 querySelectorAll: function(selector) {
19479 return this._parent.querySelectorAll(selector);
19483 // node_modules/d3-selection/src/constant.js
19484 function constant_default(x) {
19485 return function() {
19490 // node_modules/d3-selection/src/selection/data.js
19491 function bindIndex(parent, group, enter, update, exit, data) {
19492 var i2 = 0, node, groupLength = group.length, dataLength = data.length;
19493 for (; i2 < dataLength; ++i2) {
19494 if (node = group[i2]) {
19495 node.__data__ = data[i2];
19498 enter[i2] = new EnterNode(parent, data[i2]);
19501 for (; i2 < groupLength; ++i2) {
19502 if (node = group[i2]) {
19507 function bindKey(parent, group, enter, update, exit, data, key) {
19508 var i2, node, nodeByKeyValue = /* @__PURE__ */ new Map(), groupLength = group.length, dataLength = data.length, keyValues = new Array(groupLength), keyValue;
19509 for (i2 = 0; i2 < groupLength; ++i2) {
19510 if (node = group[i2]) {
19511 keyValues[i2] = keyValue = key.call(node, node.__data__, i2, group) + "";
19512 if (nodeByKeyValue.has(keyValue)) {
19515 nodeByKeyValue.set(keyValue, node);
19519 for (i2 = 0; i2 < dataLength; ++i2) {
19520 keyValue = key.call(parent, data[i2], i2, data) + "";
19521 if (node = nodeByKeyValue.get(keyValue)) {
19523 node.__data__ = data[i2];
19524 nodeByKeyValue.delete(keyValue);
19526 enter[i2] = new EnterNode(parent, data[i2]);
19529 for (i2 = 0; i2 < groupLength; ++i2) {
19530 if ((node = group[i2]) && nodeByKeyValue.get(keyValues[i2]) === node) {
19535 function datum(node) {
19536 return node.__data__;
19538 function data_default(value, key) {
19539 if (!arguments.length)
19540 return Array.from(this, datum);
19541 var bind = key ? bindKey : bindIndex, parents = this._parents, groups = this._groups;
19542 if (typeof value !== "function")
19543 value = constant_default(value);
19544 for (var m = groups.length, update = new Array(m), enter = new Array(m), exit = new Array(m), j2 = 0; j2 < m; ++j2) {
19545 var parent = parents[j2], group = groups[j2], groupLength = group.length, data = arraylike(value.call(parent, parent && parent.__data__, j2, parents)), dataLength = data.length, enterGroup = enter[j2] = new Array(dataLength), updateGroup = update[j2] = new Array(dataLength), exitGroup = exit[j2] = new Array(groupLength);
19546 bind(parent, group, enterGroup, updateGroup, exitGroup, data, key);
19547 for (var i0 = 0, i1 = 0, previous, next; i0 < dataLength; ++i0) {
19548 if (previous = enterGroup[i0]) {
19551 while (!(next = updateGroup[i1]) && ++i1 < dataLength)
19553 previous._next = next || null;
19557 update = new Selection(update, parents);
19558 update._enter = enter;
19559 update._exit = exit;
19562 function arraylike(data) {
19563 return typeof data === "object" && "length" in data ? data : Array.from(data);
19566 // node_modules/d3-selection/src/selection/exit.js
19567 function exit_default() {
19568 return new Selection(this._exit || this._groups.map(sparse_default), this._parents);
19571 // node_modules/d3-selection/src/selection/join.js
19572 function join_default(onenter, onupdate, onexit) {
19573 var enter = this.enter(), update = this, exit = this.exit();
19574 if (typeof onenter === "function") {
19575 enter = onenter(enter);
19577 enter = enter.selection();
19579 enter = enter.append(onenter + "");
19581 if (onupdate != null) {
19582 update = onupdate(update);
19584 update = update.selection();
19586 if (onexit == null)
19590 return enter && update ? enter.merge(update).order() : update;
19593 // node_modules/d3-selection/src/selection/merge.js
19594 function merge_default(context) {
19595 var selection2 = context.selection ? context.selection() : context;
19596 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) {
19597 for (var group0 = groups0[j2], group1 = groups1[j2], n2 = group0.length, merge3 = merges[j2] = new Array(n2), node, i2 = 0; i2 < n2; ++i2) {
19598 if (node = group0[i2] || group1[i2]) {
19603 for (; j2 < m0; ++j2) {
19604 merges[j2] = groups0[j2];
19606 return new Selection(merges, this._parents);
19609 // node_modules/d3-selection/src/selection/order.js
19610 function order_default() {
19611 for (var groups = this._groups, j2 = -1, m = groups.length; ++j2 < m; ) {
19612 for (var group = groups[j2], i2 = group.length - 1, next = group[i2], node; --i2 >= 0; ) {
19613 if (node = group[i2]) {
19614 if (next && node.compareDocumentPosition(next) ^ 4)
19615 next.parentNode.insertBefore(node, next);
19623 // node_modules/d3-selection/src/selection/sort.js
19624 function sort_default(compare) {
19626 compare = ascending2;
19627 function compareNode(a, b) {
19628 return a && b ? compare(a.__data__, b.__data__) : !a - !b;
19630 for (var groups = this._groups, m = groups.length, sortgroups = new Array(m), j2 = 0; j2 < m; ++j2) {
19631 for (var group = groups[j2], n2 = group.length, sortgroup = sortgroups[j2] = new Array(n2), node, i2 = 0; i2 < n2; ++i2) {
19632 if (node = group[i2]) {
19633 sortgroup[i2] = node;
19636 sortgroup.sort(compareNode);
19638 return new Selection(sortgroups, this._parents).order();
19640 function ascending2(a, b) {
19641 return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
19644 // node_modules/d3-selection/src/selection/call.js
19645 function call_default() {
19646 var callback = arguments[0];
19647 arguments[0] = this;
19648 callback.apply(null, arguments);
19652 // node_modules/d3-selection/src/selection/nodes.js
19653 function nodes_default() {
19654 return Array.from(this);
19657 // node_modules/d3-selection/src/selection/node.js
19658 function node_default() {
19659 for (var groups = this._groups, j2 = 0, m = groups.length; j2 < m; ++j2) {
19660 for (var group = groups[j2], i2 = 0, n2 = group.length; i2 < n2; ++i2) {
19661 var node = group[i2];
19669 // node_modules/d3-selection/src/selection/size.js
19670 function size_default() {
19672 for (const node of this)
19677 // node_modules/d3-selection/src/selection/empty.js
19678 function empty_default() {
19679 return !this.node();
19682 // node_modules/d3-selection/src/selection/each.js
19683 function each_default(callback) {
19684 for (var groups = this._groups, j2 = 0, m = groups.length; j2 < m; ++j2) {
19685 for (var group = groups[j2], i2 = 0, n2 = group.length, node; i2 < n2; ++i2) {
19686 if (node = group[i2])
19687 callback.call(node, node.__data__, i2, group);
19693 // node_modules/d3-selection/src/selection/attr.js
19694 function attrRemove(name) {
19695 return function() {
19696 this.removeAttribute(name);
19699 function attrRemoveNS(fullname) {
19700 return function() {
19701 this.removeAttributeNS(fullname.space, fullname.local);
19704 function attrConstant(name, value) {
19705 return function() {
19706 this.setAttribute(name, value);
19709 function attrConstantNS(fullname, value) {
19710 return function() {
19711 this.setAttributeNS(fullname.space, fullname.local, value);
19714 function attrFunction(name, value) {
19715 return function() {
19716 var v = value.apply(this, arguments);
19718 this.removeAttribute(name);
19720 this.setAttribute(name, v);
19723 function attrFunctionNS(fullname, value) {
19724 return function() {
19725 var v = value.apply(this, arguments);
19727 this.removeAttributeNS(fullname.space, fullname.local);
19729 this.setAttributeNS(fullname.space, fullname.local, v);
19732 function attr_default(name, value) {
19733 var fullname = namespace_default(name);
19734 if (arguments.length < 2) {
19735 var node = this.node();
19736 return fullname.local ? node.getAttributeNS(fullname.space, fullname.local) : node.getAttribute(fullname);
19738 return this.each((value == null ? fullname.local ? attrRemoveNS : attrRemove : typeof value === "function" ? fullname.local ? attrFunctionNS : attrFunction : fullname.local ? attrConstantNS : attrConstant)(fullname, value));
19741 // node_modules/d3-selection/src/window.js
19742 function window_default(node) {
19743 return node.ownerDocument && node.ownerDocument.defaultView || node.document && node || node.defaultView;
19746 // node_modules/d3-selection/src/selection/style.js
19747 function styleRemove(name) {
19748 return function() {
19749 this.style.removeProperty(name);
19752 function styleConstant(name, value, priority) {
19753 return function() {
19754 this.style.setProperty(name, value, priority);
19757 function styleFunction(name, value, priority) {
19758 return function() {
19759 var v = value.apply(this, arguments);
19761 this.style.removeProperty(name);
19763 this.style.setProperty(name, v, priority);
19766 function style_default(name, value, priority) {
19767 return arguments.length > 1 ? this.each((value == null ? styleRemove : typeof value === "function" ? styleFunction : styleConstant)(name, value, priority == null ? "" : priority)) : styleValue(this.node(), name);
19769 function styleValue(node, name) {
19770 return node.style.getPropertyValue(name) || window_default(node).getComputedStyle(node, null).getPropertyValue(name);
19773 // node_modules/d3-selection/src/selection/property.js
19774 function propertyRemove(name) {
19775 return function() {
19779 function propertyConstant(name, value) {
19780 return function() {
19781 this[name] = value;
19784 function propertyFunction(name, value) {
19785 return function() {
19786 var v = value.apply(this, arguments);
19793 function property_default(name, value) {
19794 return arguments.length > 1 ? this.each((value == null ? propertyRemove : typeof value === "function" ? propertyFunction : propertyConstant)(name, value)) : this.node()[name];
19797 // node_modules/d3-selection/src/selection/classed.js
19798 function classArray(string) {
19799 return string.trim().split(/^|\s+/);
19801 function classList(node) {
19802 return node.classList || new ClassList(node);
19804 function ClassList(node) {
19806 this._names = classArray(node.getAttribute("class") || "");
19808 ClassList.prototype = {
19809 add: function(name) {
19810 var i2 = this._names.indexOf(name);
19812 this._names.push(name);
19813 this._node.setAttribute("class", this._names.join(" "));
19816 remove: function(name) {
19817 var i2 = this._names.indexOf(name);
19819 this._names.splice(i2, 1);
19820 this._node.setAttribute("class", this._names.join(" "));
19823 contains: function(name) {
19824 return this._names.indexOf(name) >= 0;
19827 function classedAdd(node, names) {
19828 var list = classList(node), i2 = -1, n2 = names.length;
19830 list.add(names[i2]);
19832 function classedRemove(node, names) {
19833 var list = classList(node), i2 = -1, n2 = names.length;
19835 list.remove(names[i2]);
19837 function classedTrue(names) {
19838 return function() {
19839 classedAdd(this, names);
19842 function classedFalse(names) {
19843 return function() {
19844 classedRemove(this, names);
19847 function classedFunction(names, value) {
19848 return function() {
19849 (value.apply(this, arguments) ? classedAdd : classedRemove)(this, names);
19852 function classed_default(name, value) {
19853 var names = classArray(name + "");
19854 if (arguments.length < 2) {
19855 var list = classList(this.node()), i2 = -1, n2 = names.length;
19857 if (!list.contains(names[i2]))
19861 return this.each((typeof value === "function" ? classedFunction : value ? classedTrue : classedFalse)(names, value));
19864 // node_modules/d3-selection/src/selection/text.js
19865 function textRemove() {
19866 this.textContent = "";
19868 function textConstant(value) {
19869 return function() {
19870 this.textContent = value;
19873 function textFunction(value) {
19874 return function() {
19875 var v = value.apply(this, arguments);
19876 this.textContent = v == null ? "" : v;
19879 function text_default(value) {
19880 return arguments.length ? this.each(value == null ? textRemove : (typeof value === "function" ? textFunction : textConstant)(value)) : this.node().textContent;
19883 // node_modules/d3-selection/src/selection/html.js
19884 function htmlRemove() {
19885 this.innerHTML = "";
19887 function htmlConstant(value) {
19888 return function() {
19889 this.innerHTML = value;
19892 function htmlFunction(value) {
19893 return function() {
19894 var v = value.apply(this, arguments);
19895 this.innerHTML = v == null ? "" : v;
19898 function html_default(value) {
19899 return arguments.length ? this.each(value == null ? htmlRemove : (typeof value === "function" ? htmlFunction : htmlConstant)(value)) : this.node().innerHTML;
19902 // node_modules/d3-selection/src/selection/raise.js
19904 if (this.nextSibling)
19905 this.parentNode.appendChild(this);
19907 function raise_default() {
19908 return this.each(raise);
19911 // node_modules/d3-selection/src/selection/lower.js
19913 if (this.previousSibling)
19914 this.parentNode.insertBefore(this, this.parentNode.firstChild);
19916 function lower_default() {
19917 return this.each(lower);
19920 // node_modules/d3-selection/src/selection/append.js
19921 function append_default(name) {
19922 var create2 = typeof name === "function" ? name : creator_default(name);
19923 return this.select(function() {
19924 return this.appendChild(create2.apply(this, arguments));
19928 // node_modules/d3-selection/src/selection/insert.js
19929 function constantNull() {
19932 function insert_default(name, before) {
19933 var create2 = typeof name === "function" ? name : creator_default(name), select = before == null ? constantNull : typeof before === "function" ? before : selector_default(before);
19934 return this.select(function() {
19935 return this.insertBefore(create2.apply(this, arguments), select.apply(this, arguments) || null);
19939 // node_modules/d3-selection/src/selection/remove.js
19940 function remove() {
19941 var parent = this.parentNode;
19943 parent.removeChild(this);
19945 function remove_default() {
19946 return this.each(remove);
19949 // node_modules/d3-selection/src/selection/clone.js
19950 function selection_cloneShallow() {
19951 var clone = this.cloneNode(false), parent = this.parentNode;
19952 return parent ? parent.insertBefore(clone, this.nextSibling) : clone;
19954 function selection_cloneDeep() {
19955 var clone = this.cloneNode(true), parent = this.parentNode;
19956 return parent ? parent.insertBefore(clone, this.nextSibling) : clone;
19958 function clone_default(deep) {
19959 return this.select(deep ? selection_cloneDeep : selection_cloneShallow);
19962 // node_modules/d3-selection/src/selection/datum.js
19963 function datum_default(value) {
19964 return arguments.length ? this.property("__data__", value) : this.node().__data__;
19967 // node_modules/d3-selection/src/selection/on.js
19968 function contextListener(listener) {
19969 return function(event) {
19970 listener.call(this, event, this.__data__);
19973 function parseTypenames2(typenames) {
19974 return typenames.trim().split(/^|\s+/).map(function(t) {
19975 var name = "", i2 = t.indexOf(".");
19977 name = t.slice(i2 + 1), t = t.slice(0, i2);
19978 return { type: t, name };
19981 function onRemove(typename) {
19982 return function() {
19983 var on = this.__on;
19986 for (var j2 = 0, i2 = -1, m = on.length, o; j2 < m; ++j2) {
19987 if (o = on[j2], (!typename.type || o.type === typename.type) && o.name === typename.name) {
19988 this.removeEventListener(o.type, o.listener, o.options);
19999 function onAdd(typename, value, options2) {
20000 return function() {
20001 var on = this.__on, o, listener = contextListener(value);
20003 for (var j2 = 0, m = on.length; j2 < m; ++j2) {
20004 if ((o = on[j2]).type === typename.type && o.name === typename.name) {
20005 this.removeEventListener(o.type, o.listener, o.options);
20006 this.addEventListener(o.type, o.listener = listener, o.options = options2);
20011 this.addEventListener(typename.type, listener, options2);
20012 o = { type: typename.type, name: typename.name, value, listener, options: options2 };
20019 function on_default(typename, value, options2) {
20020 var typenames = parseTypenames2(typename + ""), i2, n2 = typenames.length, t;
20021 if (arguments.length < 2) {
20022 var on = this.node().__on;
20024 for (var j2 = 0, m = on.length, o; j2 < m; ++j2) {
20025 for (i2 = 0, o = on[j2]; i2 < n2; ++i2) {
20026 if ((t = typenames[i2]).type === o.type && t.name === o.name) {
20033 on = value ? onAdd : onRemove;
20034 for (i2 = 0; i2 < n2; ++i2)
20035 this.each(on(typenames[i2], value, options2));
20039 // node_modules/d3-selection/src/selection/dispatch.js
20040 function dispatchEvent(node, type2, params) {
20041 var window2 = window_default(node), event = window2.CustomEvent;
20042 if (typeof event === "function") {
20043 event = new event(type2, params);
20045 event = window2.document.createEvent("Event");
20047 event.initEvent(type2, params.bubbles, params.cancelable), event.detail = params.detail;
20049 event.initEvent(type2, false, false);
20051 node.dispatchEvent(event);
20053 function dispatchConstant(type2, params) {
20054 return function() {
20055 return dispatchEvent(this, type2, params);
20058 function dispatchFunction(type2, params) {
20059 return function() {
20060 return dispatchEvent(this, type2, params.apply(this, arguments));
20063 function dispatch_default2(type2, params) {
20064 return this.each((typeof params === "function" ? dispatchFunction : dispatchConstant)(type2, params));
20067 // node_modules/d3-selection/src/selection/iterator.js
20068 function* iterator_default() {
20069 for (var groups = this._groups, j2 = 0, m = groups.length; j2 < m; ++j2) {
20070 for (var group = groups[j2], i2 = 0, n2 = group.length, node; i2 < n2; ++i2) {
20071 if (node = group[i2])
20077 // node_modules/d3-selection/src/selection/index.js
20079 function Selection(groups, parents) {
20080 this._groups = groups;
20081 this._parents = parents;
20083 function selection() {
20084 return new Selection([[document.documentElement]], root);
20086 function selection_selection() {
20089 Selection.prototype = selection.prototype = {
20090 constructor: Selection,
20091 select: select_default,
20092 selectAll: selectAll_default,
20093 selectChild: selectChild_default,
20094 selectChildren: selectChildren_default,
20095 filter: filter_default,
20096 data: data_default,
20097 enter: enter_default,
20098 exit: exit_default,
20099 join: join_default,
20100 merge: merge_default,
20101 selection: selection_selection,
20102 order: order_default,
20103 sort: sort_default,
20104 call: call_default,
20105 nodes: nodes_default,
20106 node: node_default,
20107 size: size_default,
20108 empty: empty_default,
20109 each: each_default,
20110 attr: attr_default,
20111 style: style_default,
20112 property: property_default,
20113 classed: classed_default,
20114 text: text_default,
20115 html: html_default,
20116 raise: raise_default,
20117 lower: lower_default,
20118 append: append_default,
20119 insert: insert_default,
20120 remove: remove_default,
20121 clone: clone_default,
20122 datum: datum_default,
20124 dispatch: dispatch_default2,
20125 [Symbol.iterator]: iterator_default
20127 var selection_default = selection;
20129 // node_modules/d3-selection/src/select.js
20130 function select_default2(selector) {
20131 return typeof selector === "string" ? new Selection([[document.querySelector(selector)]], [document.documentElement]) : new Selection([[selector]], root);
20134 // node_modules/d3-selection/src/sourceEvent.js
20135 function sourceEvent_default(event) {
20137 while (sourceEvent = event.sourceEvent)
20138 event = sourceEvent;
20142 // node_modules/d3-selection/src/pointer.js
20143 function pointer_default(event, node) {
20144 event = sourceEvent_default(event);
20145 if (node === void 0)
20146 node = event.currentTarget;
20148 var svg2 = node.ownerSVGElement || node;
20149 if (svg2.createSVGPoint) {
20150 var point2 = svg2.createSVGPoint();
20151 point2.x = event.clientX, point2.y = event.clientY;
20152 point2 = point2.matrixTransform(node.getScreenCTM().inverse());
20153 return [point2.x, point2.y];
20155 if (node.getBoundingClientRect) {
20156 var rect = node.getBoundingClientRect();
20157 return [event.clientX - rect.left - node.clientLeft, event.clientY - rect.top - node.clientTop];
20160 return [event.pageX, event.pageY];
20163 // node_modules/d3-selection/src/selectAll.js
20164 function selectAll_default2(selector) {
20165 return typeof selector === "string" ? new Selection([document.querySelectorAll(selector)], [document.documentElement]) : new Selection([array(selector)], root);
20168 // node_modules/d3-drag/src/noevent.js
20169 var nonpassive = { passive: false };
20170 var nonpassivecapture = { capture: true, passive: false };
20171 function nopropagation(event) {
20172 event.stopImmediatePropagation();
20174 function noevent_default(event) {
20175 event.preventDefault();
20176 event.stopImmediatePropagation();
20179 // node_modules/d3-drag/src/nodrag.js
20180 function nodrag_default(view) {
20181 var root3 = view.document.documentElement, selection2 = select_default2(view).on("dragstart.drag", noevent_default, nonpassivecapture);
20182 if ("onselectstart" in root3) {
20183 selection2.on("selectstart.drag", noevent_default, nonpassivecapture);
20185 root3.__noselect = root3.style.MozUserSelect;
20186 root3.style.MozUserSelect = "none";
20189 function yesdrag(view, noclick) {
20190 var root3 = view.document.documentElement, selection2 = select_default2(view).on("dragstart.drag", null);
20192 selection2.on("click.drag", noevent_default, nonpassivecapture);
20193 setTimeout(function() {
20194 selection2.on("click.drag", null);
20197 if ("onselectstart" in root3) {
20198 selection2.on("selectstart.drag", null);
20200 root3.style.MozUserSelect = root3.__noselect;
20201 delete root3.__noselect;
20205 // node_modules/d3-drag/src/constant.js
20206 var constant_default2 = (x) => () => x;
20208 // node_modules/d3-drag/src/event.js
20209 function DragEvent(type2, {
20219 dispatch: dispatch10
20221 Object.defineProperties(this, {
20222 type: { value: type2, enumerable: true, configurable: true },
20223 sourceEvent: { value: sourceEvent, enumerable: true, configurable: true },
20224 subject: { value: subject, enumerable: true, configurable: true },
20225 target: { value: target, enumerable: true, configurable: true },
20226 identifier: { value: identifier, enumerable: true, configurable: true },
20227 active: { value: active, enumerable: true, configurable: true },
20228 x: { value: x, enumerable: true, configurable: true },
20229 y: { value: y, enumerable: true, configurable: true },
20230 dx: { value: dx, enumerable: true, configurable: true },
20231 dy: { value: dy, enumerable: true, configurable: true },
20232 _: { value: dispatch10 }
20235 DragEvent.prototype.on = function() {
20236 var value = this._.on.apply(this._, arguments);
20237 return value === this._ ? this : value;
20240 // node_modules/d3-drag/src/drag.js
20241 function defaultFilter(event) {
20242 return !event.ctrlKey && !event.button;
20244 function defaultContainer() {
20245 return this.parentNode;
20247 function defaultSubject(event, d) {
20248 return d == null ? { x: event.x, y: event.y } : d;
20250 function defaultTouchable() {
20251 return navigator.maxTouchPoints || "ontouchstart" in this;
20253 function drag_default() {
20254 var filter2 = defaultFilter, container = defaultContainer, subject = defaultSubject, touchable = defaultTouchable, gestures = {}, listeners = dispatch_default("start", "drag", "end"), active = 0, mousedownx, mousedowny, mousemoving, touchending, clickDistance2 = 0;
20255 function drag(selection2) {
20256 selection2.on("mousedown.drag", mousedowned).filter(touchable).on("touchstart.drag", touchstarted).on("touchmove.drag", touchmoved, nonpassive).on("touchend.drag touchcancel.drag", touchended).style("touch-action", "none").style("-webkit-tap-highlight-color", "rgba(0,0,0,0)");
20258 function mousedowned(event, d) {
20259 if (touchending || !filter2.call(this, event, d))
20261 var gesture = beforestart(this, container.call(this, event, d), event, d, "mouse");
20264 select_default2(event.view).on("mousemove.drag", mousemoved, nonpassivecapture).on("mouseup.drag", mouseupped, nonpassivecapture);
20265 nodrag_default(event.view);
20266 nopropagation(event);
20267 mousemoving = false;
20268 mousedownx = event.clientX;
20269 mousedowny = event.clientY;
20270 gesture("start", event);
20272 function mousemoved(event) {
20273 noevent_default(event);
20274 if (!mousemoving) {
20275 var dx = event.clientX - mousedownx, dy = event.clientY - mousedowny;
20276 mousemoving = dx * dx + dy * dy > clickDistance2;
20278 gestures.mouse("drag", event);
20280 function mouseupped(event) {
20281 select_default2(event.view).on("mousemove.drag mouseup.drag", null);
20282 yesdrag(event.view, mousemoving);
20283 noevent_default(event);
20284 gestures.mouse("end", event);
20286 function touchstarted(event, d) {
20287 if (!filter2.call(this, event, d))
20289 var touches = event.changedTouches, c = container.call(this, event, d), n2 = touches.length, i2, gesture;
20290 for (i2 = 0; i2 < n2; ++i2) {
20291 if (gesture = beforestart(this, c, event, d, touches[i2].identifier, touches[i2])) {
20292 nopropagation(event);
20293 gesture("start", event, touches[i2]);
20297 function touchmoved(event) {
20298 var touches = event.changedTouches, n2 = touches.length, i2, gesture;
20299 for (i2 = 0; i2 < n2; ++i2) {
20300 if (gesture = gestures[touches[i2].identifier]) {
20301 noevent_default(event);
20302 gesture("drag", event, touches[i2]);
20306 function touchended(event) {
20307 var touches = event.changedTouches, n2 = touches.length, i2, gesture;
20309 clearTimeout(touchending);
20310 touchending = setTimeout(function() {
20311 touchending = null;
20313 for (i2 = 0; i2 < n2; ++i2) {
20314 if (gesture = gestures[touches[i2].identifier]) {
20315 nopropagation(event);
20316 gesture("end", event, touches[i2]);
20320 function beforestart(that, container2, event, d, identifier, touch) {
20321 var dispatch10 = listeners.copy(), p = pointer_default(touch || event, container2), dx, dy, s;
20322 if ((s = subject.call(that, new DragEvent("beforestart", {
20323 sourceEvent: event,
20331 dispatch: dispatch10
20334 dx = s.x - p[0] || 0;
20335 dy = s.y - p[1] || 0;
20336 return function gesture(type2, event2, touch2) {
20340 gestures[identifier] = gesture, n2 = active++;
20343 delete gestures[identifier], --active;
20345 p = pointer_default(touch2 || event2, container2), n2 = active;
20351 new DragEvent(type2, {
20352 sourceEvent: event2,
20361 dispatch: dispatch10
20367 drag.filter = function(_) {
20368 return arguments.length ? (filter2 = typeof _ === "function" ? _ : constant_default2(!!_), drag) : filter2;
20370 drag.container = function(_) {
20371 return arguments.length ? (container = typeof _ === "function" ? _ : constant_default2(_), drag) : container;
20373 drag.subject = function(_) {
20374 return arguments.length ? (subject = typeof _ === "function" ? _ : constant_default2(_), drag) : subject;
20376 drag.touchable = function(_) {
20377 return arguments.length ? (touchable = typeof _ === "function" ? _ : constant_default2(!!_), drag) : touchable;
20379 drag.on = function() {
20380 var value = listeners.on.apply(listeners, arguments);
20381 return value === listeners ? drag : value;
20383 drag.clickDistance = function(_) {
20384 return arguments.length ? (clickDistance2 = (_ = +_) * _, drag) : Math.sqrt(clickDistance2);
20389 // node_modules/d3-color/src/define.js
20390 function define_default(constructor, factory, prototype) {
20391 constructor.prototype = factory.prototype = prototype;
20392 prototype.constructor = constructor;
20394 function extend(parent, definition) {
20395 var prototype = Object.create(parent.prototype);
20396 for (var key in definition)
20397 prototype[key] = definition[key];
20401 // node_modules/d3-color/src/color.js
20405 var brighter = 1 / darker;
20406 var reI = "\\s*([+-]?\\d+)\\s*";
20407 var reN = "\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)\\s*";
20408 var reP = "\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)%\\s*";
20409 var reHex = /^#([0-9a-f]{3,8})$/;
20410 var reRgbInteger = new RegExp(`^rgb\\(${reI},${reI},${reI}\\)$`);
20411 var reRgbPercent = new RegExp(`^rgb\\(${reP},${reP},${reP}\\)$`);
20412 var reRgbaInteger = new RegExp(`^rgba\\(${reI},${reI},${reI},${reN}\\)$`);
20413 var reRgbaPercent = new RegExp(`^rgba\\(${reP},${reP},${reP},${reN}\\)$`);
20414 var reHslPercent = new RegExp(`^hsl\\(${reN},${reP},${reP}\\)$`);
20415 var reHslaPercent = new RegExp(`^hsla\\(${reN},${reP},${reP},${reN}\\)$`);
20417 aliceblue: 15792383,
20418 antiquewhite: 16444375,
20420 aquamarine: 8388564,
20425 blanchedalmond: 16772045,
20427 blueviolet: 9055202,
20429 burlywood: 14596231,
20430 cadetblue: 6266528,
20431 chartreuse: 8388352,
20432 chocolate: 13789470,
20434 cornflowerblue: 6591981,
20435 cornsilk: 16775388,
20440 darkgoldenrod: 12092939,
20441 darkgray: 11119017,
20443 darkgrey: 11119017,
20444 darkkhaki: 12433259,
20445 darkmagenta: 9109643,
20446 darkolivegreen: 5597999,
20447 darkorange: 16747520,
20448 darkorchid: 10040012,
20450 darksalmon: 15308410,
20451 darkseagreen: 9419919,
20452 darkslateblue: 4734347,
20453 darkslategray: 3100495,
20454 darkslategrey: 3100495,
20455 darkturquoise: 52945,
20456 darkviolet: 9699539,
20457 deeppink: 16716947,
20458 deepskyblue: 49151,
20461 dodgerblue: 2003199,
20462 firebrick: 11674146,
20463 floralwhite: 16775920,
20464 forestgreen: 2263842,
20466 gainsboro: 14474460,
20467 ghostwhite: 16316671,
20469 goldenrod: 14329120,
20472 greenyellow: 11403055,
20474 honeydew: 15794160,
20476 indianred: 13458524,
20480 lavender: 15132410,
20481 lavenderblush: 16773365,
20482 lawngreen: 8190976,
20483 lemonchiffon: 16775885,
20484 lightblue: 11393254,
20485 lightcoral: 15761536,
20486 lightcyan: 14745599,
20487 lightgoldenrodyellow: 16448210,
20488 lightgray: 13882323,
20489 lightgreen: 9498256,
20490 lightgrey: 13882323,
20491 lightpink: 16758465,
20492 lightsalmon: 16752762,
20493 lightseagreen: 2142890,
20494 lightskyblue: 8900346,
20495 lightslategray: 7833753,
20496 lightslategrey: 7833753,
20497 lightsteelblue: 11584734,
20498 lightyellow: 16777184,
20500 limegreen: 3329330,
20504 mediumaquamarine: 6737322,
20506 mediumorchid: 12211667,
20507 mediumpurple: 9662683,
20508 mediumseagreen: 3978097,
20509 mediumslateblue: 8087790,
20510 mediumspringgreen: 64154,
20511 mediumturquoise: 4772300,
20512 mediumvioletred: 13047173,
20513 midnightblue: 1644912,
20514 mintcream: 16121850,
20515 mistyrose: 16770273,
20516 moccasin: 16770229,
20517 navajowhite: 16768685,
20521 olivedrab: 7048739,
20523 orangered: 16729344,
20525 palegoldenrod: 15657130,
20526 palegreen: 10025880,
20527 paleturquoise: 11529966,
20528 palevioletred: 14381203,
20529 papayawhip: 16773077,
20530 peachpuff: 16767673,
20534 powderblue: 11591910,
20536 rebeccapurple: 6697881,
20538 rosybrown: 12357519,
20539 royalblue: 4286945,
20540 saddlebrown: 9127187,
20542 sandybrown: 16032864,
20544 seashell: 16774638,
20548 slateblue: 6970061,
20549 slategray: 7372944,
20550 slategrey: 7372944,
20552 springgreen: 65407,
20553 steelblue: 4620980,
20558 turquoise: 4251856,
20562 whitesmoke: 16119285,
20564 yellowgreen: 10145074
20566 define_default(Color, color, {
20568 return Object.assign(new this.constructor(), this, channels);
20571 return this.rgb().displayable();
20573 hex: color_formatHex,
20574 // Deprecated! Use color.formatHex.
20575 formatHex: color_formatHex,
20576 formatHex8: color_formatHex8,
20577 formatHsl: color_formatHsl,
20578 formatRgb: color_formatRgb,
20579 toString: color_formatRgb
20581 function color_formatHex() {
20582 return this.rgb().formatHex();
20584 function color_formatHex8() {
20585 return this.rgb().formatHex8();
20587 function color_formatHsl() {
20588 return hslConvert(this).formatHsl();
20590 function color_formatRgb() {
20591 return this.rgb().formatRgb();
20593 function color(format2) {
20595 format2 = (format2 + "").trim().toLowerCase();
20596 return (m = reHex.exec(format2)) ? (l = m[1].length, m = parseInt(m[1], 16), l === 6 ? rgbn(m) : l === 3 ? new Rgb(m >> 8 & 15 | m >> 4 & 240, m >> 4 & 15 | m & 240, (m & 15) << 4 | m & 15, 1) : l === 8 ? rgba(m >> 24 & 255, m >> 16 & 255, m >> 8 & 255, (m & 255) / 255) : l === 4 ? rgba(m >> 12 & 15 | m >> 8 & 240, m >> 8 & 15 | m >> 4 & 240, m >> 4 & 15 | m & 240, ((m & 15) << 4 | m & 15) / 255) : null) : (m = reRgbInteger.exec(format2)) ? new Rgb(m[1], m[2], m[3], 1) : (m = reRgbPercent.exec(format2)) ? new Rgb(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, 1) : (m = reRgbaInteger.exec(format2)) ? rgba(m[1], m[2], m[3], m[4]) : (m = reRgbaPercent.exec(format2)) ? rgba(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, m[4]) : (m = reHslPercent.exec(format2)) ? hsla(m[1], m[2] / 100, m[3] / 100, 1) : (m = reHslaPercent.exec(format2)) ? hsla(m[1], m[2] / 100, m[3] / 100, m[4]) : named.hasOwnProperty(format2) ? rgbn(named[format2]) : format2 === "transparent" ? new Rgb(NaN, NaN, NaN, 0) : null;
20598 function rgbn(n2) {
20599 return new Rgb(n2 >> 16 & 255, n2 >> 8 & 255, n2 & 255, 1);
20601 function rgba(r, g, b, a) {
20604 return new Rgb(r, g, b, a);
20606 function rgbConvert(o) {
20607 if (!(o instanceof Color))
20612 return new Rgb(o.r, o.g, o.b, o.opacity);
20614 function rgb(r, g, b, opacity) {
20615 return arguments.length === 1 ? rgbConvert(r) : new Rgb(r, g, b, opacity == null ? 1 : opacity);
20617 function Rgb(r, g, b, opacity) {
20621 this.opacity = +opacity;
20623 define_default(Rgb, rgb, extend(Color, {
20625 k = k == null ? brighter : Math.pow(brighter, k);
20626 return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);
20629 k = k == null ? darker : Math.pow(darker, k);
20630 return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);
20636 return new Rgb(clampi(this.r), clampi(this.g), clampi(this.b), clampa(this.opacity));
20639 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);
20641 hex: rgb_formatHex,
20642 // Deprecated! Use color.formatHex.
20643 formatHex: rgb_formatHex,
20644 formatHex8: rgb_formatHex8,
20645 formatRgb: rgb_formatRgb,
20646 toString: rgb_formatRgb
20648 function rgb_formatHex() {
20649 return `#${hex(this.r)}${hex(this.g)}${hex(this.b)}`;
20651 function rgb_formatHex8() {
20652 return `#${hex(this.r)}${hex(this.g)}${hex(this.b)}${hex((isNaN(this.opacity) ? 1 : this.opacity) * 255)}`;
20654 function rgb_formatRgb() {
20655 const a = clampa(this.opacity);
20656 return `${a === 1 ? "rgb(" : "rgba("}${clampi(this.r)}, ${clampi(this.g)}, ${clampi(this.b)}${a === 1 ? ")" : `, ${a})`}`;
20658 function clampa(opacity) {
20659 return isNaN(opacity) ? 1 : Math.max(0, Math.min(1, opacity));
20661 function clampi(value) {
20662 return Math.max(0, Math.min(255, Math.round(value) || 0));
20664 function hex(value) {
20665 value = clampi(value);
20666 return (value < 16 ? "0" : "") + value.toString(16);
20668 function hsla(h, s, l, a) {
20671 else if (l <= 0 || l >= 1)
20675 return new Hsl(h, s, l, a);
20677 function hslConvert(o) {
20678 if (o instanceof Hsl)
20679 return new Hsl(o.h, o.s, o.l, o.opacity);
20680 if (!(o instanceof Color))
20684 if (o instanceof Hsl)
20687 var r = o.r / 255, g = o.g / 255, b = o.b / 255, min3 = Math.min(r, g, b), max3 = Math.max(r, g, b), h = NaN, s = max3 - min3, l = (max3 + min3) / 2;
20690 h = (g - b) / s + (g < b) * 6;
20691 else if (g === max3)
20692 h = (b - r) / s + 2;
20694 h = (r - g) / s + 4;
20695 s /= l < 0.5 ? max3 + min3 : 2 - max3 - min3;
20698 s = l > 0 && l < 1 ? 0 : h;
20700 return new Hsl(h, s, l, o.opacity);
20702 function hsl(h, s, l, opacity) {
20703 return arguments.length === 1 ? hslConvert(h) : new Hsl(h, s, l, opacity == null ? 1 : opacity);
20705 function Hsl(h, s, l, opacity) {
20709 this.opacity = +opacity;
20711 define_default(Hsl, hsl, extend(Color, {
20713 k = k == null ? brighter : Math.pow(brighter, k);
20714 return new Hsl(this.h, this.s, this.l * k, this.opacity);
20717 k = k == null ? darker : Math.pow(darker, k);
20718 return new Hsl(this.h, this.s, this.l * k, this.opacity);
20721 var h = this.h % 360 + (this.h < 0) * 360, s = isNaN(h) || isNaN(this.s) ? 0 : this.s, l = this.l, m2 = l + (l < 0.5 ? l : 1 - l) * s, m1 = 2 * l - m2;
20723 hsl2rgb(h >= 240 ? h - 240 : h + 120, m1, m2),
20724 hsl2rgb(h, m1, m2),
20725 hsl2rgb(h < 120 ? h + 240 : h - 120, m1, m2),
20730 return new Hsl(clamph(this.h), clampt(this.s), clampt(this.l), clampa(this.opacity));
20733 return (0 <= this.s && this.s <= 1 || isNaN(this.s)) && (0 <= this.l && this.l <= 1) && (0 <= this.opacity && this.opacity <= 1);
20736 const a = clampa(this.opacity);
20737 return `${a === 1 ? "hsl(" : "hsla("}${clamph(this.h)}, ${clampt(this.s) * 100}%, ${clampt(this.l) * 100}%${a === 1 ? ")" : `, ${a})`}`;
20740 function clamph(value) {
20741 value = (value || 0) % 360;
20742 return value < 0 ? value + 360 : value;
20744 function clampt(value) {
20745 return Math.max(0, Math.min(1, value || 0));
20747 function hsl2rgb(h, m1, m2) {
20748 return (h < 60 ? m1 + (m2 - m1) * h / 60 : h < 180 ? m2 : h < 240 ? m1 + (m2 - m1) * (240 - h) / 60 : m1) * 255;
20751 // node_modules/d3-interpolate/src/basis.js
20752 function basis(t1, v0, v1, v2, v3) {
20753 var t2 = t1 * t1, t3 = t2 * t1;
20754 return ((1 - 3 * t1 + 3 * t2 - t3) * v0 + (4 - 6 * t2 + 3 * t3) * v1 + (1 + 3 * t1 + 3 * t2 - 3 * t3) * v2 + t3 * v3) / 6;
20756 function basis_default(values) {
20757 var n2 = values.length - 1;
20758 return function(t) {
20759 var i2 = t <= 0 ? t = 0 : t >= 1 ? (t = 1, n2 - 1) : Math.floor(t * n2), v1 = values[i2], v2 = values[i2 + 1], v0 = i2 > 0 ? values[i2 - 1] : 2 * v1 - v2, v3 = i2 < n2 - 1 ? values[i2 + 2] : 2 * v2 - v1;
20760 return basis((t - i2 / n2) * n2, v0, v1, v2, v3);
20764 // node_modules/d3-interpolate/src/basisClosed.js
20765 function basisClosed_default(values) {
20766 var n2 = values.length;
20767 return function(t) {
20768 var i2 = Math.floor(((t %= 1) < 0 ? ++t : t) * n2), v0 = values[(i2 + n2 - 1) % n2], v1 = values[i2 % n2], v2 = values[(i2 + 1) % n2], v3 = values[(i2 + 2) % n2];
20769 return basis((t - i2 / n2) * n2, v0, v1, v2, v3);
20773 // node_modules/d3-interpolate/src/constant.js
20774 var constant_default3 = (x) => () => x;
20776 // node_modules/d3-interpolate/src/color.js
20777 function linear(a, d) {
20778 return function(t) {
20782 function exponential(a, b, y) {
20783 return a = Math.pow(a, y), b = Math.pow(b, y) - a, y = 1 / y, function(t) {
20784 return Math.pow(a + t * b, y);
20787 function gamma(y) {
20788 return (y = +y) === 1 ? nogamma : function(a, b) {
20789 return b - a ? exponential(a, b, y) : constant_default3(isNaN(a) ? b : a);
20792 function nogamma(a, b) {
20794 return d ? linear(a, d) : constant_default3(isNaN(a) ? b : a);
20797 // node_modules/d3-interpolate/src/rgb.js
20798 var rgb_default = function rgbGamma(y) {
20799 var color2 = gamma(y);
20800 function rgb2(start2, end) {
20801 var r = color2((start2 = rgb(start2)).r, (end = rgb(end)).r), g = color2(start2.g, end.g), b = color2(start2.b, end.b), opacity = nogamma(start2.opacity, end.opacity);
20802 return function(t) {
20806 start2.opacity = opacity(t);
20807 return start2 + "";
20810 rgb2.gamma = rgbGamma;
20813 function rgbSpline(spline) {
20814 return function(colors) {
20815 var n2 = colors.length, r = new Array(n2), g = new Array(n2), b = new Array(n2), i2, color2;
20816 for (i2 = 0; i2 < n2; ++i2) {
20817 color2 = rgb(colors[i2]);
20818 r[i2] = color2.r || 0;
20819 g[i2] = color2.g || 0;
20820 b[i2] = color2.b || 0;
20825 color2.opacity = 1;
20826 return function(t) {
20830 return color2 + "";
20834 var rgbBasis = rgbSpline(basis_default);
20835 var rgbBasisClosed = rgbSpline(basisClosed_default);
20837 // node_modules/d3-interpolate/src/numberArray.js
20838 function numberArray_default(a, b) {
20841 var n2 = a ? Math.min(b.length, a.length) : 0, c = b.slice(), i2;
20842 return function(t) {
20843 for (i2 = 0; i2 < n2; ++i2)
20844 c[i2] = a[i2] * (1 - t) + b[i2] * t;
20848 function isNumberArray(x) {
20849 return ArrayBuffer.isView(x) && !(x instanceof DataView);
20852 // node_modules/d3-interpolate/src/array.js
20853 function genericArray(a, b) {
20854 var nb = b ? b.length : 0, na = a ? Math.min(nb, a.length) : 0, x = new Array(na), c = new Array(nb), i2;
20855 for (i2 = 0; i2 < na; ++i2)
20856 x[i2] = value_default(a[i2], b[i2]);
20857 for (; i2 < nb; ++i2)
20859 return function(t) {
20860 for (i2 = 0; i2 < na; ++i2)
20866 // node_modules/d3-interpolate/src/date.js
20867 function date_default(a, b) {
20868 var d = /* @__PURE__ */ new Date();
20869 return a = +a, b = +b, function(t) {
20870 return d.setTime(a * (1 - t) + b * t), d;
20874 // node_modules/d3-interpolate/src/number.js
20875 function number_default(a, b) {
20876 return a = +a, b = +b, function(t) {
20877 return a * (1 - t) + b * t;
20881 // node_modules/d3-interpolate/src/object.js
20882 function object_default(a, b) {
20883 var i2 = {}, c = {}, k;
20884 if (a === null || typeof a !== "object")
20886 if (b === null || typeof b !== "object")
20890 i2[k] = value_default(a[k], b[k]);
20895 return function(t) {
20902 // node_modules/d3-interpolate/src/string.js
20903 var reA = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g;
20904 var reB = new RegExp(reA.source, "g");
20905 function zero2(b) {
20906 return function() {
20911 return function(t) {
20915 function string_default(a, b) {
20916 var bi = reA.lastIndex = reB.lastIndex = 0, am, bm, bs, i2 = -1, s = [], q = [];
20917 a = a + "", b = b + "";
20918 while ((am = reA.exec(a)) && (bm = reB.exec(b))) {
20919 if ((bs = bm.index) > bi) {
20920 bs = b.slice(bi, bs);
20926 if ((am = am[0]) === (bm = bm[0])) {
20933 q.push({ i: i2, x: number_default(am, bm) });
20935 bi = reB.lastIndex;
20937 if (bi < b.length) {
20944 return s.length < 2 ? q[0] ? one(q[0].x) : zero2(b) : (b = q.length, function(t) {
20945 for (var i3 = 0, o; i3 < b; ++i3)
20946 s[(o = q[i3]).i] = o.x(t);
20951 // node_modules/d3-interpolate/src/value.js
20952 function value_default(a, b) {
20953 var t = typeof b, c;
20954 return b == null || t === "boolean" ? constant_default3(b) : (t === "number" ? number_default : t === "string" ? (c = color(b)) ? (b = c, rgb_default) : string_default : b instanceof color ? rgb_default : b instanceof Date ? date_default : isNumberArray(b) ? numberArray_default : Array.isArray(b) ? genericArray : typeof b.valueOf !== "function" && typeof b.toString !== "function" || isNaN(b) ? object_default : number_default)(a, b);
20957 // node_modules/d3-interpolate/src/round.js
20958 function round_default(a, b) {
20959 return a = +a, b = +b, function(t) {
20960 return Math.round(a * (1 - t) + b * t);
20964 // node_modules/d3-interpolate/src/transform/decompose.js
20965 var degrees2 = 180 / Math.PI;
20974 function decompose_default(a, b, c, d, e, f2) {
20975 var scaleX, scaleY, skewX;
20976 if (scaleX = Math.sqrt(a * a + b * b))
20977 a /= scaleX, b /= scaleX;
20978 if (skewX = a * c + b * d)
20979 c -= a * skewX, d -= b * skewX;
20980 if (scaleY = Math.sqrt(c * c + d * d))
20981 c /= scaleY, d /= scaleY, skewX /= scaleY;
20983 a = -a, b = -b, skewX = -skewX, scaleX = -scaleX;
20987 rotate: Math.atan2(b, a) * degrees2,
20988 skewX: Math.atan(skewX) * degrees2,
20994 // node_modules/d3-interpolate/src/transform/parse.js
20996 function parseCss(value) {
20997 const m = new (typeof DOMMatrix === "function" ? DOMMatrix : WebKitCSSMatrix)(value + "");
20998 return m.isIdentity ? identity : decompose_default(m.a, m.b, m.c, m.d, m.e, m.f);
21000 function parseSvg(value) {
21004 svgNode = document.createElementNS("http://www.w3.org/2000/svg", "g");
21005 svgNode.setAttribute("transform", value);
21006 if (!(value = svgNode.transform.baseVal.consolidate()))
21008 value = value.matrix;
21009 return decompose_default(value.a, value.b, value.c, value.d, value.e, value.f);
21012 // node_modules/d3-interpolate/src/transform/index.js
21013 function interpolateTransform(parse, pxComma, pxParen, degParen) {
21015 return s.length ? s.pop() + " " : "";
21017 function translate(xa, ya, xb, yb, s, q) {
21018 if (xa !== xb || ya !== yb) {
21019 var i2 = s.push("translate(", null, pxComma, null, pxParen);
21020 q.push({ i: i2 - 4, x: number_default(xa, xb) }, { i: i2 - 2, x: number_default(ya, yb) });
21021 } else if (xb || yb) {
21022 s.push("translate(" + xb + pxComma + yb + pxParen);
21025 function rotate(a, b, s, q) {
21029 else if (b - a > 180)
21031 q.push({ i: s.push(pop(s) + "rotate(", null, degParen) - 2, x: number_default(a, b) });
21033 s.push(pop(s) + "rotate(" + b + degParen);
21036 function skewX(a, b, s, q) {
21038 q.push({ i: s.push(pop(s) + "skewX(", null, degParen) - 2, x: number_default(a, b) });
21040 s.push(pop(s) + "skewX(" + b + degParen);
21043 function scale(xa, ya, xb, yb, s, q) {
21044 if (xa !== xb || ya !== yb) {
21045 var i2 = s.push(pop(s) + "scale(", null, ",", null, ")");
21046 q.push({ i: i2 - 4, x: number_default(xa, xb) }, { i: i2 - 2, x: number_default(ya, yb) });
21047 } else if (xb !== 1 || yb !== 1) {
21048 s.push(pop(s) + "scale(" + xb + "," + yb + ")");
21051 return function(a, b) {
21052 var s = [], q = [];
21053 a = parse(a), b = parse(b);
21054 translate(a.translateX, a.translateY, b.translateX, b.translateY, s, q);
21055 rotate(a.rotate, b.rotate, s, q);
21056 skewX(a.skewX, b.skewX, s, q);
21057 scale(a.scaleX, a.scaleY, b.scaleX, b.scaleY, s, q);
21059 return function(t) {
21060 var i2 = -1, n2 = q.length, o;
21062 s[(o = q[i2]).i] = o.x(t);
21067 var interpolateTransformCss = interpolateTransform(parseCss, "px, ", "px)", "deg)");
21068 var interpolateTransformSvg = interpolateTransform(parseSvg, ", ", ")", ")");
21070 // node_modules/d3-interpolate/src/zoom.js
21071 var epsilon22 = 1e-12;
21073 return ((x = Math.exp(x)) + 1 / x) / 2;
21076 return ((x = Math.exp(x)) - 1 / x) / 2;
21079 return ((x = Math.exp(2 * x)) - 1) / (x + 1);
21081 var zoom_default = function zoomRho(rho, rho2, rho4) {
21082 function zoom(p02, p1) {
21083 var ux0 = p02[0], uy0 = p02[1], w0 = p02[2], ux1 = p1[0], uy1 = p1[1], w1 = p1[2], dx = ux1 - ux0, dy = uy1 - uy0, d2 = dx * dx + dy * dy, i2, S;
21084 if (d2 < epsilon22) {
21085 S = Math.log(w1 / w0) / rho;
21090 w0 * Math.exp(rho * t * S)
21094 var d1 = Math.sqrt(d2), b0 = (w1 * w1 - w0 * w0 + rho4 * d2) / (2 * w0 * rho2 * d1), b1 = (w1 * w1 - w0 * w0 - rho4 * d2) / (2 * w1 * rho2 * d1), r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0), r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1);
21095 S = (r1 - r0) / rho;
21097 var s = t * S, coshr0 = cosh(r0), u = w0 / (rho2 * d1) * (coshr0 * tanh(rho * s + r0) - sinh(r0));
21101 w0 * coshr0 / cosh(rho * s + r0)
21105 i2.duration = S * 1e3 * rho / Math.SQRT2;
21108 zoom.rho = function(_) {
21109 var _1 = Math.max(1e-3, +_), _2 = _1 * _1, _4 = _2 * _2;
21110 return zoomRho(_1, _2, _4);
21113 }(Math.SQRT2, 2, 4);
21115 // node_modules/d3-interpolate/src/quantize.js
21116 function quantize_default(interpolator, n2) {
21117 var samples = new Array(n2);
21118 for (var i2 = 0; i2 < n2; ++i2)
21119 samples[i2] = interpolator(i2 / (n2 - 1));
21123 // node_modules/d3-timer/src/timer.js
21127 var pokeDelay = 1e3;
21133 var clock = typeof performance === "object" && performance.now ? performance : Date;
21134 var setFrame = typeof window === "object" && window.requestAnimationFrame ? window.requestAnimationFrame.bind(window) : function(f2) {
21135 setTimeout(f2, 17);
21138 return clockNow || (setFrame(clearNow), clockNow = clock.now() + clockSkew);
21140 function clearNow() {
21144 this._call = this._time = this._next = null;
21146 Timer.prototype = timer.prototype = {
21147 constructor: Timer,
21148 restart: function(callback, delay, time) {
21149 if (typeof callback !== "function")
21150 throw new TypeError("callback is not a function");
21151 time = (time == null ? now() : +time) + (delay == null ? 0 : +delay);
21152 if (!this._next && taskTail !== this) {
21154 taskTail._next = this;
21159 this._call = callback;
21166 this._time = Infinity;
21171 function timer(callback, delay, time) {
21172 var t = new Timer();
21173 t.restart(callback, delay, time);
21176 function timerFlush() {
21179 var t = taskHead, e;
21181 if ((e = clockNow - t._time) >= 0)
21182 t._call.call(void 0, e);
21188 clockNow = (clockLast = clock.now()) + clockSkew;
21189 frame = timeout = 0;
21199 var now3 = clock.now(), delay = now3 - clockLast;
21200 if (delay > pokeDelay)
21201 clockSkew -= delay, clockLast = now3;
21204 var t0, t1 = taskHead, t2, time = Infinity;
21207 if (time > t1._time)
21209 t0 = t1, t1 = t1._next;
21211 t2 = t1._next, t1._next = null;
21212 t1 = t0 ? t0._next = t2 : taskHead = t2;
21218 function sleep(time) {
21222 timeout = clearTimeout(timeout);
21223 var delay = time - clockNow;
21225 if (time < Infinity)
21226 timeout = setTimeout(wake, time - clock.now() - clockSkew);
21228 interval = clearInterval(interval);
21231 clockLast = clock.now(), interval = setInterval(poke, pokeDelay);
21232 frame = 1, setFrame(wake);
21236 // node_modules/d3-timer/src/timeout.js
21237 function timeout_default(callback, delay, time) {
21238 var t = new Timer();
21239 delay = delay == null ? 0 : +delay;
21240 t.restart((elapsed) => {
21242 callback(elapsed + delay);
21247 // node_modules/d3-transition/src/transition/schedule.js
21248 var emptyOn = dispatch_default("start", "end", "cancel", "interrupt");
21249 var emptyTween = [];
21257 function schedule_default(node, name, id2, index, group, timing) {
21258 var schedules = node.__transition;
21260 node.__transition = {};
21261 else if (id2 in schedules)
21263 create(node, id2, {
21266 // For context during callback.
21268 // For context during callback.
21272 delay: timing.delay,
21273 duration: timing.duration,
21279 function init(node, id2) {
21280 var schedule = get2(node, id2);
21281 if (schedule.state > CREATED)
21282 throw new Error("too late; already scheduled");
21285 function set2(node, id2) {
21286 var schedule = get2(node, id2);
21287 if (schedule.state > STARTED)
21288 throw new Error("too late; already running");
21291 function get2(node, id2) {
21292 var schedule = node.__transition;
21293 if (!schedule || !(schedule = schedule[id2]))
21294 throw new Error("transition not found");
21297 function create(node, id2, self2) {
21298 var schedules = node.__transition, tween;
21299 schedules[id2] = self2;
21300 self2.timer = timer(schedule, 0, self2.time);
21301 function schedule(elapsed) {
21302 self2.state = SCHEDULED;
21303 self2.timer.restart(start2, self2.delay, self2.time);
21304 if (self2.delay <= elapsed)
21305 start2(elapsed - self2.delay);
21307 function start2(elapsed) {
21309 if (self2.state !== SCHEDULED)
21311 for (i2 in schedules) {
21313 if (o.name !== self2.name)
21315 if (o.state === STARTED)
21316 return timeout_default(start2);
21317 if (o.state === RUNNING) {
21320 o.on.call("interrupt", node, node.__data__, o.index, o.group);
21321 delete schedules[i2];
21322 } else if (+i2 < id2) {
21325 o.on.call("cancel", node, node.__data__, o.index, o.group);
21326 delete schedules[i2];
21329 timeout_default(function() {
21330 if (self2.state === STARTED) {
21331 self2.state = RUNNING;
21332 self2.timer.restart(tick, self2.delay, self2.time);
21336 self2.state = STARTING;
21337 self2.on.call("start", node, node.__data__, self2.index, self2.group);
21338 if (self2.state !== STARTING)
21340 self2.state = STARTED;
21341 tween = new Array(n2 = self2.tween.length);
21342 for (i2 = 0, j2 = -1; i2 < n2; ++i2) {
21343 if (o = self2.tween[i2].value.call(node, node.__data__, self2.index, self2.group)) {
21347 tween.length = j2 + 1;
21349 function tick(elapsed) {
21350 var t = elapsed < self2.duration ? self2.ease.call(null, elapsed / self2.duration) : (self2.timer.restart(stop), self2.state = ENDING, 1), i2 = -1, n2 = tween.length;
21351 while (++i2 < n2) {
21352 tween[i2].call(node, t);
21354 if (self2.state === ENDING) {
21355 self2.on.call("end", node, node.__data__, self2.index, self2.group);
21360 self2.state = ENDED;
21361 self2.timer.stop();
21362 delete schedules[id2];
21363 for (var i2 in schedules)
21365 delete node.__transition;
21369 // node_modules/d3-transition/src/interrupt.js
21370 function interrupt_default(node, name) {
21371 var schedules = node.__transition, schedule, active, empty2 = true, i2;
21374 name = name == null ? null : name + "";
21375 for (i2 in schedules) {
21376 if ((schedule = schedules[i2]).name !== name) {
21380 active = schedule.state > STARTING && schedule.state < ENDING;
21381 schedule.state = ENDED;
21382 schedule.timer.stop();
21383 schedule.on.call(active ? "interrupt" : "cancel", node, node.__data__, schedule.index, schedule.group);
21384 delete schedules[i2];
21387 delete node.__transition;
21390 // node_modules/d3-transition/src/selection/interrupt.js
21391 function interrupt_default2(name) {
21392 return this.each(function() {
21393 interrupt_default(this, name);
21397 // node_modules/d3-transition/src/transition/tween.js
21398 function tweenRemove(id2, name) {
21399 var tween0, tween1;
21400 return function() {
21401 var schedule = set2(this, id2), tween = schedule.tween;
21402 if (tween !== tween0) {
21403 tween1 = tween0 = tween;
21404 for (var i2 = 0, n2 = tween1.length; i2 < n2; ++i2) {
21405 if (tween1[i2].name === name) {
21406 tween1 = tween1.slice();
21407 tween1.splice(i2, 1);
21412 schedule.tween = tween1;
21415 function tweenFunction(id2, name, value) {
21416 var tween0, tween1;
21417 if (typeof value !== "function")
21419 return function() {
21420 var schedule = set2(this, id2), tween = schedule.tween;
21421 if (tween !== tween0) {
21422 tween1 = (tween0 = tween).slice();
21423 for (var t = { name, value }, i2 = 0, n2 = tween1.length; i2 < n2; ++i2) {
21424 if (tween1[i2].name === name) {
21432 schedule.tween = tween1;
21435 function tween_default(name, value) {
21436 var id2 = this._id;
21438 if (arguments.length < 2) {
21439 var tween = get2(this.node(), id2).tween;
21440 for (var i2 = 0, n2 = tween.length, t; i2 < n2; ++i2) {
21441 if ((t = tween[i2]).name === name) {
21447 return this.each((value == null ? tweenRemove : tweenFunction)(id2, name, value));
21449 function tweenValue(transition2, name, value) {
21450 var id2 = transition2._id;
21451 transition2.each(function() {
21452 var schedule = set2(this, id2);
21453 (schedule.value || (schedule.value = {}))[name] = value.apply(this, arguments);
21455 return function(node) {
21456 return get2(node, id2).value[name];
21460 // node_modules/d3-transition/src/transition/interpolate.js
21461 function interpolate_default(a, b) {
21463 return (typeof b === "number" ? number_default : b instanceof color ? rgb_default : (c = color(b)) ? (b = c, rgb_default) : string_default)(a, b);
21466 // node_modules/d3-transition/src/transition/attr.js
21467 function attrRemove2(name) {
21468 return function() {
21469 this.removeAttribute(name);
21472 function attrRemoveNS2(fullname) {
21473 return function() {
21474 this.removeAttributeNS(fullname.space, fullname.local);
21477 function attrConstant2(name, interpolate, value1) {
21478 var string00, string1 = value1 + "", interpolate0;
21479 return function() {
21480 var string0 = this.getAttribute(name);
21481 return string0 === string1 ? null : string0 === string00 ? interpolate0 : interpolate0 = interpolate(string00 = string0, value1);
21484 function attrConstantNS2(fullname, interpolate, value1) {
21485 var string00, string1 = value1 + "", interpolate0;
21486 return function() {
21487 var string0 = this.getAttributeNS(fullname.space, fullname.local);
21488 return string0 === string1 ? null : string0 === string00 ? interpolate0 : interpolate0 = interpolate(string00 = string0, value1);
21491 function attrFunction2(name, interpolate, value) {
21492 var string00, string10, interpolate0;
21493 return function() {
21494 var string0, value1 = value(this), string1;
21495 if (value1 == null)
21496 return void this.removeAttribute(name);
21497 string0 = this.getAttribute(name);
21498 string1 = value1 + "";
21499 return string0 === string1 ? null : string0 === string00 && string1 === string10 ? interpolate0 : (string10 = string1, interpolate0 = interpolate(string00 = string0, value1));
21502 function attrFunctionNS2(fullname, interpolate, value) {
21503 var string00, string10, interpolate0;
21504 return function() {
21505 var string0, value1 = value(this), string1;
21506 if (value1 == null)
21507 return void this.removeAttributeNS(fullname.space, fullname.local);
21508 string0 = this.getAttributeNS(fullname.space, fullname.local);
21509 string1 = value1 + "";
21510 return string0 === string1 ? null : string0 === string00 && string1 === string10 ? interpolate0 : (string10 = string1, interpolate0 = interpolate(string00 = string0, value1));
21513 function attr_default2(name, value) {
21514 var fullname = namespace_default(name), i2 = fullname === "transform" ? interpolateTransformSvg : interpolate_default;
21515 return this.attrTween(name, typeof value === "function" ? (fullname.local ? attrFunctionNS2 : attrFunction2)(fullname, i2, tweenValue(this, "attr." + name, value)) : value == null ? (fullname.local ? attrRemoveNS2 : attrRemove2)(fullname) : (fullname.local ? attrConstantNS2 : attrConstant2)(fullname, i2, value));
21518 // node_modules/d3-transition/src/transition/attrTween.js
21519 function attrInterpolate(name, i2) {
21520 return function(t) {
21521 this.setAttribute(name, i2.call(this, t));
21524 function attrInterpolateNS(fullname, i2) {
21525 return function(t) {
21526 this.setAttributeNS(fullname.space, fullname.local, i2.call(this, t));
21529 function attrTweenNS(fullname, value) {
21532 var i2 = value.apply(this, arguments);
21534 t0 = (i0 = i2) && attrInterpolateNS(fullname, i2);
21537 tween._value = value;
21540 function attrTween(name, value) {
21543 var i2 = value.apply(this, arguments);
21545 t0 = (i0 = i2) && attrInterpolate(name, i2);
21548 tween._value = value;
21551 function attrTween_default(name, value) {
21552 var key = "attr." + name;
21553 if (arguments.length < 2)
21554 return (key = this.tween(key)) && key._value;
21556 return this.tween(key, null);
21557 if (typeof value !== "function")
21559 var fullname = namespace_default(name);
21560 return this.tween(key, (fullname.local ? attrTweenNS : attrTween)(fullname, value));
21563 // node_modules/d3-transition/src/transition/delay.js
21564 function delayFunction(id2, value) {
21565 return function() {
21566 init(this, id2).delay = +value.apply(this, arguments);
21569 function delayConstant(id2, value) {
21570 return value = +value, function() {
21571 init(this, id2).delay = value;
21574 function delay_default(value) {
21575 var id2 = this._id;
21576 return arguments.length ? this.each((typeof value === "function" ? delayFunction : delayConstant)(id2, value)) : get2(this.node(), id2).delay;
21579 // node_modules/d3-transition/src/transition/duration.js
21580 function durationFunction(id2, value) {
21581 return function() {
21582 set2(this, id2).duration = +value.apply(this, arguments);
21585 function durationConstant(id2, value) {
21586 return value = +value, function() {
21587 set2(this, id2).duration = value;
21590 function duration_default(value) {
21591 var id2 = this._id;
21592 return arguments.length ? this.each((typeof value === "function" ? durationFunction : durationConstant)(id2, value)) : get2(this.node(), id2).duration;
21595 // node_modules/d3-transition/src/transition/ease.js
21596 function easeConstant(id2, value) {
21597 if (typeof value !== "function")
21599 return function() {
21600 set2(this, id2).ease = value;
21603 function ease_default(value) {
21604 var id2 = this._id;
21605 return arguments.length ? this.each(easeConstant(id2, value)) : get2(this.node(), id2).ease;
21608 // node_modules/d3-transition/src/transition/easeVarying.js
21609 function easeVarying(id2, value) {
21610 return function() {
21611 var v = value.apply(this, arguments);
21612 if (typeof v !== "function")
21614 set2(this, id2).ease = v;
21617 function easeVarying_default(value) {
21618 if (typeof value !== "function")
21620 return this.each(easeVarying(this._id, value));
21623 // node_modules/d3-transition/src/transition/filter.js
21624 function filter_default2(match) {
21625 if (typeof match !== "function")
21626 match = matcher_default(match);
21627 for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j2 = 0; j2 < m; ++j2) {
21628 for (var group = groups[j2], n2 = group.length, subgroup = subgroups[j2] = [], node, i2 = 0; i2 < n2; ++i2) {
21629 if ((node = group[i2]) && match.call(node, node.__data__, i2, group)) {
21630 subgroup.push(node);
21634 return new Transition(subgroups, this._parents, this._name, this._id);
21637 // node_modules/d3-transition/src/transition/merge.js
21638 function merge_default2(transition2) {
21639 if (transition2._id !== this._id)
21641 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) {
21642 for (var group0 = groups0[j2], group1 = groups1[j2], n2 = group0.length, merge3 = merges[j2] = new Array(n2), node, i2 = 0; i2 < n2; ++i2) {
21643 if (node = group0[i2] || group1[i2]) {
21648 for (; j2 < m0; ++j2) {
21649 merges[j2] = groups0[j2];
21651 return new Transition(merges, this._parents, this._name, this._id);
21654 // node_modules/d3-transition/src/transition/on.js
21655 function start(name) {
21656 return (name + "").trim().split(/^|\s+/).every(function(t) {
21657 var i2 = t.indexOf(".");
21659 t = t.slice(0, i2);
21660 return !t || t === "start";
21663 function onFunction(id2, name, listener) {
21664 var on0, on1, sit = start(name) ? init : set2;
21665 return function() {
21666 var schedule = sit(this, id2), on = schedule.on;
21668 (on1 = (on0 = on).copy()).on(name, listener);
21672 function on_default2(name, listener) {
21673 var id2 = this._id;
21674 return arguments.length < 2 ? get2(this.node(), id2).on.on(name) : this.each(onFunction(id2, name, listener));
21677 // node_modules/d3-transition/src/transition/remove.js
21678 function removeFunction(id2) {
21679 return function() {
21680 var parent = this.parentNode;
21681 for (var i2 in this.__transition)
21685 parent.removeChild(this);
21688 function remove_default2() {
21689 return this.on("end.remove", removeFunction(this._id));
21692 // node_modules/d3-transition/src/transition/select.js
21693 function select_default3(select) {
21694 var name = this._name, id2 = this._id;
21695 if (typeof select !== "function")
21696 select = selector_default(select);
21697 for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j2 = 0; j2 < m; ++j2) {
21698 for (var group = groups[j2], n2 = group.length, subgroup = subgroups[j2] = new Array(n2), node, subnode, i2 = 0; i2 < n2; ++i2) {
21699 if ((node = group[i2]) && (subnode = select.call(node, node.__data__, i2, group))) {
21700 if ("__data__" in node)
21701 subnode.__data__ = node.__data__;
21702 subgroup[i2] = subnode;
21703 schedule_default(subgroup[i2], name, id2, i2, subgroup, get2(node, id2));
21707 return new Transition(subgroups, this._parents, name, id2);
21710 // node_modules/d3-transition/src/transition/selectAll.js
21711 function selectAll_default3(select) {
21712 var name = this._name, id2 = this._id;
21713 if (typeof select !== "function")
21714 select = selectorAll_default(select);
21715 for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j2 = 0; j2 < m; ++j2) {
21716 for (var group = groups[j2], n2 = group.length, node, i2 = 0; i2 < n2; ++i2) {
21717 if (node = group[i2]) {
21718 for (var children2 = select.call(node, node.__data__, i2, group), child, inherit2 = get2(node, id2), k = 0, l = children2.length; k < l; ++k) {
21719 if (child = children2[k]) {
21720 schedule_default(child, name, id2, k, children2, inherit2);
21723 subgroups.push(children2);
21724 parents.push(node);
21728 return new Transition(subgroups, parents, name, id2);
21731 // node_modules/d3-transition/src/transition/selection.js
21732 var Selection2 = selection_default.prototype.constructor;
21733 function selection_default2() {
21734 return new Selection2(this._groups, this._parents);
21737 // node_modules/d3-transition/src/transition/style.js
21738 function styleNull(name, interpolate) {
21739 var string00, string10, interpolate0;
21740 return function() {
21741 var string0 = styleValue(this, name), string1 = (this.style.removeProperty(name), styleValue(this, name));
21742 return string0 === string1 ? null : string0 === string00 && string1 === string10 ? interpolate0 : interpolate0 = interpolate(string00 = string0, string10 = string1);
21745 function styleRemove2(name) {
21746 return function() {
21747 this.style.removeProperty(name);
21750 function styleConstant2(name, interpolate, value1) {
21751 var string00, string1 = value1 + "", interpolate0;
21752 return function() {
21753 var string0 = styleValue(this, name);
21754 return string0 === string1 ? null : string0 === string00 ? interpolate0 : interpolate0 = interpolate(string00 = string0, value1);
21757 function styleFunction2(name, interpolate, value) {
21758 var string00, string10, interpolate0;
21759 return function() {
21760 var string0 = styleValue(this, name), value1 = value(this), string1 = value1 + "";
21761 if (value1 == null)
21762 string1 = value1 = (this.style.removeProperty(name), styleValue(this, name));
21763 return string0 === string1 ? null : string0 === string00 && string1 === string10 ? interpolate0 : (string10 = string1, interpolate0 = interpolate(string00 = string0, value1));
21766 function styleMaybeRemove(id2, name) {
21767 var on0, on1, listener0, key = "style." + name, event = "end." + key, remove2;
21768 return function() {
21769 var schedule = set2(this, id2), on = schedule.on, listener = schedule.value[key] == null ? remove2 || (remove2 = styleRemove2(name)) : void 0;
21770 if (on !== on0 || listener0 !== listener)
21771 (on1 = (on0 = on).copy()).on(event, listener0 = listener);
21775 function style_default2(name, value, priority) {
21776 var i2 = (name += "") === "transform" ? interpolateTransformCss : interpolate_default;
21777 return value == null ? this.styleTween(name, styleNull(name, i2)).on("end.style." + name, styleRemove2(name)) : typeof value === "function" ? this.styleTween(name, styleFunction2(name, i2, tweenValue(this, "style." + name, value))).each(styleMaybeRemove(this._id, name)) : this.styleTween(name, styleConstant2(name, i2, value), priority).on("end.style." + name, null);
21780 // node_modules/d3-transition/src/transition/styleTween.js
21781 function styleInterpolate(name, i2, priority) {
21782 return function(t) {
21783 this.style.setProperty(name, i2.call(this, t), priority);
21786 function styleTween(name, value, priority) {
21789 var i2 = value.apply(this, arguments);
21791 t = (i0 = i2) && styleInterpolate(name, i2, priority);
21794 tween._value = value;
21797 function styleTween_default(name, value, priority) {
21798 var key = "style." + (name += "");
21799 if (arguments.length < 2)
21800 return (key = this.tween(key)) && key._value;
21802 return this.tween(key, null);
21803 if (typeof value !== "function")
21805 return this.tween(key, styleTween(name, value, priority == null ? "" : priority));
21808 // node_modules/d3-transition/src/transition/text.js
21809 function textConstant2(value) {
21810 return function() {
21811 this.textContent = value;
21814 function textFunction2(value) {
21815 return function() {
21816 var value1 = value(this);
21817 this.textContent = value1 == null ? "" : value1;
21820 function text_default2(value) {
21821 return this.tween("text", typeof value === "function" ? textFunction2(tweenValue(this, "text", value)) : textConstant2(value == null ? "" : value + ""));
21824 // node_modules/d3-transition/src/transition/textTween.js
21825 function textInterpolate(i2) {
21826 return function(t) {
21827 this.textContent = i2.call(this, t);
21830 function textTween(value) {
21833 var i2 = value.apply(this, arguments);
21835 t0 = (i0 = i2) && textInterpolate(i2);
21838 tween._value = value;
21841 function textTween_default(value) {
21843 if (arguments.length < 1)
21844 return (key = this.tween(key)) && key._value;
21846 return this.tween(key, null);
21847 if (typeof value !== "function")
21849 return this.tween(key, textTween(value));
21852 // node_modules/d3-transition/src/transition/transition.js
21853 function transition_default() {
21854 var name = this._name, id0 = this._id, id1 = newId();
21855 for (var groups = this._groups, m = groups.length, j2 = 0; j2 < m; ++j2) {
21856 for (var group = groups[j2], n2 = group.length, node, i2 = 0; i2 < n2; ++i2) {
21857 if (node = group[i2]) {
21858 var inherit2 = get2(node, id0);
21859 schedule_default(node, name, id1, i2, group, {
21860 time: inherit2.time + inherit2.delay + inherit2.duration,
21862 duration: inherit2.duration,
21863 ease: inherit2.ease
21868 return new Transition(groups, this._parents, name, id1);
21871 // node_modules/d3-transition/src/transition/end.js
21872 function end_default() {
21873 var on0, on1, that = this, id2 = that._id, size = that.size();
21874 return new Promise(function(resolve, reject) {
21875 var cancel = { value: reject }, end = { value: function() {
21879 that.each(function() {
21880 var schedule = set2(this, id2), on = schedule.on;
21882 on1 = (on0 = on).copy();
21883 on1._.cancel.push(cancel);
21884 on1._.interrupt.push(cancel);
21885 on1._.end.push(end);
21894 // node_modules/d3-transition/src/transition/index.js
21896 function Transition(groups, parents, name, id2) {
21897 this._groups = groups;
21898 this._parents = parents;
21902 function transition(name) {
21903 return selection_default().transition(name);
21908 var selection_prototype = selection_default.prototype;
21909 Transition.prototype = transition.prototype = {
21910 constructor: Transition,
21911 select: select_default3,
21912 selectAll: selectAll_default3,
21913 selectChild: selection_prototype.selectChild,
21914 selectChildren: selection_prototype.selectChildren,
21915 filter: filter_default2,
21916 merge: merge_default2,
21917 selection: selection_default2,
21918 transition: transition_default,
21919 call: selection_prototype.call,
21920 nodes: selection_prototype.nodes,
21921 node: selection_prototype.node,
21922 size: selection_prototype.size,
21923 empty: selection_prototype.empty,
21924 each: selection_prototype.each,
21926 attr: attr_default2,
21927 attrTween: attrTween_default,
21928 style: style_default2,
21929 styleTween: styleTween_default,
21930 text: text_default2,
21931 textTween: textTween_default,
21932 remove: remove_default2,
21933 tween: tween_default,
21934 delay: delay_default,
21935 duration: duration_default,
21936 ease: ease_default,
21937 easeVarying: easeVarying_default,
21939 [Symbol.iterator]: selection_prototype[Symbol.iterator]
21942 // node_modules/d3-ease/src/linear.js
21943 var linear2 = (t) => +t;
21945 // node_modules/d3-ease/src/cubic.js
21946 function cubicInOut(t) {
21947 return ((t *= 2) <= 1 ? t * t * t : (t -= 2) * t * t + 2) / 2;
21950 // node_modules/d3-transition/src/selection/transition.js
21951 var defaultTiming = {
21958 function inherit(node, id2) {
21960 while (!(timing = node.__transition) || !(timing = timing[id2])) {
21961 if (!(node = node.parentNode)) {
21962 throw new Error(`transition ${id2} not found`);
21967 function transition_default2(name) {
21969 if (name instanceof Transition) {
21970 id2 = name._id, name = name._name;
21972 id2 = newId(), (timing = defaultTiming).time = now(), name = name == null ? null : name + "";
21974 for (var groups = this._groups, m = groups.length, j2 = 0; j2 < m; ++j2) {
21975 for (var group = groups[j2], n2 = group.length, node, i2 = 0; i2 < n2; ++i2) {
21976 if (node = group[i2]) {
21977 schedule_default(node, name, id2, i2, group, timing || inherit(node, id2));
21981 return new Transition(groups, this._parents, name, id2);
21984 // node_modules/d3-transition/src/selection/index.js
21985 selection_default.prototype.interrupt = interrupt_default2;
21986 selection_default.prototype.transition = transition_default2;
21988 // node_modules/d3-zoom/src/constant.js
21989 var constant_default4 = (x) => () => x;
21991 // node_modules/d3-zoom/src/event.js
21992 function ZoomEvent(type2, {
21995 transform: transform2,
21996 dispatch: dispatch10
21998 Object.defineProperties(this, {
21999 type: { value: type2, enumerable: true, configurable: true },
22000 sourceEvent: { value: sourceEvent, enumerable: true, configurable: true },
22001 target: { value: target, enumerable: true, configurable: true },
22002 transform: { value: transform2, enumerable: true, configurable: true },
22003 _: { value: dispatch10 }
22007 // node_modules/d3-zoom/src/transform.js
22008 function Transform(k, x, y) {
22013 Transform.prototype = {
22014 constructor: Transform,
22015 scale: function(k) {
22016 return k === 1 ? this : new Transform(this.k * k, this.x, this.y);
22018 translate: function(x, y) {
22019 return x === 0 & y === 0 ? this : new Transform(this.k, this.x + this.k * x, this.y + this.k * y);
22021 apply: function(point2) {
22022 return [point2[0] * this.k + this.x, point2[1] * this.k + this.y];
22024 applyX: function(x) {
22025 return x * this.k + this.x;
22027 applyY: function(y) {
22028 return y * this.k + this.y;
22030 invert: function(location) {
22031 return [(location[0] - this.x) / this.k, (location[1] - this.y) / this.k];
22033 invertX: function(x) {
22034 return (x - this.x) / this.k;
22036 invertY: function(y) {
22037 return (y - this.y) / this.k;
22039 rescaleX: function(x) {
22040 return x.copy().domain(x.range().map(this.invertX, this).map(x.invert, x));
22042 rescaleY: function(y) {
22043 return y.copy().domain(y.range().map(this.invertY, this).map(y.invert, y));
22045 toString: function() {
22046 return "translate(" + this.x + "," + this.y + ") scale(" + this.k + ")";
22049 var identity2 = new Transform(1, 0, 0);
22050 transform.prototype = Transform.prototype;
22051 function transform(node) {
22052 while (!node.__zoom)
22053 if (!(node = node.parentNode))
22055 return node.__zoom;
22058 // node_modules/d3-zoom/src/noevent.js
22059 function nopropagation2(event) {
22060 event.stopImmediatePropagation();
22062 function noevent_default2(event) {
22063 event.preventDefault();
22064 event.stopImmediatePropagation();
22067 // node_modules/d3-zoom/src/zoom.js
22068 function defaultFilter2(event) {
22069 return (!event.ctrlKey || event.type === "wheel") && !event.button;
22071 function defaultExtent() {
22073 if (e instanceof SVGElement) {
22074 e = e.ownerSVGElement || e;
22075 if (e.hasAttribute("viewBox")) {
22076 e = e.viewBox.baseVal;
22077 return [[e.x, e.y], [e.x + e.width, e.y + e.height]];
22079 return [[0, 0], [e.width.baseVal.value, e.height.baseVal.value]];
22081 return [[0, 0], [e.clientWidth, e.clientHeight]];
22083 function defaultTransform() {
22084 return this.__zoom || identity2;
22086 function defaultWheelDelta(event) {
22087 return -event.deltaY * (event.deltaMode === 1 ? 0.05 : event.deltaMode ? 1 : 2e-3) * (event.ctrlKey ? 10 : 1);
22089 function defaultTouchable2() {
22090 return navigator.maxTouchPoints || "ontouchstart" in this;
22092 function defaultConstrain(transform2, extent, translateExtent) {
22093 var dx0 = transform2.invertX(extent[0][0]) - translateExtent[0][0], dx1 = transform2.invertX(extent[1][0]) - translateExtent[1][0], dy0 = transform2.invertY(extent[0][1]) - translateExtent[0][1], dy1 = transform2.invertY(extent[1][1]) - translateExtent[1][1];
22094 return transform2.translate(
22095 dx1 > dx0 ? (dx0 + dx1) / 2 : Math.min(0, dx0) || Math.max(0, dx1),
22096 dy1 > dy0 ? (dy0 + dy1) / 2 : Math.min(0, dy0) || Math.max(0, dy1)
22099 function zoom_default2() {
22100 var filter2 = defaultFilter2, extent = defaultExtent, constrain = defaultConstrain, wheelDelta = defaultWheelDelta, touchable = defaultTouchable2, scaleExtent = [0, Infinity], translateExtent = [[-Infinity, -Infinity], [Infinity, Infinity]], duration = 250, interpolate = zoom_default, listeners = dispatch_default("start", "zoom", "end"), touchstarting, touchfirst, touchending, touchDelay = 500, wheelDelay = 150, clickDistance2 = 0, tapDistance = 10;
22101 function zoom(selection2) {
22102 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)");
22104 zoom.transform = function(collection, transform2, point2, event) {
22105 var selection2 = collection.selection ? collection.selection() : collection;
22106 selection2.property("__zoom", defaultTransform);
22107 if (collection !== selection2) {
22108 schedule(collection, transform2, point2, event);
22110 selection2.interrupt().each(function() {
22111 gesture(this, arguments).event(event).start().zoom(null, typeof transform2 === "function" ? transform2.apply(this, arguments) : transform2).end();
22115 zoom.scaleBy = function(selection2, k, p, event) {
22116 zoom.scaleTo(selection2, function() {
22117 var k0 = this.__zoom.k, k1 = typeof k === "function" ? k.apply(this, arguments) : k;
22121 zoom.scaleTo = function(selection2, k, p, event) {
22122 zoom.transform(selection2, function() {
22123 var e = extent.apply(this, arguments), t0 = this.__zoom, p02 = p == null ? centroid(e) : typeof p === "function" ? p.apply(this, arguments) : p, p1 = t0.invert(p02), k1 = typeof k === "function" ? k.apply(this, arguments) : k;
22124 return constrain(translate(scale(t0, k1), p02, p1), e, translateExtent);
22127 zoom.translateBy = function(selection2, x, y, event) {
22128 zoom.transform(selection2, function() {
22129 return constrain(this.__zoom.translate(
22130 typeof x === "function" ? x.apply(this, arguments) : x,
22131 typeof y === "function" ? y.apply(this, arguments) : y
22132 ), extent.apply(this, arguments), translateExtent);
22135 zoom.translateTo = function(selection2, x, y, p, event) {
22136 zoom.transform(selection2, function() {
22137 var e = extent.apply(this, arguments), t = this.__zoom, p02 = p == null ? centroid(e) : typeof p === "function" ? p.apply(this, arguments) : p;
22138 return constrain(identity2.translate(p02[0], p02[1]).scale(t.k).translate(
22139 typeof x === "function" ? -x.apply(this, arguments) : -x,
22140 typeof y === "function" ? -y.apply(this, arguments) : -y
22141 ), e, translateExtent);
22144 function scale(transform2, k) {
22145 k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], k));
22146 return k === transform2.k ? transform2 : new Transform(k, transform2.x, transform2.y);
22148 function translate(transform2, p02, p1) {
22149 var x = p02[0] - p1[0] * transform2.k, y = p02[1] - p1[1] * transform2.k;
22150 return x === transform2.x && y === transform2.y ? transform2 : new Transform(transform2.k, x, y);
22152 function centroid(extent2) {
22153 return [(+extent2[0][0] + +extent2[1][0]) / 2, (+extent2[0][1] + +extent2[1][1]) / 2];
22155 function schedule(transition2, transform2, point2, event) {
22156 transition2.on("start.zoom", function() {
22157 gesture(this, arguments).event(event).start();
22158 }).on("interrupt.zoom end.zoom", function() {
22159 gesture(this, arguments).event(event).end();
22160 }).tween("zoom", function() {
22161 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));
22162 return function(t) {
22166 var l = i2(t), k = w / l[2];
22167 t = new Transform(k, p[0] - l[0] * k, p[1] - l[1] * k);
22173 function gesture(that, args, clean2) {
22174 return !clean2 && that.__zooming || new Gesture(that, args);
22176 function Gesture(that, args) {
22180 this.sourceEvent = null;
22181 this.extent = extent.apply(that, args);
22184 Gesture.prototype = {
22185 event: function(event) {
22187 this.sourceEvent = event;
22190 start: function() {
22191 if (++this.active === 1) {
22192 this.that.__zooming = this;
22193 this.emit("start");
22197 zoom: function(key, transform2) {
22198 if (this.mouse && key !== "mouse")
22199 this.mouse[1] = transform2.invert(this.mouse[0]);
22200 if (this.touch0 && key !== "touch")
22201 this.touch0[1] = transform2.invert(this.touch0[0]);
22202 if (this.touch1 && key !== "touch")
22203 this.touch1[1] = transform2.invert(this.touch1[0]);
22204 this.that.__zoom = transform2;
22209 if (--this.active === 0) {
22210 delete this.that.__zooming;
22215 emit: function(type2) {
22216 var d = select_default2(this.that).datum();
22220 new ZoomEvent(type2, {
22221 sourceEvent: this.sourceEvent,
22224 transform: this.that.__zoom,
22225 dispatch: listeners
22231 function wheeled(event, ...args) {
22232 if (!filter2.apply(this, arguments))
22234 var g = gesture(this, args).event(event), t = this.__zoom, k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], t.k * Math.pow(2, wheelDelta.apply(this, arguments)))), p = pointer_default(event);
22236 if (g.mouse[0][0] !== p[0] || g.mouse[0][1] !== p[1]) {
22237 g.mouse[1] = t.invert(g.mouse[0] = p);
22239 clearTimeout(g.wheel);
22240 } else if (t.k === k)
22243 g.mouse = [p, t.invert(p)];
22244 interrupt_default(this);
22247 noevent_default2(event);
22248 g.wheel = setTimeout(wheelidled, wheelDelay);
22249 g.zoom("mouse", constrain(translate(scale(t, k), g.mouse[0], g.mouse[1]), g.extent, translateExtent));
22250 function wheelidled() {
22255 function mousedowned(event, ...args) {
22256 if (touchending || !filter2.apply(this, arguments))
22258 var currentTarget = event.currentTarget, g = gesture(this, args, true).event(event), v = select_default2(event.view).on("mousemove.zoom", mousemoved, true).on("mouseup.zoom", mouseupped, true), p = pointer_default(event, currentTarget), x05 = event.clientX, y05 = event.clientY;
22259 nodrag_default(event.view);
22260 nopropagation2(event);
22261 g.mouse = [p, this.__zoom.invert(p)];
22262 interrupt_default(this);
22264 function mousemoved(event2) {
22265 noevent_default2(event2);
22267 var dx = event2.clientX - x05, dy = event2.clientY - y05;
22268 g.moved = dx * dx + dy * dy > clickDistance2;
22270 g.event(event2).zoom("mouse", constrain(translate(g.that.__zoom, g.mouse[0] = pointer_default(event2, currentTarget), g.mouse[1]), g.extent, translateExtent));
22272 function mouseupped(event2) {
22273 v.on("mousemove.zoom mouseup.zoom", null);
22274 yesdrag(event2.view, g.moved);
22275 noevent_default2(event2);
22276 g.event(event2).end();
22279 function dblclicked(event, ...args) {
22280 if (!filter2.apply(this, arguments))
22282 var t0 = this.__zoom, p02 = pointer_default(event.changedTouches ? event.changedTouches[0] : event, this), p1 = t0.invert(p02), k1 = t0.k * (event.shiftKey ? 0.5 : 2), t1 = constrain(translate(scale(t0, k1), p02, p1), extent.apply(this, args), translateExtent);
22283 noevent_default2(event);
22285 select_default2(this).transition().duration(duration).call(schedule, t1, p02, event);
22287 select_default2(this).call(zoom.transform, t1, p02, event);
22289 function touchstarted(event, ...args) {
22290 if (!filter2.apply(this, arguments))
22292 var touches = event.touches, n2 = touches.length, g = gesture(this, args, event.changedTouches.length === n2).event(event), started, i2, t, p;
22293 nopropagation2(event);
22294 for (i2 = 0; i2 < n2; ++i2) {
22295 t = touches[i2], p = pointer_default(t, this);
22296 p = [p, this.__zoom.invert(p), t.identifier];
22298 g.touch0 = p, started = true, g.taps = 1 + !!touchstarting;
22299 else if (!g.touch1 && g.touch0[2] !== p[2])
22300 g.touch1 = p, g.taps = 0;
22303 touchstarting = clearTimeout(touchstarting);
22306 touchfirst = p[0], touchstarting = setTimeout(function() {
22307 touchstarting = null;
22309 interrupt_default(this);
22313 function touchmoved(event, ...args) {
22314 if (!this.__zooming)
22316 var g = gesture(this, args).event(event), touches = event.changedTouches, n2 = touches.length, i2, t, p, l;
22317 noevent_default2(event);
22318 for (i2 = 0; i2 < n2; ++i2) {
22319 t = touches[i2], p = pointer_default(t, this);
22320 if (g.touch0 && g.touch0[2] === t.identifier)
22322 else if (g.touch1 && g.touch1[2] === t.identifier)
22327 var p02 = g.touch0[0], l0 = g.touch0[1], p1 = g.touch1[0], l1 = g.touch1[1], dp = (dp = p1[0] - p02[0]) * dp + (dp = p1[1] - p02[1]) * dp, dl = (dl = l1[0] - l0[0]) * dl + (dl = l1[1] - l0[1]) * dl;
22328 t = scale(t, Math.sqrt(dp / dl));
22329 p = [(p02[0] + p1[0]) / 2, (p02[1] + p1[1]) / 2];
22330 l = [(l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2];
22331 } else if (g.touch0)
22332 p = g.touch0[0], l = g.touch0[1];
22335 g.zoom("touch", constrain(translate(t, p, l), g.extent, translateExtent));
22337 function touchended(event, ...args) {
22338 if (!this.__zooming)
22340 var g = gesture(this, args).event(event), touches = event.changedTouches, n2 = touches.length, i2, t;
22341 nopropagation2(event);
22343 clearTimeout(touchending);
22344 touchending = setTimeout(function() {
22345 touchending = null;
22347 for (i2 = 0; i2 < n2; ++i2) {
22349 if (g.touch0 && g.touch0[2] === t.identifier)
22351 else if (g.touch1 && g.touch1[2] === t.identifier)
22354 if (g.touch1 && !g.touch0)
22355 g.touch0 = g.touch1, delete g.touch1;
22357 g.touch0[1] = this.__zoom.invert(g.touch0[0]);
22360 if (g.taps === 2) {
22361 t = pointer_default(t, this);
22362 if (Math.hypot(touchfirst[0] - t[0], touchfirst[1] - t[1]) < tapDistance) {
22363 var p = select_default2(this).on("dblclick.zoom");
22365 p.apply(this, arguments);
22370 zoom.wheelDelta = function(_) {
22371 return arguments.length ? (wheelDelta = typeof _ === "function" ? _ : constant_default4(+_), zoom) : wheelDelta;
22373 zoom.filter = function(_) {
22374 return arguments.length ? (filter2 = typeof _ === "function" ? _ : constant_default4(!!_), zoom) : filter2;
22376 zoom.touchable = function(_) {
22377 return arguments.length ? (touchable = typeof _ === "function" ? _ : constant_default4(!!_), zoom) : touchable;
22379 zoom.extent = function(_) {
22380 return arguments.length ? (extent = typeof _ === "function" ? _ : constant_default4([[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]]), zoom) : extent;
22382 zoom.scaleExtent = function(_) {
22383 return arguments.length ? (scaleExtent[0] = +_[0], scaleExtent[1] = +_[1], zoom) : [scaleExtent[0], scaleExtent[1]];
22385 zoom.translateExtent = function(_) {
22386 return arguments.length ? (translateExtent[0][0] = +_[0][0], translateExtent[1][0] = +_[1][0], translateExtent[0][1] = +_[0][1], translateExtent[1][1] = +_[1][1], zoom) : [[translateExtent[0][0], translateExtent[0][1]], [translateExtent[1][0], translateExtent[1][1]]];
22388 zoom.constrain = function(_) {
22389 return arguments.length ? (constrain = _, zoom) : constrain;
22391 zoom.duration = function(_) {
22392 return arguments.length ? (duration = +_, zoom) : duration;
22394 zoom.interpolate = function(_) {
22395 return arguments.length ? (interpolate = _, zoom) : interpolate;
22397 zoom.on = function() {
22398 var value = listeners.on.apply(listeners, arguments);
22399 return value === listeners ? zoom : value;
22401 zoom.clickDistance = function(_) {
22402 return arguments.length ? (clickDistance2 = (_ = +_) * _, zoom) : Math.sqrt(clickDistance2);
22404 zoom.tapDistance = function(_) {
22405 return arguments.length ? (tapDistance = +_, zoom) : tapDistance;
22410 // modules/geo/raw_mercator.js
22411 function geoRawMercator() {
22412 var project = mercatorRaw;
22413 var k = 512 / Math.PI;
22416 var clipExtent = [[0, 0], [0, 0]];
22417 function projection2(point2) {
22418 point2 = project(point2[0] * Math.PI / 180, point2[1] * Math.PI / 180);
22419 return [point2[0] * k + x, y - point2[1] * k];
22421 projection2.invert = function(point2) {
22422 point2 = project.invert((point2[0] - x) / k, (y - point2[1]) / k);
22423 return point2 && [point2[0] * 180 / Math.PI, point2[1] * 180 / Math.PI];
22425 projection2.scale = function(_) {
22426 if (!arguments.length)
22429 return projection2;
22431 projection2.translate = function(_) {
22432 if (!arguments.length)
22436 return projection2;
22438 projection2.clipExtent = function(_) {
22439 if (!arguments.length)
22442 return projection2;
22444 projection2.transform = function(obj) {
22445 if (!arguments.length)
22446 return identity2.translate(x, y).scale(k);
22450 return projection2;
22452 projection2.stream = transform_default({
22453 point: function(x2, y2) {
22454 var vec = projection2([x2, y2]);
22455 this.stream.point(vec[0], vec[1]);
22458 return projection2;
22461 // modules/geo/ortho.js
22462 function geoOrthoNormalizedDotProduct(a, b, origin) {
22463 if (geoVecEqual(origin, a) || geoVecEqual(origin, b)) {
22466 return geoVecNormalizedDot(a, b, origin);
22468 function geoOrthoFilterDotProduct(dotp, epsilon3, lowerThreshold, upperThreshold, allowStraightAngles) {
22469 var val = Math.abs(dotp);
22470 if (val < epsilon3) {
22472 } else if (allowStraightAngles && Math.abs(val - 1) < epsilon3) {
22474 } else if (val < lowerThreshold || val > upperThreshold) {
22480 function geoOrthoCalcScore(points, isClosed, epsilon3, threshold) {
22482 var first = isClosed ? 0 : 1;
22483 var last = isClosed ? points.length : points.length - 1;
22484 var coords = points.map(function(p) {
22487 var lowerThreshold = Math.cos((90 - threshold) * Math.PI / 180);
22488 var upperThreshold = Math.cos(threshold * Math.PI / 180);
22489 for (var i2 = first; i2 < last; i2++) {
22490 var a = coords[(i2 - 1 + coords.length) % coords.length];
22491 var origin = coords[i2];
22492 var b = coords[(i2 + 1) % coords.length];
22493 var dotp = geoOrthoFilterDotProduct(geoOrthoNormalizedDotProduct(a, b, origin), epsilon3, lowerThreshold, upperThreshold);
22496 score = score + 2 * Math.min(Math.abs(dotp - 1), Math.min(Math.abs(dotp), Math.abs(dotp + 1)));
22500 function geoOrthoMaxOffsetAngle(coords, isClosed, lessThan) {
22501 var max3 = -Infinity;
22502 var first = isClosed ? 0 : 1;
22503 var last = isClosed ? coords.length : coords.length - 1;
22504 for (var i2 = first; i2 < last; i2++) {
22505 var a = coords[(i2 - 1 + coords.length) % coords.length];
22506 var origin = coords[i2];
22507 var b = coords[(i2 + 1) % coords.length];
22508 var normalizedDotP = geoOrthoNormalizedDotProduct(a, b, origin);
22509 var angle2 = Math.acos(Math.abs(normalizedDotP)) * 180 / Math.PI;
22511 angle2 = 90 - angle2;
22512 if (angle2 >= lessThan)
22517 if (max3 === -Infinity)
22521 function geoOrthoCanOrthogonalize(coords, isClosed, epsilon3, threshold, allowStraightAngles) {
22523 var first = isClosed ? 0 : 1;
22524 var last = isClosed ? coords.length : coords.length - 1;
22525 var lowerThreshold = Math.cos((90 - threshold) * Math.PI / 180);
22526 var upperThreshold = Math.cos(threshold * Math.PI / 180);
22527 for (var i2 = first; i2 < last; i2++) {
22528 var a = coords[(i2 - 1 + coords.length) % coords.length];
22529 var origin = coords[i2];
22530 var b = coords[(i2 + 1) % coords.length];
22531 var dotp = geoOrthoFilterDotProduct(geoOrthoNormalizedDotProduct(a, b, origin), epsilon3, lowerThreshold, upperThreshold, allowStraightAngles);
22534 if (Math.abs(dotp) > 0)
22541 // modules/util/array.js
22542 function utilArrayIdentical(a, b) {
22546 if (i2 !== b.length)
22549 if (a[i2] !== b[i2])
22554 function utilArrayDifference(a, b) {
22555 var other = new Set(b);
22556 return Array.from(new Set(a)).filter(function(v) {
22557 return !other.has(v);
22560 function utilArrayIntersection(a, b) {
22561 var other = new Set(b);
22562 return Array.from(new Set(a)).filter(function(v) {
22563 return other.has(v);
22566 function utilArrayUnion(a, b) {
22567 var result = new Set(a);
22568 b.forEach(function(v) {
22571 return Array.from(result);
22573 function utilArrayUniq(a) {
22574 return Array.from(new Set(a));
22576 function utilArrayChunk(a, chunkSize) {
22577 if (!chunkSize || chunkSize < 0)
22578 return [a.slice()];
22579 var result = new Array(Math.ceil(a.length / chunkSize));
22580 return Array.from(result, function(item, i2) {
22581 return a.slice(i2 * chunkSize, i2 * chunkSize + chunkSize);
22584 function utilArrayFlatten(a) {
22585 return a.reduce(function(acc, val) {
22586 return acc.concat(val);
22589 function utilArrayGroupBy(a, key) {
22590 return a.reduce(function(acc, item) {
22591 var group = typeof key === "function" ? key(item) : item[key];
22592 (acc[group] = acc[group] || []).push(item);
22596 function utilArrayUniqBy(a, key) {
22597 var seen = /* @__PURE__ */ new Set();
22598 return a.reduce(function(acc, item) {
22599 var val = typeof key === "function" ? key(item) : item[key];
22600 if (val && !seen.has(val)) {
22608 // modules/util/util.js
22609 var import_diacritics = __toESM(require_diacritics());
22611 // modules/util/svg_paths_rtl_fix.js
22612 var import_alif_toolkit = __toESM(require_lib());
22613 var rtlRegex = /[\u0590-\u05FF\u0600-\u06FF\u0750-\u07BF\u08A0–\u08BF]/;
22614 function fixRTLTextForSvg(inputText) {
22615 var ret = "", rtlBuffer = [];
22616 var arabicRegex = /[\u0600-\u06FF]/g;
22617 var arabicDiacritics = /[\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06ED]/g;
22618 var arabicMath = /[\u0660-\u066C\u06F0-\u06F9]+/g;
22619 var thaanaVowel = /[\u07A6-\u07B0]/;
22620 var hebrewSign = /[\u0591-\u05bd\u05bf\u05c1-\u05c5\u05c7]/;
22621 if (arabicRegex.test(inputText)) {
22622 inputText = (0, import_alif_toolkit.WordShaper)(inputText);
22624 for (var n2 = 0; n2 < inputText.length; n2++) {
22625 var c = inputText[n2];
22626 if (arabicMath.test(c)) {
22627 ret += rtlBuffer.reverse().join("");
22630 if (rtlBuffer.length && arabicMath.test(rtlBuffer[rtlBuffer.length - 1])) {
22631 ret += rtlBuffer.reverse().join("");
22634 if ((thaanaVowel.test(c) || hebrewSign.test(c) || arabicDiacritics.test(c)) && rtlBuffer.length) {
22635 rtlBuffer[rtlBuffer.length - 1] += c;
22636 } else if (rtlRegex.test(c) || c.charCodeAt(0) >= 64336 && c.charCodeAt(0) <= 65023 || c.charCodeAt(0) >= 65136 && c.charCodeAt(0) <= 65279) {
22638 } else if (c === " " && rtlBuffer.length) {
22639 rtlBuffer = [rtlBuffer.reverse().join("") + " "];
22641 ret += rtlBuffer.reverse().join("") + c;
22646 ret += rtlBuffer.reverse().join("");
22650 // modules/core/preferences.js
22653 _storage = localStorage;
22656 _storage = _storage || (() => {
22659 getItem: (k) => s[k],
22660 setItem: (k, v) => s[k] = v,
22661 removeItem: (k) => delete s[k]
22664 var _listeners = {};
22665 function corePreferences(k, v) {
22668 return _storage.getItem(k);
22669 else if (v === null)
22670 _storage.removeItem(k);
22672 _storage.setItem(k, v);
22673 if (_listeners[k]) {
22674 _listeners[k].forEach((handler) => handler(v));
22678 if (typeof console !== "undefined") {
22679 console.error("localStorage quota exceeded");
22684 corePreferences.onChange = function(k, handler) {
22685 _listeners[k] = _listeners[k] || [];
22686 _listeners[k].push(handler);
22689 // modules/core/file_fetcher.js
22690 var import_vparse = __toESM(require_vparse());
22693 var presetsCdnUrl = "https://cdn.jsdelivr.net/npm/@openstreetmap/id-tagging-schema@{presets_version}/";
22694 var ociCdnUrl = "https://cdn.jsdelivr.net/npm/osm-community-index@{version}/";
22695 var wmfSitematrixCdnUrl = "https://cdn.jsdelivr.net/npm/wmf-sitematrix@{version}/";
22696 var nsiCdnUrl = "https://cdn.jsdelivr.net/npm/name-suggestion-index@{version}/";
22697 var defaultOsmApiConnections = {
22699 url: "https://www.openstreetmap.org",
22700 client_id: "0tmNTmd0Jo1dQp4AUmMBLtGiD9YpMuXzHefitcuVStc",
22701 client_secret: "BTlNrNxIPitHdL4sP2clHw5KLoee9aKkA7dQbc0Bj7Q"
22704 url: "https://api06.dev.openstreetmap.org",
22705 client_id: "Ee1wWJ6UlpERbF6BfTNOpwn0R8k_06mvMXdDUkeHMgw",
22706 client_secret: "OnfWFC-JkZNHyYdr_viNn_h_RTZXRslKcUxllOXqf5g"
22709 var osmApiConnections = [];
22711 osmApiConnections.push({
22714 client_secret: null
22716 } else if (false) {
22717 osmApiConnections.push(defaultOsmApiConnections[null]);
22719 osmApiConnections.push(defaultOsmApiConnections.live);
22720 osmApiConnections.push(defaultOsmApiConnections.dev);
22722 var taginfoApiUrl = "https://taginfo.openstreetmap.org/api/4/";
22723 var nominatimApiUrl = "https://nominatim.openstreetmap.org/";
22726 var package_default = {
22729 description: "A friendly editor for OpenStreetMap",
22730 main: "dist/iD.min.js",
22731 repository: "github:openstreetmap/iD",
22732 homepage: "https://github.com/openstreetmap/iD",
22733 bugs: "https://github.com/openstreetmap/iD/issues",
22740 all: "run-s clean build dist",
22741 build: "run-s build:css build:data build:js",
22742 "build:css": "node scripts/build_css.js",
22743 "build:data": "shx mkdir -p dist/data && node scripts/build_data.js",
22744 "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",
22745 "build:js": "node config/esbuild.config.mjs",
22746 "build:js:watch": "node config/esbuild.config.mjs --watch",
22747 clean: "shx rm -f dist/esbuild.json dist/*.js dist/*.map dist/*.css dist/img/*.svg",
22748 dist: "run-p dist:**",
22749 "dist:mapillary": "shx mkdir -p dist/mapillary-js && shx cp -R node_modules/mapillary-js/dist/* dist/mapillary-js/",
22750 "dist:pannellum": "shx mkdir -p dist/pannellum-streetside && shx cp -R node_modules/pannellum/build/* dist/pannellum-streetside/",
22751 "dist:min": "node config/esbuild.config.min.mjs",
22752 "dist:svg:iD": 'svg-sprite --symbol --symbol-dest . --shape-id-generator "iD-%s" --symbol-sprite dist/img/iD-sprite.svg "svg/iD-sprite/**/*.svg"',
22753 "dist:svg:community": 'svg-sprite --symbol --symbol-dest . --shape-id-generator "community-%s" --symbol-sprite dist/img/community-sprite.svg node_modules/osm-community-index/dist/img/*.svg',
22754 "dist:svg:fa": "svg-sprite --symbol --symbol-dest . --symbol-sprite dist/img/fa-sprite.svg svg/fontawesome/*.svg",
22755 "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',
22756 "dist:svg:mapillary:signs": "svg-sprite --symbol --symbol-dest . --symbol-sprite dist/img/mapillary-sprite.svg node_modules/mapillary_sprite_source/package_signs/*.svg",
22757 "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",
22758 "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',
22759 "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',
22760 imagery: "node scripts/update_imagery.js",
22761 lint: "eslint scripts test/spec modules",
22762 "lint:fix": "eslint scripts test/spec modules --fix",
22763 start: "run-s start:watch",
22764 "start:single-build": "run-p build:js start:server",
22765 "start:watch": "run-p build:js:watch start:server",
22766 "start:server": "node scripts/server.js",
22767 test: "npm-run-all -s lint build test:spec",
22768 "test:spec": "karma start config/karma.conf.js",
22769 translations: "node scripts/update_locales.js"
22772 "@ideditor/country-coder": "~5.1.0",
22773 "@ideditor/location-conflation": "~1.1.0",
22774 "@mapbox/geojson-area": "^0.2.2",
22775 "@mapbox/sexagesimal": "1.2.0",
22776 "@mapbox/vector-tile": "^1.3.1",
22777 "@tmcw/togeojson": "^5.2.1",
22778 "@turf/bbox": "^6.0.0",
22779 "@turf/bbox-clip": "^6.0.0",
22780 "abortcontroller-polyfill": "^1.4.0",
22781 "aes-js": "^3.1.2",
22782 "alif-toolkit": "^1.2.9",
22783 "core-js-bundle": "^3.19.0",
22784 diacritics: "1.3.0",
22785 "fast-deep-equal": "~3.1.1",
22786 "fast-json-stable-stringify": "2.1.0",
22787 "lodash-es": "~4.17.15",
22789 "node-diff3": "~3.1.0",
22790 "osm-auth": "~2.0.0",
22791 pannellum: "2.5.6",
22793 "polygon-clipping": "~0.15.1",
22795 "whatwg-fetch": "^3.4.1",
22796 "which-polygon": "2.2.0"
22799 "@fortawesome/fontawesome-svg-core": "~6.2.0",
22800 "@fortawesome/free-brands-svg-icons": "~6.2.0",
22801 "@fortawesome/free-regular-svg-icons": "~6.2.0",
22802 "@fortawesome/free-solid-svg-icons": "~6.2.0",
22803 "@ideditor/temaki": "~5.2.0",
22804 "@mapbox/maki": "^8.0.0",
22805 "@openstreetmap/id-tagging-schema": "^6.0.0",
22806 "@transifex/api": "^5.0.1",
22807 autoprefixer: "^10.0.1",
22810 "cldr-core": "^41.0.0",
22811 "cldr-localenames-full": "^41.0.0",
22812 "concat-files": "^0.1.1",
22815 "editor-layer-index": "github:osmlab/editor-layer-index#gh-pages",
22816 esbuild: "^0.17.10",
22817 "esbuild-visualizer": "^0.4.0",
22819 "fetch-mock": "^9.11.0",
22823 "js-yaml": "^4.0.0",
22824 "json-stringify-pretty-compact": "^3.0.0",
22826 "karma-chrome-launcher": "^3.1.0",
22827 "karma-coverage": "2.1.1",
22828 "karma-mocha": "^2.0.1",
22829 "karma-remap-istanbul": "^0.6.0",
22830 mapillary_sprite_source: "^1.8.0",
22831 "mapillary-js": "4.1.1",
22832 minimist: "^1.2.3",
22834 "name-suggestion-index": "~6.0",
22835 "node-fetch": "^2.6.1",
22836 "npm-run-all": "^4.0.0",
22837 "osm-community-index": "~5.5.0",
22839 "postcss-selector-prepend": "^0.5.0",
22843 "sinon-chai": "^3.7.0",
22845 "static-server": "^2.2.1",
22846 "svg-sprite": "2.0.2",
22853 "> 0.2%, last 6 major versions, Firefox ESR, maintained node versions"
22857 // modules/core/file_fetcher.js
22858 var _mainFileFetcher = coreFileFetcher();
22859 function coreFileFetcher() {
22860 const ociVersion = package_default.dependencies["osm-community-index"] || package_default.devDependencies["osm-community-index"];
22861 const v = (0, import_vparse.default)(ociVersion);
22862 const ociVersionMinor = `${v.major}.${v.minor}`;
22863 const presetsVersion = package_default.devDependencies["@openstreetmap/id-tagging-schema"];
22865 let _inflight4 = {};
22867 "address_formats": "data/address_formats.min.json",
22868 "imagery": "data/imagery.min.json",
22869 "intro_graph": "data/intro_graph.min.json",
22870 "keepRight": "data/keepRight.min.json",
22871 "languages": "data/languages.min.json",
22872 "locales": "locales/index.min.json",
22873 "phone_formats": "data/phone_formats.min.json",
22874 "qa_data": "data/qa_data.min.json",
22875 "shortcuts": "data/shortcuts.min.json",
22876 "territory_languages": "data/territory_languages.min.json",
22877 "oci_defaults": ociCdnUrl.replace("{version}", ociVersionMinor) + "dist/defaults.min.json",
22878 "oci_features": ociCdnUrl.replace("{version}", ociVersionMinor) + "dist/featureCollection.min.json",
22879 "oci_resources": ociCdnUrl.replace("{version}", ociVersionMinor) + "dist/resources.min.json",
22880 "presets_package": presetsCdnUrl.replace("{presets_version}", presetsVersion) + "package.json",
22881 "deprecated": presetsCdnUrl + "dist/deprecated.min.json",
22882 "discarded": presetsCdnUrl + "dist/discarded.min.json",
22883 "preset_categories": presetsCdnUrl + "dist/preset_categories.min.json",
22884 "preset_defaults": presetsCdnUrl + "dist/preset_defaults.min.json",
22885 "preset_fields": presetsCdnUrl + "dist/fields.min.json",
22886 "preset_presets": presetsCdnUrl + "dist/presets.min.json",
22887 "wmf_sitematrix": wmfSitematrixCdnUrl.replace("{version}", "0.1") + "wikipedia.min.json"
22889 let _cachedData = {};
22890 _this.cache = () => _cachedData;
22891 _this.get = (which) => {
22892 if (_cachedData[which]) {
22893 return Promise.resolve(_cachedData[which]);
22895 const file = _fileMap[which];
22896 const url = file && _this.asset(file);
22898 return Promise.reject(`Unknown data file for "${which}"`);
22900 if (url.includes("{presets_version}")) {
22901 return _this.get("presets_package").then((result) => {
22902 const presetsVersion2 = result.version;
22903 return getUrl(url.replace("{presets_version}", presetsVersion2), which);
22906 return getUrl(url);
22909 function getUrl(url, which) {
22910 let prom = _inflight4[url];
22912 _inflight4[url] = prom = fetch(url).then((response) => {
22913 if (!response.ok || !response.json) {
22914 throw new Error(response.status + " " + response.statusText);
22916 if (response.status === 204 || response.status === 205)
22918 return response.json();
22919 }).then((result) => {
22920 delete _inflight4[url];
22922 throw new Error(`No data loaded for "${which}"`);
22924 _cachedData[which] = result;
22926 }).catch((err) => {
22927 delete _inflight4[url];
22933 _this.fileMap = function(val) {
22934 if (!arguments.length)
22939 let _assetPath = "";
22940 _this.assetPath = function(val) {
22941 if (!arguments.length)
22946 let _assetMap = {};
22947 _this.assetMap = function(val) {
22948 if (!arguments.length)
22953 _this.asset = (val) => {
22954 if (/^http(s)?:\/\//i.test(val))
22956 const filename = _assetPath + val;
22957 return _assetMap[filename] || filename;
22962 // node_modules/@ideditor/country-coder/dist/country-coder.mjs
22963 var import_which_polygon = __toESM(require_which_polygon(), 1);
22964 var borders_default = { type: "FeatureCollection", features: [
22965 { 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]]]] } },
22966 { 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]]]] } },
22967 { 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]]]] } },
22968 { type: "Feature", properties: { wikidata: "Q26", nameEn: "Northern Ireland", aliases: ["GB-NIR"], country: "GB", groups: ["Q22890", "Q3336843", "154", "150", "UN"], driveSide: "left", roadSpeedUnit: "mph", roadHeightUnit: "ft", callingCodes: ["44"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-6.34755, 55.49206], [-7.2471, 55.06933], [-7.34464, 55.04688], [-7.4033, 55.00391], [-7.40004, 54.94498], [-7.44404, 54.9403], [-7.4473, 54.87003], [-7.47626, 54.83084], [-7.54508, 54.79401], [-7.54671, 54.74606], [-7.64449, 54.75265], [-7.75041, 54.7103], [-7.83352, 54.73854], [-7.93293, 54.66603], [-7.70315, 54.62077], [-7.8596, 54.53671], [-7.99812, 54.54427], [-8.04538, 54.48941], [-8.179, 54.46763], [-8.04555, 54.36292], [-7.87101, 54.29299], [-7.8596, 54.21779], [-7.81397, 54.20159], [-7.69501, 54.20731], [-7.55812, 54.12239], [-7.4799, 54.12239], [-7.44567, 54.1539], [-7.32834, 54.11475], [-7.30553, 54.11869], [-7.34005, 54.14698], [-7.29157, 54.17191], [-7.28017, 54.16714], [-7.29687, 54.1354], [-7.29493, 54.12013], [-7.26316, 54.13863], [-7.25012, 54.20063], [-7.14908, 54.22732], [-7.19145, 54.31296], [-7.02034, 54.4212], [-6.87775, 54.34682], [-6.85179, 54.29176], [-6.81583, 54.22791], [-6.74575, 54.18788], [-6.70175, 54.20218], [-6.6382, 54.17071], [-6.66264, 54.0666], [-6.62842, 54.03503], [-6.47849, 54.06947], [-6.36605, 54.07234], [-6.36279, 54.11248], [-6.32694, 54.09337], [-6.29003, 54.11278], [-6.26218, 54.09785], [-5.83481, 53.87749], [-4.69044, 54.3629], [-6.34755, 55.49206]]]] } },
22969 { type: "Feature", properties: { wikidata: "Q35", nameEn: "Denmark", country: "DK", groups: ["EU", "154", "150", "UN"], callingCodes: ["45"] }, geometry: { type: "MultiPolygon", coordinates: [[[[12.16597, 56.60205], [10.40861, 58.38489], [7.28637, 57.35913], [8.02459, 55.09613], [8.45719, 55.06747], [8.55769, 54.91837], [8.63979, 54.91069], [8.76387, 54.8948], [8.81178, 54.90518], [8.92795, 54.90452], [9.04629, 54.87249], [9.14275, 54.87421], [9.20571, 54.85841], [9.24631, 54.84726], [9.23445, 54.83432], [9.2474, 54.8112], [9.32771, 54.80602], [9.33849, 54.80233], [9.36496, 54.81749], [9.38532, 54.83968], [9.41213, 54.84254], [9.43155, 54.82586], [9.4659, 54.83131], [9.58937, 54.88785], [9.62734, 54.88057], [9.61187, 54.85548], [9.73563, 54.8247], [9.89314, 54.84171], [10.16755, 54.73883], [10.31111, 54.65968], [11.00303, 54.63689], [11.90309, 54.38543], [12.85844, 54.82438], [13.93395, 54.84044], [15.36991, 54.73263], [15.79951, 55.54655], [14.89259, 55.5623], [14.28399, 55.1553], [12.84405, 55.13257], [12.60345, 55.42675], [12.88472, 55.63369], [12.6372, 55.91371], [12.65312, 56.04345], [12.07466, 56.29488], [12.16597, 56.60205]]]] } },
22970 { type: "Feature", properties: { wikidata: "Q55", nameEn: "Netherlands", country: "NL", groups: ["EU", "155", "150", "UN"], callingCodes: ["31"] }, geometry: { type: "MultiPolygon", coordinates: [[[[5.45168, 54.20039], [2.56575, 51.85301], [3.36263, 51.37112], [3.38696, 51.33436], [3.35847, 51.31572], [3.38289, 51.27331], [3.41704, 51.25933], [3.43488, 51.24135], [3.52698, 51.2458], [3.51502, 51.28697], [3.58939, 51.30064], [3.78999, 51.25766], [3.78783, 51.2151], [3.90125, 51.20371], [3.97889, 51.22537], [4.01957, 51.24504], [4.05165, 51.24171], [4.16721, 51.29348], [4.24024, 51.35371], [4.21923, 51.37443], [4.33265, 51.37687], [4.34086, 51.35738], [4.39292, 51.35547], [4.43777, 51.36989], [4.38064, 51.41965], [4.39747, 51.43316], [4.38122, 51.44905], [4.47736, 51.4778], [4.5388, 51.48184], [4.54675, 51.47265], [4.52846, 51.45002], [4.53521, 51.4243], [4.57489, 51.4324], [4.65442, 51.42352], [4.72935, 51.48424], [4.74578, 51.48937], [4.77321, 51.50529], [4.78803, 51.50284], [4.84139, 51.4799], [4.82409, 51.44736], [4.82946, 51.4213], [4.78314, 51.43319], [4.76577, 51.43046], [4.77229, 51.41337], [4.78941, 51.41102], [4.84988, 51.41502], [4.90016, 51.41404], [4.92152, 51.39487], [5.00393, 51.44406], [5.0106, 51.47167], [5.03281, 51.48679], [5.04774, 51.47022], [5.07891, 51.4715], [5.10456, 51.43163], [5.07102, 51.39469], [5.13105, 51.34791], [5.13377, 51.31592], [5.16222, 51.31035], [5.2002, 51.32243], [5.24244, 51.30495], [5.22542, 51.26888], [5.23814, 51.26064], [5.26461, 51.26693], [5.29716, 51.26104], [5.33886, 51.26314], [5.347, 51.27502], [5.41672, 51.26248], [5.4407, 51.28169], [5.46519, 51.2849], [5.48476, 51.30053], [5.515, 51.29462], [5.5569, 51.26544], [5.5603, 51.22249], [5.65145, 51.19788], [5.65528, 51.18736], [5.70344, 51.1829], [5.74617, 51.18928], [5.77735, 51.17845], [5.77697, 51.1522], [5.82564, 51.16753], [5.85508, 51.14445], [5.80798, 51.11661], [5.8109, 51.10861], [5.83226, 51.10585], [5.82921, 51.09328], [5.79903, 51.09371], [5.79835, 51.05834], [5.77258, 51.06196], [5.75961, 51.03113], [5.77688, 51.02483], [5.76242, 50.99703], [5.71864, 50.96092], [5.72875, 50.95428], [5.74752, 50.96202], [5.75927, 50.95601], [5.74644, 50.94723], [5.72545, 50.92312], [5.72644, 50.91167], [5.71626, 50.90796], [5.69858, 50.91046], [5.67886, 50.88142], [5.64504, 50.87107], [5.64009, 50.84742], [5.65259, 50.82309], [5.70118, 50.80764], [5.68995, 50.79641], [5.70107, 50.7827], [5.68091, 50.75804], [5.69469, 50.75529], [5.72216, 50.76398], [5.73904, 50.75674], [5.74356, 50.7691], [5.76533, 50.78159], [5.77513, 50.78308], [5.80673, 50.7558], [5.84548, 50.76542], [5.84888, 50.75448], [5.88734, 50.77092], [5.89129, 50.75125], [5.89132, 50.75124], [5.95942, 50.7622], [5.97545, 50.75441], [6.01976, 50.75398], [6.02624, 50.77453], [5.97497, 50.79992], [5.98404, 50.80988], [6.00462, 50.80065], [6.02328, 50.81694], [6.01921, 50.84435], [6.05623, 50.8572], [6.05702, 50.85179], [6.07431, 50.84674], [6.07693, 50.86025], [6.08805, 50.87223], [6.07486, 50.89307], [6.09297, 50.92066], [6.01615, 50.93367], [6.02697, 50.98303], [5.95282, 50.98728], [5.90296, 50.97356], [5.90493, 51.00198], [5.87849, 51.01969], [5.86735, 51.05182], [5.9134, 51.06736], [5.9541, 51.03496], [5.98292, 51.07469], [6.16706, 51.15677], [6.17384, 51.19589], [6.07889, 51.17038], [6.07889, 51.24432], [6.16977, 51.33169], [6.22674, 51.36135], [6.22641, 51.39948], [6.20654, 51.40049], [6.21724, 51.48568], [6.18017, 51.54096], [6.09055, 51.60564], [6.11759, 51.65609], [6.02767, 51.6742], [6.04091, 51.71821], [5.95003, 51.7493], [5.98665, 51.76944], [5.94568, 51.82786], [5.99848, 51.83195], [6.06705, 51.86136], [6.10337, 51.84829], [6.16902, 51.84094], [6.11551, 51.89769], [6.15349, 51.90439], [6.21443, 51.86801], [6.29872, 51.86801], [6.30593, 51.84998], [6.40704, 51.82771], [6.38815, 51.87257], [6.47179, 51.85395], [6.50231, 51.86313], [6.58556, 51.89386], [6.68386, 51.91861], [6.72319, 51.89518], [6.82357, 51.96711], [6.83035, 51.9905], [6.68128, 52.05052], [6.76117, 52.11895], [6.83984, 52.11728], [6.97189, 52.20329], [6.9897, 52.2271], [7.03729, 52.22695], [7.06365, 52.23789], [7.02703, 52.27941], [7.07044, 52.37805], [7.03417, 52.40237], [6.99041, 52.47235], [6.94293, 52.43597], [6.69507, 52.488], [6.71641, 52.62905], [6.77307, 52.65375], [7.04557, 52.63318], [7.07253, 52.81083], [7.21694, 53.00742], [7.17898, 53.13817], [7.22681, 53.18165], [7.21679, 53.20058], [7.19052, 53.31866], [7.00198, 53.32672], [6.91025, 53.44221], [5.45168, 54.20039]], [[4.93295, 51.44945], [4.95244, 51.45207], [4.9524, 51.45014], [4.93909, 51.44632], [4.93295, 51.44945]], [[4.91493, 51.4353], [4.91935, 51.43634], [4.92227, 51.44252], [4.91811, 51.44621], [4.92287, 51.44741], [4.92811, 51.4437], [4.92566, 51.44273], [4.92815, 51.43856], [4.92879, 51.44161], [4.93544, 51.44634], [4.94025, 51.44193], [4.93416, 51.44185], [4.93471, 51.43861], [4.94265, 51.44003], [4.93986, 51.43064], [4.92952, 51.42984], [4.92652, 51.43329], [4.91493, 51.4353]]]] } },
22971 { type: "Feature", properties: { wikidata: "Q782", nameEn: "Hawaii", aliases: ["US-HI"], country: "US", groups: ["Q35657", "061", "009", "UN"], roadSpeedUnit: "mph", roadHeightUnit: "ft", callingCodes: ["1"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-177.8563, 29.18961], [-179.49839, 27.86265], [-151.6784, 9.55515], [-154.05867, 45.51124], [-177.5224, 27.7635], [-177.8563, 29.18961]]]] } },
22972 { type: "Feature", properties: { wikidata: "Q797", nameEn: "Alaska", aliases: ["US-AK"], country: "US", groups: ["Q35657", "021", "003", "019", "UN"], roadSpeedUnit: "mph", roadHeightUnit: "ft", callingCodes: ["1"] }, geometry: { type: "MultiPolygon", coordinates: [[[[169.34848, 52.47228], [180, 51.0171], [179.84401, 55.10087], [169.34848, 52.47228]]], [[[-168.95635, 65.98512], [-169.03888, 65.48473], [-172.76104, 63.77445], [-179.55295, 57.62081], [-179.55295, 50.81807], [-133.92876, 54.62289], [-130.61931, 54.70835], [-130.64499, 54.76912], [-130.44184, 54.85377], [-130.27203, 54.97174], [-130.18765, 55.07744], [-130.08035, 55.21556], [-129.97513, 55.28029], [-130.15373, 55.74895], [-130.00857, 55.91344], [-130.00093, 56.00325], [-130.10173, 56.12178], [-130.33965, 56.10849], [-130.77769, 56.36185], [-131.8271, 56.62247], [-133.38523, 58.42773], [-133.84645, 58.73543], [-134.27175, 58.8634], [-134.48059, 59.13231], [-134.55699, 59.1297], [-134.7047, 59.2458], [-135.00267, 59.28745], [-135.03069, 59.56208], [-135.48007, 59.79937], [-136.31566, 59.59083], [-136.22381, 59.55526], [-136.33727, 59.44466], [-136.47323, 59.46617], [-136.52365, 59.16752], [-136.82619, 59.16198], [-137.4925, 58.89415], [-137.60623, 59.24465], [-138.62145, 59.76431], [-138.71149, 59.90728], [-139.05365, 59.99655], [-139.20603, 60.08896], [-139.05831, 60.35205], [-139.68991, 60.33693], [-139.98024, 60.18027], [-140.45648, 60.30919], [-140.5227, 60.22077], [-141.00116, 60.30648], [-140.97446, 84.39275], [-168.25765, 71.99091], [-168.95635, 65.98512]]]] } },
22973 { type: "Feature", properties: { wikidata: "Q3492", nameEn: "Sumatra", aliases: ["ID-SM"], country: "ID", groups: ["035", "142", "UN"], driveSide: "left", callingCodes: ["62"] }, geometry: { type: "MultiPolygon", coordinates: [[[[109.82788, 2.86812], [110.90339, 7.52694], [105.01437, 3.24936], [104.56723, 1.44271], [104.34728, 1.33529], [104.12282, 1.27714], [104.03085, 1.26954], [103.74084, 1.12902], [103.66049, 1.18825], [103.56591, 1.19719], [103.03657, 1.30383], [96.11174, 6.69841], [74.28481, -3.17525], [102.92489, -8.17146], [106.32259, -5.50116], [106.38511, -5.16715], [109.17017, -4.07401], [109.3962, -2.07276], [108.50935, -2.01066], [107.94791, 1.06924], [109.82788, 2.86812]]]] } },
22974 { type: "Feature", properties: { wikidata: "Q3757", nameEn: "Java", aliases: ["ID-JW"], country: "ID", groups: ["035", "142", "UN"], driveSide: "left", callingCodes: ["62"] }, geometry: { type: "MultiPolygon", coordinates: [[[[109.17017, -4.07401], [106.38511, -5.16715], [106.32259, -5.50116], [102.92489, -8.17146], [116.22542, -10.49172], [114.39575, -8.2889], [114.42235, -8.09762], [114.92859, -7.49253], [116.33992, -7.56171], [116.58433, -5.30385], [109.17017, -4.07401]]]] } },
22975 { type: "Feature", properties: { wikidata: "Q3795", nameEn: "Kalimantan", aliases: ["ID-KA"], country: "ID", groups: ["Q36117", "035", "142", "UN"], driveSide: "left", callingCodes: ["62"] }, geometry: { type: "MultiPolygon", coordinates: [[[[120.02464, 2.83703], [118.06469, 4.16638], [117.67641, 4.16535], [117.47313, 4.18857], [117.25801, 4.35108], [115.90217, 4.37708], [115.58276, 3.93499], [115.53713, 3.14776], [115.11343, 2.82879], [115.1721, 2.49671], [114.80706, 2.21665], [114.80706, 1.92351], [114.57892, 1.5], [114.03788, 1.44787], [113.64677, 1.23933], [113.01448, 1.42832], [113.021, 1.57819], [112.48648, 1.56516], [112.2127, 1.44135], [112.15679, 1.17004], [111.94553, 1.12016], [111.82846, 0.99349], [111.55434, 0.97864], [111.22979, 1.08326], [110.62374, 0.873], [110.49182, 0.88088], [110.35354, 0.98869], [109.66397, 1.60425], [109.66397, 1.79972], [109.57923, 1.80624], [109.53794, 1.91771], [109.62558, 1.99182], [109.82788, 2.86812], [107.94791, 1.06924], [108.50935, -2.01066], [109.3962, -2.07276], [109.17017, -4.07401], [116.58433, -5.30385], [120.02464, 2.83703]]]] } },
22976 { type: "Feature", properties: { wikidata: "Q3803", nameEn: "Lesser Sunda Islands", aliases: ["ID-NU"], country: "ID", groups: ["035", "142", "UN"], driveSide: "left", callingCodes: ["62"] }, geometry: { type: "MultiPolygon", coordinates: [[[[116.96967, -8.01483], [114.92859, -7.49253], [114.42235, -8.09762], [114.39575, -8.2889], [116.22542, -10.49172], [122.14954, -11.52517], [125.68138, -9.85176], [125.09025, -9.46406], [124.97892, -9.19281], [125.04044, -9.17093], [125.09434, -9.19669], [125.18907, -9.16434], [125.18632, -9.03142], [125.11764, -8.96359], [124.97742, -9.08128], [124.94011, -8.85617], [124.46701, -9.13002], [124.45971, -9.30263], [124.38554, -9.3582], [124.35258, -9.43002], [124.3535, -9.48493], [124.28115, -9.50453], [124.28115, -9.42189], [124.21247, -9.36904], [124.14517, -9.42324], [124.10539, -9.41206], [124.04286, -9.34243], [124.04628, -9.22671], [124.33472, -9.11416], [124.92337, -8.75859], [125.87688, -7.49892], [116.96967, -8.01483]]]] } },
22977 { type: "Feature", properties: { wikidata: "Q3812", nameEn: "Sulawesi", aliases: ["ID-SL"], country: "ID", groups: ["035", "142", "UN"], driveSide: "left", callingCodes: ["62"] }, geometry: { type: "MultiPolygon", coordinates: [[[[128.34321, 3.90322], [126.69413, 6.02692], [119.56457, 0.90759], [116.58433, -5.30385], [116.33992, -7.56171], [116.96967, -8.01483], [125.87688, -7.49892], [123.78965, -0.86805], [128.34321, 3.90322]]]] } },
22978 { type: "Feature", properties: { wikidata: "Q3827", nameEn: "Maluku Islands", aliases: ["ID-ML"], country: "ID", groups: ["035", "142", "UN"], driveSide: "left", callingCodes: ["62"] }, geometry: { type: "MultiPolygon", coordinates: [[[[129.63187, 2.21409], [128.34321, 3.90322], [123.78965, -0.86805], [125.87688, -7.49892], [125.58506, -7.95311], [125.87691, -8.31789], [127.42116, -8.22471], [127.55165, -9.05052], [135.49042, -9.2276], [135.35517, -5.01442], [132.8312, -4.70282], [130.8468, -2.61103], [128.40647, -2.30349], [129.71519, -0.24692], [129.63187, 2.21409]]]] } },
22979 { type: "Feature", properties: { wikidata: "Q3845", nameEn: "Western New Guinea", aliases: ["ID-PP"], country: "ID", groups: ["035", "142", "UN"], driveSide: "left", callingCodes: ["62"] }, geometry: { type: "MultiPolygon", coordinates: [[[[135.49042, -9.2276], [141.01842, -9.35091], [141.01763, -6.90181], [140.90448, -6.85033], [140.85295, -6.72996], [140.99813, -6.3233], [141.02352, 0.08993], [129.63187, 2.21409], [129.71519, -0.24692], [128.40647, -2.30349], [130.8468, -2.61103], [132.8312, -4.70282], [135.35517, -5.01442], [135.49042, -9.2276]]]] } },
22980 { type: "Feature", properties: { wikidata: "Q5765", nameEn: "Balearic Islands", aliases: ["ES-IB"], country: "ES", groups: ["EU", "039", "150", "UN"], callingCodes: ["34 971"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-2.27707, 35.35051], [5.10072, 39.89531], [3.75438, 42.33445], [-2.27707, 35.35051]]]] } },
22981 { type: "Feature", properties: { wikidata: "Q5823", nameEn: "Ceuta", aliases: ["ES-CE"], country: "ES", groups: ["EA", "EU", "015", "002", "UN"], level: "subterritory", callingCodes: ["34"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-5.38491, 35.92591], [-5.37338, 35.88417], [-5.35844, 35.87375], [-5.34379, 35.8711], [-5.21179, 35.90091], [-5.38491, 35.92591]]]] } },
22982 { type: "Feature", properties: { wikidata: "Q5831", nameEn: "Melilla", aliases: ["ES-ML"], country: "ES", groups: ["EA", "EU", "015", "002", "UN"], level: "subterritory", callingCodes: ["34"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-2.91909, 35.33927], [-2.96038, 35.31609], [-2.96648, 35.30475], [-2.96978, 35.29459], [-2.97035, 35.28852], [-2.96507, 35.28801], [-2.96826, 35.28296], [-2.96516, 35.27967], [-2.95431, 35.2728], [-2.95065, 35.26576], [-2.93893, 35.26737], [-2.92272, 35.27509], [-2.91909, 35.33927]]]] } },
22983 { type: "Feature", properties: { wikidata: "Q7835", nameEn: "Crimea", country: "RU", groups: ["151", "150", "UN"], level: "subterritory", callingCodes: ["7"] }, geometry: { type: "MultiPolygon", coordinates: [[[[33.5, 44], [36.4883, 45.0488], [36.475, 45.2411], [36.5049, 45.3136], [36.6545, 45.3417], [36.6645, 45.4514], [35.0498, 45.7683], [34.9601, 45.7563], [34.7991, 45.8101], [34.8015, 45.9005], [34.7548, 45.907], [34.6668, 45.9714], [34.6086, 45.9935], [34.5589, 45.9935], [34.5201, 45.951], [34.4873, 45.9427], [34.4415, 45.9599], [34.4122, 46.0025], [34.3391, 46.0611], [34.2511, 46.0532], [34.181, 46.068], [34.1293, 46.1049], [34.0731, 46.1177], [34.0527, 46.1084], [33.9155, 46.1594], [33.8523, 46.1986], [33.7972, 46.2048], [33.7405, 46.1855], [33.646, 46.2303], [33.6152, 46.2261], [33.6385, 46.1415], [33.6147, 46.1356], [33.5732, 46.1032], [33.5909, 46.0601], [33.5597, 46.0307], [31.5, 45.5], [33.5, 44]]]] } },
22984 { type: "Feature", properties: { wikidata: "Q12837", nameEn: "Iberia", level: "sharedLandform" }, geometry: null },
22985 { type: "Feature", properties: { wikidata: "Q14056", nameEn: "Jan Mayen", aliases: ["NO-22"], country: "NO", groups: ["SJ", "154", "150", "UN"], level: "subterritory" }, geometry: { type: "MultiPolygon", coordinates: [[[[-9.18243, 72.23144], [-10.71459, 70.09565], [-5.93364, 70.76368], [-9.18243, 72.23144]]]] } },
22986 { type: "Feature", properties: { wikidata: "Q19188", nameEn: "Mainland China", country: "CN", groups: ["030", "142", "UN"], callingCodes: ["86"] }, geometry: { type: "MultiPolygon", coordinates: [[[[125.6131, 53.07229], [125.17522, 53.20225], [124.46078, 53.21881], [123.86158, 53.49391], [123.26989, 53.54843], [122.85966, 53.47395], [122.35063, 53.49565], [121.39213, 53.31888], [120.85633, 53.28499], [120.0451, 52.7359], [120.04049, 52.58773], [120.46454, 52.63811], [120.71673, 52.54099], [120.61346, 52.32447], [120.77337, 52.20805], [120.65907, 51.93544], [120.10963, 51.671], [119.13553, 50.37412], [119.38598, 50.35162], [119.27996, 50.13348], [119.11003, 50.00276], [118.61623, 49.93809], [117.82343, 49.52696], [117.48208, 49.62324], [117.27597, 49.62544], [116.71193, 49.83813], [116.03781, 48.87014], [116.06565, 48.81716], [115.78876, 48.51781], [115.811, 48.25699], [115.52082, 48.15367], [115.57128, 47.91988], [115.94296, 47.67741], [116.21879, 47.88505], [116.4465, 47.83662], [116.67405, 47.89039], [116.9723, 47.87285], [117.37875, 47.63627], [117.50181, 47.77216], [117.80196, 48.01661], [118.03676, 48.00982], [118.11009, 48.04], [118.22677, 48.03853], [118.29654, 48.00246], [118.55766, 47.99277], [118.7564, 47.76947], [119.12343, 47.66458], [119.13995, 47.53997], [119.35892, 47.48104], [119.31964, 47.42617], [119.54918, 47.29505], [119.56019, 47.24874], [119.62403, 47.24575], [119.71209, 47.19192], [119.85518, 46.92196], [119.91242, 46.90091], [119.89261, 46.66423], [119.80455, 46.67631], [119.77373, 46.62947], [119.68127, 46.59015], [119.65265, 46.62342], [119.42827, 46.63783], [119.32827, 46.61433], [119.24978, 46.64761], [119.10448, 46.65516], [119.00541, 46.74273], [118.92616, 46.72765], [118.89974, 46.77139], [118.8337, 46.77742], [118.78747, 46.68689], [118.30534, 46.73519], [117.69554, 46.50991], [117.60748, 46.59771], [117.41782, 46.57862], [117.36609, 46.36335], [116.83166, 46.38637], [116.75551, 46.33083], [116.58612, 46.30211], [116.26678, 45.96479], [116.24012, 45.8778], [116.27366, 45.78637], [116.16989, 45.68603], [115.60329, 45.44717], [114.94546, 45.37377], [114.74612, 45.43585], [114.54801, 45.38337], [114.5166, 45.27189], [113.70918, 44.72891], [112.74662, 44.86297], [112.4164, 45.06858], [111.98695, 45.09074], [111.76275, 44.98032], [111.40498, 44.3461], [111.96289, 43.81596], [111.93776, 43.68709], [111.79758, 43.6637], [111.59087, 43.51207], [111.0149, 43.3289], [110.4327, 42.78293], [110.08401, 42.6411], [109.89402, 42.63111], [109.452, 42.44842], [109.00679, 42.45302], [108.84489, 42.40246], [107.57258, 42.40898], [107.49681, 42.46221], [107.29755, 42.41395], [107.24774, 42.36107], [106.76517, 42.28741], [105.0123, 41.63188], [104.51667, 41.66113], [104.52258, 41.8706], [103.92804, 41.78246], [102.72403, 42.14675], [102.07645, 42.22519], [101.80515, 42.50074], [100.84979, 42.67087], [100.33297, 42.68231], [99.50671, 42.56535], [97.1777, 42.7964], [96.37926, 42.72055], [96.35658, 42.90363], [95.89543, 43.2528], [95.52594, 43.99353], [95.32891, 44.02407], [95.39772, 44.2805], [95.01191, 44.25274], [94.71959, 44.35284], [94.10003, 44.71016], [93.51161, 44.95964], [91.64048, 45.07408], [90.89169, 45.19667], [90.65114, 45.49314], [90.70907, 45.73437], [91.03026, 46.04194], [90.99672, 46.14207], [90.89639, 46.30711], [91.07696, 46.57315], [91.0147, 46.58171], [91.03649, 46.72916], [90.84035, 46.99525], [90.76108, 46.99399], [90.48542, 47.30438], [90.48854, 47.41826], [90.33598, 47.68303], [90.10871, 47.7375], [90.06512, 47.88177], [89.76624, 47.82745], [89.55453, 48.0423], [89.0711, 47.98528], [88.93186, 48.10263], [88.8011, 48.11302], [88.58316, 48.21893], [88.58939, 48.34531], [87.96361, 48.58478], [88.0788, 48.71436], [87.73822, 48.89582], [87.88171, 48.95853], [87.81333, 49.17354], [87.48983, 49.13794], [87.478, 49.07403], [87.28386, 49.11626], [86.87238, 49.12432], [86.73568, 48.99918], [86.75343, 48.70331], [86.38069, 48.46064], [85.73581, 48.3939], [85.5169, 48.05493], [85.61067, 47.49753], [85.69696, 47.2898], [85.54294, 47.06171], [85.22443, 47.04816], [84.93995, 46.87399], [84.73077, 47.01394], [83.92184, 46.98912], [83.04622, 47.19053], [82.21792, 45.56619], [82.58474, 45.40027], [82.51374, 45.1755], [81.73278, 45.3504], [80.11169, 45.03352], [79.8987, 44.89957], [80.38384, 44.63073], [80.40229, 44.23319], [80.40031, 44.10986], [80.75156, 43.44948], [80.69718, 43.32589], [80.77771, 43.30065], [80.78817, 43.14235], [80.62913, 43.141], [80.3735, 43.01557], [80.58999, 42.9011], [80.38169, 42.83142], [80.26886, 42.8366], [80.16892, 42.61137], [80.26841, 42.23797], [80.17807, 42.21166], [80.17842, 42.03211], [79.92977, 42.04113], [78.3732, 41.39603], [78.15757, 41.38565], [78.12873, 41.23091], [77.81287, 41.14307], [77.76206, 41.01574], [77.52723, 41.00227], [77.3693, 41.0375], [77.28004, 41.0033], [76.99302, 41.0696], [76.75681, 40.95354], [76.5261, 40.46114], [76.33659, 40.3482], [75.96168, 40.38064], [75.91361, 40.2948], [75.69663, 40.28642], [75.5854, 40.66874], [75.22834, 40.45382], [75.08243, 40.43945], [74.82013, 40.52197], [74.78168, 40.44886], [74.85996, 40.32857], [74.69875, 40.34668], [74.35063, 40.09742], [74.25533, 40.13191], [73.97049, 40.04378], [73.83006, 39.76136], [73.9051, 39.75073], [73.92354, 39.69565], [73.94683, 39.60733], [73.87018, 39.47879], [73.59831, 39.46425], [73.59241, 39.40843], [73.5004, 39.38402], [73.55396, 39.3543], [73.54572, 39.27567], [73.60638, 39.24534], [73.75823, 39.023], [73.81728, 39.04007], [73.82964, 38.91517], [73.7445, 38.93867], [73.7033, 38.84782], [73.80656, 38.66449], [73.79806, 38.61106], [73.97933, 38.52945], [74.17022, 38.65504], [74.51217, 38.47034], [74.69619, 38.42947], [74.69894, 38.22155], [74.80331, 38.19889], [74.82665, 38.07359], [74.9063, 38.03033], [74.92416, 37.83428], [75.00935, 37.77486], [74.8912, 37.67576], [74.94338, 37.55501], [75.06011, 37.52779], [75.15899, 37.41443], [75.09719, 37.37297], [75.12328, 37.31839], [74.88887, 37.23275], [74.80605, 37.21565], [74.49981, 37.24518], [74.56453, 37.03023], [75.13839, 37.02622], [75.40481, 36.95382], [75.45562, 36.71971], [75.72737, 36.7529], [75.92391, 36.56986], [76.0324, 36.41198], [76.00906, 36.17511], [75.93028, 36.13136], [76.15325, 35.9264], [76.14913, 35.82848], [76.33453, 35.84296], [76.50961, 35.8908], [76.77323, 35.66062], [76.84539, 35.67356], [76.96624, 35.5932], [77.44277, 35.46132], [77.70232, 35.46244], [77.80532, 35.52058], [78.11664, 35.48022], [78.03466, 35.3785], [78.00033, 35.23954], [78.22692, 34.88771], [78.18435, 34.7998], [78.27781, 34.61484], [78.54964, 34.57283], [78.56475, 34.50835], [78.74465, 34.45174], [79.05364, 34.32482], [78.99802, 34.3027], [78.91769, 34.15452], [78.66225, 34.08858], [78.65657, 34.03195], [78.73367, 34.01121], [78.77349, 33.73871], [78.67599, 33.66445], [78.73636, 33.56521], [79.15252, 33.17156], [79.14016, 33.02545], [79.46562, 32.69668], [79.26768, 32.53277], [79.13174, 32.47766], [79.0979, 32.38051], [78.99322, 32.37948], [78.96713, 32.33655], [78.7831, 32.46873], [78.73916, 32.69438], [78.38897, 32.53938], [78.4645, 32.45367], [78.49609, 32.2762], [78.68754, 32.10256], [78.74404, 32.00384], [78.78036, 31.99478], [78.69933, 31.78723], [78.84516, 31.60631], [78.71032, 31.50197], [78.77898, 31.31209], [78.89344, 31.30481], [79.01931, 31.42817], [79.14016, 31.43403], [79.30694, 31.17357], [79.59884, 30.93943], [79.93255, 30.88288], [80.20721, 30.58541], [80.54504, 30.44936], [80.83343, 30.32023], [81.03953, 30.20059], [81.12842, 30.01395], [81.24362, 30.0126], [81.29032, 30.08806], [81.2623, 30.14596], [81.33355, 30.15303], [81.39928, 30.21862], [81.41018, 30.42153], [81.5459, 30.37688], [81.62033, 30.44703], [81.99082, 30.33423], [82.10135, 30.35439], [82.10757, 30.23745], [82.19475, 30.16884], [82.16984, 30.0692], [82.38622, 30.02608], [82.5341, 29.9735], [82.73024, 29.81695], [83.07116, 29.61957], [83.28131, 29.56813], [83.44787, 29.30513], [83.63156, 29.16249], [83.82303, 29.30513], [83.97559, 29.33091], [84.18107, 29.23451], [84.24801, 29.02783], [84.2231, 28.89571], [84.47528, 28.74023], [84.62317, 28.73887], [84.85511, 28.58041], [85.06059, 28.68562], [85.19135, 28.62825], [85.18668, 28.54076], [85.10729, 28.34092], [85.38127, 28.28336], [85.4233, 28.32996], [85.59765, 28.30529], [85.60854, 28.25045], [85.69105, 28.38475], [85.71907, 28.38064], [85.74864, 28.23126], [85.84672, 28.18187], [85.90743, 28.05144], [85.97813, 27.99023], [85.94946, 27.9401], [86.06309, 27.90021], [86.12069, 27.93047], [86.08333, 28.02121], [86.088, 28.09264], [86.18607, 28.17364], [86.22966, 27.9786], [86.42736, 27.91122], [86.51609, 27.96623], [86.56265, 28.09569], [86.74181, 28.10638], [86.75582, 28.04182], [87.03757, 27.94835], [87.11696, 27.84104], [87.56996, 27.84517], [87.72718, 27.80938], [87.82681, 27.95248], [88.13378, 27.88015], [88.1278, 27.95417], [88.25332, 27.9478], [88.54858, 28.06057], [88.63235, 28.12356], [88.83559, 28.01936], [88.88091, 27.85192], [88.77517, 27.45415], [88.82981, 27.38814], [88.91901, 27.32483], [88.93678, 27.33777], [88.96947, 27.30319], [89.00216, 27.32532], [88.95355, 27.4106], [88.97213, 27.51671], [89.0582, 27.60985], [89.12825, 27.62502], [89.59525, 28.16433], [89.79762, 28.23979], [90.13387, 28.19178], [90.58842, 28.02838], [90.69894, 28.07784], [91.20019, 27.98715], [91.25779, 28.07509], [91.46327, 28.0064], [91.48973, 27.93903], [91.5629, 27.84823], [91.6469, 27.76358], [91.84722, 27.76325], [91.87057, 27.7195], [92.27432, 27.89077], [92.32101, 27.79363], [92.42538, 27.80092], [92.7275, 27.98662], [92.73025, 28.05814], [92.65472, 28.07632], [92.67486, 28.15018], [92.93075, 28.25671], [93.14635, 28.37035], [93.18069, 28.50319], [93.44621, 28.67189], [93.72797, 28.68821], [94.35897, 29.01965], [94.2752, 29.11687], [94.69318, 29.31739], [94.81353, 29.17804], [95.0978, 29.14446], [95.11291, 29.09527], [95.2214, 29.10727], [95.26122, 29.07727], [95.3038, 29.13847], [95.41091, 29.13007], [95.50842, 29.13487], [95.72086, 29.20797], [95.75149, 29.32063], [95.84899, 29.31464], [96.05361, 29.38167], [96.31316, 29.18643], [96.18682, 29.11087], [96.20467, 29.02325], [96.3626, 29.10607], [96.61391, 28.72742], [96.40929, 28.51526], [96.48895, 28.42955], [96.6455, 28.61657], [96.85561, 28.4875], [96.88445, 28.39452], [96.98882, 28.32564], [97.1289, 28.3619], [97.34547, 28.21385], [97.41729, 28.29783], [97.47085, 28.2688], [97.50518, 28.49716], [97.56835, 28.55628], [97.70705, 28.5056], [97.79632, 28.33168], [97.90069, 28.3776], [98.15337, 28.12114], [98.13964, 27.9478], [98.32641, 27.51385], [98.42529, 27.55404], [98.43353, 27.67086], [98.69582, 27.56499], [98.7333, 26.85615], [98.77547, 26.61994], [98.72741, 26.36183], [98.67797, 26.24487], [98.7329, 26.17218], [98.66884, 26.09165], [98.63128, 26.15492], [98.57085, 26.11547], [98.60763, 26.01512], [98.70818, 25.86241], [98.63128, 25.79937], [98.54064, 25.85129], [98.40606, 25.61129], [98.31268, 25.55307], [98.25774, 25.6051], [98.16848, 25.62739], [98.18084, 25.56298], [98.12591, 25.50722], [98.14925, 25.41547], [97.92541, 25.20815], [97.83614, 25.2715], [97.77023, 25.11492], [97.72216, 25.08508], [97.72903, 24.91332], [97.79949, 24.85655], [97.76481, 24.8289], [97.73127, 24.83015], [97.70181, 24.84557], [97.64354, 24.79171], [97.56648, 24.76475], [97.56383, 24.75535], [97.5542, 24.74943], [97.54675, 24.74202], [97.56525, 24.72838], [97.56286, 24.54535], [97.52757, 24.43748], [97.60029, 24.4401], [97.66998, 24.45288], [97.7098, 24.35658], [97.65624, 24.33781], [97.66723, 24.30027], [97.71941, 24.29652], [97.76799, 24.26365], [97.72998, 24.2302], [97.72799, 24.18883], [97.75305, 24.16902], [97.72903, 24.12606], [97.62363, 24.00506], [97.5247, 23.94032], [97.64667, 23.84574], [97.72302, 23.89288], [97.79456, 23.94836], [97.79416, 23.95663], [97.84328, 23.97603], [97.86545, 23.97723], [97.88811, 23.97446], [97.8955, 23.97758], [97.89676, 23.97931], [97.89683, 23.98389], [97.88814, 23.98605], [97.88414, 23.99405], [97.88616, 24.00463], [97.90998, 24.02094], [97.93951, 24.01953], [97.98691, 24.03897], [97.99583, 24.04932], [98.04709, 24.07616], [98.05302, 24.07408], [98.05671, 24.07961], [98.0607, 24.07812], [98.06703, 24.08028], [98.07806, 24.07988], [98.20666, 24.11406], [98.54476, 24.13119], [98.59256, 24.08371], [98.85319, 24.13042], [98.87998, 24.15624], [98.89632, 24.10612], [98.67797, 23.9644], [98.68209, 23.80492], [98.79607, 23.77947], [98.82933, 23.72921], [98.81775, 23.694], [98.88396, 23.59555], [98.80294, 23.5345], [98.82877, 23.47908], [98.87683, 23.48995], [98.92104, 23.36946], [98.87573, 23.33038], [98.93958, 23.31414], [98.92515, 23.29535], [98.88597, 23.18656], [99.05975, 23.16382], [99.04601, 23.12215], [99.25741, 23.09025], [99.34127, 23.13099], [99.52214, 23.08218], [99.54218, 22.90014], [99.43537, 22.94086], [99.45654, 22.85726], [99.31243, 22.73893], [99.38247, 22.57544], [99.37972, 22.50188], [99.28771, 22.4105], [99.17318, 22.18025], [99.19176, 22.16983], [99.1552, 22.15874], [99.33166, 22.09656], [99.47585, 22.13345], [99.85351, 22.04183], [99.96612, 22.05965], [99.99084, 21.97053], [99.94003, 21.82782], [99.98654, 21.71064], [100.04956, 21.66843], [100.12679, 21.70539], [100.17486, 21.65306], [100.10757, 21.59945], [100.12542, 21.50365], [100.1625, 21.48704], [100.18447, 21.51898], [100.25863, 21.47043], [100.35201, 21.53176], [100.42892, 21.54325], [100.4811, 21.46148], [100.57861, 21.45637], [100.72143, 21.51898], [100.87265, 21.67396], [101.11744, 21.77659], [101.15156, 21.56129], [101.2124, 21.56422], [101.19349, 21.41959], [101.26912, 21.36482], [101.2229, 21.23271], [101.29326, 21.17254], [101.54563, 21.25668], [101.6068, 21.23329], [101.59491, 21.18621], [101.60886, 21.17947], [101.66977, 21.20004], [101.70548, 21.14911], [101.7622, 21.14813], [101.79266, 21.19025], [101.76745, 21.21571], [101.83887, 21.20983], [101.84412, 21.25291], [101.74014, 21.30967], [101.74224, 21.48276], [101.7727, 21.51794], [101.7475, 21.5873], [101.80001, 21.57461], [101.83257, 21.61562], [101.74555, 21.72852], [101.7791, 21.83019], [101.62566, 21.96574], [101.57525, 22.13026], [101.60675, 22.13513], [101.53638, 22.24794], [101.56789, 22.28876], [101.61306, 22.27515], [101.68973, 22.46843], [101.7685, 22.50337], [101.86828, 22.38397], [101.90714, 22.38688], [101.91344, 22.44417], [101.98487, 22.42766], [102.03633, 22.46164], [102.1245, 22.43372], [102.14099, 22.40092], [102.16621, 22.43336], [102.26428, 22.41321], [102.25339, 22.4607], [102.41061, 22.64184], [102.38415, 22.67919], [102.42618, 22.69212], [102.46665, 22.77108], [102.51802, 22.77969], [102.57095, 22.7036], [102.60675, 22.73376], [102.8636, 22.60735], [102.9321, 22.48659], [103.0722, 22.44775], [103.07843, 22.50097], [103.17961, 22.55705], [103.15782, 22.59873], [103.18895, 22.64471], [103.28079, 22.68063], [103.32282, 22.8127], [103.43179, 22.75816], [103.43646, 22.70648], [103.52675, 22.59155], [103.57812, 22.65764], [103.56255, 22.69499], [103.64506, 22.79979], [103.87904, 22.56683], [103.93286, 22.52703], [103.94513, 22.52553], [103.95191, 22.5134], [103.96352, 22.50584], [103.96783, 22.51173], [103.97384, 22.50634], [103.99247, 22.51958], [104.01088, 22.51823], [104.03734, 22.72945], [104.11384, 22.80363], [104.27084, 22.8457], [104.25683, 22.76534], [104.35593, 22.69353], [104.47225, 22.75813], [104.58122, 22.85571], [104.60457, 22.81841], [104.65283, 22.83419], [104.72755, 22.81984], [104.77114, 22.90017], [104.84942, 22.93631], [104.86765, 22.95178], [104.8334, 23.01484], [104.79478, 23.12934], [104.87382, 23.12854], [104.87992, 23.17141], [104.91435, 23.18666], [104.9486, 23.17235], [104.96532, 23.20463], [104.98712, 23.19176], [105.07002, 23.26248], [105.11672, 23.25247], [105.17276, 23.28679], [105.22569, 23.27249], [105.32376, 23.39684], [105.40782, 23.28107], [105.42805, 23.30824], [105.49966, 23.20669], [105.56037, 23.16806], [105.57594, 23.075], [105.72382, 23.06641], [105.8726, 22.92756], [105.90119, 22.94168], [105.99568, 22.94178], [106.00179, 22.99049], [106.19705, 22.98475], [106.27022, 22.87722], [106.34961, 22.86718], [106.49749, 22.91164], [106.51306, 22.94891], [106.55976, 22.92311], [106.60179, 22.92884], [106.6516, 22.86862], [106.6734, 22.89587], [106.71387, 22.88296], [106.71128, 22.85982], [106.78422, 22.81532], [106.81271, 22.8226], [106.83685, 22.8098], [106.82404, 22.7881], [106.76293, 22.73491], [106.72321, 22.63606], [106.71698, 22.58432], [106.65316, 22.5757], [106.61269, 22.60301], [106.58395, 22.474], [106.55665, 22.46498], [106.57221, 22.37], [106.55976, 22.34841], [106.6516, 22.33977], [106.69986, 22.22309], [106.67495, 22.1885], [106.6983, 22.15102], [106.70142, 22.02409], [106.68274, 21.99811], [106.69276, 21.96013], [106.72551, 21.97923], [106.74345, 22.00965], [106.81038, 21.97934], [106.9178, 21.97357], [106.92714, 21.93459], [106.97228, 21.92592], [106.99252, 21.95191], [107.05634, 21.92303], [107.06101, 21.88982], [107.00964, 21.85948], [107.02615, 21.81981], [107.10771, 21.79879], [107.20734, 21.71493], [107.24625, 21.7077], [107.29296, 21.74674], [107.35834, 21.6672], [107.35989, 21.60063], [107.38636, 21.59774], [107.41593, 21.64839], [107.47197, 21.6672], [107.49532, 21.62958], [107.49065, 21.59774], [107.54047, 21.5934], [107.56537, 21.61945], [107.66967, 21.60787], [107.80355, 21.66141], [107.86114, 21.65128], [107.90006, 21.5905], [107.92652, 21.58906], [107.95232, 21.5388], [107.96774, 21.53601], [107.97074, 21.54072], [107.97383, 21.53961], [107.97932, 21.54503], [108.02926, 21.54997], [108.0569, 21.53604], [108.10003, 21.47338], [108.00365, 17.98159], [111.60491, 13.57105], [118.41371, 24.06775], [118.11703, 24.39734], [118.28244, 24.51231], [118.35291, 24.51645], [118.42453, 24.54644], [118.56434, 24.49266], [120.49232, 25.22863], [121.03532, 26.8787], [123.5458, 31.01942], [122.29378, 31.76513], [122.80525, 33.30571], [123.85601, 37.49093], [123.90497, 38.79949], [124.17532, 39.8232], [124.23201, 39.9248], [124.35029, 39.95639], [124.37089, 40.03004], [124.3322, 40.05573], [124.38556, 40.11047], [124.40719, 40.13655], [124.86913, 40.45387], [125.71172, 40.85223], [125.76869, 40.87908], [126.00335, 40.92835], [126.242, 41.15454], [126.53189, 41.35206], [126.60631, 41.65565], [126.90729, 41.79955], [127.17841, 41.59714], [127.29712, 41.49473], [127.92943, 41.44291], [128.02633, 41.42103], [128.03311, 41.39232], [128.12967, 41.37931], [128.18546, 41.41279], [128.20061, 41.40895], [128.30716, 41.60322], [128.15119, 41.74568], [128.04487, 42.01769], [128.94007, 42.03537], [128.96068, 42.06657], [129.15178, 42.17224], [129.22285, 42.26491], [129.22423, 42.3553], [129.28541, 42.41574], [129.42882, 42.44702], [129.54701, 42.37254], [129.60482, 42.44461], [129.72541, 42.43739], [129.75294, 42.59409], [129.77183, 42.69435], [129.7835, 42.76521], [129.80719, 42.79218], [129.83277, 42.86746], [129.85261, 42.96494], [129.8865, 43.00395], [129.95082, 43.01051], [129.96409, 42.97306], [130.12957, 42.98361], [130.09764, 42.91425], [130.26095, 42.9027], [130.23068, 42.80125], [130.2385, 42.71127], [130.41826, 42.6011], [130.44361, 42.54849], [130.50123, 42.61636], [130.55143, 42.52158], [130.62107, 42.58413], [130.56576, 42.68925], [130.40213, 42.70788], [130.44361, 42.76205], [130.66524, 42.84753], [131.02438, 42.86518], [131.02668, 42.91246], [131.135, 42.94114], [131.10274, 43.04734], [131.20414, 43.13654], [131.19031, 43.21385], [131.30324, 43.39498], [131.29402, 43.46695], [131.19492, 43.53047], [131.21105, 43.82383], [131.26176, 43.94011], [131.23583, 43.96085], [131.25484, 44.03131], [131.30365, 44.04262], [131.1108, 44.70266], [130.95639, 44.85154], [131.48415, 44.99513], [131.68466, 45.12374], [131.66852, 45.2196], [131.76532, 45.22609], [131.86903, 45.33636], [131.99417, 45.2567], [132.83978, 45.05916], [132.96373, 45.0212], [133.12293, 45.1332], [133.09279, 45.25693], [133.19419, 45.51913], [133.41083, 45.57723], [133.48457, 45.86203], [133.60442, 45.90053], [133.67569, 45.9759], [133.72695, 46.05576], [133.68047, 46.14697], [133.88097, 46.25066], [133.91496, 46.4274], [133.84104, 46.46681], [134.03538, 46.75668], [134.20016, 47.33458], [134.50898, 47.4812], [134.7671, 47.72051], [134.55508, 47.98651], [134.67098, 48.1564], [134.75328, 48.36763], [134.49516, 48.42884], [132.66989, 47.96491], [132.57309, 47.71741], [131.90448, 47.68011], [131.2635, 47.73325], [131.09871, 47.6852], [130.95985, 47.6957], [130.90915, 47.90623], [130.65103, 48.10052], [130.84462, 48.30942], [130.52147, 48.61745], [130.66946, 48.88251], [130.43232, 48.90844], [130.2355, 48.86741], [129.85416, 49.11067], [129.67598, 49.29596], [129.50685, 49.42398], [129.40398, 49.44194], [129.35317, 49.3481], [129.23232, 49.40353], [129.11153, 49.36813], [128.72896, 49.58676], [127.83476, 49.5748], [127.53516, 49.84306], [127.49299, 50.01251], [127.60515, 50.23503], [127.37384, 50.28393], [127.36009, 50.43787], [127.28765, 50.46585], [127.36335, 50.58306], [127.28165, 50.72075], [127.14586, 50.91152], [126.93135, 51.0841], [126.90369, 51.3238], [126.68349, 51.70607], [126.44606, 51.98254], [126.558, 52.13738], [125.6131, 53.07229]], [[113.56865, 22.20973], [113.57123, 22.20416], [113.60504, 22.20464], [113.63011, 22.10782], [113.57191, 22.07696], [113.54839, 22.10909], [113.54942, 22.14519], [113.54093, 22.15497], [113.52659, 22.18271], [113.53552, 22.20607], [113.53301, 22.21235], [113.53591, 22.21369], [113.54093, 22.21314], [113.54333, 22.21688], [113.5508, 22.21672], [113.56865, 22.20973]], [[114.50148, 22.15017], [113.92195, 22.13873], [113.83338, 22.1826], [113.81621, 22.2163], [113.86771, 22.42972], [114.03113, 22.5065], [114.05438, 22.5026], [114.05729, 22.51104], [114.06272, 22.51617], [114.07267, 22.51855], [114.07817, 22.52997], [114.08606, 22.53276], [114.09048, 22.53716], [114.09692, 22.53435], [114.1034, 22.5352], [114.11181, 22.52878], [114.11656, 22.53415], [114.12665, 22.54003], [114.13823, 22.54319], [114.1482, 22.54091], [114.15123, 22.55163], [114.1597, 22.56041], [114.17247, 22.55944], [114.18338, 22.55444], [114.20655, 22.55706], [114.22185, 22.55343], [114.22888, 22.5436], [114.25154, 22.55977], [114.44998, 22.55977], [114.50148, 22.15017]]]] } },
22987 { type: "Feature", properties: { wikidata: "Q22890", nameEn: "Ireland", level: "sharedLandform" }, geometry: null },
22988 { type: "Feature", properties: { wikidata: "Q23666", nameEn: "Great Britain", country: "GB", level: "sharedLandform" }, geometry: null },
22989 { type: "Feature", properties: { wikidata: "Q23681", nameEn: "Northern Cyprus", groups: ["Q644636", "145", "142"], driveSide: "left", callingCodes: ["90 392"] }, geometry: { type: "MultiPolygon", coordinates: [[[[33.67678, 35.03866], [33.67742, 35.05963], [33.68474, 35.06602], [33.69095, 35.06237], [33.70861, 35.07644], [33.7161, 35.07279], [33.70209, 35.04882], [33.71482, 35.03722], [33.73824, 35.05321], [33.76106, 35.04253], [33.78581, 35.05104], [33.82067, 35.07826], [33.84168, 35.06823], [33.8541, 35.07201], [33.87479, 35.08881], [33.87097, 35.09389], [33.87622, 35.10457], [33.87224, 35.12293], [33.88561, 35.12449], [33.88943, 35.12007], [33.88737, 35.11408], [33.89853, 35.11377], [33.91789, 35.08688], [33.91299, 35.07579], [33.90247, 35.07686], [33.89485, 35.06873], [33.88367, 35.07877], [33.85261, 35.0574], [33.8355, 35.05777], [33.82051, 35.0667], [33.8012, 35.04786], [33.81524, 35.04192], [33.83055, 35.02865], [33.82875, 35.01685], [33.84045, 35.00616], [33.85216, 35.00579], [33.85891, 35.001], [33.85621, 34.98956], [33.83505, 34.98108], [33.84811, 34.97075], [33.86432, 34.97592], [33.90075, 34.96623], [33.98684, 34.76642], [35.48515, 34.70851], [35.51152, 36.10954], [32.82353, 35.70297], [32.46489, 35.48584], [32.60361, 35.16647], [32.64864, 35.19967], [32.70947, 35.18328], [32.70779, 35.14127], [32.85733, 35.07742], [32.86406, 35.1043], [32.94471, 35.09422], [33.01192, 35.15639], [33.08249, 35.17319], [33.11105, 35.15639], [33.15138, 35.19504], [33.27068, 35.16815], [33.3072, 35.16816], [33.31955, 35.18096], [33.35056, 35.18328], [33.34964, 35.17803], [33.35596, 35.17942], [33.35612, 35.17402], [33.36569, 35.17479], [33.3717, 35.1788], [33.37248, 35.18698], [33.38575, 35.2018], [33.4076, 35.20062], [33.41675, 35.16325], [33.46813, 35.10564], [33.48136, 35.0636], [33.47825, 35.04103], [33.45178, 35.02078], [33.45256, 35.00288], [33.47666, 35.00701], [33.48915, 35.06594], [33.53975, 35.08151], [33.57478, 35.06049], [33.567, 35.04803], [33.59658, 35.03635], [33.61215, 35.0527], [33.63765, 35.03869], [33.67678, 35.03866]]]] } },
22990 { type: "Feature", properties: { wikidata: "Q25231", nameEn: "Svalbard", aliases: ["NO-21"], country: "NO", groups: ["SJ", "154", "150", "UN"], level: "subterritory", callingCodes: ["47 79"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-7.49892, 77.24208], [32.07813, 72.01005], [36.85549, 84.09565], [-7.49892, 77.24208]]]] } },
22991 { type: "Feature", properties: { wikidata: "Q25263", nameEn: "Azores", aliases: ["PT-20"], country: "PT", groups: ["Q3320166", "Q2914565", "Q105472", "EU", "039", "150", "UN"], callingCodes: ["351"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-23.12984, 40.26428], [-36.43765, 41.39418], [-22.54767, 33.34416], [-23.12984, 40.26428]]]] } },
22992 { type: "Feature", properties: { wikidata: "Q25359", nameEn: "Navassa Island", aliases: ["UM-76"], country: "US", groups: ["UM", "Q1352230", "029", "003", "419", "019", "UN"], level: "subterritory", roadSpeedUnit: "mph", roadHeightUnit: "ft" }, geometry: { type: "MultiPolygon", coordinates: [[[[-74.7289, 18.71009], [-75.71816, 18.46438], [-74.76465, 18.06252], [-74.7289, 18.71009]]]] } },
22993 { type: "Feature", properties: { wikidata: "Q25396", nameEn: "Bonaire", aliases: ["BQ-BO", "NL-BQ1"], country: "NL", groups: ["Q1451600", "BQ", "029", "003", "419", "019", "UN"], level: "subterritory", callingCodes: ["599 7"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-67.89186, 12.4116], [-68.90012, 12.62309], [-68.33524, 11.78151], [-68.01417, 11.77722], [-67.89186, 12.4116]]]] } },
22994 { type: "Feature", properties: { wikidata: "Q25528", nameEn: "Saba", aliases: ["BQ-SA", "NL-BQ2"], country: "NL", groups: ["Q1451600", "BQ", "029", "003", "419", "019", "UN"], level: "subterritory", callingCodes: ["599 4"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-63.07669, 17.79659], [-63.81314, 17.95045], [-63.22932, 17.32592], [-63.07669, 17.79659]]]] } },
22995 { type: "Feature", properties: { wikidata: "Q26180", nameEn: "Sint Eustatius", aliases: ["BQ-SE", "NL-BQ3"], country: "NL", groups: ["Q1451600", "BQ", "029", "003", "419", "019", "UN"], level: "subterritory", callingCodes: ["599 3"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-63.07669, 17.79659], [-63.34999, 16.94218], [-62.76692, 17.64353], [-63.07669, 17.79659]]]] } },
22996 { type: "Feature", properties: { wikidata: "Q26253", nameEn: "Madeira", aliases: ["PT-30"], country: "PT", groups: ["Q3320166", "Q2914565", "Q105472", "EU", "039", "150", "UN"], callingCodes: ["351"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-19.30302, 33.65304], [-16.04789, 29.65076], [-11.68307, 33.12333], [-19.30302, 33.65304]]]] } },
22997 { type: "Feature", properties: { wikidata: "Q26927", nameEn: "Lakshadweep", aliases: ["IN-LD"], country: "IN", groups: ["034", "142", "UN"], driveSide: "left", callingCodes: ["91"] }, geometry: { type: "MultiPolygon", coordinates: [[[[67.64074, 11.57295], [76.59015, 5.591], [72.67494, 13.58102], [67.64074, 11.57295]]]] } },
22998 { type: "Feature", properties: { wikidata: "Q27329", nameEn: "Asian Russia", country: "RU", groups: ["142", "UN"], callingCodes: ["7"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-179.99933, 64.74703], [-172.76104, 63.77445], [-169.03888, 65.48473], [-168.95635, 65.98512], [-168.25765, 71.99091], [-179.9843, 71.90735], [-179.99933, 64.74703]]], [[[59.99809, 51.98263], [60.19925, 51.99173], [60.48915, 52.15175], [60.72581, 52.15538], [60.78201, 52.22067], [61.05417, 52.35096], [60.98021, 52.50068], [60.84709, 52.52228], [60.84118, 52.63912], [60.71693, 52.66245], [60.71989, 52.75923], [61.05842, 52.92217], [61.23462, 53.03227], [62.0422, 52.96105], [62.12799, 52.99133], [62.14574, 53.09626], [61.19024, 53.30536], [61.14291, 53.41481], [61.29082, 53.50992], [61.37957, 53.45887], [61.57185, 53.50112], [61.55706, 53.57144], [60.90626, 53.62937], [61.22574, 53.80268], [61.14283, 53.90063], [60.99796, 53.93699], [61.26863, 53.92797], [61.3706, 54.08464], [61.47603, 54.08048], [61.56941, 53.95703], [61.65318, 54.02445], [62.03913, 53.94768], [62.00966, 54.04134], [62.38535, 54.03961], [62.45931, 53.90737], [62.56876, 53.94047], [62.58651, 54.05871], [63.80604, 54.27079], [63.91224, 54.20013], [64.02715, 54.22679], [63.97686, 54.29763], [64.97216, 54.4212], [65.11033, 54.33028], [65.24663, 54.35721], [65.20174, 54.55216], [68.21308, 54.98645], [68.26661, 55.09226], [68.19206, 55.18823], [68.90865, 55.38148], [69.34224, 55.36344], [69.74917, 55.35545], [70.19179, 55.1476], [70.76493, 55.3027], [70.96009, 55.10558], [71.08288, 54.71253], [71.24185, 54.64965], [71.08706, 54.33376], [71.10379, 54.13326], [71.96141, 54.17736], [72.17477, 54.36303], [72.43415, 53.92685], [72.71026, 54.1161], [73.37963, 53.96132], [73.74778, 54.07194], [73.68921, 53.86522], [73.25412, 53.61532], [73.39218, 53.44623], [75.07405, 53.80831], [75.43398, 53.98652], [75.3668, 54.07439], [76.91052, 54.4677], [76.82266, 54.1798], [76.44076, 54.16017], [76.54243, 53.99329], [77.90383, 53.29807], [79.11255, 52.01171], [80.08138, 50.77658], [80.4127, 50.95581], [80.44819, 51.20855], [80.80318, 51.28262], [81.16999, 51.15662], [81.06091, 50.94833], [81.41248, 50.97524], [81.46581, 50.77658], [81.94999, 50.79307], [82.55443, 50.75412], [83.14607, 51.00796], [83.8442, 50.87375], [84.29385, 50.27257], [84.99198, 50.06793], [85.24047, 49.60239], [86.18709, 49.50259], [86.63674, 49.80136], [86.79056, 49.74787], [86.61307, 49.60239], [86.82606, 49.51796], [87.03071, 49.25142], [87.31465, 49.23603], [87.28386, 49.11626], [87.478, 49.07403], [87.48983, 49.13794], [87.81333, 49.17354], [87.98977, 49.18147], [88.15543, 49.30314], [88.17223, 49.46934], [88.42449, 49.48821], [88.82499, 49.44808], [89.70687, 49.72535], [89.59711, 49.90851], [91.86048, 50.73734], [92.07173, 50.69585], [92.44714, 50.78762], [93.01109, 50.79001], [92.99595, 50.63183], [94.30823, 50.57498], [94.39258, 50.22193], [94.49477, 50.17832], [94.6121, 50.04239], [94.97166, 50.04725], [95.02465, 49.96941], [95.74757, 49.97915], [95.80056, 50.04239], [96.97388, 49.88413], [97.24639, 49.74737], [97.56811, 49.84265], [97.56432, 49.92801], [97.76871, 49.99861], [97.85197, 49.91339], [98.29481, 50.33561], [98.31373, 50.4996], [98.06393, 50.61262], [97.9693, 50.78044], [98.01472, 50.86652], [97.83305, 51.00248], [98.05257, 51.46696], [98.22053, 51.46579], [98.33222, 51.71832], [98.74142, 51.8637], [98.87768, 52.14563], [99.27888, 51.96876], [99.75578, 51.90108], [99.89203, 51.74903], [100.61116, 51.73028], [101.39085, 51.45753], [101.5044, 51.50467], [102.14032, 51.35566], [102.32194, 50.67982], [102.71178, 50.38873], [103.70343, 50.13952], [105.32528, 50.4648], [106.05562, 50.40582], [106.07865, 50.33474], [106.47156, 50.31909], [106.49628, 50.32436], [106.51122, 50.34408], [106.58373, 50.34044], [106.80326, 50.30177], [107.00007, 50.1977], [107.1174, 50.04239], [107.36407, 49.97612], [107.96116, 49.93191], [107.95387, 49.66659], [108.27937, 49.53167], [108.53969, 49.32325], [109.18017, 49.34709], [109.51325, 49.22859], [110.24373, 49.16676], [110.39891, 49.25083], [110.64493, 49.1816], [113.02647, 49.60772], [113.20216, 49.83356], [114.325, 50.28098], [114.9703, 50.19254], [115.26068, 49.97367], [115.73602, 49.87688], [116.22402, 50.04477], [116.62502, 49.92919], [116.71193, 49.83813], [117.27597, 49.62544], [117.48208, 49.62324], [117.82343, 49.52696], [118.61623, 49.93809], [119.11003, 50.00276], [119.27996, 50.13348], [119.38598, 50.35162], [119.13553, 50.37412], [120.10963, 51.671], [120.65907, 51.93544], [120.77337, 52.20805], [120.61346, 52.32447], [120.71673, 52.54099], [120.46454, 52.63811], [120.04049, 52.58773], [120.0451, 52.7359], [120.85633, 53.28499], [121.39213, 53.31888], [122.35063, 53.49565], [122.85966, 53.47395], [123.26989, 53.54843], [123.86158, 53.49391], [124.46078, 53.21881], [125.17522, 53.20225], [125.6131, 53.07229], [126.558, 52.13738], [126.44606, 51.98254], [126.68349, 51.70607], [126.90369, 51.3238], [126.93135, 51.0841], [127.14586, 50.91152], [127.28165, 50.72075], [127.36335, 50.58306], [127.28765, 50.46585], [127.36009, 50.43787], [127.37384, 50.28393], [127.60515, 50.23503], [127.49299, 50.01251], [127.53516, 49.84306], [127.83476, 49.5748], [128.72896, 49.58676], [129.11153, 49.36813], [129.23232, 49.40353], [129.35317, 49.3481], [129.40398, 49.44194], [129.50685, 49.42398], [129.67598, 49.29596], [129.85416, 49.11067], [130.2355, 48.86741], [130.43232, 48.90844], [130.66946, 48.88251], [130.52147, 48.61745], [130.84462, 48.30942], [130.65103, 48.10052], [130.90915, 47.90623], [130.95985, 47.6957], [131.09871, 47.6852], [131.2635, 47.73325], [131.90448, 47.68011], [132.57309, 47.71741], [132.66989, 47.96491], [134.49516, 48.42884], [134.75328, 48.36763], [134.67098, 48.1564], [134.55508, 47.98651], [134.7671, 47.72051], [134.50898, 47.4812], [134.20016, 47.33458], [134.03538, 46.75668], [133.84104, 46.46681], [133.91496, 46.4274], [133.88097, 46.25066], [133.68047, 46.14697], [133.72695, 46.05576], [133.67569, 45.9759], [133.60442, 45.90053], [133.48457, 45.86203], [133.41083, 45.57723], [133.19419, 45.51913], [133.09279, 45.25693], [133.12293, 45.1332], [132.96373, 45.0212], [132.83978, 45.05916], [131.99417, 45.2567], [131.86903, 45.33636], [131.76532, 45.22609], [131.66852, 45.2196], [131.68466, 45.12374], [131.48415, 44.99513], [130.95639, 44.85154], [131.1108, 44.70266], [131.30365, 44.04262], [131.25484, 44.03131], [131.23583, 43.96085], [131.26176, 43.94011], [131.21105, 43.82383], [131.19492, 43.53047], [131.29402, 43.46695], [131.30324, 43.39498], [131.19031, 43.21385], [131.20414, 43.13654], [131.10274, 43.04734], [131.135, 42.94114], [131.02668, 42.91246], [131.02438, 42.86518], [130.66524, 42.84753], [130.44361, 42.76205], [130.40213, 42.70788], [130.56576, 42.68925], [130.62107, 42.58413], [130.55143, 42.52158], [130.56835, 42.43281], [130.60805, 42.4317], [130.64181, 42.41422], [130.66367, 42.38024], [130.65022, 42.32281], [131.95041, 41.5445], [140.9182, 45.92937], [145.82343, 44.571], [145.23667, 43.76813], [153.94307, 38.42848], [180, 62.52334], [180, 71.53642], [155.31937, 81.93282], [76.13964, 83.37843], [64.18965, 69.94255], [66.1708, 67.61252], [61.98014, 65.72191], [60.74386, 64.95767], [59.63945, 64.78384], [59.80579, 64.13948], [59.24834, 63.01859], [59.61398, 62.44915], [59.36223, 61.3882], [59.50685, 60.91162], [58.3853, 59.487], [59.15636, 59.14682], [59.40376, 58.45822], [58.71104, 58.07475], [58.81412, 57.71602], [58.13789, 57.68097], [58.07604, 57.08308], [57.28024, 56.87898], [57.51527, 56.08729], [59.28419, 56.15739], [59.49035, 55.60486], [58.81825, 55.03378], [57.25137, 55.26262], [57.14829, 54.84204], [57.95234, 54.39672], [59.95217, 54.85853], [59.70487, 54.14846], [58.94336, 53.953], [58.79644, 52.43392], [59.22409, 52.28437], [59.25033, 52.46803], [60.17516, 52.39457], [60.17253, 52.25814], [59.91279, 52.06924], [59.99809, 51.98263]]]] } },
22999 { type: "Feature", properties: { wikidata: "Q34366", nameEn: "Tasmania", aliases: ["AU-TAS"], country: "AU", groups: ["053", "009", "UN"], driveSide: "left", callingCodes: ["61"] }, geometry: { type: "MultiPolygon", coordinates: [[[[123.64533, -39.13605], [159.69067, -56.28945], [159.74028, -39.1978], [123.64533, -39.13605]]]] } },
23000 { type: "Feature", properties: { wikidata: "Q34497", nameEn: "Saint Helena", aliases: ["SH-HL"], country: "GB", groups: ["SH", "BOTS", "011", "202", "002", "UN"], level: "subterritory", driveSide: "left", roadSpeedUnit: "mph", roadHeightUnit: "ft", callingCodes: ["290"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-8.3824, -13.9131], [-6.17428, -19.07236], [-3.29308, -15.22647], [-8.3824, -13.9131]]]] } },
23001 { type: "Feature", properties: { wikidata: "Q35657", nameEn: "US States", country: "US", level: "subcountryGroup" }, geometry: null },
23002 { type: "Feature", properties: { wikidata: "Q36117", nameEn: "Borneo", level: "sharedLandform" }, geometry: null },
23003 { type: "Feature", properties: { wikidata: "Q36678", nameEn: "West Bank", country: "PS", groups: ["145", "142"], callingCodes: ["970"] }, geometry: { type: "MultiPolygon", coordinates: [[[[35.47672, 31.49578], [35.55941, 31.76535], [35.52758, 31.9131], [35.54375, 31.96587], [35.52012, 32.04076], [35.57111, 32.21877], [35.55807, 32.38674], [35.42078, 32.41562], [35.41048, 32.43706], [35.41598, 32.45593], [35.42034, 32.46009], [35.40224, 32.50136], [35.35212, 32.52047], [35.30685, 32.51024], [35.29306, 32.50947], [35.25049, 32.52453], [35.2244, 32.55289], [35.15937, 32.50466], [35.10882, 32.4757], [35.10024, 32.47856], [35.09236, 32.47614], [35.08564, 32.46948], [35.07059, 32.4585], [35.05423, 32.41754], [35.05311, 32.4024], [35.0421, 32.38242], [35.05142, 32.3667], [35.04243, 32.35008], [35.01772, 32.33863], [35.01119, 32.28684], [35.02939, 32.2671], [35.01841, 32.23981], [34.98885, 32.20758], [34.95703, 32.19522], [34.96009, 32.17503], [34.99039, 32.14626], [34.98507, 32.12606], [34.99437, 32.10962], [34.9863, 32.09551], [35.00261, 32.027], [34.98682, 31.96935], [35.00124, 31.93264], [35.03489, 31.92448], [35.03978, 31.89276], [35.03489, 31.85919], [34.99712, 31.85569], [34.9724, 31.83352], [35.01978, 31.82944], [35.05617, 31.85685], [35.07677, 31.85627], [35.14174, 31.81325], [35.18603, 31.80901], [35.18169, 31.82542], [35.19461, 31.82687], [35.21469, 31.81835], [35.216, 31.83894], [35.21128, 31.863], [35.20381, 31.86716], [35.20673, 31.88151], [35.20791, 31.8821], [35.20945, 31.8815], [35.21016, 31.88237], [35.21276, 31.88153], [35.2136, 31.88241], [35.22014, 31.88264], [35.22294, 31.87889], [35.22567, 31.86745], [35.22817, 31.8638], [35.2249, 31.85433], [35.2304, 31.84222], [35.24816, 31.8458], [35.25753, 31.8387], [35.251, 31.83085], [35.26404, 31.82567], [35.25573, 31.81362], [35.26058, 31.79064], [35.25225, 31.7678], [35.26319, 31.74846], [35.25182, 31.73945], [35.24981, 31.72543], [35.2438, 31.7201], [35.24315, 31.71244], [35.23972, 31.70896], [35.22392, 31.71899], [35.21937, 31.71578], [35.20538, 31.72388], [35.18023, 31.72067], [35.16478, 31.73242], [35.15474, 31.73352], [35.15119, 31.73634], [35.13931, 31.73012], [35.12933, 31.7325], [35.11895, 31.71454], [35.10782, 31.71594], [35.08226, 31.69107], [35.00879, 31.65426], [34.95249, 31.59813], [34.9415, 31.55601], [34.94356, 31.50743], [34.93258, 31.47816], [34.89756, 31.43891], [34.87833, 31.39321], [34.88932, 31.37093], [34.92571, 31.34337], [35.02459, 31.35979], [35.13033, 31.3551], [35.22921, 31.37445], [35.39675, 31.49572], [35.47672, 31.49578]]]] } },
23004 { type: "Feature", properties: { wikidata: "Q37362", nameEn: "Akrotiri and Dhekelia", aliases: ["SBA"], country: "GB" }, geometry: null },
23005 { type: "Feature", properties: { wikidata: "Q38095", nameEn: "Gal\xE1pagos Islands", aliases: ["EC-W"], country: "EC", groups: ["005", "419", "019", "UN"], callingCodes: ["593"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-93.12365, 2.64343], [-92.46744, -2.52874], [-87.07749, -0.8849], [-93.12365, 2.64343]]]] } },
23006 { type: "Feature", properties: { wikidata: "Q39760", nameEn: "Gaza Strip", country: "PS", groups: ["145", "142"], callingCodes: ["970"] }, geometry: { type: "MultiPolygon", coordinates: [[[[34.052, 31.46619], [34.21853, 31.32363], [34.23572, 31.2966], [34.24012, 31.29591], [34.26742, 31.21998], [34.29417, 31.24194], [34.36523, 31.28963], [34.37381, 31.30598], [34.36505, 31.36404], [34.40077, 31.40926], [34.48892, 31.48365], [34.56797, 31.54197], [34.48681, 31.59711], [34.29262, 31.70393], [34.052, 31.46619]]]] } },
23007 { type: "Feature", properties: { wikidata: "Q40888", nameEn: "Andaman and Nicobar Islands", aliases: ["IN-AN"], country: "IN", groups: ["034", "142", "UN"], driveSide: "left", callingCodes: ["91"] }, geometry: { type: "MultiPolygon", coordinates: [[[[94.42132, 5.96581], [94.6371, 13.81803], [86.7822, 13.41052], [94.42132, 5.96581]]]] } },
23008 { type: "Feature", properties: { wikidata: "Q41684", nameEn: "Stewart Island", country: "NZ", groups: ["053", "009", "UN"], driveSide: "left", callingCodes: ["64"] }, geometry: { type: "MultiPolygon", coordinates: [[[[166.59185, -47.61313], [169.70504, -47.56021], [167.52103, -46.41337], [166.59185, -47.61313]]]] } },
23009 { type: "Feature", properties: { wikidata: "Q43296", nameEn: "Wake Island", aliases: ["WK", "WAK", "WKUM", "872", "UM-79"], country: "US", groups: ["UM", "Q1352230", "057", "009", "UN"], level: "subterritory", roadSpeedUnit: "mph", roadHeightUnit: "ft", callingCodes: ["1"] }, geometry: { type: "MultiPolygon", coordinates: [[[[167.34779, 18.97692], [166.67967, 20.14834], [165.82549, 18.97692], [167.34779, 18.97692]]]] } },
23010 { type: "Feature", properties: { wikidata: "Q46275", nameEn: "New Zealand Subantarctic Islands", country: "NZ", groups: ["Q851132", "053", "009", "UN"], driveSide: "left" }, geometry: { type: "MultiPolygon", coordinates: [[[[164.30551, -47.88072], [161.96603, -56.07661], [179.49541, -50.04657], [179.49541, -47.2902], [169.91032, -47.66283], [164.30551, -47.88072]]]] } },
23011 { type: "Feature", properties: { wikidata: "Q46395", nameEn: "British Overseas Territories", aliases: ["BOTS", "UKOTS"], country: "GB", level: "subcountryGroup" }, geometry: null },
23012 { type: "Feature", properties: { wikidata: "Q46772", nameEn: "Kerguelen Islands", country: "FR", groups: ["EU", "TF", "Q1451600", "014", "202", "002", "UN"], level: "subterritory" }, geometry: { type: "MultiPolygon", coordinates: [[[[61.9216, -49.39746], [70.67507, -51.14192], [74.25129, -45.45074], [61.9216, -49.39746]]]] } },
23013 { type: "Feature", properties: { wikidata: "Q46879", nameEn: "Baker Island", aliases: ["UM-81"], country: "US", groups: ["UM", "Q1352230", "061", "009", "UN"], level: "subterritory", roadSpeedUnit: "mph", roadHeightUnit: "ft" }, geometry: { type: "MultiPolygon", coordinates: [[[[-175.33482, -1.40631], [-175.31323, 0.5442], [-177.91421, 0.39582], [-175.33482, -1.40631]]]] } },
23014 { type: "Feature", properties: { wikidata: "Q47863", nameEn: "Midway Atoll", aliases: ["MI", "MID", "MIUM", "488", "UM-71"], country: "US", groups: ["UM", "Q1352230", "061", "009", "UN"], level: "subterritory", roadSpeedUnit: "mph", roadHeightUnit: "ft", callingCodes: ["1"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-176.29741, 29.09786], [-177.77531, 29.29793], [-177.5224, 27.7635], [-176.29741, 29.09786]]]] } },
23015 { type: "Feature", properties: { wikidata: "Q62218", nameEn: "Jarvis Island", aliases: ["UM-86"], country: "US", groups: ["UM", "Q1352230", "061", "009", "UN"], level: "subterritory", roadSpeedUnit: "mph", roadHeightUnit: "ft" }, geometry: { type: "MultiPolygon", coordinates: [[[[-160.42921, -1.4364], [-159.12443, 0.19975], [-160.38779, 0.30331], [-160.42921, -1.4364]]]] } },
23016 { type: "Feature", properties: { wikidata: "Q105472", nameEn: "Macaronesia", level: "sharedLandform" }, geometry: null },
23017 { type: "Feature", properties: { wikidata: "Q114935", nameEn: "Kermadec Islands", country: "NZ", groups: ["Q851132", "053", "009", "UN"], driveSide: "left", callingCodes: ["64"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-174.40891, -29.09438], [-180, -24.21376], [-179.96512, -35.00791], [-174.40891, -29.09438]]]] } },
23018 { type: "Feature", properties: { wikidata: "Q115459", nameEn: "Chatham Islands", aliases: ["NZ-CIT"], country: "NZ", groups: ["Q851132", "053", "009", "UN"], driveSide: "left", callingCodes: ["64"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-179.93224, -45.18423], [-172.47015, -45.17912], [-176.30998, -41.38382], [-179.93224, -45.18423]]]] } },
23019 { type: "Feature", properties: { wikidata: "Q118863", nameEn: "North Island", country: "NZ", groups: ["053", "009", "UN"], driveSide: "left", callingCodes: ["64"] }, geometry: { type: "MultiPolygon", coordinates: [[[[179.49541, -47.2902], [179.49541, -36.79303], [174.17679, -32.62487], [170.27492, -36.38133], [174.58663, -40.80446], [174.46634, -41.55028], [179.49541, -47.2902]]]] } },
23020 { type: "Feature", properties: { wikidata: "Q120755", nameEn: "South Island", country: "NZ", groups: ["053", "009", "UN"], driveSide: "left", callingCodes: ["64"] }, geometry: { type: "MultiPolygon", coordinates: [[[[169.70504, -47.56021], [179.49541, -47.2902], [174.46634, -41.55028], [174.58663, -40.80446], [170.27492, -36.38133], [166.56976, -39.94841], [164.8365, -46.0205], [167.52103, -46.41337], [169.70504, -47.56021]]]] } },
23021 { type: "Feature", properties: { wikidata: "Q123076", nameEn: "Palmyra Atoll", aliases: ["UM-95"], country: "US", groups: ["UM", "Q1352230", "061", "009", "UN"], level: "subterritory", roadSpeedUnit: "mph", roadHeightUnit: "ft", callingCodes: ["1"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-161.06795, 5.2462], [-161.0731, 7.1291], [-163.24478, 5.24198], [-161.06795, 5.2462]]]] } },
23022 { type: "Feature", properties: { wikidata: "Q130574", nameEn: "Chafarinas Islands", country: "ES", groups: ["EU", "Q191011", "015", "002", "UN"], level: "subterritory" }, geometry: { type: "MultiPolygon", coordinates: [[[[-2.40316, 35.16893], [-2.43262, 35.20652], [-2.45965, 35.16527], [-2.40316, 35.16893]]]] } },
23023 { type: "Feature", properties: { wikidata: "Q130895", nameEn: "Kingman Reef", aliases: ["UM-89"], country: "US", groups: ["UM", "Q1352230", "061", "009", "UN"], level: "subterritory", roadSpeedUnit: "mph", roadHeightUnit: "ft" }, geometry: { type: "MultiPolygon", coordinates: [[[[-161.0731, 7.1291], [-163.16627, 7.15036], [-163.24478, 5.24198], [-161.0731, 7.1291]]]] } },
23024 { type: "Feature", properties: { wikidata: "Q131008", nameEn: "Johnston Atoll", aliases: ["JT", "JTN", "JTUM", "396", "UM-67"], country: "US", groups: ["UM", "Q1352230", "061", "009", "UN"], level: "subterritory", roadSpeedUnit: "mph", roadHeightUnit: "ft", callingCodes: ["1"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-170.65691, 16.57199], [-168.87689, 16.01159], [-169.2329, 17.4933], [-170.65691, 16.57199]]]] } },
23025 { type: "Feature", properties: { wikidata: "Q131305", nameEn: "Howland Island", aliases: ["UM-84"], country: "US", groups: ["UM", "Q1352230", "061", "009", "UN"], level: "subterritory", roadSpeedUnit: "mph", roadHeightUnit: "ft" }, geometry: { type: "MultiPolygon", coordinates: [[[[-177.91421, 0.39582], [-175.31323, 0.5442], [-176.74464, 2.28109], [-177.91421, 0.39582]]]] } },
23026 { type: "Feature", properties: { wikidata: "Q133888", nameEn: "Ashmore and Cartier Islands", country: "AU", groups: ["053", "009", "UN"], driveSide: "left", callingCodes: ["61"] }, geometry: { type: "MultiPolygon", coordinates: [[[[123.7463, -11.1783], [120.6877, -13.59408], [125.29076, -12.33139], [123.7463, -11.1783]]]] } },
23027 { type: "Feature", properties: { wikidata: "Q153732", nameEn: "Mariana Islands", level: "sharedLandform" }, geometry: null },
23028 { type: "Feature", properties: { wikidata: "Q172216", nameEn: "Coral Sea Islands", country: "AU", groups: ["053", "009", "UN"], driveSide: "left", callingCodes: ["61"] }, geometry: { type: "MultiPolygon", coordinates: [[[[159.77159, -28.41151], [156.73836, -14.50464], [145.2855, -9.62524], [147.69992, -17.5933], [152.93188, -20.92631], [154.02855, -24.43238], [159.77159, -28.41151]]]] } },
23029 { type: "Feature", properties: { wikidata: "Q179313", nameEn: "Alderney", country: "GB", groups: ["GG", "830", "Q185086", "154", "150", "UN"], level: "subterritory", driveSide: "left", roadSpeedUnit: "mph", roadHeightUnit: "ft", callingCodes: ["44 01481"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-2.36485, 49.48223], [-2.09454, 49.46288], [-2.02963, 49.91866], [-2.49556, 49.79012], [-2.36485, 49.48223]]]] } },
23030 { type: "Feature", properties: { wikidata: "Q185086", nameEn: "Crown Dependencies", country: "GB", level: "subcountryGroup" }, geometry: null },
23031 { type: "Feature", properties: { wikidata: "Q190571", nameEn: "Scattered Islands", country: "FR", groups: ["EU", "TF", "Q1451600", "014", "202", "002", "UN"], level: "subterritory" }, geometry: { type: "MultiPolygon", coordinates: [[[[53.53458, -16.36909], [54.96649, -16.28353], [54.61476, -15.02273], [53.53458, -16.36909]]], [[[38.55969, -20.75596], [40.68027, -23.38889], [43.52893, -15.62903], [38.55969, -20.75596]]], [[[47.03092, -11.05648], [47.11593, -12.08552], [47.96702, -11.46447], [47.03092, -11.05648]]]] } },
23032 { type: "Feature", properties: { wikidata: "Q191011", nameEn: "Plazas de soberan\xEDa", country: "ES" }, geometry: null },
23033 { type: "Feature", properties: { wikidata: "Q191146", nameEn: "Pe\xF1\xF3n de V\xE9lez de la Gomera", country: "ES", groups: ["EU", "Q191011", "015", "002", "UN"], level: "subterritory" }, geometry: { type: "MultiPolygon", coordinates: [[[[-4.30191, 35.17419], [-4.30112, 35.17058], [-4.29436, 35.17149], [-4.30191, 35.17419]]]] } },
23034 { type: "Feature", properties: { wikidata: "Q201698", nameEn: "Crozet Islands", country: "FR", groups: ["EU", "TF", "Q1451600", "014", "202", "002", "UN"], level: "subterritory" }, geometry: { type: "MultiPolygon", coordinates: [[[[55.03425, -43.65017], [46.31615, -46.28749], [54.5587, -47.93013], [55.03425, -43.65017]]]] } },
23035 { type: "Feature", properties: { wikidata: "Q578170", nameEn: "Contiguous United States", aliases: ["CONUS"], country: "US", groups: ["Q35657", "021", "003", "019", "UN"], roadSpeedUnit: "mph", roadHeightUnit: "ft", callingCodes: ["1"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-97.13927, 25.96583], [-96.92418, 25.97377], [-80.57035, 24.0565], [-78.91214, 27.76553], [-61.98255, 37.34815], [-67.16117, 44.20069], [-66.93432, 44.82597], [-66.96824, 44.83078], [-66.98249, 44.87071], [-66.96824, 44.90965], [-67.0216, 44.95333], [-67.11316, 45.11176], [-67.15965, 45.16179], [-67.19603, 45.16771], [-67.20349, 45.1722], [-67.22751, 45.16344], [-67.27039, 45.1934], [-67.29748, 45.18173], [-67.29754, 45.14865], [-67.34927, 45.122], [-67.48201, 45.27351], [-67.42394, 45.37969], [-67.50578, 45.48971], [-67.42144, 45.50584], [-67.43815, 45.59162], [-67.6049, 45.60725], [-67.80705, 45.69528], [-67.80653, 45.80022], [-67.75654, 45.82324], [-67.80961, 45.87531], [-67.75196, 45.91814], [-67.78111, 45.9392], [-67.78578, 47.06473], [-67.87993, 47.10377], [-67.94843, 47.1925], [-68.23244, 47.35712], [-68.37458, 47.35851], [-68.38332, 47.28723], [-68.57914, 47.28431], [-68.60575, 47.24659], [-68.70125, 47.24399], [-68.89222, 47.1807], [-69.05039, 47.2456], [-69.05073, 47.30076], [-69.05148, 47.42012], [-69.22119, 47.46461], [-69.99966, 46.69543], [-70.05812, 46.41768], [-70.18547, 46.35357], [-70.29078, 46.18832], [-70.23855, 46.1453], [-70.31025, 45.96424], [-70.24694, 45.95138], [-70.25976, 45.89675], [-70.41523, 45.79497], [-70.38934, 45.73215], [-70.54019, 45.67291], [-70.68516, 45.56964], [-70.72651, 45.49771], [-70.62518, 45.42286], [-70.65383, 45.37592], [-70.78372, 45.43269], [-70.82638, 45.39828], [-70.80236, 45.37444], [-70.84816, 45.22698], [-70.89864, 45.2398], [-70.91169, 45.29849], [-70.95193, 45.33895], [-71.0107, 45.34819], [-71.01866, 45.31573], [-71.08364, 45.30623], [-71.14568, 45.24128], [-71.19723, 45.25438], [-71.22338, 45.25184], [-71.29371, 45.29996], [-71.37133, 45.24624], [-71.44252, 45.2361], [-71.40364, 45.21382], [-71.42778, 45.12624], [-71.48735, 45.07784], [-71.50067, 45.01357], [-73.35025, 45.00942], [-74.32699, 44.99029], [-74.66689, 45.00646], [-74.8447, 45.00606], [-74.99101, 44.98051], [-75.01363, 44.95608], [-75.2193, 44.87821], [-75.41441, 44.76614], [-75.76813, 44.51537], [-75.8217, 44.43176], [-75.95947, 44.34463], [-76.00018, 44.34896], [-76.16285, 44.28262], [-76.1664, 44.23051], [-76.244, 44.19643], [-76.31222, 44.19894], [-76.35324, 44.13493], [-76.43859, 44.09393], [-76.79706, 43.63099], [-79.25796, 43.54052], [-79.06921, 43.26183], [-79.05512, 43.25375], [-79.05544, 43.21224], [-79.05002, 43.20133], [-79.05384, 43.17418], [-79.04652, 43.16396], [-79.0427, 43.13934], [-79.06881, 43.12029], [-79.05671, 43.10937], [-79.07486, 43.07845], [-79.01055, 43.06659], [-78.99941, 43.05612], [-79.02424, 43.01983], [-79.02074, 42.98444], [-78.98126, 42.97], [-78.96312, 42.95509], [-78.93224, 42.95229], [-78.90905, 42.93022], [-78.90712, 42.89733], [-78.93684, 42.82887], [-82.67862, 41.67615], [-83.11184, 41.95671], [-83.14962, 42.04089], [-83.12724, 42.2376], [-83.09837, 42.28877], [-83.07837, 42.30978], [-83.02253, 42.33045], [-82.82964, 42.37355], [-82.64242, 42.55594], [-82.58873, 42.54984], [-82.57583, 42.5718], [-82.51858, 42.611], [-82.51063, 42.66025], [-82.46613, 42.76615], [-82.4826, 42.8068], [-82.45331, 42.93139], [-82.4253, 42.95423], [-82.4146, 42.97626], [-82.42469, 42.992], [-82.48419, 45.30225], [-83.59589, 45.82131], [-83.43746, 45.99749], [-83.57017, 46.105], [-83.83329, 46.12169], [-83.90453, 46.05922], [-83.95399, 46.05634], [-84.1096, 46.23987], [-84.09756, 46.25512], [-84.11615, 46.2681], [-84.11254, 46.32329], [-84.13451, 46.39218], [-84.11196, 46.50248], [-84.12885, 46.53068], [-84.17723, 46.52753], [-84.1945, 46.54061], [-84.2264, 46.53337], [-84.26351, 46.49508], [-84.29893, 46.49127], [-84.34174, 46.50683], [-84.42101, 46.49853], [-84.4481, 46.48972], [-84.47607, 46.45225], [-84.55635, 46.45974], [-84.85871, 46.88881], [-88.37033, 48.30586], [-89.48837, 48.01412], [-89.57972, 48.00023], [-89.77248, 48.02607], [-89.89974, 47.98109], [-90.07418, 48.11043], [-90.56312, 48.09488], [-90.56444, 48.12184], [-90.75045, 48.09143], [-90.87588, 48.2484], [-91.08016, 48.18096], [-91.25025, 48.08522], [-91.43248, 48.04912], [-91.45829, 48.07454], [-91.58025, 48.04339], [-91.55649, 48.10611], [-91.70451, 48.11805], [-91.71231, 48.19875], [-91.86125, 48.21278], [-91.98929, 48.25409], [-92.05339, 48.35958], [-92.14732, 48.36578], [-92.202, 48.35252], [-92.26662, 48.35651], [-92.30939, 48.31251], [-92.27167, 48.25046], [-92.37185, 48.22259], [-92.48147, 48.36609], [-92.45588, 48.40624], [-92.50712, 48.44921], [-92.65606, 48.43471], [-92.71323, 48.46081], [-92.69927, 48.49573], [-92.62747, 48.50278], [-92.6342, 48.54133], [-92.7287, 48.54005], [-92.94973, 48.60866], [-93.25391, 48.64266], [-93.33946, 48.62787], [-93.3712, 48.60599], [-93.39758, 48.60364], [-93.40693, 48.60948], [-93.44472, 48.59147], [-93.47022, 48.54357], [-93.66382, 48.51845], [-93.79267, 48.51631], [-93.80939, 48.52439], [-93.80676, 48.58232], [-93.83288, 48.62745], [-93.85769, 48.63284], [-94.23215, 48.65202], [-94.25104, 48.65729], [-94.25172, 48.68404], [-94.27153, 48.70232], [-94.4174, 48.71049], [-94.44258, 48.69223], [-94.53826, 48.70216], [-94.54885, 48.71543], [-94.58903, 48.71803], [-94.69335, 48.77883], [-94.69669, 48.80918], [-94.70486, 48.82365], [-94.70087, 48.8339], [-94.687, 48.84077], [-94.75017, 49.09931], [-94.77355, 49.11998], [-94.82487, 49.29483], [-94.8159, 49.32299], [-94.85381, 49.32492], [-94.95681, 49.37035], [-94.99532, 49.36579], [-95.01419, 49.35647], [-95.05825, 49.35311], [-95.12903, 49.37056], [-95.15357, 49.384], [-95.15355, 48.9996], [-123.32163, 49.00419], [-123.0093, 48.83186], [-123.0093, 48.76586], [-123.26565, 48.6959], [-123.15614, 48.35395], [-123.50039, 48.21223], [-125.03842, 48.53282], [-133.98258, 38.06389], [-118.48109, 32.5991], [-117.1243, 32.53427], [-115.88053, 32.63624], [-114.71871, 32.71894], [-114.76736, 32.64094], [-114.80584, 32.62028], [-114.81141, 32.55543], [-114.79524, 32.55731], [-114.82011, 32.49609], [-111.07523, 31.33232], [-108.20979, 31.33316], [-108.20899, 31.78534], [-106.529, 31.784], [-106.52266, 31.77509], [-106.51251, 31.76922], [-106.50962, 31.76155], [-106.50111, 31.75714], [-106.48815, 31.74769], [-106.47298, 31.75054], [-106.46726, 31.75998], [-106.45244, 31.76523], [-106.43419, 31.75478], [-106.41773, 31.75196], [-106.38003, 31.73151], [-106.3718, 31.71165], [-106.34864, 31.69663], [-106.33419, 31.66303], [-106.30305, 31.62154], [-106.28084, 31.56173], [-106.24612, 31.54193], [-106.23711, 31.51262], [-106.20346, 31.46305], [-106.09025, 31.40569], [-106.00363, 31.39181], [-104.77674, 30.4236], [-104.5171, 29.64671], [-104.3969, 29.57105], [-104.39363, 29.55396], [-104.37752, 29.54255], [-103.15787, 28.93865], [-102.60596, 29.8192], [-101.47277, 29.7744], [-101.05686, 29.44738], [-101.01128, 29.36947], [-100.96725, 29.3477], [-100.94579, 29.34523], [-100.94056, 29.33371], [-100.87982, 29.296], [-100.79696, 29.24688], [-100.67294, 29.09744], [-100.63689, 28.90812], [-100.59809, 28.88197], [-100.52313, 28.75598], [-100.5075, 28.74066], [-100.51222, 28.70679], [-100.50029, 28.66117], [-99.55409, 27.61314], [-99.51478, 27.55836], [-99.52955, 27.49747], [-99.50208, 27.50021], [-99.48045, 27.49016], [-99.482, 27.47128], [-99.49744, 27.43746], [-99.53573, 27.30926], [-99.08477, 26.39849], [-99.03053, 26.41249], [-99.00546, 26.3925], [-98.35126, 26.15129], [-98.30491, 26.10475], [-98.27075, 26.09457], [-98.24603, 26.07191], [-97.97017, 26.05232], [-97.95155, 26.0625], [-97.66511, 26.01708], [-97.52025, 25.88518], [-97.49828, 25.89877], [-97.45669, 25.86874], [-97.42511, 25.83969], [-97.37332, 25.83854], [-97.35946, 25.92189], [-97.13927, 25.96583]]]] } },
23036 { type: "Feature", properties: { wikidata: "Q620634", nameEn: "Bir Tawil", groups: ["015", "002"], level: "territory" }, geometry: { type: "MultiPolygon", coordinates: [[[[33.17563, 22.00405], [33.57251, 21.72406], [33.99686, 21.76784], [34.0765, 22.00501], [33.17563, 22.00405]]]] } },
23037 { type: "Feature", properties: { wikidata: "Q639185", nameEn: "Peros Banhos", country: "GB", groups: ["IO", "BOTS", "014", "202", "002", "UN"], level: "subterritory" }, geometry: { type: "MultiPolygon", coordinates: [[[[72.12587, -4.02588], [70.1848, -6.37445], [72.09518, -5.61768], [72.12587, -4.02588]]]] } },
23038 { type: "Feature", properties: { wikidata: "Q644636", nameEn: "Cyprus", level: "sharedLandform" }, geometry: null },
23039 { type: "Feature", properties: { wikidata: "Q851132", nameEn: "New Zealand Outlying Islands", country: "NZ", level: "subcountryGroup" }, geometry: null },
23040 { type: "Feature", properties: { wikidata: "Q875134", nameEn: "European Russia", country: "RU", groups: ["151", "150", "UN"], callingCodes: ["7"] }, geometry: { type: "MultiPolygon", coordinates: [[[[18.57853, 55.25302], [19.64312, 54.45423], [19.8038, 54.44203], [20.63871, 54.3706], [21.41123, 54.32395], [22.79705, 54.36264], [22.7253, 54.41732], [22.70208, 54.45312], [22.67788, 54.532], [22.71293, 54.56454], [22.68021, 54.58486], [22.7522, 54.63525], [22.74225, 54.64339], [22.75467, 54.6483], [22.73397, 54.66604], [22.73631, 54.72952], [22.87317, 54.79492], [22.85083, 54.88711], [22.76422, 54.92521], [22.68723, 54.9811], [22.65451, 54.97037], [22.60075, 55.01863], [22.58907, 55.07085], [22.47688, 55.04408], [22.31562, 55.0655], [22.14267, 55.05345], [22.11697, 55.02131], [22.06087, 55.02935], [22.02582, 55.05078], [22.03984, 55.07888], [21.99543, 55.08691], [21.96505, 55.07353], [21.85521, 55.09493], [21.64954, 55.1791], [21.55605, 55.20311], [21.51095, 55.18507], [21.46766, 55.21115], [21.38446, 55.29348], [21.35465, 55.28427], [21.26425, 55.24456], [20.95181, 55.27994], [20.60454, 55.40986], [18.57853, 55.25302]]], [[[26.32936, 60.00121], [26.90044, 59.63819], [27.85643, 59.58538], [28.04187, 59.47017], [28.19061, 59.39962], [28.21137, 59.38058], [28.20537, 59.36491], [28.19284, 59.35791], [28.14215, 59.28934], [28.00689, 59.28351], [27.90911, 59.24353], [27.87978, 59.18097], [27.80482, 59.1116], [27.74429, 58.98351], [27.36366, 58.78381], [27.55489, 58.39525], [27.48541, 58.22615], [27.62393, 58.09462], [27.67282, 57.92627], [27.81841, 57.89244], [27.78526, 57.83963], [27.56689, 57.83356], [27.50171, 57.78842], [27.52615, 57.72843], [27.3746, 57.66834], [27.40393, 57.62125], [27.31919, 57.57672], [27.34698, 57.52242], [27.56832, 57.53728], [27.52453, 57.42826], [27.86101, 57.29402], [27.66511, 56.83921], [27.86101, 56.88204], [28.04768, 56.59004], [28.13526, 56.57989], [28.10069, 56.524], [28.19057, 56.44637], [28.16599, 56.37806], [28.23716, 56.27588], [28.15217, 56.16964], [28.30571, 56.06035], [28.36888, 56.05805], [28.37987, 56.11399], [28.43068, 56.09407], [28.5529, 56.11705], [28.68337, 56.10173], [28.63668, 56.07262], [28.73418, 55.97131], [29.08299, 56.03427], [29.21717, 55.98971], [29.44692, 55.95978], [29.3604, 55.75862], [29.51283, 55.70294], [29.61446, 55.77716], [29.80672, 55.79569], [29.97975, 55.87281], [30.12136, 55.8358], [30.27776, 55.86819], [30.30987, 55.83592], [30.48257, 55.81066], [30.51346, 55.78982], [30.51037, 55.76568], [30.63344, 55.73079], [30.67464, 55.64176], [30.72957, 55.66268], [30.7845, 55.58514], [30.86003, 55.63169], [30.93419, 55.6185], [30.95204, 55.50667], [30.90123, 55.46621], [30.93144, 55.3914], [30.8257, 55.3313], [30.81946, 55.27931], [30.87944, 55.28223], [30.97369, 55.17134], [31.02071, 55.06167], [31.00972, 55.02783], [30.94243, 55.03964], [30.9081, 55.02232], [30.95754, 54.98609], [30.93144, 54.9585], [30.81759, 54.94064], [30.8264, 54.90062], [30.75165, 54.80699], [30.95479, 54.74346], [30.97127, 54.71967], [31.0262, 54.70698], [30.98226, 54.68872], [30.99187, 54.67046], [31.19339, 54.66947], [31.21399, 54.63113], [31.08543, 54.50361], [31.22945, 54.46585], [31.3177, 54.34067], [31.30791, 54.25315], [31.57002, 54.14535], [31.89599, 54.0837], [31.88744, 54.03653], [31.85019, 53.91801], [31.77028, 53.80015], [31.89137, 53.78099], [32.12621, 53.81586], [32.36663, 53.7166], [32.45717, 53.74039], [32.50112, 53.68594], [32.40499, 53.6656], [32.47777, 53.5548], [32.74968, 53.45597], [32.73257, 53.33494], [32.51725, 53.28431], [32.40773, 53.18856], [32.15368, 53.07594], [31.82373, 53.10042], [31.787, 53.18033], [31.62496, 53.22886], [31.56316, 53.19432], [31.40523, 53.21406], [31.36403, 53.13504], [31.3915, 53.09712], [31.33519, 53.08805], [31.32283, 53.04101], [31.24147, 53.031], [31.35667, 52.97854], [31.592, 52.79011], [31.57277, 52.71613], [31.50406, 52.69707], [31.63869, 52.55361], [31.56316, 52.51518], [31.61397, 52.48843], [31.62084, 52.33849], [31.57971, 52.32146], [31.70735, 52.26711], [31.6895, 52.1973], [31.77877, 52.18636], [31.7822, 52.11406], [31.81722, 52.09955], [31.85018, 52.11305], [31.96141, 52.08015], [31.92159, 52.05144], [32.08813, 52.03319], [32.23331, 52.08085], [32.2777, 52.10266], [32.34044, 52.1434], [32.33083, 52.23685], [32.38988, 52.24946], [32.3528, 52.32842], [32.54781, 52.32423], [32.69475, 52.25535], [32.85405, 52.27888], [32.89937, 52.2461], [33.18913, 52.3754], [33.51323, 52.35779], [33.48027, 52.31499], [33.55718, 52.30324], [33.78789, 52.37204], [34.05239, 52.20132], [34.11199, 52.14087], [34.09413, 52.00835], [34.41136, 51.82793], [34.42922, 51.72852], [34.07765, 51.67065], [34.17599, 51.63253], [34.30562, 51.5205], [34.22048, 51.4187], [34.33446, 51.363], [34.23009, 51.26429], [34.31661, 51.23936], [34.38802, 51.2746], [34.6613, 51.25053], [34.6874, 51.18], [34.82472, 51.17483], [34.97304, 51.2342], [35.14058, 51.23162], [35.12685, 51.16191], [35.20375, 51.04723], [35.31774, 51.08434], [35.40837, 51.04119], [35.32598, 50.94524], [35.39307, 50.92145], [35.41367, 50.80227], [35.47704, 50.77274], [35.48116, 50.66405], [35.39464, 50.64751], [35.47463, 50.49247], [35.58003, 50.45117], [35.61711, 50.35707], [35.73659, 50.35489], [35.80388, 50.41356], [35.8926, 50.43829], [36.06893, 50.45205], [36.20763, 50.3943], [36.30101, 50.29088], [36.47817, 50.31457], [36.58371, 50.28563], [36.56655, 50.2413], [36.64571, 50.218], [36.69377, 50.26982], [36.91762, 50.34963], [37.08468, 50.34935], [37.48204, 50.46079], [37.47243, 50.36277], [37.62486, 50.29966], [37.62879, 50.24481], [37.61113, 50.21976], [37.75807, 50.07896], [37.79515, 50.08425], [37.90776, 50.04194], [38.02999, 49.94482], [38.02999, 49.90592], [38.21675, 49.98104], [38.18517, 50.08161], [38.32524, 50.08866], [38.35408, 50.00664], [38.65688, 49.97176], [38.68677, 50.00904], [38.73311, 49.90238], [38.90477, 49.86787], [38.9391, 49.79524], [39.1808, 49.88911], [39.27968, 49.75976], [39.44496, 49.76067], [39.59142, 49.73758], [39.65047, 49.61761], [39.84548, 49.56064], [40.13249, 49.61672], [40.16683, 49.56865], [40.03636, 49.52321], [40.03087, 49.45452], [40.1141, 49.38798], [40.14912, 49.37681], [40.18331, 49.34996], [40.22176, 49.25683], [40.01988, 49.1761], [39.93437, 49.05709], [39.6836, 49.05121], [39.6683, 48.99454], [39.71353, 48.98959], [39.72649, 48.9754], [39.74874, 48.98675], [39.78368, 48.91596], [39.98967, 48.86901], [40.03636, 48.91957], [40.08168, 48.87443], [39.97182, 48.79398], [39.79466, 48.83739], [39.73104, 48.7325], [39.71765, 48.68673], [39.67226, 48.59368], [39.79764, 48.58668], [39.84548, 48.57821], [39.86196, 48.46633], [39.88794, 48.44226], [39.94847, 48.35055], [39.84136, 48.33321], [39.84273, 48.30947], [39.90041, 48.3049], [39.91465, 48.26743], [39.95248, 48.29972], [39.9693, 48.29904], [39.97325, 48.31399], [39.99241, 48.31768], [40.00752, 48.22445], [39.94847, 48.22811], [39.83724, 48.06501], [39.88256, 48.04482], [39.77544, 48.04206], [39.82213, 47.96396], [39.73935, 47.82876], [38.87979, 47.87719], [38.79628, 47.81109], [38.76379, 47.69346], [38.35062, 47.61631], [38.28679, 47.53552], [38.28954, 47.39255], [38.22225, 47.30788], [38.33074, 47.30508], [38.32112, 47.2585], [38.23049, 47.2324], [38.22955, 47.12069], [38.3384, 46.98085], [38.12112, 46.86078], [37.62608, 46.82615], [35.23066, 45.79231], [35.04991, 45.76827], [36.6645, 45.4514], [36.6545, 45.3417], [36.5049, 45.3136], [36.475, 45.2411], [36.4883, 45.0488], [33.5943, 44.03313], [39.81147, 43.06294], [40.0078, 43.38551], [40.00853, 43.40578], [40.01552, 43.42025], [40.01007, 43.42411], [40.03312, 43.44262], [40.04445, 43.47776], [40.10657, 43.57344], [40.65957, 43.56212], [41.64935, 43.22331], [42.40563, 43.23226], [42.66667, 43.13917], [42.75889, 43.19651], [43.03322, 43.08883], [43.0419, 43.02413], [43.81453, 42.74297], [43.73119, 42.62043], [43.95517, 42.55396], [44.54202, 42.75699], [44.70002, 42.74679], [44.80941, 42.61277], [44.88754, 42.74934], [45.15318, 42.70598], [45.36501, 42.55268], [45.78692, 42.48358], [45.61676, 42.20768], [46.42738, 41.91323], [46.5332, 41.87389], [46.58924, 41.80547], [46.75269, 41.8623], [46.8134, 41.76252], [47.00955, 41.63583], [46.99554, 41.59743], [47.03757, 41.55434], [47.10762, 41.59044], [47.34579, 41.27884], [47.49004, 41.26366], [47.54504, 41.20275], [47.62288, 41.22969], [47.75831, 41.19455], [47.87973, 41.21798], [48.07587, 41.49957], [48.22064, 41.51472], [48.2878, 41.56221], [48.40277, 41.60441], [48.42301, 41.65444], [48.55078, 41.77917], [48.5867, 41.84306], [48.80971, 41.95365], [49.2134, 44.84989], [49.88945, 46.04554], [49.32259, 46.26944], [49.16518, 46.38542], [48.54988, 46.56267], [48.51142, 46.69268], [49.01136, 46.72716], [48.52326, 47.4102], [48.45173, 47.40818], [48.15348, 47.74545], [47.64973, 47.76559], [47.41689, 47.83687], [47.38731, 47.68176], [47.12107, 47.83687], [47.11516, 48.27188], [46.49011, 48.43019], [46.78392, 48.95352], [47.00857, 49.04921], [47.04658, 49.19834], [46.78398, 49.34026], [46.9078, 49.86707], [47.18319, 49.93721], [47.34589, 50.09308], [47.30448, 50.30894], [47.58551, 50.47867], [48.10044, 50.09242], [48.24519, 49.86099], [48.42564, 49.82283], [48.68352, 49.89546], [48.90782, 50.02281], [48.57946, 50.63278], [48.86936, 50.61589], [49.12673, 50.78639], [49.41959, 50.85927], [49.39001, 51.09396], [49.76866, 51.11067], [49.97277, 51.2405], [50.26859, 51.28677], [50.59695, 51.61859], [51.26254, 51.68466], [51.301, 51.48799], [51.77431, 51.49536], [51.8246, 51.67916], [52.36119, 51.74161], [52.54329, 51.48444], [53.46165, 51.49445], [53.69299, 51.23466], [54.12248, 51.11542], [54.46331, 50.85554], [54.41894, 50.61214], [54.55797, 50.52006], [54.71476, 50.61214], [54.56685, 51.01958], [54.72067, 51.03261], [55.67774, 50.54508], [56.11398, 50.7471], [56.17906, 50.93204], [57.17302, 51.11253], [57.44221, 50.88354], [57.74986, 50.93017], [57.75578, 51.13852], [58.3208, 51.15151], [58.87974, 50.70852], [59.48928, 50.64216], [59.51886, 50.49937], [59.81172, 50.54451], [60.01288, 50.8163], [60.17262, 50.83312], [60.31914, 50.67705], [60.81833, 50.6629], [61.4431, 50.80679], [61.56889, 51.23679], [61.6813, 51.25716], [61.55114, 51.32746], [61.50677, 51.40687], [60.95655, 51.48615], [60.92401, 51.61124], [60.5424, 51.61675], [60.36787, 51.66815], [60.50986, 51.7964], [60.09867, 51.87135], [59.99809, 51.98263], [59.91279, 52.06924], [60.17253, 52.25814], [60.17516, 52.39457], [59.25033, 52.46803], [59.22409, 52.28437], [58.79644, 52.43392], [58.94336, 53.953], [59.70487, 54.14846], [59.95217, 54.85853], [57.95234, 54.39672], [57.14829, 54.84204], [57.25137, 55.26262], [58.81825, 55.03378], [59.49035, 55.60486], [59.28419, 56.15739], [57.51527, 56.08729], [57.28024, 56.87898], [58.07604, 57.08308], [58.13789, 57.68097], [58.81412, 57.71602], [58.71104, 58.07475], [59.40376, 58.45822], [59.15636, 59.14682], [58.3853, 59.487], [59.50685, 60.91162], [59.36223, 61.3882], [59.61398, 62.44915], [59.24834, 63.01859], [59.80579, 64.13948], [59.63945, 64.78384], [60.74386, 64.95767], [61.98014, 65.72191], [66.1708, 67.61252], [64.18965, 69.94255], [76.13964, 83.37843], [36.85549, 84.09565], [32.07813, 72.01005], [31.59909, 70.16571], [30.84095, 69.80584], [30.95011, 69.54699], [30.52662, 69.54699], [30.16363, 69.65244], [29.97205, 69.41623], [29.27631, 69.2811], [29.26623, 69.13794], [29.0444, 69.0119], [28.91738, 69.04774], [28.45957, 68.91417], [28.78224, 68.86696], [28.43941, 68.53366], [28.62982, 68.19816], [29.34179, 68.06655], [29.66955, 67.79872], [30.02041, 67.67523], [29.91155, 67.51507], [28.9839, 66.94139], [29.91155, 66.13863], [30.16363, 65.66935], [29.97205, 65.70256], [29.74013, 65.64025], [29.84096, 65.56945], [29.68972, 65.31803], [29.61914, 65.23791], [29.8813, 65.22101], [29.84096, 65.1109], [29.61914, 65.05993], [29.68972, 64.80789], [30.05271, 64.79072], [30.12329, 64.64862], [30.01238, 64.57513], [30.06279, 64.35782], [30.4762, 64.25728], [30.55687, 64.09036], [30.25437, 63.83364], [29.98213, 63.75795], [30.49637, 63.46666], [31.23244, 63.22239], [31.29294, 63.09035], [31.58535, 62.91642], [31.38369, 62.66284], [31.10136, 62.43042], [29.01829, 61.17448], [28.82816, 61.1233], [28.47974, 60.93365], [27.77352, 60.52722], [27.71177, 60.3893], [27.44953, 60.22766], [26.32936, 60.00121]]]] } },
23041 { type: "Feature", properties: { wikidata: "Q1083368", nameEn: "Mainland Finland", country: "FI", groups: ["EU", "154", "150", "UN"], callingCodes: ["358"] }, geometry: { type: "MultiPolygon", coordinates: [[[[29.12697, 69.69193], [28.36883, 69.81658], [28.32849, 69.88605], [27.97558, 69.99671], [27.95542, 70.0965], [27.57226, 70.06215], [27.05802, 69.92069], [26.64461, 69.96565], [26.40261, 69.91377], [25.96904, 69.68397], [25.69679, 69.27039], [25.75729, 68.99383], [25.61613, 68.89602], [25.42455, 68.90328], [25.12206, 68.78684], [25.10189, 68.63307], [24.93048, 68.61102], [24.90023, 68.55579], [24.74898, 68.65143], [24.18432, 68.73936], [24.02299, 68.81601], [23.781, 68.84514], [23.68017, 68.70276], [23.13064, 68.64684], [22.53321, 68.74393], [22.38367, 68.71561], [22.27276, 68.89514], [21.63833, 69.27485], [21.27827, 69.31281], [21.00732, 69.22755], [20.98641, 69.18809], [21.11099, 69.10291], [21.05775, 69.0356], [20.72171, 69.11874], [20.55258, 69.06069], [20.78802, 69.03087], [20.91658, 68.96764], [20.85104, 68.93142], [20.90649, 68.89696], [21.03001, 68.88969], [22.00429, 68.50692], [22.73028, 68.40881], [23.10336, 68.26551], [23.15377, 68.14759], [23.26469, 68.15134], [23.40081, 68.05545], [23.65793, 67.9497], [23.45627, 67.85297], [23.54701, 67.59306], [23.39577, 67.46974], [23.75372, 67.43688], [23.75372, 67.29914], [23.54701, 67.25435], [23.58735, 67.20752], [23.56214, 67.17038], [23.98563, 66.84149], [23.98059, 66.79585], [23.89488, 66.772], [23.85959, 66.56434], [23.63776, 66.43568], [23.67591, 66.3862], [23.64982, 66.30603], [23.71339, 66.21299], [23.90497, 66.15802], [24.15791, 65.85385], [24.14798, 65.83466], [24.15107, 65.81427], [24.14112, 65.39731], [20.15877, 63.06556], [19.23413, 60.61414], [20.96741, 60.71528], [21.15143, 60.54555], [21.08159, 60.20167], [21.02509, 60.12142], [21.35468, 59.67511], [20.5104, 59.15546], [26.32936, 60.00121], [27.44953, 60.22766], [27.71177, 60.3893], [27.77352, 60.52722], [28.47974, 60.93365], [28.82816, 61.1233], [29.01829, 61.17448], [31.10136, 62.43042], [31.38369, 62.66284], [31.58535, 62.91642], [31.29294, 63.09035], [31.23244, 63.22239], [30.49637, 63.46666], [29.98213, 63.75795], [30.25437, 63.83364], [30.55687, 64.09036], [30.4762, 64.25728], [30.06279, 64.35782], [30.01238, 64.57513], [30.12329, 64.64862], [30.05271, 64.79072], [29.68972, 64.80789], [29.61914, 65.05993], [29.84096, 65.1109], [29.8813, 65.22101], [29.61914, 65.23791], [29.68972, 65.31803], [29.84096, 65.56945], [29.74013, 65.64025], [29.97205, 65.70256], [30.16363, 65.66935], [29.91155, 66.13863], [28.9839, 66.94139], [29.91155, 67.51507], [30.02041, 67.67523], [29.66955, 67.79872], [29.34179, 68.06655], [28.62982, 68.19816], [28.43941, 68.53366], [28.78224, 68.86696], [28.45957, 68.91417], [28.91738, 69.04774], [28.81248, 69.11997], [28.8629, 69.22395], [29.31664, 69.47994], [29.12697, 69.69193]]]] } },
23042 { type: "Feature", properties: { wikidata: "Q1184963", nameEn: "Alhucemas Islands", country: "ES", groups: ["EU", "Q191011", "015", "002", "UN"], level: "subterritory" }, geometry: { type: "MultiPolygon", coordinates: [[[[-3.90602, 35.21494], [-3.88372, 35.20767], [-3.89343, 35.22728], [-3.90602, 35.21494]]]] } },
23043 { type: "Feature", properties: { wikidata: "Q1298289", nameEn: "Egmont Islands", country: "GB", groups: ["IO", "BOTS", "014", "202", "002", "UN"], level: "subterritory" }, geometry: { type: "MultiPolygon", coordinates: [[[[70.1848, -6.37445], [70.67958, -8.2663], [72.17991, -6.68509], [70.1848, -6.37445]]]] } },
23044 { type: "Feature", properties: { wikidata: "Q1352230", nameEn: "US Territories", country: "US", level: "subcountryGroup" }, geometry: null },
23045 { type: "Feature", properties: { wikidata: "Q1451600", nameEn: "Overseas Countries and Territories of the EU", aliases: ["OCT"], level: "subunion" }, geometry: null },
23046 { type: "Feature", properties: { wikidata: "Q1544253", nameEn: "Great Chagos Bank", country: "GB", groups: ["IO", "BOTS", "014", "202", "002", "UN"], level: "subterritory" }, geometry: { type: "MultiPolygon", coordinates: [[[[70.1848, -6.37445], [72.17991, -6.68509], [73.20573, -5.20727], [70.1848, -6.37445]]]] } },
23047 { type: "Feature", properties: { wikidata: "Q1585511", nameEn: "Salomon Atoll", country: "GB", groups: ["IO", "BOTS", "014", "202", "002", "UN"], level: "subterritory" }, geometry: { type: "MultiPolygon", coordinates: [[[[72.09518, -5.61768], [73.20573, -5.20727], [72.12587, -4.02588], [72.09518, -5.61768]]]] } },
23048 { type: "Feature", properties: { wikidata: "Q1681727", nameEn: "Saint-Paul and Amsterdam", country: "FR", groups: ["EU", "TF", "Q1451600", "014", "202", "002", "UN"], level: "subterritory" }, geometry: { type: "MultiPolygon", coordinates: [[[[76.31747, -42.16264], [80.15867, -36.04977], [71.22311, -38.75287], [76.31747, -42.16264]]]] } },
23049 { type: "Feature", properties: { wikidata: "Q1901211", nameEn: "East Malaysia", country: "MY", groups: ["Q36117", "035", "142", "UN"], driveSide: "left", callingCodes: ["60"] }, geometry: { type: "MultiPolygon", coordinates: [[[[110.90339, 7.52694], [109.82788, 2.86812], [109.62558, 1.99182], [109.53794, 1.91771], [109.57923, 1.80624], [109.66397, 1.79972], [109.66397, 1.60425], [110.35354, 0.98869], [110.49182, 0.88088], [110.62374, 0.873], [111.22979, 1.08326], [111.55434, 0.97864], [111.82846, 0.99349], [111.94553, 1.12016], [112.15679, 1.17004], [112.2127, 1.44135], [112.48648, 1.56516], [113.021, 1.57819], [113.01448, 1.42832], [113.64677, 1.23933], [114.03788, 1.44787], [114.57892, 1.5], [114.80706, 1.92351], [114.80706, 2.21665], [115.1721, 2.49671], [115.11343, 2.82879], [115.53713, 3.14776], [115.58276, 3.93499], [115.90217, 4.37708], [117.25801, 4.35108], [117.47313, 4.18857], [117.67641, 4.16535], [118.06469, 4.16638], [118.93936, 4.09009], [119.52945, 5.35672], [117.98544, 6.27477], [117.93857, 6.89845], [117.17735, 7.52841], [116.79524, 7.43869], [115.02521, 5.35005], [115.16236, 5.01011], [115.15092, 4.87604], [115.20737, 4.8256], [115.27819, 4.63661], [115.2851, 4.42295], [115.36346, 4.33563], [115.31275, 4.30806], [115.09978, 4.39123], [115.07737, 4.53418], [115.04064, 4.63706], [115.02278, 4.74137], [115.02955, 4.82087], [115.05038, 4.90275], [114.99417, 4.88201], [114.96982, 4.81146], [114.88841, 4.81905], [114.8266, 4.75062], [114.77303, 4.72871], [114.83189, 4.42387], [114.88039, 4.4257], [114.78539, 4.12205], [114.64211, 4.00694], [114.49922, 4.13108], [114.4416, 4.27588], [114.32176, 4.2552], [114.32176, 4.34942], [114.26876, 4.49878], [114.15813, 4.57], [114.07448, 4.58441], [114.10166, 4.76112], [110.90339, 7.52694]]]] } },
23050 { type: "Feature", properties: { wikidata: "Q1973345", nameEn: "Peninsular Malaysia", country: "MY", groups: ["035", "142", "UN"], driveSide: "left", callingCodes: ["60"] }, geometry: { type: "MultiPolygon", coordinates: [[[[102.46318, 7.22462], [102.09086, 6.23546], [102.08127, 6.22679], [102.07732, 6.193], [102.09182, 6.14161], [102.01835, 6.05407], [101.99209, 6.04075], [101.97114, 6.01992], [101.9714, 6.00575], [101.94712, 5.98421], [101.92819, 5.85511], [101.91776, 5.84269], [101.89188, 5.8386], [101.80144, 5.74505], [101.75074, 5.79091], [101.69773, 5.75881], [101.58019, 5.93534], [101.25524, 5.78633], [101.25755, 5.71065], [101.14062, 5.61613], [100.98815, 5.79464], [101.02708, 5.91013], [101.087, 5.9193], [101.12388, 6.11411], [101.06165, 6.14161], [101.12618, 6.19431], [101.10313, 6.25617], [100.85884, 6.24929], [100.81045, 6.45086], [100.74822, 6.46231], [100.74361, 6.50811], [100.66986, 6.45086], [100.43027, 6.52389], [100.42351, 6.51762], [100.41791, 6.5189], [100.41152, 6.52299], [100.35413, 6.54932], [100.31929, 6.65413], [100.32607, 6.65933], [100.32671, 6.66526], [100.31884, 6.66423], [100.31618, 6.66781], [100.30828, 6.66462], [100.29651, 6.68439], [100.19511, 6.72559], [100.12, 6.42105], [100.0756, 6.4045], [99.91873, 6.50233], [99.50117, 6.44501], [99.31854, 5.99868], [99.75778, 3.86466], [103.03657, 1.30383], [103.56591, 1.19719], [103.62738, 1.35255], [103.67468, 1.43166], [103.7219, 1.46108], [103.74161, 1.4502], [103.76395, 1.45183], [103.81181, 1.47953], [103.86383, 1.46288], [103.89565, 1.42841], [103.93384, 1.42926], [104.00131, 1.42405], [104.02277, 1.4438], [104.04622, 1.44691], [104.07348, 1.43322], [104.08871, 1.42015], [104.09162, 1.39694], [104.08072, 1.35998], [104.12282, 1.27714], [104.34728, 1.33529], [104.56723, 1.44271], [105.01437, 3.24936], [102.46318, 7.22462]]]] } },
23051 { type: "Feature", properties: { wikidata: "Q2093907", nameEn: "Three Kings Islands", country: "NZ", groups: ["Q851132", "053", "009", "UN"], driveSide: "left" }, geometry: { type: "MultiPolygon", coordinates: [[[[174.17679, -32.62487], [170.93268, -32.97889], [171.97383, -34.64644], [174.17679, -32.62487]]]] } },
23052 { type: "Feature", properties: { wikidata: "Q2298216", nameEn: "Solander Islands", country: "NZ", groups: ["Q851132", "053", "009", "UN"], driveSide: "left" }, geometry: { type: "MultiPolygon", coordinates: [[[[167.39068, -46.49187], [166.5534, -46.39484], [166.84561, -46.84889], [167.39068, -46.49187]]]] } },
23053 { type: "Feature", properties: { wikidata: "Q2872203", nameEn: "Mainland Australia", country: "AU", groups: ["053", "009", "UN"], level: "subcountryGroup", driveSide: "left", callingCodes: ["61"] }, geometry: { type: "MultiPolygon", coordinates: [[[[88.16419, -23.49578], [123.64533, -39.13605], [159.74028, -39.1978], [159.76765, -29.76946], [154.02855, -24.43238], [152.93188, -20.92631], [147.69992, -17.5933], [145.2855, -9.62524], [143.87386, -9.02382], [143.29772, -9.33993], [142.48658, -9.36754], [142.19246, -9.15378], [141.88934, -9.36111], [141.01842, -9.35091], [135.49042, -9.2276], [127.55165, -9.05052], [125.29076, -12.33139], [88.16419, -23.49578]]]] } },
23054 { type: "Feature", properties: { wikidata: "Q2914565", nameEn: "Autonomous Regions of Portugal", country: "PT", level: "subcountryGroup" }, geometry: null },
23055 { type: "Feature", properties: { wikidata: "Q2915956", nameEn: "Mainland Portugal", country: "PT", groups: ["Q12837", "EU", "039", "150", "UN"], level: "subcountryGroup", callingCodes: ["351"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-10.39881, 36.12218], [-7.37282, 36.96896], [-7.39769, 37.16868], [-7.41133, 37.20314], [-7.41854, 37.23813], [-7.43227, 37.25152], [-7.43974, 37.38913], [-7.46878, 37.47127], [-7.51759, 37.56119], [-7.41981, 37.75729], [-7.33441, 37.81193], [-7.27314, 37.90145], [-7.24544, 37.98884], [-7.12648, 38.00296], [-7.10366, 38.04404], [-7.05966, 38.01966], [-7.00375, 38.01914], [-6.93418, 38.21454], [-7.09389, 38.17227], [-7.15581, 38.27597], [-7.32529, 38.44336], [-7.265, 38.61674], [-7.26174, 38.72107], [-7.03848, 38.87221], [-7.051, 38.907], [-6.95211, 39.0243], [-6.97004, 39.07619], [-7.04011, 39.11919], [-7.10692, 39.10275], [-7.14929, 39.11287], [-7.12811, 39.17101], [-7.23566, 39.20132], [-7.23403, 39.27579], [-7.3149, 39.34857], [-7.2927, 39.45847], [-7.49477, 39.58794], [-7.54121, 39.66717], [-7.33507, 39.64569], [-7.24707, 39.66576], [-7.01613, 39.66877], [-6.97492, 39.81488], [-6.91463, 39.86618], [-6.86737, 40.01986], [-6.94233, 40.10716], [-7.00589, 40.12087], [-7.02544, 40.18564], [-7.00426, 40.23169], [-6.86085, 40.26776], [-6.86085, 40.2976], [-6.80218, 40.33239], [-6.78426, 40.36468], [-6.84618, 40.42177], [-6.84944, 40.46394], [-6.7973, 40.51723], [-6.80218, 40.55067], [-6.84292, 40.56801], [-6.79567, 40.65955], [-6.82826, 40.74603], [-6.82337, 40.84472], [-6.79892, 40.84842], [-6.80707, 40.88047], [-6.84292, 40.89771], [-6.8527, 40.93958], [-6.9357, 41.02888], [-6.913, 41.03922], [-6.88843, 41.03027], [-6.84781, 41.02692], [-6.80942, 41.03629], [-6.79241, 41.05397], [-6.75655, 41.10187], [-6.77319, 41.13049], [-6.69711, 41.1858], [-6.68286, 41.21641], [-6.65046, 41.24725], [-6.55937, 41.24417], [-6.38551, 41.35274], [-6.38553, 41.38655], [-6.3306, 41.37677], [-6.26777, 41.48796], [-6.19128, 41.57638], [-6.29863, 41.66432], [-6.44204, 41.68258], [-6.49907, 41.65823], [-6.54633, 41.68623], [-6.56426, 41.74219], [-6.51374, 41.8758], [-6.56752, 41.88429], [-6.5447, 41.94371], [-6.58544, 41.96674], [-6.61967, 41.94008], [-6.75004, 41.94129], [-6.76959, 41.98734], [-6.81196, 41.99097], [-6.82174, 41.94493], [-6.94396, 41.94403], [-6.95537, 41.96553], [-6.98144, 41.9728], [-7.01078, 41.94977], [-7.07596, 41.94977], [-7.08574, 41.97401], [-7.14115, 41.98855], [-7.18549, 41.97515], [-7.18677, 41.88793], [-7.32366, 41.8406], [-7.37092, 41.85031], [-7.42864, 41.80589], [-7.42854, 41.83262], [-7.44759, 41.84451], [-7.45566, 41.86488], [-7.49803, 41.87095], [-7.52737, 41.83939], [-7.62188, 41.83089], [-7.58603, 41.87944], [-7.65774, 41.88308], [-7.69848, 41.90977], [-7.84188, 41.88065], [-7.88055, 41.84571], [-7.88751, 41.92553], [-7.90707, 41.92432], [-7.92336, 41.8758], [-7.9804, 41.87337], [-8.01136, 41.83453], [-8.0961, 41.81024], [-8.16455, 41.81753], [-8.16944, 41.87944], [-8.19551, 41.87459], [-8.2185, 41.91237], [-8.16232, 41.9828], [-8.08796, 42.01398], [-8.08847, 42.05767], [-8.11729, 42.08537], [-8.18178, 42.06436], [-8.19406, 42.12141], [-8.18947, 42.13853], [-8.1986, 42.15402], [-8.22406, 42.1328], [-8.24681, 42.13993], [-8.2732, 42.12396], [-8.29809, 42.106], [-8.32161, 42.10218], [-8.33912, 42.08358], [-8.36353, 42.09065], [-8.38323, 42.07683], [-8.40143, 42.08052], [-8.42512, 42.07199], [-8.44123, 42.08218], [-8.48185, 42.0811], [-8.52837, 42.07658], [-8.5252, 42.06264], [-8.54563, 42.0537], [-8.58086, 42.05147], [-8.59493, 42.05708], [-8.63791, 42.04691], [-8.64626, 42.03668], [-8.65832, 42.02972], [-8.6681, 41.99703], [-8.69071, 41.98862], [-8.7478, 41.96282], [-8.74606, 41.9469], [-8.75712, 41.92833], [-8.81794, 41.90375], [-8.87157, 41.86488], [-11.19304, 41.83075], [-10.39881, 36.12218]]]] } },
23056 { type: "Feature", properties: { wikidata: "Q3311985", nameEn: "Guernsey", country: "GB", groups: ["GG", "830", "Q185086", "154", "150", "UN"], level: "subterritory", driveSide: "left", roadSpeedUnit: "mph", roadHeightUnit: "ft", callingCodes: ["44 01481"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-2.49556, 49.79012], [-3.28154, 49.57329], [-2.65349, 49.15373], [-2.36485, 49.48223], [-2.49556, 49.79012]]]] } },
23057 { type: "Feature", properties: { wikidata: "Q3320166", nameEn: "Outermost Regions of the EU", aliases: ["OMR"], level: "subunion" }, geometry: null },
23058 { type: "Feature", properties: { wikidata: "Q3336843", nameEn: "Countries of the United Kingdom", aliases: ["GB-UKM"], country: "GB", level: "subcountryGroup" }, geometry: null },
23059 { type: "Feature", properties: { wikidata: "Q6736667", nameEn: "Mainland India", country: "IN", groups: ["034", "142", "UN"], driveSide: "left", callingCodes: ["91"] }, geometry: { type: "MultiPolygon", coordinates: [[[[89.08044, 21.41871], [89.07114, 22.15335], [88.9367, 22.58527], [88.94614, 22.66941], [88.9151, 22.75228], [88.96713, 22.83346], [88.87063, 22.95235], [88.88327, 23.03885], [88.86377, 23.08759], [88.99148, 23.21134], [88.71133, 23.2492], [88.79254, 23.46028], [88.79351, 23.50535], [88.74841, 23.47361], [88.56507, 23.64044], [88.58087, 23.87105], [88.66189, 23.87607], [88.73743, 23.91751], [88.6976, 24.14703], [88.74841, 24.1959], [88.68801, 24.31464], [88.50934, 24.32474], [88.12296, 24.51301], [88.08786, 24.63232], [88.00683, 24.66477], [88.15515, 24.85806], [88.14004, 24.93529], [88.21832, 24.96642], [88.27325, 24.88796], [88.33917, 24.86803], [88.46277, 25.07468], [88.44766, 25.20149], [88.94067, 25.18534], [89.00463, 25.26583], [89.01105, 25.30303], [88.85278, 25.34679], [88.81296, 25.51546], [88.677, 25.46959], [88.4559, 25.59227], [88.45103, 25.66245], [88.242, 25.80811], [88.13138, 25.78773], [88.08804, 25.91334], [88.16581, 26.0238], [88.1844, 26.14417], [88.34757, 26.22216], [88.35153, 26.29123], [88.51649, 26.35923], [88.48749, 26.45855], [88.36938, 26.48683], [88.35153, 26.45241], [88.33093, 26.48929], [88.41196, 26.63837], [88.4298, 26.54489], [88.62144, 26.46783], [88.69485, 26.38353], [88.67837, 26.26291], [88.78961, 26.31093], [88.85004, 26.23211], [89.05328, 26.2469], [88.91321, 26.37984], [88.92357, 26.40711], [88.95612, 26.4564], [89.08899, 26.38845], [89.15869, 26.13708], [89.35953, 26.0077], [89.53515, 26.00382], [89.57101, 25.9682], [89.63968, 26.22595], [89.70201, 26.15138], [89.73581, 26.15818], [89.77865, 26.08387], [89.77728, 26.04254], [89.86592, 25.93115], [89.80585, 25.82489], [89.84388, 25.70042], [89.86129, 25.61714], [89.81208, 25.37244], [89.84086, 25.31854], [89.83371, 25.29548], [89.87629, 25.28337], [89.90478, 25.31038], [90.1155, 25.22686], [90.40034, 25.1534], [90.65042, 25.17788], [90.87427, 25.15799], [91.25517, 25.20677], [91.63648, 25.12846], [92.0316, 25.1834], [92.33957, 25.07593], [92.39147, 25.01471], [92.49887, 24.88796], [92.38626, 24.86055], [92.25854, 24.9191], [92.15796, 24.54435], [92.11662, 24.38997], [91.96603, 24.3799], [91.89258, 24.14674], [91.82596, 24.22345], [91.76004, 24.23848], [91.73257, 24.14703], [91.65292, 24.22095], [91.63782, 24.1132], [91.55542, 24.08687], [91.37414, 24.10693], [91.35741, 23.99072], [91.29587, 24.0041], [91.22308, 23.89616], [91.25192, 23.83463], [91.15579, 23.6599], [91.28293, 23.37538], [91.36453, 23.06612], [91.40848, 23.07117], [91.4035, 23.27522], [91.46615, 23.2328], [91.54993, 23.01051], [91.61571, 22.93929], [91.7324, 23.00043], [91.81634, 23.08001], [91.76417, 23.26619], [91.84789, 23.42235], [91.95642, 23.47361], [91.95093, 23.73284], [92.04706, 23.64229], [92.15417, 23.73409], [92.26541, 23.70392], [92.38214, 23.28705], [92.37665, 22.9435], [92.5181, 22.71441], [92.60029, 22.1522], [92.56616, 22.13554], [92.60949, 21.97638], [92.67532, 22.03547], [92.70416, 22.16017], [92.86208, 22.05456], [92.89504, 21.95143], [92.93899, 22.02656], [92.99804, 21.98964], [92.99255, 22.05965], [93.04885, 22.20595], [93.15734, 22.18687], [93.14224, 22.24535], [93.19991, 22.25425], [93.18206, 22.43716], [93.13537, 22.45873], [93.11477, 22.54374], [93.134, 22.59573], [93.09417, 22.69459], [93.134, 22.92498], [93.12988, 23.05772], [93.2878, 23.00464], [93.38478, 23.13698], [93.36862, 23.35426], [93.38781, 23.36139], [93.39981, 23.38828], [93.38805, 23.4728], [93.43475, 23.68299], [93.3908, 23.7622], [93.3908, 23.92925], [93.36059, 23.93176], [93.32351, 24.04468], [93.34735, 24.10151], [93.41415, 24.07854], [93.46633, 23.97067], [93.50616, 23.94432], [93.62871, 24.00922], [93.75952, 24.0003], [93.80279, 23.92549], [93.92089, 23.95812], [94.14081, 23.83333], [94.30215, 24.23752], [94.32362, 24.27692], [94.45279, 24.56656], [94.50729, 24.59281], [94.5526, 24.70764], [94.60204, 24.70889], [94.73937, 25.00545], [94.74212, 25.13606], [94.57458, 25.20318], [94.68032, 25.47003], [94.80117, 25.49359], [95.18556, 26.07338], [95.11428, 26.1019], [95.12801, 26.38397], [95.05798, 26.45408], [95.23513, 26.68499], [95.30339, 26.65372], [95.437, 26.7083], [95.81603, 27.01335], [95.93002, 27.04149], [96.04949, 27.19428], [96.15591, 27.24572], [96.40779, 27.29818], [96.55761, 27.29928], [96.73888, 27.36638], [96.88445, 27.25046], [96.85287, 27.2065], [96.89132, 27.17474], [97.14675, 27.09041], [97.17422, 27.14052], [96.91431, 27.45752], [96.90112, 27.62149], [97.29919, 27.92233], [97.35824, 27.87256], [97.38845, 28.01329], [97.35412, 28.06663], [97.31292, 28.06784], [97.34547, 28.21385], [97.1289, 28.3619], [96.98882, 28.32564], [96.88445, 28.39452], [96.85561, 28.4875], [96.6455, 28.61657], [96.48895, 28.42955], [96.40929, 28.51526], [96.61391, 28.72742], [96.3626, 29.10607], [96.20467, 29.02325], [96.18682, 29.11087], [96.31316, 29.18643], [96.05361, 29.38167], [95.84899, 29.31464], [95.75149, 29.32063], [95.72086, 29.20797], [95.50842, 29.13487], [95.41091, 29.13007], [95.3038, 29.13847], [95.26122, 29.07727], [95.2214, 29.10727], [95.11291, 29.09527], [95.0978, 29.14446], [94.81353, 29.17804], [94.69318, 29.31739], [94.2752, 29.11687], [94.35897, 29.01965], [93.72797, 28.68821], [93.44621, 28.67189], [93.18069, 28.50319], [93.14635, 28.37035], [92.93075, 28.25671], [92.67486, 28.15018], [92.65472, 28.07632], [92.73025, 28.05814], [92.7275, 27.98662], [92.42538, 27.80092], [92.32101, 27.79363], [92.27432, 27.89077], [91.87057, 27.7195], [91.84722, 27.76325], [91.6469, 27.76358], [91.55819, 27.6144], [91.65007, 27.48287], [92.01132, 27.47352], [92.12019, 27.27829], [92.04702, 27.26861], [92.03457, 27.07334], [92.11863, 26.893], [92.05523, 26.8692], [91.83181, 26.87318], [91.50067, 26.79223], [90.67715, 26.77215], [90.48504, 26.8594], [90.39271, 26.90704], [90.30402, 26.85098], [90.04535, 26.72422], [89.86124, 26.73307], [89.63369, 26.74402], [89.42349, 26.83727], [89.3901, 26.84225], [89.38319, 26.85963], [89.37913, 26.86224], [89.1926, 26.81329], [89.12825, 26.81661], [89.09554, 26.89089], [88.95807, 26.92668], [88.92301, 26.99286], [88.8714, 26.97488], [88.86984, 27.10937], [88.74219, 27.144], [88.91901, 27.32483], [88.82981, 27.38814], [88.77517, 27.45415], [88.88091, 27.85192], [88.83559, 28.01936], [88.63235, 28.12356], [88.54858, 28.06057], [88.25332, 27.9478], [88.1278, 27.95417], [88.13378, 27.88015], [88.1973, 27.85067], [88.19107, 27.79285], [88.04008, 27.49223], [88.07277, 27.43007], [88.01646, 27.21612], [88.01587, 27.21388], [87.9887, 27.11045], [88.11719, 26.98758], [88.13422, 26.98705], [88.12302, 26.95324], [88.19107, 26.75516], [88.1659, 26.68177], [88.16452, 26.64111], [88.09963, 26.54195], [88.09414, 26.43732], [88.00895, 26.36029], [87.90115, 26.44923], [87.89085, 26.48565], [87.84193, 26.43663], [87.7918, 26.46737], [87.76004, 26.40711], [87.67893, 26.43501], [87.66803, 26.40294], [87.59175, 26.38342], [87.55274, 26.40596], [87.51571, 26.43106], [87.46566, 26.44058], [87.37314, 26.40815], [87.34568, 26.34787], [87.26568, 26.37294], [87.26587, 26.40592], [87.24682, 26.4143], [87.18863, 26.40558], [87.14751, 26.40542], [87.09147, 26.45039], [87.0707, 26.58571], [87.04691, 26.58685], [87.01559, 26.53228], [86.95912, 26.52076], [86.94543, 26.52076], [86.82898, 26.43919], [86.76797, 26.45892], [86.74025, 26.42386], [86.69124, 26.45169], [86.62686, 26.46891], [86.61313, 26.48658], [86.57073, 26.49825], [86.54258, 26.53819], [86.49726, 26.54218], [86.31564, 26.61925], [86.26235, 26.61886], [86.22513, 26.58863], [86.13596, 26.60651], [86.02729, 26.66756], [85.8492, 26.56667], [85.85126, 26.60866], [85.83126, 26.61134], [85.76907, 26.63076], [85.72315, 26.67471], [85.73483, 26.79613], [85.66239, 26.84822], [85.61621, 26.86721], [85.59461, 26.85161], [85.5757, 26.85955], [85.56471, 26.84133], [85.47752, 26.79292], [85.34302, 26.74954], [85.21159, 26.75933], [85.18046, 26.80519], [85.19291, 26.86909], [85.15883, 26.86966], [85.02635, 26.85381], [85.05592, 26.88991], [85.00536, 26.89523], [84.97186, 26.9149], [84.96687, 26.95599], [84.85754, 26.98984], [84.82913, 27.01989], [84.793, 26.9968], [84.64496, 27.04669], [84.69166, 27.21294], [84.62161, 27.33885], [84.29315, 27.39], [84.25735, 27.44941], [84.21376, 27.45218], [84.10791, 27.52399], [84.02229, 27.43836], [83.93306, 27.44939], [83.86182, 27.4241], [83.85595, 27.35797], [83.61288, 27.47013], [83.39495, 27.4798], [83.38872, 27.39276], [83.35136, 27.33885], [83.29999, 27.32778], [83.2673, 27.36235], [83.27197, 27.38309], [83.19413, 27.45632], [82.94938, 27.46036], [82.93261, 27.50328], [82.74119, 27.49838], [82.70378, 27.72122], [82.46405, 27.6716], [82.06554, 27.92222], [81.97214, 27.93322], [81.91223, 27.84995], [81.47867, 28.08303], [81.48179, 28.12148], [81.38683, 28.17638], [81.32923, 28.13521], [81.19847, 28.36284], [81.03471, 28.40054], [80.55142, 28.69182], [80.50575, 28.6706], [80.52443, 28.54897], [80.44504, 28.63098], [80.37188, 28.63371], [80.12125, 28.82346], [80.06957, 28.82763], [80.05743, 28.91479], [80.18085, 29.13649], [80.23178, 29.11626], [80.26602, 29.13938], [80.24112, 29.21414], [80.28626, 29.20327], [80.31428, 29.30784], [80.24322, 29.44299], [80.37939, 29.57098], [80.41858, 29.63581], [80.38428, 29.68513], [80.36803, 29.73865], [80.41554, 29.79451], [80.43458, 29.80466], [80.48997, 29.79566], [80.56247, 29.86661], [80.57179, 29.91422], [80.60226, 29.95732], [80.67076, 29.95732], [80.8778, 30.13384], [80.86673, 30.17321], [80.91143, 30.22173], [80.92547, 30.17193], [81.03953, 30.20059], [80.83343, 30.32023], [80.54504, 30.44936], [80.20721, 30.58541], [79.93255, 30.88288], [79.59884, 30.93943], [79.30694, 31.17357], [79.14016, 31.43403], [79.01931, 31.42817], [78.89344, 31.30481], [78.77898, 31.31209], [78.71032, 31.50197], [78.84516, 31.60631], [78.69933, 31.78723], [78.78036, 31.99478], [78.74404, 32.00384], [78.68754, 32.10256], [78.49609, 32.2762], [78.4645, 32.45367], [78.38897, 32.53938], [78.73916, 32.69438], [78.7831, 32.46873], [78.96713, 32.33655], [78.99322, 32.37948], [79.0979, 32.38051], [79.13174, 32.47766], [79.26768, 32.53277], [79.46562, 32.69668], [79.14016, 33.02545], [79.15252, 33.17156], [78.73636, 33.56521], [78.67599, 33.66445], [78.77349, 33.73871], [78.73367, 34.01121], [78.65657, 34.03195], [78.66225, 34.08858], [78.91769, 34.15452], [78.99802, 34.3027], [79.05364, 34.32482], [78.74465, 34.45174], [78.56475, 34.50835], [78.54964, 34.57283], [78.27781, 34.61484], [78.18435, 34.7998], [78.22692, 34.88771], [78.00033, 35.23954], [78.03466, 35.3785], [78.11664, 35.48022], [77.80532, 35.52058], [77.70232, 35.46244], [77.44277, 35.46132], [76.96624, 35.5932], [76.84539, 35.67356], [76.77323, 35.66062], [76.75475, 35.52617], [76.85088, 35.39754], [76.93465, 35.39866], [77.11796, 35.05419], [76.99251, 34.93349], [76.87193, 34.96906], [76.74514, 34.92488], [76.74377, 34.84039], [76.67648, 34.76371], [76.47186, 34.78965], [76.15463, 34.6429], [76.04614, 34.67566], [75.75438, 34.51827], [75.38009, 34.55021], [75.01479, 34.64629], [74.6663, 34.703], [74.58083, 34.77386], [74.31239, 34.79626], [74.12897, 34.70073], [73.96423, 34.68244], [73.93401, 34.63386], [73.93951, 34.57169], [73.89419, 34.54568], [73.88732, 34.48911], [73.74999, 34.3781], [73.74862, 34.34183], [73.8475, 34.32935], [73.90517, 34.35317], [73.98208, 34.2522], [73.90677, 34.10504], [73.88732, 34.05105], [73.91341, 34.01235], [74.21554, 34.03853], [74.25262, 34.01577], [74.26086, 33.92237], [74.14001, 33.83002], [74.05898, 33.82089], [74.00891, 33.75437], [73.96423, 33.73071], [73.98968, 33.66155], [73.97367, 33.64061], [74.03576, 33.56718], [74.10115, 33.56392], [74.18121, 33.4745], [74.17983, 33.3679], [74.08782, 33.26232], [74.01366, 33.25199], [74.02144, 33.18908], [74.15374, 33.13477], [74.17571, 33.07495], [74.31854, 33.02891], [74.34875, 32.97823], [74.31227, 32.92795], [74.41467, 32.90563], [74.45312, 32.77755], [74.6289, 32.75561], [74.64675, 32.82604], [74.7113, 32.84219], [74.65345, 32.71225], [74.69542, 32.66792], [74.64424, 32.60985], [74.65251, 32.56416], [74.67431, 32.56676], [74.68362, 32.49298], [74.84725, 32.49075], [74.97634, 32.45367], [75.03265, 32.49538], [75.28259, 32.36556], [75.38046, 32.26836], [75.25649, 32.10187], [75.00793, 32.03786], [74.9269, 32.0658], [74.86236, 32.04485], [74.79919, 31.95983], [74.58907, 31.87824], [74.47771, 31.72227], [74.57498, 31.60382], [74.61517, 31.55698], [74.59319, 31.50197], [74.64713, 31.45605], [74.59773, 31.4136], [74.53223, 31.30321], [74.51629, 31.13829], [74.56023, 31.08303], [74.60281, 31.10419], [74.60006, 31.13711], [74.6852, 31.12771], [74.67971, 31.05479], [74.5616, 31.04153], [73.88993, 30.36305], [73.95736, 30.28466], [73.97225, 30.19829], [73.80299, 30.06969], [73.58665, 30.01848], [73.3962, 29.94707], [73.28094, 29.56646], [73.05886, 29.1878], [73.01337, 29.16422], [72.94272, 29.02487], [72.40402, 28.78283], [72.29495, 28.66367], [72.20329, 28.3869], [71.9244, 28.11555], [71.89921, 27.96035], [70.79054, 27.68423], [70.60927, 28.02178], [70.37307, 28.01208], [70.12502, 27.8057], [70.03136, 27.56627], [69.58519, 27.18109], [69.50904, 26.74892], [69.88555, 26.56836], [70.05584, 26.60398], [70.17532, 26.55362], [70.17532, 26.24118], [70.08193, 26.08094], [70.0985, 25.93238], [70.2687, 25.71156], [70.37444, 25.67443], [70.53649, 25.68928], [70.60378, 25.71898], [70.67382, 25.68186], [70.66695, 25.39314], [70.89148, 25.15064], [70.94002, 24.92843], [71.09405, 24.69017], [70.97594, 24.60904], [71.00341, 24.46038], [71.12838, 24.42662], [71.04461, 24.34657], [70.94985, 24.3791], [70.85784, 24.30903], [70.88393, 24.27398], [70.71502, 24.23517], [70.57906, 24.27774], [70.5667, 24.43787], [70.11712, 24.30915], [70.03428, 24.172], [69.73335, 24.17007], [69.59579, 24.29777], [69.29778, 24.28712], [69.19341, 24.25646], [69.07806, 24.29777], [68.97781, 24.26021], [68.90914, 24.33156], [68.7416, 24.31904], [68.74643, 23.97027], [68.39339, 23.96838], [68.20763, 23.85849], [68.11329, 23.53945], [76.59015, 5.591], [79.50447, 8.91876], [79.42124, 9.80115], [80.48418, 10.20786], [89.08044, 21.41871]]]] } },
23060 { type: "Feature", properties: { wikidata: "Q9143535", nameEn: "Akrotiri", country: "GB", groups: ["Q644636", "Q37362", "BOTS", "145", "142", "UN"], level: "subterritory", driveSide: "left", callingCodes: ["357"] }, geometry: { type: "MultiPolygon", coordinates: [[[[32.86014, 34.70585], [32.82717, 34.70622], [32.79433, 34.67883], [32.76136, 34.68318], [32.75515, 34.64985], [32.74412, 34.43926], [33.26744, 34.49942], [33.0138, 34.64424], [32.96968, 34.64046], [32.96718, 34.63446], [32.95891, 34.62919], [32.95323, 34.64075], [32.95471, 34.64528], [32.94976, 34.65204], [32.94796, 34.6587], [32.95325, 34.66462], [32.97079, 34.66112], [32.97736, 34.65277], [32.99014, 34.65518], [32.98668, 34.67268], [32.99135, 34.68061], [32.95539, 34.68471], [32.94683, 34.67907], [32.94379, 34.67111], [32.93693, 34.67027], [32.93449, 34.66241], [32.92807, 34.66736], [32.93043, 34.67091], [32.91398, 34.67343], [32.9068, 34.66102], [32.86167, 34.68734], [32.86014, 34.70585]]]] } },
23061 { type: "Feature", properties: { wikidata: "Q9206745", nameEn: "Dhekelia", country: "GB", groups: ["Q644636", "Q37362", "BOTS", "145", "142", "UN"], level: "subterritory", driveSide: "left", callingCodes: ["357"] }, geometry: { type: "MultiPolygon", coordinates: [[[[33.70575, 34.97947], [33.83531, 34.73974], [33.98684, 34.76642], [33.90075, 34.96623], [33.86432, 34.97592], [33.84811, 34.97075], [33.83505, 34.98108], [33.85621, 34.98956], [33.85891, 35.001], [33.85216, 35.00579], [33.84045, 35.00616], [33.82875, 35.01685], [33.83055, 35.02865], [33.81524, 35.04192], [33.8012, 35.04786], [33.82051, 35.0667], [33.8355, 35.05777], [33.85261, 35.0574], [33.88367, 35.07877], [33.89485, 35.06873], [33.90247, 35.07686], [33.91299, 35.07579], [33.91789, 35.08688], [33.89853, 35.11377], [33.88737, 35.11408], [33.88943, 35.12007], [33.88561, 35.12449], [33.87224, 35.12293], [33.87622, 35.10457], [33.87097, 35.09389], [33.87479, 35.08881], [33.8541, 35.07201], [33.84168, 35.06823], [33.82067, 35.07826], [33.78581, 35.05104], [33.76106, 35.04253], [33.73824, 35.05321], [33.71482, 35.03722], [33.70209, 35.04882], [33.7161, 35.07279], [33.70861, 35.07644], [33.69095, 35.06237], [33.68474, 35.06602], [33.67742, 35.05963], [33.67678, 35.03866], [33.69938, 35.03123], [33.69731, 35.01754], [33.71514, 35.00294], [33.70639, 34.99303], [33.70575, 34.97947]], [[33.77312, 34.9976], [33.77553, 34.99518], [33.78516, 34.99582], [33.79191, 34.98914], [33.78917, 34.98854], [33.78571, 34.98951], [33.78318, 34.98699], [33.78149, 34.98854], [33.77843, 34.988], [33.7778, 34.98981], [33.76738, 34.99188], [33.76605, 34.99543], [33.75682, 34.99916], [33.75994, 35.00113], [33.77312, 34.9976]], [[33.74144, 35.01053], [33.7343, 35.01178], [33.73781, 35.02181], [33.74265, 35.02329], [33.74983, 35.02274], [33.7492, 35.01319], [33.74144, 35.01053]]]] } },
23062 { type: "Feature", properties: { wikidata: "Q16390686", nameEn: "Peninsular Spain", country: "ES", groups: ["Q12837", "EU", "039", "150", "UN"], callingCodes: ["34"] }, geometry: { type: "MultiPolygon", coordinates: [[[[3.75438, 42.33445], [3.17156, 42.43545], [3.11379, 42.43646], [3.10027, 42.42621], [3.08167, 42.42748], [3.03734, 42.47363], [2.96518, 42.46692], [2.94283, 42.48174], [2.92107, 42.4573], [2.88413, 42.45938], [2.86983, 42.46843], [2.85675, 42.45444], [2.84335, 42.45724], [2.77464, 42.41046], [2.75497, 42.42578], [2.72056, 42.42298], [2.65311, 42.38771], [2.6747, 42.33974], [2.57934, 42.35808], [2.55516, 42.35351], [2.54382, 42.33406], [2.48457, 42.33933], [2.43508, 42.37568], [2.43299, 42.39423], [2.38504, 42.39977], [2.25551, 42.43757], [2.20578, 42.41633], [2.16599, 42.42314], [2.12789, 42.41291], [2.11621, 42.38393], [2.06241, 42.35906], [2.00488, 42.35399], [1.96482, 42.37787], [1.9574, 42.42401], [1.94084, 42.43039], [1.94061, 42.43333], [1.94292, 42.44316], [1.93663, 42.45439], [1.88853, 42.4501], [1.83037, 42.48395], [1.76335, 42.48863], [1.72515, 42.50338], [1.70571, 42.48867], [1.66826, 42.50779], [1.65674, 42.47125], [1.58933, 42.46275], [1.57953, 42.44957], [1.55937, 42.45808], [1.55073, 42.43299], [1.5127, 42.42959], [1.44529, 42.43724], [1.43838, 42.47848], [1.41648, 42.48315], [1.46661, 42.50949], [1.44759, 42.54431], [1.41245, 42.53539], [1.4234, 42.55959], [1.44529, 42.56722], [1.42512, 42.58292], [1.44197, 42.60217], [1.35562, 42.71944], [1.15928, 42.71407], [1.0804, 42.78569], [0.98292, 42.78754], [0.96166, 42.80629], [0.93089, 42.79154], [0.711, 42.86372], [0.66121, 42.84021], [0.65421, 42.75872], [0.67873, 42.69458], [0.40214, 42.69779], [0.36251, 42.72282], [0.29407, 42.67431], [0.25336, 42.7174], [0.17569, 42.73424], [-0.02468, 42.68513], [-0.10519, 42.72761], [-0.16141, 42.79535], [-0.17939, 42.78974], [-0.3122, 42.84788], [-0.38833, 42.80132], [-0.41319, 42.80776], [-0.44334, 42.79939], [-0.50863, 42.82713], [-0.55497, 42.77846], [-0.67637, 42.88303], [-0.69837, 42.87945], [-0.72608, 42.89318], [-0.73422, 42.91228], [-0.72037, 42.92541], [-0.75478, 42.96916], [-0.81652, 42.95166], [-0.97133, 42.96239], [-1.00963, 42.99279], [-1.10333, 43.0059], [-1.22881, 43.05534], [-1.25244, 43.04164], [-1.30531, 43.06859], [-1.30052, 43.09581], [-1.27118, 43.11961], [-1.32209, 43.1127], [-1.34419, 43.09665], [-1.35272, 43.02658], [-1.44067, 43.047], [-1.47555, 43.08372], [-1.41562, 43.12815], [-1.3758, 43.24511], [-1.40942, 43.27272], [-1.45289, 43.27049], [-1.50992, 43.29481], [-1.55963, 43.28828], [-1.57674, 43.25269], [-1.61341, 43.25269], [-1.63052, 43.28591], [-1.62481, 43.30726], [-1.69407, 43.31378], [-1.73074, 43.29481], [-1.7397, 43.32979], [-1.75079, 43.3317], [-1.75334, 43.34107], [-1.77068, 43.34396], [-1.78714, 43.35476], [-1.78332, 43.36399], [-1.79319, 43.37497], [-1.77289, 43.38957], [-1.81005, 43.59738], [-10.14298, 44.17365], [-11.19304, 41.83075], [-8.87157, 41.86488], [-8.81794, 41.90375], [-8.75712, 41.92833], [-8.74606, 41.9469], [-8.7478, 41.96282], [-8.69071, 41.98862], [-8.6681, 41.99703], [-8.65832, 42.02972], [-8.64626, 42.03668], [-8.63791, 42.04691], [-8.59493, 42.05708], [-8.58086, 42.05147], [-8.54563, 42.0537], [-8.5252, 42.06264], [-8.52837, 42.07658], [-8.48185, 42.0811], [-8.44123, 42.08218], [-8.42512, 42.07199], [-8.40143, 42.08052], [-8.38323, 42.07683], [-8.36353, 42.09065], [-8.33912, 42.08358], [-8.32161, 42.10218], [-8.29809, 42.106], [-8.2732, 42.12396], [-8.24681, 42.13993], [-8.22406, 42.1328], [-8.1986, 42.15402], [-8.18947, 42.13853], [-8.19406, 42.12141], [-8.18178, 42.06436], [-8.11729, 42.08537], [-8.08847, 42.05767], [-8.08796, 42.01398], [-8.16232, 41.9828], [-8.2185, 41.91237], [-8.19551, 41.87459], [-8.16944, 41.87944], [-8.16455, 41.81753], [-8.0961, 41.81024], [-8.01136, 41.83453], [-7.9804, 41.87337], [-7.92336, 41.8758], [-7.90707, 41.92432], [-7.88751, 41.92553], [-7.88055, 41.84571], [-7.84188, 41.88065], [-7.69848, 41.90977], [-7.65774, 41.88308], [-7.58603, 41.87944], [-7.62188, 41.83089], [-7.52737, 41.83939], [-7.49803, 41.87095], [-7.45566, 41.86488], [-7.44759, 41.84451], [-7.42854, 41.83262], [-7.42864, 41.80589], [-7.37092, 41.85031], [-7.32366, 41.8406], [-7.18677, 41.88793], [-7.18549, 41.97515], [-7.14115, 41.98855], [-7.08574, 41.97401], [-7.07596, 41.94977], [-7.01078, 41.94977], [-6.98144, 41.9728], [-6.95537, 41.96553], [-6.94396, 41.94403], [-6.82174, 41.94493], [-6.81196, 41.99097], [-6.76959, 41.98734], [-6.75004, 41.94129], [-6.61967, 41.94008], [-6.58544, 41.96674], [-6.5447, 41.94371], [-6.56752, 41.88429], [-6.51374, 41.8758], [-6.56426, 41.74219], [-6.54633, 41.68623], [-6.49907, 41.65823], [-6.44204, 41.68258], [-6.29863, 41.66432], [-6.19128, 41.57638], [-6.26777, 41.48796], [-6.3306, 41.37677], [-6.38553, 41.38655], [-6.38551, 41.35274], [-6.55937, 41.24417], [-6.65046, 41.24725], [-6.68286, 41.21641], [-6.69711, 41.1858], [-6.77319, 41.13049], [-6.75655, 41.10187], [-6.79241, 41.05397], [-6.80942, 41.03629], [-6.84781, 41.02692], [-6.88843, 41.03027], [-6.913, 41.03922], [-6.9357, 41.02888], [-6.8527, 40.93958], [-6.84292, 40.89771], [-6.80707, 40.88047], [-6.79892, 40.84842], [-6.82337, 40.84472], [-6.82826, 40.74603], [-6.79567, 40.65955], [-6.84292, 40.56801], [-6.80218, 40.55067], [-6.7973, 40.51723], [-6.84944, 40.46394], [-6.84618, 40.42177], [-6.78426, 40.36468], [-6.80218, 40.33239], [-6.86085, 40.2976], [-6.86085, 40.26776], [-7.00426, 40.23169], [-7.02544, 40.18564], [-7.00589, 40.12087], [-6.94233, 40.10716], [-6.86737, 40.01986], [-6.91463, 39.86618], [-6.97492, 39.81488], [-7.01613, 39.66877], [-7.24707, 39.66576], [-7.33507, 39.64569], [-7.54121, 39.66717], [-7.49477, 39.58794], [-7.2927, 39.45847], [-7.3149, 39.34857], [-7.23403, 39.27579], [-7.23566, 39.20132], [-7.12811, 39.17101], [-7.14929, 39.11287], [-7.10692, 39.10275], [-7.04011, 39.11919], [-6.97004, 39.07619], [-6.95211, 39.0243], [-7.051, 38.907], [-7.03848, 38.87221], [-7.26174, 38.72107], [-7.265, 38.61674], [-7.32529, 38.44336], [-7.15581, 38.27597], [-7.09389, 38.17227], [-6.93418, 38.21454], [-7.00375, 38.01914], [-7.05966, 38.01966], [-7.10366, 38.04404], [-7.12648, 38.00296], [-7.24544, 37.98884], [-7.27314, 37.90145], [-7.33441, 37.81193], [-7.41981, 37.75729], [-7.51759, 37.56119], [-7.46878, 37.47127], [-7.43974, 37.38913], [-7.43227, 37.25152], [-7.41854, 37.23813], [-7.41133, 37.20314], [-7.39769, 37.16868], [-7.37282, 36.96896], [-7.2725, 35.73269], [-5.10878, 36.05227], [-2.27707, 35.35051], [3.75438, 42.33445]], [[-5.27801, 36.14942], [-5.34064, 36.03744], [-5.40526, 36.15488], [-5.34536, 36.15501], [-5.33822, 36.15272], [-5.27801, 36.14942]]], [[[1.99838, 42.44682], [2.01564, 42.45171], [1.99216, 42.46208], [1.98579, 42.47486], [1.99766, 42.4858], [1.98916, 42.49351], [1.98022, 42.49569], [1.97697, 42.48568], [1.97227, 42.48487], [1.97003, 42.48081], [1.96215, 42.47854], [1.95606, 42.45785], [1.96125, 42.45364], [1.98378, 42.44697], [1.99838, 42.44682]]]] } },
23063 { type: "Feature", properties: { wikidata: "Q98059339", nameEn: "Mainland Norway", country: "NO", groups: ["154", "150", "UN"], callingCodes: ["47"] }, geometry: { type: "MultiPolygon", coordinates: [[[[10.40861, 58.38489], [10.64958, 58.89391], [11.08911, 58.98745], [11.15367, 59.07862], [11.34459, 59.11672], [11.4601, 58.99022], [11.45199, 58.89604], [11.65732, 58.90177], [11.8213, 59.24985], [11.69297, 59.59442], [11.92112, 59.69531], [11.87121, 59.86039], [12.15641, 59.8926], [12.36317, 59.99259], [12.52003, 60.13846], [12.59133, 60.50559], [12.2277, 61.02442], [12.69115, 61.06584], [12.86939, 61.35427], [12.57707, 61.56547], [12.40595, 61.57226], [12.14746, 61.7147], [12.29187, 62.25699], [12.07085, 62.6297], [12.19919, 63.00104], [11.98529, 63.27487], [12.19919, 63.47935], [12.14928, 63.59373], [12.74105, 64.02171], [13.23411, 64.09087], [13.98222, 64.00953], [14.16051, 64.18725], [14.11117, 64.46674], [13.64276, 64.58402], [14.50926, 65.31786], [14.53778, 66.12399], [15.05113, 66.15572], [15.49318, 66.28509], [15.37197, 66.48217], [16.35589, 67.06419], [16.39154, 67.21653], [16.09922, 67.4364], [16.12774, 67.52106], [16.38441, 67.52923], [16.7409, 67.91037], [17.30416, 68.11591], [17.90787, 67.96537], [18.13836, 68.20874], [18.1241, 68.53721], [18.39503, 68.58672], [18.63032, 68.50849], [18.97255, 68.52416], [19.93508, 68.35911], [20.22027, 68.48759], [19.95647, 68.55546], [20.22027, 68.67246], [20.33435, 68.80174], [20.28444, 68.93283], [20.0695, 69.04469], [20.55258, 69.06069], [20.72171, 69.11874], [21.05775, 69.0356], [21.11099, 69.10291], [20.98641, 69.18809], [21.00732, 69.22755], [21.27827, 69.31281], [21.63833, 69.27485], [22.27276, 68.89514], [22.38367, 68.71561], [22.53321, 68.74393], [23.13064, 68.64684], [23.68017, 68.70276], [23.781, 68.84514], [24.02299, 68.81601], [24.18432, 68.73936], [24.74898, 68.65143], [24.90023, 68.55579], [24.93048, 68.61102], [25.10189, 68.63307], [25.12206, 68.78684], [25.42455, 68.90328], [25.61613, 68.89602], [25.75729, 68.99383], [25.69679, 69.27039], [25.96904, 69.68397], [26.40261, 69.91377], [26.64461, 69.96565], [27.05802, 69.92069], [27.57226, 70.06215], [27.95542, 70.0965], [27.97558, 69.99671], [28.32849, 69.88605], [28.36883, 69.81658], [29.12697, 69.69193], [29.31664, 69.47994], [28.8629, 69.22395], [28.81248, 69.11997], [28.91738, 69.04774], [29.0444, 69.0119], [29.26623, 69.13794], [29.27631, 69.2811], [29.97205, 69.41623], [30.16363, 69.65244], [30.52662, 69.54699], [30.95011, 69.54699], [30.84095, 69.80584], [31.59909, 70.16571], [32.07813, 72.01005], [-11.60274, 67.73467], [7.28637, 57.35913], [10.40861, 58.38489]]]] } },
23064 { type: "Feature", properties: { wikidata: "Q98543636", nameEn: "Mainland Ecuador", country: "EC", groups: ["005", "419", "019", "UN"], callingCodes: ["593"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-84.52388, -3.36941], [-80.30602, -3.39149], [-80.20647, -3.431], [-80.24123, -3.46124], [-80.24586, -3.48677], [-80.23651, -3.48652], [-80.22629, -3.501], [-80.20535, -3.51667], [-80.21642, -3.5888], [-80.19848, -3.59249], [-80.18741, -3.63994], [-80.19926, -3.68894], [-80.13232, -3.90317], [-80.46386, -4.01342], [-80.4822, -4.05477], [-80.45023, -4.20938], [-80.32114, -4.21323], [-80.46386, -4.41516], [-80.39256, -4.48269], [-80.13945, -4.29786], [-79.79722, -4.47558], [-79.59402, -4.46848], [-79.26248, -4.95167], [-79.1162, -4.97774], [-79.01659, -5.01481], [-78.85149, -4.66795], [-78.68394, -4.60754], [-78.34362, -3.38633], [-78.24589, -3.39907], [-78.22642, -3.51113], [-78.14324, -3.47653], [-78.19369, -3.36431], [-77.94147, -3.05454], [-76.6324, -2.58397], [-76.05203, -2.12179], [-75.57429, -1.55961], [-75.3872, -0.9374], [-75.22862, -0.95588], [-75.22862, -0.60048], [-75.53615, -0.19213], [-75.60169, -0.18708], [-75.61997, -0.10012], [-75.40192, -0.17196], [-75.25764, -0.11943], [-75.82927, 0.09578], [-76.23441, 0.42294], [-76.41215, 0.38228], [-76.4094, 0.24015], [-76.89177, 0.24736], [-77.52001, 0.40782], [-77.49984, 0.64476], [-77.67815, 0.73863], [-77.66416, 0.81604], [-77.68613, 0.83029], [-77.7148, 0.85003], [-77.85677, 0.80197], [-78.42749, 1.15389], [-78.87137, 1.47457], [-82.12561, 4.00341], [-84.52388, -3.36941]]]] } },
23065 { type: "Feature", properties: { m49: "001", wikidata: "Q2", nameEn: "World", aliases: ["Earth", "Planet"], level: "world" }, geometry: null },
23066 { type: "Feature", properties: { m49: "002", wikidata: "Q15", nameEn: "Africa", level: "region" }, geometry: null },
23067 { type: "Feature", properties: { m49: "003", wikidata: "Q49", nameEn: "North America", level: "subregion" }, geometry: null },
23068 { type: "Feature", properties: { m49: "005", wikidata: "Q18", nameEn: "South America", level: "intermediateRegion" }, geometry: null },
23069 { type: "Feature", properties: { m49: "009", wikidata: "Q538", nameEn: "Oceania", level: "region" }, geometry: null },
23070 { type: "Feature", properties: { m49: "011", wikidata: "Q4412", nameEn: "Western Africa", level: "intermediateRegion" }, geometry: null },
23071 { type: "Feature", properties: { m49: "013", wikidata: "Q27611", nameEn: "Central America", level: "intermediateRegion" }, geometry: null },
23072 { type: "Feature", properties: { m49: "014", wikidata: "Q27407", nameEn: "Eastern Africa", level: "intermediateRegion" }, geometry: null },
23073 { type: "Feature", properties: { m49: "015", wikidata: "Q27381", nameEn: "Northern Africa", level: "subregion" }, geometry: null },
23074 { type: "Feature", properties: { m49: "017", wikidata: "Q27433", nameEn: "Middle Africa", level: "intermediateRegion" }, geometry: null },
23075 { type: "Feature", properties: { m49: "018", wikidata: "Q27394", nameEn: "Southern Africa", level: "intermediateRegion" }, geometry: null },
23076 { type: "Feature", properties: { m49: "019", wikidata: "Q828", nameEn: "Americas", level: "region" }, geometry: null },
23077 { type: "Feature", properties: { m49: "021", wikidata: "Q2017699", nameEn: "Northern America", level: "subregion" }, geometry: null },
23078 { type: "Feature", properties: { m49: "029", wikidata: "Q664609", nameEn: "Caribbean", level: "intermediateRegion" }, geometry: null },
23079 { type: "Feature", properties: { m49: "030", wikidata: "Q27231", nameEn: "Eastern Asia", level: "subregion" }, geometry: null },
23080 { type: "Feature", properties: { m49: "034", wikidata: "Q771405", nameEn: "Southern Asia", level: "subregion" }, geometry: null },
23081 { type: "Feature", properties: { m49: "035", wikidata: "Q11708", nameEn: "South-eastern Asia", level: "subregion" }, geometry: null },
23082 { type: "Feature", properties: { m49: "039", wikidata: "Q27449", nameEn: "Southern Europe", level: "subregion" }, geometry: null },
23083 { type: "Feature", properties: { m49: "053", wikidata: "Q45256", nameEn: "Australia and New Zealand", aliases: ["Australasia"], level: "subregion" }, geometry: null },
23084 { type: "Feature", properties: { m49: "054", wikidata: "Q37394", nameEn: "Melanesia", level: "subregion" }, geometry: null },
23085 { type: "Feature", properties: { m49: "057", wikidata: "Q3359409", nameEn: "Micronesia", level: "subregion" }, geometry: null },
23086 { type: "Feature", properties: { m49: "061", wikidata: "Q35942", nameEn: "Polynesia", level: "subregion" }, geometry: null },
23087 { type: "Feature", properties: { m49: "142", wikidata: "Q48", nameEn: "Asia", level: "region" }, geometry: null },
23088 { type: "Feature", properties: { m49: "143", wikidata: "Q27275", nameEn: "Central Asia", level: "subregion" }, geometry: null },
23089 { type: "Feature", properties: { m49: "145", wikidata: "Q27293", nameEn: "Western Asia", level: "subregion" }, geometry: null },
23090 { type: "Feature", properties: { m49: "150", wikidata: "Q46", nameEn: "Europe", level: "region" }, geometry: null },
23091 { type: "Feature", properties: { m49: "151", wikidata: "Q27468", nameEn: "Eastern Europe", level: "subregion" }, geometry: null },
23092 { type: "Feature", properties: { m49: "154", wikidata: "Q27479", nameEn: "Northern Europe", level: "subregion" }, geometry: null },
23093 { type: "Feature", properties: { m49: "155", wikidata: "Q27496", nameEn: "Western Europe", level: "subregion" }, geometry: null },
23094 { type: "Feature", properties: { m49: "202", wikidata: "Q132959", nameEn: "Sub-Saharan Africa", level: "subregion" }, geometry: null },
23095 { type: "Feature", properties: { m49: "419", wikidata: "Q72829598", nameEn: "Latin America and the Caribbean", level: "subregion" }, geometry: null },
23096 { type: "Feature", properties: { m49: "680", wikidata: "Q3405693", nameEn: "Sark", country: "GB", groups: ["GG", "830", "Q185086", "154", "150", "UN"], level: "subterritory", driveSide: "left", roadSpeedUnit: "mph", roadHeightUnit: "ft", callingCodes: ["44 01481"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-2.36485, 49.48223], [-2.65349, 49.15373], [-2.09454, 49.46288], [-2.36485, 49.48223]]]] } },
23097 { type: "Feature", properties: { m49: "830", wikidata: "Q42314", nameEn: "Channel Islands", level: "intermediateRegion" }, geometry: null },
23098 { type: "Feature", properties: { iso1A2: "AC", iso1A3: "ASC", wikidata: "Q46197", nameEn: "Ascension Island", aliases: ["SH-AC"], country: "GB", groups: ["SH", "BOTS", "011", "202", "002", "UN"], isoStatus: "excRes", driveSide: "left", roadSpeedUnit: "mph", roadHeightUnit: "ft", callingCodes: ["247"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-14.82771, -8.70814], [-13.33271, -8.07391], [-14.91926, -6.63386], [-14.82771, -8.70814]]]] } },
23099 { type: "Feature", properties: { iso1A2: "AD", iso1A3: "AND", iso1N3: "020", wikidata: "Q228", nameEn: "Andorra", groups: ["Q12837", "039", "150", "UN"], callingCodes: ["376"] }, geometry: { type: "MultiPolygon", coordinates: [[[[1.72515, 42.50338], [1.73683, 42.55492], [1.7858, 42.57698], [1.72588, 42.59098], [1.73452, 42.61515], [1.68267, 42.62533], [1.6625, 42.61982], [1.63485, 42.62957], [1.60085, 42.62703], [1.55418, 42.65669], [1.50867, 42.64483], [1.48043, 42.65203], [1.46718, 42.63296], [1.47986, 42.61346], [1.44197, 42.60217], [1.42512, 42.58292], [1.44529, 42.56722], [1.4234, 42.55959], [1.41245, 42.53539], [1.44759, 42.54431], [1.46661, 42.50949], [1.41648, 42.48315], [1.43838, 42.47848], [1.44529, 42.43724], [1.5127, 42.42959], [1.55073, 42.43299], [1.55937, 42.45808], [1.57953, 42.44957], [1.58933, 42.46275], [1.65674, 42.47125], [1.66826, 42.50779], [1.70571, 42.48867], [1.72515, 42.50338]]]] } },
23100 { type: "Feature", properties: { iso1A2: "AE", iso1A3: "ARE", iso1N3: "784", wikidata: "Q878", nameEn: "United Arab Emirates", groups: ["145", "142", "UN"], callingCodes: ["971"] }, geometry: { type: "MultiPolygon", coordinates: [[[[56.26534, 25.62825], [56.25341, 25.61443], [56.26636, 25.60643], [56.25365, 25.60211], [56.20473, 25.61119], [56.18363, 25.65508], [56.14826, 25.66351], [56.13579, 25.73524], [56.17416, 25.77239], [56.13963, 25.82765], [56.19334, 25.9795], [56.15498, 26.06828], [56.08666, 26.05038], [55.81777, 26.18798], [55.14145, 25.62624], [53.97892, 24.64436], [52.82259, 25.51697], [52.35509, 25.00368], [52.02277, 24.75635], [51.83108, 24.71675], [51.58834, 24.66608], [51.41644, 24.39615], [51.58871, 24.27256], [51.59617, 24.12041], [52.56622, 22.94341], [55.13599, 22.63334], [55.2137, 22.71065], [55.22634, 23.10378], [55.57358, 23.669], [55.48677, 23.94946], [55.73301, 24.05994], [55.8308, 24.01633], [56.01799, 24.07426], [55.95472, 24.2172], [55.83367, 24.20193], [55.77658, 24.23476], [55.76558, 24.23227], [55.75257, 24.23466], [55.75382, 24.2466], [55.75939, 24.26114], [55.76781, 24.26209], [55.79145, 24.27914], [55.80747, 24.31069], [55.83395, 24.32776], [55.83271, 24.41521], [55.76461, 24.5287], [55.83271, 24.68567], [55.83408, 24.77858], [55.81348, 24.80102], [55.81116, 24.9116], [55.85094, 24.96858], [55.90849, 24.96771], [55.96316, 25.00857], [56.05715, 24.95727], [56.05106, 24.87461], [55.97467, 24.89639], [55.97836, 24.87673], [56.03535, 24.81161], [56.06128, 24.74457], [56.13684, 24.73699], [56.20062, 24.78565], [56.20568, 24.85063], [56.30269, 24.88334], [56.34873, 24.93205], [56.3227, 24.97284], [56.86325, 25.03856], [56.82555, 25.7713], [56.26534, 25.62825]], [[56.26062, 25.33108], [56.3005, 25.31815], [56.3111, 25.30107], [56.35172, 25.30681], [56.34438, 25.26653], [56.27628, 25.23404], [56.24341, 25.22867], [56.20872, 25.24104], [56.20838, 25.25668], [56.24465, 25.27505], [56.25008, 25.28843], [56.23362, 25.31253], [56.26062, 25.33108]]], [[[56.28423, 25.26344], [56.29379, 25.2754], [56.28102, 25.28486], [56.2716, 25.27916], [56.27086, 25.26128], [56.28423, 25.26344]]]] } },
23101 { type: "Feature", properties: { iso1A2: "AF", iso1A3: "AFG", iso1N3: "004", wikidata: "Q889", nameEn: "Afghanistan", groups: ["034", "142", "UN"], callingCodes: ["93"] }, geometry: { type: "MultiPolygon", coordinates: [[[[70.61526, 38.34774], [70.60407, 38.28046], [70.54673, 38.24541], [70.4898, 38.12546], [70.17206, 37.93276], [70.1863, 37.84296], [70.27694, 37.81258], [70.28243, 37.66706], [70.15015, 37.52519], [69.95971, 37.5659], [69.93362, 37.61378], [69.84435, 37.60616], [69.80041, 37.5746], [69.51888, 37.5844], [69.44954, 37.4869], [69.36645, 37.40462], [69.45022, 37.23315], [69.39529, 37.16752], [69.25152, 37.09426], [69.03274, 37.25174], [68.96407, 37.32603], [68.88168, 37.33368], [68.91189, 37.26704], [68.80889, 37.32494], [68.81438, 37.23862], [68.6798, 37.27906], [68.61851, 37.19815], [68.41888, 37.13906], [68.41201, 37.10402], [68.29253, 37.10621], [68.27605, 37.00977], [68.18542, 37.02074], [68.02194, 36.91923], [67.87917, 37.0591], [67.7803, 37.08978], [67.78329, 37.1834], [67.51868, 37.26102], [67.2581, 37.17216], [67.2224, 37.24545], [67.13039, 37.27168], [67.08232, 37.35469], [66.95598, 37.40162], [66.64699, 37.32958], [66.55743, 37.35409], [66.30993, 37.32409], [65.72274, 37.55438], [65.64137, 37.45061], [65.64263, 37.34388], [65.51778, 37.23881], [64.97945, 37.21913], [64.61141, 36.6351], [64.62514, 36.44311], [64.57295, 36.34362], [64.43288, 36.24401], [64.05385, 36.10433], [63.98519, 36.03773], [63.56496, 35.95106], [63.53475, 35.90881], [63.29579, 35.85985], [63.12276, 35.86208], [63.10318, 35.81782], [63.23262, 35.67487], [63.10079, 35.63024], [63.12276, 35.53196], [63.0898, 35.43131], [62.90853, 35.37086], [62.74098, 35.25432], [62.62288, 35.22067], [62.48006, 35.28796], [62.29878, 35.13312], [62.29191, 35.25964], [62.15871, 35.33278], [62.05709, 35.43803], [61.97743, 35.4604], [61.77693, 35.41341], [61.58742, 35.43803], [61.27371, 35.61482], [61.18187, 35.30249], [61.0991, 35.27845], [61.12831, 35.09938], [61.06926, 34.82139], [61.00197, 34.70631], [60.99922, 34.63064], [60.72316, 34.52857], [60.91321, 34.30411], [60.66502, 34.31539], [60.50209, 34.13992], [60.5838, 33.80793], [60.5485, 33.73422], [60.57762, 33.59772], [60.69573, 33.56054], [60.91133, 33.55596], [60.88908, 33.50219], [60.56485, 33.12944], [60.86191, 32.22565], [60.84541, 31.49561], [61.70929, 31.37391], [61.80569, 31.16167], [61.80957, 31.12576], [61.83257, 31.0452], [61.8335, 30.97669], [61.78268, 30.92724], [61.80829, 30.84224], [60.87231, 29.86514], [62.47751, 29.40782], [63.5876, 29.50456], [64.12966, 29.39157], [64.19796, 29.50407], [64.62116, 29.58903], [65.04005, 29.53957], [66.24175, 29.85181], [66.36042, 29.9583], [66.23609, 30.06321], [66.34869, 30.404], [66.28413, 30.57001], [66.39194, 30.9408], [66.42645, 30.95309], [66.58175, 30.97532], [66.68166, 31.07597], [66.72561, 31.20526], [66.83273, 31.26867], [67.04147, 31.31561], [67.03323, 31.24519], [67.29964, 31.19586], [67.78854, 31.33203], [67.7748, 31.4188], [67.62374, 31.40473], [67.58323, 31.52772], [67.72056, 31.52304], [67.86887, 31.63536], [68.00071, 31.6564], [68.1655, 31.82691], [68.25614, 31.80357], [68.27605, 31.75863], [68.44222, 31.76446], [68.57475, 31.83158], [68.6956, 31.75687], [68.79997, 31.61665], [68.91078, 31.59687], [68.95995, 31.64822], [69.00939, 31.62249], [69.11514, 31.70782], [69.20577, 31.85957], [69.3225, 31.93186], [69.27032, 32.14141], [69.27932, 32.29119], [69.23599, 32.45946], [69.2868, 32.53938], [69.38155, 32.56601], [69.44747, 32.6678], [69.43649, 32.7302], [69.38018, 32.76601], [69.47082, 32.85834], [69.5436, 32.8768], [69.49854, 32.88843], [69.49004, 33.01509], [69.57656, 33.09911], [69.71526, 33.09911], [69.79766, 33.13247], [69.85259, 33.09451], [70.02563, 33.14282], [70.07369, 33.22557], [70.13686, 33.21064], [70.32775, 33.34496], [70.17062, 33.53535], [70.20141, 33.64387], [70.14785, 33.6553], [70.14236, 33.71701], [70.00503, 33.73528], [69.85671, 33.93719], [69.87307, 33.9689], [69.90203, 34.04194], [70.54336, 33.9463], [70.88119, 33.97933], [71.07345, 34.06242], [71.06933, 34.10564], [71.09307, 34.11961], [71.09453, 34.13524], [71.13078, 34.16503], [71.12815, 34.26619], [71.17662, 34.36769], [71.02401, 34.44835], [71.0089, 34.54568], [71.11602, 34.63047], [71.08718, 34.69034], [71.28356, 34.80882], [71.29472, 34.87728], [71.50329, 34.97328], [71.49917, 35.00478], [71.55273, 35.02615], [71.52938, 35.09023], [71.67495, 35.21262], [71.5541, 35.28776], [71.54294, 35.31037], [71.65435, 35.4479], [71.49917, 35.6267], [71.55273, 35.71483], [71.37969, 35.95865], [71.19505, 36.04134], [71.60491, 36.39429], [71.80267, 36.49924], [72.18135, 36.71838], [72.6323, 36.84601], [73.82685, 36.91421], [74.04856, 36.82648], [74.43389, 37.00977], [74.53739, 36.96224], [74.56453, 37.03023], [74.49981, 37.24518], [74.80605, 37.21565], [74.88887, 37.23275], [74.8294, 37.3435], [74.68383, 37.3948], [74.56161, 37.37734], [74.41055, 37.3948], [74.23339, 37.41116], [74.20308, 37.34208], [73.8564, 37.26158], [73.82552, 37.22659], [73.64974, 37.23643], [73.61129, 37.27469], [73.76647, 37.33913], [73.77197, 37.4417], [73.29633, 37.46495], [73.06884, 37.31729], [72.79693, 37.22222], [72.66381, 37.02014], [72.54095, 37.00007], [72.31676, 36.98115], [71.83229, 36.68084], [71.67083, 36.67346], [71.57195, 36.74943], [71.51502, 36.89128], [71.48481, 36.93218], [71.46923, 36.99925], [71.45578, 37.03094], [71.43097, 37.05855], [71.44127, 37.11856], [71.4494, 37.18137], [71.4555, 37.21418], [71.47386, 37.2269], [71.48339, 37.23937], [71.4824, 37.24921], [71.48536, 37.26017], [71.50674, 37.31502], [71.49821, 37.31975], [71.4862, 37.33405], [71.47685, 37.40281], [71.49612, 37.4279], [71.5256, 37.47971], [71.50616, 37.50733], [71.49693, 37.53527], [71.5065, 37.60912], [71.51972, 37.61945], [71.54186, 37.69691], [71.55234, 37.73209], [71.53053, 37.76534], [71.54324, 37.77104], [71.55752, 37.78677], [71.59255, 37.79956], [71.58843, 37.92425], [71.51565, 37.95349], [71.32871, 37.88564], [71.296, 37.93403], [71.2809, 37.91995], [71.24969, 37.93031], [71.27278, 37.96496], [71.27622, 37.99946], [71.28922, 38.01272], [71.29878, 38.04429], [71.36444, 38.15358], [71.37803, 38.25641], [71.33869, 38.27335], [71.33114, 38.30339], [71.21291, 38.32797], [71.1451, 38.40106], [71.10957, 38.40671], [71.10592, 38.42077], [71.09542, 38.42517], [71.0556, 38.40176], [71.03545, 38.44779], [70.98693, 38.48862], [70.92728, 38.43021], [70.88719, 38.46826], [70.84376, 38.44688], [70.82538, 38.45394], [70.81697, 38.44507], [70.80521, 38.44447], [70.79766, 38.44944], [70.78702, 38.45031], [70.78581, 38.45502], [70.77132, 38.45548], [70.75455, 38.4252], [70.72485, 38.4131], [70.69807, 38.41861], [70.67438, 38.40597], [70.6761, 38.39144], [70.69189, 38.37031], [70.64966, 38.34999], [70.61526, 38.34774]]]] } },
23102 { type: "Feature", properties: { iso1A2: "AG", iso1A3: "ATG", iso1N3: "028", wikidata: "Q781", nameEn: "Antigua and Barbuda", groups: ["029", "003", "419", "019", "UN"], driveSide: "left", roadSpeedUnit: "mph", callingCodes: ["1 268"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-61.66959, 18.6782], [-62.58307, 16.68909], [-62.1023, 16.97277], [-61.23098, 16.62484], [-61.66959, 18.6782]]]] } },
23103 { type: "Feature", properties: { iso1A2: "AI", iso1A3: "AIA", iso1N3: "660", wikidata: "Q25228", nameEn: "Anguilla", country: "GB", groups: ["BOTS", "029", "003", "419", "019", "UN"], driveSide: "left", roadSpeedUnit: "mph", callingCodes: ["1 264"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-63.79029, 19.11219], [-63.35989, 18.06012], [-62.62718, 18.26185], [-63.79029, 19.11219]]]] } },
23104 { type: "Feature", properties: { iso1A2: "AL", iso1A3: "ALB", iso1N3: "008", wikidata: "Q222", nameEn: "Albania", groups: ["039", "150", "UN"], callingCodes: ["355"] }, geometry: { type: "MultiPolygon", coordinates: [[[[20.07761, 42.55582], [20.01834, 42.54622], [20.00842, 42.5109], [19.9324, 42.51699], [19.82333, 42.46581], [19.76549, 42.50237], [19.74731, 42.57422], [19.77375, 42.58517], [19.73244, 42.66299], [19.65972, 42.62774], [19.4836, 42.40831], [19.42352, 42.36546], [19.42, 42.33019], [19.28623, 42.17745], [19.40687, 42.10024], [19.37548, 42.06835], [19.36867, 42.02564], [19.37691, 41.96977], [19.34601, 41.95675], [19.33812, 41.90669], [19.37451, 41.8842], [19.37597, 41.84849], [19.26406, 41.74971], [19.0384, 40.35325], [19.95905, 39.82857], [19.97622, 39.78684], [19.92466, 39.69533], [19.98042, 39.6504], [20.00957, 39.69227], [20.05189, 39.69112], [20.12956, 39.65805], [20.15988, 39.652], [20.22376, 39.64532], [20.22707, 39.67459], [20.27412, 39.69884], [20.31961, 39.72799], [20.29152, 39.80421], [20.30804, 39.81563], [20.38572, 39.78516], [20.41475, 39.81437], [20.41546, 39.82832], [20.31135, 39.99438], [20.37911, 39.99058], [20.42373, 40.06777], [20.48487, 40.06271], [20.51297, 40.08168], [20.55593, 40.06524], [20.61081, 40.07866], [20.62566, 40.0897], [20.67162, 40.09433], [20.71789, 40.27739], [20.78234, 40.35803], [20.7906, 40.42726], [20.83688, 40.47882], [20.94925, 40.46625], [20.96908, 40.51526], [21.03932, 40.56299], [21.05833, 40.66586], [20.98134, 40.76046], [20.95752, 40.76982], [20.98396, 40.79109], [20.97887, 40.85475], [20.97693, 40.90103], [20.94305, 40.92399], [20.83671, 40.92752], [20.81567, 40.89662], [20.73504, 40.9081], [20.71634, 40.91781], [20.65558, 41.08009], [20.63454, 41.0889], [20.59832, 41.09066], [20.58546, 41.11179], [20.59715, 41.13644], [20.51068, 41.2323], [20.49432, 41.33679], [20.52119, 41.34381], [20.55976, 41.4087], [20.51301, 41.442], [20.49039, 41.49277], [20.45331, 41.51436], [20.45809, 41.5549], [20.52103, 41.56473], [20.55508, 41.58113], [20.51769, 41.65975], [20.52937, 41.69292], [20.51301, 41.72433], [20.53405, 41.78099], [20.57144, 41.7897], [20.55976, 41.87068], [20.59524, 41.8818], [20.57946, 41.91593], [20.63069, 41.94913], [20.59434, 42.03879], [20.55633, 42.08173], [20.56955, 42.12097], [20.48857, 42.25444], [20.3819, 42.3029], [20.34479, 42.32656], [20.24399, 42.32168], [20.21797, 42.41237], [20.17127, 42.50469], [20.07761, 42.55582]]]] } },
23105 { type: "Feature", properties: { iso1A2: "AM", iso1A3: "ARM", iso1N3: "051", wikidata: "Q399", nameEn: "Armenia", groups: ["145", "142", "UN"], callingCodes: ["374"] }, geometry: { type: "MultiPolygon", coordinates: [[[[45.0133, 41.29747], [44.93493, 41.25685], [44.81437, 41.30371], [44.80053, 41.25949], [44.81749, 41.23488], [44.84358, 41.23088], [44.89911, 41.21366], [44.87887, 41.20195], [44.82084, 41.21513], [44.72814, 41.20338], [44.61462, 41.24018], [44.59322, 41.1933], [44.46791, 41.18204], [44.34417, 41.2382], [44.34337, 41.20312], [44.32139, 41.2079], [44.18148, 41.24644], [44.16591, 41.19141], [43.84835, 41.16329], [43.74717, 41.1117], [43.67712, 41.13398], [43.4717, 41.12611], [43.44984, 41.0988], [43.47319, 41.02251], [43.58683, 40.98961], [43.67712, 40.93084], [43.67712, 40.84846], [43.74872, 40.7365], [43.7425, 40.66805], [43.63664, 40.54159], [43.54791, 40.47413], [43.60862, 40.43267], [43.59928, 40.34019], [43.71136, 40.16673], [43.65221, 40.14889], [43.65688, 40.11199], [43.92307, 40.01787], [44.1057, 40.03555], [44.1778, 40.02845], [44.26973, 40.04866], [44.46635, 39.97733], [44.61845, 39.8281], [44.75779, 39.7148], [44.88354, 39.74432], [44.92869, 39.72157], [45.06604, 39.79277], [45.18554, 39.67846], [45.17464, 39.58614], [45.21784, 39.58074], [45.23535, 39.61373], [45.30385, 39.61373], [45.29606, 39.57654], [45.46992, 39.49888], [45.70547, 39.60174], [45.80804, 39.56716], [45.83, 39.46487], [45.79225, 39.3695], [45.99774, 39.28931], [46.02303, 39.09978], [46.06973, 39.0744], [46.14785, 38.84206], [46.20601, 38.85262], [46.34059, 38.92076], [46.53497, 38.86548], [46.51805, 38.94982], [46.54296, 39.07078], [46.44022, 39.19636], [46.52584, 39.18912], [46.54141, 39.15895], [46.58032, 39.21204], [46.63481, 39.23013], [46.56476, 39.24942], [46.50093, 39.33736], [46.43244, 39.35181], [46.37795, 39.42039], [46.4013, 39.45405], [46.53051, 39.47809], [46.51027, 39.52373], [46.57721, 39.54414], [46.57098, 39.56694], [46.52117, 39.58734], [46.42465, 39.57534], [46.40286, 39.63651], [46.18493, 39.60533], [45.96543, 39.78859], [45.82533, 39.82925], [45.7833, 39.9475], [45.60895, 39.97733], [45.59806, 40.0131], [45.78642, 40.03218], [45.83779, 39.98925], [45.97944, 40.181], [45.95609, 40.27846], [45.65098, 40.37696], [45.42994, 40.53804], [45.45484, 40.57707], [45.35366, 40.65979], [45.4206, 40.7424], [45.55914, 40.78366], [45.60584, 40.87436], [45.40814, 40.97904], [45.44083, 41.01663], [45.39725, 41.02603], [45.35677, 40.99784], [45.28859, 41.03757], [45.26162, 41.0228], [45.25897, 41.0027], [45.1994, 41.04518], [45.16493, 41.05068], [45.1634, 41.08082], [45.1313, 41.09369], [45.12923, 41.06059], [45.06784, 41.05379], [45.08028, 41.10917], [45.19942, 41.13299], [45.1969, 41.168], [45.11811, 41.19967], [45.05201, 41.19211], [45.02932, 41.2101], [45.05497, 41.2464], [45.0133, 41.29747]], [[45.21324, 40.9817], [45.21219, 40.99001], [45.20518, 40.99348], [45.19312, 40.98998], [45.18382, 41.0066], [45.20625, 41.01484], [45.23487, 41.00226], [45.23095, 40.97828], [45.21324, 40.9817]], [[45.00864, 41.03411], [44.9903, 41.05657], [44.96031, 41.06345], [44.95383, 41.07553], [44.97169, 41.09176], [45.00864, 41.09407], [45.03406, 41.07931], [45.04517, 41.06653], [45.03792, 41.03938], [45.00864, 41.03411]]], [[[45.50279, 40.58424], [45.56071, 40.64765], [45.51825, 40.67382], [45.47927, 40.65023], [45.50279, 40.58424]]]] } },
23106 { type: "Feature", properties: { iso1A2: "AO", iso1A3: "AGO", iso1N3: "024", wikidata: "Q916", nameEn: "Angola", groups: ["017", "202", "002", "UN"], callingCodes: ["244"] }, geometry: { type: "MultiPolygon", coordinates: [[[[16.55507, -5.85631], [13.04371, -5.87078], [12.42245, -6.07585], [11.95767, -5.94705], [12.20376, -5.76338], [12.26557, -5.74031], [12.52318, -5.74353], [12.52301, -5.17481], [12.53599, -5.1618], [12.53586, -5.14658], [12.51589, -5.1332], [12.49815, -5.14058], [12.46297, -5.09408], [12.60251, -5.01715], [12.63465, -4.94632], [12.70868, -4.95505], [12.8733, -4.74346], [13.11195, -4.67745], [13.09648, -4.63739], [12.91489, -4.47907], [12.87096, -4.40315], [12.76844, -4.38709], [12.64835, -4.55937], [12.40964, -4.60609], [12.32324, -4.78415], [12.25587, -4.79437], [12.20901, -4.75642], [12.16068, -4.90089], [12.00924, -5.02627], [11.50888, -5.33417], [10.5065, -17.25284], [11.75063, -17.25013], [12.07076, -17.15165], [12.52111, -17.24495], [12.97145, -16.98567], [13.36212, -16.98048], [13.95896, -17.43141], [14.28743, -17.38814], [18.39229, -17.38927], [18.84226, -17.80375], [21.14283, -17.94318], [21.42741, -18.02787], [23.47474, -17.62877], [23.20038, -17.47563], [22.17217, -16.50269], [22.00323, -16.18028], [21.97988, -13.00148], [24.03339, -12.99091], [23.90937, -12.844], [24.06672, -12.29058], [23.98804, -12.13149], [24.02603, -11.15368], [24.00027, -10.89356], [23.86868, -11.02856], [23.45631, -10.946], [23.16602, -11.10577], [22.54205, -11.05784], [22.25951, -11.24911], [22.17954, -10.85884], [22.32604, -10.76291], [22.19039, -9.94628], [21.84856, -9.59871], [21.79824, -7.29628], [20.56263, -7.28566], [20.61689, -6.90876], [20.31846, -6.91953], [20.30218, -6.98955], [19.5469, -7.00195], [19.33698, -7.99743], [18.33635, -8.00126], [17.5828, -8.13784], [16.96282, -7.21787], [16.55507, -5.85631]]]] } },
23107 { type: "Feature", properties: { iso1A2: "AQ", iso1A3: "ATA", iso1N3: "010", wikidata: "Q51", nameEn: "Antarctica", level: "region", callingCodes: ["672"] }, geometry: { type: "MultiPolygon", coordinates: [[[[180, -60], [-180, -60], [-180, -90], [180, -90], [180, -60]]]] } },
23108 { type: "Feature", properties: { iso1A2: "AR", iso1A3: "ARG", iso1N3: "032", wikidata: "Q414", nameEn: "Argentina", aliases: ["RA"], groups: ["005", "419", "019", "UN"], callingCodes: ["54"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-72.31343, -50.58411], [-72.33873, -51.59954], [-71.99889, -51.98018], [-69.97824, -52.00845], [-68.41683, -52.33516], [-68.60702, -52.65781], [-68.60733, -54.9125], [-68.01394, -54.8753], [-67.46182, -54.92205], [-67.11046, -54.94199], [-66.07313, -55.19618], [-63.67376, -55.11859], [-54.78916, -36.21945], [-57.83001, -34.69099], [-58.34425, -34.15035], [-58.44442, -33.84033], [-58.40475, -33.11777], [-58.1224, -32.98842], [-58.22362, -32.52416], [-58.10036, -32.25338], [-58.20252, -31.86966], [-58.00076, -31.65016], [-58.0023, -31.53084], [-58.07569, -31.44916], [-57.98127, -31.3872], [-57.9908, -31.34924], [-57.86729, -31.06352], [-57.89476, -30.95994], [-57.8024, -30.77193], [-57.89115, -30.49572], [-57.64859, -30.35095], [-57.61478, -30.25165], [-57.65132, -30.19229], [-57.09386, -29.74211], [-56.81251, -29.48154], [-56.62789, -29.18073], [-56.57295, -29.11357], [-56.54171, -29.11447], [-56.05265, -28.62651], [-56.00458, -28.60421], [-56.01729, -28.51223], [-55.65418, -28.18304], [-55.6262, -28.17124], [-55.33303, -27.94661], [-55.16872, -27.86224], [-55.1349, -27.89759], [-54.90805, -27.73149], [-54.90159, -27.63132], [-54.67657, -27.57214], [-54.50416, -27.48232], [-54.41888, -27.40882], [-54.19268, -27.30751], [-54.19062, -27.27639], [-54.15978, -27.2889], [-53.80144, -27.09844], [-53.73372, -26.6131], [-53.68269, -26.33359], [-53.64505, -26.28089], [-53.64186, -26.25976], [-53.64632, -26.24798], [-53.63881, -26.25075], [-53.63739, -26.2496], [-53.65237, -26.23289], [-53.65018, -26.19501], [-53.73968, -26.10012], [-53.73391, -26.07006], [-53.7264, -26.0664], [-53.73086, -26.05842], [-53.73511, -26.04211], [-53.83691, -25.94849], [-53.90831, -25.55513], [-54.52926, -25.62846], [-54.5502, -25.58915], [-54.59398, -25.59224], [-54.62063, -25.91213], [-54.60664, -25.9691], [-54.67359, -25.98607], [-54.69333, -26.37705], [-54.70732, -26.45099], [-54.80868, -26.55669], [-55.00584, -26.78754], [-55.06351, -26.80195], [-55.16948, -26.96068], [-55.25243, -26.93808], [-55.39611, -26.97679], [-55.62322, -27.1941], [-55.59094, -27.32444], [-55.74475, -27.44485], [-55.89195, -27.3467], [-56.18313, -27.29851], [-56.85337, -27.5165], [-58.04205, -27.2387], [-58.59549, -27.29973], [-58.65321, -27.14028], [-58.3198, -26.83443], [-58.1188, -26.16704], [-57.87176, -25.93604], [-57.57431, -25.47269], [-57.80821, -25.13863], [-58.25492, -24.92528], [-58.33055, -24.97099], [-59.33886, -24.49935], [-59.45482, -24.34787], [-60.03367, -24.00701], [-60.28163, -24.04436], [-60.99754, -23.80934], [-61.0782, -23.62932], [-61.9756, -23.0507], [-62.22768, -22.55807], [-62.51761, -22.37684], [-62.64455, -22.25091], [-62.8078, -22.12534], [-62.81124, -21.9987], [-63.66482, -21.99918], [-63.68113, -22.0544], [-63.70963, -21.99934], [-63.93287, -21.99934], [-64.22918, -22.55807], [-64.31489, -22.88824], [-64.35108, -22.73282], [-64.4176, -22.67692], [-64.58888, -22.25035], [-64.67174, -22.18957], [-64.90014, -22.12136], [-64.99524, -22.08255], [-65.47435, -22.08908], [-65.57743, -22.07675], [-65.58694, -22.09794], [-65.61166, -22.09504], [-65.7467, -22.10105], [-65.9261, -21.93335], [-66.04832, -21.9187], [-66.03836, -21.84829], [-66.24077, -21.77837], [-66.29714, -22.08741], [-66.7298, -22.23644], [-67.18382, -22.81525], [-66.99632, -22.99839], [-67.33563, -24.04237], [-68.24825, -24.42596], [-68.56909, -24.69831], [-68.38372, -25.08636], [-68.57622, -25.32505], [-68.38372, -26.15353], [-68.56909, -26.28146], [-68.59048, -26.49861], [-68.27677, -26.90626], [-68.43363, -27.08414], [-68.77586, -27.16029], [-69.22504, -27.95042], [-69.66709, -28.44055], [-69.80969, -29.07185], [-69.99507, -29.28351], [-69.8596, -30.26131], [-70.14479, -30.36595], [-70.55832, -31.51559], [-69.88099, -33.34489], [-69.87386, -34.13344], [-70.49416, -35.24145], [-70.38008, -36.02375], [-70.95047, -36.4321], [-71.24279, -37.20264], [-70.89532, -38.6923], [-71.37826, -38.91474], [-71.92726, -40.72714], [-71.74901, -42.11711], [-72.15541, -42.15941], [-72.14828, -42.85321], [-71.64206, -43.64774], [-71.81318, -44.38097], [-71.16436, -44.46244], [-71.26418, -44.75684], [-72.06985, -44.81756], [-71.35687, -45.22075], [-71.75614, -45.61611], [-71.68577, -46.55385], [-71.94152, -47.13595], [-72.50478, -47.80586], [-72.27662, -48.28727], [-72.54042, -48.52392], [-72.56894, -48.81116], [-73.09655, -49.14342], [-73.45156, -49.79461], [-73.55259, -49.92488], [-73.15765, -50.78337], [-72.31343, -50.58411]]]] } },
23109 { type: "Feature", properties: { iso1A2: "AS", iso1A3: "ASM", iso1N3: "016", wikidata: "Q16641", nameEn: "American Samoa", aliases: ["US-AS"], country: "US", groups: ["Q1352230", "061", "009", "UN"], roadSpeedUnit: "mph", roadHeightUnit: "ft", callingCodes: ["1 684"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-171.39864, -10.21587], [-170.99605, -15.1275], [-166.32598, -15.26169], [-171.39864, -10.21587]]]] } },
23110 { type: "Feature", properties: { iso1A2: "AT", iso1A3: "AUT", iso1N3: "040", wikidata: "Q40", nameEn: "Austria", groups: ["EU", "155", "150", "UN"], callingCodes: ["43"] }, geometry: { type: "MultiPolygon", coordinates: [[[[15.34823, 48.98444], [15.28305, 48.98831], [15.26177, 48.95766], [15.16358, 48.94278], [15.15534, 48.99056], [14.99878, 49.01444], [14.97612, 48.96983], [14.98917, 48.90082], [14.95072, 48.79101], [14.98032, 48.77959], [14.9782, 48.7766], [14.98112, 48.77524], [14.9758, 48.76857], [14.95641, 48.75915], [14.94773, 48.76268], [14.81545, 48.7874], [14.80821, 48.77711], [14.80584, 48.73489], [14.72756, 48.69502], [14.71794, 48.59794], [14.66762, 48.58215], [14.60808, 48.62881], [14.56139, 48.60429], [14.4587, 48.64695], [14.43076, 48.58855], [14.33909, 48.55852], [14.20691, 48.5898], [14.09104, 48.5943], [14.01482, 48.63788], [14.06151, 48.66873], [13.84023, 48.76988], [13.82266, 48.75544], [13.81863, 48.73257], [13.79337, 48.71375], [13.81791, 48.69832], [13.81283, 48.68426], [13.81901, 48.6761], [13.82609, 48.62345], [13.80038, 48.59487], [13.80519, 48.58026], [13.76921, 48.55324], [13.7513, 48.5624], [13.74816, 48.53058], [13.72802, 48.51208], [13.66113, 48.53558], [13.65186, 48.55092], [13.62508, 48.55501], [13.59705, 48.57013], [13.57535, 48.55912], [13.51291, 48.59023], [13.50131, 48.58091], [13.50663, 48.57506], [13.46967, 48.55157], [13.45214, 48.56472], [13.43695, 48.55776], [13.45727, 48.51092], [13.42527, 48.45711], [13.43929, 48.43386], [13.40709, 48.37292], [13.30897, 48.31575], [13.26039, 48.29422], [13.18093, 48.29577], [13.126, 48.27867], [13.0851, 48.27711], [13.02083, 48.25689], [12.95306, 48.20629], [12.87126, 48.20318], [12.84475, 48.16556], [12.836, 48.1647], [12.8362, 48.15876], [12.82673, 48.15245], [12.80676, 48.14979], [12.78595, 48.12445], [12.7617, 48.12796], [12.74973, 48.10885], [12.76141, 48.07373], [12.8549, 48.01122], [12.87476, 47.96195], [12.91683, 47.95647], [12.9211, 47.95135], [12.91985, 47.94069], [12.92668, 47.93879], [12.93419, 47.94063], [12.93642, 47.94436], [12.93886, 47.94046], [12.94163, 47.92927], [13.00588, 47.84374], [12.98543, 47.82896], [12.96311, 47.79957], [12.93202, 47.77302], [12.94371, 47.76281], [12.9353, 47.74788], [12.91711, 47.74026], [12.90274, 47.72513], [12.91333, 47.7178], [12.92969, 47.71094], [12.98578, 47.7078], [13.01382, 47.72116], [13.07692, 47.68814], [13.09562, 47.63304], [13.06407, 47.60075], [13.06641, 47.58577], [13.04537, 47.58183], [13.05355, 47.56291], [13.03252, 47.53373], [13.04537, 47.49426], [12.9998, 47.46267], [12.98344, 47.48716], [12.9624, 47.47452], [12.85256, 47.52741], [12.84672, 47.54556], [12.80699, 47.54477], [12.77427, 47.58025], [12.82101, 47.61493], [12.76492, 47.64485], [12.77777, 47.66689], [12.7357, 47.6787], [12.6071, 47.6741], [12.57438, 47.63238], [12.53816, 47.63553], [12.50076, 47.62293], [12.44117, 47.6741], [12.43883, 47.6977], [12.37222, 47.68433], [12.336, 47.69534], [12.27991, 47.68827], [12.26004, 47.67725], [12.24017, 47.69534], [12.26238, 47.73544], [12.2542, 47.7433], [12.22571, 47.71776], [12.18303, 47.70065], [12.16217, 47.70105], [12.16769, 47.68167], [12.18347, 47.66663], [12.18507, 47.65984], [12.19895, 47.64085], [12.20801, 47.61082], [12.20398, 47.60667], [12.18568, 47.6049], [12.17737, 47.60121], [12.18145, 47.61019], [12.17824, 47.61506], [12.13734, 47.60639], [12.05788, 47.61742], [12.02282, 47.61033], [12.0088, 47.62451], [11.85572, 47.60166], [11.84052, 47.58354], [11.63934, 47.59202], [11.60681, 47.57881], [11.58811, 47.55515], [11.58578, 47.52281], [11.52618, 47.50939], [11.4362, 47.51413], [11.38128, 47.47465], [11.4175, 47.44621], [11.33804, 47.44937], [11.29597, 47.42566], [11.27844, 47.39956], [11.22002, 47.3964], [11.25157, 47.43277], [11.20482, 47.43198], [11.12536, 47.41222], [11.11835, 47.39719], [10.97111, 47.39561], [10.97111, 47.41617], [10.98513, 47.42882], [10.92437, 47.46991], [10.93839, 47.48018], [10.90918, 47.48571], [10.87061, 47.4786], [10.86945, 47.5015], [10.91268, 47.51334], [10.88814, 47.53701], [10.77596, 47.51729], [10.7596, 47.53228], [10.6965, 47.54253], [10.68832, 47.55752], [10.63456, 47.5591], [10.60337, 47.56755], [10.56912, 47.53584], [10.48849, 47.54057], [10.47329, 47.58552], [10.43473, 47.58394], [10.44992, 47.5524], [10.4324, 47.50111], [10.44291, 47.48453], [10.46278, 47.47901], [10.47446, 47.43318], [10.4359, 47.41183], [10.4324, 47.38494], [10.39851, 47.37623], [10.33424, 47.30813], [10.23257, 47.27088], [10.17531, 47.27167], [10.17648, 47.29149], [10.2147, 47.31014], [10.19998, 47.32832], [10.23757, 47.37609], [10.22774, 47.38904], [10.2127, 47.38019], [10.17648, 47.38889], [10.16362, 47.36674], [10.11805, 47.37228], [10.09819, 47.35724], [10.06897, 47.40709], [10.1052, 47.4316], [10.09001, 47.46005], [10.07131, 47.45531], [10.03859, 47.48927], [10.00003, 47.48216], [9.96029, 47.53899], [9.92407, 47.53111], [9.87733, 47.54688], [9.87499, 47.52953], [9.8189, 47.54688], [9.82591, 47.58158], [9.80254, 47.59419], [9.76748, 47.5934], [9.72736, 47.53457], [9.55125, 47.53629], [9.56312, 47.49495], [9.58208, 47.48344], [9.59482, 47.46305], [9.60205, 47.46165], [9.60484, 47.46358], [9.60841, 47.47178], [9.62158, 47.45858], [9.62475, 47.45685], [9.6423, 47.45599], [9.65728, 47.45383], [9.65863, 47.44847], [9.64483, 47.43842], [9.6446, 47.43233], [9.65043, 47.41937], [9.65136, 47.40504], [9.6629, 47.39591], [9.67334, 47.39191], [9.67445, 47.38429], [9.6711, 47.37824], [9.66243, 47.37136], [9.65427, 47.36824], [9.62476, 47.36639], [9.59978, 47.34671], [9.58513, 47.31334], [9.55857, 47.29919], [9.54773, 47.2809], [9.53116, 47.27029], [9.56766, 47.24281], [9.55176, 47.22585], [9.56981, 47.21926], [9.58264, 47.20673], [9.56539, 47.17124], [9.62623, 47.14685], [9.63395, 47.08443], [9.61216, 47.07732], [9.60717, 47.06091], [9.87935, 47.01337], [9.88266, 46.93343], [9.98058, 46.91434], [10.10715, 46.84296], [10.22675, 46.86942], [10.24128, 46.93147], [10.30031, 46.92093], [10.36933, 47.00212], [10.48376, 46.93891], [10.47197, 46.85698], [10.54783, 46.84505], [10.66405, 46.87614], [10.75753, 46.82258], [10.72974, 46.78972], [11.00764, 46.76896], [11.10618, 46.92966], [11.33355, 46.99862], [11.50739, 47.00644], [11.74789, 46.98484], [12.19254, 47.09331], [12.21781, 47.03996], [12.11675, 47.01241], [12.2006, 46.88854], [12.27591, 46.88651], [12.38708, 46.71529], [12.59992, 46.6595], [12.94445, 46.60401], [13.27627, 46.56059], [13.64088, 46.53438], [13.7148, 46.5222], [13.89837, 46.52331], [14.00422, 46.48474], [14.04002, 46.49117], [14.12097, 46.47724], [14.15989, 46.43327], [14.28326, 46.44315], [14.314, 46.43327], [14.42608, 46.44614], [14.45877, 46.41717], [14.52176, 46.42617], [14.56463, 46.37208], [14.5942, 46.43434], [14.66892, 46.44936], [14.72185, 46.49974], [14.81836, 46.51046], [14.83549, 46.56614], [14.86419, 46.59411], [14.87129, 46.61], [14.92283, 46.60848], [14.96002, 46.63459], [14.98024, 46.6009], [15.01451, 46.641], [15.14215, 46.66131], [15.23711, 46.63994], [15.41235, 46.65556], [15.45514, 46.63697], [15.46906, 46.61321], [15.54431, 46.6312], [15.55333, 46.64988], [15.54533, 46.66985], [15.59826, 46.68908], [15.62317, 46.67947], [15.63255, 46.68069], [15.6365, 46.6894], [15.6543, 46.69228], [15.6543, 46.70616], [15.67411, 46.70735], [15.69523, 46.69823], [15.72279, 46.69548], [15.73823, 46.70011], [15.76771, 46.69863], [15.78518, 46.70712], [15.8162, 46.71897], [15.87691, 46.7211], [15.94864, 46.68769], [15.98512, 46.68463], [15.99988, 46.67947], [16.04036, 46.6549], [16.04347, 46.68694], [16.02808, 46.71094], [15.99769, 46.7266], [15.98432, 46.74991], [15.99126, 46.78199], [15.99054, 46.82772], [16.05786, 46.83927], [16.10983, 46.867], [16.19904, 46.94134], [16.22403, 46.939], [16.27594, 46.9643], [16.28202, 47.00159], [16.51369, 47.00084], [16.43936, 47.03548], [16.52176, 47.05747], [16.46134, 47.09395], [16.52863, 47.13974], [16.44932, 47.14418], [16.46442, 47.16845], [16.4523, 47.18812], [16.42801, 47.18422], [16.41739, 47.20649], [16.43663, 47.21127], [16.44142, 47.25079], [16.47782, 47.25918], [16.45104, 47.41181], [16.49908, 47.39416], [16.52414, 47.41007], [16.57152, 47.40868], [16.6718, 47.46139], [16.64821, 47.50155], [16.71059, 47.52692], [16.64193, 47.63114], [16.58699, 47.61772], [16.4222, 47.66537], [16.55129, 47.72268], [16.53514, 47.73837], [16.54779, 47.75074], [16.61183, 47.76171], [16.65679, 47.74197], [16.72089, 47.73469], [16.7511, 47.67878], [16.82938, 47.68432], [16.86509, 47.72268], [16.87538, 47.68895], [17.08893, 47.70928], [17.05048, 47.79377], [17.07039, 47.81129], [17.00997, 47.86245], [17.08275, 47.87719], [17.11022, 47.92461], [17.09786, 47.97336], [17.16001, 48.00636], [17.07039, 48.0317], [17.09168, 48.09366], [17.05735, 48.14179], [17.02919, 48.13996], [16.97701, 48.17385], [16.89461, 48.31332], [16.90903, 48.32519], [16.84243, 48.35258], [16.83317, 48.38138], [16.83588, 48.3844], [16.8497, 48.38321], [16.85204, 48.44968], [16.94611, 48.53614], [16.93955, 48.60371], [16.90354, 48.71541], [16.79779, 48.70998], [16.71883, 48.73806], [16.68518, 48.7281], [16.67008, 48.77699], [16.46134, 48.80865], [16.40915, 48.74576], [16.37345, 48.729], [16.06034, 48.75436], [15.84404, 48.86921], [15.78087, 48.87644], [15.75341, 48.8516], [15.6921, 48.85973], [15.61622, 48.89541], [15.51357, 48.91549], [15.48027, 48.94481], [15.34823, 48.98444]]]] } },
23111 { type: "Feature", properties: { iso1A2: "AU", iso1A3: "AUS", iso1N3: "036", wikidata: "Q408", nameEn: "Australia" }, geometry: null },
23112 { type: "Feature", properties: { iso1A2: "AW", iso1A3: "ABW", iso1N3: "533", wikidata: "Q21203", nameEn: "Aruba", aliases: ["NL-AW"], country: "NL", groups: ["Q1451600", "029", "003", "419", "019", "UN"], callingCodes: ["297"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-70.00823, 12.98375], [-70.35625, 12.58277], [-69.60231, 12.17], [-70.00823, 12.98375]]]] } },
23113 { type: "Feature", properties: { iso1A2: "AX", iso1A3: "ALA", iso1N3: "248", wikidata: "Q5689", nameEn: "\xC5land Islands", country: "FI", groups: ["EU", "154", "150", "UN"], callingCodes: ["358 18", "358 457"] }, geometry: { type: "MultiPolygon", coordinates: [[[[19.08191, 60.19152], [20.5104, 59.15546], [21.35468, 59.67511], [21.02509, 60.12142], [21.08159, 60.20167], [21.15143, 60.54555], [20.96741, 60.71528], [19.23413, 60.61414], [19.08191, 60.19152]]]] } },
23114 { type: "Feature", properties: { iso1A2: "AZ", iso1A3: "AZE", iso1N3: "031", wikidata: "Q227", nameEn: "Azerbaijan", groups: ["145", "142", "UN"], callingCodes: ["994"] }, geometry: { type: "MultiPolygon", coordinates: [[[[46.42738, 41.91323], [46.3984, 41.84399], [46.30863, 41.79133], [46.23962, 41.75811], [46.20538, 41.77205], [46.17891, 41.72094], [46.19759, 41.62327], [46.24429, 41.59883], [46.26531, 41.63339], [46.28182, 41.60089], [46.3253, 41.60912], [46.34039, 41.5947], [46.34126, 41.57454], [46.29794, 41.5724], [46.33925, 41.4963], [46.40307, 41.48464], [46.4669, 41.43331], [46.63658, 41.37727], [46.72375, 41.28609], [46.66148, 41.20533], [46.63969, 41.09515], [46.55096, 41.1104], [46.48558, 41.0576], [46.456, 41.09984], [46.37661, 41.10805], [46.27698, 41.19011], [46.13221, 41.19479], [45.95786, 41.17956], [45.80842, 41.2229], [45.69946, 41.29545], [45.75705, 41.35157], [45.71035, 41.36208], [45.68389, 41.3539], [45.45973, 41.45898], [45.4006, 41.42402], [45.31352, 41.47168], [45.26285, 41.46433], [45.1797, 41.42231], [45.09867, 41.34065], [45.0133, 41.29747], [45.05497, 41.2464], [45.02932, 41.2101], [45.05201, 41.19211], [45.11811, 41.19967], [45.1969, 41.168], [45.19942, 41.13299], [45.08028, 41.10917], [45.06784, 41.05379], [45.12923, 41.06059], [45.1313, 41.09369], [45.1634, 41.08082], [45.16493, 41.05068], [45.1994, 41.04518], [45.25897, 41.0027], [45.26162, 41.0228], [45.28859, 41.03757], [45.35677, 40.99784], [45.39725, 41.02603], [45.44083, 41.01663], [45.40814, 40.97904], [45.60584, 40.87436], [45.55914, 40.78366], [45.4206, 40.7424], [45.35366, 40.65979], [45.45484, 40.57707], [45.42994, 40.53804], [45.65098, 40.37696], [45.95609, 40.27846], [45.97944, 40.181], [45.83779, 39.98925], [45.78642, 40.03218], [45.59806, 40.0131], [45.60895, 39.97733], [45.7833, 39.9475], [45.82533, 39.82925], [45.96543, 39.78859], [46.18493, 39.60533], [46.40286, 39.63651], [46.42465, 39.57534], [46.52117, 39.58734], [46.57098, 39.56694], [46.57721, 39.54414], [46.51027, 39.52373], [46.53051, 39.47809], [46.4013, 39.45405], [46.37795, 39.42039], [46.43244, 39.35181], [46.50093, 39.33736], [46.56476, 39.24942], [46.63481, 39.23013], [46.58032, 39.21204], [46.54141, 39.15895], [46.52584, 39.18912], [46.44022, 39.19636], [46.54296, 39.07078], [46.51805, 38.94982], [46.53497, 38.86548], [46.75752, 39.03231], [46.83822, 39.13143], [46.92539, 39.16644], [46.95341, 39.13505], [47.05771, 39.20143], [47.05927, 39.24846], [47.31301, 39.37492], [47.38978, 39.45999], [47.50099, 39.49615], [47.84774, 39.66285], [47.98977, 39.70999], [48.34264, 39.42935], [48.37385, 39.37584], [48.15984, 39.30028], [48.12404, 39.25208], [48.15361, 39.19419], [48.31239, 39.09278], [48.33884, 39.03022], [48.28437, 38.97186], [48.08627, 38.94434], [48.07734, 38.91616], [48.01409, 38.90333], [48.02581, 38.82705], [48.24773, 38.71883], [48.3146, 38.59958], [48.45084, 38.61013], [48.58793, 38.45076], [48.62217, 38.40198], [48.70001, 38.40564], [48.78979, 38.45026], [48.81072, 38.44853], [48.84969, 38.45015], [48.88288, 38.43975], [52.39847, 39.43556], [48.80971, 41.95365], [48.5867, 41.84306], [48.55078, 41.77917], [48.42301, 41.65444], [48.40277, 41.60441], [48.2878, 41.56221], [48.22064, 41.51472], [48.07587, 41.49957], [47.87973, 41.21798], [47.75831, 41.19455], [47.62288, 41.22969], [47.54504, 41.20275], [47.49004, 41.26366], [47.34579, 41.27884], [47.10762, 41.59044], [47.03757, 41.55434], [46.99554, 41.59743], [47.00955, 41.63583], [46.8134, 41.76252], [46.75269, 41.8623], [46.58924, 41.80547], [46.5332, 41.87389], [46.42738, 41.91323]], [[45.50279, 40.58424], [45.47927, 40.65023], [45.51825, 40.67382], [45.56071, 40.64765], [45.50279, 40.58424]]], [[[45.00864, 41.03411], [45.03792, 41.03938], [45.04517, 41.06653], [45.03406, 41.07931], [45.00864, 41.09407], [44.97169, 41.09176], [44.95383, 41.07553], [44.96031, 41.06345], [44.9903, 41.05657], [45.00864, 41.03411]]], [[[45.21324, 40.9817], [45.23095, 40.97828], [45.23487, 41.00226], [45.20625, 41.01484], [45.18382, 41.0066], [45.19312, 40.98998], [45.20518, 40.99348], [45.21219, 40.99001], [45.21324, 40.9817]]], [[[45.46992, 39.49888], [45.29606, 39.57654], [45.30385, 39.61373], [45.23535, 39.61373], [45.21784, 39.58074], [45.17464, 39.58614], [45.18554, 39.67846], [45.06604, 39.79277], [44.92869, 39.72157], [44.88354, 39.74432], [44.75779, 39.7148], [44.80977, 39.65768], [44.81043, 39.62677], [44.88916, 39.59653], [44.96746, 39.42998], [45.05932, 39.36435], [45.08751, 39.35052], [45.16168, 39.21952], [45.30489, 39.18333], [45.40148, 39.09007], [45.40452, 39.07224], [45.44811, 39.04927], [45.44966, 38.99243], [45.6131, 38.964], [45.6155, 38.94304], [45.65172, 38.95199], [45.83883, 38.90768], [45.90266, 38.87739], [45.94624, 38.89072], [46.00228, 38.87376], [46.06766, 38.87861], [46.14785, 38.84206], [46.06973, 39.0744], [46.02303, 39.09978], [45.99774, 39.28931], [45.79225, 39.3695], [45.83, 39.46487], [45.80804, 39.56716], [45.70547, 39.60174], [45.46992, 39.49888]]]] } },
23115 { type: "Feature", properties: { iso1A2: "BA", iso1A3: "BIH", iso1N3: "070", wikidata: "Q225", nameEn: "Bosnia and Herzegovina", groups: ["039", "150", "UN"], callingCodes: ["387"] }, geometry: { type: "MultiPolygon", coordinates: [[[[17.84826, 45.04489], [17.66571, 45.13408], [17.59104, 45.10816], [17.51469, 45.10791], [17.47589, 45.12656], [17.45615, 45.12523], [17.4498, 45.16119], [17.41229, 45.13335], [17.33573, 45.14521], [17.32092, 45.16246], [17.26815, 45.18444], [17.25131, 45.14957], [17.24325, 45.146], [17.18438, 45.14764], [17.0415, 45.20759], [16.9385, 45.22742], [16.92405, 45.27607], [16.83804, 45.18951], [16.81137, 45.18434], [16.78219, 45.19002], [16.74845, 45.20393], [16.64962, 45.20714], [16.60194, 45.23042], [16.56559, 45.22307], [16.5501, 45.2212], [16.52982, 45.22713], [16.49155, 45.21153], [16.4634, 45.14522], [16.40023, 45.1147], [16.38309, 45.05955], [16.38219, 45.05139], [16.3749, 45.05206], [16.35863, 45.03529], [16.35404, 45.00241], [16.29036, 44.99732], [16.12153, 45.09616], [15.98412, 45.23088], [15.83512, 45.22459], [15.76371, 45.16508], [15.78842, 45.11519], [15.74585, 45.0638], [15.78568, 44.97401], [15.74723, 44.96818], [15.76096, 44.87045], [15.79472, 44.8455], [15.72584, 44.82334], [15.8255, 44.71501], [15.89348, 44.74964], [16.05828, 44.61538], [16.00884, 44.58605], [16.03012, 44.55572], [16.10566, 44.52586], [16.16814, 44.40679], [16.12969, 44.38275], [16.21346, 44.35231], [16.18688, 44.27012], [16.36864, 44.08263], [16.43662, 44.07523], [16.43629, 44.02826], [16.50528, 44.0244], [16.55472, 43.95326], [16.70922, 43.84887], [16.75316, 43.77157], [16.80736, 43.76011], [17.00585, 43.58037], [17.15828, 43.49376], [17.24411, 43.49376], [17.29699, 43.44542], [17.25579, 43.40353], [17.286, 43.33065], [17.46986, 43.16559], [17.64268, 43.08595], [17.70879, 42.97223], [17.5392, 42.92787], [17.6444, 42.88641], [17.68151, 42.92725], [17.7948, 42.89556], [17.80854, 42.9182], [17.88201, 42.83668], [18.24318, 42.6112], [18.36197, 42.61423], [18.43735, 42.55921], [18.49778, 42.58409], [18.53751, 42.57376], [18.55504, 42.58409], [18.52232, 42.62279], [18.57373, 42.64429], [18.54841, 42.68328], [18.54603, 42.69171], [18.55221, 42.69045], [18.56789, 42.72074], [18.47324, 42.74992], [18.45921, 42.81682], [18.47633, 42.85829], [18.4935, 42.86433], [18.49661, 42.89306], [18.49076, 42.95553], [18.52232, 43.01451], [18.66254, 43.03928], [18.64735, 43.14766], [18.66605, 43.2056], [18.71747, 43.2286], [18.6976, 43.25243], [18.76538, 43.29838], [18.85342, 43.32426], [18.84794, 43.33735], [18.83912, 43.34795], [18.90911, 43.36383], [18.95819, 43.32899], [18.95001, 43.29327], [19.00844, 43.24988], [19.04233, 43.30008], [19.08206, 43.29668], [19.08673, 43.31453], [19.04071, 43.397], [19.01078, 43.43854], [18.96053, 43.45042], [18.95469, 43.49367], [18.91379, 43.50299], [19.01078, 43.55806], [19.04934, 43.50384], [19.13933, 43.5282], [19.15685, 43.53943], [19.22807, 43.5264], [19.24774, 43.53061], [19.2553, 43.5938], [19.33426, 43.58833], [19.36653, 43.60921], [19.41941, 43.54056], [19.42696, 43.57987], [19.50455, 43.58385], [19.5176, 43.71403], [19.3986, 43.79668], [19.23465, 43.98764], [19.24363, 44.01502], [19.38439, 43.96611], [19.52515, 43.95573], [19.56498, 43.99922], [19.61836, 44.01464], [19.61991, 44.05254], [19.57467, 44.04716], [19.55999, 44.06894], [19.51167, 44.08158], [19.47321, 44.1193], [19.48386, 44.14332], [19.47338, 44.15034], [19.43905, 44.13088], [19.40927, 44.16722], [19.3588, 44.18353], [19.34773, 44.23244], [19.32464, 44.27185], [19.26945, 44.26957], [19.23306, 44.26097], [19.20508, 44.2917], [19.18328, 44.28383], [19.16741, 44.28648], [19.13332, 44.31492], [19.13556, 44.338], [19.11547, 44.34218], [19.1083, 44.3558], [19.11865, 44.36712], [19.10298, 44.36924], [19.10365, 44.37795], [19.10704, 44.38249], [19.10749, 44.39421], [19.11785, 44.40313], [19.14681, 44.41463], [19.14837, 44.45253], [19.12278, 44.50132], [19.13369, 44.52521], [19.16699, 44.52197], [19.26388, 44.65412], [19.32543, 44.74058], [19.36722, 44.88164], [19.18183, 44.92055], [19.01994, 44.85493], [18.8704, 44.85097], [18.76347, 44.90669], [18.76369, 44.93707], [18.80661, 44.93561], [18.78357, 44.97741], [18.65723, 45.07544], [18.47939, 45.05871], [18.41896, 45.11083], [18.32077, 45.1021], [18.24387, 45.13699], [18.1624, 45.07654], [18.03121, 45.12632], [18.01594, 45.15163], [17.99479, 45.14958], [17.97834, 45.13831], [17.97336, 45.12245], [17.93706, 45.08016], [17.87148, 45.04645], [17.84826, 45.04489]]]] } },
23116 { type: "Feature", properties: { iso1A2: "BB", iso1A3: "BRB", iso1N3: "052", wikidata: "Q244", nameEn: "Barbados", groups: ["029", "003", "419", "019", "UN"], driveSide: "left", callingCodes: ["1 246"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-58.56442, 13.24471], [-59.80731, 13.87556], [-59.82929, 12.70644], [-58.56442, 13.24471]]]] } },
23117 { type: "Feature", properties: { iso1A2: "BD", iso1A3: "BGD", iso1N3: "050", wikidata: "Q902", nameEn: "Bangladesh", groups: ["034", "142", "UN"], driveSide: "left", callingCodes: ["880"] }, geometry: { type: "MultiPolygon", coordinates: [[[[89.15869, 26.13708], [89.08899, 26.38845], [88.95612, 26.4564], [88.92357, 26.40711], [88.91321, 26.37984], [89.05328, 26.2469], [88.85004, 26.23211], [88.78961, 26.31093], [88.67837, 26.26291], [88.69485, 26.38353], [88.62144, 26.46783], [88.4298, 26.54489], [88.41196, 26.63837], [88.33093, 26.48929], [88.35153, 26.45241], [88.36938, 26.48683], [88.48749, 26.45855], [88.51649, 26.35923], [88.35153, 26.29123], [88.34757, 26.22216], [88.1844, 26.14417], [88.16581, 26.0238], [88.08804, 25.91334], [88.13138, 25.78773], [88.242, 25.80811], [88.45103, 25.66245], [88.4559, 25.59227], [88.677, 25.46959], [88.81296, 25.51546], [88.85278, 25.34679], [89.01105, 25.30303], [89.00463, 25.26583], [88.94067, 25.18534], [88.44766, 25.20149], [88.46277, 25.07468], [88.33917, 24.86803], [88.27325, 24.88796], [88.21832, 24.96642], [88.14004, 24.93529], [88.15515, 24.85806], [88.00683, 24.66477], [88.08786, 24.63232], [88.12296, 24.51301], [88.50934, 24.32474], [88.68801, 24.31464], [88.74841, 24.1959], [88.6976, 24.14703], [88.73743, 23.91751], [88.66189, 23.87607], [88.58087, 23.87105], [88.56507, 23.64044], [88.74841, 23.47361], [88.79351, 23.50535], [88.79254, 23.46028], [88.71133, 23.2492], [88.99148, 23.21134], [88.86377, 23.08759], [88.88327, 23.03885], [88.87063, 22.95235], [88.96713, 22.83346], [88.9151, 22.75228], [88.94614, 22.66941], [88.9367, 22.58527], [89.07114, 22.15335], [89.08044, 21.41871], [92.47409, 20.38654], [92.26071, 21.05697], [92.17752, 21.17445], [92.20087, 21.337], [92.37939, 21.47764], [92.43158, 21.37025], [92.55105, 21.3856], [92.60187, 21.24615], [92.68152, 21.28454], [92.59775, 21.6092], [92.62187, 21.87037], [92.60949, 21.97638], [92.56616, 22.13554], [92.60029, 22.1522], [92.5181, 22.71441], [92.37665, 22.9435], [92.38214, 23.28705], [92.26541, 23.70392], [92.15417, 23.73409], [92.04706, 23.64229], [91.95093, 23.73284], [91.95642, 23.47361], [91.84789, 23.42235], [91.76417, 23.26619], [91.81634, 23.08001], [91.7324, 23.00043], [91.61571, 22.93929], [91.54993, 23.01051], [91.46615, 23.2328], [91.4035, 23.27522], [91.40848, 23.07117], [91.36453, 23.06612], [91.28293, 23.37538], [91.15579, 23.6599], [91.25192, 23.83463], [91.22308, 23.89616], [91.29587, 24.0041], [91.35741, 23.99072], [91.37414, 24.10693], [91.55542, 24.08687], [91.63782, 24.1132], [91.65292, 24.22095], [91.73257, 24.14703], [91.76004, 24.23848], [91.82596, 24.22345], [91.89258, 24.14674], [91.96603, 24.3799], [92.11662, 24.38997], [92.15796, 24.54435], [92.25854, 24.9191], [92.38626, 24.86055], [92.49887, 24.88796], [92.39147, 25.01471], [92.33957, 25.07593], [92.0316, 25.1834], [91.63648, 25.12846], [91.25517, 25.20677], [90.87427, 25.15799], [90.65042, 25.17788], [90.40034, 25.1534], [90.1155, 25.22686], [89.90478, 25.31038], [89.87629, 25.28337], [89.83371, 25.29548], [89.84086, 25.31854], [89.81208, 25.37244], [89.86129, 25.61714], [89.84388, 25.70042], [89.80585, 25.82489], [89.86592, 25.93115], [89.77728, 26.04254], [89.77865, 26.08387], [89.73581, 26.15818], [89.70201, 26.15138], [89.63968, 26.22595], [89.57101, 25.9682], [89.53515, 26.00382], [89.35953, 26.0077], [89.15869, 26.13708]]]] } },
23118 { type: "Feature", properties: { iso1A2: "BE", iso1A3: "BEL", iso1N3: "056", wikidata: "Q31", nameEn: "Belgium", groups: ["EU", "155", "150", "UN"], callingCodes: ["32"] }, geometry: { type: "MultiPolygon", coordinates: [[[[4.93295, 51.44945], [4.93909, 51.44632], [4.9524, 51.45014], [4.95244, 51.45207], [4.93295, 51.44945]]], [[[4.91493, 51.4353], [4.92652, 51.43329], [4.92952, 51.42984], [4.93986, 51.43064], [4.94265, 51.44003], [4.93471, 51.43861], [4.93416, 51.44185], [4.94025, 51.44193], [4.93544, 51.44634], [4.92879, 51.44161], [4.92815, 51.43856], [4.92566, 51.44273], [4.92811, 51.4437], [4.92287, 51.44741], [4.91811, 51.44621], [4.92227, 51.44252], [4.91935, 51.43634], [4.91493, 51.4353]]], [[[4.82946, 51.4213], [4.82409, 51.44736], [4.84139, 51.4799], [4.78803, 51.50284], [4.77321, 51.50529], [4.74578, 51.48937], [4.72935, 51.48424], [4.65442, 51.42352], [4.57489, 51.4324], [4.53521, 51.4243], [4.52846, 51.45002], [4.54675, 51.47265], [4.5388, 51.48184], [4.47736, 51.4778], [4.38122, 51.44905], [4.39747, 51.43316], [4.38064, 51.41965], [4.43777, 51.36989], [4.39292, 51.35547], [4.34086, 51.35738], [4.33265, 51.37687], [4.21923, 51.37443], [4.24024, 51.35371], [4.16721, 51.29348], [4.05165, 51.24171], [4.01957, 51.24504], [3.97889, 51.22537], [3.90125, 51.20371], [3.78783, 51.2151], [3.78999, 51.25766], [3.58939, 51.30064], [3.51502, 51.28697], [3.52698, 51.2458], [3.43488, 51.24135], [3.41704, 51.25933], [3.38289, 51.27331], [3.35847, 51.31572], [3.38696, 51.33436], [3.36263, 51.37112], [2.56575, 51.85301], [2.18458, 51.52087], [2.55904, 51.07014], [2.57551, 51.00326], [2.63074, 50.94746], [2.59093, 50.91751], [2.63331, 50.81457], [2.71165, 50.81295], [2.81056, 50.71773], [2.8483, 50.72276], [2.86985, 50.7033], [2.87937, 50.70298], [2.88504, 50.70656], [2.90069, 50.69263], [2.91036, 50.6939], [2.90873, 50.702], [2.95019, 50.75138], [2.96778, 50.75242], [3.00537, 50.76588], [3.04314, 50.77674], [3.09163, 50.77717], [3.10614, 50.78303], [3.11206, 50.79416], [3.11987, 50.79188], [3.1257, 50.78603], [3.15017, 50.79031], [3.16476, 50.76843], [3.18339, 50.74981], [3.18811, 50.74025], [3.20064, 50.73547], [3.19017, 50.72569], [3.20845, 50.71662], [3.22042, 50.71019], [3.24593, 50.71389], [3.26063, 50.70086], [3.26141, 50.69151], [3.2536, 50.68977], [3.264, 50.67668], [3.23951, 50.6585], [3.2729, 50.60718], [3.28575, 50.52724], [3.37693, 50.49538], [3.44629, 50.51009], [3.47385, 50.53397], [3.51564, 50.5256], [3.49509, 50.48885], [3.5683, 50.50192], [3.58361, 50.49049], [3.61014, 50.49568], [3.64426, 50.46275], [3.66153, 50.45165], [3.67494, 50.40239], [3.67262, 50.38663], [3.65709, 50.36873], [3.66976, 50.34563], [3.71009, 50.30305], [3.70987, 50.3191], [3.73911, 50.34809], [3.84314, 50.35219], [3.90781, 50.32814], [3.96771, 50.34989], [4.0268, 50.35793], [4.0689, 50.3254], [4.10237, 50.31247], [4.10957, 50.30234], [4.11954, 50.30425], [4.13665, 50.25609], [4.16808, 50.25786], [4.15524, 50.2833], [4.17347, 50.28838], [4.17861, 50.27443], [4.20651, 50.27333], [4.21945, 50.25539], [4.15524, 50.21103], [4.16014, 50.19239], [4.13561, 50.13078], [4.20147, 50.13535], [4.23101, 50.06945], [4.16294, 50.04719], [4.13508, 50.01976], [4.14239, 49.98034], [4.20532, 49.95803], [4.31963, 49.97043], [4.35051, 49.95315], [4.43488, 49.94122], [4.51098, 49.94659], [4.5414, 49.96911], [4.68695, 49.99685], [4.70064, 50.09384], [4.75237, 50.11314], [4.82438, 50.16878], [4.83279, 50.15331], [4.88602, 50.15182], [4.8382, 50.06738], [4.78827, 49.95609], [4.88529, 49.9236], [4.85134, 49.86457], [4.86965, 49.82271], [4.85464, 49.78995], [4.96714, 49.79872], [5.09249, 49.76193], [5.14545, 49.70287], [5.26232, 49.69456], [5.31465, 49.66846], [5.33039, 49.6555], [5.30214, 49.63055], [5.3137, 49.61225], [5.33851, 49.61599], [5.34837, 49.62889], [5.3974, 49.61596], [5.43713, 49.5707], [5.46734, 49.52648], [5.46541, 49.49825], [5.55001, 49.52729], [5.60909, 49.51228], [5.64505, 49.55146], [5.75649, 49.54321], [5.7577, 49.55915], [5.77435, 49.56298], [5.79195, 49.55228], [5.81838, 49.54777], [5.84143, 49.5533], [5.84692, 49.55663], [5.8424, 49.56082], [5.87256, 49.57539], [5.86986, 49.58756], [5.84971, 49.58674], [5.84826, 49.5969], [5.8762, 49.60898], [5.87609, 49.62047], [5.88393, 49.62802], [5.88552, 49.63507], [5.90599, 49.63853], [5.90164, 49.6511], [5.9069, 49.66377], [5.86175, 49.67862], [5.86527, 49.69291], [5.88677, 49.70951], [5.86503, 49.72739], [5.84193, 49.72161], [5.82562, 49.72395], [5.83149, 49.74729], [5.82245, 49.75048], [5.78871, 49.7962], [5.75409, 49.79239], [5.74953, 49.81428], [5.74364, 49.82058], [5.74844, 49.82435], [5.7404, 49.83452], [5.74076, 49.83823], [5.74975, 49.83933], [5.74953, 49.84709], [5.75884, 49.84811], [5.74567, 49.85368], [5.75861, 49.85631], [5.75269, 49.8711], [5.78415, 49.87922], [5.73621, 49.89796], [5.77314, 49.93646], [5.77291, 49.96056], [5.80833, 49.96451], [5.81163, 49.97142], [5.83467, 49.97823], [5.83968, 49.9892], [5.82331, 49.99662], [5.81866, 50.01286], [5.8551, 50.02683], [5.86904, 50.04614], [5.85474, 50.06342], [5.8857, 50.07824], [5.89488, 50.11476], [5.95929, 50.13295], [5.96453, 50.17259], [6.02488, 50.18283], [6.03093, 50.16362], [6.06406, 50.15344], [6.08577, 50.17246], [6.12028, 50.16374], [6.1137, 50.13668], [6.1379, 50.12964], [6.15298, 50.14126], [6.14132, 50.14971], [6.14588, 50.17106], [6.18739, 50.1822], [6.18364, 50.20815], [6.16853, 50.2234], [6.208, 50.25179], [6.28797, 50.27458], [6.29949, 50.30887], [6.32488, 50.32333], [6.35701, 50.31139], [6.40641, 50.32425], [6.40785, 50.33557], [6.3688, 50.35898], [6.34406, 50.37994], [6.36852, 50.40776], [6.37219, 50.45397], [6.34005, 50.46083], [6.3465, 50.48833], [6.30809, 50.50058], [6.26637, 50.50272], [6.22335, 50.49578], [6.20599, 50.52089], [6.19193, 50.5212], [6.18716, 50.52653], [6.19579, 50.5313], [6.19735, 50.53576], [6.17802, 50.54179], [6.17739, 50.55875], [6.20281, 50.56952], [6.22581, 50.5907], [6.24005, 50.58732], [6.24888, 50.59869], [6.2476, 50.60392], [6.26957, 50.62444], [6.17852, 50.6245], [6.11707, 50.72231], [6.04428, 50.72861], [6.0406, 50.71848], [6.0326, 50.72647], [6.03889, 50.74618], [6.01976, 50.75398], [5.97545, 50.75441], [5.95942, 50.7622], [5.89132, 50.75124], [5.89129, 50.75125], [5.88734, 50.77092], [5.84888, 50.75448], [5.84548, 50.76542], [5.80673, 50.7558], [5.77513, 50.78308], [5.76533, 50.78159], [5.74356, 50.7691], [5.73904, 50.75674], [5.72216, 50.76398], [5.69469, 50.75529], [5.68091, 50.75804], [5.70107, 50.7827], [5.68995, 50.79641], [5.70118, 50.80764], [5.65259, 50.82309], [5.64009, 50.84742], [5.64504, 50.87107], [5.67886, 50.88142], [5.69858, 50.91046], [5.71626, 50.90796], [5.72644, 50.91167], [5.72545, 50.92312], [5.74644, 50.94723], [5.75927, 50.95601], [5.74752, 50.96202], [5.72875, 50.95428], [5.71864, 50.96092], [5.76242, 50.99703], [5.77688, 51.02483], [5.75961, 51.03113], [5.77258, 51.06196], [5.79835, 51.05834], [5.79903, 51.09371], [5.82921, 51.09328], [5.83226, 51.10585], [5.8109, 51.10861], [5.80798, 51.11661], [5.85508, 51.14445], [5.82564, 51.16753], [5.77697, 51.1522], [5.77735, 51.17845], [5.74617, 51.18928], [5.70344, 51.1829], [5.65528, 51.18736], [5.65145, 51.19788], [5.5603, 51.22249], [5.5569, 51.26544], [5.515, 51.29462], [5.48476, 51.30053], [5.46519, 51.2849], [5.4407, 51.28169], [5.41672, 51.26248], [5.347, 51.27502], [5.33886, 51.26314], [5.29716, 51.26104], [5.26461, 51.26693], [5.23814, 51.26064], [5.22542, 51.26888], [5.24244, 51.30495], [5.2002, 51.32243], [5.16222, 51.31035], [5.13377, 51.31592], [5.13105, 51.34791], [5.07102, 51.39469], [5.10456, 51.43163], [5.07891, 51.4715], [5.04774, 51.47022], [5.03281, 51.48679], [5.0106, 51.47167], [5.00393, 51.44406], [4.92152, 51.39487], [4.90016, 51.41404], [4.84988, 51.41502], [4.78941, 51.41102], [4.77229, 51.41337], [4.76577, 51.43046], [4.78314, 51.43319], [4.82946, 51.4213]]]] } },
23119 { type: "Feature", properties: { iso1A2: "BF", iso1A3: "BFA", iso1N3: "854", wikidata: "Q965", nameEn: "Burkina Faso", groups: ["011", "202", "002", "UN"], callingCodes: ["226"] }, geometry: { type: "MultiPolygon", coordinates: [[[[0.23859, 15.00135], [0.06588, 14.96961], [-0.24673, 15.07805], [-0.72004, 15.08655], [-1.05875, 14.7921], [-1.32166, 14.72774], [-1.68083, 14.50023], [-1.97945, 14.47709], [-1.9992, 14.19011], [-2.10223, 14.14878], [-2.47587, 14.29671], [-2.66175, 14.14713], [-2.84667, 14.05532], [-2.90831, 13.81174], [-2.88189, 13.64921], [-3.26407, 13.70699], [-3.28396, 13.5422], [-3.23599, 13.29035], [-3.43507, 13.27272], [-3.4313, 13.1588], [-3.54454, 13.1781], [-3.7911, 13.36665], [-3.96282, 13.38164], [-3.90558, 13.44375], [-3.96501, 13.49778], [-4.34477, 13.12927], [-4.21819, 12.95722], [-4.238, 12.71467], [-4.47356, 12.71252], [-4.41412, 12.31922], [-4.57703, 12.19875], [-4.54841, 12.1385], [-4.62546, 12.13204], [-4.62987, 12.06531], [-4.70692, 12.06746], [-4.72893, 12.01579], [-5.07897, 11.97918], [-5.26389, 11.84778], [-5.40258, 11.8327], [-5.26389, 11.75728], [-5.29251, 11.61715], [-5.22867, 11.60421], [-5.20665, 11.43811], [-5.25509, 11.36905], [-5.25949, 11.24816], [-5.32553, 11.21578], [-5.32994, 11.13371], [-5.49284, 11.07538], [-5.41579, 10.84628], [-5.47083, 10.75329], [-5.46643, 10.56074], [-5.51058, 10.43177], [-5.39602, 10.2929], [-5.12465, 10.29788], [-4.96453, 9.99923], [-4.96621, 9.89132], [-4.6426, 9.70696], [-4.31392, 9.60062], [-4.25999, 9.76012], [-3.69703, 9.94279], [-3.31779, 9.91125], [-3.27228, 9.84981], [-3.19306, 9.93781], [-3.16609, 9.85147], [-3.00765, 9.74019], [-2.93012, 9.57403], [-2.76494, 9.40778], [-2.68802, 9.49343], [-2.76534, 9.56589], [-2.74174, 9.83172], [-2.83108, 10.40252], [-2.94232, 10.64281], [-2.83373, 11.0067], [-0.67143, 10.99811], [-0.61937, 10.91305], [-0.44298, 11.04292], [-0.42391, 11.11661], [-0.38219, 11.12596], [-0.35955, 11.07801], [-0.28566, 11.12713], [-0.27374, 11.17157], [-0.13493, 11.14075], [0.50388, 11.01011], [0.48852, 10.98561], [0.50521, 10.98035], [0.4958, 10.93269], [0.66104, 10.99964], [0.91245, 10.99597], [0.9813, 11.08876], [1.03409, 11.04719], [1.42823, 11.46822], [2.00988, 11.42227], [2.29983, 11.68254], [2.39723, 11.89473], [2.05785, 12.35539], [2.26349, 12.41915], [0.99167, 13.10727], [0.99253, 13.37515], [1.18873, 13.31771], [1.21217, 13.37853], [1.24516, 13.33968], [1.28509, 13.35488], [1.24429, 13.39373], [1.20088, 13.38951], [1.02813, 13.46635], [0.99514, 13.5668], [0.77637, 13.64442], [0.77377, 13.6866], [0.61924, 13.68491], [0.38051, 14.05575], [0.16936, 14.51654], [0.23859, 15.00135]]]] } },
23120 { type: "Feature", properties: { iso1A2: "BG", iso1A3: "BGR", iso1N3: "100", wikidata: "Q219", nameEn: "Bulgaria", groups: ["EU", "151", "150", "UN"], callingCodes: ["359"] }, geometry: { type: "MultiPolygon", coordinates: [[[[23.05288, 43.79494], [22.85314, 43.84452], [22.83753, 43.88055], [22.87873, 43.9844], [23.01674, 44.01946], [23.04988, 44.07694], [22.67173, 44.21564], [22.61711, 44.16938], [22.61688, 44.06534], [22.41449, 44.00514], [22.35558, 43.81281], [22.41043, 43.69566], [22.47582, 43.6558], [22.53397, 43.47225], [22.82036, 43.33665], [22.89727, 43.22417], [23.00806, 43.19279], [22.98104, 43.11199], [22.89521, 43.03625], [22.78397, 42.98253], [22.74826, 42.88701], [22.54302, 42.87774], [22.43309, 42.82057], [22.4997, 42.74144], [22.43983, 42.56851], [22.55669, 42.50144], [22.51961, 42.3991], [22.47498, 42.3915], [22.45919, 42.33822], [22.34773, 42.31725], [22.38136, 42.30339], [22.47251, 42.20393], [22.50289, 42.19527], [22.51224, 42.15457], [22.67701, 42.06614], [22.86749, 42.02275], [22.90254, 41.87587], [22.96682, 41.77137], [23.01239, 41.76527], [23.03342, 41.71034], [22.95513, 41.63265], [22.96331, 41.35782], [22.93334, 41.34104], [23.1833, 41.31755], [23.21953, 41.33773], [23.22771, 41.37106], [23.31301, 41.40525], [23.33639, 41.36317], [23.40416, 41.39999], [23.52453, 41.40262], [23.63203, 41.37632], [23.67644, 41.41139], [23.76525, 41.40175], [23.80148, 41.43943], [23.89613, 41.45257], [23.91483, 41.47971], [23.96975, 41.44118], [24.06908, 41.46132], [24.06323, 41.53222], [24.10063, 41.54796], [24.18126, 41.51735], [24.27124, 41.57682], [24.30513, 41.51297], [24.52599, 41.56808], [24.61129, 41.42278], [24.71529, 41.41928], [24.8041, 41.34913], [24.82514, 41.4035], [24.86136, 41.39298], [24.90928, 41.40876], [24.942, 41.38685], [25.11611, 41.34212], [25.28322, 41.23411], [25.48187, 41.28506], [25.52394, 41.2798], [25.55082, 41.31667], [25.61042, 41.30614], [25.66183, 41.31316], [25.70507, 41.29209], [25.8266, 41.34563], [25.87919, 41.30526], [26.12926, 41.35878], [26.16548, 41.42278], [26.20288, 41.43943], [26.14796, 41.47533], [26.176, 41.50072], [26.17951, 41.55409], [26.14328, 41.55496], [26.15146, 41.60828], [26.07083, 41.64584], [26.06148, 41.70345], [26.16841, 41.74858], [26.21325, 41.73223], [26.22888, 41.74139], [26.2654, 41.71544], [26.30255, 41.70925], [26.35957, 41.71149], [26.32952, 41.73637], [26.33589, 41.76802], [26.36952, 41.82265], [26.53968, 41.82653], [26.57961, 41.90024], [26.56051, 41.92995], [26.62996, 41.97644], [26.79143, 41.97386], [26.95638, 42.00741], [27.03277, 42.0809], [27.08486, 42.08735], [27.19251, 42.06028], [27.22376, 42.10152], [27.27411, 42.10409], [27.45478, 41.96591], [27.52379, 41.93756], [27.55191, 41.90928], [27.69949, 41.97515], [27.81235, 41.94803], [27.83492, 41.99709], [27.91479, 41.97902], [28.02971, 41.98066], [28.32297, 41.98371], [29.24336, 43.70874], [28.23293, 43.76], [27.99558, 43.84193], [27.92008, 44.00761], [27.73468, 43.95326], [27.64542, 44.04958], [27.60834, 44.01206], [27.39757, 44.0141], [27.26845, 44.12602], [26.95141, 44.13555], [26.62712, 44.05698], [26.38764, 44.04356], [26.10115, 43.96908], [26.05584, 43.90925], [25.94911, 43.85745], [25.72792, 43.69263], [25.39528, 43.61866], [25.17144, 43.70261], [25.10718, 43.6831], [24.96682, 43.72693], [24.73542, 43.68523], [24.62281, 43.74082], [24.50264, 43.76314], [24.35364, 43.70211], [24.18149, 43.68218], [23.73978, 43.80627], [23.61687, 43.79289], [23.4507, 43.84936], [23.26772, 43.84843], [23.05288, 43.79494]]]] } },
23121 { type: "Feature", properties: { iso1A2: "BH", iso1A3: "BHR", iso1N3: "048", wikidata: "Q398", nameEn: "Bahrain", groups: ["145", "142", "UN"], callingCodes: ["973"] }, geometry: { type: "MultiPolygon", coordinates: [[[[50.93865, 26.30758], [50.71771, 26.73086], [50.38162, 26.53976], [50.26923, 26.08243], [50.302, 25.87592], [50.57069, 25.57887], [50.80824, 25.54641], [50.7801, 25.595], [50.86149, 25.6965], [50.81266, 25.88946], [50.93865, 26.30758]]]] } },
23122 { type: "Feature", properties: { iso1A2: "BI", iso1A3: "BDI", iso1N3: "108", wikidata: "Q967", nameEn: "Burundi", groups: ["014", "202", "002", "UN"], callingCodes: ["257"] }, geometry: { type: "MultiPolygon", coordinates: [[[[30.54501, -2.41404], [30.42933, -2.31064], [30.14034, -2.43626], [29.95911, -2.33348], [29.88237, -2.75105], [29.36805, -2.82933], [29.32234, -2.6483], [29.0562, -2.58632], [29.04081, -2.7416], [29.00167, -2.78523], [29.00404, -2.81978], [29.0505, -2.81774], [29.09119, -2.87871], [29.09797, -2.91935], [29.16037, -2.95457], [29.17258, -2.99385], [29.25633, -3.05471], [29.21463, -3.3514], [29.23708, -3.75856], [29.43673, -4.44845], [29.63827, -4.44681], [29.75109, -4.45836], [29.77289, -4.41733], [29.82885, -4.36153], [29.88172, -4.35743], [30.03323, -4.26631], [30.22042, -4.01738], [30.45915, -3.56532], [30.84165, -3.25152], [30.83823, -2.97837], [30.6675, -2.98987], [30.57926, -2.89791], [30.4987, -2.9573], [30.40662, -2.86151], [30.52747, -2.65841], [30.41789, -2.66266], [30.54501, -2.41404]]]] } },
23123 { type: "Feature", properties: { iso1A2: "BJ", iso1A3: "BEN", iso1N3: "204", wikidata: "Q962", nameEn: "Benin", aliases: ["DY"], groups: ["011", "202", "002", "UN"], callingCodes: ["229"] }, geometry: { type: "MultiPolygon", coordinates: [[[[3.59375, 11.70269], [3.48187, 11.86092], [3.31613, 11.88495], [3.25352, 12.01467], [2.83978, 12.40585], [2.6593, 12.30631], [2.37783, 12.24804], [2.39657, 12.10952], [2.45824, 11.98672], [2.39723, 11.89473], [2.29983, 11.68254], [2.00988, 11.42227], [1.42823, 11.46822], [1.03409, 11.04719], [0.9813, 11.08876], [0.91245, 10.99597], [0.8804, 10.803], [0.80358, 10.71459], [0.77666, 10.37665], [1.35507, 9.99525], [1.36624, 9.5951], [1.33675, 9.54765], [1.41746, 9.3226], [1.5649, 9.16941], [1.61838, 9.0527], [1.64249, 6.99562], [1.55877, 6.99737], [1.61812, 6.74843], [1.58105, 6.68619], [1.76906, 6.43189], [1.79826, 6.28221], [1.62913, 6.24075], [1.67336, 6.02702], [2.74181, 6.13349], [2.70566, 6.38038], [2.70464, 6.50831], [2.74334, 6.57291], [2.7325, 6.64057], [2.78204, 6.70514], [2.78823, 6.76356], [2.73405, 6.78508], [2.74024, 6.92802], [2.71702, 6.95722], [2.76965, 7.13543], [2.74489, 7.42565], [2.79442, 7.43486], [2.78668, 7.5116], [2.73405, 7.5423], [2.73095, 7.7755], [2.67523, 7.87825], [2.77907, 9.06924], [3.08017, 9.10006], [3.14147, 9.28375], [3.13928, 9.47167], [3.25093, 9.61632], [3.34726, 9.70696], [3.32099, 9.78032], [3.35383, 9.83641], [3.54429, 9.87739], [3.66908, 10.18136], [3.57275, 10.27185], [3.6844, 10.46351], [3.78292, 10.40538], [3.84243, 10.59316], [3.71505, 11.13015], [3.49175, 11.29765], [3.59375, 11.70269]]]] } },
23124 { type: "Feature", properties: { iso1A2: "BL", iso1A3: "BLM", iso1N3: "652", wikidata: "Q25362", nameEn: "Saint-Barth\xE9lemy", country: "FR", groups: ["EU", "Q1451600", "029", "003", "419", "019", "UN"], callingCodes: ["590"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-62.62718, 18.26185], [-63.1055, 17.86651], [-62.34423, 17.49165], [-62.62718, 18.26185]]]] } },
23125 { type: "Feature", properties: { iso1A2: "BM", iso1A3: "BMU", iso1N3: "060", wikidata: "Q23635", nameEn: "Bermuda", country: "GB", groups: ["BOTS", "021", "003", "019", "UN"], driveSide: "left", callingCodes: ["1 441"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-63.20987, 32.6953], [-65.31453, 32.68437], [-65.63955, 31.43417], [-63.20987, 32.6953]]]] } },
23126 { type: "Feature", properties: { iso1A2: "BN", iso1A3: "BRN", iso1N3: "096", wikidata: "Q921", nameEn: "Brunei", groups: ["Q36117", "035", "142", "UN"], driveSide: "left", callingCodes: ["673"] }, geometry: { type: "MultiPolygon", coordinates: [[[[115.16236, 5.01011], [115.02521, 5.35005], [114.10166, 4.76112], [114.07448, 4.58441], [114.15813, 4.57], [114.26876, 4.49878], [114.32176, 4.34942], [114.32176, 4.2552], [114.4416, 4.27588], [114.49922, 4.13108], [114.64211, 4.00694], [114.78539, 4.12205], [114.88039, 4.4257], [114.83189, 4.42387], [114.77303, 4.72871], [114.8266, 4.75062], [114.88841, 4.81905], [114.96982, 4.81146], [114.99417, 4.88201], [115.05038, 4.90275], [115.02955, 4.82087], [115.02278, 4.74137], [115.04064, 4.63706], [115.07737, 4.53418], [115.09978, 4.39123], [115.31275, 4.30806], [115.36346, 4.33563], [115.2851, 4.42295], [115.27819, 4.63661], [115.20737, 4.8256], [115.15092, 4.87604], [115.16236, 5.01011]]]] } },
23127 { type: "Feature", properties: { iso1A2: "BO", iso1A3: "BOL", iso1N3: "068", wikidata: "Q750", nameEn: "Bolivia", groups: ["005", "419", "019", "UN"], callingCodes: ["591"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-63.90248, -12.52544], [-64.22539, -12.45267], [-64.30708, -12.46398], [-64.99778, -11.98604], [-65.30027, -11.48749], [-65.28141, -10.86289], [-65.35402, -10.78685], [-65.37923, -10.35141], [-65.29019, -9.86253], [-65.40615, -9.63894], [-65.56244, -9.84266], [-65.68343, -9.75323], [-67.17784, -10.34016], [-68.71533, -11.14749], [-68.7651, -11.0496], [-68.75179, -11.03688], [-68.75265, -11.02383], [-68.74802, -11.00891], [-69.42792, -10.93451], [-69.47839, -10.95254], [-69.57156, -10.94555], [-68.98115, -11.8979], [-68.65044, -12.50689], [-68.85615, -12.87769], [-68.8864, -13.40792], [-69.05265, -13.68546], [-68.88135, -14.18639], [-69.36254, -14.94634], [-69.14856, -15.23478], [-69.40336, -15.61358], [-69.20291, -16.16668], [-69.09986, -16.22693], [-68.96238, -16.194], [-68.79464, -16.33272], [-68.98358, -16.42165], [-69.04027, -16.57214], [-69.00853, -16.66769], [-69.16896, -16.72233], [-69.62883, -17.28142], [-69.46863, -17.37466], [-69.46897, -17.4988], [-69.46623, -17.60518], [-69.34126, -17.72753], [-69.28671, -17.94844], [-69.07496, -18.03715], [-69.14807, -18.16893], [-69.07432, -18.28259], [-68.94987, -18.93302], [-68.87082, -19.06003], [-68.80602, -19.08355], [-68.61989, -19.27584], [-68.41218, -19.40499], [-68.66761, -19.72118], [-68.54611, -19.84651], [-68.57132, -20.03134], [-68.74273, -20.08817], [-68.7276, -20.46178], [-68.44023, -20.62701], [-68.55383, -20.7355], [-68.53957, -20.91542], [-68.40403, -20.94562], [-68.18816, -21.28614], [-67.85114, -22.87076], [-67.54284, -22.89771], [-67.18382, -22.81525], [-66.7298, -22.23644], [-66.29714, -22.08741], [-66.24077, -21.77837], [-66.03836, -21.84829], [-66.04832, -21.9187], [-65.9261, -21.93335], [-65.7467, -22.10105], [-65.61166, -22.09504], [-65.58694, -22.09794], [-65.57743, -22.07675], [-65.47435, -22.08908], [-64.99524, -22.08255], [-64.90014, -22.12136], [-64.67174, -22.18957], [-64.58888, -22.25035], [-64.4176, -22.67692], [-64.35108, -22.73282], [-64.31489, -22.88824], [-64.22918, -22.55807], [-63.93287, -21.99934], [-63.70963, -21.99934], [-63.68113, -22.0544], [-63.66482, -21.99918], [-62.81124, -21.9987], [-62.8078, -22.12534], [-62.64455, -22.25091], [-62.2757, -21.06657], [-62.26883, -20.55311], [-61.93912, -20.10053], [-61.73723, -19.63958], [-60.00638, -19.2981], [-59.06965, -19.29148], [-58.23216, -19.80058], [-58.16225, -20.16193], [-57.8496, -19.98346], [-58.14215, -19.76276], [-57.78463, -19.03259], [-57.71113, -19.03161], [-57.69134, -19.00544], [-57.71995, -18.97546], [-57.71995, -18.89573], [-57.76764, -18.90087], [-57.56807, -18.25655], [-57.48237, -18.24219], [-57.69877, -17.8431], [-57.73949, -17.56095], [-57.90082, -17.44555], [-57.99661, -17.5273], [-58.32935, -17.28195], [-58.5058, -16.80958], [-58.30918, -16.3699], [-58.32431, -16.25861], [-58.41506, -16.32636], [-60.16069, -16.26479], [-60.23797, -15.50267], [-60.58224, -15.09887], [-60.23968, -15.09515], [-60.27887, -14.63021], [-60.46037, -14.22496], [-60.48053, -13.77981], [-61.05527, -13.50054], [-61.81151, -13.49564], [-63.76259, -12.42952], [-63.90248, -12.52544]]]] } },
23128 { type: "Feature", properties: { iso1A2: "BQ", iso1A3: "BES", iso1N3: "535", wikidata: "Q27561", nameEn: "Caribbean Netherlands", country: "NL" }, geometry: null },
23129 { type: "Feature", properties: { iso1A2: "BR", iso1A3: "BRA", iso1N3: "076", wikidata: "Q155", nameEn: "Brazil", groups: ["005", "419", "019", "UN"], callingCodes: ["55"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-59.69361, 4.34069], [-59.78878, 4.45637], [-60.15953, 4.53456], [-60.04189, 4.69801], [-59.98129, 5.07097], [-60.20944, 5.28754], [-60.32352, 5.21299], [-60.73204, 5.20931], [-60.5802, 4.94312], [-60.86539, 4.70512], [-60.98303, 4.54167], [-61.15703, 4.49839], [-61.31457, 4.54167], [-61.29675, 4.44216], [-61.48569, 4.43149], [-61.54629, 4.2822], [-62.13094, 4.08309], [-62.44822, 4.18621], [-62.57656, 4.04754], [-62.74411, 4.03331], [-62.7655, 3.73099], [-62.98296, 3.59935], [-63.21111, 3.96219], [-63.4464, 3.9693], [-63.42233, 3.89995], [-63.50611, 3.83592], [-63.67099, 4.01731], [-63.70218, 3.91417], [-63.86082, 3.94796], [-63.99183, 3.90172], [-64.14512, 4.12932], [-64.57648, 4.12576], [-64.72977, 4.28931], [-64.84028, 4.24665], [-64.48379, 3.7879], [-64.02908, 2.79797], [-64.0257, 2.48156], [-63.39114, 2.4317], [-63.39827, 2.16098], [-64.06135, 1.94722], [-64.08274, 1.64792], [-64.34654, 1.35569], [-64.38932, 1.5125], [-65.11657, 1.12046], [-65.57288, 0.62856], [-65.50158, 0.92086], [-65.6727, 1.01353], [-66.28507, 0.74585], [-66.85795, 1.22998], [-67.08222, 1.17441], [-67.15784, 1.80439], [-67.299, 1.87494], [-67.40488, 2.22258], [-67.9292, 1.82455], [-68.18632, 2.00091], [-68.26699, 1.83463], [-68.18128, 1.72881], [-69.38621, 1.70865], [-69.53746, 1.76408], [-69.83491, 1.69353], [-69.82987, 1.07864], [-69.26017, 1.06856], [-69.14422, 0.84172], [-69.20976, 0.57958], [-69.47696, 0.71065], [-70.04162, 0.55437], [-70.03658, -0.19681], [-69.603, -0.51947], [-69.59796, -0.75136], [-69.4215, -1.01853], [-69.43395, -1.42219], [-69.94708, -4.2431], [-70.00888, -4.37833], [-70.11305, -4.27281], [-70.19582, -4.3607], [-70.33236, -4.15214], [-70.77601, -4.15717], [-70.96814, -4.36915], [-71.87003, -4.51661], [-72.64391, -5.0391], [-72.83973, -5.14765], [-73.24579, -6.05764], [-73.12983, -6.43852], [-73.73986, -6.87919], [-73.77011, -7.28944], [-73.96938, -7.58465], [-73.65485, -7.77897], [-73.76576, -7.89884], [-72.92886, -9.04074], [-73.21498, -9.40904], [-72.72216, -9.41397], [-72.31883, -9.5184], [-72.14742, -9.98049], [-71.23394, -9.9668], [-70.53373, -9.42628], [-70.58453, -9.58303], [-70.55429, -9.76692], [-70.62487, -9.80666], [-70.64134, -11.0108], [-70.51395, -10.92249], [-70.38791, -11.07096], [-69.90896, -10.92744], [-69.57835, -10.94051], [-69.57156, -10.94555], [-69.47839, -10.95254], [-69.42792, -10.93451], [-68.74802, -11.00891], [-68.75265, -11.02383], [-68.75179, -11.03688], [-68.7651, -11.0496], [-68.71533, -11.14749], [-67.17784, -10.34016], [-65.68343, -9.75323], [-65.56244, -9.84266], [-65.40615, -9.63894], [-65.29019, -9.86253], [-65.37923, -10.35141], [-65.35402, -10.78685], [-65.28141, -10.86289], [-65.30027, -11.48749], [-64.99778, -11.98604], [-64.30708, -12.46398], [-64.22539, -12.45267], [-63.90248, -12.52544], [-63.76259, -12.42952], [-61.81151, -13.49564], [-61.05527, -13.50054], [-60.48053, -13.77981], [-60.46037, -14.22496], [-60.27887, -14.63021], [-60.23968, -15.09515], [-60.58224, -15.09887], [-60.23797, -15.50267], [-60.16069, -16.26479], [-58.41506, -16.32636], [-58.32431, -16.25861], [-58.30918, -16.3699], [-58.5058, -16.80958], [-58.32935, -17.28195], [-57.99661, -17.5273], [-57.90082, -17.44555], [-57.73949, -17.56095], [-57.69877, -17.8431], [-57.48237, -18.24219], [-57.56807, -18.25655], [-57.76764, -18.90087], [-57.71995, -18.89573], [-57.71995, -18.97546], [-57.69134, -19.00544], [-57.71113, -19.03161], [-57.78463, -19.03259], [-58.14215, -19.76276], [-57.8496, -19.98346], [-58.16225, -20.16193], [-57.84536, -20.93155], [-57.93492, -21.65505], [-57.88239, -21.6868], [-57.94642, -21.73799], [-57.98625, -22.09157], [-56.6508, -22.28387], [-56.5212, -22.11556], [-56.45893, -22.08072], [-56.23206, -22.25347], [-55.8331, -22.29008], [-55.74941, -22.46436], [-55.741, -22.52018], [-55.72366, -22.5519], [-55.6986, -22.56268], [-55.68742, -22.58407], [-55.62493, -22.62765], [-55.63849, -22.95122], [-55.5446, -23.22811], [-55.52288, -23.2595], [-55.5555, -23.28237], [-55.43585, -23.87157], [-55.44117, -23.9185], [-55.41784, -23.9657], [-55.12292, -23.99669], [-55.0518, -23.98666], [-55.02691, -23.97317], [-54.6238, -23.83078], [-54.32807, -24.01865], [-54.28207, -24.07305], [-54.4423, -25.13381], [-54.62033, -25.46026], [-54.60196, -25.48397], [-54.59509, -25.53696], [-54.59398, -25.59224], [-54.5502, -25.58915], [-54.52926, -25.62846], [-53.90831, -25.55513], [-53.83691, -25.94849], [-53.73511, -26.04211], [-53.73086, -26.05842], [-53.7264, -26.0664], [-53.73391, -26.07006], [-53.73968, -26.10012], [-53.65018, -26.19501], [-53.65237, -26.23289], [-53.63739, -26.2496], [-53.63881, -26.25075], [-53.64632, -26.24798], [-53.64186, -26.25976], [-53.64505, -26.28089], [-53.68269, -26.33359], [-53.73372, -26.6131], [-53.80144, -27.09844], [-54.15978, -27.2889], [-54.19062, -27.27639], [-54.19268, -27.30751], [-54.41888, -27.40882], [-54.50416, -27.48232], [-54.67657, -27.57214], [-54.90159, -27.63132], [-54.90805, -27.73149], [-55.1349, -27.89759], [-55.16872, -27.86224], [-55.33303, -27.94661], [-55.6262, -28.17124], [-55.65418, -28.18304], [-56.01729, -28.51223], [-56.00458, -28.60421], [-56.05265, -28.62651], [-56.54171, -29.11447], [-56.57295, -29.11357], [-56.62789, -29.18073], [-56.81251, -29.48154], [-57.09386, -29.74211], [-57.65132, -30.19229], [-57.22502, -30.26121], [-56.90236, -30.02578], [-56.49267, -30.39471], [-56.4795, -30.3899], [-56.4619, -30.38457], [-55.87388, -31.05053], [-55.58866, -30.84117], [-55.5634, -30.8686], [-55.55373, -30.8732], [-55.55218, -30.88193], [-55.54572, -30.89051], [-55.53431, -30.89714], [-55.53276, -30.90218], [-55.52712, -30.89997], [-55.51862, -30.89828], [-55.50841, -30.9027], [-55.50821, -30.91349], [-54.17384, -31.86168], [-53.76024, -32.0751], [-53.39572, -32.58596], [-53.37671, -32.57005], [-53.1111, -32.71147], [-53.53459, -33.16843], [-53.52794, -33.68908], [-53.44031, -33.69344], [-53.39593, -33.75169], [-53.37138, -33.74313], [-52.83257, -34.01481], [-28.34015, -20.99094], [-28.99601, 1.86593], [-51.35485, 4.8383], [-51.63798, 4.51394], [-51.61983, 4.14596], [-51.79599, 3.89336], [-51.82312, 3.85825], [-51.85573, 3.83427], [-52.31787, 3.17896], [-52.6906, 2.37298], [-52.96539, 2.1881], [-53.78743, 2.34412], [-54.16286, 2.10779], [-54.6084, 2.32856], [-55.01919, 2.564], [-55.71493, 2.40342], [-55.96292, 2.53188], [-56.13054, 2.27723], [-55.92159, 2.05236], [-55.89863, 1.89861], [-55.99278, 1.83137], [-56.47045, 1.95135], [-56.7659, 1.89509], [-57.07092, 1.95304], [-57.09109, 2.01854], [-57.23981, 1.95808], [-57.35073, 1.98327], [-57.55743, 1.69605], [-57.77281, 1.73344], [-57.97336, 1.64566], [-58.01873, 1.51966], [-58.33887, 1.58014], [-58.4858, 1.48399], [-58.53571, 1.29154], [-58.84229, 1.17749], [-58.92072, 1.31293], [-59.25583, 1.40559], [-59.74066, 1.87596], [-59.7264, 2.27497], [-59.91177, 2.36759], [-59.99733, 2.92312], [-59.79769, 3.37162], [-59.86899, 3.57089], [-59.51963, 3.91951], [-59.73353, 4.20399], [-59.69361, 4.34069]]]] } },
23130 { type: "Feature", properties: { iso1A2: "BS", iso1A3: "BHS", iso1N3: "044", wikidata: "Q778", nameEn: "The Bahamas", groups: ["029", "003", "419", "019", "UN"], driveSide: "left", roadSpeedUnit: "mph", callingCodes: ["1 242"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-72.98446, 20.4801], [-71.70065, 25.7637], [-78.91214, 27.76553], [-80.65727, 23.71953], [-72.98446, 20.4801]]]] } },
23131 { type: "Feature", properties: { iso1A2: "BT", iso1A3: "BTN", iso1N3: "064", wikidata: "Q917", nameEn: "Bhutan", groups: ["034", "142", "UN"], driveSide: "left", callingCodes: ["975"] }, geometry: { type: "MultiPolygon", coordinates: [[[[91.6469, 27.76358], [91.5629, 27.84823], [91.48973, 27.93903], [91.46327, 28.0064], [91.25779, 28.07509], [91.20019, 27.98715], [90.69894, 28.07784], [90.58842, 28.02838], [90.13387, 28.19178], [89.79762, 28.23979], [89.59525, 28.16433], [89.12825, 27.62502], [89.0582, 27.60985], [88.97213, 27.51671], [88.95355, 27.4106], [89.00216, 27.32532], [88.96947, 27.30319], [88.93678, 27.33777], [88.91901, 27.32483], [88.74219, 27.144], [88.86984, 27.10937], [88.8714, 26.97488], [88.92301, 26.99286], [88.95807, 26.92668], [89.09554, 26.89089], [89.12825, 26.81661], [89.1926, 26.81329], [89.37913, 26.86224], [89.38319, 26.85963], [89.3901, 26.84225], [89.42349, 26.83727], [89.63369, 26.74402], [89.86124, 26.73307], [90.04535, 26.72422], [90.30402, 26.85098], [90.39271, 26.90704], [90.48504, 26.8594], [90.67715, 26.77215], [91.50067, 26.79223], [91.83181, 26.87318], [92.05523, 26.8692], [92.11863, 26.893], [92.03457, 27.07334], [92.04702, 27.26861], [92.12019, 27.27829], [92.01132, 27.47352], [91.65007, 27.48287], [91.55819, 27.6144], [91.6469, 27.76358]]]] } },
23132 { type: "Feature", properties: { iso1A2: "BV", iso1A3: "BVT", iso1N3: "074", wikidata: "Q23408", nameEn: "Bouvet Island", country: "NO", groups: ["005", "419", "019", "UN"] }, geometry: { type: "MultiPolygon", coordinates: [[[[4.54042, -54.0949], [2.28941, -54.13089], [3.35353, -55.17558], [4.54042, -54.0949]]]] } },
23133 { type: "Feature", properties: { iso1A2: "BW", iso1A3: "BWA", iso1N3: "072", wikidata: "Q963", nameEn: "Botswana", groups: ["018", "202", "002", "UN"], driveSide: "left", callingCodes: ["267"] }, geometry: { type: "MultiPolygon", coordinates: [[[[25.26433, -17.79571], [25.16882, -17.78253], [25.05895, -17.84452], [24.95586, -17.79674], [24.73364, -17.89338], [24.71887, -17.9218], [24.6303, -17.9863], [24.57485, -18.07151], [24.40577, -17.95726], [24.19416, -18.01919], [23.61088, -18.4881], [23.29618, -17.99855], [23.0996, -18.00075], [21.45556, -18.31795], [20.99904, -18.31743], [20.99751, -22.00026], [19.99912, -21.99991], [19.99817, -24.76768], [20.02809, -24.78725], [20.03678, -24.81004], [20.29826, -24.94869], [20.64795, -25.47827], [20.86081, -26.14892], [20.61754, -26.4692], [20.63275, -26.78181], [20.68596, -26.9039], [20.87031, -26.80047], [21.13353, -26.86661], [21.37869, -26.82083], [21.69322, -26.86152], [21.7854, -26.79199], [21.77114, -26.69015], [21.83291, -26.65959], [21.90703, -26.66808], [22.06192, -26.61882], [22.21206, -26.3773], [22.41921, -26.23078], [22.56365, -26.19668], [22.70808, -25.99186], [22.86012, -25.50572], [23.03497, -25.29971], [23.47588, -25.29971], [23.9244, -25.64286], [24.18287, -25.62916], [24.36531, -25.773], [24.44703, -25.73021], [24.67319, -25.81749], [24.8946, -25.80723], [25.01718, -25.72507], [25.12266, -25.75931], [25.33076, -25.76616], [25.58543, -25.6343], [25.6643, -25.4491], [25.69661, -25.29284], [25.72702, -25.25503], [25.88571, -24.87802], [25.84295, -24.78661], [25.8515, -24.75727], [26.39409, -24.63468], [26.46346, -24.60358], [26.51667, -24.47219], [26.84165, -24.24885], [26.99749, -23.65486], [27.33768, -23.40917], [27.52393, -23.37952], [27.6066, -23.21894], [27.74154, -23.2137], [27.93539, -23.04941], [27.93729, -22.96194], [28.04752, -22.90243], [28.04562, -22.8394], [28.34874, -22.5694], [28.63287, -22.55887], [28.91889, -22.44299], [29.0151, -22.22907], [29.10881, -22.21202], [29.15268, -22.21399], [29.18974, -22.18599], [29.21955, -22.17771], [29.37703, -22.19581], [29.3533, -22.18363], [29.24648, -22.05967], [29.1974, -22.07472], [29.14501, -22.07275], [29.08495, -22.04867], [29.04108, -22.00563], [29.02191, -21.95665], [29.02191, -21.90647], [29.04023, -21.85864], [29.07763, -21.81877], [28.58114, -21.63455], [28.49942, -21.66634], [28.29416, -21.59037], [28.01669, -21.57624], [27.91407, -21.31621], [27.69171, -21.08409], [27.72972, -20.51735], [27.69361, -20.48531], [27.28865, -20.49873], [27.29831, -20.28935], [27.21278, -20.08244], [26.72246, -19.92707], [26.17227, -19.53709], [25.96226, -19.08152], [25.99837, -19.02943], [25.94326, -18.90362], [25.82353, -18.82808], [25.79217, -18.6355], [25.68859, -18.56165], [25.53465, -18.39041], [25.39972, -18.12691], [25.31799, -18.07091], [25.23909, -17.90832], [25.26433, -17.79571]]]] } },
23134 { type: "Feature", properties: { iso1A2: "BY", iso1A3: "BLR", iso1N3: "112", wikidata: "Q184", nameEn: "Belarus", groups: ["151", "150", "UN"], callingCodes: ["375"] }, geometry: { type: "MultiPolygon", coordinates: [[[[28.15217, 56.16964], [27.97865, 56.11849], [27.63065, 55.89687], [27.61683, 55.78558], [27.3541, 55.8089], [27.27804, 55.78299], [27.1559, 55.85032], [26.97153, 55.8102], [26.87448, 55.7172], [26.76872, 55.67658], [26.71802, 55.70645], [26.64888, 55.70515], [26.63231, 55.67968], [26.63167, 55.57887], [26.55094, 55.5093], [26.5522, 55.40277], [26.44937, 55.34832], [26.5709, 55.32572], [26.6714, 55.33902], [26.80929, 55.31642], [26.83266, 55.30444], [26.835, 55.28182], [26.73017, 55.24226], [26.72983, 55.21788], [26.68075, 55.19787], [26.69243, 55.16718], [26.54753, 55.14181], [26.51481, 55.16051], [26.46249, 55.12814], [26.35121, 55.1525], [26.30628, 55.12536], [26.23202, 55.10439], [26.26941, 55.08032], [26.20397, 54.99729], [26.13386, 54.98924], [26.05907, 54.94631], [25.99129, 54.95705], [25.89462, 54.93438], [25.74122, 54.80108], [25.75977, 54.57252], [25.68045, 54.5321], [25.64813, 54.48704], [25.62203, 54.4656], [25.63371, 54.42075], [25.5376, 54.33158], [25.55425, 54.31591], [25.68513, 54.31727], [25.78553, 54.23327], [25.78563, 54.15747], [25.71084, 54.16704], [25.64875, 54.1259], [25.54724, 54.14925], [25.51452, 54.17799], [25.56823, 54.25212], [25.509, 54.30267], [25.35559, 54.26544], [25.22705, 54.26271], [25.19199, 54.219], [25.0728, 54.13419], [24.991, 54.14241], [24.96894, 54.17589], [24.77131, 54.11091], [24.85311, 54.02862], [24.74279, 53.96663], [24.69185, 53.96543], [24.69652, 54.01901], [24.62275, 54.00217], [24.44411, 53.90076], [24.34128, 53.90076], [24.19638, 53.96405], [23.98837, 53.92554], [23.95098, 53.9613], [23.81309, 53.94205], [23.80543, 53.89558], [23.71726, 53.93379], [23.61677, 53.92691], [23.51284, 53.95052], [23.62004, 53.60942], [23.81995, 53.24131], [23.85657, 53.22923], [23.91393, 53.16469], [23.87548, 53.0831], [23.92184, 53.02079], [23.94689, 52.95919], [23.91805, 52.94016], [23.93763, 52.71332], [23.73615, 52.6149], [23.58296, 52.59868], [23.45112, 52.53774], [23.34141, 52.44845], [23.18196, 52.28812], [23.20071, 52.22848], [23.47859, 52.18215], [23.54314, 52.12148], [23.61, 52.11264], [23.64066, 52.07626], [23.68733, 51.9906], [23.61523, 51.92066], [23.62691, 51.78208], [23.53198, 51.74298], [23.57053, 51.55938], [23.56236, 51.53673], [23.62751, 51.50512], [23.6736, 51.50255], [23.60906, 51.62122], [23.7766, 51.66809], [23.91118, 51.63316], [23.8741, 51.59734], [23.99907, 51.58369], [24.13075, 51.66979], [24.3163, 51.75063], [24.29021, 51.80841], [24.37123, 51.88222], [24.98784, 51.91273], [25.20228, 51.97143], [25.46163, 51.92205], [25.73673, 51.91973], [25.80574, 51.94556], [25.83217, 51.92587], [26.00408, 51.92967], [26.19084, 51.86781], [26.39367, 51.87315], [26.46962, 51.80501], [26.69759, 51.82284], [26.80043, 51.75777], [26.9489, 51.73788], [26.99422, 51.76933], [27.20602, 51.77291], [27.20948, 51.66713], [27.26613, 51.65957], [27.24828, 51.60161], [27.47212, 51.61184], [27.51058, 51.5854], [27.55727, 51.63486], [27.71932, 51.60672], [27.67125, 51.50854], [27.76052, 51.47604], [27.85253, 51.62293], [27.91844, 51.61952], [27.95827, 51.56065], [28.10658, 51.57857], [28.23452, 51.66988], [28.37592, 51.54505], [28.47051, 51.59734], [28.64429, 51.5664], [28.69161, 51.44695], [28.73143, 51.46236], [28.75615, 51.41442], [28.78224, 51.45294], [28.76027, 51.48802], [28.81795, 51.55552], [28.95528, 51.59222], [28.99098, 51.56833], [29.1187, 51.65872], [29.16402, 51.64679], [29.20659, 51.56918], [29.25603, 51.57089], [29.25191, 51.49828], [29.32881, 51.37843], [29.42357, 51.4187], [29.49773, 51.39814], [29.54372, 51.48372], [29.7408, 51.53417], [29.77376, 51.4461], [30.17888, 51.51025], [30.34642, 51.42555], [30.36153, 51.33984], [30.56203, 51.25655], [30.64992, 51.35014], [30.51946, 51.59649], [30.68804, 51.82806], [30.76443, 51.89739], [30.90897, 52.00699], [30.95589, 52.07775], [31.13332, 52.1004], [31.25142, 52.04131], [31.38326, 52.12991], [31.7822, 52.11406], [31.77877, 52.18636], [31.6895, 52.1973], [31.70735, 52.26711], [31.57971, 52.32146], [31.62084, 52.33849], [31.61397, 52.48843], [31.56316, 52.51518], [31.63869, 52.55361], [31.50406, 52.69707], [31.57277, 52.71613], [31.592, 52.79011], [31.35667, 52.97854], [31.24147, 53.031], [31.32283, 53.04101], [31.33519, 53.08805], [31.3915, 53.09712], [31.36403, 53.13504], [31.40523, 53.21406], [31.56316, 53.19432], [31.62496, 53.22886], [31.787, 53.18033], [31.82373, 53.10042], [32.15368, 53.07594], [32.40773, 53.18856], [32.51725, 53.28431], [32.73257, 53.33494], [32.74968, 53.45597], [32.47777, 53.5548], [32.40499, 53.6656], [32.50112, 53.68594], [32.45717, 53.74039], [32.36663, 53.7166], [32.12621, 53.81586], [31.89137, 53.78099], [31.77028, 53.80015], [31.85019, 53.91801], [31.88744, 54.03653], [31.89599, 54.0837], [31.57002, 54.14535], [31.30791, 54.25315], [31.3177, 54.34067], [31.22945, 54.46585], [31.08543, 54.50361], [31.21399, 54.63113], [31.19339, 54.66947], [30.99187, 54.67046], [30.98226, 54.68872], [31.0262, 54.70698], [30.97127, 54.71967], [30.95479, 54.74346], [30.75165, 54.80699], [30.8264, 54.90062], [30.81759, 54.94064], [30.93144, 54.9585], [30.95754, 54.98609], [30.9081, 55.02232], [30.94243, 55.03964], [31.00972, 55.02783], [31.02071, 55.06167], [30.97369, 55.17134], [30.87944, 55.28223], [30.81946, 55.27931], [30.8257, 55.3313], [30.93144, 55.3914], [30.90123, 55.46621], [30.95204, 55.50667], [30.93419, 55.6185], [30.86003, 55.63169], [30.7845, 55.58514], [30.72957, 55.66268], [30.67464, 55.64176], [30.63344, 55.73079], [30.51037, 55.76568], [30.51346, 55.78982], [30.48257, 55.81066], [30.30987, 55.83592], [30.27776, 55.86819], [30.12136, 55.8358], [29.97975, 55.87281], [29.80672, 55.79569], [29.61446, 55.77716], [29.51283, 55.70294], [29.3604, 55.75862], [29.44692, 55.95978], [29.21717, 55.98971], [29.08299, 56.03427], [28.73418, 55.97131], [28.63668, 56.07262], [28.68337, 56.10173], [28.5529, 56.11705], [28.43068, 56.09407], [28.37987, 56.11399], [28.36888, 56.05805], [28.30571, 56.06035], [28.15217, 56.16964]]]] } },
23135 { type: "Feature", properties: { iso1A2: "BZ", iso1A3: "BLZ", iso1N3: "084", wikidata: "Q242", nameEn: "Belize", groups: ["013", "003", "419", "019", "UN"], roadSpeedUnit: "mph", callingCodes: ["501"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-88.3268, 18.49048], [-88.48242, 18.49164], [-88.71505, 18.0707], [-88.8716, 17.89535], [-89.03839, 18.0067], [-89.15105, 17.95104], [-89.14985, 17.81563], [-89.15025, 17.04813], [-89.22683, 15.88619], [-89.17418, 15.90898], [-89.02415, 15.9063], [-88.95358, 15.88698], [-88.40779, 16.09624], [-86.92368, 17.61462], [-87.84815, 18.18511], [-87.85693, 18.18266], [-87.86657, 18.19971], [-87.87604, 18.18313], [-87.90671, 18.15213], [-88.03165, 18.16657], [-88.03238, 18.41778], [-88.26593, 18.47617], [-88.29909, 18.47591], [-88.3268, 18.49048]]]] } },
23136 { type: "Feature", properties: { iso1A2: "CA", iso1A3: "CAN", iso1N3: "124", wikidata: "Q16", nameEn: "Canada", groups: ["021", "003", "019", "UN"], callingCodes: ["1"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-67.20349, 45.1722], [-67.19603, 45.16771], [-67.15965, 45.16179], [-67.11316, 45.11176], [-67.0216, 44.95333], [-66.96824, 44.90965], [-66.98249, 44.87071], [-66.96824, 44.83078], [-66.93432, 44.82597], [-67.16117, 44.20069], [-61.98255, 37.34815], [-56.27503, 47.39728], [-53.12387, 41.40385], [-46.37635, 57.3249], [-77.52957, 77.23408], [-68.21821, 80.48551], [-49.33696, 84.57952], [-140.97446, 84.39275], [-141.00116, 60.30648], [-140.5227, 60.22077], [-140.45648, 60.30919], [-139.98024, 60.18027], [-139.68991, 60.33693], [-139.05831, 60.35205], [-139.20603, 60.08896], [-139.05365, 59.99655], [-138.71149, 59.90728], [-138.62145, 59.76431], [-137.60623, 59.24465], [-137.4925, 58.89415], [-136.82619, 59.16198], [-136.52365, 59.16752], [-136.47323, 59.46617], [-136.33727, 59.44466], [-136.22381, 59.55526], [-136.31566, 59.59083], [-135.48007, 59.79937], [-135.03069, 59.56208], [-135.00267, 59.28745], [-134.7047, 59.2458], [-134.55699, 59.1297], [-134.48059, 59.13231], [-134.27175, 58.8634], [-133.84645, 58.73543], [-133.38523, 58.42773], [-131.8271, 56.62247], [-130.77769, 56.36185], [-130.33965, 56.10849], [-130.10173, 56.12178], [-130.00093, 56.00325], [-130.00857, 55.91344], [-130.15373, 55.74895], [-129.97513, 55.28029], [-130.08035, 55.21556], [-130.18765, 55.07744], [-130.27203, 54.97174], [-130.44184, 54.85377], [-130.64499, 54.76912], [-130.61931, 54.70835], [-133.92876, 54.62289], [-133.36909, 48.51151], [-125.03842, 48.53282], [-123.50039, 48.21223], [-123.15614, 48.35395], [-123.26565, 48.6959], [-123.0093, 48.76586], [-123.0093, 48.83186], [-123.32163, 49.00419], [-95.15355, 48.9996], [-95.15357, 49.384], [-95.12903, 49.37056], [-95.05825, 49.35311], [-95.01419, 49.35647], [-94.99532, 49.36579], [-94.95681, 49.37035], [-94.85381, 49.32492], [-94.8159, 49.32299], [-94.82487, 49.29483], [-94.77355, 49.11998], [-94.75017, 49.09931], [-94.687, 48.84077], [-94.70087, 48.8339], [-94.70486, 48.82365], [-94.69669, 48.80918], [-94.69335, 48.77883], [-94.58903, 48.71803], [-94.54885, 48.71543], [-94.53826, 48.70216], [-94.44258, 48.69223], [-94.4174, 48.71049], [-94.27153, 48.70232], [-94.25172, 48.68404], [-94.25104, 48.65729], [-94.23215, 48.65202], [-93.85769, 48.63284], [-93.83288, 48.62745], [-93.80676, 48.58232], [-93.80939, 48.52439], [-93.79267, 48.51631], [-93.66382, 48.51845], [-93.47022, 48.54357], [-93.44472, 48.59147], [-93.40693, 48.60948], [-93.39758, 48.60364], [-93.3712, 48.60599], [-93.33946, 48.62787], [-93.25391, 48.64266], [-92.94973, 48.60866], [-92.7287, 48.54005], [-92.6342, 48.54133], [-92.62747, 48.50278], [-92.69927, 48.49573], [-92.71323, 48.46081], [-92.65606, 48.43471], [-92.50712, 48.44921], [-92.45588, 48.40624], [-92.48147, 48.36609], [-92.37185, 48.22259], [-92.27167, 48.25046], [-92.30939, 48.31251], [-92.26662, 48.35651], [-92.202, 48.35252], [-92.14732, 48.36578], [-92.05339, 48.35958], [-91.98929, 48.25409], [-91.86125, 48.21278], [-91.71231, 48.19875], [-91.70451, 48.11805], [-91.55649, 48.10611], [-91.58025, 48.04339], [-91.45829, 48.07454], [-91.43248, 48.04912], [-91.25025, 48.08522], [-91.08016, 48.18096], [-90.87588, 48.2484], [-90.75045, 48.09143], [-90.56444, 48.12184], [-90.56312, 48.09488], [-90.07418, 48.11043], [-89.89974, 47.98109], [-89.77248, 48.02607], [-89.57972, 48.00023], [-89.48837, 48.01412], [-88.37033, 48.30586], [-84.85871, 46.88881], [-84.55635, 46.45974], [-84.47607, 46.45225], [-84.4481, 46.48972], [-84.42101, 46.49853], [-84.34174, 46.50683], [-84.29893, 46.49127], [-84.26351, 46.49508], [-84.2264, 46.53337], [-84.1945, 46.54061], [-84.17723, 46.52753], [-84.12885, 46.53068], [-84.11196, 46.50248], [-84.13451, 46.39218], [-84.11254, 46.32329], [-84.11615, 46.2681], [-84.09756, 46.25512], [-84.1096, 46.23987], [-83.95399, 46.05634], [-83.90453, 46.05922], [-83.83329, 46.12169], [-83.57017, 46.105], [-83.43746, 45.99749], [-83.59589, 45.82131], [-82.48419, 45.30225], [-82.42469, 42.992], [-82.4146, 42.97626], [-82.4253, 42.95423], [-82.45331, 42.93139], [-82.4826, 42.8068], [-82.46613, 42.76615], [-82.51063, 42.66025], [-82.51858, 42.611], [-82.57583, 42.5718], [-82.58873, 42.54984], [-82.64242, 42.55594], [-82.82964, 42.37355], [-83.02253, 42.33045], [-83.07837, 42.30978], [-83.09837, 42.28877], [-83.12724, 42.2376], [-83.14962, 42.04089], [-83.11184, 41.95671], [-82.67862, 41.67615], [-78.93684, 42.82887], [-78.90712, 42.89733], [-78.90905, 42.93022], [-78.93224, 42.95229], [-78.96312, 42.95509], [-78.98126, 42.97], [-79.02074, 42.98444], [-79.02424, 43.01983], [-78.99941, 43.05612], [-79.01055, 43.06659], [-79.07486, 43.07845], [-79.05671, 43.10937], [-79.06881, 43.12029], [-79.0427, 43.13934], [-79.04652, 43.16396], [-79.05384, 43.17418], [-79.05002, 43.20133], [-79.05544, 43.21224], [-79.05512, 43.25375], [-79.06921, 43.26183], [-79.25796, 43.54052], [-76.79706, 43.63099], [-76.43859, 44.09393], [-76.35324, 44.13493], [-76.31222, 44.19894], [-76.244, 44.19643], [-76.1664, 44.23051], [-76.16285, 44.28262], [-76.00018, 44.34896], [-75.95947, 44.34463], [-75.8217, 44.43176], [-75.76813, 44.51537], [-75.41441, 44.76614], [-75.2193, 44.87821], [-75.01363, 44.95608], [-74.99101, 44.98051], [-74.8447, 45.00606], [-74.66689, 45.00646], [-74.32699, 44.99029], [-73.35025, 45.00942], [-71.50067, 45.01357], [-71.48735, 45.07784], [-71.42778, 45.12624], [-71.40364, 45.21382], [-71.44252, 45.2361], [-71.37133, 45.24624], [-71.29371, 45.29996], [-71.22338, 45.25184], [-71.19723, 45.25438], [-71.14568, 45.24128], [-71.08364, 45.30623], [-71.01866, 45.31573], [-71.0107, 45.34819], [-70.95193, 45.33895], [-70.91169, 45.29849], [-70.89864, 45.2398], [-70.84816, 45.22698], [-70.80236, 45.37444], [-70.82638, 45.39828], [-70.78372, 45.43269], [-70.65383, 45.37592], [-70.62518, 45.42286], [-70.72651, 45.49771], [-70.68516, 45.56964], [-70.54019, 45.67291], [-70.38934, 45.73215], [-70.41523, 45.79497], [-70.25976, 45.89675], [-70.24694, 45.95138], [-70.31025, 45.96424], [-70.23855, 46.1453], [-70.29078, 46.18832], [-70.18547, 46.35357], [-70.05812, 46.41768], [-69.99966, 46.69543], [-69.22119, 47.46461], [-69.05148, 47.42012], [-69.05073, 47.30076], [-69.05039, 47.2456], [-68.89222, 47.1807], [-68.70125, 47.24399], [-68.60575, 47.24659], [-68.57914, 47.28431], [-68.38332, 47.28723], [-68.37458, 47.35851], [-68.23244, 47.35712], [-67.94843, 47.1925], [-67.87993, 47.10377], [-67.78578, 47.06473], [-67.78111, 45.9392], [-67.75196, 45.91814], [-67.80961, 45.87531], [-67.75654, 45.82324], [-67.80653, 45.80022], [-67.80705, 45.69528], [-67.6049, 45.60725], [-67.43815, 45.59162], [-67.42144, 45.50584], [-67.50578, 45.48971], [-67.42394, 45.37969], [-67.48201, 45.27351], [-67.34927, 45.122], [-67.29754, 45.14865], [-67.29748, 45.18173], [-67.27039, 45.1934], [-67.22751, 45.16344], [-67.20349, 45.1722]]]] } },
23137 { type: "Feature", properties: { iso1A2: "CC", iso1A3: "CCK", iso1N3: "166", wikidata: "Q36004", nameEn: "Cocos (Keeling) Islands", country: "AU", groups: ["053", "009", "UN"], driveSide: "left", callingCodes: ["61"] }, geometry: { type: "MultiPolygon", coordinates: [[[[96.61846, -10.82438], [96.02343, -12.68334], [97.93979, -12.33309], [96.61846, -10.82438]]]] } },
23138 { 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]]]] } },
23139 { 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]]]] } },
23140 { 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]]]] } },
23141 { 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"] } },
23142 { 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]]]] } },
23143 { 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]]]] } },
23144 { 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]]]] } },
23145 { type: "Feature", properties: { iso1A2: "CM", iso1A3: "CMR", iso1N3: "120", wikidata: "Q1009", nameEn: "Cameroon", groups: ["017", "202", "002", "UN"], callingCodes: ["237"] }, geometry: { type: "MultiPolygon", coordinates: [[[[14.83314, 12.62963], [14.55058, 12.78256], [14.56101, 12.91036], [14.46881, 13.08259], [14.08251, 13.0797], [14.20204, 12.53405], [14.17523, 12.41916], [14.22215, 12.36533], [14.4843, 12.35223], [14.6474, 12.17466], [14.61612, 11.7798], [14.55207, 11.72001], [14.64591, 11.66166], [14.6124, 11.51283], [14.17821, 11.23831], [13.97489, 11.30258], [13.78945, 11.00154], [13.7403, 11.00593], [13.70753, 10.94451], [13.73434, 10.9255], [13.54964, 10.61236], [13.5705, 10.53183], [13.43644, 10.13326], [13.34111, 10.12299], [13.25025, 10.03647], [13.25323, 10.00127], [13.286, 9.9822], [13.27409, 9.93232], [13.24132, 9.91031], [13.25025, 9.86042], [13.29941, 9.8296], [13.25472, 9.76795], [13.22642, 9.57266], [13.02385, 9.49334], [12.85628, 9.36698], [12.91958, 9.33905], [12.90022, 9.11411], [12.81085, 8.91992], [12.79, 8.75361], [12.71701, 8.7595], [12.68722, 8.65938], [12.44146, 8.6152], [12.4489, 8.52536], [12.26123, 8.43696], [12.24782, 8.17904], [12.19271, 8.10826], [12.20909, 7.97553], [11.99908, 7.67302], [12.01844, 7.52981], [11.93205, 7.47812], [11.84864, 7.26098], [11.87396, 7.09398], [11.63117, 6.9905], [11.55818, 6.86186], [11.57755, 6.74059], [11.51499, 6.60892], [11.42264, 6.5882], [11.42041, 6.53789], [11.09495, 6.51717], [11.09644, 6.68437], [10.94302, 6.69325], [10.8179, 6.83377], [10.83727, 6.9358], [10.60789, 7.06885], [10.59746, 7.14719], [10.57214, 7.16345], [10.53639, 6.93432], [10.21466, 6.88996], [10.15135, 7.03781], [9.86314, 6.77756], [9.77824, 6.79088], [9.70674, 6.51717], [9.51757, 6.43874], [8.84209, 5.82562], [8.88156, 5.78857], [8.83687, 5.68483], [8.92029, 5.58403], [8.78027, 5.1243], [8.60302, 4.87353], [8.34397, 4.30689], [9.22018, 3.72052], [9.81162, 2.33797], [9.82123, 2.35097], [9.83754, 2.32428], [9.83238, 2.29079], [9.84716, 2.24676], [9.89012, 2.20457], [9.90749, 2.20049], [9.991, 2.16561], [11.3561, 2.17217], [11.37116, 2.29975], [13.28534, 2.25716], [13.29457, 2.16106], [14.61145, 2.17866], [15.00996, 1.98887], [15.22634, 2.03243], [15.34776, 1.91264], [15.48942, 1.98265], [16.02959, 1.76483], [16.02647, 1.65591], [16.14634, 1.70259], [16.05294, 1.9811], [16.08563, 2.19733], [16.15568, 2.18955], [16.19357, 2.21537], [16.08252, 2.45708], [16.05449, 3.02306], [15.77725, 3.26835], [15.73522, 3.24348], [15.07686, 4.01805], [15.17482, 4.05131], [15.10644, 4.1362], [15.08609, 4.30282], [15.00825, 4.41458], [14.73383, 4.6135], [14.65489, 5.21343], [14.57083, 5.23979], [14.52724, 5.28319], [14.62531, 5.51411], [14.58951, 5.59777], [14.62375, 5.70466], [14.60974, 5.91838], [14.49455, 5.91683], [14.42917, 6.00508], [14.43073, 6.08867], [14.56149, 6.18928], [14.74206, 6.26356], [14.80122, 6.34866], [14.79966, 6.39043], [14.96311, 6.75693], [15.04717, 6.77085], [15.23397, 7.25135], [15.49743, 7.52179], [15.56964, 7.58936], [15.59272, 7.7696], [15.50743, 7.79302], [15.20426, 8.50892], [15.09484, 8.65982], [14.83566, 8.80557], [14.35707, 9.19611], [14.37094, 9.2954], [13.97544, 9.6365], [14.01793, 9.73169], [14.1317, 9.82413], [14.20411, 10.00055], [14.4673, 10.00264], [14.80082, 9.93818], [14.95722, 9.97926], [15.05999, 9.94845], [15.14043, 9.99246], [15.24618, 9.99246], [15.41408, 9.92876], [15.68761, 9.99344], [15.50535, 10.1098], [15.30874, 10.31063], [15.23724, 10.47764], [15.14936, 10.53915], [15.15532, 10.62846], [15.06737, 10.80921], [15.09127, 10.87431], [15.04957, 11.02347], [15.10021, 11.04101], [15.0585, 11.40481], [15.13149, 11.5537], [15.06595, 11.71126], [15.11579, 11.79313], [15.04808, 11.8731], [15.05786, 12.0608], [15.0349, 12.10698], [15.00146, 12.1223], [14.96952, 12.0925], [14.89019, 12.16593], [14.90827, 12.3269], [14.83314, 12.62963]]]] } },
23146 { type: "Feature", properties: { iso1A2: "CN", iso1A3: "CHN", iso1N3: "156", wikidata: "Q148", nameEn: "People's Republic of China" }, geometry: null },
23147 { type: "Feature", properties: { iso1A2: "CO", iso1A3: "COL", iso1N3: "170", wikidata: "Q739", nameEn: "Colombia", groups: ["005", "419", "019", "UN"], callingCodes: ["57"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-71.19849, 12.65801], [-81.58685, 18.0025], [-82.06974, 14.49418], [-82.56142, 11.91792], [-78.79327, 9.93766], [-77.58292, 9.22278], [-77.32389, 8.81247], [-77.45064, 8.49991], [-77.17257, 7.97422], [-77.57185, 7.51147], [-77.72514, 7.72348], [-77.72157, 7.47612], [-77.81426, 7.48319], [-77.89178, 7.22681], [-78.06168, 7.07793], [-82.12561, 4.00341], [-78.87137, 1.47457], [-78.42749, 1.15389], [-77.85677, 0.80197], [-77.7148, 0.85003], [-77.68613, 0.83029], [-77.66416, 0.81604], [-77.67815, 0.73863], [-77.49984, 0.64476], [-77.52001, 0.40782], [-76.89177, 0.24736], [-76.4094, 0.24015], [-76.41215, 0.38228], [-76.23441, 0.42294], [-75.82927, 0.09578], [-75.25764, -0.11943], [-75.18513, -0.0308], [-74.42701, -0.50218], [-74.26675, -0.97229], [-73.65312, -1.26222], [-72.92587, -2.44514], [-71.75223, -2.15058], [-70.94377, -2.23142], [-70.04609, -2.73906], [-70.71396, -3.7921], [-70.52393, -3.87553], [-70.3374, -3.79505], [-69.94708, -4.2431], [-69.43395, -1.42219], [-69.4215, -1.01853], [-69.59796, -0.75136], [-69.603, -0.51947], [-70.03658, -0.19681], [-70.04162, 0.55437], [-69.47696, 0.71065], [-69.20976, 0.57958], [-69.14422, 0.84172], [-69.26017, 1.06856], [-69.82987, 1.07864], [-69.83491, 1.69353], [-69.53746, 1.76408], [-69.38621, 1.70865], [-68.18128, 1.72881], [-68.26699, 1.83463], [-68.18632, 2.00091], [-67.9292, 1.82455], [-67.40488, 2.22258], [-67.299, 1.87494], [-67.15784, 1.80439], [-67.08222, 1.17441], [-66.85795, 1.22998], [-67.21967, 2.35778], [-67.65696, 2.81691], [-67.85862, 2.79173], [-67.85862, 2.86727], [-67.30945, 3.38393], [-67.50067, 3.75812], [-67.62671, 3.74303], [-67.85358, 4.53249], [-67.83341, 5.31104], [-67.59141, 5.5369], [-67.63914, 5.64963], [-67.58558, 5.84537], [-67.43513, 5.98835], [-67.4625, 6.20625], [-67.60654, 6.2891], [-69.41843, 6.1072], [-70.10716, 6.96516], [-70.7596, 7.09799], [-71.03941, 6.98163], [-71.37234, 7.01588], [-71.42212, 7.03854], [-71.44118, 7.02116], [-71.82441, 7.04314], [-72.04895, 7.03837], [-72.19437, 7.37034], [-72.43132, 7.40034], [-72.47415, 7.48928], [-72.45321, 7.57232], [-72.47827, 7.65604], [-72.46763, 7.79518], [-72.44454, 7.86031], [-72.46183, 7.90682], [-72.45806, 7.91141], [-72.47042, 7.92306], [-72.48183, 7.92909], [-72.48801, 7.94329], [-72.47213, 7.96106], [-72.39137, 8.03534], [-72.35163, 8.01163], [-72.36987, 8.19976], [-72.4042, 8.36513], [-72.65474, 8.61428], [-72.77415, 9.10165], [-72.94052, 9.10663], [-73.02119, 9.27584], [-73.36905, 9.16636], [-72.98085, 9.85253], [-72.88002, 10.44309], [-72.4767, 11.1117], [-72.24983, 11.14138], [-71.9675, 11.65536], [-71.3275, 11.85], [-70.92579, 11.96275], [-71.19849, 12.65801]]]] } },
23148 { type: "Feature", properties: { iso1A2: "CP", iso1A3: "CPT", wikidata: "Q161258", nameEn: "Clipperton Island", country: "FR", groups: ["EU", "013", "003", "019", "UN"], isoStatus: "excRes" }, geometry: { type: "MultiPolygon", coordinates: [[[[-110.36279, 9.79626], [-108.755, 9.84085], [-109.04145, 11.13245], [-110.36279, 9.79626]]]] } },
23149 { type: "Feature", properties: { iso1A2: "CR", iso1A3: "CRI", iso1N3: "188", wikidata: "Q800", nameEn: "Costa Rica", groups: ["013", "003", "419", "019", "UN"], callingCodes: ["506"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-83.68276, 11.01562], [-83.66597, 10.79916], [-83.90838, 10.71161], [-84.68197, 11.07568], [-84.92439, 10.9497], [-85.60529, 11.22607], [-85.71223, 11.06868], [-86.14524, 11.09059], [-87.41779, 5.02401], [-82.94503, 7.93865], [-82.89978, 8.04083], [-82.89137, 8.05755], [-82.88641, 8.10219], [-82.9388, 8.26634], [-83.05209, 8.33394], [-82.93056, 8.43465], [-82.8679, 8.44042], [-82.8382, 8.48117], [-82.83322, 8.52464], [-82.83975, 8.54755], [-82.82739, 8.60153], [-82.8794, 8.6981], [-82.92068, 8.74832], [-82.91377, 8.774], [-82.88253, 8.83331], [-82.72126, 8.97125], [-82.93516, 9.07687], [-82.93516, 9.46741], [-82.84871, 9.4973], [-82.87919, 9.62645], [-82.77206, 9.59573], [-82.66667, 9.49746], [-82.61345, 9.49881], [-82.56507, 9.57279], [-82.51044, 9.65379], [-83.54024, 10.96805], [-83.68276, 11.01562]]]] } },
23150 { type: "Feature", properties: { iso1A2: "CU", iso1A3: "CUB", iso1N3: "192", wikidata: "Q241", nameEn: "Cuba", groups: ["029", "003", "419", "019", "UN"], callingCodes: ["53"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-73.62304, 20.6935], [-82.02215, 24.23074], [-85.77883, 21.92705], [-74.81171, 18.82201], [-73.62304, 20.6935]]]] } },
23151 { type: "Feature", properties: { iso1A2: "CV", iso1A3: "CPV", iso1N3: "132", wikidata: "Q1011", nameEn: "Cape Verde", groups: ["Q105472", "011", "202", "002", "UN"], callingCodes: ["238"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-28.81604, 14.57305], [-20.39702, 14.12816], [-23.37101, 19.134], [-28.81604, 14.57305]]]] } },
23152 { type: "Feature", properties: { iso1A2: "CW", iso1A3: "CUW", iso1N3: "531", wikidata: "Q25279", nameEn: "Cura\xE7ao", aliases: ["NL-CW"], country: "NL", groups: ["Q1451600", "029", "003", "419", "019", "UN"], callingCodes: ["599"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-68.90012, 12.62309], [-69.59009, 12.46019], [-68.99639, 11.79035], [-68.33524, 11.78151], [-68.90012, 12.62309]]]] } },
23153 { type: "Feature", properties: { iso1A2: "CX", iso1A3: "CXR", iso1N3: "162", wikidata: "Q31063", nameEn: "Christmas Island", country: "AU", groups: ["053", "009", "UN"], driveSide: "left", callingCodes: ["61"] }, geometry: { type: "MultiPolygon", coordinates: [[[[105.66835, -9.31927], [104.67494, -11.2566], [106.66176, -11.14349], [105.66835, -9.31927]]]] } },
23154 { type: "Feature", properties: { iso1A2: "CY", iso1A3: "CYP", iso1N3: "196", wikidata: "Q229", nameEn: "Republic of Cyprus", groups: ["Q644636", "EU", "145", "142", "UN"], driveSide: "left", callingCodes: ["357"] }, geometry: { type: "MultiPolygon", coordinates: [[[[32.46489, 35.48584], [30.15137, 34.08517], [32.74412, 34.43926], [32.75515, 34.64985], [32.76136, 34.68318], [32.79433, 34.67883], [32.82717, 34.70622], [32.86014, 34.70585], [32.86167, 34.68734], [32.9068, 34.66102], [32.91398, 34.67343], [32.93043, 34.67091], [32.92807, 34.66736], [32.93449, 34.66241], [32.93693, 34.67027], [32.94379, 34.67111], [32.94683, 34.67907], [32.95539, 34.68471], [32.99135, 34.68061], [32.98668, 34.67268], [32.99014, 34.65518], [32.97736, 34.65277], [32.97079, 34.66112], [32.95325, 34.66462], [32.94796, 34.6587], [32.94976, 34.65204], [32.95471, 34.64528], [32.95323, 34.64075], [32.95891, 34.62919], [32.96718, 34.63446], [32.96968, 34.64046], [33.0138, 34.64424], [33.26744, 34.49942], [33.83531, 34.73974], [33.70575, 34.97947], [33.70639, 34.99303], [33.71514, 35.00294], [33.69731, 35.01754], [33.69938, 35.03123], [33.67678, 35.03866], [33.63765, 35.03869], [33.61215, 35.0527], [33.59658, 35.03635], [33.567, 35.04803], [33.57478, 35.06049], [33.53975, 35.08151], [33.48915, 35.06594], [33.47666, 35.00701], [33.45256, 35.00288], [33.45178, 35.02078], [33.47825, 35.04103], [33.48136, 35.0636], [33.46813, 35.10564], [33.41675, 35.16325], [33.4076, 35.20062], [33.38575, 35.2018], [33.37248, 35.18698], [33.3717, 35.1788], [33.36569, 35.17479], [33.35612, 35.17402], [33.35596, 35.17942], [33.34964, 35.17803], [33.35056, 35.18328], [33.31955, 35.18096], [33.3072, 35.16816], [33.27068, 35.16815], [33.15138, 35.19504], [33.11105, 35.15639], [33.08249, 35.17319], [33.01192, 35.15639], [32.94471, 35.09422], [32.86406, 35.1043], [32.85733, 35.07742], [32.70779, 35.14127], [32.70947, 35.18328], [32.64864, 35.19967], [32.60361, 35.16647], [32.46489, 35.48584]]], [[[33.74144, 35.01053], [33.7492, 35.01319], [33.74983, 35.02274], [33.74265, 35.02329], [33.73781, 35.02181], [33.7343, 35.01178], [33.74144, 35.01053]]], [[[33.77312, 34.9976], [33.75994, 35.00113], [33.75682, 34.99916], [33.76605, 34.99543], [33.76738, 34.99188], [33.7778, 34.98981], [33.77843, 34.988], [33.78149, 34.98854], [33.78318, 34.98699], [33.78571, 34.98951], [33.78917, 34.98854], [33.79191, 34.98914], [33.78516, 34.99582], [33.77553, 34.99518], [33.77312, 34.9976]]]] } },
23155 { type: "Feature", properties: { iso1A2: "CZ", iso1A3: "CZE", iso1N3: "203", wikidata: "Q213", nameEn: "Czechia", groups: ["EU", "151", "150", "UN"], callingCodes: ["420"] }, geometry: { type: "MultiPolygon", coordinates: [[[[14.82803, 50.86966], [14.79139, 50.81438], [14.70661, 50.84096], [14.61993, 50.86049], [14.63434, 50.8883], [14.65259, 50.90513], [14.64802, 50.93241], [14.58024, 50.91443], [14.56374, 50.922], [14.59702, 50.96148], [14.59908, 50.98685], [14.58215, 50.99306], [14.56432, 51.01008], [14.53438, 51.00374], [14.53321, 51.01679], [14.49873, 51.02242], [14.50809, 51.0427], [14.49991, 51.04692], [14.49154, 51.04382], [14.49202, 51.02286], [14.45827, 51.03712], [14.41335, 51.02086], [14.30098, 51.05515], [14.25665, 50.98935], [14.28776, 50.97718], [14.32353, 50.98556], [14.32793, 50.97379], [14.30251, 50.96606], [14.31422, 50.95243], [14.39848, 50.93866], [14.38691, 50.89907], [14.30098, 50.88448], [14.27123, 50.89386], [14.24314, 50.88761], [14.22331, 50.86049], [14.02982, 50.80662], [13.98864, 50.8177], [13.89113, 50.78533], [13.89444, 50.74142], [13.82942, 50.7251], [13.76316, 50.73487], [13.70204, 50.71771], [13.65977, 50.73096], [13.52474, 50.70394], [13.53748, 50.67654], [13.5226, 50.64721], [13.49742, 50.63133], [13.46413, 50.60102], [13.42189, 50.61243], [13.37485, 50.64931], [13.37805, 50.627], [13.32264, 50.60317], [13.32594, 50.58009], [13.29454, 50.57904], [13.25158, 50.59268], [13.19043, 50.50237], [13.13424, 50.51709], [13.08301, 50.50132], [13.0312, 50.50944], [13.02038, 50.4734], [13.02147, 50.44763], [12.98433, 50.42016], [12.94058, 50.40944], [12.82465, 50.45738], [12.73476, 50.43237], [12.73044, 50.42268], [12.70731, 50.39948], [12.67261, 50.41949], [12.51356, 50.39694], [12.48747, 50.37278], [12.49214, 50.35228], [12.48256, 50.34784], [12.46643, 50.35527], [12.43722, 50.33774], [12.43371, 50.32506], [12.39924, 50.32302], [12.40158, 50.29521], [12.36594, 50.28289], [12.35425, 50.23993], [12.33263, 50.24367], [12.32445, 50.20442], [12.33847, 50.19432], [12.32596, 50.17146], [12.29232, 50.17524], [12.28063, 50.19544], [12.28755, 50.22429], [12.23943, 50.24594], [12.24791, 50.25525], [12.26953, 50.25189], [12.25119, 50.27079], [12.20823, 50.2729], [12.18013, 50.32146], [12.10907, 50.32041], [12.13716, 50.27396], [12.09287, 50.25032], [12.19335, 50.19997], [12.21484, 50.16399], [12.1917, 50.13434], [12.2073, 50.10315], [12.23709, 50.10213], [12.27433, 50.0771], [12.26111, 50.06331], [12.30798, 50.05719], [12.49908, 49.97305], [12.47264, 49.94222], [12.55197, 49.92094], [12.48256, 49.83575], [12.46603, 49.78882], [12.40489, 49.76321], [12.4462, 49.70233], [12.52553, 49.68415], [12.53544, 49.61888], [12.56188, 49.6146], [12.60155, 49.52887], [12.64782, 49.52565], [12.64121, 49.47628], [12.669, 49.42935], [12.71227, 49.42363], [12.75854, 49.3989], [12.78168, 49.34618], [12.88414, 49.33541], [12.88249, 49.35479], [12.94859, 49.34079], [13.03618, 49.30417], [13.02957, 49.27399], [13.05883, 49.26259], [13.17665, 49.16713], [13.17019, 49.14339], [13.20405, 49.12303], [13.23689, 49.11412], [13.28242, 49.1228], [13.39479, 49.04812], [13.40802, 48.98851], [13.50221, 48.93752], [13.50552, 48.97441], [13.58319, 48.96899], [13.61624, 48.9462], [13.67739, 48.87886], [13.73854, 48.88538], [13.76994, 48.83537], [13.78977, 48.83319], [13.8096, 48.77877], [13.84023, 48.76988], [14.06151, 48.66873], [14.01482, 48.63788], [14.09104, 48.5943], [14.20691, 48.5898], [14.33909, 48.55852], [14.43076, 48.58855], [14.4587, 48.64695], [14.56139, 48.60429], [14.60808, 48.62881], [14.66762, 48.58215], [14.71794, 48.59794], [14.72756, 48.69502], [14.80584, 48.73489], [14.80821, 48.77711], [14.81545, 48.7874], [14.94773, 48.76268], [14.95641, 48.75915], [14.9758, 48.76857], [14.98112, 48.77524], [14.9782, 48.7766], [14.98032, 48.77959], [14.95072, 48.79101], [14.98917, 48.90082], [14.97612, 48.96983], [14.99878, 49.01444], [15.15534, 48.99056], [15.16358, 48.94278], [15.26177, 48.95766], [15.28305, 48.98831], [15.34823, 48.98444], [15.48027, 48.94481], [15.51357, 48.91549], [15.61622, 48.89541], [15.6921, 48.85973], [15.75341, 48.8516], [15.78087, 48.87644], [15.84404, 48.86921], [16.06034, 48.75436], [16.37345, 48.729], [16.40915, 48.74576], [16.46134, 48.80865], [16.67008, 48.77699], [16.68518, 48.7281], [16.71883, 48.73806], [16.79779, 48.70998], [16.90354, 48.71541], [16.93955, 48.60371], [17.00215, 48.70887], [17.11202, 48.82925], [17.19355, 48.87602], [17.29054, 48.85546], [17.3853, 48.80936], [17.45671, 48.85004], [17.5295, 48.81117], [17.7094, 48.86721], [17.73126, 48.87885], [17.77944, 48.92318], [17.87831, 48.92679], [17.91814, 49.01784], [18.06885, 49.03157], [18.1104, 49.08624], [18.15022, 49.24518], [18.18456, 49.28909], [18.36446, 49.3267], [18.4139, 49.36517], [18.4084, 49.40003], [18.44686, 49.39467], [18.54848, 49.47059], [18.53063, 49.49022], [18.57183, 49.51162], [18.6144, 49.49824], [18.67757, 49.50895], [18.74761, 49.492], [18.84521, 49.51672], [18.84786, 49.5446], [18.80479, 49.6815], [18.72838, 49.68163], [18.69817, 49.70473], [18.62676, 49.71983], [18.62943, 49.74603], [18.62645, 49.75002], [18.61368, 49.75426], [18.61278, 49.7618], [18.57183, 49.83334], [18.60341, 49.86256], [18.57045, 49.87849], [18.57697, 49.91565], [18.54299, 49.92537], [18.54495, 49.9079], [18.53423, 49.89906], [18.41604, 49.93498], [18.33562, 49.94747], [18.33278, 49.92415], [18.31914, 49.91565], [18.27794, 49.93863], [18.27107, 49.96779], [18.21752, 49.97309], [18.20241, 49.99958], [18.10628, 50.00223], [18.07898, 50.04535], [18.03212, 50.06574], [18.00396, 50.04954], [18.04585, 50.03311], [18.04585, 50.01194], [18.00191, 50.01723], [17.86886, 49.97452], [17.77669, 50.02253], [17.7506, 50.07896], [17.6888, 50.12037], [17.66683, 50.10275], [17.59404, 50.16437], [17.70528, 50.18812], [17.76296, 50.23382], [17.72176, 50.25665], [17.74648, 50.29966], [17.69292, 50.32859], [17.67764, 50.28977], [17.58889, 50.27837], [17.3702, 50.28123], [17.34548, 50.2628], [17.34273, 50.32947], [17.27681, 50.32246], [17.19991, 50.3654], [17.19579, 50.38817], [17.14498, 50.38117], [17.1224, 50.39494], [16.89229, 50.45117], [16.85933, 50.41093], [16.90877, 50.38642], [16.94448, 50.31281], [16.99803, 50.30316], [17.02138, 50.27772], [16.99803, 50.25753], [17.02825, 50.23118], [17.00353, 50.21449], [16.98018, 50.24172], [16.8456, 50.20834], [16.7014, 50.09659], [16.63137, 50.1142], [16.55446, 50.16613], [16.56407, 50.21009], [16.42674, 50.32509], [16.39379, 50.3207], [16.3622, 50.34875], [16.36495, 50.37679], [16.30289, 50.38292], [16.28118, 50.36891], [16.22821, 50.41054], [16.21585, 50.40627], [16.19526, 50.43291], [16.31413, 50.50274], [16.34572, 50.49575], [16.44597, 50.58041], [16.33611, 50.66579], [16.23174, 50.67101], [16.20839, 50.63096], [16.10265, 50.66405], [16.02437, 50.60046], [15.98317, 50.61528], [16.0175, 50.63009], [15.97219, 50.69799], [15.87331, 50.67188], [15.81683, 50.75666], [15.73186, 50.73885], [15.43798, 50.80833], [15.3803, 50.77187], [15.36656, 50.83956], [15.2773, 50.8907], [15.27043, 50.97724], [15.2361, 50.99886], [15.1743, 50.9833], [15.16744, 51.01959], [15.11937, 50.99021], [15.10152, 51.01095], [15.06218, 51.02269], [15.03895, 51.0123], [15.02433, 51.0242], [14.96419, 50.99108], [15.01088, 50.97984], [14.99852, 50.86817], [14.82803, 50.86966]]]] } },
23156 { type: "Feature", properties: { iso1A2: "DE", iso1A3: "DEU", iso1N3: "276", wikidata: "Q183", nameEn: "Germany", groups: ["EU", "155", "150", "UN"], callingCodes: ["49"] }, geometry: { type: "MultiPolygon", coordinates: [[[[8.70847, 47.68904], [8.71773, 47.69088], [8.70237, 47.71453], [8.66416, 47.71367], [8.67508, 47.6979], [8.65769, 47.68928], [8.66837, 47.68437], [8.68985, 47.69552], [8.70847, 47.68904]]], [[[8.72617, 47.69651], [8.72809, 47.69282], [8.75856, 47.68969], [8.79511, 47.67462], [8.79966, 47.70222], [8.76965, 47.7075], [8.77309, 47.72059], [8.80663, 47.73821], [8.82002, 47.71458], [8.86989, 47.70504], [8.85065, 47.68209], [8.87383, 47.67045], [8.87625, 47.65441], [8.89946, 47.64769], [8.94093, 47.65596], [9.02093, 47.6868], [9.09891, 47.67801], [9.13845, 47.66389], [9.15181, 47.66904], [9.1705, 47.65513], [9.1755, 47.65584], [9.17593, 47.65399], [9.18203, 47.65598], [9.25619, 47.65939], [9.55125, 47.53629], [9.72736, 47.53457], [9.76748, 47.5934], [9.80254, 47.59419], [9.82591, 47.58158], [9.8189, 47.54688], [9.87499, 47.52953], [9.87733, 47.54688], [9.92407, 47.53111], [9.96029, 47.53899], [10.00003, 47.48216], [10.03859, 47.48927], [10.07131, 47.45531], [10.09001, 47.46005], [10.1052, 47.4316], [10.06897, 47.40709], [10.09819, 47.35724], [10.11805, 47.37228], [10.16362, 47.36674], [10.17648, 47.38889], [10.2127, 47.38019], [10.22774, 47.38904], [10.23757, 47.37609], [10.19998, 47.32832], [10.2147, 47.31014], [10.17648, 47.29149], [10.17531, 47.27167], [10.23257, 47.27088], [10.33424, 47.30813], [10.39851, 47.37623], [10.4324, 47.38494], [10.4359, 47.41183], [10.47446, 47.43318], [10.46278, 47.47901], [10.44291, 47.48453], [10.4324, 47.50111], [10.44992, 47.5524], [10.43473, 47.58394], [10.47329, 47.58552], [10.48849, 47.54057], [10.56912, 47.53584], [10.60337, 47.56755], [10.63456, 47.5591], [10.68832, 47.55752], [10.6965, 47.54253], [10.7596, 47.53228], [10.77596, 47.51729], [10.88814, 47.53701], [10.91268, 47.51334], [10.86945, 47.5015], [10.87061, 47.4786], [10.90918, 47.48571], [10.93839, 47.48018], [10.92437, 47.46991], [10.98513, 47.42882], [10.97111, 47.41617], [10.97111, 47.39561], [11.11835, 47.39719], [11.12536, 47.41222], [11.20482, 47.43198], [11.25157, 47.43277], [11.22002, 47.3964], [11.27844, 47.39956], [11.29597, 47.42566], [11.33804, 47.44937], [11.4175, 47.44621], [11.38128, 47.47465], [11.4362, 47.51413], [11.52618, 47.50939], [11.58578, 47.52281], [11.58811, 47.55515], [11.60681, 47.57881], [11.63934, 47.59202], [11.84052, 47.58354], [11.85572, 47.60166], [12.0088, 47.62451], [12.02282, 47.61033], [12.05788, 47.61742], [12.13734, 47.60639], [12.17824, 47.61506], [12.18145, 47.61019], [12.17737, 47.60121], [12.18568, 47.6049], [12.20398, 47.60667], [12.20801, 47.61082], [12.19895, 47.64085], [12.18507, 47.65984], [12.18347, 47.66663], [12.16769, 47.68167], [12.16217, 47.70105], [12.18303, 47.70065], [12.22571, 47.71776], [12.2542, 47.7433], [12.26238, 47.73544], [12.24017, 47.69534], [12.26004, 47.67725], [12.27991, 47.68827], [12.336, 47.69534], [12.37222, 47.68433], [12.43883, 47.6977], [12.44117, 47.6741], [12.50076, 47.62293], [12.53816, 47.63553], [12.57438, 47.63238], [12.6071, 47.6741], [12.7357, 47.6787], [12.77777, 47.66689], [12.76492, 47.64485], [12.82101, 47.61493], [12.77427, 47.58025], [12.80699, 47.54477], [12.84672, 47.54556], [12.85256, 47.52741], [12.9624, 47.47452], [12.98344, 47.48716], [12.9998, 47.46267], [13.04537, 47.49426], [13.03252, 47.53373], [13.05355, 47.56291], [13.04537, 47.58183], [13.06641, 47.58577], [13.06407, 47.60075], [13.09562, 47.63304], [13.07692, 47.68814], [13.01382, 47.72116], [12.98578, 47.7078], [12.92969, 47.71094], [12.91333, 47.7178], [12.90274, 47.72513], [12.91711, 47.74026], [12.9353, 47.74788], [12.94371, 47.76281], [12.93202, 47.77302], [12.96311, 47.79957], [12.98543, 47.82896], [13.00588, 47.84374], [12.94163, 47.92927], [12.93886, 47.94046], [12.93642, 47.94436], [12.93419, 47.94063], [12.92668, 47.93879], [12.91985, 47.94069], [12.9211, 47.95135], [12.91683, 47.95647], [12.87476, 47.96195], [12.8549, 48.01122], [12.76141, 48.07373], [12.74973, 48.10885], [12.7617, 48.12796], [12.78595, 48.12445], [12.80676, 48.14979], [12.82673, 48.15245], [12.8362, 48.15876], [12.836, 48.1647], [12.84475, 48.16556], [12.87126, 48.20318], [12.95306, 48.20629], [13.02083, 48.25689], [13.0851, 48.27711], [13.126, 48.27867], [13.18093, 48.29577], [13.26039, 48.29422], [13.30897, 48.31575], [13.40709, 48.37292], [13.43929, 48.43386], [13.42527, 48.45711], [13.45727, 48.51092], [13.43695, 48.55776], [13.45214, 48.56472], [13.46967, 48.55157], [13.50663, 48.57506], [13.50131, 48.58091], [13.51291, 48.59023], [13.57535, 48.55912], [13.59705, 48.57013], [13.62508, 48.55501], [13.65186, 48.55092], [13.66113, 48.53558], [13.72802, 48.51208], [13.74816, 48.53058], [13.7513, 48.5624], [13.76921, 48.55324], [13.80519, 48.58026], [13.80038, 48.59487], [13.82609, 48.62345], [13.81901, 48.6761], [13.81283, 48.68426], [13.81791, 48.69832], [13.79337, 48.71375], [13.81863, 48.73257], [13.82266, 48.75544], [13.84023, 48.76988], [13.8096, 48.77877], [13.78977, 48.83319], [13.76994, 48.83537], [13.73854, 48.88538], [13.67739, 48.87886], [13.61624, 48.9462], [13.58319, 48.96899], [13.50552, 48.97441], [13.50221, 48.93752], [13.40802, 48.98851], [13.39479, 49.04812], [13.28242, 49.1228], [13.23689, 49.11412], [13.20405, 49.12303], [13.17019, 49.14339], [13.17665, 49.16713], [13.05883, 49.26259], [13.02957, 49.27399], [13.03618, 49.30417], [12.94859, 49.34079], [12.88249, 49.35479], [12.88414, 49.33541], [12.78168, 49.34618], [12.75854, 49.3989], [12.71227, 49.42363], [12.669, 49.42935], [12.64121, 49.47628], [12.64782, 49.52565], [12.60155, 49.52887], [12.56188, 49.6146], [12.53544, 49.61888], [12.52553, 49.68415], [12.4462, 49.70233], [12.40489, 49.76321], [12.46603, 49.78882], [12.48256, 49.83575], [12.55197, 49.92094], [12.47264, 49.94222], [12.49908, 49.97305], [12.30798, 50.05719], [12.26111, 50.06331], [12.27433, 50.0771], [12.23709, 50.10213], [12.2073, 50.10315], [12.1917, 50.13434], [12.21484, 50.16399], [12.19335, 50.19997], [12.09287, 50.25032], [12.13716, 50.27396], [12.10907, 50.32041], [12.18013, 50.32146], [12.20823, 50.2729], [12.25119, 50.27079], [12.26953, 50.25189], [12.24791, 50.25525], [12.23943, 50.24594], [12.28755, 50.22429], [12.28063, 50.19544], [12.29232, 50.17524], [12.32596, 50.17146], [12.33847, 50.19432], [12.32445, 50.20442], [12.33263, 50.24367], [12.35425, 50.23993], [12.36594, 50.28289], [12.40158, 50.29521], [12.39924, 50.32302], [12.43371, 50.32506], [12.43722, 50.33774], [12.46643, 50.35527], [12.48256, 50.34784], [12.49214, 50.35228], [12.48747, 50.37278], [12.51356, 50.39694], [12.67261, 50.41949], [12.70731, 50.39948], [12.73044, 50.42268], [12.73476, 50.43237], [12.82465, 50.45738], [12.94058, 50.40944], [12.98433, 50.42016], [13.02147, 50.44763], [13.02038, 50.4734], [13.0312, 50.50944], [13.08301, 50.50132], [13.13424, 50.51709], [13.19043, 50.50237], [13.25158, 50.59268], [13.29454, 50.57904], [13.32594, 50.58009], [13.32264, 50.60317], [13.37805, 50.627], [13.37485, 50.64931], [13.42189, 50.61243], [13.46413, 50.60102], [13.49742, 50.63133], [13.5226, 50.64721], [13.53748, 50.67654], [13.52474, 50.70394], [13.65977, 50.73096], [13.70204, 50.71771], [13.76316, 50.73487], [13.82942, 50.7251], [13.89444, 50.74142], [13.89113, 50.78533], [13.98864, 50.8177], [14.02982, 50.80662], [14.22331, 50.86049], [14.24314, 50.88761], [14.27123, 50.89386], [14.30098, 50.88448], [14.38691, 50.89907], [14.39848, 50.93866], [14.31422, 50.95243], [14.30251, 50.96606], [14.32793, 50.97379], [14.32353, 50.98556], [14.28776, 50.97718], [14.25665, 50.98935], [14.30098, 51.05515], [14.41335, 51.02086], [14.45827, 51.03712], [14.49202, 51.02286], [14.49154, 51.04382], [14.49991, 51.04692], [14.50809, 51.0427], [14.49873, 51.02242], [14.53321, 51.01679], [14.53438, 51.00374], [14.56432, 51.01008], [14.58215, 50.99306], [14.59908, 50.98685], [14.59702, 50.96148], [14.56374, 50.922], [14.58024, 50.91443], [14.64802, 50.93241], [14.65259, 50.90513], [14.63434, 50.8883], [14.61993, 50.86049], [14.70661, 50.84096], [14.79139, 50.81438], [14.82803, 50.86966], [14.81664, 50.88148], [14.89681, 50.9422], [14.89252, 50.94999], [14.92942, 50.99744], [14.95529, 51.04552], [14.97938, 51.07742], [14.98229, 51.11354], [14.99689, 51.12205], [14.99079, 51.14284], [14.99646, 51.14365], [15.00083, 51.14974], [14.99414, 51.15813], [14.99311, 51.16249], [15.0047, 51.16874], [15.01242, 51.21285], [15.04288, 51.28387], [14.98008, 51.33449], [14.96899, 51.38367], [14.9652, 51.44793], [14.94749, 51.47155], [14.73219, 51.52922], [14.72652, 51.53902], [14.73047, 51.54606], [14.71125, 51.56209], [14.7727, 51.61263], [14.75759, 51.62318], [14.75392, 51.67445], [14.69065, 51.70842], [14.66386, 51.73282], [14.64625, 51.79472], [14.60493, 51.80473], [14.59089, 51.83302], [14.6588, 51.88359], [14.6933, 51.9044], [14.70601, 51.92944], [14.7177, 51.94048], [14.72163, 51.95188], [14.71836, 51.95606], [14.7139, 51.95643], [14.70488, 51.97679], [14.71339, 52.00337], [14.76026, 52.06624], [14.72971, 52.09167], [14.6917, 52.10283], [14.67683, 52.13936], [14.70616, 52.16927], [14.68344, 52.19612], [14.71319, 52.22144], [14.70139, 52.25038], [14.58149, 52.28007], [14.56378, 52.33838], [14.55228, 52.35264], [14.54423, 52.42568], [14.63056, 52.48993], [14.60081, 52.53116], [14.6289, 52.57136], [14.61073, 52.59847], [14.22071, 52.81175], [14.13806, 52.82392], [14.12256, 52.84311], [14.15873, 52.87715], [14.14056, 52.95786], [14.25954, 53.00264], [14.35044, 53.05829], [14.38679, 53.13669], [14.36696, 53.16444], [14.37853, 53.20405], [14.40662, 53.21098], [14.45125, 53.26241], [14.44133, 53.27427], [14.4215, 53.27724], [14.35209, 53.49506], [14.3273, 53.50587], [14.30416, 53.55499], [14.31904, 53.61581], [14.2853, 53.63392], [14.28477, 53.65955], [14.27133, 53.66613], [14.2836, 53.67721], [14.26782, 53.69866], [14.27249, 53.74464], [14.21323, 53.8664], [14.20823, 53.90776], [14.18544, 53.91258], [14.20647, 53.91671], [14.22634, 53.9291], [14.20811, 54.12784], [13.93395, 54.84044], [12.85844, 54.82438], [11.90309, 54.38543], [11.00303, 54.63689], [10.31111, 54.65968], [10.16755, 54.73883], [9.89314, 54.84171], [9.73563, 54.8247], [9.61187, 54.85548], [9.62734, 54.88057], [9.58937, 54.88785], [9.4659, 54.83131], [9.43155, 54.82586], [9.41213, 54.84254], [9.38532, 54.83968], [9.36496, 54.81749], [9.33849, 54.80233], [9.32771, 54.80602], [9.2474, 54.8112], [9.23445, 54.83432], [9.24631, 54.84726], [9.20571, 54.85841], [9.14275, 54.87421], [9.04629, 54.87249], [8.92795, 54.90452], [8.81178, 54.90518], [8.76387, 54.8948], [8.63979, 54.91069], [8.55769, 54.91837], [8.45719, 55.06747], [8.02459, 55.09613], [5.45168, 54.20039], [6.91025, 53.44221], [7.00198, 53.32672], [7.19052, 53.31866], [7.21679, 53.20058], [7.22681, 53.18165], [7.17898, 53.13817], [7.21694, 53.00742], [7.07253, 52.81083], [7.04557, 52.63318], [6.77307, 52.65375], [6.71641, 52.62905], [6.69507, 52.488], [6.94293, 52.43597], [6.99041, 52.47235], [7.03417, 52.40237], [7.07044, 52.37805], [7.02703, 52.27941], [7.06365, 52.23789], [7.03729, 52.22695], [6.9897, 52.2271], [6.97189, 52.20329], [6.83984, 52.11728], [6.76117, 52.11895], [6.68128, 52.05052], [6.83035, 51.9905], [6.82357, 51.96711], [6.72319, 51.89518], [6.68386, 51.91861], [6.58556, 51.89386], [6.50231, 51.86313], [6.47179, 51.85395], [6.38815, 51.87257], [6.40704, 51.82771], [6.30593, 51.84998], [6.29872, 51.86801], [6.21443, 51.86801], [6.15349, 51.90439], [6.11551, 51.89769], [6.16902, 51.84094], [6.10337, 51.84829], [6.06705, 51.86136], [5.99848, 51.83195], [5.94568, 51.82786], [5.98665, 51.76944], [5.95003, 51.7493], [6.04091, 51.71821], [6.02767, 51.6742], [6.11759, 51.65609], [6.09055, 51.60564], [6.18017, 51.54096], [6.21724, 51.48568], [6.20654, 51.40049], [6.22641, 51.39948], [6.22674, 51.36135], [6.16977, 51.33169], [6.07889, 51.24432], [6.07889, 51.17038], [6.17384, 51.19589], [6.16706, 51.15677], [5.98292, 51.07469], [5.9541, 51.03496], [5.9134, 51.06736], [5.86735, 51.05182], [5.87849, 51.01969], [5.90493, 51.00198], [5.90296, 50.97356], [5.95282, 50.98728], [6.02697, 50.98303], [6.01615, 50.93367], [6.09297, 50.92066], [6.07486, 50.89307], [6.08805, 50.87223], [6.07693, 50.86025], [6.07431, 50.84674], [6.05702, 50.85179], [6.05623, 50.8572], [6.01921, 50.84435], [6.02328, 50.81694], [6.00462, 50.80065], [5.98404, 50.80988], [5.97497, 50.79992], [6.02624, 50.77453], [6.01976, 50.75398], [6.03889, 50.74618], [6.0326, 50.72647], [6.0406, 50.71848], [6.04428, 50.72861], [6.11707, 50.72231], [6.17852, 50.6245], [6.26957, 50.62444], [6.2476, 50.60392], [6.24888, 50.59869], [6.24005, 50.58732], [6.22581, 50.5907], [6.20281, 50.56952], [6.17739, 50.55875], [6.17802, 50.54179], [6.19735, 50.53576], [6.19579, 50.5313], [6.18716, 50.52653], [6.19193, 50.5212], [6.20599, 50.52089], [6.22335, 50.49578], [6.26637, 50.50272], [6.30809, 50.50058], [6.3465, 50.48833], [6.34005, 50.46083], [6.37219, 50.45397], [6.36852, 50.40776], [6.34406, 50.37994], [6.3688, 50.35898], [6.40785, 50.33557], [6.40641, 50.32425], [6.35701, 50.31139], [6.32488, 50.32333], [6.29949, 50.30887], [6.28797, 50.27458], [6.208, 50.25179], [6.16853, 50.2234], [6.18364, 50.20815], [6.18739, 50.1822], [6.14588, 50.17106], [6.14132, 50.14971], [6.15298, 50.14126], [6.1379, 50.12964], [6.12055, 50.09171], [6.11274, 50.05916], [6.13458, 50.04141], [6.13044, 50.02929], [6.14666, 50.02207], [6.13794, 50.01466], [6.13273, 50.02019], [6.1295, 50.01849], [6.13806, 50.01056], [6.14948, 50.00908], [6.14147, 49.99563], [6.1701, 49.98518], [6.16466, 49.97086], [6.17872, 49.9537], [6.18554, 49.95622], [6.18045, 49.96611], [6.19089, 49.96991], [6.19856, 49.95053], [6.22094, 49.94955], [6.22608, 49.929], [6.21882, 49.92403], [6.22926, 49.92096], [6.23496, 49.89972], [6.26146, 49.88203], [6.28874, 49.87592], [6.29692, 49.86685], [6.30963, 49.87021], [6.32303, 49.85133], [6.32098, 49.83728], [6.33585, 49.83785], [6.34267, 49.84974], [6.36576, 49.85032], [6.40022, 49.82029], [6.42521, 49.81591], [6.42905, 49.81091], [6.44131, 49.81443], [6.45425, 49.81164], [6.47111, 49.82263], [6.48718, 49.81267], [6.50647, 49.80916], [6.51215, 49.80124], [6.52121, 49.81338], [6.53122, 49.80666], [6.52169, 49.79787], [6.50534, 49.78952], [6.51669, 49.78336], [6.51056, 49.77515], [6.51828, 49.76855], [6.51646, 49.75961], [6.50174, 49.75292], [6.50193, 49.73291], [6.51805, 49.72425], [6.51397, 49.72058], [6.50261, 49.72718], [6.49535, 49.72645], [6.49694, 49.72205], [6.5042, 49.71808], [6.50647, 49.71353], [6.49785, 49.71118], [6.48014, 49.69767], [6.46048, 49.69092], [6.44654, 49.67799], [6.42937, 49.66857], [6.42726, 49.66078], [6.43768, 49.66021], [6.4413, 49.65722], [6.41861, 49.61723], [6.39822, 49.60081], [6.385, 49.59946], [6.37464, 49.58886], [6.38342, 49.5799], [6.38024, 49.57593], [6.36676, 49.57813], [6.35825, 49.57053], [6.38228, 49.55855], [6.38072, 49.55171], [6.35666, 49.52931], [6.36788, 49.50377], [6.36907, 49.48931], [6.36778, 49.46937], [6.38352, 49.46463], [6.39168, 49.4667], [6.40274, 49.46546], [6.42432, 49.47683], [6.55404, 49.42464], [6.533, 49.40748], [6.60091, 49.36864], [6.58807, 49.35358], [6.572, 49.35027], [6.60186, 49.31055], [6.66583, 49.28065], [6.69274, 49.21661], [6.71843, 49.2208], [6.73256, 49.20486], [6.71137, 49.18808], [6.73765, 49.16375], [6.78265, 49.16793], [6.83385, 49.15162], [6.84703, 49.15734], [6.86225, 49.18185], [6.85016, 49.19354], [6.85119, 49.20038], [6.83555, 49.21249], [6.85939, 49.22376], [6.89298, 49.20863], [6.91875, 49.22261], [6.93831, 49.2223], [6.94028, 49.21641], [6.95963, 49.203], [6.97273, 49.2099], [7.01318, 49.19018], [7.03459, 49.19096], [7.0274, 49.17042], [7.03178, 49.15734], [7.04662, 49.13724], [7.04409, 49.12123], [7.04843, 49.11422], [7.05548, 49.11185], [7.06642, 49.11415], [7.07162, 49.1255], [7.09007, 49.13094], [7.07859, 49.15031], [7.10715, 49.15631], [7.10384, 49.13787], [7.12504, 49.14253], [7.1358, 49.1282], [7.1593, 49.1204], [7.23473, 49.12971], [7.29514, 49.11426], [7.3195, 49.14231], [7.35995, 49.14399], [7.3662, 49.17308], [7.44052, 49.18354], [7.44455, 49.16765], [7.49473, 49.17], [7.49172, 49.13915], [7.53012, 49.09818], [7.56416, 49.08136], [7.62575, 49.07654], [7.63618, 49.05428], [7.75948, 49.04562], [7.79557, 49.06583], [7.86386, 49.03499], [7.93641, 49.05544], [7.97783, 49.03161], [8.14189, 48.97833], [8.22604, 48.97352], [8.20031, 48.95856], [8.19989, 48.95825], [8.12813, 48.87985], [8.10253, 48.81829], [8.06802, 48.78957], [8.0326, 48.79017], [8.01534, 48.76085], [7.96994, 48.75606], [7.96812, 48.72491], [7.89002, 48.66317], [7.84098, 48.64217], [7.80057, 48.5857], [7.80167, 48.54758], [7.80647, 48.51239], [7.76833, 48.48945], [7.73109, 48.39192], [7.74562, 48.32736], [7.69022, 48.30018], [7.6648, 48.22219], [7.57137, 48.12292], [7.56966, 48.03265], [7.62302, 47.97898], [7.55673, 47.87371], [7.52921, 47.77747], [7.54761, 47.72912], [7.53722, 47.71635], [7.51266, 47.70197], [7.51915, 47.68335], [7.52067, 47.66437], [7.53384, 47.65115], [7.5591, 47.63849], [7.57423, 47.61628], [7.58851, 47.60794], [7.59301, 47.60058], [7.58945, 47.59017], [7.60523, 47.58519], [7.60459, 47.57869], [7.61929, 47.57683], [7.64309, 47.59151], [7.64213, 47.5944], [7.64599, 47.59695], [7.67395, 47.59212], [7.68229, 47.59905], [7.69385, 47.60099], [7.68486, 47.59601], [7.67115, 47.5871], [7.68904, 47.57133], [7.67655, 47.56435], [7.63338, 47.56256], [7.65083, 47.54662], [7.66174, 47.54554], [7.6656, 47.53752], [7.68101, 47.53232], [7.69642, 47.53297], [7.71961, 47.54219], [7.75261, 47.54599], [7.79486, 47.55691], [7.81901, 47.58798], [7.84412, 47.5841], [7.88664, 47.58854], [7.90673, 47.57674], [7.91251, 47.55031], [7.94494, 47.54511], [7.95682, 47.55789], [7.97581, 47.55493], [8.00113, 47.55616], [8.02136, 47.55096], [8.04383, 47.55443], [8.06663, 47.56374], [8.08557, 47.55768], [8.10002, 47.56504], [8.10395, 47.57918], [8.11543, 47.5841], [8.13662, 47.58432], [8.13823, 47.59147], [8.14947, 47.59558], [8.1652, 47.5945], [8.19378, 47.61636], [8.20617, 47.62141], [8.22011, 47.6181], [8.22577, 47.60385], [8.23809, 47.61204], [8.25863, 47.61571], [8.26313, 47.6103], [8.2824, 47.61225], [8.29722, 47.60603], [8.29524, 47.5919], [8.30277, 47.58607], [8.32735, 47.57133], [8.35512, 47.57014], [8.38273, 47.56608], [8.39477, 47.57826], [8.43235, 47.56617], [8.49431, 47.58107], [8.48949, 47.588], [8.46637, 47.58389], [8.45578, 47.60121], [8.50747, 47.61897], [8.51686, 47.63476], [8.55756, 47.62394], [8.57586, 47.59537], [8.60348, 47.61204], [8.59545, 47.64298], [8.60701, 47.65271], [8.61471, 47.64514], [8.60412, 47.63735], [8.62049, 47.63757], [8.62884, 47.65098], [8.61113, 47.66332], [8.6052, 47.67258], [8.57683, 47.66158], [8.56141, 47.67088], [8.52801, 47.66059], [8.5322, 47.64687], [8.49656, 47.64709], [8.46605, 47.64103], [8.4667, 47.65747], [8.44711, 47.65379], [8.42264, 47.66667], [8.41346, 47.66676], [8.40473, 47.67499], [8.4211, 47.68407], [8.40569, 47.69855], [8.44807, 47.72426], [8.45771, 47.7493], [8.48868, 47.77215], [8.56814, 47.78001], [8.56415, 47.80633], [8.61657, 47.79998], [8.62408, 47.7626], [8.64425, 47.76398], [8.65292, 47.80066], [8.68022, 47.78599], [8.68985, 47.75686], [8.71778, 47.76571], [8.74251, 47.75168], [8.70543, 47.73121], [8.73671, 47.7169], [8.72617, 47.69651]]]] } },
23157 { type: "Feature", properties: { iso1A2: "DG", iso1A3: "DGA", wikidata: "Q184851", nameEn: "Diego Garcia", country: "GB", groups: ["IO", "BOTS", "014", "202", "002", "UN"], isoStatus: "excRes", callingCodes: ["246"] }, geometry: { type: "MultiPolygon", coordinates: [[[[73.14823, -7.76302], [73.09982, -6.07324], [71.43792, -7.73904], [73.14823, -7.76302]]]] } },
23158 { type: "Feature", properties: { iso1A2: "DJ", iso1A3: "DJI", iso1N3: "262", wikidata: "Q977", nameEn: "Djibouti", groups: ["014", "202", "002", "UN"], callingCodes: ["253"] }, geometry: { type: "MultiPolygon", coordinates: [[[[43.90659, 12.3823], [43.90659, 12.3823], [43.32909, 12.59711], [43.29075, 12.79154], [42.86195, 12.58747], [42.7996, 12.42629], [42.6957, 12.36201], [42.46941, 12.52661], [42.4037, 12.46478], [41.95461, 11.81157], [41.82878, 11.72361], [41.77727, 11.49902], [41.8096, 11.33606], [41.80056, 10.97127], [42.06302, 10.92599], [42.13691, 10.97586], [42.42669, 10.98493], [42.62989, 11.09711], [42.75111, 11.06992], [42.79037, 10.98493], [42.95776, 10.98533], [43.90659, 12.3823]]]] } },
23159 { type: "Feature", properties: { iso1A2: "DK", iso1A3: "DNK", iso1N3: "208", wikidata: "Q756617", nameEn: "Kingdom of Denmark" }, geometry: null },
23160 { type: "Feature", properties: { iso1A2: "DM", iso1A3: "DMA", iso1N3: "212", wikidata: "Q784", nameEn: "Dominica", groups: ["029", "003", "419", "019", "UN"], driveSide: "left", roadSpeedUnit: "mph", callingCodes: ["1 767"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-61.32485, 14.91445], [-60.86656, 15.82603], [-61.95646, 15.5094], [-61.32485, 14.91445]]]] } },
23161 { type: "Feature", properties: { iso1A2: "DO", iso1A3: "DOM", iso1N3: "214", wikidata: "Q786", nameEn: "Dominican Republic", groups: ["029", "003", "419", "019", "UN"], callingCodes: ["1 809", "1 829", "1 849"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-67.87844, 21.7938], [-72.38946, 20.27111], [-71.77419, 19.73128], [-71.75865, 19.70231], [-71.7429, 19.58445], [-71.71449, 19.55364], [-71.71268, 19.53374], [-71.6802, 19.45008], [-71.69448, 19.37866], [-71.77766, 19.33823], [-71.73229, 19.26686], [-71.62642, 19.21212], [-71.65337, 19.11759], [-71.69938, 19.10916], [-71.71088, 19.08353], [-71.74088, 19.0437], [-71.88102, 18.95007], [-71.77766, 18.95007], [-71.72624, 18.87802], [-71.71885, 18.78423], [-71.82556, 18.62551], [-71.95412, 18.64939], [-72.00201, 18.62312], [-71.88102, 18.50125], [-71.90875, 18.45821], [-71.69952, 18.34101], [-71.78271, 18.18302], [-71.75465, 18.14405], [-71.74994, 18.11115], [-71.73783, 18.07177], [-71.75671, 18.03456], [-72.29523, 17.48026], [-68.39466, 16.14167], [-67.87844, 21.7938]]]] } },
23162 { type: "Feature", properties: { iso1A2: "DZ", iso1A3: "DZA", iso1N3: "012", wikidata: "Q262", nameEn: "Algeria", groups: ["015", "002", "UN"], callingCodes: ["213"] }, geometry: { type: "MultiPolygon", coordinates: [[[[8.59123, 37.14286], [5.10072, 39.89531], [-2.27707, 35.35051], [-2.21248, 35.08532], [-2.21445, 35.04378], [-2.04734, 34.93218], [-1.97833, 34.93218], [-1.97469, 34.886], [-1.73707, 34.74226], [-1.84569, 34.61907], [-1.69788, 34.48056], [-1.78042, 34.39018], [-1.64666, 34.10405], [-1.73494, 33.71721], [-1.59508, 33.59929], [-1.67067, 33.27084], [-1.46249, 33.0499], [-1.54244, 32.95499], [-1.37794, 32.73628], [-0.9912, 32.52467], [-1.24998, 32.32993], [-1.24453, 32.1917], [-1.15735, 32.12096], [-1.22829, 32.07832], [-2.46166, 32.16603], [-2.93873, 32.06557], [-2.82784, 31.79459], [-3.66314, 31.6339], [-3.66386, 31.39202], [-3.77647, 31.31912], [-3.77103, 31.14984], [-3.54944, 31.0503], [-3.65418, 30.85566], [-3.64735, 30.67539], [-4.31774, 30.53229], [-4.6058, 30.28343], [-5.21671, 29.95253], [-5.58831, 29.48103], [-5.72121, 29.52322], [-5.75616, 29.61407], [-6.69965, 29.51623], [-6.78351, 29.44634], [-6.95824, 29.50924], [-7.61585, 29.36252], [-8.6715, 28.71194], [-8.66879, 27.6666], [-8.66674, 27.31569], [-4.83423, 24.99935], [1.15698, 21.12843], [1.20992, 20.73533], [3.24648, 19.81703], [3.12501, 19.1366], [3.36082, 18.9745], [4.26651, 19.14224], [5.8153, 19.45101], [7.38361, 20.79165], [7.48273, 20.87258], [11.96886, 23.51735], [11.62498, 24.26669], [11.41061, 24.21456], [10.85323, 24.5595], [10.33159, 24.5465], [10.02432, 24.98124], [10.03146, 25.35635], [9.38834, 26.19288], [9.51696, 26.39148], [9.89569, 26.57696], [9.78136, 29.40961], [9.3876, 30.16738], [9.55544, 30.23971], [9.07483, 32.07865], [8.35999, 32.50101], [8.31895, 32.83483], [8.1179, 33.05086], [8.11433, 33.10175], [7.83028, 33.18851], [7.73687, 33.42114], [7.54088, 33.7726], [7.52851, 34.06493], [7.66174, 34.20167], [7.74207, 34.16492], [7.81242, 34.21841], [7.86264, 34.3987], [8.20482, 34.57575], [8.29655, 34.72798], [8.25189, 34.92009], [8.30727, 34.95378], [8.3555, 35.10007], [8.47318, 35.23376], [8.30329, 35.29884], [8.36086, 35.47774], [8.35371, 35.66373], [8.26472, 35.73669], [8.2626, 35.91733], [8.40731, 36.42208], [8.18936, 36.44939], [8.16167, 36.48817], [8.47609, 36.66607], [8.46537, 36.7706], [8.57613, 36.78062], [8.67706, 36.8364], [8.62972, 36.86499], [8.64044, 36.9401], [8.59123, 37.14286]]]] } },
23163 { type: "Feature", properties: { iso1A2: "EA", wikidata: "Q28868874", nameEn: "Ceuta, Melilla", country: "ES", level: "territory", isoStatus: "excRes" }, geometry: null },
23164 { type: "Feature", properties: { iso1A2: "EC", iso1A3: "ECU", iso1N3: "218", wikidata: "Q736", nameEn: "Ecuador" }, geometry: null },
23165 { type: "Feature", properties: { iso1A2: "EE", iso1A3: "EST", iso1N3: "233", wikidata: "Q191", nameEn: "Estonia", aliases: ["EW"], groups: ["EU", "154", "150", "UN"], callingCodes: ["372"] }, geometry: { type: "MultiPolygon", coordinates: [[[[26.32936, 60.00121], [20.5104, 59.15546], [19.84909, 57.57876], [22.80496, 57.87798], [23.20055, 57.56697], [24.26221, 57.91787], [24.3579, 57.87471], [25.19484, 58.0831], [25.28237, 57.98539], [25.29581, 58.08288], [25.73499, 57.90193], [26.05949, 57.84744], [26.0324, 57.79037], [26.02456, 57.78342], [26.027, 57.78158], [26.0266, 57.77441], [26.02069, 57.77169], [26.02415, 57.76865], [26.03332, 57.7718], [26.0543, 57.76105], [26.08098, 57.76619], [26.2029, 57.7206], [26.1866, 57.6849], [26.29253, 57.59244], [26.46527, 57.56885], [26.54675, 57.51813], [26.90364, 57.62823], [27.34698, 57.52242], [27.31919, 57.57672], [27.40393, 57.62125], [27.3746, 57.66834], [27.52615, 57.72843], [27.50171, 57.78842], [27.56689, 57.83356], [27.78526, 57.83963], [27.81841, 57.89244], [27.67282, 57.92627], [27.62393, 58.09462], [27.48541, 58.22615], [27.55489, 58.39525], [27.36366, 58.78381], [27.74429, 58.98351], [27.80482, 59.1116], [27.87978, 59.18097], [27.90911, 59.24353], [28.00689, 59.28351], [28.14215, 59.28934], [28.19284, 59.35791], [28.20537, 59.36491], [28.21137, 59.38058], [28.19061, 59.39962], [28.04187, 59.47017], [27.85643, 59.58538], [26.90044, 59.63819], [26.32936, 60.00121]]]] } },
23166 { type: "Feature", properties: { iso1A2: "EG", iso1A3: "EGY", iso1N3: "818", wikidata: "Q79", nameEn: "Egypt", groups: ["015", "002", "UN"], callingCodes: ["20"] }, geometry: { type: "MultiPolygon", coordinates: [[[[33.62659, 31.82938], [26.92891, 33.39516], [24.8458, 31.39877], [25.01077, 30.73861], [24.71117, 30.17441], [24.99968, 29.24574], [24.99885, 21.99535], [33.17563, 22.00405], [34.0765, 22.00501], [37.8565, 22.00903], [34.4454, 27.91479], [34.8812, 29.36878], [34.92298, 29.45305], [34.26742, 31.21998], [34.24012, 31.29591], [34.23572, 31.2966], [34.21853, 31.32363], [34.052, 31.46619], [33.62659, 31.82938]]]] } },
23167 { type: "Feature", properties: { iso1A2: "EH", iso1A3: "ESH", iso1N3: "732", wikidata: "Q6250", nameEn: "Western Sahara", groups: ["015", "002"], callingCodes: ["212"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-8.66879, 27.6666], [-8.77527, 27.66663], [-8.71787, 26.9898], [-9.08698, 26.98639], [-9.56957, 26.90042], [-9.81998, 26.71379], [-10.68417, 26.90984], [-11.35695, 26.8505], [-11.23622, 26.72023], [-11.38635, 26.611], [-11.62052, 26.05229], [-12.06001, 26.04442], [-12.12281, 25.13682], [-12.92147, 24.39502], [-13.00628, 24.01923], [-13.75627, 23.77231], [-14.10361, 22.75501], [-14.1291, 22.41636], [-14.48112, 22.00886], [-14.47329, 21.63839], [-14.78487, 21.36587], [-16.44269, 21.39745], [-16.9978, 21.36239], [-17.02707, 21.34022], [-17.21511, 21.34226], [-17.35589, 20.80492], [-17.0471, 20.76408], [-17.0695, 20.85742], [-17.06781, 20.92697], [-17.0396, 20.9961], [-17.0357, 21.05368], [-16.99806, 21.12142], [-16.95474, 21.33997], [-13.01525, 21.33343], [-13.08438, 22.53866], [-13.15313, 22.75649], [-13.10753, 22.89493], [-13.00412, 23.02297], [-12.5741, 23.28975], [-12.36213, 23.3187], [-12.14969, 23.41935], [-12.00251, 23.4538], [-12.0002, 25.9986], [-8.66721, 25.99918], [-8.66674, 27.31569], [-8.66879, 27.6666]]]] } },
23168 { type: "Feature", properties: { iso1A2: "ER", iso1A3: "ERI", iso1N3: "232", wikidata: "Q986", nameEn: "Eritrea", groups: ["014", "202", "002", "UN"], callingCodes: ["291"] }, geometry: { type: "MultiPolygon", coordinates: [[[[40.99158, 15.81743], [39.63762, 18.37348], [38.57727, 17.98125], [38.45916, 17.87167], [38.37133, 17.66269], [38.13362, 17.53906], [37.50967, 17.32199], [37.42694, 17.04041], [36.99777, 17.07172], [36.92193, 16.23451], [36.76371, 15.80831], [36.69761, 15.75323], [36.54276, 15.23478], [36.44337, 15.14963], [36.54376, 14.25597], [36.56536, 14.26177], [36.55659, 14.28237], [36.63364, 14.31172], [36.85787, 14.32201], [37.01622, 14.2561], [37.09486, 14.27155], [37.13206, 14.40746], [37.3106, 14.44657], [37.47319, 14.2149], [37.528, 14.18413], [37.91287, 14.89447], [38.0364, 14.72745], [38.25562, 14.67287], [38.3533, 14.51323], [38.45748, 14.41445], [38.78306, 14.4754], [38.98058, 14.54895], [39.02834, 14.63717], [39.16074, 14.65187], [39.14772, 14.61827], [39.19547, 14.56996], [39.23888, 14.56365], [39.26927, 14.48801], [39.2302, 14.44598], [39.2519, 14.40393], [39.37685, 14.54402], [39.52756, 14.49011], [39.50585, 14.55735], [39.58182, 14.60987], [39.76632, 14.54264], [39.9443, 14.41024], [40.07236, 14.54264], [40.14649, 14.53969], [40.21128, 14.39342], [40.25686, 14.41445], [40.9167, 14.11152], [41.25097, 13.60787], [41.62864, 13.38626], [42.05841, 12.80912], [42.21469, 12.75832], [42.2798, 12.6355], [42.4037, 12.46478], [42.46941, 12.52661], [42.6957, 12.36201], [42.7996, 12.42629], [42.86195, 12.58747], [43.29075, 12.79154], [40.99158, 15.81743]]]] } },
23169 { type: "Feature", properties: { iso1A2: "ES", iso1A3: "ESP", iso1N3: "724", wikidata: "Q29", nameEn: "Spain" }, geometry: null },
23170 { type: "Feature", properties: { iso1A2: "ET", iso1A3: "ETH", iso1N3: "231", wikidata: "Q115", nameEn: "Ethiopia", groups: ["014", "202", "002", "UN"], callingCodes: ["251"] }, geometry: { type: "MultiPolygon", coordinates: [[[[42.4037, 12.46478], [42.2798, 12.6355], [42.21469, 12.75832], [42.05841, 12.80912], [41.62864, 13.38626], [41.25097, 13.60787], [40.9167, 14.11152], [40.25686, 14.41445], [40.21128, 14.39342], [40.14649, 14.53969], [40.07236, 14.54264], [39.9443, 14.41024], [39.76632, 14.54264], [39.58182, 14.60987], [39.50585, 14.55735], [39.52756, 14.49011], [39.37685, 14.54402], [39.2519, 14.40393], [39.2302, 14.44598], [39.26927, 14.48801], [39.23888, 14.56365], [39.19547, 14.56996], [39.14772, 14.61827], [39.16074, 14.65187], [39.02834, 14.63717], [38.98058, 14.54895], [38.78306, 14.4754], [38.45748, 14.41445], [38.3533, 14.51323], [38.25562, 14.67287], [38.0364, 14.72745], [37.91287, 14.89447], [37.528, 14.18413], [37.47319, 14.2149], [37.3106, 14.44657], [37.13206, 14.40746], [37.09486, 14.27155], [37.01622, 14.2561], [36.85787, 14.32201], [36.63364, 14.31172], [36.55659, 14.28237], [36.56536, 14.26177], [36.54376, 14.25597], [36.44653, 13.95666], [36.48824, 13.83954], [36.38993, 13.56459], [36.24545, 13.36759], [36.13374, 12.92665], [36.16651, 12.88019], [36.14268, 12.70879], [36.01458, 12.72478], [35.70476, 12.67101], [35.24302, 11.91132], [35.11492, 11.85156], [35.05832, 11.71158], [35.09556, 11.56278], [34.95704, 11.24448], [35.01215, 11.19626], [34.93172, 10.95946], [34.97789, 10.91559], [34.97491, 10.86147], [34.86916, 10.78832], [34.86618, 10.74588], [34.77532, 10.69027], [34.77383, 10.74588], [34.59062, 10.89072], [34.4372, 10.781], [34.2823, 10.53508], [34.34783, 10.23914], [34.32102, 10.11599], [34.22718, 10.02506], [34.20484, 9.9033], [34.13186, 9.7492], [34.08717, 9.55243], [34.10229, 9.50238], [34.14304, 9.04654], [34.14453, 8.60204], [34.01346, 8.50041], [33.89579, 8.4842], [33.87195, 8.41938], [33.71407, 8.3678], [33.66938, 8.44442], [33.54575, 8.47094], [33.3119, 8.45474], [33.19721, 8.40317], [33.1853, 8.29264], [33.18083, 8.13047], [33.08401, 8.05822], [33.0006, 7.90333], [33.04944, 7.78989], [33.24637, 7.77939], [33.32531, 7.71297], [33.44745, 7.7543], [33.71407, 7.65983], [33.87642, 7.5491], [34.02984, 7.36449], [34.03878, 7.27437], [34.01495, 7.25664], [34.19369, 7.12807], [34.19369, 7.04382], [34.35753, 6.91963], [34.47669, 6.91076], [34.53925, 6.82794], [34.53776, 6.74808], [34.65096, 6.72589], [34.77459, 6.5957], [34.87736, 6.60161], [35.01738, 6.46991], [34.96227, 6.26415], [35.00546, 5.89387], [35.12611, 5.68937], [35.13058, 5.62118], [35.31188, 5.50106], [35.29938, 5.34042], [35.50792, 5.42431], [35.8576, 5.33413], [35.81968, 5.10757], [35.82118, 4.77382], [35.9419, 4.61933], [35.95449, 4.53244], [36.03924, 4.44406], [36.84474, 4.44518], [37.07724, 4.33503], [38.14168, 3.62487], [38.45812, 3.60445], [38.52336, 3.62551], [38.91938, 3.51198], [39.07736, 3.5267], [39.19954, 3.47834], [39.49444, 3.45521], [39.51551, 3.40895], [39.55132, 3.39634], [39.58339, 3.47434], [39.76808, 3.67058], [39.86043, 3.86974], [40.77498, 4.27683], [41.1754, 3.94079], [41.89488, 3.97375], [42.07619, 4.17667], [42.55853, 4.20518], [42.84526, 4.28357], [42.97746, 4.44032], [43.04177, 4.57923], [43.40263, 4.79289], [44.02436, 4.9451], [44.98104, 4.91821], [47.97917, 8.00124], [47.92477, 8.00111], [46.99339, 7.9989], [44.19222, 8.93028], [43.32613, 9.59205], [43.23518, 9.84605], [43.0937, 9.90579], [42.87643, 10.18441], [42.69452, 10.62672], [42.95776, 10.98533], [42.79037, 10.98493], [42.75111, 11.06992], [42.62989, 11.09711], [42.42669, 10.98493], [42.13691, 10.97586], [42.06302, 10.92599], [41.80056, 10.97127], [41.8096, 11.33606], [41.77727, 11.49902], [41.82878, 11.72361], [41.95461, 11.81157], [42.4037, 12.46478]]]] } },
23171 { type: "Feature", properties: { iso1A2: "EU", iso1A3: "EUE", wikidata: "Q458", nameEn: "European Union", level: "union", isoStatus: "excRes" }, geometry: null },
23172 { type: "Feature", properties: { iso1A2: "FI", iso1A3: "FIN", iso1N3: "246", wikidata: "Q33", nameEn: "Finland", aliases: ["SF"] }, geometry: null },
23173 { type: "Feature", properties: { iso1A2: "FJ", iso1A3: "FJI", iso1N3: "242", wikidata: "Q712", nameEn: "Fiji", groups: ["054", "009", "UN"], driveSide: "left", callingCodes: ["679"] }, geometry: { type: "MultiPolygon", coordinates: [[[[174.245, -23.1974], [179.99999, -22.5], [179.99999, -11.5], [174, -11.5], [174.245, -23.1974]]], [[[-176.76826, -14.95183], [-180, -14.96041], [-180, -22.90585], [-176.74538, -22.89767], [-176.76826, -14.95183]]]] } },
23174 { type: "Feature", properties: { iso1A2: "FK", iso1A3: "FLK", iso1N3: "238", wikidata: "Q9648", nameEn: "Falkland Islands", country: "GB", groups: ["BOTS", "005", "419", "019", "UN"], driveSide: "left", roadSpeedUnit: "mph", roadHeightUnit: "ft", callingCodes: ["500"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-63.67376, -55.11859], [-54.56126, -51.26248], [-61.26735, -50.63919], [-63.67376, -55.11859]]]] } },
23175 { type: "Feature", properties: { iso1A2: "FM", iso1A3: "FSM", iso1N3: "583", wikidata: "Q702", nameEn: "Federated States of Micronesia", groups: ["057", "009", "UN"], roadSpeedUnit: "mph", roadHeightUnit: "ft", callingCodes: ["691"] }, geometry: { type: "MultiPolygon", coordinates: [[[[138.20583, 13.3783], [136.27107, 6.73747], [156.88247, -1.39237], [165.19726, 6.22546], [138.20583, 13.3783]]]] } },
23176 { type: "Feature", properties: { iso1A2: "FO", iso1A3: "FRO", iso1N3: "234", wikidata: "Q4628", nameEn: "Faroe Islands", country: "DK", groups: ["154", "150", "UN"], callingCodes: ["298"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-8.51774, 62.35338], [-6.51083, 60.95272], [-5.70102, 62.77194], [-8.51774, 62.35338]]]] } },
23177 { type: "Feature", properties: { iso1A2: "FR", iso1A3: "FRA", iso1N3: "250", wikidata: "Q142", nameEn: "France" }, geometry: null },
23178 { type: "Feature", properties: { iso1A2: "FX", iso1A3: "FXX", iso1N3: "249", wikidata: "Q212429", nameEn: "Metropolitan France", country: "FR", groups: ["EU", "155", "150", "UN"], isoStatus: "excRes", callingCodes: ["33"] }, geometry: { type: "MultiPolygon", coordinates: [[[[2.55904, 51.07014], [2.18458, 51.52087], [1.17405, 50.74239], [-2.02963, 49.91866], [-2.09454, 49.46288], [-1.83944, 49.23037], [-2.00491, 48.86706], [-2.65349, 49.15373], [-6.28985, 48.93406], [-1.81005, 43.59738], [-1.77289, 43.38957], [-1.79319, 43.37497], [-1.78332, 43.36399], [-1.78714, 43.35476], [-1.77068, 43.34396], [-1.75334, 43.34107], [-1.75079, 43.3317], [-1.7397, 43.32979], [-1.73074, 43.29481], [-1.69407, 43.31378], [-1.62481, 43.30726], [-1.63052, 43.28591], [-1.61341, 43.25269], [-1.57674, 43.25269], [-1.55963, 43.28828], [-1.50992, 43.29481], [-1.45289, 43.27049], [-1.40942, 43.27272], [-1.3758, 43.24511], [-1.41562, 43.12815], [-1.47555, 43.08372], [-1.44067, 43.047], [-1.35272, 43.02658], [-1.34419, 43.09665], [-1.32209, 43.1127], [-1.27118, 43.11961], [-1.30052, 43.09581], [-1.30531, 43.06859], [-1.25244, 43.04164], [-1.22881, 43.05534], [-1.10333, 43.0059], [-1.00963, 42.99279], [-0.97133, 42.96239], [-0.81652, 42.95166], [-0.75478, 42.96916], [-0.72037, 42.92541], [-0.73422, 42.91228], [-0.72608, 42.89318], [-0.69837, 42.87945], [-0.67637, 42.88303], [-0.55497, 42.77846], [-0.50863, 42.82713], [-0.44334, 42.79939], [-0.41319, 42.80776], [-0.38833, 42.80132], [-0.3122, 42.84788], [-0.17939, 42.78974], [-0.16141, 42.79535], [-0.10519, 42.72761], [-0.02468, 42.68513], [0.17569, 42.73424], [0.25336, 42.7174], [0.29407, 42.67431], [0.36251, 42.72282], [0.40214, 42.69779], [0.67873, 42.69458], [0.65421, 42.75872], [0.66121, 42.84021], [0.711, 42.86372], [0.93089, 42.79154], [0.96166, 42.80629], [0.98292, 42.78754], [1.0804, 42.78569], [1.15928, 42.71407], [1.35562, 42.71944], [1.44197, 42.60217], [1.47986, 42.61346], [1.46718, 42.63296], [1.48043, 42.65203], [1.50867, 42.64483], [1.55418, 42.65669], [1.60085, 42.62703], [1.63485, 42.62957], [1.6625, 42.61982], [1.68267, 42.62533], [1.73452, 42.61515], [1.72588, 42.59098], [1.7858, 42.57698], [1.73683, 42.55492], [1.72515, 42.50338], [1.76335, 42.48863], [1.83037, 42.48395], [1.88853, 42.4501], [1.93663, 42.45439], [1.94292, 42.44316], [1.94061, 42.43333], [1.94084, 42.43039], [1.9574, 42.42401], [1.96482, 42.37787], [2.00488, 42.35399], [2.06241, 42.35906], [2.11621, 42.38393], [2.12789, 42.41291], [2.16599, 42.42314], [2.20578, 42.41633], [2.25551, 42.43757], [2.38504, 42.39977], [2.43299, 42.39423], [2.43508, 42.37568], [2.48457, 42.33933], [2.54382, 42.33406], [2.55516, 42.35351], [2.57934, 42.35808], [2.6747, 42.33974], [2.65311, 42.38771], [2.72056, 42.42298], [2.75497, 42.42578], [2.77464, 42.41046], [2.84335, 42.45724], [2.85675, 42.45444], [2.86983, 42.46843], [2.88413, 42.45938], [2.92107, 42.4573], [2.94283, 42.48174], [2.96518, 42.46692], [3.03734, 42.47363], [3.08167, 42.42748], [3.10027, 42.42621], [3.11379, 42.43646], [3.17156, 42.43545], [3.75438, 42.33445], [7.60802, 41.05927], [10.09675, 41.44089], [9.56115, 43.20816], [7.50102, 43.51859], [7.42422, 43.72209], [7.40903, 43.7296], [7.41113, 43.73156], [7.41291, 43.73168], [7.41298, 43.73311], [7.41233, 43.73439], [7.42062, 43.73977], [7.42299, 43.74176], [7.42443, 43.74087], [7.42809, 43.74396], [7.43013, 43.74895], [7.43624, 43.75014], [7.43708, 43.75197], [7.4389, 43.75151], [7.4379, 43.74963], [7.47823, 43.73341], [7.53006, 43.78405], [7.50423, 43.84345], [7.49355, 43.86551], [7.51162, 43.88301], [7.56075, 43.89932], [7.56858, 43.94506], [7.60771, 43.95772], [7.65266, 43.9763], [7.66848, 43.99943], [7.6597, 44.03009], [7.72508, 44.07578], [7.66878, 44.12795], [7.68694, 44.17487], [7.63245, 44.17877], [7.62155, 44.14881], [7.36364, 44.11882], [7.34547, 44.14359], [7.27827, 44.1462], [7.16929, 44.20352], [7.00764, 44.23736], [6.98221, 44.28289], [6.89171, 44.36637], [6.88784, 44.42043], [6.94504, 44.43112], [6.86233, 44.49834], [6.85507, 44.53072], [6.96042, 44.62129], [6.95133, 44.66264], [7.00582, 44.69364], [7.07484, 44.68073], [7.00401, 44.78782], [7.02217, 44.82519], [6.93499, 44.8664], [6.90774, 44.84322], [6.75518, 44.89915], [6.74519, 44.93661], [6.74791, 45.01939], [6.66981, 45.02324], [6.62803, 45.11175], [6.7697, 45.16044], [6.85144, 45.13226], [6.96706, 45.20841], [7.07074, 45.21228], [7.13115, 45.25386], [7.10572, 45.32924], [7.18019, 45.40071], [7.00037, 45.509], [6.98948, 45.63869], [6.80785, 45.71864], [6.80785, 45.83265], [6.95315, 45.85163], [7.04151, 45.92435], [7.00946, 45.9944], [6.93862, 46.06502], [6.87868, 46.03855], [6.89321, 46.12548], [6.78968, 46.14058], [6.86052, 46.28512], [6.77152, 46.34784], [6.8024, 46.39171], [6.82312, 46.42661], [6.53358, 46.45431], [6.25432, 46.3632], [6.21981, 46.31304], [6.24826, 46.30175], [6.25137, 46.29014], [6.23775, 46.27822], [6.24952, 46.26255], [6.26749, 46.24745], [6.29474, 46.26221], [6.31041, 46.24417], [6.29663, 46.22688], [6.27694, 46.21566], [6.26007, 46.21165], [6.24821, 46.20531], [6.23913, 46.20511], [6.23544, 46.20714], [6.22175, 46.20045], [6.22222, 46.19888], [6.21844, 46.19837], [6.21603, 46.19507], [6.21273, 46.19409], [6.21114, 46.1927], [6.20539, 46.19163], [6.19807, 46.18369], [6.19552, 46.18401], [6.18707, 46.17999], [6.18871, 46.16644], [6.18116, 46.16187], [6.15305, 46.15194], [6.13397, 46.1406], [6.09926, 46.14373], [6.09199, 46.15191], [6.07491, 46.14879], [6.05203, 46.15191], [6.04564, 46.14031], [6.03614, 46.13712], [6.01791, 46.14228], [5.9871, 46.14499], [5.97893, 46.13303], [5.95781, 46.12925], [5.9641, 46.14412], [5.97508, 46.15863], [5.98188, 46.17392], [5.98846, 46.17046], [5.99573, 46.18587], [5.96515, 46.19638], [5.97542, 46.21525], [6.02461, 46.23313], [6.03342, 46.2383], [6.04602, 46.23127], [6.05029, 46.23518], [6.0633, 46.24583], [6.07072, 46.24085], [6.08563, 46.24651], [6.10071, 46.23772], [6.12446, 46.25059], [6.11926, 46.2634], [6.1013, 46.28512], [6.11697, 46.29547], [6.1198, 46.31157], [6.13876, 46.33844], [6.15738, 46.3491], [6.16987, 46.36759], [6.15985, 46.37721], [6.15016, 46.3778], [6.09926, 46.40768], [6.06407, 46.41676], [6.08427, 46.44305], [6.07269, 46.46244], [6.1567, 46.54402], [6.11084, 46.57649], [6.27135, 46.68251], [6.38351, 46.73171], [6.45209, 46.77502], [6.43216, 46.80336], [6.46456, 46.88865], [6.43341, 46.92703], [6.71531, 47.0494], [6.68823, 47.06616], [6.76788, 47.1208], [6.8489, 47.15933], [6.9508, 47.24338], [6.95108, 47.26428], [6.94316, 47.28747], [7.05305, 47.33304], [7.0564, 47.35134], [7.03125, 47.36996], [6.87959, 47.35335], [6.88542, 47.37262], [6.93744, 47.40714], [6.93953, 47.43388], [7.0024, 47.45264], [6.98425, 47.49432], [7.0231, 47.50522], [7.07425, 47.48863], [7.12781, 47.50371], [7.16249, 47.49025], [7.19583, 47.49455], [7.17026, 47.44312], [7.24669, 47.4205], [7.33526, 47.44186], [7.35603, 47.43432], [7.40308, 47.43638], [7.43088, 47.45846], [7.4462, 47.46264], [7.4583, 47.47216], [7.42923, 47.48628], [7.43356, 47.49712], [7.47534, 47.47932], [7.51076, 47.49651], [7.49804, 47.51798], [7.5229, 47.51644], [7.53199, 47.5284], [7.51904, 47.53515], [7.50588, 47.52856], [7.49691, 47.53821], [7.50873, 47.54546], [7.51723, 47.54578], [7.52831, 47.55347], [7.53634, 47.55553], [7.55652, 47.56779], [7.55689, 47.57232], [7.56548, 47.57617], [7.56684, 47.57785], [7.58386, 47.57536], [7.58945, 47.59017], [7.59301, 47.60058], [7.58851, 47.60794], [7.57423, 47.61628], [7.5591, 47.63849], [7.53384, 47.65115], [7.52067, 47.66437], [7.51915, 47.68335], [7.51266, 47.70197], [7.53722, 47.71635], [7.54761, 47.72912], [7.52921, 47.77747], [7.55673, 47.87371], [7.62302, 47.97898], [7.56966, 48.03265], [7.57137, 48.12292], [7.6648, 48.22219], [7.69022, 48.30018], [7.74562, 48.32736], [7.73109, 48.39192], [7.76833, 48.48945], [7.80647, 48.51239], [7.80167, 48.54758], [7.80057, 48.5857], [7.84098, 48.64217], [7.89002, 48.66317], [7.96812, 48.72491], [7.96994, 48.75606], [8.01534, 48.76085], [8.0326, 48.79017], [8.06802, 48.78957], [8.10253, 48.81829], [8.12813, 48.87985], [8.19989, 48.95825], [8.20031, 48.95856], [8.22604, 48.97352], [8.14189, 48.97833], [7.97783, 49.03161], [7.93641, 49.05544], [7.86386, 49.03499], [7.79557, 49.06583], [7.75948, 49.04562], [7.63618, 49.05428], [7.62575, 49.07654], [7.56416, 49.08136], [7.53012, 49.09818], [7.49172, 49.13915], [7.49473, 49.17], [7.44455, 49.16765], [7.44052, 49.18354], [7.3662, 49.17308], [7.35995, 49.14399], [7.3195, 49.14231], [7.29514, 49.11426], [7.23473, 49.12971], [7.1593, 49.1204], [7.1358, 49.1282], [7.12504, 49.14253], [7.10384, 49.13787], [7.10715, 49.15631], [7.07859, 49.15031], [7.09007, 49.13094], [7.07162, 49.1255], [7.06642, 49.11415], [7.05548, 49.11185], [7.04843, 49.11422], [7.04409, 49.12123], [7.04662, 49.13724], [7.03178, 49.15734], [7.0274, 49.17042], [7.03459, 49.19096], [7.01318, 49.19018], [6.97273, 49.2099], [6.95963, 49.203], [6.94028, 49.21641], [6.93831, 49.2223], [6.91875, 49.22261], [6.89298, 49.20863], [6.85939, 49.22376], [6.83555, 49.21249], [6.85119, 49.20038], [6.85016, 49.19354], [6.86225, 49.18185], [6.84703, 49.15734], [6.83385, 49.15162], [6.78265, 49.16793], [6.73765, 49.16375], [6.71137, 49.18808], [6.73256, 49.20486], [6.71843, 49.2208], [6.69274, 49.21661], [6.66583, 49.28065], [6.60186, 49.31055], [6.572, 49.35027], [6.58807, 49.35358], [6.60091, 49.36864], [6.533, 49.40748], [6.55404, 49.42464], [6.42432, 49.47683], [6.40274, 49.46546], [6.39168, 49.4667], [6.38352, 49.46463], [6.36778, 49.46937], [6.3687, 49.4593], [6.28818, 49.48465], [6.27875, 49.503], [6.25029, 49.50609], [6.2409, 49.51408], [6.19543, 49.50536], [6.17386, 49.50934], [6.15366, 49.50226], [6.16115, 49.49297], [6.14321, 49.48796], [6.12814, 49.49365], [6.12346, 49.4735], [6.10325, 49.4707], [6.09845, 49.46351], [6.10072, 49.45268], [6.08373, 49.45594], [6.07887, 49.46399], [6.05553, 49.46663], [6.04176, 49.44801], [6.02743, 49.44845], [6.02648, 49.45451], [5.97693, 49.45513], [5.96876, 49.49053], [5.94224, 49.49608], [5.94128, 49.50034], [5.86571, 49.50015], [5.83389, 49.52152], [5.83467, 49.52717], [5.84466, 49.53027], [5.83648, 49.5425], [5.81664, 49.53775], [5.80871, 49.5425], [5.81838, 49.54777], [5.79195, 49.55228], [5.77435, 49.56298], [5.7577, 49.55915], [5.75649, 49.54321], [5.64505, 49.55146], [5.60909, 49.51228], [5.55001, 49.52729], [5.46541, 49.49825], [5.46734, 49.52648], [5.43713, 49.5707], [5.3974, 49.61596], [5.34837, 49.62889], [5.33851, 49.61599], [5.3137, 49.61225], [5.30214, 49.63055], [5.33039, 49.6555], [5.31465, 49.66846], [5.26232, 49.69456], [5.14545, 49.70287], [5.09249, 49.76193], [4.96714, 49.79872], [4.85464, 49.78995], [4.86965, 49.82271], [4.85134, 49.86457], [4.88529, 49.9236], [4.78827, 49.95609], [4.8382, 50.06738], [4.88602, 50.15182], [4.83279, 50.15331], [4.82438, 50.16878], [4.75237, 50.11314], [4.70064, 50.09384], [4.68695, 49.99685], [4.5414, 49.96911], [4.51098, 49.94659], [4.43488, 49.94122], [4.35051, 49.95315], [4.31963, 49.97043], [4.20532, 49.95803], [4.14239, 49.98034], [4.13508, 50.01976], [4.16294, 50.04719], [4.23101, 50.06945], [4.20147, 50.13535], [4.13561, 50.13078], [4.16014, 50.19239], [4.15524, 50.21103], [4.21945, 50.25539], [4.20651, 50.27333], [4.17861, 50.27443], [4.17347, 50.28838], [4.15524, 50.2833], [4.16808, 50.25786], [4.13665, 50.25609], [4.11954, 50.30425], [4.10957, 50.30234], [4.10237, 50.31247], [4.0689, 50.3254], [4.0268, 50.35793], [3.96771, 50.34989], [3.90781, 50.32814], [3.84314, 50.35219], [3.73911, 50.34809], [3.70987, 50.3191], [3.71009, 50.30305], [3.66976, 50.34563], [3.65709, 50.36873], [3.67262, 50.38663], [3.67494, 50.40239], [3.66153, 50.45165], [3.64426, 50.46275], [3.61014, 50.49568], [3.58361, 50.49049], [3.5683, 50.50192], [3.49509, 50.48885], [3.51564, 50.5256], [3.47385, 50.53397], [3.44629, 50.51009], [3.37693, 50.49538], [3.28575, 50.52724], [3.2729, 50.60718], [3.23951, 50.6585], [3.264, 50.67668], [3.2536, 50.68977], [3.26141, 50.69151], [3.26063, 50.70086], [3.24593, 50.71389], [3.22042, 50.71019], [3.20845, 50.71662], [3.19017, 50.72569], [3.20064, 50.73547], [3.18811, 50.74025], [3.18339, 50.74981], [3.16476, 50.76843], [3.15017, 50.79031], [3.1257, 50.78603], [3.11987, 50.79188], [3.11206, 50.79416], [3.10614, 50.78303], [3.09163, 50.77717], [3.04314, 50.77674], [3.00537, 50.76588], [2.96778, 50.75242], [2.95019, 50.75138], [2.90873, 50.702], [2.91036, 50.6939], [2.90069, 50.69263], [2.88504, 50.70656], [2.87937, 50.70298], [2.86985, 50.7033], [2.8483, 50.72276], [2.81056, 50.71773], [2.71165, 50.81295], [2.63331, 50.81457], [2.59093, 50.91751], [2.63074, 50.94746], [2.57551, 51.00326], [2.55904, 51.07014]], [[1.99838, 42.44682], [1.98378, 42.44697], [1.96125, 42.45364], [1.95606, 42.45785], [1.96215, 42.47854], [1.97003, 42.48081], [1.97227, 42.48487], [1.97697, 42.48568], [1.98022, 42.49569], [1.98916, 42.49351], [1.99766, 42.4858], [1.98579, 42.47486], [1.99216, 42.46208], [2.01564, 42.45171], [1.99838, 42.44682]]]] } },
23179 { type: "Feature", properties: { iso1A2: "GA", iso1A3: "GAB", iso1N3: "266", wikidata: "Q1000", nameEn: "Gabon", groups: ["017", "202", "002", "UN"], callingCodes: ["241"] }, geometry: { type: "MultiPolygon", coordinates: [[[[13.29457, 2.16106], [13.28534, 2.25716], [11.37116, 2.29975], [11.3561, 2.17217], [11.35307, 1.00251], [9.79648, 1.0019], [9.75065, 1.06753], [9.66433, 1.06723], [7.24416, -0.64092], [10.75913, -4.39519], [11.12647, -3.94169], [11.22301, -3.69888], [11.48764, -3.51089], [11.57949, -3.52798], [11.68608, -3.68942], [11.87083, -3.71571], [11.92719, -3.62768], [11.8318, -3.5812], [11.96554, -3.30267], [11.70227, -3.17465], [11.70558, -3.0773], [11.80365, -3.00424], [11.64798, -2.81146], [11.5359, -2.85654], [11.64487, -2.61865], [11.57637, -2.33379], [11.74605, -2.39936], [11.96866, -2.33559], [12.04895, -2.41704], [12.47925, -2.32626], [12.44656, -1.92025], [12.61312, -1.8129], [12.82172, -1.91091], [13.02759, -2.33098], [13.47977, -2.43224], [13.75884, -2.09293], [13.92073, -2.35581], [13.85846, -2.46935], [14.10442, -2.49268], [14.23829, -2.33715], [14.16202, -2.23916], [14.23518, -2.15671], [14.25932, -1.97624], [14.41838, -1.89412], [14.52569, -0.57818], [14.41887, -0.44799], [14.2165, -0.38261], [14.06862, -0.20826], [13.90632, -0.2287], [13.88648, 0.26652], [14.10909, 0.58563], [14.26066, 0.57255], [14.48179, 0.9152], [14.25186, 1.39842], [13.89582, 1.4261], [13.15519, 1.23368], [13.25447, 1.32339], [13.13461, 1.57238], [13.29457, 2.16106]]]] } },
23180 { type: "Feature", properties: { iso1A2: "GB", iso1A3: "GBR", iso1N3: "826", wikidata: "Q145", ccTLD: ".uk", nameEn: "United Kingdom", aliases: ["UK"] }, geometry: null },
23181 { type: "Feature", properties: { iso1A2: "GD", iso1A3: "GRD", iso1N3: "308", wikidata: "Q769", nameEn: "Grenada", aliases: ["WG"], groups: ["029", "003", "419", "019", "UN"], driveSide: "left", roadSpeedUnit: "mph", callingCodes: ["1 473"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-62.64026, 12.69984], [-61.77886, 11.36496], [-59.94058, 12.34011], [-62.64026, 12.69984]]]] } },
23182 { type: "Feature", properties: { iso1A2: "GE", iso1A3: "GEO", iso1N3: "268", wikidata: "Q230", nameEn: "Georgia", groups: ["145", "142", "UN"], callingCodes: ["995"] }, geometry: { type: "MultiPolygon", coordinates: [[[[46.42738, 41.91323], [45.61676, 42.20768], [45.78692, 42.48358], [45.36501, 42.55268], [45.15318, 42.70598], [44.88754, 42.74934], [44.80941, 42.61277], [44.70002, 42.74679], [44.54202, 42.75699], [43.95517, 42.55396], [43.73119, 42.62043], [43.81453, 42.74297], [43.0419, 43.02413], [43.03322, 43.08883], [42.75889, 43.19651], [42.66667, 43.13917], [42.40563, 43.23226], [41.64935, 43.22331], [40.65957, 43.56212], [40.10657, 43.57344], [40.04445, 43.47776], [40.03312, 43.44262], [40.01007, 43.42411], [40.01552, 43.42025], [40.00853, 43.40578], [40.0078, 43.38551], [39.81147, 43.06294], [40.89217, 41.72528], [41.54366, 41.52185], [41.7148, 41.4932], [41.7124, 41.47417], [41.81939, 41.43621], [41.95134, 41.52466], [42.26387, 41.49346], [42.51772, 41.43606], [42.59202, 41.58183], [42.72794, 41.59714], [42.84471, 41.58912], [42.78995, 41.50126], [42.84899, 41.47265], [42.8785, 41.50516], [43.02956, 41.37891], [43.21707, 41.30331], [43.13373, 41.25503], [43.1945, 41.25242], [43.23096, 41.17536], [43.36118, 41.2028], [43.44973, 41.17666], [43.4717, 41.12611], [43.67712, 41.13398], [43.74717, 41.1117], [43.84835, 41.16329], [44.16591, 41.19141], [44.18148, 41.24644], [44.32139, 41.2079], [44.34337, 41.20312], [44.34417, 41.2382], [44.46791, 41.18204], [44.59322, 41.1933], [44.61462, 41.24018], [44.72814, 41.20338], [44.82084, 41.21513], [44.87887, 41.20195], [44.89911, 41.21366], [44.84358, 41.23088], [44.81749, 41.23488], [44.80053, 41.25949], [44.81437, 41.30371], [44.93493, 41.25685], [45.0133, 41.29747], [45.09867, 41.34065], [45.1797, 41.42231], [45.26285, 41.46433], [45.31352, 41.47168], [45.4006, 41.42402], [45.45973, 41.45898], [45.68389, 41.3539], [45.71035, 41.36208], [45.75705, 41.35157], [45.69946, 41.29545], [45.80842, 41.2229], [45.95786, 41.17956], [46.13221, 41.19479], [46.27698, 41.19011], [46.37661, 41.10805], [46.456, 41.09984], [46.48558, 41.0576], [46.55096, 41.1104], [46.63969, 41.09515], [46.66148, 41.20533], [46.72375, 41.28609], [46.63658, 41.37727], [46.4669, 41.43331], [46.40307, 41.48464], [46.33925, 41.4963], [46.29794, 41.5724], [46.34126, 41.57454], [46.34039, 41.5947], [46.3253, 41.60912], [46.28182, 41.60089], [46.26531, 41.63339], [46.24429, 41.59883], [46.19759, 41.62327], [46.17891, 41.72094], [46.20538, 41.77205], [46.23962, 41.75811], [46.30863, 41.79133], [46.3984, 41.84399], [46.42738, 41.91323]]]] } },
23183 { type: "Feature", properties: { iso1A2: "GF", iso1A3: "GUF", iso1N3: "254", wikidata: "Q3769", nameEn: "French Guiana", country: "FR", groups: ["Q3320166", "EU", "005", "419", "019", "UN"], callingCodes: ["594"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-51.35485, 4.8383], [-53.7094, 6.2264], [-54.01074, 5.68785], [-54.01877, 5.52789], [-54.26916, 5.26909], [-54.4717, 4.91964], [-54.38444, 4.13222], [-54.19367, 3.84387], [-54.05128, 3.63557], [-53.98914, 3.627], [-53.9849, 3.58697], [-54.28534, 2.67798], [-54.42864, 2.42442], [-54.6084, 2.32856], [-54.16286, 2.10779], [-53.78743, 2.34412], [-52.96539, 2.1881], [-52.6906, 2.37298], [-52.31787, 3.17896], [-51.85573, 3.83427], [-51.82312, 3.85825], [-51.79599, 3.89336], [-51.61983, 4.14596], [-51.63798, 4.51394], [-51.35485, 4.8383]]]] } },
23184 { type: "Feature", properties: { iso1A2: "GG", iso1A3: "GGY", iso1N3: "831", wikidata: "Q25230", nameEn: "Bailiwick of Guernsey", country: "GB" }, geometry: null },
23185 { type: "Feature", properties: { iso1A2: "GH", iso1A3: "GHA", iso1N3: "288", wikidata: "Q117", nameEn: "Ghana", groups: ["011", "202", "002", "UN"], callingCodes: ["233"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-0.13493, 11.14075], [-0.27374, 11.17157], [-0.28566, 11.12713], [-0.35955, 11.07801], [-0.38219, 11.12596], [-0.42391, 11.11661], [-0.44298, 11.04292], [-0.61937, 10.91305], [-0.67143, 10.99811], [-2.83373, 11.0067], [-2.94232, 10.64281], [-2.83108, 10.40252], [-2.74174, 9.83172], [-2.76534, 9.56589], [-2.68802, 9.49343], [-2.69814, 9.22717], [-2.77799, 9.04949], [-2.66357, 9.01771], [-2.58243, 8.7789], [-2.49037, 8.20872], [-2.62901, 8.11495], [-2.61232, 8.02645], [-2.67787, 8.02055], [-2.74819, 7.92613], [-2.78395, 7.94974], [-2.79467, 7.86002], [-2.92339, 7.60847], [-2.97822, 7.27165], [-2.95438, 7.23737], [-3.23327, 6.81744], [-3.21954, 6.74407], [-3.25999, 6.62521], [-3.01896, 5.71697], [-2.95323, 5.71865], [-2.96671, 5.6415], [-2.93132, 5.62137], [-2.85378, 5.65156], [-2.76614, 5.60963], [-2.72737, 5.34789], [-2.77625, 5.34621], [-2.73074, 5.1364], [-2.75502, 5.10657], [-2.95261, 5.12477], [-2.96554, 5.10397], [-3.063, 5.13665], [-3.11073, 5.12675], [-3.10675, 5.08515], [-3.34019, 4.17519], [1.07031, 5.15655], [1.27574, 5.93551], [1.19771, 6.11522], [1.19966, 6.17069], [1.09187, 6.17074], [1.05969, 6.22998], [1.03108, 6.24064], [0.99652, 6.33779], [0.89283, 6.33779], [0.71048, 6.53083], [0.74862, 6.56517], [0.63659, 6.63857], [0.6497, 6.73682], [0.58176, 6.76049], [0.57406, 6.80348], [0.52853, 6.82921], [0.56508, 6.92971], [0.52098, 6.94391], [0.52217, 6.9723], [0.59606, 7.01252], [0.65327, 7.31643], [0.62943, 7.41099], [0.57223, 7.39326], [0.52455, 7.45354], [0.51979, 7.58706], [0.58295, 7.62368], [0.62943, 7.85751], [0.58891, 8.12779], [0.6056, 8.13959], [0.61156, 8.18324], [0.5913, 8.19622], [0.63897, 8.25873], [0.73432, 8.29529], [0.64731, 8.48866], [0.47211, 8.59945], [0.37319, 8.75262], [0.52455, 8.87746], [0.45424, 9.04581], [0.56388, 9.40697], [0.49118, 9.48339], [0.36485, 9.49749], [0.33148, 9.44812], [0.25758, 9.42696], [0.2254, 9.47869], [0.31241, 9.50337], [0.30406, 9.521], [0.2409, 9.52335], [0.23851, 9.57389], [0.38153, 9.58682], [0.36008, 9.6256], [0.29334, 9.59387], [0.26712, 9.66437], [0.28261, 9.69022], [0.32313, 9.6491], [0.34816, 9.66907], [0.34816, 9.71607], [0.32075, 9.72781], [0.36366, 10.03309], [0.41252, 10.02018], [0.41371, 10.06361], [0.35293, 10.09412], [0.39584, 10.31112], [0.33028, 10.30408], [0.29453, 10.41546], [0.18846, 10.4096], [0.12886, 10.53149], [-0.05945, 10.63458], [-0.09141, 10.7147], [-0.07327, 10.71845], [-0.07183, 10.76794], [-0.0228, 10.81916], [-0.02685, 10.8783], [-908e-5, 10.91644], [-63e-4, 10.96417], [0.03355, 10.9807], [0.02395, 11.06229], [342e-5, 11.08317], [-514e-5, 11.10763], [-0.0275, 11.11202], [-0.05733, 11.08628], [-0.14462, 11.10811], [-0.13493, 11.14075]]]] } },
23186 { type: "Feature", properties: { iso1A2: "GI", iso1A3: "GIB", iso1N3: "292", wikidata: "Q1410", nameEn: "Gibraltar", country: "GB", groups: ["Q12837", "BOTS", "039", "150", "UN"], callingCodes: ["350"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-5.34064, 36.03744], [-5.27801, 36.14942], [-5.33822, 36.15272], [-5.34536, 36.15501], [-5.40526, 36.15488], [-5.34064, 36.03744]]]] } },
23187 { type: "Feature", properties: { iso1A2: "GL", iso1A3: "GRL", iso1N3: "304", wikidata: "Q223", nameEn: "Greenland", country: "DK", groups: ["Q1451600", "021", "003", "019", "UN"], callingCodes: ["299"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-49.33696, 84.57952], [-68.21821, 80.48551], [-77.52957, 77.23408], [-46.37635, 57.3249], [-9.68082, 72.73731], [-5.7106, 84.28058], [-49.33696, 84.57952]]]] } },
23188 { type: "Feature", properties: { iso1A2: "GM", iso1A3: "GMB", iso1N3: "270", wikidata: "Q1005", nameEn: "The Gambia", groups: ["011", "202", "002", "UN"], callingCodes: ["220"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-15.14917, 13.57989], [-14.36795, 13.23033], [-13.79409, 13.34472], [-13.8955, 13.59126], [-14.34721, 13.46578], [-14.93719, 13.80173], [-15.36504, 13.79313], [-15.47902, 13.58758], [-17.43598, 13.59273], [-17.43966, 13.04579], [-16.74676, 13.06025], [-16.69343, 13.16791], [-15.80355, 13.16729], [-15.80478, 13.34832], [-15.26908, 13.37768], [-15.14917, 13.57989]]]] } },
23189 { type: "Feature", properties: { iso1A2: "GN", iso1A3: "GIN", iso1N3: "324", wikidata: "Q1006", nameEn: "Guinea", groups: ["011", "202", "002", "UN"], callingCodes: ["224"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-11.37536, 12.40788], [-11.46267, 12.44559], [-11.91331, 12.42008], [-12.35415, 12.32758], [-12.87336, 12.51892], [-13.06603, 12.49342], [-13.05296, 12.64003], [-13.70523, 12.68013], [-13.7039, 12.60313], [-13.65089, 12.49515], [-13.64168, 12.42764], [-13.70851, 12.24978], [-13.92745, 12.24077], [-13.94589, 12.16869], [-13.7039, 12.00869], [-13.7039, 11.70195], [-14.09799, 11.63649], [-14.26623, 11.67486], [-14.31513, 11.60713], [-14.51173, 11.49708], [-14.66677, 11.51188], [-14.77786, 11.36323], [-14.95993, 10.99244], [-15.07174, 10.89557], [-15.96748, 10.162], [-14.36218, 8.64107], [-13.29911, 9.04245], [-13.18586, 9.0925], [-13.08953, 9.0409], [-12.94095, 9.26335], [-12.76788, 9.3133], [-12.47254, 9.86834], [-12.24262, 9.92386], [-12.12634, 9.87203], [-11.91023, 9.93927], [-11.89624, 9.99763], [-11.2118, 10.00098], [-10.6534, 9.29919], [-10.74484, 9.07998], [-10.5783, 9.06386], [-10.56197, 8.81225], [-10.47707, 8.67669], [-10.61422, 8.5314], [-10.70565, 8.29235], [-10.63934, 8.35326], [-10.54891, 8.31174], [-10.37257, 8.48941], [-10.27575, 8.48711], [-10.203, 8.47991], [-10.14579, 8.52665], [-10.05375, 8.50697], [-10.05873, 8.42578], [-9.77763, 8.54633], [-9.47415, 8.35195], [-9.50898, 8.18455], [-9.41445, 8.02448], [-9.44928, 7.9284], [-9.35724, 7.74111], [-9.37465, 7.62032], [-9.48161, 7.37122], [-9.41943, 7.41809], [-9.305, 7.42056], [-9.20798, 7.38109], [-9.18311, 7.30461], [-9.09107, 7.1985], [-8.93435, 7.2824], [-8.85724, 7.26019], [-8.8448, 7.35149], [-8.72789, 7.51429], [-8.67814, 7.69428], [-8.55874, 7.70167], [-8.55874, 7.62525], [-8.47114, 7.55676], [-8.4003, 7.6285], [-8.21374, 7.54466], [-8.09931, 7.78626], [-8.13414, 7.87991], [-8.06449, 8.04989], [-7.94695, 8.00925], [-7.99919, 8.11023], [-7.98675, 8.20134], [-8.062, 8.16071], [-8.2411, 8.24196], [-8.22991, 8.48438], [-7.92518, 8.50652], [-7.65653, 8.36873], [-7.69882, 8.66148], [-7.95503, 8.81146], [-7.92518, 8.99332], [-7.73862, 9.08422], [-7.90777, 9.20456], [-7.85056, 9.41812], [-8.03463, 9.39604], [-8.14657, 9.55062], [-8.09434, 9.86936], [-8.15652, 9.94288], [-8.11921, 10.04577], [-8.01225, 10.1021], [-7.97971, 10.17117], [-7.9578, 10.2703], [-8.10207, 10.44649], [-8.22711, 10.41722], [-8.32614, 10.69273], [-8.2667, 10.91762], [-8.35083, 11.06234], [-8.66923, 10.99397], [-8.40058, 11.37466], [-8.80854, 11.66715], [-8.94784, 12.34842], [-9.13689, 12.50875], [-9.38067, 12.48446], [-9.32097, 12.29009], [-9.63938, 12.18312], [-9.714, 12.0226], [-10.30604, 12.24634], [-10.71897, 11.91552], [-10.80355, 12.1053], [-10.99758, 12.24634], [-11.24136, 12.01286], [-11.50006, 12.17826], [-11.37536, 12.40788]]]] } },
23190 { type: "Feature", properties: { iso1A2: "GP", iso1A3: "GLP", iso1N3: "312", wikidata: "Q17012", nameEn: "Guadeloupe", country: "FR", groups: ["Q3320166", "EU", "029", "003", "419", "019", "UN"], callingCodes: ["590"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-60.03183, 16.1129], [-61.60296, 16.73066], [-63.00549, 15.26166], [-60.03183, 16.1129]]]] } },
23191 { type: "Feature", properties: { iso1A2: "GQ", iso1A3: "GNQ", iso1N3: "226", wikidata: "Q983", nameEn: "Equatorial Guinea", groups: ["017", "202", "002", "UN"], callingCodes: ["240"] }, geometry: { type: "MultiPolygon", coordinates: [[[[9.22018, 3.72052], [8.34397, 4.30689], [7.71762, 0.6674], [3.35016, -3.29031], [9.66433, 1.06723], [9.75065, 1.06753], [9.79648, 1.0019], [11.35307, 1.00251], [11.3561, 2.17217], [9.991, 2.16561], [9.90749, 2.20049], [9.89012, 2.20457], [9.84716, 2.24676], [9.83238, 2.29079], [9.83754, 2.32428], [9.82123, 2.35097], [9.81162, 2.33797], [9.22018, 3.72052]]]] } },
23192 { type: "Feature", properties: { iso1A2: "GR", iso1A3: "GRC", iso1N3: "300", wikidata: "Q41", nameEn: "Greece", aliases: ["EL"], groups: ["EU", "039", "150", "UN"], callingCodes: ["30"] }, geometry: { type: "MultiPolygon", coordinates: [[[[26.03489, 40.73051], [26.0754, 40.72772], [26.08638, 40.73214], [26.12495, 40.74283], [26.12854, 40.77339], [26.15685, 40.80709], [26.21351, 40.83298], [26.20856, 40.86048], [26.26169, 40.9168], [26.29441, 40.89119], [26.28623, 40.93005], [26.32259, 40.94042], [26.35894, 40.94292], [26.33297, 40.98388], [26.3606, 41.02027], [26.31928, 41.07386], [26.32259, 41.24929], [26.39861, 41.25053], [26.5209, 41.33993], [26.5837, 41.32131], [26.62997, 41.34613], [26.61767, 41.42281], [26.59742, 41.48058], [26.59196, 41.60491], [26.5209, 41.62592], [26.47958, 41.67037], [26.35957, 41.71149], [26.30255, 41.70925], [26.2654, 41.71544], [26.22888, 41.74139], [26.21325, 41.73223], [26.16841, 41.74858], [26.06148, 41.70345], [26.07083, 41.64584], [26.15146, 41.60828], [26.14328, 41.55496], [26.17951, 41.55409], [26.176, 41.50072], [26.14796, 41.47533], [26.20288, 41.43943], [26.16548, 41.42278], [26.12926, 41.35878], [25.87919, 41.30526], [25.8266, 41.34563], [25.70507, 41.29209], [25.66183, 41.31316], [25.61042, 41.30614], [25.55082, 41.31667], [25.52394, 41.2798], [25.48187, 41.28506], [25.28322, 41.23411], [25.11611, 41.34212], [24.942, 41.38685], [24.90928, 41.40876], [24.86136, 41.39298], [24.82514, 41.4035], [24.8041, 41.34913], [24.71529, 41.41928], [24.61129, 41.42278], [24.52599, 41.56808], [24.30513, 41.51297], [24.27124, 41.57682], [24.18126, 41.51735], [24.10063, 41.54796], [24.06323, 41.53222], [24.06908, 41.46132], [23.96975, 41.44118], [23.91483, 41.47971], [23.89613, 41.45257], [23.80148, 41.43943], [23.76525, 41.40175], [23.67644, 41.41139], [23.63203, 41.37632], [23.52453, 41.40262], [23.40416, 41.39999], [23.33639, 41.36317], [23.31301, 41.40525], [23.22771, 41.37106], [23.21953, 41.33773], [23.1833, 41.31755], [22.93334, 41.34104], [22.81199, 41.3398], [22.76408, 41.32225], [22.74538, 41.16321], [22.71266, 41.13945], [22.65306, 41.18168], [22.62852, 41.14385], [22.58295, 41.11568], [22.5549, 41.13065], [22.42285, 41.11921], [22.26744, 41.16409], [22.17629, 41.15969], [22.1424, 41.12449], [22.06527, 41.15617], [21.90869, 41.09191], [21.91102, 41.04786], [21.7556, 40.92525], [21.69601, 40.9429], [21.57448, 40.86076], [21.53007, 40.90759], [21.41555, 40.9173], [21.35595, 40.87578], [21.25779, 40.86165], [21.21105, 40.8855], [21.15262, 40.85546], [20.97887, 40.85475], [20.98396, 40.79109], [20.95752, 40.76982], [20.98134, 40.76046], [21.05833, 40.66586], [21.03932, 40.56299], [20.96908, 40.51526], [20.94925, 40.46625], [20.83688, 40.47882], [20.7906, 40.42726], [20.78234, 40.35803], [20.71789, 40.27739], [20.67162, 40.09433], [20.62566, 40.0897], [20.61081, 40.07866], [20.55593, 40.06524], [20.51297, 40.08168], [20.48487, 40.06271], [20.42373, 40.06777], [20.37911, 39.99058], [20.31135, 39.99438], [20.41546, 39.82832], [20.41475, 39.81437], [20.38572, 39.78516], [20.30804, 39.81563], [20.29152, 39.80421], [20.31961, 39.72799], [20.27412, 39.69884], [20.22707, 39.67459], [20.22376, 39.64532], [20.15988, 39.652], [20.12956, 39.65805], [20.05189, 39.69112], [20.00957, 39.69227], [19.98042, 39.6504], [19.92466, 39.69533], [19.97622, 39.78684], [19.95905, 39.82857], [19.0384, 40.35325], [19.20409, 39.7532], [22.5213, 33.45682], [29.73302, 35.92555], [29.69611, 36.10365], [29.61805, 36.14179], [29.61002, 36.1731], [29.48192, 36.18377], [29.30783, 36.01033], [28.23708, 36.56812], [27.95037, 36.46155], [27.89482, 36.69898], [27.46117, 36.53789], [27.24613, 36.71622], [27.45627, 36.9008], [27.20312, 36.94571], [27.14757, 37.32], [26.95583, 37.64989], [26.99377, 37.69034], [27.16428, 37.72343], [27.05537, 37.9131], [26.21136, 38.17558], [26.24183, 38.44695], [26.32173, 38.48731], [26.21136, 38.65436], [26.61814, 38.81372], [26.70773, 39.0312], [26.43357, 39.43096], [25.94257, 39.39358], [25.61285, 40.17161], [26.04292, 40.3958], [25.94795, 40.72797], [26.03489, 40.73051]]]] } },
23193 { type: "Feature", properties: { iso1A2: "GS", iso1A3: "SGS", iso1N3: "239", wikidata: "Q35086", nameEn: "South Georgia and South Sandwich Islands", country: "GB", groups: ["BOTS", "005", "419", "019", "UN"], driveSide: "left", roadSpeedUnit: "mph", roadHeightUnit: "ft", callingCodes: ["500"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-35.26394, -43.68272], [-53.39656, -59.87088], [-22.31757, -59.85974], [-35.26394, -43.68272]]]] } },
23194 { type: "Feature", properties: { iso1A2: "GT", iso1A3: "GTM", iso1N3: "320", wikidata: "Q774", nameEn: "Guatemala", groups: ["013", "003", "419", "019", "UN"], callingCodes: ["502"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-89.14985, 17.81563], [-90.98678, 17.81655], [-90.99199, 17.25192], [-91.43809, 17.25373], [-91.04436, 16.92175], [-90.69064, 16.70697], [-90.61212, 16.49832], [-90.40499, 16.40524], [-90.44567, 16.07573], [-91.73182, 16.07371], [-92.20983, 15.26077], [-92.0621, 15.07406], [-92.1454, 14.98143], [-92.1423, 14.88647], [-92.18161, 14.84147], [-92.1454, 14.6804], [-92.2261, 14.53423], [-92.37213, 14.39277], [-90.55276, 12.8866], [-90.11344, 13.73679], [-90.10505, 13.85104], [-89.88937, 14.0396], [-89.81807, 14.07073], [-89.76103, 14.02923], [-89.73251, 14.04133], [-89.75569, 14.07073], [-89.70756, 14.1537], [-89.61844, 14.21937], [-89.52397, 14.22628], [-89.50614, 14.26084], [-89.58814, 14.33165], [-89.57441, 14.41637], [-89.39028, 14.44561], [-89.34776, 14.43013], [-89.35189, 14.47553], [-89.23719, 14.58046], [-89.15653, 14.57802], [-89.13132, 14.71582], [-89.23467, 14.85596], [-89.15149, 14.97775], [-89.18048, 14.99967], [-89.15149, 15.07392], [-88.97343, 15.14039], [-88.32467, 15.63665], [-88.31459, 15.66942], [-88.24022, 15.69247], [-88.22552, 15.72294], [-88.20359, 16.03858], [-88.40779, 16.09624], [-88.95358, 15.88698], [-89.02415, 15.9063], [-89.17418, 15.90898], [-89.22683, 15.88619], [-89.15025, 17.04813], [-89.14985, 17.81563]]]] } },
23195 { type: "Feature", properties: { iso1A2: "GU", iso1A3: "GUM", iso1N3: "316", wikidata: "Q16635", nameEn: "Guam", aliases: ["US-GU"], country: "US", groups: ["Q1352230", "Q153732", "057", "009", "UN"], roadSpeedUnit: "mph", roadHeightUnit: "ft", callingCodes: ["1 671"] }, geometry: { type: "MultiPolygon", coordinates: [[[[146.25931, 13.85876], [143.82485, 13.92273], [144.61642, 12.82462], [146.25931, 13.85876]]]] } },
23196 { type: "Feature", properties: { iso1A2: "GW", iso1A3: "GNB", iso1N3: "624", wikidata: "Q1007", nameEn: "Guinea-Bissau", groups: ["011", "202", "002", "UN"], callingCodes: ["245"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-14.31513, 11.60713], [-14.26623, 11.67486], [-14.09799, 11.63649], [-13.7039, 11.70195], [-13.7039, 12.00869], [-13.94589, 12.16869], [-13.92745, 12.24077], [-13.70851, 12.24978], [-13.64168, 12.42764], [-13.65089, 12.49515], [-13.7039, 12.60313], [-13.70523, 12.68013], [-15.17582, 12.6847], [-15.67302, 12.42974], [-16.20591, 12.46157], [-16.38191, 12.36449], [-16.70562, 12.34803], [-17.4623, 11.92379], [-15.96748, 10.162], [-15.07174, 10.89557], [-14.95993, 10.99244], [-14.77786, 11.36323], [-14.66677, 11.51188], [-14.51173, 11.49708], [-14.31513, 11.60713]]]] } },
23197 { type: "Feature", properties: { iso1A2: "GY", iso1A3: "GUY", iso1N3: "328", wikidata: "Q734", nameEn: "Guyana", groups: ["005", "419", "019", "UN"], driveSide: "left", callingCodes: ["592"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-56.84822, 6.73257], [-59.54058, 8.6862], [-59.98508, 8.53046], [-59.85562, 8.35213], [-59.80661, 8.28906], [-59.83156, 8.23261], [-59.97059, 8.20791], [-60.02407, 8.04557], [-60.38056, 7.8302], [-60.51959, 7.83373], [-60.64793, 7.56877], [-60.71923, 7.55817], [-60.59802, 7.33194], [-60.63367, 7.25061], [-60.54098, 7.14804], [-60.44116, 7.20817], [-60.28074, 7.1162], [-60.39419, 6.94847], [-60.54873, 6.8631], [-61.13632, 6.70922], [-61.20762, 6.58174], [-61.15058, 6.19558], [-61.4041, 5.95304], [-60.73204, 5.20931], [-60.32352, 5.21299], [-60.20944, 5.28754], [-59.98129, 5.07097], [-60.04189, 4.69801], [-60.15953, 4.53456], [-59.78878, 4.45637], [-59.69361, 4.34069], [-59.73353, 4.20399], [-59.51963, 3.91951], [-59.86899, 3.57089], [-59.79769, 3.37162], [-59.99733, 2.92312], [-59.91177, 2.36759], [-59.7264, 2.27497], [-59.74066, 1.87596], [-59.25583, 1.40559], [-58.92072, 1.31293], [-58.84229, 1.17749], [-58.53571, 1.29154], [-58.4858, 1.48399], [-58.33887, 1.58014], [-58.01873, 1.51966], [-57.97336, 1.64566], [-57.77281, 1.73344], [-57.55743, 1.69605], [-57.35073, 1.98327], [-57.23981, 1.95808], [-57.09109, 2.01854], [-57.07092, 1.95304], [-56.7659, 1.89509], [-56.47045, 1.95135], [-56.55439, 2.02003], [-56.70519, 2.02964], [-57.35891, 3.32121], [-58.0307, 3.95513], [-57.8699, 4.89394], [-57.37442, 5.0208], [-57.22536, 5.15605], [-57.31629, 5.33714], [-56.84822, 6.73257]]]] } },
23198 { type: "Feature", properties: { iso1A2: "HK", iso1A3: "HKG", iso1N3: "344", wikidata: "Q8646", nameEn: "Hong Kong", country: "CN", groups: ["030", "142", "UN"], driveSide: "left", callingCodes: ["852"] }, geometry: { type: "MultiPolygon", coordinates: [[[[113.92195, 22.13873], [114.50148, 22.15017], [114.44998, 22.55977], [114.25154, 22.55977], [114.22888, 22.5436], [114.22185, 22.55343], [114.20655, 22.55706], [114.18338, 22.55444], [114.17247, 22.55944], [114.1597, 22.56041], [114.15123, 22.55163], [114.1482, 22.54091], [114.13823, 22.54319], [114.12665, 22.54003], [114.11656, 22.53415], [114.11181, 22.52878], [114.1034, 22.5352], [114.09692, 22.53435], [114.09048, 22.53716], [114.08606, 22.53276], [114.07817, 22.52997], [114.07267, 22.51855], [114.06272, 22.51617], [114.05729, 22.51104], [114.05438, 22.5026], [114.03113, 22.5065], [113.86771, 22.42972], [113.81621, 22.2163], [113.83338, 22.1826], [113.92195, 22.13873]]]] } },
23199 { type: "Feature", properties: { iso1A2: "HM", iso1A3: "HMD", iso1N3: "334", wikidata: "Q131198", nameEn: "Heard Island and McDonald Islands", country: "AU", groups: ["053", "009", "UN"], driveSide: "left" }, geometry: { type: "MultiPolygon", coordinates: [[[[71.08716, -53.87687], [75.44182, -53.99822], [72.87012, -51.48322], [71.08716, -53.87687]]]] } },
23200 { type: "Feature", properties: { iso1A2: "HN", iso1A3: "HND", iso1N3: "340", wikidata: "Q783", nameEn: "Honduras", groups: ["013", "003", "419", "019", "UN"], callingCodes: ["504"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-83.86109, 17.73736], [-88.20359, 16.03858], [-88.22552, 15.72294], [-88.24022, 15.69247], [-88.31459, 15.66942], [-88.32467, 15.63665], [-88.97343, 15.14039], [-89.15149, 15.07392], [-89.18048, 14.99967], [-89.15149, 14.97775], [-89.23467, 14.85596], [-89.13132, 14.71582], [-89.15653, 14.57802], [-89.23719, 14.58046], [-89.35189, 14.47553], [-89.34776, 14.43013], [-89.04187, 14.33644], [-88.94608, 14.20207], [-88.85785, 14.17763], [-88.815, 14.11652], [-88.73182, 14.10919], [-88.70661, 14.04317], [-88.49738, 13.97224], [-88.48982, 13.86458], [-88.25791, 13.91108], [-88.23018, 13.99915], [-88.07641, 13.98447], [-88.00331, 13.86948], [-87.7966, 13.91353], [-87.68821, 13.80829], [-87.73106, 13.75443], [-87.78148, 13.52906], [-87.71657, 13.50577], [-87.72115, 13.46083], [-87.73841, 13.44169], [-87.77354, 13.45767], [-87.83467, 13.44655], [-87.84675, 13.41078], [-87.80177, 13.35689], [-87.73714, 13.32715], [-87.69751, 13.25228], [-87.55124, 13.12523], [-87.37107, 12.98646], [-87.06306, 13.00892], [-87.03785, 12.98682], [-86.93197, 13.05313], [-86.93383, 13.18677], [-86.87066, 13.30641], [-86.71267, 13.30348], [-86.76812, 13.79605], [-86.35219, 13.77157], [-86.14801, 14.04317], [-86.00685, 14.08474], [-86.03458, 13.99181], [-85.75477, 13.8499], [-85.73964, 13.9698], [-85.45762, 14.11304], [-85.32149, 14.2562], [-85.18602, 14.24929], [-85.1575, 14.53934], [-84.90082, 14.80489], [-84.82596, 14.82212], [-84.70119, 14.68078], [-84.48373, 14.63249], [-84.10584, 14.76353], [-83.89551, 14.76697], [-83.62101, 14.89448], [-83.49268, 15.01158], [-83.13724, 15.00002], [-83.04763, 15.03256], [-82.06974, 14.49418], [-81.58685, 18.0025], [-83.86109, 17.73736]]]] } },
23201 { type: "Feature", properties: { iso1A2: "HR", iso1A3: "HRV", iso1N3: "191", wikidata: "Q224", nameEn: "Croatia", groups: ["EU", "039", "150", "UN"], callingCodes: ["385"] }, geometry: { type: "MultiPolygon", coordinates: [[[[17.6444, 42.88641], [17.5392, 42.92787], [17.70879, 42.97223], [17.64268, 43.08595], [17.46986, 43.16559], [17.286, 43.33065], [17.25579, 43.40353], [17.29699, 43.44542], [17.24411, 43.49376], [17.15828, 43.49376], [17.00585, 43.58037], [16.80736, 43.76011], [16.75316, 43.77157], [16.70922, 43.84887], [16.55472, 43.95326], [16.50528, 44.0244], [16.43629, 44.02826], [16.43662, 44.07523], [16.36864, 44.08263], [16.18688, 44.27012], [16.21346, 44.35231], [16.12969, 44.38275], [16.16814, 44.40679], [16.10566, 44.52586], [16.03012, 44.55572], [16.00884, 44.58605], [16.05828, 44.61538], [15.89348, 44.74964], [15.8255, 44.71501], [15.72584, 44.82334], [15.79472, 44.8455], [15.76096, 44.87045], [15.74723, 44.96818], [15.78568, 44.97401], [15.74585, 45.0638], [15.78842, 45.11519], [15.76371, 45.16508], [15.83512, 45.22459], [15.98412, 45.23088], [16.12153, 45.09616], [16.29036, 44.99732], [16.35404, 45.00241], [16.35863, 45.03529], [16.3749, 45.05206], [16.38219, 45.05139], [16.38309, 45.05955], [16.40023, 45.1147], [16.4634, 45.14522], [16.49155, 45.21153], [16.52982, 45.22713], [16.5501, 45.2212], [16.56559, 45.22307], [16.60194, 45.23042], [16.64962, 45.20714], [16.74845, 45.20393], [16.78219, 45.19002], [16.81137, 45.18434], [16.83804, 45.18951], [16.92405, 45.27607], [16.9385, 45.22742], [17.0415, 45.20759], [17.18438, 45.14764], [17.24325, 45.146], [17.25131, 45.14957], [17.26815, 45.18444], [17.32092, 45.16246], [17.33573, 45.14521], [17.41229, 45.13335], [17.4498, 45.16119], [17.45615, 45.12523], [17.47589, 45.12656], [17.51469, 45.10791], [17.59104, 45.10816], [17.66571, 45.13408], [17.84826, 45.04489], [17.87148, 45.04645], [17.93706, 45.08016], [17.97336, 45.12245], [17.97834, 45.13831], [17.99479, 45.14958], [18.01594, 45.15163], [18.03121, 45.12632], [18.1624, 45.07654], [18.24387, 45.13699], [18.32077, 45.1021], [18.41896, 45.11083], [18.47939, 45.05871], [18.65723, 45.07544], [18.78357, 44.97741], [18.80661, 44.93561], [18.76369, 44.93707], [18.76347, 44.90669], [18.8704, 44.85097], [19.01994, 44.85493], [18.98957, 44.90645], [19.02871, 44.92541], [19.06853, 44.89915], [19.15573, 44.95409], [19.05205, 44.97692], [19.1011, 45.01191], [19.07952, 45.14668], [19.14063, 45.12972], [19.19144, 45.17863], [19.43589, 45.17137], [19.41941, 45.23475], [19.28208, 45.23813], [19.10774, 45.29547], [18.97446, 45.37528], [18.99918, 45.49333], [19.08364, 45.48804], [19.07471, 45.53086], [18.94562, 45.53712], [18.88776, 45.57253], [18.96691, 45.66731], [18.90305, 45.71863], [18.85783, 45.85493], [18.81394, 45.91329], [18.80211, 45.87995], [18.6792, 45.92057], [18.57483, 45.80772], [18.44368, 45.73972], [18.12439, 45.78905], [18.08869, 45.76511], [17.99805, 45.79671], [17.87377, 45.78522], [17.66545, 45.84207], [17.56821, 45.93728], [17.35672, 45.95209], [17.14592, 46.16697], [16.8903, 46.28122], [16.8541, 46.36255], [16.7154, 46.39523], [16.6639, 46.45203], [16.59527, 46.47524], [16.52604, 46.47831], [16.5007, 46.49644], [16.44036, 46.5171], [16.38771, 46.53608], [16.37193, 46.55008], [16.29793, 46.5121], [16.26733, 46.51505], [16.26759, 46.50566], [16.23961, 46.49653], [16.25124, 46.48067], [16.27398, 46.42875], [16.27329, 46.41467], [16.30162, 46.40437], [16.30233, 46.37837], [16.18824, 46.38282], [16.14859, 46.40547], [16.05281, 46.39141], [16.05065, 46.3833], [16.07314, 46.36458], [16.07616, 46.3463], [15.97965, 46.30652], [15.79284, 46.25811], [15.78817, 46.21719], [15.75479, 46.20336], [15.75436, 46.21969], [15.67395, 46.22478], [15.6434, 46.21396], [15.64904, 46.19229], [15.59909, 46.14761], [15.6083, 46.11992], [15.62317, 46.09103], [15.72977, 46.04682], [15.71246, 46.01196], [15.70327, 46.00015], [15.70636, 45.92116], [15.67967, 45.90455], [15.68383, 45.88867], [15.68232, 45.86819], [15.70411, 45.8465], [15.66662, 45.84085], [15.64185, 45.82915], [15.57952, 45.84953], [15.52234, 45.82195], [15.47325, 45.8253], [15.47531, 45.79802], [15.40836, 45.79491], [15.25423, 45.72275], [15.30872, 45.69014], [15.34919, 45.71623], [15.4057, 45.64727], [15.38952, 45.63682], [15.34214, 45.64702], [15.34695, 45.63382], [15.31027, 45.6303], [15.27747, 45.60504], [15.29837, 45.5841], [15.30249, 45.53224], [15.38188, 45.48752], [15.33051, 45.45258], [15.27758, 45.46678], [15.16862, 45.42309], [15.05187, 45.49079], [15.02385, 45.48533], [14.92266, 45.52788], [14.90554, 45.47769], [14.81992, 45.45913], [14.80124, 45.49515], [14.71718, 45.53442], [14.68605, 45.53006], [14.69694, 45.57366], [14.59576, 45.62812], [14.60977, 45.66403], [14.57397, 45.67165], [14.53816, 45.6205], [14.5008, 45.60852], [14.49769, 45.54424], [14.36693, 45.48642], [14.32487, 45.47142], [14.27681, 45.4902], [14.26611, 45.48239], [14.24239, 45.50607], [14.22371, 45.50388], [14.20348, 45.46896], [14.07116, 45.48752], [14.00578, 45.52352], [13.96063, 45.50825], [13.99488, 45.47551], [13.97309, 45.45258], [13.90771, 45.45149], [13.88124, 45.42637], [13.81742, 45.43729], [13.7785, 45.46787], [13.67398, 45.4436], [13.62902, 45.45898], [13.56979, 45.4895], [13.45644, 45.59464], [13.05142, 45.33128], [13.12821, 44.48877], [16.15283, 42.18525], [18.45131, 42.21682], [18.54128, 42.39171], [18.52152, 42.42302], [18.43588, 42.48556], [18.44307, 42.51077], [18.43735, 42.55921], [18.36197, 42.61423], [18.24318, 42.6112], [17.88201, 42.83668], [17.80854, 42.9182], [17.7948, 42.89556], [17.68151, 42.92725], [17.6444, 42.88641]]]] } },
23202 { type: "Feature", properties: { iso1A2: "HT", iso1A3: "HTI", iso1N3: "332", wikidata: "Q790", nameEn: "Haiti", aliases: ["RH"], groups: ["029", "003", "419", "019", "UN"], callingCodes: ["509"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-71.71885, 18.78423], [-71.72624, 18.87802], [-71.77766, 18.95007], [-71.88102, 18.95007], [-71.74088, 19.0437], [-71.71088, 19.08353], [-71.69938, 19.10916], [-71.65337, 19.11759], [-71.62642, 19.21212], [-71.73229, 19.26686], [-71.77766, 19.33823], [-71.69448, 19.37866], [-71.6802, 19.45008], [-71.71268, 19.53374], [-71.71449, 19.55364], [-71.7429, 19.58445], [-71.75865, 19.70231], [-71.77419, 19.73128], [-72.38946, 20.27111], [-73.37289, 20.43199], [-74.7289, 18.71009], [-74.76465, 18.06252], [-72.29523, 17.48026], [-71.75671, 18.03456], [-71.73783, 18.07177], [-71.74994, 18.11115], [-71.75465, 18.14405], [-71.78271, 18.18302], [-71.69952, 18.34101], [-71.90875, 18.45821], [-71.88102, 18.50125], [-72.00201, 18.62312], [-71.95412, 18.64939], [-71.82556, 18.62551], [-71.71885, 18.78423]]]] } },
23203 { 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]]]] } },
23204 { 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]]]] } },
23205 { type: "Feature", properties: { iso1A2: "ID", iso1A3: "IDN", iso1N3: "360", wikidata: "Q252", nameEn: "Indonesia", aliases: ["RI"] }, geometry: null },
23206 { 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"] } },
23207 { 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]]]] } },
23208 { 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]]]] } },
23209 { type: "Feature", properties: { iso1A2: "IN", iso1A3: "IND", iso1N3: "356", wikidata: "Q668", nameEn: "India" }, geometry: null },
23210 { type: "Feature", properties: { iso1A2: "IO", iso1A3: "IOT", iso1N3: "086", wikidata: "Q43448", nameEn: "British Indian Ocean Territory", country: "GB" }, geometry: null },
23211 { type: "Feature", properties: { iso1A2: "IQ", iso1A3: "IRQ", iso1N3: "368", wikidata: "Q796", nameEn: "Iraq", groups: ["145", "142", "UN"], callingCodes: ["964"] }, geometry: { type: "MultiPolygon", coordinates: [[[[42.78887, 37.38615], [42.56725, 37.14878], [42.35724, 37.10998], [42.36697, 37.0627], [41.81736, 36.58782], [41.40058, 36.52502], [41.28864, 36.35368], [41.2564, 36.06012], [41.37027, 35.84095], [41.38184, 35.62502], [41.26569, 35.42708], [41.21654, 35.1508], [41.2345, 34.80049], [41.12388, 34.65742], [40.97676, 34.39788], [40.64314, 34.31604], [38.79171, 33.37328], [39.08202, 32.50304], [38.98762, 32.47694], [39.04251, 32.30203], [39.26157, 32.35555], [39.29903, 32.23259], [40.01521, 32.05667], [42.97601, 30.72204], [42.97796, 30.48295], [44.72255, 29.19736], [46.42415, 29.05947], [46.5527, 29.10283], [46.89695, 29.50584], [47.15166, 30.01044], [47.37192, 30.10421], [47.7095, 30.10453], [48.01114, 29.98906], [48.06782, 30.02906], [48.17332, 30.02448], [48.40479, 29.85763], [48.59531, 29.66815], [48.83867, 29.78572], [48.61441, 29.93675], [48.51011, 29.96238], [48.44785, 30.00148], [48.4494, 30.04456], [48.43384, 30.08233], [48.38869, 30.11062], [48.38714, 30.13485], [48.41671, 30.17254], [48.41117, 30.19846], [48.26393, 30.3408], [48.24385, 30.33846], [48.21279, 30.31644], [48.19425, 30.32796], [48.18321, 30.39703], [48.14585, 30.44133], [48.02443, 30.4789], [48.03221, 30.9967], [47.68219, 31.00004], [47.6804, 31.39086], [47.86337, 31.78422], [47.64771, 32.07666], [47.52474, 32.15972], [47.57144, 32.20583], [47.37529, 32.47808], [47.17218, 32.45393], [46.46788, 32.91992], [46.32298, 32.9731], [46.17198, 32.95612], [46.09103, 32.98354], [46.15175, 33.07229], [46.03966, 33.09577], [46.05367, 33.13097], [46.11905, 33.11924], [46.20623, 33.20395], [45.99919, 33.5082], [45.86687, 33.49263], [45.96183, 33.55751], [45.89801, 33.63661], [45.77814, 33.60938], [45.50261, 33.94968], [45.42789, 33.9458], [45.41077, 33.97421], [45.47264, 34.03099], [45.56176, 34.15088], [45.58667, 34.30147], [45.53552, 34.35148], [45.49171, 34.3439], [45.46697, 34.38221], [45.43879, 34.45949], [45.51883, 34.47692], [45.53219, 34.60441], [45.59074, 34.55558], [45.60224, 34.55057], [45.73923, 34.54416], [45.70031, 34.69277], [45.65672, 34.7222], [45.68284, 34.76624], [45.70031, 34.82322], [45.73641, 34.83975], [45.79682, 34.85133], [45.78904, 34.91135], [45.86532, 34.89858], [45.89477, 34.95805], [45.87864, 35.03441], [45.92173, 35.0465], [45.92203, 35.09538], [45.93108, 35.08148], [45.94756, 35.09188], [46.06508, 35.03699], [46.07747, 35.0838], [46.11763, 35.07551], [46.19116, 35.11097], [46.15642, 35.1268], [46.16229, 35.16984], [46.19738, 35.18536], [46.18457, 35.22561], [46.11367, 35.23729], [46.15474, 35.2883], [46.13152, 35.32548], [46.05358, 35.38568], [45.98453, 35.49848], [46.01518, 35.52012], [45.97584, 35.58132], [46.03028, 35.57416], [46.01307, 35.59756], [46.0165, 35.61501], [45.99452, 35.63574], [46.0117, 35.65059], [46.01631, 35.69139], [46.23736, 35.71414], [46.34166, 35.78363], [46.32921, 35.82655], [46.17198, 35.8013], [46.08325, 35.8581], [45.94711, 35.82218], [45.89784, 35.83708], [45.81442, 35.82107], [45.76145, 35.79898], [45.6645, 35.92872], [45.60018, 35.96069], [45.55245, 35.99943], [45.46594, 36.00042], [45.38275, 35.97156], [45.33916, 35.99424], [45.37652, 36.06222], [45.37312, 36.09917], [45.32235, 36.17383], [45.30038, 36.27769], [45.26261, 36.3001], [45.27394, 36.35846], [45.23953, 36.43257], [45.11811, 36.40751], [45.00759, 36.5402], [45.06985, 36.62645], [45.06985, 36.6814], [45.01537, 36.75128], [44.84725, 36.77622], [44.83479, 36.81362], [44.90173, 36.86096], [44.91199, 36.91468], [44.89862, 37.01897], [44.81611, 37.04383], [44.75229, 37.11958], [44.78319, 37.1431], [44.76698, 37.16162], [44.63179, 37.19229], [44.42631, 37.05825], [44.38117, 37.05825], [44.35315, 37.04955], [44.35937, 37.02843], [44.30645, 36.97373], [44.25975, 36.98119], [44.18503, 37.09551], [44.22239, 37.15756], [44.27998, 37.16501], [44.2613, 37.25055], [44.13521, 37.32486], [44.02002, 37.33229], [43.90949, 37.22453], [43.84878, 37.22205], [43.82699, 37.19477], [43.8052, 37.22825], [43.7009, 37.23692], [43.63085, 37.21957], [43.56702, 37.25675], [43.50787, 37.24436], [43.33508, 37.33105], [43.30083, 37.30629], [43.11403, 37.37436], [42.93705, 37.32015], [42.78887, 37.38615]]]] } },
23212 { type: "Feature", properties: { iso1A2: "IR", iso1A3: "IRN", iso1N3: "364", wikidata: "Q794", nameEn: "Iran", groups: ["034", "142", "UN"], callingCodes: ["98"] }, geometry: { type: "MultiPolygon", coordinates: [[[[44.96746, 39.42998], [44.88916, 39.59653], [44.81043, 39.62677], [44.71806, 39.71124], [44.65422, 39.72163], [44.6137, 39.78393], [44.47298, 39.68788], [44.48111, 39.61579], [44.41849, 39.56659], [44.42832, 39.4131], [44.37921, 39.4131], [44.29818, 39.378], [44.22452, 39.4169], [44.03667, 39.39223], [44.1043, 39.19842], [44.20946, 39.13975], [44.18863, 38.93881], [44.30322, 38.81581], [44.26155, 38.71427], [44.28065, 38.6465], [44.32058, 38.62752], [44.3207, 38.49799], [44.3119, 38.37887], [44.38309, 38.36117], [44.44386, 38.38295], [44.50115, 38.33939], [44.42476, 38.25763], [44.22509, 37.88859], [44.3883, 37.85433], [44.45948, 37.77065], [44.55498, 37.783], [44.62096, 37.71985], [44.56887, 37.6429], [44.61401, 37.60165], [44.58449, 37.45018], [44.81021, 37.2915], [44.75986, 37.21549], [44.7868, 37.16644], [44.78319, 37.1431], [44.75229, 37.11958], [44.81611, 37.04383], [44.89862, 37.01897], [44.91199, 36.91468], [44.90173, 36.86096], [44.83479, 36.81362], [44.84725, 36.77622], [45.01537, 36.75128], [45.06985, 36.6814], [45.06985, 36.62645], [45.00759, 36.5402], [45.11811, 36.40751], [45.23953, 36.43257], [45.27394, 36.35846], [45.26261, 36.3001], [45.30038, 36.27769], [45.32235, 36.17383], [45.37312, 36.09917], [45.37652, 36.06222], [45.33916, 35.99424], [45.38275, 35.97156], [45.46594, 36.00042], [45.55245, 35.99943], [45.60018, 35.96069], [45.6645, 35.92872], [45.76145, 35.79898], [45.81442, 35.82107], [45.89784, 35.83708], [45.94711, 35.82218], [46.08325, 35.8581], [46.17198, 35.8013], [46.32921, 35.82655], [46.34166, 35.78363], [46.23736, 35.71414], [46.01631, 35.69139], [46.0117, 35.65059], [45.99452, 35.63574], [46.0165, 35.61501], [46.01307, 35.59756], [46.03028, 35.57416], [45.97584, 35.58132], [46.01518, 35.52012], [45.98453, 35.49848], [46.05358, 35.38568], [46.13152, 35.32548], [46.15474, 35.2883], [46.11367, 35.23729], [46.18457, 35.22561], [46.19738, 35.18536], [46.16229, 35.16984], [46.15642, 35.1268], [46.19116, 35.11097], [46.11763, 35.07551], [46.07747, 35.0838], [46.06508, 35.03699], [45.94756, 35.09188], [45.93108, 35.08148], [45.92203, 35.09538], [45.92173, 35.0465], [45.87864, 35.03441], [45.89477, 34.95805], [45.86532, 34.89858], [45.78904, 34.91135], [45.79682, 34.85133], [45.73641, 34.83975], [45.70031, 34.82322], [45.68284, 34.76624], [45.65672, 34.7222], [45.70031, 34.69277], [45.73923, 34.54416], [45.60224, 34.55057], [45.59074, 34.55558], [45.53219, 34.60441], [45.51883, 34.47692], [45.43879, 34.45949], [45.46697, 34.38221], [45.49171, 34.3439], [45.53552, 34.35148], [45.58667, 34.30147], [45.56176, 34.15088], [45.47264, 34.03099], [45.41077, 33.97421], [45.42789, 33.9458], [45.50261, 33.94968], [45.77814, 33.60938], [45.89801, 33.63661], [45.96183, 33.55751], [45.86687, 33.49263], [45.99919, 33.5082], [46.20623, 33.20395], [46.11905, 33.11924], [46.05367, 33.13097], [46.03966, 33.09577], [46.15175, 33.07229], [46.09103, 32.98354], [46.17198, 32.95612], [46.32298, 32.9731], [46.46788, 32.91992], [47.17218, 32.45393], [47.37529, 32.47808], [47.57144, 32.20583], [47.52474, 32.15972], [47.64771, 32.07666], [47.86337, 31.78422], [47.6804, 31.39086], [47.68219, 31.00004], [48.03221, 30.9967], [48.02443, 30.4789], [48.14585, 30.44133], [48.18321, 30.39703], [48.19425, 30.32796], [48.21279, 30.31644], [48.24385, 30.33846], [48.26393, 30.3408], [48.41117, 30.19846], [48.41671, 30.17254], [48.38714, 30.13485], [48.38869, 30.11062], [48.43384, 30.08233], [48.4494, 30.04456], [48.44785, 30.00148], [48.51011, 29.96238], [48.61441, 29.93675], [48.83867, 29.78572], [49.98877, 27.87827], [50.37726, 27.89227], [54.39838, 25.68383], [55.14145, 25.62624], [55.81777, 26.18798], [56.2644, 26.58649], [56.68954, 26.76645], [56.79239, 26.41236], [56.82555, 25.7713], [56.86325, 25.03856], [61.46682, 24.57869], [61.6433, 25.27541], [61.683, 25.66638], [61.83968, 25.7538], [61.83831, 26.07249], [61.89391, 26.26251], [62.05117, 26.31647], [62.21304, 26.26601], [62.31484, 26.528], [62.77352, 26.64099], [63.1889, 26.65072], [63.18688, 26.83844], [63.25005, 26.84212], [63.25005, 27.08692], [63.32283, 27.14437], [63.19649, 27.25674], [62.80604, 27.22412], [62.79684, 27.34381], [62.84905, 27.47627], [62.7638, 28.02992], [62.79412, 28.28108], [62.59499, 28.24842], [62.40259, 28.42703], [61.93581, 28.55284], [61.65978, 28.77937], [61.53765, 29.00507], [61.31508, 29.38903], [60.87231, 29.86514], [61.80829, 30.84224], [61.78268, 30.92724], [61.8335, 30.97669], [61.83257, 31.0452], [61.80957, 31.12576], [61.80569, 31.16167], [61.70929, 31.37391], [60.84541, 31.49561], [60.86191, 32.22565], [60.56485, 33.12944], [60.88908, 33.50219], [60.91133, 33.55596], [60.69573, 33.56054], [60.57762, 33.59772], [60.5485, 33.73422], [60.5838, 33.80793], [60.50209, 34.13992], [60.66502, 34.31539], [60.91321, 34.30411], [60.72316, 34.52857], [60.99922, 34.63064], [61.00197, 34.70631], [61.06926, 34.82139], [61.12831, 35.09938], [61.0991, 35.27845], [61.18187, 35.30249], [61.27371, 35.61482], [61.22719, 35.67038], [61.26152, 35.80749], [61.22444, 35.92879], [61.12007, 35.95992], [61.22719, 36.12759], [61.1393, 36.38782], [61.18187, 36.55348], [61.14516, 36.64644], [60.34767, 36.63214], [60.00768, 37.04102], [59.74678, 37.12499], [59.55178, 37.13594], [59.39385, 37.34257], [59.39797, 37.47892], [59.33507, 37.53146], [59.22905, 37.51161], [58.9338, 37.67374], [58.6921, 37.64548], [58.5479, 37.70526], [58.47786, 37.6433], [58.39959, 37.63134], [58.22999, 37.6856], [58.21399, 37.77281], [57.79534, 37.89299], [57.35042, 37.98546], [57.37236, 38.09321], [57.21169, 38.28965], [57.03453, 38.18717], [56.73928, 38.27887], [56.62255, 38.24005], [56.43303, 38.26054], [56.32454, 38.18502], [56.33278, 38.08132], [55.97847, 38.08024], [55.76561, 38.12238], [55.44152, 38.08564], [55.13412, 37.94705], [54.851, 37.75739], [54.77684, 37.62264], [54.81804, 37.61285], [54.77822, 37.51597], [54.67247, 37.43532], [54.58664, 37.45809], [54.36211, 37.34912], [54.24565, 37.32047], [53.89734, 37.3464], [48.88288, 38.43975], [48.84969, 38.45015], [48.81072, 38.44853], [48.78979, 38.45026], [48.70001, 38.40564], [48.62217, 38.40198], [48.58793, 38.45076], [48.45084, 38.61013], [48.3146, 38.59958], [48.24773, 38.71883], [48.02581, 38.82705], [48.01409, 38.90333], [48.07734, 38.91616], [48.08627, 38.94434], [48.28437, 38.97186], [48.33884, 39.03022], [48.31239, 39.09278], [48.15361, 39.19419], [48.12404, 39.25208], [48.15984, 39.30028], [48.37385, 39.37584], [48.34264, 39.42935], [47.98977, 39.70999], [47.84774, 39.66285], [47.50099, 39.49615], [47.38978, 39.45999], [47.31301, 39.37492], [47.05927, 39.24846], [47.05771, 39.20143], [46.95341, 39.13505], [46.92539, 39.16644], [46.83822, 39.13143], [46.75752, 39.03231], [46.53497, 38.86548], [46.34059, 38.92076], [46.20601, 38.85262], [46.14785, 38.84206], [46.06766, 38.87861], [46.00228, 38.87376], [45.94624, 38.89072], [45.90266, 38.87739], [45.83883, 38.90768], [45.65172, 38.95199], [45.6155, 38.94304], [45.6131, 38.964], [45.44966, 38.99243], [45.44811, 39.04927], [45.40452, 39.07224], [45.40148, 39.09007], [45.30489, 39.18333], [45.16168, 39.21952], [45.08751, 39.35052], [45.05932, 39.36435], [44.96746, 39.42998]]]] } },
23213 { type: "Feature", properties: { iso1A2: "IS", iso1A3: "ISL", iso1N3: "352", wikidata: "Q189", nameEn: "Iceland", groups: ["154", "150", "UN"], callingCodes: ["354"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-33.15676, 62.62995], [-8.25539, 63.0423], [-15.70914, 69.67442], [-33.15676, 62.62995]]]] } },
23214 { type: "Feature", properties: { iso1A2: "IT", iso1A3: "ITA", iso1N3: "380", wikidata: "Q38", nameEn: "Italy", groups: ["EU", "039", "150", "UN"], callingCodes: ["39"] }, geometry: { type: "MultiPolygon", coordinates: [[[[8.95861, 45.96485], [8.97604, 45.96151], [8.97741, 45.98317], [8.96668, 45.98436], [8.95861, 45.96485]]], [[[7.63035, 43.57419], [9.56115, 43.20816], [10.09675, 41.44089], [7.60802, 41.05927], [7.89009, 38.19924], [11.2718, 37.6713], [12.13667, 34.20326], [14.02721, 36.53141], [17.67657, 35.68918], [18.83516, 40.36999], [16.15283, 42.18525], [13.12821, 44.48877], [13.05142, 45.33128], [13.45644, 45.59464], [13.6076, 45.64761], [13.7198, 45.59352], [13.74587, 45.59811], [13.78445, 45.5825], [13.84106, 45.58185], [13.86771, 45.59898], [13.8695, 45.60835], [13.9191, 45.6322], [13.87933, 45.65207], [13.83422, 45.68703], [13.83332, 45.70855], [13.8235, 45.7176], [13.66986, 45.79955], [13.59784, 45.8072], [13.58858, 45.83503], [13.57563, 45.8425], [13.58644, 45.88173], [13.59565, 45.89446], [13.60857, 45.89907], [13.61931, 45.91782], [13.63815, 45.93607], [13.6329, 45.94894], [13.64307, 45.98326], [13.63458, 45.98947], [13.62074, 45.98388], [13.58903, 45.99009], [13.56759, 45.96991], [13.52963, 45.96588], [13.50104, 45.98078], [13.47474, 46.00546], [13.49702, 46.01832], [13.50998, 46.04498], [13.49568, 46.04839], [13.50104, 46.05986], [13.57072, 46.09022], [13.64053, 46.13587], [13.66472, 46.17392], [13.64451, 46.18966], [13.56682, 46.18703], [13.56114, 46.2054], [13.47587, 46.22725], [13.42218, 46.20758], [13.37671, 46.29668], [13.44808, 46.33507], [13.43418, 46.35992], [13.47019, 46.3621], [13.5763, 46.40915], [13.5763, 46.42613], [13.59777, 46.44137], [13.68684, 46.43881], [13.7148, 46.5222], [13.64088, 46.53438], [13.27627, 46.56059], [12.94445, 46.60401], [12.59992, 46.6595], [12.38708, 46.71529], [12.27591, 46.88651], [12.2006, 46.88854], [12.11675, 47.01241], [12.21781, 47.03996], [12.19254, 47.09331], [11.74789, 46.98484], [11.50739, 47.00644], [11.33355, 46.99862], [11.10618, 46.92966], [11.00764, 46.76896], [10.72974, 46.78972], [10.75753, 46.82258], [10.66405, 46.87614], [10.54783, 46.84505], [10.47197, 46.85698], [10.38659, 46.67847], [10.40475, 46.63671], [10.44686, 46.64162], [10.49375, 46.62049], [10.46136, 46.53164], [10.25309, 46.57432], [10.23674, 46.63484], [10.10307, 46.61003], [10.03715, 46.44479], [10.165, 46.41051], [10.10506, 46.3372], [10.17862, 46.25626], [10.14439, 46.22992], [10.07055, 46.21668], [9.95249, 46.38045], [9.73086, 46.35071], [9.71273, 46.29266], [9.57015, 46.2958], [9.46117, 46.37481], [9.45936, 46.50873], [9.40487, 46.46621], [9.36128, 46.5081], [9.28136, 46.49685], [9.25502, 46.43743], [9.29226, 46.32717], [9.24503, 46.23616], [9.01618, 46.04928], [8.99257, 45.9698], [9.09065, 45.89906], [9.06642, 45.8761], [9.04546, 45.84968], [9.04059, 45.8464], [9.03505, 45.83976], [9.03793, 45.83548], [9.03279, 45.82865], [9.0298, 45.82127], [9.00324, 45.82055], [8.99663, 45.83466], [8.9621, 45.83707], [8.94737, 45.84285], [8.91129, 45.8388], [8.93504, 45.86245], [8.94372, 45.86587], [8.93649, 45.86775], [8.88904, 45.95465], [8.86688, 45.96135], [8.85121, 45.97239], [8.8319, 45.9879], [8.79362, 45.99207], [8.78585, 45.98973], [8.79414, 46.00913], [8.85617, 46.0748], [8.80778, 46.10085], [8.75697, 46.10395], [8.62242, 46.12112], [8.45032, 46.26869], [8.46317, 46.43712], [8.42464, 46.46367], [8.30648, 46.41587], [8.31162, 46.38044], [8.08814, 46.26692], [8.16866, 46.17817], [8.11383, 46.11577], [8.02906, 46.10331], [7.98881, 45.99867], [7.9049, 45.99945], [7.85949, 45.91485], [7.56343, 45.97421], [7.10685, 45.85653], [7.04151, 45.92435], [6.95315, 45.85163], [6.80785, 45.83265], [6.80785, 45.71864], [6.98948, 45.63869], [7.00037, 45.509], [7.18019, 45.40071], [7.10572, 45.32924], [7.13115, 45.25386], [7.07074, 45.21228], [6.96706, 45.20841], [6.85144, 45.13226], [6.7697, 45.16044], [6.62803, 45.11175], [6.66981, 45.02324], [6.74791, 45.01939], [6.74519, 44.93661], [6.75518, 44.89915], [6.90774, 44.84322], [6.93499, 44.8664], [7.02217, 44.82519], [7.00401, 44.78782], [7.07484, 44.68073], [7.00582, 44.69364], [6.95133, 44.66264], [6.96042, 44.62129], [6.85507, 44.53072], [6.86233, 44.49834], [6.94504, 44.43112], [6.88784, 44.42043], [6.89171, 44.36637], [6.98221, 44.28289], [7.00764, 44.23736], [7.16929, 44.20352], [7.27827, 44.1462], [7.34547, 44.14359], [7.36364, 44.11882], [7.62155, 44.14881], [7.63245, 44.17877], [7.68694, 44.17487], [7.66878, 44.12795], [7.72508, 44.07578], [7.6597, 44.03009], [7.66848, 43.99943], [7.65266, 43.9763], [7.60771, 43.95772], [7.56858, 43.94506], [7.56075, 43.89932], [7.51162, 43.88301], [7.49355, 43.86551], [7.50423, 43.84345], [7.53006, 43.78405], [7.63035, 43.57419]], [[12.45181, 41.90056], [12.44834, 41.90095], [12.44582, 41.90194], [12.44815, 41.90326], [12.44984, 41.90545], [12.45091, 41.90625], [12.45543, 41.90738], [12.45561, 41.90629], [12.45762, 41.9058], [12.45755, 41.9033], [12.45826, 41.90281], [12.45834, 41.90174], [12.4577, 41.90115], [12.45691, 41.90125], [12.45626, 41.90172], [12.45435, 41.90143], [12.45446, 41.90028], [12.45181, 41.90056]], [[12.45648, 43.89369], [12.44184, 43.90498], [12.41641, 43.89991], [12.40935, 43.9024], [12.41233, 43.90956], [12.40733, 43.92379], [12.41551, 43.92984], [12.41165, 43.93769], [12.40506, 43.94325], [12.40415, 43.95485], [12.41414, 43.95273], [12.42005, 43.9578], [12.43662, 43.95698], [12.44684, 43.96597], [12.46205, 43.97463], [12.47853, 43.98052], [12.49406, 43.98492], [12.50678, 43.99113], [12.51463, 43.99122], [12.5154, 43.98508], [12.51064, 43.98165], [12.51109, 43.97201], [12.50622, 43.97131], [12.50875, 43.96198], [12.50655, 43.95796], [12.51427, 43.94897], [12.51553, 43.94096], [12.50496, 43.93017], [12.50269, 43.92363], [12.49724, 43.92248], [12.49247, 43.91774], [12.49429, 43.90973], [12.48771, 43.89706], [12.45648, 43.89369]]]] } },
23215 { type: "Feature", properties: { iso1A2: "JE", iso1A3: "JEY", iso1N3: "832", wikidata: "Q785", nameEn: "Bailiwick of Jersey", country: "GB", groups: ["830", "Q185086", "154", "150", "UN"], driveSide: "left", roadSpeedUnit: "mph", roadHeightUnit: "ft", callingCodes: ["44 01534"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-2.00491, 48.86706], [-1.83944, 49.23037], [-2.09454, 49.46288], [-2.65349, 49.15373], [-2.00491, 48.86706]]]] } },
23216 { type: "Feature", properties: { iso1A2: "JM", iso1A3: "JAM", iso1N3: "388", wikidata: "Q766", nameEn: "Jamaica", aliases: ["JA"], groups: ["029", "003", "419", "019", "UN"], driveSide: "left", callingCodes: ["1 876", "1 658"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-74.09729, 17.36817], [-78.9741, 19.59515], [-78.34606, 16.57862], [-74.09729, 17.36817]]]] } },
23217 { type: "Feature", properties: { iso1A2: "JO", iso1A3: "JOR", iso1N3: "400", wikidata: "Q810", nameEn: "Jordan", groups: ["145", "142", "UN"], callingCodes: ["962"] }, geometry: { type: "MultiPolygon", coordinates: [[[[39.04251, 32.30203], [38.98762, 32.47694], [39.08202, 32.50304], [38.79171, 33.37328], [36.83946, 32.31293], [36.40959, 32.37908], [36.23948, 32.50108], [36.20875, 32.49529], [36.20379, 32.52751], [36.08074, 32.51463], [36.02239, 32.65911], [35.96633, 32.66237], [35.93307, 32.71966], [35.88405, 32.71321], [35.75983, 32.74803], [35.68467, 32.70715], [35.66527, 32.681], [35.61669, 32.67999], [35.59813, 32.65159], [35.56614, 32.64393], [35.57485, 32.48669], [35.55494, 32.42687], [35.55807, 32.38674], [35.57111, 32.21877], [35.52012, 32.04076], [35.54375, 31.96587], [35.52758, 31.9131], [35.55941, 31.76535], [35.47672, 31.49578], [35.40316, 31.25535], [35.43658, 31.12444], [35.41371, 30.95565], [35.33984, 30.8802], [35.33456, 30.81224], [35.29311, 30.71365], [35.21379, 30.60401], [35.19595, 30.50297], [35.16218, 30.43535], [35.19183, 30.34636], [35.14108, 30.07374], [35.02147, 29.66343], [34.98207, 29.58147], [34.97718, 29.54294], [34.92298, 29.45305], [34.8812, 29.36878], [36.07081, 29.18469], [36.50005, 29.49696], [36.75083, 29.86903], [37.4971, 29.99949], [37.66395, 30.33245], [37.99354, 30.49998], [36.99791, 31.50081], [38.99233, 31.99721], [39.29903, 32.23259], [39.26157, 32.35555], [39.04251, 32.30203]]]] } },
23218 { type: "Feature", properties: { iso1A2: "JP", iso1A3: "JPN", iso1N3: "392", wikidata: "Q17", nameEn: "Japan", groups: ["030", "142", "UN"], driveSide: "left", callingCodes: ["81"] }, geometry: { type: "MultiPolygon", coordinates: [[[[145.82361, 43.38904], [145.23667, 43.76813], [145.82343, 44.571], [140.9182, 45.92937], [133.61399, 37.41], [129.2669, 34.87122], [122.26612, 25.98197], [123.92912, 17.8782], [155.16731, 23.60141], [145.82361, 43.38904]]]] } },
23219 { type: "Feature", properties: { iso1A2: "KE", iso1A3: "KEN", iso1N3: "404", wikidata: "Q114", nameEn: "Kenya", groups: ["014", "202", "002", "UN"], driveSide: "left", callingCodes: ["254"] }, geometry: { type: "MultiPolygon", coordinates: [[[[35.9419, 4.61933], [35.51424, 4.61643], [35.42366, 4.76969], [35.47843, 4.91872], [35.30992, 4.90402], [35.34151, 5.02364], [34.47601, 4.72162], [33.9873, 4.23316], [34.06046, 4.15235], [34.15429, 3.80464], [34.45815, 3.67385], [34.44922, 3.51627], [34.39112, 3.48802], [34.41794, 3.44342], [34.40006, 3.37949], [34.45815, 3.18319], [34.56242, 3.11478], [34.60114, 2.93034], [34.65774, 2.8753], [34.73967, 2.85447], [34.78137, 2.76223], [34.77244, 2.70272], [34.95267, 2.47209], [34.90947, 2.42447], [34.98692, 1.97348], [34.9899, 1.6668], [34.92734, 1.56109], [34.87819, 1.5596], [34.7918, 1.36752], [34.82606, 1.30944], [34.82606, 1.26626], [34.80223, 1.22754], [34.67562, 1.21265], [34.58029, 1.14712], [34.57427, 1.09868], [34.52369, 1.10692], [34.43349, 0.85254], [34.40041, 0.80266], [34.31516, 0.75693], [34.27345, 0.63182], [34.20196, 0.62289], [34.13493, 0.58118], [34.11408, 0.48884], [34.08727, 0.44713], [34.10067, 0.36372], [33.90936, 0.10581], [33.98449, -0.13079], [33.9264, -0.54188], [33.93107, -0.99298], [34.02286, -1.00779], [34.03084, -1.05101], [34.0824, -1.02264], [37.67199, -3.06222], [37.71745, -3.304], [37.5903, -3.42735], [37.63099, -3.50723], [37.75036, -3.54243], [37.81321, -3.69179], [39.21631, -4.67835], [39.44306, -4.93877], [39.62121, -4.68136], [41.75542, -1.85308], [41.56362, -1.66375], [41.56, -1.59812], [41.00099, -0.83068], [40.98767, 2.82959], [41.31368, 3.14314], [41.89488, 3.97375], [41.1754, 3.94079], [40.77498, 4.27683], [39.86043, 3.86974], [39.76808, 3.67058], [39.58339, 3.47434], [39.55132, 3.39634], [39.51551, 3.40895], [39.49444, 3.45521], [39.19954, 3.47834], [39.07736, 3.5267], [38.91938, 3.51198], [38.52336, 3.62551], [38.45812, 3.60445], [38.14168, 3.62487], [37.07724, 4.33503], [36.84474, 4.44518], [36.03924, 4.44406], [35.95449, 4.53244], [35.9419, 4.61933]]]] } },
23220 { type: "Feature", properties: { iso1A2: "KG", iso1A3: "KGZ", iso1N3: "417", wikidata: "Q813", nameEn: "Kyrgyzstan", groups: ["143", "142", "UN"], callingCodes: ["996"] }, geometry: { type: "MultiPolygon", coordinates: [[[[74.88756, 42.98612], [74.75, 42.99029], [74.70331, 43.02519], [74.64615, 43.05881], [74.57491, 43.13702], [74.22489, 43.24657], [73.55634, 43.03071], [73.50992, 42.82356], [73.44393, 42.43098], [71.88792, 42.83578], [71.62405, 42.76613], [71.53272, 42.8014], [71.2724, 42.77853], [71.22785, 42.69248], [71.17807, 42.67381], [71.15232, 42.60486], [70.97717, 42.50147], [70.85973, 42.30188], [70.94483, 42.26238], [71.13263, 42.28356], [71.28719, 42.18033], [70.69777, 41.92554], [70.17682, 41.5455], [70.48909, 41.40335], [70.67586, 41.47953], [70.78572, 41.36419], [70.77885, 41.24813], [70.86263, 41.23833], [70.9615, 41.16393], [71.02193, 41.19494], [71.11806, 41.15359], [71.25813, 41.18796], [71.27187, 41.11015], [71.34877, 41.16807], [71.40198, 41.09436], [71.46148, 41.13958], [71.43814, 41.19644], [71.46688, 41.31883], [71.57227, 41.29175], [71.6787, 41.42111], [71.65914, 41.49599], [71.73054, 41.54713], [71.71132, 41.43012], [71.76625, 41.4466], [71.83914, 41.3546], [71.91457, 41.2982], [71.85964, 41.19081], [72.07249, 41.11739], [72.10745, 41.15483], [72.16433, 41.16483], [72.17594, 41.15522], [72.14864, 41.13363], [72.1792, 41.10621], [72.21061, 41.05607], [72.17594, 41.02377], [72.18339, 40.99571], [72.324, 41.03381], [72.34026, 41.04539], [72.34757, 41.06104], [72.36138, 41.04384], [72.38511, 41.02785], [72.45206, 41.03018], [72.48742, 40.97136], [72.55109, 40.96046], [72.59136, 40.86947], [72.68157, 40.84942], [72.84291, 40.85512], [72.94454, 40.8094], [73.01869, 40.84681], [73.13267, 40.83512], [73.13412, 40.79122], [73.0612, 40.76678], [72.99133, 40.76457], [72.93296, 40.73089], [72.8722, 40.71111], [72.85372, 40.7116], [72.84754, 40.67229], [72.80137, 40.67856], [72.74866, 40.60873], [72.74894, 40.59592], [72.75982, 40.57273], [72.74862, 40.57131], [72.74768, 40.58051], [72.73995, 40.58409], [72.69579, 40.59778], [72.66713, 40.59076], [72.66713, 40.5219], [72.47795, 40.5532], [72.40517, 40.61917], [72.34406, 40.60144], [72.41714, 40.55736], [72.38384, 40.51535], [72.41513, 40.50856], [72.44191, 40.48222], [72.40346, 40.4007], [72.24368, 40.46091], [72.18648, 40.49893], [71.96401, 40.31907], [72.05464, 40.27586], [71.85002, 40.25647], [71.82646, 40.21872], [71.73054, 40.14818], [71.71719, 40.17886], [71.69621, 40.18492], [71.70569, 40.20391], [71.68386, 40.26984], [71.61931, 40.26775], [71.61725, 40.20615], [71.51549, 40.22986], [71.51215, 40.26943], [71.4246, 40.28619], [71.36663, 40.31593], [71.13042, 40.34106], [71.05901, 40.28765], [70.95789, 40.28761], [70.9818, 40.22392], [70.80495, 40.16813], [70.7928, 40.12797], [70.65827, 40.0981], [70.65946, 39.9878], [70.58912, 39.95211], [70.55033, 39.96619], [70.47557, 39.93216], [70.57384, 39.99394], [70.58297, 40.00891], [70.01283, 40.23288], [69.67001, 40.10639], [69.64704, 40.12165], [69.57615, 40.10524], [69.55555, 40.12296], [69.53794, 40.11833], [69.53855, 40.0887], [69.5057, 40.03277], [69.53615, 39.93991], [69.43557, 39.92877], [69.43134, 39.98431], [69.35649, 40.01994], [69.26938, 39.8127], [69.3594, 39.52516], [69.68677, 39.59281], [69.87491, 39.53882], [70.11111, 39.58223], [70.2869, 39.53141], [70.44757, 39.60128], [70.64087, 39.58792], [70.7854, 39.38933], [71.06418, 39.41586], [71.08752, 39.50704], [71.49814, 39.61397], [71.55856, 39.57588], [71.5517, 39.45722], [71.62688, 39.44056], [71.76816, 39.45456], [71.80164, 39.40631], [71.7522, 39.32031], [71.79202, 39.27355], [71.90601, 39.27674], [72.04059, 39.36704], [72.09689, 39.26823], [72.17242, 39.2661], [72.23834, 39.17248], [72.33173, 39.33093], [72.62027, 39.39696], [72.85934, 39.35116], [73.18454, 39.35536], [73.31912, 39.38615], [73.45096, 39.46677], [73.59831, 39.46425], [73.87018, 39.47879], [73.94683, 39.60733], [73.92354, 39.69565], [73.9051, 39.75073], [73.83006, 39.76136], [73.97049, 40.04378], [74.25533, 40.13191], [74.35063, 40.09742], [74.69875, 40.34668], [74.85996, 40.32857], [74.78168, 40.44886], [74.82013, 40.52197], [75.08243, 40.43945], [75.22834, 40.45382], [75.5854, 40.66874], [75.69663, 40.28642], [75.91361, 40.2948], [75.96168, 40.38064], [76.33659, 40.3482], [76.5261, 40.46114], [76.75681, 40.95354], [76.99302, 41.0696], [77.28004, 41.0033], [77.3693, 41.0375], [77.52723, 41.00227], [77.76206, 41.01574], [77.81287, 41.14307], [78.12873, 41.23091], [78.15757, 41.38565], [78.3732, 41.39603], [79.92977, 42.04113], [80.17842, 42.03211], [80.17807, 42.21166], [79.97364, 42.42816], [79.52921, 42.44778], [79.19763, 42.804], [78.91502, 42.76839], [78.48469, 42.89649], [75.82823, 42.94848], [75.72174, 42.79672], [75.29966, 42.86183], [75.22619, 42.85528], [74.88756, 42.98612]], [[70.74189, 39.86319], [70.63105, 39.77923], [70.59667, 39.83542], [70.54998, 39.85137], [70.52631, 39.86989], [70.53651, 39.89155], [70.74189, 39.86319]], [[71.86463, 39.98598], [71.84316, 39.95582], [71.7504, 39.93701], [71.71511, 39.96348], [71.78838, 40.01404], [71.86463, 39.98598]], [[71.21139, 40.03369], [71.1427, 39.95026], [71.23067, 39.93581], [71.16101, 39.88423], [71.10531, 39.91354], [71.04979, 39.89808], [71.10501, 39.95568], [71.09063, 39.99], [71.11668, 39.99291], [71.11037, 40.01984], [71.01035, 40.05481], [71.00236, 40.18154], [71.06305, 40.1771], [71.12218, 40.03052], [71.21139, 40.03369]]]] } },
23221 { type: "Feature", properties: { iso1A2: "KH", iso1A3: "KHM", iso1N3: "116", wikidata: "Q424", nameEn: "Cambodia", groups: ["035", "142", "UN"], callingCodes: ["855"] }, geometry: { type: "MultiPolygon", coordinates: [[[[105.87328, 11.55953], [105.81645, 11.56876], [105.80867, 11.60536], [105.8507, 11.66635], [105.88962, 11.67854], [105.95188, 11.63738], [106.00792, 11.7197], [106.02038, 11.77457], [106.06708, 11.77761], [106.13158, 11.73283], [106.18539, 11.75171], [106.26478, 11.72122], [106.30525, 11.67549], [106.37219, 11.69836], [106.44691, 11.66787], [106.45158, 11.68616], [106.41577, 11.76999], [106.44535, 11.8279], [106.44068, 11.86294], [106.4687, 11.86751], [106.4111, 11.97413], [106.70687, 11.96956], [106.79405, 12.0807], [106.92325, 12.06548], [106.99953, 12.08983], [107.15831, 12.27547], [107.34511, 12.33327], [107.42917, 12.24657], [107.4463, 12.29373], [107.55059, 12.36824], [107.5755, 12.52177], [107.55993, 12.7982], [107.49611, 12.88926], [107.49144, 13.01215], [107.62843, 13.3668], [107.61909, 13.52577], [107.53503, 13.73908], [107.45252, 13.78897], [107.46498, 13.91593], [107.44318, 13.99751], [107.38247, 13.99147], [107.35757, 14.02319], [107.37158, 14.07906], [107.33577, 14.11832], [107.40427, 14.24509], [107.39493, 14.32655], [107.44941, 14.41552], [107.48521, 14.40346], [107.52569, 14.54665], [107.52102, 14.59034], [107.55371, 14.628], [107.54361, 14.69092], [107.47238, 14.61523], [107.44435, 14.52785], [107.37897, 14.54443], [107.3276, 14.58812], [107.29803, 14.58963], [107.26534, 14.54292], [107.256, 14.48716], [107.21241, 14.48716], [107.17038, 14.41782], [107.09722, 14.3937], [107.03962, 14.45099], [107.04585, 14.41782], [106.98825, 14.36806], [106.9649, 14.3198], [106.90574, 14.33639], [106.8497, 14.29416], [106.80767, 14.31226], [106.73762, 14.42687], [106.63333, 14.44194], [106.59908, 14.50977], [106.57106, 14.50525], [106.54148, 14.59565], [106.50723, 14.58963], [106.45898, 14.55045], [106.47766, 14.50977], [106.43874, 14.52032], [106.40916, 14.45249], [106.32355, 14.44043], [106.25194, 14.48415], [106.21302, 14.36203], [106.00131, 14.36957], [105.99509, 14.32734], [106.02311, 14.30623], [106.04801, 14.20363], [106.10872, 14.18401], [106.11962, 14.11307], [106.18656, 14.06324], [106.16632, 14.01794], [106.10094, 13.98471], [106.10405, 13.9137], [105.90791, 13.92881], [105.78182, 14.02247], [105.78338, 14.08438], [105.5561, 14.15684], [105.44869, 14.10703], [105.36775, 14.09948], [105.2759, 14.17496], [105.20894, 14.34967], [105.17748, 14.34432], [105.14012, 14.23873], [105.08408, 14.20402], [105.02804, 14.23722], [104.97667, 14.38806], [104.69335, 14.42726], [104.55014, 14.36091], [104.27616, 14.39861], [103.93836, 14.3398], [103.70175, 14.38052], [103.71109, 14.4348], [103.53518, 14.42575], [103.39353, 14.35639], [103.16469, 14.33075], [102.93275, 14.19044], [102.91251, 14.01531], [102.77864, 13.93374], [102.72727, 13.77806], [102.56848, 13.69366], [102.5481, 13.6589], [102.58635, 13.6286], [102.62483, 13.60883], [102.57573, 13.60461], [102.5358, 13.56933], [102.44601, 13.5637], [102.36859, 13.57488], [102.33828, 13.55613], [102.361, 13.50551], [102.35563, 13.47307], [102.35692, 13.38274], [102.34611, 13.35618], [102.36001, 13.31142], [102.36146, 13.26006], [102.43422, 13.09061], [102.46011, 13.08057], [102.52275, 12.99813], [102.48694, 12.97537], [102.49335, 12.92711], [102.53053, 12.77506], [102.4994, 12.71736], [102.51963, 12.66117], [102.57567, 12.65358], [102.7796, 12.43781], [102.78116, 12.40284], [102.73134, 12.37091], [102.70176, 12.1686], [102.77026, 12.06815], [102.78427, 11.98746], [102.83957, 11.8519], [102.90973, 11.75613], [102.91449, 11.65512], [102.52395, 11.25257], [102.47649, 9.66162], [103.99198, 10.48391], [104.43778, 10.42386], [104.47963, 10.43046], [104.49869, 10.4057], [104.59018, 10.53073], [104.87933, 10.52833], [104.95094, 10.64003], [105.09571, 10.72722], [105.02722, 10.89236], [105.08326, 10.95656], [105.11449, 10.96332], [105.34011, 10.86179], [105.42884, 10.96878], [105.50045, 10.94586], [105.77751, 11.03671], [105.86376, 10.89839], [105.84603, 10.85873], [105.93403, 10.83853], [105.94535, 10.9168], [106.06708, 10.8098], [106.18539, 10.79451], [106.14301, 10.98176], [106.20095, 10.97795], [106.1757, 11.07301], [106.1527, 11.10476], [106.10444, 11.07879], [105.86782, 11.28343], [105.88962, 11.43605], [105.87328, 11.55953]]]] } },
23222 { type: "Feature", properties: { iso1A2: "KI", iso1A3: "KIR", iso1N3: "296", wikidata: "Q710", nameEn: "Kiribati", groups: ["057", "009", "UN"], driveSide: "left", callingCodes: ["686"] }, geometry: { type: "MultiPolygon", coordinates: [[[[169, 3.9], [169, -3.5], [178, -3.5], [178, 3.9], [169, 3.9]]], [[[-161.06795, 5.2462], [-158.12991, -1.86122], [-175.33482, -1.40631], [-175.31804, -7.54825], [-156.50903, -7.4975], [-156.48634, -15.52824], [-135.59706, -4.70473], [-161.06795, 5.2462]]]] } },
23223 { type: "Feature", properties: { iso1A2: "KM", iso1A3: "COM", iso1N3: "174", wikidata: "Q970", nameEn: "Comoros", groups: ["014", "202", "002", "UN"], callingCodes: ["269"] }, geometry: { type: "MultiPolygon", coordinates: [[[[42.63904, -10.02522], [43.28731, -13.97126], [45.4971, -11.75965], [42.63904, -10.02522]]]] } },
23224 { type: "Feature", properties: { iso1A2: "KN", iso1A3: "KNA", iso1N3: "659", wikidata: "Q763", nameEn: "St. Kitts and Nevis", groups: ["029", "003", "419", "019", "UN"], driveSide: "left", roadSpeedUnit: "mph", callingCodes: ["1 869"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-62.29333, 17.43155], [-62.76692, 17.64353], [-63.09677, 17.21372], [-62.63813, 16.65446], [-62.29333, 17.43155]]]] } },
23225 { type: "Feature", properties: { iso1A2: "KP", iso1A3: "PRK", iso1N3: "408", wikidata: "Q423", nameEn: "North Korea", groups: ["030", "142", "UN"], callingCodes: ["850"] }, geometry: { type: "MultiPolygon", coordinates: [[[[130.26095, 42.9027], [130.09764, 42.91425], [130.12957, 42.98361], [129.96409, 42.97306], [129.95082, 43.01051], [129.8865, 43.00395], [129.85261, 42.96494], [129.83277, 42.86746], [129.80719, 42.79218], [129.7835, 42.76521], [129.77183, 42.69435], [129.75294, 42.59409], [129.72541, 42.43739], [129.60482, 42.44461], [129.54701, 42.37254], [129.42882, 42.44702], [129.28541, 42.41574], [129.22423, 42.3553], [129.22285, 42.26491], [129.15178, 42.17224], [128.96068, 42.06657], [128.94007, 42.03537], [128.04487, 42.01769], [128.15119, 41.74568], [128.30716, 41.60322], [128.20061, 41.40895], [128.18546, 41.41279], [128.12967, 41.37931], [128.03311, 41.39232], [128.02633, 41.42103], [127.92943, 41.44291], [127.29712, 41.49473], [127.17841, 41.59714], [126.90729, 41.79955], [126.60631, 41.65565], [126.53189, 41.35206], [126.242, 41.15454], [126.00335, 40.92835], [125.76869, 40.87908], [125.71172, 40.85223], [124.86913, 40.45387], [124.40719, 40.13655], [124.38556, 40.11047], [124.3322, 40.05573], [124.37089, 40.03004], [124.35029, 39.95639], [124.23201, 39.9248], [124.17532, 39.8232], [123.90497, 38.79949], [123.85601, 37.49093], [124.67666, 38.05679], [124.84224, 37.977], [124.87921, 37.80827], [125.06408, 37.66334], [125.37112, 37.62643], [125.81159, 37.72949], [126.13074, 37.70512], [126.18776, 37.74728], [126.19097, 37.81462], [126.24402, 37.83113], [126.43239, 37.84095], [126.46818, 37.80873], [126.56709, 37.76857], [126.59918, 37.76364], [126.66067, 37.7897], [126.68793, 37.83728], [126.68793, 37.9175], [126.67023, 37.95852], [126.84961, 38.0344], [126.88106, 38.10246], [126.95887, 38.1347], [126.95338, 38.17735], [127.04479, 38.25518], [127.15749, 38.30722], [127.38727, 38.33227], [127.49672, 38.30647], [127.55013, 38.32257], [128.02917, 38.31861], [128.27652, 38.41657], [128.31105, 38.58462], [128.37487, 38.62345], [128.65655, 38.61914], [131.95041, 41.5445], [130.65022, 42.32281], [130.66367, 42.38024], [130.64181, 42.41422], [130.60805, 42.4317], [130.56835, 42.43281], [130.55143, 42.52158], [130.50123, 42.61636], [130.44361, 42.54849], [130.41826, 42.6011], [130.2385, 42.71127], [130.23068, 42.80125], [130.26095, 42.9027]]]] } },
23226 { type: "Feature", properties: { iso1A2: "KR", iso1A3: "KOR", iso1N3: "410", wikidata: "Q884", nameEn: "South Korea", groups: ["030", "142", "UN"], callingCodes: ["82"] }, geometry: { type: "MultiPolygon", coordinates: [[[[133.11729, 37.53115], [128.65655, 38.61914], [128.37487, 38.62345], [128.31105, 38.58462], [128.27652, 38.41657], [128.02917, 38.31861], [127.55013, 38.32257], [127.49672, 38.30647], [127.38727, 38.33227], [127.15749, 38.30722], [127.04479, 38.25518], [126.95338, 38.17735], [126.95887, 38.1347], [126.88106, 38.10246], [126.84961, 38.0344], [126.67023, 37.95852], [126.68793, 37.9175], [126.68793, 37.83728], [126.66067, 37.7897], [126.59918, 37.76364], [126.56709, 37.76857], [126.46818, 37.80873], [126.43239, 37.84095], [126.24402, 37.83113], [126.19097, 37.81462], [126.18776, 37.74728], [126.13074, 37.70512], [125.81159, 37.72949], [125.37112, 37.62643], [125.06408, 37.66334], [124.87921, 37.80827], [124.84224, 37.977], [124.67666, 38.05679], [123.85601, 37.49093], [122.80525, 33.30571], [125.99728, 32.63328], [129.2669, 34.87122], [133.11729, 37.53115]]]] } },
23227 { type: "Feature", properties: { iso1A2: "KW", iso1A3: "KWT", iso1N3: "414", wikidata: "Q817", nameEn: "Kuwait", groups: ["145", "142", "UN"], callingCodes: ["965"] }, geometry: { type: "MultiPolygon", coordinates: [[[[49.00421, 28.81495], [48.59531, 29.66815], [48.40479, 29.85763], [48.17332, 30.02448], [48.06782, 30.02906], [48.01114, 29.98906], [47.7095, 30.10453], [47.37192, 30.10421], [47.15166, 30.01044], [46.89695, 29.50584], [46.5527, 29.10283], [47.46202, 29.0014], [47.58376, 28.83382], [47.59863, 28.66798], [47.70561, 28.5221], [48.42991, 28.53628], [49.00421, 28.81495]]]] } },
23228 { type: "Feature", properties: { iso1A2: "KY", iso1A3: "CYM", iso1N3: "136", wikidata: "Q5785", nameEn: "Cayman Islands", country: "GB", groups: ["BOTS", "029", "003", "419", "019", "UN"], driveSide: "left", roadSpeedUnit: "mph", roadHeightUnit: "ft", callingCodes: ["1 345"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-82.11509, 19.60401], [-80.36068, 18.11751], [-79.32727, 20.06742], [-82.11509, 19.60401]]]] } },
23229 { type: "Feature", properties: { iso1A2: "KZ", iso1A3: "KAZ", iso1N3: "398", wikidata: "Q232", nameEn: "Kazakhstan", groups: ["143", "142", "UN"], callingCodes: ["7"] }, geometry: { type: "MultiPolygon", coordinates: [[[[68.90865, 55.38148], [68.19206, 55.18823], [68.26661, 55.09226], [68.21308, 54.98645], [65.20174, 54.55216], [65.24663, 54.35721], [65.11033, 54.33028], [64.97216, 54.4212], [63.97686, 54.29763], [64.02715, 54.22679], [63.91224, 54.20013], [63.80604, 54.27079], [62.58651, 54.05871], [62.56876, 53.94047], [62.45931, 53.90737], [62.38535, 54.03961], [62.00966, 54.04134], [62.03913, 53.94768], [61.65318, 54.02445], [61.56941, 53.95703], [61.47603, 54.08048], [61.3706, 54.08464], [61.26863, 53.92797], [60.99796, 53.93699], [61.14283, 53.90063], [61.22574, 53.80268], [60.90626, 53.62937], [61.55706, 53.57144], [61.57185, 53.50112], [61.37957, 53.45887], [61.29082, 53.50992], [61.14291, 53.41481], [61.19024, 53.30536], [62.14574, 53.09626], [62.12799, 52.99133], [62.0422, 52.96105], [61.23462, 53.03227], [61.05842, 52.92217], [60.71989, 52.75923], [60.71693, 52.66245], [60.84118, 52.63912], [60.84709, 52.52228], [60.98021, 52.50068], [61.05417, 52.35096], [60.78201, 52.22067], [60.72581, 52.15538], [60.48915, 52.15175], [60.19925, 51.99173], [59.99809, 51.98263], [60.09867, 51.87135], [60.50986, 51.7964], [60.36787, 51.66815], [60.5424, 51.61675], [60.92401, 51.61124], [60.95655, 51.48615], [61.50677, 51.40687], [61.55114, 51.32746], [61.6813, 51.25716], [61.56889, 51.23679], [61.4431, 50.80679], [60.81833, 50.6629], [60.31914, 50.67705], [60.17262, 50.83312], [60.01288, 50.8163], [59.81172, 50.54451], [59.51886, 50.49937], [59.48928, 50.64216], [58.87974, 50.70852], [58.3208, 51.15151], [57.75578, 51.13852], [57.74986, 50.93017], [57.44221, 50.88354], [57.17302, 51.11253], [56.17906, 50.93204], [56.11398, 50.7471], [55.67774, 50.54508], [54.72067, 51.03261], [54.56685, 51.01958], [54.71476, 50.61214], [54.55797, 50.52006], [54.41894, 50.61214], [54.46331, 50.85554], [54.12248, 51.11542], [53.69299, 51.23466], [53.46165, 51.49445], [52.54329, 51.48444], [52.36119, 51.74161], [51.8246, 51.67916], [51.77431, 51.49536], [51.301, 51.48799], [51.26254, 51.68466], [50.59695, 51.61859], [50.26859, 51.28677], [49.97277, 51.2405], [49.76866, 51.11067], [49.39001, 51.09396], [49.41959, 50.85927], [49.12673, 50.78639], [48.86936, 50.61589], [48.57946, 50.63278], [48.90782, 50.02281], [48.68352, 49.89546], [48.42564, 49.82283], [48.24519, 49.86099], [48.10044, 50.09242], [47.58551, 50.47867], [47.30448, 50.30894], [47.34589, 50.09308], [47.18319, 49.93721], [46.9078, 49.86707], [46.78398, 49.34026], [47.04658, 49.19834], [47.00857, 49.04921], [46.78392, 48.95352], [46.49011, 48.43019], [47.11516, 48.27188], [47.12107, 47.83687], [47.38731, 47.68176], [47.41689, 47.83687], [47.64973, 47.76559], [48.15348, 47.74545], [48.45173, 47.40818], [48.52326, 47.4102], [49.01136, 46.72716], [48.51142, 46.69268], [48.54988, 46.56267], [49.16518, 46.38542], [49.32259, 46.26944], [49.88945, 46.04554], [49.2134, 44.84989], [52.26048, 41.69249], [52.47884, 41.78034], [52.97575, 42.1308], [54.20635, 42.38477], [54.95182, 41.92424], [55.45471, 41.25609], [56.00314, 41.32584], [55.97584, 44.99322], [55.97584, 44.99328], [55.97584, 44.99338], [55.97584, 44.99343], [55.97584, 44.99348], [55.97584, 44.99353], [55.97584, 44.99359], [55.97584, 44.99369], [55.97584, 44.99374], [55.97584, 44.99384], [55.97584, 44.9939], [55.97584, 44.994], [55.97584, 44.99405], [55.97584, 44.99415], [55.97584, 44.99421], [55.97584, 44.99426], [55.97584, 44.99431], [55.97584, 44.99436], [55.97584, 44.99441], [55.97594, 44.99446], [55.97605, 44.99452], [55.97605, 44.99457], [55.97605, 44.99462], [55.97605, 44.99467], [55.97605, 44.99477], [55.97615, 44.99477], [55.97615, 44.99483], [55.97615, 44.99493], [55.97615, 44.99498], [55.97615, 44.99503], [55.97615, 44.99508], [55.97625, 44.99514], [55.97636, 44.99519], [55.97636, 44.99524], [55.97646, 44.99529], [55.97646, 44.99534], [55.97656, 44.99539], [55.97667, 44.99545], [55.97677, 44.9955], [55.97677, 44.99555], [55.97677, 44.9956], [55.97687, 44.9956], [55.97698, 44.99565], [55.97698, 44.9957], [55.97708, 44.99576], [55.97718, 44.99581], [55.97729, 44.99586], [55.97739, 44.99586], [55.97739, 44.99591], [55.97749, 44.99591], [55.9776, 44.99591], [55.9777, 44.99596], [55.9777, 44.99601], [55.9778, 44.99607], [55.97791, 44.99607], [55.97801, 44.99607], [55.97801, 44.99612], [55.97811, 44.99617], [55.97822, 44.99617], [55.97832, 44.99622], [55.97842, 44.99622], [58.59711, 45.58671], [61.01475, 44.41383], [62.01711, 43.51008], [63.34656, 43.64003], [64.53885, 43.56941], [64.96464, 43.74748], [65.18666, 43.48835], [65.53277, 43.31856], [65.85194, 42.85481], [66.09482, 42.93426], [66.00546, 41.94455], [66.53302, 41.87388], [66.69129, 41.1311], [67.9644, 41.14611], [67.98511, 41.02794], [68.08273, 41.08148], [68.1271, 41.0324], [67.96736, 40.83798], [68.49983, 40.56437], [68.63, 40.59358], [68.58444, 40.91447], [68.49983, 40.99669], [68.62221, 41.03019], [68.65662, 40.93861], [68.73945, 40.96989], [68.7217, 41.05025], [69.01308, 41.22804], [69.05006, 41.36183], [69.15137, 41.43078], [69.17701, 41.43769], [69.18528, 41.45175], [69.20439, 41.45391], [69.22671, 41.46298], [69.23332, 41.45847], [69.25059, 41.46693], [69.29778, 41.43673], [69.35554, 41.47211], [69.37468, 41.46555], [69.45081, 41.46246], [69.39485, 41.51518], [69.45751, 41.56863], [69.49545, 41.545], [70.94483, 42.26238], [70.85973, 42.30188], [70.97717, 42.50147], [71.15232, 42.60486], [71.17807, 42.67381], [71.22785, 42.69248], [71.2724, 42.77853], [71.53272, 42.8014], [71.62405, 42.76613], [71.88792, 42.83578], [73.44393, 42.43098], [73.50992, 42.82356], [73.55634, 43.03071], [74.22489, 43.24657], [74.57491, 43.13702], [74.64615, 43.05881], [74.70331, 43.02519], [74.75, 42.99029], [74.88756, 42.98612], [75.22619, 42.85528], [75.29966, 42.86183], [75.72174, 42.79672], [75.82823, 42.94848], [78.48469, 42.89649], [78.91502, 42.76839], [79.19763, 42.804], [79.52921, 42.44778], [79.97364, 42.42816], [80.17807, 42.21166], [80.26841, 42.23797], [80.16892, 42.61137], [80.26886, 42.8366], [80.38169, 42.83142], [80.58999, 42.9011], [80.3735, 43.01557], [80.62913, 43.141], [80.78817, 43.14235], [80.77771, 43.30065], [80.69718, 43.32589], [80.75156, 43.44948], [80.40031, 44.10986], [80.40229, 44.23319], [80.38384, 44.63073], [79.8987, 44.89957], [80.11169, 45.03352], [81.73278, 45.3504], [82.51374, 45.1755], [82.58474, 45.40027], [82.21792, 45.56619], [83.04622, 47.19053], [83.92184, 46.98912], [84.73077, 47.01394], [84.93995, 46.87399], [85.22443, 47.04816], [85.54294, 47.06171], [85.69696, 47.2898], [85.61067, 47.49753], [85.5169, 48.05493], [85.73581, 48.3939], [86.38069, 48.46064], [86.75343, 48.70331], [86.73568, 48.99918], [86.87238, 49.12432], [87.28386, 49.11626], [87.31465, 49.23603], [87.03071, 49.25142], [86.82606, 49.51796], [86.61307, 49.60239], [86.79056, 49.74787], [86.63674, 49.80136], [86.18709, 49.50259], [85.24047, 49.60239], [84.99198, 50.06793], [84.29385, 50.27257], [83.8442, 50.87375], [83.14607, 51.00796], [82.55443, 50.75412], [81.94999, 50.79307], [81.46581, 50.77658], [81.41248, 50.97524], [81.06091, 50.94833], [81.16999, 51.15662], [80.80318, 51.28262], [80.44819, 51.20855], [80.4127, 50.95581], [80.08138, 50.77658], [79.11255, 52.01171], [77.90383, 53.29807], [76.54243, 53.99329], [76.44076, 54.16017], [76.82266, 54.1798], [76.91052, 54.4677], [75.3668, 54.07439], [75.43398, 53.98652], [75.07405, 53.80831], [73.39218, 53.44623], [73.25412, 53.61532], [73.68921, 53.86522], [73.74778, 54.07194], [73.37963, 53.96132], [72.71026, 54.1161], [72.43415, 53.92685], [72.17477, 54.36303], [71.96141, 54.17736], [71.10379, 54.13326], [71.08706, 54.33376], [71.24185, 54.64965], [71.08288, 54.71253], [70.96009, 55.10558], [70.76493, 55.3027], [70.19179, 55.1476], [69.74917, 55.35545], [69.34224, 55.36344], [68.90865, 55.38148]]]] } },
23230 { type: "Feature", properties: { iso1A2: "LA", iso1A3: "LAO", iso1N3: "418", wikidata: "Q819", nameEn: "Laos", groups: ["035", "142", "UN"], callingCodes: ["856"] }, geometry: { type: "MultiPolygon", coordinates: [[[[102.1245, 22.43372], [102.03633, 22.46164], [101.98487, 22.42766], [101.91344, 22.44417], [101.90714, 22.38688], [101.86828, 22.38397], [101.7685, 22.50337], [101.68973, 22.46843], [101.61306, 22.27515], [101.56789, 22.28876], [101.53638, 22.24794], [101.60675, 22.13513], [101.57525, 22.13026], [101.62566, 21.96574], [101.7791, 21.83019], [101.74555, 21.72852], [101.83257, 21.61562], [101.80001, 21.57461], [101.7475, 21.5873], [101.7727, 21.51794], [101.74224, 21.48276], [101.74014, 21.30967], [101.84412, 21.25291], [101.83887, 21.20983], [101.76745, 21.21571], [101.79266, 21.19025], [101.7622, 21.14813], [101.70548, 21.14911], [101.66977, 21.20004], [101.60886, 21.17947], [101.59491, 21.18621], [101.6068, 21.23329], [101.54563, 21.25668], [101.29326, 21.17254], [101.2229, 21.23271], [101.26912, 21.36482], [101.19349, 21.41959], [101.2124, 21.56422], [101.15156, 21.56129], [101.16198, 21.52808], [101.00234, 21.39612], [100.80173, 21.2934], [100.72716, 21.31786], [100.63578, 21.05639], [100.55281, 21.02796], [100.50974, 20.88574], [100.64628, 20.88279], [100.60112, 20.8347], [100.51079, 20.82194], [100.36375, 20.82783], [100.1957, 20.68247], [100.08404, 20.36626], [100.09999, 20.31614], [100.09337, 20.26293], [100.11785, 20.24787], [100.1712, 20.24324], [100.16668, 20.2986], [100.22076, 20.31598], [100.25769, 20.3992], [100.33383, 20.4028], [100.37439, 20.35156], [100.41473, 20.25625], [100.44992, 20.23644], [100.4537, 20.19971], [100.47567, 20.19133], [100.51052, 20.14928], [100.55218, 20.17741], [100.58808, 20.15791], [100.5094, 19.87904], [100.398, 19.75047], [100.49604, 19.53504], [100.58219, 19.49164], [100.64606, 19.55884], [100.77231, 19.48324], [100.90302, 19.61901], [101.08928, 19.59748], [101.26545, 19.59242], [101.26991, 19.48324], [101.21347, 19.46223], [101.20604, 19.35296], [101.24911, 19.33334], [101.261, 19.12717], [101.35606, 19.04716], [101.25803, 18.89545], [101.22832, 18.73377], [101.27585, 18.68875], [101.06047, 18.43247], [101.18227, 18.34367], [101.15108, 18.25624], [101.19118, 18.2125], [101.1793, 18.0544], [101.02185, 17.87637], [100.96541, 17.57926], [101.15108, 17.47586], [101.44667, 17.7392], [101.72294, 17.92867], [101.78087, 18.07559], [101.88485, 18.02474], [102.11359, 18.21532], [102.45523, 17.97106], [102.59234, 17.96127], [102.60971, 17.95411], [102.61432, 17.92273], [102.5896, 17.84889], [102.59485, 17.83537], [102.68194, 17.80151], [102.69946, 17.81686], [102.67543, 17.84529], [102.68538, 17.86653], [102.75954, 17.89561], [102.79044, 17.93612], [102.81988, 17.94233], [102.86323, 17.97531], [102.95812, 18.0054], [102.9912, 17.9949], [103.01998, 17.97095], [103.0566, 18.00144], [103.07823, 18.03833], [103.07343, 18.12351], [103.1493, 18.17799], [103.14994, 18.23172], [103.17093, 18.2618], [103.29757, 18.30475], [103.23818, 18.34875], [103.24779, 18.37807], [103.30977, 18.4341], [103.41044, 18.4486], [103.47773, 18.42841], [103.60957, 18.40528], [103.699, 18.34125], [103.82449, 18.33979], [103.85642, 18.28666], [103.93916, 18.33914], [103.97725, 18.33631], [104.06533, 18.21656], [104.10927, 18.10826], [104.21776, 17.99335], [104.2757, 17.86139], [104.35432, 17.82871], [104.45404, 17.66788], [104.69867, 17.53038], [104.80061, 17.39367], [104.80716, 17.19025], [104.73712, 17.01404], [104.7373, 16.91125], [104.76442, 16.84752], [104.7397, 16.81005], [104.76099, 16.69302], [104.73349, 16.565], [104.88057, 16.37311], [105.00262, 16.25627], [105.06204, 16.09792], [105.42001, 16.00657], [105.38508, 15.987], [105.34115, 15.92737], [105.37959, 15.84074], [105.42285, 15.76971], [105.46573, 15.74742], [105.61756, 15.68792], [105.60446, 15.53301], [105.58191, 15.41031], [105.47635, 15.3796], [105.4692, 15.33709], [105.50662, 15.32054], [105.58043, 15.32724], [105.46661, 15.13132], [105.61162, 15.00037], [105.5121, 14.80802], [105.53864, 14.55731], [105.43783, 14.43865], [105.20894, 14.34967], [105.2759, 14.17496], [105.36775, 14.09948], [105.44869, 14.10703], [105.5561, 14.15684], [105.78338, 14.08438], [105.78182, 14.02247], [105.90791, 13.92881], [106.10405, 13.9137], [106.10094, 13.98471], [106.16632, 14.01794], [106.18656, 14.06324], [106.11962, 14.11307], [106.10872, 14.18401], [106.04801, 14.20363], [106.02311, 14.30623], [105.99509, 14.32734], [106.00131, 14.36957], [106.21302, 14.36203], [106.25194, 14.48415], [106.32355, 14.44043], [106.40916, 14.45249], [106.43874, 14.52032], [106.47766, 14.50977], [106.45898, 14.55045], [106.50723, 14.58963], [106.54148, 14.59565], [106.57106, 14.50525], [106.59908, 14.50977], [106.63333, 14.44194], [106.73762, 14.42687], [106.80767, 14.31226], [106.8497, 14.29416], [106.90574, 14.33639], [106.9649, 14.3198], [106.98825, 14.36806], [107.04585, 14.41782], [107.03962, 14.45099], [107.09722, 14.3937], [107.17038, 14.41782], [107.21241, 14.48716], [107.256, 14.48716], [107.26534, 14.54292], [107.29803, 14.58963], [107.3276, 14.58812], [107.37897, 14.54443], [107.44435, 14.52785], [107.47238, 14.61523], [107.54361, 14.69092], [107.51579, 14.79282], [107.59285, 14.87795], [107.48277, 14.93751], [107.46516, 15.00982], [107.61486, 15.0566], [107.61926, 15.13949], [107.58844, 15.20111], [107.62587, 15.2266], [107.60605, 15.37524], [107.62367, 15.42193], [107.53341, 15.40496], [107.50699, 15.48771], [107.3815, 15.49832], [107.34408, 15.62345], [107.27583, 15.62769], [107.27143, 15.71459], [107.21859, 15.74638], [107.21419, 15.83747], [107.34188, 15.89464], [107.39471, 15.88829], [107.46296, 16.01106], [107.44975, 16.08511], [107.33968, 16.05549], [107.25822, 16.13587], [107.14595, 16.17816], [107.15035, 16.26271], [107.09091, 16.3092], [107.02597, 16.31132], [106.97385, 16.30204], [106.96638, 16.34938], [106.88067, 16.43594], [106.88727, 16.52671], [106.84104, 16.55415], [106.74418, 16.41904], [106.65832, 16.47816], [106.66052, 16.56892], [106.61477, 16.60713], [106.58267, 16.6012], [106.59013, 16.62259], [106.55485, 16.68704], [106.55265, 16.86831], [106.52183, 16.87884], [106.51963, 16.92097], [106.54824, 16.92729], [106.55045, 17.0031], [106.50862, 16.9673], [106.43597, 17.01362], [106.31929, 17.20509], [106.29287, 17.3018], [106.24444, 17.24714], [106.18991, 17.28227], [106.09019, 17.36399], [105.85744, 17.63221], [105.76612, 17.67147], [105.60381, 17.89356], [105.64784, 17.96687], [105.46292, 18.22008], [105.38366, 18.15315], [105.15942, 18.38691], [105.10408, 18.43533], [105.1327, 18.58355], [105.19654, 18.64196], [105.12829, 18.70453], [104.64617, 18.85668], [104.5361, 18.97747], [103.87125, 19.31854], [104.06058, 19.43484], [104.10832, 19.51575], [104.05617, 19.61743], [104.06498, 19.66926], [104.23229, 19.70242], [104.41281, 19.70035], [104.53169, 19.61743], [104.64837, 19.62365], [104.68359, 19.72729], [104.8355, 19.80395], [104.8465, 19.91783], [104.9874, 20.09573], [104.91695, 20.15567], [104.86852, 20.14121], [104.61315, 20.24452], [104.62195, 20.36633], [104.72102, 20.40554], [104.66158, 20.47774], [104.47886, 20.37459], [104.40621, 20.3849], [104.38199, 20.47155], [104.63957, 20.6653], [104.27412, 20.91433], [104.11121, 20.96779], [103.98024, 20.91531], [103.82282, 20.8732], [103.73478, 20.6669], [103.68633, 20.66324], [103.45737, 20.82382], [103.38032, 20.79501], [103.21497, 20.89832], [103.12055, 20.89994], [103.03469, 21.05821], [102.97745, 21.05821], [102.89825, 21.24707], [102.80794, 21.25736], [102.88939, 21.3107], [102.94223, 21.46034], [102.86297, 21.4255], [102.98846, 21.58936], [102.97965, 21.74076], [102.86077, 21.71213], [102.85637, 21.84501], [102.81894, 21.83888], [102.82115, 21.73667], [102.74189, 21.66713], [102.67145, 21.65894], [102.62301, 21.91447], [102.49092, 21.99002], [102.51734, 22.02676], [102.18712, 22.30403], [102.14099, 22.40092], [102.1245, 22.43372]]]] } },
23231 { type: "Feature", properties: { iso1A2: "LB", iso1A3: "LBN", iso1N3: "422", wikidata: "Q822", nameEn: "Lebanon", aliases: ["RL"], groups: ["145", "142", "UN"], callingCodes: ["961"] }, geometry: { type: "MultiPolygon", coordinates: [[[[35.94816, 33.47886], [35.94465, 33.52774], [36.05723, 33.57904], [35.9341, 33.6596], [36.06778, 33.82927], [36.14517, 33.85118], [36.3967, 33.83365], [36.38263, 33.86579], [36.28589, 33.91981], [36.41078, 34.05253], [36.50576, 34.05982], [36.5128, 34.09916], [36.62537, 34.20251], [36.59195, 34.2316], [36.58667, 34.27667], [36.60778, 34.31009], [36.56556, 34.31881], [36.53039, 34.3798], [36.55853, 34.41609], [36.46179, 34.46541], [36.4442, 34.50165], [36.34745, 34.5002], [36.3369, 34.52629], [36.39846, 34.55672], [36.41429, 34.61175], [36.45299, 34.59438], [36.46003, 34.6378], [36.42941, 34.62505], [36.35384, 34.65447], [36.35135, 34.68516], [36.32399, 34.69334], [36.29165, 34.62991], [35.98718, 34.64977], [35.97386, 34.63322], [35.48515, 34.70851], [34.78515, 33.20368], [35.10645, 33.09318], [35.1924, 33.08743], [35.31429, 33.10515], [35.35223, 33.05617], [35.43059, 33.06659], [35.448, 33.09264], [35.50272, 33.09056], [35.50335, 33.114], [35.52573, 33.11921], [35.54228, 33.19865], [35.5362, 33.23196], [35.54808, 33.236], [35.54544, 33.25513], [35.55555, 33.25844], [35.56523, 33.28969], [35.58326, 33.28381], [35.58502, 33.26653], [35.62283, 33.24226], [35.62019, 33.27278], [35.77477, 33.33609], [35.81324, 33.36354], [35.82577, 33.40479], [35.88668, 33.43183], [35.94816, 33.47886]]]] } },
23232 { type: "Feature", properties: { iso1A2: "LC", iso1A3: "LCA", iso1N3: "662", wikidata: "Q760", nameEn: "St. Lucia", aliases: ["WL"], groups: ["029", "003", "419", "019", "UN"], driveSide: "left", roadSpeedUnit: "mph", callingCodes: ["1 758"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-59.95997, 14.20285], [-61.69315, 14.26451], [-59.94058, 12.34011], [-59.95997, 14.20285]]]] } },
23233 { type: "Feature", properties: { iso1A2: "LI", iso1A3: "LIE", iso1N3: "438", wikidata: "Q347", nameEn: "Liechtenstein", aliases: ["FL"], groups: ["155", "150", "UN"], callingCodes: ["423"] }, geometry: { type: "MultiPolygon", coordinates: [[[[9.60717, 47.06091], [9.61216, 47.07732], [9.63395, 47.08443], [9.62623, 47.14685], [9.56539, 47.17124], [9.58264, 47.20673], [9.56981, 47.21926], [9.55176, 47.22585], [9.56766, 47.24281], [9.53116, 47.27029], [9.52406, 47.24959], [9.50318, 47.22153], [9.4891, 47.19346], [9.48774, 47.17402], [9.51044, 47.13727], [9.52089, 47.10019], [9.51362, 47.08505], [9.47139, 47.06402], [9.47548, 47.05257], [9.54041, 47.06495], [9.55721, 47.04762], [9.60717, 47.06091]]]] } },
23234 { type: "Feature", properties: { iso1A2: "LK", iso1A3: "LKA", iso1N3: "144", wikidata: "Q854", nameEn: "Sri Lanka", groups: ["034", "142", "UN"], driveSide: "left", callingCodes: ["94"] }, geometry: { type: "MultiPolygon", coordinates: [[[[76.59015, 5.591], [85.15017, 5.21497], [80.48418, 10.20786], [79.42124, 9.80115], [79.50447, 8.91876], [76.59015, 5.591]]]] } },
23235 { type: "Feature", properties: { iso1A2: "LR", iso1A3: "LBR", iso1N3: "430", wikidata: "Q1014", nameEn: "Liberia", groups: ["011", "202", "002", "UN"], callingCodes: ["231"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-8.47114, 7.55676], [-8.55874, 7.62525], [-8.55874, 7.70167], [-8.67814, 7.69428], [-8.72789, 7.51429], [-8.8448, 7.35149], [-8.85724, 7.26019], [-8.93435, 7.2824], [-9.09107, 7.1985], [-9.18311, 7.30461], [-9.20798, 7.38109], [-9.305, 7.42056], [-9.41943, 7.41809], [-9.48161, 7.37122], [-9.37465, 7.62032], [-9.35724, 7.74111], [-9.44928, 7.9284], [-9.41445, 8.02448], [-9.50898, 8.18455], [-9.47415, 8.35195], [-9.77763, 8.54633], [-10.05873, 8.42578], [-10.05375, 8.50697], [-10.14579, 8.52665], [-10.203, 8.47991], [-10.27575, 8.48711], [-10.30084, 8.30008], [-10.31635, 8.28554], [-10.29839, 8.21283], [-10.35227, 8.15223], [-10.45023, 8.15627], [-10.51554, 8.1393], [-10.57523, 8.04829], [-10.60492, 8.04072], [-10.60422, 7.7739], [-11.29417, 7.21576], [-11.4027, 6.97746], [-11.50429, 6.92704], [-12.15048, 6.15992], [-7.52774, 3.7105], [-7.53259, 4.35145], [-7.59349, 4.8909], [-7.53876, 4.94294], [-7.55369, 5.08667], [-7.48901, 5.14118], [-7.46165, 5.26256], [-7.36463, 5.32944], [-7.43428, 5.42355], [-7.37209, 5.61173], [-7.43926, 5.74787], [-7.43677, 5.84687], [-7.46165, 5.84934], [-7.48155, 5.80974], [-7.67309, 5.94337], [-7.70294, 5.90625], [-7.78254, 5.99037], [-7.79747, 6.07696], [-7.8497, 6.08932], [-7.83478, 6.20309], [-7.90692, 6.27728], [-8.00642, 6.31684], [-8.17557, 6.28222], [-8.3298, 6.36381], [-8.38453, 6.35887], [-8.45666, 6.49977], [-8.48652, 6.43797], [-8.59456, 6.50612], [-8.31736, 6.82837], [-8.29249, 7.1691], [-8.37458, 7.25794], [-8.41935, 7.51203], [-8.47114, 7.55676]]]] } },
23236 { type: "Feature", properties: { iso1A2: "LS", iso1A3: "LSO", iso1N3: "426", wikidata: "Q1013", nameEn: "Lesotho", groups: ["018", "202", "002", "UN"], driveSide: "left", callingCodes: ["266"] }, geometry: { type: "MultiPolygon", coordinates: [[[[29.33204, -29.45598], [29.44883, -29.3772], [29.40524, -29.21246], [28.68043, -28.58744], [28.65091, -28.57025], [28.40612, -28.6215], [28.30518, -28.69531], [28.2348, -28.69471], [28.1317, -28.7293], [28.02503, -28.85991], [27.98675, -28.8787], [27.9392, -28.84864], [27.88933, -28.88156], [27.8907, -28.91612], [27.75458, -28.89839], [27.55974, -29.18954], [27.5158, -29.2261], [27.54258, -29.25575], [27.48679, -29.29349], [27.45125, -29.29708], [27.47254, -29.31968], [27.4358, -29.33465], [27.33464, -29.48161], [27.01016, -29.65439], [27.09489, -29.72796], [27.22719, -30.00718], [27.29603, -30.05473], [27.32555, -30.14785], [27.40778, -30.14577], [27.37293, -30.19401], [27.36649, -30.27246], [27.38108, -30.33456], [27.45452, -30.32239], [27.56901, -30.42504], [27.56781, -30.44562], [27.62137, -30.50509], [27.6521, -30.51707], [27.67819, -30.53437], [27.69467, -30.55862], [27.74814, -30.60635], [28.12073, -30.68072], [28.2319, -30.28476], [28.399, -30.1592], [28.68627, -30.12885], [28.80222, -30.10579], [28.9338, -30.05072], [29.16548, -29.91706], [29.12553, -29.76266], [29.28545, -29.58456], [29.33204, -29.45598]]]] } },
23237 { type: "Feature", properties: { iso1A2: "LT", iso1A3: "LTU", iso1N3: "440", wikidata: "Q37", nameEn: "Lithuania", groups: ["EU", "154", "150", "UN"], callingCodes: ["370"] }, geometry: { type: "MultiPolygon", coordinates: [[[[24.89005, 56.46666], [24.83686, 56.41565], [24.70022, 56.40483], [24.57353, 56.31525], [24.58143, 56.29125], [24.42746, 56.26522], [24.32334, 56.30226], [24.13139, 56.24881], [24.02657, 56.3231], [23.75726, 56.37282], [23.49803, 56.34307], [23.40486, 56.37689], [23.31606, 56.3827], [23.17312, 56.36795], [23.09531, 56.30511], [22.96988, 56.41213], [22.83048, 56.367], [22.69354, 56.36284], [22.56441, 56.39305], [22.3361, 56.4016], [22.09728, 56.42851], [22.00548, 56.41508], [21.74558, 56.33181], [21.57888, 56.31406], [21.49736, 56.29106], [21.24644, 56.16917], [21.15016, 56.07818], [20.68447, 56.04073], [20.60454, 55.40986], [20.95181, 55.27994], [21.26425, 55.24456], [21.35465, 55.28427], [21.38446, 55.29348], [21.46766, 55.21115], [21.51095, 55.18507], [21.55605, 55.20311], [21.64954, 55.1791], [21.85521, 55.09493], [21.96505, 55.07353], [21.99543, 55.08691], [22.03984, 55.07888], [22.02582, 55.05078], [22.06087, 55.02935], [22.11697, 55.02131], [22.14267, 55.05345], [22.31562, 55.0655], [22.47688, 55.04408], [22.58907, 55.07085], [22.60075, 55.01863], [22.65451, 54.97037], [22.68723, 54.9811], [22.76422, 54.92521], [22.85083, 54.88711], [22.87317, 54.79492], [22.73631, 54.72952], [22.73397, 54.66604], [22.75467, 54.6483], [22.74225, 54.64339], [22.7522, 54.63525], [22.68021, 54.58486], [22.71293, 54.56454], [22.67788, 54.532], [22.70208, 54.45312], [22.7253, 54.41732], [22.79705, 54.36264], [22.83756, 54.40827], [23.00584, 54.38514], [22.99649, 54.35927], [23.05726, 54.34565], [23.04323, 54.31567], [23.104, 54.29794], [23.13905, 54.31567], [23.15526, 54.31076], [23.15938, 54.29894], [23.24656, 54.25701], [23.3494, 54.25155], [23.39525, 54.21672], [23.42418, 54.17911], [23.45223, 54.17775], [23.49196, 54.14764], [23.52702, 54.04622], [23.48261, 53.98855], [23.51284, 53.95052], [23.61677, 53.92691], [23.71726, 53.93379], [23.80543, 53.89558], [23.81309, 53.94205], [23.95098, 53.9613], [23.98837, 53.92554], [24.19638, 53.96405], [24.34128, 53.90076], [24.44411, 53.90076], [24.62275, 54.00217], [24.69652, 54.01901], [24.69185, 53.96543], [24.74279, 53.96663], [24.85311, 54.02862], [24.77131, 54.11091], [24.96894, 54.17589], [24.991, 54.14241], [25.0728, 54.13419], [25.19199, 54.219], [25.22705, 54.26271], [25.35559, 54.26544], [25.509, 54.30267], [25.56823, 54.25212], [25.51452, 54.17799], [25.54724, 54.14925], [25.64875, 54.1259], [25.71084, 54.16704], [25.78563, 54.15747], [25.78553, 54.23327], [25.68513, 54.31727], [25.55425, 54.31591], [25.5376, 54.33158], [25.63371, 54.42075], [25.62203, 54.4656], [25.64813, 54.48704], [25.68045, 54.5321], [25.75977, 54.57252], [25.74122, 54.80108], [25.89462, 54.93438], [25.99129, 54.95705], [26.05907, 54.94631], [26.13386, 54.98924], [26.20397, 54.99729], [26.26941, 55.08032], [26.23202, 55.10439], [26.30628, 55.12536], [26.35121, 55.1525], [26.46249, 55.12814], [26.51481, 55.16051], [26.54753, 55.14181], [26.69243, 55.16718], [26.68075, 55.19787], [26.72983, 55.21788], [26.73017, 55.24226], [26.835, 55.28182], [26.83266, 55.30444], [26.80929, 55.31642], [26.6714, 55.33902], [26.5709, 55.32572], [26.44937, 55.34832], [26.5522, 55.40277], [26.55094, 55.5093], [26.63167, 55.57887], [26.63231, 55.67968], [26.58248, 55.6754], [26.46661, 55.70375], [26.39561, 55.71156], [26.18509, 55.86813], [26.03815, 55.95884], [25.90047, 56.0013], [25.85893, 56.00188], [25.81773, 56.05444], [25.69246, 56.08892], [25.68588, 56.14725], [25.53621, 56.16663], [25.39751, 56.15707], [25.23099, 56.19147], [25.09325, 56.1878], [25.05762, 56.26742], [24.89005, 56.46666]]]] } },
23238 { type: "Feature", properties: { iso1A2: "LU", iso1A3: "LUX", iso1N3: "442", wikidata: "Q32", nameEn: "Luxembourg", groups: ["EU", "155", "150", "UN"], callingCodes: ["352"] }, geometry: { type: "MultiPolygon", coordinates: [[[[6.1379, 50.12964], [6.1137, 50.13668], [6.12028, 50.16374], [6.08577, 50.17246], [6.06406, 50.15344], [6.03093, 50.16362], [6.02488, 50.18283], [5.96453, 50.17259], [5.95929, 50.13295], [5.89488, 50.11476], [5.8857, 50.07824], [5.85474, 50.06342], [5.86904, 50.04614], [5.8551, 50.02683], [5.81866, 50.01286], [5.82331, 49.99662], [5.83968, 49.9892], [5.83467, 49.97823], [5.81163, 49.97142], [5.80833, 49.96451], [5.77291, 49.96056], [5.77314, 49.93646], [5.73621, 49.89796], [5.78415, 49.87922], [5.75269, 49.8711], [5.75861, 49.85631], [5.74567, 49.85368], [5.75884, 49.84811], [5.74953, 49.84709], [5.74975, 49.83933], [5.74076, 49.83823], [5.7404, 49.83452], [5.74844, 49.82435], [5.74364, 49.82058], [5.74953, 49.81428], [5.75409, 49.79239], [5.78871, 49.7962], [5.82245, 49.75048], [5.83149, 49.74729], [5.82562, 49.72395], [5.84193, 49.72161], [5.86503, 49.72739], [5.88677, 49.70951], [5.86527, 49.69291], [5.86175, 49.67862], [5.9069, 49.66377], [5.90164, 49.6511], [5.90599, 49.63853], [5.88552, 49.63507], [5.88393, 49.62802], [5.87609, 49.62047], [5.8762, 49.60898], [5.84826, 49.5969], [5.84971, 49.58674], [5.86986, 49.58756], [5.87256, 49.57539], [5.8424, 49.56082], [5.84692, 49.55663], [5.84143, 49.5533], [5.81838, 49.54777], [5.80871, 49.5425], [5.81664, 49.53775], [5.83648, 49.5425], [5.84466, 49.53027], [5.83467, 49.52717], [5.83389, 49.52152], [5.86571, 49.50015], [5.94128, 49.50034], [5.94224, 49.49608], [5.96876, 49.49053], [5.97693, 49.45513], [6.02648, 49.45451], [6.02743, 49.44845], [6.04176, 49.44801], [6.05553, 49.46663], [6.07887, 49.46399], [6.08373, 49.45594], [6.10072, 49.45268], [6.09845, 49.46351], [6.10325, 49.4707], [6.12346, 49.4735], [6.12814, 49.49365], [6.14321, 49.48796], [6.16115, 49.49297], [6.15366, 49.50226], [6.17386, 49.50934], [6.19543, 49.50536], [6.2409, 49.51408], [6.25029, 49.50609], [6.27875, 49.503], [6.28818, 49.48465], [6.3687, 49.4593], [6.36778, 49.46937], [6.36907, 49.48931], [6.36788, 49.50377], [6.35666, 49.52931], [6.38072, 49.55171], [6.38228, 49.55855], [6.35825, 49.57053], [6.36676, 49.57813], [6.38024, 49.57593], [6.38342, 49.5799], [6.37464, 49.58886], [6.385, 49.59946], [6.39822, 49.60081], [6.41861, 49.61723], [6.4413, 49.65722], [6.43768, 49.66021], [6.42726, 49.66078], [6.42937, 49.66857], [6.44654, 49.67799], [6.46048, 49.69092], [6.48014, 49.69767], [6.49785, 49.71118], [6.50647, 49.71353], [6.5042, 49.71808], [6.49694, 49.72205], [6.49535, 49.72645], [6.50261, 49.72718], [6.51397, 49.72058], [6.51805, 49.72425], [6.50193, 49.73291], [6.50174, 49.75292], [6.51646, 49.75961], [6.51828, 49.76855], [6.51056, 49.77515], [6.51669, 49.78336], [6.50534, 49.78952], [6.52169, 49.79787], [6.53122, 49.80666], [6.52121, 49.81338], [6.51215, 49.80124], [6.50647, 49.80916], [6.48718, 49.81267], [6.47111, 49.82263], [6.45425, 49.81164], [6.44131, 49.81443], [6.42905, 49.81091], [6.42521, 49.81591], [6.40022, 49.82029], [6.36576, 49.85032], [6.34267, 49.84974], [6.33585, 49.83785], [6.32098, 49.83728], [6.32303, 49.85133], [6.30963, 49.87021], [6.29692, 49.86685], [6.28874, 49.87592], [6.26146, 49.88203], [6.23496, 49.89972], [6.22926, 49.92096], [6.21882, 49.92403], [6.22608, 49.929], [6.22094, 49.94955], [6.19856, 49.95053], [6.19089, 49.96991], [6.18045, 49.96611], [6.18554, 49.95622], [6.17872, 49.9537], [6.16466, 49.97086], [6.1701, 49.98518], [6.14147, 49.99563], [6.14948, 50.00908], [6.13806, 50.01056], [6.1295, 50.01849], [6.13273, 50.02019], [6.13794, 50.01466], [6.14666, 50.02207], [6.13044, 50.02929], [6.13458, 50.04141], [6.11274, 50.05916], [6.12055, 50.09171], [6.1379, 50.12964]]]] } },
23239 { type: "Feature", properties: { iso1A2: "LV", iso1A3: "LVA", iso1N3: "428", wikidata: "Q211", nameEn: "Latvia", groups: ["EU", "154", "150", "UN"], callingCodes: ["371"] }, geometry: { type: "MultiPolygon", coordinates: [[[[27.34698, 57.52242], [26.90364, 57.62823], [26.54675, 57.51813], [26.46527, 57.56885], [26.29253, 57.59244], [26.1866, 57.6849], [26.2029, 57.7206], [26.08098, 57.76619], [26.0543, 57.76105], [26.03332, 57.7718], [26.02415, 57.76865], [26.02069, 57.77169], [26.0266, 57.77441], [26.027, 57.78158], [26.02456, 57.78342], [26.0324, 57.79037], [26.05949, 57.84744], [25.73499, 57.90193], [25.29581, 58.08288], [25.28237, 57.98539], [25.19484, 58.0831], [24.3579, 57.87471], [24.26221, 57.91787], [23.20055, 57.56697], [22.80496, 57.87798], [19.84909, 57.57876], [19.64795, 57.06466], [20.68447, 56.04073], [21.15016, 56.07818], [21.24644, 56.16917], [21.49736, 56.29106], [21.57888, 56.31406], [21.74558, 56.33181], [22.00548, 56.41508], [22.09728, 56.42851], [22.3361, 56.4016], [22.56441, 56.39305], [22.69354, 56.36284], [22.83048, 56.367], [22.96988, 56.41213], [23.09531, 56.30511], [23.17312, 56.36795], [23.31606, 56.3827], [23.40486, 56.37689], [23.49803, 56.34307], [23.75726, 56.37282], [24.02657, 56.3231], [24.13139, 56.24881], [24.32334, 56.30226], [24.42746, 56.26522], [24.58143, 56.29125], [24.57353, 56.31525], [24.70022, 56.40483], [24.83686, 56.41565], [24.89005, 56.46666], [25.05762, 56.26742], [25.09325, 56.1878], [25.23099, 56.19147], [25.39751, 56.15707], [25.53621, 56.16663], [25.68588, 56.14725], [25.69246, 56.08892], [25.81773, 56.05444], [25.85893, 56.00188], [25.90047, 56.0013], [26.03815, 55.95884], [26.18509, 55.86813], [26.39561, 55.71156], [26.46661, 55.70375], [26.58248, 55.6754], [26.63231, 55.67968], [26.64888, 55.70515], [26.71802, 55.70645], [26.76872, 55.67658], [26.87448, 55.7172], [26.97153, 55.8102], [27.1559, 55.85032], [27.27804, 55.78299], [27.3541, 55.8089], [27.61683, 55.78558], [27.63065, 55.89687], [27.97865, 56.11849], [28.15217, 56.16964], [28.23716, 56.27588], [28.16599, 56.37806], [28.19057, 56.44637], [28.10069, 56.524], [28.13526, 56.57989], [28.04768, 56.59004], [27.86101, 56.88204], [27.66511, 56.83921], [27.86101, 57.29402], [27.52453, 57.42826], [27.56832, 57.53728], [27.34698, 57.52242]]]] } },
23240 { type: "Feature", properties: { iso1A2: "LY", iso1A3: "LBY", iso1N3: "434", wikidata: "Q1016", nameEn: "Libya", groups: ["015", "002", "UN"], callingCodes: ["218"] }, geometry: { type: "MultiPolygon", coordinates: [[[[26.92891, 33.39516], [11.58941, 33.36891], [11.55852, 33.1409], [11.51549, 33.09826], [11.46037, 32.6307], [11.57828, 32.48013], [11.53898, 32.4138], [11.04234, 32.2145], [10.7315, 31.97235], [10.62788, 31.96629], [10.48497, 31.72956], [10.31364, 31.72648], [10.12239, 31.42098], [10.29516, 30.90337], [9.88152, 30.34074], [9.76848, 30.34366], [9.55544, 30.23971], [9.3876, 30.16738], [9.78136, 29.40961], [9.89569, 26.57696], [9.51696, 26.39148], [9.38834, 26.19288], [10.03146, 25.35635], [10.02432, 24.98124], [10.33159, 24.5465], [10.85323, 24.5595], [11.41061, 24.21456], [11.62498, 24.26669], [11.96886, 23.51735], [13.5631, 23.16574], [14.22918, 22.61719], [14.99751, 23.00539], [15.99566, 23.49639], [23.99539, 19.49944], [23.99715, 20.00038], [24.99794, 19.99661], [24.99885, 21.99535], [24.99968, 29.24574], [24.71117, 30.17441], [25.01077, 30.73861], [24.8458, 31.39877], [26.92891, 33.39516]]]] } },
23241 { type: "Feature", properties: { iso1A2: "MA", iso1A3: "MAR", iso1N3: "504", wikidata: "Q1028", nameEn: "Morocco", groups: ["015", "002", "UN"], callingCodes: ["212"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-2.27707, 35.35051], [-5.10878, 36.05227], [-7.2725, 35.73269], [-14.43883, 27.02969], [-17.27295, 21.93519], [-17.21511, 21.34226], [-17.02707, 21.34022], [-16.9978, 21.36239], [-16.44269, 21.39745], [-14.78487, 21.36587], [-14.47329, 21.63839], [-14.48112, 22.00886], [-14.1291, 22.41636], [-14.10361, 22.75501], [-13.75627, 23.77231], [-13.00628, 24.01923], [-12.92147, 24.39502], [-12.12281, 25.13682], [-12.06001, 26.04442], [-11.62052, 26.05229], [-11.38635, 26.611], [-11.23622, 26.72023], [-11.35695, 26.8505], [-10.68417, 26.90984], [-9.81998, 26.71379], [-9.56957, 26.90042], [-9.08698, 26.98639], [-8.71787, 26.9898], [-8.77527, 27.66663], [-8.66879, 27.6666], [-8.6715, 28.71194], [-7.61585, 29.36252], [-6.95824, 29.50924], [-6.78351, 29.44634], [-6.69965, 29.51623], [-5.75616, 29.61407], [-5.72121, 29.52322], [-5.58831, 29.48103], [-5.21671, 29.95253], [-4.6058, 30.28343], [-4.31774, 30.53229], [-3.64735, 30.67539], [-3.65418, 30.85566], [-3.54944, 31.0503], [-3.77103, 31.14984], [-3.77647, 31.31912], [-3.66386, 31.39202], [-3.66314, 31.6339], [-2.82784, 31.79459], [-2.93873, 32.06557], [-2.46166, 32.16603], [-1.22829, 32.07832], [-1.15735, 32.12096], [-1.24453, 32.1917], [-1.24998, 32.32993], [-0.9912, 32.52467], [-1.37794, 32.73628], [-1.54244, 32.95499], [-1.46249, 33.0499], [-1.67067, 33.27084], [-1.59508, 33.59929], [-1.73494, 33.71721], [-1.64666, 34.10405], [-1.78042, 34.39018], [-1.69788, 34.48056], [-1.84569, 34.61907], [-1.73707, 34.74226], [-1.97469, 34.886], [-1.97833, 34.93218], [-2.04734, 34.93218], [-2.21445, 35.04378], [-2.21248, 35.08532], [-2.27707, 35.35051]], [[-2.91909, 35.33927], [-2.92272, 35.27509], [-2.93893, 35.26737], [-2.95065, 35.26576], [-2.95431, 35.2728], [-2.96516, 35.27967], [-2.96826, 35.28296], [-2.96507, 35.28801], [-2.97035, 35.28852], [-2.96978, 35.29459], [-2.96648, 35.30475], [-2.96038, 35.31609], [-2.91909, 35.33927]], [[-3.90602, 35.21494], [-3.89343, 35.22728], [-3.88372, 35.20767], [-3.90602, 35.21494]], [[-4.30191, 35.17419], [-4.29436, 35.17149], [-4.30112, 35.17058], [-4.30191, 35.17419]], [[-2.40316, 35.16893], [-2.45965, 35.16527], [-2.43262, 35.20652], [-2.40316, 35.16893]], [[-5.38491, 35.92591], [-5.21179, 35.90091], [-5.34379, 35.8711], [-5.35844, 35.87375], [-5.37338, 35.88417], [-5.38491, 35.92591]]]] } },
23242 { type: "Feature", properties: { iso1A2: "MC", iso1A3: "MCO", iso1N3: "492", wikidata: "Q235", nameEn: "Monaco", groups: ["155", "150", "UN"], callingCodes: ["377"] }, geometry: { type: "MultiPolygon", coordinates: [[[[7.47823, 43.73341], [7.4379, 43.74963], [7.4389, 43.75151], [7.43708, 43.75197], [7.43624, 43.75014], [7.43013, 43.74895], [7.42809, 43.74396], [7.42443, 43.74087], [7.42299, 43.74176], [7.42062, 43.73977], [7.41233, 43.73439], [7.41298, 43.73311], [7.41291, 43.73168], [7.41113, 43.73156], [7.40903, 43.7296], [7.42422, 43.72209], [7.47823, 43.73341]]]] } },
23243 { type: "Feature", properties: { iso1A2: "MD", iso1A3: "MDA", iso1N3: "498", wikidata: "Q217", nameEn: "Moldova", groups: ["151", "150", "UN"], callingCodes: ["373"] }, geometry: { type: "MultiPolygon", coordinates: [[[[27.74422, 48.45926], [27.6658, 48.44034], [27.59027, 48.46311], [27.5889, 48.49224], [27.46942, 48.454], [27.44333, 48.41209], [27.37741, 48.41026], [27.37604, 48.44398], [27.32159, 48.4434], [27.27855, 48.37534], [27.13434, 48.37288], [27.08078, 48.43214], [27.0231, 48.42485], [27.03821, 48.37653], [26.93384, 48.36558], [26.85556, 48.41095], [26.71274, 48.40388], [26.82809, 48.31629], [26.79239, 48.29071], [26.6839, 48.35828], [26.62823, 48.25804], [26.81161, 48.25049], [26.87708, 48.19919], [26.94265, 48.1969], [26.98042, 48.15752], [26.96119, 48.13003], [27.04118, 48.12522], [27.02985, 48.09083], [27.15622, 47.98538], [27.1618, 47.92391], [27.29069, 47.73722], [27.25519, 47.71366], [27.32202, 47.64009], [27.3979, 47.59473], [27.47942, 47.48113], [27.55731, 47.46637], [27.60263, 47.32507], [27.68706, 47.28962], [27.73172, 47.29248], [27.81892, 47.1381], [28.09095, 46.97621], [28.12173, 46.82283], [28.24808, 46.64305], [28.22281, 46.50481], [28.25769, 46.43334], [28.18902, 46.35283], [28.19864, 46.31869], [28.10937, 46.22852], [28.13684, 46.18099], [28.08612, 46.01105], [28.13111, 45.92819], [28.16568, 45.6421], [28.08927, 45.6051], [28.18741, 45.47358], [28.21139, 45.46895], [28.30201, 45.54744], [28.41836, 45.51715], [28.43072, 45.48538], [28.51449, 45.49982], [28.49252, 45.56716], [28.54196, 45.58062], [28.51587, 45.6613], [28.47879, 45.66994], [28.52823, 45.73803], [28.70401, 45.78019], [28.69852, 45.81753], [28.78503, 45.83475], [28.74383, 45.96664], [28.98004, 46.00385], [29.00613, 46.04962], [28.94643, 46.09176], [29.06656, 46.19716], [28.94953, 46.25852], [28.98478, 46.31803], [29.004, 46.31495], [28.9306, 46.45699], [29.01241, 46.46177], [29.02409, 46.49582], [29.23547, 46.55435], [29.24886, 46.37912], [29.35357, 46.49505], [29.49914, 46.45889], [29.5939, 46.35472], [29.6763, 46.36041], [29.66359, 46.4215], [29.74496, 46.45605], [29.88329, 46.35851], [29.94114, 46.40114], [30.09103, 46.38694], [30.16794, 46.40967], [30.02511, 46.45132], [29.88916, 46.54302], [29.94409, 46.56002], [29.9743, 46.75325], [29.94522, 46.80055], [29.98814, 46.82358], [29.87405, 46.88199], [29.75458, 46.8604], [29.72986, 46.92234], [29.57056, 46.94766], [29.62137, 47.05069], [29.61038, 47.09932], [29.53044, 47.07851], [29.49732, 47.12878], [29.57696, 47.13581], [29.54996, 47.24962], [29.59665, 47.25521], [29.5733, 47.36508], [29.48678, 47.36043], [29.47854, 47.30366], [29.39889, 47.30179], [29.3261, 47.44664], [29.18603, 47.43387], [29.11743, 47.55001], [29.22414, 47.60012], [29.22242, 47.73607], [29.27255, 47.79953], [29.20663, 47.80367], [29.27804, 47.88893], [29.19839, 47.89261], [29.1723, 47.99013], [28.9306, 47.96255], [28.8414, 48.03392], [28.85232, 48.12506], [28.69896, 48.13106], [28.53921, 48.17453], [28.48428, 48.0737], [28.42454, 48.12047], [28.43701, 48.15832], [28.38712, 48.17567], [28.34009, 48.13147], [28.30609, 48.14018], [28.30586, 48.1597], [28.34912, 48.1787], [28.36996, 48.20543], [28.35519, 48.24957], [28.32508, 48.23384], [28.2856, 48.23202], [28.19314, 48.20749], [28.17666, 48.25963], [28.07504, 48.23494], [28.09873, 48.3124], [28.04527, 48.32661], [27.95883, 48.32368], [27.88391, 48.36699], [27.87533, 48.4037], [27.81902, 48.41874], [27.79225, 48.44244], [27.74422, 48.45926]]]] } },
23244 { type: "Feature", properties: { iso1A2: "ME", iso1A3: "MNE", iso1N3: "499", wikidata: "Q236", nameEn: "Montenegro", groups: ["039", "150", "UN"], callingCodes: ["382"] }, geometry: { type: "MultiPolygon", coordinates: [[[[19.22807, 43.5264], [19.15685, 43.53943], [19.13933, 43.5282], [19.04934, 43.50384], [19.01078, 43.55806], [18.91379, 43.50299], [18.95469, 43.49367], [18.96053, 43.45042], [19.01078, 43.43854], [19.04071, 43.397], [19.08673, 43.31453], [19.08206, 43.29668], [19.04233, 43.30008], [19.00844, 43.24988], [18.95001, 43.29327], [18.95819, 43.32899], [18.90911, 43.36383], [18.83912, 43.34795], [18.84794, 43.33735], [18.85342, 43.32426], [18.76538, 43.29838], [18.6976, 43.25243], [18.71747, 43.2286], [18.66605, 43.2056], [18.64735, 43.14766], [18.66254, 43.03928], [18.52232, 43.01451], [18.49076, 42.95553], [18.49661, 42.89306], [18.4935, 42.86433], [18.47633, 42.85829], [18.45921, 42.81682], [18.47324, 42.74992], [18.56789, 42.72074], [18.55221, 42.69045], [18.54603, 42.69171], [18.54841, 42.68328], [18.57373, 42.64429], [18.52232, 42.62279], [18.55504, 42.58409], [18.53751, 42.57376], [18.49778, 42.58409], [18.43735, 42.55921], [18.44307, 42.51077], [18.43588, 42.48556], [18.52152, 42.42302], [18.54128, 42.39171], [18.45131, 42.21682], [19.26406, 41.74971], [19.37597, 41.84849], [19.37451, 41.8842], [19.33812, 41.90669], [19.34601, 41.95675], [19.37691, 41.96977], [19.36867, 42.02564], [19.37548, 42.06835], [19.40687, 42.10024], [19.28623, 42.17745], [19.42, 42.33019], [19.42352, 42.36546], [19.4836, 42.40831], [19.65972, 42.62774], [19.73244, 42.66299], [19.77375, 42.58517], [19.74731, 42.57422], [19.76549, 42.50237], [19.82333, 42.46581], [19.9324, 42.51699], [20.00842, 42.5109], [20.01834, 42.54622], [20.07761, 42.55582], [20.0969, 42.65559], [20.02915, 42.71147], [20.02088, 42.74789], [20.04898, 42.77701], [20.2539, 42.76245], [20.27869, 42.81945], [20.35692, 42.8335], [20.34528, 42.90676], [20.16415, 42.97177], [20.14896, 42.99058], [20.12325, 42.96237], [20.05431, 42.99571], [20.04729, 43.02732], [19.98887, 43.0538], [19.96549, 43.11098], [19.92576, 43.08539], [19.79255, 43.11951], [19.76918, 43.16044], [19.64063, 43.19027], [19.62661, 43.2286], [19.54598, 43.25158], [19.52962, 43.31623], [19.48171, 43.32644], [19.44315, 43.38846], [19.22229, 43.47926], [19.22807, 43.5264]]]] } },
23245 { type: "Feature", properties: { iso1A2: "MF", iso1A3: "MAF", iso1N3: "663", wikidata: "Q126125", nameEn: "Saint-Martin", country: "FR", groups: ["Q3320166", "EU", "029", "003", "419", "019", "UN"], callingCodes: ["590"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-62.93924, 18.02904], [-62.62718, 18.26185], [-63.35989, 18.06012], [-63.33064, 17.9615], [-63.13502, 18.05445], [-63.11042, 18.05339], [-63.09686, 18.04608], [-63.07759, 18.04943], [-63.0579, 18.06614], [-63.04039, 18.05619], [-63.02323, 18.05757], [-62.93924, 18.02904]]]] } },
23246 { type: "Feature", properties: { iso1A2: "MG", iso1A3: "MDG", iso1N3: "450", wikidata: "Q1019", nameEn: "Madagascar", aliases: ["RM"], groups: ["014", "202", "002", "UN"], callingCodes: ["261"] }, geometry: { type: "MultiPolygon", coordinates: [[[[51.93891, -10.85085], [45.84651, -12.77177], [42.14681, -19.63341], [45.80092, -33.00974], [51.93891, -10.85085]]]] } },
23247 { type: "Feature", properties: { iso1A2: "MH", iso1A3: "MHL", iso1N3: "584", wikidata: "Q709", nameEn: "Marshall Islands", groups: ["057", "009", "UN"], roadSpeedUnit: "mph", callingCodes: ["692"] }, geometry: { type: "MultiPolygon", coordinates: [[[[169, 3.9], [173.53711, 5.70687], [169.29099, 15.77133], [159.04653, 10.59067], [169, 3.9]]]] } },
23248 { type: "Feature", properties: { iso1A2: "MK", iso1A3: "MKD", iso1N3: "807", wikidata: "Q221", nameEn: "North Macedonia", groups: ["039", "150", "UN"], callingCodes: ["389"] }, geometry: { type: "MultiPolygon", coordinates: [[[[22.34773, 42.31725], [22.29275, 42.34913], [22.29605, 42.37477], [22.16384, 42.32103], [22.02908, 42.29848], [21.94405, 42.34669], [21.91595, 42.30392], [21.84654, 42.3247], [21.77176, 42.2648], [21.70111, 42.23789], [21.58992, 42.25915], [21.52145, 42.24465], [21.50823, 42.27156], [21.43882, 42.2789], [21.43882, 42.23609], [21.38428, 42.24465], [21.30496, 42.1418], [21.29913, 42.13954], [21.31983, 42.10993], [21.22728, 42.08909], [21.16614, 42.19815], [21.11491, 42.20794], [20.75464, 42.05229], [20.76786, 41.91839], [20.68523, 41.85318], [20.59524, 41.8818], [20.55976, 41.87068], [20.57144, 41.7897], [20.53405, 41.78099], [20.51301, 41.72433], [20.52937, 41.69292], [20.51769, 41.65975], [20.55508, 41.58113], [20.52103, 41.56473], [20.45809, 41.5549], [20.45331, 41.51436], [20.49039, 41.49277], [20.51301, 41.442], [20.55976, 41.4087], [20.52119, 41.34381], [20.49432, 41.33679], [20.51068, 41.2323], [20.59715, 41.13644], [20.58546, 41.11179], [20.59832, 41.09066], [20.63454, 41.0889], [20.65558, 41.08009], [20.71634, 40.91781], [20.73504, 40.9081], [20.81567, 40.89662], [20.83671, 40.92752], [20.94305, 40.92399], [20.97693, 40.90103], [20.97887, 40.85475], [21.15262, 40.85546], [21.21105, 40.8855], [21.25779, 40.86165], [21.35595, 40.87578], [21.41555, 40.9173], [21.53007, 40.90759], [21.57448, 40.86076], [21.69601, 40.9429], [21.7556, 40.92525], [21.91102, 41.04786], [21.90869, 41.09191], [22.06527, 41.15617], [22.1424, 41.12449], [22.17629, 41.15969], [22.26744, 41.16409], [22.42285, 41.11921], [22.5549, 41.13065], [22.58295, 41.11568], [22.62852, 41.14385], [22.65306, 41.18168], [22.71266, 41.13945], [22.74538, 41.16321], [22.76408, 41.32225], [22.81199, 41.3398], [22.93334, 41.34104], [22.96331, 41.35782], [22.95513, 41.63265], [23.03342, 41.71034], [23.01239, 41.76527], [22.96682, 41.77137], [22.90254, 41.87587], [22.86749, 42.02275], [22.67701, 42.06614], [22.51224, 42.15457], [22.50289, 42.19527], [22.47251, 42.20393], [22.38136, 42.30339], [22.34773, 42.31725]]]] } },
23249 { type: "Feature", properties: { iso1A2: "ML", iso1A3: "MLI", iso1N3: "466", wikidata: "Q912", nameEn: "Mali", groups: ["011", "202", "002", "UN"], callingCodes: ["223"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-4.83423, 24.99935], [-6.57191, 25.0002], [-5.60725, 16.49919], [-5.33435, 16.33354], [-5.50165, 15.50061], [-9.32979, 15.50032], [-9.31106, 15.69412], [-9.33314, 15.7044], [-9.44673, 15.60553], [-9.40447, 15.4396], [-10.71721, 15.4223], [-10.90932, 15.11001], [-11.43483, 15.62339], [-11.70705, 15.51558], [-11.94903, 14.76143], [-12.23936, 14.76324], [-11.93043, 13.84505], [-12.06897, 13.71049], [-11.83345, 13.33333], [-11.63025, 13.39174], [-11.39935, 12.97808], [-11.37536, 12.40788], [-11.50006, 12.17826], [-11.24136, 12.01286], [-10.99758, 12.24634], [-10.80355, 12.1053], [-10.71897, 11.91552], [-10.30604, 12.24634], [-9.714, 12.0226], [-9.63938, 12.18312], [-9.32097, 12.29009], [-9.38067, 12.48446], [-9.13689, 12.50875], [-8.94784, 12.34842], [-8.80854, 11.66715], [-8.40058, 11.37466], [-8.66923, 10.99397], [-8.35083, 11.06234], [-8.2667, 10.91762], [-8.32614, 10.69273], [-8.22711, 10.41722], [-8.10207, 10.44649], [-7.9578, 10.2703], [-7.97971, 10.17117], [-7.92107, 10.15577], [-7.63048, 10.46334], [-7.54462, 10.40921], [-7.52261, 10.4655], [-7.44555, 10.44602], [-7.3707, 10.24677], [-7.13331, 10.24877], [-7.0603, 10.14711], [-7.00966, 10.15794], [-6.97444, 10.21644], [-7.01186, 10.25111], [-6.93921, 10.35291], [-6.68164, 10.35074], [-6.63541, 10.66893], [-6.52974, 10.59104], [-6.42847, 10.5694], [-6.40646, 10.69922], [-6.325, 10.68624], [-6.24795, 10.74248], [-6.1731, 10.46983], [-6.18851, 10.24244], [-5.99478, 10.19694], [-5.78124, 10.43952], [-5.65135, 10.46767], [-5.51058, 10.43177], [-5.46643, 10.56074], [-5.47083, 10.75329], [-5.41579, 10.84628], [-5.49284, 11.07538], [-5.32994, 11.13371], [-5.32553, 11.21578], [-5.25949, 11.24816], [-5.25509, 11.36905], [-5.20665, 11.43811], [-5.22867, 11.60421], [-5.29251, 11.61715], [-5.26389, 11.75728], [-5.40258, 11.8327], [-5.26389, 11.84778], [-5.07897, 11.97918], [-4.72893, 12.01579], [-4.70692, 12.06746], [-4.62987, 12.06531], [-4.62546, 12.13204], [-4.54841, 12.1385], [-4.57703, 12.19875], [-4.41412, 12.31922], [-4.47356, 12.71252], [-4.238, 12.71467], [-4.21819, 12.95722], [-4.34477, 13.12927], [-3.96501, 13.49778], [-3.90558, 13.44375], [-3.96282, 13.38164], [-3.7911, 13.36665], [-3.54454, 13.1781], [-3.4313, 13.1588], [-3.43507, 13.27272], [-3.23599, 13.29035], [-3.28396, 13.5422], [-3.26407, 13.70699], [-2.88189, 13.64921], [-2.90831, 13.81174], [-2.84667, 14.05532], [-2.66175, 14.14713], [-2.47587, 14.29671], [-2.10223, 14.14878], [-1.9992, 14.19011], [-1.97945, 14.47709], [-1.68083, 14.50023], [-1.32166, 14.72774], [-1.05875, 14.7921], [-0.72004, 15.08655], [-0.24673, 15.07805], [0.06588, 14.96961], [0.23859, 15.00135], [0.72632, 14.95898], [0.96711, 14.98275], [1.31275, 15.27978], [3.01806, 15.34571], [3.03134, 15.42221], [3.50368, 15.35934], [4.19893, 16.39923], [4.21787, 17.00118], [4.26762, 17.00432], [4.26651, 19.14224], [3.36082, 18.9745], [3.12501, 19.1366], [3.24648, 19.81703], [1.20992, 20.73533], [1.15698, 21.12843], [-4.83423, 24.99935]]]] } },
23250 { type: "Feature", properties: { iso1A2: "MM", iso1A3: "MMR", iso1N3: "104", wikidata: "Q836", nameEn: "Myanmar", aliases: ["Burma", "BU"], groups: ["035", "142", "UN"], callingCodes: ["95"] }, geometry: { type: "MultiPolygon", coordinates: [[[[92.62187, 21.87037], [92.59775, 21.6092], [92.68152, 21.28454], [92.60187, 21.24615], [92.55105, 21.3856], [92.43158, 21.37025], [92.37939, 21.47764], [92.20087, 21.337], [92.17752, 21.17445], [92.26071, 21.05697], [92.47409, 20.38654], [92.61042, 13.76986], [94.6371, 13.81803], [97.63455, 9.60854], [98.12555, 9.44056], [98.33094, 9.91973], [98.47298, 9.95782], [98.52291, 9.92389], [98.55174, 9.92804], [98.7391, 10.31488], [98.81944, 10.52761], [98.77275, 10.62548], [98.78511, 10.68351], [98.86819, 10.78336], [99.0069, 10.85485], [98.99701, 10.92962], [99.02337, 10.97217], [99.06938, 10.94857], [99.32756, 11.28545], [99.31573, 11.32081], [99.39485, 11.3925], [99.47598, 11.62434], [99.5672, 11.62732], [99.64108, 11.78948], [99.64891, 11.82699], [99.53424, 12.02317], [99.56445, 12.14805], [99.47519, 12.1353], [99.409, 12.60603], [99.29254, 12.68921], [99.18905, 12.84799], [99.18748, 12.9898], [99.10646, 13.05804], [99.12225, 13.19847], [99.20617, 13.20575], [99.16695, 13.72621], [98.97356, 14.04868], [98.56762, 14.37701], [98.24874, 14.83013], [98.18821, 15.13125], [98.22, 15.21327], [98.30446, 15.30667], [98.40522, 15.25268], [98.41906, 15.27103], [98.39351, 15.34177], [98.4866, 15.39154], [98.56027, 15.33471], [98.58598, 15.46821], [98.541, 15.65406], [98.59853, 15.87197], [98.57019, 16.04578], [98.69585, 16.13353], [98.8376, 16.11706], [98.92656, 16.36425], [98.84485, 16.42354], [98.68074, 16.27068], [98.63817, 16.47424], [98.57912, 16.55983], [98.5695, 16.62826], [98.51113, 16.64503], [98.51833, 16.676], [98.51472, 16.68521], [98.51579, 16.69433], [98.51043, 16.70107], [98.49713, 16.69022], [98.50253, 16.7139], [98.46994, 16.73613], [98.53833, 16.81934], [98.49603, 16.8446], [98.52624, 16.89979], [98.39441, 17.06266], [98.34566, 17.04822], [98.10439, 17.33847], [98.11185, 17.36829], [97.91829, 17.54504], [97.76407, 17.71595], [97.66794, 17.88005], [97.73723, 17.97912], [97.60841, 18.23846], [97.64116, 18.29778], [97.56219, 18.33885], [97.50383, 18.26844], [97.34522, 18.54596], [97.36444, 18.57138], [97.5258, 18.4939], [97.76752, 18.58097], [97.73836, 18.88478], [97.66487, 18.9371], [97.73654, 18.9812], [97.73797, 19.04261], [97.83479, 19.09972], [97.84024, 19.22217], [97.78606, 19.26769], [97.84186, 19.29526], [97.78769, 19.39429], [97.88423, 19.5041], [97.84715, 19.55782], [98.04364, 19.65755], [98.03314, 19.80941], [98.13829, 19.78541], [98.24884, 19.67876], [98.51182, 19.71303], [98.56065, 19.67807], [98.83661, 19.80931], [98.98679, 19.7419], [99.0735, 20.10298], [99.20328, 20.12877], [99.416, 20.08614], [99.52943, 20.14811], [99.5569, 20.20676], [99.46077, 20.36198], [99.46008, 20.39673], [99.68255, 20.32077], [99.81096, 20.33687], [99.86383, 20.44371], [99.88211, 20.44488], [99.88451, 20.44596], [99.89168, 20.44548], [99.89301, 20.44311], [99.89692, 20.44789], [99.90499, 20.4487], [99.91616, 20.44986], [99.95721, 20.46301], [100.08404, 20.36626], [100.1957, 20.68247], [100.36375, 20.82783], [100.51079, 20.82194], [100.60112, 20.8347], [100.64628, 20.88279], [100.50974, 20.88574], [100.55281, 21.02796], [100.63578, 21.05639], [100.72716, 21.31786], [100.80173, 21.2934], [101.00234, 21.39612], [101.16198, 21.52808], [101.15156, 21.56129], [101.11744, 21.77659], [100.87265, 21.67396], [100.72143, 21.51898], [100.57861, 21.45637], [100.4811, 21.46148], [100.42892, 21.54325], [100.35201, 21.53176], [100.25863, 21.47043], [100.18447, 21.51898], [100.1625, 21.48704], [100.12542, 21.50365], [100.10757, 21.59945], [100.17486, 21.65306], [100.12679, 21.70539], [100.04956, 21.66843], [99.98654, 21.71064], [99.94003, 21.82782], [99.99084, 21.97053], [99.96612, 22.05965], [99.85351, 22.04183], [99.47585, 22.13345], [99.33166, 22.09656], [99.1552, 22.15874], [99.19176, 22.16983], [99.17318, 22.18025], [99.28771, 22.4105], [99.37972, 22.50188], [99.38247, 22.57544], [99.31243, 22.73893], [99.45654, 22.85726], [99.43537, 22.94086], [99.54218, 22.90014], [99.52214, 23.08218], [99.34127, 23.13099], [99.25741, 23.09025], [99.04601, 23.12215], [99.05975, 23.16382], [98.88597, 23.18656], [98.92515, 23.29535], [98.93958, 23.31414], [98.87573, 23.33038], [98.92104, 23.36946], [98.87683, 23.48995], [98.82877, 23.47908], [98.80294, 23.5345], [98.88396, 23.59555], [98.81775, 23.694], [98.82933, 23.72921], [98.79607, 23.77947], [98.68209, 23.80492], [98.67797, 23.9644], [98.89632, 24.10612], [98.87998, 24.15624], [98.85319, 24.13042], [98.59256, 24.08371], [98.54476, 24.13119], [98.20666, 24.11406], [98.07806, 24.07988], [98.06703, 24.08028], [98.0607, 24.07812], [98.05671, 24.07961], [98.05302, 24.07408], [98.04709, 24.07616], [97.99583, 24.04932], [97.98691, 24.03897], [97.93951, 24.01953], [97.90998, 24.02094], [97.88616, 24.00463], [97.88414, 23.99405], [97.88814, 23.98605], [97.89683, 23.98389], [97.89676, 23.97931], [97.8955, 23.97758], [97.88811, 23.97446], [97.86545, 23.97723], [97.84328, 23.97603], [97.79416, 23.95663], [97.79456, 23.94836], [97.72302, 23.89288], [97.64667, 23.84574], [97.5247, 23.94032], [97.62363, 24.00506], [97.72903, 24.12606], [97.75305, 24.16902], [97.72799, 24.18883], [97.72998, 24.2302], [97.76799, 24.26365], [97.71941, 24.29652], [97.66723, 24.30027], [97.65624, 24.33781], [97.7098, 24.35658], [97.66998, 24.45288], [97.60029, 24.4401], [97.52757, 24.43748], [97.56286, 24.54535], [97.56525, 24.72838], [97.54675, 24.74202], [97.5542, 24.74943], [97.56383, 24.75535], [97.56648, 24.76475], [97.64354, 24.79171], [97.70181, 24.84557], [97.73127, 24.83015], [97.76481, 24.8289], [97.79949, 24.85655], [97.72903, 24.91332], [97.72216, 25.08508], [97.77023, 25.11492], [97.83614, 25.2715], [97.92541, 25.20815], [98.14925, 25.41547], [98.12591, 25.50722], [98.18084, 25.56298], [98.16848, 25.62739], [98.25774, 25.6051], [98.31268, 25.55307], [98.40606, 25.61129], [98.54064, 25.85129], [98.63128, 25.79937], [98.70818, 25.86241], [98.60763, 26.01512], [98.57085, 26.11547], [98.63128, 26.15492], [98.66884, 26.09165], [98.7329, 26.17218], [98.67797, 26.24487], [98.72741, 26.36183], [98.77547, 26.61994], [98.7333, 26.85615], [98.69582, 27.56499], [98.43353, 27.67086], [98.42529, 27.55404], [98.32641, 27.51385], [98.13964, 27.9478], [98.15337, 28.12114], [97.90069, 28.3776], [97.79632, 28.33168], [97.70705, 28.5056], [97.56835, 28.55628], [97.50518, 28.49716], [97.47085, 28.2688], [97.41729, 28.29783], [97.34547, 28.21385], [97.31292, 28.06784], [97.35412, 28.06663], [97.38845, 28.01329], [97.35824, 27.87256], [97.29919, 27.92233], [96.90112, 27.62149], [96.91431, 27.45752], [97.17422, 27.14052], [97.14675, 27.09041], [96.89132, 27.17474], [96.85287, 27.2065], [96.88445, 27.25046], [96.73888, 27.36638], [96.55761, 27.29928], [96.40779, 27.29818], [96.15591, 27.24572], [96.04949, 27.19428], [95.93002, 27.04149], [95.81603, 27.01335], [95.437, 26.7083], [95.30339, 26.65372], [95.23513, 26.68499], [95.05798, 26.45408], [95.12801, 26.38397], [95.11428, 26.1019], [95.18556, 26.07338], [94.80117, 25.49359], [94.68032, 25.47003], [94.57458, 25.20318], [94.74212, 25.13606], [94.73937, 25.00545], [94.60204, 24.70889], [94.5526, 24.70764], [94.50729, 24.59281], [94.45279, 24.56656], [94.32362, 24.27692], [94.30215, 24.23752], [94.14081, 23.83333], [93.92089, 23.95812], [93.80279, 23.92549], [93.75952, 24.0003], [93.62871, 24.00922], [93.50616, 23.94432], [93.46633, 23.97067], [93.41415, 24.07854], [93.34735, 24.10151], [93.32351, 24.04468], [93.36059, 23.93176], [93.3908, 23.92925], [93.3908, 23.7622], [93.43475, 23.68299], [93.38805, 23.4728], [93.39981, 23.38828], [93.38781, 23.36139], [93.36862, 23.35426], [93.38478, 23.13698], [93.2878, 23.00464], [93.12988, 23.05772], [93.134, 22.92498], [93.09417, 22.69459], [93.134, 22.59573], [93.11477, 22.54374], [93.13537, 22.45873], [93.18206, 22.43716], [93.19991, 22.25425], [93.14224, 22.24535], [93.15734, 22.18687], [93.04885, 22.20595], [92.99255, 22.05965], [92.99804, 21.98964], [92.93899, 22.02656], [92.89504, 21.95143], [92.86208, 22.05456], [92.70416, 22.16017], [92.67532, 22.03547], [92.60949, 21.97638], [92.62187, 21.87037]]]] } },
23251 { type: "Feature", properties: { iso1A2: "MN", iso1A3: "MNG", iso1N3: "496", wikidata: "Q711", nameEn: "Mongolia", groups: ["030", "142", "UN"], callingCodes: ["976"] }, geometry: { type: "MultiPolygon", coordinates: [[[[102.14032, 51.35566], [101.5044, 51.50467], [101.39085, 51.45753], [100.61116, 51.73028], [99.89203, 51.74903], [99.75578, 51.90108], [99.27888, 51.96876], [98.87768, 52.14563], [98.74142, 51.8637], [98.33222, 51.71832], [98.22053, 51.46579], [98.05257, 51.46696], [97.83305, 51.00248], [98.01472, 50.86652], [97.9693, 50.78044], [98.06393, 50.61262], [98.31373, 50.4996], [98.29481, 50.33561], [97.85197, 49.91339], [97.76871, 49.99861], [97.56432, 49.92801], [97.56811, 49.84265], [97.24639, 49.74737], [96.97388, 49.88413], [95.80056, 50.04239], [95.74757, 49.97915], [95.02465, 49.96941], [94.97166, 50.04725], [94.6121, 50.04239], [94.49477, 50.17832], [94.39258, 50.22193], [94.30823, 50.57498], [92.99595, 50.63183], [93.01109, 50.79001], [92.44714, 50.78762], [92.07173, 50.69585], [91.86048, 50.73734], [89.59711, 49.90851], [89.70687, 49.72535], [88.82499, 49.44808], [88.42449, 49.48821], [88.17223, 49.46934], [88.15543, 49.30314], [87.98977, 49.18147], [87.81333, 49.17354], [87.88171, 48.95853], [87.73822, 48.89582], [88.0788, 48.71436], [87.96361, 48.58478], [88.58939, 48.34531], [88.58316, 48.21893], [88.8011, 48.11302], [88.93186, 48.10263], [89.0711, 47.98528], [89.55453, 48.0423], [89.76624, 47.82745], [90.06512, 47.88177], [90.10871, 47.7375], [90.33598, 47.68303], [90.48854, 47.41826], [90.48542, 47.30438], [90.76108, 46.99399], [90.84035, 46.99525], [91.03649, 46.72916], [91.0147, 46.58171], [91.07696, 46.57315], [90.89639, 46.30711], [90.99672, 46.14207], [91.03026, 46.04194], [90.70907, 45.73437], [90.65114, 45.49314], [90.89169, 45.19667], [91.64048, 45.07408], [93.51161, 44.95964], [94.10003, 44.71016], [94.71959, 44.35284], [95.01191, 44.25274], [95.39772, 44.2805], [95.32891, 44.02407], [95.52594, 43.99353], [95.89543, 43.2528], [96.35658, 42.90363], [96.37926, 42.72055], [97.1777, 42.7964], [99.50671, 42.56535], [100.33297, 42.68231], [100.84979, 42.67087], [101.80515, 42.50074], [102.07645, 42.22519], [102.72403, 42.14675], [103.92804, 41.78246], [104.52258, 41.8706], [104.51667, 41.66113], [105.0123, 41.63188], [106.76517, 42.28741], [107.24774, 42.36107], [107.29755, 42.41395], [107.49681, 42.46221], [107.57258, 42.40898], [108.84489, 42.40246], [109.00679, 42.45302], [109.452, 42.44842], [109.89402, 42.63111], [110.08401, 42.6411], [110.4327, 42.78293], [111.0149, 43.3289], [111.59087, 43.51207], [111.79758, 43.6637], [111.93776, 43.68709], [111.96289, 43.81596], [111.40498, 44.3461], [111.76275, 44.98032], [111.98695, 45.09074], [112.4164, 45.06858], [112.74662, 44.86297], [113.70918, 44.72891], [114.5166, 45.27189], [114.54801, 45.38337], [114.74612, 45.43585], [114.94546, 45.37377], [115.60329, 45.44717], [116.16989, 45.68603], [116.27366, 45.78637], [116.24012, 45.8778], [116.26678, 45.96479], [116.58612, 46.30211], [116.75551, 46.33083], [116.83166, 46.38637], [117.36609, 46.36335], [117.41782, 46.57862], [117.60748, 46.59771], [117.69554, 46.50991], [118.30534, 46.73519], [118.78747, 46.68689], [118.8337, 46.77742], [118.89974, 46.77139], [118.92616, 46.72765], [119.00541, 46.74273], [119.10448, 46.65516], [119.24978, 46.64761], [119.32827, 46.61433], [119.42827, 46.63783], [119.65265, 46.62342], [119.68127, 46.59015], [119.77373, 46.62947], [119.80455, 46.67631], [119.89261, 46.66423], [119.91242, 46.90091], [119.85518, 46.92196], [119.71209, 47.19192], [119.62403, 47.24575], [119.56019, 47.24874], [119.54918, 47.29505], [119.31964, 47.42617], [119.35892, 47.48104], [119.13995, 47.53997], [119.12343, 47.66458], [118.7564, 47.76947], [118.55766, 47.99277], [118.29654, 48.00246], [118.22677, 48.03853], [118.11009, 48.04], [118.03676, 48.00982], [117.80196, 48.01661], [117.50181, 47.77216], [117.37875, 47.63627], [116.9723, 47.87285], [116.67405, 47.89039], [116.4465, 47.83662], [116.21879, 47.88505], [115.94296, 47.67741], [115.57128, 47.91988], [115.52082, 48.15367], [115.811, 48.25699], [115.78876, 48.51781], [116.06565, 48.81716], [116.03781, 48.87014], [116.71193, 49.83813], [116.62502, 49.92919], [116.22402, 50.04477], [115.73602, 49.87688], [115.26068, 49.97367], [114.9703, 50.19254], [114.325, 50.28098], [113.20216, 49.83356], [113.02647, 49.60772], [110.64493, 49.1816], [110.39891, 49.25083], [110.24373, 49.16676], [109.51325, 49.22859], [109.18017, 49.34709], [108.53969, 49.32325], [108.27937, 49.53167], [107.95387, 49.66659], [107.96116, 49.93191], [107.36407, 49.97612], [107.1174, 50.04239], [107.00007, 50.1977], [106.80326, 50.30177], [106.58373, 50.34044], [106.51122, 50.34408], [106.49628, 50.32436], [106.47156, 50.31909], [106.07865, 50.33474], [106.05562, 50.40582], [105.32528, 50.4648], [103.70343, 50.13952], [102.71178, 50.38873], [102.32194, 50.67982], [102.14032, 51.35566]]]] } },
23252 { type: "Feature", properties: { iso1A2: "MO", iso1A3: "MAC", iso1N3: "446", wikidata: "Q14773", nameEn: "Macau", aliases: ["Macao"], country: "CN", groups: ["030", "142", "UN"], driveSide: "left", callingCodes: ["853"] }, geometry: { type: "MultiPolygon", coordinates: [[[[113.54942, 22.14519], [113.54839, 22.10909], [113.57191, 22.07696], [113.63011, 22.10782], [113.60504, 22.20464], [113.57123, 22.20416], [113.56865, 22.20973], [113.5508, 22.21672], [113.54333, 22.21688], [113.54093, 22.21314], [113.53593, 22.2137], [113.53301, 22.21235], [113.53552, 22.20607], [113.52659, 22.18271], [113.54093, 22.15497], [113.54942, 22.14519]]]] } },
23253 { type: "Feature", properties: { iso1A2: "MP", iso1A3: "MNP", iso1N3: "580", wikidata: "Q16644", nameEn: "Northern Mariana Islands", aliases: ["US-MP"], country: "US", groups: ["Q1352230", "Q153732", "057", "009", "UN"], roadSpeedUnit: "mph", callingCodes: ["1 670"] }, geometry: { type: "MultiPolygon", coordinates: [[[[135.52896, 14.32623], [152.19114, 13.63487], [145.05972, 21.28731], [135.52896, 14.32623]]]] } },
23254 { type: "Feature", properties: { iso1A2: "MQ", iso1A3: "MTQ", iso1N3: "474", wikidata: "Q17054", nameEn: "Martinique", country: "FR", groups: ["Q3320166", "EU", "029", "003", "419", "019", "UN"], callingCodes: ["596"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-59.95997, 14.20285], [-61.07821, 15.25109], [-61.69315, 14.26451], [-59.95997, 14.20285]]]] } },
23255 { type: "Feature", properties: { iso1A2: "MR", iso1A3: "MRT", iso1N3: "478", wikidata: "Q1025", nameEn: "Mauritania", groups: ["011", "202", "002", "UN"], callingCodes: ["222"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-5.60725, 16.49919], [-6.57191, 25.0002], [-4.83423, 24.99935], [-8.66674, 27.31569], [-8.66721, 25.99918], [-12.0002, 25.9986], [-12.00251, 23.4538], [-12.14969, 23.41935], [-12.36213, 23.3187], [-12.5741, 23.28975], [-13.00412, 23.02297], [-13.10753, 22.89493], [-13.15313, 22.75649], [-13.08438, 22.53866], [-13.01525, 21.33343], [-16.95474, 21.33997], [-16.99806, 21.12142], [-17.0357, 21.05368], [-17.0396, 20.9961], [-17.06781, 20.92697], [-17.0695, 20.85742], [-17.0471, 20.76408], [-17.15288, 16.07139], [-16.50854, 16.09032], [-16.48967, 16.0496], [-16.44814, 16.09753], [-16.4429, 16.20605], [-16.27016, 16.51565], [-15.6509, 16.50315], [-15.00557, 16.64997], [-14.32144, 16.61495], [-13.80075, 16.13961], [-13.43135, 16.09022], [-13.11029, 15.52116], [-12.23936, 14.76324], [-11.94903, 14.76143], [-11.70705, 15.51558], [-11.43483, 15.62339], [-10.90932, 15.11001], [-10.71721, 15.4223], [-9.40447, 15.4396], [-9.44673, 15.60553], [-9.33314, 15.7044], [-9.31106, 15.69412], [-9.32979, 15.50032], [-5.50165, 15.50061], [-5.33435, 16.33354], [-5.60725, 16.49919]]]] } },
23256 { type: "Feature", properties: { iso1A2: "MS", iso1A3: "MSR", iso1N3: "500", wikidata: "Q13353", nameEn: "Montserrat", country: "GB", groups: ["BOTS", "029", "003", "419", "019", "UN"], driveSide: "left", roadSpeedUnit: "mph", roadHeightUnit: "ft", callingCodes: ["1 664"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-61.91508, 16.51165], [-62.1023, 16.97277], [-62.58307, 16.68909], [-61.91508, 16.51165]]]] } },
23257 { type: "Feature", properties: { iso1A2: "MT", iso1A3: "MLT", iso1N3: "470", wikidata: "Q233", nameEn: "Malta", groups: ["EU", "039", "150", "UN"], driveSide: "left", callingCodes: ["356"] }, geometry: { type: "MultiPolygon", coordinates: [[[[15.70991, 35.79901], [14.07544, 36.41525], [13.27636, 35.20764], [15.70991, 35.79901]]]] } },
23258 { type: "Feature", properties: { iso1A2: "MU", iso1A3: "MUS", iso1N3: "480", wikidata: "Q1027", nameEn: "Mauritius", groups: ["014", "202", "002", "UN"], driveSide: "left", callingCodes: ["230"] }, geometry: { type: "MultiPolygon", coordinates: [[[[56.09755, -9.55401], [57.50644, -31.92637], [68.4673, -19.15185], [56.09755, -9.55401]]]] } },
23259 { type: "Feature", properties: { iso1A2: "MV", iso1A3: "MDV", iso1N3: "462", wikidata: "Q826", nameEn: "Maldives", groups: ["034", "142", "UN"], driveSide: "left", callingCodes: ["960"] }, geometry: { type: "MultiPolygon", coordinates: [[[[71.9161, 8.55531], [72.57428, -3.7623], [76.59015, 5.591], [71.9161, 8.55531]]]] } },
23260 { type: "Feature", properties: { iso1A2: "MW", iso1A3: "MWI", iso1N3: "454", wikidata: "Q1020", nameEn: "Malawi", groups: ["014", "202", "002", "UN"], driveSide: "left", callingCodes: ["265"] }, geometry: { type: "MultiPolygon", coordinates: [[[[33.48052, -9.62442], [33.31581, -9.48554], [33.14925, -9.49322], [32.99397, -9.36712], [32.95389, -9.40138], [33.00476, -9.5133], [33.00256, -9.63053], [33.05485, -9.61316], [33.10163, -9.66525], [33.12144, -9.58929], [33.2095, -9.61099], [33.31517, -9.82364], [33.36581, -9.81063], [33.37902, -9.9104], [33.31297, -10.05133], [33.53863, -10.20148], [33.54797, -10.36077], [33.70675, -10.56896], [33.47636, -10.78465], [33.28022, -10.84428], [33.25998, -10.88862], [33.39697, -11.15296], [33.29267, -11.3789], [33.29267, -11.43536], [33.23663, -11.40637], [33.24252, -11.59302], [33.32692, -11.59248], [33.33937, -11.91252], [33.25998, -12.14242], [33.3705, -12.34931], [33.47636, -12.32498], [33.54485, -12.35996], [33.37517, -12.54085], [33.28177, -12.54692], [33.18837, -12.61377], [33.05917, -12.59554], [32.94397, -12.76868], [32.96733, -12.88251], [33.02181, -12.88707], [32.98289, -13.12671], [33.0078, -13.19492], [32.86113, -13.47292], [32.84176, -13.52794], [32.73683, -13.57682], [32.68436, -13.55769], [32.66468, -13.60019], [32.68654, -13.64268], [32.7828, -13.64805], [32.84528, -13.71576], [32.76962, -13.77224], [32.79015, -13.80755], [32.88985, -13.82956], [32.99042, -13.95689], [33.02977, -14.05022], [33.07568, -13.98447], [33.16749, -13.93992], [33.24249, -14.00019], [33.66677, -14.61306], [33.7247, -14.4989], [33.88503, -14.51652], [33.92898, -14.47929], [34.08588, -14.48893], [34.18733, -14.43823], [34.22355, -14.43607], [34.34453, -14.3985], [34.35843, -14.38652], [34.39277, -14.39467], [34.4192, -14.43191], [34.44641, -14.47746], [34.45053, -14.49873], [34.47628, -14.53363], [34.48932, -14.53646], [34.49636, -14.55091], [34.52366, -14.5667], [34.53962, -14.59776], [34.55112, -14.64494], [34.53516, -14.67782], [34.52057, -14.68263], [34.54503, -14.74672], [34.567, -14.77345], [34.61522, -14.99583], [34.57503, -15.30619], [34.43126, -15.44778], [34.44981, -15.60864], [34.25195, -15.90321], [34.43126, -16.04737], [34.40344, -16.20923], [35.04805, -16.83167], [35.13771, -16.81687], [35.17017, -16.93521], [35.04805, -17.00027], [35.0923, -17.13235], [35.3062, -17.1244], [35.27065, -16.93817], [35.30929, -16.82871], [35.27219, -16.69402], [35.14235, -16.56812], [35.25828, -16.4792], [35.30157, -16.2211], [35.43355, -16.11371], [35.52365, -16.15414], [35.70107, -16.10147], [35.80487, -16.03907], [35.85303, -15.41913], [35.78799, -15.17428], [35.91812, -14.89514], [35.87212, -14.89478], [35.86945, -14.67481], [35.5299, -14.27714], [35.47989, -14.15594], [34.86229, -13.48958], [34.60253, -13.48487], [34.37831, -12.17408], [34.46088, -12.0174], [34.70739, -12.15652], [34.82903, -12.04837], [34.57917, -11.87849], [34.64241, -11.57499], [34.96296, -11.57354], [34.91153, -11.39799], [34.79375, -11.32245], [34.63305, -11.11731], [34.61161, -11.01611], [34.67047, -10.93796], [34.65946, -10.6828], [34.57581, -10.56271], [34.51911, -10.12279], [34.54499, -10.0678], [34.03865, -9.49398], [33.95829, -9.54066], [33.9638, -9.62206], [33.93298, -9.71647], [33.76677, -9.58516], [33.48052, -9.62442]]]] } },
23261 { type: "Feature", properties: { iso1A2: "MX", iso1A3: "MEX", iso1N3: "484", wikidata: "Q96", nameEn: "Mexico", groups: ["013", "003", "419", "019", "UN"], callingCodes: ["52"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-117.1243, 32.53427], [-118.48109, 32.5991], [-120.12904, 18.41089], [-92.37213, 14.39277], [-92.2261, 14.53423], [-92.1454, 14.6804], [-92.18161, 14.84147], [-92.1423, 14.88647], [-92.1454, 14.98143], [-92.0621, 15.07406], [-92.20983, 15.26077], [-91.73182, 16.07371], [-90.44567, 16.07573], [-90.40499, 16.40524], [-90.61212, 16.49832], [-90.69064, 16.70697], [-91.04436, 16.92175], [-91.43809, 17.25373], [-90.99199, 17.25192], [-90.98678, 17.81655], [-89.14985, 17.81563], [-89.15105, 17.95104], [-89.03839, 18.0067], [-88.8716, 17.89535], [-88.71505, 18.0707], [-88.48242, 18.49164], [-88.3268, 18.49048], [-88.29909, 18.47591], [-88.26593, 18.47617], [-88.03238, 18.41778], [-88.03165, 18.16657], [-87.90671, 18.15213], [-87.87604, 18.18313], [-87.86657, 18.19971], [-87.85693, 18.18266], [-87.84815, 18.18511], [-86.92368, 17.61462], [-85.9092, 21.8218], [-96.92418, 25.97377], [-97.13927, 25.96583], [-97.35946, 25.92189], [-97.37332, 25.83854], [-97.42511, 25.83969], [-97.45669, 25.86874], [-97.49828, 25.89877], [-97.52025, 25.88518], [-97.66511, 26.01708], [-97.95155, 26.0625], [-97.97017, 26.05232], [-98.24603, 26.07191], [-98.27075, 26.09457], [-98.30491, 26.10475], [-98.35126, 26.15129], [-99.00546, 26.3925], [-99.03053, 26.41249], [-99.08477, 26.39849], [-99.53573, 27.30926], [-99.49744, 27.43746], [-99.482, 27.47128], [-99.48045, 27.49016], [-99.50208, 27.50021], [-99.52955, 27.49747], [-99.51478, 27.55836], [-99.55409, 27.61314], [-100.50029, 28.66117], [-100.51222, 28.70679], [-100.5075, 28.74066], [-100.52313, 28.75598], [-100.59809, 28.88197], [-100.63689, 28.90812], [-100.67294, 29.09744], [-100.79696, 29.24688], [-100.87982, 29.296], [-100.94056, 29.33371], [-100.94579, 29.34523], [-100.96725, 29.3477], [-101.01128, 29.36947], [-101.05686, 29.44738], [-101.47277, 29.7744], [-102.60596, 29.8192], [-103.15787, 28.93865], [-104.37752, 29.54255], [-104.39363, 29.55396], [-104.3969, 29.57105], [-104.5171, 29.64671], [-104.77674, 30.4236], [-106.00363, 31.39181], [-106.09025, 31.40569], [-106.20346, 31.46305], [-106.23711, 31.51262], [-106.24612, 31.54193], [-106.28084, 31.56173], [-106.30305, 31.62154], [-106.33419, 31.66303], [-106.34864, 31.69663], [-106.3718, 31.71165], [-106.38003, 31.73151], [-106.41773, 31.75196], [-106.43419, 31.75478], [-106.45244, 31.76523], [-106.46726, 31.75998], [-106.47298, 31.75054], [-106.48815, 31.74769], [-106.50111, 31.75714], [-106.50962, 31.76155], [-106.51251, 31.76922], [-106.52266, 31.77509], [-106.529, 31.784], [-108.20899, 31.78534], [-108.20979, 31.33316], [-111.07523, 31.33232], [-114.82011, 32.49609], [-114.79524, 32.55731], [-114.81141, 32.55543], [-114.80584, 32.62028], [-114.76736, 32.64094], [-114.71871, 32.71894], [-115.88053, 32.63624], [-117.1243, 32.53427]]]] } },
23262 { type: "Feature", properties: { iso1A2: "MY", iso1A3: "MYS", iso1N3: "458", wikidata: "Q833", nameEn: "Malaysia" }, geometry: null },
23263 { type: "Feature", properties: { iso1A2: "MZ", iso1A3: "MOZ", iso1N3: "508", wikidata: "Q1029", nameEn: "Mozambique", groups: ["014", "202", "002", "UN"], driveSide: "left", callingCodes: ["258"] }, geometry: { type: "MultiPolygon", coordinates: [[[[40.74206, -10.25691], [40.44265, -10.4618], [40.00295, -10.80255], [39.58249, -10.96043], [39.24395, -11.17433], [38.88996, -11.16978], [38.47258, -11.4199], [38.21598, -11.27289], [37.93618, -11.26228], [37.8388, -11.3123], [37.76614, -11.53352], [37.3936, -11.68949], [36.80309, -11.56836], [36.62068, -11.72884], [36.19094, -11.70008], [36.19094, -11.57593], [35.82767, -11.41081], [35.63599, -11.55927], [34.96296, -11.57354], [34.64241, -11.57499], [34.57917, -11.87849], [34.82903, -12.04837], [34.70739, -12.15652], [34.46088, -12.0174], [34.37831, -12.17408], [34.60253, -13.48487], [34.86229, -13.48958], [35.47989, -14.15594], [35.5299, -14.27714], [35.86945, -14.67481], [35.87212, -14.89478], [35.91812, -14.89514], [35.78799, -15.17428], [35.85303, -15.41913], [35.80487, -16.03907], [35.70107, -16.10147], [35.52365, -16.15414], [35.43355, -16.11371], [35.30157, -16.2211], [35.25828, -16.4792], [35.14235, -16.56812], [35.27219, -16.69402], [35.30929, -16.82871], [35.27065, -16.93817], [35.3062, -17.1244], [35.0923, -17.13235], [35.04805, -17.00027], [35.17017, -16.93521], [35.13771, -16.81687], [35.04805, -16.83167], [34.40344, -16.20923], [34.43126, -16.04737], [34.25195, -15.90321], [34.44981, -15.60864], [34.43126, -15.44778], [34.57503, -15.30619], [34.61522, -14.99583], [34.567, -14.77345], [34.54503, -14.74672], [34.52057, -14.68263], [34.53516, -14.67782], [34.55112, -14.64494], [34.53962, -14.59776], [34.52366, -14.5667], [34.49636, -14.55091], [34.48932, -14.53646], [34.47628, -14.53363], [34.45053, -14.49873], [34.44641, -14.47746], [34.4192, -14.43191], [34.39277, -14.39467], [34.35843, -14.38652], [34.34453, -14.3985], [34.22355, -14.43607], [34.18733, -14.43823], [34.08588, -14.48893], [33.92898, -14.47929], [33.88503, -14.51652], [33.7247, -14.4989], [33.66677, -14.61306], [33.24249, -14.00019], [30.22098, -14.99447], [30.41902, -15.62269], [30.42568, -15.9962], [30.91597, -15.99924], [30.97761, -16.05848], [31.13171, -15.98019], [31.30563, -16.01193], [31.42451, -16.15154], [31.67988, -16.19595], [31.90223, -16.34388], [31.91324, -16.41569], [32.02772, -16.43892], [32.28529, -16.43892], [32.42838, -16.4727], [32.71017, -16.59932], [32.69917, -16.66893], [32.78943, -16.70267], [32.97655, -16.70689], [32.91051, -16.89446], [32.84113, -16.92259], [32.96554, -17.11971], [33.00517, -17.30477], [33.0426, -17.3468], [32.96554, -17.48964], [32.98536, -17.55891], [33.0492, -17.60298], [32.94133, -17.99705], [33.03159, -18.35054], [33.02278, -18.4696], [32.88629, -18.51344], [32.88629, -18.58023], [32.95013, -18.69079], [32.9017, -18.7992], [32.82465, -18.77419], [32.70137, -18.84712], [32.73439, -18.92628], [32.69917, -18.94293], [32.72118, -19.02204], [32.84006, -19.0262], [32.87088, -19.09279], [32.85107, -19.29238], [32.77966, -19.36098], [32.78282, -19.47513], [32.84446, -19.48343], [32.84666, -19.68462], [32.95013, -19.67219], [33.06461, -19.77787], [33.01178, -20.02007], [32.93032, -20.03868], [32.85987, -20.16686], [32.85987, -20.27841], [32.66174, -20.56106], [32.55167, -20.56312], [32.48122, -20.63319], [32.51644, -20.91929], [32.37115, -21.133], [32.48236, -21.32873], [32.41234, -21.31246], [31.38336, -22.36919], [31.30611, -22.422], [31.55779, -23.176], [31.56539, -23.47268], [31.67942, -23.60858], [31.70223, -23.72695], [31.77445, -23.90082], [31.87707, -23.95293], [31.90368, -24.18892], [31.9835, -24.29983], [32.03196, -25.10785], [32.01676, -25.38117], [31.97875, -25.46356], [32.00631, -25.65044], [31.92649, -25.84216], [31.974, -25.95387], [32.00916, -25.999], [32.08599, -26.00978], [32.10435, -26.15656], [32.07352, -26.40185], [32.13409, -26.5317], [32.13315, -26.84345], [32.19409, -26.84032], [32.22302, -26.84136], [32.29584, -26.852], [32.35222, -26.86027], [34.51034, -26.91792], [42.99868, -12.65261], [40.74206, -10.25691]]]] } },
23264 { type: "Feature", properties: { iso1A2: "NA", iso1A3: "NAM", iso1N3: "516", wikidata: "Q1030", nameEn: "Namibia", groups: ["018", "202", "002", "UN"], driveSide: "left", callingCodes: ["264"] }, geometry: { type: "MultiPolygon", coordinates: [[[[14.28743, -17.38814], [13.95896, -17.43141], [13.36212, -16.98048], [12.97145, -16.98567], [12.52111, -17.24495], [12.07076, -17.15165], [11.75063, -17.25013], [10.5065, -17.25284], [12.51595, -32.27486], [16.45332, -28.63117], [16.46592, -28.57126], [16.59922, -28.53246], [16.90446, -28.057], [17.15405, -28.08573], [17.4579, -28.68718], [18.99885, -28.89165], [19.99882, -28.42622], [19.99817, -24.76768], [19.99912, -21.99991], [20.99751, -22.00026], [20.99904, -18.31743], [21.45556, -18.31795], [23.0996, -18.00075], [23.29618, -17.99855], [23.61088, -18.4881], [24.19416, -18.01919], [24.40577, -17.95726], [24.57485, -18.07151], [24.6303, -17.9863], [24.71887, -17.9218], [24.73364, -17.89338], [24.95586, -17.79674], [25.05895, -17.84452], [25.16882, -17.78253], [25.26433, -17.79571], [25.00198, -17.58221], [24.70864, -17.49501], [24.5621, -17.52963], [24.38712, -17.46818], [24.32811, -17.49082], [24.23619, -17.47489], [23.47474, -17.62877], [21.42741, -18.02787], [21.14283, -17.94318], [18.84226, -17.80375], [18.39229, -17.38927], [14.28743, -17.38814]]]] } },
23265 { type: "Feature", properties: { iso1A2: "NC", iso1A3: "NCL", iso1N3: "540", wikidata: "Q33788", nameEn: "New Caledonia", country: "FR", groups: ["EU", "Q1451600", "054", "009", "UN"], callingCodes: ["687"] }, geometry: { type: "MultiPolygon", coordinates: [[[[159.77159, -28.41151], [174.245, -23.1974], [156.73836, -14.50464], [159.77159, -28.41151]]]] } },
23266 { type: "Feature", properties: { iso1A2: "NE", iso1A3: "NER", iso1N3: "562", wikidata: "Q1032", nameEn: "Niger", aliases: ["RN"], groups: ["011", "202", "002", "UN"], callingCodes: ["227"] }, geometry: { type: "MultiPolygon", coordinates: [[[[14.22918, 22.61719], [13.5631, 23.16574], [11.96886, 23.51735], [7.48273, 20.87258], [7.38361, 20.79165], [5.8153, 19.45101], [4.26651, 19.14224], [4.26762, 17.00432], [4.21787, 17.00118], [4.19893, 16.39923], [3.50368, 15.35934], [3.03134, 15.42221], [3.01806, 15.34571], [1.31275, 15.27978], [0.96711, 14.98275], [0.72632, 14.95898], [0.23859, 15.00135], [0.16936, 14.51654], [0.38051, 14.05575], [0.61924, 13.68491], [0.77377, 13.6866], [0.77637, 13.64442], [0.99514, 13.5668], [1.02813, 13.46635], [1.20088, 13.38951], [1.24429, 13.39373], [1.28509, 13.35488], [1.24516, 13.33968], [1.21217, 13.37853], [1.18873, 13.31771], [0.99253, 13.37515], [0.99167, 13.10727], [2.26349, 12.41915], [2.05785, 12.35539], [2.39723, 11.89473], [2.45824, 11.98672], [2.39657, 12.10952], [2.37783, 12.24804], [2.6593, 12.30631], [2.83978, 12.40585], [3.25352, 12.01467], [3.31613, 11.88495], [3.48187, 11.86092], [3.59375, 11.70269], [3.61075, 11.69181], [3.67988, 11.75429], [3.67122, 11.80865], [3.63063, 11.83042], [3.61955, 11.91847], [3.67775, 11.97599], [3.63136, 12.11826], [3.66364, 12.25884], [3.65111, 12.52223], [3.94339, 12.74979], [4.10006, 12.98862], [4.14367, 13.17189], [4.14186, 13.47586], [4.23456, 13.47725], [4.4668, 13.68286], [4.87425, 13.78], [4.9368, 13.7345], [5.07396, 13.75052], [5.21026, 13.73627], [5.27797, 13.75474], [5.35437, 13.83567], [5.52957, 13.8845], [6.15771, 13.64564], [6.27411, 13.67835], [6.43053, 13.6006], [6.69617, 13.34057], [6.94445, 12.99825], [7.0521, 13.00076], [7.12676, 13.02445], [7.22399, 13.1293], [7.39241, 13.09717], [7.81085, 13.34902], [8.07997, 13.30847], [8.25185, 13.20369], [8.41853, 13.06166], [8.49493, 13.07519], [8.60431, 13.01768], [8.64251, 12.93985], [8.97413, 12.83661], [9.65995, 12.80614], [10.00373, 13.18171], [10.19993, 13.27129], [10.46731, 13.28819], [10.66004, 13.36422], [11.4535, 13.37773], [11.88236, 13.2527], [12.04209, 13.14452], [12.16189, 13.10056], [12.19315, 13.12423], [12.47095, 13.06673], [12.58033, 13.27805], [12.6793, 13.29157], [12.87376, 13.48919], [13.05085, 13.53984], [13.19844, 13.52802], [13.33213, 13.71195], [13.6302, 13.71094], [13.47559, 14.40881], [13.48259, 14.46704], [13.68573, 14.55276], [13.67878, 14.64013], [13.809, 14.72915], [13.78991, 14.87519], [13.86301, 15.04043], [14.37425, 15.72591], [15.50373, 16.89649], [15.6032, 18.77402], [15.75098, 19.93002], [15.99632, 20.35364], [15.6721, 20.70069], [15.59841, 20.74039], [15.56004, 20.79488], [15.55382, 20.86507], [15.57248, 20.92138], [15.62515, 20.95395], [15.28332, 21.44557], [15.20213, 21.49365], [15.19692, 21.99339], [14.99751, 23.00539], [14.22918, 22.61719]]]] } },
23267 { type: "Feature", properties: { iso1A2: "NF", iso1A3: "NFK", iso1N3: "574", wikidata: "Q31057", nameEn: "Norfolk Island", country: "AU", groups: ["053", "009", "UN"], driveSide: "left", callingCodes: ["672 3"] }, geometry: { type: "MultiPolygon", coordinates: [[[[169.82316, -28.16667], [166.29505, -28.29175], [167.94076, -30.60745], [169.82316, -28.16667]]]] } },
23268 { type: "Feature", properties: { iso1A2: "NG", iso1A3: "NGA", iso1N3: "566", wikidata: "Q1033", nameEn: "Nigeria", groups: ["011", "202", "002", "UN"], callingCodes: ["234"] }, geometry: { type: "MultiPolygon", coordinates: [[[[6.15771, 13.64564], [5.52957, 13.8845], [5.35437, 13.83567], [5.27797, 13.75474], [5.21026, 13.73627], [5.07396, 13.75052], [4.9368, 13.7345], [4.87425, 13.78], [4.4668, 13.68286], [4.23456, 13.47725], [4.14186, 13.47586], [4.14367, 13.17189], [4.10006, 12.98862], [3.94339, 12.74979], [3.65111, 12.52223], [3.66364, 12.25884], [3.63136, 12.11826], [3.67775, 11.97599], [3.61955, 11.91847], [3.63063, 11.83042], [3.67122, 11.80865], [3.67988, 11.75429], [3.61075, 11.69181], [3.59375, 11.70269], [3.49175, 11.29765], [3.71505, 11.13015], [3.84243, 10.59316], [3.78292, 10.40538], [3.6844, 10.46351], [3.57275, 10.27185], [3.66908, 10.18136], [3.54429, 9.87739], [3.35383, 9.83641], [3.32099, 9.78032], [3.34726, 9.70696], [3.25093, 9.61632], [3.13928, 9.47167], [3.14147, 9.28375], [3.08017, 9.10006], [2.77907, 9.06924], [2.67523, 7.87825], [2.73095, 7.7755], [2.73405, 7.5423], [2.78668, 7.5116], [2.79442, 7.43486], [2.74489, 7.42565], [2.76965, 7.13543], [2.71702, 6.95722], [2.74024, 6.92802], [2.73405, 6.78508], [2.78823, 6.76356], [2.78204, 6.70514], [2.7325, 6.64057], [2.74334, 6.57291], [2.70464, 6.50831], [2.70566, 6.38038], [2.74181, 6.13349], [5.87055, 3.78489], [8.34397, 4.30689], [8.60302, 4.87353], [8.78027, 5.1243], [8.92029, 5.58403], [8.83687, 5.68483], [8.88156, 5.78857], [8.84209, 5.82562], [9.51757, 6.43874], [9.70674, 6.51717], [9.77824, 6.79088], [9.86314, 6.77756], [10.15135, 7.03781], [10.21466, 6.88996], [10.53639, 6.93432], [10.57214, 7.16345], [10.59746, 7.14719], [10.60789, 7.06885], [10.83727, 6.9358], [10.8179, 6.83377], [10.94302, 6.69325], [11.09644, 6.68437], [11.09495, 6.51717], [11.42041, 6.53789], [11.42264, 6.5882], [11.51499, 6.60892], [11.57755, 6.74059], [11.55818, 6.86186], [11.63117, 6.9905], [11.87396, 7.09398], [11.84864, 7.26098], [11.93205, 7.47812], [12.01844, 7.52981], [11.99908, 7.67302], [12.20909, 7.97553], [12.19271, 8.10826], [12.24782, 8.17904], [12.26123, 8.43696], [12.4489, 8.52536], [12.44146, 8.6152], [12.68722, 8.65938], [12.71701, 8.7595], [12.79, 8.75361], [12.81085, 8.91992], [12.90022, 9.11411], [12.91958, 9.33905], [12.85628, 9.36698], [13.02385, 9.49334], [13.22642, 9.57266], [13.25472, 9.76795], [13.29941, 9.8296], [13.25025, 9.86042], [13.24132, 9.91031], [13.27409, 9.93232], [13.286, 9.9822], [13.25323, 10.00127], [13.25025, 10.03647], [13.34111, 10.12299], [13.43644, 10.13326], [13.5705, 10.53183], [13.54964, 10.61236], [13.73434, 10.9255], [13.70753, 10.94451], [13.7403, 11.00593], [13.78945, 11.00154], [13.97489, 11.30258], [14.17821, 11.23831], [14.6124, 11.51283], [14.64591, 11.66166], [14.55207, 11.72001], [14.61612, 11.7798], [14.6474, 12.17466], [14.4843, 12.35223], [14.22215, 12.36533], [14.17523, 12.41916], [14.20204, 12.53405], [14.08251, 13.0797], [13.6302, 13.71094], [13.33213, 13.71195], [13.19844, 13.52802], [13.05085, 13.53984], [12.87376, 13.48919], [12.6793, 13.29157], [12.58033, 13.27805], [12.47095, 13.06673], [12.19315, 13.12423], [12.16189, 13.10056], [12.04209, 13.14452], [11.88236, 13.2527], [11.4535, 13.37773], [10.66004, 13.36422], [10.46731, 13.28819], [10.19993, 13.27129], [10.00373, 13.18171], [9.65995, 12.80614], [8.97413, 12.83661], [8.64251, 12.93985], [8.60431, 13.01768], [8.49493, 13.07519], [8.41853, 13.06166], [8.25185, 13.20369], [8.07997, 13.30847], [7.81085, 13.34902], [7.39241, 13.09717], [7.22399, 13.1293], [7.12676, 13.02445], [7.0521, 13.00076], [6.94445, 12.99825], [6.69617, 13.34057], [6.43053, 13.6006], [6.27411, 13.67835], [6.15771, 13.64564]]]] } },
23269 { type: "Feature", properties: { iso1A2: "NI", iso1A3: "NIC", iso1N3: "558", wikidata: "Q811", nameEn: "Nicaragua", groups: ["013", "003", "419", "019", "UN"], callingCodes: ["505"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-83.13724, 15.00002], [-83.49268, 15.01158], [-83.62101, 14.89448], [-83.89551, 14.76697], [-84.10584, 14.76353], [-84.48373, 14.63249], [-84.70119, 14.68078], [-84.82596, 14.82212], [-84.90082, 14.80489], [-85.1575, 14.53934], [-85.18602, 14.24929], [-85.32149, 14.2562], [-85.45762, 14.11304], [-85.73964, 13.9698], [-85.75477, 13.8499], [-86.03458, 13.99181], [-86.00685, 14.08474], [-86.14801, 14.04317], [-86.35219, 13.77157], [-86.76812, 13.79605], [-86.71267, 13.30348], [-86.87066, 13.30641], [-86.93383, 13.18677], [-86.93197, 13.05313], [-87.03785, 12.98682], [-87.06306, 13.00892], [-87.37107, 12.98646], [-87.55124, 13.12523], [-87.7346, 13.13228], [-88.11443, 12.63306], [-86.14524, 11.09059], [-85.71223, 11.06868], [-85.60529, 11.22607], [-84.92439, 10.9497], [-84.68197, 11.07568], [-83.90838, 10.71161], [-83.66597, 10.79916], [-83.68276, 11.01562], [-82.56142, 11.91792], [-82.06974, 14.49418], [-83.04763, 15.03256], [-83.13724, 15.00002]]]] } },
23270 { type: "Feature", properties: { iso1A2: "NL", iso1A3: "NLD", iso1N3: "528", wikidata: "Q29999", nameEn: "Kingdom of the Netherlands" }, geometry: null },
23271 { type: "Feature", properties: { iso1A2: "NO", iso1A3: "NOR", iso1N3: "578", wikidata: "Q20", nameEn: "Norway" }, geometry: null },
23272 { type: "Feature", properties: { iso1A2: "NP", iso1A3: "NPL", iso1N3: "524", wikidata: "Q837", nameEn: "Nepal", groups: ["034", "142", "UN"], driveSide: "left", callingCodes: ["977"] }, geometry: { type: "MultiPolygon", coordinates: [[[[88.13378, 27.88015], [87.82681, 27.95248], [87.72718, 27.80938], [87.56996, 27.84517], [87.11696, 27.84104], [87.03757, 27.94835], [86.75582, 28.04182], [86.74181, 28.10638], [86.56265, 28.09569], [86.51609, 27.96623], [86.42736, 27.91122], [86.22966, 27.9786], [86.18607, 28.17364], [86.088, 28.09264], [86.08333, 28.02121], [86.12069, 27.93047], [86.06309, 27.90021], [85.94946, 27.9401], [85.97813, 27.99023], [85.90743, 28.05144], [85.84672, 28.18187], [85.74864, 28.23126], [85.71907, 28.38064], [85.69105, 28.38475], [85.60854, 28.25045], [85.59765, 28.30529], [85.4233, 28.32996], [85.38127, 28.28336], [85.10729, 28.34092], [85.18668, 28.54076], [85.19135, 28.62825], [85.06059, 28.68562], [84.85511, 28.58041], [84.62317, 28.73887], [84.47528, 28.74023], [84.2231, 28.89571], [84.24801, 29.02783], [84.18107, 29.23451], [83.97559, 29.33091], [83.82303, 29.30513], [83.63156, 29.16249], [83.44787, 29.30513], [83.28131, 29.56813], [83.07116, 29.61957], [82.73024, 29.81695], [82.5341, 29.9735], [82.38622, 30.02608], [82.16984, 30.0692], [82.19475, 30.16884], [82.10757, 30.23745], [82.10135, 30.35439], [81.99082, 30.33423], [81.62033, 30.44703], [81.5459, 30.37688], [81.41018, 30.42153], [81.39928, 30.21862], [81.33355, 30.15303], [81.2623, 30.14596], [81.29032, 30.08806], [81.24362, 30.0126], [81.12842, 30.01395], [81.03953, 30.20059], [80.92547, 30.17193], [80.91143, 30.22173], [80.86673, 30.17321], [80.8778, 30.13384], [80.67076, 29.95732], [80.60226, 29.95732], [80.57179, 29.91422], [80.56247, 29.86661], [80.48997, 29.79566], [80.43458, 29.80466], [80.41554, 29.79451], [80.36803, 29.73865], [80.38428, 29.68513], [80.41858, 29.63581], [80.37939, 29.57098], [80.24322, 29.44299], [80.31428, 29.30784], [80.28626, 29.20327], [80.24112, 29.21414], [80.26602, 29.13938], [80.23178, 29.11626], [80.18085, 29.13649], [80.05743, 28.91479], [80.06957, 28.82763], [80.12125, 28.82346], [80.37188, 28.63371], [80.44504, 28.63098], [80.52443, 28.54897], [80.50575, 28.6706], [80.55142, 28.69182], [81.03471, 28.40054], [81.19847, 28.36284], [81.32923, 28.13521], [81.38683, 28.17638], [81.48179, 28.12148], [81.47867, 28.08303], [81.91223, 27.84995], [81.97214, 27.93322], [82.06554, 27.92222], [82.46405, 27.6716], [82.70378, 27.72122], [82.74119, 27.49838], [82.93261, 27.50328], [82.94938, 27.46036], [83.19413, 27.45632], [83.27197, 27.38309], [83.2673, 27.36235], [83.29999, 27.32778], [83.35136, 27.33885], [83.38872, 27.39276], [83.39495, 27.4798], [83.61288, 27.47013], [83.85595, 27.35797], [83.86182, 27.4241], [83.93306, 27.44939], [84.02229, 27.43836], [84.10791, 27.52399], [84.21376, 27.45218], [84.25735, 27.44941], [84.29315, 27.39], [84.62161, 27.33885], [84.69166, 27.21294], [84.64496, 27.04669], [84.793, 26.9968], [84.82913, 27.01989], [84.85754, 26.98984], [84.96687, 26.95599], [84.97186, 26.9149], [85.00536, 26.89523], [85.05592, 26.88991], [85.02635, 26.85381], [85.15883, 26.86966], [85.19291, 26.86909], [85.18046, 26.80519], [85.21159, 26.75933], [85.34302, 26.74954], [85.47752, 26.79292], [85.56471, 26.84133], [85.5757, 26.85955], [85.59461, 26.85161], [85.61621, 26.86721], [85.66239, 26.84822], [85.73483, 26.79613], [85.72315, 26.67471], [85.76907, 26.63076], [85.83126, 26.61134], [85.85126, 26.60866], [85.8492, 26.56667], [86.02729, 26.66756], [86.13596, 26.60651], [86.22513, 26.58863], [86.26235, 26.61886], [86.31564, 26.61925], [86.49726, 26.54218], [86.54258, 26.53819], [86.57073, 26.49825], [86.61313, 26.48658], [86.62686, 26.46891], [86.69124, 26.45169], [86.74025, 26.42386], [86.76797, 26.45892], [86.82898, 26.43919], [86.94543, 26.52076], [86.95912, 26.52076], [87.01559, 26.53228], [87.04691, 26.58685], [87.0707, 26.58571], [87.09147, 26.45039], [87.14751, 26.40542], [87.18863, 26.40558], [87.24682, 26.4143], [87.26587, 26.40592], [87.26568, 26.37294], [87.34568, 26.34787], [87.37314, 26.40815], [87.46566, 26.44058], [87.51571, 26.43106], [87.55274, 26.40596], [87.59175, 26.38342], [87.66803, 26.40294], [87.67893, 26.43501], [87.76004, 26.40711], [87.7918, 26.46737], [87.84193, 26.43663], [87.89085, 26.48565], [87.90115, 26.44923], [88.00895, 26.36029], [88.09414, 26.43732], [88.09963, 26.54195], [88.16452, 26.64111], [88.1659, 26.68177], [88.19107, 26.75516], [88.12302, 26.95324], [88.13422, 26.98705], [88.11719, 26.98758], [87.9887, 27.11045], [88.01587, 27.21388], [88.01646, 27.21612], [88.07277, 27.43007], [88.04008, 27.49223], [88.19107, 27.79285], [88.1973, 27.85067], [88.13378, 27.88015]]]] } },
23273 { type: "Feature", properties: { iso1A2: "NR", iso1A3: "NRU", iso1N3: "520", wikidata: "Q697", nameEn: "Nauru", groups: ["057", "009", "UN"], driveSide: "left", callingCodes: ["674"] }, geometry: { type: "MultiPolygon", coordinates: [[[[166.95155, 0.14829], [166.21778, -0.7977], [167.60042, -0.88259], [166.95155, 0.14829]]]] } },
23274 { type: "Feature", properties: { iso1A2: "NU", iso1A3: "NIU", iso1N3: "570", wikidata: "Q34020", nameEn: "Niue", country: "NZ", groups: ["061", "009", "UN"], driveSide: "left", callingCodes: ["683"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-170.83899, -18.53439], [-170.82274, -20.44429], [-168.63096, -18.60489], [-170.83899, -18.53439]]]] } },
23275 { type: "Feature", properties: { iso1A2: "NZ", iso1A3: "NZL", iso1N3: "554", wikidata: "Q664", nameEn: "New Zealand" }, geometry: null },
23276 { type: "Feature", properties: { iso1A2: "OM", iso1A3: "OMN", iso1N3: "512", wikidata: "Q842", nameEn: "Oman", groups: ["145", "142", "UN"], callingCodes: ["968"] }, geometry: { type: "MultiPolygon", coordinates: [[[[56.82555, 25.7713], [56.79239, 26.41236], [56.68954, 26.76645], [56.2644, 26.58649], [55.81777, 26.18798], [56.08666, 26.05038], [56.15498, 26.06828], [56.19334, 25.9795], [56.13963, 25.82765], [56.17416, 25.77239], [56.13579, 25.73524], [56.14826, 25.66351], [56.18363, 25.65508], [56.20473, 25.61119], [56.25365, 25.60211], [56.26636, 25.60643], [56.25341, 25.61443], [56.26534, 25.62825], [56.82555, 25.7713]]], [[[56.26062, 25.33108], [56.23362, 25.31253], [56.25008, 25.28843], [56.24465, 25.27505], [56.20838, 25.25668], [56.20872, 25.24104], [56.24341, 25.22867], [56.27628, 25.23404], [56.34438, 25.26653], [56.35172, 25.30681], [56.3111, 25.30107], [56.3005, 25.31815], [56.26062, 25.33108]], [[56.28423, 25.26344], [56.27086, 25.26128], [56.2716, 25.27916], [56.28102, 25.28486], [56.29379, 25.2754], [56.28423, 25.26344]]], [[[61.45114, 22.55394], [56.86325, 25.03856], [56.3227, 24.97284], [56.34873, 24.93205], [56.30269, 24.88334], [56.20568, 24.85063], [56.20062, 24.78565], [56.13684, 24.73699], [56.06128, 24.74457], [56.03535, 24.81161], [55.97836, 24.87673], [55.97467, 24.89639], [56.05106, 24.87461], [56.05715, 24.95727], [55.96316, 25.00857], [55.90849, 24.96771], [55.85094, 24.96858], [55.81116, 24.9116], [55.81348, 24.80102], [55.83408, 24.77858], [55.83271, 24.68567], [55.76461, 24.5287], [55.83271, 24.41521], [55.83395, 24.32776], [55.80747, 24.31069], [55.79145, 24.27914], [55.76781, 24.26209], [55.75939, 24.26114], [55.75382, 24.2466], [55.75257, 24.23466], [55.76558, 24.23227], [55.77658, 24.23476], [55.83367, 24.20193], [55.95472, 24.2172], [56.01799, 24.07426], [55.8308, 24.01633], [55.73301, 24.05994], [55.48677, 23.94946], [55.57358, 23.669], [55.22634, 23.10378], [55.2137, 22.71065], [55.66469, 21.99658], [54.99756, 20.00083], [52.00311, 19.00083], [52.78009, 17.35124], [52.74267, 17.29519], [52.81185, 17.28568], [57.49095, 8.14549], [61.45114, 22.55394]]]] } },
23277 { type: "Feature", properties: { iso1A2: "PA", iso1A3: "PAN", iso1N3: "591", wikidata: "Q804", nameEn: "Panama", groups: ["013", "003", "419", "019", "UN"], callingCodes: ["507"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-77.32389, 8.81247], [-77.58292, 9.22278], [-78.79327, 9.93766], [-82.51044, 9.65379], [-82.56507, 9.57279], [-82.61345, 9.49881], [-82.66667, 9.49746], [-82.77206, 9.59573], [-82.87919, 9.62645], [-82.84871, 9.4973], [-82.93516, 9.46741], [-82.93516, 9.07687], [-82.72126, 8.97125], [-82.88253, 8.83331], [-82.91377, 8.774], [-82.92068, 8.74832], [-82.8794, 8.6981], [-82.82739, 8.60153], [-82.83975, 8.54755], [-82.83322, 8.52464], [-82.8382, 8.48117], [-82.8679, 8.44042], [-82.93056, 8.43465], [-83.05209, 8.33394], [-82.9388, 8.26634], [-82.88641, 8.10219], [-82.89137, 8.05755], [-82.89978, 8.04083], [-82.94503, 7.93865], [-82.13751, 6.97312], [-78.06168, 7.07793], [-77.89178, 7.22681], [-77.81426, 7.48319], [-77.72157, 7.47612], [-77.72514, 7.72348], [-77.57185, 7.51147], [-77.17257, 7.97422], [-77.45064, 8.49991], [-77.32389, 8.81247]]]] } },
23278 { type: "Feature", properties: { iso1A2: "PE", iso1A3: "PER", iso1N3: "604", wikidata: "Q419", nameEn: "Peru", groups: ["005", "419", "019", "UN"], callingCodes: ["51"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-74.26675, -0.97229], [-74.42701, -0.50218], [-75.18513, -0.0308], [-75.25764, -0.11943], [-75.40192, -0.17196], [-75.61997, -0.10012], [-75.60169, -0.18708], [-75.53615, -0.19213], [-75.22862, -0.60048], [-75.22862, -0.95588], [-75.3872, -0.9374], [-75.57429, -1.55961], [-76.05203, -2.12179], [-76.6324, -2.58397], [-77.94147, -3.05454], [-78.19369, -3.36431], [-78.14324, -3.47653], [-78.22642, -3.51113], [-78.24589, -3.39907], [-78.34362, -3.38633], [-78.68394, -4.60754], [-78.85149, -4.66795], [-79.01659, -5.01481], [-79.1162, -4.97774], [-79.26248, -4.95167], [-79.59402, -4.46848], [-79.79722, -4.47558], [-80.13945, -4.29786], [-80.39256, -4.48269], [-80.46386, -4.41516], [-80.32114, -4.21323], [-80.45023, -4.20938], [-80.4822, -4.05477], [-80.46386, -4.01342], [-80.13232, -3.90317], [-80.19926, -3.68894], [-80.18741, -3.63994], [-80.19848, -3.59249], [-80.21642, -3.5888], [-80.20535, -3.51667], [-80.22629, -3.501], [-80.23651, -3.48652], [-80.24586, -3.48677], [-80.24123, -3.46124], [-80.20647, -3.431], [-80.30602, -3.39149], [-84.52388, -3.36941], [-85.71054, -21.15413], [-70.59118, -18.35072], [-70.378, -18.3495], [-70.31267, -18.31258], [-70.16394, -18.31737], [-69.96732, -18.25992], [-69.81607, -18.12582], [-69.75305, -17.94605], [-69.82868, -17.72048], [-69.79087, -17.65563], [-69.66483, -17.65083], [-69.46897, -17.4988], [-69.46863, -17.37466], [-69.62883, -17.28142], [-69.16896, -16.72233], [-69.00853, -16.66769], [-69.04027, -16.57214], [-68.98358, -16.42165], [-68.79464, -16.33272], [-68.96238, -16.194], [-69.09986, -16.22693], [-69.20291, -16.16668], [-69.40336, -15.61358], [-69.14856, -15.23478], [-69.36254, -14.94634], [-68.88135, -14.18639], [-69.05265, -13.68546], [-68.8864, -13.40792], [-68.85615, -12.87769], [-68.65044, -12.50689], [-68.98115, -11.8979], [-69.57156, -10.94555], [-69.57835, -10.94051], [-69.90896, -10.92744], [-70.38791, -11.07096], [-70.51395, -10.92249], [-70.64134, -11.0108], [-70.62487, -9.80666], [-70.55429, -9.76692], [-70.58453, -9.58303], [-70.53373, -9.42628], [-71.23394, -9.9668], [-72.14742, -9.98049], [-72.31883, -9.5184], [-72.72216, -9.41397], [-73.21498, -9.40904], [-72.92886, -9.04074], [-73.76576, -7.89884], [-73.65485, -7.77897], [-73.96938, -7.58465], [-73.77011, -7.28944], [-73.73986, -6.87919], [-73.12983, -6.43852], [-73.24579, -6.05764], [-72.83973, -5.14765], [-72.64391, -5.0391], [-71.87003, -4.51661], [-70.96814, -4.36915], [-70.77601, -4.15717], [-70.33236, -4.15214], [-70.19582, -4.3607], [-70.11305, -4.27281], [-70.00888, -4.37833], [-69.94708, -4.2431], [-70.3374, -3.79505], [-70.52393, -3.87553], [-70.71396, -3.7921], [-70.04609, -2.73906], [-70.94377, -2.23142], [-71.75223, -2.15058], [-72.92587, -2.44514], [-73.65312, -1.26222], [-74.26675, -0.97229]]]] } },
23279 { type: "Feature", properties: { iso1A2: "PF", iso1A3: "PYF", iso1N3: "258", wikidata: "Q30971", nameEn: "French Polynesia", country: "FR", groups: ["EU", "Q1451600", "061", "009", "UN"], callingCodes: ["689"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-135.59706, -4.70473], [-156.48634, -15.52824], [-156.45576, -31.75456], [-133.59543, -28.4709], [-135.59706, -4.70473]]]] } },
23280 { type: "Feature", properties: { iso1A2: "PG", iso1A3: "PNG", iso1N3: "598", wikidata: "Q691", nameEn: "Papua New Guinea", groups: ["054", "009", "UN"], driveSide: "left", callingCodes: ["675"] }, geometry: { type: "MultiPolygon", coordinates: [[[[141.03157, 2.12829], [140.99813, -6.3233], [140.85295, -6.72996], [140.90448, -6.85033], [141.01763, -6.90181], [141.01842, -9.35091], [141.88934, -9.36111], [142.19246, -9.15378], [142.48658, -9.36754], [143.29772, -9.33993], [143.87386, -9.02382], [145.2855, -9.62524], [156.73836, -14.50464], [154.74815, -7.33315], [155.60735, -6.92266], [155.69784, -6.92661], [155.92557, -6.84664], [156.03993, -6.65703], [156.03296, -6.55528], [160.43769, -4.17974], [141.03157, 2.12829]]]] } },
23281 { type: "Feature", properties: { iso1A2: "PH", iso1A3: "PHL", iso1N3: "608", wikidata: "Q928", nameEn: "Philippines", aliases: ["PI", "RP"], groups: ["035", "142", "UN"], callingCodes: ["63"] }, geometry: { type: "MultiPolygon", coordinates: [[[[129.19694, 7.84182], [121.8109, 21.77688], [120.69238, 21.52331], [118.82252, 14.67191], [115.39742, 10.92666], [116.79524, 7.43869], [117.17735, 7.52841], [117.93857, 6.89845], [117.98544, 6.27477], [119.52945, 5.35672], [118.93936, 4.09009], [118.06469, 4.16638], [121.14448, 2.12444], [129.19694, 7.84182]]]] } },
23282 { type: "Feature", properties: { iso1A2: "PK", iso1A3: "PAK", iso1N3: "586", wikidata: "Q843", nameEn: "Pakistan", groups: ["034", "142", "UN"], driveSide: "left", callingCodes: ["92"] }, geometry: { type: "MultiPolygon", coordinates: [[[[75.72737, 36.7529], [75.45562, 36.71971], [75.40481, 36.95382], [75.13839, 37.02622], [74.56453, 37.03023], [74.53739, 36.96224], [74.43389, 37.00977], [74.04856, 36.82648], [73.82685, 36.91421], [72.6323, 36.84601], [72.18135, 36.71838], [71.80267, 36.49924], [71.60491, 36.39429], [71.19505, 36.04134], [71.37969, 35.95865], [71.55273, 35.71483], [71.49917, 35.6267], [71.65435, 35.4479], [71.54294, 35.31037], [71.5541, 35.28776], [71.67495, 35.21262], [71.52938, 35.09023], [71.55273, 35.02615], [71.49917, 35.00478], [71.50329, 34.97328], [71.29472, 34.87728], [71.28356, 34.80882], [71.08718, 34.69034], [71.11602, 34.63047], [71.0089, 34.54568], [71.02401, 34.44835], [71.17662, 34.36769], [71.12815, 34.26619], [71.13078, 34.16503], [71.09453, 34.13524], [71.09307, 34.11961], [71.06933, 34.10564], [71.07345, 34.06242], [70.88119, 33.97933], [70.54336, 33.9463], [69.90203, 34.04194], [69.87307, 33.9689], [69.85671, 33.93719], [70.00503, 33.73528], [70.14236, 33.71701], [70.14785, 33.6553], [70.20141, 33.64387], [70.17062, 33.53535], [70.32775, 33.34496], [70.13686, 33.21064], [70.07369, 33.22557], [70.02563, 33.14282], [69.85259, 33.09451], [69.79766, 33.13247], [69.71526, 33.09911], [69.57656, 33.09911], [69.49004, 33.01509], [69.49854, 32.88843], [69.5436, 32.8768], [69.47082, 32.85834], [69.38018, 32.76601], [69.43649, 32.7302], [69.44747, 32.6678], [69.38155, 32.56601], [69.2868, 32.53938], [69.23599, 32.45946], [69.27932, 32.29119], [69.27032, 32.14141], [69.3225, 31.93186], [69.20577, 31.85957], [69.11514, 31.70782], [69.00939, 31.62249], [68.95995, 31.64822], [68.91078, 31.59687], [68.79997, 31.61665], [68.6956, 31.75687], [68.57475, 31.83158], [68.44222, 31.76446], [68.27605, 31.75863], [68.25614, 31.80357], [68.1655, 31.82691], [68.00071, 31.6564], [67.86887, 31.63536], [67.72056, 31.52304], [67.58323, 31.52772], [67.62374, 31.40473], [67.7748, 31.4188], [67.78854, 31.33203], [67.29964, 31.19586], [67.03323, 31.24519], [67.04147, 31.31561], [66.83273, 31.26867], [66.72561, 31.20526], [66.68166, 31.07597], [66.58175, 30.97532], [66.42645, 30.95309], [66.39194, 30.9408], [66.28413, 30.57001], [66.34869, 30.404], [66.23609, 30.06321], [66.36042, 29.9583], [66.24175, 29.85181], [65.04005, 29.53957], [64.62116, 29.58903], [64.19796, 29.50407], [64.12966, 29.39157], [63.5876, 29.50456], [62.47751, 29.40782], [60.87231, 29.86514], [61.31508, 29.38903], [61.53765, 29.00507], [61.65978, 28.77937], [61.93581, 28.55284], [62.40259, 28.42703], [62.59499, 28.24842], [62.79412, 28.28108], [62.7638, 28.02992], [62.84905, 27.47627], [62.79684, 27.34381], [62.80604, 27.22412], [63.19649, 27.25674], [63.32283, 27.14437], [63.25005, 27.08692], [63.25005, 26.84212], [63.18688, 26.83844], [63.1889, 26.65072], [62.77352, 26.64099], [62.31484, 26.528], [62.21304, 26.26601], [62.05117, 26.31647], [61.89391, 26.26251], [61.83831, 26.07249], [61.83968, 25.7538], [61.683, 25.66638], [61.6433, 25.27541], [61.46682, 24.57869], [68.11329, 23.53945], [68.20763, 23.85849], [68.39339, 23.96838], [68.74643, 23.97027], [68.7416, 24.31904], [68.90914, 24.33156], [68.97781, 24.26021], [69.07806, 24.29777], [69.19341, 24.25646], [69.29778, 24.28712], [69.59579, 24.29777], [69.73335, 24.17007], [70.03428, 24.172], [70.11712, 24.30915], [70.5667, 24.43787], [70.57906, 24.27774], [70.71502, 24.23517], [70.88393, 24.27398], [70.85784, 24.30903], [70.94985, 24.3791], [71.04461, 24.34657], [71.12838, 24.42662], [71.00341, 24.46038], [70.97594, 24.60904], [71.09405, 24.69017], [70.94002, 24.92843], [70.89148, 25.15064], [70.66695, 25.39314], [70.67382, 25.68186], [70.60378, 25.71898], [70.53649, 25.68928], [70.37444, 25.67443], [70.2687, 25.71156], [70.0985, 25.93238], [70.08193, 26.08094], [70.17532, 26.24118], [70.17532, 26.55362], [70.05584, 26.60398], [69.88555, 26.56836], [69.50904, 26.74892], [69.58519, 27.18109], [70.03136, 27.56627], [70.12502, 27.8057], [70.37307, 28.01208], [70.60927, 28.02178], [70.79054, 27.68423], [71.89921, 27.96035], [71.9244, 28.11555], [72.20329, 28.3869], [72.29495, 28.66367], [72.40402, 28.78283], [72.94272, 29.02487], [73.01337, 29.16422], [73.05886, 29.1878], [73.28094, 29.56646], [73.3962, 29.94707], [73.58665, 30.01848], [73.80299, 30.06969], [73.97225, 30.19829], [73.95736, 30.28466], [73.88993, 30.36305], [74.5616, 31.04153], [74.67971, 31.05479], [74.6852, 31.12771], [74.60006, 31.13711], [74.60281, 31.10419], [74.56023, 31.08303], [74.51629, 31.13829], [74.53223, 31.30321], [74.59773, 31.4136], [74.64713, 31.45605], [74.59319, 31.50197], [74.61517, 31.55698], [74.57498, 31.60382], [74.47771, 31.72227], [74.58907, 31.87824], [74.79919, 31.95983], [74.86236, 32.04485], [74.9269, 32.0658], [75.00793, 32.03786], [75.25649, 32.10187], [75.38046, 32.26836], [75.28259, 32.36556], [75.03265, 32.49538], [74.97634, 32.45367], [74.84725, 32.49075], [74.68362, 32.49298], [74.67431, 32.56676], [74.65251, 32.56416], [74.64424, 32.60985], [74.69542, 32.66792], [74.65345, 32.71225], [74.7113, 32.84219], [74.64675, 32.82604], [74.6289, 32.75561], [74.45312, 32.77755], [74.41467, 32.90563], [74.31227, 32.92795], [74.34875, 32.97823], [74.31854, 33.02891], [74.17571, 33.07495], [74.15374, 33.13477], [74.02144, 33.18908], [74.01366, 33.25199], [74.08782, 33.26232], [74.17983, 33.3679], [74.18121, 33.4745], [74.10115, 33.56392], [74.03576, 33.56718], [73.97367, 33.64061], [73.98968, 33.66155], [73.96423, 33.73071], [74.00891, 33.75437], [74.05898, 33.82089], [74.14001, 33.83002], [74.26086, 33.92237], [74.25262, 34.01577], [74.21554, 34.03853], [73.91341, 34.01235], [73.88732, 34.05105], [73.90677, 34.10504], [73.98208, 34.2522], [73.90517, 34.35317], [73.8475, 34.32935], [73.74862, 34.34183], [73.74999, 34.3781], [73.88732, 34.48911], [73.89419, 34.54568], [73.93951, 34.57169], [73.93401, 34.63386], [73.96423, 34.68244], [74.12897, 34.70073], [74.31239, 34.79626], [74.58083, 34.77386], [74.6663, 34.703], [75.01479, 34.64629], [75.38009, 34.55021], [75.75438, 34.51827], [76.04614, 34.67566], [76.15463, 34.6429], [76.47186, 34.78965], [76.67648, 34.76371], [76.74377, 34.84039], [76.74514, 34.92488], [76.87193, 34.96906], [76.99251, 34.93349], [77.11796, 35.05419], [76.93465, 35.39866], [76.85088, 35.39754], [76.75475, 35.52617], [76.77323, 35.66062], [76.50961, 35.8908], [76.33453, 35.84296], [76.14913, 35.82848], [76.15325, 35.9264], [75.93028, 36.13136], [76.00906, 36.17511], [76.0324, 36.41198], [75.92391, 36.56986], [75.72737, 36.7529]]]] } },
23283 { type: "Feature", properties: { iso1A2: "PL", iso1A3: "POL", iso1N3: "616", wikidata: "Q36", nameEn: "Poland", groups: ["EU", "151", "150", "UN"], callingCodes: ["48"] }, geometry: { type: "MultiPolygon", coordinates: [[[[18.57853, 55.25302], [14.20811, 54.12784], [14.22634, 53.9291], [14.20647, 53.91671], [14.18544, 53.91258], [14.20823, 53.90776], [14.21323, 53.8664], [14.27249, 53.74464], [14.26782, 53.69866], [14.2836, 53.67721], [14.27133, 53.66613], [14.28477, 53.65955], [14.2853, 53.63392], [14.31904, 53.61581], [14.30416, 53.55499], [14.3273, 53.50587], [14.35209, 53.49506], [14.4215, 53.27724], [14.44133, 53.27427], [14.45125, 53.26241], [14.40662, 53.21098], [14.37853, 53.20405], [14.36696, 53.16444], [14.38679, 53.13669], [14.35044, 53.05829], [14.25954, 53.00264], [14.14056, 52.95786], [14.15873, 52.87715], [14.12256, 52.84311], [14.13806, 52.82392], [14.22071, 52.81175], [14.61073, 52.59847], [14.6289, 52.57136], [14.60081, 52.53116], [14.63056, 52.48993], [14.54423, 52.42568], [14.55228, 52.35264], [14.56378, 52.33838], [14.58149, 52.28007], [14.70139, 52.25038], [14.71319, 52.22144], [14.68344, 52.19612], [14.70616, 52.16927], [14.67683, 52.13936], [14.6917, 52.10283], [14.72971, 52.09167], [14.76026, 52.06624], [14.71339, 52.00337], [14.70488, 51.97679], [14.7139, 51.95643], [14.71836, 51.95606], [14.72163, 51.95188], [14.7177, 51.94048], [14.70601, 51.92944], [14.6933, 51.9044], [14.6588, 51.88359], [14.59089, 51.83302], [14.60493, 51.80473], [14.64625, 51.79472], [14.66386, 51.73282], [14.69065, 51.70842], [14.75392, 51.67445], [14.75759, 51.62318], [14.7727, 51.61263], [14.71125, 51.56209], [14.73047, 51.54606], [14.72652, 51.53902], [14.73219, 51.52922], [14.94749, 51.47155], [14.9652, 51.44793], [14.96899, 51.38367], [14.98008, 51.33449], [15.04288, 51.28387], [15.01242, 51.21285], [15.0047, 51.16874], [14.99311, 51.16249], [14.99414, 51.15813], [15.00083, 51.14974], [14.99646, 51.14365], [14.99079, 51.14284], [14.99689, 51.12205], [14.98229, 51.11354], [14.97938, 51.07742], [14.95529, 51.04552], [14.92942, 50.99744], [14.89252, 50.94999], [14.89681, 50.9422], [14.81664, 50.88148], [14.82803, 50.86966], [14.99852, 50.86817], [15.01088, 50.97984], [14.96419, 50.99108], [15.02433, 51.0242], [15.03895, 51.0123], [15.06218, 51.02269], [15.10152, 51.01095], [15.11937, 50.99021], [15.16744, 51.01959], [15.1743, 50.9833], [15.2361, 50.99886], [15.27043, 50.97724], [15.2773, 50.8907], [15.36656, 50.83956], [15.3803, 50.77187], [15.43798, 50.80833], [15.73186, 50.73885], [15.81683, 50.75666], [15.87331, 50.67188], [15.97219, 50.69799], [16.0175, 50.63009], [15.98317, 50.61528], [16.02437, 50.60046], [16.10265, 50.66405], [16.20839, 50.63096], [16.23174, 50.67101], [16.33611, 50.66579], [16.44597, 50.58041], [16.34572, 50.49575], [16.31413, 50.50274], [16.19526, 50.43291], [16.21585, 50.40627], [16.22821, 50.41054], [16.28118, 50.36891], [16.30289, 50.38292], [16.36495, 50.37679], [16.3622, 50.34875], [16.39379, 50.3207], [16.42674, 50.32509], [16.56407, 50.21009], [16.55446, 50.16613], [16.63137, 50.1142], [16.7014, 50.09659], [16.8456, 50.20834], [16.98018, 50.24172], [17.00353, 50.21449], [17.02825, 50.23118], [16.99803, 50.25753], [17.02138, 50.27772], [16.99803, 50.30316], [16.94448, 50.31281], [16.90877, 50.38642], [16.85933, 50.41093], [16.89229, 50.45117], [17.1224, 50.39494], [17.14498, 50.38117], [17.19579, 50.38817], [17.19991, 50.3654], [17.27681, 50.32246], [17.34273, 50.32947], [17.34548, 50.2628], [17.3702, 50.28123], [17.58889, 50.27837], [17.67764, 50.28977], [17.69292, 50.32859], [17.74648, 50.29966], [17.72176, 50.25665], [17.76296, 50.23382], [17.70528, 50.18812], [17.59404, 50.16437], [17.66683, 50.10275], [17.6888, 50.12037], [17.7506, 50.07896], [17.77669, 50.02253], [17.86886, 49.97452], [18.00191, 50.01723], [18.04585, 50.01194], [18.04585, 50.03311], [18.00396, 50.04954], [18.03212, 50.06574], [18.07898, 50.04535], [18.10628, 50.00223], [18.20241, 49.99958], [18.21752, 49.97309], [18.27107, 49.96779], [18.27794, 49.93863], [18.31914, 49.91565], [18.33278, 49.92415], [18.33562, 49.94747], [18.41604, 49.93498], [18.53423, 49.89906], [18.54495, 49.9079], [18.54299, 49.92537], [18.57697, 49.91565], [18.57045, 49.87849], [18.60341, 49.86256], [18.57183, 49.83334], [18.61278, 49.7618], [18.61368, 49.75426], [18.62645, 49.75002], [18.62943, 49.74603], [18.62676, 49.71983], [18.69817, 49.70473], [18.72838, 49.68163], [18.80479, 49.6815], [18.84786, 49.5446], [18.84521, 49.51672], [18.94536, 49.52143], [18.97283, 49.49914], [18.9742, 49.39557], [19.18019, 49.41165], [19.25435, 49.53391], [19.36009, 49.53747], [19.37795, 49.574], [19.45348, 49.61583], [19.52626, 49.57311], [19.53313, 49.52856], [19.57845, 49.46077], [19.64162, 49.45184], [19.6375, 49.40897], [19.72127, 49.39288], [19.78581, 49.41701], [19.82237, 49.27806], [19.75286, 49.20751], [19.86409, 49.19316], [19.90529, 49.23532], [19.98494, 49.22904], [20.08238, 49.1813], [20.13738, 49.31685], [20.21977, 49.35265], [20.31453, 49.34817], [20.31728, 49.39914], [20.39939, 49.3896], [20.46422, 49.41612], [20.5631, 49.375], [20.61666, 49.41791], [20.72274, 49.41813], [20.77971, 49.35383], [20.9229, 49.29626], [20.98733, 49.30774], [21.09799, 49.37176], [21.041, 49.41791], [21.12477, 49.43666], [21.19756, 49.4054], [21.27858, 49.45988], [21.43376, 49.41433], [21.62328, 49.4447], [21.77983, 49.35443], [21.82927, 49.39467], [21.96385, 49.3437], [22.04427, 49.22136], [22.56155, 49.08865], [22.89122, 49.00725], [22.86336, 49.10513], [22.72009, 49.20288], [22.748, 49.32759], [22.69444, 49.49378], [22.64534, 49.53094], [22.78304, 49.65543], [22.80261, 49.69098], [22.83179, 49.69875], [22.99329, 49.84249], [23.28221, 50.0957], [23.67635, 50.33385], [23.71382, 50.38248], [23.79445, 50.40481], [23.99563, 50.41289], [24.03668, 50.44507], [24.07048, 50.5071], [24.0996, 50.60752], [24.0595, 50.71625], [23.95925, 50.79271], [23.99254, 50.83847], [24.0952, 50.83262], [24.14524, 50.86128], [24.04576, 50.90196], [23.92217, 51.00836], [23.90376, 51.07697], [23.80678, 51.18405], [23.63858, 51.32182], [23.69905, 51.40871], [23.62751, 51.50512], [23.56236, 51.53673], [23.57053, 51.55938], [23.53198, 51.74298], [23.62691, 51.78208], [23.61523, 51.92066], [23.68733, 51.9906], [23.64066, 52.07626], [23.61, 52.11264], [23.54314, 52.12148], [23.47859, 52.18215], [23.20071, 52.22848], [23.18196, 52.28812], [23.34141, 52.44845], [23.45112, 52.53774], [23.58296, 52.59868], [23.73615, 52.6149], [23.93763, 52.71332], [23.91805, 52.94016], [23.94689, 52.95919], [23.92184, 53.02079], [23.87548, 53.0831], [23.91393, 53.16469], [23.85657, 53.22923], [23.81995, 53.24131], [23.62004, 53.60942], [23.51284, 53.95052], [23.48261, 53.98855], [23.52702, 54.04622], [23.49196, 54.14764], [23.45223, 54.17775], [23.42418, 54.17911], [23.39525, 54.21672], [23.3494, 54.25155], [23.24656, 54.25701], [23.15938, 54.29894], [23.15526, 54.31076], [23.13905, 54.31567], [23.104, 54.29794], [23.04323, 54.31567], [23.05726, 54.34565], [22.99649, 54.35927], [23.00584, 54.38514], [22.83756, 54.40827], [22.79705, 54.36264], [21.41123, 54.32395], [20.63871, 54.3706], [19.8038, 54.44203], [19.64312, 54.45423], [18.57853, 55.25302]]]] } },
23284 { type: "Feature", properties: { iso1A2: "PM", iso1A3: "SPM", iso1N3: "666", wikidata: "Q34617", nameEn: "Saint Pierre and Miquelon", country: "FR", groups: ["EU", "Q1451600", "021", "003", "019", "UN"], callingCodes: ["508"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-56.72993, 46.65575], [-55.90758, 46.6223], [-56.27503, 47.39728], [-56.72993, 46.65575]]]] } },
23285 { type: "Feature", properties: { iso1A2: "PN", iso1A3: "PCN", iso1N3: "612", wikidata: "Q35672", nameEn: "Pitcairn Islands", country: "GB", groups: ["BOTS", "061", "009", "UN"], driveSide: "left", callingCodes: ["64"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-133.59543, -28.4709], [-122.0366, -24.55017], [-133.61511, -21.93325], [-133.59543, -28.4709]]]] } },
23286 { type: "Feature", properties: { iso1A2: "PR", iso1A3: "PRI", iso1N3: "630", wikidata: "Q1183", nameEn: "Puerto Rico", aliases: ["US-PR"], country: "US", groups: ["Q1352230", "029", "003", "419", "019", "UN"], roadSpeedUnit: "mph", callingCodes: ["1 787", "1 939"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-65.27974, 17.56928], [-65.02435, 18.73231], [-67.99519, 18.97186], [-68.23894, 17.84663], [-65.27974, 17.56928]]]] } },
23287 { type: "Feature", properties: { iso1A2: "PS", iso1A3: "PSE", iso1N3: "275", wikidata: "Q219060", nameEn: "Palestine" }, geometry: null },
23288 { type: "Feature", properties: { iso1A2: "PT", iso1A3: "PRT", iso1N3: "620", wikidata: "Q45", nameEn: "Portugal" }, geometry: null },
23289 { type: "Feature", properties: { iso1A2: "PW", iso1A3: "PLW", iso1N3: "585", wikidata: "Q695", nameEn: "Palau", groups: ["057", "009", "UN"], roadSpeedUnit: "mph", callingCodes: ["680"] }, geometry: { type: "MultiPolygon", coordinates: [[[[128.97621, 3.08804], [136.39296, 1.54187], [136.04605, 12.45908], [128.97621, 3.08804]]]] } },
23290 { type: "Feature", properties: { iso1A2: "PY", iso1A3: "PRY", iso1N3: "600", wikidata: "Q733", nameEn: "Paraguay", groups: ["005", "419", "019", "UN"], callingCodes: ["595"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-58.16225, -20.16193], [-58.23216, -19.80058], [-59.06965, -19.29148], [-60.00638, -19.2981], [-61.73723, -19.63958], [-61.93912, -20.10053], [-62.26883, -20.55311], [-62.2757, -21.06657], [-62.64455, -22.25091], [-62.51761, -22.37684], [-62.22768, -22.55807], [-61.9756, -23.0507], [-61.0782, -23.62932], [-60.99754, -23.80934], [-60.28163, -24.04436], [-60.03367, -24.00701], [-59.45482, -24.34787], [-59.33886, -24.49935], [-58.33055, -24.97099], [-58.25492, -24.92528], [-57.80821, -25.13863], [-57.57431, -25.47269], [-57.87176, -25.93604], [-58.1188, -26.16704], [-58.3198, -26.83443], [-58.65321, -27.14028], [-58.59549, -27.29973], [-58.04205, -27.2387], [-56.85337, -27.5165], [-56.18313, -27.29851], [-55.89195, -27.3467], [-55.74475, -27.44485], [-55.59094, -27.32444], [-55.62322, -27.1941], [-55.39611, -26.97679], [-55.25243, -26.93808], [-55.16948, -26.96068], [-55.06351, -26.80195], [-55.00584, -26.78754], [-54.80868, -26.55669], [-54.70732, -26.45099], [-54.69333, -26.37705], [-54.67359, -25.98607], [-54.60664, -25.9691], [-54.62063, -25.91213], [-54.59398, -25.59224], [-54.59509, -25.53696], [-54.60196, -25.48397], [-54.62033, -25.46026], [-54.4423, -25.13381], [-54.28207, -24.07305], [-54.32807, -24.01865], [-54.6238, -23.83078], [-55.02691, -23.97317], [-55.0518, -23.98666], [-55.12292, -23.99669], [-55.41784, -23.9657], [-55.44117, -23.9185], [-55.43585, -23.87157], [-55.5555, -23.28237], [-55.52288, -23.2595], [-55.5446, -23.22811], [-55.63849, -22.95122], [-55.62493, -22.62765], [-55.68742, -22.58407], [-55.6986, -22.56268], [-55.72366, -22.5519], [-55.741, -22.52018], [-55.74941, -22.46436], [-55.8331, -22.29008], [-56.23206, -22.25347], [-56.45893, -22.08072], [-56.5212, -22.11556], [-56.6508, -22.28387], [-57.98625, -22.09157], [-57.94642, -21.73799], [-57.88239, -21.6868], [-57.93492, -21.65505], [-57.84536, -20.93155], [-58.16225, -20.16193]]]] } },
23291 { type: "Feature", properties: { iso1A2: "QA", iso1A3: "QAT", iso1N3: "634", wikidata: "Q846", nameEn: "Qatar", groups: ["145", "142", "UN"], callingCodes: ["974"] }, geometry: { type: "MultiPolygon", coordinates: [[[[50.92992, 24.54396], [51.09638, 24.46907], [51.29972, 24.50747], [51.39468, 24.62785], [51.58834, 24.66608], [51.83108, 24.71675], [51.83682, 26.70231], [50.93865, 26.30758], [50.81266, 25.88946], [50.86149, 25.6965], [50.7801, 25.595], [50.80824, 25.54641], [50.57069, 25.57887], [50.8133, 24.74049], [50.92992, 24.54396]]]] } },
23292 { type: "Feature", properties: { iso1A2: "RE", iso1A3: "REU", iso1N3: "638", wikidata: "Q17070", nameEn: "R\xE9union", country: "FR", groups: ["Q3320166", "EU", "014", "202", "002", "UN"], callingCodes: ["262"] }, geometry: { type: "MultiPolygon", coordinates: [[[[53.37984, -21.23941], [56.73473, -21.9174], [56.62373, -20.2711], [53.37984, -21.23941]]]] } },
23293 { type: "Feature", properties: { iso1A2: "RO", iso1A3: "ROU", iso1N3: "642", wikidata: "Q218", nameEn: "Romania", groups: ["EU", "151", "150", "UN"], callingCodes: ["40"] }, geometry: { type: "MultiPolygon", coordinates: [[[[27.15622, 47.98538], [27.02985, 48.09083], [27.04118, 48.12522], [26.96119, 48.13003], [26.98042, 48.15752], [26.94265, 48.1969], [26.87708, 48.19919], [26.81161, 48.25049], [26.62823, 48.25804], [26.55202, 48.22445], [26.33504, 48.18418], [26.17711, 47.99246], [26.05901, 47.9897], [25.77723, 47.93919], [25.63878, 47.94924], [25.23778, 47.89403], [25.11144, 47.75203], [24.88896, 47.7234], [24.81893, 47.82031], [24.70632, 47.84428], [24.61994, 47.95062], [24.43578, 47.97131], [24.34926, 47.9244], [24.22566, 47.90231], [24.11281, 47.91487], [24.06466, 47.95317], [24.02999, 47.95087], [24.00801, 47.968], [23.98553, 47.96076], [23.96337, 47.96672], [23.94192, 47.94868], [23.89352, 47.94512], [23.8602, 47.9329], [23.80904, 47.98142], [23.75188, 47.99705], [23.66262, 47.98786], [23.63894, 48.00293], [23.5653, 48.00499], [23.52803, 48.01818], [23.4979, 47.96858], [23.33577, 48.0237], [23.27397, 48.08245], [23.15999, 48.12188], [23.1133, 48.08061], [23.08858, 48.00716], [23.0158, 47.99338], [22.92241, 48.02002], [22.94301, 47.96672], [22.89849, 47.95851], [22.77991, 47.87211], [22.76617, 47.8417], [22.67247, 47.7871], [22.46559, 47.76583], [22.41979, 47.7391], [22.31816, 47.76126], [22.00917, 47.50492], [22.03389, 47.42508], [22.01055, 47.37767], [21.94463, 47.38046], [21.78395, 47.11104], [21.648, 47.03902], [21.68645, 46.99595], [21.59581, 46.91628], [21.59307, 46.86935], [21.52028, 46.84118], [21.48935, 46.7577], [21.5151, 46.72147], [21.43926, 46.65109], [21.33214, 46.63035], [21.26929, 46.4993], [21.28061, 46.44941], [21.16872, 46.30118], [21.06572, 46.24897], [20.86797, 46.28884], [20.74574, 46.25467], [20.76085, 46.21002], [20.63863, 46.12728], [20.49718, 46.18721], [20.45377, 46.14405], [20.35573, 46.16629], [20.28324, 46.1438], [20.26068, 46.12332], [20.35862, 45.99356], [20.54818, 45.89939], [20.65645, 45.82801], [20.70069, 45.7493], [20.77416, 45.75601], [20.78446, 45.78522], [20.82364, 45.77738], [20.80361, 45.65875], [20.76798, 45.60969], [20.83321, 45.53567], [20.77217, 45.49788], [20.86026, 45.47295], [20.87948, 45.42743], [21.09894, 45.30144], [21.17612, 45.32566], [21.20392, 45.2677], [21.29398, 45.24148], [21.48278, 45.19557], [21.51299, 45.15345], [21.4505, 45.04294], [21.35855, 45.01941], [21.54938, 44.9327], [21.56328, 44.89502], [21.48202, 44.87199], [21.44013, 44.87613], [21.35643, 44.86364], [21.38802, 44.78133], [21.55007, 44.77304], [21.60019, 44.75208], [21.61942, 44.67059], [21.67504, 44.67107], [21.71692, 44.65349], [21.7795, 44.66165], [21.99364, 44.63395], [22.08016, 44.49844], [22.13234, 44.47444], [22.18315, 44.48179], [22.30844, 44.6619], [22.45301, 44.7194], [22.61917, 44.61489], [22.69196, 44.61587], [22.76749, 44.54446], [22.70981, 44.51852], [22.61368, 44.55719], [22.56493, 44.53419], [22.54021, 44.47836], [22.45436, 44.47258], [22.56012, 44.30712], [22.68166, 44.28206], [22.67173, 44.21564], [23.04988, 44.07694], [23.01674, 44.01946], [22.87873, 43.9844], [22.83753, 43.88055], [22.85314, 43.84452], [23.05288, 43.79494], [23.26772, 43.84843], [23.4507, 43.84936], [23.61687, 43.79289], [23.73978, 43.80627], [24.18149, 43.68218], [24.35364, 43.70211], [24.50264, 43.76314], [24.62281, 43.74082], [24.73542, 43.68523], [24.96682, 43.72693], [25.10718, 43.6831], [25.17144, 43.70261], [25.39528, 43.61866], [25.72792, 43.69263], [25.94911, 43.85745], [26.05584, 43.90925], [26.10115, 43.96908], [26.38764, 44.04356], [26.62712, 44.05698], [26.95141, 44.13555], [27.26845, 44.12602], [27.39757, 44.0141], [27.60834, 44.01206], [27.64542, 44.04958], [27.73468, 43.95326], [27.92008, 44.00761], [27.99558, 43.84193], [28.23293, 43.76], [29.24336, 43.70874], [30.04414, 45.08461], [29.69272, 45.19227], [29.65428, 45.25629], [29.68175, 45.26885], [29.59798, 45.38857], [29.42632, 45.44545], [29.24779, 45.43388], [28.96077, 45.33164], [28.94292, 45.28045], [28.81383, 45.3384], [28.78911, 45.24179], [28.71358, 45.22631], [28.5735, 45.24759], [28.34554, 45.32102], [28.28504, 45.43907], [28.21139, 45.46895], [28.18741, 45.47358], [28.08927, 45.6051], [28.16568, 45.6421], [28.13111, 45.92819], [28.08612, 46.01105], [28.13684, 46.18099], [28.10937, 46.22852], [28.19864, 46.31869], [28.18902, 46.35283], [28.25769, 46.43334], [28.22281, 46.50481], [28.24808, 46.64305], [28.12173, 46.82283], [28.09095, 46.97621], [27.81892, 47.1381], [27.73172, 47.29248], [27.68706, 47.28962], [27.60263, 47.32507], [27.55731, 47.46637], [27.47942, 47.48113], [27.3979, 47.59473], [27.32202, 47.64009], [27.25519, 47.71366], [27.29069, 47.73722], [27.1618, 47.92391], [27.15622, 47.98538]]]] } },
23294 { type: "Feature", properties: { iso1A2: "RS", iso1A3: "SRB", iso1N3: "688", wikidata: "Q403", nameEn: "Serbia", groups: ["039", "150", "UN"], callingCodes: ["381"] }, geometry: { type: "MultiPolygon", coordinates: [[[[19.66007, 46.19005], [19.56113, 46.16824], [19.52473, 46.1171], [19.28826, 45.99694], [19.14543, 45.9998], [19.10388, 46.04015], [19.0791, 45.96458], [19.01284, 45.96529], [18.99712, 45.93537], [18.81394, 45.91329], [18.85783, 45.85493], [18.90305, 45.71863], [18.96691, 45.66731], [18.88776, 45.57253], [18.94562, 45.53712], [19.07471, 45.53086], [19.08364, 45.48804], [18.99918, 45.49333], [18.97446, 45.37528], [19.10774, 45.29547], [19.28208, 45.23813], [19.41941, 45.23475], [19.43589, 45.17137], [19.19144, 45.17863], [19.14063, 45.12972], [19.07952, 45.14668], [19.1011, 45.01191], [19.05205, 44.97692], [19.15573, 44.95409], [19.06853, 44.89915], [19.02871, 44.92541], [18.98957, 44.90645], [19.01994, 44.85493], [19.18183, 44.92055], [19.36722, 44.88164], [19.32543, 44.74058], [19.26388, 44.65412], [19.16699, 44.52197], [19.13369, 44.52521], [19.12278, 44.50132], [19.14837, 44.45253], [19.14681, 44.41463], [19.11785, 44.40313], [19.10749, 44.39421], [19.10704, 44.38249], [19.10365, 44.37795], [19.10298, 44.36924], [19.11865, 44.36712], [19.1083, 44.3558], [19.11547, 44.34218], [19.13556, 44.338], [19.13332, 44.31492], [19.16741, 44.28648], [19.18328, 44.28383], [19.20508, 44.2917], [19.23306, 44.26097], [19.26945, 44.26957], [19.32464, 44.27185], [19.34773, 44.23244], [19.3588, 44.18353], [19.40927, 44.16722], [19.43905, 44.13088], [19.47338, 44.15034], [19.48386, 44.14332], [19.47321, 44.1193], [19.51167, 44.08158], [19.55999, 44.06894], [19.57467, 44.04716], [19.61991, 44.05254], [19.61836, 44.01464], [19.56498, 43.99922], [19.52515, 43.95573], [19.38439, 43.96611], [19.24363, 44.01502], [19.23465, 43.98764], [19.3986, 43.79668], [19.5176, 43.71403], [19.50455, 43.58385], [19.42696, 43.57987], [19.41941, 43.54056], [19.36653, 43.60921], [19.33426, 43.58833], [19.2553, 43.5938], [19.24774, 43.53061], [19.22807, 43.5264], [19.22229, 43.47926], [19.44315, 43.38846], [19.48171, 43.32644], [19.52962, 43.31623], [19.54598, 43.25158], [19.62661, 43.2286], [19.64063, 43.19027], [19.76918, 43.16044], [19.79255, 43.11951], [19.92576, 43.08539], [19.96549, 43.11098], [19.98887, 43.0538], [20.04729, 43.02732], [20.05431, 42.99571], [20.12325, 42.96237], [20.14896, 42.99058], [20.16415, 42.97177], [20.34528, 42.90676], [20.35692, 42.8335], [20.40594, 42.84853], [20.43734, 42.83157], [20.53484, 42.8885], [20.48692, 42.93208], [20.59929, 43.01067], [20.64557, 43.00826], [20.69515, 43.09641], [20.59929, 43.20492], [20.68688, 43.21335], [20.73811, 43.25068], [20.82145, 43.26769], [20.88685, 43.21697], [20.83727, 43.17842], [20.96287, 43.12416], [21.00749, 43.13984], [21.05378, 43.10707], [21.08952, 43.13471], [21.14465, 43.11089], [21.16734, 42.99694], [21.2041, 43.02277], [21.23877, 43.00848], [21.23534, 42.95523], [21.2719, 42.8994], [21.32974, 42.90424], [21.36941, 42.87397], [21.44047, 42.87276], [21.39045, 42.74888], [21.47498, 42.74695], [21.59154, 42.72643], [21.58755, 42.70418], [21.6626, 42.67813], [21.75025, 42.70125], [21.79413, 42.65923], [21.75672, 42.62695], [21.7327, 42.55041], [21.70522, 42.54176], [21.7035, 42.51899], [21.62556, 42.45106], [21.64209, 42.41081], [21.62887, 42.37664], [21.59029, 42.38042], [21.57021, 42.3647], [21.53467, 42.36809], [21.5264, 42.33634], [21.56772, 42.30946], [21.58992, 42.25915], [21.70111, 42.23789], [21.77176, 42.2648], [21.84654, 42.3247], [21.91595, 42.30392], [21.94405, 42.34669], [22.02908, 42.29848], [22.16384, 42.32103], [22.29605, 42.37477], [22.29275, 42.34913], [22.34773, 42.31725], [22.45919, 42.33822], [22.47498, 42.3915], [22.51961, 42.3991], [22.55669, 42.50144], [22.43983, 42.56851], [22.4997, 42.74144], [22.43309, 42.82057], [22.54302, 42.87774], [22.74826, 42.88701], [22.78397, 42.98253], [22.89521, 43.03625], [22.98104, 43.11199], [23.00806, 43.19279], [22.89727, 43.22417], [22.82036, 43.33665], [22.53397, 43.47225], [22.47582, 43.6558], [22.41043, 43.69566], [22.35558, 43.81281], [22.41449, 44.00514], [22.61688, 44.06534], [22.61711, 44.16938], [22.67173, 44.21564], [22.68166, 44.28206], [22.56012, 44.30712], [22.45436, 44.47258], [22.54021, 44.47836], [22.56493, 44.53419], [22.61368, 44.55719], [22.70981, 44.51852], [22.76749, 44.54446], [22.69196, 44.61587], [22.61917, 44.61489], [22.45301, 44.7194], [22.30844, 44.6619], [22.18315, 44.48179], [22.13234, 44.47444], [22.08016, 44.49844], [21.99364, 44.63395], [21.7795, 44.66165], [21.71692, 44.65349], [21.67504, 44.67107], [21.61942, 44.67059], [21.60019, 44.75208], [21.55007, 44.77304], [21.38802, 44.78133], [21.35643, 44.86364], [21.44013, 44.87613], [21.48202, 44.87199], [21.56328, 44.89502], [21.54938, 44.9327], [21.35855, 45.01941], [21.4505, 45.04294], [21.51299, 45.15345], [21.48278, 45.19557], [21.29398, 45.24148], [21.20392, 45.2677], [21.17612, 45.32566], [21.09894, 45.30144], [20.87948, 45.42743], [20.86026, 45.47295], [20.77217, 45.49788], [20.83321, 45.53567], [20.76798, 45.60969], [20.80361, 45.65875], [20.82364, 45.77738], [20.78446, 45.78522], [20.77416, 45.75601], [20.70069, 45.7493], [20.65645, 45.82801], [20.54818, 45.89939], [20.35862, 45.99356], [20.26068, 46.12332], [20.09713, 46.17315], [20.03533, 46.14509], [20.01816, 46.17696], [19.93508, 46.17553], [19.81491, 46.1313], [19.66007, 46.19005]]]] } },
23295 { type: "Feature", properties: { iso1A2: "RU", iso1A3: "RUS", iso1N3: "643", wikidata: "Q159", nameEn: "Russia" }, geometry: null },
23296 { type: "Feature", properties: { iso1A2: "RW", iso1A3: "RWA", iso1N3: "646", wikidata: "Q1037", nameEn: "Rwanda", groups: ["014", "202", "002", "UN"], callingCodes: ["250"] }, geometry: { type: "MultiPolygon", coordinates: [[[[30.47194, -1.0555], [30.35212, -1.06896], [30.16369, -1.34303], [29.912, -1.48269], [29.82657, -1.31187], [29.59061, -1.39016], [29.53062, -1.40499], [29.45038, -1.5054], [29.36322, -1.50887], [29.24323, -1.66826], [29.24458, -1.69663], [29.11847, -1.90576], [29.17562, -2.12278], [29.105, -2.27043], [29.00051, -2.29001], [28.95642, -2.37321], [28.89601, -2.37321], [28.86826, -2.41888], [28.86846, -2.44866], [28.89132, -2.47557], [28.89342, -2.49017], [28.88846, -2.50493], [28.87497, -2.50887], [28.86209, -2.5231], [28.86193, -2.53185], [28.87943, -2.55165], [28.89288, -2.55848], [28.90226, -2.62385], [28.89793, -2.66111], [28.94346, -2.69124], [29.00357, -2.70596], [29.04081, -2.7416], [29.0562, -2.58632], [29.32234, -2.6483], [29.36805, -2.82933], [29.88237, -2.75105], [29.95911, -2.33348], [30.14034, -2.43626], [30.42933, -2.31064], [30.54501, -2.41404], [30.83915, -2.35795], [30.89303, -2.08223], [30.80802, -1.91477], [30.84079, -1.64652], [30.71974, -1.43244], [30.57123, -1.33264], [30.50889, -1.16412], [30.45116, -1.10641], [30.47194, -1.0555]]]] } },
23297 { type: "Feature", properties: { iso1A2: "SA", iso1A3: "SAU", iso1N3: "682", wikidata: "Q851", nameEn: "Saudi Arabia", groups: ["145", "142", "UN"], callingCodes: ["966"] }, geometry: { type: "MultiPolygon", coordinates: [[[[40.01521, 32.05667], [39.29903, 32.23259], [38.99233, 31.99721], [36.99791, 31.50081], [37.99354, 30.49998], [37.66395, 30.33245], [37.4971, 29.99949], [36.75083, 29.86903], [36.50005, 29.49696], [36.07081, 29.18469], [34.8812, 29.36878], [34.4454, 27.91479], [37.8565, 22.00903], [39.63762, 18.37348], [40.99158, 15.81743], [42.15205, 16.40211], [42.76801, 16.40371], [42.94625, 16.39721], [42.94351, 16.49467], [42.97215, 16.51093], [43.11601, 16.53166], [43.15274, 16.67248], [43.22066, 16.65179], [43.21325, 16.74416], [43.25857, 16.75304], [43.26303, 16.79479], [43.24801, 16.80613], [43.22956, 16.80613], [43.22012, 16.83932], [43.18338, 16.84852], [43.1398, 16.90696], [43.19328, 16.94703], [43.1813, 16.98438], [43.18233, 17.02673], [43.23967, 17.03428], [43.17787, 17.14717], [43.20156, 17.25901], [43.32653, 17.31179], [43.22533, 17.38343], [43.29185, 17.53224], [43.43005, 17.56148], [43.70631, 17.35762], [44.50126, 17.47475], [46.31018, 17.20464], [46.76494, 17.29151], [47.00571, 16.94765], [47.48245, 17.10808], [47.58351, 17.50366], [48.19996, 18.20584], [49.04884, 18.59899], [52.00311, 19.00083], [54.99756, 20.00083], [55.66469, 21.99658], [55.2137, 22.71065], [55.13599, 22.63334], [52.56622, 22.94341], [51.59617, 24.12041], [51.58871, 24.27256], [51.41644, 24.39615], [51.58834, 24.66608], [51.39468, 24.62785], [51.29972, 24.50747], [51.09638, 24.46907], [50.92992, 24.54396], [50.8133, 24.74049], [50.57069, 25.57887], [50.302, 25.87592], [50.26923, 26.08243], [50.38162, 26.53976], [50.71771, 26.73086], [50.37726, 27.89227], [49.98877, 27.87827], [49.00421, 28.81495], [48.42991, 28.53628], [47.70561, 28.5221], [47.59863, 28.66798], [47.58376, 28.83382], [47.46202, 29.0014], [46.5527, 29.10283], [46.42415, 29.05947], [44.72255, 29.19736], [42.97796, 30.48295], [42.97601, 30.72204], [40.01521, 32.05667]]]] } },
23298 { type: "Feature", properties: { iso1A2: "SB", iso1A3: "SLB", iso1N3: "090", wikidata: "Q685", nameEn: "Solomon Islands", groups: ["054", "009", "UN"], driveSide: "left", callingCodes: ["677"] }, geometry: { type: "MultiPolygon", coordinates: [[[[172.71443, -12.01327], [160.43769, -4.17974], [156.03296, -6.55528], [156.03993, -6.65703], [155.92557, -6.84664], [155.69784, -6.92661], [155.60735, -6.92266], [154.74815, -7.33315], [156.73836, -14.50464], [172.71443, -12.01327]]]] } },
23299 { type: "Feature", properties: { iso1A2: "SC", iso1A3: "SYC", iso1N3: "690", wikidata: "Q1042", nameEn: "Seychelles", groups: ["014", "202", "002", "UN"], driveSide: "left", callingCodes: ["248"] }, geometry: { type: "MultiPolygon", coordinates: [[[[43.75112, -10.38913], [54.83239, -10.93575], [66.3222, 5.65313], [43.75112, -10.38913]]]] } },
23300 { type: "Feature", properties: { iso1A2: "SD", iso1A3: "SDN", iso1N3: "729", wikidata: "Q1049", nameEn: "Sudan", groups: ["015", "002", "UN"], callingCodes: ["249"] }, geometry: { type: "MultiPolygon", coordinates: [[[[37.8565, 22.00903], [34.0765, 22.00501], [33.99686, 21.76784], [33.57251, 21.72406], [33.17563, 22.00405], [24.99885, 21.99535], [24.99794, 19.99661], [23.99715, 20.00038], [23.99539, 19.49944], [23.99997, 15.69575], [23.62785, 15.7804], [23.38812, 15.69649], [23.10792, 15.71297], [22.93201, 15.55107], [22.92579, 15.47007], [22.99584, 15.40105], [22.99584, 15.22989], [22.66115, 14.86308], [22.70474, 14.69149], [22.38562, 14.58907], [22.44944, 14.24986], [22.55997, 14.23024], [22.5553, 14.11704], [22.22995, 13.96754], [22.08674, 13.77863], [22.29689, 13.3731], [22.1599, 13.19281], [22.02914, 13.13976], [21.94819, 13.05637], [21.81432, 12.81362], [21.89371, 12.68001], [21.98711, 12.63292], [22.15679, 12.66634], [22.22684, 12.74682], [22.46345, 12.61925], [22.38873, 12.45514], [22.50548, 12.16769], [22.48369, 12.02766], [22.64092, 12.07485], [22.54907, 11.64372], [22.7997, 11.40424], [22.93124, 11.41645], [22.97249, 11.21955], [22.87758, 10.91915], [23.02221, 10.69235], [23.3128, 10.45214], [23.67164, 9.86923], [23.69155, 9.67566], [24.09319, 9.66572], [24.12744, 9.73784], [24.49389, 9.79962], [24.84653, 9.80643], [24.97739, 9.9081], [25.05688, 10.06776], [25.0918, 10.33718], [25.78141, 10.42599], [25.93163, 10.38159], [25.93241, 10.17941], [26.21338, 9.91545], [26.35815, 9.57946], [26.70685, 9.48735], [27.14427, 9.62858], [27.90704, 9.61323], [28.99983, 9.67155], [29.06988, 9.74826], [29.53844, 9.75133], [29.54, 10.07949], [29.94629, 10.29245], [30.00389, 10.28633], [30.53005, 9.95992], [30.82893, 9.71451], [30.84605, 9.7498], [31.28504, 9.75287], [31.77539, 10.28939], [31.99177, 10.65065], [32.46967, 11.04662], [32.39358, 11.18207], [32.39578, 11.70208], [32.10079, 11.95203], [32.73921, 11.95203], [32.73921, 12.22757], [33.25876, 12.22111], [33.13988, 11.43248], [33.26977, 10.83632], [33.24645, 10.77913], [33.52294, 10.64382], [33.66604, 10.44254], [33.80913, 10.32994], [33.90159, 10.17179], [33.96984, 10.15446], [33.99185, 9.99623], [33.96323, 9.80972], [33.9082, 9.762], [33.87958, 9.49937], [34.10229, 9.50238], [34.08717, 9.55243], [34.13186, 9.7492], [34.20484, 9.9033], [34.22718, 10.02506], [34.32102, 10.11599], [34.34783, 10.23914], [34.2823, 10.53508], [34.4372, 10.781], [34.59062, 10.89072], [34.77383, 10.74588], [34.77532, 10.69027], [34.86618, 10.74588], [34.86916, 10.78832], [34.97491, 10.86147], [34.97789, 10.91559], [34.93172, 10.95946], [35.01215, 11.19626], [34.95704, 11.24448], [35.09556, 11.56278], [35.05832, 11.71158], [35.11492, 11.85156], [35.24302, 11.91132], [35.70476, 12.67101], [36.01458, 12.72478], [36.14268, 12.70879], [36.16651, 12.88019], [36.13374, 12.92665], [36.24545, 13.36759], [36.38993, 13.56459], [36.48824, 13.83954], [36.44653, 13.95666], [36.54376, 14.25597], [36.44337, 15.14963], [36.54276, 15.23478], [36.69761, 15.75323], [36.76371, 15.80831], [36.92193, 16.23451], [36.99777, 17.07172], [37.42694, 17.04041], [37.50967, 17.32199], [38.13362, 17.53906], [38.37133, 17.66269], [38.45916, 17.87167], [38.57727, 17.98125], [39.63762, 18.37348], [37.8565, 22.00903]]]] } },
23301 { type: "Feature", properties: { iso1A2: "SE", iso1A3: "SWE", iso1N3: "752", wikidata: "Q34", nameEn: "Sweden", groups: ["EU", "154", "150", "UN"], callingCodes: ["46"] }, geometry: { type: "MultiPolygon", coordinates: [[[[24.15791, 65.85385], [23.90497, 66.15802], [23.71339, 66.21299], [23.64982, 66.30603], [23.67591, 66.3862], [23.63776, 66.43568], [23.85959, 66.56434], [23.89488, 66.772], [23.98059, 66.79585], [23.98563, 66.84149], [23.56214, 67.17038], [23.58735, 67.20752], [23.54701, 67.25435], [23.75372, 67.29914], [23.75372, 67.43688], [23.39577, 67.46974], [23.54701, 67.59306], [23.45627, 67.85297], [23.65793, 67.9497], [23.40081, 68.05545], [23.26469, 68.15134], [23.15377, 68.14759], [23.10336, 68.26551], [22.73028, 68.40881], [22.00429, 68.50692], [21.03001, 68.88969], [20.90649, 68.89696], [20.85104, 68.93142], [20.91658, 68.96764], [20.78802, 69.03087], [20.55258, 69.06069], [20.0695, 69.04469], [20.28444, 68.93283], [20.33435, 68.80174], [20.22027, 68.67246], [19.95647, 68.55546], [20.22027, 68.48759], [19.93508, 68.35911], [18.97255, 68.52416], [18.63032, 68.50849], [18.39503, 68.58672], [18.1241, 68.53721], [18.13836, 68.20874], [17.90787, 67.96537], [17.30416, 68.11591], [16.7409, 67.91037], [16.38441, 67.52923], [16.12774, 67.52106], [16.09922, 67.4364], [16.39154, 67.21653], [16.35589, 67.06419], [15.37197, 66.48217], [15.49318, 66.28509], [15.05113, 66.15572], [14.53778, 66.12399], [14.50926, 65.31786], [13.64276, 64.58402], [14.11117, 64.46674], [14.16051, 64.18725], [13.98222, 64.00953], [13.23411, 64.09087], [12.74105, 64.02171], [12.14928, 63.59373], [12.19919, 63.47935], [11.98529, 63.27487], [12.19919, 63.00104], [12.07085, 62.6297], [12.29187, 62.25699], [12.14746, 61.7147], [12.40595, 61.57226], [12.57707, 61.56547], [12.86939, 61.35427], [12.69115, 61.06584], [12.2277, 61.02442], [12.59133, 60.50559], [12.52003, 60.13846], [12.36317, 59.99259], [12.15641, 59.8926], [11.87121, 59.86039], [11.92112, 59.69531], [11.69297, 59.59442], [11.8213, 59.24985], [11.65732, 58.90177], [11.45199, 58.89604], [11.4601, 58.99022], [11.34459, 59.11672], [11.15367, 59.07862], [11.08911, 58.98745], [10.64958, 58.89391], [10.40861, 58.38489], [12.16597, 56.60205], [12.07466, 56.29488], [12.65312, 56.04345], [12.6372, 55.91371], [12.88472, 55.63369], [12.60345, 55.42675], [12.84405, 55.13257], [14.28399, 55.1553], [14.89259, 55.5623], [15.79951, 55.54655], [19.64795, 57.06466], [19.84909, 57.57876], [20.5104, 59.15546], [19.08191, 60.19152], [19.23413, 60.61414], [20.15877, 63.06556], [24.14112, 65.39731], [24.15107, 65.81427], [24.14798, 65.83466], [24.15791, 65.85385]]]] } },
23302 { type: "Feature", properties: { iso1A2: "SG", iso1A3: "SGP", iso1N3: "702", wikidata: "Q334", nameEn: "Singapore", groups: ["035", "142", "UN"], driveSide: "left", callingCodes: ["65"] }, geometry: { type: "MultiPolygon", coordinates: [[[[104.00131, 1.42405], [103.93384, 1.42926], [103.89565, 1.42841], [103.86383, 1.46288], [103.81181, 1.47953], [103.76395, 1.45183], [103.74161, 1.4502], [103.7219, 1.46108], [103.67468, 1.43166], [103.62738, 1.35255], [103.56591, 1.19719], [103.66049, 1.18825], [103.74084, 1.12902], [104.03085, 1.26954], [104.12282, 1.27714], [104.08072, 1.35998], [104.09162, 1.39694], [104.08871, 1.42015], [104.07348, 1.43322], [104.04622, 1.44691], [104.02277, 1.4438], [104.00131, 1.42405]]]] } },
23303 { type: "Feature", properties: { iso1A2: "SH", iso1A3: "SHN", iso1N3: "654", wikidata: "Q192184", nameEn: "Saint Helena, Ascension and Tristan da Cunha", country: "GB" }, geometry: null },
23304 { type: "Feature", properties: { iso1A2: "SI", iso1A3: "SVN", iso1N3: "705", wikidata: "Q215", nameEn: "Slovenia", groups: ["EU", "039", "150", "UN"], callingCodes: ["386"] }, geometry: { type: "MultiPolygon", coordinates: [[[[16.50139, 46.56684], [16.39217, 46.63673], [16.38594, 46.6549], [16.41863, 46.66238], [16.42641, 46.69228], [16.37816, 46.69975], [16.30966, 46.7787], [16.31303, 46.79838], [16.3408, 46.80641], [16.34547, 46.83836], [16.2941, 46.87137], [16.2365, 46.87775], [16.21892, 46.86961], [16.15711, 46.85434], [16.14365, 46.8547], [16.10983, 46.867], [16.05786, 46.83927], [15.99054, 46.82772], [15.99126, 46.78199], [15.98432, 46.74991], [15.99769, 46.7266], [16.02808, 46.71094], [16.04347, 46.68694], [16.04036, 46.6549], [15.99988, 46.67947], [15.98512, 46.68463], [15.94864, 46.68769], [15.87691, 46.7211], [15.8162, 46.71897], [15.78518, 46.70712], [15.76771, 46.69863], [15.73823, 46.70011], [15.72279, 46.69548], [15.69523, 46.69823], [15.67411, 46.70735], [15.6543, 46.70616], [15.6543, 46.69228], [15.6365, 46.6894], [15.63255, 46.68069], [15.62317, 46.67947], [15.59826, 46.68908], [15.54533, 46.66985], [15.55333, 46.64988], [15.54431, 46.6312], [15.46906, 46.61321], [15.45514, 46.63697], [15.41235, 46.65556], [15.23711, 46.63994], [15.14215, 46.66131], [15.01451, 46.641], [14.98024, 46.6009], [14.96002, 46.63459], [14.92283, 46.60848], [14.87129, 46.61], [14.86419, 46.59411], [14.83549, 46.56614], [14.81836, 46.51046], [14.72185, 46.49974], [14.66892, 46.44936], [14.5942, 46.43434], [14.56463, 46.37208], [14.52176, 46.42617], [14.45877, 46.41717], [14.42608, 46.44614], [14.314, 46.43327], [14.28326, 46.44315], [14.15989, 46.43327], [14.12097, 46.47724], [14.04002, 46.49117], [14.00422, 46.48474], [13.89837, 46.52331], [13.7148, 46.5222], [13.68684, 46.43881], [13.59777, 46.44137], [13.5763, 46.42613], [13.5763, 46.40915], [13.47019, 46.3621], [13.43418, 46.35992], [13.44808, 46.33507], [13.37671, 46.29668], [13.42218, 46.20758], [13.47587, 46.22725], [13.56114, 46.2054], [13.56682, 46.18703], [13.64451, 46.18966], [13.66472, 46.17392], [13.64053, 46.13587], [13.57072, 46.09022], [13.50104, 46.05986], [13.49568, 46.04839], [13.50998, 46.04498], [13.49702, 46.01832], [13.47474, 46.00546], [13.50104, 45.98078], [13.52963, 45.96588], [13.56759, 45.96991], [13.58903, 45.99009], [13.62074, 45.98388], [13.63458, 45.98947], [13.64307, 45.98326], [13.6329, 45.94894], [13.63815, 45.93607], [13.61931, 45.91782], [13.60857, 45.89907], [13.59565, 45.89446], [13.58644, 45.88173], [13.57563, 45.8425], [13.58858, 45.83503], [13.59784, 45.8072], [13.66986, 45.79955], [13.8235, 45.7176], [13.83332, 45.70855], [13.83422, 45.68703], [13.87933, 45.65207], [13.9191, 45.6322], [13.8695, 45.60835], [13.86771, 45.59898], [13.84106, 45.58185], [13.78445, 45.5825], [13.74587, 45.59811], [13.7198, 45.59352], [13.6076, 45.64761], [13.45644, 45.59464], [13.56979, 45.4895], [13.62902, 45.45898], [13.67398, 45.4436], [13.7785, 45.46787], [13.81742, 45.43729], [13.88124, 45.42637], [13.90771, 45.45149], [13.97309, 45.45258], [13.99488, 45.47551], [13.96063, 45.50825], [14.00578, 45.52352], [14.07116, 45.48752], [14.20348, 45.46896], [14.22371, 45.50388], [14.24239, 45.50607], [14.26611, 45.48239], [14.27681, 45.4902], [14.32487, 45.47142], [14.36693, 45.48642], [14.49769, 45.54424], [14.5008, 45.60852], [14.53816, 45.6205], [14.57397, 45.67165], [14.60977, 45.66403], [14.59576, 45.62812], [14.69694, 45.57366], [14.68605, 45.53006], [14.71718, 45.53442], [14.80124, 45.49515], [14.81992, 45.45913], [14.90554, 45.47769], [14.92266, 45.52788], [15.02385, 45.48533], [15.05187, 45.49079], [15.16862, 45.42309], [15.27758, 45.46678], [15.33051, 45.45258], [15.38188, 45.48752], [15.30249, 45.53224], [15.29837, 45.5841], [15.27747, 45.60504], [15.31027, 45.6303], [15.34695, 45.63382], [15.34214, 45.64702], [15.38952, 45.63682], [15.4057, 45.64727], [15.34919, 45.71623], [15.30872, 45.69014], [15.25423, 45.72275], [15.40836, 45.79491], [15.47531, 45.79802], [15.47325, 45.8253], [15.52234, 45.82195], [15.57952, 45.84953], [15.64185, 45.82915], [15.66662, 45.84085], [15.70411, 45.8465], [15.68232, 45.86819], [15.68383, 45.88867], [15.67967, 45.90455], [15.70636, 45.92116], [15.70327, 46.00015], [15.71246, 46.01196], [15.72977, 46.04682], [15.62317, 46.09103], [15.6083, 46.11992], [15.59909, 46.14761], [15.64904, 46.19229], [15.6434, 46.21396], [15.67395, 46.22478], [15.75436, 46.21969], [15.75479, 46.20336], [15.78817, 46.21719], [15.79284, 46.25811], [15.97965, 46.30652], [16.07616, 46.3463], [16.07314, 46.36458], [16.05065, 46.3833], [16.05281, 46.39141], [16.14859, 46.40547], [16.18824, 46.38282], [16.30233, 46.37837], [16.30162, 46.40437], [16.27329, 46.41467], [16.27398, 46.42875], [16.25124, 46.48067], [16.23961, 46.49653], [16.26759, 46.50566], [16.26733, 46.51505], [16.29793, 46.5121], [16.37193, 46.55008], [16.38771, 46.53608], [16.44036, 46.5171], [16.5007, 46.49644], [16.52604, 46.47831], [16.59527, 46.47524], [16.52604, 46.5051], [16.52885, 46.53303], [16.50139, 46.56684]]]] } },
23305 { type: "Feature", properties: { iso1A2: "SJ", iso1A3: "SJM", iso1N3: "744", wikidata: "Q842829", nameEn: "Svalbard and Jan Mayen", country: "NO" }, geometry: null },
23306 { type: "Feature", properties: { iso1A2: "SK", iso1A3: "SVK", iso1N3: "703", wikidata: "Q214", nameEn: "Slovakia", groups: ["EU", "151", "150", "UN"], callingCodes: ["421"] }, geometry: { type: "MultiPolygon", coordinates: [[[[19.82237, 49.27806], [19.78581, 49.41701], [19.72127, 49.39288], [19.6375, 49.40897], [19.64162, 49.45184], [19.57845, 49.46077], [19.53313, 49.52856], [19.52626, 49.57311], [19.45348, 49.61583], [19.37795, 49.574], [19.36009, 49.53747], [19.25435, 49.53391], [19.18019, 49.41165], [18.9742, 49.39557], [18.97283, 49.49914], [18.94536, 49.52143], [18.84521, 49.51672], [18.74761, 49.492], [18.67757, 49.50895], [18.6144, 49.49824], [18.57183, 49.51162], [18.53063, 49.49022], [18.54848, 49.47059], [18.44686, 49.39467], [18.4084, 49.40003], [18.4139, 49.36517], [18.36446, 49.3267], [18.18456, 49.28909], [18.15022, 49.24518], [18.1104, 49.08624], [18.06885, 49.03157], [17.91814, 49.01784], [17.87831, 48.92679], [17.77944, 48.92318], [17.73126, 48.87885], [17.7094, 48.86721], [17.5295, 48.81117], [17.45671, 48.85004], [17.3853, 48.80936], [17.29054, 48.85546], [17.19355, 48.87602], [17.11202, 48.82925], [17.00215, 48.70887], [16.93955, 48.60371], [16.94611, 48.53614], [16.85204, 48.44968], [16.8497, 48.38321], [16.83588, 48.3844], [16.83317, 48.38138], [16.84243, 48.35258], [16.90903, 48.32519], [16.89461, 48.31332], [16.97701, 48.17385], [17.02919, 48.13996], [17.05735, 48.14179], [17.09168, 48.09366], [17.07039, 48.0317], [17.16001, 48.00636], [17.23699, 48.02094], [17.71215, 47.7548], [18.02938, 47.75665], [18.29305, 47.73541], [18.56496, 47.76588], [18.66521, 47.76772], [18.74074, 47.8157], [18.8506, 47.82308], [18.76821, 47.87469], [18.76134, 47.97499], [18.82176, 48.04206], [19.01952, 48.07052], [19.23924, 48.0595], [19.28182, 48.08336], [19.47957, 48.09437], [19.52489, 48.19791], [19.63338, 48.25006], [19.92452, 48.1283], [20.24312, 48.2784], [20.29943, 48.26104], [20.5215, 48.53336], [20.83248, 48.5824], [21.11516, 48.49546], [21.44063, 48.58456], [21.6068, 48.50365], [21.67134, 48.3989], [21.72525, 48.34628], [21.8279, 48.33321], [21.83339, 48.36242], [22.14689, 48.4005], [22.16023, 48.56548], [22.21379, 48.6218], [22.34151, 48.68893], [22.42934, 48.92857], [22.48296, 48.99172], [22.54338, 49.01424], [22.56155, 49.08865], [22.04427, 49.22136], [21.96385, 49.3437], [21.82927, 49.39467], [21.77983, 49.35443], [21.62328, 49.4447], [21.43376, 49.41433], [21.27858, 49.45988], [21.19756, 49.4054], [21.12477, 49.43666], [21.041, 49.41791], [21.09799, 49.37176], [20.98733, 49.30774], [20.9229, 49.29626], [20.77971, 49.35383], [20.72274, 49.41813], [20.61666, 49.41791], [20.5631, 49.375], [20.46422, 49.41612], [20.39939, 49.3896], [20.31728, 49.39914], [20.31453, 49.34817], [20.21977, 49.35265], [20.13738, 49.31685], [20.08238, 49.1813], [19.98494, 49.22904], [19.90529, 49.23532], [19.86409, 49.19316], [19.75286, 49.20751], [19.82237, 49.27806]]]] } },
23307 { type: "Feature", properties: { iso1A2: "SL", iso1A3: "SLE", iso1N3: "694", wikidata: "Q1044", nameEn: "Sierra Leone", groups: ["011", "202", "002", "UN"], callingCodes: ["232"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-10.27575, 8.48711], [-10.37257, 8.48941], [-10.54891, 8.31174], [-10.63934, 8.35326], [-10.70565, 8.29235], [-10.61422, 8.5314], [-10.47707, 8.67669], [-10.56197, 8.81225], [-10.5783, 9.06386], [-10.74484, 9.07998], [-10.6534, 9.29919], [-11.2118, 10.00098], [-11.89624, 9.99763], [-11.91023, 9.93927], [-12.12634, 9.87203], [-12.24262, 9.92386], [-12.47254, 9.86834], [-12.76788, 9.3133], [-12.94095, 9.26335], [-13.08953, 9.0409], [-13.18586, 9.0925], [-13.29911, 9.04245], [-14.36218, 8.64107], [-12.15048, 6.15992], [-11.50429, 6.92704], [-11.4027, 6.97746], [-11.29417, 7.21576], [-10.60422, 7.7739], [-10.60492, 8.04072], [-10.57523, 8.04829], [-10.51554, 8.1393], [-10.45023, 8.15627], [-10.35227, 8.15223], [-10.29839, 8.21283], [-10.31635, 8.28554], [-10.30084, 8.30008], [-10.27575, 8.48711]]]] } },
23308 { type: "Feature", properties: { iso1A2: "SM", iso1A3: "SMR", iso1N3: "674", wikidata: "Q238", nameEn: "San Marino", groups: ["039", "150", "UN"], callingCodes: ["378"] }, geometry: { type: "MultiPolygon", coordinates: [[[[12.45648, 43.89369], [12.48771, 43.89706], [12.49429, 43.90973], [12.49247, 43.91774], [12.49724, 43.92248], [12.50269, 43.92363], [12.50496, 43.93017], [12.51553, 43.94096], [12.51427, 43.94897], [12.50655, 43.95796], [12.50875, 43.96198], [12.50622, 43.97131], [12.51109, 43.97201], [12.51064, 43.98165], [12.5154, 43.98508], [12.51463, 43.99122], [12.50678, 43.99113], [12.49406, 43.98492], [12.47853, 43.98052], [12.46205, 43.97463], [12.44684, 43.96597], [12.43662, 43.95698], [12.42005, 43.9578], [12.41414, 43.95273], [12.40415, 43.95485], [12.40506, 43.94325], [12.41165, 43.93769], [12.41551, 43.92984], [12.40733, 43.92379], [12.41233, 43.90956], [12.40935, 43.9024], [12.41641, 43.89991], [12.44184, 43.90498], [12.45648, 43.89369]]]] } },
23309 { type: "Feature", properties: { iso1A2: "SN", iso1A3: "SEN", iso1N3: "686", wikidata: "Q1041", nameEn: "Senegal", groups: ["011", "202", "002", "UN"], callingCodes: ["221"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-14.32144, 16.61495], [-15.00557, 16.64997], [-15.6509, 16.50315], [-16.27016, 16.51565], [-16.4429, 16.20605], [-16.44814, 16.09753], [-16.48967, 16.0496], [-16.50854, 16.09032], [-17.15288, 16.07139], [-18.35085, 14.63444], [-17.43598, 13.59273], [-15.47902, 13.58758], [-15.36504, 13.79313], [-14.93719, 13.80173], [-14.34721, 13.46578], [-13.8955, 13.59126], [-13.79409, 13.34472], [-14.36795, 13.23033], [-15.14917, 13.57989], [-15.26908, 13.37768], [-15.80478, 13.34832], [-15.80355, 13.16729], [-16.69343, 13.16791], [-16.74676, 13.06025], [-17.43966, 13.04579], [-17.4623, 11.92379], [-16.70562, 12.34803], [-16.38191, 12.36449], [-16.20591, 12.46157], [-15.67302, 12.42974], [-15.17582, 12.6847], [-13.70523, 12.68013], [-13.05296, 12.64003], [-13.06603, 12.49342], [-12.87336, 12.51892], [-12.35415, 12.32758], [-11.91331, 12.42008], [-11.46267, 12.44559], [-11.37536, 12.40788], [-11.39935, 12.97808], [-11.63025, 13.39174], [-11.83345, 13.33333], [-12.06897, 13.71049], [-11.93043, 13.84505], [-12.23936, 14.76324], [-13.11029, 15.52116], [-13.43135, 16.09022], [-13.80075, 16.13961], [-14.32144, 16.61495]]]] } },
23310 { type: "Feature", properties: { iso1A2: "SO", iso1A3: "SOM", iso1N3: "706", wikidata: "Q1045", nameEn: "Somalia", groups: ["014", "202", "002", "UN"], callingCodes: ["252"] }, geometry: { type: "MultiPolygon", coordinates: [[[[51.12877, 12.56479], [43.90659, 12.3823], [42.95776, 10.98533], [42.69452, 10.62672], [42.87643, 10.18441], [43.0937, 9.90579], [43.23518, 9.84605], [43.32613, 9.59205], [44.19222, 8.93028], [46.99339, 7.9989], [47.92477, 8.00111], [47.97917, 8.00124], [44.98104, 4.91821], [44.02436, 4.9451], [43.40263, 4.79289], [43.04177, 4.57923], [42.97746, 4.44032], [42.84526, 4.28357], [42.55853, 4.20518], [42.07619, 4.17667], [41.89488, 3.97375], [41.31368, 3.14314], [40.98767, 2.82959], [41.00099, -0.83068], [41.56, -1.59812], [41.56362, -1.66375], [41.75542, -1.85308], [57.49095, 8.14549], [51.12877, 12.56479]]]] } },
23311 { type: "Feature", properties: { iso1A2: "SR", iso1A3: "SUR", iso1N3: "740", wikidata: "Q730", nameEn: "Suriname", groups: ["005", "419", "019", "UN"], driveSide: "left", callingCodes: ["597"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-54.26916, 5.26909], [-54.01877, 5.52789], [-54.01074, 5.68785], [-53.7094, 6.2264], [-56.84822, 6.73257], [-57.31629, 5.33714], [-57.22536, 5.15605], [-57.37442, 5.0208], [-57.8699, 4.89394], [-58.0307, 3.95513], [-57.35891, 3.32121], [-56.70519, 2.02964], [-56.55439, 2.02003], [-56.47045, 1.95135], [-55.99278, 1.83137], [-55.89863, 1.89861], [-55.92159, 2.05236], [-56.13054, 2.27723], [-55.96292, 2.53188], [-55.71493, 2.40342], [-55.01919, 2.564], [-54.6084, 2.32856], [-54.42864, 2.42442], [-54.28534, 2.67798], [-53.9849, 3.58697], [-53.98914, 3.627], [-54.05128, 3.63557], [-54.19367, 3.84387], [-54.38444, 4.13222], [-54.4717, 4.91964], [-54.26916, 5.26909]]]] } },
23312 { type: "Feature", properties: { iso1A2: "SS", iso1A3: "SSD", iso1N3: "728", wikidata: "Q958", nameEn: "South Sudan", groups: ["014", "202", "002", "UN"], callingCodes: ["211"] }, geometry: { type: "MultiPolygon", coordinates: [[[[34.10229, 9.50238], [33.87958, 9.49937], [33.9082, 9.762], [33.96323, 9.80972], [33.99185, 9.99623], [33.96984, 10.15446], [33.90159, 10.17179], [33.80913, 10.32994], [33.66604, 10.44254], [33.52294, 10.64382], [33.24645, 10.77913], [33.26977, 10.83632], [33.13988, 11.43248], [33.25876, 12.22111], [32.73921, 12.22757], [32.73921, 11.95203], [32.10079, 11.95203], [32.39578, 11.70208], [32.39358, 11.18207], [32.46967, 11.04662], [31.99177, 10.65065], [31.77539, 10.28939], [31.28504, 9.75287], [30.84605, 9.7498], [30.82893, 9.71451], [30.53005, 9.95992], [30.00389, 10.28633], [29.94629, 10.29245], [29.54, 10.07949], [29.53844, 9.75133], [29.06988, 9.74826], [28.99983, 9.67155], [27.90704, 9.61323], [27.14427, 9.62858], [26.70685, 9.48735], [26.35815, 9.57946], [26.21338, 9.91545], [25.93241, 10.17941], [25.93163, 10.38159], [25.78141, 10.42599], [25.0918, 10.33718], [25.05688, 10.06776], [24.97739, 9.9081], [24.84653, 9.80643], [24.49389, 9.79962], [24.12744, 9.73784], [24.09319, 9.66572], [23.69155, 9.67566], [23.62179, 9.53823], [23.64981, 9.44303], [23.64358, 9.28637], [23.56263, 9.19418], [23.4848, 9.16959], [23.44744, 8.99128], [23.59065, 8.99743], [23.51905, 8.71749], [24.25691, 8.69288], [24.13238, 8.36959], [24.35965, 8.26177], [24.85156, 8.16933], [24.98855, 7.96588], [25.25319, 7.8487], [25.29214, 7.66675], [25.20649, 7.61115], [25.20337, 7.50312], [25.35281, 7.42595], [25.37461, 7.33024], [25.90076, 7.09549], [26.38022, 6.63493], [26.32729, 6.36272], [26.58259, 6.1987], [26.51721, 6.09655], [27.22705, 5.71254], [27.22705, 5.62889], [27.28621, 5.56382], [27.23017, 5.37167], [27.26886, 5.25876], [27.44012, 5.07349], [27.56656, 4.89375], [27.65462, 4.89375], [27.76469, 4.79284], [27.79551, 4.59976], [28.20719, 4.35614], [28.6651, 4.42638], [28.8126, 4.48784], [29.03054, 4.48784], [29.22207, 4.34297], [29.43341, 4.50101], [29.49726, 4.7007], [29.82087, 4.56246], [29.79666, 4.37809], [30.06964, 4.13221], [30.1621, 4.10586], [30.22374, 3.93896], [30.27658, 3.95653], [30.47691, 3.83353], [30.55396, 3.84451], [30.57378, 3.74567], [30.56277, 3.62703], [30.78512, 3.67097], [30.80713, 3.60506], [30.85997, 3.5743], [30.85153, 3.48867], [30.97601, 3.693], [31.16666, 3.79853], [31.29476, 3.8015], [31.50478, 3.67814], [31.50776, 3.63652], [31.72075, 3.74354], [31.81459, 3.82083], [31.86821, 3.78664], [31.96205, 3.6499], [31.95907, 3.57408], [32.05187, 3.589], [32.08491, 3.56287], [32.08866, 3.53543], [32.19888, 3.50867], [32.20782, 3.6053], [32.41337, 3.748], [32.72021, 3.77327], [32.89746, 3.81339], [33.02852, 3.89296], [33.18356, 3.77812], [33.51264, 3.75068], [33.9873, 4.23316], [34.47601, 4.72162], [35.34151, 5.02364], [35.30992, 4.90402], [35.47843, 4.91872], [35.42366, 4.76969], [35.51424, 4.61643], [35.9419, 4.61933], [35.82118, 4.77382], [35.81968, 5.10757], [35.8576, 5.33413], [35.50792, 5.42431], [35.29938, 5.34042], [35.31188, 5.50106], [35.13058, 5.62118], [35.12611, 5.68937], [35.00546, 5.89387], [34.96227, 6.26415], [35.01738, 6.46991], [34.87736, 6.60161], [34.77459, 6.5957], [34.65096, 6.72589], [34.53776, 6.74808], [34.53925, 6.82794], [34.47669, 6.91076], [34.35753, 6.91963], [34.19369, 7.04382], [34.19369, 7.12807], [34.01495, 7.25664], [34.03878, 7.27437], [34.02984, 7.36449], [33.87642, 7.5491], [33.71407, 7.65983], [33.44745, 7.7543], [33.32531, 7.71297], [33.24637, 7.77939], [33.04944, 7.78989], [33.0006, 7.90333], [33.08401, 8.05822], [33.18083, 8.13047], [33.1853, 8.29264], [33.19721, 8.40317], [33.3119, 8.45474], [33.54575, 8.47094], [33.66938, 8.44442], [33.71407, 8.3678], [33.87195, 8.41938], [33.89579, 8.4842], [34.01346, 8.50041], [34.14453, 8.60204], [34.14304, 9.04654], [34.10229, 9.50238]]]] } },
23313 { type: "Feature", properties: { iso1A2: "ST", iso1A3: "STP", iso1N3: "678", wikidata: "Q1039", nameEn: "S\xE3o Tom\xE9 and Principe", groups: ["017", "202", "002", "UN"], callingCodes: ["239"] }, geometry: { type: "MultiPolygon", coordinates: [[[[4.34149, 1.91417], [6.6507, -0.28606], [7.9035, 1.92304], [4.34149, 1.91417]]]] } },
23314 { type: "Feature", properties: { iso1A2: "SV", iso1A3: "SLV", iso1N3: "222", wikidata: "Q792", nameEn: "El Salvador", groups: ["013", "003", "419", "019", "UN"], callingCodes: ["503"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-89.34776, 14.43013], [-89.39028, 14.44561], [-89.57441, 14.41637], [-89.58814, 14.33165], [-89.50614, 14.26084], [-89.52397, 14.22628], [-89.61844, 14.21937], [-89.70756, 14.1537], [-89.75569, 14.07073], [-89.73251, 14.04133], [-89.76103, 14.02923], [-89.81807, 14.07073], [-89.88937, 14.0396], [-90.10505, 13.85104], [-90.11344, 13.73679], [-90.55276, 12.8866], [-88.11443, 12.63306], [-87.7346, 13.13228], [-87.55124, 13.12523], [-87.69751, 13.25228], [-87.73714, 13.32715], [-87.80177, 13.35689], [-87.84675, 13.41078], [-87.83467, 13.44655], [-87.77354, 13.45767], [-87.73841, 13.44169], [-87.72115, 13.46083], [-87.71657, 13.50577], [-87.78148, 13.52906], [-87.73106, 13.75443], [-87.68821, 13.80829], [-87.7966, 13.91353], [-88.00331, 13.86948], [-88.07641, 13.98447], [-88.23018, 13.99915], [-88.25791, 13.91108], [-88.48982, 13.86458], [-88.49738, 13.97224], [-88.70661, 14.04317], [-88.73182, 14.10919], [-88.815, 14.11652], [-88.85785, 14.17763], [-88.94608, 14.20207], [-89.04187, 14.33644], [-89.34776, 14.43013]]]] } },
23315 { type: "Feature", properties: { iso1A2: "SX", iso1A3: "SXM", iso1N3: "534", wikidata: "Q26273", nameEn: "Sint Maarten", aliases: ["NL-SX"], country: "NL", groups: ["Q1451600", "029", "003", "419", "019", "UN"], callingCodes: ["1 721"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-63.33064, 17.9615], [-63.1055, 17.86651], [-62.93924, 18.02904], [-63.02323, 18.05757], [-63.04039, 18.05619], [-63.0579, 18.06614], [-63.07759, 18.04943], [-63.09686, 18.04608], [-63.11042, 18.05339], [-63.13502, 18.05445], [-63.33064, 17.9615]]]] } },
23316 { type: "Feature", properties: { iso1A2: "SY", iso1A3: "SYR", iso1N3: "760", wikidata: "Q858", nameEn: "Syria", groups: ["145", "142", "UN"], callingCodes: ["963"] }, geometry: { type: "MultiPolygon", coordinates: [[[[42.23683, 37.2863], [42.21548, 37.28026], [42.20454, 37.28715], [42.22381, 37.30238], [42.22257, 37.31395], [42.2112, 37.32491], [42.19301, 37.31323], [42.18225, 37.28569], [42.00894, 37.17209], [41.515, 37.08084], [41.21937, 37.07665], [40.90856, 37.13147], [40.69136, 37.0996], [39.81589, 36.75538], [39.21538, 36.66834], [39.03217, 36.70911], [38.74042, 36.70629], [38.55908, 36.84429], [38.38859, 36.90064], [38.21064, 36.91842], [37.81974, 36.76055], [37.68048, 36.75065], [37.49103, 36.66904], [37.47253, 36.63243], [37.21988, 36.6736], [37.16177, 36.66069], [37.10894, 36.6704], [37.08279, 36.63495], [37.02088, 36.66422], [37.01647, 36.69512], [37.04619, 36.71101], [37.04399, 36.73483], [36.99886, 36.74012], [36.99557, 36.75997], [36.66727, 36.82901], [36.61581, 36.74629], [36.62681, 36.71189], [36.57398, 36.65186], [36.58829, 36.58295], [36.54206, 36.49539], [36.6081, 36.33772], [36.65653, 36.33861], [36.68672, 36.23677], [36.6125, 36.22592], [36.50463, 36.2419], [36.4617, 36.20461], [36.39206, 36.22088], [36.37474, 36.01163], [36.33956, 35.98687], [36.30099, 36.00985], [36.28338, 36.00273], [36.29769, 35.96086], [36.27678, 35.94839], [36.25366, 35.96264], [36.19973, 35.95195], [36.17441, 35.92076], [36.1623, 35.80925], [36.14029, 35.81015], [36.13919, 35.83692], [36.11827, 35.85923], [35.99829, 35.88242], [36.01844, 35.92403], [36.00514, 35.94113], [35.98499, 35.94107], [35.931, 35.92109], [35.51152, 36.10954], [35.48515, 34.70851], [35.97386, 34.63322], [35.98718, 34.64977], [36.29165, 34.62991], [36.32399, 34.69334], [36.35135, 34.68516], [36.35384, 34.65447], [36.42941, 34.62505], [36.46003, 34.6378], [36.45299, 34.59438], [36.41429, 34.61175], [36.39846, 34.55672], [36.3369, 34.52629], [36.34745, 34.5002], [36.4442, 34.50165], [36.46179, 34.46541], [36.55853, 34.41609], [36.53039, 34.3798], [36.56556, 34.31881], [36.60778, 34.31009], [36.58667, 34.27667], [36.59195, 34.2316], [36.62537, 34.20251], [36.5128, 34.09916], [36.50576, 34.05982], [36.41078, 34.05253], [36.28589, 33.91981], [36.38263, 33.86579], [36.3967, 33.83365], [36.14517, 33.85118], [36.06778, 33.82927], [35.9341, 33.6596], [36.05723, 33.57904], [35.94465, 33.52774], [35.94816, 33.47886], [35.88668, 33.43183], [35.82577, 33.40479], [35.81324, 33.36354], [35.77477, 33.33609], [35.813, 33.3172], [35.77513, 33.27342], [35.81295, 33.24841], [35.81647, 33.2028], [35.83846, 33.19397], [35.84285, 33.16673], [35.81911, 33.1336], [35.81911, 33.11077], [35.84802, 33.1031], [35.87188, 32.98028], [35.89298, 32.9456], [35.87012, 32.91976], [35.84021, 32.8725], [35.83758, 32.82817], [35.78745, 32.77938], [35.75983, 32.74803], [35.88405, 32.71321], [35.93307, 32.71966], [35.96633, 32.66237], [36.02239, 32.65911], [36.08074, 32.51463], [36.20379, 32.52751], [36.20875, 32.49529], [36.23948, 32.50108], [36.40959, 32.37908], [36.83946, 32.31293], [38.79171, 33.37328], [40.64314, 34.31604], [40.97676, 34.39788], [41.12388, 34.65742], [41.2345, 34.80049], [41.21654, 35.1508], [41.26569, 35.42708], [41.38184, 35.62502], [41.37027, 35.84095], [41.2564, 36.06012], [41.28864, 36.35368], [41.40058, 36.52502], [41.81736, 36.58782], [42.36697, 37.0627], [42.35724, 37.10998], [42.32313, 37.17814], [42.34735, 37.22548], [42.2824, 37.2798], [42.26039, 37.27017], [42.23683, 37.2863]]]] } },
23317 { type: "Feature", properties: { iso1A2: "SZ", iso1A3: "SWZ", iso1N3: "748", wikidata: "Q1050", nameEn: "Eswatini", aliases: ["Swaziland"], groups: ["018", "202", "002", "UN"], driveSide: "left", callingCodes: ["268"] }, geometry: { type: "MultiPolygon", coordinates: [[[[31.86881, -25.99973], [31.4175, -25.71886], [31.31237, -25.7431], [31.13073, -25.91558], [30.95819, -26.26303], [30.78927, -26.48271], [30.81101, -26.84722], [30.88826, -26.79622], [30.97757, -26.92706], [30.96088, -27.0245], [31.15027, -27.20151], [31.49834, -27.31549], [31.97592, -27.31675], [31.97463, -27.11057], [32.00893, -26.8096], [32.09664, -26.80721], [32.13315, -26.84345], [32.13409, -26.5317], [32.07352, -26.40185], [32.10435, -26.15656], [32.08599, -26.00978], [32.00916, -25.999], [31.974, -25.95387], [31.86881, -25.99973]]]] } },
23318 { type: "Feature", properties: { iso1A2: "TA", iso1A3: "TAA", wikidata: "Q220982", nameEn: "Tristan da Cunha", aliases: ["SH-TA"], country: "GB", groups: ["SH", "BOTS", "011", "202", "002", "UN"], isoStatus: "excRes", driveSide: "left", roadSpeedUnit: "mph", roadHeightUnit: "ft", callingCodes: ["290 8", "44 20"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-13.38232, -34.07258], [-16.67337, -41.9188], [-5.88482, -41.4829], [-13.38232, -34.07258]]]] } },
23319 { type: "Feature", properties: { iso1A2: "TC", iso1A3: "TCA", iso1N3: "796", wikidata: "Q18221", nameEn: "Turks and Caicos Islands", country: "GB", groups: ["BOTS", "029", "003", "419", "019", "UN"], driveSide: "left", roadSpeedUnit: "mph", roadHeightUnit: "ft", callingCodes: ["1 649"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-71.70065, 25.7637], [-72.98446, 20.4801], [-69.80718, 21.35956], [-71.70065, 25.7637]]]] } },
23320 { type: "Feature", properties: { iso1A2: "TD", iso1A3: "TCD", iso1N3: "148", wikidata: "Q657", nameEn: "Chad", groups: ["017", "202", "002", "UN"], callingCodes: ["235"] }, geometry: { type: "MultiPolygon", coordinates: [[[[23.99539, 19.49944], [15.99566, 23.49639], [14.99751, 23.00539], [15.19692, 21.99339], [15.20213, 21.49365], [15.28332, 21.44557], [15.62515, 20.95395], [15.57248, 20.92138], [15.55382, 20.86507], [15.56004, 20.79488], [15.59841, 20.74039], [15.6721, 20.70069], [15.99632, 20.35364], [15.75098, 19.93002], [15.6032, 18.77402], [15.50373, 16.89649], [14.37425, 15.72591], [13.86301, 15.04043], [13.78991, 14.87519], [13.809, 14.72915], [13.67878, 14.64013], [13.68573, 14.55276], [13.48259, 14.46704], [13.47559, 14.40881], [13.6302, 13.71094], [14.08251, 13.0797], [14.46881, 13.08259], [14.56101, 12.91036], [14.55058, 12.78256], [14.83314, 12.62963], [14.90827, 12.3269], [14.89019, 12.16593], [14.96952, 12.0925], [15.00146, 12.1223], [15.0349, 12.10698], [15.05786, 12.0608], [15.04808, 11.8731], [15.11579, 11.79313], [15.06595, 11.71126], [15.13149, 11.5537], [15.0585, 11.40481], [15.10021, 11.04101], [15.04957, 11.02347], [15.09127, 10.87431], [15.06737, 10.80921], [15.15532, 10.62846], [15.14936, 10.53915], [15.23724, 10.47764], [15.30874, 10.31063], [15.50535, 10.1098], [15.68761, 9.99344], [15.41408, 9.92876], [15.24618, 9.99246], [15.14043, 9.99246], [15.05999, 9.94845], [14.95722, 9.97926], [14.80082, 9.93818], [14.4673, 10.00264], [14.20411, 10.00055], [14.1317, 9.82413], [14.01793, 9.73169], [13.97544, 9.6365], [14.37094, 9.2954], [14.35707, 9.19611], [14.83566, 8.80557], [15.09484, 8.65982], [15.20426, 8.50892], [15.50743, 7.79302], [15.59272, 7.7696], [15.56964, 7.58936], [15.49743, 7.52179], [15.73118, 7.52006], [15.79942, 7.44149], [16.40703, 7.68809], [16.41583, 7.77971], [16.58315, 7.88657], [16.59415, 7.76444], [16.658, 7.75353], [16.6668, 7.67281], [16.8143, 7.53971], [17.67288, 7.98905], [17.93926, 7.95853], [18.02731, 8.01085], [18.6085, 8.05009], [18.64153, 8.08714], [18.62612, 8.14163], [18.67455, 8.22226], [18.79783, 8.25929], [19.11044, 8.68172], [18.86388, 8.87971], [19.06421, 9.00367], [20.36748, 9.11019], [20.82979, 9.44696], [21.26348, 9.97642], [21.34934, 9.95907], [21.52766, 10.2105], [21.63553, 10.217], [21.71479, 10.29932], [21.72139, 10.64136], [22.45889, 11.00246], [22.87758, 10.91915], [22.97249, 11.21955], [22.93124, 11.41645], [22.7997, 11.40424], [22.54907, 11.64372], [22.64092, 12.07485], [22.48369, 12.02766], [22.50548, 12.16769], [22.38873, 12.45514], [22.46345, 12.61925], [22.22684, 12.74682], [22.15679, 12.66634], [21.98711, 12.63292], [21.89371, 12.68001], [21.81432, 12.81362], [21.94819, 13.05637], [22.02914, 13.13976], [22.1599, 13.19281], [22.29689, 13.3731], [22.08674, 13.77863], [22.22995, 13.96754], [22.5553, 14.11704], [22.55997, 14.23024], [22.44944, 14.24986], [22.38562, 14.58907], [22.70474, 14.69149], [22.66115, 14.86308], [22.99584, 15.22989], [22.99584, 15.40105], [22.92579, 15.47007], [22.93201, 15.55107], [23.10792, 15.71297], [23.38812, 15.69649], [23.62785, 15.7804], [23.99997, 15.69575], [23.99539, 19.49944]]]] } },
23321 { type: "Feature", properties: { iso1A2: "TF", iso1A3: "ATF", iso1N3: "260", wikidata: "Q129003", nameEn: "French Southern Territories", country: "FR", groups: ["EU", "UN"] }, geometry: null },
23322 { type: "Feature", properties: { iso1A2: "TG", iso1A3: "TGO", iso1N3: "768", wikidata: "Q945", nameEn: "Togo", groups: ["011", "202", "002", "UN"], callingCodes: ["228"] }, geometry: { type: "MultiPolygon", coordinates: [[[[0.50388, 11.01011], [-0.13493, 11.14075], [-0.14462, 11.10811], [-0.05733, 11.08628], [-0.0275, 11.11202], [-514e-5, 11.10763], [342e-5, 11.08317], [0.02395, 11.06229], [0.03355, 10.9807], [-63e-4, 10.96417], [-908e-5, 10.91644], [-0.02685, 10.8783], [-0.0228, 10.81916], [-0.07183, 10.76794], [-0.07327, 10.71845], [-0.09141, 10.7147], [-0.05945, 10.63458], [0.12886, 10.53149], [0.18846, 10.4096], [0.29453, 10.41546], [0.33028, 10.30408], [0.39584, 10.31112], [0.35293, 10.09412], [0.41371, 10.06361], [0.41252, 10.02018], [0.36366, 10.03309], [0.32075, 9.72781], [0.34816, 9.71607], [0.34816, 9.66907], [0.32313, 9.6491], [0.28261, 9.69022], [0.26712, 9.66437], [0.29334, 9.59387], [0.36008, 9.6256], [0.38153, 9.58682], [0.23851, 9.57389], [0.2409, 9.52335], [0.30406, 9.521], [0.31241, 9.50337], [0.2254, 9.47869], [0.25758, 9.42696], [0.33148, 9.44812], [0.36485, 9.49749], [0.49118, 9.48339], [0.56388, 9.40697], [0.45424, 9.04581], [0.52455, 8.87746], [0.37319, 8.75262], [0.47211, 8.59945], [0.64731, 8.48866], [0.73432, 8.29529], [0.63897, 8.25873], [0.5913, 8.19622], [0.61156, 8.18324], [0.6056, 8.13959], [0.58891, 8.12779], [0.62943, 7.85751], [0.58295, 7.62368], [0.51979, 7.58706], [0.52455, 7.45354], [0.57223, 7.39326], [0.62943, 7.41099], [0.65327, 7.31643], [0.59606, 7.01252], [0.52217, 6.9723], [0.52098, 6.94391], [0.56508, 6.92971], [0.52853, 6.82921], [0.57406, 6.80348], [0.58176, 6.76049], [0.6497, 6.73682], [0.63659, 6.63857], [0.74862, 6.56517], [0.71048, 6.53083], [0.89283, 6.33779], [0.99652, 6.33779], [1.03108, 6.24064], [1.05969, 6.22998], [1.09187, 6.17074], [1.19966, 6.17069], [1.19771, 6.11522], [1.27574, 5.93551], [1.67336, 6.02702], [1.62913, 6.24075], [1.79826, 6.28221], [1.76906, 6.43189], [1.58105, 6.68619], [1.61812, 6.74843], [1.55877, 6.99737], [1.64249, 6.99562], [1.61838, 9.0527], [1.5649, 9.16941], [1.41746, 9.3226], [1.33675, 9.54765], [1.36624, 9.5951], [1.35507, 9.99525], [0.77666, 10.37665], [0.80358, 10.71459], [0.8804, 10.803], [0.91245, 10.99597], [0.66104, 10.99964], [0.4958, 10.93269], [0.50521, 10.98035], [0.48852, 10.98561], [0.50388, 11.01011]]]] } },
23323 { type: "Feature", properties: { iso1A2: "TH", iso1A3: "THA", iso1N3: "764", wikidata: "Q869", nameEn: "Thailand", groups: ["035", "142", "UN"], driveSide: "left", callingCodes: ["66"] }, geometry: { type: "MultiPolygon", coordinates: [[[[100.08404, 20.36626], [99.95721, 20.46301], [99.91616, 20.44986], [99.90499, 20.4487], [99.89692, 20.44789], [99.89301, 20.44311], [99.89168, 20.44548], [99.88451, 20.44596], [99.88211, 20.44488], [99.86383, 20.44371], [99.81096, 20.33687], [99.68255, 20.32077], [99.46008, 20.39673], [99.46077, 20.36198], [99.5569, 20.20676], [99.52943, 20.14811], [99.416, 20.08614], [99.20328, 20.12877], [99.0735, 20.10298], [98.98679, 19.7419], [98.83661, 19.80931], [98.56065, 19.67807], [98.51182, 19.71303], [98.24884, 19.67876], [98.13829, 19.78541], [98.03314, 19.80941], [98.04364, 19.65755], [97.84715, 19.55782], [97.88423, 19.5041], [97.78769, 19.39429], [97.84186, 19.29526], [97.78606, 19.26769], [97.84024, 19.22217], [97.83479, 19.09972], [97.73797, 19.04261], [97.73654, 18.9812], [97.66487, 18.9371], [97.73836, 18.88478], [97.76752, 18.58097], [97.5258, 18.4939], [97.36444, 18.57138], [97.34522, 18.54596], [97.50383, 18.26844], [97.56219, 18.33885], [97.64116, 18.29778], [97.60841, 18.23846], [97.73723, 17.97912], [97.66794, 17.88005], [97.76407, 17.71595], [97.91829, 17.54504], [98.11185, 17.36829], [98.10439, 17.33847], [98.34566, 17.04822], [98.39441, 17.06266], [98.52624, 16.89979], [98.49603, 16.8446], [98.53833, 16.81934], [98.46994, 16.73613], [98.50253, 16.7139], [98.49713, 16.69022], [98.51043, 16.70107], [98.51579, 16.69433], [98.51472, 16.68521], [98.51833, 16.676], [98.51113, 16.64503], [98.5695, 16.62826], [98.57912, 16.55983], [98.63817, 16.47424], [98.68074, 16.27068], [98.84485, 16.42354], [98.92656, 16.36425], [98.8376, 16.11706], [98.69585, 16.13353], [98.57019, 16.04578], [98.59853, 15.87197], [98.541, 15.65406], [98.58598, 15.46821], [98.56027, 15.33471], [98.4866, 15.39154], [98.39351, 15.34177], [98.41906, 15.27103], [98.40522, 15.25268], [98.30446, 15.30667], [98.22, 15.21327], [98.18821, 15.13125], [98.24874, 14.83013], [98.56762, 14.37701], [98.97356, 14.04868], [99.16695, 13.72621], [99.20617, 13.20575], [99.12225, 13.19847], [99.10646, 13.05804], [99.18748, 12.9898], [99.18905, 12.84799], [99.29254, 12.68921], [99.409, 12.60603], [99.47519, 12.1353], [99.56445, 12.14805], [99.53424, 12.02317], [99.64891, 11.82699], [99.64108, 11.78948], [99.5672, 11.62732], [99.47598, 11.62434], [99.39485, 11.3925], [99.31573, 11.32081], [99.32756, 11.28545], [99.06938, 10.94857], [99.02337, 10.97217], [98.99701, 10.92962], [99.0069, 10.85485], [98.86819, 10.78336], [98.78511, 10.68351], [98.77275, 10.62548], [98.81944, 10.52761], [98.7391, 10.31488], [98.55174, 9.92804], [98.52291, 9.92389], [98.47298, 9.95782], [98.33094, 9.91973], [98.12555, 9.44056], [97.63455, 9.60854], [97.19814, 8.18901], [99.31854, 5.99868], [99.50117, 6.44501], [99.91873, 6.50233], [100.0756, 6.4045], [100.12, 6.42105], [100.19511, 6.72559], [100.29651, 6.68439], [100.30828, 6.66462], [100.31618, 6.66781], [100.31884, 6.66423], [100.32671, 6.66526], [100.32607, 6.65933], [100.31929, 6.65413], [100.35413, 6.54932], [100.41152, 6.52299], [100.41791, 6.5189], [100.42351, 6.51762], [100.43027, 6.52389], [100.66986, 6.45086], [100.74361, 6.50811], [100.74822, 6.46231], [100.81045, 6.45086], [100.85884, 6.24929], [101.10313, 6.25617], [101.12618, 6.19431], [101.06165, 6.14161], [101.12388, 6.11411], [101.087, 5.9193], [101.02708, 5.91013], [100.98815, 5.79464], [101.14062, 5.61613], [101.25755, 5.71065], [101.25524, 5.78633], [101.58019, 5.93534], [101.69773, 5.75881], [101.75074, 5.79091], [101.80144, 5.74505], [101.89188, 5.8386], [101.91776, 5.84269], [101.92819, 5.85511], [101.94712, 5.98421], [101.9714, 6.00575], [101.97114, 6.01992], [101.99209, 6.04075], [102.01835, 6.05407], [102.09182, 6.14161], [102.07732, 6.193], [102.08127, 6.22679], [102.09086, 6.23546], [102.46318, 7.22462], [102.47649, 9.66162], [102.52395, 11.25257], [102.91449, 11.65512], [102.90973, 11.75613], [102.83957, 11.8519], [102.78427, 11.98746], [102.77026, 12.06815], [102.70176, 12.1686], [102.73134, 12.37091], [102.78116, 12.40284], [102.7796, 12.43781], [102.57567, 12.65358], [102.51963, 12.66117], [102.4994, 12.71736], [102.53053, 12.77506], [102.49335, 12.92711], [102.48694, 12.97537], [102.52275, 12.99813], [102.46011, 13.08057], [102.43422, 13.09061], [102.36146, 13.26006], [102.36001, 13.31142], [102.34611, 13.35618], [102.35692, 13.38274], [102.35563, 13.47307], [102.361, 13.50551], [102.33828, 13.55613], [102.36859, 13.57488], [102.44601, 13.5637], [102.5358, 13.56933], [102.57573, 13.60461], [102.62483, 13.60883], [102.58635, 13.6286], [102.5481, 13.6589], [102.56848, 13.69366], [102.72727, 13.77806], [102.77864, 13.93374], [102.91251, 14.01531], [102.93275, 14.19044], [103.16469, 14.33075], [103.39353, 14.35639], [103.53518, 14.42575], [103.71109, 14.4348], [103.70175, 14.38052], [103.93836, 14.3398], [104.27616, 14.39861], [104.55014, 14.36091], [104.69335, 14.42726], [104.97667, 14.38806], [105.02804, 14.23722], [105.08408, 14.20402], [105.14012, 14.23873], [105.17748, 14.34432], [105.20894, 14.34967], [105.43783, 14.43865], [105.53864, 14.55731], [105.5121, 14.80802], [105.61162, 15.00037], [105.46661, 15.13132], [105.58043, 15.32724], [105.50662, 15.32054], [105.4692, 15.33709], [105.47635, 15.3796], [105.58191, 15.41031], [105.60446, 15.53301], [105.61756, 15.68792], [105.46573, 15.74742], [105.42285, 15.76971], [105.37959, 15.84074], [105.34115, 15.92737], [105.38508, 15.987], [105.42001, 16.00657], [105.06204, 16.09792], [105.00262, 16.25627], [104.88057, 16.37311], [104.73349, 16.565], [104.76099, 16.69302], [104.7397, 16.81005], [104.76442, 16.84752], [104.7373, 16.91125], [104.73712, 17.01404], [104.80716, 17.19025], [104.80061, 17.39367], [104.69867, 17.53038], [104.45404, 17.66788], [104.35432, 17.82871], [104.2757, 17.86139], [104.21776, 17.99335], [104.10927, 18.10826], [104.06533, 18.21656], [103.97725, 18.33631], [103.93916, 18.33914], [103.85642, 18.28666], [103.82449, 18.33979], [103.699, 18.34125], [103.60957, 18.40528], [103.47773, 18.42841], [103.41044, 18.4486], [103.30977, 18.4341], [103.24779, 18.37807], [103.23818, 18.34875], [103.29757, 18.30475], [103.17093, 18.2618], [103.14994, 18.23172], [103.1493, 18.17799], [103.07343, 18.12351], [103.07823, 18.03833], [103.0566, 18.00144], [103.01998, 17.97095], [102.9912, 17.9949], [102.95812, 18.0054], [102.86323, 17.97531], [102.81988, 17.94233], [102.79044, 17.93612], [102.75954, 17.89561], [102.68538, 17.86653], [102.67543, 17.84529], [102.69946, 17.81686], [102.68194, 17.80151], [102.59485, 17.83537], [102.5896, 17.84889], [102.61432, 17.92273], [102.60971, 17.95411], [102.59234, 17.96127], [102.45523, 17.97106], [102.11359, 18.21532], [101.88485, 18.02474], [101.78087, 18.07559], [101.72294, 17.92867], [101.44667, 17.7392], [101.15108, 17.47586], [100.96541, 17.57926], [101.02185, 17.87637], [101.1793, 18.0544], [101.19118, 18.2125], [101.15108, 18.25624], [101.18227, 18.34367], [101.06047, 18.43247], [101.27585, 18.68875], [101.22832, 18.73377], [101.25803, 18.89545], [101.35606, 19.04716], [101.261, 19.12717], [101.24911, 19.33334], [101.20604, 19.35296], [101.21347, 19.46223], [101.26991, 19.48324], [101.26545, 19.59242], [101.08928, 19.59748], [100.90302, 19.61901], [100.77231, 19.48324], [100.64606, 19.55884], [100.58219, 19.49164], [100.49604, 19.53504], [100.398, 19.75047], [100.5094, 19.87904], [100.58808, 20.15791], [100.55218, 20.17741], [100.51052, 20.14928], [100.47567, 20.19133], [100.4537, 20.19971], [100.44992, 20.23644], [100.41473, 20.25625], [100.37439, 20.35156], [100.33383, 20.4028], [100.25769, 20.3992], [100.22076, 20.31598], [100.16668, 20.2986], [100.1712, 20.24324], [100.11785, 20.24787], [100.09337, 20.26293], [100.09999, 20.31614], [100.08404, 20.36626]]]] } },
23324 { type: "Feature", properties: { iso1A2: "TJ", iso1A3: "TJK", iso1N3: "762", wikidata: "Q863", nameEn: "Tajikistan", groups: ["143", "142", "UN"], callingCodes: ["992"] }, geometry: { type: "MultiPolygon", coordinates: [[[[70.45251, 41.04438], [70.38028, 41.02014], [70.36655, 40.90296], [69.69434, 40.62615], [69.59441, 40.70181], [69.53021, 40.77621], [69.38327, 40.7918], [69.32834, 40.70233], [69.3455, 40.57988], [69.2643, 40.57506], [69.21063, 40.54469], [69.27066, 40.49274], [69.28525, 40.41894], [69.30774, 40.36102], [69.33794, 40.34819], [69.32833, 40.29794], [69.30808, 40.2821], [69.24817, 40.30357], [69.25229, 40.26362], [69.30104, 40.24502], [69.30448, 40.18774], [69.2074, 40.21488], [69.15659, 40.2162], [69.04544, 40.22904], [68.85832, 40.20885], [68.84357, 40.18604], [68.79276, 40.17555], [68.77902, 40.20492], [68.5332, 40.14826], [68.52771, 40.11676], [68.62796, 40.07789], [69.01523, 40.15771], [69.01935, 40.11466], [68.96579, 40.06949], [68.84906, 40.04952], [68.93695, 39.91167], [68.88889, 39.87163], [68.63071, 39.85265], [68.61972, 39.68905], [68.54166, 39.53929], [68.12053, 39.56317], [67.70992, 39.66156], [67.62889, 39.60234], [67.44899, 39.57799], [67.46547, 39.53564], [67.39681, 39.52505], [67.46822, 39.46146], [67.45998, 39.315], [67.36522, 39.31287], [67.33226, 39.23739], [67.67833, 39.14479], [67.68915, 39.00775], [68.09704, 39.02589], [68.19743, 38.85985], [68.06948, 38.82115], [68.12877, 38.73677], [68.05598, 38.71641], [68.0807, 38.64136], [68.05873, 38.56087], [68.11366, 38.47169], [68.06274, 38.39435], [68.13289, 38.40822], [68.40343, 38.19484], [68.27159, 37.91477], [68.12635, 37.93], [67.81566, 37.43107], [67.8474, 37.31594], [67.78329, 37.1834], [67.7803, 37.08978], [67.87917, 37.0591], [68.02194, 36.91923], [68.18542, 37.02074], [68.27605, 37.00977], [68.29253, 37.10621], [68.41201, 37.10402], [68.41888, 37.13906], [68.61851, 37.19815], [68.6798, 37.27906], [68.81438, 37.23862], [68.80889, 37.32494], [68.91189, 37.26704], [68.88168, 37.33368], [68.96407, 37.32603], [69.03274, 37.25174], [69.25152, 37.09426], [69.39529, 37.16752], [69.45022, 37.23315], [69.36645, 37.40462], [69.44954, 37.4869], [69.51888, 37.5844], [69.80041, 37.5746], [69.84435, 37.60616], [69.93362, 37.61378], [69.95971, 37.5659], [70.15015, 37.52519], [70.28243, 37.66706], [70.27694, 37.81258], [70.1863, 37.84296], [70.17206, 37.93276], [70.4898, 38.12546], [70.54673, 38.24541], [70.60407, 38.28046], [70.61526, 38.34774], [70.64966, 38.34999], [70.69189, 38.37031], [70.6761, 38.39144], [70.67438, 38.40597], [70.69807, 38.41861], [70.72485, 38.4131], [70.75455, 38.4252], [70.77132, 38.45548], [70.78581, 38.45502], [70.78702, 38.45031], [70.79766, 38.44944], [70.80521, 38.44447], [70.81697, 38.44507], [70.82538, 38.45394], [70.84376, 38.44688], [70.88719, 38.46826], [70.92728, 38.43021], [70.98693, 38.48862], [71.03545, 38.44779], [71.0556, 38.40176], [71.09542, 38.42517], [71.10592, 38.42077], [71.10957, 38.40671], [71.1451, 38.40106], [71.21291, 38.32797], [71.33114, 38.30339], [71.33869, 38.27335], [71.37803, 38.25641], [71.36444, 38.15358], [71.29878, 38.04429], [71.28922, 38.01272], [71.27622, 37.99946], [71.27278, 37.96496], [71.24969, 37.93031], [71.2809, 37.91995], [71.296, 37.93403], [71.32871, 37.88564], [71.51565, 37.95349], [71.58843, 37.92425], [71.59255, 37.79956], [71.55752, 37.78677], [71.54324, 37.77104], [71.53053, 37.76534], [71.55234, 37.73209], [71.54186, 37.69691], [71.51972, 37.61945], [71.5065, 37.60912], [71.49693, 37.53527], [71.50616, 37.50733], [71.5256, 37.47971], [71.49612, 37.4279], [71.47685, 37.40281], [71.4862, 37.33405], [71.49821, 37.31975], [71.50674, 37.31502], [71.48536, 37.26017], [71.4824, 37.24921], [71.48339, 37.23937], [71.47386, 37.2269], [71.4555, 37.21418], [71.4494, 37.18137], [71.44127, 37.11856], [71.43097, 37.05855], [71.45578, 37.03094], [71.46923, 36.99925], [71.48481, 36.93218], [71.51502, 36.89128], [71.57195, 36.74943], [71.67083, 36.67346], [71.83229, 36.68084], [72.31676, 36.98115], [72.54095, 37.00007], [72.66381, 37.02014], [72.79693, 37.22222], [73.06884, 37.31729], [73.29633, 37.46495], [73.77197, 37.4417], [73.76647, 37.33913], [73.61129, 37.27469], [73.64974, 37.23643], [73.82552, 37.22659], [73.8564, 37.26158], [74.20308, 37.34208], [74.23339, 37.41116], [74.41055, 37.3948], [74.56161, 37.37734], [74.68383, 37.3948], [74.8294, 37.3435], [74.88887, 37.23275], [75.12328, 37.31839], [75.09719, 37.37297], [75.15899, 37.41443], [75.06011, 37.52779], [74.94338, 37.55501], [74.8912, 37.67576], [75.00935, 37.77486], [74.92416, 37.83428], [74.9063, 38.03033], [74.82665, 38.07359], [74.80331, 38.19889], [74.69894, 38.22155], [74.69619, 38.42947], [74.51217, 38.47034], [74.17022, 38.65504], [73.97933, 38.52945], [73.79806, 38.61106], [73.80656, 38.66449], [73.7033, 38.84782], [73.7445, 38.93867], [73.82964, 38.91517], [73.81728, 39.04007], [73.75823, 39.023], [73.60638, 39.24534], [73.54572, 39.27567], [73.55396, 39.3543], [73.5004, 39.38402], [73.59241, 39.40843], [73.59831, 39.46425], [73.45096, 39.46677], [73.31912, 39.38615], [73.18454, 39.35536], [72.85934, 39.35116], [72.62027, 39.39696], [72.33173, 39.33093], [72.23834, 39.17248], [72.17242, 39.2661], [72.09689, 39.26823], [72.04059, 39.36704], [71.90601, 39.27674], [71.79202, 39.27355], [71.7522, 39.32031], [71.80164, 39.40631], [71.76816, 39.45456], [71.62688, 39.44056], [71.5517, 39.45722], [71.55856, 39.57588], [71.49814, 39.61397], [71.08752, 39.50704], [71.06418, 39.41586], [70.7854, 39.38933], [70.64087, 39.58792], [70.44757, 39.60128], [70.2869, 39.53141], [70.11111, 39.58223], [69.87491, 39.53882], [69.68677, 39.59281], [69.3594, 39.52516], [69.26938, 39.8127], [69.35649, 40.01994], [69.43134, 39.98431], [69.43557, 39.92877], [69.53615, 39.93991], [69.5057, 40.03277], [69.53855, 40.0887], [69.53794, 40.11833], [69.55555, 40.12296], [69.57615, 40.10524], [69.64704, 40.12165], [69.67001, 40.10639], [70.01283, 40.23288], [70.58297, 40.00891], [70.57384, 39.99394], [70.47557, 39.93216], [70.55033, 39.96619], [70.58912, 39.95211], [70.65946, 39.9878], [70.65827, 40.0981], [70.7928, 40.12797], [70.80495, 40.16813], [70.9818, 40.22392], [70.8607, 40.217], [70.62342, 40.17396], [70.56394, 40.26421], [70.57149, 40.3442], [70.37511, 40.38605], [70.32626, 40.45174], [70.49871, 40.52503], [70.80009, 40.72825], [70.45251, 41.04438]]], [[[70.68112, 40.90612], [70.6158, 40.97661], [70.56077, 41.00642], [70.54223, 40.98787], [70.57501, 40.98941], [70.6721, 40.90555], [70.68112, 40.90612]]], [[[70.74189, 39.86319], [70.53651, 39.89155], [70.52631, 39.86989], [70.54998, 39.85137], [70.59667, 39.83542], [70.63105, 39.77923], [70.74189, 39.86319]]]] } },
23325 { type: "Feature", properties: { iso1A2: "TK", iso1A3: "TKL", iso1N3: "772", wikidata: "Q36823", nameEn: "Tokelau", country: "NZ", groups: ["061", "009", "UN"], driveSide: "left", callingCodes: ["690"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-168.251, -9.44289], [-174.18635, -7.80441], [-174.17993, -10.13616], [-168.251, -9.44289]]]] } },
23326 { type: "Feature", properties: { iso1A2: "TL", iso1A3: "TLS", iso1N3: "626", wikidata: "Q574", nameEn: "East Timor", aliases: ["Timor-Leste", "TP"], groups: ["035", "142", "UN"], driveSide: "left", callingCodes: ["670"] }, geometry: { type: "MultiPolygon", coordinates: [[[[124.46701, -9.13002], [124.94011, -8.85617], [124.97742, -9.08128], [125.11764, -8.96359], [125.18632, -9.03142], [125.18907, -9.16434], [125.09434, -9.19669], [125.04044, -9.17093], [124.97892, -9.19281], [125.09025, -9.46406], [125.68138, -9.85176], [127.55165, -9.05052], [127.42116, -8.22471], [125.87691, -8.31789], [125.58506, -7.95311], [124.92337, -8.75859], [124.33472, -9.11416], [124.04628, -9.22671], [124.04286, -9.34243], [124.10539, -9.41206], [124.14517, -9.42324], [124.21247, -9.36904], [124.28115, -9.42189], [124.28115, -9.50453], [124.3535, -9.48493], [124.35258, -9.43002], [124.38554, -9.3582], [124.45971, -9.30263], [124.46701, -9.13002]]]] } },
23327 { type: "Feature", properties: { iso1A2: "TM", iso1A3: "TKM", iso1N3: "795", wikidata: "Q874", nameEn: "Turkmenistan", groups: ["143", "142", "UN"], callingCodes: ["993"] }, geometry: { type: "MultiPolygon", coordinates: [[[[60.5078, 41.21694], [60.06581, 41.4363], [60.18117, 41.60082], [60.06032, 41.76287], [60.08504, 41.80997], [60.33223, 41.75058], [59.95046, 41.97966], [60.0356, 42.01028], [60.04659, 42.08982], [59.96419, 42.1428], [60.00539, 42.212], [59.94633, 42.27655], [59.4341, 42.29738], [59.2955, 42.37064], [59.17317, 42.52248], [58.93422, 42.5407], [58.6266, 42.79314], [58.57991, 42.64988], [58.27504, 42.69632], [58.14321, 42.62159], [58.29427, 42.56497], [58.51674, 42.30348], [58.40688, 42.29535], [58.3492, 42.43335], [57.99214, 42.50021], [57.90975, 42.4374], [57.92897, 42.24047], [57.84932, 42.18555], [57.6296, 42.16519], [57.30275, 42.14076], [57.03633, 41.92043], [56.96218, 41.80383], [57.03359, 41.41777], [57.13796, 41.36625], [57.03423, 41.25435], [56.00314, 41.32584], [55.45471, 41.25609], [54.95182, 41.92424], [54.20635, 42.38477], [52.97575, 42.1308], [52.47884, 41.78034], [52.26048, 41.69249], [51.7708, 40.29239], [53.89734, 37.3464], [54.24565, 37.32047], [54.36211, 37.34912], [54.58664, 37.45809], [54.67247, 37.43532], [54.77822, 37.51597], [54.81804, 37.61285], [54.77684, 37.62264], [54.851, 37.75739], [55.13412, 37.94705], [55.44152, 38.08564], [55.76561, 38.12238], [55.97847, 38.08024], [56.33278, 38.08132], [56.32454, 38.18502], [56.43303, 38.26054], [56.62255, 38.24005], [56.73928, 38.27887], [57.03453, 38.18717], [57.21169, 38.28965], [57.37236, 38.09321], [57.35042, 37.98546], [57.79534, 37.89299], [58.21399, 37.77281], [58.22999, 37.6856], [58.39959, 37.63134], [58.47786, 37.6433], [58.5479, 37.70526], [58.6921, 37.64548], [58.9338, 37.67374], [59.22905, 37.51161], [59.33507, 37.53146], [59.39797, 37.47892], [59.39385, 37.34257], [59.55178, 37.13594], [59.74678, 37.12499], [60.00768, 37.04102], [60.34767, 36.63214], [61.14516, 36.64644], [61.18187, 36.55348], [61.1393, 36.38782], [61.22719, 36.12759], [61.12007, 35.95992], [61.22444, 35.92879], [61.26152, 35.80749], [61.22719, 35.67038], [61.27371, 35.61482], [61.58742, 35.43803], [61.77693, 35.41341], [61.97743, 35.4604], [62.05709, 35.43803], [62.15871, 35.33278], [62.29191, 35.25964], [62.29878, 35.13312], [62.48006, 35.28796], [62.62288, 35.22067], [62.74098, 35.25432], [62.90853, 35.37086], [63.0898, 35.43131], [63.12276, 35.53196], [63.10079, 35.63024], [63.23262, 35.67487], [63.10318, 35.81782], [63.12276, 35.86208], [63.29579, 35.85985], [63.53475, 35.90881], [63.56496, 35.95106], [63.98519, 36.03773], [64.05385, 36.10433], [64.43288, 36.24401], [64.57295, 36.34362], [64.62514, 36.44311], [64.61141, 36.6351], [64.97945, 37.21913], [65.51778, 37.23881], [65.64263, 37.34388], [65.64137, 37.45061], [65.72274, 37.55438], [66.30993, 37.32409], [66.55743, 37.35409], [66.52303, 37.39827], [66.65761, 37.45497], [66.52852, 37.58568], [66.53676, 37.80084], [66.67684, 37.96776], [66.56697, 38.0435], [66.41042, 38.02403], [66.24013, 38.16238], [65.83913, 38.25733], [65.55873, 38.29052], [64.32576, 38.98691], [64.19086, 38.95561], [63.70778, 39.22349], [63.6913, 39.27666], [62.43337, 39.98528], [62.34273, 40.43206], [62.11751, 40.58242], [61.87856, 41.12257], [61.4446, 41.29407], [61.39732, 41.19873], [61.33199, 41.14946], [61.22212, 41.14946], [61.03261, 41.25691], [60.5078, 41.21694]]]] } },
23328 { type: "Feature", properties: { iso1A2: "TN", iso1A3: "TUN", iso1N3: "788", wikidata: "Q948", nameEn: "Tunisia", groups: ["015", "002", "UN"], callingCodes: ["216"] }, geometry: { type: "MultiPolygon", coordinates: [[[[11.2718, 37.6713], [7.89009, 38.19924], [8.59123, 37.14286], [8.64044, 36.9401], [8.62972, 36.86499], [8.67706, 36.8364], [8.57613, 36.78062], [8.46537, 36.7706], [8.47609, 36.66607], [8.16167, 36.48817], [8.18936, 36.44939], [8.40731, 36.42208], [8.2626, 35.91733], [8.26472, 35.73669], [8.35371, 35.66373], [8.36086, 35.47774], [8.30329, 35.29884], [8.47318, 35.23376], [8.3555, 35.10007], [8.30727, 34.95378], [8.25189, 34.92009], [8.29655, 34.72798], [8.20482, 34.57575], [7.86264, 34.3987], [7.81242, 34.21841], [7.74207, 34.16492], [7.66174, 34.20167], [7.52851, 34.06493], [7.54088, 33.7726], [7.73687, 33.42114], [7.83028, 33.18851], [8.11433, 33.10175], [8.1179, 33.05086], [8.31895, 32.83483], [8.35999, 32.50101], [9.07483, 32.07865], [9.55544, 30.23971], [9.76848, 30.34366], [9.88152, 30.34074], [10.29516, 30.90337], [10.12239, 31.42098], [10.31364, 31.72648], [10.48497, 31.72956], [10.62788, 31.96629], [10.7315, 31.97235], [11.04234, 32.2145], [11.53898, 32.4138], [11.57828, 32.48013], [11.46037, 32.6307], [11.51549, 33.09826], [11.55852, 33.1409], [11.58941, 33.36891], [11.2718, 37.6713]]]] } },
23329 { type: "Feature", properties: { iso1A2: "TO", iso1A3: "TON", iso1N3: "776", wikidata: "Q678", nameEn: "Tonga", groups: ["061", "009", "UN"], driveSide: "left", callingCodes: ["676"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-176.74538, -22.89767], [-180, -22.90585], [-180, -24.21376], [-173.10761, -24.19665], [-173.13438, -14.94228], [-176.76826, -14.95183], [-176.74538, -22.89767]]]] } },
23330 { type: "Feature", properties: { iso1A2: "TR", iso1A3: "TUR", iso1N3: "792", wikidata: "Q43", nameEn: "Turkey", groups: ["145", "142", "UN"], callingCodes: ["90"] }, geometry: { type: "MultiPolygon", coordinates: [[[[41.54366, 41.52185], [40.89217, 41.72528], [34.8305, 42.4581], [28.32297, 41.98371], [28.02971, 41.98066], [27.91479, 41.97902], [27.83492, 41.99709], [27.81235, 41.94803], [27.69949, 41.97515], [27.55191, 41.90928], [27.52379, 41.93756], [27.45478, 41.96591], [27.27411, 42.10409], [27.22376, 42.10152], [27.19251, 42.06028], [27.08486, 42.08735], [27.03277, 42.0809], [26.95638, 42.00741], [26.79143, 41.97386], [26.62996, 41.97644], [26.56051, 41.92995], [26.57961, 41.90024], [26.53968, 41.82653], [26.36952, 41.82265], [26.33589, 41.76802], [26.32952, 41.73637], [26.35957, 41.71149], [26.47958, 41.67037], [26.5209, 41.62592], [26.59196, 41.60491], [26.59742, 41.48058], [26.61767, 41.42281], [26.62997, 41.34613], [26.5837, 41.32131], [26.5209, 41.33993], [26.39861, 41.25053], [26.32259, 41.24929], [26.31928, 41.07386], [26.3606, 41.02027], [26.33297, 40.98388], [26.35894, 40.94292], [26.32259, 40.94042], [26.28623, 40.93005], [26.29441, 40.89119], [26.26169, 40.9168], [26.20856, 40.86048], [26.21351, 40.83298], [26.15685, 40.80709], [26.12854, 40.77339], [26.12495, 40.74283], [26.08638, 40.73214], [26.0754, 40.72772], [26.03489, 40.73051], [25.94795, 40.72797], [26.04292, 40.3958], [25.61285, 40.17161], [25.94257, 39.39358], [26.43357, 39.43096], [26.70773, 39.0312], [26.61814, 38.81372], [26.21136, 38.65436], [26.32173, 38.48731], [26.24183, 38.44695], [26.21136, 38.17558], [27.05537, 37.9131], [27.16428, 37.72343], [26.99377, 37.69034], [26.95583, 37.64989], [27.14757, 37.32], [27.20312, 36.94571], [27.45627, 36.9008], [27.24613, 36.71622], [27.46117, 36.53789], [27.89482, 36.69898], [27.95037, 36.46155], [28.23708, 36.56812], [29.30783, 36.01033], [29.48192, 36.18377], [29.61002, 36.1731], [29.61805, 36.14179], [29.69611, 36.10365], [29.73302, 35.92555], [32.82353, 35.70297], [35.51152, 36.10954], [35.931, 35.92109], [35.98499, 35.94107], [36.00514, 35.94113], [36.01844, 35.92403], [35.99829, 35.88242], [36.11827, 35.85923], [36.13919, 35.83692], [36.14029, 35.81015], [36.1623, 35.80925], [36.17441, 35.92076], [36.19973, 35.95195], [36.25366, 35.96264], [36.27678, 35.94839], [36.29769, 35.96086], [36.28338, 36.00273], [36.30099, 36.00985], [36.33956, 35.98687], [36.37474, 36.01163], [36.39206, 36.22088], [36.4617, 36.20461], [36.50463, 36.2419], [36.6125, 36.22592], [36.68672, 36.23677], [36.65653, 36.33861], [36.6081, 36.33772], [36.54206, 36.49539], [36.58829, 36.58295], [36.57398, 36.65186], [36.62681, 36.71189], [36.61581, 36.74629], [36.66727, 36.82901], [36.99557, 36.75997], [36.99886, 36.74012], [37.04399, 36.73483], [37.04619, 36.71101], [37.01647, 36.69512], [37.02088, 36.66422], [37.08279, 36.63495], [37.10894, 36.6704], [37.16177, 36.66069], [37.21988, 36.6736], [37.47253, 36.63243], [37.49103, 36.66904], [37.68048, 36.75065], [37.81974, 36.76055], [38.21064, 36.91842], [38.38859, 36.90064], [38.55908, 36.84429], [38.74042, 36.70629], [39.03217, 36.70911], [39.21538, 36.66834], [39.81589, 36.75538], [40.69136, 37.0996], [40.90856, 37.13147], [41.21937, 37.07665], [41.515, 37.08084], [42.00894, 37.17209], [42.18225, 37.28569], [42.19301, 37.31323], [42.2112, 37.32491], [42.22257, 37.31395], [42.22381, 37.30238], [42.20454, 37.28715], [42.21548, 37.28026], [42.23683, 37.2863], [42.26039, 37.27017], [42.2824, 37.2798], [42.34735, 37.22548], [42.32313, 37.17814], [42.35724, 37.10998], [42.56725, 37.14878], [42.78887, 37.38615], [42.93705, 37.32015], [43.11403, 37.37436], [43.30083, 37.30629], [43.33508, 37.33105], [43.50787, 37.24436], [43.56702, 37.25675], [43.63085, 37.21957], [43.7009, 37.23692], [43.8052, 37.22825], [43.82699, 37.19477], [43.84878, 37.22205], [43.90949, 37.22453], [44.02002, 37.33229], [44.13521, 37.32486], [44.2613, 37.25055], [44.27998, 37.16501], [44.22239, 37.15756], [44.18503, 37.09551], [44.25975, 36.98119], [44.30645, 36.97373], [44.35937, 37.02843], [44.35315, 37.04955], [44.38117, 37.05825], [44.42631, 37.05825], [44.63179, 37.19229], [44.76698, 37.16162], [44.78319, 37.1431], [44.7868, 37.16644], [44.75986, 37.21549], [44.81021, 37.2915], [44.58449, 37.45018], [44.61401, 37.60165], [44.56887, 37.6429], [44.62096, 37.71985], [44.55498, 37.783], [44.45948, 37.77065], [44.3883, 37.85433], [44.22509, 37.88859], [44.42476, 38.25763], [44.50115, 38.33939], [44.44386, 38.38295], [44.38309, 38.36117], [44.3119, 38.37887], [44.3207, 38.49799], [44.32058, 38.62752], [44.28065, 38.6465], [44.26155, 38.71427], [44.30322, 38.81581], [44.18863, 38.93881], [44.20946, 39.13975], [44.1043, 39.19842], [44.03667, 39.39223], [44.22452, 39.4169], [44.29818, 39.378], [44.37921, 39.4131], [44.42832, 39.4131], [44.41849, 39.56659], [44.48111, 39.61579], [44.47298, 39.68788], [44.6137, 39.78393], [44.65422, 39.72163], [44.71806, 39.71124], [44.81043, 39.62677], [44.80977, 39.65768], [44.75779, 39.7148], [44.61845, 39.8281], [44.46635, 39.97733], [44.26973, 40.04866], [44.1778, 40.02845], [44.1057, 40.03555], [43.92307, 40.01787], [43.65688, 40.11199], [43.65221, 40.14889], [43.71136, 40.16673], [43.59928, 40.34019], [43.60862, 40.43267], [43.54791, 40.47413], [43.63664, 40.54159], [43.7425, 40.66805], [43.74872, 40.7365], [43.67712, 40.84846], [43.67712, 40.93084], [43.58683, 40.98961], [43.47319, 41.02251], [43.44984, 41.0988], [43.4717, 41.12611], [43.44973, 41.17666], [43.36118, 41.2028], [43.23096, 41.17536], [43.1945, 41.25242], [43.13373, 41.25503], [43.21707, 41.30331], [43.02956, 41.37891], [42.8785, 41.50516], [42.84899, 41.47265], [42.78995, 41.50126], [42.84471, 41.58912], [42.72794, 41.59714], [42.59202, 41.58183], [42.51772, 41.43606], [42.26387, 41.49346], [41.95134, 41.52466], [41.81939, 41.43621], [41.7124, 41.47417], [41.7148, 41.4932], [41.54366, 41.52185]]]] } },
23331 { type: "Feature", properties: { iso1A2: "TT", iso1A3: "TTO", iso1N3: "780", wikidata: "Q754", nameEn: "Trinidad and Tobago", groups: ["029", "003", "419", "019", "UN"], driveSide: "left", callingCodes: ["1 868"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-61.62505, 11.18974], [-62.08693, 10.04435], [-60.89962, 9.81445], [-60.07172, 11.77667], [-61.62505, 11.18974]]]] } },
23332 { type: "Feature", properties: { iso1A2: "TV", iso1A3: "TUV", iso1N3: "798", wikidata: "Q672", nameEn: "Tuvalu", groups: ["061", "009", "UN"], driveSide: "left", callingCodes: ["688"] }, geometry: { type: "MultiPolygon", coordinates: [[[[174, -5], [174, -11.5], [179.99999, -11.5], [179.99999, -5], [174, -5]]]] } },
23333 { type: "Feature", properties: { iso1A2: "TW", iso1A3: "TWN", iso1N3: "158", wikidata: "Q865", nameEn: "Taiwan", aliases: ["RC"], groups: ["030", "142"], callingCodes: ["886"] }, geometry: { type: "MultiPolygon", coordinates: [[[[121.8109, 21.77688], [122.26612, 25.98197], [120.49232, 25.22863], [118.56434, 24.49266], [118.42453, 24.54644], [118.35291, 24.51645], [118.28244, 24.51231], [118.11703, 24.39734], [120.69238, 21.52331], [121.8109, 21.77688]]]] } },
23334 { type: "Feature", properties: { iso1A2: "TZ", iso1A3: "TZA", iso1N3: "834", wikidata: "Q924", nameEn: "Tanzania", groups: ["014", "202", "002", "UN"], driveSide: "left", callingCodes: ["255"] }, geometry: { type: "MultiPolygon", coordinates: [[[[30.80408, -0.99911], [30.76635, -0.9852], [30.70631, -1.01175], [30.64166, -1.06601], [30.47194, -1.0555], [30.45116, -1.10641], [30.50889, -1.16412], [30.57123, -1.33264], [30.71974, -1.43244], [30.84079, -1.64652], [30.80802, -1.91477], [30.89303, -2.08223], [30.83915, -2.35795], [30.54501, -2.41404], [30.41789, -2.66266], [30.52747, -2.65841], [30.40662, -2.86151], [30.4987, -2.9573], [30.57926, -2.89791], [30.6675, -2.98987], [30.83823, -2.97837], [30.84165, -3.25152], [30.45915, -3.56532], [30.22042, -4.01738], [30.03323, -4.26631], [29.88172, -4.35743], [29.82885, -4.36153], [29.77289, -4.41733], [29.75109, -4.45836], [29.63827, -4.44681], [29.43673, -4.44845], [29.52552, -6.2731], [30.2567, -7.14121], [30.79243, -8.27382], [31.00796, -8.58615], [31.37533, -8.60769], [31.57147, -8.70619], [31.57147, -8.81388], [31.71158, -8.91386], [31.81587, -8.88618], [31.94663, -8.93846], [31.94196, -9.02303], [31.98866, -9.07069], [32.08206, -9.04609], [32.16146, -9.05993], [32.25486, -9.13371], [32.43543, -9.11988], [32.49147, -9.14754], [32.53661, -9.24281], [32.75611, -9.28583], [32.76233, -9.31963], [32.95389, -9.40138], [32.99397, -9.36712], [33.14925, -9.49322], [33.31581, -9.48554], [33.48052, -9.62442], [33.76677, -9.58516], [33.93298, -9.71647], [33.9638, -9.62206], [33.95829, -9.54066], [34.03865, -9.49398], [34.54499, -10.0678], [34.51911, -10.12279], [34.57581, -10.56271], [34.65946, -10.6828], [34.67047, -10.93796], [34.61161, -11.01611], [34.63305, -11.11731], [34.79375, -11.32245], [34.91153, -11.39799], [34.96296, -11.57354], [35.63599, -11.55927], [35.82767, -11.41081], [36.19094, -11.57593], [36.19094, -11.70008], [36.62068, -11.72884], [36.80309, -11.56836], [37.3936, -11.68949], [37.76614, -11.53352], [37.8388, -11.3123], [37.93618, -11.26228], [38.21598, -11.27289], [38.47258, -11.4199], [38.88996, -11.16978], [39.24395, -11.17433], [39.58249, -10.96043], [40.00295, -10.80255], [40.44265, -10.4618], [40.74206, -10.25691], [40.14328, -4.64201], [39.62121, -4.68136], [39.44306, -4.93877], [39.21631, -4.67835], [37.81321, -3.69179], [37.75036, -3.54243], [37.63099, -3.50723], [37.5903, -3.42735], [37.71745, -3.304], [37.67199, -3.06222], [34.0824, -1.02264], [34.03084, -1.05101], [34.02286, -1.00779], [33.93107, -0.99298], [30.80408, -0.99911]]]] } },
23335 { type: "Feature", properties: { iso1A2: "UA", iso1A3: "UKR", iso1N3: "804", wikidata: "Q212", nameEn: "Ukraine", groups: ["151", "150", "UN"], callingCodes: ["380"] }, geometry: { type: "MultiPolygon", coordinates: [[[[33.57318, 46.10317], [33.61467, 46.13561], [33.63854, 46.14147], [33.61517, 46.22615], [33.646, 46.23028], [33.74047, 46.18555], [33.79715, 46.20482], [33.85234, 46.19863], [33.91549, 46.15938], [34.05272, 46.10838], [34.07311, 46.11769], [34.12929, 46.10494], [34.181, 46.06804], [34.25111, 46.0532], [34.33912, 46.06114], [34.41221, 46.00245], [34.44155, 45.95995], [34.48729, 45.94267], [34.52011, 45.95097], [34.55889, 45.99347], [34.60861, 45.99347], [34.66679, 45.97136], [34.75479, 45.90705], [34.80153, 45.90047], [34.79905, 45.81009], [34.96015, 45.75634], [35.23066, 45.79231], [37.62608, 46.82615], [38.12112, 46.86078], [38.3384, 46.98085], [38.22955, 47.12069], [38.23049, 47.2324], [38.32112, 47.2585], [38.33074, 47.30508], [38.22225, 47.30788], [38.28954, 47.39255], [38.28679, 47.53552], [38.35062, 47.61631], [38.76379, 47.69346], [38.79628, 47.81109], [38.87979, 47.87719], [39.73935, 47.82876], [39.82213, 47.96396], [39.77544, 48.04206], [39.88256, 48.04482], [39.83724, 48.06501], [39.94847, 48.22811], [40.00752, 48.22445], [39.99241, 48.31768], [39.97325, 48.31399], [39.9693, 48.29904], [39.95248, 48.29972], [39.91465, 48.26743], [39.90041, 48.3049], [39.84273, 48.30947], [39.84136, 48.33321], [39.94847, 48.35055], [39.88794, 48.44226], [39.86196, 48.46633], [39.84548, 48.57821], [39.79764, 48.58668], [39.67226, 48.59368], [39.71765, 48.68673], [39.73104, 48.7325], [39.79466, 48.83739], [39.97182, 48.79398], [40.08168, 48.87443], [40.03636, 48.91957], [39.98967, 48.86901], [39.78368, 48.91596], [39.74874, 48.98675], [39.72649, 48.9754], [39.71353, 48.98959], [39.6683, 48.99454], [39.6836, 49.05121], [39.93437, 49.05709], [40.01988, 49.1761], [40.22176, 49.25683], [40.18331, 49.34996], [40.14912, 49.37681], [40.1141, 49.38798], [40.03087, 49.45452], [40.03636, 49.52321], [40.16683, 49.56865], [40.13249, 49.61672], [39.84548, 49.56064], [39.65047, 49.61761], [39.59142, 49.73758], [39.44496, 49.76067], [39.27968, 49.75976], [39.1808, 49.88911], [38.9391, 49.79524], [38.90477, 49.86787], [38.73311, 49.90238], [38.68677, 50.00904], [38.65688, 49.97176], [38.35408, 50.00664], [38.32524, 50.08866], [38.18517, 50.08161], [38.21675, 49.98104], [38.02999, 49.90592], [38.02999, 49.94482], [37.90776, 50.04194], [37.79515, 50.08425], [37.75807, 50.07896], [37.61113, 50.21976], [37.62879, 50.24481], [37.62486, 50.29966], [37.47243, 50.36277], [37.48204, 50.46079], [37.08468, 50.34935], [36.91762, 50.34963], [36.69377, 50.26982], [36.64571, 50.218], [36.56655, 50.2413], [36.58371, 50.28563], [36.47817, 50.31457], [36.30101, 50.29088], [36.20763, 50.3943], [36.06893, 50.45205], [35.8926, 50.43829], [35.80388, 50.41356], [35.73659, 50.35489], [35.61711, 50.35707], [35.58003, 50.45117], [35.47463, 50.49247], [35.39464, 50.64751], [35.48116, 50.66405], [35.47704, 50.77274], [35.41367, 50.80227], [35.39307, 50.92145], [35.32598, 50.94524], [35.40837, 51.04119], [35.31774, 51.08434], [35.20375, 51.04723], [35.12685, 51.16191], [35.14058, 51.23162], [34.97304, 51.2342], [34.82472, 51.17483], [34.6874, 51.18], [34.6613, 51.25053], [34.38802, 51.2746], [34.31661, 51.23936], [34.23009, 51.26429], [34.33446, 51.363], [34.22048, 51.4187], [34.30562, 51.5205], [34.17599, 51.63253], [34.07765, 51.67065], [34.42922, 51.72852], [34.41136, 51.82793], [34.09413, 52.00835], [34.11199, 52.14087], [34.05239, 52.20132], [33.78789, 52.37204], [33.55718, 52.30324], [33.48027, 52.31499], [33.51323, 52.35779], [33.18913, 52.3754], [32.89937, 52.2461], [32.85405, 52.27888], [32.69475, 52.25535], [32.54781, 52.32423], [32.3528, 52.32842], [32.38988, 52.24946], [32.33083, 52.23685], [32.34044, 52.1434], [32.2777, 52.10266], [32.23331, 52.08085], [32.08813, 52.03319], [31.92159, 52.05144], [31.96141, 52.08015], [31.85018, 52.11305], [31.81722, 52.09955], [31.7822, 52.11406], [31.38326, 52.12991], [31.25142, 52.04131], [31.13332, 52.1004], [30.95589, 52.07775], [30.90897, 52.00699], [30.76443, 51.89739], [30.68804, 51.82806], [30.51946, 51.59649], [30.64992, 51.35014], [30.56203, 51.25655], [30.36153, 51.33984], [30.34642, 51.42555], [30.17888, 51.51025], [29.77376, 51.4461], [29.7408, 51.53417], [29.54372, 51.48372], [29.49773, 51.39814], [29.42357, 51.4187], [29.32881, 51.37843], [29.25191, 51.49828], [29.25603, 51.57089], [29.20659, 51.56918], [29.16402, 51.64679], [29.1187, 51.65872], [28.99098, 51.56833], [28.95528, 51.59222], [28.81795, 51.55552], [28.76027, 51.48802], [28.78224, 51.45294], [28.75615, 51.41442], [28.73143, 51.46236], [28.69161, 51.44695], [28.64429, 51.5664], [28.47051, 51.59734], [28.37592, 51.54505], [28.23452, 51.66988], [28.10658, 51.57857], [27.95827, 51.56065], [27.91844, 51.61952], [27.85253, 51.62293], [27.76052, 51.47604], [27.67125, 51.50854], [27.71932, 51.60672], [27.55727, 51.63486], [27.51058, 51.5854], [27.47212, 51.61184], [27.24828, 51.60161], [27.26613, 51.65957], [27.20948, 51.66713], [27.20602, 51.77291], [26.99422, 51.76933], [26.9489, 51.73788], [26.80043, 51.75777], [26.69759, 51.82284], [26.46962, 51.80501], [26.39367, 51.87315], [26.19084, 51.86781], [26.00408, 51.92967], [25.83217, 51.92587], [25.80574, 51.94556], [25.73673, 51.91973], [25.46163, 51.92205], [25.20228, 51.97143], [24.98784, 51.91273], [24.37123, 51.88222], [24.29021, 51.80841], [24.3163, 51.75063], [24.13075, 51.66979], [23.99907, 51.58369], [23.8741, 51.59734], [23.91118, 51.63316], [23.7766, 51.66809], [23.60906, 51.62122], [23.6736, 51.50255], [23.62751, 51.50512], [23.69905, 51.40871], [23.63858, 51.32182], [23.80678, 51.18405], [23.90376, 51.07697], [23.92217, 51.00836], [24.04576, 50.90196], [24.14524, 50.86128], [24.0952, 50.83262], [23.99254, 50.83847], [23.95925, 50.79271], [24.0595, 50.71625], [24.0996, 50.60752], [24.07048, 50.5071], [24.03668, 50.44507], [23.99563, 50.41289], [23.79445, 50.40481], [23.71382, 50.38248], [23.67635, 50.33385], [23.28221, 50.0957], [22.99329, 49.84249], [22.83179, 49.69875], [22.80261, 49.69098], [22.78304, 49.65543], [22.64534, 49.53094], [22.69444, 49.49378], [22.748, 49.32759], [22.72009, 49.20288], [22.86336, 49.10513], [22.89122, 49.00725], [22.56155, 49.08865], [22.54338, 49.01424], [22.48296, 48.99172], [22.42934, 48.92857], [22.34151, 48.68893], [22.21379, 48.6218], [22.16023, 48.56548], [22.14689, 48.4005], [22.2083, 48.42534], [22.38133, 48.23726], [22.49806, 48.25189], [22.59007, 48.15121], [22.58733, 48.10813], [22.66835, 48.09162], [22.73427, 48.12005], [22.81804, 48.11363], [22.87847, 48.04665], [22.84276, 47.98602], [22.89849, 47.95851], [22.94301, 47.96672], [22.92241, 48.02002], [23.0158, 47.99338], [23.08858, 48.00716], [23.1133, 48.08061], [23.15999, 48.12188], [23.27397, 48.08245], [23.33577, 48.0237], [23.4979, 47.96858], [23.52803, 48.01818], [23.5653, 48.00499], [23.63894, 48.00293], [23.66262, 47.98786], [23.75188, 47.99705], [23.80904, 47.98142], [23.8602, 47.9329], [23.89352, 47.94512], [23.94192, 47.94868], [23.96337, 47.96672], [23.98553, 47.96076], [24.00801, 47.968], [24.02999, 47.95087], [24.06466, 47.95317], [24.11281, 47.91487], [24.22566, 47.90231], [24.34926, 47.9244], [24.43578, 47.97131], [24.61994, 47.95062], [24.70632, 47.84428], [24.81893, 47.82031], [24.88896, 47.7234], [25.11144, 47.75203], [25.23778, 47.89403], [25.63878, 47.94924], [25.77723, 47.93919], [26.05901, 47.9897], [26.17711, 47.99246], [26.33504, 48.18418], [26.55202, 48.22445], [26.62823, 48.25804], [26.6839, 48.35828], [26.79239, 48.29071], [26.82809, 48.31629], [26.71274, 48.40388], [26.85556, 48.41095], [26.93384, 48.36558], [27.03821, 48.37653], [27.0231, 48.42485], [27.08078, 48.43214], [27.13434, 48.37288], [27.27855, 48.37534], [27.32159, 48.4434], [27.37604, 48.44398], [27.37741, 48.41026], [27.44333, 48.41209], [27.46942, 48.454], [27.5889, 48.49224], [27.59027, 48.46311], [27.6658, 48.44034], [27.74422, 48.45926], [27.79225, 48.44244], [27.81902, 48.41874], [27.87533, 48.4037], [27.88391, 48.36699], [27.95883, 48.32368], [28.04527, 48.32661], [28.09873, 48.3124], [28.07504, 48.23494], [28.17666, 48.25963], [28.19314, 48.20749], [28.2856, 48.23202], [28.32508, 48.23384], [28.35519, 48.24957], [28.36996, 48.20543], [28.34912, 48.1787], [28.30586, 48.1597], [28.30609, 48.14018], [28.34009, 48.13147], [28.38712, 48.17567], [28.43701, 48.15832], [28.42454, 48.12047], [28.48428, 48.0737], [28.53921, 48.17453], [28.69896, 48.13106], [28.85232, 48.12506], [28.8414, 48.03392], [28.9306, 47.96255], [29.1723, 47.99013], [29.19839, 47.89261], [29.27804, 47.88893], [29.20663, 47.80367], [29.27255, 47.79953], [29.22242, 47.73607], [29.22414, 47.60012], [29.11743, 47.55001], [29.18603, 47.43387], [29.3261, 47.44664], [29.39889, 47.30179], [29.47854, 47.30366], [29.48678, 47.36043], [29.5733, 47.36508], [29.59665, 47.25521], [29.54996, 47.24962], [29.57696, 47.13581], [29.49732, 47.12878], [29.53044, 47.07851], [29.61038, 47.09932], [29.62137, 47.05069], [29.57056, 46.94766], [29.72986, 46.92234], [29.75458, 46.8604], [29.87405, 46.88199], [29.98814, 46.82358], [29.94522, 46.80055], [29.9743, 46.75325], [29.94409, 46.56002], [29.88916, 46.54302], [30.02511, 46.45132], [30.16794, 46.40967], [30.09103, 46.38694], [29.94114, 46.40114], [29.88329, 46.35851], [29.74496, 46.45605], [29.66359, 46.4215], [29.6763, 46.36041], [29.5939, 46.35472], [29.49914, 46.45889], [29.35357, 46.49505], [29.24886, 46.37912], [29.23547, 46.55435], [29.02409, 46.49582], [29.01241, 46.46177], [28.9306, 46.45699], [29.004, 46.31495], [28.98478, 46.31803], [28.94953, 46.25852], [29.06656, 46.19716], [28.94643, 46.09176], [29.00613, 46.04962], [28.98004, 46.00385], [28.74383, 45.96664], [28.78503, 45.83475], [28.69852, 45.81753], [28.70401, 45.78019], [28.52823, 45.73803], [28.47879, 45.66994], [28.51587, 45.6613], [28.54196, 45.58062], [28.49252, 45.56716], [28.51449, 45.49982], [28.43072, 45.48538], [28.41836, 45.51715], [28.30201, 45.54744], [28.21139, 45.46895], [28.28504, 45.43907], [28.34554, 45.32102], [28.5735, 45.24759], [28.71358, 45.22631], [28.78911, 45.24179], [28.81383, 45.3384], [28.94292, 45.28045], [28.96077, 45.33164], [29.24779, 45.43388], [29.42632, 45.44545], [29.59798, 45.38857], [29.68175, 45.26885], [29.65428, 45.25629], [29.69272, 45.19227], [30.04414, 45.08461], [31.62627, 45.50633], [33.54017, 46.0123], [33.59087, 46.06013], [33.57318, 46.10317]]]] } },
23336 { type: "Feature", properties: { iso1A2: "UG", iso1A3: "UGA", iso1N3: "800", wikidata: "Q1036", nameEn: "Uganda", groups: ["014", "202", "002", "UN"], driveSide: "left", callingCodes: ["256"] }, geometry: { type: "MultiPolygon", coordinates: [[[[33.93107, -0.99298], [33.9264, -0.54188], [33.98449, -0.13079], [33.90936, 0.10581], [34.10067, 0.36372], [34.08727, 0.44713], [34.11408, 0.48884], [34.13493, 0.58118], [34.20196, 0.62289], [34.27345, 0.63182], [34.31516, 0.75693], [34.40041, 0.80266], [34.43349, 0.85254], [34.52369, 1.10692], [34.57427, 1.09868], [34.58029, 1.14712], [34.67562, 1.21265], [34.80223, 1.22754], [34.82606, 1.26626], [34.82606, 1.30944], [34.7918, 1.36752], [34.87819, 1.5596], [34.92734, 1.56109], [34.9899, 1.6668], [34.98692, 1.97348], [34.90947, 2.42447], [34.95267, 2.47209], [34.77244, 2.70272], [34.78137, 2.76223], [34.73967, 2.85447], [34.65774, 2.8753], [34.60114, 2.93034], [34.56242, 3.11478], [34.45815, 3.18319], [34.40006, 3.37949], [34.41794, 3.44342], [34.39112, 3.48802], [34.44922, 3.51627], [34.45815, 3.67385], [34.15429, 3.80464], [34.06046, 4.15235], [33.9873, 4.23316], [33.51264, 3.75068], [33.18356, 3.77812], [33.02852, 3.89296], [32.89746, 3.81339], [32.72021, 3.77327], [32.41337, 3.748], [32.20782, 3.6053], [32.19888, 3.50867], [32.08866, 3.53543], [32.08491, 3.56287], [32.05187, 3.589], [31.95907, 3.57408], [31.96205, 3.6499], [31.86821, 3.78664], [31.81459, 3.82083], [31.72075, 3.74354], [31.50776, 3.63652], [31.50478, 3.67814], [31.29476, 3.8015], [31.16666, 3.79853], [30.97601, 3.693], [30.85153, 3.48867], [30.94081, 3.50847], [30.93486, 3.40737], [30.84251, 3.26908], [30.77101, 3.04897], [30.8574, 2.9508], [30.8857, 2.83923], [30.75612, 2.5863], [30.74271, 2.43601], [30.83059, 2.42559], [30.91102, 2.33332], [30.96911, 2.41071], [31.06593, 2.35862], [31.07934, 2.30207], [31.12104, 2.27676], [31.1985, 2.29462], [31.20148, 2.2217], [31.28042, 2.17853], [31.30127, 2.11006], [30.48503, 1.21675], [30.24671, 1.14974], [30.22139, 0.99635], [30.1484, 0.89805], [29.98307, 0.84295], [29.95477, 0.64486], [29.97413, 0.52124], [29.87284, 0.39166], [29.81922, 0.16824], [29.77454, 0.16675], [29.7224, 0.07291], [29.72687, -0.08051], [29.65091, -0.46777], [29.67474, -0.47969], [29.67176, -0.55714], [29.62708, -0.71055], [29.63006, -0.8997], [29.58388, -0.89821], [29.59061, -1.39016], [29.82657, -1.31187], [29.912, -1.48269], [30.16369, -1.34303], [30.35212, -1.06896], [30.47194, -1.0555], [30.64166, -1.06601], [30.70631, -1.01175], [30.76635, -0.9852], [30.80408, -0.99911], [33.93107, -0.99298]]]] } },
23337 { type: "Feature", properties: { iso1A2: "UM", iso1A3: "UMI", iso1N3: "581", wikidata: "Q16645", nameEn: "United States Minor Outlying Islands", country: "US" }, geometry: null },
23338 { type: "Feature", properties: { iso1A2: "UN", wikidata: "Q1065", nameEn: "United Nations", level: "unitedNations", isoStatus: "excRes" }, geometry: null },
23339 { type: "Feature", properties: { iso1A2: "US", iso1A3: "USA", iso1N3: "840", wikidata: "Q30", nameEn: "United States of America" }, geometry: null },
23340 { type: "Feature", properties: { iso1A2: "UY", iso1A3: "URY", iso1N3: "858", wikidata: "Q77", nameEn: "Uruguay", groups: ["005", "419", "019", "UN"], callingCodes: ["598"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-57.65132, -30.19229], [-57.61478, -30.25165], [-57.64859, -30.35095], [-57.89115, -30.49572], [-57.8024, -30.77193], [-57.89476, -30.95994], [-57.86729, -31.06352], [-57.9908, -31.34924], [-57.98127, -31.3872], [-58.07569, -31.44916], [-58.0023, -31.53084], [-58.00076, -31.65016], [-58.20252, -31.86966], [-58.10036, -32.25338], [-58.22362, -32.52416], [-58.1224, -32.98842], [-58.40475, -33.11777], [-58.44442, -33.84033], [-58.34425, -34.15035], [-57.83001, -34.69099], [-54.78916, -36.21945], [-52.83257, -34.01481], [-53.37138, -33.74313], [-53.39593, -33.75169], [-53.44031, -33.69344], [-53.52794, -33.68908], [-53.53459, -33.16843], [-53.1111, -32.71147], [-53.37671, -32.57005], [-53.39572, -32.58596], [-53.76024, -32.0751], [-54.17384, -31.86168], [-55.50821, -30.91349], [-55.50841, -30.9027], [-55.51862, -30.89828], [-55.52712, -30.89997], [-55.53276, -30.90218], [-55.53431, -30.89714], [-55.54572, -30.89051], [-55.55218, -30.88193], [-55.55373, -30.8732], [-55.5634, -30.8686], [-55.58866, -30.84117], [-55.87388, -31.05053], [-56.4619, -30.38457], [-56.4795, -30.3899], [-56.49267, -30.39471], [-56.90236, -30.02578], [-57.22502, -30.26121], [-57.65132, -30.19229]]]] } },
23341 { type: "Feature", properties: { iso1A2: "UZ", iso1A3: "UZB", iso1N3: "860", wikidata: "Q265", nameEn: "Uzbekistan", groups: ["143", "142", "UN"], callingCodes: ["998"] }, geometry: { type: "MultiPolygon", coordinates: [[[[65.85194, 42.85481], [65.53277, 43.31856], [65.18666, 43.48835], [64.96464, 43.74748], [64.53885, 43.56941], [63.34656, 43.64003], [62.01711, 43.51008], [61.01475, 44.41383], [58.59711, 45.58671], [55.97842, 44.99622], [55.97832, 44.99622], [55.97822, 44.99617], [55.97811, 44.99617], [55.97801, 44.99612], [55.97801, 44.99607], [55.97791, 44.99607], [55.9778, 44.99607], [55.9777, 44.99601], [55.9777, 44.99596], [55.9776, 44.99591], [55.97749, 44.99591], [55.97739, 44.99591], [55.97739, 44.99586], [55.97729, 44.99586], [55.97718, 44.99581], [55.97708, 44.99576], [55.97698, 44.9957], [55.97698, 44.99565], [55.97687, 44.9956], [55.97677, 44.9956], [55.97677, 44.99555], [55.97677, 44.9955], [55.97667, 44.99545], [55.97656, 44.99539], [55.97646, 44.99534], [55.97646, 44.99529], [55.97636, 44.99524], [55.97636, 44.99519], [55.97625, 44.99514], [55.97615, 44.99508], [55.97615, 44.99503], [55.97615, 44.99498], [55.97615, 44.99493], [55.97615, 44.99483], [55.97615, 44.99477], [55.97605, 44.99477], [55.97605, 44.99467], [55.97605, 44.99462], [55.97605, 44.99457], [55.97605, 44.99452], [55.97594, 44.99446], [55.97584, 44.99441], [55.97584, 44.99436], [55.97584, 44.99431], [55.97584, 44.99426], [55.97584, 44.99421], [55.97584, 44.99415], [55.97584, 44.99405], [55.97584, 44.994], [55.97584, 44.9939], [55.97584, 44.99384], [55.97584, 44.99374], [55.97584, 44.99369], [55.97584, 44.99359], [55.97584, 44.99353], [55.97584, 44.99348], [55.97584, 44.99343], [55.97584, 44.99338], [55.97584, 44.99328], [55.97584, 44.99322], [56.00314, 41.32584], [57.03423, 41.25435], [57.13796, 41.36625], [57.03359, 41.41777], [56.96218, 41.80383], [57.03633, 41.92043], [57.30275, 42.14076], [57.6296, 42.16519], [57.84932, 42.18555], [57.92897, 42.24047], [57.90975, 42.4374], [57.99214, 42.50021], [58.3492, 42.43335], [58.40688, 42.29535], [58.51674, 42.30348], [58.29427, 42.56497], [58.14321, 42.62159], [58.27504, 42.69632], [58.57991, 42.64988], [58.6266, 42.79314], [58.93422, 42.5407], [59.17317, 42.52248], [59.2955, 42.37064], [59.4341, 42.29738], [59.94633, 42.27655], [60.00539, 42.212], [59.96419, 42.1428], [60.04659, 42.08982], [60.0356, 42.01028], [59.95046, 41.97966], [60.33223, 41.75058], [60.08504, 41.80997], [60.06032, 41.76287], [60.18117, 41.60082], [60.06581, 41.4363], [60.5078, 41.21694], [61.03261, 41.25691], [61.22212, 41.14946], [61.33199, 41.14946], [61.39732, 41.19873], [61.4446, 41.29407], [61.87856, 41.12257], [62.11751, 40.58242], [62.34273, 40.43206], [62.43337, 39.98528], [63.6913, 39.27666], [63.70778, 39.22349], [64.19086, 38.95561], [64.32576, 38.98691], [65.55873, 38.29052], [65.83913, 38.25733], [66.24013, 38.16238], [66.41042, 38.02403], [66.56697, 38.0435], [66.67684, 37.96776], [66.53676, 37.80084], [66.52852, 37.58568], [66.65761, 37.45497], [66.52303, 37.39827], [66.55743, 37.35409], [66.64699, 37.32958], [66.95598, 37.40162], [67.08232, 37.35469], [67.13039, 37.27168], [67.2224, 37.24545], [67.2581, 37.17216], [67.51868, 37.26102], [67.78329, 37.1834], [67.8474, 37.31594], [67.81566, 37.43107], [68.12635, 37.93], [68.27159, 37.91477], [68.40343, 38.19484], [68.13289, 38.40822], [68.06274, 38.39435], [68.11366, 38.47169], [68.05873, 38.56087], [68.0807, 38.64136], [68.05598, 38.71641], [68.12877, 38.73677], [68.06948, 38.82115], [68.19743, 38.85985], [68.09704, 39.02589], [67.68915, 39.00775], [67.67833, 39.14479], [67.33226, 39.23739], [67.36522, 39.31287], [67.45998, 39.315], [67.46822, 39.46146], [67.39681, 39.52505], [67.46547, 39.53564], [67.44899, 39.57799], [67.62889, 39.60234], [67.70992, 39.66156], [68.12053, 39.56317], [68.54166, 39.53929], [68.61972, 39.68905], [68.63071, 39.85265], [68.88889, 39.87163], [68.93695, 39.91167], [68.84906, 40.04952], [68.96579, 40.06949], [69.01935, 40.11466], [69.01523, 40.15771], [68.62796, 40.07789], [68.52771, 40.11676], [68.5332, 40.14826], [68.77902, 40.20492], [68.79276, 40.17555], [68.84357, 40.18604], [68.85832, 40.20885], [69.04544, 40.22904], [69.15659, 40.2162], [69.2074, 40.21488], [69.30448, 40.18774], [69.30104, 40.24502], [69.25229, 40.26362], [69.24817, 40.30357], [69.30808, 40.2821], [69.32833, 40.29794], [69.33794, 40.34819], [69.30774, 40.36102], [69.28525, 40.41894], [69.27066, 40.49274], [69.21063, 40.54469], [69.2643, 40.57506], [69.3455, 40.57988], [69.32834, 40.70233], [69.38327, 40.7918], [69.53021, 40.77621], [69.59441, 40.70181], [69.69434, 40.62615], [70.36655, 40.90296], [70.38028, 41.02014], [70.45251, 41.04438], [70.80009, 40.72825], [70.49871, 40.52503], [70.32626, 40.45174], [70.37511, 40.38605], [70.57149, 40.3442], [70.56394, 40.26421], [70.62342, 40.17396], [70.8607, 40.217], [70.9818, 40.22392], [70.95789, 40.28761], [71.05901, 40.28765], [71.13042, 40.34106], [71.36663, 40.31593], [71.4246, 40.28619], [71.51215, 40.26943], [71.51549, 40.22986], [71.61725, 40.20615], [71.61931, 40.26775], [71.68386, 40.26984], [71.70569, 40.20391], [71.69621, 40.18492], [71.71719, 40.17886], [71.73054, 40.14818], [71.82646, 40.21872], [71.85002, 40.25647], [72.05464, 40.27586], [71.96401, 40.31907], [72.18648, 40.49893], [72.24368, 40.46091], [72.40346, 40.4007], [72.44191, 40.48222], [72.41513, 40.50856], [72.38384, 40.51535], [72.41714, 40.55736], [72.34406, 40.60144], [72.40517, 40.61917], [72.47795, 40.5532], [72.66713, 40.5219], [72.66713, 40.59076], [72.69579, 40.59778], [72.73995, 40.58409], [72.74768, 40.58051], [72.74862, 40.57131], [72.75982, 40.57273], [72.74894, 40.59592], [72.74866, 40.60873], [72.80137, 40.67856], [72.84754, 40.67229], [72.85372, 40.7116], [72.8722, 40.71111], [72.93296, 40.73089], [72.99133, 40.76457], [73.0612, 40.76678], [73.13412, 40.79122], [73.13267, 40.83512], [73.01869, 40.84681], [72.94454, 40.8094], [72.84291, 40.85512], [72.68157, 40.84942], [72.59136, 40.86947], [72.55109, 40.96046], [72.48742, 40.97136], [72.45206, 41.03018], [72.38511, 41.02785], [72.36138, 41.04384], [72.34757, 41.06104], [72.34026, 41.04539], [72.324, 41.03381], [72.18339, 40.99571], [72.17594, 41.02377], [72.21061, 41.05607], [72.1792, 41.10621], [72.14864, 41.13363], [72.17594, 41.15522], [72.16433, 41.16483], [72.10745, 41.15483], [72.07249, 41.11739], [71.85964, 41.19081], [71.91457, 41.2982], [71.83914, 41.3546], [71.76625, 41.4466], [71.71132, 41.43012], [71.73054, 41.54713], [71.65914, 41.49599], [71.6787, 41.42111], [71.57227, 41.29175], [71.46688, 41.31883], [71.43814, 41.19644], [71.46148, 41.13958], [71.40198, 41.09436], [71.34877, 41.16807], [71.27187, 41.11015], [71.25813, 41.18796], [71.11806, 41.15359], [71.02193, 41.19494], [70.9615, 41.16393], [70.86263, 41.23833], [70.77885, 41.24813], [70.78572, 41.36419], [70.67586, 41.47953], [70.48909, 41.40335], [70.17682, 41.5455], [70.69777, 41.92554], [71.28719, 42.18033], [71.13263, 42.28356], [70.94483, 42.26238], [69.49545, 41.545], [69.45751, 41.56863], [69.39485, 41.51518], [69.45081, 41.46246], [69.37468, 41.46555], [69.35554, 41.47211], [69.29778, 41.43673], [69.25059, 41.46693], [69.23332, 41.45847], [69.22671, 41.46298], [69.20439, 41.45391], [69.18528, 41.45175], [69.17701, 41.43769], [69.15137, 41.43078], [69.05006, 41.36183], [69.01308, 41.22804], [68.7217, 41.05025], [68.73945, 40.96989], [68.65662, 40.93861], [68.62221, 41.03019], [68.49983, 40.99669], [68.58444, 40.91447], [68.63, 40.59358], [68.49983, 40.56437], [67.96736, 40.83798], [68.1271, 41.0324], [68.08273, 41.08148], [67.98511, 41.02794], [67.9644, 41.14611], [66.69129, 41.1311], [66.53302, 41.87388], [66.00546, 41.94455], [66.09482, 42.93426], [65.85194, 42.85481]], [[70.68112, 40.90612], [70.6721, 40.90555], [70.57501, 40.98941], [70.54223, 40.98787], [70.56077, 41.00642], [70.6158, 40.97661], [70.68112, 40.90612]]], [[[71.21139, 40.03369], [71.12218, 40.03052], [71.06305, 40.1771], [71.00236, 40.18154], [71.01035, 40.05481], [71.11037, 40.01984], [71.11668, 39.99291], [71.09063, 39.99], [71.10501, 39.95568], [71.04979, 39.89808], [71.10531, 39.91354], [71.16101, 39.88423], [71.23067, 39.93581], [71.1427, 39.95026], [71.21139, 40.03369]]], [[[71.86463, 39.98598], [71.78838, 40.01404], [71.71511, 39.96348], [71.7504, 39.93701], [71.84316, 39.95582], [71.86463, 39.98598]]]] } },
23342 { type: "Feature", properties: { iso1A2: "VA", iso1A3: "VAT", iso1N3: "336", wikidata: "Q237", nameEn: "Vatican City", aliases: ["Holy See"], groups: ["039", "150"], callingCodes: ["379", "39 06"] }, geometry: { type: "MultiPolygon", coordinates: [[[[12.45181, 41.90056], [12.45446, 41.90028], [12.45435, 41.90143], [12.45626, 41.90172], [12.45691, 41.90125], [12.4577, 41.90115], [12.45834, 41.90174], [12.45826, 41.90281], [12.45755, 41.9033], [12.45762, 41.9058], [12.45561, 41.90629], [12.45543, 41.90738], [12.45091, 41.90625], [12.44984, 41.90545], [12.44815, 41.90326], [12.44582, 41.90194], [12.44834, 41.90095], [12.45181, 41.90056]]]] } },
23343 { type: "Feature", properties: { iso1A2: "VC", iso1A3: "VCT", iso1N3: "670", wikidata: "Q757", nameEn: "St. Vincent and the Grenadines", aliases: ["WV"], groups: ["029", "003", "419", "019", "UN"], driveSide: "left", roadSpeedUnit: "mph", callingCodes: ["1 784"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-62.64026, 12.69984], [-59.94058, 12.34011], [-61.69315, 14.26451], [-62.64026, 12.69984]]]] } },
23344 { type: "Feature", properties: { iso1A2: "VE", iso1A3: "VEN", iso1N3: "862", wikidata: "Q717", nameEn: "Venezuela", aliases: ["YV"], groups: ["005", "419", "019", "UN"], callingCodes: ["58"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-71.22331, 13.01387], [-70.92579, 11.96275], [-71.3275, 11.85], [-71.9675, 11.65536], [-72.24983, 11.14138], [-72.4767, 11.1117], [-72.88002, 10.44309], [-72.98085, 9.85253], [-73.36905, 9.16636], [-73.02119, 9.27584], [-72.94052, 9.10663], [-72.77415, 9.10165], [-72.65474, 8.61428], [-72.4042, 8.36513], [-72.36987, 8.19976], [-72.35163, 8.01163], [-72.39137, 8.03534], [-72.47213, 7.96106], [-72.48801, 7.94329], [-72.48183, 7.92909], [-72.47042, 7.92306], [-72.45806, 7.91141], [-72.46183, 7.90682], [-72.44454, 7.86031], [-72.46763, 7.79518], [-72.47827, 7.65604], [-72.45321, 7.57232], [-72.47415, 7.48928], [-72.43132, 7.40034], [-72.19437, 7.37034], [-72.04895, 7.03837], [-71.82441, 7.04314], [-71.44118, 7.02116], [-71.42212, 7.03854], [-71.37234, 7.01588], [-71.03941, 6.98163], [-70.7596, 7.09799], [-70.10716, 6.96516], [-69.41843, 6.1072], [-67.60654, 6.2891], [-67.4625, 6.20625], [-67.43513, 5.98835], [-67.58558, 5.84537], [-67.63914, 5.64963], [-67.59141, 5.5369], [-67.83341, 5.31104], [-67.85358, 4.53249], [-67.62671, 3.74303], [-67.50067, 3.75812], [-67.30945, 3.38393], [-67.85862, 2.86727], [-67.85862, 2.79173], [-67.65696, 2.81691], [-67.21967, 2.35778], [-66.85795, 1.22998], [-66.28507, 0.74585], [-65.6727, 1.01353], [-65.50158, 0.92086], [-65.57288, 0.62856], [-65.11657, 1.12046], [-64.38932, 1.5125], [-64.34654, 1.35569], [-64.08274, 1.64792], [-64.06135, 1.94722], [-63.39827, 2.16098], [-63.39114, 2.4317], [-64.0257, 2.48156], [-64.02908, 2.79797], [-64.48379, 3.7879], [-64.84028, 4.24665], [-64.72977, 4.28931], [-64.57648, 4.12576], [-64.14512, 4.12932], [-63.99183, 3.90172], [-63.86082, 3.94796], [-63.70218, 3.91417], [-63.67099, 4.01731], [-63.50611, 3.83592], [-63.42233, 3.89995], [-63.4464, 3.9693], [-63.21111, 3.96219], [-62.98296, 3.59935], [-62.7655, 3.73099], [-62.74411, 4.03331], [-62.57656, 4.04754], [-62.44822, 4.18621], [-62.13094, 4.08309], [-61.54629, 4.2822], [-61.48569, 4.43149], [-61.29675, 4.44216], [-61.31457, 4.54167], [-61.15703, 4.49839], [-60.98303, 4.54167], [-60.86539, 4.70512], [-60.5802, 4.94312], [-60.73204, 5.20931], [-61.4041, 5.95304], [-61.15058, 6.19558], [-61.20762, 6.58174], [-61.13632, 6.70922], [-60.54873, 6.8631], [-60.39419, 6.94847], [-60.28074, 7.1162], [-60.44116, 7.20817], [-60.54098, 7.14804], [-60.63367, 7.25061], [-60.59802, 7.33194], [-60.71923, 7.55817], [-60.64793, 7.56877], [-60.51959, 7.83373], [-60.38056, 7.8302], [-60.02407, 8.04557], [-59.97059, 8.20791], [-59.83156, 8.23261], [-59.80661, 8.28906], [-59.85562, 8.35213], [-59.98508, 8.53046], [-59.54058, 8.6862], [-60.89962, 9.81445], [-62.08693, 10.04435], [-61.62505, 11.18974], [-63.73917, 11.92623], [-63.19938, 16.44103], [-67.89186, 12.4116], [-68.01417, 11.77722], [-68.33524, 11.78151], [-68.99639, 11.79035], [-71.22331, 13.01387]]]] } },
23345 { type: "Feature", properties: { iso1A2: "VG", iso1A3: "VGB", iso1N3: "092", wikidata: "Q25305", nameEn: "British Virgin Islands", country: "GB", groups: ["BOTS", "029", "003", "419", "019", "UN"], driveSide: "left", roadSpeedUnit: "mph", roadHeightUnit: "ft", callingCodes: ["1 284"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-64.47127, 17.55688], [-63.88746, 19.15706], [-65.02435, 18.73231], [-64.86027, 18.39056], [-64.64673, 18.36549], [-64.47127, 17.55688]]]] } },
23346 { type: "Feature", properties: { iso1A2: "VI", iso1A3: "VIR", iso1N3: "850", wikidata: "Q11703", nameEn: "United States Virgin Islands", aliases: ["US-VI"], country: "US", groups: ["Q1352230", "029", "003", "419", "019", "UN"], driveSide: "left", roadSpeedUnit: "mph", roadHeightUnit: "ft", callingCodes: ["1 340"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-65.02435, 18.73231], [-65.27974, 17.56928], [-64.47127, 17.55688], [-64.64673, 18.36549], [-64.86027, 18.39056], [-65.02435, 18.73231]]]] } },
23347 { type: "Feature", properties: { iso1A2: "VN", iso1A3: "VNM", iso1N3: "704", wikidata: "Q881", nameEn: "Vietnam", groups: ["035", "142", "UN"], callingCodes: ["84"] }, geometry: { type: "MultiPolygon", coordinates: [[[[108.10003, 21.47338], [108.0569, 21.53604], [108.02926, 21.54997], [107.97932, 21.54503], [107.97383, 21.53961], [107.97074, 21.54072], [107.96774, 21.53601], [107.95232, 21.5388], [107.92652, 21.58906], [107.90006, 21.5905], [107.86114, 21.65128], [107.80355, 21.66141], [107.66967, 21.60787], [107.56537, 21.61945], [107.54047, 21.5934], [107.49065, 21.59774], [107.49532, 21.62958], [107.47197, 21.6672], [107.41593, 21.64839], [107.38636, 21.59774], [107.35989, 21.60063], [107.35834, 21.6672], [107.29296, 21.74674], [107.24625, 21.7077], [107.20734, 21.71493], [107.10771, 21.79879], [107.02615, 21.81981], [107.00964, 21.85948], [107.06101, 21.88982], [107.05634, 21.92303], [106.99252, 21.95191], [106.97228, 21.92592], [106.92714, 21.93459], [106.9178, 21.97357], [106.81038, 21.97934], [106.74345, 22.00965], [106.72551, 21.97923], [106.69276, 21.96013], [106.68274, 21.99811], [106.70142, 22.02409], [106.6983, 22.15102], [106.67495, 22.1885], [106.69986, 22.22309], [106.6516, 22.33977], [106.55976, 22.34841], [106.57221, 22.37], [106.55665, 22.46498], [106.58395, 22.474], [106.61269, 22.60301], [106.65316, 22.5757], [106.71698, 22.58432], [106.72321, 22.63606], [106.76293, 22.73491], [106.82404, 22.7881], [106.83685, 22.8098], [106.81271, 22.8226], [106.78422, 22.81532], [106.71128, 22.85982], [106.71387, 22.88296], [106.6734, 22.89587], [106.6516, 22.86862], [106.60179, 22.92884], [106.55976, 22.92311], [106.51306, 22.94891], [106.49749, 22.91164], [106.34961, 22.86718], [106.27022, 22.87722], [106.19705, 22.98475], [106.00179, 22.99049], [105.99568, 22.94178], [105.90119, 22.94168], [105.8726, 22.92756], [105.72382, 23.06641], [105.57594, 23.075], [105.56037, 23.16806], [105.49966, 23.20669], [105.42805, 23.30824], [105.40782, 23.28107], [105.32376, 23.39684], [105.22569, 23.27249], [105.17276, 23.28679], [105.11672, 23.25247], [105.07002, 23.26248], [104.98712, 23.19176], [104.96532, 23.20463], [104.9486, 23.17235], [104.91435, 23.18666], [104.87992, 23.17141], [104.87382, 23.12854], [104.79478, 23.12934], [104.8334, 23.01484], [104.86765, 22.95178], [104.84942, 22.93631], [104.77114, 22.90017], [104.72755, 22.81984], [104.65283, 22.83419], [104.60457, 22.81841], [104.58122, 22.85571], [104.47225, 22.75813], [104.35593, 22.69353], [104.25683, 22.76534], [104.27084, 22.8457], [104.11384, 22.80363], [104.03734, 22.72945], [104.01088, 22.51823], [103.99247, 22.51958], [103.97384, 22.50634], [103.96783, 22.51173], [103.96352, 22.50584], [103.95191, 22.5134], [103.94513, 22.52553], [103.93286, 22.52703], [103.87904, 22.56683], [103.64506, 22.79979], [103.56255, 22.69499], [103.57812, 22.65764], [103.52675, 22.59155], [103.43646, 22.70648], [103.43179, 22.75816], [103.32282, 22.8127], [103.28079, 22.68063], [103.18895, 22.64471], [103.15782, 22.59873], [103.17961, 22.55705], [103.07843, 22.50097], [103.0722, 22.44775], [102.9321, 22.48659], [102.8636, 22.60735], [102.60675, 22.73376], [102.57095, 22.7036], [102.51802, 22.77969], [102.46665, 22.77108], [102.42618, 22.69212], [102.38415, 22.67919], [102.41061, 22.64184], [102.25339, 22.4607], [102.26428, 22.41321], [102.16621, 22.43336], [102.14099, 22.40092], [102.18712, 22.30403], [102.51734, 22.02676], [102.49092, 21.99002], [102.62301, 21.91447], [102.67145, 21.65894], [102.74189, 21.66713], [102.82115, 21.73667], [102.81894, 21.83888], [102.85637, 21.84501], [102.86077, 21.71213], [102.97965, 21.74076], [102.98846, 21.58936], [102.86297, 21.4255], [102.94223, 21.46034], [102.88939, 21.3107], [102.80794, 21.25736], [102.89825, 21.24707], [102.97745, 21.05821], [103.03469, 21.05821], [103.12055, 20.89994], [103.21497, 20.89832], [103.38032, 20.79501], [103.45737, 20.82382], [103.68633, 20.66324], [103.73478, 20.6669], [103.82282, 20.8732], [103.98024, 20.91531], [104.11121, 20.96779], [104.27412, 20.91433], [104.63957, 20.6653], [104.38199, 20.47155], [104.40621, 20.3849], [104.47886, 20.37459], [104.66158, 20.47774], [104.72102, 20.40554], [104.62195, 20.36633], [104.61315, 20.24452], [104.86852, 20.14121], [104.91695, 20.15567], [104.9874, 20.09573], [104.8465, 19.91783], [104.8355, 19.80395], [104.68359, 19.72729], [104.64837, 19.62365], [104.53169, 19.61743], [104.41281, 19.70035], [104.23229, 19.70242], [104.06498, 19.66926], [104.05617, 19.61743], [104.10832, 19.51575], [104.06058, 19.43484], [103.87125, 19.31854], [104.5361, 18.97747], [104.64617, 18.85668], [105.12829, 18.70453], [105.19654, 18.64196], [105.1327, 18.58355], [105.10408, 18.43533], [105.15942, 18.38691], [105.38366, 18.15315], [105.46292, 18.22008], [105.64784, 17.96687], [105.60381, 17.89356], [105.76612, 17.67147], [105.85744, 17.63221], [106.09019, 17.36399], [106.18991, 17.28227], [106.24444, 17.24714], [106.29287, 17.3018], [106.31929, 17.20509], [106.43597, 17.01362], [106.50862, 16.9673], [106.55045, 17.0031], [106.54824, 16.92729], [106.51963, 16.92097], [106.52183, 16.87884], [106.55265, 16.86831], [106.55485, 16.68704], [106.59013, 16.62259], [106.58267, 16.6012], [106.61477, 16.60713], [106.66052, 16.56892], [106.65832, 16.47816], [106.74418, 16.41904], [106.84104, 16.55415], [106.88727, 16.52671], [106.88067, 16.43594], [106.96638, 16.34938], [106.97385, 16.30204], [107.02597, 16.31132], [107.09091, 16.3092], [107.15035, 16.26271], [107.14595, 16.17816], [107.25822, 16.13587], [107.33968, 16.05549], [107.44975, 16.08511], [107.46296, 16.01106], [107.39471, 15.88829], [107.34188, 15.89464], [107.21419, 15.83747], [107.21859, 15.74638], [107.27143, 15.71459], [107.27583, 15.62769], [107.34408, 15.62345], [107.3815, 15.49832], [107.50699, 15.48771], [107.53341, 15.40496], [107.62367, 15.42193], [107.60605, 15.37524], [107.62587, 15.2266], [107.58844, 15.20111], [107.61926, 15.13949], [107.61486, 15.0566], [107.46516, 15.00982], [107.48277, 14.93751], [107.59285, 14.87795], [107.51579, 14.79282], [107.54361, 14.69092], [107.55371, 14.628], [107.52102, 14.59034], [107.52569, 14.54665], [107.48521, 14.40346], [107.44941, 14.41552], [107.39493, 14.32655], [107.40427, 14.24509], [107.33577, 14.11832], [107.37158, 14.07906], [107.35757, 14.02319], [107.38247, 13.99147], [107.44318, 13.99751], [107.46498, 13.91593], [107.45252, 13.78897], [107.53503, 13.73908], [107.61909, 13.52577], [107.62843, 13.3668], [107.49144, 13.01215], [107.49611, 12.88926], [107.55993, 12.7982], [107.5755, 12.52177], [107.55059, 12.36824], [107.4463, 12.29373], [107.42917, 12.24657], [107.34511, 12.33327], [107.15831, 12.27547], [106.99953, 12.08983], [106.92325, 12.06548], [106.79405, 12.0807], [106.70687, 11.96956], [106.4111, 11.97413], [106.4687, 11.86751], [106.44068, 11.86294], [106.44535, 11.8279], [106.41577, 11.76999], [106.45158, 11.68616], [106.44691, 11.66787], [106.37219, 11.69836], [106.30525, 11.67549], [106.26478, 11.72122], [106.18539, 11.75171], [106.13158, 11.73283], [106.06708, 11.77761], [106.02038, 11.77457], [106.00792, 11.7197], [105.95188, 11.63738], [105.88962, 11.67854], [105.8507, 11.66635], [105.80867, 11.60536], [105.81645, 11.56876], [105.87328, 11.55953], [105.88962, 11.43605], [105.86782, 11.28343], [106.10444, 11.07879], [106.1527, 11.10476], [106.1757, 11.07301], [106.20095, 10.97795], [106.14301, 10.98176], [106.18539, 10.79451], [106.06708, 10.8098], [105.94535, 10.9168], [105.93403, 10.83853], [105.84603, 10.85873], [105.86376, 10.89839], [105.77751, 11.03671], [105.50045, 10.94586], [105.42884, 10.96878], [105.34011, 10.86179], [105.11449, 10.96332], [105.08326, 10.95656], [105.02722, 10.89236], [105.09571, 10.72722], [104.95094, 10.64003], [104.87933, 10.52833], [104.59018, 10.53073], [104.49869, 10.4057], [104.47963, 10.43046], [104.43778, 10.42386], [103.99198, 10.48391], [102.47649, 9.66162], [104.81582, 8.03101], [109.55486, 8.10026], [111.60491, 13.57105], [108.00365, 17.98159], [108.10003, 21.47338]]]] } },
23348 { type: "Feature", properties: { iso1A2: "VU", iso1A3: "VUT", iso1N3: "548", wikidata: "Q686", nameEn: "Vanuatu", groups: ["054", "009", "UN"], callingCodes: ["678"] }, geometry: { type: "MultiPolygon", coordinates: [[[[156.73836, -14.50464], [174.245, -23.1974], [172.71443, -12.01327], [156.73836, -14.50464]]]] } },
23349 { type: "Feature", properties: { iso1A2: "WF", iso1A3: "WLF", iso1N3: "876", wikidata: "Q35555", nameEn: "Wallis and Futuna", country: "FR", groups: ["EU", "Q1451600", "061", "009", "UN"], callingCodes: ["681"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-178.66551, -14.32452], [-176.76826, -14.95183], [-175.59809, -12.61507], [-178.66551, -14.32452]]]] } },
23350 { type: "Feature", properties: { iso1A2: "WS", iso1A3: "WSM", iso1N3: "882", wikidata: "Q683", nameEn: "Samoa", groups: ["061", "009", "UN"], driveSide: "left", callingCodes: ["685"] }, geometry: { type: "MultiPolygon", coordinates: [[[[-173.74402, -14.26669], [-170.99605, -15.1275], [-171.39864, -10.21587], [-173.74402, -14.26669]]]] } },
23351 { type: "Feature", properties: { iso1A2: "XK", iso1A3: "XKX", wikidata: "Q1246", nameEn: "Kosovo", aliases: ["KV"], groups: ["039", "150"], isoStatus: "usrAssn", callingCodes: ["383"] }, geometry: { type: "MultiPolygon", coordinates: [[[[21.39045, 42.74888], [21.44047, 42.87276], [21.36941, 42.87397], [21.32974, 42.90424], [21.2719, 42.8994], [21.23534, 42.95523], [21.23877, 43.00848], [21.2041, 43.02277], [21.16734, 42.99694], [21.14465, 43.11089], [21.08952, 43.13471], [21.05378, 43.10707], [21.00749, 43.13984], [20.96287, 43.12416], [20.83727, 43.17842], [20.88685, 43.21697], [20.82145, 43.26769], [20.73811, 43.25068], [20.68688, 43.21335], [20.59929, 43.20492], [20.69515, 43.09641], [20.64557, 43.00826], [20.59929, 43.01067], [20.48692, 42.93208], [20.53484, 42.8885], [20.43734, 42.83157], [20.40594, 42.84853], [20.35692, 42.8335], [20.27869, 42.81945], [20.2539, 42.76245], [20.04898, 42.77701], [20.02088, 42.74789], [20.02915, 42.71147], [20.0969, 42.65559], [20.07761, 42.55582], [20.17127, 42.50469], [20.21797, 42.41237], [20.24399, 42.32168], [20.34479, 42.32656], [20.3819, 42.3029], [20.48857, 42.25444], [20.56955, 42.12097], [20.55633, 42.08173], [20.59434, 42.03879], [20.63069, 41.94913], [20.57946, 41.91593], [20.59524, 41.8818], [20.68523, 41.85318], [20.76786, 41.91839], [20.75464, 42.05229], [21.11491, 42.20794], [21.16614, 42.19815], [21.22728, 42.08909], [21.31983, 42.10993], [21.29913, 42.13954], [21.30496, 42.1418], [21.38428, 42.24465], [21.43882, 42.23609], [21.43882, 42.2789], [21.50823, 42.27156], [21.52145, 42.24465], [21.58992, 42.25915], [21.56772, 42.30946], [21.5264, 42.33634], [21.53467, 42.36809], [21.57021, 42.3647], [21.59029, 42.38042], [21.62887, 42.37664], [21.64209, 42.41081], [21.62556, 42.45106], [21.7035, 42.51899], [21.70522, 42.54176], [21.7327, 42.55041], [21.75672, 42.62695], [21.79413, 42.65923], [21.75025, 42.70125], [21.6626, 42.67813], [21.58755, 42.70418], [21.59154, 42.72643], [21.47498, 42.74695], [21.39045, 42.74888]]]] } },
23352 { type: "Feature", properties: { iso1A2: "YE", iso1A3: "YEM", iso1N3: "887", wikidata: "Q805", nameEn: "Yemen", groups: ["145", "142", "UN"], callingCodes: ["967"] }, geometry: { type: "MultiPolygon", coordinates: [[[[57.49095, 8.14549], [52.81185, 17.28568], [52.74267, 17.29519], [52.78009, 17.35124], [52.00311, 19.00083], [49.04884, 18.59899], [48.19996, 18.20584], [47.58351, 17.50366], [47.48245, 17.10808], [47.00571, 16.94765], [46.76494, 17.29151], [46.31018, 17.20464], [44.50126, 17.47475], [43.70631, 17.35762], [43.43005, 17.56148], [43.29185, 17.53224], [43.22533, 17.38343], [43.32653, 17.31179], [43.20156, 17.25901], [43.17787, 17.14717], [43.23967, 17.03428], [43.18233, 17.02673], [43.1813, 16.98438], [43.19328, 16.94703], [43.1398, 16.90696], [43.18338, 16.84852], [43.22012, 16.83932], [43.22956, 16.80613], [43.24801, 16.80613], [43.26303, 16.79479], [43.25857, 16.75304], [43.21325, 16.74416], [43.22066, 16.65179], [43.15274, 16.67248], [43.11601, 16.53166], [42.97215, 16.51093], [42.94351, 16.49467], [42.94625, 16.39721], [42.76801, 16.40371], [42.15205, 16.40211], [40.99158, 15.81743], [43.29075, 12.79154], [43.32909, 12.59711], [43.90659, 12.3823], [51.12877, 12.56479], [57.49095, 8.14549]]]] } },
23353 { type: "Feature", properties: { iso1A2: "YT", iso1A3: "MYT", iso1N3: "175", wikidata: "Q17063", nameEn: "Mayotte", country: "FR", groups: ["Q3320166", "EU", "014", "202", "002", "UN"], callingCodes: ["262"] }, geometry: { type: "MultiPolygon", coordinates: [[[[43.28731, -13.97126], [45.54824, -13.22353], [45.4971, -11.75965], [43.28731, -13.97126]]]] } },
23354 { 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]]]] } },
23355 { 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]]]] } },
23356 { 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]]]] } }
23358 var borders = borders_default;
23359 var whichPolygonGetter = {};
23360 var featuresByCode = {};
23361 var idFilterRegex = /(?=(?!^(and|the|of|el|la|de)$))(\b(and|the|of|el|la|de)\b)|[-_ .,'()&[\]/]/gi;
23362 function canonicalID(id2) {
23363 const s = id2 || "";
23364 if (s.charAt(0) === ".") {
23365 return s.toUpperCase();
23367 return s.replace(idFilterRegex, "").toUpperCase();
23376 "intermediateRegion",
23384 loadDerivedDataAndCaches(borders);
23385 function loadDerivedDataAndCaches(borders2) {
23386 const identifierProps = ["iso1A2", "iso1A3", "m49", "wikidata", "emojiFlag", "ccTLD", "nameEn"];
23387 let geometryFeatures = [];
23388 borders2.features.forEach((feature22) => {
23389 feature22.properties.id = feature22.properties.iso1A2 || feature22.properties.m49 || feature22.properties.wikidata;
23390 loadM49(feature22);
23391 loadTLD(feature22);
23392 loadIsoStatus(feature22);
23393 loadLevel(feature22);
23394 loadGroups(feature22);
23395 loadFlag(feature22);
23396 cacheFeatureByIDs(feature22);
23397 if (feature22.geometry)
23398 geometryFeatures.push(feature22);
23400 borders2.features.forEach((feature22) => {
23401 feature22.properties.groups = feature22.properties.groups.map((groupID) => {
23402 return featuresByCode[groupID].properties.id;
23404 loadMembersForGroupsOf(feature22);
23406 borders2.features.forEach((feature22) => {
23407 loadRoadSpeedUnit(feature22);
23408 loadRoadHeightUnit(feature22);
23409 loadDriveSide(feature22);
23410 loadCallingCodes(feature22);
23411 loadGroupGroups(feature22);
23413 borders2.features.forEach((feature22) => {
23414 feature22.properties.groups.sort((groupID1, groupID2) => {
23415 return levels.indexOf(featuresByCode[groupID1].properties.level) - levels.indexOf(featuresByCode[groupID2].properties.level);
23417 if (feature22.properties.members)
23418 feature22.properties.members.sort((id1, id2) => {
23419 const diff = levels.indexOf(featuresByCode[id1].properties.level) - levels.indexOf(featuresByCode[id2].properties.level);
23421 return borders2.features.indexOf(featuresByCode[id1]) - borders2.features.indexOf(featuresByCode[id2]);
23426 const geometryOnlyCollection = {
23427 type: "FeatureCollection",
23428 features: geometryFeatures
23430 whichPolygonGetter = (0, import_which_polygon.default)(geometryOnlyCollection);
23431 function loadGroups(feature22) {
23432 const props = feature22.properties;
23433 if (!props.groups) {
23436 if (feature22.geometry && props.country) {
23437 props.groups.push(props.country);
23439 if (props.m49 !== "001") {
23440 props.groups.push("001");
23443 function loadM49(feature22) {
23444 const props = feature22.properties;
23445 if (!props.m49 && props.iso1N3) {
23446 props.m49 = props.iso1N3;
23449 function loadTLD(feature22) {
23450 const props = feature22.properties;
23451 if (props.level === "unitedNations")
23453 if (!props.ccTLD && props.iso1A2) {
23454 props.ccTLD = "." + props.iso1A2.toLowerCase();
23457 function loadIsoStatus(feature22) {
23458 const props = feature22.properties;
23459 if (!props.isoStatus && props.iso1A2) {
23460 props.isoStatus = "official";
23463 function loadLevel(feature22) {
23464 const props = feature22.properties;
23467 if (!props.country) {
23468 props.level = "country";
23469 } else if (!props.iso1A2 || props.isoStatus === "official") {
23470 props.level = "territory";
23472 props.level = "subterritory";
23475 function loadGroupGroups(feature22) {
23476 const props = feature22.properties;
23477 if (feature22.geometry || !props.members)
23479 const featureLevelIndex = levels.indexOf(props.level);
23480 let sharedGroups = [];
23481 props.members.forEach((memberID, index) => {
23482 const member = featuresByCode[memberID];
23483 const memberGroups = member.properties.groups.filter((groupID) => {
23484 return groupID !== feature22.properties.id && featureLevelIndex < levels.indexOf(featuresByCode[groupID].properties.level);
23487 sharedGroups = memberGroups;
23489 sharedGroups = sharedGroups.filter((groupID) => memberGroups.indexOf(groupID) !== -1);
23492 props.groups = props.groups.concat(
23493 sharedGroups.filter((groupID) => props.groups.indexOf(groupID) === -1)
23495 sharedGroups.forEach((groupID) => {
23496 const groupFeature = featuresByCode[groupID];
23497 if (groupFeature.properties.members.indexOf(props.id) === -1) {
23498 groupFeature.properties.members.push(props.id);
23502 function loadRoadSpeedUnit(feature22) {
23503 const props = feature22.properties;
23504 if (feature22.geometry) {
23505 if (!props.roadSpeedUnit)
23506 props.roadSpeedUnit = "km/h";
23507 } else if (props.members) {
23508 const vals = Array.from(
23510 props.members.map((id2) => {
23511 const member = featuresByCode[id2];
23512 if (member.geometry)
23513 return member.properties.roadSpeedUnit || "km/h";
23517 if (vals.length === 1)
23518 props.roadSpeedUnit = vals[0];
23521 function loadRoadHeightUnit(feature22) {
23522 const props = feature22.properties;
23523 if (feature22.geometry) {
23524 if (!props.roadHeightUnit)
23525 props.roadHeightUnit = "m";
23526 } else if (props.members) {
23527 const vals = Array.from(
23529 props.members.map((id2) => {
23530 const member = featuresByCode[id2];
23531 if (member.geometry)
23532 return member.properties.roadHeightUnit || "m";
23536 if (vals.length === 1)
23537 props.roadHeightUnit = vals[0];
23540 function loadDriveSide(feature22) {
23541 const props = feature22.properties;
23542 if (feature22.geometry) {
23543 if (!props.driveSide)
23544 props.driveSide = "right";
23545 } else if (props.members) {
23546 const vals = Array.from(
23548 props.members.map((id2) => {
23549 const member = featuresByCode[id2];
23550 if (member.geometry)
23551 return member.properties.driveSide || "right";
23555 if (vals.length === 1)
23556 props.driveSide = vals[0];
23559 function loadCallingCodes(feature22) {
23560 const props = feature22.properties;
23561 if (!feature22.geometry && props.members) {
23562 props.callingCodes = Array.from(
23564 props.members.reduce((array2, id2) => {
23565 const member = featuresByCode[id2];
23566 if (member.geometry && member.properties.callingCodes) {
23567 return array2.concat(member.properties.callingCodes);
23575 function loadFlag(feature22) {
23576 if (!feature22.properties.iso1A2)
23578 const flag = feature22.properties.iso1A2.replace(/./g, function(char) {
23579 return String.fromCodePoint(char.charCodeAt(0) + 127397);
23581 feature22.properties.emojiFlag = flag;
23583 function loadMembersForGroupsOf(feature22) {
23584 feature22.properties.groups.forEach((groupID) => {
23585 const groupFeature = featuresByCode[groupID];
23586 if (!groupFeature.properties.members) {
23587 groupFeature.properties.members = [];
23589 groupFeature.properties.members.push(feature22.properties.id);
23592 function cacheFeatureByIDs(feature22) {
23594 identifierProps.forEach((prop) => {
23595 const id2 = feature22.properties[prop];
23599 (feature22.properties.aliases || []).forEach((alias) => {
23602 ids.forEach((id2) => {
23603 let cid = canonicalID(id2);
23604 featuresByCode[cid] = feature22;
23608 function locArray(loc) {
23609 if (Array.isArray(loc)) {
23611 } else if (loc.coordinates) {
23612 return loc.coordinates;
23614 return loc.geometry.coordinates;
23616 function smallestFeature(loc) {
23617 const query = locArray(loc);
23618 const featureProperties = whichPolygonGetter(query);
23619 if (!featureProperties)
23621 return featuresByCode[featureProperties.id];
23623 function countryFeature(loc) {
23624 const feature22 = smallestFeature(loc);
23627 const countryCode = feature22.properties.country || feature22.properties.iso1A2;
23628 return featuresByCode[countryCode] || null;
23630 var defaultOpts = {
23635 function featureForLoc(loc, opts) {
23636 const targetLevel = opts.level || "country";
23637 const maxLevel = opts.maxLevel || "world";
23638 const withProp = opts.withProp;
23639 const targetLevelIndex = levels.indexOf(targetLevel);
23640 if (targetLevelIndex === -1)
23642 const maxLevelIndex = levels.indexOf(maxLevel);
23643 if (maxLevelIndex === -1)
23645 if (maxLevelIndex < targetLevelIndex)
23647 if (targetLevel === "country") {
23648 const fastFeature = countryFeature(loc);
23650 if (!withProp || fastFeature.properties[withProp]) {
23651 return fastFeature;
23655 const features = featuresContaining(loc);
23656 const match = features.find((feature22) => {
23657 let levelIndex = levels.indexOf(feature22.properties.level);
23658 if (feature22.properties.level === targetLevel || levelIndex > targetLevelIndex && levelIndex <= maxLevelIndex) {
23659 if (!withProp || feature22.properties[withProp]) {
23665 return match || null;
23667 function featureForID(id2) {
23669 if (typeof id2 === "number") {
23670 stringID = id2.toString();
23671 if (stringID.length === 1) {
23672 stringID = "00" + stringID;
23673 } else if (stringID.length === 2) {
23674 stringID = "0" + stringID;
23677 stringID = canonicalID(id2);
23679 return featuresByCode[stringID] || null;
23681 function smallestFeaturesForBbox(bbox2) {
23682 return whichPolygonGetter.bbox(bbox2).map((props) => featuresByCode[props.id]);
23684 function smallestOrMatchingFeature(query) {
23685 if (typeof query === "object") {
23686 return smallestFeature(query);
23688 return featureForID(query);
23690 function feature(query, opts = defaultOpts) {
23691 if (typeof query === "object") {
23692 return featureForLoc(query, opts);
23694 return featureForID(query);
23696 function iso1A2Code(query, opts = defaultOpts) {
23697 opts.withProp = "iso1A2";
23698 const match = feature(query, opts);
23701 return match.properties.iso1A2 || null;
23703 function featuresContaining(query, strict) {
23704 let matchingFeatures;
23705 if (Array.isArray(query) && query.length === 4) {
23706 matchingFeatures = smallestFeaturesForBbox(query);
23708 const smallestOrMatching = smallestOrMatchingFeature(query);
23709 matchingFeatures = smallestOrMatching ? [smallestOrMatching] : [];
23711 if (!matchingFeatures.length)
23713 let returnFeatures;
23714 if (!strict || typeof query === "object") {
23715 returnFeatures = matchingFeatures.slice();
23717 returnFeatures = [];
23719 matchingFeatures.forEach((feature22) => {
23720 const properties = feature22.properties;
23721 properties.groups.forEach((groupID) => {
23722 const groupFeature = featuresByCode[groupID];
23723 if (returnFeatures.indexOf(groupFeature) === -1) {
23724 returnFeatures.push(groupFeature);
23728 return returnFeatures;
23730 function featuresIn(id2, strict) {
23731 const feature22 = featureForID(id2);
23736 features.push(feature22);
23738 const properties = feature22.properties;
23739 (properties.members || []).forEach((memberID) => {
23740 features.push(featuresByCode[memberID]);
23744 function aggregateFeature(id2) {
23745 const features = featuresIn(id2, false);
23746 if (features.length === 0)
23748 let aggregateCoordinates = [];
23749 features.forEach((feature22) => {
23750 if (feature22.geometry && feature22.geometry.type === "MultiPolygon" && feature22.geometry.coordinates) {
23751 aggregateCoordinates = aggregateCoordinates.concat(feature22.geometry.coordinates);
23756 properties: features[0].properties,
23758 type: "MultiPolygon",
23759 coordinates: aggregateCoordinates
23763 function roadSpeedUnit(query) {
23764 const feature22 = smallestOrMatchingFeature(query);
23765 return feature22 && feature22.properties.roadSpeedUnit || null;
23767 function roadHeightUnit(query) {
23768 const feature22 = smallestOrMatchingFeature(query);
23769 return feature22 && feature22.properties.roadHeightUnit || null;
23772 // node_modules/@ideditor/location-conflation/index.mjs
23773 var import_geojson_area = __toESM(require_geojson_area(), 1);
23774 var import_circle_to_polygon = __toESM(require_circle_to_polygon(), 1);
23775 var import_polygon_clipping = __toESM(require_polygon_clipping_umd(), 1);
23776 var import_geojson_precision = __toESM(require_geojson_precision(), 1);
23777 var import_json_stringify_pretty_compact = __toESM(require_json_stringify_pretty_compact(), 1);
23778 var location_conflation_default = class {
23781 // `fc` Optional FeatureCollection of known features
23783 // Optionally pass a GeoJSON FeatureCollection of known features which we can refer to later.
23784 // Each feature must have a filename-like `id`, for example: `something.geojson`
23787 // "type": "FeatureCollection"
23790 // "type": "Feature",
23791 // "id": "philly_metro.geojson",
23792 // "properties": { … },
23793 // "geometry": { … }
23799 this._strict = true;
23800 if (fc && fc.type === "FeatureCollection" && Array.isArray(fc.features)) {
23801 fc.features.forEach((feature3) => {
23802 feature3.properties = feature3.properties || {};
23803 let props = feature3.properties;
23804 let id2 = feature3.id || props.id;
23805 if (!id2 || !/^\S+\.geojson$/i.test(id2))
23807 id2 = id2.toLowerCase();
23811 const area = import_geojson_area.default.geometry(feature3.geometry) / 1e6;
23812 props.area = Number(area.toFixed(2));
23814 this._cache[id2] = feature3;
23817 let world = _cloneDeep(feature("Q2"));
23820 coordinates: [[[-180, -90], [180, -90], [180, 90], [-180, 90], [-180, -90]]]
23823 world.properties.id = "Q2";
23824 world.properties.area = import_geojson_area.default.geometry(world.geometry) / 1e6;
23825 this._cache.Q2 = world;
23827 // validateLocation
23828 // `location` The location to validate
23830 // Pass a `location` value to validate
23832 // Returns a result like:
23834 // type: 'point', 'geojson', or 'countrycoder'
23835 // location: the queried location
23836 // id: the stable identifier for the feature
23838 // or `null` if the location is invalid
23840 validateLocation(location) {
23841 if (Array.isArray(location) && (location.length === 2 || location.length === 3)) {
23842 const lon = location[0];
23843 const lat = location[1];
23844 const radius = location[2];
23845 if (Number.isFinite(lon) && lon >= -180 && lon <= 180 && Number.isFinite(lat) && lat >= -90 && lat <= 90 && (location.length === 2 || Number.isFinite(radius) && radius > 0)) {
23846 const id2 = "[" + location.toString() + "]";
23847 return { type: "point", location, id: id2 };
23849 } else if (typeof location === "string" && /^\S+\.geojson$/i.test(location)) {
23850 const id2 = location.toLowerCase();
23851 if (this._cache[id2]) {
23852 return { type: "geojson", location, id: id2 };
23854 } else if (typeof location === "string" || typeof location === "number") {
23855 const feature3 = feature(location);
23857 const id2 = feature3.properties.wikidata;
23858 return { type: "countrycoder", location, id: id2 };
23861 if (this._strict) {
23862 throw new Error(`validateLocation: Invalid location: "${location}".`);
23868 // `location` The location to resolve
23870 // Pass a `location` value to resolve
23872 // Returns a result like:
23874 // type: 'point', 'geojson', or 'countrycoder'
23875 // location: the queried location
23876 // id: a stable identifier for the feature
23877 // feature: the resolved GeoJSON feature
23879 // or `null` if the location is invalid
23881 resolveLocation(location) {
23882 const valid = this.validateLocation(location);
23885 const id2 = valid.id;
23886 if (this._cache[id2]) {
23887 return Object.assign(valid, { feature: this._cache[id2] });
23889 if (valid.type === "point") {
23890 const lon = location[0];
23891 const lat = location[1];
23892 const radius = location[2] || 25;
23894 const PRECISION = 3;
23895 const area = Math.PI * radius * radius;
23896 const feature3 = this._cache[id2] = (0, import_geojson_precision.default)({
23899 properties: { id: id2, area: Number(area.toFixed(2)) },
23900 geometry: (0, import_circle_to_polygon.default)([lon, lat], radius * 1e3, EDGES)
23903 return Object.assign(valid, { feature: feature3 });
23904 } else if (valid.type === "geojson") {
23905 } else if (valid.type === "countrycoder") {
23906 let feature3 = _cloneDeep(feature(id2));
23907 let props = feature3.properties;
23908 if (Array.isArray(props.members)) {
23909 let aggregate = aggregateFeature(id2);
23910 aggregate.geometry.coordinates = _clip([aggregate], "UNION").geometry.coordinates;
23911 feature3.geometry = aggregate.geometry;
23914 const area = import_geojson_area.default.geometry(feature3.geometry) / 1e6;
23915 props.area = Number(area.toFixed(2));
23919 this._cache[id2] = feature3;
23920 return Object.assign(valid, { feature: feature3 });
23922 if (this._strict) {
23923 throw new Error(`resolveLocation: Couldn't resolve location "${location}".`);
23928 // validateLocationSet
23929 // `locationSet` the locationSet to validate
23931 // Pass a locationSet Object to validate like:
23933 // include: [ Array of locations ],
23934 // exclude: [ Array of locations ]
23937 // Returns a result like:
23939 // type: 'locationset'
23940 // locationSet: the queried locationSet
23941 // id: the stable identifier for the feature
23943 // or `null` if the locationSet is invalid
23945 validateLocationSet(locationSet) {
23946 locationSet = locationSet || {};
23947 const validator = this.validateLocation.bind(this);
23948 let include = (locationSet.include || []).map(validator).filter(Boolean);
23949 let exclude = (locationSet.exclude || []).map(validator).filter(Boolean);
23950 if (!include.length) {
23951 if (this._strict) {
23952 throw new Error(`validateLocationSet: LocationSet includes nothing.`);
23954 locationSet.include = ["Q2"];
23955 include = [{ type: "countrycoder", location: "Q2", id: "Q2" }];
23958 include.sort(_sortLocations);
23959 let id2 = "+[" + include.map((d) => d.id).join(",") + "]";
23960 if (exclude.length) {
23961 exclude.sort(_sortLocations);
23962 id2 += "-[" + exclude.map((d) => d.id).join(",") + "]";
23964 return { type: "locationset", locationSet, id: id2 };
23966 // resolveLocationSet
23967 // `locationSet` the locationSet to resolve
23969 // Pass a locationSet Object to validate like:
23971 // include: [ Array of locations ],
23972 // exclude: [ Array of locations ]
23975 // Returns a result like:
23977 // type: 'locationset'
23978 // locationSet: the queried locationSet
23979 // id: the stable identifier for the feature
23980 // feature: the resolved GeoJSON feature
23982 // or `null` if the locationSet is invalid
23984 resolveLocationSet(locationSet) {
23985 locationSet = locationSet || {};
23986 const valid = this.validateLocationSet(locationSet);
23989 const id2 = valid.id;
23990 if (this._cache[id2]) {
23991 return Object.assign(valid, { feature: this._cache[id2] });
23993 const resolver = this.resolveLocation.bind(this);
23994 const includes = (locationSet.include || []).map(resolver).filter(Boolean);
23995 const excludes = (locationSet.exclude || []).map(resolver).filter(Boolean);
23996 if (includes.length === 1 && excludes.length === 0) {
23997 return Object.assign(valid, { feature: includes[0].feature });
23999 const includeGeoJSON = _clip(includes.map((d) => d.feature), "UNION");
24000 const excludeGeoJSON = _clip(excludes.map((d) => d.feature), "UNION");
24001 let resultGeoJSON = excludeGeoJSON ? _clip([includeGeoJSON, excludeGeoJSON], "DIFFERENCE") : includeGeoJSON;
24002 const area = import_geojson_area.default.geometry(resultGeoJSON.geometry) / 1e6;
24003 resultGeoJSON.id = id2;
24004 resultGeoJSON.properties = { id: id2, area: Number(area.toFixed(2)) };
24005 this._cache[id2] = resultGeoJSON;
24006 return Object.assign(valid, { feature: resultGeoJSON });
24011 if (val === void 0) {
24012 return this._strict;
24014 this._strict = val;
24019 // convenience method to access the internal cache
24021 return this._cache;
24024 // convenience method to prettyStringify the given object
24025 stringify(obj, options2) {
24026 return (0, import_json_stringify_pretty_compact.default)(obj, options2);
24029 function _clip(features, which) {
24030 if (!Array.isArray(features) || !features.length)
24032 const fn = { UNION: import_polygon_clipping.default.union, DIFFERENCE: import_polygon_clipping.default.difference }[which];
24033 const args = features.map((feature3) => feature3.geometry.coordinates);
24034 const coords = fn.apply(null, args);
24039 type: whichType(coords),
24040 coordinates: coords
24043 function whichType(coords2) {
24044 const a = Array.isArray(coords2);
24045 const b = a && Array.isArray(coords2[0]);
24046 const c = b && Array.isArray(coords2[0][0]);
24047 const d = c && Array.isArray(coords2[0][0][0]);
24048 return d ? "MultiPolygon" : "Polygon";
24051 function _cloneDeep(obj) {
24052 return JSON.parse(JSON.stringify(obj));
24054 function _sortLocations(a, b) {
24055 const rank = { countrycoder: 1, geojson: 2, point: 3 };
24056 const aRank = rank[a.type];
24057 const bRank = rank[b.type];
24058 return aRank > bRank ? 1 : aRank < bRank ? -1 : a.id.localeCompare(b.id);
24061 // modules/core/LocationManager.js
24062 var import_which_polygon2 = __toESM(require_which_polygon());
24063 var import_geojson_area2 = __toESM(require_geojson_area());
24064 var _loco = new location_conflation_default();
24065 var LocationManager = class {
24071 this._resolved = /* @__PURE__ */ new Map();
24072 this._knownLocationSets = /* @__PURE__ */ new Map();
24073 this._locationIncludedIn = /* @__PURE__ */ new Map();
24074 this._locationExcludedIn = /* @__PURE__ */ new Map();
24075 const world = { locationSet: { include: ["Q2"] } };
24076 this._resolveLocationSet(world);
24077 this._rebuildIndex();
24080 * _validateLocationSet
24081 * Pass an Object with a `locationSet` property.
24082 * Validates the `locationSet` and sets a `locationSetID` property on the object.
24083 * To avoid so much computation we only resolve the include and exclude regions, but not the locationSet itself.
24085 * Use `_resolveLocationSet()` instead if you need to resolve geojson of locationSet, for example to render it.
24086 * Note: You need to call `_rebuildIndex()` after you're all finished validating the locationSets.
24088 * @param `obj` Object to check, it should have `locationSet` property
24090 _validateLocationSet(obj) {
24091 if (obj.locationSetID)
24094 let locationSet = obj.locationSet;
24095 if (!locationSet) {
24096 throw new Error("object missing locationSet property");
24098 if (!locationSet.include) {
24099 locationSet.include = ["Q2"];
24101 const locationSetID = _loco.validateLocationSet(locationSet).id;
24102 obj.locationSetID = locationSetID;
24103 if (this._knownLocationSets.has(locationSetID))
24106 (locationSet.include || []).forEach((location) => {
24107 const locationID = _loco.validateLocation(location).id;
24108 let geojson = this._resolved.get(locationID);
24110 geojson = _loco.resolveLocation(location).feature;
24111 this._resolved.set(locationID, geojson);
24113 area += geojson.properties.area;
24114 let s = this._locationIncludedIn.get(locationID);
24116 s = /* @__PURE__ */ new Set();
24117 this._locationIncludedIn.set(locationID, s);
24119 s.add(locationSetID);
24121 (locationSet.exclude || []).forEach((location) => {
24122 const locationID = _loco.validateLocation(location).id;
24123 let geojson = this._resolved.get(locationID);
24125 geojson = _loco.resolveLocation(location).feature;
24126 this._resolved.set(locationID, geojson);
24128 area -= geojson.properties.area;
24129 let s = this._locationExcludedIn.get(locationID);
24131 s = /* @__PURE__ */ new Set();
24132 this._locationExcludedIn.set(locationID, s);
24134 s.add(locationSetID);
24136 this._knownLocationSets.set(locationSetID, area);
24138 obj.locationSet = { include: ["Q2"] };
24139 obj.locationSetID = "+[Q2]";
24143 * _resolveLocationSet
24144 * Does everything that `_validateLocationSet()` does, but then "resolves" the locationSet into GeoJSON.
24145 * This step is a bit more computationally expensive, so really only needed if you intend to render the shape.
24147 * Note: You need to call `_rebuildIndex()` after you're all finished validating the locationSets.
24149 * @param `obj` Object to check, it should have `locationSet` property
24151 _resolveLocationSet(obj) {
24152 this._validateLocationSet(obj);
24153 if (this._resolved.has(obj.locationSetID))
24156 const result = _loco.resolveLocationSet(obj.locationSet);
24157 const locationSetID = result.id;
24158 obj.locationSetID = locationSetID;
24159 if (!result.feature.geometry.coordinates.length || !result.feature.properties.area) {
24160 throw new Error(`locationSet ${locationSetID} resolves to an empty feature.`);
24162 let geojson = JSON.parse(JSON.stringify(result.feature));
24163 geojson.id = locationSetID;
24164 geojson.properties.id = locationSetID;
24165 this._resolved.set(locationSetID, geojson);
24167 obj.locationSet = { include: ["Q2"] };
24168 obj.locationSetID = "+[Q2]";
24173 * Rebuilds the whichPolygon index with whatever features have been resolved into GeoJSON.
24176 this._wp = (0, import_which_polygon2.default)({ features: [...this._resolved.values()] });
24179 * mergeCustomGeoJSON
24180 * Accepts a FeatureCollection-like object containing custom locations
24181 * Each feature must have a filename-like `id`, for example: `something.geojson`
24183 * "type": "FeatureCollection"
24186 * "type": "Feature",
24187 * "id": "philly_metro.geojson",
24188 * "properties": { … },
24189 * "geometry": { … }
24194 * @param `fc` FeatureCollection-like Object containing custom locations
24196 mergeCustomGeoJSON(fc) {
24197 if (!fc || fc.type !== "FeatureCollection" || !Array.isArray(fc.features))
24199 fc.features.forEach((feature3) => {
24200 feature3.properties = feature3.properties || {};
24201 let props = feature3.properties;
24202 let id2 = feature3.id || props.id;
24203 if (!id2 || !/^\S+\.geojson$/i.test(id2))
24205 id2 = id2.toLowerCase();
24209 const area = import_geojson_area2.default.geometry(feature3.geometry) / 1e6;
24210 props.area = Number(area.toFixed(2));
24212 _loco._cache[id2] = feature3;
24216 * mergeLocationSets
24217 * Accepts an Array of Objects containing `locationSet` properties:
24219 * { id: 'preset1', locationSet: {…} },
24220 * { id: 'preset2', locationSet: {…} },
24223 * After validating, the Objects will be decorated with a `locationSetID` property:
24225 * { id: 'preset1', locationSet: {…}, locationSetID: '+[Q2]' },
24226 * { id: 'preset2', locationSet: {…}, locationSetID: '+[Q30]' },
24230 * @param `objects` Objects to check - they should have `locationSet` property
24231 * @return Promise resolved true (this function used to be slow/async, now it's faster and sync)
24233 mergeLocationSets(objects) {
24234 if (!Array.isArray(objects))
24235 return Promise.reject("nothing to do");
24236 objects.forEach((obj) => this._validateLocationSet(obj));
24237 this._rebuildIndex();
24238 return Promise.resolve(objects);
24242 * Returns a locationSetID for a given locationSet (fallback to `+[Q2]`, world)
24243 * (The locationSet doesn't necessarily need to be resolved to compute its `id`)
24245 * @param `locationSet` A locationSet Object, e.g. `{ include: ['us'] }`
24246 * @return String locationSetID, e.g. `+[Q30]`
24248 locationSetID(locationSet) {
24251 locationSetID = _loco.validateLocationSet(locationSet).id;
24253 locationSetID = "+[Q2]";
24255 return locationSetID;
24259 * Returns the resolved GeoJSON feature for a given locationSetID (fallback to 'world')
24260 * A GeoJSON feature:
24264 * properties: { id: '+[Q30]', area: 21817019.17, … },
24268 * @param `locationSetID` String identifier, e.g. `+[Q30]`
24269 * @return GeoJSON object (fallback to world)
24271 feature(locationSetID = "+[Q2]") {
24272 const feature3 = this._resolved.get(locationSetID);
24273 return feature3 || this._resolved.get("+[Q2]");
24277 * Find all the locationSets valid at the given location.
24278 * Results include the area (in km²) to facilitate sorting.
24280 * Object of locationSetIDs to areas (in km²)
24282 * "+[Q2]": 511207893.3958111,
24283 * "+[Q30]": 21817019.17,
24284 * "+[new_jersey.geojson]": 22390.77,
24288 * @param `loc` `[lon,lat]` location to query, e.g. `[-74.4813, 40.7967]`
24289 * @return Object of locationSetIDs valid at given location
24291 locationSetsAt(loc) {
24293 const hits = this._wp(loc, true) || [];
24295 hits.forEach((prop) => {
24296 if (prop.id[0] !== "+")
24298 const locationSetID = prop.id;
24299 const area = thiz._knownLocationSets.get(locationSetID);
24301 result[locationSetID] = area;
24304 hits.forEach((prop) => {
24305 if (prop.id[0] === "+")
24307 const locationID = prop.id;
24308 const included = thiz._locationIncludedIn.get(locationID);
24309 (included || []).forEach((locationSetID) => {
24310 const area = thiz._knownLocationSets.get(locationSetID);
24312 result[locationSetID] = area;
24316 hits.forEach((prop) => {
24317 if (prop.id[0] === "+")
24319 const locationID = prop.id;
24320 const excluded = thiz._locationExcludedIn.get(locationID);
24321 (excluded || []).forEach((locationSetID) => {
24322 delete result[locationSetID];
24327 // Direct access to the location-conflation resolver
24332 var _sharedLocationManager = new LocationManager();
24334 // node_modules/lodash-es/_freeGlobal.js
24335 var freeGlobal = typeof global == "object" && global && global.Object === Object && global;
24336 var freeGlobal_default = freeGlobal;
24338 // node_modules/lodash-es/_root.js
24339 var freeSelf = typeof self == "object" && self && self.Object === Object && self;
24340 var root2 = freeGlobal_default || freeSelf || Function("return this")();
24341 var root_default = root2;
24343 // node_modules/lodash-es/_Symbol.js
24344 var Symbol2 = root_default.Symbol;
24345 var Symbol_default = Symbol2;
24347 // node_modules/lodash-es/_getRawTag.js
24348 var objectProto = Object.prototype;
24349 var hasOwnProperty = objectProto.hasOwnProperty;
24350 var nativeObjectToString = objectProto.toString;
24351 var symToStringTag = Symbol_default ? Symbol_default.toStringTag : void 0;
24352 function getRawTag(value) {
24353 var isOwn = hasOwnProperty.call(value, symToStringTag), tag = value[symToStringTag];
24355 value[symToStringTag] = void 0;
24356 var unmasked = true;
24359 var result = nativeObjectToString.call(value);
24362 value[symToStringTag] = tag;
24364 delete value[symToStringTag];
24369 var getRawTag_default = getRawTag;
24371 // node_modules/lodash-es/_objectToString.js
24372 var objectProto2 = Object.prototype;
24373 var nativeObjectToString2 = objectProto2.toString;
24374 function objectToString(value) {
24375 return nativeObjectToString2.call(value);
24377 var objectToString_default = objectToString;
24379 // node_modules/lodash-es/_baseGetTag.js
24380 var nullTag = "[object Null]";
24381 var undefinedTag = "[object Undefined]";
24382 var symToStringTag2 = Symbol_default ? Symbol_default.toStringTag : void 0;
24383 function baseGetTag(value) {
24384 if (value == null) {
24385 return value === void 0 ? undefinedTag : nullTag;
24387 return symToStringTag2 && symToStringTag2 in Object(value) ? getRawTag_default(value) : objectToString_default(value);
24389 var baseGetTag_default = baseGetTag;
24391 // node_modules/lodash-es/isObjectLike.js
24392 function isObjectLike(value) {
24393 return value != null && typeof value == "object";
24395 var isObjectLike_default = isObjectLike;
24397 // node_modules/lodash-es/isSymbol.js
24398 var symbolTag = "[object Symbol]";
24399 function isSymbol(value) {
24400 return typeof value == "symbol" || isObjectLike_default(value) && baseGetTag_default(value) == symbolTag;
24402 var isSymbol_default = isSymbol;
24404 // node_modules/lodash-es/_arrayMap.js
24405 function arrayMap(array2, iteratee) {
24406 var index = -1, length = array2 == null ? 0 : array2.length, result = Array(length);
24407 while (++index < length) {
24408 result[index] = iteratee(array2[index], index, array2);
24412 var arrayMap_default = arrayMap;
24414 // node_modules/lodash-es/isArray.js
24415 var isArray = Array.isArray;
24416 var isArray_default = isArray;
24418 // node_modules/lodash-es/_baseToString.js
24419 var INFINITY = 1 / 0;
24420 var symbolProto = Symbol_default ? Symbol_default.prototype : void 0;
24421 var symbolToString = symbolProto ? symbolProto.toString : void 0;
24422 function baseToString(value) {
24423 if (typeof value == "string") {
24426 if (isArray_default(value)) {
24427 return arrayMap_default(value, baseToString) + "";
24429 if (isSymbol_default(value)) {
24430 return symbolToString ? symbolToString.call(value) : "";
24432 var result = value + "";
24433 return result == "0" && 1 / value == -INFINITY ? "-0" : result;
24435 var baseToString_default = baseToString;
24437 // node_modules/lodash-es/_trimmedEndIndex.js
24438 var reWhitespace = /\s/;
24439 function trimmedEndIndex(string) {
24440 var index = string.length;
24441 while (index-- && reWhitespace.test(string.charAt(index))) {
24445 var trimmedEndIndex_default = trimmedEndIndex;
24447 // node_modules/lodash-es/_baseTrim.js
24448 var reTrimStart = /^\s+/;
24449 function baseTrim(string) {
24450 return string ? string.slice(0, trimmedEndIndex_default(string) + 1).replace(reTrimStart, "") : string;
24452 var baseTrim_default = baseTrim;
24454 // node_modules/lodash-es/isObject.js
24455 function isObject(value) {
24456 var type2 = typeof value;
24457 return value != null && (type2 == "object" || type2 == "function");
24459 var isObject_default = isObject;
24461 // node_modules/lodash-es/toNumber.js
24463 var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
24464 var reIsBinary = /^0b[01]+$/i;
24465 var reIsOctal = /^0o[0-7]+$/i;
24466 var freeParseInt = parseInt;
24467 function toNumber(value) {
24468 if (typeof value == "number") {
24471 if (isSymbol_default(value)) {
24474 if (isObject_default(value)) {
24475 var other = typeof value.valueOf == "function" ? value.valueOf() : value;
24476 value = isObject_default(other) ? other + "" : other;
24478 if (typeof value != "string") {
24479 return value === 0 ? value : +value;
24481 value = baseTrim_default(value);
24482 var isBinary = reIsBinary.test(value);
24483 return isBinary || reIsOctal.test(value) ? freeParseInt(value.slice(2), isBinary ? 2 : 8) : reIsBadHex.test(value) ? NAN : +value;
24485 var toNumber_default = toNumber;
24487 // node_modules/lodash-es/toString.js
24488 function toString(value) {
24489 return value == null ? "" : baseToString_default(value);
24491 var toString_default = toString;
24493 // node_modules/lodash-es/_basePropertyOf.js
24494 function basePropertyOf(object) {
24495 return function(key) {
24496 return object == null ? void 0 : object[key];
24499 var basePropertyOf_default = basePropertyOf;
24501 // node_modules/lodash-es/now.js
24502 var now2 = function() {
24503 return root_default.Date.now();
24505 var now_default = now2;
24507 // node_modules/lodash-es/debounce.js
24508 var FUNC_ERROR_TEXT = "Expected a function";
24509 var nativeMax = Math.max;
24510 var nativeMin = Math.min;
24511 function debounce(func, wait, options2) {
24512 var lastArgs, lastThis, maxWait, result, timerId, lastCallTime, lastInvokeTime = 0, leading = false, maxing = false, trailing = true;
24513 if (typeof func != "function") {
24514 throw new TypeError(FUNC_ERROR_TEXT);
24516 wait = toNumber_default(wait) || 0;
24517 if (isObject_default(options2)) {
24518 leading = !!options2.leading;
24519 maxing = "maxWait" in options2;
24520 maxWait = maxing ? nativeMax(toNumber_default(options2.maxWait) || 0, wait) : maxWait;
24521 trailing = "trailing" in options2 ? !!options2.trailing : trailing;
24523 function invokeFunc(time) {
24524 var args = lastArgs, thisArg = lastThis;
24525 lastArgs = lastThis = void 0;
24526 lastInvokeTime = time;
24527 result = func.apply(thisArg, args);
24530 function leadingEdge(time) {
24531 lastInvokeTime = time;
24532 timerId = setTimeout(timerExpired, wait);
24533 return leading ? invokeFunc(time) : result;
24535 function remainingWait(time) {
24536 var timeSinceLastCall = time - lastCallTime, timeSinceLastInvoke = time - lastInvokeTime, timeWaiting = wait - timeSinceLastCall;
24537 return maxing ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke) : timeWaiting;
24539 function shouldInvoke(time) {
24540 var timeSinceLastCall = time - lastCallTime, timeSinceLastInvoke = time - lastInvokeTime;
24541 return lastCallTime === void 0 || timeSinceLastCall >= wait || timeSinceLastCall < 0 || maxing && timeSinceLastInvoke >= maxWait;
24543 function timerExpired() {
24544 var time = now_default();
24545 if (shouldInvoke(time)) {
24546 return trailingEdge(time);
24548 timerId = setTimeout(timerExpired, remainingWait(time));
24550 function trailingEdge(time) {
24552 if (trailing && lastArgs) {
24553 return invokeFunc(time);
24555 lastArgs = lastThis = void 0;
24558 function cancel() {
24559 if (timerId !== void 0) {
24560 clearTimeout(timerId);
24562 lastInvokeTime = 0;
24563 lastArgs = lastCallTime = lastThis = timerId = void 0;
24566 return timerId === void 0 ? result : trailingEdge(now_default());
24568 function debounced() {
24569 var time = now_default(), isInvoking = shouldInvoke(time);
24570 lastArgs = arguments;
24572 lastCallTime = time;
24574 if (timerId === void 0) {
24575 return leadingEdge(lastCallTime);
24578 clearTimeout(timerId);
24579 timerId = setTimeout(timerExpired, wait);
24580 return invokeFunc(lastCallTime);
24583 if (timerId === void 0) {
24584 timerId = setTimeout(timerExpired, wait);
24588 debounced.cancel = cancel;
24589 debounced.flush = flush;
24592 var debounce_default = debounce;
24594 // node_modules/lodash-es/_escapeHtmlChar.js
24595 var htmlEscapes = {
24602 var escapeHtmlChar = basePropertyOf_default(htmlEscapes);
24603 var escapeHtmlChar_default = escapeHtmlChar;
24605 // node_modules/lodash-es/escape.js
24606 var reUnescapedHtml = /[&<>"']/g;
24607 var reHasUnescapedHtml = RegExp(reUnescapedHtml.source);
24608 function escape2(string) {
24609 string = toString_default(string);
24610 return string && reHasUnescapedHtml.test(string) ? string.replace(reUnescapedHtml, escapeHtmlChar_default) : string;
24612 var escape_default = escape2;
24614 // node_modules/lodash-es/throttle.js
24615 var FUNC_ERROR_TEXT2 = "Expected a function";
24616 function throttle(func, wait, options2) {
24617 var leading = true, trailing = true;
24618 if (typeof func != "function") {
24619 throw new TypeError(FUNC_ERROR_TEXT2);
24621 if (isObject_default(options2)) {
24622 leading = "leading" in options2 ? !!options2.leading : leading;
24623 trailing = "trailing" in options2 ? !!options2.trailing : trailing;
24625 return debounce_default(func, wait, {
24626 "leading": leading,
24628 "trailing": trailing
24631 var throttle_default = throttle;
24633 // node_modules/lodash-es/_unescapeHtmlChar.js
24634 var htmlUnescapes = {
24641 var unescapeHtmlChar = basePropertyOf_default(htmlUnescapes);
24642 var unescapeHtmlChar_default = unescapeHtmlChar;
24644 // node_modules/lodash-es/unescape.js
24645 var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g;
24646 var reHasEscapedHtml = RegExp(reEscapedHtml.source);
24647 function unescape2(string) {
24648 string = toString_default(string);
24649 return string && reHasEscapedHtml.test(string) ? string.replace(reEscapedHtml, unescapeHtmlChar_default) : string;
24651 var unescape_default = unescape2;
24653 // modules/util/detect.js
24655 function utilDetect(refresh2) {
24656 if (_detected && !refresh2)
24659 const ua = navigator.userAgent;
24661 m = ua.match(/(edge)\/?\s*(\.?\d+(\.\d+)*)/i);
24663 _detected.browser = m[1];
24664 _detected.version = m[2];
24666 if (!_detected.browser) {
24667 m = ua.match(/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/i);
24669 _detected.browser = "msie";
24670 _detected.version = m[1];
24673 if (!_detected.browser) {
24674 m = ua.match(/(opr)\/?\s*(\.?\d+(\.\d+)*)/i);
24676 _detected.browser = "Opera";
24677 _detected.version = m[2];
24680 if (!_detected.browser) {
24681 m = ua.match(/(opera|chrome|safari|firefox|msie)\/?\s*(\.?\d+(\.\d+)*)/i);
24683 _detected.browser = m[1];
24684 _detected.version = m[2];
24685 m = ua.match(/version\/([\.\d]+)/i);
24687 _detected.version = m[1];
24690 if (!_detected.browser) {
24691 _detected.browser = navigator.appName;
24692 _detected.version = navigator.appVersion;
24694 _detected.version = _detected.version.split(/\W/).slice(0, 2).join(".");
24695 _detected.opera = _detected.browser.toLowerCase() === "opera" && Number(_detected.version) < 15;
24696 if (_detected.browser.toLowerCase() === "msie") {
24697 _detected.ie = true;
24698 _detected.browser = "Internet Explorer";
24699 _detected.support = false;
24701 _detected.ie = false;
24702 _detected.support = true;
24704 _detected.filedrop = window.FileReader && "ondrop" in window;
24705 if (/Win/.test(ua)) {
24706 _detected.os = "win";
24707 _detected.platform = "Windows";
24708 } else if (/Mac/.test(ua)) {
24709 _detected.os = "mac";
24710 _detected.platform = "Macintosh";
24711 } else if (/X11/.test(ua) || /Linux/.test(ua)) {
24712 _detected.os = "linux";
24713 _detected.platform = "Linux";
24715 _detected.os = "win";
24716 _detected.platform = "Unknown";
24718 _detected.isMobileWebKit = (/\b(iPad|iPhone|iPod)\b/.test(ua) || // HACK: iPadOS 13+ requests desktop sites by default by using a Mac user agent,
24719 // so assume any "mac" with multitouch is actually iOS
24720 navigator.platform === "MacIntel" && "maxTouchPoints" in navigator && navigator.maxTouchPoints > 1) && /WebKit/.test(ua) && !/Edge/.test(ua) && !window.MSStream;
24721 _detected.browserLocales = Array.from(new Set(
24722 // remove duplicates
24723 [navigator.language].concat(navigator.languages || []).concat([
24724 // old property for backwards compatibility
24725 navigator.userLanguage
24728 const loc = window.top.location;
24729 let origin = loc.origin;
24731 origin = loc.protocol + "//" + loc.hostname + (loc.port ? ":" + loc.port : "");
24733 _detected.host = origin + loc.pathname;
24737 // modules/util/aes.js
24738 var import_aes_js = __toESM(require_aes_js());
24739 var DEFAULT_128 = [250, 157, 60, 79, 142, 134, 229, 129, 138, 126, 210, 129, 29, 71, 160, 208];
24740 function utilAesEncrypt(text2, key) {
24741 key = key || DEFAULT_128;
24742 const textBytes = import_aes_js.default.utils.utf8.toBytes(text2);
24743 const aesCtr = new import_aes_js.default.ModeOfOperation.ctr(key);
24744 const encryptedBytes = aesCtr.encrypt(textBytes);
24745 const encryptedHex = import_aes_js.default.utils.hex.fromBytes(encryptedBytes);
24746 return encryptedHex;
24748 function utilAesDecrypt(encryptedHex, key) {
24749 key = key || DEFAULT_128;
24750 const encryptedBytes = import_aes_js.default.utils.hex.toBytes(encryptedHex);
24751 const aesCtr = new import_aes_js.default.ModeOfOperation.ctr(key);
24752 const decryptedBytes = aesCtr.decrypt(encryptedBytes);
24753 const text2 = import_aes_js.default.utils.utf8.fromBytes(decryptedBytes);
24757 // modules/util/clean_tags.js
24758 function utilCleanTags(tags) {
24760 for (var k in tags) {
24764 if (v !== void 0) {
24765 out[k] = cleanValue(k, v);
24769 function cleanValue(k2, v2) {
24770 function keepSpaces(k3) {
24771 return /_hours|_times|:conditional$/.test(k3);
24773 function skip(k3) {
24774 return /^(description|note|fixme)$/.test(k3);
24778 var cleaned = v2.split(";").map(function(s) {
24780 }).join(keepSpaces(k2) ? "; " : ";");
24781 if (k2.indexOf("website") !== -1 || k2.indexOf("email") !== -1 || cleaned.indexOf("http") === 0) {
24782 cleaned = cleaned.replace(/[\u200B-\u200F\uFEFF]/g, "");
24788 // modules/util/get_set_value.js
24789 function utilGetSetValue(selection2, value) {
24790 function d3_selection_value(value2) {
24791 function valueNull() {
24794 function valueConstant() {
24795 if (this.value !== value2) {
24796 this.value = value2;
24799 function valueFunction() {
24800 var x = value2.apply(this, arguments);
24801 if (x === null || x === void 0) {
24803 } else if (this.value !== x) {
24807 return value2 === null || value2 === void 0 ? valueNull : typeof value2 === "function" ? valueFunction : valueConstant;
24809 if (arguments.length === 1) {
24810 return selection2.property("value");
24812 return selection2.each(d3_selection_value(value));
24815 // modules/util/keybinding.js
24816 function utilKeybinding(namespace) {
24817 var _keybindings = {};
24818 function testBindings(d3_event, isCapturing) {
24819 var didMatch = false;
24820 var bindings = Object.keys(_keybindings).map(function(id2) {
24821 return _keybindings[id2];
24824 for (i2 = 0; i2 < bindings.length; i2++) {
24825 binding = bindings[i2];
24826 if (!binding.event.modifiers.shiftKey)
24828 if (!!binding.capture !== isCapturing)
24830 if (matches(d3_event, binding, true)) {
24831 binding.callback(d3_event);
24838 for (i2 = 0; i2 < bindings.length; i2++) {
24839 binding = bindings[i2];
24840 if (binding.event.modifiers.shiftKey)
24842 if (!!binding.capture !== isCapturing)
24844 if (matches(d3_event, binding, false)) {
24845 binding.callback(d3_event);
24849 function matches(d3_event2, binding2, testShift) {
24850 var event = d3_event2;
24851 var isMatch = false;
24852 var tryKeyCode = true;
24853 if (event.key !== void 0) {
24854 tryKeyCode = event.key.charCodeAt(0) > 127;
24856 if (binding2.event.key === void 0) {
24858 } else if (Array.isArray(binding2.event.key)) {
24859 if (binding2.event.key.map(function(s) {
24860 return s.toLowerCase();
24861 }).indexOf(event.key.toLowerCase()) === -1) {
24865 if (event.key.toLowerCase() !== binding2.event.key.toLowerCase()) {
24870 if (!isMatch && (tryKeyCode || binding2.event.modifiers.altKey)) {
24871 isMatch = event.keyCode === binding2.event.keyCode;
24875 if (!(event.ctrlKey && event.altKey)) {
24876 if (event.ctrlKey !== binding2.event.modifiers.ctrlKey)
24878 if (event.altKey !== binding2.event.modifiers.altKey)
24881 if (event.metaKey !== binding2.event.modifiers.metaKey)
24883 if (testShift && event.shiftKey !== binding2.event.modifiers.shiftKey)
24888 function capture(d3_event) {
24889 testBindings(d3_event, true);
24891 function bubble(d3_event) {
24892 var tagName = select_default2(d3_event.target).node().tagName;
24893 if (tagName === "INPUT" || tagName === "SELECT" || tagName === "TEXTAREA") {
24896 testBindings(d3_event, false);
24898 function keybinding(selection2) {
24899 selection2 = selection2 || select_default2(document);
24900 selection2.on("keydown.capture." + namespace, capture, true);
24901 selection2.on("keydown.bubble." + namespace, bubble, false);
24904 keybinding.unbind = function(selection2) {
24906 selection2 = selection2 || select_default2(document);
24907 selection2.on("keydown.capture." + namespace, null);
24908 selection2.on("keydown.bubble." + namespace, null);
24911 keybinding.clear = function() {
24915 keybinding.off = function(codes, capture2) {
24916 var arr = utilArrayUniq([].concat(codes));
24917 for (var i2 = 0; i2 < arr.length; i2++) {
24918 var id2 = arr[i2] + (capture2 ? "-capture" : "-bubble");
24919 delete _keybindings[id2];
24923 keybinding.on = function(codes, callback, capture2) {
24924 if (typeof callback !== "function") {
24925 return keybinding.off(codes, capture2);
24927 var arr = utilArrayUniq([].concat(codes));
24928 for (var i2 = 0; i2 < arr.length; i2++) {
24929 var id2 = arr[i2] + (capture2 ? "-capture" : "-bubble");
24947 if (_keybindings[id2]) {
24948 console.warn('warning: duplicate keybinding for "' + id2 + '"');
24950 _keybindings[id2] = binding;
24951 var matches = arr[i2].toLowerCase().match(/(?:(?:[^+⇧⌃⌥⌘])+|[⇧⌃⌥⌘]|\+\+|^\+$)/g);
24952 for (var j2 = 0; j2 < matches.length; j2++) {
24953 if (matches[j2] === "++")
24955 if (matches[j2] in utilKeybinding.modifierCodes) {
24956 var prop = utilKeybinding.modifierProperties[utilKeybinding.modifierCodes[matches[j2]]];
24957 binding.event.modifiers[prop] = true;
24959 binding.event.key = utilKeybinding.keys[matches[j2]] || matches[j2];
24960 if (matches[j2] in utilKeybinding.keyCodes) {
24961 binding.event.keyCode = utilKeybinding.keyCodes[matches[j2]];
24970 utilKeybinding.modifierCodes = {
24974 // CTRL key, on Mac: ⌃
24977 // ALT key, on Mac: ⌥ (Alt)
24981 // META, on Mac: ⌘ (CMD), on Windows (Win), on Linux (Super)
24988 utilKeybinding.modifierProperties = {
24994 utilKeybinding.plusKeys = ["plus", "ffplus", "=", "ffequals", "\u2260", "\xB1"];
24995 utilKeybinding.minusKeys = ["_", "-", "ffminus", "dash", "\u2013", "\u2014"];
24996 utilKeybinding.keys = {
24997 // Backspace key, on Mac: ⌫ (Backspace)
24998 "\u232B": "Backspace",
24999 backspace: "Backspace",
25000 // Tab Key, on Mac: ⇥ (Tab), on Windows ⇥⇥
25013 "pause-break": "Pause",
25014 // Caps Lock key, ⇪
25015 "\u21EA": "CapsLock",
25017 "caps-lock": "CapsLock",
25018 // Escape key, on Mac: ⎋, on Windows: Esc
25019 "\u238B": ["Escape", "Esc"],
25020 escape: ["Escape", "Esc"],
25021 esc: ["Escape", "Esc"],
25023 space: [" ", "Spacebar"],
25024 // Page-Up key, or pgup, on Mac: ↖
25025 "\u2196": "PageUp",
25027 "page-up": "PageUp",
25028 // Page-Down key, or pgdown, on Mac: ↘
25029 "\u2198": "PageDown",
25030 pgdown: "PageDown",
25031 "page-down": "PageDown",
25032 // END key, on Mac: ⇟
25035 // HOME key, on Mac: ⇞
25038 // Insert key, or ins
25041 // Delete key, on Mac: ⌦ (Delete)
25042 "\u2326": ["Delete", "Del"],
25043 del: ["Delete", "Del"],
25044 "delete": ["Delete", "Del"],
25045 // Left Arrow Key, or ←
25046 "\u2190": ["ArrowLeft", "Left"],
25047 left: ["ArrowLeft", "Left"],
25048 "arrow-left": ["ArrowLeft", "Left"],
25049 // Up Arrow Key, or ↑
25050 "\u2191": ["ArrowUp", "Up"],
25051 up: ["ArrowUp", "Up"],
25052 "arrow-up": ["ArrowUp", "Up"],
25053 // Right Arrow Key, or →
25054 "\u2192": ["ArrowRight", "Right"],
25055 right: ["ArrowRight", "Right"],
25056 "arrow-right": ["ArrowRight", "Right"],
25057 // Up Arrow Key, or ↓
25058 "\u2193": ["ArrowDown", "Down"],
25059 down: ["ArrowDown", "Down"],
25060 "arrow-down": ["ArrowDown", "Down"],
25061 // odities, stuff for backward compatibility (browsers and code):
25062 // Num-Multiply, or *
25063 "*": ["*", "Multiply"],
25064 star: ["*", "Multiply"],
25065 asterisk: ["*", "Multiply"],
25066 multiply: ["*", "Multiply"],
25069 "plus": ["+", "Add"],
25070 // Num-Subtract, or -
25071 "-": ["-", "Subtract"],
25072 subtract: ["-", "Subtract"],
25073 "dash": ["-", "Subtract"],
25080 // Period, or ., or full-stop
25083 // Slash, or /, or forward-slash
25085 "forward-slash": "/",
25086 // Tick, or `, or back-quote
25089 // Open bracket, or [
25090 "open-bracket": "[",
25091 // Back slash, or \
25092 "back-slash": "\\",
25093 // Close backet, or ]
25094 "close-bracket": "]",
25095 // Apostrophe, or Quote, or '
25136 utilKeybinding.keyCodes = {
25137 // Backspace key, on Mac: ⌫ (Backspace)
25140 // Tab Key, on Mac: ⇥ (Tab), on Windows ⇥⇥
25154 // Caps Lock key, ⇪
25158 // Escape key, on Mac: ⎋, on Windows: Esc
25164 // Page-Up key, or pgup, on Mac: ↖
25168 // Page-Down key, or pgdown, on Mac: ↘
25172 // END key, on Mac: ⇟
25175 // HOME key, on Mac: ⇞
25178 // Insert key, or ins
25181 // Delete key, on Mac: ⌦ (Delete)
25185 // Left Arrow Key, or ←
25189 // Up Arrow Key, or ↑
25193 // Right Arrow Key, or →
25197 // Up Arrow Key, or ↓
25201 // odities, printing characters that come out wrong:
25204 // Num-Multiply, or *
25212 // Num-Subtract, or -
25215 // Vertical Bar / Pipe
25230 // Dash / Underscore key
25232 // Period, or ., or full-stop
25236 // Slash, or /, or forward-slash
25239 "forward-slash": 191,
25240 // Tick, or `, or back-quote
25244 // Open bracket, or [
25246 "open-bracket": 219,
25247 // Back slash, or \
25250 // Close backet, or ]
25252 "close-bracket": 221,
25253 // Apostrophe, or Quote, or '
25260 while (++i < 106) {
25261 utilKeybinding.keyCodes["num-" + n] = i;
25267 utilKeybinding.keyCodes[n] = i;
25272 while (++i < 136) {
25273 utilKeybinding.keyCodes["f" + n] = i;
25278 utilKeybinding.keyCodes[String.fromCharCode(i).toLowerCase()] = i;
25281 // modules/util/object.js
25282 function utilObjectOmit(obj, omitKeys) {
25283 return Object.keys(obj).reduce(function(result, key) {
25284 if (omitKeys.indexOf(key) === -1) {
25285 result[key] = obj[key];
25291 // modules/util/rebind.js
25292 function utilRebind(target, source) {
25293 var i2 = 1, n2 = arguments.length, method;
25294 while (++i2 < n2) {
25295 target[method = arguments[i2]] = d3_rebind(target, source, source[method]);
25299 function d3_rebind(target, source, method) {
25300 return function() {
25301 var value = method.apply(source, arguments);
25302 return value === source ? target : value;
25306 // modules/util/session_mutex.js
25307 function utilSessionMutex(name) {
25311 var expires = /* @__PURE__ */ new Date();
25312 expires.setSeconds(expires.getSeconds() + 5);
25313 document.cookie = name + "=1; expires=" + expires.toUTCString() + "; sameSite=strict";
25315 mutex.lock = function() {
25318 var cookie = document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + name + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1");
25322 intervalID = window.setInterval(renew, 4e3);
25325 mutex.unlock = function() {
25328 document.cookie = name + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT; sameSite=strict";
25329 clearInterval(intervalID);
25332 mutex.locked = function() {
25333 return !!intervalID;
25338 // modules/util/tiler.js
25339 function utilTiler() {
25340 var _size = [256, 256];
25342 var _tileSize = 256;
25343 var _zoomExtent = [0, 20];
25344 var _translate = [_size[0] / 2, _size[1] / 2];
25346 var _skipNullIsland = false;
25347 function clamp3(num, min3, max3) {
25348 return Math.max(min3, Math.min(num, max3));
25350 function nearNullIsland(tile) {
25355 var center = Math.pow(2, z - 1);
25356 var width = Math.pow(2, z - 6);
25357 var min3 = center - width / 2;
25358 var max3 = center + width / 2 - 1;
25359 return x >= min3 && x <= max3 && y >= min3 && y <= max3;
25363 function tiler8() {
25364 var z = geoScaleToZoom(_scale / (2 * Math.PI), _tileSize);
25365 var z0 = clamp3(Math.round(z), _zoomExtent[0], _zoomExtent[1]);
25367 var tileMax = Math.pow(2, z0) - 1;
25368 var log2ts = Math.log(_tileSize) * Math.LOG2E;
25369 var k = Math.pow(2, z - z0 + log2ts);
25371 (_translate[0] - _scale / 2) / k,
25372 (_translate[1] - _scale / 2) / k
25375 clamp3(Math.floor(-origin[0]) - _margin, tileMin, tileMax + 1),
25376 clamp3(Math.ceil(_size[0] / k - origin[0]) + _margin, tileMin, tileMax + 1)
25379 clamp3(Math.floor(-origin[1]) - _margin, tileMin, tileMax + 1),
25380 clamp3(Math.ceil(_size[1] / k - origin[1]) + _margin, tileMin, tileMax + 1)
25383 for (var i2 = 0; i2 < rows.length; i2++) {
25385 for (var j2 = 0; j2 < cols.length; j2++) {
25387 if (i2 >= _margin && i2 <= rows.length - _margin && j2 >= _margin && j2 <= cols.length - _margin) {
25388 tiles.unshift([x, y, z0]);
25390 tiles.push([x, y, z0]);
25394 tiles.translate = origin;
25398 tiler8.getTiles = function(projection2) {
25400 projection2.scale() * Math.PI - projection2.translate()[0],
25401 projection2.scale() * Math.PI - projection2.translate()[1]
25403 this.size(projection2.clipExtent()[1]).scale(projection2.scale() * 2 * Math.PI).translate(projection2.translate());
25404 var tiles = tiler8();
25405 var ts = tiles.scale;
25406 return tiles.map(function(tile) {
25407 if (_skipNullIsland && nearNullIsland(tile)) {
25410 var x = tile[0] * ts - origin[0];
25411 var y = tile[1] * ts - origin[1];
25413 id: tile.toString(),
25416 projection2.invert([x, y + ts]),
25417 projection2.invert([x + ts, y])
25420 }).filter(Boolean);
25422 tiler8.getGeoJSON = function(projection2) {
25423 var features = tiler8.getTiles(projection2).map(function(tile) {
25432 coordinates: [tile.extent.polygon()]
25437 type: "FeatureCollection",
25441 tiler8.tileSize = function(val) {
25442 if (!arguments.length)
25447 tiler8.zoomExtent = function(val) {
25448 if (!arguments.length)
25449 return _zoomExtent;
25453 tiler8.size = function(val) {
25454 if (!arguments.length)
25459 tiler8.scale = function(val) {
25460 if (!arguments.length)
25465 tiler8.translate = function(val) {
25466 if (!arguments.length)
25471 tiler8.margin = function(val) {
25472 if (!arguments.length)
25477 tiler8.skipNullIsland = function(val) {
25478 if (!arguments.length)
25479 return _skipNullIsland;
25480 _skipNullIsland = val;
25486 // modules/util/trigger_event.js
25487 function utilTriggerEvent(target, type2) {
25488 target.each(function() {
25489 var evt = document.createEvent("HTMLEvents");
25490 evt.initEvent(type2, true, true);
25491 this.dispatchEvent(evt);
25495 // modules/core/localizer.js
25496 var _mainLocalizer = coreLocalizer();
25497 var _t = _mainLocalizer.t;
25498 function coreLocalizer() {
25499 let localizer = {};
25500 let _dataLanguages = {};
25501 let _dataLocales = {};
25502 let _localeStrings = {};
25503 let _localeCode = "en-US";
25504 let _localeCodes = ["en-US", "en"];
25505 let _languageCode = "en";
25506 let _textDirection = "ltr";
25507 let _usesMetric = false;
25508 let _languageNames = {};
25509 let _scriptNames = {};
25510 localizer.localeCode = () => _localeCode;
25511 localizer.localeCodes = () => _localeCodes;
25512 localizer.languageCode = () => _languageCode;
25513 localizer.textDirection = () => _textDirection;
25514 localizer.usesMetric = () => _usesMetric;
25515 localizer.languageNames = () => _languageNames;
25516 localizer.scriptNames = () => _scriptNames;
25517 let _preferredLocaleCodes = [];
25518 localizer.preferredLocaleCodes = function(codes) {
25519 if (!arguments.length)
25520 return _preferredLocaleCodes;
25521 if (typeof codes === "string") {
25522 _preferredLocaleCodes = codes.split(/,|;| /gi).filter(Boolean);
25524 _preferredLocaleCodes = codes;
25529 localizer.ensureLoaded = () => {
25531 return _loadPromise;
25532 let filesToFetch = [
25534 // load the list of languages
25536 // load the list of supported locales
25538 const localeDirs = {
25539 general: "locales",
25540 tagging: presetsCdnUrl + "dist/translations"
25542 let fileMap = _mainFileFetcher.fileMap();
25543 for (let scopeId in localeDirs) {
25544 const key = `locales_index_${scopeId}`;
25545 if (!fileMap[key]) {
25546 fileMap[key] = localeDirs[scopeId] + "/index.min.json";
25548 filesToFetch.push(key);
25550 return _loadPromise = Promise.all(filesToFetch.map((key) => _mainFileFetcher.get(key))).then((results) => {
25551 _dataLanguages = results[0];
25552 _dataLocales = results[1];
25553 let indexes = results.slice(2);
25554 let requestedLocales = (_preferredLocaleCodes || []).concat(utilDetect().browserLocales).concat(["en"]);
25555 _localeCodes = localesToUseFrom(requestedLocales);
25556 _localeCode = _localeCodes[0];
25557 let loadStringsPromises = [];
25558 indexes.forEach((index, i2) => {
25559 const fullCoverageIndex = _localeCodes.findIndex(function(locale2) {
25560 return index[locale2] && index[locale2].pct === 1;
25562 _localeCodes.slice(0, fullCoverageIndex + 1).forEach(function(code) {
25563 let scopeId = Object.keys(localeDirs)[i2];
25564 let directory = Object.values(localeDirs)[i2];
25566 loadStringsPromises.push(localizer.loadLocale(code, scopeId, directory));
25569 return Promise.all(loadStringsPromises);
25571 updateForCurrentLocale();
25572 }).catch((err) => console.error(err));
25574 function localesToUseFrom(requestedLocales) {
25575 let supportedLocales = _dataLocales;
25577 for (let i2 in requestedLocales) {
25578 let locale2 = requestedLocales[i2];
25579 if (supportedLocales[locale2])
25580 toUse.push(locale2);
25581 if (locale2.includes("-")) {
25582 let langPart = locale2.split("-")[0];
25583 if (supportedLocales[langPart])
25584 toUse.push(langPart);
25587 return utilArrayUniq(toUse);
25589 function updateForCurrentLocale() {
25592 _languageCode = _localeCode.split("-")[0];
25593 const currentData = _dataLocales[_localeCode] || _dataLocales[_languageCode];
25594 const hash = utilStringQs(window.location.hash);
25595 if (hash.rtl === "true") {
25596 _textDirection = "rtl";
25597 } else if (hash.rtl === "false") {
25598 _textDirection = "ltr";
25600 _textDirection = currentData && currentData.rtl ? "rtl" : "ltr";
25602 let locale2 = _localeCode;
25603 if (locale2.toLowerCase() === "en-us")
25605 _languageNames = _localeStrings.general[locale2].languageNames;
25606 _scriptNames = _localeStrings.general[locale2].scriptNames;
25607 _usesMetric = _localeCode.slice(-3).toLowerCase() !== "-us";
25609 localizer.loadLocale = (locale2, scopeId, directory) => {
25610 if (locale2.toLowerCase() === "en-us")
25612 if (_localeStrings[scopeId] && _localeStrings[scopeId][locale2]) {
25613 return Promise.resolve(locale2);
25615 let fileMap = _mainFileFetcher.fileMap();
25616 const key = `locale_${scopeId}_${locale2}`;
25617 if (!fileMap[key]) {
25618 fileMap[key] = `${directory}/${locale2}.min.json`;
25620 return _mainFileFetcher.get(key).then((d) => {
25621 if (!_localeStrings[scopeId])
25622 _localeStrings[scopeId] = {};
25623 _localeStrings[scopeId][locale2] = d[locale2];
25627 localizer.pluralRule = function(number3) {
25628 return pluralRule(number3, _localeCode);
25630 function pluralRule(number3, localeCode) {
25631 const rules = "Intl" in window && Intl.PluralRules && new Intl.PluralRules(localeCode);
25633 return rules.select(number3);
25639 localizer.tInfo = function(origStringId, replacements, locale2) {
25640 let stringId = origStringId.trim();
25641 let scopeId = "general";
25642 if (stringId[0] === "_") {
25643 let split = stringId.split(".");
25644 scopeId = split[0].slice(1);
25645 stringId = split.slice(1).join(".");
25647 locale2 = locale2 || _localeCode;
25648 let path = stringId.split(".").map((s) => s.replace(/<TX_DOT>/g, ".")).reverse();
25649 let stringsKey = locale2;
25650 if (stringsKey.toLowerCase() === "en-us")
25652 let result = _localeStrings && _localeStrings[scopeId] && _localeStrings[scopeId][stringsKey];
25653 while (result !== void 0 && path.length) {
25654 result = result[path.pop()];
25656 if (result !== void 0) {
25657 if (replacements) {
25658 if (typeof result === "object" && Object.keys(result).length) {
25659 const number3 = Object.values(replacements).find(function(value) {
25660 return typeof value === "number";
25662 if (number3 !== void 0) {
25663 const rule = pluralRule(number3, locale2);
25664 if (result[rule]) {
25665 result = result[rule];
25667 result = Object.values(result)[0];
25671 if (typeof result === "string") {
25672 for (let key in replacements) {
25673 let value = replacements[key];
25674 if (typeof value === "number") {
25675 if (value.toLocaleString) {
25676 value = value.toLocaleString(locale2, {
25679 minimumFractionDigits: 0
25682 value = value.toString();
25685 const token = `{${key}}`;
25686 const regex = new RegExp(token, "g");
25687 result = result.replace(regex, value);
25691 if (typeof result === "string") {
25698 let index = _localeCodes.indexOf(locale2);
25699 if (index >= 0 && index < _localeCodes.length - 1) {
25700 let fallback = _localeCodes[index + 1];
25701 return localizer.tInfo(origStringId, replacements, fallback);
25703 if (replacements && "default" in replacements) {
25705 text: replacements.default,
25709 const missing = `Missing ${locale2} translation: ${origStringId}`;
25710 if (typeof console !== "undefined")
25711 console.error(missing);
25717 localizer.hasTextForStringId = function(stringId) {
25718 return !!localizer.tInfo(stringId, { default: "nothing found" }).locale;
25720 localizer.t = function(stringId, replacements, locale2) {
25721 return localizer.tInfo(stringId, replacements, locale2).text;
25723 localizer.t.html = function(stringId, replacements, locale2) {
25724 replacements = Object.assign({}, replacements);
25725 for (var k in replacements) {
25726 if (typeof replacements[k] === "string") {
25727 replacements[k] = escape_default(replacements[k]);
25729 if (typeof replacements[k] === "object" && typeof replacements[k].html === "string") {
25730 replacements[k] = replacements[k].html;
25733 const info = localizer.tInfo(stringId, replacements, locale2);
25735 return `<span class="localized-text" lang="${info.locale || "und"}">${info.text}</span>`;
25740 localizer.t.append = function(stringId, replacements, locale2) {
25741 const ret = function(selection2) {
25742 const info = localizer.tInfo(stringId, replacements, locale2);
25743 return selection2.append("span").attr("class", "localized-text").attr("lang", info.locale || "und").text((replacements && replacements.prefix || "") + info.text + (replacements && replacements.suffix || ""));
25745 ret.stringId = stringId;
25748 localizer.languageName = (code, options2) => {
25749 if (_languageNames[code]) {
25750 return _languageNames[code];
25752 if (options2 && options2.localOnly)
25754 const langInfo = _dataLanguages[code];
25756 if (langInfo.nativeName) {
25757 return localizer.t("translate.language_and_code", { language: langInfo.nativeName, code });
25758 } else if (langInfo.base && langInfo.script) {
25759 const base = langInfo.base;
25760 if (_languageNames[base]) {
25761 const scriptCode = langInfo.script;
25762 const script = _scriptNames[scriptCode] || scriptCode;
25763 return localizer.t("translate.language_and_code", { language: _languageNames[base], code: script });
25764 } else if (_dataLanguages[base] && _dataLanguages[base].nativeName) {
25765 return localizer.t("translate.language_and_code", { language: _dataLanguages[base].nativeName, code });
25774 // modules/presets/collection.js
25775 function presetCollection(collection) {
25776 const MAXRESULTS = 50;
25779 _this.collection = collection;
25780 _this.item = (id2) => {
25783 const found = _this.collection.find((d) => d.id === id2);
25785 _memo[id2] = found;
25788 _this.index = (id2) => _this.collection.findIndex((d) => d.id === id2);
25789 _this.matchGeometry = (geometry) => {
25790 return presetCollection(
25791 _this.collection.filter((d) => d.matchGeometry(geometry))
25794 _this.matchAllGeometry = (geometries) => {
25795 return presetCollection(
25796 _this.collection.filter((d) => d && d.matchAllGeometry(geometries))
25799 _this.matchAnyGeometry = (geometries) => {
25800 return presetCollection(
25801 _this.collection.filter((d) => geometries.some((geom) => d.matchGeometry(geom)))
25804 _this.fallback = (geometry) => {
25805 let id2 = geometry;
25806 if (id2 === "vertex")
25808 return _this.item(id2);
25810 _this.search = (value, geometry, loc) => {
25813 value = value.toLowerCase().trim();
25814 function leading(a) {
25815 const index = a.indexOf(value);
25816 return index === 0 || a[index - 1] === " ";
25818 function leadingStrict(a) {
25819 const index = a.indexOf(value);
25820 return index === 0;
25822 function sortPresets(nameProp, aliasesProp) {
25823 return function sortNames(a, b) {
25824 let aCompare = a[nameProp]();
25825 let bCompare = b[nameProp]();
25827 const findMatchingAlias = (strings) => {
25828 if (strings.some((s) => s === value)) {
25829 return strings.find((s) => s === value);
25831 return strings.filter((s) => s.includes(value)).sort((a2, b2) => a2.length - b2.length)[0];
25834 aCompare = findMatchingAlias([aCompare].concat(a[aliasesProp]()));
25835 bCompare = findMatchingAlias([bCompare].concat(b[aliasesProp]()));
25837 if (value === aCompare)
25839 if (value === bCompare)
25841 let i2 = b.originalScore - a.originalScore;
25844 i2 = aCompare.indexOf(value) - bCompare.indexOf(value);
25847 return aCompare.length - bCompare.length;
25850 let pool = _this.collection;
25851 if (Array.isArray(loc)) {
25852 const validHere = _sharedLocationManager.locationSetsAt(loc);
25853 pool = pool.filter((a) => !a.locationSetID || validHere[a.locationSetID]);
25855 const searchable = pool.filter((a) => a.searchable !== false && a.suggestion !== true);
25856 const suggestions = pool.filter((a) => a.suggestion === true);
25857 const leadingNames = searchable.filter((a) => leading(a.searchName()) || a.searchAliases().some(leading)).sort(sortPresets("searchName", "searchAliases"));
25858 const leadingSuggestions = suggestions.filter((a) => leadingStrict(a.searchName())).sort(sortPresets("searchName"));
25859 const leadingNamesStripped = searchable.filter((a) => leading(a.searchNameStripped()) || a.searchAliasesStripped().some(leading)).sort(sortPresets("searchNameStripped", "searchAliasesStripped"));
25860 const leadingSuggestionsStripped = suggestions.filter((a) => leadingStrict(a.searchNameStripped())).sort(sortPresets("searchNameStripped"));
25861 const leadingTerms = searchable.filter((a) => (a.terms() || []).some(leading));
25862 const leadingSuggestionTerms = suggestions.filter((a) => (a.terms() || []).some(leading));
25863 const leadingTagValues = searchable.filter((a) => Object.values(a.tags || {}).filter((val) => val !== "*").some(leading));
25864 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);
25865 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);
25866 const similarTerms = searchable.filter((a) => {
25867 return (a.terms() || []).some((b) => {
25868 return utilEditDistance(value, b) + Math.min(value.length - b.length, 0) < 3;
25871 let leadingTagKeyValues = [];
25872 if (value.includes("=")) {
25873 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]))));
25875 let results = leadingNames.concat(
25876 leadingSuggestions,
25877 leadingNamesStripped,
25878 leadingSuggestionsStripped,
25880 leadingSuggestionTerms,
25883 similarSuggestions,
25885 leadingTagKeyValues
25886 ).slice(0, MAXRESULTS - 1);
25888 if (typeof geometry === "string") {
25889 results.push(_this.fallback(geometry));
25891 geometry.forEach((geom) => results.push(_this.fallback(geom)));
25894 return presetCollection(utilArrayUniq(results));
25899 // modules/presets/category.js
25900 function presetCategory(categoryID, category, allPresets) {
25901 let _this = Object.assign({}, category);
25903 let _searchNameStripped;
25904 _this.id = categoryID;
25905 _this.members = presetCollection(
25906 (category.members || []).map((presetID) => allPresets[presetID]).filter(Boolean)
25908 _this.geometry = _this.members.collection.reduce((acc, preset) => {
25909 for (let i2 in preset.geometry) {
25910 const geometry = preset.geometry[i2];
25911 if (acc.indexOf(geometry) === -1) {
25912 acc.push(geometry);
25917 _this.matchGeometry = (geom) => _this.geometry.indexOf(geom) >= 0;
25918 _this.matchAllGeometry = (geometries) => _this.members.collection.some((preset) => preset.matchAllGeometry(geometries));
25919 _this.matchScore = () => -1;
25920 _this.name = () => _t(`_tagging.presets.categories.${categoryID}.name`, { "default": categoryID });
25921 _this.nameLabel = () => _t.append(`_tagging.presets.categories.${categoryID}.name`, { "default": categoryID });
25922 _this.terms = () => [];
25923 _this.searchName = () => {
25924 if (!_searchName) {
25925 _searchName = (_this.suggestion ? _this.originalName : _this.name()).toLowerCase();
25927 return _searchName;
25929 _this.searchNameStripped = () => {
25930 if (!_searchNameStripped) {
25931 _searchNameStripped = _this.searchName();
25932 if (_searchNameStripped.normalize)
25933 _searchNameStripped = _searchNameStripped.normalize("NFD");
25934 _searchNameStripped = _searchNameStripped.replace(/[\u0300-\u036f]/g, "");
25936 return _searchNameStripped;
25938 _this.searchAliases = () => [];
25939 _this.searchAliasesStripped = () => [];
25943 // modules/presets/field.js
25944 function presetField(fieldID, field, allFields) {
25945 allFields = allFields || {};
25946 let _this = Object.assign({}, field);
25947 _this.id = fieldID;
25948 _this.safeid = utilSafeClassName(fieldID);
25949 _this.matchGeometry = (geom) => !_this.geometry || _this.geometry.indexOf(geom) !== -1;
25950 _this.matchAllGeometry = (geometries) => {
25951 return !_this.geometry || geometries.every((geom) => _this.geometry.indexOf(geom) !== -1);
25953 _this.t = (scope, options2) => _t(`_tagging.presets.fields.${fieldID}.${scope}`, options2);
25954 _this.t.html = (scope, options2) => _t.html(`_tagging.presets.fields.${fieldID}.${scope}`, options2);
25955 _this.t.append = (scope, options2) => _t.append(`_tagging.presets.fields.${fieldID}.${scope}`, options2);
25956 _this.hasTextForStringId = (scope) => _mainLocalizer.hasTextForStringId(`_tagging.presets.fields.${fieldID}.${scope}`);
25957 _this.resolveReference = (which) => {
25958 const referenceRegex = /^\{(.*)\}$/;
25959 const match = (field[which] || "").match(referenceRegex);
25961 const field2 = allFields[match[1]];
25965 console.error(`Unable to resolve referenced field: ${match[1]}`);
25969 _this.title = () => _this.overrideLabel || _this.resolveReference("label").t("label", { "default": fieldID });
25970 _this.label = () => _this.overrideLabel ? (selection2) => selection2.text(_this.overrideLabel) : _this.resolveReference("label").t.append("label", { "default": fieldID });
25971 _this.placeholder = () => _this.resolveReference("placeholder").t("placeholder", { "default": "" });
25972 _this.originalTerms = (_this.terms || []).join();
25973 _this.terms = () => _this.resolveReference("label").t("terms", { "default": _this.originalTerms }).toLowerCase().trim().split(/\s*,+\s*/);
25974 _this.increment = _this.type === "number" ? _this.increment || 1 : void 0;
25978 // modules/presets/preset.js
25979 function presetPreset(presetID, preset, addable, allFields, allPresets) {
25980 allFields = allFields || {};
25981 allPresets = allPresets || {};
25982 let _this = Object.assign({}, preset);
25983 let _addable = addable || false;
25984 let _resolvedFields;
25985 let _resolvedMoreFields;
25987 let _searchNameStripped;
25988 let _searchAliases;
25989 let _searchAliasesStripped;
25990 const referenceRegex = /^\{(.*)\}$/;
25991 _this.id = presetID;
25992 _this.safeid = utilSafeClassName(presetID);
25993 _this.originalTerms = (_this.terms || []).join();
25994 _this.originalName = _this.name || "";
25995 _this.originalAliases = (_this.aliases || []).join("\n");
25996 _this.originalScore = _this.matchScore || 1;
25997 _this.originalReference = _this.reference || {};
25998 _this.originalFields = _this.fields || [];
25999 _this.originalMoreFields = _this.moreFields || [];
26000 _this.fields = () => _resolvedFields || (_resolvedFields = resolveFields("fields"));
26001 _this.moreFields = () => _resolvedMoreFields || (_resolvedMoreFields = resolveFields("moreFields"));
26002 _this.resetFields = () => _resolvedFields = _resolvedMoreFields = null;
26003 _this.tags = _this.tags || {};
26004 _this.addTags = _this.addTags || _this.tags;
26005 _this.removeTags = _this.removeTags || _this.addTags;
26006 _this.geometry = _this.geometry || [];
26007 _this.matchGeometry = (geom) => _this.geometry.indexOf(geom) >= 0;
26008 _this.matchAllGeometry = (geoms) => geoms.every(_this.matchGeometry);
26009 _this.matchScore = (entityTags) => {
26010 const tags = _this.tags;
26013 for (let k in tags) {
26015 if (entityTags[k] === tags[k]) {
26016 score += _this.originalScore;
26017 } else if (tags[k] === "*" && k in entityTags) {
26018 score += _this.originalScore / 2;
26023 const addTags = _this.addTags;
26024 for (let k in addTags) {
26025 if (!seen[k] && entityTags[k] === addTags[k]) {
26026 score += _this.originalScore;
26029 if (_this.searchable === false) {
26034 _this.t = (scope, options2) => {
26035 const textID = `_tagging.presets.presets.${presetID}.${scope}`;
26036 return _t(textID, options2);
26038 _this.t.append = (scope, options2) => {
26039 const textID = `_tagging.presets.presets.${presetID}.${scope}`;
26040 return _t.append(textID, options2);
26042 function resolveReference(which) {
26043 const match = (_this[which] || "").match(referenceRegex);
26045 const preset2 = allPresets[match[1]];
26049 console.error(`Unable to resolve referenced preset: ${match[1]}`);
26053 _this.name = () => {
26054 return resolveReference("originalName").t("name", { "default": _this.originalName || presetID });
26056 _this.nameLabel = () => {
26057 return resolveReference("originalName").t.append("name", { "default": _this.originalName || presetID });
26059 _this.subtitle = () => {
26060 if (_this.suggestion) {
26061 let path = presetID.split("/");
26063 return _t("_tagging.presets.presets." + path.join("/") + ".name");
26067 _this.subtitleLabel = () => {
26068 if (_this.suggestion) {
26069 let path = presetID.split("/");
26071 return _t.append("_tagging.presets.presets." + path.join("/") + ".name");
26075 _this.aliases = () => {
26076 return resolveReference("originalName").t("aliases", { "default": _this.originalAliases }).trim().split(/\s*[\r\n]+\s*/);
26078 _this.terms = () => {
26079 return resolveReference("originalName").t("terms", { "default": _this.originalTerms }).toLowerCase().trim().split(/\s*,+\s*/);
26081 _this.searchName = () => {
26082 if (!_searchName) {
26083 _searchName = (_this.suggestion ? _this.originalName : _this.name()).toLowerCase();
26085 return _searchName;
26087 _this.searchNameStripped = () => {
26088 if (!_searchNameStripped) {
26089 _searchNameStripped = stripDiacritics(_this.searchName());
26091 return _searchNameStripped;
26093 _this.searchAliases = () => {
26094 if (!_searchAliases) {
26095 _searchAliases = _this.aliases().map((alias) => alias.toLowerCase());
26097 return _searchAliases;
26099 _this.searchAliasesStripped = () => {
26100 if (!_searchAliasesStripped) {
26101 _searchAliasesStripped = _this.searchAliases();
26102 _searchAliasesStripped = _searchAliasesStripped.map(stripDiacritics);
26104 return _searchAliasesStripped;
26106 _this.isFallback = () => {
26107 const tagCount = Object.keys(_this.tags).length;
26108 return tagCount === 0 || tagCount === 1 && _this.tags.hasOwnProperty("area");
26110 _this.addable = function(val) {
26111 if (!arguments.length)
26116 _this.reference = () => {
26117 const qid = _this.tags.wikidata || _this.tags["flag:wikidata"] || _this.tags["brand:wikidata"] || _this.tags["network:wikidata"] || _this.tags["operator:wikidata"];
26121 let key = _this.originalReference.key || Object.keys(utilObjectOmit(_this.tags, "name"))[0];
26122 let value = _this.originalReference.value || _this.tags[key];
26123 if (value === "*") {
26126 return { key, value };
26129 _this.unsetTags = (tags, geometry, ignoringKeys, skipFieldDefaults) => {
26130 let removeTags = ignoringKeys ? utilObjectOmit(_this.removeTags, ignoringKeys) : _this.removeTags;
26131 tags = utilObjectOmit(tags, Object.keys(removeTags));
26132 if (geometry && !skipFieldDefaults) {
26133 _this.fields().forEach((field) => {
26134 if (field.matchGeometry(geometry) && field.key && field.default === tags[field.key] && (!ignoringKeys || ignoringKeys.indexOf(field.key) === -1)) {
26135 delete tags[field.key];
26142 _this.setTags = (tags, geometry, skipFieldDefaults) => {
26143 const addTags = _this.addTags;
26144 tags = Object.assign({}, tags);
26145 for (let k in addTags) {
26146 if (addTags[k] === "*") {
26147 if (_this.tags[k] || !tags[k]) {
26151 tags[k] = addTags[k];
26154 if (!addTags.hasOwnProperty("area")) {
26156 if (geometry === "area") {
26157 let needsAreaTag = true;
26158 for (let k in addTags) {
26159 if (_this.geometry.indexOf("line") === -1 && k in osmAreaKeys || k in osmAreaKeysExceptions && addTags[k] in osmAreaKeysExceptions[k]) {
26160 needsAreaTag = false;
26164 if (needsAreaTag) {
26169 if (geometry && !skipFieldDefaults) {
26170 _this.fields().forEach((field) => {
26171 if (field.matchGeometry(geometry) && field.key && !tags[field.key] && field.default) {
26172 tags[field.key] = field.default;
26178 function resolveFields(which) {
26179 const fieldIDs = which === "fields" ? _this.originalFields : _this.originalMoreFields;
26181 fieldIDs.forEach((fieldID) => {
26182 const match = fieldID.match(referenceRegex);
26183 if (match !== null) {
26184 resolved = resolved.concat(inheritFields(match[1], which));
26185 } else if (allFields[fieldID]) {
26186 resolved.push(allFields[fieldID]);
26188 console.log(`Cannot resolve "${fieldID}" found in ${_this.id}.${which}`);
26191 if (!resolved.length) {
26192 const endIndex = _this.id.lastIndexOf("/");
26193 const parentID = endIndex && _this.id.substring(0, endIndex);
26195 resolved = inheritFields(parentID, which);
26198 return utilArrayUniq(resolved);
26199 function inheritFields(presetID2, which2) {
26200 const parent = allPresets[presetID2];
26203 if (which2 === "fields") {
26204 return parent.fields().filter(shouldInherit);
26205 } else if (which2 === "moreFields") {
26206 return parent.moreFields();
26211 function shouldInherit(f2) {
26212 if (f2.key && _this.tags[f2.key] !== void 0 && // inherit anyway if multiple values are allowed or just a checkbox
26213 f2.type !== "multiCombo" && f2.type !== "semiCombo" && f2.type !== "manyCombo" && f2.type !== "check")
26218 function stripDiacritics(s) {
26220 s = s.normalize("NFD");
26221 s = s.replace(/[\u0300-\u036f]/g, "");
26227 // modules/presets/index.js
26228 var _mainPresetIndex = presetIndex();
26229 function presetIndex() {
26230 const dispatch10 = dispatch_default("favoritePreset", "recentsChange");
26231 const MAXRECENTS = 30;
26232 const POINT = presetPreset("point", { name: "Point", tags: {}, geometry: ["point", "vertex"], matchScore: 0.1 });
26233 const LINE = presetPreset("line", { name: "Line", tags: {}, geometry: ["line"], matchScore: 0.1 });
26234 const AREA = presetPreset("area", { name: "Area", tags: { area: "yes" }, geometry: ["area"], matchScore: 0.1 });
26235 const RELATION = presetPreset("relation", { name: "Relation", tags: {}, geometry: ["relation"], matchScore: 0.1 });
26236 let _this = presetCollection([POINT, LINE, AREA, RELATION]);
26237 let _presets = { point: POINT, line: LINE, area: AREA, relation: RELATION };
26239 point: presetCollection([POINT]),
26240 vertex: presetCollection([POINT]),
26241 line: presetCollection([LINE]),
26242 area: presetCollection([AREA]),
26243 relation: presetCollection([RELATION])
26246 let _categories = {};
26247 let _universal = [];
26248 let _addablePresetIDs = null;
26251 let _geometryIndex = { point: {}, vertex: {}, line: {}, area: {}, relation: {} };
26253 _this.ensureLoaded = () => {
26255 return _loadPromise;
26256 return _loadPromise = Promise.all([
26257 _mainFileFetcher.get("preset_categories"),
26258 _mainFileFetcher.get("preset_defaults"),
26259 _mainFileFetcher.get("preset_presets"),
26260 _mainFileFetcher.get("preset_fields")
26261 ]).then((vals) => {
26263 categories: vals[0],
26268 osmSetAreaKeys(_this.areaKeys());
26269 osmSetLineTags(_this.lineTags());
26270 osmSetPointTags(_this.pointTags());
26271 osmSetVertexTags(_this.vertexTags());
26274 _this.merge = (d) => {
26275 let newLocationSets = [];
26277 Object.keys(d.fields).forEach((fieldID) => {
26278 let f2 = d.fields[fieldID];
26280 f2 = presetField(fieldID, f2, _fields);
26281 if (f2.locationSet)
26282 newLocationSets.push(f2);
26283 _fields[fieldID] = f2;
26285 delete _fields[fieldID];
26290 Object.keys(d.presets).forEach((presetID) => {
26291 let p = d.presets[presetID];
26293 const isAddable = !_addablePresetIDs || _addablePresetIDs.has(presetID);
26294 p = presetPreset(presetID, p, isAddable, _fields, _presets);
26296 newLocationSets.push(p);
26297 _presets[presetID] = p;
26299 const existing = _presets[presetID];
26300 if (existing && !existing.isFallback()) {
26301 delete _presets[presetID];
26306 if (d.categories) {
26307 Object.keys(d.categories).forEach((categoryID) => {
26308 let c = d.categories[categoryID];
26310 c = presetCategory(categoryID, c, _presets);
26312 newLocationSets.push(c);
26313 _categories[categoryID] = c;
26315 delete _categories[categoryID];
26319 _this.collection = Object.values(_presets).concat(Object.values(_categories));
26321 Object.keys(d.defaults).forEach((geometry) => {
26322 const def = d.defaults[geometry];
26323 if (Array.isArray(def)) {
26324 _defaults[geometry] = presetCollection(
26325 def.map((id2) => _presets[id2] || _categories[id2]).filter(Boolean)
26328 delete _defaults[geometry];
26332 _universal = Object.values(_fields).filter((field) => field.universal);
26333 Object.values(_presets).forEach((preset) => preset.resetFields());
26334 _geometryIndex = { point: {}, vertex: {}, line: {}, area: {}, relation: {} };
26335 _this.collection.forEach((preset) => {
26336 (preset.geometry || []).forEach((geometry) => {
26337 let g = _geometryIndex[geometry];
26338 for (let key in preset.tags) {
26339 g[key] = g[key] || {};
26340 let value = preset.tags[key];
26341 (g[key][value] = g[key][value] || []).push(preset);
26345 if (d.featureCollection && Array.isArray(d.featureCollection.features)) {
26346 _sharedLocationManager.mergeCustomGeoJSON(d.featureCollection);
26348 if (newLocationSets.length) {
26349 _sharedLocationManager.mergeLocationSets(newLocationSets);
26353 _this.match = (entity, resolver) => {
26354 return resolver.transient(entity, "presetMatch", () => {
26355 let geometry = entity.geometry(resolver);
26356 if (geometry === "vertex" && entity.isOnAddressLine(resolver)) {
26357 geometry = "point";
26359 const entityExtent = entity.extent(resolver);
26360 return _this.matchTags(entity.tags, geometry, entityExtent.center());
26363 _this.matchTags = (tags, geometry, loc) => {
26364 const keyIndex = _geometryIndex[geometry];
26365 let bestScore = -1;
26367 let matchCandidates = [];
26368 for (let k in tags) {
26369 let indexMatches = [];
26370 let valueIndex = keyIndex[k];
26373 let keyValueMatches = valueIndex[tags[k]];
26374 if (keyValueMatches)
26375 indexMatches.push(...keyValueMatches);
26376 let keyStarMatches = valueIndex["*"];
26377 if (keyStarMatches)
26378 indexMatches.push(...keyStarMatches);
26379 if (indexMatches.length === 0)
26381 for (let i2 = 0; i2 < indexMatches.length; i2++) {
26382 const candidate = indexMatches[i2];
26383 const score = candidate.matchScore(tags);
26384 if (score === -1) {
26387 matchCandidates.push({ score, candidate });
26388 if (score > bestScore) {
26390 bestMatch = candidate;
26394 if (bestMatch && bestMatch.locationSetID && bestMatch.locationSetID !== "+[Q2]" && Array.isArray(loc)) {
26395 const validHere = _sharedLocationManager.locationSetsAt(loc);
26396 if (!validHere[bestMatch.locationSetID]) {
26397 matchCandidates.sort((a, b) => a.score < b.score ? 1 : -1);
26398 for (let i2 = 0; i2 < matchCandidates.length; i2++) {
26399 const candidateScore = matchCandidates[i2];
26400 if (!candidateScore.candidate.locationSetID || validHere[candidateScore.candidate.locationSetID]) {
26401 bestMatch = candidateScore.candidate;
26402 bestScore = candidateScore.score;
26408 if (!bestMatch || bestMatch.isFallback()) {
26409 for (let k in tags) {
26410 if (/^addr:/.test(k) && keyIndex["addr:*"] && keyIndex["addr:*"]["*"]) {
26411 bestMatch = keyIndex["addr:*"]["*"][0];
26416 return bestMatch || _this.fallback(geometry);
26418 _this.allowsVertex = (entity, resolver) => {
26419 if (entity.type !== "node")
26421 if (Object.keys(entity.tags).length === 0)
26423 return resolver.transient(entity, "vertexMatch", () => {
26424 if (entity.isOnAddressLine(resolver))
26426 const geometries = osmNodeGeometriesForTags(entity.tags);
26427 if (geometries.vertex)
26429 if (geometries.point)
26434 _this.areaKeys = () => {
26441 traffic_calming: true,
26445 const presets = _this.collection.filter((p) => !p.suggestion && !p.replacement);
26446 presets.forEach((p) => {
26447 const keys = p.tags && Object.keys(p.tags);
26448 const key = keys && keys.length && keys[0];
26453 if (p.geometry.indexOf("area") !== -1) {
26454 areaKeys[key] = areaKeys[key] || {};
26457 presets.forEach((p) => {
26459 for (key in p.addTags) {
26460 const value = p.addTags[key];
26461 if (key in areaKeys && // probably an area...
26462 p.geometry.indexOf("line") !== -1 && // but sometimes a line
26464 areaKeys[key][value] = true;
26470 _this.lineTags = () => {
26471 return _this.collection.filter((lineTags, d) => {
26472 if (d.suggestion || d.replacement || d.searchable === false)
26474 const keys = d.tags && Object.keys(d.tags);
26475 const key = keys && keys.length && keys[0];
26478 if (d.geometry.indexOf("line") !== -1) {
26479 lineTags[key] = lineTags[key] || [];
26480 lineTags[key].push(d.tags);
26485 _this.pointTags = () => {
26486 return _this.collection.reduce((pointTags, d) => {
26487 if (d.suggestion || d.replacement || d.searchable === false)
26489 const keys = d.tags && Object.keys(d.tags);
26490 const key = keys && keys.length && keys[0];
26493 if (d.geometry.indexOf("point") !== -1) {
26494 pointTags[key] = pointTags[key] || {};
26495 pointTags[key][d.tags[key]] = true;
26500 _this.vertexTags = () => {
26501 return _this.collection.reduce((vertexTags, d) => {
26502 if (d.suggestion || d.replacement || d.searchable === false)
26504 const keys = d.tags && Object.keys(d.tags);
26505 const key = keys && keys.length && keys[0];
26508 if (d.geometry.indexOf("vertex") !== -1) {
26509 vertexTags[key] = vertexTags[key] || {};
26510 vertexTags[key][d.tags[key]] = true;
26515 _this.field = (id2) => _fields[id2];
26516 _this.universal = () => _universal;
26517 _this.defaults = (geometry, n2, startWithRecents, loc, extraPresets) => {
26519 if (startWithRecents) {
26520 recents = _this.recent().matchGeometry(geometry).collection.slice(0, 4);
26523 if (_addablePresetIDs) {
26524 defaults2 = Array.from(_addablePresetIDs).map(function(id2) {
26525 var preset = _this.item(id2);
26526 if (preset && preset.matchGeometry(geometry))
26529 }).filter(Boolean);
26531 defaults2 = _defaults[geometry].collection.concat(_this.fallback(geometry));
26533 let result = presetCollection(
26534 utilArrayUniq(recents.concat(defaults2).concat(extraPresets || [])).slice(0, n2 - 1)
26536 if (Array.isArray(loc)) {
26537 const validHere = _sharedLocationManager.locationSetsAt(loc);
26538 result.collection = result.collection.filter((a) => !a.locationSetID || validHere[a.locationSetID]);
26542 _this.addablePresetIDs = function(val) {
26543 if (!arguments.length)
26544 return _addablePresetIDs;
26545 if (Array.isArray(val))
26546 val = new Set(val);
26547 _addablePresetIDs = val;
26548 if (_addablePresetIDs) {
26549 _this.collection.forEach((p) => {
26551 p.addable(_addablePresetIDs.has(p.id));
26554 _this.collection.forEach((p) => {
26561 _this.recent = () => {
26562 return presetCollection(
26563 utilArrayUniq(_this.getRecents().map((d) => d.preset).filter((d) => d.searchable !== false))
26566 function RibbonItem(preset, source) {
26568 item.preset = preset;
26569 item.source = source;
26570 item.isFavorite = () => item.source === "favorite";
26571 item.isRecent = () => item.source === "recent";
26572 item.matches = (preset2) => item.preset.id === preset2.id;
26573 item.minified = () => ({ pID: item.preset.id });
26576 function ribbonItemForMinified(d, source) {
26578 const preset = _this.item(d.pID);
26581 return RibbonItem(preset, source);
26585 _this.getGenericRibbonItems = () => {
26586 return ["point", "line", "area"].map((id2) => RibbonItem(_this.item(id2), "generic"));
26588 _this.getAddable = () => {
26589 if (!_addablePresetIDs)
26591 return _addablePresetIDs.map((id2) => {
26592 const preset = _this.item(id2);
26594 return RibbonItem(preset, "addable");
26596 }).filter(Boolean);
26598 function setRecents(items) {
26600 const minifiedItems = items.map((d) => d.minified());
26601 corePreferences("preset_recents", JSON.stringify(minifiedItems));
26602 dispatch10.call("recentsChange");
26604 _this.getRecents = () => {
26606 _recents = (JSON.parse(corePreferences("preset_recents")) || []).reduce((acc, d) => {
26607 let item = ribbonItemForMinified(d, "recent");
26608 if (item && item.preset.addable())
26615 _this.addRecent = (preset, besidePreset, after) => {
26616 const recents = _this.getRecents();
26617 const beforeItem = _this.recentMatching(besidePreset);
26618 let toIndex = recents.indexOf(beforeItem);
26621 const newItem = RibbonItem(preset, "recent");
26622 recents.splice(toIndex, 0, newItem);
26623 setRecents(recents);
26625 _this.removeRecent = (preset) => {
26626 const item = _this.recentMatching(preset);
26628 let items = _this.getRecents();
26629 items.splice(items.indexOf(item), 1);
26633 _this.recentMatching = (preset) => {
26634 const items = _this.getRecents();
26635 for (let i2 in items) {
26636 if (items[i2].matches(preset)) {
26642 _this.moveItem = (items, fromIndex, toIndex) => {
26643 if (fromIndex === toIndex || fromIndex < 0 || toIndex < 0 || fromIndex >= items.length || toIndex >= items.length)
26645 items.splice(toIndex, 0, items.splice(fromIndex, 1)[0]);
26648 _this.moveRecent = (item, beforeItem) => {
26649 const recents = _this.getRecents();
26650 const fromIndex = recents.indexOf(item);
26651 const toIndex = recents.indexOf(beforeItem);
26652 const items = _this.moveItem(recents, fromIndex, toIndex);
26656 _this.setMostRecent = (preset) => {
26657 if (preset.searchable === false)
26659 let items = _this.getRecents();
26660 let item = _this.recentMatching(preset);
26662 items.splice(items.indexOf(item), 1);
26664 item = RibbonItem(preset, "recent");
26666 while (items.length >= MAXRECENTS) {
26669 items.unshift(item);
26672 function setFavorites(items) {
26673 _favorites = items;
26674 const minifiedItems = items.map((d) => d.minified());
26675 corePreferences("preset_favorites", JSON.stringify(minifiedItems));
26676 dispatch10.call("favoritePreset");
26678 _this.addFavorite = (preset, besidePreset, after) => {
26679 const favorites = _this.getFavorites();
26680 const beforeItem = _this.favoriteMatching(besidePreset);
26681 let toIndex = favorites.indexOf(beforeItem);
26684 const newItem = RibbonItem(preset, "favorite");
26685 favorites.splice(toIndex, 0, newItem);
26686 setFavorites(favorites);
26688 _this.toggleFavorite = (preset) => {
26689 const favs = _this.getFavorites();
26690 const favorite = _this.favoriteMatching(preset);
26692 favs.splice(favs.indexOf(favorite), 1);
26694 if (favs.length === 10) {
26697 favs.push(RibbonItem(preset, "favorite"));
26699 setFavorites(favs);
26701 _this.removeFavorite = (preset) => {
26702 const item = _this.favoriteMatching(preset);
26704 const items = _this.getFavorites();
26705 items.splice(items.indexOf(item), 1);
26706 setFavorites(items);
26709 _this.getFavorites = () => {
26711 let rawFavorites = JSON.parse(corePreferences("preset_favorites"));
26712 if (!rawFavorites) {
26714 corePreferences("preset_favorites", JSON.stringify(rawFavorites));
26716 _favorites = rawFavorites.reduce((output, d) => {
26717 const item = ribbonItemForMinified(d, "favorite");
26718 if (item && item.preset.addable())
26725 _this.favoriteMatching = (preset) => {
26726 const favs = _this.getFavorites();
26727 for (let index in favs) {
26728 if (favs[index].matches(preset)) {
26729 return favs[index];
26734 return utilRebind(_this, dispatch10, "on");
26737 // modules/util/util.js
26738 function utilTagText(entity) {
26739 var obj = entity && entity.tags || {};
26740 return Object.keys(obj).map(function(k) {
26741 return k + "=" + obj[k];
26744 function utilTotalExtent(array2, graph) {
26745 var extent = geoExtent();
26747 for (var i2 = 0; i2 < array2.length; i2++) {
26749 entity = typeof val === "string" ? graph.hasEntity(val) : val;
26751 extent._extend(entity.extent(graph));
26756 function utilTagDiff(oldTags, newTags) {
26758 var keys = utilArrayUnion(Object.keys(oldTags), Object.keys(newTags)).sort();
26759 keys.forEach(function(k) {
26760 var oldVal = oldTags[k];
26761 var newVal = newTags[k];
26762 if ((oldVal || oldVal === "") && (newVal === void 0 || newVal !== oldVal)) {
26768 display: "- " + k + "=" + oldVal
26771 if ((newVal || newVal === "") && (oldVal === void 0 || newVal !== oldVal)) {
26777 display: "+ " + k + "=" + newVal
26783 function utilEntitySelector(ids) {
26784 return ids.length ? "." + ids.join(",.") : "nothing";
26786 function utilEntityOrMemberSelector(ids, graph) {
26787 var seen = new Set(ids);
26788 ids.forEach(collectShallowDescendants);
26789 return utilEntitySelector(Array.from(seen));
26790 function collectShallowDescendants(id2) {
26791 var entity = graph.hasEntity(id2);
26792 if (!entity || entity.type !== "relation")
26794 entity.members.map(function(member) {
26796 }).forEach(function(id3) {
26801 function utilEntityOrDeepMemberSelector(ids, graph) {
26802 return utilEntitySelector(utilEntityAndDeepMemberIDs(ids, graph));
26804 function utilEntityAndDeepMemberIDs(ids, graph) {
26805 var seen = /* @__PURE__ */ new Set();
26806 ids.forEach(collectDeepDescendants);
26807 return Array.from(seen);
26808 function collectDeepDescendants(id2) {
26812 var entity = graph.hasEntity(id2);
26813 if (!entity || entity.type !== "relation")
26815 entity.members.map(function(member) {
26817 }).forEach(collectDeepDescendants);
26820 function utilDeepMemberSelector(ids, graph, skipMultipolgonMembers) {
26821 var idsSet = new Set(ids);
26822 var seen = /* @__PURE__ */ new Set();
26823 var returners = /* @__PURE__ */ new Set();
26824 ids.forEach(collectDeepDescendants);
26825 return utilEntitySelector(Array.from(returners));
26826 function collectDeepDescendants(id2) {
26830 if (!idsSet.has(id2)) {
26831 returners.add(id2);
26833 var entity = graph.hasEntity(id2);
26834 if (!entity || entity.type !== "relation")
26836 if (skipMultipolgonMembers && entity.isMultipolygon())
26838 entity.members.map(function(member) {
26840 }).forEach(collectDeepDescendants);
26843 function utilHighlightEntities(ids, highlighted, context) {
26844 context.surface().selectAll(utilEntityOrDeepMemberSelector(ids, context.graph())).classed("highlighted", highlighted);
26846 function utilGetAllNodes(ids, graph) {
26847 var seen = /* @__PURE__ */ new Set();
26848 var nodes = /* @__PURE__ */ new Set();
26849 ids.forEach(collectNodes);
26850 return Array.from(nodes);
26851 function collectNodes(id2) {
26855 var entity = graph.hasEntity(id2);
26858 if (entity.type === "node") {
26860 } else if (entity.type === "way") {
26861 entity.nodes.forEach(collectNodes);
26863 entity.members.map(function(member) {
26865 }).forEach(collectNodes);
26869 function utilDisplayName(entity) {
26870 var localizedNameKey = "name:" + _mainLocalizer.languageCode().toLowerCase();
26871 var name = entity.tags[localizedNameKey] || entity.tags.name || "";
26875 direction: entity.tags.direction,
26876 from: entity.tags.from,
26877 network: entity.tags.cycle_network || entity.tags.network,
26878 ref: entity.tags.ref,
26879 to: entity.tags.to,
26880 via: entity.tags.via
26882 var keyComponents = [];
26883 if (tags.network) {
26884 keyComponents.push("network");
26887 keyComponents.push("ref");
26889 if (entity.tags.route) {
26890 if (tags.direction) {
26891 keyComponents.push("direction");
26892 } else if (tags.from && tags.to) {
26893 keyComponents.push("from");
26894 keyComponents.push("to");
26896 keyComponents.push("via");
26900 if (keyComponents.length) {
26901 name = _t("inspector.display_name." + keyComponents.join("_"), tags);
26905 function utilDisplayNameForPath(entity) {
26906 var name = utilDisplayName(entity);
26907 var isFirefox = utilDetect().browser.toLowerCase().indexOf("firefox") > -1;
26908 var isNewChromium = Number(utilDetect().version.split(".")[0]) >= 96;
26909 if (!isFirefox && !isNewChromium && name && rtlRegex.test(name)) {
26910 name = fixRTLTextForSvg(name);
26914 function utilDisplayType(id2) {
26916 n: _t("inspector.node"),
26917 w: _t("inspector.way"),
26918 r: _t("inspector.relation")
26921 function utilDisplayLabel(entity, graphOrGeometry, verbose) {
26923 var displayName = utilDisplayName(entity);
26924 var preset = typeof graphOrGeometry === "string" ? _mainPresetIndex.matchTags(entity.tags, graphOrGeometry) : _mainPresetIndex.match(entity, graphOrGeometry);
26925 var presetName = preset && (preset.suggestion ? preset.subtitle() : preset.name());
26927 result = [presetName, displayName].filter(Boolean).join(" ");
26929 result = displayName || presetName;
26931 return result || utilDisplayType(entity.id);
26933 function utilEntityRoot(entityType) {
26940 function utilCombinedTags(entityIDs, graph) {
26942 var tagCounts = {};
26943 var allKeys = /* @__PURE__ */ new Set();
26944 var entities = entityIDs.map(function(entityID) {
26945 return graph.hasEntity(entityID);
26946 }).filter(Boolean);
26947 entities.forEach(function(entity) {
26948 var keys = Object.keys(entity.tags).filter(Boolean);
26949 keys.forEach(function(key2) {
26953 entities.forEach(function(entity) {
26954 allKeys.forEach(function(key2) {
26955 var value = entity.tags[key2];
26956 if (!tags.hasOwnProperty(key2)) {
26957 tags[key2] = value;
26959 if (!Array.isArray(tags[key2])) {
26960 if (tags[key2] !== value) {
26961 tags[key2] = [tags[key2], value];
26964 if (tags[key2].indexOf(value) === -1) {
26965 tags[key2].push(value);
26969 var tagHash = key2 + "=" + value;
26970 if (!tagCounts[tagHash])
26971 tagCounts[tagHash] = 0;
26972 tagCounts[tagHash] += 1;
26975 for (var key in tags) {
26976 if (!Array.isArray(tags[key]))
26978 tags[key] = tags[key].sort(function(val12, val2) {
26980 var count2 = tagCounts[key2 + "=" + val2];
26981 var count1 = tagCounts[key2 + "=" + val12];
26982 if (count2 !== count1) {
26983 return count2 - count1;
26985 if (val2 && val12) {
26986 return val12.localeCompare(val2);
26988 return val12 ? 1 : -1;
26993 function utilStringQs(str2) {
26995 while (i2 < str2.length && (str2[i2] === "?" || str2[i2] === "#"))
26997 str2 = str2.slice(i2);
26998 return str2.split("&").reduce(function(obj, pair2) {
26999 var parts = pair2.split("=");
27000 if (parts.length === 2) {
27001 obj[parts[0]] = null === parts[1] ? "" : decodeURIComponent(parts[1]);
27006 function utilQsString(obj, noencode) {
27007 function softEncode(s) {
27008 return encodeURIComponent(s).replace(/(%2F|%3A|%2C|%7B|%7D)/g, decodeURIComponent);
27010 return Object.keys(obj).sort().map(function(key) {
27011 return encodeURIComponent(key) + "=" + (noencode ? softEncode(obj[key]) : encodeURIComponent(obj[key]));
27014 function utilPrefixDOMProperty(property) {
27015 var prefixes2 = ["webkit", "ms", "moz", "o"];
27017 var n2 = prefixes2.length;
27018 var s = document.body;
27021 property = property.slice(0, 1).toUpperCase() + property.slice(1);
27022 while (++i2 < n2) {
27023 if (prefixes2[i2] + property in s) {
27024 return prefixes2[i2] + property;
27029 function utilPrefixCSSProperty(property) {
27030 var prefixes2 = ["webkit", "ms", "Moz", "O"];
27032 var n2 = prefixes2.length;
27033 var s = document.body.style;
27034 if (property.toLowerCase() in s) {
27035 return property.toLowerCase();
27037 while (++i2 < n2) {
27038 if (prefixes2[i2] + property in s) {
27039 return "-" + prefixes2[i2].toLowerCase() + property.replace(/([A-Z])/g, "-$1").toLowerCase();
27044 var transformProperty;
27045 function utilSetTransform(el, x, y, scale) {
27046 var prop = transformProperty = transformProperty || utilPrefixCSSProperty("Transform");
27047 var translate = utilDetect().opera ? "translate(" + x + "px," + y + "px)" : "translate3d(" + x + "px," + y + "px,0)";
27048 return el.style(prop, translate + (scale ? " scale(" + scale + ")" : ""));
27050 function utilEditDistance(a, b) {
27051 a = (0, import_diacritics.remove)(a.toLowerCase());
27052 b = (0, import_diacritics.remove)(b.toLowerCase());
27053 if (a.length === 0)
27055 if (b.length === 0)
27059 for (i2 = 0; i2 <= b.length; i2++) {
27062 for (j2 = 0; j2 <= a.length; j2++) {
27063 matrix[0][j2] = j2;
27065 for (i2 = 1; i2 <= b.length; i2++) {
27066 for (j2 = 1; j2 <= a.length; j2++) {
27067 if (b.charAt(i2 - 1) === a.charAt(j2 - 1)) {
27068 matrix[i2][j2] = matrix[i2 - 1][j2 - 1];
27070 matrix[i2][j2] = Math.min(
27071 matrix[i2 - 1][j2 - 1] + 1,
27074 matrix[i2][j2 - 1] + 1,
27076 matrix[i2 - 1][j2] + 1
27082 return matrix[b.length][a.length];
27084 function utilFastMouse(container) {
27085 var rect = container.getBoundingClientRect();
27086 var rectLeft = rect.left;
27087 var rectTop = rect.top;
27088 var clientLeft = +container.clientLeft;
27089 var clientTop = +container.clientTop;
27090 return function(e) {
27092 e.clientX - rectLeft - clientLeft,
27093 e.clientY - rectTop - clientTop
27097 function utilAsyncMap(inputs, func, callback) {
27098 var remaining = inputs.length;
27101 inputs.forEach(function(d, i2) {
27102 func(d, function done(err, data) {
27104 results[i2] = data;
27107 callback(errors, results);
27111 function utilWrap(index, length) {
27113 index += Math.ceil(-index / length) * length;
27115 return index % length;
27117 function utilFunctor(value) {
27118 if (typeof value === "function")
27120 return function() {
27124 function utilNoAuto(selection2) {
27125 var isText = selection2.size() && selection2.node().tagName.toLowerCase() === "textarea";
27126 return selection2.attr("autocomplete", "new-password").attr("autocorrect", "off").attr("autocapitalize", "off").attr("spellcheck", isText ? "true" : "false");
27128 function utilHashcode(str2) {
27130 if (str2.length === 0) {
27133 for (var i2 = 0; i2 < str2.length; i2++) {
27134 var char = str2.charCodeAt(i2);
27135 hash = (hash << 5) - hash + char;
27136 hash = hash & hash;
27140 function utilSafeClassName(str2) {
27141 return str2.toLowerCase().replace(/[^a-z0-9]+/g, "_");
27143 function utilUniqueDomId(val) {
27144 return "ideditor-" + utilSafeClassName(val.toString()) + "-" + (/* @__PURE__ */ new Date()).getTime().toString();
27146 function utilUnicodeCharsCount(str2) {
27147 return Array.from(str2).length;
27149 function utilUnicodeCharsTruncated(str2, limit) {
27150 return Array.from(str2).slice(0, limit).join("");
27152 function toNumericID(id2) {
27153 var match = id2.match(/^[cnwr](-?\d+)$/);
27155 return parseInt(match[1], 10);
27159 function compareNumericIDs(left, right) {
27160 if (isNaN(left) && isNaN(right))
27166 if (Math.sign(left) !== Math.sign(right))
27167 return -Math.sign(left);
27168 if (Math.sign(left) < 0)
27169 return Math.sign(right - left);
27170 return Math.sign(left - right);
27172 function utilCompareIDs(left, right) {
27173 return compareNumericIDs(toNumericID(left), toNumericID(right));
27175 function utilOldestID(ids) {
27176 if (ids.length === 0) {
27179 var oldestIDIndex = 0;
27180 var oldestID = toNumericID(ids[0]);
27181 for (var i2 = 1; i2 < ids.length; i2++) {
27182 var num = toNumericID(ids[i2]);
27183 if (compareNumericIDs(oldestID, num) === 1) {
27184 oldestIDIndex = i2;
27188 return ids[oldestIDIndex];
27190 function utilCleanOsmString(val, maxChars) {
27191 if (val === void 0 || val === null) {
27194 val = val.toString();
27198 val = val.normalize("NFC");
27199 return utilUnicodeCharsTruncated(val, maxChars);
27202 // modules/osm/entity.js
27203 function osmEntity(attrs) {
27204 if (this instanceof osmEntity)
27206 if (attrs && attrs.type) {
27207 return osmEntity[attrs.type].apply(this, arguments);
27208 } else if (attrs && attrs.id) {
27209 return osmEntity[osmEntity.id.type(attrs.id)].apply(this, arguments);
27211 return new osmEntity().initialize(arguments);
27213 osmEntity.id = function(type2) {
27214 return osmEntity.id.fromOSM(type2, osmEntity.id.next[type2]--);
27216 osmEntity.id.next = {
27222 osmEntity.id.fromOSM = function(type2, id2) {
27223 return type2[0] + id2;
27225 osmEntity.id.toOSM = function(id2) {
27226 var match = id2.match(/^[cnwr](-?\d+)$/);
27232 osmEntity.id.type = function(id2) {
27233 return { "c": "changeset", "n": "node", "w": "way", "r": "relation" }[id2[0]];
27235 osmEntity.key = function(entity) {
27236 return entity.id + "v" + (entity.v || 0);
27238 var _deprecatedTagValuesByKey;
27239 osmEntity.deprecatedTagValuesByKey = function(dataDeprecated) {
27240 if (!_deprecatedTagValuesByKey) {
27241 _deprecatedTagValuesByKey = {};
27242 dataDeprecated.forEach(function(d) {
27243 var oldKeys = Object.keys(d.old);
27244 if (oldKeys.length === 1) {
27245 var oldKey = oldKeys[0];
27246 var oldValue = d.old[oldKey];
27247 if (oldValue !== "*") {
27248 if (!_deprecatedTagValuesByKey[oldKey]) {
27249 _deprecatedTagValuesByKey[oldKey] = [oldValue];
27251 _deprecatedTagValuesByKey[oldKey].push(oldValue);
27257 return _deprecatedTagValuesByKey;
27259 osmEntity.prototype = {
27261 initialize: function(sources) {
27262 for (var i2 = 0; i2 < sources.length; ++i2) {
27263 var source = sources[i2];
27264 for (var prop in source) {
27265 if (Object.prototype.hasOwnProperty.call(source, prop)) {
27266 if (source[prop] === void 0) {
27269 this[prop] = source[prop];
27274 if (!this.id && this.type) {
27275 this.id = osmEntity.id(this.type);
27277 if (!this.hasOwnProperty("visible")) {
27278 this.visible = true;
27281 Object.freeze(this);
27282 Object.freeze(this.tags);
27284 Object.freeze(this.loc);
27286 Object.freeze(this.nodes);
27288 Object.freeze(this.members);
27292 copy: function(resolver, copies) {
27293 if (copies[this.id])
27294 return copies[this.id];
27295 var copy2 = osmEntity(this, { id: void 0, user: void 0, version: void 0 });
27296 copies[this.id] = copy2;
27299 osmId: function() {
27300 return osmEntity.id.toOSM(this.id);
27302 isNew: function() {
27303 var osmId = osmEntity.id.toOSM(this.id);
27304 return osmId.length === 0 || osmId[0] === "-";
27306 update: function(attrs) {
27307 return osmEntity(this, attrs, { v: 1 + (this.v || 0) });
27309 mergeTags: function(tags) {
27310 var merged = Object.assign({}, this.tags);
27311 var changed = false;
27312 for (var k in tags) {
27313 var t1 = merged[k];
27318 } else if (t1 !== t2) {
27320 merged[k] = utilUnicodeCharsTruncated(
27321 utilArrayUnion(t1.split(/;\s*/), t2.split(/;\s*/)).join(";"),
27323 // avoid exceeding character limit; see also context.maxCharsForTagValue()
27327 return changed ? this.update({ tags: merged }) : this;
27329 intersects: function(extent, resolver) {
27330 return this.extent(resolver).intersects(extent);
27332 hasNonGeometryTags: function() {
27333 return Object.keys(this.tags).some(function(k) {
27334 return k !== "area";
27337 hasParentRelations: function(resolver) {
27338 return resolver.parentRelations(this).length > 0;
27340 hasInterestingTags: function() {
27341 return Object.keys(this.tags).some(osmIsInterestingTag);
27343 isHighwayIntersection: function() {
27346 isDegenerate: function() {
27349 deprecatedTags: function(dataDeprecated) {
27350 var tags = this.tags;
27351 if (Object.keys(tags).length === 0)
27353 var deprecated = [];
27354 dataDeprecated.forEach(function(d) {
27355 var oldKeys = Object.keys(d.old);
27357 var hasExistingValues = Object.keys(d.replace).some(function(replaceKey) {
27358 if (!tags[replaceKey] || d.old[replaceKey])
27360 var replaceValue = d.replace[replaceKey];
27361 if (replaceValue === "*")
27363 if (replaceValue === tags[replaceKey])
27367 if (hasExistingValues)
27370 var matchesDeprecatedTags = oldKeys.every(function(oldKey) {
27373 if (d.old[oldKey] === "*")
27375 if (d.old[oldKey] === tags[oldKey])
27377 var vals = tags[oldKey].split(";").filter(Boolean);
27378 if (vals.length === 0) {
27380 } else if (vals.length > 1) {
27381 return vals.indexOf(d.old[oldKey]) !== -1;
27383 if (tags[oldKey] === d.old[oldKey]) {
27384 if (d.replace && d.old[oldKey] === d.replace[oldKey]) {
27385 var replaceKeys = Object.keys(d.replace);
27386 return !replaceKeys.every(function(replaceKey) {
27387 return tags[replaceKey] === d.replace[replaceKey];
27396 if (matchesDeprecatedTags) {
27397 deprecated.push(d);
27404 // modules/osm/lanes.js
27405 function osmLanes(entity) {
27406 if (entity.type !== "way")
27408 if (!entity.tags.highway)
27410 var tags = entity.tags;
27411 var isOneWay = entity.isOneWay();
27412 var laneCount = getLaneCount(tags, isOneWay);
27413 var maxspeed = parseMaxspeed(tags);
27414 var laneDirections = parseLaneDirections(tags, isOneWay, laneCount);
27415 var forward = laneDirections.forward;
27416 var backward = laneDirections.backward;
27417 var bothways = laneDirections.bothways;
27418 var turnLanes = {};
27419 turnLanes.unspecified = parseTurnLanes(tags["turn:lanes"]);
27420 turnLanes.forward = parseTurnLanes(tags["turn:lanes:forward"]);
27421 turnLanes.backward = parseTurnLanes(tags["turn:lanes:backward"]);
27422 var maxspeedLanes = {};
27423 maxspeedLanes.unspecified = parseMaxspeedLanes(tags["maxspeed:lanes"], maxspeed);
27424 maxspeedLanes.forward = parseMaxspeedLanes(tags["maxspeed:lanes:forward"], maxspeed);
27425 maxspeedLanes.backward = parseMaxspeedLanes(tags["maxspeed:lanes:backward"], maxspeed);
27427 psvLanes.unspecified = parseMiscLanes(tags["psv:lanes"]);
27428 psvLanes.forward = parseMiscLanes(tags["psv:lanes:forward"]);
27429 psvLanes.backward = parseMiscLanes(tags["psv:lanes:backward"]);
27431 busLanes.unspecified = parseMiscLanes(tags["bus:lanes"]);
27432 busLanes.forward = parseMiscLanes(tags["bus:lanes:forward"]);
27433 busLanes.backward = parseMiscLanes(tags["bus:lanes:backward"]);
27434 var taxiLanes = {};
27435 taxiLanes.unspecified = parseMiscLanes(tags["taxi:lanes"]);
27436 taxiLanes.forward = parseMiscLanes(tags["taxi:lanes:forward"]);
27437 taxiLanes.backward = parseMiscLanes(tags["taxi:lanes:backward"]);
27439 hovLanes.unspecified = parseMiscLanes(tags["hov:lanes"]);
27440 hovLanes.forward = parseMiscLanes(tags["hov:lanes:forward"]);
27441 hovLanes.backward = parseMiscLanes(tags["hov:lanes:backward"]);
27443 hgvLanes.unspecified = parseMiscLanes(tags["hgv:lanes"]);
27444 hgvLanes.forward = parseMiscLanes(tags["hgv:lanes:forward"]);
27445 hgvLanes.backward = parseMiscLanes(tags["hgv:lanes:backward"]);
27446 var bicyclewayLanes = {};
27447 bicyclewayLanes.unspecified = parseBicycleWay(tags["bicycleway:lanes"]);
27448 bicyclewayLanes.forward = parseBicycleWay(tags["bicycleway:lanes:forward"]);
27449 bicyclewayLanes.backward = parseBicycleWay(tags["bicycleway:lanes:backward"]);
27455 mapToLanesObj(lanesObj, turnLanes, "turnLane");
27456 mapToLanesObj(lanesObj, maxspeedLanes, "maxspeed");
27457 mapToLanesObj(lanesObj, psvLanes, "psv");
27458 mapToLanesObj(lanesObj, busLanes, "bus");
27459 mapToLanesObj(lanesObj, taxiLanes, "taxi");
27460 mapToLanesObj(lanesObj, hovLanes, "hov");
27461 mapToLanesObj(lanesObj, hgvLanes, "hgv");
27462 mapToLanesObj(lanesObj, bicyclewayLanes, "bicycleway");
27483 function getLaneCount(tags, isOneWay) {
27486 count = parseInt(tags.lanes, 10);
27491 switch (tags.highway) {
27494 count = isOneWay ? 2 : 4;
27497 count = isOneWay ? 1 : 2;
27502 function parseMaxspeed(tags) {
27503 var maxspeed = tags.maxspeed;
27506 var maxspeedRegex = /^([0-9][\.0-9]+?)(?:[ ]?(?:km\/h|kmh|kph|mph|knots))?$/;
27507 if (!maxspeedRegex.test(maxspeed))
27509 return parseInt(maxspeed, 10);
27511 function parseLaneDirections(tags, isOneWay, laneCount) {
27512 var forward = parseInt(tags["lanes:forward"], 10);
27513 var backward = parseInt(tags["lanes:backward"], 10);
27514 var bothways = parseInt(tags["lanes:both_ways"], 10) > 0 ? 1 : 0;
27515 if (parseInt(tags.oneway, 10) === -1) {
27518 backward = laneCount;
27519 } else if (isOneWay) {
27520 forward = laneCount;
27523 } else if (isNaN(forward) && isNaN(backward)) {
27524 backward = Math.floor((laneCount - bothways) / 2);
27525 forward = laneCount - bothways - backward;
27526 } else if (isNaN(forward)) {
27527 if (backward > laneCount - bothways) {
27528 backward = laneCount - bothways;
27530 forward = laneCount - bothways - backward;
27531 } else if (isNaN(backward)) {
27532 if (forward > laneCount - bothways) {
27533 forward = laneCount - bothways;
27535 backward = laneCount - bothways - forward;
27543 function parseTurnLanes(tag) {
27546 var validValues = [
27559 return tag.split("|").map(function(s) {
27562 return s.split(";").map(function(d) {
27563 return validValues.indexOf(d) === -1 ? "unknown" : d;
27567 function parseMaxspeedLanes(tag, maxspeed) {
27570 return tag.split("|").map(function(s) {
27573 var m = parseInt(s, 10);
27574 if (s === "" || m === maxspeed)
27576 return isNaN(m) ? "unknown" : m;
27579 function parseMiscLanes(tag) {
27582 var validValues = [
27587 return tag.split("|").map(function(s) {
27590 return validValues.indexOf(s) === -1 ? "unknown" : s;
27593 function parseBicycleWay(tag) {
27596 var validValues = [
27602 return tag.split("|").map(function(s) {
27605 return validValues.indexOf(s) === -1 ? "unknown" : s;
27608 function mapToLanesObj(lanesObj, data, key) {
27609 if (data.forward) {
27610 data.forward.forEach(function(l, i2) {
27611 if (!lanesObj.forward[i2])
27612 lanesObj.forward[i2] = {};
27613 lanesObj.forward[i2][key] = l;
27616 if (data.backward) {
27617 data.backward.forEach(function(l, i2) {
27618 if (!lanesObj.backward[i2])
27619 lanesObj.backward[i2] = {};
27620 lanesObj.backward[i2][key] = l;
27623 if (data.unspecified) {
27624 data.unspecified.forEach(function(l, i2) {
27625 if (!lanesObj.unspecified[i2])
27626 lanesObj.unspecified[i2] = {};
27627 lanesObj.unspecified[i2][key] = l;
27632 // modules/osm/way.js
27633 function osmWay() {
27634 if (!(this instanceof osmWay)) {
27635 return new osmWay().initialize(arguments);
27636 } else if (arguments.length) {
27637 this.initialize(arguments);
27640 osmEntity.way = osmWay;
27641 osmWay.prototype = Object.create(osmEntity.prototype);
27642 Object.assign(osmWay.prototype, {
27645 copy: function(resolver, copies) {
27646 if (copies[this.id])
27647 return copies[this.id];
27648 var copy2 = osmEntity.prototype.copy.call(this, resolver, copies);
27649 var nodes = this.nodes.map(function(id2) {
27650 return resolver.entity(id2).copy(resolver, copies).id;
27652 copy2 = copy2.update({ nodes });
27653 copies[this.id] = copy2;
27656 extent: function(resolver) {
27657 return resolver.transient(this, "extent", function() {
27658 var extent = geoExtent();
27659 for (var i2 = 0; i2 < this.nodes.length; i2++) {
27660 var node = resolver.hasEntity(this.nodes[i2]);
27662 extent._extend(node.extent());
27668 first: function() {
27669 return this.nodes[0];
27672 return this.nodes[this.nodes.length - 1];
27674 contains: function(node) {
27675 return this.nodes.indexOf(node) >= 0;
27677 affix: function(node) {
27678 if (this.nodes[0] === node)
27680 if (this.nodes[this.nodes.length - 1] === node)
27683 layer: function() {
27684 if (isFinite(this.tags.layer)) {
27685 return Math.max(-10, Math.min(+this.tags.layer, 10));
27687 if (this.tags.covered === "yes")
27689 if (this.tags.location === "overground")
27691 if (this.tags.location === "underground")
27693 if (this.tags.location === "underwater")
27695 if (this.tags.power === "line")
27697 if (this.tags.power === "minor_line")
27699 if (this.tags.aerialway)
27701 if (this.tags.bridge)
27703 if (this.tags.cutting)
27705 if (this.tags.tunnel)
27707 if (this.tags.waterway)
27709 if (this.tags.man_made === "pipeline")
27711 if (this.tags.boundary)
27715 // the approximate width of the line based on its tags except its `width` tag
27716 impliedLineWidthMeters: function() {
27717 var averageWidths = {
27719 // width is for single lane
27746 // width includes ties and rail bed, not just track gauge
27768 for (var key in averageWidths) {
27769 if (this.tags[key] && averageWidths[key][this.tags[key]]) {
27770 var width = averageWidths[key][this.tags[key]];
27771 if (key === "highway") {
27772 var laneCount = this.tags.lanes && parseInt(this.tags.lanes, 10);
27774 laneCount = this.isOneWay() ? 1 : 2;
27775 return width * laneCount;
27782 isOneWay: function() {
27787 "reversible": true,
27788 "alternating": true,
27792 if (values[this.tags.oneway] !== void 0) {
27793 return values[this.tags.oneway];
27795 for (var key in this.tags) {
27796 if (key in osmOneWayTags && this.tags[key] in osmOneWayTags[key]) {
27802 // Some identifier for tag that implies that this way is "sided",
27803 // i.e. the right side is the 'inside' (e.g. the right side of a
27804 // natural=cliff is lower).
27805 sidednessIdentifier: function() {
27806 for (var key in this.tags) {
27807 var value = this.tags[key];
27808 if (key in osmRightSideIsInsideTags && value in osmRightSideIsInsideTags[key]) {
27809 if (osmRightSideIsInsideTags[key][value] === true) {
27812 return osmRightSideIsInsideTags[key][value];
27818 isSided: function() {
27819 if (this.tags.two_sided === "yes") {
27822 return this.sidednessIdentifier() !== null;
27824 lanes: function() {
27825 return osmLanes(this);
27827 isClosed: function() {
27828 return this.nodes.length > 1 && this.first() === this.last();
27830 isConvex: function(resolver) {
27831 if (!this.isClosed() || this.isDegenerate())
27833 var nodes = utilArrayUniq(resolver.childNodes(this));
27834 var coords = nodes.map(function(n2) {
27839 for (var i2 = 0; i2 < coords.length; i2++) {
27840 var o = coords[(i2 + 1) % coords.length];
27841 var a = coords[i2];
27842 var b = coords[(i2 + 2) % coords.length];
27843 var res = geoVecCross(a, b, o);
27844 curr = res > 0 ? 1 : res < 0 ? -1 : 0;
27847 } else if (prev && curr !== prev) {
27854 // returns an object with the tag that implies this is an area, if any
27855 tagSuggestingArea: function() {
27856 return osmTagSuggestingArea(this.tags);
27858 isArea: function() {
27859 if (this.tags.area === "yes")
27861 if (!this.isClosed() || this.tags.area === "no")
27863 return this.tagSuggestingArea() !== null;
27865 isDegenerate: function() {
27866 return new Set(this.nodes).size < (this.isArea() ? 3 : 2);
27868 areAdjacent: function(n1, n2) {
27869 for (var i2 = 0; i2 < this.nodes.length; i2++) {
27870 if (this.nodes[i2] === n1) {
27871 if (this.nodes[i2 - 1] === n2)
27873 if (this.nodes[i2 + 1] === n2)
27879 geometry: function(graph) {
27880 return graph.transient(this, "geometry", function() {
27881 return this.isArea() ? "area" : "line";
27884 // returns an array of objects representing the segments between the nodes in this way
27885 segments: function(graph) {
27886 function segmentExtent(graph2) {
27887 var n1 = graph2.hasEntity(this.nodes[0]);
27888 var n2 = graph2.hasEntity(this.nodes[1]);
27889 return n1 && n2 && geoExtent([
27891 Math.min(n1.loc[0], n2.loc[0]),
27892 Math.min(n1.loc[1], n2.loc[1])
27895 Math.max(n1.loc[0], n2.loc[0]),
27896 Math.max(n1.loc[1], n2.loc[1])
27900 return graph.transient(this, "segments", function() {
27902 for (var i2 = 0; i2 < this.nodes.length - 1; i2++) {
27904 id: this.id + "-" + i2,
27907 nodes: [this.nodes[i2], this.nodes[i2 + 1]],
27908 extent: segmentExtent
27914 // If this way is not closed, append the beginning node to the end of the nodelist to close it.
27915 close: function() {
27916 if (this.isClosed() || !this.nodes.length)
27918 var nodes = this.nodes.slice();
27919 nodes = nodes.filter(noRepeatNodes);
27920 nodes.push(nodes[0]);
27921 return this.update({ nodes });
27923 // If this way is closed, remove any connector nodes from the end of the nodelist to unclose it.
27924 unclose: function() {
27925 if (!this.isClosed())
27927 var nodes = this.nodes.slice();
27928 var connector = this.first();
27929 var i2 = nodes.length - 1;
27930 while (i2 > 0 && nodes.length > 1 && nodes[i2] === connector) {
27931 nodes.splice(i2, 1);
27932 i2 = nodes.length - 1;
27934 nodes = nodes.filter(noRepeatNodes);
27935 return this.update({ nodes });
27937 // Adds a node (id) in front of the node which is currently at position index.
27938 // If index is undefined, the node will be added to the end of the way for linear ways,
27939 // or just before the final connecting node for circular ways.
27940 // Consecutive duplicates are eliminated including existing ones.
27941 // Circularity is always preserved when adding a node.
27942 addNode: function(id2, index) {
27943 var nodes = this.nodes.slice();
27944 var isClosed = this.isClosed();
27945 var max3 = isClosed ? nodes.length - 1 : nodes.length;
27946 if (index === void 0) {
27949 if (index < 0 || index > max3) {
27950 throw new RangeError("index " + index + " out of range 0.." + max3);
27953 var connector = this.first();
27955 while (i2 < nodes.length && nodes.length > 2 && nodes[i2] === connector) {
27956 nodes.splice(i2, 1);
27960 i2 = nodes.length - 1;
27961 while (i2 > 0 && nodes.length > 1 && nodes[i2] === connector) {
27962 nodes.splice(i2, 1);
27965 i2 = nodes.length - 1;
27968 nodes.splice(index, 0, id2);
27969 nodes = nodes.filter(noRepeatNodes);
27970 if (isClosed && (nodes.length === 1 || nodes[0] !== nodes[nodes.length - 1])) {
27971 nodes.push(nodes[0]);
27973 return this.update({ nodes });
27975 // Replaces the node which is currently at position index with the given node (id).
27976 // Consecutive duplicates are eliminated including existing ones.
27977 // Circularity is preserved when updating a node.
27978 updateNode: function(id2, index) {
27979 var nodes = this.nodes.slice();
27980 var isClosed = this.isClosed();
27981 var max3 = nodes.length - 1;
27982 if (index === void 0 || index < 0 || index > max3) {
27983 throw new RangeError("index " + index + " out of range 0.." + max3);
27986 var connector = this.first();
27988 while (i2 < nodes.length && nodes.length > 2 && nodes[i2] === connector) {
27989 nodes.splice(i2, 1);
27993 i2 = nodes.length - 1;
27994 while (i2 > 0 && nodes.length > 1 && nodes[i2] === connector) {
27995 nodes.splice(i2, 1);
27998 i2 = nodes.length - 1;
28001 nodes.splice(index, 1, id2);
28002 nodes = nodes.filter(noRepeatNodes);
28003 if (isClosed && (nodes.length === 1 || nodes[0] !== nodes[nodes.length - 1])) {
28004 nodes.push(nodes[0]);
28006 return this.update({ nodes });
28008 // Replaces each occurrence of node id needle with replacement.
28009 // Consecutive duplicates are eliminated including existing ones.
28010 // Circularity is preserved.
28011 replaceNode: function(needleID, replacementID) {
28012 var nodes = this.nodes.slice();
28013 var isClosed = this.isClosed();
28014 for (var i2 = 0; i2 < nodes.length; i2++) {
28015 if (nodes[i2] === needleID) {
28016 nodes[i2] = replacementID;
28019 nodes = nodes.filter(noRepeatNodes);
28020 if (isClosed && (nodes.length === 1 || nodes[0] !== nodes[nodes.length - 1])) {
28021 nodes.push(nodes[0]);
28023 return this.update({ nodes });
28025 // Removes each occurrence of node id.
28026 // Consecutive duplicates are eliminated including existing ones.
28027 // Circularity is preserved.
28028 removeNode: function(id2) {
28029 var nodes = this.nodes.slice();
28030 var isClosed = this.isClosed();
28031 nodes = nodes.filter(function(node) {
28032 return node !== id2;
28033 }).filter(noRepeatNodes);
28034 if (isClosed && (nodes.length === 1 || nodes[0] !== nodes[nodes.length - 1])) {
28035 nodes.push(nodes[0]);
28037 return this.update({ nodes });
28039 asJXON: function(changeset_id) {
28042 "@id": this.osmId(),
28043 "@version": this.version || 0,
28044 nd: this.nodes.map(function(id2) {
28045 return { keyAttributes: { ref: osmEntity.id.toOSM(id2) } };
28047 tag: Object.keys(this.tags).map(function(k) {
28048 return { keyAttributes: { k, v: this.tags[k] } };
28052 if (changeset_id) {
28053 r.way["@changeset"] = changeset_id;
28057 asGeoJSON: function(resolver) {
28058 return resolver.transient(this, "GeoJSON", function() {
28059 var coordinates = resolver.childNodes(this).map(function(n2) {
28062 if (this.isArea() && this.isClosed()) {
28065 coordinates: [coordinates]
28069 type: "LineString",
28075 area: function(resolver) {
28076 return resolver.transient(this, "area", function() {
28077 var nodes = resolver.childNodes(this);
28080 coordinates: [nodes.map(function(n2) {
28084 if (!this.isClosed() && nodes.length) {
28085 json.coordinates[0].push(nodes[0].loc);
28087 var area = area_default(json);
28088 if (area > 2 * Math.PI) {
28089 json.coordinates[0] = json.coordinates[0].reverse();
28090 area = area_default(json);
28092 return isNaN(area) ? 0 : area;
28096 function noRepeatNodes(node, i2, arr) {
28097 return i2 === 0 || node !== arr[i2 - 1];
28100 // modules/osm/multipolygon.js
28101 function osmOldMultipolygonOuterMemberOfRelation(entity, graph) {
28102 if (entity.type !== "relation" || !entity.isMultipolygon() || Object.keys(entity.tags).filter(osmIsInterestingTag).length > 1) {
28106 for (var memberIndex in entity.members) {
28107 var member = entity.members[memberIndex];
28108 if (!member.role || member.role === "outer") {
28111 if (member.type !== "way")
28113 if (!graph.hasEntity(member.id))
28115 outerMember = graph.entity(member.id);
28116 if (Object.keys(outerMember.tags).filter(osmIsInterestingTag).length === 0) {
28121 return outerMember;
28123 function osmIsOldMultipolygonOuterMember(entity, graph) {
28124 if (entity.type !== "way" || Object.keys(entity.tags).filter(osmIsInterestingTag).length === 0) {
28127 var parents = graph.parentRelations(entity);
28128 if (parents.length !== 1)
28130 var parent = parents[0];
28131 if (!parent.isMultipolygon() || Object.keys(parent.tags).filter(osmIsInterestingTag).length > 1) {
28134 var members = parent.members, member;
28135 for (var i2 = 0; i2 < members.length; i2++) {
28136 member = members[i2];
28137 if (member.id === entity.id && member.role && member.role !== "outer") {
28140 if (member.id !== entity.id && (!member.role || member.role === "outer")) {
28146 function osmOldMultipolygonOuterMember(entity, graph) {
28147 if (entity.type !== "way")
28149 var parents = graph.parentRelations(entity);
28150 if (parents.length !== 1)
28152 var parent = parents[0];
28153 if (!parent.isMultipolygon() || Object.keys(parent.tags).filter(osmIsInterestingTag).length > 1) {
28156 var members = parent.members, member, outerMember;
28157 for (var i2 = 0; i2 < members.length; i2++) {
28158 member = members[i2];
28159 if (!member.role || member.role === "outer") {
28162 outerMember = member;
28167 var outerEntity = graph.hasEntity(outerMember.id);
28168 if (!outerEntity || !Object.keys(outerEntity.tags).filter(osmIsInterestingTag).length) {
28171 return outerEntity;
28173 function osmJoinWays(toJoin, graph) {
28174 function resolve(member) {
28175 return graph.childNodes(graph.entity(member.id));
28177 function reverse(item2) {
28178 var action = actionReverse(item2.id, { reverseOneway: true });
28179 sequences.actions.push(action);
28180 return item2 instanceof osmWay ? action(graph).entity(item2.id) : item2;
28182 toJoin = toJoin.filter(function(member) {
28183 return member.type === "way" && graph.hasEntity(member.id);
28186 var joinAsMembers = true;
28187 for (i2 = 0; i2 < toJoin.length; i2++) {
28188 if (toJoin[i2] instanceof osmWay) {
28189 joinAsMembers = false;
28193 var sequences = [];
28194 sequences.actions = [];
28195 while (toJoin.length) {
28196 var item = toJoin.shift();
28197 var currWays = [item];
28198 var currNodes = resolve(item).slice();
28199 while (toJoin.length) {
28200 var start2 = currNodes[0];
28201 var end = currNodes[currNodes.length - 1];
28204 for (i2 = 0; i2 < toJoin.length; i2++) {
28206 nodes = resolve(item);
28207 if (joinAsMembers && currWays.length === 1 && nodes[0] !== end && nodes[nodes.length - 1] !== end && (nodes[nodes.length - 1] === start2 || nodes[0] === start2)) {
28208 currWays[0] = reverse(currWays[0]);
28209 currNodes.reverse();
28210 start2 = currNodes[0];
28211 end = currNodes[currNodes.length - 1];
28213 if (nodes[0] === end) {
28214 fn = currNodes.push;
28215 nodes = nodes.slice(1);
28217 } else if (nodes[nodes.length - 1] === end) {
28218 fn = currNodes.push;
28219 nodes = nodes.slice(0, -1).reverse();
28220 item = reverse(item);
28222 } else if (nodes[nodes.length - 1] === start2) {
28223 fn = currNodes.unshift;
28224 nodes = nodes.slice(0, -1);
28226 } else if (nodes[0] === start2) {
28227 fn = currNodes.unshift;
28228 nodes = nodes.slice(1).reverse();
28229 item = reverse(item);
28238 fn.apply(currWays, [item]);
28239 fn.apply(currNodes, nodes);
28240 toJoin.splice(i2, 1);
28242 currWays.nodes = currNodes;
28243 sequences.push(currWays);
28248 // modules/actions/add_member.js
28249 function actionAddMember(relationId, member, memberIndex, insertPair) {
28250 return function action(graph) {
28251 var relation = graph.entity(relationId);
28252 var isPTv2 = /stop|platform/.test(member.role);
28253 if ((isNaN(memberIndex) || insertPair) && member.type === "way" && !isPTv2) {
28254 graph = addWayMember(relation, graph);
28256 if (isPTv2 && isNaN(memberIndex)) {
28259 graph = graph.replace(relation.addMember(member, memberIndex));
28263 function addWayMember(relation, graph) {
28264 var groups, tempWay, insertPairIsReversed, item, i2, j2, k;
28265 var PTv2members = [];
28267 for (i2 = 0; i2 < relation.members.length; i2++) {
28268 var m = relation.members[i2];
28269 if (/stop|platform/.test(m.role)) {
28270 PTv2members.push(m);
28275 relation = relation.update({ members });
28277 tempWay = osmWay({ id: "wTemp", nodes: insertPair.nodes });
28278 graph = graph.replace(tempWay);
28279 var tempMember = { id: tempWay.id, type: "way", role: member.role };
28280 var tempRelation = relation.replaceMember({ id: insertPair.originalID }, tempMember, true);
28281 groups = utilArrayGroupBy(tempRelation.members, "type");
28282 groups.way = groups.way || [];
28283 var originalWay = graph.entity(insertPair.originalID);
28284 var insertedWay = graph.entity(insertPair.insertedID);
28285 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];
28287 groups = utilArrayGroupBy(relation.members, "type");
28288 groups.way = groups.way || [];
28289 groups.way.push(member);
28291 members = withIndex(groups.way);
28292 var joined = osmJoinWays(members, graph);
28293 for (i2 = 0; i2 < joined.length; i2++) {
28294 var segment = joined[i2];
28295 var nodes = segment.nodes.slice();
28296 var startIndex = segment[0].index;
28297 for (j2 = 0; j2 < members.length; j2++) {
28298 if (members[j2].index === startIndex) {
28302 for (k = 0; k < segment.length; k++) {
28304 var way = graph.entity(item.id);
28305 if (tempWay && item.id === tempWay.id) {
28306 var reverse = nodes[0].id !== insertPair.nodes[0] ^ insertPairIsReversed;
28309 { id: insertPair.insertedID, type: "way", role: item.role },
28310 { id: insertPair.originalID, type: "way", role: item.role }
28314 { id: insertPair.originalID, type: "way", role: item.role },
28315 { id: insertPair.insertedID, type: "way", role: item.role }
28320 if (j2 + k >= members.length || item.index !== members[j2 + k].index) {
28321 moveMember(members, item.index, j2 + k);
28324 nodes.splice(0, way.nodes.length - 1);
28328 graph = graph.remove(tempWay);
28330 var wayMembers = [];
28331 for (i2 = 0; i2 < members.length; i2++) {
28332 item = members[i2];
28333 if (item.index === -1)
28336 wayMembers.push(item.pair[0]);
28337 wayMembers.push(item.pair[1]);
28339 wayMembers.push(utilObjectOmit(item, ["index"]));
28342 var newMembers = PTv2members.concat(groups.node || [], wayMembers, groups.relation || []);
28343 return graph.replace(relation.update({ members: newMembers }));
28344 function moveMember(arr, findIndex, toIndex) {
28346 for (i3 = 0; i3 < arr.length; i3++) {
28347 if (arr[i3].index === findIndex) {
28351 var item2 = Object.assign({}, arr[i3]);
28352 arr[i3].index = -1;
28353 item2.index = toIndex;
28354 arr.splice(toIndex, 0, item2);
28356 function withIndex(arr) {
28357 var result = new Array(arr.length);
28358 for (var i3 = 0; i3 < arr.length; i3++) {
28359 result[i3] = Object.assign({}, arr[i3]);
28360 result[i3].index = i3;
28367 // modules/actions/add_midpoint.js
28368 function actionAddMidpoint(midpoint, node) {
28369 return function(graph) {
28370 graph = graph.replace(node.move(midpoint.loc));
28371 var parents = utilArrayIntersection(
28372 graph.parentWays(graph.entity(midpoint.edge[0])),
28373 graph.parentWays(graph.entity(midpoint.edge[1]))
28375 parents.forEach(function(way) {
28376 for (var i2 = 0; i2 < way.nodes.length - 1; i2++) {
28377 if (geoEdgeEqual([way.nodes[i2], way.nodes[i2 + 1]], midpoint.edge)) {
28378 graph = graph.replace(graph.entity(way.id).addNode(node.id, i2 + 1));
28387 // modules/actions/add_vertex.js
28388 function actionAddVertex(wayId, nodeId, index) {
28389 return function(graph) {
28390 return graph.replace(graph.entity(wayId).addNode(nodeId, index));
28394 // modules/actions/change_member.js
28395 function actionChangeMember(relationId, member, memberIndex) {
28396 return function(graph) {
28397 return graph.replace(graph.entity(relationId).updateMember(member, memberIndex));
28401 // modules/actions/change_preset.js
28402 function actionChangePreset(entityID, oldPreset, newPreset, skipFieldDefaults) {
28403 return function action(graph) {
28404 var entity = graph.entity(entityID);
28405 var geometry = entity.geometry(graph);
28406 var tags = entity.tags;
28410 if (newPreset.addTags) {
28411 preserveKeys = preserveKeys.concat(Object.keys(newPreset.addTags));
28413 if (oldPreset && !oldPreset.id.startsWith(newPreset.id)) {
28414 newPreset.fields().concat(newPreset.moreFields()).filter((f2) => f2.matchGeometry(geometry)).map((f2) => f2.key).filter(Boolean).forEach((key) => preserveKeys.push(key));
28418 tags = oldPreset.unsetTags(tags, geometry, preserveKeys);
28420 tags = newPreset.setTags(tags, geometry, skipFieldDefaults);
28421 return graph.replace(entity.update({ tags }));
28425 // modules/actions/change_tags.js
28426 function actionChangeTags(entityId, tags) {
28427 return function(graph) {
28428 var entity = graph.entity(entityId);
28429 return graph.replace(entity.update({ tags }));
28433 // modules/osm/node.js
28437 northnortheast: 22,
28445 eastsoutheast: 112,
28449 southsoutheast: 157,
28453 southsouthwest: 202,
28457 westsouthwest: 247,
28461 westnorthwest: 292,
28465 northnorthwest: 337,
28468 function osmNode() {
28469 if (!(this instanceof osmNode)) {
28470 return new osmNode().initialize(arguments);
28471 } else if (arguments.length) {
28472 this.initialize(arguments);
28475 osmEntity.node = osmNode;
28476 osmNode.prototype = Object.create(osmEntity.prototype);
28477 Object.assign(osmNode.prototype, {
28480 extent: function() {
28481 return new geoExtent(this.loc);
28483 geometry: function(graph) {
28484 return graph.transient(this, "geometry", function() {
28485 return graph.isPoi(this) ? "point" : "vertex";
28488 move: function(loc) {
28489 return this.update({ loc });
28491 isDegenerate: function() {
28492 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);
28494 // Inspect tags and geometry to determine which direction(s) this node/vertex points
28495 directions: function(resolver, projection2) {
28498 if (this.isHighwayIntersection(resolver) && (this.tags.stop || "").toLowerCase() === "all") {
28501 val = (this.tags.direction || "").toLowerCase();
28502 var re2 = /:direction$/i;
28503 var keys = Object.keys(this.tags);
28504 for (i2 = 0; i2 < keys.length; i2++) {
28505 if (re2.test(keys[i2])) {
28506 val = this.tags[keys[i2]].toLowerCase();
28513 var values = val.split(";");
28515 values.forEach(function(v) {
28516 if (cardinal[v] !== void 0) {
28519 if (v !== "" && !isNaN(+v)) {
28523 var lookBackward = this.tags["traffic_sign:backward"] || v === "backward" || v === "both" || v === "all";
28524 var lookForward = this.tags["traffic_sign:forward"] || v === "forward" || v === "both" || v === "all";
28525 if (!lookForward && !lookBackward)
28528 resolver.parentWays(this).forEach(function(parent) {
28529 var nodes = parent.nodes;
28530 for (i2 = 0; i2 < nodes.length; i2++) {
28531 if (nodes[i2] === this.id) {
28532 if (lookForward && i2 > 0) {
28533 nodeIds[nodes[i2 - 1]] = true;
28535 if (lookBackward && i2 < nodes.length - 1) {
28536 nodeIds[nodes[i2 + 1]] = true;
28541 Object.keys(nodeIds).forEach(function(nodeId) {
28543 geoAngle(this, resolver.entity(nodeId), projection2) * (180 / Math.PI) + 90
28547 return utilArrayUniq(results);
28549 isCrossing: function() {
28550 return this.tags.highway === "crossing" || this.tags.railway && this.tags.railway.indexOf("crossing") !== -1;
28552 isEndpoint: function(resolver) {
28553 return resolver.transient(this, "isEndpoint", function() {
28555 return resolver.parentWays(this).filter(function(parent) {
28556 return !parent.isClosed() && !!parent.affix(id2);
28560 isConnected: function(resolver) {
28561 return resolver.transient(this, "isConnected", function() {
28562 var parents = resolver.parentWays(this);
28563 if (parents.length > 1) {
28564 for (var i2 in parents) {
28565 if (parents[i2].geometry(resolver) === "line" && parents[i2].hasInterestingTags())
28568 } else if (parents.length === 1) {
28569 var way = parents[0];
28570 var nodes = way.nodes.slice();
28571 if (way.isClosed()) {
28574 return nodes.indexOf(this.id) !== nodes.lastIndexOf(this.id);
28579 parentIntersectionWays: function(resolver) {
28580 return resolver.transient(this, "parentIntersectionWays", function() {
28581 return resolver.parentWays(this).filter(function(parent) {
28582 return (parent.tags.highway || parent.tags.waterway || parent.tags.railway || parent.tags.aeroway) && parent.geometry(resolver) === "line";
28586 isIntersection: function(resolver) {
28587 return this.parentIntersectionWays(resolver).length > 1;
28589 isHighwayIntersection: function(resolver) {
28590 return resolver.transient(this, "isHighwayIntersection", function() {
28591 return resolver.parentWays(this).filter(function(parent) {
28592 return parent.tags.highway && parent.geometry(resolver) === "line";
28596 isOnAddressLine: function(resolver) {
28597 return resolver.transient(this, "isOnAddressLine", function() {
28598 return resolver.parentWays(this).filter(function(parent) {
28599 return parent.tags.hasOwnProperty("addr:interpolation") && parent.geometry(resolver) === "line";
28603 asJXON: function(changeset_id) {
28606 "@id": this.osmId(),
28607 "@lon": this.loc[0],
28608 "@lat": this.loc[1],
28609 "@version": this.version || 0,
28610 tag: Object.keys(this.tags).map(function(k) {
28611 return { keyAttributes: { k, v: this.tags[k] } };
28616 r.node["@changeset"] = changeset_id;
28619 asGeoJSON: function() {
28622 coordinates: this.loc
28627 // modules/actions/circularize.js
28628 function actionCircularize(wayId, projection2, maxAngle) {
28629 maxAngle = (maxAngle || 20) * Math.PI / 180;
28630 var action = function(graph, t) {
28631 if (t === null || !isFinite(t))
28633 t = Math.min(Math.max(+t, 0), 1);
28634 var way = graph.entity(wayId);
28635 var origNodes = {};
28636 graph.childNodes(way).forEach(function(node2) {
28637 if (!origNodes[node2.id])
28638 origNodes[node2.id] = node2;
28640 if (!way.isConvex(graph)) {
28641 graph = action.makeConvex(graph);
28643 var nodes = utilArrayUniq(graph.childNodes(way));
28644 var keyNodes = nodes.filter(function(n2) {
28645 return graph.parentWays(n2).length !== 1;
28647 var points = nodes.map(function(n2) {
28648 return projection2(n2.loc);
28650 var keyPoints = keyNodes.map(function(n2) {
28651 return projection2(n2.loc);
28653 var centroid = points.length === 2 ? geoVecInterp(points[0], points[1], 0.5) : centroid_default2(points);
28654 var radius = median(points, function(p) {
28655 return geoVecLength(centroid, p);
28657 var sign2 = area_default3(points) > 0 ? 1 : -1;
28658 var ids, i2, j2, k;
28659 if (!keyNodes.length) {
28660 keyNodes = [nodes[0]];
28661 keyPoints = [points[0]];
28663 if (keyNodes.length === 1) {
28664 var index = nodes.indexOf(keyNodes[0]);
28665 var oppositeIndex = Math.floor((index + nodes.length / 2) % nodes.length);
28666 keyNodes.push(nodes[oppositeIndex]);
28667 keyPoints.push(points[oppositeIndex]);
28669 for (i2 = 0; i2 < keyPoints.length; i2++) {
28670 var nextKeyNodeIndex = (i2 + 1) % keyNodes.length;
28671 var startNode = keyNodes[i2];
28672 var endNode = keyNodes[nextKeyNodeIndex];
28673 var startNodeIndex = nodes.indexOf(startNode);
28674 var endNodeIndex = nodes.indexOf(endNode);
28675 var numberNewPoints = -1;
28676 var indexRange = endNodeIndex - startNodeIndex;
28677 var nearNodes = {};
28678 var inBetweenNodes = [];
28679 var startAngle, endAngle, totalAngle, eachAngle;
28680 var angle2, loc, node, origNode;
28681 if (indexRange < 0) {
28682 indexRange += nodes.length;
28684 var distance = geoVecLength(centroid, keyPoints[i2]) || 1e-4;
28686 centroid[0] + (keyPoints[i2][0] - centroid[0]) / distance * radius,
28687 centroid[1] + (keyPoints[i2][1] - centroid[1]) / distance * radius
28689 loc = projection2.invert(keyPoints[i2]);
28690 node = keyNodes[i2];
28691 origNode = origNodes[node.id];
28692 node = node.move(geoVecInterp(origNode.loc, loc, t));
28693 graph = graph.replace(node);
28694 startAngle = Math.atan2(keyPoints[i2][1] - centroid[1], keyPoints[i2][0] - centroid[0]);
28695 endAngle = Math.atan2(keyPoints[nextKeyNodeIndex][1] - centroid[1], keyPoints[nextKeyNodeIndex][0] - centroid[0]);
28696 totalAngle = endAngle - startAngle;
28697 if (totalAngle * sign2 > 0) {
28698 totalAngle = -sign2 * (2 * Math.PI - Math.abs(totalAngle));
28702 eachAngle = totalAngle / (indexRange + numberNewPoints);
28703 } while (Math.abs(eachAngle) > maxAngle);
28704 for (j2 = 1; j2 < indexRange; j2++) {
28705 angle2 = startAngle + j2 * eachAngle;
28706 loc = projection2.invert([
28707 centroid[0] + Math.cos(angle2) * radius,
28708 centroid[1] + Math.sin(angle2) * radius
28710 node = nodes[(j2 + startNodeIndex) % nodes.length];
28711 origNode = origNodes[node.id];
28712 nearNodes[node.id] = angle2;
28713 node = node.move(geoVecInterp(origNode.loc, loc, t));
28714 graph = graph.replace(node);
28716 for (j2 = 0; j2 < numberNewPoints; j2++) {
28717 angle2 = startAngle + (indexRange + j2) * eachAngle;
28718 loc = projection2.invert([
28719 centroid[0] + Math.cos(angle2) * radius,
28720 centroid[1] + Math.sin(angle2) * radius
28722 var min3 = Infinity;
28723 for (var nodeId in nearNodes) {
28724 var nearAngle = nearNodes[nodeId];
28725 var dist = Math.abs(nearAngle - angle2);
28728 origNode = origNodes[nodeId];
28731 node = osmNode({ loc: geoVecInterp(origNode.loc, loc, t) });
28732 graph = graph.replace(node);
28733 nodes.splice(endNodeIndex + j2, 0, node);
28734 inBetweenNodes.push(node.id);
28736 if (indexRange === 1 && inBetweenNodes.length) {
28737 var startIndex1 = way.nodes.lastIndexOf(startNode.id);
28738 var endIndex1 = way.nodes.lastIndexOf(endNode.id);
28739 var wayDirection1 = endIndex1 - startIndex1;
28740 if (wayDirection1 < -1) {
28743 var parentWays = graph.parentWays(keyNodes[i2]);
28744 for (j2 = 0; j2 < parentWays.length; j2++) {
28745 var sharedWay = parentWays[j2];
28746 if (sharedWay === way)
28748 if (sharedWay.areAdjacent(startNode.id, endNode.id)) {
28749 var startIndex2 = sharedWay.nodes.lastIndexOf(startNode.id);
28750 var endIndex2 = sharedWay.nodes.lastIndexOf(endNode.id);
28751 var wayDirection2 = endIndex2 - startIndex2;
28752 var insertAt = endIndex2;
28753 if (wayDirection2 < -1) {
28756 if (wayDirection1 !== wayDirection2) {
28757 inBetweenNodes.reverse();
28758 insertAt = startIndex2;
28760 for (k = 0; k < inBetweenNodes.length; k++) {
28761 sharedWay = sharedWay.addNode(inBetweenNodes[k], insertAt + k);
28763 graph = graph.replace(sharedWay);
28768 ids = nodes.map(function(n2) {
28772 way = way.update({ nodes: ids });
28773 graph = graph.replace(way);
28776 action.makeConvex = function(graph) {
28777 var way = graph.entity(wayId);
28778 var nodes = utilArrayUniq(graph.childNodes(way));
28779 var points = nodes.map(function(n2) {
28780 return projection2(n2.loc);
28782 var sign2 = area_default3(points) > 0 ? 1 : -1;
28783 var hull = hull_default(points);
28785 if (sign2 === -1) {
28789 for (i2 = 0; i2 < hull.length - 1; i2++) {
28790 var startIndex = points.indexOf(hull[i2]);
28791 var endIndex = points.indexOf(hull[i2 + 1]);
28792 var indexRange = endIndex - startIndex;
28793 if (indexRange < 0) {
28794 indexRange += nodes.length;
28796 for (j2 = 1; j2 < indexRange; j2++) {
28797 var point2 = geoVecInterp(hull[i2], hull[i2 + 1], j2 / indexRange);
28798 var node = nodes[(j2 + startIndex) % nodes.length].move(projection2.invert(point2));
28799 graph = graph.replace(node);
28804 action.disabled = function(graph) {
28805 if (!graph.entity(wayId).isClosed()) {
28806 return "not_closed";
28808 var way = graph.entity(wayId);
28809 var nodes = utilArrayUniq(graph.childNodes(way));
28810 var points = nodes.map(function(n2) {
28811 return projection2(n2.loc);
28813 var hull = hull_default(points);
28814 var epsilonAngle = Math.PI / 180;
28815 if (hull.length !== points.length || hull.length < 3) {
28818 var centroid = centroid_default2(points);
28819 var radius = geoVecLengthSquare(centroid, points[0]);
28820 var i2, actualPoint;
28821 for (i2 = 0; i2 < hull.length; i2++) {
28822 actualPoint = hull[i2];
28823 var actualDist = geoVecLengthSquare(actualPoint, centroid);
28824 var diff = Math.abs(actualDist - radius);
28825 if (diff > 0.05 * radius) {
28829 for (i2 = 0; i2 < hull.length; i2++) {
28830 actualPoint = hull[i2];
28831 var nextPoint = hull[(i2 + 1) % hull.length];
28832 var startAngle = Math.atan2(actualPoint[1] - centroid[1], actualPoint[0] - centroid[0]);
28833 var endAngle = Math.atan2(nextPoint[1] - centroid[1], nextPoint[0] - centroid[0]);
28834 var angle2 = endAngle - startAngle;
28838 if (angle2 > Math.PI) {
28839 angle2 = 2 * Math.PI - angle2;
28841 if (angle2 > maxAngle + epsilonAngle) {
28845 return "already_circular";
28847 action.transitionable = true;
28851 // modules/actions/delete_way.js
28852 function actionDeleteWay(wayID) {
28853 function canDeleteNode(node, graph) {
28854 if (graph.parentWays(node).length || graph.parentRelations(node).length)
28856 var geometries = osmNodeGeometriesForTags(node.tags);
28857 if (geometries.point)
28859 if (geometries.vertex)
28861 return !node.hasInterestingTags();
28863 var action = function(graph) {
28864 var way = graph.entity(wayID);
28865 graph.parentRelations(way).forEach(function(parent) {
28866 parent = parent.removeMembersWithID(wayID);
28867 graph = graph.replace(parent);
28868 if (parent.isDegenerate()) {
28869 graph = actionDeleteRelation(parent.id)(graph);
28872 new Set(way.nodes).forEach(function(nodeID) {
28873 graph = graph.replace(way.removeNode(nodeID));
28874 var node = graph.entity(nodeID);
28875 if (canDeleteNode(node, graph)) {
28876 graph = graph.remove(node);
28879 return graph.remove(way);
28884 // modules/actions/delete_multiple.js
28885 function actionDeleteMultiple(ids) {
28887 way: actionDeleteWay,
28888 node: actionDeleteNode,
28889 relation: actionDeleteRelation
28891 var action = function(graph) {
28892 ids.forEach(function(id2) {
28893 if (graph.hasEntity(id2)) {
28894 graph = actions[graph.entity(id2).type](id2)(graph);
28902 // modules/actions/delete_relation.js
28903 function actionDeleteRelation(relationID, allowUntaggedMembers) {
28904 function canDeleteEntity(entity, graph) {
28905 return !graph.parentWays(entity).length && !graph.parentRelations(entity).length && (!entity.hasInterestingTags() && !allowUntaggedMembers);
28907 var action = function(graph) {
28908 var relation = graph.entity(relationID);
28909 graph.parentRelations(relation).forEach(function(parent) {
28910 parent = parent.removeMembersWithID(relationID);
28911 graph = graph.replace(parent);
28912 if (parent.isDegenerate()) {
28913 graph = actionDeleteRelation(parent.id)(graph);
28916 var memberIDs = utilArrayUniq(relation.members.map(function(m) {
28919 memberIDs.forEach(function(memberID) {
28920 graph = graph.replace(relation.removeMembersWithID(memberID));
28921 var entity = graph.entity(memberID);
28922 if (canDeleteEntity(entity, graph)) {
28923 graph = actionDeleteMultiple([memberID])(graph);
28926 return graph.remove(relation);
28931 // modules/actions/delete_node.js
28932 function actionDeleteNode(nodeId) {
28933 var action = function(graph) {
28934 var node = graph.entity(nodeId);
28935 graph.parentWays(node).forEach(function(parent) {
28936 parent = parent.removeNode(nodeId);
28937 graph = graph.replace(parent);
28938 if (parent.isDegenerate()) {
28939 graph = actionDeleteWay(parent.id)(graph);
28942 graph.parentRelations(node).forEach(function(parent) {
28943 parent = parent.removeMembersWithID(nodeId);
28944 graph = graph.replace(parent);
28945 if (parent.isDegenerate()) {
28946 graph = actionDeleteRelation(parent.id)(graph);
28949 return graph.remove(node);
28954 // modules/actions/connect.js
28955 function actionConnect(nodeIDs) {
28956 var action = function(graph) {
28962 var interestingIDs = [];
28963 for (i2 = 0; i2 < nodeIDs.length; i2++) {
28964 node = graph.entity(nodeIDs[i2]);
28965 if (node.hasInterestingTags()) {
28966 if (!node.isNew()) {
28967 interestingIDs.push(node.id);
28971 survivor = graph.entity(utilOldestID(interestingIDs.length > 0 ? interestingIDs : nodeIDs));
28972 for (i2 = 0; i2 < nodeIDs.length; i2++) {
28973 node = graph.entity(nodeIDs[i2]);
28974 if (node.id === survivor.id)
28976 parents = graph.parentWays(node);
28977 for (j2 = 0; j2 < parents.length; j2++) {
28978 graph = graph.replace(parents[j2].replaceNode(node.id, survivor.id));
28980 parents = graph.parentRelations(node);
28981 for (j2 = 0; j2 < parents.length; j2++) {
28982 graph = graph.replace(parents[j2].replaceMember(node, survivor));
28984 survivor = survivor.mergeTags(node.tags);
28985 graph = actionDeleteNode(node.id)(graph);
28987 graph = graph.replace(survivor);
28988 parents = graph.parentWays(survivor);
28989 for (i2 = 0; i2 < parents.length; i2++) {
28990 if (parents[i2].isDegenerate()) {
28991 graph = actionDeleteWay(parents[i2].id)(graph);
28996 action.disabled = function(graph) {
28998 var restrictionIDs = [];
29001 var relations, relation, role;
29003 survivor = graph.entity(utilOldestID(nodeIDs));
29004 for (i2 = 0; i2 < nodeIDs.length; i2++) {
29005 node = graph.entity(nodeIDs[i2]);
29006 relations = graph.parentRelations(node);
29007 for (j2 = 0; j2 < relations.length; j2++) {
29008 relation = relations[j2];
29009 role = relation.memberById(node.id).role || "";
29010 if (relation.hasFromViaTo()) {
29011 restrictionIDs.push(relation.id);
29013 if (seen[relation.id] !== void 0 && seen[relation.id] !== role) {
29016 seen[relation.id] = role;
29020 for (i2 = 0; i2 < nodeIDs.length; i2++) {
29021 node = graph.entity(nodeIDs[i2]);
29022 var parents = graph.parentWays(node);
29023 for (j2 = 0; j2 < parents.length; j2++) {
29024 var parent = parents[j2];
29025 relations = graph.parentRelations(parent);
29026 for (k = 0; k < relations.length; k++) {
29027 relation = relations[k];
29028 if (relation.hasFromViaTo()) {
29029 restrictionIDs.push(relation.id);
29034 restrictionIDs = utilArrayUniq(restrictionIDs);
29035 for (i2 = 0; i2 < restrictionIDs.length; i2++) {
29036 relation = graph.entity(restrictionIDs[i2]);
29037 if (!relation.isComplete(graph))
29039 var memberWays = relation.members.filter(function(m) {
29040 return m.type === "way";
29041 }).map(function(m) {
29042 return graph.entity(m.id);
29044 memberWays = utilArrayUniq(memberWays);
29045 var f2 = relation.memberByRole("from");
29046 var t = relation.memberByRole("to");
29047 var isUturn = f2.id === t.id;
29048 var nodes = { from: [], via: [], to: [], keyfrom: [], keyto: [] };
29049 for (j2 = 0; j2 < relation.members.length; j2++) {
29050 collectNodes(relation.members[j2], nodes);
29052 nodes.keyfrom = utilArrayUniq(nodes.keyfrom.filter(hasDuplicates));
29053 nodes.keyto = utilArrayUniq(nodes.keyto.filter(hasDuplicates));
29054 var filter2 = keyNodeFilter(nodes.keyfrom, nodes.keyto);
29055 nodes.from = nodes.from.filter(filter2);
29056 nodes.via = nodes.via.filter(filter2);
29057 nodes.to = nodes.to.filter(filter2);
29058 var connectFrom = false;
29059 var connectVia = false;
29060 var connectTo = false;
29061 var connectKeyFrom = false;
29062 var connectKeyTo = false;
29063 for (j2 = 0; j2 < nodeIDs.length; j2++) {
29064 var n2 = nodeIDs[j2];
29065 if (nodes.from.indexOf(n2) !== -1) {
29066 connectFrom = true;
29068 if (nodes.via.indexOf(n2) !== -1) {
29071 if (nodes.to.indexOf(n2) !== -1) {
29074 if (nodes.keyfrom.indexOf(n2) !== -1) {
29075 connectKeyFrom = true;
29077 if (nodes.keyto.indexOf(n2) !== -1) {
29078 connectKeyTo = true;
29081 if (connectFrom && connectTo && !isUturn) {
29082 return "restriction";
29084 if (connectFrom && connectVia) {
29085 return "restriction";
29087 if (connectTo && connectVia) {
29088 return "restriction";
29090 if (connectKeyFrom || connectKeyTo) {
29091 if (nodeIDs.length !== 2) {
29092 return "restriction";
29096 for (j2 = 0; j2 < memberWays.length; j2++) {
29097 way = memberWays[j2];
29098 if (way.contains(nodeIDs[0])) {
29101 if (way.contains(nodeIDs[1])) {
29107 for (j2 = 0; j2 < memberWays.length; j2++) {
29108 way = memberWays[j2];
29109 if (way.areAdjacent(n0, n1)) {
29115 return "restriction";
29119 for (j2 = 0; j2 < memberWays.length; j2++) {
29120 way = memberWays[j2].update({});
29121 for (k = 0; k < nodeIDs.length; k++) {
29122 if (nodeIDs[k] === survivor.id)
29124 if (way.areAdjacent(nodeIDs[k], survivor.id)) {
29125 way = way.removeNode(nodeIDs[k]);
29127 way = way.replaceNode(nodeIDs[k], survivor.id);
29130 if (way.isDegenerate()) {
29131 return "restriction";
29136 function hasDuplicates(n3, i3, arr) {
29137 return arr.indexOf(n3) !== arr.lastIndexOf(n3);
29139 function keyNodeFilter(froms, tos) {
29140 return function(n3) {
29141 return froms.indexOf(n3) === -1 && tos.indexOf(n3) === -1;
29144 function collectNodes(member, collection) {
29145 var entity = graph.hasEntity(member.id);
29148 var role2 = member.role || "";
29149 if (!collection[role2]) {
29150 collection[role2] = [];
29152 if (member.type === "node") {
29153 collection[role2].push(member.id);
29154 if (role2 === "via") {
29155 collection.keyfrom.push(member.id);
29156 collection.keyto.push(member.id);
29158 } else if (member.type === "way") {
29159 collection[role2].push.apply(collection[role2], entity.nodes);
29160 if (role2 === "from" || role2 === "via") {
29161 collection.keyfrom.push(entity.first());
29162 collection.keyfrom.push(entity.last());
29164 if (role2 === "to" || role2 === "via") {
29165 collection.keyto.push(entity.first());
29166 collection.keyto.push(entity.last());
29174 // modules/actions/copy_entities.js
29175 function actionCopyEntities(ids, fromGraph) {
29177 var action = function(graph) {
29178 ids.forEach(function(id3) {
29179 fromGraph.entity(id3).copy(fromGraph, _copies);
29181 for (var id2 in _copies) {
29182 graph = graph.replace(_copies[id2]);
29186 action.copies = function() {
29192 // modules/actions/delete_member.js
29193 function actionDeleteMember(relationId, memberIndex) {
29194 return function(graph) {
29195 var relation = graph.entity(relationId).removeMember(memberIndex);
29196 graph = graph.replace(relation);
29197 if (relation.isDegenerate()) {
29198 graph = actionDeleteRelation(relation.id)(graph);
29204 // modules/actions/discard_tags.js
29205 function actionDiscardTags(difference, discardTags) {
29206 discardTags = discardTags || {};
29207 return (graph) => {
29208 difference.modified().forEach(checkTags);
29209 difference.created().forEach(checkTags);
29211 function checkTags(entity) {
29212 const keys = Object.keys(entity.tags);
29213 let didDiscard = false;
29215 for (let i2 = 0; i2 < keys.length; i2++) {
29216 const k = keys[i2];
29217 if (discardTags[k] || !entity.tags[k]) {
29220 tags[k] = entity.tags[k];
29224 graph = graph.replace(entity.update({ tags }));
29230 // modules/actions/disconnect.js
29231 function actionDisconnect(nodeId, newNodeId) {
29233 var disconnectableRelationTypes = {
29234 "associatedStreet": true,
29235 "enforcement": true,
29238 var action = function(graph) {
29239 var node = graph.entity(nodeId);
29240 var connections = action.connections(graph);
29241 connections.forEach(function(connection) {
29242 var way = graph.entity(connection.wayID);
29243 var newNode = osmNode({ id: newNodeId, loc: node.loc, tags: node.tags });
29244 graph = graph.replace(newNode);
29245 if (connection.index === 0 && way.isArea()) {
29246 graph = graph.replace(way.replaceNode(way.nodes[0], newNode.id));
29247 } else if (way.isClosed() && connection.index === way.nodes.length - 1) {
29248 graph = graph.replace(way.unclose().addNode(newNode.id));
29250 graph = graph.replace(way.updateNode(newNode.id, connection.index));
29255 action.connections = function(graph) {
29256 var candidates = [];
29257 var keeping = false;
29258 var parentWays = graph.parentWays(graph.entity(nodeId));
29260 for (var i2 = 0; i2 < parentWays.length; i2++) {
29261 way = parentWays[i2];
29262 if (wayIds && wayIds.indexOf(way.id) === -1) {
29266 if (way.isArea() && way.nodes[0] === nodeId) {
29267 candidates.push({ wayID: way.id, index: 0 });
29269 for (var j2 = 0; j2 < way.nodes.length; j2++) {
29270 waynode = way.nodes[j2];
29271 if (waynode === nodeId) {
29272 if (way.isClosed() && parentWays.length > 1 && wayIds && wayIds.indexOf(way.id) !== -1 && j2 === way.nodes.length - 1) {
29275 candidates.push({ wayID: way.id, index: j2 });
29280 return keeping ? candidates : candidates.slice(1);
29282 action.disabled = function(graph) {
29283 var connections = action.connections(graph);
29284 if (connections.length === 0)
29285 return "not_connected";
29286 var parentWays = graph.parentWays(graph.entity(nodeId));
29287 var seenRelationIds = {};
29288 var sharedRelation;
29289 parentWays.forEach(function(way) {
29290 var relations = graph.parentRelations(way);
29291 relations.filter((relation) => !disconnectableRelationTypes[relation.tags.type]).forEach(function(relation) {
29292 if (relation.id in seenRelationIds) {
29294 if (wayIds.indexOf(way.id) !== -1 || wayIds.indexOf(seenRelationIds[relation.id]) !== -1) {
29295 sharedRelation = relation;
29298 sharedRelation = relation;
29301 seenRelationIds[relation.id] = way.id;
29305 if (sharedRelation)
29308 action.limitWays = function(val) {
29309 if (!arguments.length)
29317 // modules/actions/extract.js
29318 function actionExtract(entityID, projection2) {
29319 var extractedNodeID;
29320 var action = function(graph) {
29321 var entity = graph.entity(entityID);
29322 if (entity.type === "node") {
29323 return extractFromNode(entity, graph);
29325 return extractFromWayOrRelation(entity, graph);
29327 function extractFromNode(node, graph) {
29328 extractedNodeID = node.id;
29329 var replacement = osmNode({ loc: node.loc });
29330 graph = graph.replace(replacement);
29331 graph = graph.parentWays(node).reduce(function(accGraph, parentWay) {
29332 return accGraph.replace(parentWay.replaceNode(entityID, replacement.id));
29334 return graph.parentRelations(node).reduce(function(accGraph, parentRel) {
29335 return accGraph.replace(parentRel.replaceMember(node, replacement));
29338 function extractFromWayOrRelation(entity, graph) {
29339 var fromGeometry = entity.geometry(graph);
29340 var keysToCopyAndRetain = ["source", "wheelchair"];
29341 var keysToRetain = ["area"];
29342 var buildingKeysToRetain = ["architect", "building", "height", "layer"];
29343 var extractedLoc = path_default(projection2).centroid(entity.asGeoJSON(graph));
29344 extractedLoc = extractedLoc && projection2.invert(extractedLoc);
29345 if (!extractedLoc || !isFinite(extractedLoc[0]) || !isFinite(extractedLoc[1])) {
29346 extractedLoc = entity.extent(graph).center();
29348 var indoorAreaValues = {
29355 var isBuilding = entity.tags.building && entity.tags.building !== "no" || entity.tags["building:part"] && entity.tags["building:part"] !== "no";
29356 var isIndoorArea = fromGeometry === "area" && entity.tags.indoor && indoorAreaValues[entity.tags.indoor];
29357 var entityTags = Object.assign({}, entity.tags);
29358 var pointTags = {};
29359 for (var key in entityTags) {
29360 if (entity.type === "relation" && key === "type") {
29363 if (keysToRetain.indexOf(key) !== -1) {
29367 if (buildingKeysToRetain.indexOf(key) !== -1 || key.match(/^building:.{1,}/) || key.match(/^roof:.{1,}/))
29370 if (isIndoorArea && key === "indoor") {
29373 pointTags[key] = entityTags[key];
29374 if (keysToCopyAndRetain.indexOf(key) !== -1 || key.match(/^addr:.{1,}/)) {
29376 } else if (isIndoorArea && key === "level") {
29379 delete entityTags[key];
29381 if (!isBuilding && !isIndoorArea && fromGeometry === "area") {
29382 entityTags.area = "yes";
29384 var replacement = osmNode({ loc: extractedLoc, tags: pointTags });
29385 graph = graph.replace(replacement);
29386 extractedNodeID = replacement.id;
29387 return graph.replace(entity.update({ tags: entityTags }));
29389 action.getExtractedNodeID = function() {
29390 return extractedNodeID;
29395 // modules/actions/join.js
29396 function actionJoin(ids) {
29397 function groupEntitiesByGeometry(graph) {
29398 var entities = ids.map(function(id2) {
29399 return graph.entity(id2);
29401 return Object.assign(
29403 utilArrayGroupBy(entities, function(entity) {
29404 return entity.geometry(graph);
29408 var action = function(graph) {
29409 var ways = ids.map(graph.entity, graph);
29410 var survivorID = utilOldestID(ways.map((way) => way.id));
29411 ways.sort(function(a, b) {
29412 var aSided = a.isSided();
29413 var bSided = b.isSided();
29414 return aSided && !bSided ? -1 : bSided && !aSided ? 1 : 0;
29416 var sequences = osmJoinWays(ways, graph);
29417 var joined = sequences[0];
29418 graph = sequences.actions.reduce(function(g, action2) {
29421 var survivor = graph.entity(survivorID);
29422 survivor = survivor.update({ nodes: joined.nodes.map(function(n2) {
29425 graph = graph.replace(survivor);
29426 joined.forEach(function(way) {
29427 if (way.id === survivorID)
29429 graph.parentRelations(way).forEach(function(parent) {
29430 graph = graph.replace(parent.replaceMember(way, survivor));
29432 survivor = survivor.mergeTags(way.tags);
29433 graph = graph.replace(survivor);
29434 graph = actionDeleteWay(way.id)(graph);
29436 function checkForSimpleMultipolygon() {
29437 if (!survivor.isClosed())
29439 var multipolygons = graph.parentMultipolygons(survivor).filter(function(multipolygon2) {
29440 return multipolygon2.members.length === 1;
29442 if (multipolygons.length !== 1)
29444 var multipolygon = multipolygons[0];
29445 for (var key in survivor.tags) {
29446 if (multipolygon.tags[key] && // don't collapse if tags cannot be cleanly merged
29447 multipolygon.tags[key] !== survivor.tags[key])
29450 survivor = survivor.mergeTags(multipolygon.tags);
29451 graph = graph.replace(survivor);
29452 graph = actionDeleteRelation(
29455 /* allow untagged members */
29457 var tags = Object.assign({}, survivor.tags);
29458 if (survivor.geometry(graph) !== "area") {
29462 survivor = survivor.update({ tags });
29463 graph = graph.replace(survivor);
29465 checkForSimpleMultipolygon();
29468 action.resultingWayNodesLength = function(graph) {
29469 return ids.reduce(function(count, id2) {
29470 return count + graph.entity(id2).nodes.length;
29471 }, 0) - ids.length - 1;
29473 action.disabled = function(graph) {
29474 var geometries = groupEntitiesByGeometry(graph);
29475 if (ids.length < 2 || ids.length !== geometries.line.length) {
29476 return "not_eligible";
29478 var joined = osmJoinWays(ids.map(graph.entity, graph), graph);
29479 if (joined.length > 1) {
29480 return "not_adjacent";
29483 var sortedParentRelations = function(id2) {
29484 return graph.parentRelations(graph.entity(id2)).filter((rel) => !rel.isRestriction() && !rel.isConnectivity()).sort((a, b) => a.id - b.id);
29486 var relsA = sortedParentRelations(ids[0]);
29487 for (i2 = 1; i2 < ids.length; i2++) {
29488 var relsB = sortedParentRelations(ids[i2]);
29489 if (!utilArrayIdentical(relsA, relsB)) {
29490 return "conflicting_relations";
29493 for (i2 = 0; i2 < ids.length - 1; i2++) {
29494 for (var j2 = i2 + 1; j2 < ids.length; j2++) {
29495 var path1 = graph.childNodes(graph.entity(ids[i2])).map(function(e) {
29498 var path2 = graph.childNodes(graph.entity(ids[j2])).map(function(e) {
29501 var intersections = geoPathIntersections(path1, path2);
29502 var common = utilArrayIntersection(
29503 joined[0].nodes.map(function(n2) {
29504 return n2.loc.toString();
29506 intersections.map(function(n2) {
29507 return n2.toString();
29510 if (common.length !== intersections.length) {
29511 return "paths_intersect";
29515 var nodeIds = joined[0].nodes.map(function(n2) {
29520 var conflicting = false;
29521 joined[0].forEach(function(way) {
29522 var parents = graph.parentRelations(way);
29523 parents.forEach(function(parent) {
29524 if ((parent.isRestriction() || parent.isConnectivity()) && parent.members.some(function(m) {
29525 return nodeIds.indexOf(m.id) >= 0;
29530 for (var k in way.tags) {
29531 if (!(k in tags)) {
29532 tags[k] = way.tags[k];
29533 } else if (tags[k] && osmIsInterestingTag(k) && tags[k] !== way.tags[k]) {
29534 conflicting = true;
29539 return relation.isRestriction() ? "restriction" : "connectivity";
29542 return "conflicting_tags";
29548 // modules/actions/merge.js
29549 function actionMerge(ids) {
29550 function groupEntitiesByGeometry(graph) {
29551 var entities = ids.map(function(id2) {
29552 return graph.entity(id2);
29554 return Object.assign(
29555 { point: [], area: [], line: [], relation: [] },
29556 utilArrayGroupBy(entities, function(entity) {
29557 return entity.geometry(graph);
29561 var action = function(graph) {
29562 var geometries = groupEntitiesByGeometry(graph);
29563 var target = geometries.area[0] || geometries.line[0];
29564 var points = geometries.point;
29565 points.forEach(function(point2) {
29566 target = target.mergeTags(point2.tags);
29567 graph = graph.replace(target);
29568 graph.parentRelations(point2).forEach(function(parent) {
29569 graph = graph.replace(parent.replaceMember(point2, target));
29571 var nodes = utilArrayUniq(graph.childNodes(target));
29572 var removeNode = point2;
29573 if (!point2.isNew()) {
29574 var inserted = false;
29575 var canBeReplaced = function(node2) {
29576 return !(graph.parentWays(node2).length > 1 || graph.parentRelations(node2).length);
29578 var replaceNode = function(node2) {
29579 graph = graph.replace(point2.update({ tags: node2.tags, loc: node2.loc }));
29580 target = target.replaceNode(node2.id, point2.id);
29581 graph = graph.replace(target);
29582 removeNode = node2;
29587 for (i2 = 0; i2 < nodes.length; i2++) {
29589 if (canBeReplaced(node) && node.isNew()) {
29594 if (!inserted && point2.hasInterestingTags()) {
29595 for (i2 = 0; i2 < nodes.length; i2++) {
29597 if (canBeReplaced(node) && !node.hasInterestingTags()) {
29603 for (i2 = 0; i2 < nodes.length; i2++) {
29605 if (canBeReplaced(node) && utilCompareIDs(point2.id, node.id) < 0) {
29613 graph = graph.remove(removeNode);
29615 if (target.tags.area === "yes") {
29616 var tags = Object.assign({}, target.tags);
29618 if (osmTagSuggestingArea(tags)) {
29619 target = target.update({ tags });
29620 graph = graph.replace(target);
29625 action.disabled = function(graph) {
29626 var geometries = groupEntitiesByGeometry(graph);
29627 if (geometries.point.length === 0 || geometries.area.length + geometries.line.length !== 1 || geometries.relation.length !== 0) {
29628 return "not_eligible";
29634 // modules/actions/merge_nodes.js
29635 function actionMergeNodes(nodeIDs, loc) {
29636 function chooseLoc(graph) {
29637 if (!nodeIDs.length)
29640 var interestingCount = 0;
29641 var interestingLoc;
29642 for (var i2 = 0; i2 < nodeIDs.length; i2++) {
29643 var node = graph.entity(nodeIDs[i2]);
29644 if (node.hasInterestingTags()) {
29645 interestingLoc = ++interestingCount === 1 ? node.loc : null;
29647 sum = geoVecAdd(sum, node.loc);
29649 return interestingLoc || geoVecScale(sum, 1 / nodeIDs.length);
29651 var action = function(graph) {
29652 if (nodeIDs.length < 2)
29656 toLoc = chooseLoc(graph);
29658 for (var i2 = 0; i2 < nodeIDs.length; i2++) {
29659 var node = graph.entity(nodeIDs[i2]);
29660 if (node.loc !== toLoc) {
29661 graph = graph.replace(node.move(toLoc));
29664 return actionConnect(nodeIDs)(graph);
29666 action.disabled = function(graph) {
29667 if (nodeIDs.length < 2)
29668 return "not_eligible";
29669 for (var i2 = 0; i2 < nodeIDs.length; i2++) {
29670 var entity = graph.entity(nodeIDs[i2]);
29671 if (entity.type !== "node")
29672 return "not_eligible";
29674 return actionConnect(nodeIDs).disabled(graph);
29679 // modules/osm/changeset.js
29680 function osmChangeset() {
29681 if (!(this instanceof osmChangeset)) {
29682 return new osmChangeset().initialize(arguments);
29683 } else if (arguments.length) {
29684 this.initialize(arguments);
29687 osmEntity.changeset = osmChangeset;
29688 osmChangeset.prototype = Object.create(osmEntity.prototype);
29689 Object.assign(osmChangeset.prototype, {
29691 extent: function() {
29692 return new geoExtent();
29694 geometry: function() {
29695 return "changeset";
29697 asJXON: function() {
29701 tag: Object.keys(this.tags).map(function(k) {
29702 return { "@k": k, "@v": this.tags[k] };
29710 // Generate [osmChange](http://wiki.openstreetmap.org/wiki/OsmChange)
29711 // XML. Returns a string.
29712 osmChangeJXON: function(changes) {
29713 var changeset_id = this.id;
29714 function nest(x, order) {
29716 for (var i2 = 0; i2 < x.length; i2++) {
29717 var tagName = Object.keys(x[i2])[0];
29718 if (!groups[tagName])
29719 groups[tagName] = [];
29720 groups[tagName].push(x[i2][tagName]);
29723 order.forEach(function(o) {
29725 ordered[o] = groups[o];
29729 function sort(changes2) {
29730 function resolve(item) {
29731 return relations.find(function(relation2) {
29732 return item.keyAttributes.type === "relation" && item.keyAttributes.ref === relation2["@id"];
29735 function isNew(item) {
29736 return !sorted[item["@id"]] && !processing.find(function(proc) {
29737 return proc["@id"] === item["@id"];
29740 var processing = [];
29742 var relations = changes2.relation;
29745 for (var i2 = 0; i2 < relations.length; i2++) {
29746 var relation = relations[i2];
29747 if (!sorted[relation["@id"]]) {
29748 processing.push(relation);
29750 while (processing.length > 0) {
29751 var next = processing[0], deps = next.member.map(resolve).filter(Boolean).filter(isNew);
29752 if (deps.length === 0) {
29753 sorted[next["@id"]] = next;
29754 processing.shift();
29756 processing = deps.concat(processing);
29760 changes2.relation = Object.values(sorted);
29763 function rep2(entity) {
29764 return entity.asJXON(changeset_id);
29769 "@generator": "iD",
29770 "create": sort(nest(changes.created.map(rep2), ["node", "way", "relation"])),
29771 "modify": nest(changes.modified.map(rep2), ["node", "way", "relation"]),
29772 "delete": Object.assign(nest(changes.deleted.map(rep2), ["relation", "way", "node"]), { "@if-unused": true })
29776 asGeoJSON: function() {
29781 // modules/osm/note.js
29782 function osmNote() {
29783 if (!(this instanceof osmNote)) {
29784 return new osmNote().initialize(arguments);
29785 } else if (arguments.length) {
29786 this.initialize(arguments);
29789 osmNote.id = function() {
29790 return osmNote.id.next--;
29792 osmNote.id.next = -1;
29793 Object.assign(osmNote.prototype, {
29795 initialize: function(sources) {
29796 for (var i2 = 0; i2 < sources.length; ++i2) {
29797 var source = sources[i2];
29798 for (var prop in source) {
29799 if (Object.prototype.hasOwnProperty.call(source, prop)) {
29800 if (source[prop] === void 0) {
29803 this[prop] = source[prop];
29809 this.id = osmNote.id().toString();
29813 extent: function() {
29814 return new geoExtent(this.loc);
29816 update: function(attrs) {
29817 return osmNote(this, attrs);
29819 isNew: function() {
29820 return this.id < 0;
29822 move: function(loc) {
29823 return this.update({ loc });
29827 // modules/osm/relation.js
29828 function osmRelation() {
29829 if (!(this instanceof osmRelation)) {
29830 return new osmRelation().initialize(arguments);
29831 } else if (arguments.length) {
29832 this.initialize(arguments);
29835 osmEntity.relation = osmRelation;
29836 osmRelation.prototype = Object.create(osmEntity.prototype);
29837 osmRelation.creationOrder = function(a, b) {
29838 var aId = parseInt(osmEntity.id.toOSM(a.id), 10);
29839 var bId = parseInt(osmEntity.id.toOSM(b.id), 10);
29840 if (aId < 0 || bId < 0)
29844 Object.assign(osmRelation.prototype, {
29847 copy: function(resolver, copies) {
29848 if (copies[this.id])
29849 return copies[this.id];
29850 var copy2 = osmEntity.prototype.copy.call(this, resolver, copies);
29851 var members = this.members.map(function(member) {
29852 return Object.assign({}, member, { id: resolver.entity(member.id).copy(resolver, copies).id });
29854 copy2 = copy2.update({ members });
29855 copies[this.id] = copy2;
29858 extent: function(resolver, memo) {
29859 return resolver.transient(this, "extent", function() {
29860 if (memo && memo[this.id])
29861 return geoExtent();
29863 memo[this.id] = true;
29864 var extent = geoExtent();
29865 for (var i2 = 0; i2 < this.members.length; i2++) {
29866 var member = resolver.hasEntity(this.members[i2].id);
29868 extent._extend(member.extent(resolver, memo));
29874 geometry: function(graph) {
29875 return graph.transient(this, "geometry", function() {
29876 return this.isMultipolygon() ? "area" : "relation";
29879 isDegenerate: function() {
29880 return this.members.length === 0;
29882 // Return an array of members, each extended with an 'index' property whose value
29883 // is the member index.
29884 indexedMembers: function() {
29885 var result = new Array(this.members.length);
29886 for (var i2 = 0; i2 < this.members.length; i2++) {
29887 result[i2] = Object.assign({}, this.members[i2], { index: i2 });
29891 // Return the first member with the given role. A copy of the member object
29892 // is returned, extended with an 'index' property whose value is the member index.
29893 memberByRole: function(role) {
29894 for (var i2 = 0; i2 < this.members.length; i2++) {
29895 if (this.members[i2].role === role) {
29896 return Object.assign({}, this.members[i2], { index: i2 });
29900 // Same as memberByRole, but returns all members with the given role
29901 membersByRole: function(role) {
29903 for (var i2 = 0; i2 < this.members.length; i2++) {
29904 if (this.members[i2].role === role) {
29905 result.push(Object.assign({}, this.members[i2], { index: i2 }));
29910 // Return the first member with the given id. A copy of the member object
29911 // is returned, extended with an 'index' property whose value is the member index.
29912 memberById: function(id2) {
29913 for (var i2 = 0; i2 < this.members.length; i2++) {
29914 if (this.members[i2].id === id2) {
29915 return Object.assign({}, this.members[i2], { index: i2 });
29919 // Return the first member with the given id and role. A copy of the member object
29920 // is returned, extended with an 'index' property whose value is the member index.
29921 memberByIdAndRole: function(id2, role) {
29922 for (var i2 = 0; i2 < this.members.length; i2++) {
29923 if (this.members[i2].id === id2 && this.members[i2].role === role) {
29924 return Object.assign({}, this.members[i2], { index: i2 });
29928 addMember: function(member, index) {
29929 var members = this.members.slice();
29930 members.splice(index === void 0 ? members.length : index, 0, member);
29931 return this.update({ members });
29933 updateMember: function(member, index) {
29934 var members = this.members.slice();
29935 members.splice(index, 1, Object.assign({}, members[index], member));
29936 return this.update({ members });
29938 removeMember: function(index) {
29939 var members = this.members.slice();
29940 members.splice(index, 1);
29941 return this.update({ members });
29943 removeMembersWithID: function(id2) {
29944 var members = this.members.filter(function(m) {
29945 return m.id !== id2;
29947 return this.update({ members });
29949 moveMember: function(fromIndex, toIndex) {
29950 var members = this.members.slice();
29951 members.splice(toIndex, 0, members.splice(fromIndex, 1)[0]);
29952 return this.update({ members });
29954 // Wherever a member appears with id `needle.id`, replace it with a member
29955 // with id `replacement.id`, type `replacement.type`, and the original role,
29956 // By default, adding a duplicate member (by id and role) is prevented.
29957 // Return an updated relation.
29958 replaceMember: function(needle, replacement, keepDuplicates) {
29959 if (!this.memberById(needle.id))
29962 for (var i2 = 0; i2 < this.members.length; i2++) {
29963 var member = this.members[i2];
29964 if (member.id !== needle.id) {
29965 members.push(member);
29966 } else if (keepDuplicates || !this.memberByIdAndRole(replacement.id, member.role)) {
29967 members.push({ id: replacement.id, type: replacement.type, role: member.role });
29970 return this.update({ members });
29972 asJXON: function(changeset_id) {
29975 "@id": this.osmId(),
29976 "@version": this.version || 0,
29977 member: this.members.map(function(member) {
29982 ref: osmEntity.id.toOSM(member.id)
29986 tag: Object.keys(this.tags).map(function(k) {
29987 return { keyAttributes: { k, v: this.tags[k] } };
29991 if (changeset_id) {
29992 r.relation["@changeset"] = changeset_id;
29996 asGeoJSON: function(resolver) {
29997 return resolver.transient(this, "GeoJSON", function() {
29998 if (this.isMultipolygon()) {
30000 type: "MultiPolygon",
30001 coordinates: this.multipolygon(resolver)
30005 type: "FeatureCollection",
30006 properties: this.tags,
30007 features: this.members.map(function(member) {
30008 return Object.assign({ role: member.role }, resolver.entity(member.id).asGeoJSON(resolver));
30014 area: function(resolver) {
30015 return resolver.transient(this, "area", function() {
30016 return area_default(this.asGeoJSON(resolver));
30019 isMultipolygon: function() {
30020 return this.tags.type === "multipolygon";
30022 isComplete: function(resolver) {
30023 for (var i2 = 0; i2 < this.members.length; i2++) {
30024 if (!resolver.hasEntity(this.members[i2].id)) {
30030 hasFromViaTo: function() {
30031 return this.members.some(function(m) {
30032 return m.role === "from";
30033 }) && this.members.some(function(m) {
30034 return m.role === "via";
30035 }) && this.members.some(function(m) {
30036 return m.role === "to";
30039 isRestriction: function() {
30040 return !!(this.tags.type && this.tags.type.match(/^restriction:?/));
30042 isValidRestriction: function() {
30043 if (!this.isRestriction())
30045 var froms = this.members.filter(function(m) {
30046 return m.role === "from";
30048 var vias = this.members.filter(function(m) {
30049 return m.role === "via";
30051 var tos = this.members.filter(function(m) {
30052 return m.role === "to";
30054 if (froms.length !== 1 && this.tags.restriction !== "no_entry")
30056 if (froms.some(function(m) {
30057 return m.type !== "way";
30060 if (tos.length !== 1 && this.tags.restriction !== "no_exit")
30062 if (tos.some(function(m) {
30063 return m.type !== "way";
30066 if (vias.length === 0)
30068 if (vias.length > 1 && vias.some(function(m) {
30069 return m.type !== "way";
30074 isConnectivity: function() {
30075 return !!(this.tags.type && this.tags.type.match(/^connectivity:?/));
30077 // Returns an array [A0, ... An], each Ai being an array of node arrays [Nds0, ... Ndsm],
30078 // where Nds0 is an outer ring and subsequent Ndsi's (if any i > 0) being inner rings.
30080 // This corresponds to the structure needed for rendering a multipolygon path using a
30081 // `evenodd` fill rule, as well as the structure of a GeoJSON MultiPolygon geometry.
30083 // In the case of invalid geometries, this function will still return a result which
30084 // includes the nodes of all way members, but some Nds may be unclosed and some inner
30085 // rings not matched with the intended outer ring.
30087 multipolygon: function(resolver) {
30088 var outers = this.members.filter(function(m) {
30089 return "outer" === (m.role || "outer");
30091 var inners = this.members.filter(function(m) {
30092 return "inner" === m.role;
30094 outers = osmJoinWays(outers, resolver);
30095 inners = osmJoinWays(inners, resolver);
30096 var sequenceToLineString = function(sequence) {
30097 if (sequence.nodes.length > 2 && sequence.nodes[0] !== sequence.nodes[sequence.nodes.length - 1]) {
30098 sequence.nodes.push(sequence.nodes[0]);
30100 return sequence.nodes.map(function(node) {
30104 outers = outers.map(sequenceToLineString);
30105 inners = inners.map(sequenceToLineString);
30106 var result = outers.map(function(o2) {
30107 return [area_default({ type: "Polygon", coordinates: [o2] }) > 2 * Math.PI ? o2.reverse() : o2];
30109 function findOuter(inner2) {
30111 for (o2 = 0; o2 < outers.length; o2++) {
30112 outer = outers[o2];
30113 if (geoPolygonContainsPolygon(outer, inner2)) {
30117 for (o2 = 0; o2 < outers.length; o2++) {
30118 outer = outers[o2];
30119 if (geoPolygonIntersectsPolygon(outer, inner2, false)) {
30124 for (var i2 = 0; i2 < inners.length; i2++) {
30125 var inner = inners[i2];
30126 if (area_default({ type: "Polygon", coordinates: [inner] }) < 2 * Math.PI) {
30127 inner = inner.reverse();
30129 var o = findOuter(inners[i2]);
30130 if (o !== void 0) {
30131 result[o].push(inners[i2]);
30133 result.push([inners[i2]]);
30140 // modules/osm/qa_item.js
30141 var QAItem = class {
30142 constructor(loc, service, itemType, id2, props) {
30144 this.service = service.title;
30145 this.itemType = itemType;
30146 this.id = id2 ? id2 : `${QAItem.id()}`;
30147 this.update(props);
30148 if (service && typeof service.getIcon === "function") {
30149 this.icon = service.getIcon(itemType);
30153 const { loc, service, itemType, id: id2 } = this;
30154 Object.keys(props).forEach((prop) => this[prop] = props[prop]);
30156 this.service = service;
30157 this.itemType = itemType;
30161 // Generic handling for newly created QAItems
30163 return this.nextId--;
30166 QAItem.nextId = -1;
30168 // modules/actions/split.js
30169 function actionSplit(nodeIds, newWayIds) {
30170 if (typeof nodeIds === "string")
30171 nodeIds = [nodeIds];
30173 var _keepHistoryOn = "longest";
30174 var _createdWayIDs = [];
30175 function dist(graph, nA, nB) {
30176 var locA = graph.entity(nA).loc;
30177 var locB = graph.entity(nB).loc;
30178 var epsilon3 = 1e-6;
30179 return locA && locB ? geoSphericalDistance(locA, locB) : epsilon3;
30181 function splitArea(nodes, idxA, graph) {
30182 var lengths = new Array(nodes.length);
30187 function wrap2(index) {
30188 return utilWrap(index, nodes.length);
30191 for (i2 = wrap2(idxA + 1); i2 !== idxA; i2 = wrap2(i2 + 1)) {
30192 length += dist(graph, nodes[i2], nodes[wrap2(i2 - 1)]);
30193 lengths[i2] = length;
30196 for (i2 = wrap2(idxA - 1); i2 !== idxA; i2 = wrap2(i2 - 1)) {
30197 length += dist(graph, nodes[i2], nodes[wrap2(i2 + 1)]);
30198 if (length < lengths[i2]) {
30199 lengths[i2] = length;
30202 for (i2 = 0; i2 < nodes.length; i2++) {
30203 var cost = lengths[i2] / dist(graph, nodes[idxA], nodes[i2]);
30211 function totalLengthBetweenNodes(graph, nodes) {
30212 var totalLength = 0;
30213 for (var i2 = 0; i2 < nodes.length - 1; i2++) {
30214 totalLength += dist(graph, nodes[i2], nodes[i2 + 1]);
30216 return totalLength;
30218 function split(graph, nodeId, wayA, newWayId) {
30219 var wayB = osmWay({ id: newWayId, tags: wayA.tags });
30220 var origNodes = wayA.nodes.slice();
30223 var isArea = wayA.isArea();
30224 var isOuter = osmIsOldMultipolygonOuterMember(wayA, graph);
30225 if (wayA.isClosed()) {
30226 var nodes = wayA.nodes.slice(0, -1);
30227 var idxA = nodes.indexOf(nodeId);
30228 var idxB = splitArea(nodes, idxA, graph);
30230 nodesA = nodes.slice(idxA).concat(nodes.slice(0, idxB + 1));
30231 nodesB = nodes.slice(idxB, idxA + 1);
30233 nodesA = nodes.slice(idxA, idxB + 1);
30234 nodesB = nodes.slice(idxB).concat(nodes.slice(0, idxA + 1));
30237 var idx = wayA.nodes.indexOf(nodeId, 1);
30238 nodesA = wayA.nodes.slice(0, idx + 1);
30239 nodesB = wayA.nodes.slice(idx);
30241 var lengthA = totalLengthBetweenNodes(graph, nodesA);
30242 var lengthB = totalLengthBetweenNodes(graph, nodesB);
30243 if (_keepHistoryOn === "longest" && lengthB > lengthA) {
30244 wayA = wayA.update({ nodes: nodesB });
30245 wayB = wayB.update({ nodes: nodesA });
30246 var temp = lengthA;
30250 wayA = wayA.update({ nodes: nodesA });
30251 wayB = wayB.update({ nodes: nodesB });
30253 if (wayA.tags.step_count) {
30254 var stepCount = Number(wayA.tags.step_count);
30255 if (stepCount && // ensure a number
30256 isFinite(stepCount) && // ensure positive
30257 stepCount > 0 && // ensure integer
30258 Math.round(stepCount) === stepCount) {
30259 var tagsA = Object.assign({}, wayA.tags);
30260 var tagsB = Object.assign({}, wayB.tags);
30261 var ratioA = lengthA / (lengthA + lengthB);
30262 var countA = Math.round(stepCount * ratioA);
30263 tagsA.step_count = countA.toString();
30264 tagsB.step_count = (stepCount - countA).toString();
30265 wayA = wayA.update({ tags: tagsA });
30266 wayB = wayB.update({ tags: tagsB });
30269 graph = graph.replace(wayA);
30270 graph = graph.replace(wayB);
30271 graph.parentRelations(wayA).forEach(function(relation) {
30273 if (relation.hasFromViaTo()) {
30274 var f2 = relation.memberByRole("from");
30275 var v = relation.membersByRole("via");
30276 var t = relation.memberByRole("to");
30278 if (f2.id === wayA.id || t.id === wayA.id) {
30280 if (v.length === 1 && v[0].type === "node") {
30281 keepB = wayB.contains(v[0].id);
30283 for (i2 = 0; i2 < v.length; i2++) {
30284 if (v[i2].type === "way") {
30285 var wayVia = graph.hasEntity(v[i2].id);
30286 if (wayVia && utilArrayIntersection(wayB.nodes, wayVia.nodes).length) {
30294 relation = relation.replaceMember(wayA, wayB);
30295 graph = graph.replace(relation);
30298 for (i2 = 0; i2 < v.length; i2++) {
30299 if (v[i2].type === "way" && v[i2].id === wayA.id) {
30305 graph = actionAddMember(relation.id, member, v[i2].index + 1)(graph);
30311 if (relation === isOuter) {
30312 graph = graph.replace(relation.mergeTags(wayA.tags));
30313 graph = graph.replace(wayA.update({ tags: {} }));
30314 graph = graph.replace(wayB.update({ tags: {} }));
30319 role: relation.memberById(wayA.id).role
30322 originalID: wayA.id,
30323 insertedID: wayB.id,
30326 graph = actionAddMember(relation.id, member, void 0, insertPair)(graph);
30329 if (!isOuter && isArea) {
30330 var multipolygon = osmRelation({
30331 tags: Object.assign({}, wayA.tags, { type: "multipolygon" }),
30333 { id: wayA.id, role: "outer", type: "way" },
30334 { id: wayB.id, role: "outer", type: "way" }
30337 graph = graph.replace(multipolygon);
30338 graph = graph.replace(wayA.update({ tags: {} }));
30339 graph = graph.replace(wayB.update({ tags: {} }));
30341 _createdWayIDs.push(wayB.id);
30344 var action = function(graph) {
30345 _createdWayIDs = [];
30346 var newWayIndex = 0;
30347 for (var i2 = 0; i2 < nodeIds.length; i2++) {
30348 var nodeId = nodeIds[i2];
30349 var candidates = action.waysForNode(nodeId, graph);
30350 for (var j2 = 0; j2 < candidates.length; j2++) {
30351 graph = split(graph, nodeId, candidates[j2], newWayIds && newWayIds[newWayIndex]);
30357 action.getCreatedWayIDs = function() {
30358 return _createdWayIDs;
30360 action.waysForNode = function(nodeId, graph) {
30361 var node = graph.entity(nodeId);
30362 var splittableParents = graph.parentWays(node).filter(isSplittable);
30364 var hasLine = splittableParents.some(function(parent) {
30365 return parent.geometry(graph) === "line";
30368 return splittableParents.filter(function(parent) {
30369 return parent.geometry(graph) === "line";
30373 return splittableParents;
30374 function isSplittable(parent) {
30375 if (_wayIDs && _wayIDs.indexOf(parent.id) === -1)
30377 if (parent.isClosed())
30379 for (var i2 = 1; i2 < parent.nodes.length - 1; i2++) {
30380 if (parent.nodes[i2] === nodeId)
30386 action.ways = function(graph) {
30387 return utilArrayUniq([].concat.apply([], nodeIds.map(function(nodeId) {
30388 return action.waysForNode(nodeId, graph);
30391 action.disabled = function(graph) {
30392 for (var i2 = 0; i2 < nodeIds.length; i2++) {
30393 var nodeId = nodeIds[i2];
30394 var candidates = action.waysForNode(nodeId, graph);
30395 if (candidates.length === 0 || _wayIDs && _wayIDs.length !== candidates.length) {
30396 return "not_eligible";
30400 action.limitWays = function(val) {
30401 if (!arguments.length)
30406 action.keepHistoryOn = function(val) {
30407 if (!arguments.length)
30408 return _keepHistoryOn;
30409 _keepHistoryOn = val;
30415 // modules/core/graph.js
30416 function coreGraph(other, mutable) {
30417 if (!(this instanceof coreGraph))
30418 return new coreGraph(other, mutable);
30419 if (other instanceof coreGraph) {
30420 var base = other.base();
30421 this.entities = Object.assign(Object.create(base.entities), other.entities);
30422 this._parentWays = Object.assign(Object.create(base.parentWays), other._parentWays);
30423 this._parentRels = Object.assign(Object.create(base.parentRels), other._parentRels);
30425 this.entities = /* @__PURE__ */ Object.create({});
30426 this._parentWays = /* @__PURE__ */ Object.create({});
30427 this._parentRels = /* @__PURE__ */ Object.create({});
30428 this.rebase(other || [], [this]);
30430 this.transients = {};
30431 this._childNodes = {};
30432 this.frozen = !mutable;
30434 coreGraph.prototype = {
30435 hasEntity: function(id2) {
30436 return this.entities[id2];
30438 entity: function(id2) {
30439 var entity = this.entities[id2];
30441 entity = this.entities.__proto__[id2];
30444 throw new Error("entity " + id2 + " not found");
30448 geometry: function(id2) {
30449 return this.entity(id2).geometry(this);
30451 transient: function(entity, key, fn) {
30452 var id2 = entity.id;
30453 var transients = this.transients[id2] || (this.transients[id2] = {});
30454 if (transients[key] !== void 0) {
30455 return transients[key];
30457 transients[key] = fn.call(entity);
30458 return transients[key];
30460 parentWays: function(entity) {
30461 var parents = this._parentWays[entity.id];
30464 parents.forEach(function(id2) {
30465 result.push(this.entity(id2));
30470 isPoi: function(entity) {
30471 var parents = this._parentWays[entity.id];
30472 return !parents || parents.size === 0;
30474 isShared: function(entity) {
30475 var parents = this._parentWays[entity.id];
30476 return parents && parents.size > 1;
30478 parentRelations: function(entity) {
30479 var parents = this._parentRels[entity.id];
30482 parents.forEach(function(id2) {
30483 result.push(this.entity(id2));
30488 parentMultipolygons: function(entity) {
30489 return this.parentRelations(entity).filter(function(relation) {
30490 return relation.isMultipolygon();
30493 childNodes: function(entity) {
30494 if (this._childNodes[entity.id])
30495 return this._childNodes[entity.id];
30499 for (var i2 = 0; i2 < entity.nodes.length; i2++) {
30500 nodes[i2] = this.entity(entity.nodes[i2]);
30503 Object.freeze(nodes);
30504 this._childNodes[entity.id] = nodes;
30505 return this._childNodes[entity.id];
30509 "entities": Object.getPrototypeOf(this.entities),
30510 "parentWays": Object.getPrototypeOf(this._parentWays),
30511 "parentRels": Object.getPrototypeOf(this._parentRels)
30514 // Unlike other graph methods, rebase mutates in place. This is because it
30515 // is used only during the history operation that merges newly downloaded
30516 // data into each state. To external consumers, it should appear as if the
30517 // graph always contained the newly downloaded data.
30518 rebase: function(entities, stack, force) {
30519 var base = this.base();
30520 var i2, j2, k, id2;
30521 for (i2 = 0; i2 < entities.length; i2++) {
30522 var entity = entities[i2];
30523 if (!entity.visible || !force && base.entities[entity.id])
30525 base.entities[entity.id] = entity;
30526 this._updateCalculated(void 0, entity, base.parentWays, base.parentRels);
30527 if (entity.type === "way") {
30528 for (j2 = 0; j2 < entity.nodes.length; j2++) {
30529 id2 = entity.nodes[j2];
30530 for (k = 1; k < stack.length; k++) {
30531 var ents = stack[k].entities;
30532 if (ents.hasOwnProperty(id2) && ents[id2] === void 0) {
30539 for (i2 = 0; i2 < stack.length; i2++) {
30540 stack[i2]._updateRebased();
30543 _updateRebased: function() {
30544 var base = this.base();
30545 Object.keys(this._parentWays).forEach(function(child) {
30546 if (base.parentWays[child]) {
30547 base.parentWays[child].forEach(function(id2) {
30548 if (!this.entities.hasOwnProperty(id2)) {
30549 this._parentWays[child].add(id2);
30554 Object.keys(this._parentRels).forEach(function(child) {
30555 if (base.parentRels[child]) {
30556 base.parentRels[child].forEach(function(id2) {
30557 if (!this.entities.hasOwnProperty(id2)) {
30558 this._parentRels[child].add(id2);
30563 this.transients = {};
30565 // Updates calculated properties (parentWays, parentRels) for the specified change
30566 _updateCalculated: function(oldentity, entity, parentWays, parentRels) {
30567 parentWays = parentWays || this._parentWays;
30568 parentRels = parentRels || this._parentRels;
30569 var type2 = entity && entity.type || oldentity && oldentity.type;
30570 var removed, added, i2;
30571 if (type2 === "way") {
30572 if (oldentity && entity) {
30573 removed = utilArrayDifference(oldentity.nodes, entity.nodes);
30574 added = utilArrayDifference(entity.nodes, oldentity.nodes);
30575 } else if (oldentity) {
30576 removed = oldentity.nodes;
30578 } else if (entity) {
30580 added = entity.nodes;
30582 for (i2 = 0; i2 < removed.length; i2++) {
30583 parentWays[removed[i2]] = new Set(parentWays[removed[i2]]);
30584 parentWays[removed[i2]].delete(oldentity.id);
30586 for (i2 = 0; i2 < added.length; i2++) {
30587 parentWays[added[i2]] = new Set(parentWays[added[i2]]);
30588 parentWays[added[i2]].add(entity.id);
30590 } else if (type2 === "relation") {
30591 var oldentityMemberIDs = oldentity ? oldentity.members.map(function(m) {
30594 var entityMemberIDs = entity ? entity.members.map(function(m) {
30597 if (oldentity && entity) {
30598 removed = utilArrayDifference(oldentityMemberIDs, entityMemberIDs);
30599 added = utilArrayDifference(entityMemberIDs, oldentityMemberIDs);
30600 } else if (oldentity) {
30601 removed = oldentityMemberIDs;
30603 } else if (entity) {
30605 added = entityMemberIDs;
30607 for (i2 = 0; i2 < removed.length; i2++) {
30608 parentRels[removed[i2]] = new Set(parentRels[removed[i2]]);
30609 parentRels[removed[i2]].delete(oldentity.id);
30611 for (i2 = 0; i2 < added.length; i2++) {
30612 parentRels[added[i2]] = new Set(parentRels[added[i2]]);
30613 parentRels[added[i2]].add(entity.id);
30617 replace: function(entity) {
30618 if (this.entities[entity.id] === entity)
30620 return this.update(function() {
30621 this._updateCalculated(this.entities[entity.id], entity);
30622 this.entities[entity.id] = entity;
30625 remove: function(entity) {
30626 return this.update(function() {
30627 this._updateCalculated(entity, void 0);
30628 this.entities[entity.id] = void 0;
30631 revert: function(id2) {
30632 var baseEntity = this.base().entities[id2];
30633 var headEntity = this.entities[id2];
30634 if (headEntity === baseEntity)
30636 return this.update(function() {
30637 this._updateCalculated(headEntity, baseEntity);
30638 delete this.entities[id2];
30641 update: function() {
30642 var graph = this.frozen ? coreGraph(this, true) : this;
30643 for (var i2 = 0; i2 < arguments.length; i2++) {
30644 arguments[i2].call(graph, graph);
30647 graph.frozen = true;
30650 // Obliterates any existing entities
30651 load: function(entities) {
30652 var base = this.base();
30653 this.entities = Object.create(base.entities);
30654 for (var i2 in entities) {
30655 this.entities[i2] = entities[i2];
30656 this._updateCalculated(base.entities[i2], this.entities[i2]);
30662 // modules/osm/intersection.js
30663 function osmTurn(turn) {
30664 if (!(this instanceof osmTurn)) {
30665 return new osmTurn(turn);
30667 Object.assign(this, turn);
30669 function osmIntersection(graph, startVertexId, maxDistance) {
30670 maxDistance = maxDistance || 30;
30671 var vgraph = coreGraph();
30673 function memberOfRestriction(entity) {
30674 return graph.parentRelations(entity).some(function(r) {
30675 return r.isRestriction();
30678 function isRoad(way2) {
30679 if (way2.isArea() || way2.isDegenerate())
30683 "motorway_link": true,
30685 "trunk_link": true,
30687 "primary_link": true,
30689 "secondary_link": true,
30691 "tertiary_link": true,
30692 "residential": true,
30693 "unclassified": true,
30694 "living_street": true,
30699 return roads[way2.tags.highway];
30701 var startNode = graph.entity(startVertexId);
30702 var checkVertices = [startNode];
30705 var vertexIds = [];
30715 while (checkVertices.length) {
30716 vertex = checkVertices.pop();
30717 checkWays = graph.parentWays(vertex);
30718 var hasWays = false;
30719 for (i2 = 0; i2 < checkWays.length; i2++) {
30720 way = checkWays[i2];
30721 if (!isRoad(way) && !memberOfRestriction(way))
30725 nodes = utilArrayUniq(graph.childNodes(way));
30726 for (j2 = 0; j2 < nodes.length; j2++) {
30728 if (node === vertex)
30730 if (vertices.indexOf(node) !== -1)
30732 if (geoSphericalDistance(node.loc, startNode.loc) > maxDistance)
30734 var hasParents = false;
30735 parents = graph.parentWays(node);
30736 for (k = 0; k < parents.length; k++) {
30737 parent = parents[k];
30738 if (parent === way)
30740 if (ways.indexOf(parent) !== -1)
30742 if (!isRoad(parent))
30748 checkVertices.push(node);
30753 vertices.push(vertex);
30756 vertices = utilArrayUniq(vertices);
30757 ways = utilArrayUniq(ways);
30758 ways.forEach(function(way2) {
30759 graph.childNodes(way2).forEach(function(node2) {
30760 vgraph = vgraph.replace(node2);
30762 vgraph = vgraph.replace(way2);
30763 graph.parentRelations(way2).forEach(function(relation) {
30764 if (relation.isRestriction()) {
30765 if (relation.isValidRestriction(graph)) {
30766 vgraph = vgraph.replace(relation);
30767 } else if (relation.isComplete(graph)) {
30768 actions.push(actionDeleteRelation(relation.id));
30773 ways.forEach(function(w) {
30774 var way2 = vgraph.entity(w.id);
30775 if (way2.tags.oneway === "-1") {
30776 var action = actionReverse(way2.id, { reverseOneway: true });
30777 actions.push(action);
30778 vgraph = action(vgraph);
30781 var origCount = osmEntity.id.next.way;
30782 vertices.forEach(function(v) {
30783 var splitAll = actionSplit([v.id]).keepHistoryOn("first");
30784 if (!splitAll.disabled(vgraph)) {
30785 splitAll.ways(vgraph).forEach(function(way2) {
30786 var splitOne = actionSplit([v.id]).limitWays([way2.id]).keepHistoryOn("first");
30787 actions.push(splitOne);
30788 vgraph = splitOne(vgraph);
30792 osmEntity.id.next.way = origCount;
30793 vertexIds = vertices.map(function(v) {
30798 vertexIds.forEach(function(id2) {
30799 var vertex2 = vgraph.entity(id2);
30800 var parents2 = vgraph.parentWays(vertex2);
30801 vertices.push(vertex2);
30802 ways = ways.concat(parents2);
30804 vertices = utilArrayUniq(vertices);
30805 ways = utilArrayUniq(ways);
30806 vertexIds = vertices.map(function(v) {
30809 wayIds = ways.map(function(w) {
30812 function withMetadata(way2, vertexIds2) {
30813 var __oneWay = way2.isOneWay();
30814 var __first = vertexIds2.indexOf(way2.first()) !== -1;
30815 var __last = vertexIds2.indexOf(way2.last()) !== -1;
30816 var __via = __first && __last;
30817 var __from = __first && !__oneWay || __last;
30818 var __to = __first || __last && !__oneWay;
30819 return way2.update({
30829 wayIds.forEach(function(id2) {
30830 var way2 = withMetadata(vgraph.entity(id2), vertexIds);
30831 vgraph = vgraph.replace(way2);
30835 var removeWayIds = [];
30836 var removeVertexIds = [];
30839 checkVertices = vertexIds.slice();
30840 for (i2 = 0; i2 < checkVertices.length; i2++) {
30841 var vertexId = checkVertices[i2];
30842 vertex = vgraph.hasEntity(vertexId);
30844 if (vertexIds.indexOf(vertexId) !== -1) {
30845 vertexIds.splice(vertexIds.indexOf(vertexId), 1);
30847 removeVertexIds.push(vertexId);
30850 parents = vgraph.parentWays(vertex);
30851 if (parents.length < 3) {
30852 if (vertexIds.indexOf(vertexId) !== -1) {
30853 vertexIds.splice(vertexIds.indexOf(vertexId), 1);
30856 if (parents.length === 2) {
30857 var a = parents[0];
30858 var b = parents[1];
30859 var aIsLeaf = a && !a.__via;
30860 var bIsLeaf = b && !b.__via;
30861 var leaf, survivor;
30862 if (aIsLeaf && !bIsLeaf) {
30865 } else if (!aIsLeaf && bIsLeaf) {
30869 if (leaf && survivor) {
30870 survivor = withMetadata(survivor, vertexIds);
30871 vgraph = vgraph.replace(survivor).remove(leaf);
30872 removeWayIds.push(leaf.id);
30876 parents = vgraph.parentWays(vertex);
30877 if (parents.length < 2) {
30878 if (vertexIds.indexOf(vertexId) !== -1) {
30879 vertexIds.splice(vertexIds.indexOf(vertexId), 1);
30881 removeVertexIds.push(vertexId);
30884 if (parents.length < 1) {
30885 vgraph = vgraph.remove(vertex);
30888 } while (keepGoing);
30889 vertices = vertices.filter(function(vertex2) {
30890 return removeVertexIds.indexOf(vertex2.id) === -1;
30891 }).map(function(vertex2) {
30892 return vgraph.entity(vertex2.id);
30894 ways = ways.filter(function(way2) {
30895 return removeWayIds.indexOf(way2.id) === -1;
30896 }).map(function(way2) {
30897 return vgraph.entity(way2.id);
30899 var intersection = {
30905 intersection.turns = function(fromWayId, maxViaWay) {
30910 var vgraph2 = intersection.graph;
30911 var keyVertexIds = intersection.vertices.map(function(v) {
30914 var start2 = vgraph2.entity(fromWayId);
30915 if (!start2 || !(start2.__from || start2.__via))
30917 var maxPathLength = maxViaWay * 2 + 3;
30921 function step(entity, currPath, currRestrictions, matchedRestriction) {
30922 currPath = (currPath || []).slice();
30923 if (currPath.length >= maxPathLength)
30925 currPath.push(entity.id);
30926 currRestrictions = (currRestrictions || []).slice();
30927 if (entity.type === "node") {
30928 stepNode(entity, currPath, currRestrictions);
30930 stepWay(entity, currPath, currRestrictions, matchedRestriction);
30933 function stepNode(entity, currPath, currRestrictions) {
30935 var parents2 = vgraph2.parentWays(entity);
30937 for (i3 = 0; i3 < parents2.length; i3++) {
30938 var way2 = parents2[i3];
30939 if (way2.__oneWay && way2.nodes[0] !== entity.id)
30941 if (currPath.indexOf(way2.id) !== -1 && currPath.length >= 3)
30943 var restrict = null;
30944 for (j3 = 0; j3 < currRestrictions.length; j3++) {
30945 var restriction = currRestrictions[j3];
30946 var f2 = restriction.memberByRole("from");
30947 var v = restriction.membersByRole("via");
30948 var t = restriction.memberByRole("to");
30949 var isNo = /^no_/.test(restriction.tags.restriction);
30950 var isOnly = /^only_/.test(restriction.tags.restriction);
30951 if (!(isNo || isOnly)) {
30954 var matchesFrom = f2.id === fromWayId;
30955 var matchesViaTo = false;
30956 var isAlongOnlyPath = false;
30957 if (t.id === way2.id) {
30958 if (v.length === 1 && v[0].type === "node") {
30959 matchesViaTo = v[0].id === entity.id && (matchesFrom && currPath.length === 2 || !matchesFrom && currPath.length > 2);
30962 for (k = 2; k < currPath.length; k += 2) {
30963 pathVias.push(currPath[k]);
30965 var restrictionVias = [];
30966 for (k = 0; k < v.length; k++) {
30967 if (v[k].type === "way") {
30968 restrictionVias.push(v[k].id);
30971 var diff = utilArrayDifference(pathVias, restrictionVias);
30972 matchesViaTo = !diff.length;
30974 } else if (isOnly) {
30975 for (k = 0; k < v.length; k++) {
30976 if (v[k].type === "way" && v[k].id === way2.id) {
30977 isAlongOnlyPath = true;
30982 if (matchesViaTo) {
30984 restrict = { id: restriction.id, direct: matchesFrom, from: f2.id, only: true, end: true };
30986 restrict = { id: restriction.id, direct: matchesFrom, from: f2.id, no: true, end: true };
30989 if (isAlongOnlyPath) {
30990 restrict = { id: restriction.id, direct: false, from: f2.id, only: true, end: false };
30991 } else if (isOnly) {
30992 restrict = { id: restriction.id, direct: false, from: f2.id, no: true, end: true };
30995 if (restrict && restrict.direct)
30998 nextWays.push({ way: way2, restrict });
31000 nextWays.forEach(function(nextWay) {
31001 step(nextWay.way, currPath, currRestrictions, nextWay.restrict);
31004 function stepWay(entity, currPath, currRestrictions, matchedRestriction) {
31006 if (currPath.length >= 3) {
31007 var turnPath = currPath.slice();
31008 if (matchedRestriction && matchedRestriction.direct === false) {
31009 for (i3 = 0; i3 < turnPath.length; i3++) {
31010 if (turnPath[i3] === matchedRestriction.from) {
31011 turnPath = turnPath.slice(i3);
31016 var turn = pathToTurn(turnPath);
31018 if (matchedRestriction) {
31019 turn.restrictionID = matchedRestriction.id;
31020 turn.no = matchedRestriction.no;
31021 turn.only = matchedRestriction.only;
31022 turn.direct = matchedRestriction.direct;
31024 turns.push(osmTurn(turn));
31026 if (currPath[0] === currPath[2])
31029 if (matchedRestriction && matchedRestriction.end)
31031 var n1 = vgraph2.entity(entity.first());
31032 var n2 = vgraph2.entity(entity.last());
31033 var dist = geoSphericalDistance(n1.loc, n2.loc);
31034 var nextNodes = [];
31035 if (currPath.length > 1) {
31036 if (dist > maxDistance)
31041 if (!entity.__oneWay && // bidirectional..
31042 keyVertexIds.indexOf(n1.id) !== -1 && // key vertex..
31043 currPath.indexOf(n1.id) === -1) {
31044 nextNodes.push(n1);
31046 if (keyVertexIds.indexOf(n2.id) !== -1 && // key vertex..
31047 currPath.indexOf(n2.id) === -1) {
31048 nextNodes.push(n2);
31050 nextNodes.forEach(function(nextNode) {
31051 var fromRestrictions = vgraph2.parentRelations(entity).filter(function(r) {
31052 if (!r.isRestriction())
31054 var f2 = r.memberByRole("from");
31055 if (!f2 || f2.id !== entity.id)
31057 var isOnly = /^only_/.test(r.tags.restriction);
31060 var isOnlyVia = false;
31061 var v = r.membersByRole("via");
31062 if (v.length === 1 && v[0].type === "node") {
31063 isOnlyVia = v[0].id === nextNode.id;
31065 for (var i4 = 0; i4 < v.length; i4++) {
31066 if (v[i4].type !== "way")
31068 var viaWay = vgraph2.entity(v[i4].id);
31069 if (viaWay.first() === nextNode.id || viaWay.last() === nextNode.id) {
31077 step(nextNode, currPath, currRestrictions.concat(fromRestrictions), false);
31080 function pathToTurn(path) {
31081 if (path.length < 3)
31083 var fromWayId2, fromNodeId, fromVertexId;
31084 var toWayId, toNodeId, toVertexId;
31085 var viaWayIds, viaNodeId, isUturn;
31086 fromWayId2 = path[0];
31087 toWayId = path[path.length - 1];
31088 if (path.length === 3 && fromWayId2 === toWayId) {
31089 var way2 = vgraph2.entity(fromWayId2);
31093 viaNodeId = fromVertexId = toVertexId = path[1];
31094 fromNodeId = toNodeId = adjacentNode(fromWayId2, viaNodeId);
31097 fromVertexId = path[1];
31098 fromNodeId = adjacentNode(fromWayId2, fromVertexId);
31099 toVertexId = path[path.length - 2];
31100 toNodeId = adjacentNode(toWayId, toVertexId);
31101 if (path.length === 3) {
31102 viaNodeId = path[1];
31104 viaWayIds = path.filter(function(entityId) {
31105 return entityId[0] === "w";
31107 viaWayIds = viaWayIds.slice(1, viaWayIds.length - 1);
31111 key: path.join("_"),
31113 from: { node: fromNodeId, way: fromWayId2, vertex: fromVertexId },
31114 via: { node: viaNodeId, ways: viaWayIds },
31115 to: { node: toNodeId, way: toWayId, vertex: toVertexId },
31118 function adjacentNode(wayId, affixId) {
31119 var nodes2 = vgraph2.entity(wayId).nodes;
31120 return affixId === nodes2[0] ? nodes2[1] : nodes2[nodes2.length - 2];
31124 return intersection;
31126 function osmInferRestriction(graph, turn, projection2) {
31127 var fromWay = graph.entity(turn.from.way);
31128 var fromNode = graph.entity(turn.from.node);
31129 var fromVertex = graph.entity(turn.from.vertex);
31130 var toWay = graph.entity(turn.to.way);
31131 var toNode = graph.entity(turn.to.node);
31132 var toVertex = graph.entity(turn.to.vertex);
31133 var fromOneWay = fromWay.tags.oneway === "yes";
31134 var toOneWay = toWay.tags.oneway === "yes";
31135 var angle2 = (geoAngle(fromVertex, fromNode, projection2) - geoAngle(toVertex, toNode, projection2)) * 180 / Math.PI;
31136 while (angle2 < 0) {
31139 if (fromNode === toNode) {
31140 return "no_u_turn";
31142 if ((angle2 < 23 || angle2 > 336) && fromOneWay && toOneWay) {
31143 return "no_u_turn";
31145 if ((angle2 < 40 || angle2 > 319) && fromOneWay && toOneWay && turn.from.vertex !== turn.to.vertex) {
31146 return "no_u_turn";
31148 if (angle2 < 158) {
31149 return "no_right_turn";
31151 if (angle2 > 202) {
31152 return "no_left_turn";
31154 return "no_straight_on";
31157 // modules/actions/merge_polygon.js
31158 function actionMergePolygon(ids, newRelationId) {
31159 function groupEntities(graph) {
31160 var entities = ids.map(function(id2) {
31161 return graph.entity(id2);
31163 var geometryGroups = utilArrayGroupBy(entities, function(entity) {
31164 if (entity.type === "way" && entity.isClosed()) {
31165 return "closedWay";
31166 } else if (entity.type === "relation" && entity.isMultipolygon()) {
31167 return "multipolygon";
31172 return Object.assign(
31173 { closedWay: [], multipolygon: [], other: [] },
31177 var action = function(graph) {
31178 var entities = groupEntities(graph);
31179 var polygons = entities.multipolygon.reduce(function(polygons2, m) {
31180 return polygons2.concat(osmJoinWays(m.members, graph));
31181 }, []).concat(entities.closedWay.map(function(d) {
31182 var member = [{ id: d.id }];
31183 member.nodes = graph.childNodes(d);
31186 var contained = polygons.map(function(w, i2) {
31187 return polygons.map(function(d, n2) {
31190 return geoPolygonContainsPolygon(
31191 d.nodes.map(function(n3) {
31194 w.nodes.map(function(n3) {
31202 while (polygons.length) {
31203 extractUncontained(polygons);
31204 polygons = polygons.filter(isContained);
31205 contained = contained.filter(isContained).map(filterContained);
31207 function isContained(d, i2) {
31208 return contained[i2].some(function(val) {
31212 function filterContained(d) {
31213 return d.filter(isContained);
31215 function extractUncontained(polygons2) {
31216 polygons2.forEach(function(d, i2) {
31217 if (!isContained(d, i2)) {
31218 d.forEach(function(member) {
31222 role: outer ? "outer" : "inner"
31230 if (entities.multipolygon.length > 0) {
31231 var oldestID = utilOldestID(entities.multipolygon.map((entity) => entity.id));
31232 relation = entities.multipolygon.find((entity) => entity.id === oldestID);
31234 relation = osmRelation({ id: newRelationId, tags: { type: "multipolygon" } });
31236 entities.multipolygon.forEach(function(m) {
31237 if (m.id !== relation.id) {
31238 relation = relation.mergeTags(m.tags);
31239 graph = graph.remove(m);
31242 entities.closedWay.forEach(function(way) {
31243 function isThisOuter(m) {
31244 return m.id === way.id && m.role !== "inner";
31246 if (members.some(isThisOuter)) {
31247 relation = relation.mergeTags(way.tags);
31248 graph = graph.replace(way.update({ tags: {} }));
31251 return graph.replace(relation.update({
31253 tags: utilObjectOmit(relation.tags, ["area"])
31256 action.disabled = function(graph) {
31257 var entities = groupEntities(graph);
31258 if (entities.other.length > 0 || entities.closedWay.length + entities.multipolygon.length < 2) {
31259 return "not_eligible";
31261 if (!entities.multipolygon.every(function(r) {
31262 return r.isComplete(graph);
31264 return "incomplete_relation";
31266 if (!entities.multipolygon.length) {
31267 var sharedMultipolygons = [];
31268 entities.closedWay.forEach(function(way, i2) {
31270 sharedMultipolygons = graph.parentMultipolygons(way);
31272 sharedMultipolygons = utilArrayIntersection(sharedMultipolygons, graph.parentMultipolygons(way));
31275 sharedMultipolygons = sharedMultipolygons.filter(function(relation) {
31276 return relation.members.length === entities.closedWay.length;
31278 if (sharedMultipolygons.length) {
31279 return "not_eligible";
31281 } else if (entities.closedWay.some(function(way) {
31282 return utilArrayIntersection(graph.parentMultipolygons(way), entities.multipolygon).length;
31284 return "not_eligible";
31290 // modules/actions/merge_remote_changes.js
31291 var import_fast_deep_equal = __toESM(require_fast_deep_equal());
31293 // node_modules/node-diff3/index.mjs
31294 function LCS(buffer1, buffer2) {
31295 let equivalenceClasses = {};
31296 for (let j2 = 0; j2 < buffer2.length; j2++) {
31297 const item = buffer2[j2];
31298 if (equivalenceClasses[item]) {
31299 equivalenceClasses[item].push(j2);
31301 equivalenceClasses[item] = [j2];
31304 const NULLRESULT = { buffer1index: -1, buffer2index: -1, chain: null };
31305 let candidates = [NULLRESULT];
31306 for (let i2 = 0; i2 < buffer1.length; i2++) {
31307 const item = buffer1[i2];
31308 const buffer2indices = equivalenceClasses[item] || [];
31310 let c = candidates[0];
31311 for (let jx = 0; jx < buffer2indices.length; jx++) {
31312 const j2 = buffer2indices[jx];
31314 for (s = r; s < candidates.length; s++) {
31315 if (candidates[s].buffer2index < j2 && (s === candidates.length - 1 || candidates[s + 1].buffer2index > j2)) {
31319 if (s < candidates.length) {
31320 const newCandidate = { buffer1index: i2, buffer2index: j2, chain: candidates[s] };
31321 if (r === candidates.length) {
31322 candidates.push(c);
31328 if (r === candidates.length) {
31335 return candidates[candidates.length - 1];
31337 function diffIndices(buffer1, buffer2) {
31338 const lcs = LCS(buffer1, buffer2);
31340 let tail1 = buffer1.length;
31341 let tail2 = buffer2.length;
31342 for (let candidate = lcs; candidate !== null; candidate = candidate.chain) {
31343 const mismatchLength1 = tail1 - candidate.buffer1index - 1;
31344 const mismatchLength2 = tail2 - candidate.buffer2index - 1;
31345 tail1 = candidate.buffer1index;
31346 tail2 = candidate.buffer2index;
31347 if (mismatchLength1 || mismatchLength2) {
31349 buffer1: [tail1 + 1, mismatchLength1],
31350 buffer1Content: buffer1.slice(tail1 + 1, tail1 + 1 + mismatchLength1),
31351 buffer2: [tail2 + 1, mismatchLength2],
31352 buffer2Content: buffer2.slice(tail2 + 1, tail2 + 1 + mismatchLength2)
31359 function diff3MergeRegions(a, o, b) {
31361 function addHunk(h, ab) {
31364 oStart: h.buffer1[0],
31365 oLength: h.buffer1[1],
31366 // length of o to remove
31367 abStart: h.buffer2[0],
31368 abLength: h.buffer2[1]
31369 // length of a/b to insert
31370 // abContent: (ab === 'a' ? a : b).slice(h.buffer2[0], h.buffer2[0] + h.buffer2[1])
31373 diffIndices(o, a).forEach((item) => addHunk(item, "a"));
31374 diffIndices(o, b).forEach((item) => addHunk(item, "b"));
31375 hunks.sort((x, y) => x.oStart - y.oStart);
31377 let currOffset = 0;
31378 function advanceTo(endOffset) {
31379 if (endOffset > currOffset) {
31383 bufferStart: currOffset,
31384 bufferLength: endOffset - currOffset,
31385 bufferContent: o.slice(currOffset, endOffset)
31387 currOffset = endOffset;
31390 while (hunks.length) {
31391 let hunk = hunks.shift();
31392 let regionStart = hunk.oStart;
31393 let regionEnd = hunk.oStart + hunk.oLength;
31394 let regionHunks = [hunk];
31395 advanceTo(regionStart);
31396 while (hunks.length) {
31397 const nextHunk = hunks[0];
31398 const nextHunkStart = nextHunk.oStart;
31399 if (nextHunkStart > regionEnd)
31401 regionEnd = Math.max(regionEnd, nextHunkStart + nextHunk.oLength);
31402 regionHunks.push(hunks.shift());
31404 if (regionHunks.length === 1) {
31405 if (hunk.abLength > 0) {
31406 const buffer = hunk.ab === "a" ? a : b;
31410 bufferStart: hunk.abStart,
31411 bufferLength: hunk.abLength,
31412 bufferContent: buffer.slice(hunk.abStart, hunk.abStart + hunk.abLength)
31417 a: [a.length, -1, o.length, -1],
31418 b: [b.length, -1, o.length, -1]
31420 while (regionHunks.length) {
31421 hunk = regionHunks.shift();
31422 const oStart = hunk.oStart;
31423 const oEnd = oStart + hunk.oLength;
31424 const abStart = hunk.abStart;
31425 const abEnd = abStart + hunk.abLength;
31426 let b2 = bounds[hunk.ab];
31427 b2[0] = Math.min(abStart, b2[0]);
31428 b2[1] = Math.max(abEnd, b2[1]);
31429 b2[2] = Math.min(oStart, b2[2]);
31430 b2[3] = Math.max(oEnd, b2[3]);
31432 const aStart = bounds.a[0] + (regionStart - bounds.a[2]);
31433 const aEnd = bounds.a[1] + (regionEnd - bounds.a[3]);
31434 const bStart = bounds.b[0] + (regionStart - bounds.b[2]);
31435 const bEnd = bounds.b[1] + (regionEnd - bounds.b[3]);
31439 aLength: aEnd - aStart,
31440 aContent: a.slice(aStart, aEnd),
31441 oStart: regionStart,
31442 oLength: regionEnd - regionStart,
31443 oContent: o.slice(regionStart, regionEnd),
31445 bLength: bEnd - bStart,
31446 bContent: b.slice(bStart, bEnd)
31448 results.push(result);
31450 currOffset = regionEnd;
31452 advanceTo(o.length);
31455 function diff3Merge(a, o, b, options2) {
31457 excludeFalseConflicts: true,
31458 stringSeparator: /\s+/
31460 options2 = Object.assign(defaults2, options2);
31461 if (typeof a === "string")
31462 a = a.split(options2.stringSeparator);
31463 if (typeof o === "string")
31464 o = o.split(options2.stringSeparator);
31465 if (typeof b === "string")
31466 b = b.split(options2.stringSeparator);
31468 const regions = diff3MergeRegions(a, o, b);
31470 function flushOk() {
31471 if (okBuffer.length) {
31472 results.push({ ok: okBuffer });
31476 function isFalseConflict(a2, b2) {
31477 if (a2.length !== b2.length)
31479 for (let i2 = 0; i2 < a2.length; i2++) {
31480 if (a2[i2] !== b2[i2])
31485 regions.forEach((region) => {
31486 if (region.stable) {
31487 okBuffer.push(...region.bufferContent);
31489 if (options2.excludeFalseConflicts && isFalseConflict(region.aContent, region.bContent)) {
31490 okBuffer.push(...region.aContent);
31495 a: region.aContent,
31496 aIndex: region.aStart,
31497 o: region.oContent,
31498 oIndex: region.oStart,
31499 b: region.bContent,
31500 bIndex: region.bStart
31510 // modules/actions/merge_remote_changes.js
31511 var import_lodash = __toESM(require_lodash());
31512 function actionMergeRemoteChanges(id2, localGraph, remoteGraph, discardTags, formatUser) {
31513 discardTags = discardTags || {};
31514 var _option = "safe";
31515 var _conflicts = [];
31517 return typeof formatUser === "function" ? formatUser(d) : (0, import_lodash.escape)(d);
31519 function mergeLocation(remote, target) {
31520 function pointEqual(a, b) {
31521 var epsilon3 = 1e-6;
31522 return Math.abs(a[0] - b[0]) < epsilon3 && Math.abs(a[1] - b[1]) < epsilon3;
31524 if (_option === "force_local" || pointEqual(target.loc, remote.loc)) {
31527 if (_option === "force_remote") {
31528 return target.update({ loc: remote.loc });
31530 _conflicts.push(_t.html("merge_remote_changes.conflict.location", { user: { html: user(remote.user) } }));
31533 function mergeNodes(base, remote, target) {
31534 if (_option === "force_local" || (0, import_fast_deep_equal.default)(target.nodes, remote.nodes)) {
31537 if (_option === "force_remote") {
31538 return target.update({ nodes: remote.nodes });
31540 var ccount = _conflicts.length;
31541 var o = base.nodes || [];
31542 var a = target.nodes || [];
31543 var b = remote.nodes || [];
31545 var hunks = diff3Merge(a, o, b, { excludeFalseConflicts: true });
31546 for (var i2 = 0; i2 < hunks.length; i2++) {
31547 var hunk = hunks[i2];
31549 nodes.push.apply(nodes, hunk.ok);
31551 var c = hunk.conflict;
31552 if ((0, import_fast_deep_equal.default)(c.o, c.a)) {
31553 nodes.push.apply(nodes, c.b);
31554 } else if ((0, import_fast_deep_equal.default)(c.o, c.b)) {
31555 nodes.push.apply(nodes, c.a);
31557 _conflicts.push(_t.html("merge_remote_changes.conflict.nodelist", { user: { html: user(remote.user) } }));
31562 return _conflicts.length === ccount ? target.update({ nodes }) : target;
31564 function mergeChildren(targetWay, children2, updates, graph) {
31565 function isUsed(node2, targetWay2) {
31566 var hasInterestingParent = graph.parentWays(node2).some(function(way) {
31567 return way.id !== targetWay2.id;
31569 return node2.hasInterestingTags() || hasInterestingParent || graph.parentRelations(node2).length > 0;
31571 var ccount = _conflicts.length;
31572 for (var i2 = 0; i2 < children2.length; i2++) {
31573 var id3 = children2[i2];
31574 var node = graph.hasEntity(id3);
31575 if (targetWay.nodes.indexOf(id3) === -1) {
31576 if (node && !isUsed(node, targetWay)) {
31577 updates.removeIds.push(id3);
31581 var local = localGraph.hasEntity(id3);
31582 var remote = remoteGraph.hasEntity(id3);
31584 if (_option === "force_remote" && remote && remote.visible) {
31585 updates.replacements.push(remote);
31586 } else if (_option === "force_local" && local) {
31587 target = osmEntity(local);
31589 target = target.update({ version: remote.version });
31591 updates.replacements.push(target);
31592 } else if (_option === "safe" && local && remote && local.version !== remote.version) {
31593 target = osmEntity(local, { version: remote.version });
31594 if (remote.visible) {
31595 target = mergeLocation(remote, target);
31597 _conflicts.push(_t.html("merge_remote_changes.conflict.deleted", { user: { html: user(remote.user) } }));
31599 if (_conflicts.length !== ccount)
31601 updates.replacements.push(target);
31606 function updateChildren(updates, graph) {
31607 for (var i2 = 0; i2 < updates.replacements.length; i2++) {
31608 graph = graph.replace(updates.replacements[i2]);
31610 if (updates.removeIds.length) {
31611 graph = actionDeleteMultiple(updates.removeIds)(graph);
31615 function mergeMembers(remote, target) {
31616 if (_option === "force_local" || (0, import_fast_deep_equal.default)(target.members, remote.members)) {
31619 if (_option === "force_remote") {
31620 return target.update({ members: remote.members });
31622 _conflicts.push(_t.html("merge_remote_changes.conflict.memberlist", { user: { html: user(remote.user) } }));
31625 function mergeTags(base, remote, target) {
31626 if (_option === "force_local" || (0, import_fast_deep_equal.default)(target.tags, remote.tags)) {
31629 if (_option === "force_remote") {
31630 return target.update({ tags: remote.tags });
31632 var ccount = _conflicts.length;
31633 var o = base.tags || {};
31634 var a = target.tags || {};
31635 var b = remote.tags || {};
31636 var keys = utilArrayUnion(utilArrayUnion(Object.keys(o), Object.keys(a)), Object.keys(b)).filter(function(k2) {
31637 return !discardTags[k2];
31639 var tags = Object.assign({}, a);
31640 var changed = false;
31641 for (var i2 = 0; i2 < keys.length; i2++) {
31643 if (o[k] !== b[k] && a[k] !== b[k]) {
31644 if (o[k] !== a[k]) {
31645 _conflicts.push(_t.html(
31646 "merge_remote_changes.conflict.tags",
31647 { tag: k, local: a[k], remote: b[k], user: { html: user(remote.user) } }
31650 if (b.hasOwnProperty(k)) {
31659 return changed && _conflicts.length === ccount ? target.update({ tags }) : target;
31661 var action = function(graph) {
31662 var updates = { replacements: [], removeIds: [] };
31663 var base = graph.base().entities[id2];
31664 var local = localGraph.entity(id2);
31665 var remote = remoteGraph.entity(id2);
31666 var target = osmEntity(local, { version: remote.version });
31667 if (!remote.visible) {
31668 if (_option === "force_remote") {
31669 return actionDeleteMultiple([id2])(graph);
31670 } else if (_option === "force_local") {
31671 if (target.type === "way") {
31672 target = mergeChildren(target, utilArrayUniq(local.nodes), updates, graph);
31673 graph = updateChildren(updates, graph);
31675 return graph.replace(target);
31677 _conflicts.push(_t.html("merge_remote_changes.conflict.deleted", { user: { html: user(remote.user) } }));
31681 if (target.type === "node") {
31682 target = mergeLocation(remote, target);
31683 } else if (target.type === "way") {
31684 graph.rebase(remoteGraph.childNodes(remote), [graph], false);
31685 target = mergeNodes(base, remote, target);
31686 target = mergeChildren(target, utilArrayUnion(local.nodes, remote.nodes), updates, graph);
31687 } else if (target.type === "relation") {
31688 target = mergeMembers(remote, target);
31690 target = mergeTags(base, remote, target);
31691 if (!_conflicts.length) {
31692 graph = updateChildren(updates, graph).replace(target);
31696 action.withOption = function(opt) {
31700 action.conflicts = function() {
31706 // modules/actions/move.js
31707 function actionMove(moveIDs, tryDelta, projection2, cache) {
31708 var _delta = tryDelta;
31709 function setupCache(graph) {
31710 function canMove(nodeID) {
31711 if (moveIDs.indexOf(nodeID) !== -1)
31713 var parents = graph.parentWays(graph.entity(nodeID));
31714 if (parents.length < 3)
31716 var parentsMoving = parents.every(function(way) {
31717 return cache.moving[way.id];
31719 if (!parentsMoving)
31720 delete cache.moving[nodeID];
31721 return parentsMoving;
31723 function cacheEntities(ids) {
31724 for (var i2 = 0; i2 < ids.length; i2++) {
31726 if (cache.moving[id2])
31728 cache.moving[id2] = true;
31729 var entity = graph.hasEntity(id2);
31732 if (entity.type === "node") {
31733 cache.nodes.push(id2);
31734 cache.startLoc[id2] = entity.loc;
31735 } else if (entity.type === "way") {
31736 cache.ways.push(id2);
31737 cacheEntities(entity.nodes);
31739 cacheEntities(entity.members.map(function(member) {
31745 function cacheIntersections(ids) {
31746 function isEndpoint(way2, id3) {
31747 return !way2.isClosed() && !!way2.affix(id3);
31749 for (var i2 = 0; i2 < ids.length; i2++) {
31751 var childNodes = graph.childNodes(graph.entity(id2));
31752 for (var j2 = 0; j2 < childNodes.length; j2++) {
31753 var node = childNodes[j2];
31754 var parents = graph.parentWays(node);
31755 if (parents.length !== 2)
31757 var moved = graph.entity(id2);
31758 var unmoved = null;
31759 for (var k = 0; k < parents.length; k++) {
31760 var way = parents[k];
31761 if (!cache.moving[way.id]) {
31768 if (utilArrayIntersection(moved.nodes, unmoved.nodes).length > 2)
31770 if (moved.isArea() || unmoved.isArea())
31772 cache.intersections.push({
31775 unmovedId: unmoved.id,
31776 movedIsEP: isEndpoint(moved, node.id),
31777 unmovedIsEP: isEndpoint(unmoved, node.id)
31787 cache.intersections = [];
31788 cache.replacedVertex = {};
31789 cache.startLoc = {};
31792 cacheEntities(moveIDs);
31793 cacheIntersections(cache.ways);
31794 cache.nodes = cache.nodes.filter(canMove);
31798 function replaceMovedVertex(nodeId, wayId, graph, delta) {
31799 var way = graph.entity(wayId);
31800 var moved = graph.entity(nodeId);
31801 var movedIndex = way.nodes.indexOf(nodeId);
31802 var len, prevIndex, nextIndex;
31803 if (way.isClosed()) {
31804 len = way.nodes.length - 1;
31805 prevIndex = (movedIndex + len - 1) % len;
31806 nextIndex = (movedIndex + len + 1) % len;
31808 len = way.nodes.length;
31809 prevIndex = movedIndex - 1;
31810 nextIndex = movedIndex + 1;
31812 var prev = graph.hasEntity(way.nodes[prevIndex]);
31813 var next = graph.hasEntity(way.nodes[nextIndex]);
31814 if (!prev || !next)
31816 var key = wayId + "_" + nodeId;
31817 var orig = cache.replacedVertex[key];
31820 cache.replacedVertex[key] = orig;
31821 cache.startLoc[orig.id] = cache.startLoc[nodeId];
31825 start2 = projection2(cache.startLoc[nodeId]);
31826 end = projection2.invert(geoVecAdd(start2, delta));
31828 end = cache.startLoc[nodeId];
31830 orig = orig.move(end);
31831 var angle2 = Math.abs(geoAngle(orig, prev, projection2) - geoAngle(orig, next, projection2)) * 180 / Math.PI;
31832 if (angle2 > 175 && angle2 < 185)
31834 var p1 = [prev.loc, orig.loc, moved.loc, next.loc].map(projection2);
31835 var p2 = [prev.loc, moved.loc, orig.loc, next.loc].map(projection2);
31836 var d1 = geoPathLength(p1);
31837 var d2 = geoPathLength(p2);
31838 var insertAt = d1 <= d2 ? movedIndex : nextIndex;
31839 if (way.isClosed() && insertAt === 0)
31841 way = way.addNode(orig.id, insertAt);
31842 return graph.replace(orig).replace(way);
31844 function removeDuplicateVertices(wayId, graph) {
31845 var way = graph.entity(wayId);
31846 var epsilon3 = 1e-6;
31848 function isInteresting(node, graph2) {
31849 return graph2.parentWays(node).length > 1 || graph2.parentRelations(node).length || node.hasInterestingTags();
31851 for (var i2 = 0; i2 < way.nodes.length; i2++) {
31852 curr = graph.entity(way.nodes[i2]);
31853 if (prev && curr && geoVecEqual(prev.loc, curr.loc, epsilon3)) {
31854 if (!isInteresting(prev, graph)) {
31855 way = way.removeNode(prev.id);
31856 graph = graph.replace(way).remove(prev);
31857 } else if (!isInteresting(curr, graph)) {
31858 way = way.removeNode(curr.id);
31859 graph = graph.replace(way).remove(curr);
31866 function unZorroIntersection(intersection, graph) {
31867 var vertex = graph.entity(intersection.nodeId);
31868 var way1 = graph.entity(intersection.movedId);
31869 var way2 = graph.entity(intersection.unmovedId);
31870 var isEP1 = intersection.movedIsEP;
31871 var isEP2 = intersection.unmovedIsEP;
31872 if (isEP1 && isEP2)
31874 var nodes1 = graph.childNodes(way1).filter(function(n2) {
31875 return n2 !== vertex;
31877 var nodes2 = graph.childNodes(way2).filter(function(n2) {
31878 return n2 !== vertex;
31880 if (way1.isClosed() && way1.first() === vertex.id)
31881 nodes1.push(nodes1[0]);
31882 if (way2.isClosed() && way2.first() === vertex.id)
31883 nodes2.push(nodes2[0]);
31884 var edge1 = !isEP1 && geoChooseEdge(nodes1, projection2(vertex.loc), projection2);
31885 var edge2 = !isEP2 && geoChooseEdge(nodes2, projection2(vertex.loc), projection2);
31887 if (!isEP1 && !isEP2) {
31888 var epsilon3 = 1e-6, maxIter = 10;
31889 for (var i2 = 0; i2 < maxIter; i2++) {
31890 loc = geoVecInterp(edge1.loc, edge2.loc, 0.5);
31891 edge1 = geoChooseEdge(nodes1, projection2(loc), projection2);
31892 edge2 = geoChooseEdge(nodes2, projection2(loc), projection2);
31893 if (Math.abs(edge1.distance - edge2.distance) < epsilon3)
31896 } else if (!isEP1) {
31901 graph = graph.replace(vertex.move(loc));
31902 if (!isEP1 && edge1.index !== way1.nodes.indexOf(vertex.id)) {
31903 way1 = way1.removeNode(vertex.id).addNode(vertex.id, edge1.index);
31904 graph = graph.replace(way1);
31906 if (!isEP2 && edge2.index !== way2.nodes.indexOf(vertex.id)) {
31907 way2 = way2.removeNode(vertex.id).addNode(vertex.id, edge2.index);
31908 graph = graph.replace(way2);
31912 function cleanupIntersections(graph) {
31913 for (var i2 = 0; i2 < cache.intersections.length; i2++) {
31914 var obj = cache.intersections[i2];
31915 graph = replaceMovedVertex(obj.nodeId, obj.movedId, graph, _delta);
31916 graph = replaceMovedVertex(obj.nodeId, obj.unmovedId, graph, null);
31917 graph = unZorroIntersection(obj, graph);
31918 graph = removeDuplicateVertices(obj.movedId, graph);
31919 graph = removeDuplicateVertices(obj.unmovedId, graph);
31923 function limitDelta(graph) {
31924 function moveNode(loc) {
31925 return geoVecAdd(projection2(loc), _delta);
31927 for (var i2 = 0; i2 < cache.intersections.length; i2++) {
31928 var obj = cache.intersections[i2];
31929 if (obj.movedIsEP && obj.unmovedIsEP)
31931 if (!obj.movedIsEP)
31933 var node = graph.entity(obj.nodeId);
31934 var start2 = projection2(node.loc);
31935 var end = geoVecAdd(start2, _delta);
31936 var movedNodes = graph.childNodes(graph.entity(obj.movedId));
31937 var movedPath = movedNodes.map(function(n2) {
31938 return moveNode(n2.loc);
31940 var unmovedNodes = graph.childNodes(graph.entity(obj.unmovedId));
31941 var unmovedPath = unmovedNodes.map(function(n2) {
31942 return projection2(n2.loc);
31944 var hits = geoPathIntersections(movedPath, unmovedPath);
31945 for (var j2 = 0; i2 < hits.length; i2++) {
31946 if (geoVecEqual(hits[j2], end))
31948 var edge = geoChooseEdge(unmovedNodes, end, projection2);
31949 _delta = geoVecSubtract(projection2(edge.loc), start2);
31953 var action = function(graph) {
31954 if (_delta[0] === 0 && _delta[1] === 0)
31957 if (cache.intersections.length) {
31960 for (var i2 = 0; i2 < cache.nodes.length; i2++) {
31961 var node = graph.entity(cache.nodes[i2]);
31962 var start2 = projection2(node.loc);
31963 var end = geoVecAdd(start2, _delta);
31964 graph = graph.replace(node.move(projection2.invert(end)));
31966 if (cache.intersections.length) {
31967 graph = cleanupIntersections(graph);
31971 action.delta = function() {
31977 // modules/actions/move_member.js
31978 function actionMoveMember(relationId, fromIndex, toIndex) {
31979 return function(graph) {
31980 return graph.replace(graph.entity(relationId).moveMember(fromIndex, toIndex));
31984 // modules/actions/move_node.js
31985 function actionMoveNode(nodeID, toLoc) {
31986 var action = function(graph, t) {
31987 if (t === null || !isFinite(t))
31989 t = Math.min(Math.max(+t, 0), 1);
31990 var node = graph.entity(nodeID);
31991 return graph.replace(
31992 node.move(geoVecInterp(node.loc, toLoc, t))
31995 action.transitionable = true;
31999 // modules/actions/noop.js
32000 function actionNoop() {
32001 return function(graph) {
32006 // modules/actions/orthogonalize.js
32007 function actionOrthogonalize(wayID, projection2, vertexID, degThresh, ep) {
32008 var epsilon3 = ep || 1e-4;
32009 var threshold = degThresh || 13;
32010 var lowerThreshold = Math.cos((90 - threshold) * Math.PI / 180);
32011 var upperThreshold = Math.cos(threshold * Math.PI / 180);
32012 var action = function(graph, t) {
32013 if (t === null || !isFinite(t))
32015 t = Math.min(Math.max(+t, 0), 1);
32016 var way = graph.entity(wayID);
32017 way = way.removeNode("");
32018 if (way.tags.nonsquare) {
32019 var tags = Object.assign({}, way.tags);
32020 delete tags.nonsquare;
32021 way = way.update({ tags });
32023 graph = graph.replace(way);
32024 var isClosed = way.isClosed();
32025 var nodes = graph.childNodes(way).slice();
32028 if (vertexID !== void 0) {
32029 nodes = nodeSubset(nodes, vertexID, isClosed);
32030 if (nodes.length !== 3)
32033 var nodeCount = {};
32035 var corner = { i: 0, dotp: 1 };
32036 var node, point2, loc, score, motions, i2, j2;
32037 for (i2 = 0; i2 < nodes.length; i2++) {
32039 nodeCount[node.id] = (nodeCount[node.id] || 0) + 1;
32040 points.push({ id: node.id, coord: projection2(node.loc) });
32042 if (points.length === 3) {
32043 for (i2 = 0; i2 < 1e3; i2++) {
32044 motions = points.map(calcMotion);
32045 points[corner.i].coord = geoVecAdd(points[corner.i].coord, motions[corner.i]);
32046 score = corner.dotp;
32047 if (score < epsilon3) {
32051 node = graph.entity(nodes[corner.i].id);
32052 loc = projection2.invert(points[corner.i].coord);
32053 graph = graph.replace(node.move(geoVecInterp(node.loc, loc, t)));
32055 var straights = [];
32056 var simplified = [];
32057 for (i2 = 0; i2 < points.length; i2++) {
32058 point2 = points[i2];
32060 if (isClosed || i2 > 0 && i2 < points.length - 1) {
32061 var a = points[(i2 - 1 + points.length) % points.length];
32062 var b = points[(i2 + 1) % points.length];
32063 dotp = Math.abs(geoOrthoNormalizedDotProduct(a.coord, b.coord, point2.coord));
32065 if (dotp > upperThreshold) {
32066 straights.push(point2);
32068 simplified.push(point2);
32071 var bestPoints = clonePoints(simplified);
32072 var originalPoints = clonePoints(simplified);
32074 for (i2 = 0; i2 < 1e3; i2++) {
32075 motions = simplified.map(calcMotion);
32076 for (j2 = 0; j2 < motions.length; j2++) {
32077 simplified[j2].coord = geoVecAdd(simplified[j2].coord, motions[j2]);
32079 var newScore = geoOrthoCalcScore(simplified, isClosed, epsilon3, threshold);
32080 if (newScore < score) {
32081 bestPoints = clonePoints(simplified);
32084 if (score < epsilon3) {
32088 var bestCoords = bestPoints.map(function(p) {
32092 bestCoords.push(bestCoords[0]);
32093 for (i2 = 0; i2 < bestPoints.length; i2++) {
32094 point2 = bestPoints[i2];
32095 if (!geoVecEqual(originalPoints[i2].coord, point2.coord)) {
32096 node = graph.entity(point2.id);
32097 loc = projection2.invert(point2.coord);
32098 graph = graph.replace(node.move(geoVecInterp(node.loc, loc, t)));
32101 for (i2 = 0; i2 < straights.length; i2++) {
32102 point2 = straights[i2];
32103 if (nodeCount[point2.id] > 1)
32105 node = graph.entity(point2.id);
32106 if (t === 1 && graph.parentWays(node).length === 1 && graph.parentRelations(node).length === 0 && !node.hasInterestingTags()) {
32107 graph = actionDeleteNode(node.id)(graph);
32109 var choice = geoVecProject(point2.coord, bestCoords);
32111 loc = projection2.invert(choice.target);
32112 graph = graph.replace(node.move(geoVecInterp(node.loc, loc, t)));
32118 function clonePoints(array2) {
32119 return array2.map(function(p) {
32120 return { id: p.id, coord: [p.coord[0], p.coord[1]] };
32123 function calcMotion(point3, i3, array2) {
32124 if (!isClosed && (i3 === 0 || i3 === array2.length - 1))
32126 if (nodeCount[array2[i3].id] > 1)
32128 var a2 = array2[(i3 - 1 + array2.length) % array2.length].coord;
32129 var origin = point3.coord;
32130 var b2 = array2[(i3 + 1) % array2.length].coord;
32131 var p = geoVecSubtract(a2, origin);
32132 var q = geoVecSubtract(b2, origin);
32133 var scale = 2 * Math.min(geoVecLength(p), geoVecLength(q));
32134 p = geoVecNormalize(p);
32135 q = geoVecNormalize(q);
32136 var dotp2 = p[0] * q[0] + p[1] * q[1];
32137 var val = Math.abs(dotp2);
32138 if (val < lowerThreshold) {
32141 var vec = geoVecNormalize(geoVecAdd(p, q));
32142 return geoVecScale(vec, 0.1 * dotp2 * scale);
32147 function nodeSubset(nodes, vertexID2, isClosed) {
32148 var first = isClosed ? 0 : 1;
32149 var last = isClosed ? nodes.length : nodes.length - 1;
32150 for (var i2 = first; i2 < last; i2++) {
32151 if (nodes[i2].id === vertexID2) {
32153 nodes[(i2 - 1 + nodes.length) % nodes.length],
32155 nodes[(i2 + 1) % nodes.length]
32161 action.disabled = function(graph) {
32162 var way = graph.entity(wayID);
32163 way = way.removeNode("");
32164 graph = graph.replace(way);
32165 var isClosed = way.isClosed();
32166 var nodes = graph.childNodes(way).slice();
32169 var allowStraightAngles = false;
32170 if (vertexID !== void 0) {
32171 allowStraightAngles = true;
32172 nodes = nodeSubset(nodes, vertexID, isClosed);
32173 if (nodes.length !== 3)
32174 return "end_vertex";
32176 var coords = nodes.map(function(n2) {
32177 return projection2(n2.loc);
32179 var score = geoOrthoCanOrthogonalize(coords, isClosed, epsilon3, threshold, allowStraightAngles);
32180 if (score === null) {
32181 return "not_squarish";
32182 } else if (score === 0) {
32183 return "square_enough";
32188 action.transitionable = true;
32192 // modules/actions/restrict_turn.js
32193 function actionRestrictTurn(turn, restrictionType, restrictionID) {
32194 return function(graph) {
32195 var fromWay = graph.entity(turn.from.way);
32196 var toWay = graph.entity(turn.to.way);
32197 var viaNode = turn.via.node && graph.entity(turn.via.node);
32198 var viaWays = turn.via.ways && turn.via.ways.map(function(id2) {
32199 return graph.entity(id2);
32202 members.push({ id: fromWay.id, type: "way", role: "from" });
32204 members.push({ id: viaNode.id, type: "node", role: "via" });
32205 } else if (viaWays) {
32206 viaWays.forEach(function(viaWay) {
32207 members.push({ id: viaWay.id, type: "way", role: "via" });
32210 members.push({ id: toWay.id, type: "way", role: "to" });
32211 return graph.replace(osmRelation({
32214 type: "restriction",
32215 restriction: restrictionType
32222 // modules/actions/revert.js
32223 function actionRevert(id2) {
32224 var action = function(graph) {
32225 var entity = graph.hasEntity(id2), base = graph.base().entities[id2];
32226 if (entity && !base) {
32227 if (entity.type === "node") {
32228 graph.parentWays(entity).forEach(function(parent) {
32229 parent = parent.removeNode(id2);
32230 graph = graph.replace(parent);
32231 if (parent.isDegenerate()) {
32232 graph = actionDeleteWay(parent.id)(graph);
32236 graph.parentRelations(entity).forEach(function(parent) {
32237 parent = parent.removeMembersWithID(id2);
32238 graph = graph.replace(parent);
32239 if (parent.isDegenerate()) {
32240 graph = actionDeleteRelation(parent.id)(graph);
32244 return graph.revert(id2);
32249 // modules/actions/rotate.js
32250 function actionRotate(rotateIds, pivot, angle2, projection2) {
32251 var action = function(graph) {
32252 return graph.update(function(graph2) {
32253 utilGetAllNodes(rotateIds, graph2).forEach(function(node) {
32254 var point2 = geoRotate([projection2(node.loc)], angle2, pivot)[0];
32255 graph2 = graph2.replace(node.move(projection2.invert(point2)));
32262 // modules/actions/scale.js
32263 function actionScale(ids, pivotLoc, scaleFactor, projection2) {
32264 return function(graph) {
32265 return graph.update(function(graph2) {
32266 let point2, radial;
32267 utilGetAllNodes(ids, graph2).forEach(function(node) {
32268 point2 = projection2(node.loc);
32270 point2[0] - pivotLoc[0],
32271 point2[1] - pivotLoc[1]
32274 pivotLoc[0] + scaleFactor * radial[0],
32275 pivotLoc[1] + scaleFactor * radial[1]
32277 graph2 = graph2.replace(node.move(projection2.invert(point2)));
32283 // modules/actions/straighten_nodes.js
32284 function actionStraightenNodes(nodeIDs, projection2) {
32285 function positionAlongWay(a, o, b) {
32286 return geoVecDot(a, b, o) / geoVecDot(b, b, o);
32288 function getEndpoints(points) {
32289 var ssr = geoGetSmallestSurroundingRectangle(points);
32290 var p1 = [(ssr.poly[0][0] + ssr.poly[1][0]) / 2, (ssr.poly[0][1] + ssr.poly[1][1]) / 2];
32291 var q1 = [(ssr.poly[2][0] + ssr.poly[3][0]) / 2, (ssr.poly[2][1] + ssr.poly[3][1]) / 2];
32292 var p2 = [(ssr.poly[3][0] + ssr.poly[4][0]) / 2, (ssr.poly[3][1] + ssr.poly[4][1]) / 2];
32293 var q2 = [(ssr.poly[1][0] + ssr.poly[2][0]) / 2, (ssr.poly[1][1] + ssr.poly[2][1]) / 2];
32294 var isLong = geoVecLength(p1, q1) > geoVecLength(p2, q2);
32300 var action = function(graph, t) {
32301 if (t === null || !isFinite(t))
32303 t = Math.min(Math.max(+t, 0), 1);
32304 var nodes = nodeIDs.map(function(id2) {
32305 return graph.entity(id2);
32307 var points = nodes.map(function(n2) {
32308 return projection2(n2.loc);
32310 var endpoints = getEndpoints(points);
32311 var startPoint = endpoints[0];
32312 var endPoint = endpoints[1];
32313 for (var i2 = 0; i2 < points.length; i2++) {
32314 var node = nodes[i2];
32315 var point2 = points[i2];
32316 var u = positionAlongWay(point2, startPoint, endPoint);
32317 var point22 = geoVecInterp(startPoint, endPoint, u);
32318 var loc2 = projection2.invert(point22);
32319 graph = graph.replace(node.move(geoVecInterp(node.loc, loc2, t)));
32323 action.disabled = function(graph) {
32324 var nodes = nodeIDs.map(function(id2) {
32325 return graph.entity(id2);
32327 var points = nodes.map(function(n2) {
32328 return projection2(n2.loc);
32330 var endpoints = getEndpoints(points);
32331 var startPoint = endpoints[0];
32332 var endPoint = endpoints[1];
32333 var maxDistance = 0;
32334 for (var i2 = 0; i2 < points.length; i2++) {
32335 var point2 = points[i2];
32336 var u = positionAlongWay(point2, startPoint, endPoint);
32337 var p = geoVecInterp(startPoint, endPoint, u);
32338 var dist = geoVecLength(p, point2);
32339 if (!isNaN(dist) && dist > maxDistance) {
32340 maxDistance = dist;
32343 if (maxDistance < 1e-4) {
32344 return "straight_enough";
32347 action.transitionable = true;
32351 // modules/actions/straighten_way.js
32352 function actionStraightenWay(selectedIDs, projection2) {
32353 function positionAlongWay(a, o, b) {
32354 return geoVecDot(a, b, o) / geoVecDot(b, b, o);
32356 function allNodes(graph) {
32358 var startNodes = [];
32360 var remainingWays = [];
32361 var selectedWays = selectedIDs.filter(function(w) {
32362 return graph.entity(w).type === "way";
32364 var selectedNodes = selectedIDs.filter(function(n2) {
32365 return graph.entity(n2).type === "node";
32367 for (var i2 = 0; i2 < selectedWays.length; i2++) {
32368 var way = graph.entity(selectedWays[i2]);
32369 nodes = way.nodes.slice(0);
32370 remainingWays.push(nodes);
32371 startNodes.push(nodes[0]);
32372 endNodes.push(nodes[nodes.length - 1]);
32374 startNodes = startNodes.filter(function(n2) {
32375 return startNodes.indexOf(n2) === startNodes.lastIndexOf(n2);
32377 endNodes = endNodes.filter(function(n2) {
32378 return endNodes.indexOf(n2) === endNodes.lastIndexOf(n2);
32380 var currNode = utilArrayDifference(startNodes, endNodes).concat(utilArrayDifference(endNodes, startNodes))[0];
32383 var getNextWay = function(currNode2, remainingWays2) {
32384 return remainingWays2.filter(function(way2) {
32385 return way2[0] === currNode2 || way2[way2.length - 1] === currNode2;
32388 while (remainingWays.length) {
32389 nextWay = getNextWay(currNode, remainingWays);
32390 remainingWays = utilArrayDifference(remainingWays, [nextWay]);
32391 if (nextWay[0] !== currNode) {
32394 nodes = nodes.concat(nextWay);
32395 currNode = nodes[nodes.length - 1];
32397 if (selectedNodes.length === 2) {
32398 var startNodeIdx = nodes.indexOf(selectedNodes[0]);
32399 var endNodeIdx = nodes.indexOf(selectedNodes[1]);
32400 var sortedStartEnd = [startNodeIdx, endNodeIdx];
32401 sortedStartEnd.sort(function(a, b) {
32404 nodes = nodes.slice(sortedStartEnd[0], sortedStartEnd[1] + 1);
32406 return nodes.map(function(n2) {
32407 return graph.entity(n2);
32410 function shouldKeepNode(node, graph) {
32411 return graph.parentWays(node).length > 1 || graph.parentRelations(node).length || node.hasInterestingTags();
32413 var action = function(graph, t) {
32414 if (t === null || !isFinite(t))
32416 t = Math.min(Math.max(+t, 0), 1);
32417 var nodes = allNodes(graph);
32418 var points = nodes.map(function(n2) {
32419 return projection2(n2.loc);
32421 var startPoint = points[0];
32422 var endPoint = points[points.length - 1];
32425 for (i2 = 1; i2 < points.length - 1; i2++) {
32426 var node = nodes[i2];
32427 var point2 = points[i2];
32428 if (t < 1 || shouldKeepNode(node, graph)) {
32429 var u = positionAlongWay(point2, startPoint, endPoint);
32430 var p = geoVecInterp(startPoint, endPoint, u);
32431 var loc2 = projection2.invert(p);
32432 graph = graph.replace(node.move(geoVecInterp(node.loc, loc2, t)));
32434 if (toDelete.indexOf(node) === -1) {
32435 toDelete.push(node);
32439 for (i2 = 0; i2 < toDelete.length; i2++) {
32440 graph = actionDeleteNode(toDelete[i2].id)(graph);
32444 action.disabled = function(graph) {
32445 var nodes = allNodes(graph);
32446 var points = nodes.map(function(n2) {
32447 return projection2(n2.loc);
32449 var startPoint = points[0];
32450 var endPoint = points[points.length - 1];
32451 var threshold = 0.2 * geoVecLength(startPoint, endPoint);
32453 if (threshold === 0) {
32454 return "too_bendy";
32456 var maxDistance = 0;
32457 for (i2 = 1; i2 < points.length - 1; i2++) {
32458 var point2 = points[i2];
32459 var u = positionAlongWay(point2, startPoint, endPoint);
32460 var p = geoVecInterp(startPoint, endPoint, u);
32461 var dist = geoVecLength(p, point2);
32462 if (isNaN(dist) || dist > threshold) {
32463 return "too_bendy";
32464 } else if (dist > maxDistance) {
32465 maxDistance = dist;
32468 var keepingAllNodes = nodes.every(function(node, i3) {
32469 return i3 === 0 || i3 === nodes.length - 1 || shouldKeepNode(node, graph);
32471 if (maxDistance < 1e-4 && // Allow straightening even if already straight in order to remove extraneous nodes
32473 return "straight_enough";
32476 action.transitionable = true;
32480 // modules/actions/unrestrict_turn.js
32481 function actionUnrestrictTurn(turn) {
32482 return function(graph) {
32483 return actionDeleteRelation(turn.restrictionID)(graph);
32487 // modules/actions/reflect.js
32488 function actionReflect(reflectIds, projection2) {
32489 var _useLongAxis = true;
32490 var action = function(graph, t) {
32491 if (t === null || !isFinite(t))
32493 t = Math.min(Math.max(+t, 0), 1);
32494 var nodes = utilGetAllNodes(reflectIds, graph);
32495 var points = nodes.map(function(n2) {
32496 return projection2(n2.loc);
32498 var ssr = geoGetSmallestSurroundingRectangle(points);
32499 var p1 = [(ssr.poly[0][0] + ssr.poly[1][0]) / 2, (ssr.poly[0][1] + ssr.poly[1][1]) / 2];
32500 var q1 = [(ssr.poly[2][0] + ssr.poly[3][0]) / 2, (ssr.poly[2][1] + ssr.poly[3][1]) / 2];
32501 var p2 = [(ssr.poly[3][0] + ssr.poly[4][0]) / 2, (ssr.poly[3][1] + ssr.poly[4][1]) / 2];
32502 var q2 = [(ssr.poly[1][0] + ssr.poly[2][0]) / 2, (ssr.poly[1][1] + ssr.poly[2][1]) / 2];
32504 var isLong = geoVecLength(p1, q1) > geoVecLength(p2, q2);
32505 if (_useLongAxis && isLong || !_useLongAxis && !isLong) {
32512 var dx = q[0] - p[0];
32513 var dy = q[1] - p[1];
32514 var a = (dx * dx - dy * dy) / (dx * dx + dy * dy);
32515 var b = 2 * dx * dy / (dx * dx + dy * dy);
32516 for (var i2 = 0; i2 < nodes.length; i2++) {
32517 var node = nodes[i2];
32518 var c = projection2(node.loc);
32520 a * (c[0] - p[0]) + b * (c[1] - p[1]) + p[0],
32521 b * (c[0] - p[0]) - a * (c[1] - p[1]) + p[1]
32523 var loc2 = projection2.invert(c2);
32524 node = node.move(geoVecInterp(node.loc, loc2, t));
32525 graph = graph.replace(node);
32529 action.useLongAxis = function(val) {
32530 if (!arguments.length)
32531 return _useLongAxis;
32532 _useLongAxis = val;
32535 action.transitionable = true;
32539 // modules/actions/upgrade_tags.js
32540 function actionUpgradeTags(entityId, oldTags, replaceTags) {
32541 return function(graph) {
32542 var entity = graph.entity(entityId);
32543 var tags = Object.assign({}, entity.tags);
32546 for (var oldTagKey in oldTags) {
32547 if (!(oldTagKey in tags))
32549 if (oldTags[oldTagKey] === "*") {
32550 transferValue = tags[oldTagKey];
32551 delete tags[oldTagKey];
32552 } else if (oldTags[oldTagKey] === tags[oldTagKey]) {
32553 delete tags[oldTagKey];
32555 var vals = tags[oldTagKey].split(";").filter(Boolean);
32556 var oldIndex = vals.indexOf(oldTags[oldTagKey]);
32557 if (vals.length === 1 || oldIndex === -1) {
32558 delete tags[oldTagKey];
32560 if (replaceTags && replaceTags[oldTagKey]) {
32561 semiIndex = oldIndex;
32563 vals.splice(oldIndex, 1);
32564 tags[oldTagKey] = vals.join(";");
32569 for (var replaceKey in replaceTags) {
32570 var replaceValue = replaceTags[replaceKey];
32571 if (replaceValue === "*") {
32572 if (tags[replaceKey] && tags[replaceKey] !== "no") {
32575 tags[replaceKey] = "yes";
32577 } else if (replaceValue === "$1") {
32578 tags[replaceKey] = transferValue;
32580 if (tags[replaceKey] && oldTags[replaceKey] && semiIndex !== void 0) {
32581 var existingVals = tags[replaceKey].split(";").filter(Boolean);
32582 if (existingVals.indexOf(replaceValue) === -1) {
32583 existingVals.splice(semiIndex, 0, replaceValue);
32584 tags[replaceKey] = existingVals.join(";");
32587 tags[replaceKey] = replaceValue;
32592 return graph.replace(entity.update({ tags }));
32596 // modules/behavior/edit.js
32597 function behaviorEdit(context) {
32598 function behavior() {
32599 context.map().minzoom(context.minEditableZoom());
32601 behavior.off = function() {
32602 context.map().minzoom(0);
32607 // modules/behavior/hover.js
32608 function behaviorHover(context) {
32609 var dispatch10 = dispatch_default("hover");
32610 var _selection = select_default2(null);
32611 var _newNodeId = null;
32612 var _initialNodeID = null;
32616 var _pointerPrefix = "PointerEvent" in window ? "pointer" : "mouse";
32617 function keydown(d3_event) {
32618 if (_altDisables && d3_event.keyCode === utilKeybinding.modifierCodes.alt) {
32619 _selection.selectAll(".hover").classed("hover-suppressed", true).classed("hover", false);
32620 _selection.classed("hover-disabled", true);
32621 dispatch10.call("hover", this, null);
32624 function keyup(d3_event) {
32625 if (_altDisables && d3_event.keyCode === utilKeybinding.modifierCodes.alt) {
32626 _selection.selectAll(".hover-suppressed").classed("hover-suppressed", false).classed("hover", true);
32627 _selection.classed("hover-disabled", false);
32628 dispatch10.call("hover", this, _targets);
32631 function behavior(selection2) {
32632 _selection = selection2;
32634 if (_initialNodeID) {
32635 _newNodeId = _initialNodeID;
32636 _initialNodeID = null;
32640 _selection.on(_pointerPrefix + "over.hover", pointerover).on(_pointerPrefix + "out.hover", pointerout).on(_pointerPrefix + "down.hover", pointerover);
32641 select_default2(window).on(_pointerPrefix + "up.hover pointercancel.hover", pointerout, true).on("keydown.hover", keydown).on("keyup.hover", keyup);
32642 function eventTarget(d3_event) {
32643 var datum2 = d3_event.target && d3_event.target.__data__;
32644 if (typeof datum2 !== "object")
32646 if (!(datum2 instanceof osmEntity) && datum2.properties && datum2.properties.entity instanceof osmEntity) {
32647 return datum2.properties.entity;
32651 function pointerover(d3_event) {
32652 if (context.mode().id.indexOf("drag") === -1 && (!d3_event.pointerType || d3_event.pointerType === "mouse") && d3_event.buttons)
32654 var target = eventTarget(d3_event);
32655 if (target && _targets.indexOf(target) === -1) {
32656 _targets.push(target);
32657 updateHover(d3_event, _targets);
32660 function pointerout(d3_event) {
32661 var target = eventTarget(d3_event);
32662 var index = _targets.indexOf(target);
32663 if (index !== -1) {
32664 _targets.splice(index);
32665 updateHover(d3_event, _targets);
32668 function allowsVertex(d) {
32669 return d.geometry(context.graph()) === "vertex" || _mainPresetIndex.allowsVertex(d, context.graph());
32671 function modeAllowsHover(target) {
32672 var mode = context.mode();
32673 if (mode.id === "add-point") {
32674 return mode.preset.matchGeometry("vertex") || target.type !== "way" && target.geometry(context.graph()) !== "vertex";
32678 function updateHover(d3_event, targets) {
32679 _selection.selectAll(".hover").classed("hover", false);
32680 _selection.selectAll(".hover-suppressed").classed("hover-suppressed", false);
32681 var mode = context.mode();
32682 if (!_newNodeId && (mode.id === "draw-line" || mode.id === "draw-area")) {
32683 var node = targets.find(function(target) {
32684 return target instanceof osmEntity && target.type === "node";
32686 _newNodeId = node && node.id;
32688 targets = targets.filter(function(datum3) {
32689 if (datum3 instanceof osmEntity) {
32690 return datum3.id !== _newNodeId && (datum3.type !== "node" || !_ignoreVertex || allowsVertex(datum3)) && modeAllowsHover(datum3);
32695 for (var i2 in targets) {
32696 var datum2 = targets[i2];
32697 if (datum2.__featurehash__) {
32698 selector += ", .data" + datum2.__featurehash__;
32699 } else if (datum2 instanceof QAItem) {
32700 selector += ", ." + datum2.service + ".itemId-" + datum2.id;
32701 } else if (datum2 instanceof osmNote) {
32702 selector += ", .note-" + datum2.id;
32703 } else if (datum2 instanceof osmEntity) {
32704 selector += ", ." + datum2.id;
32705 if (datum2.type === "relation") {
32706 for (var j2 in datum2.members) {
32707 selector += ", ." + datum2.members[j2].id;
32712 var suppressed = _altDisables && d3_event && d3_event.altKey;
32713 if (selector.trim().length) {
32714 selector = selector.slice(1);
32715 _selection.selectAll(selector).classed(suppressed ? "hover-suppressed" : "hover", true);
32717 dispatch10.call("hover", this, !suppressed && targets);
32720 behavior.off = function(selection2) {
32721 selection2.selectAll(".hover").classed("hover", false);
32722 selection2.selectAll(".hover-suppressed").classed("hover-suppressed", false);
32723 selection2.classed("hover-disabled", false);
32724 selection2.on(_pointerPrefix + "over.hover", null).on(_pointerPrefix + "out.hover", null).on(_pointerPrefix + "down.hover", null);
32725 select_default2(window).on(_pointerPrefix + "up.hover pointercancel.hover", null, true).on("keydown.hover", null).on("keyup.hover", null);
32727 behavior.altDisables = function(val) {
32728 if (!arguments.length)
32729 return _altDisables;
32730 _altDisables = val;
32733 behavior.ignoreVertex = function(val) {
32734 if (!arguments.length)
32735 return _ignoreVertex;
32736 _ignoreVertex = val;
32739 behavior.initialNodeID = function(nodeId) {
32740 _initialNodeID = nodeId;
32743 return utilRebind(behavior, dispatch10, "on");
32746 // modules/behavior/draw.js
32747 var _disableSpace = false;
32748 var _lastSpace = null;
32749 function behaviorDraw(context) {
32750 var dispatch10 = dispatch_default(
32761 var keybinding = utilKeybinding("draw");
32762 var _hover = behaviorHover(context).altDisables(true).ignoreVertex(true).on("hover", context.ui().sidebar.hover);
32763 var _edit = behaviorEdit(context);
32764 var _closeTolerance = 4;
32765 var _tolerance = 12;
32766 var _mouseLeave = false;
32767 var _lastMouse = null;
32768 var _lastPointerUpEvent;
32770 var _pointerPrefix = "PointerEvent" in window ? "pointer" : "mouse";
32771 function datum2(d3_event) {
32772 var mode = context.mode();
32773 var isNote = mode && mode.id.indexOf("note") !== -1;
32774 if (d3_event.altKey || isNote)
32777 if (d3_event.type === "keydown") {
32778 element = _lastMouse && _lastMouse.target;
32780 element = d3_event.target;
32782 var d = element.__data__;
32783 return d && d.properties && d.properties.target ? d : {};
32785 function pointerdown(d3_event) {
32788 var pointerLocGetter = utilFastMouse(this);
32790 id: d3_event.pointerId || "mouse",
32792 downTime: +/* @__PURE__ */ new Date(),
32793 downLoc: pointerLocGetter(d3_event)
32795 dispatch10.call("down", this, d3_event, datum2(d3_event));
32797 function pointerup(d3_event) {
32798 if (!_downPointer || _downPointer.id !== (d3_event.pointerId || "mouse"))
32800 var downPointer = _downPointer;
32801 _downPointer = null;
32802 _lastPointerUpEvent = d3_event;
32803 if (downPointer.isCancelled)
32805 var t2 = +/* @__PURE__ */ new Date();
32806 var p2 = downPointer.pointerLocGetter(d3_event);
32807 var dist = geoVecLength(downPointer.downLoc, p2);
32808 if (dist < _closeTolerance || dist < _tolerance && t2 - downPointer.downTime < 500) {
32809 select_default2(window).on("click.draw-block", function() {
32810 d3_event.stopPropagation();
32812 context.map().dblclickZoomEnable(false);
32813 window.setTimeout(function() {
32814 context.map().dblclickZoomEnable(true);
32815 select_default2(window).on("click.draw-block", null);
32817 click(d3_event, p2);
32820 function pointermove(d3_event) {
32821 if (_downPointer && _downPointer.id === (d3_event.pointerId || "mouse") && !_downPointer.isCancelled) {
32822 var p2 = _downPointer.pointerLocGetter(d3_event);
32823 var dist = geoVecLength(_downPointer.downLoc, p2);
32824 if (dist >= _closeTolerance) {
32825 _downPointer.isCancelled = true;
32826 dispatch10.call("downcancel", this);
32829 if (d3_event.pointerType && d3_event.pointerType !== "mouse" || d3_event.buttons || _downPointer)
32831 if (_lastPointerUpEvent && _lastPointerUpEvent.pointerType !== "mouse" && d3_event.timeStamp - _lastPointerUpEvent.timeStamp < 100)
32833 _lastMouse = d3_event;
32834 dispatch10.call("move", this, d3_event, datum2(d3_event));
32836 function pointercancel(d3_event) {
32837 if (_downPointer && _downPointer.id === (d3_event.pointerId || "mouse")) {
32838 if (!_downPointer.isCancelled) {
32839 dispatch10.call("downcancel", this);
32841 _downPointer = null;
32844 function mouseenter() {
32845 _mouseLeave = false;
32847 function mouseleave() {
32848 _mouseLeave = true;
32850 function allowsVertex(d) {
32851 return d.geometry(context.graph()) === "vertex" || _mainPresetIndex.allowsVertex(d, context.graph());
32853 function click(d3_event, loc) {
32854 var d = datum2(d3_event);
32855 var target = d && d.properties && d.properties.entity;
32856 var mode = context.mode();
32857 if (target && target.type === "node" && allowsVertex(target)) {
32858 dispatch10.call("clickNode", this, target, d);
32860 } else if (target && target.type === "way" && (mode.id !== "add-point" || mode.preset.matchGeometry("vertex"))) {
32861 var choice = geoChooseEdge(
32862 context.graph().childNodes(target),
32864 context.projection,
32868 var edge = [target.nodes[choice.index - 1], target.nodes[choice.index]];
32869 dispatch10.call("clickWay", this, choice.loc, edge, d);
32872 } else if (mode.id !== "add-point" || mode.preset.matchGeometry("point")) {
32873 var locLatLng = context.projection.invert(loc);
32874 dispatch10.call("click", this, locLatLng, d);
32877 function space(d3_event) {
32878 d3_event.preventDefault();
32879 d3_event.stopPropagation();
32880 var currSpace = context.map().mouse();
32881 if (_disableSpace && _lastSpace) {
32882 var dist = geoVecLength(_lastSpace, currSpace);
32883 if (dist > _tolerance) {
32884 _disableSpace = false;
32887 if (_disableSpace || _mouseLeave || !_lastMouse)
32889 _lastSpace = currSpace;
32890 _disableSpace = true;
32891 select_default2(window).on("keyup.space-block", function() {
32892 d3_event.preventDefault();
32893 d3_event.stopPropagation();
32894 _disableSpace = false;
32895 select_default2(window).on("keyup.space-block", null);
32897 var loc = context.map().mouse() || // or the map center if the mouse has never entered the map
32898 context.projection(context.map().center());
32899 click(d3_event, loc);
32901 function backspace(d3_event) {
32902 d3_event.preventDefault();
32903 dispatch10.call("undo");
32905 function del(d3_event) {
32906 d3_event.preventDefault();
32907 dispatch10.call("cancel");
32909 function ret(d3_event) {
32910 d3_event.preventDefault();
32911 dispatch10.call("finish");
32913 function behavior(selection2) {
32914 context.install(_hover);
32915 context.install(_edit);
32916 _downPointer = null;
32917 keybinding.on("\u232B", backspace).on("\u2326", del).on("\u238B", ret).on("\u21A9", ret).on("space", space).on("\u2325space", space);
32918 selection2.on("mouseenter.draw", mouseenter).on("mouseleave.draw", mouseleave).on(_pointerPrefix + "down.draw", pointerdown).on(_pointerPrefix + "move.draw", pointermove);
32919 select_default2(window).on(_pointerPrefix + "up.draw", pointerup, true).on("pointercancel.draw", pointercancel, true);
32920 select_default2(document).call(keybinding);
32923 behavior.off = function(selection2) {
32924 context.ui().sidebar.hover.cancel();
32925 context.uninstall(_hover);
32926 context.uninstall(_edit);
32927 selection2.on("mouseenter.draw", null).on("mouseleave.draw", null).on(_pointerPrefix + "down.draw", null).on(_pointerPrefix + "move.draw", null);
32928 select_default2(window).on(_pointerPrefix + "up.draw", null).on("pointercancel.draw", null);
32929 select_default2(document).call(keybinding.unbind);
32931 behavior.hover = function() {
32934 return utilRebind(behavior, dispatch10, "on");
32937 // modules/behavior/breathe.js
32938 var import_fast_deep_equal2 = __toESM(require_fast_deep_equal());
32940 // node_modules/d3-scale/src/init.js
32941 function initRange(domain2, range3) {
32942 switch (arguments.length) {
32946 this.range(domain2);
32949 this.range(range3).domain(domain2);
32955 // node_modules/d3-scale/src/constant.js
32956 function constants(x) {
32957 return function() {
32962 // node_modules/d3-scale/src/number.js
32963 function number2(x) {
32967 // node_modules/d3-scale/src/continuous.js
32969 function identity3(x) {
32972 function normalize(a, b) {
32973 return (b -= a = +a) ? function(x) {
32974 return (x - a) / b;
32975 } : constants(isNaN(b) ? NaN : 0.5);
32977 function clamper(a, b) {
32980 t = a, a = b, b = t;
32981 return function(x) {
32982 return Math.max(a, Math.min(b, x));
32985 function bimap(domain2, range3, interpolate) {
32986 var d0 = domain2[0], d1 = domain2[1], r0 = range3[0], r1 = range3[1];
32988 d0 = normalize(d1, d0), r0 = interpolate(r1, r0);
32990 d0 = normalize(d0, d1), r0 = interpolate(r0, r1);
32991 return function(x) {
32995 function polymap(domain2, range3, interpolate) {
32996 var j2 = Math.min(domain2.length, range3.length) - 1, d = new Array(j2), r = new Array(j2), i2 = -1;
32997 if (domain2[j2] < domain2[0]) {
32998 domain2 = domain2.slice().reverse();
32999 range3 = range3.slice().reverse();
33001 while (++i2 < j2) {
33002 d[i2] = normalize(domain2[i2], domain2[i2 + 1]);
33003 r[i2] = interpolate(range3[i2], range3[i2 + 1]);
33005 return function(x) {
33006 var i3 = bisect_default(domain2, x, 1, j2) - 1;
33007 return r[i3](d[i3](x));
33010 function copy(source, target) {
33011 return target.domain(source.domain()).range(source.range()).interpolate(source.interpolate()).clamp(source.clamp()).unknown(source.unknown());
33013 function transformer2() {
33014 var domain2 = unit, range3 = unit, interpolate = value_default, transform2, untransform, unknown, clamp3 = identity3, piecewise, output, input;
33015 function rescale() {
33016 var n2 = Math.min(domain2.length, range3.length);
33017 if (clamp3 !== identity3)
33018 clamp3 = clamper(domain2[0], domain2[n2 - 1]);
33019 piecewise = n2 > 2 ? polymap : bimap;
33020 output = input = null;
33023 function scale(x) {
33024 return x == null || isNaN(x = +x) ? unknown : (output || (output = piecewise(domain2.map(transform2), range3, interpolate)))(transform2(clamp3(x)));
33026 scale.invert = function(y) {
33027 return clamp3(untransform((input || (input = piecewise(range3, domain2.map(transform2), number_default)))(y)));
33029 scale.domain = function(_) {
33030 return arguments.length ? (domain2 = Array.from(_, number2), rescale()) : domain2.slice();
33032 scale.range = function(_) {
33033 return arguments.length ? (range3 = Array.from(_), rescale()) : range3.slice();
33035 scale.rangeRound = function(_) {
33036 return range3 = Array.from(_), interpolate = round_default, rescale();
33038 scale.clamp = function(_) {
33039 return arguments.length ? (clamp3 = _ ? true : identity3, rescale()) : clamp3 !== identity3;
33041 scale.interpolate = function(_) {
33042 return arguments.length ? (interpolate = _, rescale()) : interpolate;
33044 scale.unknown = function(_) {
33045 return arguments.length ? (unknown = _, scale) : unknown;
33047 return function(t, u) {
33048 transform2 = t, untransform = u;
33052 function continuous() {
33053 return transformer2()(identity3, identity3);
33056 // node_modules/d3-format/src/formatDecimal.js
33057 function formatDecimal_default(x) {
33058 return Math.abs(x = Math.round(x)) >= 1e21 ? x.toLocaleString("en").replace(/,/g, "") : x.toString(10);
33060 function formatDecimalParts(x, p) {
33061 if ((i2 = (x = p ? x.toExponential(p - 1) : x.toExponential()).indexOf("e")) < 0)
33063 var i2, coefficient = x.slice(0, i2);
33065 coefficient.length > 1 ? coefficient[0] + coefficient.slice(2) : coefficient,
33070 // node_modules/d3-format/src/exponent.js
33071 function exponent_default(x) {
33072 return x = formatDecimalParts(Math.abs(x)), x ? x[1] : NaN;
33075 // node_modules/d3-format/src/formatGroup.js
33076 function formatGroup_default(grouping, thousands) {
33077 return function(value, width) {
33078 var i2 = value.length, t = [], j2 = 0, g = grouping[0], length = 0;
33079 while (i2 > 0 && g > 0) {
33080 if (length + g + 1 > width)
33081 g = Math.max(1, width - length);
33082 t.push(value.substring(i2 -= g, i2 + g));
33083 if ((length += g + 1) > width)
33085 g = grouping[j2 = (j2 + 1) % grouping.length];
33087 return t.reverse().join(thousands);
33091 // node_modules/d3-format/src/formatNumerals.js
33092 function formatNumerals_default(numerals) {
33093 return function(value) {
33094 return value.replace(/[0-9]/g, function(i2) {
33095 return numerals[+i2];
33100 // node_modules/d3-format/src/formatSpecifier.js
33101 var re = /^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;
33102 function formatSpecifier(specifier) {
33103 if (!(match = re.exec(specifier)))
33104 throw new Error("invalid format: " + specifier);
33106 return new FormatSpecifier({
33114 precision: match[8] && match[8].slice(1),
33119 formatSpecifier.prototype = FormatSpecifier.prototype;
33120 function FormatSpecifier(specifier) {
33121 this.fill = specifier.fill === void 0 ? " " : specifier.fill + "";
33122 this.align = specifier.align === void 0 ? ">" : specifier.align + "";
33123 this.sign = specifier.sign === void 0 ? "-" : specifier.sign + "";
33124 this.symbol = specifier.symbol === void 0 ? "" : specifier.symbol + "";
33125 this.zero = !!specifier.zero;
33126 this.width = specifier.width === void 0 ? void 0 : +specifier.width;
33127 this.comma = !!specifier.comma;
33128 this.precision = specifier.precision === void 0 ? void 0 : +specifier.precision;
33129 this.trim = !!specifier.trim;
33130 this.type = specifier.type === void 0 ? "" : specifier.type + "";
33132 FormatSpecifier.prototype.toString = function() {
33133 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;
33136 // node_modules/d3-format/src/formatTrim.js
33137 function formatTrim_default(s) {
33139 for (var n2 = s.length, i2 = 1, i0 = -1, i1; i2 < n2; ++i2) {
33157 return i0 > 0 ? s.slice(0, i0) + s.slice(i1 + 1) : s;
33160 // node_modules/d3-format/src/formatPrefixAuto.js
33161 var prefixExponent;
33162 function formatPrefixAuto_default(x, p) {
33163 var d = formatDecimalParts(x, p);
33166 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;
33167 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];
33170 // node_modules/d3-format/src/formatRounded.js
33171 function formatRounded_default(x, p) {
33172 var d = formatDecimalParts(x, p);
33175 var coefficient = d[0], exponent = d[1];
33176 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");
33179 // node_modules/d3-format/src/formatTypes.js
33180 var formatTypes_default = {
33181 "%": (x, p) => (x * 100).toFixed(p),
33182 "b": (x) => Math.round(x).toString(2),
33183 "c": (x) => x + "",
33184 "d": formatDecimal_default,
33185 "e": (x, p) => x.toExponential(p),
33186 "f": (x, p) => x.toFixed(p),
33187 "g": (x, p) => x.toPrecision(p),
33188 "o": (x) => Math.round(x).toString(8),
33189 "p": (x, p) => formatRounded_default(x * 100, p),
33190 "r": formatRounded_default,
33191 "s": formatPrefixAuto_default,
33192 "X": (x) => Math.round(x).toString(16).toUpperCase(),
33193 "x": (x) => Math.round(x).toString(16)
33196 // node_modules/d3-format/src/identity.js
33197 function identity_default3(x) {
33201 // node_modules/d3-format/src/locale.js
33202 var map = Array.prototype.map;
33203 var prefixes = ["y", "z", "a", "f", "p", "n", "\xB5", "m", "", "k", "M", "G", "T", "P", "E", "Z", "Y"];
33204 function locale_default(locale2) {
33205 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 + "";
33206 function newFormat(specifier) {
33207 specifier = formatSpecifier(specifier);
33208 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;
33210 comma = true, type2 = "g";
33211 else if (!formatTypes_default[type2])
33212 precision2 === void 0 && (precision2 = 12), trim = true, type2 = "g";
33213 if (zero3 || fill === "0" && align === "=")
33214 zero3 = true, fill = "0", align = "=";
33215 var prefix = symbol === "$" ? currencyPrefix : symbol === "#" && /[boxX]/.test(type2) ? "0" + type2.toLowerCase() : "", suffix = symbol === "$" ? currencySuffix : /[%p]/.test(type2) ? percent : "";
33216 var formatType = formatTypes_default[type2], maybeSuffix = /[defgprs%]/.test(type2);
33217 precision2 = precision2 === void 0 ? 6 : /[gprs]/.test(type2) ? Math.max(1, Math.min(21, precision2)) : Math.max(0, Math.min(20, precision2));
33218 function format2(value) {
33219 var valuePrefix = prefix, valueSuffix = suffix, i2, n2, c;
33220 if (type2 === "c") {
33221 valueSuffix = formatType(value) + valueSuffix;
33225 var valueNegative = value < 0 || 1 / value < 0;
33226 value = isNaN(value) ? nan : formatType(Math.abs(value), precision2);
33228 value = formatTrim_default(value);
33229 if (valueNegative && +value === 0 && sign2 !== "+")
33230 valueNegative = false;
33231 valuePrefix = (valueNegative ? sign2 === "(" ? sign2 : minus : sign2 === "-" || sign2 === "(" ? "" : sign2) + valuePrefix;
33232 valueSuffix = (type2 === "s" ? prefixes[8 + prefixExponent / 3] : "") + valueSuffix + (valueNegative && sign2 === "(" ? ")" : "");
33234 i2 = -1, n2 = value.length;
33235 while (++i2 < n2) {
33236 if (c = value.charCodeAt(i2), 48 > c || c > 57) {
33237 valueSuffix = (c === 46 ? decimal + value.slice(i2 + 1) : value.slice(i2)) + valueSuffix;
33238 value = value.slice(0, i2);
33244 if (comma && !zero3)
33245 value = group(value, Infinity);
33246 var length = valuePrefix.length + value.length + valueSuffix.length, padding = length < width ? new Array(width - length + 1).join(fill) : "";
33247 if (comma && zero3)
33248 value = group(padding + value, padding.length ? width - valueSuffix.length : Infinity), padding = "";
33251 value = valuePrefix + value + valueSuffix + padding;
33254 value = valuePrefix + padding + value + valueSuffix;
33257 value = padding.slice(0, length = padding.length >> 1) + valuePrefix + value + valueSuffix + padding.slice(length);
33260 value = padding + valuePrefix + value + valueSuffix;
33263 return numerals(value);
33265 format2.toString = function() {
33266 return specifier + "";
33270 function formatPrefix2(specifier, value) {
33271 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];
33272 return function(value2) {
33273 return f2(k * value2) + prefix;
33278 formatPrefix: formatPrefix2
33282 // node_modules/d3-format/src/defaultLocale.js
33289 currency: ["$", ""]
33291 function defaultLocale(definition) {
33292 locale = locale_default(definition);
33293 format = locale.format;
33294 formatPrefix = locale.formatPrefix;
33298 // node_modules/d3-format/src/precisionFixed.js
33299 function precisionFixed_default(step) {
33300 return Math.max(0, -exponent_default(Math.abs(step)));
33303 // node_modules/d3-format/src/precisionPrefix.js
33304 function precisionPrefix_default(step, value) {
33305 return Math.max(0, Math.max(-8, Math.min(8, Math.floor(exponent_default(value) / 3))) * 3 - exponent_default(Math.abs(step)));
33308 // node_modules/d3-format/src/precisionRound.js
33309 function precisionRound_default(step, max3) {
33310 step = Math.abs(step), max3 = Math.abs(max3) - step;
33311 return Math.max(0, exponent_default(max3) - exponent_default(step)) + 1;
33314 // node_modules/d3-scale/src/tickFormat.js
33315 function tickFormat(start2, stop, count, specifier) {
33316 var step = tickStep(start2, stop, count), precision2;
33317 specifier = formatSpecifier(specifier == null ? ",f" : specifier);
33318 switch (specifier.type) {
33320 var value = Math.max(Math.abs(start2), Math.abs(stop));
33321 if (specifier.precision == null && !isNaN(precision2 = precisionPrefix_default(step, value)))
33322 specifier.precision = precision2;
33323 return formatPrefix(specifier, value);
33330 if (specifier.precision == null && !isNaN(precision2 = precisionRound_default(step, Math.max(Math.abs(start2), Math.abs(stop)))))
33331 specifier.precision = precision2 - (specifier.type === "e");
33336 if (specifier.precision == null && !isNaN(precision2 = precisionFixed_default(step)))
33337 specifier.precision = precision2 - (specifier.type === "%") * 2;
33341 return format(specifier);
33344 // node_modules/d3-scale/src/linear.js
33345 function linearish(scale) {
33346 var domain2 = scale.domain;
33347 scale.ticks = function(count) {
33349 return ticks(d[0], d[d.length - 1], count == null ? 10 : count);
33351 scale.tickFormat = function(count, specifier) {
33353 return tickFormat(d[0], d[d.length - 1], count == null ? 10 : count, specifier);
33355 scale.nice = function(count) {
33360 var i1 = d.length - 1;
33361 var start2 = d[i0];
33366 if (stop < start2) {
33367 step = start2, start2 = stop, stop = step;
33368 step = i0, i0 = i1, i1 = step;
33370 while (maxIter-- > 0) {
33371 step = tickIncrement(start2, stop, count);
33372 if (step === prestep) {
33376 } else if (step > 0) {
33377 start2 = Math.floor(start2 / step) * step;
33378 stop = Math.ceil(stop / step) * step;
33379 } else if (step < 0) {
33380 start2 = Math.ceil(start2 * step) / step;
33381 stop = Math.floor(stop * step) / step;
33391 function linear3() {
33392 var scale = continuous();
33393 scale.copy = function() {
33394 return copy(scale, linear3());
33396 initRange.apply(scale, arguments);
33397 return linearish(scale);
33400 // node_modules/d3-scale/src/quantize.js
33401 function quantize() {
33402 var x05 = 0, x12 = 1, n2 = 1, domain2 = [0.5], range3 = [0, 1], unknown;
33403 function scale(x) {
33404 return x != null && x <= x ? range3[bisect_default(domain2, x, 0, n2)] : unknown;
33406 function rescale() {
33408 domain2 = new Array(n2);
33410 domain2[i2] = ((i2 + 1) * x12 - (i2 - n2) * x05) / (n2 + 1);
33413 scale.domain = function(_) {
33414 return arguments.length ? ([x05, x12] = _, x05 = +x05, x12 = +x12, rescale()) : [x05, x12];
33416 scale.range = function(_) {
33417 return arguments.length ? (n2 = (range3 = Array.from(_)).length - 1, rescale()) : range3.slice();
33419 scale.invertExtent = function(y) {
33420 var i2 = range3.indexOf(y);
33421 return i2 < 0 ? [NaN, NaN] : i2 < 1 ? [x05, domain2[0]] : i2 >= n2 ? [domain2[n2 - 1], x12] : [domain2[i2 - 1], domain2[i2]];
33423 scale.unknown = function(_) {
33424 return arguments.length ? (unknown = _, scale) : scale;
33426 scale.thresholds = function() {
33427 return domain2.slice();
33429 scale.copy = function() {
33430 return quantize().domain([x05, x12]).range(range3).unknown(unknown);
33432 return initRange.apply(linearish(scale), arguments);
33435 // modules/behavior/breathe.js
33436 function behaviorBreathe() {
33437 var duration = 800;
33439 var selector = ".selected.shadow, .selected .shadow";
33440 var _selected = select_default2(null);
33445 function ratchetyInterpolator(a, b, steps2, units) {
33448 var sample = quantize().domain([0, 1]).range(quantize_default(number_default(a, b), steps2));
33449 return function(t) {
33450 return String(sample(t)) + (units || "");
33453 function reset(selection2) {
33454 selection2.style("stroke-opacity", null).style("stroke-width", null).style("fill-opacity", null).style("r", null);
33456 function setAnimationParams(transition2, fromTo) {
33457 var toFrom = fromTo === "from" ? "to" : "from";
33458 transition2.styleTween("stroke-opacity", function(d) {
33459 return ratchetyInterpolator(
33460 _params[d.id][toFrom].opacity,
33461 _params[d.id][fromTo].opacity,
33464 }).styleTween("stroke-width", function(d) {
33465 return ratchetyInterpolator(
33466 _params[d.id][toFrom].width,
33467 _params[d.id][fromTo].width,
33471 }).styleTween("fill-opacity", function(d) {
33472 return ratchetyInterpolator(
33473 _params[d.id][toFrom].opacity,
33474 _params[d.id][fromTo].opacity,
33477 }).styleTween("r", function(d) {
33478 return ratchetyInterpolator(
33479 _params[d.id][toFrom].width,
33480 _params[d.id][fromTo].width,
33486 function calcAnimationParams(selection2) {
33487 selection2.call(reset).each(function(d) {
33488 var s = select_default2(this);
33489 var tag = s.node().tagName;
33490 var p = { "from": {}, "to": {} };
33493 if (tag === "circle") {
33494 opacity = Number(s.style("fill-opacity") || 0.5);
33495 width = Number(s.style("r") || 15.5);
33497 opacity = Number(s.style("stroke-opacity") || 0.7);
33498 width = Number(s.style("stroke-width") || 10);
33501 p.from.opacity = opacity * 0.6;
33502 p.to.opacity = opacity * 1.25;
33503 p.from.width = width * 0.7;
33504 p.to.width = width * (tag === "circle" ? 1.5 : 1);
33508 function run(surface, fromTo) {
33509 var toFrom = fromTo === "from" ? "to" : "from";
33510 var currSelected = surface.selectAll(selector);
33511 var currClassed = surface.attr("class");
33512 if (_done || currSelected.empty()) {
33513 _selected.call(reset);
33514 _selected = select_default2(null);
33517 if (!(0, import_fast_deep_equal2.default)(currSelected.data(), _selected.data()) || currClassed !== _classed) {
33518 _selected.call(reset);
33519 _classed = currClassed;
33520 _selected = currSelected.call(calcAnimationParams);
33522 var didCallNextRun = false;
33523 _selected.transition().duration(duration).call(setAnimationParams, fromTo).on("end", function() {
33524 if (!didCallNextRun) {
33525 surface.call(run, toFrom);
33526 didCallNextRun = true;
33528 if (!select_default2(this).classed("selected")) {
33529 reset(select_default2(this));
33533 function behavior(surface) {
33535 _timer = timer(function() {
33536 if (surface.selectAll(selector).empty()) {
33539 surface.call(run, "from");
33544 behavior.restartIfNeeded = function(surface) {
33545 if (_selected.empty()) {
33546 surface.call(run, "from");
33552 behavior.off = function() {
33557 _selected.interrupt().call(reset);
33562 // modules/behavior/operation.js
33563 function behaviorOperation(context) {
33565 function keypress(d3_event) {
33566 if (!context.map().withinEditableZoom())
33568 if (_operation.availableForKeypress && !_operation.availableForKeypress())
33570 d3_event.preventDefault();
33571 var disabled = _operation.disabled();
33573 context.ui().flash.duration(4e3).iconName("#iD-operation-" + _operation.id).iconClass("operation disabled").label(_operation.tooltip())();
33575 context.ui().flash.duration(2e3).iconName("#iD-operation-" + _operation.id).iconClass("operation").label(_operation.annotation() || _operation.title)();
33576 if (_operation.point)
33577 _operation.point(null);
33581 function behavior() {
33582 if (_operation && _operation.available()) {
33583 context.keybinding().on(_operation.keys, keypress);
33587 behavior.off = function() {
33588 context.keybinding().off(_operation.keys);
33590 behavior.which = function(_) {
33591 if (!arguments.length)
33599 // modules/operations/circularize.js
33600 function operationCircularize(context, selectedIDs) {
33602 var _actions = selectedIDs.map(getAction).filter(Boolean);
33603 var _amount = _actions.length === 1 ? "single" : "multiple";
33604 var _coords = utilGetAllNodes(selectedIDs, context.graph()).map(function(n2) {
33607 function getAction(entityID) {
33608 var entity = context.entity(entityID);
33609 if (entity.type !== "way" || new Set(entity.nodes).size <= 1)
33612 _extent = entity.extent(context.graph());
33614 _extent = _extent.extend(entity.extent(context.graph()));
33616 return actionCircularize(entityID, context.projection);
33618 var operation = function() {
33619 if (!_actions.length)
33621 var combinedAction = function(graph, t) {
33622 _actions.forEach(function(action) {
33623 if (!action.disabled(graph)) {
33624 graph = action(graph, t);
33629 combinedAction.transitionable = true;
33630 context.perform(combinedAction, operation.annotation());
33631 window.setTimeout(function() {
33632 context.validator().validate();
33635 operation.available = function() {
33636 return _actions.length && selectedIDs.length === _actions.length;
33638 operation.disabled = function() {
33639 if (!_actions.length)
33641 var actionDisableds = _actions.map(function(action) {
33642 return action.disabled(context.graph());
33643 }).filter(Boolean);
33644 if (actionDisableds.length === _actions.length) {
33645 if (new Set(actionDisableds).size > 1) {
33646 return "multiple_blockers";
33648 return actionDisableds[0];
33649 } else if (_extent.percentContainedIn(context.map().extent()) < 0.8) {
33650 return "too_large";
33651 } else if (someMissing()) {
33652 return "not_downloaded";
33653 } else if (selectedIDs.some(context.hasHiddenConnections)) {
33654 return "connected_to_hidden";
33657 function someMissing() {
33658 if (context.inIntro())
33660 var osm = context.connection();
33662 var missing = _coords.filter(function(loc) {
33663 return !osm.isDataLoaded(loc);
33665 if (missing.length) {
33666 missing.forEach(function(loc) {
33667 context.loadTileAtLoc(loc);
33675 operation.tooltip = function() {
33676 var disable = operation.disabled();
33677 return disable ? _t.append("operations.circularize." + disable + "." + _amount) : _t.append("operations.circularize.description." + _amount);
33679 operation.annotation = function() {
33680 return _t("operations.circularize.annotation.feature", { n: _actions.length });
33682 operation.id = "circularize";
33683 operation.keys = [_t("operations.circularize.key")];
33684 operation.title = _t.append("operations.circularize.title");
33685 operation.behavior = behaviorOperation(context).which(operation);
33689 // modules/ui/cmd.js
33690 var uiCmd = function(code) {
33691 var detected = utilDetect();
33692 if (detected.os === "mac") {
33695 if (detected.os === "win") {
33696 if (code === "\u2318\u21E7Z")
33699 var result = "", replacements = {
33703 "\u232B": "Backspace",
33706 for (var i2 = 0; i2 < code.length; i2++) {
33707 if (code[i2] in replacements) {
33708 result += replacements[code[i2]] + (i2 < code.length - 1 ? "+" : "");
33710 result += code[i2];
33715 uiCmd.display = function(code) {
33716 if (code.length !== 1)
33718 var detected = utilDetect();
33719 var mac = detected.os === "mac";
33720 var replacements = {
33721 "\u2318": mac ? "\u2318 " + _t("shortcuts.key.cmd") : _t("shortcuts.key.ctrl"),
33722 "\u21E7": mac ? "\u21E7 " + _t("shortcuts.key.shift") : _t("shortcuts.key.shift"),
33723 "\u2325": mac ? "\u2325 " + _t("shortcuts.key.option") : _t("shortcuts.key.alt"),
33724 "\u2303": mac ? "\u2303 " + _t("shortcuts.key.ctrl") : _t("shortcuts.key.ctrl"),
33725 "\u232B": mac ? "\u232B " + _t("shortcuts.key.delete") : _t("shortcuts.key.backspace"),
33726 "\u2326": mac ? "\u2326 " + _t("shortcuts.key.del") : _t("shortcuts.key.del"),
33727 "\u2196": mac ? "\u2196 " + _t("shortcuts.key.pgup") : _t("shortcuts.key.pgup"),
33728 "\u2198": mac ? "\u2198 " + _t("shortcuts.key.pgdn") : _t("shortcuts.key.pgdn"),
33729 "\u21DE": mac ? "\u21DE " + _t("shortcuts.key.home") : _t("shortcuts.key.home"),
33730 "\u21DF": mac ? "\u21DF " + _t("shortcuts.key.end") : _t("shortcuts.key.end"),
33731 "\u21B5": mac ? "\u23CE " + _t("shortcuts.key.return") : _t("shortcuts.key.enter"),
33732 "\u238B": mac ? "\u238B " + _t("shortcuts.key.esc") : _t("shortcuts.key.esc"),
33733 "\u2630": mac ? "\u2630 " + _t("shortcuts.key.menu") : _t("shortcuts.key.menu")
33735 return replacements[code] || code;
33738 // modules/operations/delete.js
33739 function operationDelete(context, selectedIDs) {
33740 var multi = selectedIDs.length === 1 ? "single" : "multiple";
33741 var action = actionDeleteMultiple(selectedIDs);
33742 var nodes = utilGetAllNodes(selectedIDs, context.graph());
33743 var coords = nodes.map(function(n2) {
33746 var extent = utilTotalExtent(selectedIDs, context.graph());
33747 var operation = function() {
33748 var nextSelectedID;
33749 var nextSelectedLoc;
33750 if (selectedIDs.length === 1) {
33751 var id2 = selectedIDs[0];
33752 var entity = context.entity(id2);
33753 var geometry = entity.geometry(context.graph());
33754 var parents = context.graph().parentWays(entity);
33755 var parent = parents[0];
33756 if (geometry === "vertex") {
33757 var nodes2 = parent.nodes;
33758 var i2 = nodes2.indexOf(id2);
33761 } else if (i2 === nodes2.length - 1) {
33764 var a = geoSphericalDistance(entity.loc, context.entity(nodes2[i2 - 1]).loc);
33765 var b = geoSphericalDistance(entity.loc, context.entity(nodes2[i2 + 1]).loc);
33766 i2 = a < b ? i2 - 1 : i2 + 1;
33768 nextSelectedID = nodes2[i2];
33769 nextSelectedLoc = context.entity(nextSelectedID).loc;
33772 context.perform(action, operation.annotation());
33773 context.validator().validate();
33774 if (nextSelectedID && nextSelectedLoc) {
33775 if (context.hasEntity(nextSelectedID)) {
33776 context.enter(modeSelect(context, [nextSelectedID]).follow(true));
33778 context.map().centerEase(nextSelectedLoc);
33779 context.enter(modeBrowse(context));
33782 context.enter(modeBrowse(context));
33785 operation.available = function() {
33788 operation.disabled = function() {
33789 if (extent.percentContainedIn(context.map().extent()) < 0.8) {
33790 return "too_large";
33791 } else if (someMissing()) {
33792 return "not_downloaded";
33793 } else if (selectedIDs.some(context.hasHiddenConnections)) {
33794 return "connected_to_hidden";
33795 } else if (selectedIDs.some(protectedMember)) {
33796 return "part_of_relation";
33797 } else if (selectedIDs.some(incompleteRelation)) {
33798 return "incomplete_relation";
33799 } else if (selectedIDs.some(hasWikidataTag)) {
33800 return "has_wikidata_tag";
33803 function someMissing() {
33804 if (context.inIntro())
33806 var osm = context.connection();
33808 var missing = coords.filter(function(loc) {
33809 return !osm.isDataLoaded(loc);
33811 if (missing.length) {
33812 missing.forEach(function(loc) {
33813 context.loadTileAtLoc(loc);
33820 function hasWikidataTag(id2) {
33821 var entity = context.entity(id2);
33822 return entity.tags.wikidata && entity.tags.wikidata.trim().length > 0;
33824 function incompleteRelation(id2) {
33825 var entity = context.entity(id2);
33826 return entity.type === "relation" && !entity.isComplete(context.graph());
33828 function protectedMember(id2) {
33829 var entity = context.entity(id2);
33830 if (entity.type !== "way")
33832 var parents = context.graph().parentRelations(entity);
33833 for (var i2 = 0; i2 < parents.length; i2++) {
33834 var parent = parents[i2];
33835 var type2 = parent.tags.type;
33836 var role = parent.memberById(id2).role || "outer";
33837 if (type2 === "route" || type2 === "boundary" || type2 === "multipolygon" && role === "outer") {
33844 operation.tooltip = function() {
33845 var disable = operation.disabled();
33846 return disable ? _t.append("operations.delete." + disable + "." + multi) : _t.append("operations.delete.description." + multi);
33848 operation.annotation = function() {
33849 return selectedIDs.length === 1 ? _t("operations.delete.annotation." + context.graph().geometry(selectedIDs[0])) : _t("operations.delete.annotation.feature", { n: selectedIDs.length });
33851 operation.id = "delete";
33852 operation.keys = [uiCmd("\u2318\u232B"), uiCmd("\u2318\u2326"), uiCmd("\u2326")];
33853 operation.title = _t.append("operations.delete.title");
33854 operation.behavior = behaviorOperation(context).which(operation);
33858 // modules/operations/orthogonalize.js
33859 function operationOrthogonalize(context, selectedIDs) {
33862 var _actions = selectedIDs.map(chooseAction).filter(Boolean);
33863 var _amount = _actions.length === 1 ? "single" : "multiple";
33864 var _coords = utilGetAllNodes(selectedIDs, context.graph()).map(function(n2) {
33867 function chooseAction(entityID) {
33868 var entity = context.entity(entityID);
33869 var geometry = entity.geometry(context.graph());
33871 _extent = entity.extent(context.graph());
33873 _extent = _extent.extend(entity.extent(context.graph()));
33875 if (entity.type === "way" && new Set(entity.nodes).size > 2) {
33876 if (_type && _type !== "feature")
33879 return actionOrthogonalize(entityID, context.projection);
33880 } else if (geometry === "vertex") {
33881 if (_type && _type !== "corner")
33884 var graph = context.graph();
33885 var parents = graph.parentWays(entity);
33886 if (parents.length === 1) {
33887 var way = parents[0];
33888 if (way.nodes.indexOf(entityID) !== -1) {
33889 return actionOrthogonalize(way.id, context.projection, entityID);
33895 var operation = function() {
33896 if (!_actions.length)
33898 var combinedAction = function(graph, t) {
33899 _actions.forEach(function(action) {
33900 if (!action.disabled(graph)) {
33901 graph = action(graph, t);
33906 combinedAction.transitionable = true;
33907 context.perform(combinedAction, operation.annotation());
33908 window.setTimeout(function() {
33909 context.validator().validate();
33912 operation.available = function() {
33913 return _actions.length && selectedIDs.length === _actions.length;
33915 operation.disabled = function() {
33916 if (!_actions.length)
33918 var actionDisableds = _actions.map(function(action) {
33919 return action.disabled(context.graph());
33920 }).filter(Boolean);
33921 if (actionDisableds.length === _actions.length) {
33922 if (new Set(actionDisableds).size > 1) {
33923 return "multiple_blockers";
33925 return actionDisableds[0];
33926 } else if (_extent && _extent.percentContainedIn(context.map().extent()) < 0.8) {
33927 return "too_large";
33928 } else if (someMissing()) {
33929 return "not_downloaded";
33930 } else if (selectedIDs.some(context.hasHiddenConnections)) {
33931 return "connected_to_hidden";
33934 function someMissing() {
33935 if (context.inIntro())
33937 var osm = context.connection();
33939 var missing = _coords.filter(function(loc) {
33940 return !osm.isDataLoaded(loc);
33942 if (missing.length) {
33943 missing.forEach(function(loc) {
33944 context.loadTileAtLoc(loc);
33952 operation.tooltip = function() {
33953 var disable = operation.disabled();
33954 return disable ? _t.append("operations.orthogonalize." + disable + "." + _amount) : _t.append("operations.orthogonalize.description." + _type + "." + _amount);
33956 operation.annotation = function() {
33957 return _t("operations.orthogonalize.annotation." + _type, { n: _actions.length });
33959 operation.id = "orthogonalize";
33960 operation.keys = [_t("operations.orthogonalize.key")];
33961 operation.title = _t.append("operations.orthogonalize.title");
33962 operation.behavior = behaviorOperation(context).which(operation);
33966 // modules/operations/reflect.js
33967 function operationReflectShort(context, selectedIDs) {
33968 return operationReflect(context, selectedIDs, "short");
33970 function operationReflectLong(context, selectedIDs) {
33971 return operationReflect(context, selectedIDs, "long");
33973 function operationReflect(context, selectedIDs, axis) {
33974 axis = axis || "long";
33975 var multi = selectedIDs.length === 1 ? "single" : "multiple";
33976 var nodes = utilGetAllNodes(selectedIDs, context.graph());
33977 var coords = nodes.map(function(n2) {
33980 var extent = utilTotalExtent(selectedIDs, context.graph());
33981 var operation = function() {
33982 var action = actionReflect(selectedIDs, context.projection).useLongAxis(Boolean(axis === "long"));
33983 context.perform(action, operation.annotation());
33984 window.setTimeout(function() {
33985 context.validator().validate();
33988 operation.available = function() {
33989 return nodes.length >= 3;
33991 operation.disabled = function() {
33992 if (extent.percentContainedIn(context.map().extent()) < 0.8) {
33993 return "too_large";
33994 } else if (someMissing()) {
33995 return "not_downloaded";
33996 } else if (selectedIDs.some(context.hasHiddenConnections)) {
33997 return "connected_to_hidden";
33998 } else if (selectedIDs.some(incompleteRelation)) {
33999 return "incomplete_relation";
34002 function someMissing() {
34003 if (context.inIntro())
34005 var osm = context.connection();
34007 var missing = coords.filter(function(loc) {
34008 return !osm.isDataLoaded(loc);
34010 if (missing.length) {
34011 missing.forEach(function(loc) {
34012 context.loadTileAtLoc(loc);
34019 function incompleteRelation(id2) {
34020 var entity = context.entity(id2);
34021 return entity.type === "relation" && !entity.isComplete(context.graph());
34024 operation.tooltip = function() {
34025 var disable = operation.disabled();
34026 return disable ? _t.append("operations.reflect." + disable + "." + multi) : _t.append("operations.reflect.description." + axis + "." + multi);
34028 operation.annotation = function() {
34029 return _t("operations.reflect.annotation." + axis + ".feature", { n: selectedIDs.length });
34031 operation.id = "reflect-" + axis;
34032 operation.keys = [_t("operations.reflect.key." + axis)];
34033 operation.title = _t.append("operations.reflect.title." + axis);
34034 operation.behavior = behaviorOperation(context).which(operation);
34038 // modules/operations/move.js
34039 function operationMove(context, selectedIDs) {
34040 var multi = selectedIDs.length === 1 ? "single" : "multiple";
34041 var nodes = utilGetAllNodes(selectedIDs, context.graph());
34042 var coords = nodes.map(function(n2) {
34045 var extent = utilTotalExtent(selectedIDs, context.graph());
34046 var operation = function() {
34047 context.enter(modeMove(context, selectedIDs));
34049 operation.available = function() {
34050 return selectedIDs.length > 0;
34052 operation.disabled = function() {
34053 if (extent.percentContainedIn(context.map().extent()) < 0.8) {
34054 return "too_large";
34055 } else if (someMissing()) {
34056 return "not_downloaded";
34057 } else if (selectedIDs.some(context.hasHiddenConnections)) {
34058 return "connected_to_hidden";
34059 } else if (selectedIDs.some(incompleteRelation)) {
34060 return "incomplete_relation";
34063 function someMissing() {
34064 if (context.inIntro())
34066 var osm = context.connection();
34068 var missing = coords.filter(function(loc) {
34069 return !osm.isDataLoaded(loc);
34071 if (missing.length) {
34072 missing.forEach(function(loc) {
34073 context.loadTileAtLoc(loc);
34080 function incompleteRelation(id2) {
34081 var entity = context.entity(id2);
34082 return entity.type === "relation" && !entity.isComplete(context.graph());
34085 operation.tooltip = function() {
34086 var disable = operation.disabled();
34087 return disable ? _t.append("operations.move." + disable + "." + multi) : _t.append("operations.move.description." + multi);
34089 operation.annotation = function() {
34090 return selectedIDs.length === 1 ? _t("operations.move.annotation." + context.graph().geometry(selectedIDs[0])) : _t("operations.move.annotation.feature", { n: selectedIDs.length });
34092 operation.id = "move";
34093 operation.keys = [_t("operations.move.key")];
34094 operation.title = _t.append("operations.move.title");
34095 operation.behavior = behaviorOperation(context).which(operation);
34096 operation.mouseOnly = true;
34100 // modules/modes/rotate.js
34101 function modeRotate(context, entityIDs) {
34102 var _tolerancePx = 4;
34107 var keybinding = utilKeybinding("rotate");
34109 behaviorEdit(context),
34110 operationCircularize(context, entityIDs).behavior,
34111 operationDelete(context, entityIDs).behavior,
34112 operationMove(context, entityIDs).behavior,
34113 operationOrthogonalize(context, entityIDs).behavior,
34114 operationReflectLong(context, entityIDs).behavior,
34115 operationReflectShort(context, entityIDs).behavior
34117 var annotation = entityIDs.length === 1 ? _t("operations.rotate.annotation." + context.graph().geometry(entityIDs[0])) : _t("operations.rotate.annotation.feature", { n: entityIDs.length });
34120 var _prevTransform;
34122 var _pointerPrefix = "PointerEvent" in window ? "pointer" : "mouse";
34123 function doRotate(d3_event) {
34125 if (context.graph() !== _prevGraph) {
34126 fn = context.perform;
34128 fn = context.replace;
34130 var projection2 = context.projection;
34131 var currTransform = projection2.transform();
34132 if (!_prevTransform || currTransform.k !== _prevTransform.k || currTransform.x !== _prevTransform.x || currTransform.y !== _prevTransform.y) {
34133 var nodes = utilGetAllNodes(entityIDs, context.graph());
34134 var points = nodes.map(function(n2) {
34135 return projection2(n2.loc);
34137 _pivot = getPivot(points);
34138 _prevAngle = void 0;
34140 var currMouse = context.map().mouse(d3_event);
34141 var currAngle = Math.atan2(currMouse[1] - _pivot[1], currMouse[0] - _pivot[0]);
34142 if (typeof _prevAngle === "undefined")
34143 _prevAngle = currAngle;
34144 var delta = currAngle - _prevAngle;
34145 fn(actionRotate(entityIDs, _pivot, delta, projection2));
34146 _prevTransform = currTransform;
34147 _prevAngle = currAngle;
34148 _prevGraph = context.graph();
34150 function getPivot(points) {
34152 if (points.length === 1) {
34153 _pivot2 = points[0];
34154 } else if (points.length === 2) {
34155 _pivot2 = geoVecInterp(points[0], points[1], 0.5);
34157 var polygonHull = hull_default(points);
34158 if (polygonHull.length === 2) {
34159 _pivot2 = geoVecInterp(points[0], points[1], 0.5);
34161 _pivot2 = centroid_default2(hull_default(points));
34166 function finish(d3_event) {
34167 d3_event.stopPropagation();
34168 context.replace(actionNoop(), annotation);
34169 context.enter(modeSelect(context, entityIDs));
34171 function cancel() {
34174 context.enter(modeSelect(context, entityIDs));
34176 function undone() {
34177 context.enter(modeBrowse(context));
34179 mode.enter = function() {
34181 context.features().forceVisible(entityIDs);
34182 behaviors.forEach(context.install);
34184 context.surface().on(_pointerPrefix + "down.modeRotate", function(d3_event) {
34185 downEvent = d3_event;
34187 select_default2(window).on(_pointerPrefix + "move.modeRotate", doRotate, true).on(_pointerPrefix + "up.modeRotate", function(d3_event) {
34190 var mapNode = context.container().select(".main-map").node();
34191 var pointGetter = utilFastMouse(mapNode);
34192 var p1 = pointGetter(downEvent);
34193 var p2 = pointGetter(d3_event);
34194 var dist = geoVecLength(p1, p2);
34195 if (dist <= _tolerancePx)
34199 context.history().on("undone.modeRotate", undone);
34200 keybinding.on("\u238B", cancel).on("\u21A9", finish);
34201 select_default2(document).call(keybinding);
34203 mode.exit = function() {
34204 behaviors.forEach(context.uninstall);
34205 context.surface().on(_pointerPrefix + "down.modeRotate", null);
34206 select_default2(window).on(_pointerPrefix + "move.modeRotate", null, true).on(_pointerPrefix + "up.modeRotate", null, true);
34207 context.history().on("undone.modeRotate", null);
34208 select_default2(document).call(keybinding.unbind);
34209 context.features().forceVisible([]);
34211 mode.selectedIDs = function() {
34212 if (!arguments.length)
34219 // modules/operations/rotate.js
34220 function operationRotate(context, selectedIDs) {
34221 var multi = selectedIDs.length === 1 ? "single" : "multiple";
34222 var nodes = utilGetAllNodes(selectedIDs, context.graph());
34223 var coords = nodes.map(function(n2) {
34226 var extent = utilTotalExtent(selectedIDs, context.graph());
34227 var operation = function() {
34228 context.enter(modeRotate(context, selectedIDs));
34230 operation.available = function() {
34231 return nodes.length >= 2;
34233 operation.disabled = function() {
34234 if (extent.percentContainedIn(context.map().extent()) < 0.8) {
34235 return "too_large";
34236 } else if (someMissing()) {
34237 return "not_downloaded";
34238 } else if (selectedIDs.some(context.hasHiddenConnections)) {
34239 return "connected_to_hidden";
34240 } else if (selectedIDs.some(incompleteRelation)) {
34241 return "incomplete_relation";
34244 function someMissing() {
34245 if (context.inIntro())
34247 var osm = context.connection();
34249 var missing = coords.filter(function(loc) {
34250 return !osm.isDataLoaded(loc);
34252 if (missing.length) {
34253 missing.forEach(function(loc) {
34254 context.loadTileAtLoc(loc);
34261 function incompleteRelation(id2) {
34262 var entity = context.entity(id2);
34263 return entity.type === "relation" && !entity.isComplete(context.graph());
34266 operation.tooltip = function() {
34267 var disable = operation.disabled();
34268 return disable ? _t.append("operations.rotate." + disable + "." + multi) : _t.append("operations.rotate.description." + multi);
34270 operation.annotation = function() {
34271 return selectedIDs.length === 1 ? _t("operations.rotate.annotation." + context.graph().geometry(selectedIDs[0])) : _t("operations.rotate.annotation.feature", { n: selectedIDs.length });
34273 operation.id = "rotate";
34274 operation.keys = [_t("operations.rotate.key")];
34275 operation.title = _t.append("operations.rotate.title");
34276 operation.behavior = behaviorOperation(context).which(operation);
34277 operation.mouseOnly = true;
34281 // modules/modes/move.js
34282 function modeMove(context, entityIDs, baseGraph) {
34283 var _tolerancePx = 4;
34288 var keybinding = utilKeybinding("move");
34290 behaviorEdit(context),
34291 operationCircularize(context, entityIDs).behavior,
34292 operationDelete(context, entityIDs).behavior,
34293 operationOrthogonalize(context, entityIDs).behavior,
34294 operationReflectLong(context, entityIDs).behavior,
34295 operationReflectShort(context, entityIDs).behavior,
34296 operationRotate(context, entityIDs).behavior
34298 var annotation = entityIDs.length === 1 ? _t("operations.move.annotation." + context.graph().geometry(entityIDs[0])) : _t("operations.move.annotation.feature", { n: entityIDs.length });
34302 var _nudgeInterval;
34303 var _pointerPrefix = "PointerEvent" in window ? "pointer" : "mouse";
34304 function doMove(nudge) {
34305 nudge = nudge || [0, 0];
34307 if (_prevGraph !== context.graph()) {
34309 _origin = context.map().mouseCoordinates();
34310 fn = context.perform;
34312 fn = context.overwrite;
34314 var currMouse = context.map().mouse();
34315 var origMouse = context.projection(_origin);
34316 var delta = geoVecSubtract(geoVecSubtract(currMouse, origMouse), nudge);
34317 fn(actionMove(entityIDs, delta, context.projection, _cache4));
34318 _prevGraph = context.graph();
34320 function startNudge(nudge) {
34321 if (_nudgeInterval)
34322 window.clearInterval(_nudgeInterval);
34323 _nudgeInterval = window.setInterval(function() {
34324 context.map().pan(nudge);
34328 function stopNudge() {
34329 if (_nudgeInterval) {
34330 window.clearInterval(_nudgeInterval);
34331 _nudgeInterval = null;
34336 var nudge = geoViewportEdge(context.map().mouse(), context.map().dimensions());
34343 function finish(d3_event) {
34344 d3_event.stopPropagation();
34345 context.replace(actionNoop(), annotation);
34346 context.enter(modeSelect(context, entityIDs));
34349 function cancel() {
34351 while (context.graph() !== baseGraph)
34353 context.enter(modeBrowse(context));
34357 context.enter(modeSelect(context, entityIDs));
34361 function undone() {
34362 context.enter(modeBrowse(context));
34364 mode.enter = function() {
34365 _origin = context.map().mouseCoordinates();
34368 context.features().forceVisible(entityIDs);
34369 behaviors.forEach(context.install);
34371 context.surface().on(_pointerPrefix + "down.modeMove", function(d3_event) {
34372 downEvent = d3_event;
34374 select_default2(window).on(_pointerPrefix + "move.modeMove", move, true).on(_pointerPrefix + "up.modeMove", function(d3_event) {
34377 var mapNode = context.container().select(".main-map").node();
34378 var pointGetter = utilFastMouse(mapNode);
34379 var p1 = pointGetter(downEvent);
34380 var p2 = pointGetter(d3_event);
34381 var dist = geoVecLength(p1, p2);
34382 if (dist <= _tolerancePx)
34386 context.history().on("undone.modeMove", undone);
34387 keybinding.on("\u238B", cancel).on("\u21A9", finish);
34388 select_default2(document).call(keybinding);
34390 mode.exit = function() {
34392 behaviors.forEach(function(behavior) {
34393 context.uninstall(behavior);
34395 context.surface().on(_pointerPrefix + "down.modeMove", null);
34396 select_default2(window).on(_pointerPrefix + "move.modeMove", null, true).on(_pointerPrefix + "up.modeMove", null, true);
34397 context.history().on("undone.modeMove", null);
34398 select_default2(document).call(keybinding.unbind);
34399 context.features().forceVisible([]);
34401 mode.selectedIDs = function() {
34402 if (!arguments.length)
34409 // modules/behavior/paste.js
34410 function behaviorPaste(context) {
34411 function doPaste(d3_event) {
34412 if (!context.map().withinEditableZoom())
34414 d3_event.preventDefault();
34415 var baseGraph = context.graph();
34416 var mouse = context.map().mouse();
34417 var projection2 = context.projection;
34418 var viewport = geoExtent(projection2.clipExtent()).polygon();
34419 if (!geoPointInPolygon(mouse, viewport))
34421 var oldIDs = context.copyIDs();
34422 if (!oldIDs.length)
34424 var extent = geoExtent();
34425 var oldGraph = context.copyGraph();
34427 var action = actionCopyEntities(oldIDs, oldGraph);
34428 context.perform(action);
34429 var copies = action.copies();
34430 var originals = /* @__PURE__ */ new Set();
34431 Object.values(copies).forEach(function(entity) {
34432 originals.add(entity.id);
34434 for (var id2 in copies) {
34435 var oldEntity = oldGraph.entity(id2);
34436 var newEntity = copies[id2];
34437 extent._extend(oldEntity.extent(oldGraph));
34438 var parents = context.graph().parentWays(newEntity);
34439 var parentCopied = parents.some(function(parent) {
34440 return originals.has(parent.id);
34442 if (!parentCopied) {
34443 newIDs.push(newEntity.id);
34446 var copyPoint = context.copyLonLat() && projection2(context.copyLonLat()) || projection2(extent.center());
34447 var delta = geoVecSubtract(mouse, copyPoint);
34448 context.perform(actionMove(newIDs, delta, projection2));
34449 context.enter(modeMove(context, newIDs, baseGraph));
34451 function behavior() {
34452 context.keybinding().on(uiCmd("\u2318V"), doPaste);
34455 behavior.off = function() {
34456 context.keybinding().off(uiCmd("\u2318V"));
34461 // modules/behavior/drag.js
34462 function behaviorDrag() {
34463 var dispatch10 = dispatch_default("start", "move", "end");
34464 var _tolerancePx = 1;
34465 var _penTolerancePx = 4;
34466 var _origin = null;
34467 var _selector = "";
34472 var _pointerPrefix = "PointerEvent" in window ? "pointer" : "mouse";
34473 var d3_event_userSelectProperty = utilPrefixCSSProperty("UserSelect");
34474 var d3_event_userSelectSuppress = function() {
34475 var selection2 = selection_default();
34476 var select = selection2.style(d3_event_userSelectProperty);
34477 selection2.style(d3_event_userSelectProperty, "none");
34478 return function() {
34479 selection2.style(d3_event_userSelectProperty, select);
34482 function pointerdown(d3_event) {
34485 _pointerId = d3_event.pointerId || "mouse";
34486 _targetNode = this;
34487 var pointerLocGetter = utilFastMouse(_surface || _targetNode.parentNode);
34489 var startOrigin = pointerLocGetter(d3_event);
34490 var started = false;
34491 var selectEnable = d3_event_userSelectSuppress();
34492 select_default2(window).on(_pointerPrefix + "move.drag", pointermove).on(_pointerPrefix + "up.drag pointercancel.drag", pointerup, true);
34494 offset = _origin.call(_targetNode, _targetEntity);
34495 offset = [offset[0] - startOrigin[0], offset[1] - startOrigin[1]];
34499 d3_event.stopPropagation();
34500 function pointermove(d3_event2) {
34501 if (_pointerId !== (d3_event2.pointerId || "mouse"))
34503 var p = pointerLocGetter(d3_event2);
34505 var dist = geoVecLength(startOrigin, p);
34506 var tolerance = d3_event2.pointerType === "pen" ? _penTolerancePx : _tolerancePx;
34507 if (dist < tolerance)
34510 dispatch10.call("start", this, d3_event2, _targetEntity);
34513 d3_event2.stopPropagation();
34514 d3_event2.preventDefault();
34515 var dx = p[0] - startOrigin[0];
34516 var dy = p[1] - startOrigin[1];
34517 dispatch10.call("move", this, d3_event2, _targetEntity, [p[0] + offset[0], p[1] + offset[1]], [dx, dy]);
34520 function pointerup(d3_event2) {
34521 if (_pointerId !== (d3_event2.pointerId || "mouse"))
34525 dispatch10.call("end", this, d3_event2, _targetEntity);
34526 d3_event2.preventDefault();
34528 select_default2(window).on(_pointerPrefix + "move.drag", null).on(_pointerPrefix + "up.drag pointercancel.drag", null);
34532 function behavior(selection2) {
34533 var matchesSelector = utilPrefixDOMProperty("matchesSelector");
34534 var delegate = pointerdown;
34536 delegate = function(d3_event) {
34538 var target = d3_event.target;
34539 for (; target && target !== root3; target = target.parentNode) {
34540 var datum2 = target.__data__;
34541 _targetEntity = datum2 instanceof osmNote ? datum2 : datum2 && datum2.properties && datum2.properties.entity;
34542 if (_targetEntity && target[matchesSelector](_selector)) {
34543 return pointerdown.call(target, d3_event);
34548 selection2.on(_pointerPrefix + "down.drag" + _selector, delegate);
34550 behavior.off = function(selection2) {
34551 selection2.on(_pointerPrefix + "down.drag" + _selector, null);
34553 behavior.selector = function(_) {
34554 if (!arguments.length)
34559 behavior.origin = function(_) {
34560 if (!arguments.length)
34565 behavior.cancel = function() {
34566 select_default2(window).on(_pointerPrefix + "move.drag", null).on(_pointerPrefix + "up.drag pointercancel.drag", null);
34569 behavior.targetNode = function(_) {
34570 if (!arguments.length)
34571 return _targetNode;
34575 behavior.targetEntity = function(_) {
34576 if (!arguments.length)
34577 return _targetEntity;
34581 behavior.surface = function(_) {
34582 if (!arguments.length)
34587 return utilRebind(behavior, dispatch10, "on");
34590 // modules/modes/drag_node.js
34591 function modeDragNode(context) {
34596 var hover = behaviorHover(context).altDisables(true).on("hover", context.ui().sidebar.hover);
34597 var edit2 = behaviorEdit(context);
34598 var _nudgeInterval;
34599 var _restoreSelectedIDs = [];
34600 var _wasMidpoint = false;
34601 var _isCancelled = false;
34605 function startNudge(d3_event, entity, nudge) {
34606 if (_nudgeInterval)
34607 window.clearInterval(_nudgeInterval);
34608 _nudgeInterval = window.setInterval(function() {
34609 context.map().pan(nudge);
34610 doMove(d3_event, entity, nudge);
34613 function stopNudge() {
34614 if (_nudgeInterval) {
34615 window.clearInterval(_nudgeInterval);
34616 _nudgeInterval = null;
34619 function moveAnnotation(entity) {
34620 return _t("operations.move.annotation." + entity.geometry(context.graph()));
34622 function connectAnnotation(nodeEntity, targetEntity) {
34623 var nodeGeometry = nodeEntity.geometry(context.graph());
34624 var targetGeometry = targetEntity.geometry(context.graph());
34625 if (nodeGeometry === "vertex" && targetGeometry === "vertex") {
34626 var nodeParentWayIDs = context.graph().parentWays(nodeEntity);
34627 var targetParentWayIDs = context.graph().parentWays(targetEntity);
34628 var sharedParentWays = utilArrayIntersection(nodeParentWayIDs, targetParentWayIDs);
34629 if (sharedParentWays.length !== 0) {
34630 if (sharedParentWays[0].areAdjacent(nodeEntity.id, targetEntity.id)) {
34631 return _t("operations.connect.annotation.from_vertex.to_adjacent_vertex");
34633 return _t("operations.connect.annotation.from_vertex.to_sibling_vertex");
34636 return _t("operations.connect.annotation.from_" + nodeGeometry + ".to_" + targetGeometry);
34638 function shouldSnapToNode(target) {
34639 if (!_activeEntity)
34641 return _activeEntity.geometry(context.graph()) !== "vertex" || (target.geometry(context.graph()) === "vertex" || _mainPresetIndex.allowsVertex(target, context.graph()));
34643 function origin(entity) {
34644 return context.projection(entity.loc);
34646 function keydown(d3_event) {
34647 if (d3_event.keyCode === utilKeybinding.modifierCodes.alt) {
34648 if (context.surface().classed("nope")) {
34649 context.surface().classed("nope-suppressed", true);
34651 context.surface().classed("nope", false).classed("nope-disabled", true);
34654 function keyup(d3_event) {
34655 if (d3_event.keyCode === utilKeybinding.modifierCodes.alt) {
34656 if (context.surface().classed("nope-suppressed")) {
34657 context.surface().classed("nope", true);
34659 context.surface().classed("nope-suppressed", false).classed("nope-disabled", false);
34662 function start2(d3_event, entity) {
34663 _wasMidpoint = entity.type === "midpoint";
34664 var hasHidden = context.features().hasHiddenConnections(entity, context.graph());
34665 _isCancelled = !context.editable() || d3_event.shiftKey || hasHidden;
34666 if (_isCancelled) {
34668 context.ui().flash.duration(4e3).iconName("#iD-icon-no").label(_t.append("modes.drag_node.connected_to_hidden"))();
34670 return drag.cancel();
34672 if (_wasMidpoint) {
34673 var midpoint = entity;
34674 entity = osmNode();
34675 context.perform(actionAddMidpoint(midpoint, entity));
34676 entity = context.entity(entity.id);
34677 var vertex = context.surface().selectAll("." + entity.id);
34678 drag.targetNode(vertex.node()).targetEntity(entity);
34680 context.perform(actionNoop());
34682 _activeEntity = entity;
34683 _startLoc = entity.loc;
34684 hover.ignoreVertex(entity.geometry(context.graph()) === "vertex");
34685 context.surface().selectAll("." + _activeEntity.id).classed("active", true);
34686 context.enter(mode);
34688 function datum2(d3_event) {
34689 if (!d3_event || d3_event.altKey) {
34692 var d = d3_event.target.__data__;
34693 return d && d.properties && d.properties.target ? d : {};
34696 function doMove(d3_event, entity, nudge) {
34697 nudge = nudge || [0, 0];
34698 var currPoint = d3_event && d3_event.point || context.projection(_lastLoc);
34699 var currMouse = geoVecSubtract(currPoint, nudge);
34700 var loc = context.projection.invert(currMouse);
34702 if (!_nudgeInterval) {
34703 var d = datum2(d3_event);
34704 target = d && d.properties && d.properties.entity;
34705 var targetLoc = target && target.loc;
34706 var targetNodes = d && d.properties && d.properties.nodes;
34708 if (shouldSnapToNode(target)) {
34711 } else if (targetNodes) {
34712 edge = geoChooseEdge(targetNodes, context.map().mouse(), context.projection, end.id);
34719 actionMoveNode(entity.id, loc)
34721 var isInvalid = false;
34723 isInvalid = hasRelationConflict(entity, target, edge, context.graph());
34726 isInvalid = hasInvalidGeometry(entity, context.graph());
34728 var nope = context.surface().classed("nope");
34729 if (isInvalid === "relation" || isInvalid === "restriction") {
34731 context.ui().flash.duration(4e3).iconName("#iD-icon-no").label(_t.append(
34732 "operations.connect." + isInvalid,
34733 { relation: _mainPresetIndex.item("type/restriction").name() }
34736 } else if (isInvalid) {
34737 var errorID = isInvalid === "line" ? "lines" : "areas";
34738 context.ui().flash.duration(3e3).iconName("#iD-icon-no").label(_t.append("self_intersection.error." + errorID))();
34741 context.ui().flash.duration(1).label("")();
34744 var nopeDisabled = context.surface().classed("nope-disabled");
34745 if (nopeDisabled) {
34746 context.surface().classed("nope", false).classed("nope-suppressed", isInvalid);
34748 context.surface().classed("nope", isInvalid).classed("nope-suppressed", false);
34752 function hasRelationConflict(entity, target, edge, graph) {
34753 var testGraph = graph.update();
34755 var midpoint = osmNode();
34756 var action = actionAddMidpoint({
34758 edge: [target.nodes[edge.index - 1], target.nodes[edge.index]]
34760 testGraph = action(testGraph);
34763 var ids = [entity.id, target.id];
34764 return actionConnect(ids).disabled(testGraph);
34766 function hasInvalidGeometry(entity, graph) {
34767 var parents = graph.parentWays(entity);
34769 for (i2 = 0; i2 < parents.length; i2++) {
34770 var parent = parents[i2];
34772 var activeIndex = null;
34773 var relations = graph.parentRelations(parent);
34774 for (j2 = 0; j2 < relations.length; j2++) {
34775 if (!relations[j2].isMultipolygon())
34777 var rings = osmJoinWays(relations[j2].members, graph);
34778 for (k = 0; k < rings.length; k++) {
34779 nodes = rings[k].nodes;
34780 if (nodes.find(function(n2) {
34781 return n2.id === entity.id;
34784 if (geoHasSelfIntersections(nodes, entity.id)) {
34785 return "multipolygonMember";
34788 rings[k].coords = nodes.map(function(n2) {
34792 for (k = 0; k < rings.length; k++) {
34793 if (k === activeIndex)
34795 if (geoHasLineIntersections(rings[activeIndex].nodes, rings[k].nodes, entity.id)) {
34796 return "multipolygonRing";
34800 if (activeIndex === null) {
34801 nodes = parent.nodes.map(function(nodeID) {
34802 return graph.entity(nodeID);
34804 if (nodes.length && geoHasSelfIntersections(nodes, entity.id)) {
34805 return parent.geometry(graph);
34811 function move(d3_event, entity, point2) {
34814 d3_event.stopPropagation();
34815 context.surface().classed("nope-disabled", d3_event.altKey);
34816 _lastLoc = context.projection.invert(point2);
34817 doMove(d3_event, entity);
34818 var nudge = geoViewportEdge(point2, context.map().dimensions());
34820 startNudge(d3_event, entity, nudge);
34825 function end(d3_event, entity) {
34828 var wasPoint = entity.geometry(context.graph()) === "point";
34829 var d = datum2(d3_event);
34830 var nope = d && d.properties && d.properties.nope || context.surface().classed("nope");
34831 var target = d && d.properties && d.properties.entity;
34834 _actionBounceBack(entity.id, _startLoc)
34836 } else if (target && target.type === "way") {
34837 var choice = geoChooseEdge(context.graph().childNodes(target), context.map().mouse(), context.projection, entity.id);
34839 actionAddMidpoint({
34841 edge: [target.nodes[choice.index - 1], target.nodes[choice.index]]
34843 connectAnnotation(entity, target)
34845 } else if (target && target.type === "node" && shouldSnapToNode(target)) {
34847 actionConnect([target.id, entity.id]),
34848 connectAnnotation(entity, target)
34850 } else if (_wasMidpoint) {
34853 _t("operations.add.annotation.vertex")
34858 moveAnnotation(entity)
34862 context.enter(modeSelect(context, [entity.id]));
34864 var reselection = _restoreSelectedIDs.filter(function(id2) {
34865 return context.graph().hasEntity(id2);
34867 if (reselection.length) {
34868 context.enter(modeSelect(context, reselection));
34870 context.enter(modeBrowse(context));
34874 function _actionBounceBack(nodeID, toLoc) {
34875 var moveNode = actionMoveNode(nodeID, toLoc);
34876 var action = function(graph, t) {
34879 return moveNode(graph, t);
34881 action.transitionable = true;
34884 function cancel() {
34886 context.enter(modeBrowse(context));
34888 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);
34889 mode.enter = function() {
34890 context.install(hover);
34891 context.install(edit2);
34892 select_default2(window).on("keydown.dragNode", keydown).on("keyup.dragNode", keyup);
34893 context.history().on("undone.drag-node", cancel);
34895 mode.exit = function() {
34896 context.ui().sidebar.hover.cancel();
34897 context.uninstall(hover);
34898 context.uninstall(edit2);
34899 select_default2(window).on("keydown.dragNode", null).on("keyup.dragNode", null);
34900 context.history().on("undone.drag-node", null);
34901 _activeEntity = null;
34902 context.surface().classed("nope", false).classed("nope-suppressed", false).classed("nope-disabled", false).selectAll(".active").classed("active", false);
34905 mode.selectedIDs = function() {
34906 if (!arguments.length)
34907 return _activeEntity ? [_activeEntity.id] : [];
34910 mode.activeID = function() {
34911 if (!arguments.length)
34912 return _activeEntity && _activeEntity.id;
34915 mode.restoreSelectedIDs = function(_) {
34916 if (!arguments.length)
34917 return _restoreSelectedIDs;
34918 _restoreSelectedIDs = _;
34921 mode.behavior = drag;
34925 // modules/services/keepRight.js
34926 var import_rbush = __toESM(require_rbush_min());
34928 // node_modules/d3-fetch/src/text.js
34929 function responseText(response) {
34931 throw new Error(response.status + " " + response.statusText);
34932 return response.text();
34934 function text_default3(input, init2) {
34935 return fetch(input, init2).then(responseText);
34938 // node_modules/d3-fetch/src/json.js
34939 function responseJson(response) {
34941 throw new Error(response.status + " " + response.statusText);
34942 if (response.status === 204 || response.status === 205)
34944 return response.json();
34946 function json_default(input, init2) {
34947 return fetch(input, init2).then(responseJson);
34950 // node_modules/d3-fetch/src/xml.js
34951 function parser(type2) {
34952 return (input, init2) => text_default3(input, init2).then((text2) => new DOMParser().parseFromString(text2, type2));
34954 var xml_default = parser("application/xml");
34955 var html = parser("text/html");
34956 var svg = parser("image/svg+xml");
34958 // modules/services/keepRight.js
34959 var tiler = utilTiler();
34960 var dispatch2 = dispatch_default("loaded");
34961 var _tileZoom = 14;
34962 var _krUrlRoot = "https://www.keepright.at";
34963 var _krData = { errorTypes: {}, localizeStrings: {} };
34966 // no 20 - multiple node on same spot - these are mostly boundaries overlapping roads
35039 function abortRequest(controller) {
35041 controller.abort();
35044 function abortUnwantedRequests(cache, tiles) {
35045 Object.keys(cache.inflightTile).forEach((k) => {
35046 const wanted = tiles.find((tile) => k === tile.id);
35048 abortRequest(cache.inflightTile[k]);
35049 delete cache.inflightTile[k];
35053 function encodeIssueRtree(d) {
35054 return { minX: d.loc[0], minY: d.loc[1], maxX: d.loc[0], maxY: d.loc[1], data: d };
35056 function updateRtree(item, replace) {
35057 _cache.rtree.remove(item, (a, b) => a.data.id === b.data.id);
35059 _cache.rtree.insert(item);
35062 function tokenReplacements(d) {
35063 if (!(d instanceof QAItem))
35065 const replacements = {};
35066 const issueTemplate = _krData.errorTypes[d.whichType];
35067 if (!issueTemplate) {
35068 console.log("No Template: ", d.whichType);
35069 console.log(" ", d.description);
35072 if (!issueTemplate.regex)
35074 const errorRegex = new RegExp(issueTemplate.regex, "i");
35075 const errorMatch = errorRegex.exec(d.description);
35077 console.log("Unmatched: ", d.whichType);
35078 console.log(" ", d.description);
35079 console.log(" ", errorRegex);
35082 for (let i2 = 1; i2 < errorMatch.length; i2++) {
35083 let capture = errorMatch[i2];
35085 idType = "IDs" in issueTemplate ? issueTemplate.IDs[i2 - 1] : "";
35086 if (idType && capture) {
35087 capture = parseError(capture, idType);
35089 const compare = capture.toLowerCase();
35090 if (_krData.localizeStrings[compare]) {
35091 capture = _t("QA.keepRight.error_parts." + _krData.localizeStrings[compare]);
35093 capture = unescape_default(capture);
35096 replacements["var" + i2] = capture;
35098 return replacements;
35100 function parseError(capture, idType) {
35101 const compare = capture.toLowerCase();
35102 if (_krData.localizeStrings[compare]) {
35103 capture = _t("QA.keepRight.error_parts." + _krData.localizeStrings[compare]);
35107 capture = linkErrorObject2(capture);
35110 capture = linkURL(capture);
35115 capture = linkEntity2(idType + capture);
35118 capture = parse20(capture);
35121 capture = parse211(capture);
35124 capture = parse231(capture);
35127 capture = parse294(capture);
35130 capture = parse370(capture);
35134 function linkErrorObject2(d) {
35135 return { html: `<a class="error_object_link">${d}</a>` };
35137 function linkEntity2(d) {
35138 return { html: `<a class="error_entity_link">${d}</a>` };
35140 function linkURL(d) {
35141 return { html: `<a class="kr_external_link" target="_blank" href="${d}">${d}</a>` };
35143 function parse211(capture2) {
35145 const items = capture2.split(", ");
35146 items.forEach((item) => {
35147 let id2 = linkEntity2("n" + item.slice(1));
35150 return newList.join(", ");
35152 function parse231(capture2) {
35154 const items = capture2.split("),");
35155 items.forEach((item) => {
35156 const match = item.match(/\#(\d+)\((.+)\)?/);
35157 if (match !== null && match.length > 2) {
35159 linkEntity2("w" + match[1]) + " " + _t("QA.keepRight.errorTypes.231.layer", { layer: match[2] })
35163 return newList.join(", ");
35165 function parse294(capture2) {
35167 const items = capture2.split(",");
35168 items.forEach((item) => {
35169 item = item.split(" ");
35170 const role = `"${item[0]}"`;
35171 const idType2 = item[1].slice(0, 1);
35172 let id2 = item[2].slice(1);
35173 id2 = linkEntity2(idType2 + id2);
35174 newList.push(`${role} ${item[1]} ${id2}`);
35176 return newList.join(", ");
35178 function parse370(capture2) {
35181 const match = capture2.match(/\(including the name (\'.+\')\)/);
35182 if (match && match.length) {
35183 return _t("QA.keepRight.errorTypes.370.including_the_name", { name: match[1] });
35187 function parse20(capture2) {
35189 const items = capture2.split(",");
35190 items.forEach((item) => {
35191 const id2 = linkEntity2("n" + item.slice(1));
35194 return newList.join(", ");
35197 var keepRight_default = {
35198 title: "keepRight",
35200 _mainFileFetcher.get("keepRight").then((d) => _krData = d);
35204 this.event = utilRebind(this, dispatch2, "on");
35208 Object.values(_cache.inflightTile).forEach(abortRequest);
35216 rtree: new import_rbush.default()
35219 // KeepRight API: http://osm.mueschelsoft.de/keepright/interfacing.php
35220 loadIssues(projection2) {
35225 const tiles = tiler.zoomExtent([_tileZoom, _tileZoom]).getTiles(projection2);
35226 abortUnwantedRequests(_cache, tiles);
35227 tiles.forEach((tile) => {
35228 if (_cache.loadedTile[tile.id] || _cache.inflightTile[tile.id])
35230 const [left, top, right, bottom] = tile.extent.rectangle();
35231 const params = Object.assign({}, options2, { left, bottom, right, top });
35232 const url = `${_krUrlRoot}/export.php?` + utilQsString(params);
35233 const controller = new AbortController();
35234 _cache.inflightTile[tile.id] = controller;
35235 json_default(url, { signal: controller.signal }).then((data) => {
35236 delete _cache.inflightTile[tile.id];
35237 _cache.loadedTile[tile.id] = true;
35238 if (!data || !data.features || !data.features.length) {
35239 throw new Error("No Data");
35241 data.features.forEach((feature3) => {
35244 error_type: itemType,
35247 object_id: objectId,
35248 object_type: objectType,
35254 geometry: { coordinates: loc },
35255 properties: { description = "" }
35257 const issueTemplate = _krData.errorTypes[itemType];
35258 const parentIssueType = (Math.floor(itemType / 10) * 10).toString();
35259 const whichType = issueTemplate ? itemType : parentIssueType;
35260 const whichTemplate = _krData.errorTypes[whichType];
35261 switch (whichType) {
35263 description = `This feature has a FIXME tag: ${description}`;
35267 description = description.replace("A turn-", "This turn-");
35274 description = `This turn-restriction~${description}`;
35277 description = "This highway is missing a maxspeed tag";
35282 description = `This feature~${description}`;
35285 let coincident = false;
35287 let delta = coincident ? [1e-5, 0] : [0, 1e-5];
35288 loc = geoVecAdd(loc, delta);
35289 let bbox2 = geoExtent(loc).bbox();
35290 coincident = _cache.rtree.search(bbox2).length;
35291 } while (coincident);
35292 let d = new QAItem(loc, this, itemType, id2, {
35297 severity: whichTemplate.severity || "error",
35303 d.replacements = tokenReplacements(d);
35304 _cache.data[id2] = d;
35305 _cache.rtree.insert(encodeIssueRtree(d));
35307 dispatch2.call("loaded");
35309 delete _cache.inflightTile[tile.id];
35310 _cache.loadedTile[tile.id] = true;
35314 postUpdate(d, callback) {
35315 if (_cache.inflightPost[d.id]) {
35316 return callback({ message: "Error update already inflight", status: -2 }, d);
35318 const params = { schema: d.schema, id: d.id };
35320 params.st = d.newStatus;
35322 if (d.newComment !== void 0) {
35323 params.co = d.newComment;
35325 const url = `${_krUrlRoot}/comment.php?` + utilQsString(params);
35326 const controller = new AbortController();
35327 _cache.inflightPost[d.id] = controller;
35328 json_default(url, { signal: controller.signal }).finally(() => {
35329 delete _cache.inflightPost[d.id];
35330 if (d.newStatus === "ignore") {
35331 this.removeItem(d);
35332 } else if (d.newStatus === "ignore_t") {
35333 this.removeItem(d);
35334 _cache.closed[`${d.schema}:${d.id}`] = true;
35336 d = this.replaceItem(d.update({
35337 comment: d.newComment,
35338 newComment: void 0,
35346 // Get all cached QAItems covering the viewport
35347 getItems(projection2) {
35348 const viewport = projection2.clipExtent();
35349 const min3 = [viewport[0][0], viewport[1][1]];
35350 const max3 = [viewport[1][0], viewport[0][1]];
35351 const bbox2 = geoExtent(projection2.invert(min3), projection2.invert(max3)).bbox();
35352 return _cache.rtree.search(bbox2).map((d) => d.data);
35354 // Get a QAItem from cache
35355 // NOTE: Don't change method name until UI v3 is merged
35357 return _cache.data[id2];
35359 // Replace a single QAItem in the cache
35360 replaceItem(item) {
35361 if (!(item instanceof QAItem) || !item.id)
35363 _cache.data[item.id] = item;
35364 updateRtree(encodeIssueRtree(item), true);
35367 // Remove a single QAItem from the cache
35369 if (!(item instanceof QAItem) || !item.id)
35371 delete _cache.data[item.id];
35372 updateRtree(encodeIssueRtree(item), false);
35375 return `${_krUrlRoot}/report_map.php?schema=${item.schema}&error=${item.id}`;
35377 // Get an array of issues closed during this session.
35378 // Used to populate `closed:keepright` changeset tag
35380 return Object.keys(_cache.closed).sort();
35384 // modules/services/improveOSM.js
35385 var import_rbush2 = __toESM(require_rbush_min());
35386 var tiler2 = utilTiler();
35387 var dispatch3 = dispatch_default("loaded");
35388 var _tileZoom2 = 14;
35389 var _impOsmUrls = {
35390 ow: "https://grab.community.improve-osm.org/directionOfFlowService",
35391 mr: "https://grab.community.improve-osm.org/missingGeoService",
35392 tr: "https://grab.community.improve-osm.org/turnRestrictionService"
35394 var _impOsmData = { icons: {} };
35396 function abortRequest2(i2) {
35397 Object.values(i2).forEach((controller) => {
35399 controller.abort();
35403 function abortUnwantedRequests2(cache, tiles) {
35404 Object.keys(cache.inflightTile).forEach((k) => {
35405 const wanted = tiles.find((tile) => k === tile.id);
35407 abortRequest2(cache.inflightTile[k]);
35408 delete cache.inflightTile[k];
35412 function encodeIssueRtree2(d) {
35413 return { minX: d.loc[0], minY: d.loc[1], maxX: d.loc[0], maxY: d.loc[1], data: d };
35415 function updateRtree2(item, replace) {
35416 _cache2.rtree.remove(item, (a, b) => a.data.id === b.data.id);
35418 _cache2.rtree.insert(item);
35421 function linkErrorObject(d) {
35422 return { html: `<a class="error_object_link">${d}</a>` };
35424 function linkEntity(d) {
35425 return { html: `<a class="error_entity_link">${d}</a>` };
35427 function pointAverage(points) {
35428 if (points.length) {
35429 const sum = points.reduce(
35430 (acc, point2) => geoVecAdd(acc, [point2.lon, point2.lat]),
35433 return geoVecScale(sum, 1 / points.length);
35438 function relativeBearing(p1, p2) {
35439 let angle2 = Math.atan2(p2.lon - p1.lon, p2.lat - p1.lat);
35441 angle2 += 2 * Math.PI;
35443 return angle2 * 180 / Math.PI;
35445 function cardinalDirection(bearing) {
35446 const dir = 45 * Math.round(bearing / 45);
35458 return _t(`QA.improveOSM.directions.${compass[dir]}`);
35460 function preventCoincident(loc, bumpUp) {
35461 let coincident = false;
35463 let delta = coincident ? [1e-5, 0] : bumpUp ? [0, 1e-5] : [0, 0];
35464 loc = geoVecAdd(loc, delta);
35465 let bbox2 = geoExtent(loc).bbox();
35466 coincident = _cache2.rtree.search(bbox2).length;
35467 } while (coincident);
35470 var improveOSM_default = {
35471 title: "improveOSM",
35473 _mainFileFetcher.get("qa_data").then((d) => _impOsmData = d.improveOSM);
35477 this.event = utilRebind(this, dispatch3, "on");
35481 Object.values(_cache2.inflightTile).forEach(abortRequest2);
35489 rtree: new import_rbush2.default()
35492 loadIssues(projection2) {
35497 // Use a high zoom so that clusters aren't returned
35499 const tiles = tiler2.zoomExtent([_tileZoom2, _tileZoom2]).getTiles(projection2);
35500 abortUnwantedRequests2(_cache2, tiles);
35501 tiles.forEach((tile) => {
35502 if (_cache2.loadedTile[tile.id] || _cache2.inflightTile[tile.id])
35504 const [east, north, west, south] = tile.extent.rectangle();
35505 const params = Object.assign({}, options2, { east, south, west, north });
35506 const requests = {};
35507 Object.keys(_impOsmUrls).forEach((k) => {
35508 const kParams = Object.assign(
35511 k === "mr" ? { type: "PARKING,ROAD,BOTH,PATH" } : { confidenceLevel: "C1" }
35513 const url = `${_impOsmUrls[k]}/search?` + utilQsString(kParams);
35514 const controller = new AbortController();
35515 requests[k] = controller;
35516 json_default(url, { signal: controller.signal }).then((data) => {
35517 delete _cache2.inflightTile[tile.id][k];
35518 if (!Object.keys(_cache2.inflightTile[tile.id]).length) {
35519 delete _cache2.inflightTile[tile.id];
35520 _cache2.loadedTile[tile.id] = true;
35522 if (data.roadSegments) {
35523 data.roadSegments.forEach((feature3) => {
35524 const { points, wayId, fromNodeId, toNodeId } = feature3;
35525 const itemId = `${wayId}${fromNodeId}${toNodeId}`;
35526 let mid = points.length / 2;
35528 if (mid % 1 === 0) {
35529 loc = pointAverage([points[mid - 1], points[mid]]);
35531 mid = points[Math.floor(mid)];
35532 loc = [mid.lon, mid.lat];
35534 loc = preventCoincident(loc, false);
35535 let d = new QAItem(loc, this, k, itemId, {
35537 // used as a category
35539 // used to post changes
35548 percentage: feature3.percentOfTrips,
35549 num_trips: feature3.numberOfTrips,
35550 highway: linkErrorObject(_t("QA.keepRight.error_parts.highway")),
35551 from_node: linkEntity("n" + feature3.fromNodeId),
35552 to_node: linkEntity("n" + feature3.toNodeId)
35554 _cache2.data[d.id] = d;
35555 _cache2.rtree.insert(encodeIssueRtree2(d));
35559 data.tiles.forEach((feature3) => {
35560 const { type: type2, x, y, numberOfTrips } = feature3;
35561 const geoType = type2.toLowerCase();
35562 const itemId = `${geoType}${x}${y}${numberOfTrips}`;
35563 let loc = pointAverage(feature3.points);
35564 loc = preventCoincident(loc, false);
35565 let d = new QAItem(loc, this, `${k}-${geoType}`, itemId, {
35567 identifier: { x, y }
35570 num_trips: numberOfTrips,
35571 geometry_type: _t(`QA.improveOSM.geometry_types.${geoType}`)
35573 if (numberOfTrips === -1) {
35574 d.desc = _t("QA.improveOSM.error_types.mr.description_alt", d.replacements);
35576 _cache2.data[d.id] = d;
35577 _cache2.rtree.insert(encodeIssueRtree2(d));
35580 if (data.entities) {
35581 data.entities.forEach((feature3) => {
35582 const { point: point2, id: id2, segments, numberOfPasses, turnType } = feature3;
35583 const itemId = `${id2.replace(/[,:+#]/g, "_")}`;
35584 const loc = preventCoincident([point2.lon, point2.lat], true);
35585 const ids = id2.split(",");
35586 const from_way = ids[0];
35587 const via_node = ids[3];
35588 const to_way = ids[2].split(":")[1];
35589 let d = new QAItem(loc, this, k, itemId, {
35592 objectId: via_node,
35595 const [p1, p2] = segments[0].points;
35596 const dir_of_travel = cardinalDirection(relativeBearing(p1, p2));
35598 num_passed: numberOfPasses,
35599 num_trips: segments[0].numberOfTrips,
35600 turn_restriction: turnType.toLowerCase(),
35601 from_way: linkEntity("w" + from_way),
35602 to_way: linkEntity("w" + to_way),
35603 travel_direction: dir_of_travel,
35604 junction: linkErrorObject(_t("QA.keepRight.error_parts.this_node"))
35606 _cache2.data[d.id] = d;
35607 _cache2.rtree.insert(encodeIssueRtree2(d));
35608 dispatch3.call("loaded");
35612 delete _cache2.inflightTile[tile.id][k];
35613 if (!Object.keys(_cache2.inflightTile[tile.id]).length) {
35614 delete _cache2.inflightTile[tile.id];
35615 _cache2.loadedTile[tile.id] = true;
35619 _cache2.inflightTile[tile.id] = requests;
35622 getComments(item) {
35623 if (item.comments) {
35624 return Promise.resolve(item);
35626 const key = item.issueKey;
35628 if (key === "ow") {
35629 qParams = item.identifier;
35630 } else if (key === "mr") {
35631 qParams.tileX = item.identifier.x;
35632 qParams.tileY = item.identifier.y;
35633 } else if (key === "tr") {
35634 qParams.targetId = item.identifier;
35636 const url = `${_impOsmUrls[key]}/retrieveComments?` + utilQsString(qParams);
35637 const cacheComments = (data) => {
35638 item.comments = data.comments ? data.comments.reverse() : [];
35639 this.replaceItem(item);
35641 return json_default(url).then(cacheComments).then(() => item);
35643 postUpdate(d, callback) {
35644 if (!osm_default.authenticated()) {
35645 return callback({ message: "Not Authenticated", status: -3 }, d);
35647 if (_cache2.inflightPost[d.id]) {
35648 return callback({ message: "Error update already inflight", status: -2 }, d);
35650 osm_default.userDetails(sendPayload.bind(this));
35651 function sendPayload(err, user) {
35653 return callback(err, d);
35655 const key = d.issueKey;
35656 const url = `${_impOsmUrls[key]}/comment`;
35658 username: user.display_name,
35659 targetIds: [d.identifier]
35662 payload.status = d.newStatus;
35663 payload.text = "status changed";
35665 if (d.newComment) {
35666 payload.text = d.newComment;
35668 const controller = new AbortController();
35669 _cache2.inflightPost[d.id] = controller;
35672 signal: controller.signal,
35673 body: JSON.stringify(payload)
35675 json_default(url, options2).then(() => {
35676 delete _cache2.inflightPost[d.id];
35677 if (!d.newStatus) {
35678 const now3 = /* @__PURE__ */ new Date();
35679 let comments = d.comments ? d.comments : [];
35681 username: payload.username,
35682 text: payload.text,
35683 timestamp: now3.getTime() / 1e3
35685 this.replaceItem(d.update({
35690 this.removeItem(d);
35691 if (d.newStatus === "SOLVED") {
35692 if (!(d.issueKey in _cache2.closed)) {
35693 _cache2.closed[d.issueKey] = 0;
35695 _cache2.closed[d.issueKey] += 1;
35700 }).catch((err2) => {
35701 delete _cache2.inflightPost[d.id];
35703 callback(err2.message);
35707 // Get all cached QAItems covering the viewport
35708 getItems(projection2) {
35709 const viewport = projection2.clipExtent();
35710 const min3 = [viewport[0][0], viewport[1][1]];
35711 const max3 = [viewport[1][0], viewport[0][1]];
35712 const bbox2 = geoExtent(projection2.invert(min3), projection2.invert(max3)).bbox();
35713 return _cache2.rtree.search(bbox2).map((d) => d.data);
35715 // Get a QAItem from cache
35716 // NOTE: Don't change method name until UI v3 is merged
35718 return _cache2.data[id2];
35720 // get the name of the icon to display for this item
35721 getIcon(itemType) {
35722 return _impOsmData.icons[itemType];
35724 // Replace a single QAItem in the cache
35725 replaceItem(issue) {
35726 if (!(issue instanceof QAItem) || !issue.id)
35728 _cache2.data[issue.id] = issue;
35729 updateRtree2(encodeIssueRtree2(issue), true);
35732 // Remove a single QAItem from the cache
35733 removeItem(issue) {
35734 if (!(issue instanceof QAItem) || !issue.id)
35736 delete _cache2.data[issue.id];
35737 updateRtree2(encodeIssueRtree2(issue), false);
35739 // Used to populate `closed:improveosm:*` changeset tags
35740 getClosedCounts() {
35741 return _cache2.closed;
35745 // modules/services/osmose.js
35746 var import_rbush3 = __toESM(require_rbush_min());
35748 // node_modules/marked/lib/marked.esm.js
35749 function getDefaults() {
35759 langPrefix: "language-",
35766 smartypants: false,
35772 var defaults = getDefaults();
35773 function changeDefaults(newDefaults) {
35774 defaults = newDefaults;
35776 var escapeTest = /[&<>"']/;
35777 var escapeReplace = /[&<>"']/g;
35778 var escapeTestNoEncode = /[<>"']|&(?!#?\w+;)/;
35779 var escapeReplaceNoEncode = /[<>"']|&(?!#?\w+;)/g;
35780 var escapeReplacements = {
35787 var getEscapeReplacement = (ch) => escapeReplacements[ch];
35788 function escape4(html2, encode) {
35790 if (escapeTest.test(html2)) {
35791 return html2.replace(escapeReplace, getEscapeReplacement);
35794 if (escapeTestNoEncode.test(html2)) {
35795 return html2.replace(escapeReplaceNoEncode, getEscapeReplacement);
35800 var unescapeTest = /&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig;
35801 function unescape3(html2) {
35802 return html2.replace(unescapeTest, (_, n2) => {
35803 n2 = n2.toLowerCase();
35804 if (n2 === "colon")
35806 if (n2.charAt(0) === "#") {
35807 return n2.charAt(1) === "x" ? String.fromCharCode(parseInt(n2.substring(2), 16)) : String.fromCharCode(+n2.substring(1));
35812 var caret = /(^|[^\[])\^/g;
35813 function edit(regex, opt) {
35814 regex = typeof regex === "string" ? regex : regex.source;
35817 replace: (name, val) => {
35818 val = val.source || val;
35819 val = val.replace(caret, "$1");
35820 regex = regex.replace(name, val);
35824 return new RegExp(regex, opt);
35829 var nonWordAndColonTest = /[^\w:]/g;
35830 var originIndependentUrl = /^$|^[a-z][a-z0-9+.-]*:|^[?#]/i;
35831 function cleanUrl(sanitize, base, href) {
35835 prot = decodeURIComponent(unescape3(href)).replace(nonWordAndColonTest, "").toLowerCase();
35839 if (prot.indexOf("javascript:") === 0 || prot.indexOf("vbscript:") === 0 || prot.indexOf("data:") === 0) {
35843 if (base && !originIndependentUrl.test(href)) {
35844 href = resolveUrl(base, href);
35847 href = encodeURI(href).replace(/%25/g, "%");
35854 var justDomain = /^[^:]+:\/*[^/]*$/;
35855 var protocol = /^([^:]+:)[\s\S]*$/;
35856 var domain = /^([^:]+:\/*[^/]*)[\s\S]*$/;
35857 function resolveUrl(base, href) {
35858 if (!baseUrls[" " + base]) {
35859 if (justDomain.test(base)) {
35860 baseUrls[" " + base] = base + "/";
35862 baseUrls[" " + base] = rtrim(base, "/", true);
35865 base = baseUrls[" " + base];
35866 const relativeBase = base.indexOf(":") === -1;
35867 if (href.substring(0, 2) === "//") {
35868 if (relativeBase) {
35871 return base.replace(protocol, "$1") + href;
35872 } else if (href.charAt(0) === "/") {
35873 if (relativeBase) {
35876 return base.replace(domain, "$1") + href;
35878 return base + href;
35881 var noopTest = { exec: function noopTest2() {
35883 function merge2(obj) {
35884 let i2 = 1, target, key;
35885 for (; i2 < arguments.length; i2++) {
35886 target = arguments[i2];
35887 for (key in target) {
35888 if (Object.prototype.hasOwnProperty.call(target, key)) {
35889 obj[key] = target[key];
35895 function splitCells(tableRow, count) {
35896 const row = tableRow.replace(/\|/g, (match, offset, str2) => {
35897 let escaped = false, curr = offset;
35898 while (--curr >= 0 && str2[curr] === "\\")
35899 escaped = !escaped;
35905 }), cells = row.split(/ \|/);
35907 if (!cells[0].trim()) {
35910 if (cells.length > 0 && !cells[cells.length - 1].trim()) {
35913 if (cells.length > count) {
35914 cells.splice(count);
35916 while (cells.length < count)
35919 for (; i2 < cells.length; i2++) {
35920 cells[i2] = cells[i2].trim().replace(/\\\|/g, "|");
35924 function rtrim(str2, c, invert) {
35925 const l = str2.length;
35930 while (suffLen < l) {
35931 const currChar = str2.charAt(l - suffLen - 1);
35932 if (currChar === c && !invert) {
35934 } else if (currChar !== c && invert) {
35940 return str2.slice(0, l - suffLen);
35942 function findClosingBracket(str2, b) {
35943 if (str2.indexOf(b[1]) === -1) {
35946 const l = str2.length;
35947 let level = 0, i2 = 0;
35948 for (; i2 < l; i2++) {
35949 if (str2[i2] === "\\") {
35951 } else if (str2[i2] === b[0]) {
35953 } else if (str2[i2] === b[1]) {
35962 function checkSanitizeDeprecation(opt) {
35963 if (opt && opt.sanitize && !opt.silent) {
35964 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");
35967 function repeatString(pattern, count) {
35972 while (count > 1) {
35977 pattern += pattern;
35979 return result + pattern;
35981 function outputLink(cap, link2, raw, lexer2) {
35982 const href = link2.href;
35983 const title = link2.title ? escape4(link2.title) : null;
35984 const text2 = cap[1].replace(/\\([\[\]])/g, "$1");
35985 if (cap[0].charAt(0) !== "!") {
35986 lexer2.state.inLink = true;
35993 tokens: lexer2.inlineTokens(text2)
35995 lexer2.state.inLink = false;
36003 text: escape4(text2)
36006 function indentCodeCompensation(raw, text2) {
36007 const matchIndentToCode = raw.match(/^(\s+)(?:```)/);
36008 if (matchIndentToCode === null) {
36011 const indentToCode = matchIndentToCode[1];
36012 return text2.split("\n").map((node) => {
36013 const matchIndentInNode = node.match(/^\s+/);
36014 if (matchIndentInNode === null) {
36017 const [indentInNode] = matchIndentInNode;
36018 if (indentInNode.length >= indentToCode.length) {
36019 return node.slice(indentToCode.length);
36024 var Tokenizer = class {
36025 constructor(options2) {
36026 this.options = options2 || defaults;
36029 const cap = this.rules.block.newline.exec(src);
36030 if (cap && cap[0].length > 0) {
36038 const cap = this.rules.block.code.exec(src);
36040 const text2 = cap[0].replace(/^ {1,4}/gm, "");
36044 codeBlockStyle: "indented",
36045 text: !this.options.pedantic ? rtrim(text2, "\n") : text2
36050 const cap = this.rules.block.fences.exec(src);
36052 const raw = cap[0];
36053 const text2 = indentCodeCompensation(raw, cap[3] || "");
36057 lang: cap[2] ? cap[2].trim().replace(this.rules.inline._escapes, "$1") : cap[2],
36063 const cap = this.rules.block.heading.exec(src);
36065 let text2 = cap[2].trim();
36066 if (/#$/.test(text2)) {
36067 const trimmed = rtrim(text2, "#");
36068 if (this.options.pedantic) {
36069 text2 = trimmed.trim();
36070 } else if (!trimmed || / $/.test(trimmed)) {
36071 text2 = trimmed.trim();
36077 depth: cap[1].length,
36079 tokens: this.lexer.inline(text2)
36084 const cap = this.rules.block.hr.exec(src);
36093 const cap = this.rules.block.blockquote.exec(src);
36095 const text2 = cap[0].replace(/^ *>[ \t]?/gm, "");
36097 type: "blockquote",
36099 tokens: this.lexer.blockTokens(text2, []),
36105 let cap = this.rules.block.list.exec(src);
36107 let raw, istask, ischecked, indent2, i2, blankLine, endsWithBlankLine, line, nextLine, rawLine, itemContents, endEarly;
36108 let bull = cap[1].trim();
36109 const isordered = bull.length > 1;
36113 ordered: isordered,
36114 start: isordered ? +bull.slice(0, -1) : "",
36118 bull = isordered ? `\\d{1,9}\\${bull.slice(-1)}` : `\\${bull}`;
36119 if (this.options.pedantic) {
36120 bull = isordered ? bull : "[*+-]";
36122 const itemRegex = new RegExp(`^( {0,3}${bull})((?:[ ][^\\n]*)?(?:\\n|$))`);
36125 if (!(cap = itemRegex.exec(src))) {
36128 if (this.rules.block.hr.test(src)) {
36132 src = src.substring(raw.length);
36133 line = cap[2].split("\n", 1)[0];
36134 nextLine = src.split("\n", 1)[0];
36135 if (this.options.pedantic) {
36137 itemContents = line.trimLeft();
36139 indent2 = cap[2].search(/[^ ]/);
36140 indent2 = indent2 > 4 ? 1 : indent2;
36141 itemContents = line.slice(indent2);
36142 indent2 += cap[1].length;
36145 if (!line && /^ *$/.test(nextLine)) {
36146 raw += nextLine + "\n";
36147 src = src.substring(nextLine.length + 1);
36151 const nextBulletRegex = new RegExp(`^ {0,${Math.min(3, indent2 - 1)}}(?:[*+-]|\\d{1,9}[.)])((?: [^\\n]*)?(?:\\n|$))`);
36152 const hrRegex = new RegExp(`^ {0,${Math.min(3, indent2 - 1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`);
36153 const fencesBeginRegex = new RegExp(`^ {0,${Math.min(3, indent2 - 1)}}(?:\`\`\`|~~~)`);
36154 const headingBeginRegex = new RegExp(`^ {0,${Math.min(3, indent2 - 1)}}#`);
36156 rawLine = src.split("\n", 1)[0];
36158 if (this.options.pedantic) {
36159 line = line.replace(/^ {1,4}(?=( {4})*[^ ])/g, " ");
36161 if (fencesBeginRegex.test(line)) {
36164 if (headingBeginRegex.test(line)) {
36167 if (nextBulletRegex.test(line)) {
36170 if (hrRegex.test(src)) {
36173 if (line.search(/[^ ]/) >= indent2 || !line.trim()) {
36174 itemContents += "\n" + line.slice(indent2);
36175 } else if (!blankLine) {
36176 itemContents += "\n" + line;
36180 if (!blankLine && !line.trim()) {
36183 raw += rawLine + "\n";
36184 src = src.substring(rawLine.length + 1);
36188 if (endsWithBlankLine) {
36190 } else if (/\n *\n *$/.test(raw)) {
36191 endsWithBlankLine = true;
36194 if (this.options.gfm) {
36195 istask = /^\[[ xX]\] /.exec(itemContents);
36197 ischecked = istask[0] !== "[ ] ";
36198 itemContents = itemContents.replace(/^\[[ xX]\] +/, "");
36205 checked: ischecked,
36211 list.items[list.items.length - 1].raw = raw.trimRight();
36212 list.items[list.items.length - 1].text = itemContents.trimRight();
36213 list.raw = list.raw.trimRight();
36214 const l = list.items.length;
36215 for (i2 = 0; i2 < l; i2++) {
36216 this.lexer.state.top = false;
36217 list.items[i2].tokens = this.lexer.blockTokens(list.items[i2].text, []);
36218 const spacers = list.items[i2].tokens.filter((t) => t.type === "space");
36219 const hasMultipleLineBreaks = spacers.every((t) => {
36220 const chars = t.raw.split("");
36221 let lineBreaks = 0;
36222 for (const char of chars) {
36223 if (char === "\n") {
36226 if (lineBreaks > 1) {
36232 if (!list.loose && spacers.length && hasMultipleLineBreaks) {
36234 list.items[i2].loose = true;
36241 const cap = this.rules.block.html.exec(src);
36246 pre: !this.options.sanitizer && (cap[1] === "pre" || cap[1] === "script" || cap[1] === "style"),
36249 if (this.options.sanitize) {
36250 const text2 = this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape4(cap[0]);
36251 token.type = "paragraph";
36252 token.text = text2;
36253 token.tokens = this.lexer.inline(text2);
36259 const cap = this.rules.block.def.exec(src);
36262 cap[3] = cap[3].substring(1, cap[3].length - 1);
36263 const tag = cap[1].toLowerCase().replace(/\s+/g, " ");
36268 href: cap[2] ? cap[2].replace(this.rules.inline._escapes, "$1") : cap[2],
36269 title: cap[3] ? cap[3].replace(this.rules.inline._escapes, "$1") : cap[3]
36274 const cap = this.rules.block.table.exec(src);
36278 header: splitCells(cap[1]).map((c) => {
36279 return { text: c };
36281 align: cap[2].replace(/^ *|\| *$/g, "").split(/ *\| */),
36282 rows: cap[3] && cap[3].trim() ? cap[3].replace(/\n[ \t]*$/, "").split("\n") : []
36284 if (item.header.length === item.align.length) {
36286 let l = item.align.length;
36287 let i2, j2, k, row;
36288 for (i2 = 0; i2 < l; i2++) {
36289 if (/^ *-+: *$/.test(item.align[i2])) {
36290 item.align[i2] = "right";
36291 } else if (/^ *:-+: *$/.test(item.align[i2])) {
36292 item.align[i2] = "center";
36293 } else if (/^ *:-+ *$/.test(item.align[i2])) {
36294 item.align[i2] = "left";
36296 item.align[i2] = null;
36299 l = item.rows.length;
36300 for (i2 = 0; i2 < l; i2++) {
36301 item.rows[i2] = splitCells(item.rows[i2], item.header.length).map((c) => {
36302 return { text: c };
36305 l = item.header.length;
36306 for (j2 = 0; j2 < l; j2++) {
36307 item.header[j2].tokens = this.lexer.inline(item.header[j2].text);
36309 l = item.rows.length;
36310 for (j2 = 0; j2 < l; j2++) {
36311 row = item.rows[j2];
36312 for (k = 0; k < row.length; k++) {
36313 row[k].tokens = this.lexer.inline(row[k].text);
36321 const cap = this.rules.block.lheading.exec(src);
36326 depth: cap[2].charAt(0) === "=" ? 1 : 2,
36328 tokens: this.lexer.inline(cap[1])
36333 const cap = this.rules.block.paragraph.exec(src);
36335 const text2 = cap[1].charAt(cap[1].length - 1) === "\n" ? cap[1].slice(0, -1) : cap[1];
36340 tokens: this.lexer.inline(text2)
36345 const cap = this.rules.block.text.exec(src);
36351 tokens: this.lexer.inline(cap[0])
36356 const cap = this.rules.inline.escape.exec(src);
36361 text: escape4(cap[1])
36366 const cap = this.rules.inline.tag.exec(src);
36368 if (!this.lexer.state.inLink && /^<a /i.test(cap[0])) {
36369 this.lexer.state.inLink = true;
36370 } else if (this.lexer.state.inLink && /^<\/a>/i.test(cap[0])) {
36371 this.lexer.state.inLink = false;
36373 if (!this.lexer.state.inRawBlock && /^<(pre|code|kbd|script)(\s|>)/i.test(cap[0])) {
36374 this.lexer.state.inRawBlock = true;
36375 } else if (this.lexer.state.inRawBlock && /^<\/(pre|code|kbd|script)(\s|>)/i.test(cap[0])) {
36376 this.lexer.state.inRawBlock = false;
36379 type: this.options.sanitize ? "text" : "html",
36381 inLink: this.lexer.state.inLink,
36382 inRawBlock: this.lexer.state.inRawBlock,
36383 text: this.options.sanitize ? this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape4(cap[0]) : cap[0]
36388 const cap = this.rules.inline.link.exec(src);
36390 const trimmedUrl = cap[2].trim();
36391 if (!this.options.pedantic && /^</.test(trimmedUrl)) {
36392 if (!/>$/.test(trimmedUrl)) {
36395 const rtrimSlash = rtrim(trimmedUrl.slice(0, -1), "\\");
36396 if ((trimmedUrl.length - rtrimSlash.length) % 2 === 0) {
36400 const lastParenIndex = findClosingBracket(cap[2], "()");
36401 if (lastParenIndex > -1) {
36402 const start2 = cap[0].indexOf("!") === 0 ? 5 : 4;
36403 const linkLen = start2 + cap[1].length + lastParenIndex;
36404 cap[2] = cap[2].substring(0, lastParenIndex);
36405 cap[0] = cap[0].substring(0, linkLen).trim();
36411 if (this.options.pedantic) {
36412 const link2 = /^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(href);
36418 title = cap[3] ? cap[3].slice(1, -1) : "";
36420 href = href.trim();
36421 if (/^</.test(href)) {
36422 if (this.options.pedantic && !/>$/.test(trimmedUrl)) {
36423 href = href.slice(1);
36425 href = href.slice(1, -1);
36428 return outputLink(cap, {
36429 href: href ? href.replace(this.rules.inline._escapes, "$1") : href,
36430 title: title ? title.replace(this.rules.inline._escapes, "$1") : title
36431 }, cap[0], this.lexer);
36434 reflink(src, links) {
36436 if ((cap = this.rules.inline.reflink.exec(src)) || (cap = this.rules.inline.nolink.exec(src))) {
36437 let link2 = (cap[2] || cap[1]).replace(/\s+/g, " ");
36438 link2 = links[link2.toLowerCase()];
36439 if (!link2 || !link2.href) {
36440 const text2 = cap[0].charAt(0);
36447 return outputLink(cap, link2, cap[0], this.lexer);
36450 emStrong(src, maskedSrc, prevChar = "") {
36451 let match = this.rules.inline.emStrong.lDelim.exec(src);
36454 if (match[3] && prevChar.match(/[\p{L}\p{N}]/u))
36456 const nextChar = match[1] || match[2] || "";
36457 if (!nextChar || nextChar && (prevChar === "" || this.rules.inline.punctuation.exec(prevChar))) {
36458 const lLength = match[0].length - 1;
36459 let rDelim, rLength, delimTotal = lLength, midDelimTotal = 0;
36460 const endReg = match[0][0] === "*" ? this.rules.inline.emStrong.rDelimAst : this.rules.inline.emStrong.rDelimUnd;
36461 endReg.lastIndex = 0;
36462 maskedSrc = maskedSrc.slice(-1 * src.length + lLength);
36463 while ((match = endReg.exec(maskedSrc)) != null) {
36464 rDelim = match[1] || match[2] || match[3] || match[4] || match[5] || match[6];
36467 rLength = rDelim.length;
36468 if (match[3] || match[4]) {
36469 delimTotal += rLength;
36471 } else if (match[5] || match[6]) {
36472 if (lLength % 3 && !((lLength + rLength) % 3)) {
36473 midDelimTotal += rLength;
36477 delimTotal -= rLength;
36478 if (delimTotal > 0)
36480 rLength = Math.min(rLength, rLength + delimTotal + midDelimTotal);
36481 const raw = src.slice(0, lLength + match.index + (match[0].length - rDelim.length) + rLength);
36482 if (Math.min(lLength, rLength) % 2) {
36483 const text3 = raw.slice(1, -1);
36488 tokens: this.lexer.inlineTokens(text3)
36491 const text2 = raw.slice(2, -2);
36496 tokens: this.lexer.inlineTokens(text2)
36502 const cap = this.rules.inline.code.exec(src);
36504 let text2 = cap[2].replace(/\n/g, " ");
36505 const hasNonSpaceChars = /[^ ]/.test(text2);
36506 const hasSpaceCharsOnBothEnds = /^ /.test(text2) && / $/.test(text2);
36507 if (hasNonSpaceChars && hasSpaceCharsOnBothEnds) {
36508 text2 = text2.substring(1, text2.length - 1);
36510 text2 = escape4(text2, true);
36519 const cap = this.rules.inline.br.exec(src);
36528 const cap = this.rules.inline.del.exec(src);
36534 tokens: this.lexer.inlineTokens(cap[2])
36538 autolink(src, mangle2) {
36539 const cap = this.rules.inline.autolink.exec(src);
36542 if (cap[2] === "@") {
36543 text2 = escape4(this.options.mangle ? mangle2(cap[1]) : cap[1]);
36544 href = "mailto:" + text2;
36546 text2 = escape4(cap[1]);
36564 url(src, mangle2) {
36566 if (cap = this.rules.inline.url.exec(src)) {
36568 if (cap[2] === "@") {
36569 text2 = escape4(this.options.mangle ? mangle2(cap[0]) : cap[0]);
36570 href = "mailto:" + text2;
36574 prevCapZero = cap[0];
36575 cap[0] = this.rules.inline._backpedal.exec(cap[0])[0];
36576 } while (prevCapZero !== cap[0]);
36577 text2 = escape4(cap[0]);
36578 if (cap[1] === "www.") {
36579 href = "http://" + text2;
36599 inlineText(src, smartypants2) {
36600 const cap = this.rules.inline.text.exec(src);
36603 if (this.lexer.state.inRawBlock) {
36604 text2 = this.options.sanitize ? this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape4(cap[0]) : cap[0];
36606 text2 = escape4(this.options.smartypants ? smartypants2(cap[0]) : cap[0]);
36617 newline: /^(?: *(?:\n|$))+/,
36618 code: /^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/,
36619 fences: /^ {0,3}(`{3,}(?=[^`\n]*\n)|~{3,})([^\n]*)\n(?:|([\s\S]*?)\n)(?: {0,3}\1[~`]* *(?=\n|$)|$)/,
36620 hr: /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/,
36621 heading: /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,
36622 blockquote: /^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/,
36623 list: /^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/,
36624 html: "^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|<![A-Z][\\s\\S]*?(?:>\\n*|$)|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n *)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$))",
36625 def: /^ {0,3}\[(label)\]: *(?:\n *)?<?([^\s>]+)>?(?:(?: +(?:\n *)?| *\n *)(title))? *(?:\n+|$)/,
36627 lheading: /^([^\n]+)\n {0,3}(=+|-+) *(?:\n+|$)/,
36628 // regex template, placeholders will be replaced according to different paragraph
36629 // interruption rules of commonmark and the original markdown spec:
36630 _paragraph: /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/,
36633 block._label = /(?!\s*\])(?:\\.|[^\[\]\\])+/;
36634 block._title = /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/;
36635 block.def = edit(block.def).replace("label", block._label).replace("title", block._title).getRegex();
36636 block.bullet = /(?:[*+-]|\d{1,9}[.)])/;
36637 block.listItemStart = edit(/^( *)(bull) */).replace("bull", block.bullet).getRegex();
36638 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();
36639 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";
36640 block._comment = /<!--(?!-?>)[\s\S]*?(?:-->|$)/;
36641 block.html = edit(block.html, "i").replace("comment", block._comment).replace("tag", block._tag).replace("attribute", / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex();
36642 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", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", block._tag).getRegex();
36643 block.blockquote = edit(block.blockquote).replace("paragraph", block.paragraph).getRegex();
36644 block.normal = merge2({}, block);
36645 block.gfm = merge2({}, block.normal, {
36646 table: "^ *([^\\n ].*\\|.*)\\n {0,3}(?:\\| *)?(:?-+:? *(?:\\| *:?-+:? *)*)(?:\\| *)?(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)"
36649 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", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", block._tag).getRegex();
36650 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", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", block._tag).getRegex();
36651 block.pedantic = merge2({}, block.normal, {
36653 `^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)|<tag(?:"[^"]*"|'[^']*'|\\s[^'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))`
36654 ).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(),
36655 def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,
36656 heading: /^(#{1,6})(.*)(?:\n+|$)/,
36658 // fences not supported
36659 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()
36662 escape: /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,
36663 autolink: /^<(scheme:[^\s\x00-\x1f<>]*|email)>/,
36665 tag: "^comment|^</[a-zA-Z][\\w:-]*\\s*>|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^<![a-zA-Z]+\\s[\\s\\S]*?>|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>",
36667 link: /^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/,
36668 reflink: /^!?\[(label)\]\[(ref)\]/,
36669 nolink: /^!?\[(ref)\](?:\[\])?/,
36670 reflinkSearch: "reflink|nolink(?!\\()",
36672 lDelim: /^(?:\*+(?:([punct_])|[^\s*]))|^_+(?:([punct*])|([^\s_]))/,
36673 // (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.
36674 // () Skip orphan inside strong () Consume to delim (1) #*** (2) a***#, a*** (3) #***a, ***a (4) ***# (5) #***# (6) a***a
36675 rDelimAst: /^(?:[^_*\\]|\\.)*?\_\_(?:[^_*\\]|\\.)*?\*(?:[^_*\\]|\\.)*?(?=\_\_)|(?:[^*\\]|\\.)+(?=[^*])|[punct_](\*+)(?=[\s]|$)|(?:[^punct*_\s\\]|\\.)(\*+)(?=[punct_\s]|$)|[punct_\s](\*+)(?=[^punct*_\s])|[\s](\*+)(?=[punct_])|[punct_](\*+)(?=[punct_])|(?:[^punct*_\s\\]|\\.)(\*+)(?=[^punct*_\s])/,
36676 rDelimUnd: /^(?:[^_*\\]|\\.)*?\*\*(?:[^_*\\]|\\.)*?\_(?:[^_*\\]|\\.)*?(?=\*\*)|(?:[^_\\]|\\.)+(?=[^_])|[punct*](\_+)(?=[\s]|$)|(?:[^punct*_\s\\]|\\.)(\_+)(?=[punct*\s]|$)|[punct*\s](\_+)(?=[^punct*_\s])|[\s](\_+)(?=[punct*])|[punct*](\_+)(?=[punct*])/
36677 // ^- Not allowed for _
36679 code: /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,
36680 br: /^( {2,}|\\)\n(?!\s*$)/,
36682 text: /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/,
36683 punctuation: /^([\spunctuation])/
36685 inline._punctuation = "!\"#$%&'()+\\-.,/:;<=>?@\\[\\]`^{|}~";
36686 inline.punctuation = edit(inline.punctuation).replace(/punctuation/g, inline._punctuation).getRegex();
36687 inline.blockSkip = /\[[^\]]*?\]\([^\)]*?\)|`[^`]*?`|<[^>]*?>/g;
36688 inline.escapedEmSt = /(?:^|[^\\])(?:\\\\)*\\[*_]/g;
36689 inline._comment = edit(block._comment).replace("(?:-->|$)", "-->").getRegex();
36690 inline.emStrong.lDelim = edit(inline.emStrong.lDelim).replace(/punct/g, inline._punctuation).getRegex();
36691 inline.emStrong.rDelimAst = edit(inline.emStrong.rDelimAst, "g").replace(/punct/g, inline._punctuation).getRegex();
36692 inline.emStrong.rDelimUnd = edit(inline.emStrong.rDelimUnd, "g").replace(/punct/g, inline._punctuation).getRegex();
36693 inline._escapes = /\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/g;
36694 inline._scheme = /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/;
36695 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])?)+(?![-_])/;
36696 inline.autolink = edit(inline.autolink).replace("scheme", inline._scheme).replace("email", inline._email).getRegex();
36697 inline._attribute = /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/;
36698 inline.tag = edit(inline.tag).replace("comment", inline._comment).replace("attribute", inline._attribute).getRegex();
36699 inline._label = /(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/;
36700 inline._href = /<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/;
36701 inline._title = /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/;
36702 inline.link = edit(inline.link).replace("label", inline._label).replace("href", inline._href).replace("title", inline._title).getRegex();
36703 inline.reflink = edit(inline.reflink).replace("label", inline._label).replace("ref", block._label).getRegex();
36704 inline.nolink = edit(inline.nolink).replace("ref", block._label).getRegex();
36705 inline.reflinkSearch = edit(inline.reflinkSearch, "g").replace("reflink", inline.reflink).replace("nolink", inline.nolink).getRegex();
36706 inline.normal = merge2({}, inline);
36707 inline.pedantic = merge2({}, inline.normal, {
36710 middle: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
36711 endAst: /\*\*(?!\*)/g,
36716 middle: /^()\*(?=\S)([\s\S]*?\S)\*(?!\*)|^_(?=\S)([\s\S]*?\S)_(?!_)/,
36717 endAst: /\*(?!\*)/g,
36720 link: edit(/^!?\[(label)\]\((.*?)\)/).replace("label", inline._label).getRegex(),
36721 reflink: edit(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label", inline._label).getRegex()
36723 inline.gfm = merge2({}, inline.normal, {
36724 escape: edit(inline.escape).replace("])", "~|])").getRegex(),
36725 _extended_email: /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/,
36726 url: /^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/,
36727 _backpedal: /(?:[^?!.,:;*_~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_~)]+(?!$))+/,
36728 del: /^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/,
36729 text: /^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|https?:\/\/|ftp:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/
36731 inline.gfm.url = edit(inline.gfm.url, "i").replace("email", inline.gfm._extended_email).getRegex();
36732 inline.breaks = merge2({}, inline.gfm, {
36733 br: edit(inline.br).replace("{2,}", "*").getRegex(),
36734 text: edit(inline.gfm.text).replace("\\b_", "\\b_| {2,}\\n").replace(/\{2,\}/g, "*").getRegex()
36736 function smartypants(text2) {
36737 return text2.replace(/---/g, "\u2014").replace(/--/g, "\u2013").replace(/(^|[-\u2014/(\[{"\s])'/g, "$1\u2018").replace(/'/g, "\u2019").replace(/(^|[-\u2014/(\[{\u2018\s])"/g, "$1\u201C").replace(/"/g, "\u201D").replace(/\.{3}/g, "\u2026");
36739 function mangle(text2) {
36740 let out = "", i2, ch;
36741 const l = text2.length;
36742 for (i2 = 0; i2 < l; i2++) {
36743 ch = text2.charCodeAt(i2);
36744 if (Math.random() > 0.5) {
36745 ch = "x" + ch.toString(16);
36747 out += "&#" + ch + ";";
36751 var Lexer = class {
36752 constructor(options2) {
36754 this.tokens.links = /* @__PURE__ */ Object.create(null);
36755 this.options = options2 || defaults;
36756 this.options.tokenizer = this.options.tokenizer || new Tokenizer();
36757 this.tokenizer = this.options.tokenizer;
36758 this.tokenizer.options = this.options;
36759 this.tokenizer.lexer = this;
36760 this.inlineQueue = [];
36767 block: block.normal,
36768 inline: inline.normal
36770 if (this.options.pedantic) {
36771 rules.block = block.pedantic;
36772 rules.inline = inline.pedantic;
36773 } else if (this.options.gfm) {
36774 rules.block = block.gfm;
36775 if (this.options.breaks) {
36776 rules.inline = inline.breaks;
36778 rules.inline = inline.gfm;
36781 this.tokenizer.rules = rules;
36786 static get rules() {
36793 * Static Lex Method
36795 static lex(src, options2) {
36796 const lexer2 = new Lexer(options2);
36797 return lexer2.lex(src);
36800 * Static Lex Inline Method
36802 static lexInline(src, options2) {
36803 const lexer2 = new Lexer(options2);
36804 return lexer2.inlineTokens(src);
36810 src = src.replace(/\r\n|\r/g, "\n");
36811 this.blockTokens(src, this.tokens);
36813 while (next = this.inlineQueue.shift()) {
36814 this.inlineTokens(next.src, next.tokens);
36816 return this.tokens;
36821 blockTokens(src, tokens = []) {
36822 if (this.options.pedantic) {
36823 src = src.replace(/\t/g, " ").replace(/^ +$/gm, "");
36825 src = src.replace(/^( *)(\t+)/gm, (_, leading, tabs) => {
36826 return leading + " ".repeat(tabs.length);
36829 let token, lastToken, cutSrc, lastParagraphClipped;
36831 if (this.options.extensions && this.options.extensions.block && this.options.extensions.block.some((extTokenizer) => {
36832 if (token = extTokenizer.call({ lexer: this }, src, tokens)) {
36833 src = src.substring(token.raw.length);
36834 tokens.push(token);
36841 if (token = this.tokenizer.space(src)) {
36842 src = src.substring(token.raw.length);
36843 if (token.raw.length === 1 && tokens.length > 0) {
36844 tokens[tokens.length - 1].raw += "\n";
36846 tokens.push(token);
36850 if (token = this.tokenizer.code(src)) {
36851 src = src.substring(token.raw.length);
36852 lastToken = tokens[tokens.length - 1];
36853 if (lastToken && (lastToken.type === "paragraph" || lastToken.type === "text")) {
36854 lastToken.raw += "\n" + token.raw;
36855 lastToken.text += "\n" + token.text;
36856 this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
36858 tokens.push(token);
36862 if (token = this.tokenizer.fences(src)) {
36863 src = src.substring(token.raw.length);
36864 tokens.push(token);
36867 if (token = this.tokenizer.heading(src)) {
36868 src = src.substring(token.raw.length);
36869 tokens.push(token);
36872 if (token = this.tokenizer.hr(src)) {
36873 src = src.substring(token.raw.length);
36874 tokens.push(token);
36877 if (token = this.tokenizer.blockquote(src)) {
36878 src = src.substring(token.raw.length);
36879 tokens.push(token);
36882 if (token = this.tokenizer.list(src)) {
36883 src = src.substring(token.raw.length);
36884 tokens.push(token);
36887 if (token = this.tokenizer.html(src)) {
36888 src = src.substring(token.raw.length);
36889 tokens.push(token);
36892 if (token = this.tokenizer.def(src)) {
36893 src = src.substring(token.raw.length);
36894 lastToken = tokens[tokens.length - 1];
36895 if (lastToken && (lastToken.type === "paragraph" || lastToken.type === "text")) {
36896 lastToken.raw += "\n" + token.raw;
36897 lastToken.text += "\n" + token.raw;
36898 this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
36899 } else if (!this.tokens.links[token.tag]) {
36900 this.tokens.links[token.tag] = {
36907 if (token = this.tokenizer.table(src)) {
36908 src = src.substring(token.raw.length);
36909 tokens.push(token);
36912 if (token = this.tokenizer.lheading(src)) {
36913 src = src.substring(token.raw.length);
36914 tokens.push(token);
36918 if (this.options.extensions && this.options.extensions.startBlock) {
36919 let startIndex = Infinity;
36920 const tempSrc = src.slice(1);
36922 this.options.extensions.startBlock.forEach(function(getStartIndex) {
36923 tempStart = getStartIndex.call({ lexer: this }, tempSrc);
36924 if (typeof tempStart === "number" && tempStart >= 0) {
36925 startIndex = Math.min(startIndex, tempStart);
36928 if (startIndex < Infinity && startIndex >= 0) {
36929 cutSrc = src.substring(0, startIndex + 1);
36932 if (this.state.top && (token = this.tokenizer.paragraph(cutSrc))) {
36933 lastToken = tokens[tokens.length - 1];
36934 if (lastParagraphClipped && lastToken.type === "paragraph") {
36935 lastToken.raw += "\n" + token.raw;
36936 lastToken.text += "\n" + token.text;
36937 this.inlineQueue.pop();
36938 this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
36940 tokens.push(token);
36942 lastParagraphClipped = cutSrc.length !== src.length;
36943 src = src.substring(token.raw.length);
36946 if (token = this.tokenizer.text(src)) {
36947 src = src.substring(token.raw.length);
36948 lastToken = tokens[tokens.length - 1];
36949 if (lastToken && lastToken.type === "text") {
36950 lastToken.raw += "\n" + token.raw;
36951 lastToken.text += "\n" + token.text;
36952 this.inlineQueue.pop();
36953 this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
36955 tokens.push(token);
36960 const errMsg = "Infinite loop on byte: " + src.charCodeAt(0);
36961 if (this.options.silent) {
36962 console.error(errMsg);
36965 throw new Error(errMsg);
36969 this.state.top = true;
36972 inline(src, tokens = []) {
36973 this.inlineQueue.push({ src, tokens });
36979 inlineTokens(src, tokens = []) {
36980 let token, lastToken, cutSrc;
36981 let maskedSrc = src;
36983 let keepPrevChar, prevChar;
36984 if (this.tokens.links) {
36985 const links = Object.keys(this.tokens.links);
36986 if (links.length > 0) {
36987 while ((match = this.tokenizer.rules.inline.reflinkSearch.exec(maskedSrc)) != null) {
36988 if (links.includes(match[0].slice(match[0].lastIndexOf("[") + 1, -1))) {
36989 maskedSrc = maskedSrc.slice(0, match.index) + "[" + repeatString("a", match[0].length - 2) + "]" + maskedSrc.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex);
36994 while ((match = this.tokenizer.rules.inline.blockSkip.exec(maskedSrc)) != null) {
36995 maskedSrc = maskedSrc.slice(0, match.index) + "[" + repeatString("a", match[0].length - 2) + "]" + maskedSrc.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);
36997 while ((match = this.tokenizer.rules.inline.escapedEmSt.exec(maskedSrc)) != null) {
36998 maskedSrc = maskedSrc.slice(0, match.index + match[0].length - 2) + "++" + maskedSrc.slice(this.tokenizer.rules.inline.escapedEmSt.lastIndex);
36999 this.tokenizer.rules.inline.escapedEmSt.lastIndex--;
37002 if (!keepPrevChar) {
37005 keepPrevChar = false;
37006 if (this.options.extensions && this.options.extensions.inline && this.options.extensions.inline.some((extTokenizer) => {
37007 if (token = extTokenizer.call({ lexer: this }, src, tokens)) {
37008 src = src.substring(token.raw.length);
37009 tokens.push(token);
37016 if (token = this.tokenizer.escape(src)) {
37017 src = src.substring(token.raw.length);
37018 tokens.push(token);
37021 if (token = this.tokenizer.tag(src)) {
37022 src = src.substring(token.raw.length);
37023 lastToken = tokens[tokens.length - 1];
37024 if (lastToken && token.type === "text" && lastToken.type === "text") {
37025 lastToken.raw += token.raw;
37026 lastToken.text += token.text;
37028 tokens.push(token);
37032 if (token = this.tokenizer.link(src)) {
37033 src = src.substring(token.raw.length);
37034 tokens.push(token);
37037 if (token = this.tokenizer.reflink(src, this.tokens.links)) {
37038 src = src.substring(token.raw.length);
37039 lastToken = tokens[tokens.length - 1];
37040 if (lastToken && token.type === "text" && lastToken.type === "text") {
37041 lastToken.raw += token.raw;
37042 lastToken.text += token.text;
37044 tokens.push(token);
37048 if (token = this.tokenizer.emStrong(src, maskedSrc, prevChar)) {
37049 src = src.substring(token.raw.length);
37050 tokens.push(token);
37053 if (token = this.tokenizer.codespan(src)) {
37054 src = src.substring(token.raw.length);
37055 tokens.push(token);
37058 if (token = this.tokenizer.br(src)) {
37059 src = src.substring(token.raw.length);
37060 tokens.push(token);
37063 if (token = this.tokenizer.del(src)) {
37064 src = src.substring(token.raw.length);
37065 tokens.push(token);
37068 if (token = this.tokenizer.autolink(src, mangle)) {
37069 src = src.substring(token.raw.length);
37070 tokens.push(token);
37073 if (!this.state.inLink && (token = this.tokenizer.url(src, mangle))) {
37074 src = src.substring(token.raw.length);
37075 tokens.push(token);
37079 if (this.options.extensions && this.options.extensions.startInline) {
37080 let startIndex = Infinity;
37081 const tempSrc = src.slice(1);
37083 this.options.extensions.startInline.forEach(function(getStartIndex) {
37084 tempStart = getStartIndex.call({ lexer: this }, tempSrc);
37085 if (typeof tempStart === "number" && tempStart >= 0) {
37086 startIndex = Math.min(startIndex, tempStart);
37089 if (startIndex < Infinity && startIndex >= 0) {
37090 cutSrc = src.substring(0, startIndex + 1);
37093 if (token = this.tokenizer.inlineText(cutSrc, smartypants)) {
37094 src = src.substring(token.raw.length);
37095 if (token.raw.slice(-1) !== "_") {
37096 prevChar = token.raw.slice(-1);
37098 keepPrevChar = true;
37099 lastToken = tokens[tokens.length - 1];
37100 if (lastToken && lastToken.type === "text") {
37101 lastToken.raw += token.raw;
37102 lastToken.text += token.text;
37104 tokens.push(token);
37109 const errMsg = "Infinite loop on byte: " + src.charCodeAt(0);
37110 if (this.options.silent) {
37111 console.error(errMsg);
37114 throw new Error(errMsg);
37121 var Renderer = class {
37122 constructor(options2) {
37123 this.options = options2 || defaults;
37125 code(code, infostring, escaped) {
37126 const lang = (infostring || "").match(/\S*/)[0];
37127 if (this.options.highlight) {
37128 const out = this.options.highlight(code, lang);
37129 if (out != null && out !== code) {
37134 code = code.replace(/\n$/, "") + "\n";
37136 return "<pre><code>" + (escaped ? code : escape4(code, true)) + "</code></pre>\n";
37138 return '<pre><code class="' + this.options.langPrefix + escape4(lang, true) + '">' + (escaped ? code : escape4(code, true)) + "</code></pre>\n";
37141 * @param {string} quote
37143 blockquote(quote2) {
37144 return `<blockquote>
37145 ${quote2}</blockquote>
37152 * @param {string} text
37153 * @param {string} level
37154 * @param {string} raw
37155 * @param {any} slugger
37157 heading(text2, level, raw, slugger) {
37158 if (this.options.headerIds) {
37159 const id2 = this.options.headerPrefix + slugger.slug(raw);
37160 return `<h${level} id="${id2}">${text2}</h${level}>
37163 return `<h${level}>${text2}</h${level}>
37167 return this.options.xhtml ? "<hr/>\n" : "<hr>\n";
37169 list(body, ordered, start2) {
37170 const type2 = ordered ? "ol" : "ul", startatt = ordered && start2 !== 1 ? ' start="' + start2 + '"' : "";
37171 return "<" + type2 + startatt + ">\n" + body + "</" + type2 + ">\n";
37174 * @param {string} text
37177 return `<li>${text2}</li>
37180 checkbox(checked) {
37181 return "<input " + (checked ? 'checked="" ' : "") + 'disabled="" type="checkbox"' + (this.options.xhtml ? " /" : "") + "> ";
37184 * @param {string} text
37187 return `<p>${text2}</p>
37191 * @param {string} header
37192 * @param {string} body
37194 table(header, body) {
37196 body = `<tbody>${body}</tbody>`;
37197 return "<table>\n<thead>\n" + header + "</thead>\n" + body + "</table>\n";
37200 * @param {string} content
37202 tablerow(content) {
37207 tablecell(content, flags) {
37208 const type2 = flags.header ? "th" : "td";
37209 const tag = flags.align ? `<${type2} align="${flags.align}">` : `<${type2}>`;
37210 return tag + content + `</${type2}>
37214 * span level renderer
37215 * @param {string} text
37218 return `<strong>${text2}</strong>`;
37221 * @param {string} text
37224 return `<em>${text2}</em>`;
37227 * @param {string} text
37230 return `<code>${text2}</code>`;
37233 return this.options.xhtml ? "<br/>" : "<br>";
37236 * @param {string} text
37239 return `<del>${text2}</del>`;
37242 * @param {string} href
37243 * @param {string} title
37244 * @param {string} text
37246 link(href, title, text2) {
37247 href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
37248 if (href === null) {
37251 let out = '<a href="' + escape4(href) + '"';
37253 out += ' title="' + title + '"';
37255 out += ">" + text2 + "</a>";
37259 * @param {string} href
37260 * @param {string} title
37261 * @param {string} text
37263 image(href, title, text2) {
37264 href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
37265 if (href === null) {
37268 let out = `<img src="${href}" alt="${text2}"`;
37270 out += ` title="${title}"`;
37272 out += this.options.xhtml ? "/>" : ">";
37279 var TextRenderer = class {
37280 // no need for block level renderers
37299 link(href, title, text2) {
37302 image(href, title, text2) {
37309 var Slugger = class {
37314 * @param {string} value
37317 return value.toLowerCase().trim().replace(/<[!\/a-z].*?>/ig, "").replace(/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g, "").replace(/\s/g, "-");
37320 * Finds the next safe (unique) slug to use
37321 * @param {string} originalSlug
37322 * @param {boolean} isDryRun
37324 getNextSafeSlug(originalSlug, isDryRun) {
37325 let slug = originalSlug;
37326 let occurenceAccumulator = 0;
37327 if (this.seen.hasOwnProperty(slug)) {
37328 occurenceAccumulator = this.seen[originalSlug];
37330 occurenceAccumulator++;
37331 slug = originalSlug + "-" + occurenceAccumulator;
37332 } while (this.seen.hasOwnProperty(slug));
37335 this.seen[originalSlug] = occurenceAccumulator;
37336 this.seen[slug] = 0;
37341 * Convert string to unique id
37342 * @param {object} [options]
37343 * @param {boolean} [options.dryrun] Generates the next unique slug without
37344 * updating the internal accumulator.
37346 slug(value, options2 = {}) {
37347 const slug = this.serialize(value);
37348 return this.getNextSafeSlug(slug, options2.dryrun);
37351 var Parser = class {
37352 constructor(options2) {
37353 this.options = options2 || defaults;
37354 this.options.renderer = this.options.renderer || new Renderer();
37355 this.renderer = this.options.renderer;
37356 this.renderer.options = this.options;
37357 this.textRenderer = new TextRenderer();
37358 this.slugger = new Slugger();
37361 * Static Parse Method
37363 static parse(tokens, options2) {
37364 const parser3 = new Parser(options2);
37365 return parser3.parse(tokens);
37368 * Static Parse Inline Method
37370 static parseInline(tokens, options2) {
37371 const parser3 = new Parser(options2);
37372 return parser3.parseInline(tokens);
37377 parse(tokens, top = true) {
37378 let out = "", i2, j2, k, l2, l3, row, cell, header, body, token, ordered, start2, loose, itemBody, item, checked, task, checkbox, ret;
37379 const l = tokens.length;
37380 for (i2 = 0; i2 < l; i2++) {
37381 token = tokens[i2];
37382 if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) {
37383 ret = this.options.extensions.renderers[token.type].call({ parser: this }, token);
37384 if (ret !== false || !["space", "hr", "heading", "code", "table", "blockquote", "list", "html", "paragraph", "text"].includes(token.type)) {
37389 switch (token.type) {
37394 out += this.renderer.hr();
37398 out += this.renderer.heading(
37399 this.parseInline(token.tokens),
37401 unescape3(this.parseInline(token.tokens, this.textRenderer)),
37407 out += this.renderer.code(
37417 l2 = token.header.length;
37418 for (j2 = 0; j2 < l2; j2++) {
37419 cell += this.renderer.tablecell(
37420 this.parseInline(token.header[j2].tokens),
37421 { header: true, align: token.align[j2] }
37424 header += this.renderer.tablerow(cell);
37426 l2 = token.rows.length;
37427 for (j2 = 0; j2 < l2; j2++) {
37428 row = token.rows[j2];
37431 for (k = 0; k < l3; k++) {
37432 cell += this.renderer.tablecell(
37433 this.parseInline(row[k].tokens),
37434 { header: false, align: token.align[k] }
37437 body += this.renderer.tablerow(cell);
37439 out += this.renderer.table(header, body);
37442 case "blockquote": {
37443 body = this.parse(token.tokens);
37444 out += this.renderer.blockquote(body);
37448 ordered = token.ordered;
37449 start2 = token.start;
37450 loose = token.loose;
37451 l2 = token.items.length;
37453 for (j2 = 0; j2 < l2; j2++) {
37454 item = token.items[j2];
37455 checked = item.checked;
37459 checkbox = this.renderer.checkbox(checked);
37461 if (item.tokens.length > 0 && item.tokens[0].type === "paragraph") {
37462 item.tokens[0].text = checkbox + " " + item.tokens[0].text;
37463 if (item.tokens[0].tokens && item.tokens[0].tokens.length > 0 && item.tokens[0].tokens[0].type === "text") {
37464 item.tokens[0].tokens[0].text = checkbox + " " + item.tokens[0].tokens[0].text;
37467 item.tokens.unshift({
37473 itemBody += checkbox;
37476 itemBody += this.parse(item.tokens, loose);
37477 body += this.renderer.listitem(itemBody, task, checked);
37479 out += this.renderer.list(body, ordered, start2);
37483 out += this.renderer.html(token.text);
37486 case "paragraph": {
37487 out += this.renderer.paragraph(this.parseInline(token.tokens));
37491 body = token.tokens ? this.parseInline(token.tokens) : token.text;
37492 while (i2 + 1 < l && tokens[i2 + 1].type === "text") {
37493 token = tokens[++i2];
37494 body += "\n" + (token.tokens ? this.parseInline(token.tokens) : token.text);
37496 out += top ? this.renderer.paragraph(body) : body;
37500 const errMsg = 'Token with "' + token.type + '" type was not found.';
37501 if (this.options.silent) {
37502 console.error(errMsg);
37505 throw new Error(errMsg);
37513 * Parse Inline Tokens
37515 parseInline(tokens, renderer) {
37516 renderer = renderer || this.renderer;
37517 let out = "", i2, token, ret;
37518 const l = tokens.length;
37519 for (i2 = 0; i2 < l; i2++) {
37520 token = tokens[i2];
37521 if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) {
37522 ret = this.options.extensions.renderers[token.type].call({ parser: this }, token);
37523 if (ret !== false || !["escape", "html", "link", "image", "strong", "em", "codespan", "br", "del", "text"].includes(token.type)) {
37528 switch (token.type) {
37530 out += renderer.text(token.text);
37534 out += renderer.html(token.text);
37538 out += renderer.link(token.href, token.title, this.parseInline(token.tokens, renderer));
37542 out += renderer.image(token.href, token.title, token.text);
37546 out += renderer.strong(this.parseInline(token.tokens, renderer));
37550 out += renderer.em(this.parseInline(token.tokens, renderer));
37554 out += renderer.codespan(token.text);
37558 out += renderer.br();
37562 out += renderer.del(this.parseInline(token.tokens, renderer));
37566 out += renderer.text(token.text);
37570 const errMsg = 'Token with "' + token.type + '" type was not found.';
37571 if (this.options.silent) {
37572 console.error(errMsg);
37575 throw new Error(errMsg);
37583 function marked(src, opt, callback) {
37584 if (typeof src === "undefined" || src === null) {
37585 throw new Error("marked(): input parameter is undefined or null");
37587 if (typeof src !== "string") {
37588 throw new Error("marked(): input parameter is of type " + Object.prototype.toString.call(src) + ", string expected");
37590 if (typeof opt === "function") {
37594 opt = merge2({}, marked.defaults, opt || {});
37595 checkSanitizeDeprecation(opt);
37597 const highlight = opt.highlight;
37600 tokens = Lexer.lex(src, opt);
37602 return callback(e);
37604 const done = function(err) {
37608 if (opt.walkTokens) {
37609 marked.walkTokens(tokens, opt.walkTokens);
37611 out = Parser.parse(tokens, opt);
37616 opt.highlight = highlight;
37617 return err ? callback(err) : callback(null, out);
37619 if (!highlight || highlight.length < 3) {
37622 delete opt.highlight;
37623 if (!tokens.length)
37626 marked.walkTokens(tokens, function(token) {
37627 if (token.type === "code") {
37630 highlight(token.text, token.lang, function(err, code) {
37634 if (code != null && code !== token.text) {
37636 token.escaped = true;
37639 if (pending === 0) {
37646 if (pending === 0) {
37651 function onError(e) {
37652 e.message += "\nPlease report this to https://github.com/markedjs/marked.";
37654 return "<p>An error occurred:</p><pre>" + escape4(e.message + "", true) + "</pre>";
37659 const tokens = Lexer.lex(src, opt);
37660 if (opt.walkTokens) {
37662 return Promise.all(marked.walkTokens(tokens, opt.walkTokens)).then(() => {
37663 return Parser.parse(tokens, opt);
37666 marked.walkTokens(tokens, opt.walkTokens);
37668 return Parser.parse(tokens, opt);
37673 marked.options = marked.setOptions = function(opt) {
37674 merge2(marked.defaults, opt);
37675 changeDefaults(marked.defaults);
37678 marked.getDefaults = getDefaults;
37679 marked.defaults = defaults;
37680 marked.use = function(...args) {
37681 const opts = merge2({}, ...args);
37682 const extensions = marked.defaults.extensions || { renderers: {}, childTokens: {} };
37684 args.forEach((pack) => {
37685 if (pack.extensions) {
37686 hasExtensions = true;
37687 pack.extensions.forEach((ext) => {
37689 throw new Error("extension name required");
37691 if (ext.renderer) {
37692 const prevRenderer = extensions.renderers ? extensions.renderers[ext.name] : null;
37693 if (prevRenderer) {
37694 extensions.renderers[ext.name] = function(...args2) {
37695 let ret = ext.renderer.apply(this, args2);
37696 if (ret === false) {
37697 ret = prevRenderer.apply(this, args2);
37702 extensions.renderers[ext.name] = ext.renderer;
37705 if (ext.tokenizer) {
37706 if (!ext.level || ext.level !== "block" && ext.level !== "inline") {
37707 throw new Error("extension level must be 'block' or 'inline'");
37709 if (extensions[ext.level]) {
37710 extensions[ext.level].unshift(ext.tokenizer);
37712 extensions[ext.level] = [ext.tokenizer];
37715 if (ext.level === "block") {
37716 if (extensions.startBlock) {
37717 extensions.startBlock.push(ext.start);
37719 extensions.startBlock = [ext.start];
37721 } else if (ext.level === "inline") {
37722 if (extensions.startInline) {
37723 extensions.startInline.push(ext.start);
37725 extensions.startInline = [ext.start];
37730 if (ext.childTokens) {
37731 extensions.childTokens[ext.name] = ext.childTokens;
37735 if (pack.renderer) {
37736 const renderer = marked.defaults.renderer || new Renderer();
37737 for (const prop in pack.renderer) {
37738 const prevRenderer = renderer[prop];
37739 renderer[prop] = (...args2) => {
37740 let ret = pack.renderer[prop].apply(renderer, args2);
37741 if (ret === false) {
37742 ret = prevRenderer.apply(renderer, args2);
37747 opts.renderer = renderer;
37749 if (pack.tokenizer) {
37750 const tokenizer = marked.defaults.tokenizer || new Tokenizer();
37751 for (const prop in pack.tokenizer) {
37752 const prevTokenizer = tokenizer[prop];
37753 tokenizer[prop] = (...args2) => {
37754 let ret = pack.tokenizer[prop].apply(tokenizer, args2);
37755 if (ret === false) {
37756 ret = prevTokenizer.apply(tokenizer, args2);
37761 opts.tokenizer = tokenizer;
37763 if (pack.walkTokens) {
37764 const walkTokens2 = marked.defaults.walkTokens;
37765 opts.walkTokens = function(token) {
37767 values.push(pack.walkTokens.call(this, token));
37769 values = values.concat(walkTokens2.call(this, token));
37774 if (hasExtensions) {
37775 opts.extensions = extensions;
37777 marked.setOptions(opts);
37780 marked.walkTokens = function(tokens, callback) {
37782 for (const token of tokens) {
37783 values = values.concat(callback.call(marked, token));
37784 switch (token.type) {
37786 for (const cell of token.header) {
37787 values = values.concat(marked.walkTokens(cell.tokens, callback));
37789 for (const row of token.rows) {
37790 for (const cell of row) {
37791 values = values.concat(marked.walkTokens(cell.tokens, callback));
37797 values = values.concat(marked.walkTokens(token.items, callback));
37801 if (marked.defaults.extensions && marked.defaults.extensions.childTokens && marked.defaults.extensions.childTokens[token.type]) {
37802 marked.defaults.extensions.childTokens[token.type].forEach(function(childTokens) {
37803 values = values.concat(marked.walkTokens(token[childTokens], callback));
37805 } else if (token.tokens) {
37806 values = values.concat(marked.walkTokens(token.tokens, callback));
37813 marked.parseInline = function(src, opt) {
37814 if (typeof src === "undefined" || src === null) {
37815 throw new Error("marked.parseInline(): input parameter is undefined or null");
37817 if (typeof src !== "string") {
37818 throw new Error("marked.parseInline(): input parameter is of type " + Object.prototype.toString.call(src) + ", string expected");
37820 opt = merge2({}, marked.defaults, opt || {});
37821 checkSanitizeDeprecation(opt);
37823 const tokens = Lexer.lexInline(src, opt);
37824 if (opt.walkTokens) {
37825 marked.walkTokens(tokens, opt.walkTokens);
37827 return Parser.parseInline(tokens, opt);
37829 e.message += "\nPlease report this to https://github.com/markedjs/marked.";
37831 return "<p>An error occurred:</p><pre>" + escape4(e.message + "", true) + "</pre>";
37836 marked.Parser = Parser;
37837 marked.parser = Parser.parse;
37838 marked.Renderer = Renderer;
37839 marked.TextRenderer = TextRenderer;
37840 marked.Lexer = Lexer;
37841 marked.lexer = Lexer.lex;
37842 marked.Tokenizer = Tokenizer;
37843 marked.Slugger = Slugger;
37844 marked.parse = marked;
37845 var options = marked.options;
37846 var setOptions = marked.setOptions;
37847 var use = marked.use;
37848 var walkTokens = marked.walkTokens;
37849 var parseInline = marked.parseInline;
37850 var parser2 = Parser.parse;
37851 var lexer = Lexer.lex;
37853 // modules/services/osmose.js
37854 var tiler3 = utilTiler();
37855 var dispatch4 = dispatch_default("loaded");
37856 var _tileZoom3 = 14;
37857 var _osmoseUrlRoot = "https://osmose.openstreetmap.fr/api/0.3";
37858 var _osmoseData = { icons: {}, items: [] };
37860 function abortRequest3(controller) {
37862 controller.abort();
37865 function abortUnwantedRequests3(cache, tiles) {
37866 Object.keys(cache.inflightTile).forEach((k) => {
37867 let wanted = tiles.find((tile) => k === tile.id);
37869 abortRequest3(cache.inflightTile[k]);
37870 delete cache.inflightTile[k];
37874 function encodeIssueRtree3(d) {
37875 return { minX: d.loc[0], minY: d.loc[1], maxX: d.loc[0], maxY: d.loc[1], data: d };
37877 function updateRtree3(item, replace) {
37878 _cache3.rtree.remove(item, (a, b) => a.data.id === b.data.id);
37880 _cache3.rtree.insert(item);
37883 function preventCoincident2(loc) {
37884 let coincident = false;
37886 let delta = coincident ? [1e-5, 0] : [0, 1e-5];
37887 loc = geoVecAdd(loc, delta);
37888 let bbox2 = geoExtent(loc).bbox();
37889 coincident = _cache3.rtree.search(bbox2).length;
37890 } while (coincident);
37893 var osmose_default = {
37896 _mainFileFetcher.get("qa_data").then((d) => {
37897 _osmoseData = d.osmose;
37898 _osmoseData.items = Object.keys(d.osmose.icons).map((s) => s.split("-")[0]).reduce((unique, item) => unique.indexOf(item) !== -1 ? unique : [...unique, item], []);
37903 this.event = utilRebind(this, dispatch4, "on");
37909 Object.values(_cache3.inflightTile).forEach(abortRequest3);
37910 _strings = _cache3.strings;
37911 _colors = _cache3.colors;
37919 rtree: new import_rbush3.default(),
37924 loadIssues(projection2) {
37926 // Tiles return a maximum # of issues
37927 // So we want to filter our request for only types iD supports
37928 item: _osmoseData.items
37930 let tiles = tiler3.zoomExtent([_tileZoom3, _tileZoom3]).getTiles(projection2);
37931 abortUnwantedRequests3(_cache3, tiles);
37932 tiles.forEach((tile) => {
37933 if (_cache3.loadedTile[tile.id] || _cache3.inflightTile[tile.id])
37935 let [x, y, z] = tile.xyz;
37936 let url = `${_osmoseUrlRoot}/issues/${z}/${x}/${y}.geojson?` + utilQsString(params);
37937 let controller = new AbortController();
37938 _cache3.inflightTile[tile.id] = controller;
37939 json_default(url, { signal: controller.signal }).then((data) => {
37940 delete _cache3.inflightTile[tile.id];
37941 _cache3.loadedTile[tile.id] = true;
37942 if (data.features) {
37943 data.features.forEach((issue) => {
37944 const { item, class: cl, uuid: id2 } = issue.properties;
37945 const itemType = `${item}-${cl}`;
37946 if (itemType in _osmoseData.icons) {
37947 let loc = issue.geometry.coordinates;
37948 loc = preventCoincident2(loc);
37949 let d = new QAItem(loc, this, itemType, id2, { item });
37950 if (item === 8300 || item === 8360) {
37953 _cache3.data[d.id] = d;
37954 _cache3.rtree.insert(encodeIssueRtree3(d));
37958 dispatch4.call("loaded");
37960 delete _cache3.inflightTile[tile.id];
37961 _cache3.loadedTile[tile.id] = true;
37965 loadIssueDetail(issue) {
37966 if (issue.elems !== void 0) {
37967 return Promise.resolve(issue);
37969 const url = `${_osmoseUrlRoot}/issue/${issue.id}?langs=${_mainLocalizer.localeCode()}`;
37970 const cacheDetails = (data) => {
37971 issue.elems = data.elems.map((e) => e.type.substring(0, 1) + e.id);
37972 issue.detail = data.subtitle ? marked(data.subtitle.auto) : "";
37973 this.replaceItem(issue);
37975 return json_default(url).then(cacheDetails).then(() => issue);
37977 loadStrings(locale2 = _mainLocalizer.localeCode()) {
37978 const items = Object.keys(_osmoseData.icons);
37979 if (locale2 in _cache3.strings && Object.keys(_cache3.strings[locale2]).length === items.length) {
37980 return Promise.resolve(_cache3.strings[locale2]);
37982 if (!(locale2 in _cache3.strings)) {
37983 _cache3.strings[locale2] = {};
37985 const allRequests = items.map((itemType) => {
37986 if (itemType in _cache3.strings[locale2])
37988 const cacheData = (data) => {
37989 const [cat = { items: [] }] = data.categories;
37990 const [item2 = { class: [] }] = cat.items;
37991 const [cl2 = null] = item2.class;
37993 console.log(`Osmose strings request (${itemType}) had unexpected data`);
37996 const { item: itemInt, color: color2 } = item2;
37997 if (/^#[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3}/.test(color2)) {
37998 _cache3.colors[itemInt] = color2;
38000 const { title, detail, fix, trap } = cl2;
38001 let issueStrings = {};
38003 issueStrings.title = title.auto;
38005 issueStrings.detail = marked(detail.auto);
38007 issueStrings.trap = marked(trap.auto);
38009 issueStrings.fix = marked(fix.auto);
38010 _cache3.strings[locale2][itemType] = issueStrings;
38012 const [item, cl] = itemType.split("-");
38013 const url = `${_osmoseUrlRoot}/items/${item}/class/${cl}?langs=${locale2}`;
38014 return json_default(url).then(cacheData);
38015 }).filter(Boolean);
38016 return Promise.all(allRequests).then(() => _cache3.strings[locale2]);
38018 getStrings(itemType, locale2 = _mainLocalizer.localeCode()) {
38019 return locale2 in _cache3.strings ? _cache3.strings[locale2][itemType] : {};
38021 getColor(itemType) {
38022 return itemType in _cache3.colors ? _cache3.colors[itemType] : "#FFFFFF";
38024 postUpdate(issue, callback) {
38025 if (_cache3.inflightPost[issue.id]) {
38026 return callback({ message: "Issue update already inflight", status: -2 }, issue);
38028 const url = `${_osmoseUrlRoot}/issue/${issue.id}/${issue.newStatus}`;
38029 const controller = new AbortController();
38030 const after = () => {
38031 delete _cache3.inflightPost[issue.id];
38032 this.removeItem(issue);
38033 if (issue.newStatus === "done") {
38034 if (!(issue.item in _cache3.closed)) {
38035 _cache3.closed[issue.item] = 0;
38037 _cache3.closed[issue.item] += 1;
38040 callback(null, issue);
38042 _cache3.inflightPost[issue.id] = controller;
38043 fetch(url, { signal: controller.signal }).then(after).catch((err) => {
38044 delete _cache3.inflightPost[issue.id];
38046 callback(err.message);
38049 // Get all cached QAItems covering the viewport
38050 getItems(projection2) {
38051 const viewport = projection2.clipExtent();
38052 const min3 = [viewport[0][0], viewport[1][1]];
38053 const max3 = [viewport[1][0], viewport[0][1]];
38054 const bbox2 = geoExtent(projection2.invert(min3), projection2.invert(max3)).bbox();
38055 return _cache3.rtree.search(bbox2).map((d) => d.data);
38057 // Get a QAItem from cache
38058 // NOTE: Don't change method name until UI v3 is merged
38060 return _cache3.data[id2];
38062 // get the name of the icon to display for this item
38063 getIcon(itemType) {
38064 return _osmoseData.icons[itemType];
38066 // Replace a single QAItem in the cache
38067 replaceItem(item) {
38068 if (!(item instanceof QAItem) || !item.id)
38070 _cache3.data[item.id] = item;
38071 updateRtree3(encodeIssueRtree3(item), true);
38074 // Remove a single QAItem from the cache
38076 if (!(item instanceof QAItem) || !item.id)
38078 delete _cache3.data[item.id];
38079 updateRtree3(encodeIssueRtree3(item), false);
38081 // Used to populate `closed:osmose:*` changeset tags
38082 getClosedCounts() {
38083 return _cache3.closed;
38086 return `https://osmose.openstreetmap.fr/en/error/${item.id}`;
38090 // modules/services/mapillary.js
38091 var import_pbf = __toESM(require_pbf());
38092 var import_rbush4 = __toESM(require_rbush_min());
38093 var import_vector_tile = __toESM(require_vector_tile());
38094 var accessToken = "MLY|4100327730013843|5bb78b81720791946a9a7b956c57b7cf";
38095 var apiUrl = "https://graph.mapillary.com/";
38096 var baseTileUrl = "https://tiles.mapillary.com/maps/vtp";
38097 var mapFeatureTileUrl = `${baseTileUrl}/mly_map_feature_point/2/{z}/{x}/{y}?access_token=${accessToken}`;
38098 var tileUrl = `${baseTileUrl}/mly1_public/2/{z}/{x}/{y}?access_token=${accessToken}`;
38099 var trafficSignTileUrl = `${baseTileUrl}/mly_map_feature_traffic_sign/2/{z}/{x}/{y}?access_token=${accessToken}`;
38100 var viewercss = "mapillary-js/mapillary.css";
38101 var viewerjs = "mapillary-js/mapillary.js";
38103 var dispatch5 = dispatch_default("change", "loadedImages", "loadedSigns", "loadedMapFeatures", "bearingChanged", "imageChanged");
38104 var _loadViewerPromise;
38105 var _mlyActiveImage;
38107 var _mlyFallback = false;
38108 var _mlyHighlightedDetection;
38109 var _mlyShowFeatureDetections = false;
38110 var _mlyShowSignDetections = false;
38112 var _mlyViewerFilter = ["all"];
38113 function loadTiles(which, url, maxZoom2, projection2) {
38114 const tiler8 = utilTiler().zoomExtent([minZoom, maxZoom2]).skipNullIsland(true);
38115 const tiles = tiler8.getTiles(projection2);
38116 tiles.forEach(function(tile) {
38117 loadTile(which, url, tile);
38120 function loadTile(which, url, tile) {
38121 const cache = _mlyCache.requests;
38122 const tileId = `${tile.id}-${which}`;
38123 if (cache.loaded[tileId] || cache.inflight[tileId])
38125 const controller = new AbortController();
38126 cache.inflight[tileId] = controller;
38127 const requestUrl = url.replace("{x}", tile.xyz[0]).replace("{y}", tile.xyz[1]).replace("{z}", tile.xyz[2]);
38128 fetch(requestUrl, { signal: controller.signal }).then(function(response) {
38129 if (!response.ok) {
38130 throw new Error(response.status + " " + response.statusText);
38132 cache.loaded[tileId] = true;
38133 delete cache.inflight[tileId];
38134 return response.arrayBuffer();
38135 }).then(function(data) {
38137 throw new Error("No Data");
38139 loadTileDataToCache(data, tile, which);
38140 if (which === "images") {
38141 dispatch5.call("loadedImages");
38142 } else if (which === "signs") {
38143 dispatch5.call("loadedSigns");
38144 } else if (which === "points") {
38145 dispatch5.call("loadedMapFeatures");
38147 }).catch(function() {
38148 cache.loaded[tileId] = true;
38149 delete cache.inflight[tileId];
38152 function loadTileDataToCache(data, tile, which) {
38153 const vectorTile = new import_vector_tile.VectorTile(new import_pbf.default(data));
38154 let features, cache, layer, i2, feature3, loc, d;
38155 if (vectorTile.layers.hasOwnProperty("image")) {
38157 cache = _mlyCache.images;
38158 layer = vectorTile.layers.image;
38159 for (i2 = 0; i2 < layer.length; i2++) {
38160 feature3 = layer.feature(i2).toGeoJSON(tile.xyz[0], tile.xyz[1], tile.xyz[2]);
38161 loc = feature3.geometry.coordinates;
38164 captured_at: feature3.properties.captured_at,
38165 ca: feature3.properties.compass_angle,
38166 id: feature3.properties.id,
38167 is_pano: feature3.properties.is_pano,
38168 sequence_id: feature3.properties.sequence_id
38170 cache.forImageId[d.id] = d;
38180 cache.rtree.load(features);
38183 if (vectorTile.layers.hasOwnProperty("sequence")) {
38185 cache = _mlyCache.sequences;
38186 layer = vectorTile.layers.sequence;
38187 for (i2 = 0; i2 < layer.length; i2++) {
38188 feature3 = layer.feature(i2).toGeoJSON(tile.xyz[0], tile.xyz[1], tile.xyz[2]);
38189 if (cache.lineString[feature3.properties.id]) {
38190 cache.lineString[feature3.properties.id].push(feature3);
38192 cache.lineString[feature3.properties.id] = [feature3];
38196 if (vectorTile.layers.hasOwnProperty("point")) {
38198 cache = _mlyCache[which];
38199 layer = vectorTile.layers.point;
38200 for (i2 = 0; i2 < layer.length; i2++) {
38201 feature3 = layer.feature(i2).toGeoJSON(tile.xyz[0], tile.xyz[1], tile.xyz[2]);
38202 loc = feature3.geometry.coordinates;
38205 id: feature3.properties.id,
38206 first_seen_at: feature3.properties.first_seen_at,
38207 last_seen_at: feature3.properties.last_seen_at,
38208 value: feature3.properties.value
38219 cache.rtree.load(features);
38222 if (vectorTile.layers.hasOwnProperty("traffic_sign")) {
38224 cache = _mlyCache[which];
38225 layer = vectorTile.layers.traffic_sign;
38226 for (i2 = 0; i2 < layer.length; i2++) {
38227 feature3 = layer.feature(i2).toGeoJSON(tile.xyz[0], tile.xyz[1], tile.xyz[2]);
38228 loc = feature3.geometry.coordinates;
38231 id: feature3.properties.id,
38232 first_seen_at: feature3.properties.first_seen_at,
38233 last_seen_at: feature3.properties.last_seen_at,
38234 value: feature3.properties.value
38245 cache.rtree.load(features);
38249 function loadData(url) {
38250 return fetch(url).then(function(response) {
38251 if (!response.ok) {
38252 throw new Error(response.status + " " + response.statusText);
38254 return response.json();
38255 }).then(function(result) {
38259 return result.data || [];
38262 function partitionViewport(projection2) {
38263 const z = geoScaleToZoom(projection2.scale());
38264 const z2 = Math.ceil(z * 2) / 2 + 2.5;
38265 const tiler8 = utilTiler().zoomExtent([z2, z2]);
38266 return tiler8.getTiles(projection2).map(function(tile) {
38267 return tile.extent;
38270 function searchLimited(limit, projection2, rtree) {
38271 limit = limit || 5;
38272 return partitionViewport(projection2).reduce(function(result, extent) {
38273 const found = rtree.search(extent.bbox()).slice(0, limit).map(function(d) {
38276 return found.length ? result.concat(found) : result;
38279 var mapillary_default = {
38280 // Initialize Mapillary
38285 this.event = utilRebind(this, dispatch5, "on");
38287 // Reset cache and state
38288 reset: function() {
38290 Object.values(_mlyCache.requests.inflight).forEach(function(request3) {
38295 images: { rtree: new import_rbush4.default(), forImageId: {} },
38296 image_detections: { forImageId: {} },
38297 signs: { rtree: new import_rbush4.default() },
38298 points: { rtree: new import_rbush4.default() },
38299 sequences: { rtree: new import_rbush4.default(), lineString: {} },
38300 requests: { loaded: {}, inflight: {} }
38302 _mlyActiveImage = null;
38304 // Get visible images
38305 images: function(projection2) {
38307 return searchLimited(limit, projection2, _mlyCache.images.rtree);
38309 // Get visible traffic signs
38310 signs: function(projection2) {
38312 return searchLimited(limit, projection2, _mlyCache.signs.rtree);
38314 // Get visible map (point) features
38315 mapFeatures: function(projection2) {
38317 return searchLimited(limit, projection2, _mlyCache.points.rtree);
38319 // Get cached image by id
38320 cachedImage: function(imageId) {
38321 return _mlyCache.images.forImageId[imageId];
38323 // Get visible sequences
38324 sequences: function(projection2) {
38325 const viewport = projection2.clipExtent();
38326 const min3 = [viewport[0][0], viewport[1][1]];
38327 const max3 = [viewport[1][0], viewport[0][1]];
38328 const bbox2 = geoExtent(projection2.invert(min3), projection2.invert(max3)).bbox();
38329 const sequenceIds = {};
38330 let lineStrings = [];
38331 _mlyCache.images.rtree.search(bbox2).forEach(function(d) {
38332 if (d.data.sequence_id) {
38333 sequenceIds[d.data.sequence_id] = true;
38336 Object.keys(sequenceIds).forEach(function(sequenceId) {
38337 if (_mlyCache.sequences.lineString[sequenceId]) {
38338 lineStrings = lineStrings.concat(_mlyCache.sequences.lineString[sequenceId]);
38341 return lineStrings;
38343 // Load images in the visible area
38344 loadImages: function(projection2) {
38345 loadTiles("images", tileUrl, 14, projection2);
38347 // Load traffic signs in the visible area
38348 loadSigns: function(projection2) {
38349 loadTiles("signs", trafficSignTileUrl, 14, projection2);
38351 // Load map (point) features in the visible area
38352 loadMapFeatures: function(projection2) {
38353 loadTiles("points", mapFeatureTileUrl, 14, projection2);
38355 // Return a promise that resolves when the image viewer (Mapillary JS) library has finished loading
38356 ensureViewerLoaded: function(context) {
38357 if (_loadViewerPromise)
38358 return _loadViewerPromise;
38359 const wrap2 = context.container().select(".photoviewer").selectAll(".mly-wrapper").data([0]);
38360 wrap2.enter().append("div").attr("id", "ideditor-mly").attr("class", "photo-wrapper mly-wrapper").classed("hide", true);
38362 _loadViewerPromise = new Promise((resolve, reject) => {
38363 let loadedCount = 0;
38364 function loaded() {
38366 if (loadedCount === 2)
38369 const head = select_default2("head");
38370 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() {
38373 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() {
38376 }).catch(function() {
38377 _loadViewerPromise = null;
38378 }).then(function() {
38379 that.initViewer(context);
38381 return _loadViewerPromise;
38383 // Load traffic sign image sprites
38384 loadSignResources: function(context) {
38385 context.ui().svgDefs.addSprites(
38386 ["mapillary-sprite"],
38388 /* don't override colors */
38392 // Load map (point) feature image sprites
38393 loadObjectResources: function(context) {
38394 context.ui().svgDefs.addSprites(
38395 ["mapillary-object-sprite"],
38397 /* don't override colors */
38401 // Remove previous detections in image viewer
38402 resetTags: function() {
38403 if (_mlyViewer && !_mlyFallback) {
38404 _mlyViewer.getComponent("tag").removeAll();
38407 // Show map feature detections in image viewer
38408 showFeatureDetections: function(value) {
38409 _mlyShowFeatureDetections = value;
38410 if (!_mlyShowFeatureDetections && !_mlyShowSignDetections) {
38414 // Show traffic sign detections in image viewer
38415 showSignDetections: function(value) {
38416 _mlyShowSignDetections = value;
38417 if (!_mlyShowFeatureDetections && !_mlyShowSignDetections) {
38421 // Apply filter to image viewer
38422 filterViewer: function(context) {
38423 const showsPano = context.photos().showsPanoramic();
38424 const showsFlat = context.photos().showsFlat();
38425 const fromDate = context.photos().fromDate();
38426 const toDate = context.photos().toDate();
38427 const filter2 = ["all"];
38429 filter2.push(["!=", "cameraType", "spherical"]);
38430 if (!showsFlat && showsPano)
38431 filter2.push(["==", "pano", true]);
38433 filter2.push([">=", "capturedAt", new Date(fromDate).getTime()]);
38436 filter2.push([">=", "capturedAt", new Date(toDate).getTime()]);
38439 _mlyViewer.setFilter(filter2);
38441 _mlyViewerFilter = filter2;
38444 // Make the image viewer visible
38445 showViewer: function(context) {
38446 const wrap2 = context.container().select(".photoviewer").classed("hide", false);
38447 const isHidden = wrap2.selectAll(".photo-wrapper.mly-wrapper.hide").size();
38448 if (isHidden && _mlyViewer) {
38449 wrap2.selectAll(".photo-wrapper:not(.mly-wrapper)").classed("hide", true);
38450 wrap2.selectAll(".photo-wrapper.mly-wrapper").classed("hide", false);
38451 _mlyViewer.resize();
38455 // Hide the image viewer and resets map markers
38456 hideViewer: function(context) {
38457 _mlyActiveImage = null;
38458 if (!_mlyFallback && _mlyViewer) {
38459 _mlyViewer.getComponent("sequence").stop();
38461 const viewer = context.container().select(".photoviewer");
38462 if (!viewer.empty())
38463 viewer.datum(null);
38464 viewer.classed("hide", true).selectAll(".photo-wrapper").classed("hide", true);
38465 this.updateUrlImage(null);
38466 dispatch5.call("imageChanged");
38467 dispatch5.call("loadedMapFeatures");
38468 dispatch5.call("loadedSigns");
38469 return this.setStyles(context, null);
38471 // Update the URL with current image id
38472 updateUrlImage: function(imageId) {
38473 if (!window.mocha) {
38474 const hash = utilStringQs(window.location.hash);
38476 hash.photo = "mapillary/" + imageId;
38480 window.location.replace("#" + utilQsString(hash, true));
38483 // Highlight the detection in the viewer that is related to the clicked map feature
38484 highlightDetection: function(detection) {
38486 _mlyHighlightedDetection = detection.id;
38490 // Initialize image viewer (Mapillar JS)
38491 initViewer: function(context) {
38493 if (!window.mapillary)
38502 container: "ideditor-mly"
38504 if (!mapillary.isSupported() && mapillary.isFallbackSupported()) {
38505 _mlyFallback = true;
38520 _mlyViewer = new mapillary.Viewer(opts);
38521 _mlyViewer.on("image", imageChanged);
38522 _mlyViewer.on("bearing", bearingChanged);
38523 if (_mlyViewerFilter) {
38524 _mlyViewer.setFilter(_mlyViewerFilter);
38526 context.ui().photoviewer.on("resize.mapillary", function() {
38528 _mlyViewer.resize();
38530 function imageChanged(node) {
38532 const image = node.image;
38533 that.setActiveImage(image);
38534 that.setStyles(context, null);
38535 const loc = [image.originalLngLat.lng, image.originalLngLat.lat];
38536 context.map().centerEase(loc);
38537 that.updateUrlImage(image.id);
38538 if (_mlyShowFeatureDetections || _mlyShowSignDetections) {
38539 that.updateDetections(image.id, `${apiUrl}/${image.id}/detections?access_token=${accessToken}&fields=id,image,geometry,value`);
38541 dispatch5.call("imageChanged");
38543 function bearingChanged(e) {
38544 dispatch5.call("bearingChanged", void 0, e);
38547 // Move to an image
38548 selectImage: function(context, imageId) {
38549 if (_mlyViewer && imageId) {
38550 _mlyViewer.moveTo(imageId).catch(function(e) {
38551 console.error("mly3", e);
38556 // Return the currently displayed image
38557 getActiveImage: function() {
38558 return _mlyActiveImage;
38560 // Return a list of detection objects for the given id
38561 getDetections: function(id2) {
38562 return loadData(`${apiUrl}/${id2}/detections?access_token=${accessToken}&fields=id,value,image`);
38564 // Set the currently visible image
38565 setActiveImage: function(image) {
38567 _mlyActiveImage = {
38568 ca: image.originalCompassAngle,
38570 loc: [image.originalLngLat.lng, image.originalLngLat.lat],
38571 is_pano: image.cameraType === "spherical",
38572 sequence_id: image.sequenceId
38575 _mlyActiveImage = null;
38578 // Update the currently highlighted sequence and selected bubble.
38579 setStyles: function(context, hovered) {
38580 const hoveredImageId = hovered && hovered.id;
38581 const hoveredSequenceId = hovered && hovered.sequence_id;
38582 const selectedSequenceId = _mlyActiveImage && _mlyActiveImage.sequence_id;
38583 context.container().selectAll(".layer-mapillary .viewfield-group").classed("highlighted", function(d) {
38584 return d.sequence_id === selectedSequenceId || d.id === hoveredImageId;
38585 }).classed("hovered", function(d) {
38586 return d.id === hoveredImageId;
38588 context.container().selectAll(".layer-mapillary .sequence").classed("highlighted", function(d) {
38589 return d.properties.id === hoveredSequenceId;
38590 }).classed("currentView", function(d) {
38591 return d.properties.id === selectedSequenceId;
38595 // Get detections for the current image and shows them in the image viewer
38596 updateDetections: function(imageId, url) {
38597 if (!_mlyViewer || _mlyFallback)
38601 const cache = _mlyCache.image_detections;
38602 if (cache.forImageId[imageId]) {
38603 showDetections(_mlyCache.image_detections.forImageId[imageId]);
38605 loadData(url).then((detections) => {
38606 detections.forEach(function(detection) {
38607 if (!cache.forImageId[imageId]) {
38608 cache.forImageId[imageId] = [];
38610 cache.forImageId[imageId].push({
38611 geometry: detection.geometry,
38614 value: detection.value
38617 showDetections(_mlyCache.image_detections.forImageId[imageId] || []);
38620 function showDetections(detections) {
38621 const tagComponent = _mlyViewer.getComponent("tag");
38622 detections.forEach(function(data) {
38623 const tag = makeTag(data);
38625 tagComponent.add([tag]);
38629 function makeTag(data) {
38630 const valueParts = data.value.split("--");
38631 if (!valueParts.length)
38635 let color2 = 16777215;
38636 if (_mlyHighlightedDetection === data.id) {
38638 text2 = valueParts[1];
38639 if (text2 === "flat" || text2 === "discrete" || text2 === "sign") {
38640 text2 = valueParts[2];
38642 text2 = text2.replace(/-/g, " ");
38643 text2 = text2.charAt(0).toUpperCase() + text2.slice(1);
38644 _mlyHighlightedDetection = null;
38646 var decodedGeometry = window.atob(data.geometry);
38647 var uintArray = new Uint8Array(decodedGeometry.length);
38648 for (var i2 = 0; i2 < decodedGeometry.length; i2++) {
38649 uintArray[i2] = decodedGeometry.charCodeAt(i2);
38651 const tile = new import_vector_tile.VectorTile(new import_pbf.default(uintArray.buffer));
38652 const layer = tile.layers["mpy-or"];
38653 const geometries = layer.feature(0).loadGeometry();
38654 const polygon2 = geometries.map((ring) => ring.map((point2) => [point2.x / layer.extent, point2.y / layer.extent]));
38655 tag = new mapillary.OutlineTag(
38657 new mapillary.PolygonGeometry(polygon2[0]),
38670 // Return the current cache
38671 cache: function() {
38676 // modules/core/validation/models.js
38677 function validationIssue(attrs) {
38678 this.type = attrs.type;
38679 this.subtype = attrs.subtype;
38680 this.severity = attrs.severity;
38681 this.message = attrs.message;
38682 this.reference = attrs.reference;
38683 this.entityIds = attrs.entityIds;
38684 this.loc = attrs.loc;
38685 this.data = attrs.data;
38686 this.dynamicFixes = attrs.dynamicFixes;
38687 this.hash = attrs.hash;
38688 this.id = generateID.apply(this);
38689 this.key = generateKey.apply(this);
38690 this.autoFix = null;
38691 function generateID() {
38692 var parts = [this.type];
38694 parts.push(this.hash);
38696 if (this.subtype) {
38697 parts.push(this.subtype);
38699 if (this.entityIds) {
38700 var entityKeys = this.entityIds.slice().sort();
38701 parts.push.apply(parts, entityKeys);
38703 return parts.join(":");
38705 function generateKey() {
38706 return this.id + ":" + Date.now().toString();
38708 this.extent = function(resolver) {
38710 return geoExtent(this.loc);
38712 if (this.entityIds && this.entityIds.length) {
38713 return this.entityIds.reduce(function(extent, entityId) {
38714 return extent.extend(resolver.entity(entityId).extent(resolver));
38719 this.fixes = function(context) {
38720 var fixes = this.dynamicFixes ? this.dynamicFixes(context) : [];
38722 if (issue.severity === "warning") {
38723 fixes.push(new validationIssueFix({
38724 title: _t.append("issues.fix.ignore_issue.title"),
38725 icon: "iD-icon-close",
38726 onClick: function() {
38727 context.validator().ignoreIssue(this.issue.id);
38731 fixes.forEach(function(fix) {
38732 fix.id = fix.title.stringId;
38734 if (fix.autoArgs) {
38735 issue.autoFix = fix;
38741 function validationIssueFix(attrs) {
38742 this.title = attrs.title;
38743 this.onClick = attrs.onClick;
38744 this.disabledReason = attrs.disabledReason;
38745 this.icon = attrs.icon;
38746 this.entityIds = attrs.entityIds || [];
38747 this.autoArgs = attrs.autoArgs;
38751 // modules/services/maprules.js
38752 var buildRuleChecks = function() {
38754 equals: function(equals) {
38755 return function(tags) {
38756 return Object.keys(equals).every(function(k) {
38757 return equals[k] === tags[k];
38761 notEquals: function(notEquals) {
38762 return function(tags) {
38763 return Object.keys(notEquals).some(function(k) {
38764 return notEquals[k] !== tags[k];
38768 absence: function(absence) {
38769 return function(tags) {
38770 return Object.keys(tags).indexOf(absence) === -1;
38773 presence: function(presence) {
38774 return function(tags) {
38775 return Object.keys(tags).indexOf(presence) > -1;
38778 greaterThan: function(greaterThan) {
38779 var key = Object.keys(greaterThan)[0];
38780 var value = greaterThan[key];
38781 return function(tags) {
38782 return tags[key] > value;
38785 greaterThanEqual: function(greaterThanEqual) {
38786 var key = Object.keys(greaterThanEqual)[0];
38787 var value = greaterThanEqual[key];
38788 return function(tags) {
38789 return tags[key] >= value;
38792 lessThan: function(lessThan) {
38793 var key = Object.keys(lessThan)[0];
38794 var value = lessThan[key];
38795 return function(tags) {
38796 return tags[key] < value;
38799 lessThanEqual: function(lessThanEqual) {
38800 var key = Object.keys(lessThanEqual)[0];
38801 var value = lessThanEqual[key];
38802 return function(tags) {
38803 return tags[key] <= value;
38806 positiveRegex: function(positiveRegex) {
38807 var tagKey = Object.keys(positiveRegex)[0];
38808 var expression = positiveRegex[tagKey].join("|");
38809 var regex = new RegExp(expression);
38810 return function(tags) {
38811 return regex.test(tags[tagKey]);
38814 negativeRegex: function(negativeRegex) {
38815 var tagKey = Object.keys(negativeRegex)[0];
38816 var expression = negativeRegex[tagKey].join("|");
38817 var regex = new RegExp(expression);
38818 return function(tags) {
38819 return !regex.test(tags[tagKey]);
38824 var buildLineKeys = function() {
38839 var maprules_default = {
38841 this._ruleChecks = buildRuleChecks();
38842 this._validationRules = [];
38843 this._areaKeys = osmAreaKeys;
38844 this._lineKeys = buildLineKeys();
38846 // list of rules only relevant to tag checks...
38847 filterRuleChecks: function(selector) {
38848 var _ruleChecks = this._ruleChecks;
38849 return Object.keys(selector).reduce(function(rules, key) {
38850 if (["geometry", "error", "warning"].indexOf(key) === -1) {
38851 rules.push(_ruleChecks[key](selector[key]));
38856 // builds tagMap from mapcss-parse selector object...
38857 buildTagMap: function(selector) {
38858 var getRegexValues = function(regexes) {
38859 return regexes.map(function(regex) {
38860 return regex.replace(/\$|\^/g, "");
38863 var tagMap = Object.keys(selector).reduce(function(expectedTags, key) {
38865 var isRegex = /regex/gi.test(key);
38866 var isEqual = /equals/gi.test(key);
38867 if (isRegex || isEqual) {
38868 Object.keys(selector[key]).forEach(function(selectorKey) {
38869 values = isEqual ? [selector[key][selectorKey]] : getRegexValues(selector[key][selectorKey]);
38870 if (expectedTags.hasOwnProperty(selectorKey)) {
38871 values = values.concat(expectedTags[selectorKey]);
38873 expectedTags[selectorKey] = values;
38875 } else if (/(greater|less)Than(Equal)?|presence/g.test(key)) {
38876 var tagKey = /presence/.test(key) ? selector[key] : Object.keys(selector[key])[0];
38877 values = [selector[key][tagKey]];
38878 if (expectedTags.hasOwnProperty(tagKey)) {
38879 values = values.concat(expectedTags[tagKey]);
38881 expectedTags[tagKey] = values;
38883 return expectedTags;
38887 // inspired by osmWay#isArea()
38888 inferGeometry: function(tagMap) {
38889 var _lineKeys = this._lineKeys;
38890 var _areaKeys = this._areaKeys;
38891 var keyValueDoesNotImplyArea = function(key2) {
38892 return utilArrayIntersection(tagMap[key2], Object.keys(_areaKeys[key2])).length > 0;
38894 var keyValueImpliesLine = function(key2) {
38895 return utilArrayIntersection(tagMap[key2], Object.keys(_lineKeys[key2])).length > 0;
38897 if (tagMap.hasOwnProperty("area")) {
38898 if (tagMap.area.indexOf("yes") > -1) {
38901 if (tagMap.area.indexOf("no") > -1) {
38905 for (var key in tagMap) {
38906 if (key in _areaKeys && !keyValueDoesNotImplyArea(key)) {
38909 if (key in _lineKeys && keyValueImpliesLine(key)) {
38915 // adds from mapcss-parse selector check...
38916 addRule: function(selector) {
38918 // checks relevant to mapcss-selector
38919 checks: this.filterRuleChecks(selector),
38920 // true if all conditions for a tag error are true..
38921 matches: function(entity) {
38922 return this.checks.every(function(check) {
38923 return check(entity.tags);
38926 // borrowed from Way#isArea()
38927 inferredGeometry: this.inferGeometry(this.buildTagMap(selector), this._areaKeys),
38928 geometryMatches: function(entity, graph) {
38929 if (entity.type === "node" || entity.type === "relation") {
38930 return selector.geometry === entity.type;
38931 } else if (entity.type === "way") {
38932 return this.inferredGeometry === entity.geometry(graph);
38935 // when geometries match and tag matches are present, return a warning...
38936 findIssues: function(entity, graph, issues) {
38937 if (this.geometryMatches(entity, graph) && this.matches(entity)) {
38938 var severity = Object.keys(selector).indexOf("error") > -1 ? "error" : "warning";
38939 var message = selector[severity];
38940 issues.push(new validationIssue({
38943 message: function() {
38946 entityIds: [entity.id]
38951 this._validationRules.push(rule);
38953 clearRules: function() {
38954 this._validationRules = [];
38956 // returns validationRules...
38957 validationRules: function() {
38958 return this._validationRules;
38960 // returns ruleChecks
38961 ruleChecks: function() {
38962 return this._ruleChecks;
38966 // modules/services/nominatim.js
38967 var import_rbush5 = __toESM(require_rbush_min());
38968 var apibase = nominatimApiUrl;
38969 var _inflight = {};
38970 var _nominatimCache;
38971 var nominatim_default = {
38974 _nominatimCache = new import_rbush5.default();
38976 reset: function() {
38977 Object.values(_inflight).forEach(function(controller) {
38978 controller.abort();
38981 _nominatimCache = new import_rbush5.default();
38983 countryCode: function(location, callback) {
38984 this.reverse(location, function(err, result) {
38986 return callback(err);
38987 } else if (result.address) {
38988 return callback(null, result.address.country_code);
38990 return callback("Unable to geocode", null);
38994 reverse: function(loc, callback) {
38995 var cached = _nominatimCache.search(
38996 { minX: loc[0], minY: loc[1], maxX: loc[0], maxY: loc[1] }
38998 if (cached.length > 0) {
39000 callback(null, cached[0].data);
39003 var params = { zoom: 13, format: "json", addressdetails: 1, lat: loc[1], lon: loc[0] };
39004 var url = apibase + "reverse?" + utilQsString(params);
39005 if (_inflight[url])
39007 var controller = new AbortController();
39008 _inflight[url] = controller;
39009 json_default(url, { signal: controller.signal }).then(function(result) {
39010 delete _inflight[url];
39011 if (result && result.error) {
39012 throw new Error(result.error);
39014 var extent = geoExtent(loc).padByMeters(200);
39015 _nominatimCache.insert(Object.assign(extent.bbox(), { data: result }));
39017 callback(null, result);
39018 }).catch(function(err) {
39019 delete _inflight[url];
39020 if (err.name === "AbortError")
39023 callback(err.message);
39026 search: function(val, callback) {
39027 var searchVal = encodeURIComponent(val);
39028 var url = apibase + "search/" + searchVal + "?limit=10&format=json";
39029 if (_inflight[url])
39031 var controller = new AbortController();
39032 _inflight[url] = controller;
39033 json_default(url, { signal: controller.signal }).then(function(result) {
39034 delete _inflight[url];
39035 if (result && result.error) {
39036 throw new Error(result.error);
39039 callback(null, result);
39040 }).catch(function(err) {
39041 delete _inflight[url];
39042 if (err.name === "AbortError")
39045 callback(err.message);
39050 // node_modules/name-suggestion-index/lib/matcher.js
39051 var import_which_polygon3 = __toESM(require_which_polygon(), 1);
39053 // node_modules/name-suggestion-index/lib/simplify.js
39054 var import_diacritics2 = __toESM(require_diacritics(), 1);
39055 function simplify(str2) {
39056 if (typeof str2 !== "string")
39058 return import_diacritics2.default.remove(
39059 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()
39063 // node_modules/name-suggestion-index/config/matchGroups.json
39064 var matchGroups_default = {
39066 adult_gaming_centre: [
39068 "amenity/gambling",
39069 "leisure/adult_gaming_centre"
39073 "shop/hairdresser_supply"
39087 "tourism/camp_site",
39088 "tourism/caravan_site"
39099 "healthcare/clinic",
39100 "healthcare/laboratory",
39101 "healthcare/physiotherapist",
39102 "healthcare/sample_collection",
39103 "healthcare/dialysis"
39108 "shop/convenience",
39116 "amenity/coworking_space",
39117 "office/coworking",
39118 "office/coworking_space"
39123 "healthcare/dentist"
39126 "office/telecommunication",
39128 "shop/electronics",
39132 "shop/mobile_phone",
39133 "shop/telecommunication"
39137 "shop/haberdashery",
39141 "shop/accessories",
39145 "shop/department_store",
39147 "shop/fashion_accessories",
39153 "office/accountant",
39154 "office/financial",
39155 "office/financial_advisor",
39156 "office/tax_advisor",
39160 "leisure/fitness_centre",
39161 "leisure/fitness_center",
39162 "leisure/sports_centre",
39163 "leisure/sports_center"
39168 "amenity/fast_food",
39169 "amenity/ice_cream",
39171 "amenity/restaurant",
39176 "shop/confectionary",
39177 "shop/confectionery",
39187 "shop/convenience;gas",
39188 "shop/gas;convenience"
39198 "shop/bathroom_furnishing",
39201 "shop/doityourself",
39206 "shop/hardware_store",
39207 "shop/power_tools",
39214 "shop/health_food",
39216 "shop/nutrition_supplements"
39219 "shop/electronics",
39226 "shop/video_games",
39231 "amenity/hospital",
39232 "healthcare/hospital"
39236 "shop/interior_decoration"
39238 lifeboat_station: [
39239 "amenity/lifeboat_station",
39240 "emergency/lifeboat_station",
39241 "emergency/marine_rescue"
39248 "amenity/money_transfer",
39249 "shop/money_transfer"
39252 "shop/office_supplies",
39262 "amenity/parcel_locker",
39263 "amenity/vending_machine"
39267 "amenity/pharmacy",
39268 "healthcare/pharmacy"
39271 "amenity/theme_park",
39272 "leisure/amusement_arcade",
39273 "leisure/playground"
39276 "amenity/bicycle_rental",
39277 "amenity/boat_rental",
39278 "amenity/car_rental",
39279 "amenity/truck_rental",
39280 "amenity/vehicle_rental",
39285 "amenity/childcare",
39287 "amenity/kindergarten",
39288 "amenity/language_school",
39289 "amenity/prep_school",
39291 "amenity/university"
39294 "shop/storage_units",
39295 "shop/storage_rental"
39299 "power/substation",
39300 "power/sub_station"
39304 "shop/frozen_food",
39305 "shop/greengrocer",
39307 "shop/supermarket",
39311 "shop/variety_store",
39316 "amenity/vending_machine",
39318 "shop/vending_machine"
39323 "amenity/weight_clinic",
39324 "healthcare/counselling",
39325 "leisure/fitness_centre",
39326 "office/therapist",
39330 "shop/health_food",
39333 "shop/nutrition_supplements",
39338 "shop/supermarket",
39339 "shop/department_store"
39344 // node_modules/name-suggestion-index/config/genericWords.json
39345 var genericWords_default = {
39347 "^(barn|bazaa?r|bench|bou?tique|building|casa|church)$",
39348 "^(baseball|basketball|football|soccer|softball|tennis(halle)?)\\s?(field|court)?$",
39349 "^(club|green|out|ware)\\s?house$",
39350 "^(driveway|el \xE1rbol|fountain|generic|golf|government|graveyard)$",
39351 "^(fixme|n\\s?\\/?\\s?a|name|no\\s?name|none|null|temporary|test|unknown)$",
39352 "^(hofladen|librairie|magazine?|maison)$",
39353 "^(mobile home|skate)?\\s?park$",
39354 "^(obuwie|pond|pool|sale|shops?|sklep|stores?)$",
39357 "^tattoo( studio)?$",
39359 "^\u0446\u0435\u0440\u043A\u043E\u0432\u043D\u0430\u044F( \u043B\u0430\u0432\u043A\u0430)?$"
39363 // node_modules/name-suggestion-index/config/trees.json
39364 var trees_default = {
39367 emoji: "\u{1F354}",
39368 mainTag: "brand:wikidata",
39369 sourceTags: ["brand", "name"],
39371 primary: "^(name|name:\\w+)$",
39372 alternate: "^(brand|brand:\\w+|operator|operator:\\w+|\\w+_name|\\w+_name:\\w+)$"
39376 emoji: "\u{1F6A9}",
39377 mainTag: "flag:wikidata",
39379 primary: "^(flag:name|flag:name:\\w+)$",
39380 alternate: "^(country|country:\\w+|flag|flag:\\w+|subject|subject:\\w+)$"
39384 emoji: "\u{1F4BC}",
39385 mainTag: "operator:wikidata",
39386 sourceTags: ["operator"],
39388 primary: "^(name|name:\\w+|operator|operator:\\w+)$",
39389 alternate: "^(brand|brand:\\w+|\\w+_name|\\w+_name:\\w+)$"
39393 emoji: "\u{1F687}",
39394 mainTag: "network:wikidata",
39395 sourceTags: ["network"],
39397 primary: "^network$",
39398 alternate: "^(operator|operator:\\w+|network:\\w+|\\w+_name|\\w+_name:\\w+)$"
39404 // node_modules/name-suggestion-index/lib/matcher.js
39405 var matchGroups = matchGroups_default.matchGroups;
39406 var trees = trees_default.trees;
39407 var Matcher = class {
39410 // initialize the genericWords regexes
39412 this.matchIndex = void 0;
39413 this.genericWords = /* @__PURE__ */ new Map();
39414 (genericWords_default.genericWords || []).forEach((s) => this.genericWords.set(s, new RegExp(s, "i")));
39415 this.itemLocation = void 0;
39416 this.locationSets = void 0;
39417 this.locationIndex = void 0;
39418 this.warnings = [];
39421 // `buildMatchIndex()`
39422 // Call this to prepare the matcher for use
39424 // `data` needs to be an Object indexed on a 'tree/key/value' path.
39425 // (e.g. cache filled by `fileTree.read` or data found in `dist/nsi.json`)
39427 // 'brands/amenity/bank': { properties: {}, items: [ {}, {}, … ] },
39428 // 'brands/amenity/bar': { properties: {}, items: [ {}, {}, … ] },
39432 buildMatchIndex(data) {
39434 if (that.matchIndex)
39436 that.matchIndex = /* @__PURE__ */ new Map();
39437 const seenTree = /* @__PURE__ */ new Map();
39438 Object.keys(data).forEach((tkv) => {
39439 const category = data[tkv];
39440 const parts = tkv.split("/", 3);
39441 const t = parts[0];
39442 const k = parts[1];
39443 const v = parts[2];
39444 const thiskv = `${k}/${v}`;
39445 const tree = trees[t];
39446 let branch = that.matchIndex.get(thiskv);
39449 primary: /* @__PURE__ */ new Map(),
39450 alternate: /* @__PURE__ */ new Map(),
39451 excludeGeneric: /* @__PURE__ */ new Map(),
39452 excludeNamed: /* @__PURE__ */ new Map()
39454 that.matchIndex.set(thiskv, branch);
39456 const properties = category.properties || {};
39457 const exclude = properties.exclude || {};
39458 (exclude.generic || []).forEach((s) => branch.excludeGeneric.set(s, new RegExp(s, "i")));
39459 (exclude.named || []).forEach((s) => branch.excludeNamed.set(s, new RegExp(s, "i")));
39460 const excludeRegexes = [...branch.excludeGeneric.values(), ...branch.excludeNamed.values()];
39461 let items = category.items;
39462 if (!Array.isArray(items) || !items.length)
39464 const primaryName = new RegExp(tree.nameTags.primary, "i");
39465 const alternateName = new RegExp(tree.nameTags.alternate, "i");
39466 const notName = /:(colou?r|type|forward|backward|left|right|etymology|pronunciation|wikipedia)$/i;
39467 const skipGenericKV = skipGenericKVMatches(t, k, v);
39468 const genericKV = /* @__PURE__ */ new Set([`${k}/yes`, `building/yes`]);
39469 const matchGroupKV = /* @__PURE__ */ new Set();
39470 Object.values(matchGroups).forEach((matchGroup) => {
39471 const inGroup = matchGroup.some((otherkv) => otherkv === thiskv);
39474 matchGroup.forEach((otherkv) => {
39475 if (otherkv === thiskv)
39477 matchGroupKV.add(otherkv);
39478 const otherk = otherkv.split("/", 2)[0];
39479 genericKV.add(`${otherk}/yes`);
39482 items.forEach((item) => {
39485 if (Array.isArray(item.matchTags) && item.matchTags.length) {
39486 item.matchTags = item.matchTags.filter((matchTag) => !matchGroupKV.has(matchTag) && !genericKV.has(matchTag));
39487 if (!item.matchTags.length)
39488 delete item.matchTags;
39490 let kvTags = [`${thiskv}`].concat(item.matchTags || []);
39491 if (!skipGenericKV) {
39492 kvTags = kvTags.concat(Array.from(genericKV));
39494 Object.keys(item.tags).forEach((osmkey) => {
39495 if (notName.test(osmkey))
39497 const osmvalue = item.tags[osmkey];
39498 if (!osmvalue || excludeRegexes.some((regex) => regex.test(osmvalue)))
39500 if (primaryName.test(osmkey)) {
39501 kvTags.forEach((kv) => insertName("primary", t, kv, simplify(osmvalue), item.id));
39502 } else if (alternateName.test(osmkey)) {
39503 kvTags.forEach((kv) => insertName("alternate", t, kv, simplify(osmvalue), item.id));
39506 let keepMatchNames = /* @__PURE__ */ new Set();
39507 (item.matchNames || []).forEach((matchName) => {
39508 const nsimple = simplify(matchName);
39509 kvTags.forEach((kv) => {
39510 const branch2 = that.matchIndex.get(kv);
39511 const primaryLeaf = branch2 && branch2.primary.get(nsimple);
39512 const alternateLeaf = branch2 && branch2.alternate.get(nsimple);
39513 const inPrimary = primaryLeaf && primaryLeaf.has(item.id);
39514 const inAlternate = alternateLeaf && alternateLeaf.has(item.id);
39515 if (!inPrimary && !inAlternate) {
39516 insertName("alternate", t, kv, nsimple, item.id);
39517 keepMatchNames.add(matchName);
39521 if (keepMatchNames.size) {
39522 item.matchNames = Array.from(keepMatchNames);
39524 delete item.matchNames;
39528 function insertName(which, t, kv, nsimple, itemID) {
39530 that.warnings.push(`Warning: skipping empty ${which} name for item ${t}/${kv}: ${itemID}`);
39533 let branch = that.matchIndex.get(kv);
39536 primary: /* @__PURE__ */ new Map(),
39537 alternate: /* @__PURE__ */ new Map(),
39538 excludeGeneric: /* @__PURE__ */ new Map(),
39539 excludeNamed: /* @__PURE__ */ new Map()
39541 that.matchIndex.set(kv, branch);
39543 let leaf = branch[which].get(nsimple);
39545 leaf = /* @__PURE__ */ new Set();
39546 branch[which].set(nsimple, leaf);
39549 if (!/yes$/.test(kv)) {
39550 const kvnsimple = `${kv}/${nsimple}`;
39551 const existing = seenTree.get(kvnsimple);
39552 if (existing && existing !== t) {
39553 const items = Array.from(leaf);
39554 that.warnings.push(`Duplicate cache key "${kvnsimple}" in trees "${t}" and "${existing}", check items: ${items}`);
39557 seenTree.set(kvnsimple, t);
39560 function skipGenericKVMatches(t, k, v) {
39561 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";
39565 // `buildLocationIndex()`
39566 // Call this to prepare a which-polygon location index.
39567 // This *resolves* all the locationSets into GeoJSON, which takes some time.
39568 // You can skip this step if you don't care about matching within a location.
39570 // `data` needs to be an Object indexed on a 'tree/key/value' path.
39571 // (e.g. cache filled by `fileTree.read` or data found in `dist/nsi.json`)
39573 // 'brands/amenity/bank': { properties: {}, items: [ {}, {}, … ] },
39574 // 'brands/amenity/bar': { properties: {}, items: [ {}, {}, … ] },
39578 buildLocationIndex(data, loco) {
39580 if (that.locationIndex)
39582 that.itemLocation = /* @__PURE__ */ new Map();
39583 that.locationSets = /* @__PURE__ */ new Map();
39584 Object.keys(data).forEach((tkv) => {
39585 const items = data[tkv].items;
39586 if (!Array.isArray(items) || !items.length)
39588 items.forEach((item) => {
39589 if (that.itemLocation.has(item.id))
39593 resolved = loco.resolveLocationSet(item.locationSet);
39595 console.warn(`buildLocationIndex: ${err.message}`);
39597 if (!resolved || !resolved.id)
39599 that.itemLocation.set(item.id, resolved.id);
39600 if (that.locationSets.has(resolved.id))
39602 let feature3 = _cloneDeep2(resolved.feature);
39603 feature3.id = resolved.id;
39604 feature3.properties.id = resolved.id;
39605 if (!feature3.geometry.coordinates.length || !feature3.properties.area) {
39606 console.warn(`buildLocationIndex: locationSet ${resolved.id} for ${item.id} resolves to an empty feature:`);
39607 console.warn(JSON.stringify(feature3));
39610 that.locationSets.set(resolved.id, feature3);
39613 that.locationIndex = (0, import_which_polygon3.default)({ type: "FeatureCollection", features: [...that.locationSets.values()] });
39614 function _cloneDeep2(obj) {
39615 return JSON.parse(JSON.stringify(obj));
39620 // Pass parts and return an Array of matches.
39624 // `loc` - optional - [lon,lat] location to search
39626 // 1. If the [k,v,n] tuple matches a canonical item…
39627 // Return an Array of match results.
39628 // Each result will include the area in km² that the item is valid.
39630 // Order of results:
39631 // Primary ordering will be on the "match" column:
39632 // "primary" - where the query matches the `name` tag, followed by
39633 // "alternate" - where the query matches an alternate name tag (e.g. short_name, brand, operator, etc)
39634 // Secondary ordering will be on the "area" column:
39635 // "area descending" if no location was provided, (worldwide before local)
39636 // "area ascending" if location was provided (local before worldwide)
39639 // { match: 'primary', itemID: String, area: Number, kv: String, nsimple: String },
39640 // { match: 'primary', itemID: String, area: Number, kv: String, nsimple: String },
39641 // { match: 'alternate', itemID: String, area: Number, kv: String, nsimple: String },
39642 // { match: 'alternate', itemID: String, area: Number, kv: String, nsimple: String },
39648 // 2. If the [k,v,n] tuple matches an exclude pattern…
39649 // Return an Array with a single exclude result, either
39651 // [ { match: 'excludeGeneric', pattern: String, kv: String } ] // "generic" e.g. "Food Court"
39653 // [ { match: 'excludeNamed', pattern: String, kv: String } ] // "named", e.g. "Kebabai"
39656 // "generic" - a generic word that is probably not really a name.
39657 // For these, iD should warn the user "Hey don't put 'food court' in the name tag".
39658 // "named" - a real name like "Kebabai" that is just common, but not a brand.
39659 // For these, iD should just let it be. We don't include these in NSI, but we don't want to nag users about it either.
39663 // 3. If the [k,v,n] tuple matches nothing of any kind, return `null`
39666 match(k, v, n2, loc) {
39668 if (!that.matchIndex) {
39669 throw new Error("match: matchIndex not built.");
39671 let matchLocations;
39672 if (Array.isArray(loc) && that.locationIndex) {
39673 matchLocations = that.locationIndex([loc[0], loc[1], loc[0], loc[1]], true);
39675 const nsimple = simplify(n2);
39676 let seen = /* @__PURE__ */ new Set();
39678 gatherResults("primary");
39679 gatherResults("alternate");
39680 if (results.length)
39682 gatherResults("exclude");
39683 return results.length ? results : null;
39684 function gatherResults(which) {
39685 const kv = `${k}/${v}`;
39686 let didMatch = tryMatch(which, kv);
39689 for (let mg in matchGroups) {
39690 const matchGroup = matchGroups[mg];
39691 const inGroup = matchGroup.some((otherkv) => otherkv === kv);
39694 for (let i2 = 0; i2 < matchGroup.length; i2++) {
39695 const otherkv = matchGroup[i2];
39696 if (otherkv === kv)
39698 didMatch = tryMatch(which, otherkv);
39703 if (which === "exclude") {
39704 const regex = [...that.genericWords.values()].find((regex2) => regex2.test(n2));
39706 results.push({ match: "excludeGeneric", pattern: String(regex) });
39711 function tryMatch(which, kv) {
39712 const branch = that.matchIndex.get(kv);
39715 if (which === "exclude") {
39716 let regex = [...branch.excludeNamed.values()].find((regex2) => regex2.test(n2));
39718 results.push({ match: "excludeNamed", pattern: String(regex), kv });
39721 regex = [...branch.excludeGeneric.values()].find((regex2) => regex2.test(n2));
39723 results.push({ match: "excludeGeneric", pattern: String(regex), kv });
39728 const leaf = branch[which].get(nsimple);
39729 if (!leaf || !leaf.size)
39731 let hits = Array.from(leaf).map((itemID) => {
39732 let area = Infinity;
39733 if (that.itemLocation && that.locationSets) {
39734 const location = that.locationSets.get(that.itemLocation.get(itemID));
39735 area = location && location.properties.area || Infinity;
39737 return { match: which, itemID, area, kv, nsimple };
39739 let sortFn = byAreaDescending;
39740 if (matchLocations) {
39741 hits = hits.filter(isValidLocation);
39742 sortFn = byAreaAscending;
39746 hits.sort(sortFn).forEach((hit) => {
39747 if (seen.has(hit.itemID))
39749 seen.add(hit.itemID);
39753 function isValidLocation(hit) {
39754 if (!that.itemLocation)
39756 return matchLocations.find((props) => props.id === that.itemLocation.get(hit.itemID));
39758 function byAreaAscending(hitA, hitB) {
39759 return hitA.area - hitB.area;
39761 function byAreaDescending(hitA, hitB) {
39762 return hitB.area - hitA.area;
39768 // Return any warnings discovered when buiding the index.
39769 // (currently this does nothing)
39772 return this.warnings;
39776 // modules/services/nsi.js
39777 var import_vparse2 = __toESM(require_vparse());
39779 // modules/core/difference.js
39780 var import_fast_deep_equal3 = __toESM(require_fast_deep_equal());
39781 function coreDifference(base, head) {
39783 var _didChange = {};
39785 function checkEntityID(id2) {
39786 var h = head.entities[id2];
39787 var b = base.entities[id2];
39793 _changes[id2] = { base: b, head: h };
39794 _didChange.deletion = true;
39798 _changes[id2] = { base: b, head: h };
39799 _didChange.addition = true;
39803 if (h.members && b.members && !(0, import_fast_deep_equal3.default)(h.members, b.members)) {
39804 _changes[id2] = { base: b, head: h };
39805 _didChange.geometry = true;
39806 _didChange.properties = true;
39809 if (h.loc && b.loc && !geoVecEqual(h.loc, b.loc)) {
39810 _changes[id2] = { base: b, head: h };
39811 _didChange.geometry = true;
39813 if (h.nodes && b.nodes && !(0, import_fast_deep_equal3.default)(h.nodes, b.nodes)) {
39814 _changes[id2] = { base: b, head: h };
39815 _didChange.geometry = true;
39817 if (h.tags && b.tags && !(0, import_fast_deep_equal3.default)(h.tags, b.tags)) {
39818 _changes[id2] = { base: b, head: h };
39819 _didChange.properties = true;
39824 var ids = utilArrayUniq(Object.keys(head.entities).concat(Object.keys(base.entities)));
39825 for (var i2 = 0; i2 < ids.length; i2++) {
39826 checkEntityID(ids[i2]);
39830 _diff.length = function length() {
39831 return Object.keys(_changes).length;
39833 _diff.changes = function changes() {
39836 _diff.didChange = _didChange;
39837 _diff.extantIDs = function extantIDs(includeRelMembers) {
39838 var result = /* @__PURE__ */ new Set();
39839 Object.keys(_changes).forEach(function(id2) {
39840 if (_changes[id2].head) {
39843 var h = _changes[id2].head;
39844 var b = _changes[id2].base;
39845 var entity = h || b;
39846 if (includeRelMembers && entity.type === "relation") {
39847 var mh = h ? h.members.map(function(m) {
39850 var mb = b ? b.members.map(function(m) {
39853 utilArrayUnion(mh, mb).forEach(function(memberID) {
39854 if (head.hasEntity(memberID)) {
39855 result.add(memberID);
39860 return Array.from(result);
39862 _diff.modified = function modified() {
39864 Object.values(_changes).forEach(function(change) {
39865 if (change.base && change.head) {
39866 result.push(change.head);
39871 _diff.created = function created() {
39873 Object.values(_changes).forEach(function(change) {
39874 if (!change.base && change.head) {
39875 result.push(change.head);
39880 _diff.deleted = function deleted() {
39882 Object.values(_changes).forEach(function(change) {
39883 if (change.base && !change.head) {
39884 result.push(change.base);
39889 _diff.summary = function summary() {
39891 var keys = Object.keys(_changes);
39892 for (var i2 = 0; i2 < keys.length; i2++) {
39893 var change = _changes[keys[i2]];
39894 if (change.head && change.head.geometry(head) !== "vertex") {
39895 addEntity(change.head, head, change.base ? "modified" : "created");
39896 } else if (change.base && change.base.geometry(base) !== "vertex") {
39897 addEntity(change.base, base, "deleted");
39898 } else if (change.base && change.head) {
39899 var moved = !(0, import_fast_deep_equal3.default)(change.base.loc, change.head.loc);
39900 var retagged = !(0, import_fast_deep_equal3.default)(change.base.tags, change.head.tags);
39902 addParents(change.head);
39904 if (retagged || moved && change.head.hasInterestingTags()) {
39905 addEntity(change.head, head, "modified");
39907 } else if (change.head && change.head.hasInterestingTags()) {
39908 addEntity(change.head, head, "created");
39909 } else if (change.base && change.base.hasInterestingTags()) {
39910 addEntity(change.base, base, "deleted");
39913 return Object.values(relevant);
39914 function addEntity(entity, graph, changeType) {
39915 relevant[entity.id] = {
39921 function addParents(entity) {
39922 var parents = head.parentWays(entity);
39923 for (var j2 = parents.length - 1; j2 >= 0; j2--) {
39924 var parent = parents[j2];
39925 if (!(parent.id in relevant)) {
39926 addEntity(parent, head, "modified");
39931 _diff.complete = function complete(extent) {
39934 for (id2 in _changes) {
39935 change = _changes[id2];
39936 var h = change.head;
39937 var b = change.base;
39938 var entity = h || b;
39940 if (extent && (!h || !h.intersects(extent, head)) && (!b || !b.intersects(extent, base))) {
39944 if (entity.type === "way") {
39945 var nh = h ? h.nodes : [];
39946 var nb = b ? b.nodes : [];
39948 diff = utilArrayDifference(nh, nb);
39949 for (i2 = 0; i2 < diff.length; i2++) {
39950 result[diff[i2]] = head.hasEntity(diff[i2]);
39952 diff = utilArrayDifference(nb, nh);
39953 for (i2 = 0; i2 < diff.length; i2++) {
39954 result[diff[i2]] = head.hasEntity(diff[i2]);
39957 if (entity.type === "relation" && entity.isMultipolygon()) {
39958 var mh = h ? h.members.map(function(m) {
39961 var mb = b ? b.members.map(function(m) {
39964 var ids = utilArrayUnion(mh, mb);
39965 for (i2 = 0; i2 < ids.length; i2++) {
39966 var member = head.hasEntity(ids[i2]);
39969 if (extent && !member.intersects(extent, head))
39971 result[ids[i2]] = member;
39974 addParents(head.parentWays(entity), result);
39975 addParents(head.parentRelations(entity), result);
39978 function addParents(parents, result2) {
39979 for (var i3 = 0; i3 < parents.length; i3++) {
39980 var parent = parents[i3];
39981 if (parent.id in result2)
39983 result2[parent.id] = parent;
39984 addParents(head.parentRelations(parent), result2);
39991 // modules/core/tree.js
39992 var import_rbush6 = __toESM(require_rbush_min());
39993 function coreTree(head) {
39994 var _rtree = new import_rbush6.default();
39996 var _segmentsRTree = new import_rbush6.default();
39997 var _segmentsBBoxes = {};
39998 var _segmentsByWayId = {};
40000 function entityBBox(entity) {
40001 var bbox2 = entity.extent(head).bbox();
40002 bbox2.id = entity.id;
40003 _bboxes[entity.id] = bbox2;
40006 function segmentBBox(segment) {
40007 var extent = segment.extent(head);
40010 var bbox2 = extent.bbox();
40011 bbox2.segment = segment;
40012 _segmentsBBoxes[segment.id] = bbox2;
40015 function removeEntity(entity) {
40016 _rtree.remove(_bboxes[entity.id]);
40017 delete _bboxes[entity.id];
40018 if (_segmentsByWayId[entity.id]) {
40019 _segmentsByWayId[entity.id].forEach(function(segment) {
40020 _segmentsRTree.remove(_segmentsBBoxes[segment.id]);
40021 delete _segmentsBBoxes[segment.id];
40023 delete _segmentsByWayId[entity.id];
40026 function loadEntities(entities) {
40027 _rtree.load(entities.map(entityBBox));
40029 entities.forEach(function(entity) {
40030 if (entity.segments) {
40031 var entitySegments = entity.segments(head);
40032 _segmentsByWayId[entity.id] = entitySegments;
40033 segments = segments.concat(entitySegments);
40036 if (segments.length)
40037 _segmentsRTree.load(segments.map(segmentBBox).filter(Boolean));
40039 function updateParents(entity, insertions, memo) {
40040 head.parentWays(entity).forEach(function(way) {
40041 if (_bboxes[way.id]) {
40043 insertions[way.id] = way;
40045 updateParents(way, insertions, memo);
40047 head.parentRelations(entity).forEach(function(relation) {
40048 if (memo[entity.id])
40050 memo[entity.id] = true;
40051 if (_bboxes[relation.id]) {
40052 removeEntity(relation);
40053 insertions[relation.id] = relation;
40055 updateParents(relation, insertions, memo);
40058 tree.rebase = function(entities, force) {
40059 var insertions = {};
40060 for (var i2 = 0; i2 < entities.length; i2++) {
40061 var entity = entities[i2];
40062 if (!entity.visible)
40064 if (head.entities.hasOwnProperty(entity.id) || _bboxes[entity.id]) {
40067 } else if (_bboxes[entity.id]) {
40068 removeEntity(entity);
40071 insertions[entity.id] = entity;
40072 updateParents(entity, insertions, {});
40074 loadEntities(Object.values(insertions));
40077 function updateToGraph(graph) {
40078 if (graph === head)
40080 var diff = coreDifference(head, graph);
40082 var changed = diff.didChange;
40083 if (!changed.addition && !changed.deletion && !changed.geometry)
40085 var insertions = {};
40086 if (changed.deletion) {
40087 diff.deleted().forEach(function(entity) {
40088 removeEntity(entity);
40091 if (changed.geometry) {
40092 diff.modified().forEach(function(entity) {
40093 removeEntity(entity);
40094 insertions[entity.id] = entity;
40095 updateParents(entity, insertions, {});
40098 if (changed.addition) {
40099 diff.created().forEach(function(entity) {
40100 insertions[entity.id] = entity;
40103 loadEntities(Object.values(insertions));
40105 tree.intersects = function(extent, graph) {
40106 updateToGraph(graph);
40107 return _rtree.search(extent.bbox()).map(function(bbox2) {
40108 return graph.entity(bbox2.id);
40111 tree.waySegments = function(extent, graph) {
40112 updateToGraph(graph);
40113 return _segmentsRTree.search(extent.bbox()).map(function(bbox2) {
40114 return bbox2.segment;
40120 // modules/svg/icon.js
40121 function svgIcon(name, svgklass, useklass) {
40122 return function drawIcon(selection2) {
40123 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);
40127 // modules/ui/modal.js
40128 function uiModal(selection2, blocking) {
40129 let keybinding = utilKeybinding("modal");
40130 let previous = selection2.select("div.modal");
40131 let animate = previous.empty();
40132 previous.transition().duration(200).style("opacity", 0).remove();
40133 let shaded = selection2.append("div").attr("class", "shaded").style("opacity", 0);
40134 shaded.close = () => {
40135 shaded.transition().duration(200).style("opacity", 0).remove();
40136 modal.transition().duration(200).style("top", "0px");
40137 select_default2(document).call(keybinding.unbind);
40139 let modal = shaded.append("div").attr("class", "modal fillL");
40140 modal.append("input").attr("class", "keytrap keytrap-first").on("focus.keytrap", moveFocusToLast);
40142 shaded.on("click.remove-modal", (d3_event) => {
40143 if (d3_event.target === this) {
40147 modal.append("button").attr("class", "close").attr("title", _t("icons.close")).on("click", shaded.close).call(svgIcon("#iD-icon-close"));
40148 keybinding.on("\u232B", shaded.close).on("\u238B", shaded.close);
40149 select_default2(document).call(keybinding);
40151 modal.append("div").attr("class", "content");
40152 modal.append("input").attr("class", "keytrap keytrap-last").on("focus.keytrap", moveFocusToFirst);
40154 shaded.transition().style("opacity", 1);
40156 shaded.style("opacity", 1);
40159 function moveFocusToFirst() {
40160 let node = modal.select("a, button, input:not(.keytrap), select, textarea").node();
40164 select_default2(this).node().blur();
40167 function moveFocusToLast() {
40168 let nodes = modal.selectAll("a, button, input:not(.keytrap), select, textarea").nodes();
40169 if (nodes.length) {
40170 nodes[nodes.length - 1].focus();
40172 select_default2(this).node().blur();
40177 // modules/ui/loading.js
40178 function uiLoading(context) {
40179 let _modalSelection = select_default2(null);
40181 let _blocking = false;
40182 let loading = (selection2) => {
40183 _modalSelection = uiModal(selection2, _blocking);
40184 let loadertext = _modalSelection.select(".content").classed("loading-modal", true).append("div").attr("class", "modal-section fillL");
40185 loadertext.append("img").attr("class", "loader").attr("src", context.imagePath("loader-white.gif"));
40186 loadertext.append("h3").html(_message);
40187 _modalSelection.select("button.close").attr("class", "hide");
40190 loading.message = function(val) {
40191 if (!arguments.length)
40196 loading.blocking = function(val) {
40197 if (!arguments.length)
40202 loading.close = () => {
40203 _modalSelection.remove();
40205 loading.isShown = () => {
40206 return _modalSelection && !_modalSelection.empty() && _modalSelection.node().parentNode;
40211 // modules/core/history.js
40212 function coreHistory(context) {
40213 var dispatch10 = dispatch_default("reset", "change", "merge", "restore", "undone", "redone", "storage_error");
40214 var lock = utilSessionMutex("lock");
40215 var _hasUnresolvedRestorableChanges = lock.lock() && !!corePreferences(getKey("saved_history"));
40216 var duration = 150;
40217 var _imageryUsed = [];
40218 var _photoOverlaysUsed = [];
40219 var _checkpoints = {};
40224 function _act(actions, t) {
40225 actions = Array.prototype.slice.call(actions);
40227 if (typeof actions[actions.length - 1] !== "function") {
40228 annotation = actions.pop();
40230 var graph = _stack[_index].graph;
40231 for (var i2 = 0; i2 < actions.length; i2++) {
40232 graph = actions[i2](graph, t);
40237 imageryUsed: _imageryUsed,
40238 photoOverlaysUsed: _photoOverlaysUsed,
40239 transform: context.projection.transform(),
40240 selectedIDs: context.selectedIDs()
40243 function _perform(args, t) {
40244 var previous = _stack[_index].graph;
40245 _stack = _stack.slice(0, _index + 1);
40246 var actionResult = _act(args, t);
40247 _stack.push(actionResult);
40249 return change(previous);
40251 function _replace(args, t) {
40252 var previous = _stack[_index].graph;
40253 var actionResult = _act(args, t);
40254 _stack[_index] = actionResult;
40255 return change(previous);
40257 function _overwrite(args, t) {
40258 var previous = _stack[_index].graph;
40263 _stack = _stack.slice(0, _index + 1);
40264 var actionResult = _act(args, t);
40265 _stack.push(actionResult);
40267 return change(previous);
40269 function change(previous) {
40270 var difference = coreDifference(previous, history.graph());
40271 if (!_pausedGraph) {
40272 dispatch10.call("change", this, difference);
40276 function getKey(n2) {
40277 return "iD_" + window.location.origin + "_" + n2;
40280 graph: function() {
40281 return _stack[_index].graph;
40287 return _stack[0].graph;
40289 merge: function(entities) {
40290 var stack = _stack.map(function(state) {
40291 return state.graph;
40293 _stack[0].graph.rebase(entities, stack, false);
40294 _tree.rebase(entities, false);
40295 dispatch10.call("merge", this, entities);
40297 perform: function() {
40298 select_default2(document).interrupt("history.perform");
40299 var transitionable = false;
40300 var action0 = arguments[0];
40301 if (arguments.length === 1 || arguments.length === 2 && typeof arguments[1] !== "function") {
40302 transitionable = !!action0.transitionable;
40304 if (transitionable) {
40305 var origArguments = arguments;
40306 select_default2(document).transition("history.perform").duration(duration).ease(linear2).tween("history.tween", function() {
40307 return function(t) {
40309 _overwrite([action0], t);
40311 }).on("start", function() {
40312 _perform([action0], 0);
40313 }).on("end interrupt", function() {
40314 _overwrite(origArguments, 1);
40317 return _perform(arguments);
40320 replace: function() {
40321 select_default2(document).interrupt("history.perform");
40322 return _replace(arguments, 1);
40324 // Same as calling pop and then perform
40325 overwrite: function() {
40326 select_default2(document).interrupt("history.perform");
40327 return _overwrite(arguments, 1);
40329 pop: function(n2) {
40330 select_default2(document).interrupt("history.perform");
40331 var previous = _stack[_index].graph;
40332 if (isNaN(+n2) || +n2 < 0) {
40335 while (n2-- > 0 && _index > 0) {
40339 return change(previous);
40341 // Back to the previous annotated state or _index = 0.
40343 select_default2(document).interrupt("history.perform");
40344 var previousStack = _stack[_index];
40345 var previous = previousStack.graph;
40346 while (_index > 0) {
40348 if (_stack[_index].annotation)
40351 dispatch10.call("undone", this, _stack[_index], previousStack);
40352 return change(previous);
40354 // Forward to the next annotated state.
40356 select_default2(document).interrupt("history.perform");
40357 var previousStack = _stack[_index];
40358 var previous = previousStack.graph;
40359 var tryIndex = _index;
40360 while (tryIndex < _stack.length - 1) {
40362 if (_stack[tryIndex].annotation) {
40364 dispatch10.call("redone", this, _stack[_index], previousStack);
40368 return change(previous);
40370 pauseChangeDispatch: function() {
40371 if (!_pausedGraph) {
40372 _pausedGraph = _stack[_index].graph;
40375 resumeChangeDispatch: function() {
40376 if (_pausedGraph) {
40377 var previous = _pausedGraph;
40378 _pausedGraph = null;
40379 return change(previous);
40382 undoAnnotation: function() {
40385 if (_stack[i2].annotation)
40386 return _stack[i2].annotation;
40390 redoAnnotation: function() {
40391 var i2 = _index + 1;
40392 while (i2 <= _stack.length - 1) {
40393 if (_stack[i2].annotation)
40394 return _stack[i2].annotation;
40398 // Returns the entities from the active graph with bounding boxes
40399 // overlapping the given `extent`.
40400 intersects: function(extent) {
40401 return _tree.intersects(extent, _stack[_index].graph);
40403 difference: function() {
40404 var base = _stack[0].graph;
40405 var head = _stack[_index].graph;
40406 return coreDifference(base, head);
40408 changes: function(action) {
40409 var base = _stack[0].graph;
40410 var head = _stack[_index].graph;
40412 head = action(head);
40414 var difference = coreDifference(base, head);
40416 modified: difference.modified(),
40417 created: difference.created(),
40418 deleted: difference.deleted()
40421 hasChanges: function() {
40422 return this.difference().length() > 0;
40424 imageryUsed: function(sources) {
40426 _imageryUsed = sources;
40429 var s = /* @__PURE__ */ new Set();
40430 _stack.slice(1, _index + 1).forEach(function(state) {
40431 state.imageryUsed.forEach(function(source) {
40432 if (source !== "Custom") {
40437 return Array.from(s);
40440 photoOverlaysUsed: function(sources) {
40442 _photoOverlaysUsed = sources;
40445 var s = /* @__PURE__ */ new Set();
40446 _stack.slice(1, _index + 1).forEach(function(state) {
40447 if (state.photoOverlaysUsed && Array.isArray(state.photoOverlaysUsed)) {
40448 state.photoOverlaysUsed.forEach(function(photoOverlay) {
40449 s.add(photoOverlay);
40453 return Array.from(s);
40456 // save the current history state
40457 checkpoint: function(key) {
40458 _checkpoints[key] = {
40464 // restore history state to a given checkpoint or reset completely
40465 reset: function(key) {
40466 if (key !== void 0 && _checkpoints.hasOwnProperty(key)) {
40467 _stack = _checkpoints[key].stack;
40468 _index = _checkpoints[key].index;
40470 _stack = [{ graph: coreGraph() }];
40472 _tree = coreTree(_stack[0].graph);
40475 dispatch10.call("reset");
40476 dispatch10.call("change");
40479 // `toIntroGraph()` is used to export the intro graph used by the walkthrough.
40482 // 1. Start the walkthrough.
40483 // 2. Get to a "free editing" tutorial step
40484 // 3. Make your edits to the walkthrough map
40485 // 4. In your browser dev console run:
40486 // `id.history().toIntroGraph()`
40487 // 5. This outputs stringified JSON to the browser console
40488 // 6. Copy it to `data/intro_graph.json` and prettify it in your code editor
40489 toIntroGraph: function() {
40490 var nextID = { n: 0, r: 0, w: 0 };
40492 var graph = this.graph();
40493 var baseEntities = {};
40494 Object.values(graph.base().entities).forEach(function(entity) {
40495 var copy2 = copyIntroEntity(entity);
40496 baseEntities[copy2.id] = copy2;
40498 Object.keys(graph.entities).forEach(function(id2) {
40499 var entity = graph.entities[id2];
40501 var copy2 = copyIntroEntity(entity);
40502 baseEntities[copy2.id] = copy2;
40504 delete baseEntities[id2];
40507 Object.values(baseEntities).forEach(function(entity) {
40508 if (Array.isArray(entity.nodes)) {
40509 entity.nodes = entity.nodes.map(function(node) {
40510 return permIDs[node] || node;
40513 if (Array.isArray(entity.members)) {
40514 entity.members = entity.members.map(function(member) {
40515 member.id = permIDs[member.id] || member.id;
40520 return JSON.stringify({ dataIntroGraph: baseEntities });
40521 function copyIntroEntity(source) {
40522 var copy2 = utilObjectOmit(source, ["type", "user", "v", "version", "visible"]);
40523 if (copy2.tags && !Object.keys(copy2.tags)) {
40526 if (Array.isArray(copy2.loc)) {
40527 copy2.loc[0] = +copy2.loc[0].toFixed(6);
40528 copy2.loc[1] = +copy2.loc[1].toFixed(6);
40530 var match = source.id.match(/([nrw])-\d*/);
40531 if (match !== null) {
40532 var nrw = match[1];
40535 permID = nrw + ++nextID[nrw];
40536 } while (baseEntities.hasOwnProperty(permID));
40537 copy2.id = permIDs[source.id] = permID;
40542 toJSON: function() {
40543 if (!this.hasChanges())
40545 var allEntities = {};
40546 var baseEntities = {};
40547 var base = _stack[0];
40548 var s = _stack.map(function(i2) {
40551 Object.keys(i2.graph.entities).forEach(function(id2) {
40552 var entity = i2.graph.entities[id2];
40554 var key = osmEntity.key(entity);
40555 allEntities[key] = entity;
40556 modified.push(key);
40560 if (id2 in base.graph.entities) {
40561 baseEntities[id2] = base.graph.entities[id2];
40563 if (entity && entity.nodes) {
40564 entity.nodes.forEach(function(nodeID) {
40565 if (nodeID in base.graph.entities) {
40566 baseEntities[nodeID] = base.graph.entities[nodeID];
40570 var baseParents = base.graph._parentWays[id2];
40572 baseParents.forEach(function(parentID) {
40573 if (parentID in base.graph.entities) {
40574 baseEntities[parentID] = base.graph.entities[parentID];
40580 if (modified.length)
40581 x.modified = modified;
40582 if (deleted.length)
40583 x.deleted = deleted;
40584 if (i2.imageryUsed)
40585 x.imageryUsed = i2.imageryUsed;
40586 if (i2.photoOverlaysUsed)
40587 x.photoOverlaysUsed = i2.photoOverlaysUsed;
40589 x.annotation = i2.annotation;
40591 x.transform = i2.transform;
40592 if (i2.selectedIDs)
40593 x.selectedIDs = i2.selectedIDs;
40596 return JSON.stringify({
40598 entities: Object.values(allEntities),
40599 baseEntities: Object.values(baseEntities),
40601 nextIDs: osmEntity.id.next,
40603 // note the time the changes were saved
40604 timestamp: (/* @__PURE__ */ new Date()).getTime()
40607 fromJSON: function(json, loadChildNodes) {
40608 var h = JSON.parse(json);
40609 var loadComplete = true;
40610 osmEntity.id.next = h.nextIDs;
40612 if (h.version === 2 || h.version === 3) {
40613 var allEntities = {};
40614 h.entities.forEach(function(entity) {
40615 allEntities[osmEntity.key(entity)] = osmEntity(entity);
40617 if (h.version === 3) {
40618 var baseEntities = h.baseEntities.map(function(d) {
40619 return osmEntity(d);
40621 var stack = _stack.map(function(state) {
40622 return state.graph;
40624 _stack[0].graph.rebase(baseEntities, stack, true);
40625 _tree.rebase(baseEntities, true);
40626 if (loadChildNodes) {
40627 var osm = context.connection();
40628 var baseWays = baseEntities.filter(function(e) {
40629 return e.type === "way";
40631 var nodeIDs = baseWays.reduce(function(acc, way) {
40632 return utilArrayUnion(acc, way.nodes);
40634 var missing = nodeIDs.filter(function(n2) {
40635 return !_stack[0].graph.hasEntity(n2);
40637 if (missing.length && osm) {
40638 loadComplete = false;
40639 context.map().redrawEnable(false);
40640 var loading = uiLoading(context).blocking(true);
40641 context.container().call(loading);
40642 var childNodesLoaded = function(err, result) {
40644 var visibleGroups = utilArrayGroupBy(result.data, "visible");
40645 var visibles = visibleGroups.true || [];
40646 var invisibles = visibleGroups.false || [];
40647 if (visibles.length) {
40648 var visibleIDs = visibles.map(function(entity) {
40651 var stack2 = _stack.map(function(state) {
40652 return state.graph;
40654 missing = utilArrayDifference(missing, visibleIDs);
40655 _stack[0].graph.rebase(visibles, stack2, true);
40656 _tree.rebase(visibles, true);
40658 invisibles.forEach(function(entity) {
40659 osm.loadEntityVersion(entity.id, +entity.version - 1, childNodesLoaded);
40662 if (err || !missing.length) {
40664 context.map().redrawEnable(true);
40665 dispatch10.call("change");
40666 dispatch10.call("restore", this);
40669 osm.loadMultiple(missing, childNodesLoaded);
40673 _stack = h.stack.map(function(d) {
40674 var entities = {}, entity;
40676 d.modified.forEach(function(key) {
40677 entity = allEntities[key];
40678 entities[entity.id] = entity;
40682 d.deleted.forEach(function(id2) {
40683 entities[id2] = void 0;
40687 graph: coreGraph(_stack[0].graph).load(entities),
40688 annotation: d.annotation,
40689 imageryUsed: d.imageryUsed,
40690 photoOverlaysUsed: d.photoOverlaysUsed,
40691 transform: d.transform,
40692 selectedIDs: d.selectedIDs
40696 _stack = h.stack.map(function(d) {
40698 for (var i2 in d.entities) {
40699 var entity = d.entities[i2];
40700 entities[i2] = entity === "undefined" ? void 0 : osmEntity(entity);
40702 d.graph = coreGraph(_stack[0].graph).load(entities);
40706 var transform2 = _stack[_index].transform;
40708 context.map().transformEase(transform2, 0);
40710 if (loadComplete) {
40711 dispatch10.call("change");
40712 dispatch10.call("restore", this);
40717 return lock.lock();
40719 unlock: function() {
40723 if (lock.locked() && // don't overwrite existing, unresolved changes
40724 !_hasUnresolvedRestorableChanges) {
40725 const success = corePreferences(getKey("saved_history"), history.toJSON() || null);
40727 dispatch10.call("storage_error");
40731 // delete the history version saved in localStorage
40732 clearSaved: function() {
40733 context.debouncedSave.cancel();
40734 if (lock.locked()) {
40735 _hasUnresolvedRestorableChanges = false;
40736 corePreferences(getKey("saved_history"), null);
40737 corePreferences("comment", null);
40738 corePreferences("hashtags", null);
40739 corePreferences("source", null);
40743 savedHistoryJSON: function() {
40744 return corePreferences(getKey("saved_history"));
40746 hasRestorableChanges: function() {
40747 return _hasUnresolvedRestorableChanges;
40749 // load history from a version stored in localStorage
40750 restore: function() {
40751 if (lock.locked()) {
40752 _hasUnresolvedRestorableChanges = false;
40753 var json = this.savedHistoryJSON();
40755 history.fromJSON(json, true);
40761 return utilRebind(history, dispatch10, "on");
40764 // modules/validations/index.js
40765 var validations_exports = {};
40766 __export(validations_exports, {
40767 validationAlmostJunction: () => validationAlmostJunction,
40768 validationCloseNodes: () => validationCloseNodes,
40769 validationCrossingWays: () => validationCrossingWays,
40770 validationDisconnectedWay: () => validationDisconnectedWay,
40771 validationFormatting: () => validationFormatting,
40772 validationHelpRequest: () => validationHelpRequest,
40773 validationImpossibleOneway: () => validationImpossibleOneway,
40774 validationIncompatibleSource: () => validationIncompatibleSource,
40775 validationMaprules: () => validationMaprules,
40776 validationMismatchedGeometry: () => validationMismatchedGeometry,
40777 validationMissingRole: () => validationMissingRole,
40778 validationMissingTag: () => validationMissingTag,
40779 validationOutdatedTags: () => validationOutdatedTags,
40780 validationPrivateData: () => validationPrivateData,
40781 validationSuspiciousName: () => validationSuspiciousName,
40782 validationUnsquareWay: () => validationUnsquareWay
40785 // modules/validations/almost_junction.js
40786 function validationAlmostJunction(context) {
40787 const type2 = "almost_junction";
40788 const EXTEND_TH_METERS = 5;
40789 const WELD_TH_METERS = 0.75;
40790 const CLOSE_NODE_TH = EXTEND_TH_METERS - WELD_TH_METERS;
40791 const SIG_ANGLE_TH = Math.atan(WELD_TH_METERS / EXTEND_TH_METERS);
40792 function isHighway(entity) {
40793 return entity.type === "way" && osmRoutableHighwayTagValues[entity.tags.highway];
40795 function isTaggedAsNotContinuing(node) {
40796 return node.tags.noexit === "yes" || node.tags.amenity === "parking_entrance" || node.tags.entrance && node.tags.entrance !== "no";
40798 const validation = function checkAlmostJunction(entity, graph) {
40799 if (!isHighway(entity))
40801 if (entity.isDegenerate())
40803 const tree = context.history().tree();
40804 const extendableNodeInfos = findConnectableEndNodesByExtension(entity);
40806 extendableNodeInfos.forEach((extendableNodeInfo) => {
40807 issues.push(new validationIssue({
40809 subtype: "highway-highway",
40810 severity: "warning",
40811 message: function(context2) {
40812 const entity1 = context2.hasEntity(this.entityIds[0]);
40813 if (this.entityIds[0] === this.entityIds[2]) {
40814 return entity1 ? _t.append("issues.almost_junction.self.message", {
40815 feature: utilDisplayLabel(entity1, context2.graph())
40818 const entity2 = context2.hasEntity(this.entityIds[2]);
40819 return entity1 && entity2 ? _t.append("issues.almost_junction.message", {
40820 feature: utilDisplayLabel(entity1, context2.graph()),
40821 feature2: utilDisplayLabel(entity2, context2.graph())
40825 reference: showReference,
40828 extendableNodeInfo.node.id,
40829 extendableNodeInfo.wid
40831 loc: extendableNodeInfo.node.loc,
40832 hash: JSON.stringify(extendableNodeInfo.node.loc),
40834 midId: extendableNodeInfo.mid.id,
40835 edge: extendableNodeInfo.edge,
40836 cross_loc: extendableNodeInfo.cross_loc
40838 dynamicFixes: makeFixes
40842 function makeFixes(context2) {
40843 let fixes = [new validationIssueFix({
40844 icon: "iD-icon-abutment",
40845 title: _t.append("issues.fix.connect_features.title"),
40846 onClick: function(context3) {
40847 const annotation = _t("issues.fix.connect_almost_junction.annotation");
40848 const [, endNodeId, crossWayId] = this.issue.entityIds;
40849 const midNode = context3.entity(this.issue.data.midId);
40850 const endNode = context3.entity(endNodeId);
40851 const crossWay = context3.entity(crossWayId);
40852 const nearEndNodes = findNearbyEndNodes(endNode, crossWay);
40853 if (nearEndNodes.length > 0) {
40854 const collinear = findSmallJoinAngle(midNode, endNode, nearEndNodes);
40857 actionMergeNodes([collinear.id, endNode.id], collinear.loc),
40863 const targetEdge = this.issue.data.edge;
40864 const crossLoc = this.issue.data.cross_loc;
40865 const edgeNodes = [context3.entity(targetEdge[0]), context3.entity(targetEdge[1])];
40866 const closestNodeInfo = geoSphericalClosestNode(edgeNodes, crossLoc);
40867 if (closestNodeInfo.distance < WELD_TH_METERS) {
40869 actionMergeNodes([closestNodeInfo.node.id, endNode.id], closestNodeInfo.node.loc),
40874 actionAddMidpoint({ loc: crossLoc, edge: targetEdge }, endNode),
40880 const node = context2.hasEntity(this.entityIds[1]);
40881 if (node && !node.hasInterestingTags()) {
40882 fixes.push(new validationIssueFix({
40883 icon: "maki-barrier",
40884 title: _t.append("issues.fix.tag_as_disconnected.title"),
40885 onClick: function(context3) {
40886 const nodeID = this.issue.entityIds[1];
40887 const tags = Object.assign({}, context3.entity(nodeID).tags);
40888 tags.noexit = "yes";
40890 actionChangeTags(nodeID, tags),
40891 _t("issues.fix.tag_as_disconnected.annotation")
40898 function showReference(selection2) {
40899 selection2.selectAll(".issue-reference").data([0]).enter().append("div").attr("class", "issue-reference").call(_t.append("issues.almost_junction.highway-highway.reference"));
40901 function isExtendableCandidate(node, way) {
40902 const osm = services.osm;
40903 if (osm && !osm.isDataLoaded(node.loc)) {
40906 if (isTaggedAsNotContinuing(node) || graph.parentWays(node).length !== 1) {
40909 let occurrences = 0;
40910 for (const index in way.nodes) {
40911 if (way.nodes[index] === node.id) {
40913 if (occurrences > 1) {
40920 function findConnectableEndNodesByExtension(way) {
40922 if (way.isClosed())
40925 const indices = [0, way.nodes.length - 1];
40926 indices.forEach((nodeIndex) => {
40927 const nodeID = way.nodes[nodeIndex];
40928 const node = graph.entity(nodeID);
40929 if (!isExtendableCandidate(node, way))
40931 const connectionInfo = canConnectByExtend(way, nodeIndex);
40932 if (!connectionInfo)
40934 testNodes = graph.childNodes(way).slice();
40935 testNodes[nodeIndex] = testNodes[nodeIndex].move(connectionInfo.cross_loc);
40936 if (geoHasSelfIntersections(testNodes, nodeID))
40938 results.push(connectionInfo);
40942 function findNearbyEndNodes(node, way) {
40945 way.nodes[way.nodes.length - 1]
40946 ].map((d) => graph.entity(d)).filter((d) => {
40947 return d.id !== node.id && geoSphericalDistance(node.loc, d.loc) <= CLOSE_NODE_TH;
40950 function findSmallJoinAngle(midNode, tipNode, endNodes) {
40952 let minAngle = Infinity;
40953 endNodes.forEach((endNode) => {
40954 const a1 = geoAngle(midNode, tipNode, context.projection) + Math.PI;
40955 const a2 = geoAngle(midNode, endNode, context.projection) + Math.PI;
40956 const diff = Math.max(a1, a2) - Math.min(a1, a2);
40957 if (diff < minAngle) {
40962 if (minAngle <= SIG_ANGLE_TH)
40966 function hasTag(tags, key) {
40967 return tags[key] !== void 0 && tags[key] !== "no";
40969 function canConnectWays(way, way2) {
40970 if (way.id === way2.id)
40972 if ((hasTag(way.tags, "bridge") || hasTag(way2.tags, "bridge")) && !(hasTag(way.tags, "bridge") && hasTag(way2.tags, "bridge")))
40974 if ((hasTag(way.tags, "tunnel") || hasTag(way2.tags, "tunnel")) && !(hasTag(way.tags, "tunnel") && hasTag(way2.tags, "tunnel")))
40976 const layer1 = way.tags.layer || "0", layer2 = way2.tags.layer || "0";
40977 if (layer1 !== layer2)
40979 const level1 = way.tags.level || "0", level2 = way2.tags.level || "0";
40980 if (level1 !== level2)
40984 function canConnectByExtend(way, endNodeIdx) {
40985 const tipNid = way.nodes[endNodeIdx];
40986 const midNid = endNodeIdx === 0 ? way.nodes[1] : way.nodes[way.nodes.length - 2];
40987 const tipNode = graph.entity(tipNid);
40988 const midNode = graph.entity(midNid);
40989 const lon = tipNode.loc[0];
40990 const lat = tipNode.loc[1];
40991 const lon_range = geoMetersToLon(EXTEND_TH_METERS, lat) / 2;
40992 const lat_range = geoMetersToLat(EXTEND_TH_METERS) / 2;
40993 const queryExtent = geoExtent([
40994 [lon - lon_range, lat - lat_range],
40995 [lon + lon_range, lat + lat_range]
40997 const edgeLen = geoSphericalDistance(midNode.loc, tipNode.loc);
40998 const t = EXTEND_TH_METERS / edgeLen + 1;
40999 const extTipLoc = geoVecInterp(midNode.loc, tipNode.loc, t);
41000 const segmentInfos = tree.waySegments(queryExtent, graph);
41001 for (let i2 = 0; i2 < segmentInfos.length; i2++) {
41002 let segmentInfo = segmentInfos[i2];
41003 let way2 = graph.entity(segmentInfo.wayId);
41004 if (!isHighway(way2))
41006 if (!canConnectWays(way, way2))
41008 let nAid = segmentInfo.nodes[0], nBid = segmentInfo.nodes[1];
41009 if (nAid === tipNid || nBid === tipNid)
41011 let nA = graph.entity(nAid), nB = graph.entity(nBid);
41012 let crossLoc = geoLineIntersection([tipNode.loc, extTipLoc], [nA.loc, nB.loc]);
41018 edge: [nA.id, nB.id],
41019 cross_loc: crossLoc
41026 validation.type = type2;
41030 // modules/validations/close_nodes.js
41031 function validationCloseNodes(context) {
41032 var type2 = "close_nodes";
41033 var pointThresholdMeters = 0.2;
41034 var validation = function(entity, graph) {
41035 if (entity.type === "node") {
41036 return getIssuesForNode(entity);
41037 } else if (entity.type === "way") {
41038 return getIssuesForWay(entity);
41041 function getIssuesForNode(node) {
41042 var parentWays = graph.parentWays(node);
41043 if (parentWays.length) {
41044 return getIssuesForVertex(node, parentWays);
41046 return getIssuesForDetachedPoint(node);
41049 function wayTypeFor(way) {
41050 if (way.tags.boundary && way.tags.boundary !== "no")
41052 if (way.tags.indoor && way.tags.indoor !== "no")
41054 if (way.tags.building && way.tags.building !== "no" || way.tags["building:part"] && way.tags["building:part"] !== "no")
41056 if (osmPathHighwayTagValues[way.tags.highway])
41058 var parentRelations = graph.parentRelations(way);
41059 for (var i2 in parentRelations) {
41060 var relation = parentRelations[i2];
41061 if (relation.tags.type === "boundary")
41063 if (relation.isMultipolygon()) {
41064 if (relation.tags.indoor && relation.tags.indoor !== "no")
41066 if (relation.tags.building && relation.tags.building !== "no" || relation.tags["building:part"] && relation.tags["building:part"] !== "no")
41072 function shouldCheckWay(way) {
41073 if (way.nodes.length <= 2 || way.isClosed() && way.nodes.length <= 4)
41075 var bbox2 = way.extent(graph).bbox();
41076 var hypotenuseMeters = geoSphericalDistance([bbox2.minX, bbox2.minY], [bbox2.maxX, bbox2.maxY]);
41077 if (hypotenuseMeters < 1.5)
41081 function getIssuesForWay(way) {
41082 if (!shouldCheckWay(way))
41084 var issues = [], nodes = graph.childNodes(way);
41085 for (var i2 = 0; i2 < nodes.length - 1; i2++) {
41086 var node1 = nodes[i2];
41087 var node2 = nodes[i2 + 1];
41088 var issue = getWayIssueIfAny(node1, node2, way);
41090 issues.push(issue);
41094 function getIssuesForVertex(node, parentWays) {
41096 function checkForCloseness(node1, node2, way) {
41097 var issue = getWayIssueIfAny(node1, node2, way);
41099 issues.push(issue);
41101 for (var i2 = 0; i2 < parentWays.length; i2++) {
41102 var parentWay = parentWays[i2];
41103 if (!shouldCheckWay(parentWay))
41105 var lastIndex = parentWay.nodes.length - 1;
41106 for (var j2 = 0; j2 < parentWay.nodes.length; j2++) {
41108 if (parentWay.nodes[j2 - 1] === node.id) {
41109 checkForCloseness(node, graph.entity(parentWay.nodes[j2]), parentWay);
41112 if (j2 !== lastIndex) {
41113 if (parentWay.nodes[j2 + 1] === node.id) {
41114 checkForCloseness(graph.entity(parentWay.nodes[j2]), node, parentWay);
41121 function thresholdMetersForWay(way) {
41122 if (!shouldCheckWay(way))
41124 var wayType = wayTypeFor(way);
41125 if (wayType === "boundary")
41127 if (wayType === "indoor")
41129 if (wayType === "building")
41131 if (wayType === "path")
41135 function getIssuesForDetachedPoint(node) {
41137 var lon = node.loc[0];
41138 var lat = node.loc[1];
41139 var lon_range = geoMetersToLon(pointThresholdMeters, lat) / 2;
41140 var lat_range = geoMetersToLat(pointThresholdMeters) / 2;
41141 var queryExtent = geoExtent([
41142 [lon - lon_range, lat - lat_range],
41143 [lon + lon_range, lat + lat_range]
41145 var intersected = context.history().tree().intersects(queryExtent, graph);
41146 for (var j2 = 0; j2 < intersected.length; j2++) {
41147 var nearby = intersected[j2];
41148 if (nearby.id === node.id)
41150 if (nearby.type !== "node" || nearby.geometry(graph) !== "point")
41152 if (nearby.loc === node.loc || geoSphericalDistance(node.loc, nearby.loc) < pointThresholdMeters) {
41153 if ("memorial:type" in node.tags && "memorial:type" in nearby.tags && node.tags["memorial:type"] === "stolperstein" && nearby.tags["memorial:type"] === "stolperstein")
41155 if ("memorial" in node.tags && "memorial" in nearby.tags && node.tags.memorial === "stolperstein" && nearby.tags.memorial === "stolperstein")
41157 var zAxisKeys = { layer: true, level: true, "addr:housenumber": true, "addr:unit": true };
41158 var zAxisDifferentiates = false;
41159 for (var key in zAxisKeys) {
41160 var nodeValue = node.tags[key] || "0";
41161 var nearbyValue = nearby.tags[key] || "0";
41162 if (nodeValue !== nearbyValue) {
41163 zAxisDifferentiates = true;
41167 if (zAxisDifferentiates)
41169 issues.push(new validationIssue({
41171 subtype: "detached",
41172 severity: "warning",
41173 message: function(context2) {
41174 var entity2 = context2.hasEntity(this.entityIds[0]), entity22 = context2.hasEntity(this.entityIds[1]);
41175 return entity2 && entity22 ? _t.append("issues.close_nodes.detached.message", {
41176 feature: utilDisplayLabel(entity2, context2.graph()),
41177 feature2: utilDisplayLabel(entity22, context2.graph())
41180 reference: showReference,
41181 entityIds: [node.id, nearby.id],
41182 dynamicFixes: function() {
41184 new validationIssueFix({
41185 icon: "iD-operation-disconnect",
41186 title: _t.append("issues.fix.move_points_apart.title")
41188 new validationIssueFix({
41189 icon: "iD-icon-layers",
41190 title: _t.append("issues.fix.use_different_layers_or_levels.title")
41198 function showReference(selection2) {
41199 var referenceText = _t("issues.close_nodes.detached.reference");
41200 selection2.selectAll(".issue-reference").data([0]).enter().append("div").attr("class", "issue-reference").html(referenceText);
41203 function getWayIssueIfAny(node1, node2, way) {
41204 if (node1.id === node2.id || node1.hasInterestingTags() && node2.hasInterestingTags()) {
41207 if (node1.loc !== node2.loc) {
41208 var parentWays1 = graph.parentWays(node1);
41209 var parentWays2 = new Set(graph.parentWays(node2));
41210 var sharedWays = parentWays1.filter(function(parentWay) {
41211 return parentWays2.has(parentWay);
41213 var thresholds = sharedWays.map(function(parentWay) {
41214 return thresholdMetersForWay(parentWay);
41216 var threshold = Math.min(...thresholds);
41217 var distance = geoSphericalDistance(node1.loc, node2.loc);
41218 if (distance > threshold)
41221 return new validationIssue({
41223 subtype: "vertices",
41224 severity: "warning",
41225 message: function(context2) {
41226 var entity2 = context2.hasEntity(this.entityIds[0]);
41227 return entity2 ? _t.append("issues.close_nodes.message", { way: utilDisplayLabel(entity2, context2.graph()) }) : "";
41229 reference: showReference,
41230 entityIds: [way.id, node1.id, node2.id],
41232 dynamicFixes: function() {
41234 new validationIssueFix({
41235 icon: "iD-icon-plus",
41236 title: _t.append("issues.fix.merge_points.title"),
41237 onClick: function(context2) {
41238 var entityIds = this.issue.entityIds;
41239 var action = actionMergeNodes([entityIds[1], entityIds[2]]);
41240 context2.perform(action, _t("issues.fix.merge_close_vertices.annotation"));
41243 new validationIssueFix({
41244 icon: "iD-operation-disconnect",
41245 title: _t.append("issues.fix.move_points_apart.title")
41250 function showReference(selection2) {
41251 var referenceText = _t("issues.close_nodes.reference");
41252 selection2.selectAll(".issue-reference").data([0]).enter().append("div").attr("class", "issue-reference").html(referenceText);
41256 validation.type = type2;
41260 // modules/validations/crossing_ways.js
41261 function validationCrossingWays(context) {
41262 var type2 = "crossing_ways";
41263 function getFeatureWithFeatureTypeTagsForWay(way, graph) {
41264 if (getFeatureType(way, graph) === null) {
41265 var parentRels = graph.parentRelations(way);
41266 for (var i2 = 0; i2 < parentRels.length; i2++) {
41267 var rel = parentRels[i2];
41268 if (getFeatureType(rel, graph) !== null) {
41275 function hasTag(tags, key) {
41276 return tags[key] !== void 0 && tags[key] !== "no";
41278 function taggedAsIndoor(tags) {
41279 return hasTag(tags, "indoor") || hasTag(tags, "level") || tags.highway === "corridor";
41281 function allowsBridge(featureType) {
41282 return featureType === "highway" || featureType === "railway" || featureType === "waterway";
41284 function allowsTunnel(featureType) {
41285 return featureType === "highway" || featureType === "railway" || featureType === "waterway";
41287 var ignoredBuildings = {
41293 function getFeatureType(entity, graph) {
41294 var geometry = entity.geometry(graph);
41295 if (geometry !== "line" && geometry !== "area")
41297 var tags = entity.tags;
41298 if (hasTag(tags, "building") && !ignoredBuildings[tags.building])
41300 if (hasTag(tags, "highway") && osmRoutableHighwayTagValues[tags.highway])
41302 if (geometry !== "line")
41304 if (hasTag(tags, "railway") && osmRailwayTrackTagValues[tags.railway])
41306 if (hasTag(tags, "waterway") && osmFlowingWaterwayTagValues[tags.waterway])
41310 function isLegitCrossing(tags1, featureType1, tags2, featureType2) {
41311 var level1 = tags1.level || "0";
41312 var level2 = tags2.level || "0";
41313 if (taggedAsIndoor(tags1) && taggedAsIndoor(tags2) && level1 !== level2) {
41316 var layer1 = tags1.layer || "0";
41317 var layer2 = tags2.layer || "0";
41318 if (allowsBridge(featureType1) && allowsBridge(featureType2)) {
41319 if (hasTag(tags1, "bridge") && !hasTag(tags2, "bridge"))
41321 if (!hasTag(tags1, "bridge") && hasTag(tags2, "bridge"))
41323 if (hasTag(tags1, "bridge") && hasTag(tags2, "bridge") && layer1 !== layer2)
41325 } else if (allowsBridge(featureType1) && hasTag(tags1, "bridge"))
41327 else if (allowsBridge(featureType2) && hasTag(tags2, "bridge"))
41329 if (allowsTunnel(featureType1) && allowsTunnel(featureType2)) {
41330 if (hasTag(tags1, "tunnel") && !hasTag(tags2, "tunnel"))
41332 if (!hasTag(tags1, "tunnel") && hasTag(tags2, "tunnel"))
41334 if (hasTag(tags1, "tunnel") && hasTag(tags2, "tunnel") && layer1 !== layer2)
41336 } else if (allowsTunnel(featureType1) && hasTag(tags1, "tunnel"))
41338 else if (allowsTunnel(featureType2) && hasTag(tags2, "tunnel"))
41340 if (featureType1 === "waterway" && featureType2 === "highway" && tags2.man_made === "pier")
41342 if (featureType2 === "waterway" && featureType1 === "highway" && tags1.man_made === "pier")
41344 if (featureType1 === "building" || featureType2 === "building" || taggedAsIndoor(tags1) || taggedAsIndoor(tags2)) {
41345 if (layer1 !== layer2)
41350 var highwaysDisallowingFords = {
41352 motorway_link: true,
41356 primary_link: true,
41358 secondary_link: true
41360 var nonCrossingHighways = { track: true };
41361 function tagsForConnectionNodeIfAllowed(entity1, entity2, graph) {
41362 var featureType1 = getFeatureType(entity1, graph);
41363 var featureType2 = getFeatureType(entity2, graph);
41364 var geometry1 = entity1.geometry(graph);
41365 var geometry2 = entity2.geometry(graph);
41366 var bothLines = geometry1 === "line" && geometry2 === "line";
41367 if (featureType1 === featureType2) {
41368 if (featureType1 === "highway") {
41369 var entity1IsPath = osmPathHighwayTagValues[entity1.tags.highway];
41370 var entity2IsPath = osmPathHighwayTagValues[entity2.tags.highway];
41371 if ((entity1IsPath || entity2IsPath) && entity1IsPath !== entity2IsPath) {
41372 var roadFeature = entity1IsPath ? entity2 : entity1;
41373 if (nonCrossingHighways[roadFeature.tags.highway]) {
41376 var pathFeature = entity1IsPath ? entity1 : entity2;
41377 if (["marked", "unmarked", "traffic_signals", "uncontrolled"].indexOf(pathFeature.tags.crossing) !== -1) {
41378 return bothLines ? { highway: "crossing", crossing: pathFeature.tags.crossing } : {};
41380 return bothLines ? { highway: "crossing" } : {};
41384 if (featureType1 === "waterway")
41386 if (featureType1 === "railway")
41389 var featureTypes = [featureType1, featureType2];
41390 if (featureTypes.indexOf("highway") !== -1) {
41391 if (featureTypes.indexOf("railway") !== -1) {
41394 var isTram = entity1.tags.railway === "tram" || entity2.tags.railway === "tram";
41395 if (osmPathHighwayTagValues[entity1.tags.highway] || osmPathHighwayTagValues[entity2.tags.highway]) {
41397 return { railway: "tram_crossing" };
41398 return { railway: "crossing" };
41401 return { railway: "tram_level_crossing" };
41402 return { railway: "level_crossing" };
41405 if (featureTypes.indexOf("waterway") !== -1) {
41406 if (hasTag(entity1.tags, "tunnel") && hasTag(entity2.tags, "tunnel"))
41408 if (hasTag(entity1.tags, "bridge") && hasTag(entity2.tags, "bridge"))
41410 if (highwaysDisallowingFords[entity1.tags.highway] || highwaysDisallowingFords[entity2.tags.highway]) {
41413 return bothLines ? { ford: "yes" } : {};
41419 function findCrossingsByWay(way1, graph, tree) {
41420 var edgeCrossInfos = [];
41421 if (way1.type !== "way")
41422 return edgeCrossInfos;
41423 var taggedFeature1 = getFeatureWithFeatureTypeTagsForWay(way1, graph);
41424 var way1FeatureType = getFeatureType(taggedFeature1, graph);
41425 if (way1FeatureType === null)
41426 return edgeCrossInfos;
41427 var checkedSingleCrossingWays = {};
41430 var n1, n2, nA, nB, nAId, nBId;
41431 var segment1, segment2;
41433 var segmentInfos, segment2Info, way2, taggedFeature2, way2FeatureType;
41434 var way1Nodes = graph.childNodes(way1);
41435 var comparedWays = {};
41436 for (i2 = 0; i2 < way1Nodes.length - 1; i2++) {
41437 n1 = way1Nodes[i2];
41438 n2 = way1Nodes[i2 + 1];
41439 extent = geoExtent([
41441 Math.min(n1.loc[0], n2.loc[0]),
41442 Math.min(n1.loc[1], n2.loc[1])
41445 Math.max(n1.loc[0], n2.loc[0]),
41446 Math.max(n1.loc[1], n2.loc[1])
41449 segmentInfos = tree.waySegments(extent, graph);
41450 for (j2 = 0; j2 < segmentInfos.length; j2++) {
41451 segment2Info = segmentInfos[j2];
41452 if (segment2Info.wayId === way1.id)
41454 if (checkedSingleCrossingWays[segment2Info.wayId])
41456 comparedWays[segment2Info.wayId] = true;
41457 way2 = graph.hasEntity(segment2Info.wayId);
41460 taggedFeature2 = getFeatureWithFeatureTypeTagsForWay(way2, graph);
41461 way2FeatureType = getFeatureType(taggedFeature2, graph);
41462 if (way2FeatureType === null || isLegitCrossing(taggedFeature1.tags, way1FeatureType, taggedFeature2.tags, way2FeatureType)) {
41465 oneOnly = way1FeatureType === "building" || way2FeatureType === "building";
41466 nAId = segment2Info.nodes[0];
41467 nBId = segment2Info.nodes[1];
41468 if (nAId === n1.id || nAId === n2.id || nBId === n1.id || nBId === n2.id) {
41471 nA = graph.hasEntity(nAId);
41474 nB = graph.hasEntity(nBId);
41477 segment1 = [n1.loc, n2.loc];
41478 segment2 = [nA.loc, nB.loc];
41479 var point2 = geoLineIntersection(segment1, segment2);
41481 edgeCrossInfos.push({
41485 featureType: way1FeatureType,
41486 edge: [n1.id, n2.id]
41490 featureType: way2FeatureType,
41491 edge: [nA.id, nB.id]
41497 checkedSingleCrossingWays[way2.id] = true;
41503 return edgeCrossInfos;
41505 function waysToCheck(entity, graph) {
41506 var featureType = getFeatureType(entity, graph);
41509 if (entity.type === "way") {
41511 } else if (entity.type === "relation") {
41512 return entity.members.reduce(function(array2, member) {
41513 if (member.type === "way" && // only look at geometry ways
41514 (!member.role || member.role === "outer" || member.role === "inner")) {
41515 var entity2 = graph.hasEntity(member.id);
41516 if (entity2 && array2.indexOf(entity2) === -1) {
41517 array2.push(entity2);
41525 var validation = function checkCrossingWays(entity, graph) {
41526 var tree = context.history().tree();
41527 var ways = waysToCheck(entity, graph);
41529 var wayIndex, crossingIndex, crossings;
41530 for (wayIndex in ways) {
41531 crossings = findCrossingsByWay(ways[wayIndex], graph, tree);
41532 for (crossingIndex in crossings) {
41533 issues.push(createIssue(crossings[crossingIndex], graph));
41538 function createIssue(crossing, graph) {
41539 crossing.wayInfos.sort(function(way1Info, way2Info) {
41540 var type1 = way1Info.featureType;
41541 var type22 = way2Info.featureType;
41542 if (type1 === type22) {
41543 return utilDisplayLabel(way1Info.way, graph) > utilDisplayLabel(way2Info.way, graph);
41544 } else if (type1 === "waterway") {
41546 } else if (type22 === "waterway") {
41549 return type1 < type22;
41551 var entities = crossing.wayInfos.map(function(wayInfo) {
41552 return getFeatureWithFeatureTypeTagsForWay(wayInfo.way, graph);
41554 var edges = [crossing.wayInfos[0].edge, crossing.wayInfos[1].edge];
41555 var featureTypes = [crossing.wayInfos[0].featureType, crossing.wayInfos[1].featureType];
41556 var connectionTags = tagsForConnectionNodeIfAllowed(entities[0], entities[1], graph);
41557 var featureType1 = crossing.wayInfos[0].featureType;
41558 var featureType2 = crossing.wayInfos[1].featureType;
41559 var isCrossingIndoors = taggedAsIndoor(entities[0].tags) && taggedAsIndoor(entities[1].tags);
41560 var isCrossingTunnels = allowsTunnel(featureType1) && hasTag(entities[0].tags, "tunnel") && allowsTunnel(featureType2) && hasTag(entities[1].tags, "tunnel");
41561 var isCrossingBridges = allowsBridge(featureType1) && hasTag(entities[0].tags, "bridge") && allowsBridge(featureType2) && hasTag(entities[1].tags, "bridge");
41562 var subtype = [featureType1, featureType2].sort().join("-");
41563 var crossingTypeID = subtype;
41564 if (isCrossingIndoors) {
41565 crossingTypeID = "indoor-indoor";
41566 } else if (isCrossingTunnels) {
41567 crossingTypeID = "tunnel-tunnel";
41568 } else if (isCrossingBridges) {
41569 crossingTypeID = "bridge-bridge";
41571 if (connectionTags && (isCrossingIndoors || isCrossingTunnels || isCrossingBridges)) {
41572 crossingTypeID += "_connectable";
41574 var uniqueID = crossing.crossPoint[0].toFixed(4) + "," + crossing.crossPoint[1].toFixed(4);
41575 return new validationIssue({
41578 severity: "warning",
41579 message: function(context2) {
41580 var graph2 = context2.graph();
41581 var entity1 = graph2.hasEntity(this.entityIds[0]), entity2 = graph2.hasEntity(this.entityIds[1]);
41582 return entity1 && entity2 ? _t.append("issues.crossing_ways.message", {
41583 feature: utilDisplayLabel(entity1, graph2),
41584 feature2: utilDisplayLabel(entity2, graph2)
41587 reference: showReference,
41588 entityIds: entities.map(function(entity) {
41597 loc: crossing.crossPoint,
41598 dynamicFixes: function(context2) {
41599 var mode = context2.mode();
41600 if (!mode || mode.id !== "select" || mode.selectedIDs().length !== 1)
41602 var selectedIndex = this.entityIds[0] === mode.selectedIDs()[0] ? 0 : 1;
41603 var selectedFeatureType = this.data.featureTypes[selectedIndex];
41604 var otherFeatureType = this.data.featureTypes[selectedIndex === 0 ? 1 : 0];
41606 if (connectionTags) {
41607 fixes.push(makeConnectWaysFix(this.data.connectionTags));
41609 if (isCrossingIndoors) {
41610 fixes.push(new validationIssueFix({
41611 icon: "iD-icon-layers",
41612 title: _t.append("issues.fix.use_different_levels.title")
41614 } else if (isCrossingTunnels || isCrossingBridges || featureType1 === "building" || featureType2 === "building") {
41615 fixes.push(makeChangeLayerFix("higher"));
41616 fixes.push(makeChangeLayerFix("lower"));
41617 } else if (context2.graph().geometry(this.entityIds[0]) === "line" && context2.graph().geometry(this.entityIds[1]) === "line") {
41618 if (allowsBridge(selectedFeatureType) && selectedFeatureType !== "waterway") {
41619 fixes.push(makeAddBridgeOrTunnelFix("add_a_bridge", "temaki-bridge", "bridge"));
41621 var skipTunnelFix = otherFeatureType === "waterway" && selectedFeatureType !== "waterway";
41622 if (allowsTunnel(selectedFeatureType) && !skipTunnelFix) {
41623 fixes.push(makeAddBridgeOrTunnelFix("add_a_tunnel", "temaki-tunnel", "tunnel"));
41626 fixes.push(new validationIssueFix({
41627 icon: "iD-operation-move",
41628 title: _t.append("issues.fix.reposition_features.title")
41633 function showReference(selection2) {
41634 selection2.selectAll(".issue-reference").data([0]).enter().append("div").attr("class", "issue-reference").call(_t.append("issues.crossing_ways." + crossingTypeID + ".reference"));
41637 function makeAddBridgeOrTunnelFix(fixTitleID, iconName, bridgeOrTunnel) {
41638 return new validationIssueFix({
41640 title: _t.append("issues.fix." + fixTitleID + ".title"),
41641 onClick: function(context2) {
41642 var mode = context2.mode();
41643 if (!mode || mode.id !== "select")
41645 var selectedIDs = mode.selectedIDs();
41646 if (selectedIDs.length !== 1)
41648 var selectedWayID = selectedIDs[0];
41649 if (!context2.hasEntity(selectedWayID))
41651 var resultWayIDs = [selectedWayID];
41652 var edge, crossedEdge, crossedWayID;
41653 if (this.issue.entityIds[0] === selectedWayID) {
41654 edge = this.issue.data.edges[0];
41655 crossedEdge = this.issue.data.edges[1];
41656 crossedWayID = this.issue.entityIds[1];
41658 edge = this.issue.data.edges[1];
41659 crossedEdge = this.issue.data.edges[0];
41660 crossedWayID = this.issue.entityIds[0];
41662 var crossingLoc = this.issue.loc;
41663 var projection2 = context2.projection;
41664 var action = function actionAddStructure(graph) {
41665 var edgeNodes = [graph.entity(edge[0]), graph.entity(edge[1])];
41666 var crossedWay = graph.hasEntity(crossedWayID);
41667 var structLengthMeters = crossedWay && isFinite(crossedWay.tags.width) && Number(crossedWay.tags.width);
41668 if (!structLengthMeters) {
41669 structLengthMeters = crossedWay && crossedWay.impliedLineWidthMeters();
41671 if (structLengthMeters) {
41672 if (getFeatureType(crossedWay, graph) === "railway") {
41673 structLengthMeters *= 2;
41676 structLengthMeters = 8;
41678 var a1 = geoAngle(edgeNodes[0], edgeNodes[1], projection2) + Math.PI;
41679 var a2 = geoAngle(graph.entity(crossedEdge[0]), graph.entity(crossedEdge[1]), projection2) + Math.PI;
41680 var crossingAngle = Math.max(a1, a2) - Math.min(a1, a2);
41681 if (crossingAngle > Math.PI)
41682 crossingAngle -= Math.PI;
41683 structLengthMeters = structLengthMeters / 2 / Math.sin(crossingAngle) * 2;
41684 structLengthMeters += 4;
41685 structLengthMeters = Math.min(Math.max(structLengthMeters, 4), 50);
41686 function geomToProj(geoPoint) {
41688 geoLonToMeters(geoPoint[0], geoPoint[1]),
41689 geoLatToMeters(geoPoint[1])
41692 function projToGeom(projPoint) {
41693 var lat = geoMetersToLat(projPoint[1]);
41695 geoMetersToLon(projPoint[0], lat),
41699 var projEdgeNode1 = geomToProj(edgeNodes[0].loc);
41700 var projEdgeNode2 = geomToProj(edgeNodes[1].loc);
41701 var projectedAngle = geoVecAngle(projEdgeNode1, projEdgeNode2);
41702 var projectedCrossingLoc = geomToProj(crossingLoc);
41703 var linearToSphericalMetersRatio = geoVecLength(projEdgeNode1, projEdgeNode2) / geoSphericalDistance(edgeNodes[0].loc, edgeNodes[1].loc);
41704 function locSphericalDistanceFromCrossingLoc(angle2, distanceMeters) {
41705 var lengthSphericalMeters = distanceMeters * linearToSphericalMetersRatio;
41706 return projToGeom([
41707 projectedCrossingLoc[0] + Math.cos(angle2) * lengthSphericalMeters,
41708 projectedCrossingLoc[1] + Math.sin(angle2) * lengthSphericalMeters
41711 var endpointLocGetter1 = function(lengthMeters) {
41712 return locSphericalDistanceFromCrossingLoc(projectedAngle, lengthMeters);
41714 var endpointLocGetter2 = function(lengthMeters) {
41715 return locSphericalDistanceFromCrossingLoc(projectedAngle + Math.PI, lengthMeters);
41717 var minEdgeLengthMeters = 0.55;
41718 function determineEndpoint(edge2, endNode, locGetter) {
41720 var idealLengthMeters = structLengthMeters / 2;
41721 var crossingToEdgeEndDistance = geoSphericalDistance(crossingLoc, endNode.loc);
41722 if (crossingToEdgeEndDistance - idealLengthMeters > minEdgeLengthMeters) {
41723 var idealNodeLoc = locGetter(idealLengthMeters);
41724 newNode = osmNode();
41725 graph = actionAddMidpoint({ loc: idealNodeLoc, edge: edge2 }, newNode)(graph);
41728 endNode.parentIntersectionWays(graph).forEach(function(way) {
41729 way.nodes.forEach(function(nodeID) {
41730 if (nodeID === endNode.id) {
41731 if (endNode.id === way.first() && endNode.id !== way.last() || endNode.id === way.last() && endNode.id !== way.first()) {
41739 if (edgeCount >= 3) {
41740 var insetLength = crossingToEdgeEndDistance - minEdgeLengthMeters;
41741 if (insetLength > minEdgeLengthMeters) {
41742 var insetNodeLoc = locGetter(insetLength);
41743 newNode = osmNode();
41744 graph = actionAddMidpoint({ loc: insetNodeLoc, edge: edge2 }, newNode)(graph);
41750 var splitAction = actionSplit([newNode.id]).limitWays(resultWayIDs);
41751 graph = splitAction(graph);
41752 if (splitAction.getCreatedWayIDs().length) {
41753 resultWayIDs.push(splitAction.getCreatedWayIDs()[0]);
41757 var structEndNode1 = determineEndpoint(edge, edgeNodes[1], endpointLocGetter1);
41758 var structEndNode2 = determineEndpoint([edgeNodes[0].id, structEndNode1.id], edgeNodes[0], endpointLocGetter2);
41759 var structureWay = resultWayIDs.map(function(id2) {
41760 return graph.entity(id2);
41761 }).find(function(way) {
41762 return way.nodes.indexOf(structEndNode1.id) !== -1 && way.nodes.indexOf(structEndNode2.id) !== -1;
41764 var tags = Object.assign({}, structureWay.tags);
41765 if (bridgeOrTunnel === "bridge") {
41766 tags.bridge = "yes";
41769 var tunnelValue = "yes";
41770 if (getFeatureType(structureWay, graph) === "waterway") {
41771 tunnelValue = "culvert";
41773 tags.tunnel = tunnelValue;
41776 graph = actionChangeTags(structureWay.id, tags)(graph);
41779 context2.perform(action, _t("issues.fix." + fixTitleID + ".annotation"));
41780 context2.enter(modeSelect(context2, resultWayIDs));
41784 function makeConnectWaysFix(connectionTags) {
41785 var fixTitleID = "connect_features";
41786 if (connectionTags.ford) {
41787 fixTitleID = "connect_using_ford";
41789 return new validationIssueFix({
41790 icon: "iD-icon-crossing",
41791 title: _t.append("issues.fix." + fixTitleID + ".title"),
41792 onClick: function(context2) {
41793 var loc = this.issue.loc;
41794 var connectionTags2 = this.issue.data.connectionTags;
41795 var edges = this.issue.data.edges;
41797 function actionConnectCrossingWays(graph) {
41798 var node = osmNode({ loc, tags: connectionTags2 });
41799 graph = graph.replace(node);
41800 var nodesToMerge = [node.id];
41801 var mergeThresholdInMeters = 0.75;
41802 edges.forEach(function(edge) {
41803 var edgeNodes = [graph.entity(edge[0]), graph.entity(edge[1])];
41804 var nearby = geoSphericalClosestNode(edgeNodes, loc);
41805 if ((!nearby.node.hasInterestingTags() || nearby.node.isCrossing()) && nearby.distance < mergeThresholdInMeters) {
41806 nodesToMerge.push(nearby.node.id);
41808 graph = actionAddMidpoint({ loc, edge }, node)(graph);
41811 if (nodesToMerge.length > 1) {
41812 graph = actionMergeNodes(nodesToMerge, loc)(graph);
41816 _t("issues.fix.connect_crossing_features.annotation")
41821 function makeChangeLayerFix(higherOrLower) {
41822 return new validationIssueFix({
41823 icon: "iD-icon-" + (higherOrLower === "higher" ? "up" : "down"),
41824 title: _t.append("issues.fix.tag_this_as_" + higherOrLower + ".title"),
41825 onClick: function(context2) {
41826 var mode = context2.mode();
41827 if (!mode || mode.id !== "select")
41829 var selectedIDs = mode.selectedIDs();
41830 if (selectedIDs.length !== 1)
41832 var selectedID = selectedIDs[0];
41833 if (!this.issue.entityIds.some(function(entityId) {
41834 return entityId === selectedID;
41837 var entity = context2.hasEntity(selectedID);
41840 var tags = Object.assign({}, entity.tags);
41841 var layer = tags.layer && Number(tags.layer);
41842 if (layer && !isNaN(layer)) {
41843 if (higherOrLower === "higher") {
41849 if (higherOrLower === "higher") {
41855 tags.layer = layer.toString();
41857 actionChangeTags(entity.id, tags),
41858 _t("operations.change_tags.annotation")
41863 validation.type = type2;
41867 // modules/behavior/draw_way.js
41868 function behaviorDrawWay(context, wayID, mode, startGraph) {
41869 const keybinding = utilKeybinding("drawWay");
41870 var dispatch10 = dispatch_default("rejectedSelfIntersection");
41871 var behavior = behaviorDraw(context);
41877 var _pointerHasMoved = false;
41879 var _didResolveTempEdit = false;
41880 function createDrawNode(loc) {
41881 _drawNode = osmNode({ loc });
41882 context.pauseChangeDispatch();
41883 context.replace(function actionAddDrawNode(graph) {
41884 var way = graph.entity(wayID);
41885 return graph.replace(_drawNode).replace(way.addNode(_drawNode.id, _nodeIndex));
41887 context.resumeChangeDispatch();
41888 setActiveElements();
41890 function removeDrawNode() {
41891 context.pauseChangeDispatch();
41893 function actionDeleteDrawNode(graph) {
41894 var way = graph.entity(wayID);
41895 return graph.replace(way.removeNode(_drawNode.id)).remove(_drawNode);
41899 _drawNode = void 0;
41900 context.resumeChangeDispatch();
41902 function keydown(d3_event) {
41903 if (d3_event.keyCode === utilKeybinding.modifierCodes.alt) {
41904 if (context.surface().classed("nope")) {
41905 context.surface().classed("nope-suppressed", true);
41907 context.surface().classed("nope", false).classed("nope-disabled", true);
41910 function keyup(d3_event) {
41911 if (d3_event.keyCode === utilKeybinding.modifierCodes.alt) {
41912 if (context.surface().classed("nope-suppressed")) {
41913 context.surface().classed("nope", true);
41915 context.surface().classed("nope-suppressed", false).classed("nope-disabled", false);
41918 function allowsVertex(d) {
41919 return d.geometry(context.graph()) === "vertex" || _mainPresetIndex.allowsVertex(d, context.graph());
41921 function move(d3_event, datum2) {
41922 var loc = context.map().mouseCoordinates();
41924 createDrawNode(loc);
41925 context.surface().classed("nope-disabled", d3_event.altKey);
41926 var targetLoc = datum2 && datum2.properties && datum2.properties.entity && allowsVertex(datum2.properties.entity) && datum2.properties.entity.loc;
41927 var targetNodes = datum2 && datum2.properties && datum2.properties.nodes;
41930 } else if (targetNodes) {
41931 var choice = geoChooseEdge(targetNodes, context.map().mouse(), context.projection, _drawNode.id);
41936 context.replace(actionMoveNode(_drawNode.id, loc), _annotation);
41937 _drawNode = context.entity(_drawNode.id);
41940 /* includeDrawNode */
41943 function checkGeometry(includeDrawNode) {
41944 var nopeDisabled = context.surface().classed("nope-disabled");
41945 var isInvalid = isInvalidGeometry(includeDrawNode);
41946 if (nopeDisabled) {
41947 context.surface().classed("nope", false).classed("nope-suppressed", isInvalid);
41949 context.surface().classed("nope", isInvalid).classed("nope-suppressed", false);
41952 function isInvalidGeometry(includeDrawNode) {
41953 var testNode = _drawNode;
41954 var parentWay = context.graph().entity(wayID);
41955 var nodes = context.graph().childNodes(parentWay).slice();
41956 if (includeDrawNode) {
41957 if (parentWay.isClosed()) {
41961 if (parentWay.isClosed()) {
41962 if (nodes.length < 3)
41965 nodes.splice(-2, 1);
41966 testNode = nodes[nodes.length - 2];
41971 return testNode && geoHasSelfIntersections(nodes, testNode.id);
41973 function undone() {
41974 _didResolveTempEdit = true;
41975 context.pauseChangeDispatch();
41977 if (context.graph() === startGraph) {
41978 nextMode = modeSelect(context, [wayID]);
41983 context.perform(actionNoop());
41985 context.resumeChangeDispatch();
41986 context.enter(nextMode);
41988 function setActiveElements() {
41991 context.surface().selectAll("." + _drawNode.id).classed("active", true);
41993 function resetToStartGraph() {
41994 while (context.graph() !== startGraph) {
41998 var drawWay = function(surface) {
41999 _drawNode = void 0;
42000 _didResolveTempEdit = false;
42001 _origWay = context.entity(wayID);
42002 if (typeof _nodeIndex === "number") {
42003 _headNodeID = _origWay.nodes[_nodeIndex];
42004 } else if (_origWay.isClosed()) {
42005 _headNodeID = _origWay.nodes[_origWay.nodes.length - 2];
42007 _headNodeID = _origWay.nodes[_origWay.nodes.length - 1];
42009 _wayGeometry = _origWay.geometry(context.graph());
42011 (_origWay.nodes.length === (_origWay.isClosed() ? 2 : 1) ? "operations.start.annotation." : "operations.continue.annotation.") + _wayGeometry
42013 _pointerHasMoved = false;
42014 context.pauseChangeDispatch();
42015 context.perform(actionNoop(), _annotation);
42016 context.resumeChangeDispatch();
42017 behavior.hover().initialNodeID(_headNodeID);
42018 behavior.on("move", function() {
42019 _pointerHasMoved = true;
42020 move.apply(this, arguments);
42021 }).on("down", function() {
42022 move.apply(this, arguments);
42023 }).on("downcancel", function() {
42026 }).on("click", drawWay.add).on("clickWay", drawWay.addWay).on("clickNode", drawWay.addNode).on("undo", context.undo).on("cancel", drawWay.cancel).on("finish", drawWay.finish);
42027 select_default2(window).on("keydown.drawWay", keydown).on("keyup.drawWay", keyup);
42028 context.map().dblclickZoomEnable(false).on("drawn.draw", setActiveElements);
42029 setActiveElements();
42030 surface.call(behavior);
42031 context.history().on("undone.draw", undone);
42033 drawWay.off = function(surface) {
42034 if (!_didResolveTempEdit) {
42035 context.pauseChangeDispatch();
42036 resetToStartGraph();
42037 context.resumeChangeDispatch();
42039 _drawNode = void 0;
42040 _nodeIndex = void 0;
42041 context.map().on("drawn.draw", null);
42042 surface.call(behavior.off).selectAll(".active").classed("active", false);
42043 surface.classed("nope", false).classed("nope-suppressed", false).classed("nope-disabled", false);
42044 select_default2(window).on("keydown.drawWay", null).on("keyup.drawWay", null);
42045 context.history().on("undone.draw", null);
42047 function attemptAdd(d, loc, doAdd) {
42049 context.replace(actionMoveNode(_drawNode.id, loc), _annotation);
42050 _drawNode = context.entity(_drawNode.id);
42052 createDrawNode(loc);
42056 /* includeDrawNode */
42058 if (d && d.properties && d.properties.nope || context.surface().classed("nope")) {
42059 if (!_pointerHasMoved) {
42062 dispatch10.call("rejectedSelfIntersection", this);
42065 context.pauseChangeDispatch();
42067 _didResolveTempEdit = true;
42068 context.resumeChangeDispatch();
42069 context.enter(mode);
42071 drawWay.add = function(loc, d) {
42072 attemptAdd(d, loc, function() {
42075 drawWay.addWay = function(loc, edge, d) {
42076 attemptAdd(d, loc, function() {
42078 actionAddMidpoint({ loc, edge }, _drawNode),
42083 drawWay.addNode = function(node, d) {
42084 if (node.id === _headNodeID || // or the first node when drawing an area
42085 _origWay.isClosed() && node.id === _origWay.first()) {
42089 attemptAdd(d, node.loc, function() {
42091 function actionReplaceDrawNode(graph) {
42092 graph = graph.replace(graph.entity(wayID).removeNode(_drawNode.id)).remove(_drawNode);
42093 return graph.replace(graph.entity(wayID).addNode(node.id, _nodeIndex));
42099 function getFeatureType(ways) {
42100 if (ways.every((way) => way.isClosed()))
42102 if (ways.every((way) => !way.isClosed()))
42106 function followMode() {
42107 if (_didResolveTempEdit)
42110 const isDrawingArea = _origWay.nodes[0] === _origWay.nodes.slice(-1)[0];
42111 const [secondLastNodeId, lastNodeId] = _origWay.nodes.slice(isDrawingArea ? -3 : -2);
42112 const historyGraph = context.history().graph();
42113 if (!lastNodeId || !secondLastNodeId || !historyGraph.hasEntity(lastNodeId) || !historyGraph.hasEntity(secondLastNodeId)) {
42114 context.ui().flash.duration(4e3).iconName("#iD-icon-no").label(_t.append("operations.follow.error.needs_more_initial_nodes"))();
42117 const lastNodesParents = historyGraph.parentWays(historyGraph.entity(lastNodeId)).filter((w) => w.id !== wayID);
42118 const secondLastNodesParents = historyGraph.parentWays(historyGraph.entity(secondLastNodeId)).filter((w) => w.id !== wayID);
42119 const featureType = getFeatureType(lastNodesParents);
42120 if (lastNodesParents.length !== 1 || secondLastNodesParents.length === 0) {
42121 context.ui().flash.duration(4e3).iconName("#iD-icon-no").label(_t.append(`operations.follow.error.intersection_of_multiple_ways.${featureType}`))();
42124 if (!secondLastNodesParents.some((n2) => n2.id === lastNodesParents[0].id)) {
42125 context.ui().flash.duration(4e3).iconName("#iD-icon-no").label(_t.append(`operations.follow.error.intersection_of_different_ways.${featureType}`))();
42128 const way = lastNodesParents[0];
42129 const indexOfLast = way.nodes.indexOf(lastNodeId);
42130 const indexOfSecondLast = way.nodes.indexOf(secondLastNodeId);
42131 const isDescendingPastZero = indexOfLast === way.nodes.length - 2 && indexOfSecondLast === 0;
42132 let nextNodeIndex = indexOfLast + (indexOfLast > indexOfSecondLast && !isDescendingPastZero ? 1 : -1);
42133 if (nextNodeIndex === -1)
42134 nextNodeIndex = indexOfSecondLast === 1 ? way.nodes.length - 2 : 1;
42135 const nextNode = historyGraph.entity(way.nodes[nextNodeIndex]);
42136 drawWay.addNode(nextNode, {
42137 geometry: { type: "Point", coordinates: nextNode.loc },
42139 properties: { target: true, entity: nextNode }
42142 context.ui().flash.duration(4e3).iconName("#iD-icon-no").label(_t.append("operations.follow.error.unknown"))();
42145 keybinding.on(_t("operations.follow.key"), followMode);
42146 select_default2(document).call(keybinding);
42147 drawWay.finish = function() {
42150 /* includeDrawNode */
42152 if (context.surface().classed("nope")) {
42153 dispatch10.call("rejectedSelfIntersection", this);
42156 context.pauseChangeDispatch();
42158 _didResolveTempEdit = true;
42159 context.resumeChangeDispatch();
42160 var way = context.hasEntity(wayID);
42161 if (!way || way.isDegenerate()) {
42165 window.setTimeout(function() {
42166 context.map().dblclickZoomEnable(true);
42168 var isNewFeature = !mode.isContinuing;
42169 context.enter(modeSelect(context, [wayID]).newFeature(isNewFeature));
42171 drawWay.cancel = function() {
42172 context.pauseChangeDispatch();
42173 resetToStartGraph();
42174 context.resumeChangeDispatch();
42175 window.setTimeout(function() {
42176 context.map().dblclickZoomEnable(true);
42178 context.surface().classed("nope", false).classed("nope-disabled", false).classed("nope-suppressed", false);
42179 context.enter(modeBrowse(context));
42181 drawWay.nodeIndex = function(val) {
42182 if (!arguments.length)
42187 drawWay.activeID = function() {
42188 if (!arguments.length)
42189 return _drawNode && _drawNode.id;
42192 return utilRebind(drawWay, dispatch10, "on");
42195 // modules/modes/draw_line.js
42196 function modeDrawLine(context, wayID, startGraph, button, affix, continuing) {
42201 var behavior = behaviorDrawWay(context, wayID, mode, startGraph).on("rejectedSelfIntersection.modeDrawLine", function() {
42202 context.ui().flash.iconName("#iD-icon-no").label(_t.append("self_intersection.error.lines"))();
42204 mode.wayID = wayID;
42205 mode.isContinuing = continuing;
42206 mode.enter = function() {
42207 behavior.nodeIndex(affix === "prefix" ? 0 : void 0);
42208 context.install(behavior);
42210 mode.exit = function() {
42211 context.uninstall(behavior);
42213 mode.selectedIDs = function() {
42216 mode.activeID = function() {
42217 return behavior && behavior.activeID() || [];
42222 // modules/validations/disconnected_way.js
42223 function validationDisconnectedWay() {
42224 var type2 = "disconnected_way";
42225 function isTaggedAsHighway(entity) {
42226 return osmRoutableHighwayTagValues[entity.tags.highway];
42228 var validation = function checkDisconnectedWay(entity, graph) {
42229 var routingIslandWays = routingIslandForEntity(entity);
42230 if (!routingIslandWays)
42232 return [new validationIssue({
42234 subtype: "highway",
42235 severity: "warning",
42236 message: function(context) {
42237 var entity2 = this.entityIds.length && context.hasEntity(this.entityIds[0]);
42238 var label = entity2 && utilDisplayLabel(entity2, context.graph());
42239 return _t.append("issues.disconnected_way.routable.message", { count: this.entityIds.length, highway: label });
42241 reference: showReference,
42242 entityIds: Array.from(routingIslandWays).map(function(way) {
42245 dynamicFixes: makeFixes
42247 function makeFixes(context) {
42249 var singleEntity = this.entityIds.length === 1 && context.hasEntity(this.entityIds[0]);
42250 if (singleEntity) {
42251 if (singleEntity.type === "way" && !singleEntity.isClosed()) {
42252 var textDirection = _mainLocalizer.textDirection();
42253 var startFix = makeContinueDrawingFixIfAllowed(textDirection, singleEntity.first(), "start");
42255 fixes.push(startFix);
42256 var endFix = makeContinueDrawingFixIfAllowed(textDirection, singleEntity.last(), "end");
42258 fixes.push(endFix);
42260 if (!fixes.length) {
42261 fixes.push(new validationIssueFix({
42262 title: _t.append("issues.fix.connect_feature.title")
42265 fixes.push(new validationIssueFix({
42266 icon: "iD-operation-delete",
42267 title: _t.append("issues.fix.delete_feature.title"),
42268 entityIds: [singleEntity.id],
42269 onClick: function(context2) {
42270 var id2 = this.issue.entityIds[0];
42271 var operation = operationDelete(context2, [id2]);
42272 if (!operation.disabled()) {
42278 fixes.push(new validationIssueFix({
42279 title: _t.append("issues.fix.connect_features.title")
42284 function showReference(selection2) {
42285 selection2.selectAll(".issue-reference").data([0]).enter().append("div").attr("class", "issue-reference").call(_t.append("issues.disconnected_way.routable.reference"));
42287 function routingIslandForEntity(entity2) {
42288 var routingIsland = /* @__PURE__ */ new Set();
42289 var waysToCheck = [];
42290 function queueParentWays(node) {
42291 graph.parentWays(node).forEach(function(parentWay) {
42292 if (!routingIsland.has(parentWay) && // only check each feature once
42293 isRoutableWay(parentWay, false)) {
42294 routingIsland.add(parentWay);
42295 waysToCheck.push(parentWay);
42299 if (entity2.type === "way" && isRoutableWay(entity2, true)) {
42300 routingIsland.add(entity2);
42301 waysToCheck.push(entity2);
42302 } else if (entity2.type === "node" && isRoutableNode(entity2)) {
42303 routingIsland.add(entity2);
42304 queueParentWays(entity2);
42308 while (waysToCheck.length) {
42309 var wayToCheck = waysToCheck.pop();
42310 var childNodes = graph.childNodes(wayToCheck);
42311 for (var i2 in childNodes) {
42312 var vertex = childNodes[i2];
42313 if (isConnectedVertex(vertex)) {
42316 if (isRoutableNode(vertex)) {
42317 routingIsland.add(vertex);
42319 queueParentWays(vertex);
42322 return routingIsland;
42324 function isConnectedVertex(vertex) {
42325 var osm = services.osm;
42326 if (osm && !osm.isDataLoaded(vertex.loc))
42328 if (vertex.tags.entrance && vertex.tags.entrance !== "no")
42330 if (vertex.tags.amenity === "parking_entrance")
42334 function isRoutableNode(node) {
42335 if (node.tags.highway === "elevator")
42339 function isRoutableWay(way, ignoreInnerWays) {
42340 if (isTaggedAsHighway(way) || way.tags.route === "ferry")
42342 return graph.parentRelations(way).some(function(parentRelation) {
42343 if (parentRelation.tags.type === "route" && parentRelation.tags.route === "ferry")
42345 if (parentRelation.isMultipolygon() && isTaggedAsHighway(parentRelation) && (!ignoreInnerWays || parentRelation.memberById(way.id).role !== "inner"))
42350 function makeContinueDrawingFixIfAllowed(textDirection, vertexID, whichEnd) {
42351 var vertex = graph.hasEntity(vertexID);
42352 if (!vertex || vertex.tags.noexit === "yes")
42354 var useLeftContinue = whichEnd === "start" && textDirection === "ltr" || whichEnd === "end" && textDirection === "rtl";
42355 return new validationIssueFix({
42356 icon: "iD-operation-continue" + (useLeftContinue ? "-left" : ""),
42357 title: _t.append("issues.fix.continue_from_" + whichEnd + ".title"),
42358 entityIds: [vertexID],
42359 onClick: function(context) {
42360 var wayId = this.issue.entityIds[0];
42361 var way = context.hasEntity(wayId);
42362 var vertexId = this.entityIds[0];
42363 var vertex2 = context.hasEntity(vertexId);
42364 if (!way || !vertex2)
42366 var map2 = context.map();
42367 if (!context.editable() || !map2.trimmedExtent().contains(vertex2.loc)) {
42368 map2.zoomToEase(vertex2);
42371 modeDrawLine(context, wayId, context.graph(), "line", way.affix(vertexId), true)
42377 validation.type = type2;
42381 // modules/validations/invalid_format.js
42382 function validationFormatting() {
42383 var type2 = "invalid_format";
42384 var validation = function(entity) {
42386 function isValidEmail(email) {
42387 var valid_email = /^[^\(\)\\,":;<>@\[\]]+@[^\(\)\\,":;<>@\[\]\.]+(?:\.[a-z0-9-]+)*$/i;
42388 return !email || valid_email.test(email);
42390 function showReferenceEmail(selection2) {
42391 selection2.selectAll(".issue-reference").data([0]).enter().append("div").attr("class", "issue-reference").call(_t.append("issues.invalid_format.email.reference"));
42393 if (entity.tags.email) {
42394 var emails = entity.tags.email.split(";").map(function(s) {
42396 }).filter(function(x) {
42397 return !isValidEmail(x);
42399 if (emails.length) {
42400 issues.push(new validationIssue({
42403 severity: "warning",
42404 message: function(context) {
42405 var entity2 = context.hasEntity(this.entityIds[0]);
42406 return entity2 ? _t.append(
42407 "issues.invalid_format.email.message" + this.data,
42408 { feature: utilDisplayLabel(entity2, context.graph()), email: emails.join(", ") }
42411 reference: showReferenceEmail,
42412 entityIds: [entity.id],
42413 hash: emails.join(),
42414 data: emails.length > 1 ? "_multi" : ""
42420 validation.type = type2;
42424 // modules/validations/help_request.js
42425 function validationHelpRequest(context) {
42426 var type2 = "help_request";
42427 var validation = function checkFixmeTag(entity) {
42428 if (!entity.tags.fixme)
42430 if (entity.version === void 0)
42432 if (entity.v !== void 0) {
42433 var baseEntity = context.history().base().hasEntity(entity.id);
42434 if (!baseEntity || !baseEntity.tags.fixme)
42437 return [new validationIssue({
42439 subtype: "fixme_tag",
42440 severity: "warning",
42441 message: function(context2) {
42442 var entity2 = context2.hasEntity(this.entityIds[0]);
42443 return entity2 ? _t.append("issues.fixme_tag.message", {
42444 feature: utilDisplayLabel(
42452 dynamicFixes: function() {
42454 new validationIssueFix({
42455 title: _t.append("issues.fix.address_the_concern.title")
42459 reference: showReference,
42460 entityIds: [entity.id]
42462 function showReference(selection2) {
42463 selection2.selectAll(".issue-reference").data([0]).enter().append("div").attr("class", "issue-reference").call(_t.append("issues.fixme_tag.reference"));
42466 validation.type = type2;
42470 // modules/validations/impossible_oneway.js
42471 function validationImpossibleOneway() {
42472 var type2 = "impossible_oneway";
42473 var validation = function checkImpossibleOneway(entity, graph) {
42474 if (entity.type !== "way" || entity.geometry(graph) !== "line")
42476 if (entity.isClosed())
42478 if (!typeForWay(entity))
42480 if (!isOneway(entity))
42482 var firstIssues = issuesForNode(entity, entity.first());
42483 var lastIssues = issuesForNode(entity, entity.last());
42484 return firstIssues.concat(lastIssues);
42485 function typeForWay(way) {
42486 if (way.geometry(graph) !== "line")
42488 if (osmRoutableHighwayTagValues[way.tags.highway])
42490 if (osmFlowingWaterwayTagValues[way.tags.waterway])
42494 function isOneway(way) {
42495 if (way.tags.oneway === "yes")
42497 if (way.tags.oneway)
42499 for (var key in way.tags) {
42500 if (osmOneWayTags[key] && osmOneWayTags[key][way.tags[key]]) {
42506 function nodeOccursMoreThanOnce(way, nodeID) {
42507 var occurrences = 0;
42508 for (var index in way.nodes) {
42509 if (way.nodes[index] === nodeID) {
42511 if (occurrences > 1)
42517 function isConnectedViaOtherTypes(way, node) {
42518 var wayType = typeForWay(way);
42519 if (wayType === "highway") {
42520 if (node.tags.entrance && node.tags.entrance !== "no")
42522 if (node.tags.amenity === "parking_entrance")
42524 } else if (wayType === "waterway") {
42525 if (node.id === way.first()) {
42526 if (node.tags.natural === "spring")
42529 if (node.tags.manhole === "drain")
42533 return graph.parentWays(node).some(function(parentWay) {
42534 if (parentWay.id === way.id)
42536 if (wayType === "highway") {
42537 if (parentWay.geometry(graph) === "area" && osmRoutableHighwayTagValues[parentWay.tags.highway])
42539 if (parentWay.tags.route === "ferry")
42541 return graph.parentRelations(parentWay).some(function(parentRelation) {
42542 if (parentRelation.tags.type === "route" && parentRelation.tags.route === "ferry")
42544 return parentRelation.isMultipolygon() && osmRoutableHighwayTagValues[parentRelation.tags.highway];
42546 } else if (wayType === "waterway") {
42547 if (parentWay.tags.natural === "water" || parentWay.tags.natural === "coastline")
42553 function issuesForNode(way, nodeID) {
42554 var isFirst = nodeID === way.first();
42555 var wayType = typeForWay(way);
42556 if (nodeOccursMoreThanOnce(way, nodeID))
42558 var osm = services.osm;
42561 var node = graph.hasEntity(nodeID);
42562 if (!node || !osm.isDataLoaded(node.loc))
42564 if (isConnectedViaOtherTypes(way, node))
42566 var attachedWaysOfSameType = graph.parentWays(node).filter(function(parentWay) {
42567 if (parentWay.id === way.id)
42569 return typeForWay(parentWay) === wayType;
42571 if (wayType === "waterway" && attachedWaysOfSameType.length === 0)
42573 var attachedOneways = attachedWaysOfSameType.filter(function(attachedWay) {
42574 return isOneway(attachedWay);
42576 if (attachedOneways.length < attachedWaysOfSameType.length)
42578 if (attachedOneways.length) {
42579 var connectedEndpointsOkay = attachedOneways.some(function(attachedOneway) {
42580 if ((isFirst ? attachedOneway.first() : attachedOneway.last()) !== nodeID)
42582 if (nodeOccursMoreThanOnce(attachedOneway, nodeID))
42586 if (connectedEndpointsOkay)
42589 var placement = isFirst ? "start" : "end", messageID = wayType + ".", referenceID = wayType + ".";
42590 if (wayType === "waterway") {
42591 messageID += "connected." + placement;
42592 referenceID += "connected";
42594 messageID += placement;
42595 referenceID += placement;
42597 return [new validationIssue({
42600 severity: "warning",
42601 message: function(context) {
42602 var entity2 = context.hasEntity(this.entityIds[0]);
42603 return entity2 ? _t.append("issues.impossible_oneway." + messageID + ".message", {
42604 feature: utilDisplayLabel(entity2, context.graph())
42607 reference: getReference(referenceID),
42608 entityIds: [way.id, node.id],
42609 dynamicFixes: function() {
42611 if (attachedOneways.length) {
42612 fixes.push(new validationIssueFix({
42613 icon: "iD-operation-reverse",
42614 title: _t.append("issues.fix.reverse_feature.title"),
42615 entityIds: [way.id],
42616 onClick: function(context) {
42617 var id2 = this.issue.entityIds[0];
42618 context.perform(actionReverse(id2), _t("operations.reverse.annotation.line", { n: 1 }));
42622 if (node.tags.noexit !== "yes") {
42623 var textDirection = _mainLocalizer.textDirection();
42624 var useLeftContinue = isFirst && textDirection === "ltr" || !isFirst && textDirection === "rtl";
42625 fixes.push(new validationIssueFix({
42626 icon: "iD-operation-continue" + (useLeftContinue ? "-left" : ""),
42627 title: _t.append("issues.fix.continue_from_" + (isFirst ? "start" : "end") + ".title"),
42628 onClick: function(context) {
42629 var entityID = this.issue.entityIds[0];
42630 var vertexID = this.issue.entityIds[1];
42631 var way2 = context.entity(entityID);
42632 var vertex = context.entity(vertexID);
42633 continueDrawing(way2, vertex, context);
42641 function getReference(referenceID2) {
42642 return function showReference(selection2) {
42643 selection2.selectAll(".issue-reference").data([0]).enter().append("div").attr("class", "issue-reference").call(_t.append("issues.impossible_oneway." + referenceID2 + ".reference"));
42648 function continueDrawing(way, vertex, context) {
42649 var map2 = context.map();
42650 if (!context.editable() || !map2.trimmedExtent().contains(vertex.loc)) {
42651 map2.zoomToEase(vertex);
42654 modeDrawLine(context, way.id, context.graph(), "line", way.affix(vertex.id), true)
42657 validation.type = type2;
42661 // modules/validations/incompatible_source.js
42662 function validationIncompatibleSource() {
42663 const type2 = "incompatible_source";
42664 const incompatibleRules = [
42667 regex: /(^amap$|^amap\.com|autonavi|mapabc|高德)/i
42671 regex: /(baidu|mapbar|百度)/i
42676 exceptRegex: /((books|drive)\.google|google\s?(books|drive|plus))|(esri\/Google_Africa_Buildings)/i
42679 const validation = function checkIncompatibleSource(entity) {
42680 const entitySources = entity.tags && entity.tags.source && entity.tags.source.split(";");
42681 if (!entitySources)
42683 const entityID = entity.id;
42684 return entitySources.map((source) => {
42685 const matchRule = incompatibleRules.find((rule) => {
42686 if (!rule.regex.test(source))
42688 if (rule.exceptRegex && rule.exceptRegex.test(source))
42694 return new validationIssue({
42696 severity: "warning",
42697 message: (context) => {
42698 const entity2 = context.hasEntity(entityID);
42699 return entity2 ? _t.append("issues.incompatible_source.feature.message", {
42700 feature: utilDisplayLabel(
42709 reference: getReference(matchRule.id),
42710 entityIds: [entityID],
42712 dynamicFixes: () => {
42714 new validationIssueFix({ title: _t.append("issues.fix.remove_proprietary_data.title") })
42718 }).filter(Boolean);
42719 function getReference(id2) {
42720 return function showReference(selection2) {
42721 selection2.selectAll(".issue-reference").data([0]).enter().append("div").attr("class", "issue-reference").call(_t.append(`issues.incompatible_source.reference.${id2}`));
42725 validation.type = type2;
42729 // modules/validations/maprules.js
42730 function validationMaprules() {
42731 var type2 = "maprules";
42732 var validation = function checkMaprules(entity, graph) {
42733 if (!services.maprules)
42735 var rules = services.maprules.validationRules();
42737 for (var i2 = 0; i2 < rules.length; i2++) {
42738 var rule = rules[i2];
42739 rule.findIssues(entity, graph, issues);
42743 validation.type = type2;
42747 // modules/validations/mismatched_geometry.js
42748 var import_fast_deep_equal4 = __toESM(require_fast_deep_equal());
42749 function validationMismatchedGeometry() {
42750 var type2 = "mismatched_geometry";
42751 function tagSuggestingLineIsArea(entity) {
42752 if (entity.type !== "way" || entity.isClosed())
42754 var tagSuggestingArea = entity.tagSuggestingArea();
42755 if (!tagSuggestingArea) {
42758 var asLine = _mainPresetIndex.matchTags(tagSuggestingArea, "line");
42759 var asArea = _mainPresetIndex.matchTags(tagSuggestingArea, "area");
42760 if (asLine && asArea && asLine === asArea) {
42763 return tagSuggestingArea;
42765 function makeConnectEndpointsFixOnClick(way, graph) {
42766 if (way.nodes.length < 3)
42768 var nodes = graph.childNodes(way), testNodes;
42769 var firstToLastDistanceMeters = geoSphericalDistance(nodes[0].loc, nodes[nodes.length - 1].loc);
42770 if (firstToLastDistanceMeters < 0.75) {
42771 testNodes = nodes.slice();
42773 testNodes.push(testNodes[0]);
42774 if (!geoHasSelfIntersections(testNodes, testNodes[0].id)) {
42775 return function(context) {
42776 var way2 = context.entity(this.issue.entityIds[0]);
42778 actionMergeNodes([way2.nodes[0], way2.nodes[way2.nodes.length - 1]], nodes[0].loc),
42779 _t("issues.fix.connect_endpoints.annotation")
42784 testNodes = nodes.slice();
42785 testNodes.push(testNodes[0]);
42786 if (!geoHasSelfIntersections(testNodes, testNodes[0].id)) {
42787 return function(context) {
42788 var wayId = this.issue.entityIds[0];
42789 var way2 = context.entity(wayId);
42790 var nodeId = way2.nodes[0];
42791 var index = way2.nodes.length;
42793 actionAddVertex(wayId, nodeId, index),
42794 _t("issues.fix.connect_endpoints.annotation")
42799 function lineTaggedAsAreaIssue(entity) {
42800 var tagSuggestingArea = tagSuggestingLineIsArea(entity);
42801 if (!tagSuggestingArea)
42803 var validAsLine = false;
42804 var presetAsLine = _mainPresetIndex.matchTags(entity.tags, "line");
42805 if (presetAsLine) {
42806 validAsLine = true;
42807 var key = Object.keys(tagSuggestingArea)[0];
42808 if (presetAsLine.tags[key] && presetAsLine.tags[key] === "*") {
42809 validAsLine = false;
42811 if (Object.keys(presetAsLine.tags).length === 0) {
42812 validAsLine = false;
42815 return new validationIssue({
42817 subtype: "area_as_line",
42818 severity: "warning",
42819 message: function(context) {
42820 var entity2 = context.hasEntity(this.entityIds[0]);
42821 return entity2 ? _t.append("issues.tag_suggests_area.message", {
42822 feature: utilDisplayLabel(
42828 tag: utilTagText({ tags: tagSuggestingArea })
42831 reference: showReference,
42832 entityIds: [entity.id],
42833 hash: JSON.stringify(tagSuggestingArea),
42834 dynamicFixes: function(context) {
42836 var entity2 = context.entity(this.entityIds[0]);
42837 var connectEndsOnClick = makeConnectEndpointsFixOnClick(entity2, context.graph());
42838 if (!validAsLine) {
42839 fixes.push(new validationIssueFix({
42840 title: _t.append("issues.fix.connect_endpoints.title"),
42841 onClick: connectEndsOnClick
42844 fixes.push(new validationIssueFix({
42845 icon: "iD-operation-delete",
42846 title: _t.append("issues.fix.remove_tag.title"),
42847 onClick: function(context2) {
42848 var entityId = this.issue.entityIds[0];
42849 var entity3 = context2.entity(entityId);
42850 var tags = Object.assign({}, entity3.tags);
42851 for (var key2 in tagSuggestingArea) {
42855 actionChangeTags(entityId, tags),
42856 _t("issues.fix.remove_tag.annotation")
42863 function showReference(selection2) {
42864 selection2.selectAll(".issue-reference").data([0]).enter().append("div").attr("class", "issue-reference").call(_t.append("issues.tag_suggests_area.reference"));
42867 function vertexPointIssue(entity, graph) {
42868 if (entity.type !== "node")
42870 if (Object.keys(entity.tags).length === 0)
42872 if (entity.isOnAddressLine(graph))
42874 var geometry = entity.geometry(graph);
42875 var allowedGeometries = osmNodeGeometriesForTags(entity.tags);
42876 if (geometry === "point" && !allowedGeometries.point && allowedGeometries.vertex) {
42877 return new validationIssue({
42879 subtype: "vertex_as_point",
42880 severity: "warning",
42881 message: function(context) {
42882 var entity2 = context.hasEntity(this.entityIds[0]);
42883 return entity2 ? _t.append("issues.vertex_as_point.message", {
42884 feature: utilDisplayLabel(
42892 reference: function showReference(selection2) {
42893 selection2.selectAll(".issue-reference").data([0]).enter().append("div").attr("class", "issue-reference").call(_t.append("issues.vertex_as_point.reference"));
42895 entityIds: [entity.id]
42897 } else if (geometry === "vertex" && !allowedGeometries.vertex && allowedGeometries.point) {
42898 return new validationIssue({
42900 subtype: "point_as_vertex",
42901 severity: "warning",
42902 message: function(context) {
42903 var entity2 = context.hasEntity(this.entityIds[0]);
42904 return entity2 ? _t.append("issues.point_as_vertex.message", {
42905 feature: utilDisplayLabel(
42913 reference: function showReference(selection2) {
42914 selection2.selectAll(".issue-reference").data([0]).enter().append("div").attr("class", "issue-reference").call(_t.append("issues.point_as_vertex.reference"));
42916 entityIds: [entity.id],
42917 dynamicFixes: extractPointDynamicFixes
42922 function otherMismatchIssue(entity, graph) {
42923 if (!entity.hasInterestingTags())
42925 if (entity.type !== "node" && entity.type !== "way")
42927 if (entity.type === "node" && entity.isOnAddressLine(graph))
42929 var sourceGeom = entity.geometry(graph);
42930 var targetGeoms = entity.type === "way" ? ["point", "vertex"] : ["line", "area"];
42931 if (sourceGeom === "area")
42932 targetGeoms.unshift("line");
42933 var asSource = _mainPresetIndex.match(entity, graph);
42934 var targetGeom = targetGeoms.find((nodeGeom) => {
42935 var asTarget = _mainPresetIndex.matchTags(entity.tags, nodeGeom);
42936 if (!asSource || !asTarget || asSource === asTarget || // sometimes there are two presets with the same tags for different geometries
42937 (0, import_fast_deep_equal4.default)(asSource.tags, asTarget.tags))
42939 if (asTarget.isFallback())
42941 var primaryKey = Object.keys(asTarget.tags)[0];
42942 if (primaryKey === "building")
42944 if (asTarget.tags[primaryKey] === "*")
42946 return asSource.isFallback() || asSource.tags[primaryKey] === "*";
42950 var subtype = targetGeom + "_as_" + sourceGeom;
42951 if (targetGeom === "vertex")
42952 targetGeom = "point";
42953 if (sourceGeom === "vertex")
42954 sourceGeom = "point";
42955 var referenceId = targetGeom + "_as_" + sourceGeom;
42957 if (targetGeom === "point") {
42958 dynamicFixes = extractPointDynamicFixes;
42959 } else if (sourceGeom === "area" && targetGeom === "line") {
42960 dynamicFixes = lineToAreaDynamicFixes;
42962 return new validationIssue({
42965 severity: "warning",
42966 message: function(context) {
42967 var entity2 = context.hasEntity(this.entityIds[0]);
42968 return entity2 ? _t.append("issues." + referenceId + ".message", {
42969 feature: utilDisplayLabel(
42977 reference: function showReference(selection2) {
42978 selection2.selectAll(".issue-reference").data([0]).enter().append("div").attr("class", "issue-reference").call(_t.append("issues.mismatched_geometry.reference"));
42980 entityIds: [entity.id],
42984 function lineToAreaDynamicFixes(context) {
42985 var convertOnClick;
42986 var entityId = this.entityIds[0];
42987 var entity = context.entity(entityId);
42988 var tags = Object.assign({}, entity.tags);
42990 if (!osmTagSuggestingArea(tags)) {
42991 convertOnClick = function(context2) {
42992 var entityId2 = this.issue.entityIds[0];
42993 var entity2 = context2.entity(entityId2);
42994 var tags2 = Object.assign({}, entity2.tags);
42999 actionChangeTags(entityId2, tags2),
43000 _t("issues.fix.convert_to_line.annotation")
43005 new validationIssueFix({
43006 icon: "iD-icon-line",
43007 title: _t.append("issues.fix.convert_to_line.title"),
43008 onClick: convertOnClick
43012 function extractPointDynamicFixes(context) {
43013 var entityId = this.entityIds[0];
43014 var extractOnClick = null;
43015 if (!context.hasHiddenConnections(entityId)) {
43016 extractOnClick = function(context2) {
43017 var entityId2 = this.issue.entityIds[0];
43018 var action = actionExtract(entityId2, context2.projection);
43021 _t("operations.extract.annotation", { n: 1 })
43023 context2.enter(modeSelect(context2, [action.getExtractedNodeID()]));
43027 new validationIssueFix({
43028 icon: "iD-operation-extract",
43029 title: _t.append("issues.fix.extract_point.title"),
43030 onClick: extractOnClick
43034 function unclosedMultipolygonPartIssues(entity, graph) {
43035 if (entity.type !== "relation" || !entity.isMultipolygon() || entity.isDegenerate() || // cannot determine issues for incompletely-downloaded relations
43036 !entity.isComplete(graph))
43038 var sequences = osmJoinWays(entity.members, graph);
43040 for (var i2 in sequences) {
43041 var sequence = sequences[i2];
43042 if (!sequence.nodes)
43044 var firstNode = sequence.nodes[0];
43045 var lastNode = sequence.nodes[sequence.nodes.length - 1];
43046 if (firstNode === lastNode)
43048 var issue = new validationIssue({
43050 subtype: "unclosed_multipolygon_part",
43051 severity: "warning",
43052 message: function(context) {
43053 var entity2 = context.hasEntity(this.entityIds[0]);
43054 return entity2 ? _t.append("issues.unclosed_multipolygon_part.message", {
43055 feature: utilDisplayLabel(
43063 reference: showReference,
43064 loc: sequence.nodes[0].loc,
43065 entityIds: [entity.id],
43066 hash: sequence.map(function(way) {
43070 issues.push(issue);
43073 function showReference(selection2) {
43074 selection2.selectAll(".issue-reference").data([0]).enter().append("div").attr("class", "issue-reference").call(_t.append("issues.unclosed_multipolygon_part.reference"));
43077 var validation = function checkMismatchedGeometry(entity, graph) {
43078 var vertexPoint = vertexPointIssue(entity, graph);
43080 return [vertexPoint];
43081 var lineAsArea = lineTaggedAsAreaIssue(entity);
43083 return [lineAsArea];
43084 var mismatch = otherMismatchIssue(entity, graph);
43087 return unclosedMultipolygonPartIssues(entity, graph);
43089 validation.type = type2;
43093 // modules/validations/missing_role.js
43094 function validationMissingRole() {
43095 var type2 = "missing_role";
43096 var validation = function checkMissingRole(entity, graph) {
43098 if (entity.type === "way") {
43099 graph.parentRelations(entity).forEach(function(relation) {
43100 if (!relation.isMultipolygon())
43102 var member = relation.memberById(entity.id);
43103 if (member && isMissingRole(member)) {
43104 issues.push(makeIssue(entity, relation, member));
43107 } else if (entity.type === "relation" && entity.isMultipolygon()) {
43108 entity.indexedMembers().forEach(function(member) {
43109 var way = graph.hasEntity(member.id);
43110 if (way && isMissingRole(member)) {
43111 issues.push(makeIssue(way, entity, member));
43117 function isMissingRole(member) {
43118 return !member.role || !member.role.trim().length;
43120 function makeIssue(way, relation, member) {
43121 return new validationIssue({
43123 severity: "warning",
43124 message: function(context) {
43125 var member2 = context.hasEntity(this.entityIds[1]), relation2 = context.hasEntity(this.entityIds[0]);
43126 return member2 && relation2 ? _t.append("issues.missing_role.message", {
43127 member: utilDisplayLabel(member2, context.graph()),
43128 relation: utilDisplayLabel(relation2, context.graph())
43131 reference: showReference,
43132 entityIds: [relation.id, way.id],
43136 hash: member.index.toString(),
43137 dynamicFixes: function() {
43139 makeAddRoleFix("inner"),
43140 makeAddRoleFix("outer"),
43141 new validationIssueFix({
43142 icon: "iD-operation-delete",
43143 title: _t.append("issues.fix.remove_from_relation.title"),
43144 onClick: function(context) {
43146 actionDeleteMember(this.issue.entityIds[0], this.issue.data.member.index),
43147 _t("operations.delete_member.annotation", {
43156 function showReference(selection2) {
43157 selection2.selectAll(".issue-reference").data([0]).enter().append("div").attr("class", "issue-reference").call(_t.append("issues.missing_role.multipolygon.reference"));
43160 function makeAddRoleFix(role) {
43161 return new validationIssueFix({
43162 title: _t.append("issues.fix.set_as_" + role + ".title"),
43163 onClick: function(context) {
43164 var oldMember = this.issue.data.member;
43165 var member = { id: this.issue.entityIds[1], type: oldMember.type, role };
43167 actionChangeMember(this.issue.entityIds[0], member, oldMember.index),
43168 _t("operations.change_role.annotation", {
43175 validation.type = type2;
43179 // modules/validations/missing_tag.js
43180 function validationMissingTag(context) {
43181 var type2 = "missing_tag";
43182 function hasDescriptiveTags(entity, graph) {
43183 var onlyAttributeKeys = ["description", "name", "note", "start_date"];
43184 var entityDescriptiveKeys = Object.keys(entity.tags).filter(function(k) {
43185 if (k === "area" || !osmIsInterestingTag(k))
43187 return !onlyAttributeKeys.some(function(attributeKey) {
43188 return k === attributeKey || k.indexOf(attributeKey + ":") === 0;
43191 if (entity.type === "relation" && entityDescriptiveKeys.length === 1 && entity.tags.type === "multipolygon") {
43192 return osmOldMultipolygonOuterMemberOfRelation(entity, graph);
43194 return entityDescriptiveKeys.length > 0;
43196 function isUnknownRoad(entity) {
43197 return entity.type === "way" && entity.tags.highway === "road";
43199 function isUntypedRelation(entity) {
43200 return entity.type === "relation" && !entity.tags.type;
43202 var validation = function checkMissingTag(entity, graph) {
43204 var osm = context.connection();
43205 var isUnloadedNode = entity.type === "node" && osm && !osm.isDataLoaded(entity.loc);
43206 if (!isUnloadedNode && // allow untagged nodes that are part of ways
43207 entity.geometry(graph) !== "vertex" && // allow untagged entities that are part of relations
43208 !entity.hasParentRelations(graph)) {
43209 if (Object.keys(entity.tags).length === 0) {
43211 } else if (!hasDescriptiveTags(entity, graph)) {
43212 subtype = "descriptive";
43213 } else if (isUntypedRelation(entity)) {
43214 subtype = "relation_type";
43217 if (!subtype && isUnknownRoad(entity)) {
43218 subtype = "highway_classification";
43222 var messageID = subtype === "highway_classification" ? "unknown_road" : "missing_tag." + subtype;
43223 var referenceID = subtype === "highway_classification" ? "unknown_road" : "missing_tag";
43224 var canDelete = entity.version === void 0 || entity.v !== void 0;
43225 var severity = canDelete && subtype !== "highway_classification" ? "error" : "warning";
43226 return [new validationIssue({
43230 message: function(context2) {
43231 var entity2 = context2.hasEntity(this.entityIds[0]);
43232 return entity2 ? _t.append("issues." + messageID + ".message", {
43233 feature: utilDisplayLabel(entity2, context2.graph())
43236 reference: showReference,
43237 entityIds: [entity.id],
43238 dynamicFixes: function(context2) {
43240 var selectFixType = subtype === "highway_classification" ? "select_road_type" : "select_preset";
43241 fixes.push(new validationIssueFix({
43242 icon: "iD-icon-search",
43243 title: _t.append("issues.fix." + selectFixType + ".title"),
43244 onClick: function(context3) {
43245 context3.ui().sidebar.showPresetList();
43249 var id2 = this.entityIds[0];
43250 var operation = operationDelete(context2, [id2]);
43251 var disabledReasonID = operation.disabled();
43252 if (!disabledReasonID) {
43253 deleteOnClick = function(context3) {
43254 var id3 = this.issue.entityIds[0];
43255 var operation2 = operationDelete(context3, [id3]);
43256 if (!operation2.disabled()) {
43262 new validationIssueFix({
43263 icon: "iD-operation-delete",
43264 title: _t.append("issues.fix.delete_feature.title"),
43265 disabledReason: disabledReasonID ? _t("operations.delete." + disabledReasonID + ".single") : void 0,
43266 onClick: deleteOnClick
43272 function showReference(selection2) {
43273 selection2.selectAll(".issue-reference").data([0]).enter().append("div").attr("class", "issue-reference").call(_t.append("issues." + referenceID + ".reference"));
43276 validation.type = type2;
43280 // modules/validations/outdated_tags.js
43281 function validationOutdatedTags() {
43282 const type2 = "outdated_tags";
43283 let _waitingForDeprecated = true;
43284 let _dataDeprecated;
43285 _mainFileFetcher.get("deprecated").then((d) => _dataDeprecated = d).catch(() => {
43286 }).finally(() => _waitingForDeprecated = false);
43287 function oldTagIssues(entity, graph) {
43288 if (!entity.hasInterestingTags())
43290 let preset = _mainPresetIndex.match(entity, graph);
43293 const oldTags = Object.assign({}, entity.tags);
43294 let subtype = "deprecated_tags";
43295 if (preset.replacement) {
43296 const newPreset = _mainPresetIndex.item(preset.replacement);
43297 graph = actionChangePreset(
43302 /* skip field defaults */
43304 entity = graph.entity(entity.id);
43305 preset = newPreset;
43307 if (_dataDeprecated) {
43308 const deprecatedTags = entity.deprecatedTags(_dataDeprecated);
43309 if (deprecatedTags.length) {
43310 deprecatedTags.forEach((tag) => {
43311 graph = actionUpgradeTags(entity.id, tag.old, tag.replace)(graph);
43313 entity = graph.entity(entity.id);
43316 let newTags = Object.assign({}, entity.tags);
43317 if (preset.tags !== preset.addTags) {
43318 Object.keys(preset.addTags).forEach((k) => {
43320 if (preset.addTags[k] === "*") {
43321 newTags[k] = "yes";
43323 newTags[k] = preset.addTags[k];
43328 const nsi = services.nsi;
43329 let waitingForNsi = false;
43332 waitingForNsi = nsi.status() === "loading";
43333 if (!waitingForNsi) {
43334 const loc = entity.extent(graph).center();
43335 nsiResult = nsi.upgradeTags(newTags, loc);
43337 newTags = nsiResult.newTags;
43338 subtype = "noncanonical_brand";
43343 issues.provisional = _waitingForDeprecated || waitingForNsi;
43344 const tagDiff = utilTagDiff(oldTags, newTags);
43345 if (!tagDiff.length)
43347 const isOnlyAddingTags = tagDiff.every((d) => d.type === "+");
43350 prefix = "noncanonical_brand.";
43351 } else if (subtype === "deprecated_tags" && isOnlyAddingTags) {
43352 subtype = "incomplete_tags";
43353 prefix = "incomplete.";
43355 let autoArgs = subtype !== "noncanonical_brand" ? [doUpgrade, _t("issues.fix.upgrade_tags.annotation")] : null;
43356 issues.push(new validationIssue({
43359 severity: "warning",
43360 message: showMessage,
43361 reference: showReference,
43362 entityIds: [entity.id],
43363 hash: utilHashcode(JSON.stringify(tagDiff)),
43364 dynamicFixes: () => {
43366 new validationIssueFix({
43368 title: _t.append("issues.fix.upgrade_tags.title"),
43369 onClick: (context) => {
43370 context.perform(doUpgrade, _t("issues.fix.upgrade_tags.annotation"));
43374 const item = nsiResult && nsiResult.matched;
43377 new validationIssueFix({
43378 title: _t.append("issues.fix.tag_as_not.title", { name: item.displayName }),
43379 onClick: (context) => {
43380 context.perform(addNotTag, _t("issues.fix.tag_as_not.annotation"));
43389 function doUpgrade(graph2) {
43390 const currEntity = graph2.hasEntity(entity.id);
43393 let newTags2 = Object.assign({}, currEntity.tags);
43394 tagDiff.forEach((diff) => {
43395 if (diff.type === "-") {
43396 delete newTags2[diff.key];
43397 } else if (diff.type === "+") {
43398 newTags2[diff.key] = diff.newVal;
43401 return actionChangeTags(currEntity.id, newTags2)(graph2);
43403 function addNotTag(graph2) {
43404 const currEntity = graph2.hasEntity(entity.id);
43407 const item = nsiResult && nsiResult.matched;
43410 let newTags2 = Object.assign({}, currEntity.tags);
43411 const wd = item.mainTag;
43412 const notwd = `not:${wd}`;
43413 const qid = item.tags[wd];
43414 newTags2[notwd] = qid;
43415 if (newTags2[wd] === qid) {
43416 const wp = item.mainTag.replace("wikidata", "wikipedia");
43417 delete newTags2[wd];
43418 delete newTags2[wp];
43420 return actionChangeTags(currEntity.id, newTags2)(graph2);
43422 function showMessage(context) {
43423 const currEntity = context.hasEntity(entity.id);
43426 let messageID = `issues.outdated_tags.${prefix}message`;
43427 if (subtype === "noncanonical_brand" && isOnlyAddingTags) {
43428 messageID += "_incomplete";
43430 return _t.append(messageID, {
43431 feature: utilDisplayLabel(
43439 function showReference(selection2) {
43440 let enter = selection2.selectAll(".issue-reference").data([0]).enter();
43441 enter.append("div").attr("class", "issue-reference").call(_t.append(`issues.outdated_tags.${prefix}reference`));
43442 enter.append("strong").call(_t.append("issues.suggested"));
43443 enter.append("table").attr("class", "tagDiff-table").selectAll(".tagDiff-row").data(tagDiff).enter().append("tr").attr("class", "tagDiff-row").append("td").attr("class", (d) => {
43444 let klass = d.type === "+" ? "add" : "remove";
43445 return `tagDiff-cell tagDiff-cell-${klass}`;
43446 }).html((d) => d.display);
43449 function oldMultipolygonIssues(entity, graph) {
43450 let multipolygon, outerWay;
43451 if (entity.type === "relation") {
43452 outerWay = osmOldMultipolygonOuterMemberOfRelation(entity, graph);
43453 multipolygon = entity;
43454 } else if (entity.type === "way") {
43455 multipolygon = osmIsOldMultipolygonOuterMember(entity, graph);
43460 if (!multipolygon || !outerWay)
43462 return [new validationIssue({
43464 subtype: "old_multipolygon",
43465 severity: "warning",
43466 message: showMessage,
43467 reference: showReference,
43468 entityIds: [outerWay.id, multipolygon.id],
43469 dynamicFixes: () => {
43471 new validationIssueFix({
43472 autoArgs: [doUpgrade, _t("issues.fix.move_tags.annotation")],
43473 title: _t.append("issues.fix.move_tags.title"),
43474 onClick: (context) => {
43475 context.perform(doUpgrade, _t("issues.fix.move_tags.annotation"));
43481 function doUpgrade(graph2) {
43482 let currMultipolygon = graph2.hasEntity(multipolygon.id);
43483 let currOuterWay = graph2.hasEntity(outerWay.id);
43484 if (!currMultipolygon || !currOuterWay)
43486 currMultipolygon = currMultipolygon.mergeTags(currOuterWay.tags);
43487 graph2 = graph2.replace(currMultipolygon);
43488 return actionChangeTags(currOuterWay.id, {})(graph2);
43490 function showMessage(context) {
43491 let currMultipolygon = context.hasEntity(multipolygon.id);
43492 if (!currMultipolygon)
43495 "issues.old_multipolygon.message",
43496 { multipolygon: utilDisplayLabel(
43504 function showReference(selection2) {
43505 selection2.selectAll(".issue-reference").data([0]).enter().append("div").attr("class", "issue-reference").call(_t.append("issues.old_multipolygon.reference"));
43508 let validation = function checkOutdatedTags(entity, graph) {
43509 let issues = oldMultipolygonIssues(entity, graph);
43510 if (!issues.length)
43511 issues = oldTagIssues(entity, graph);
43514 validation.type = type2;
43518 // modules/validations/private_data.js
43519 function validationPrivateData() {
43520 var type2 = "private_data";
43521 var privateBuildingValues = {
43527 semidetached_house: true,
43528 static_caravan: true
43539 var personalTags = {
43540 "contact:email": true,
43541 "contact:fax": true,
43542 "contact:phone": true,
43547 var validation = function checkPrivateData(entity) {
43548 var tags = entity.tags;
43549 if (!tags.building || !privateBuildingValues[tags.building])
43552 for (var k in tags) {
43555 if (!personalTags[k]) {
43556 keepTags[k] = tags[k];
43559 var tagDiff = utilTagDiff(tags, keepTags);
43560 if (!tagDiff.length)
43562 var fixID = tagDiff.length === 1 ? "remove_tag" : "remove_tags";
43563 return [new validationIssue({
43565 severity: "warning",
43566 message: showMessage,
43567 reference: showReference,
43568 entityIds: [entity.id],
43569 dynamicFixes: function() {
43571 new validationIssueFix({
43572 icon: "iD-operation-delete",
43573 title: _t.append("issues.fix." + fixID + ".title"),
43574 onClick: function(context) {
43575 context.perform(doUpgrade, _t("issues.fix.remove_tag.annotation"));
43581 function doUpgrade(graph) {
43582 var currEntity = graph.hasEntity(entity.id);
43585 var newTags = Object.assign({}, currEntity.tags);
43586 tagDiff.forEach(function(diff) {
43587 if (diff.type === "-") {
43588 delete newTags[diff.key];
43589 } else if (diff.type === "+") {
43590 newTags[diff.key] = diff.newVal;
43593 return actionChangeTags(currEntity.id, newTags)(graph);
43595 function showMessage(context) {
43596 var currEntity = context.hasEntity(this.entityIds[0]);
43600 "issues.private_data.contact.message",
43601 { feature: utilDisplayLabel(currEntity, context.graph()) }
43604 function showReference(selection2) {
43605 var enter = selection2.selectAll(".issue-reference").data([0]).enter();
43606 enter.append("div").attr("class", "issue-reference").call(_t.append("issues.private_data.reference"));
43607 enter.append("strong").call(_t.append("issues.suggested"));
43608 enter.append("table").attr("class", "tagDiff-table").selectAll(".tagDiff-row").data(tagDiff).enter().append("tr").attr("class", "tagDiff-row").append("td").attr("class", function(d) {
43609 var klass = d.type === "+" ? "add" : "remove";
43610 return "tagDiff-cell tagDiff-cell-" + klass;
43611 }).html(function(d) {
43616 validation.type = type2;
43620 // modules/validations/suspicious_name.js
43621 function validationSuspiciousName() {
43622 const type2 = "suspicious_name";
43623 const keysToTestForGenericValues = [
43638 let _waitingForNsi = false;
43639 function isGenericMatchInNsi(tags) {
43640 const nsi = services.nsi;
43642 _waitingForNsi = nsi.status() === "loading";
43643 if (!_waitingForNsi) {
43644 return nsi.isGenericName(tags);
43649 function nameMatchesRawTag(lowercaseName, tags) {
43650 for (let i2 = 0; i2 < keysToTestForGenericValues.length; i2++) {
43651 let key = keysToTestForGenericValues[i2];
43652 let val = tags[key];
43654 val = val.toLowerCase();
43655 if (key === lowercaseName || val === lowercaseName || key.replace(/\_/g, " ") === lowercaseName || val.replace(/\_/g, " ") === lowercaseName) {
43662 function isGenericName(name, tags) {
43663 name = name.toLowerCase();
43664 return nameMatchesRawTag(name, tags) || isGenericMatchInNsi(tags);
43666 function makeGenericNameIssue(entityId, nameKey, genericName, langCode) {
43667 return new validationIssue({
43669 subtype: "generic_name",
43670 severity: "warning",
43671 message: function(context) {
43672 let entity = context.hasEntity(this.entityIds[0]);
43675 let preset = _mainPresetIndex.match(entity, context.graph());
43676 let langName = langCode && _mainLocalizer.languageName(langCode);
43678 "issues.generic_name.message" + (langName ? "_language" : ""),
43679 { feature: preset.name(), name: genericName, language: langName }
43682 reference: showReference,
43683 entityIds: [entityId],
43684 hash: `${nameKey}=${genericName}`,
43685 dynamicFixes: function() {
43687 new validationIssueFix({
43688 icon: "iD-operation-delete",
43689 title: _t.append("issues.fix.remove_the_name.title"),
43690 onClick: function(context) {
43691 let entityId2 = this.issue.entityIds[0];
43692 let entity = context.entity(entityId2);
43693 let tags = Object.assign({}, entity.tags);
43694 delete tags[nameKey];
43696 actionChangeTags(entityId2, tags),
43697 _t("issues.fix.remove_generic_name.annotation")
43704 function showReference(selection2) {
43705 selection2.selectAll(".issue-reference").data([0]).enter().append("div").attr("class", "issue-reference").call(_t.append("issues.generic_name.reference"));
43708 function makeIncorrectNameIssue(entityId, nameKey, incorrectName, langCode) {
43709 return new validationIssue({
43711 subtype: "not_name",
43712 severity: "warning",
43713 message: function(context) {
43714 const entity = context.hasEntity(this.entityIds[0]);
43717 const preset = _mainPresetIndex.match(entity, context.graph());
43718 const langName = langCode && _mainLocalizer.languageName(langCode);
43720 "issues.incorrect_name.message" + (langName ? "_language" : ""),
43721 { feature: preset.name(), name: incorrectName, language: langName }
43724 reference: showReference,
43725 entityIds: [entityId],
43726 hash: `${nameKey}=${incorrectName}`,
43727 dynamicFixes: function() {
43729 new validationIssueFix({
43730 icon: "iD-operation-delete",
43731 title: _t.append("issues.fix.remove_the_name.title"),
43732 onClick: function(context) {
43733 const entityId2 = this.issue.entityIds[0];
43734 const entity = context.entity(entityId2);
43735 let tags = Object.assign({}, entity.tags);
43736 delete tags[nameKey];
43738 actionChangeTags(entityId2, tags),
43739 _t("issues.fix.remove_mistaken_name.annotation")
43746 function showReference(selection2) {
43747 selection2.selectAll(".issue-reference").data([0]).enter().append("div").attr("class", "issue-reference").call(_t.append("issues.generic_name.reference"));
43750 let validation = function checkGenericName(entity) {
43751 const tags = entity.tags;
43752 const hasWikidata = !!tags.wikidata || !!tags["brand:wikidata"] || !!tags["operator:wikidata"];
43756 const notNames2 = (tags["not:name"] || "").split(";");
43757 for (let key in tags) {
43758 const m = key.match(/^name(?:(?::)([a-zA-Z_-]+))?$/);
43761 const langCode = m.length >= 2 ? m[1] : null;
43762 const value = tags[key];
43763 if (notNames2.length) {
43764 for (let i2 in notNames2) {
43765 const notName = notNames2[i2];
43766 if (notName && value === notName) {
43767 issues.push(makeIncorrectNameIssue(entity.id, key, value, langCode));
43772 if (isGenericName(value, tags)) {
43773 issues.provisional = _waitingForNsi;
43774 issues.push(makeGenericNameIssue(entity.id, key, value, langCode));
43779 validation.type = type2;
43783 // modules/validations/unsquare_way.js
43784 function validationUnsquareWay(context) {
43785 var type2 = "unsquare_way";
43786 var DEFAULT_DEG_THRESHOLD = 5;
43787 var epsilon3 = 0.05;
43788 var nodeThreshold = 10;
43789 function isBuilding(entity, graph) {
43790 if (entity.type !== "way" || entity.geometry(graph) !== "area")
43792 return entity.tags.building && entity.tags.building !== "no";
43794 var validation = function checkUnsquareWay(entity, graph) {
43795 if (!isBuilding(entity, graph))
43797 if (entity.tags.nonsquare === "yes")
43799 var isClosed = entity.isClosed();
43802 var nodes = graph.childNodes(entity).slice();
43803 if (nodes.length > nodeThreshold + 1)
43805 var osm = services.osm;
43806 if (!osm || nodes.some(function(node) {
43807 return !osm.isDataLoaded(node.loc);
43810 var hasConnectedSquarableWays = nodes.some(function(node) {
43811 return graph.parentWays(node).some(function(way) {
43812 if (way.id === entity.id)
43814 if (isBuilding(way, graph))
43816 return graph.parentRelations(way).some(function(parentRelation) {
43817 return parentRelation.isMultipolygon() && parentRelation.tags.building && parentRelation.tags.building !== "no";
43821 if (hasConnectedSquarableWays)
43823 var storedDegreeThreshold = corePreferences("validate-square-degrees");
43824 var degreeThreshold = isFinite(storedDegreeThreshold) ? Number(storedDegreeThreshold) : DEFAULT_DEG_THRESHOLD;
43825 var points = nodes.map(function(node) {
43826 return context.projection(node.loc);
43828 if (!geoOrthoCanOrthogonalize(points, isClosed, epsilon3, degreeThreshold, true))
43831 if (!entity.tags.wikidata) {
43832 var autoAction = actionOrthogonalize(entity.id, context.projection, void 0, degreeThreshold);
43833 autoAction.transitionable = false;
43834 autoArgs = [autoAction, _t("operations.orthogonalize.annotation.feature", { n: 1 })];
43836 return [new validationIssue({
43838 subtype: "building",
43839 severity: "warning",
43840 message: function(context2) {
43841 var entity2 = context2.hasEntity(this.entityIds[0]);
43842 return entity2 ? _t.append("issues.unsquare_way.message", {
43843 feature: utilDisplayLabel(entity2, context2.graph())
43846 reference: showReference,
43847 entityIds: [entity.id],
43848 hash: degreeThreshold,
43849 dynamicFixes: function() {
43851 new validationIssueFix({
43852 icon: "iD-operation-orthogonalize",
43853 title: _t.append("issues.fix.square_feature.title"),
43855 onClick: function(context2, completionHandler) {
43856 var entityId = this.issue.entityIds[0];
43858 actionOrthogonalize(entityId, context2.projection, void 0, degreeThreshold),
43859 _t("operations.orthogonalize.annotation.feature", { n: 1 })
43861 window.setTimeout(function() {
43862 completionHandler();
43867 new validationIssueFix({
43868 title: t.append('issues.fix.tag_as_unsquare.title'),
43869 onClick: function(context) {
43870 var entityId = this.issue.entityIds[0];
43871 var entity = context.entity(entityId);
43872 var tags = Object.assign({}, entity.tags); // shallow copy
43873 tags.nonsquare = 'yes';
43875 actionChangeTags(entityId, tags),
43876 t('issues.fix.tag_as_unsquare.annotation')
43884 function showReference(selection2) {
43885 selection2.selectAll(".issue-reference").data([0]).enter().append("div").attr("class", "issue-reference").call(_t.append("issues.unsquare_way.buildings.reference"));
43888 validation.type = type2;
43892 // modules/core/validator.js
43893 function coreValidator(context) {
43894 let dispatch10 = dispatch_default("validated", "focusedIssue");
43895 let validator = utilRebind({}, dispatch10, "on");
43897 let _disabledRules = {};
43898 let _ignoredIssueIDs = /* @__PURE__ */ new Set();
43899 let _resolvedIssueIDs = /* @__PURE__ */ new Set();
43900 let _baseCache = validationCache("base");
43901 let _headCache = validationCache("head");
43902 let _completeDiff = {};
43903 let _headIsCurrent = false;
43904 let _deferredRIC = {};
43905 let _deferredST = /* @__PURE__ */ new Set();
43908 const _errorOverrides = parseHashParam(context.initialHashParams.validationError);
43909 const _warningOverrides = parseHashParam(context.initialHashParams.validationWarning);
43910 const _disableOverrides = parseHashParam(context.initialHashParams.validationDisable);
43911 function parseHashParam(param) {
43913 let rules = (param || "").split(",");
43914 rules.forEach((rule) => {
43915 rule = rule.trim();
43916 const parts = rule.split("/", 2);
43917 const type2 = parts[0];
43918 const subtype = parts[1] || "*";
43919 if (!type2 || !subtype)
43921 result.push({ type: makeRegExp(type2), subtype: makeRegExp(subtype) });
43924 function makeRegExp(str2) {
43925 const escaped = str2.replace(/[-\/\\^$+?.()|[\]{}]/g, "\\$&").replace(/\*/g, ".*");
43926 return new RegExp("^" + escaped + "$");
43929 validator.init = () => {
43930 Object.values(validations_exports).forEach((validation) => {
43931 if (typeof validation !== "function")
43933 const fn = validation(context);
43934 const key = fn.type;
43937 let disabledRules = corePreferences("validate-disabledRules");
43938 if (disabledRules) {
43939 disabledRules.split(",").forEach((k) => _disabledRules[k] = true);
43942 function reset(resetIgnored) {
43943 _baseCache.queue = [];
43944 _headCache.queue = [];
43945 Object.keys(_deferredRIC).forEach((key) => {
43946 window.cancelIdleCallback(key);
43947 _deferredRIC[key]();
43950 _deferredST.forEach(window.clearTimeout);
43951 _deferredST.clear();
43953 _ignoredIssueIDs.clear();
43954 _resolvedIssueIDs.clear();
43955 _baseCache = validationCache("base");
43956 _headCache = validationCache("head");
43957 _completeDiff = {};
43958 _headIsCurrent = false;
43960 validator.reset = () => {
43963 validator.resetIgnoredIssues = () => {
43964 _ignoredIssueIDs.clear();
43965 dispatch10.call("validated");
43967 validator.revalidateUnsquare = () => {
43968 revalidateUnsquare(_headCache);
43969 revalidateUnsquare(_baseCache);
43970 dispatch10.call("validated");
43972 function revalidateUnsquare(cache) {
43973 const checkUnsquareWay = _rules.unsquare_way;
43974 if (!cache.graph || typeof checkUnsquareWay !== "function")
43976 cache.uncacheIssuesOfType("unsquare_way");
43977 const buildings = context.history().tree().intersects(geoExtent([-180, -90], [180, 90]), cache.graph).filter((entity) => entity.type === "way" && entity.tags.building && entity.tags.building !== "no");
43978 buildings.forEach((entity) => {
43979 const detected = checkUnsquareWay(entity, cache.graph);
43980 if (!detected.length)
43982 cache.cacheIssues(detected);
43985 validator.getIssues = (options2) => {
43986 const opts = Object.assign({ what: "all", where: "all", includeIgnored: false, includeDisabledRules: false }, options2);
43987 const view = context.map().extent();
43988 let seen = /* @__PURE__ */ new Set();
43990 if (_headCache.graph && _headCache.graph !== _baseCache.graph) {
43991 Object.values(_headCache.issuesByIssueID).forEach((issue) => {
43992 const userModified = (issue.entityIds || []).some((id2) => _completeDiff.hasOwnProperty(id2));
43993 if (opts.what === "edited" && !userModified)
43995 if (!filter2(issue))
43997 seen.add(issue.id);
43998 results.push(issue);
44001 if (opts.what === "all") {
44002 Object.values(_baseCache.issuesByIssueID).forEach((issue) => {
44003 if (!filter2(issue))
44005 seen.add(issue.id);
44006 results.push(issue);
44010 function filter2(issue) {
44013 if (seen.has(issue.id))
44015 if (_resolvedIssueIDs.has(issue.id))
44017 if (opts.includeDisabledRules === "only" && !_disabledRules[issue.type])
44019 if (!opts.includeDisabledRules && _disabledRules[issue.type])
44021 if (opts.includeIgnored === "only" && !_ignoredIssueIDs.has(issue.id))
44023 if (!opts.includeIgnored && _ignoredIssueIDs.has(issue.id))
44025 if ((issue.entityIds || []).some((id2) => !context.hasEntity(id2)))
44027 if (opts.where === "visible") {
44028 const extent = issue.extent(context.graph());
44029 if (!view.intersects(extent))
44035 validator.getResolvedIssues = () => {
44036 return Array.from(_resolvedIssueIDs).map((issueID) => _baseCache.issuesByIssueID[issueID]).filter(Boolean);
44038 validator.focusIssue = (issue) => {
44039 const graph = context.graph();
44042 const issueExtent = issue.extent(graph);
44044 focusCenter = issueExtent.center();
44046 if (issue.entityIds && issue.entityIds.length) {
44047 selectID = issue.entityIds[0];
44048 if (selectID && selectID.charAt(0) === "r") {
44049 const ids = utilEntityAndDeepMemberIDs([selectID], graph);
44050 let nodeID = ids.find((id2) => id2.charAt(0) === "n" && graph.hasEntity(id2));
44052 const wayID = ids.find((id2) => id2.charAt(0) === "w" && graph.hasEntity(id2));
44054 nodeID = graph.entity(wayID).first();
44058 focusCenter = graph.entity(nodeID).loc;
44063 const setZoom = Math.max(context.map().zoom(), 19);
44064 context.map().unobscuredCenterZoomEase(focusCenter, setZoom);
44067 window.setTimeout(() => {
44068 context.enter(modeSelect(context, [selectID]));
44069 dispatch10.call("focusedIssue", this, issue);
44073 validator.getIssuesBySeverity = (options2) => {
44074 let groups = utilArrayGroupBy(validator.getIssues(options2), "severity");
44075 groups.error = groups.error || [];
44076 groups.warning = groups.warning || [];
44079 validator.getSharedEntityIssues = (entityIDs, options2) => {
44080 const orderedIssueTypes = [
44081 // Show some issue types in a particular order:
44084 // - missing data first
44086 "mismatched_geometry",
44087 // - identity issues
44090 // - geometry issues where fixing them might solve connectivity issues
44091 "disconnected_way",
44092 "impossible_oneway"
44093 // - finally connectivity issues
44095 const allIssues = validator.getIssues(options2);
44096 const forEntityIDs = new Set(entityIDs);
44097 return allIssues.filter((issue) => (issue.entityIds || []).some((entityID) => forEntityIDs.has(entityID))).sort((issue1, issue2) => {
44098 if (issue1.type === issue2.type) {
44099 return issue1.id < issue2.id ? -1 : 1;
44101 const index1 = orderedIssueTypes.indexOf(issue1.type);
44102 const index2 = orderedIssueTypes.indexOf(issue2.type);
44103 if (index1 !== -1 && index2 !== -1) {
44104 return index1 - index2;
44105 } else if (index1 === -1 && index2 === -1) {
44106 return issue1.type < issue2.type ? -1 : 1;
44108 return index1 !== -1 ? -1 : 1;
44112 validator.getEntityIssues = (entityID, options2) => {
44113 return validator.getSharedEntityIssues([entityID], options2);
44115 validator.getRuleKeys = () => {
44116 return Object.keys(_rules);
44118 validator.isRuleEnabled = (key) => {
44119 return !_disabledRules[key];
44121 validator.toggleRule = (key) => {
44122 if (_disabledRules[key]) {
44123 delete _disabledRules[key];
44125 _disabledRules[key] = true;
44127 corePreferences("validate-disabledRules", Object.keys(_disabledRules).join(","));
44128 validator.validate();
44130 validator.disableRules = (keys) => {
44131 _disabledRules = {};
44132 keys.forEach((k) => _disabledRules[k] = true);
44133 corePreferences("validate-disabledRules", Object.keys(_disabledRules).join(","));
44134 validator.validate();
44136 validator.ignoreIssue = (issueID) => {
44137 _ignoredIssueIDs.add(issueID);
44139 validator.validate = () => {
44140 const baseGraph = context.history().base();
44141 if (!_headCache.graph)
44142 _headCache.graph = baseGraph;
44143 if (!_baseCache.graph)
44144 _baseCache.graph = baseGraph;
44145 const prevGraph = _headCache.graph;
44146 const currGraph = context.graph();
44147 if (currGraph === prevGraph) {
44148 _headIsCurrent = true;
44149 dispatch10.call("validated");
44150 return Promise.resolve();
44152 if (_headPromise) {
44153 _headIsCurrent = false;
44154 return _headPromise;
44156 _headCache.graph = currGraph;
44157 _completeDiff = context.history().difference().complete();
44158 const incrementalDiff = coreDifference(prevGraph, currGraph);
44159 let entityIDs = Object.keys(incrementalDiff.complete());
44160 entityIDs = _headCache.withAllRelatedEntities(entityIDs);
44161 if (!entityIDs.size) {
44162 dispatch10.call("validated");
44163 return Promise.resolve();
44165 _headPromise = validateEntitiesAsync(entityIDs, _headCache).then(() => updateResolvedIssues(entityIDs)).then(() => dispatch10.call("validated")).catch(() => {
44167 _headPromise = null;
44168 if (!_headIsCurrent) {
44169 validator.validate();
44172 return _headPromise;
44174 context.history().on("restore.validator", validator.validate).on("undone.validator", validator.validate).on("redone.validator", validator.validate).on("reset.validator", () => {
44176 validator.validate();
44178 context.on("exit.validator", validator.validate);
44179 context.history().on("merge.validator", (entities) => {
44182 const baseGraph = context.history().base();
44183 if (!_headCache.graph)
44184 _headCache.graph = baseGraph;
44185 if (!_baseCache.graph)
44186 _baseCache.graph = baseGraph;
44187 let entityIDs = entities.map((entity) => entity.id);
44188 entityIDs = _baseCache.withAllRelatedEntities(entityIDs);
44189 validateEntitiesAsync(entityIDs, _baseCache);
44191 function validateEntity(entity, graph) {
44192 let result = { issues: [], provisional: false };
44193 Object.keys(_rules).forEach(runValidation);
44195 function runValidation(key) {
44196 const fn = _rules[key];
44197 if (typeof fn !== "function") {
44198 console.error("no such validation rule = " + key);
44201 let detected = fn(entity, graph);
44202 if (detected.provisional) {
44203 result.provisional = true;
44205 detected = detected.filter(applySeverityOverrides);
44206 result.issues = result.issues.concat(detected);
44207 function applySeverityOverrides(issue) {
44208 const type2 = issue.type;
44209 const subtype = issue.subtype || "";
44211 for (i2 = 0; i2 < _errorOverrides.length; i2++) {
44212 if (_errorOverrides[i2].type.test(type2) && _errorOverrides[i2].subtype.test(subtype)) {
44213 issue.severity = "error";
44217 for (i2 = 0; i2 < _warningOverrides.length; i2++) {
44218 if (_warningOverrides[i2].type.test(type2) && _warningOverrides[i2].subtype.test(subtype)) {
44219 issue.severity = "warning";
44223 for (i2 = 0; i2 < _disableOverrides.length; i2++) {
44224 if (_disableOverrides[i2].type.test(type2) && _disableOverrides[i2].subtype.test(subtype)) {
44232 function updateResolvedIssues(entityIDs) {
44233 entityIDs.forEach((entityID) => {
44234 const baseIssues = _baseCache.issuesByEntityID[entityID];
44237 baseIssues.forEach((issueID) => {
44238 const issue = _baseCache.issuesByIssueID[issueID];
44239 const userModified = (issue.entityIds || []).some((id2) => _completeDiff.hasOwnProperty(id2));
44240 if (userModified && !_headCache.issuesByIssueID[issueID]) {
44241 _resolvedIssueIDs.add(issueID);
44243 _resolvedIssueIDs.delete(issueID);
44248 function validateEntitiesAsync(entityIDs, cache) {
44249 const jobs = Array.from(entityIDs).map((entityID) => {
44250 if (cache.queuedEntityIDs.has(entityID))
44252 cache.queuedEntityIDs.add(entityID);
44253 cache.uncacheEntityID(entityID);
44255 cache.queuedEntityIDs.delete(entityID);
44256 const graph = cache.graph;
44259 const entity = graph.hasEntity(entityID);
44262 const result = validateEntity(entity, graph);
44263 if (result.provisional) {
44264 cache.provisionalEntityIDs.add(entityID);
44266 cache.cacheIssues(result.issues);
44268 }).filter(Boolean);
44269 cache.queue = cache.queue.concat(utilArrayChunk(jobs, 100));
44270 if (cache.queuePromise)
44271 return cache.queuePromise;
44272 cache.queuePromise = processQueue(cache).then(() => revalidateProvisionalEntities(cache)).catch(() => {
44273 }).finally(() => cache.queuePromise = null);
44274 return cache.queuePromise;
44276 function revalidateProvisionalEntities(cache) {
44277 if (!cache.provisionalEntityIDs.size)
44279 const handle = window.setTimeout(() => {
44280 _deferredST.delete(handle);
44281 if (!cache.provisionalEntityIDs.size)
44283 validateEntitiesAsync(Array.from(cache.provisionalEntityIDs), cache);
44285 _deferredST.add(handle);
44287 function processQueue(cache) {
44288 if (!cache.queue.length)
44289 return Promise.resolve();
44290 const chunk = cache.queue.pop();
44291 return new Promise((resolvePromise, rejectPromise) => {
44292 const handle = window.requestIdleCallback(() => {
44293 delete _deferredRIC[handle];
44294 chunk.forEach((job) => job());
44297 _deferredRIC[handle] = rejectPromise;
44299 if (cache.queue.length % 25 === 0)
44300 dispatch10.call("validated");
44301 }).then(() => processQueue(cache));
44305 function validationCache(which) {
44310 queuePromise: null,
44311 queuedEntityIDs: /* @__PURE__ */ new Set(),
44312 provisionalEntityIDs: /* @__PURE__ */ new Set(),
44313 issuesByIssueID: {},
44314 // issue.id -> issue
44315 issuesByEntityID: {}
44316 // entity.id -> Set(issue.id)
44318 cache.cacheIssue = (issue) => {
44319 (issue.entityIds || []).forEach((entityID) => {
44320 if (!cache.issuesByEntityID[entityID]) {
44321 cache.issuesByEntityID[entityID] = /* @__PURE__ */ new Set();
44323 cache.issuesByEntityID[entityID].add(issue.id);
44325 cache.issuesByIssueID[issue.id] = issue;
44327 cache.uncacheIssue = (issue) => {
44328 (issue.entityIds || []).forEach((entityID) => {
44329 if (cache.issuesByEntityID[entityID]) {
44330 cache.issuesByEntityID[entityID].delete(issue.id);
44333 delete cache.issuesByIssueID[issue.id];
44335 cache.cacheIssues = (issues) => {
44336 issues.forEach(cache.cacheIssue);
44338 cache.uncacheIssues = (issues) => {
44339 issues.forEach(cache.uncacheIssue);
44341 cache.uncacheIssuesOfType = (type2) => {
44342 const issuesOfType = Object.values(cache.issuesByIssueID).filter((issue) => issue.type === type2);
44343 cache.uncacheIssues(issuesOfType);
44345 cache.uncacheEntityID = (entityID) => {
44346 const entityIssueIDs = cache.issuesByEntityID[entityID];
44347 if (entityIssueIDs) {
44348 entityIssueIDs.forEach((issueID) => {
44349 const issue = cache.issuesByIssueID[issueID];
44351 cache.uncacheIssue(issue);
44353 delete cache.issuesByIssueID[issueID];
44357 delete cache.issuesByEntityID[entityID];
44358 cache.provisionalEntityIDs.delete(entityID);
44360 cache.withAllRelatedEntities = (entityIDs) => {
44361 let result = /* @__PURE__ */ new Set();
44362 (entityIDs || []).forEach((entityID) => {
44363 result.add(entityID);
44364 const entityIssueIDs = cache.issuesByEntityID[entityID];
44365 if (entityIssueIDs) {
44366 entityIssueIDs.forEach((issueID) => {
44367 const issue = cache.issuesByIssueID[issueID];
44369 (issue.entityIds || []).forEach((relatedID) => result.add(relatedID));
44371 delete cache.issuesByIssueID[issueID];
44381 // modules/core/uploader.js
44382 function coreUploader(context) {
44383 var dispatch10 = dispatch_default(
44384 // Start and end events are dispatched exactly once each per legitimate outside call to `save`
44386 // dispatched as soon as a call to `save` has been deemed legitimate
44388 // dispatched after the result event has been dispatched
44389 "willAttemptUpload",
44390 // dispatched before the actual upload call occurs, if it will
44392 // Each save results in one of these outcomes:
44394 // upload wasn't attempted since there were no edits
44396 // upload failed due to errors
44398 // upload failed due to data conflicts
44400 // upload completed without errors
44402 var _isSaving = false;
44403 var _conflicts = [];
44406 var _discardTags = {};
44407 _mainFileFetcher.get("discarded").then(function(d) {
44409 }).catch(function() {
44411 var uploader = utilRebind({}, dispatch10, "on");
44412 uploader.isSaving = function() {
44415 uploader.save = function(changeset, tryAgain, checkConflicts) {
44416 if (_isSaving && !tryAgain) {
44419 var osm = context.connection();
44422 if (!osm.authenticated()) {
44423 osm.authenticate(function(err) {
44425 uploader.save(changeset, tryAgain, checkConflicts);
44432 dispatch10.call("saveStarted", this);
44434 var history = context.history();
44437 _origChanges = history.changes(actionDiscardTags(history.difference(), _discardTags));
44439 history.perform(actionNoop());
44441 if (!checkConflicts) {
44444 performFullConflictCheck(changeset);
44447 function performFullConflictCheck(changeset) {
44448 var osm = context.connection();
44451 var history = context.history();
44452 var localGraph = context.graph();
44453 var remoteGraph = coreGraph(history.base(), true);
44454 var summary = history.difference().summary();
44456 for (var i2 = 0; i2 < summary.length; i2++) {
44457 var item = summary[i2];
44458 if (item.changeType === "modified") {
44459 _toCheck.push(item.entity.id);
44462 var _toLoad = withChildNodes(_toCheck, localGraph);
44464 var _toLoadCount = 0;
44465 var _toLoadTotal = _toLoad.length;
44466 if (_toCheck.length) {
44467 dispatch10.call("progressChanged", this, _toLoadCount, _toLoadTotal);
44468 _toLoad.forEach(function(id2) {
44469 _loaded[id2] = false;
44471 osm.loadMultiple(_toLoad, loaded);
44476 function withChildNodes(ids, graph) {
44477 var s = new Set(ids);
44478 ids.forEach(function(id2) {
44479 var entity = graph.entity(id2);
44480 if (entity.type !== "way")
44482 graph.childNodes(entity).forEach(function(child) {
44483 if (child.version !== void 0) {
44488 return Array.from(s);
44490 function loaded(err, result) {
44491 if (_errors.length)
44495 msg: err.message || err.responseText,
44496 details: [_t("save.status_code", { code: err.status })]
44498 didResultInErrors();
44501 result.data.forEach(function(entity) {
44502 remoteGraph.replace(entity);
44503 _loaded[entity.id] = true;
44504 _toLoad = _toLoad.filter(function(val) {
44505 return val !== entity.id;
44507 if (!entity.visible)
44510 if (entity.type === "way") {
44511 for (i3 = 0; i3 < entity.nodes.length; i3++) {
44512 id2 = entity.nodes[i3];
44513 if (_loaded[id2] === void 0) {
44514 _loaded[id2] = false;
44515 loadMore.push(id2);
44518 } else if (entity.type === "relation" && entity.isMultipolygon()) {
44519 for (i3 = 0; i3 < entity.members.length; i3++) {
44520 id2 = entity.members[i3].id;
44521 if (_loaded[id2] === void 0) {
44522 _loaded[id2] = false;
44523 loadMore.push(id2);
44528 _toLoadCount += result.data.length;
44529 _toLoadTotal += loadMore.length;
44530 dispatch10.call("progressChanged", this, _toLoadCount, _toLoadTotal);
44531 if (loadMore.length) {
44532 _toLoad.push.apply(_toLoad, loadMore);
44533 osm.loadMultiple(loadMore, loaded);
44535 if (!_toLoad.length) {
44541 function detectConflicts() {
44542 function choice(id2, text2, action) {
44546 action: function() {
44547 history.replace(action);
44551 function formatUser(d) {
44552 return '<a href="' + osm.userURL(d) + '" target="_blank">' + escape_default(d) + "</a>";
44554 function entityName(entity) {
44555 return utilDisplayName(entity) || utilDisplayType(entity.id) + " " + entity.id;
44557 function sameVersions(local, remote) {
44558 if (local.version !== remote.version)
44560 if (local.type === "way") {
44561 var children2 = utilArrayUnion(local.nodes, remote.nodes);
44562 for (var i3 = 0; i3 < children2.length; i3++) {
44563 var a = localGraph.hasEntity(children2[i3]);
44564 var b = remoteGraph.hasEntity(children2[i3]);
44565 if (a && b && a.version !== b.version)
44571 _toCheck.forEach(function(id2) {
44572 var local = localGraph.entity(id2);
44573 var remote = remoteGraph.entity(id2);
44574 if (sameVersions(local, remote))
44576 var merge3 = actionMergeRemoteChanges(id2, localGraph, remoteGraph, _discardTags, formatUser);
44577 history.replace(merge3);
44578 var mergeConflicts = merge3.conflicts();
44579 if (!mergeConflicts.length)
44581 var forceLocal = actionMergeRemoteChanges(id2, localGraph, remoteGraph, _discardTags).withOption("force_local");
44582 var forceRemote = actionMergeRemoteChanges(id2, localGraph, remoteGraph, _discardTags).withOption("force_remote");
44583 var keepMine = _t("save.conflict." + (remote.visible ? "keep_local" : "restore"));
44584 var keepTheirs = _t("save.conflict." + (remote.visible ? "keep_remote" : "delete"));
44587 name: entityName(local),
44588 details: mergeConflicts,
44591 choice(id2, keepMine, forceLocal),
44592 choice(id2, keepTheirs, forceRemote)
44598 function upload(changeset) {
44599 var osm = context.connection();
44601 _errors.push({ msg: "No OSM Service" });
44603 if (_conflicts.length) {
44604 didResultInConflicts(changeset);
44605 } else if (_errors.length) {
44606 didResultInErrors();
44608 var history = context.history();
44609 var changes = history.changes(actionDiscardTags(history.difference(), _discardTags));
44610 if (changes.modified.length || changes.created.length || changes.deleted.length) {
44611 dispatch10.call("willAttemptUpload", this);
44612 osm.putChangeset(changeset, changes, uploadCallback);
44614 didResultInNoChanges();
44618 function uploadCallback(err, changeset) {
44620 if (err.status === 409) {
44621 uploader.save(changeset, true, true);
44624 msg: err.message || err.responseText,
44625 details: [_t("save.status_code", { code: err.status })]
44627 didResultInErrors();
44630 didResultInSuccess(changeset);
44633 function didResultInNoChanges() {
44634 dispatch10.call("resultNoChanges", this);
44638 function didResultInErrors() {
44639 context.history().pop();
44640 dispatch10.call("resultErrors", this, _errors);
44643 function didResultInConflicts(changeset) {
44644 _conflicts.sort(function(a, b) {
44645 return b.id.localeCompare(a.id);
44647 dispatch10.call("resultConflicts", this, changeset, _conflicts, _origChanges);
44650 function didResultInSuccess(changeset) {
44651 context.history().clearSaved();
44652 dispatch10.call("resultSuccess", this, changeset);
44653 window.setTimeout(function() {
44658 function endSave() {
44660 dispatch10.call("saveEnded", this);
44662 uploader.cancelConflictResolution = function() {
44663 context.history().pop();
44665 uploader.processResolvedConflicts = function(changeset) {
44666 var history = context.history();
44667 for (var i2 = 0; i2 < _conflicts.length; i2++) {
44668 if (_conflicts[i2].chosen === 1) {
44669 var entity = context.hasEntity(_conflicts[i2].id);
44670 if (entity && entity.type === "way") {
44671 var children2 = utilArrayUniq(entity.nodes);
44672 for (var j2 = 0; j2 < children2.length; j2++) {
44673 history.replace(actionRevert(children2[j2]));
44676 history.replace(actionRevert(_conflicts[i2].id));
44679 uploader.save(changeset, true, false);
44681 uploader.reset = function() {
44686 // modules/renderer/background_source.js
44687 var import_lodash2 = __toESM(require_lodash());
44689 // modules/util/IntervalTasksQueue.js
44690 var IntervalTasksQueue = class {
44692 * Interval in milliseconds inside which only 1 task can execute.
44693 * e.g. if interval is 200ms, and 5 async tasks are unqueued,
44694 * they will complete in ~1s if not cleared
44695 * @param {number} intervalInMs
44697 constructor(intervalInMs) {
44698 this.intervalInMs = intervalInMs;
44699 this.pendingHandles = [];
44703 let taskTimeout = this.time;
44704 this.time += this.intervalInMs;
44705 this.pendingHandles.push(setTimeout(() => {
44706 this.time -= this.intervalInMs;
44711 this.pendingHandles.forEach((timeoutHandle) => {
44712 clearTimeout(timeoutHandle);
44714 this.pendingHandles = [];
44719 // modules/renderer/background_source.js
44720 var isRetina = window.devicePixelRatio && window.devicePixelRatio >= 2;
44721 window.matchMedia(`
44722 (-webkit-min-device-pixel-ratio: 2), /* Safari */
44723 (min-resolution: 2dppx), /* standard */
44724 (min-resolution: 192dpi) /* fallback */
44725 `).addListener(function() {
44726 isRetina = window.devicePixelRatio && window.devicePixelRatio >= 2;
44728 function localeDateString(s) {
44731 var options2 = { day: "numeric", month: "short", year: "numeric" };
44732 var d = new Date(s);
44733 if (isNaN(d.getTime()))
44735 return d.toLocaleDateString(_mainLocalizer.localeCode(), options2);
44737 function vintageRange(vintage) {
44739 if (vintage.start || vintage.end) {
44740 s = vintage.start || "?";
44741 if (vintage.start !== vintage.end) {
44742 s += " - " + (vintage.end || "?");
44747 function rendererBackgroundSource(data) {
44748 var source = Object.assign({}, data);
44749 var _offset = [0, 0];
44750 var _name = source.name;
44751 var _description = source.description;
44752 var _best = !!source.best;
44753 var _template = source.encrypted ? utilAesDecrypt(source.template) : source.template;
44754 source.tileSize = data.tileSize || 256;
44755 source.zoomExtent = data.zoomExtent || [0, 22];
44756 source.overzoom = data.overzoom !== false;
44757 source.offset = function(val) {
44758 if (!arguments.length)
44763 source.nudge = function(val, zoomlevel) {
44764 _offset[0] += val[0] / Math.pow(2, zoomlevel);
44765 _offset[1] += val[1] / Math.pow(2, zoomlevel);
44768 source.name = function() {
44769 var id_safe = source.id.replace(/\./g, "<TX_DOT>");
44770 return _t("imagery." + id_safe + ".name", { default: (0, import_lodash2.escape)(_name) });
44772 source.label = function() {
44773 var id_safe = source.id.replace(/\./g, "<TX_DOT>");
44774 return _t.append("imagery." + id_safe + ".name", { default: (0, import_lodash2.escape)(_name) });
44776 source.hasDescription = function() {
44777 var id_safe = source.id.replace(/\./g, "<TX_DOT>");
44778 var descriptionText = _mainLocalizer.tInfo("imagery." + id_safe + ".description", { default: (0, import_lodash2.escape)(_description) }).text;
44779 return descriptionText !== "";
44781 source.description = function() {
44782 var id_safe = source.id.replace(/\./g, "<TX_DOT>");
44783 return _t.append("imagery." + id_safe + ".description", { default: (0, import_lodash2.escape)(_description) });
44785 source.best = function() {
44788 source.area = function() {
44790 return Number.MAX_VALUE;
44791 var area = area_default({ type: "MultiPolygon", coordinates: [data.polygon] });
44792 return isNaN(area) ? 0 : area;
44794 source.imageryUsed = function() {
44795 return _name || source.id;
44797 source.template = function(val) {
44798 if (!arguments.length)
44800 if (source.id === "custom" || source.id === "Bing") {
44805 source.url = function(coord2) {
44806 var result = _template.replace(/#[\s\S]*/u, "");
44809 if (!source.type || source.id === "custom") {
44810 if (/SERVICE=WMS|\{(proj|wkid|bbox)\}/.test(result)) {
44811 source.type = "wms";
44812 source.projection = "EPSG:3857";
44813 } else if (/\{(x|y)\}/.test(result)) {
44814 source.type = "tms";
44815 } else if (/\{u\}/.test(result)) {
44816 source.type = "bing";
44819 if (source.type === "wms") {
44820 var tileToProjectedCoords = function(x, y, z) {
44821 var zoomSize = Math.pow(2, z);
44822 var lon = x / zoomSize * Math.PI * 2 - Math.PI;
44823 var lat = Math.atan(Math.sinh(Math.PI * (1 - 2 * y / zoomSize)));
44824 switch (source.projection) {
44827 x: lon * 180 / Math.PI,
44828 y: lat * 180 / Math.PI
44831 var mercCoords = mercatorRaw(lon, lat);
44833 x: 2003750834e-2 / Math.PI * mercCoords[0],
44834 y: 2003750834e-2 / Math.PI * mercCoords[1]
44838 var tileSize = source.tileSize;
44839 var projection2 = source.projection;
44840 var minXmaxY = tileToProjectedCoords(coord2[0], coord2[1], coord2[2]);
44841 var maxXminY = tileToProjectedCoords(coord2[0] + 1, coord2[1] + 1, coord2[2]);
44842 result = result.replace(/\{(\w+)\}/g, function(token, key) {
44848 return projection2;
44850 return projection2.replace(/^EPSG:/, "");
44852 if (projection2 === "EPSG:4326" && // The CRS parameter implies version 1.3 (prior versions use SRS)
44853 /VERSION=1.3|CRS={proj}/.test(source.template().toUpperCase())) {
44854 return maxXminY.y + "," + minXmaxY.x + "," + minXmaxY.y + "," + maxXminY.x;
44856 return minXmaxY.x + "," + maxXminY.y + "," + maxXminY.x + "," + minXmaxY.y;
44870 } else if (source.type === "tms") {
44871 result = result.replace("{x}", coord2[0]).replace("{y}", coord2[1]).replace(/\{[t-]y\}/, Math.pow(2, coord2[2]) - coord2[1] - 1).replace(/\{z(oom)?\}/, coord2[2]).replace(/\{@2x\}|\{r\}/, isRetina ? "@2x" : "");
44872 } else if (source.type === "bing") {
44873 result = result.replace("{u}", function() {
44875 for (var zoom = coord2[2]; zoom > 0; zoom--) {
44877 var mask = 1 << zoom - 1;
44878 if ((coord2[0] & mask) !== 0)
44880 if ((coord2[1] & mask) !== 0)
44887 result = result.replace(/\{switch:([^}]+)\}/, function(s, r) {
44888 var subdomains = r.split(",");
44889 return subdomains[(coord2[0] + coord2[1]) % subdomains.length];
44893 source.validZoom = function(z) {
44894 return source.zoomExtent[0] <= z && (source.overzoom || source.zoomExtent[1] > z);
44896 source.isLocatorOverlay = function() {
44897 return source.id === "mapbox_locator_overlay";
44899 source.isHidden = function() {
44900 return source.id === "DigitalGlobe-Premium-vintage" || source.id === "DigitalGlobe-Standard-vintage";
44902 source.copyrightNotices = function() {
44904 source.getMetadata = function(center, tileCoord, callback) {
44906 start: localeDateString(source.startDate),
44907 end: localeDateString(source.endDate)
44909 vintage.range = vintageRange(vintage);
44910 var metadata = { vintage };
44911 callback(null, metadata);
44915 rendererBackgroundSource.Bing = function(data, dispatch10) {
44916 data.template = "https://ecn.t{switch:0,1,2,3}.tiles.virtualearth.net/tiles/a{u}.jpeg?g=1&pr=odbl&n=z";
44917 var bing = rendererBackgroundSource(data);
44918 var key = utilAesDecrypt("5c875730b09c6b422433e807e1ff060b6536c791dbfffcffc4c6b18a1bdba1f14593d151adb50e19e1be1ab19aef813bf135d0f103475e5c724dec94389e45d0");
44919 const strictParam = "n";
44920 var url = "https://dev.virtualearth.net/REST/v1/Imagery/Metadata/AerialOSM?include=ImageryProviders&uriScheme=https&key=" + key;
44923 var providers = [];
44924 var taskQueue = new IntervalTasksQueue(250);
44925 var metadataLastZoom = -1;
44926 json_default(url).then(function(json) {
44927 let imageryResource = json.resourceSets[0].resources[0];
44928 let template = imageryResource.imageUrl;
44929 let subDomains = imageryResource.imageUrlSubdomains;
44930 let subDomainNumbers = subDomains.map((subDomain) => {
44931 return subDomain.substring(1);
44933 template = template.replace("{subdomain}", `t{switch:${subDomainNumbers}}`).replace("{quadkey}", "{u}");
44934 if (!new URLSearchParams(template).has(strictParam)) {
44935 template += `&${strictParam}=z`;
44937 bing.template(template);
44938 providers = imageryResource.imageryProviders.map(function(provider) {
44940 attribution: provider.attribution,
44941 areas: provider.coverageAreas.map(function(area) {
44943 zoom: [area.zoomMin, area.zoomMax],
44944 extent: geoExtent([area.bbox[1], area.bbox[0]], [area.bbox[3], area.bbox[2]])
44949 dispatch10.call("change");
44950 }).catch(function() {
44952 bing.copyrightNotices = function(zoom, extent) {
44953 zoom = Math.min(zoom, 21);
44954 return providers.filter(function(provider) {
44955 return provider.areas.some(function(area) {
44956 return extent.intersects(area.extent) && area.zoom[0] <= zoom && area.zoom[1] >= zoom;
44958 }).map(function(provider) {
44959 return provider.attribution;
44962 bing.getMetadata = function(center, tileCoord, callback) {
44963 var tileID = tileCoord.slice(0, 3).join("/");
44964 var zoom = Math.min(tileCoord[2], 21);
44965 var centerPoint = center[1] + "," + center[0];
44966 var url2 = "https://dev.virtualearth.net/REST/v1/Imagery/BasicMetadata/AerialOSM/" + centerPoint + "?zl=" + zoom + "&key=" + key;
44967 if (inflight[tileID])
44969 if (!cache[tileID]) {
44970 cache[tileID] = {};
44972 if (cache[tileID] && cache[tileID].metadata) {
44973 return callback(null, cache[tileID].metadata);
44975 inflight[tileID] = true;
44976 if (metadataLastZoom !== tileCoord[2]) {
44977 metadataLastZoom = tileCoord[2];
44980 taskQueue.enqueue(() => {
44981 json_default(url2).then(function(result) {
44982 delete inflight[tileID];
44984 throw new Error("Unknown Error");
44987 start: localeDateString(result.resourceSets[0].resources[0].vintageStart),
44988 end: localeDateString(result.resourceSets[0].resources[0].vintageEnd)
44990 vintage.range = vintageRange(vintage);
44991 var metadata = { vintage };
44992 cache[tileID].metadata = metadata;
44994 callback(null, metadata);
44995 }).catch(function(err) {
44996 delete inflight[tileID];
44998 callback(err.message);
45002 bing.terms_url = "https://blog.openstreetmap.org/2010/11/30/microsoft-imagery-details";
45005 rendererBackgroundSource.Esri = function(data) {
45006 if (data.template.match(/blankTile/) === null) {
45007 data.template = data.template + "?blankTile=false";
45009 var esri = rendererBackgroundSource(data);
45013 esri.fetchTilemap = function(center) {
45014 if (_prevCenter && geoSphericalDistance(center, _prevCenter) < 5e3)
45016 _prevCenter = center;
45018 var dummyUrl = esri.url([1, 2, 3]);
45019 var x = Math.floor((center[0] + 180) / 360 * Math.pow(2, z));
45020 var y = Math.floor((1 - Math.log(Math.tan(center[1] * Math.PI / 180) + 1 / Math.cos(center[1] * Math.PI / 180)) / Math.PI) / 2 * Math.pow(2, z));
45021 var tilemapUrl = dummyUrl.replace(/tile\/[0-9]+\/[0-9]+\/[0-9]+\?blankTile=false/, "tilemap") + "/" + z + "/" + y + "/" + x + "/8/8";
45022 json_default(tilemapUrl).then(function(tilemap) {
45024 throw new Error("Unknown Error");
45026 var hasTiles = true;
45027 for (var i2 = 0; i2 < tilemap.data.length; i2++) {
45028 if (!tilemap.data[i2]) {
45033 esri.zoomExtent[1] = hasTiles ? 22 : 19;
45034 }).catch(function() {
45037 esri.getMetadata = function(center, tileCoord, callback) {
45038 if (esri.id !== "EsriWorldImagery") {
45039 return callback(null, {});
45041 var tileID = tileCoord.slice(0, 3).join("/");
45042 var zoom = Math.min(tileCoord[2], esri.zoomExtent[1]);
45043 var centerPoint = center[0] + "," + center[1];
45044 var unknown = _t("info_panels.background.unknown");
45047 if (inflight[tileID])
45049 var url = "https://services.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer/4/query";
45050 url += "?returnGeometry=false&geometry=" + centerPoint + "&inSR=4326&geometryType=esriGeometryPoint&outFields=*&f=json";
45051 if (!cache[tileID]) {
45052 cache[tileID] = {};
45054 if (cache[tileID] && cache[tileID].metadata) {
45055 return callback(null, cache[tileID].metadata);
45057 inflight[tileID] = true;
45058 json_default(url).then(function(result) {
45059 delete inflight[tileID];
45060 result = result.features.map((f2) => f2.attributes).filter((a) => a.MinMapLevel <= zoom && a.MaxMapLevel >= zoom)[0];
45062 throw new Error("Unknown Error");
45063 } else if (result.features && result.features.length < 1) {
45064 throw new Error("No Results");
45065 } else if (result.error && result.error.message) {
45066 throw new Error(result.error.message);
45068 var captureDate = localeDateString(result.SRC_DATE2);
45070 start: captureDate,
45076 source: clean2(result.NICE_NAME),
45077 description: clean2(result.NICE_DESC),
45078 resolution: clean2(+Number(result.SRC_RES).toFixed(4)),
45079 accuracy: clean2(+Number(result.SRC_ACC).toFixed(4))
45081 if (isFinite(metadata.resolution)) {
45082 metadata.resolution += " m";
45084 if (isFinite(metadata.accuracy)) {
45085 metadata.accuracy += " m";
45087 cache[tileID].metadata = metadata;
45089 callback(null, metadata);
45090 }).catch(function(err) {
45091 delete inflight[tileID];
45093 callback(err.message);
45095 function clean2(val) {
45096 return String(val).trim() || unknown;
45101 rendererBackgroundSource.None = function() {
45102 var source = rendererBackgroundSource({ id: "none", template: "" });
45103 source.name = function() {
45104 return _t("background.none");
45106 source.label = function() {
45107 return _t.append("background.none");
45109 source.imageryUsed = function() {
45112 source.area = function() {
45117 rendererBackgroundSource.Custom = function(template) {
45118 var source = rendererBackgroundSource({ id: "custom", template });
45119 source.name = function() {
45120 return _t("background.custom");
45122 source.label = function() {
45123 return _t.append("background.custom");
45125 source.imageryUsed = function() {
45126 var cleaned = source.template();
45127 if (cleaned.indexOf("?") !== -1) {
45128 var parts = cleaned.split("?", 2);
45129 var qs = utilStringQs(parts[1]);
45130 ["access_token", "connectId", "token"].forEach(function(param) {
45132 qs[param] = "{apikey}";
45135 cleaned = parts[0] + "?" + utilQsString(qs, true);
45137 cleaned = cleaned.replace(/token\/(\w+)/, "token/{apikey}").replace(/key=(\w+)/, "key={apikey}");
45138 return "Custom (" + cleaned + " )";
45140 source.area = function() {
45146 // node_modules/@turf/helpers/dist/es/index.js
45147 var earthRadius = 63710088e-1;
45149 centimeters: earthRadius * 100,
45150 centimetres: earthRadius * 100,
45151 degrees: earthRadius / 111325,
45152 feet: earthRadius * 3.28084,
45153 inches: earthRadius * 39.37,
45154 kilometers: earthRadius / 1e3,
45155 kilometres: earthRadius / 1e3,
45156 meters: earthRadius,
45157 metres: earthRadius,
45158 miles: earthRadius / 1609.344,
45159 millimeters: earthRadius * 1e3,
45160 millimetres: earthRadius * 1e3,
45161 nauticalmiles: earthRadius / 1852,
45163 yards: earthRadius * 1.0936
45165 var unitsFactors = {
45168 degrees: 1 / 111325,
45171 kilometers: 1 / 1e3,
45172 kilometres: 1 / 1e3,
45175 miles: 1 / 1609.344,
45178 nauticalmiles: 1 / 1852,
45179 radians: 1 / earthRadius,
45182 function feature2(geom, properties, options2) {
45183 if (options2 === void 0) {
45186 var feat = { type: "Feature" };
45187 if (options2.id === 0 || options2.id) {
45188 feat.id = options2.id;
45190 if (options2.bbox) {
45191 feat.bbox = options2.bbox;
45193 feat.properties = properties || {};
45194 feat.geometry = geom;
45197 function polygon(coordinates, properties, options2) {
45198 if (options2 === void 0) {
45201 for (var _i = 0, coordinates_1 = coordinates; _i < coordinates_1.length; _i++) {
45202 var ring = coordinates_1[_i];
45203 if (ring.length < 4) {
45204 throw new Error("Each LinearRing of a Polygon must have 4 or more Positions.");
45206 for (var j2 = 0; j2 < ring[ring.length - 1].length; j2++) {
45207 if (ring[ring.length - 1][j2] !== ring[0][j2]) {
45208 throw new Error("First and last Position are not equivalent.");
45216 return feature2(geom, properties, options2);
45218 function lineString(coordinates, properties, options2) {
45219 if (options2 === void 0) {
45222 if (coordinates.length < 2) {
45223 throw new Error("coordinates must be an array of two or more positions");
45226 type: "LineString",
45229 return feature2(geom, properties, options2);
45231 function multiLineString(coordinates, properties, options2) {
45232 if (options2 === void 0) {
45236 type: "MultiLineString",
45239 return feature2(geom, properties, options2);
45241 function multiPolygon(coordinates, properties, options2) {
45242 if (options2 === void 0) {
45246 type: "MultiPolygon",
45249 return feature2(geom, properties, options2);
45252 // node_modules/@turf/invariant/dist/es/index.js
45253 function getGeom(geojson) {
45254 if (geojson.type === "Feature") {
45255 return geojson.geometry;
45260 // node_modules/@turf/bbox-clip/dist/es/lib/lineclip.js
45261 function lineclip(points, bbox2, result) {
45262 var len = points.length, codeA = bitCode(points[0], bbox2), part = [], i2, codeB, lastCode;
45267 for (i2 = 1; i2 < len; i2++) {
45268 a = points[i2 - 1];
45270 codeB = lastCode = bitCode(b, bbox2);
45272 if (!(codeA | codeB)) {
45274 if (codeB !== lastCode) {
45276 if (i2 < len - 1) {
45280 } else if (i2 === len - 1) {
45284 } else if (codeA & codeB) {
45286 } else if (codeA) {
45287 a = intersect(a, b, codeA, bbox2);
45288 codeA = bitCode(a, bbox2);
45290 b = intersect(a, b, codeB, bbox2);
45291 codeB = bitCode(b, bbox2);
45300 function polygonclip(points, bbox2) {
45301 var result, edge, prev, prevInside, i2, p, inside;
45302 for (edge = 1; edge <= 8; edge *= 2) {
45304 prev = points[points.length - 1];
45305 prevInside = !(bitCode(prev, bbox2) & edge);
45306 for (i2 = 0; i2 < points.length; i2++) {
45308 inside = !(bitCode(p, bbox2) & edge);
45309 if (inside !== prevInside)
45310 result.push(intersect(prev, p, edge, bbox2));
45314 prevInside = inside;
45317 if (!points.length)
45322 function intersect(a, b, edge, bbox2) {
45323 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;
45325 function bitCode(p, bbox2) {
45327 if (p[0] < bbox2[0])
45329 else if (p[0] > bbox2[2])
45331 if (p[1] < bbox2[1])
45333 else if (p[1] > bbox2[3])
45338 // node_modules/@turf/bbox-clip/dist/es/index.js
45339 function bboxClip(feature3, bbox2) {
45340 var geom = getGeom(feature3);
45341 var type2 = geom.type;
45342 var properties = feature3.type === "Feature" ? feature3.properties : {};
45343 var coords = geom.coordinates;
45346 case "MultiLineString": {
45348 if (type2 === "LineString") {
45351 coords.forEach(function(line) {
45352 lineclip(line, bbox2, lines_1);
45354 if (lines_1.length === 1) {
45355 return lineString(lines_1[0], properties);
45357 return multiLineString(lines_1, properties);
45360 return polygon(clipPolygon(coords, bbox2), properties);
45361 case "MultiPolygon":
45362 return multiPolygon(coords.map(function(poly) {
45363 return clipPolygon(poly, bbox2);
45366 throw new Error("geometry " + type2 + " not supported");
45369 function clipPolygon(rings, bbox2) {
45371 for (var _i = 0, rings_1 = rings; _i < rings_1.length; _i++) {
45372 var ring = rings_1[_i];
45373 var clipped = polygonclip(ring, bbox2);
45374 if (clipped.length > 0) {
45375 if (clipped[0][0] !== clipped[clipped.length - 1][0] || clipped[0][1] !== clipped[clipped.length - 1][1]) {
45376 clipped.push(clipped[0]);
45378 if (clipped.length >= 4) {
45379 outRings.push(clipped);
45386 // node_modules/@turf/meta/dist/es/index.js
45387 function coordEach(geojson, callback, excludeWrapCoord) {
45388 if (geojson === null)
45390 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;
45391 for (var featureIndex = 0; featureIndex < stop; featureIndex++) {
45392 geometryMaybeCollection = isFeatureCollection ? geojson.features[featureIndex].geometry : isFeature ? geojson.geometry : geojson;
45393 isGeometryCollection = geometryMaybeCollection ? geometryMaybeCollection.type === "GeometryCollection" : false;
45394 stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1;
45395 for (var geomIndex = 0; geomIndex < stopG; geomIndex++) {
45396 var multiFeatureIndex = 0;
45397 var geometryIndex = 0;
45398 geometry = isGeometryCollection ? geometryMaybeCollection.geometries[geomIndex] : geometryMaybeCollection;
45399 if (geometry === null)
45401 coords = geometry.coordinates;
45402 var geomType = geometry.type;
45403 wrapShrink = excludeWrapCoord && (geomType === "Polygon" || geomType === "MultiPolygon") ? 1 : 0;
45404 switch (geomType) {
45417 multiFeatureIndex++;
45421 for (j2 = 0; j2 < coords.length; j2++) {
45431 if (geomType === "MultiPoint")
45432 multiFeatureIndex++;
45434 if (geomType === "LineString")
45435 multiFeatureIndex++;
45438 case "MultiLineString":
45439 for (j2 = 0; j2 < coords.length; j2++) {
45440 for (k = 0; k < coords[j2].length - wrapShrink; k++) {
45451 if (geomType === "MultiLineString")
45452 multiFeatureIndex++;
45453 if (geomType === "Polygon")
45456 if (geomType === "Polygon")
45457 multiFeatureIndex++;
45459 case "MultiPolygon":
45460 for (j2 = 0; j2 < coords.length; j2++) {
45462 for (k = 0; k < coords[j2].length; k++) {
45463 for (l = 0; l < coords[j2][k].length - wrapShrink; l++) {
45476 multiFeatureIndex++;
45479 case "GeometryCollection":
45480 for (j2 = 0; j2 < geometry.geometries.length; j2++)
45481 if (coordEach(geometry.geometries[j2], callback, excludeWrapCoord) === false)
45485 throw new Error("Unknown Geometry Type");
45491 // node_modules/@turf/bbox/dist/es/index.js
45492 function bbox(geojson) {
45493 var result = [Infinity, Infinity, -Infinity, -Infinity];
45494 coordEach(geojson, function(coord2) {
45495 if (result[0] > coord2[0]) {
45496 result[0] = coord2[0];
45498 if (result[1] > coord2[1]) {
45499 result[1] = coord2[1];
45501 if (result[2] < coord2[0]) {
45502 result[2] = coord2[0];
45504 if (result[3] < coord2[1]) {
45505 result[3] = coord2[1];
45510 bbox["default"] = bbox;
45511 var es_default = bbox;
45513 // modules/renderer/background.js
45514 var import_which_polygon4 = __toESM(require_which_polygon());
45516 // modules/renderer/tile_layer.js
45517 function rendererTileLayer(context) {
45518 var transformProp = utilPrefixCSSProperty("Transform");
45519 var tiler8 = utilTiler();
45520 var _tileSize = 256;
45526 function tileSizeAtZoom(d, z) {
45527 var EPSILON = 2e-3;
45528 return _tileSize * Math.pow(2, z - d[2]) / _tileSize + EPSILON;
45530 function atZoom(t, distance) {
45531 var power = Math.pow(2, distance);
45533 Math.floor(t[0] * power),
45534 Math.floor(t[1] * power),
45538 function lookUp(d) {
45539 for (var up = -1; up > -d[2]; up--) {
45540 var tile = atZoom(d, up);
45541 if (_cache4[_source.url(tile)] !== false) {
45546 function uniqueBy(a, n2) {
45549 for (var i2 = 0; i2 < a.length; i2++) {
45550 if (seen[a[i2][n2]] === void 0) {
45552 seen[a[i2][n2]] = true;
45557 function addSource(d) {
45558 d.push(_source.url(d));
45561 function background(selection2) {
45562 _zoom = geoScaleToZoom(_projection.scale(), _tileSize);
45566 _source.offset()[0] * Math.pow(2, _zoom),
45567 _source.offset()[1] * Math.pow(2, _zoom)
45570 pixelOffset = [0, 0];
45573 _projection.translate()[0] + pixelOffset[0],
45574 _projection.translate()[1] + pixelOffset[1]
45576 tiler8.scale(_projection.scale() * 2 * Math.PI).translate(translate);
45578 _projection.scale() * Math.PI - translate[0],
45579 _projection.scale() * Math.PI - translate[1]
45581 render(selection2);
45583 function render(selection2) {
45587 var showDebug = context.getDebug("tile") && !_source.overlay;
45588 if (_source.validZoom(_zoom)) {
45589 tiler8.skipNullIsland(!!_source.overlay);
45590 tiler8().forEach(function(d) {
45594 if (typeof d[3] !== "string")
45597 if (_cache4[d[3]] === false && lookUp(d)) {
45598 requests.push(addSource(lookUp(d)));
45601 requests = uniqueBy(requests, 3).filter(function(r) {
45602 return _cache4[r[3]] !== false;
45605 function load(d3_event, d) {
45606 _cache4[d[3]] = true;
45607 select_default2(this).on("error", null).on("load", null).classed("tile-loaded", true);
45608 render(selection2);
45610 function error(d3_event, d) {
45611 _cache4[d[3]] = false;
45612 select_default2(this).on("error", null).on("load", null).remove();
45613 render(selection2);
45615 function imageTransform(d) {
45616 var ts = _tileSize * Math.pow(2, _zoom - d[2]);
45617 var scale = tileSizeAtZoom(d, _zoom);
45618 return "translate(" + (d[0] * ts - _tileOrigin[0]) + "px," + (d[1] * ts - _tileOrigin[1]) + "px) scale(" + scale + "," + scale + ")";
45620 function tileCenter(d) {
45621 var ts = _tileSize * Math.pow(2, _zoom - d[2]);
45623 d[0] * ts - _tileOrigin[0] + ts / 2,
45624 d[1] * ts - _tileOrigin[1] + ts / 2
45627 function debugTransform(d) {
45628 var coord2 = tileCenter(d);
45629 return "translate(" + coord2[0] + "px," + coord2[1] + "px)";
45631 var dims = tiler8.size();
45632 var mapCenter = [dims[0] / 2, dims[1] / 2];
45633 var minDist = Math.max(dims[0], dims[1]);
45635 requests.forEach(function(d) {
45636 var c = tileCenter(d);
45637 var dist = geoVecLength(c, mapCenter);
45638 if (dist < minDist) {
45643 var image = selection2.selectAll("img").data(requests, function(d) {
45646 image.exit().style(transformProp, imageTransform).classed("tile-removing", true).classed("tile-center", false).each(function() {
45647 var tile = select_default2(this);
45648 window.setTimeout(function() {
45649 if (tile.classed("tile-removing")) {
45654 image.enter().append("img").attr("class", "tile").attr("alt", "").attr("draggable", "false").style("width", _tileSize + "px").style("height", _tileSize + "px").attr("src", function(d) {
45656 }).on("error", error).on("load", load).merge(image).style(transformProp, imageTransform).classed("tile-debug", showDebug).classed("tile-removing", false).classed("tile-center", function(d) {
45657 return d === nearCenter;
45659 var debug2 = selection2.selectAll(".tile-label-debug").data(showDebug ? requests : [], function(d) {
45662 debug2.exit().remove();
45664 var debugEnter = debug2.enter().append("div").attr("class", "tile-label-debug");
45665 debugEnter.append("div").attr("class", "tile-label-debug-coord");
45666 debugEnter.append("div").attr("class", "tile-label-debug-vintage");
45667 debug2 = debug2.merge(debugEnter);
45668 debug2.style(transformProp, debugTransform);
45669 debug2.selectAll(".tile-label-debug-coord").text(function(d) {
45670 return d[2] + " / " + d[0] + " / " + d[1];
45672 debug2.selectAll(".tile-label-debug-vintage").each(function(d) {
45673 var span = select_default2(this);
45674 var center = context.projection.invert(tileCenter(d));
45675 _source.getMetadata(center, d, function(err, result) {
45676 if (result && result.vintage && result.vintage.range) {
45677 span.text(result.vintage.range);
45680 span.call(_t.append("info_panels.background.vintage"));
45681 span.append("span").text(": ");
45682 span.call(_t.append("info_panels.background.unknown"));
45688 background.projection = function(val) {
45689 if (!arguments.length)
45690 return _projection;
45694 background.dimensions = function(val) {
45695 if (!arguments.length)
45696 return tiler8.size();
45700 background.source = function(val) {
45701 if (!arguments.length)
45704 _tileSize = _source.tileSize;
45706 tiler8.tileSize(_source.tileSize).zoomExtent(_source.zoomExtent);
45712 // modules/renderer/background.js
45713 var _imageryIndex = null;
45714 function rendererBackground(context) {
45715 const dispatch10 = dispatch_default("change");
45716 const baseLayer = rendererTileLayer(context).projection(context.projection);
45717 let _checkedBlocklists = [];
45718 let _isValid = true;
45719 let _overlayLayers = [];
45720 let _brightness = 1;
45722 let _saturation = 1;
45723 let _sharpness = 1;
45724 function ensureImageryIndex() {
45725 return _mainFileFetcher.get("imagery").then((sources) => {
45727 return _imageryIndex;
45732 const features = sources.map((source) => {
45733 if (!source.polygon)
45735 const rings = source.polygon.map((ring) => [ring]);
45738 properties: { id: source.id },
45739 geometry: { type: "MultiPolygon", coordinates: rings }
45741 _imageryIndex.features[source.id] = feature3;
45743 }).filter(Boolean);
45744 _imageryIndex.query = (0, import_which_polygon4.default)({ type: "FeatureCollection", features });
45745 _imageryIndex.backgrounds = sources.map((source) => {
45746 if (source.type === "bing") {
45747 return rendererBackgroundSource.Bing(source, dispatch10);
45748 } else if (/^EsriWorldImagery/.test(source.id)) {
45749 return rendererBackgroundSource.Esri(source);
45751 return rendererBackgroundSource(source);
45754 _imageryIndex.backgrounds.unshift(rendererBackgroundSource.None());
45755 let template = corePreferences("background-custom-template") || "";
45756 const custom = rendererBackgroundSource.Custom(template);
45757 _imageryIndex.backgrounds.unshift(custom);
45758 return _imageryIndex;
45761 function background(selection2) {
45762 const currSource = baseLayer.source();
45763 if (context.map().zoom() > 18) {
45764 if (currSource && /^EsriWorldImagery/.test(currSource.id)) {
45765 const center = context.map().center();
45766 currSource.fetchTilemap(center);
45769 const sources = background.sources(context.map().extent());
45770 const wasValid = _isValid;
45771 _isValid = !!sources.filter((d) => d === currSource).length;
45772 if (wasValid !== _isValid) {
45773 background.updateImagery();
45775 let baseFilter = "";
45776 if (_brightness !== 1) {
45777 baseFilter += ` brightness(${_brightness})`;
45779 if (_contrast !== 1) {
45780 baseFilter += ` contrast(${_contrast})`;
45782 if (_saturation !== 1) {
45783 baseFilter += ` saturate(${_saturation})`;
45785 if (_sharpness < 1) {
45786 const blur = number_default(0.5, 5)(1 - _sharpness);
45787 baseFilter += ` blur(${blur}px)`;
45789 let base = selection2.selectAll(".layer-background").data([0]);
45790 base = base.enter().insert("div", ".layer-data").attr("class", "layer layer-background").merge(base);
45791 base.style("filter", baseFilter || null);
45792 let imagery = base.selectAll(".layer-imagery").data([0]);
45793 imagery.enter().append("div").attr("class", "layer layer-imagery").merge(imagery).call(baseLayer);
45794 let maskFilter = "";
45795 let mixBlendMode = "";
45796 if (_sharpness > 1) {
45797 mixBlendMode = "overlay";
45798 maskFilter = "saturate(0) blur(3px) invert(1)";
45799 let contrast = _sharpness - 1;
45800 maskFilter += ` contrast(${contrast})`;
45801 let brightness = number_default(1, 0.85)(_sharpness - 1);
45802 maskFilter += ` brightness(${brightness})`;
45804 let mask = base.selectAll(".layer-unsharp-mask").data(_sharpness > 1 ? [0] : []);
45805 mask.exit().remove();
45806 mask.enter().append("div").attr("class", "layer layer-mask layer-unsharp-mask").merge(mask).call(baseLayer).style("filter", maskFilter || null).style("mix-blend-mode", mixBlendMode || null);
45807 let overlays = selection2.selectAll(".layer-overlay").data(_overlayLayers, (d) => d.source().name());
45808 overlays.exit().remove();
45809 overlays.enter().insert("div", ".layer-data").attr("class", "layer layer-overlay").merge(overlays).each((layer, i2, nodes) => select_default2(nodes[i2]).call(layer));
45811 background.updateImagery = function() {
45812 let currSource = baseLayer.source();
45813 if (context.inIntro() || !currSource)
45815 let o = _overlayLayers.filter((d) => !d.source().isLocatorOverlay() && !d.source().isHidden()).map((d) => d.source().id).join(",");
45816 const meters = geoOffsetToMeters(currSource.offset());
45817 const EPSILON = 0.01;
45818 const x = +meters[0].toFixed(2);
45819 const y = +meters[1].toFixed(2);
45820 let hash = utilStringQs(window.location.hash);
45821 let id2 = currSource.id;
45822 if (id2 === "custom") {
45823 id2 = `custom:${currSource.template()}`;
45826 hash.background = id2;
45828 delete hash.background;
45833 delete hash.overlays;
45835 if (Math.abs(x) > EPSILON || Math.abs(y) > EPSILON) {
45836 hash.offset = `${x},${y}`;
45838 delete hash.offset;
45840 if (!window.mocha) {
45841 window.location.replace("#" + utilQsString(hash, true));
45843 let imageryUsed = [];
45844 let photoOverlaysUsed = [];
45845 const currUsed = currSource.imageryUsed();
45846 if (currUsed && _isValid) {
45847 imageryUsed.push(currUsed);
45849 _overlayLayers.filter((d) => !d.source().isLocatorOverlay() && !d.source().isHidden()).forEach((d) => imageryUsed.push(d.source().imageryUsed()));
45850 const dataLayer = context.layers().layer("data");
45851 if (dataLayer && dataLayer.enabled() && dataLayer.hasData()) {
45852 imageryUsed.push(dataLayer.getSrc());
45854 const photoOverlayLayers = {
45855 streetside: "Bing Streetside",
45856 mapillary: "Mapillary Images",
45857 "mapillary-map-features": "Mapillary Map Features",
45858 "mapillary-signs": "Mapillary Signs",
45859 kartaview: "KartaView Images"
45861 for (let layerID in photoOverlayLayers) {
45862 const layer = context.layers().layer(layerID);
45863 if (layer && layer.enabled()) {
45864 photoOverlaysUsed.push(layerID);
45865 imageryUsed.push(photoOverlayLayers[layerID]);
45868 context.history().imageryUsed(imageryUsed);
45869 context.history().photoOverlaysUsed(photoOverlaysUsed);
45871 background.sources = (extent, zoom, includeCurrent) => {
45872 if (!_imageryIndex)
45875 (_imageryIndex.query.bbox(extent.rectangle(), true) || []).forEach((d) => visible[d.id] = true);
45876 const currSource = baseLayer.source();
45877 const osm = context.connection();
45878 const blocklists = osm && osm.imageryBlocklists() || [];
45879 const blocklistChanged = blocklists.length !== _checkedBlocklists.length || blocklists.some((regex, index) => String(regex) !== _checkedBlocklists[index]);
45880 if (blocklistChanged) {
45881 _imageryIndex.backgrounds.forEach((source) => {
45882 source.isBlocked = blocklists.some((regex) => regex.test(source.template()));
45884 _checkedBlocklists = blocklists.map((regex) => String(regex));
45886 return _imageryIndex.backgrounds.filter((source) => {
45887 if (includeCurrent && currSource === source)
45889 if (source.isBlocked)
45891 if (!source.polygon)
45893 if (zoom && zoom < 6)
45895 return visible[source.id];
45898 background.dimensions = (val) => {
45901 baseLayer.dimensions(val);
45902 _overlayLayers.forEach((layer) => layer.dimensions(val));
45904 background.baseLayerSource = function(d) {
45905 if (!arguments.length)
45906 return baseLayer.source();
45907 const osm = context.connection();
45910 const blocklists = osm.imageryBlocklists();
45911 const template = d.template();
45915 for (let i2 = 0; i2 < blocklists.length; i2++) {
45916 regex = blocklists[i2];
45917 fail = regex.test(template);
45923 regex = /.*\.google(apis)?\..*\/(vt|kh)[\?\/].*([xyz]=.*){3}.*/;
45924 fail = regex.test(template);
45926 baseLayer.source(!fail ? d : background.findSource("none"));
45927 dispatch10.call("change");
45928 background.updateImagery();
45931 background.findSource = (id2) => {
45932 if (!id2 || !_imageryIndex)
45934 return _imageryIndex.backgrounds.find((d) => d.id && d.id === id2);
45936 background.bing = () => {
45937 background.baseLayerSource(background.findSource("Bing"));
45939 background.showsLayer = (d) => {
45940 const currSource = baseLayer.source();
45941 if (!d || !currSource)
45943 return d.id === currSource.id || _overlayLayers.some((layer) => d.id === layer.source().id);
45945 background.overlayLayerSources = () => {
45946 return _overlayLayers.map((layer) => layer.source());
45948 background.toggleOverlayLayer = (d) => {
45950 for (let i2 = 0; i2 < _overlayLayers.length; i2++) {
45951 layer = _overlayLayers[i2];
45952 if (layer.source() === d) {
45953 _overlayLayers.splice(i2, 1);
45954 dispatch10.call("change");
45955 background.updateImagery();
45959 layer = rendererTileLayer(context).source(d).projection(context.projection).dimensions(
45960 baseLayer.dimensions()
45962 _overlayLayers.push(layer);
45963 dispatch10.call("change");
45964 background.updateImagery();
45966 background.nudge = (d, zoom) => {
45967 const currSource = baseLayer.source();
45969 currSource.nudge(d, zoom);
45970 dispatch10.call("change");
45971 background.updateImagery();
45975 background.offset = function(d) {
45976 const currSource = baseLayer.source();
45977 if (!arguments.length) {
45978 return currSource && currSource.offset() || [0, 0];
45981 currSource.offset(d);
45982 dispatch10.call("change");
45983 background.updateImagery();
45987 background.brightness = function(d) {
45988 if (!arguments.length)
45989 return _brightness;
45991 if (context.mode())
45992 dispatch10.call("change");
45995 background.contrast = function(d) {
45996 if (!arguments.length)
45999 if (context.mode())
46000 dispatch10.call("change");
46003 background.saturation = function(d) {
46004 if (!arguments.length)
46005 return _saturation;
46007 if (context.mode())
46008 dispatch10.call("change");
46011 background.sharpness = function(d) {
46012 if (!arguments.length)
46015 if (context.mode())
46016 dispatch10.call("change");
46020 background.ensureLoaded = () => {
46022 return _loadPromise;
46023 return _loadPromise = ensureImageryIndex();
46025 background.init = () => {
46026 const loadPromise = background.ensureLoaded();
46027 const hash = utilStringQs(window.location.hash);
46028 const requestedBackground = hash.background || hash.layer;
46029 const lastUsedBackground = corePreferences("background-last-used");
46030 return loadPromise.then((imageryIndex) => {
46031 const extent = context.map().extent();
46032 const validBackgrounds = background.sources(extent).filter((d) => d.id !== "none" && d.id !== "custom");
46033 const first = validBackgrounds.length && validBackgrounds[0];
46034 const isLastUsedValid = !!validBackgrounds.find((d) => d.id && d.id === lastUsedBackground);
46036 if (!requestedBackground && extent) {
46037 const viewArea = extent.area();
46038 best = validBackgrounds.find((s) => {
46039 if (!s.best() || s.overlay)
46041 let bbox2 = es_default(bboxClip(
46042 { type: "MultiPolygon", coordinates: [s.polygon || [extent.polygon()]] },
46045 let area = geoExtent(bbox2.slice(0, 2), bbox2.slice(2, 4)).area();
46046 return area / viewArea > 0.5;
46049 if (requestedBackground && requestedBackground.indexOf("custom:") === 0) {
46050 const template = requestedBackground.replace(/^custom:/, "");
46051 const custom = background.findSource("custom");
46052 background.baseLayerSource(custom.template(template));
46053 corePreferences("background-custom-template", template);
46055 background.baseLayerSource(
46056 background.findSource(requestedBackground) || best || isLastUsedValid && background.findSource(lastUsedBackground) || background.findSource("Bing") || first || background.findSource("none")
46059 const locator = imageryIndex.backgrounds.find((d) => d.overlay && d.default);
46061 background.toggleOverlayLayer(locator);
46063 const overlays = (hash.overlays || "").split(",");
46064 overlays.forEach((overlay) => {
46065 overlay = background.findSource(overlay);
46067 background.toggleOverlayLayer(overlay);
46071 const gpx2 = context.layers().layer("data");
46073 gpx2.url(hash.gpx, ".gpx");
46077 const offset = hash.offset.replace(/;/g, ",").split(",").map((n2) => !isNaN(n2) && n2);
46078 if (offset.length === 2) {
46079 background.offset(geoMetersToOffset(offset));
46082 }).catch((err) => {
46083 console.error(err);
46086 return utilRebind(background, dispatch10, "on");
46089 // modules/renderer/features.js
46090 function rendererFeatures(context) {
46091 var dispatch10 = dispatch_default("change", "redraw");
46092 var features = utilRebind({}, dispatch10, "on");
46093 var _deferred2 = /* @__PURE__ */ new Set();
46094 var traffic_roads = {
46096 "motorway_link": true,
46098 "trunk_link": true,
46100 "primary_link": true,
46102 "secondary_link": true,
46104 "tertiary_link": true,
46105 "residential": true,
46106 "unclassified": true,
46107 "living_street": true,
46110 var service_roads = {
46123 var _cullFactor = 1;
46129 var _forceVisible = {};
46130 function update() {
46131 if (!window.mocha) {
46132 var hash = utilStringQs(window.location.hash);
46133 var disabled = features.disabled();
46134 if (disabled.length) {
46135 hash.disable_features = disabled.join(",");
46137 delete hash.disable_features;
46139 window.location.replace("#" + utilQsString(hash, true));
46140 corePreferences("disabled-features", disabled.join(","));
46142 _hidden = features.hidden();
46143 dispatch10.call("change");
46144 dispatch10.call("redraw");
46146 function defineRule(k, filter2, max3) {
46147 var isEnabled = true;
46151 enabled: isEnabled,
46152 // whether the user wants it enabled..
46154 currentMax: max3 || Infinity,
46155 defaultMax: max3 || Infinity,
46156 enable: function() {
46157 this.enabled = true;
46158 this.currentMax = this.defaultMax;
46160 disable: function() {
46161 this.enabled = false;
46162 this.currentMax = 0;
46164 hidden: function() {
46165 return this.count === 0 && !this.enabled || this.count > this.currentMax * _cullFactor;
46167 autoHidden: function() {
46168 return this.hidden() && this.currentMax > 0;
46172 defineRule("points", function isPoint(tags, geometry) {
46173 return geometry === "point";
46175 defineRule("traffic_roads", function isTrafficRoad(tags) {
46176 return traffic_roads[tags.highway];
46178 defineRule("service_roads", function isServiceRoad(tags) {
46179 return service_roads[tags.highway];
46181 defineRule("paths", function isPath(tags) {
46182 return paths[tags.highway];
46184 defineRule("buildings", function isBuilding(tags) {
46185 return !!tags.building && tags.building !== "no" || tags.parking === "multi-storey" || tags.parking === "sheds" || tags.parking === "carports" || tags.parking === "garage_boxes";
46187 defineRule("building_parts", function isBuildingPart(tags) {
46188 return tags["building:part"];
46190 defineRule("indoor", function isIndoor(tags) {
46191 return tags.indoor;
46193 defineRule("landuse", function isLanduse(tags, geometry) {
46194 return geometry === "area" && !_rules.buildings.filter(tags) && !_rules.building_parts.filter(tags) && !_rules.indoor.filter(tags) && !_rules.water.filter(tags) && !_rules.pistes.filter(tags);
46196 defineRule("boundaries", function isBoundary(tags, geometry) {
46197 return (geometry === "line" && !!tags.boundary || geometry === "relation" && tags.type === "boundary") && !(traffic_roads[tags.highway] || service_roads[tags.highway] || paths[tags.highway] || tags.waterway || tags.railway || tags.landuse || tags.natural || tags.building || tags.power);
46199 defineRule("water", function isWater(tags) {
46200 return !!tags.waterway || tags.natural === "water" || tags.natural === "coastline" || tags.natural === "bay" || tags.landuse === "pond" || tags.landuse === "basin" || tags.landuse === "reservoir" || tags.landuse === "salt_pond";
46202 defineRule("rail", function isRail(tags) {
46203 return (!!tags.railway || tags.landuse === "railway") && !(traffic_roads[tags.highway] || service_roads[tags.highway] || paths[tags.highway]);
46205 defineRule("pistes", function isPiste(tags) {
46206 return tags["piste:type"];
46208 defineRule("aerialways", function isPiste(tags) {
46209 return tags.aerialway && tags.aerialway !== "yes" && tags.aerialway !== "station";
46211 defineRule("power", function isPower(tags) {
46212 return !!tags.power;
46214 defineRule("past_future", function isPastFuture(tags) {
46215 if (traffic_roads[tags.highway] || service_roads[tags.highway] || paths[tags.highway]) {
46218 var strings = Object.keys(tags);
46219 for (var i2 = 0; i2 < strings.length; i2++) {
46220 var s = strings[i2];
46221 if (osmLifecyclePrefixes[s] || osmLifecyclePrefixes[tags[s]])
46226 defineRule("others", function isOther(tags, geometry) {
46227 return geometry === "line" || geometry === "area";
46229 features.features = function() {
46232 features.keys = function() {
46235 features.enabled = function(k) {
46236 if (!arguments.length) {
46237 return _keys.filter(function(k2) {
46238 return _rules[k2].enabled;
46241 return _rules[k] && _rules[k].enabled;
46243 features.disabled = function(k) {
46244 if (!arguments.length) {
46245 return _keys.filter(function(k2) {
46246 return !_rules[k2].enabled;
46249 return _rules[k] && !_rules[k].enabled;
46251 features.hidden = function(k) {
46252 if (!arguments.length) {
46253 return _keys.filter(function(k2) {
46254 return _rules[k2].hidden();
46257 return _rules[k] && _rules[k].hidden();
46259 features.autoHidden = function(k) {
46260 if (!arguments.length) {
46261 return _keys.filter(function(k2) {
46262 return _rules[k2].autoHidden();
46265 return _rules[k] && _rules[k].autoHidden();
46267 features.enable = function(k) {
46268 if (_rules[k] && !_rules[k].enabled) {
46269 _rules[k].enable();
46273 features.enableAll = function() {
46274 var didEnable = false;
46275 for (var k in _rules) {
46276 if (!_rules[k].enabled) {
46278 _rules[k].enable();
46284 features.disable = function(k) {
46285 if (_rules[k] && _rules[k].enabled) {
46286 _rules[k].disable();
46290 features.disableAll = function() {
46291 var didDisable = false;
46292 for (var k in _rules) {
46293 if (_rules[k].enabled) {
46295 _rules[k].disable();
46301 features.toggle = function(k) {
46304 return f2.enabled ? f2.disable() : f2.enable();
46309 features.resetStats = function() {
46310 for (var i2 = 0; i2 < _keys.length; i2++) {
46311 _rules[_keys[i2]].count = 0;
46313 dispatch10.call("change");
46315 features.gatherStats = function(d, resolver, dimensions) {
46316 var needsRedraw = false;
46317 var types = utilArrayGroupBy(d, "type");
46318 var entities = [].concat(types.relation || [], types.way || [], types.node || []);
46319 var currHidden, geometry, matches, i2, j2;
46320 for (i2 = 0; i2 < _keys.length; i2++) {
46321 _rules[_keys[i2]].count = 0;
46323 _cullFactor = dimensions[0] * dimensions[1] / 1e6;
46324 for (i2 = 0; i2 < entities.length; i2++) {
46325 geometry = entities[i2].geometry(resolver);
46326 matches = Object.keys(features.getMatches(entities[i2], resolver, geometry));
46327 for (j2 = 0; j2 < matches.length; j2++) {
46328 _rules[matches[j2]].count++;
46331 currHidden = features.hidden();
46332 if (currHidden !== _hidden) {
46333 _hidden = currHidden;
46334 needsRedraw = true;
46335 dispatch10.call("change");
46337 return needsRedraw;
46339 features.stats = function() {
46340 for (var i2 = 0; i2 < _keys.length; i2++) {
46341 _stats[_keys[i2]] = _rules[_keys[i2]].count;
46345 features.clear = function(d) {
46346 for (var i2 = 0; i2 < d.length; i2++) {
46347 features.clearEntity(d[i2]);
46350 features.clearEntity = function(entity) {
46351 delete _cache4[osmEntity.key(entity)];
46353 features.reset = function() {
46354 Array.from(_deferred2).forEach(function(handle) {
46355 window.cancelIdleCallback(handle);
46356 _deferred2.delete(handle);
46360 function relationShouldBeChecked(relation) {
46361 return relation.tags.type === "boundary";
46363 features.getMatches = function(entity, resolver, geometry) {
46364 if (geometry === "vertex" || geometry === "relation" && !relationShouldBeChecked(entity))
46366 var ent = osmEntity.key(entity);
46367 if (!_cache4[ent]) {
46370 if (!_cache4[ent].matches) {
46372 var hasMatch = false;
46373 for (var i2 = 0; i2 < _keys.length; i2++) {
46374 if (_keys[i2] === "others") {
46377 if (entity.type === "way") {
46378 var parents = features.getParents(entity, resolver, geometry);
46379 if (parents.length === 1 && parents[0].isMultipolygon() || // 2b. or belongs only to boundary relations
46380 parents.length > 0 && parents.every(function(parent) {
46381 return parent.tags.type === "boundary";
46383 var pkey = osmEntity.key(parents[0]);
46384 if (_cache4[pkey] && _cache4[pkey].matches) {
46385 matches = Object.assign({}, _cache4[pkey].matches);
46391 if (_rules[_keys[i2]].filter(entity.tags, geometry)) {
46392 matches[_keys[i2]] = hasMatch = true;
46395 _cache4[ent].matches = matches;
46397 return _cache4[ent].matches;
46399 features.getParents = function(entity, resolver, geometry) {
46400 if (geometry === "point")
46402 var ent = osmEntity.key(entity);
46403 if (!_cache4[ent]) {
46406 if (!_cache4[ent].parents) {
46408 if (geometry === "vertex") {
46409 parents = resolver.parentWays(entity);
46411 parents = resolver.parentRelations(entity);
46413 _cache4[ent].parents = parents;
46415 return _cache4[ent].parents;
46417 features.isHiddenPreset = function(preset, geometry) {
46418 if (!_hidden.length)
46422 var test = preset.setTags({}, geometry);
46423 for (var key in _rules) {
46424 if (_rules[key].filter(test, geometry)) {
46425 if (_hidden.indexOf(key) !== -1) {
46433 features.isHiddenFeature = function(entity, resolver, geometry) {
46434 if (!_hidden.length)
46436 if (!entity.version)
46438 if (_forceVisible[entity.id])
46440 var matches = Object.keys(features.getMatches(entity, resolver, geometry));
46441 return matches.length && matches.every(function(k) {
46442 return features.hidden(k);
46445 features.isHiddenChild = function(entity, resolver, geometry) {
46446 if (!_hidden.length)
46448 if (!entity.version || geometry === "point")
46450 if (_forceVisible[entity.id])
46452 var parents = features.getParents(entity, resolver, geometry);
46453 if (!parents.length)
46455 for (var i2 = 0; i2 < parents.length; i2++) {
46456 if (!features.isHidden(parents[i2], resolver, parents[i2].geometry(resolver))) {
46462 features.hasHiddenConnections = function(entity, resolver) {
46463 if (!_hidden.length)
46465 var childNodes, connections;
46466 if (entity.type === "midpoint") {
46467 childNodes = [resolver.entity(entity.edge[0]), resolver.entity(entity.edge[1])];
46470 childNodes = entity.nodes ? resolver.childNodes(entity) : [];
46471 connections = features.getParents(entity, resolver, entity.geometry(resolver));
46473 connections = childNodes.reduce(function(result, e) {
46474 return resolver.isShared(e) ? utilArrayUnion(result, resolver.parentWays(e)) : result;
46476 return connections.some(function(e) {
46477 return features.isHidden(e, resolver, e.geometry(resolver));
46480 features.isHidden = function(entity, resolver, geometry) {
46481 if (!_hidden.length)
46483 if (!entity.version)
46485 var fn = geometry === "vertex" ? features.isHiddenChild : features.isHiddenFeature;
46486 return fn(entity, resolver, geometry);
46488 features.filter = function(d, resolver) {
46489 if (!_hidden.length)
46492 for (var i2 = 0; i2 < d.length; i2++) {
46493 var entity = d[i2];
46494 if (!features.isHidden(entity, resolver, entity.geometry(resolver))) {
46495 result.push(entity);
46500 features.forceVisible = function(entityIDs) {
46501 if (!arguments.length)
46502 return Object.keys(_forceVisible);
46503 _forceVisible = {};
46504 for (var i2 = 0; i2 < entityIDs.length; i2++) {
46505 _forceVisible[entityIDs[i2]] = true;
46506 var entity = context.hasEntity(entityIDs[i2]);
46507 if (entity && entity.type === "relation") {
46508 for (var j2 in entity.members) {
46509 _forceVisible[entity.members[j2].id] = true;
46515 features.init = function() {
46516 var storage = corePreferences("disabled-features");
46518 var storageDisabled = storage.replace(/;/g, ",").split(",");
46519 storageDisabled.forEach(features.disable);
46521 var hash = utilStringQs(window.location.hash);
46522 if (hash.disable_features) {
46523 var hashDisabled = hash.disable_features.replace(/;/g, ",").split(",");
46524 hashDisabled.forEach(features.disable);
46527 context.history().on("merge.features", function(newEntities) {
46530 var handle = window.requestIdleCallback(function() {
46531 var graph = context.graph();
46532 var types = utilArrayGroupBy(newEntities, "type");
46533 var entities = [].concat(types.relation || [], types.way || [], types.node || []);
46534 for (var i2 = 0; i2 < entities.length; i2++) {
46535 var geometry = entities[i2].geometry(graph);
46536 features.getMatches(entities[i2], graph, geometry);
46539 _deferred2.add(handle);
46544 // modules/svg/areas.js
46545 var import_fast_deep_equal5 = __toESM(require_fast_deep_equal());
46547 // modules/svg/helpers.js
46548 function svgPassiveVertex(node, graph, activeID) {
46551 if (activeID === node.id)
46553 var parents = graph.parentWays(node);
46554 var i2, j2, nodes, isClosed, ix1, ix2, ix3, ix4, max3;
46555 for (i2 = 0; i2 < parents.length; i2++) {
46556 nodes = parents[i2].nodes;
46557 isClosed = parents[i2].isClosed();
46558 for (j2 = 0; j2 < nodes.length; j2++) {
46559 if (nodes[j2] === node.id) {
46565 max3 = nodes.length - 1;
46575 if (nodes[ix1] === activeID)
46577 else if (nodes[ix2] === activeID)
46579 else if (nodes[ix3] === activeID)
46581 else if (nodes[ix4] === activeID)
46583 else if (isClosed && nodes.indexOf(activeID) !== -1)
46590 function svgMarkerSegments(projection2, graph, dt, shouldReverse, bothDirections) {
46591 return function(entity) {
46595 var clip = identity_default2().clipExtent(projection2.clipExtent()).stream;
46596 var coordinates = graph.childNodes(entity).map(function(n2) {
46600 if (shouldReverse(entity)) {
46601 coordinates.reverse();
46604 type: "LineString",
46606 }, projection2.stream(clip({
46607 lineStart: function() {
46609 lineEnd: function() {
46612 point: function(x, y) {
46615 var span = geoVecLength(a, b) - offset;
46617 var heading = geoVecAngle(a, b);
46618 var dx = dt * Math.cos(heading);
46619 var dy = dt * Math.sin(heading);
46621 a[0] + offset * Math.cos(heading),
46622 a[1] + offset * Math.sin(heading)
46624 var coord2 = [a, p];
46625 for (span -= dt; span >= 0; span -= dt) {
46626 p = geoVecAdd(p, [dx, dy]);
46632 for (j2 = 0; j2 < coord2.length; j2++) {
46633 segment += (j2 === 0 ? "M" : "L") + coord2[j2][0] + "," + coord2[j2][1];
46635 segments.push({ id: entity.id, index: i2++, d: segment });
46636 if (bothDirections(entity)) {
46638 for (j2 = coord2.length - 1; j2 >= 0; j2--) {
46639 segment += (j2 === coord2.length - 1 ? "M" : "L") + coord2[j2][0] + "," + coord2[j2][1];
46641 segments.push({ id: entity.id, index: i2++, d: segment });
46652 function svgPath(projection2, graph, isArea) {
46654 var padding = isArea ? 65 : 5;
46655 var viewport = projection2.clipExtent();
46656 var paddedExtent = [
46657 [viewport[0][0] - padding, viewport[0][1] - padding],
46658 [viewport[1][0] + padding, viewport[1][1] + padding]
46660 var clip = identity_default2().clipExtent(paddedExtent).stream;
46661 var project = projection2.stream;
46662 var path = path_default().projection({ stream: function(output) {
46663 return project(clip(output));
46665 var svgpath = function(entity) {
46666 if (entity.id in cache) {
46667 return cache[entity.id];
46669 return cache[entity.id] = path(entity.asGeoJSON(graph));
46672 svgpath.geojson = function(d) {
46673 if (d.__featurehash__ !== void 0) {
46674 if (d.__featurehash__ in cache) {
46675 return cache[d.__featurehash__];
46677 return cache[d.__featurehash__] = path(d);
46685 function svgPointTransform(projection2) {
46686 var svgpoint = function(entity) {
46687 var pt = projection2(entity.loc);
46688 return "translate(" + pt[0] + "," + pt[1] + ")";
46690 svgpoint.geojson = function(d) {
46691 return svgpoint(d.properties.entity);
46695 function svgRelationMemberTags(graph) {
46696 return function(entity) {
46697 var tags = entity.tags;
46698 var shouldCopyMultipolygonTags = !entity.hasInterestingTags();
46699 graph.parentRelations(entity).forEach(function(relation) {
46700 var type2 = relation.tags.type;
46701 if (type2 === "multipolygon" && shouldCopyMultipolygonTags || type2 === "boundary") {
46702 tags = Object.assign({}, relation.tags, tags);
46708 function svgSegmentWay(way, graph, activeID) {
46709 if (activeID === void 0) {
46710 return graph.transient(way, "waySegments", getWaySegments);
46712 return getWaySegments();
46714 function getWaySegments() {
46715 var isActiveWay = way.nodes.indexOf(activeID) !== -1;
46716 var features = { passive: [], active: [] };
46720 for (var i2 = 0; i2 < way.nodes.length; i2++) {
46721 node = graph.entity(way.nodes[i2]);
46722 type2 = svgPassiveVertex(node, graph, activeID);
46723 end = { node, type: type2 };
46724 if (start2.type !== void 0) {
46725 if (start2.node.id === activeID || end.node.id === activeID) {
46726 } else if (isActiveWay && (start2.type === 2 || end.type === 2)) {
46727 pushActive(start2, end, i2);
46728 } else if (start2.type === 0 && end.type === 0) {
46729 pushActive(start2, end, i2);
46731 pushPassive(start2, end, i2);
46737 function pushActive(start3, end2, index) {
46738 features.active.push({
46740 id: way.id + "-" + index + "-nope",
46745 nodes: [start3.node, end2.node],
46749 type: "LineString",
46750 coordinates: [start3.node.loc, end2.node.loc]
46754 function pushPassive(start3, end2, index) {
46755 features.passive.push({
46757 id: way.id + "-" + index,
46761 nodes: [start3.node, end2.node],
46765 type: "LineString",
46766 coordinates: [start3.node.loc, end2.node.loc]
46773 // modules/svg/tag_classes.js
46774 function svgTagClasses() {
46797 var statuses = Object.keys(osmLifecyclePrefixes);
46798 var secondaries = [
46811 "public_transport",
46822 var _tags = function(entity) {
46823 return entity.tags;
46825 var tagClasses = function(selection2) {
46826 selection2.each(function tagClassesEach(entity) {
46827 var value = this.className;
46828 if (value.baseVal !== void 0) {
46829 value = value.baseVal;
46831 var t = _tags(entity);
46832 var computed = tagClasses.getClassesString(t, value);
46833 if (computed !== value) {
46834 select_default2(this).attr("class", computed);
46838 tagClasses.getClassesString = function(t, value) {
46839 var primary, status;
46841 var overrideGeometry;
46842 if (/\bstroke\b/.test(value)) {
46843 if (!!t.barrier && t.barrier !== "no") {
46844 overrideGeometry = "line";
46847 var classes = value.trim().split(/\s+/).filter(function(klass) {
46848 return klass.length && !/^tag-/.test(klass);
46849 }).map(function(klass) {
46850 return klass === "line" || klass === "area" ? overrideGeometry || klass : klass;
46852 for (i2 = 0; i2 < primaries.length; i2++) {
46855 if (!v || v === "no")
46857 if (k === "piste:type") {
46859 } else if (k === "building:part") {
46860 k = "building_part";
46863 if (statuses.indexOf(v) !== -1) {
46865 classes.push("tag-" + k);
46867 classes.push("tag-" + k);
46868 classes.push("tag-" + k + "-" + v);
46873 for (i2 = 0; i2 < statuses.length; i2++) {
46874 for (j2 = 0; j2 < primaries.length; j2++) {
46875 k = statuses[i2] + ":" + primaries[j2];
46877 if (!v || v === "no")
46879 status = statuses[i2];
46885 for (i2 = 0; i2 < statuses.length; i2++) {
46888 if (!v || v === "no")
46892 } else if (primary && primary === v) {
46894 } else if (!primary && primaries.indexOf(v) !== -1) {
46897 classes.push("tag-" + v);
46904 classes.push("tag-status");
46905 classes.push("tag-status-" + status);
46907 for (i2 = 0; i2 < secondaries.length; i2++) {
46908 k = secondaries[i2];
46910 if (!v || v === "no" || k === primary)
46912 classes.push("tag-" + k);
46913 classes.push("tag-" + k + "-" + v);
46915 if (primary === "highway" && !osmPathHighwayTagValues[t.highway] || primary === "aeroway") {
46916 var surface = t.highway === "track" ? "unpaved" : "paved";
46919 if (k in osmPavedTags) {
46920 surface = osmPavedTags[k][v] ? "paved" : "unpaved";
46922 if (k in osmSemipavedTags && !!osmSemipavedTags[k][v]) {
46923 surface = "semipaved";
46926 classes.push("tag-" + surface);
46928 var qid = t.wikidata || t["flag:wikidata"] || t["brand:wikidata"] || t["network:wikidata"] || t["operator:wikidata"];
46930 classes.push("tag-wikidata");
46932 return classes.join(" ").trim();
46934 tagClasses.tags = function(val) {
46935 if (!arguments.length)
46943 // modules/svg/tag_pattern.js
46945 // tag - pattern name
46947 // tag - value - pattern name
46949 // tag - value - rules (optional tag-values, pattern name)
46950 // (matches earlier rules first, so fallback should be last entry)
46952 grave_yard: "cemetery",
46953 fountain: "water_standing"
46957 { religion: "christian", pattern: "cemetery_christian" },
46958 { religion: "buddhist", pattern: "cemetery_buddhist" },
46959 { religion: "muslim", pattern: "cemetery_muslim" },
46960 { religion: "jewish", pattern: "cemetery_jewish" },
46961 { pattern: "cemetery" }
46963 construction: "construction",
46964 farmland: "farmland",
46965 farmyard: "farmyard",
46967 { leaf_type: "broadleaved", pattern: "forest_broadleaved" },
46968 { leaf_type: "needleleaved", pattern: "forest_needleleaved" },
46969 { leaf_type: "leafless", pattern: "forest_leafless" },
46970 { pattern: "forest" }
46971 // same as 'leaf_type:mixed'
46973 grave_yard: "cemetery",
46975 landfill: "landfill",
46977 military: "construction",
46978 orchard: "orchard",
46980 vineyard: "vineyard"
46983 horse_riding: "farmyard"
46987 grassland: "grass",
46991 { water: "pond", pattern: "pond" },
46992 { water: "reservoir", pattern: "water_standing" },
46993 { pattern: "waves" }
46996 { wetland: "marsh", pattern: "wetland_marsh" },
46997 { wetland: "swamp", pattern: "wetland_swamp" },
46998 { wetland: "bog", pattern: "wetland_bog" },
46999 { wetland: "reedbed", pattern: "wetland_reedbed" },
47000 { pattern: "wetland" }
47003 { leaf_type: "broadleaved", pattern: "forest_broadleaved" },
47004 { leaf_type: "needleleaved", pattern: "forest_needleleaved" },
47005 { leaf_type: "leafless", pattern: "forest_leafless" },
47006 { pattern: "forest" }
47007 // same as 'leaf_type:mixed'
47011 green: "golf_green",
47021 function svgTagPattern(tags) {
47022 if (tags.building && tags.building !== "no") {
47025 for (var tag in patterns) {
47026 var entityValue = tags[tag];
47029 if (typeof patterns[tag] === "string") {
47030 return "pattern-" + patterns[tag];
47032 var values = patterns[tag];
47033 for (var value in values) {
47034 if (entityValue !== value)
47036 var rules = values[value];
47037 if (typeof rules === "string") {
47038 return "pattern-" + rules;
47040 for (var ruleKey in rules) {
47041 var rule = rules[ruleKey];
47043 for (var criterion in rule) {
47044 if (criterion !== "pattern") {
47045 var v = tags[criterion];
47046 if (!v || v !== rule[criterion]) {
47053 return "pattern-" + rule.pattern;
47062 // modules/svg/areas.js
47063 function svgAreas(projection2, context) {
47064 function getPatternStyle(tags) {
47065 var imageID = svgTagPattern(tags);
47067 return 'url("#ideditor-' + imageID + '")';
47071 function drawTargets(selection2, graph, entities, filter2) {
47072 var targetClass = context.getDebug("target") ? "pink " : "nocolor ";
47073 var nopeClass = context.getDebug("target") ? "red " : "nocolor ";
47074 var getPath = svgPath(projection2).geojson;
47075 var activeID = context.activeID();
47076 var base = context.history().base();
47077 var data = { targets: [], nopes: [] };
47078 entities.forEach(function(way) {
47079 var features = svgSegmentWay(way, graph, activeID);
47080 data.targets.push.apply(data.targets, features.passive);
47081 data.nopes.push.apply(data.nopes, features.active);
47083 var targetData = data.targets.filter(getPath);
47084 var targets = selection2.selectAll(".area.target-allowed").filter(function(d) {
47085 return filter2(d.properties.entity);
47086 }).data(targetData, function key(d) {
47089 targets.exit().remove();
47090 var segmentWasEdited = function(d) {
47091 var wayID = d.properties.entity.id;
47092 if (!base.entities[wayID] || !(0, import_fast_deep_equal5.default)(graph.entities[wayID].nodes, base.entities[wayID].nodes)) {
47095 return d.properties.nodes.some(function(n2) {
47096 return !base.entities[n2.id] || !(0, import_fast_deep_equal5.default)(graph.entities[n2.id].loc, base.entities[n2.id].loc);
47099 targets.enter().append("path").merge(targets).attr("d", getPath).attr("class", function(d) {
47100 return "way area target target-allowed " + targetClass + d.id;
47101 }).classed("segment-edited", segmentWasEdited);
47102 var nopeData = data.nopes.filter(getPath);
47103 var nopes = selection2.selectAll(".area.target-nope").filter(function(d) {
47104 return filter2(d.properties.entity);
47105 }).data(nopeData, function key(d) {
47108 nopes.exit().remove();
47109 nopes.enter().append("path").merge(nopes).attr("d", getPath).attr("class", function(d) {
47110 return "way area target target-nope " + nopeClass + d.id;
47111 }).classed("segment-edited", segmentWasEdited);
47113 function drawAreas(selection2, graph, entities, filter2) {
47114 var path = svgPath(projection2, graph, true);
47117 var base = context.history().base();
47118 for (var i2 = 0; i2 < entities.length; i2++) {
47119 var entity = entities[i2];
47120 if (entity.geometry(graph) !== "area")
47122 multipolygon = osmIsOldMultipolygonOuterMember(entity, graph);
47123 if (multipolygon) {
47124 areas[multipolygon.id] = {
47125 entity: multipolygon.mergeTags(entity.tags),
47126 area: Math.abs(entity.area(graph))
47128 } else if (!areas[entity.id]) {
47129 areas[entity.id] = {
47131 area: Math.abs(entity.area(graph))
47135 var fills = Object.values(areas).filter(function hasPath(a) {
47136 return path(a.entity);
47138 fills.sort(function areaSort(a, b) {
47139 return b.area - a.area;
47141 fills = fills.map(function(a) {
47144 var strokes = fills.filter(function(area) {
47145 return area.type === "way";
47153 var clipPaths = context.surface().selectAll("defs").selectAll(".clipPath-osm").filter(filter2).data(data.clip, osmEntity.key);
47154 clipPaths.exit().remove();
47155 var clipPathsEnter = clipPaths.enter().append("clipPath").attr("class", "clipPath-osm").attr("id", function(entity2) {
47156 return "ideditor-" + entity2.id + "-clippath";
47158 clipPathsEnter.append("path");
47159 clipPaths.merge(clipPathsEnter).selectAll("path").attr("d", path);
47160 var drawLayer = selection2.selectAll(".layer-osm.areas");
47161 var touchLayer = selection2.selectAll(".layer-touch.areas");
47162 var areagroup = drawLayer.selectAll("g.areagroup").data(["fill", "shadow", "stroke"]);
47163 areagroup = areagroup.enter().append("g").attr("class", function(d) {
47164 return "areagroup area-" + d;
47165 }).merge(areagroup);
47166 var paths = areagroup.selectAll("path").filter(filter2).data(function(layer) {
47167 return data[layer];
47169 paths.exit().remove();
47170 var fillpaths = selection2.selectAll(".area-fill path.area").nodes();
47171 var bisect = bisector(function(node) {
47172 return -node.__data__.area(graph);
47174 function sortedByArea(entity2) {
47175 if (this._parent.__data__ === "fill") {
47176 return fillpaths[bisect(fillpaths, -entity2.area(graph))];
47179 paths = paths.enter().insert("path", sortedByArea).merge(paths).each(function(entity2) {
47180 var layer = this.parentNode.__data__;
47181 this.setAttribute("class", entity2.type + " area " + layer + " " + entity2.id);
47182 if (layer === "fill") {
47183 this.setAttribute("clip-path", "url(#ideditor-" + entity2.id + "-clippath)");
47184 this.style.fill = this.style.stroke = getPatternStyle(entity2.tags);
47186 }).classed("added", function(d) {
47187 return !base.entities[d.id];
47188 }).classed("geometry-edited", function(d) {
47189 return graph.entities[d.id] && base.entities[d.id] && !(0, import_fast_deep_equal5.default)(graph.entities[d.id].nodes, base.entities[d.id].nodes);
47190 }).classed("retagged", function(d) {
47191 return graph.entities[d.id] && base.entities[d.id] && !(0, import_fast_deep_equal5.default)(graph.entities[d.id].tags, base.entities[d.id].tags);
47192 }).call(svgTagClasses()).attr("d", path);
47193 touchLayer.call(drawTargets, graph, data.stroke, filter2);
47198 // modules/svg/data.js
47199 var import_fast_json_stable_stringify = __toESM(require_fast_json_stable_stringify());
47201 // node_modules/@tmcw/togeojson/dist/togeojson.es.mjs
47202 function $(element, tagName) {
47203 return Array.from(element.getElementsByTagName(tagName));
47205 function normalizeId(id2) {
47206 return id2[0] === "#" ? id2 : `#${id2}`;
47208 function $ns(element, tagName, ns) {
47209 return Array.from(element.getElementsByTagNameNS(ns, tagName));
47211 function nodeVal(node) {
47213 return node && node.textContent || "";
47215 function get1(node, tagName, callback) {
47216 const n2 = node.getElementsByTagName(tagName);
47217 const result = n2.length ? n2[0] : null;
47218 if (result && callback)
47222 function get3(node, tagName, callback) {
47223 const properties = {};
47226 const n2 = node.getElementsByTagName(tagName);
47227 const result = n2.length ? n2[0] : null;
47228 if (result && callback) {
47229 return callback(result, properties);
47233 function val1(node, tagName, callback) {
47234 const val = nodeVal(get1(node, tagName));
47235 if (val && callback)
47236 return callback(val) || {};
47239 function $num(node, tagName, callback) {
47240 const val = parseFloat(nodeVal(get1(node, tagName)));
47243 if (val && callback)
47244 return callback(val) || {};
47247 function num1(node, tagName, callback) {
47248 const val = parseFloat(nodeVal(get1(node, tagName)));
47251 if (val && callback)
47255 function getMulti(node, propertyNames) {
47256 const properties = {};
47257 for (const property of propertyNames) {
47258 val1(node, property, (val) => {
47259 properties[property] = val;
47264 function isElement(node) {
47265 return node?.nodeType === 1;
47267 function getLineStyle(node) {
47268 return get3(node, "line", (lineStyle) => {
47269 const val = Object.assign({}, val1(lineStyle, "color", (color2) => {
47270 return { stroke: `#${color2}` };
47271 }), $num(lineStyle, "opacity", (opacity) => {
47272 return { "stroke-opacity": opacity };
47273 }), $num(lineStyle, "width", (width) => {
47274 return { "stroke-width": width * 96 / 25.4 };
47279 function getExtensions(node) {
47283 for (const child of Array.from(node.childNodes)) {
47284 if (!isElement(child))
47286 const name = abbreviateName(child.nodeName);
47287 if (name === "gpxtpx:TrackPointExtension") {
47288 values = values.concat(getExtensions(child));
47290 const val = nodeVal(child);
47291 values.push([name, parseNumeric(val)]);
47296 function abbreviateName(name) {
47297 return ["heart", "gpxtpx:hr", "hr"].includes(name) ? "heart" : name;
47299 function parseNumeric(val) {
47300 const num = parseFloat(val);
47301 return isNaN(num) ? val : num;
47303 function coordPair$1(node) {
47305 parseFloat(node.getAttribute("lon") || ""),
47306 parseFloat(node.getAttribute("lat") || "")
47308 if (isNaN(ll[0]) || isNaN(ll[1])) {
47311 num1(node, "ele", (val) => {
47314 const time = get1(node, "time");
47317 time: time ? nodeVal(time) : null,
47318 extendedValues: getExtensions(get1(node, "extensions"))
47321 function extractProperties(node) {
47322 const properties = getMulti(node, [
47330 const extensions = Array.from(node.getElementsByTagNameNS("http://www.garmin.com/xmlschemas/GpxExtensions/v3", "*"));
47331 for (const child of extensions) {
47332 if (child.parentNode?.parentNode === node) {
47333 properties[child.tagName.replace(":", "_")] = nodeVal(child);
47336 const links = $(node, "link");
47337 if (links.length) {
47338 properties.links = links.map((link2) => Object.assign({ href: link2.getAttribute("href") }, getMulti(link2, ["text", "type"])));
47342 function getPoints$1(node, pointname) {
47343 const pts = $(node, pointname);
47346 const extendedValues = {};
47347 for (let i2 = 0; i2 < pts.length; i2++) {
47348 const c = coordPair$1(pts[i2]);
47352 line.push(c.coordinates);
47354 times.push(c.time);
47355 for (const [name, val] of c.extendedValues) {
47356 const plural = name === "heart" ? name : name.replace("gpxtpx:", "") + "s";
47357 if (!extendedValues[plural]) {
47358 extendedValues[plural] = Array(pts.length).fill(null);
47360 extendedValues[plural][i2] = val;
47363 if (line.length < 2)
47371 function getRoute(node) {
47372 const line = getPoints$1(node, "rtept");
47377 properties: Object.assign({ _gpxType: "rte" }, extractProperties(node), getLineStyle(get1(node, "extensions"))),
47379 type: "LineString",
47380 coordinates: line.line
47384 function getTrack(node) {
47385 const segments = $(node, "trkseg");
47388 const extractedLines = [];
47389 for (const segment of segments) {
47390 const line = getPoints$1(segment, "trkpt");
47392 extractedLines.push(line);
47393 if (line.times && line.times.length)
47394 times.push(line.times);
47397 if (extractedLines.length === 0)
47399 const multi = extractedLines.length > 1;
47400 const properties = Object.assign({ _gpxType: "trk" }, extractProperties(node), getLineStyle(get1(node, "extensions")), times.length ? {
47401 coordinateProperties: {
47402 times: multi ? times : times[0]
47405 for (const line of extractedLines) {
47406 track.push(line.line);
47407 if (!properties.coordinateProperties) {
47408 properties.coordinateProperties = {};
47410 const props = properties.coordinateProperties;
47411 const entries = Object.entries(line.extendedValues);
47412 for (let i2 = 0; i2 < entries.length; i2++) {
47413 const [name, val] = entries[i2];
47415 if (!props[name]) {
47416 props[name] = extractedLines.map((line2) => new Array(line2.line.length).fill(null));
47418 props[name][i2] = val;
47427 geometry: multi ? {
47428 type: "MultiLineString",
47431 type: "LineString",
47432 coordinates: track[0]
47436 function getPoint(node) {
47437 const properties = Object.assign(extractProperties(node), getMulti(node, ["sym"]));
47438 const pair2 = coordPair$1(node);
47446 coordinates: pair2.coordinates
47450 function* gpxGen(node) {
47451 for (const track of $(node, "trk")) {
47452 const feature3 = getTrack(track);
47456 for (const route of $(node, "rte")) {
47457 const feature3 = getRoute(route);
47461 for (const waypoint of $(node, "wpt")) {
47462 const point2 = getPoint(waypoint);
47467 function gpx(node) {
47469 type: "FeatureCollection",
47470 features: Array.from(gpxGen(node))
47473 function fixColor(v, prefix) {
47474 const properties = {};
47475 const colorProp = prefix == "stroke" || prefix === "fill" ? prefix : prefix + "-color";
47476 if (v[0] === "#") {
47477 v = v.substring(1);
47479 if (v.length === 6 || v.length === 3) {
47480 properties[colorProp] = "#" + v;
47481 } else if (v.length === 8) {
47482 properties[prefix + "-opacity"] = parseInt(v.substring(0, 2), 16) / 255;
47483 properties[colorProp] = "#" + v.substring(6, 8) + v.substring(4, 6) + v.substring(2, 4);
47487 function numericProperty(node, source, target) {
47488 const properties = {};
47489 num1(node, source, (val) => {
47490 properties[target] = val;
47494 function getColor(node, output) {
47495 return get3(node, "color", (elem) => fixColor(nodeVal(elem), output));
47497 function extractIcon(node) {
47498 return get3(node, "IconStyle", (iconStyle) => {
47499 return Object.assign(getColor(iconStyle, "icon"), numericProperty(iconStyle, "scale", "icon-scale"), numericProperty(iconStyle, "heading", "icon-heading"), get3(iconStyle, "hotSpot", (hotspot) => {
47500 const left = parseFloat(hotspot.getAttribute("x") || "");
47501 const top = parseFloat(hotspot.getAttribute("y") || "");
47502 const xunits = hotspot.getAttribute("xunits") || "";
47503 const yunits = hotspot.getAttribute("yunits") || "";
47504 if (!isNaN(left) && !isNaN(top))
47506 "icon-offset": [left, top],
47507 "icon-offset-units": [xunits, yunits]
47510 }), get3(iconStyle, "Icon", (icon2, properties) => {
47511 val1(icon2, "href", (href) => {
47512 properties.icon = href;
47518 function extractLabel(node) {
47519 return get3(node, "LabelStyle", (labelStyle) => {
47520 return Object.assign(getColor(labelStyle, "label"), numericProperty(labelStyle, "scale", "label-scale"));
47523 function extractLine(node) {
47524 return get3(node, "LineStyle", (lineStyle) => {
47525 return Object.assign(getColor(lineStyle, "stroke"), numericProperty(lineStyle, "width", "stroke-width"));
47528 function extractPoly(node) {
47529 return get3(node, "PolyStyle", (polyStyle, properties) => {
47530 return Object.assign(properties, get3(polyStyle, "color", (elem) => fixColor(nodeVal(elem), "fill")), val1(polyStyle, "fill", (fill) => {
47532 return { "fill-opacity": 0 };
47533 }), val1(polyStyle, "outline", (outline) => {
47534 if (outline === "0")
47535 return { "stroke-opacity": 0 };
47539 function extractStyle(node) {
47540 return Object.assign({}, extractPoly(node), extractLine(node), extractLabel(node), extractIcon(node));
47542 var removeSpace = /\s*/g;
47543 var trimSpace = /^\s*|\s*$/g;
47544 var splitSpace = /\s+/;
47545 function coord1(value) {
47546 return value.replace(removeSpace, "").split(",").map(parseFloat).filter((num) => !isNaN(num)).slice(0, 3);
47548 function coord(value) {
47549 return value.replace(trimSpace, "").split(splitSpace).map(coord1).filter((coord2) => {
47550 return coord2.length >= 2;
47553 function gxCoords(node) {
47554 let elems = $(node, "coord");
47555 if (elems.length === 0) {
47556 elems = $ns(node, "coord", "*");
47558 const coordinates = elems.map((elem) => {
47559 return nodeVal(elem).split(" ").map(parseFloat);
47561 if (coordinates.length === 0) {
47565 geometry: coordinates.length > 2 ? {
47566 type: "LineString",
47570 coordinates: coordinates[0]
47572 times: $(node, "when").map((elem) => nodeVal(elem))
47575 function fixRing(ring) {
47576 if (ring.length === 0)
47578 const first = ring[0];
47579 const last = ring[ring.length - 1];
47581 for (let i2 = 0; i2 < Math.max(first.length, last.length); i2++) {
47582 if (first[i2] !== last[i2]) {
47588 return ring.concat([ring[0]]);
47599 function getCoordinates(node) {
47600 return nodeVal(get1(node, "coordinates"));
47602 function getGeometry(node) {
47603 const geometries = [];
47604 const coordTimes = [];
47605 for (const t of ["MultiGeometry", "MultiTrack", "gx:MultiTrack"]) {
47606 const elem = get1(node, t);
47608 return getGeometry(elem);
47611 for (const geoType of GEO_TYPES) {
47612 for (const geomNode of $(node, geoType)) {
47615 const coordinates = coord1(getCoordinates(geomNode));
47616 if (coordinates.length >= 2) {
47624 case "LineString": {
47625 const coordinates = coord(getCoordinates(geomNode));
47626 if (coordinates.length >= 2) {
47628 type: "LineString",
47636 for (const linearRing of $(geomNode, "LinearRing")) {
47637 const ring = fixRing(coord(getCoordinates(linearRing)));
47638 if (ring.length >= 4) {
47642 if (coords.length) {
47645 coordinates: coords
47652 const gx = gxCoords(geomNode);
47655 const { times, geometry } = gx;
47656 geometries.push(geometry);
47658 coordTimes.push(times);
47669 function extractExtendedData(node) {
47670 return get3(node, "ExtendedData", (extendedData, properties) => {
47671 for (const data of $(extendedData, "Data")) {
47672 properties[data.getAttribute("name") || ""] = nodeVal(get1(data, "value"));
47674 for (const simpleData of $(extendedData, "SimpleData")) {
47675 properties[simpleData.getAttribute("name") || ""] = nodeVal(simpleData);
47680 function geometryListToGeometry(geometries) {
47681 return geometries.length === 0 ? null : geometries.length === 1 ? geometries[0] : {
47682 type: "GeometryCollection",
47686 function extractTimeSpan(node) {
47687 return get3(node, "TimeSpan", (timeSpan) => {
47690 begin: nodeVal(get1(timeSpan, "begin")),
47691 end: nodeVal(get1(timeSpan, "end"))
47696 function extractTimeStamp(node) {
47697 return get3(node, "TimeStamp", (timeStamp) => {
47698 return { timestamp: nodeVal(get1(timeStamp, "when")) };
47701 function extractCascadedStyle(node, styleMap) {
47702 return val1(node, "styleUrl", (styleUrl) => {
47703 styleUrl = normalizeId(styleUrl);
47704 if (styleMap[styleUrl]) {
47705 return Object.assign({ styleUrl }, styleMap[styleUrl]);
47707 return { styleUrl };
47710 function getMaybeHTMLDescription(node) {
47711 const descriptionNode = get1(node, "description");
47712 for (const c of Array.from(descriptionNode?.childNodes || [])) {
47713 if (c.nodeType === 4) {
47724 function getPlacemark(node, styleMap) {
47725 const { coordTimes, geometries } = getGeometry(node);
47728 geometry: geometryListToGeometry(geometries),
47729 properties: Object.assign(getMulti(node, [
47736 ]), getMaybeHTMLDescription(node), extractCascadedStyle(node, styleMap), extractStyle(node), extractExtendedData(node), extractTimeSpan(node), extractTimeStamp(node), coordTimes.length ? {
47737 coordinateProperties: {
47738 times: coordTimes.length === 1 ? coordTimes[0] : coordTimes
47742 if (feature3.properties?.visibility !== void 0) {
47743 feature3.properties.visibility = feature3.properties.visibility !== "0";
47745 const id2 = node.getAttribute("id");
47746 if (id2 !== null && id2 !== "")
47750 function getStyleId(style) {
47751 let id2 = style.getAttribute("id");
47752 const parentNode = style.parentNode;
47753 if (!id2 && isElement(parentNode) && parentNode.localName === "CascadingStyle") {
47754 id2 = parentNode.getAttribute("kml:id") || parentNode.getAttribute("id");
47756 return normalizeId(id2 || "");
47758 function buildStyleMap(node) {
47759 const styleMap = {};
47760 for (const style of $(node, "Style")) {
47761 styleMap[getStyleId(style)] = extractStyle(style);
47763 for (const map2 of $(node, "StyleMap")) {
47764 const id2 = normalizeId(map2.getAttribute("id") || "");
47765 val1(map2, "styleUrl", (styleUrl) => {
47766 styleUrl = normalizeId(styleUrl);
47767 if (styleMap[styleUrl]) {
47768 styleMap[id2] = styleMap[styleUrl];
47774 function* kmlGen(node) {
47775 const styleMap = buildStyleMap(node);
47776 for (const placemark of $(node, "Placemark")) {
47777 const feature3 = getPlacemark(placemark, styleMap);
47782 function kml(node) {
47784 type: "FeatureCollection",
47785 features: Array.from(kmlGen(node))
47789 // modules/svg/data.js
47790 var _initialized = false;
47791 var _enabled = false;
47793 function svgData(projection2, context, dispatch10) {
47794 var throttledRedraw = throttle_default(function() {
47795 dispatch10.call("change");
47797 var _showLabels = true;
47798 var detected = utilDetect();
47799 var layer = select_default2(null);
47809 function over(d3_event) {
47810 d3_event.stopPropagation();
47811 d3_event.preventDefault();
47812 d3_event.dataTransfer.dropEffect = "copy";
47814 context.container().attr("dropzone", "copy").on("drop.svgData", function(d3_event) {
47815 d3_event.stopPropagation();
47816 d3_event.preventDefault();
47817 if (!detected.filedrop)
47819 drawData.fileList(d3_event.dataTransfer.files);
47820 }).on("dragenter.svgData", over).on("dragexit.svgData", over).on("dragover.svgData", over);
47821 _initialized = true;
47823 function getService() {
47824 if (services.vectorTile && !_vtService) {
47825 _vtService = services.vectorTile;
47826 _vtService.event.on("loadedData", throttledRedraw);
47827 } else if (!services.vectorTile && _vtService) {
47832 function showLayer() {
47834 layer.style("opacity", 0).transition().duration(250).style("opacity", 1).on("end", function() {
47835 dispatch10.call("change");
47838 function hideLayer() {
47839 throttledRedraw.cancel();
47840 layer.transition().duration(250).style("opacity", 0).on("end", layerOff);
47842 function layerOn() {
47843 layer.style("display", "block");
47845 function layerOff() {
47846 layer.selectAll(".viewfield-group").remove();
47847 layer.style("display", "none");
47849 function ensureIDs(gj) {
47852 if (gj.type === "FeatureCollection") {
47853 for (var i2 = 0; i2 < gj.features.length; i2++) {
47854 ensureFeatureID(gj.features[i2]);
47857 ensureFeatureID(gj);
47861 function ensureFeatureID(feature3) {
47864 feature3.__featurehash__ = utilHashcode((0, import_fast_json_stable_stringify.default)(feature3));
47867 function getFeatures(gj) {
47870 if (gj.type === "FeatureCollection") {
47871 return gj.features;
47876 function featureKey(d) {
47877 return d.__featurehash__;
47879 function isPolygon(d) {
47880 return d.geometry.type === "Polygon" || d.geometry.type === "MultiPolygon";
47882 function clipPathID(d) {
47883 return "ideditor-data-" + d.__featurehash__ + "-clippath";
47885 function featureClasses(d) {
47887 "data" + d.__featurehash__,
47889 isPolygon(d) ? "area" : "",
47890 d.__layerID__ || ""
47891 ].filter(Boolean).join(" ");
47893 function drawData(selection2) {
47894 var vtService = getService();
47895 var getPath = svgPath(projection2).geojson;
47896 var getAreaPath = svgPath(projection2, null, true).geojson;
47897 var hasData = drawData.hasData();
47898 layer = selection2.selectAll(".layer-mapdata").data(_enabled && hasData ? [0] : []);
47899 layer.exit().remove();
47900 layer = layer.enter().append("g").attr("class", "layer-mapdata").merge(layer);
47901 var surface = context.surface();
47902 if (!surface || surface.empty())
47904 var geoData, polygonData;
47905 if (_template && vtService) {
47906 var sourceID = _template;
47907 vtService.loadTiles(sourceID, _template, projection2);
47908 geoData = vtService.data(sourceID, projection2);
47910 geoData = getFeatures(_geojson);
47912 geoData = geoData.filter(getPath);
47913 polygonData = geoData.filter(isPolygon);
47914 var clipPaths = surface.selectAll("defs").selectAll(".clipPath-data").data(polygonData, featureKey);
47915 clipPaths.exit().remove();
47916 var clipPathsEnter = clipPaths.enter().append("clipPath").attr("class", "clipPath-data").attr("id", clipPathID);
47917 clipPathsEnter.append("path");
47918 clipPaths.merge(clipPathsEnter).selectAll("path").attr("d", getAreaPath);
47919 var datagroups = layer.selectAll("g.datagroup").data(["fill", "shadow", "stroke"]);
47920 datagroups = datagroups.enter().append("g").attr("class", function(d) {
47921 return "datagroup datagroup-" + d;
47922 }).merge(datagroups);
47928 var paths = datagroups.selectAll("path").data(function(layer2) {
47929 return pathData[layer2];
47931 paths.exit().remove();
47932 paths = paths.enter().append("path").attr("class", function(d) {
47933 var datagroup = this.parentNode.__data__;
47934 return "pathdata " + datagroup + " " + featureClasses(d);
47935 }).attr("clip-path", function(d) {
47936 var datagroup = this.parentNode.__data__;
47937 return datagroup === "fill" ? "url(#" + clipPathID(d) + ")" : null;
47938 }).merge(paths).attr("d", function(d) {
47939 var datagroup = this.parentNode.__data__;
47940 return datagroup === "fill" ? getAreaPath(d) : getPath(d);
47942 layer.call(drawLabels, "label-halo", geoData).call(drawLabels, "label", geoData);
47943 function drawLabels(selection3, textClass, data) {
47944 var labelPath = path_default(projection2);
47945 var labelData = data.filter(function(d) {
47946 return _showLabels && d.properties && (d.properties.desc || d.properties.name);
47948 var labels = selection3.selectAll("text." + textClass).data(labelData, featureKey);
47949 labels.exit().remove();
47950 labels = labels.enter().append("text").attr("class", function(d) {
47951 return textClass + " " + featureClasses(d);
47952 }).merge(labels).text(function(d) {
47953 return d.properties.desc || d.properties.name;
47954 }).attr("x", function(d) {
47955 var centroid = labelPath.centroid(d);
47956 return centroid[0] + 11;
47957 }).attr("y", function(d) {
47958 var centroid = labelPath.centroid(d);
47959 return centroid[1];
47963 function getExtension(fileName) {
47966 var re2 = /\.(gpx|kml|(geo)?json)$/i;
47967 var match = fileName.toLowerCase().match(re2);
47968 return match && match.length && match[0];
47970 function xmlToDom(textdata) {
47971 return new DOMParser().parseFromString(textdata, "text/xml");
47973 function stringifyGeojsonProperties(feature3) {
47974 const properties = feature3.properties;
47975 for (const key in properties) {
47976 const property = properties[key];
47977 if (typeof property === "number" || typeof property === "boolean" || Array.isArray(property)) {
47978 properties[key] = property.toString();
47979 } else if (property === null) {
47980 properties[key] = "null";
47981 } else if (typeof property === "object") {
47982 properties[key] = JSON.stringify(property);
47986 drawData.setFile = function(extension, data) {
47992 switch (extension) {
47994 gj = gpx(xmlToDom(data));
47997 gj = kml(xmlToDom(data));
48001 gj = JSON.parse(data);
48002 if (gj.type === "FeatureCollection") {
48003 gj.features.forEach(stringifyGeojsonProperties);
48004 } else if (gj.type === "Feature") {
48005 stringifyGeojsonProperties(gj);
48010 if (Object.keys(gj).length) {
48011 _geojson = ensureIDs(gj);
48012 _src = extension + " data file";
48015 dispatch10.call("change");
48018 drawData.showLabels = function(val) {
48019 if (!arguments.length)
48020 return _showLabels;
48024 drawData.enabled = function(val) {
48025 if (!arguments.length)
48033 dispatch10.call("change");
48036 drawData.hasData = function() {
48037 var gj = _geojson || {};
48038 return !!(_template || Object.keys(gj).length);
48040 drawData.template = function(val, src) {
48041 if (!arguments.length)
48043 var osm = context.connection();
48045 var blocklists = osm.imageryBlocklists();
48049 for (var i2 = 0; i2 < blocklists.length; i2++) {
48050 regex = blocklists[i2];
48051 fail = regex.test(val);
48057 regex = /.*\.google(apis)?\..*\/(vt|kh)[\?\/].*([xyz]=.*){3}.*/;
48058 fail = regex.test(val);
48064 _src = src || "vectortile:" + val.split(/[?#]/)[0];
48065 dispatch10.call("change");
48068 drawData.geojson = function(gj, src) {
48069 if (!arguments.length)
48076 if (Object.keys(gj).length) {
48077 _geojson = ensureIDs(gj);
48078 _src = src || "unknown.geojson";
48080 dispatch10.call("change");
48083 drawData.fileList = function(fileList) {
48084 if (!arguments.length)
48087 _fileList = fileList;
48090 if (!fileList || !fileList.length)
48092 var f2 = fileList[0];
48093 var extension = getExtension(f2.name);
48094 var reader = new FileReader();
48095 reader.onload = function() {
48096 return function(e) {
48097 drawData.setFile(extension, e.target.result);
48100 reader.readAsText(f2);
48103 drawData.url = function(url, defaultExtension) {
48108 var testUrl = url.split(/[?#]/)[0];
48109 var extension = getExtension(testUrl) || defaultExtension;
48112 text_default3(url).then(function(data) {
48113 drawData.setFile(extension, data);
48114 }).catch(function() {
48117 drawData.template(url);
48121 drawData.getSrc = function() {
48124 drawData.fitZoom = function() {
48125 var features = getFeatures(_geojson);
48126 if (!features.length)
48128 var map2 = context.map();
48129 var viewport = map2.trimmedExtent().polygon();
48130 var coords = features.reduce(function(coords2, feature3) {
48131 var geom = feature3.geometry;
48134 var c = geom.coordinates;
48135 switch (geom.type) {
48141 case "MultiPolygon":
48142 c = utilArrayFlatten(c);
48144 case "MultiLineString":
48145 c = utilArrayFlatten(c);
48148 return utilArrayUnion(coords2, c);
48150 if (!geoPolygonIntersectsPolygon(viewport, coords, true)) {
48151 var extent = geoExtent(bounds_default({ type: "LineString", coordinates: coords }));
48152 map2.centerZoom(extent.center(), map2.trimmedExtentZoom(extent));
48160 // modules/svg/debug.js
48161 function svgDebug(projection2, context) {
48162 function drawDebug(selection2) {
48163 const showTile = context.getDebug("tile");
48164 const showCollision = context.getDebug("collision");
48165 const showImagery = context.getDebug("imagery");
48166 const showTouchTargets = context.getDebug("target");
48167 const showDownloaded = context.getDebug("downloaded");
48168 let debugData = [];
48170 debugData.push({ class: "red", label: "tile" });
48172 if (showCollision) {
48173 debugData.push({ class: "yellow", label: "collision" });
48176 debugData.push({ class: "orange", label: "imagery" });
48178 if (showTouchTargets) {
48179 debugData.push({ class: "pink", label: "touchTargets" });
48181 if (showDownloaded) {
48182 debugData.push({ class: "purple", label: "downloaded" });
48184 let legend = context.container().select(".main-content").selectAll(".debug-legend").data(debugData.length ? [0] : []);
48185 legend.exit().remove();
48186 legend = legend.enter().append("div").attr("class", "fillD debug-legend").merge(legend);
48187 let legendItems = legend.selectAll(".debug-legend-item").data(debugData, (d) => d.label);
48188 legendItems.exit().remove();
48189 legendItems.enter().append("span").attr("class", (d) => `debug-legend-item ${d.class}`).text((d) => d.label);
48190 let layer = selection2.selectAll(".layer-debug").data(showImagery || showDownloaded ? [0] : []);
48191 layer.exit().remove();
48192 layer = layer.enter().append("g").attr("class", "layer-debug").merge(layer);
48193 const extent = context.map().extent();
48194 _mainFileFetcher.get("imagery").then((d) => {
48195 const hits = showImagery && d.query.bbox(extent.rectangle(), true) || [];
48196 const features = hits.map((d2) => d2.features[d2.id]);
48197 let imagery = layer.selectAll("path.debug-imagery").data(features);
48198 imagery.exit().remove();
48199 imagery.enter().append("path").attr("class", "debug-imagery debug orange");
48202 const osm = context.connection();
48203 let dataDownloaded = [];
48204 if (osm && showDownloaded) {
48205 const rtree = osm.caches("get").tile.rtree;
48206 dataDownloaded = rtree.all().map((bbox2) => {
48209 properties: { id: bbox2.id },
48213 [bbox2.minX, bbox2.minY],
48214 [bbox2.minX, bbox2.maxY],
48215 [bbox2.maxX, bbox2.maxY],
48216 [bbox2.maxX, bbox2.minY],
48217 [bbox2.minX, bbox2.minY]
48223 let downloaded = layer.selectAll("path.debug-downloaded").data(showDownloaded ? dataDownloaded : []);
48224 downloaded.exit().remove();
48225 downloaded.enter().append("path").attr("class", "debug-downloaded debug purple");
48226 layer.selectAll("path").attr("d", svgPath(projection2).geojson);
48228 drawDebug.enabled = function() {
48229 if (!arguments.length) {
48230 return context.getDebug("tile") || context.getDebug("collision") || context.getDebug("imagery") || context.getDebug("target") || context.getDebug("downloaded");
48238 // modules/svg/defs.js
48239 function svgDefs(context) {
48240 var _defsSelection = select_default2(null);
48241 var _spritesheetIds = [
48249 function drawDefs(selection2) {
48250 _defsSelection = selection2.append("defs");
48251 _defsSelection.append("marker").attr("id", "ideditor-oneway-marker").attr("viewBox", "0 0 10 5").attr("refX", 2.5).attr("refY", 2.5).attr("markerWidth", 2).attr("markerHeight", 2).attr("markerUnits", "strokeWidth").attr("orient", "auto").append("path").attr("class", "oneway-marker-path").attr("d", "M 5,3 L 0,3 L 0,2 L 5,2 L 5,0 L 10,2.5 L 5,5 z").attr("stroke", "none").attr("fill", "#000").attr("opacity", "0.75");
48252 function addSidedMarker(name, color2, offset) {
48253 _defsSelection.append("marker").attr("id", "ideditor-sided-marker-" + name).attr("viewBox", "0 0 2 2").attr("refX", 1).attr("refY", -offset).attr("markerWidth", 1.5).attr("markerHeight", 1.5).attr("markerUnits", "strokeWidth").attr("orient", "auto").append("path").attr("class", "sided-marker-path sided-marker-" + name + "-path").attr("d", "M 0,0 L 1,1 L 2,0 z").attr("stroke", "none").attr("fill", color2);
48255 addSidedMarker("natural", "rgb(170, 170, 170)", 0);
48256 addSidedMarker("coastline", "#77dede", 1);
48257 addSidedMarker("waterway", "#77dede", 1);
48258 addSidedMarker("barrier", "#ddd", 1);
48259 addSidedMarker("man_made", "#fff", 0);
48260 _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");
48261 _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");
48262 var patterns2 = _defsSelection.selectAll("pattern").data([
48263 // pattern name, pattern image name
48265 ["construction", "construction"],
48266 ["cemetery", "cemetery"],
48267 ["cemetery_christian", "cemetery_christian"],
48268 ["cemetery_buddhist", "cemetery_buddhist"],
48269 ["cemetery_muslim", "cemetery_muslim"],
48270 ["cemetery_jewish", "cemetery_jewish"],
48271 ["farmland", "farmland"],
48272 ["farmyard", "farmyard"],
48273 ["forest", "forest"],
48274 ["forest_broadleaved", "forest_broadleaved"],
48275 ["forest_needleleaved", "forest_needleleaved"],
48276 ["forest_leafless", "forest_leafless"],
48277 ["golf_green", "grass"],
48278 ["grass", "grass"],
48279 ["landfill", "landfill"],
48280 ["meadow", "grass"],
48281 ["orchard", "orchard"],
48283 ["quarry", "quarry"],
48284 ["scrub", "bushes"],
48285 ["vineyard", "vineyard"],
48286 ["water_standing", "lines"],
48287 ["waves", "waves"],
48288 ["wetland", "wetland"],
48289 ["wetland_marsh", "wetland_marsh"],
48290 ["wetland_swamp", "wetland_swamp"],
48291 ["wetland_bog", "wetland_bog"],
48292 ["wetland_reedbed", "wetland_reedbed"]
48293 ]).enter().append("pattern").attr("id", function(d) {
48294 return "ideditor-pattern-" + d[0];
48295 }).attr("width", 32).attr("height", 32).attr("patternUnits", "userSpaceOnUse");
48296 patterns2.append("rect").attr("x", 0).attr("y", 0).attr("width", 32).attr("height", 32).attr("class", function(d) {
48297 return "pattern-color-" + d[0];
48299 patterns2.append("image").attr("x", 0).attr("y", 0).attr("width", 32).attr("height", 32).attr("xlink:href", function(d) {
48300 return context.imagePath("pattern/" + d[1] + ".png");
48302 _defsSelection.selectAll("clipPath").data([12, 18, 20, 32, 45]).enter().append("clipPath").attr("id", function(d) {
48303 return "ideditor-clip-square-" + d;
48304 }).append("rect").attr("x", 0).attr("y", 0).attr("width", function(d) {
48306 }).attr("height", function(d) {
48309 addSprites(_spritesheetIds, true);
48311 function addSprites(ids, overrideColors) {
48312 _spritesheetIds = utilArrayUniq(_spritesheetIds.concat(ids));
48313 var spritesheets = _defsSelection.selectAll(".spritesheet").data(_spritesheetIds);
48314 spritesheets.enter().append("g").attr("class", function(d) {
48315 return "spritesheet spritesheet-" + d;
48316 }).each(function(d) {
48317 var url = context.imagePath(d + ".svg");
48318 var node = select_default2(this).node();
48319 svg(url).then(function(svg2) {
48321 select_default2(svg2.documentElement).attr("id", "ideditor-" + d).node()
48323 if (overrideColors && d !== "iD-sprite") {
48324 select_default2(node).selectAll("path").attr("fill", "currentColor");
48326 }).catch(function() {
48329 spritesheets.exit().remove();
48331 drawDefs.addSprites = addSprites;
48335 // modules/svg/keepRight.js
48336 var _layerEnabled = false;
48338 function svgKeepRight(projection2, context, dispatch10) {
48339 const throttledRedraw = throttle_default(() => dispatch10.call("change"), 1e3);
48340 const minZoom3 = 12;
48341 let touchLayer = select_default2(null);
48342 let drawLayer = select_default2(null);
48343 let layerVisible = false;
48344 function markerPath(selection2, klass) {
48345 selection2.attr("class", klass).attr("transform", "translate(-4, -24)").attr("d", "M11.6,6.2H7.1l1.4-5.1C8.6,0.6,8.1,0,7.5,0H2.2C1.7,0,1.3,0.3,1.3,0.8L0,10.2c-0.1,0.6,0.4,1.1,0.9,1.1h4.6l-1.8,7.6C3.6,19.4,4.1,20,4.7,20c0.3,0,0.6-0.2,0.8-0.5l6.9-11.9C12.7,7,12.3,6.2,11.6,6.2z");
48347 function getService() {
48348 if (services.keepRight && !_qaService) {
48349 _qaService = services.keepRight;
48350 _qaService.on("loaded", throttledRedraw);
48351 } else if (!services.keepRight && _qaService) {
48356 function editOn() {
48357 if (!layerVisible) {
48358 layerVisible = true;
48359 drawLayer.style("display", "block");
48362 function editOff() {
48363 if (layerVisible) {
48364 layerVisible = false;
48365 drawLayer.style("display", "none");
48366 drawLayer.selectAll(".qaItem.keepRight").remove();
48367 touchLayer.selectAll(".qaItem.keepRight").remove();
48370 function layerOn() {
48372 drawLayer.style("opacity", 0).transition().duration(250).style("opacity", 1).on("end interrupt", () => dispatch10.call("change"));
48374 function layerOff() {
48375 throttledRedraw.cancel();
48376 drawLayer.interrupt();
48377 touchLayer.selectAll(".qaItem.keepRight").remove();
48378 drawLayer.transition().duration(250).style("opacity", 0).on("end interrupt", () => {
48380 dispatch10.call("change");
48383 function updateMarkers() {
48384 if (!layerVisible || !_layerEnabled)
48386 const service = getService();
48387 const selectedID = context.selectedErrorID();
48388 const data = service ? service.getItems(projection2) : [];
48389 const getTransform = svgPointTransform(projection2);
48390 const markers = drawLayer.selectAll(".qaItem.keepRight").data(data, (d) => d.id);
48391 markers.exit().remove();
48392 const markersEnter = markers.enter().append("g").attr("class", (d) => `qaItem ${d.service} itemId-${d.id} itemType-${d.parentIssueType}`);
48393 markersEnter.append("ellipse").attr("cx", 0.5).attr("cy", 1).attr("rx", 6.5).attr("ry", 3).attr("class", "stroke");
48394 markersEnter.append("path").call(markerPath, "shadow");
48395 markersEnter.append("use").attr("class", "qaItem-fill").attr("width", "20px").attr("height", "20px").attr("x", "-8px").attr("y", "-22px").attr("xlink:href", "#iD-icon-bolt");
48396 markers.merge(markersEnter).sort(sortY).classed("selected", (d) => d.id === selectedID).attr("transform", getTransform);
48397 if (touchLayer.empty())
48399 const fillClass = context.getDebug("target") ? "pink " : "nocolor ";
48400 const targets = touchLayer.selectAll(".qaItem.keepRight").data(data, (d) => d.id);
48401 targets.exit().remove();
48402 targets.enter().append("rect").attr("width", "20px").attr("height", "20px").attr("x", "-8px").attr("y", "-22px").merge(targets).sort(sortY).attr("class", (d) => `qaItem ${d.service} target ${fillClass} itemId-${d.id}`).attr("transform", getTransform);
48403 function sortY(a, b) {
48404 return a.id === selectedID ? 1 : b.id === selectedID ? -1 : a.severity === "error" && b.severity !== "error" ? 1 : b.severity === "error" && a.severity !== "error" ? -1 : b.loc[1] - a.loc[1];
48407 function drawKeepRight(selection2) {
48408 const service = getService();
48409 const surface = context.surface();
48410 if (surface && !surface.empty()) {
48411 touchLayer = surface.selectAll(".data-layer.touch .layer-touch.markers");
48413 drawLayer = selection2.selectAll(".layer-keepRight").data(service ? [0] : []);
48414 drawLayer.exit().remove();
48415 drawLayer = drawLayer.enter().append("g").attr("class", "layer-keepRight").style("display", _layerEnabled ? "block" : "none").merge(drawLayer);
48416 if (_layerEnabled) {
48417 if (service && ~~context.map().zoom() >= minZoom3) {
48419 service.loadIssues(projection2);
48426 drawKeepRight.enabled = function(val) {
48427 if (!arguments.length)
48428 return _layerEnabled;
48429 _layerEnabled = val;
48430 if (_layerEnabled) {
48434 if (context.selectedErrorID()) {
48435 context.enter(modeBrowse(context));
48438 dispatch10.call("change");
48441 drawKeepRight.supported = () => !!getService();
48442 return drawKeepRight;
48445 // modules/svg/geolocate.js
48446 function svgGeolocate(projection2) {
48447 var layer = select_default2(null);
48450 if (svgGeolocate.initialized)
48452 svgGeolocate.enabled = false;
48453 svgGeolocate.initialized = true;
48455 function showLayer() {
48456 layer.style("display", "block");
48458 function hideLayer() {
48459 layer.transition().duration(250).style("opacity", 0);
48461 function layerOn() {
48462 layer.style("opacity", 0).transition().duration(250).style("opacity", 1);
48464 function layerOff() {
48465 layer.style("display", "none");
48467 function transform2(d) {
48468 return svgPointTransform(projection2)(d);
48470 function accuracy(accuracy2, loc) {
48471 var degreesRadius = geoMetersToLat(accuracy2), tangentLoc = [loc[0], loc[1] + degreesRadius], projectedTangent = projection2(tangentLoc), projectedLoc = projection2([loc[0], loc[1]]);
48472 return Math.round(projectedLoc[1] - projectedTangent[1]).toString();
48474 function update() {
48475 var geolocation = { loc: [_position.coords.longitude, _position.coords.latitude] };
48476 var groups = layer.selectAll(".geolocations").selectAll(".geolocation").data([geolocation]);
48477 groups.exit().remove();
48478 var pointsEnter = groups.enter().append("g").attr("class", "geolocation");
48479 pointsEnter.append("circle").attr("class", "geolocate-radius").attr("dx", "0").attr("dy", "0").attr("fill", "rgb(15,128,225)").attr("fill-opacity", "0.3").attr("r", "0");
48480 pointsEnter.append("circle").attr("dx", "0").attr("dy", "0").attr("fill", "rgb(15,128,225)").attr("stroke", "white").attr("stroke-width", "1.5").attr("r", "6");
48481 groups.merge(pointsEnter).attr("transform", transform2);
48482 layer.select(".geolocate-radius").attr("r", accuracy(_position.coords.accuracy, geolocation.loc));
48484 function drawLocation(selection2) {
48485 var enabled = svgGeolocate.enabled;
48486 layer = selection2.selectAll(".layer-geolocate").data([0]);
48487 layer.exit().remove();
48488 var layerEnter = layer.enter().append("g").attr("class", "layer-geolocate").style("display", enabled ? "block" : "none");
48489 layerEnter.append("g").attr("class", "geolocations");
48490 layer = layerEnter.merge(layer);
48497 drawLocation.enabled = function(position, enabled) {
48498 if (!arguments.length)
48499 return svgGeolocate.enabled;
48500 _position = position;
48501 svgGeolocate.enabled = enabled;
48502 if (svgGeolocate.enabled) {
48511 return drawLocation;
48514 // modules/svg/labels.js
48515 var import_rbush7 = __toESM(require_rbush_min());
48516 function svgLabels(projection2, context) {
48517 var path = path_default(projection2);
48518 var detected = utilDetect();
48519 var baselineHack = detected.ie || detected.browser.toLowerCase() === "edge" || detected.browser.toLowerCase() === "firefox" && detected.version >= 70;
48520 var _rdrawn = new import_rbush7.default();
48521 var _rskipped = new import_rbush7.default();
48522 var _textWidthCache = {};
48523 var _entitybboxes = {};
48525 ["line", "aeroway", "*", 12],
48526 ["line", "highway", "motorway", 12],
48527 ["line", "highway", "trunk", 12],
48528 ["line", "highway", "primary", 12],
48529 ["line", "highway", "secondary", 12],
48530 ["line", "highway", "tertiary", 12],
48531 ["line", "highway", "*", 12],
48532 ["line", "railway", "*", 12],
48533 ["line", "waterway", "*", 12],
48534 ["area", "aeroway", "*", 12],
48535 ["area", "amenity", "*", 12],
48536 ["area", "building", "*", 12],
48537 ["area", "historic", "*", 12],
48538 ["area", "leisure", "*", 12],
48539 ["area", "man_made", "*", 12],
48540 ["area", "natural", "*", 12],
48541 ["area", "shop", "*", 12],
48542 ["area", "tourism", "*", 12],
48543 ["area", "camp_site", "*", 12],
48544 ["point", "aeroway", "*", 10],
48545 ["point", "amenity", "*", 10],
48546 ["point", "building", "*", 10],
48547 ["point", "historic", "*", 10],
48548 ["point", "leisure", "*", 10],
48549 ["point", "man_made", "*", 10],
48550 ["point", "natural", "*", 10],
48551 ["point", "shop", "*", 10],
48552 ["point", "tourism", "*", 10],
48553 ["point", "camp_site", "*", 10],
48554 ["line", "ref", "*", 12],
48555 ["area", "ref", "*", 12],
48556 ["point", "ref", "*", 10],
48557 ["line", "name", "*", 12],
48558 ["area", "name", "*", 12],
48559 ["point", "name", "*", 10]
48561 function shouldSkipIcon(preset) {
48562 var noIcons = ["building", "landuse", "natural"];
48563 return noIcons.some(function(s) {
48564 return preset.id.indexOf(s) >= 0;
48567 function get4(array2, prop) {
48568 return function(d, i2) {
48569 return array2[i2][prop];
48572 function textWidth(text2, size, elem) {
48573 var c = _textWidthCache[size];
48575 c = _textWidthCache[size] = {};
48579 c[text2] = elem.getComputedTextLength();
48582 var str2 = encodeURIComponent(text2).match(/%[CDEFcdef]/g);
48583 if (str2 === null) {
48584 return size / 3 * 2 * text2.length;
48586 return size / 3 * (2 * text2.length + str2.length);
48590 function drawLinePaths(selection2, entities, filter2, classes, labels) {
48591 var paths = selection2.selectAll("path").filter(filter2).data(entities, osmEntity.key);
48592 paths.exit().remove();
48593 paths.enter().append("path").style("stroke-width", get4(labels, "font-size")).attr("id", function(d) {
48594 return "ideditor-labelpath-" + d.id;
48595 }).attr("class", classes).merge(paths).attr("d", get4(labels, "lineString"));
48597 function drawLineLabels(selection2, entities, filter2, classes, labels) {
48598 var texts = selection2.selectAll("text." + classes).filter(filter2).data(entities, osmEntity.key);
48599 texts.exit().remove();
48600 texts.enter().append("text").attr("class", function(d, i2) {
48601 return classes + " " + labels[i2].classes + " " + d.id;
48602 }).attr("dy", baselineHack ? "0.35em" : null).append("textPath").attr("class", "textpath");
48603 selection2.selectAll("text." + classes).selectAll(".textpath").filter(filter2).data(entities, osmEntity.key).attr("startOffset", "50%").attr("xlink:href", function(d) {
48604 return "#ideditor-labelpath-" + d.id;
48605 }).text(utilDisplayNameForPath);
48607 function drawPointLabels(selection2, entities, filter2, classes, labels) {
48608 var texts = selection2.selectAll("text." + classes).filter(filter2).data(entities, osmEntity.key);
48609 texts.exit().remove();
48610 texts.enter().append("text").attr("class", function(d, i2) {
48611 return classes + " " + labels[i2].classes + " " + d.id;
48612 }).merge(texts).attr("x", get4(labels, "x")).attr("y", get4(labels, "y")).style("text-anchor", get4(labels, "textAnchor")).text(utilDisplayName).each(function(d, i2) {
48613 textWidth(utilDisplayName(d), labels[i2].height, this);
48616 function drawAreaLabels(selection2, entities, filter2, classes, labels) {
48617 entities = entities.filter(hasText);
48618 labels = labels.filter(hasText);
48619 drawPointLabels(selection2, entities, filter2, classes, labels);
48620 function hasText(d, i2) {
48621 return labels[i2].hasOwnProperty("x") && labels[i2].hasOwnProperty("y");
48624 function drawAreaIcons(selection2, entities, filter2, classes, labels) {
48625 var icons = selection2.selectAll("use." + classes).filter(filter2).data(entities, osmEntity.key);
48626 icons.exit().remove();
48627 icons.enter().append("use").attr("class", "icon " + classes).attr("width", "17px").attr("height", "17px").merge(icons).attr("transform", get4(labels, "transform")).attr("xlink:href", function(d) {
48628 var preset = _mainPresetIndex.match(d, context.graph());
48629 var picon = preset && preset.icon;
48630 return picon ? "#" + picon : "";
48633 function drawCollisionBoxes(selection2, rtree, which) {
48634 var classes = "debug " + which + " " + (which === "debug-skipped" ? "orange" : "yellow");
48636 if (context.getDebug("collision")) {
48637 gj = rtree.all().map(function(d) {
48638 return { type: "Polygon", coordinates: [[
48647 var boxes = selection2.selectAll("." + which).data(gj);
48648 boxes.exit().remove();
48649 boxes.enter().append("path").attr("class", classes).merge(boxes).attr("d", path_default());
48651 function drawLabels(selection2, graph, entities, filter2, dimensions, fullRedraw) {
48652 var wireframe = context.surface().classed("fill-wireframe");
48653 var zoom = geoScaleToZoom(projection2.scale());
48654 var labelable = [];
48655 var renderNodeAs = {};
48656 var i2, j2, k, entity, geometry;
48657 for (i2 = 0; i2 < labelStack.length; i2++) {
48658 labelable.push([]);
48663 _entitybboxes = {};
48665 for (i2 = 0; i2 < entities.length; i2++) {
48666 entity = entities[i2];
48667 var toRemove = [].concat(_entitybboxes[entity.id] || []).concat(_entitybboxes[entity.id + "I"] || []);
48668 for (j2 = 0; j2 < toRemove.length; j2++) {
48669 _rdrawn.remove(toRemove[j2]);
48670 _rskipped.remove(toRemove[j2]);
48674 for (i2 = 0; i2 < entities.length; i2++) {
48675 entity = entities[i2];
48676 geometry = entity.geometry(graph);
48677 if (geometry === "point" || geometry === "vertex" && isInterestingVertex(entity)) {
48678 var hasDirections = entity.directions(graph, projection2).length;
48680 if (!wireframe && geometry === "point" && !(zoom >= 18 && hasDirections)) {
48681 renderNodeAs[entity.id] = "point";
48682 markerPadding = 20;
48684 renderNodeAs[entity.id] = "vertex";
48687 var coord2 = projection2(entity.loc);
48688 var nodePadding = 10;
48690 minX: coord2[0] - nodePadding,
48691 minY: coord2[1] - nodePadding - markerPadding,
48692 maxX: coord2[0] + nodePadding,
48693 maxY: coord2[1] + nodePadding
48695 doInsert(bbox2, entity.id + "P");
48697 if (geometry === "vertex") {
48698 geometry = "point";
48700 var preset = geometry === "area" && _mainPresetIndex.match(entity, graph);
48701 var icon2 = preset && !shouldSkipIcon(preset) && preset.icon;
48702 if (!icon2 && !utilDisplayName(entity))
48704 for (k = 0; k < labelStack.length; k++) {
48705 var matchGeom = labelStack[k][0];
48706 var matchKey = labelStack[k][1];
48707 var matchVal = labelStack[k][2];
48708 var hasVal = entity.tags[matchKey];
48709 if (geometry === matchGeom && hasVal && (matchVal === "*" || matchVal === hasVal)) {
48710 labelable[k].push(entity);
48725 for (k = 0; k < labelable.length; k++) {
48726 var fontSize = labelStack[k][3];
48727 for (i2 = 0; i2 < labelable[k].length; i2++) {
48728 entity = labelable[k][i2];
48729 geometry = entity.geometry(graph);
48730 var getName = geometry === "line" ? utilDisplayNameForPath : utilDisplayName;
48731 var name = getName(entity);
48732 var width = name && textWidth(name, fontSize);
48734 if (geometry === "point" || geometry === "vertex") {
48737 var renderAs = renderNodeAs[entity.id];
48738 if (renderAs === "vertex" && zoom < 17)
48740 p = getPointLabel(entity, width, fontSize, renderAs);
48741 } else if (geometry === "line") {
48742 p = getLineLabel(entity, width, fontSize);
48743 } else if (geometry === "area") {
48744 p = getAreaLabel(entity, width, fontSize);
48747 if (geometry === "vertex") {
48748 geometry = "point";
48750 p.classes = geometry + " tag-" + labelStack[k][1];
48751 positions[geometry].push(p);
48752 labelled[geometry].push(entity);
48756 function isInterestingVertex(entity2) {
48757 var selectedIDs = context.selectedIDs();
48758 return entity2.hasInterestingTags() || entity2.isEndpoint(graph) || entity2.isConnected(graph) || selectedIDs.indexOf(entity2.id) !== -1 || graph.parentWays(entity2).some(function(parent) {
48759 return selectedIDs.indexOf(parent.id) !== -1;
48762 function getPointLabel(entity2, width2, height, geometry2) {
48763 var y = geometry2 === "point" ? -12 : 0;
48764 var pointOffsets = {
48765 ltr: [15, y, "start"],
48766 rtl: [-15, y, "end"]
48768 var textDirection = _mainLocalizer.textDirection();
48769 var coord3 = projection2(entity2.loc);
48770 var textPadding = 2;
48771 var offset = pointOffsets[textDirection];
48775 x: coord3[0] + offset[0],
48776 y: coord3[1] + offset[1],
48777 textAnchor: offset[2]
48780 if (textDirection === "rtl") {
48782 minX: p2.x - width2 - textPadding,
48783 minY: p2.y - height / 2 - textPadding,
48784 maxX: p2.x + textPadding,
48785 maxY: p2.y + height / 2 + textPadding
48789 minX: p2.x - textPadding,
48790 minY: p2.y - height / 2 - textPadding,
48791 maxX: p2.x + width2 + textPadding,
48792 maxY: p2.y + height / 2 + textPadding
48795 if (tryInsert([bbox3], entity2.id, true)) {
48799 function getLineLabel(entity2, width2, height) {
48800 var viewport = geoExtent(context.projection.clipExtent()).polygon();
48801 var points = graph.childNodes(entity2).map(function(node) {
48802 return projection2(node.loc);
48804 var length = geoPathLength(points);
48805 if (length < width2 + 20)
48807 var lineOffsets = [
48829 for (var i3 = 0; i3 < lineOffsets.length; i3++) {
48830 var offset = lineOffsets[i3];
48831 var middle = offset / 100 * length;
48832 var start2 = middle - width2 / 2;
48833 if (start2 < 0 || start2 + width2 > length)
48835 var sub = subpath(points, start2, start2 + width2);
48836 if (!sub || !geoPolygonIntersectsPolygon(viewport, sub, true)) {
48839 var isReverse = reverse(sub);
48841 sub = sub.reverse();
48844 var boxsize = (height + 2) / 2;
48845 for (var j3 = 0; j3 < sub.length - 1; j3++) {
48847 var b = sub[j3 + 1];
48848 var num = Math.max(1, Math.floor(geoVecLength(a, b) / boxsize / 2));
48849 for (var box = 0; box < num; box++) {
48850 var p2 = geoVecInterp(a, b, box / num);
48851 var x05 = p2[0] - boxsize - padding;
48852 var y05 = p2[1] - boxsize - padding;
48853 var x12 = p2[0] + boxsize + padding;
48854 var y12 = p2[1] + boxsize + padding;
48856 minX: Math.min(x05, x12),
48857 minY: Math.min(y05, y12),
48858 maxX: Math.max(x05, x12),
48859 maxY: Math.max(y05, y12)
48863 if (tryInsert(bboxes, entity2.id, false)) {
48865 "font-size": height + 2,
48866 lineString: lineString2(sub),
48867 startOffset: offset + "%"
48871 function reverse(p3) {
48872 var angle2 = Math.atan2(p3[1][1] - p3[0][1], p3[1][0] - p3[0][0]);
48873 return !(p3[0][0] < p3[p3.length - 1][0] && angle2 < Math.PI / 2 && angle2 > -Math.PI / 2);
48875 function lineString2(points2) {
48876 return "M" + points2.join("L");
48878 function subpath(points2, from, to) {
48880 var start3, end, i0, i1;
48881 for (var i4 = 0; i4 < points2.length - 1; i4++) {
48882 var a2 = points2[i4];
48883 var b2 = points2[i4 + 1];
48884 var current = geoVecLength(a2, b2);
48886 if (!start3 && sofar + current >= from) {
48887 portion = (from - sofar) / current;
48889 a2[0] + portion * (b2[0] - a2[0]),
48890 a2[1] + portion * (b2[1] - a2[1])
48894 if (!end && sofar + current >= to) {
48895 portion = (to - sofar) / current;
48897 a2[0] + portion * (b2[0] - a2[0]),
48898 a2[1] + portion * (b2[1] - a2[1])
48904 var result = points2.slice(i0, i1);
48905 result.unshift(start3);
48910 function getAreaLabel(entity2, width2, height) {
48911 var centroid = path.centroid(entity2.asGeoJSON(graph));
48912 var extent = entity2.extent(graph);
48913 var areaWidth = projection2(extent[1])[0] - projection2(extent[0])[0];
48914 if (isNaN(centroid[0]) || areaWidth < 20)
48916 var preset2 = _mainPresetIndex.match(entity2, context.graph());
48917 var picon = preset2 && preset2.icon;
48923 addLabel(iconSize + padding);
48931 function addIcon() {
48932 var iconX = centroid[0] - iconSize / 2;
48933 var iconY = centroid[1] - iconSize / 2;
48937 maxX: iconX + iconSize,
48938 maxY: iconY + iconSize
48940 if (tryInsert([bbox3], entity2.id + "I", true)) {
48941 p2.transform = "translate(" + iconX + "," + iconY + ")";
48946 function addLabel(yOffset) {
48947 if (width2 && areaWidth >= width2 + 20) {
48948 var labelX = centroid[0];
48949 var labelY = centroid[1] + yOffset;
48951 minX: labelX - width2 / 2 - padding,
48952 minY: labelY - height / 2 - padding,
48953 maxX: labelX + width2 / 2 + padding,
48954 maxY: labelY + height / 2 + padding
48956 if (tryInsert([bbox3], entity2.id, true)) {
48959 p2.textAnchor = "middle";
48960 p2.height = height;
48967 function doInsert(bbox3, id2) {
48969 var oldbox = _entitybboxes[id2];
48971 _rdrawn.remove(oldbox);
48973 _entitybboxes[id2] = bbox3;
48974 _rdrawn.insert(bbox3);
48976 function tryInsert(bboxes, id2, saveSkipped) {
48977 var skipped = false;
48978 for (var i3 = 0; i3 < bboxes.length; i3++) {
48979 var bbox3 = bboxes[i3];
48981 if (bbox3.minX < 0 || bbox3.minY < 0 || bbox3.maxX > dimensions[0] || bbox3.maxY > dimensions[1]) {
48985 if (_rdrawn.collides(bbox3)) {
48990 _entitybboxes[id2] = bboxes;
48993 _rskipped.load(bboxes);
48996 _rdrawn.load(bboxes);
49000 var layer = selection2.selectAll(".layer-osm.labels");
49001 layer.selectAll(".labels-group").data(["halo", "label", "debug"]).enter().append("g").attr("class", function(d) {
49002 return "labels-group " + d;
49004 var halo = layer.selectAll(".labels-group.halo");
49005 var label = layer.selectAll(".labels-group.label");
49006 var debug2 = layer.selectAll(".labels-group.debug");
49007 drawPointLabels(label, labelled.point, filter2, "pointlabel", positions.point);
49008 drawPointLabels(halo, labelled.point, filter2, "pointlabel-halo", positions.point);
49009 drawLinePaths(layer, labelled.line, filter2, "", positions.line);
49010 drawLineLabels(label, labelled.line, filter2, "linelabel", positions.line);
49011 drawLineLabels(halo, labelled.line, filter2, "linelabel-halo", positions.line);
49012 drawAreaLabels(label, labelled.area, filter2, "arealabel", positions.area);
49013 drawAreaLabels(halo, labelled.area, filter2, "arealabel-halo", positions.area);
49014 drawAreaIcons(label, labelled.area, filter2, "areaicon", positions.area);
49015 drawAreaIcons(halo, labelled.area, filter2, "areaicon-halo", positions.area);
49016 drawCollisionBoxes(debug2, _rskipped, "debug-skipped");
49017 drawCollisionBoxes(debug2, _rdrawn, "debug-drawn");
49018 layer.call(filterLabels);
49020 function filterLabels(selection2) {
49021 var drawLayer = selection2.selectAll(".layer-osm.labels");
49022 var layers = drawLayer.selectAll(".labels-group.halo, .labels-group.label");
49023 layers.selectAll(".nolabel").classed("nolabel", false);
49024 var mouse = context.map().mouse();
49025 var graph = context.graph();
49026 var selectedIDs = context.selectedIDs();
49031 bbox2 = { minX: mouse[0] - pad2, minY: mouse[1] - pad2, maxX: mouse[0] + pad2, maxY: mouse[1] + pad2 };
49032 var nearMouse = _rdrawn.search(bbox2).map(function(entity2) {
49035 ids.push.apply(ids, nearMouse);
49037 for (var i2 = 0; i2 < selectedIDs.length; i2++) {
49038 var entity = graph.hasEntity(selectedIDs[i2]);
49039 if (entity && entity.type === "node") {
49040 ids.push(selectedIDs[i2]);
49043 layers.selectAll(utilEntitySelector(ids)).classed("nolabel", true);
49044 var debug2 = selection2.selectAll(".labels-group.debug");
49046 if (context.getDebug("collision")) {
49050 [bbox2.minX, bbox2.minY],
49051 [bbox2.maxX, bbox2.minY],
49052 [bbox2.maxX, bbox2.maxY],
49053 [bbox2.minX, bbox2.maxY],
49054 [bbox2.minX, bbox2.minY]
49058 var box = debug2.selectAll(".debug-mouse").data(gj);
49059 box.exit().remove();
49060 box.enter().append("path").attr("class", "debug debug-mouse yellow").merge(box).attr("d", path_default());
49062 var throttleFilterLabels = throttle_default(filterLabels, 100);
49063 drawLabels.observe = function(selection2) {
49064 var listener = function() {
49065 throttleFilterLabels(selection2);
49067 selection2.on("mousemove.hidelabels", listener);
49068 context.on("enter.hidelabels", listener);
49070 drawLabels.off = function(selection2) {
49071 throttleFilterLabels.cancel();
49072 selection2.on("mousemove.hidelabels", null);
49073 context.on("enter.hidelabels", null);
49078 // modules/svg/improveOSM.js
49079 var _layerEnabled2 = false;
49081 function svgImproveOSM(projection2, context, dispatch10) {
49082 const throttledRedraw = throttle_default(() => dispatch10.call("change"), 1e3);
49083 const minZoom3 = 12;
49084 let touchLayer = select_default2(null);
49085 let drawLayer = select_default2(null);
49086 let layerVisible = false;
49087 function markerPath(selection2, klass) {
49088 selection2.attr("class", klass).attr("transform", "translate(-10, -28)").attr("points", "16,3 4,3 1,6 1,17 4,20 7,20 10,27 13,20 16,20 19,17.033 19,6");
49090 function getService() {
49091 if (services.improveOSM && !_qaService2) {
49092 _qaService2 = services.improveOSM;
49093 _qaService2.on("loaded", throttledRedraw);
49094 } else if (!services.improveOSM && _qaService2) {
49095 _qaService2 = null;
49097 return _qaService2;
49099 function editOn() {
49100 if (!layerVisible) {
49101 layerVisible = true;
49102 drawLayer.style("display", "block");
49105 function editOff() {
49106 if (layerVisible) {
49107 layerVisible = false;
49108 drawLayer.style("display", "none");
49109 drawLayer.selectAll(".qaItem.improveOSM").remove();
49110 touchLayer.selectAll(".qaItem.improveOSM").remove();
49113 function layerOn() {
49115 drawLayer.style("opacity", 0).transition().duration(250).style("opacity", 1).on("end interrupt", () => dispatch10.call("change"));
49117 function layerOff() {
49118 throttledRedraw.cancel();
49119 drawLayer.interrupt();
49120 touchLayer.selectAll(".qaItem.improveOSM").remove();
49121 drawLayer.transition().duration(250).style("opacity", 0).on("end interrupt", () => {
49123 dispatch10.call("change");
49126 function updateMarkers() {
49127 if (!layerVisible || !_layerEnabled2)
49129 const service = getService();
49130 const selectedID = context.selectedErrorID();
49131 const data = service ? service.getItems(projection2) : [];
49132 const getTransform = svgPointTransform(projection2);
49133 const markers = drawLayer.selectAll(".qaItem.improveOSM").data(data, (d) => d.id);
49134 markers.exit().remove();
49135 const markersEnter = markers.enter().append("g").attr("class", (d) => `qaItem ${d.service} itemId-${d.id} itemType-${d.itemType}`);
49136 markersEnter.append("polygon").call(markerPath, "shadow");
49137 markersEnter.append("ellipse").attr("cx", 0).attr("cy", 0).attr("rx", 4.5).attr("ry", 2).attr("class", "stroke");
49138 markersEnter.append("polygon").attr("fill", "currentColor").call(markerPath, "qaItem-fill");
49139 markersEnter.append("use").attr("class", "icon-annotation").attr("transform", "translate(-6, -22)").attr("width", "12px").attr("height", "12px").attr("xlink:href", (d) => d.icon ? "#" + d.icon : "");
49140 markers.merge(markersEnter).sort(sortY).classed("selected", (d) => d.id === selectedID).attr("transform", getTransform);
49141 if (touchLayer.empty())
49143 const fillClass = context.getDebug("target") ? "pink " : "nocolor ";
49144 const targets = touchLayer.selectAll(".qaItem.improveOSM").data(data, (d) => d.id);
49145 targets.exit().remove();
49146 targets.enter().append("rect").attr("width", "20px").attr("height", "30px").attr("x", "-10px").attr("y", "-28px").merge(targets).sort(sortY).attr("class", (d) => `qaItem ${d.service} target ${fillClass} itemId-${d.id}`).attr("transform", getTransform);
49147 function sortY(a, b) {
49148 return a.id === selectedID ? 1 : b.id === selectedID ? -1 : b.loc[1] - a.loc[1];
49151 function drawImproveOSM(selection2) {
49152 const service = getService();
49153 const surface = context.surface();
49154 if (surface && !surface.empty()) {
49155 touchLayer = surface.selectAll(".data-layer.touch .layer-touch.markers");
49157 drawLayer = selection2.selectAll(".layer-improveOSM").data(service ? [0] : []);
49158 drawLayer.exit().remove();
49159 drawLayer = drawLayer.enter().append("g").attr("class", "layer-improveOSM").style("display", _layerEnabled2 ? "block" : "none").merge(drawLayer);
49160 if (_layerEnabled2) {
49161 if (service && ~~context.map().zoom() >= minZoom3) {
49163 service.loadIssues(projection2);
49170 drawImproveOSM.enabled = function(val) {
49171 if (!arguments.length)
49172 return _layerEnabled2;
49173 _layerEnabled2 = val;
49174 if (_layerEnabled2) {
49178 if (context.selectedErrorID()) {
49179 context.enter(modeBrowse(context));
49182 dispatch10.call("change");
49185 drawImproveOSM.supported = () => !!getService();
49186 return drawImproveOSM;
49189 // modules/svg/osmose.js
49190 var _layerEnabled3 = false;
49192 function svgOsmose(projection2, context, dispatch10) {
49193 const throttledRedraw = throttle_default(() => dispatch10.call("change"), 1e3);
49194 const minZoom3 = 12;
49195 let touchLayer = select_default2(null);
49196 let drawLayer = select_default2(null);
49197 let layerVisible = false;
49198 function markerPath(selection2, klass) {
49199 selection2.attr("class", klass).attr("transform", "translate(-10, -28)").attr("points", "16,3 4,3 1,6 1,17 4,20 7,20 10,27 13,20 16,20 19,17.033 19,6");
49201 function getService() {
49202 if (services.osmose && !_qaService3) {
49203 _qaService3 = services.osmose;
49204 _qaService3.on("loaded", throttledRedraw);
49205 } else if (!services.osmose && _qaService3) {
49206 _qaService3 = null;
49208 return _qaService3;
49210 function editOn() {
49211 if (!layerVisible) {
49212 layerVisible = true;
49213 drawLayer.style("display", "block");
49216 function editOff() {
49217 if (layerVisible) {
49218 layerVisible = false;
49219 drawLayer.style("display", "none");
49220 drawLayer.selectAll(".qaItem.osmose").remove();
49221 touchLayer.selectAll(".qaItem.osmose").remove();
49224 function layerOn() {
49226 drawLayer.style("opacity", 0).transition().duration(250).style("opacity", 1).on("end interrupt", () => dispatch10.call("change"));
49228 function layerOff() {
49229 throttledRedraw.cancel();
49230 drawLayer.interrupt();
49231 touchLayer.selectAll(".qaItem.osmose").remove();
49232 drawLayer.transition().duration(250).style("opacity", 0).on("end interrupt", () => {
49234 dispatch10.call("change");
49237 function updateMarkers() {
49238 if (!layerVisible || !_layerEnabled3)
49240 const service = getService();
49241 const selectedID = context.selectedErrorID();
49242 const data = service ? service.getItems(projection2) : [];
49243 const getTransform = svgPointTransform(projection2);
49244 const markers = drawLayer.selectAll(".qaItem.osmose").data(data, (d) => d.id);
49245 markers.exit().remove();
49246 const markersEnter = markers.enter().append("g").attr("class", (d) => `qaItem ${d.service} itemId-${d.id} itemType-${d.itemType}`);
49247 markersEnter.append("polygon").call(markerPath, "shadow");
49248 markersEnter.append("ellipse").attr("cx", 0).attr("cy", 0).attr("rx", 4.5).attr("ry", 2).attr("class", "stroke");
49249 markersEnter.append("polygon").attr("fill", (d) => service.getColor(d.item)).call(markerPath, "qaItem-fill");
49250 markersEnter.append("use").attr("class", "icon-annotation").attr("transform", "translate(-6, -22)").attr("width", "12px").attr("height", "12px").attr("xlink:href", (d) => d.icon ? "#" + d.icon : "");
49251 markers.merge(markersEnter).sort(sortY).classed("selected", (d) => d.id === selectedID).attr("transform", getTransform);
49252 if (touchLayer.empty())
49254 const fillClass = context.getDebug("target") ? "pink" : "nocolor";
49255 const targets = touchLayer.selectAll(".qaItem.osmose").data(data, (d) => d.id);
49256 targets.exit().remove();
49257 targets.enter().append("rect").attr("width", "20px").attr("height", "30px").attr("x", "-10px").attr("y", "-28px").merge(targets).sort(sortY).attr("class", (d) => `qaItem ${d.service} target ${fillClass} itemId-${d.id}`).attr("transform", getTransform);
49258 function sortY(a, b) {
49259 return a.id === selectedID ? 1 : b.id === selectedID ? -1 : b.loc[1] - a.loc[1];
49262 function drawOsmose(selection2) {
49263 const service = getService();
49264 const surface = context.surface();
49265 if (surface && !surface.empty()) {
49266 touchLayer = surface.selectAll(".data-layer.touch .layer-touch.markers");
49268 drawLayer = selection2.selectAll(".layer-osmose").data(service ? [0] : []);
49269 drawLayer.exit().remove();
49270 drawLayer = drawLayer.enter().append("g").attr("class", "layer-osmose").style("display", _layerEnabled3 ? "block" : "none").merge(drawLayer);
49271 if (_layerEnabled3) {
49272 if (service && ~~context.map().zoom() >= minZoom3) {
49274 service.loadIssues(projection2);
49281 drawOsmose.enabled = function(val) {
49282 if (!arguments.length)
49283 return _layerEnabled3;
49284 _layerEnabled3 = val;
49285 if (_layerEnabled3) {
49286 getService().loadStrings().then(layerOn).catch((err) => {
49291 if (context.selectedErrorID()) {
49292 context.enter(modeBrowse(context));
49295 dispatch10.call("change");
49298 drawOsmose.supported = () => !!getService();
49302 // modules/svg/streetside.js
49303 function svgStreetside(projection2, context, dispatch10) {
49304 var throttledRedraw = throttle_default(function() {
49305 dispatch10.call("change");
49308 var minMarkerZoom = 16;
49309 var minViewfieldZoom = 18;
49310 var layer = select_default2(null);
49311 var _viewerYaw = 0;
49312 var _selectedSequence = null;
49315 if (svgStreetside.initialized)
49317 svgStreetside.enabled = false;
49318 svgStreetside.initialized = true;
49320 function getService() {
49321 if (services.streetside && !_streetside) {
49322 _streetside = services.streetside;
49323 _streetside.event.on("viewerChanged.svgStreetside", viewerChanged).on("loadedImages.svgStreetside", throttledRedraw);
49324 } else if (!services.streetside && _streetside) {
49325 _streetside = null;
49327 return _streetside;
49329 function showLayer() {
49330 var service = getService();
49334 layer.style("opacity", 0).transition().duration(250).style("opacity", 1).on("end", function() {
49335 dispatch10.call("change");
49338 function hideLayer() {
49339 throttledRedraw.cancel();
49340 layer.transition().duration(250).style("opacity", 0).on("end", editOff);
49342 function editOn() {
49343 layer.style("display", "block");
49345 function editOff() {
49346 layer.selectAll(".viewfield-group").remove();
49347 layer.style("display", "none");
49349 function click(d3_event, d) {
49350 var service = getService();
49353 if (d.sequenceKey !== _selectedSequence) {
49356 _selectedSequence = d.sequenceKey;
49357 service.ensureViewerLoaded(context).then(function() {
49358 service.selectImage(context, d.key).yaw(_viewerYaw).showViewer(context);
49360 context.map().centerEase(d.loc);
49362 function mouseover(d3_event, d) {
49363 var service = getService();
49365 service.setStyles(context, d);
49367 function mouseout() {
49368 var service = getService();
49370 service.setStyles(context, null);
49372 function transform2(d) {
49373 var t = svgPointTransform(projection2)(d);
49374 var rot = d.ca + _viewerYaw;
49376 t += " rotate(" + Math.floor(rot) + ",0,0)";
49380 function viewerChanged() {
49381 var service = getService();
49384 var viewer = service.viewer();
49387 _viewerYaw = viewer.getYaw();
49388 if (context.map().isTransformed())
49390 layer.selectAll(".viewfield-group.currentView").attr("transform", transform2);
49392 function filterBubbles(bubbles) {
49393 var fromDate = context.photos().fromDate();
49394 var toDate = context.photos().toDate();
49395 var usernames = context.photos().usernames();
49397 var fromTimestamp = new Date(fromDate).getTime();
49398 bubbles = bubbles.filter(function(bubble) {
49399 return new Date(bubble.captured_at).getTime() >= fromTimestamp;
49403 var toTimestamp = new Date(toDate).getTime();
49404 bubbles = bubbles.filter(function(bubble) {
49405 return new Date(bubble.captured_at).getTime() <= toTimestamp;
49409 bubbles = bubbles.filter(function(bubble) {
49410 return usernames.indexOf(bubble.captured_by) !== -1;
49415 function filterSequences(sequences) {
49416 var fromDate = context.photos().fromDate();
49417 var toDate = context.photos().toDate();
49418 var usernames = context.photos().usernames();
49420 var fromTimestamp = new Date(fromDate).getTime();
49421 sequences = sequences.filter(function(sequences2) {
49422 return new Date(sequences2.properties.captured_at).getTime() >= fromTimestamp;
49426 var toTimestamp = new Date(toDate).getTime();
49427 sequences = sequences.filter(function(sequences2) {
49428 return new Date(sequences2.properties.captured_at).getTime() <= toTimestamp;
49432 sequences = sequences.filter(function(sequences2) {
49433 return usernames.indexOf(sequences2.properties.captured_by) !== -1;
49438 function update() {
49439 var viewer = context.container().select(".photoviewer");
49440 var selected = viewer.empty() ? void 0 : viewer.datum();
49441 var z = ~~context.map().zoom();
49442 var showMarkers = z >= minMarkerZoom;
49443 var showViewfields = z >= minViewfieldZoom;
49444 var service = getService();
49445 var sequences = [];
49447 if (context.photos().showsPanoramic()) {
49448 sequences = service ? service.sequences(projection2) : [];
49449 bubbles = service && showMarkers ? service.bubbles(projection2) : [];
49450 sequences = filterSequences(sequences);
49451 bubbles = filterBubbles(bubbles);
49453 var traces = layer.selectAll(".sequences").selectAll(".sequence").data(sequences, function(d) {
49454 return d.properties.key;
49456 traces.exit().remove();
49457 traces = traces.enter().append("path").attr("class", "sequence").merge(traces).attr("d", svgPath(projection2).geojson);
49458 var groups = layer.selectAll(".markers").selectAll(".viewfield-group").data(bubbles, function(d) {
49459 return d.key + (d.sequenceKey ? "v1" : "v0");
49461 groups.exit().remove();
49462 var groupsEnter = groups.enter().append("g").attr("class", "viewfield-group").on("mouseenter", mouseover).on("mouseleave", mouseout).on("click", click);
49463 groupsEnter.append("g").attr("class", "viewfield-scale");
49464 var markers = groups.merge(groupsEnter).sort(function(a, b) {
49465 return a === selected ? 1 : b === selected ? -1 : b.loc[1] - a.loc[1];
49466 }).attr("transform", transform2).select(".viewfield-scale");
49467 markers.selectAll("circle").data([0]).enter().append("circle").attr("dx", "0").attr("dy", "0").attr("r", "6");
49468 var viewfields = markers.selectAll(".viewfield").data(showViewfields ? [0] : []);
49469 viewfields.exit().remove();
49470 viewfields.enter().insert("path", "circle").attr("class", "viewfield").attr("transform", "scale(1.5,1.5),translate(-8, -13)").attr("d", viewfieldPath);
49471 function viewfieldPath() {
49472 var d = this.parentNode.__data__;
49474 return "M 8,13 m -10,0 a 10,10 0 1,0 20,0 a 10,10 0 1,0 -20,0";
49476 return "M 6,9 C 8,8.4 8,8.4 10,9 L 16,-2 C 12,-5 4,-5 0,-2 z";
49480 function drawImages(selection2) {
49481 var enabled = svgStreetside.enabled;
49482 var service = getService();
49483 layer = selection2.selectAll(".layer-streetside-images").data(service ? [0] : []);
49484 layer.exit().remove();
49485 var layerEnter = layer.enter().append("g").attr("class", "layer-streetside-images").style("display", enabled ? "block" : "none");
49486 layerEnter.append("g").attr("class", "sequences");
49487 layerEnter.append("g").attr("class", "markers");
49488 layer = layerEnter.merge(layer);
49490 if (service && ~~context.map().zoom() >= minZoom3) {
49493 service.loadBubbles(projection2);
49499 drawImages.enabled = function(_) {
49500 if (!arguments.length)
49501 return svgStreetside.enabled;
49502 svgStreetside.enabled = _;
49503 if (svgStreetside.enabled) {
49505 context.photos().on("change.streetside", update);
49508 context.photos().on("change.streetside", null);
49510 dispatch10.call("change");
49513 drawImages.supported = function() {
49514 return !!getService();
49520 // modules/svg/mapillary_images.js
49521 function svgMapillaryImages(projection2, context, dispatch10) {
49522 const throttledRedraw = throttle_default(function() {
49523 dispatch10.call("change");
49525 const minZoom3 = 12;
49526 const minMarkerZoom = 16;
49527 const minViewfieldZoom = 18;
49528 let layer = select_default2(null);
49531 if (svgMapillaryImages.initialized)
49533 svgMapillaryImages.enabled = false;
49534 svgMapillaryImages.initialized = true;
49536 function getService() {
49537 if (services.mapillary && !_mapillary) {
49538 _mapillary = services.mapillary;
49539 _mapillary.event.on("loadedImages", throttledRedraw);
49540 } else if (!services.mapillary && _mapillary) {
49545 function showLayer() {
49546 const service = getService();
49550 layer.style("opacity", 0).transition().duration(250).style("opacity", 1).on("end", function() {
49551 dispatch10.call("change");
49554 function hideLayer() {
49555 throttledRedraw.cancel();
49556 layer.transition().duration(250).style("opacity", 0).on("end", editOff);
49558 function editOn() {
49559 layer.style("display", "block");
49561 function editOff() {
49562 layer.selectAll(".viewfield-group").remove();
49563 layer.style("display", "none");
49565 function click(d3_event, image) {
49566 const service = getService();
49569 service.ensureViewerLoaded(context).then(function() {
49570 service.selectImage(context, image.id).showViewer(context);
49572 context.map().centerEase(image.loc);
49574 function mouseover(d3_event, image) {
49575 const service = getService();
49577 service.setStyles(context, image);
49579 function mouseout() {
49580 const service = getService();
49582 service.setStyles(context, null);
49584 function transform2(d) {
49585 let t = svgPointTransform(projection2)(d);
49587 t += " rotate(" + Math.floor(d.ca) + ",0,0)";
49591 function filterImages(images) {
49592 const showsPano = context.photos().showsPanoramic();
49593 const showsFlat = context.photos().showsFlat();
49594 const fromDate = context.photos().fromDate();
49595 const toDate = context.photos().toDate();
49596 if (!showsPano || !showsFlat) {
49597 images = images.filter(function(image) {
49604 images = images.filter(function(image) {
49605 return new Date(image.captured_at).getTime() >= new Date(fromDate).getTime();
49609 images = images.filter(function(image) {
49610 return new Date(image.captured_at).getTime() <= new Date(toDate).getTime();
49615 function filterSequences(sequences) {
49616 const showsPano = context.photos().showsPanoramic();
49617 const showsFlat = context.photos().showsFlat();
49618 const fromDate = context.photos().fromDate();
49619 const toDate = context.photos().toDate();
49620 if (!showsPano || !showsFlat) {
49621 sequences = sequences.filter(function(sequence) {
49622 if (sequence.properties.hasOwnProperty("is_pano")) {
49623 if (sequence.properties.is_pano)
49631 sequences = sequences.filter(function(sequence) {
49632 return new Date(sequence.properties.captured_at).getTime() >= new Date(fromDate).getTime().toString();
49636 sequences = sequences.filter(function(sequence) {
49637 return new Date(sequence.properties.captured_at).getTime() <= new Date(toDate).getTime().toString();
49642 function update() {
49643 const z = ~~context.map().zoom();
49644 const showMarkers = z >= minMarkerZoom;
49645 const showViewfields = z >= minViewfieldZoom;
49646 const service = getService();
49647 let sequences = service ? service.sequences(projection2) : [];
49648 let images = service && showMarkers ? service.images(projection2) : [];
49649 images = filterImages(images);
49650 sequences = filterSequences(sequences, service);
49651 service.filterViewer(context);
49652 let traces = layer.selectAll(".sequences").selectAll(".sequence").data(sequences, function(d) {
49653 return d.properties.id;
49655 traces.exit().remove();
49656 traces = traces.enter().append("path").attr("class", "sequence").merge(traces).attr("d", svgPath(projection2).geojson);
49657 const groups = layer.selectAll(".markers").selectAll(".viewfield-group").data(images, function(d) {
49660 groups.exit().remove();
49661 const groupsEnter = groups.enter().append("g").attr("class", "viewfield-group").on("mouseenter", mouseover).on("mouseleave", mouseout).on("click", click);
49662 groupsEnter.append("g").attr("class", "viewfield-scale");
49663 const markers = groups.merge(groupsEnter).sort(function(a, b) {
49664 return b.loc[1] - a.loc[1];
49665 }).attr("transform", transform2).select(".viewfield-scale");
49666 markers.selectAll("circle").data([0]).enter().append("circle").attr("dx", "0").attr("dy", "0").attr("r", "6");
49667 const viewfields = markers.selectAll(".viewfield").data(showViewfields ? [0] : []);
49668 viewfields.exit().remove();
49669 viewfields.enter().insert("path", "circle").attr("class", "viewfield").classed("pano", function() {
49670 return this.parentNode.__data__.is_pano;
49671 }).attr("transform", "scale(1.5,1.5),translate(-8, -13)").attr("d", viewfieldPath);
49672 function viewfieldPath() {
49673 if (this.parentNode.__data__.is_pano) {
49674 return "M 8,13 m -10,0 a 10,10 0 1,0 20,0 a 10,10 0 1,0 -20,0";
49676 return "M 6,9 C 8,8.4 8,8.4 10,9 L 16,-2 C 12,-5 4,-5 0,-2 z";
49680 function drawImages(selection2) {
49681 const enabled = svgMapillaryImages.enabled;
49682 const service = getService();
49683 layer = selection2.selectAll(".layer-mapillary").data(service ? [0] : []);
49684 layer.exit().remove();
49685 const layerEnter = layer.enter().append("g").attr("class", "layer-mapillary").style("display", enabled ? "block" : "none");
49686 layerEnter.append("g").attr("class", "sequences");
49687 layerEnter.append("g").attr("class", "markers");
49688 layer = layerEnter.merge(layer);
49690 if (service && ~~context.map().zoom() >= minZoom3) {
49693 service.loadImages(projection2);
49699 drawImages.enabled = function(_) {
49700 if (!arguments.length)
49701 return svgMapillaryImages.enabled;
49702 svgMapillaryImages.enabled = _;
49703 if (svgMapillaryImages.enabled) {
49705 context.photos().on("change.mapillary_images", update);
49708 context.photos().on("change.mapillary_images", null);
49710 dispatch10.call("change");
49713 drawImages.supported = function() {
49714 return !!getService();
49720 // modules/svg/mapillary_position.js
49721 function svgMapillaryPosition(projection2, context) {
49722 const throttledRedraw = throttle_default(function() {
49725 const minZoom3 = 12;
49726 const minViewfieldZoom = 18;
49727 let layer = select_default2(null);
49729 let viewerCompassAngle;
49731 if (svgMapillaryPosition.initialized)
49733 svgMapillaryPosition.initialized = true;
49735 function getService() {
49736 if (services.mapillary && !_mapillary) {
49737 _mapillary = services.mapillary;
49738 _mapillary.event.on("imageChanged", throttledRedraw);
49739 _mapillary.event.on("bearingChanged", function(e) {
49740 viewerCompassAngle = e.bearing;
49741 if (context.map().isTransformed())
49743 layer.selectAll(".viewfield-group.currentView").filter(function(d) {
49745 }).attr("transform", transform2);
49747 } else if (!services.mapillary && _mapillary) {
49752 function editOn() {
49753 layer.style("display", "block");
49755 function editOff() {
49756 layer.selectAll(".viewfield-group").remove();
49757 layer.style("display", "none");
49759 function transform2(d) {
49760 let t = svgPointTransform(projection2)(d);
49761 if (d.is_pano && viewerCompassAngle !== null && isFinite(viewerCompassAngle)) {
49762 t += " rotate(" + Math.floor(viewerCompassAngle) + ",0,0)";
49764 t += " rotate(" + Math.floor(d.ca) + ",0,0)";
49768 function update() {
49769 const z = ~~context.map().zoom();
49770 const showViewfields = z >= minViewfieldZoom;
49771 const service = getService();
49772 const image = service && service.getActiveImage();
49773 const groups = layer.selectAll(".markers").selectAll(".viewfield-group").data(image ? [image] : [], function(d) {
49776 groups.exit().remove();
49777 const groupsEnter = groups.enter().append("g").attr("class", "viewfield-group currentView highlighted");
49778 groupsEnter.append("g").attr("class", "viewfield-scale");
49779 const markers = groups.merge(groupsEnter).attr("transform", transform2).select(".viewfield-scale");
49780 markers.selectAll("circle").data([0]).enter().append("circle").attr("dx", "0").attr("dy", "0").attr("r", "6");
49781 const viewfields = markers.selectAll(".viewfield").data(showViewfields ? [0] : []);
49782 viewfields.exit().remove();
49783 viewfields.enter().insert("path", "circle").attr("class", "viewfield").attr("transform", "scale(1.5,1.5),translate(-8, -13)").attr("d", "M 6,9 C 8,8.4 8,8.4 10,9 L 16,-2 C 12,-5 4,-5 0,-2 z");
49785 function drawImages(selection2) {
49786 const service = getService();
49787 layer = selection2.selectAll(".layer-mapillary-position").data(service ? [0] : []);
49788 layer.exit().remove();
49789 const layerEnter = layer.enter().append("g").attr("class", "layer-mapillary-position");
49790 layerEnter.append("g").attr("class", "markers");
49791 layer = layerEnter.merge(layer);
49792 if (service && ~~context.map().zoom() >= minZoom3) {
49799 drawImages.enabled = function() {
49803 drawImages.supported = function() {
49804 return !!getService();
49810 // modules/svg/mapillary_signs.js
49811 function svgMapillarySigns(projection2, context, dispatch10) {
49812 const throttledRedraw = throttle_default(function() {
49813 dispatch10.call("change");
49815 const minZoom3 = 12;
49816 let layer = select_default2(null);
49819 if (svgMapillarySigns.initialized)
49821 svgMapillarySigns.enabled = false;
49822 svgMapillarySigns.initialized = true;
49824 function getService() {
49825 if (services.mapillary && !_mapillary) {
49826 _mapillary = services.mapillary;
49827 _mapillary.event.on("loadedSigns", throttledRedraw);
49828 } else if (!services.mapillary && _mapillary) {
49833 function showLayer() {
49834 const service = getService();
49837 service.loadSignResources(context);
49840 function hideLayer() {
49841 throttledRedraw.cancel();
49844 function editOn() {
49845 layer.style("display", "block");
49847 function editOff() {
49848 layer.selectAll(".icon-sign").remove();
49849 layer.style("display", "none");
49851 function click(d3_event, d) {
49852 const service = getService();
49855 context.map().centerEase(d.loc);
49856 const selectedImageId = service.getActiveImage() && service.getActiveImage().id;
49857 service.getDetections(d.id).then((detections) => {
49858 if (detections.length) {
49859 const imageId = detections[0].image.id;
49860 if (imageId === selectedImageId) {
49861 service.highlightDetection(detections[0]).selectImage(context, imageId);
49863 service.ensureViewerLoaded(context).then(function() {
49864 service.highlightDetection(detections[0]).selectImage(context, imageId).showViewer(context);
49870 function filterData(detectedFeatures) {
49871 var fromDate = context.photos().fromDate();
49872 var toDate = context.photos().toDate();
49874 var fromTimestamp = new Date(fromDate).getTime();
49875 detectedFeatures = detectedFeatures.filter(function(feature3) {
49876 return new Date(feature3.last_seen_at).getTime() >= fromTimestamp;
49880 var toTimestamp = new Date(toDate).getTime();
49881 detectedFeatures = detectedFeatures.filter(function(feature3) {
49882 return new Date(feature3.first_seen_at).getTime() <= toTimestamp;
49885 return detectedFeatures;
49887 function update() {
49888 const service = getService();
49889 let data = service ? service.signs(projection2) : [];
49890 data = filterData(data);
49891 const transform2 = svgPointTransform(projection2);
49892 const signs = layer.selectAll(".icon-sign").data(data, function(d) {
49895 signs.exit().remove();
49896 const enter = signs.enter().append("g").attr("class", "icon-sign icon-detected").on("click", click);
49897 enter.append("use").attr("width", "24px").attr("height", "24px").attr("x", "-12px").attr("y", "-12px").attr("xlink:href", function(d) {
49898 return "#" + d.value;
49900 enter.append("rect").attr("width", "24px").attr("height", "24px").attr("x", "-12px").attr("y", "-12px");
49901 signs.merge(enter).attr("transform", transform2);
49903 function drawSigns(selection2) {
49904 const enabled = svgMapillarySigns.enabled;
49905 const service = getService();
49906 layer = selection2.selectAll(".layer-mapillary-signs").data(service ? [0] : []);
49907 layer.exit().remove();
49908 layer = layer.enter().append("g").attr("class", "layer-mapillary-signs layer-mapillary-detections").style("display", enabled ? "block" : "none").merge(layer);
49910 if (service && ~~context.map().zoom() >= minZoom3) {
49913 service.loadSigns(projection2);
49914 service.showSignDetections(true);
49918 } else if (service) {
49919 service.showSignDetections(false);
49922 drawSigns.enabled = function(_) {
49923 if (!arguments.length)
49924 return svgMapillarySigns.enabled;
49925 svgMapillarySigns.enabled = _;
49926 if (svgMapillarySigns.enabled) {
49928 context.photos().on("change.mapillary_signs", update);
49931 context.photos().on("change.mapillary_signs", null);
49933 dispatch10.call("change");
49936 drawSigns.supported = function() {
49937 return !!getService();
49943 // modules/svg/mapillary_map_features.js
49944 function svgMapillaryMapFeatures(projection2, context, dispatch10) {
49945 const throttledRedraw = throttle_default(function() {
49946 dispatch10.call("change");
49948 const minZoom3 = 12;
49949 let layer = select_default2(null);
49952 if (svgMapillaryMapFeatures.initialized)
49954 svgMapillaryMapFeatures.enabled = false;
49955 svgMapillaryMapFeatures.initialized = true;
49957 function getService() {
49958 if (services.mapillary && !_mapillary) {
49959 _mapillary = services.mapillary;
49960 _mapillary.event.on("loadedMapFeatures", throttledRedraw);
49961 } else if (!services.mapillary && _mapillary) {
49966 function showLayer() {
49967 const service = getService();
49970 service.loadObjectResources(context);
49973 function hideLayer() {
49974 throttledRedraw.cancel();
49977 function editOn() {
49978 layer.style("display", "block");
49980 function editOff() {
49981 layer.selectAll(".icon-map-feature").remove();
49982 layer.style("display", "none");
49984 function click(d3_event, d) {
49985 const service = getService();
49988 context.map().centerEase(d.loc);
49989 const selectedImageId = service.getActiveImage() && service.getActiveImage().id;
49990 service.getDetections(d.id).then((detections) => {
49991 if (detections.length) {
49992 const imageId = detections[0].image.id;
49993 if (imageId === selectedImageId) {
49994 service.highlightDetection(detections[0]).selectImage(context, imageId);
49996 service.ensureViewerLoaded(context).then(function() {
49997 service.highlightDetection(detections[0]).selectImage(context, imageId).showViewer(context);
50003 function filterData(detectedFeatures) {
50004 const fromDate = context.photos().fromDate();
50005 const toDate = context.photos().toDate();
50007 detectedFeatures = detectedFeatures.filter(function(feature3) {
50008 return new Date(feature3.last_seen_at).getTime() >= new Date(fromDate).getTime();
50012 detectedFeatures = detectedFeatures.filter(function(feature3) {
50013 return new Date(feature3.first_seen_at).getTime() <= new Date(toDate).getTime();
50016 return detectedFeatures;
50018 function update() {
50019 const service = getService();
50020 let data = service ? service.mapFeatures(projection2) : [];
50021 data = filterData(data);
50022 const transform2 = svgPointTransform(projection2);
50023 const mapFeatures = layer.selectAll(".icon-map-feature").data(data, function(d) {
50026 mapFeatures.exit().remove();
50027 const enter = mapFeatures.enter().append("g").attr("class", "icon-map-feature icon-detected").on("click", click);
50028 enter.append("title").text(function(d) {
50029 var id2 = d.value.replace(/--/g, ".").replace(/-/g, "_");
50030 return _t("mapillary_map_features." + id2);
50032 enter.append("use").attr("width", "24px").attr("height", "24px").attr("x", "-12px").attr("y", "-12px").attr("xlink:href", function(d) {
50033 if (d.value === "object--billboard") {
50034 return "#object--sign--advertisement";
50036 return "#" + d.value;
50038 enter.append("rect").attr("width", "24px").attr("height", "24px").attr("x", "-12px").attr("y", "-12px");
50039 mapFeatures.merge(enter).attr("transform", transform2);
50041 function drawMapFeatures(selection2) {
50042 const enabled = svgMapillaryMapFeatures.enabled;
50043 const service = getService();
50044 layer = selection2.selectAll(".layer-mapillary-map-features").data(service ? [0] : []);
50045 layer.exit().remove();
50046 layer = layer.enter().append("g").attr("class", "layer-mapillary-map-features layer-mapillary-detections").style("display", enabled ? "block" : "none").merge(layer);
50048 if (service && ~~context.map().zoom() >= minZoom3) {
50051 service.loadMapFeatures(projection2);
50052 service.showFeatureDetections(true);
50056 } else if (service) {
50057 service.showFeatureDetections(false);
50060 drawMapFeatures.enabled = function(_) {
50061 if (!arguments.length)
50062 return svgMapillaryMapFeatures.enabled;
50063 svgMapillaryMapFeatures.enabled = _;
50064 if (svgMapillaryMapFeatures.enabled) {
50066 context.photos().on("change.mapillary_map_features", update);
50069 context.photos().on("change.mapillary_map_features", null);
50071 dispatch10.call("change");
50074 drawMapFeatures.supported = function() {
50075 return !!getService();
50078 return drawMapFeatures;
50081 // modules/svg/kartaview_images.js
50082 function svgKartaviewImages(projection2, context, dispatch10) {
50083 var throttledRedraw = throttle_default(function() {
50084 dispatch10.call("change");
50087 var minMarkerZoom = 16;
50088 var minViewfieldZoom = 18;
50089 var layer = select_default2(null);
50092 if (svgKartaviewImages.initialized)
50094 svgKartaviewImages.enabled = false;
50095 svgKartaviewImages.initialized = true;
50097 function getService() {
50098 if (services.kartaview && !_kartaview) {
50099 _kartaview = services.kartaview;
50100 _kartaview.event.on("loadedImages", throttledRedraw);
50101 } else if (!services.kartaview && _kartaview) {
50106 function showLayer() {
50107 var service = getService();
50111 layer.style("opacity", 0).transition().duration(250).style("opacity", 1).on("end", function() {
50112 dispatch10.call("change");
50115 function hideLayer() {
50116 throttledRedraw.cancel();
50117 layer.transition().duration(250).style("opacity", 0).on("end", editOff);
50119 function editOn() {
50120 layer.style("display", "block");
50122 function editOff() {
50123 layer.selectAll(".viewfield-group").remove();
50124 layer.style("display", "none");
50126 function click(d3_event, d) {
50127 var service = getService();
50130 service.ensureViewerLoaded(context).then(function() {
50131 service.selectImage(context, d.key).showViewer(context);
50133 context.map().centerEase(d.loc);
50135 function mouseover(d3_event, d) {
50136 var service = getService();
50138 service.setStyles(context, d);
50140 function mouseout() {
50141 var service = getService();
50143 service.setStyles(context, null);
50145 function transform2(d) {
50146 var t = svgPointTransform(projection2)(d);
50148 t += " rotate(" + Math.floor(d.ca) + ",0,0)";
50152 function filterImages(images) {
50153 var fromDate = context.photos().fromDate();
50154 var toDate = context.photos().toDate();
50155 var usernames = context.photos().usernames();
50157 var fromTimestamp = new Date(fromDate).getTime();
50158 images = images.filter(function(item) {
50159 return new Date(item.captured_at).getTime() >= fromTimestamp;
50163 var toTimestamp = new Date(toDate).getTime();
50164 images = images.filter(function(item) {
50165 return new Date(item.captured_at).getTime() <= toTimestamp;
50169 images = images.filter(function(item) {
50170 return usernames.indexOf(item.captured_by) !== -1;
50175 function filterSequences(sequences) {
50176 var fromDate = context.photos().fromDate();
50177 var toDate = context.photos().toDate();
50178 var usernames = context.photos().usernames();
50180 var fromTimestamp = new Date(fromDate).getTime();
50181 sequences = sequences.filter(function(image) {
50182 return new Date(image.properties.captured_at).getTime() >= fromTimestamp;
50186 var toTimestamp = new Date(toDate).getTime();
50187 sequences = sequences.filter(function(image) {
50188 return new Date(image.properties.captured_at).getTime() <= toTimestamp;
50192 sequences = sequences.filter(function(image) {
50193 return usernames.indexOf(image.properties.captured_by) !== -1;
50198 function update() {
50199 var viewer = context.container().select(".photoviewer");
50200 var selected = viewer.empty() ? void 0 : viewer.datum();
50201 var z = ~~context.map().zoom();
50202 var showMarkers = z >= minMarkerZoom;
50203 var showViewfields = z >= minViewfieldZoom;
50204 var service = getService();
50205 var sequences = [];
50207 if (context.photos().showsFlat()) {
50208 sequences = service ? service.sequences(projection2) : [];
50209 images = service && showMarkers ? service.images(projection2) : [];
50210 sequences = filterSequences(sequences);
50211 images = filterImages(images);
50213 var traces = layer.selectAll(".sequences").selectAll(".sequence").data(sequences, function(d) {
50214 return d.properties.key;
50216 traces.exit().remove();
50217 traces = traces.enter().append("path").attr("class", "sequence").merge(traces).attr("d", svgPath(projection2).geojson);
50218 var groups = layer.selectAll(".markers").selectAll(".viewfield-group").data(images, function(d) {
50221 groups.exit().remove();
50222 var groupsEnter = groups.enter().append("g").attr("class", "viewfield-group").on("mouseenter", mouseover).on("mouseleave", mouseout).on("click", click);
50223 groupsEnter.append("g").attr("class", "viewfield-scale");
50224 var markers = groups.merge(groupsEnter).sort(function(a, b) {
50225 return a === selected ? 1 : b === selected ? -1 : b.loc[1] - a.loc[1];
50226 }).attr("transform", transform2).select(".viewfield-scale");
50227 markers.selectAll("circle").data([0]).enter().append("circle").attr("dx", "0").attr("dy", "0").attr("r", "6");
50228 var viewfields = markers.selectAll(".viewfield").data(showViewfields ? [0] : []);
50229 viewfields.exit().remove();
50230 viewfields.enter().insert("path", "circle").attr("class", "viewfield").attr("transform", "scale(1.5,1.5),translate(-8, -13)").attr("d", "M 6,9 C 8,8.4 8,8.4 10,9 L 16,-2 C 12,-5 4,-5 0,-2 z");
50232 function drawImages(selection2) {
50233 var enabled = svgKartaviewImages.enabled, service = getService();
50234 layer = selection2.selectAll(".layer-kartaview").data(service ? [0] : []);
50235 layer.exit().remove();
50236 var layerEnter = layer.enter().append("g").attr("class", "layer-kartaview").style("display", enabled ? "block" : "none");
50237 layerEnter.append("g").attr("class", "sequences");
50238 layerEnter.append("g").attr("class", "markers");
50239 layer = layerEnter.merge(layer);
50241 if (service && ~~context.map().zoom() >= minZoom3) {
50244 service.loadImages(projection2);
50250 drawImages.enabled = function(_) {
50251 if (!arguments.length)
50252 return svgKartaviewImages.enabled;
50253 svgKartaviewImages.enabled = _;
50254 if (svgKartaviewImages.enabled) {
50256 context.photos().on("change.kartaview_images", update);
50259 context.photos().on("change.kartaview_images", null);
50261 dispatch10.call("change");
50264 drawImages.supported = function() {
50265 return !!getService();
50271 // modules/svg/osm.js
50272 function svgOsm(projection2, context, dispatch10) {
50273 var enabled = true;
50274 function drawOsm(selection2) {
50275 selection2.selectAll(".layer-osm").data(["covered", "areas", "lines", "points", "labels"]).enter().append("g").attr("class", function(d) {
50276 return "layer-osm " + d;
50278 selection2.selectAll(".layer-osm.points").selectAll(".points-group").data(["points", "midpoints", "vertices", "turns"]).enter().append("g").attr("class", function(d) {
50279 return "points-group " + d;
50282 function showLayer() {
50283 var layer = context.surface().selectAll(".data-layer.osm");
50285 layer.classed("disabled", false).style("opacity", 0).transition().duration(250).style("opacity", 1).on("end interrupt", function() {
50286 dispatch10.call("change");
50289 function hideLayer() {
50290 var layer = context.surface().selectAll(".data-layer.osm");
50292 layer.transition().duration(250).style("opacity", 0).on("end interrupt", function() {
50293 layer.classed("disabled", true);
50294 dispatch10.call("change");
50297 drawOsm.enabled = function(val) {
50298 if (!arguments.length)
50306 dispatch10.call("change");
50312 // modules/svg/notes.js
50313 var _notesEnabled = false;
50315 function svgNotes(projection2, context, dispatch10) {
50317 dispatch10 = dispatch_default("change");
50319 var throttledRedraw = throttle_default(function() {
50320 dispatch10.call("change");
50323 var touchLayer = select_default2(null);
50324 var drawLayer = select_default2(null);
50325 var _notesVisible = false;
50326 function markerPath(selection2, klass) {
50327 selection2.attr("class", klass).attr("transform", "translate(-8, -22)").attr("d", "m17.5,0l-15,0c-1.37,0 -2.5,1.12 -2.5,2.5l0,11.25c0,1.37 1.12,2.5 2.5,2.5l3.75,0l0,3.28c0,0.38 0.43,0.6 0.75,0.37l4.87,-3.65l5.62,0c1.37,0 2.5,-1.12 2.5,-2.5l0,-11.25c0,-1.37 -1.12,-2.5 -2.5,-2.5z");
50329 function getService() {
50330 if (services.osm && !_osmService) {
50331 _osmService = services.osm;
50332 _osmService.on("loadedNotes", throttledRedraw);
50333 } else if (!services.osm && _osmService) {
50334 _osmService = null;
50336 return _osmService;
50338 function editOn() {
50339 if (!_notesVisible) {
50340 _notesVisible = true;
50341 drawLayer.style("display", "block");
50344 function editOff() {
50345 if (_notesVisible) {
50346 _notesVisible = false;
50347 drawLayer.style("display", "none");
50348 drawLayer.selectAll(".note").remove();
50349 touchLayer.selectAll(".note").remove();
50352 function layerOn() {
50354 drawLayer.style("opacity", 0).transition().duration(250).style("opacity", 1).on("end interrupt", function() {
50355 dispatch10.call("change");
50358 function layerOff() {
50359 throttledRedraw.cancel();
50360 drawLayer.interrupt();
50361 touchLayer.selectAll(".note").remove();
50362 drawLayer.transition().duration(250).style("opacity", 0).on("end interrupt", function() {
50364 dispatch10.call("change");
50367 function updateMarkers() {
50368 if (!_notesVisible || !_notesEnabled)
50370 var service = getService();
50371 var selectedID = context.selectedNoteID();
50372 var data = service ? service.notes(projection2) : [];
50373 var getTransform = svgPointTransform(projection2);
50374 var notes = drawLayer.selectAll(".note").data(data, function(d) {
50375 return d.status + d.id;
50377 notes.exit().remove();
50378 var notesEnter = notes.enter().append("g").attr("class", function(d) {
50379 return "note note-" + d.id + " " + d.status;
50380 }).classed("new", function(d) {
50383 notesEnter.append("ellipse").attr("cx", 0.5).attr("cy", 1).attr("rx", 6.5).attr("ry", 3).attr("class", "stroke");
50384 notesEnter.append("path").call(markerPath, "shadow");
50385 notesEnter.append("use").attr("class", "note-fill").attr("width", "20px").attr("height", "20px").attr("x", "-8px").attr("y", "-22px").attr("xlink:href", "#iD-icon-note");
50386 notesEnter.selectAll(".icon-annotation").data(function(d) {
50388 }).enter().append("use").attr("class", "icon-annotation").attr("width", "10px").attr("height", "10px").attr("x", "-3px").attr("y", "-19px").attr("xlink:href", function(d) {
50390 return "#iD-icon-plus";
50391 if (d.status === "open")
50392 return "#iD-icon-close";
50393 return "#iD-icon-apply";
50395 notes.merge(notesEnter).sort(sortY).classed("selected", function(d) {
50396 var mode = context.mode();
50397 var isMoving = mode && mode.id === "drag-note";
50398 return !isMoving && d.id === selectedID;
50399 }).attr("transform", getTransform);
50400 if (touchLayer.empty())
50402 var fillClass = context.getDebug("target") ? "pink " : "nocolor ";
50403 var targets = touchLayer.selectAll(".note").data(data, function(d) {
50406 targets.exit().remove();
50407 targets.enter().append("rect").attr("width", "20px").attr("height", "20px").attr("x", "-8px").attr("y", "-22px").merge(targets).sort(sortY).attr("class", function(d) {
50408 var newClass = d.id < 0 ? "new" : "";
50409 return "note target note-" + d.id + " " + fillClass + newClass;
50410 }).attr("transform", getTransform);
50411 function sortY(a, b) {
50412 if (a.id === selectedID)
50414 if (b.id === selectedID)
50416 return b.loc[1] - a.loc[1];
50419 function drawNotes(selection2) {
50420 var service = getService();
50421 var surface = context.surface();
50422 if (surface && !surface.empty()) {
50423 touchLayer = surface.selectAll(".data-layer.touch .layer-touch.markers");
50425 drawLayer = selection2.selectAll(".layer-notes").data(service ? [0] : []);
50426 drawLayer.exit().remove();
50427 drawLayer = drawLayer.enter().append("g").attr("class", "layer-notes").style("display", _notesEnabled ? "block" : "none").merge(drawLayer);
50428 if (_notesEnabled) {
50429 if (service && ~~context.map().zoom() >= minZoom3) {
50431 service.loadNotes(projection2);
50438 drawNotes.enabled = function(val) {
50439 if (!arguments.length)
50440 return _notesEnabled;
50441 _notesEnabled = val;
50442 if (_notesEnabled) {
50446 if (context.selectedNoteID()) {
50447 context.enter(modeBrowse(context));
50450 dispatch10.call("change");
50456 // modules/svg/touch.js
50457 function svgTouch() {
50458 function drawTouch(selection2) {
50459 selection2.selectAll(".layer-touch").data(["areas", "lines", "points", "turns", "markers"]).enter().append("g").attr("class", function(d) {
50460 return "layer-touch " + d;
50466 // modules/util/dimensions.js
50467 function refresh(selection2, node) {
50468 var cr = node.getBoundingClientRect();
50469 var prop = [cr.width, cr.height];
50470 selection2.property("__dimensions__", prop);
50473 function utilGetDimensions(selection2, force) {
50474 if (!selection2 || selection2.empty()) {
50477 var node = selection2.node(), cached = selection2.property("__dimensions__");
50478 return !cached || force ? refresh(selection2, node) : cached;
50480 function utilSetDimensions(selection2, dimensions) {
50481 if (!selection2 || selection2.empty()) {
50484 var node = selection2.node();
50485 if (dimensions === null) {
50486 refresh(selection2, node);
50489 return selection2.property("__dimensions__", [dimensions[0], dimensions[1]]).attr("width", dimensions[0]).attr("height", dimensions[1]);
50492 // modules/svg/layers.js
50493 function svgLayers(projection2, context) {
50494 var dispatch10 = dispatch_default("change");
50495 var svg2 = select_default2(null);
50497 { id: "osm", layer: svgOsm(projection2, context, dispatch10) },
50498 { id: "notes", layer: svgNotes(projection2, context, dispatch10) },
50499 { id: "data", layer: svgData(projection2, context, dispatch10) },
50500 { id: "keepRight", layer: svgKeepRight(projection2, context, dispatch10) },
50501 { id: "improveOSM", layer: svgImproveOSM(projection2, context, dispatch10) },
50502 { id: "osmose", layer: svgOsmose(projection2, context, dispatch10) },
50503 { id: "streetside", layer: svgStreetside(projection2, context, dispatch10) },
50504 { id: "mapillary", layer: svgMapillaryImages(projection2, context, dispatch10) },
50505 { id: "mapillary-position", layer: svgMapillaryPosition(projection2, context, dispatch10) },
50506 { id: "mapillary-map-features", layer: svgMapillaryMapFeatures(projection2, context, dispatch10) },
50507 { id: "mapillary-signs", layer: svgMapillarySigns(projection2, context, dispatch10) },
50508 { id: "kartaview", layer: svgKartaviewImages(projection2, context, dispatch10) },
50509 { id: "debug", layer: svgDebug(projection2, context, dispatch10) },
50510 { id: "geolocate", layer: svgGeolocate(projection2, context, dispatch10) },
50511 { id: "touch", layer: svgTouch(projection2, context, dispatch10) }
50513 function drawLayers(selection2) {
50514 svg2 = selection2.selectAll(".surface").data([0]);
50515 svg2 = svg2.enter().append("svg").attr("class", "surface").merge(svg2);
50516 var defs = svg2.selectAll(".surface-defs").data([0]);
50517 defs.enter().append("defs").attr("class", "surface-defs");
50518 var groups = svg2.selectAll(".data-layer").data(_layers);
50519 groups.exit().remove();
50520 groups.enter().append("g").attr("class", function(d) {
50521 return "data-layer " + d.id;
50522 }).merge(groups).each(function(d) {
50523 select_default2(this).call(d.layer);
50526 drawLayers.all = function() {
50529 drawLayers.layer = function(id2) {
50530 var obj = _layers.find(function(o) {
50531 return o.id === id2;
50533 return obj && obj.layer;
50535 drawLayers.only = function(what) {
50536 var arr = [].concat(what);
50537 var all = _layers.map(function(layer) {
50540 return drawLayers.remove(utilArrayDifference(all, arr));
50542 drawLayers.remove = function(what) {
50543 var arr = [].concat(what);
50544 arr.forEach(function(id2) {
50545 _layers = _layers.filter(function(o) {
50546 return o.id !== id2;
50549 dispatch10.call("change");
50552 drawLayers.add = function(what) {
50553 var arr = [].concat(what);
50554 arr.forEach(function(obj) {
50555 if ("id" in obj && "layer" in obj) {
50559 dispatch10.call("change");
50562 drawLayers.dimensions = function(val) {
50563 if (!arguments.length)
50564 return utilGetDimensions(svg2);
50565 utilSetDimensions(svg2, val);
50568 return utilRebind(drawLayers, dispatch10, "on");
50571 // modules/svg/lines.js
50572 var import_fast_deep_equal6 = __toESM(require_fast_deep_equal());
50573 function svgLines(projection2, context) {
50574 var detected = utilDetect();
50575 var highway_stack = {
50589 function drawTargets(selection2, graph, entities, filter2) {
50590 var targetClass = context.getDebug("target") ? "pink " : "nocolor ";
50591 var nopeClass = context.getDebug("target") ? "red " : "nocolor ";
50592 var getPath = svgPath(projection2).geojson;
50593 var activeID = context.activeID();
50594 var base = context.history().base();
50595 var data = { targets: [], nopes: [] };
50596 entities.forEach(function(way) {
50597 var features = svgSegmentWay(way, graph, activeID);
50598 data.targets.push.apply(data.targets, features.passive);
50599 data.nopes.push.apply(data.nopes, features.active);
50601 var targetData = data.targets.filter(getPath);
50602 var targets = selection2.selectAll(".line.target-allowed").filter(function(d) {
50603 return filter2(d.properties.entity);
50604 }).data(targetData, function key(d) {
50607 targets.exit().remove();
50608 var segmentWasEdited = function(d) {
50609 var wayID = d.properties.entity.id;
50610 if (!base.entities[wayID] || !(0, import_fast_deep_equal6.default)(graph.entities[wayID].nodes, base.entities[wayID].nodes)) {
50613 return d.properties.nodes.some(function(n2) {
50614 return !base.entities[n2.id] || !(0, import_fast_deep_equal6.default)(graph.entities[n2.id].loc, base.entities[n2.id].loc);
50617 targets.enter().append("path").merge(targets).attr("d", getPath).attr("class", function(d) {
50618 return "way line target target-allowed " + targetClass + d.id;
50619 }).classed("segment-edited", segmentWasEdited);
50620 var nopeData = data.nopes.filter(getPath);
50621 var nopes = selection2.selectAll(".line.target-nope").filter(function(d) {
50622 return filter2(d.properties.entity);
50623 }).data(nopeData, function key(d) {
50626 nopes.exit().remove();
50627 nopes.enter().append("path").merge(nopes).attr("d", getPath).attr("class", function(d) {
50628 return "way line target target-nope " + nopeClass + d.id;
50629 }).classed("segment-edited", segmentWasEdited);
50631 function drawLines(selection2, graph, entities, filter2) {
50632 var base = context.history().base();
50633 function waystack(a, b) {
50634 var selected = context.selectedIDs();
50635 var scoreA = selected.indexOf(a.id) !== -1 ? 20 : 0;
50636 var scoreB = selected.indexOf(b.id) !== -1 ? 20 : 0;
50637 if (a.tags.highway) {
50638 scoreA -= highway_stack[a.tags.highway];
50640 if (b.tags.highway) {
50641 scoreB -= highway_stack[b.tags.highway];
50643 return scoreA - scoreB;
50645 function drawLineGroup(selection3, klass, isSelected) {
50646 var mode = context.mode();
50647 var isDrawing = mode && /^draw/.test(mode.id);
50648 var selectedClass = !isDrawing && isSelected ? "selected " : "";
50649 var lines = selection3.selectAll("path").filter(filter2).data(getPathData(isSelected), osmEntity.key);
50650 lines.exit().remove();
50651 lines.enter().append("path").attr("class", function(d) {
50652 var prefix = "way line";
50653 if (!d.hasInterestingTags()) {
50654 var parentRelations = graph.parentRelations(d);
50655 var parentMultipolygons = parentRelations.filter(function(relation) {
50656 return relation.isMultipolygon();
50658 if (parentMultipolygons.length > 0 && // and only multipolygon relations
50659 parentRelations.length === parentMultipolygons.length) {
50660 prefix = "relation area";
50663 var oldMPClass = oldMultiPolygonOuters[d.id] ? "old-multipolygon " : "";
50664 return prefix + " " + klass + " " + selectedClass + oldMPClass + d.id;
50665 }).classed("added", function(d) {
50666 return !base.entities[d.id];
50667 }).classed("geometry-edited", function(d) {
50668 return graph.entities[d.id] && base.entities[d.id] && !(0, import_fast_deep_equal6.default)(graph.entities[d.id].nodes, base.entities[d.id].nodes);
50669 }).classed("retagged", function(d) {
50670 return graph.entities[d.id] && base.entities[d.id] && !(0, import_fast_deep_equal6.default)(graph.entities[d.id].tags, base.entities[d.id].tags);
50671 }).call(svgTagClasses()).merge(lines).sort(waystack).attr("d", getPath).call(svgTagClasses().tags(svgRelationMemberTags(graph)));
50674 function getPathData(isSelected) {
50675 return function() {
50676 var layer = this.parentNode.__data__;
50677 var data = pathdata[layer] || [];
50678 return data.filter(function(d) {
50680 return context.selectedIDs().indexOf(d.id) !== -1;
50682 return context.selectedIDs().indexOf(d.id) === -1;
50687 function addMarkers(layergroup, pathclass, groupclass, groupdata, marker) {
50688 var markergroup = layergroup.selectAll("g." + groupclass).data([pathclass]);
50689 markergroup = markergroup.enter().append("g").attr("class", groupclass).merge(markergroup);
50690 var markers = markergroup.selectAll("path").filter(filter2).data(
50692 return groupdata[this.parentNode.__data__] || [];
50695 return [d.id, d.index];
50698 markers.exit().remove();
50699 markers = markers.enter().append("path").attr("class", pathclass).merge(markers).attr("marker-mid", marker).attr("d", function(d) {
50703 markers.each(function() {
50704 this.parentNode.insertBefore(this, this);
50708 var getPath = svgPath(projection2, graph);
50710 var onewaydata = {};
50711 var sideddata = {};
50712 var oldMultiPolygonOuters = {};
50713 for (var i2 = 0; i2 < entities.length; i2++) {
50714 var entity = entities[i2];
50715 var outer = osmOldMultipolygonOuterMember(entity, graph);
50717 ways.push(entity.mergeTags(outer.tags));
50718 oldMultiPolygonOuters[outer.id] = true;
50719 } else if (entity.geometry(graph) === "line" || entity.geometry(graph) === "area" && entity.sidednessIdentifier && entity.sidednessIdentifier() === "coastline") {
50723 ways = ways.filter(getPath);
50724 var pathdata = utilArrayGroupBy(ways, function(way) {
50725 return way.layer();
50727 Object.keys(pathdata).forEach(function(k) {
50728 var v = pathdata[k];
50729 var onewayArr = v.filter(function(d) {
50730 return d.isOneWay();
50732 var onewaySegments = svgMarkerSegments(
50736 function shouldReverse(entity2) {
50737 return entity2.tags.oneway === "-1";
50739 function bothDirections(entity2) {
50740 return entity2.tags.oneway === "reversible" || entity2.tags.oneway === "alternating";
50743 onewaydata[k] = utilArrayFlatten(onewayArr.map(onewaySegments));
50744 var sidedArr = v.filter(function(d) {
50745 return d.isSided();
50747 var sidedSegments = svgMarkerSegments(
50751 function shouldReverse() {
50754 function bothDirections() {
50758 sideddata[k] = utilArrayFlatten(sidedArr.map(sidedSegments));
50760 var covered = selection2.selectAll(".layer-osm.covered");
50761 var uncovered = selection2.selectAll(".layer-osm.lines");
50762 var touchLayer = selection2.selectAll(".layer-touch.lines");
50763 [covered, uncovered].forEach(function(selection3) {
50764 var range3 = selection3 === covered ? range(-10, 0) : range(0, 11);
50765 var layergroup = selection3.selectAll("g.layergroup").data(range3);
50766 layergroup = layergroup.enter().append("g").attr("class", function(d) {
50767 return "layergroup layer" + String(d);
50768 }).merge(layergroup);
50769 layergroup.selectAll("g.linegroup").data(["shadow", "casing", "stroke", "shadow-highlighted", "casing-highlighted", "stroke-highlighted"]).enter().append("g").attr("class", function(d) {
50770 return "linegroup line-" + d;
50772 layergroup.selectAll("g.line-shadow").call(drawLineGroup, "shadow", false);
50773 layergroup.selectAll("g.line-casing").call(drawLineGroup, "casing", false);
50774 layergroup.selectAll("g.line-stroke").call(drawLineGroup, "stroke", false);
50775 layergroup.selectAll("g.line-shadow-highlighted").call(drawLineGroup, "shadow", true);
50776 layergroup.selectAll("g.line-casing-highlighted").call(drawLineGroup, "casing", true);
50777 layergroup.selectAll("g.line-stroke-highlighted").call(drawLineGroup, "stroke", true);
50778 addMarkers(layergroup, "oneway", "onewaygroup", onewaydata, "url(#ideditor-oneway-marker)");
50784 function marker(d) {
50785 var category = graph.entity(d.id).sidednessIdentifier();
50786 return "url(#ideditor-sided-marker-" + category + ")";
50790 touchLayer.call(drawTargets, graph, ways, filter2);
50795 // modules/svg/midpoints.js
50796 function svgMidpoints(projection2, context) {
50797 var targetRadius = 8;
50798 function drawTargets(selection2, graph, entities, filter2) {
50799 var fillClass = context.getDebug("target") ? "pink " : "nocolor ";
50800 var getTransform = svgPointTransform(projection2).geojson;
50801 var data = entities.map(function(midpoint) {
50811 coordinates: midpoint.loc
50815 var targets = selection2.selectAll(".midpoint.target").filter(function(d) {
50816 return filter2(d.properties.entity);
50817 }).data(data, function key(d) {
50820 targets.exit().remove();
50821 targets.enter().append("circle").attr("r", targetRadius).merge(targets).attr("class", function(d) {
50822 return "node midpoint target " + fillClass + d.id;
50823 }).attr("transform", getTransform);
50825 function drawMidpoints(selection2, graph, entities, filter2, extent) {
50826 var drawLayer = selection2.selectAll(".layer-osm.points .points-group.midpoints");
50827 var touchLayer = selection2.selectAll(".layer-touch.points");
50828 var mode = context.mode();
50829 if (mode && mode.id !== "select" || !context.map().withinEditableZoom()) {
50830 drawLayer.selectAll(".midpoint").remove();
50831 touchLayer.selectAll(".midpoint.target").remove();
50834 var poly = extent.polygon();
50835 var midpoints = {};
50836 for (var i2 = 0; i2 < entities.length; i2++) {
50837 var entity = entities[i2];
50838 if (entity.type !== "way")
50840 if (!filter2(entity))
50842 if (context.selectedIDs().indexOf(entity.id) < 0)
50844 var nodes = graph.childNodes(entity);
50845 for (var j2 = 0; j2 < nodes.length - 1; j2++) {
50847 var b = nodes[j2 + 1];
50848 var id2 = [a.id, b.id].sort().join("-");
50849 if (midpoints[id2]) {
50850 midpoints[id2].parents.push(entity);
50851 } else if (geoVecLength(projection2(a.loc), projection2(b.loc)) > 40) {
50852 var point2 = geoVecInterp(a.loc, b.loc, 0.5);
50854 if (extent.intersects(point2)) {
50857 for (var k = 0; k < 4; k++) {
50858 point2 = geoLineIntersection([a.loc, b.loc], [poly[k], poly[k + 1]]);
50859 if (point2 && geoVecLength(projection2(a.loc), projection2(point2)) > 20 && geoVecLength(projection2(b.loc), projection2(point2)) > 20) {
50870 edge: [a.id, b.id],
50877 function midpointFilter(d) {
50878 if (midpoints[d.id])
50880 for (var i3 = 0; i3 < d.parents.length; i3++) {
50881 if (filter2(d.parents[i3])) {
50887 var groups = drawLayer.selectAll(".midpoint").filter(midpointFilter).data(Object.values(midpoints), function(d) {
50890 groups.exit().remove();
50891 var enter = groups.enter().insert("g", ":first-child").attr("class", "midpoint");
50892 enter.append("polygon").attr("points", "-6,8 10,0 -6,-8").attr("class", "shadow");
50893 enter.append("polygon").attr("points", "-3,4 5,0 -3,-4").attr("class", "fill");
50894 groups = groups.merge(enter).attr("transform", function(d) {
50895 var translate = svgPointTransform(projection2);
50896 var a2 = graph.entity(d.edge[0]);
50897 var b2 = graph.entity(d.edge[1]);
50898 var angle2 = geoAngle(a2, b2, projection2) * (180 / Math.PI);
50899 return translate(d) + " rotate(" + angle2 + ")";
50900 }).call(svgTagClasses().tags(
50902 return d.parents[0].tags;
50905 groups.select("polygon.shadow");
50906 groups.select("polygon.fill");
50907 touchLayer.call(drawTargets, graph, Object.values(midpoints), midpointFilter);
50909 return drawMidpoints;
50912 // modules/svg/points.js
50913 var import_fast_deep_equal7 = __toESM(require_fast_deep_equal());
50914 function svgPoints(projection2, context) {
50915 function markerPath(selection2, klass) {
50916 selection2.attr("class", klass).attr("transform", "translate(-8, -23)").attr("d", "M 17,8 C 17,13 11,21 8.5,23.5 C 6,21 0,13 0,8 C 0,4 4,-0.5 8.5,-0.5 C 13,-0.5 17,4 17,8 z");
50918 function sortY(a, b) {
50919 return b.loc[1] - a.loc[1];
50921 function fastEntityKey(d) {
50922 var mode = context.mode();
50923 var isMoving = mode && /^(add|draw|drag|move|rotate)/.test(mode.id);
50924 return isMoving ? d.id : osmEntity.key(d);
50926 function drawTargets(selection2, graph, entities, filter2) {
50927 var fillClass = context.getDebug("target") ? "pink " : "nocolor ";
50928 var getTransform = svgPointTransform(projection2).geojson;
50929 var activeID = context.activeID();
50931 entities.forEach(function(node) {
50932 if (activeID === node.id)
50941 geometry: node.asGeoJSON()
50944 var targets = selection2.selectAll(".point.target").filter(function(d) {
50945 return filter2(d.properties.entity);
50946 }).data(data, function key(d) {
50949 targets.exit().remove();
50950 targets.enter().append("rect").attr("x", -10).attr("y", -26).attr("width", 20).attr("height", 30).merge(targets).attr("class", function(d) {
50951 return "node point target " + fillClass + d.id;
50952 }).attr("transform", getTransform);
50954 function drawPoints(selection2, graph, entities, filter2) {
50955 var wireframe = context.surface().classed("fill-wireframe");
50956 var zoom = geoScaleToZoom(projection2.scale());
50957 var base = context.history().base();
50958 function renderAsPoint(entity) {
50959 return entity.geometry(graph) === "point" && !(zoom >= 18 && entity.directions(graph, projection2).length);
50961 var points = wireframe ? [] : entities.filter(renderAsPoint);
50962 points.sort(sortY);
50963 var drawLayer = selection2.selectAll(".layer-osm.points .points-group.points");
50964 var touchLayer = selection2.selectAll(".layer-touch.points");
50965 var groups = drawLayer.selectAll("g.point").filter(filter2).data(points, fastEntityKey);
50966 groups.exit().remove();
50967 var enter = groups.enter().append("g").attr("class", function(d) {
50968 return "node point " + d.id;
50970 enter.append("path").call(markerPath, "shadow");
50971 enter.append("ellipse").attr("cx", 0.5).attr("cy", 1).attr("rx", 6.5).attr("ry", 3).attr("class", "stroke");
50972 enter.append("path").call(markerPath, "stroke");
50973 enter.append("use").attr("transform", "translate(-5.5, -20)").attr("class", "icon").attr("width", "12px").attr("height", "12px");
50974 groups = groups.merge(enter).attr("transform", svgPointTransform(projection2)).classed("added", function(d) {
50975 return !base.entities[d.id];
50976 }).classed("moved", function(d) {
50977 return base.entities[d.id] && !(0, import_fast_deep_equal7.default)(graph.entities[d.id].loc, base.entities[d.id].loc);
50978 }).classed("retagged", function(d) {
50979 return base.entities[d.id] && !(0, import_fast_deep_equal7.default)(graph.entities[d.id].tags, base.entities[d.id].tags);
50980 }).call(svgTagClasses());
50981 groups.select(".shadow");
50982 groups.select(".stroke");
50983 groups.select(".icon").attr("xlink:href", function(entity) {
50984 var preset = _mainPresetIndex.match(entity, graph);
50985 var picon = preset && preset.icon;
50986 return picon ? "#" + picon : "";
50988 touchLayer.call(drawTargets, graph, points, filter2);
50993 // modules/svg/turns.js
50994 function svgTurns(projection2, context) {
50995 function icon2(turn) {
50996 var u = turn.u ? "-u" : "";
50998 return "#iD-turn-no" + u;
51000 return "#iD-turn-only" + u;
51001 return "#iD-turn-yes" + u;
51003 function drawTurns(selection2, graph, turns) {
51004 function turnTransform(d) {
51006 var toWay = graph.entity(d.to.way);
51007 var toPoints = graph.childNodes(toWay).map(function(n2) {
51009 }).map(projection2);
51010 var toLength = geoPathLength(toPoints);
51011 var mid = toLength / 2;
51012 var toNode = graph.entity(d.to.node);
51013 var toVertex = graph.entity(d.to.vertex);
51014 var a = geoAngle(toVertex, toNode, projection2);
51015 var o = projection2(toVertex.loc);
51016 var r = d.u ? 0 : !toWay.__via ? pxRadius : Math.min(mid, pxRadius);
51017 return "translate(" + (r * Math.cos(a) + o[0]) + "," + (r * Math.sin(a) + o[1]) + ") rotate(" + a * 180 / Math.PI + ")";
51019 var drawLayer = selection2.selectAll(".layer-osm.points .points-group.turns");
51020 var touchLayer = selection2.selectAll(".layer-touch.turns");
51021 var groups = drawLayer.selectAll("g.turn").data(turns, function(d) {
51024 groups.exit().remove();
51025 var groupsEnter = groups.enter().append("g").attr("class", function(d) {
51026 return "turn " + d.key;
51028 var turnsEnter = groupsEnter.filter(function(d) {
51031 turnsEnter.append("rect").attr("transform", "translate(-22, -12)").attr("width", "44").attr("height", "24");
51032 turnsEnter.append("use").attr("transform", "translate(-22, -12)").attr("width", "44").attr("height", "24");
51033 var uEnter = groupsEnter.filter(function(d) {
51036 uEnter.append("circle").attr("r", "16");
51037 uEnter.append("use").attr("transform", "translate(-16, -16)").attr("width", "32").attr("height", "32");
51038 groups = groups.merge(groupsEnter).attr("opacity", function(d) {
51039 return d.direct === false ? "0.7" : null;
51040 }).attr("transform", turnTransform);
51041 groups.select("use").attr("xlink:href", icon2);
51042 groups.select("rect");
51043 groups.select("circle");
51044 var fillClass = context.getDebug("target") ? "pink " : "nocolor ";
51045 groups = touchLayer.selectAll("g.turn").data(turns, function(d) {
51048 groups.exit().remove();
51049 groupsEnter = groups.enter().append("g").attr("class", function(d) {
51050 return "turn " + d.key;
51052 turnsEnter = groupsEnter.filter(function(d) {
51055 turnsEnter.append("rect").attr("class", "target " + fillClass).attr("transform", "translate(-22, -12)").attr("width", "44").attr("height", "24");
51056 uEnter = groupsEnter.filter(function(d) {
51059 uEnter.append("circle").attr("class", "target " + fillClass).attr("r", "16");
51060 groups = groups.merge(groupsEnter).attr("transform", turnTransform);
51061 groups.select("rect");
51062 groups.select("circle");
51068 // modules/svg/vertices.js
51069 var import_fast_deep_equal8 = __toESM(require_fast_deep_equal());
51070 function svgVertices(projection2, context) {
51072 // z16-, z17, z18+, w/icon
51073 shadow: [6, 7.5, 7.5, 12],
51074 stroke: [2.5, 3.5, 3.5, 8],
51075 fill: [1, 1.5, 1.5, 1.5]
51077 var _currHoverTarget;
51078 var _currPersistent = {};
51079 var _currHover = {};
51080 var _prevHover = {};
51081 var _currSelected = {};
51082 var _prevSelected = {};
51084 function sortY(a, b) {
51085 return b.loc[1] - a.loc[1];
51087 function fastEntityKey(d) {
51088 var mode = context.mode();
51089 var isMoving = mode && /^(add|draw|drag|move|rotate)/.test(mode.id);
51090 return isMoving ? d.id : osmEntity.key(d);
51092 function draw(selection2, graph, vertices, sets2, filter2) {
51093 sets2 = sets2 || { selected: {}, important: {}, hovered: {} };
51095 var directions = {};
51096 var wireframe = context.surface().classed("fill-wireframe");
51097 var zoom = geoScaleToZoom(projection2.scale());
51098 var z = zoom < 17 ? 0 : zoom < 18 ? 1 : 2;
51099 var activeID = context.activeID();
51100 var base = context.history().base();
51101 function getIcon(d) {
51102 var entity = graph.entity(d.id);
51103 if (entity.id in icons)
51104 return icons[entity.id];
51105 icons[entity.id] = entity.hasInterestingTags() && _mainPresetIndex.match(entity, graph).icon;
51106 return icons[entity.id];
51108 function getDirections(entity) {
51109 if (entity.id in directions)
51110 return directions[entity.id];
51111 var angles = entity.directions(graph, projection2);
51112 directions[entity.id] = angles.length ? angles : false;
51115 function updateAttributes(selection3) {
51116 ["shadow", "stroke", "fill"].forEach(function(klass) {
51117 var rads = radiuses[klass];
51118 selection3.selectAll("." + klass).each(function(entity) {
51119 var i2 = z && getIcon(entity);
51120 var r = rads[i2 ? 3 : z];
51121 if (entity.id !== activeID && entity.isEndpoint(graph) && !entity.isConnected(graph)) {
51124 if (klass === "shadow") {
51125 _radii[entity.id] = r;
51127 select_default2(this).attr("r", r).attr("visibility", i2 && klass === "fill" ? "hidden" : null);
51131 vertices.sort(sortY);
51132 var groups = selection2.selectAll("g.vertex").filter(filter2).data(vertices, fastEntityKey);
51133 groups.exit().remove();
51134 var enter = groups.enter().append("g").attr("class", function(d) {
51135 return "node vertex " + d.id;
51137 enter.append("circle").attr("class", "shadow");
51138 enter.append("circle").attr("class", "stroke");
51139 enter.filter(function(d) {
51140 return d.hasInterestingTags();
51141 }).append("circle").attr("class", "fill");
51142 groups = groups.merge(enter).attr("transform", svgPointTransform(projection2)).classed("sibling", function(d) {
51143 return d.id in sets2.selected;
51144 }).classed("shared", function(d) {
51145 return graph.isShared(d);
51146 }).classed("endpoint", function(d) {
51147 return d.isEndpoint(graph);
51148 }).classed("added", function(d) {
51149 return !base.entities[d.id];
51150 }).classed("moved", function(d) {
51151 return base.entities[d.id] && !(0, import_fast_deep_equal8.default)(graph.entities[d.id].loc, base.entities[d.id].loc);
51152 }).classed("retagged", function(d) {
51153 return base.entities[d.id] && !(0, import_fast_deep_equal8.default)(graph.entities[d.id].tags, base.entities[d.id].tags);
51154 }).call(updateAttributes);
51155 var iconUse = groups.selectAll(".icon").data(function data(d) {
51156 return zoom >= 17 && getIcon(d) ? [d] : [];
51158 iconUse.exit().remove();
51159 iconUse.enter().append("use").attr("class", "icon").attr("width", "12px").attr("height", "12px").attr("transform", "translate(-6, -6)").attr("xlink:href", function(d) {
51160 var picon = getIcon(d);
51161 return picon ? "#" + picon : "";
51163 var dgroups = groups.selectAll(".viewfieldgroup").data(function data(d) {
51164 return zoom >= 18 && getDirections(d) ? [d] : [];
51166 dgroups.exit().remove();
51167 dgroups = dgroups.enter().insert("g", ".shadow").attr("class", "viewfieldgroup").merge(dgroups);
51168 var viewfields = dgroups.selectAll(".viewfield").data(getDirections, function key(d) {
51169 return osmEntity.key(d);
51171 viewfields.exit().remove();
51172 viewfields.enter().append("path").attr("class", "viewfield").attr("d", "M0,0H0").merge(viewfields).attr("marker-start", "url(#ideditor-viewfield-marker" + (wireframe ? "-wireframe" : "") + ")").attr("transform", function(d) {
51173 return "rotate(" + d + ")";
51176 function drawTargets(selection2, graph, entities, filter2) {
51177 var targetClass = context.getDebug("target") ? "pink " : "nocolor ";
51178 var nopeClass = context.getDebug("target") ? "red " : "nocolor ";
51179 var getTransform = svgPointTransform(projection2).geojson;
51180 var activeID = context.activeID();
51181 var data = { targets: [], nopes: [] };
51182 entities.forEach(function(node) {
51183 if (activeID === node.id)
51185 var vertexType = svgPassiveVertex(node, graph, activeID);
51186 if (vertexType !== 0) {
51187 data.targets.push({
51194 geometry: node.asGeoJSON()
51199 id: node.id + "-nope",
51205 geometry: node.asGeoJSON()
51209 var targets = selection2.selectAll(".vertex.target-allowed").filter(function(d) {
51210 return filter2(d.properties.entity);
51211 }).data(data.targets, function key(d) {
51214 targets.exit().remove();
51215 targets.enter().append("circle").attr("r", function(d) {
51216 return _radii[d.id] || radiuses.shadow[3];
51217 }).merge(targets).attr("class", function(d) {
51218 return "node vertex target target-allowed " + targetClass + d.id;
51219 }).attr("transform", getTransform);
51220 var nopes = selection2.selectAll(".vertex.target-nope").filter(function(d) {
51221 return filter2(d.properties.entity);
51222 }).data(data.nopes, function key(d) {
51225 nopes.exit().remove();
51226 nopes.enter().append("circle").attr("r", function(d) {
51227 return _radii[d.properties.entity.id] || radiuses.shadow[3];
51228 }).merge(nopes).attr("class", function(d) {
51229 return "node vertex target target-nope " + nopeClass + d.id;
51230 }).attr("transform", getTransform);
51232 function renderAsVertex(entity, graph, wireframe, zoom) {
51233 var geometry = entity.geometry(graph);
51234 return geometry === "vertex" || geometry === "point" && (wireframe || zoom >= 18 && entity.directions(graph, projection2).length);
51236 function isEditedNode(node, base, head) {
51237 var baseNode = base.entities[node.id];
51238 var headNode = head.entities[node.id];
51239 return !headNode || !baseNode || !(0, import_fast_deep_equal8.default)(headNode.tags, baseNode.tags) || !(0, import_fast_deep_equal8.default)(headNode.loc, baseNode.loc);
51241 function getSiblingAndChildVertices(ids, graph, wireframe, zoom) {
51244 function addChildVertices(entity) {
51245 if (seenIds[entity.id])
51247 seenIds[entity.id] = true;
51248 var geometry = entity.geometry(graph);
51249 if (!context.features().isHiddenFeature(entity, graph, geometry)) {
51251 if (entity.type === "way") {
51252 for (i2 = 0; i2 < entity.nodes.length; i2++) {
51253 var child = graph.hasEntity(entity.nodes[i2]);
51255 addChildVertices(child);
51258 } else if (entity.type === "relation") {
51259 for (i2 = 0; i2 < entity.members.length; i2++) {
51260 var member = graph.hasEntity(entity.members[i2].id);
51262 addChildVertices(member);
51265 } else if (renderAsVertex(entity, graph, wireframe, zoom)) {
51266 results[entity.id] = entity;
51270 ids.forEach(function(id2) {
51271 var entity = graph.hasEntity(id2);
51274 if (entity.type === "node") {
51275 if (renderAsVertex(entity, graph, wireframe, zoom)) {
51276 results[entity.id] = entity;
51277 graph.parentWays(entity).forEach(function(entity2) {
51278 addChildVertices(entity2);
51282 addChildVertices(entity);
51287 function drawVertices(selection2, graph, entities, filter2, extent, fullRedraw) {
51288 var wireframe = context.surface().classed("fill-wireframe");
51289 var visualDiff = context.surface().classed("highlight-edited");
51290 var zoom = geoScaleToZoom(projection2.scale());
51291 var mode = context.mode();
51292 var isMoving = mode && /^(add|draw|drag|move|rotate)/.test(mode.id);
51293 var base = context.history().base();
51294 var drawLayer = selection2.selectAll(".layer-osm.points .points-group.vertices");
51295 var touchLayer = selection2.selectAll(".layer-touch.points");
51297 _currPersistent = {};
51300 for (var i2 = 0; i2 < entities.length; i2++) {
51301 var entity = entities[i2];
51302 var geometry = entity.geometry(graph);
51304 if (geometry === "point" && renderAsVertex(entity, graph, wireframe, zoom)) {
51305 _currPersistent[entity.id] = entity;
51307 } else if (geometry === "vertex" && (entity.hasInterestingTags() || entity.isEndpoint(graph) || entity.isConnected(graph) || visualDiff && isEditedNode(entity, base, graph))) {
51308 _currPersistent[entity.id] = entity;
51311 if (!keep && !fullRedraw) {
51312 delete _currPersistent[entity.id];
51316 persistent: _currPersistent,
51317 // persistent = important vertices (render always)
51318 selected: _currSelected,
51319 // selected + siblings of selected (render always)
51320 hovered: _currHover
51321 // hovered + siblings of hovered (render only in draw modes)
51323 var all = Object.assign({}, isMoving ? _currHover : {}, _currSelected, _currPersistent);
51324 var filterRendered = function(d) {
51325 return d.id in _currPersistent || d.id in _currSelected || d.id in _currHover || filter2(d);
51327 drawLayer.call(draw, graph, currentVisible(all), sets2, filterRendered);
51328 var filterTouch = function(d) {
51329 return isMoving ? true : filterRendered(d);
51331 touchLayer.call(drawTargets, graph, currentVisible(all), filterTouch);
51332 function currentVisible(which) {
51333 return Object.keys(which).map(graph.hasEntity, graph).filter(function(entity2) {
51334 return entity2 && entity2.intersects(extent, graph);
51338 drawVertices.drawSelected = function(selection2, graph, extent) {
51339 var wireframe = context.surface().classed("fill-wireframe");
51340 var zoom = geoScaleToZoom(projection2.scale());
51341 _prevSelected = _currSelected || {};
51342 if (context.map().isInWideSelection()) {
51343 _currSelected = {};
51344 context.selectedIDs().forEach(function(id2) {
51345 var entity = graph.hasEntity(id2);
51348 if (entity.type === "node") {
51349 if (renderAsVertex(entity, graph, wireframe, zoom)) {
51350 _currSelected[entity.id] = entity;
51355 _currSelected = getSiblingAndChildVertices(context.selectedIDs(), graph, wireframe, zoom);
51357 var filter2 = function(d) {
51358 return d.id in _prevSelected;
51360 drawVertices(selection2, graph, Object.values(_prevSelected), filter2, extent, false);
51362 drawVertices.drawHover = function(selection2, graph, target, extent) {
51363 if (target === _currHoverTarget)
51365 var wireframe = context.surface().classed("fill-wireframe");
51366 var zoom = geoScaleToZoom(projection2.scale());
51367 _prevHover = _currHover || {};
51368 _currHoverTarget = target;
51369 var entity = target && target.properties && target.properties.entity;
51371 _currHover = getSiblingAndChildVertices([entity.id], graph, wireframe, zoom);
51375 var filter2 = function(d) {
51376 return d.id in _prevHover;
51378 drawVertices(selection2, graph, Object.values(_prevHover), filter2, extent, false);
51380 return drawVertices;
51383 // modules/util/bind_once.js
51384 function utilBindOnce(target, type2, listener, capture) {
51385 var typeOnce = type2 + ".once";
51387 target.on(typeOnce, null);
51388 listener.apply(this, arguments);
51390 target.on(typeOnce, one2, capture);
51394 // modules/util/zoom_pan.js
51395 function defaultFilter3(d3_event) {
51396 return !d3_event.ctrlKey && !d3_event.button;
51398 function defaultExtent2() {
51400 if (e instanceof SVGElement) {
51401 e = e.ownerSVGElement || e;
51402 if (e.hasAttribute("viewBox")) {
51403 e = e.viewBox.baseVal;
51404 return [[e.x, e.y], [e.x + e.width, e.y + e.height]];
51406 return [[0, 0], [e.width.baseVal.value, e.height.baseVal.value]];
51408 return [[0, 0], [e.clientWidth, e.clientHeight]];
51410 function defaultWheelDelta2(d3_event) {
51411 return -d3_event.deltaY * (d3_event.deltaMode === 1 ? 0.05 : d3_event.deltaMode ? 1 : 2e-3);
51413 function defaultConstrain2(transform2, extent, translateExtent) {
51414 var dx0 = transform2.invertX(extent[0][0]) - translateExtent[0][0], dx1 = transform2.invertX(extent[1][0]) - translateExtent[1][0], dy0 = transform2.invertY(extent[0][1]) - translateExtent[0][1], dy1 = transform2.invertY(extent[1][1]) - translateExtent[1][1];
51415 return transform2.translate(
51416 dx1 > dx0 ? (dx0 + dx1) / 2 : Math.min(0, dx0) || Math.max(0, dx1),
51417 dy1 > dy0 ? (dy0 + dy1) / 2 : Math.min(0, dy0) || Math.max(0, dy1)
51420 function utilZoomPan() {
51421 var filter2 = defaultFilter3, extent = defaultExtent2, constrain = defaultConstrain2, wheelDelta = defaultWheelDelta2, scaleExtent = [0, Infinity], translateExtent = [[-Infinity, -Infinity], [Infinity, Infinity]], interpolate = zoom_default, dispatch10 = dispatch_default("start", "zoom", "end"), _wheelDelay = 150, _transform = identity2, _activeGesture;
51422 function zoom(selection2) {
51423 selection2.on("pointerdown.zoom", pointerdown).on("wheel.zoom", wheeled).style("touch-action", "none").style("-webkit-tap-highlight-color", "rgba(0,0,0,0)");
51424 select_default2(window).on("pointermove.zoompan", pointermove).on("pointerup.zoompan pointercancel.zoompan", pointerup);
51426 zoom.transform = function(collection, transform2, point2) {
51427 var selection2 = collection.selection ? collection.selection() : collection;
51428 if (collection !== selection2) {
51429 schedule(collection, transform2, point2);
51431 selection2.interrupt().each(function() {
51432 gesture(this, arguments).start(null).zoom(null, null, typeof transform2 === "function" ? transform2.apply(this, arguments) : transform2).end(null);
51436 zoom.scaleBy = function(selection2, k, p) {
51437 zoom.scaleTo(selection2, function() {
51438 var k0 = _transform.k, k1 = typeof k === "function" ? k.apply(this, arguments) : k;
51442 zoom.scaleTo = function(selection2, k, p) {
51443 zoom.transform(selection2, function() {
51444 var e = extent.apply(this, arguments), t0 = _transform, p02 = !p ? centroid(e) : typeof p === "function" ? p.apply(this, arguments) : p, p1 = t0.invert(p02), k1 = typeof k === "function" ? k.apply(this, arguments) : k;
51445 return constrain(translate(scale(t0, k1), p02, p1), e, translateExtent);
51448 zoom.translateBy = function(selection2, x, y) {
51449 zoom.transform(selection2, function() {
51450 return constrain(_transform.translate(
51451 typeof x === "function" ? x.apply(this, arguments) : x,
51452 typeof y === "function" ? y.apply(this, arguments) : y
51453 ), extent.apply(this, arguments), translateExtent);
51456 zoom.translateTo = function(selection2, x, y, p) {
51457 zoom.transform(selection2, function() {
51458 var e = extent.apply(this, arguments), t = _transform, p02 = !p ? centroid(e) : typeof p === "function" ? p.apply(this, arguments) : p;
51459 return constrain(identity2.translate(p02[0], p02[1]).scale(t.k).translate(
51460 typeof x === "function" ? -x.apply(this, arguments) : -x,
51461 typeof y === "function" ? -y.apply(this, arguments) : -y
51462 ), e, translateExtent);
51465 function scale(transform2, k) {
51466 k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], k));
51467 return k === transform2.k ? transform2 : new Transform(k, transform2.x, transform2.y);
51469 function translate(transform2, p02, p1) {
51470 var x = p02[0] - p1[0] * transform2.k, y = p02[1] - p1[1] * transform2.k;
51471 return x === transform2.x && y === transform2.y ? transform2 : new Transform(transform2.k, x, y);
51473 function centroid(extent2) {
51474 return [(+extent2[0][0] + +extent2[1][0]) / 2, (+extent2[0][1] + +extent2[1][1]) / 2];
51476 function schedule(transition2, transform2, point2) {
51477 transition2.on("start.zoom", function() {
51478 gesture(this, arguments).start(null);
51479 }).on("interrupt.zoom end.zoom", function() {
51480 gesture(this, arguments).end(null);
51481 }).tween("zoom", function() {
51482 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));
51483 return function(t) {
51489 t = new Transform(k, p[0] - l[0] * k, p[1] - l[1] * k);
51491 g.zoom(null, null, t);
51495 function gesture(that, args, clean2) {
51496 return !clean2 && _activeGesture || new Gesture(that, args);
51498 function Gesture(that, args) {
51502 this.extent = extent.apply(that, args);
51504 Gesture.prototype = {
51505 start: function(d3_event) {
51506 if (++this.active === 1) {
51507 _activeGesture = this;
51508 dispatch10.call("start", this, d3_event);
51512 zoom: function(d3_event, key, transform2) {
51513 if (this.mouse && key !== "mouse")
51514 this.mouse[1] = transform2.invert(this.mouse[0]);
51515 if (this.pointer0 && key !== "touch")
51516 this.pointer0[1] = transform2.invert(this.pointer0[0]);
51517 if (this.pointer1 && key !== "touch")
51518 this.pointer1[1] = transform2.invert(this.pointer1[0]);
51519 _transform = transform2;
51520 dispatch10.call("zoom", this, d3_event, key, transform2);
51523 end: function(d3_event) {
51524 if (--this.active === 0) {
51525 _activeGesture = null;
51526 dispatch10.call("end", this, d3_event);
51531 function wheeled(d3_event) {
51532 if (!filter2.apply(this, arguments))
51534 var g = gesture(this, arguments), t = _transform, k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], t.k * Math.pow(2, wheelDelta.apply(this, arguments)))), p = utilFastMouse(this)(d3_event);
51536 if (g.mouse[0][0] !== p[0] || g.mouse[0][1] !== p[1]) {
51537 g.mouse[1] = t.invert(g.mouse[0] = p);
51539 clearTimeout(g.wheel);
51541 g.mouse = [p, t.invert(p)];
51542 interrupt_default(this);
51545 d3_event.preventDefault();
51546 d3_event.stopImmediatePropagation();
51547 g.wheel = setTimeout(wheelidled, _wheelDelay);
51548 g.zoom(d3_event, "mouse", constrain(translate(scale(t, k), g.mouse[0], g.mouse[1]), g.extent, translateExtent));
51549 function wheelidled() {
51554 var _downPointerIDs = /* @__PURE__ */ new Set();
51555 var _pointerLocGetter;
51556 function pointerdown(d3_event) {
51557 _downPointerIDs.add(d3_event.pointerId);
51558 if (!filter2.apply(this, arguments))
51560 var g = gesture(this, arguments, _downPointerIDs.size === 1);
51562 d3_event.stopImmediatePropagation();
51563 _pointerLocGetter = utilFastMouse(this);
51564 var loc = _pointerLocGetter(d3_event);
51565 var p = [loc, _transform.invert(loc), d3_event.pointerId];
51569 } else if (!g.pointer1 && g.pointer0[2] !== p[2]) {
51573 interrupt_default(this);
51577 function pointermove(d3_event) {
51578 if (!_downPointerIDs.has(d3_event.pointerId))
51580 if (!_activeGesture || !_pointerLocGetter)
51582 var g = gesture(this, arguments);
51583 var isPointer0 = g.pointer0 && g.pointer0[2] === d3_event.pointerId;
51584 var isPointer1 = !isPointer0 && g.pointer1 && g.pointer1[2] === d3_event.pointerId;
51585 if ((isPointer0 || isPointer1) && "buttons" in d3_event && !d3_event.buttons) {
51587 _downPointerIDs.delete(g.pointer0[2]);
51589 _downPointerIDs.delete(g.pointer1[2]);
51593 d3_event.preventDefault();
51594 d3_event.stopImmediatePropagation();
51595 var loc = _pointerLocGetter(d3_event);
51598 g.pointer0[0] = loc;
51599 else if (isPointer1)
51600 g.pointer1[0] = loc;
51603 var p02 = g.pointer0[0], l0 = g.pointer0[1], p1 = g.pointer1[0], l1 = g.pointer1[1], dp = (dp = p1[0] - p02[0]) * dp + (dp = p1[1] - p02[1]) * dp, dl = (dl = l1[0] - l0[0]) * dl + (dl = l1[1] - l0[1]) * dl;
51604 t = scale(t, Math.sqrt(dp / dl));
51605 p = [(p02[0] + p1[0]) / 2, (p02[1] + p1[1]) / 2];
51606 l = [(l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2];
51607 } else if (g.pointer0) {
51613 g.zoom(d3_event, "touch", constrain(translate(t, p, l), g.extent, translateExtent));
51615 function pointerup(d3_event) {
51616 if (!_downPointerIDs.has(d3_event.pointerId))
51618 _downPointerIDs.delete(d3_event.pointerId);
51619 if (!_activeGesture)
51621 var g = gesture(this, arguments);
51622 d3_event.stopImmediatePropagation();
51623 if (g.pointer0 && g.pointer0[2] === d3_event.pointerId)
51625 else if (g.pointer1 && g.pointer1[2] === d3_event.pointerId)
51627 if (g.pointer1 && !g.pointer0) {
51628 g.pointer0 = g.pointer1;
51632 g.pointer0[1] = _transform.invert(g.pointer0[0]);
51637 zoom.wheelDelta = function(_) {
51638 return arguments.length ? (wheelDelta = utilFunctor(+_), zoom) : wheelDelta;
51640 zoom.filter = function(_) {
51641 return arguments.length ? (filter2 = utilFunctor(!!_), zoom) : filter2;
51643 zoom.extent = function(_) {
51644 return arguments.length ? (extent = utilFunctor([[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]]), zoom) : extent;
51646 zoom.scaleExtent = function(_) {
51647 return arguments.length ? (scaleExtent[0] = +_[0], scaleExtent[1] = +_[1], zoom) : [scaleExtent[0], scaleExtent[1]];
51649 zoom.translateExtent = function(_) {
51650 return arguments.length ? (translateExtent[0][0] = +_[0][0], translateExtent[1][0] = +_[1][0], translateExtent[0][1] = +_[0][1], translateExtent[1][1] = +_[1][1], zoom) : [[translateExtent[0][0], translateExtent[0][1]], [translateExtent[1][0], translateExtent[1][1]]];
51652 zoom.constrain = function(_) {
51653 return arguments.length ? (constrain = _, zoom) : constrain;
51655 zoom.interpolate = function(_) {
51656 return arguments.length ? (interpolate = _, zoom) : interpolate;
51658 zoom._transform = function(_) {
51659 return arguments.length ? (_transform = _, zoom) : _transform;
51661 return utilRebind(zoom, dispatch10, "on");
51664 // modules/util/double_up.js
51665 function utilDoubleUp() {
51666 var dispatch10 = dispatch_default("doubleUp");
51667 var _maxTimespan = 500;
51668 var _maxDistance = 20;
51670 function pointerIsValidFor(loc) {
51671 return (/* @__PURE__ */ new Date()).getTime() - _pointer.startTime <= _maxTimespan && // all pointer events must occur within a small distance of the first pointerdown
51672 geoVecLength(_pointer.startLoc, loc) <= _maxDistance;
51674 function pointerdown(d3_event) {
51675 if (d3_event.ctrlKey || d3_event.button === 2)
51677 var loc = [d3_event.clientX, d3_event.clientY];
51678 if (_pointer && !pointerIsValidFor(loc)) {
51684 startTime: (/* @__PURE__ */ new Date()).getTime(),
51686 pointerId: d3_event.pointerId
51689 _pointer.pointerId = d3_event.pointerId;
51692 function pointerup(d3_event) {
51693 if (d3_event.ctrlKey || d3_event.button === 2)
51695 if (!_pointer || _pointer.pointerId !== d3_event.pointerId)
51697 _pointer.upCount += 1;
51698 if (_pointer.upCount === 2) {
51699 var loc = [d3_event.clientX, d3_event.clientY];
51700 if (pointerIsValidFor(loc)) {
51701 var locInThis = utilFastMouse(this)(d3_event);
51702 dispatch10.call("doubleUp", this, d3_event, locInThis);
51707 function doubleUp(selection2) {
51708 if ("PointerEvent" in window) {
51709 selection2.on("pointerdown.doubleUp", pointerdown).on("pointerup.doubleUp", pointerup);
51711 selection2.on("dblclick.doubleUp", function(d3_event) {
51712 dispatch10.call("doubleUp", this, d3_event, utilFastMouse(this)(d3_event));
51716 doubleUp.off = function(selection2) {
51717 selection2.on("pointerdown.doubleUp", null).on("pointerup.doubleUp", null).on("dblclick.doubleUp", null);
51719 return utilRebind(doubleUp, dispatch10, "on");
51722 // modules/renderer/map.js
51723 var TILESIZE = 256;
51726 var kMin = geoZoomToScale(minZoom2, TILESIZE);
51727 var kMax = geoZoomToScale(maxZoom, TILESIZE);
51728 function clamp(num, min3, max3) {
51729 return Math.max(min3, Math.min(num, max3));
51731 function rendererMap(context) {
51732 var dispatch10 = dispatch_default(
51735 "crossEditableZoom",
51737 "changeHighlighting",
51740 var projection2 = context.projection;
51741 var curtainProjection = context.curtainProjection;
51749 var _selection = select_default2(null);
51750 var supersurface = select_default2(null);
51751 var wrapper = select_default2(null);
51752 var surface = select_default2(null);
51753 var _dimensions = [1, 1];
51754 var _dblClickZoomEnabled = true;
51755 var _redrawEnabled = true;
51756 var _gestureTransformStart;
51757 var _transformStart = projection2.transform();
51758 var _transformLast;
51759 var _isTransformed = false;
51761 var _getMouseCoords;
51762 var _lastPointerEvent;
51763 var _lastWithinEditableZoom;
51764 var _pointerDown = false;
51765 var _pointerPrefix = "PointerEvent" in window ? "pointer" : "mouse";
51766 var _zoomerPannerFunction = "PointerEvent" in window ? utilZoomPan : zoom_default2;
51767 var _zoomerPanner = _zoomerPannerFunction().scaleExtent([kMin, kMax]).interpolate(value_default).filter(zoomEventFilter).on("zoom.map", zoomPan).on("start.map", function(d3_event) {
51768 _pointerDown = d3_event && (d3_event.type === "pointerdown" || d3_event.sourceEvent && d3_event.sourceEvent.type === "pointerdown");
51769 }).on("end.map", function() {
51770 _pointerDown = false;
51772 var _doubleUpHandler = utilDoubleUp();
51773 var scheduleRedraw = throttle_default(redraw, 750);
51774 function cancelPendingRedraw() {
51775 scheduleRedraw.cancel();
51777 function map2(selection2) {
51778 _selection = selection2;
51779 context.on("change.map", immediateRedraw);
51780 var osm = context.connection();
51782 osm.on("change.map", immediateRedraw);
51784 function didUndoOrRedo(targetTransform) {
51785 var mode = context.mode().id;
51786 if (mode !== "browse" && mode !== "select")
51788 if (targetTransform) {
51789 map2.transformEase(targetTransform);
51792 context.history().on("merge.map", function() {
51794 }).on("change.map", immediateRedraw).on("undone.map", function(stack, fromStack) {
51795 didUndoOrRedo(fromStack.transform);
51796 }).on("redone.map", function(stack) {
51797 didUndoOrRedo(stack.transform);
51799 context.background().on("change.map", immediateRedraw);
51800 context.features().on("redraw.map", immediateRedraw);
51801 drawLayers.on("change.map", function() {
51802 context.background().updateImagery();
51805 selection2.on("wheel.map mousewheel.map", function(d3_event) {
51806 d3_event.preventDefault();
51807 }).call(_zoomerPanner).call(_zoomerPanner.transform, projection2.transform()).on("dblclick.zoom", null);
51808 map2.supersurface = supersurface = selection2.append("div").attr("class", "supersurface").call(utilSetTransform, 0, 0);
51809 wrapper = supersurface.append("div").attr("class", "layer layer-data");
51810 map2.surface = surface = wrapper.call(drawLayers).selectAll(".surface");
51811 surface.call(drawLabels.observe).call(_doubleUpHandler).on(_pointerPrefix + "down.zoom", function(d3_event) {
51812 _lastPointerEvent = d3_event;
51813 if (d3_event.button === 2) {
51814 d3_event.stopPropagation();
51816 }, true).on(_pointerPrefix + "up.zoom", function(d3_event) {
51817 _lastPointerEvent = d3_event;
51818 if (resetTransform()) {
51821 }).on(_pointerPrefix + "move.map", function(d3_event) {
51822 _lastPointerEvent = d3_event;
51823 }).on(_pointerPrefix + "over.vertices", function(d3_event) {
51824 if (map2.editableDataEnabled() && !_isTransformed) {
51825 var hover = d3_event.target.__data__;
51826 surface.call(drawVertices.drawHover, context.graph(), hover, map2.extent());
51827 dispatch10.call("drawn", this, { full: false });
51829 }).on(_pointerPrefix + "out.vertices", function(d3_event) {
51830 if (map2.editableDataEnabled() && !_isTransformed) {
51831 var hover = d3_event.relatedTarget && d3_event.relatedTarget.__data__;
51832 surface.call(drawVertices.drawHover, context.graph(), hover, map2.extent());
51833 dispatch10.call("drawn", this, { full: false });
51836 var detected = utilDetect();
51837 if ("GestureEvent" in window && // Listening for gesture events on iOS 13.4+ breaks double-tapping,
51838 // but we only need to do this on desktop Safari anyway. – #7694
51839 !detected.isMobileWebKit) {
51840 surface.on("gesturestart.surface", function(d3_event) {
51841 d3_event.preventDefault();
51842 _gestureTransformStart = projection2.transform();
51843 }).on("gesturechange.surface", gestureChange);
51846 _doubleUpHandler.on("doubleUp.map", function(d3_event, p02) {
51847 if (!_dblClickZoomEnabled)
51849 if (typeof d3_event.target.__data__ === "object" && // or area fills
51850 !select_default2(d3_event.target).classed("fill"))
51852 var zoomOut2 = d3_event.shiftKey;
51853 var t = projection2.transform();
51854 var p1 = t.invert(p02);
51855 t = t.scale(zoomOut2 ? 0.5 : 2);
51856 t.x = p02[0] - p1[0] * t.k;
51857 t.y = p02[1] - p1[1] * t.k;
51858 map2.transformEase(t);
51860 context.on("enter.map", function() {
51861 if (!map2.editableDataEnabled(
51863 /* skip zoom check */
51866 if (_isTransformed)
51868 var graph = context.graph();
51869 var selectedAndParents = {};
51870 context.selectedIDs().forEach(function(id2) {
51871 var entity = graph.hasEntity(id2);
51873 selectedAndParents[entity.id] = entity;
51874 if (entity.type === "node") {
51875 graph.parentWays(entity).forEach(function(parent) {
51876 selectedAndParents[parent.id] = parent;
51881 var data = Object.values(selectedAndParents);
51882 var filter2 = function(d) {
51883 return d.id in selectedAndParents;
51885 data = context.features().filter(data, graph);
51886 surface.call(drawVertices.drawSelected, graph, map2.extent()).call(drawLines, graph, data, filter2).call(drawAreas, graph, data, filter2).call(drawMidpoints, graph, data, filter2, map2.trimmedExtent());
51887 dispatch10.call("drawn", this, { full: false });
51890 map2.dimensions(utilGetDimensions(selection2));
51892 function zoomEventFilter(d3_event) {
51893 if (d3_event.type === "mousedown") {
51894 var hasOrphan = false;
51895 var listeners = window.__on;
51896 for (var i2 = 0; i2 < listeners.length; i2++) {
51897 var listener = listeners[i2];
51898 if (listener.name === "zoom" && listener.type === "mouseup") {
51904 var event = window.CustomEvent;
51906 event = new event("mouseup");
51908 event = window.document.createEvent("Event");
51909 event.initEvent("mouseup", false, false);
51911 event.view = window;
51912 window.dispatchEvent(event);
51915 return d3_event.button !== 2;
51917 function pxCenter() {
51918 return [_dimensions[0] / 2, _dimensions[1] / 2];
51920 function drawEditable(difference, extent) {
51921 var mode = context.mode();
51922 var graph = context.graph();
51923 var features = context.features();
51924 var all = context.history().intersects(map2.extent());
51925 var fullRedraw = false;
51929 var applyFeatureLayerFilters = true;
51930 if (map2.isInWideSelection()) {
51932 utilEntityAndDeepMemberIDs(mode.selectedIDs(), context.graph()).forEach(function(id2) {
51933 var entity = context.hasEntity(id2);
51938 filter2 = utilFunctor(true);
51939 applyFeatureLayerFilters = false;
51940 } else if (difference) {
51941 var complete = difference.complete(map2.extent());
51942 data = Object.values(complete).filter(Boolean);
51943 set3 = new Set(Object.keys(complete));
51944 filter2 = function(d) {
51945 return set3.has(d.id);
51947 features.clear(data);
51949 if (features.gatherStats(all, graph, _dimensions)) {
51953 data = context.history().intersects(map2.extent().intersection(extent));
51954 set3 = new Set(data.map(function(entity) {
51957 filter2 = function(d) {
51958 return set3.has(d.id);
51963 filter2 = utilFunctor(true);
51966 if (applyFeatureLayerFilters) {
51967 data = features.filter(data, graph);
51969 context.features().resetStats();
51971 if (mode && mode.id === "select") {
51972 surface.call(drawVertices.drawSelected, graph, map2.extent());
51974 surface.call(drawVertices, graph, data, filter2, map2.extent(), fullRedraw).call(drawLines, graph, data, filter2).call(drawAreas, graph, data, filter2).call(drawMidpoints, graph, data, filter2, map2.trimmedExtent()).call(drawLabels, graph, data, filter2, _dimensions, fullRedraw).call(drawPoints, graph, data, filter2);
51975 dispatch10.call("drawn", this, { full: true });
51977 map2.init = function() {
51978 drawLayers = svgLayers(projection2, context);
51979 drawPoints = svgPoints(projection2, context);
51980 drawVertices = svgVertices(projection2, context);
51981 drawLines = svgLines(projection2, context);
51982 drawAreas = svgAreas(projection2, context);
51983 drawMidpoints = svgMidpoints(projection2, context);
51984 drawLabels = svgLabels(projection2, context);
51986 function editOff() {
51987 context.features().resetStats();
51988 surface.selectAll(".layer-osm *").remove();
51989 surface.selectAll(".layer-touch:not(.markers) *").remove();
51993 "select-note": true,
51994 "select-data": true,
51995 "select-error": true
51997 var mode = context.mode();
51998 if (mode && !allowed[mode.id]) {
51999 context.enter(modeBrowse(context));
52001 dispatch10.call("drawn", this, { full: true });
52003 function gestureChange(d3_event) {
52005 e.preventDefault();
52008 // dummy values to ignore in zoomPan
52010 // dummy values to ignore in zoomPan
52011 clientX: e.clientX,
52012 clientY: e.clientY,
52013 screenX: e.screenX,
52014 screenY: e.screenY,
52018 var e22 = new WheelEvent("wheel", props);
52019 e22._scale = e.scale;
52020 e22._rotation = e.rotation;
52021 _selection.node().dispatchEvent(e22);
52023 function zoomPan(event, key, transform2) {
52024 var source = event && event.sourceEvent || event;
52025 var eventTransform = transform2 || event && event.transform;
52026 var x = eventTransform.x;
52027 var y = eventTransform.y;
52028 var k = eventTransform.k;
52029 if (source && source.type === "wheel") {
52032 var detected = utilDetect();
52033 var dX = source.deltaX;
52034 var dY = source.deltaY;
52039 if (source.deltaMode === 1) {
52040 var lines = Math.abs(source.deltaY);
52041 var sign2 = source.deltaY > 0 ? 1 : -1;
52042 dY = sign2 * clamp(
52043 Math.exp((lines - 1) * 0.75) * 4.000244140625,
52049 if (detected.os !== "mac") {
52052 t0 = _isTransformed ? _transformLast : _transformStart;
52053 p02 = _getMouseCoords(source);
52054 p1 = t0.invert(p02);
52055 k2 = t0.k * Math.pow(2, -dY / 500);
52056 k2 = clamp(k2, kMin, kMax);
52057 x2 = p02[0] - p1[0] * k2;
52058 y2 = p02[1] - p1[1] * k2;
52059 } else if (source._scale) {
52060 t0 = _gestureTransformStart;
52061 p02 = _getMouseCoords(source);
52062 p1 = t0.invert(p02);
52063 k2 = t0.k * source._scale;
52064 k2 = clamp(k2, kMin, kMax);
52065 x2 = p02[0] - p1[0] * k2;
52066 y2 = p02[1] - p1[1] * k2;
52067 } else if (source.ctrlKey && !isInteger(dY)) {
52069 t0 = _isTransformed ? _transformLast : _transformStart;
52070 p02 = _getMouseCoords(source);
52071 p1 = t0.invert(p02);
52072 k2 = t0.k * Math.pow(2, -dY / 500);
52073 k2 = clamp(k2, kMin, kMax);
52074 x2 = p02[0] - p1[0] * k2;
52075 y2 = p02[1] - p1[1] * k2;
52076 } else if ((source.altKey || source.shiftKey) && isInteger(dY)) {
52077 t0 = _isTransformed ? _transformLast : _transformStart;
52078 p02 = _getMouseCoords(source);
52079 p1 = t0.invert(p02);
52080 k2 = t0.k * Math.pow(2, -dY / 500);
52081 k2 = clamp(k2, kMin, kMax);
52082 x2 = p02[0] - p1[0] * k2;
52083 y2 = p02[1] - p1[1] * k2;
52084 } else if (detected.os === "mac" && detected.browser !== "Firefox" && !source.ctrlKey && isInteger(dX) && isInteger(dY)) {
52085 p1 = projection2.translate();
52088 k2 = projection2.scale();
52089 k2 = clamp(k2, kMin, kMax);
52091 if (x2 !== x || y2 !== y || k2 !== k) {
52095 eventTransform = identity2.translate(x2, y2).scale(k2);
52096 if (_zoomerPanner._transform) {
52097 _zoomerPanner._transform(eventTransform);
52099 _selection.node().__zoom = eventTransform;
52103 if (_transformStart.x === x && _transformStart.y === y && _transformStart.k === k) {
52106 if (geoScaleToZoom(k, TILESIZE) < _minzoom) {
52107 surface.interrupt();
52108 dispatch10.call("hitMinZoom", this, map2);
52109 setCenterZoom(map2.center(), context.minEditableZoom(), 0, true);
52111 dispatch10.call("move", this, map2);
52114 projection2.transform(eventTransform);
52115 var withinEditableZoom = map2.withinEditableZoom();
52116 if (_lastWithinEditableZoom !== withinEditableZoom) {
52117 if (_lastWithinEditableZoom !== void 0) {
52118 dispatch10.call("crossEditableZoom", this, withinEditableZoom);
52120 _lastWithinEditableZoom = withinEditableZoom;
52122 var scale = k / _transformStart.k;
52123 var tX = (x / scale - _transformStart.x) * scale;
52124 var tY = (y / scale - _transformStart.y) * scale;
52125 if (context.inIntro()) {
52126 curtainProjection.transform({
52133 _lastPointerEvent = event;
52135 _isTransformed = true;
52136 _transformLast = eventTransform;
52137 utilSetTransform(supersurface, tX, tY, scale);
52139 dispatch10.call("move", this, map2);
52140 function isInteger(val) {
52141 return typeof val === "number" && isFinite(val) && Math.floor(val) === val;
52144 function resetTransform() {
52145 if (!_isTransformed)
52147 utilSetTransform(supersurface, 0, 0);
52148 _isTransformed = false;
52149 if (context.inIntro()) {
52150 curtainProjection.transform(projection2.transform());
52154 function redraw(difference, extent) {
52155 if (surface.empty() || !_redrawEnabled)
52157 if (resetTransform()) {
52158 difference = extent = void 0;
52160 var zoom = map2.zoom();
52161 var z = String(~~zoom);
52162 if (surface.attr("data-zoom") !== z) {
52163 surface.attr("data-zoom", z);
52165 var lat = map2.center()[1];
52166 var lowzoom = linear3().domain([-60, 0, 60]).range([17, 18.5, 17]).clamp(true);
52167 surface.classed("low-zoom", zoom <= lowzoom(lat));
52169 supersurface.call(context.background());
52170 wrapper.call(drawLayers);
52172 if (map2.editableDataEnabled() || map2.isInWideSelection()) {
52173 context.loadTiles(projection2);
52174 drawEditable(difference, extent);
52178 _transformStart = projection2.transform();
52181 var immediateRedraw = function(difference, extent) {
52182 if (!difference && !extent)
52183 cancelPendingRedraw();
52184 redraw(difference, extent);
52186 map2.lastPointerEvent = function() {
52187 return _lastPointerEvent;
52189 map2.mouse = function(d3_event) {
52190 var event = d3_event || _lastPointerEvent;
52193 while (s = event.sourceEvent) {
52196 return _getMouseCoords(event);
52200 map2.mouseCoordinates = function() {
52201 var coord2 = map2.mouse() || pxCenter();
52202 return projection2.invert(coord2);
52204 map2.dblclickZoomEnable = function(val) {
52205 if (!arguments.length)
52206 return _dblClickZoomEnabled;
52207 _dblClickZoomEnabled = val;
52210 map2.redrawEnable = function(val) {
52211 if (!arguments.length)
52212 return _redrawEnabled;
52213 _redrawEnabled = val;
52216 map2.isTransformed = function() {
52217 return _isTransformed;
52219 function setTransform(t2, duration, force) {
52220 var t = projection2.transform();
52221 if (!force && t2.k === t.k && t2.x === t.x && t2.y === t.y)
52224 _selection.transition().duration(duration).on("start", function() {
52226 }).call(_zoomerPanner.transform, identity2.translate(t2.x, t2.y).scale(t2.k));
52228 projection2.transform(t2);
52229 _transformStart = t2;
52230 _selection.call(_zoomerPanner.transform, _transformStart);
52234 function setCenterZoom(loc2, z2, duration, force) {
52235 var c = map2.center();
52236 var z = map2.zoom();
52237 if (loc2[0] === c[0] && loc2[1] === c[1] && z2 === z && !force)
52239 var proj = geoRawMercator().transform(projection2.transform());
52240 var k2 = clamp(geoZoomToScale(z2, TILESIZE), kMin, kMax);
52242 var t = proj.translate();
52243 var point2 = proj(loc2);
52244 var center = pxCenter();
52245 t[0] += center[0] - point2[0];
52246 t[1] += center[1] - point2[1];
52247 return setTransform(identity2.translate(t[0], t[1]).scale(k2), duration, force);
52249 map2.pan = function(delta, duration) {
52250 var t = projection2.translate();
52251 var k = projection2.scale();
52255 _selection.transition().duration(duration).on("start", function() {
52257 }).call(_zoomerPanner.transform, identity2.translate(t[0], t[1]).scale(k));
52259 projection2.translate(t);
52260 _transformStart = projection2.transform();
52261 _selection.call(_zoomerPanner.transform, _transformStart);
52262 dispatch10.call("move", this, map2);
52267 map2.dimensions = function(val) {
52268 if (!arguments.length)
52269 return _dimensions;
52271 drawLayers.dimensions(_dimensions);
52272 context.background().dimensions(_dimensions);
52273 projection2.clipExtent([[0, 0], _dimensions]);
52274 _getMouseCoords = utilFastMouse(supersurface.node());
52278 function zoomIn(delta) {
52279 setCenterZoom(map2.center(), ~~map2.zoom() + delta, 250, true);
52281 function zoomOut(delta) {
52282 setCenterZoom(map2.center(), ~~map2.zoom() - delta, 250, true);
52284 map2.zoomIn = function() {
52287 map2.zoomInFurther = function() {
52290 map2.canZoomIn = function() {
52291 return map2.zoom() < maxZoom;
52293 map2.zoomOut = function() {
52296 map2.zoomOutFurther = function() {
52299 map2.canZoomOut = function() {
52300 return map2.zoom() > minZoom2;
52302 map2.center = function(loc2) {
52303 if (!arguments.length) {
52304 return projection2.invert(pxCenter());
52306 if (setCenterZoom(loc2, map2.zoom())) {
52307 dispatch10.call("move", this, map2);
52312 map2.unobscuredCenterZoomEase = function(loc, zoom) {
52313 var offset = map2.unobscuredOffsetPx();
52314 var proj = geoRawMercator().transform(projection2.transform());
52315 proj.scale(geoZoomToScale(zoom, TILESIZE));
52316 var locPx = proj(loc);
52317 var offsetLocPx = [locPx[0] + offset[0], locPx[1] + offset[1]];
52318 var offsetLoc = proj.invert(offsetLocPx);
52319 map2.centerZoomEase(offsetLoc, zoom);
52321 map2.unobscuredOffsetPx = function() {
52322 var openPane = context.container().select(".map-panes .map-pane.shown");
52323 if (!openPane.empty()) {
52324 return [openPane.node().offsetWidth / 2, 0];
52328 map2.zoom = function(z2) {
52329 if (!arguments.length) {
52330 return Math.max(geoScaleToZoom(projection2.scale(), TILESIZE), 0);
52332 if (z2 < _minzoom) {
52333 surface.interrupt();
52334 dispatch10.call("hitMinZoom", this, map2);
52335 z2 = context.minEditableZoom();
52337 if (setCenterZoom(map2.center(), z2)) {
52338 dispatch10.call("move", this, map2);
52343 map2.centerZoom = function(loc2, z2) {
52344 if (setCenterZoom(loc2, z2)) {
52345 dispatch10.call("move", this, map2);
52350 map2.zoomTo = function(entity) {
52351 var extent = entity.extent(context.graph());
52352 if (!isFinite(extent.area()))
52354 var z2 = clamp(map2.trimmedExtentZoom(extent), 0, 20);
52355 return map2.centerZoom(extent.center(), z2);
52357 map2.centerEase = function(loc2, duration) {
52358 duration = duration || 250;
52359 setCenterZoom(loc2, map2.zoom(), duration);
52362 map2.zoomEase = function(z2, duration) {
52363 duration = duration || 250;
52364 setCenterZoom(map2.center(), z2, duration, false);
52367 map2.centerZoomEase = function(loc2, z2, duration) {
52368 duration = duration || 250;
52369 setCenterZoom(loc2, z2, duration, false);
52372 map2.transformEase = function(t2, duration) {
52373 duration = duration || 250;
52382 map2.zoomToEase = function(obj, duration) {
52384 if (Array.isArray(obj)) {
52385 obj.forEach(function(entity) {
52386 var entityExtent = entity.extent(context.graph());
52388 extent = entityExtent;
52390 extent = extent.extend(entityExtent);
52394 extent = obj.extent(context.graph());
52396 if (!isFinite(extent.area()))
52398 var z2 = clamp(map2.trimmedExtentZoom(extent), 0, 20);
52399 return map2.centerZoomEase(extent.center(), z2, duration);
52401 map2.startEase = function() {
52402 utilBindOnce(surface, _pointerPrefix + "down.ease", function() {
52407 map2.cancelEase = function() {
52408 _selection.interrupt();
52411 map2.extent = function(val) {
52412 if (!arguments.length) {
52413 return new geoExtent(
52414 projection2.invert([0, _dimensions[1]]),
52415 projection2.invert([_dimensions[0], 0])
52418 var extent = geoExtent(val);
52419 map2.centerZoom(extent.center(), map2.extentZoom(extent));
52422 map2.trimmedExtent = function(val) {
52423 if (!arguments.length) {
52427 return new geoExtent(
52428 projection2.invert([pad2, _dimensions[1] - footerY - pad2]),
52429 projection2.invert([_dimensions[0] - pad2, headerY + pad2])
52432 var extent = geoExtent(val);
52433 map2.centerZoom(extent.center(), map2.trimmedExtentZoom(extent));
52436 function calcExtentZoom(extent, dim) {
52437 var tl = projection2([extent[0][0], extent[1][1]]);
52438 var br = projection2([extent[1][0], extent[0][1]]);
52439 var hFactor = (br[0] - tl[0]) / dim[0];
52440 var vFactor = (br[1] - tl[1]) / dim[1];
52441 var hZoomDiff = Math.log(Math.abs(hFactor)) / Math.LN2;
52442 var vZoomDiff = Math.log(Math.abs(vFactor)) / Math.LN2;
52443 var newZoom = map2.zoom() - Math.max(hZoomDiff, vZoomDiff);
52446 map2.extentZoom = function(val) {
52447 return calcExtentZoom(geoExtent(val), _dimensions);
52449 map2.trimmedExtentZoom = function(val) {
52452 var trimmed = [_dimensions[0] - trimX, _dimensions[1] - trimY];
52453 return calcExtentZoom(geoExtent(val), trimmed);
52455 map2.withinEditableZoom = function() {
52456 return map2.zoom() >= context.minEditableZoom();
52458 map2.isInWideSelection = function() {
52459 return !map2.withinEditableZoom() && context.selectedIDs().length;
52461 map2.editableDataEnabled = function(skipZoomCheck) {
52462 var layer = context.layers().layer("osm");
52463 if (!layer || !layer.enabled())
52465 return skipZoomCheck || map2.withinEditableZoom();
52467 map2.notesEditable = function() {
52468 var layer = context.layers().layer("notes");
52469 if (!layer || !layer.enabled())
52471 return map2.withinEditableZoom();
52473 map2.minzoom = function(val) {
52474 if (!arguments.length)
52479 map2.toggleHighlightEdited = function() {
52480 surface.classed("highlight-edited", !surface.classed("highlight-edited"));
52482 dispatch10.call("changeHighlighting", this);
52484 map2.areaFillOptions = ["wireframe", "partial", "full"];
52485 map2.activeAreaFill = function(val) {
52486 if (!arguments.length)
52487 return corePreferences("area-fill") || "partial";
52488 corePreferences("area-fill", val);
52489 if (val !== "wireframe") {
52490 corePreferences("area-fill-toggle", val);
52494 dispatch10.call("changeAreaFill", this);
52497 map2.toggleWireframe = function() {
52498 var activeFill = map2.activeAreaFill();
52499 if (activeFill === "wireframe") {
52500 activeFill = corePreferences("area-fill-toggle") || "partial";
52502 activeFill = "wireframe";
52504 map2.activeAreaFill(activeFill);
52506 function updateAreaFill() {
52507 var activeFill = map2.activeAreaFill();
52508 map2.areaFillOptions.forEach(function(opt) {
52509 surface.classed("fill-" + opt, Boolean(opt === activeFill));
52512 map2.layers = () => drawLayers;
52513 map2.doubleUpHandler = function() {
52514 return _doubleUpHandler;
52516 return utilRebind(map2, dispatch10, "on");
52519 // modules/renderer/photos.js
52520 function rendererPhotos(context) {
52521 var dispatch10 = dispatch_default("change");
52522 var _layerIDs = ["streetside", "mapillary", "mapillary-map-features", "mapillary-signs", "kartaview"];
52523 var _allPhotoTypes = ["flat", "panoramic"];
52524 var _shownPhotoTypes = _allPhotoTypes.slice();
52525 var _dateFilters = ["fromDate", "toDate"];
52529 function photos() {
52531 function updateStorage() {
52534 var hash = utilStringQs(window.location.hash);
52535 var enabled = context.layers().all().filter(function(d) {
52536 return _layerIDs.indexOf(d.id) !== -1 && d.layer && d.layer.supported() && d.layer.enabled();
52537 }).map(function(d) {
52540 if (enabled.length) {
52541 hash.photo_overlay = enabled.join(",");
52543 delete hash.photo_overlay;
52545 window.location.replace("#" + utilQsString(hash, true));
52547 photos.overlayLayerIDs = function() {
52550 photos.allPhotoTypes = function() {
52551 return _allPhotoTypes;
52553 photos.dateFilters = function() {
52554 return _dateFilters;
52556 photos.dateFilterValue = function(val) {
52557 return val === _dateFilters[0] ? _fromDate : _toDate;
52559 photos.setDateFilter = function(type2, val, updateUrl) {
52560 var date = val && new Date(val);
52561 if (date && !isNaN(date)) {
52562 val = date.toISOString().slice(0, 10);
52566 if (type2 === _dateFilters[0]) {
52568 if (_fromDate && _toDate && new Date(_toDate) < new Date(_fromDate)) {
52569 _toDate = _fromDate;
52572 if (type2 === _dateFilters[1]) {
52574 if (_fromDate && _toDate && new Date(_toDate) < new Date(_fromDate)) {
52575 _fromDate = _toDate;
52578 dispatch10.call("change", this);
52581 if (_fromDate || _toDate) {
52582 rangeString = (_fromDate || "") + "_" + (_toDate || "");
52584 setUrlFilterValue("photo_dates", rangeString);
52587 photos.setUsernameFilter = function(val, updateUrl) {
52588 if (val && typeof val === "string")
52589 val = val.replace(/;/g, ",").split(",");
52591 val = val.map((d) => d.trim()).filter(Boolean);
52597 dispatch10.call("change", this);
52601 hashString = _usernames.join(",");
52603 setUrlFilterValue("photo_username", hashString);
52606 function setUrlFilterValue(property, val) {
52607 if (!window.mocha) {
52608 var hash = utilStringQs(window.location.hash);
52610 if (hash[property] === val)
52612 hash[property] = val;
52614 if (!(property in hash))
52616 delete hash[property];
52618 window.location.replace("#" + utilQsString(hash, true));
52621 function showsLayer(id2) {
52622 var layer = context.layers().layer(id2);
52623 return layer && layer.supported() && layer.enabled();
52625 photos.shouldFilterByDate = function() {
52626 return showsLayer("mapillary") || showsLayer("kartaview") || showsLayer("streetside");
52628 photos.shouldFilterByPhotoType = function() {
52629 return showsLayer("mapillary") || showsLayer("streetside") && showsLayer("kartaview");
52631 photos.shouldFilterByUsername = function() {
52632 return !showsLayer("mapillary") && showsLayer("kartaview") && !showsLayer("streetside");
52634 photos.showsPhotoType = function(val) {
52635 if (!photos.shouldFilterByPhotoType())
52637 return _shownPhotoTypes.indexOf(val) !== -1;
52639 photos.showsFlat = function() {
52640 return photos.showsPhotoType("flat");
52642 photos.showsPanoramic = function() {
52643 return photos.showsPhotoType("panoramic");
52645 photos.fromDate = function() {
52648 photos.toDate = function() {
52651 photos.togglePhotoType = function(val) {
52652 var index = _shownPhotoTypes.indexOf(val);
52653 if (index !== -1) {
52654 _shownPhotoTypes.splice(index, 1);
52656 _shownPhotoTypes.push(val);
52658 dispatch10.call("change", this);
52661 photos.usernames = function() {
52664 photos.init = function() {
52665 var hash = utilStringQs(window.location.hash);
52666 if (hash.photo_dates) {
52667 var parts = /^(.*)[–_](.*)$/g.exec(hash.photo_dates.trim());
52668 this.setDateFilter("fromDate", parts && parts.length >= 2 && parts[1], false);
52669 this.setDateFilter("toDate", parts && parts.length >= 3 && parts[2], false);
52671 if (hash.photo_username) {
52672 this.setUsernameFilter(hash.photo_username, false);
52674 if (hash.photo_overlay) {
52675 var hashOverlayIDs = hash.photo_overlay.replace(/;/g, ",").split(",");
52676 hashOverlayIDs.forEach(function(id2) {
52677 if (id2 === "openstreetcam")
52679 var layer2 = _layerIDs.indexOf(id2) !== -1 && context.layers().layer(id2);
52680 if (layer2 && !layer2.enabled())
52681 layer2.enabled(true);
52685 var photoIds = hash.photo.replace(/;/g, ",").split(",");
52686 var photoId = photoIds.length && photoIds[0].trim();
52687 var results = /(.*)\/(.*)/g.exec(photoId);
52688 if (results && results.length >= 3) {
52689 var serviceId = results[1];
52690 if (serviceId === "openstreetcam")
52691 serviceId = "kartaview";
52692 var photoKey = results[2];
52693 var service = services[serviceId];
52694 if (service && service.ensureViewerLoaded) {
52695 var layer = _layerIDs.indexOf(serviceId) !== -1 && context.layers().layer(serviceId);
52696 if (layer && !layer.enabled())
52697 layer.enabled(true);
52698 var baselineTime = Date.now();
52699 service.on("loadedImages.rendererPhotos", function() {
52700 if (Date.now() - baselineTime > 45e3) {
52701 service.on("loadedImages.rendererPhotos", null);
52704 if (!service.cachedImage(photoKey))
52706 service.on("loadedImages.rendererPhotos", null);
52707 service.ensureViewerLoaded(context).then(function() {
52708 service.selectImage(context, photoKey).showViewer(context);
52714 context.layers().on("change.rendererPhotos", updateStorage);
52716 return utilRebind(photos, dispatch10, "on");
52719 // modules/ui/account.js
52720 function uiAccount(context) {
52721 const osm = context.connection();
52722 function updateUserDetails(selection2) {
52725 if (!osm.authenticated()) {
52726 render(selection2, null);
52728 osm.userDetails((err, user) => render(selection2, user));
52731 function render(selection2, user) {
52732 let userInfo = selection2.select(".userInfo");
52733 let loginLogout = selection2.select(".loginLogout");
52735 userInfo.html("").classed("hide", false);
52736 let userLink = userInfo.append("a").attr("href", osm.userURL(user.display_name)).attr("target", "_blank");
52737 if (user.image_url) {
52738 userLink.append("img").attr("class", "icon pre-text user-icon").attr("src", user.image_url);
52740 userLink.call(svgIcon("#iD-icon-avatar", "pre-text light"));
52742 userLink.append("span").attr("class", "label").html(user.display_name);
52743 loginLogout.classed("hide", false).select("a").text(_t("logout")).on("click", (e) => {
52744 e.preventDefault();
52749 userInfo.html("").classed("hide", true);
52750 loginLogout.classed("hide", false).select("a").text(_t("login")).on("click", (e) => {
52751 e.preventDefault();
52752 osm.authenticate();
52756 function tryLogout() {
52759 const url = osm.getUrlRoot() + "/logout?referer=%2Flogin";
52765 ["left", window.screen.width / 2 - w / 2],
52766 ["top", window.screen.height / 2 - h / 2]
52767 ].map((x) => x.join("=")).join(",");
52768 window.open(url, "_blank", settings);
52770 return function(selection2) {
52773 selection2.append("li").attr("class", "userInfo").classed("hide", true);
52774 selection2.append("li").attr("class", "loginLogout").classed("hide", true).append("a").attr("href", "#");
52775 osm.on("change.account", () => updateUserDetails(selection2));
52776 updateUserDetails(selection2);
52780 // modules/ui/attribution.js
52781 function uiAttribution(context) {
52782 let _selection = select_default2(null);
52783 function render(selection2, data, klass) {
52784 let div = selection2.selectAll(`.${klass}`).data([0]);
52785 div = div.enter().append("div").attr("class", klass).merge(div);
52786 let attributions = div.selectAll(".attribution").data(data, (d) => d.id);
52787 attributions.exit().remove();
52788 attributions = attributions.enter().append("span").attr("class", "attribution").each((d, i2, nodes) => {
52789 let attribution = select_default2(nodes[i2]);
52790 if (d.terms_html) {
52791 attribution.html(d.terms_html);
52795 attribution = attribution.append("a").attr("href", d.terms_url).attr("target", "_blank");
52797 const sourceID = d.id.replace(/\./g, "<TX_DOT>");
52798 const terms_text = _t(
52799 `imagery.${sourceID}.attribution.text`,
52800 { default: d.terms_text || d.id || d.name() }
52802 if (d.icon && !d.overlay) {
52803 attribution.append("img").attr("class", "source-image").attr("src", d.icon);
52805 attribution.append("span").attr("class", "attribution-text").text(terms_text);
52806 }).merge(attributions);
52807 let copyright = attributions.selectAll(".copyright-notice").data((d) => {
52808 let notice = d.copyrightNotices(context.map().zoom(), context.map().extent());
52809 return notice ? [notice] : [];
52811 copyright.exit().remove();
52812 copyright = copyright.enter().append("span").attr("class", "copyright-notice").merge(copyright);
52813 copyright.text(String);
52815 function update() {
52816 let baselayer = context.background().baseLayerSource();
52817 _selection.call(render, baselayer ? [baselayer] : [], "base-layer-attribution");
52818 const z = context.map().zoom();
52819 let overlays = context.background().overlayLayerSources() || [];
52820 _selection.call(render, overlays.filter((s) => s.validZoom(z)), "overlay-layer-attribution");
52822 return function(selection2) {
52823 _selection = selection2;
52824 context.background().on("change.attribution", update);
52825 context.map().on("move.attribution", throttle_default(update, 400, { leading: false }));
52830 // modules/ui/contributors.js
52831 function uiContributors(context) {
52832 var osm = context.connection(), debouncedUpdate = debounce_default(function() {
52834 }, 1e3), limit = 4, hidden = false, wrap2 = select_default2(null);
52835 function update() {
52838 var users = {}, entities = context.history().intersects(context.map().extent());
52839 entities.forEach(function(entity) {
52840 if (entity && entity.user)
52841 users[entity.user] = true;
52843 var u = Object.keys(users), subset = u.slice(0, u.length > limit ? limit - 1 : limit);
52844 wrap2.html("").call(svgIcon("#iD-icon-nearby", "pre-text light"));
52845 var userList = select_default2(document.createElement("span"));
52846 userList.selectAll().data(subset).enter().append("a").attr("class", "user-link").attr("href", function(d) {
52847 return osm.userURL(d);
52848 }).attr("target", "_blank").text(String);
52849 if (u.length > limit) {
52850 var count = select_default2(document.createElement("span"));
52851 var othersNum = u.length - limit + 1;
52852 count.append("a").attr("target", "_blank").attr("href", function() {
52853 return osm.changesetsURL(context.map().center(), context.map().zoom());
52854 }).text(othersNum);
52855 wrap2.append("span").html(_t.html("contributors.truncated_list", { n: othersNum, users: { html: userList.html() }, count: { html: count.html() } }));
52857 wrap2.append("span").html(_t.html("contributors.list", { users: { html: userList.html() } }));
52861 wrap2.transition().style("opacity", 0);
52862 } else if (hidden) {
52863 wrap2.transition().style("opacity", 1);
52866 return function(selection2) {
52869 wrap2 = selection2;
52871 osm.on("loaded.contributors", debouncedUpdate);
52872 context.map().on("move.contributors", debouncedUpdate);
52876 // modules/ui/popover.js
52877 var _popoverID = 0;
52878 function uiPopover(klass) {
52879 var _id = _popoverID++;
52880 var _anchorSelection = select_default2(null);
52881 var popover = function(selection2) {
52882 _anchorSelection = selection2;
52883 selection2.each(setup);
52885 var _animation = utilFunctor(false);
52886 var _placement = utilFunctor("top");
52887 var _alignment = utilFunctor("center");
52888 var _scrollContainer = utilFunctor(select_default2(null));
52890 var _displayType = utilFunctor("");
52891 var _hasArrow = utilFunctor(true);
52892 var _pointerPrefix = "PointerEvent" in window ? "pointer" : "mouse";
52893 popover.displayType = function(val) {
52894 if (arguments.length) {
52895 _displayType = utilFunctor(val);
52898 return _displayType;
52901 popover.hasArrow = function(val) {
52902 if (arguments.length) {
52903 _hasArrow = utilFunctor(val);
52909 popover.placement = function(val) {
52910 if (arguments.length) {
52911 _placement = utilFunctor(val);
52917 popover.alignment = function(val) {
52918 if (arguments.length) {
52919 _alignment = utilFunctor(val);
52925 popover.scrollContainer = function(val) {
52926 if (arguments.length) {
52927 _scrollContainer = utilFunctor(val);
52930 return _scrollContainer;
52933 popover.content = function(val) {
52934 if (arguments.length) {
52941 popover.isShown = function() {
52942 var popoverSelection = _anchorSelection.select(".popover-" + _id);
52943 return !popoverSelection.empty() && popoverSelection.classed("in");
52945 popover.show = function() {
52946 _anchorSelection.each(show);
52948 popover.updateContent = function() {
52949 _anchorSelection.each(updateContent);
52951 popover.hide = function() {
52952 _anchorSelection.each(hide);
52954 popover.toggle = function() {
52955 _anchorSelection.each(toggle);
52957 popover.destroy = function(selection2, selector) {
52958 selector = selector || ".popover-" + _id;
52959 selection2.on(_pointerPrefix + "enter.popover", null).on(_pointerPrefix + "leave.popover", null).on(_pointerPrefix + "up.popover", null).on(_pointerPrefix + "down.popover", null).on("click.popover", null).attr("title", function() {
52960 return this.getAttribute("data-original-title") || this.getAttribute("title");
52961 }).attr("data-original-title", null).selectAll(selector).remove();
52963 popover.destroyAny = function(selection2) {
52964 selection2.call(popover.destroy, ".popover");
52967 var anchor = select_default2(this);
52968 var animate = _animation.apply(this, arguments);
52969 var popoverSelection = anchor.selectAll(".popover-" + _id).data([0]);
52970 var enter = popoverSelection.enter().append("div").attr("class", "popover popover-" + _id + " " + (klass ? klass : "")).classed("arrowed", _hasArrow.apply(this, arguments));
52971 enter.append("div").attr("class", "popover-arrow");
52972 enter.append("div").attr("class", "popover-inner");
52973 popoverSelection = enter.merge(popoverSelection);
52975 popoverSelection.classed("fade", true);
52977 var display = _displayType.apply(this, arguments);
52978 if (display === "hover") {
52979 var _lastNonMouseEnterTime;
52980 anchor.on(_pointerPrefix + "enter.popover", function(d3_event) {
52981 if (d3_event.pointerType) {
52982 if (d3_event.pointerType !== "mouse") {
52983 _lastNonMouseEnterTime = d3_event.timeStamp;
52985 } else if (_lastNonMouseEnterTime && d3_event.timeStamp - _lastNonMouseEnterTime < 1500) {
52989 if (d3_event.buttons !== 0)
52991 show.apply(this, arguments);
52992 }).on(_pointerPrefix + "leave.popover", function() {
52993 hide.apply(this, arguments);
52994 }).on("focus.popover", function() {
52995 show.apply(this, arguments);
52996 }).on("blur.popover", function() {
52997 hide.apply(this, arguments);
52999 } else if (display === "clickFocus") {
53000 anchor.on(_pointerPrefix + "down.popover", function(d3_event) {
53001 d3_event.preventDefault();
53002 d3_event.stopPropagation();
53003 }).on(_pointerPrefix + "up.popover", function(d3_event) {
53004 d3_event.preventDefault();
53005 d3_event.stopPropagation();
53006 }).on("click.popover", toggle);
53007 popoverSelection.attr("tabindex", 0).on("blur.popover", function() {
53008 anchor.each(function() {
53009 hide.apply(this, arguments);
53015 var anchor = select_default2(this);
53016 var popoverSelection = anchor.selectAll(".popover-" + _id);
53017 if (popoverSelection.empty()) {
53018 anchor.call(popover.destroy);
53019 anchor.each(setup);
53020 popoverSelection = anchor.selectAll(".popover-" + _id);
53022 popoverSelection.classed("in", true);
53023 var displayType = _displayType.apply(this, arguments);
53024 if (displayType === "clickFocus") {
53025 anchor.classed("active", true);
53026 popoverSelection.node().focus();
53028 anchor.each(updateContent);
53030 function updateContent() {
53031 var anchor = select_default2(this);
53033 anchor.selectAll(".popover-" + _id + " > .popover-inner").call(_content.apply(this, arguments));
53035 updatePosition.apply(this, arguments);
53036 updatePosition.apply(this, arguments);
53037 updatePosition.apply(this, arguments);
53039 function updatePosition() {
53040 var anchor = select_default2(this);
53041 var popoverSelection = anchor.selectAll(".popover-" + _id);
53042 var scrollContainer = _scrollContainer && _scrollContainer.apply(this, arguments);
53043 var scrollNode = scrollContainer && !scrollContainer.empty() && scrollContainer.node();
53044 var scrollLeft = scrollNode ? scrollNode.scrollLeft : 0;
53045 var scrollTop = scrollNode ? scrollNode.scrollTop : 0;
53046 var placement = _placement.apply(this, arguments);
53047 popoverSelection.classed("left", false).classed("right", false).classed("top", false).classed("bottom", false).classed(placement, true);
53048 var alignment = _alignment.apply(this, arguments);
53049 var alignFactor = 0.5;
53050 if (alignment === "leading") {
53052 } else if (alignment === "trailing") {
53055 var anchorFrame = getFrame(anchor.node());
53056 var popoverFrame = getFrame(popoverSelection.node());
53058 switch (placement) {
53061 x: anchorFrame.x + (anchorFrame.w - popoverFrame.w) * alignFactor,
53062 y: anchorFrame.y - popoverFrame.h
53067 x: anchorFrame.x + (anchorFrame.w - popoverFrame.w) * alignFactor,
53068 y: anchorFrame.y + anchorFrame.h
53073 x: anchorFrame.x - popoverFrame.w,
53074 y: anchorFrame.y + (anchorFrame.h - popoverFrame.h) * alignFactor
53079 x: anchorFrame.x + anchorFrame.w,
53080 y: anchorFrame.y + (anchorFrame.h - popoverFrame.h) * alignFactor
53085 if (scrollNode && (placement === "top" || placement === "bottom")) {
53086 var initialPosX = position.x;
53087 if (position.x + popoverFrame.w > scrollNode.offsetWidth - 10) {
53088 position.x = scrollNode.offsetWidth - 10 - popoverFrame.w;
53089 } else if (position.x < 10) {
53092 var arrow = anchor.selectAll(".popover-" + _id + " > .popover-arrow");
53093 var arrowPosX = Math.min(Math.max(popoverFrame.w / 2 - (position.x - initialPosX), 10), popoverFrame.w - 10);
53094 arrow.style("left", ~~arrowPosX + "px");
53096 popoverSelection.style("left", ~~position.x + "px").style("top", ~~position.y + "px");
53098 popoverSelection.style("left", null).style("top", null);
53100 function getFrame(node) {
53101 var positionStyle = select_default2(node).style("position");
53102 if (positionStyle === "absolute" || positionStyle === "static") {
53104 x: node.offsetLeft - scrollLeft,
53105 y: node.offsetTop - scrollTop,
53106 w: node.offsetWidth,
53107 h: node.offsetHeight
53113 w: node.offsetWidth,
53114 h: node.offsetHeight
53120 var anchor = select_default2(this);
53121 if (_displayType.apply(this, arguments) === "clickFocus") {
53122 anchor.classed("active", false);
53124 anchor.selectAll(".popover-" + _id).classed("in", false);
53126 function toggle() {
53127 if (select_default2(this).select(".popover-" + _id).classed("in")) {
53128 hide.apply(this, arguments);
53130 show.apply(this, arguments);
53136 // modules/ui/tooltip.js
53137 function uiTooltip(klass) {
53138 var tooltip = uiPopover((klass || "") + " tooltip").displayType("hover");
53139 var _title = function() {
53140 var title = this.getAttribute("data-original-title");
53144 title = this.getAttribute("title");
53145 this.removeAttribute("title");
53146 this.setAttribute("data-original-title", title);
53150 var _heading = utilFunctor(null);
53151 var _keys = utilFunctor(null);
53152 tooltip.title = function(val) {
53153 if (!arguments.length)
53155 _title = utilFunctor(val);
53158 tooltip.heading = function(val) {
53159 if (!arguments.length)
53161 _heading = utilFunctor(val);
53164 tooltip.keys = function(val) {
53165 if (!arguments.length)
53167 _keys = utilFunctor(val);
53170 tooltip.content(function() {
53171 var heading = _heading.apply(this, arguments);
53172 var text2 = _title.apply(this, arguments);
53173 var keys = _keys.apply(this, arguments);
53174 var headingCallback = typeof heading === "function" ? heading : (s) => s.text(heading);
53175 var textCallback = typeof text2 === "function" ? text2 : (s) => s.text(text2);
53176 return function(selection2) {
53177 var headingSelect = selection2.selectAll(".tooltip-heading").data(heading ? [heading] : []);
53178 headingSelect.exit().remove();
53179 headingSelect.enter().append("div").attr("class", "tooltip-heading").merge(headingSelect).text("").call(headingCallback);
53180 var textSelect = selection2.selectAll(".tooltip-text").data(text2 ? [text2] : []);
53181 textSelect.exit().remove();
53182 textSelect.enter().append("div").attr("class", "tooltip-text").merge(textSelect).text("").call(textCallback);
53183 var keyhintWrap = selection2.selectAll(".keyhint-wrap").data(keys && keys.length ? [0] : []);
53184 keyhintWrap.exit().remove();
53185 var keyhintWrapEnter = keyhintWrap.enter().append("div").attr("class", "keyhint-wrap");
53186 keyhintWrapEnter.append("span").call(_t.append("tooltip_keyhint"));
53187 keyhintWrap = keyhintWrapEnter.merge(keyhintWrap);
53188 keyhintWrap.selectAll("kbd.shortcut").data(keys && keys.length ? keys : []).enter().append("kbd").attr("class", "shortcut").text(function(d) {
53196 // modules/ui/edit_menu.js
53197 function uiEditMenu(context) {
53198 var dispatch10 = dispatch_default("toggled");
53199 var _menu = select_default2(null);
53200 var _operations = [];
53201 var _anchorLoc = [0, 0];
53202 var _anchorLocLonLat = [0, 0];
53203 var _triggerType = "";
53204 var _vpTopMargin = 85;
53205 var _vpBottomMargin = 45;
53206 var _vpSideMargin = 35;
53207 var _menuTop = false;
53210 var _verticalPadding = 4;
53211 var _tooltipWidth = 210;
53212 var _menuSideMargin = 10;
53213 var _tooltips = [];
53214 var editMenu = function(selection2) {
53215 var isTouchMenu = _triggerType.includes("touch") || _triggerType.includes("pen");
53216 var ops = _operations.filter(function(op) {
53217 return !isTouchMenu || !op.mouseOnly;
53222 _menuTop = isTouchMenu;
53223 var showLabels = isTouchMenu;
53224 var buttonHeight = showLabels ? 32 : 34;
53226 _menuWidth = 52 + Math.min(120, 6 * Math.max.apply(Math, ops.map(function(op) {
53227 return op.title.length;
53232 _menuHeight = _verticalPadding * 2 + ops.length * buttonHeight;
53233 _menu = selection2.append("div").attr("class", "edit-menu").classed("touch-menu", isTouchMenu).style("padding", _verticalPadding + "px 0");
53234 var buttons = _menu.selectAll(".edit-menu-item").data(ops);
53235 var buttonsEnter = buttons.enter().append("button").attr("class", function(d) {
53236 return "edit-menu-item edit-menu-item-" + d.id;
53237 }).style("height", buttonHeight + "px").on("click", click).on("pointerup", pointerup).on("pointerdown mousedown", function pointerdown(d3_event) {
53238 d3_event.stopPropagation();
53239 }).on("mouseenter.highlight", function(d3_event, d) {
53240 if (!d.relatedEntityIds || select_default2(this).classed("disabled"))
53242 utilHighlightEntities(d.relatedEntityIds(), true, context);
53243 }).on("mouseleave.highlight", function(d3_event, d) {
53244 if (!d.relatedEntityIds)
53246 utilHighlightEntities(d.relatedEntityIds(), false, context);
53248 buttonsEnter.each(function(d) {
53249 var tooltip = uiTooltip().heading(() => d.title).title(d.tooltip).keys([d.keys[0]]);
53250 _tooltips.push(tooltip);
53251 select_default2(this).call(tooltip).append("div").attr("class", "icon-wrap").call(svgIcon(d.icon && d.icon() || "#iD-operation-" + d.id, "operation"));
53254 buttonsEnter.append("span").attr("class", "label").each(function(d) {
53255 select_default2(this).call(d.title);
53258 buttonsEnter.merge(buttons).classed("disabled", function(d) {
53259 return d.disabled();
53262 var initialScale = context.projection.scale();
53263 context.map().on("move.edit-menu", function() {
53264 if (initialScale !== context.projection.scale()) {
53267 }).on("drawn.edit-menu", function(info) {
53271 var lastPointerUpType;
53272 function pointerup(d3_event) {
53273 lastPointerUpType = d3_event.pointerType;
53275 function click(d3_event, operation) {
53276 d3_event.stopPropagation();
53277 if (operation.relatedEntityIds) {
53278 utilHighlightEntities(operation.relatedEntityIds(), false, context);
53280 if (operation.disabled()) {
53281 if (lastPointerUpType === "touch" || lastPointerUpType === "pen") {
53282 context.ui().flash.duration(4e3).iconName("#iD-operation-" + operation.id).iconClass("operation disabled").label(operation.tooltip())();
53285 if (lastPointerUpType === "touch" || lastPointerUpType === "pen") {
53286 context.ui().flash.duration(2e3).iconName("#iD-operation-" + operation.id).iconClass("operation").label(operation.annotation() || operation.title)();
53291 lastPointerUpType = null;
53293 dispatch10.call("toggled", this, true);
53295 function updatePosition() {
53296 if (!_menu || _menu.empty())
53298 var anchorLoc = context.projection(_anchorLocLonLat);
53299 var viewport = context.surfaceRect();
53300 if (anchorLoc[0] < 0 || anchorLoc[0] > viewport.width || anchorLoc[1] < 0 || anchorLoc[1] > viewport.height) {
53304 var menuLeft = displayOnLeft(viewport);
53305 var offset = [0, 0];
53306 offset[0] = menuLeft ? -1 * (_menuSideMargin + _menuWidth) : _menuSideMargin;
53308 if (anchorLoc[1] - _menuHeight < _vpTopMargin) {
53309 offset[1] = -anchorLoc[1] + _vpTopMargin;
53311 offset[1] = -_menuHeight;
53314 if (anchorLoc[1] + _menuHeight > viewport.height - _vpBottomMargin) {
53315 offset[1] = -anchorLoc[1] - _menuHeight + viewport.height - _vpBottomMargin;
53320 var origin = geoVecAdd(anchorLoc, offset);
53321 _menu.style("left", origin[0] + "px").style("top", origin[1] + "px");
53322 var tooltipSide = tooltipPosition(viewport, menuLeft);
53323 _tooltips.forEach(function(tooltip) {
53324 tooltip.placement(tooltipSide);
53326 function displayOnLeft(viewport2) {
53327 if (_mainLocalizer.textDirection() === "ltr") {
53328 if (anchorLoc[0] + _menuSideMargin + _menuWidth > viewport2.width - _vpSideMargin) {
53333 if (anchorLoc[0] - _menuSideMargin - _menuWidth < _vpSideMargin) {
53339 function tooltipPosition(viewport2, menuLeft2) {
53340 if (_mainLocalizer.textDirection() === "ltr") {
53344 if (anchorLoc[0] + _menuSideMargin + _menuWidth + _tooltipWidth > viewport2.width - _vpSideMargin) {
53352 if (anchorLoc[0] - _menuSideMargin - _menuWidth - _tooltipWidth < _vpSideMargin) {
53359 editMenu.close = function() {
53360 context.map().on("move.edit-menu", null).on("drawn.edit-menu", null);
53363 dispatch10.call("toggled", this, false);
53365 editMenu.anchorLoc = function(val) {
53366 if (!arguments.length)
53369 _anchorLocLonLat = context.projection.invert(_anchorLoc);
53372 editMenu.triggerType = function(val) {
53373 if (!arguments.length)
53374 return _triggerType;
53375 _triggerType = val;
53378 editMenu.operations = function(val) {
53379 if (!arguments.length)
53380 return _operations;
53384 return utilRebind(editMenu, dispatch10, "on");
53387 // modules/ui/feature_info.js
53388 function uiFeatureInfo(context) {
53389 function update(selection2) {
53390 var features = context.features();
53391 var stats = features.stats();
53393 var hiddenList = features.hidden().map(function(k) {
53396 return _t.append("inspector.title_count", {
53397 title: _t("feature." + k + ".description"),
53402 }).filter(Boolean);
53403 selection2.text("");
53404 if (hiddenList.length) {
53405 var tooltipBehavior = uiTooltip().placement("top").title(function() {
53406 return (selection3) => {
53407 hiddenList.forEach((hiddenFeature) => {
53408 selection3.append("div").call(hiddenFeature);
53412 selection2.append("a").attr("class", "chip").attr("href", "#").call(_t.append("feature_info.hidden_warning", { count })).call(tooltipBehavior).on("click", function(d3_event) {
53413 tooltipBehavior.hide();
53414 d3_event.preventDefault();
53415 context.ui().togglePanes(context.container().select(".map-panes .map-data-pane"));
53418 selection2.classed("hide", !hiddenList.length);
53420 return function(selection2) {
53421 update(selection2);
53422 context.features().on("change.feature_info", function() {
53423 update(selection2);
53428 // modules/ui/flash.js
53429 function uiFlash(context) {
53431 var _duration = 2e3;
53432 var _iconName = "#iD-icon-no";
53433 var _iconClass = "disabled";
53434 var _label = (s) => s.text("");
53437 _flashTimer.stop();
53439 context.container().select(".main-footer-wrap").classed("footer-hide", true).classed("footer-show", false);
53440 context.container().select(".flash-wrap").classed("footer-hide", false).classed("footer-show", true);
53441 var content = context.container().select(".flash-wrap").selectAll(".flash-content").data([0]);
53442 var contentEnter = content.enter().append("div").attr("class", "flash-content");
53443 var iconEnter = contentEnter.append("svg").attr("class", "flash-icon icon").append("g").attr("transform", "translate(10,10)");
53444 iconEnter.append("circle").attr("r", 9);
53445 iconEnter.append("use").attr("transform", "translate(-7,-7)").attr("width", "14").attr("height", "14");
53446 contentEnter.append("div").attr("class", "flash-text");
53447 content = content.merge(contentEnter);
53448 content.selectAll(".flash-icon").attr("class", "icon flash-icon " + (_iconClass || ""));
53449 content.selectAll(".flash-icon use").attr("xlink:href", _iconName);
53450 content.selectAll(".flash-text").attr("class", "flash-text").call(_label);
53451 _flashTimer = timeout_default(function() {
53452 _flashTimer = null;
53453 context.container().select(".main-footer-wrap").classed("footer-hide", false).classed("footer-show", true);
53454 context.container().select(".flash-wrap").classed("footer-hide", true).classed("footer-show", false);
53458 flash.duration = function(_) {
53459 if (!arguments.length)
53464 flash.label = function(_) {
53465 if (!arguments.length)
53467 if (typeof _ !== "function") {
53468 _label = (selection2) => selection2.text(_);
53470 _label = (selection2) => selection2.text("").call(_);
53474 flash.iconName = function(_) {
53475 if (!arguments.length)
53480 flash.iconClass = function(_) {
53481 if (!arguments.length)
53489 // modules/ui/full_screen.js
53490 function uiFullScreen(context) {
53491 var element = context.container().node();
53492 function getFullScreenFn() {
53493 if (element.requestFullscreen) {
53494 return element.requestFullscreen;
53495 } else if (element.msRequestFullscreen) {
53496 return element.msRequestFullscreen;
53497 } else if (element.mozRequestFullScreen) {
53498 return element.mozRequestFullScreen;
53499 } else if (element.webkitRequestFullscreen) {
53500 return element.webkitRequestFullscreen;
53503 function getExitFullScreenFn() {
53504 if (document.exitFullscreen) {
53505 return document.exitFullscreen;
53506 } else if (document.msExitFullscreen) {
53507 return document.msExitFullscreen;
53508 } else if (document.mozCancelFullScreen) {
53509 return document.mozCancelFullScreen;
53510 } else if (document.webkitExitFullscreen) {
53511 return document.webkitExitFullscreen;
53514 function isFullScreen() {
53515 return document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement;
53517 function isSupported() {
53518 return !!getFullScreenFn();
53520 function fullScreen(d3_event) {
53521 d3_event.preventDefault();
53522 if (!isFullScreen()) {
53523 getFullScreenFn().apply(element);
53525 getExitFullScreenFn().apply(document);
53528 return function() {
53529 if (!isSupported())
53531 var detected = utilDetect();
53532 var keys = detected.os === "mac" ? [uiCmd("\u2303\u2318F"), "f11"] : ["f11"];
53533 context.keybinding().on(keys, fullScreen);
53537 // modules/ui/geolocate.js
53538 function uiGeolocate(context) {
53539 var _geolocationOptions = {
53540 // prioritize speed and power usage over precision
53541 enableHighAccuracy: false,
53542 // don't hang indefinitely getting the location
53546 var _locating = uiLoading(context).message(_t.html("geolocate.locating")).blocking(true);
53547 var _layer = context.layers().layer("geolocate");
53551 var _button = select_default2(null);
53553 if (context.inIntro())
53555 if (!_layer.enabled() && !_locating.isShown()) {
53556 _timeoutID = setTimeout(
53561 context.container().call(_locating);
53562 navigator.geolocation.getCurrentPosition(success, error, _geolocationOptions);
53565 _layer.enabled(null, false);
53566 updateButtonState();
53569 function zoomTo() {
53570 context.enter(modeBrowse(context));
53571 var map2 = context.map();
53572 _layer.enabled(_position, true);
53573 updateButtonState();
53574 map2.centerZoomEase(_extent.center(), Math.min(20, map2.extentZoom(_extent)));
53576 function success(geolocation) {
53577 _position = geolocation;
53578 var coords = _position.coords;
53579 _extent = geoExtent([coords.longitude, coords.latitude]).padByMeters(coords.accuracy);
53587 context.ui().flash.label(_t.append("geolocate.location_unavailable")).iconName("#iD-icon-geolocate")();
53591 function finish() {
53594 clearTimeout(_timeoutID);
53596 _timeoutID = void 0;
53598 function updateButtonState() {
53599 _button.classed("active", _layer.enabled());
53600 _button.attr("aria-pressed", _layer.enabled());
53602 return function(selection2) {
53603 if (!navigator.geolocation || !navigator.geolocation.getCurrentPosition)
53605 _button = selection2.append("button").on("click", click).attr("aria-pressed", false).call(svgIcon("#iD-icon-geolocate", "light")).call(
53606 uiTooltip().placement(_mainLocalizer.textDirection() === "rtl" ? "right" : "left").title(() => _t.append("geolocate.title")).keys([_t("geolocate.key")])
53608 context.keybinding().on(_t("geolocate.key"), click);
53612 // modules/ui/panels/background.js
53613 function uiPanelBackground(context) {
53614 var background = context.background();
53615 var _currSourceName = null;
53616 var _metadata = {};
53617 var _metadataKeys = [
53625 var debouncedRedraw = debounce_default(redraw, 250);
53626 function redraw(selection2) {
53627 var source = background.baseLayerSource();
53630 var isDG = source.id.match(/^DigitalGlobe/i) !== null;
53631 var sourceLabel = source.label();
53632 if (_currSourceName !== sourceLabel) {
53633 _currSourceName = sourceLabel;
53636 selection2.text("");
53637 var list = selection2.append("ul").attr("class", "background-info");
53638 list.append("li").call(_currSourceName);
53639 _metadataKeys.forEach(function(k) {
53640 if (isDG && k === "vintage")
53642 list.append("li").attr("class", "background-info-list-" + k).classed("hide", !_metadata[k]).call(_t.append("info_panels.background." + k, { suffix: ":" })).append("span").attr("class", "background-info-span-" + k).text(_metadata[k]);
53644 debouncedGetMetadata(selection2);
53645 var toggleTiles = context.getDebug("tile") ? "hide_tiles" : "show_tiles";
53646 selection2.append("a").call(_t.append("info_panels.background." + toggleTiles)).attr("href", "#").attr("class", "button button-toggle-tiles").on("click", function(d3_event) {
53647 d3_event.preventDefault();
53648 context.setDebug("tile", !context.getDebug("tile"));
53649 selection2.call(redraw);
53652 var key = source.id + "-vintage";
53653 var sourceVintage = context.background().findSource(key);
53654 var showsVintage = context.background().showsLayer(sourceVintage);
53655 var toggleVintage = showsVintage ? "hide_vintage" : "show_vintage";
53656 selection2.append("a").call(_t.append("info_panels.background." + toggleVintage)).attr("href", "#").attr("class", "button button-toggle-vintage").on("click", function(d3_event) {
53657 d3_event.preventDefault();
53658 context.background().toggleOverlayLayer(sourceVintage);
53659 selection2.call(redraw);
53662 ["DigitalGlobe-Premium", "DigitalGlobe-Standard"].forEach(function(layerId) {
53663 if (source.id !== layerId) {
53664 var key2 = layerId + "-vintage";
53665 var sourceVintage2 = context.background().findSource(key2);
53666 if (context.background().showsLayer(sourceVintage2)) {
53667 context.background().toggleOverlayLayer(sourceVintage2);
53672 var debouncedGetMetadata = debounce_default(getMetadata, 250);
53673 function getMetadata(selection2) {
53674 var tile = context.container().select(".layer-background img.tile-center");
53677 var sourceName = _currSourceName;
53678 var d = tile.datum();
53679 var zoom = d && d.length >= 3 && d[2] || Math.floor(context.map().zoom());
53680 var center = context.map().center();
53681 _metadata.zoom = String(zoom);
53682 selection2.selectAll(".background-info-list-zoom").classed("hide", false).selectAll(".background-info-span-zoom").text(_metadata.zoom);
53683 if (!d || !d.length >= 3)
53685 background.baseLayerSource().getMetadata(center, d, function(err, result) {
53686 if (err || _currSourceName !== sourceName)
53688 var vintage = result.vintage;
53689 _metadata.vintage = vintage && vintage.range || _t("info_panels.background.unknown");
53690 selection2.selectAll(".background-info-list-vintage").classed("hide", false).selectAll(".background-info-span-vintage").text(_metadata.vintage);
53691 _metadataKeys.forEach(function(k) {
53692 if (k === "zoom" || k === "vintage")
53694 var val = result[k];
53695 _metadata[k] = val;
53696 selection2.selectAll(".background-info-list-" + k).classed("hide", !val).selectAll(".background-info-span-" + k).text(val);
53700 var panel = function(selection2) {
53701 selection2.call(redraw);
53702 context.map().on("drawn.info-background", function() {
53703 selection2.call(debouncedRedraw);
53704 }).on("move.info-background", function() {
53705 selection2.call(debouncedGetMetadata);
53708 panel.off = function() {
53709 context.map().on("drawn.info-background", null).on("move.info-background", null);
53711 panel.id = "background";
53712 panel.label = _t.append("info_panels.background.title");
53713 panel.key = _t("info_panels.background.key");
53717 // modules/ui/panels/history.js
53718 function uiPanelHistory(context) {
53720 function displayTimestamp(timestamp) {
53722 return _t("info_panels.history.unknown");
53731 var d = new Date(timestamp);
53732 if (isNaN(d.getTime()))
53733 return _t("info_panels.history.unknown");
53734 return d.toLocaleString(_mainLocalizer.localeCode(), options2);
53736 function displayUser(selection2, userName) {
53738 selection2.append("span").call(_t.append("info_panels.history.unknown"));
53741 selection2.append("span").attr("class", "user-name").text(userName);
53742 var links = selection2.append("div").attr("class", "links");
53744 links.append("a").attr("class", "user-osm-link").attr("href", osm.userURL(userName)).attr("target", "_blank").call(_t.append("info_panels.history.profile_link"));
53746 links.append("a").attr("class", "user-hdyc-link").attr("href", "https://hdyc.neis-one.org/?" + userName).attr("target", "_blank").attr("tabindex", -1).text("HDYC");
53748 function displayChangeset(selection2, changeset) {
53750 selection2.append("span").call(_t.append("info_panels.history.unknown"));
53753 selection2.append("span").attr("class", "changeset-id").text(changeset);
53754 var links = selection2.append("div").attr("class", "links");
53756 links.append("a").attr("class", "changeset-osm-link").attr("href", osm.changesetURL(changeset)).attr("target", "_blank").call(_t.append("info_panels.history.changeset_link"));
53758 links.append("a").attr("class", "changeset-osmcha-link").attr("href", "https://osmcha.org/changesets/" + changeset).attr("target", "_blank").text("OSMCha");
53759 links.append("a").attr("class", "changeset-achavi-link").attr("href", "https://overpass-api.de/achavi/?changeset=" + changeset).attr("target", "_blank").text("Achavi");
53761 function redraw(selection2) {
53762 var selectedNoteID = context.selectedNoteID();
53763 osm = context.connection();
53764 var selected, note, entity;
53765 if (selectedNoteID && osm) {
53766 selected = [_t.html("note.note") + " " + selectedNoteID];
53767 note = osm.getNote(selectedNoteID);
53769 selected = context.selectedIDs().filter(function(e) {
53770 return context.hasEntity(e);
53772 if (selected.length) {
53773 entity = context.entity(selected[0]);
53776 var singular = selected.length === 1 ? selected[0] : null;
53777 selection2.html("");
53779 selection2.append("h4").attr("class", "history-heading").html(singular);
53781 selection2.append("h4").attr("class", "history-heading").call(_t.append("info_panels.selected", { n: selected.length }));
53786 selection2.call(redrawEntity, entity);
53788 selection2.call(redrawNote, note);
53791 function redrawNote(selection2, note) {
53792 if (!note || note.isNew()) {
53793 selection2.append("div").call(_t.append("info_panels.history.note_no_history"));
53796 var list = selection2.append("ul");
53797 list.append("li").call(_t.append("info_panels.history.note_comments", { suffix: ":" })).append("span").text(note.comments.length);
53798 if (note.comments.length) {
53799 list.append("li").call(_t.append("info_panels.history.note_created_date", { suffix: ":" })).append("span").text(displayTimestamp(note.comments[0].date));
53800 list.append("li").call(_t.append("info_panels.history.note_created_user", { suffix: ":" })).call(displayUser, note.comments[0].user);
53803 selection2.append("a").attr("class", "view-history-on-osm").attr("target", "_blank").attr("href", osm.noteURL(note)).call(svgIcon("#iD-icon-out-link", "inline")).append("span").call(_t.append("info_panels.history.note_link_text"));
53806 function redrawEntity(selection2, entity) {
53807 if (!entity || entity.isNew()) {
53808 selection2.append("div").call(_t.append("info_panels.history.no_history"));
53811 var links = selection2.append("div").attr("class", "links");
53813 links.append("a").attr("class", "view-history-on-osm").attr("href", osm.historyURL(entity)).attr("target", "_blank").call(_t.append("info_panels.history.history_link"));
53815 links.append("a").attr("class", "pewu-history-viewer-link").attr("href", "https://pewu.github.io/osm-history/#/" + entity.type + "/" + entity.osmId()).attr("target", "_blank").attr("tabindex", -1).text("PeWu");
53816 var list = selection2.append("ul");
53817 list.append("li").call(_t.append("info_panels.history.version", { suffix: ":" })).append("span").text(entity.version);
53818 list.append("li").call(_t.append("info_panels.history.last_edit", { suffix: ":" })).append("span").text(displayTimestamp(entity.timestamp));
53819 list.append("li").call(_t.append("info_panels.history.edited_by", { suffix: ":" })).call(displayUser, entity.user);
53820 list.append("li").call(_t.append("info_panels.history.changeset", { suffix: ":" })).call(displayChangeset, entity.changeset);
53822 var panel = function(selection2) {
53823 selection2.call(redraw);
53824 context.map().on("drawn.info-history", function() {
53825 selection2.call(redraw);
53827 context.on("enter.info-history", function() {
53828 selection2.call(redraw);
53831 panel.off = function() {
53832 context.map().on("drawn.info-history", null);
53833 context.on("enter.info-history", null);
53835 panel.id = "history";
53836 panel.label = _t.append("info_panels.history.title");
53837 panel.key = _t("info_panels.history.key");
53841 // modules/util/units.js
53842 var OSM_PRECISION = 7;
53843 function displayLength(m, isImperial) {
53844 var d = m * (isImperial ? 3.28084 : 1);
53856 unit2 = "kilometers";
53861 return _t("units." + unit2, {
53862 quantity: d.toLocaleString(_mainLocalizer.localeCode(), {
53863 maximumSignificantDigits: 4
53867 function displayArea(m2, isImperial) {
53868 var locale2 = _mainLocalizer.localeCode();
53869 var d = m2 * (isImperial ? 10.7639111056 : 1);
53874 if (d >= 6969600) {
53876 unit1 = "square_miles";
53879 unit1 = "square_feet";
53881 if (d > 4356 && d < 4356e4) {
53888 unit1 = "square_kilometers";
53891 unit1 = "square_meters";
53893 if (d > 1e3 && d < 1e7) {
53895 unit2 = "hectares";
53898 area = _t("units." + unit1, {
53899 quantity: d1.toLocaleString(locale2, {
53900 maximumSignificantDigits: 4
53904 return _t("units.area_pair", {
53906 area2: _t("units." + unit2, {
53907 quantity: d2.toLocaleString(locale2, {
53908 maximumSignificantDigits: 2
53916 function wrap(x, min3, max3) {
53917 var d = max3 - min3;
53918 return ((x - min3) % d + d) % d + min3;
53920 function clamp2(x, min3, max3) {
53921 return Math.max(min3, Math.min(x, max3));
53923 function displayCoordinate(deg, pos, neg) {
53924 var locale2 = _mainLocalizer.localeCode();
53925 var min3 = (Math.abs(deg) - Math.floor(Math.abs(deg))) * 60;
53926 var sec = (min3 - Math.floor(min3)) * 60;
53927 var displayDegrees = _t("units.arcdegrees", {
53928 quantity: Math.floor(Math.abs(deg)).toLocaleString(locale2)
53930 var displayCoordinate2;
53931 if (Math.floor(sec) > 0) {
53932 displayCoordinate2 = displayDegrees + _t("units.arcminutes", {
53933 quantity: Math.floor(min3).toLocaleString(locale2)
53934 }) + _t("units.arcseconds", {
53935 quantity: Math.round(sec).toLocaleString(locale2)
53937 } else if (Math.floor(min3) > 0) {
53938 displayCoordinate2 = displayDegrees + _t("units.arcminutes", {
53939 quantity: Math.round(min3).toLocaleString(locale2)
53942 displayCoordinate2 = _t("units.arcdegrees", {
53943 quantity: Math.round(Math.abs(deg)).toLocaleString(locale2)
53947 return displayCoordinate2;
53949 return _t("units.coordinate", {
53950 coordinate: displayCoordinate2,
53951 direction: _t("units." + (deg > 0 ? pos : neg))
53955 function dmsCoordinatePair(coord2) {
53956 return _t("units.coordinate_pair", {
53957 latitude: displayCoordinate(clamp2(coord2[1], -90, 90), "north", "south"),
53958 longitude: displayCoordinate(wrap(coord2[0], -180, 180), "east", "west")
53961 function decimalCoordinatePair(coord2) {
53962 return _t("units.coordinate_pair", {
53963 latitude: clamp2(coord2[1], -90, 90).toFixed(OSM_PRECISION),
53964 longitude: wrap(coord2[0], -180, 180).toFixed(OSM_PRECISION)
53968 // modules/ui/panels/location.js
53969 function uiPanelLocation(context) {
53970 var currLocation = "";
53971 function redraw(selection2) {
53972 selection2.html("");
53973 var list = selection2.append("ul");
53974 var coord2 = context.map().mouseCoordinates();
53975 if (coord2.some(isNaN)) {
53976 coord2 = context.map().center();
53978 list.append("li").text(dmsCoordinatePair(coord2)).append("li").text(decimalCoordinatePair(coord2));
53979 selection2.append("div").attr("class", "location-info").text(currLocation || " ");
53980 debouncedGetLocation(selection2, coord2);
53982 var debouncedGetLocation = debounce_default(getLocation, 250);
53983 function getLocation(selection2, coord2) {
53984 if (!services.geocoder) {
53985 currLocation = _t("info_panels.location.unknown_location");
53986 selection2.selectAll(".location-info").text(currLocation);
53988 services.geocoder.reverse(coord2, function(err, result) {
53989 currLocation = result ? result.display_name : _t("info_panels.location.unknown_location");
53990 selection2.selectAll(".location-info").text(currLocation);
53994 var panel = function(selection2) {
53995 selection2.call(redraw);
53996 context.surface().on(("PointerEvent" in window ? "pointer" : "mouse") + "move.info-location", function() {
53997 selection2.call(redraw);
54000 panel.off = function() {
54001 context.surface().on(".info-location", null);
54003 panel.id = "location";
54004 panel.label = _t.append("info_panels.location.title");
54005 panel.key = _t("info_panels.location.key");
54009 // modules/ui/panels/measurement.js
54010 function uiPanelMeasurement(context) {
54011 function radiansToMeters(r) {
54012 return r * 63710071809e-4;
54014 function steradiansToSqmeters(r) {
54015 return r / (4 * Math.PI) * 510065621724e3;
54017 function toLineString(feature3) {
54018 if (feature3.type === "LineString")
54020 var result = { type: "LineString", coordinates: [] };
54021 if (feature3.type === "Polygon") {
54022 result.coordinates = feature3.coordinates[0];
54023 } else if (feature3.type === "MultiPolygon") {
54024 result.coordinates = feature3.coordinates[0][0];
54028 var _isImperial = !_mainLocalizer.usesMetric();
54029 function redraw(selection2) {
54030 var graph = context.graph();
54031 var selectedNoteID = context.selectedNoteID();
54032 var osm = services.osm;
54033 var localeCode = _mainLocalizer.localeCode();
54035 var center, location, centroid;
54036 var closed, geometry;
54037 var totalNodeCount, length = 0, area = 0, distance;
54038 if (selectedNoteID && osm) {
54039 var note = osm.getNote(selectedNoteID);
54040 heading = _t.html("note.note") + " " + selectedNoteID;
54041 location = note.loc;
54044 var selectedIDs = context.selectedIDs().filter(function(id2) {
54045 return context.hasEntity(id2);
54047 var selected = selectedIDs.map(function(id2) {
54048 return context.entity(id2);
54050 heading = selected.length === 1 ? selected[0].id : _t.html("info_panels.selected", { n: selected.length });
54051 if (selected.length) {
54052 var extent = geoExtent();
54053 for (var i2 in selected) {
54054 var entity = selected[i2];
54055 extent._extend(entity.extent(graph));
54056 geometry = entity.geometry(graph);
54057 if (geometry === "line" || geometry === "area") {
54058 closed = entity.type === "relation" || entity.isClosed() && !entity.isDegenerate();
54059 var feature3 = entity.asGeoJSON(graph);
54060 length += radiansToMeters(length_default(toLineString(feature3)));
54061 centroid = path_default(context.projection).centroid(entity.asGeoJSON(graph));
54062 centroid = centroid && context.projection.invert(centroid);
54063 if (!centroid || !isFinite(centroid[0]) || !isFinite(centroid[1])) {
54064 centroid = entity.extent(graph).center();
54067 area += steradiansToSqmeters(entity.area(graph));
54071 if (selected.length > 1) {
54076 if (selected.length === 2 && selected[0].type === "node" && selected[1].type === "node") {
54077 distance = geoSphericalDistance(selected[0].loc, selected[1].loc);
54079 if (selected.length === 1 && selected[0].type === "node") {
54080 location = selected[0].loc;
54082 totalNodeCount = utilGetAllNodes(selectedIDs, context.graph()).length;
54084 if (!location && !centroid) {
54085 center = extent.center();
54089 selection2.html("");
54091 selection2.append("h4").attr("class", "measurement-heading").html(heading);
54093 var list = selection2.append("ul");
54096 list.append("li").call(_t.append("info_panels.measurement.geometry", { suffix: ":" })).append("span").html(
54097 closed ? _t.html("info_panels.measurement.closed_" + geometry) : _t.html("geometry." + geometry)
54100 if (totalNodeCount) {
54101 list.append("li").call(_t.append("info_panels.measurement.node_count", { suffix: ":" })).append("span").text(totalNodeCount.toLocaleString(localeCode));
54104 list.append("li").call(_t.append("info_panels.measurement.area", { suffix: ":" })).append("span").text(displayArea(area, _isImperial));
54107 list.append("li").call(_t.append("info_panels.measurement." + (closed ? "perimeter" : "length"), { suffix: ":" })).append("span").text(displayLength(length, _isImperial));
54109 if (typeof distance === "number") {
54110 list.append("li").call(_t.append("info_panels.measurement.distance", { suffix: ":" })).append("span").text(displayLength(distance, _isImperial));
54113 coordItem = list.append("li").call(_t.append("info_panels.measurement.location", { suffix: ":" }));
54114 coordItem.append("span").text(dmsCoordinatePair(location));
54115 coordItem.append("span").text(decimalCoordinatePair(location));
54118 coordItem = list.append("li").call(_t.append("info_panels.measurement.centroid", { suffix: ":" }));
54119 coordItem.append("span").text(dmsCoordinatePair(centroid));
54120 coordItem.append("span").text(decimalCoordinatePair(centroid));
54123 coordItem = list.append("li").call(_t.append("info_panels.measurement.center", { suffix: ":" }));
54124 coordItem.append("span").text(dmsCoordinatePair(center));
54125 coordItem.append("span").text(decimalCoordinatePair(center));
54127 if (length || area || typeof distance === "number") {
54128 var toggle = _isImperial ? "imperial" : "metric";
54129 selection2.append("a").call(_t.append("info_panels.measurement." + toggle)).attr("href", "#").attr("class", "button button-toggle-units").on("click", function(d3_event) {
54130 d3_event.preventDefault();
54131 _isImperial = !_isImperial;
54132 selection2.call(redraw);
54136 var panel = function(selection2) {
54137 selection2.call(redraw);
54138 context.map().on("drawn.info-measurement", function() {
54139 selection2.call(redraw);
54141 context.on("enter.info-measurement", function() {
54142 selection2.call(redraw);
54145 panel.off = function() {
54146 context.map().on("drawn.info-measurement", null);
54147 context.on("enter.info-measurement", null);
54149 panel.id = "measurement";
54150 panel.label = _t.append("info_panels.measurement.title");
54151 panel.key = _t("info_panels.measurement.key");
54155 // modules/ui/panels/index.js
54156 var uiInfoPanels = {
54157 background: uiPanelBackground,
54158 history: uiPanelHistory,
54159 location: uiPanelLocation,
54160 measurement: uiPanelMeasurement
54163 // modules/ui/info.js
54164 function uiInfo(context) {
54165 var ids = Object.keys(uiInfoPanels);
54166 var wasActive = ["measurement"];
54169 ids.forEach(function(k) {
54171 panels[k] = uiInfoPanels[k](context);
54175 function info(selection2) {
54176 function redraw() {
54177 var activeids = ids.filter(function(k) {
54180 var containers = infoPanels.selectAll(".panel-container").data(activeids, function(k) {
54183 containers.exit().style("opacity", 1).transition().duration(200).style("opacity", 0).on("end", function(d) {
54184 select_default2(this).call(panels[d].off).remove();
54186 var enter = containers.enter().append("div").attr("class", function(d) {
54187 return "fillD2 panel-container panel-container-" + d;
54189 enter.style("opacity", 0).transition().duration(200).style("opacity", 1);
54190 var title = enter.append("div").attr("class", "panel-title fillD2");
54191 title.append("h3").each(function(d) {
54192 return panels[d].label(select_default2(this));
54194 title.append("button").attr("class", "close").attr("title", _t("icons.close")).on("click", function(d3_event, d) {
54195 d3_event.stopImmediatePropagation();
54196 d3_event.preventDefault();
54198 }).call(svgIcon("#iD-icon-close"));
54199 enter.append("div").attr("class", function(d) {
54200 return "panel-content panel-content-" + d;
54202 infoPanels.selectAll(".panel-content").each(function(d) {
54203 select_default2(this).call(panels[d]);
54206 info.toggle = function(which) {
54207 var activeids = ids.filter(function(k) {
54211 active[which] = !active[which];
54212 if (activeids.length === 1 && activeids[0] === which) {
54213 wasActive = [which];
54215 context.container().select("." + which + "-panel-toggle-item").classed("active", active[which]).select("input").property("checked", active[which]);
54217 if (activeids.length) {
54218 wasActive = activeids;
54219 activeids.forEach(function(k) {
54223 wasActive.forEach(function(k) {
54230 var infoPanels = selection2.selectAll(".info-panels").data([0]);
54231 infoPanels = infoPanels.enter().append("div").attr("class", "info-panels").merge(infoPanels);
54233 context.keybinding().on(uiCmd("\u2318" + _t("info_panels.key")), function(d3_event) {
54234 d3_event.stopImmediatePropagation();
54235 d3_event.preventDefault();
54238 ids.forEach(function(k) {
54239 var key = _t("info_panels." + k + ".key", { default: null });
54242 context.keybinding().on(uiCmd("\u2318\u21E7" + key), function(d3_event) {
54243 d3_event.stopImmediatePropagation();
54244 d3_event.preventDefault();
54252 // modules/ui/intro/helper.js
54253 function pointBox(loc, context) {
54254 var rect = context.surfaceRect();
54255 var point2 = context.curtainProjection(loc);
54257 left: point2[0] + rect.left - 40,
54258 top: point2[1] + rect.top - 60,
54263 function pad(locOrBox, padding, context) {
54265 if (locOrBox instanceof Array) {
54266 var rect = context.surfaceRect();
54267 var point2 = context.curtainProjection(locOrBox);
54269 left: point2[0] + rect.left,
54270 top: point2[1] + rect.top
54276 left: box.left - padding,
54277 top: box.top - padding,
54278 width: (box.width || 0) + 2 * padding,
54279 height: (box.width || 0) + 2 * padding
54282 function icon(name, svgklass, useklass) {
54283 return '<svg class="icon ' + (svgklass || "") + '"><use xlink:href="' + name + '"' + (useklass ? ' class="' + useklass + '"' : "") + "></use></svg>";
54285 var helpStringReplacements;
54286 function helpHtml(id2, replacements) {
54287 if (!helpStringReplacements) {
54288 helpStringReplacements = {
54289 // insert icons corresponding to various UI elements
54290 point_icon: icon("#iD-icon-point", "inline"),
54291 line_icon: icon("#iD-icon-line", "inline"),
54292 area_icon: icon("#iD-icon-area", "inline"),
54293 note_icon: icon("#iD-icon-note", "inline add-note"),
54294 plus: icon("#iD-icon-plus", "inline"),
54295 minus: icon("#iD-icon-minus", "inline"),
54296 layers_icon: icon("#iD-icon-layers", "inline"),
54297 data_icon: icon("#iD-icon-data", "inline"),
54298 inspect: icon("#iD-icon-inspect", "inline"),
54299 help_icon: icon("#iD-icon-help", "inline"),
54300 undo_icon: icon(_mainLocalizer.textDirection() === "rtl" ? "#iD-icon-redo" : "#iD-icon-undo", "inline"),
54301 redo_icon: icon(_mainLocalizer.textDirection() === "rtl" ? "#iD-icon-undo" : "#iD-icon-redo", "inline"),
54302 save_icon: icon("#iD-icon-save", "inline"),
54304 circularize_icon: icon("#iD-operation-circularize", "inline operation"),
54305 continue_icon: icon("#iD-operation-continue", "inline operation"),
54306 copy_icon: icon("#iD-operation-copy", "inline operation"),
54307 delete_icon: icon("#iD-operation-delete", "inline operation"),
54308 disconnect_icon: icon("#iD-operation-disconnect", "inline operation"),
54309 downgrade_icon: icon("#iD-operation-downgrade", "inline operation"),
54310 extract_icon: icon("#iD-operation-extract", "inline operation"),
54311 merge_icon: icon("#iD-operation-merge", "inline operation"),
54312 move_icon: icon("#iD-operation-move", "inline operation"),
54313 orthogonalize_icon: icon("#iD-operation-orthogonalize", "inline operation"),
54314 paste_icon: icon("#iD-operation-paste", "inline operation"),
54315 reflect_long_icon: icon("#iD-operation-reflect-long", "inline operation"),
54316 reflect_short_icon: icon("#iD-operation-reflect-short", "inline operation"),
54317 reverse_icon: icon("#iD-operation-reverse", "inline operation"),
54318 rotate_icon: icon("#iD-operation-rotate", "inline operation"),
54319 split_icon: icon("#iD-operation-split", "inline operation"),
54320 straighten_icon: icon("#iD-operation-straighten", "inline operation"),
54321 // interaction icons
54322 leftclick: icon("#iD-walkthrough-mouse-left", "inline operation"),
54323 rightclick: icon("#iD-walkthrough-mouse-right", "inline operation"),
54324 mousewheel_icon: icon("#iD-walkthrough-mousewheel", "inline operation"),
54325 tap_icon: icon("#iD-walkthrough-tap", "inline operation"),
54326 doubletap_icon: icon("#iD-walkthrough-doubletap", "inline operation"),
54327 longpress_icon: icon("#iD-walkthrough-longpress", "inline operation"),
54328 touchdrag_icon: icon("#iD-walkthrough-touchdrag", "inline operation"),
54329 pinch_icon: icon("#iD-walkthrough-pinch-apart", "inline operation"),
54330 // insert keys; may be localized and platform-dependent
54331 shift: uiCmd.display("\u21E7"),
54332 alt: uiCmd.display("\u2325"),
54333 return: uiCmd.display("\u21B5"),
54334 esc: _t.html("shortcuts.key.esc"),
54335 space: _t.html("shortcuts.key.space"),
54336 add_note_key: _t.html("modes.add_note.key"),
54337 help_key: _t.html("help.key"),
54338 shortcuts_key: _t.html("shortcuts.toggle.key"),
54339 // reference localized UI labels directly so that they'll always match
54340 save: _t.html("save.title"),
54341 undo: _t.html("undo.title"),
54342 redo: _t.html("redo.title"),
54343 upload: _t.html("commit.save"),
54344 point: _t.html("modes.add_point.title"),
54345 line: _t.html("modes.add_line.title"),
54346 area: _t.html("modes.add_area.title"),
54347 note: _t.html("modes.add_note.label"),
54348 circularize: _t.html("operations.circularize.title"),
54349 continue: _t.html("operations.continue.title"),
54350 copy: _t.html("operations.copy.title"),
54351 delete: _t.html("operations.delete.title"),
54352 disconnect: _t.html("operations.disconnect.title"),
54353 downgrade: _t.html("operations.downgrade.title"),
54354 extract: _t.html("operations.extract.title"),
54355 merge: _t.html("operations.merge.title"),
54356 move: _t.html("operations.move.title"),
54357 orthogonalize: _t.html("operations.orthogonalize.title"),
54358 paste: _t.html("operations.paste.title"),
54359 reflect_long: _t.html("operations.reflect.title.long"),
54360 reflect_short: _t.html("operations.reflect.title.short"),
54361 reverse: _t.html("operations.reverse.title"),
54362 rotate: _t.html("operations.rotate.title"),
54363 split: _t.html("operations.split.title"),
54364 straighten: _t.html("operations.straighten.title"),
54365 map_data: _t.html("map_data.title"),
54366 osm_notes: _t.html("map_data.layers.notes.title"),
54367 fields: _t.html("inspector.fields"),
54368 tags: _t.html("inspector.tags"),
54369 relations: _t.html("inspector.relations"),
54370 new_relation: _t.html("inspector.new_relation"),
54371 turn_restrictions: _t.html("_tagging.presets.fields.restrictions.label"),
54372 background_settings: _t.html("background.description"),
54373 imagery_offset: _t.html("background.fix_misalignment"),
54374 start_the_walkthrough: _t.html("splash.walkthrough"),
54375 help: _t.html("help.title"),
54376 ok: _t.html("intro.ok")
54378 for (var key in helpStringReplacements) {
54379 helpStringReplacements[key] = { html: helpStringReplacements[key] };
54383 if (replacements) {
54384 reps = Object.assign(replacements, helpStringReplacements);
54386 reps = helpStringReplacements;
54388 return _t.html(id2, reps).replace(/\`(.*?)\`/g, "<kbd>$1</kbd>");
54390 function slugify(text2) {
54391 return text2.toString().toLowerCase().replace(/\s+/g, "-").replace(/[^\w\-]+/g, "").replace(/\-\-+/g, "-").replace(/^-+/, "").replace(/-+$/, "");
54393 var missingStrings = {};
54394 function checkKey(key, text2) {
54395 if (_t(key, { default: void 0 }) === void 0) {
54396 if (missingStrings.hasOwnProperty(key))
54398 missingStrings[key] = text2;
54399 var missing = key + ": " + text2;
54400 if (typeof console !== "undefined")
54401 console.log(missing);
54404 function localize(obj) {
54406 var name = obj.tags && obj.tags.name;
54408 key = "intro.graph.name." + slugify(name);
54409 obj.tags.name = _t(key, { default: name });
54410 checkKey(key, name);
54412 var street = obj.tags && obj.tags["addr:street"];
54414 key = "intro.graph.name." + slugify(street);
54415 obj.tags["addr:street"] = _t(key, { default: street });
54416 checkKey(key, street);
54431 addrTags.forEach(function(k) {
54432 var key2 = "intro.graph." + k;
54433 var tag = "addr:" + k;
54434 var val = obj.tags && obj.tags[tag];
54435 var str2 = _t(key2, { default: val });
54437 if (str2.match(/^<.*>$/) !== null) {
54438 delete obj.tags[tag];
54440 obj.tags[tag] = str2;
54447 function isMostlySquare(points) {
54448 var threshold = 15;
54449 var lowerBound = Math.cos((90 - threshold) * Math.PI / 180);
54450 var upperBound = Math.cos(threshold * Math.PI / 180);
54451 for (var i2 = 0; i2 < points.length; i2++) {
54452 var a = points[(i2 - 1 + points.length) % points.length];
54453 var origin = points[i2];
54454 var b = points[(i2 + 1) % points.length];
54455 var dotp = geoVecNormalizedDot(a, b, origin);
54456 var mag = Math.abs(dotp);
54457 if (mag > lowerBound && mag < upperBound) {
54463 function selectMenuItem(context, operation) {
54464 return context.container().select(".edit-menu .edit-menu-item-" + operation);
54466 function transitionTime(point1, point2) {
54467 var distance = geoSphericalDistance(point1, point2);
54468 if (distance === 0) {
54470 } else if (distance < 80) {
54477 // modules/ui/toggle.js
54478 function uiToggle(show, callback) {
54479 return function(selection2) {
54480 selection2.style("opacity", show ? 0 : 1).classed("hide", false).transition().style("opacity", show ? 1 : 0).on("end", function() {
54481 select_default2(this).classed("hide", !show).style("opacity", null);
54483 callback.apply(this);
54488 // modules/ui/curtain.js
54489 function uiCurtain(containerNode) {
54490 var surface = select_default2(null), tooltip = select_default2(null), darkness = select_default2(null);
54491 function curtain(selection2) {
54492 surface = selection2.append("svg").attr("class", "curtain").style("top", 0).style("left", 0);
54493 darkness = surface.append("path").attr("x", 0).attr("y", 0).attr("class", "curtain-darkness");
54494 select_default2(window).on("resize.curtain", resize);
54495 tooltip = selection2.append("div").attr("class", "tooltip");
54496 tooltip.append("div").attr("class", "popover-arrow");
54497 tooltip.append("div").attr("class", "popover-inner");
54499 function resize() {
54500 surface.attr("width", containerNode.clientWidth).attr("height", containerNode.clientHeight);
54501 curtain.cut(darkness.datum());
54504 curtain.reveal = function(box, html2, options2) {
54505 options2 = options2 || {};
54506 if (typeof box === "string") {
54507 box = select_default2(box).node();
54509 if (box && box.getBoundingClientRect) {
54510 box = copyBox(box.getBoundingClientRect());
54511 var containerRect = containerNode.getBoundingClientRect();
54512 box.top -= containerRect.top;
54513 box.left -= containerRect.left;
54515 if (box && options2.padding) {
54516 box.top -= options2.padding;
54517 box.left -= options2.padding;
54518 box.bottom += options2.padding;
54519 box.right += options2.padding;
54520 box.height += options2.padding * 2;
54521 box.width += options2.padding * 2;
54524 if (options2.tooltipBox) {
54525 tooltipBox = options2.tooltipBox;
54526 if (typeof tooltipBox === "string") {
54527 tooltipBox = select_default2(tooltipBox).node();
54529 if (tooltipBox && tooltipBox.getBoundingClientRect) {
54530 tooltipBox = copyBox(tooltipBox.getBoundingClientRect());
54535 if (tooltipBox && html2) {
54536 if (html2.indexOf("**") !== -1) {
54537 if (html2.indexOf("<span") === 0) {
54538 html2 = html2.replace(/^(<span.*?>)(.+?)(\*\*)/, "$1<span>$2</span>$3");
54540 html2 = html2.replace(/^(.+?)(\*\*)/, "<span>$1</span>$2");
54542 html2 = html2.replace(/\*\*(.*?)\*\*/g, '<span class="instruction">$1</span>');
54544 html2 = html2.replace(/\*(.*?)\*/g, "<em>$1</em>");
54545 html2 = html2.replace(/\{br\}/g, "<br/><br/>");
54546 if (options2.buttonText && options2.buttonCallback) {
54547 html2 += '<div class="button-section"><button href="#" class="button action">' + options2.buttonText + "</button></div>";
54549 var classes = "curtain-tooltip popover tooltip arrowed in " + (options2.tooltipClass || "");
54550 tooltip.classed(classes, true).selectAll(".popover-inner").html(html2);
54551 if (options2.buttonText && options2.buttonCallback) {
54552 var button = tooltip.selectAll(".button-section .button.action");
54553 button.on("click", function(d3_event) {
54554 d3_event.preventDefault();
54555 options2.buttonCallback();
54558 var tip = copyBox(tooltip.node().getBoundingClientRect()), w = containerNode.clientWidth, h = containerNode.clientHeight, tooltipWidth = 200, tooltipArrow = 5, side, pos;
54559 if (options2.tooltipClass === "intro-mouse") {
54562 if (tooltipBox.top + tooltipBox.height > h) {
54563 tooltipBox.height -= tooltipBox.top + tooltipBox.height - h;
54565 if (tooltipBox.left + tooltipBox.width > w) {
54566 tooltipBox.width -= tooltipBox.left + tooltipBox.width - w;
54568 if (tooltipBox.top + tooltipBox.height < 100) {
54571 tooltipBox.left + tooltipBox.width / 2 - tip.width / 2,
54572 tooltipBox.top + tooltipBox.height
54574 } else if (tooltipBox.top > h - 140) {
54577 tooltipBox.left + tooltipBox.width / 2 - tip.width / 2,
54578 tooltipBox.top - tip.height
54581 var tipY = tooltipBox.top + tooltipBox.height / 2 - tip.height / 2;
54582 if (_mainLocalizer.textDirection() === "rtl") {
54583 if (tooltipBox.left - tooltipWidth - tooltipArrow < 70) {
54585 pos = [tooltipBox.left + tooltipBox.width + tooltipArrow, tipY];
54588 pos = [tooltipBox.left - tooltipWidth - tooltipArrow, tipY];
54591 if (tooltipBox.left + tooltipBox.width + tooltipArrow + tooltipWidth > w - 70) {
54593 pos = [tooltipBox.left - tooltipWidth - tooltipArrow, tipY];
54596 pos = [tooltipBox.left + tooltipBox.width + tooltipArrow, tipY];
54600 if (options2.duration !== 0 || !tooltip.classed(side)) {
54601 tooltip.call(uiToggle(true));
54603 tooltip.style("top", pos[1] + "px").style("left", pos[0] + "px").attr("class", classes + " " + side);
54605 if (side === "left" || side === "right") {
54607 shiftY = 60 - pos[1];
54608 } else if (pos[1] + tip.height > h - 100) {
54609 shiftY = h - pos[1] - tip.height - 100;
54612 tooltip.selectAll(".popover-inner").style("top", shiftY + "px");
54614 tooltip.classed("in", false).call(uiToggle(false));
54616 curtain.cut(box, options2.duration);
54619 curtain.cut = function(datum2, duration) {
54620 darkness.datum(datum2).interrupt();
54622 if (duration === 0) {
54623 selection2 = darkness;
54625 selection2 = darkness.transition().duration(duration || 600).ease(linear2);
54627 selection2.attr("d", function(d) {
54628 var containerWidth = containerNode.clientWidth;
54629 var containerHeight = containerNode.clientHeight;
54630 var string = "M 0,0 L 0," + containerHeight + " L " + containerWidth + "," + containerHeight + "L" + containerWidth + ",0 Z";
54633 return string + "M" + d.left + "," + d.top + "L" + d.left + "," + (d.top + d.height) + "L" + (d.left + d.width) + "," + (d.top + d.height) + "L" + (d.left + d.width) + "," + d.top + "Z";
54636 curtain.remove = function() {
54639 select_default2(window).on("resize.curtain", null);
54641 function copyBox(src) {
54645 bottom: src.bottom,
54654 // modules/ui/intro/welcome.js
54655 function uiIntroWelcome(context, reveal) {
54656 var dispatch10 = dispatch_default("done");
54658 title: "intro.welcome.title"
54660 function welcome() {
54661 context.map().centerZoom([-85.63591, 41.94285], 19);
54663 ".intro-nav-wrap .chapter-welcome",
54664 helpHtml("intro.welcome.welcome"),
54665 { buttonText: _t.html("intro.ok"), buttonCallback: practice }
54668 function practice() {
54670 ".intro-nav-wrap .chapter-welcome",
54671 helpHtml("intro.welcome.practice"),
54672 { buttonText: _t.html("intro.ok"), buttonCallback: words }
54677 ".intro-nav-wrap .chapter-welcome",
54678 helpHtml("intro.welcome.words"),
54679 { buttonText: _t.html("intro.ok"), buttonCallback: chapters }
54682 function chapters() {
54683 dispatch10.call("done");
54685 ".intro-nav-wrap .chapter-navigation",
54686 helpHtml("intro.welcome.chapters", { next: _t("intro.navigation.title") })
54689 chapter.enter = function() {
54692 chapter.exit = function() {
54693 context.container().select(".curtain-tooltip.intro-mouse").selectAll(".counter").remove();
54695 chapter.restart = function() {
54699 return utilRebind(chapter, dispatch10, "on");
54702 // modules/ui/intro/navigation.js
54703 function uiIntroNavigation(context, reveal) {
54704 var dispatch10 = dispatch_default("done");
54706 var hallId = "n2061";
54707 var townHall = [-85.63591, 41.94285];
54708 var springStreetId = "w397";
54709 var springStreetEndId = "n1834";
54710 var springStreet = [-85.63582, 41.94255];
54711 var onewayField = _mainPresetIndex.field("oneway");
54712 var maxspeedField = _mainPresetIndex.field("maxspeed");
54714 title: "intro.navigation.title"
54716 function timeout2(f2, t) {
54717 timeouts.push(window.setTimeout(f2, t));
54719 function eventCancel(d3_event) {
54720 d3_event.stopPropagation();
54721 d3_event.preventDefault();
54723 function isTownHallSelected() {
54724 var ids = context.selectedIDs();
54725 return ids.length === 1 && ids[0] === hallId;
54727 function dragMap() {
54728 context.enter(modeBrowse(context));
54729 context.history().reset("initial");
54730 var msec = transitionTime(townHall, context.map().center());
54732 reveal(null, null, { duration: 0 });
54734 context.map().centerZoomEase(townHall, 19, msec);
54735 timeout2(function() {
54736 var centerStart = context.map().center();
54737 var textId = context.lastPointerType() === "mouse" ? "drag" : "drag_touch";
54738 var dragString = helpHtml("intro.navigation.map_info") + "{br}" + helpHtml("intro.navigation." + textId);
54739 reveal(".surface", dragString);
54740 context.map().on("drawn.intro", function() {
54741 reveal(".surface", dragString, { duration: 0 });
54743 context.map().on("move.intro", function() {
54744 var centerNow = context.map().center();
54745 if (centerStart[0] !== centerNow[0] || centerStart[1] !== centerNow[1]) {
54746 context.map().on("move.intro", null);
54747 timeout2(function() {
54748 continueTo(zoomMap);
54753 function continueTo(nextStep) {
54754 context.map().on("move.intro drawn.intro", null);
54758 function zoomMap() {
54759 var zoomStart = context.map().zoom();
54760 var textId = context.lastPointerType() === "mouse" ? "zoom" : "zoom_touch";
54761 var zoomString = helpHtml("intro.navigation." + textId);
54762 reveal(".surface", zoomString);
54763 context.map().on("drawn.intro", function() {
54764 reveal(".surface", zoomString, { duration: 0 });
54766 context.map().on("move.intro", function() {
54767 if (context.map().zoom() !== zoomStart) {
54768 context.map().on("move.intro", null);
54769 timeout2(function() {
54770 continueTo(features);
54774 function continueTo(nextStep) {
54775 context.map().on("move.intro drawn.intro", null);
54779 function features() {
54780 var onClick = function() {
54781 continueTo(pointsLinesAreas);
54785 helpHtml("intro.navigation.features"),
54786 { buttonText: _t.html("intro.ok"), buttonCallback: onClick }
54788 context.map().on("drawn.intro", function() {
54791 helpHtml("intro.navigation.features"),
54792 { duration: 0, buttonText: _t.html("intro.ok"), buttonCallback: onClick }
54795 function continueTo(nextStep) {
54796 context.map().on("drawn.intro", null);
54800 function pointsLinesAreas() {
54801 var onClick = function() {
54802 continueTo(nodesWays);
54806 helpHtml("intro.navigation.points_lines_areas"),
54807 { buttonText: _t.html("intro.ok"), buttonCallback: onClick }
54809 context.map().on("drawn.intro", function() {
54812 helpHtml("intro.navigation.points_lines_areas"),
54813 { duration: 0, buttonText: _t.html("intro.ok"), buttonCallback: onClick }
54816 function continueTo(nextStep) {
54817 context.map().on("drawn.intro", null);
54821 function nodesWays() {
54822 var onClick = function() {
54823 continueTo(clickTownHall);
54827 helpHtml("intro.navigation.nodes_ways"),
54828 { buttonText: _t.html("intro.ok"), buttonCallback: onClick }
54830 context.map().on("drawn.intro", function() {
54833 helpHtml("intro.navigation.nodes_ways"),
54834 { duration: 0, buttonText: _t.html("intro.ok"), buttonCallback: onClick }
54837 function continueTo(nextStep) {
54838 context.map().on("drawn.intro", null);
54842 function clickTownHall() {
54843 context.enter(modeBrowse(context));
54844 context.history().reset("initial");
54845 var entity = context.hasEntity(hallId);
54848 reveal(null, null, { duration: 0 });
54849 context.map().centerZoomEase(entity.loc, 19, 500);
54850 timeout2(function() {
54851 var entity2 = context.hasEntity(hallId);
54854 var box = pointBox(entity2.loc, context);
54855 var textId = context.lastPointerType() === "mouse" ? "click_townhall" : "tap_townhall";
54856 reveal(box, helpHtml("intro.navigation." + textId));
54857 context.map().on("move.intro drawn.intro", function() {
54858 var entity3 = context.hasEntity(hallId);
54861 var box2 = pointBox(entity3.loc, context);
54862 reveal(box2, helpHtml("intro.navigation." + textId), { duration: 0 });
54864 context.on("enter.intro", function() {
54865 if (isTownHallSelected())
54866 continueTo(selectedTownHall);
54869 context.history().on("change.intro", function() {
54870 if (!context.hasEntity(hallId)) {
54871 continueTo(clickTownHall);
54874 function continueTo(nextStep) {
54875 context.on("enter.intro", null);
54876 context.map().on("move.intro drawn.intro", null);
54877 context.history().on("change.intro", null);
54881 function selectedTownHall() {
54882 if (!isTownHallSelected())
54883 return clickTownHall();
54884 var entity = context.hasEntity(hallId);
54886 return clickTownHall();
54887 var box = pointBox(entity.loc, context);
54888 var onClick = function() {
54889 continueTo(editorTownHall);
54893 helpHtml("intro.navigation.selected_townhall"),
54894 { buttonText: _t.html("intro.ok"), buttonCallback: onClick }
54896 context.map().on("move.intro drawn.intro", function() {
54897 var entity2 = context.hasEntity(hallId);
54900 var box2 = pointBox(entity2.loc, context);
54903 helpHtml("intro.navigation.selected_townhall"),
54904 { duration: 0, buttonText: _t.html("intro.ok"), buttonCallback: onClick }
54907 context.history().on("change.intro", function() {
54908 if (!context.hasEntity(hallId)) {
54909 continueTo(clickTownHall);
54912 function continueTo(nextStep) {
54913 context.map().on("move.intro drawn.intro", null);
54914 context.history().on("change.intro", null);
54918 function editorTownHall() {
54919 if (!isTownHallSelected())
54920 return clickTownHall();
54921 context.container().select(".inspector-wrap").on("wheel.intro", eventCancel);
54922 var onClick = function() {
54923 continueTo(presetTownHall);
54926 ".entity-editor-pane",
54927 helpHtml("intro.navigation.editor_townhall"),
54928 { buttonText: _t.html("intro.ok"), buttonCallback: onClick }
54930 context.on("exit.intro", function() {
54931 continueTo(clickTownHall);
54933 context.history().on("change.intro", function() {
54934 if (!context.hasEntity(hallId)) {
54935 continueTo(clickTownHall);
54938 function continueTo(nextStep) {
54939 context.on("exit.intro", null);
54940 context.history().on("change.intro", null);
54941 context.container().select(".inspector-wrap").on("wheel.intro", null);
54945 function presetTownHall() {
54946 if (!isTownHallSelected())
54947 return clickTownHall();
54948 context.container().select(".inspector-wrap .panewrap").style("right", "0%");
54949 context.container().select(".inspector-wrap").on("wheel.intro", eventCancel);
54950 var entity = context.entity(context.selectedIDs()[0]);
54951 var preset = _mainPresetIndex.match(entity, context.graph());
54952 var onClick = function() {
54953 continueTo(fieldsTownHall);
54956 ".entity-editor-pane .section-feature-type",
54957 helpHtml("intro.navigation.preset_townhall", { preset: preset.name() }),
54958 { buttonText: _t.html("intro.ok"), buttonCallback: onClick }
54960 context.on("exit.intro", function() {
54961 continueTo(clickTownHall);
54963 context.history().on("change.intro", function() {
54964 if (!context.hasEntity(hallId)) {
54965 continueTo(clickTownHall);
54968 function continueTo(nextStep) {
54969 context.on("exit.intro", null);
54970 context.history().on("change.intro", null);
54971 context.container().select(".inspector-wrap").on("wheel.intro", null);
54975 function fieldsTownHall() {
54976 if (!isTownHallSelected())
54977 return clickTownHall();
54978 context.container().select(".inspector-wrap .panewrap").style("right", "0%");
54979 context.container().select(".inspector-wrap").on("wheel.intro", eventCancel);
54980 var onClick = function() {
54981 continueTo(closeTownHall);
54984 ".entity-editor-pane .section-preset-fields",
54985 helpHtml("intro.navigation.fields_townhall"),
54986 { buttonText: _t.html("intro.ok"), buttonCallback: onClick }
54988 context.on("exit.intro", function() {
54989 continueTo(clickTownHall);
54991 context.history().on("change.intro", function() {
54992 if (!context.hasEntity(hallId)) {
54993 continueTo(clickTownHall);
54996 function continueTo(nextStep) {
54997 context.on("exit.intro", null);
54998 context.history().on("change.intro", null);
54999 context.container().select(".inspector-wrap").on("wheel.intro", null);
55003 function closeTownHall() {
55004 if (!isTownHallSelected())
55005 return clickTownHall();
55006 var selector = ".entity-editor-pane button.close svg use";
55007 var href = select_default2(selector).attr("href") || "#iD-icon-close";
55009 ".entity-editor-pane",
55010 helpHtml("intro.navigation.close_townhall", { button: { html: icon(href, "inline") } })
55012 context.on("exit.intro", function() {
55013 continueTo(searchStreet);
55015 context.history().on("change.intro", function() {
55016 var selector2 = ".entity-editor-pane button.close svg use";
55017 var href2 = select_default2(selector2).attr("href") || "#iD-icon-close";
55019 ".entity-editor-pane",
55020 helpHtml("intro.navigation.close_townhall", { button: { html: icon(href2, "inline") } }),
55024 function continueTo(nextStep) {
55025 context.on("exit.intro", null);
55026 context.history().on("change.intro", null);
55030 function searchStreet() {
55031 context.enter(modeBrowse(context));
55032 context.history().reset("initial");
55033 var msec = transitionTime(springStreet, context.map().center());
55035 reveal(null, null, { duration: 0 });
55037 context.map().centerZoomEase(springStreet, 19, msec);
55038 timeout2(function() {
55040 ".search-header input",
55041 helpHtml("intro.navigation.search_street", { name: _t("intro.graph.name.spring-street") })
55043 context.container().select(".search-header input").on("keyup.intro", checkSearchResult);
55046 function checkSearchResult() {
55047 var first = context.container().select(".feature-list-item:nth-child(0n+2)");
55048 var firstName = first.select(".entity-name");
55049 var name = _t("intro.graph.name.spring-street");
55050 if (!firstName.empty() && firstName.html() === name) {
55053 helpHtml("intro.navigation.choose_street", { name }),
55056 context.on("exit.intro", function() {
55057 continueTo(selectedStreet);
55059 context.container().select(".search-header input").on("keydown.intro", eventCancel, true).on("keyup.intro", null);
55061 function continueTo(nextStep) {
55062 context.on("exit.intro", null);
55063 context.container().select(".search-header input").on("keydown.intro", null).on("keyup.intro", null);
55067 function selectedStreet() {
55068 if (!context.hasEntity(springStreetEndId) || !context.hasEntity(springStreetId)) {
55069 return searchStreet();
55071 var onClick = function() {
55072 continueTo(editorStreet);
55074 var entity = context.entity(springStreetEndId);
55075 var box = pointBox(entity.loc, context);
55079 helpHtml("intro.navigation.selected_street", { name: _t("intro.graph.name.spring-street") }),
55080 { duration: 600, buttonText: _t.html("intro.ok"), buttonCallback: onClick }
55082 timeout2(function() {
55083 context.map().on("move.intro drawn.intro", function() {
55084 var entity2 = context.hasEntity(springStreetEndId);
55087 var box2 = pointBox(entity2.loc, context);
55091 helpHtml("intro.navigation.selected_street", { name: _t("intro.graph.name.spring-street") }),
55092 { duration: 0, buttonText: _t.html("intro.ok"), buttonCallback: onClick }
55096 context.on("enter.intro", function(mode) {
55097 if (!context.hasEntity(springStreetId)) {
55098 return continueTo(searchStreet);
55100 var ids = context.selectedIDs();
55101 if (mode.id !== "select" || !ids.length || ids[0] !== springStreetId) {
55102 context.enter(modeSelect(context, [springStreetId]));
55105 context.history().on("change.intro", function() {
55106 if (!context.hasEntity(springStreetEndId) || !context.hasEntity(springStreetId)) {
55107 timeout2(function() {
55108 continueTo(searchStreet);
55112 function continueTo(nextStep) {
55113 context.map().on("move.intro drawn.intro", null);
55114 context.on("enter.intro", null);
55115 context.history().on("change.intro", null);
55119 function editorStreet() {
55120 var selector = ".entity-editor-pane button.close svg use";
55121 var href = select_default2(selector).attr("href") || "#iD-icon-close";
55122 reveal(".entity-editor-pane", helpHtml("intro.navigation.street_different_fields") + "{br}" + helpHtml("intro.navigation.editor_street", {
55123 button: { html: icon(href, "inline") },
55124 field1: onewayField.title(),
55125 field2: maxspeedField.title()
55127 context.on("exit.intro", function() {
55130 context.history().on("change.intro", function() {
55131 var selector2 = ".entity-editor-pane button.close svg use";
55132 var href2 = select_default2(selector2).attr("href") || "#iD-icon-close";
55134 ".entity-editor-pane",
55135 helpHtml("intro.navigation.street_different_fields") + "{br}" + helpHtml("intro.navigation.editor_street", {
55136 button: { html: icon(href2, "inline") },
55137 field1: onewayField.title(),
55138 field2: maxspeedField.title()
55143 function continueTo(nextStep) {
55144 context.on("exit.intro", null);
55145 context.history().on("change.intro", null);
55150 dispatch10.call("done");
55153 helpHtml("intro.navigation.play", { next: _t("intro.points.title") }),
55155 tooltipBox: ".intro-nav-wrap .chapter-point",
55156 buttonText: _t.html("intro.ok"),
55157 buttonCallback: function() {
55158 reveal(".ideditor");
55163 chapter.enter = function() {
55166 chapter.exit = function() {
55167 timeouts.forEach(window.clearTimeout);
55168 context.on("enter.intro exit.intro", null);
55169 context.map().on("move.intro drawn.intro", null);
55170 context.history().on("change.intro", null);
55171 context.container().select(".inspector-wrap").on("wheel.intro", null);
55172 context.container().select(".search-header input").on("keydown.intro keyup.intro", null);
55174 chapter.restart = function() {
55178 return utilRebind(chapter, dispatch10, "on");
55181 // modules/ui/intro/point.js
55182 function uiIntroPoint(context, reveal) {
55183 var dispatch10 = dispatch_default("done");
55185 var intersection = [-85.63279, 41.94394];
55186 var building = [-85.632422, 41.944045];
55187 var cafePreset = _mainPresetIndex.item("amenity/cafe");
55188 var _pointID = null;
55190 title: "intro.points.title"
55192 function timeout2(f2, t) {
55193 timeouts.push(window.setTimeout(f2, t));
55195 function eventCancel(d3_event) {
55196 d3_event.stopPropagation();
55197 d3_event.preventDefault();
55199 function addPoint() {
55200 context.enter(modeBrowse(context));
55201 context.history().reset("initial");
55202 var msec = transitionTime(intersection, context.map().center());
55204 reveal(null, null, { duration: 0 });
55206 context.map().centerZoomEase(intersection, 19, msec);
55207 timeout2(function() {
55208 var tooltip = reveal(
55209 "button.add-point",
55210 helpHtml("intro.points.points_info") + "{br}" + helpHtml("intro.points.add_point")
55213 tooltip.selectAll(".popover-inner").insert("svg", "span").attr("class", "tooltip-illustration").append("use").attr("xlink:href", "#iD-graphic-points");
55214 context.on("enter.intro", function(mode) {
55215 if (mode.id !== "add-point")
55217 continueTo(placePoint);
55220 function continueTo(nextStep) {
55221 context.on("enter.intro", null);
55225 function placePoint() {
55226 if (context.mode().id !== "add-point") {
55227 return chapter.restart();
55229 var pointBox2 = pad(building, 150, context);
55230 var textId = context.lastPointerType() === "mouse" ? "place_point" : "place_point_touch";
55231 reveal(pointBox2, helpHtml("intro.points." + textId));
55232 context.map().on("move.intro drawn.intro", function() {
55233 pointBox2 = pad(building, 150, context);
55234 reveal(pointBox2, helpHtml("intro.points." + textId), { duration: 0 });
55236 context.on("enter.intro", function(mode) {
55237 if (mode.id !== "select")
55238 return chapter.restart();
55239 _pointID = context.mode().selectedIDs()[0];
55240 continueTo(searchPreset);
55242 function continueTo(nextStep) {
55243 context.map().on("move.intro drawn.intro", null);
55244 context.on("enter.intro", null);
55248 function searchPreset() {
55249 if (context.mode().id !== "select" || !_pointID || !context.hasEntity(_pointID)) {
55252 context.container().select(".inspector-wrap").on("wheel.intro", eventCancel);
55253 context.container().select(".preset-search-input").on("keydown.intro", null).on("keyup.intro", checkPresetSearch);
55255 ".preset-search-input",
55256 helpHtml("intro.points.search_cafe", { preset: cafePreset.name() })
55258 context.on("enter.intro", function(mode) {
55259 if (!_pointID || !context.hasEntity(_pointID)) {
55260 return continueTo(addPoint);
55262 var ids = context.selectedIDs();
55263 if (mode.id !== "select" || !ids.length || ids[0] !== _pointID) {
55264 context.enter(modeSelect(context, [_pointID]));
55265 context.container().select(".inspector-wrap").on("wheel.intro", eventCancel);
55266 context.container().select(".preset-search-input").on("keydown.intro", null).on("keyup.intro", checkPresetSearch);
55268 ".preset-search-input",
55269 helpHtml("intro.points.search_cafe", { preset: cafePreset.name() })
55271 context.history().on("change.intro", null);
55274 function checkPresetSearch() {
55275 var first = context.container().select(".preset-list-item:first-child");
55276 if (first.classed("preset-amenity-cafe")) {
55277 context.container().select(".preset-search-input").on("keydown.intro", eventCancel, true).on("keyup.intro", null);
55279 first.select(".preset-list-button").node(),
55280 helpHtml("intro.points.choose_cafe", { preset: cafePreset.name() }),
55283 context.history().on("change.intro", function() {
55284 continueTo(aboutFeatureEditor);
55288 function continueTo(nextStep) {
55289 context.on("enter.intro", null);
55290 context.history().on("change.intro", null);
55291 context.container().select(".inspector-wrap").on("wheel.intro", null);
55292 context.container().select(".preset-search-input").on("keydown.intro keyup.intro", null);
55296 function aboutFeatureEditor() {
55297 if (context.mode().id !== "select" || !_pointID || !context.hasEntity(_pointID)) {
55300 timeout2(function() {
55301 reveal(".entity-editor-pane", helpHtml("intro.points.feature_editor"), {
55302 tooltipClass: "intro-points-describe",
55303 buttonText: _t.html("intro.ok"),
55304 buttonCallback: function() {
55305 continueTo(addName);
55309 context.on("exit.intro", function() {
55310 continueTo(reselectPoint);
55312 function continueTo(nextStep) {
55313 context.on("exit.intro", null);
55317 function addName() {
55318 if (context.mode().id !== "select" || !_pointID || !context.hasEntity(_pointID)) {
55321 context.container().select(".inspector-wrap .panewrap").style("right", "0%");
55322 var addNameString = helpHtml("intro.points.fields_info") + "{br}" + helpHtml("intro.points.add_name");
55323 timeout2(function() {
55324 var entity = context.entity(_pointID);
55325 if (entity.tags.name) {
55326 var tooltip = reveal(".entity-editor-pane", addNameString, {
55327 tooltipClass: "intro-points-describe",
55328 buttonText: _t.html("intro.ok"),
55329 buttonCallback: function() {
55330 continueTo(addCloseEditor);
55333 tooltip.select(".instruction").style("display", "none");
55336 ".entity-editor-pane",
55338 { tooltipClass: "intro-points-describe" }
55342 context.history().on("change.intro", function() {
55343 continueTo(addCloseEditor);
55345 context.on("exit.intro", function() {
55346 continueTo(reselectPoint);
55348 function continueTo(nextStep) {
55349 context.on("exit.intro", null);
55350 context.history().on("change.intro", null);
55354 function addCloseEditor() {
55355 context.container().select(".inspector-wrap .panewrap").style("right", "0%");
55356 var selector = ".entity-editor-pane button.close svg use";
55357 var href = select_default2(selector).attr("href") || "#iD-icon-close";
55358 context.on("exit.intro", function() {
55359 continueTo(reselectPoint);
55362 ".entity-editor-pane",
55363 helpHtml("intro.points.add_close", { button: { html: icon(href, "inline") } })
55365 function continueTo(nextStep) {
55366 context.on("exit.intro", null);
55370 function reselectPoint() {
55372 return chapter.restart();
55373 var entity = context.hasEntity(_pointID);
55375 return chapter.restart();
55376 var oldPreset = _mainPresetIndex.match(entity, context.graph());
55377 context.replace(actionChangePreset(_pointID, oldPreset, cafePreset));
55378 context.enter(modeBrowse(context));
55379 var msec = transitionTime(entity.loc, context.map().center());
55381 reveal(null, null, { duration: 0 });
55383 context.map().centerEase(entity.loc, msec);
55384 timeout2(function() {
55385 var box = pointBox(entity.loc, context);
55386 reveal(box, helpHtml("intro.points.reselect"), { duration: 600 });
55387 timeout2(function() {
55388 context.map().on("move.intro drawn.intro", function() {
55389 var entity2 = context.hasEntity(_pointID);
55391 return chapter.restart();
55392 var box2 = pointBox(entity2.loc, context);
55393 reveal(box2, helpHtml("intro.points.reselect"), { duration: 0 });
55396 context.on("enter.intro", function(mode) {
55397 if (mode.id !== "select")
55399 continueTo(updatePoint);
55402 function continueTo(nextStep) {
55403 context.map().on("move.intro drawn.intro", null);
55404 context.on("enter.intro", null);
55408 function updatePoint() {
55409 if (context.mode().id !== "select" || !_pointID || !context.hasEntity(_pointID)) {
55410 return continueTo(reselectPoint);
55412 context.container().select(".inspector-wrap .panewrap").style("right", "0%");
55413 context.on("exit.intro", function() {
55414 continueTo(reselectPoint);
55416 context.history().on("change.intro", function() {
55417 continueTo(updateCloseEditor);
55419 timeout2(function() {
55421 ".entity-editor-pane",
55422 helpHtml("intro.points.update"),
55423 { tooltipClass: "intro-points-describe" }
55426 function continueTo(nextStep) {
55427 context.on("exit.intro", null);
55428 context.history().on("change.intro", null);
55432 function updateCloseEditor() {
55433 if (context.mode().id !== "select" || !_pointID || !context.hasEntity(_pointID)) {
55434 return continueTo(reselectPoint);
55436 context.container().select(".inspector-wrap .panewrap").style("right", "0%");
55437 context.on("exit.intro", function() {
55438 continueTo(rightClickPoint);
55440 timeout2(function() {
55442 ".entity-editor-pane",
55443 helpHtml("intro.points.update_close", { button: { html: icon("#iD-icon-close", "inline") } })
55446 function continueTo(nextStep) {
55447 context.on("exit.intro", null);
55451 function rightClickPoint() {
55453 return chapter.restart();
55454 var entity = context.hasEntity(_pointID);
55456 return chapter.restart();
55457 context.enter(modeBrowse(context));
55458 var box = pointBox(entity.loc, context);
55459 var textId = context.lastPointerType() === "mouse" ? "rightclick" : "edit_menu_touch";
55460 reveal(box, helpHtml("intro.points." + textId), { duration: 600 });
55461 timeout2(function() {
55462 context.map().on("move.intro", function() {
55463 var entity2 = context.hasEntity(_pointID);
55465 return chapter.restart();
55466 var box2 = pointBox(entity2.loc, context);
55467 reveal(box2, helpHtml("intro.points." + textId), { duration: 0 });
55470 context.on("enter.intro", function(mode) {
55471 if (mode.id !== "select")
55473 var ids = context.selectedIDs();
55474 if (ids.length !== 1 || ids[0] !== _pointID)
55476 timeout2(function() {
55477 var node = selectMenuItem(context, "delete").node();
55480 continueTo(enterDelete);
55483 function continueTo(nextStep) {
55484 context.on("enter.intro", null);
55485 context.map().on("move.intro", null);
55489 function enterDelete() {
55491 return chapter.restart();
55492 var entity = context.hasEntity(_pointID);
55494 return chapter.restart();
55495 var node = selectMenuItem(context, "delete").node();
55497 return continueTo(rightClickPoint);
55501 helpHtml("intro.points.delete"),
55504 timeout2(function() {
55505 context.map().on("move.intro", function() {
55508 helpHtml("intro.points.delete"),
55509 { duration: 0, padding: 50 }
55513 context.on("exit.intro", function() {
55515 return chapter.restart();
55516 var entity2 = context.hasEntity(_pointID);
55518 return continueTo(rightClickPoint);
55520 context.history().on("change.intro", function(changed) {
55521 if (changed.deleted().length) {
55525 function continueTo(nextStep) {
55526 context.map().on("move.intro", null);
55527 context.history().on("change.intro", null);
55528 context.on("exit.intro", null);
55533 context.history().on("change.intro", function() {
55537 ".top-toolbar button.undo-button",
55538 helpHtml("intro.points.undo")
55540 function continueTo(nextStep) {
55541 context.history().on("change.intro", null);
55546 dispatch10.call("done");
55549 helpHtml("intro.points.play", { next: _t("intro.areas.title") }),
55551 tooltipBox: ".intro-nav-wrap .chapter-area",
55552 buttonText: _t.html("intro.ok"),
55553 buttonCallback: function() {
55554 reveal(".ideditor");
55559 chapter.enter = function() {
55562 chapter.exit = function() {
55563 timeouts.forEach(window.clearTimeout);
55564 context.on("enter.intro exit.intro", null);
55565 context.map().on("move.intro drawn.intro", null);
55566 context.history().on("change.intro", null);
55567 context.container().select(".inspector-wrap").on("wheel.intro", eventCancel);
55568 context.container().select(".preset-search-input").on("keydown.intro keyup.intro", null);
55570 chapter.restart = function() {
55574 return utilRebind(chapter, dispatch10, "on");
55577 // modules/ui/intro/area.js
55578 function uiIntroArea(context, reveal) {
55579 var dispatch10 = dispatch_default("done");
55580 var playground = [-85.63552, 41.94159];
55581 var playgroundPreset = _mainPresetIndex.item("leisure/playground");
55582 var nameField = _mainPresetIndex.field("name");
55583 var descriptionField = _mainPresetIndex.field("description");
55587 title: "intro.areas.title"
55589 function timeout2(f2, t) {
55590 timeouts.push(window.setTimeout(f2, t));
55592 function eventCancel(d3_event) {
55593 d3_event.stopPropagation();
55594 d3_event.preventDefault();
55596 function revealPlayground(center, text2, options2) {
55597 var padding = 180 * Math.pow(2, context.map().zoom() - 19.5);
55598 var box = pad(center, padding, context);
55599 reveal(box, text2, options2);
55601 function addArea() {
55602 context.enter(modeBrowse(context));
55603 context.history().reset("initial");
55605 var msec = transitionTime(playground, context.map().center());
55607 reveal(null, null, { duration: 0 });
55609 context.map().centerZoomEase(playground, 19, msec);
55610 timeout2(function() {
55611 var tooltip = reveal(
55613 helpHtml("intro.areas.add_playground")
55615 tooltip.selectAll(".popover-inner").insert("svg", "span").attr("class", "tooltip-illustration").append("use").attr("xlink:href", "#iD-graphic-areas");
55616 context.on("enter.intro", function(mode) {
55617 if (mode.id !== "add-area")
55619 continueTo(startPlayground);
55622 function continueTo(nextStep) {
55623 context.on("enter.intro", null);
55627 function startPlayground() {
55628 if (context.mode().id !== "add-area") {
55629 return chapter.restart();
55632 context.map().zoomEase(19.5, 500);
55633 timeout2(function() {
55634 var textId = context.lastPointerType() === "mouse" ? "starting_node_click" : "starting_node_tap";
55635 var startDrawString = helpHtml("intro.areas.start_playground") + helpHtml("intro.areas." + textId);
55641 timeout2(function() {
55642 context.map().on("move.intro drawn.intro", function() {
55649 context.on("enter.intro", function(mode) {
55650 if (mode.id !== "draw-area")
55651 return chapter.restart();
55652 continueTo(continuePlayground);
55656 function continueTo(nextStep) {
55657 context.map().on("move.intro drawn.intro", null);
55658 context.on("enter.intro", null);
55662 function continuePlayground() {
55663 if (context.mode().id !== "draw-area") {
55664 return chapter.restart();
55669 helpHtml("intro.areas.continue_playground"),
55672 timeout2(function() {
55673 context.map().on("move.intro drawn.intro", function() {
55676 helpHtml("intro.areas.continue_playground"),
55681 context.on("enter.intro", function(mode) {
55682 if (mode.id === "draw-area") {
55683 var entity = context.hasEntity(context.selectedIDs()[0]);
55684 if (entity && entity.nodes.length >= 6) {
55685 return continueTo(finishPlayground);
55689 } else if (mode.id === "select") {
55690 _areaID = context.selectedIDs()[0];
55691 return continueTo(searchPresets);
55693 return chapter.restart();
55696 function continueTo(nextStep) {
55697 context.map().on("move.intro drawn.intro", null);
55698 context.on("enter.intro", null);
55702 function finishPlayground() {
55703 if (context.mode().id !== "draw-area") {
55704 return chapter.restart();
55707 var finishString = helpHtml("intro.areas.finish_area_" + (context.lastPointerType() === "mouse" ? "click" : "tap")) + helpHtml("intro.areas.finish_playground");
55713 timeout2(function() {
55714 context.map().on("move.intro drawn.intro", function() {
55722 context.on("enter.intro", function(mode) {
55723 if (mode.id === "draw-area") {
55725 } else if (mode.id === "select") {
55726 _areaID = context.selectedIDs()[0];
55727 return continueTo(searchPresets);
55729 return chapter.restart();
55732 function continueTo(nextStep) {
55733 context.map().on("move.intro drawn.intro", null);
55734 context.on("enter.intro", null);
55738 function searchPresets() {
55739 if (!_areaID || !context.hasEntity(_areaID)) {
55742 var ids = context.selectedIDs();
55743 if (context.mode().id !== "select" || !ids.length || ids[0] !== _areaID) {
55744 context.enter(modeSelect(context, [_areaID]));
55746 context.container().select(".inspector-wrap").on("wheel.intro", eventCancel);
55747 timeout2(function() {
55748 context.container().select(".inspector-wrap .panewrap").style("right", "-100%");
55749 context.container().select(".preset-search-input").on("keydown.intro", null).on("keyup.intro", checkPresetSearch);
55751 ".preset-search-input",
55752 helpHtml("intro.areas.search_playground", { preset: playgroundPreset.name() })
55755 context.on("enter.intro", function(mode) {
55756 if (!_areaID || !context.hasEntity(_areaID)) {
55757 return continueTo(addArea);
55759 var ids2 = context.selectedIDs();
55760 if (mode.id !== "select" || !ids2.length || ids2[0] !== _areaID) {
55761 context.enter(modeSelect(context, [_areaID]));
55762 context.container().select(".inspector-wrap .panewrap").style("right", "-100%");
55763 context.container().select(".inspector-wrap").on("wheel.intro", eventCancel);
55764 context.container().select(".preset-search-input").on("keydown.intro", null).on("keyup.intro", checkPresetSearch);
55766 ".preset-search-input",
55767 helpHtml("intro.areas.search_playground", { preset: playgroundPreset.name() })
55769 context.history().on("change.intro", null);
55772 function checkPresetSearch() {
55773 var first = context.container().select(".preset-list-item:first-child");
55774 if (first.classed("preset-leisure-playground")) {
55776 first.select(".preset-list-button").node(),
55777 helpHtml("intro.areas.choose_playground", { preset: playgroundPreset.name() }),
55780 context.container().select(".preset-search-input").on("keydown.intro", eventCancel, true).on("keyup.intro", null);
55781 context.history().on("change.intro", function() {
55782 continueTo(clickAddField);
55786 function continueTo(nextStep) {
55787 context.container().select(".inspector-wrap").on("wheel.intro", null);
55788 context.on("enter.intro", null);
55789 context.history().on("change.intro", null);
55790 context.container().select(".preset-search-input").on("keydown.intro keyup.intro", null);
55794 function clickAddField() {
55795 if (!_areaID || !context.hasEntity(_areaID)) {
55798 var ids = context.selectedIDs();
55799 if (context.mode().id !== "select" || !ids.length || ids[0] !== _areaID) {
55800 return searchPresets();
55802 if (!context.container().select(".form-field-description").empty()) {
55803 return continueTo(describePlayground);
55805 context.container().select(".inspector-wrap").on("wheel.intro", eventCancel);
55806 timeout2(function() {
55807 context.container().select(".inspector-wrap .panewrap").style("right", "0%");
55808 var entity = context.entity(_areaID);
55809 if (entity.tags.description) {
55810 return continueTo(play);
55812 var box = context.container().select(".more-fields").node().getBoundingClientRect();
55813 if (box.top > 300) {
55814 var pane = context.container().select(".entity-editor-pane .inspector-body");
55815 var start2 = pane.node().scrollTop;
55816 var end = start2 + (box.top - 300);
55817 pane.transition().duration(250).tween("scroll.inspector", function() {
55819 var i2 = number_default(start2, end);
55820 return function(t) {
55821 node.scrollTop = i2(t);
55825 timeout2(function() {
55827 ".more-fields .combobox-input",
55828 helpHtml("intro.areas.add_field", {
55829 name: nameField.title(),
55830 description: descriptionField.title()
55834 context.container().select(".more-fields .combobox-input").on("click.intro", function() {
55836 watcher = window.setInterval(function() {
55837 if (!context.container().select("div.combobox").empty()) {
55838 window.clearInterval(watcher);
55839 continueTo(chooseDescriptionField);
55845 context.on("exit.intro", function() {
55846 return continueTo(searchPresets);
55848 function continueTo(nextStep) {
55849 context.container().select(".inspector-wrap").on("wheel.intro", null);
55850 context.container().select(".more-fields .combobox-input").on("click.intro", null);
55851 context.on("exit.intro", null);
55855 function chooseDescriptionField() {
55856 if (!_areaID || !context.hasEntity(_areaID)) {
55859 var ids = context.selectedIDs();
55860 if (context.mode().id !== "select" || !ids.length || ids[0] !== _areaID) {
55861 return searchPresets();
55863 if (!context.container().select(".form-field-description").empty()) {
55864 return continueTo(describePlayground);
55866 if (context.container().select("div.combobox").empty()) {
55867 return continueTo(clickAddField);
55870 watcher = window.setInterval(function() {
55871 if (context.container().select("div.combobox").empty()) {
55872 window.clearInterval(watcher);
55873 timeout2(function() {
55874 if (context.container().select(".form-field-description").empty()) {
55875 continueTo(retryChooseDescription);
55877 continueTo(describePlayground);
55884 helpHtml("intro.areas.choose_field", { field: descriptionField.title() }),
55887 context.on("exit.intro", function() {
55888 return continueTo(searchPresets);
55890 function continueTo(nextStep) {
55892 window.clearInterval(watcher);
55893 context.on("exit.intro", null);
55897 function describePlayground() {
55898 if (!_areaID || !context.hasEntity(_areaID)) {
55901 var ids = context.selectedIDs();
55902 if (context.mode().id !== "select" || !ids.length || ids[0] !== _areaID) {
55903 return searchPresets();
55905 context.container().select(".inspector-wrap .panewrap").style("right", "0%");
55906 if (context.container().select(".form-field-description").empty()) {
55907 return continueTo(retryChooseDescription);
55909 context.on("exit.intro", function() {
55913 ".entity-editor-pane",
55914 helpHtml("intro.areas.describe_playground", { button: { html: icon("#iD-icon-close", "inline") } }),
55917 function continueTo(nextStep) {
55918 context.on("exit.intro", null);
55922 function retryChooseDescription() {
55923 if (!_areaID || !context.hasEntity(_areaID)) {
55926 var ids = context.selectedIDs();
55927 if (context.mode().id !== "select" || !ids.length || ids[0] !== _areaID) {
55928 return searchPresets();
55930 context.container().select(".inspector-wrap .panewrap").style("right", "0%");
55932 ".entity-editor-pane",
55933 helpHtml("intro.areas.retry_add_field", { field: descriptionField.title() }),
55935 buttonText: _t.html("intro.ok"),
55936 buttonCallback: function() {
55937 continueTo(clickAddField);
55941 context.on("exit.intro", function() {
55942 return continueTo(searchPresets);
55944 function continueTo(nextStep) {
55945 context.on("exit.intro", null);
55950 dispatch10.call("done");
55953 helpHtml("intro.areas.play", { next: _t("intro.lines.title") }),
55955 tooltipBox: ".intro-nav-wrap .chapter-line",
55956 buttonText: _t.html("intro.ok"),
55957 buttonCallback: function() {
55958 reveal(".ideditor");
55963 chapter.enter = function() {
55966 chapter.exit = function() {
55967 timeouts.forEach(window.clearTimeout);
55968 context.on("enter.intro exit.intro", null);
55969 context.map().on("move.intro drawn.intro", null);
55970 context.history().on("change.intro", null);
55971 context.container().select(".inspector-wrap").on("wheel.intro", null);
55972 context.container().select(".preset-search-input").on("keydown.intro keyup.intro", null);
55973 context.container().select(".more-fields .combobox-input").on("click.intro", null);
55975 chapter.restart = function() {
55979 return utilRebind(chapter, dispatch10, "on");
55982 // modules/ui/intro/line.js
55983 function uiIntroLine(context, reveal) {
55984 var dispatch10 = dispatch_default("done");
55986 var _tulipRoadID = null;
55987 var flowerRoadID = "w646";
55988 var tulipRoadStart = [-85.6297754121684, 41.95805253325314];
55989 var tulipRoadMidpoint = [-85.62975395449628, 41.95787501510204];
55990 var tulipRoadIntersection = [-85.62974496187628, 41.95742515554585];
55991 var roadCategory = _mainPresetIndex.item("category-road_minor");
55992 var residentialPreset = _mainPresetIndex.item("highway/residential");
55993 var woodRoadID = "w525";
55994 var woodRoadEndID = "n2862";
55995 var woodRoadAddNode = [-85.62390110349587, 41.95397111462291];
55996 var woodRoadDragEndpoint = [-85.623867390213, 41.95466987786487];
55997 var woodRoadDragMidpoint = [-85.62386254803509, 41.95430395953872];
55998 var washingtonStreetID = "w522";
55999 var twelfthAvenueID = "w1";
56000 var eleventhAvenueEndID = "n3550";
56001 var twelfthAvenueEndID = "n5";
56002 var _washingtonSegmentID = null;
56003 var eleventhAvenueEnd = context.entity(eleventhAvenueEndID).loc;
56004 var twelfthAvenueEnd = context.entity(twelfthAvenueEndID).loc;
56005 var deleteLinesLoc = [-85.6219395542764, 41.95228033922477];
56006 var twelfthAvenue = [-85.62219310052491, 41.952505413152956];
56008 title: "intro.lines.title"
56010 function timeout2(f2, t) {
56011 timeouts.push(window.setTimeout(f2, t));
56013 function eventCancel(d3_event) {
56014 d3_event.stopPropagation();
56015 d3_event.preventDefault();
56017 function addLine() {
56018 context.enter(modeBrowse(context));
56019 context.history().reset("initial");
56020 var msec = transitionTime(tulipRoadStart, context.map().center());
56022 reveal(null, null, { duration: 0 });
56024 context.map().centerZoomEase(tulipRoadStart, 18.5, msec);
56025 timeout2(function() {
56026 var tooltip = reveal(
56028 helpHtml("intro.lines.add_line")
56030 tooltip.selectAll(".popover-inner").insert("svg", "span").attr("class", "tooltip-illustration").append("use").attr("xlink:href", "#iD-graphic-lines");
56031 context.on("enter.intro", function(mode) {
56032 if (mode.id !== "add-line")
56034 continueTo(startLine);
56037 function continueTo(nextStep) {
56038 context.on("enter.intro", null);
56042 function startLine() {
56043 if (context.mode().id !== "add-line")
56044 return chapter.restart();
56045 _tulipRoadID = null;
56046 var padding = 70 * Math.pow(2, context.map().zoom() - 18);
56047 var box = pad(tulipRoadStart, padding, context);
56048 box.height = box.height + 100;
56049 var textId = context.lastPointerType() === "mouse" ? "start_line" : "start_line_tap";
56050 var startLineString = helpHtml("intro.lines.missing_road") + "{br}" + helpHtml("intro.lines.line_draw_info") + helpHtml("intro.lines." + textId);
56051 reveal(box, startLineString);
56052 context.map().on("move.intro drawn.intro", function() {
56053 padding = 70 * Math.pow(2, context.map().zoom() - 18);
56054 box = pad(tulipRoadStart, padding, context);
56055 box.height = box.height + 100;
56056 reveal(box, startLineString, { duration: 0 });
56058 context.on("enter.intro", function(mode) {
56059 if (mode.id !== "draw-line")
56060 return chapter.restart();
56061 continueTo(drawLine);
56063 function continueTo(nextStep) {
56064 context.map().on("move.intro drawn.intro", null);
56065 context.on("enter.intro", null);
56069 function drawLine() {
56070 if (context.mode().id !== "draw-line")
56071 return chapter.restart();
56072 _tulipRoadID = context.mode().selectedIDs()[0];
56073 context.map().centerEase(tulipRoadMidpoint, 500);
56074 timeout2(function() {
56075 var padding = 200 * Math.pow(2, context.map().zoom() - 18.5);
56076 var box = pad(tulipRoadMidpoint, padding, context);
56077 box.height = box.height * 2;
56080 helpHtml("intro.lines.intersect", { name: _t("intro.graph.name.flower-street") })
56082 context.map().on("move.intro drawn.intro", function() {
56083 padding = 200 * Math.pow(2, context.map().zoom() - 18.5);
56084 box = pad(tulipRoadMidpoint, padding, context);
56085 box.height = box.height * 2;
56088 helpHtml("intro.lines.intersect", { name: _t("intro.graph.name.flower-street") }),
56093 context.history().on("change.intro", function() {
56094 if (isLineConnected()) {
56095 continueTo(continueLine);
56098 context.on("enter.intro", function(mode) {
56099 if (mode.id === "draw-line") {
56101 } else if (mode.id === "select") {
56102 continueTo(retryIntersect);
56105 return chapter.restart();
56108 function continueTo(nextStep) {
56109 context.map().on("move.intro drawn.intro", null);
56110 context.history().on("change.intro", null);
56111 context.on("enter.intro", null);
56115 function isLineConnected() {
56116 var entity = _tulipRoadID && context.hasEntity(_tulipRoadID);
56119 var drawNodes = context.graph().childNodes(entity);
56120 return drawNodes.some(function(node) {
56121 return context.graph().parentWays(node).some(function(parent) {
56122 return parent.id === flowerRoadID;
56126 function retryIntersect() {
56127 select_default2(window).on("pointerdown.intro mousedown.intro", eventCancel, true);
56128 var box = pad(tulipRoadIntersection, 80, context);
56131 helpHtml("intro.lines.retry_intersect", { name: _t("intro.graph.name.flower-street") })
56133 timeout2(chapter.restart, 3e3);
56135 function continueLine() {
56136 if (context.mode().id !== "draw-line")
56137 return chapter.restart();
56138 var entity = _tulipRoadID && context.hasEntity(_tulipRoadID);
56140 return chapter.restart();
56141 context.map().centerEase(tulipRoadIntersection, 500);
56142 var continueLineText = helpHtml("intro.lines.continue_line") + "{br}" + helpHtml("intro.lines.finish_line_" + (context.lastPointerType() === "mouse" ? "click" : "tap")) + helpHtml("intro.lines.finish_road");
56143 reveal(".surface", continueLineText);
56144 context.on("enter.intro", function(mode) {
56145 if (mode.id === "draw-line") {
56147 } else if (mode.id === "select") {
56148 return continueTo(chooseCategoryRoad);
56150 return chapter.restart();
56153 function continueTo(nextStep) {
56154 context.on("enter.intro", null);
56158 function chooseCategoryRoad() {
56159 if (context.mode().id !== "select")
56160 return chapter.restart();
56161 context.on("exit.intro", function() {
56162 return chapter.restart();
56164 var button = context.container().select(".preset-category-road_minor .preset-list-button");
56165 if (button.empty())
56166 return chapter.restart();
56167 context.container().select(".inspector-wrap").on("wheel.intro", eventCancel);
56168 timeout2(function() {
56169 context.container().select(".inspector-wrap .panewrap").style("right", "-100%");
56172 helpHtml("intro.lines.choose_category_road", { category: roadCategory.name() })
56174 button.on("click.intro", function() {
56175 continueTo(choosePresetResidential);
56178 function continueTo(nextStep) {
56179 context.container().select(".inspector-wrap").on("wheel.intro", null);
56180 context.container().select(".preset-list-button").on("click.intro", null);
56181 context.on("exit.intro", null);
56185 function choosePresetResidential() {
56186 if (context.mode().id !== "select")
56187 return chapter.restart();
56188 context.on("exit.intro", function() {
56189 return chapter.restart();
56191 var subgrid = context.container().select(".preset-category-road_minor .subgrid");
56192 if (subgrid.empty())
56193 return chapter.restart();
56194 subgrid.selectAll(":not(.preset-highway-residential) .preset-list-button").on("click.intro", function() {
56195 continueTo(retryPresetResidential);
56197 subgrid.selectAll(".preset-highway-residential .preset-list-button").on("click.intro", function() {
56198 continueTo(nameRoad);
56200 timeout2(function() {
56203 helpHtml("intro.lines.choose_preset_residential", { preset: residentialPreset.name() }),
56204 { tooltipBox: ".preset-highway-residential .preset-list-button", duration: 300 }
56207 function continueTo(nextStep) {
56208 context.container().select(".preset-list-button").on("click.intro", null);
56209 context.on("exit.intro", null);
56213 function retryPresetResidential() {
56214 if (context.mode().id !== "select")
56215 return chapter.restart();
56216 context.on("exit.intro", function() {
56217 return chapter.restart();
56219 context.container().select(".inspector-wrap").on("wheel.intro", eventCancel);
56220 timeout2(function() {
56221 var button = context.container().select(".entity-editor-pane .preset-list-button");
56224 helpHtml("intro.lines.retry_preset_residential", { preset: residentialPreset.name() })
56226 button.on("click.intro", function() {
56227 continueTo(chooseCategoryRoad);
56230 function continueTo(nextStep) {
56231 context.container().select(".inspector-wrap").on("wheel.intro", null);
56232 context.container().select(".preset-list-button").on("click.intro", null);
56233 context.on("exit.intro", null);
56237 function nameRoad() {
56238 context.on("exit.intro", function() {
56239 continueTo(didNameRoad);
56241 timeout2(function() {
56243 ".entity-editor-pane",
56244 helpHtml("intro.lines.name_road", { button: { html: icon("#iD-icon-close", "inline") } }),
56245 { tooltipClass: "intro-lines-name_road" }
56248 function continueTo(nextStep) {
56249 context.on("exit.intro", null);
56253 function didNameRoad() {
56254 context.history().checkpoint("doneAddLine");
56255 timeout2(function() {
56256 reveal(".surface", helpHtml("intro.lines.did_name_road"), {
56257 buttonText: _t.html("intro.ok"),
56258 buttonCallback: function() {
56259 continueTo(updateLine);
56263 function continueTo(nextStep) {
56267 function updateLine() {
56268 context.history().reset("doneAddLine");
56269 if (!context.hasEntity(woodRoadID) || !context.hasEntity(woodRoadEndID)) {
56270 return chapter.restart();
56272 var msec = transitionTime(woodRoadDragMidpoint, context.map().center());
56274 reveal(null, null, { duration: 0 });
56276 context.map().centerZoomEase(woodRoadDragMidpoint, 19, msec);
56277 timeout2(function() {
56278 var padding = 250 * Math.pow(2, context.map().zoom() - 19);
56279 var box = pad(woodRoadDragMidpoint, padding, context);
56280 var advance = function() {
56281 continueTo(addNode);
56285 helpHtml("intro.lines.update_line"),
56286 { buttonText: _t.html("intro.ok"), buttonCallback: advance }
56288 context.map().on("move.intro drawn.intro", function() {
56289 var padding2 = 250 * Math.pow(2, context.map().zoom() - 19);
56290 var box2 = pad(woodRoadDragMidpoint, padding2, context);
56293 helpHtml("intro.lines.update_line"),
56294 { duration: 0, buttonText: _t.html("intro.ok"), buttonCallback: advance }
56298 function continueTo(nextStep) {
56299 context.map().on("move.intro drawn.intro", null);
56303 function addNode() {
56304 context.history().reset("doneAddLine");
56305 if (!context.hasEntity(woodRoadID) || !context.hasEntity(woodRoadEndID)) {
56306 return chapter.restart();
56308 var padding = 40 * Math.pow(2, context.map().zoom() - 19);
56309 var box = pad(woodRoadAddNode, padding, context);
56310 var addNodeString = helpHtml("intro.lines.add_node" + (context.lastPointerType() === "mouse" ? "" : "_touch"));
56311 reveal(box, addNodeString);
56312 context.map().on("move.intro drawn.intro", function() {
56313 var padding2 = 40 * Math.pow(2, context.map().zoom() - 19);
56314 var box2 = pad(woodRoadAddNode, padding2, context);
56315 reveal(box2, addNodeString, { duration: 0 });
56317 context.history().on("change.intro", function(changed) {
56318 if (!context.hasEntity(woodRoadID) || !context.hasEntity(woodRoadEndID)) {
56319 return continueTo(updateLine);
56321 if (changed.created().length === 1) {
56322 timeout2(function() {
56323 continueTo(startDragEndpoint);
56327 context.on("enter.intro", function(mode) {
56328 if (mode.id !== "select") {
56329 continueTo(updateLine);
56332 function continueTo(nextStep) {
56333 context.map().on("move.intro drawn.intro", null);
56334 context.history().on("change.intro", null);
56335 context.on("enter.intro", null);
56339 function startDragEndpoint() {
56340 if (!context.hasEntity(woodRoadID) || !context.hasEntity(woodRoadEndID)) {
56341 return continueTo(updateLine);
56343 var padding = 100 * Math.pow(2, context.map().zoom() - 19);
56344 var box = pad(woodRoadDragEndpoint, padding, context);
56345 var startDragString = helpHtml("intro.lines.start_drag_endpoint" + (context.lastPointerType() === "mouse" ? "" : "_touch")) + helpHtml("intro.lines.drag_to_intersection");
56346 reveal(box, startDragString);
56347 context.map().on("move.intro drawn.intro", function() {
56348 if (!context.hasEntity(woodRoadID) || !context.hasEntity(woodRoadEndID)) {
56349 return continueTo(updateLine);
56351 var padding2 = 100 * Math.pow(2, context.map().zoom() - 19);
56352 var box2 = pad(woodRoadDragEndpoint, padding2, context);
56353 reveal(box2, startDragString, { duration: 0 });
56354 var entity = context.entity(woodRoadEndID);
56355 if (geoSphericalDistance(entity.loc, woodRoadDragEndpoint) <= 4) {
56356 continueTo(finishDragEndpoint);
56359 function continueTo(nextStep) {
56360 context.map().on("move.intro drawn.intro", null);
56364 function finishDragEndpoint() {
56365 if (!context.hasEntity(woodRoadID) || !context.hasEntity(woodRoadEndID)) {
56366 return continueTo(updateLine);
56368 var padding = 100 * Math.pow(2, context.map().zoom() - 19);
56369 var box = pad(woodRoadDragEndpoint, padding, context);
56370 var finishDragString = helpHtml("intro.lines.spot_looks_good") + helpHtml("intro.lines.finish_drag_endpoint" + (context.lastPointerType() === "mouse" ? "" : "_touch"));
56371 reveal(box, finishDragString);
56372 context.map().on("move.intro drawn.intro", function() {
56373 if (!context.hasEntity(woodRoadID) || !context.hasEntity(woodRoadEndID)) {
56374 return continueTo(updateLine);
56376 var padding2 = 100 * Math.pow(2, context.map().zoom() - 19);
56377 var box2 = pad(woodRoadDragEndpoint, padding2, context);
56378 reveal(box2, finishDragString, { duration: 0 });
56379 var entity = context.entity(woodRoadEndID);
56380 if (geoSphericalDistance(entity.loc, woodRoadDragEndpoint) > 4) {
56381 continueTo(startDragEndpoint);
56384 context.on("enter.intro", function() {
56385 continueTo(startDragMidpoint);
56387 function continueTo(nextStep) {
56388 context.map().on("move.intro drawn.intro", null);
56389 context.on("enter.intro", null);
56393 function startDragMidpoint() {
56394 if (!context.hasEntity(woodRoadID) || !context.hasEntity(woodRoadEndID)) {
56395 return continueTo(updateLine);
56397 if (context.selectedIDs().indexOf(woodRoadID) === -1) {
56398 context.enter(modeSelect(context, [woodRoadID]));
56400 var padding = 80 * Math.pow(2, context.map().zoom() - 19);
56401 var box = pad(woodRoadDragMidpoint, padding, context);
56402 reveal(box, helpHtml("intro.lines.start_drag_midpoint"));
56403 context.map().on("move.intro drawn.intro", function() {
56404 if (!context.hasEntity(woodRoadID) || !context.hasEntity(woodRoadEndID)) {
56405 return continueTo(updateLine);
56407 var padding2 = 80 * Math.pow(2, context.map().zoom() - 19);
56408 var box2 = pad(woodRoadDragMidpoint, padding2, context);
56409 reveal(box2, helpHtml("intro.lines.start_drag_midpoint"), { duration: 0 });
56411 context.history().on("change.intro", function(changed) {
56412 if (changed.created().length === 1) {
56413 continueTo(continueDragMidpoint);
56416 context.on("enter.intro", function(mode) {
56417 if (mode.id !== "select") {
56418 context.enter(modeSelect(context, [woodRoadID]));
56421 function continueTo(nextStep) {
56422 context.map().on("move.intro drawn.intro", null);
56423 context.history().on("change.intro", null);
56424 context.on("enter.intro", null);
56428 function continueDragMidpoint() {
56429 if (!context.hasEntity(woodRoadID) || !context.hasEntity(woodRoadEndID)) {
56430 return continueTo(updateLine);
56432 var padding = 100 * Math.pow(2, context.map().zoom() - 19);
56433 var box = pad(woodRoadDragEndpoint, padding, context);
56435 var advance = function() {
56436 context.history().checkpoint("doneUpdateLine");
56437 continueTo(deleteLines);
56441 helpHtml("intro.lines.continue_drag_midpoint"),
56442 { buttonText: _t.html("intro.ok"), buttonCallback: advance }
56444 context.map().on("move.intro drawn.intro", function() {
56445 if (!context.hasEntity(woodRoadID) || !context.hasEntity(woodRoadEndID)) {
56446 return continueTo(updateLine);
56448 var padding2 = 100 * Math.pow(2, context.map().zoom() - 19);
56449 var box2 = pad(woodRoadDragEndpoint, padding2, context);
56450 box2.height += 400;
56453 helpHtml("intro.lines.continue_drag_midpoint"),
56454 { duration: 0, buttonText: _t.html("intro.ok"), buttonCallback: advance }
56457 function continueTo(nextStep) {
56458 context.map().on("move.intro drawn.intro", null);
56462 function deleteLines() {
56463 context.history().reset("doneUpdateLine");
56464 context.enter(modeBrowse(context));
56465 if (!context.hasEntity(washingtonStreetID) || !context.hasEntity(twelfthAvenueID) || !context.hasEntity(eleventhAvenueEndID)) {
56466 return chapter.restart();
56468 var msec = transitionTime(deleteLinesLoc, context.map().center());
56470 reveal(null, null, { duration: 0 });
56472 context.map().centerZoomEase(deleteLinesLoc, 18, msec);
56473 timeout2(function() {
56474 var padding = 200 * Math.pow(2, context.map().zoom() - 18);
56475 var box = pad(deleteLinesLoc, padding, context);
56478 var advance = function() {
56479 continueTo(rightClickIntersection);
56483 helpHtml("intro.lines.delete_lines", { street: _t("intro.graph.name.12th-avenue") }),
56484 { buttonText: _t.html("intro.ok"), buttonCallback: advance }
56486 context.map().on("move.intro drawn.intro", function() {
56487 var padding2 = 200 * Math.pow(2, context.map().zoom() - 18);
56488 var box2 = pad(deleteLinesLoc, padding2, context);
56490 box2.height += 400;
56493 helpHtml("intro.lines.delete_lines", { street: _t("intro.graph.name.12th-avenue") }),
56494 { duration: 0, buttonText: _t.html("intro.ok"), buttonCallback: advance }
56497 context.history().on("change.intro", function() {
56498 timeout2(function() {
56499 continueTo(deleteLines);
56503 function continueTo(nextStep) {
56504 context.map().on("move.intro drawn.intro", null);
56505 context.history().on("change.intro", null);
56509 function rightClickIntersection() {
56510 context.history().reset("doneUpdateLine");
56511 context.enter(modeBrowse(context));
56512 context.map().centerZoomEase(eleventhAvenueEnd, 18, 500);
56513 var rightClickString = helpHtml("intro.lines.split_street", {
56514 street1: _t("intro.graph.name.11th-avenue"),
56515 street2: _t("intro.graph.name.washington-street")
56516 }) + helpHtml("intro.lines." + (context.lastPointerType() === "mouse" ? "rightclick_intersection" : "edit_menu_intersection_touch"));
56517 timeout2(function() {
56518 var padding = 60 * Math.pow(2, context.map().zoom() - 18);
56519 var box = pad(eleventhAvenueEnd, padding, context);
56520 reveal(box, rightClickString);
56521 context.map().on("move.intro drawn.intro", function() {
56522 var padding2 = 60 * Math.pow(2, context.map().zoom() - 18);
56523 var box2 = pad(eleventhAvenueEnd, padding2, context);
56530 context.on("enter.intro", function(mode) {
56531 if (mode.id !== "select")
56533 var ids = context.selectedIDs();
56534 if (ids.length !== 1 || ids[0] !== eleventhAvenueEndID)
56536 timeout2(function() {
56537 var node = selectMenuItem(context, "split").node();
56540 continueTo(splitIntersection);
56543 context.history().on("change.intro", function() {
56544 timeout2(function() {
56545 continueTo(deleteLines);
56549 function continueTo(nextStep) {
56550 context.map().on("move.intro drawn.intro", null);
56551 context.on("enter.intro", null);
56552 context.history().on("change.intro", null);
56556 function splitIntersection() {
56557 if (!context.hasEntity(washingtonStreetID) || !context.hasEntity(twelfthAvenueID) || !context.hasEntity(eleventhAvenueEndID)) {
56558 return continueTo(deleteLines);
56560 var node = selectMenuItem(context, "split").node();
56562 return continueTo(rightClickIntersection);
56564 var wasChanged = false;
56565 _washingtonSegmentID = null;
56569 "intro.lines.split_intersection",
56570 { street: _t("intro.graph.name.washington-street") }
56574 context.map().on("move.intro drawn.intro", function() {
56575 var node2 = selectMenuItem(context, "split").node();
56576 if (!wasChanged && !node2) {
56577 return continueTo(rightClickIntersection);
56582 "intro.lines.split_intersection",
56583 { street: _t("intro.graph.name.washington-street") }
56585 { duration: 0, padding: 50 }
56588 context.history().on("change.intro", function(changed) {
56590 timeout2(function() {
56591 if (context.history().undoAnnotation() === _t("operations.split.annotation.line", { n: 1 })) {
56592 _washingtonSegmentID = changed.created()[0].id;
56593 continueTo(didSplit);
56595 _washingtonSegmentID = null;
56596 continueTo(retrySplit);
56600 function continueTo(nextStep) {
56601 context.map().on("move.intro drawn.intro", null);
56602 context.history().on("change.intro", null);
56606 function retrySplit() {
56607 context.enter(modeBrowse(context));
56608 context.map().centerZoomEase(eleventhAvenueEnd, 18, 500);
56609 var advance = function() {
56610 continueTo(rightClickIntersection);
56612 var padding = 60 * Math.pow(2, context.map().zoom() - 18);
56613 var box = pad(eleventhAvenueEnd, padding, context);
56616 helpHtml("intro.lines.retry_split"),
56617 { buttonText: _t.html("intro.ok"), buttonCallback: advance }
56619 context.map().on("move.intro drawn.intro", function() {
56620 var padding2 = 60 * Math.pow(2, context.map().zoom() - 18);
56621 var box2 = pad(eleventhAvenueEnd, padding2, context);
56624 helpHtml("intro.lines.retry_split"),
56625 { duration: 0, buttonText: _t.html("intro.ok"), buttonCallback: advance }
56628 function continueTo(nextStep) {
56629 context.map().on("move.intro drawn.intro", null);
56633 function didSplit() {
56634 if (!_washingtonSegmentID || !context.hasEntity(_washingtonSegmentID) || !context.hasEntity(washingtonStreetID) || !context.hasEntity(twelfthAvenueID) || !context.hasEntity(eleventhAvenueEndID)) {
56635 return continueTo(rightClickIntersection);
56637 var ids = context.selectedIDs();
56638 var string = "intro.lines.did_split_" + (ids.length > 1 ? "multi" : "single");
56639 var street = _t("intro.graph.name.washington-street");
56640 var padding = 200 * Math.pow(2, context.map().zoom() - 18);
56641 var box = pad(twelfthAvenue, padding, context);
56642 box.width = box.width / 2;
56645 helpHtml(string, { street1: street, street2: street }),
56648 timeout2(function() {
56649 context.map().centerZoomEase(twelfthAvenue, 18, 500);
56650 context.map().on("move.intro drawn.intro", function() {
56651 var padding2 = 200 * Math.pow(2, context.map().zoom() - 18);
56652 var box2 = pad(twelfthAvenue, padding2, context);
56653 box2.width = box2.width / 2;
56656 helpHtml(string, { street1: street, street2: street }),
56661 context.on("enter.intro", function() {
56662 var ids2 = context.selectedIDs();
56663 if (ids2.length === 1 && ids2[0] === _washingtonSegmentID) {
56664 continueTo(multiSelect);
56667 context.history().on("change.intro", function() {
56668 if (!_washingtonSegmentID || !context.hasEntity(_washingtonSegmentID) || !context.hasEntity(washingtonStreetID) || !context.hasEntity(twelfthAvenueID) || !context.hasEntity(eleventhAvenueEndID)) {
56669 return continueTo(rightClickIntersection);
56672 function continueTo(nextStep) {
56673 context.map().on("move.intro drawn.intro", null);
56674 context.on("enter.intro", null);
56675 context.history().on("change.intro", null);
56679 function multiSelect() {
56680 if (!_washingtonSegmentID || !context.hasEntity(_washingtonSegmentID) || !context.hasEntity(washingtonStreetID) || !context.hasEntity(twelfthAvenueID) || !context.hasEntity(eleventhAvenueEndID)) {
56681 return continueTo(rightClickIntersection);
56683 var ids = context.selectedIDs();
56684 var hasWashington = ids.indexOf(_washingtonSegmentID) !== -1;
56685 var hasTwelfth = ids.indexOf(twelfthAvenueID) !== -1;
56686 if (hasWashington && hasTwelfth) {
56687 return continueTo(multiRightClick);
56688 } else if (!hasWashington && !hasTwelfth) {
56689 return continueTo(didSplit);
56691 context.map().centerZoomEase(twelfthAvenue, 18, 500);
56692 timeout2(function() {
56693 var selected, other, padding, box;
56694 if (hasWashington) {
56695 selected = _t("intro.graph.name.washington-street");
56696 other = _t("intro.graph.name.12th-avenue");
56697 padding = 60 * Math.pow(2, context.map().zoom() - 18);
56698 box = pad(twelfthAvenueEnd, padding, context);
56701 selected = _t("intro.graph.name.12th-avenue");
56702 other = _t("intro.graph.name.washington-street");
56703 padding = 200 * Math.pow(2, context.map().zoom() - 18);
56704 box = pad(twelfthAvenue, padding, context);
56710 "intro.lines.multi_select",
56711 { selected, other1: other }
56712 ) + " " + helpHtml(
56713 "intro.lines.add_to_selection_" + (context.lastPointerType() === "mouse" ? "click" : "touch"),
56714 { selected, other2: other }
56717 context.map().on("move.intro drawn.intro", function() {
56718 if (hasWashington) {
56719 selected = _t("intro.graph.name.washington-street");
56720 other = _t("intro.graph.name.12th-avenue");
56721 padding = 60 * Math.pow(2, context.map().zoom() - 18);
56722 box = pad(twelfthAvenueEnd, padding, context);
56725 selected = _t("intro.graph.name.12th-avenue");
56726 other = _t("intro.graph.name.washington-street");
56727 padding = 200 * Math.pow(2, context.map().zoom() - 18);
56728 box = pad(twelfthAvenue, padding, context);
56734 "intro.lines.multi_select",
56735 { selected, other1: other }
56736 ) + " " + helpHtml(
56737 "intro.lines.add_to_selection_" + (context.lastPointerType() === "mouse" ? "click" : "touch"),
56738 { selected, other2: other }
56743 context.on("enter.intro", function() {
56744 continueTo(multiSelect);
56746 context.history().on("change.intro", function() {
56747 if (!_washingtonSegmentID || !context.hasEntity(_washingtonSegmentID) || !context.hasEntity(washingtonStreetID) || !context.hasEntity(twelfthAvenueID) || !context.hasEntity(eleventhAvenueEndID)) {
56748 return continueTo(rightClickIntersection);
56752 function continueTo(nextStep) {
56753 context.map().on("move.intro drawn.intro", null);
56754 context.on("enter.intro", null);
56755 context.history().on("change.intro", null);
56759 function multiRightClick() {
56760 if (!_washingtonSegmentID || !context.hasEntity(_washingtonSegmentID) || !context.hasEntity(washingtonStreetID) || !context.hasEntity(twelfthAvenueID) || !context.hasEntity(eleventhAvenueEndID)) {
56761 return continueTo(rightClickIntersection);
56763 var padding = 200 * Math.pow(2, context.map().zoom() - 18);
56764 var box = pad(twelfthAvenue, padding, context);
56765 var rightClickString = helpHtml("intro.lines.multi_select_success") + helpHtml("intro.lines.multi_" + (context.lastPointerType() === "mouse" ? "rightclick" : "edit_menu_touch"));
56766 reveal(box, rightClickString);
56767 context.map().on("move.intro drawn.intro", function() {
56768 var padding2 = 200 * Math.pow(2, context.map().zoom() - 18);
56769 var box2 = pad(twelfthAvenue, padding2, context);
56770 reveal(box2, rightClickString, { duration: 0 });
56772 context.ui().editMenu().on("toggled.intro", function(open) {
56775 timeout2(function() {
56776 var ids = context.selectedIDs();
56777 if (ids.length === 2 && ids.indexOf(twelfthAvenueID) !== -1 && ids.indexOf(_washingtonSegmentID) !== -1) {
56778 var node = selectMenuItem(context, "delete").node();
56781 continueTo(multiDelete);
56782 } else if (ids.length === 1 && ids.indexOf(_washingtonSegmentID) !== -1) {
56783 return continueTo(multiSelect);
56785 return continueTo(didSplit);
56789 context.history().on("change.intro", function() {
56790 if (!_washingtonSegmentID || !context.hasEntity(_washingtonSegmentID) || !context.hasEntity(washingtonStreetID) || !context.hasEntity(twelfthAvenueID) || !context.hasEntity(eleventhAvenueEndID)) {
56791 return continueTo(rightClickIntersection);
56794 function continueTo(nextStep) {
56795 context.map().on("move.intro drawn.intro", null);
56796 context.ui().editMenu().on("toggled.intro", null);
56797 context.history().on("change.intro", null);
56801 function multiDelete() {
56802 if (!_washingtonSegmentID || !context.hasEntity(_washingtonSegmentID) || !context.hasEntity(washingtonStreetID) || !context.hasEntity(twelfthAvenueID) || !context.hasEntity(eleventhAvenueEndID)) {
56803 return continueTo(rightClickIntersection);
56805 var node = selectMenuItem(context, "delete").node();
56807 return continueTo(multiRightClick);
56810 helpHtml("intro.lines.multi_delete"),
56813 context.map().on("move.intro drawn.intro", function() {
56816 helpHtml("intro.lines.multi_delete"),
56817 { duration: 0, padding: 50 }
56820 context.on("exit.intro", function() {
56821 if (context.hasEntity(_washingtonSegmentID) || context.hasEntity(twelfthAvenueID)) {
56822 return continueTo(multiSelect);
56825 context.history().on("change.intro", function() {
56826 if (context.hasEntity(_washingtonSegmentID) || context.hasEntity(twelfthAvenueID)) {
56827 continueTo(retryDelete);
56832 function continueTo(nextStep) {
56833 context.map().on("move.intro drawn.intro", null);
56834 context.on("exit.intro", null);
56835 context.history().on("change.intro", null);
56839 function retryDelete() {
56840 context.enter(modeBrowse(context));
56841 var padding = 200 * Math.pow(2, context.map().zoom() - 18);
56842 var box = pad(twelfthAvenue, padding, context);
56843 reveal(box, helpHtml("intro.lines.retry_delete"), {
56844 buttonText: _t.html("intro.ok"),
56845 buttonCallback: function() {
56846 continueTo(multiSelect);
56849 function continueTo(nextStep) {
56854 dispatch10.call("done");
56857 helpHtml("intro.lines.play", { next: _t("intro.buildings.title") }),
56859 tooltipBox: ".intro-nav-wrap .chapter-building",
56860 buttonText: _t.html("intro.ok"),
56861 buttonCallback: function() {
56862 reveal(".ideditor");
56867 chapter.enter = function() {
56870 chapter.exit = function() {
56871 timeouts.forEach(window.clearTimeout);
56872 select_default2(window).on("pointerdown.intro mousedown.intro", null, true);
56873 context.on("enter.intro exit.intro", null);
56874 context.map().on("move.intro drawn.intro", null);
56875 context.history().on("change.intro", null);
56876 context.container().select(".inspector-wrap").on("wheel.intro", null);
56877 context.container().select(".preset-list-button").on("click.intro", null);
56879 chapter.restart = function() {
56883 return utilRebind(chapter, dispatch10, "on");
56886 // modules/ui/intro/building.js
56887 function uiIntroBuilding(context, reveal) {
56888 var dispatch10 = dispatch_default("done");
56889 var house = [-85.62815, 41.95638];
56890 var tank = [-85.62732, 41.95347];
56891 var buildingCatetory = _mainPresetIndex.item("category-building");
56892 var housePreset = _mainPresetIndex.item("building/house");
56893 var tankPreset = _mainPresetIndex.item("man_made/storage_tank");
56895 var _houseID = null;
56896 var _tankID = null;
56898 title: "intro.buildings.title"
56900 function timeout2(f2, t) {
56901 timeouts.push(window.setTimeout(f2, t));
56903 function eventCancel(d3_event) {
56904 d3_event.stopPropagation();
56905 d3_event.preventDefault();
56907 function revealHouse(center, text2, options2) {
56908 var padding = 160 * Math.pow(2, context.map().zoom() - 20);
56909 var box = pad(center, padding, context);
56910 reveal(box, text2, options2);
56912 function revealTank(center, text2, options2) {
56913 var padding = 190 * Math.pow(2, context.map().zoom() - 19.5);
56914 var box = pad(center, padding, context);
56915 reveal(box, text2, options2);
56917 function addHouse() {
56918 context.enter(modeBrowse(context));
56919 context.history().reset("initial");
56921 var msec = transitionTime(house, context.map().center());
56923 reveal(null, null, { duration: 0 });
56925 context.map().centerZoomEase(house, 19, msec);
56926 timeout2(function() {
56927 var tooltip = reveal(
56929 helpHtml("intro.buildings.add_building")
56931 tooltip.selectAll(".popover-inner").insert("svg", "span").attr("class", "tooltip-illustration").append("use").attr("xlink:href", "#iD-graphic-buildings");
56932 context.on("enter.intro", function(mode) {
56933 if (mode.id !== "add-area")
56935 continueTo(startHouse);
56938 function continueTo(nextStep) {
56939 context.on("enter.intro", null);
56943 function startHouse() {
56944 if (context.mode().id !== "add-area") {
56945 return continueTo(addHouse);
56948 context.map().zoomEase(20, 500);
56949 timeout2(function() {
56950 var startString = helpHtml("intro.buildings.start_building") + helpHtml("intro.buildings.building_corner_" + (context.lastPointerType() === "mouse" ? "click" : "tap"));
56951 revealHouse(house, startString);
56952 context.map().on("move.intro drawn.intro", function() {
56953 revealHouse(house, startString, { duration: 0 });
56955 context.on("enter.intro", function(mode) {
56956 if (mode.id !== "draw-area")
56957 return chapter.restart();
56958 continueTo(continueHouse);
56961 function continueTo(nextStep) {
56962 context.map().on("move.intro drawn.intro", null);
56963 context.on("enter.intro", null);
56967 function continueHouse() {
56968 if (context.mode().id !== "draw-area") {
56969 return continueTo(addHouse);
56972 var continueString = helpHtml("intro.buildings.continue_building") + "{br}" + helpHtml("intro.areas.finish_area_" + (context.lastPointerType() === "mouse" ? "click" : "tap")) + helpHtml("intro.buildings.finish_building");
56973 revealHouse(house, continueString);
56974 context.map().on("move.intro drawn.intro", function() {
56975 revealHouse(house, continueString, { duration: 0 });
56977 context.on("enter.intro", function(mode) {
56978 if (mode.id === "draw-area") {
56980 } else if (mode.id === "select") {
56981 var graph = context.graph();
56982 var way = context.entity(context.selectedIDs()[0]);
56983 var nodes = graph.childNodes(way);
56984 var points = utilArrayUniq(nodes).map(function(n2) {
56985 return context.projection(n2.loc);
56987 if (isMostlySquare(points)) {
56989 return continueTo(chooseCategoryBuilding);
56991 return continueTo(retryHouse);
56994 return chapter.restart();
56997 function continueTo(nextStep) {
56998 context.map().on("move.intro drawn.intro", null);
56999 context.on("enter.intro", null);
57003 function retryHouse() {
57004 var onClick = function() {
57005 continueTo(addHouse);
57009 helpHtml("intro.buildings.retry_building"),
57010 { buttonText: _t.html("intro.ok"), buttonCallback: onClick }
57012 context.map().on("move.intro drawn.intro", function() {
57015 helpHtml("intro.buildings.retry_building"),
57016 { duration: 0, buttonText: _t.html("intro.ok"), buttonCallback: onClick }
57019 function continueTo(nextStep) {
57020 context.map().on("move.intro drawn.intro", null);
57024 function chooseCategoryBuilding() {
57025 if (!_houseID || !context.hasEntity(_houseID)) {
57028 var ids = context.selectedIDs();
57029 if (context.mode().id !== "select" || !ids.length || ids[0] !== _houseID) {
57030 context.enter(modeSelect(context, [_houseID]));
57032 context.container().select(".inspector-wrap").on("wheel.intro", eventCancel);
57033 timeout2(function() {
57034 context.container().select(".inspector-wrap .panewrap").style("right", "-100%");
57035 var button = context.container().select(".preset-category-building .preset-list-button");
57038 helpHtml("intro.buildings.choose_category_building", { category: buildingCatetory.name() })
57040 button.on("click.intro", function() {
57041 button.on("click.intro", null);
57042 continueTo(choosePresetHouse);
57045 context.on("enter.intro", function(mode) {
57046 if (!_houseID || !context.hasEntity(_houseID)) {
57047 return continueTo(addHouse);
57049 var ids2 = context.selectedIDs();
57050 if (mode.id !== "select" || !ids2.length || ids2[0] !== _houseID) {
57051 return continueTo(chooseCategoryBuilding);
57054 function continueTo(nextStep) {
57055 context.container().select(".inspector-wrap").on("wheel.intro", null);
57056 context.container().select(".preset-list-button").on("click.intro", null);
57057 context.on("enter.intro", null);
57061 function choosePresetHouse() {
57062 if (!_houseID || !context.hasEntity(_houseID)) {
57065 var ids = context.selectedIDs();
57066 if (context.mode().id !== "select" || !ids.length || ids[0] !== _houseID) {
57067 context.enter(modeSelect(context, [_houseID]));
57069 context.container().select(".inspector-wrap").on("wheel.intro", eventCancel);
57070 timeout2(function() {
57071 context.container().select(".inspector-wrap .panewrap").style("right", "-100%");
57072 var button = context.container().select(".preset-building-house .preset-list-button");
57075 helpHtml("intro.buildings.choose_preset_house", { preset: housePreset.name() }),
57078 button.on("click.intro", function() {
57079 button.on("click.intro", null);
57080 continueTo(closeEditorHouse);
57083 context.on("enter.intro", function(mode) {
57084 if (!_houseID || !context.hasEntity(_houseID)) {
57085 return continueTo(addHouse);
57087 var ids2 = context.selectedIDs();
57088 if (mode.id !== "select" || !ids2.length || ids2[0] !== _houseID) {
57089 return continueTo(chooseCategoryBuilding);
57092 function continueTo(nextStep) {
57093 context.container().select(".inspector-wrap").on("wheel.intro", null);
57094 context.container().select(".preset-list-button").on("click.intro", null);
57095 context.on("enter.intro", null);
57099 function closeEditorHouse() {
57100 if (!_houseID || !context.hasEntity(_houseID)) {
57103 var ids = context.selectedIDs();
57104 if (context.mode().id !== "select" || !ids.length || ids[0] !== _houseID) {
57105 context.enter(modeSelect(context, [_houseID]));
57107 context.history().checkpoint("hasHouse");
57108 context.on("exit.intro", function() {
57109 continueTo(rightClickHouse);
57111 timeout2(function() {
57113 ".entity-editor-pane",
57114 helpHtml("intro.buildings.close", { button: { html: icon("#iD-icon-close", "inline") } })
57117 function continueTo(nextStep) {
57118 context.on("exit.intro", null);
57122 function rightClickHouse() {
57124 return chapter.restart();
57125 context.enter(modeBrowse(context));
57126 context.history().reset("hasHouse");
57127 var zoom = context.map().zoom();
57131 context.map().centerZoomEase(house, zoom, 500);
57132 context.on("enter.intro", function(mode) {
57133 if (mode.id !== "select")
57135 var ids = context.selectedIDs();
57136 if (ids.length !== 1 || ids[0] !== _houseID)
57138 timeout2(function() {
57139 var node = selectMenuItem(context, "orthogonalize").node();
57142 continueTo(clickSquare);
57145 context.map().on("move.intro drawn.intro", function() {
57146 var rightclickString = helpHtml("intro.buildings." + (context.lastPointerType() === "mouse" ? "rightclick_building" : "edit_menu_building_touch"));
57147 revealHouse(house, rightclickString, { duration: 0 });
57149 context.history().on("change.intro", function() {
57150 continueTo(rightClickHouse);
57152 function continueTo(nextStep) {
57153 context.on("enter.intro", null);
57154 context.map().on("move.intro drawn.intro", null);
57155 context.history().on("change.intro", null);
57159 function clickSquare() {
57161 return chapter.restart();
57162 var entity = context.hasEntity(_houseID);
57164 return continueTo(rightClickHouse);
57165 var node = selectMenuItem(context, "orthogonalize").node();
57167 return continueTo(rightClickHouse);
57169 var wasChanged = false;
57172 helpHtml("intro.buildings.square_building"),
57175 context.on("enter.intro", function(mode) {
57176 if (mode.id === "browse") {
57177 continueTo(rightClickHouse);
57178 } else if (mode.id === "move" || mode.id === "rotate") {
57179 continueTo(retryClickSquare);
57182 context.map().on("move.intro", function() {
57183 var node2 = selectMenuItem(context, "orthogonalize").node();
57184 if (!wasChanged && !node2) {
57185 return continueTo(rightClickHouse);
57189 helpHtml("intro.buildings.square_building"),
57190 { duration: 0, padding: 50 }
57193 context.history().on("change.intro", function() {
57195 context.history().on("change.intro", null);
57196 timeout2(function() {
57197 if (context.history().undoAnnotation() === _t("operations.orthogonalize.annotation.feature", { n: 1 })) {
57198 continueTo(doneSquare);
57200 continueTo(retryClickSquare);
57204 function continueTo(nextStep) {
57205 context.on("enter.intro", null);
57206 context.map().on("move.intro", null);
57207 context.history().on("change.intro", null);
57211 function retryClickSquare() {
57212 context.enter(modeBrowse(context));
57213 revealHouse(house, helpHtml("intro.buildings.retry_square"), {
57214 buttonText: _t.html("intro.ok"),
57215 buttonCallback: function() {
57216 continueTo(rightClickHouse);
57219 function continueTo(nextStep) {
57223 function doneSquare() {
57224 context.history().checkpoint("doneSquare");
57225 revealHouse(house, helpHtml("intro.buildings.done_square"), {
57226 buttonText: _t.html("intro.ok"),
57227 buttonCallback: function() {
57228 continueTo(addTank);
57231 function continueTo(nextStep) {
57235 function addTank() {
57236 context.enter(modeBrowse(context));
57237 context.history().reset("doneSquare");
57239 var msec = transitionTime(tank, context.map().center());
57241 reveal(null, null, { duration: 0 });
57243 context.map().centerZoomEase(tank, 19.5, msec);
57244 timeout2(function() {
57247 helpHtml("intro.buildings.add_tank")
57249 context.on("enter.intro", function(mode) {
57250 if (mode.id !== "add-area")
57252 continueTo(startTank);
57255 function continueTo(nextStep) {
57256 context.on("enter.intro", null);
57260 function startTank() {
57261 if (context.mode().id !== "add-area") {
57262 return continueTo(addTank);
57265 timeout2(function() {
57266 var startString = helpHtml("intro.buildings.start_tank") + helpHtml("intro.buildings.tank_edge_" + (context.lastPointerType() === "mouse" ? "click" : "tap"));
57267 revealTank(tank, startString);
57268 context.map().on("move.intro drawn.intro", function() {
57269 revealTank(tank, startString, { duration: 0 });
57271 context.on("enter.intro", function(mode) {
57272 if (mode.id !== "draw-area")
57273 return chapter.restart();
57274 continueTo(continueTank);
57277 function continueTo(nextStep) {
57278 context.map().on("move.intro drawn.intro", null);
57279 context.on("enter.intro", null);
57283 function continueTank() {
57284 if (context.mode().id !== "draw-area") {
57285 return continueTo(addTank);
57288 var continueString = helpHtml("intro.buildings.continue_tank") + "{br}" + helpHtml("intro.areas.finish_area_" + (context.lastPointerType() === "mouse" ? "click" : "tap")) + helpHtml("intro.buildings.finish_tank");
57289 revealTank(tank, continueString);
57290 context.map().on("move.intro drawn.intro", function() {
57291 revealTank(tank, continueString, { duration: 0 });
57293 context.on("enter.intro", function(mode) {
57294 if (mode.id === "draw-area") {
57296 } else if (mode.id === "select") {
57297 _tankID = context.selectedIDs()[0];
57298 return continueTo(searchPresetTank);
57300 return continueTo(addTank);
57303 function continueTo(nextStep) {
57304 context.map().on("move.intro drawn.intro", null);
57305 context.on("enter.intro", null);
57309 function searchPresetTank() {
57310 if (!_tankID || !context.hasEntity(_tankID)) {
57313 var ids = context.selectedIDs();
57314 if (context.mode().id !== "select" || !ids.length || ids[0] !== _tankID) {
57315 context.enter(modeSelect(context, [_tankID]));
57317 context.container().select(".inspector-wrap").on("wheel.intro", eventCancel);
57318 timeout2(function() {
57319 context.container().select(".inspector-wrap .panewrap").style("right", "-100%");
57320 context.container().select(".preset-search-input").on("keydown.intro", null).on("keyup.intro", checkPresetSearch);
57322 ".preset-search-input",
57323 helpHtml("intro.buildings.search_tank", { preset: tankPreset.name() })
57326 context.on("enter.intro", function(mode) {
57327 if (!_tankID || !context.hasEntity(_tankID)) {
57328 return continueTo(addTank);
57330 var ids2 = context.selectedIDs();
57331 if (mode.id !== "select" || !ids2.length || ids2[0] !== _tankID) {
57332 context.enter(modeSelect(context, [_tankID]));
57333 context.container().select(".inspector-wrap .panewrap").style("right", "-100%");
57334 context.container().select(".inspector-wrap").on("wheel.intro", eventCancel);
57335 context.container().select(".preset-search-input").on("keydown.intro", null).on("keyup.intro", checkPresetSearch);
57337 ".preset-search-input",
57338 helpHtml("intro.buildings.search_tank", { preset: tankPreset.name() })
57340 context.history().on("change.intro", null);
57343 function checkPresetSearch() {
57344 var first = context.container().select(".preset-list-item:first-child");
57345 if (first.classed("preset-man_made-storage_tank")) {
57347 first.select(".preset-list-button").node(),
57348 helpHtml("intro.buildings.choose_tank", { preset: tankPreset.name() }),
57351 context.container().select(".preset-search-input").on("keydown.intro", eventCancel, true).on("keyup.intro", null);
57352 context.history().on("change.intro", function() {
57353 continueTo(closeEditorTank);
57357 function continueTo(nextStep) {
57358 context.container().select(".inspector-wrap").on("wheel.intro", null);
57359 context.on("enter.intro", null);
57360 context.history().on("change.intro", null);
57361 context.container().select(".preset-search-input").on("keydown.intro keyup.intro", null);
57365 function closeEditorTank() {
57366 if (!_tankID || !context.hasEntity(_tankID)) {
57369 var ids = context.selectedIDs();
57370 if (context.mode().id !== "select" || !ids.length || ids[0] !== _tankID) {
57371 context.enter(modeSelect(context, [_tankID]));
57373 context.history().checkpoint("hasTank");
57374 context.on("exit.intro", function() {
57375 continueTo(rightClickTank);
57377 timeout2(function() {
57379 ".entity-editor-pane",
57380 helpHtml("intro.buildings.close", { button: { html: icon("#iD-icon-close", "inline") } })
57383 function continueTo(nextStep) {
57384 context.on("exit.intro", null);
57388 function rightClickTank() {
57390 return continueTo(addTank);
57391 context.enter(modeBrowse(context));
57392 context.history().reset("hasTank");
57393 context.map().centerEase(tank, 500);
57394 timeout2(function() {
57395 context.on("enter.intro", function(mode) {
57396 if (mode.id !== "select")
57398 var ids = context.selectedIDs();
57399 if (ids.length !== 1 || ids[0] !== _tankID)
57401 timeout2(function() {
57402 var node = selectMenuItem(context, "circularize").node();
57405 continueTo(clickCircle);
57408 var rightclickString = helpHtml("intro.buildings." + (context.lastPointerType() === "mouse" ? "rightclick_tank" : "edit_menu_tank_touch"));
57409 revealTank(tank, rightclickString);
57410 context.map().on("move.intro drawn.intro", function() {
57411 revealTank(tank, rightclickString, { duration: 0 });
57413 context.history().on("change.intro", function() {
57414 continueTo(rightClickTank);
57417 function continueTo(nextStep) {
57418 context.on("enter.intro", null);
57419 context.map().on("move.intro drawn.intro", null);
57420 context.history().on("change.intro", null);
57424 function clickCircle() {
57426 return chapter.restart();
57427 var entity = context.hasEntity(_tankID);
57429 return continueTo(rightClickTank);
57430 var node = selectMenuItem(context, "circularize").node();
57432 return continueTo(rightClickTank);
57434 var wasChanged = false;
57437 helpHtml("intro.buildings.circle_tank"),
57440 context.on("enter.intro", function(mode) {
57441 if (mode.id === "browse") {
57442 continueTo(rightClickTank);
57443 } else if (mode.id === "move" || mode.id === "rotate") {
57444 continueTo(retryClickCircle);
57447 context.map().on("move.intro", function() {
57448 var node2 = selectMenuItem(context, "circularize").node();
57449 if (!wasChanged && !node2) {
57450 return continueTo(rightClickTank);
57454 helpHtml("intro.buildings.circle_tank"),
57455 { duration: 0, padding: 50 }
57458 context.history().on("change.intro", function() {
57460 context.history().on("change.intro", null);
57461 timeout2(function() {
57462 if (context.history().undoAnnotation() === _t("operations.circularize.annotation.feature", { n: 1 })) {
57465 continueTo(retryClickCircle);
57469 function continueTo(nextStep) {
57470 context.on("enter.intro", null);
57471 context.map().on("move.intro", null);
57472 context.history().on("change.intro", null);
57476 function retryClickCircle() {
57477 context.enter(modeBrowse(context));
57478 revealTank(tank, helpHtml("intro.buildings.retry_circle"), {
57479 buttonText: _t.html("intro.ok"),
57480 buttonCallback: function() {
57481 continueTo(rightClickTank);
57484 function continueTo(nextStep) {
57489 dispatch10.call("done");
57492 helpHtml("intro.buildings.play", { next: _t("intro.startediting.title") }),
57494 tooltipBox: ".intro-nav-wrap .chapter-startEditing",
57495 buttonText: _t.html("intro.ok"),
57496 buttonCallback: function() {
57497 reveal(".ideditor");
57502 chapter.enter = function() {
57505 chapter.exit = function() {
57506 timeouts.forEach(window.clearTimeout);
57507 context.on("enter.intro exit.intro", null);
57508 context.map().on("move.intro drawn.intro", null);
57509 context.history().on("change.intro", null);
57510 context.container().select(".inspector-wrap").on("wheel.intro", null);
57511 context.container().select(".preset-search-input").on("keydown.intro keyup.intro", null);
57512 context.container().select(".more-fields .combobox-input").on("click.intro", null);
57514 chapter.restart = function() {
57518 return utilRebind(chapter, dispatch10, "on");
57521 // modules/ui/intro/start_editing.js
57522 function uiIntroStartEditing(context, reveal) {
57523 var dispatch10 = dispatch_default("done", "startEditing");
57524 var modalSelection = select_default2(null);
57526 title: "intro.startediting.title"
57528 function showHelp() {
57530 ".map-control.help-control",
57531 helpHtml("intro.startediting.help"),
57533 buttonText: _t.html("intro.ok"),
57534 buttonCallback: function() {
57540 function shortcuts() {
57542 ".map-control.help-control",
57543 helpHtml("intro.startediting.shortcuts"),
57545 buttonText: _t.html("intro.ok"),
57546 buttonCallback: function() {
57552 function showSave() {
57553 context.container().selectAll(".shaded").remove();
57555 ".top-toolbar button.save",
57556 helpHtml("intro.startediting.save"),
57558 buttonText: _t.html("intro.ok"),
57559 buttonCallback: function() {
57565 function showStart() {
57566 context.container().selectAll(".shaded").remove();
57567 modalSelection = uiModal(context.container());
57568 modalSelection.select(".modal").attr("class", "modal-splash modal");
57569 modalSelection.selectAll(".close").remove();
57570 var startbutton = modalSelection.select(".content").attr("class", "fillL").append("button").attr("class", "modal-section huge-modal-button").on("click", function() {
57571 modalSelection.remove();
57573 startbutton.append("svg").attr("class", "illustration").append("use").attr("xlink:href", "#iD-logo-walkthrough");
57574 startbutton.append("h2").call(_t.append("intro.startediting.start"));
57575 dispatch10.call("startEditing");
57577 chapter.enter = function() {
57580 chapter.exit = function() {
57581 modalSelection.remove();
57582 context.container().selectAll(".shaded").remove();
57584 return utilRebind(chapter, dispatch10, "on");
57587 // modules/ui/intro/intro.js
57589 welcome: uiIntroWelcome,
57590 navigation: uiIntroNavigation,
57591 point: uiIntroPoint,
57594 building: uiIntroBuilding,
57595 startEditing: uiIntroStartEditing
57597 var chapterFlow = [
57606 function uiIntro(context) {
57607 const INTRO_IMAGERY = "EsriWorldImageryClarity";
57608 let _introGraph = {};
57610 function intro(selection2) {
57611 _mainFileFetcher.get("intro_graph").then((dataIntroGraph) => {
57612 for (let id2 in dataIntroGraph) {
57613 if (!_introGraph[id2]) {
57614 _introGraph[id2] = osmEntity(localize(dataIntroGraph[id2]));
57617 selection2.call(startIntro);
57618 }).catch(function() {
57621 function startIntro(selection2) {
57622 context.enter(modeBrowse(context));
57623 let osm = context.connection();
57624 let history = context.history().toJSON();
57625 let hash = window.location.hash;
57626 let center = context.map().center();
57627 let zoom = context.map().zoom();
57628 let background = context.background().baseLayerSource();
57629 let overlays = context.background().overlayLayerSources();
57630 let opacity = context.container().selectAll(".main-map .layer-background").style("opacity");
57631 let caches = osm && osm.caches();
57632 let baseEntities = context.history().graph().base().entities;
57633 context.ui().sidebar.expand();
57634 context.container().selectAll("button.sidebar-toggle").classed("disabled", true);
57635 context.inIntro(true);
57637 osm.toggle(false).reset();
57639 context.history().reset();
57640 context.history().merge(Object.values(coreGraph().load(_introGraph).entities));
57641 context.history().checkpoint("initial");
57642 let imagery = context.background().findSource(INTRO_IMAGERY);
57644 context.background().baseLayerSource(imagery);
57646 context.background().bing();
57648 overlays.forEach((d) => context.background().toggleOverlayLayer(d));
57649 let layers = context.layers();
57650 layers.all().forEach((item) => {
57651 if (typeof item.layer.enabled === "function") {
57652 item.layer.enabled(item.id === "osm");
57655 context.container().selectAll(".main-map .layer-background").style("opacity", 1);
57656 let curtain = uiCurtain(context.container().node());
57657 selection2.call(curtain);
57658 corePreferences("walkthrough_started", "yes");
57659 let storedProgress = corePreferences("walkthrough_progress") || "";
57660 let progress = storedProgress.split(";").filter(Boolean);
57661 let chapters = chapterFlow.map((chapter, i2) => {
57662 let s = chapterUi[chapter](context, curtain.reveal).on("done", () => {
57663 buttons.filter((d) => d.title === s.title).classed("finished", true);
57664 if (i2 < chapterFlow.length - 1) {
57665 const next = chapterFlow[i2 + 1];
57666 context.container().select(`button.chapter-${next}`).classed("next", true);
57668 progress.push(chapter);
57669 corePreferences("walkthrough_progress", utilArrayUniq(progress).join(";"));
57673 chapters[chapters.length - 1].on("startEditing", () => {
57674 progress.push("startEditing");
57675 corePreferences("walkthrough_progress", utilArrayUniq(progress).join(";"));
57676 let incomplete = utilArrayDifference(chapterFlow, progress);
57677 if (!incomplete.length) {
57678 corePreferences("walkthrough_completed", "yes");
57682 context.container().selectAll(".main-map .layer-background").style("opacity", opacity);
57683 context.container().selectAll("button.sidebar-toggle").classed("disabled", false);
57685 osm.toggle(true).reset().caches(caches);
57687 context.history().reset().merge(Object.values(baseEntities));
57688 context.background().baseLayerSource(background);
57689 overlays.forEach((d) => context.background().toggleOverlayLayer(d));
57691 context.history().fromJSON(history, false);
57693 context.map().centerZoom(center, zoom);
57694 window.location.replace(hash);
57695 context.inIntro(false);
57697 let navwrap = selection2.append("div").attr("class", "intro-nav-wrap fillD");
57698 navwrap.append("svg").attr("class", "intro-nav-wrap-logo").append("use").attr("xlink:href", "#iD-logo-walkthrough");
57699 let buttonwrap = navwrap.append("div").attr("class", "joined").selectAll("button.chapter");
57700 let buttons = buttonwrap.data(chapters).enter().append("button").attr("class", (d, i2) => `chapter chapter-${chapterFlow[i2]}`).on("click", enterChapter);
57701 buttons.append("span").html((d) => _t.html(d.title));
57702 buttons.append("span").attr("class", "status").call(svgIcon(_mainLocalizer.textDirection() === "rtl" ? "#iD-icon-backward" : "#iD-icon-forward", "inline"));
57703 enterChapter(null, chapters[0]);
57704 function enterChapter(d3_event, newChapter) {
57705 if (_currChapter) {
57706 _currChapter.exit();
57708 context.enter(modeBrowse(context));
57709 _currChapter = newChapter;
57710 _currChapter.enter();
57711 buttons.classed("next", false).classed("active", (d) => d.title === _currChapter.title);
57717 // modules/ui/issues_info.js
57718 function uiIssuesInfo(context) {
57719 var warningsItem = {
57722 iconID: "iD-icon-alert",
57723 descriptionID: "issues.warnings_and_errors"
57725 var resolvedItem = {
57728 iconID: "iD-icon-apply",
57729 descriptionID: "issues.user_resolved_issues"
57731 function update(selection2) {
57732 var shownItems = [];
57733 var liveIssues = context.validator().getIssues({
57734 what: corePreferences("validate-what") || "edited",
57735 where: corePreferences("validate-where") || "all"
57737 if (liveIssues.length) {
57738 warningsItem.count = liveIssues.length;
57739 shownItems.push(warningsItem);
57741 if (corePreferences("validate-what") === "all") {
57742 var resolvedIssues = context.validator().getResolvedIssues();
57743 if (resolvedIssues.length) {
57744 resolvedItem.count = resolvedIssues.length;
57745 shownItems.push(resolvedItem);
57748 var chips = selection2.selectAll(".chip").data(shownItems, function(d) {
57751 chips.exit().remove();
57752 var enter = chips.enter().append("a").attr("class", function(d) {
57753 return "chip " + d.id + "-count";
57754 }).attr("href", "#").each(function(d) {
57755 var chipSelection = select_default2(this);
57756 var tooltipBehavior = uiTooltip().placement("top").title(() => _t.append(d.descriptionID));
57757 chipSelection.call(tooltipBehavior).on("click", function(d3_event) {
57758 d3_event.preventDefault();
57759 tooltipBehavior.hide(select_default2(this));
57760 context.ui().togglePanes(context.container().select(".map-panes .issues-pane"));
57762 chipSelection.call(svgIcon("#" + d.iconID));
57764 enter.append("span").attr("class", "count");
57765 enter.merge(chips).selectAll("span.count").text(function(d) {
57766 return d.count.toString();
57769 return function(selection2) {
57770 update(selection2);
57771 context.validator().on("validated.infobox", function() {
57772 update(selection2);
57777 // modules/ui/map_in_map.js
57778 function uiMapInMap(context) {
57779 function mapInMap(selection2) {
57780 var backgroundLayer = rendererTileLayer(context);
57781 var overlayLayers = {};
57782 var projection2 = geoRawMercator();
57783 var dataLayer = svgData(projection2, context).showLabels(false);
57784 var debugLayer = svgDebug(projection2, context);
57785 var zoom = zoom_default2().scaleExtent([geoZoomToScale(0.5), geoZoomToScale(24)]).on("start", zoomStarted).on("zoom", zoomed).on("end", zoomEnded);
57786 var wrap2 = select_default2(null);
57787 var tiles = select_default2(null);
57788 var viewport = select_default2(null);
57789 var _isTransformed = false;
57790 var _isHidden = true;
57791 var _skipEvents = false;
57792 var _gesture = null;
57799 function zoomStarted() {
57802 _tStart = _tCurr = projection2.transform();
57805 function zoomed(d3_event) {
57808 var x = d3_event.transform.x;
57809 var y = d3_event.transform.y;
57810 var k = d3_event.transform.k;
57811 var isZooming = k !== _tStart.k;
57812 var isPanning = x !== _tStart.x || y !== _tStart.y;
57813 if (!isZooming && !isPanning) {
57817 _gesture = isZooming ? "zoom" : "pan";
57819 var tMini = projection2.transform();
57821 if (_gesture === "zoom") {
57822 scale = k / tMini.k;
57823 tX = (_cMini[0] / scale - _cMini[0]) * scale;
57824 tY = (_cMini[1] / scale - _cMini[1]) * scale;
57831 utilSetTransform(tiles, tX, tY, scale);
57832 utilSetTransform(viewport, 0, 0, scale);
57833 _isTransformed = true;
57834 _tCurr = identity2.translate(x, y).scale(k);
57835 var zMain = geoScaleToZoom(context.projection.scale());
57836 var zMini = geoScaleToZoom(k);
57837 _zDiff = zMain - zMini;
57840 function zoomEnded() {
57843 if (_gesture !== "pan")
57845 updateProjection();
57847 context.map().center(projection2.invert(_cMini));
57849 function updateProjection() {
57850 var loc = context.map().center();
57851 var tMain = context.projection.transform();
57852 var zMain = geoScaleToZoom(tMain.k);
57853 var zMini = Math.max(zMain - _zDiff, 0.5);
57854 var kMini = geoZoomToScale(zMini);
57855 projection2.translate([tMain.x, tMain.y]).scale(kMini);
57856 var point2 = projection2(loc);
57857 var mouse = _gesture === "pan" ? geoVecSubtract([_tCurr.x, _tCurr.y], [_tStart.x, _tStart.y]) : [0, 0];
57858 var xMini = _cMini[0] - point2[0] + tMain.x + mouse[0];
57859 var yMini = _cMini[1] - point2[1] + tMain.y + mouse[1];
57860 projection2.translate([xMini, yMini]).clipExtent([[0, 0], _dMini]);
57861 _tCurr = projection2.transform();
57862 if (_isTransformed) {
57863 utilSetTransform(tiles, 0, 0);
57864 utilSetTransform(viewport, 0, 0);
57865 _isTransformed = false;
57867 zoom.scaleExtent([geoZoomToScale(0.5), geoZoomToScale(zMain - 3)]);
57868 _skipEvents = true;
57869 wrap2.call(zoom.transform, _tCurr);
57870 _skipEvents = false;
57872 function redraw() {
57873 clearTimeout(_timeoutID);
57876 updateProjection();
57877 var zMini = geoScaleToZoom(projection2.scale());
57878 tiles = wrap2.selectAll(".map-in-map-tiles").data([0]);
57879 tiles = tiles.enter().append("div").attr("class", "map-in-map-tiles").merge(tiles);
57880 backgroundLayer.source(context.background().baseLayerSource()).projection(projection2).dimensions(_dMini);
57881 var background = tiles.selectAll(".map-in-map-background").data([0]);
57882 background.enter().append("div").attr("class", "map-in-map-background").merge(background).call(backgroundLayer);
57883 var overlaySources = context.background().overlayLayerSources();
57884 var activeOverlayLayers = [];
57885 for (var i2 = 0; i2 < overlaySources.length; i2++) {
57886 if (overlaySources[i2].validZoom(zMini)) {
57887 if (!overlayLayers[i2])
57888 overlayLayers[i2] = rendererTileLayer(context);
57889 activeOverlayLayers.push(overlayLayers[i2].source(overlaySources[i2]).projection(projection2).dimensions(_dMini));
57892 var overlay = tiles.selectAll(".map-in-map-overlay").data([0]);
57893 overlay = overlay.enter().append("div").attr("class", "map-in-map-overlay").merge(overlay);
57894 var overlays = overlay.selectAll("div").data(activeOverlayLayers, function(d) {
57895 return d.source().name();
57897 overlays.exit().remove();
57898 overlays = overlays.enter().append("div").merge(overlays).each(function(layer) {
57899 select_default2(this).call(layer);
57901 var dataLayers = tiles.selectAll(".map-in-map-data").data([0]);
57902 dataLayers.exit().remove();
57903 dataLayers = dataLayers.enter().append("svg").attr("class", "map-in-map-data").merge(dataLayers).call(dataLayer).call(debugLayer);
57904 if (_gesture !== "pan") {
57905 var getPath = path_default(projection2);
57906 var bbox2 = { type: "Polygon", coordinates: [context.map().extent().polygon()] };
57907 viewport = wrap2.selectAll(".map-in-map-viewport").data([0]);
57908 viewport = viewport.enter().append("svg").attr("class", "map-in-map-viewport").merge(viewport);
57909 var path = viewport.selectAll(".map-in-map-bbox").data([bbox2]);
57910 path.enter().append("path").attr("class", "map-in-map-bbox").merge(path).attr("d", getPath).classed("thick", function(d) {
57911 return getPath.area(d) < 30;
57915 function queueRedraw() {
57916 clearTimeout(_timeoutID);
57917 _timeoutID = setTimeout(function() {
57921 function toggle(d3_event) {
57923 d3_event.preventDefault();
57924 _isHidden = !_isHidden;
57925 context.container().select(".minimap-toggle-item").classed("active", !_isHidden).select("input").property("checked", !_isHidden);
57927 wrap2.style("display", "block").style("opacity", "1").transition().duration(200).style("opacity", "0").on("end", function() {
57928 selection2.selectAll(".map-in-map").style("display", "none");
57931 wrap2.style("display", "block").style("opacity", "0").transition().duration(200).style("opacity", "1").on("end", function() {
57936 uiMapInMap.toggle = toggle;
57937 wrap2 = selection2.selectAll(".map-in-map").data([0]);
57938 wrap2 = wrap2.enter().append("div").attr("class", "map-in-map").style("display", _isHidden ? "none" : "block").call(zoom).on("dblclick.zoom", null).merge(wrap2);
57939 _dMini = [200, 150];
57940 _cMini = geoVecScale(_dMini, 0.5);
57941 context.map().on("drawn.map-in-map", function(drawn) {
57942 if (drawn.full === true) {
57947 context.keybinding().on(_t("background.minimap.key"), toggle);
57952 // modules/ui/notice.js
57953 function uiNotice(context) {
57954 return function(selection2) {
57955 var div = selection2.append("div").attr("class", "notice");
57956 var button = div.append("button").attr("class", "zoom-to notice fillD").on("click", function() {
57957 context.map().zoomEase(context.minEditableZoom());
57958 }).on("wheel", function(d3_event) {
57959 var e22 = new WheelEvent(d3_event.type, d3_event);
57960 context.surface().node().dispatchEvent(e22);
57962 button.call(svgIcon("#iD-icon-plus", "pre-text")).append("span").attr("class", "label").call(_t.append("zoom_in_edit"));
57963 function disableTooHigh() {
57964 var canEdit = context.map().zoom() >= context.minEditableZoom();
57965 div.style("display", canEdit ? "none" : "block");
57967 context.map().on("move.notice", debounce_default(disableTooHigh, 500));
57972 // modules/ui/photoviewer.js
57973 function uiPhotoviewer(context) {
57974 var dispatch10 = dispatch_default("resize");
57975 var _pointerPrefix = "PointerEvent" in window ? "pointer" : "mouse";
57976 function photoviewer(selection2) {
57977 selection2.append("button").attr("class", "thumb-hide").attr("title", _t("icons.close")).on("click", function() {
57978 if (services.streetside) {
57979 services.streetside.hideViewer(context);
57981 if (services.mapillary) {
57982 services.mapillary.hideViewer(context);
57984 if (services.kartaview) {
57985 services.kartaview.hideViewer(context);
57987 }).append("div").call(svgIcon("#iD-icon-close"));
57988 function preventDefault(d3_event) {
57989 d3_event.preventDefault();
57991 selection2.append("button").attr("class", "resize-handle-xy").on("touchstart touchdown touchend", preventDefault).on(
57992 _pointerPrefix + "down",
57993 buildResizeListener(selection2, "resize", dispatch10, { resizeOnX: true, resizeOnY: true })
57995 selection2.append("button").attr("class", "resize-handle-x").on("touchstart touchdown touchend", preventDefault).on(
57996 _pointerPrefix + "down",
57997 buildResizeListener(selection2, "resize", dispatch10, { resizeOnX: true })
57999 selection2.append("button").attr("class", "resize-handle-y").on("touchstart touchdown touchend", preventDefault).on(
58000 _pointerPrefix + "down",
58001 buildResizeListener(selection2, "resize", dispatch10, { resizeOnY: true })
58003 function buildResizeListener(target, eventName, dispatch11, options2) {
58004 var resizeOnX = !!options2.resizeOnX;
58005 var resizeOnY = !!options2.resizeOnY;
58006 var minHeight = options2.minHeight || 240;
58007 var minWidth = options2.minWidth || 320;
58013 function startResize(d3_event) {
58014 if (pointerId !== (d3_event.pointerId || "mouse"))
58016 d3_event.preventDefault();
58017 d3_event.stopPropagation();
58018 var mapSize = context.map().dimensions();
58020 var maxWidth = mapSize[0];
58021 var newWidth = clamp3(startWidth + d3_event.clientX - startX, minWidth, maxWidth);
58022 target.style("width", newWidth + "px");
58025 var maxHeight = mapSize[1] - 90;
58026 var newHeight = clamp3(startHeight + startY - d3_event.clientY, minHeight, maxHeight);
58027 target.style("height", newHeight + "px");
58029 dispatch11.call(eventName, target, utilGetDimensions(target, true));
58031 function clamp3(num, min3, max3) {
58032 return Math.max(min3, Math.min(num, max3));
58034 function stopResize(d3_event) {
58035 if (pointerId !== (d3_event.pointerId || "mouse"))
58037 d3_event.preventDefault();
58038 d3_event.stopPropagation();
58039 select_default2(window).on("." + eventName, null);
58041 return function initResize(d3_event) {
58042 d3_event.preventDefault();
58043 d3_event.stopPropagation();
58044 pointerId = d3_event.pointerId || "mouse";
58045 startX = d3_event.clientX;
58046 startY = d3_event.clientY;
58047 var targetRect = target.node().getBoundingClientRect();
58048 startWidth = targetRect.width;
58049 startHeight = targetRect.height;
58050 select_default2(window).on(_pointerPrefix + "move." + eventName, startResize, false).on(_pointerPrefix + "up." + eventName, stopResize, false);
58051 if (_pointerPrefix === "pointer") {
58052 select_default2(window).on("pointercancel." + eventName, stopResize, false);
58057 photoviewer.onMapResize = function() {
58058 var photoviewer2 = context.container().select(".photoviewer");
58059 var content = context.container().select(".main-content");
58060 var mapDimensions = utilGetDimensions(content, true);
58061 var photoDimensions = utilGetDimensions(photoviewer2, true);
58062 if (photoDimensions[0] > mapDimensions[0] || photoDimensions[1] > mapDimensions[1] - 90) {
58063 var setPhotoDimensions = [
58064 Math.min(photoDimensions[0], mapDimensions[0]),
58065 Math.min(photoDimensions[1], mapDimensions[1] - 90)
58067 photoviewer2.style("width", setPhotoDimensions[0] + "px").style("height", setPhotoDimensions[1] + "px");
58068 dispatch10.call("resize", photoviewer2, setPhotoDimensions);
58071 return utilRebind(photoviewer, dispatch10, "on");
58074 // modules/ui/restore.js
58075 function uiRestore(context) {
58076 return function(selection2) {
58077 if (!context.history().hasRestorableChanges())
58079 let modalSelection = uiModal(selection2, true);
58080 modalSelection.select(".modal").attr("class", "modal fillL");
58081 let introModal = modalSelection.select(".content");
58082 introModal.append("div").attr("class", "modal-section").append("h3").call(_t.append("restore.heading"));
58083 introModal.append("div").attr("class", "modal-section").append("p").call(_t.append("restore.description"));
58084 let buttonWrap = introModal.append("div").attr("class", "modal-actions");
58085 let restore = buttonWrap.append("button").attr("class", "restore").on("click", () => {
58086 context.history().restore();
58087 modalSelection.remove();
58089 restore.append("svg").attr("class", "logo logo-restore").append("use").attr("xlink:href", "#iD-logo-restore");
58090 restore.append("div").call(_t.append("restore.restore"));
58091 let reset = buttonWrap.append("button").attr("class", "reset").on("click", () => {
58092 context.history().clearSaved();
58093 modalSelection.remove();
58095 reset.append("svg").attr("class", "logo logo-reset").append("use").attr("xlink:href", "#iD-logo-reset");
58096 reset.append("div").call(_t.append("restore.reset"));
58097 restore.node().focus();
58101 // modules/ui/scale.js
58102 function uiScale(context) {
58103 var projection2 = context.projection, isImperial = !_mainLocalizer.usesMetric(), maxLength = 180, tickHeight = 8;
58104 function scaleDefs(loc1, loc2) {
58105 var lat = (loc2[1] + loc1[1]) / 2, conversion = isImperial ? 3.28084 : 1, dist = geoLonToMeters(loc2[0] - loc1[0], lat) * conversion, scale = { dist: 0, px: 0, text: "" }, buckets, i2, val, dLon;
58107 buckets = [528e4, 528e3, 52800, 5280, 500, 50, 5, 1];
58109 buckets = [5e6, 5e5, 5e4, 5e3, 500, 50, 5, 1];
58111 for (i2 = 0; i2 < buckets.length; i2++) {
58114 scale.dist = Math.floor(dist / val) * val;
58117 scale.dist = +dist.toFixed(2);
58120 dLon = geoMetersToLon(scale.dist / conversion, lat);
58121 scale.px = Math.round(projection2([loc1[0] + dLon, loc1[1]])[0]);
58122 scale.text = displayLength(scale.dist / conversion, isImperial);
58125 function update(selection2) {
58126 var dims = context.map().dimensions(), loc1 = projection2.invert([0, dims[1]]), loc2 = projection2.invert([maxLength, dims[1]]), scale = scaleDefs(loc1, loc2);
58127 selection2.select(".scale-path").attr("d", "M0.5,0.5v" + tickHeight + "h" + scale.px + "v-" + tickHeight);
58128 selection2.select(".scale-text").style(_mainLocalizer.textDirection() === "ltr" ? "left" : "right", scale.px + 16 + "px").text(scale.text);
58130 return function(selection2) {
58131 function switchUnits() {
58132 isImperial = !isImperial;
58133 selection2.call(update);
58135 var scalegroup = selection2.append("svg").attr("class", "scale").on("click", switchUnits).append("g").attr("transform", "translate(10,11)");
58136 scalegroup.append("path").attr("class", "scale-path");
58137 selection2.append("div").attr("class", "scale-text");
58138 selection2.call(update);
58139 context.map().on("move.scale", function() {
58140 update(selection2);
58145 // modules/ui/shortcuts.js
58146 function uiShortcuts(context) {
58147 var detected = utilDetect();
58148 var _activeTab = 0;
58149 var _modalSelection;
58150 var _selection = select_default2(null);
58151 var _dataShortcuts;
58152 function shortcutsModal(_modalSelection2) {
58153 _modalSelection2.select(".modal").classed("modal-shortcuts", true);
58154 var content = _modalSelection2.select(".content");
58155 content.append("div").attr("class", "modal-section header").append("h2").call(_t.append("shortcuts.title"));
58156 _mainFileFetcher.get("shortcuts").then(function(data) {
58157 _dataShortcuts = data;
58158 content.call(render);
58159 }).catch(function() {
58162 function render(selection2) {
58163 if (!_dataShortcuts)
58165 var wrapper = selection2.selectAll(".wrapper").data([0]);
58166 var wrapperEnter = wrapper.enter().append("div").attr("class", "wrapper modal-section");
58167 var tabsBar = wrapperEnter.append("div").attr("class", "tabs-bar");
58168 var shortcutsList = wrapperEnter.append("div").attr("class", "shortcuts-list");
58169 wrapper = wrapper.merge(wrapperEnter);
58170 var tabs = tabsBar.selectAll(".tab").data(_dataShortcuts);
58171 var tabsEnter = tabs.enter().append("a").attr("class", "tab").attr("href", "#").on("click", function(d3_event, d) {
58172 d3_event.preventDefault();
58173 var i2 = _dataShortcuts.indexOf(d);
58175 render(selection2);
58177 tabsEnter.append("span").html(function(d) {
58178 return _t.html(d.text);
58180 wrapper.selectAll(".tab").classed("active", function(d, i2) {
58181 return i2 === _activeTab;
58183 var shortcuts = shortcutsList.selectAll(".shortcut-tab").data(_dataShortcuts);
58184 var shortcutsEnter = shortcuts.enter().append("div").attr("class", function(d) {
58185 return "shortcut-tab shortcut-tab-" + d.tab;
58187 var columnsEnter = shortcutsEnter.selectAll(".shortcut-column").data(function(d) {
58189 }).enter().append("table").attr("class", "shortcut-column");
58190 var rowsEnter = columnsEnter.selectAll(".shortcut-row").data(function(d) {
58192 }).enter().append("tr").attr("class", "shortcut-row");
58193 var sectionRows = rowsEnter.filter(function(d) {
58194 return !d.shortcuts;
58196 sectionRows.append("td");
58197 sectionRows.append("td").attr("class", "shortcut-section").append("h3").html(function(d) {
58198 return _t.html(d.text);
58200 var shortcutRows = rowsEnter.filter(function(d) {
58201 return d.shortcuts;
58203 var shortcutKeys = shortcutRows.append("td").attr("class", "shortcut-keys");
58204 var modifierKeys = shortcutKeys.filter(function(d) {
58205 return d.modifiers;
58207 modifierKeys.selectAll("kbd.modifier").data(function(d) {
58208 if (detected.os === "win" && d.text === "shortcuts.editing.commands.redo") {
58210 } else if (detected.os !== "mac" && d.text === "shortcuts.browsing.display_options.fullscreen") {
58213 return d.modifiers;
58215 }).enter().each(function() {
58216 var selection3 = select_default2(this);
58217 selection3.append("kbd").attr("class", "modifier").text(function(d) {
58218 return uiCmd.display(d);
58220 selection3.append("span").text("+");
58222 shortcutKeys.selectAll("kbd.shortcut").data(function(d) {
58223 var arr = d.shortcuts;
58224 if (detected.os === "win" && d.text === "shortcuts.editing.commands.redo") {
58226 } else if (detected.os !== "mac" && d.text === "shortcuts.browsing.display_options.fullscreen") {
58229 arr = arr.map(function(s) {
58230 return uiCmd.display(s.indexOf(".") !== -1 ? _t(s) : s);
58232 return utilArrayUniq(arr).map(function(s) {
58235 separator: d.separator,
58239 }).enter().each(function(d, i2, nodes) {
58240 var selection3 = select_default2(this);
58241 var click = d.shortcut.toLowerCase().match(/(.*).click/);
58242 if (click && click[1]) {
58243 selection3.call(svgIcon("#iD-walkthrough-mouse-" + click[1], "operation"));
58244 } else if (d.shortcut.toLowerCase() === "long-press") {
58245 selection3.call(svgIcon("#iD-walkthrough-longpress", "longpress operation"));
58246 } else if (d.shortcut.toLowerCase() === "tap") {
58247 selection3.call(svgIcon("#iD-walkthrough-tap", "tap operation"));
58249 selection3.append("kbd").attr("class", "shortcut").text(function(d2) {
58250 return d2.shortcut;
58253 if (i2 < nodes.length - 1) {
58254 selection3.append("span").html(d.separator || "\xA0" + _t.html("shortcuts.or") + "\xA0");
58255 } else if (i2 === nodes.length - 1 && d.suffix) {
58256 selection3.append("span").text(d.suffix);
58259 shortcutKeys.filter(function(d) {
58261 }).each(function() {
58262 var selection3 = select_default2(this);
58263 selection3.append("span").text("+");
58264 selection3.append("span").attr("class", "gesture").html(function(d) {
58265 return _t.html(d.gesture);
58268 shortcutRows.append("td").attr("class", "shortcut-desc").html(function(d) {
58269 return d.text ? _t.html(d.text) : "\xA0";
58271 wrapper.selectAll(".shortcut-tab").style("display", function(d, i2) {
58272 return i2 === _activeTab ? "flex" : "none";
58275 return function(selection2, show) {
58276 _selection = selection2;
58278 _modalSelection = uiModal(selection2);
58279 _modalSelection.call(shortcutsModal);
58281 context.keybinding().on([_t("shortcuts.toggle.key"), "?"], function() {
58282 if (context.container().selectAll(".modal-shortcuts").size()) {
58283 if (_modalSelection) {
58284 _modalSelection.close();
58285 _modalSelection = null;
58288 _modalSelection = uiModal(_selection);
58289 _modalSelection.call(shortcutsModal);
58296 // modules/ui/data_header.js
58297 function uiDataHeader() {
58299 function dataHeader(selection2) {
58300 var header = selection2.selectAll(".data-header").data(
58301 _datum ? [_datum] : [],
58303 return d.__featurehash__;
58306 header.exit().remove();
58307 var headerEnter = header.enter().append("div").attr("class", "data-header");
58308 var iconEnter = headerEnter.append("div").attr("class", "data-header-icon");
58309 iconEnter.append("div").attr("class", "preset-icon-28").call(svgIcon("#iD-icon-data", "note-fill"));
58310 headerEnter.append("div").attr("class", "data-header-label").call(_t.append("map_data.layers.custom.title"));
58312 dataHeader.datum = function(val) {
58313 if (!arguments.length)
58321 // modules/ui/combobox.js
58322 var _comboHideTimerID;
58323 function uiCombobox(context, klass) {
58324 var dispatch10 = dispatch_default("accept", "cancel", "update");
58325 var container = context.container();
58326 var _suggestions = [];
58329 var _selected = null;
58330 var _canAutocomplete = true;
58331 var _caseSensitive = false;
58332 var _cancelFetch = false;
58335 var _mouseEnterHandler, _mouseLeaveHandler;
58336 var _fetcher = function(val, cb) {
58337 cb(_data.filter(function(d) {
58338 var terms = d.terms || [];
58339 terms.push(d.value);
58343 return terms.some(function(term) {
58344 return term.toString().toLowerCase().indexOf(val.toLowerCase()) !== -1;
58348 var combobox = function(input, attachTo) {
58349 if (!input || input.empty())
58351 input.classed("combobox-input", true).on("focus.combo-input", focus).on("blur.combo-input", blur).on("keydown.combo-input", keydown).on("keyup.combo-input", keyup).on("input.combo-input", change).on("mousedown.combo-input", mousedown).each(function() {
58352 var parent = this.parentNode;
58353 var sibling = this.nextSibling;
58354 select_default2(parent).selectAll(".combobox-caret").filter(function(d) {
58355 return d === input.node();
58356 }).data([input.node()]).enter().insert("div", function() {
58358 }).attr("class", "combobox-caret").on("mousedown.combo-caret", function(d3_event) {
58359 d3_event.preventDefault();
58360 input.node().focus();
58361 mousedown(d3_event);
58362 }).on("mouseup.combo-caret", function(d3_event) {
58363 d3_event.preventDefault();
58367 function mousedown(d3_event) {
58368 if (d3_event.button !== 0)
58370 if (input.classed("disabled"))
58372 _tDown = +/* @__PURE__ */ new Date();
58373 var start2 = input.property("selectionStart");
58374 var end = input.property("selectionEnd");
58375 if (start2 !== end) {
58376 var val = utilGetSetValue(input);
58377 input.node().setSelectionRange(val.length, val.length);
58380 input.on("mouseup.combo-input", mouseup);
58382 function mouseup(d3_event) {
58383 input.on("mouseup.combo-input", null);
58384 if (d3_event.button !== 0)
58386 if (input.classed("disabled"))
58388 if (input.node() !== document.activeElement)
58390 var start2 = input.property("selectionStart");
58391 var end = input.property("selectionEnd");
58392 if (start2 !== end)
58394 var combo = container.selectAll(".combobox");
58395 if (combo.empty() || combo.datum() !== input.node()) {
58396 var tOrig = _tDown;
58397 window.setTimeout(function() {
58398 if (tOrig !== _tDown)
58400 fetchComboData("", function() {
58410 fetchComboData("");
58413 _comboHideTimerID = window.setTimeout(hide, 75);
58417 container.insert("div", ":first-child").datum(input.node()).attr("class", "combobox" + (klass ? " combobox-" + klass : "")).style("position", "absolute").style("display", "block").style("left", "0px").on("mousedown.combo-container", function(d3_event) {
58418 d3_event.preventDefault();
58420 container.on("scroll.combo-scroll", render, true);
58423 if (_comboHideTimerID) {
58424 window.clearTimeout(_comboHideTimerID);
58425 _comboHideTimerID = void 0;
58427 container.selectAll(".combobox").remove();
58428 container.on("scroll.combo-scroll", null);
58430 function keydown(d3_event) {
58431 var shown = !container.selectAll(".combobox").empty();
58432 var tagName = input.node() ? input.node().tagName.toLowerCase() : "";
58433 switch (d3_event.keyCode) {
58436 d3_event.stopPropagation();
58439 input.on("input.combo-input", function() {
58440 var start2 = input.property("selectionStart");
58441 input.node().setSelectionRange(start2, start2);
58442 input.on("input.combo-input", change);
58450 d3_event.preventDefault();
58451 d3_event.stopPropagation();
58455 if (tagName === "textarea" && !shown)
58457 d3_event.preventDefault();
58458 if (tagName === "input" && !shown) {
58464 if (tagName === "textarea" && !shown)
58466 d3_event.preventDefault();
58467 if (tagName === "input" && !shown) {
58474 function keyup(d3_event) {
58475 switch (d3_event.keyCode) {
58481 function change(doAutoComplete) {
58482 if (doAutoComplete === void 0)
58483 doAutoComplete = true;
58484 fetchComboData(value(), function() {
58486 var val = input.property("value");
58487 if (_suggestions.length) {
58488 if (doAutoComplete && input.property("selectionEnd") === val.length) {
58489 _selected = tryAutocomplete();
58496 var combo = container.selectAll(".combobox");
58497 if (combo.empty()) {
58506 function nav(dir) {
58507 if (_suggestions.length) {
58509 for (var i2 = 0; i2 < _suggestions.length; i2++) {
58510 if (_selected && _suggestions[i2].value === _selected) {
58515 index = Math.max(Math.min(index + dir, _suggestions.length - 1), 0);
58516 _selected = _suggestions[index].value;
58517 utilGetSetValue(input, _selected);
58518 dispatch10.call("update");
58523 function ensureVisible() {
58524 var combo = container.selectAll(".combobox");
58527 var containerRect = container.node().getBoundingClientRect();
58528 var comboRect = combo.node().getBoundingClientRect();
58529 if (comboRect.bottom > containerRect.bottom) {
58530 var node = attachTo ? attachTo.node() : input.node();
58531 node.scrollIntoView({ behavior: "instant", block: "center" });
58534 var selected = combo.selectAll(".combobox-option.selected").node();
58536 selected.scrollIntoView({ behavior: "smooth", block: "nearest" });
58540 var value2 = input.property("value");
58541 var start2 = input.property("selectionStart");
58542 var end = input.property("selectionEnd");
58543 if (start2 && end) {
58544 value2 = value2.substring(0, start2);
58548 function fetchComboData(v, cb) {
58549 _cancelFetch = false;
58550 _fetcher.call(input, v, function(results) {
58553 _suggestions = results;
58554 results.forEach(function(d) {
58555 _fetched[d.value] = d;
58562 function tryAutocomplete() {
58563 if (!_canAutocomplete)
58565 var val = _caseSensitive ? value() : value().toLowerCase();
58570 const suggestionValues = [];
58571 _suggestions.forEach((s) => {
58572 suggestionValues.push(s.value);
58573 if (s.key && s.key !== s.value) {
58574 suggestionValues.push(s.key);
58577 var bestIndex = -1;
58578 for (var i2 = 0; i2 < suggestionValues.length; i2++) {
58579 var suggestion = suggestionValues[i2];
58580 var compare = _caseSensitive ? suggestion : suggestion.toLowerCase();
58581 if (compare === val) {
58584 } else if (bestIndex === -1 && compare.indexOf(val) === 0) {
58588 if (bestIndex !== -1) {
58589 var bestVal = suggestionValues[bestIndex];
58590 input.property("value", bestVal);
58591 input.node().setSelectionRange(val.length, bestVal.length);
58592 dispatch10.call("update");
58596 function render() {
58597 if (_suggestions.length < _minItems || document.activeElement !== input.node()) {
58601 var shown = !container.selectAll(".combobox").empty();
58604 var combo = container.selectAll(".combobox");
58605 var options2 = combo.selectAll(".combobox-option").data(_suggestions, function(d) {
58608 options2.exit().remove();
58609 options2.enter().append("a").attr("class", function(d) {
58610 return "combobox-option " + (d.klass || "");
58611 }).attr("title", function(d) {
58613 }).each(function(d) {
58615 d.display(select_default2(this));
58617 select_default2(this).text(d.value);
58619 }).on("mouseenter", _mouseEnterHandler).on("mouseleave", _mouseLeaveHandler).merge(options2).classed("selected", function(d) {
58620 return d.value === _selected || d.key === _selected;
58621 }).on("click.combo-option", accept).order();
58622 var node = attachTo ? attachTo.node() : input.node();
58623 var containerRect = container.node().getBoundingClientRect();
58624 var rect = node.getBoundingClientRect();
58625 combo.style("left", rect.left + 5 - containerRect.left + "px").style("width", rect.width - 10 + "px").style("top", rect.height + rect.top - containerRect.top + "px");
58627 function accept(d3_event, d) {
58628 _cancelFetch = true;
58629 var thiz = input.node();
58631 utilGetSetValue(input, d.value);
58632 utilTriggerEvent(input, "change");
58634 var val = utilGetSetValue(input);
58635 thiz.setSelectionRange(val.length, val.length);
58637 dispatch10.call("accept", thiz, d, val);
58640 function cancel() {
58641 _cancelFetch = true;
58642 var thiz = input.node();
58643 var val = utilGetSetValue(input);
58644 var start2 = input.property("selectionStart");
58645 var end = input.property("selectionEnd");
58646 val = val.slice(0, start2) + val.slice(end);
58647 utilGetSetValue(input, val);
58648 thiz.setSelectionRange(val.length, val.length);
58649 dispatch10.call("cancel", thiz);
58653 combobox.canAutocomplete = function(val) {
58654 if (!arguments.length)
58655 return _canAutocomplete;
58656 _canAutocomplete = val;
58659 combobox.caseSensitive = function(val) {
58660 if (!arguments.length)
58661 return _caseSensitive;
58662 _caseSensitive = val;
58665 combobox.data = function(val) {
58666 if (!arguments.length)
58671 combobox.fetcher = function(val) {
58672 if (!arguments.length)
58677 combobox.minItems = function(val) {
58678 if (!arguments.length)
58683 combobox.itemsMouseEnter = function(val) {
58684 if (!arguments.length)
58685 return _mouseEnterHandler;
58686 _mouseEnterHandler = val;
58689 combobox.itemsMouseLeave = function(val) {
58690 if (!arguments.length)
58691 return _mouseLeaveHandler;
58692 _mouseLeaveHandler = val;
58695 return utilRebind(combobox, dispatch10, "on");
58697 uiCombobox.off = function(input, context) {
58698 input.on("focus.combo-input", null).on("blur.combo-input", null).on("keydown.combo-input", null).on("keyup.combo-input", null).on("input.combo-input", null).on("mousedown.combo-input", null).on("mouseup.combo-input", null);
58699 context.container().on("scroll.combo-scroll", null);
58702 // modules/ui/disclosure.js
58703 function uiDisclosure(context, key, expandedDefault) {
58704 var dispatch10 = dispatch_default("toggled");
58706 var _label = utilFunctor("");
58707 var _updatePreference = true;
58708 var _content = function() {
58710 var disclosure = function(selection2) {
58711 if (_expanded === void 0 || _expanded === null) {
58712 var preference = corePreferences("disclosure." + key + ".expanded");
58713 _expanded = preference === null ? !!expandedDefault : preference === "true";
58715 var hideToggle = selection2.selectAll(".hide-toggle-" + key).data([0]);
58716 var hideToggleEnter = hideToggle.enter().append("h3").append("a").attr("role", "button").attr("href", "#").attr("class", "hide-toggle hide-toggle-" + key).call(svgIcon("", "pre-text", "hide-toggle-icon"));
58717 hideToggleEnter.append("span").attr("class", "hide-toggle-text");
58718 hideToggle = hideToggleEnter.merge(hideToggle);
58719 hideToggle.on("click", toggle).attr("title", _t(`icons.${_expanded ? "collapse" : "expand"}`)).attr("aria-expanded", _expanded).classed("expanded", _expanded);
58720 const label = _label();
58721 const labelSelection = hideToggle.selectAll(".hide-toggle-text");
58722 if (typeof label !== "function") {
58723 labelSelection.text(_label());
58725 labelSelection.text("").call(label);
58727 hideToggle.selectAll(".hide-toggle-icon").attr(
58729 _expanded ? "#iD-icon-down" : _mainLocalizer.textDirection() === "rtl" ? "#iD-icon-backward" : "#iD-icon-forward"
58731 var wrap2 = selection2.selectAll(".disclosure-wrap").data([0]);
58732 wrap2 = wrap2.enter().append("div").attr("class", "disclosure-wrap disclosure-wrap-" + key).merge(wrap2).classed("hide", !_expanded);
58734 wrap2.call(_content);
58736 function toggle(d3_event) {
58737 d3_event.preventDefault();
58738 _expanded = !_expanded;
58739 if (_updatePreference) {
58740 corePreferences("disclosure." + key + ".expanded", _expanded);
58742 hideToggle.classed("expanded", _expanded).attr("aria-expanded", _expanded).attr("title", _t(`icons.${_expanded ? "collapse" : "expand"}`));
58743 hideToggle.selectAll(".hide-toggle-icon").attr(
58745 _expanded ? "#iD-icon-down" : _mainLocalizer.textDirection() === "rtl" ? "#iD-icon-backward" : "#iD-icon-forward"
58747 wrap2.call(uiToggle(_expanded));
58749 wrap2.call(_content);
58751 dispatch10.call("toggled", this, _expanded);
58754 disclosure.label = function(val) {
58755 if (!arguments.length)
58757 _label = utilFunctor(val);
58760 disclosure.expanded = function(val) {
58761 if (!arguments.length)
58766 disclosure.updatePreference = function(val) {
58767 if (!arguments.length)
58768 return _updatePreference;
58769 _updatePreference = val;
58772 disclosure.content = function(val) {
58773 if (!arguments.length)
58778 return utilRebind(disclosure, dispatch10, "on");
58781 // modules/ui/section.js
58782 function uiSection(id2, context) {
58783 var _classes = utilFunctor("");
58784 var _shouldDisplay;
58788 var _expandedByDefault = utilFunctor(true);
58789 var _disclosureContent;
58790 var _disclosureExpanded;
58791 var _containerSelection = select_default2(null);
58795 section.classes = function(val) {
58796 if (!arguments.length)
58798 _classes = utilFunctor(val);
58801 section.label = function(val) {
58802 if (!arguments.length)
58804 _label = utilFunctor(val);
58807 section.expandedByDefault = function(val) {
58808 if (!arguments.length)
58809 return _expandedByDefault;
58810 _expandedByDefault = utilFunctor(val);
58813 section.shouldDisplay = function(val) {
58814 if (!arguments.length)
58815 return _shouldDisplay;
58816 _shouldDisplay = utilFunctor(val);
58819 section.content = function(val) {
58820 if (!arguments.length)
58825 section.disclosureContent = function(val) {
58826 if (!arguments.length)
58827 return _disclosureContent;
58828 _disclosureContent = val;
58831 section.disclosureExpanded = function(val) {
58832 if (!arguments.length)
58833 return _disclosureExpanded;
58834 _disclosureExpanded = val;
58837 section.render = function(selection2) {
58838 _containerSelection = selection2.selectAll(".section-" + id2).data([0]);
58839 var sectionEnter = _containerSelection.enter().append("div").attr("class", "section section-" + id2 + " " + (_classes && _classes() || ""));
58840 _containerSelection = sectionEnter.merge(_containerSelection);
58841 _containerSelection.call(renderContent);
58843 section.reRender = function() {
58844 _containerSelection.call(renderContent);
58846 section.selection = function() {
58847 return _containerSelection;
58849 section.disclosure = function() {
58850 return _disclosure;
58852 function renderContent(selection2) {
58853 if (_shouldDisplay) {
58854 var shouldDisplay = _shouldDisplay();
58855 selection2.classed("hide", !shouldDisplay);
58856 if (!shouldDisplay) {
58857 selection2.html("");
58861 if (_disclosureContent) {
58862 if (!_disclosure) {
58863 _disclosure = uiDisclosure(context, id2.replace(/-/g, "_"), _expandedByDefault()).label(_label || "").content(_disclosureContent);
58865 if (_disclosureExpanded !== void 0) {
58866 _disclosure.expanded(_disclosureExpanded);
58867 _disclosureExpanded = void 0;
58869 selection2.call(_disclosure);
58873 selection2.call(_content);
58879 // modules/ui/tag_reference.js
58880 function uiTagReference(what) {
58881 var wikibase = what.qid ? services.wikidata : services.osmWikibase;
58882 var tagReference = {};
58883 var _button = select_default2(null);
58884 var _body = select_default2(null);
58890 _button.classed("tag-reference-loading", true);
58891 wikibase.getDocs(what, gotDocs);
58893 function gotDocs(err, docs) {
58895 if (!docs || !docs.title) {
58896 _body.append("p").attr("class", "tag-reference-description").call(_t.append("inspector.no_documentation_key"));
58900 if (docs.imageURL) {
58901 _body.append("img").attr("class", "tag-reference-wiki-image").attr("alt", docs.description).attr("src", docs.imageURL).on("load", function() {
58903 }).on("error", function() {
58904 select_default2(this).remove();
58910 var tagReferenceDescription = _body.append("p").attr("class", "tag-reference-description").append("span");
58911 if (docs.description) {
58912 tagReferenceDescription = tagReferenceDescription.attr("class", "localized-text").attr("lang", docs.descriptionLocaleCode || "und").text(docs.description);
58914 tagReferenceDescription = tagReferenceDescription.call(_t.append("inspector.no_documentation_key"));
58916 tagReferenceDescription.append("a").attr("class", "tag-reference-edit").attr("target", "_blank").attr("title", _t("inspector.edit_reference")).attr("href", docs.editURL).call(svgIcon("#iD-icon-edit", "inline"));
58918 _body.append("a").attr("class", "tag-reference-link").attr("target", "_blank").attr("href", docs.wiki.url).call(svgIcon("#iD-icon-out-link", "inline")).append("span").call(_t.append(docs.wiki.text));
58920 if (what.key === "comment") {
58921 _body.append("a").attr("class", "tag-reference-comment-link").attr("target", "_blank").call(svgIcon("#iD-icon-out-link", "inline")).attr("href", _t("commit.about_changeset_comments_link")).append("span").call(_t.append("commit.about_changeset_comments"));
58926 _button.classed("tag-reference-loading", false);
58927 _body.classed("expanded", true).transition().duration(200).style("max-height", "200px").style("opacity", "1");
58929 _button.selectAll("svg.icon use").each(function() {
58930 var iconUse = select_default2(this);
58931 if (iconUse.attr("href") === "#iD-icon-info") {
58932 iconUse.attr("href", "#iD-icon-info-filled");
58937 _body.transition().duration(200).style("max-height", "0px").style("opacity", "0").on("end", function() {
58938 _body.classed("expanded", false);
58941 _button.selectAll("svg.icon use").each(function() {
58942 var iconUse = select_default2(this);
58943 if (iconUse.attr("href") === "#iD-icon-info-filled") {
58944 iconUse.attr("href", "#iD-icon-info");
58948 tagReference.button = function(selection2, klass, iconName) {
58949 _button = selection2.selectAll(".tag-reference-button").data([0]);
58950 _button = _button.enter().append("button").attr("class", "tag-reference-button " + (klass || "")).attr("title", _t("icons.information")).call(svgIcon("#iD-icon-" + (iconName || "inspect"))).merge(_button);
58951 _button.on("click", function(d3_event) {
58952 d3_event.stopPropagation();
58953 d3_event.preventDefault();
58957 } else if (_loaded) {
58964 tagReference.body = function(selection2) {
58965 var itemID = what.qid || what.key + "-" + (what.value || "");
58966 _body = selection2.selectAll(".tag-reference-body").data([itemID], function(d) {
58969 _body.exit().remove();
58970 _body = _body.enter().append("div").attr("class", "tag-reference-body").style("max-height", "0").style("opacity", "0").merge(_body);
58971 if (_showing === false) {
58975 tagReference.showing = function(val) {
58976 if (!arguments.length)
58979 return tagReference;
58981 return tagReference;
58984 // modules/ui/field_help.js
58985 function uiFieldHelp(context, fieldName) {
58986 var fieldHelp = {};
58987 var _inspector = select_default2(null);
58988 var _wrap = select_default2(null);
58989 var _body = select_default2(null);
58990 var fieldHelpKeys = {
59018 "indirect_example",
59023 var fieldHelpHeadings = {};
59024 var replacements = {
59025 distField: { html: _t.html("restriction.controls.distance") },
59026 viaField: { html: _t.html("restriction.controls.via") },
59027 fromShadow: { html: icon("#iD-turn-shadow", "inline shadow from") },
59028 allowShadow: { html: icon("#iD-turn-shadow", "inline shadow allow") },
59029 restrictShadow: { html: icon("#iD-turn-shadow", "inline shadow restrict") },
59030 onlyShadow: { html: icon("#iD-turn-shadow", "inline shadow only") },
59031 allowTurn: { html: icon("#iD-turn-yes", "inline turn") },
59032 restrictTurn: { html: icon("#iD-turn-no", "inline turn") },
59033 onlyTurn: { html: icon("#iD-turn-only", "inline turn") }
59035 var docs = fieldHelpKeys[fieldName].map(function(key) {
59036 var helpkey = "help.field." + fieldName + "." + key[0];
59037 var text2 = key[1].reduce(function(all, part) {
59038 var subkey = helpkey + "." + part;
59039 var depth = fieldHelpHeadings[subkey];
59040 var hhh = depth ? Array(depth + 1).join("#") + " " : "";
59041 return all + hhh + _t.html(subkey, replacements) + "\n\n";
59045 title: _t.html(helpkey + ".title"),
59046 html: marked(text2.trim())
59051 _body.classed("hide", false).style("opacity", "0").transition().duration(200).style("opacity", "1");
59054 _body.classed("hide", true).transition().duration(200).style("opacity", "0").on("end", function() {
59055 _body.classed("hide", true);
59058 function clickHelp(index) {
59059 var d = docs[index];
59060 var tkeys = fieldHelpKeys[fieldName][index][1];
59061 _body.selectAll(".field-help-nav-item").classed("active", function(d2, i2) {
59062 return i2 === index;
59064 var content = _body.selectAll(".field-help-content").html(d.html);
59065 content.selectAll("p").attr("class", function(d2, i2) {
59068 if (d.key === "help.field.restrictions.inspecting") {
59069 content.insert("img", "p.from_shadow").attr("class", "field-help-image cf").attr("src", context.imagePath("tr_inspect.gif"));
59070 } else if (d.key === "help.field.restrictions.modifying") {
59071 content.insert("img", "p.allow_turn").attr("class", "field-help-image cf").attr("src", context.imagePath("tr_modify.gif"));
59074 fieldHelp.button = function(selection2) {
59077 var button = selection2.selectAll(".field-help-button").data([0]);
59078 button.enter().append("button").attr("class", "field-help-button").call(svgIcon("#iD-icon-help")).merge(button).on("click", function(d3_event) {
59079 d3_event.stopPropagation();
59080 d3_event.preventDefault();
59081 if (_body.classed("hide")) {
59088 function updatePosition() {
59089 var wrap2 = _wrap.node();
59090 var inspector = _inspector.node();
59091 var wRect = wrap2.getBoundingClientRect();
59092 var iRect = inspector.getBoundingClientRect();
59093 _body.style("top", wRect.top + inspector.scrollTop - iRect.top + "px");
59095 fieldHelp.body = function(selection2) {
59096 _wrap = selection2.selectAll(".form-field-input-wrap");
59099 _inspector = context.container().select(".sidebar .entity-editor-pane .inspector-body");
59100 if (_inspector.empty())
59102 _body = _inspector.selectAll(".field-help-body").data([0]);
59103 var enter = _body.enter().append("div").attr("class", "field-help-body hide");
59104 var titleEnter = enter.append("div").attr("class", "field-help-title cf");
59105 titleEnter.append("h2").attr("class", _mainLocalizer.textDirection() === "rtl" ? "fr" : "fl").call(_t.append("help.field." + fieldName + ".title"));
59106 titleEnter.append("button").attr("class", "fr close").attr("title", _t("icons.close")).on("click", function(d3_event) {
59107 d3_event.stopPropagation();
59108 d3_event.preventDefault();
59110 }).call(svgIcon("#iD-icon-close"));
59111 var navEnter = enter.append("div").attr("class", "field-help-nav cf");
59112 var titles = docs.map(function(d) {
59115 navEnter.selectAll(".field-help-nav-item").data(titles).enter().append("div").attr("class", "field-help-nav-item").html(function(d) {
59117 }).on("click", function(d3_event, d) {
59118 d3_event.stopPropagation();
59119 d3_event.preventDefault();
59120 clickHelp(titles.indexOf(d));
59122 enter.append("div").attr("class", "field-help-content");
59123 _body = _body.merge(enter);
59129 // modules/ui/fields/check.js
59130 function uiFieldCheck(field, context) {
59131 var dispatch10 = dispatch_default("change");
59132 var options2 = field.options;
59136 var input = select_default2(null);
59137 var text2 = select_default2(null);
59138 var label = select_default2(null);
59139 var reverser = select_default2(null);
59141 var _entityIDs = [];
59143 var stringsField = field.resolveReference("stringsCrossReference");
59144 if (!options2 && stringsField.options) {
59145 options2 = stringsField.options;
59148 for (var i2 in options2) {
59149 var v = options2[i2];
59150 values.push(v === "undefined" ? void 0 : v);
59151 texts.push(stringsField.t.html("options." + v, { "default": v }));
59154 values = [void 0, "yes"];
59155 texts = [_t.html("inspector.unknown"), _t.html("inspector.check.yes")];
59156 if (field.type !== "defaultCheck") {
59158 texts.push(_t.html("inspector.check.no"));
59161 function checkImpliedYes() {
59162 _impliedYes = field.id === "oneway_yes";
59163 if (field.id === "oneway") {
59164 var entity = context.entity(_entityIDs[0]);
59165 for (var key in entity.tags) {
59166 if (key in osmOneWayTags && entity.tags[key] in osmOneWayTags[key]) {
59167 _impliedYes = true;
59168 texts[0] = _t.html("_tagging.presets.fields.oneway_yes.options.undefined");
59174 function reverserHidden() {
59175 if (!context.container().select("div.inspector-hover").empty())
59177 return !(_value === "yes" || _impliedYes && !_value);
59179 function reverserSetText(selection2) {
59180 var entity = _entityIDs.length && context.hasEntity(_entityIDs[0]);
59181 if (reverserHidden() || !entity)
59183 var first = entity.first();
59184 var last = entity.isClosed() ? entity.nodes[entity.nodes.length - 2] : entity.last();
59185 var pseudoDirection = first < last;
59186 var icon2 = pseudoDirection ? "#iD-icon-forward" : "#iD-icon-backward";
59187 selection2.selectAll(".reverser-span").html("").call(_t.append("inspector.check.reverser")).call(svgIcon(icon2, "inline"));
59190 var check = function(selection2) {
59192 label = selection2.selectAll(".form-field-input-wrap").data([0]);
59193 var enter = label.enter().append("label").attr("class", "form-field-input-wrap form-field-input-check");
59194 enter.append("input").property("indeterminate", field.type !== "defaultCheck").attr("type", "checkbox").attr("id", field.domId);
59195 enter.append("span").html(texts[0]).attr("class", "value");
59196 if (field.type === "onewayCheck") {
59197 enter.append("button").attr("class", "reverser" + (reverserHidden() ? " hide" : "")).append("span").attr("class", "reverser-span");
59199 label = label.merge(enter);
59200 input = label.selectAll("input");
59201 text2 = label.selectAll("span.value");
59202 input.on("click", function(d3_event) {
59203 d3_event.stopPropagation();
59205 if (Array.isArray(_tags[field.key])) {
59206 if (values.indexOf("yes") !== -1) {
59207 t[field.key] = "yes";
59209 t[field.key] = values[0];
59212 t[field.key] = values[(values.indexOf(_value) + 1) % values.length];
59214 if (t[field.key] === "reversible" || t[field.key] === "alternating") {
59215 t[field.key] = values[0];
59217 dispatch10.call("change", this, t);
59219 if (field.type === "onewayCheck") {
59220 reverser = label.selectAll(".reverser");
59221 reverser.call(reverserSetText).on("click", function(d3_event) {
59222 d3_event.preventDefault();
59223 d3_event.stopPropagation();
59226 for (var i3 in _entityIDs) {
59227 graph = actionReverse(_entityIDs[i3])(graph);
59231 _t("operations.reverse.annotation.line", { n: 1 })
59233 context.validator().validate();
59234 select_default2(this).call(reverserSetText);
59238 check.entityIDs = function(val) {
59239 if (!arguments.length)
59244 check.tags = function(tags) {
59246 function isChecked(val) {
59247 return val !== "no" && val !== "" && val !== void 0 && val !== null;
59249 function textFor(val) {
59252 var index = values.indexOf(val);
59253 return index !== -1 ? texts[index] : '"' + val + '"';
59256 var isMixed = Array.isArray(tags[field.key]);
59257 _value = !isMixed && tags[field.key] && tags[field.key].toLowerCase();
59258 if (field.type === "onewayCheck" && (_value === "1" || _value === "-1")) {
59261 input.property("indeterminate", isMixed || field.type !== "defaultCheck" && !_value).property("checked", isChecked(_value));
59262 text2.html(isMixed ? _t.html("inspector.multiple_values") : textFor(_value)).classed("mixed", isMixed);
59263 label.classed("set", !!_value);
59264 if (field.type === "onewayCheck") {
59265 reverser.classed("hide", reverserHidden()).call(reverserSetText);
59268 check.focus = function() {
59269 input.node().focus();
59271 return utilRebind(check, dispatch10, "on");
59274 // modules/ui/length_indicator.js
59275 function uiLengthIndicator(maxChars) {
59276 var _wrap = select_default2(null);
59277 var _tooltip = uiPopover("tooltip max-length-warning").placement("bottom").hasArrow(true).content(() => (selection2) => {
59278 selection2.text("");
59279 selection2.call(svgIcon("#iD-icon-alert", "inline"));
59280 selection2.call(_t.append("inspector.max_length_reached", { maxChars }));
59282 var _silent = false;
59283 var lengthIndicator = function(selection2) {
59284 _wrap = selection2.selectAll("span.length-indicator-wrap").data([0]);
59285 _wrap = _wrap.enter().append("span").merge(_wrap).classed("length-indicator-wrap", true);
59286 selection2.call(_tooltip);
59288 lengthIndicator.update = function(val) {
59289 const strLen = utilUnicodeCharsCount(utilCleanOsmString(val, Number.POSITIVE_INFINITY));
59290 let indicator = _wrap.selectAll("span.length-indicator").data([strLen]);
59291 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");
59294 if (strLen > maxChars) {
59300 lengthIndicator.silent = function(val) {
59301 if (!arguments.length)
59304 return lengthIndicator;
59306 return lengthIndicator;
59309 // modules/ui/fields/combo.js
59310 function uiFieldCombo(field, context) {
59311 var dispatch10 = dispatch_default("change");
59312 var _isMulti = field.type === "multiCombo" || field.type === "manyCombo";
59313 var _isNetwork = field.type === "networkCombo";
59314 var _isSemi = field.type === "semiCombo";
59315 var _showTagInfoSuggestions = field.type !== "manyCombo" && field.autoSuggestions !== false;
59316 var _allowCustomValues = field.type !== "manyCombo" && field.customValues !== false;
59317 var _snake_case = field.snake_case || field.snake_case === void 0;
59318 var _combobox = uiCombobox(context, "combo-" + field.safeid).caseSensitive(field.caseSensitive).minItems(1);
59319 var _container = select_default2(null);
59320 var _inputWrap = select_default2(null);
59321 var _input = select_default2(null);
59322 var _lengthIndicator = uiLengthIndicator(context.maxCharsForTagValue());
59323 var _comboData = [];
59324 var _multiData = [];
59325 var _entityIDs = [];
59328 var _staticPlaceholder;
59329 var _dataDeprecated = [];
59330 _mainFileFetcher.get("deprecated").then(function(d) {
59331 _dataDeprecated = d;
59332 }).catch(function() {
59334 if (_isMulti && field.key && /[^:]$/.test(field.key)) {
59337 function snake(s) {
59338 return s.replace(/\s+/g, "_");
59340 function clean2(s) {
59341 return s.split(";").map(function(s2) {
59345 function tagValue(dval) {
59346 dval = clean2(dval || "");
59347 var found = getOptions().find(function(o) {
59348 return o.key && clean2(o.value) === dval;
59352 if (field.type === "typeCombo" && !dval) {
59355 return restrictTagValueSpelling(dval) || void 0;
59357 function restrictTagValueSpelling(dval) {
59359 dval = snake(dval);
59361 if (!field.caseSensitive) {
59362 dval = dval.toLowerCase();
59366 function getLabelId(field2, v) {
59367 return field2.hasTextForStringId(`options.${v}.title`) ? `options.${v}.title` : `options.${v}`;
59369 function displayValue(tval) {
59371 var stringsField = field.resolveReference("stringsCrossReference");
59372 const labelId = getLabelId(stringsField, tval);
59373 if (stringsField.hasTextForStringId(labelId)) {
59374 return stringsField.t(labelId, { default: tval });
59376 if (field.type === "typeCombo" && tval.toLowerCase() === "yes") {
59381 function renderValue(tval) {
59383 var stringsField = field.resolveReference("stringsCrossReference");
59384 const labelId = getLabelId(stringsField, tval);
59385 if (stringsField.hasTextForStringId(labelId)) {
59386 return stringsField.t.append(labelId, { default: tval });
59388 if (field.type === "typeCombo" && tval.toLowerCase() === "yes") {
59391 return (selection2) => selection2.text(tval);
59393 function objectDifference(a, b) {
59394 return a.filter(function(d1) {
59395 return !b.some(function(d2) {
59396 return !d2.isMixed && d1.value === d2.value;
59400 function initCombo(selection2, attachTo) {
59401 if (!_allowCustomValues) {
59402 selection2.attr("readonly", "readonly");
59404 if (_showTagInfoSuggestions && services.taginfo) {
59405 selection2.call(_combobox.fetcher(setTaginfoValues), attachTo);
59406 setTaginfoValues("", setPlaceholder);
59408 selection2.call(_combobox, attachTo);
59409 setStaticValues(setPlaceholder);
59412 function getOptions() {
59413 var stringsField = field.resolveReference("stringsCrossReference");
59414 if (!(field.options || stringsField.options))
59416 return (field.options || stringsField.options).map(function(v) {
59417 const labelId = getLabelId(stringsField, v);
59420 value: stringsField.t(labelId, { default: v }),
59421 title: stringsField.t(`options.${v}.description`, { default: v }),
59422 display: addComboboxIcons(stringsField.t.append(labelId, { default: v }), v),
59423 klass: stringsField.hasTextForStringId(labelId) ? "" : "raw-option"
59427 function setStaticValues(callback, filter2) {
59428 _comboData = getOptions();
59429 if (filter2 !== void 0) {
59430 _comboData = _comboData.filter(filter2);
59432 _comboData = objectDifference(_comboData, _multiData);
59433 _combobox.data(_comboData);
59435 callback(_comboData);
59437 function setTaginfoValues(q, callback) {
59438 var queryFilter = (d) => d.value.toLowerCase().includes(q.toLowerCase()) || d.key.toLowerCase().includes(q.toLowerCase());
59439 setStaticValues(callback, queryFilter);
59440 var stringsField = field.resolveReference("stringsCrossReference");
59441 var fn = _isMulti ? "multikeys" : "values";
59442 var query = (_isMulti ? field.key : "") + q;
59443 var hasCountryPrefix = _isNetwork && _countryCode && _countryCode.indexOf(q.toLowerCase()) === 0;
59444 if (hasCountryPrefix) {
59445 query = _countryCode + ":";
59448 debounce: q !== "",
59452 if (_entityIDs.length) {
59453 params.geometry = context.graph().geometry(_entityIDs[0]);
59455 services.taginfo[fn](params, function(err, data) {
59458 data = data.filter((d) => field.type !== "typeCombo" || d.value !== "yes");
59459 data = data.filter((d) => {
59460 var value = d.value;
59462 value = value.slice(field.key.length);
59464 return value === restrictTagValueSpelling(value);
59466 var deprecatedValues = osmEntity.deprecatedTagValuesByKey(_dataDeprecated)[field.key];
59467 if (deprecatedValues) {
59468 data = data.filter((d) => !deprecatedValues.includes(d.value));
59470 if (hasCountryPrefix) {
59471 data = data.filter((d) => d.value.toLowerCase().indexOf(_countryCode + ":") === 0);
59473 const additionalOptions = (field.options || stringsField.options || []).filter((v) => !data.some((dv) => dv.value === (_isMulti ? field.key + v : v))).map((v) => ({ value: v }));
59474 _container.classed("empty-combobox", data.length === 0);
59475 _comboData = data.concat(additionalOptions).map(function(d) {
59478 v = v.replace(field.key, "");
59479 const labelId = getLabelId(stringsField, v);
59480 var isLocalizable = stringsField.hasTextForStringId(labelId);
59481 var label = stringsField.t(labelId, { default: v });
59485 title: stringsField.t(`options.${v}.description`, { default: isLocalizable ? v : d.title !== label ? d.title : "" }),
59486 display: addComboboxIcons(stringsField.t.append(labelId, { default: v }), v),
59487 klass: isLocalizable ? "" : "raw-option"
59490 _comboData = _comboData.filter(queryFilter);
59491 _comboData = objectDifference(_comboData, _multiData);
59493 callback(_comboData);
59496 function addComboboxIcons(disp, value) {
59497 const iconsField = field.resolveReference("iconsCrossReference");
59498 if (iconsField.icons) {
59499 return function(selection2) {
59500 var span = selection2.insert("span", ":first-child").attr("class", "tag-value-icon");
59501 if (iconsField.icons[value]) {
59502 span.call(svgIcon(`#${iconsField.icons[value]}`));
59504 disp.call(this, selection2);
59509 function setPlaceholder(values) {
59510 if (_isMulti || _isSemi) {
59511 _staticPlaceholder = field.placeholder() || _t("inspector.add");
59513 var vals = values.map(function(d) {
59515 }).filter(function(s) {
59516 return s.length < 20;
59518 var placeholders = vals.length > 1 ? vals : values.map(function(d) {
59521 _staticPlaceholder = field.placeholder() || placeholders.slice(0, 3).join(", ");
59523 if (!/(…|\.\.\.)$/.test(_staticPlaceholder)) {
59524 _staticPlaceholder += "\u2026";
59527 if (!_isMulti && !_isSemi && _tags && Array.isArray(_tags[field.key])) {
59528 ph = _t("inspector.multiple_values");
59530 ph = _staticPlaceholder;
59532 _container.selectAll("input").attr("placeholder", ph);
59534 function change() {
59537 if (_isMulti || _isSemi) {
59540 vals = [tagValue(utilGetSetValue(_input))];
59541 } else if (_isSemi) {
59542 val = tagValue(utilGetSetValue(_input)) || "";
59543 val = val.replace(/,/g, ";");
59544 vals = val.split(";");
59546 vals = vals.filter(Boolean);
59549 _container.classed("active", false);
59550 utilGetSetValue(_input, "");
59552 utilArrayUniq(vals).forEach(function(v) {
59553 var key = (field.key || "") + v;
59555 var old = _tags[key];
59556 if (typeof old === "string" && old.toLowerCase() !== "no")
59559 key = context.cleanTagKey(key);
59560 field.keys.push(key);
59563 } else if (_isSemi) {
59564 var arr = _multiData.map(function(d) {
59567 arr = arr.concat(vals);
59568 t[field.key] = context.cleanTagValue(utilArrayUniq(arr).filter(Boolean).join(";"));
59570 window.setTimeout(function() {
59571 _input.node().focus();
59574 var rawValue = utilGetSetValue(_input);
59575 if (!rawValue && Array.isArray(_tags[field.key]))
59577 val = context.cleanTagValue(tagValue(rawValue));
59578 t[field.key] = val || void 0;
59580 dispatch10.call("change", this, t);
59582 function removeMultikey(d3_event, d) {
59583 d3_event.preventDefault();
59584 d3_event.stopPropagation();
59588 } else if (_isSemi) {
59589 var arr = _multiData.map(function(md) {
59590 return md.key === d.key ? null : md.key;
59591 }).filter(Boolean);
59592 arr = utilArrayUniq(arr);
59593 t[field.key] = arr.length ? arr.join(";") : void 0;
59594 _lengthIndicator.update(t[field.key]);
59596 dispatch10.call("change", this, t);
59598 function combo(selection2) {
59599 _container = selection2.selectAll(".form-field-input-wrap").data([0]);
59600 var type2 = _isMulti || _isSemi ? "multicombo" : "combo";
59601 _container = _container.enter().append("div").attr("class", "form-field-input-wrap form-field-input-" + type2).merge(_container);
59602 if (_isMulti || _isSemi) {
59603 _container = _container.selectAll(".chiplist").data([0]);
59604 var listClass = "chiplist";
59605 if (field.key === "destination" || field.key === "via") {
59606 listClass += " full-line-chips";
59608 _container = _container.enter().append("ul").attr("class", listClass).on("click", function() {
59609 window.setTimeout(function() {
59610 _input.node().focus();
59612 }).merge(_container);
59613 _inputWrap = _container.selectAll(".input-wrap").data([0]);
59614 _inputWrap = _inputWrap.enter().append("li").attr("class", "input-wrap").merge(_inputWrap);
59615 _input = _inputWrap.selectAll("input").data([0]);
59617 _input = _container.selectAll("input").data([0]);
59619 _input = _input.enter().append("input").attr("type", "text").attr("id", field.domId).call(utilNoAuto).call(initCombo, selection2).merge(_input);
59621 _inputWrap.call(_lengthIndicator);
59622 } else if (!_isMulti) {
59623 _container.call(_lengthIndicator);
59626 var extent = combinedEntityExtent();
59627 var countryCode = extent && iso1A2Code(extent.center());
59628 _countryCode = countryCode && countryCode.toLowerCase();
59630 _input.on("change", change).on("blur", change).on("input", function() {
59631 let val = utilGetSetValue(_input);
59633 if (_isSemi && _tags[field.key]) {
59634 val += ";" + _tags[field.key];
59636 _lengthIndicator.update(val);
59638 _input.on("keydown.field", function(d3_event) {
59639 switch (d3_event.keyCode) {
59641 _input.node().blur();
59642 d3_event.stopPropagation();
59646 if (_isMulti || _isSemi) {
59647 _combobox.on("accept", function() {
59648 _input.node().blur();
59649 _input.node().focus();
59651 _input.on("focus", function() {
59652 _container.classed("active", true);
59655 _combobox.on("cancel", function() {
59656 _input.node().blur();
59657 }).on("update", function() {
59658 updateIcon(utilGetSetValue(_input));
59661 function updateIcon(value) {
59662 value = tagValue(value);
59663 const iconsField = field.resolveReference("iconsCrossReference");
59664 if (iconsField.icons) {
59665 _container.selectAll(".tag-value-icon").remove();
59666 if (iconsField.icons[value]) {
59667 _container.selectAll(".tag-value-icon").data([value]).enter().insert("div", "input").attr("class", "tag-value-icon").call(svgIcon(`#${iconsField.icons[value]}`));
59671 combo.tags = function(tags) {
59673 var stringsField = field.resolveReference("stringsCrossReference");
59674 if (_isMulti || _isSemi) {
59678 for (var k in tags) {
59679 if (field.key && k.indexOf(field.key) !== 0)
59681 if (!field.key && field.keys.indexOf(k) === -1)
59684 if (!v || typeof v === "string" && v.toLowerCase() === "no")
59686 var suffix = field.key ? k.slice(field.key.length) : k;
59689 value: displayValue(suffix),
59690 display: renderValue(suffix),
59691 isMixed: Array.isArray(v)
59695 field.keys = _multiData.map(function(d) {
59698 maxLength = context.maxCharsForTagKey() - utilUnicodeCharsCount(field.key);
59700 maxLength = context.maxCharsForTagKey();
59702 } else if (_isSemi) {
59703 var allValues = [];
59705 if (Array.isArray(tags[field.key])) {
59706 tags[field.key].forEach(function(tagVal) {
59707 var thisVals = utilArrayUniq((tagVal || "").split(";")).filter(Boolean);
59708 allValues = allValues.concat(thisVals);
59709 if (!commonValues) {
59710 commonValues = thisVals;
59712 commonValues = commonValues.filter((value) => thisVals.includes(value));
59715 allValues = utilArrayUniq(allValues).filter(Boolean);
59717 allValues = utilArrayUniq((tags[field.key] || "").split(";")).filter(Boolean);
59718 commonValues = allValues;
59720 _multiData = allValues.map(function(v2) {
59723 value: displayValue(v2),
59724 display: renderValue(v2),
59725 isMixed: !commonValues.includes(v2)
59728 var currLength = utilUnicodeCharsCount(commonValues.join(";"));
59729 maxLength = context.maxCharsForTagValue() - currLength;
59730 if (currLength > 0) {
59734 maxLength = Math.max(0, maxLength);
59735 var allowDragAndDrop = _isSemi && !Array.isArray(tags[field.key]);
59736 var available = objectDifference(_comboData, _multiData);
59737 _combobox.data(available);
59738 var hideAdd = !_allowCustomValues && !available.length || maxLength <= 0;
59739 _container.selectAll(".chiplist .input-wrap").style("display", hideAdd ? "none" : null);
59740 var chips = _container.selectAll(".chip").data(_multiData);
59741 chips.exit().remove();
59742 var enter = chips.enter().insert("li", ".input-wrap").attr("class", "chip");
59743 enter.append("span");
59745 chips = chips.merge(enter).order().classed("raw-value", function(d) {
59748 k2 = k2.replace(field.key, "");
59749 return !stringsField.hasTextForStringId("options." + k2);
59750 }).classed("draggable", allowDragAndDrop).classed("mixed", function(d) {
59752 }).attr("title", function(d) {
59753 return d.isMixed ? _t("inspector.unshared_value_tooltip") : null;
59755 if (allowDragAndDrop) {
59756 registerDragAndDrop(chips);
59758 chips.select("span").each(function(d) {
59759 const selection2 = select_default2(this);
59761 selection2.text("");
59762 d.display(selection2);
59764 selection2.text(d.value);
59767 chips.select("a").attr("href", "#").on("click", removeMultikey).attr("class", "remove").text("\xD7");
59769 var isMixed = Array.isArray(tags[field.key]);
59770 var mixedValues = isMixed && tags[field.key].map(function(val) {
59771 return displayValue(val);
59772 }).filter(Boolean);
59773 var showsValue = !isMixed && tags[field.key] && !(field.type === "typeCombo" && tags[field.key] === "yes");
59774 var isRawValue = showsValue && !stringsField.hasTextForStringId(`options.${tags[field.key]}`) && !stringsField.hasTextForStringId(`options.${tags[field.key]}.title`);
59775 var isKnownValue = showsValue && !isRawValue;
59776 var isReadOnly = !_allowCustomValues || isKnownValue;
59777 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) {
59778 if (isReadOnly && isKnownValue && (d3_event.keyCode === utilKeybinding.keyCodes["\u232B"] || d3_event.keyCode === utilKeybinding.keyCodes["\u2326"])) {
59779 d3_event.preventDefault();
59780 d3_event.stopPropagation();
59782 t[field.key] = void 0;
59783 dispatch10.call("change", this, t);
59786 if (!Array.isArray(tags[field.key])) {
59787 updateIcon(tags[field.key]);
59790 _lengthIndicator.update(tags[field.key]);
59794 function registerDragAndDrop(selection2) {
59795 var dragOrigin, targetIndex;
59797 drag_default().on("start", function(d3_event) {
59802 targetIndex = null;
59803 }).on("drag", function(d3_event) {
59804 var x = d3_event.x - dragOrigin.x, y = d3_event.y - dragOrigin.y;
59805 if (!select_default2(this).classed("dragging") && // don't display drag until dragging beyond a distance threshold
59806 Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)) <= 5)
59808 var index = selection2.nodes().indexOf(this);
59809 select_default2(this).classed("dragging", true);
59810 targetIndex = null;
59811 var targetIndexOffsetTop = null;
59812 var draggedTagWidth = select_default2(this).node().offsetWidth;
59813 if (field.key === "destination" || field.key === "via") {
59814 _container.selectAll(".chip").style("transform", function(d2, index2) {
59815 var node = select_default2(this).node();
59816 if (index === index2) {
59817 return "translate(" + x + "px, " + y + "px)";
59818 } else if (index2 > index && d3_event.y > node.offsetTop) {
59819 if (targetIndex === null || index2 > targetIndex) {
59820 targetIndex = index2;
59822 return "translateY(-100%)";
59823 } else if (index2 < index && d3_event.y < node.offsetTop + node.offsetHeight) {
59824 if (targetIndex === null || index2 < targetIndex) {
59825 targetIndex = index2;
59827 return "translateY(100%)";
59832 _container.selectAll(".chip").each(function(d2, index2) {
59833 var node = select_default2(this).node();
59834 if (index !== index2 && d3_event.x < node.offsetLeft + node.offsetWidth + 5 && d3_event.x > node.offsetLeft && d3_event.y < node.offsetTop + node.offsetHeight && d3_event.y > node.offsetTop) {
59835 targetIndex = index2;
59836 targetIndexOffsetTop = node.offsetTop;
59838 }).style("transform", function(d2, index2) {
59839 var node = select_default2(this).node();
59840 if (index === index2) {
59841 return "translate(" + x + "px, " + y + "px)";
59843 if (node.offsetTop === targetIndexOffsetTop) {
59844 if (index2 < index && index2 >= targetIndex) {
59845 return "translateX(" + draggedTagWidth + "px)";
59846 } else if (index2 > index && index2 <= targetIndex) {
59847 return "translateX(-" + draggedTagWidth + "px)";
59853 }).on("end", function() {
59854 if (!select_default2(this).classed("dragging")) {
59857 var index = selection2.nodes().indexOf(this);
59858 select_default2(this).classed("dragging", false);
59859 _container.selectAll(".chip").style("transform", null);
59860 if (typeof targetIndex === "number") {
59861 var element = _multiData[index];
59862 _multiData.splice(index, 1);
59863 _multiData.splice(targetIndex, 0, element);
59865 if (_multiData.length) {
59866 t[field.key] = _multiData.map(function(element2) {
59867 return element2.key;
59870 t[field.key] = void 0;
59872 dispatch10.call("change", this, t);
59874 dragOrigin = void 0;
59875 targetIndex = void 0;
59879 combo.focus = function() {
59880 _input.node().focus();
59882 combo.entityIDs = function(val) {
59883 if (!arguments.length)
59888 function combinedEntityExtent() {
59889 return _entityIDs && _entityIDs.length && utilTotalExtent(_entityIDs, context.graph());
59891 return utilRebind(combo, dispatch10, "on");
59894 // modules/ui/fields/input.js
59895 function uiFieldText(field, context) {
59896 var dispatch10 = dispatch_default("change");
59897 var input = select_default2(null);
59898 var outlinkButton = select_default2(null);
59899 var wrap2 = select_default2(null);
59900 var _lengthIndicator = uiLengthIndicator(context.maxCharsForTagValue());
59901 var _entityIDs = [];
59903 var _phoneFormats = {};
59904 const isDirectionField = field.key.split(":").some((keyPart) => keyPart === "direction");
59905 if (field.type === "tel") {
59906 _mainFileFetcher.get("phone_formats").then(function(d) {
59908 updatePhonePlaceholder();
59909 }).catch(function() {
59912 function calcLocked() {
59913 var isLocked = (field.id === "brand" || field.id === "network" || field.id === "operator" || field.id === "flag") && _entityIDs.length && _entityIDs.some(function(entityID) {
59914 var entity = context.graph().hasEntity(entityID);
59917 if (entity.tags.wikidata)
59919 var preset = _mainPresetIndex.match(entity, context.graph());
59920 var isSuggestion = preset && preset.suggestion;
59921 var which = field.id;
59922 return isSuggestion && !!entity.tags[which] && !!entity.tags[which + ":wikidata"];
59924 field.locked(isLocked);
59926 function i2(selection2) {
59928 var isLocked = field.locked();
59929 wrap2 = selection2.selectAll(".form-field-input-wrap").data([0]);
59930 wrap2 = wrap2.enter().append("div").attr("class", "form-field-input-wrap form-field-input-" + field.type).merge(wrap2);
59931 input = wrap2.selectAll("input").data([0]);
59932 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);
59933 input.classed("disabled", !!isLocked).attr("readonly", isLocked || null).on("input", change(true)).on("blur", change()).on("change", change());
59934 wrap2.call(_lengthIndicator);
59935 if (field.type === "tel") {
59936 updatePhonePlaceholder();
59937 } else if (field.type === "number") {
59938 var rtl = _mainLocalizer.textDirection() === "rtl";
59939 input.attr("type", "text");
59940 var inc = field.increment;
59941 var buttons = wrap2.selectAll(".increment, .decrement").data(rtl ? [inc, -inc] : [-inc, inc]);
59942 buttons.enter().append("button").attr("class", function(d) {
59943 var which = d > 0 ? "increment" : "decrement";
59944 return "form-field-button " + which;
59945 }).attr("title", function(d) {
59946 var which = d > 0 ? "increment" : "decrement";
59947 return _t(`inspector.${which}`);
59948 }).merge(buttons).on("click", function(d3_event, d) {
59949 d3_event.preventDefault();
59950 var isMixed = Array.isArray(_tags[field.key]);
59953 var raw_vals = input.node().value || "0";
59954 var vals = raw_vals.split(";");
59955 vals = vals.map(function(v) {
59956 var num = Number(v);
59957 if (isDirectionField) {
59958 const compassDir = cardinal[v.trim().toLowerCase()];
59959 if (compassDir !== void 0) {
59963 if (!isFinite(num)) {
59967 if (isDirectionField) {
59968 num = (num % 360 + 360) % 360;
59970 const numDecimals = v.includes(".") ? v.split(".")[1].length : 0;
59971 return clamped(num).toFixed(numDecimals);
59973 input.node().value = vals.join(";");
59976 } else if (field.type === "identifier" && field.urlFormat && field.pattern) {
59977 input.attr("type", "text");
59978 outlinkButton = wrap2.selectAll(".foreign-id-permalink").data([0]);
59979 outlinkButton.enter().append("button").call(svgIcon("#iD-icon-out-link")).attr("class", "form-field-button foreign-id-permalink").attr("title", function() {
59980 var domainResults = /^https?:\/\/(.{1,}?)\//.exec(field.urlFormat);
59981 if (domainResults.length >= 2 && domainResults[1]) {
59982 var domain2 = domainResults[1];
59983 return _t("icons.view_on", { domain: domain2 });
59986 }).on("click", function(d3_event) {
59987 d3_event.preventDefault();
59988 var value = validIdentifierValueForLink();
59990 var url = field.urlFormat.replace(/{value}/, encodeURIComponent(value));
59991 window.open(url, "_blank");
59993 }).merge(outlinkButton);
59994 } else if (field.type === "url") {
59995 input.attr("type", "text");
59996 outlinkButton = wrap2.selectAll(".foreign-id-permalink").data([0]);
59997 outlinkButton.enter().append("button").call(svgIcon("#iD-icon-out-link")).attr("class", "form-field-button foreign-id-permalink").attr("title", () => _t("icons.visit_website")).on("click", function(d3_event) {
59998 d3_event.preventDefault();
59999 const value = validIdentifierValueForLink();
60001 window.open(value, "_blank");
60002 }).merge(outlinkButton);
60003 } else if (field.type === "colour") {
60004 input.attr("type", "text");
60005 updateColourPreview();
60006 } else if (field.type === "date") {
60007 input.attr("type", "text");
60011 function updateColourPreview() {
60012 function isColourValid(colour2) {
60013 if (!colour2.match(/^(#([0-9a-fA-F]{3}){1,2}|\w+)$/)) {
60015 } else if (!CSS.supports("color", colour2) || ["unset", "inherit", "initial", "revert"].includes(colour2)) {
60020 wrap2.selectAll(".colour-preview").remove();
60021 const colour = utilGetSetValue(input);
60022 if (!isColourValid(colour) && colour !== "") {
60023 wrap2.selectAll("input.colour-selector").remove();
60024 wrap2.selectAll(".form-field-button").remove();
60027 var colourSelector = wrap2.selectAll(".colour-selector").data([0]);
60028 colourSelector.enter().append("input").attr("type", "color").attr("class", "colour-selector").on("input", debounce_default(function(d3_event) {
60029 d3_event.preventDefault();
60030 var colour2 = this.value;
60031 if (!isColourValid(colour2))
60033 utilGetSetValue(input, this.value);
60035 updateColourPreview();
60037 wrap2.selectAll("input.colour-selector").attr("value", colour);
60038 var chooserButton = wrap2.selectAll(".colour-preview").data([colour]);
60039 chooserButton = chooserButton.enter().append("div").attr("class", "form-field-button colour-preview").append("div").style("background-color", (d) => d).attr("class", "colour-box");
60040 if (colour === "") {
60041 chooserButton = chooserButton.call(svgIcon("#iD-icon-edit"));
60043 chooserButton.on("click", () => wrap2.select(".colour-selector").node().showPicker());
60045 function updateDateField() {
60046 function isDateValid(date2) {
60047 return date2.match(/^[0-9]{4}(-[0-9]{2}(-[0-9]{2})?)?$/);
60049 const date = utilGetSetValue(input);
60050 const now3 = /* @__PURE__ */ new Date();
60051 const today = new Date(now3.getTime() - now3.getTimezoneOffset() * 6e4).toISOString().split("T")[0];
60052 if ((field.key === "check_date" || field.key === "survey:date") && date !== today) {
60053 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", () => {
60054 utilGetSetValue(input, today);
60059 wrap2.selectAll(".date-set-today").remove();
60061 if (!isDateValid(date) && date !== "") {
60062 wrap2.selectAll("input.date-selector").remove();
60063 wrap2.selectAll(".date-calendar").remove();
60066 if (utilDetect().browser !== "Safari") {
60067 var dateSelector = wrap2.selectAll(".date-selector").data([0]);
60068 dateSelector.enter().append("input").attr("type", "date").attr("class", "date-selector").on("input", debounce_default(function(d3_event) {
60069 d3_event.preventDefault();
60070 var date2 = this.value;
60071 if (!isDateValid(date2))
60073 utilGetSetValue(input, this.value);
60077 wrap2.selectAll("input.date-selector").attr("value", date);
60078 var calendarButton = wrap2.selectAll(".date-calendar").data([date]);
60079 calendarButton = calendarButton.enter().append("button").attr("class", "form-field-button date-calendar").call(svgIcon("#fas-calendar-days"));
60080 calendarButton.on("click", () => wrap2.select(".date-selector").node().showPicker());
60083 function updatePhonePlaceholder() {
60084 if (input.empty() || !Object.keys(_phoneFormats).length)
60086 var extent = combinedEntityExtent();
60087 var countryCode = extent && iso1A2Code(extent.center());
60088 var format2 = countryCode && _phoneFormats[countryCode.toLowerCase()];
60090 input.attr("placeholder", format2);
60092 function validIdentifierValueForLink() {
60093 const value = utilGetSetValue(input).trim();
60094 if (field.type === "url" && value) {
60096 return new URL(value).href;
60101 if (field.type === "identifier" && field.pattern) {
60102 return value && value.match(new RegExp(field.pattern))[0];
60106 function clamped(num) {
60107 if (field.minValue !== void 0) {
60108 num = Math.max(num, field.minValue);
60110 if (field.maxValue !== void 0) {
60111 num = Math.min(num, field.maxValue);
60115 function change(onInput) {
60116 return function() {
60118 var val = utilGetSetValue(input);
60120 val = context.cleanTagValue(val);
60121 if (!val && Array.isArray(_tags[field.key]))
60124 if (field.type === "number" && val) {
60125 var vals = val.split(";");
60126 vals = vals.map(function(v) {
60127 var num = Number(v);
60128 return isFinite(num) ? clamped(num) : v.trim();
60130 val = vals.join(";");
60132 utilGetSetValue(input, val);
60134 t[field.key] = val || void 0;
60135 dispatch10.call("change", this, t, onInput);
60138 i2.entityIDs = function(val) {
60139 if (!arguments.length)
60144 i2.tags = function(tags) {
60146 var isMixed = Array.isArray(tags[field.key]);
60147 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);
60148 if (field.type === "number") {
60149 const buttons = wrap2.selectAll(".increment, .decrement");
60151 buttons.attr("disabled", "disabled").classed("disabled", true);
60153 var raw_vals = tags[field.key] || "0";
60154 const canIncDec = raw_vals.split(";").some((val) => isFinite(Number(val)) || isDirectionField && cardinal[val.trim().toLowerCase()]);
60155 buttons.attr("disabled", canIncDec ? null : "disabled").classed("disabled", !canIncDec);
60158 if (field.type === "tel")
60159 updatePhonePlaceholder();
60160 if (field.type === "colour")
60161 updateColourPreview();
60162 if (field.type === "date")
60164 if (outlinkButton && !outlinkButton.empty()) {
60165 var disabled = !validIdentifierValueForLink();
60166 outlinkButton.classed("disabled", disabled);
60169 _lengthIndicator.update(tags[field.key]);
60172 i2.focus = function() {
60173 var node = input.node();
60177 function combinedEntityExtent() {
60178 return _entityIDs && _entityIDs.length && utilTotalExtent(_entityIDs, context.graph());
60180 return utilRebind(i2, dispatch10, "on");
60183 // modules/ui/fields/access.js
60184 function uiFieldAccess(field, context) {
60185 var dispatch10 = dispatch_default("change");
60186 var items = select_default2(null);
60188 function access(selection2) {
60189 var wrap2 = selection2.selectAll(".form-field-input-wrap").data([0]);
60190 wrap2 = wrap2.enter().append("div").attr("class", "form-field-input-wrap form-field-input-" + field.type).merge(wrap2);
60191 var list = wrap2.selectAll("ul").data([0]);
60192 list = list.enter().append("ul").attr("class", "rows").merge(list);
60193 items = list.selectAll("li").data(field.keys);
60194 var enter = items.enter().append("li").attr("class", function(d) {
60195 return "labeled-input preset-access-" + d;
60197 enter.append("span").attr("class", "label preset-label-access").attr("for", function(d) {
60198 return "preset-input-access-" + d;
60199 }).html(function(d) {
60200 return field.t.html("types." + d);
60202 enter.append("div").attr("class", "preset-input-access-wrap").append("input").attr("type", "text").attr("class", function(d) {
60203 return "preset-input-access preset-input-access-" + d;
60204 }).call(utilNoAuto).each(function(d) {
60205 select_default2(this).call(
60206 uiCombobox(context, "access-" + d).data(access.options(d))
60209 items = items.merge(enter);
60210 wrap2.selectAll(".preset-input-access").on("change", change).on("blur", change);
60212 function change(d3_event, d) {
60214 var value = context.cleanTagValue(utilGetSetValue(select_default2(this)));
60215 if (!value && typeof _tags[d] !== "string")
60217 tag[d] = value || void 0;
60218 dispatch10.call("change", this, tag);
60220 access.options = function(type2) {
60232 if (type2 === "access") {
60233 options2 = options2.filter((v) => v !== "yes" && v !== "designated");
60235 if (type2 === "bicycle") {
60236 options2.splice(options2.length - 4, 0, "dismount");
60238 var stringsField = field.resolveReference("stringsCrossReference");
60239 return options2.map(function(option) {
60241 title: stringsField.t("options." + option + ".description"),
60246 const placeholdersByTag = {
60249 foot: "designated",
60250 motor_vehicle: "no"
60254 motor_vehicle: "no",
60260 motor_vehicle: "no"
60263 motor_vehicle: "no",
60264 bicycle: "designated"
60267 motor_vehicle: "no",
60268 horse: "designated"
60272 motor_vehicle: "no",
60278 motor_vehicle: "yes",
60283 motor_vehicle: "yes"
60287 motor_vehicle: "yes",
60293 motor_vehicle: "yes",
60299 motor_vehicle: "yes",
60305 motor_vehicle: "yes",
60311 motor_vehicle: "yes",
60317 motor_vehicle: "yes",
60323 motor_vehicle: "yes",
60328 motor_vehicle: "yes"
60332 motor_vehicle: "yes",
60338 motor_vehicle: "yes",
60344 motor_vehicle: "yes",
60359 motor_vehicle: "no",
60371 motor_vehicle: "no"
60388 motorcycle_barrier: {
60389 motor_vehicle: "no"
60396 access.tags = function(tags) {
60398 utilGetSetValue(items.selectAll(".preset-input-access"), function(d) {
60399 return typeof tags[d] === "string" ? tags[d] : "";
60400 }).classed("mixed", function(d) {
60401 return tags[d] && Array.isArray(tags[d]);
60402 }).attr("title", function(d) {
60403 return tags[d] && Array.isArray(tags[d]) && tags[d].filter(Boolean).join("\n");
60404 }).attr("placeholder", function(d) {
60405 if (tags[d] && Array.isArray(tags[d])) {
60406 return _t("inspector.multiple_values");
60408 if (d === "bicycle" || d === "motor_vehicle") {
60409 if (tags.vehicle && typeof tags.vehicle === "string") {
60410 return tags.vehicle;
60413 if (tags.access && typeof tags.access === "string") {
60414 return tags.access;
60416 function getPlaceholdersByTag(key, placeholdersByKey) {
60417 if (typeof tags[key] === "string") {
60418 if (placeholdersByKey[tags[key]] && placeholdersByKey[tags[key]][d]) {
60419 return placeholdersByKey[tags[key]][d];
60422 var impliedAccesses = tags[key].filter(Boolean).map(function(val) {
60423 return placeholdersByKey[val] && placeholdersByKey[val][d];
60424 }).filter(Boolean);
60425 if (impliedAccesses.length === tags[key].length && new Set(impliedAccesses).size === 1) {
60426 return impliedAccesses[0];
60430 for (const key in placeholdersByTag) {
60432 const impliedAccess = getPlaceholdersByTag(key, placeholdersByTag[key]);
60433 if (impliedAccess) {
60434 return impliedAccess;
60438 if (d === "access" && !tags.barrier) {
60441 return field.placeholder();
60444 access.focus = function() {
60445 items.selectAll(".preset-input-access").node().focus();
60447 return utilRebind(access, dispatch10, "on");
60450 // modules/ui/fields/address.js
60451 function uiFieldAddress(field, context) {
60452 var dispatch10 = dispatch_default("change");
60453 var _selection = select_default2(null);
60454 var _wrap = select_default2(null);
60455 var addrField = _mainPresetIndex.field("address");
60456 var _entityIDs = [];
60459 var _addressFormats = [{
60461 ["housenumber", "street"],
60462 ["city", "postcode"]
60465 _mainFileFetcher.get("address_formats").then(function(d) {
60466 _addressFormats = d;
60467 if (!_selection.empty()) {
60468 _selection.call(address);
60470 }).catch(function() {
60472 function getNearStreets() {
60473 var extent = combinedEntityExtent();
60474 var l = extent.center();
60475 var box = geoExtent(l).padByMeters(200);
60476 var streets = context.history().intersects(box).filter(isAddressable).map(function(d) {
60477 var loc = context.projection([
60478 (extent[0][0] + extent[1][0]) / 2,
60479 (extent[0][1] + extent[1][1]) / 2
60481 var choice = geoChooseEdge(context.graph().childNodes(d), loc, context.projection);
60483 title: d.tags.name,
60484 value: d.tags.name,
60485 dist: choice.distance
60487 }).sort(function(a, b) {
60488 return a.dist - b.dist;
60490 return utilArrayUniqBy(streets, "value");
60491 function isAddressable(d) {
60492 return d.tags.highway && d.tags.name && d.type === "way";
60495 function getNearCities() {
60496 var extent = combinedEntityExtent();
60497 var l = extent.center();
60498 var box = geoExtent(l).padByMeters(200);
60499 var cities = context.history().intersects(box).filter(isAddressable).map(function(d) {
60501 title: d.tags["addr:city"] || d.tags.name,
60502 value: d.tags["addr:city"] || d.tags.name,
60503 dist: geoSphericalDistance(d.extent(context.graph()).center(), l)
60505 }).sort(function(a, b) {
60506 return a.dist - b.dist;
60508 return utilArrayUniqBy(cities, "value");
60509 function isAddressable(d) {
60511 if (d.tags.admin_level === "8" && d.tags.boundary === "administrative")
60513 if (d.tags.border_type === "city")
60515 if (d.tags.place === "city" || d.tags.place === "town" || d.tags.place === "village")
60518 if (d.tags["addr:city"])
60523 function getNearValues(key) {
60524 var extent = combinedEntityExtent();
60525 var l = extent.center();
60526 var box = geoExtent(l).padByMeters(200);
60527 var results = context.history().intersects(box).filter(function hasTag(d) {
60528 return _entityIDs.indexOf(d.id) === -1 && d.tags[key];
60529 }).map(function(d) {
60531 title: d.tags[key],
60532 value: d.tags[key],
60533 dist: geoSphericalDistance(d.extent(context.graph()).center(), l)
60535 }).sort(function(a, b) {
60536 return a.dist - b.dist;
60538 return utilArrayUniqBy(results, "value");
60540 function updateForCountryCode() {
60544 for (var i2 = 0; i2 < _addressFormats.length; i2++) {
60545 var format2 = _addressFormats[i2];
60546 if (!format2.countryCodes) {
60547 addressFormat = format2;
60548 } else if (format2.countryCodes.indexOf(_countryCode) !== -1) {
60549 addressFormat = format2;
60553 var dropdowns = addressFormat.dropdowns || [
60569 var widths = addressFormat.widths || {
60570 housenumber: 1 / 3,
60577 var total = r.reduce(function(sum, key) {
60578 return sum + (widths[key] || 0.5);
60580 return r.map(function(key) {
60583 width: (widths[key] || 0.5) / total
60587 var rows = _wrap.selectAll(".addr-row").data(addressFormat.format, function(d) {
60588 return d.toString();
60590 rows.exit().remove();
60591 rows.enter().append("div").attr("class", "addr-row").selectAll("input").data(row).enter().append("input").property("type", "text").call(updatePlaceholder).attr("class", function(d) {
60592 return "addr-" + d.id;
60593 }).call(utilNoAuto).each(addDropdown).style("width", function(d) {
60594 return d.width * 100 + "%";
60596 function addDropdown(d) {
60597 if (dropdowns.indexOf(d.id) === -1)
60599 var nearValues = d.id === "street" ? getNearStreets : d.id === "city" ? getNearCities : getNearValues;
60600 select_default2(this).call(
60601 uiCombobox(context, "address-" + d.id).minItems(1).caseSensitive(true).fetcher(function(value, callback) {
60602 callback(nearValues("addr:" + d.id));
60606 _wrap.selectAll("input").on("blur", change()).on("change", change());
60607 _wrap.selectAll("input:not(.combobox-input)").on("input", change(true));
60611 function address(selection2) {
60612 _selection = selection2;
60613 _wrap = selection2.selectAll(".form-field-input-wrap").data([0]);
60614 _wrap = _wrap.enter().append("div").attr("class", "form-field-input-wrap form-field-input-" + field.type).merge(_wrap);
60615 var extent = combinedEntityExtent();
60618 if (context.inIntro()) {
60619 countryCode = _t("intro.graph.countrycode");
60621 var center = extent.center();
60622 countryCode = iso1A2Code(center);
60625 _countryCode = countryCode.toLowerCase();
60626 updateForCountryCode();
60630 function change(onInput) {
60631 return function() {
60633 _wrap.selectAll("input").each(function(subfield) {
60634 var key = field.key + ":" + subfield.id;
60635 var value = this.value;
60637 value = context.cleanTagValue(value);
60638 if (Array.isArray(_tags[key]) && !value)
60640 tags[key] = value || void 0;
60642 dispatch10.call("change", this, tags, onInput);
60645 function updatePlaceholder(inputSelection) {
60646 return inputSelection.attr("placeholder", function(subfield) {
60647 if (_tags && Array.isArray(_tags[field.key + ":" + subfield.id])) {
60648 return _t("inspector.multiple_values");
60650 if (_countryCode) {
60651 var localkey = subfield.id + "!" + _countryCode;
60652 var tkey = addrField.hasTextForStringId("placeholders." + localkey) ? localkey : subfield.id;
60653 return addrField.t("placeholders." + tkey);
60657 function updateTags(tags) {
60658 utilGetSetValue(_wrap.selectAll("input"), function(subfield) {
60659 var val = tags[field.key + ":" + subfield.id];
60660 return typeof val === "string" ? val : "";
60661 }).attr("title", function(subfield) {
60662 var val = tags[field.key + ":" + subfield.id];
60663 return val && Array.isArray(val) ? val.filter(Boolean).join("\n") : void 0;
60664 }).classed("mixed", function(subfield) {
60665 return Array.isArray(tags[field.key + ":" + subfield.id]);
60666 }).call(updatePlaceholder);
60668 function combinedEntityExtent() {
60669 return _entityIDs && _entityIDs.length && utilTotalExtent(_entityIDs, context.graph());
60671 address.entityIDs = function(val) {
60672 if (!arguments.length)
60677 address.tags = function(tags) {
60681 address.focus = function() {
60682 var node = _wrap.selectAll("input").node();
60686 return utilRebind(address, dispatch10, "on");
60689 // modules/ui/fields/directional_combo.js
60690 function uiFieldDirectionalCombo(field, context) {
60691 var dispatch10 = dispatch_default("change");
60692 var items = select_default2(null);
60693 var wrap2 = select_default2(null);
60696 if (field.type === "cycleway") {
60699 key: field.keys[0],
60700 keys: field.keys.slice(1)
60703 function directionalCombo(selection2) {
60704 function stripcolon(s) {
60705 return s.replace(":", "");
60707 wrap2 = selection2.selectAll(".form-field-input-wrap").data([0]);
60708 wrap2 = wrap2.enter().append("div").attr("class", "form-field-input-wrap form-field-input-" + field.type).merge(wrap2);
60709 var div = wrap2.selectAll("ul").data([0]);
60710 div = div.enter().append("ul").attr("class", "rows").merge(div);
60711 items = div.selectAll("li").data(field.keys);
60712 var enter = items.enter().append("li").attr("class", function(d) {
60713 return "labeled-input preset-directionalcombo-" + stripcolon(d);
60715 enter.append("span").attr("class", "label preset-label-directionalcombo").attr("for", function(d) {
60716 return "preset-input-directionalcombo-" + stripcolon(d);
60717 }).html(function(d) {
60718 return field.t.html("types." + d);
60720 enter.append("div").attr("class", "preset-input-directionalcombo-wrap form-field-input-wrap").each(function(key) {
60726 const combo = uiFieldCombo(subField, context);
60727 combo.on("change", (t) => change(key, t[key]));
60728 _combos[key] = combo;
60729 select_default2(this).call(combo);
60731 items = items.merge(enter);
60732 wrap2.selectAll(".preset-input-directionalcombo").on("change", change).on("blur", change);
60734 function change(key, newValue) {
60735 const commonKey = field.key;
60736 const otherKey = key === field.keys[0] ? field.keys[1] : field.keys[0];
60737 dispatch10.call("change", this, (tags) => {
60738 const otherValue = tags[otherKey] || tags[commonKey];
60739 if (newValue === otherValue) {
60740 tags[commonKey] = newValue;
60742 delete tags[otherKey];
60744 tags[key] = newValue;
60745 delete tags[commonKey];
60746 tags[otherKey] = otherValue;
60751 directionalCombo.tags = function(tags) {
60753 const commonKey = field.key;
60754 for (let key in _combos) {
60755 const uniqueValues = [...new Set([].concat(_tags[commonKey]).concat(_tags[key]).filter(Boolean))];
60756 _combos[key].tags({ [key]: uniqueValues.length > 1 ? uniqueValues : uniqueValues[0] });
60759 directionalCombo.focus = function() {
60760 var node = wrap2.selectAll("input").node();
60764 return utilRebind(directionalCombo, dispatch10, "on");
60767 // modules/ui/fields/lanes.js
60768 function uiFieldLanes(field, context) {
60769 var dispatch10 = dispatch_default("change");
60770 var LANE_WIDTH = 40;
60771 var LANE_HEIGHT = 200;
60772 var _entityIDs = [];
60773 function lanes(selection2) {
60774 var lanesData = context.entity(_entityIDs[0]).lanes();
60775 if (!context.container().select(".inspector-wrap.inspector-hidden").empty() || !selection2.node().parentNode) {
60776 selection2.call(lanes.off);
60779 var wrap2 = selection2.selectAll(".form-field-input-wrap").data([0]);
60780 wrap2 = wrap2.enter().append("div").attr("class", "form-field-input-wrap form-field-input-" + field.type).merge(wrap2);
60781 var surface = wrap2.selectAll(".surface").data([0]);
60782 var d = utilGetDimensions(wrap2);
60783 var freeSpace = d[0] - lanesData.lanes.length * LANE_WIDTH * 1.5 + LANE_WIDTH * 0.5;
60784 surface = surface.enter().append("svg").attr("width", d[0]).attr("height", 300).attr("class", "surface").merge(surface);
60785 var lanesSelection = surface.selectAll(".lanes").data([0]);
60786 lanesSelection = lanesSelection.enter().append("g").attr("class", "lanes").merge(lanesSelection);
60787 lanesSelection.attr("transform", function() {
60788 return "translate(" + freeSpace / 2 + ", 0)";
60790 var lane = lanesSelection.selectAll(".lane").data(lanesData.lanes);
60791 lane.exit().remove();
60792 var enter = lane.enter().append("g").attr("class", "lane");
60793 enter.append("g").append("rect").attr("y", 50).attr("width", LANE_WIDTH).attr("height", LANE_HEIGHT);
60794 enter.append("g").attr("class", "forward").append("text").attr("y", 40).attr("x", 14).text("\u25B2");
60795 enter.append("g").attr("class", "bothways").append("text").attr("y", 40).attr("x", 14).text("\u25B2\u25BC");
60796 enter.append("g").attr("class", "backward").append("text").attr("y", 40).attr("x", 14).text("\u25BC");
60797 lane = lane.merge(enter);
60798 lane.attr("transform", function(d2) {
60799 return "translate(" + LANE_WIDTH * d2.index * 1.5 + ", 0)";
60801 lane.select(".forward").style("visibility", function(d2) {
60802 return d2.direction === "forward" ? "visible" : "hidden";
60804 lane.select(".bothways").style("visibility", function(d2) {
60805 return d2.direction === "bothways" ? "visible" : "hidden";
60807 lane.select(".backward").style("visibility", function(d2) {
60808 return d2.direction === "backward" ? "visible" : "hidden";
60811 lanes.entityIDs = function(val) {
60814 lanes.tags = function() {
60816 lanes.focus = function() {
60818 lanes.off = function() {
60820 return utilRebind(lanes, dispatch10, "on");
60822 uiFieldLanes.supportsMultiselection = false;
60824 // modules/ui/fields/localized.js
60825 var _languagesArray = [];
60826 function uiFieldLocalized(field, context) {
60827 var dispatch10 = dispatch_default("change", "input");
60828 var wikipedia = services.wikipedia;
60829 var input = select_default2(null);
60830 var localizedInputs = select_default2(null);
60831 var _lengthIndicator = uiLengthIndicator(context.maxCharsForTagValue());
60834 _mainFileFetcher.get("languages").then(loadLanguagesArray).catch(function() {
60836 var _territoryLanguages = {};
60837 _mainFileFetcher.get("territory_languages").then(function(d) {
60838 _territoryLanguages = d;
60839 }).catch(function() {
60841 var langCombo = uiCombobox(context, "localized-lang").fetcher(fetchLanguages).minItems(0);
60842 var _selection = select_default2(null);
60843 var _multilingual = [];
60844 var _buttonTip = uiTooltip().title(() => _t.append("translate.translate")).placement("left");
60846 var _entityIDs = [];
60847 function loadLanguagesArray(dataLanguages) {
60848 if (_languagesArray.length !== 0)
60850 var replacements = {
60852 // in OSM, `sr` implies Cyrillic
60854 // `sr-Cyrl` isn't used in OSM
60856 for (var code in dataLanguages) {
60857 if (replacements[code] === false)
60859 var metaCode = code;
60860 if (replacements[code])
60861 metaCode = replacements[code];
60862 _languagesArray.push({
60863 localName: _mainLocalizer.languageName(metaCode, { localOnly: true }),
60864 nativeName: dataLanguages[metaCode].nativeName,
60866 label: _mainLocalizer.languageName(metaCode)
60870 function calcLocked() {
60871 var isLocked = field.id === "name" && _entityIDs.length && _entityIDs.some(function(entityID) {
60872 var entity = context.graph().hasEntity(entityID);
60875 if (entity.tags.wikidata)
60877 if (entity.tags["name:etymology:wikidata"])
60879 var preset = _mainPresetIndex.match(entity, context.graph());
60881 var isSuggestion = preset.suggestion;
60882 var fields = preset.fields();
60883 var showsBrandField = fields.some(function(d) {
60884 return d.id === "brand";
60886 var showsOperatorField = fields.some(function(d) {
60887 return d.id === "operator";
60889 var setsName = preset.addTags.name;
60890 var setsBrandWikidata = preset.addTags["brand:wikidata"];
60891 var setsOperatorWikidata = preset.addTags["operator:wikidata"];
60892 return isSuggestion && setsName && (setsBrandWikidata && !showsBrandField || setsOperatorWikidata && !showsOperatorField);
60896 field.locked(isLocked);
60898 function calcMultilingual(tags) {
60899 var existingLangsOrdered = _multilingual.map(function(item2) {
60902 var existingLangs = new Set(existingLangsOrdered.filter(Boolean));
60903 for (var k in tags) {
60904 var m = k.match(/^(.*):([a-z]{2,3}(?:-[A-Z][a-z]{3})?(?:-[A-Z]{2})?)$/);
60905 if (m && m[1] === field.key && m[2]) {
60906 var item = { lang: m[2], value: tags[k] };
60907 if (existingLangs.has(item.lang)) {
60908 _multilingual[existingLangsOrdered.indexOf(item.lang)].value = item.value;
60909 existingLangs.delete(item.lang);
60911 _multilingual.push(item);
60915 _multilingual.forEach(function(item2) {
60916 if (item2.lang && existingLangs.has(item2.lang)) {
60921 function localized(selection2) {
60922 _selection = selection2;
60924 var isLocked = field.locked();
60925 var wrap2 = selection2.selectAll(".form-field-input-wrap").data([0]);
60926 wrap2 = wrap2.enter().append("div").attr("class", "form-field-input-wrap form-field-input-" + field.type).merge(wrap2);
60927 input = wrap2.selectAll(".localized-main").data([0]);
60928 input = input.enter().append("input").attr("type", "text").attr("id", field.domId).attr("class", "localized-main").call(utilNoAuto).merge(input);
60929 input.classed("disabled", !!isLocked).attr("readonly", isLocked || null).on("input", change(true)).on("blur", change()).on("change", change());
60930 wrap2.call(_lengthIndicator);
60931 var translateButton = wrap2.selectAll(".localized-add").data([0]);
60932 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);
60933 translateButton.classed("disabled", !!isLocked).call(isLocked ? _buttonTip.destroy : _buttonTip).on("click", addNew);
60934 if (_tags && !_multilingual.length) {
60935 calcMultilingual(_tags);
60937 localizedInputs = selection2.selectAll(".localized-multilingual").data([0]);
60938 localizedInputs = localizedInputs.enter().append("div").attr("class", "localized-multilingual").merge(localizedInputs);
60939 localizedInputs.call(renderMultilingual);
60940 localizedInputs.selectAll("button, input").classed("disabled", !!isLocked).attr("readonly", isLocked || null);
60941 selection2.selectAll(".combobox-caret").classed("nope", true);
60942 function addNew(d3_event) {
60943 d3_event.preventDefault();
60944 if (field.locked())
60946 var defaultLang = _mainLocalizer.languageCode().toLowerCase();
60947 var langExists = _multilingual.find(function(datum2) {
60948 return datum2.lang === defaultLang;
60950 var isLangEn = defaultLang.indexOf("en") > -1;
60951 if (isLangEn || langExists) {
60953 langExists = _multilingual.find(function(datum2) {
60954 return datum2.lang === defaultLang;
60958 _multilingual.unshift({ lang: defaultLang, value: "" });
60959 localizedInputs.call(renderMultilingual);
60962 function change(onInput) {
60963 return function(d3_event) {
60964 if (field.locked()) {
60965 d3_event.preventDefault();
60968 var val = utilGetSetValue(select_default2(this));
60970 val = context.cleanTagValue(val);
60971 if (!val && Array.isArray(_tags[field.key]))
60974 t[field.key] = val || void 0;
60975 dispatch10.call("change", this, t, onInput);
60979 function key(lang) {
60980 return field.key + ":" + lang;
60982 function changeLang(d3_event, d) {
60984 var lang = utilGetSetValue(select_default2(this)).toLowerCase();
60985 var language = _languagesArray.find(function(d2) {
60986 return d2.label.toLowerCase() === lang || d2.localName && d2.localName.toLowerCase() === lang || d2.nativeName && d2.nativeName.toLowerCase() === lang;
60989 lang = language.code;
60990 if (d.lang && d.lang !== lang) {
60991 tags[key(d.lang)] = void 0;
60993 var newKey = lang && context.cleanTagKey(key(lang));
60994 var value = utilGetSetValue(select_default2(this.parentNode).selectAll(".localized-value"));
60995 if (newKey && value) {
60996 tags[newKey] = value;
60997 } else if (newKey && _wikiTitles && _wikiTitles[d.lang]) {
60998 tags[newKey] = _wikiTitles[d.lang];
61001 dispatch10.call("change", this, tags);
61003 function changeValue(d3_event, d) {
61006 var value = context.cleanTagValue(utilGetSetValue(select_default2(this))) || void 0;
61007 if (!value && Array.isArray(d.value))
61010 t[key(d.lang)] = value;
61012 dispatch10.call("change", this, t);
61014 function fetchLanguages(value, cb) {
61015 var v = value.toLowerCase();
61016 var langCodes = [_mainLocalizer.localeCode(), _mainLocalizer.languageCode()];
61017 if (_countryCode && _territoryLanguages[_countryCode]) {
61018 langCodes = langCodes.concat(_territoryLanguages[_countryCode]);
61020 var langItems = [];
61021 langCodes.forEach(function(code) {
61022 var langItem = _languagesArray.find(function(item) {
61023 return item.code === code;
61026 langItems.push(langItem);
61028 langItems = utilArrayUniq(langItems.concat(_languagesArray));
61029 cb(langItems.filter(function(d) {
61030 return d.label.toLowerCase().indexOf(v) >= 0 || d.localName && d.localName.toLowerCase().indexOf(v) >= 0 || d.nativeName && d.nativeName.toLowerCase().indexOf(v) >= 0 || d.code.toLowerCase().indexOf(v) >= 0;
61031 }).map(function(d) {
61032 return { value: d.label };
61035 function renderMultilingual(selection2) {
61036 var entries = selection2.selectAll("div.entry").data(_multilingual, function(d) {
61039 entries.exit().style("top", "0").style("max-height", "240px").transition().duration(200).style("opacity", "0").style("max-height", "0px").remove();
61040 var entriesEnter = entries.enter().append("div").attr("class", "entry").each(function(_, index) {
61041 var wrap2 = select_default2(this);
61042 var domId = utilUniqueDomId(index);
61043 var label = wrap2.append("label").attr("class", "field-label").attr("for", domId);
61044 var text2 = label.append("span").attr("class", "label-text");
61045 text2.append("span").attr("class", "label-textvalue").call(_t.append("translate.localized_translation_label"));
61046 text2.append("span").attr("class", "label-textannotation");
61047 label.append("button").attr("class", "remove-icon-multilingual").attr("title", _t("icons.remove")).on("click", function(d3_event, d) {
61048 if (field.locked())
61050 d3_event.preventDefault();
61051 _multilingual.splice(_multilingual.indexOf(d), 1);
61052 var langKey = d.lang && key(d.lang);
61053 if (langKey && langKey in _tags) {
61054 delete _tags[langKey];
61056 t[langKey] = void 0;
61057 dispatch10.call("change", this, t);
61060 renderMultilingual(selection2);
61061 }).call(svgIcon("#iD-operation-delete"));
61062 wrap2.append("input").attr("class", "localized-lang").attr("id", domId).attr("type", "text").attr("placeholder", _t("translate.localized_translation_language")).on("blur", changeLang).on("change", changeLang).call(langCombo);
61063 wrap2.append("input").attr("type", "text").attr("class", "localized-value").on("blur", changeValue).on("change", changeValue);
61065 entriesEnter.style("margin-top", "0px").style("max-height", "0px").style("opacity", "0").transition().duration(200).style("margin-top", "10px").style("max-height", "240px").style("opacity", "1").on("end", function() {
61066 select_default2(this).style("max-height", "").style("overflow", "visible");
61068 entries = entries.merge(entriesEnter);
61070 entries.classed("present", true);
61071 utilGetSetValue(entries.select(".localized-lang"), function(d) {
61072 var langItem = _languagesArray.find(function(item) {
61073 return item.code === d.lang;
61076 return langItem.label;
61079 utilGetSetValue(entries.select(".localized-value"), function(d) {
61080 return typeof d.value === "string" ? d.value : "";
61081 }).attr("title", function(d) {
61082 return Array.isArray(d.value) ? d.value.filter(Boolean).join("\n") : null;
61083 }).attr("placeholder", function(d) {
61084 return Array.isArray(d.value) ? _t("inspector.multiple_values") : _t("translate.localized_translation_name");
61085 }).classed("mixed", function(d) {
61086 return Array.isArray(d.value);
61089 localized.tags = function(tags) {
61091 if (typeof tags.wikipedia === "string" && !_wikiTitles) {
61093 var wm = tags.wikipedia.match(/([^:]+):(.+)/);
61094 if (wm && wm[0] && wm[1]) {
61095 wikipedia.translations(wm[1], wm[2], function(err, d) {
61102 var isMixed = Array.isArray(tags[field.key]);
61103 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);
61104 calcMultilingual(tags);
61105 _selection.call(localized);
61107 _lengthIndicator.update(tags[field.key]);
61110 localized.focus = function() {
61111 input.node().focus();
61113 localized.entityIDs = function(val) {
61114 if (!arguments.length)
61117 _multilingual = [];
61121 function loadCountryCode() {
61122 var extent = combinedEntityExtent();
61123 var countryCode = extent && iso1A2Code(extent.center());
61124 _countryCode = countryCode && countryCode.toLowerCase();
61126 function combinedEntityExtent() {
61127 return _entityIDs && _entityIDs.length && utilTotalExtent(_entityIDs, context.graph());
61129 return utilRebind(localized, dispatch10, "on");
61132 // modules/ui/fields/roadheight.js
61133 function uiFieldRoadheight(field, context) {
61134 var dispatch10 = dispatch_default("change");
61135 var primaryUnitInput = select_default2(null);
61136 var primaryInput = select_default2(null);
61137 var secondaryInput = select_default2(null);
61138 var secondaryUnitInput = select_default2(null);
61139 var _entityIDs = [];
61142 var primaryUnits = [
61145 title: _t("inspector.roadheight.meter")
61149 title: _t("inspector.roadheight.foot")
61152 var unitCombo = uiCombobox(context, "roadheight-unit").data(primaryUnits);
61153 function roadheight(selection2) {
61154 var wrap2 = selection2.selectAll(".form-field-input-wrap").data([0]);
61155 wrap2 = wrap2.enter().append("div").attr("class", "form-field-input-wrap form-field-input-" + field.type).merge(wrap2);
61156 primaryInput = wrap2.selectAll("input.roadheight-number").data([0]);
61157 primaryInput = primaryInput.enter().append("input").attr("type", "text").attr("class", "roadheight-number").attr("id", field.domId).call(utilNoAuto).merge(primaryInput);
61158 primaryInput.on("change", change).on("blur", change);
61159 var loc = combinedEntityExtent().center();
61160 _isImperial = roadHeightUnit(loc) === "ft";
61161 primaryUnitInput = wrap2.selectAll("input.roadheight-unit").data([0]);
61162 primaryUnitInput = primaryUnitInput.enter().append("input").attr("type", "text").attr("class", "roadheight-unit").call(unitCombo).merge(primaryUnitInput);
61163 primaryUnitInput.on("blur", changeUnits).on("change", changeUnits);
61164 secondaryInput = wrap2.selectAll("input.roadheight-secondary-number").data([0]);
61165 secondaryInput = secondaryInput.enter().append("input").attr("type", "text").attr("class", "roadheight-secondary-number").call(utilNoAuto).merge(secondaryInput);
61166 secondaryInput.on("change", change).on("blur", change);
61167 secondaryUnitInput = wrap2.selectAll("input.roadheight-secondary-unit").data([0]);
61168 secondaryUnitInput = secondaryUnitInput.enter().append("input").attr("type", "text").call(utilNoAuto).classed("disabled", true).classed("roadheight-secondary-unit", true).attr("readonly", "readonly").merge(secondaryUnitInput);
61169 function changeUnits() {
61170 var primaryUnit = utilGetSetValue(primaryUnitInput);
61171 if (primaryUnit === "m") {
61172 _isImperial = false;
61173 } else if (primaryUnit === "ft") {
61174 _isImperial = true;
61176 utilGetSetValue(primaryUnitInput, _isImperial ? "ft" : "m");
61177 setUnitSuggestions();
61181 function setUnitSuggestions() {
61182 utilGetSetValue(primaryUnitInput, _isImperial ? "ft" : "m");
61184 function change() {
61186 var primaryValue = utilGetSetValue(primaryInput).trim();
61187 var secondaryValue = utilGetSetValue(secondaryInput).trim();
61188 if (!primaryValue && !secondaryValue && Array.isArray(_tags[field.key]))
61190 if (!primaryValue && !secondaryValue) {
61191 tag[field.key] = void 0;
61192 } else if (isNaN(primaryValue) || isNaN(secondaryValue) || !_isImperial) {
61193 tag[field.key] = context.cleanTagValue(primaryValue);
61195 if (primaryValue !== "") {
61196 primaryValue = context.cleanTagValue(primaryValue + "'");
61198 if (secondaryValue !== "") {
61199 secondaryValue = context.cleanTagValue(secondaryValue + '"');
61201 tag[field.key] = primaryValue + secondaryValue;
61203 dispatch10.call("change", this, tag);
61205 roadheight.tags = function(tags) {
61207 var primaryValue = tags[field.key];
61208 var secondaryValue;
61209 var isMixed = Array.isArray(primaryValue);
61211 if (primaryValue && (primaryValue.indexOf("'") >= 0 || primaryValue.indexOf('"') >= 0)) {
61212 secondaryValue = primaryValue.match(/(-?[\d.]+)"/);
61213 if (secondaryValue !== null) {
61214 secondaryValue = secondaryValue[1];
61216 primaryValue = primaryValue.match(/(-?[\d.]+)'/);
61217 if (primaryValue !== null) {
61218 primaryValue = primaryValue[1];
61220 _isImperial = true;
61221 } else if (primaryValue) {
61222 _isImperial = false;
61225 setUnitSuggestions();
61226 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);
61227 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");
61228 secondaryUnitInput.attr("value", _isImperial ? _t("inspector.roadheight.inch") : null);
61230 roadheight.focus = function() {
61231 primaryInput.node().focus();
61233 roadheight.entityIDs = function(val) {
61236 function combinedEntityExtent() {
61237 return _entityIDs && _entityIDs.length && utilTotalExtent(_entityIDs, context.graph());
61239 return utilRebind(roadheight, dispatch10, "on");
61242 // modules/ui/fields/roadspeed.js
61243 function uiFieldRoadspeed(field, context) {
61244 var dispatch10 = dispatch_default("change");
61245 var unitInput = select_default2(null);
61246 var input = select_default2(null);
61247 var _entityIDs = [];
61250 var speedCombo = uiCombobox(context, "roadspeed");
61251 var unitCombo = uiCombobox(context, "roadspeed-unit").data(["km/h", "mph"].map(comboValues));
61252 var metricValues = [20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120];
61253 var imperialValues = [5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80];
61254 function roadspeed(selection2) {
61255 var wrap2 = selection2.selectAll(".form-field-input-wrap").data([0]);
61256 wrap2 = wrap2.enter().append("div").attr("class", "form-field-input-wrap form-field-input-" + field.type).merge(wrap2);
61257 input = wrap2.selectAll("input.roadspeed-number").data([0]);
61258 input = input.enter().append("input").attr("type", "text").attr("class", "roadspeed-number").attr("id", field.domId).call(utilNoAuto).call(speedCombo).merge(input);
61259 input.on("change", change).on("blur", change);
61260 var loc = combinedEntityExtent().center();
61261 _isImperial = roadSpeedUnit(loc) === "mph";
61262 unitInput = wrap2.selectAll("input.roadspeed-unit").data([0]);
61263 unitInput = unitInput.enter().append("input").attr("type", "text").attr("class", "roadspeed-unit").attr("aria-label", _t("inspector.speed_unit")).call(unitCombo).merge(unitInput);
61264 unitInput.on("blur", changeUnits).on("change", changeUnits);
61265 function changeUnits() {
61266 var unit2 = utilGetSetValue(unitInput);
61267 if (unit2 === "km/h") {
61268 _isImperial = false;
61269 } else if (unit2 === "mph") {
61270 _isImperial = true;
61272 utilGetSetValue(unitInput, _isImperial ? "mph" : "km/h");
61273 setUnitSuggestions();
61277 function setUnitSuggestions() {
61278 speedCombo.data((_isImperial ? imperialValues : metricValues).map(comboValues));
61279 utilGetSetValue(unitInput, _isImperial ? "mph" : "km/h");
61281 function comboValues(d) {
61283 value: d.toString(),
61284 title: d.toString()
61287 function change() {
61289 var value = utilGetSetValue(input).trim();
61290 if (!value && Array.isArray(_tags[field.key]))
61293 tag[field.key] = void 0;
61294 } else if (isNaN(value) || !_isImperial) {
61295 tag[field.key] = context.cleanTagValue(value);
61297 tag[field.key] = context.cleanTagValue(value + " mph");
61299 dispatch10.call("change", this, tag);
61301 roadspeed.tags = function(tags) {
61303 var value = tags[field.key];
61304 var isMixed = Array.isArray(value);
61306 if (value && value.indexOf("mph") >= 0) {
61307 value = parseInt(value, 10).toString();
61308 _isImperial = true;
61309 } else if (value) {
61310 _isImperial = false;
61313 setUnitSuggestions();
61314 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);
61316 roadspeed.focus = function() {
61317 input.node().focus();
61319 roadspeed.entityIDs = function(val) {
61322 function combinedEntityExtent() {
61323 return _entityIDs && _entityIDs.length && utilTotalExtent(_entityIDs, context.graph());
61325 return utilRebind(roadspeed, dispatch10, "on");
61328 // modules/ui/fields/radio.js
61329 function uiFieldRadio(field, context) {
61330 var dispatch10 = dispatch_default("change");
61331 var placeholder = select_default2(null);
61332 var wrap2 = select_default2(null);
61333 var labels = select_default2(null);
61334 var radios = select_default2(null);
61335 var radioData = (field.options || field.keys).slice();
61339 var _entityIDs = [];
61340 function selectedKey() {
61341 var node = wrap2.selectAll(".form-field-input-radio label.active input");
61342 return !node.empty() && node.datum();
61344 function radio(selection2) {
61345 selection2.classed("preset-radio", true);
61346 wrap2 = selection2.selectAll(".form-field-input-wrap").data([0]);
61347 var enter = wrap2.enter().append("div").attr("class", "form-field-input-wrap form-field-input-radio");
61348 enter.append("span").attr("class", "placeholder");
61349 wrap2 = wrap2.merge(enter);
61350 placeholder = wrap2.selectAll(".placeholder");
61351 labels = wrap2.selectAll("label").data(radioData);
61352 enter = labels.enter().append("label");
61353 var stringsField = field.resolveReference("stringsCrossReference");
61354 enter.append("input").attr("type", "radio").attr("name", field.id).attr("value", function(d) {
61355 return stringsField.t("options." + d, { "default": d });
61356 }).attr("checked", false);
61357 enter.append("span").each(function(d) {
61358 stringsField.t.append("options." + d, { "default": d })(select_default2(this));
61360 labels = labels.merge(enter);
61361 radios = labels.selectAll("input").on("change", changeRadio);
61363 function structureExtras(selection2, tags) {
61364 var selected = selectedKey() || tags.layer !== void 0;
61365 var type2 = _mainPresetIndex.field(selected);
61366 var layer = _mainPresetIndex.field("layer");
61367 var showLayer = selected === "bridge" || selected === "tunnel" || tags.layer !== void 0;
61368 var extrasWrap = selection2.selectAll(".structure-extras-wrap").data(selected ? [0] : []);
61369 extrasWrap.exit().remove();
61370 extrasWrap = extrasWrap.enter().append("div").attr("class", "structure-extras-wrap").merge(extrasWrap);
61371 var list = extrasWrap.selectAll("ul").data([0]);
61372 list = list.enter().append("ul").attr("class", "rows").merge(list);
61374 if (!typeField || typeField.id !== selected) {
61375 typeField = uiField(context, type2, _entityIDs, { wrap: false }).on("change", changeType);
61377 typeField.tags(tags);
61381 var typeItem = list.selectAll(".structure-type-item").data(typeField ? [typeField] : [], function(d) {
61384 typeItem.exit().remove();
61385 var typeEnter = typeItem.enter().insert("li", ":first-child").attr("class", "labeled-input structure-type-item");
61386 typeEnter.append("span").attr("class", "label structure-label-type").attr("for", "preset-input-" + selected).call(_t.append("inspector.radio.structure.type"));
61387 typeEnter.append("div").attr("class", "structure-input-type-wrap");
61388 typeItem = typeItem.merge(typeEnter);
61390 typeItem.selectAll(".structure-input-type-wrap").call(typeField.render);
61392 if (layer && showLayer) {
61394 layerField = uiField(context, layer, _entityIDs, { wrap: false }).on("change", changeLayer);
61396 layerField.tags(tags);
61397 field.keys = utilArrayUnion(field.keys, ["layer"]);
61400 field.keys = field.keys.filter(function(k) {
61401 return k !== "layer";
61404 var layerItem = list.selectAll(".structure-layer-item").data(layerField ? [layerField] : []);
61405 layerItem.exit().remove();
61406 var layerEnter = layerItem.enter().append("li").attr("class", "labeled-input structure-layer-item");
61407 layerEnter.append("span").attr("class", "label structure-label-layer").attr("for", "preset-input-layer").call(_t.append("inspector.radio.structure.layer"));
61408 layerEnter.append("div").attr("class", "structure-input-layer-wrap");
61409 layerItem = layerItem.merge(layerEnter);
61411 layerItem.selectAll(".structure-input-layer-wrap").call(layerField.render);
61414 function changeType(t, onInput) {
61415 var key = selectedKey();
61419 if (val !== "no") {
61420 _oldType[key] = val;
61422 if (field.type === "structureRadio") {
61423 if (val === "no" || key !== "bridge" && key !== "tunnel" || key === "tunnel" && val === "building_passage") {
61426 if (t.layer === void 0) {
61427 if (key === "bridge" && val !== "no") {
61430 if (key === "tunnel" && val !== "no" && val !== "building_passage") {
61435 dispatch10.call("change", this, t, onInput);
61437 function changeLayer(t, onInput) {
61438 if (t.layer === "0") {
61441 dispatch10.call("change", this, t, onInput);
61443 function changeRadio() {
61447 t[field.key] = void 0;
61449 radios.each(function(d) {
61450 var active = select_default2(this).property("checked");
61457 var val = _oldType[activeKey] || "yes";
61458 t[d] = active ? val : void 0;
61461 if (field.type === "structureRadio") {
61462 if (activeKey === "bridge") {
61464 } else if (activeKey === "tunnel" && t.tunnel !== "building_passage") {
61470 dispatch10.call("change", this, t);
61472 radio.tags = function(tags) {
61473 function isOptionChecked(d) {
61475 return tags[field.key] === d;
61477 return !!(typeof tags[d] === "string" && tags[d].toLowerCase() !== "no");
61479 function isMixed(d) {
61481 return Array.isArray(tags[field.key]) && tags[field.key].includes(d);
61483 return Array.isArray(tags[d]);
61485 radios.property("checked", function(d) {
61486 return isOptionChecked(d) && (field.key || field.options.filter(isOptionChecked).length === 1);
61488 labels.classed("active", function(d) {
61490 return Array.isArray(tags[field.key]) && tags[field.key].includes(d) || tags[field.key] === d;
61492 return Array.isArray(tags[d]) && tags[d].some((v) => typeof v === "string" && v.toLowerCase() !== "no") || !!(typeof tags[d] === "string" && tags[d].toLowerCase() !== "no");
61493 }).classed("mixed", isMixed).attr("title", function(d) {
61494 return isMixed(d) ? _t("inspector.unshared_value_tooltip") : null;
61496 var selection2 = radios.filter(function() {
61497 return this.checked;
61499 if (selection2.empty()) {
61500 placeholder.text("");
61501 placeholder.call(_t.append("inspector.none"));
61503 placeholder.text(selection2.attr("value"));
61504 _oldType[selection2.datum()] = tags[selection2.datum()];
61506 if (field.type === "structureRadio") {
61507 if (!!tags.waterway && !_oldType.tunnel) {
61508 _oldType.tunnel = "culvert";
61510 wrap2.call(structureExtras, tags);
61513 radio.focus = function() {
61514 radios.node().focus();
61516 radio.entityIDs = function(val) {
61517 if (!arguments.length)
61523 radio.isAllowed = function() {
61524 return _entityIDs.length === 1;
61526 return utilRebind(radio, dispatch10, "on");
61529 // modules/ui/fields/restrictions.js
61530 function uiFieldRestrictions(field, context) {
61531 var dispatch10 = dispatch_default("change");
61532 var breathe = behaviorBreathe(context);
61533 corePreferences("turn-restriction-via-way", null);
61534 var storedViaWay = corePreferences("turn-restriction-via-way0");
61535 var storedDistance = corePreferences("turn-restriction-distance");
61536 var _maxViaWay = storedViaWay !== null ? +storedViaWay : 0;
61537 var _maxDistance = storedDistance ? +storedDistance : 30;
61538 var _initialized2 = false;
61539 var _parent = select_default2(null);
61540 var _container = select_default2(null);
61547 function restrictions(selection2) {
61548 _parent = selection2;
61549 if (_vertexID && (context.graph() !== _graph || !_intersection)) {
61550 _graph = context.graph();
61551 _intersection = osmIntersection(_graph, _vertexID, _maxDistance);
61553 var isOK = _intersection && _intersection.vertices.length && // has vertices
61554 _intersection.vertices.filter(function(vertex) {
61555 return vertex.id === _vertexID;
61556 }).length && _intersection.ways.length > 2 && // has more than 2 ways
61557 _intersection.ways.filter(function(way) {
61560 select_default2(selection2.node().parentNode).classed("hide", !isOK);
61561 if (!isOK || !context.container().select(".inspector-wrap.inspector-hidden").empty() || !selection2.node().parentNode || !selection2.node().parentNode.parentNode) {
61562 selection2.call(restrictions.off);
61565 var wrap2 = selection2.selectAll(".form-field-input-wrap").data([0]);
61566 wrap2 = wrap2.enter().append("div").attr("class", "form-field-input-wrap form-field-input-" + field.type).merge(wrap2);
61567 var container = wrap2.selectAll(".restriction-container").data([0]);
61568 var containerEnter = container.enter().append("div").attr("class", "restriction-container");
61569 containerEnter.append("div").attr("class", "restriction-help");
61570 _container = containerEnter.merge(container).call(renderViewer);
61571 var controls = wrap2.selectAll(".restriction-controls").data([0]);
61572 controls.enter().append("div").attr("class", "restriction-controls-container").append("div").attr("class", "restriction-controls").merge(controls).call(renderControls);
61574 function renderControls(selection2) {
61575 var distControl = selection2.selectAll(".restriction-distance").data([0]);
61576 distControl.exit().remove();
61577 var distControlEnter = distControl.enter().append("div").attr("class", "restriction-control restriction-distance");
61578 distControlEnter.append("span").attr("class", "restriction-control-label restriction-distance-label").call(_t.append("restriction.controls.distance", { suffix: ":" }));
61579 distControlEnter.append("input").attr("class", "restriction-distance-input").attr("type", "range").attr("min", "20").attr("max", "50").attr("step", "5");
61580 distControlEnter.append("span").attr("class", "restriction-distance-text");
61581 selection2.selectAll(".restriction-distance-input").property("value", _maxDistance).on("input", function() {
61582 var val = select_default2(this).property("value");
61583 _maxDistance = +val;
61584 _intersection = null;
61585 _container.selectAll(".layer-osm .layer-turns *").remove();
61586 corePreferences("turn-restriction-distance", _maxDistance);
61587 _parent.call(restrictions);
61589 selection2.selectAll(".restriction-distance-text").call(displayMaxDistance(_maxDistance));
61590 var viaControl = selection2.selectAll(".restriction-via-way").data([0]);
61591 viaControl.exit().remove();
61592 var viaControlEnter = viaControl.enter().append("div").attr("class", "restriction-control restriction-via-way");
61593 viaControlEnter.append("span").attr("class", "restriction-control-label restriction-via-way-label").call(_t.append("restriction.controls.via", { suffix: ":" }));
61594 viaControlEnter.append("input").attr("class", "restriction-via-way-input").attr("type", "range").attr("min", "0").attr("max", "2").attr("step", "1");
61595 viaControlEnter.append("span").attr("class", "restriction-via-way-text");
61596 selection2.selectAll(".restriction-via-way-input").property("value", _maxViaWay).on("input", function() {
61597 var val = select_default2(this).property("value");
61599 _container.selectAll(".layer-osm .layer-turns *").remove();
61600 corePreferences("turn-restriction-via-way0", _maxViaWay);
61601 _parent.call(restrictions);
61603 selection2.selectAll(".restriction-via-way-text").call(displayMaxVia(_maxViaWay));
61605 function renderViewer(selection2) {
61606 if (!_intersection)
61608 var vgraph = _intersection.graph;
61609 var filter2 = utilFunctor(true);
61610 var projection2 = geoRawMercator();
61611 var sdims = utilGetDimensions(context.container().select(".sidebar"));
61612 var d = [sdims[0] - 50, 370];
61613 var c = geoVecScale(d, 0.5);
61615 projection2.scale(geoZoomToScale(z));
61616 var extent = geoExtent();
61617 for (var i2 = 0; i2 < _intersection.vertices.length; i2++) {
61618 extent._extend(_intersection.vertices[i2].extent());
61621 if (_intersection.vertices.length > 1) {
61622 var hPadding = Math.min(160, Math.max(110, d[0] * 0.4));
61623 var vPadding = 160;
61624 var tl = projection2([extent[0][0], extent[1][1]]);
61625 var br = projection2([extent[1][0], extent[0][1]]);
61626 var hFactor = (br[0] - tl[0]) / (d[0] - hPadding);
61627 var vFactor = (br[1] - tl[1]) / (d[1] - vPadding - padTop);
61628 var hZoomDiff = Math.log(Math.abs(hFactor)) / Math.LN2;
61629 var vZoomDiff = Math.log(Math.abs(vFactor)) / Math.LN2;
61630 z = z - Math.max(hZoomDiff, vZoomDiff);
61631 projection2.scale(geoZoomToScale(z));
61633 var extentCenter = projection2(extent.center());
61634 extentCenter[1] = extentCenter[1] - padTop / 2;
61635 projection2.translate(geoVecSubtract(c, extentCenter)).clipExtent([[0, 0], d]);
61636 var drawLayers = svgLayers(projection2, context).only(["osm", "touch"]).dimensions(d);
61637 var drawVertices = svgVertices(projection2, context);
61638 var drawLines = svgLines(projection2, context);
61639 var drawTurns = svgTurns(projection2, context);
61640 var firstTime = selection2.selectAll(".surface").empty();
61641 selection2.call(drawLayers);
61642 var surface = selection2.selectAll(".surface").classed("tr", true);
61644 _initialized2 = true;
61645 surface.call(breathe);
61647 if (_fromWayID && !vgraph.hasEntity(_fromWayID)) {
61651 surface.call(utilSetDimensions, d).call(drawVertices, vgraph, _intersection.vertices, filter2, extent, z).call(drawLines, vgraph, _intersection.ways, filter2).call(drawTurns, vgraph, _intersection.turns(_fromWayID, _maxViaWay));
61652 surface.on("click.restrictions", click).on("mouseover.restrictions", mouseover);
61653 surface.selectAll(".selected").classed("selected", false);
61654 surface.selectAll(".related").classed("related", false);
61657 way = vgraph.entity(_fromWayID);
61658 surface.selectAll("." + _fromWayID).classed("selected", true).classed("related", true);
61660 document.addEventListener("resizeWindow", function() {
61661 utilSetDimensions(_container, null);
61665 function click(d3_event) {
61666 surface.call(breathe.off).call(breathe);
61667 var datum2 = d3_event.target.__data__;
61668 var entity = datum2 && datum2.properties && datum2.properties.entity;
61672 if (datum2 instanceof osmWay && (datum2.__from || datum2.__via)) {
61673 _fromWayID = datum2.id;
61676 } else if (datum2 instanceof osmTurn) {
61677 var actions, extraActions, turns, i3;
61678 var restrictionType = osmInferRestriction(vgraph, datum2, projection2);
61679 if (datum2.restrictionID && !datum2.direct) {
61681 } else if (datum2.restrictionID && !datum2.only) {
61683 var datumOnly = JSON.parse(JSON.stringify(datum2));
61684 datumOnly.only = true;
61685 restrictionType = restrictionType.replace(/^no/, "only");
61686 turns = _intersection.turns(_fromWayID, 2);
61689 for (i3 = 0; i3 < turns.length; i3++) {
61690 var turn = turns[i3];
61691 if (seen[turn.restrictionID])
61693 if (turn.direct && turn.path[1] === datum2.path[1]) {
61694 seen[turns[i3].restrictionID] = true;
61695 turn.restrictionType = osmInferRestriction(vgraph, turn, projection2);
61696 _oldTurns.push(turn);
61697 extraActions.push(actionUnrestrictTurn(turn));
61700 actions = _intersection.actions.concat(extraActions, [
61701 actionRestrictTurn(datumOnly, restrictionType),
61702 _t("operations.restriction.annotation.create")
61704 } else if (datum2.restrictionID) {
61705 turns = _oldTurns || [];
61707 for (i3 = 0; i3 < turns.length; i3++) {
61708 if (turns[i3].key !== datum2.key) {
61709 extraActions.push(actionRestrictTurn(turns[i3], turns[i3].restrictionType));
61713 actions = _intersection.actions.concat(extraActions, [
61714 actionUnrestrictTurn(datum2),
61715 _t("operations.restriction.annotation.delete")
61718 actions = _intersection.actions.concat([
61719 actionRestrictTurn(datum2, restrictionType),
61720 _t("operations.restriction.annotation.create")
61723 context.perform.apply(context, actions);
61724 var s = surface.selectAll("." + datum2.key);
61725 datum2 = s.empty() ? null : s.datum();
61726 updateHints(datum2);
61733 function mouseover(d3_event) {
61734 var datum2 = d3_event.target.__data__;
61735 updateHints(datum2);
61737 _lastXPos = _lastXPos || sdims[0];
61738 function redraw(minChange) {
61741 xPos = utilGetDimensions(context.container().select(".sidebar"))[0];
61743 if (!minChange || minChange && Math.abs(xPos - _lastXPos) >= minChange) {
61744 if (context.hasEntity(_vertexID)) {
61746 _container.call(renderViewer);
61750 function highlightPathsFrom(wayID) {
61751 surface.selectAll(".related").classed("related", false).classed("allow", false).classed("restrict", false).classed("only", false);
61752 surface.selectAll("." + wayID).classed("related", true);
61754 var turns = _intersection.turns(wayID, _maxViaWay);
61755 for (var i3 = 0; i3 < turns.length; i3++) {
61756 var turn = turns[i3];
61757 var ids = [turn.to.way];
61758 var klass = turn.no ? "restrict" : turn.only ? "only" : "allow";
61759 if (turn.only || turns.length === 1) {
61760 if (turn.via.ways) {
61761 ids = ids.concat(turn.via.ways);
61763 } else if (turn.to.way === wayID) {
61766 surface.selectAll(utilEntitySelector(ids)).classed("related", true).classed("allow", klass === "allow").classed("restrict", klass === "restrict").classed("only", klass === "only");
61770 function updateHints(datum2) {
61771 var help = _container.selectAll(".restriction-help").html("");
61772 var placeholders = {};
61773 ["from", "via", "to"].forEach(function(k) {
61774 placeholders[k] = { html: '<span class="qualifier">' + _t("restriction.help." + k) + "</span>" };
61776 var entity = datum2 && datum2.properties && datum2.properties.entity;
61781 way = vgraph.entity(_fromWayID);
61782 surface.selectAll("." + _fromWayID).classed("selected", true).classed("related", true);
61784 if (datum2 instanceof osmWay && datum2.__from) {
61786 highlightPathsFrom(_fromWayID ? null : way.id);
61787 surface.selectAll("." + way.id).classed("related", true);
61788 var clickSelect = !_fromWayID || _fromWayID !== way.id;
61789 help.append("div").html(_t.html("restriction.help." + (clickSelect ? "select_from_name" : "from_name"), {
61790 from: placeholders.from,
61791 fromName: displayName(way.id, vgraph)
61793 } else if (datum2 instanceof osmTurn) {
61794 var restrictionType = osmInferRestriction(vgraph, datum2, projection2);
61795 var turnType = restrictionType.replace(/^(only|no)\_/, "");
61796 var indirect = datum2.direct === false ? _t.html("restriction.help.indirect") : "";
61797 var klass, turnText, nextText;
61799 klass = "restrict";
61800 turnText = _t.html("restriction.help.turn.no_" + turnType, { indirect: { html: indirect } });
61801 nextText = _t.html("restriction.help.turn.only_" + turnType, { indirect: "" });
61802 } else if (datum2.only) {
61804 turnText = _t.html("restriction.help.turn.only_" + turnType, { indirect: { html: indirect } });
61805 nextText = _t.html("restriction.help.turn.allowed_" + turnType, { indirect: "" });
61808 turnText = _t.html("restriction.help.turn.allowed_" + turnType, { indirect: { html: indirect } });
61809 nextText = _t.html("restriction.help.turn.no_" + turnType, { indirect: "" });
61811 help.append("div").attr("class", "qualifier " + klass).html(turnText);
61812 help.append("div").html(_t.html("restriction.help.from_name_to_name", {
61813 from: placeholders.from,
61814 fromName: displayName(datum2.from.way, vgraph),
61815 to: placeholders.to,
61816 toName: displayName(datum2.to.way, vgraph)
61818 if (datum2.via.ways && datum2.via.ways.length) {
61820 for (var i3 = 0; i3 < datum2.via.ways.length; i3++) {
61821 var prev = names[names.length - 1];
61822 var curr = displayName(datum2.via.ways[i3], vgraph);
61823 if (!prev || curr !== prev) {
61827 help.append("div").html(_t.html("restriction.help.via_names", {
61828 via: placeholders.via,
61829 viaNames: names.join(", ")
61833 help.append("div").html(_t.html("restriction.help.toggle", { turn: { html: nextText.trim() } }));
61835 highlightPathsFrom(null);
61836 var alongIDs = datum2.path.slice();
61837 surface.selectAll(utilEntitySelector(alongIDs)).classed("related", true).classed("allow", klass === "allow").classed("restrict", klass === "restrict").classed("only", klass === "only");
61839 highlightPathsFrom(null);
61841 help.append("div").html(_t.html("restriction.help.from_name", {
61842 from: placeholders.from,
61843 fromName: displayName(_fromWayID, vgraph)
61846 help.append("div").html(_t.html("restriction.help.select_from", {
61847 from: placeholders.from
61853 function displayMaxDistance(maxDist) {
61854 return (selection2) => {
61855 var isImperial = !_mainLocalizer.usesMetric();
61859 // imprecise conversion for prettier display
61868 opts = { distance: _t("units.feet", { quantity: distToFeet }) };
61870 opts = { distance: _t("units.meters", { quantity: maxDist }) };
61872 return selection2.html("").call(_t.append("restriction.controls.distance_up_to", opts));
61875 function displayMaxVia(maxVia) {
61876 return (selection2) => {
61877 selection2 = selection2.html("");
61878 return maxVia === 0 ? selection2.call(_t.append("restriction.controls.via_node_only")) : maxVia === 1 ? selection2.call(_t.append("restriction.controls.via_up_to_one")) : selection2.call(_t.append("restriction.controls.via_up_to_two"));
61881 function displayName(entityID, graph) {
61882 var entity = graph.entity(entityID);
61883 var name = utilDisplayName(entity) || "";
61884 var matched = _mainPresetIndex.match(entity, graph);
61885 var type2 = matched && matched.name() || utilDisplayType(entity.id);
61886 return name || type2;
61888 restrictions.entityIDs = function(val) {
61889 _intersection = null;
61892 _vertexID = val[0];
61894 restrictions.tags = function() {
61896 restrictions.focus = function() {
61898 restrictions.off = function(selection2) {
61899 if (!_initialized2)
61901 selection2.selectAll(".surface").call(breathe.off).on("click.restrictions", null).on("mouseover.restrictions", null);
61902 select_default2(window).on("resize.restrictions", null);
61904 return utilRebind(restrictions, dispatch10, "on");
61906 uiFieldRestrictions.supportsMultiselection = false;
61908 // modules/ui/fields/textarea.js
61909 function uiFieldTextarea(field, context) {
61910 var dispatch10 = dispatch_default("change");
61911 var input = select_default2(null);
61912 var _lengthIndicator = uiLengthIndicator(context.maxCharsForTagValue()).silent(field.usage === "changeset" && field.key === "comment");
61914 function textarea(selection2) {
61915 var wrap2 = selection2.selectAll(".form-field-input-wrap").data([0]);
61916 wrap2 = wrap2.enter().append("div").attr("class", "form-field-input-wrap form-field-input-" + field.type).style("position", "relative").merge(wrap2);
61917 input = wrap2.selectAll("textarea").data([0]);
61918 input = input.enter().append("textarea").attr("id", field.domId).call(utilNoAuto).on("input", change(true)).on("blur", change()).on("change", change()).merge(input);
61919 wrap2.call(_lengthIndicator);
61920 function change(onInput) {
61921 return function() {
61922 var val = utilGetSetValue(input);
61924 val = context.cleanTagValue(val);
61925 if (!val && Array.isArray(_tags[field.key]))
61928 t[field.key] = val || void 0;
61929 dispatch10.call("change", this, t, onInput);
61933 textarea.tags = function(tags) {
61935 var isMixed = Array.isArray(tags[field.key]);
61936 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);
61938 _lengthIndicator.update(tags[field.key]);
61941 textarea.focus = function() {
61942 input.node().focus();
61944 return utilRebind(textarea, dispatch10, "on");
61947 // modules/ui/fields/wikidata.js
61948 function uiFieldWikidata(field, context) {
61949 var wikidata = services.wikidata;
61950 var dispatch10 = dispatch_default("change");
61951 var _selection = select_default2(null);
61952 var _searchInput = select_default2(null);
61954 var _wikidataEntity = null;
61956 var _entityIDs = [];
61957 var _wikipediaKey = field.keys && field.keys.find(function(key) {
61958 return key.includes("wikipedia");
61960 var _hintKey = field.key === "wikidata" ? "name" : field.key.split(":")[0];
61961 var combobox = uiCombobox(context, "combo-" + field.safeid).caseSensitive(true).minItems(1);
61962 function wiki(selection2) {
61963 _selection = selection2;
61964 var wrap2 = selection2.selectAll(".form-field-input-wrap").data([0]);
61965 wrap2 = wrap2.enter().append("div").attr("class", "form-field-input-wrap form-field-input-" + field.type).merge(wrap2);
61966 var list = wrap2.selectAll("ul").data([0]);
61967 list = list.enter().append("ul").attr("class", "rows").merge(list);
61968 var searchRow = list.selectAll("li.wikidata-search").data([0]);
61969 var searchRowEnter = searchRow.enter().append("li").attr("class", "wikidata-search");
61970 searchRowEnter.append("input").attr("type", "text").attr("id", field.domId).style("flex", "1").call(utilNoAuto).on("focus", function() {
61971 var node = select_default2(this).node();
61972 node.setSelectionRange(0, node.value.length);
61973 }).on("blur", function() {
61974 setLabelForEntity();
61975 }).call(combobox.fetcher(fetchWikidataItems));
61976 combobox.on("accept", function(d) {
61981 }).on("cancel", function() {
61982 setLabelForEntity();
61984 searchRowEnter.append("button").attr("class", "form-field-button wiki-link").attr("title", _t("icons.view_on", { domain: "wikidata.org" })).call(svgIcon("#iD-icon-out-link")).on("click", function(d3_event) {
61985 d3_event.preventDefault();
61987 window.open(_wikiURL, "_blank");
61989 searchRow = searchRow.merge(searchRowEnter);
61990 _searchInput = searchRow.select("input");
61991 var wikidataProperties = ["description", "identifier"];
61992 var items = list.selectAll("li.labeled-input").data(wikidataProperties);
61993 var enter = items.enter().append("li").attr("class", function(d) {
61994 return "labeled-input preset-wikidata-" + d;
61996 enter.append("span").attr("class", "label").html(function(d) {
61997 return _t.html("wikidata." + d);
61999 enter.append("input").attr("type", "text").call(utilNoAuto).classed("disabled", "true").attr("readonly", "true");
62000 enter.append("button").attr("class", "form-field-button").attr("title", _t("icons.copy")).call(svgIcon("#iD-operation-copy")).on("click", function(d3_event) {
62001 d3_event.preventDefault();
62002 select_default2(this.parentNode).select("input").node().select();
62003 document.execCommand("copy");
62006 function fetchWikidataItems(q, callback) {
62007 if (!q && _hintKey) {
62008 for (var i2 in _entityIDs) {
62009 var entity = context.hasEntity(_entityIDs[i2]);
62010 if (entity.tags[_hintKey]) {
62011 q = entity.tags[_hintKey];
62016 wikidata.itemsForSearchQuery(q, function(err, data) {
62019 var result = data.map(function(item) {
62022 value: item.display.label.value + " (" + item.id + ")",
62023 display: (selection2) => selection2.append("span").attr("class", "localized-text").attr("lang", item.display.label.language).text(item.display.label.value),
62024 title: item.display.description && item.display.description.value,
62025 terms: item.aliases
62032 function change() {
62034 syncTags[field.key] = _qid;
62035 dispatch10.call("change", this, syncTags);
62036 var initGraph = context.graph();
62037 var initEntityIDs = _entityIDs;
62038 wikidata.entityByQID(_qid, function(err, entity) {
62041 if (context.graph() !== initGraph)
62043 if (!entity.sitelinks)
62045 var langs = wikidata.languagesToQuery();
62046 ["labels", "descriptions"].forEach(function(key) {
62049 var valueLangs = Object.keys(entity[key]);
62050 if (valueLangs.length === 0)
62052 var valueLang = valueLangs[0];
62053 if (langs.indexOf(valueLang) === -1) {
62054 langs.push(valueLang);
62057 var newWikipediaValue;
62058 if (_wikipediaKey) {
62059 var foundPreferred;
62060 for (var i2 in langs) {
62061 var lang = langs[i2];
62062 var siteID = lang.replace("-", "_") + "wiki";
62063 if (entity.sitelinks[siteID]) {
62064 foundPreferred = true;
62065 newWikipediaValue = lang + ":" + entity.sitelinks[siteID].title;
62069 if (!foundPreferred) {
62070 var wikiSiteKeys = Object.keys(entity.sitelinks).filter(function(site) {
62071 return site.endsWith("wiki");
62073 if (wikiSiteKeys.length === 0) {
62074 newWikipediaValue = null;
62076 var wikiLang = wikiSiteKeys[0].slice(0, -4).replace("_", "-");
62077 var wikiTitle = entity.sitelinks[wikiSiteKeys[0]].title;
62078 newWikipediaValue = wikiLang + ":" + wikiTitle;
62082 if (newWikipediaValue) {
62083 newWikipediaValue = context.cleanTagValue(newWikipediaValue);
62085 if (typeof newWikipediaValue === "undefined")
62087 var actions = initEntityIDs.map(function(entityID) {
62088 var entity2 = context.hasEntity(entityID);
62091 var currTags = Object.assign({}, entity2.tags);
62092 if (newWikipediaValue === null) {
62093 if (!currTags[_wikipediaKey])
62095 delete currTags[_wikipediaKey];
62097 currTags[_wikipediaKey] = newWikipediaValue;
62099 return actionChangeTags(entityID, currTags);
62100 }).filter(Boolean);
62101 if (!actions.length)
62104 function actionUpdateWikipediaTags(graph) {
62105 actions.forEach(function(action) {
62106 graph = action(graph);
62110 context.history().undoAnnotation()
62114 function setLabelForEntity() {
62116 if (_wikidataEntity) {
62117 label = entityPropertyForDisplay(_wikidataEntity, "labels");
62118 if (label.length === 0) {
62119 label = _wikidataEntity.id.toString();
62122 utilGetSetValue(_searchInput, label);
62124 wiki.tags = function(tags) {
62125 var isMixed = Array.isArray(tags[field.key]);
62126 _searchInput.attr("title", isMixed ? tags[field.key].filter(Boolean).join("\n") : null).attr("placeholder", isMixed ? _t("inspector.multiple_values") : "").classed("mixed", isMixed);
62127 _qid = typeof tags[field.key] === "string" && tags[field.key] || "";
62128 if (!/^Q[0-9]*$/.test(_qid)) {
62132 _wikiURL = "https://wikidata.org/wiki/" + _qid;
62133 wikidata.entityByQID(_qid, function(err, entity) {
62138 _wikidataEntity = entity;
62139 setLabelForEntity();
62140 var description = entityPropertyForDisplay(entity, "descriptions");
62141 _selection.select("button.wiki-link").classed("disabled", false);
62142 _selection.select(".preset-wikidata-description").style("display", function() {
62143 return description.length > 0 ? "flex" : "none";
62144 }).select("input").attr("value", description);
62145 _selection.select(".preset-wikidata-identifier").style("display", function() {
62146 return entity.id ? "flex" : "none";
62147 }).select("input").attr("value", entity.id);
62149 function unrecognized() {
62150 _wikidataEntity = null;
62151 setLabelForEntity();
62152 _selection.select(".preset-wikidata-description").style("display", "none");
62153 _selection.select(".preset-wikidata-identifier").style("display", "none");
62154 _selection.select("button.wiki-link").classed("disabled", true);
62155 if (_qid && _qid !== "") {
62156 _wikiURL = "https://wikidata.org/wiki/Special:Search?search=" + _qid;
62162 function entityPropertyForDisplay(wikidataEntity, propKey) {
62163 if (!wikidataEntity[propKey])
62165 var propObj = wikidataEntity[propKey];
62166 var langKeys = Object.keys(propObj);
62167 if (langKeys.length === 0)
62169 var langs = wikidata.languagesToQuery();
62170 for (var i2 in langs) {
62171 var lang = langs[i2];
62172 var valueObj = propObj[lang];
62173 if (valueObj && valueObj.value && valueObj.value.length > 0)
62174 return valueObj.value;
62176 return propObj[langKeys[0]].value;
62178 wiki.entityIDs = function(val) {
62179 if (!arguments.length)
62184 wiki.focus = function() {
62185 _searchInput.node().focus();
62187 return utilRebind(wiki, dispatch10, "on");
62190 // modules/ui/fields/wikipedia.js
62191 function uiFieldWikipedia(field, context) {
62192 const dispatch10 = dispatch_default("change");
62193 const wikipedia = services.wikipedia;
62194 const wikidata = services.wikidata;
62195 let _langInput = select_default2(null);
62196 let _titleInput = select_default2(null);
62200 let _dataWikipedia = [];
62201 _mainFileFetcher.get("wmf_sitematrix").then((d) => {
62202 _dataWikipedia = d;
62204 updateForTags(_tags);
62207 const langCombo = uiCombobox(context, "wikipedia-lang").fetcher((value, callback) => {
62208 const v = value.toLowerCase();
62210 _dataWikipedia.filter((d) => {
62211 return d[0].toLowerCase().indexOf(v) >= 0 || d[1].toLowerCase().indexOf(v) >= 0 || d[2].toLowerCase().indexOf(v) >= 0;
62212 }).map((d) => ({ value: d[1] }))
62215 const titleCombo = uiCombobox(context, "wikipedia-title").fetcher((value, callback) => {
62218 for (let i2 in _entityIDs) {
62219 let entity = context.hasEntity(_entityIDs[i2]);
62220 if (entity.tags.name) {
62221 value = entity.tags.name;
62226 const searchfn = value.length > 7 ? wikipedia.search : wikipedia.suggestions;
62227 searchfn(language()[2], value, (query, data) => {
62228 callback(data.map((d) => ({ value: d })));
62231 function wiki(selection2) {
62232 let wrap2 = selection2.selectAll(".form-field-input-wrap").data([0]);
62233 wrap2 = wrap2.enter().append("div").attr("class", `form-field-input-wrap form-field-input-${field.type}`).merge(wrap2);
62234 let langContainer = wrap2.selectAll(".wiki-lang-container").data([0]);
62235 langContainer = langContainer.enter().append("div").attr("class", "wiki-lang-container").merge(langContainer);
62236 _langInput = langContainer.selectAll("input.wiki-lang").data([0]);
62237 _langInput = _langInput.enter().append("input").attr("type", "text").attr("class", "wiki-lang").attr("placeholder", _t("translate.localized_translation_language")).call(utilNoAuto).call(langCombo).merge(_langInput);
62238 _langInput.on("blur", changeLang).on("change", changeLang);
62239 let titleContainer = wrap2.selectAll(".wiki-title-container").data([0]);
62240 titleContainer = titleContainer.enter().append("div").attr("class", "wiki-title-container").merge(titleContainer);
62241 _titleInput = titleContainer.selectAll("input.wiki-title").data([0]);
62242 _titleInput = _titleInput.enter().append("input").attr("type", "text").attr("class", "wiki-title").attr("id", field.domId).call(utilNoAuto).call(titleCombo).merge(_titleInput);
62243 _titleInput.on("blur", function() {
62245 }).on("change", function() {
62248 let link2 = titleContainer.selectAll(".wiki-link").data([0]);
62249 link2 = link2.enter().append("button").attr("class", "form-field-button wiki-link").attr("title", _t("icons.view_on", { domain: "wikipedia.org" })).call(svgIcon("#iD-icon-out-link")).merge(link2);
62250 link2.on("click", (d3_event) => {
62251 d3_event.preventDefault();
62253 window.open(_wikiURL, "_blank");
62256 function defaultLanguageInfo(skipEnglishFallback) {
62257 const langCode = _mainLocalizer.languageCode().toLowerCase();
62258 for (let i2 in _dataWikipedia) {
62259 let d = _dataWikipedia[i2];
62260 if (d[2] === langCode)
62263 return skipEnglishFallback ? ["", "", ""] : ["English", "English", "en"];
62265 function language(skipEnglishFallback) {
62266 const value = utilGetSetValue(_langInput).toLowerCase();
62267 for (let i2 in _dataWikipedia) {
62268 let d = _dataWikipedia[i2];
62269 if (d[0].toLowerCase() === value || d[1].toLowerCase() === value || d[2] === value)
62272 return defaultLanguageInfo(skipEnglishFallback);
62274 function changeLang() {
62275 utilGetSetValue(_langInput, language()[1]);
62278 function change(skipWikidata) {
62279 let value = utilGetSetValue(_titleInput);
62280 const m = value.match(/https?:\/\/([-a-z]+)\.wikipedia\.org\/(?:wiki|\1-[-a-z]+)\/([^#]+)(?:#(.+))?/);
62281 const langInfo = m && _dataWikipedia.find((d) => m[1] === d[2]);
62284 const nativeLangName = langInfo[1];
62285 value = decodeURIComponent(m[2]).replace(/_/g, " ");
62288 anchor = decodeURIComponent(m[3]);
62289 value += "#" + anchor.replace(/_/g, " ");
62291 value = value.slice(0, 1).toUpperCase() + value.slice(1);
62292 utilGetSetValue(_langInput, nativeLangName);
62293 utilGetSetValue(_titleInput, value);
62296 syncTags.wikipedia = context.cleanTagValue(language()[2] + ":" + value);
62298 syncTags.wikipedia = void 0;
62300 dispatch10.call("change", this, syncTags);
62301 if (skipWikidata || !value || !language()[2])
62303 const initGraph = context.graph();
62304 const initEntityIDs = _entityIDs;
62305 wikidata.itemsByTitle(language()[2], value, (err, data) => {
62306 if (err || !data || !Object.keys(data).length)
62308 if (context.graph() !== initGraph)
62310 const qids = Object.keys(data);
62311 const value2 = qids && qids.find((id2) => id2.match(/^Q\d+$/));
62312 let actions = initEntityIDs.map((entityID) => {
62313 let entity = context.entity(entityID).tags;
62314 let currTags = Object.assign({}, entity);
62315 if (currTags.wikidata !== value2) {
62316 currTags.wikidata = value2;
62317 return actionChangeTags(entityID, currTags);
62320 }).filter(Boolean);
62321 if (!actions.length)
62324 function actionUpdateWikidataTags(graph) {
62325 actions.forEach(function(action) {
62326 graph = action(graph);
62330 context.history().undoAnnotation()
62334 wiki.tags = (tags) => {
62336 updateForTags(tags);
62338 function updateForTags(tags) {
62339 const value = typeof tags[field.key] === "string" ? tags[field.key] : "";
62340 const m = value.match(/([^:]+):([^#]+)(?:#(.+))?/);
62341 const tagLang = m && m[1];
62342 const tagArticleTitle = m && m[2];
62343 let anchor = m && m[3];
62344 const tagLangInfo = tagLang && _dataWikipedia.find((d) => tagLang === d[2]);
62346 const nativeLangName = tagLangInfo[1];
62347 utilGetSetValue(_langInput, nativeLangName);
62348 utilGetSetValue(_titleInput, tagArticleTitle + (anchor ? "#" + anchor : ""));
62351 anchor = encodeURIComponent(anchor.replace(/ /g, "_")).replace(/%/g, ".");
62353 anchor = anchor.replace(/ /g, "_");
62356 _wikiURL = "https://" + tagLang + ".wikipedia.org/wiki/" + tagArticleTitle.replace(/ /g, "_") + (anchor ? "#" + anchor : "");
62358 utilGetSetValue(_titleInput, value);
62359 if (value && value !== "") {
62360 utilGetSetValue(_langInput, "");
62361 const defaultLangInfo = defaultLanguageInfo();
62362 _wikiURL = `https://${defaultLangInfo[2]}.wikipedia.org/w/index.php?fulltext=1&search=${value}`;
62364 const shownOrDefaultLangInfo = language(
62366 /* skipEnglishFallback */
62368 utilGetSetValue(_langInput, shownOrDefaultLangInfo[1]);
62373 wiki.entityIDs = (val) => {
62374 if (!arguments.length)
62379 wiki.focus = () => {
62380 _titleInput.node().focus();
62382 return utilRebind(wiki, dispatch10, "on");
62384 uiFieldWikipedia.supportsMultiselection = false;
62386 // modules/ui/fields/index.js
62388 access: uiFieldAccess,
62389 address: uiFieldAddress,
62390 check: uiFieldCheck,
62391 colour: uiFieldText,
62392 combo: uiFieldCombo,
62393 cycleway: uiFieldDirectionalCombo,
62395 defaultCheck: uiFieldCheck,
62396 directionalCombo: uiFieldDirectionalCombo,
62397 email: uiFieldText,
62398 identifier: uiFieldText,
62399 lanes: uiFieldLanes,
62400 localized: uiFieldLocalized,
62401 roadheight: uiFieldRoadheight,
62402 roadspeed: uiFieldRoadspeed,
62403 manyCombo: uiFieldCombo,
62404 multiCombo: uiFieldCombo,
62405 networkCombo: uiFieldCombo,
62406 number: uiFieldText,
62407 onewayCheck: uiFieldCheck,
62408 radio: uiFieldRadio,
62409 restrictions: uiFieldRestrictions,
62410 semiCombo: uiFieldCombo,
62411 structureRadio: uiFieldRadio,
62414 textarea: uiFieldTextarea,
62415 typeCombo: uiFieldCombo,
62417 wikidata: uiFieldWikidata,
62418 wikipedia: uiFieldWikipedia
62421 // modules/ui/field.js
62422 function uiField(context, presetField2, entityIDs, options2) {
62423 options2 = Object.assign({
62430 var dispatch10 = dispatch_default("change", "revert");
62431 var field = Object.assign({}, presetField2);
62432 field.domId = utilUniqueDomId("form-field-" + field.safeid);
62433 var _show = options2.show;
62437 if (entityIDs && entityIDs.length) {
62438 _entityExtent = entityIDs.reduce(function(extent, entityID) {
62439 var entity = context.graph().entity(entityID);
62440 return extent.extend(entity.extent(context.graph()));
62443 var _locked = false;
62444 var _lockedTip = uiTooltip().title(() => _t.append("inspector.lock.suggestion", { label: field.title })).placement("bottom");
62445 if (_show && !field.impl) {
62448 function createField() {
62449 field.impl = uiFields[field.type](field, context).on("change", function(t, onInput) {
62450 dispatch10.call("change", field, t, onInput);
62453 field.entityIDs = entityIDs;
62454 if (field.impl.entityIDs) {
62455 field.impl.entityIDs(entityIDs);
62459 function allKeys() {
62460 let keys = field.keys || [field.key];
62461 if (field.type === "directionalCombo" && field.key) {
62462 keys = keys.concat(field.key);
62466 function isModified() {
62467 if (!entityIDs || !entityIDs.length)
62469 return entityIDs.some(function(entityID) {
62470 var original = context.graph().base().entities[entityID];
62471 var latest = context.graph().entity(entityID);
62472 return allKeys().some(function(key) {
62473 return original ? latest.tags[key] !== original.tags[key] : latest.tags[key];
62477 function tagsContainFieldKey() {
62478 return allKeys().some(function(key) {
62479 if (field.type === "multiCombo") {
62480 for (var tagKey in _tags) {
62481 if (tagKey.indexOf(key) === 0) {
62487 return _tags[key] !== void 0;
62490 function revert(d3_event, d) {
62491 d3_event.stopPropagation();
62492 d3_event.preventDefault();
62493 if (!entityIDs || _locked)
62495 dispatch10.call("revert", d, allKeys());
62497 function remove2(d3_event, d) {
62498 d3_event.stopPropagation();
62499 d3_event.preventDefault();
62503 allKeys().forEach(function(key) {
62506 dispatch10.call("change", d, t);
62508 field.render = function(selection2) {
62509 var container = selection2.selectAll(".form-field").data([field]);
62510 var enter = container.enter().append("div").attr("class", function(d) {
62511 return "form-field form-field-" + d.safeid;
62512 }).classed("nowrap", !options2.wrap);
62513 if (options2.wrap) {
62514 var labelEnter = enter.append("label").attr("class", "field-label").attr("for", function(d) {
62517 var textEnter = labelEnter.append("span").attr("class", "label-text");
62518 textEnter.append("span").attr("class", "label-textvalue").each(function(d) {
62519 d.label()(select_default2(this));
62521 textEnter.append("span").attr("class", "label-textannotation");
62522 if (options2.remove) {
62523 labelEnter.append("button").attr("class", "remove-icon").attr("title", _t("icons.remove")).call(svgIcon("#iD-operation-delete"));
62525 if (options2.revert) {
62526 labelEnter.append("button").attr("class", "modified-icon").attr("title", _t("icons.undo")).call(svgIcon(_mainLocalizer.textDirection() === "rtl" ? "#iD-icon-redo" : "#iD-icon-undo"));
62529 container = container.merge(enter);
62530 container.select(".field-label > .remove-icon").on("click", remove2);
62531 container.select(".field-label > .modified-icon").on("click", revert);
62532 container.each(function(d) {
62533 var selection3 = select_default2(this);
62537 var reference, help;
62538 if (options2.wrap && field.type === "restrictions") {
62539 help = uiFieldHelp(context, "restrictions");
62541 if (options2.wrap && options2.info) {
62542 var referenceKey = d.key || "";
62543 if (d.type === "multiCombo") {
62544 referenceKey = referenceKey.replace(/:$/, "");
62546 reference = uiTagReference(d.reference || { key: referenceKey }, context);
62547 if (_state === "hover") {
62548 reference.showing(false);
62551 selection3.call(d.impl);
62553 selection3.call(help.body).select(".field-label").call(help.button);
62556 selection3.call(reference.body).select(".field-label").call(reference.button);
62558 d.impl.tags(_tags);
62560 container.classed("locked", _locked).classed("modified", isModified()).classed("present", tagsContainFieldKey());
62561 var annotation = container.selectAll(".field-label .label-textannotation");
62562 var icon2 = annotation.selectAll(".icon").data(_locked ? [0] : []);
62563 icon2.exit().remove();
62564 icon2.enter().append("svg").attr("class", "icon").append("use").attr("xlink:href", "#fas-lock");
62565 container.call(_locked ? _lockedTip : _lockedTip.destroy);
62567 field.state = function(val) {
62568 if (!arguments.length)
62573 field.tags = function(val) {
62574 if (!arguments.length)
62577 if (tagsContainFieldKey() && !_show) {
62585 field.locked = function(val) {
62586 if (!arguments.length)
62591 field.show = function() {
62596 if (field.default && field.key && _tags[field.key] !== field.default) {
62598 t[field.key] = field.default;
62599 dispatch10.call("change", this, t);
62602 field.isShown = function() {
62605 field.isAllowed = function() {
62606 if (entityIDs && entityIDs.length > 1 && uiFields[field.type].supportsMultiselection === false)
62608 if (field.geometry && !entityIDs.every(function(entityID) {
62609 return field.matchGeometry(context.graph().geometry(entityID));
62612 if (entityIDs && _entityExtent && field.locationSetID) {
62613 var validHere = _sharedLocationManager.locationSetsAt(_entityExtent.center());
62614 if (!validHere[field.locationSetID])
62617 var prerequisiteTag = field.prerequisiteTag;
62618 if (entityIDs && !tagsContainFieldKey() && // ignore tagging prerequisites if a value is already present
62620 if (!entityIDs.every(function(entityID) {
62621 var entity = context.graph().entity(entityID);
62622 if (prerequisiteTag.key) {
62623 var value = entity.tags[prerequisiteTag.key];
62626 if (prerequisiteTag.valueNot) {
62627 return prerequisiteTag.valueNot !== value;
62629 if (prerequisiteTag.value) {
62630 return prerequisiteTag.value === value;
62632 } else if (prerequisiteTag.keyNot) {
62633 if (entity.tags[prerequisiteTag.keyNot])
62642 field.focus = function() {
62644 field.impl.focus();
62647 return utilRebind(field, dispatch10, "on");
62650 // modules/ui/form_fields.js
62651 function uiFormFields(context) {
62652 var moreCombo = uiCombobox(context, "more-fields").minItems(1);
62653 var _fieldsArr = [];
62654 var _lastPlaceholder = "";
62657 function formFields(selection2) {
62658 var allowedFields = _fieldsArr.filter(function(field) {
62659 return field.isAllowed();
62661 var shown = allowedFields.filter(function(field) {
62662 return field.isShown();
62664 var notShown = allowedFields.filter(function(field) {
62665 return !field.isShown();
62667 var container = selection2.selectAll(".form-fields-container").data([0]);
62668 container = container.enter().append("div").attr("class", "form-fields-container " + (_klass || "")).merge(container);
62669 var fields = container.selectAll(".wrap-form-field").data(shown, function(d) {
62670 return d.id + (d.entityIDs ? d.entityIDs.join() : "");
62672 fields.exit().remove();
62673 var enter = fields.enter().append("div").attr("class", function(d) {
62674 return "wrap-form-field wrap-form-field-" + d.safeid;
62676 fields = fields.merge(enter);
62677 fields.order().each(function(d) {
62678 select_default2(this).call(d.render);
62681 var moreFields = notShown.map(function(field) {
62682 var title = field.title();
62683 titles.push(title);
62684 var terms = field.terms();
62686 terms.push(field.key);
62688 terms = terms.concat(field.keys);
62690 display: field.label(),
62697 var placeholder = titles.slice(0, 3).join(", ") + (titles.length > 3 ? "\u2026" : "");
62698 var more = selection2.selectAll(".more-fields").data(_state === "hover" || moreFields.length === 0 ? [] : [0]);
62699 more.exit().remove();
62700 var moreEnter = more.enter().append("div").attr("class", "more-fields").append("label");
62701 moreEnter.append("span").call(_t.append("inspector.add_fields"));
62702 more = moreEnter.merge(more);
62703 var input = more.selectAll(".value").data([0]);
62704 input.exit().remove();
62705 input = input.enter().append("input").attr("class", "value").attr("type", "text").attr("placeholder", placeholder).call(utilNoAuto).merge(input);
62706 input.call(utilGetSetValue, "").call(
62707 moreCombo.data(moreFields).on("accept", function(d) {
62710 var field = d.field;
62712 selection2.call(formFields);
62716 if (_lastPlaceholder !== placeholder) {
62717 input.attr("placeholder", placeholder);
62718 _lastPlaceholder = placeholder;
62721 formFields.fieldsArr = function(val) {
62722 if (!arguments.length)
62724 _fieldsArr = val || [];
62727 formFields.state = function(val) {
62728 if (!arguments.length)
62733 formFields.klass = function(val) {
62734 if (!arguments.length)
62742 // modules/ui/changeset_editor.js
62743 function uiChangesetEditor(context) {
62744 var dispatch10 = dispatch_default("change");
62745 var formFields = uiFormFields(context);
62746 var commentCombo = uiCombobox(context, "comment").caseSensitive(true);
62750 function changesetEditor(selection2) {
62751 render(selection2);
62753 function render(selection2) {
62754 var initial = false;
62757 var presets = _mainPresetIndex;
62759 uiField(context, presets.field("comment"), null, { show: true, revert: false }),
62760 uiField(context, presets.field("source"), null, { show: false, revert: false }),
62761 uiField(context, presets.field("hashtags"), null, { show: false, revert: false })
62763 _fieldsArr.forEach(function(field) {
62764 field.on("change", function(t, onInput) {
62765 dispatch10.call("change", field, void 0, t, onInput);
62769 _fieldsArr.forEach(function(field) {
62772 selection2.call(formFields.fieldsArr(_fieldsArr));
62774 var commentField = selection2.select(".form-field-comment textarea");
62775 var commentNode = commentField.node();
62777 commentNode.focus();
62778 commentNode.select();
62780 utilTriggerEvent(commentField, "blur");
62781 var osm = context.connection();
62783 osm.userChangesets(function(err, changesets) {
62786 var comments = changesets.map(function(changeset) {
62787 var comment = changeset.tags.comment;
62788 return comment ? { title: comment, value: comment } : null;
62789 }).filter(Boolean);
62791 commentCombo.data(utilArrayUniqBy(comments, "title"))
62796 const warnings = [];
62797 if (_tags.comment.match(/google/i)) {
62799 id: 'contains "google"',
62800 msg: _t.append("commit.google_warning"),
62801 link: _t("commit.google_warning_link")
62804 const maxChars = context.maxCharsForTagValue();
62805 const strLen = utilUnicodeCharsCount(utilCleanOsmString(_tags.comment, Number.POSITIVE_INFINITY));
62806 if (strLen > maxChars || false) {
62808 id: "message too long",
62809 msg: _t.append("commit.changeset_comment_length_warning", { maxChars })
62812 var commentWarning = selection2.select(".form-field-comment").selectAll(".comment-warning").data(warnings, (d) => d.id);
62813 commentWarning.exit().transition().duration(200).style("opacity", 0).remove();
62814 var commentEnter = commentWarning.enter().insert("div", ".comment-warning").attr("class", "comment-warning field-warning").style("opacity", 0);
62815 commentEnter.call(svgIcon("#iD-icon-alert", "inline")).append("span");
62816 commentEnter.transition().duration(200).style("opacity", 1);
62817 commentWarning.merge(commentEnter).selectAll("div > span").text("").each(function(d) {
62818 let selection3 = select_default2(this);
62820 selection3 = selection3.append("a").attr("target", "_blank").attr("href", d.link);
62822 selection3.call(d.msg);
62825 changesetEditor.tags = function(_) {
62826 if (!arguments.length)
62829 return changesetEditor;
62831 changesetEditor.changesetID = function(_) {
62832 if (!arguments.length)
62833 return _changesetID;
62834 if (_changesetID === _)
62835 return changesetEditor;
62838 return changesetEditor;
62840 return utilRebind(changesetEditor, dispatch10, "on");
62843 // modules/ui/commit.js
62844 var import_fast_deep_equal9 = __toESM(require_fast_deep_equal());
62846 // modules/util/jxon.js
62847 var JXON = new function() {
62848 var sValueProp = "keyValue", sAttributesProp = "keyAttributes", sAttrPref = "@", aCache = [], rIsNull = /^\s*$/, rIsBool = /^(?:true|false)$/i;
62849 function parseText(sValue) {
62850 if (rIsNull.test(sValue)) {
62853 if (rIsBool.test(sValue)) {
62854 return sValue.toLowerCase() === "true";
62856 if (isFinite(sValue)) {
62857 return parseFloat(sValue);
62859 if (isFinite(Date.parse(sValue))) {
62860 return new Date(sValue);
62864 function EmptyTree() {
62866 EmptyTree.prototype.toString = function() {
62869 EmptyTree.prototype.valueOf = function() {
62872 function objectify(vValue) {
62873 return vValue === null ? new EmptyTree() : vValue instanceof Object ? vValue : new vValue.constructor(vValue);
62875 function createObjTree(oParentNode, nVerb, bFreeze, bNesteAttr) {
62876 var nLevelStart = aCache.length, bChildren = oParentNode.hasChildNodes(), bAttributes = oParentNode.hasAttributes(), bHighVerb = Boolean(nVerb & 2);
62877 var sProp, vContent, nLength = 0, sCollectedTxt = "", vResult = bHighVerb ? {} : (
62878 /* put here the default value for empty nodes: */
62882 for (var oNode, nItem = 0; nItem < oParentNode.childNodes.length; nItem++) {
62883 oNode = oParentNode.childNodes.item(nItem);
62884 if (oNode.nodeType === 4) {
62885 sCollectedTxt += oNode.nodeValue;
62886 } else if (oNode.nodeType === 3) {
62887 sCollectedTxt += oNode.nodeValue.trim();
62888 } else if (oNode.nodeType === 1 && !oNode.prefix) {
62889 aCache.push(oNode);
62893 var nLevelEnd = aCache.length, vBuiltVal = parseText(sCollectedTxt);
62894 if (!bHighVerb && (bChildren || bAttributes)) {
62895 vResult = nVerb === 0 ? objectify(vBuiltVal) : {};
62897 for (var nElId = nLevelStart; nElId < nLevelEnd; nElId++) {
62898 sProp = aCache[nElId].nodeName.toLowerCase();
62899 vContent = createObjTree(aCache[nElId], nVerb, bFreeze, bNesteAttr);
62900 if (vResult.hasOwnProperty(sProp)) {
62901 if (vResult[sProp].constructor !== Array) {
62902 vResult[sProp] = [vResult[sProp]];
62904 vResult[sProp].push(vContent);
62906 vResult[sProp] = vContent;
62911 var nAttrLen = oParentNode.attributes.length, sAPrefix = bNesteAttr ? "" : sAttrPref, oAttrParent = bNesteAttr ? {} : vResult;
62912 for (var oAttrib, nAttrib = 0; nAttrib < nAttrLen; nLength++, nAttrib++) {
62913 oAttrib = oParentNode.attributes.item(nAttrib);
62914 oAttrParent[sAPrefix + oAttrib.name.toLowerCase()] = parseText(oAttrib.value.trim());
62918 Object.freeze(oAttrParent);
62920 vResult[sAttributesProp] = oAttrParent;
62921 nLength -= nAttrLen - 1;
62924 if (nVerb === 3 || (nVerb === 2 || nVerb === 1 && nLength > 0) && sCollectedTxt) {
62925 vResult[sValueProp] = vBuiltVal;
62926 } else if (!bHighVerb && nLength === 0 && sCollectedTxt) {
62927 vResult = vBuiltVal;
62929 if (bFreeze && (bHighVerb || nLength > 0)) {
62930 Object.freeze(vResult);
62932 aCache.length = nLevelStart;
62935 function loadObjTree(oXMLDoc, oParentEl, oParentObj) {
62936 var vValue, oChild;
62937 if (oParentObj instanceof String || oParentObj instanceof Number || oParentObj instanceof Boolean) {
62938 oParentEl.appendChild(oXMLDoc.createTextNode(oParentObj.toString()));
62939 } else if (oParentObj.constructor === Date) {
62940 oParentEl.appendChild(oXMLDoc.createTextNode(oParentObj.toGMTString()));
62942 for (var sName in oParentObj) {
62943 vValue = oParentObj[sName];
62944 if (isFinite(sName) || vValue instanceof Function) {
62947 if (sName === sValueProp) {
62948 if (vValue !== null && vValue !== true) {
62949 oParentEl.appendChild(oXMLDoc.createTextNode(vValue.constructor === Date ? vValue.toGMTString() : String(vValue)));
62951 } else if (sName === sAttributesProp) {
62952 for (var sAttrib in vValue) {
62953 oParentEl.setAttribute(sAttrib, vValue[sAttrib]);
62955 } else if (sName.charAt(0) === sAttrPref) {
62956 oParentEl.setAttribute(sName.slice(1), vValue);
62957 } else if (vValue.constructor === Array) {
62958 for (var nItem = 0; nItem < vValue.length; nItem++) {
62959 oChild = oXMLDoc.createElement(sName);
62960 loadObjTree(oXMLDoc, oChild, vValue[nItem]);
62961 oParentEl.appendChild(oChild);
62964 oChild = oXMLDoc.createElement(sName);
62965 if (vValue instanceof Object) {
62966 loadObjTree(oXMLDoc, oChild, vValue);
62967 } else if (vValue !== null && vValue !== true) {
62968 oChild.appendChild(oXMLDoc.createTextNode(vValue.toString()));
62970 oParentEl.appendChild(oChild);
62974 this.build = function(oXMLParent, nVerbosity, bFreeze, bNesteAttributes) {
62975 var _nVerb = arguments.length > 1 && typeof nVerbosity === "number" ? nVerbosity & 3 : (
62976 /* put here the default verbosity level: */
62979 return createObjTree(oXMLParent, _nVerb, bFreeze || false, arguments.length > 3 ? bNesteAttributes : _nVerb === 3);
62981 this.unbuild = function(oObjTree) {
62982 var oNewDoc = document.implementation.createDocument("", "", null);
62983 loadObjTree(oNewDoc, oNewDoc, oObjTree);
62986 this.stringify = function(oObjTree) {
62987 return new XMLSerializer().serializeToString(JXON.unbuild(oObjTree));
62991 // modules/ui/sections/changes.js
62992 function uiSectionChanges(context) {
62993 var _discardTags = {};
62994 _mainFileFetcher.get("discarded").then(function(d) {
62996 }).catch(function() {
62998 var section = uiSection("changes-list", context).label(function() {
62999 var history = context.history();
63000 var summary = history.difference().summary();
63001 return _t.append("inspector.title_count", { title: _t("commit.changes"), count: summary.length });
63002 }).disclosureContent(renderDisclosureContent);
63003 function renderDisclosureContent(selection2) {
63004 var history = context.history();
63005 var summary = history.difference().summary();
63006 var container = selection2.selectAll(".commit-section").data([0]);
63007 var containerEnter = container.enter().append("div").attr("class", "commit-section");
63008 containerEnter.append("ul").attr("class", "changeset-list");
63009 container = containerEnter.merge(container);
63010 var items = container.select("ul").selectAll("li").data(summary);
63011 var itemsEnter = items.enter().append("li").attr("class", "change-item");
63012 var buttons = itemsEnter.append("button").on("mouseover", mouseover).on("mouseout", mouseout).on("click", click);
63013 buttons.each(function(d) {
63014 select_default2(this).call(svgIcon("#iD-icon-" + d.entity.geometry(d.graph), "pre-text " + d.changeType));
63016 buttons.append("span").attr("class", "change-type").html(function(d) {
63017 return _t.html("commit." + d.changeType) + " ";
63019 buttons.append("strong").attr("class", "entity-type").text(function(d) {
63020 var matched = _mainPresetIndex.match(d.entity, d.graph);
63021 return matched && matched.name() || utilDisplayType(d.entity.id);
63023 buttons.append("span").attr("class", "entity-name").text(function(d) {
63024 var name = utilDisplayName(d.entity) || "", string = "";
63028 return string += " " + name;
63030 items = itemsEnter.merge(items);
63031 var changeset = new osmChangeset().update({ id: void 0 });
63032 var changes = history.changes(actionDiscardTags(history.difference(), _discardTags));
63033 delete changeset.id;
63034 var data = JXON.stringify(changeset.osmChangeJXON(changes));
63035 var blob = new Blob([data], { type: "text/xml;charset=utf-8;" });
63036 var fileName = "changes.osc";
63037 var linkEnter = container.selectAll(".download-changes").data([0]).enter().append("a").attr("class", "download-changes");
63038 linkEnter.attr("href", window.URL.createObjectURL(blob)).attr("download", fileName);
63039 linkEnter.call(svgIcon("#iD-icon-load", "inline")).append("span").call(_t.append("commit.download_changes"));
63040 function mouseover(d) {
63042 context.surface().selectAll(
63043 utilEntityOrMemberSelector([d.entity.id], context.graph())
63044 ).classed("hover", true);
63047 function mouseout() {
63048 context.surface().selectAll(".hover").classed("hover", false);
63050 function click(d3_event, change) {
63051 if (change.changeType !== "deleted") {
63052 var entity = change.entity;
63053 context.map().zoomToEase(entity);
63054 context.surface().selectAll(utilEntityOrMemberSelector([entity.id], context.graph())).classed("hover", true);
63061 // modules/ui/commit_warnings.js
63062 function uiCommitWarnings(context) {
63063 function commitWarnings(selection2) {
63064 var issuesBySeverity = context.validator().getIssuesBySeverity({ what: "edited", where: "all", includeDisabledRules: true });
63065 for (var severity in issuesBySeverity) {
63066 var issues = issuesBySeverity[severity];
63067 if (severity !== "error") {
63068 issues = issues.filter(function(issue) {
63069 return issue.type !== "help_request";
63072 var section = severity + "-section";
63073 var issueItem = severity + "-item";
63074 var container = selection2.selectAll("." + section).data(issues.length ? [0] : []);
63075 container.exit().remove();
63076 var containerEnter = container.enter().append("div").attr("class", "modal-section " + section + " fillL2");
63077 containerEnter.append("h3").call(severity === "warning" ? _t.append("commit.warnings") : _t.append("commit.errors"));
63078 containerEnter.append("ul").attr("class", "changeset-list");
63079 container = containerEnter.merge(container);
63080 var items = container.select("ul").selectAll("li").data(issues, function(d) {
63083 items.exit().remove();
63084 var itemsEnter = items.enter().append("li").attr("class", issueItem);
63085 var buttons = itemsEnter.append("button").on("mouseover", function(d3_event, d) {
63087 context.surface().selectAll(
63088 utilEntityOrMemberSelector(
63092 ).classed("hover", true);
63094 }).on("mouseout", function() {
63095 context.surface().selectAll(".hover").classed("hover", false);
63096 }).on("click", function(d3_event, d) {
63097 context.validator().focusIssue(d);
63099 buttons.call(svgIcon("#iD-icon-alert", "pre-text"));
63100 buttons.append("strong").attr("class", "issue-message");
63101 buttons.filter(function(d) {
63104 uiTooltip().title(function(d) {
63106 }).placement("top")
63108 items = itemsEnter.merge(items);
63109 items.selectAll(".issue-message").text("").each(function(d) {
63110 return d.message(context)(select_default2(this));
63114 return commitWarnings;
63117 // modules/ui/commit.js
63118 var readOnlyTags = [
63119 /^changesets_count$/,
63128 /^closed:keepright$/,
63129 /^closed:improveosm:/,
63132 var hashtagRegex = /(#[^\u2000-\u206F\u2E00-\u2E7F\s\\'!"#$%()*,.\/:;<=>?@\[\]^`{|}~]+)/g;
63133 function uiCommit(context) {
63134 var dispatch10 = dispatch_default("cancel");
63137 var changesetEditor = uiChangesetEditor(context).on("change", changeTags);
63138 var rawTagEditor = uiSectionRawTagEditor("changeset-tag-editor", context).on("change", changeTags).readOnlyTags(readOnlyTags);
63139 var commitChanges = uiSectionChanges(context);
63140 var commitWarnings = uiCommitWarnings(context);
63141 function commit(selection2) {
63142 _selection = selection2;
63143 if (!context.changeset)
63145 loadDerivedChangesetTags();
63146 selection2.call(render);
63148 function initChangeset() {
63149 var commentDate = +corePreferences("commentDate") || 0;
63150 var currDate = Date.now();
63151 var cutoff = 2 * 86400 * 1e3;
63152 if (commentDate > currDate || currDate - commentDate > cutoff) {
63153 corePreferences("comment", null);
63154 corePreferences("hashtags", null);
63155 corePreferences("source", null);
63157 if (context.defaultChangesetComment()) {
63158 corePreferences("comment", context.defaultChangesetComment());
63159 corePreferences("commentDate", Date.now());
63161 if (context.defaultChangesetSource()) {
63162 corePreferences("source", context.defaultChangesetSource());
63163 corePreferences("commentDate", Date.now());
63165 if (context.defaultChangesetHashtags()) {
63166 corePreferences("hashtags", context.defaultChangesetHashtags());
63167 corePreferences("commentDate", Date.now());
63169 var detected = utilDetect();
63171 comment: corePreferences("comment") || "",
63172 created_by: context.cleanTagValue("iD " + context.version),
63173 host: context.cleanTagValue(detected.host),
63174 locale: context.cleanTagValue(_mainLocalizer.localeCode())
63176 findHashtags(tags, true);
63177 var hashtags = corePreferences("hashtags");
63179 tags.hashtags = hashtags;
63181 var source = corePreferences("source");
63183 tags.source = source;
63185 var photoOverlaysUsed = context.history().photoOverlaysUsed();
63186 if (photoOverlaysUsed.length) {
63187 var sources = (tags.source || "").split(";");
63188 if (sources.indexOf("streetlevel imagery") === -1) {
63189 sources.push("streetlevel imagery");
63191 photoOverlaysUsed.forEach(function(photoOverlay) {
63192 if (sources.indexOf(photoOverlay) === -1) {
63193 sources.push(photoOverlay);
63196 tags.source = context.cleanTagValue(sources.join(";"));
63198 context.changeset = new osmChangeset({ tags });
63200 function loadDerivedChangesetTags() {
63201 var osm = context.connection();
63204 var tags = Object.assign({}, context.changeset.tags);
63205 var imageryUsed = context.cleanTagValue(context.history().imageryUsed().join(";"));
63206 tags.imagery_used = imageryUsed || "None";
63207 var osmClosed = osm.getClosedIDs();
63209 if (osmClosed.length) {
63210 tags["closed:note"] = context.cleanTagValue(osmClosed.join(";"));
63212 if (services.keepRight) {
63213 var krClosed = services.keepRight.getClosedIDs();
63214 if (krClosed.length) {
63215 tags["closed:keepright"] = context.cleanTagValue(krClosed.join(";"));
63218 if (services.improveOSM) {
63219 var iOsmClosed = services.improveOSM.getClosedCounts();
63220 for (itemType in iOsmClosed) {
63221 tags["closed:improveosm:" + itemType] = context.cleanTagValue(iOsmClosed[itemType].toString());
63224 if (services.osmose) {
63225 var osmoseClosed = services.osmose.getClosedCounts();
63226 for (itemType in osmoseClosed) {
63227 tags["closed:osmose:" + itemType] = context.cleanTagValue(osmoseClosed[itemType].toString());
63230 for (var key in tags) {
63231 if (key.match(/(^warnings:)|(^resolved:)/)) {
63235 function addIssueCounts(issues, prefix) {
63236 var issuesByType = utilArrayGroupBy(issues, "type");
63237 for (var issueType in issuesByType) {
63238 var issuesOfType = issuesByType[issueType];
63239 if (issuesOfType[0].subtype) {
63240 var issuesBySubtype = utilArrayGroupBy(issuesOfType, "subtype");
63241 for (var issueSubtype in issuesBySubtype) {
63242 var issuesOfSubtype = issuesBySubtype[issueSubtype];
63243 tags[prefix + ":" + issueType + ":" + issueSubtype] = context.cleanTagValue(issuesOfSubtype.length.toString());
63246 tags[prefix + ":" + issueType] = context.cleanTagValue(issuesOfType.length.toString());
63250 var warnings = context.validator().getIssuesBySeverity({ what: "edited", where: "all", includeIgnored: true, includeDisabledRules: true }).warning.filter(function(issue) {
63251 return issue.type !== "help_request";
63253 addIssueCounts(warnings, "warnings");
63254 var resolvedIssues = context.validator().getResolvedIssues();
63255 addIssueCounts(resolvedIssues, "resolved");
63256 context.changeset = context.changeset.update({ tags });
63258 function render(selection2) {
63259 var osm = context.connection();
63262 var header = selection2.selectAll(".header").data([0]);
63263 var headerTitle = header.enter().append("div").attr("class", "header fillL");
63264 headerTitle.append("div").append("h2").call(_t.append("commit.title"));
63265 headerTitle.append("button").attr("class", "close").attr("title", _t("icons.close")).on("click", function() {
63266 dispatch10.call("cancel", this);
63267 }).call(svgIcon("#iD-icon-close"));
63268 var body = selection2.selectAll(".body").data([0]);
63269 body = body.enter().append("div").attr("class", "body").merge(body);
63270 var changesetSection = body.selectAll(".changeset-editor").data([0]);
63271 changesetSection = changesetSection.enter().append("div").attr("class", "modal-section changeset-editor").merge(changesetSection);
63272 changesetSection.call(
63273 changesetEditor.changesetID(context.changeset.id).tags(context.changeset.tags)
63275 body.call(commitWarnings);
63276 var saveSection = body.selectAll(".save-section").data([0]);
63277 saveSection = saveSection.enter().append("div").attr("class", "modal-section save-section fillL").merge(saveSection);
63278 var prose = saveSection.selectAll(".commit-info").data([0]);
63279 if (prose.enter().size()) {
63280 _userDetails2 = null;
63282 prose = prose.enter().append("p").attr("class", "commit-info").call(_t.append("commit.upload_explanation")).merge(prose);
63283 osm.userDetails(function(err, user) {
63286 if (_userDetails2 === user)
63288 _userDetails2 = user;
63289 var userLink = select_default2(document.createElement("div"));
63290 if (user.image_url) {
63291 userLink.append("img").attr("src", user.image_url).attr("class", "icon pre-text user-icon");
63293 userLink.append("a").attr("class", "user-info").text(user.display_name).attr("href", osm.userURL(user.display_name)).attr("target", "_blank");
63294 prose.html(_t.html("commit.upload_explanation_with_user", { user: { html: userLink.html() } }));
63296 var requestReview = saveSection.selectAll(".request-review").data([0]);
63297 var requestReviewEnter = requestReview.enter().append("div").attr("class", "request-review");
63298 var requestReviewDomId = utilUniqueDomId("commit-input-request-review");
63299 var labelEnter = requestReviewEnter.append("label").attr("for", requestReviewDomId);
63300 if (!labelEnter.empty()) {
63301 labelEnter.call(uiTooltip().title(() => _t.append("commit.request_review_info")).placement("top"));
63303 labelEnter.append("input").attr("type", "checkbox").attr("id", requestReviewDomId);
63304 labelEnter.append("span").call(_t.append("commit.request_review"));
63305 requestReview = requestReview.merge(requestReviewEnter);
63306 var requestReviewInput = requestReview.selectAll("input").property("checked", isReviewRequested(context.changeset.tags)).on("change", toggleRequestReview);
63307 var buttonSection = saveSection.selectAll(".buttons").data([0]);
63308 var buttonEnter = buttonSection.enter().append("div").attr("class", "buttons fillL");
63309 buttonEnter.append("button").attr("class", "secondary-action button cancel-button").append("span").attr("class", "label").call(_t.append("commit.cancel"));
63310 var uploadButton = buttonEnter.append("button").attr("class", "action button save-button");
63311 uploadButton.append("span").attr("class", "label").call(_t.append("commit.save"));
63312 var uploadBlockerTooltipText = getUploadBlockerMessage();
63313 buttonSection = buttonSection.merge(buttonEnter);
63314 buttonSection.selectAll(".cancel-button").on("click.cancel", function() {
63315 dispatch10.call("cancel", this);
63317 buttonSection.selectAll(".save-button").classed("disabled", uploadBlockerTooltipText !== null).on("click.save", function() {
63318 if (!select_default2(this).classed("disabled")) {
63320 for (var key in context.changeset.tags) {
63322 delete context.changeset.tags[key];
63324 context.uploader().save(context.changeset);
63327 uiTooltip().destroyAny(buttonSection.selectAll(".save-button"));
63328 if (uploadBlockerTooltipText) {
63329 buttonSection.selectAll(".save-button").call(uiTooltip().title(() => uploadBlockerTooltipText).placement("top"));
63331 var tagSection = body.selectAll(".tag-section.raw-tag-editor").data([0]);
63332 tagSection = tagSection.enter().append("div").attr("class", "modal-section tag-section raw-tag-editor").merge(tagSection);
63334 rawTagEditor.tags(Object.assign({}, context.changeset.tags)).render
63336 var changesSection = body.selectAll(".commit-changes-section").data([0]);
63337 changesSection = changesSection.enter().append("div").attr("class", "modal-section commit-changes-section").merge(changesSection);
63338 changesSection.call(commitChanges.render);
63339 function toggleRequestReview() {
63340 var rr = requestReviewInput.property("checked");
63341 updateChangeset({ review_requested: rr ? "yes" : void 0 });
63343 rawTagEditor.tags(Object.assign({}, context.changeset.tags)).render
63347 function getUploadBlockerMessage() {
63348 var errors = context.validator().getIssuesBySeverity({ what: "edited", where: "all" }).error;
63349 if (errors.length) {
63350 return _t.append("commit.outstanding_errors_message", { count: errors.length });
63352 var hasChangesetComment = context.changeset && context.changeset.tags.comment && context.changeset.tags.comment.trim().length;
63353 if (!hasChangesetComment) {
63354 return _t.append("commit.comment_needed_message");
63359 function changeTags(_, changed, onInput) {
63360 if (changed.hasOwnProperty("comment")) {
63361 if (changed.comment === void 0) {
63362 changed.comment = "";
63365 corePreferences("comment", changed.comment);
63366 corePreferences("commentDate", Date.now());
63369 if (changed.hasOwnProperty("source")) {
63370 if (changed.source === void 0) {
63371 corePreferences("source", null);
63372 } else if (!onInput) {
63373 corePreferences("source", changed.source);
63374 corePreferences("commentDate", Date.now());
63377 updateChangeset(changed, onInput);
63379 _selection.call(render);
63382 function findHashtags(tags, commentOnly) {
63383 var detectedHashtags = commentHashtags();
63384 if (detectedHashtags.length) {
63385 corePreferences("hashtags", null);
63387 if (!detectedHashtags.length || !commentOnly) {
63388 detectedHashtags = detectedHashtags.concat(hashtagHashtags());
63390 var allLowerCase = /* @__PURE__ */ new Set();
63391 return detectedHashtags.filter(function(hashtag) {
63392 var lowerCase = hashtag.toLowerCase();
63393 if (!allLowerCase.has(lowerCase)) {
63394 allLowerCase.add(lowerCase);
63399 function commentHashtags() {
63400 var matches = (tags.comment || "").replace(/http\S*/g, "").match(hashtagRegex);
63401 return matches || [];
63403 function hashtagHashtags() {
63404 var matches = (tags.hashtags || "").split(/[,;\s]+/).map(function(s) {
63405 if (s[0] !== "#") {
63408 var matched = s.match(hashtagRegex);
63409 return matched && matched[0];
63410 }).filter(Boolean);
63411 return matches || [];
63414 function isReviewRequested(tags) {
63415 var rr = tags.review_requested;
63418 rr = rr.trim().toLowerCase();
63419 return !(rr === "" || rr === "no");
63421 function updateChangeset(changed, onInput) {
63422 var tags = Object.assign({}, context.changeset.tags);
63423 Object.keys(changed).forEach(function(k) {
63424 var v = changed[k];
63425 k = context.cleanTagKey(k);
63426 if (readOnlyTags.indexOf(k) !== -1)
63428 if (v === void 0) {
63430 } else if (onInput) {
63433 tags[k] = context.cleanTagValue(v);
63437 var commentOnly = changed.hasOwnProperty("comment") && changed.comment !== "";
63438 var arr = findHashtags(tags, commentOnly);
63440 tags.hashtags = context.cleanTagValue(arr.join(";"));
63441 corePreferences("hashtags", tags.hashtags);
63443 delete tags.hashtags;
63444 corePreferences("hashtags", null);
63447 if (_userDetails2 && _userDetails2.changesets_count !== void 0) {
63448 var changesetsCount = parseInt(_userDetails2.changesets_count, 10) + 1;
63449 tags.changesets_count = String(changesetsCount);
63450 if (changesetsCount <= 100) {
63452 s = corePreferences("walkthrough_completed");
63454 tags["ideditor:walkthrough_completed"] = s;
63456 s = corePreferences("walkthrough_progress");
63458 tags["ideditor:walkthrough_progress"] = s;
63460 s = corePreferences("walkthrough_started");
63462 tags["ideditor:walkthrough_started"] = s;
63466 delete tags.changesets_count;
63468 if (!(0, import_fast_deep_equal9.default)(context.changeset.tags, tags)) {
63469 context.changeset = context.changeset.update({ tags });
63472 commit.reset = function() {
63473 context.changeset = null;
63475 return utilRebind(commit, dispatch10, "on");
63478 // modules/ui/confirm.js
63479 function uiConfirm(selection2) {
63480 var modalSelection = uiModal(selection2);
63481 modalSelection.select(".modal").classed("modal-alert", true);
63482 var section = modalSelection.select(".content");
63483 section.append("div").attr("class", "modal-section header");
63484 section.append("div").attr("class", "modal-section message-text");
63485 var buttons = section.append("div").attr("class", "modal-section buttons cf");
63486 modalSelection.okButton = function() {
63487 buttons.append("button").attr("class", "button ok-button action").on("click.confirm", function() {
63488 modalSelection.remove();
63489 }).call(_t.append("confirm.okay")).node().focus();
63490 return modalSelection;
63492 return modalSelection;
63495 // modules/ui/conflicts.js
63496 function uiConflicts(context) {
63497 var dispatch10 = dispatch_default("cancel", "save");
63498 var keybinding = utilKeybinding("conflicts");
63501 var _shownConflictIndex;
63502 function keybindingOn() {
63503 select_default2(document).call(keybinding.on("\u238B", cancel, true));
63505 function keybindingOff() {
63506 select_default2(document).call(keybinding.unbind);
63508 function tryAgain() {
63510 dispatch10.call("save");
63512 function cancel() {
63514 dispatch10.call("cancel");
63516 function conflicts(selection2) {
63518 var headerEnter = selection2.selectAll(".header").data([0]).enter().append("div").attr("class", "header fillL");
63519 headerEnter.append("button").attr("class", "fr").attr("title", _t("icons.close")).on("click", cancel).call(svgIcon("#iD-icon-close"));
63520 headerEnter.append("h2").call(_t.append("save.conflict.header"));
63521 var bodyEnter = selection2.selectAll(".body").data([0]).enter().append("div").attr("class", "body fillL");
63522 var conflictsHelpEnter = bodyEnter.append("div").attr("class", "conflicts-help").call(_t.append("save.conflict.help"));
63523 var changeset = new osmChangeset();
63524 delete changeset.id;
63525 var data = JXON.stringify(changeset.osmChangeJXON(_origChanges));
63526 var blob = new Blob([data], { type: "text/xml;charset=utf-8;" });
63527 var fileName = "changes.osc";
63528 var linkEnter = conflictsHelpEnter.selectAll(".download-changes").append("a").attr("class", "download-changes");
63529 linkEnter.attr("href", window.URL.createObjectURL(blob)).attr("download", fileName);
63530 linkEnter.call(svgIcon("#iD-icon-load", "inline")).append("span").call(_t.append("save.conflict.download_changes"));
63531 bodyEnter.append("div").attr("class", "conflict-container fillL3").call(showConflict, 0);
63532 bodyEnter.append("div").attr("class", "conflicts-done").attr("opacity", 0).style("display", "none").call(_t.append("save.conflict.done"));
63533 var buttonsEnter = bodyEnter.append("div").attr("class", "buttons col12 joined conflicts-buttons");
63534 buttonsEnter.append("button").attr("disabled", _conflictList.length > 1).attr("class", "action conflicts-button col6").call(_t.append("save.title")).on("click.try_again", tryAgain);
63535 buttonsEnter.append("button").attr("class", "secondary-action conflicts-button col6").call(_t.append("confirm.cancel")).on("click.cancel", cancel);
63537 function showConflict(selection2, index) {
63538 index = utilWrap(index, _conflictList.length);
63539 _shownConflictIndex = index;
63540 var parent = select_default2(selection2.node().parentNode);
63541 if (index === _conflictList.length - 1) {
63542 window.setTimeout(function() {
63543 parent.select(".conflicts-button").attr("disabled", null);
63544 parent.select(".conflicts-done").transition().attr("opacity", 1).style("display", "block");
63547 var conflict = selection2.selectAll(".conflict").data([_conflictList[index]]);
63548 conflict.exit().remove();
63549 var conflictEnter = conflict.enter().append("div").attr("class", "conflict");
63550 conflictEnter.append("h4").attr("class", "conflict-count").call(_t.append("save.conflict.count", { num: index + 1, total: _conflictList.length }));
63551 conflictEnter.append("a").attr("class", "conflict-description").attr("href", "#").text(function(d) {
63553 }).on("click", function(d3_event, d) {
63554 d3_event.preventDefault();
63555 zoomToEntity(d.id);
63557 var details = conflictEnter.append("div").attr("class", "conflict-detail-container");
63558 details.append("ul").attr("class", "conflict-detail-list").selectAll("li").data(function(d) {
63559 return d.details || [];
63560 }).enter().append("li").attr("class", "conflict-detail-item").html(function(d) {
63563 details.append("div").attr("class", "conflict-choices").call(addChoices);
63564 details.append("div").attr("class", "conflict-nav-buttons joined cf").selectAll("button").data(["previous", "next"]).enter().append("button").attr("class", "conflict-nav-button action col6").attr("disabled", function(d, i2) {
63565 return i2 === 0 && index === 0 || i2 === 1 && index === _conflictList.length - 1 || null;
63566 }).on("click", function(d3_event, d) {
63567 d3_event.preventDefault();
63568 var container = parent.selectAll(".conflict-container");
63569 var sign2 = d === "previous" ? -1 : 1;
63570 container.selectAll(".conflict").remove();
63571 container.call(showConflict, index + sign2);
63572 }).each(function(d) {
63573 _t.append("save.conflict." + d)(select_default2(this));
63576 function addChoices(selection2) {
63577 var choices = selection2.append("ul").attr("class", "layer-list").selectAll("li").data(function(d) {
63578 return d.choices || [];
63580 var choicesEnter = choices.enter().append("li").attr("class", "layer");
63581 var labelEnter = choicesEnter.append("label");
63582 labelEnter.append("input").attr("type", "radio").attr("name", function(d) {
63584 }).on("change", function(d3_event, d) {
63585 var ul = this.parentNode.parentNode.parentNode;
63586 ul.__data__.chosen = d.id;
63587 choose(d3_event, ul, d);
63589 labelEnter.append("span").text(function(d) {
63592 choicesEnter.merge(choices).each(function(d) {
63593 var ul = this.parentNode;
63594 if (ul.__data__.chosen === d.id) {
63595 choose(null, ul, d);
63599 function choose(d3_event, ul, datum2) {
63601 d3_event.preventDefault();
63602 select_default2(ul).selectAll("li").classed("active", function(d) {
63603 return d === datum2;
63604 }).selectAll("input").property("checked", function(d) {
63605 return d === datum2;
63607 var extent = geoExtent();
63609 entity = context.graph().hasEntity(datum2.id);
63611 extent._extend(entity.extent(context.graph()));
63613 entity = context.graph().hasEntity(datum2.id);
63615 extent._extend(entity.extent(context.graph()));
63616 zoomToEntity(datum2.id, extent);
63618 function zoomToEntity(id2, extent) {
63619 context.surface().selectAll(".hover").classed("hover", false);
63620 var entity = context.graph().hasEntity(id2);
63623 context.map().trimmedExtent(extent);
63625 context.map().zoomToEase(entity);
63627 context.surface().selectAll(utilEntityOrMemberSelector([entity.id], context.graph())).classed("hover", true);
63630 conflicts.conflictList = function(_) {
63631 if (!arguments.length)
63632 return _conflictList;
63636 conflicts.origChanges = function(_) {
63637 if (!arguments.length)
63638 return _origChanges;
63642 conflicts.shownEntityIds = function() {
63643 if (_conflictList && typeof _shownConflictIndex === "number") {
63644 return [_conflictList[_shownConflictIndex].id];
63648 return utilRebind(conflicts, dispatch10, "on");
63651 // modules/ui/entity_editor.js
63652 var import_fast_deep_equal10 = __toESM(require_fast_deep_equal());
63654 // modules/ui/sections/entity_issues.js
63655 function uiSectionEntityIssues(context) {
63656 var preference = corePreferences("entity-issues.reference.expanded");
63657 var _expanded = preference === null ? true : preference === "true";
63658 var _entityIDs = [];
63660 var _activeIssueID;
63661 var section = uiSection("entity-issues", context).shouldDisplay(function() {
63662 return _issues.length > 0;
63663 }).label(function() {
63664 return _t.append("inspector.title_count", { title: _t("issues.list_title"), count: _issues.length });
63665 }).disclosureContent(renderDisclosureContent);
63666 context.validator().on("validated.entity_issues", function() {
63668 section.reRender();
63669 }).on("focusedIssue.entity_issues", function(issue) {
63670 makeActiveIssue(issue.id);
63672 function reloadIssues() {
63673 _issues = context.validator().getSharedEntityIssues(_entityIDs, { includeDisabledRules: true });
63675 function makeActiveIssue(issueID) {
63676 _activeIssueID = issueID;
63677 section.selection().selectAll(".issue-container").classed("active", function(d) {
63678 return d.id === _activeIssueID;
63681 function renderDisclosureContent(selection2) {
63682 selection2.classed("grouped-items-area", true);
63683 _activeIssueID = _issues.length > 0 ? _issues[0].id : null;
63684 var containers = selection2.selectAll(".issue-container").data(_issues, function(d) {
63687 containers.exit().remove();
63688 var containersEnter = containers.enter().append("div").attr("class", "issue-container");
63689 var itemsEnter = containersEnter.append("div").attr("class", function(d) {
63690 return "issue severity-" + d.severity;
63691 }).on("mouseover.highlight", function(d3_event, d) {
63692 var ids = d.entityIds.filter(function(e) {
63693 return _entityIDs.indexOf(e) === -1;
63695 utilHighlightEntities(ids, true, context);
63696 }).on("mouseout.highlight", function(d3_event, d) {
63697 var ids = d.entityIds.filter(function(e) {
63698 return _entityIDs.indexOf(e) === -1;
63700 utilHighlightEntities(ids, false, context);
63702 var labelsEnter = itemsEnter.append("div").attr("class", "issue-label");
63703 var textEnter = labelsEnter.append("button").attr("class", "issue-text").on("click", function(d3_event, d) {
63704 makeActiveIssue(d.id);
63705 var extent = d.extent(context.graph());
63707 var setZoom = Math.max(context.map().zoom(), 19);
63708 context.map().unobscuredCenterZoomEase(extent.center(), setZoom);
63711 textEnter.each(function(d) {
63712 var iconName = "#iD-icon-" + (d.severity === "warning" ? "alert" : "error");
63713 select_default2(this).call(svgIcon(iconName, "issue-icon"));
63715 textEnter.append("span").attr("class", "issue-message");
63716 var infoButton = labelsEnter.append("button").attr("class", "issue-info-button").attr("title", _t("icons.information")).call(svgIcon("#iD-icon-inspect"));
63717 infoButton.on("click", function(d3_event) {
63718 d3_event.stopPropagation();
63719 d3_event.preventDefault();
63721 var container = select_default2(this.parentNode.parentNode.parentNode);
63722 var info = container.selectAll(".issue-info");
63723 var isExpanded = info.classed("expanded");
63724 _expanded = !isExpanded;
63725 corePreferences("entity-issues.reference.expanded", _expanded);
63727 info.transition().duration(200).style("max-height", "0px").style("opacity", "0").on("end", function() {
63728 info.classed("expanded", false);
63731 info.classed("expanded", true).transition().duration(200).style("max-height", "200px").style("opacity", "1").on("end", function() {
63732 info.style("max-height", null);
63736 itemsEnter.append("ul").attr("class", "issue-fix-list");
63737 containersEnter.append("div").attr("class", "issue-info" + (_expanded ? " expanded" : "")).style("max-height", _expanded ? null : "0").style("opacity", _expanded ? "1" : "0").each(function(d) {
63738 if (typeof d.reference === "function") {
63739 select_default2(this).call(d.reference);
63741 select_default2(this).call(_t.append("inspector.no_documentation_key"));
63744 containers = containers.merge(containersEnter).classed("active", function(d) {
63745 return d.id === _activeIssueID;
63747 containers.selectAll(".issue-message").text("").each(function(d) {
63748 return d.message(context)(select_default2(this));
63750 var fixLists = containers.selectAll(".issue-fix-list");
63751 var fixes = fixLists.selectAll(".issue-fix-item").data(function(d) {
63752 return d.fixes ? d.fixes(context) : [];
63756 fixes.exit().remove();
63757 var fixesEnter = fixes.enter().append("li").attr("class", "issue-fix-item");
63758 var buttons = fixesEnter.append("button").on("click", function(d3_event, d) {
63759 if (select_default2(this).attr("disabled") || !d.onClick)
63761 if (d.issue.dateLastRanFix && /* @__PURE__ */ new Date() - d.issue.dateLastRanFix < 1e3)
63763 d.issue.dateLastRanFix = /* @__PURE__ */ new Date();
63764 utilHighlightEntities(d.issue.entityIds.concat(d.entityIds), false, context);
63765 new Promise(function(resolve, reject) {
63766 d.onClick(context, resolve, reject);
63767 if (d.onClick.length <= 1) {
63770 }).then(function() {
63771 context.validator().validate();
63773 }).on("mouseover.highlight", function(d3_event, d) {
63774 utilHighlightEntities(d.entityIds, true, context);
63775 }).on("mouseout.highlight", function(d3_event, d) {
63776 utilHighlightEntities(d.entityIds, false, context);
63778 buttons.each(function(d) {
63779 var iconName = d.icon || "iD-icon-wrench";
63780 if (iconName.startsWith("maki")) {
63783 select_default2(this).call(svgIcon("#" + iconName, "fix-icon"));
63785 buttons.append("span").attr("class", "fix-message").each(function(d) {
63786 return d.title(select_default2(this));
63788 fixesEnter.merge(fixes).selectAll("button").classed("actionable", function(d) {
63790 }).attr("disabled", function(d) {
63791 return d.onClick ? null : "true";
63792 }).attr("title", function(d) {
63793 if (d.disabledReason) {
63794 return d.disabledReason;
63799 section.entityIDs = function(val) {
63800 if (!arguments.length)
63802 if (!_entityIDs || !val || !utilArrayIdentical(_entityIDs, val)) {
63804 _activeIssueID = null;
63812 // modules/ui/preset_icon.js
63813 function uiPresetIcon() {
63816 function presetIcon(selection2) {
63817 selection2.each(render);
63819 function getIcon(p, geom) {
63820 if (p.isFallback && p.isFallback())
63821 return geom === "vertex" ? "" : "iD-icon-" + p.id;
63824 if (geom === "line")
63825 return "iD-other-line";
63826 if (geom === "vertex")
63827 return "temaki-vertex";
63828 return "maki-marker-stroked";
63830 function renderPointBorder(container, drawPoint) {
63831 let pointBorder = container.selectAll(".preset-icon-point-border").data(drawPoint ? [0] : []);
63832 pointBorder.exit().remove();
63833 let pointBorderEnter = pointBorder.enter();
63836 pointBorderEnter.append("svg").attr("class", "preset-icon-fill preset-icon-point-border").attr("width", w).attr("height", h).attr("viewBox", `0 0 ${w} ${h}`).append("path").attr("transform", "translate(11.5, 8)").attr("d", "M 17,8 C 17,13 11,21 8.5,23.5 C 6,21 0,13 0,8 C 0,4 4,-0.5 8.5,-0.5 C 13,-0.5 17,4 17,8 z");
63837 pointBorder = pointBorderEnter.merge(pointBorder);
63839 function renderCategoryBorder(container, category) {
63840 let categoryBorder = container.selectAll(".preset-icon-category-border").data(category ? [0] : []);
63841 categoryBorder.exit().remove();
63842 let categoryBorderEnter = categoryBorder.enter();
63844 let svgEnter = categoryBorderEnter.append("svg").attr("class", "preset-icon-fill preset-icon-category-border").attr("width", d).attr("height", d).attr("viewBox", `0 0 ${d} ${d}`);
63845 svgEnter.append("path").attr("class", "area").attr("d", "M9.5,7.5 L25.5,7.5 L28.5,12.5 L49.5,12.5 C51.709139,12.5 53.5,14.290861 53.5,16.5 L53.5,43.5 C53.5,45.709139 51.709139,47.5 49.5,47.5 L10.5,47.5 C8.290861,47.5 6.5,45.709139 6.5,43.5 L6.5,12.5 L9.5,7.5 Z");
63846 categoryBorder = categoryBorderEnter.merge(categoryBorder);
63848 categoryBorder.selectAll("path").attr("class", `area ${category.id}`);
63851 function renderCircleFill(container, drawVertex) {
63852 let vertexFill = container.selectAll(".preset-icon-fill-vertex").data(drawVertex ? [0] : []);
63853 vertexFill.exit().remove();
63854 let vertexFillEnter = vertexFill.enter();
63858 vertexFillEnter.append("svg").attr("class", "preset-icon-fill preset-icon-fill-vertex").attr("width", w).attr("height", h).attr("viewBox", `0 0 ${w} ${h}`).append("circle").attr("cx", w / 2).attr("cy", h / 2).attr("r", d / 2);
63859 vertexFill = vertexFillEnter.merge(vertexFill);
63861 function renderSquareFill(container, drawArea, tagClasses) {
63862 let fill = container.selectAll(".preset-icon-fill-area").data(drawArea ? [0] : []);
63863 fill.exit().remove();
63864 let fillEnter = fill.enter();
63868 const l = d * 2 / 3;
63869 const c1 = (w - l) / 2;
63871 fillEnter = fillEnter.append("svg").attr("class", "preset-icon-fill preset-icon-fill-area").attr("width", w).attr("height", h).attr("viewBox", `0 0 ${w} ${h}`);
63872 ["fill", "stroke"].forEach((klass) => {
63873 fillEnter.append("path").attr("d", `M${c1} ${c1} L${c1} ${c2} L${c2} ${c2} L${c2} ${c1} Z`).attr("class", `area ${klass}`);
63875 const rVertex = 2.5;
63876 [[c1, c1], [c1, c2], [c2, c2], [c2, c1]].forEach((point2) => {
63877 fillEnter.append("circle").attr("class", "vertex").attr("cx", point2[0]).attr("cy", point2[1]).attr("r", rVertex);
63879 const rMidpoint = 1.25;
63880 [[c1, w / 2], [c2, w / 2], [h / 2, c1], [h / 2, c2]].forEach((point2) => {
63881 fillEnter.append("circle").attr("class", "midpoint").attr("cx", point2[0]).attr("cy", point2[1]).attr("r", rMidpoint);
63883 fill = fillEnter.merge(fill);
63884 fill.selectAll("path.stroke").attr("class", `area stroke ${tagClasses}`);
63885 fill.selectAll("path.fill").attr("class", `area fill ${tagClasses}`);
63887 function renderLine(container, drawLine, tagClasses) {
63888 let line = container.selectAll(".preset-icon-line").data(drawLine ? [0] : []);
63889 line.exit().remove();
63890 let lineEnter = line.enter();
63894 const y = Math.round(d * 0.72);
63895 const l = Math.round(d * 0.6);
63897 const x12 = (w - l) / 2;
63898 const x2 = x12 + l;
63899 lineEnter = lineEnter.append("svg").attr("class", "preset-icon-line").attr("width", w).attr("height", h).attr("viewBox", `0 0 ${w} ${h}`);
63900 ["casing", "stroke"].forEach((klass) => {
63901 lineEnter.append("path").attr("d", `M${x12} ${y} L${x2} ${y}`).attr("class", `line ${klass}`);
63903 [[x12 - 1, y], [x2 + 1, y]].forEach((point2) => {
63904 lineEnter.append("circle").attr("class", "vertex").attr("cx", point2[0]).attr("cy", point2[1]).attr("r", r);
63906 line = lineEnter.merge(line);
63907 line.selectAll("path.stroke").attr("class", `line stroke ${tagClasses}`);
63908 line.selectAll("path.casing").attr("class", `line casing ${tagClasses}`);
63910 function renderRoute(container, drawRoute, p) {
63911 let route = container.selectAll(".preset-icon-route").data(drawRoute ? [0] : []);
63912 route.exit().remove();
63913 let routeEnter = route.enter();
63917 const y12 = Math.round(d * 0.8);
63918 const y2 = Math.round(d * 0.68);
63919 const l = Math.round(d * 0.6);
63921 const x12 = (w - l) / 2;
63922 const x2 = x12 + l / 3;
63923 const x3 = x2 + l / 3;
63924 const x4 = x3 + l / 3;
63925 routeEnter = routeEnter.append("svg").attr("class", "preset-icon-route").attr("width", w).attr("height", h).attr("viewBox", `0 0 ${w} ${h}`);
63926 ["casing", "stroke"].forEach((klass) => {
63927 routeEnter.append("path").attr("d", `M${x12} ${y12} L${x2} ${y2}`).attr("class", `segment0 line ${klass}`);
63928 routeEnter.append("path").attr("d", `M${x2} ${y2} L${x3} ${y12}`).attr("class", `segment1 line ${klass}`);
63929 routeEnter.append("path").attr("d", `M${x3} ${y12} L${x4} ${y2}`).attr("class", `segment2 line ${klass}`);
63931 [[x12, y12], [x2, y2], [x3, y12], [x4, y2]].forEach((point2) => {
63932 routeEnter.append("circle").attr("class", "vertex").attr("cx", point2[0]).attr("cy", point2[1]).attr("r", r);
63934 route = routeEnter.merge(route);
63936 let routeType = p.tags.type === "waterway" ? "waterway" : p.tags.route;
63937 const segmentPresetIDs = routeSegments[routeType];
63938 for (let i2 in segmentPresetIDs) {
63939 const segmentPreset = _mainPresetIndex.item(segmentPresetIDs[i2]);
63940 const segmentTagClasses = svgTagClasses().getClassesString(segmentPreset.tags, "");
63941 route.selectAll(`path.stroke.segment${i2}`).attr("class", `segment${i2} line stroke ${segmentTagClasses}`);
63942 route.selectAll(`path.casing.segment${i2}`).attr("class", `segment${i2} line casing ${segmentTagClasses}`);
63946 function renderSvgIcon(container, picon, geom, isFramed, category, tagClasses) {
63947 const isMaki = picon && /^maki-/.test(picon);
63948 const isTemaki = picon && /^temaki-/.test(picon);
63949 const isFa = picon && /^fa[srb]-/.test(picon);
63950 const isR\u00F6ntgen = picon && /^roentgen-/.test(picon);
63951 const isiDIcon = picon && !(isMaki || isTemaki || isFa || isR\u00F6ntgen);
63952 let icon2 = container.selectAll(".preset-icon").data(picon ? [0] : []);
63953 icon2.exit().remove();
63954 icon2 = icon2.enter().append("div").attr("class", "preset-icon").call(svgIcon("")).merge(icon2);
63955 icon2.attr("class", "preset-icon " + (geom ? geom + "-geom" : "")).classed("category", category).classed("framed", isFramed).classed("preset-icon-iD", isiDIcon);
63956 icon2.selectAll("svg").attr("class", "icon " + picon + " " + (!isiDIcon && geom !== "line" ? "" : tagClasses));
63957 icon2.selectAll("use").attr("href", "#" + picon);
63959 function renderImageIcon(container, imageURL) {
63960 let imageIcon = container.selectAll("img.image-icon").data(imageURL ? [0] : []);
63961 imageIcon.exit().remove();
63962 imageIcon = imageIcon.enter().append("img").attr("class", "image-icon").on("load", () => container.classed("showing-img", true)).on("error", () => container.classed("showing-img", false)).merge(imageIcon);
63963 imageIcon.attr("src", imageURL);
63965 const routeSegments = {
63966 bicycle: ["highway/cycleway", "highway/cycleway", "highway/cycleway"],
63967 bus: ["highway/unclassified", "highway/secondary", "highway/primary"],
63968 trolleybus: ["highway/unclassified", "highway/secondary", "highway/primary"],
63969 detour: ["highway/tertiary", "highway/residential", "highway/unclassified"],
63970 ferry: ["route/ferry", "route/ferry", "route/ferry"],
63971 foot: ["highway/footway", "highway/footway", "highway/footway"],
63972 hiking: ["highway/path", "highway/path", "highway/path"],
63973 horse: ["highway/bridleway", "highway/bridleway", "highway/bridleway"],
63974 light_rail: ["railway/light_rail", "railway/light_rail", "railway/light_rail"],
63975 monorail: ["railway/monorail", "railway/monorail", "railway/monorail"],
63976 mtb: ["highway/path", "highway/track", "highway/bridleway"],
63977 pipeline: ["man_made/pipeline", "man_made/pipeline", "man_made/pipeline"],
63978 piste: ["piste/downhill", "piste/hike", "piste/nordic"],
63979 power: ["power/line", "power/line", "power/line"],
63980 road: ["highway/secondary", "highway/primary", "highway/trunk"],
63981 subway: ["railway/subway", "railway/subway", "railway/subway"],
63982 train: ["railway/rail", "railway/rail", "railway/rail"],
63983 tram: ["railway/tram", "railway/tram", "railway/tram"],
63984 waterway: ["waterway/stream", "waterway/stream", "waterway/stream"]
63986 function render() {
63987 let p = _preset.apply(this, arguments);
63988 let geom = _geometry ? _geometry.apply(this, arguments) : null;
63989 if (geom === "relation" && p.tags && (p.tags.type === "route" && p.tags.route && routeSegments[p.tags.route] || p.tags.type === "waterway")) {
63992 const showThirdPartyIcons = corePreferences("preferences.privacy.thirdpartyicons") || "true";
63993 const isFallback = p.isFallback && p.isFallback();
63994 const imageURL = showThirdPartyIcons === "true" && p.imageURL;
63995 const picon = getIcon(p, geom);
63996 const isCategory = !p.setTags;
63997 const drawPoint = false;
63998 const drawVertex = picon !== null && geom === "vertex";
63999 const drawLine = picon && geom === "line" && !isFallback && !isCategory;
64000 const drawArea = picon && geom === "area" && !isFallback && !isCategory;
64001 const drawRoute = picon && geom === "route";
64002 const isFramed = drawVertex || drawArea || drawLine || drawRoute || isCategory;
64003 let tags = !isCategory ? p.setTags({}, geom) : {};
64004 for (let k in tags) {
64005 if (tags[k] === "*") {
64009 let tagClasses = svgTagClasses().getClassesString(tags, "");
64010 let selection2 = select_default2(this);
64011 let container = selection2.selectAll(".preset-icon-container").data([0]);
64012 container = container.enter().append("div").attr("class", "preset-icon-container").merge(container);
64013 container.classed("showing-img", !!imageURL).classed("fallback", isFallback);
64014 renderCategoryBorder(container, isCategory && p);
64015 renderPointBorder(container, drawPoint);
64016 renderCircleFill(container, drawVertex);
64017 renderSquareFill(container, drawArea, tagClasses);
64018 renderLine(container, drawLine, tagClasses);
64019 renderRoute(container, drawRoute, p);
64020 renderSvgIcon(container, picon, geom, isFramed, isCategory, tagClasses);
64021 renderImageIcon(container, imageURL);
64023 presetIcon.preset = function(val) {
64024 if (!arguments.length)
64026 _preset = utilFunctor(val);
64029 presetIcon.geometry = function(val) {
64030 if (!arguments.length)
64032 _geometry = utilFunctor(val);
64038 // modules/ui/sections/feature_type.js
64039 function uiSectionFeatureType(context) {
64040 var dispatch10 = dispatch_default("choose");
64041 var _entityIDs = [];
64044 var section = uiSection("feature-type", context).label(() => _t.append("inspector.feature_type")).disclosureContent(renderDisclosureContent);
64045 function renderDisclosureContent(selection2) {
64046 selection2.classed("preset-list-item", true);
64047 selection2.classed("mixed-types", _presets.length > 1);
64048 var presetButtonWrap = selection2.selectAll(".preset-list-button-wrap").data([0]).enter().append("div").attr("class", "preset-list-button-wrap");
64049 var presetButton = presetButtonWrap.append("button").attr("class", "preset-list-button preset-reset").call(
64050 uiTooltip().title(() => _t.append("inspector.back_tooltip")).placement("bottom")
64052 presetButton.append("div").attr("class", "preset-icon-container");
64053 presetButton.append("div").attr("class", "label").append("div").attr("class", "label-inner");
64054 presetButtonWrap.append("div").attr("class", "accessory-buttons");
64055 var tagReferenceBodyWrap = selection2.selectAll(".tag-reference-body-wrap").data([0]);
64056 tagReferenceBodyWrap = tagReferenceBodyWrap.enter().append("div").attr("class", "tag-reference-body-wrap").merge(tagReferenceBodyWrap);
64057 if (_tagReference) {
64058 selection2.selectAll(".preset-list-button-wrap .accessory-buttons").style("display", _presets.length === 1 ? null : "none").call(_tagReference.button);
64059 tagReferenceBodyWrap.style("display", _presets.length === 1 ? null : "none").call(_tagReference.body);
64061 selection2.selectAll(".preset-reset").on("click", function() {
64062 dispatch10.call("choose", this, _presets);
64063 }).on("pointerdown pointerup mousedown mouseup", function(d3_event) {
64064 d3_event.preventDefault();
64065 d3_event.stopPropagation();
64067 var geometries = entityGeometries();
64068 selection2.select(".preset-list-item button").call(
64069 uiPresetIcon().geometry(_presets.length === 1 ? geometries.length === 1 && geometries[0] : null).preset(_presets.length === 1 ? _presets[0] : _mainPresetIndex.item("point"))
64071 var names = _presets.length === 1 ? [
64072 _presets[0].nameLabel(),
64073 _presets[0].subtitleLabel()
64074 ].filter(Boolean) : [_t.append("inspector.multiple_types")];
64075 var label = selection2.select(".label-inner");
64076 var nameparts = label.selectAll(".namepart").data(names, (d) => d.stringId);
64077 nameparts.exit().remove();
64078 nameparts.enter().append("div").attr("class", "namepart").text("").each(function(d) {
64079 d(select_default2(this));
64082 section.entityIDs = function(val) {
64083 if (!arguments.length)
64088 section.presets = function(val) {
64089 if (!arguments.length)
64091 if (!utilArrayIdentical(val, _presets)) {
64093 if (_presets.length === 1) {
64094 _tagReference = uiTagReference(_presets[0].reference(), context).showing(false);
64099 function entityGeometries() {
64101 for (var i2 in _entityIDs) {
64102 var geometry = context.graph().geometry(_entityIDs[i2]);
64103 if (!counts[geometry])
64104 counts[geometry] = 0;
64105 counts[geometry] += 1;
64107 return Object.keys(counts).sort(function(geom1, geom2) {
64108 return counts[geom2] - counts[geom1];
64111 return utilRebind(section, dispatch10, "on");
64114 // modules/ui/sections/preset_fields.js
64115 function uiSectionPresetFields(context) {
64116 var section = uiSection("preset-fields", context).label(() => _t.append("inspector.fields")).disclosureContent(renderDisclosureContent);
64117 var dispatch10 = dispatch_default("change", "revert");
64118 var formFields = uiFormFields(context);
64124 function renderDisclosureContent(selection2) {
64126 var graph = context.graph();
64127 var geometries = Object.keys(_entityIDs.reduce(function(geoms, entityID) {
64128 geoms[graph.entity(entityID).geometry(graph)] = true;
64131 var presetsManager = _mainPresetIndex;
64132 var allFields = [];
64133 var allMoreFields = [];
64134 var sharedTotalFields;
64135 _presets.forEach(function(preset) {
64136 var fields = preset.fields();
64137 var moreFields = preset.moreFields();
64138 allFields = utilArrayUnion(allFields, fields);
64139 allMoreFields = utilArrayUnion(allMoreFields, moreFields);
64140 if (!sharedTotalFields) {
64141 sharedTotalFields = utilArrayUnion(fields, moreFields);
64143 sharedTotalFields = sharedTotalFields.filter(function(field) {
64144 return fields.indexOf(field) !== -1 || moreFields.indexOf(field) !== -1;
64148 var sharedFields = allFields.filter(function(field) {
64149 return sharedTotalFields.indexOf(field) !== -1;
64151 var sharedMoreFields = allMoreFields.filter(function(field) {
64152 return sharedTotalFields.indexOf(field) !== -1;
64155 sharedFields.forEach(function(field) {
64156 if (field.matchAllGeometry(geometries)) {
64158 uiField(context, field, _entityIDs)
64162 var singularEntity = _entityIDs.length === 1 && graph.hasEntity(_entityIDs[0]);
64163 if (singularEntity && singularEntity.isHighwayIntersection(graph) && presetsManager.field("restrictions")) {
64165 uiField(context, presetsManager.field("restrictions"), _entityIDs)
64168 var additionalFields = utilArrayUnion(sharedMoreFields, presetsManager.universal());
64169 additionalFields.sort(function(field1, field2) {
64170 return field1.title().localeCompare(field2.title(), _mainLocalizer.localeCode());
64172 additionalFields.forEach(function(field) {
64173 if (sharedFields.indexOf(field) === -1 && field.matchAllGeometry(geometries)) {
64175 uiField(context, field, _entityIDs, { show: false })
64179 _fieldsArr.forEach(function(field) {
64180 field.on("change", function(t, onInput) {
64181 dispatch10.call("change", field, _entityIDs, t, onInput);
64182 }).on("revert", function(keys) {
64183 dispatch10.call("revert", field, keys);
64187 _fieldsArr.forEach(function(field) {
64188 field.state(_state).tags(_tags);
64191 formFields.fieldsArr(_fieldsArr).state(_state).klass("grouped-items-area")
64194 section.presets = function(val) {
64195 if (!arguments.length)
64197 if (!_presets || !val || !utilArrayIdentical(_presets, val)) {
64203 section.state = function(val) {
64204 if (!arguments.length)
64209 section.tags = function(val) {
64210 if (!arguments.length)
64215 section.entityIDs = function(val) {
64216 if (!arguments.length)
64218 if (!val || !_entityIDs || !utilArrayIdentical(_entityIDs, val)) {
64224 return utilRebind(section, dispatch10, "on");
64227 // modules/ui/sections/raw_member_editor.js
64228 function uiSectionRawMemberEditor(context) {
64229 var section = uiSection("raw-member-editor", context).shouldDisplay(function() {
64230 if (!_entityIDs || _entityIDs.length !== 1)
64232 var entity = context.hasEntity(_entityIDs[0]);
64233 return entity && entity.type === "relation";
64234 }).label(function() {
64235 var entity = context.hasEntity(_entityIDs[0]);
64238 var gt = entity.members.length > _maxMembers ? ">" : "";
64239 var count = gt + entity.members.slice(0, _maxMembers).length;
64240 return _t.append("inspector.title_count", { title: _t("inspector.members"), count });
64241 }).disclosureContent(renderDisclosureContent);
64242 var taginfo = services.taginfo;
64244 var _maxMembers = 1e3;
64245 function downloadMember(d3_event, d) {
64246 d3_event.preventDefault();
64247 select_default2(this.parentNode).classed("tag-reference-loading", true);
64248 context.loadEntity(d.id, function() {
64249 section.reRender();
64252 function zoomToMember(d3_event, d) {
64253 d3_event.preventDefault();
64254 var entity = context.entity(d.id);
64255 context.map().zoomToEase(entity);
64256 utilHighlightEntities([d.id], true, context);
64258 function selectMember(d3_event, d) {
64259 d3_event.preventDefault();
64260 utilHighlightEntities([d.id], false, context);
64261 var entity = context.entity(d.id);
64262 var mapExtent = context.map().extent();
64263 if (!entity.intersects(mapExtent, context.graph())) {
64264 context.map().zoomToEase(entity);
64266 context.enter(modeSelect(context, [d.id]));
64268 function changeRole(d3_event, d) {
64269 var oldRole = d.role;
64270 var newRole = context.cleanRelationRole(select_default2(this).property("value"));
64271 if (oldRole !== newRole) {
64272 var member = { id: d.id, type: d.type, role: newRole };
64274 actionChangeMember(d.relation.id, member, d.index),
64275 _t("operations.change_role.annotation", {
64279 context.validator().validate();
64282 function deleteMember(d3_event, d) {
64283 utilHighlightEntities([d.id], false, context);
64285 actionDeleteMember(d.relation.id, d.index),
64286 _t("operations.delete_member.annotation", {
64290 if (!context.hasEntity(d.relation.id)) {
64291 context.enter(modeBrowse(context));
64293 context.validator().validate();
64296 function renderDisclosureContent(selection2) {
64297 var entityID = _entityIDs[0];
64298 var memberships = [];
64299 var entity = context.entity(entityID);
64300 entity.members.slice(0, _maxMembers).forEach(function(member, index) {
64307 member: context.hasEntity(member.id),
64308 domId: utilUniqueDomId(entityID + "-member-" + index)
64311 var list = selection2.selectAll(".member-list").data([0]);
64312 list = list.enter().append("ul").attr("class", "member-list").merge(list);
64313 var items = list.selectAll("li").data(memberships, function(d) {
64314 return osmEntity.key(d.relation) + "," + d.index + "," + (d.member ? osmEntity.key(d.member) : "incomplete");
64316 items.exit().each(unbind).remove();
64317 var itemsEnter = items.enter().append("li").attr("class", "member-row form-field").classed("member-incomplete", function(d) {
64320 itemsEnter.each(function(d) {
64321 var item = select_default2(this);
64322 var label = item.append("label").attr("class", "field-label").attr("for", d.domId);
64324 item.on("mouseover", function() {
64325 utilHighlightEntities([d.id], true, context);
64326 }).on("mouseout", function() {
64327 utilHighlightEntities([d.id], false, context);
64329 var labelLink = label.append("span").attr("class", "label-text").append("a").attr("href", "#").on("click", selectMember);
64330 labelLink.append("span").attr("class", "member-entity-type").text(function(d2) {
64331 var matched = _mainPresetIndex.match(d2.member, context.graph());
64332 return matched && matched.name() || utilDisplayType(d2.member.id);
64334 labelLink.append("span").attr("class", "member-entity-name").text(function(d2) {
64335 return utilDisplayName(d2.member);
64337 label.append("button").attr("title", _t("icons.remove")).attr("class", "remove member-delete").call(svgIcon("#iD-operation-delete"));
64338 label.append("button").attr("class", "member-zoom").attr("title", _t("icons.zoom_to")).call(svgIcon("#iD-icon-framed-dot", "monochrome")).on("click", zoomToMember);
64340 var labelText = label.append("span").attr("class", "label-text");
64341 labelText.append("span").attr("class", "member-entity-type").call(_t.append("inspector." + d.type, { id: d.id }));
64342 labelText.append("span").attr("class", "member-entity-name").call(_t.append("inspector.incomplete", { id: d.id }));
64343 label.append("button").attr("class", "member-download").attr("title", _t("icons.download")).call(svgIcon("#iD-icon-load")).on("click", downloadMember);
64346 var wrapEnter = itemsEnter.append("div").attr("class", "form-field-input-wrap form-field-input-member");
64347 wrapEnter.append("input").attr("class", "member-role").attr("id", function(d) {
64349 }).property("type", "text").attr("placeholder", _t("inspector.role")).call(utilNoAuto);
64351 wrapEnter.each(bindTypeahead);
64353 items = items.merge(itemsEnter).order();
64354 items.select("input.member-role").property("value", function(d) {
64356 }).on("blur", changeRole).on("change", changeRole);
64357 items.select("button.member-delete").on("click", deleteMember);
64358 var dragOrigin, targetIndex;
64360 drag_default().on("start", function(d3_event) {
64365 targetIndex = null;
64366 }).on("drag", function(d3_event) {
64367 var x = d3_event.x - dragOrigin.x, y = d3_event.y - dragOrigin.y;
64368 if (!select_default2(this).classed("dragging") && // don't display drag until dragging beyond a distance threshold
64369 Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)) <= 5)
64371 var index = items.nodes().indexOf(this);
64372 select_default2(this).classed("dragging", true);
64373 targetIndex = null;
64374 selection2.selectAll("li.member-row").style("transform", function(d2, index2) {
64375 var node = select_default2(this).node();
64376 if (index === index2) {
64377 return "translate(" + x + "px, " + y + "px)";
64378 } else if (index2 > index && d3_event.y > node.offsetTop) {
64379 if (targetIndex === null || index2 > targetIndex) {
64380 targetIndex = index2;
64382 return "translateY(-100%)";
64383 } else if (index2 < index && d3_event.y < node.offsetTop + node.offsetHeight) {
64384 if (targetIndex === null || index2 < targetIndex) {
64385 targetIndex = index2;
64387 return "translateY(100%)";
64391 }).on("end", function(d3_event, d) {
64392 if (!select_default2(this).classed("dragging"))
64394 var index = items.nodes().indexOf(this);
64395 select_default2(this).classed("dragging", false);
64396 selection2.selectAll("li.member-row").style("transform", null);
64397 if (targetIndex !== null) {
64399 actionMoveMember(d.relation.id, index, targetIndex),
64400 _t("operations.reorder_members.annotation")
64402 context.validator().validate();
64406 function bindTypeahead(d) {
64407 var row = select_default2(this);
64408 var role = row.selectAll("input.member-role");
64409 var origValue = role.property("value");
64410 function sort(value, data) {
64411 var sameletter = [];
64413 for (var i2 = 0; i2 < data.length; i2++) {
64414 if (data[i2].value.substring(0, value.length) === value) {
64415 sameletter.push(data[i2]);
64417 other.push(data[i2]);
64420 return sameletter.concat(other);
64423 uiCombobox(context, "member-role").fetcher(function(role2, callback) {
64426 geometry = context.graph().geometry(d.member.id);
64427 } else if (d.type === "relation") {
64428 geometry = "relation";
64429 } else if (d.type === "way") {
64432 geometry = "point";
64434 var rtype = entity.tags.type;
64437 rtype: rtype || "",
64440 }, function(err, data) {
64442 callback(sort(role2, data));
64444 }).on("cancel", function() {
64445 role.property("value", origValue);
64449 function unbind() {
64450 var row = select_default2(this);
64451 row.selectAll("input.member-role").call(uiCombobox.off, context);
64454 section.entityIDs = function(val) {
64455 if (!arguments.length)
64463 // modules/actions/delete_members.js
64464 function actionDeleteMembers(relationId, memberIndexes) {
64465 return function(graph) {
64466 memberIndexes.sort((a, b) => b - a);
64467 for (var i2 in memberIndexes) {
64468 graph = actionDeleteMember(relationId, memberIndexes[i2])(graph);
64474 // modules/ui/sections/raw_membership_editor.js
64475 function uiSectionRawMembershipEditor(context) {
64476 var section = uiSection("raw-membership-editor", context).shouldDisplay(function() {
64477 return _entityIDs && _entityIDs.length;
64478 }).label(function() {
64479 var parents = getSharedParentRelations();
64480 var gt = parents.length > _maxMemberships ? ">" : "";
64481 var count = gt + parents.slice(0, _maxMemberships).length;
64482 return _t.append("inspector.title_count", { title: _t("inspector.relations"), count });
64483 }).disclosureContent(renderDisclosureContent);
64484 var taginfo = services.taginfo;
64485 var nearbyCombo = uiCombobox(context, "parent-relation").minItems(1).fetcher(fetchNearbyRelations).itemsMouseEnter(function(d3_event, d) {
64487 utilHighlightEntities([d.relation.id], true, context);
64488 }).itemsMouseLeave(function(d3_event, d) {
64490 utilHighlightEntities([d.relation.id], false, context);
64492 var _inChange = false;
64493 var _entityIDs = [];
64495 var _maxMemberships = 1e3;
64496 function getSharedParentRelations() {
64498 for (var i2 = 0; i2 < _entityIDs.length; i2++) {
64499 var entity = context.graph().hasEntity(_entityIDs[i2]);
64503 parents = context.graph().parentRelations(entity);
64505 parents = utilArrayIntersection(parents, context.graph().parentRelations(entity));
64507 if (!parents.length)
64512 function getMemberships() {
64513 var memberships = [];
64514 var relations = getSharedParentRelations().slice(0, _maxMemberships);
64515 var isMultiselect = _entityIDs.length > 1;
64516 var i2, relation, membership, index, member, indexedMember;
64517 for (i2 = 0; i2 < relations.length; i2++) {
64518 relation = relations[i2];
64522 hash: osmEntity.key(relation)
64524 for (index = 0; index < relation.members.length; index++) {
64525 member = relation.members[index];
64526 if (_entityIDs.indexOf(member.id) !== -1) {
64527 indexedMember = Object.assign({}, member, { index });
64528 membership.members.push(indexedMember);
64529 membership.hash += "," + index.toString();
64530 if (!isMultiselect) {
64531 memberships.push(membership);
64535 hash: osmEntity.key(relation)
64540 if (membership.members.length)
64541 memberships.push(membership);
64543 memberships.forEach(function(membership2) {
64544 membership2.domId = utilUniqueDomId("membership-" + membership2.relation.id);
64546 membership2.members.forEach(function(member2) {
64547 if (roles.indexOf(member2.role) === -1)
64548 roles.push(member2.role);
64550 membership2.role = roles.length === 1 ? roles[0] : roles;
64552 return memberships;
64554 function selectRelation(d3_event, d) {
64555 d3_event.preventDefault();
64556 utilHighlightEntities([d.relation.id], false, context);
64557 context.enter(modeSelect(context, [d.relation.id]));
64559 function zoomToRelation(d3_event, d) {
64560 d3_event.preventDefault();
64561 var entity = context.entity(d.relation.id);
64562 context.map().zoomToEase(entity);
64563 utilHighlightEntities([d.relation.id], true, context);
64565 function changeRole(d3_event, d) {
64570 var newRole = context.cleanRelationRole(select_default2(this).property("value"));
64571 if (!newRole.trim() && typeof d.role !== "string")
64573 var membersToUpdate = d.members.filter(function(member) {
64574 return member.role !== newRole;
64576 if (membersToUpdate.length) {
64579 function actionChangeMemberRoles(graph) {
64580 membersToUpdate.forEach(function(member) {
64581 var newMember = Object.assign({}, member, { role: newRole });
64582 delete newMember.index;
64583 graph = actionChangeMember(d.relation.id, newMember, member.index)(graph);
64587 _t("operations.change_role.annotation", {
64588 n: membersToUpdate.length
64591 context.validator().validate();
64595 function addMembership(d, role) {
64597 _showBlank = false;
64598 function actionAddMembers(relationId, ids, role2) {
64599 return function(graph) {
64600 for (var i2 in ids) {
64601 var member = { id: ids[i2], type: graph.entity(ids[i2]).type, role: role2 };
64602 graph = actionAddMember(relationId, member)(graph);
64609 actionAddMembers(d.relation.id, _entityIDs, role),
64610 _t("operations.add_member.annotation", {
64611 n: _entityIDs.length
64614 context.validator().validate();
64616 var relation = osmRelation();
64618 actionAddEntity(relation),
64619 actionAddMembers(relation.id, _entityIDs, role),
64620 _t("operations.add.annotation.relation")
64622 context.enter(modeSelect(context, [relation.id]).newFeature(true));
64625 function deleteMembership(d3_event, d) {
64629 utilHighlightEntities([d.relation.id], false, context);
64630 var indexes = d.members.map(function(member) {
64631 return member.index;
64634 actionDeleteMembers(d.relation.id, indexes),
64635 _t("operations.delete_member.annotation", {
64636 n: _entityIDs.length
64639 context.validator().validate();
64641 function fetchNearbyRelations(q, callback) {
64642 var newRelation = {
64644 value: _t("inspector.new_relation"),
64645 display: _t.append("inspector.new_relation")
64647 var entityID = _entityIDs[0];
64649 var graph = context.graph();
64650 function baseDisplayLabel(entity) {
64651 var matched = _mainPresetIndex.match(entity, graph);
64652 var presetName = matched && matched.name() || _t("inspector.relation");
64653 var entityName = utilDisplayName(entity) || "";
64654 return presetName + " " + entityName;
64656 var explicitRelation = q && context.hasEntity(q.toLowerCase());
64657 if (explicitRelation && explicitRelation.type === "relation" && explicitRelation.id !== entityID) {
64659 relation: explicitRelation,
64660 value: baseDisplayLabel(explicitRelation) + " " + explicitRelation.id
64663 context.history().intersects(context.map().extent()).forEach(function(entity) {
64664 if (entity.type !== "relation" || entity.id === entityID)
64666 var value = baseDisplayLabel(entity);
64667 if (q && (value + " " + entity.id).toLowerCase().indexOf(q.toLowerCase()) === -1)
64669 result.push({ relation: entity, value });
64671 result.sort(function(a, b) {
64672 return osmRelation.creationOrder(a.relation, b.relation);
64674 var dupeGroups = Object.values(utilArrayGroupBy(result, "value")).filter(function(v) {
64675 return v.length > 1;
64677 dupeGroups.forEach(function(group) {
64678 group.forEach(function(obj) {
64679 obj.value += " " + obj.relation.id;
64683 result.forEach(function(obj) {
64684 obj.title = obj.value;
64686 result.unshift(newRelation);
64689 function renderDisclosureContent(selection2) {
64690 var memberships = getMemberships();
64691 var list = selection2.selectAll(".member-list").data([0]);
64692 list = list.enter().append("ul").attr("class", "member-list").merge(list);
64693 var items = list.selectAll("li.member-row-normal").data(memberships, function(d) {
64696 items.exit().each(unbind).remove();
64697 var itemsEnter = items.enter().append("li").attr("class", "member-row member-row-normal form-field");
64698 itemsEnter.on("mouseover", function(d3_event, d) {
64699 utilHighlightEntities([d.relation.id], true, context);
64700 }).on("mouseout", function(d3_event, d) {
64701 utilHighlightEntities([d.relation.id], false, context);
64703 var labelEnter = itemsEnter.append("label").attr("class", "field-label").attr("for", function(d) {
64706 var labelLink = labelEnter.append("span").attr("class", "label-text").append("a").attr("href", "#").on("click", selectRelation);
64707 labelLink.append("span").attr("class", "member-entity-type").text(function(d) {
64708 var matched = _mainPresetIndex.match(d.relation, context.graph());
64709 return matched && matched.name() || _t.html("inspector.relation");
64711 labelLink.append("span").attr("class", "member-entity-name").text(function(d) {
64712 return utilDisplayName(d.relation);
64714 labelEnter.append("button").attr("class", "remove member-delete").attr("title", _t("icons.remove")).call(svgIcon("#iD-operation-delete")).on("click", deleteMembership);
64715 labelEnter.append("button").attr("class", "member-zoom").attr("title", _t("icons.zoom_to")).call(svgIcon("#iD-icon-framed-dot", "monochrome")).on("click", zoomToRelation);
64716 var wrapEnter = itemsEnter.append("div").attr("class", "form-field-input-wrap form-field-input-member");
64717 wrapEnter.append("input").attr("class", "member-role").attr("id", function(d) {
64719 }).property("type", "text").property("value", function(d) {
64720 return typeof d.role === "string" ? d.role : "";
64721 }).attr("title", function(d) {
64722 return Array.isArray(d.role) ? d.role.filter(Boolean).join("\n") : d.role;
64723 }).attr("placeholder", function(d) {
64724 return Array.isArray(d.role) ? _t("inspector.multiple_roles") : _t("inspector.role");
64725 }).classed("mixed", function(d) {
64726 return Array.isArray(d.role);
64727 }).call(utilNoAuto).on("blur", changeRole).on("change", changeRole);
64729 wrapEnter.each(bindTypeahead);
64731 var newMembership = list.selectAll(".member-row-new").data(_showBlank ? [0] : []);
64732 newMembership.exit().remove();
64733 var newMembershipEnter = newMembership.enter().append("li").attr("class", "member-row member-row-new form-field");
64734 var newLabelEnter = newMembershipEnter.append("label").attr("class", "field-label");
64735 newLabelEnter.append("input").attr("placeholder", _t("inspector.choose_relation")).attr("type", "text").attr("class", "member-entity-input").call(utilNoAuto);
64736 newLabelEnter.append("button").attr("class", "remove member-delete").attr("title", _t("icons.remove")).call(svgIcon("#iD-operation-delete")).on("click", function() {
64737 list.selectAll(".member-row-new").remove();
64739 var newWrapEnter = newMembershipEnter.append("div").attr("class", "form-field-input-wrap form-field-input-member");
64740 newWrapEnter.append("input").attr("class", "member-role").property("type", "text").attr("placeholder", _t("inspector.role")).call(utilNoAuto);
64741 newMembership = newMembership.merge(newMembershipEnter);
64742 newMembership.selectAll(".member-entity-input").on("blur", cancelEntity).call(
64743 nearbyCombo.on("accept", acceptEntity).on("cancel", cancelEntity)
64745 var addRow = selection2.selectAll(".add-row").data([0]);
64746 var addRowEnter = addRow.enter().append("div").attr("class", "add-row");
64747 var addRelationButton = addRowEnter.append("button").attr("class", "add-relation").attr("aria-label", _t("inspector.add_to_relation"));
64748 addRelationButton.call(svgIcon("#iD-icon-plus", "light"));
64749 addRelationButton.call(uiTooltip().title(() => _t.append("inspector.add_to_relation")).placement(_mainLocalizer.textDirection() === "ltr" ? "right" : "left"));
64750 addRowEnter.append("div").attr("class", "space-value");
64751 addRowEnter.append("div").attr("class", "space-buttons");
64752 addRow = addRow.merge(addRowEnter);
64753 addRow.select(".add-relation").on("click", function() {
64755 section.reRender();
64756 list.selectAll(".member-entity-input").node().focus();
64758 function acceptEntity(d) {
64764 utilHighlightEntities([d.relation.id], false, context);
64765 var role = context.cleanRelationRole(list.selectAll(".member-row-new .member-role").property("value"));
64766 addMembership(d, role);
64768 function cancelEntity() {
64769 var input = newMembership.selectAll(".member-entity-input");
64770 input.property("value", "");
64771 context.surface().selectAll(".highlighted").classed("highlighted", false);
64773 function bindTypeahead(d) {
64774 var row = select_default2(this);
64775 var role = row.selectAll("input.member-role");
64776 var origValue = role.property("value");
64777 function sort(value, data) {
64778 var sameletter = [];
64780 for (var i2 = 0; i2 < data.length; i2++) {
64781 if (data[i2].value.substring(0, value.length) === value) {
64782 sameletter.push(data[i2]);
64784 other.push(data[i2]);
64787 return sameletter.concat(other);
64790 uiCombobox(context, "member-role").fetcher(function(role2, callback) {
64791 var rtype = d.relation.tags.type;
64794 rtype: rtype || "",
64795 geometry: context.graph().geometry(_entityIDs[0]),
64797 }, function(err, data) {
64799 callback(sort(role2, data));
64801 }).on("cancel", function() {
64802 role.property("value", origValue);
64806 function unbind() {
64807 var row = select_default2(this);
64808 row.selectAll("input.member-role").call(uiCombobox.off, context);
64811 section.entityIDs = function(val) {
64812 if (!arguments.length)
64815 _showBlank = false;
64821 // modules/ui/sections/selection_list.js
64822 function uiSectionSelectionList(context) {
64823 var _selectedIDs = [];
64824 var section = uiSection("selected-features", context).shouldDisplay(function() {
64825 return _selectedIDs.length > 1;
64826 }).label(function() {
64827 return _t.append("inspector.title_count", { title: _t("inspector.features"), count: _selectedIDs.length });
64828 }).disclosureContent(renderDisclosureContent);
64829 context.history().on("change.selectionList", function(difference) {
64831 section.reRender();
64834 section.entityIDs = function(val) {
64835 if (!arguments.length)
64836 return _selectedIDs;
64837 _selectedIDs = val;
64840 function selectEntity(d3_event, entity) {
64841 context.enter(modeSelect(context, [entity.id]));
64843 function deselectEntity(d3_event, entity) {
64844 var selectedIDs = _selectedIDs.slice();
64845 var index = selectedIDs.indexOf(entity.id);
64847 selectedIDs.splice(index, 1);
64848 context.enter(modeSelect(context, selectedIDs));
64851 function renderDisclosureContent(selection2) {
64852 var list = selection2.selectAll(".feature-list").data([0]);
64853 list = list.enter().append("ul").attr("class", "feature-list").merge(list);
64854 var entities = _selectedIDs.map(function(id2) {
64855 return context.hasEntity(id2);
64856 }).filter(Boolean);
64857 var items = list.selectAll(".feature-list-item").data(entities, osmEntity.key);
64858 items.exit().remove();
64859 var enter = items.enter().append("li").attr("class", "feature-list-item").each(function(d) {
64860 select_default2(this).on("mouseover", function() {
64861 utilHighlightEntities([d.id], true, context);
64862 }).on("mouseout", function() {
64863 utilHighlightEntities([d.id], false, context);
64866 var label = enter.append("button").attr("class", "label").on("click", selectEntity);
64867 label.append("span").attr("class", "entity-geom-icon").call(svgIcon("", "pre-text"));
64868 label.append("span").attr("class", "entity-type");
64869 label.append("span").attr("class", "entity-name");
64870 enter.append("button").attr("class", "close").attr("title", _t("icons.deselect")).on("click", deselectEntity).call(svgIcon("#iD-icon-close"));
64871 items = items.merge(enter);
64872 items.selectAll(".entity-geom-icon use").attr("href", function() {
64873 var entity = this.parentNode.parentNode.__data__;
64874 return "#iD-icon-" + entity.geometry(context.graph());
64876 items.selectAll(".entity-type").text(function(entity) {
64877 return _mainPresetIndex.match(entity, context.graph()).name();
64879 items.selectAll(".entity-name").text(function(d) {
64880 var entity = context.entity(d.id);
64881 return utilDisplayName(entity);
64887 // modules/ui/entity_editor.js
64888 function uiEntityEditor(context) {
64889 var dispatch10 = dispatch_default("choose");
64890 var _state = "select";
64891 var _coalesceChanges = false;
64892 var _modified = false;
64895 var _activePresets = [];
64898 function entityEditor(selection2) {
64899 var combinedTags = utilCombinedTags(_entityIDs, context.graph());
64900 var header = selection2.selectAll(".header").data([0]);
64901 var headerEnter = header.enter().append("div").attr("class", "header fillL");
64902 var direction = _mainLocalizer.textDirection() === "rtl" ? "forward" : "backward";
64903 headerEnter.append("button").attr("class", "preset-reset preset-choose").attr("title", _t("inspector.back_tooltip")).call(svgIcon(`#iD-icon-${direction}`));
64904 headerEnter.append("button").attr("class", "close").attr("title", _t("icons.close")).on("click", function() {
64905 context.enter(modeBrowse(context));
64906 }).call(svgIcon(_modified ? "#iD-icon-apply" : "#iD-icon-close"));
64907 headerEnter.append("h2");
64908 header = header.merge(headerEnter);
64909 header.selectAll("h2").text("").call(_entityIDs.length === 1 ? _t.append("inspector.edit") : _t.append("inspector.edit_features"));
64910 header.selectAll(".preset-reset").on("click", function() {
64911 dispatch10.call("choose", this, _activePresets);
64913 var body = selection2.selectAll(".inspector-body").data([0]);
64914 var bodyEnter = body.enter().append("div").attr("class", "entity-editor inspector-body sep-top");
64915 body = body.merge(bodyEnter);
64918 uiSectionSelectionList(context),
64919 uiSectionFeatureType(context).on("choose", function(presets) {
64920 dispatch10.call("choose", this, presets);
64922 uiSectionEntityIssues(context),
64923 uiSectionPresetFields(context).on("change", changeTags).on("revert", revertTags),
64924 uiSectionRawTagEditor("raw-tag-editor", context).on("change", changeTags),
64925 uiSectionRawMemberEditor(context),
64926 uiSectionRawMembershipEditor(context)
64929 _sections.forEach(function(section) {
64930 if (section.entityIDs) {
64931 section.entityIDs(_entityIDs);
64933 if (section.presets) {
64934 section.presets(_activePresets);
64936 if (section.tags) {
64937 section.tags(combinedTags);
64939 if (section.state) {
64940 section.state(_state);
64942 body.call(section.render);
64944 context.history().on("change.entity-editor", historyChanged);
64945 function historyChanged(difference) {
64946 if (selection2.selectAll(".entity-editor").empty())
64948 if (_state === "hide")
64950 var significant = !difference || difference.didChange.properties || difference.didChange.addition || difference.didChange.deletion;
64953 _entityIDs = _entityIDs.filter(context.hasEntity);
64954 if (!_entityIDs.length)
64956 var priorActivePreset = _activePresets.length === 1 && _activePresets[0];
64957 loadActivePresets();
64958 var graph = context.graph();
64959 entityEditor.modified(_base !== graph);
64960 entityEditor(selection2);
64961 if (priorActivePreset && _activePresets.length === 1 && priorActivePreset !== _activePresets[0]) {
64962 context.container().selectAll(".entity-editor button.preset-reset .label").style("background-color", "#fff").transition().duration(750).style("background-color", null);
64966 function changeTags(entityIDs, changed, onInput) {
64968 for (var i2 in entityIDs) {
64969 var entityID = entityIDs[i2];
64970 var entity = context.entity(entityID);
64971 var tags = Object.assign({}, entity.tags);
64972 if (typeof changed === "function") {
64973 tags = changed(tags);
64975 for (var k in changed) {
64978 var v = changed[k];
64979 if (typeof v === "object") {
64980 tags[k] = tags[v.oldKey];
64981 } else if (v !== void 0 || tags.hasOwnProperty(k)) {
64987 tags = utilCleanTags(tags);
64989 if (!(0, import_fast_deep_equal10.default)(entity.tags, tags)) {
64990 actions.push(actionChangeTags(entityID, tags));
64993 if (actions.length) {
64994 var combinedAction = function(graph) {
64995 actions.forEach(function(action) {
64996 graph = action(graph);
65000 var annotation = _t("operations.change_tags.annotation");
65001 if (_coalesceChanges) {
65002 context.overwrite(combinedAction, annotation);
65004 context.perform(combinedAction, annotation);
65005 _coalesceChanges = !!onInput;
65009 context.validator().validate();
65012 function revertTags(keys) {
65014 for (var i2 in _entityIDs) {
65015 var entityID = _entityIDs[i2];
65016 var original = context.graph().base().entities[entityID];
65018 for (var j2 in keys) {
65019 var key = keys[j2];
65020 changed[key] = original ? original.tags[key] : void 0;
65022 var entity = context.entity(entityID);
65023 var tags = Object.assign({}, entity.tags);
65024 for (var k in changed) {
65027 var v = changed[k];
65028 if (v !== void 0 || tags.hasOwnProperty(k)) {
65032 tags = utilCleanTags(tags);
65033 if (!(0, import_fast_deep_equal10.default)(entity.tags, tags)) {
65034 actions.push(actionChangeTags(entityID, tags));
65037 if (actions.length) {
65038 var combinedAction = function(graph) {
65039 actions.forEach(function(action) {
65040 graph = action(graph);
65044 var annotation = _t("operations.change_tags.annotation");
65045 if (_coalesceChanges) {
65046 context.overwrite(combinedAction, annotation);
65048 context.perform(combinedAction, annotation);
65049 _coalesceChanges = false;
65052 context.validator().validate();
65054 entityEditor.modified = function(val) {
65055 if (!arguments.length)
65058 return entityEditor;
65060 entityEditor.state = function(val) {
65061 if (!arguments.length)
65064 return entityEditor;
65066 entityEditor.entityIDs = function(val) {
65067 if (!arguments.length)
65069 _base = context.graph();
65070 _coalesceChanges = false;
65071 if (val && _entityIDs && utilArrayIdentical(_entityIDs, val))
65072 return entityEditor;
65074 loadActivePresets(true);
65075 return entityEditor.modified(false);
65077 entityEditor.newFeature = function(val) {
65078 if (!arguments.length)
65079 return _newFeature;
65081 return entityEditor;
65083 function loadActivePresets(isForNewSelection) {
65084 var graph = context.graph();
65086 for (var i2 in _entityIDs) {
65087 var entity = graph.hasEntity(_entityIDs[i2]);
65090 var match = _mainPresetIndex.match(entity, graph);
65091 if (!counts[match.id])
65092 counts[match.id] = 0;
65093 counts[match.id] += 1;
65095 var matches = Object.keys(counts).sort(function(p1, p2) {
65096 return counts[p2] - counts[p1];
65097 }).map(function(pID) {
65098 return _mainPresetIndex.item(pID);
65100 if (!isForNewSelection) {
65101 var weakPreset = _activePresets.length === 1 && !_activePresets[0].isFallback() && Object.keys(_activePresets[0].addTags || {}).length === 0;
65102 if (weakPreset && matches.length === 1 && matches[0].isFallback())
65105 entityEditor.presets(matches);
65107 entityEditor.presets = function(val) {
65108 if (!arguments.length)
65109 return _activePresets;
65110 if (!utilArrayIdentical(val, _activePresets)) {
65111 _activePresets = val;
65113 return entityEditor;
65115 return utilRebind(entityEditor, dispatch10, "on");
65118 // modules/ui/feature_list.js
65119 var sexagesimal = __toESM(require_sexagesimal());
65120 function uiFeatureList(context) {
65121 var _geocodeResults;
65122 function featureList(selection2) {
65123 var header = selection2.append("div").attr("class", "header fillL");
65124 header.append("h2").call(_t.append("inspector.feature_list"));
65125 var searchWrap = selection2.append("div").attr("class", "search-header");
65126 searchWrap.call(svgIcon("#iD-icon-search", "pre-text"));
65127 var search = searchWrap.append("input").attr("placeholder", _t("inspector.search")).attr("type", "search").call(utilNoAuto).on("keypress", keypress).on("keydown", keydown).on("input", inputevent);
65128 var listWrap = selection2.append("div").attr("class", "inspector-body");
65129 var list = listWrap.append("div").attr("class", "feature-list");
65130 context.on("exit.feature-list", clearSearch);
65131 context.map().on("drawn.feature-list", mapDrawn);
65132 context.keybinding().on(uiCmd("\u2318F"), focusSearch);
65133 function focusSearch(d3_event) {
65134 var mode = context.mode() && context.mode().id;
65135 if (mode !== "browse")
65137 d3_event.preventDefault();
65138 search.node().focus();
65140 function keydown(d3_event) {
65141 if (d3_event.keyCode === 27) {
65142 search.node().blur();
65145 function keypress(d3_event) {
65146 var q = search.property("value"), items = list.selectAll(".feature-list-item");
65147 if (d3_event.keyCode === 13 && // ↩ Return
65148 q.length && items.size()) {
65149 click(d3_event, items.datum());
65152 function inputevent() {
65153 _geocodeResults = void 0;
65156 function clearSearch() {
65157 search.property("value", "");
65160 function mapDrawn(e) {
65165 function features() {
65167 var graph = context.graph();
65168 var visibleCenter = context.map().extent().center();
65169 var q = search.property("value").toLowerCase();
65172 var locationMatch = sexagesimal.pair(q.toUpperCase()) || q.match(/^(-?\d+\.?\d*)\s+(-?\d+\.?\d*)$/);
65173 if (locationMatch) {
65174 var loc = [Number(locationMatch[0]), Number(locationMatch[1])];
65178 type: _t("inspector.location"),
65179 name: dmsCoordinatePair([loc[1], loc[0]]),
65183 var idMatch = !locationMatch && q.match(/(?:^|\W)(node|way|relation|[nwr])\W?0*([1-9]\d*)(?:\W|$)/i);
65185 var elemType = idMatch[1].charAt(0);
65186 var elemId = idMatch[2];
65188 id: elemType + elemId,
65189 geometry: elemType === "n" ? "point" : elemType === "w" ? "line" : "relation",
65190 type: elemType === "n" ? _t("inspector.node") : elemType === "w" ? _t("inspector.way") : _t("inspector.relation"),
65194 var allEntities = graph.entities;
65195 var localResults = [];
65196 for (var id2 in allEntities) {
65197 var entity = allEntities[id2];
65200 var name = utilDisplayName(entity) || "";
65201 if (name.toLowerCase().indexOf(q) < 0)
65203 var matched = _mainPresetIndex.match(entity, graph);
65204 var type2 = matched && matched.name() || utilDisplayType(entity.id);
65205 var extent = entity.extent(graph);
65206 var distance = extent ? geoSphericalDistance(visibleCenter, extent.center()) : 0;
65207 localResults.push({
65210 geometry: entity.geometry(graph),
65215 if (localResults.length > 100)
65218 localResults = localResults.sort(function byDistance(a, b) {
65219 return a.distance - b.distance;
65221 result = result.concat(localResults);
65222 (_geocodeResults || []).forEach(function(d) {
65223 if (d.osm_type && d.osm_id) {
65224 var id3 = osmEntity.id.fromOSM(d.osm_type, d.osm_id);
65226 tags[d.class] = d.type;
65227 var attrs = { id: id3, type: d.osm_type, tags };
65228 if (d.osm_type === "way") {
65229 attrs.nodes = ["a", "a"];
65231 var tempEntity = osmEntity(attrs);
65232 var tempGraph = coreGraph([tempEntity]);
65233 var matched2 = _mainPresetIndex.match(tempEntity, tempGraph);
65234 var type3 = matched2 && matched2.name() || utilDisplayType(id3);
65237 geometry: tempEntity.geometry(tempGraph),
65239 name: d.display_name,
65240 extent: new geoExtent(
65241 [Number(d.boundingbox[3]), Number(d.boundingbox[0])],
65242 [Number(d.boundingbox[2]), Number(d.boundingbox[1])]
65247 if (q.match(/^[0-9]+$/)) {
65251 type: _t("inspector.node"),
65257 type: _t("inspector.way"),
65262 geometry: "relation",
65263 type: _t("inspector.relation"),
65269 function drawList() {
65270 var value = search.property("value");
65271 var results = features();
65272 list.classed("filtered", value.length);
65273 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"));
65274 resultsIndicator.append("span").attr("class", "entity-name");
65275 list.selectAll(".no-results-item .entity-name").html("").call(_t.append("geocoder.no_results_worldwide"));
65276 if (services.geocoder) {
65277 list.selectAll(".geocode-item").data([0]).enter().append("button").attr("class", "geocode-item secondary-action").on("click", geocoderSearch).append("div").attr("class", "label").append("span").attr("class", "entity-name").call(_t.append("geocoder.search"));
65279 list.selectAll(".no-results-item").style("display", value.length && !results.length ? "block" : "none");
65280 list.selectAll(".geocode-item").style("display", value && _geocodeResults === void 0 ? "block" : "none");
65281 list.selectAll(".feature-list-item").data([-1]).remove();
65282 var items = list.selectAll(".feature-list-item").data(results, function(d) {
65285 var enter = items.enter().insert("button", ".geocode-item").attr("class", "feature-list-item").on("mouseover", mouseover).on("mouseout", mouseout).on("click", click);
65286 var label = enter.append("div").attr("class", "label");
65287 label.each(function(d) {
65288 select_default2(this).call(svgIcon("#iD-icon-" + d.geometry, "pre-text"));
65290 label.append("span").attr("class", "entity-type").text(function(d) {
65293 label.append("span").attr("class", "entity-name").text(function(d) {
65296 enter.style("opacity", 0).transition().style("opacity", 1);
65298 items.exit().remove();
65300 function mouseover(d3_event, d) {
65303 utilHighlightEntities([d.id], true, context);
65305 function mouseout(d3_event, d) {
65308 utilHighlightEntities([d.id], false, context);
65310 function click(d3_event, d) {
65311 d3_event.preventDefault();
65313 context.map().centerZoomEase([d.location[1], d.location[0]], 19);
65314 } else if (d.entity) {
65315 utilHighlightEntities([d.id], false, context);
65316 context.enter(modeSelect(context, [d.entity.id]));
65317 context.map().zoomToEase(d.entity);
65319 context.zoomToEntity(d.id);
65322 function geocoderSearch() {
65323 services.geocoder.search(search.property("value"), function(err, resp) {
65324 _geocodeResults = resp || [];
65329 return featureList;
65332 // modules/ui/improveOSM_comments.js
65333 function uiImproveOsmComments() {
65335 function issueComments(selection2) {
65336 let comments = selection2.selectAll(".comments-container").data([0]);
65337 comments = comments.enter().append("div").attr("class", "comments-container").merge(comments);
65338 services.improveOSM.getComments(_qaItem).then((d) => {
65341 const commentEnter = comments.selectAll(".comment").data(d.comments).enter().append("div").attr("class", "comment");
65342 commentEnter.append("div").attr("class", "comment-avatar").call(svgIcon("#iD-icon-avatar", "comment-avatar-icon"));
65343 const mainEnter = commentEnter.append("div").attr("class", "comment-main");
65344 const metadataEnter = mainEnter.append("div").attr("class", "comment-metadata");
65345 metadataEnter.append("div").attr("class", "comment-author").each(function(d2) {
65346 const osm = services.osm;
65347 let selection3 = select_default2(this);
65348 if (osm && d2.username) {
65349 selection3 = selection3.append("a").attr("class", "comment-author-link").attr("href", osm.userURL(d2.username)).attr("target", "_blank");
65351 selection3.text((d4) => d4.username);
65353 metadataEnter.append("div").attr("class", "comment-date").html((d2) => _t.html("note.status.commented", { when: localeDateString2(d2.timestamp) }));
65354 mainEnter.append("div").attr("class", "comment-text").append("p").text((d2) => d2.text);
65355 }).catch((err) => {
65359 function localeDateString2(s) {
65362 const options2 = { day: "numeric", month: "short", year: "numeric" };
65363 const d = new Date(s * 1e3);
65364 if (isNaN(d.getTime()))
65366 return d.toLocaleDateString(_mainLocalizer.localeCode(), options2);
65368 issueComments.issue = function(val) {
65369 if (!arguments.length)
65372 return issueComments;
65374 return issueComments;
65377 // modules/ui/improveOSM_details.js
65378 function uiImproveOsmDetails(context) {
65380 function issueDetail(d) {
65383 const issueKey = d.issueKey;
65384 d.replacements = d.replacements || {};
65385 d.replacements.default = { html: _t.html("inspector.unknown") };
65386 return _t.html(`QA.improveOSM.error_types.${issueKey}.description`, d.replacements);
65388 function improveOsmDetails(selection2) {
65389 const details = selection2.selectAll(".error-details").data(
65390 _qaItem ? [_qaItem] : [],
65391 (d) => `${d.id}-${d.status || 0}`
65393 details.exit().remove();
65394 const detailsEnter = details.enter().append("div").attr("class", "error-details qa-details-container");
65395 const descriptionEnter = detailsEnter.append("div").attr("class", "qa-details-subsection");
65396 descriptionEnter.append("h4").call(_t.append("QA.keepRight.detail_description"));
65397 descriptionEnter.append("div").attr("class", "qa-details-description-text").html(issueDetail);
65398 let relatedEntities = [];
65399 descriptionEnter.selectAll(".error_entity_link, .error_object_link").attr("href", "#").each(function() {
65400 const link2 = select_default2(this);
65401 const isObjectLink = link2.classed("error_object_link");
65402 const entityID = isObjectLink ? utilEntityRoot(_qaItem.objectType) + _qaItem.objectId : this.textContent;
65403 const entity = context.hasEntity(entityID);
65404 relatedEntities.push(entityID);
65405 link2.on("mouseenter", () => {
65406 utilHighlightEntities([entityID], true, context);
65407 }).on("mouseleave", () => {
65408 utilHighlightEntities([entityID], false, context);
65409 }).on("click", (d3_event) => {
65410 d3_event.preventDefault();
65411 utilHighlightEntities([entityID], false, context);
65412 const osmlayer = context.layers().layer("osm");
65413 if (!osmlayer.enabled()) {
65414 osmlayer.enabled(true);
65416 context.map().centerZoom(_qaItem.loc, 20);
65418 context.enter(modeSelect(context, [entityID]));
65420 context.loadEntity(entityID, (err, result) => {
65423 const entity2 = result.data.find((e) => e.id === entityID);
65425 context.enter(modeSelect(context, [entityID]));
65430 let name = utilDisplayName(entity);
65431 if (!name && !isObjectLink) {
65432 const preset = _mainPresetIndex.match(entity, context.graph());
65433 name = preset && !preset.isFallback() && preset.name();
65436 this.innerText = name;
65440 context.features().forceVisible(relatedEntities);
65441 context.map().pan([0, 0]);
65443 improveOsmDetails.issue = function(val) {
65444 if (!arguments.length)
65447 return improveOsmDetails;
65449 return improveOsmDetails;
65452 // modules/ui/improveOSM_header.js
65453 function uiImproveOsmHeader() {
65455 function issueTitle(d) {
65456 const issueKey = d.issueKey;
65457 d.replacements = d.replacements || {};
65458 d.replacements.default = { html: _t.html("inspector.unknown") };
65459 return _t.html(`QA.improveOSM.error_types.${issueKey}.title`, d.replacements);
65461 function improveOsmHeader(selection2) {
65462 const header = selection2.selectAll(".qa-header").data(
65463 _qaItem ? [_qaItem] : [],
65464 (d) => `${d.id}-${d.status || 0}`
65466 header.exit().remove();
65467 const headerEnter = header.enter().append("div").attr("class", "qa-header");
65468 const svgEnter = headerEnter.append("div").attr("class", "qa-header-icon").classed("new", (d) => d.id < 0).append("svg").attr("width", "20px").attr("height", "30px").attr("viewbox", "0 0 20 30").attr("class", (d) => `preset-icon-28 qaItem ${d.service} itemId-${d.id} itemType-${d.itemType}`);
65469 svgEnter.append("polygon").attr("fill", "currentColor").attr("class", "qaItem-fill").attr("points", "16,3 4,3 1,6 1,17 4,20 7,20 10,27 13,20 16,20 19,17.033 19,6");
65470 svgEnter.append("use").attr("class", "icon-annotation").attr("width", "12px").attr("height", "12px").attr("transform", "translate(4, 5.5)").attr("xlink:href", (d) => d.icon ? "#" + d.icon : "");
65471 headerEnter.append("div").attr("class", "qa-header-label").html(issueTitle);
65473 improveOsmHeader.issue = function(val) {
65474 if (!arguments.length)
65477 return improveOsmHeader;
65479 return improveOsmHeader;
65482 // modules/ui/improveOSM_editor.js
65483 function uiImproveOsmEditor(context) {
65484 const dispatch10 = dispatch_default("change");
65485 const qaDetails = uiImproveOsmDetails(context);
65486 const qaComments = uiImproveOsmComments(context);
65487 const qaHeader = uiImproveOsmHeader(context);
65489 function improveOsmEditor(selection2) {
65490 const headerEnter = selection2.selectAll(".header").data([0]).enter().append("div").attr("class", "header fillL");
65491 headerEnter.append("button").attr("class", "close").attr("title", _t("icons.close")).on("click", () => context.enter(modeBrowse(context))).call(svgIcon("#iD-icon-close"));
65492 headerEnter.append("h2").call(_t.append("QA.improveOSM.title"));
65493 let body = selection2.selectAll(".body").data([0]);
65494 body = body.enter().append("div").attr("class", "body").merge(body);
65495 const editor = body.selectAll(".qa-editor").data([0]);
65496 editor.enter().append("div").attr("class", "modal-section qa-editor").merge(editor).call(qaHeader.issue(_qaItem)).call(qaDetails.issue(_qaItem)).call(qaComments.issue(_qaItem)).call(improveOsmSaveSection);
65498 function improveOsmSaveSection(selection2) {
65499 const isSelected = _qaItem && _qaItem.id === context.selectedErrorID();
65500 const isShown = _qaItem && (isSelected || _qaItem.newComment || _qaItem.comment);
65501 let saveSection = selection2.selectAll(".qa-save").data(
65502 isShown ? [_qaItem] : [],
65503 (d) => `${d.id}-${d.status || 0}`
65505 saveSection.exit().remove();
65506 const saveSectionEnter = saveSection.enter().append("div").attr("class", "qa-save save-section cf");
65507 saveSectionEnter.append("h4").attr("class", ".qa-save-header").call(_t.append("note.newComment"));
65508 saveSectionEnter.append("textarea").attr("class", "new-comment-input").attr("placeholder", _t("QA.keepRight.comment_placeholder")).attr("maxlength", 1e3).property("value", (d) => d.newComment).call(utilNoAuto).on("input", changeInput).on("blur", changeInput);
65509 saveSection = saveSectionEnter.merge(saveSection).call(qaSaveButtons);
65510 function changeInput() {
65511 const input = select_default2(this);
65512 let val = input.property("value").trim();
65516 _qaItem = _qaItem.update({ newComment: val });
65517 const qaService = services.improveOSM;
65519 qaService.replaceItem(_qaItem);
65521 saveSection.call(qaSaveButtons);
65524 function qaSaveButtons(selection2) {
65525 const isSelected = _qaItem && _qaItem.id === context.selectedErrorID();
65526 let buttonSection = selection2.selectAll(".buttons").data(isSelected ? [_qaItem] : [], (d) => d.status + d.id);
65527 buttonSection.exit().remove();
65528 const buttonEnter = buttonSection.enter().append("div").attr("class", "buttons");
65529 buttonEnter.append("button").attr("class", "button comment-button action").call(_t.append("QA.keepRight.save_comment"));
65530 buttonEnter.append("button").attr("class", "button close-button action");
65531 buttonEnter.append("button").attr("class", "button ignore-button action");
65532 buttonSection = buttonSection.merge(buttonEnter);
65533 buttonSection.select(".comment-button").attr("disabled", (d) => d.newComment ? null : true).on("click.comment", function(d3_event, d) {
65535 const qaService = services.improveOSM;
65537 qaService.postUpdate(d, (err, item) => dispatch10.call("change", item));
65540 buttonSection.select(".close-button").html((d) => {
65541 const andComment = d.newComment ? "_comment" : "";
65542 return _t.html(`QA.keepRight.close${andComment}`);
65543 }).on("click.close", function(d3_event, d) {
65545 const qaService = services.improveOSM;
65547 d.newStatus = "SOLVED";
65548 qaService.postUpdate(d, (err, item) => dispatch10.call("change", item));
65551 buttonSection.select(".ignore-button").html((d) => {
65552 const andComment = d.newComment ? "_comment" : "";
65553 return _t.html(`QA.keepRight.ignore${andComment}`);
65554 }).on("click.ignore", function(d3_event, d) {
65556 const qaService = services.improveOSM;
65558 d.newStatus = "INVALID";
65559 qaService.postUpdate(d, (err, item) => dispatch10.call("change", item));
65563 improveOsmEditor.error = function(val) {
65564 if (!arguments.length)
65567 return improveOsmEditor;
65569 return utilRebind(improveOsmEditor, dispatch10, "on");
65572 // modules/ui/preset_list.js
65573 function uiPresetList(context) {
65574 var dispatch10 = dispatch_default("cancel", "choose");
65577 var _currentPresets;
65578 var _autofocus = false;
65579 function presetList(selection2) {
65582 var presets = _mainPresetIndex.matchAllGeometry(entityGeometries());
65583 selection2.html("");
65584 var messagewrap = selection2.append("div").attr("class", "header fillL");
65585 var message = messagewrap.append("h2").call(_t.append("inspector.choose"));
65586 var direction = _mainLocalizer.textDirection() === "rtl" ? "backward" : "forward";
65587 messagewrap.append("button").attr("class", "preset-choose").attr("title", _entityIDs.length === 1 ? _t("inspector.edit") : _t("inspector.edit_features")).on("click", function() {
65588 dispatch10.call("cancel", this);
65589 }).call(svgIcon(`#iD-icon-${direction}`));
65590 function initialKeydown(d3_event) {
65591 if (search.property("value").length === 0 && (d3_event.keyCode === utilKeybinding.keyCodes["\u232B"] || d3_event.keyCode === utilKeybinding.keyCodes["\u2326"])) {
65592 d3_event.preventDefault();
65593 d3_event.stopPropagation();
65594 operationDelete(context, _entityIDs)();
65595 } else if (search.property("value").length === 0 && (d3_event.ctrlKey || d3_event.metaKey) && d3_event.keyCode === utilKeybinding.keyCodes.z) {
65596 d3_event.preventDefault();
65597 d3_event.stopPropagation();
65599 } else if (!d3_event.ctrlKey && !d3_event.metaKey) {
65600 select_default2(this).on("keydown", keydown);
65601 keydown.call(this, d3_event);
65604 function keydown(d3_event) {
65605 if (d3_event.keyCode === utilKeybinding.keyCodes["\u2193"] && // if insertion point is at the end of the string
65606 search.node().selectionStart === search.property("value").length) {
65607 d3_event.preventDefault();
65608 d3_event.stopPropagation();
65609 var buttons = list.selectAll(".preset-list-button");
65610 if (!buttons.empty())
65611 buttons.nodes()[0].focus();
65614 function keypress(d3_event) {
65615 var value = search.property("value");
65616 if (d3_event.keyCode === 13 && // ↩ Return
65618 list.selectAll(".preset-list-item:first-child").each(function(d) {
65619 d.choose.call(this);
65623 function inputevent() {
65624 var value = search.property("value");
65625 list.classed("filtered", value.length);
65626 var results, messageText;
65627 if (value.length) {
65628 results = presets.search(value, entityGeometries()[0], _currLoc);
65629 messageText = _t.html("inspector.results", {
65630 n: results.collection.length,
65634 var entityPresets2 = _entityIDs.map((entityID) => _mainPresetIndex.match(context.graph().entity(entityID), context.graph()));
65635 results = _mainPresetIndex.defaults(entityGeometries()[0], 36, !context.inIntro(), _currLoc, entityPresets2);
65636 messageText = _t.html("inspector.choose");
65638 list.call(drawList, results);
65639 message.html(messageText);
65641 var searchWrap = selection2.append("div").attr("class", "search-header");
65642 searchWrap.call(svgIcon("#iD-icon-search", "pre-text"));
65643 var search = searchWrap.append("input").attr("class", "preset-search-input").attr("placeholder", _t("inspector.search")).attr("type", "search").call(utilNoAuto).on("keydown", initialKeydown).on("keypress", keypress).on("input", debounce_default(inputevent));
65645 search.node().focus();
65646 setTimeout(function() {
65647 search.node().focus();
65650 var listWrap = selection2.append("div").attr("class", "inspector-body");
65651 var entityPresets = _entityIDs.map((entityID) => _mainPresetIndex.match(context.graph().entity(entityID), context.graph()));
65652 var list = listWrap.append("div").attr("class", "preset-list").call(drawList, _mainPresetIndex.defaults(entityGeometries()[0], 36, !context.inIntro(), _currLoc, entityPresets));
65653 context.features().on("change.preset-list", updateForFeatureHiddenState);
65655 function drawList(list, presets) {
65656 presets = presets.matchAllGeometry(entityGeometries());
65657 var collection = presets.collection.reduce(function(collection2, preset) {
65659 return collection2;
65660 if (preset.members) {
65661 if (preset.members.collection.filter(function(preset2) {
65662 return preset2.addable();
65664 collection2.push(CategoryItem(preset));
65666 } else if (preset.addable()) {
65667 collection2.push(PresetItem(preset));
65669 return collection2;
65671 var items = list.selectAll(".preset-list-item").data(collection, function(d) {
65672 return d.preset.id;
65675 items.exit().remove();
65676 items.enter().append("div").attr("class", function(item) {
65677 return "preset-list-item preset-" + item.preset.id.replace("/", "-");
65678 }).classed("current", function(item) {
65679 return _currentPresets.indexOf(item.preset) !== -1;
65680 }).each(function(item) {
65681 select_default2(this).call(item);
65682 }).style("opacity", 0).transition().style("opacity", 1);
65683 updateForFeatureHiddenState();
65685 function itemKeydown(d3_event) {
65686 var item = select_default2(this.closest(".preset-list-item"));
65687 var parentItem = select_default2(item.node().parentNode.closest(".preset-list-item"));
65688 if (d3_event.keyCode === utilKeybinding.keyCodes["\u2193"]) {
65689 d3_event.preventDefault();
65690 d3_event.stopPropagation();
65691 var nextItem = select_default2(item.node().nextElementSibling);
65692 if (nextItem.empty()) {
65693 if (!parentItem.empty()) {
65694 nextItem = select_default2(parentItem.node().nextElementSibling);
65696 } else if (select_default2(this).classed("expanded")) {
65697 nextItem = item.select(".subgrid .preset-list-item:first-child");
65699 if (!nextItem.empty()) {
65700 nextItem.select(".preset-list-button").node().focus();
65702 } else if (d3_event.keyCode === utilKeybinding.keyCodes["\u2191"]) {
65703 d3_event.preventDefault();
65704 d3_event.stopPropagation();
65705 var previousItem = select_default2(item.node().previousElementSibling);
65706 if (previousItem.empty()) {
65707 if (!parentItem.empty()) {
65708 previousItem = parentItem;
65710 } else if (previousItem.select(".preset-list-button").classed("expanded")) {
65711 previousItem = previousItem.select(".subgrid .preset-list-item:last-child");
65713 if (!previousItem.empty()) {
65714 previousItem.select(".preset-list-button").node().focus();
65716 var search = select_default2(this.closest(".preset-list-pane")).select(".preset-search-input");
65717 search.node().focus();
65719 } else if (d3_event.keyCode === utilKeybinding.keyCodes[_mainLocalizer.textDirection() === "rtl" ? "\u2192" : "\u2190"]) {
65720 d3_event.preventDefault();
65721 d3_event.stopPropagation();
65722 if (!parentItem.empty()) {
65723 parentItem.select(".preset-list-button").node().focus();
65725 } else if (d3_event.keyCode === utilKeybinding.keyCodes[_mainLocalizer.textDirection() === "rtl" ? "\u2190" : "\u2192"]) {
65726 d3_event.preventDefault();
65727 d3_event.stopPropagation();
65728 item.datum().choose.call(select_default2(this).node());
65731 function CategoryItem(preset) {
65732 var box, sublist, shown = false;
65733 function item(selection2) {
65734 var wrap2 = selection2.append("div").attr("class", "preset-list-button-wrap category");
65736 var isExpanded = select_default2(this).classed("expanded");
65737 var iconName = isExpanded ? _mainLocalizer.textDirection() === "rtl" ? "#iD-icon-backward" : "#iD-icon-forward" : "#iD-icon-down";
65738 select_default2(this).classed("expanded", !isExpanded).attr("title", !isExpanded ? _t("icons.collapse") : _t("icons.expand"));
65739 select_default2(this).selectAll("div.label-inner svg.icon use").attr("href", iconName);
65742 var geometries = entityGeometries();
65743 var button = wrap2.append("button").attr("class", "preset-list-button").attr("title", _t("icons.expand")).classed("expanded", false).call(uiPresetIcon().geometry(geometries.length === 1 && geometries[0]).preset(preset)).on("click", click).on("keydown", function(d3_event) {
65744 if (d3_event.keyCode === utilKeybinding.keyCodes[_mainLocalizer.textDirection() === "rtl" ? "\u2190" : "\u2192"]) {
65745 d3_event.preventDefault();
65746 d3_event.stopPropagation();
65747 if (!select_default2(this).classed("expanded")) {
65748 click.call(this, d3_event);
65750 } else if (d3_event.keyCode === utilKeybinding.keyCodes[_mainLocalizer.textDirection() === "rtl" ? "\u2192" : "\u2190"]) {
65751 d3_event.preventDefault();
65752 d3_event.stopPropagation();
65753 if (select_default2(this).classed("expanded")) {
65754 click.call(this, d3_event);
65757 itemKeydown.call(this, d3_event);
65760 var label = button.append("div").attr("class", "label").append("div").attr("class", "label-inner");
65761 label.append("div").attr("class", "namepart").call(svgIcon(_mainLocalizer.textDirection() === "rtl" ? "#iD-icon-backward" : "#iD-icon-forward", "inline")).append("span").call(preset.nameLabel()).append("span").text("\u2026");
65762 box = selection2.append("div").attr("class", "subgrid").style("max-height", "0px").style("opacity", 0);
65763 box.append("div").attr("class", "arrow");
65764 sublist = box.append("div").attr("class", "preset-list fillL3");
65766 item.choose = function() {
65767 if (!box || !sublist)
65771 box.transition().duration(200).style("opacity", "0").style("max-height", "0px").style("padding-bottom", "0px");
65774 var members = preset.members.matchAllGeometry(entityGeometries());
65775 sublist.call(drawList, members);
65776 box.transition().duration(200).style("opacity", "1").style("max-height", 200 + members.collection.length * 190 + "px").style("padding-bottom", "10px");
65779 item.preset = preset;
65782 function PresetItem(preset) {
65783 function item(selection2) {
65784 var wrap2 = selection2.append("div").attr("class", "preset-list-button-wrap");
65785 var geometries = entityGeometries();
65786 var button = wrap2.append("button").attr("class", "preset-list-button").call(uiPresetIcon().geometry(geometries.length === 1 && geometries[0]).preset(preset)).on("click", item.choose).on("keydown", itemKeydown);
65787 var label = button.append("div").attr("class", "label").append("div").attr("class", "label-inner");
65789 preset.nameLabel(),
65790 preset.subtitleLabel()
65792 label.selectAll(".namepart").data(nameparts, (d) => d.stringId).enter().append("div").attr("class", "namepart").text("").each(function(d) {
65793 d(select_default2(this));
65795 wrap2.call(item.reference.button);
65796 selection2.call(item.reference.body);
65798 item.choose = function() {
65799 if (select_default2(this).classed("disabled"))
65801 if (!context.inIntro()) {
65802 _mainPresetIndex.setMostRecent(preset, entityGeometries()[0]);
65806 for (var i2 in _entityIDs) {
65807 var entityID = _entityIDs[i2];
65808 var oldPreset = _mainPresetIndex.match(graph.entity(entityID), graph);
65809 graph = actionChangePreset(entityID, oldPreset, preset)(graph);
65813 _t("operations.change_tags.annotation")
65815 context.validator().validate();
65816 dispatch10.call("choose", this, preset);
65818 item.help = function(d3_event) {
65819 d3_event.stopPropagation();
65820 item.reference.toggle();
65822 item.preset = preset;
65823 item.reference = uiTagReference(preset.reference(), context);
65826 function updateForFeatureHiddenState() {
65827 if (!_entityIDs.every(context.hasEntity))
65829 var geometries = entityGeometries();
65830 var button = context.container().selectAll(".preset-list .preset-list-button");
65831 button.call(uiTooltip().destroyAny);
65832 button.each(function(item, index) {
65833 var hiddenPresetFeaturesId;
65834 for (var i2 in geometries) {
65835 hiddenPresetFeaturesId = context.features().isHiddenPreset(item.preset, geometries[i2]);
65836 if (hiddenPresetFeaturesId)
65839 var isHiddenPreset = !context.inIntro() && !!hiddenPresetFeaturesId && (_currentPresets.length !== 1 || item.preset !== _currentPresets[0]);
65840 select_default2(this).classed("disabled", isHiddenPreset);
65841 if (isHiddenPreset) {
65842 var isAutoHidden = context.features().autoHidden(hiddenPresetFeaturesId);
65843 select_default2(this).call(
65844 uiTooltip().title(() => _t.append("inspector.hidden_preset." + (isAutoHidden ? "zoom" : "manual"), {
65845 features: _t("feature." + hiddenPresetFeaturesId + ".description")
65846 })).placement(index < 2 ? "bottom" : "top")
65851 presetList.autofocus = function(val) {
65852 if (!arguments.length)
65857 presetList.entityIDs = function(val) {
65858 if (!arguments.length)
65862 if (_entityIDs && _entityIDs.length) {
65863 const extent = _entityIDs.reduce(function(extent2, entityID) {
65864 var entity = context.graph().entity(entityID);
65865 return extent2.extend(entity.extent(context.graph()));
65867 _currLoc = extent.center();
65868 var presets = _entityIDs.map(function(entityID) {
65869 return _mainPresetIndex.match(context.entity(entityID), context.graph());
65871 presetList.presets(presets);
65875 presetList.presets = function(val) {
65876 if (!arguments.length)
65877 return _currentPresets;
65878 _currentPresets = val;
65881 function entityGeometries() {
65883 for (var i2 in _entityIDs) {
65884 var entityID = _entityIDs[i2];
65885 var entity = context.entity(entityID);
65886 var geometry = entity.geometry(context.graph());
65887 if (geometry === "vertex" && entity.isOnAddressLine(context.graph())) {
65888 geometry = "point";
65890 if (!counts[geometry])
65891 counts[geometry] = 0;
65892 counts[geometry] += 1;
65894 return Object.keys(counts).sort(function(geom1, geom2) {
65895 return counts[geom2] - counts[geom1];
65898 return utilRebind(presetList, dispatch10, "on");
65901 // modules/ui/view_on_osm.js
65902 function uiViewOnOSM(context) {
65904 function viewOnOSM(selection2) {
65906 if (_what instanceof osmEntity) {
65907 url = context.connection().entityURL(_what);
65908 } else if (_what instanceof osmNote) {
65909 url = context.connection().noteURL(_what);
65911 var data = !_what || _what.isNew() ? [] : [_what];
65912 var link2 = selection2.selectAll(".view-on-osm").data(data, function(d) {
65915 link2.exit().remove();
65916 var linkEnter = link2.enter().append("a").attr("class", "view-on-osm").attr("target", "_blank").attr("href", url).call(svgIcon("#iD-icon-out-link", "inline"));
65917 linkEnter.append("span").call(_t.append("inspector.view_on_osm"));
65919 viewOnOSM.what = function(_) {
65920 if (!arguments.length)
65928 // modules/ui/inspector.js
65929 function uiInspector(context) {
65930 var presetList = uiPresetList(context);
65931 var entityEditor = uiEntityEditor(context);
65932 var wrap2 = select_default2(null), presetPane = select_default2(null), editorPane = select_default2(null);
65933 var _state = "select";
65935 var _newFeature = false;
65936 function inspector(selection2) {
65937 presetList.entityIDs(_entityIDs).autofocus(_newFeature).on("choose", inspector.setPreset).on("cancel", function() {
65938 inspector.setPreset();
65940 entityEditor.state(_state).entityIDs(_entityIDs).on("choose", inspector.showList);
65941 wrap2 = selection2.selectAll(".panewrap").data([0]);
65942 var enter = wrap2.enter().append("div").attr("class", "panewrap");
65943 enter.append("div").attr("class", "preset-list-pane pane");
65944 enter.append("div").attr("class", "entity-editor-pane pane");
65945 wrap2 = wrap2.merge(enter);
65946 presetPane = wrap2.selectAll(".preset-list-pane");
65947 editorPane = wrap2.selectAll(".entity-editor-pane");
65948 function shouldDefaultToPresetList() {
65949 if (_state !== "select")
65951 if (_entityIDs.length !== 1)
65953 var entityID = _entityIDs[0];
65954 var entity = context.hasEntity(entityID);
65957 if (entity.hasNonGeometryTags())
65961 if (entity.geometry(context.graph()) !== "vertex")
65963 if (context.graph().parentRelations(entity).length)
65965 if (context.validator().getEntityIssues(entityID).length)
65967 if (entity.isHighwayIntersection(context.graph()))
65971 if (shouldDefaultToPresetList()) {
65972 wrap2.style("right", "-100%");
65973 editorPane.classed("hide", true);
65974 presetPane.classed("hide", false).call(presetList);
65976 wrap2.style("right", "0%");
65977 presetPane.classed("hide", true);
65978 editorPane.classed("hide", false).call(entityEditor);
65980 var footer = selection2.selectAll(".footer").data([0]);
65981 footer = footer.enter().append("div").attr("class", "footer").merge(footer);
65983 uiViewOnOSM(context).what(context.hasEntity(_entityIDs.length === 1 && _entityIDs[0]))
65986 inspector.showList = function(presets) {
65987 presetPane.classed("hide", false);
65988 wrap2.transition().styleTween("right", function() {
65989 return value_default("0%", "-100%");
65990 }).on("end", function() {
65991 editorPane.classed("hide", true);
65994 presetList.presets(presets);
65996 presetPane.call(presetList.autofocus(true));
65998 inspector.setPreset = function(preset) {
65999 if (preset && preset.id === "type/multipolygon") {
66000 presetPane.call(presetList.autofocus(true));
66002 editorPane.classed("hide", false);
66003 wrap2.transition().styleTween("right", function() {
66004 return value_default("-100%", "0%");
66005 }).on("end", function() {
66006 presetPane.classed("hide", true);
66009 entityEditor.presets([preset]);
66011 editorPane.call(entityEditor);
66014 inspector.state = function(val) {
66015 if (!arguments.length)
66018 entityEditor.state(_state);
66019 context.container().selectAll(".field-help-body").remove();
66022 inspector.entityIDs = function(val) {
66023 if (!arguments.length)
66028 inspector.newFeature = function(val) {
66029 if (!arguments.length)
66030 return _newFeature;
66037 // modules/ui/keepRight_details.js
66038 function uiKeepRightDetails(context) {
66040 function issueDetail(d) {
66041 const { itemType, parentIssueType } = d;
66042 const unknown = { html: _t.html("inspector.unknown") };
66043 let replacements = d.replacements || {};
66044 replacements.default = unknown;
66045 if (_mainLocalizer.hasTextForStringId(`QA.keepRight.errorTypes.${itemType}.title`)) {
66046 return _t.html(`QA.keepRight.errorTypes.${itemType}.description`, replacements);
66048 return _t.html(`QA.keepRight.errorTypes.${parentIssueType}.description`, replacements);
66051 function keepRightDetails(selection2) {
66052 const details = selection2.selectAll(".error-details").data(
66053 _qaItem ? [_qaItem] : [],
66054 (d) => `${d.id}-${d.status || 0}`
66056 details.exit().remove();
66057 const detailsEnter = details.enter().append("div").attr("class", "error-details qa-details-container");
66058 const descriptionEnter = detailsEnter.append("div").attr("class", "qa-details-subsection");
66059 descriptionEnter.append("h4").call(_t.append("QA.keepRight.detail_description"));
66060 descriptionEnter.append("div").attr("class", "qa-details-description-text").html(issueDetail);
66061 let relatedEntities = [];
66062 descriptionEnter.selectAll(".error_entity_link, .error_object_link").attr("href", "#").each(function() {
66063 const link2 = select_default2(this);
66064 const isObjectLink = link2.classed("error_object_link");
66065 const entityID = isObjectLink ? utilEntityRoot(_qaItem.objectType) + _qaItem.objectId : this.textContent;
66066 const entity = context.hasEntity(entityID);
66067 relatedEntities.push(entityID);
66068 link2.on("mouseenter", () => {
66069 utilHighlightEntities([entityID], true, context);
66070 }).on("mouseleave", () => {
66071 utilHighlightEntities([entityID], false, context);
66072 }).on("click", (d3_event) => {
66073 d3_event.preventDefault();
66074 utilHighlightEntities([entityID], false, context);
66075 const osmlayer = context.layers().layer("osm");
66076 if (!osmlayer.enabled()) {
66077 osmlayer.enabled(true);
66079 context.map().centerZoomEase(_qaItem.loc, 20);
66081 context.enter(modeSelect(context, [entityID]));
66083 context.loadEntity(entityID, (err, result) => {
66086 const entity2 = result.data.find((e) => e.id === entityID);
66088 context.enter(modeSelect(context, [entityID]));
66093 let name = utilDisplayName(entity);
66094 if (!name && !isObjectLink) {
66095 const preset = _mainPresetIndex.match(entity, context.graph());
66096 name = preset && !preset.isFallback() && preset.name();
66099 this.innerText = name;
66103 context.features().forceVisible(relatedEntities);
66104 context.map().pan([0, 0]);
66106 keepRightDetails.issue = function(val) {
66107 if (!arguments.length)
66110 return keepRightDetails;
66112 return keepRightDetails;
66115 // modules/ui/keepRight_header.js
66116 function uiKeepRightHeader() {
66118 function issueTitle(d) {
66119 const { itemType, parentIssueType } = d;
66120 const unknown = _t.html("inspector.unknown");
66121 let replacements = d.replacements || {};
66122 replacements.default = { html: unknown };
66123 if (_mainLocalizer.hasTextForStringId(`QA.keepRight.errorTypes.${itemType}.title`)) {
66124 return _t.html(`QA.keepRight.errorTypes.${itemType}.title`, replacements);
66126 return _t.html(`QA.keepRight.errorTypes.${parentIssueType}.title`, replacements);
66129 function keepRightHeader(selection2) {
66130 const header = selection2.selectAll(".qa-header").data(
66131 _qaItem ? [_qaItem] : [],
66132 (d) => `${d.id}-${d.status || 0}`
66134 header.exit().remove();
66135 const headerEnter = header.enter().append("div").attr("class", "qa-header");
66136 const iconEnter = headerEnter.append("div").attr("class", "qa-header-icon").classed("new", (d) => d.id < 0);
66137 iconEnter.append("div").attr("class", (d) => `preset-icon-28 qaItem ${d.service} itemId-${d.id} itemType-${d.parentIssueType}`).call(svgIcon("#iD-icon-bolt", "qaItem-fill"));
66138 headerEnter.append("div").attr("class", "qa-header-label").html(issueTitle);
66140 keepRightHeader.issue = function(val) {
66141 if (!arguments.length)
66144 return keepRightHeader;
66146 return keepRightHeader;
66149 // modules/ui/view_on_keepRight.js
66150 function uiViewOnKeepRight() {
66152 function viewOnKeepRight(selection2) {
66154 if (services.keepRight && _qaItem instanceof QAItem) {
66155 url = services.keepRight.issueURL(_qaItem);
66157 const link2 = selection2.selectAll(".view-on-keepRight").data(url ? [url] : []);
66158 link2.exit().remove();
66159 const linkEnter = link2.enter().append("a").attr("class", "view-on-keepRight").attr("target", "_blank").attr("rel", "noopener").attr("href", (d) => d).call(svgIcon("#iD-icon-out-link", "inline"));
66160 linkEnter.append("span").call(_t.append("inspector.view_on_keepRight"));
66162 viewOnKeepRight.what = function(val) {
66163 if (!arguments.length)
66166 return viewOnKeepRight;
66168 return viewOnKeepRight;
66171 // modules/ui/keepRight_editor.js
66172 function uiKeepRightEditor(context) {
66173 const dispatch10 = dispatch_default("change");
66174 const qaDetails = uiKeepRightDetails(context);
66175 const qaHeader = uiKeepRightHeader(context);
66177 function keepRightEditor(selection2) {
66178 const headerEnter = selection2.selectAll(".header").data([0]).enter().append("div").attr("class", "header fillL");
66179 headerEnter.append("button").attr("class", "close").attr("title", _t("icons.close")).on("click", () => context.enter(modeBrowse(context))).call(svgIcon("#iD-icon-close"));
66180 headerEnter.append("h2").call(_t.append("QA.keepRight.title"));
66181 let body = selection2.selectAll(".body").data([0]);
66182 body = body.enter().append("div").attr("class", "body").merge(body);
66183 const editor = body.selectAll(".qa-editor").data([0]);
66184 editor.enter().append("div").attr("class", "modal-section qa-editor").merge(editor).call(qaHeader.issue(_qaItem)).call(qaDetails.issue(_qaItem)).call(keepRightSaveSection);
66185 const footer = selection2.selectAll(".footer").data([0]);
66186 footer.enter().append("div").attr("class", "footer").merge(footer).call(uiViewOnKeepRight(context).what(_qaItem));
66188 function keepRightSaveSection(selection2) {
66189 const isSelected = _qaItem && _qaItem.id === context.selectedErrorID();
66190 const isShown = _qaItem && (isSelected || _qaItem.newComment || _qaItem.comment);
66191 let saveSection = selection2.selectAll(".qa-save").data(
66192 isShown ? [_qaItem] : [],
66193 (d) => `${d.id}-${d.status || 0}`
66195 saveSection.exit().remove();
66196 const saveSectionEnter = saveSection.enter().append("div").attr("class", "qa-save save-section cf");
66197 saveSectionEnter.append("h4").attr("class", ".qa-save-header").call(_t.append("QA.keepRight.comment"));
66198 saveSectionEnter.append("textarea").attr("class", "new-comment-input").attr("placeholder", _t("QA.keepRight.comment_placeholder")).attr("maxlength", 1e3).property("value", (d) => d.newComment || d.comment).call(utilNoAuto).on("input", changeInput).on("blur", changeInput);
66199 saveSection = saveSectionEnter.merge(saveSection).call(qaSaveButtons);
66200 function changeInput() {
66201 const input = select_default2(this);
66202 let val = input.property("value").trim();
66203 if (val === _qaItem.comment) {
66206 _qaItem = _qaItem.update({ newComment: val });
66207 const qaService = services.keepRight;
66209 qaService.replaceItem(_qaItem);
66211 saveSection.call(qaSaveButtons);
66214 function qaSaveButtons(selection2) {
66215 const isSelected = _qaItem && _qaItem.id === context.selectedErrorID();
66216 let buttonSection = selection2.selectAll(".buttons").data(isSelected ? [_qaItem] : [], (d) => d.status + d.id);
66217 buttonSection.exit().remove();
66218 const buttonEnter = buttonSection.enter().append("div").attr("class", "buttons");
66219 buttonEnter.append("button").attr("class", "button comment-button action").call(_t.append("QA.keepRight.save_comment"));
66220 buttonEnter.append("button").attr("class", "button close-button action");
66221 buttonEnter.append("button").attr("class", "button ignore-button action");
66222 buttonSection = buttonSection.merge(buttonEnter);
66223 buttonSection.select(".comment-button").attr("disabled", (d) => d.newComment ? null : true).on("click.comment", function(d3_event, d) {
66225 const qaService = services.keepRight;
66227 qaService.postUpdate(d, (err, item) => dispatch10.call("change", item));
66230 buttonSection.select(".close-button").html((d) => {
66231 const andComment = d.newComment ? "_comment" : "";
66232 return _t.html(`QA.keepRight.close${andComment}`);
66233 }).on("click.close", function(d3_event, d) {
66235 const qaService = services.keepRight;
66237 d.newStatus = "ignore_t";
66238 qaService.postUpdate(d, (err, item) => dispatch10.call("change", item));
66241 buttonSection.select(".ignore-button").html((d) => {
66242 const andComment = d.newComment ? "_comment" : "";
66243 return _t.html(`QA.keepRight.ignore${andComment}`);
66244 }).on("click.ignore", function(d3_event, d) {
66246 const qaService = services.keepRight;
66248 d.newStatus = "ignore";
66249 qaService.postUpdate(d, (err, item) => dispatch10.call("change", item));
66253 keepRightEditor.error = function(val) {
66254 if (!arguments.length)
66257 return keepRightEditor;
66259 return utilRebind(keepRightEditor, dispatch10, "on");
66262 // modules/ui/lasso.js
66263 function uiLasso(context) {
66264 var group, polygon2;
66265 lasso.coordinates = [];
66266 function lasso(selection2) {
66267 context.container().classed("lasso", true);
66268 group = selection2.append("g").attr("class", "lasso hide");
66269 polygon2 = group.append("path").attr("class", "lasso-path");
66270 group.call(uiToggle(true));
66274 polygon2.data([lasso.coordinates]).attr("d", function(d) {
66275 return "M" + d.join(" L") + " Z";
66279 lasso.extent = function() {
66280 return lasso.coordinates.reduce(function(extent, point2) {
66281 return extent.extend(geoExtent(point2));
66284 lasso.p = function(_) {
66285 if (!arguments.length)
66287 lasso.coordinates.push(_);
66291 lasso.close = function() {
66293 group.call(uiToggle(false, function() {
66294 select_default2(this).remove();
66297 context.container().classed("lasso", false);
66302 // modules/ui/note_comments.js
66303 function uiNoteComments() {
66305 function noteComments(selection2) {
66308 var comments = selection2.selectAll(".comments-container").data([0]);
66309 comments = comments.enter().append("div").attr("class", "comments-container").merge(comments);
66310 var commentEnter = comments.selectAll(".comment").data(_note.comments).enter().append("div").attr("class", "comment");
66311 commentEnter.append("div").attr("class", function(d) {
66312 return "comment-avatar user-" + d.uid;
66313 }).call(svgIcon("#iD-icon-avatar", "comment-avatar-icon"));
66314 var mainEnter = commentEnter.append("div").attr("class", "comment-main");
66315 var metadataEnter = mainEnter.append("div").attr("class", "comment-metadata");
66316 metadataEnter.append("div").attr("class", "comment-author").each(function(d) {
66317 var selection3 = select_default2(this);
66318 var osm = services.osm;
66319 if (osm && d.user) {
66320 selection3 = selection3.append("a").attr("class", "comment-author-link").attr("href", osm.userURL(d.user)).attr("target", "_blank");
66323 selection3.text(d.user);
66325 selection3.call(_t.append("note.anonymous"));
66328 metadataEnter.append("div").attr("class", "comment-date").html(function(d) {
66329 return _t.html("note.status." + d.action, { when: localeDateString2(d.date) });
66331 mainEnter.append("div").attr("class", "comment-text").html(function(d) {
66333 }).selectAll("a").attr("rel", "noopener nofollow").attr("target", "_blank");
66334 comments.call(replaceAvatars);
66336 function replaceAvatars(selection2) {
66337 var showThirdPartyIcons = corePreferences("preferences.privacy.thirdpartyicons") || "true";
66338 var osm = services.osm;
66339 if (showThirdPartyIcons !== "true" || !osm)
66342 _note.comments.forEach(function(d) {
66344 uids[d.uid] = true;
66346 Object.keys(uids).forEach(function(uid) {
66347 osm.loadUser(uid, function(err, user) {
66348 if (!user || !user.image_url)
66350 selection2.selectAll(".comment-avatar.user-" + uid).html("").append("img").attr("class", "icon comment-avatar-icon").attr("src", user.image_url).attr("alt", user.display_name);
66354 function localeDateString2(s) {
66357 var options2 = { day: "numeric", month: "short", year: "numeric" };
66358 s = s.replace(/-/g, "/");
66359 var d = new Date(s);
66360 if (isNaN(d.getTime()))
66362 return d.toLocaleDateString(_mainLocalizer.localeCode(), options2);
66364 noteComments.note = function(val) {
66365 if (!arguments.length)
66368 return noteComments;
66370 return noteComments;
66373 // modules/ui/note_header.js
66374 function uiNoteHeader() {
66376 function noteHeader(selection2) {
66377 var header = selection2.selectAll(".note-header").data(
66378 _note ? [_note] : [],
66380 return d.status + d.id;
66383 header.exit().remove();
66384 var headerEnter = header.enter().append("div").attr("class", "note-header");
66385 var iconEnter = headerEnter.append("div").attr("class", function(d) {
66386 return "note-header-icon " + d.status;
66387 }).classed("new", function(d) {
66390 iconEnter.append("div").attr("class", "preset-icon-28").call(svgIcon("#iD-icon-note", "note-fill"));
66391 iconEnter.each(function(d) {
66394 statusIcon = "#iD-icon-plus";
66395 } else if (d.status === "open") {
66396 statusIcon = "#iD-icon-close";
66398 statusIcon = "#iD-icon-apply";
66400 iconEnter.append("div").attr("class", "note-icon-annotation").attr("title", _t("icons.close")).call(svgIcon(statusIcon, "icon-annotation"));
66402 headerEnter.append("div").attr("class", "note-header-label").html(function(d) {
66403 if (_note.isNew()) {
66404 return _t.html("note.new");
66406 return _t.html("note.note") + " " + d.id + " " + (d.status === "closed" ? _t.html("note.closed") : "");
66409 noteHeader.note = function(val) {
66410 if (!arguments.length)
66418 // modules/ui/note_report.js
66419 function uiNoteReport() {
66421 function noteReport(selection2) {
66423 if (services.osm && _note instanceof osmNote && !_note.isNew()) {
66424 url = services.osm.noteReportURL(_note);
66426 var link2 = selection2.selectAll(".note-report").data(url ? [url] : []);
66427 link2.exit().remove();
66428 var linkEnter = link2.enter().append("a").attr("class", "note-report").attr("target", "_blank").attr("href", function(d) {
66430 }).call(svgIcon("#iD-icon-out-link", "inline"));
66431 linkEnter.append("span").call(_t.append("note.report"));
66433 noteReport.note = function(val) {
66434 if (!arguments.length)
66442 // modules/ui/note_editor.js
66443 function uiNoteEditor(context) {
66444 var dispatch10 = dispatch_default("change");
66445 var noteComments = uiNoteComments(context);
66446 var noteHeader = uiNoteHeader();
66449 function noteEditor(selection2) {
66450 var header = selection2.selectAll(".header").data([0]);
66451 var headerEnter = header.enter().append("div").attr("class", "header fillL");
66452 headerEnter.append("button").attr("class", "close").attr("title", _t("icons.close")).on("click", function() {
66453 context.enter(modeBrowse(context));
66454 }).call(svgIcon("#iD-icon-close"));
66455 headerEnter.append("h2").call(_t.append("note.title"));
66456 var body = selection2.selectAll(".body").data([0]);
66457 body = body.enter().append("div").attr("class", "body").merge(body);
66458 var editor = body.selectAll(".note-editor").data([0]);
66459 editor.enter().append("div").attr("class", "modal-section note-editor").merge(editor).call(noteHeader.note(_note)).call(noteComments.note(_note)).call(noteSaveSection);
66460 var footer = selection2.selectAll(".footer").data([0]);
66461 footer.enter().append("div").attr("class", "footer").merge(footer).call(uiViewOnOSM(context).what(_note)).call(uiNoteReport(context).note(_note));
66462 var osm = services.osm;
66464 osm.on("change.note-save", function() {
66465 selection2.call(noteEditor);
66469 function noteSaveSection(selection2) {
66470 var isSelected = _note && _note.id === context.selectedNoteID();
66471 var noteSave = selection2.selectAll(".note-save").data(isSelected ? [_note] : [], function(d) {
66472 return d.status + d.id;
66474 noteSave.exit().remove();
66475 var noteSaveEnter = noteSave.enter().append("div").attr("class", "note-save save-section cf");
66476 noteSaveEnter.append("h4").attr("class", ".note-save-header").html(function() {
66477 return _note.isNew() ? _t.html("note.newDescription") : _t.html("note.newComment");
66479 var commentTextarea = noteSaveEnter.append("textarea").attr("class", "new-comment-input").attr("placeholder", _t("note.inputPlaceholder")).attr("maxlength", 1e3).property("value", function(d) {
66480 return d.newComment;
66481 }).call(utilNoAuto).on("keydown.note-input", keydown).on("input.note-input", changeInput).on("blur.note-input", changeInput);
66482 if (!commentTextarea.empty() && _newNote) {
66483 commentTextarea.node().focus();
66485 noteSave = noteSaveEnter.merge(noteSave).call(userDetails).call(noteSaveButtons);
66486 function keydown(d3_event) {
66487 if (!(d3_event.keyCode === 13 && // ↩ Return
66490 var osm = services.osm;
66493 var hasAuth = osm.authenticated();
66496 if (!_note.newComment)
66498 d3_event.preventDefault();
66499 select_default2(this).on("keydown.note-input", null);
66500 window.setTimeout(function() {
66501 if (_note.isNew()) {
66502 noteSave.selectAll(".save-button").node().focus();
66505 noteSave.selectAll(".comment-button").node().focus();
66506 clickComment(_note);
66510 function changeInput() {
66511 var input = select_default2(this);
66512 var val = input.property("value").trim() || void 0;
66513 _note = _note.update({ newComment: val });
66514 var osm = services.osm;
66516 osm.replaceNote(_note);
66518 noteSave.call(noteSaveButtons);
66521 function userDetails(selection2) {
66522 var detailSection = selection2.selectAll(".detail-section").data([0]);
66523 detailSection = detailSection.enter().append("div").attr("class", "detail-section").merge(detailSection);
66524 var osm = services.osm;
66527 var hasAuth = osm.authenticated();
66528 var authWarning = detailSection.selectAll(".auth-warning").data(hasAuth ? [] : [0]);
66529 authWarning.exit().transition().duration(200).style("opacity", 0).remove();
66530 var authEnter = authWarning.enter().insert("div", ".tag-reference-body").attr("class", "field-warning auth-warning").style("opacity", 0);
66531 authEnter.call(svgIcon("#iD-icon-alert", "inline"));
66532 authEnter.append("span").call(_t.append("note.login"));
66533 authEnter.append("a").attr("target", "_blank").call(svgIcon("#iD-icon-out-link", "inline")).append("span").call(_t.append("login")).on("click.note-login", function(d3_event) {
66534 d3_event.preventDefault();
66535 osm.authenticate();
66537 authEnter.transition().duration(200).style("opacity", 1);
66538 var prose = detailSection.selectAll(".note-save-prose").data(hasAuth ? [0] : []);
66539 prose.exit().remove();
66540 prose = prose.enter().append("p").attr("class", "note-save-prose").call(_t.append("note.upload_explanation")).merge(prose);
66541 osm.userDetails(function(err, user) {
66544 var userLink = select_default2(document.createElement("div"));
66545 if (user.image_url) {
66546 userLink.append("img").attr("src", user.image_url).attr("class", "icon pre-text user-icon");
66548 userLink.append("a").attr("class", "user-info").text(user.display_name).attr("href", osm.userURL(user.display_name)).attr("target", "_blank");
66549 prose.html(_t.html("note.upload_explanation_with_user", { user: { html: userLink.html() } }));
66552 function noteSaveButtons(selection2) {
66553 var osm = services.osm;
66554 var hasAuth = osm && osm.authenticated();
66555 var isSelected = _note && _note.id === context.selectedNoteID();
66556 var buttonSection = selection2.selectAll(".buttons").data(isSelected ? [_note] : [], function(d) {
66557 return d.status + d.id;
66559 buttonSection.exit().remove();
66560 var buttonEnter = buttonSection.enter().append("div").attr("class", "buttons");
66561 if (_note.isNew()) {
66562 buttonEnter.append("button").attr("class", "button cancel-button secondary-action").call(_t.append("confirm.cancel"));
66563 buttonEnter.append("button").attr("class", "button save-button action").call(_t.append("note.save"));
66565 buttonEnter.append("button").attr("class", "button status-button action");
66566 buttonEnter.append("button").attr("class", "button comment-button action").call(_t.append("note.comment"));
66568 buttonSection = buttonSection.merge(buttonEnter);
66569 buttonSection.select(".cancel-button").on("click.cancel", clickCancel);
66570 buttonSection.select(".save-button").attr("disabled", isSaveDisabled).on("click.save", clickSave);
66571 buttonSection.select(".status-button").attr("disabled", hasAuth ? null : true).html(function(d) {
66572 var action = d.status === "open" ? "close" : "open";
66573 var andComment = d.newComment ? "_comment" : "";
66574 return _t.html("note." + action + andComment);
66575 }).on("click.status", clickStatus);
66576 buttonSection.select(".comment-button").attr("disabled", isSaveDisabled).on("click.comment", clickComment);
66577 function isSaveDisabled(d) {
66578 return hasAuth && d.status === "open" && d.newComment ? null : true;
66581 function clickCancel(d3_event, d) {
66583 var osm = services.osm;
66587 context.enter(modeBrowse(context));
66588 dispatch10.call("change");
66590 function clickSave(d3_event, d) {
66592 var osm = services.osm;
66594 osm.postNoteCreate(d, function(err, note) {
66595 dispatch10.call("change", note);
66599 function clickStatus(d3_event, d) {
66601 var osm = services.osm;
66603 var setStatus = d.status === "open" ? "closed" : "open";
66604 osm.postNoteUpdate(d, setStatus, function(err, note) {
66605 dispatch10.call("change", note);
66609 function clickComment(d3_event, d) {
66611 var osm = services.osm;
66613 osm.postNoteUpdate(d, d.status, function(err, note) {
66614 dispatch10.call("change", note);
66618 noteEditor.note = function(val) {
66619 if (!arguments.length)
66624 noteEditor.newNote = function(val) {
66625 if (!arguments.length)
66630 return utilRebind(noteEditor, dispatch10, "on");
66633 // modules/ui/source_switch.js
66634 function uiSourceSwitch(context) {
66636 function click(d3_event) {
66637 d3_event.preventDefault();
66638 var osm = context.connection();
66641 if (context.inIntro())
66643 if (context.history().hasChanges() && !window.confirm(_t("source_switch.lose_changes")))
66645 var isLive = select_default2(this).classed("live");
66647 context.enter(modeBrowse(context));
66648 context.history().clearSaved();
66650 select_default2(this).html(isLive ? _t.html("source_switch.live") : _t.html("source_switch.dev")).classed("live", isLive).classed("chip", isLive);
66651 osm.switch(isLive ? keys[0] : keys[1]);
66653 var sourceSwitch = function(selection2) {
66654 selection2.append("a").attr("href", "#").call(_t.append("source_switch.live")).attr("class", "live chip").on("click", click);
66656 sourceSwitch.keys = function(_) {
66657 if (!arguments.length)
66660 return sourceSwitch;
66662 return sourceSwitch;
66665 // modules/ui/spinner.js
66666 function uiSpinner(context) {
66667 var osm = context.connection();
66668 return function(selection2) {
66669 var img = selection2.append("img").attr("src", context.imagePath("loader-black.gif")).style("opacity", 0);
66671 osm.on("loading.spinner", function() {
66672 img.transition().style("opacity", 1);
66673 }).on("loaded.spinner", function() {
66674 img.transition().style("opacity", 0);
66680 // modules/ui/sections/privacy.js
66681 function uiSectionPrivacy(context) {
66682 let section = uiSection("preferences-third-party", context).label(() => _t.append("preferences.privacy.title")).disclosureContent(renderDisclosureContent);
66683 function renderDisclosureContent(selection2) {
66684 selection2.selectAll(".privacy-options-list").data([0]).enter().append("ul").attr("class", "layer-list privacy-options-list");
66685 let thirdPartyIconsEnter = selection2.select(".privacy-options-list").selectAll(".privacy-third-party-icons-item").data([corePreferences("preferences.privacy.thirdpartyicons") || "true"]).enter().append("li").attr("class", "privacy-third-party-icons-item").append("label").call(
66686 uiTooltip().title(() => _t.append("preferences.privacy.third_party_icons.tooltip")).placement("bottom")
66688 thirdPartyIconsEnter.append("input").attr("type", "checkbox").on("change", (d3_event, d) => {
66689 d3_event.preventDefault();
66690 corePreferences("preferences.privacy.thirdpartyicons", d === "true" ? "false" : "true");
66692 thirdPartyIconsEnter.append("span").call(_t.append("preferences.privacy.third_party_icons.description"));
66693 selection2.selectAll(".privacy-third-party-icons-item").classed("active", (d) => d === "true").select("input").property("checked", (d) => d === "true");
66694 selection2.selectAll(".privacy-link").data([0]).enter().append("div").attr("class", "privacy-link").append("a").attr("target", "_blank").call(svgIcon("#iD-icon-out-link", "inline")).attr("href", "https://github.com/openstreetmap/iD/blob/release/PRIVACY.md").append("span").call(_t.append("preferences.privacy.privacy_link"));
66696 corePreferences.onChange("preferences.privacy.thirdpartyicons", section.reRender);
66700 // modules/ui/splash.js
66701 function uiSplash(context) {
66702 return (selection2) => {
66703 if (context.history().hasRestorableChanges())
66705 let updateMessage = "";
66706 const sawPrivacyVersion = corePreferences("sawPrivacyVersion");
66707 let showSplash = !corePreferences("sawSplash");
66708 if (sawPrivacyVersion !== context.privacyVersion) {
66709 updateMessage = _t("splash.privacy_update");
66714 corePreferences("sawSplash", true);
66715 corePreferences("sawPrivacyVersion", context.privacyVersion);
66716 _mainFileFetcher.get("intro_graph");
66717 let modalSelection = uiModal(selection2);
66718 modalSelection.select(".modal").attr("class", "modal-splash modal");
66719 let introModal = modalSelection.select(".content").append("div").attr("class", "fillL");
66720 introModal.append("div").attr("class", "modal-section").append("h3").call(_t.append("splash.welcome"));
66721 let modalSection = introModal.append("div").attr("class", "modal-section");
66722 modalSection.append("p").html(_t.html("splash.text", {
66723 version: context.version,
66724 website: { html: '<a target="_blank" href="https://github.com/openstreetmap/iD/blob/develop/CHANGELOG.md#whats-new">' + _t.html("splash.changelog") + "</a>" },
66725 github: { html: '<a target="_blank" href="https://github.com/openstreetmap/iD/issues">github.com</a>' }
66727 modalSection.append("p").html(_t.html("splash.privacy", {
66729 privacyLink: { html: '<a target="_blank" href="https://github.com/openstreetmap/iD/blob/release/PRIVACY.md">' + _t("splash.privacy_policy") + "</a>" }
66731 uiSectionPrivacy(context).label(() => _t.append("splash.privacy_settings")).render(modalSection);
66732 let buttonWrap = introModal.append("div").attr("class", "modal-actions");
66733 let walkthrough = buttonWrap.append("button").attr("class", "walkthrough").on("click", () => {
66734 context.container().call(uiIntro(context));
66735 modalSelection.close();
66737 walkthrough.append("svg").attr("class", "logo logo-walkthrough").append("use").attr("xlink:href", "#iD-logo-walkthrough");
66738 walkthrough.append("div").call(_t.append("splash.walkthrough"));
66739 let startEditing = buttonWrap.append("button").attr("class", "start-editing").on("click", modalSelection.close);
66740 startEditing.append("svg").attr("class", "logo logo-features").append("use").attr("xlink:href", "#iD-logo-features");
66741 startEditing.append("div").call(_t.append("splash.start"));
66742 modalSelection.select("button.close").attr("class", "hide");
66746 // modules/ui/status.js
66747 function uiStatus(context) {
66748 var osm = context.connection();
66749 return function(selection2) {
66752 function update(err, apiStatus) {
66753 selection2.html("");
66755 if (apiStatus === "connectionSwitched") {
66757 } else if (apiStatus === "rateLimited") {
66758 selection2.call(_t.append("osm_api_status.message.rateLimit")).append("a").attr("href", "#").attr("class", "api-status-login").attr("target", "_blank").call(svgIcon("#iD-icon-out-link", "inline")).append("span").call(_t.append("login")).on("click.login", function(d3_event) {
66759 d3_event.preventDefault();
66760 osm.authenticate();
66763 var throttledRetry = throttle_default(function() {
66764 context.loadTiles(context.projection);
66765 osm.reloadApiStatus();
66767 selection2.call(_t.append("osm_api_status.message.error", { suffix: " " })).append("a").attr("href", "#").call(_t.append("osm_api_status.retry")).on("click.retry", function(d3_event) {
66768 d3_event.preventDefault();
66772 } else if (apiStatus === "readonly") {
66773 selection2.call(_t.append("osm_api_status.message.readonly"));
66774 } else if (apiStatus === "offline") {
66775 selection2.call(_t.append("osm_api_status.message.offline"));
66777 selection2.attr("class", "api-status " + (err ? "error" : apiStatus));
66779 osm.on("apiStatusChange.uiStatus", update);
66780 context.history().on("storage_error", () => {
66781 selection2.selectAll("span.local-storage-full").remove();
66782 selection2.append("span").attr("class", "local-storage-full").call(_t.append("osm_api_status.message.local_storage_full"));
66783 selection2.classed("error", true);
66785 window.setInterval(function() {
66786 osm.reloadApiStatus();
66788 osm.reloadApiStatus();
66792 // node_modules/osm-community-index/lib/simplify.js
66793 var import_diacritics3 = __toESM(require_diacritics(), 1);
66794 function simplify2(str2) {
66795 if (typeof str2 !== "string")
66797 return import_diacritics3.default.remove(
66798 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()
66802 // node_modules/osm-community-index/lib/resolve_strings.js
66803 function resolveStrings(item, defaults2, localizerFn) {
66804 let itemStrings = Object.assign({}, item.strings);
66805 let defaultStrings = Object.assign({}, defaults2[item.type]);
66806 const anyToken = new RegExp(/(\{\w+\})/, "gi");
66808 if (itemStrings.community) {
66809 const communityID = simplify2(itemStrings.community);
66810 itemStrings.community = localizerFn(`_communities.${communityID}`);
66812 ["name", "description", "extendedDescription"].forEach((prop) => {
66813 if (defaultStrings[prop])
66814 defaultStrings[prop] = localizerFn(`_defaults.${item.type}.${prop}`);
66815 if (itemStrings[prop])
66816 itemStrings[prop] = localizerFn(`${item.id}.${prop}`);
66819 let replacements = {
66820 account: item.account,
66821 community: itemStrings.community,
66822 signupUrl: itemStrings.signupUrl,
66823 url: itemStrings.url
66825 if (!replacements.signupUrl) {
66826 replacements.signupUrl = resolve(itemStrings.signupUrl || defaultStrings.signupUrl);
66828 if (!replacements.url) {
66829 replacements.url = resolve(itemStrings.url || defaultStrings.url);
66832 name: resolve(itemStrings.name || defaultStrings.name),
66833 url: resolve(itemStrings.url || defaultStrings.url),
66834 signupUrl: resolve(itemStrings.signupUrl || defaultStrings.signupUrl),
66835 description: resolve(itemStrings.description || defaultStrings.description),
66836 extendedDescription: resolve(itemStrings.extendedDescription || defaultStrings.extendedDescription)
66838 resolved.nameHTML = linkify(resolved.url, resolved.name);
66839 resolved.urlHTML = linkify(resolved.url);
66840 resolved.signupUrlHTML = linkify(resolved.signupUrl);
66841 resolved.descriptionHTML = resolve(itemStrings.description || defaultStrings.description, true);
66842 resolved.extendedDescriptionHTML = resolve(itemStrings.extendedDescription || defaultStrings.extendedDescription, true);
66844 function resolve(s, addLinks) {
66848 for (let key in replacements) {
66849 const token = `{${key}}`;
66850 const regex = new RegExp(token, "g");
66851 if (regex.test(result)) {
66852 let replacement = replacements[key];
66853 if (!replacement) {
66854 throw new Error(`Cannot resolve token: ${token}`);
66856 if (addLinks && (key === "signupUrl" || key === "url")) {
66857 replacement = linkify(replacement);
66859 result = result.replace(regex, replacement);
66863 const leftovers = result.match(anyToken);
66865 throw new Error(`Cannot resolve tokens: ${leftovers}`);
66867 if (addLinks && item.type === "reddit") {
66868 result = result.replace(/(\/r\/\w+\/*)/i, (match) => linkify(resolved.url, match));
66872 function linkify(url, text2) {
66875 text2 = text2 || url;
66876 return `<a target="_blank" href="${url}">${text2}</a>`;
66880 // modules/ui/success.js
66882 function uiSuccess(context) {
66883 const MAXEVENTS = 2;
66884 const dispatch10 = dispatch_default("cancel");
66887 ensureOSMCommunityIndex();
66888 function ensureOSMCommunityIndex() {
66889 const data = _mainFileFetcher;
66890 return Promise.all([
66891 data.get("oci_features"),
66892 data.get("oci_resources"),
66893 data.get("oci_defaults")
66894 ]).then((vals) => {
66897 if (vals[0] && Array.isArray(vals[0].features)) {
66898 _sharedLocationManager.mergeCustomGeoJSON(vals[0]);
66900 let ociResources = Object.values(vals[1].resources);
66901 if (ociResources.length) {
66902 return _sharedLocationManager.mergeLocationSets(ociResources).then(() => {
66904 resources: ociResources,
66905 defaults: vals[2].defaults
66913 defaults: vals[2].defaults
66919 function parseEventDate(when) {
66922 let raw = when.trim();
66925 if (!/Z$/.test(raw)) {
66928 const parsed = new Date(raw);
66929 return new Date(parsed.toUTCString().slice(0, 25));
66931 function success(selection2) {
66932 let header = selection2.append("div").attr("class", "header fillL");
66933 header.append("h2").call(_t.append("success.just_edited"));
66934 header.append("button").attr("class", "close").attr("title", _t("icons.close")).on("click", () => dispatch10.call("cancel")).call(svgIcon("#iD-icon-close"));
66935 let body = selection2.append("div").attr("class", "body save-success fillL");
66936 let summary = body.append("div").attr("class", "save-summary");
66937 summary.append("h3").call(_t.append("success.thank_you" + (_location ? "_location" : ""), { where: _location }));
66938 summary.append("p").call(_t.append("success.help_html")).append("a").attr("class", "link-out").attr("target", "_blank").attr("href", _t("success.help_link_url")).call(svgIcon("#iD-icon-out-link", "inline")).append("span").call(_t.append("success.help_link_text"));
66939 let osm = context.connection();
66942 let changesetURL = osm.changesetURL(_changeset2.id);
66943 let table = summary.append("table").attr("class", "summary-table");
66944 let row = table.append("tr").attr("class", "summary-row");
66945 row.append("td").attr("class", "cell-icon summary-icon").append("a").attr("target", "_blank").attr("href", changesetURL).append("svg").attr("class", "logo-small").append("use").attr("xlink:href", "#iD-logo-osm");
66946 let summaryDetail = row.append("td").attr("class", "cell-detail summary-detail");
66947 summaryDetail.append("a").attr("class", "cell-detail summary-view-on-osm").attr("target", "_blank").attr("href", changesetURL).call(_t.append("success.view_on_osm"));
66948 summaryDetail.append("div").html(_t.html("success.changeset_id", {
66949 changeset_id: { html: `<a href="${changesetURL}" target="_blank">${_changeset2.id}</a>` }
66951 ensureOSMCommunityIndex().then((oci) => {
66952 const loc = context.map().center();
66953 const validHere = _sharedLocationManager.locationSetsAt(loc);
66954 let communities = [];
66955 oci.resources.forEach((resource) => {
66956 let area = validHere[resource.locationSetID];
66959 const localizer = (stringID) => _t.html(`community.${stringID}`);
66960 resource.resolved = resolveStrings(resource, oci.defaults, localizer);
66963 order: resource.order || 0,
66967 communities.sort((a, b) => a.area - b.area || b.order - a.order);
66968 body.call(showCommunityLinks, communities.map((c) => c.resource));
66971 function showCommunityLinks(selection2, resources) {
66972 let communityLinks = selection2.append("div").attr("class", "save-communityLinks");
66973 communityLinks.append("h3").call(_t.append("success.like_osm"));
66974 let table = communityLinks.append("table").attr("class", "community-table");
66975 let row = table.selectAll(".community-row").data(resources);
66976 let rowEnter = row.enter().append("tr").attr("class", "community-row");
66977 rowEnter.append("td").attr("class", "cell-icon community-icon").append("a").attr("target", "_blank").attr("href", (d) => d.resolved.url).append("svg").attr("class", "logo-small").append("use").attr("xlink:href", (d) => `#community-${d.type}`);
66978 let communityDetail = rowEnter.append("td").attr("class", "cell-detail community-detail");
66979 communityDetail.each(showCommunityDetails);
66980 communityLinks.append("div").attr("class", "community-missing").call(_t.append("success.missing")).append("a").attr("class", "link-out").attr("target", "_blank").call(svgIcon("#iD-icon-out-link", "inline")).attr("href", "https://github.com/osmlab/osm-community-index/issues").append("span").call(_t.append("success.tell_us"));
66982 function showCommunityDetails(d) {
66983 let selection2 = select_default2(this);
66984 let communityID = d.id;
66985 selection2.append("div").attr("class", "community-name").html(d.resolved.nameHTML);
66986 selection2.append("div").attr("class", "community-description").html(d.resolved.descriptionHTML);
66987 if (d.resolved.extendedDescriptionHTML || d.languageCodes && d.languageCodes.length) {
66988 selection2.append("div").call(
66989 uiDisclosure(context, `community-more-${d.id}`, false).expanded(false).updatePreference(false).label(() => _t.append("success.more")).content(showMore)
66992 let nextEvents = (d.events || []).map((event) => {
66993 event.date = parseEventDate(event.when);
66995 }).filter((event) => {
66996 const t = event.date.getTime();
66997 const now3 = (/* @__PURE__ */ new Date()).setHours(0, 0, 0, 0);
66998 return !isNaN(t) && t >= now3;
66999 }).sort((a, b) => {
67000 return a.date < b.date ? -1 : a.date > b.date ? 1 : 0;
67001 }).slice(0, MAXEVENTS);
67002 if (nextEvents.length) {
67003 selection2.append("div").call(
67004 uiDisclosure(context, `community-events-${d.id}`, false).expanded(false).updatePreference(false).label(_t.html("success.events")).content(showNextEvents)
67005 ).select(".hide-toggle").append("span").attr("class", "badge-text").text(nextEvents.length);
67007 function showMore(selection3) {
67008 let more = selection3.selectAll(".community-more").data([0]);
67009 let moreEnter = more.enter().append("div").attr("class", "community-more");
67010 if (d.resolved.extendedDescriptionHTML) {
67011 moreEnter.append("div").attr("class", "community-extended-description").html(d.resolved.extendedDescriptionHTML);
67013 if (d.languageCodes && d.languageCodes.length) {
67014 const languageList = d.languageCodes.map((code) => _mainLocalizer.languageName(code)).join(", ");
67015 moreEnter.append("div").attr("class", "community-languages").call(_t.append("success.languages", { languages: languageList }));
67018 function showNextEvents(selection3) {
67019 let events = selection3.append("div").attr("class", "community-events");
67020 let item = events.selectAll(".community-event").data(nextEvents);
67021 let itemEnter = item.enter().append("div").attr("class", "community-event");
67022 itemEnter.append("div").attr("class", "community-event-name").append("a").attr("target", "_blank").attr("href", (d2) => d2.url).text((d2) => {
67023 let name = d2.name;
67024 if (d2.i18n && d2.id) {
67025 name = _t(`community.${communityID}.events.${d2.id}.name`, { default: name });
67029 itemEnter.append("div").attr("class", "community-event-when").text((d2) => {
67030 let options2 = { weekday: "short", day: "numeric", month: "short", year: "numeric" };
67031 if (d2.date.getHours() || d2.date.getMinutes()) {
67032 options2.hour = "numeric";
67033 options2.minute = "numeric";
67035 return d2.date.toLocaleString(_mainLocalizer.localeCode(), options2);
67037 itemEnter.append("div").attr("class", "community-event-where").text((d2) => {
67038 let where = d2.where;
67039 if (d2.i18n && d2.id) {
67040 where = _t(`community.${communityID}.events.${d2.id}.where`, { default: where });
67044 itemEnter.append("div").attr("class", "community-event-description").text((d2) => {
67045 let description = d2.description;
67046 if (d2.i18n && d2.id) {
67047 description = _t(`community.${communityID}.events.${d2.id}.description`, { default: description });
67049 return description;
67053 success.changeset = function(val) {
67054 if (!arguments.length)
67055 return _changeset2;
67059 success.location = function(val) {
67060 if (!arguments.length)
67065 return utilRebind(success, dispatch10, "on");
67068 // modules/ui/version.js
67069 var sawVersion = null;
67070 var isNewVersion = false;
67071 var isNewUser = false;
67072 function uiVersion(context) {
67073 var currVersion = context.version;
67074 var matchedVersion = currVersion.match(/\d+\.\d+\.\d+.*/);
67075 if (sawVersion === null && matchedVersion !== null) {
67076 if (corePreferences("sawVersion")) {
67078 isNewVersion = corePreferences("sawVersion") !== currVersion && currVersion.indexOf("-") === -1;
67081 isNewVersion = true;
67083 corePreferences("sawVersion", currVersion);
67084 sawVersion = currVersion;
67086 return function(selection2) {
67087 selection2.append("a").attr("target", "_blank").attr("href", "https://github.com/openstreetmap/iD").text(currVersion);
67088 if (isNewVersion && !isNewUser) {
67089 selection2.append("a").attr("class", "badge").attr("target", "_blank").attr("href", "https://github.com/openstreetmap/iD/blob/release/CHANGELOG.md#whats-new").call(svgIcon("#maki-gift")).call(
67090 uiTooltip().title(() => _t.append("version.whats_new", { version: currVersion })).placement("top").scrollContainer(context.container().select(".main-footer-wrap"))
67096 // modules/ui/zoom.js
67097 function uiZoom(context) {
67100 icon: "iD-icon-plus",
67101 title: _t.append("zoom.in"),
67103 disabled: function() {
67104 return !context.map().canZoomIn();
67106 disabledTitle: _t.append("zoom.disabled.in"),
67110 icon: "iD-icon-minus",
67111 title: _t.append("zoom.out"),
67113 disabled: function() {
67114 return !context.map().canZoomOut();
67116 disabledTitle: _t.append("zoom.disabled.out"),
67119 function zoomIn(d3_event) {
67120 if (d3_event.shiftKey)
67122 d3_event.preventDefault();
67123 context.map().zoomIn();
67125 function zoomOut(d3_event) {
67126 if (d3_event.shiftKey)
67128 d3_event.preventDefault();
67129 context.map().zoomOut();
67131 function zoomInFurther(d3_event) {
67132 if (d3_event.shiftKey)
67134 d3_event.preventDefault();
67135 context.map().zoomInFurther();
67137 function zoomOutFurther(d3_event) {
67138 if (d3_event.shiftKey)
67140 d3_event.preventDefault();
67141 context.map().zoomOutFurther();
67143 return function(selection2) {
67144 var tooltipBehavior = uiTooltip().placement(_mainLocalizer.textDirection() === "rtl" ? "right" : "left").title(function(d) {
67145 if (d.disabled()) {
67146 return d.disabledTitle;
67149 }).keys(function(d) {
67152 var lastPointerUpType;
67153 var buttons = selection2.selectAll("button").data(zooms).enter().append("button").attr("class", function(d) {
67155 }).on("pointerup.editor", function(d3_event) {
67156 lastPointerUpType = d3_event.pointerType;
67157 }).on("click.editor", function(d3_event, d) {
67158 if (!d.disabled()) {
67159 d.action(d3_event);
67160 } else if (lastPointerUpType === "touch" || lastPointerUpType === "pen") {
67161 context.ui().flash.duration(2e3).iconName("#" + d.icon).iconClass("disabled").label(d.disabledTitle)();
67163 lastPointerUpType = null;
67164 }).call(tooltipBehavior);
67165 buttons.each(function(d) {
67166 select_default2(this).call(svgIcon("#" + d.icon, "light"));
67168 utilKeybinding.plusKeys.forEach(function(key) {
67169 context.keybinding().on([key], zoomIn);
67170 context.keybinding().on([uiCmd("\u2325" + key)], zoomInFurther);
67172 utilKeybinding.minusKeys.forEach(function(key) {
67173 context.keybinding().on([key], zoomOut);
67174 context.keybinding().on([uiCmd("\u2325" + key)], zoomOutFurther);
67176 function updateButtonStates() {
67177 buttons.classed("disabled", function(d) {
67178 return d.disabled();
67179 }).each(function() {
67180 var selection3 = select_default2(this);
67181 if (!selection3.select(".tooltip.in").empty()) {
67182 selection3.call(tooltipBehavior.updateContent);
67186 updateButtonStates();
67187 context.map().on("move.uiZoom", updateButtonStates);
67191 // modules/ui/sections/raw_tag_editor.js
67192 function uiSectionRawTagEditor(id2, context) {
67193 var section = uiSection(id2, context).classes("raw-tag-editor").label(function() {
67194 var count = Object.keys(_tags).filter(function(d) {
67197 return _t.append("inspector.title_count", { title: _t("inspector.tags"), count });
67198 }).expandedByDefault(false).disclosureContent(renderDisclosureContent);
67199 var taginfo = services.taginfo;
67200 var dispatch10 = dispatch_default("change");
67201 var availableViews = [
67202 { id: "list", icon: "#fas-th-list" },
67203 { id: "text", icon: "#fas-i-cursor" }
67205 var _tagView = corePreferences("raw-tag-editor-view") || "list";
67206 var _readOnlyTags = [];
67207 var _orderedKeys = [];
67208 var _showBlank = false;
67209 var _pendingChange = null;
67214 var _didInteract = false;
67215 function interacted() {
67216 _didInteract = true;
67218 function renderDisclosureContent(wrap2) {
67219 _orderedKeys = _orderedKeys.filter(function(key) {
67220 return _tags[key] !== void 0;
67222 var all = Object.keys(_tags).sort();
67223 var missingKeys = utilArrayDifference(all, _orderedKeys);
67224 for (var i2 in missingKeys) {
67225 _orderedKeys.push(missingKeys[i2]);
67227 var rowData = _orderedKeys.map(function(key, i3) {
67228 return { index: i3, key, value: _tags[key] };
67230 if (!rowData.length || _showBlank) {
67231 _showBlank = false;
67232 rowData.push({ index: rowData.length, key: "", value: "" });
67234 var options2 = wrap2.selectAll(".raw-tag-options").data([0]);
67235 options2.exit().remove();
67236 var optionsEnter = options2.enter().insert("div", ":first-child").attr("class", "raw-tag-options").attr("role", "tablist");
67237 var optionEnter = optionsEnter.selectAll(".raw-tag-option").data(availableViews, function(d) {
67240 optionEnter.append("button").attr("class", function(d) {
67241 return "raw-tag-option raw-tag-option-" + d.id + (_tagView === d.id ? " selected" : "");
67242 }).attr("aria-selected", function(d) {
67243 return _tagView === d.id;
67244 }).attr("role", "tab").attr("title", function(d) {
67245 return _t("icons." + d.id);
67246 }).on("click", function(d3_event, d) {
67248 corePreferences("raw-tag-editor-view", d.id);
67249 wrap2.selectAll(".raw-tag-option").classed("selected", function(datum2) {
67250 return datum2 === d;
67251 }).attr("aria-selected", function(datum2) {
67252 return datum2 === d;
67254 wrap2.selectAll(".tag-text").classed("hide", d.id !== "text").each(setTextareaHeight);
67255 wrap2.selectAll(".tag-list, .add-row").classed("hide", d.id !== "list");
67256 }).each(function(d) {
67257 select_default2(this).call(svgIcon(d.icon));
67259 var textData = rowsToText(rowData);
67260 var textarea = wrap2.selectAll(".tag-text").data([0]);
67261 textarea = textarea.enter().append("textarea").attr("class", "tag-text" + (_tagView !== "text" ? " hide" : "")).call(utilNoAuto).attr("placeholder", _t("inspector.key_value")).attr("spellcheck", "false").merge(textarea);
67262 textarea.call(utilGetSetValue, textData).each(setTextareaHeight).on("input", setTextareaHeight).on("focus", interacted).on("blur", textChanged).on("change", textChanged);
67263 var list = wrap2.selectAll(".tag-list").data([0]);
67264 list = list.enter().append("ul").attr("class", "tag-list" + (_tagView !== "list" ? " hide" : "")).merge(list);
67265 var addRowEnter = wrap2.selectAll(".add-row").data([0]).enter().append("div").attr("class", "add-row" + (_tagView !== "list" ? " hide" : ""));
67266 addRowEnter.append("button").attr("class", "add-tag").attr("aria-label", _t("inspector.add_to_tag")).call(svgIcon("#iD-icon-plus", "light")).call(uiTooltip().title(() => _t.append("inspector.add_to_tag")).placement(_mainLocalizer.textDirection() === "ltr" ? "right" : "left")).on("click", addTag);
67267 addRowEnter.append("div").attr("class", "space-value");
67268 addRowEnter.append("div").attr("class", "space-buttons");
67269 var items = list.selectAll(".tag-row").data(rowData, function(d) {
67272 items.exit().each(unbind).remove();
67273 var itemsEnter = items.enter().append("li").attr("class", "tag-row").classed("readonly", isReadOnly);
67274 var innerWrap = itemsEnter.append("div").attr("class", "inner-wrap");
67275 innerWrap.append("div").attr("class", "key-wrap").append("input").property("type", "text").attr("class", "key").call(utilNoAuto).on("focus", interacted).on("blur", keyChange).on("change", keyChange);
67276 innerWrap.append("div").attr("class", "value-wrap").append("input").property("type", "text").attr("class", "value").call(utilNoAuto).on("focus", interacted).on("blur", valueChange).on("change", valueChange).on("keydown.push-more", pushMore);
67277 innerWrap.append("button").attr("class", "form-field-button remove").attr("title", _t("icons.remove")).call(svgIcon("#iD-operation-delete"));
67278 items = items.merge(itemsEnter).sort(function(a, b) {
67279 return a.index - b.index;
67281 items.each(function(d) {
67282 var row = select_default2(this);
67283 var key = row.select("input.key");
67284 var value = row.select("input.value");
67285 if (_entityIDs && taginfo && _state !== "hover") {
67286 bindTypeahead(key, value);
67288 var referenceOptions = { key: d.key };
67289 if (typeof d.value === "string") {
67290 referenceOptions.value = d.value;
67292 var reference = uiTagReference(referenceOptions, context);
67293 if (_state === "hover") {
67294 reference.showing(false);
67296 row.select(".inner-wrap").call(reference.button);
67297 row.call(reference.body);
67298 row.select("button.remove");
67300 items.selectAll("input.key").attr("title", function(d) {
67302 }).call(utilGetSetValue, function(d) {
67304 }).attr("readonly", function(d) {
67305 return isReadOnly(d) || null;
67307 items.selectAll("input.value").attr("title", function(d) {
67308 return Array.isArray(d.value) ? d.value.filter(Boolean).join("\n") : d.value;
67309 }).classed("mixed", function(d) {
67310 return Array.isArray(d.value);
67311 }).attr("placeholder", function(d) {
67312 return typeof d.value === "string" ? null : _t("inspector.multiple_values");
67313 }).call(utilGetSetValue, function(d) {
67314 return typeof d.value === "string" ? d.value : "";
67315 }).attr("readonly", function(d) {
67316 return isReadOnly(d) || null;
67318 items.selectAll("button.remove").on(("PointerEvent" in window ? "pointer" : "mouse") + "down", removeTag);
67320 function isReadOnly(d) {
67321 for (var i2 = 0; i2 < _readOnlyTags.length; i2++) {
67322 if (d.key.match(_readOnlyTags[i2]) !== null) {
67328 function setTextareaHeight() {
67329 if (_tagView !== "text")
67331 var selection2 = select_default2(this);
67332 var matches = selection2.node().value.match(/\n/g);
67333 var lineCount = 2 + Number(matches && matches.length);
67334 var lineHeight = 20;
67335 selection2.style("height", lineCount * lineHeight + "px");
67337 function stringify3(s) {
67338 return JSON.stringify(s).slice(1, -1);
67340 function unstringify(s) {
67343 if (s.length < 1 || s.charAt(0) !== '"') {
67346 if (s.length < 2 || s.charAt(s.length - 1) !== '"' || s.charAt(s.length - 1) === '"' && s.charAt(s.length - 2) === "\\") {
67349 return JSON.parse(leading + s + trailing);
67351 function rowsToText(rows) {
67352 var str2 = rows.filter(function(row) {
67353 return row.key && row.key.trim() !== "";
67354 }).map(function(row) {
67355 var rawVal = row.value;
67356 if (typeof rawVal !== "string")
67358 var val = rawVal ? stringify3(rawVal) : "";
67359 return stringify3(row.key) + "=" + val;
67361 if (_state !== "hover" && str2.length) {
67362 return str2 + "\n";
67366 function textChanged() {
67367 var newText = this.value.trim();
67369 newText.split("\n").forEach(function(row) {
67370 var m = row.match(/^\s*([^=]+)=(.*)$/);
67372 var k = context.cleanTagKey(unstringify(m[1].trim()));
67373 var v = context.cleanTagValue(unstringify(m[2].trim()));
67377 var tagDiff = utilTagDiff(_tags, newTags);
67378 if (!tagDiff.length)
67380 _pendingChange = _pendingChange || {};
67381 tagDiff.forEach(function(change) {
67382 if (isReadOnly({ key: change.key }))
67384 if (change.newVal === "*" && typeof change.oldVal !== "string")
67386 if (change.type === "-") {
67387 _pendingChange[change.key] = void 0;
67388 } else if (change.type === "+") {
67389 _pendingChange[change.key] = change.newVal || "";
67392 if (Object.keys(_pendingChange).length === 0) {
67393 _pendingChange = null;
67398 function pushMore(d3_event) {
67399 if (d3_event.keyCode === 9 && !d3_event.shiftKey && section.selection().selectAll(".tag-list li:last-child input.value").node() === this && utilGetSetValue(select_default2(this))) {
67403 function bindTypeahead(key, value) {
67404 if (isReadOnly(key.datum()))
67406 if (Array.isArray(value.datum().value)) {
67407 value.call(uiCombobox(context, "tag-value").minItems(1).fetcher(function(value2, callback) {
67408 var keyString = utilGetSetValue(key);
67409 if (!_tags[keyString])
67411 var data = _tags[keyString].filter(Boolean).map(function(tagValue) {
67421 var geometry = context.graph().geometry(_entityIDs[0]);
67422 key.call(uiCombobox(context, "tag-key").fetcher(function(value2, callback) {
67427 }, function(err, data) {
67429 var filtered = data.filter(function(d) {
67430 return _tags[d.value] === void 0;
67432 callback(sort(value2, filtered));
67436 value.call(uiCombobox(context, "tag-value").fetcher(function(value2, callback) {
67439 key: utilGetSetValue(key),
67442 }, function(err, data) {
67444 callback(sort(value2, data));
67447 function sort(value2, data) {
67448 var sameletter = [];
67450 for (var i2 = 0; i2 < data.length; i2++) {
67451 if (data[i2].value.substring(0, value2.length) === value2) {
67452 sameletter.push(data[i2]);
67454 other.push(data[i2]);
67457 return sameletter.concat(other);
67460 function unbind() {
67461 var row = select_default2(this);
67462 row.selectAll("input.key").call(uiCombobox.off, context);
67463 row.selectAll("input.value").call(uiCombobox.off, context);
67465 function keyChange(d3_event, d) {
67466 if (select_default2(this).attr("readonly"))
67469 if (_pendingChange && _pendingChange.hasOwnProperty(kOld) && _pendingChange[kOld] === void 0)
67471 var kNew = context.cleanTagKey(this.value.trim());
67472 if (isReadOnly({ key: kNew })) {
67476 if (kNew && kNew !== kOld && _tags[kNew] !== void 0) {
67478 section.selection().selectAll(".tag-list input.value").each(function(d2) {
67479 if (d2.key === kNew) {
67480 var input = select_default2(this).node();
67487 _pendingChange = _pendingChange || {};
67491 _pendingChange[kNew] = _pendingChange[kOld] || { oldKey: kOld };
67492 _pendingChange[kOld] = void 0;
67494 let row = this.parentNode.parentNode;
67495 let inputVal = select_default2(row).selectAll("input.value");
67496 let vNew = context.cleanTagValue(utilGetSetValue(inputVal));
67497 _pendingChange[kNew] = vNew;
67498 utilGetSetValue(inputVal, vNew);
67500 var existingKeyIndex = _orderedKeys.indexOf(kOld);
67501 if (existingKeyIndex !== -1)
67502 _orderedKeys[existingKeyIndex] = kNew;
67507 function valueChange(d3_event, d) {
67510 if (typeof d.value !== "string" && !this.value)
67512 if (_pendingChange && _pendingChange.hasOwnProperty(d.key) && _pendingChange[d.key] === void 0)
67514 _pendingChange = _pendingChange || {};
67515 _pendingChange[d.key] = context.cleanTagValue(this.value);
67518 function removeTag(d3_event, d) {
67521 if (d.key === "") {
67522 _showBlank = false;
67523 section.reRender();
67525 _orderedKeys = _orderedKeys.filter(function(key) {
67526 return key !== d.key;
67528 _pendingChange = _pendingChange || {};
67529 _pendingChange[d.key] = void 0;
67533 function addTag() {
67534 window.setTimeout(function() {
67536 section.reRender();
67537 section.selection().selectAll(".tag-list li:last-child input.key").node().focus();
67540 function scheduleChange() {
67541 var entityIDs = _entityIDs;
67542 window.setTimeout(function() {
67543 if (!_pendingChange)
67545 dispatch10.call("change", this, entityIDs, _pendingChange);
67546 _pendingChange = null;
67549 section.state = function(val) {
67550 if (!arguments.length)
67552 if (_state !== val) {
67558 section.presets = function(val) {
67559 if (!arguments.length)
67562 if (_presets && _presets.length && _presets[0].isFallback()) {
67563 section.disclosureExpanded(true);
67564 } else if (!_didInteract) {
67565 section.disclosureExpanded(null);
67569 section.tags = function(val) {
67570 if (!arguments.length)
67575 section.entityIDs = function(val) {
67576 if (!arguments.length)
67578 if (!_entityIDs || !val || !utilArrayIdentical(_entityIDs, val)) {
67584 section.readOnlyTags = function(val) {
67585 if (!arguments.length)
67586 return _readOnlyTags;
67587 _readOnlyTags = val;
67590 return utilRebind(section, dispatch10, "on");
67593 // modules/ui/data_editor.js
67594 function uiDataEditor(context) {
67595 var dataHeader = uiDataHeader();
67596 var rawTagEditor = uiSectionRawTagEditor("custom-data-tag-editor", context).expandedByDefault(true).readOnlyTags([/./]);
67598 function dataEditor(selection2) {
67599 var header = selection2.selectAll(".header").data([0]);
67600 var headerEnter = header.enter().append("div").attr("class", "header fillL");
67601 headerEnter.append("button").attr("class", "close").attr("title", _t("icons.close")).on("click", function() {
67602 context.enter(modeBrowse(context));
67603 }).call(svgIcon("#iD-icon-close"));
67604 headerEnter.append("h2").call(_t.append("map_data.title"));
67605 var body = selection2.selectAll(".body").data([0]);
67606 body = body.enter().append("div").attr("class", "body").merge(body);
67607 var editor = body.selectAll(".data-editor").data([0]);
67608 editor.enter().append("div").attr("class", "modal-section data-editor").merge(editor).call(dataHeader.datum(_datum));
67609 var rte = body.selectAll(".raw-tag-editor").data([0]);
67610 rte.enter().append("div").attr("class", "raw-tag-editor data-editor").merge(rte).call(
67611 rawTagEditor.tags(_datum && _datum.properties || {}).state("hover").render
67612 ).selectAll("textarea.tag-text").attr("readonly", true).classed("readonly", true);
67614 dataEditor.datum = function(val) {
67615 if (!arguments.length)
67623 // modules/ui/osmose_details.js
67624 function uiOsmoseDetails(context) {
67626 function issueString(d, type2) {
67629 const s = services.osmose.getStrings(d.itemType);
67630 return type2 in s ? s[type2] : "";
67632 function osmoseDetails(selection2) {
67633 const details = selection2.selectAll(".error-details").data(
67634 _qaItem ? [_qaItem] : [],
67635 (d) => `${d.id}-${d.status || 0}`
67637 details.exit().remove();
67638 const detailsEnter = details.enter().append("div").attr("class", "error-details qa-details-container");
67639 if (issueString(_qaItem, "detail")) {
67640 const div = detailsEnter.append("div").attr("class", "qa-details-subsection");
67641 div.append("h4").call(_t.append("QA.keepRight.detail_description"));
67642 div.append("p").attr("class", "qa-details-description-text").html((d) => issueString(d, "detail")).selectAll("a").attr("rel", "noopener").attr("target", "_blank");
67644 const detailsDiv = detailsEnter.append("div").attr("class", "qa-details-subsection");
67645 const elemsDiv = detailsEnter.append("div").attr("class", "qa-details-subsection");
67646 if (issueString(_qaItem, "fix")) {
67647 const div = detailsEnter.append("div").attr("class", "qa-details-subsection");
67648 div.append("h4").call(_t.append("QA.osmose.fix_title"));
67649 div.append("p").html((d) => issueString(d, "fix")).selectAll("a").attr("rel", "noopener").attr("target", "_blank");
67651 if (issueString(_qaItem, "trap")) {
67652 const div = detailsEnter.append("div").attr("class", "qa-details-subsection");
67653 div.append("h4").call(_t.append("QA.osmose.trap_title"));
67654 div.append("p").html((d) => issueString(d, "trap")).selectAll("a").attr("rel", "noopener").attr("target", "_blank");
67656 const thisItem = _qaItem;
67657 services.osmose.loadIssueDetail(_qaItem).then((d) => {
67658 if (!d.elems || d.elems.length === 0)
67660 if (context.selectedErrorID() !== thisItem.id && context.container().selectAll(`.qaItem.osmose.hover.itemId-${thisItem.id}`).empty())
67663 detailsDiv.append("h4").call(_t.append("QA.osmose.detail_title"));
67664 detailsDiv.append("p").html((d2) => d2.detail).selectAll("a").attr("rel", "noopener").attr("target", "_blank");
67666 elemsDiv.append("h4").call(_t.append("QA.osmose.elems_title"));
67667 elemsDiv.append("ul").selectAll("li").data(d.elems).enter().append("li").append("a").attr("href", "#").attr("class", "error_entity_link").text((d2) => d2).each(function() {
67668 const link2 = select_default2(this);
67669 const entityID = this.textContent;
67670 const entity = context.hasEntity(entityID);
67671 link2.on("mouseenter", () => {
67672 utilHighlightEntities([entityID], true, context);
67673 }).on("mouseleave", () => {
67674 utilHighlightEntities([entityID], false, context);
67675 }).on("click", (d3_event) => {
67676 d3_event.preventDefault();
67677 utilHighlightEntities([entityID], false, context);
67678 const osmlayer = context.layers().layer("osm");
67679 if (!osmlayer.enabled()) {
67680 osmlayer.enabled(true);
67682 context.map().centerZoom(d.loc, 20);
67684 context.enter(modeSelect(context, [entityID]));
67686 context.loadEntity(entityID, (err, result) => {
67689 const entity2 = result.data.find((e) => e.id === entityID);
67691 context.enter(modeSelect(context, [entityID]));
67696 let name = utilDisplayName(entity);
67698 const preset = _mainPresetIndex.match(entity, context.graph());
67699 name = preset && !preset.isFallback() && preset.name();
67702 this.innerText = name;
67706 context.features().forceVisible(d.elems);
67707 context.map().pan([0, 0]);
67708 }).catch((err) => {
67712 osmoseDetails.issue = function(val) {
67713 if (!arguments.length)
67716 return osmoseDetails;
67718 return osmoseDetails;
67721 // modules/ui/osmose_header.js
67722 function uiOsmoseHeader() {
67724 function issueTitle(d) {
67725 const unknown = _t("inspector.unknown");
67728 const s = services.osmose.getStrings(d.itemType);
67729 return "title" in s ? s.title : unknown;
67731 function osmoseHeader(selection2) {
67732 const header = selection2.selectAll(".qa-header").data(
67733 _qaItem ? [_qaItem] : [],
67734 (d) => `${d.id}-${d.status || 0}`
67736 header.exit().remove();
67737 const headerEnter = header.enter().append("div").attr("class", "qa-header");
67738 const svgEnter = headerEnter.append("div").attr("class", "qa-header-icon").classed("new", (d) => d.id < 0).append("svg").attr("width", "20px").attr("height", "30px").attr("viewbox", "0 0 20 30").attr("class", (d) => `preset-icon-28 qaItem ${d.service} itemId-${d.id} itemType-${d.itemType}`);
67739 svgEnter.append("polygon").attr("fill", (d) => services.osmose.getColor(d.item)).attr("class", "qaItem-fill").attr("points", "16,3 4,3 1,6 1,17 4,20 7,20 10,27 13,20 16,20 19,17.033 19,6");
67740 svgEnter.append("use").attr("class", "icon-annotation").attr("width", "12px").attr("height", "12px").attr("transform", "translate(4, 5.5)").attr("xlink:href", (d) => d.icon ? "#" + d.icon : "");
67741 headerEnter.append("div").attr("class", "qa-header-label").text(issueTitle);
67743 osmoseHeader.issue = function(val) {
67744 if (!arguments.length)
67747 return osmoseHeader;
67749 return osmoseHeader;
67752 // modules/ui/view_on_osmose.js
67753 function uiViewOnOsmose() {
67755 function viewOnOsmose(selection2) {
67757 if (services.osmose && _qaItem instanceof QAItem) {
67758 url = services.osmose.itemURL(_qaItem);
67760 const link2 = selection2.selectAll(".view-on-osmose").data(url ? [url] : []);
67761 link2.exit().remove();
67762 const linkEnter = link2.enter().append("a").attr("class", "view-on-osmose").attr("target", "_blank").attr("rel", "noopener").attr("href", (d) => d).call(svgIcon("#iD-icon-out-link", "inline"));
67763 linkEnter.append("span").call(_t.append("inspector.view_on_osmose"));
67765 viewOnOsmose.what = function(val) {
67766 if (!arguments.length)
67769 return viewOnOsmose;
67771 return viewOnOsmose;
67774 // modules/ui/osmose_editor.js
67775 function uiOsmoseEditor(context) {
67776 const dispatch10 = dispatch_default("change");
67777 const qaDetails = uiOsmoseDetails(context);
67778 const qaHeader = uiOsmoseHeader(context);
67780 function osmoseEditor(selection2) {
67781 const header = selection2.selectAll(".header").data([0]);
67782 const headerEnter = header.enter().append("div").attr("class", "header fillL");
67783 headerEnter.append("button").attr("class", "close").attr("title", _t("icons.close")).on("click", () => context.enter(modeBrowse(context))).call(svgIcon("#iD-icon-close"));
67784 headerEnter.append("h2").call(_t.append("QA.osmose.title"));
67785 let body = selection2.selectAll(".body").data([0]);
67786 body = body.enter().append("div").attr("class", "body").merge(body);
67787 let editor = body.selectAll(".qa-editor").data([0]);
67788 editor.enter().append("div").attr("class", "modal-section qa-editor").merge(editor).call(qaHeader.issue(_qaItem)).call(qaDetails.issue(_qaItem)).call(osmoseSaveSection);
67789 const footer = selection2.selectAll(".footer").data([0]);
67790 footer.enter().append("div").attr("class", "footer").merge(footer).call(uiViewOnOsmose(context).what(_qaItem));
67792 function osmoseSaveSection(selection2) {
67793 const isSelected = _qaItem && _qaItem.id === context.selectedErrorID();
67794 const isShown = _qaItem && isSelected;
67795 let saveSection = selection2.selectAll(".qa-save").data(
67796 isShown ? [_qaItem] : [],
67797 (d) => `${d.id}-${d.status || 0}`
67799 saveSection.exit().remove();
67800 const saveSectionEnter = saveSection.enter().append("div").attr("class", "qa-save save-section cf");
67801 saveSection = saveSectionEnter.merge(saveSection).call(qaSaveButtons);
67803 function qaSaveButtons(selection2) {
67804 const isSelected = _qaItem && _qaItem.id === context.selectedErrorID();
67805 let buttonSection = selection2.selectAll(".buttons").data(isSelected ? [_qaItem] : [], (d) => d.status + d.id);
67806 buttonSection.exit().remove();
67807 const buttonEnter = buttonSection.enter().append("div").attr("class", "buttons");
67808 buttonEnter.append("button").attr("class", "button close-button action");
67809 buttonEnter.append("button").attr("class", "button ignore-button action");
67810 buttonSection = buttonSection.merge(buttonEnter);
67811 buttonSection.select(".close-button").call(_t.append("QA.keepRight.close")).on("click.close", function(d3_event, d) {
67813 const qaService = services.osmose;
67815 d.newStatus = "done";
67816 qaService.postUpdate(d, (err, item) => dispatch10.call("change", item));
67819 buttonSection.select(".ignore-button").call(_t.append("QA.keepRight.ignore")).on("click.ignore", function(d3_event, d) {
67821 const qaService = services.osmose;
67823 d.newStatus = "false";
67824 qaService.postUpdate(d, (err, item) => dispatch10.call("change", item));
67828 osmoseEditor.error = function(val) {
67829 if (!arguments.length)
67832 return osmoseEditor;
67834 return utilRebind(osmoseEditor, dispatch10, "on");
67837 // modules/ui/sidebar.js
67838 function uiSidebar(context) {
67839 var inspector = uiInspector(context);
67840 var dataEditor = uiDataEditor(context);
67841 var noteEditor = uiNoteEditor(context);
67842 var improveOsmEditor = uiImproveOsmEditor(context);
67843 var keepRightEditor = uiKeepRightEditor(context);
67844 var osmoseEditor = uiOsmoseEditor(context);
67846 var _wasData = false;
67847 var _wasNote = false;
67848 var _wasQaItem = false;
67849 var _pointerPrefix = "PointerEvent" in window ? "pointer" : "mouse";
67850 function sidebar(selection2) {
67851 var container = context.container();
67852 var minWidth = 240;
67854 var containerWidth;
67856 selection2.style("min-width", minWidth + "px").style("max-width", "400px").style("width", "33.3333%");
67857 var resizer = selection2.append("div").attr("class", "sidebar-resizer").on(_pointerPrefix + "down.sidebar-resizer", pointerdown);
67858 var downPointerId, lastClientX, containerLocGetter;
67859 function pointerdown(d3_event) {
67862 if ("button" in d3_event && d3_event.button !== 0)
67864 downPointerId = d3_event.pointerId || "mouse";
67865 lastClientX = d3_event.clientX;
67866 containerLocGetter = utilFastMouse(container.node());
67867 dragOffset = utilFastMouse(resizer.node())(d3_event)[0] - 1;
67868 sidebarWidth = selection2.node().getBoundingClientRect().width;
67869 containerWidth = container.node().getBoundingClientRect().width;
67870 var widthPct = sidebarWidth / containerWidth * 100;
67871 selection2.style("width", widthPct + "%").style("max-width", "85%");
67872 resizer.classed("dragging", true);
67873 select_default2(window).on("touchmove.sidebar-resizer", function(d3_event2) {
67874 d3_event2.preventDefault();
67875 }, { passive: false }).on(_pointerPrefix + "move.sidebar-resizer", pointermove).on(_pointerPrefix + "up.sidebar-resizer pointercancel.sidebar-resizer", pointerup);
67877 function pointermove(d3_event) {
67878 if (downPointerId !== (d3_event.pointerId || "mouse"))
67880 d3_event.preventDefault();
67881 var dx = d3_event.clientX - lastClientX;
67882 lastClientX = d3_event.clientX;
67883 var isRTL = _mainLocalizer.textDirection() === "rtl";
67884 var scaleX = isRTL ? 0 : 1;
67885 var xMarginProperty = isRTL ? "margin-right" : "margin-left";
67886 var x = containerLocGetter(d3_event)[0] - dragOffset;
67887 sidebarWidth = isRTL ? containerWidth - x : x;
67888 var isCollapsed = selection2.classed("collapsed");
67889 var shouldCollapse = sidebarWidth < minWidth;
67890 selection2.classed("collapsed", shouldCollapse);
67891 if (shouldCollapse) {
67892 if (!isCollapsed) {
67893 selection2.style(xMarginProperty, "-400px").style("width", "400px");
67894 context.ui().onResize([(sidebarWidth - dx) * scaleX, 0]);
67897 var widthPct = sidebarWidth / containerWidth * 100;
67898 selection2.style(xMarginProperty, null).style("width", widthPct + "%");
67900 context.ui().onResize([-sidebarWidth * scaleX, 0]);
67902 context.ui().onResize([-dx * scaleX, 0]);
67906 function pointerup(d3_event) {
67907 if (downPointerId !== (d3_event.pointerId || "mouse"))
67909 downPointerId = null;
67910 resizer.classed("dragging", false);
67911 select_default2(window).on("touchmove.sidebar-resizer", null).on(_pointerPrefix + "move.sidebar-resizer", null).on(_pointerPrefix + "up.sidebar-resizer pointercancel.sidebar-resizer", null);
67913 var featureListWrap = selection2.append("div").attr("class", "feature-list-pane").call(uiFeatureList(context));
67914 var inspectorWrap = selection2.append("div").attr("class", "inspector-hidden inspector-wrap");
67915 var hoverModeSelect = function(targets) {
67916 context.container().selectAll(".feature-list-item button").classed("hover", false);
67917 if (context.selectedIDs().length > 1 && targets && targets.length) {
67918 var elements = context.container().selectAll(".feature-list-item button").filter(function(node) {
67919 return targets.indexOf(node) !== -1;
67921 if (!elements.empty()) {
67922 elements.classed("hover", true);
67926 sidebar.hoverModeSelect = throttle_default(hoverModeSelect, 200);
67927 function hover(targets) {
67928 var datum2 = targets && targets.length && targets[0];
67929 if (datum2 && datum2.__featurehash__) {
67931 sidebar.show(dataEditor.datum(datum2));
67932 selection2.selectAll(".sidebar-component").classed("inspector-hover", true);
67933 } else if (datum2 instanceof osmNote) {
67934 if (context.mode().id === "drag-note")
67937 var osm = services.osm;
67939 datum2 = osm.getNote(datum2.id);
67941 sidebar.show(noteEditor.note(datum2));
67942 selection2.selectAll(".sidebar-component").classed("inspector-hover", true);
67943 } else if (datum2 instanceof QAItem) {
67945 var errService = services[datum2.service];
67947 datum2 = errService.getError(datum2.id);
67950 if (datum2.service === "keepRight") {
67951 errEditor = keepRightEditor;
67952 } else if (datum2.service === "osmose") {
67953 errEditor = osmoseEditor;
67955 errEditor = improveOsmEditor;
67957 context.container().selectAll(".qaItem." + datum2.service).classed("hover", function(d) {
67958 return d.id === datum2.id;
67960 sidebar.show(errEditor.error(datum2));
67961 selection2.selectAll(".sidebar-component").classed("inspector-hover", true);
67962 } else if (!_current && datum2 instanceof osmEntity) {
67963 featureListWrap.classed("inspector-hidden", true);
67964 inspectorWrap.classed("inspector-hidden", false).classed("inspector-hover", true);
67965 if (!inspector.entityIDs() || !utilArrayIdentical(inspector.entityIDs(), [datum2.id]) || inspector.state() !== "hover") {
67966 inspector.state("hover").entityIDs([datum2.id]).newFeature(false);
67967 inspectorWrap.call(inspector);
67969 } else if (!_current) {
67970 featureListWrap.classed("inspector-hidden", false);
67971 inspectorWrap.classed("inspector-hidden", true);
67972 inspector.state("hide");
67973 } else if (_wasData || _wasNote || _wasQaItem) {
67976 _wasQaItem = false;
67977 context.container().selectAll(".note").classed("hover", false);
67978 context.container().selectAll(".qaItem").classed("hover", false);
67982 sidebar.hover = throttle_default(hover, 200);
67983 sidebar.intersects = function(extent) {
67984 var rect = selection2.node().getBoundingClientRect();
67985 return extent.intersects([
67986 context.projection.invert([0, rect.height]),
67987 context.projection.invert([rect.width, 0])
67990 sidebar.select = function(ids, newFeature) {
67992 if (ids && ids.length) {
67993 var entity = ids.length === 1 && context.entity(ids[0]);
67994 if (entity && newFeature && selection2.classed("collapsed")) {
67995 var extent = entity.extent(context.graph());
67996 sidebar.expand(sidebar.intersects(extent));
67998 featureListWrap.classed("inspector-hidden", true);
67999 inspectorWrap.classed("inspector-hidden", false).classed("inspector-hover", false);
68000 inspector.state("select").entityIDs(ids).newFeature(newFeature);
68001 inspectorWrap.call(inspector);
68003 inspector.state("hide");
68006 sidebar.showPresetList = function() {
68007 inspector.showList();
68009 sidebar.show = function(component, element) {
68010 featureListWrap.classed("inspector-hidden", true);
68011 inspectorWrap.classed("inspector-hidden", true);
68014 _current = selection2.append("div").attr("class", "sidebar-component").call(component, element);
68016 sidebar.hide = function() {
68017 featureListWrap.classed("inspector-hidden", false);
68018 inspectorWrap.classed("inspector-hidden", true);
68023 sidebar.expand = function(moveMap) {
68024 if (selection2.classed("collapsed")) {
68025 sidebar.toggle(moveMap);
68028 sidebar.collapse = function(moveMap) {
68029 if (!selection2.classed("collapsed")) {
68030 sidebar.toggle(moveMap);
68033 sidebar.toggle = function(moveMap) {
68034 if (context.inIntro())
68036 var isCollapsed = selection2.classed("collapsed");
68037 var isCollapsing = !isCollapsed;
68038 var isRTL = _mainLocalizer.textDirection() === "rtl";
68039 var scaleX = isRTL ? 0 : 1;
68040 var xMarginProperty = isRTL ? "margin-right" : "margin-left";
68041 sidebarWidth = selection2.node().getBoundingClientRect().width;
68042 selection2.style("width", sidebarWidth + "px");
68043 var startMargin, endMargin, lastMargin;
68044 if (isCollapsing) {
68045 startMargin = lastMargin = 0;
68046 endMargin = -sidebarWidth;
68048 startMargin = lastMargin = -sidebarWidth;
68051 if (!isCollapsing) {
68052 selection2.classed("collapsed", isCollapsing);
68054 selection2.transition().style(xMarginProperty, endMargin + "px").tween("panner", function() {
68055 var i2 = number_default(startMargin, endMargin);
68056 return function(t) {
68057 var dx = lastMargin - Math.round(i2(t));
68058 lastMargin = lastMargin - dx;
68059 context.ui().onResize(moveMap ? void 0 : [dx * scaleX, 0]);
68061 }).on("end", function() {
68062 if (isCollapsing) {
68063 selection2.classed("collapsed", isCollapsing);
68065 if (!isCollapsing) {
68066 var containerWidth2 = container.node().getBoundingClientRect().width;
68067 var widthPct = sidebarWidth / containerWidth2 * 100;
68068 selection2.style(xMarginProperty, null).style("width", widthPct + "%");
68072 resizer.on("dblclick", function(d3_event) {
68073 d3_event.preventDefault();
68074 if (d3_event.sourceEvent) {
68075 d3_event.sourceEvent.preventDefault();
68079 context.map().on("crossEditableZoom.sidebar", function(within) {
68080 if (!within && !selection2.select(".inspector-hover").empty()) {
68085 sidebar.showPresetList = function() {
68087 sidebar.hover = function() {
68089 sidebar.hover.cancel = function() {
68091 sidebar.intersects = function() {
68093 sidebar.select = function() {
68095 sidebar.show = function() {
68097 sidebar.hide = function() {
68099 sidebar.expand = function() {
68101 sidebar.collapse = function() {
68103 sidebar.toggle = function() {
68108 // modules/modes/draw_area.js
68109 function modeDrawArea(context, wayID, startGraph, button) {
68114 var behavior = behaviorDrawWay(context, wayID, mode, startGraph).on("rejectedSelfIntersection.modeDrawArea", function() {
68115 context.ui().flash.iconName("#iD-icon-no").label(_t.append("self_intersection.error.areas"))();
68117 mode.wayID = wayID;
68118 mode.enter = function() {
68119 context.install(behavior);
68121 mode.exit = function() {
68122 context.uninstall(behavior);
68124 mode.selectedIDs = function() {
68127 mode.activeID = function() {
68128 return behavior && behavior.activeID() || [];
68133 // modules/modes/add_area.js
68134 function modeAddArea(context, mode) {
68135 mode.id = "add-area";
68136 var behavior = behaviorAddWay(context).on("start", start2).on("startFromWay", startFromWay).on("startFromNode", startFromNode);
68137 var defaultTags = { area: "yes" };
68139 defaultTags = mode.preset.setTags(defaultTags, "area");
68140 function actionClose(wayId) {
68141 return function(graph) {
68142 return graph.replace(graph.entity(wayId).close());
68145 function start2(loc) {
68146 var startGraph = context.graph();
68147 var node = osmNode({ loc });
68148 var way = osmWay({ tags: defaultTags });
68150 actionAddEntity(node),
68151 actionAddEntity(way),
68152 actionAddVertex(way.id, node.id),
68153 actionClose(way.id)
68155 context.enter(modeDrawArea(context, way.id, startGraph, mode.button));
68157 function startFromWay(loc, edge) {
68158 var startGraph = context.graph();
68159 var node = osmNode({ loc });
68160 var way = osmWay({ tags: defaultTags });
68162 actionAddEntity(node),
68163 actionAddEntity(way),
68164 actionAddVertex(way.id, node.id),
68165 actionClose(way.id),
68166 actionAddMidpoint({ loc, edge }, node)
68168 context.enter(modeDrawArea(context, way.id, startGraph, mode.button));
68170 function startFromNode(node) {
68171 var startGraph = context.graph();
68172 var way = osmWay({ tags: defaultTags });
68174 actionAddEntity(way),
68175 actionAddVertex(way.id, node.id),
68176 actionClose(way.id)
68178 context.enter(modeDrawArea(context, way.id, startGraph, mode.button));
68180 mode.enter = function() {
68181 context.install(behavior);
68183 mode.exit = function() {
68184 context.uninstall(behavior);
68189 // modules/modes/add_line.js
68190 function modeAddLine(context, mode) {
68191 mode.id = "add-line";
68192 var behavior = behaviorAddWay(context).on("start", start2).on("startFromWay", startFromWay).on("startFromNode", startFromNode);
68193 var defaultTags = {};
68195 defaultTags = mode.preset.setTags(defaultTags, "line");
68196 function start2(loc) {
68197 var startGraph = context.graph();
68198 var node = osmNode({ loc });
68199 var way = osmWay({ tags: defaultTags });
68201 actionAddEntity(node),
68202 actionAddEntity(way),
68203 actionAddVertex(way.id, node.id)
68205 context.enter(modeDrawLine(context, way.id, startGraph, mode.button));
68207 function startFromWay(loc, edge) {
68208 var startGraph = context.graph();
68209 var node = osmNode({ loc });
68210 var way = osmWay({ tags: defaultTags });
68212 actionAddEntity(node),
68213 actionAddEntity(way),
68214 actionAddVertex(way.id, node.id),
68215 actionAddMidpoint({ loc, edge }, node)
68217 context.enter(modeDrawLine(context, way.id, startGraph, mode.button));
68219 function startFromNode(node) {
68220 var startGraph = context.graph();
68221 var way = osmWay({ tags: defaultTags });
68223 actionAddEntity(way),
68224 actionAddVertex(way.id, node.id)
68226 context.enter(modeDrawLine(context, way.id, startGraph, mode.button));
68228 mode.enter = function() {
68229 context.install(behavior);
68231 mode.exit = function() {
68232 context.uninstall(behavior);
68237 // modules/modes/add_point.js
68238 function modeAddPoint(context, mode) {
68239 mode.id = "add-point";
68240 var behavior = behaviorDraw(context).on("click", add).on("clickWay", addWay).on("clickNode", addNode).on("cancel", cancel).on("finish", cancel);
68241 var defaultTags = {};
68243 defaultTags = mode.preset.setTags(defaultTags, "point");
68244 function add(loc) {
68245 var node = osmNode({ loc, tags: defaultTags });
68247 actionAddEntity(node),
68248 _t("operations.add.annotation.point")
68250 enterSelectMode(node);
68252 function addWay(loc, edge) {
68253 var node = osmNode({ tags: defaultTags });
68255 actionAddMidpoint({ loc, edge }, node),
68256 _t("operations.add.annotation.vertex")
68258 enterSelectMode(node);
68260 function enterSelectMode(node) {
68262 modeSelect(context, [node.id]).newFeature(true)
68265 function addNode(node) {
68266 if (Object.keys(defaultTags).length === 0) {
68267 enterSelectMode(node);
68270 var tags = Object.assign({}, node.tags);
68271 for (var key in defaultTags) {
68272 tags[key] = defaultTags[key];
68275 actionChangeTags(node.id, tags),
68276 _t("operations.add.annotation.point")
68278 enterSelectMode(node);
68280 function cancel() {
68281 context.enter(modeBrowse(context));
68283 mode.enter = function() {
68284 context.install(behavior);
68286 mode.exit = function() {
68287 context.uninstall(behavior);
68292 // modules/modes/select_note.js
68293 function modeSelectNote(context, selectedNoteID) {
68298 var _keybinding = utilKeybinding("select-note");
68299 var _noteEditor = uiNoteEditor(context).on("change", function() {
68300 context.map().pan([0, 0]);
68301 var note = checkSelectedID();
68304 context.ui().sidebar.show(_noteEditor.note(note));
68307 behaviorBreathe(context),
68308 behaviorHover(context),
68309 behaviorSelect(context),
68310 behaviorLasso(context),
68311 modeDragNode(context).behavior,
68312 modeDragNote(context).behavior
68314 var _newFeature = false;
68315 function checkSelectedID() {
68318 var note = services.osm.getNote(selectedNoteID);
68320 context.enter(modeBrowse(context));
68324 function selectNote(d3_event, drawn) {
68325 if (!checkSelectedID())
68327 var selection2 = context.surface().selectAll(".layer-notes .note-" + selectedNoteID);
68328 if (selection2.empty()) {
68329 var source = d3_event && d3_event.type === "zoom" && d3_event.sourceEvent;
68330 if (drawn && source && (source.type === "pointermove" || source.type === "mousemove" || source.type === "touchmove")) {
68331 context.enter(modeBrowse(context));
68334 selection2.classed("selected", true);
68335 context.selectedNoteID(selectedNoteID);
68339 if (context.container().select(".combobox").size())
68341 context.enter(modeBrowse(context));
68343 mode.zoomToSelected = function() {
68346 var note = services.osm.getNote(selectedNoteID);
68348 context.map().centerZoomEase(note.loc, 20);
68351 mode.newFeature = function(val) {
68352 if (!arguments.length)
68353 return _newFeature;
68357 mode.enter = function() {
68358 var note = checkSelectedID();
68361 _behaviors.forEach(context.install);
68362 _keybinding.on(_t("inspector.zoom_to.key"), mode.zoomToSelected).on("\u238B", esc, true);
68363 select_default2(document).call(_keybinding);
68365 var sidebar = context.ui().sidebar;
68366 sidebar.show(_noteEditor.note(note).newNote(_newFeature));
68367 sidebar.expand(sidebar.intersects(note.extent()));
68368 context.map().on("drawn.select", selectNote);
68370 mode.exit = function() {
68371 _behaviors.forEach(context.uninstall);
68372 select_default2(document).call(_keybinding.unbind);
68373 context.surface().selectAll(".layer-notes .selected").classed("selected hover", false);
68374 context.map().on("drawn.select", null);
68375 context.ui().sidebar.hide();
68376 context.selectedNoteID(null);
68381 // modules/modes/add_note.js
68382 function modeAddNote(context) {
68386 description: _t.append("modes.add_note.description"),
68387 key: _t("modes.add_note.key")
68389 var behavior = behaviorDraw(context).on("click", add).on("cancel", cancel).on("finish", cancel);
68390 function add(loc) {
68391 var osm = services.osm;
68394 var note = osmNote({ loc, status: "open", comments: [] });
68395 osm.replaceNote(note);
68396 context.map().pan([0, 0]);
68397 context.selectedNoteID(note.id).enter(modeSelectNote(context, note.id).newFeature(true));
68399 function cancel() {
68400 context.enter(modeBrowse(context));
68402 mode.enter = function() {
68403 context.install(behavior);
68405 mode.exit = function() {
68406 context.uninstall(behavior);
68411 // modules/modes/save.js
68412 function modeSave(context) {
68413 var mode = { id: "save" };
68414 var keybinding = utilKeybinding("modeSave");
68415 var commit = uiCommit(context).on("cancel", cancel);
68419 var uploader = context.uploader().on("saveStarted.modeSave", function() {
68421 }).on("willAttemptUpload.modeSave", prepareForSuccess).on("progressChanged.modeSave", showProgress).on("resultNoChanges.modeSave", function() {
68423 }).on("resultErrors.modeSave", showErrors).on("resultConflicts.modeSave", showConflicts).on("resultSuccess.modeSave", showSuccess);
68424 function cancel() {
68425 context.enter(modeBrowse(context));
68427 function showProgress(num, total) {
68428 var modal = context.container().select(".loading-modal .modal-section");
68429 var progress = modal.selectAll(".progress").data([0]);
68430 progress.enter().append("div").attr("class", "progress").merge(progress).text(_t("save.conflict_progress", { num, total }));
68432 function showConflicts(changeset, conflicts, origChanges) {
68433 var selection2 = context.container().select(".sidebar").append("div").attr("class", "sidebar-component");
68434 context.container().selectAll(".main-content").classed("active", true).classed("inactive", false);
68435 _conflictsUi = uiConflicts(context).conflictList(conflicts).origChanges(origChanges).on("cancel", function() {
68436 context.container().selectAll(".main-content").classed("active", false).classed("inactive", true);
68437 selection2.remove();
68439 uploader.cancelConflictResolution();
68440 }).on("save", function() {
68441 context.container().selectAll(".main-content").classed("active", false).classed("inactive", true);
68442 selection2.remove();
68443 uploader.processResolvedConflicts(changeset);
68445 selection2.call(_conflictsUi);
68447 function showErrors(errors) {
68449 var selection2 = uiConfirm(context.container());
68450 selection2.select(".modal-section.header").append("h3").text(_t("save.error"));
68451 addErrors(selection2, errors);
68452 selection2.okButton();
68454 function addErrors(selection2, data) {
68455 var message = selection2.select(".modal-section.message-text");
68456 var items = message.selectAll(".error-container").data(data);
68457 var enter = items.enter().append("div").attr("class", "error-container");
68458 enter.append("a").attr("class", "error-description").attr("href", "#").classed("hide-toggle", true).text(function(d) {
68459 return d.msg || _t("save.unknown_error_details");
68460 }).on("click", function(d3_event) {
68461 d3_event.preventDefault();
68462 var error = select_default2(this);
68463 var detail = select_default2(this.nextElementSibling);
68464 var exp2 = error.classed("expanded");
68465 detail.style("display", exp2 ? "none" : "block");
68466 error.classed("expanded", !exp2);
68468 var details = enter.append("div").attr("class", "error-detail-container").style("display", "none");
68469 details.append("ul").attr("class", "error-detail-list").selectAll("li").data(function(d) {
68470 return d.details || [];
68471 }).enter().append("li").attr("class", "error-detail-item").text(function(d) {
68474 items.exit().remove();
68476 function showSuccess(changeset) {
68478 var ui = _success.changeset(changeset).location(_location).on("cancel", function() {
68479 context.ui().sidebar.hide();
68481 context.enter(modeBrowse(context).sidebar(ui));
68483 function keybindingOn() {
68484 select_default2(document).call(keybinding.on("\u238B", cancel, true));
68486 function keybindingOff() {
68487 select_default2(document).call(keybinding.unbind);
68489 function prepareForSuccess() {
68490 _success = uiSuccess(context);
68492 if (!services.geocoder)
68494 services.geocoder.reverse(context.map().center(), function(err, result) {
68495 if (err || !result || !result.address)
68497 var addr = result.address;
68498 var place = addr && (addr.town || addr.city || addr.county) || "";
68499 var region = addr && (addr.state || addr.country) || "";
68500 var separator = place && region ? _t("success.thank_you_where.separator") : "";
68502 "success.thank_you_where.format",
68503 { place, separator, region }
68507 mode.selectedIDs = function() {
68508 return _conflictsUi ? _conflictsUi.shownEntityIds() : [];
68510 mode.enter = function() {
68511 context.ui().sidebar.expand();
68513 context.ui().sidebar.show(commit);
68516 context.container().selectAll(".main-content").classed("active", false).classed("inactive", true);
68517 var osm = context.connection();
68522 if (osm.authenticated()) {
68525 osm.authenticate(function(err) {
68534 mode.exit = function() {
68536 context.container().selectAll(".main-content").classed("active", true).classed("inactive", false);
68537 context.ui().sidebar.hide();
68542 // modules/modes/select_error.js
68543 function modeSelectError(context, selectedErrorID, selectedErrorService) {
68545 id: "select-error",
68548 var keybinding = utilKeybinding("select-error");
68549 var errorService = services[selectedErrorService];
68551 switch (selectedErrorService) {
68553 errorEditor = uiImproveOsmEditor(context).on("change", function() {
68554 context.map().pan([0, 0]);
68555 var error = checkSelectedID();
68558 context.ui().sidebar.show(errorEditor.error(error));
68562 errorEditor = uiKeepRightEditor(context).on("change", function() {
68563 context.map().pan([0, 0]);
68564 var error = checkSelectedID();
68567 context.ui().sidebar.show(errorEditor.error(error));
68571 errorEditor = uiOsmoseEditor(context).on("change", function() {
68572 context.map().pan([0, 0]);
68573 var error = checkSelectedID();
68576 context.ui().sidebar.show(errorEditor.error(error));
68581 behaviorBreathe(context),
68582 behaviorHover(context),
68583 behaviorSelect(context),
68584 behaviorLasso(context),
68585 modeDragNode(context).behavior,
68586 modeDragNote(context).behavior
68588 function checkSelectedID() {
68591 var error = errorService.getError(selectedErrorID);
68593 context.enter(modeBrowse(context));
68597 mode.zoomToSelected = function() {
68600 var error = errorService.getError(selectedErrorID);
68602 context.map().centerZoomEase(error.loc, 20);
68605 mode.enter = function() {
68606 var error = checkSelectedID();
68609 behaviors.forEach(context.install);
68610 keybinding.on(_t("inspector.zoom_to.key"), mode.zoomToSelected).on("\u238B", esc, true);
68611 select_default2(document).call(keybinding);
68613 var sidebar = context.ui().sidebar;
68614 sidebar.show(errorEditor.error(error));
68615 context.map().on("drawn.select-error", selectError);
68616 function selectError(d3_event, drawn) {
68617 if (!checkSelectedID())
68619 var selection2 = context.surface().selectAll(".itemId-" + selectedErrorID + "." + selectedErrorService);
68620 if (selection2.empty()) {
68621 var source = d3_event && d3_event.type === "zoom" && d3_event.sourceEvent;
68622 if (drawn && source && (source.type === "pointermove" || source.type === "mousemove" || source.type === "touchmove")) {
68623 context.enter(modeBrowse(context));
68626 selection2.classed("selected", true);
68627 context.selectedErrorID(selectedErrorID);
68631 if (context.container().select(".combobox").size())
68633 context.enter(modeBrowse(context));
68636 mode.exit = function() {
68637 behaviors.forEach(context.uninstall);
68638 select_default2(document).call(keybinding.unbind);
68639 context.surface().selectAll(".qaItem.selected").classed("selected hover", false);
68640 context.map().on("drawn.select-error", null);
68641 context.ui().sidebar.hide();
68642 context.selectedErrorID(null);
68643 context.features().forceVisible([]);
68648 // modules/ui/tools/modes.js
68649 function uiToolDrawModes(context) {
68652 label: _t.append("toolbar.add_feature")
68655 modeAddPoint(context, {
68656 title: _t.append("modes.add_point.title"),
68658 description: _t.append("modes.add_point.description"),
68659 preset: _mainPresetIndex.item("point"),
68662 modeAddLine(context, {
68663 title: _t.append("modes.add_line.title"),
68665 description: _t.append("modes.add_line.description"),
68666 preset: _mainPresetIndex.item("line"),
68669 modeAddArea(context, {
68670 title: _t.append("modes.add_area.title"),
68672 description: _t.append("modes.add_area.description"),
68673 preset: _mainPresetIndex.item("area"),
68677 function enabled(_mode) {
68678 return osmEditable();
68680 function osmEditable() {
68681 return context.editable();
68683 modes.forEach(function(mode) {
68684 context.keybinding().on(mode.key, function() {
68685 if (!enabled(mode))
68687 if (mode.id === context.mode().id) {
68688 context.enter(modeBrowse(context));
68690 context.enter(mode);
68694 tool.render = function(selection2) {
68695 var wrap2 = selection2.append("div").attr("class", "joined").style("display", "flex");
68696 var debouncedUpdate = debounce_default(update, 500, { leading: true, trailing: true });
68697 context.map().on("move.modes", debouncedUpdate).on("drawn.modes", debouncedUpdate);
68698 context.on("enter.modes", update);
68700 function update() {
68701 var buttons = wrap2.selectAll("button.add-button").data(modes, function(d) {
68704 buttons.exit().remove();
68705 var buttonsEnter = buttons.enter().append("button").attr("class", function(d) {
68706 return d.id + " add-button bar-button";
68707 }).on("click.mode-buttons", function(d3_event, d) {
68710 var currMode = context.mode().id;
68711 if (/^draw/.test(currMode))
68713 if (d.id === currMode) {
68714 context.enter(modeBrowse(context));
68719 uiTooltip().placement("bottom").title(function(d) {
68720 return d.description;
68721 }).keys(function(d) {
68723 }).scrollContainer(context.container().select(".top-toolbar"))
68725 buttonsEnter.each(function(d) {
68726 select_default2(this).call(svgIcon("#iD-icon-" + d.button));
68728 buttonsEnter.append("span").attr("class", "label").text("").each(function(mode) {
68729 mode.title(select_default2(this));
68731 if (buttons.enter().size() || buttons.exit().size()) {
68732 context.ui().checkOverflow(".top-toolbar", true);
68734 buttons = buttons.merge(buttonsEnter).attr("aria-disabled", function(d) {
68735 return !enabled(d);
68736 }).classed("disabled", function(d) {
68737 return !enabled(d);
68738 }).attr("aria-pressed", function(d) {
68739 return context.mode() && context.mode().button === d.button;
68740 }).classed("active", function(d) {
68741 return context.mode() && context.mode().button === d.button;
68748 // modules/ui/tools/notes.js
68749 function uiToolNotes(context) {
68752 label: _t.append("modes.add_note.label")
68754 var mode = modeAddNote(context);
68755 function enabled() {
68756 return notesEnabled() && notesEditable();
68758 function notesEnabled() {
68759 var noteLayer = context.layers().layer("notes");
68760 return noteLayer && noteLayer.enabled();
68762 function notesEditable() {
68763 var mode2 = context.mode();
68764 return context.map().notesEditable() && mode2 && mode2.id !== "save";
68766 context.keybinding().on(mode.key, function() {
68769 if (mode.id === context.mode().id) {
68770 context.enter(modeBrowse(context));
68772 context.enter(mode);
68775 tool.render = function(selection2) {
68776 var debouncedUpdate = debounce_default(update, 500, { leading: true, trailing: true });
68777 context.map().on("move.notes", debouncedUpdate).on("drawn.notes", debouncedUpdate);
68778 context.on("enter.notes", update);
68780 function update() {
68781 var showNotes = notesEnabled();
68782 var data = showNotes ? [mode] : [];
68783 var buttons = selection2.selectAll("button.add-button").data(data, function(d) {
68786 buttons.exit().remove();
68787 var buttonsEnter = buttons.enter().append("button").attr("class", function(d) {
68788 return d.id + " add-button bar-button";
68789 }).on("click.notes", function(d3_event, d) {
68792 var currMode = context.mode().id;
68793 if (/^draw/.test(currMode))
68795 if (d.id === currMode) {
68796 context.enter(modeBrowse(context));
68801 uiTooltip().placement("bottom").title(function(d) {
68802 return d.description;
68803 }).keys(function(d) {
68805 }).scrollContainer(context.container().select(".top-toolbar"))
68807 buttonsEnter.each(function(d) {
68808 select_default2(this).call(svgIcon(d.icon || "#iD-icon-" + d.button));
68810 if (buttons.enter().size() || buttons.exit().size()) {
68811 context.ui().checkOverflow(".top-toolbar", true);
68813 buttons = buttons.merge(buttonsEnter).classed("disabled", function() {
68815 }).attr("aria-disabled", function() {
68817 }).classed("active", function(d) {
68818 return context.mode() && context.mode().button === d.button;
68819 }).attr("aria-pressed", function(d) {
68820 return context.mode() && context.mode().button === d.button;
68824 tool.uninstall = function() {
68825 context.on("enter.editor.notes", null).on("exit.editor.notes", null).on("enter.notes", null);
68826 context.map().on("move.notes", null).on("drawn.notes", null);
68831 // modules/ui/tools/save.js
68832 function uiToolSave(context) {
68835 label: _t.append("save.title")
68838 var tooltipBehavior = null;
68839 var history = context.history();
68840 var key = uiCmd("\u2318S");
68841 var _numChanges = 0;
68842 function isSaving() {
68843 var mode = context.mode();
68844 return mode && mode.id === "save";
68846 function isDisabled() {
68847 return _numChanges === 0 || isSaving();
68849 function save(d3_event) {
68850 d3_event.preventDefault();
68851 if (!context.inIntro() && !isSaving() && history.hasChanges()) {
68852 context.enter(modeSave(context));
68855 function bgColor(numChanges) {
68857 if (numChanges === 0) {
68859 } else if (numChanges <= 50) {
68860 step = numChanges / 50;
68861 return rgb_default("#fff", "#ff8")(step);
68863 step = Math.min((numChanges - 50) / 50, 1);
68864 return rgb_default("#ff8", "#f88")(step);
68867 function updateCount() {
68868 var val = history.difference().summary().length;
68869 if (val === _numChanges)
68872 if (tooltipBehavior) {
68873 tooltipBehavior.title(() => _t.append(_numChanges > 0 ? "save.help" : "save.no_changes")).keys([key]);
68876 button.classed("disabled", isDisabled()).style("background", bgColor(_numChanges));
68877 button.select("span.count").text(_numChanges);
68880 tool.render = function(selection2) {
68881 tooltipBehavior = uiTooltip().placement("bottom").title(() => _t.append("save.no_changes")).keys([key]).scrollContainer(context.container().select(".top-toolbar"));
68882 var lastPointerUpType;
68883 button = selection2.append("button").attr("class", "save disabled bar-button").on("pointerup", function(d3_event) {
68884 lastPointerUpType = d3_event.pointerType;
68885 }).on("click", function(d3_event) {
68887 if (_numChanges === 0 && (lastPointerUpType === "touch" || lastPointerUpType === "pen")) {
68888 context.ui().flash.duration(2e3).iconName("#iD-icon-save").iconClass("disabled").label(_t.append("save.no_changes"))();
68890 lastPointerUpType = null;
68891 }).call(tooltipBehavior);
68892 button.call(svgIcon("#iD-icon-save"));
68893 button.append("span").attr("class", "count").attr("aria-hidden", "true").text("0");
68895 context.keybinding().on(key, save, true);
68896 context.history().on("change.save", updateCount);
68897 context.on("enter.save", function() {
68899 button.classed("disabled", isDisabled());
68901 button.call(tooltipBehavior.hide);
68906 tool.uninstall = function() {
68907 context.keybinding().off(key, true);
68908 context.history().on("change.save", null);
68909 context.on("enter.save", null);
68911 tooltipBehavior = null;
68916 // modules/ui/tools/sidebar_toggle.js
68917 function uiToolSidebarToggle(context) {
68919 id: "sidebar_toggle",
68920 label: _t.append("toolbar.inspect")
68922 tool.render = function(selection2) {
68923 selection2.append("button").attr("class", "bar-button").attr("aria-label", _t("sidebar.tooltip")).on("click", function() {
68924 context.ui().sidebar.toggle();
68926 uiTooltip().placement("bottom").title(() => _t.append("sidebar.tooltip")).keys([_t("sidebar.key")]).scrollContainer(context.container().select(".top-toolbar"))
68927 ).call(svgIcon("#iD-icon-sidebar-" + (_mainLocalizer.textDirection() === "rtl" ? "right" : "left")));
68932 // modules/ui/tools/undo_redo.js
68933 function uiToolUndoRedo(context) {
68936 label: _t.append("toolbar.undo_redo")
68940 cmd: uiCmd("\u2318Z"),
68941 action: function() {
68944 annotation: function() {
68945 return context.history().undoAnnotation();
68947 icon: "iD-icon-" + (_mainLocalizer.textDirection() === "rtl" ? "redo" : "undo")
68950 cmd: uiCmd("\u2318\u21E7Z"),
68951 action: function() {
68954 annotation: function() {
68955 return context.history().redoAnnotation();
68957 icon: "iD-icon-" + (_mainLocalizer.textDirection() === "rtl" ? "undo" : "redo")
68959 function editable() {
68960 return context.mode() && context.mode().id !== "save" && context.map().editableDataEnabled(
68962 /* ignore min zoom */
68965 tool.render = function(selection2) {
68966 var tooltipBehavior = uiTooltip().placement("bottom").title(function(d) {
68967 return d.annotation() ? _t.append(d.id + ".tooltip", { action: d.annotation() }) : _t.append(d.id + ".nothing");
68968 }).keys(function(d) {
68970 }).scrollContainer(context.container().select(".top-toolbar"));
68971 var lastPointerUpType;
68972 var buttons = selection2.selectAll("button").data(commands).enter().append("button").attr("class", function(d) {
68973 return "disabled " + d.id + "-button bar-button";
68974 }).on("pointerup", function(d3_event) {
68975 lastPointerUpType = d3_event.pointerType;
68976 }).on("click", function(d3_event, d) {
68977 d3_event.preventDefault();
68978 var annotation = d.annotation();
68979 if (editable() && annotation) {
68982 if (editable() && (lastPointerUpType === "touch" || lastPointerUpType === "pen")) {
68983 var label = annotation ? _t.append(d.id + ".tooltip", { action: annotation }) : _t.append(d.id + ".nothing");
68984 context.ui().flash.duration(2e3).iconName("#" + d.icon).iconClass(annotation ? "" : "disabled").label(label)();
68986 lastPointerUpType = null;
68987 }).call(tooltipBehavior);
68988 buttons.each(function(d) {
68989 select_default2(this).call(svgIcon("#" + d.icon));
68991 context.keybinding().on(commands[0].cmd, function(d3_event) {
68992 d3_event.preventDefault();
68994 commands[0].action();
68995 }).on(commands[1].cmd, function(d3_event) {
68996 d3_event.preventDefault();
68998 commands[1].action();
69000 var debouncedUpdate = debounce_default(update, 500, { leading: true, trailing: true });
69001 context.map().on("move.undo_redo", debouncedUpdate).on("drawn.undo_redo", debouncedUpdate);
69002 context.history().on("change.undo_redo", function(difference) {
69006 context.on("enter.undo_redo", update);
69007 function update() {
69008 buttons.classed("disabled", function(d) {
69009 return !editable() || !d.annotation();
69010 }).each(function() {
69011 var selection3 = select_default2(this);
69012 if (!selection3.select(".tooltip.in").empty()) {
69013 selection3.call(tooltipBehavior.updateContent);
69018 tool.uninstall = function() {
69019 context.keybinding().off(commands[0].cmd).off(commands[1].cmd);
69020 context.map().on("move.undo_redo", null).on("drawn.undo_redo", null);
69021 context.history().on("change.undo_redo", null);
69022 context.on("enter.undo_redo", null);
69027 // modules/ui/top_toolbar.js
69028 function uiTopToolbar(context) {
69029 var sidebarToggle = uiToolSidebarToggle(context), modes = uiToolDrawModes(context), notes = uiToolNotes(context), undoRedo = uiToolUndoRedo(context), save = uiToolSave(context);
69030 function notesEnabled() {
69031 var noteLayer = context.layers().layer("notes");
69032 return noteLayer && noteLayer.enabled();
69034 function topToolbar(bar) {
69035 bar.on("wheel.topToolbar", function(d3_event) {
69036 if (!d3_event.deltaX) {
69037 bar.node().scrollLeft += d3_event.deltaY;
69040 var debouncedUpdate = debounce_default(update, 500, { leading: true, trailing: true });
69041 context.layers().on("change.topToolbar", debouncedUpdate);
69043 function update() {
69049 tools.push("spacer");
69050 if (notesEnabled()) {
69051 tools = tools.concat([notes, "spacer"]);
69053 tools = tools.concat([undoRedo, save]);
69054 var toolbarItems = bar.selectAll(".toolbar-item").data(tools, function(d) {
69057 toolbarItems.exit().each(function(d) {
69062 var itemsEnter = toolbarItems.enter().append("div").attr("class", function(d) {
69063 var classes = "toolbar-item " + (d.id || d).replace("_", "-");
69065 classes += " " + d.klass;
69068 var actionableItems = itemsEnter.filter(function(d) {
69069 return d !== "spacer";
69071 actionableItems.append("div").attr("class", "item-content").each(function(d) {
69072 select_default2(this).call(d.render, bar);
69074 actionableItems.append("div").attr("class", "item-label").each(function(d) {
69075 d.label(select_default2(this));
69082 // modules/ui/zoom_to_selection.js
69083 function uiZoomToSelection(context) {
69084 function isDisabled() {
69085 var mode = context.mode();
69086 return !mode || !mode.zoomToSelected;
69088 var _lastPointerUpType;
69089 function pointerup(d3_event) {
69090 _lastPointerUpType = d3_event.pointerType;
69092 function click(d3_event) {
69093 d3_event.preventDefault();
69094 if (isDisabled()) {
69095 if (_lastPointerUpType === "touch" || _lastPointerUpType === "pen") {
69096 context.ui().flash.duration(2e3).iconName("#iD-icon-framed-dot").iconClass("disabled").label(_t.append("inspector.zoom_to.no_selection"))();
69099 var mode = context.mode();
69100 if (mode && mode.zoomToSelected) {
69101 mode.zoomToSelected();
69104 _lastPointerUpType = null;
69106 return function(selection2) {
69107 var tooltipBehavior = uiTooltip().placement(_mainLocalizer.textDirection() === "rtl" ? "right" : "left").title(function() {
69108 if (isDisabled()) {
69109 return _t.append("inspector.zoom_to.no_selection");
69111 return _t.append("inspector.zoom_to.title");
69112 }).keys([_t("inspector.zoom_to.key")]);
69113 var button = selection2.append("button").on("pointerup", pointerup).on("click", click).call(svgIcon("#iD-icon-framed-dot", "light")).call(tooltipBehavior);
69114 function setEnabledState() {
69115 button.classed("disabled", isDisabled());
69116 if (!button.select(".tooltip.in").empty()) {
69117 button.call(tooltipBehavior.updateContent);
69120 context.on("enter.uiZoomToSelection", setEnabledState);
69125 // modules/ui/pane.js
69126 function uiPane(id2, context) {
69129 var _description = "";
69130 var _iconName = "";
69132 var _paneSelection = select_default2(null);
69137 pane.label = function(val) {
69138 if (!arguments.length)
69143 pane.key = function(val) {
69144 if (!arguments.length)
69149 pane.description = function(val) {
69150 if (!arguments.length)
69151 return _description;
69152 _description = val;
69155 pane.iconName = function(val) {
69156 if (!arguments.length)
69161 pane.sections = function(val) {
69162 if (!arguments.length)
69167 pane.selection = function() {
69168 return _paneSelection;
69170 function hidePane() {
69171 context.ui().togglePanes();
69173 pane.togglePane = function(d3_event) {
69175 d3_event.preventDefault();
69176 _paneTooltip.hide();
69177 context.ui().togglePanes(!_paneSelection.classed("shown") ? _paneSelection : void 0);
69179 pane.renderToggleButton = function(selection2) {
69180 if (!_paneTooltip) {
69181 _paneTooltip = uiTooltip().placement(_mainLocalizer.textDirection() === "rtl" ? "right" : "left").title(() => _description).keys([_key]);
69183 selection2.append("button").on("click", pane.togglePane).call(svgIcon("#" + _iconName, "light")).call(_paneTooltip);
69185 pane.renderContent = function(selection2) {
69187 _sections.forEach(function(section) {
69188 selection2.call(section.render);
69192 pane.renderPane = function(selection2) {
69193 _paneSelection = selection2.append("div").attr("class", "fillL map-pane hide " + id2 + "-pane").attr("pane", id2);
69194 var heading = _paneSelection.append("div").attr("class", "pane-heading");
69195 heading.append("h2").text("").call(_label);
69196 heading.append("button").attr("title", _t("icons.close")).on("click", hidePane).call(svgIcon("#iD-icon-close"));
69197 _paneSelection.append("div").attr("class", "pane-content").call(pane.renderContent);
69199 context.keybinding().on(_key, pane.togglePane);
69205 // modules/ui/sections/background_display_options.js
69206 function uiSectionBackgroundDisplayOptions(context) {
69207 var section = uiSection("background-display-options", context).label(() => _t.append("background.display_options")).disclosureContent(renderDisclosureContent);
69208 var _storedOpacity = corePreferences("background-opacity");
69211 var _sliders = ["brightness", "contrast", "saturation", "sharpness"];
69213 brightness: _storedOpacity !== null ? +_storedOpacity : 1,
69218 function clamp3(x, min3, max3) {
69219 return Math.max(min3, Math.min(x, max3));
69221 function updateValue(d, val) {
69222 val = clamp3(val, _minVal, _maxVal);
69224 context.background()[d](val);
69225 if (d === "brightness") {
69226 corePreferences("background-opacity", val);
69228 section.reRender();
69230 function renderDisclosureContent(selection2) {
69231 var container = selection2.selectAll(".display-options-container").data([0]);
69232 var containerEnter = container.enter().append("div").attr("class", "display-options-container controls-list");
69233 var slidersEnter = containerEnter.selectAll(".display-control").data(_sliders).enter().append("label").attr("class", function(d) {
69234 return "display-control display-control-" + d;
69236 slidersEnter.html(function(d) {
69237 return _t.html("background." + d);
69238 }).append("span").attr("class", function(d) {
69239 return "display-option-value display-option-value-" + d;
69241 var sildersControlEnter = slidersEnter.append("div").attr("class", "control-wrap");
69242 sildersControlEnter.append("input").attr("class", function(d) {
69243 return "display-option-input display-option-input-" + d;
69244 }).attr("type", "range").attr("min", _minVal).attr("max", _maxVal).attr("step", "0.05").on("input", function(d3_event, d) {
69245 var val = select_default2(this).property("value");
69246 if (!val && d3_event && d3_event.target) {
69247 val = d3_event.target.value;
69249 updateValue(d, val);
69251 sildersControlEnter.append("button").attr("title", function(d) {
69252 return `${_t("background.reset")} ${_t("background." + d)}`;
69253 }).attr("class", function(d) {
69254 return "display-option-reset display-option-reset-" + d;
69255 }).on("click", function(d3_event, d) {
69256 if (d3_event.button !== 0)
69259 }).call(svgIcon("#iD-icon-" + (_mainLocalizer.textDirection() === "rtl" ? "redo" : "undo")));
69260 containerEnter.append("a").attr("class", "display-option-resetlink").attr("role", "button").attr("href", "#").call(_t.append("background.reset_all")).on("click", function(d3_event) {
69261 d3_event.preventDefault();
69262 for (var i2 = 0; i2 < _sliders.length; i2++) {
69263 updateValue(_sliders[i2], 1);
69266 container = containerEnter.merge(container);
69267 container.selectAll(".display-option-input").property("value", function(d) {
69268 return _options[d];
69270 container.selectAll(".display-option-value").text(function(d) {
69271 return Math.floor(_options[d] * 100) + "%";
69273 container.selectAll(".display-option-reset").classed("disabled", function(d) {
69274 return _options[d] === 1;
69276 if (containerEnter.size() && _options.brightness !== 1) {
69277 context.background().brightness(_options.brightness);
69283 // modules/ui/settings/custom_background.js
69284 function uiSettingsCustomBackground() {
69285 var dispatch10 = dispatch_default("change");
69286 function render(selection2) {
69287 var _origSettings = {
69288 template: corePreferences("background-custom-template")
69290 var _currSettings = {
69291 template: corePreferences("background-custom-template")
69293 var example = "https://{switch:a,b,c}.tile.openstreetmap.org/{zoom}/{x}/{y}.png";
69294 var modal = uiConfirm(selection2).okButton();
69295 modal.classed("settings-modal settings-custom-background", true);
69296 modal.select(".modal-section.header").append("h3").call(_t.append("settings.custom_background.header"));
69297 var textSection = modal.select(".modal-section.message-text");
69298 var instructions = `${_t.html("settings.custom_background.instructions.info")}
69300 #### ${_t.html("settings.custom_background.instructions.wms.tokens_label")}
69301 * ${_t.html("settings.custom_background.instructions.wms.tokens.proj")}
69302 * ${_t.html("settings.custom_background.instructions.wms.tokens.wkid")}
69303 * ${_t.html("settings.custom_background.instructions.wms.tokens.dimensions")}
69304 * ${_t.html("settings.custom_background.instructions.wms.tokens.bbox")}
69306 #### ${_t.html("settings.custom_background.instructions.tms.tokens_label")}
69307 * ${_t.html("settings.custom_background.instructions.tms.tokens.xyz")}
69308 * ${_t.html("settings.custom_background.instructions.tms.tokens.flipped_y")}
69309 * ${_t.html("settings.custom_background.instructions.tms.tokens.switch")}
69310 * ${_t.html("settings.custom_background.instructions.tms.tokens.quadtile")}
69311 * ${_t.html("settings.custom_background.instructions.tms.tokens.scale_factor")}
69313 #### ${_t.html("settings.custom_background.instructions.example")}
69315 textSection.append("div").attr("class", "instructions-template").html(marked(instructions));
69316 textSection.append("textarea").attr("class", "field-template").attr("placeholder", _t("settings.custom_background.template.placeholder")).call(utilNoAuto).property("value", _currSettings.template);
69317 var buttonSection = modal.select(".modal-section.buttons");
69318 buttonSection.insert("button", ".ok-button").attr("class", "button cancel-button secondary-action").call(_t.append("confirm.cancel"));
69319 buttonSection.select(".cancel-button").on("click.cancel", clickCancel);
69320 buttonSection.select(".ok-button").attr("disabled", isSaveDisabled).on("click.save", clickSave);
69321 function isSaveDisabled() {
69324 function clickCancel() {
69325 textSection.select(".field-template").property("value", _origSettings.template);
69326 corePreferences("background-custom-template", _origSettings.template);
69330 function clickSave() {
69331 _currSettings.template = textSection.select(".field-template").property("value");
69332 corePreferences("background-custom-template", _currSettings.template);
69335 dispatch10.call("change", this, _currSettings);
69338 return utilRebind(render, dispatch10, "on");
69341 // modules/ui/sections/background_list.js
69342 function uiSectionBackgroundList(context) {
69343 var _backgroundList = select_default2(null);
69344 var _customSource = context.background().findSource("custom");
69345 var _settingsCustomBackground = uiSettingsCustomBackground(context).on("change", customChanged);
69346 var section = uiSection("background-list", context).label(() => _t.append("background.backgrounds")).disclosureContent(renderDisclosureContent);
69347 function previousBackgroundID() {
69348 return corePreferences("background-last-used-toggle");
69350 function renderDisclosureContent(selection2) {
69351 var container = selection2.selectAll(".layer-background-list").data([0]);
69352 _backgroundList = container.enter().append("ul").attr("class", "layer-list layer-background-list").attr("dir", "auto").merge(container);
69353 var bgExtrasListEnter = selection2.selectAll(".bg-extras-list").data([0]).enter().append("ul").attr("class", "layer-list bg-extras-list");
69354 var minimapLabelEnter = bgExtrasListEnter.append("li").attr("class", "minimap-toggle-item").append("label").call(
69355 uiTooltip().title(() => _t.append("background.minimap.tooltip")).keys([_t("background.minimap.key")]).placement("top")
69357 minimapLabelEnter.append("input").attr("type", "checkbox").on("change", function(d3_event) {
69358 d3_event.preventDefault();
69359 uiMapInMap.toggle();
69361 minimapLabelEnter.append("span").call(_t.append("background.minimap.description"));
69362 var panelLabelEnter = bgExtrasListEnter.append("li").attr("class", "background-panel-toggle-item").append("label").call(
69363 uiTooltip().title(() => _t.append("background.panel.tooltip")).keys([uiCmd("\u2318\u21E7" + _t("info_panels.background.key"))]).placement("top")
69365 panelLabelEnter.append("input").attr("type", "checkbox").on("change", function(d3_event) {
69366 d3_event.preventDefault();
69367 context.ui().info.toggle("background");
69369 panelLabelEnter.append("span").call(_t.append("background.panel.description"));
69370 var locPanelLabelEnter = bgExtrasListEnter.append("li").attr("class", "location-panel-toggle-item").append("label").call(
69371 uiTooltip().title(() => _t.append("background.location_panel.tooltip")).keys([uiCmd("\u2318\u21E7" + _t("info_panels.location.key"))]).placement("top")
69373 locPanelLabelEnter.append("input").attr("type", "checkbox").on("change", function(d3_event) {
69374 d3_event.preventDefault();
69375 context.ui().info.toggle("location");
69377 locPanelLabelEnter.append("span").call(_t.append("background.location_panel.description"));
69378 selection2.selectAll(".imagery-faq").data([0]).enter().append("div").attr("class", "imagery-faq").append("a").attr("target", "_blank").call(svgIcon("#iD-icon-out-link", "inline")).attr("href", "https://github.com/openstreetmap/iD/blob/develop/FAQ.md#how-can-i-report-an-issue-with-background-imagery").append("span").call(_t.append("background.imagery_problem_faq"));
69379 _backgroundList.call(drawListItems, "radio", function(d3_event, d) {
69380 chooseBackground(d);
69382 return !d.isHidden() && !d.overlay;
69385 function setTooltips(selection2) {
69386 selection2.each(function(d, i2, nodes) {
69387 var item = select_default2(this).select("label");
69388 var span = item.select("span");
69389 var placement = i2 < nodes.length / 2 ? "bottom" : "top";
69390 var hasDescription = d.hasDescription();
69391 var isOverflowing = span.property("clientWidth") !== span.property("scrollWidth");
69392 item.call(uiTooltip().destroyAny);
69393 if (d.id === previousBackgroundID()) {
69395 uiTooltip().placement(placement).title(() => _t.append("background.switch")).keys([uiCmd("\u2318" + _t("background.key"))])
69397 } else if (hasDescription || isOverflowing) {
69399 uiTooltip().placement(placement).title(() => hasDescription ? d.description() : d.label())
69404 function drawListItems(layerList, type2, change, filter2) {
69405 var sources = context.background().sources(context.map().extent(), context.map().zoom(), true).filter(filter2).sort(function(a, b) {
69406 return a.best() && !b.best() ? -1 : b.best() && !a.best() ? 1 : descending(a.area(), b.area()) || ascending(a.name(), b.name()) || 0;
69408 var layerLinks = layerList.selectAll("li").data(sources, function(d, i2) {
69409 return d.id + "---" + i2;
69411 layerLinks.exit().remove();
69412 var enter = layerLinks.enter().append("li").classed("layer-custom", function(d) {
69413 return d.id === "custom";
69414 }).classed("best", function(d) {
69417 var label = enter.append("label");
69418 label.append("input").attr("type", type2).attr("name", "background-layer").attr("value", function(d) {
69420 }).on("change", change);
69421 label.append("span").each(function(d) {
69422 d.label()(select_default2(this));
69424 enter.filter(function(d) {
69425 return d.id === "custom";
69426 }).append("button").attr("class", "layer-browse").call(
69427 uiTooltip().title(() => _t.append("settings.custom_background.tooltip")).placement(_mainLocalizer.textDirection() === "rtl" ? "right" : "left")
69428 ).on("click", function(d3_event) {
69429 d3_event.preventDefault();
69431 }).call(svgIcon("#iD-icon-more"));
69432 enter.filter(function(d) {
69434 }).append("div").attr("class", "best").call(
69435 uiTooltip().title(() => _t.append("background.best_imagery")).placement(_mainLocalizer.textDirection() === "rtl" ? "right" : "left")
69436 ).append("span").text("\u2605");
69437 layerList.call(updateLayerSelections);
69439 function updateLayerSelections(selection2) {
69440 function active(d) {
69441 return context.background().showsLayer(d);
69443 selection2.selectAll("li").classed("active", active).classed("switch", function(d) {
69444 return d.id === previousBackgroundID();
69445 }).call(setTooltips).selectAll("input").property("checked", active);
69447 function chooseBackground(d) {
69448 if (d.id === "custom" && !d.template()) {
69449 return editCustom();
69451 var previousBackground = context.background().baseLayerSource();
69452 corePreferences("background-last-used-toggle", previousBackground.id);
69453 corePreferences("background-last-used", d.id);
69454 context.background().baseLayerSource(d);
69456 function customChanged(d) {
69457 if (d && d.template) {
69458 _customSource.template(d.template);
69459 chooseBackground(_customSource);
69461 _customSource.template("");
69462 chooseBackground(context.background().findSource("none"));
69465 function editCustom() {
69466 context.container().call(_settingsCustomBackground);
69468 context.background().on("change.background_list", function() {
69469 _backgroundList.call(updateLayerSelections);
69472 "move.background_list",
69473 debounce_default(function() {
69474 window.requestIdleCallback(section.reRender);
69480 // modules/ui/sections/background_offset.js
69481 function uiSectionBackgroundOffset(context) {
69482 var section = uiSection("background-offset", context).label(() => _t.append("background.fix_misalignment")).disclosureContent(renderDisclosureContent).expandedByDefault(false);
69483 var _pointerPrefix = "PointerEvent" in window ? "pointer" : "mouse";
69484 var _directions = [
69485 ["top", [0, -0.5]],
69486 ["left", [-0.5, 0]],
69487 ["right", [0.5, 0]],
69488 ["bottom", [0, 0.5]]
69490 function updateValue() {
69491 var meters = geoOffsetToMeters(context.background().offset());
69492 var x = +meters[0].toFixed(2);
69493 var y = +meters[1].toFixed(2);
69494 context.container().selectAll(".nudge-inner-rect").select("input").classed("error", false).property("value", x + ", " + y);
69495 context.container().selectAll(".nudge-reset").classed("disabled", function() {
69496 return x === 0 && y === 0;
69499 function resetOffset() {
69500 context.background().offset([0, 0]);
69503 function nudge(d) {
69504 context.background().nudge(d, context.map().zoom());
69507 function inputOffset() {
69508 var input = select_default2(this);
69509 var d = input.node().value;
69511 return resetOffset();
69512 d = d.replace(/;/g, ",").split(",").map(function(n2) {
69513 return !isNaN(n2) && n2;
69515 if (d.length !== 2 || !d[0] || !d[1]) {
69516 input.classed("error", true);
69519 context.background().offset(geoMetersToOffset(d));
69522 function dragOffset(d3_event) {
69523 if (d3_event.button !== 0)
69525 var origin = [d3_event.clientX, d3_event.clientY];
69526 var pointerId = d3_event.pointerId || "mouse";
69527 context.container().append("div").attr("class", "nudge-surface");
69528 select_default2(window).on(_pointerPrefix + "move.drag-bg-offset", pointermove).on(_pointerPrefix + "up.drag-bg-offset", pointerup);
69529 if (_pointerPrefix === "pointer") {
69530 select_default2(window).on("pointercancel.drag-bg-offset", pointerup);
69532 function pointermove(d3_event2) {
69533 if (pointerId !== (d3_event2.pointerId || "mouse"))
69535 var latest = [d3_event2.clientX, d3_event2.clientY];
69537 -(origin[0] - latest[0]) / 4,
69538 -(origin[1] - latest[1]) / 4
69543 function pointerup(d3_event2) {
69544 if (pointerId !== (d3_event2.pointerId || "mouse"))
69546 if (d3_event2.button !== 0)
69548 context.container().selectAll(".nudge-surface").remove();
69549 select_default2(window).on(".drag-bg-offset", null);
69552 function renderDisclosureContent(selection2) {
69553 var container = selection2.selectAll(".nudge-container").data([0]);
69554 var containerEnter = container.enter().append("div").attr("class", "nudge-container");
69555 containerEnter.append("div").attr("class", "nudge-instructions").call(_t.append("background.offset"));
69556 var nudgeWrapEnter = containerEnter.append("div").attr("class", "nudge-controls-wrap");
69557 var nudgeEnter = nudgeWrapEnter.append("div").attr("class", "nudge-outer-rect").on(_pointerPrefix + "down", dragOffset);
69558 nudgeEnter.append("div").attr("class", "nudge-inner-rect").append("input").attr("type", "text").attr("aria-label", _t("background.offset_label")).on("change", inputOffset);
69559 nudgeWrapEnter.append("div").selectAll("button").data(_directions).enter().append("button").attr("title", function(d) {
69560 return _t(`background.nudge.${d[0]}`);
69561 }).attr("class", function(d) {
69562 return d[0] + " nudge";
69563 }).on("click", function(d3_event, d) {
69566 nudgeWrapEnter.append("button").attr("title", _t("background.reset")).attr("class", "nudge-reset disabled").on("click", function(d3_event) {
69567 d3_event.preventDefault();
69569 }).call(svgIcon("#iD-icon-" + (_mainLocalizer.textDirection() === "rtl" ? "redo" : "undo")));
69572 context.background().on("change.backgroundOffset-update", updateValue);
69576 // modules/ui/sections/overlay_list.js
69577 function uiSectionOverlayList(context) {
69578 var section = uiSection("overlay-list", context).label(() => _t.append("background.overlays")).disclosureContent(renderDisclosureContent);
69579 var _overlayList = select_default2(null);
69580 function setTooltips(selection2) {
69581 selection2.each(function(d, i2, nodes) {
69582 var item = select_default2(this).select("label");
69583 var span = item.select("span");
69584 var placement = i2 < nodes.length / 2 ? "bottom" : "top";
69585 var description = d.description();
69586 var isOverflowing = span.property("clientWidth") !== span.property("scrollWidth");
69587 item.call(uiTooltip().destroyAny);
69588 if (description || isOverflowing) {
69590 uiTooltip().placement(placement).title(() => description || d.name())
69595 function updateLayerSelections(selection2) {
69596 function active(d) {
69597 return context.background().showsLayer(d);
69599 selection2.selectAll("li").classed("active", active).call(setTooltips).selectAll("input").property("checked", active);
69601 function chooseOverlay(d3_event, d) {
69602 d3_event.preventDefault();
69603 context.background().toggleOverlayLayer(d);
69604 _overlayList.call(updateLayerSelections);
69605 document.activeElement.blur();
69607 function drawListItems(layerList, type2, change, filter2) {
69608 var sources = context.background().sources(context.map().extent(), context.map().zoom(), true).filter(filter2);
69609 var layerLinks = layerList.selectAll("li").data(sources, function(d) {
69612 layerLinks.exit().remove();
69613 var enter = layerLinks.enter().append("li");
69614 var label = enter.append("label");
69615 label.append("input").attr("type", type2).attr("name", "layers").on("change", change);
69616 label.append("span").each(function(d) {
69617 d.label()(select_default2(this));
69619 layerList.selectAll("li").sort(sortSources);
69620 layerList.call(updateLayerSelections);
69621 function sortSources(a, b) {
69622 return a.best() && !b.best() ? -1 : b.best() && !a.best() ? 1 : descending(a.area(), b.area()) || ascending(a.name(), b.name()) || 0;
69625 function renderDisclosureContent(selection2) {
69626 var container = selection2.selectAll(".layer-overlay-list").data([0]);
69627 _overlayList = container.enter().append("ul").attr("class", "layer-list layer-overlay-list").attr("dir", "auto").merge(container);
69628 _overlayList.call(drawListItems, "checkbox", chooseOverlay, function(d) {
69629 return !d.isHidden() && d.overlay;
69633 "move.overlay_list",
69634 debounce_default(function() {
69635 window.requestIdleCallback(section.reRender);
69641 // modules/ui/panes/background.js
69642 function uiPaneBackground(context) {
69643 var backgroundPane = uiPane("background", context).key(_t("background.key")).label(_t.append("background.title")).description(_t.append("background.description")).iconName("iD-icon-layers").sections([
69644 uiSectionBackgroundList(context),
69645 uiSectionOverlayList(context),
69646 uiSectionBackgroundDisplayOptions(context),
69647 uiSectionBackgroundOffset(context)
69649 return backgroundPane;
69652 // modules/ui/panes/help.js
69653 function uiPaneHelp(context) {
69663 "open_source_attribution",
69676 "select_left_click",
69677 "select_right_click",
69681 "multiselect_shift_click",
69682 "multiselect_lasso",
69695 ["feature_editor", [
69702 "fields_all_fields",
69704 "fields_add_field",
69713 "add_point_finish",
69718 "delete_point_command"
69725 "add_line_continue",
69728 "modify_line_dragnode",
69729 "modify_line_addnode",
69732 "connect_line_display",
69733 "connect_line_drag",
69734 "connect_line_tag",
69735 "disconnect_line_h",
69736 "disconnect_line_command",
69738 "move_line_command",
69739 "move_line_connected",
69742 "delete_line_command"
69749 "add_area_command",
69751 "add_area_continue",
69754 "square_area_command",
69756 "modify_area_dragnode",
69757 "modify_area_addnode",
69760 "delete_area_command"
69766 "edit_relation_add",
69767 "edit_relation_delete",
69768 "maintain_relation_h",
69769 "maintain_relation",
69770 "relation_types_h",
69773 "multipolygon_create",
69774 "multipolygon_merge",
69775 "turn_restriction_h",
69776 "turn_restriction",
69777 "turn_restriction_field",
69778 "turn_restriction_editing",
69849 "help.help.open_data_h": 3,
69850 "help.help.before_start_h": 3,
69851 "help.help.open_source_h": 3,
69852 "help.overview.navigation_h": 3,
69853 "help.overview.features_h": 3,
69854 "help.editing.select_h": 3,
69855 "help.editing.multiselect_h": 3,
69856 "help.editing.undo_redo_h": 3,
69857 "help.editing.save_h": 3,
69858 "help.editing.upload_h": 3,
69859 "help.editing.backups_h": 3,
69860 "help.editing.keyboard_h": 3,
69861 "help.feature_editor.type_h": 3,
69862 "help.feature_editor.fields_h": 3,
69863 "help.feature_editor.tags_h": 3,
69864 "help.points.add_point_h": 3,
69865 "help.points.move_point_h": 3,
69866 "help.points.delete_point_h": 3,
69867 "help.lines.add_line_h": 3,
69868 "help.lines.modify_line_h": 3,
69869 "help.lines.connect_line_h": 3,
69870 "help.lines.disconnect_line_h": 3,
69871 "help.lines.move_line_h": 3,
69872 "help.lines.delete_line_h": 3,
69873 "help.areas.point_or_area_h": 3,
69874 "help.areas.add_area_h": 3,
69875 "help.areas.square_area_h": 3,
69876 "help.areas.modify_area_h": 3,
69877 "help.areas.delete_area_h": 3,
69878 "help.relations.edit_relation_h": 3,
69879 "help.relations.maintain_relation_h": 3,
69880 "help.relations.relation_types_h": 2,
69881 "help.relations.multipolygon_h": 3,
69882 "help.relations.turn_restriction_h": 3,
69883 "help.relations.route_h": 3,
69884 "help.relations.boundary_h": 3,
69885 "help.notes.add_note_h": 3,
69886 "help.notes.update_note_h": 3,
69887 "help.notes.save_note_h": 3,
69888 "help.imagery.sources_h": 3,
69889 "help.imagery.offsets_h": 3,
69890 "help.streetlevel.using_h": 3,
69891 "help.gps.using_h": 3,
69892 "help.qa.tools_h": 3,
69893 "help.qa.issues_h": 3
69895 var docs = docKeys.map(function(key) {
69896 var helpkey = "help." + key[0];
69897 var helpPaneReplacements = { version: context.version };
69898 var text2 = key[1].reduce(function(all, part) {
69899 var subkey = helpkey + "." + part;
69900 var depth = headings[subkey];
69901 var hhh = depth ? Array(depth + 1).join("#") + " " : "";
69902 return all + hhh + helpHtml(subkey, helpPaneReplacements) + "\n\n";
69905 title: _t.html(helpkey + ".title"),
69906 content: marked(text2.trim()).replace(/<code>/g, "<kbd>").replace(/<\/code>/g, "</kbd>")
69909 var helpPane = uiPane("help", context).key(_t("help.key")).label(_t.append("help.title")).description(_t.append("help.title")).iconName("iD-icon-help");
69910 helpPane.renderContent = function(content) {
69911 function clickHelp(d, i2) {
69912 var rtl = _mainLocalizer.textDirection() === "rtl";
69913 content.property("scrollTop", 0);
69914 helpPane.selection().select(".pane-heading h2").html(d.title);
69915 body.html(d.content);
69916 body.selectAll("a").attr("target", "_blank");
69917 menuItems.classed("selected", function(m) {
69918 return m.title === d.title;
69922 nav.call(drawNext).call(drawPrevious);
69924 nav.call(drawPrevious).call(drawNext);
69926 function drawNext(selection2) {
69927 if (i2 < docs.length - 1) {
69928 var nextLink = selection2.append("a").attr("href", "#").attr("class", "next").on("click", function(d3_event) {
69929 d3_event.preventDefault();
69930 clickHelp(docs[i2 + 1], i2 + 1);
69932 nextLink.append("span").html(docs[i2 + 1].title).call(svgIcon(rtl ? "#iD-icon-backward" : "#iD-icon-forward", "inline"));
69935 function drawPrevious(selection2) {
69937 var prevLink = selection2.append("a").attr("href", "#").attr("class", "previous").on("click", function(d3_event) {
69938 d3_event.preventDefault();
69939 clickHelp(docs[i2 - 1], i2 - 1);
69941 prevLink.call(svgIcon(rtl ? "#iD-icon-forward" : "#iD-icon-backward", "inline")).append("span").html(docs[i2 - 1].title);
69945 function clickWalkthrough(d3_event) {
69946 d3_event.preventDefault();
69947 if (context.inIntro())
69949 context.container().call(uiIntro(context));
69950 context.ui().togglePanes();
69952 function clickShortcuts(d3_event) {
69953 d3_event.preventDefault();
69954 context.container().call(context.ui().shortcuts, true);
69956 var toc = content.append("ul").attr("class", "toc");
69957 var menuItems = toc.selectAll("li").data(docs).enter().append("li").append("a").attr("role", "button").attr("href", "#").html(function(d) {
69959 }).on("click", function(d3_event, d) {
69960 d3_event.preventDefault();
69961 clickHelp(d, docs.indexOf(d));
69963 var shortcuts = toc.append("li").attr("class", "shortcuts").call(
69964 uiTooltip().title(() => _t.append("shortcuts.tooltip")).keys(["?"]).placement("top")
69965 ).append("a").attr("href", "#").on("click", clickShortcuts);
69966 shortcuts.append("div").call(_t.append("shortcuts.title"));
69967 var walkthrough = toc.append("li").attr("class", "walkthrough").append("a").attr("href", "#").on("click", clickWalkthrough);
69968 walkthrough.append("svg").attr("class", "logo logo-walkthrough").append("use").attr("xlink:href", "#iD-logo-walkthrough");
69969 walkthrough.append("div").call(_t.append("splash.walkthrough"));
69970 var helpContent = content.append("div").attr("class", "left-content");
69971 var body = helpContent.append("div").attr("class", "body");
69972 var nav = helpContent.append("div").attr("class", "nav");
69973 clickHelp(docs[0], 0);
69978 // modules/ui/sections/validation_issues.js
69979 function uiSectionValidationIssues(id2, severity, context) {
69981 var section = uiSection(id2, context).label(function() {
69984 var issueCountText = _issues.length > 1e3 ? "1000+" : String(_issues.length);
69985 return _t.append("inspector.title_count", { title: _t("issues." + severity + "s.list_title"), count: issueCountText });
69986 }).disclosureContent(renderDisclosureContent).shouldDisplay(function() {
69987 return _issues && _issues.length;
69989 function getOptions() {
69991 what: corePreferences("validate-what") || "edited",
69992 where: corePreferences("validate-where") || "all"
69995 function reloadIssues() {
69996 _issues = context.validator().getIssuesBySeverity(getOptions())[severity];
69998 function renderDisclosureContent(selection2) {
69999 var center = context.map().center();
70000 var graph = context.graph();
70001 var issues = _issues.map(function withDistance(issue) {
70002 var extent = issue.extent(graph);
70003 var dist = extent ? geoSphericalDistance(center, extent.center()) : 0;
70004 return Object.assign(issue, { dist });
70005 }).sort(function byDistance(a, b) {
70006 return a.dist - b.dist;
70008 issues = issues.slice(0, 1e3);
70009 selection2.call(drawIssuesList, issues);
70011 function drawIssuesList(selection2, issues) {
70012 var list = selection2.selectAll(".issues-list").data([0]);
70013 list = list.enter().append("ul").attr("class", "layer-list issues-list " + severity + "s-list").merge(list);
70014 var items = list.selectAll("li").data(issues, function(d) {
70017 items.exit().remove();
70018 var itemsEnter = items.enter().append("li").attr("class", function(d) {
70019 return "issue severity-" + d.severity;
70021 var labelsEnter = itemsEnter.append("button").attr("class", "issue-label").on("click", function(d3_event, d) {
70022 context.validator().focusIssue(d);
70023 }).on("mouseover", function(d3_event, d) {
70024 utilHighlightEntities(d.entityIds, true, context);
70025 }).on("mouseout", function(d3_event, d) {
70026 utilHighlightEntities(d.entityIds, false, context);
70028 var textEnter = labelsEnter.append("span").attr("class", "issue-text");
70029 textEnter.append("span").attr("class", "issue-icon").each(function(d) {
70030 var iconName = "#iD-icon-" + (d.severity === "warning" ? "alert" : "error");
70031 select_default2(this).call(svgIcon(iconName));
70033 textEnter.append("span").attr("class", "issue-message");
70034 items = items.merge(itemsEnter).order();
70035 items.selectAll(".issue-message").text("").each(function(d) {
70036 return d.message(context)(select_default2(this));
70039 context.validator().on("validated.uiSectionValidationIssues" + id2, function() {
70040 window.requestIdleCallback(function() {
70042 section.reRender();
70046 "move.uiSectionValidationIssues" + id2,
70047 debounce_default(function() {
70048 window.requestIdleCallback(function() {
70049 if (getOptions().where === "visible") {
70052 section.reRender();
70059 // modules/ui/sections/validation_options.js
70060 function uiSectionValidationOptions(context) {
70061 var section = uiSection("issues-options", context).content(renderContent);
70062 function renderContent(selection2) {
70063 var container = selection2.selectAll(".issues-options-container").data([0]);
70064 container = container.enter().append("div").attr("class", "issues-options-container").merge(container);
70066 { key: "what", values: ["edited", "all"] },
70067 { key: "where", values: ["visible", "all"] }
70069 var options2 = container.selectAll(".issues-option").data(data, function(d) {
70072 var optionsEnter = options2.enter().append("div").attr("class", function(d) {
70073 return "issues-option issues-option-" + d.key;
70075 optionsEnter.append("div").attr("class", "issues-option-title").html(function(d) {
70076 return _t.html("issues.options." + d.key + ".title");
70078 var valuesEnter = optionsEnter.selectAll("label").data(function(d) {
70079 return d.values.map(function(val) {
70080 return { value: val, key: d.key };
70082 }).enter().append("label");
70083 valuesEnter.append("input").attr("type", "radio").attr("name", function(d) {
70084 return "issues-option-" + d.key;
70085 }).attr("value", function(d) {
70087 }).property("checked", function(d) {
70088 return getOptions()[d.key] === d.value;
70089 }).on("change", function(d3_event, d) {
70090 updateOptionValue(d3_event, d.key, d.value);
70092 valuesEnter.append("span").html(function(d) {
70093 return _t.html("issues.options." + d.key + "." + d.value);
70096 function getOptions() {
70098 what: corePreferences("validate-what") || "edited",
70100 where: corePreferences("validate-where") || "all"
70101 // 'all', 'visible'
70104 function updateOptionValue(d3_event, d, val) {
70105 if (!val && d3_event && d3_event.target) {
70106 val = d3_event.target.value;
70108 corePreferences("validate-" + d, val);
70109 context.validator().validate();
70114 // modules/ui/sections/validation_rules.js
70115 function uiSectionValidationRules(context) {
70117 var MAXSQUARE = 20;
70118 var DEFAULTSQUARE = 5;
70119 var section = uiSection("issues-rules", context).disclosureContent(renderDisclosureContent).label(() => _t.append("issues.rules.title"));
70120 var _ruleKeys = context.validator().getRuleKeys().filter(function(key) {
70121 return key !== "maprules";
70122 }).sort(function(key1, key2) {
70123 return _t("issues." + key1 + ".title") < _t("issues." + key2 + ".title") ? -1 : 1;
70125 function renderDisclosureContent(selection2) {
70126 var container = selection2.selectAll(".issues-rulelist-container").data([0]);
70127 var containerEnter = container.enter().append("div").attr("class", "issues-rulelist-container");
70128 containerEnter.append("ul").attr("class", "layer-list issue-rules-list");
70129 var ruleLinks = containerEnter.append("div").attr("class", "issue-rules-links section-footer");
70130 ruleLinks.append("a").attr("class", "issue-rules-link").attr("role", "button").attr("href", "#").call(_t.append("issues.disable_all")).on("click", function(d3_event) {
70131 d3_event.preventDefault();
70132 context.validator().disableRules(_ruleKeys);
70134 ruleLinks.append("a").attr("class", "issue-rules-link").attr("role", "button").attr("href", "#").call(_t.append("issues.enable_all")).on("click", function(d3_event) {
70135 d3_event.preventDefault();
70136 context.validator().disableRules([]);
70138 container = container.merge(containerEnter);
70139 container.selectAll(".issue-rules-list").call(drawListItems, _ruleKeys, "checkbox", "rule", toggleRule, isRuleEnabled);
70141 function drawListItems(selection2, data, type2, name, change, active) {
70142 var items = selection2.selectAll("li").data(data);
70143 items.exit().remove();
70144 var enter = items.enter().append("li");
70145 if (name === "rule") {
70147 uiTooltip().title(function(d) {
70148 return _t.append("issues." + d + ".tip");
70149 }).placement("top")
70152 var label = enter.append("label");
70153 label.append("input").attr("type", type2).attr("name", name).on("change", change);
70154 label.append("span").html(function(d) {
70156 if (d === "unsquare_way") {
70157 params.val = { html: '<span class="square-degrees"></span>' };
70159 return _t.html("issues." + d + ".title", params);
70161 items = items.merge(enter);
70162 items.classed("active", active).selectAll("input").property("checked", active).property("indeterminate", false);
70163 var degStr = corePreferences("validate-square-degrees");
70164 if (degStr === null) {
70165 degStr = DEFAULTSQUARE.toString();
70167 var span = items.selectAll(".square-degrees");
70168 var input = span.selectAll(".square-degrees-input").data([0]);
70169 input.enter().append("input").attr("type", "number").attr("min", MINSQUARE.toString()).attr("max", MAXSQUARE.toString()).attr("step", "0.5").attr("class", "square-degrees-input").call(utilNoAuto).on("click", function(d3_event) {
70170 d3_event.preventDefault();
70171 d3_event.stopPropagation();
70173 }).on("keyup", function(d3_event) {
70174 if (d3_event.keyCode === 13) {
70178 }).on("blur", changeSquare).merge(input).property("value", degStr);
70180 function changeSquare() {
70181 var input = select_default2(this);
70182 var degStr = utilGetSetValue(input).trim();
70183 var degNum = Number(degStr);
70184 if (!isFinite(degNum)) {
70185 degNum = DEFAULTSQUARE;
70186 } else if (degNum > MAXSQUARE) {
70187 degNum = MAXSQUARE;
70188 } else if (degNum < MINSQUARE) {
70189 degNum = MINSQUARE;
70191 degNum = Math.round(degNum * 10) / 10;
70192 degStr = degNum.toString();
70193 input.property("value", degStr);
70194 corePreferences("validate-square-degrees", degStr);
70195 context.validator().revalidateUnsquare();
70197 function isRuleEnabled(d) {
70198 return context.validator().isRuleEnabled(d);
70200 function toggleRule(d3_event, d) {
70201 context.validator().toggleRule(d);
70203 context.validator().on("validated.uiSectionValidationRules", function() {
70204 window.requestIdleCallback(section.reRender);
70209 // modules/ui/sections/validation_status.js
70210 function uiSectionValidationStatus(context) {
70211 var section = uiSection("issues-status", context).content(renderContent).shouldDisplay(function() {
70212 var issues = context.validator().getIssues(getOptions());
70213 return issues.length === 0;
70215 function getOptions() {
70217 what: corePreferences("validate-what") || "edited",
70218 where: corePreferences("validate-where") || "all"
70221 function renderContent(selection2) {
70222 var box = selection2.selectAll(".box").data([0]);
70223 var boxEnter = box.enter().append("div").attr("class", "box");
70224 boxEnter.append("div").call(svgIcon("#iD-icon-apply", "pre-text"));
70225 var noIssuesMessage = boxEnter.append("span");
70226 noIssuesMessage.append("strong").attr("class", "message");
70227 noIssuesMessage.append("br");
70228 noIssuesMessage.append("span").attr("class", "details");
70229 renderIgnoredIssuesReset(selection2);
70230 setNoIssuesText(selection2);
70232 function renderIgnoredIssuesReset(selection2) {
70233 var ignoredIssues = context.validator().getIssues({ what: "all", where: "all", includeDisabledRules: true, includeIgnored: "only" });
70234 var resetIgnored = selection2.selectAll(".reset-ignored").data(ignoredIssues.length ? [0] : []);
70235 resetIgnored.exit().remove();
70236 var resetIgnoredEnter = resetIgnored.enter().append("div").attr("class", "reset-ignored section-footer");
70237 resetIgnoredEnter.append("a").attr("href", "#");
70238 resetIgnored = resetIgnored.merge(resetIgnoredEnter);
70239 resetIgnored.select("a").html(_t.html("inspector.title_count", { title: { html: _t.html("issues.reset_ignored") }, count: ignoredIssues.length }));
70240 resetIgnored.on("click", function(d3_event) {
70241 d3_event.preventDefault();
70242 context.validator().resetIgnoredIssues();
70245 function setNoIssuesText(selection2) {
70246 var opts = getOptions();
70247 function checkForHiddenIssues(cases) {
70248 for (var type2 in cases) {
70249 var hiddenOpts = cases[type2];
70250 var hiddenIssues = context.validator().getIssues(hiddenOpts);
70251 if (hiddenIssues.length) {
70252 selection2.select(".box .details").html("").call(_t.append(
70253 "issues.no_issues.hidden_issues." + type2,
70254 { count: hiddenIssues.length.toString() }
70259 selection2.select(".box .details").html("").call(_t.append("issues.no_issues.hidden_issues.none"));
70262 if (opts.what === "edited" && opts.where === "visible") {
70263 messageType = "edits_in_view";
70264 checkForHiddenIssues({
70265 elsewhere: { what: "edited", where: "all" },
70266 everything_else: { what: "all", where: "visible" },
70267 disabled_rules: { what: "edited", where: "visible", includeDisabledRules: "only" },
70268 everything_else_elsewhere: { what: "all", where: "all" },
70269 disabled_rules_elsewhere: { what: "edited", where: "all", includeDisabledRules: "only" },
70270 ignored_issues: { what: "edited", where: "visible", includeIgnored: "only" },
70271 ignored_issues_elsewhere: { what: "edited", where: "all", includeIgnored: "only" }
70273 } else if (opts.what === "edited" && opts.where === "all") {
70274 messageType = "edits";
70275 checkForHiddenIssues({
70276 everything_else: { what: "all", where: "all" },
70277 disabled_rules: { what: "edited", where: "all", includeDisabledRules: "only" },
70278 ignored_issues: { what: "edited", where: "all", includeIgnored: "only" }
70280 } else if (opts.what === "all" && opts.where === "visible") {
70281 messageType = "everything_in_view";
70282 checkForHiddenIssues({
70283 elsewhere: { what: "all", where: "all" },
70284 disabled_rules: { what: "all", where: "visible", includeDisabledRules: "only" },
70285 disabled_rules_elsewhere: { what: "all", where: "all", includeDisabledRules: "only" },
70286 ignored_issues: { what: "all", where: "visible", includeIgnored: "only" },
70287 ignored_issues_elsewhere: { what: "all", where: "all", includeIgnored: "only" }
70289 } else if (opts.what === "all" && opts.where === "all") {
70290 messageType = "everything";
70291 checkForHiddenIssues({
70292 disabled_rules: { what: "all", where: "all", includeDisabledRules: "only" },
70293 ignored_issues: { what: "all", where: "all", includeIgnored: "only" }
70296 if (opts.what === "edited" && context.history().difference().summary().length === 0) {
70297 messageType = "no_edits";
70299 selection2.select(".box .message").html("").call(_t.append("issues.no_issues.message." + messageType));
70301 context.validator().on("validated.uiSectionValidationStatus", function() {
70302 window.requestIdleCallback(section.reRender);
70305 "move.uiSectionValidationStatus",
70306 debounce_default(function() {
70307 window.requestIdleCallback(section.reRender);
70313 // modules/ui/panes/issues.js
70314 function uiPaneIssues(context) {
70315 var issuesPane = uiPane("issues", context).key(_t("issues.key")).label(_t.append("issues.title")).description(_t.append("issues.title")).iconName("iD-icon-alert").sections([
70316 uiSectionValidationOptions(context),
70317 uiSectionValidationStatus(context),
70318 uiSectionValidationIssues("issues-errors", "error", context),
70319 uiSectionValidationIssues("issues-warnings", "warning", context),
70320 uiSectionValidationRules(context)
70325 // modules/ui/settings/custom_data.js
70326 function uiSettingsCustomData(context) {
70327 var dispatch10 = dispatch_default("change");
70328 function render(selection2) {
70329 var dataLayer = context.layers().layer("data");
70330 var _origSettings = {
70331 fileList: dataLayer && dataLayer.fileList() || null,
70332 url: corePreferences("settings-custom-data-url")
70334 var _currSettings = {
70335 fileList: dataLayer && dataLayer.fileList() || null,
70336 url: corePreferences("settings-custom-data-url")
70338 var modal = uiConfirm(selection2).okButton();
70339 modal.classed("settings-modal settings-custom-data", true);
70340 modal.select(".modal-section.header").append("h3").call(_t.append("settings.custom_data.header"));
70341 var textSection = modal.select(".modal-section.message-text");
70342 textSection.append("pre").attr("class", "instructions-file").call(_t.append("settings.custom_data.file.instructions"));
70343 textSection.append("input").attr("class", "field-file").attr("type", "file").attr("accept", ".gpx,.kml,.geojson,.json,application/gpx+xml,application/vnd.google-earth.kml+xml,application/geo+json,application/json").property("files", _currSettings.fileList).on("change", function(d3_event) {
70344 var files = d3_event.target.files;
70345 if (files && files.length) {
70346 _currSettings.url = "";
70347 textSection.select(".field-url").property("value", "");
70348 _currSettings.fileList = files;
70350 _currSettings.fileList = null;
70353 textSection.append("h4").call(_t.append("settings.custom_data.or"));
70354 textSection.append("pre").attr("class", "instructions-url").call(_t.append("settings.custom_data.url.instructions"));
70355 textSection.append("textarea").attr("class", "field-url").attr("placeholder", _t("settings.custom_data.url.placeholder")).call(utilNoAuto).property("value", _currSettings.url);
70356 var buttonSection = modal.select(".modal-section.buttons");
70357 buttonSection.insert("button", ".ok-button").attr("class", "button cancel-button secondary-action").call(_t.append("confirm.cancel"));
70358 buttonSection.select(".cancel-button").on("click.cancel", clickCancel);
70359 buttonSection.select(".ok-button").attr("disabled", isSaveDisabled).on("click.save", clickSave);
70360 function isSaveDisabled() {
70363 function clickCancel() {
70364 textSection.select(".field-url").property("value", _origSettings.url);
70365 corePreferences("settings-custom-data-url", _origSettings.url);
70369 function clickSave() {
70370 _currSettings.url = textSection.select(".field-url").property("value").trim();
70371 if (_currSettings.url) {
70372 _currSettings.fileList = null;
70374 if (_currSettings.fileList) {
70375 _currSettings.url = "";
70377 corePreferences("settings-custom-data-url", _currSettings.url);
70380 dispatch10.call("change", this, _currSettings);
70383 return utilRebind(render, dispatch10, "on");
70386 // modules/ui/sections/data_layers.js
70387 function uiSectionDataLayers(context) {
70388 var settingsCustomData = uiSettingsCustomData(context).on("change", customChanged);
70389 var layers = context.layers();
70390 var section = uiSection("data-layers", context).label(() => _t.append("map_data.data_layers")).disclosureContent(renderDisclosureContent);
70391 function renderDisclosureContent(selection2) {
70392 var container = selection2.selectAll(".data-layer-container").data([0]);
70393 container.enter().append("div").attr("class", "data-layer-container").merge(container).call(drawOsmItems).call(drawQAItems).call(drawCustomDataItems).call(drawVectorItems).call(drawPanelItems);
70395 function showsLayer(which) {
70396 var layer = layers.layer(which);
70398 return layer.enabled();
70402 function setLayer(which, enabled) {
70403 var mode = context.mode();
70404 if (mode && /^draw/.test(mode.id))
70406 var layer = layers.layer(which);
70408 layer.enabled(enabled);
70409 if (!enabled && (which === "osm" || which === "notes")) {
70410 context.enter(modeBrowse(context));
70414 function toggleLayer(which) {
70415 setLayer(which, !showsLayer(which));
70417 function drawOsmItems(selection2) {
70418 var osmKeys = ["osm", "notes"];
70419 var osmLayers = layers.all().filter(function(obj) {
70420 return osmKeys.indexOf(obj.id) !== -1;
70422 var ul = selection2.selectAll(".layer-list-osm").data([0]);
70423 ul = ul.enter().append("ul").attr("class", "layer-list layer-list-osm").merge(ul);
70424 var li = ul.selectAll(".list-item").data(osmLayers);
70425 li.exit().remove();
70426 var liEnter = li.enter().append("li").attr("class", function(d) {
70427 return "list-item list-item-" + d.id;
70429 var labelEnter = liEnter.append("label").each(function(d) {
70430 if (d.id === "osm") {
70431 select_default2(this).call(
70432 uiTooltip().title(() => _t.append("map_data.layers." + d.id + ".tooltip")).keys([uiCmd("\u2325" + _t("area_fill.wireframe.key"))]).placement("bottom")
70435 select_default2(this).call(
70436 uiTooltip().title(() => _t.append("map_data.layers." + d.id + ".tooltip")).placement("bottom")
70440 labelEnter.append("input").attr("type", "checkbox").on("change", function(d3_event, d) {
70443 labelEnter.append("span").html(function(d) {
70444 return _t.html("map_data.layers." + d.id + ".title");
70446 li.merge(liEnter).classed("active", function(d) {
70447 return d.layer.enabled();
70448 }).selectAll("input").property("checked", function(d) {
70449 return d.layer.enabled();
70452 function drawQAItems(selection2) {
70453 var qaKeys = ["keepRight", "improveOSM", "osmose"];
70454 var qaLayers = layers.all().filter(function(obj) {
70455 return qaKeys.indexOf(obj.id) !== -1;
70457 var ul = selection2.selectAll(".layer-list-qa").data([0]);
70458 ul = ul.enter().append("ul").attr("class", "layer-list layer-list-qa").merge(ul);
70459 var li = ul.selectAll(".list-item").data(qaLayers);
70460 li.exit().remove();
70461 var liEnter = li.enter().append("li").attr("class", function(d) {
70462 return "list-item list-item-" + d.id;
70464 var labelEnter = liEnter.append("label").each(function(d) {
70465 select_default2(this).call(
70466 uiTooltip().title(() => _t.append("map_data.layers." + d.id + ".tooltip")).placement("bottom")
70469 labelEnter.append("input").attr("type", "checkbox").on("change", function(d3_event, d) {
70472 labelEnter.append("span").each(function(d) {
70473 _t.append("map_data.layers." + d.id + ".title")(select_default2(this));
70475 li.merge(liEnter).classed("active", function(d) {
70476 return d.layer.enabled();
70477 }).selectAll("input").property("checked", function(d) {
70478 return d.layer.enabled();
70481 function drawVectorItems(selection2) {
70482 var dataLayer = layers.layer("data");
70485 name: "Detroit Neighborhoods/Parks",
70486 src: "neighborhoods-parks",
70487 tooltip: "Neighborhood boundaries and parks as compiled by City of Detroit in concert with community groups.",
70488 template: "https://{switch:a,b,c,d}.tiles.mapbox.com/v4/jonahadkins.cjksmur6x34562qp9iv1u3ksf-54hev,jonahadkins.cjksmqxdx33jj2wp90xd9x2md-4e5y2/{z}/{x}/{y}.vector.pbf?access_token=pk.eyJ1Ijoiam9uYWhhZGtpbnMiLCJhIjoiRlVVVkx3VSJ9.9sdVEK_B_VkEXPjssU5MqA"
70491 name: "Detroit Composite POIs",
70492 src: "composite-poi",
70493 tooltip: "Fire Inspections, Business Licenses, and other public location data collated from the City of Detroit.",
70494 template: "https://{switch:a,b,c,d}.tiles.mapbox.com/v4/jonahadkins.cjksmm6a02sli31myxhsr7zf3-2sw8h/{z}/{x}/{y}.vector.pbf?access_token=pk.eyJ1Ijoiam9uYWhhZGtpbnMiLCJhIjoiRlVVVkx3VSJ9.9sdVEK_B_VkEXPjssU5MqA"
70497 name: "Detroit All-The-Places POIs",
70498 src: "alltheplaces-poi",
70499 tooltip: "Public domain business location data created by web scrapers.",
70500 template: "https://{switch:a,b,c,d}.tiles.mapbox.com/v4/jonahadkins.cjksmswgk340g2vo06p1w9w0j-8fjjc/{z}/{x}/{y}.vector.pbf?access_token=pk.eyJ1Ijoiam9uYWhhZGtpbnMiLCJhIjoiRlVVVkx3VSJ9.9sdVEK_B_VkEXPjssU5MqA"
70503 var detroit = geoExtent([-83.5, 42.1], [-82.8, 42.5]);
70504 var showVectorItems = context.map().zoom() > 9 && detroit.contains(context.map().center());
70505 var container = selection2.selectAll(".vectortile-container").data(showVectorItems ? [0] : []);
70506 container.exit().remove();
70507 var containerEnter = container.enter().append("div").attr("class", "vectortile-container");
70508 containerEnter.append("h4").attr("class", "vectortile-header").text("Detroit Vector Tiles (Beta)");
70509 containerEnter.append("ul").attr("class", "layer-list layer-list-vectortile");
70510 containerEnter.append("div").attr("class", "vectortile-footer").append("a").attr("target", "_blank").call(svgIcon("#iD-icon-out-link", "inline")).attr("href", "https://github.com/osmus/detroit-mapping-challenge").append("span").text("About these layers");
70511 container = container.merge(containerEnter);
70512 var ul = container.selectAll(".layer-list-vectortile");
70513 var li = ul.selectAll(".list-item").data(vtData);
70514 li.exit().remove();
70515 var liEnter = li.enter().append("li").attr("class", function(d) {
70516 return "list-item list-item-" + d.src;
70518 var labelEnter = liEnter.append("label").each(function(d) {
70519 select_default2(this).call(
70520 uiTooltip().title(d.tooltip).placement("top")
70523 labelEnter.append("input").attr("type", "radio").attr("name", "vectortile").on("change", selectVTLayer);
70524 labelEnter.append("span").text(function(d) {
70527 li.merge(liEnter).classed("active", isVTLayerSelected).selectAll("input").property("checked", isVTLayerSelected);
70528 function isVTLayerSelected(d) {
70529 return dataLayer && dataLayer.template() === d.template;
70531 function selectVTLayer(d3_event, d) {
70532 corePreferences("settings-custom-data-url", d.template);
70534 dataLayer.template(d.template, d.src);
70535 dataLayer.enabled(true);
70539 function drawCustomDataItems(selection2) {
70540 var dataLayer = layers.layer("data");
70541 var hasData = dataLayer && dataLayer.hasData();
70542 var showsData = hasData && dataLayer.enabled();
70543 var ul = selection2.selectAll(".layer-list-data").data(dataLayer ? [0] : []);
70544 ul.exit().remove();
70545 var ulEnter = ul.enter().append("ul").attr("class", "layer-list layer-list-data");
70546 var liEnter = ulEnter.append("li").attr("class", "list-item-data");
70547 var labelEnter = liEnter.append("label").call(
70548 uiTooltip().title(() => _t.append("map_data.layers.custom.tooltip")).placement("top")
70550 labelEnter.append("input").attr("type", "checkbox").on("change", function() {
70551 toggleLayer("data");
70553 labelEnter.append("span").call(_t.append("map_data.layers.custom.title"));
70554 liEnter.append("button").attr("class", "open-data-options").call(
70555 uiTooltip().title(() => _t.append("settings.custom_data.tooltip")).placement(_mainLocalizer.textDirection() === "rtl" ? "right" : "left")
70556 ).on("click", function(d3_event) {
70557 d3_event.preventDefault();
70559 }).call(svgIcon("#iD-icon-more"));
70560 liEnter.append("button").attr("class", "zoom-to-data").call(
70561 uiTooltip().title(() => _t.append("map_data.layers.custom.zoom")).placement(_mainLocalizer.textDirection() === "rtl" ? "right" : "left")
70562 ).on("click", function(d3_event) {
70563 if (select_default2(this).classed("disabled"))
70565 d3_event.preventDefault();
70566 d3_event.stopPropagation();
70567 dataLayer.fitZoom();
70568 }).call(svgIcon("#iD-icon-framed-dot", "monochrome"));
70569 ul = ul.merge(ulEnter);
70570 ul.selectAll(".list-item-data").classed("active", showsData).selectAll("label").classed("deemphasize", !hasData).selectAll("input").property("disabled", !hasData).property("checked", showsData);
70571 ul.selectAll("button.zoom-to-data").classed("disabled", !hasData);
70573 function editCustom() {
70574 context.container().call(settingsCustomData);
70576 function customChanged(d) {
70577 var dataLayer = layers.layer("data");
70579 dataLayer.url(d.url);
70580 } else if (d && d.fileList) {
70581 dataLayer.fileList(d.fileList);
70584 function drawPanelItems(selection2) {
70585 var panelsListEnter = selection2.selectAll(".md-extras-list").data([0]).enter().append("ul").attr("class", "layer-list md-extras-list");
70586 var historyPanelLabelEnter = panelsListEnter.append("li").attr("class", "history-panel-toggle-item").append("label").call(
70587 uiTooltip().title(() => _t.append("map_data.history_panel.tooltip")).keys([uiCmd("\u2318\u21E7" + _t("info_panels.history.key"))]).placement("top")
70589 historyPanelLabelEnter.append("input").attr("type", "checkbox").on("change", function(d3_event) {
70590 d3_event.preventDefault();
70591 context.ui().info.toggle("history");
70593 historyPanelLabelEnter.append("span").call(_t.append("map_data.history_panel.title"));
70594 var measurementPanelLabelEnter = panelsListEnter.append("li").attr("class", "measurement-panel-toggle-item").append("label").call(
70595 uiTooltip().title(() => _t.append("map_data.measurement_panel.tooltip")).keys([uiCmd("\u2318\u21E7" + _t("info_panels.measurement.key"))]).placement("top")
70597 measurementPanelLabelEnter.append("input").attr("type", "checkbox").on("change", function(d3_event) {
70598 d3_event.preventDefault();
70599 context.ui().info.toggle("measurement");
70601 measurementPanelLabelEnter.append("span").call(_t.append("map_data.measurement_panel.title"));
70603 context.layers().on("change.uiSectionDataLayers", section.reRender);
70605 "move.uiSectionDataLayers",
70606 debounce_default(function() {
70607 window.requestIdleCallback(section.reRender);
70613 // modules/ui/sections/map_features.js
70614 function uiSectionMapFeatures(context) {
70615 var _features = context.features().keys();
70616 var section = uiSection("map-features", context).label(() => _t.append("map_data.map_features")).disclosureContent(renderDisclosureContent).expandedByDefault(false);
70617 function renderDisclosureContent(selection2) {
70618 var container = selection2.selectAll(".layer-feature-list-container").data([0]);
70619 var containerEnter = container.enter().append("div").attr("class", "layer-feature-list-container");
70620 containerEnter.append("ul").attr("class", "layer-list layer-feature-list");
70621 var footer = containerEnter.append("div").attr("class", "feature-list-links section-footer");
70622 footer.append("a").attr("class", "feature-list-link").attr("role", "button").attr("href", "#").call(_t.append("issues.disable_all")).on("click", function(d3_event) {
70623 d3_event.preventDefault();
70624 context.features().disableAll();
70626 footer.append("a").attr("class", "feature-list-link").attr("role", "button").attr("href", "#").call(_t.append("issues.enable_all")).on("click", function(d3_event) {
70627 d3_event.preventDefault();
70628 context.features().enableAll();
70630 container = container.merge(containerEnter);
70631 container.selectAll(".layer-feature-list").call(drawListItems, _features, "checkbox", "feature", clickFeature, showsFeature);
70633 function drawListItems(selection2, data, type2, name, change, active) {
70634 var items = selection2.selectAll("li").data(data);
70635 items.exit().remove();
70636 var enter = items.enter().append("li").call(
70637 uiTooltip().title(function(d) {
70638 var tip = _t.append(name + "." + d + ".tooltip");
70639 if (autoHiddenFeature(d)) {
70640 var msg = showsLayer("osm") ? _t.append("map_data.autohidden") : _t.append("map_data.osmhidden");
70641 return (selection3) => {
70642 selection3.call(tip);
70643 selection3.append("div").call(msg);
70647 }).placement("top")
70649 var label = enter.append("label");
70650 label.append("input").attr("type", type2).attr("name", name).on("change", change);
70651 label.append("span").html(function(d) {
70652 return _t.html(name + "." + d + ".description");
70654 items = items.merge(enter);
70655 items.classed("active", active).selectAll("input").property("checked", active).property("indeterminate", autoHiddenFeature);
70657 function autoHiddenFeature(d) {
70658 return context.features().autoHidden(d);
70660 function showsFeature(d) {
70661 return context.features().enabled(d);
70663 function clickFeature(d3_event, d) {
70664 context.features().toggle(d);
70666 function showsLayer(id2) {
70667 var layer = context.layers().layer(id2);
70668 return layer && layer.enabled();
70670 context.features().on("change.map_features", section.reRender);
70674 // modules/ui/sections/map_style_options.js
70675 function uiSectionMapStyleOptions(context) {
70676 var section = uiSection("fill-area", context).label(() => _t.append("map_data.style_options")).disclosureContent(renderDisclosureContent).expandedByDefault(false);
70677 function renderDisclosureContent(selection2) {
70678 var container = selection2.selectAll(".layer-fill-list").data([0]);
70679 container.enter().append("ul").attr("class", "layer-list layer-fill-list").merge(container).call(drawListItems, context.map().areaFillOptions, "radio", "area_fill", setFill, isActiveFill);
70680 var container2 = selection2.selectAll(".layer-visual-diff-list").data([0]);
70681 container2.enter().append("ul").attr("class", "layer-list layer-visual-diff-list").merge(container2).call(drawListItems, ["highlight_edits"], "checkbox", "visual_diff", toggleHighlightEdited, function() {
70682 return context.surface().classed("highlight-edited");
70685 function drawListItems(selection2, data, type2, name, change, active) {
70686 var items = selection2.selectAll("li").data(data);
70687 items.exit().remove();
70688 var enter = items.enter().append("li").call(
70689 uiTooltip().title(function(d) {
70690 return _t.append(name + "." + d + ".tooltip");
70691 }).keys(function(d) {
70692 var key = d === "wireframe" ? _t("area_fill.wireframe.key") : null;
70693 if (d === "highlight_edits")
70694 key = _t("map_data.highlight_edits.key");
70695 return key ? [key] : null;
70696 }).placement("top")
70698 var label = enter.append("label");
70699 label.append("input").attr("type", type2).attr("name", name).on("change", change);
70700 label.append("span").html(function(d) {
70701 return _t.html(name + "." + d + ".description");
70703 items = items.merge(enter);
70704 items.classed("active", active).selectAll("input").property("checked", active).property("indeterminate", false);
70706 function isActiveFill(d) {
70707 return context.map().activeAreaFill() === d;
70709 function toggleHighlightEdited(d3_event) {
70710 d3_event.preventDefault();
70711 context.map().toggleHighlightEdited();
70713 function setFill(d3_event, d) {
70714 context.map().activeAreaFill(d);
70716 context.map().on("changeHighlighting.ui_style, changeAreaFill.ui_style", section.reRender);
70720 // modules/ui/sections/photo_overlays.js
70721 function uiSectionPhotoOverlays(context) {
70722 var layers = context.layers();
70723 var section = uiSection("photo-overlays", context).label(() => _t.append("photo_overlays.title")).disclosureContent(renderDisclosureContent).expandedByDefault(false);
70724 function renderDisclosureContent(selection2) {
70725 var container = selection2.selectAll(".photo-overlay-container").data([0]);
70726 container.enter().append("div").attr("class", "photo-overlay-container").merge(container).call(drawPhotoItems).call(drawPhotoTypeItems).call(drawDateFilter).call(drawUsernameFilter);
70728 function drawPhotoItems(selection2) {
70729 var photoKeys = context.photos().overlayLayerIDs();
70730 var photoLayers = layers.all().filter(function(obj) {
70731 return photoKeys.indexOf(obj.id) !== -1;
70733 var data = photoLayers.filter(function(obj) {
70734 return obj.layer.supported();
70736 function layerSupported(d) {
70737 return d.layer && d.layer.supported();
70739 function layerEnabled(d) {
70740 return layerSupported(d) && d.layer.enabled();
70742 var ul = selection2.selectAll(".layer-list-photos").data([0]);
70743 ul = ul.enter().append("ul").attr("class", "layer-list layer-list-photos").merge(ul);
70744 var li = ul.selectAll(".list-item-photos").data(data);
70745 li.exit().remove();
70746 var liEnter = li.enter().append("li").attr("class", function(d) {
70747 var classes = "list-item-photos list-item-" + d.id;
70748 if (d.id === "mapillary-signs" || d.id === "mapillary-map-features") {
70749 classes += " indented";
70753 var labelEnter = liEnter.append("label").each(function(d) {
70755 if (d.id === "mapillary-signs")
70756 titleID = "mapillary.signs.tooltip";
70757 else if (d.id === "mapillary")
70758 titleID = "mapillary_images.tooltip";
70759 else if (d.id === "kartaview")
70760 titleID = "kartaview_images.tooltip";
70762 titleID = d.id.replace(/-/g, "_") + ".tooltip";
70763 select_default2(this).call(
70764 uiTooltip().title(() => _t.append(titleID)).placement("top")
70767 labelEnter.append("input").attr("type", "checkbox").on("change", function(d3_event, d) {
70770 labelEnter.append("span").html(function(d) {
70772 if (id2 === "mapillary-signs")
70773 id2 = "photo_overlays.traffic_signs";
70774 return _t.html(id2.replace(/-/g, "_") + ".title");
70776 li.merge(liEnter).classed("active", layerEnabled).selectAll("input").property("checked", layerEnabled);
70778 function drawPhotoTypeItems(selection2) {
70779 var data = context.photos().allPhotoTypes();
70780 function typeEnabled(d) {
70781 return context.photos().showsPhotoType(d);
70783 var ul = selection2.selectAll(".layer-list-photo-types").data([0]);
70784 ul.exit().remove();
70785 ul = ul.enter().append("ul").attr("class", "layer-list layer-list-photo-types").merge(ul);
70786 var li = ul.selectAll(".list-item-photo-types").data(context.photos().shouldFilterByPhotoType() ? data : []);
70787 li.exit().remove();
70788 var liEnter = li.enter().append("li").attr("class", function(d) {
70789 return "list-item-photo-types list-item-" + d;
70791 var labelEnter = liEnter.append("label").each(function(d) {
70792 select_default2(this).call(
70793 uiTooltip().title(() => _t.append("photo_overlays.photo_type." + d + ".tooltip")).placement("top")
70796 labelEnter.append("input").attr("type", "checkbox").on("change", function(d3_event, d) {
70797 context.photos().togglePhotoType(d);
70799 labelEnter.append("span").html(function(d) {
70800 return _t.html("photo_overlays.photo_type." + d + ".title");
70802 li.merge(liEnter).classed("active", typeEnabled).selectAll("input").property("checked", typeEnabled);
70804 function drawDateFilter(selection2) {
70805 var data = context.photos().dateFilters();
70806 function filterEnabled(d) {
70807 return context.photos().dateFilterValue(d);
70809 var ul = selection2.selectAll(".layer-list-date-filter").data([0]);
70810 ul.exit().remove();
70811 ul = ul.enter().append("ul").attr("class", "layer-list layer-list-date-filter").merge(ul);
70812 var li = ul.selectAll(".list-item-date-filter").data(context.photos().shouldFilterByDate() ? data : []);
70813 li.exit().remove();
70814 var liEnter = li.enter().append("li").attr("class", "list-item-date-filter");
70815 var labelEnter = liEnter.append("label").each(function(d) {
70816 select_default2(this).call(
70817 uiTooltip().title(() => _t.append("photo_overlays.date_filter." + d + ".tooltip")).placement("top")
70820 labelEnter.append("span").each(function(d) {
70821 _t.append("photo_overlays.date_filter." + d + ".title")(select_default2(this));
70823 labelEnter.append("input").attr("type", "date").attr("class", "list-item-input").attr("placeholder", _t("units.year_month_day")).call(utilNoAuto).each(function(d) {
70824 utilGetSetValue(select_default2(this), context.photos().dateFilterValue(d) || "");
70825 }).on("change", function(d3_event, d) {
70826 var value = utilGetSetValue(select_default2(this)).trim();
70827 context.photos().setDateFilter(d, value, true);
70828 li.selectAll("input").each(function(d2) {
70829 utilGetSetValue(select_default2(this), context.photos().dateFilterValue(d2) || "");
70832 li = li.merge(liEnter).classed("active", filterEnabled);
70834 function drawUsernameFilter(selection2) {
70835 function filterEnabled() {
70836 return context.photos().usernames();
70838 var ul = selection2.selectAll(".layer-list-username-filter").data([0]);
70839 ul.exit().remove();
70840 ul = ul.enter().append("ul").attr("class", "layer-list layer-list-username-filter").merge(ul);
70841 var li = ul.selectAll(".list-item-username-filter").data(context.photos().shouldFilterByUsername() ? ["username-filter"] : []);
70842 li.exit().remove();
70843 var liEnter = li.enter().append("li").attr("class", "list-item-username-filter");
70844 var labelEnter = liEnter.append("label").each(function() {
70845 select_default2(this).call(
70846 uiTooltip().title(() => _t.append("photo_overlays.username_filter.tooltip")).placement("top")
70849 labelEnter.append("span").call(_t.append("photo_overlays.username_filter.title"));
70850 labelEnter.append("input").attr("type", "text").attr("class", "list-item-input").call(utilNoAuto).property("value", usernameValue).on("change", function() {
70851 var value = select_default2(this).property("value");
70852 context.photos().setUsernameFilter(value, true);
70853 select_default2(this).property("value", usernameValue);
70855 li.merge(liEnter).classed("active", filterEnabled);
70856 function usernameValue() {
70857 var usernames = context.photos().usernames();
70859 return usernames.join("; ");
70863 function toggleLayer(which) {
70864 setLayer(which, !showsLayer(which));
70866 function showsLayer(which) {
70867 var layer = layers.layer(which);
70869 return layer.enabled();
70873 function setLayer(which, enabled) {
70874 var layer = layers.layer(which);
70876 layer.enabled(enabled);
70879 context.layers().on("change.uiSectionPhotoOverlays", section.reRender);
70880 context.photos().on("change.uiSectionPhotoOverlays", section.reRender);
70884 // modules/ui/panes/map_data.js
70885 function uiPaneMapData(context) {
70886 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([
70887 uiSectionDataLayers(context),
70888 uiSectionPhotoOverlays(context),
70889 uiSectionMapStyleOptions(context),
70890 uiSectionMapFeatures(context)
70892 return mapDataPane;
70895 // modules/ui/panes/preferences.js
70896 function uiPanePreferences(context) {
70897 let preferencesPane = uiPane("preferences", context).key(_t("preferences.key")).label(_t.append("preferences.title")).description(_t.append("preferences.description")).iconName("fas-user-cog").sections([
70898 uiSectionPrivacy(context)
70900 return preferencesPane;
70903 // modules/ui/init.js
70904 function uiInit(context) {
70905 var _initCounter = 0;
70906 var _needWidth = {};
70907 var _lastPointerType;
70908 function render(container) {
70909 container.on("click.ui", function(d3_event) {
70910 if (d3_event.button !== 0)
70912 if (!d3_event.composedPath)
70914 var isOkayTarget = d3_event.composedPath().some(function(node) {
70915 return node.nodeType === 1 && // clicking <input> focuses it and/or changes a value
70916 (node.nodeName === "INPUT" || // clicking <label> affects its <input> by default
70917 node.nodeName === "LABEL" || // clicking <a> opens a hyperlink by default
70918 node.nodeName === "A");
70922 d3_event.preventDefault();
70924 var detected = utilDetect();
70925 if ("GestureEvent" in window && // Listening for gesture events on iOS 13.4+ breaks double-tapping,
70926 // but we only need to do this on desktop Safari anyway. – #7694
70927 !detected.isMobileWebKit) {
70928 container.on("gesturestart.ui gesturechange.ui gestureend.ui", function(d3_event) {
70929 d3_event.preventDefault();
70932 if ("PointerEvent" in window) {
70933 select_default2(window).on("pointerdown.ui pointerup.ui", function(d3_event) {
70934 var pointerType = d3_event.pointerType || "mouse";
70935 if (_lastPointerType !== pointerType) {
70936 _lastPointerType = pointerType;
70937 container.attr("pointer", pointerType);
70941 _lastPointerType = "mouse";
70942 container.attr("pointer", "mouse");
70944 container.attr("lang", _mainLocalizer.localeCode()).attr("dir", _mainLocalizer.textDirection());
70945 container.call(uiFullScreen(context));
70946 var map2 = context.map();
70947 map2.redrawEnable(false);
70948 map2.on("hitMinZoom.ui", function() {
70949 ui.flash.iconName("#iD-icon-no").label(_t.append("cannot_zoom"))();
70951 container.append("svg").attr("id", "ideditor-defs").call(ui.svgDefs);
70952 container.append("div").attr("class", "sidebar").call(ui.sidebar);
70953 var content = container.append("div").attr("class", "main-content active");
70954 content.append("div").attr("class", "top-toolbar-wrap").append("div").attr("class", "top-toolbar fillD").call(uiTopToolbar(context));
70955 content.append("div").attr("class", "main-map").attr("dir", "ltr").call(map2);
70956 var overMap = content.append("div").attr("class", "over-map");
70957 overMap.append("div").attr("class", "select-trap").text("t");
70958 overMap.call(uiMapInMap(context)).call(uiNotice(context));
70959 overMap.append("div").attr("class", "spinner").call(uiSpinner(context));
70960 var controlsWrap = overMap.append("div").attr("class", "map-controls-wrap");
70961 var controls = controlsWrap.append("div").attr("class", "map-controls");
70962 controls.append("div").attr("class", "map-control zoombuttons").call(uiZoom(context));
70963 controls.append("div").attr("class", "map-control zoom-to-selection-control").call(uiZoomToSelection(context));
70964 controls.append("div").attr("class", "map-control geolocate-control").call(uiGeolocate(context));
70965 controlsWrap.on("wheel.mapControls", function(d3_event) {
70966 if (!d3_event.deltaX) {
70967 controlsWrap.node().scrollTop += d3_event.deltaY;
70970 var panes = overMap.append("div").attr("class", "map-panes");
70972 uiPaneBackground(context),
70973 uiPaneMapData(context),
70974 uiPaneIssues(context),
70975 uiPanePreferences(context),
70976 uiPaneHelp(context)
70978 uiPanes.forEach(function(pane) {
70979 controls.append("div").attr("class", "map-control map-pane-control " + pane.id + "-control").call(pane.renderToggleButton);
70980 panes.call(pane.renderPane);
70982 ui.info = uiInfo(context);
70983 overMap.call(ui.info);
70984 overMap.append("div").attr("class", "photoviewer").classed("al", true).classed("hide", true).call(ui.photoviewer);
70985 overMap.append("div").attr("class", "attribution-wrap").attr("dir", "ltr").call(uiAttribution(context));
70986 var about = content.append("div").attr("class", "map-footer");
70987 about.append("div").attr("class", "api-status").call(uiStatus(context));
70988 var footer = about.append("div").attr("class", "map-footer-bar fillD");
70989 footer.append("div").attr("class", "flash-wrap footer-hide");
70990 var footerWrap = footer.append("div").attr("class", "main-footer-wrap footer-show");
70991 footerWrap.append("div").attr("class", "scale-block").call(uiScale(context));
70992 var aboutList = footerWrap.append("div").attr("class", "info-block").append("ul").attr("class", "map-footer-list");
70993 aboutList.append("li").attr("class", "user-list").call(uiContributors(context));
70994 var apiConnections = context.connection().apiConnections();
70995 if (apiConnections && apiConnections.length > 1) {
70996 aboutList.append("li").attr("class", "source-switch").call(
70997 uiSourceSwitch(context).keys(apiConnections)
71000 aboutList.append("li").attr("class", "issues-info").call(uiIssuesInfo(context));
71001 aboutList.append("li").attr("class", "feature-warning").call(uiFeatureInfo(context));
71002 var issueLinks = aboutList.append("li");
71003 issueLinks.append("a").attr("target", "_blank").attr("href", "https://github.com/openstreetmap/iD/issues").attr("aria-label", _t("report_a_bug")).call(svgIcon("#iD-icon-bug", "light")).call(uiTooltip().title(() => _t.append("report_a_bug")).placement("top"));
71004 issueLinks.append("a").attr("target", "_blank").attr("href", "https://github.com/openstreetmap/iD/blob/develop/CONTRIBUTING.md#translating").attr("aria-label", _t("help_translate")).call(svgIcon("#iD-icon-translate", "light")).call(uiTooltip().title(() => _t.append("help_translate")).placement("top"));
71005 aboutList.append("li").attr("class", "version").call(uiVersion(context));
71006 if (!context.embed()) {
71007 aboutList.call(uiAccount(context));
71010 map2.redrawEnable(true);
71011 ui.hash = behaviorHash(context);
71013 if (!ui.hash.hadLocation) {
71014 map2.centerZoom([0, 0], 2);
71016 window.onbeforeunload = function() {
71017 return context.save();
71019 window.onunload = function() {
71020 context.history().unlock();
71022 select_default2(window).on("resize.editor", function() {
71025 var panPixels = 80;
71026 context.keybinding().on("\u232B", function(d3_event) {
71027 d3_event.preventDefault();
71028 }).on([_t("sidebar.key"), "`", "\xB2", "@"], ui.sidebar.toggle).on("\u2190", pan([panPixels, 0])).on("\u2191", pan([0, panPixels])).on("\u2192", pan([-panPixels, 0])).on("\u2193", pan([0, -panPixels])).on(uiCmd("\u2325\u2190"), pan([map2.dimensions()[0], 0])).on(uiCmd("\u2325\u2191"), pan([0, map2.dimensions()[1]])).on(uiCmd("\u2325\u2192"), pan([-map2.dimensions()[0], 0])).on(uiCmd("\u2325\u2193"), pan([0, -map2.dimensions()[1]])).on(uiCmd("\u2318" + _t("background.key")), function quickSwitch(d3_event) {
71030 d3_event.stopImmediatePropagation();
71031 d3_event.preventDefault();
71033 var previousBackground = context.background().findSource(corePreferences("background-last-used-toggle"));
71034 if (previousBackground) {
71035 var currentBackground = context.background().baseLayerSource();
71036 corePreferences("background-last-used-toggle", currentBackground.id);
71037 corePreferences("background-last-used", previousBackground.id);
71038 context.background().baseLayerSource(previousBackground);
71040 }).on(_t("area_fill.wireframe.key"), function toggleWireframe(d3_event) {
71041 d3_event.preventDefault();
71042 d3_event.stopPropagation();
71043 context.map().toggleWireframe();
71044 }).on(uiCmd("\u2325" + _t("area_fill.wireframe.key")), function toggleOsmData(d3_event) {
71045 d3_event.preventDefault();
71046 d3_event.stopPropagation();
71047 var mode = context.mode();
71048 if (mode && /^draw/.test(mode.id))
71050 var layer = context.layers().layer("osm");
71052 layer.enabled(!layer.enabled());
71053 if (!layer.enabled()) {
71054 context.enter(modeBrowse(context));
71057 }).on(_t("map_data.highlight_edits.key"), function toggleHighlightEdited(d3_event) {
71058 d3_event.preventDefault();
71059 context.map().toggleHighlightEdited();
71061 context.on("enter.editor", function(entered) {
71062 container.classed("mode-" + entered.id, true);
71063 }).on("exit.editor", function(exited) {
71064 container.classed("mode-" + exited.id, false);
71066 context.enter(modeBrowse(context));
71067 if (!_initCounter++) {
71068 if (!ui.hash.startWalkthrough) {
71069 context.container().call(uiSplash(context)).call(uiRestore(context));
71071 context.container().call(ui.shortcuts);
71073 var osm = context.connection();
71074 var auth = uiLoading(context).message(_t.html("loading_auth")).blocking(true);
71076 osm.on("authLoading.ui", function() {
71077 context.container().call(auth);
71078 }).on("authDone.ui", function() {
71083 if (ui.hash.startWalkthrough) {
71084 ui.hash.startWalkthrough = false;
71085 context.container().call(uiIntro(context));
71088 return function(d3_event) {
71089 if (d3_event.shiftKey)
71091 if (context.container().select(".combobox").size())
71093 d3_event.preventDefault();
71094 context.map().pan(d, 100);
71100 ui.ensureLoaded = () => {
71102 return _loadPromise;
71103 return _loadPromise = Promise.all([
71104 // must have strings and presets before loading the UI
71105 _mainLocalizer.ensureLoaded(),
71106 _mainPresetIndex.ensureLoaded()
71108 if (!context.container().empty())
71109 render(context.container());
71110 }).catch((err) => console.error(err));
71112 ui.restart = function() {
71113 context.keybinding().clear();
71114 _loadPromise = null;
71115 context.container().selectAll("*").remove();
71118 ui.lastPointerType = function() {
71119 return _lastPointerType;
71121 ui.svgDefs = svgDefs(context);
71122 ui.flash = uiFlash(context);
71123 ui.sidebar = uiSidebar(context);
71124 ui.photoviewer = uiPhotoviewer(context);
71125 ui.shortcuts = uiShortcuts(context);
71126 ui.onResize = function(withPan) {
71127 var map2 = context.map();
71128 var mapDimensions = utilGetDimensions(context.container().select(".main-content"), true);
71129 utilGetDimensions(context.container().select(".sidebar"), true);
71130 if (withPan !== void 0) {
71131 map2.redrawEnable(false);
71133 map2.redrawEnable(true);
71135 map2.dimensions(mapDimensions);
71136 ui.photoviewer.onMapResize();
71137 ui.checkOverflow(".top-toolbar");
71138 ui.checkOverflow(".map-footer-bar");
71139 var resizeWindowEvent = document.createEvent("Event");
71140 resizeWindowEvent.initEvent("resizeWindow", true, true);
71141 document.dispatchEvent(resizeWindowEvent);
71143 ui.checkOverflow = function(selector, reset) {
71145 delete _needWidth[selector];
71147 var selection2 = context.container().select(selector);
71148 if (selection2.empty())
71150 var scrollWidth = selection2.property("scrollWidth");
71151 var clientWidth = selection2.property("clientWidth");
71152 var needed = _needWidth[selector] || scrollWidth;
71153 if (scrollWidth > clientWidth) {
71154 selection2.classed("narrow", true);
71155 if (!_needWidth[selector]) {
71156 _needWidth[selector] = scrollWidth;
71158 } else if (scrollWidth >= needed) {
71159 selection2.classed("narrow", false);
71162 ui.togglePanes = function(showPane) {
71163 var hidePanes = context.container().selectAll(".map-pane.shown");
71164 var side = _mainLocalizer.textDirection() === "ltr" ? "right" : "left";
71165 hidePanes.classed("shown", false).classed("hide", true);
71166 context.container().selectAll(".map-pane-control button").classed("active", false);
71168 hidePanes.classed("shown", false).classed("hide", true).style(side, "-500px");
71169 context.container().selectAll("." + showPane.attr("pane") + "-control button").classed("active", true);
71170 showPane.classed("shown", true).classed("hide", false);
71171 if (hidePanes.empty()) {
71172 showPane.style(side, "-500px").transition().duration(200).style(side, "0px");
71174 showPane.style(side, "0px");
71177 hidePanes.classed("shown", true).classed("hide", false).style(side, "0px").transition().duration(200).style(side, "-500px").on("end", function() {
71178 select_default2(this).classed("shown", false).classed("hide", true);
71182 var _editMenu = uiEditMenu(context);
71183 ui.editMenu = function() {
71186 ui.showEditMenu = function(anchorPoint, triggerType, operations) {
71187 ui.closeEditMenu();
71188 if (!operations && context.mode().operations)
71189 operations = context.mode().operations();
71190 if (!operations || !operations.length)
71192 if (!context.map().editableDataEnabled())
71194 var surfaceNode = context.surface().node();
71195 if (surfaceNode.focus) {
71196 surfaceNode.focus();
71198 operations.forEach(function(operation) {
71199 if (operation.point)
71200 operation.point(anchorPoint);
71202 _editMenu.anchorLoc(anchorPoint).triggerType(triggerType).operations(operations);
71203 context.map().supersurface.call(_editMenu);
71205 ui.closeEditMenu = function() {
71206 context.map().supersurface.select(".edit-menu").remove();
71208 var _saveLoading = select_default2(null);
71209 context.uploader().on("saveStarted.ui", function() {
71210 _saveLoading = uiLoading(context).message(_t.html("save.uploading")).blocking(true);
71211 context.container().call(_saveLoading);
71212 }).on("saveEnded.ui", function() {
71213 _saveLoading.close();
71214 _saveLoading = select_default2(null);
71219 // modules/core/context.js
71220 function coreContext() {
71221 const dispatch10 = dispatch_default("enter", "exit", "change");
71222 let context = utilRebind({}, dispatch10, "on");
71223 let _deferred2 = /* @__PURE__ */ new Set();
71224 context.version = package_default.version;
71225 context.privacyVersion = "20201202";
71226 context.initialHashParams = window.location.hash ? utilStringQs(window.location.hash) : {};
71227 context.changeset = null;
71228 let _defaultChangesetComment = context.initialHashParams.comment;
71229 let _defaultChangesetSource = context.initialHashParams.source;
71230 let _defaultChangesetHashtags = context.initialHashParams.hashtags;
71231 context.defaultChangesetComment = function(val) {
71232 if (!arguments.length)
71233 return _defaultChangesetComment;
71234 _defaultChangesetComment = val;
71237 context.defaultChangesetSource = function(val) {
71238 if (!arguments.length)
71239 return _defaultChangesetSource;
71240 _defaultChangesetSource = val;
71243 context.defaultChangesetHashtags = function(val) {
71244 if (!arguments.length)
71245 return _defaultChangesetHashtags;
71246 _defaultChangesetHashtags = val;
71249 let _setsDocumentTitle = true;
71250 context.setsDocumentTitle = function(val) {
71251 if (!arguments.length)
71252 return _setsDocumentTitle;
71253 _setsDocumentTitle = val;
71256 let _documentTitleBase = document.title;
71257 context.documentTitleBase = function(val) {
71258 if (!arguments.length)
71259 return _documentTitleBase;
71260 _documentTitleBase = val;
71264 context.ui = () => _ui;
71265 context.lastPointerType = () => _ui.lastPointerType();
71266 let _keybinding = utilKeybinding("context");
71267 context.keybinding = () => _keybinding;
71268 select_default2(document).call(_keybinding);
71269 let _connection = services.osm;
71273 context.connection = () => _connection;
71274 context.history = () => _history;
71275 context.validator = () => _validator;
71276 context.uploader = () => _uploader;
71277 context.preauth = (options2) => {
71279 _connection.switch(options2);
71283 context.locale = function(locale2) {
71284 if (!arguments.length)
71285 return _mainLocalizer.localeCode();
71286 _mainLocalizer.preferredLocaleCodes(locale2);
71289 function afterLoad(cid, callback) {
71290 return (err, result) => {
71292 if (err.status === 400 || err.status === 401 || err.status === 403) {
71294 _connection.logout();
71297 if (typeof callback === "function") {
71301 } else if (_connection && _connection.getConnectionId() !== cid) {
71302 if (typeof callback === "function") {
71303 callback({ message: "Connection Switched", status: -1 });
71307 _history.merge(result.data, result.extent);
71308 if (typeof callback === "function") {
71309 callback(err, result);
71315 context.loadTiles = (projection2, callback) => {
71316 const handle = window.requestIdleCallback(() => {
71317 _deferred2.delete(handle);
71318 if (_connection && context.editableDataEnabled()) {
71319 const cid = _connection.getConnectionId();
71320 _connection.loadTiles(projection2, afterLoad(cid, callback));
71323 _deferred2.add(handle);
71325 context.loadTileAtLoc = (loc, callback) => {
71326 const handle = window.requestIdleCallback(() => {
71327 _deferred2.delete(handle);
71328 if (_connection && context.editableDataEnabled()) {
71329 const cid = _connection.getConnectionId();
71330 _connection.loadTileAtLoc(loc, afterLoad(cid, callback));
71333 _deferred2.add(handle);
71335 context.loadEntity = (entityID, callback) => {
71337 const cid = _connection.getConnectionId();
71338 _connection.loadEntity(entityID, afterLoad(cid, callback));
71339 _connection.loadEntityRelations(entityID, afterLoad(cid, callback));
71342 context.zoomToEntity = (entityID, zoomTo) => {
71343 context.loadEntity(entityID, (err, result) => {
71346 if (zoomTo !== false) {
71347 const entity = result.data.find((e) => e.id === entityID);
71349 _map.zoomTo(entity);
71353 _map.on("drawn.zoomToEntity", () => {
71354 if (!context.hasEntity(entityID))
71356 _map.on("drawn.zoomToEntity", null);
71357 context.on("enter.zoomToEntity", null);
71358 context.enter(modeSelect(context, [entityID]));
71360 context.on("enter.zoomToEntity", () => {
71361 if (_mode.id !== "browse") {
71362 _map.on("drawn.zoomToEntity", null);
71363 context.on("enter.zoomToEntity", null);
71367 let _minEditableZoom = 16;
71368 context.minEditableZoom = function(val) {
71369 if (!arguments.length)
71370 return _minEditableZoom;
71371 _minEditableZoom = val;
71373 _connection.tileZoom(val);
71377 context.maxCharsForTagKey = () => 255;
71378 context.maxCharsForTagValue = () => 255;
71379 context.maxCharsForRelationRole = () => 255;
71380 context.cleanTagKey = (val) => utilCleanOsmString(val, context.maxCharsForTagKey());
71381 context.cleanTagValue = (val) => utilCleanOsmString(val, context.maxCharsForTagValue());
71382 context.cleanRelationRole = (val) => utilCleanOsmString(val, context.maxCharsForRelationRole());
71383 let _inIntro = false;
71384 context.inIntro = function(val) {
71385 if (!arguments.length)
71390 context.save = () => {
71391 if (_inIntro || context.container().select(".modal").size())
71394 if (_mode && _mode.id === "save") {
71396 if (services.osm && services.osm.isChangesetInflight()) {
71397 _history.clearSaved();
71401 canSave = context.selectedIDs().every((id2) => {
71402 const entity = context.hasEntity(id2);
71403 return entity && !entity.isDegenerate();
71409 if (_history.hasChanges()) {
71410 return _t("save.unsaved_changes");
71413 context.debouncedSave = debounce_default(context.save, 350);
71414 function withDebouncedSave(fn) {
71415 return function() {
71416 const result = fn.apply(_history, arguments);
71417 context.debouncedSave();
71421 context.hasEntity = (id2) => _history.graph().hasEntity(id2);
71422 context.entity = (id2) => _history.graph().entity(id2);
71424 context.mode = () => _mode;
71425 context.enter = (newMode) => {
71428 dispatch10.call("exit", this, _mode);
71432 dispatch10.call("enter", this, _mode);
71434 context.selectedIDs = () => _mode && _mode.selectedIDs && _mode.selectedIDs() || [];
71435 context.activeID = () => _mode && _mode.activeID && _mode.activeID();
71436 let _selectedNoteID;
71437 context.selectedNoteID = function(noteID) {
71438 if (!arguments.length)
71439 return _selectedNoteID;
71440 _selectedNoteID = noteID;
71443 let _selectedErrorID;
71444 context.selectedErrorID = function(errorID) {
71445 if (!arguments.length)
71446 return _selectedErrorID;
71447 _selectedErrorID = errorID;
71450 context.install = (behavior) => context.surface().call(behavior);
71451 context.uninstall = (behavior) => context.surface().call(behavior.off);
71453 context.copyGraph = () => _copyGraph;
71455 context.copyIDs = function(val) {
71456 if (!arguments.length)
71459 _copyGraph = _history.graph();
71463 context.copyLonLat = function(val) {
71464 if (!arguments.length)
71465 return _copyLonLat;
71470 context.background = () => _background;
71472 context.features = () => _features;
71473 context.hasHiddenConnections = (id2) => {
71474 const graph = _history.graph();
71475 const entity = graph.entity(id2);
71476 return _features.hasHiddenConnections(entity, graph);
71479 context.photos = () => _photos;
71481 context.map = () => _map;
71482 context.layers = () => _map.layers();
71483 context.surface = () => _map.surface;
71484 context.editableDataEnabled = () => _map.editableDataEnabled();
71485 context.surfaceRect = () => _map.surface.node().getBoundingClientRect();
71486 context.editable = () => {
71487 const mode = context.mode();
71488 if (!mode || mode.id === "save")
71490 return _map.editableDataEnabled();
71492 let _debugFlags = {
71496 // label collision bounding boxes
71498 // imagery bounding polygons
71502 // downloaded data from osm
71504 context.debugFlags = () => _debugFlags;
71505 context.getDebug = (flag) => flag && _debugFlags[flag];
71506 context.setDebug = function(flag, val) {
71507 if (arguments.length === 1)
71509 _debugFlags[flag] = val;
71510 dispatch10.call("change");
71513 let _container = select_default2(null);
71514 context.container = function(val) {
71515 if (!arguments.length)
71518 _container.classed("ideditor", true);
71521 context.containerNode = function(val) {
71522 if (!arguments.length)
71523 return context.container().node();
71524 context.container(select_default2(val));
71528 context.embed = function(val) {
71529 if (!arguments.length)
71534 let _assetPath = "";
71535 context.assetPath = function(val) {
71536 if (!arguments.length)
71539 _mainFileFetcher.assetPath(val);
71542 let _assetMap = {};
71543 context.assetMap = function(val) {
71544 if (!arguments.length)
71547 _mainFileFetcher.assetMap(val);
71550 context.asset = (val) => {
71551 if (/^http(s)?:\/\//i.test(val))
71553 const filename = _assetPath + val;
71554 return _assetMap[filename] || filename;
71556 context.imagePath = (val) => context.asset(`img/${val}`);
71557 context.reset = context.flush = () => {
71558 context.debouncedSave.cancel();
71559 Array.from(_deferred2).forEach((handle) => {
71560 window.cancelIdleCallback(handle);
71561 _deferred2.delete(handle);
71563 Object.values(services).forEach((service) => {
71564 if (service && typeof service.reset === "function") {
71565 service.reset(context);
71568 context.changeset = null;
71569 _validator.reset();
71573 context.container().select(".inspector-wrap *").remove();
71576 context.projection = geoRawMercator();
71577 context.curtainProjection = geoRawMercator();
71578 context.init = () => {
71579 instantiateInternal();
71580 initializeDependents();
71582 function instantiateInternal() {
71583 _history = coreHistory(context);
71584 context.graph = _history.graph;
71585 context.pauseChangeDispatch = _history.pauseChangeDispatch;
71586 context.resumeChangeDispatch = _history.resumeChangeDispatch;
71587 context.perform = withDebouncedSave(_history.perform);
71588 context.replace = withDebouncedSave(_history.replace);
71589 context.pop = withDebouncedSave(_history.pop);
71590 context.overwrite = withDebouncedSave(_history.overwrite);
71591 context.undo = withDebouncedSave(_history.undo);
71592 context.redo = withDebouncedSave(_history.redo);
71593 _validator = coreValidator(context);
71594 _uploader = coreUploader(context);
71595 _background = rendererBackground(context);
71596 _features = rendererFeatures(context);
71597 _map = rendererMap(context);
71598 _photos = rendererPhotos(context);
71599 _ui = uiInit(context);
71601 function initializeDependents() {
71602 if (context.initialHashParams.presets) {
71603 _mainPresetIndex.addablePresetIDs(new Set(context.initialHashParams.presets.split(",")));
71605 if (context.initialHashParams.locale) {
71606 _mainLocalizer.preferredLocaleCodes(context.initialHashParams.locale);
71608 _mainLocalizer.ensureLoaded();
71609 _mainPresetIndex.ensureLoaded();
71610 _background.ensureLoaded();
71611 Object.values(services).forEach((service) => {
71612 if (service && typeof service.init === "function") {
71619 if (services.maprules && context.initialHashParams.maprules) {
71620 json_default(context.initialHashParams.maprules).then((mapcss) => {
71621 services.maprules.init();
71622 mapcss.forEach((mapcssSelector) => services.maprules.addRule(mapcssSelector));
71626 if (!context.container().empty()) {
71627 _ui.ensureLoaded().then(() => {
71628 _background.init();
71637 // modules/services/nsi.js
71638 var _nsiStatus = "loading";
71640 var buildingPreset = {
71641 "building/commercial": true,
71642 "building/government": true,
71643 "building/hotel": true,
71644 "building/retail": true,
71645 "building/office": true,
71646 "building/supermarket": true,
71647 "building/yes": true
71649 var notNames = /:(colou?r|type|forward|backward|left|right|etymology|pronunciation|wikipedia)$/i;
71650 var notBranches = /(coop|express|wireless|factory|outlet)/i;
71651 function setNsiSources() {
71652 const nsiVersion = package_default.dependencies["name-suggestion-index"] || package_default.devDependencies["name-suggestion-index"];
71653 const v = (0, import_vparse2.default)(nsiVersion);
71654 const vMinor = `${v.major}.${v.minor}`;
71655 const cdn = nsiCdnUrl.replace("{version}", vMinor);
71657 "nsi_data": cdn + "dist/nsi.min.json",
71658 "nsi_dissolved": cdn + "dist/dissolved.min.json",
71659 "nsi_features": cdn + "dist/featureCollection.min.json",
71660 "nsi_generics": cdn + "dist/genericWords.min.json",
71661 "nsi_presets": cdn + "dist/presets/nsi-id-presets.min.json",
71662 "nsi_replacements": cdn + "dist/replacements.min.json",
71663 "nsi_trees": cdn + "dist/trees.min.json"
71665 let fileMap = _mainFileFetcher.fileMap();
71666 for (const k in sources) {
71668 fileMap[k] = sources[k];
71671 function loadNsiPresets() {
71672 return Promise.all([
71673 _mainFileFetcher.get("nsi_presets"),
71674 _mainFileFetcher.get("nsi_features")
71675 ]).then((vals) => {
71676 Object.values(vals[0].presets).forEach((preset) => preset.suggestion = true);
71677 _mainPresetIndex.merge({
71678 presets: vals[0].presets,
71679 featureCollection: vals[1]
71683 function loadNsiData() {
71684 return Promise.all([
71685 _mainFileFetcher.get("nsi_data"),
71686 _mainFileFetcher.get("nsi_dissolved"),
71687 _mainFileFetcher.get("nsi_replacements"),
71688 _mainFileFetcher.get("nsi_trees")
71689 ]).then((vals) => {
71692 // the raw name-suggestion-index data
71693 dissolved: vals[1].dissolved,
71694 // list of dissolved items
71695 replacements: vals[2].replacements,
71696 // trivial old->new qid replacements
71697 trees: vals[3].trees,
71698 // metadata about trees, main tags
71699 kvt: /* @__PURE__ */ new Map(),
71700 // Map (k -> Map (v -> t) )
71701 qids: /* @__PURE__ */ new Map(),
71702 // Map (wd/wp tag values -> qids)
71703 ids: /* @__PURE__ */ new Map()
71704 // Map (id -> NSI item)
71706 const matcher = _nsi.matcher = new Matcher();
71707 matcher.buildMatchIndex(_nsi.data);
71708 matcher.itemLocation = /* @__PURE__ */ new Map();
71709 matcher.locationSets = /* @__PURE__ */ new Map();
71710 Object.keys(_nsi.data).forEach((tkv) => {
71711 const items = _nsi.data[tkv].items;
71712 if (!Array.isArray(items) || !items.length)
71714 items.forEach((item) => {
71715 if (matcher.itemLocation.has(item.id))
71717 const locationSetID = _sharedLocationManager.locationSetID(item.locationSet);
71718 matcher.itemLocation.set(item.id, locationSetID);
71719 if (matcher.locationSets.has(locationSetID))
71721 const fakeFeature = { id: locationSetID, properties: { id: locationSetID, area: 1 } };
71722 matcher.locationSets.set(locationSetID, fakeFeature);
71725 matcher.locationIndex = (bbox2) => {
71726 const validHere = _sharedLocationManager.locationSetsAt([bbox2[0], bbox2[1]]);
71727 const results = [];
71728 for (const [locationSetID, area] of Object.entries(validHere)) {
71729 const fakeFeature = matcher.locationSets.get(locationSetID);
71731 fakeFeature.properties.area = area;
71732 results.push(fakeFeature);
71737 Object.keys(_nsi.data).forEach((tkv) => {
71738 const category = _nsi.data[tkv];
71739 const parts = tkv.split("/", 3);
71740 const t = parts[0];
71741 const k = parts[1];
71742 const v = parts[2];
71743 let vmap = _nsi.kvt.get(k);
71745 vmap = /* @__PURE__ */ new Map();
71746 _nsi.kvt.set(k, vmap);
71749 const tree = _nsi.trees[t];
71750 const mainTag = tree.mainTag;
71751 const items = category.items || [];
71752 items.forEach((item) => {
71754 item.mainTag = mainTag;
71755 _nsi.ids.set(item.id, item);
71756 const wd = item.tags[mainTag];
71757 const wp = item.tags[mainTag.replace("wikidata", "wikipedia")];
71759 _nsi.qids.set(wd, wd);
71761 _nsi.qids.set(wp, wd);
71766 function gatherKVs(tags) {
71767 let primary = /* @__PURE__ */ new Set();
71768 let alternate = /* @__PURE__ */ new Set();
71769 Object.keys(tags).forEach((osmkey) => {
71770 const osmvalue = tags[osmkey];
71773 if (osmkey === "route_master")
71775 const vmap = _nsi.kvt.get(osmkey);
71778 if (vmap.get(osmvalue)) {
71779 primary.add(`${osmkey}/${osmvalue}`);
71780 } else if (osmvalue === "yes") {
71781 alternate.add(`${osmkey}/${osmvalue}`);
71784 const preset = _mainPresetIndex.matchTags(tags, "area");
71785 if (buildingPreset[preset.id]) {
71786 alternate.add("building/yes");
71788 return { primary, alternate };
71790 function identifyTree(tags) {
71793 Object.keys(tags).forEach((osmkey) => {
71796 const osmvalue = tags[osmkey];
71799 if (osmkey === "route_master")
71801 const vmap = _nsi.kvt.get(osmkey);
71804 if (osmvalue === "yes") {
71805 unknown = "unknown";
71807 t = vmap.get(osmvalue);
71810 return t || unknown || null;
71812 function gatherNames(tags) {
71813 const empty2 = { primary: /* @__PURE__ */ new Set(), alternate: /* @__PURE__ */ new Set() };
71814 let primary = /* @__PURE__ */ new Set();
71815 let alternate = /* @__PURE__ */ new Set();
71816 let foundSemi = false;
71817 let testNameFragments = false;
71819 let t = identifyTree(tags);
71822 if (t === "transit") {
71824 primary: /^network$/i,
71825 alternate: /^(operator|operator:\w+|network:\w+|\w+_name|\w+_name:\w+)$/i
71827 } else if (t === "flags") {
71829 primary: /^(flag:name|flag:name:\w+)$/i,
71830 alternate: /^(flag|flag:\w+|subject|subject:\w+)$/i
71831 // note: no `country`, we special-case it below
71833 } else if (t === "brands") {
71834 testNameFragments = true;
71836 primary: /^(name|name:\w+)$/i,
71837 alternate: /^(brand|brand:\w+|operator|operator:\w+|\w+_name|\w+_name:\w+)/i
71839 } else if (t === "operators") {
71840 testNameFragments = true;
71842 primary: /^(name|name:\w+|operator|operator:\w+)$/i,
71843 alternate: /^(brand|brand:\w+|\w+_name|\w+_name:\w+)/i
71846 testNameFragments = true;
71848 primary: /^(name|name:\w+)$/i,
71849 alternate: /^(brand|brand:\w+|network|network:\w+|operator|operator:\w+|\w+_name|\w+_name:\w+)/i
71852 if (tags.name && testNameFragments) {
71853 const nameParts = tags.name.split(/[\s\-\/,.]/);
71854 for (let split = nameParts.length; split > 0; split--) {
71855 const name = nameParts.slice(0, split).join(" ");
71859 Object.keys(tags).forEach((osmkey) => {
71860 const osmvalue = tags[osmkey];
71863 if (isNamelike(osmkey, "primary")) {
71864 if (/;/.test(osmvalue)) {
71867 primary.add(osmvalue);
71868 alternate.delete(osmvalue);
71870 } else if (!primary.has(osmvalue) && isNamelike(osmkey, "alternate")) {
71871 if (/;/.test(osmvalue)) {
71874 alternate.add(osmvalue);
71878 if (tags.man_made === "flagpole" && !primary.size && !alternate.size && !!tags.country) {
71879 const osmvalue = tags.country;
71880 if (/;/.test(osmvalue)) {
71883 alternate.add(osmvalue);
71889 return { primary, alternate };
71891 function isNamelike(osmkey, which) {
71892 if (osmkey === "old_name")
71894 return patterns2[which].test(osmkey) && !notNames.test(osmkey);
71897 function gatherTuples(tryKVs, tryNames) {
71899 ["primary", "alternate"].forEach((whichName) => {
71900 const arr = Array.from(tryNames[whichName]).sort((a, b) => b.length - a.length);
71901 arr.forEach((n2) => {
71902 ["primary", "alternate"].forEach((whichKV) => {
71903 tryKVs[whichKV].forEach((kv) => {
71904 const parts = kv.split("/", 2);
71905 const k = parts[0];
71906 const v = parts[1];
71907 tuples.push({ k, v, n: n2 });
71914 function _upgradeTags(tags, loc) {
71915 let newTags = Object.assign({}, tags);
71916 let changed = false;
71917 Object.keys(newTags).forEach((osmkey) => {
71918 const matchTag = osmkey.match(/^(\w+:)?wikidata$/);
71920 const prefix = matchTag[1] || "";
71921 const wd = newTags[osmkey];
71922 const replace = _nsi.replacements[wd];
71923 if (replace && replace.wikidata !== void 0) {
71925 if (replace.wikidata) {
71926 newTags[osmkey] = replace.wikidata;
71928 delete newTags[osmkey];
71931 if (replace && replace.wikipedia !== void 0) {
71933 const wpkey = `${prefix}wikipedia`;
71934 if (replace.wikipedia) {
71935 newTags[wpkey] = replace.wikipedia;
71937 delete newTags[wpkey];
71942 const isRouteMaster = tags.type === "route_master";
71943 const tryKVs = gatherKVs(tags);
71944 if (!tryKVs.primary.size && !tryKVs.alternate.size) {
71945 return changed ? { newTags, matched: null } : null;
71947 const tryNames = gatherNames(tags);
71948 const foundQID = _nsi.qids.get(tags.wikidata) || _nsi.qids.get(tags.wikipedia);
71950 tryNames.primary.add(foundQID);
71951 if (!tryNames.primary.size && !tryNames.alternate.size) {
71952 return changed ? { newTags, matched: null } : null;
71954 const tuples = gatherTuples(tryKVs, tryNames);
71955 for (let i2 = 0; i2 < tuples.length; i2++) {
71956 const tuple = tuples[i2];
71957 const hits = _nsi.matcher.match(tuple.k, tuple.v, tuple.n, loc);
71958 if (!hits || !hits.length)
71960 if (hits[0].match !== "primary" && hits[0].match !== "alternate")
71963 for (let j2 = 0; j2 < hits.length; j2++) {
71964 const hit = hits[j2];
71965 itemID = hit.itemID;
71966 if (_nsi.dissolved[itemID])
71968 item = _nsi.ids.get(itemID);
71971 const mainTag = item.mainTag;
71972 const itemQID = item.tags[mainTag];
71973 const notQID = newTags[`not:${mainTag}`];
71975 // Exceptions, skip this hit
71976 !itemQID || itemQID === notQID || // No `*:wikidata` or matched a `not:*:wikidata`
71977 newTags.office && !item.tags.office
71987 item = JSON.parse(JSON.stringify(item));
71988 const tkv = item.tkv;
71989 const parts = tkv.split("/", 3);
71990 const k = parts[1];
71991 const v = parts[2];
71992 const category = _nsi.data[tkv];
71993 const properties = category.properties || {};
71994 let preserveTags = item.preserveTags || properties.preserveTags || [];
71995 ["building", "emergency", "internet_access", "takeaway"].forEach((osmkey) => {
71997 preserveTags.push(`^${osmkey}$`);
71999 const regexes = preserveTags.map((s) => new RegExp(s, "i"));
72001 Object.keys(newTags).forEach((osmkey) => {
72002 if (regexes.some((regex) => regex.test(osmkey))) {
72003 keepTags[osmkey] = newTags[osmkey];
72006 _nsi.kvt.forEach((vmap, k2) => {
72007 if (newTags[k2] === "yes")
72008 delete newTags[k2];
72011 delete newTags.wikipedia;
72012 delete newTags.wikidata;
72014 Object.assign(newTags, item.tags, keepTags);
72015 if (isRouteMaster) {
72016 newTags.route_master = newTags.route;
72017 delete newTags.route;
72019 const origName = tags.name;
72020 const newName = newTags.name;
72021 if (newName && origName && newName !== origName && !newTags.branch) {
72022 const newNames = gatherNames(newTags);
72023 const newSet = /* @__PURE__ */ new Set([...newNames.primary, ...newNames.alternate]);
72024 const isMoved = newSet.has(origName);
72026 const nameParts = origName.split(/[\s\-\/,.]/);
72027 for (let split = nameParts.length; split > 0; split--) {
72028 const name = nameParts.slice(0, split).join(" ");
72029 const branch = nameParts.slice(split).join(" ");
72030 const nameHits = _nsi.matcher.match(k, v, name, loc);
72031 if (!nameHits || !nameHits.length)
72033 if (nameHits.some((hit) => hit.itemID === itemID)) {
72035 if (notBranches.test(branch)) {
72036 newTags.name = origName;
72038 const branchHits = _nsi.matcher.match(k, v, branch, loc);
72039 if (branchHits && branchHits.length) {
72040 if (branchHits[0].match === "primary" || branchHits[0].match === "alternate") {
72044 newTags.branch = branch;
72053 return { newTags, matched: item };
72055 return changed ? { newTags, matched: null } : null;
72057 function _isGenericName(tags) {
72058 const n2 = tags.name;
72061 const tryNames = { primary: /* @__PURE__ */ new Set([n2]), alternate: /* @__PURE__ */ new Set() };
72062 const tryKVs = gatherKVs(tags);
72063 if (!tryKVs.primary.size && !tryKVs.alternate.size)
72065 const tuples = gatherTuples(tryKVs, tryNames);
72066 for (let i2 = 0; i2 < tuples.length; i2++) {
72067 const tuple = tuples[i2];
72068 const hits = _nsi.matcher.match(tuple.k, tuple.v, tuple.n);
72069 if (hits && hits.length && hits[0].match === "excludeGeneric")
72074 var nsi_default = {
72076 // On init, start preparing the name-suggestion-index
72080 _mainPresetIndex.ensureLoaded().then(() => loadNsiPresets()).then(() => loadNsiData()).then(() => _nsiStatus = "ok").catch(() => _nsiStatus = "failed");
72083 // Reset is called when user saves data to OSM (does nothing here)
72088 // To let other code know how it's going...
72091 // `String`: 'loading', 'ok', 'failed'
72093 status: () => _nsiStatus,
72094 // `isGenericName()`
72095 // Is the `name` tag generic?
72098 // `tags`: `Object` containing the feature's OSM tags
72100 // `true` if it is generic, `false` if not
72102 isGenericName: (tags) => _isGenericName(tags),
72104 // Suggest tag upgrades.
72105 // This function will not modify the input tags, it makes a copy.
72108 // `tags`: `Object` containing the feature's OSM tags
72109 // `loc`: Location where this feature exists, as a [lon, lat]
72111 // `Object` containing the result, or `null` if no changes needed:
72113 // 'newTags': `Object` - The tags the the feature should have
72114 // 'matched': `Object` - The matched item
72117 upgradeTags: (tags, loc) => _upgradeTags(tags, loc),
72119 // Direct access to the NSI cache, useful for testing or breaking things
72122 // `Object`: the internal NSI cache
72127 // modules/services/kartaview.js
72128 var import_rbush8 = __toESM(require_rbush_min());
72129 var apibase2 = "https://kartaview.org";
72130 var maxResults = 1e3;
72132 var tiler4 = utilTiler().zoomExtent([tileZoom, tileZoom]).skipNullIsland(true);
72133 var dispatch6 = dispatch_default("loadedImages");
72134 var imgZoom = zoom_default2().extent([[0, 0], [320, 240]]).translateExtent([[0, 0], [320, 240]]).scaleExtent([1, 15]);
72136 var _oscSelectedImage;
72137 var _loadViewerPromise2;
72138 function abortRequest4(controller) {
72139 controller.abort();
72141 function maxPageAtZoom(z) {
72155 function loadTiles2(which, url, projection2) {
72156 var currZoom = Math.floor(geoScaleToZoom(projection2.scale()));
72157 var tiles = tiler4.getTiles(projection2);
72158 var cache = _oscCache[which];
72159 Object.keys(cache.inflight).forEach(function(k) {
72160 var wanted = tiles.find(function(tile) {
72161 return k.indexOf(tile.id + ",") === 0;
72164 abortRequest4(cache.inflight[k]);
72165 delete cache.inflight[k];
72168 tiles.forEach(function(tile) {
72169 loadNextTilePage(which, currZoom, url, tile);
72172 function loadNextTilePage(which, currZoom, url, tile) {
72173 var cache = _oscCache[which];
72174 var bbox2 = tile.extent.bbox();
72175 var maxPages = maxPageAtZoom(currZoom);
72176 var nextPage = cache.nextPage[tile.id] || 1;
72177 var params = utilQsString({
72180 // client_id: clientId,
72181 bbTopLeft: [bbox2.maxY, bbox2.minX].join(","),
72182 bbBottomRight: [bbox2.minY, bbox2.maxX].join(",")
72184 if (nextPage > maxPages)
72186 var id2 = tile.id + "," + String(nextPage);
72187 if (cache.loaded[id2] || cache.inflight[id2])
72189 var controller = new AbortController();
72190 cache.inflight[id2] = controller;
72193 signal: controller.signal,
72195 headers: { "Content-Type": "application/x-www-form-urlencoded" }
72197 json_default(url, options2).then(function(data) {
72198 cache.loaded[id2] = true;
72199 delete cache.inflight[id2];
72200 if (!data || !data.currentPageItems || !data.currentPageItems.length) {
72201 throw new Error("No Data");
72203 var features = data.currentPageItems.map(function(item) {
72204 var loc = [+item.lng, +item.lat];
72206 if (which === "images") {
72211 captured_at: item.shot_date || item.date_added,
72212 captured_by: item.username,
72213 imagePath: item.lth_name,
72214 sequence_id: item.sequence_id,
72215 sequence_index: +item.sequence_index
72217 var seq = _oscCache.sequences[d.sequence_id];
72219 seq = { rotation: 0, images: [] };
72220 _oscCache.sequences[d.sequence_id] = seq;
72222 seq.images[d.sequence_index] = d;
72223 _oscCache.images.forImageKey[d.key] = d;
72233 cache.rtree.load(features);
72234 if (data.currentPageItems.length === maxResults) {
72235 cache.nextPage[tile.id] = nextPage + 1;
72236 loadNextTilePage(which, currZoom, url, tile);
72238 cache.nextPage[tile.id] = Infinity;
72240 if (which === "images") {
72241 dispatch6.call("loadedImages");
72243 }).catch(function() {
72244 cache.loaded[id2] = true;
72245 delete cache.inflight[id2];
72248 function partitionViewport2(projection2) {
72249 var z = geoScaleToZoom(projection2.scale());
72250 var z2 = Math.ceil(z * 2) / 2 + 2.5;
72251 var tiler8 = utilTiler().zoomExtent([z2, z2]);
72252 return tiler8.getTiles(projection2).map(function(tile) {
72253 return tile.extent;
72256 function searchLimited2(limit, projection2, rtree) {
72257 limit = limit || 5;
72258 return partitionViewport2(projection2).reduce(function(result, extent) {
72259 var found = rtree.search(extent.bbox()).slice(0, limit).map(function(d) {
72262 return found.length ? result.concat(found) : result;
72265 var kartaview_default = {
72270 this.event = utilRebind(this, dispatch6, "on");
72272 reset: function() {
72274 Object.values(_oscCache.images.inflight).forEach(abortRequest4);
72277 images: { inflight: {}, loaded: {}, nextPage: {}, rtree: new import_rbush8.default(), forImageKey: {} },
72280 _oscSelectedImage = null;
72282 images: function(projection2) {
72284 return searchLimited2(limit, projection2, _oscCache.images.rtree);
72286 sequences: function(projection2) {
72287 var viewport = projection2.clipExtent();
72288 var min3 = [viewport[0][0], viewport[1][1]];
72289 var max3 = [viewport[1][0], viewport[0][1]];
72290 var bbox2 = geoExtent(projection2.invert(min3), projection2.invert(max3)).bbox();
72291 var sequenceKeys = {};
72292 _oscCache.images.rtree.search(bbox2).forEach(function(d) {
72293 sequenceKeys[d.data.sequence_id] = true;
72295 var lineStrings = [];
72296 Object.keys(sequenceKeys).forEach(function(sequenceKey) {
72297 var seq = _oscCache.sequences[sequenceKey];
72298 var images = seq && seq.images;
72301 type: "LineString",
72302 coordinates: images.map(function(d) {
72304 }).filter(Boolean),
72306 captured_at: images[0] ? images[0].captured_at : null,
72307 captured_by: images[0] ? images[0].captured_by : null,
72313 return lineStrings;
72315 cachedImage: function(imageKey) {
72316 return _oscCache.images.forImageKey[imageKey];
72318 loadImages: function(projection2) {
72319 var url = apibase2 + "/1.0/list/nearby-photos/";
72320 loadTiles2("images", url, projection2);
72322 ensureViewerLoaded: function(context) {
72323 if (_loadViewerPromise2)
72324 return _loadViewerPromise2;
72325 var wrap2 = context.container().select(".photoviewer").selectAll(".kartaview-wrapper").data([0]);
72327 var wrapEnter = wrap2.enter().append("div").attr("class", "photo-wrapper kartaview-wrapper").classed("hide", true).call(imgZoom.on("zoom", zoomPan)).on("dblclick.zoom", null);
72328 wrapEnter.append("div").attr("class", "photo-attribution fillD");
72329 var controlsEnter = wrapEnter.append("div").attr("class", "photo-controls-wrap").append("div").attr("class", "photo-controls");
72330 controlsEnter.append("button").on("click.back", step(-1)).text("\u25C4");
72331 controlsEnter.append("button").on("click.rotate-ccw", rotate(-90)).text("\u293F");
72332 controlsEnter.append("button").on("click.rotate-cw", rotate(90)).text("\u293E");
72333 controlsEnter.append("button").on("click.forward", step(1)).text("\u25BA");
72334 wrapEnter.append("div").attr("class", "kartaview-image-wrap");
72335 context.ui().photoviewer.on("resize.kartaview", function(dimensions) {
72336 imgZoom = zoom_default2().extent([[0, 0], dimensions]).translateExtent([[0, 0], dimensions]).scaleExtent([1, 15]).on("zoom", zoomPan);
72338 function zoomPan(d3_event) {
72339 var t = d3_event.transform;
72340 context.container().select(".photoviewer .kartaview-image-wrap").call(utilSetTransform, t.x, t.y, t.k);
72342 function rotate(deg) {
72343 return function() {
72344 if (!_oscSelectedImage)
72346 var sequenceKey = _oscSelectedImage.sequence_id;
72347 var sequence = _oscCache.sequences[sequenceKey];
72350 var r = sequence.rotation || 0;
72356 sequence.rotation = r;
72357 var wrap3 = context.container().select(".photoviewer .kartaview-wrapper");
72358 wrap3.transition().duration(100).call(imgZoom.transform, identity2);
72359 wrap3.selectAll(".kartaview-image").transition().duration(100).style("transform", "rotate(" + r + "deg)");
72362 function step(stepBy) {
72363 return function() {
72364 if (!_oscSelectedImage)
72366 var sequenceKey = _oscSelectedImage.sequence_id;
72367 var sequence = _oscCache.sequences[sequenceKey];
72370 var nextIndex = _oscSelectedImage.sequence_index + stepBy;
72371 var nextImage = sequence.images[nextIndex];
72374 context.map().centerEase(nextImage.loc);
72375 that.selectImage(context, nextImage.key);
72378 _loadViewerPromise2 = Promise.resolve();
72379 return _loadViewerPromise2;
72381 showViewer: function(context) {
72382 var viewer = context.container().select(".photoviewer").classed("hide", false);
72383 var isHidden = viewer.selectAll(".photo-wrapper.kartaview-wrapper.hide").size();
72385 viewer.selectAll(".photo-wrapper:not(.kartaview-wrapper)").classed("hide", true);
72386 viewer.selectAll(".photo-wrapper.kartaview-wrapper").classed("hide", false);
72390 hideViewer: function(context) {
72391 _oscSelectedImage = null;
72392 this.updateUrlImage(null);
72393 var viewer = context.container().select(".photoviewer");
72394 if (!viewer.empty())
72395 viewer.datum(null);
72396 viewer.classed("hide", true).selectAll(".photo-wrapper").classed("hide", true);
72397 context.container().selectAll(".viewfield-group, .sequence, .icon-sign").classed("currentView", false);
72398 return this.setStyles(context, null, true);
72400 selectImage: function(context, imageKey) {
72401 var d = this.cachedImage(imageKey);
72402 _oscSelectedImage = d;
72403 this.updateUrlImage(imageKey);
72404 var viewer = context.container().select(".photoviewer");
72405 if (!viewer.empty())
72407 this.setStyles(context, null, true);
72408 context.container().selectAll(".icon-sign").classed("currentView", false);
72411 var wrap2 = context.container().select(".photoviewer .kartaview-wrapper");
72412 var imageWrap = wrap2.selectAll(".kartaview-image-wrap");
72413 var attribution = wrap2.selectAll(".photo-attribution").text("");
72414 wrap2.transition().duration(100).call(imgZoom.transform, identity2);
72415 imageWrap.selectAll(".kartaview-image").remove();
72417 var sequence = _oscCache.sequences[d.sequence_id];
72418 var r = sequence && sequence.rotation || 0;
72419 imageWrap.append("img").attr("class", "kartaview-image").attr("src", apibase2 + "/" + d.imagePath).style("transform", "rotate(" + r + "deg)");
72420 if (d.captured_by) {
72421 attribution.append("a").attr("class", "captured_by").attr("target", "_blank").attr("href", "https://kartaview.org/user/" + encodeURIComponent(d.captured_by)).text("@" + d.captured_by);
72422 attribution.append("span").text("|");
72424 if (d.captured_at) {
72425 attribution.append("span").attr("class", "captured_at").text(localeDateString2(d.captured_at));
72426 attribution.append("span").text("|");
72428 attribution.append("a").attr("class", "image-link").attr("target", "_blank").attr("href", "https://kartaview.org/details/" + d.sequence_id + "/" + d.sequence_index).text("kartaview.org");
72431 function localeDateString2(s) {
72434 var options2 = { day: "numeric", month: "short", year: "numeric" };
72435 var d2 = new Date(s);
72436 if (isNaN(d2.getTime()))
72438 return d2.toLocaleDateString(_mainLocalizer.localeCode(), options2);
72441 getSelectedImage: function() {
72442 return _oscSelectedImage;
72444 getSequenceKeyForImage: function(d) {
72445 return d && d.sequence_id;
72447 // Updates the currently highlighted sequence and selected bubble.
72448 // Reset is only necessary when interacting with the viewport because
72449 // this implicitly changes the currently selected bubble/sequence
72450 setStyles: function(context, hovered, reset) {
72452 context.container().selectAll(".viewfield-group").classed("highlighted", false).classed("hovered", false).classed("currentView", false);
72453 context.container().selectAll(".sequence").classed("highlighted", false).classed("currentView", false);
72455 var hoveredImageKey = hovered && hovered.key;
72456 var hoveredSequenceKey = this.getSequenceKeyForImage(hovered);
72457 var hoveredSequence = hoveredSequenceKey && _oscCache.sequences[hoveredSequenceKey];
72458 var hoveredImageKeys = hoveredSequence && hoveredSequence.images.map(function(d) {
72461 var viewer = context.container().select(".photoviewer");
72462 var selected = viewer.empty() ? void 0 : viewer.datum();
72463 var selectedImageKey = selected && selected.key;
72464 var selectedSequenceKey = this.getSequenceKeyForImage(selected);
72465 var selectedSequence = selectedSequenceKey && _oscCache.sequences[selectedSequenceKey];
72466 var selectedImageKeys = selectedSequence && selectedSequence.images.map(function(d) {
72469 var highlightedImageKeys = utilArrayUnion(hoveredImageKeys, selectedImageKeys);
72470 context.container().selectAll(".layer-kartaview .viewfield-group").classed("highlighted", function(d) {
72471 return highlightedImageKeys.indexOf(d.key) !== -1;
72472 }).classed("hovered", function(d) {
72473 return d.key === hoveredImageKey;
72474 }).classed("currentView", function(d) {
72475 return d.key === selectedImageKey;
72477 context.container().selectAll(".layer-kartaview .sequence").classed("highlighted", function(d) {
72478 return d.properties.key === hoveredSequenceKey;
72479 }).classed("currentView", function(d) {
72480 return d.properties.key === selectedSequenceKey;
72482 context.container().selectAll(".layer-kartaview .viewfield-group .viewfield").attr("d", viewfieldPath);
72483 function viewfieldPath() {
72484 var d = this.parentNode.__data__;
72485 if (d.pano && d.key !== selectedImageKey) {
72486 return "M 8,13 m -10,0 a 10,10 0 1,0 20,0 a 10,10 0 1,0 -20,0";
72488 return "M 6,9 C 8,8.4 8,8.4 10,9 L 16,-2 C 12,-5 4,-5 0,-2 z";
72493 updateUrlImage: function(imageKey) {
72494 if (!window.mocha) {
72495 var hash = utilStringQs(window.location.hash);
72497 hash.photo = "kartaview/" + imageKey;
72501 window.location.replace("#" + utilQsString(hash, true));
72504 cache: function() {
72509 // node_modules/osm-auth/src/osm-auth.mjs
72510 var import_store = __toESM(require_store_legacy(), 1);
72511 function osmAuth(o) {
72513 oauth2.authenticated = function() {
72514 return !!token("oauth2_access_token");
72516 oauth2.logout = function() {
72517 token("oauth2_access_token", "");
72518 token("oauth_token", "");
72519 token("oauth_token_secret", "");
72520 token("oauth_request_token_secret", "");
72523 oauth2.authenticate = function(callback) {
72524 if (oauth2.authenticated()) {
72525 callback(null, oauth2);
72529 var url = o.url + "/oauth2/authorize?" + utilQsString2({
72530 client_id: o.client_id,
72531 redirect_uri: o.redirect_uri,
72532 response_type: "code",
72535 if (!o.singlepage) {
72541 ["left", screen.width / 2 - w / 2],
72542 ["top", screen.height / 2 - h / 2]
72543 ].map(function(x) {
72544 return x.join("=");
72546 var popup = window.open("about:blank", "oauth_window", settings);
72547 oauth2.popupWindow = popup;
72548 popup.location = url;
72550 var error = new Error("Popup was blocked");
72551 error.status = "popup-blocked";
72555 window.authComplete = function(url2) {
72556 var params = utilStringQs2(url2.split("?")[1]);
72557 getAccessToken(params.code);
72558 delete window.authComplete;
72560 function getAccessToken(auth_code) {
72561 var url2 = o.url + "/oauth2/token?" + utilQsString2({
72562 client_id: o.client_id,
72563 grant_type: "authorization_code",
72565 redirect_uri: o.redirect_uri,
72566 client_secret: o.client_secret
72568 oauth2.rawxhr("POST", url2, null, null, null, accessTokenDone);
72571 function accessTokenDone(err, xhr) {
72577 var access_token = JSON.parse(xhr.response);
72578 token("oauth2_access_token", access_token.access_token);
72579 callback(null, oauth2);
72582 oauth2.bringPopupWindowToFront = function() {
72583 var broughtPopupToFront = false;
72585 if (oauth2.popupWindow && !oauth2.popupWindow.closed) {
72586 oauth2.popupWindow.focus();
72587 broughtPopupToFront = true;
72591 return broughtPopupToFront;
72593 oauth2.bootstrapToken = function(auth_code, callback) {
72594 function getAccessToken(auth_code2) {
72595 var url = o.url + "/oauth2/token?" + utilQsString2({
72596 client_id: o.client_id,
72597 grant_type: "authorization_code",
72599 redirect_uri: o.redirect_uri,
72600 client_secret: o.client_secret
72602 oauth2.rawxhr("POST", url, null, null, null, accessTokenDone);
72605 function accessTokenDone(err, xhr) {
72611 var access_token = JSON.parse(xhr.response);
72612 token("oauth2_access_token", access_token.access_token);
72613 callback(null, oauth2);
72615 getAccessToken(auth_code);
72617 oauth2.xhr = function(options2, callback) {
72618 if (oauth2.authenticated()) {
72622 oauth2.authenticate(run);
72625 callback("not authenticated", null);
72630 var url = options2.prefix !== false ? o.url + options2.path : options2.path;
72631 return oauth2.rawxhr(
72634 token("oauth2_access_token"),
72640 function done(err, xhr) {
72643 } else if (xhr.responseXML) {
72644 callback(err, xhr.responseXML);
72646 callback(err, xhr.response);
72650 oauth2.rawxhr = function(method, url, access_token, data, headers, callback) {
72651 headers = headers || { "Content-Type": "application/x-www-form-urlencoded" };
72652 if (access_token) {
72653 headers.Authorization = "Bearer " + access_token;
72655 var xhr = new XMLHttpRequest();
72656 xhr.onreadystatechange = function() {
72657 if (4 === xhr.readyState && 0 !== xhr.status) {
72658 if (/^20\d$/.test(xhr.status)) {
72659 callback(null, xhr);
72661 callback(xhr, null);
72665 xhr.onerror = function(e) {
72668 xhr.open(method, url, true);
72669 for (var h in headers)
72670 xhr.setRequestHeader(h, headers[h]);
72674 oauth2.preauth = function(val) {
72675 if (val && val.access_token) {
72676 token("oauth2_access_token", val.access_token);
72680 oauth2.options = function(val) {
72681 if (!arguments.length)
72684 o.url = o.url || "https://www.openstreetmap.org";
72685 o.auto = o.auto || false;
72686 o.singlepage = o.singlepage || false;
72687 o.loading = o.loading || function() {
72689 o.done = o.done || function() {
72691 return oauth2.preauth(o);
72694 if (import_store.default.enabled) {
72695 token = function(x, y) {
72696 if (arguments.length === 1)
72697 return import_store.default.get(o.url + x);
72698 else if (arguments.length === 2)
72699 return import_store.default.set(o.url + x, y);
72703 token = function(x, y) {
72704 if (arguments.length === 1)
72705 return storage[o.url + x];
72706 else if (arguments.length === 2)
72707 return storage[o.url + x] = y;
72713 function utilQsString2(obj) {
72714 return Object.keys(obj).sort().map(function(key) {
72715 return encodeURIComponent(key) + "=" + encodeURIComponent(obj[key]);
72718 function utilStringQs2(str2) {
72720 while (i2 < str2.length && (str2[i2] === "?" || str2[i2] === "#"))
72722 str2 = str2.slice(i2);
72723 return str2.split("&").reduce(function(obj, pair2) {
72724 var parts = pair2.split("=");
72725 if (parts.length === 2) {
72726 obj[parts[0]] = decodeURIComponent(parts[1]);
72732 // modules/services/osm.js
72733 var import_rbush9 = __toESM(require_rbush_min());
72734 var tiler5 = utilTiler();
72735 var dispatch7 = dispatch_default("apiStatusChange", "authLoading", "authDone", "change", "loading", "loaded", "loadedNotes");
72736 var urlroot = osmApiConnections[0].url;
72737 var redirectPath = window.location.origin + window.location.pathname;
72738 var oauth = osmAuth({
72740 client_id: osmApiConnections[0].client_id,
72741 client_secret: osmApiConnections[0].client_secret,
72742 scope: "read_prefs write_prefs write_api read_gpx write_notes",
72743 redirect_uri: redirectPath + "land.html",
72744 loading: authLoading,
72747 var _apiConnections = osmApiConnections;
72748 var _imageryBlocklists = [/.*\.google(apis)?\..*\/(vt|kh)[\?\/].*([xyz]=.*){3}.*/];
72749 var _tileCache = { toLoad: {}, loaded: {}, inflight: {}, seen: {}, rtree: new import_rbush9.default() };
72750 var _noteCache = { toLoad: {}, loaded: {}, inflight: {}, inflightPost: {}, note: {}, closed: {}, rtree: new import_rbush9.default() };
72751 var _userCache = { toLoad: {}, user: {} };
72752 var _cachedApiStatus;
72753 var _changeset = {};
72754 var _deferred = /* @__PURE__ */ new Set();
72755 var _connectionID = 1;
72756 var _tileZoom4 = 16;
72757 var _noteZoom = 12;
72758 var _rateLimitError;
72759 var _userChangesets;
72762 var _maxWayNodes = 2e3;
72763 function authLoading() {
72764 dispatch7.call("authLoading");
72766 function authDone() {
72767 dispatch7.call("authDone");
72769 function abortRequest5(controllerOrXHR) {
72770 if (controllerOrXHR) {
72771 controllerOrXHR.abort();
72774 function hasInflightRequests(cache) {
72775 return Object.keys(cache.inflight).length;
72777 function abortUnwantedRequests4(cache, visibleTiles) {
72778 Object.keys(cache.inflight).forEach(function(k) {
72779 if (cache.toLoad[k])
72781 if (visibleTiles.find(function(tile) {
72782 return k === tile.id;
72785 abortRequest5(cache.inflight[k]);
72786 delete cache.inflight[k];
72789 function getLoc(attrs) {
72790 var lon = attrs.lon && attrs.lon.value;
72791 var lat = attrs.lat && attrs.lat.value;
72792 return [Number(lon), Number(lat)];
72794 function getNodes(obj) {
72795 var elems = obj.getElementsByTagName("nd");
72796 var nodes = new Array(elems.length);
72797 for (var i2 = 0, l = elems.length; i2 < l; i2++) {
72798 nodes[i2] = "n" + elems[i2].attributes.ref.value;
72802 function getNodesJSON(obj) {
72803 var elems = obj.nodes;
72804 var nodes = new Array(elems.length);
72805 for (var i2 = 0, l = elems.length; i2 < l; i2++) {
72806 nodes[i2] = "n" + elems[i2];
72810 function getTags(obj) {
72811 var elems = obj.getElementsByTagName("tag");
72813 for (var i2 = 0, l = elems.length; i2 < l; i2++) {
72814 var attrs = elems[i2].attributes;
72815 tags[attrs.k.value] = attrs.v.value;
72819 function getMembers(obj) {
72820 var elems = obj.getElementsByTagName("member");
72821 var members = new Array(elems.length);
72822 for (var i2 = 0, l = elems.length; i2 < l; i2++) {
72823 var attrs = elems[i2].attributes;
72825 id: attrs.type.value[0] + attrs.ref.value,
72826 type: attrs.type.value,
72827 role: attrs.role.value
72832 function getMembersJSON(obj) {
72833 var elems = obj.members;
72834 var members = new Array(elems.length);
72835 for (var i2 = 0, l = elems.length; i2 < l; i2++) {
72836 var attrs = elems[i2];
72838 id: attrs.type[0] + attrs.ref,
72845 function getVisible(attrs) {
72846 return !attrs.visible || attrs.visible.value !== "false";
72848 function parseComments(comments) {
72849 var parsedComments = [];
72850 for (var i2 = 0; i2 < comments.length; i2++) {
72851 var comment = comments[i2];
72852 if (comment.nodeName === "comment") {
72853 var childNodes = comment.childNodes;
72854 var parsedComment = {};
72855 for (var j2 = 0; j2 < childNodes.length; j2++) {
72856 var node = childNodes[j2];
72857 var nodeName = node.nodeName;
72858 if (nodeName === "#text")
72860 parsedComment[nodeName] = node.textContent;
72861 if (nodeName === "uid") {
72862 var uid = node.textContent;
72863 if (uid && !_userCache.user[uid]) {
72864 _userCache.toLoad[uid] = true;
72868 if (parsedComment) {
72869 parsedComments.push(parsedComment);
72873 return parsedComments;
72875 function encodeNoteRtree(note) {
72884 var jsonparsers = {
72885 node: function nodeData(obj, uid) {
72886 return new osmNode({
72888 visible: typeof obj.visible === "boolean" ? obj.visible : true,
72889 version: obj.version && obj.version.toString(),
72890 changeset: obj.changeset && obj.changeset.toString(),
72891 timestamp: obj.timestamp,
72893 uid: obj.uid && obj.uid.toString(),
72894 loc: [Number(obj.lon), Number(obj.lat)],
72898 way: function wayData(obj, uid) {
72899 return new osmWay({
72901 visible: typeof obj.visible === "boolean" ? obj.visible : true,
72902 version: obj.version && obj.version.toString(),
72903 changeset: obj.changeset && obj.changeset.toString(),
72904 timestamp: obj.timestamp,
72906 uid: obj.uid && obj.uid.toString(),
72908 nodes: getNodesJSON(obj)
72911 relation: function relationData(obj, uid) {
72912 return new osmRelation({
72914 visible: typeof obj.visible === "boolean" ? obj.visible : true,
72915 version: obj.version && obj.version.toString(),
72916 changeset: obj.changeset && obj.changeset.toString(),
72917 timestamp: obj.timestamp,
72919 uid: obj.uid && obj.uid.toString(),
72921 members: getMembersJSON(obj)
72924 user: function parseUser(obj, uid) {
72927 display_name: obj.display_name,
72928 account_created: obj.account_created,
72929 image_url: obj.img && obj.img.href,
72930 changesets_count: obj.changesets && obj.changesets.count && obj.changesets.count.toString() || "0",
72931 active_blocks: obj.blocks && obj.blocks.received && obj.blocks.received.active && obj.blocks.received.active.toString() || "0"
72935 function parseJSON(payload, callback, options2) {
72936 options2 = Object.assign({ skipSeen: true }, options2);
72938 return callback({ message: "No JSON", status: -1 });
72940 var json = payload;
72941 if (typeof json !== "object")
72942 json = JSON.parse(payload);
72943 if (!json.elements)
72944 return callback({ message: "No JSON", status: -1 });
72945 var children2 = json.elements;
72946 var handle = window.requestIdleCallback(function() {
72947 _deferred.delete(handle);
72950 for (var i2 = 0; i2 < children2.length; i2++) {
72951 result = parseChild(children2[i2]);
72953 results.push(result);
72955 callback(null, results);
72957 _deferred.add(handle);
72958 function parseChild(child) {
72959 var parser3 = jsonparsers[child.type];
72963 uid = osmEntity.id.fromOSM(child.type, child.id);
72964 if (options2.skipSeen) {
72965 if (_tileCache.seen[uid])
72967 _tileCache.seen[uid] = true;
72969 return parser3(child, uid);
72972 function parseUserJSON(payload, callback, options2) {
72973 options2 = Object.assign({ skipSeen: true }, options2);
72975 return callback({ message: "No JSON", status: -1 });
72977 var json = payload;
72978 if (typeof json !== "object")
72979 json = JSON.parse(payload);
72980 if (!json.users && !json.user)
72981 return callback({ message: "No JSON", status: -1 });
72982 var objs = json.users || [json];
72983 var handle = window.requestIdleCallback(function() {
72984 _deferred.delete(handle);
72987 for (var i2 = 0; i2 < objs.length; i2++) {
72988 result = parseObj(objs[i2]);
72990 results.push(result);
72992 callback(null, results);
72994 _deferred.add(handle);
72995 function parseObj(obj) {
72996 var uid = obj.user.id && obj.user.id.toString();
72997 if (options2.skipSeen && _userCache.user[uid]) {
72998 delete _userCache.toLoad[uid];
73001 var user = jsonparsers.user(obj.user, uid);
73002 _userCache.user[uid] = user;
73003 delete _userCache.toLoad[uid];
73008 node: function nodeData2(obj, uid) {
73009 var attrs = obj.attributes;
73010 return new osmNode({
73012 visible: getVisible(attrs),
73013 version: attrs.version.value,
73014 changeset: attrs.changeset && attrs.changeset.value,
73015 timestamp: attrs.timestamp && attrs.timestamp.value,
73016 user: attrs.user && attrs.user.value,
73017 uid: attrs.uid && attrs.uid.value,
73018 loc: getLoc(attrs),
73022 way: function wayData2(obj, uid) {
73023 var attrs = obj.attributes;
73024 return new osmWay({
73026 visible: getVisible(attrs),
73027 version: attrs.version.value,
73028 changeset: attrs.changeset && attrs.changeset.value,
73029 timestamp: attrs.timestamp && attrs.timestamp.value,
73030 user: attrs.user && attrs.user.value,
73031 uid: attrs.uid && attrs.uid.value,
73032 tags: getTags(obj),
73033 nodes: getNodes(obj)
73036 relation: function relationData2(obj, uid) {
73037 var attrs = obj.attributes;
73038 return new osmRelation({
73040 visible: getVisible(attrs),
73041 version: attrs.version.value,
73042 changeset: attrs.changeset && attrs.changeset.value,
73043 timestamp: attrs.timestamp && attrs.timestamp.value,
73044 user: attrs.user && attrs.user.value,
73045 uid: attrs.uid && attrs.uid.value,
73046 tags: getTags(obj),
73047 members: getMembers(obj)
73050 note: function parseNote(obj, uid) {
73051 var attrs = obj.attributes;
73052 var childNodes = obj.childNodes;
73055 props.loc = getLoc(attrs);
73056 var coincident = false;
73057 var epsilon3 = 1e-5;
73060 props.loc = geoVecAdd(props.loc, [epsilon3, epsilon3]);
73062 var bbox2 = geoExtent(props.loc).bbox();
73063 coincident = _noteCache.rtree.search(bbox2).length;
73064 } while (coincident);
73065 for (var i2 = 0; i2 < childNodes.length; i2++) {
73066 var node = childNodes[i2];
73067 var nodeName = node.nodeName;
73068 if (nodeName === "#text")
73070 if (nodeName === "comments") {
73071 props[nodeName] = parseComments(node.childNodes);
73073 props[nodeName] = node.textContent;
73076 var note = new osmNote(props);
73077 var item = encodeNoteRtree(note);
73078 _noteCache.note[note.id] = note;
73079 _noteCache.rtree.insert(item);
73082 user: function parseUser2(obj, uid) {
73083 var attrs = obj.attributes;
73086 display_name: attrs.display_name && attrs.display_name.value,
73087 account_created: attrs.account_created && attrs.account_created.value,
73088 changesets_count: "0",
73091 var img = obj.getElementsByTagName("img");
73092 if (img && img[0] && img[0].getAttribute("href")) {
73093 user.image_url = img[0].getAttribute("href");
73095 var changesets = obj.getElementsByTagName("changesets");
73096 if (changesets && changesets[0] && changesets[0].getAttribute("count")) {
73097 user.changesets_count = changesets[0].getAttribute("count");
73099 var blocks = obj.getElementsByTagName("blocks");
73100 if (blocks && blocks[0]) {
73101 var received = blocks[0].getElementsByTagName("received");
73102 if (received && received[0] && received[0].getAttribute("active")) {
73103 user.active_blocks = received[0].getAttribute("active");
73106 _userCache.user[uid] = user;
73107 delete _userCache.toLoad[uid];
73111 function parseXML(xml, callback, options2) {
73112 options2 = Object.assign({ skipSeen: true }, options2);
73113 if (!xml || !xml.childNodes) {
73114 return callback({ message: "No XML", status: -1 });
73116 var root3 = xml.childNodes[0];
73117 var children2 = root3.childNodes;
73118 var handle = window.requestIdleCallback(function() {
73119 _deferred.delete(handle);
73122 for (var i2 = 0; i2 < children2.length; i2++) {
73123 result = parseChild(children2[i2]);
73125 results.push(result);
73127 callback(null, results);
73129 _deferred.add(handle);
73130 function parseChild(child) {
73131 var parser3 = parsers[child.nodeName];
73135 if (child.nodeName === "user") {
73136 uid = child.attributes.id.value;
73137 if (options2.skipSeen && _userCache.user[uid]) {
73138 delete _userCache.toLoad[uid];
73141 } else if (child.nodeName === "note") {
73142 uid = child.getElementsByTagName("id")[0].textContent;
73144 uid = osmEntity.id.fromOSM(child.nodeName, child.attributes.id.value);
73145 if (options2.skipSeen) {
73146 if (_tileCache.seen[uid])
73148 _tileCache.seen[uid] = true;
73151 return parser3(child, uid);
73154 function updateRtree4(item, replace) {
73155 _noteCache.rtree.remove(item, function isEql(a, b) {
73156 return a.data.id === b.data.id;
73159 _noteCache.rtree.insert(item);
73162 function wrapcb(thisArg, callback, cid) {
73163 return function(err, result) {
73165 if (err.status === 400 || err.status === 401 || err.status === 403) {
73168 return callback.call(thisArg, err);
73169 } else if (thisArg.getConnectionId() !== cid) {
73170 return callback.call(thisArg, { message: "Connection Switched", status: -1 });
73172 return callback.call(thisArg, err, result);
73176 var osm_default = {
73178 utilRebind(this, dispatch7, "on");
73180 reset: function() {
73181 Array.from(_deferred).forEach(function(handle) {
73182 window.cancelIdleCallback(handle);
73183 _deferred.delete(handle);
73186 _userChangesets = void 0;
73187 _userDetails = void 0;
73188 _rateLimitError = void 0;
73189 Object.values(_tileCache.inflight).forEach(abortRequest5);
73190 Object.values(_noteCache.inflight).forEach(abortRequest5);
73191 Object.values(_noteCache.inflightPost).forEach(abortRequest5);
73192 if (_changeset.inflight)
73193 abortRequest5(_changeset.inflight);
73194 _tileCache = { toLoad: {}, loaded: {}, inflight: {}, seen: {}, rtree: new import_rbush9.default() };
73195 _noteCache = { toLoad: {}, loaded: {}, inflight: {}, inflightPost: {}, note: {}, closed: {}, rtree: new import_rbush9.default() };
73196 _userCache = { toLoad: {}, user: {} };
73197 _cachedApiStatus = void 0;
73201 getConnectionId: function() {
73202 return _connectionID;
73204 getUrlRoot: function() {
73207 changesetURL: function(changesetID) {
73208 return urlroot + "/changeset/" + changesetID;
73210 changesetsURL: function(center, zoom) {
73211 var precision2 = Math.max(0, Math.ceil(Math.log(zoom) / Math.LN2));
73212 return urlroot + "/history#map=" + Math.floor(zoom) + "/" + center[1].toFixed(precision2) + "/" + center[0].toFixed(precision2);
73214 entityURL: function(entity) {
73215 return urlroot + "/" + entity.type + "/" + entity.osmId();
73217 historyURL: function(entity) {
73218 return urlroot + "/" + entity.type + "/" + entity.osmId() + "/history";
73220 userURL: function(username) {
73221 return urlroot + "/user/" + encodeURIComponent(username);
73223 noteURL: function(note) {
73224 return urlroot + "/note/" + note.id;
73226 noteReportURL: function(note) {
73227 return urlroot + "/reports/new?reportable_type=Note&reportable_id=" + note.id;
73229 // Generic method to load data from the OSM API
73230 // Can handle either auth or unauth calls.
73231 loadFromAPI: function(path, callback, options2) {
73232 options2 = Object.assign({ skipSeen: true }, options2);
73234 var cid = _connectionID;
73235 function done(err, payload) {
73236 if (that.getConnectionId() !== cid) {
73238 callback({ message: "Connection Switched", status: -1 });
73241 var isAuthenticated = that.authenticated();
73242 if (isAuthenticated && err && err.status && (err.status === 400 || err.status === 401 || err.status === 403)) {
73244 that.loadFromAPI(path, callback, options2);
73246 if (!isAuthenticated && !_rateLimitError && err && err.status && (err.status === 509 || err.status === 429)) {
73247 _rateLimitError = err;
73248 dispatch7.call("change");
73249 that.reloadApiStatus();
73250 } else if (err && _cachedApiStatus === "online" || !err && _cachedApiStatus !== "online") {
73251 that.reloadApiStatus();
73255 return callback(err);
73257 if (path.indexOf(".json") !== -1) {
73258 return parseJSON(payload, callback, options2);
73260 return parseXML(payload, callback, options2);
73266 if (this.authenticated()) {
73267 return oauth.xhr({ method: "GET", path }, done);
73269 var url = urlroot + path;
73270 var controller = new AbortController();
73272 if (path.indexOf(".json") !== -1) {
73277 fn(url, { signal: controller.signal }).then(function(data) {
73279 }).catch(function(err) {
73280 if (err.name === "AbortError")
73282 var match = err.message.match(/^\d{3}/);
73284 done({ status: +match[0], statusText: err.message });
73292 // Load a single entity by id (ways and relations use the `/full` call to include
73293 // nodes and members). Parent relations are not included, see `loadEntityRelations`.
73294 // GET /api/0.6/node/#id
73295 // GET /api/0.6/[way|relation]/#id/full
73296 loadEntity: function(id2, callback) {
73297 var type2 = osmEntity.id.type(id2);
73298 var osmID = osmEntity.id.toOSM(id2);
73299 var options2 = { skipSeen: false };
73301 "/api/0.6/" + type2 + "/" + osmID + (type2 !== "node" ? "/full" : "") + ".json",
73302 function(err, entities) {
73304 callback(err, { data: entities });
73309 // Load a single entity with a specific version
73310 // GET /api/0.6/[node|way|relation]/#id/#version
73311 loadEntityVersion: function(id2, version, callback) {
73312 var type2 = osmEntity.id.type(id2);
73313 var osmID = osmEntity.id.toOSM(id2);
73314 var options2 = { skipSeen: false };
73316 "/api/0.6/" + type2 + "/" + osmID + "/" + version + ".json",
73317 function(err, entities) {
73319 callback(err, { data: entities });
73324 // Load the relations of a single entity with the given.
73325 // GET /api/0.6/[node|way|relation]/#id/relations
73326 loadEntityRelations: function(id2, callback) {
73327 var type2 = osmEntity.id.type(id2);
73328 var osmID = osmEntity.id.toOSM(id2);
73329 var options2 = { skipSeen: false };
73331 "/api/0.6/" + type2 + "/" + osmID + "/relations.json",
73332 function(err, entities) {
73334 callback(err, { data: entities });
73339 // Load multiple entities in chunks
73340 // (note: callback may be called multiple times)
73341 // Unlike `loadEntity`, child nodes and members are not fetched
73342 // GET /api/0.6/[nodes|ways|relations]?#parameters
73343 loadMultiple: function(ids, callback) {
73345 var groups = utilArrayGroupBy(utilArrayUniq(ids), osmEntity.id.type);
73346 Object.keys(groups).forEach(function(k) {
73347 var type2 = k + "s";
73348 var osmIDs = groups[k].map(function(id2) {
73349 return osmEntity.id.toOSM(id2);
73351 var options2 = { skipSeen: false };
73352 utilArrayChunk(osmIDs, 150).forEach(function(arr) {
73354 "/api/0.6/" + type2 + ".json?" + type2 + "=" + arr.join(),
73355 function(err, entities) {
73357 callback(err, { data: entities });
73364 // Create, upload, and close a changeset
73365 // PUT /api/0.6/changeset/create
73366 // POST /api/0.6/changeset/#id/upload
73367 // PUT /api/0.6/changeset/#id/close
73368 putChangeset: function(changeset, changes, callback) {
73369 var cid = _connectionID;
73370 if (_changeset.inflight) {
73371 return callback({ message: "Changeset already inflight", status: -2 }, changeset);
73372 } else if (_changeset.open) {
73373 return createdChangeset.call(this, null, _changeset.open);
73377 path: "/api/0.6/changeset/create",
73378 headers: { "Content-Type": "text/xml" },
73379 content: JXON.stringify(changeset.asJXON())
73381 _changeset.inflight = oauth.xhr(
73383 wrapcb(this, createdChangeset, cid)
73386 function createdChangeset(err, changesetID) {
73387 _changeset.inflight = null;
73389 return callback(err, changeset);
73391 _changeset.open = changesetID;
73392 changeset = changeset.update({ id: changesetID });
73395 path: "/api/0.6/changeset/" + changesetID + "/upload",
73396 headers: { "Content-Type": "text/xml" },
73397 content: JXON.stringify(changeset.osmChangeJXON(changes))
73399 _changeset.inflight = oauth.xhr(
73401 wrapcb(this, uploadedChangeset, cid)
73404 function uploadedChangeset(err) {
73405 _changeset.inflight = null;
73407 return callback(err, changeset);
73408 window.setTimeout(function() {
73409 callback(null, changeset);
73411 _changeset.open = null;
73412 if (this.getConnectionId() === cid) {
73415 path: "/api/0.6/changeset/" + changeset.id + "/close",
73416 headers: { "Content-Type": "text/xml" }
73423 // Load multiple users in chunks
73424 // (note: callback may be called multiple times)
73425 // GET /api/0.6/users?users=#id1,#id2,...,#idn
73426 loadUsers: function(uids, callback) {
73429 utilArrayUniq(uids).forEach(function(uid) {
73430 if (_userCache.user[uid]) {
73431 delete _userCache.toLoad[uid];
73432 cached.push(_userCache.user[uid]);
73437 if (cached.length || !this.authenticated()) {
73438 callback(void 0, cached);
73439 if (!this.authenticated())
73442 utilArrayChunk(toLoad, 150).forEach(function(arr) {
73444 { method: "GET", path: "/api/0.6/users.json?users=" + arr.join() },
73445 wrapcb(this, done, _connectionID)
73448 function done(err, payload) {
73450 return callback(err);
73451 var options2 = { skipSeen: true };
73452 return parseUserJSON(payload, function(err2, results) {
73454 return callback(err2);
73455 return callback(void 0, results);
73459 // Load a given user by id
73460 // GET /api/0.6/user/#id
73461 loadUser: function(uid, callback) {
73462 if (_userCache.user[uid] || !this.authenticated()) {
73463 delete _userCache.toLoad[uid];
73464 return callback(void 0, _userCache.user[uid]);
73467 { method: "GET", path: "/api/0.6/user/" + uid + ".json" },
73468 wrapcb(this, done, _connectionID)
73470 function done(err, payload) {
73472 return callback(err);
73473 var options2 = { skipSeen: true };
73474 return parseUserJSON(payload, function(err2, results) {
73476 return callback(err2);
73477 return callback(void 0, results[0]);
73481 // Load the details of the logged-in user
73482 // GET /api/0.6/user/details
73483 userDetails: function(callback) {
73484 if (_userDetails) {
73485 return callback(void 0, _userDetails);
73488 { method: "GET", path: "/api/0.6/user/details.json" },
73489 wrapcb(this, done, _connectionID)
73491 function done(err, payload) {
73493 return callback(err);
73494 var options2 = { skipSeen: false };
73495 return parseUserJSON(payload, function(err2, results) {
73497 return callback(err2);
73498 _userDetails = results[0];
73499 return callback(void 0, _userDetails);
73503 // Load previous changesets for the logged in user
73504 // GET /api/0.6/changesets?user=#id
73505 userChangesets: function(callback) {
73506 if (_userChangesets) {
73507 return callback(void 0, _userChangesets);
73510 wrapcb(this, gotDetails, _connectionID)
73512 function gotDetails(err, user) {
73514 return callback(err);
73517 { method: "GET", path: "/api/0.6/changesets?user=" + user.id },
73518 wrapcb(this, done, _connectionID)
73521 function done(err, xml) {
73523 return callback(err);
73525 _userChangesets = Array.prototype.map.call(
73526 xml.getElementsByTagName("changeset"),
73527 function(changeset) {
73528 return { tags: getTags(changeset) };
73530 ).filter(function(changeset) {
73531 var comment = changeset.tags.comment;
73532 return comment && comment !== "";
73534 return callback(void 0, _userChangesets);
73537 // Fetch the status of the OSM API
73538 // GET /api/capabilities
73539 status: function(callback) {
73540 var url = urlroot + "/api/capabilities";
73541 var errback = wrapcb(this, done, _connectionID);
73542 xml_default(url).then(function(data) {
73543 errback(null, data);
73544 }).catch(function(err) {
73545 errback(err.message);
73547 function done(err, xml) {
73549 return callback(err, null);
73551 var elements = xml.getElementsByTagName("blacklist");
73553 for (var i2 = 0; i2 < elements.length; i2++) {
73554 var regexString = elements[i2].getAttribute("regex");
73557 var regex = new RegExp(regexString);
73558 regexes.push(regex);
73563 if (regexes.length) {
73564 _imageryBlocklists = regexes;
73566 if (_rateLimitError) {
73567 return callback(_rateLimitError, "rateLimited");
73569 var waynodes = xml.getElementsByTagName("waynodes");
73570 var maxWayNodes = waynodes.length && parseInt(waynodes[0].getAttribute("maximum"), 10);
73571 if (maxWayNodes && isFinite(maxWayNodes))
73572 _maxWayNodes = maxWayNodes;
73573 var apiStatus = xml.getElementsByTagName("status");
73574 var val = apiStatus[0].getAttribute("api");
73575 return callback(void 0, val);
73579 // Calls `status` and dispatches an `apiStatusChange` event if the returned
73580 // status differs from the cached status.
73581 reloadApiStatus: function() {
73582 if (!this.throttledReloadApiStatus) {
73584 this.throttledReloadApiStatus = throttle_default(function() {
73585 that.status(function(err, status) {
73586 if (status !== _cachedApiStatus) {
73587 _cachedApiStatus = status;
73588 dispatch7.call("apiStatusChange", that, err, status);
73593 this.throttledReloadApiStatus();
73595 // Returns the maximum number of nodes a single way can have
73596 maxWayNodes: function() {
73597 return _maxWayNodes;
73599 // Load data (entities) from the API in tiles
73600 // GET /api/0.6/map?bbox=
73601 loadTiles: function(projection2, callback) {
73604 var tiles = tiler5.zoomExtent([_tileZoom4, _tileZoom4]).getTiles(projection2);
73605 var hadRequests = hasInflightRequests(_tileCache);
73606 abortUnwantedRequests4(_tileCache, tiles);
73607 if (hadRequests && !hasInflightRequests(_tileCache)) {
73608 dispatch7.call("loaded");
73610 tiles.forEach(function(tile) {
73611 this.loadTile(tile, callback);
73614 // Load a single data tile
73615 // GET /api/0.6/map?bbox=
73616 loadTile: function(tile, callback) {
73619 if (_tileCache.loaded[tile.id] || _tileCache.inflight[tile.id])
73621 if (!hasInflightRequests(_tileCache)) {
73622 dispatch7.call("loading");
73624 var path = "/api/0.6/map.json?bbox=";
73625 var options2 = { skipSeen: true };
73626 _tileCache.inflight[tile.id] = this.loadFromAPI(
73627 path + tile.extent.toParam(),
73631 function tileCallback(err, parsed) {
73632 delete _tileCache.inflight[tile.id];
73634 delete _tileCache.toLoad[tile.id];
73635 _tileCache.loaded[tile.id] = true;
73636 var bbox2 = tile.extent.bbox();
73637 bbox2.id = tile.id;
73638 _tileCache.rtree.insert(bbox2);
73641 callback(err, Object.assign({ data: parsed }, tile));
73643 if (!hasInflightRequests(_tileCache)) {
73644 dispatch7.call("loaded");
73648 isDataLoaded: function(loc) {
73649 var bbox2 = { minX: loc[0], minY: loc[1], maxX: loc[0], maxY: loc[1] };
73650 return _tileCache.rtree.collides(bbox2);
73652 // load the tile that covers the given `loc`
73653 loadTileAtLoc: function(loc, callback) {
73654 if (Object.keys(_tileCache.toLoad).length > 50)
73656 var k = geoZoomToScale(_tileZoom4 + 1);
73657 var offset = geoRawMercator().scale(k)(loc);
73658 var projection2 = geoRawMercator().transform({ k, x: -offset[0], y: -offset[1] });
73659 var tiles = tiler5.zoomExtent([_tileZoom4, _tileZoom4]).getTiles(projection2);
73660 tiles.forEach(function(tile) {
73661 if (_tileCache.toLoad[tile.id] || _tileCache.loaded[tile.id] || _tileCache.inflight[tile.id])
73663 _tileCache.toLoad[tile.id] = true;
73664 this.loadTile(tile, callback);
73667 // Load notes from the API in tiles
73668 // GET /api/0.6/notes?bbox=
73669 loadNotes: function(projection2, noteOptions) {
73670 noteOptions = Object.assign({ limit: 1e4, closed: 7 }, noteOptions);
73674 var path = "/api/0.6/notes?limit=" + noteOptions.limit + "&closed=" + noteOptions.closed + "&bbox=";
73675 var throttleLoadUsers = throttle_default(function() {
73676 var uids = Object.keys(_userCache.toLoad);
73679 that.loadUsers(uids, function() {
73682 var tiles = tiler5.zoomExtent([_noteZoom, _noteZoom]).getTiles(projection2);
73683 abortUnwantedRequests4(_noteCache, tiles);
73684 tiles.forEach(function(tile) {
73685 if (_noteCache.loaded[tile.id] || _noteCache.inflight[tile.id])
73687 var options2 = { skipSeen: false };
73688 _noteCache.inflight[tile.id] = that.loadFromAPI(
73689 path + tile.extent.toParam(),
73691 delete _noteCache.inflight[tile.id];
73693 _noteCache.loaded[tile.id] = true;
73695 throttleLoadUsers();
73696 dispatch7.call("loadedNotes");
73703 // POST /api/0.6/notes?params
73704 postNoteCreate: function(note, callback) {
73705 if (!this.authenticated()) {
73706 return callback({ message: "Not Authenticated", status: -3 }, note);
73708 if (_noteCache.inflightPost[note.id]) {
73709 return callback({ message: "Note update already inflight", status: -2 }, note);
73711 if (!note.loc[0] || !note.loc[1] || !note.newComment)
73713 var comment = note.newComment;
73714 if (note.newCategory && note.newCategory !== "None") {
73715 comment += " #" + note.newCategory;
73717 var path = "/api/0.6/notes?" + utilQsString({ lon: note.loc[0], lat: note.loc[1], text: comment });
73718 _noteCache.inflightPost[note.id] = oauth.xhr(
73719 { method: "POST", path },
73720 wrapcb(this, done, _connectionID)
73722 function done(err, xml) {
73723 delete _noteCache.inflightPost[note.id];
73725 return callback(err);
73727 this.removeNote(note);
73728 var options2 = { skipSeen: false };
73729 return parseXML(xml, function(err2, results) {
73731 return callback(err2);
73733 return callback(void 0, results[0]);
73739 // POST /api/0.6/notes/#id/comment?text=comment
73740 // POST /api/0.6/notes/#id/close?text=comment
73741 // POST /api/0.6/notes/#id/reopen?text=comment
73742 postNoteUpdate: function(note, newStatus, callback) {
73743 if (!this.authenticated()) {
73744 return callback({ message: "Not Authenticated", status: -3 }, note);
73746 if (_noteCache.inflightPost[note.id]) {
73747 return callback({ message: "Note update already inflight", status: -2 }, note);
73750 if (note.status !== "closed" && newStatus === "closed") {
73752 } else if (note.status !== "open" && newStatus === "open") {
73755 action = "comment";
73756 if (!note.newComment)
73759 var path = "/api/0.6/notes/" + note.id + "/" + action;
73760 if (note.newComment) {
73761 path += "?" + utilQsString({ text: note.newComment });
73763 _noteCache.inflightPost[note.id] = oauth.xhr(
73764 { method: "POST", path },
73765 wrapcb(this, done, _connectionID)
73767 function done(err, xml) {
73768 delete _noteCache.inflightPost[note.id];
73770 return callback(err);
73772 this.removeNote(note);
73773 if (action === "close") {
73774 _noteCache.closed[note.id] = true;
73775 } else if (action === "reopen") {
73776 delete _noteCache.closed[note.id];
73778 var options2 = { skipSeen: false };
73779 return parseXML(xml, function(err2, results) {
73781 return callback(err2);
73783 return callback(void 0, results[0]);
73788 /* connection options for source switcher (optional) */
73789 apiConnections: function(val) {
73790 if (!arguments.length)
73791 return _apiConnections;
73792 _apiConnections = val;
73795 switch: function(newOptions) {
73796 urlroot = newOptions.url;
73797 var oldOptions = utilObjectOmit(oauth.options(), "access_token");
73798 oauth.options(Object.assign(oldOptions, newOptions));
73800 this.userChangesets(function() {
73802 dispatch7.call("change");
73805 toggle: function(val) {
73809 isChangesetInflight: function() {
73810 return !!_changeset.inflight;
73812 // get/set cached data
73813 // This is used to save/restore the state when entering/exiting the walkthrough
73814 // Also used for testing purposes.
73815 caches: function(obj) {
73816 function cloneCache(source) {
73818 Object.keys(source).forEach(function(k) {
73819 if (k === "rtree") {
73820 target.rtree = new import_rbush9.default().fromJSON(source.rtree.toJSON());
73821 } else if (k === "note") {
73823 Object.keys(source.note).forEach(function(id2) {
73824 target.note[id2] = osmNote(source.note[id2]);
73827 target[k] = JSON.parse(JSON.stringify(source[k]));
73832 if (!arguments.length) {
73834 tile: cloneCache(_tileCache),
73835 note: cloneCache(_noteCache),
73836 user: cloneCache(_userCache)
73839 if (obj === "get") {
73847 _tileCache = obj.tile;
73848 _tileCache.inflight = {};
73851 _noteCache = obj.note;
73852 _noteCache.inflight = {};
73853 _noteCache.inflightPost = {};
73856 _userCache = obj.user;
73860 logout: function() {
73861 _userChangesets = void 0;
73862 _userDetails = void 0;
73864 dispatch7.call("change");
73867 authenticated: function() {
73868 return oauth.authenticated();
73870 authenticate: function(callback) {
73872 var cid = _connectionID;
73873 _userChangesets = void 0;
73874 _userDetails = void 0;
73875 function done(err, res) {
73881 if (that.getConnectionId() !== cid) {
73883 callback({ message: "Connection Switched", status: -1 });
73886 _rateLimitError = void 0;
73887 dispatch7.call("change");
73889 callback(err, res);
73890 that.userChangesets(function() {
73893 oauth.authenticate(done);
73895 imageryBlocklists: function() {
73896 return _imageryBlocklists;
73898 tileZoom: function(val) {
73899 if (!arguments.length)
73904 // get all cached notes covering the viewport
73905 notes: function(projection2) {
73906 var viewport = projection2.clipExtent();
73907 var min3 = [viewport[0][0], viewport[1][1]];
73908 var max3 = [viewport[1][0], viewport[0][1]];
73909 var bbox2 = geoExtent(projection2.invert(min3), projection2.invert(max3)).bbox();
73910 return _noteCache.rtree.search(bbox2).map(function(d) {
73914 // get a single note from the cache
73915 getNote: function(id2) {
73916 return _noteCache.note[id2];
73918 // remove a single note from the cache
73919 removeNote: function(note) {
73920 if (!(note instanceof osmNote) || !note.id)
73922 delete _noteCache.note[note.id];
73923 updateRtree4(encodeNoteRtree(note), false);
73925 // replace a single note in the cache
73926 replaceNote: function(note) {
73927 if (!(note instanceof osmNote) || !note.id)
73929 _noteCache.note[note.id] = note;
73930 updateRtree4(encodeNoteRtree(note), true);
73933 // Get an array of note IDs closed during this session.
73934 // Used to populate `closed:note` changeset tag
73935 getClosedIDs: function() {
73936 return Object.keys(_noteCache.closed).sort();
73940 // modules/services/osm_wikibase.js
73941 var apibase3 = "https://wiki.openstreetmap.org/w/api.php";
73942 var _inflight2 = {};
73943 var _wikibaseCache = {};
73944 var _localeIDs = { en: false };
73945 var debouncedRequest = debounce_default(request, 500, { leading: false });
73946 function request(url, callback) {
73947 if (_inflight2[url])
73949 var controller = new AbortController();
73950 _inflight2[url] = controller;
73951 json_default(url, { signal: controller.signal }).then(function(result) {
73952 delete _inflight2[url];
73954 callback(null, result);
73955 }).catch(function(err) {
73956 delete _inflight2[url];
73957 if (err.name === "AbortError")
73960 callback(err.message);
73963 var osm_wikibase_default = {
73966 _wikibaseCache = {};
73969 reset: function() {
73970 Object.values(_inflight2).forEach(function(controller) {
73971 controller.abort();
73976 * Get the best value for the property, or undefined if not found
73977 * @param entity object from wikibase
73978 * @param property string e.g. 'P4' for image
73979 * @param langCode string e.g. 'fr' for French
73981 claimToValue: function(entity, property, langCode) {
73982 if (!entity.claims[property])
73984 var locale2 = _localeIDs[langCode];
73985 var preferredPick, localePick;
73986 entity.claims[property].forEach(function(stmt) {
73987 if (!preferredPick && stmt.rank === "preferred") {
73988 preferredPick = stmt;
73990 if (locale2 && stmt.qualifiers && stmt.qualifiers.P26 && stmt.qualifiers.P26[0].datavalue.value.id === locale2) {
73994 var result = localePick || preferredPick;
73996 var datavalue = result.mainsnak.datavalue;
73997 return datavalue.type === "wikibase-entityid" ? datavalue.value.id : datavalue.value;
74003 * Convert monolingual property into a key-value object (language -> value)
74004 * @param entity object from wikibase
74005 * @param property string e.g. 'P31' for monolingual wiki page title
74007 monolingualClaimToValueObj: function(entity, property) {
74008 if (!entity || !entity.claims[property])
74010 return entity.claims[property].reduce(function(acc, obj) {
74011 var value = obj.mainsnak.datavalue.value;
74012 acc[value.language] = value.text;
74016 toSitelink: function(key, value) {
74017 var result = value ? "Tag:" + key + "=" + value : "Key:" + key;
74018 return result.replace(/_/g, " ").trim();
74021 // Pass params object of the form:
74024 // value: 'string',
74025 // langCode: 'string'
74028 getEntity: function(params, callback) {
74029 var doRequest = params.debounce ? debouncedRequest : request;
74033 var rtypeSitelink = params.key === "type" && params.value ? ("Relation:" + params.value).replace(/_/g, " ").trim() : false;
74034 var keySitelink = params.key ? this.toSitelink(params.key) : false;
74035 var tagSitelink = params.key && params.value ? this.toSitelink(params.key, params.value) : false;
74036 var localeSitelink;
74037 if (params.langCodes) {
74038 params.langCodes.forEach(function(langCode) {
74039 if (_localeIDs[langCode] === void 0) {
74040 localeSitelink = ("Locale:" + langCode).replace(/_/g, " ").trim();
74041 titles.push(localeSitelink);
74045 if (rtypeSitelink) {
74046 if (_wikibaseCache[rtypeSitelink]) {
74047 result.rtype = _wikibaseCache[rtypeSitelink];
74049 titles.push(rtypeSitelink);
74053 if (_wikibaseCache[keySitelink]) {
74054 result.key = _wikibaseCache[keySitelink];
74056 titles.push(keySitelink);
74060 if (_wikibaseCache[tagSitelink]) {
74061 result.tag = _wikibaseCache[tagSitelink];
74063 titles.push(tagSitelink);
74066 if (!titles.length) {
74067 return callback(null, result);
74070 action: "wbgetentities",
74072 titles: titles.join("|"),
74073 languages: params.langCodes.join("|"),
74074 languagefallback: 1,
74077 // There is an MW Wikibase API bug https://phabricator.wikimedia.org/T212069
74078 // We shouldn't use v1 until it gets fixed, but should switch to it afterwards
74079 // formatversion: 2,
74081 var url = apibase3 + "?" + utilQsString(obj);
74082 doRequest(url, function(err, d) {
74085 } else if (!d.success || d.error) {
74086 callback(d.error.messages.map(function(v) {
74087 return v.html["*"];
74090 var localeID = false;
74091 Object.values(d.entities).forEach(function(res) {
74092 if (res.missing !== "") {
74093 var title = res.sitelinks.wiki.title;
74094 if (title === rtypeSitelink) {
74095 _wikibaseCache[rtypeSitelink] = res;
74096 result.rtype = res;
74097 } else if (title === keySitelink) {
74098 _wikibaseCache[keySitelink] = res;
74100 } else if (title === tagSitelink) {
74101 _wikibaseCache[tagSitelink] = res;
74103 } else if (title === localeSitelink) {
74106 console.log("Unexpected title " + title);
74110 if (localeSitelink) {
74111 that.addLocale(params.langCodes[0], localeID);
74113 callback(null, result);
74118 // Pass params object of the form:
74120 // key: 'string', // required
74121 // value: 'string' // optional
74124 // Get an result object used to display tag documentation
74126 // title: 'string',
74127 // description: 'string',
74128 // editURL: 'string',
74129 // imageURL: 'string',
74130 // wiki: { title: 'string', text: 'string', url: 'string' }
74133 getDocs: function(params, callback) {
74135 var langCodes = _mainLocalizer.localeCodes().map(function(code) {
74136 return code.toLowerCase();
74138 params.langCodes = langCodes;
74139 this.getEntity(params, function(err, data) {
74144 var entity = data.rtype || data.tag || data.key;
74146 callback("No entity");
74151 for (i2 in langCodes) {
74152 let code2 = langCodes[i2];
74153 if (entity.descriptions[code2] && entity.descriptions[code2].language === code2) {
74154 description = entity.descriptions[code2];
74158 if (!description && Object.values(entity.descriptions).length)
74159 description = Object.values(entity.descriptions)[0];
74161 title: entity.title,
74162 description: description ? description.value : "",
74163 descriptionLocaleCode: description ? description.language : "",
74164 editURL: "https://wiki.openstreetmap.org/wiki/" + entity.title
74166 if (entity.claims) {
74168 var image = that.claimToValue(entity, "P4", langCodes[0]);
74170 imageroot = "https://commons.wikimedia.org/w/index.php";
74172 image = that.claimToValue(entity, "P28", langCodes[0]);
74174 imageroot = "https://wiki.openstreetmap.org/w/index.php";
74177 if (imageroot && image) {
74178 result.imageURL = imageroot + "?" + utilQsString({
74179 title: "Special:Redirect/file/" + image,
74184 var rtypeWiki = that.monolingualClaimToValueObj(data.rtype, "P31");
74185 var tagWiki = that.monolingualClaimToValueObj(data.tag, "P31");
74186 var keyWiki = that.monolingualClaimToValueObj(data.key, "P31");
74187 var wikis = [rtypeWiki, tagWiki, keyWiki];
74188 for (i2 in wikis) {
74189 var wiki = wikis[i2];
74190 for (var j2 in langCodes) {
74191 var code = langCodes[j2];
74192 var referenceId = langCodes[0].split("-")[0] !== "en" && code.split("-")[0] === "en" ? "inspector.wiki_en_reference" : "inspector.wiki_reference";
74193 var info = getWikiInfo(wiki, code, referenceId);
74195 result.wiki = info;
74202 callback(null, result);
74203 function getWikiInfo(wiki2, langCode, tKey) {
74204 if (wiki2 && wiki2[langCode]) {
74206 title: wiki2[langCode],
74208 url: "https://wiki.openstreetmap.org/wiki/" + wiki2[langCode]
74214 addLocale: function(langCode, qid) {
74215 _localeIDs[langCode] = qid;
74217 apibase: function(val) {
74218 if (!arguments.length)
74225 // modules/services/streetside.js
74226 var import_rbush10 = __toESM(require_rbush_min());
74228 // modules/util/jsonp_request.js
74229 var jsonpCache = {};
74230 window.jsonpCache = jsonpCache;
74231 function jsonpRequest(url, callback) {
74233 abort: function() {
74236 if (window.JSONP_FIX) {
74237 if (window.JSONP_DELAY === 0) {
74238 callback(window.JSONP_FIX);
74240 var t = window.setTimeout(function() {
74241 callback(window.JSONP_FIX);
74242 }, window.JSONP_DELAY || 0);
74243 request3.abort = function() {
74244 window.clearTimeout(t);
74250 var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
74254 c += chars.charAt(Math.floor(Math.random() * 52));
74257 function create2(url2) {
74258 var e = url2.match(/callback=(\w+)/);
74259 var c = e ? e[1] : rand();
74260 jsonpCache[c] = function(data) {
74261 if (jsonpCache[c]) {
74266 function finalize() {
74267 delete jsonpCache[c];
74270 request3.abort = finalize;
74271 return "jsonpCache." + c;
74273 var cb = create2(url);
74274 var script = select_default2("head").append("script").attr("type", "text/javascript").attr("src", url.replace(/(\{|%7B)callback(\}|%7D)/, cb));
74278 // modules/services/streetside.js
74279 var bubbleApi = "https://dev.virtualearth.net/mapcontrol/HumanScaleServices/GetBubbles.ashx?";
74280 var streetsideImagesApi = "https://t.ssl.ak.tiles.virtualearth.net/tiles/";
74281 var bubbleAppKey = "AuftgJsO0Xs8Ts4M1xZUQJQXJNsvmh3IV8DkNieCiy3tCwCUMq76-WpkrBtNAuEm";
74282 var pannellumViewerCSS = "pannellum-streetside/pannellum.css";
74283 var pannellumViewerJS = "pannellum-streetside/pannellum.js";
74284 var maxResults2 = 2e3;
74285 var tileZoom2 = 16.5;
74286 var tiler6 = utilTiler().zoomExtent([tileZoom2, tileZoom2]).skipNullIsland(true);
74287 var dispatch8 = dispatch_default("loadedImages", "viewerChanged");
74290 var defaultHfov = 45;
74291 var _hires = false;
74292 var _resolution = 512;
74293 var _currScene = 0;
74295 var _pannellumViewer;
74296 var _sceneOptions = {
74297 showFullscreenCtrl: false,
74307 var _loadViewerPromise3;
74308 function abortRequest6(i2) {
74311 function localeTimestamp(s) {
74314 const options2 = { day: "numeric", month: "short", year: "numeric" };
74315 const d = new Date(s);
74316 if (isNaN(d.getTime()))
74318 return d.toLocaleString(_mainLocalizer.localeCode(), options2);
74320 function loadTiles3(which, url, projection2, margin) {
74321 const tiles = tiler6.margin(margin).getTiles(projection2);
74322 const cache = _ssCache[which];
74323 Object.keys(cache.inflight).forEach((k) => {
74324 const wanted = tiles.find((tile) => k.indexOf(tile.id + ",") === 0);
74326 abortRequest6(cache.inflight[k]);
74327 delete cache.inflight[k];
74330 tiles.forEach((tile) => loadNextTilePage2(which, url, tile));
74332 function loadNextTilePage2(which, url, tile) {
74333 const cache = _ssCache[which];
74334 const nextPage = cache.nextPage[tile.id] || 0;
74335 const id2 = tile.id + "," + String(nextPage);
74336 if (cache.loaded[id2] || cache.inflight[id2])
74338 cache.inflight[id2] = getBubbles(url, tile, (bubbles) => {
74339 cache.loaded[id2] = true;
74340 delete cache.inflight[id2];
74344 const features = bubbles.map((bubble) => {
74345 if (cache.points[bubble.id])
74347 const loc = [bubble.lo, bubble.la];
74352 captured_at: bubble.cd,
74353 captured_by: "microsoft",
74354 // nbn: bubble.nbn,
74355 // pbn: bubble.pbn,
74365 cache.points[bubble.id] = d;
74366 if (bubble.pr === void 0) {
74367 cache.leaders.push(bubble.id);
74376 }).filter(Boolean);
74377 cache.rtree.load(features);
74378 connectSequences();
74379 if (which === "bubbles") {
74380 dispatch8.call("loadedImages");
74384 function connectSequences() {
74385 let cache = _ssCache.bubbles;
74386 let keepLeaders = [];
74387 for (let i2 = 0; i2 < cache.leaders.length; i2++) {
74388 let bubble = cache.points[cache.leaders[i2]];
74390 let sequence = { key: bubble.key, bubbles: [] };
74391 let complete = false;
74393 sequence.bubbles.push(bubble);
74394 seen[bubble.key] = true;
74395 if (bubble.ne === void 0) {
74398 bubble = cache.points[bubble.ne];
74400 } while (bubble && !seen[bubble.key] && !complete);
74402 _ssCache.sequences[sequence.key] = sequence;
74403 for (let j2 = 0; j2 < sequence.bubbles.length; j2++) {
74404 sequence.bubbles[j2].sequenceKey = sequence.key;
74406 sequence.geojson = {
74407 type: "LineString",
74409 captured_at: sequence.bubbles[0] ? sequence.bubbles[0].captured_at : null,
74410 captured_by: sequence.bubbles[0] ? sequence.bubbles[0].captured_by : null,
74413 coordinates: sequence.bubbles.map((d) => d.loc)
74416 keepLeaders.push(cache.leaders[i2]);
74419 cache.leaders = keepLeaders;
74421 function getBubbles(url, tile, callback) {
74422 let rect = tile.extent.rectangle();
74423 let urlForRequest = url + utilQsString({
74429 appkey: bubbleAppKey,
74430 jsCallback: "{callback}"
74432 return jsonpRequest(urlForRequest, (data) => {
74433 if (!data || data.error) {
74440 function partitionViewport3(projection2) {
74441 let z = geoScaleToZoom(projection2.scale());
74442 let z2 = Math.ceil(z * 2) / 2 + 2.5;
74443 let tiler8 = utilTiler().zoomExtent([z2, z2]);
74444 return tiler8.getTiles(projection2).map((tile) => tile.extent);
74446 function searchLimited3(limit, projection2, rtree) {
74447 limit = limit || 5;
74448 return partitionViewport3(projection2).reduce((result, extent) => {
74449 let found = rtree.search(extent.bbox()).slice(0, limit).map((d) => d.data);
74450 return found.length ? result.concat(found) : result;
74453 function loadImage(imgInfo) {
74454 return new Promise((resolve) => {
74455 let img = new Image();
74456 img.onload = () => {
74457 let canvas = document.getElementById("ideditor-canvas" + imgInfo.face);
74458 let ctx = canvas.getContext("2d");
74459 ctx.drawImage(img, imgInfo.x, imgInfo.y);
74460 resolve({ imgInfo, status: "ok" });
74462 img.onerror = () => {
74463 resolve({ data: imgInfo, status: "error" });
74465 img.setAttribute("crossorigin", "");
74466 img.src = imgInfo.url;
74469 function loadCanvas(imageGroup) {
74470 return Promise.all(imageGroup.map(loadImage)).then((data) => {
74471 let canvas = document.getElementById("ideditor-canvas" + data[0].imgInfo.face);
74472 const which = { "01": 0, "02": 1, "03": 2, "10": 3, "11": 4, "12": 5 };
74473 let face = data[0].imgInfo.face;
74474 _sceneOptions.cubeMap[which[face]] = canvas.toDataURL("image/jpeg", 1);
74475 return { status: "loadCanvas for face " + data[0].imgInfo.face + "ok" };
74478 function loadFaces(faceGroup) {
74479 return Promise.all(faceGroup.map(loadCanvas)).then(() => {
74480 return { status: "loadFaces done" };
74483 function setupCanvas(selection2, reset) {
74485 selection2.selectAll("#ideditor-stitcher-canvases").remove();
74487 selection2.selectAll("#ideditor-stitcher-canvases").data([0]).enter().append("div").attr("id", "ideditor-stitcher-canvases").attr("display", "none").selectAll("canvas").data(["canvas01", "canvas02", "canvas03", "canvas10", "canvas11", "canvas12"]).enter().append("canvas").attr("id", (d) => "ideditor-" + d).attr("width", _resolution).attr("height", _resolution);
74489 function qkToXY(qk) {
74493 for (let i2 = qk.length; i2 > 0; i2--) {
74494 const key = qk[i2 - 1];
74495 x += +(key === "1" || key === "3") * scale;
74496 y += +(key === "2" || key === "3") * scale;
74501 function getQuadKeys() {
74502 let dim = _resolution / 256;
74763 } else if (dim === 8) {
74830 } else if (dim === 4) {
74859 var streetside_default = {
74861 * init() initialize streetside.
74867 this.event = utilRebind(this, dispatch8, "on");
74870 * reset() reset the cache.
74872 reset: function() {
74874 Object.values(_ssCache.bubbles.inflight).forEach(abortRequest6);
74877 bubbles: { inflight: {}, loaded: {}, nextPage: {}, rtree: new import_rbush10.default(), points: {}, leaders: [] },
74884 bubbles: function(projection2) {
74886 return searchLimited3(limit, projection2, _ssCache.bubbles.rtree);
74888 cachedImage: function(imageKey) {
74889 return _ssCache.bubbles.points[imageKey];
74891 sequences: function(projection2) {
74892 const viewport = projection2.clipExtent();
74893 const min3 = [viewport[0][0], viewport[1][1]];
74894 const max3 = [viewport[1][0], viewport[0][1]];
74895 const bbox2 = geoExtent(projection2.invert(min3), projection2.invert(max3)).bbox();
74898 _ssCache.bubbles.rtree.search(bbox2).forEach((d) => {
74899 const key = d.data.sequenceKey;
74900 if (key && !seen[key]) {
74902 results.push(_ssCache.sequences[key].geojson);
74910 loadBubbles: function(projection2, margin) {
74911 if (margin === void 0)
74913 loadTiles3("bubbles", bubbleApi, projection2, margin);
74915 viewer: function() {
74916 return _pannellumViewer;
74918 initViewer: function() {
74919 if (!window.pannellum)
74921 if (_pannellumViewer)
74924 const sceneID = _currScene.toString();
74926 "default": { firstScene: sceneID },
74929 options2.scenes[sceneID] = _sceneOptions;
74930 _pannellumViewer = window.pannellum.viewer("ideditor-viewer-streetside", options2);
74932 ensureViewerLoaded: function(context) {
74933 if (_loadViewerPromise3)
74934 return _loadViewerPromise3;
74935 let wrap2 = context.container().select(".photoviewer").selectAll(".ms-wrapper").data([0]);
74936 let wrapEnter = wrap2.enter().append("div").attr("class", "photo-wrapper ms-wrapper").classed("hide", true);
74938 let pointerPrefix = "PointerEvent" in window ? "pointer" : "mouse";
74939 wrapEnter.append("div").attr("id", "ideditor-viewer-streetside").on(pointerPrefix + "down.streetside", () => {
74940 select_default2(window).on(pointerPrefix + "move.streetside", () => {
74941 dispatch8.call("viewerChanged");
74943 }).on(pointerPrefix + "up.streetside pointercancel.streetside", () => {
74944 select_default2(window).on(pointerPrefix + "move.streetside", null);
74945 let t = timer((elapsed) => {
74946 dispatch8.call("viewerChanged");
74947 if (elapsed > 2e3) {
74951 }).append("div").attr("class", "photo-attribution fillD");
74952 let controlsEnter = wrapEnter.append("div").attr("class", "photo-controls-wrap").append("div").attr("class", "photo-controls");
74953 controlsEnter.append("button").on("click.back", step(-1)).text("\u25C4");
74954 controlsEnter.append("button").on("click.forward", step(1)).text("\u25BA");
74955 wrap2 = wrap2.merge(wrapEnter).call(setupCanvas, true);
74956 context.ui().photoviewer.on("resize.streetside", () => {
74957 if (_pannellumViewer) {
74958 _pannellumViewer.resize();
74961 _loadViewerPromise3 = new Promise((resolve, reject) => {
74962 let loadedCount = 0;
74963 function loaded() {
74965 if (loadedCount === 2)
74968 const head = select_default2("head");
74969 head.selectAll("#ideditor-streetside-viewercss").data([0]).enter().append("link").attr("id", "ideditor-streetside-viewercss").attr("rel", "stylesheet").attr("crossorigin", "anonymous").attr("href", context.asset(pannellumViewerCSS)).on("load.serviceStreetside", loaded).on("error.serviceStreetside", function() {
74972 head.selectAll("#ideditor-streetside-viewerjs").data([0]).enter().append("script").attr("id", "ideditor-streetside-viewerjs").attr("crossorigin", "anonymous").attr("src", context.asset(pannellumViewerJS)).on("load.serviceStreetside", loaded).on("error.serviceStreetside", function() {
74975 }).catch(function() {
74976 _loadViewerPromise3 = null;
74978 return _loadViewerPromise3;
74979 function step(stepBy) {
74981 let viewer = context.container().select(".photoviewer");
74982 let selected = viewer.empty() ? void 0 : viewer.datum();
74985 let nextID = stepBy === 1 ? selected.ne : selected.pr;
74986 let yaw = _pannellumViewer.getYaw();
74987 let ca = selected.ca + yaw;
74988 let origin = selected.loc;
74991 origin[0] + geoMetersToLon(meters / 5, origin[1]),
74995 origin[0] + geoMetersToLon(meters / 2, origin[1]),
74996 origin[1] + geoMetersToLat(meters)
74999 origin[0] - geoMetersToLon(meters / 2, origin[1]),
75000 origin[1] + geoMetersToLat(meters)
75003 origin[0] - geoMetersToLon(meters / 5, origin[1]),
75006 let poly = [p1, p2, p3, p4, p1];
75007 let angle2 = (stepBy === 1 ? ca : ca + 180) * (Math.PI / 180);
75008 poly = geoRotate(poly, -angle2, origin);
75009 let extent = poly.reduce((extent2, point2) => {
75010 return extent2.extend(geoExtent(point2));
75012 let minDist = Infinity;
75013 _ssCache.bubbles.rtree.search(extent.bbox()).forEach((d) => {
75014 if (d.data.key === selected.key)
75016 if (!geoPointInPolygon(d.data.loc, poly))
75018 let dist = geoVecLength(d.data.loc, selected.loc);
75019 let theta = selected.ca - d.data.ca;
75020 let minTheta = Math.min(Math.abs(theta), 360 - Math.abs(theta));
75021 if (minTheta > 20) {
75024 if (dist < minDist) {
75025 nextID = d.data.key;
75029 let nextBubble = nextID && that.cachedImage(nextID);
75032 context.map().centerEase(nextBubble.loc);
75033 that.selectImage(context, nextBubble.key).yaw(yaw).showViewer(context);
75037 yaw: function(yaw) {
75038 if (typeof yaw !== "number")
75040 _sceneOptions.yaw = yaw;
75046 showViewer: function(context) {
75047 let wrap2 = context.container().select(".photoviewer").classed("hide", false);
75048 let isHidden = wrap2.selectAll(".photo-wrapper.ms-wrapper.hide").size();
75050 wrap2.selectAll(".photo-wrapper:not(.ms-wrapper)").classed("hide", true);
75051 wrap2.selectAll(".photo-wrapper.ms-wrapper").classed("hide", false);
75058 hideViewer: function(context) {
75059 let viewer = context.container().select(".photoviewer");
75060 if (!viewer.empty())
75061 viewer.datum(null);
75062 viewer.classed("hide", true).selectAll(".photo-wrapper").classed("hide", true);
75063 context.container().selectAll(".viewfield-group, .sequence, .icon-sign").classed("currentView", false);
75064 this.updateUrlImage(null);
75065 return this.setStyles(context, null, true);
75070 selectImage: function(context, key) {
75072 let d = this.cachedImage(key);
75073 let viewer = context.container().select(".photoviewer");
75074 if (!viewer.empty())
75076 this.setStyles(context, null, true);
75077 let wrap2 = context.container().select(".photoviewer .ms-wrapper");
75078 let attribution = wrap2.selectAll(".photo-attribution").html("");
75079 wrap2.selectAll(".pnlm-load-box").style("display", "block");
75082 this.updateUrlImage(key);
75083 _sceneOptions.northOffset = d.ca;
75084 let line1 = attribution.append("div").attr("class", "attribution-row");
75085 const hiresDomId = utilUniqueDomId("streetside-hires");
75086 let label = line1.append("label").attr("for", hiresDomId).attr("class", "streetside-hires");
75087 label.append("input").attr("type", "checkbox").attr("id", hiresDomId).property("checked", _hires).on("click", (d3_event) => {
75088 d3_event.stopPropagation();
75090 _resolution = _hires ? 1024 : 512;
75091 wrap2.call(setupCanvas, true);
75093 yaw: _pannellumViewer.getYaw(),
75094 pitch: _pannellumViewer.getPitch(),
75095 hfov: _pannellumViewer.getHfov()
75097 _sceneOptions = Object.assign(_sceneOptions, viewstate);
75098 that.selectImage(context, d.key).showViewer(context);
75100 label.append("span").call(_t.append("streetside.hires"));
75101 let captureInfo = line1.append("div").attr("class", "attribution-capture-info");
75102 if (d.captured_by) {
75103 const yyyy = (/* @__PURE__ */ new Date()).getFullYear();
75104 captureInfo.append("a").attr("class", "captured_by").attr("target", "_blank").attr("href", "https://www.microsoft.com/en-us/maps/streetside").text("\xA9" + yyyy + " Microsoft");
75105 captureInfo.append("span").text("|");
75107 if (d.captured_at) {
75108 captureInfo.append("span").attr("class", "captured_at").text(localeTimestamp(d.captured_at));
75110 let line2 = attribution.append("div").attr("class", "attribution-row");
75111 line2.append("a").attr("class", "image-view-link").attr("target", "_blank").attr("href", "https://www.bing.com/maps?cp=" + d.loc[1] + "~" + d.loc[0] + "&lvl=17&dir=" + d.ca + "&style=x&v=2&sV=1").call(_t.append("streetside.view_on_bing"));
75112 line2.append("a").attr("class", "image-report-link").attr("target", "_blank").attr("href", "https://www.bing.com/maps/privacyreport/streetsideprivacyreport?bubbleid=" + encodeURIComponent(d.key) + "&focus=photo&lat=" + d.loc[1] + "&lng=" + d.loc[0] + "&z=17").call(_t.append("streetside.report"));
75113 let bubbleIdQuadKey = d.key.toString(4);
75114 const paddingNeeded = 16 - bubbleIdQuadKey.length;
75115 for (let i2 = 0; i2 < paddingNeeded; i2++) {
75116 bubbleIdQuadKey = "0" + bubbleIdQuadKey;
75118 const imgUrlPrefix = streetsideImagesApi + "hs" + bubbleIdQuadKey;
75119 const imgUrlSuffix = ".jpg?g=6338&n=z";
75120 const faceKeys = ["01", "02", "03", "10", "11", "12"];
75121 let quadKeys = getQuadKeys();
75122 let faces = faceKeys.map((faceKey) => {
75123 return quadKeys.map((quadKey) => {
75124 const xy = qkToXY(quadKey);
75127 url: imgUrlPrefix + faceKey + quadKey + imgUrlSuffix,
75133 loadFaces(faces).then(function() {
75134 if (!_pannellumViewer) {
75138 let sceneID = _currScene.toString();
75139 _pannellumViewer.addScene(sceneID, _sceneOptions).loadScene(sceneID);
75140 if (_currScene > 2) {
75141 sceneID = (_currScene - 1).toString();
75142 _pannellumViewer.removeScene(sceneID);
75148 getSequenceKeyForBubble: function(d) {
75149 return d && d.sequenceKey;
75151 // Updates the currently highlighted sequence and selected bubble.
75152 // Reset is only necessary when interacting with the viewport because
75153 // this implicitly changes the currently selected bubble/sequence
75154 setStyles: function(context, hovered, reset) {
75156 context.container().selectAll(".viewfield-group").classed("highlighted", false).classed("hovered", false).classed("currentView", false);
75157 context.container().selectAll(".sequence").classed("highlighted", false).classed("currentView", false);
75159 let hoveredBubbleKey = hovered && hovered.key;
75160 let hoveredSequenceKey = this.getSequenceKeyForBubble(hovered);
75161 let hoveredSequence = hoveredSequenceKey && _ssCache.sequences[hoveredSequenceKey];
75162 let hoveredBubbleKeys = hoveredSequence && hoveredSequence.bubbles.map((d) => d.key) || [];
75163 let viewer = context.container().select(".photoviewer");
75164 let selected = viewer.empty() ? void 0 : viewer.datum();
75165 let selectedBubbleKey = selected && selected.key;
75166 let selectedSequenceKey = this.getSequenceKeyForBubble(selected);
75167 let selectedSequence = selectedSequenceKey && _ssCache.sequences[selectedSequenceKey];
75168 let selectedBubbleKeys = selectedSequence && selectedSequence.bubbles.map((d) => d.key) || [];
75169 let highlightedBubbleKeys = utilArrayUnion(hoveredBubbleKeys, selectedBubbleKeys);
75170 context.container().selectAll(".layer-streetside-images .viewfield-group").classed("highlighted", (d) => highlightedBubbleKeys.indexOf(d.key) !== -1).classed("hovered", (d) => d.key === hoveredBubbleKey).classed("currentView", (d) => d.key === selectedBubbleKey);
75171 context.container().selectAll(".layer-streetside-images .sequence").classed("highlighted", (d) => d.properties.key === hoveredSequenceKey).classed("currentView", (d) => d.properties.key === selectedSequenceKey);
75172 context.container().selectAll(".layer-streetside-images .viewfield-group .viewfield").attr("d", viewfieldPath);
75173 function viewfieldPath() {
75174 let d = this.parentNode.__data__;
75175 if (d.pano && d.key !== selectedBubbleKey) {
75176 return "M 8,13 m -10,0 a 10,10 0 1,0 20,0 a 10,10 0 1,0 -20,0";
75178 return "M 6,9 C 8,8.4 8,8.4 10,9 L 16,-2 C 12,-5 4,-5 0,-2 z";
75183 updateUrlImage: function(imageKey) {
75184 if (!window.mocha) {
75185 var hash = utilStringQs(window.location.hash);
75187 hash.photo = "streetside/" + imageKey;
75191 window.location.replace("#" + utilQsString(hash, true));
75197 cache: function() {
75202 // modules/services/taginfo.js
75203 var apibase4 = taginfoApiUrl;
75204 var _inflight3 = {};
75205 var _popularKeys = {};
75206 var _taginfoCache = {};
75208 point: "count_nodes",
75209 vertex: "count_nodes",
75210 area: "count_ways",
75213 var tag_sort_members = {
75214 point: "count_node_members",
75215 vertex: "count_node_members",
75216 area: "count_way_members",
75217 line: "count_way_members",
75218 relation: "count_relation_members"
75220 var tag_filters = {
75226 var tag_members_fractions = {
75227 point: "count_node_members_fraction",
75228 vertex: "count_node_members_fraction",
75229 area: "count_way_members_fraction",
75230 line: "count_way_members_fraction",
75231 relation: "count_relation_members_fraction"
75233 function sets(params, n2, o) {
75234 if (params.geometry && o[params.geometry]) {
75235 params[n2] = o[params.geometry];
75239 function setFilter(params) {
75240 return sets(params, "filter", tag_filters);
75242 function setSort(params) {
75243 return sets(params, "sortname", tag_sorts);
75245 function setSortMembers(params) {
75246 return sets(params, "sortname", tag_sort_members);
75248 function clean(params) {
75249 return utilObjectOmit(params, ["geometry", "debounce"]);
75251 function filterKeys(type2) {
75252 var count_type = type2 ? "count_" + type2 : "count_all";
75253 return function(d) {
75254 return Number(d[count_type]) > 2500 || d.in_wiki;
75257 function filterMultikeys(prefix) {
75258 return function(d) {
75259 var re2 = new RegExp("^" + prefix + "(.*)$", "i");
75260 var matches = d.key.match(re2) || [];
75261 return matches.length === 2 && matches[1].indexOf(":") === -1;
75264 function filterValues(allowUpperCase) {
75265 return function(d) {
75266 if (d.value.match(/[;,]/) !== null)
75268 if (!allowUpperCase && d.value.match(/[A-Z*]/) !== null)
75270 return d.count > 100 || d.in_wiki;
75273 function filterRoles(geometry) {
75274 return function(d) {
75277 if (d.role.match(/[A-Z*;,]/) !== null)
75279 return Number(d[tag_members_fractions[geometry]]) > 0;
75282 function valKey(d) {
75288 function valKeyDescription(d) {
75291 title: d.description || d.value
75295 function roleKey(d) {
75301 function sortKeys(a, b) {
75302 return a.key.indexOf(":") === -1 && b.key.indexOf(":") !== -1 ? -1 : a.key.indexOf(":") !== -1 && b.key.indexOf(":") === -1 ? 1 : 0;
75304 var debouncedRequest2 = debounce_default(request2, 300, { leading: false });
75305 function request2(url, params, exactMatch, callback, loaded) {
75306 if (_inflight3[url])
75308 if (checkCache(url, params, exactMatch, callback))
75310 var controller = new AbortController();
75311 _inflight3[url] = controller;
75312 json_default(url, { signal: controller.signal }).then(function(result) {
75313 delete _inflight3[url];
75315 loaded(null, result);
75316 }).catch(function(err) {
75317 delete _inflight3[url];
75318 if (err.name === "AbortError")
75321 loaded(err.message);
75324 function checkCache(url, params, exactMatch, callback) {
75325 var rp = params.rp || 25;
75326 var testQuery = params.query || "";
75329 var hit = _taginfoCache[testUrl];
75330 if (hit && (url === testUrl || hit.length < rp)) {
75331 callback(null, hit);
75334 if (exactMatch || !testQuery.length)
75336 testQuery = testQuery.slice(0, -1);
75337 testUrl = url.replace(/&query=(.*?)&/, "&query=" + testQuery + "&");
75338 } while (testQuery.length >= 0);
75341 var taginfo_default = {
75344 _taginfoCache = {};
75346 // manually exclude some keys – #5377, #7485
75352 sorting_name: true,
75357 "bridge:name": true
75361 sortname: "values_all",
75365 lang: _mainLocalizer.languageCode()
75367 this.keys(params, function(err, data) {
75370 data.forEach(function(d) {
75371 if (d.value === "opening_hours")
75373 _popularKeys[d.value] = true;
75377 reset: function() {
75378 Object.values(_inflight3).forEach(function(controller) {
75379 controller.abort();
75383 keys: function(params, callback) {
75384 var doRequest = params.debounce ? debouncedRequest2 : request2;
75385 params = clean(setSort(params));
75386 params = Object.assign({
75388 sortname: "count_all",
75391 lang: _mainLocalizer.languageCode()
75393 var url = apibase4 + "keys/all?" + utilQsString(params);
75394 doRequest(url, params, false, callback, function(err, d) {
75398 var f2 = filterKeys(params.filter);
75399 var result = d.data.filter(f2).sort(sortKeys).map(valKey);
75400 _taginfoCache[url] = result;
75401 callback(null, result);
75405 multikeys: function(params, callback) {
75406 var doRequest = params.debounce ? debouncedRequest2 : request2;
75407 params = clean(setSort(params));
75408 params = Object.assign({
75410 sortname: "count_all",
75413 lang: _mainLocalizer.languageCode()
75415 var prefix = params.query;
75416 var url = apibase4 + "keys/all?" + utilQsString(params);
75417 doRequest(url, params, true, callback, function(err, d) {
75421 var f2 = filterMultikeys(prefix);
75422 var result = d.data.filter(f2).map(valKey);
75423 _taginfoCache[url] = result;
75424 callback(null, result);
75428 values: function(params, callback) {
75429 var key = params.key;
75430 if (key && _popularKeys[key]) {
75431 callback(null, []);
75434 var doRequest = params.debounce ? debouncedRequest2 : request2;
75435 params = clean(setSort(setFilter(params)));
75436 params = Object.assign({
75438 sortname: "count_all",
75441 lang: _mainLocalizer.languageCode()
75443 var url = apibase4 + "key/values?" + utilQsString(params);
75444 doRequest(url, params, false, callback, function(err, d) {
75448 var re2 = /network|taxon|genus|species|brand|grape_variety|royal_cypher|listed_status|booth|rating|stars|:output|_hours|_times|_ref|manufacturer|country|target|brewery|cai_scale/;
75449 var allowUpperCase = re2.test(params.key);
75450 var f2 = filterValues(allowUpperCase);
75451 var result = d.data.filter(f2).map(valKeyDescription);
75452 _taginfoCache[url] = result;
75453 callback(null, result);
75457 roles: function(params, callback) {
75458 var doRequest = params.debounce ? debouncedRequest2 : request2;
75459 var geometry = params.geometry;
75460 params = clean(setSortMembers(params));
75461 params = Object.assign({
75463 sortname: "count_all_members",
75466 lang: _mainLocalizer.languageCode()
75468 var url = apibase4 + "relation/roles?" + utilQsString(params);
75469 doRequest(url, params, true, callback, function(err, d) {
75473 var f2 = filterRoles(geometry);
75474 var result = d.data.filter(f2).map(roleKey);
75475 _taginfoCache[url] = result;
75476 callback(null, result);
75480 docs: function(params, callback) {
75481 var doRequest = params.debounce ? debouncedRequest2 : request2;
75482 params = clean(setSort(params));
75483 var path = "key/wiki_pages?";
75484 if (params.value) {
75485 path = "tag/wiki_pages?";
75486 } else if (params.rtype) {
75487 path = "relation/wiki_pages?";
75489 var url = apibase4 + path + utilQsString(params);
75490 doRequest(url, params, true, callback, function(err, d) {
75494 _taginfoCache[url] = d.data;
75495 callback(null, d.data);
75499 apibase: function(_) {
75500 if (!arguments.length)
75507 // modules/services/vector_tile.js
75508 var import_fast_deep_equal11 = __toESM(require_fast_deep_equal());
75509 var import_fast_json_stable_stringify2 = __toESM(require_fast_json_stable_stringify());
75510 var import_polygon_clipping2 = __toESM(require_polygon_clipping_umd());
75511 var import_pbf2 = __toESM(require_pbf());
75512 var import_vector_tile2 = __toESM(require_vector_tile());
75513 var tiler7 = utilTiler().tileSize(512).margin(1);
75514 var dispatch9 = dispatch_default("loadedData");
75516 function abortRequest7(controller) {
75517 controller.abort();
75519 function vtToGeoJSON(data, tile, mergeCache) {
75520 var vectorTile = new import_vector_tile2.default.VectorTile(new import_pbf2.default(data));
75521 var layers = Object.keys(vectorTile.layers);
75522 if (!Array.isArray(layers)) {
75526 layers.forEach(function(layerID) {
75527 var layer = vectorTile.layers[layerID];
75529 for (var i2 = 0; i2 < layer.length; i2++) {
75530 var feature3 = layer.feature(i2).toGeoJSON(tile.xyz[0], tile.xyz[1], tile.xyz[2]);
75531 var geometry = feature3.geometry;
75532 if (geometry.type === "Polygon") {
75533 geometry.type = "MultiPolygon";
75534 geometry.coordinates = [geometry.coordinates];
75536 var isClipped = false;
75537 if (geometry.type === "MultiPolygon") {
75538 var featureClip = bboxClip(feature3, tile.extent.rectangle());
75539 if (!(0, import_fast_deep_equal11.default)(feature3.geometry, featureClip.geometry)) {
75542 if (!feature3.geometry.coordinates.length)
75544 if (!feature3.geometry.coordinates[0].length)
75547 var featurehash = utilHashcode((0, import_fast_json_stable_stringify2.default)(feature3));
75548 var propertyhash = utilHashcode((0, import_fast_json_stable_stringify2.default)(feature3.properties || {}));
75549 feature3.__layerID__ = layerID.replace(/[^_a-zA-Z0-9\-]/g, "_");
75550 feature3.__featurehash__ = featurehash;
75551 feature3.__propertyhash__ = propertyhash;
75552 features.push(feature3);
75553 if (isClipped && geometry.type === "MultiPolygon") {
75554 var merged = mergeCache[propertyhash];
75555 if (merged && merged.length) {
75556 var other = merged[0];
75557 var coords = import_polygon_clipping2.default.union(
75558 feature3.geometry.coordinates,
75559 other.geometry.coordinates
75561 if (!coords || !coords.length) {
75564 merged.push(feature3);
75565 for (var j2 = 0; j2 < merged.length; j2++) {
75566 merged[j2].geometry.coordinates = coords;
75567 merged[j2].__featurehash__ = featurehash;
75570 mergeCache[propertyhash] = [feature3];
75578 function loadTile2(source, tile) {
75579 if (source.loaded[tile.id] || source.inflight[tile.id])
75581 var url = source.template.replace("{x}", tile.xyz[0]).replace("{y}", tile.xyz[1]).replace(/\{[t-]y\}/, Math.pow(2, tile.xyz[2]) - tile.xyz[1] - 1).replace(/\{z(oom)?\}/, tile.xyz[2]).replace(/\{switch:([^}]+)\}/, function(s, r) {
75582 var subdomains = r.split(",");
75583 return subdomains[(tile.xyz[0] + tile.xyz[1]) % subdomains.length];
75585 var controller = new AbortController();
75586 source.inflight[tile.id] = controller;
75587 fetch(url, { signal: controller.signal }).then(function(response) {
75588 if (!response.ok) {
75589 throw new Error(response.status + " " + response.statusText);
75591 source.loaded[tile.id] = [];
75592 delete source.inflight[tile.id];
75593 return response.arrayBuffer();
75594 }).then(function(data) {
75596 throw new Error("No Data");
75598 var z = tile.xyz[2];
75599 if (!source.canMerge[z]) {
75600 source.canMerge[z] = {};
75602 source.loaded[tile.id] = vtToGeoJSON(data, tile, source.canMerge[z]);
75603 dispatch9.call("loadedData");
75604 }).catch(function() {
75605 source.loaded[tile.id] = [];
75606 delete source.inflight[tile.id];
75609 var vector_tile_default = {
75614 this.event = utilRebind(this, dispatch9, "on");
75616 reset: function() {
75617 for (var sourceID in _vtCache) {
75618 var source = _vtCache[sourceID];
75619 if (source && source.inflight) {
75620 Object.values(source.inflight).forEach(abortRequest7);
75625 addSource: function(sourceID, template) {
75626 _vtCache[sourceID] = { template, inflight: {}, loaded: {}, canMerge: {} };
75627 return _vtCache[sourceID];
75629 data: function(sourceID, projection2) {
75630 var source = _vtCache[sourceID];
75633 var tiles = tiler7.getTiles(projection2);
75636 for (var i2 = 0; i2 < tiles.length; i2++) {
75637 var features = source.loaded[tiles[i2].id];
75638 if (!features || !features.length)
75640 for (var j2 = 0; j2 < features.length; j2++) {
75641 var feature3 = features[j2];
75642 var hash = feature3.__featurehash__;
75646 results.push(Object.assign({}, feature3));
75651 loadTiles: function(sourceID, template, projection2) {
75652 var source = _vtCache[sourceID];
75654 source = this.addSource(sourceID, template);
75656 var tiles = tiler7.getTiles(projection2);
75657 Object.keys(source.inflight).forEach(function(k) {
75658 var wanted = tiles.find(function(tile) {
75659 return k === tile.id;
75662 abortRequest7(source.inflight[k]);
75663 delete source.inflight[k];
75666 tiles.forEach(function(tile) {
75667 loadTile2(source, tile);
75670 cache: function() {
75675 // modules/services/wikidata.js
75676 var apibase5 = "https://www.wikidata.org/w/api.php?";
75677 var _wikidataCache = {};
75678 var wikidata_default = {
75681 reset: function() {
75682 _wikidataCache = {};
75684 // Search for Wikidata items matching the query
75685 itemsForSearchQuery: function(query, callback) {
75688 callback("No query", {});
75691 var lang = this.languagesToQuery()[0];
75692 var url = apibase5 + utilQsString({
75693 action: "wbsearchentities",
75698 // the language to search
75700 // the language for the label and description in the result
75705 json_default(url).then(function(result) {
75706 if (result && result.error) {
75707 throw new Error(result.error);
75710 callback(null, result.search || {});
75711 }).catch(function(err) {
75713 callback(err.message, {});
75716 // Given a Wikipedia language and article title,
75717 // return an array of corresponding Wikidata entities.
75718 itemsByTitle: function(lang, title, callback) {
75721 callback("No title", {});
75724 lang = lang || "en";
75725 var url = apibase5 + utilQsString({
75726 action: "wbgetentities",
75729 sites: lang.replace(/-/g, "_") + "wiki",
75732 // shrink response by filtering to one language
75735 json_default(url).then(function(result) {
75736 if (result && result.error) {
75737 throw new Error(result.error);
75740 callback(null, result.entities || {});
75741 }).catch(function(err) {
75743 callback(err.message, {});
75746 languagesToQuery: function() {
75747 return _mainLocalizer.localeCodes().map(function(code) {
75748 return code.toLowerCase();
75749 }).filter(function(code) {
75750 return code !== "en-us";
75753 entityByQID: function(qid, callback) {
75755 callback("No qid", {});
75758 if (_wikidataCache[qid]) {
75760 callback(null, _wikidataCache[qid]);
75763 var langs = this.languagesToQuery();
75764 var url = apibase5 + utilQsString({
75765 action: "wbgetentities",
75769 props: "labels|descriptions|claims|sitelinks",
75770 sitefilter: langs.map(function(d) {
75773 languages: langs.join("|"),
75774 languagefallback: 1,
75777 json_default(url).then(function(result) {
75778 if (result && result.error) {
75779 throw new Error(result.error);
75782 callback(null, result.entities[qid] || {});
75783 }).catch(function(err) {
75785 callback(err.message, {});
75788 // Pass `params` object of the form:
75790 // qid: 'string' // brand wikidata (e.g. 'Q37158')
75793 // Get an result object used to display tag documentation
75795 // title: 'string',
75796 // description: 'string',
75797 // editURL: 'string',
75798 // imageURL: 'string',
75799 // wiki: { title: 'string', text: 'string', url: 'string' }
75802 getDocs: function(params, callback) {
75803 var langs = this.languagesToQuery();
75804 this.entityByQID(params.qid, function(err, entity) {
75805 if (err || !entity) {
75806 callback(err || "No entity");
75811 for (i2 in langs) {
75812 let code = langs[i2];
75813 if (entity.descriptions[code] && entity.descriptions[code].language === code) {
75814 description = entity.descriptions[code];
75818 if (!description && Object.values(entity.descriptions).length)
75819 description = Object.values(entity.descriptions)[0];
75822 description: description ? description.value : "",
75823 descriptionLocaleCode: description ? description.language : "",
75824 editURL: "https://www.wikidata.org/wiki/" + entity.id
75826 if (entity.claims) {
75827 var imageroot = "https://commons.wikimedia.org/w/index.php";
75828 var props = ["P154", "P18"];
75830 for (i2 = 0; i2 < props.length; i2++) {
75831 prop = entity.claims[props[i2]];
75832 if (prop && Object.keys(prop).length > 0) {
75833 image = prop[Object.keys(prop)[0]].mainsnak.datavalue.value;
75835 result.imageURL = imageroot + "?" + utilQsString({
75836 title: "Special:Redirect/file/" + image,
75844 if (entity.sitelinks) {
75845 var englishLocale = _mainLocalizer.languageCode().toLowerCase() === "en";
75846 for (i2 = 0; i2 < langs.length; i2++) {
75847 var w = langs[i2] + "wiki";
75848 if (entity.sitelinks[w]) {
75849 var title = entity.sitelinks[w].title;
75850 var tKey = "inspector.wiki_reference";
75851 if (!englishLocale && langs[i2] === "en") {
75852 tKey = "inspector.wiki_en_reference";
75857 url: "https://" + langs[i2] + ".wikipedia.org/wiki/" + title.replace(/ /g, "_")
75863 callback(null, result);
75868 // modules/services/wikipedia.js
75869 var endpoint = "https://en.wikipedia.org/w/api.php?";
75870 var wikipedia_default = {
75873 reset: function() {
75875 search: function(lang, query, callback) {
75878 callback("No Query", []);
75881 lang = lang || "en";
75882 var url = endpoint.replace("en", lang) + utilQsString({
75886 srinfo: "suggestion",
75891 json_default(url).then(function(result) {
75892 if (result && result.error) {
75893 throw new Error(result.error);
75894 } else if (!result || !result.query || !result.query.search) {
75895 throw new Error("No Results");
75898 var titles = result.query.search.map(function(d) {
75901 callback(null, titles);
75903 }).catch(function(err) {
75908 suggestions: function(lang, query, callback) {
75914 lang = lang || "en";
75915 var url = endpoint.replace("en", lang) + utilQsString({
75916 action: "opensearch",
75923 json_default(url).then(function(result) {
75924 if (result && result.error) {
75925 throw new Error(result.error);
75926 } else if (!result || result.length < 2) {
75927 throw new Error("No Results");
75930 callback(null, result[1] || []);
75931 }).catch(function(err) {
75933 callback(err.message, []);
75936 translations: function(lang, title, callback) {
75939 callback("No Title");
75942 var url = endpoint.replace("en", lang) + utilQsString({
75950 json_default(url).then(function(result) {
75951 if (result && result.error) {
75952 throw new Error(result.error);
75953 } else if (!result || !result.query || !result.query.pages) {
75954 throw new Error("No Results");
75957 var list = result.query.pages[Object.keys(result.query.pages)[0]];
75958 var translations = {};
75959 if (list && list.langlinks) {
75960 list.langlinks.forEach(function(d) {
75961 translations[d.lang] = d["*"];
75964 callback(null, translations);
75966 }).catch(function(err) {
75968 callback(err.message);
75973 // modules/services/index.js
75975 geocoder: nominatim_default,
75976 keepRight: keepRight_default,
75977 improveOSM: improveOSM_default,
75978 osmose: osmose_default,
75979 mapillary: mapillary_default,
75981 kartaview: kartaview_default,
75983 osmWikibase: osm_wikibase_default,
75984 maprules: maprules_default,
75985 streetside: streetside_default,
75986 taginfo: taginfo_default,
75987 vectorTile: vector_tile_default,
75988 wikidata: wikidata_default,
75989 wikipedia: wikipedia_default
75992 // modules/modes/drag_note.js
75993 function modeDragNote(context) {
75998 var edit2 = behaviorEdit(context);
75999 var _nudgeInterval;
76002 function startNudge(d3_event, nudge) {
76003 if (_nudgeInterval)
76004 window.clearInterval(_nudgeInterval);
76005 _nudgeInterval = window.setInterval(function() {
76006 context.map().pan(nudge);
76007 doMove(d3_event, nudge);
76010 function stopNudge() {
76011 if (_nudgeInterval) {
76012 window.clearInterval(_nudgeInterval);
76013 _nudgeInterval = null;
76016 function origin(note) {
76017 return context.projection(note.loc);
76019 function start2(d3_event, note) {
76021 var osm = services.osm;
76023 _note = osm.getNote(_note.id);
76025 context.surface().selectAll(".note-" + _note.id).classed("active", true);
76026 context.perform(actionNoop());
76027 context.enter(mode);
76028 context.selectedNoteID(_note.id);
76030 function move(d3_event, entity, point2) {
76031 d3_event.stopPropagation();
76032 _lastLoc = context.projection.invert(point2);
76034 var nudge = geoViewportEdge(point2, context.map().dimensions());
76036 startNudge(d3_event, nudge);
76041 function doMove(d3_event, nudge) {
76042 nudge = nudge || [0, 0];
76043 var currPoint = d3_event && d3_event.point || context.projection(_lastLoc);
76044 var currMouse = geoVecSubtract(currPoint, nudge);
76045 var loc = context.projection.invert(currMouse);
76046 _note = _note.move(loc);
76047 var osm = services.osm;
76049 osm.replaceNote(_note);
76051 context.replace(actionNoop());
76054 context.replace(actionNoop());
76055 context.selectedNoteID(_note.id).enter(modeSelectNote(context, _note.id));
76057 var drag = behaviorDrag().selector(".layer-touch.markers .target.note.new").surface(context.container().select(".main-map").node()).origin(origin).on("start", start2).on("move", move).on("end", end);
76058 mode.enter = function() {
76059 context.install(edit2);
76061 mode.exit = function() {
76062 context.ui().sidebar.hover.cancel();
76063 context.uninstall(edit2);
76064 context.surface().selectAll(".active").classed("active", false);
76067 mode.behavior = drag;
76071 // modules/modes/select_data.js
76072 function modeSelectData(context, selectedDatum) {
76077 var keybinding = utilKeybinding("select-data");
76078 var dataEditor = uiDataEditor(context);
76080 behaviorBreathe(context),
76081 behaviorHover(context),
76082 behaviorSelect(context),
76083 behaviorLasso(context),
76084 modeDragNode(context).behavior,
76085 modeDragNote(context).behavior
76087 function selectData(d3_event, drawn) {
76088 var selection2 = context.surface().selectAll(".layer-mapdata .data" + selectedDatum.__featurehash__);
76089 if (selection2.empty()) {
76090 var source = d3_event && d3_event.type === "zoom" && d3_event.sourceEvent;
76091 if (drawn && source && (source.type === "pointermove" || source.type === "mousemove" || source.type === "touchmove")) {
76092 context.enter(modeBrowse(context));
76095 selection2.classed("selected", true);
76099 if (context.container().select(".combobox").size())
76101 context.enter(modeBrowse(context));
76103 mode.zoomToSelected = function() {
76104 var extent = geoExtent(bounds_default(selectedDatum));
76105 context.map().centerZoomEase(extent.center(), context.map().trimmedExtentZoom(extent));
76107 mode.enter = function() {
76108 behaviors.forEach(context.install);
76109 keybinding.on(_t("inspector.zoom_to.key"), mode.zoomToSelected).on("\u238B", esc, true);
76110 select_default2(document).call(keybinding);
76112 var sidebar = context.ui().sidebar;
76113 sidebar.show(dataEditor.datum(selectedDatum));
76114 var extent = geoExtent(bounds_default(selectedDatum));
76115 sidebar.expand(sidebar.intersects(extent));
76116 context.map().on("drawn.select-data", selectData);
76118 mode.exit = function() {
76119 behaviors.forEach(context.uninstall);
76120 select_default2(document).call(keybinding.unbind);
76121 context.surface().selectAll(".layer-mapdata .selected").classed("selected hover", false);
76122 context.map().on("drawn.select-data", null);
76123 context.ui().sidebar.hide();
76128 // modules/behavior/select.js
76129 function behaviorSelect(context) {
76130 var _tolerancePx = 4;
76131 var _lastMouseEvent = null;
76132 var _showMenu = false;
76133 var _downPointers = {};
76134 var _longPressTimeout = null;
76135 var _lastInteractionType = null;
76136 var _multiselectionPointerId = null;
76137 var _pointerPrefix = "PointerEvent" in window ? "pointer" : "mouse";
76138 function keydown(d3_event) {
76139 if (d3_event.keyCode === 32) {
76140 var activeNode = document.activeElement;
76141 if (activeNode && (/* @__PURE__ */ new Set(["INPUT", "TEXTAREA"])).has(activeNode.nodeName))
76144 if (d3_event.keyCode === 93 || // context menu key
76145 d3_event.keyCode === 32) {
76146 d3_event.preventDefault();
76148 if (d3_event.repeat)
76151 if (d3_event.shiftKey) {
76152 context.surface().classed("behavior-multiselect", true);
76154 if (d3_event.keyCode === 32) {
76155 if (!_downPointers.spacebar && _lastMouseEvent) {
76157 _longPressTimeout = window.setTimeout(didLongPress, 500, "spacebar", "spacebar");
76158 _downPointers.spacebar = {
76159 firstEvent: _lastMouseEvent,
76160 lastEvent: _lastMouseEvent
76165 function keyup(d3_event) {
76167 if (!d3_event.shiftKey) {
76168 context.surface().classed("behavior-multiselect", false);
76170 if (d3_event.keyCode === 93) {
76171 d3_event.preventDefault();
76172 _lastInteractionType = "menukey";
76173 contextmenu(d3_event);
76174 } else if (d3_event.keyCode === 32) {
76175 var pointer = _downPointers.spacebar;
76177 delete _downPointers.spacebar;
76180 d3_event.preventDefault();
76181 _lastInteractionType = "spacebar";
76182 click(pointer.firstEvent, pointer.lastEvent, "spacebar");
76186 function pointerdown(d3_event) {
76187 var id2 = (d3_event.pointerId || "mouse").toString();
76189 if (d3_event.buttons && d3_event.buttons !== 1)
76191 context.ui().closeEditMenu();
76192 if (d3_event.pointerType !== "mouse") {
76193 _longPressTimeout = window.setTimeout(didLongPress, 500, id2, "longdown-" + (d3_event.pointerType || "mouse"));
76195 _downPointers[id2] = {
76196 firstEvent: d3_event,
76197 lastEvent: d3_event
76200 function didLongPress(id2, interactionType) {
76201 var pointer = _downPointers[id2];
76204 for (var i2 in _downPointers) {
76205 _downPointers[i2].done = true;
76207 _longPressTimeout = null;
76208 _lastInteractionType = interactionType;
76210 click(pointer.firstEvent, pointer.lastEvent, id2);
76212 function pointermove(d3_event) {
76213 var id2 = (d3_event.pointerId || "mouse").toString();
76214 if (_downPointers[id2]) {
76215 _downPointers[id2].lastEvent = d3_event;
76217 if (!d3_event.pointerType || d3_event.pointerType === "mouse") {
76218 _lastMouseEvent = d3_event;
76219 if (_downPointers.spacebar) {
76220 _downPointers.spacebar.lastEvent = d3_event;
76224 function pointerup(d3_event) {
76225 var id2 = (d3_event.pointerId || "mouse").toString();
76226 var pointer = _downPointers[id2];
76229 delete _downPointers[id2];
76230 if (_multiselectionPointerId === id2) {
76231 _multiselectionPointerId = null;
76235 click(pointer.firstEvent, d3_event, id2);
76237 function pointercancel(d3_event) {
76238 var id2 = (d3_event.pointerId || "mouse").toString();
76239 if (!_downPointers[id2])
76241 delete _downPointers[id2];
76242 if (_multiselectionPointerId === id2) {
76243 _multiselectionPointerId = null;
76246 function contextmenu(d3_event) {
76247 d3_event.preventDefault();
76248 if (!+d3_event.clientX && !+d3_event.clientY) {
76249 if (_lastMouseEvent) {
76250 d3_event = _lastMouseEvent;
76255 _lastMouseEvent = d3_event;
76256 if (d3_event.pointerType === "touch" || d3_event.pointerType === "pen" || d3_event.mozInputSource && // firefox doesn't give a pointerType on contextmenu events
76257 (d3_event.mozInputSource === MouseEvent.MOZ_SOURCE_TOUCH || d3_event.mozInputSource === MouseEvent.MOZ_SOURCE_PEN)) {
76258 _lastInteractionType = "touch";
76260 _lastInteractionType = "rightclick";
76264 click(d3_event, d3_event);
76266 function click(firstEvent, lastEvent, pointerId) {
76268 var mapNode = context.container().select(".main-map").node();
76269 var pointGetter = utilFastMouse(mapNode);
76270 var p1 = pointGetter(firstEvent);
76271 var p2 = pointGetter(lastEvent);
76272 var dist = geoVecLength(p1, p2);
76273 if (dist > _tolerancePx || !mapContains(lastEvent)) {
76277 var targetDatum = lastEvent.target.__data__;
76278 var multiselectEntityId;
76279 if (!_multiselectionPointerId) {
76280 var selectPointerInfo = pointerDownOnSelection(pointerId);
76281 if (selectPointerInfo) {
76282 _multiselectionPointerId = selectPointerInfo.pointerId;
76283 multiselectEntityId = !selectPointerInfo.selected && selectPointerInfo.entityId;
76284 _downPointers[selectPointerInfo.pointerId].done = true;
76287 var isMultiselect = context.mode().id === "select" && // and shift key is down
76288 (lastEvent && lastEvent.shiftKey || // or we're lasso-selecting
76289 context.surface().select(".lasso").node() || // or a pointer is down over a selected feature
76290 _multiselectionPointerId && !multiselectEntityId);
76291 processClick(targetDatum, isMultiselect, p2, multiselectEntityId);
76292 function mapContains(event) {
76293 var rect = mapNode.getBoundingClientRect();
76294 return event.clientX >= rect.left && event.clientX <= rect.right && event.clientY >= rect.top && event.clientY <= rect.bottom;
76296 function pointerDownOnSelection(skipPointerId) {
76297 var mode = context.mode();
76298 var selectedIDs = mode.id === "select" ? mode.selectedIDs() : [];
76299 for (var pointerId2 in _downPointers) {
76300 if (pointerId2 === "spacebar" || pointerId2 === skipPointerId)
76302 var pointerInfo = _downPointers[pointerId2];
76303 var p12 = pointGetter(pointerInfo.firstEvent);
76304 var p22 = pointGetter(pointerInfo.lastEvent);
76305 if (geoVecLength(p12, p22) > _tolerancePx)
76307 var datum2 = pointerInfo.firstEvent.target.__data__;
76308 var entity = datum2 && datum2.properties && datum2.properties.entity || datum2;
76309 if (context.graph().hasEntity(entity.id)) {
76311 pointerId: pointerId2,
76312 entityId: entity.id,
76313 selected: selectedIDs.indexOf(entity.id) !== -1
76320 function processClick(datum2, isMultiselect, point2, alsoSelectId) {
76321 var mode = context.mode();
76322 var showMenu = _showMenu;
76323 var interactionType = _lastInteractionType;
76324 var entity = datum2 && datum2.properties && datum2.properties.entity;
76327 if (datum2 && datum2.type === "midpoint") {
76328 datum2 = datum2.parents[0];
76331 if (datum2 instanceof osmEntity) {
76332 var selectedIDs = context.selectedIDs();
76333 context.selectedNoteID(null);
76334 context.selectedErrorID(null);
76335 if (!isMultiselect) {
76336 if (!showMenu || selectedIDs.length <= 1 || selectedIDs.indexOf(datum2.id) === -1) {
76337 if (alsoSelectId === datum2.id)
76338 alsoSelectId = null;
76339 selectedIDs = (alsoSelectId ? [alsoSelectId] : []).concat([datum2.id]);
76340 newMode = mode.id === "select" ? mode.selectedIDs(selectedIDs) : modeSelect(context, selectedIDs).selectBehavior(behavior);
76341 context.enter(newMode);
76344 if (selectedIDs.indexOf(datum2.id) !== -1) {
76346 selectedIDs = selectedIDs.filter(function(id2) {
76347 return id2 !== datum2.id;
76349 newMode = selectedIDs.length ? mode.selectedIDs(selectedIDs) : modeBrowse(context).selectBehavior(behavior);
76350 context.enter(newMode);
76353 selectedIDs = selectedIDs.concat([datum2.id]);
76354 newMode = mode.selectedIDs(selectedIDs);
76355 context.enter(newMode);
76358 } else if (datum2 && datum2.__featurehash__ && !isMultiselect) {
76359 context.selectedNoteID(null).enter(modeSelectData(context, datum2));
76360 } else if (datum2 instanceof osmNote && !isMultiselect) {
76361 context.selectedNoteID(datum2.id).enter(modeSelectNote(context, datum2.id));
76362 } else if (datum2 instanceof QAItem && !isMultiselect) {
76363 context.selectedErrorID(datum2.id).enter(modeSelectError(context, datum2.id, datum2.service));
76365 context.selectedNoteID(null);
76366 context.selectedErrorID(null);
76367 if (!isMultiselect && mode.id !== "browse") {
76368 context.enter(modeBrowse(context));
76371 context.ui().closeEditMenu();
76373 context.ui().showEditMenu(point2, interactionType);
76376 function cancelLongPress() {
76377 if (_longPressTimeout)
76378 window.clearTimeout(_longPressTimeout);
76379 _longPressTimeout = null;
76381 function resetProperties() {
76384 _lastInteractionType = null;
76386 function behavior(selection2) {
76388 _lastMouseEvent = context.map().lastPointerEvent();
76389 select_default2(window).on("keydown.select", keydown).on("keyup.select", keyup).on(_pointerPrefix + "move.select", pointermove, true).on(_pointerPrefix + "up.select", pointerup, true).on("pointercancel.select", pointercancel, true).on("contextmenu.select-window", function(d3_event) {
76391 if (+e.clientX === 0 && +e.clientY === 0) {
76392 d3_event.preventDefault();
76395 selection2.on(_pointerPrefix + "down.select", pointerdown).on("contextmenu.select", contextmenu);
76397 behavior.off = function(selection2) {
76399 select_default2(window).on("keydown.select", null).on("keyup.select", null).on("contextmenu.select-window", null).on(_pointerPrefix + "move.select", null, true).on(_pointerPrefix + "up.select", null, true).on("pointercancel.select", null, true);
76400 selection2.on(_pointerPrefix + "down.select", null).on("contextmenu.select", null);
76401 context.surface().classed("behavior-multiselect", false);
76406 // modules/operations/index.js
76407 var operations_exports = {};
76408 __export(operations_exports, {
76409 operationCircularize: () => operationCircularize,
76410 operationContinue: () => operationContinue,
76411 operationCopy: () => operationCopy,
76412 operationDelete: () => operationDelete,
76413 operationDisconnect: () => operationDisconnect,
76414 operationDowngrade: () => operationDowngrade,
76415 operationExtract: () => operationExtract,
76416 operationMerge: () => operationMerge,
76417 operationMove: () => operationMove,
76418 operationOrthogonalize: () => operationOrthogonalize,
76419 operationPaste: () => operationPaste,
76420 operationReflectLong: () => operationReflectLong,
76421 operationReflectShort: () => operationReflectShort,
76422 operationReverse: () => operationReverse,
76423 operationRotate: () => operationRotate,
76424 operationSplit: () => operationSplit,
76425 operationStraighten: () => operationStraighten
76428 // modules/operations/continue.js
76429 function operationContinue(context, selectedIDs) {
76430 var _entities = selectedIDs.map(function(id2) {
76431 return context.graph().entity(id2);
76433 var _geometries = Object.assign(
76434 { line: [], vertex: [] },
76435 utilArrayGroupBy(_entities, function(entity) {
76436 return entity.geometry(context.graph());
76439 var _vertex = _geometries.vertex.length && _geometries.vertex[0];
76440 function candidateWays() {
76441 return _vertex ? context.graph().parentWays(_vertex).filter(function(parent) {
76442 return parent.geometry(context.graph()) === "line" && !parent.isClosed() && parent.affix(_vertex.id) && (_geometries.line.length === 0 || _geometries.line[0] === parent);
76445 var _candidates = candidateWays();
76446 var operation = function() {
76447 var candidate = _candidates[0];
76449 modeDrawLine(context, candidate.id, context.graph(), "line", candidate.affix(_vertex.id), true)
76452 operation.relatedEntityIds = function() {
76453 return _candidates.length ? [_candidates[0].id] : [];
76455 operation.available = function() {
76456 return _geometries.vertex.length === 1 && _geometries.line.length <= 1 && !context.features().hasHiddenConnections(_vertex, context.graph());
76458 operation.disabled = function() {
76459 if (_candidates.length === 0) {
76460 return "not_eligible";
76461 } else if (_candidates.length > 1) {
76466 operation.tooltip = function() {
76467 var disable = operation.disabled();
76468 return disable ? _t.append("operations.continue." + disable) : _t.append("operations.continue.description");
76470 operation.annotation = function() {
76471 return _t("operations.continue.annotation.line");
76473 operation.id = "continue";
76474 operation.keys = [_t("operations.continue.key")];
76475 operation.title = _t.append("operations.continue.title");
76476 operation.behavior = behaviorOperation(context).which(operation);
76480 // modules/operations/copy.js
76481 function operationCopy(context, selectedIDs) {
76482 function getFilteredIdsToCopy() {
76483 return selectedIDs.filter(function(selectedID) {
76484 var entity = context.graph().hasEntity(selectedID);
76485 return entity.hasInterestingTags() || entity.geometry(context.graph()) !== "vertex";
76488 var operation = function() {
76489 var graph = context.graph();
76490 var selected = groupEntities(getFilteredIdsToCopy(), graph);
76495 for (i2 = 0; i2 < selected.relation.length; i2++) {
76496 entity = selected.relation[i2];
76497 if (!skip[entity.id] && entity.isComplete(graph)) {
76498 canCopy.push(entity.id);
76499 skip = getDescendants(entity.id, graph, skip);
76502 for (i2 = 0; i2 < selected.way.length; i2++) {
76503 entity = selected.way[i2];
76504 if (!skip[entity.id]) {
76505 canCopy.push(entity.id);
76506 skip = getDescendants(entity.id, graph, skip);
76509 for (i2 = 0; i2 < selected.node.length; i2++) {
76510 entity = selected.node[i2];
76511 if (!skip[entity.id]) {
76512 canCopy.push(entity.id);
76515 context.copyIDs(canCopy);
76516 if (_point && (canCopy.length !== 1 || graph.entity(canCopy[0]).type !== "node")) {
76517 context.copyLonLat(context.projection.invert(_point));
76519 context.copyLonLat(null);
76522 function groupEntities(ids, graph) {
76523 var entities = ids.map(function(id2) {
76524 return graph.entity(id2);
76526 return Object.assign(
76527 { relation: [], way: [], node: [] },
76528 utilArrayGroupBy(entities, "type")
76531 function getDescendants(id2, graph, descendants) {
76532 var entity = graph.entity(id2);
76534 descendants = descendants || {};
76535 if (entity.type === "relation") {
76536 children2 = entity.members.map(function(m) {
76539 } else if (entity.type === "way") {
76540 children2 = entity.nodes;
76544 for (var i2 = 0; i2 < children2.length; i2++) {
76545 if (!descendants[children2[i2]]) {
76546 descendants[children2[i2]] = true;
76547 descendants = getDescendants(children2[i2], graph, descendants);
76550 return descendants;
76552 operation.available = function() {
76553 return getFilteredIdsToCopy().length > 0;
76555 operation.disabled = function() {
76556 var extent = utilTotalExtent(getFilteredIdsToCopy(), context.graph());
76557 if (extent.percentContainedIn(context.map().extent()) < 0.8) {
76558 return "too_large";
76562 operation.availableForKeypress = function() {
76563 var selection2 = window.getSelection && window.getSelection();
76564 return !selection2 || !selection2.toString();
76566 operation.tooltip = function() {
76567 var disable = operation.disabled();
76568 return disable ? _t.append("operations.copy." + disable, { n: selectedIDs.length }) : _t.append("operations.copy.description", { n: selectedIDs.length });
76570 operation.annotation = function() {
76571 return _t("operations.copy.annotation", { n: selectedIDs.length });
76574 operation.point = function(val) {
76578 operation.id = "copy";
76579 operation.keys = [uiCmd("\u2318C")];
76580 operation.title = _t.append("operations.copy.title");
76581 operation.behavior = behaviorOperation(context).which(operation);
76585 // modules/operations/disconnect.js
76586 function operationDisconnect(context, selectedIDs) {
76587 var _vertexIDs = [];
76589 var _otherIDs = [];
76591 selectedIDs.forEach(function(id2) {
76592 var entity = context.entity(id2);
76593 if (entity.type === "way") {
76595 } else if (entity.geometry(context.graph()) === "vertex") {
76596 _vertexIDs.push(id2);
76598 _otherIDs.push(id2);
76601 var _coords, _descriptionID = "", _annotationID = "features";
76602 var _disconnectingVertexIds = [];
76603 var _disconnectingWayIds = [];
76604 if (_vertexIDs.length > 0) {
76605 _disconnectingVertexIds = _vertexIDs;
76606 _vertexIDs.forEach(function(vertexID) {
76607 var action = actionDisconnect(vertexID);
76608 if (_wayIDs.length > 0) {
76609 var waysIDsForVertex = _wayIDs.filter(function(wayID) {
76610 var way = context.entity(wayID);
76611 return way.nodes.indexOf(vertexID) !== -1;
76613 action.limitWays(waysIDsForVertex);
76615 _actions.push(action);
76616 _disconnectingWayIds = _disconnectingWayIds.concat(context.graph().parentWays(context.graph().entity(vertexID)).map((d) => d.id));
76618 _disconnectingWayIds = utilArrayUniq(_disconnectingWayIds).filter(function(id2) {
76619 return _wayIDs.indexOf(id2) === -1;
76621 _descriptionID += _actions.length === 1 ? "single_point." : "multiple_points.";
76622 if (_wayIDs.length === 1) {
76623 _descriptionID += "single_way." + context.graph().geometry(_wayIDs[0]);
76625 _descriptionID += _wayIDs.length === 0 ? "no_ways" : "multiple_ways";
76627 } else if (_wayIDs.length > 0) {
76628 var ways = _wayIDs.map(function(id2) {
76629 return context.entity(id2);
76631 var nodes = utilGetAllNodes(_wayIDs, context.graph());
76632 _coords = nodes.map(function(n2) {
76635 var sharedActions = [];
76636 var sharedNodes = [];
76637 var unsharedActions = [];
76638 var unsharedNodes = [];
76639 nodes.forEach(function(node) {
76640 var action = actionDisconnect(node.id).limitWays(_wayIDs);
76641 if (action.disabled(context.graph()) !== "not_connected") {
76643 for (var i2 in ways) {
76644 var way = ways[i2];
76645 if (way.nodes.indexOf(node.id) !== -1) {
76652 sharedActions.push(action);
76653 sharedNodes.push(node);
76655 unsharedActions.push(action);
76656 unsharedNodes.push(node);
76660 _descriptionID += "no_points.";
76661 _descriptionID += _wayIDs.length === 1 ? "single_way." : "multiple_ways.";
76662 if (sharedActions.length) {
76663 _actions = sharedActions;
76664 _disconnectingVertexIds = sharedNodes.map((node) => node.id);
76665 _descriptionID += "conjoined";
76666 _annotationID = "from_each_other";
76668 _actions = unsharedActions;
76669 _disconnectingVertexIds = unsharedNodes.map((node) => node.id);
76670 if (_wayIDs.length === 1) {
76671 _descriptionID += context.graph().geometry(_wayIDs[0]);
76673 _descriptionID += "separate";
76677 var _extent = utilTotalExtent(_disconnectingVertexIds, context.graph());
76678 var operation = function() {
76679 context.perform(function(graph) {
76680 return _actions.reduce(function(graph2, action) {
76681 return action(graph2);
76683 }, operation.annotation());
76684 context.validator().validate();
76686 operation.relatedEntityIds = function() {
76687 if (_vertexIDs.length) {
76688 return _disconnectingWayIds;
76690 return _disconnectingVertexIds;
76692 operation.available = function() {
76693 if (_actions.length === 0)
76695 if (_otherIDs.length !== 0)
76697 if (_vertexIDs.length !== 0 && _wayIDs.length !== 0 && !_wayIDs.every(function(wayID) {
76698 return _vertexIDs.some(function(vertexID) {
76699 var way = context.entity(wayID);
76700 return way.nodes.indexOf(vertexID) !== -1;
76706 operation.disabled = function() {
76708 for (var actionIndex in _actions) {
76709 reason = _actions[actionIndex].disabled(context.graph());
76713 if (_extent && _extent.percentContainedIn(context.map().extent()) < 0.8) {
76714 return "too_large." + ((_vertexIDs.length ? _vertexIDs : _wayIDs).length === 1 ? "single" : "multiple");
76715 } else if (_coords && someMissing()) {
76716 return "not_downloaded";
76717 } else if (selectedIDs.some(context.hasHiddenConnections)) {
76718 return "connected_to_hidden";
76721 function someMissing() {
76722 if (context.inIntro())
76724 var osm = context.connection();
76726 var missing = _coords.filter(function(loc) {
76727 return !osm.isDataLoaded(loc);
76729 if (missing.length) {
76730 missing.forEach(function(loc) {
76731 context.loadTileAtLoc(loc);
76739 operation.tooltip = function() {
76740 var disable = operation.disabled();
76741 return disable ? _t.append("operations.disconnect." + disable) : _t.append("operations.disconnect.description." + _descriptionID);
76743 operation.annotation = function() {
76744 return _t("operations.disconnect.annotation." + _annotationID);
76746 operation.id = "disconnect";
76747 operation.keys = [_t("operations.disconnect.key")];
76748 operation.title = _t.append("operations.disconnect.title");
76749 operation.behavior = behaviorOperation(context).which(operation);
76753 // modules/operations/downgrade.js
76754 function operationDowngrade(context, selectedIDs) {
76755 var _affectedFeatureCount = 0;
76756 var _downgradeType = downgradeTypeForEntityIDs(selectedIDs);
76757 var _multi = _affectedFeatureCount === 1 ? "single" : "multiple";
76758 function downgradeTypeForEntityIDs(entityIds) {
76760 _affectedFeatureCount = 0;
76761 for (var i2 in entityIds) {
76762 var entityID = entityIds[i2];
76763 var type2 = downgradeTypeForEntityID(entityID);
76765 _affectedFeatureCount += 1;
76766 if (downgradeType && type2 !== downgradeType) {
76767 if (downgradeType !== "generic" && type2 !== "generic") {
76768 downgradeType = "building_address";
76770 downgradeType = "generic";
76773 downgradeType = type2;
76777 return downgradeType;
76779 function downgradeTypeForEntityID(entityID) {
76780 var graph = context.graph();
76781 var entity = graph.entity(entityID);
76782 var preset = _mainPresetIndex.match(entity, graph);
76783 if (!preset || preset.isFallback())
76785 if (entity.type === "node" && preset.id !== "address" && Object.keys(entity.tags).some(function(key) {
76786 return key.match(/^addr:.{1,}/);
76790 var geometry = entity.geometry(graph);
76791 if (geometry === "area" && entity.tags.building && !preset.tags.building) {
76794 if (geometry === "vertex" && Object.keys(entity.tags).length) {
76799 var buildingKeysToKeep = ["architect", "building", "height", "layer", "source", "type", "wheelchair"];
76800 var addressKeysToKeep = ["source"];
76801 var operation = function() {
76802 context.perform(function(graph) {
76803 for (var i2 in selectedIDs) {
76804 var entityID = selectedIDs[i2];
76805 var type2 = downgradeTypeForEntityID(entityID);
76808 var tags = Object.assign({}, graph.entity(entityID).tags);
76809 for (var key in tags) {
76810 if (type2 === "address" && addressKeysToKeep.indexOf(key) !== -1)
76812 if (type2 === "building") {
76813 if (buildingKeysToKeep.indexOf(key) !== -1 || key.match(/^building:.{1,}/) || key.match(/^roof:.{1,}/))
76816 if (type2 !== "generic") {
76817 if (key.match(/^addr:.{1,}/) || key.match(/^source:.{1,}/))
76822 graph = actionChangeTags(entityID, tags)(graph);
76825 }, operation.annotation());
76826 context.validator().validate();
76827 context.enter(modeSelect(context, selectedIDs));
76829 operation.available = function() {
76830 return _downgradeType;
76832 operation.disabled = function() {
76833 if (selectedIDs.some(hasWikidataTag)) {
76834 return "has_wikidata_tag";
76837 function hasWikidataTag(id2) {
76838 var entity = context.entity(id2);
76839 return entity.tags.wikidata && entity.tags.wikidata.trim().length > 0;
76842 operation.tooltip = function() {
76843 var disable = operation.disabled();
76844 return disable ? _t.append("operations.downgrade." + disable + "." + _multi) : _t.append("operations.downgrade.description." + _downgradeType);
76846 operation.annotation = function() {
76848 if (_downgradeType === "building_address") {
76849 suffix = "generic";
76851 suffix = _downgradeType;
76853 return _t("operations.downgrade.annotation." + suffix, { n: _affectedFeatureCount });
76855 operation.id = "downgrade";
76856 operation.keys = [uiCmd("\u232B")];
76857 operation.title = _t.append("operations.downgrade.title");
76858 operation.behavior = behaviorOperation(context).which(operation);
76862 // modules/operations/extract.js
76863 function operationExtract(context, selectedIDs) {
76864 var _amount = selectedIDs.length === 1 ? "single" : "multiple";
76865 var _geometries = utilArrayUniq(selectedIDs.map(function(entityID) {
76866 return context.graph().hasEntity(entityID) && context.graph().geometry(entityID);
76867 }).filter(Boolean));
76868 var _geometryID = _geometries.length === 1 ? _geometries[0] : "feature";
76870 var _actions = selectedIDs.map(function(entityID) {
76871 var graph = context.graph();
76872 var entity = graph.hasEntity(entityID);
76873 if (!entity || !entity.hasInterestingTags())
76875 if (entity.type === "node" && graph.parentWays(entity).length === 0)
76877 if (entity.type !== "node") {
76878 var preset = _mainPresetIndex.match(entity, graph);
76879 if (preset.geometry.indexOf("point") === -1)
76882 _extent = _extent ? _extent.extend(entity.extent(graph)) : entity.extent(graph);
76883 return actionExtract(entityID, context.projection);
76884 }).filter(Boolean);
76885 var operation = function() {
76886 var combinedAction = function(graph) {
76887 _actions.forEach(function(action) {
76888 graph = action(graph);
76892 context.perform(combinedAction, operation.annotation());
76893 var extractedNodeIDs = _actions.map(function(action) {
76894 return action.getExtractedNodeID();
76896 context.enter(modeSelect(context, extractedNodeIDs));
76898 operation.available = function() {
76899 return _actions.length && selectedIDs.length === _actions.length;
76901 operation.disabled = function() {
76902 if (_extent && _extent.percentContainedIn(context.map().extent()) < 0.8) {
76903 return "too_large";
76904 } else if (selectedIDs.some(function(entityID) {
76905 return context.graph().geometry(entityID) === "vertex" && context.hasHiddenConnections(entityID);
76907 return "connected_to_hidden";
76911 operation.tooltip = function() {
76912 var disableReason = operation.disabled();
76913 if (disableReason) {
76914 return _t.append("operations.extract." + disableReason + "." + _amount);
76916 return _t.append("operations.extract.description." + _geometryID + "." + _amount);
76919 operation.annotation = function() {
76920 return _t("operations.extract.annotation", { n: selectedIDs.length });
76922 operation.id = "extract";
76923 operation.keys = [_t("operations.extract.key")];
76924 operation.title = _t.append("operations.extract.title");
76925 operation.behavior = behaviorOperation(context).which(operation);
76929 // modules/operations/merge.js
76930 function operationMerge(context, selectedIDs) {
76931 var _action = getAction();
76932 function getAction() {
76933 var join = actionJoin(selectedIDs);
76934 if (!join.disabled(context.graph()))
76936 var merge3 = actionMerge(selectedIDs);
76937 if (!merge3.disabled(context.graph()))
76939 var mergePolygon = actionMergePolygon(selectedIDs);
76940 if (!mergePolygon.disabled(context.graph()))
76941 return mergePolygon;
76942 var mergeNodes = actionMergeNodes(selectedIDs);
76943 if (!mergeNodes.disabled(context.graph()))
76945 if (join.disabled(context.graph()) !== "not_eligible")
76947 if (merge3.disabled(context.graph()) !== "not_eligible")
76949 if (mergePolygon.disabled(context.graph()) !== "not_eligible")
76950 return mergePolygon;
76953 var operation = function() {
76954 if (operation.disabled())
76956 context.perform(_action, operation.annotation());
76957 context.validator().validate();
76958 var resultIDs = selectedIDs.filter(context.hasEntity);
76959 if (resultIDs.length > 1) {
76960 var interestingIDs = resultIDs.filter(function(id2) {
76961 return context.entity(id2).hasInterestingTags();
76963 if (interestingIDs.length)
76964 resultIDs = interestingIDs;
76966 context.enter(modeSelect(context, resultIDs));
76968 operation.available = function() {
76969 return selectedIDs.length >= 2;
76971 operation.disabled = function() {
76972 var actionDisabled = _action.disabled(context.graph());
76973 if (actionDisabled)
76974 return actionDisabled;
76975 var osm = context.connection();
76976 if (osm && _action.resultingWayNodesLength && _action.resultingWayNodesLength(context.graph()) > osm.maxWayNodes()) {
76977 return "too_many_vertices";
76981 operation.tooltip = function() {
76982 var disabled = operation.disabled();
76984 if (disabled === "conflicting_relations") {
76985 return _t.append("operations.merge.conflicting_relations");
76987 if (disabled === "restriction" || disabled === "connectivity") {
76989 "operations.merge.damage_relation",
76990 { relation: _mainPresetIndex.item("type/" + disabled).name() }
76993 return _t.append("operations.merge." + disabled);
76995 return _t.append("operations.merge.description");
76997 operation.annotation = function() {
76998 return _t("operations.merge.annotation", { n: selectedIDs.length });
77000 operation.id = "merge";
77001 operation.keys = [_t("operations.merge.key")];
77002 operation.title = _t.append("operations.merge.title");
77003 operation.behavior = behaviorOperation(context).which(operation);
77007 // modules/operations/paste.js
77008 function operationPaste(context) {
77010 var operation = function() {
77013 var oldIDs = context.copyIDs();
77014 if (!oldIDs.length)
77016 var projection2 = context.projection;
77017 var extent = geoExtent();
77018 var oldGraph = context.copyGraph();
77020 var action = actionCopyEntities(oldIDs, oldGraph);
77021 context.perform(action);
77022 var copies = action.copies();
77023 var originals = /* @__PURE__ */ new Set();
77024 Object.values(copies).forEach(function(entity) {
77025 originals.add(entity.id);
77027 for (var id2 in copies) {
77028 var oldEntity = oldGraph.entity(id2);
77029 var newEntity = copies[id2];
77030 extent._extend(oldEntity.extent(oldGraph));
77031 var parents = context.graph().parentWays(newEntity);
77032 var parentCopied = parents.some(function(parent) {
77033 return originals.has(parent.id);
77035 if (!parentCopied) {
77036 newIDs.push(newEntity.id);
77039 var copyPoint = context.copyLonLat() && projection2(context.copyLonLat()) || projection2(extent.center());
77040 var delta = geoVecSubtract(_pastePoint, copyPoint);
77041 context.replace(actionMove(newIDs, delta, projection2), operation.annotation());
77042 context.enter(modeSelect(context, newIDs));
77044 operation.point = function(val) {
77048 operation.available = function() {
77049 return context.mode().id === "browse";
77051 operation.disabled = function() {
77052 return !context.copyIDs().length;
77054 operation.tooltip = function() {
77055 var oldGraph = context.copyGraph();
77056 var ids = context.copyIDs();
77058 return _t.append("operations.paste.nothing_copied");
77060 return _t.append("operations.paste.description", { feature: utilDisplayLabel(oldGraph.entity(ids[0]), oldGraph), n: ids.length });
77062 operation.annotation = function() {
77063 var ids = context.copyIDs();
77064 return _t("operations.paste.annotation", { n: ids.length });
77066 operation.id = "paste";
77067 operation.keys = [uiCmd("\u2318V")];
77068 operation.title = _t.append("operations.paste.title");
77072 // modules/operations/reverse.js
77073 function operationReverse(context, selectedIDs) {
77074 var operation = function() {
77075 context.perform(function combinedReverseAction(graph) {
77076 actions().forEach(function(action) {
77077 graph = action(graph);
77080 }, operation.annotation());
77081 context.validator().validate();
77083 function actions(situation) {
77084 return selectedIDs.map(function(entityID) {
77085 var entity = context.hasEntity(entityID);
77088 if (situation === "toolbar") {
77089 if (entity.type === "way" && (!entity.isOneWay() && !entity.isSided()))
77092 var geometry = entity.geometry(context.graph());
77093 if (entity.type !== "node" && geometry !== "line")
77095 var action = actionReverse(entityID);
77096 if (action.disabled(context.graph()))
77099 }).filter(Boolean);
77101 function reverseTypeID() {
77102 var acts = actions();
77103 var nodeActionCount = acts.filter(function(act) {
77104 var entity = context.hasEntity(act.entityID());
77105 return entity && entity.type === "node";
77107 if (nodeActionCount === 0)
77109 if (nodeActionCount === acts.length)
77113 operation.available = function(situation) {
77114 return actions(situation).length > 0;
77116 operation.disabled = function() {
77119 operation.tooltip = function() {
77120 return _t.append("operations.reverse.description." + reverseTypeID());
77122 operation.annotation = function() {
77123 var acts = actions();
77124 return _t("operations.reverse.annotation." + reverseTypeID(), { n: acts.length });
77126 operation.id = "reverse";
77127 operation.keys = [_t("operations.reverse.key")];
77128 operation.title = _t.append("operations.reverse.title");
77129 operation.behavior = behaviorOperation(context).which(operation);
77133 // modules/operations/split.js
77134 function operationSplit(context, selectedIDs) {
77135 var _vertexIds = selectedIDs.filter(function(id2) {
77136 return context.graph().geometry(id2) === "vertex";
77138 var _selectedWayIds = selectedIDs.filter(function(id2) {
77139 var entity = context.graph().hasEntity(id2);
77140 return entity && entity.type === "way";
77142 var _isAvailable = _vertexIds.length > 0 && _vertexIds.length + _selectedWayIds.length === selectedIDs.length;
77143 var _action = actionSplit(_vertexIds);
77145 var _geometry = "feature";
77146 var _waysAmount = "single";
77147 var _nodesAmount = _vertexIds.length === 1 ? "single" : "multiple";
77148 if (_isAvailable) {
77149 if (_selectedWayIds.length)
77150 _action.limitWays(_selectedWayIds);
77151 _ways = _action.ways(context.graph());
77152 var geometries = {};
77153 _ways.forEach(function(way) {
77154 geometries[way.geometry(context.graph())] = true;
77156 if (Object.keys(geometries).length === 1) {
77157 _geometry = Object.keys(geometries)[0];
77159 _waysAmount = _ways.length === 1 ? "single" : "multiple";
77161 var operation = function() {
77162 var difference = context.perform(_action, operation.annotation());
77163 var idsToSelect = _vertexIds.concat(difference.extantIDs().filter(function(id2) {
77164 return context.entity(id2).type === "way";
77166 context.enter(modeSelect(context, idsToSelect));
77168 operation.relatedEntityIds = function() {
77169 return _selectedWayIds.length ? [] : _ways.map((way) => way.id);
77171 operation.available = function() {
77172 return _isAvailable;
77174 operation.disabled = function() {
77175 var reason = _action.disabled(context.graph());
77178 } else if (selectedIDs.some(context.hasHiddenConnections)) {
77179 return "connected_to_hidden";
77183 operation.tooltip = function() {
77184 var disable = operation.disabled();
77185 return disable ? _t.append("operations.split." + disable) : _t.append("operations.split.description." + _geometry + "." + _waysAmount + "." + _nodesAmount + "_node");
77187 operation.annotation = function() {
77188 return _t("operations.split.annotation." + _geometry, { n: _ways.length });
77190 operation.icon = function() {
77191 if (_waysAmount === "multiple") {
77192 return "#iD-operation-split-multiple";
77194 return "#iD-operation-split";
77197 operation.id = "split";
77198 operation.keys = [_t("operations.split.key")];
77199 operation.title = _t.append("operations.split.title");
77200 operation.behavior = behaviorOperation(context).which(operation);
77204 // modules/operations/straighten.js
77205 function operationStraighten(context, selectedIDs) {
77206 var _wayIDs = selectedIDs.filter(function(id2) {
77207 return id2.charAt(0) === "w";
77209 var _nodeIDs = selectedIDs.filter(function(id2) {
77210 return id2.charAt(0) === "n";
77212 var _amount = (_wayIDs.length ? _wayIDs : _nodeIDs).length === 1 ? "single" : "multiple";
77213 var _nodes = utilGetAllNodes(selectedIDs, context.graph());
77214 var _coords = _nodes.map(function(n2) {
77217 var _extent = utilTotalExtent(selectedIDs, context.graph());
77218 var _action = chooseAction();
77220 function chooseAction() {
77221 if (_wayIDs.length === 0 && _nodeIDs.length > 2) {
77222 _geometry = "point";
77223 return actionStraightenNodes(_nodeIDs, context.projection);
77224 } else if (_wayIDs.length > 0 && (_nodeIDs.length === 0 || _nodeIDs.length === 2)) {
77225 var startNodeIDs = [];
77226 var endNodeIDs = [];
77227 for (var i2 = 0; i2 < selectedIDs.length; i2++) {
77228 var entity = context.entity(selectedIDs[i2]);
77229 if (entity.type === "node") {
77231 } else if (entity.type !== "way" || entity.isClosed()) {
77234 startNodeIDs.push(entity.first());
77235 endNodeIDs.push(entity.last());
77237 startNodeIDs = startNodeIDs.filter(function(n2) {
77238 return startNodeIDs.indexOf(n2) === startNodeIDs.lastIndexOf(n2);
77240 endNodeIDs = endNodeIDs.filter(function(n2) {
77241 return endNodeIDs.indexOf(n2) === endNodeIDs.lastIndexOf(n2);
77243 if (utilArrayDifference(startNodeIDs, endNodeIDs).length + utilArrayDifference(endNodeIDs, startNodeIDs).length !== 2)
77245 var wayNodeIDs = utilGetAllNodes(_wayIDs, context.graph()).map(function(node) {
77248 if (wayNodeIDs.length <= 2)
77250 if (_nodeIDs.length === 2 && (wayNodeIDs.indexOf(_nodeIDs[0]) === -1 || wayNodeIDs.indexOf(_nodeIDs[1]) === -1))
77252 if (_nodeIDs.length) {
77253 _extent = utilTotalExtent(_nodeIDs, context.graph());
77255 _geometry = "line";
77256 return actionStraightenWay(selectedIDs, context.projection);
77260 function operation() {
77263 context.perform(_action, operation.annotation());
77264 window.setTimeout(function() {
77265 context.validator().validate();
77268 operation.available = function() {
77269 return Boolean(_action);
77271 operation.disabled = function() {
77272 var reason = _action.disabled(context.graph());
77275 } else if (_extent.percentContainedIn(context.map().extent()) < 0.8) {
77276 return "too_large";
77277 } else if (someMissing()) {
77278 return "not_downloaded";
77279 } else if (selectedIDs.some(context.hasHiddenConnections)) {
77280 return "connected_to_hidden";
77283 function someMissing() {
77284 if (context.inIntro())
77286 var osm = context.connection();
77288 var missing = _coords.filter(function(loc) {
77289 return !osm.isDataLoaded(loc);
77291 if (missing.length) {
77292 missing.forEach(function(loc) {
77293 context.loadTileAtLoc(loc);
77301 operation.tooltip = function() {
77302 var disable = operation.disabled();
77303 return disable ? _t.append("operations.straighten." + disable + "." + _amount) : _t.append("operations.straighten.description." + _geometry + (_wayIDs.length === 1 ? "" : "s"));
77305 operation.annotation = function() {
77306 return _t("operations.straighten.annotation." + _geometry, { n: _wayIDs.length ? _wayIDs.length : _nodeIDs.length });
77308 operation.id = "straighten";
77309 operation.keys = [_t("operations.straighten.key")];
77310 operation.title = _t.append("operations.straighten.title");
77311 operation.behavior = behaviorOperation(context).which(operation);
77315 // modules/modes/select.js
77316 function modeSelect(context, selectedIDs) {
77321 var keybinding = utilKeybinding("select");
77322 var _breatheBehavior = behaviorBreathe(context);
77323 var _modeDragNode = modeDragNode(context);
77324 var _selectBehavior;
77325 var _behaviors = [];
77326 var _operations = [];
77327 var _newFeature = false;
77328 var _follow = false;
77329 var _focusedParentWayId;
77330 var _focusedVertexIds;
77331 function singular() {
77332 if (selectedIDs && selectedIDs.length === 1) {
77333 return context.hasEntity(selectedIDs[0]);
77336 function selectedEntities() {
77337 return selectedIDs.map(function(id2) {
77338 return context.hasEntity(id2);
77339 }).filter(Boolean);
77341 function checkSelectedIDs() {
77343 if (Array.isArray(selectedIDs)) {
77344 ids = selectedIDs.filter(function(id2) {
77345 return context.hasEntity(id2);
77349 context.enter(modeBrowse(context));
77351 } else if (selectedIDs.length > 1 && ids.length === 1 || selectedIDs.length === 1 && ids.length > 1) {
77352 context.enter(modeSelect(context, ids));
77358 function parentWaysIdsOfSelection(onlyCommonParents) {
77359 var graph = context.graph();
77361 for (var i2 = 0; i2 < selectedIDs.length; i2++) {
77362 var entity = context.hasEntity(selectedIDs[i2]);
77363 if (!entity || entity.geometry(graph) !== "vertex") {
77366 var currParents = graph.parentWays(entity).map(function(w) {
77369 if (!parents.length) {
77370 parents = currParents;
77373 parents = (onlyCommonParents ? utilArrayIntersection : utilArrayUnion)(parents, currParents);
77374 if (!parents.length) {
77380 function childNodeIdsOfSelection(onlyCommon) {
77381 var graph = context.graph();
77383 for (var i2 = 0; i2 < selectedIDs.length; i2++) {
77384 var entity = context.hasEntity(selectedIDs[i2]);
77385 if (!entity || !["area", "line"].includes(entity.geometry(graph))) {
77388 var currChilds = graph.childNodes(entity).map(function(node) {
77391 if (!childs.length) {
77392 childs = currChilds;
77395 childs = (onlyCommon ? utilArrayIntersection : utilArrayUnion)(childs, currChilds);
77396 if (!childs.length) {
77402 function checkFocusedParent() {
77403 if (_focusedParentWayId) {
77404 var parents = parentWaysIdsOfSelection(true);
77405 if (parents.indexOf(_focusedParentWayId) === -1)
77406 _focusedParentWayId = null;
77409 function parentWayIdForVertexNavigation() {
77410 var parentIds = parentWaysIdsOfSelection(true);
77411 if (_focusedParentWayId && parentIds.indexOf(_focusedParentWayId) !== -1) {
77412 return _focusedParentWayId;
77414 return parentIds.length ? parentIds[0] : null;
77416 mode.selectedIDs = function(val) {
77417 if (!arguments.length)
77418 return selectedIDs;
77422 mode.zoomToSelected = function() {
77423 context.map().zoomToEase(selectedEntities());
77425 mode.newFeature = function(val) {
77426 if (!arguments.length)
77427 return _newFeature;
77431 mode.selectBehavior = function(val) {
77432 if (!arguments.length)
77433 return _selectBehavior;
77434 _selectBehavior = val;
77437 mode.follow = function(val) {
77438 if (!arguments.length)
77443 function loadOperations() {
77444 _operations.forEach(function(operation) {
77445 if (operation.behavior) {
77446 context.uninstall(operation.behavior);
77449 _operations = Object.values(operations_exports).map(function(o) {
77450 return o(context, selectedIDs);
77451 }).filter(function(o) {
77452 return o.id !== "delete" && o.id !== "downgrade" && o.id !== "copy";
77454 // group copy/downgrade/delete operation together at the end of the list
77455 operationCopy(context, selectedIDs),
77456 operationDowngrade(context, selectedIDs),
77457 operationDelete(context, selectedIDs)
77458 ]).filter(function(operation) {
77459 return operation.available();
77461 _operations.forEach(function(operation) {
77462 if (operation.behavior) {
77463 context.install(operation.behavior);
77466 context.ui().closeEditMenu();
77468 mode.operations = function() {
77469 return _operations;
77471 mode.enter = function() {
77472 if (!checkSelectedIDs())
77474 context.features().forceVisible(selectedIDs);
77475 _modeDragNode.restoreSelectedIDs(selectedIDs);
77477 if (!_behaviors.length) {
77478 if (!_selectBehavior)
77479 _selectBehavior = behaviorSelect(context);
77481 behaviorPaste(context),
77483 behaviorHover(context).on("hover", context.ui().sidebar.hoverModeSelect),
77485 behaviorLasso(context),
77486 _modeDragNode.behavior,
77487 modeDragNote(context).behavior
77490 _behaviors.forEach(context.install);
77491 keybinding.on(_t("inspector.zoom_to.key"), mode.zoomToSelected).on(["[", "pgup"], previousVertex).on(["]", "pgdown"], nextVertex).on(["{", uiCmd("\u2318["), "home"], firstVertex).on(["}", uiCmd("\u2318]"), "end"], lastVertex).on(uiCmd("\u21E7\u2190"), nudgeSelection([-10, 0])).on(uiCmd("\u21E7\u2191"), nudgeSelection([0, -10])).on(uiCmd("\u21E7\u2192"), nudgeSelection([10, 0])).on(uiCmd("\u21E7\u2193"), nudgeSelection([0, 10])).on(uiCmd("\u21E7\u2325\u2190"), nudgeSelection([-100, 0])).on(uiCmd("\u21E7\u2325\u2191"), nudgeSelection([0, -100])).on(uiCmd("\u21E7\u2325\u2192"), nudgeSelection([100, 0])).on(uiCmd("\u21E7\u2325\u2193"), nudgeSelection([0, 100])).on(utilKeybinding.plusKeys.map((key) => uiCmd("\u21E7" + key)), scaleSelection(1.05)).on(utilKeybinding.plusKeys.map((key) => uiCmd("\u21E7\u2325" + key)), scaleSelection(Math.pow(1.05, 5))).on(utilKeybinding.minusKeys.map((key) => uiCmd("\u21E7" + key)), scaleSelection(1 / 1.05)).on(utilKeybinding.minusKeys.map((key) => uiCmd("\u21E7\u2325" + key)), scaleSelection(1 / Math.pow(1.05, 5))).on(["\\", "pause"], focusNextParent).on(uiCmd("\u2318\u2191"), selectParent).on(uiCmd("\u2318\u2193"), selectChild).on("\u238B", esc, true);
77492 select_default2(document).call(keybinding);
77493 context.ui().sidebar.select(selectedIDs, _newFeature);
77494 context.history().on("change.select", function() {
77497 }).on("undone.select", checkSelectedIDs).on("redone.select", checkSelectedIDs);
77498 context.map().on("drawn.select", selectElements).on("crossEditableZoom.select", function() {
77500 _breatheBehavior.restartIfNeeded(context.surface());
77502 context.map().doubleUpHandler().on("doubleUp.modeSelect", didDoubleUp);
77505 var extent = geoExtent();
77506 var graph = context.graph();
77507 selectedIDs.forEach(function(id2) {
77508 var entity = context.entity(id2);
77509 extent._extend(entity.extent(graph));
77511 var loc = extent.center();
77512 context.map().centerEase(loc);
77515 function nudgeSelection(delta) {
77516 return function() {
77517 if (!context.map().withinEditableZoom())
77519 var moveOp = operationMove(context, selectedIDs);
77520 if (moveOp.disabled()) {
77521 context.ui().flash.duration(4e3).iconName("#iD-operation-" + moveOp.id).iconClass("operation disabled").label(moveOp.tooltip())();
77523 context.perform(actionMove(selectedIDs, delta, context.projection), moveOp.annotation());
77524 context.validator().validate();
77528 function scaleSelection(factor) {
77529 return function() {
77530 if (!context.map().withinEditableZoom())
77532 let nodes = utilGetAllNodes(selectedIDs, context.graph());
77533 let isUp = factor > 1;
77534 if (nodes.length <= 1)
77536 let extent2 = utilTotalExtent(selectedIDs, context.graph());
77537 function scalingDisabled() {
77539 return "too_small";
77540 } else if (extent2.percentContainedIn(context.map().extent()) < 0.8) {
77541 return "too_large";
77542 } else if (someMissing() || selectedIDs.some(incompleteRelation)) {
77543 return "not_downloaded";
77544 } else if (selectedIDs.some(context.hasHiddenConnections)) {
77545 return "connected_to_hidden";
77548 function tooSmall() {
77551 let dLon = Math.abs(extent2[1][0] - extent2[0][0]);
77552 let dLat = Math.abs(extent2[1][1] - extent2[0][1]);
77553 return dLon < geoMetersToLon(1, extent2[1][1]) && dLat < geoMetersToLat(1);
77555 function someMissing() {
77556 if (context.inIntro())
77558 let osm = context.connection();
77560 let missing = nodes.filter(function(n2) {
77561 return !osm.isDataLoaded(n2.loc);
77563 if (missing.length) {
77564 missing.forEach(function(loc2) {
77565 context.loadTileAtLoc(loc2);
77572 function incompleteRelation(id2) {
77573 let entity = context.entity(id2);
77574 return entity.type === "relation" && !entity.isComplete(context.graph());
77577 const disabled = scalingDisabled();
77579 let multi = selectedIDs.length === 1 ? "single" : "multiple";
77580 context.ui().flash.duration(4e3).iconName("#iD-icon-no").iconClass("operation disabled").label(_t.append("operations.scale." + disabled + "." + multi))();
77582 const pivot = context.projection(extent2.center());
77583 const annotation = _t("operations.scale.annotation." + (isUp ? "up" : "down") + ".feature", { n: selectedIDs.length });
77584 context.perform(actionScale(selectedIDs, pivot, factor, context.projection), annotation);
77585 context.validator().validate();
77589 function didDoubleUp(d3_event, loc2) {
77590 if (!context.map().withinEditableZoom())
77592 var target = select_default2(d3_event.target);
77593 var datum2 = target.datum();
77594 var entity = datum2 && datum2.properties && datum2.properties.entity;
77597 if (entity instanceof osmWay && target.classed("target")) {
77598 var choice = geoChooseEdge(context.graph().childNodes(entity), loc2, context.projection);
77599 var prev = entity.nodes[choice.index - 1];
77600 var next = entity.nodes[choice.index];
77602 actionAddMidpoint({ loc: choice.loc, edge: [prev, next] }, osmNode()),
77603 _t("operations.add.annotation.vertex")
77605 context.validator().validate();
77606 } else if (entity.type === "midpoint") {
77608 actionAddMidpoint({ loc: entity.loc, edge: entity.edge }, osmNode()),
77609 _t("operations.add.annotation.vertex")
77611 context.validator().validate();
77614 function selectElements() {
77615 if (!checkSelectedIDs())
77617 var surface = context.surface();
77618 surface.selectAll(".selected-member").classed("selected-member", false);
77619 surface.selectAll(".selected").classed("selected", false);
77620 surface.selectAll(".related").classed("related", false);
77621 checkFocusedParent();
77622 if (_focusedParentWayId) {
77623 surface.selectAll(utilEntitySelector([_focusedParentWayId])).classed("related", true);
77625 if (context.map().withinEditableZoom()) {
77626 surface.selectAll(utilDeepMemberSelector(
77630 /* skipMultipolgonMembers */
77631 )).classed("selected-member", true);
77632 surface.selectAll(utilEntityOrDeepMemberSelector(selectedIDs, context.graph())).classed("selected", true);
77636 if (context.container().select(".combobox").size())
77638 context.enter(modeBrowse(context));
77640 function firstVertex(d3_event) {
77641 d3_event.preventDefault();
77642 var entity = singular();
77643 var parentId = parentWayIdForVertexNavigation();
77645 if (entity && entity.type === "way") {
77647 } else if (parentId) {
77648 way = context.entity(parentId);
77650 _focusedParentWayId = way && way.id;
77653 mode.selectedIDs([way.first()]).follow(true)
77657 function lastVertex(d3_event) {
77658 d3_event.preventDefault();
77659 var entity = singular();
77660 var parentId = parentWayIdForVertexNavigation();
77662 if (entity && entity.type === "way") {
77664 } else if (parentId) {
77665 way = context.entity(parentId);
77667 _focusedParentWayId = way && way.id;
77670 mode.selectedIDs([way.last()]).follow(true)
77674 function previousVertex(d3_event) {
77675 d3_event.preventDefault();
77676 var parentId = parentWayIdForVertexNavigation();
77677 _focusedParentWayId = parentId;
77680 var way = context.entity(parentId);
77681 var length = way.nodes.length;
77682 var curr = way.nodes.indexOf(selectedIDs[0]);
77686 } else if (way.isClosed()) {
77687 index = length - 2;
77689 if (index !== -1) {
77691 mode.selectedIDs([way.nodes[index]]).follow(true)
77695 function nextVertex(d3_event) {
77696 d3_event.preventDefault();
77697 var parentId = parentWayIdForVertexNavigation();
77698 _focusedParentWayId = parentId;
77701 var way = context.entity(parentId);
77702 var length = way.nodes.length;
77703 var curr = way.nodes.indexOf(selectedIDs[0]);
77705 if (curr < length - 1) {
77707 } else if (way.isClosed()) {
77710 if (index !== -1) {
77712 mode.selectedIDs([way.nodes[index]]).follow(true)
77716 function focusNextParent(d3_event) {
77717 d3_event.preventDefault();
77718 var parents = parentWaysIdsOfSelection(true);
77719 if (!parents || parents.length < 2)
77721 var index = parents.indexOf(_focusedParentWayId);
77722 if (index < 0 || index > parents.length - 2) {
77723 _focusedParentWayId = parents[0];
77725 _focusedParentWayId = parents[index + 1];
77727 var surface = context.surface();
77728 surface.selectAll(".related").classed("related", false);
77729 if (_focusedParentWayId) {
77730 surface.selectAll(utilEntitySelector([_focusedParentWayId])).classed("related", true);
77733 function selectParent(d3_event) {
77734 d3_event.preventDefault();
77735 var currentSelectedIds = mode.selectedIDs();
77736 var parentIds = _focusedParentWayId ? [_focusedParentWayId] : parentWaysIdsOfSelection(false);
77737 if (!parentIds.length)
77740 mode.selectedIDs(parentIds)
77742 _focusedVertexIds = currentSelectedIds;
77744 function selectChild(d3_event) {
77745 d3_event.preventDefault();
77746 var currentSelectedIds = mode.selectedIDs();
77747 var childIds = _focusedVertexIds ? _focusedVertexIds.filter((id2) => context.hasEntity(id2)) : childNodeIdsOfSelection(true);
77748 if (!childIds || !childIds.length)
77750 if (currentSelectedIds.length === 1)
77751 _focusedParentWayId = currentSelectedIds[0];
77753 mode.selectedIDs(childIds)
77757 mode.exit = function() {
77758 _newFeature = false;
77759 _focusedVertexIds = null;
77760 _operations.forEach(function(operation) {
77761 if (operation.behavior) {
77762 context.uninstall(operation.behavior);
77766 _behaviors.forEach(context.uninstall);
77767 select_default2(document).call(keybinding.unbind);
77768 context.ui().closeEditMenu();
77769 context.history().on("change.select", null).on("undone.select", null).on("redone.select", null);
77770 var surface = context.surface();
77771 surface.selectAll(".selected-member").classed("selected-member", false);
77772 surface.selectAll(".selected").classed("selected", false);
77773 surface.selectAll(".highlighted").classed("highlighted", false);
77774 surface.selectAll(".related").classed("related", false);
77775 context.map().on("drawn.select", null);
77776 context.ui().sidebar.hide();
77777 context.features().forceVisible([]);
77778 var entity = singular();
77779 if (_newFeature && entity && entity.type === "relation" && // no tags
77780 Object.keys(entity.tags).length === 0 && // no parent relations
77781 context.graph().parentRelations(entity).length === 0 && // no members or one member with no role
77782 (entity.members.length === 0 || entity.members.length === 1 && !entity.members[0].role)) {
77783 var deleteAction = actionDeleteRelation(
77786 /* don't delete untagged members */
77788 context.perform(deleteAction, _t("operations.delete.annotation.relation"));
77789 context.validator().validate();
77795 // modules/behavior/lasso.js
77796 function behaviorLasso(context) {
77797 var _pointerPrefix = "PointerEvent" in window ? "pointer" : "mouse";
77798 var behavior = function(selection2) {
77800 function pointerdown(d3_event) {
77802 if (d3_event.button === button && d3_event.shiftKey === true) {
77804 select_default2(window).on(_pointerPrefix + "move.lasso", pointermove).on(_pointerPrefix + "up.lasso", pointerup);
77805 d3_event.stopPropagation();
77808 function pointermove() {
77810 lasso = uiLasso(context);
77811 context.surface().call(lasso);
77813 lasso.p(context.map().mouse());
77815 function normalize2(a, b) {
77817 [Math.min(a[0], b[0]), Math.min(a[1], b[1])],
77818 [Math.max(a[0], b[0]), Math.max(a[1], b[1])]
77821 function lassoed() {
77824 var graph = context.graph();
77826 if (context.map().editableDataEnabled(
77828 /* skipZoomCheck */
77829 ) && context.map().isInWideSelection()) {
77830 limitToNodes = new Set(utilGetAllNodes(context.selectedIDs(), graph));
77831 } else if (!context.map().editableDataEnabled()) {
77834 var bounds = lasso.extent().map(context.projection.invert);
77835 var extent = geoExtent(normalize2(bounds[0], bounds[1]));
77836 var intersects = context.history().intersects(extent).filter(function(entity) {
77837 return entity.type === "node" && (!limitToNodes || limitToNodes.has(entity)) && geoPointInPolygon(context.projection(entity.loc), lasso.coordinates) && !context.features().isHidden(entity, graph, entity.geometry(graph));
77839 intersects.sort(function(node1, node2) {
77840 var parents1 = graph.parentWays(node1);
77841 var parents2 = graph.parentWays(node2);
77842 if (parents1.length && parents2.length) {
77843 var sharedParents = utilArrayIntersection(parents1, parents2);
77844 if (sharedParents.length) {
77845 var sharedParentNodes = sharedParents[0].nodes;
77846 return sharedParentNodes.indexOf(node1.id) - sharedParentNodes.indexOf(node2.id);
77848 return Number(parents1[0].id.slice(1)) - Number(parents2[0].id.slice(1));
77850 } else if (parents1.length || parents2.length) {
77851 return parents1.length - parents2.length;
77853 return node1.loc[0] - node2.loc[0];
77855 return intersects.map(function(entity) {
77859 function pointerup() {
77860 select_default2(window).on(_pointerPrefix + "move.lasso", null).on(_pointerPrefix + "up.lasso", null);
77863 var ids = lassoed();
77866 context.enter(modeSelect(context, ids));
77869 selection2.on(_pointerPrefix + "down.lasso", pointerdown);
77871 behavior.off = function(selection2) {
77872 selection2.on(_pointerPrefix + "down.lasso", null);
77877 // modules/modes/browse.js
77878 function modeBrowse(context) {
77882 title: _t.append("modes.browse.title"),
77883 description: _t.append("modes.browse.description")
77886 var _selectBehavior;
77887 var _behaviors = [];
77888 mode.selectBehavior = function(val) {
77889 if (!arguments.length)
77890 return _selectBehavior;
77891 _selectBehavior = val;
77894 mode.enter = function() {
77895 if (!_behaviors.length) {
77896 if (!_selectBehavior)
77897 _selectBehavior = behaviorSelect(context);
77899 behaviorPaste(context),
77900 behaviorHover(context).on("hover", context.ui().sidebar.hover),
77902 behaviorLasso(context),
77903 modeDragNode(context).behavior,
77904 modeDragNote(context).behavior
77907 _behaviors.forEach(context.install);
77908 if (document.activeElement && document.activeElement.blur) {
77909 document.activeElement.blur();
77912 context.ui().sidebar.show(sidebar);
77914 context.ui().sidebar.select(null);
77917 mode.exit = function() {
77918 context.ui().sidebar.hover.cancel();
77919 _behaviors.forEach(context.uninstall);
77921 context.ui().sidebar.hide();
77924 mode.sidebar = function(_) {
77925 if (!arguments.length)
77930 mode.operations = function() {
77931 return [operationPaste(context)];
77936 // modules/behavior/add_way.js
77937 function behaviorAddWay(context) {
77938 var dispatch10 = dispatch_default("start", "startFromWay", "startFromNode");
77939 var draw = behaviorDraw(context);
77940 function behavior(surface) {
77941 draw.on("click", function() {
77942 dispatch10.apply("start", this, arguments);
77943 }).on("clickWay", function() {
77944 dispatch10.apply("startFromWay", this, arguments);
77945 }).on("clickNode", function() {
77946 dispatch10.apply("startFromNode", this, arguments);
77947 }).on("cancel", behavior.cancel).on("finish", behavior.cancel);
77948 context.map().dblclickZoomEnable(false);
77949 surface.call(draw);
77951 behavior.off = function(surface) {
77952 surface.call(draw.off);
77954 behavior.cancel = function() {
77955 window.setTimeout(function() {
77956 context.map().dblclickZoomEnable(true);
77958 context.enter(modeBrowse(context));
77960 return utilRebind(behavior, dispatch10, "on");
77963 // modules/behavior/hash.js
77964 function behaviorHash(context) {
77965 var _cachedHash = null;
77966 var _latitudeLimit = 90 - 1e-8;
77967 function computedHashParameters() {
77968 var map2 = context.map();
77969 var center = map2.center();
77970 var zoom = map2.zoom();
77971 var precision2 = Math.max(0, Math.ceil(Math.log(zoom) / Math.LN2));
77972 var oldParams = utilObjectOmit(
77973 utilStringQs(window.location.hash),
77974 ["comment", "source", "hashtags", "walkthrough"]
77976 var newParams = {};
77977 delete oldParams.id;
77978 var selected = context.selectedIDs().filter(function(id2) {
77979 return context.hasEntity(id2);
77981 if (selected.length) {
77982 newParams.id = selected.join(",");
77984 newParams.map = zoom.toFixed(2) + "/" + center[1].toFixed(precision2) + "/" + center[0].toFixed(precision2);
77985 return Object.assign(oldParams, newParams);
77987 function computedHash() {
77988 return "#" + utilQsString(computedHashParameters(), true);
77990 function computedTitle(includeChangeCount) {
77991 var baseTitle = context.documentTitleBase() || "iD";
77995 var selected = context.selectedIDs().filter(function(id2) {
77996 return context.hasEntity(id2);
77998 if (selected.length) {
77999 var firstLabel = utilDisplayLabel(context.entity(selected[0]), context.graph());
78000 if (selected.length > 1) {
78001 contextual = _t("title.labeled_and_more", {
78002 labeled: firstLabel,
78003 count: selected.length - 1
78006 contextual = firstLabel;
78008 titleID = "context";
78010 if (includeChangeCount) {
78011 changeCount = context.history().difference().summary().length;
78012 if (changeCount > 0) {
78013 titleID = contextual ? "changes_context" : "changes";
78017 return _t("title.format." + titleID, {
78018 changes: changeCount,
78020 context: contextual
78025 function updateTitle(includeChangeCount) {
78026 if (!context.setsDocumentTitle())
78028 var newTitle = computedTitle(includeChangeCount);
78029 if (document.title !== newTitle) {
78030 document.title = newTitle;
78033 function updateHashIfNeeded() {
78034 if (context.inIntro())
78036 var latestHash = computedHash();
78037 if (_cachedHash !== latestHash) {
78038 _cachedHash = latestHash;
78039 window.history.replaceState(null, computedTitle(
78041 /* includeChangeCount */
78045 /* includeChangeCount */
78047 const q = utilStringQs(latestHash);
78049 corePreferences("map-location", q.map);
78053 var _throttledUpdate = throttle_default(updateHashIfNeeded, 500);
78054 var _throttledUpdateTitle = throttle_default(function() {
78057 /* includeChangeCount */
78060 function hashchange() {
78061 if (window.location.hash === _cachedHash)
78063 _cachedHash = window.location.hash;
78064 var q = utilStringQs(_cachedHash);
78065 var mapArgs = (q.map || "").split("/").map(Number);
78066 if (mapArgs.length < 3 || mapArgs.some(isNaN)) {
78067 updateHashIfNeeded();
78069 if (_cachedHash === computedHash())
78071 var mode = context.mode();
78072 context.map().centerZoom([mapArgs[2], Math.min(_latitudeLimit, Math.max(-_latitudeLimit, mapArgs[1]))], mapArgs[0]);
78073 if (q.id && mode) {
78074 var ids = q.id.split(",").filter(function(id2) {
78075 return context.hasEntity(id2);
78077 if (ids.length && (mode.id === "browse" || mode.id === "select" && !utilArrayIdentical(mode.selectedIDs(), ids))) {
78078 context.enter(modeSelect(context, ids));
78082 var center = context.map().center();
78083 var dist = geoSphericalDistance(center, [mapArgs[2], mapArgs[1]]);
78085 if (mode && mode.id.match(/^draw/) !== null && dist > maxdist) {
78086 context.enter(modeBrowse(context));
78091 function behavior() {
78092 context.map().on("move.behaviorHash", _throttledUpdate);
78093 context.history().on("change.behaviorHash", _throttledUpdateTitle);
78094 context.on("enter.behaviorHash", _throttledUpdate);
78095 select_default2(window).on("hashchange.behaviorHash", hashchange);
78096 var q = utilStringQs(window.location.hash);
78098 context.zoomToEntity(q.id.split(",")[0], !q.map);
78100 if (q.walkthrough === "true") {
78101 behavior.startWalkthrough = true;
78104 behavior.hadLocation = true;
78105 } else if (!q.id && corePreferences("map-location")) {
78106 const mapArgs = corePreferences("map-location").split("/").map(Number);
78107 context.map().centerZoom([mapArgs[2], Math.min(_latitudeLimit, Math.max(-_latitudeLimit, mapArgs[1]))], mapArgs[0]);
78108 updateHashIfNeeded();
78109 behavior.hadLocation = true;
78112 updateTitle(false);
78114 behavior.off = function() {
78115 _throttledUpdate.cancel();
78116 _throttledUpdateTitle.cancel();
78117 context.map().on("move.behaviorHash", null);
78118 context.on("enter.behaviorHash", null);
78119 select_default2(window).on("hashchange.behaviorHash", null);
78120 window.location.hash = "";
78125 // node_modules/d3-brush/src/brush.js
78126 var { abs: abs2, max: max2, min: min2 } = Math;
78127 function number1(e) {
78128 return [+e[0], +e[1]];
78130 function number22(e) {
78131 return [number1(e[0]), number1(e[1])];
78135 handles: ["w", "e"].map(type),
78136 input: function(x, e) {
78137 return x == null ? null : [[+x[0], e[0][1]], [+x[1], e[1][1]]];
78139 output: function(xy) {
78140 return xy && [xy[0][0], xy[1][0]];
78145 handles: ["n", "s"].map(type),
78146 input: function(y, e) {
78147 return y == null ? null : [[e[0][0], +y[0]], [e[1][0], +y[1]]];
78149 output: function(xy) {
78150 return xy && [xy[0][1], xy[1][1]];
78155 handles: ["n", "w", "e", "s", "nw", "ne", "sw", "se"].map(type),
78156 input: function(xy) {
78157 return xy == null ? null : number22(xy);
78159 output: function(xy) {
78164 return { type: t };
78167 // modules/index.js
78170 dispatch: dispatch_default,
78171 geoMercator: mercator_default,
78172 geoProjection: projection,
78173 polygonArea: area_default3,
78174 polygonCentroid: centroid_default2,
78175 select: select_default2,
78176 selectAll: selectAll_default2,
78181 window.requestIdleCallback = window.requestIdleCallback || function(cb) {
78182 var start2 = Date.now();
78183 return window.requestAnimationFrame(function() {
78186 timeRemaining: function() {
78187 return Math.max(0, 50 - (Date.now() - start2));
78192 window.cancelIdleCallback = window.cancelIdleCallback || function(id2) {
78193 window.cancelAnimationFrame(id2);
78195 window.iD = modules_exports;
78197 //# sourceMappingURL=iD.js.map