@wemap/geo 11.0.0-alpha.25 → 11.0.0-alpha.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +414 -1400
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +414 -1400
- package/dist/index.mjs.map +1 -1
- package/index.ts +19 -9
- package/package.json +5 -6
- package/src/Utils.ts +4 -4
- package/src/coordinates/Coordinates.ts +7 -16
- package/src/coordinates/Level.spec.ts +1 -6
- package/src/coordinates/Level.ts +6 -15
- package/src/graph/GraphEdge.spec.ts +74 -0
- package/src/graph/GraphEdge.ts +134 -0
- package/src/graph/GraphNode.spec.ts +202 -0
- package/src/graph/GraphNode.ts +174 -0
- package/src/graph/GraphProjection.ts +23 -0
- package/src/graph/GraphUtils.ts +21 -0
- package/src/graph/{GeoGraphProjectionHandler.spec.ts → MapMatching.spec.ts} +73 -74
- package/src/graph/{GeoGraphProjectionHandler.ts → MapMatching.ts} +44 -39
- package/src/graph/Network.spec.ts +148 -0
- package/src/graph/Network.ts +177 -0
- package/src/router/GraphItinerary.spec.ts +14 -0
- package/src/router/GraphItinerary.ts +80 -0
- package/src/router/GraphRouter.spec.ts +298 -0
- package/src/router/GraphRouter.ts +283 -0
- package/src/router/GraphRouterOptions.ts +14 -0
- package/src/{graph → router}/NoRouteFoundError.ts +14 -9
- package/src/types.ts +3 -3
- package/tests/CommonTest.ts +75 -69
- package/src/graph/GeoGraph.spec.ts +0 -278
- package/src/graph/GeoGraph.ts +0 -170
- package/src/graph/GeoGraphEdge.spec.ts +0 -51
- package/src/graph/GeoGraphEdge.ts +0 -98
- package/src/graph/GeoGraphItinerary.spec.ts +0 -14
- package/src/graph/GeoGraphItinerary.ts +0 -61
- package/src/graph/GeoGraphProjection.ts +0 -24
- package/src/graph/GeoGraphRouter.spec.ts +0 -297
- package/src/graph/GeoGraphRouter.ts +0 -267
- package/src/graph/GeoGraphVertex.spec.ts +0 -54
- package/src/graph/GeoGraphVertex.ts +0 -139
package/dist/index.js
CHANGED
|
@@ -80,27 +80,18 @@ const _Level = class {
|
|
|
80
80
|
if (str === null) {
|
|
81
81
|
return null;
|
|
82
82
|
}
|
|
83
|
-
if (typeof str !== "string"
|
|
84
|
-
throw Error(`argument must be a
|
|
83
|
+
if (typeof str !== "string") {
|
|
84
|
+
throw Error(`argument must be a string, got ${typeof str}`);
|
|
85
85
|
}
|
|
86
86
|
if (!isNaN(Number(str))) {
|
|
87
87
|
return parseFloat(str);
|
|
88
88
|
}
|
|
89
89
|
const splited = str.split(";");
|
|
90
|
-
if (splited.length
|
|
91
|
-
const
|
|
92
|
-
const
|
|
93
|
-
const up = Math.max(...levels);
|
|
90
|
+
if (splited.length === 2) {
|
|
91
|
+
const low = Number(splited[0]);
|
|
92
|
+
const up = Number(splited[1]);
|
|
94
93
|
this.checkType([low, up]);
|
|
95
|
-
return [
|
|
96
|
-
} else {
|
|
97
|
-
const rangeSeparator = str.substring(1).indexOf("-") + 1;
|
|
98
|
-
if (rangeSeparator > 0) {
|
|
99
|
-
const low = Number(str.substring(0, rangeSeparator));
|
|
100
|
-
const up = Number(str.substring(rangeSeparator + 1));
|
|
101
|
-
this.checkType([low, up]);
|
|
102
|
-
return [low, up];
|
|
103
|
-
}
|
|
94
|
+
return [parseFloat(splited[0]), parseFloat(splited[1])];
|
|
104
95
|
}
|
|
105
96
|
throw Error(`Cannot parse following level: ${str}`);
|
|
106
97
|
}
|
|
@@ -492,9 +483,9 @@ class Coordinates {
|
|
|
492
483
|
}
|
|
493
484
|
toJson() {
|
|
494
485
|
return {
|
|
495
|
-
lat:
|
|
496
|
-
lng:
|
|
497
|
-
...this.alt !== null && { alt:
|
|
486
|
+
lat: this.lat,
|
|
487
|
+
lng: this.lng,
|
|
488
|
+
...this.alt !== null && { alt: this.alt },
|
|
498
489
|
...this.level !== null && { level: this.level }
|
|
499
490
|
};
|
|
500
491
|
}
|
|
@@ -503,21 +494,12 @@ class Coordinates {
|
|
|
503
494
|
}
|
|
504
495
|
toCompressedJson() {
|
|
505
496
|
if (this.level !== null) {
|
|
506
|
-
return [
|
|
507
|
-
Number(this.lat.toFixed(8)),
|
|
508
|
-
Number(this.lng.toFixed(8)),
|
|
509
|
-
this.alt === null ? null : Number(this.alt.toFixed(3)),
|
|
510
|
-
this.level
|
|
511
|
-
];
|
|
497
|
+
return [this.lat, this.lng, this.alt, this.level];
|
|
512
498
|
}
|
|
513
499
|
if (this.alt !== null) {
|
|
514
|
-
return [
|
|
515
|
-
Number(this.lat.toFixed(8)),
|
|
516
|
-
Number(this.lng.toFixed(8)),
|
|
517
|
-
Number(this.alt.toFixed(3))
|
|
518
|
-
];
|
|
500
|
+
return [this.lat, this.lng, this.alt];
|
|
519
501
|
}
|
|
520
|
-
return [
|
|
502
|
+
return [this.lat, this.lng];
|
|
521
503
|
}
|
|
522
504
|
static fromCompressedJson(json) {
|
|
523
505
|
const coords = new Coordinates(json[0], json[1]);
|
|
@@ -1113,1118 +1095,158 @@ class AbsoluteHeading {
|
|
|
1113
1095
|
return new AbsoluteHeading(this.heading, this.time, this.accuracy);
|
|
1114
1096
|
}
|
|
1115
1097
|
}
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
(
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1098
|
+
class GraphNode {
|
|
1099
|
+
constructor(coords, builtFrom = null) {
|
|
1100
|
+
__publicField(this, "coords");
|
|
1101
|
+
__publicField(this, "edges", []);
|
|
1102
|
+
__publicField(this, "builtFrom");
|
|
1103
|
+
__publicField(this, "io", false);
|
|
1104
|
+
this.coords = coords;
|
|
1105
|
+
this.builtFrom = builtFrom;
|
|
1106
|
+
}
|
|
1107
|
+
distanceTo(other) {
|
|
1108
|
+
return this.coords.distanceTo(other.coords);
|
|
1109
|
+
}
|
|
1110
|
+
bearingTo(other) {
|
|
1111
|
+
return this.coords.bearingTo(other.coords);
|
|
1112
|
+
}
|
|
1113
|
+
equals(other) {
|
|
1114
|
+
return this.coords.equals(other.coords) && this.builtFrom === other.builtFrom;
|
|
1115
|
+
}
|
|
1116
|
+
clone() {
|
|
1117
|
+
const node = new GraphNode(this.coords, this.builtFrom);
|
|
1118
|
+
node.edges = this.edges.slice(0);
|
|
1119
|
+
node.io = this.io;
|
|
1120
|
+
return node;
|
|
1121
|
+
}
|
|
1122
|
+
toJson() {
|
|
1123
|
+
return this.coords.toCompressedJson();
|
|
1124
|
+
}
|
|
1125
|
+
static fromJson(json, builtFrom = null) {
|
|
1126
|
+
return new GraphNode(Coordinates.fromCompressedJson(json), builtFrom);
|
|
1127
|
+
}
|
|
1128
|
+
_generateLevelFromEdges() {
|
|
1129
|
+
let tmpLevel = null;
|
|
1130
|
+
for (let i = 0; i < this.edges.length; i++) {
|
|
1131
|
+
const edge = this.edges[i];
|
|
1132
|
+
if (edge.level !== null) {
|
|
1133
|
+
if (tmpLevel === null) {
|
|
1134
|
+
tmpLevel = Level.clone(edge.level);
|
|
1127
1135
|
} else {
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
return mergedRegexes;
|
|
1132
|
-
}, enumerize = function(arr) {
|
|
1133
|
-
var enums = {};
|
|
1134
|
-
for (var i = 0; i < arr.length; i++) {
|
|
1135
|
-
enums[arr[i].toUpperCase()] = arr[i];
|
|
1136
|
-
}
|
|
1137
|
-
return enums;
|
|
1138
|
-
}, has = function(str1, str2) {
|
|
1139
|
-
return typeof str1 === STR_TYPE ? lowerize(str2).indexOf(lowerize(str1)) !== -1 : false;
|
|
1140
|
-
}, lowerize = function(str) {
|
|
1141
|
-
return str.toLowerCase();
|
|
1142
|
-
}, majorize = function(version) {
|
|
1143
|
-
return typeof version === STR_TYPE ? version.replace(/[^\d\.]/g, EMPTY).split(".")[0] : undefined$1;
|
|
1144
|
-
}, trim = function(str, len) {
|
|
1145
|
-
if (typeof str === STR_TYPE) {
|
|
1146
|
-
str = str.replace(/^\s\s*/, EMPTY);
|
|
1147
|
-
return typeof len === UNDEF_TYPE ? str : str.substring(0, UA_MAX_LENGTH);
|
|
1148
|
-
}
|
|
1149
|
-
};
|
|
1150
|
-
var rgxMapper = function(ua, arrays) {
|
|
1151
|
-
var i = 0, j, k, p, q, matches, match;
|
|
1152
|
-
while (i < arrays.length && !matches) {
|
|
1153
|
-
var regex = arrays[i], props = arrays[i + 1];
|
|
1154
|
-
j = k = 0;
|
|
1155
|
-
while (j < regex.length && !matches) {
|
|
1156
|
-
matches = regex[j++].exec(ua);
|
|
1157
|
-
if (!!matches) {
|
|
1158
|
-
for (p = 0; p < props.length; p++) {
|
|
1159
|
-
match = matches[++k];
|
|
1160
|
-
q = props[p];
|
|
1161
|
-
if (typeof q === OBJ_TYPE && q.length > 0) {
|
|
1162
|
-
if (q.length === 2) {
|
|
1163
|
-
if (typeof q[1] == FUNC_TYPE) {
|
|
1164
|
-
this[q[0]] = q[1].call(this, match);
|
|
1165
|
-
} else {
|
|
1166
|
-
this[q[0]] = q[1];
|
|
1167
|
-
}
|
|
1168
|
-
} else if (q.length === 3) {
|
|
1169
|
-
if (typeof q[1] === FUNC_TYPE && !(q[1].exec && q[1].test)) {
|
|
1170
|
-
this[q[0]] = match ? q[1].call(this, match, q[2]) : undefined$1;
|
|
1171
|
-
} else {
|
|
1172
|
-
this[q[0]] = match ? match.replace(q[1], q[2]) : undefined$1;
|
|
1173
|
-
}
|
|
1174
|
-
} else if (q.length === 4) {
|
|
1175
|
-
this[q[0]] = match ? q[3].call(this, match.replace(q[1], q[2])) : undefined$1;
|
|
1176
|
-
}
|
|
1177
|
-
} else {
|
|
1178
|
-
this[q] = match ? match : undefined$1;
|
|
1179
|
-
}
|
|
1180
|
-
}
|
|
1181
|
-
}
|
|
1182
|
-
}
|
|
1183
|
-
i += 2;
|
|
1184
|
-
}
|
|
1185
|
-
}, strMapper = function(str, map) {
|
|
1186
|
-
for (var i in map) {
|
|
1187
|
-
if (typeof map[i] === OBJ_TYPE && map[i].length > 0) {
|
|
1188
|
-
for (var j = 0; j < map[i].length; j++) {
|
|
1189
|
-
if (has(map[i][j], str)) {
|
|
1190
|
-
return i === UNKNOWN ? undefined$1 : i;
|
|
1191
|
-
}
|
|
1136
|
+
tmpLevel = Level.intersection(tmpLevel, edge.level);
|
|
1137
|
+
if (tmpLevel === null) {
|
|
1138
|
+
throw Error("Something bad happend during parsing: We cannot retrieve node level from adjacent ways: " + this.coords);
|
|
1192
1139
|
}
|
|
1193
|
-
} else if (has(map[i], str)) {
|
|
1194
|
-
return i === UNKNOWN ? undefined$1 : i;
|
|
1195
1140
|
}
|
|
1196
1141
|
}
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
"2000": "NT 5.0",
|
|
1213
|
-
"XP": ["NT 5.1", "NT 5.2"],
|
|
1214
|
-
"Vista": "NT 6.0",
|
|
1215
|
-
"7": "NT 6.1",
|
|
1216
|
-
"8": "NT 6.2",
|
|
1217
|
-
"8.1": "NT 6.3",
|
|
1218
|
-
"10": ["NT 6.4", "NT 10.0"],
|
|
1219
|
-
"RT": "ARM"
|
|
1220
|
-
};
|
|
1221
|
-
var regexes = {
|
|
1222
|
-
browser: [
|
|
1223
|
-
[
|
|
1224
|
-
/\b(?:crmo|crios)\/([\w\.]+)/i
|
|
1225
|
-
],
|
|
1226
|
-
[VERSION, [NAME, "Chrome"]],
|
|
1227
|
-
[
|
|
1228
|
-
/edg(?:e|ios|a)?\/([\w\.]+)/i
|
|
1229
|
-
],
|
|
1230
|
-
[VERSION, [NAME, "Edge"]],
|
|
1231
|
-
[
|
|
1232
|
-
/(opera mini)\/([-\w\.]+)/i,
|
|
1233
|
-
/(opera [mobiletab]{3,6})\b.+version\/([-\w\.]+)/i,
|
|
1234
|
-
/(opera)(?:.+version\/|[\/ ]+)([\w\.]+)/i
|
|
1235
|
-
],
|
|
1236
|
-
[NAME, VERSION],
|
|
1237
|
-
[
|
|
1238
|
-
/opios[\/ ]+([\w\.]+)/i
|
|
1239
|
-
],
|
|
1240
|
-
[VERSION, [NAME, OPERA + " Mini"]],
|
|
1241
|
-
[
|
|
1242
|
-
/\bopr\/([\w\.]+)/i
|
|
1243
|
-
],
|
|
1244
|
-
[VERSION, [NAME, OPERA]],
|
|
1245
|
-
[
|
|
1246
|
-
/(kindle)\/([\w\.]+)/i,
|
|
1247
|
-
/(lunascape|maxthon|netfront|jasmine|blazer)[\/ ]?([\w\.]*)/i,
|
|
1248
|
-
/(avant |iemobile|slim)(?:browser)?[\/ ]?([\w\.]*)/i,
|
|
1249
|
-
/(ba?idubrowser)[\/ ]?([\w\.]+)/i,
|
|
1250
|
-
/(?:ms|\()(ie) ([\w\.]+)/i,
|
|
1251
|
-
/(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|quark|qupzilla|falkon|rekonq|puffin|brave|whale|qqbrowserlite|qq|duckduckgo)\/([-\w\.]+)/i,
|
|
1252
|
-
/(weibo)__([\d\.]+)/i
|
|
1253
|
-
],
|
|
1254
|
-
[NAME, VERSION],
|
|
1255
|
-
[
|
|
1256
|
-
/(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i
|
|
1257
|
-
],
|
|
1258
|
-
[VERSION, [NAME, "UC" + BROWSER]],
|
|
1259
|
-
[
|
|
1260
|
-
/microm.+\bqbcore\/([\w\.]+)/i,
|
|
1261
|
-
/\bqbcore\/([\w\.]+).+microm/i
|
|
1262
|
-
],
|
|
1263
|
-
[VERSION, [NAME, "WeChat(Win) Desktop"]],
|
|
1264
|
-
[
|
|
1265
|
-
/micromessenger\/([\w\.]+)/i
|
|
1266
|
-
],
|
|
1267
|
-
[VERSION, [NAME, "WeChat"]],
|
|
1268
|
-
[
|
|
1269
|
-
/konqueror\/([\w\.]+)/i
|
|
1270
|
-
],
|
|
1271
|
-
[VERSION, [NAME, "Konqueror"]],
|
|
1272
|
-
[
|
|
1273
|
-
/trident.+rv[: ]([\w\.]{1,9})\b.+like gecko/i
|
|
1274
|
-
],
|
|
1275
|
-
[VERSION, [NAME, "IE"]],
|
|
1276
|
-
[
|
|
1277
|
-
/yabrowser\/([\w\.]+)/i
|
|
1278
|
-
],
|
|
1279
|
-
[VERSION, [NAME, "Yandex"]],
|
|
1280
|
-
[
|
|
1281
|
-
/(avast|avg)\/([\w\.]+)/i
|
|
1282
|
-
],
|
|
1283
|
-
[[NAME, /(.+)/, "$1 Secure " + BROWSER], VERSION],
|
|
1284
|
-
[
|
|
1285
|
-
/\bfocus\/([\w\.]+)/i
|
|
1286
|
-
],
|
|
1287
|
-
[VERSION, [NAME, FIREFOX + " Focus"]],
|
|
1288
|
-
[
|
|
1289
|
-
/\bopt\/([\w\.]+)/i
|
|
1290
|
-
],
|
|
1291
|
-
[VERSION, [NAME, OPERA + " Touch"]],
|
|
1292
|
-
[
|
|
1293
|
-
/coc_coc\w+\/([\w\.]+)/i
|
|
1294
|
-
],
|
|
1295
|
-
[VERSION, [NAME, "Coc Coc"]],
|
|
1296
|
-
[
|
|
1297
|
-
/dolfin\/([\w\.]+)/i
|
|
1298
|
-
],
|
|
1299
|
-
[VERSION, [NAME, "Dolphin"]],
|
|
1300
|
-
[
|
|
1301
|
-
/coast\/([\w\.]+)/i
|
|
1302
|
-
],
|
|
1303
|
-
[VERSION, [NAME, OPERA + " Coast"]],
|
|
1304
|
-
[
|
|
1305
|
-
/miuibrowser\/([\w\.]+)/i
|
|
1306
|
-
],
|
|
1307
|
-
[VERSION, [NAME, "MIUI " + BROWSER]],
|
|
1308
|
-
[
|
|
1309
|
-
/fxios\/([-\w\.]+)/i
|
|
1310
|
-
],
|
|
1311
|
-
[VERSION, [NAME, FIREFOX]],
|
|
1312
|
-
[
|
|
1313
|
-
/\bqihu|(qi?ho?o?|360)browser/i
|
|
1314
|
-
],
|
|
1315
|
-
[[NAME, "360 " + BROWSER]],
|
|
1316
|
-
[
|
|
1317
|
-
/(oculus|samsung|sailfish|huawei)browser\/([\w\.]+)/i
|
|
1318
|
-
],
|
|
1319
|
-
[[NAME, /(.+)/, "$1 " + BROWSER], VERSION],
|
|
1320
|
-
[
|
|
1321
|
-
/(comodo_dragon)\/([\w\.]+)/i
|
|
1322
|
-
],
|
|
1323
|
-
[[NAME, /_/g, " "], VERSION],
|
|
1324
|
-
[
|
|
1325
|
-
/(electron)\/([\w\.]+) safari/i,
|
|
1326
|
-
/(tesla)(?: qtcarbrowser|\/(20\d\d\.[-\w\.]+))/i,
|
|
1327
|
-
/m?(qqbrowser|baiduboxapp|2345Explorer)[\/ ]?([\w\.]+)/i
|
|
1328
|
-
],
|
|
1329
|
-
[NAME, VERSION],
|
|
1330
|
-
[
|
|
1331
|
-
/(metasr)[\/ ]?([\w\.]+)/i,
|
|
1332
|
-
/(lbbrowser)/i,
|
|
1333
|
-
/\[(linkedin)app\]/i
|
|
1334
|
-
],
|
|
1335
|
-
[NAME],
|
|
1336
|
-
[
|
|
1337
|
-
/((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i
|
|
1338
|
-
],
|
|
1339
|
-
[[NAME, FACEBOOK], VERSION],
|
|
1340
|
-
[
|
|
1341
|
-
/safari (line)\/([\w\.]+)/i,
|
|
1342
|
-
/\b(line)\/([\w\.]+)\/iab/i,
|
|
1343
|
-
/(chromium|instagram)[\/ ]([-\w\.]+)/i
|
|
1344
|
-
],
|
|
1345
|
-
[NAME, VERSION],
|
|
1346
|
-
[
|
|
1347
|
-
/\bgsa\/([\w\.]+) .*safari\//i
|
|
1348
|
-
],
|
|
1349
|
-
[VERSION, [NAME, "GSA"]],
|
|
1350
|
-
[
|
|
1351
|
-
/headlesschrome(?:\/([\w\.]+)| )/i
|
|
1352
|
-
],
|
|
1353
|
-
[VERSION, [NAME, CHROME + " Headless"]],
|
|
1354
|
-
[
|
|
1355
|
-
/ wv\).+(chrome)\/([\w\.]+)/i
|
|
1356
|
-
],
|
|
1357
|
-
[[NAME, CHROME + " WebView"], VERSION],
|
|
1358
|
-
[
|
|
1359
|
-
/droid.+ version\/([\w\.]+)\b.+(?:mobile safari|safari)/i
|
|
1360
|
-
],
|
|
1361
|
-
[VERSION, [NAME, "Android " + BROWSER]],
|
|
1362
|
-
[
|
|
1363
|
-
/(chrome|omniweb|arora|[tizenoka]{5} ?browser)\/v?([\w\.]+)/i
|
|
1364
|
-
],
|
|
1365
|
-
[NAME, VERSION],
|
|
1366
|
-
[
|
|
1367
|
-
/version\/([\w\.\,]+) .*mobile\/\w+ (safari)/i
|
|
1368
|
-
],
|
|
1369
|
-
[VERSION, [NAME, "Mobile Safari"]],
|
|
1370
|
-
[
|
|
1371
|
-
/version\/([\w(\.|\,)]+) .*(mobile ?safari|safari)/i
|
|
1372
|
-
],
|
|
1373
|
-
[VERSION, NAME],
|
|
1374
|
-
[
|
|
1375
|
-
/webkit.+?(mobile ?safari|safari)(\/[\w\.]+)/i
|
|
1376
|
-
],
|
|
1377
|
-
[NAME, [VERSION, strMapper, oldSafariMap]],
|
|
1378
|
-
[
|
|
1379
|
-
/(webkit|khtml)\/([\w\.]+)/i
|
|
1380
|
-
],
|
|
1381
|
-
[NAME, VERSION],
|
|
1382
|
-
[
|
|
1383
|
-
/(navigator|netscape\d?)\/([-\w\.]+)/i
|
|
1384
|
-
],
|
|
1385
|
-
[[NAME, "Netscape"], VERSION],
|
|
1386
|
-
[
|
|
1387
|
-
/mobile vr; rv:([\w\.]+)\).+firefox/i
|
|
1388
|
-
],
|
|
1389
|
-
[VERSION, [NAME, FIREFOX + " Reality"]],
|
|
1390
|
-
[
|
|
1391
|
-
/ekiohf.+(flow)\/([\w\.]+)/i,
|
|
1392
|
-
/(swiftfox)/i,
|
|
1393
|
-
/(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror|klar)[\/ ]?([\w\.\+]+)/i,
|
|
1394
|
-
/(seamonkey|k-meleon|icecat|iceape|firebird|phoenix|palemoon|basilisk|waterfox)\/([-\w\.]+)$/i,
|
|
1395
|
-
/(firefox)\/([\w\.]+)/i,
|
|
1396
|
-
/(mozilla)\/([\w\.]+) .+rv\:.+gecko\/\d+/i,
|
|
1397
|
-
/(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|sleipnir|obigo|mosaic|(?:go|ice|up)[\. ]?browser)[-\/ ]?v?([\w\.]+)/i,
|
|
1398
|
-
/(links) \(([\w\.]+)/i
|
|
1399
|
-
],
|
|
1400
|
-
[NAME, VERSION],
|
|
1401
|
-
[
|
|
1402
|
-
/(cobalt)\/([\w\.]+)/i
|
|
1403
|
-
],
|
|
1404
|
-
[NAME, [VERSION, /master.|lts./, ""]]
|
|
1405
|
-
],
|
|
1406
|
-
cpu: [
|
|
1407
|
-
[
|
|
1408
|
-
/(?:(amd|x(?:(?:86|64)[-_])?|wow|win)64)[;\)]/i
|
|
1409
|
-
],
|
|
1410
|
-
[[ARCHITECTURE, "amd64"]],
|
|
1411
|
-
[
|
|
1412
|
-
/(ia32(?=;))/i
|
|
1413
|
-
],
|
|
1414
|
-
[[ARCHITECTURE, lowerize]],
|
|
1415
|
-
[
|
|
1416
|
-
/((?:i[346]|x)86)[;\)]/i
|
|
1417
|
-
],
|
|
1418
|
-
[[ARCHITECTURE, "ia32"]],
|
|
1419
|
-
[
|
|
1420
|
-
/\b(aarch64|arm(v?8e?l?|_?64))\b/i
|
|
1421
|
-
],
|
|
1422
|
-
[[ARCHITECTURE, "arm64"]],
|
|
1423
|
-
[
|
|
1424
|
-
/\b(arm(?:v[67])?ht?n?[fl]p?)\b/i
|
|
1425
|
-
],
|
|
1426
|
-
[[ARCHITECTURE, "armhf"]],
|
|
1427
|
-
[
|
|
1428
|
-
/windows (ce|mobile); ppc;/i
|
|
1429
|
-
],
|
|
1430
|
-
[[ARCHITECTURE, "arm"]],
|
|
1431
|
-
[
|
|
1432
|
-
/((?:ppc|powerpc)(?:64)?)(?: mac|;|\))/i
|
|
1433
|
-
],
|
|
1434
|
-
[[ARCHITECTURE, /ower/, EMPTY, lowerize]],
|
|
1435
|
-
[
|
|
1436
|
-
/(sun4\w)[;\)]/i
|
|
1437
|
-
],
|
|
1438
|
-
[[ARCHITECTURE, "sparc"]],
|
|
1439
|
-
[
|
|
1440
|
-
/((?:avr32|ia64(?=;))|68k(?=\))|\barm(?=v(?:[1-7]|[5-7]1)l?|;|eabi)|(?=atmel )avr|(?:irix|mips|sparc)(?:64)?\b|pa-risc)/i
|
|
1441
|
-
],
|
|
1442
|
-
[[ARCHITECTURE, lowerize]]
|
|
1443
|
-
],
|
|
1444
|
-
device: [
|
|
1445
|
-
[
|
|
1446
|
-
/\b(sch-i[89]0\d|shw-m380s|sm-[ptx]\w{2,4}|gt-[pn]\d{2,4}|sgh-t8[56]9|nexus 10)/i
|
|
1447
|
-
],
|
|
1448
|
-
[MODEL, [VENDOR, SAMSUNG], [TYPE, TABLET]],
|
|
1449
|
-
[
|
|
1450
|
-
/\b((?:s[cgp]h|gt|sm)-\w+|galaxy nexus)/i,
|
|
1451
|
-
/samsung[- ]([-\w]+)/i,
|
|
1452
|
-
/sec-(sgh\w+)/i
|
|
1453
|
-
],
|
|
1454
|
-
[MODEL, [VENDOR, SAMSUNG], [TYPE, MOBILE]],
|
|
1455
|
-
[
|
|
1456
|
-
/\((ip(?:hone|od)[\w ]*);/i
|
|
1457
|
-
],
|
|
1458
|
-
[MODEL, [VENDOR, APPLE], [TYPE, MOBILE]],
|
|
1459
|
-
[
|
|
1460
|
-
/\((ipad);[-\w\),; ]+apple/i,
|
|
1461
|
-
/applecoremedia\/[\w\.]+ \((ipad)/i,
|
|
1462
|
-
/\b(ipad)\d\d?,\d\d?[;\]].+ios/i
|
|
1463
|
-
],
|
|
1464
|
-
[MODEL, [VENDOR, APPLE], [TYPE, TABLET]],
|
|
1465
|
-
[
|
|
1466
|
-
/(macintosh);/i
|
|
1467
|
-
],
|
|
1468
|
-
[MODEL, [VENDOR, APPLE]],
|
|
1469
|
-
[
|
|
1470
|
-
/\b((?:ag[rs][23]?|bah2?|sht?|btv)-a?[lw]\d{2})\b(?!.+d\/s)/i
|
|
1471
|
-
],
|
|
1472
|
-
[MODEL, [VENDOR, HUAWEI], [TYPE, TABLET]],
|
|
1473
|
-
[
|
|
1474
|
-
/(?:huawei|honor)([-\w ]+)[;\)]/i,
|
|
1475
|
-
/\b(nexus 6p|\w{2,4}e?-[atu]?[ln][\dx][012359c][adn]?)\b(?!.+d\/s)/i
|
|
1476
|
-
],
|
|
1477
|
-
[MODEL, [VENDOR, HUAWEI], [TYPE, MOBILE]],
|
|
1478
|
-
[
|
|
1479
|
-
/\b(poco[\w ]+)(?: bui|\))/i,
|
|
1480
|
-
/\b; (\w+) build\/hm\1/i,
|
|
1481
|
-
/\b(hm[-_ ]?note?[_ ]?(?:\d\w)?) bui/i,
|
|
1482
|
-
/\b(redmi[\-_ ]?(?:note|k)?[\w_ ]+)(?: bui|\))/i,
|
|
1483
|
-
/\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max|cc)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite)?)(?: bui|\))/i
|
|
1484
|
-
],
|
|
1485
|
-
[[MODEL, /_/g, " "], [VENDOR, XIAOMI], [TYPE, MOBILE]],
|
|
1486
|
-
[
|
|
1487
|
-
/\b(mi[-_ ]?(?:pad)(?:[\w_ ]+))(?: bui|\))/i
|
|
1488
|
-
],
|
|
1489
|
-
[[MODEL, /_/g, " "], [VENDOR, XIAOMI], [TYPE, TABLET]],
|
|
1490
|
-
[
|
|
1491
|
-
/; (\w+) bui.+ oppo/i,
|
|
1492
|
-
/\b(cph[12]\d{3}|p(?:af|c[al]|d\w|e[ar])[mt]\d0|x9007|a101op)\b/i
|
|
1493
|
-
],
|
|
1494
|
-
[MODEL, [VENDOR, "OPPO"], [TYPE, MOBILE]],
|
|
1495
|
-
[
|
|
1496
|
-
/vivo (\w+)(?: bui|\))/i,
|
|
1497
|
-
/\b(v[12]\d{3}\w?[at])(?: bui|;)/i
|
|
1498
|
-
],
|
|
1499
|
-
[MODEL, [VENDOR, "Vivo"], [TYPE, MOBILE]],
|
|
1500
|
-
[
|
|
1501
|
-
/\b(rmx[12]\d{3})(?: bui|;|\))/i
|
|
1502
|
-
],
|
|
1503
|
-
[MODEL, [VENDOR, "Realme"], [TYPE, MOBILE]],
|
|
1504
|
-
[
|
|
1505
|
-
/\b(milestone|droid(?:[2-4x]| (?:bionic|x2|pro|razr))?:?( 4g)?)\b[\w ]+build\//i,
|
|
1506
|
-
/\bmot(?:orola)?[- ](\w*)/i,
|
|
1507
|
-
/((?:moto[\w\(\) ]+|xt\d{3,4}|nexus 6)(?= bui|\)))/i
|
|
1508
|
-
],
|
|
1509
|
-
[MODEL, [VENDOR, MOTOROLA], [TYPE, MOBILE]],
|
|
1510
|
-
[
|
|
1511
|
-
/\b(mz60\d|xoom[2 ]{0,2}) build\//i
|
|
1512
|
-
],
|
|
1513
|
-
[MODEL, [VENDOR, MOTOROLA], [TYPE, TABLET]],
|
|
1514
|
-
[
|
|
1515
|
-
/((?=lg)?[vl]k\-?\d{3}) bui| 3\.[-\w; ]{10}lg?-([06cv9]{3,4})/i
|
|
1516
|
-
],
|
|
1517
|
-
[MODEL, [VENDOR, LG], [TYPE, TABLET]],
|
|
1518
|
-
[
|
|
1519
|
-
/(lm(?:-?f100[nv]?|-[\w\.]+)(?= bui|\))|nexus [45])/i,
|
|
1520
|
-
/\blg[-e;\/ ]+((?!browser|netcast|android tv)\w+)/i,
|
|
1521
|
-
/\blg-?([\d\w]+) bui/i
|
|
1522
|
-
],
|
|
1523
|
-
[MODEL, [VENDOR, LG], [TYPE, MOBILE]],
|
|
1524
|
-
[
|
|
1525
|
-
/(ideatab[-\w ]+)/i,
|
|
1526
|
-
/lenovo ?(s[56]000[-\w]+|tab(?:[\w ]+)|yt[-\d\w]{6}|tb[-\d\w]{6})/i
|
|
1527
|
-
],
|
|
1528
|
-
[MODEL, [VENDOR, "Lenovo"], [TYPE, TABLET]],
|
|
1529
|
-
[
|
|
1530
|
-
/(?:maemo|nokia).*(n900|lumia \d+)/i,
|
|
1531
|
-
/nokia[-_ ]?([-\w\.]*)/i
|
|
1532
|
-
],
|
|
1533
|
-
[[MODEL, /_/g, " "], [VENDOR, "Nokia"], [TYPE, MOBILE]],
|
|
1534
|
-
[
|
|
1535
|
-
/(pixel c)\b/i
|
|
1536
|
-
],
|
|
1537
|
-
[MODEL, [VENDOR, GOOGLE], [TYPE, TABLET]],
|
|
1538
|
-
[
|
|
1539
|
-
/droid.+; (pixel[\daxl ]{0,6})(?: bui|\))/i
|
|
1540
|
-
],
|
|
1541
|
-
[MODEL, [VENDOR, GOOGLE], [TYPE, MOBILE]],
|
|
1542
|
-
[
|
|
1543
|
-
/droid.+ (a?\d[0-2]{2}so|[c-g]\d{4}|so[-gl]\w+|xq-a\w[4-7][12])(?= bui|\).+chrome\/(?![1-6]{0,1}\d\.))/i
|
|
1544
|
-
],
|
|
1545
|
-
[MODEL, [VENDOR, SONY], [TYPE, MOBILE]],
|
|
1546
|
-
[
|
|
1547
|
-
/sony tablet [ps]/i,
|
|
1548
|
-
/\b(?:sony)?sgp\w+(?: bui|\))/i
|
|
1549
|
-
],
|
|
1550
|
-
[[MODEL, "Xperia Tablet"], [VENDOR, SONY], [TYPE, TABLET]],
|
|
1551
|
-
[
|
|
1552
|
-
/ (kb2005|in20[12]5|be20[12][59])\b/i,
|
|
1553
|
-
/(?:one)?(?:plus)? (a\d0\d\d)(?: b|\))/i
|
|
1554
|
-
],
|
|
1555
|
-
[MODEL, [VENDOR, "OnePlus"], [TYPE, MOBILE]],
|
|
1556
|
-
[
|
|
1557
|
-
/(alexa)webm/i,
|
|
1558
|
-
/(kf[a-z]{2}wi)( bui|\))/i,
|
|
1559
|
-
/(kf[a-z]+)( bui|\)).+silk\//i
|
|
1560
|
-
],
|
|
1561
|
-
[MODEL, [VENDOR, AMAZON], [TYPE, TABLET]],
|
|
1562
|
-
[
|
|
1563
|
-
/((?:sd|kf)[0349hijorstuw]+)( bui|\)).+silk\//i
|
|
1564
|
-
],
|
|
1565
|
-
[[MODEL, /(.+)/g, "Fire Phone $1"], [VENDOR, AMAZON], [TYPE, MOBILE]],
|
|
1566
|
-
[
|
|
1567
|
-
/(playbook);[-\w\),; ]+(rim)/i
|
|
1568
|
-
],
|
|
1569
|
-
[MODEL, VENDOR, [TYPE, TABLET]],
|
|
1570
|
-
[
|
|
1571
|
-
/\b((?:bb[a-f]|st[hv])100-\d)/i,
|
|
1572
|
-
/\(bb10; (\w+)/i
|
|
1573
|
-
],
|
|
1574
|
-
[MODEL, [VENDOR, BLACKBERRY], [TYPE, MOBILE]],
|
|
1575
|
-
[
|
|
1576
|
-
/(?:\b|asus_)(transfo[prime ]{4,10} \w+|eeepc|slider \w+|nexus 7|padfone|p00[cj])/i
|
|
1577
|
-
],
|
|
1578
|
-
[MODEL, [VENDOR, ASUS], [TYPE, TABLET]],
|
|
1579
|
-
[
|
|
1580
|
-
/ (z[bes]6[027][012][km][ls]|zenfone \d\w?)\b/i
|
|
1581
|
-
],
|
|
1582
|
-
[MODEL, [VENDOR, ASUS], [TYPE, MOBILE]],
|
|
1583
|
-
[
|
|
1584
|
-
/(nexus 9)/i
|
|
1585
|
-
],
|
|
1586
|
-
[MODEL, [VENDOR, "HTC"], [TYPE, TABLET]],
|
|
1587
|
-
[
|
|
1588
|
-
/(htc)[-;_ ]{1,2}([\w ]+(?=\)| bui)|\w+)/i,
|
|
1589
|
-
/(zte)[- ]([\w ]+?)(?: bui|\/|\))/i,
|
|
1590
|
-
/(alcatel|geeksphone|nexian|panasonic|sony(?!-bra))[-_ ]?([-\w]*)/i
|
|
1591
|
-
],
|
|
1592
|
-
[VENDOR, [MODEL, /_/g, " "], [TYPE, MOBILE]],
|
|
1593
|
-
[
|
|
1594
|
-
/droid.+; ([ab][1-7]-?[0178a]\d\d?)/i
|
|
1595
|
-
],
|
|
1596
|
-
[MODEL, [VENDOR, "Acer"], [TYPE, TABLET]],
|
|
1597
|
-
[
|
|
1598
|
-
/droid.+; (m[1-5] note) bui/i,
|
|
1599
|
-
/\bmz-([-\w]{2,})/i
|
|
1600
|
-
],
|
|
1601
|
-
[MODEL, [VENDOR, "Meizu"], [TYPE, MOBILE]],
|
|
1602
|
-
[
|
|
1603
|
-
/\b(sh-?[altvz]?\d\d[a-ekm]?)/i
|
|
1604
|
-
],
|
|
1605
|
-
[MODEL, [VENDOR, SHARP], [TYPE, MOBILE]],
|
|
1606
|
-
[
|
|
1607
|
-
/(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron)[-_ ]?([-\w]*)/i,
|
|
1608
|
-
/(hp) ([\w ]+\w)/i,
|
|
1609
|
-
/(asus)-?(\w+)/i,
|
|
1610
|
-
/(microsoft); (lumia[\w ]+)/i,
|
|
1611
|
-
/(lenovo)[-_ ]?([-\w]+)/i,
|
|
1612
|
-
/(jolla)/i,
|
|
1613
|
-
/(oppo) ?([\w ]+) bui/i
|
|
1614
|
-
],
|
|
1615
|
-
[VENDOR, MODEL, [TYPE, MOBILE]],
|
|
1616
|
-
[
|
|
1617
|
-
/(archos) (gamepad2?)/i,
|
|
1618
|
-
/(hp).+(touchpad(?!.+tablet)|tablet)/i,
|
|
1619
|
-
/(kindle)\/([\w\.]+)/i,
|
|
1620
|
-
/(nook)[\w ]+build\/(\w+)/i,
|
|
1621
|
-
/(dell) (strea[kpr\d ]*[\dko])/i,
|
|
1622
|
-
/(le[- ]+pan)[- ]+(\w{1,9}) bui/i,
|
|
1623
|
-
/(trinity)[- ]*(t\d{3}) bui/i,
|
|
1624
|
-
/(gigaset)[- ]+(q\w{1,9}) bui/i,
|
|
1625
|
-
/(vodafone) ([\w ]+)(?:\)| bui)/i
|
|
1626
|
-
],
|
|
1627
|
-
[VENDOR, MODEL, [TYPE, TABLET]],
|
|
1628
|
-
[
|
|
1629
|
-
/(surface duo)/i
|
|
1630
|
-
],
|
|
1631
|
-
[MODEL, [VENDOR, MICROSOFT], [TYPE, TABLET]],
|
|
1632
|
-
[
|
|
1633
|
-
/droid [\d\.]+; (fp\du?)(?: b|\))/i
|
|
1634
|
-
],
|
|
1635
|
-
[MODEL, [VENDOR, "Fairphone"], [TYPE, MOBILE]],
|
|
1636
|
-
[
|
|
1637
|
-
/(u304aa)/i
|
|
1638
|
-
],
|
|
1639
|
-
[MODEL, [VENDOR, "AT&T"], [TYPE, MOBILE]],
|
|
1640
|
-
[
|
|
1641
|
-
/\bsie-(\w*)/i
|
|
1642
|
-
],
|
|
1643
|
-
[MODEL, [VENDOR, "Siemens"], [TYPE, MOBILE]],
|
|
1644
|
-
[
|
|
1645
|
-
/\b(rct\w+) b/i
|
|
1646
|
-
],
|
|
1647
|
-
[MODEL, [VENDOR, "RCA"], [TYPE, TABLET]],
|
|
1648
|
-
[
|
|
1649
|
-
/\b(venue[\d ]{2,7}) b/i
|
|
1650
|
-
],
|
|
1651
|
-
[MODEL, [VENDOR, "Dell"], [TYPE, TABLET]],
|
|
1652
|
-
[
|
|
1653
|
-
/\b(q(?:mv|ta)\w+) b/i
|
|
1654
|
-
],
|
|
1655
|
-
[MODEL, [VENDOR, "Verizon"], [TYPE, TABLET]],
|
|
1656
|
-
[
|
|
1657
|
-
/\b(?:barnes[& ]+noble |bn[rt])([\w\+ ]*) b/i
|
|
1658
|
-
],
|
|
1659
|
-
[MODEL, [VENDOR, "Barnes & Noble"], [TYPE, TABLET]],
|
|
1660
|
-
[
|
|
1661
|
-
/\b(tm\d{3}\w+) b/i
|
|
1662
|
-
],
|
|
1663
|
-
[MODEL, [VENDOR, "NuVision"], [TYPE, TABLET]],
|
|
1664
|
-
[
|
|
1665
|
-
/\b(k88) b/i
|
|
1666
|
-
],
|
|
1667
|
-
[MODEL, [VENDOR, "ZTE"], [TYPE, TABLET]],
|
|
1668
|
-
[
|
|
1669
|
-
/\b(nx\d{3}j) b/i
|
|
1670
|
-
],
|
|
1671
|
-
[MODEL, [VENDOR, "ZTE"], [TYPE, MOBILE]],
|
|
1672
|
-
[
|
|
1673
|
-
/\b(gen\d{3}) b.+49h/i
|
|
1674
|
-
],
|
|
1675
|
-
[MODEL, [VENDOR, "Swiss"], [TYPE, MOBILE]],
|
|
1676
|
-
[
|
|
1677
|
-
/\b(zur\d{3}) b/i
|
|
1678
|
-
],
|
|
1679
|
-
[MODEL, [VENDOR, "Swiss"], [TYPE, TABLET]],
|
|
1680
|
-
[
|
|
1681
|
-
/\b((zeki)?tb.*\b) b/i
|
|
1682
|
-
],
|
|
1683
|
-
[MODEL, [VENDOR, "Zeki"], [TYPE, TABLET]],
|
|
1684
|
-
[
|
|
1685
|
-
/\b([yr]\d{2}) b/i,
|
|
1686
|
-
/\b(dragon[- ]+touch |dt)(\w{5}) b/i
|
|
1687
|
-
],
|
|
1688
|
-
[[VENDOR, "Dragon Touch"], MODEL, [TYPE, TABLET]],
|
|
1689
|
-
[
|
|
1690
|
-
/\b(ns-?\w{0,9}) b/i
|
|
1691
|
-
],
|
|
1692
|
-
[MODEL, [VENDOR, "Insignia"], [TYPE, TABLET]],
|
|
1693
|
-
[
|
|
1694
|
-
/\b((nxa|next)-?\w{0,9}) b/i
|
|
1695
|
-
],
|
|
1696
|
-
[MODEL, [VENDOR, "NextBook"], [TYPE, TABLET]],
|
|
1697
|
-
[
|
|
1698
|
-
/\b(xtreme\_)?(v(1[045]|2[015]|[3469]0|7[05])) b/i
|
|
1699
|
-
],
|
|
1700
|
-
[[VENDOR, "Voice"], MODEL, [TYPE, MOBILE]],
|
|
1701
|
-
[
|
|
1702
|
-
/\b(lvtel\-)?(v1[12]) b/i
|
|
1703
|
-
],
|
|
1704
|
-
[[VENDOR, "LvTel"], MODEL, [TYPE, MOBILE]],
|
|
1705
|
-
[
|
|
1706
|
-
/\b(ph-1) /i
|
|
1707
|
-
],
|
|
1708
|
-
[MODEL, [VENDOR, "Essential"], [TYPE, MOBILE]],
|
|
1709
|
-
[
|
|
1710
|
-
/\b(v(100md|700na|7011|917g).*\b) b/i
|
|
1711
|
-
],
|
|
1712
|
-
[MODEL, [VENDOR, "Envizen"], [TYPE, TABLET]],
|
|
1713
|
-
[
|
|
1714
|
-
/\b(trio[-\w\. ]+) b/i
|
|
1715
|
-
],
|
|
1716
|
-
[MODEL, [VENDOR, "MachSpeed"], [TYPE, TABLET]],
|
|
1717
|
-
[
|
|
1718
|
-
/\btu_(1491) b/i
|
|
1719
|
-
],
|
|
1720
|
-
[MODEL, [VENDOR, "Rotor"], [TYPE, TABLET]],
|
|
1721
|
-
[
|
|
1722
|
-
/(shield[\w ]+) b/i
|
|
1723
|
-
],
|
|
1724
|
-
[MODEL, [VENDOR, "Nvidia"], [TYPE, TABLET]],
|
|
1725
|
-
[
|
|
1726
|
-
/(sprint) (\w+)/i
|
|
1727
|
-
],
|
|
1728
|
-
[VENDOR, MODEL, [TYPE, MOBILE]],
|
|
1729
|
-
[
|
|
1730
|
-
/(kin\.[onetw]{3})/i
|
|
1731
|
-
],
|
|
1732
|
-
[[MODEL, /\./g, " "], [VENDOR, MICROSOFT], [TYPE, MOBILE]],
|
|
1733
|
-
[
|
|
1734
|
-
/droid.+; (cc6666?|et5[16]|mc[239][23]x?|vc8[03]x?)\)/i
|
|
1735
|
-
],
|
|
1736
|
-
[MODEL, [VENDOR, ZEBRA], [TYPE, TABLET]],
|
|
1737
|
-
[
|
|
1738
|
-
/droid.+; (ec30|ps20|tc[2-8]\d[kx])\)/i
|
|
1739
|
-
],
|
|
1740
|
-
[MODEL, [VENDOR, ZEBRA], [TYPE, MOBILE]],
|
|
1741
|
-
[
|
|
1742
|
-
/(ouya)/i,
|
|
1743
|
-
/(nintendo) ([wids3utch]+)/i
|
|
1744
|
-
],
|
|
1745
|
-
[VENDOR, MODEL, [TYPE, CONSOLE]],
|
|
1746
|
-
[
|
|
1747
|
-
/droid.+; (shield) bui/i
|
|
1748
|
-
],
|
|
1749
|
-
[MODEL, [VENDOR, "Nvidia"], [TYPE, CONSOLE]],
|
|
1750
|
-
[
|
|
1751
|
-
/(playstation [345portablevi]+)/i
|
|
1752
|
-
],
|
|
1753
|
-
[MODEL, [VENDOR, SONY], [TYPE, CONSOLE]],
|
|
1754
|
-
[
|
|
1755
|
-
/\b(xbox(?: one)?(?!; xbox))[\); ]/i
|
|
1756
|
-
],
|
|
1757
|
-
[MODEL, [VENDOR, MICROSOFT], [TYPE, CONSOLE]],
|
|
1758
|
-
[
|
|
1759
|
-
/smart-tv.+(samsung)/i
|
|
1760
|
-
],
|
|
1761
|
-
[VENDOR, [TYPE, SMARTTV]],
|
|
1762
|
-
[
|
|
1763
|
-
/hbbtv.+maple;(\d+)/i
|
|
1764
|
-
],
|
|
1765
|
-
[[MODEL, /^/, "SmartTV"], [VENDOR, SAMSUNG], [TYPE, SMARTTV]],
|
|
1766
|
-
[
|
|
1767
|
-
/(nux; netcast.+smarttv|lg (netcast\.tv-201\d|android tv))/i
|
|
1768
|
-
],
|
|
1769
|
-
[[VENDOR, LG], [TYPE, SMARTTV]],
|
|
1770
|
-
[
|
|
1771
|
-
/(apple) ?tv/i
|
|
1772
|
-
],
|
|
1773
|
-
[VENDOR, [MODEL, APPLE + " TV"], [TYPE, SMARTTV]],
|
|
1774
|
-
[
|
|
1775
|
-
/crkey/i
|
|
1776
|
-
],
|
|
1777
|
-
[[MODEL, CHROME + "cast"], [VENDOR, GOOGLE], [TYPE, SMARTTV]],
|
|
1778
|
-
[
|
|
1779
|
-
/droid.+aft(\w)( bui|\))/i
|
|
1780
|
-
],
|
|
1781
|
-
[MODEL, [VENDOR, AMAZON], [TYPE, SMARTTV]],
|
|
1782
|
-
[
|
|
1783
|
-
/\(dtv[\);].+(aquos)/i,
|
|
1784
|
-
/(aquos-tv[\w ]+)\)/i
|
|
1785
|
-
],
|
|
1786
|
-
[MODEL, [VENDOR, SHARP], [TYPE, SMARTTV]],
|
|
1787
|
-
[
|
|
1788
|
-
/(bravia[\w ]+)( bui|\))/i
|
|
1789
|
-
],
|
|
1790
|
-
[MODEL, [VENDOR, SONY], [TYPE, SMARTTV]],
|
|
1791
|
-
[
|
|
1792
|
-
/(mitv-\w{5}) bui/i
|
|
1793
|
-
],
|
|
1794
|
-
[MODEL, [VENDOR, XIAOMI], [TYPE, SMARTTV]],
|
|
1795
|
-
[
|
|
1796
|
-
/\b(roku)[\dx]*[\)\/]((?:dvp-)?[\d\.]*)/i,
|
|
1797
|
-
/hbbtv\/\d+\.\d+\.\d+ +\([\w ]*; *(\w[^;]*);([^;]*)/i
|
|
1798
|
-
],
|
|
1799
|
-
[[VENDOR, trim], [MODEL, trim], [TYPE, SMARTTV]],
|
|
1800
|
-
[
|
|
1801
|
-
/\b(android tv|smart[- ]?tv|opera tv|tv; rv:)\b/i
|
|
1802
|
-
],
|
|
1803
|
-
[[TYPE, SMARTTV]],
|
|
1804
|
-
[
|
|
1805
|
-
/((pebble))app/i
|
|
1806
|
-
],
|
|
1807
|
-
[VENDOR, MODEL, [TYPE, WEARABLE]],
|
|
1808
|
-
[
|
|
1809
|
-
/droid.+; (glass) \d/i
|
|
1810
|
-
],
|
|
1811
|
-
[MODEL, [VENDOR, GOOGLE], [TYPE, WEARABLE]],
|
|
1812
|
-
[
|
|
1813
|
-
/droid.+; (wt63?0{2,3})\)/i
|
|
1814
|
-
],
|
|
1815
|
-
[MODEL, [VENDOR, ZEBRA], [TYPE, WEARABLE]],
|
|
1816
|
-
[
|
|
1817
|
-
/(quest( 2)?)/i
|
|
1818
|
-
],
|
|
1819
|
-
[MODEL, [VENDOR, FACEBOOK], [TYPE, WEARABLE]],
|
|
1820
|
-
[
|
|
1821
|
-
/(tesla)(?: qtcarbrowser|\/[-\w\.]+)/i
|
|
1822
|
-
],
|
|
1823
|
-
[VENDOR, [TYPE, EMBEDDED]],
|
|
1824
|
-
[
|
|
1825
|
-
/droid .+?; ([^;]+?)(?: bui|\) applew).+? mobile safari/i
|
|
1826
|
-
],
|
|
1827
|
-
[MODEL, [TYPE, MOBILE]],
|
|
1828
|
-
[
|
|
1829
|
-
/droid .+?; ([^;]+?)(?: bui|\) applew).+?(?! mobile) safari/i
|
|
1830
|
-
],
|
|
1831
|
-
[MODEL, [TYPE, TABLET]],
|
|
1832
|
-
[
|
|
1833
|
-
/\b((tablet|tab)[;\/]|focus\/\d(?!.+mobile))/i
|
|
1834
|
-
],
|
|
1835
|
-
[[TYPE, TABLET]],
|
|
1836
|
-
[
|
|
1837
|
-
/(phone|mobile(?:[;\/]| [ \w\/\.]*safari)|pda(?=.+windows ce))/i
|
|
1838
|
-
],
|
|
1839
|
-
[[TYPE, MOBILE]],
|
|
1840
|
-
[
|
|
1841
|
-
/(android[-\w\. ]{0,9});.+buil/i
|
|
1842
|
-
],
|
|
1843
|
-
[MODEL, [VENDOR, "Generic"]]
|
|
1844
|
-
],
|
|
1845
|
-
engine: [
|
|
1846
|
-
[
|
|
1847
|
-
/windows.+ edge\/([\w\.]+)/i
|
|
1848
|
-
],
|
|
1849
|
-
[VERSION, [NAME, EDGE + "HTML"]],
|
|
1850
|
-
[
|
|
1851
|
-
/webkit\/537\.36.+chrome\/(?!27)([\w\.]+)/i
|
|
1852
|
-
],
|
|
1853
|
-
[VERSION, [NAME, "Blink"]],
|
|
1854
|
-
[
|
|
1855
|
-
/(presto)\/([\w\.]+)/i,
|
|
1856
|
-
/(webkit|trident|netfront|netsurf|amaya|lynx|w3m|goanna)\/([\w\.]+)/i,
|
|
1857
|
-
/ekioh(flow)\/([\w\.]+)/i,
|
|
1858
|
-
/(khtml|tasman|links)[\/ ]\(?([\w\.]+)/i,
|
|
1859
|
-
/(icab)[\/ ]([23]\.[\d\.]+)/i
|
|
1860
|
-
],
|
|
1861
|
-
[NAME, VERSION],
|
|
1862
|
-
[
|
|
1863
|
-
/rv\:([\w\.]{1,9})\b.+(gecko)/i
|
|
1864
|
-
],
|
|
1865
|
-
[VERSION, NAME]
|
|
1866
|
-
],
|
|
1867
|
-
os: [
|
|
1868
|
-
[
|
|
1869
|
-
/microsoft (windows) (vista|xp)/i
|
|
1870
|
-
],
|
|
1871
|
-
[NAME, VERSION],
|
|
1872
|
-
[
|
|
1873
|
-
/(windows) nt 6\.2; (arm)/i,
|
|
1874
|
-
/(windows (?:phone(?: os)?|mobile))[\/ ]?([\d\.\w ]*)/i,
|
|
1875
|
-
/(windows)[\/ ]?([ntce\d\. ]+\w)(?!.+xbox)/i
|
|
1876
|
-
],
|
|
1877
|
-
[NAME, [VERSION, strMapper, windowsVersionMap]],
|
|
1878
|
-
[
|
|
1879
|
-
/(win(?=3|9|n)|win 9x )([nt\d\.]+)/i
|
|
1880
|
-
],
|
|
1881
|
-
[[NAME, "Windows"], [VERSION, strMapper, windowsVersionMap]],
|
|
1882
|
-
[
|
|
1883
|
-
/ip[honead]{2,4}\b(?:.*os ([\w]+) like mac|; opera)/i,
|
|
1884
|
-
/cfnetwork\/.+darwin/i
|
|
1885
|
-
],
|
|
1886
|
-
[[VERSION, /_/g, "."], [NAME, "iOS"]],
|
|
1887
|
-
[
|
|
1888
|
-
/(mac os x) ?([\w\. ]*)/i,
|
|
1889
|
-
/(macintosh|mac_powerpc\b)(?!.+haiku)/i
|
|
1890
|
-
],
|
|
1891
|
-
[[NAME, "Mac OS"], [VERSION, /_/g, "."]],
|
|
1892
|
-
[
|
|
1893
|
-
/droid ([\w\.]+)\b.+(android[- ]x86|harmonyos)/i
|
|
1894
|
-
],
|
|
1895
|
-
[VERSION, NAME],
|
|
1896
|
-
[
|
|
1897
|
-
/(android|webos|qnx|bada|rim tablet os|maemo|meego|sailfish)[-\/ ]?([\w\.]*)/i,
|
|
1898
|
-
/(blackberry)\w*\/([\w\.]*)/i,
|
|
1899
|
-
/(tizen|kaios)[\/ ]([\w\.]+)/i,
|
|
1900
|
-
/\((series40);/i
|
|
1901
|
-
],
|
|
1902
|
-
[NAME, VERSION],
|
|
1903
|
-
[
|
|
1904
|
-
/\(bb(10);/i
|
|
1905
|
-
],
|
|
1906
|
-
[VERSION, [NAME, BLACKBERRY]],
|
|
1907
|
-
[
|
|
1908
|
-
/(?:symbian ?os|symbos|s60(?=;)|series60)[-\/ ]?([\w\.]*)/i
|
|
1909
|
-
],
|
|
1910
|
-
[VERSION, [NAME, "Symbian"]],
|
|
1911
|
-
[
|
|
1912
|
-
/mozilla\/[\d\.]+ \((?:mobile|tablet|tv|mobile; [\w ]+); rv:.+ gecko\/([\w\.]+)/i
|
|
1913
|
-
],
|
|
1914
|
-
[VERSION, [NAME, FIREFOX + " OS"]],
|
|
1915
|
-
[
|
|
1916
|
-
/web0s;.+rt(tv)/i,
|
|
1917
|
-
/\b(?:hp)?wos(?:browser)?\/([\w\.]+)/i
|
|
1918
|
-
],
|
|
1919
|
-
[VERSION, [NAME, "webOS"]],
|
|
1920
|
-
[
|
|
1921
|
-
/crkey\/([\d\.]+)/i
|
|
1922
|
-
],
|
|
1923
|
-
[VERSION, [NAME, CHROME + "cast"]],
|
|
1924
|
-
[
|
|
1925
|
-
/(cros) [\w]+ ([\w\.]+\w)/i
|
|
1926
|
-
],
|
|
1927
|
-
[[NAME, "Chromium OS"], VERSION],
|
|
1928
|
-
[
|
|
1929
|
-
/(nintendo|playstation) ([wids345portablevuch]+)/i,
|
|
1930
|
-
/(xbox); +xbox ([^\);]+)/i,
|
|
1931
|
-
/\b(joli|palm)\b ?(?:os)?\/?([\w\.]*)/i,
|
|
1932
|
-
/(mint)[\/\(\) ]?(\w*)/i,
|
|
1933
|
-
/(mageia|vectorlinux)[; ]/i,
|
|
1934
|
-
/([kxln]?ubuntu|debian|suse|opensuse|gentoo|arch(?= linux)|slackware|fedora|mandriva|centos|pclinuxos|red ?hat|zenwalk|linpus|raspbian|plan 9|minix|risc os|contiki|deepin|manjaro|elementary os|sabayon|linspire)(?: gnu\/linux)?(?: enterprise)?(?:[- ]linux)?(?:-gnu)?[-\/ ]?(?!chrom|package)([-\w\.]*)/i,
|
|
1935
|
-
/(hurd|linux) ?([\w\.]*)/i,
|
|
1936
|
-
/(gnu) ?([\w\.]*)/i,
|
|
1937
|
-
/\b([-frentopcghs]{0,5}bsd|dragonfly)[\/ ]?(?!amd|[ix346]{1,2}86)([\w\.]*)/i,
|
|
1938
|
-
/(haiku) (\w+)/i
|
|
1939
|
-
],
|
|
1940
|
-
[NAME, VERSION],
|
|
1941
|
-
[
|
|
1942
|
-
/(sunos) ?([\w\.\d]*)/i
|
|
1943
|
-
],
|
|
1944
|
-
[[NAME, "Solaris"], VERSION],
|
|
1945
|
-
[
|
|
1946
|
-
/((?:open)?solaris)[-\/ ]?([\w\.]*)/i,
|
|
1947
|
-
/(aix) ((\d)(?=\.|\)| )[\w\.])*/i,
|
|
1948
|
-
/\b(beos|os\/2|amigaos|morphos|openvms|fuchsia|hp-ux)/i,
|
|
1949
|
-
/(unix) ?([\w\.]*)/i
|
|
1950
|
-
],
|
|
1951
|
-
[NAME, VERSION]
|
|
1952
|
-
]
|
|
1953
|
-
};
|
|
1954
|
-
var UAParser = function(ua, extensions) {
|
|
1955
|
-
if (typeof ua === OBJ_TYPE) {
|
|
1956
|
-
extensions = ua;
|
|
1957
|
-
ua = undefined$1;
|
|
1958
|
-
}
|
|
1959
|
-
if (!(this instanceof UAParser)) {
|
|
1960
|
-
return new UAParser(ua, extensions).getResult();
|
|
1142
|
+
}
|
|
1143
|
+
this.coords.level = tmpLevel;
|
|
1144
|
+
}
|
|
1145
|
+
_inferNodeLevelByRecursion() {
|
|
1146
|
+
const { level } = this.coords;
|
|
1147
|
+
if (level === null || !Level.isRange(level)) {
|
|
1148
|
+
return;
|
|
1149
|
+
}
|
|
1150
|
+
if (this.edges.length > 1) {
|
|
1151
|
+
return;
|
|
1152
|
+
}
|
|
1153
|
+
const lookForLevel = (node, visitedNodes) => {
|
|
1154
|
+
visitedNodes.push(node);
|
|
1155
|
+
if (node.coords.level === null) {
|
|
1156
|
+
return null;
|
|
1961
1157
|
}
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
this.getBrowser = function() {
|
|
1965
|
-
var _browser = {};
|
|
1966
|
-
_browser[NAME] = undefined$1;
|
|
1967
|
-
_browser[VERSION] = undefined$1;
|
|
1968
|
-
rgxMapper.call(_browser, _ua, _rgxmap.browser);
|
|
1969
|
-
_browser.major = majorize(_browser.version);
|
|
1970
|
-
return _browser;
|
|
1971
|
-
};
|
|
1972
|
-
this.getCPU = function() {
|
|
1973
|
-
var _cpu = {};
|
|
1974
|
-
_cpu[ARCHITECTURE] = undefined$1;
|
|
1975
|
-
rgxMapper.call(_cpu, _ua, _rgxmap.cpu);
|
|
1976
|
-
return _cpu;
|
|
1977
|
-
};
|
|
1978
|
-
this.getDevice = function() {
|
|
1979
|
-
var _device = {};
|
|
1980
|
-
_device[VENDOR] = undefined$1;
|
|
1981
|
-
_device[MODEL] = undefined$1;
|
|
1982
|
-
_device[TYPE] = undefined$1;
|
|
1983
|
-
rgxMapper.call(_device, _ua, _rgxmap.device);
|
|
1984
|
-
return _device;
|
|
1985
|
-
};
|
|
1986
|
-
this.getEngine = function() {
|
|
1987
|
-
var _engine = {};
|
|
1988
|
-
_engine[NAME] = undefined$1;
|
|
1989
|
-
_engine[VERSION] = undefined$1;
|
|
1990
|
-
rgxMapper.call(_engine, _ua, _rgxmap.engine);
|
|
1991
|
-
return _engine;
|
|
1992
|
-
};
|
|
1993
|
-
this.getOS = function() {
|
|
1994
|
-
var _os = {};
|
|
1995
|
-
_os[NAME] = undefined$1;
|
|
1996
|
-
_os[VERSION] = undefined$1;
|
|
1997
|
-
rgxMapper.call(_os, _ua, _rgxmap.os);
|
|
1998
|
-
return _os;
|
|
1999
|
-
};
|
|
2000
|
-
this.getResult = function() {
|
|
2001
|
-
return {
|
|
2002
|
-
ua: this.getUA(),
|
|
2003
|
-
browser: this.getBrowser(),
|
|
2004
|
-
engine: this.getEngine(),
|
|
2005
|
-
os: this.getOS(),
|
|
2006
|
-
device: this.getDevice(),
|
|
2007
|
-
cpu: this.getCPU()
|
|
2008
|
-
};
|
|
2009
|
-
};
|
|
2010
|
-
this.getUA = function() {
|
|
2011
|
-
return _ua;
|
|
2012
|
-
};
|
|
2013
|
-
this.setUA = function(ua2) {
|
|
2014
|
-
_ua = typeof ua2 === STR_TYPE && ua2.length > UA_MAX_LENGTH ? trim(ua2, UA_MAX_LENGTH) : ua2;
|
|
2015
|
-
return this;
|
|
2016
|
-
};
|
|
2017
|
-
this.setUA(_ua);
|
|
2018
|
-
return this;
|
|
2019
|
-
};
|
|
2020
|
-
UAParser.VERSION = LIBVERSION;
|
|
2021
|
-
UAParser.BROWSER = enumerize([NAME, VERSION, MAJOR]);
|
|
2022
|
-
UAParser.CPU = enumerize([ARCHITECTURE]);
|
|
2023
|
-
UAParser.DEVICE = enumerize([MODEL, VENDOR, TYPE, CONSOLE, MOBILE, SMARTTV, TABLET, WEARABLE, EMBEDDED]);
|
|
2024
|
-
UAParser.ENGINE = UAParser.OS = enumerize([NAME, VERSION]);
|
|
2025
|
-
{
|
|
2026
|
-
if (module2.exports) {
|
|
2027
|
-
exports2 = module2.exports = UAParser;
|
|
1158
|
+
if (!Level.isRange(node.coords.level)) {
|
|
1159
|
+
return node.coords.level;
|
|
2028
1160
|
}
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
$.ua.get = function() {
|
|
2036
|
-
return parser.getUA();
|
|
2037
|
-
};
|
|
2038
|
-
$.ua.set = function(ua) {
|
|
2039
|
-
parser.setUA(ua);
|
|
2040
|
-
var result = parser.getResult();
|
|
2041
|
-
for (var prop in result) {
|
|
2042
|
-
$.ua[prop] = result[prop];
|
|
2043
|
-
}
|
|
2044
|
-
};
|
|
2045
|
-
}
|
|
2046
|
-
})(typeof window === "object" ? window : commonjsGlobal);
|
|
2047
|
-
})(uaParser, uaParser.exports);
|
|
2048
|
-
var __defProp2 = Object.defineProperty;
|
|
2049
|
-
var __defNormalProp2 = (obj, key, value) => key in obj ? __defProp2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
2050
|
-
var __publicField2 = (obj, key, value) => {
|
|
2051
|
-
__defNormalProp2(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
2052
|
-
return value;
|
|
2053
|
-
};
|
|
2054
|
-
const Browser = {
|
|
2055
|
-
UNKNOWN: "Unknown",
|
|
2056
|
-
SAFARI: "Safari",
|
|
2057
|
-
FIREFOX: "Firefox",
|
|
2058
|
-
OPERA: "Opera",
|
|
2059
|
-
CHROME: "Chrome",
|
|
2060
|
-
IOS_WEBVIEW: "iOS-webview"
|
|
2061
|
-
};
|
|
2062
|
-
class BrowserUtils {
|
|
2063
|
-
static getName() {
|
|
2064
|
-
if (!this._name) {
|
|
2065
|
-
if (typeof navigator === "undefined" || !navigator) {
|
|
2066
|
-
this._name = Browser.UNKNOWN;
|
|
2067
|
-
} else {
|
|
2068
|
-
const { userAgent } = navigator;
|
|
2069
|
-
if (userAgent.match(/Firefox/i)) {
|
|
2070
|
-
this._name = Browser.FIREFOX;
|
|
2071
|
-
} else if (userAgent.match(/(Opera|OPR)/i)) {
|
|
2072
|
-
this._name = Browser.OPERA;
|
|
2073
|
-
} else if (userAgent.match(/Chrome/i)) {
|
|
2074
|
-
this._name = Browser.CHROME;
|
|
2075
|
-
} else if (userAgent.match(/Safari/i)) {
|
|
2076
|
-
this._name = Browser.SAFARI;
|
|
2077
|
-
} else if (userAgent.match(/(iPhone|iPod|iPad).*AppleWebKit(?!.*Version)/i)) {
|
|
2078
|
-
this._name = Browser.IOS_WEBVIEW;
|
|
2079
|
-
} else {
|
|
2080
|
-
this._name = Browser.UNKNOWN;
|
|
1161
|
+
let tmpLevel = null;
|
|
1162
|
+
for (let i = 0; i < node.edges.length; i++) {
|
|
1163
|
+
const edge = node.edges[i];
|
|
1164
|
+
const otherNode = edge.node1 === node ? edge.node2 : edge.node1;
|
|
1165
|
+
if (!visitedNodes.includes(otherNode)) {
|
|
1166
|
+
tmpLevel = Level.union(lookForLevel(otherNode, visitedNodes), tmpLevel);
|
|
2081
1167
|
}
|
|
2082
1168
|
}
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
const userAgent = navigator.userAgent || navigator.vendor;
|
|
2091
|
-
if (userAgent && (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(userAgent) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(userAgent.substr(0, 4)))) {
|
|
2092
|
-
this._isMobile = true;
|
|
2093
|
-
}
|
|
1169
|
+
return tmpLevel;
|
|
1170
|
+
};
|
|
1171
|
+
const othersLevels = lookForLevel(this, []);
|
|
1172
|
+
if (othersLevels !== null) {
|
|
1173
|
+
if (!Level.isRange(othersLevels)) {
|
|
1174
|
+
this.coords.level = othersLevels === level[0] ? level[1] : level[0];
|
|
1175
|
+
return;
|
|
2094
1176
|
}
|
|
2095
|
-
|
|
2096
|
-
return this._isMobile;
|
|
2097
|
-
}
|
|
2098
|
-
static clearCache() {
|
|
2099
|
-
this._name = null;
|
|
2100
|
-
this._isMobile = null;
|
|
2101
|
-
}
|
|
2102
|
-
}
|
|
2103
|
-
__publicField2(BrowserUtils, "_name", null);
|
|
2104
|
-
__publicField2(BrowserUtils, "_isMobile", null);
|
|
2105
|
-
const _GraphVertex = class {
|
|
2106
|
-
constructor(params = {}) {
|
|
2107
|
-
__publicField2(this, "name", null);
|
|
2108
|
-
__publicField2(this, "data", null);
|
|
2109
|
-
__publicField2(this, "id");
|
|
2110
|
-
__publicField2(this, "edges", []);
|
|
2111
|
-
Object.assign(this, params);
|
|
2112
|
-
if (typeof params.id === "number") {
|
|
2113
|
-
this.id = params.id;
|
|
2114
|
-
GraphEdge.currentUniqueId = Math.max(GraphEdge.currentUniqueId, params.id + 1);
|
|
2115
|
-
} else {
|
|
2116
|
-
this.id = _GraphVertex.currentUniqueId++;
|
|
1177
|
+
throw Error("Level of: " + this.coords.toString() + " cannot be decided");
|
|
2117
1178
|
}
|
|
2118
1179
|
}
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
constructor(vertex1, vertex2, params = {}) {
|
|
2124
|
-
__publicField2(this, "name", null);
|
|
2125
|
-
__publicField2(this, "data", null);
|
|
2126
|
-
__publicField2(this, "id");
|
|
2127
|
-
__publicField2(this, "_vertex1");
|
|
2128
|
-
__publicField2(this, "_vertex2");
|
|
2129
|
-
Object.assign(this, params);
|
|
2130
|
-
this.vertex1 = vertex1;
|
|
2131
|
-
this.vertex2 = vertex2;
|
|
2132
|
-
if (typeof params.id === "number") {
|
|
2133
|
-
this.id = params.id;
|
|
2134
|
-
_GraphEdge.currentUniqueId = Math.max(_GraphEdge.currentUniqueId, params.id + 1);
|
|
2135
|
-
} else {
|
|
2136
|
-
this.id = GraphVertex.currentUniqueId++;
|
|
1180
|
+
_inferNodeLevelByNeighboors() {
|
|
1181
|
+
const { level } = this.coords;
|
|
1182
|
+
if (level === null || !Level.isRange(level)) {
|
|
1183
|
+
return true;
|
|
2137
1184
|
}
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
if (this._vertex1 && this._vertex2 !== this._vertex1) {
|
|
2144
|
-
this._vertex1.edges = this._vertex1.edges.filter((edge) => edge !== this);
|
|
1185
|
+
let tmpLevel = null;
|
|
1186
|
+
for (let i = 0; i < this.edges.length; i++) {
|
|
1187
|
+
const edge = this.edges[i];
|
|
1188
|
+
const otherNode = edge.node1 === this ? edge.node2 : edge.node1;
|
|
1189
|
+
tmpLevel = Level.union(otherNode.coords.level, tmpLevel);
|
|
2145
1190
|
}
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
}
|
|
2149
|
-
get vertex2() {
|
|
2150
|
-
return this._vertex2;
|
|
2151
|
-
}
|
|
2152
|
-
set vertex2(vertex) {
|
|
2153
|
-
if (this._vertex2 && this._vertex2 !== this._vertex1) {
|
|
2154
|
-
this._vertex2.edges = this._vertex2.edges.filter((edge) => edge !== this);
|
|
1191
|
+
if (tmpLevel === null || !Level.isRange(tmpLevel)) {
|
|
1192
|
+
this.coords.level = tmpLevel === level[0] ? level[1] : level[0];
|
|
2155
1193
|
}
|
|
2156
|
-
|
|
2157
|
-
this._vertex2 = vertex;
|
|
2158
|
-
}
|
|
2159
|
-
static getEdgeByVertices(edges, vertex1, vertex2) {
|
|
2160
|
-
return edges.find(
|
|
2161
|
-
(edge) => vertex1 === edge.vertex1 && vertex2 === edge.vertex2 || vertex2 === edge.vertex1 && vertex1 === edge.vertex2
|
|
2162
|
-
);
|
|
2163
|
-
}
|
|
2164
|
-
};
|
|
2165
|
-
let GraphEdge = _GraphEdge;
|
|
2166
|
-
__publicField2(GraphEdge, "currentUniqueId", 0);
|
|
2167
|
-
class Graph {
|
|
2168
|
-
constructor(vertices, edges) {
|
|
2169
|
-
__publicField2(this, "vertices");
|
|
2170
|
-
__publicField2(this, "edges");
|
|
2171
|
-
this.vertices = Array.isArray(vertices) ? vertices : [];
|
|
2172
|
-
this.edges = Array.isArray(edges) ? edges : [];
|
|
2173
|
-
}
|
|
2174
|
-
getEdgeByVertices(vertex1, vertex2) {
|
|
2175
|
-
return GraphEdge.getEdgeByVertices(this.edges, vertex1, vertex2);
|
|
2176
|
-
}
|
|
2177
|
-
getVertexByName(name) {
|
|
2178
|
-
return this.vertices.find((vertex) => vertex.name === name);
|
|
1194
|
+
return true;
|
|
2179
1195
|
}
|
|
2180
|
-
|
|
2181
|
-
|
|
1196
|
+
_checkIO() {
|
|
1197
|
+
this.io = this.coords.level !== null && this.edges.some((edge) => edge.level === null);
|
|
1198
|
+
return true;
|
|
2182
1199
|
}
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
Vertices
|
|
2189
|
-
`;
|
|
2190
|
-
this.vertices.forEach((vertex) => {
|
|
2191
|
-
output += `${vertex.id} [edges: ${vertex.edges.length}]
|
|
2192
|
-
`;
|
|
2193
|
-
});
|
|
2194
|
-
output += "---\nEdges\n";
|
|
2195
|
-
this.edges.forEach((edge) => {
|
|
2196
|
-
output += `${edge.id} `;
|
|
2197
|
-
output += `[${edge.vertex1.id} -- ${edge.vertex2.id}]
|
|
2198
|
-
`;
|
|
2199
|
-
});
|
|
2200
|
-
output += "---";
|
|
2201
|
-
return output;
|
|
1200
|
+
static generateNodesLevels(nodes) {
|
|
1201
|
+
nodes.forEach((node) => node._generateLevelFromEdges());
|
|
1202
|
+
nodes.forEach((node) => node._inferNodeLevelByNeighboors());
|
|
1203
|
+
nodes.forEach((node) => node._inferNodeLevelByRecursion());
|
|
1204
|
+
nodes.forEach((node) => node._checkIO());
|
|
2202
1205
|
}
|
|
2203
1206
|
}
|
|
2204
|
-
class
|
|
2205
|
-
constructor(
|
|
2206
|
-
|
|
1207
|
+
class GraphEdge {
|
|
1208
|
+
constructor(node1, node2, level = null, builtFrom = null) {
|
|
1209
|
+
__publicField(this, "_node1");
|
|
1210
|
+
__publicField(this, "_node2");
|
|
2207
1211
|
__publicField(this, "_level", null);
|
|
2208
1212
|
__publicField(this, "_bearing", null);
|
|
2209
1213
|
__publicField(this, "_length", null);
|
|
2210
1214
|
__publicField(this, "_computedSizeAndBearing", false);
|
|
1215
|
+
__publicField(this, "builtFrom");
|
|
2211
1216
|
__publicField(this, "isOneway", false);
|
|
2212
|
-
|
|
1217
|
+
this.node1 = node1;
|
|
1218
|
+
this.node2 = node2;
|
|
1219
|
+
this.level = level;
|
|
1220
|
+
this.builtFrom = builtFrom;
|
|
1221
|
+
}
|
|
1222
|
+
get node1() {
|
|
1223
|
+
return this._node1;
|
|
2213
1224
|
}
|
|
2214
|
-
set
|
|
2215
|
-
|
|
1225
|
+
set node1(node) {
|
|
1226
|
+
if (!(node instanceof GraphNode)) {
|
|
1227
|
+
throw new TypeError("node1 is not a GraphNode");
|
|
1228
|
+
}
|
|
1229
|
+
if (this._node1 instanceof GraphNode && this._node2 !== this._node1) {
|
|
1230
|
+
this._node1.edges = this._node1.edges.filter((edge) => edge !== this);
|
|
1231
|
+
}
|
|
1232
|
+
node.edges.push(this);
|
|
1233
|
+
this._node1 = node;
|
|
2216
1234
|
this._computedSizeAndBearing = false;
|
|
2217
1235
|
}
|
|
2218
|
-
get
|
|
2219
|
-
return this.
|
|
1236
|
+
get node2() {
|
|
1237
|
+
return this._node2;
|
|
2220
1238
|
}
|
|
2221
|
-
set
|
|
2222
|
-
|
|
1239
|
+
set node2(node) {
|
|
1240
|
+
if (!(node instanceof GraphNode)) {
|
|
1241
|
+
throw new TypeError("node2 is not a GraphNode");
|
|
1242
|
+
}
|
|
1243
|
+
if (this._node2 instanceof GraphNode && this._node2 !== this._node1) {
|
|
1244
|
+
this._node2.edges = this._node2.edges.filter((edge) => edge !== this);
|
|
1245
|
+
}
|
|
1246
|
+
node.edges.push(this);
|
|
1247
|
+
this._node2 = node;
|
|
2223
1248
|
this._computedSizeAndBearing = false;
|
|
2224
1249
|
}
|
|
2225
|
-
get vertex2() {
|
|
2226
|
-
return this._vertex2;
|
|
2227
|
-
}
|
|
2228
1250
|
get level() {
|
|
2229
1251
|
return this._level;
|
|
2230
1252
|
}
|
|
@@ -2245,206 +1267,159 @@ class GeoGraphEdge extends GraphEdge {
|
|
|
2245
1267
|
return this._length;
|
|
2246
1268
|
}
|
|
2247
1269
|
_computeSizeAndBearing() {
|
|
2248
|
-
this._length = this.
|
|
2249
|
-
this._bearing = this.
|
|
1270
|
+
this._length = this.node1.distanceTo(this.node2);
|
|
1271
|
+
this._bearing = this.node1.bearingTo(this.node2);
|
|
2250
1272
|
this._computedSizeAndBearing = true;
|
|
2251
1273
|
}
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
}
|
|
2255
|
-
}
|
|
2256
|
-
class GeoGraphVertex extends GraphVertex {
|
|
2257
|
-
constructor(coords, params) {
|
|
2258
|
-
super(params);
|
|
2259
|
-
__publicField(this, "coords");
|
|
2260
|
-
__publicField(this, "io", false);
|
|
2261
|
-
this.coords = coords;
|
|
2262
|
-
}
|
|
2263
|
-
distanceTo(other) {
|
|
2264
|
-
return this.coords.distanceTo(other.coords);
|
|
2265
|
-
}
|
|
2266
|
-
bearingTo(other) {
|
|
2267
|
-
return this.coords.bearingTo(other.coords);
|
|
2268
|
-
}
|
|
2269
|
-
toJson() {
|
|
2270
|
-
return this.coords.toCompressedJson();
|
|
2271
|
-
}
|
|
2272
|
-
static fromJson(json) {
|
|
2273
|
-
return new GeoGraphVertex(Coordinates.fromCompressedJson(json));
|
|
2274
|
-
}
|
|
2275
|
-
inferVertexLevelFromEdges() {
|
|
2276
|
-
let tmpLevel = null;
|
|
2277
|
-
for (let i = 0; i < this.edges.length; i++) {
|
|
2278
|
-
const edge = this.edges[i];
|
|
2279
|
-
if (edge.level !== null) {
|
|
2280
|
-
if (tmpLevel === null) {
|
|
2281
|
-
tmpLevel = Level.clone(edge.level);
|
|
2282
|
-
} else {
|
|
2283
|
-
tmpLevel = Level.intersection(tmpLevel, edge.level);
|
|
2284
|
-
if (tmpLevel === null) {
|
|
2285
|
-
throw Error("Something bad happend during parsing: We cannot retrieve vertex level from adjacent ways: " + this.coords);
|
|
2286
|
-
}
|
|
2287
|
-
}
|
|
2288
|
-
}
|
|
2289
|
-
}
|
|
2290
|
-
this.coords.level = tmpLevel;
|
|
2291
|
-
}
|
|
2292
|
-
inferVertexLevelByNeighboors() {
|
|
2293
|
-
const { level } = this.coords;
|
|
2294
|
-
if (level === null || !Level.isRange(level)) {
|
|
1274
|
+
equals(other) {
|
|
1275
|
+
if (this === other) {
|
|
2295
1276
|
return true;
|
|
2296
1277
|
}
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
const edge = this.edges[i];
|
|
2300
|
-
const otherVertex = edge.vertex1 === this ? edge.vertex2 : edge.vertex1;
|
|
2301
|
-
tmpLevel = Level.union(otherVertex.coords.level, tmpLevel);
|
|
2302
|
-
}
|
|
2303
|
-
if (tmpLevel === null || !Level.isRange(tmpLevel)) {
|
|
2304
|
-
this.coords.level = tmpLevel === level[0] ? level[1] : level[0];
|
|
1278
|
+
if (!(other instanceof GraphEdge)) {
|
|
1279
|
+
return false;
|
|
2305
1280
|
}
|
|
2306
|
-
return
|
|
1281
|
+
return other.node1.equals(this.node1) && other.node2.equals(this.node2) && Level.equals(other.level, this.level) && other.isOneway === this.isOneway && other.builtFrom === this.builtFrom;
|
|
2307
1282
|
}
|
|
2308
|
-
|
|
2309
|
-
const
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
}
|
|
2313
|
-
if (this.edges.length > 1) {
|
|
2314
|
-
return;
|
|
2315
|
-
}
|
|
2316
|
-
const lookForLevel = (vertex, visitedVertices) => {
|
|
2317
|
-
visitedVertices.push(vertex);
|
|
2318
|
-
if (vertex.coords.level === null) {
|
|
2319
|
-
return null;
|
|
2320
|
-
}
|
|
2321
|
-
if (!Level.isRange(vertex.coords.level)) {
|
|
2322
|
-
return vertex.coords.level;
|
|
2323
|
-
}
|
|
2324
|
-
let tmpLevel = null;
|
|
2325
|
-
for (let i = 0; i < vertex.edges.length; i++) {
|
|
2326
|
-
const edge = vertex.edges[i];
|
|
2327
|
-
const otherVertex = edge.vertex1 === vertex ? edge.vertex2 : edge.vertex1;
|
|
2328
|
-
if (!visitedVertices.includes(otherVertex)) {
|
|
2329
|
-
tmpLevel = Level.union(lookForLevel(otherVertex, visitedVertices), tmpLevel);
|
|
2330
|
-
}
|
|
2331
|
-
}
|
|
2332
|
-
return tmpLevel;
|
|
2333
|
-
};
|
|
2334
|
-
const othersLevels = lookForLevel(this, []);
|
|
2335
|
-
if (othersLevels !== null) {
|
|
2336
|
-
if (!Level.isRange(othersLevels)) {
|
|
2337
|
-
this.coords.level = othersLevels === level[0] ? level[1] : level[0];
|
|
2338
|
-
return;
|
|
2339
|
-
}
|
|
2340
|
-
throw Error("Level of: " + this.coords.toString() + " cannot be decided");
|
|
2341
|
-
}
|
|
1283
|
+
clone() {
|
|
1284
|
+
const edge = new GraphEdge(this.node1, this.node2, this.level, this.builtFrom);
|
|
1285
|
+
edge.isOneway = this.isOneway;
|
|
1286
|
+
return edge;
|
|
2342
1287
|
}
|
|
2343
1288
|
}
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
1289
|
+
function getEdgeByNodes(edges, node1, node2) {
|
|
1290
|
+
return edges.find(
|
|
1291
|
+
(edge) => node1 === edge.node1 && node2 === edge.node2 || node2 === edge.node1 && node1 === edge.node2
|
|
1292
|
+
);
|
|
1293
|
+
}
|
|
1294
|
+
function getNodeByCoords(nodes, coords) {
|
|
1295
|
+
return nodes.find((node) => node.coords.equals(coords));
|
|
1296
|
+
}
|
|
1297
|
+
const GraphUtils = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1298
|
+
__proto__: null,
|
|
1299
|
+
getEdgeByNodes,
|
|
1300
|
+
getNodeByCoords
|
|
1301
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
1302
|
+
class Network {
|
|
1303
|
+
constructor(nodes, edges) {
|
|
1304
|
+
__publicField(this, "nodes");
|
|
1305
|
+
__publicField(this, "edges");
|
|
1306
|
+
this.nodes = Array.isArray(nodes) ? nodes : [];
|
|
1307
|
+
this.edges = Array.isArray(edges) ? edges : [];
|
|
2354
1308
|
}
|
|
2355
|
-
|
|
2356
|
-
return
|
|
1309
|
+
getNodeByCoords(coords) {
|
|
1310
|
+
return this.nodes.find((node) => node.coords.equals(coords));
|
|
2357
1311
|
}
|
|
2358
|
-
|
|
2359
|
-
return
|
|
1312
|
+
getEdgeByNodes(node1, node2) {
|
|
1313
|
+
return getEdgeByNodes(this.edges, node1, node2);
|
|
2360
1314
|
}
|
|
2361
1315
|
getBoundingBox(extendedMeasure) {
|
|
2362
|
-
if (!this.
|
|
1316
|
+
if (!this.nodes.length) {
|
|
2363
1317
|
return null;
|
|
2364
1318
|
}
|
|
2365
|
-
const boundingBox = BoundingBox.fromCoordinates(this.
|
|
1319
|
+
const boundingBox = BoundingBox.fromCoordinates(this.nodes.map((node) => node.coords));
|
|
2366
1320
|
if (extendedMeasure) {
|
|
2367
1321
|
boundingBox.extendsWithMeasure(extendedMeasure);
|
|
2368
1322
|
}
|
|
2369
1323
|
return boundingBox;
|
|
2370
1324
|
}
|
|
1325
|
+
toDetailedString(_nodeToStringFn, _edgeToStringFn) {
|
|
1326
|
+
let nodeToStringFn = _nodeToStringFn;
|
|
1327
|
+
if (!nodeToStringFn) {
|
|
1328
|
+
nodeToStringFn = (node) => `${node.builtFrom}`;
|
|
1329
|
+
}
|
|
1330
|
+
let edgeToStringFn = _edgeToStringFn;
|
|
1331
|
+
if (!_edgeToStringFn) {
|
|
1332
|
+
edgeToStringFn = (edge) => `${edge.builtFrom}`;
|
|
1333
|
+
}
|
|
1334
|
+
let output = `--- Network ---
|
|
1335
|
+
Nodes: ${this.nodes.length}
|
|
1336
|
+
Edges: ${this.edges.length}
|
|
1337
|
+
---
|
|
1338
|
+
Nodes
|
|
1339
|
+
`;
|
|
1340
|
+
this.nodes.forEach((node) => {
|
|
1341
|
+
output += `${nodeToStringFn(node)} [edges: ${node.edges.length}]
|
|
1342
|
+
`;
|
|
1343
|
+
});
|
|
1344
|
+
output += "---\nEdges\n";
|
|
1345
|
+
this.edges.forEach((edge) => {
|
|
1346
|
+
output += `${edgeToStringFn(edge)} `;
|
|
1347
|
+
output += `[${nodeToStringFn(edge.node1)} -- ${nodeToStringFn(edge.node2)}]
|
|
1348
|
+
`;
|
|
1349
|
+
});
|
|
1350
|
+
output += "---";
|
|
1351
|
+
return output;
|
|
1352
|
+
}
|
|
2371
1353
|
toCompressedJson() {
|
|
2372
1354
|
return {
|
|
2373
|
-
|
|
1355
|
+
nodes: this.nodes.map((node) => node.toJson()),
|
|
2374
1356
|
edges: this.edges.map((edge) => {
|
|
2375
|
-
const
|
|
2376
|
-
const
|
|
1357
|
+
const node1Idx = this.nodes.indexOf(edge.node1);
|
|
1358
|
+
const node2Idx = this.nodes.indexOf(edge.node2);
|
|
2377
1359
|
if (edge.isOneway) {
|
|
2378
|
-
return [
|
|
1360
|
+
return [node1Idx, node2Idx, edge.level, true];
|
|
2379
1361
|
}
|
|
2380
|
-
if (edge.level
|
|
2381
|
-
return [
|
|
1362
|
+
if (edge.level) {
|
|
1363
|
+
return [node1Idx, node2Idx, edge.level];
|
|
2382
1364
|
}
|
|
2383
|
-
return [
|
|
1365
|
+
return [node1Idx, node2Idx];
|
|
2384
1366
|
})
|
|
2385
1367
|
};
|
|
2386
1368
|
}
|
|
2387
1369
|
static fromCompressedJson(json) {
|
|
2388
|
-
const
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
const edge = new
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
1370
|
+
const network = new Network();
|
|
1371
|
+
network.nodes = json.nodes.map((node) => GraphNode.fromJson(node, null));
|
|
1372
|
+
network.edges = json.edges.map((jsonEdge) => {
|
|
1373
|
+
const edge = new GraphEdge(
|
|
1374
|
+
network.nodes[jsonEdge[0]],
|
|
1375
|
+
network.nodes[jsonEdge[1]],
|
|
1376
|
+
jsonEdge[2],
|
|
1377
|
+
null
|
|
2395
1378
|
);
|
|
2396
1379
|
if (jsonEdge.length > 3 && jsonEdge[3]) {
|
|
2397
1380
|
edge.isOneway = true;
|
|
2398
1381
|
}
|
|
2399
1382
|
return edge;
|
|
2400
1383
|
});
|
|
2401
|
-
return
|
|
1384
|
+
return network;
|
|
2402
1385
|
}
|
|
2403
1386
|
static fromCoordinates(segments) {
|
|
2404
|
-
const
|
|
2405
|
-
const
|
|
2406
|
-
const
|
|
2407
|
-
if (
|
|
2408
|
-
return
|
|
1387
|
+
const network = new Network();
|
|
1388
|
+
const getOrCreateNode = (coords) => {
|
|
1389
|
+
const node = network.nodes.find((otherNode) => otherNode.coords.equals(coords));
|
|
1390
|
+
if (node) {
|
|
1391
|
+
return node;
|
|
2409
1392
|
}
|
|
2410
|
-
const
|
|
2411
|
-
|
|
2412
|
-
return
|
|
1393
|
+
const newNode = new GraphNode(coords, null);
|
|
1394
|
+
network.nodes.push(newNode);
|
|
1395
|
+
return newNode;
|
|
2413
1396
|
};
|
|
2414
|
-
const
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
1397
|
+
const createEdgeFromNodes = (node1, node2) => new GraphEdge(
|
|
1398
|
+
node1,
|
|
1399
|
+
node2,
|
|
1400
|
+
Level.union(node1.coords.level, node2.coords.level),
|
|
1401
|
+
null
|
|
2418
1402
|
);
|
|
2419
1403
|
for (const segment of segments) {
|
|
2420
|
-
let
|
|
1404
|
+
let previousNode = null;
|
|
2421
1405
|
for (const coords of segment) {
|
|
2422
|
-
const
|
|
2423
|
-
if (
|
|
2424
|
-
const edge =
|
|
2425
|
-
|
|
1406
|
+
const currentNode = getOrCreateNode(coords);
|
|
1407
|
+
if (previousNode) {
|
|
1408
|
+
const edge = createEdgeFromNodes(currentNode, previousNode);
|
|
1409
|
+
network.edges.push(edge);
|
|
2426
1410
|
}
|
|
2427
|
-
|
|
1411
|
+
previousNode = currentNode;
|
|
2428
1412
|
}
|
|
2429
1413
|
}
|
|
2430
|
-
return
|
|
1414
|
+
return network;
|
|
2431
1415
|
}
|
|
2432
1416
|
getEdgesAtLevel(targetLevel, useMultiLevelEdges = true) {
|
|
2433
1417
|
return this.edges.filter(
|
|
2434
1418
|
({ level }) => useMultiLevelEdges ? Level.intersect(targetLevel, level) : Level.contains(targetLevel, level)
|
|
2435
1419
|
);
|
|
2436
1420
|
}
|
|
2437
|
-
generateVerticesLevels() {
|
|
2438
|
-
const { vertices } = this;
|
|
2439
|
-
vertices.forEach((vertex) => vertex.inferVertexLevelFromEdges());
|
|
2440
|
-
vertices.forEach((vertex) => vertex.inferVertexLevelByNeighboors());
|
|
2441
|
-
vertices.forEach((vertex) => vertex.inferVertexLevelByRecursion());
|
|
2442
|
-
vertices.forEach((vertex) => {
|
|
2443
|
-
vertex.io = vertex.coords.level !== null && vertex.edges.some((edge) => edge.level === null);
|
|
2444
|
-
});
|
|
2445
|
-
}
|
|
2446
1421
|
}
|
|
2447
|
-
class
|
|
1422
|
+
class GraphProjection {
|
|
2448
1423
|
constructor(origin, distanceFromNearestElement, coords, nearestElement) {
|
|
2449
1424
|
__publicField(this, "origin");
|
|
2450
1425
|
__publicField(this, "distanceFromNearestElement");
|
|
@@ -2456,12 +1431,12 @@ class GeoGraphProjection {
|
|
|
2456
1431
|
this.nearestElement = nearestElement;
|
|
2457
1432
|
}
|
|
2458
1433
|
}
|
|
2459
|
-
const
|
|
2460
|
-
constructor(
|
|
2461
|
-
__publicField(this, "
|
|
1434
|
+
const _MapMatching = class {
|
|
1435
|
+
constructor(network = null) {
|
|
1436
|
+
__publicField(this, "network", null);
|
|
2462
1437
|
__publicField(this, "_maxDistance", Number.MAX_VALUE);
|
|
2463
1438
|
__publicField(this, "_maxAngleBearing", Math.PI);
|
|
2464
|
-
this.
|
|
1439
|
+
this.network = network;
|
|
2465
1440
|
}
|
|
2466
1441
|
set maxAngleBearing(maxAngleBearing) {
|
|
2467
1442
|
this._maxAngleBearing = maxAngleBearing;
|
|
@@ -2480,14 +1455,14 @@ const _GeoGraphProjectionHandler = class {
|
|
|
2480
1455
|
return [false, false, false];
|
|
2481
1456
|
}
|
|
2482
1457
|
let checkEdge = Level.intersect(location.level, edge.level);
|
|
2483
|
-
let checkNode1 = Level.intersect(location.level, edge.
|
|
2484
|
-
let checkNode2 = Level.intersect(location.level, edge.
|
|
2485
|
-
checkNode1 = checkNode1 || edge.
|
|
2486
|
-
checkNode2 = checkNode2 || edge.
|
|
1458
|
+
let checkNode1 = Level.intersect(location.level, edge.node1.coords.level);
|
|
1459
|
+
let checkNode2 = Level.intersect(location.level, edge.node2.coords.level);
|
|
1460
|
+
checkNode1 = checkNode1 || edge.node1.io && location.level === null;
|
|
1461
|
+
checkNode2 = checkNode2 || edge.node2.io && location.level === null;
|
|
2487
1462
|
if (!useMultiLevelSegments) {
|
|
2488
1463
|
checkEdge = checkEdge && !Level.isRange(edge.level);
|
|
2489
|
-
checkNode1 = checkNode1 && !Level.isRange(edge.
|
|
2490
|
-
checkNode2 = checkNode2 && !Level.isRange(edge.
|
|
1464
|
+
checkNode1 = checkNode1 && !Level.isRange(edge.node1.coords.level);
|
|
1465
|
+
checkNode2 = checkNode2 && !Level.isRange(edge.node2.coords.level);
|
|
2491
1466
|
}
|
|
2492
1467
|
if (useBearing) {
|
|
2493
1468
|
if (checkEdge) {
|
|
@@ -2512,8 +1487,11 @@ const _GeoGraphProjectionHandler = class {
|
|
|
2512
1487
|
}
|
|
2513
1488
|
}
|
|
2514
1489
|
getProjection(location, useDistance = false, useBearing = false, useMultiLevelSegments = true, acceptEdgeFn = () => true) {
|
|
2515
|
-
if (this.
|
|
2516
|
-
throw new Error("
|
|
1490
|
+
if (this.network === null) {
|
|
1491
|
+
throw new Error("Network has not been set yet");
|
|
1492
|
+
}
|
|
1493
|
+
if (!(location instanceof Coordinates)) {
|
|
1494
|
+
throw new TypeError("location is not an instance of Coordinates");
|
|
2517
1495
|
}
|
|
2518
1496
|
if (useBearing && (!("bearing" in location && location.bearing !== null) || !this._maxAngleBearing)) {
|
|
2519
1497
|
return null;
|
|
@@ -2524,7 +1502,7 @@ const _GeoGraphProjectionHandler = class {
|
|
|
2524
1502
|
const isProjectionBetter = (distanceOfNewProjection) => {
|
|
2525
1503
|
return distanceOfNewProjection < distanceFromNearestElement && (!useDistance || distanceOfNewProjection <= this._maxDistance);
|
|
2526
1504
|
};
|
|
2527
|
-
for (const edge of this.
|
|
1505
|
+
for (const edge of this.network.edges) {
|
|
2528
1506
|
const [checkEdge, checkNode1, checkNode2] = this._shouldProjectOnEdgeAndNodes(
|
|
2529
1507
|
edge,
|
|
2530
1508
|
location,
|
|
@@ -2533,38 +1511,38 @@ const _GeoGraphProjectionHandler = class {
|
|
|
2533
1511
|
acceptEdgeFn
|
|
2534
1512
|
);
|
|
2535
1513
|
if (checkNode1) {
|
|
2536
|
-
const distNode1 = location.distanceTo(edge.
|
|
1514
|
+
const distNode1 = location.distanceTo(edge.node1.coords);
|
|
2537
1515
|
if (isProjectionBetter(distNode1) || distNode1 <= EPS_MM) {
|
|
2538
1516
|
distanceFromNearestElement = distNode1;
|
|
2539
|
-
nearestElement = edge.
|
|
2540
|
-
|
|
2541
|
-
|
|
1517
|
+
nearestElement = edge.node1;
|
|
1518
|
+
_MapMatching._assignLatLngLevel(edge.node1.coords, projection);
|
|
1519
|
+
_MapMatching._handleLevelsWithIONodes(projection, location, edge.node1);
|
|
2542
1520
|
if (distNode1 <= EPS_MM) {
|
|
2543
1521
|
break;
|
|
2544
1522
|
}
|
|
2545
1523
|
}
|
|
2546
1524
|
}
|
|
2547
1525
|
if (checkNode2) {
|
|
2548
|
-
const distNode2 = location.distanceTo(edge.
|
|
1526
|
+
const distNode2 = location.distanceTo(edge.node2.coords);
|
|
2549
1527
|
if (isProjectionBetter(distNode2) || distNode2 <= EPS_MM) {
|
|
2550
1528
|
distanceFromNearestElement = distNode2;
|
|
2551
|
-
nearestElement = edge.
|
|
2552
|
-
|
|
2553
|
-
|
|
1529
|
+
nearestElement = edge.node2;
|
|
1530
|
+
_MapMatching._assignLatLngLevel(edge.node2.coords, projection);
|
|
1531
|
+
_MapMatching._handleLevelsWithIONodes(projection, location, edge.node2);
|
|
2554
1532
|
if (distNode2 <= EPS_MM) {
|
|
2555
1533
|
break;
|
|
2556
1534
|
}
|
|
2557
1535
|
}
|
|
2558
1536
|
}
|
|
2559
1537
|
if (checkEdge) {
|
|
2560
|
-
const segmentProjection = location.getSegmentProjection(edge.
|
|
1538
|
+
const segmentProjection = location.getSegmentProjection(edge.node1.coords, edge.node2.coords);
|
|
2561
1539
|
if (segmentProjection) {
|
|
2562
1540
|
const distEdge = location.distanceTo(segmentProjection);
|
|
2563
1541
|
if (isProjectionBetter(distEdge)) {
|
|
2564
1542
|
distanceFromNearestElement = distEdge;
|
|
2565
1543
|
nearestElement = edge;
|
|
2566
|
-
|
|
2567
|
-
|
|
1544
|
+
_MapMatching._assignLatLngLevel(segmentProjection, projection);
|
|
1545
|
+
_MapMatching._updateProjectionLevelFromEdge(edge, projection);
|
|
2568
1546
|
}
|
|
2569
1547
|
}
|
|
2570
1548
|
}
|
|
@@ -2575,7 +1553,7 @@ const _GeoGraphProjectionHandler = class {
|
|
|
2575
1553
|
if (projection instanceof UserPosition && projection.accuracy !== null) {
|
|
2576
1554
|
projection.accuracy += distanceFromNearestElement;
|
|
2577
1555
|
}
|
|
2578
|
-
return new
|
|
1556
|
+
return new GraphProjection(
|
|
2579
1557
|
location,
|
|
2580
1558
|
distanceFromNearestElement,
|
|
2581
1559
|
projection,
|
|
@@ -2583,59 +1561,74 @@ const _GeoGraphProjectionHandler = class {
|
|
|
2583
1561
|
);
|
|
2584
1562
|
}
|
|
2585
1563
|
};
|
|
2586
|
-
let
|
|
2587
|
-
__publicField(
|
|
1564
|
+
let MapMatching = _MapMatching;
|
|
1565
|
+
__publicField(MapMatching, "_updateProjectionLevelFromEdge", (_edge, _projection) => {
|
|
2588
1566
|
_projection.level = Level.clone(_edge.level);
|
|
2589
1567
|
});
|
|
2590
|
-
class
|
|
2591
|
-
constructor(start, end,
|
|
2592
|
-
|
|
1568
|
+
class GraphItinerary {
|
|
1569
|
+
constructor(start, end, nodes, edges, edgesWeights) {
|
|
1570
|
+
__publicField(this, "start");
|
|
1571
|
+
__publicField(this, "end");
|
|
1572
|
+
__publicField(this, "nodes");
|
|
1573
|
+
__publicField(this, "edges");
|
|
1574
|
+
__publicField(this, "edgesWeights");
|
|
2593
1575
|
this.start = start;
|
|
2594
1576
|
this.end = end;
|
|
1577
|
+
this.nodes = nodes;
|
|
1578
|
+
this.edges = edges;
|
|
2595
1579
|
this.edgesWeights = edgesWeights;
|
|
2596
1580
|
}
|
|
2597
|
-
static
|
|
2598
|
-
const
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
1581
|
+
static fromNetworkNodes(start, end, networkNodes, edgesWeights) {
|
|
1582
|
+
const nodes = networkNodes.map((node) => {
|
|
1583
|
+
const newNode = node.clone();
|
|
1584
|
+
newNode.edges = [];
|
|
1585
|
+
if (newNode.io) {
|
|
1586
|
+
newNode.coords = newNode.coords.clone();
|
|
1587
|
+
newNode.coords.level = null;
|
|
1588
|
+
}
|
|
1589
|
+
return newNode;
|
|
2603
1590
|
});
|
|
2604
1591
|
const edges = [];
|
|
2605
|
-
|
|
1592
|
+
networkNodes.forEach((node, idx, arr) => {
|
|
2606
1593
|
if (idx === 0) {
|
|
2607
1594
|
return;
|
|
2608
1595
|
}
|
|
2609
|
-
const
|
|
2610
|
-
const edge =
|
|
1596
|
+
const prevNode = arr[idx - 1];
|
|
1597
|
+
const edge = getEdgeByNodes(prevNode.edges, prevNode, node);
|
|
2611
1598
|
if (!edge) {
|
|
2612
1599
|
Logger__default.default.error("Cannot retrieve edge to create itinerary");
|
|
2613
1600
|
return;
|
|
2614
1601
|
}
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
1602
|
+
const newEdge = new GraphEdge(
|
|
1603
|
+
nodes[idx - 1],
|
|
1604
|
+
nodes[idx],
|
|
1605
|
+
edge.level,
|
|
1606
|
+
edge.builtFrom
|
|
1607
|
+
);
|
|
1608
|
+
newEdge.isOneway = edge.isOneway;
|
|
1609
|
+
edges.push(newEdge);
|
|
2620
1610
|
});
|
|
2621
|
-
return new
|
|
1611
|
+
return new GraphItinerary(start, end, nodes, edges, edgesWeights);
|
|
2622
1612
|
}
|
|
2623
1613
|
}
|
|
2624
1614
|
class NoRouteFoundError extends Error {
|
|
2625
|
-
constructor(start, end, details
|
|
1615
|
+
constructor(start, end, details) {
|
|
2626
1616
|
super();
|
|
1617
|
+
__publicField(this, "details");
|
|
1618
|
+
__publicField(this, "end");
|
|
1619
|
+
__publicField(this, "start");
|
|
2627
1620
|
this.start = start;
|
|
2628
1621
|
this.end = end;
|
|
2629
1622
|
this.details = details;
|
|
2630
1623
|
}
|
|
2631
1624
|
get startStr() {
|
|
2632
|
-
if (this.start instanceof
|
|
1625
|
+
if (this.start instanceof GraphNode) {
|
|
2633
1626
|
return `GraphNode ${this.start.coords.toString()}`;
|
|
2634
1627
|
}
|
|
2635
1628
|
return this.start.toString();
|
|
2636
1629
|
}
|
|
2637
1630
|
get endStr() {
|
|
2638
|
-
if (this.end instanceof
|
|
1631
|
+
if (this.end instanceof GraphNode) {
|
|
2639
1632
|
return `GraphNode ${this.end.coords.toString()}`;
|
|
2640
1633
|
}
|
|
2641
1634
|
return this.end.toString();
|
|
@@ -2648,142 +1641,159 @@ class NoRouteFoundError extends Error {
|
|
|
2648
1641
|
return message;
|
|
2649
1642
|
}
|
|
2650
1643
|
}
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
1644
|
+
class GraphRouterOptions {
|
|
1645
|
+
constructor() {
|
|
1646
|
+
__publicField(this, "projectionMaxDistance", 50);
|
|
1647
|
+
__publicField(this, "weightEdgeFn", (edge) => edge.length);
|
|
1648
|
+
__publicField(this, "acceptEdgeFn", () => true);
|
|
1649
|
+
}
|
|
1650
|
+
}
|
|
1651
|
+
class GraphRouter {
|
|
1652
|
+
constructor(network) {
|
|
2658
1653
|
__publicField(this, "_mapMatching");
|
|
2659
|
-
__publicField(this, "
|
|
1654
|
+
__publicField(this, "_network");
|
|
2660
1655
|
__publicField(this, "disabledEdges", /* @__PURE__ */ new Set());
|
|
2661
|
-
this.
|
|
2662
|
-
this._mapMatching = new
|
|
1656
|
+
this._network = network;
|
|
1657
|
+
this._mapMatching = new MapMatching(network);
|
|
2663
1658
|
}
|
|
2664
|
-
getShortestPath(start, end, options =
|
|
1659
|
+
getShortestPath(start, end, options = new GraphRouterOptions()) {
|
|
1660
|
+
if (!(start instanceof GraphNode) && !(start instanceof Coordinates)) {
|
|
1661
|
+
throw new Error("Unknown start type");
|
|
1662
|
+
}
|
|
1663
|
+
if (!(end instanceof GraphNode) && !(end instanceof Coordinates)) {
|
|
1664
|
+
throw new Error("Unknown end type");
|
|
1665
|
+
}
|
|
2665
1666
|
const { acceptEdgeFn, weightEdgeFn, projectionMaxDistance } = options;
|
|
2666
1667
|
this._mapMatching.maxDistance = projectionMaxDistance;
|
|
2667
|
-
const
|
|
2668
|
-
const
|
|
2669
|
-
if (point instanceof
|
|
1668
|
+
const createdNodes = [];
|
|
1669
|
+
const retrieveOrCreateNearestNode = (point) => {
|
|
1670
|
+
if (point instanceof GraphNode) {
|
|
2670
1671
|
return point;
|
|
2671
1672
|
}
|
|
2672
|
-
const
|
|
2673
|
-
if (
|
|
2674
|
-
return
|
|
1673
|
+
const closeNode = this._network.getNodeByCoords(point);
|
|
1674
|
+
if (closeNode) {
|
|
1675
|
+
return closeNode;
|
|
2675
1676
|
}
|
|
2676
1677
|
const proj = this._mapMatching.getProjection(point, true, false, false, acceptEdgeFn);
|
|
2677
1678
|
if (!proj) {
|
|
2678
|
-
let message = `Point ${point.toString()} is too far from the
|
|
1679
|
+
let message = `Point ${point.toString()} is too far from the network > ${this._mapMatching.maxDistance.toFixed(0)} meters.`;
|
|
2679
1680
|
if (point.level !== null) {
|
|
2680
|
-
message += ` If it is a multi-level map, please verify if you have a
|
|
1681
|
+
message += ` If it is a multi-level map, please verify if you have a network at level ${Level.toString(point.level)}.`;
|
|
2681
1682
|
}
|
|
2682
1683
|
throw new NoRouteFoundError(start, end, message);
|
|
2683
1684
|
}
|
|
2684
|
-
if (proj.nearestElement instanceof
|
|
1685
|
+
if (proj.nearestElement instanceof GraphNode) {
|
|
2685
1686
|
return proj.nearestElement;
|
|
2686
1687
|
}
|
|
2687
|
-
const
|
|
1688
|
+
const nodeCreated = this.createNodeInsideEdge(
|
|
2688
1689
|
proj.nearestElement,
|
|
2689
1690
|
proj.coords
|
|
2690
1691
|
);
|
|
2691
|
-
|
|
2692
|
-
return
|
|
1692
|
+
createdNodes.push(nodeCreated);
|
|
1693
|
+
return nodeCreated;
|
|
2693
1694
|
};
|
|
2694
|
-
const
|
|
2695
|
-
while (
|
|
2696
|
-
this.
|
|
1695
|
+
const removeCreatedNodes = () => {
|
|
1696
|
+
while (createdNodes.length) {
|
|
1697
|
+
this.removeNodeFromPreviouslyCreatedEdge(createdNodes.pop());
|
|
2697
1698
|
}
|
|
2698
1699
|
};
|
|
2699
|
-
const
|
|
2700
|
-
const
|
|
2701
|
-
const startCoords = start instanceof
|
|
2702
|
-
const endCoords = end instanceof
|
|
1700
|
+
const startNode = retrieveOrCreateNearestNode(start);
|
|
1701
|
+
const endNode = retrieveOrCreateNearestNode(end);
|
|
1702
|
+
const startCoords = start instanceof GraphNode ? start.coords : start;
|
|
1703
|
+
const endCoords = end instanceof GraphNode ? end.coords : end;
|
|
2703
1704
|
let graphItinerary;
|
|
2704
|
-
if (
|
|
2705
|
-
graphItinerary =
|
|
1705
|
+
if (startNode === endNode) {
|
|
1706
|
+
graphItinerary = GraphItinerary.fromNetworkNodes(
|
|
2706
1707
|
startCoords,
|
|
2707
1708
|
endCoords,
|
|
2708
|
-
[
|
|
1709
|
+
[startNode],
|
|
2709
1710
|
[]
|
|
2710
1711
|
);
|
|
2711
1712
|
} else {
|
|
2712
|
-
graphItinerary = this.
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
1713
|
+
graphItinerary = this.getShortestPathBetweenGraphNodes(
|
|
1714
|
+
startNode,
|
|
1715
|
+
endNode,
|
|
1716
|
+
acceptEdgeFn,
|
|
1717
|
+
weightEdgeFn
|
|
2717
1718
|
);
|
|
2718
1719
|
}
|
|
2719
1720
|
graphItinerary.start = startCoords;
|
|
2720
1721
|
graphItinerary.end = endCoords;
|
|
2721
|
-
|
|
2722
|
-
if (!graphItinerary.
|
|
1722
|
+
removeCreatedNodes();
|
|
1723
|
+
if (!graphItinerary.nodes.length) {
|
|
2723
1724
|
throw new NoRouteFoundError(start, end);
|
|
2724
1725
|
}
|
|
2725
1726
|
return graphItinerary;
|
|
2726
1727
|
}
|
|
2727
|
-
|
|
2728
|
-
const a = edge.
|
|
2729
|
-
const b = edge.
|
|
2730
|
-
const m = new
|
|
2731
|
-
|
|
2732
|
-
const u =
|
|
2733
|
-
|
|
1728
|
+
createNodeInsideEdge(edge, point) {
|
|
1729
|
+
const a = edge.node1;
|
|
1730
|
+
const b = edge.node2;
|
|
1731
|
+
const m = new GraphNode(point, null);
|
|
1732
|
+
m.coords.level = edge.level;
|
|
1733
|
+
const u = edge.clone();
|
|
1734
|
+
u.node1 = a;
|
|
1735
|
+
u.node2 = m;
|
|
1736
|
+
const v = edge.clone();
|
|
1737
|
+
v.node1 = m;
|
|
1738
|
+
v.node2 = b;
|
|
2734
1739
|
a.edges = a.edges.filter((_edge) => _edge !== edge);
|
|
2735
1740
|
b.edges = b.edges.filter((_edge) => _edge !== edge);
|
|
2736
|
-
this.
|
|
2737
|
-
this.
|
|
2738
|
-
this.
|
|
1741
|
+
this._network.nodes.push(m);
|
|
1742
|
+
this._network.edges.push(u, v);
|
|
1743
|
+
this._network.edges = this._network.edges.filter(
|
|
2739
1744
|
(_edge) => _edge !== edge
|
|
2740
1745
|
);
|
|
2741
1746
|
return m;
|
|
2742
1747
|
}
|
|
2743
|
-
|
|
2744
|
-
const u =
|
|
2745
|
-
const v =
|
|
2746
|
-
u.
|
|
2747
|
-
v.
|
|
2748
|
-
const
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
this.
|
|
2752
|
-
this.
|
|
2753
|
-
this.
|
|
1748
|
+
removeNodeFromPreviouslyCreatedEdge(_node) {
|
|
1749
|
+
const u = _node.edges[0];
|
|
1750
|
+
const v = _node.edges[1];
|
|
1751
|
+
u.node1.edges = u.node1.edges.filter((edge) => edge !== u);
|
|
1752
|
+
v.node1.edges = v.node1.edges.filter((edge) => edge !== v);
|
|
1753
|
+
const oldEdge = u.clone();
|
|
1754
|
+
oldEdge.node1 = u.node1;
|
|
1755
|
+
oldEdge.node2 = v.node2;
|
|
1756
|
+
this._network.edges.push(oldEdge);
|
|
1757
|
+
this._network.nodes = this._network.nodes.filter((node) => node !== _node);
|
|
1758
|
+
this._network.edges = this._network.edges.filter(
|
|
2754
1759
|
(edge) => edge !== u && edge !== v
|
|
2755
1760
|
);
|
|
2756
1761
|
}
|
|
2757
|
-
|
|
2758
|
-
const distanceMap = {}, checking = {}, vertexList = {},
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
1762
|
+
getShortestPathBetweenGraphNodes(start, end, acceptEdgeFn, weightFn) {
|
|
1763
|
+
const distanceMap = {}, checking = {}, vertexList = {}, vertexNodes = {}, parentVertices = {}, path = [];
|
|
1764
|
+
let vertexId = 1;
|
|
1765
|
+
this._network.nodes.forEach((vertex) => {
|
|
1766
|
+
vertex.uniqueRouterId = vertexId;
|
|
1767
|
+
vertexNodes[vertexId] = vertex;
|
|
1768
|
+
distanceMap[vertexId] = Infinity;
|
|
1769
|
+
checking[vertexId] = null;
|
|
1770
|
+
vertexList[vertexId] = true;
|
|
1771
|
+
vertexId++;
|
|
2764
1772
|
});
|
|
2765
|
-
|
|
1773
|
+
const startVertex = Object.values(vertexNodes).find((vertex) => start.equals(vertex));
|
|
1774
|
+
const endVertex = Object.values(vertexNodes).find((vertex) => end.equals(vertex));
|
|
1775
|
+
distanceMap[startVertex.uniqueRouterId] = 0;
|
|
2766
1776
|
while (Object.keys(vertexList).length > 0) {
|
|
2767
1777
|
const keys = Object.keys(vertexList).map(Number);
|
|
2768
1778
|
const current = Number(
|
|
2769
|
-
keys.reduce((_checking,
|
|
2770
|
-
return distanceMap[_checking] > distanceMap[
|
|
1779
|
+
keys.reduce((_checking, vertexId2) => {
|
|
1780
|
+
return distanceMap[_checking] > distanceMap[vertexId2] ? vertexId2 : _checking;
|
|
2771
1781
|
}, keys[0])
|
|
2772
1782
|
);
|
|
2773
|
-
this.
|
|
2774
|
-
if (
|
|
1783
|
+
this._network.edges.filter((edge) => {
|
|
1784
|
+
if (!acceptEdgeFn(edge) || this.disabledEdges.has(edge)) {
|
|
2775
1785
|
return false;
|
|
2776
1786
|
}
|
|
2777
|
-
const from = edge.
|
|
1787
|
+
const from = edge.node1.uniqueRouterId, to = edge.node2.uniqueRouterId;
|
|
2778
1788
|
return from === current || to === current;
|
|
2779
1789
|
}).forEach((edge) => {
|
|
2780
1790
|
let to, from, reversed = false;
|
|
2781
|
-
if (edge.
|
|
2782
|
-
to = edge.
|
|
2783
|
-
from = edge.
|
|
1791
|
+
if (edge.node1.uniqueRouterId === current) {
|
|
1792
|
+
to = edge.node2.uniqueRouterId;
|
|
1793
|
+
from = edge.node1.uniqueRouterId;
|
|
2784
1794
|
} else {
|
|
2785
|
-
to = edge.
|
|
2786
|
-
from = edge.
|
|
1795
|
+
to = edge.node1.uniqueRouterId;
|
|
1796
|
+
from = edge.node2.uniqueRouterId;
|
|
2787
1797
|
reversed = true;
|
|
2788
1798
|
}
|
|
2789
1799
|
if (edge.isOneway && reversed) {
|
|
@@ -2799,34 +1809,38 @@ class GeoGraphRouter {
|
|
|
2799
1809
|
delete vertexList[current];
|
|
2800
1810
|
}
|
|
2801
1811
|
const edgesWeights = [];
|
|
2802
|
-
let endId =
|
|
2803
|
-
while (
|
|
2804
|
-
path.unshift(
|
|
1812
|
+
let endId = endVertex.uniqueRouterId;
|
|
1813
|
+
while (parentVertices[endId]) {
|
|
1814
|
+
path.unshift(vertexNodes[endId]);
|
|
2805
1815
|
edgesWeights.unshift(distanceMap[endId] - distanceMap[parentVertices[endId]]);
|
|
2806
1816
|
endId = parentVertices[endId];
|
|
2807
1817
|
}
|
|
2808
1818
|
if (path.length !== 0) {
|
|
2809
1819
|
path.unshift(start);
|
|
2810
1820
|
}
|
|
2811
|
-
|
|
1821
|
+
this._network.nodes.forEach((vertex) => {
|
|
1822
|
+
delete vertex.uniqueRouterId;
|
|
1823
|
+
});
|
|
1824
|
+
return GraphItinerary.fromNetworkNodes(start.coords, end.coords, path, edgesWeights);
|
|
2812
1825
|
}
|
|
2813
1826
|
}
|
|
2814
|
-
__publicField(GeoGraphRouter, "DEFAULT_OPTIONS", DEFAULT_OPTIONS);
|
|
2815
1827
|
exports.AbsoluteHeading = AbsoluteHeading;
|
|
2816
1828
|
exports.Attitude = Attitude;
|
|
2817
1829
|
exports.BoundingBox = BoundingBox;
|
|
2818
1830
|
exports.Constants = Constants;
|
|
2819
1831
|
exports.Coordinates = Coordinates;
|
|
2820
|
-
exports.GeoGraph = GeoGraph;
|
|
2821
|
-
exports.GeoGraphEdge = GeoGraphEdge;
|
|
2822
|
-
exports.GeoGraphItinerary = GeoGraphItinerary;
|
|
2823
|
-
exports.GeoGraphProjection = GeoGraphProjection;
|
|
2824
|
-
exports.GeoGraphProjectionHandler = GeoGraphProjectionHandler;
|
|
2825
|
-
exports.GeoGraphRouter = GeoGraphRouter;
|
|
2826
|
-
exports.GeoGraphVertex = GeoGraphVertex;
|
|
2827
1832
|
exports.GeoRef = GeoRef;
|
|
2828
1833
|
exports.GeoRelativePosition = GeoRelativePosition;
|
|
1834
|
+
exports.GraphEdge = GraphEdge;
|
|
1835
|
+
exports.GraphItinerary = GraphItinerary;
|
|
1836
|
+
exports.GraphNode = GraphNode;
|
|
1837
|
+
exports.GraphProjection = GraphProjection;
|
|
1838
|
+
exports.GraphRouter = GraphRouter;
|
|
1839
|
+
exports.GraphRouterOptions = GraphRouterOptions;
|
|
1840
|
+
exports.GraphUtils = GraphUtils;
|
|
2829
1841
|
exports.Level = Level;
|
|
1842
|
+
exports.MapMatching = MapMatching;
|
|
1843
|
+
exports.Network = Network;
|
|
2830
1844
|
exports.NoRouteFoundError = NoRouteFoundError;
|
|
2831
1845
|
exports.RelativePosition = RelativePosition;
|
|
2832
1846
|
exports.UserPosition = UserPosition;
|