@fleet-frontend/mower-maps 0.0.6 → 0.0.8
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/config/constants.d.ts +4 -3
- package/dist/config/constants.d.ts.map +1 -1
- package/dist/config/index.d.ts +0 -18
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/styles.d.ts +17 -15
- package/dist/config/styles.d.ts.map +1 -1
- package/dist/index.esm.js +2717 -522
- package/dist/index.js +2719 -524
- package/dist/processor/MapDataProcessor.d.ts +3 -2
- package/dist/processor/MapDataProcessor.d.ts.map +1 -1
- package/dist/processor/PathDataProcessor.d.ts +3 -2
- package/dist/processor/PathDataProcessor.d.ts.map +1 -1
- package/dist/processor/builder/AntennaDataBuilder.d.ts +2 -2
- package/dist/processor/builder/AntennaDataBuilder.d.ts.map +1 -1
- package/dist/processor/builder/BoundaryDataBuilder.d.ts +4 -3
- package/dist/processor/builder/BoundaryDataBuilder.d.ts.map +1 -1
- package/dist/processor/builder/ChannelDataBuilder.d.ts +5 -33
- package/dist/processor/builder/ChannelDataBuilder.d.ts.map +1 -1
- package/dist/processor/builder/ChargingPileDataBuilder.d.ts +4 -4
- package/dist/processor/builder/ChargingPileDataBuilder.d.ts.map +1 -1
- package/dist/processor/builder/ObstacleDataBuilder.d.ts +2 -2
- package/dist/processor/builder/ObstacleDataBuilder.d.ts.map +1 -1
- package/dist/processor/builder/PathDataBuilder.d.ts.map +1 -1
- package/dist/processor/builder/SvgElementDataBuilder.d.ts +2 -2
- package/dist/processor/builder/SvgElementDataBuilder.d.ts.map +1 -1
- package/dist/processor/builder/VisionOffDataBuilder.d.ts +2 -2
- package/dist/processor/builder/VisionOffDataBuilder.d.ts.map +1 -1
- package/dist/render/BoundaryLabelsManager.d.ts +2 -5
- package/dist/render/BoundaryLabelsManager.d.ts.map +1 -1
- package/dist/render/ChargingPileManager.d.ts.map +1 -1
- package/dist/render/MowerMapOverlay.d.ts +1 -3
- package/dist/render/MowerMapOverlay.d.ts.map +1 -1
- package/dist/render/MowerMapRenderer.d.ts.map +1 -1
- package/dist/render/layers/BoundaryLayer.d.ts.map +1 -1
- package/dist/render/layers/ChannelLayer.d.ts +6 -0
- package/dist/render/layers/ChannelLayer.d.ts.map +1 -1
- package/dist/render/layers/DrawLayer.d.ts +1 -1
- package/dist/render/layers/DrawLayer.d.ts.map +1 -1
- package/dist/render/layers/SvgElementLayer.d.ts.map +1 -1
- package/dist/render/layers/VisionOffLayer.d.ts.map +1 -1
- package/dist/render/layers/types.d.ts +3 -45
- package/dist/render/layers/types.d.ts.map +1 -1
- package/dist/types/renderer.d.ts +44 -15
- package/dist/types/renderer.d.ts.map +1 -1
- package/dist/utils/handleRealTime.d.ts.map +1 -1
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/sleep.d.ts +2 -0
- package/dist/utils/sleep.d.ts.map +1 -0
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
2
|
import React, { forwardRef, useRef, useState, useMemo, useEffect, useImperativeHandle } from 'react';
|
|
3
|
-
import { round, floor } from 'lodash-es';
|
|
4
3
|
|
|
5
4
|
/**
|
|
6
5
|
* SVG基础MapView
|
|
@@ -602,8 +601,8 @@ const createStoreImpl = (createState) => {
|
|
|
602
601
|
};
|
|
603
602
|
const createStore = (createState) => createState ? createStoreImpl(createState) : createStoreImpl;
|
|
604
603
|
|
|
605
|
-
const identity = (arg) => arg;
|
|
606
|
-
function useStore(api, selector = identity) {
|
|
604
|
+
const identity$1 = (arg) => arg;
|
|
605
|
+
function useStore(api, selector = identity$1) {
|
|
607
606
|
const slice = React.useSyncExternalStore(
|
|
608
607
|
api.subscribe,
|
|
609
608
|
() => selector(api.getState()),
|
|
@@ -654,19 +653,20 @@ const SCALE_FACTOR = 50; // 50像素/米
|
|
|
654
653
|
* 默认线宽设置
|
|
655
654
|
*/
|
|
656
655
|
const DEFAULT_LINE_WIDTHS = {
|
|
657
|
-
BOUNDARY: 2,
|
|
658
656
|
OBSTACLE: 2,
|
|
659
657
|
CHARGING_PILE: 2,
|
|
660
|
-
|
|
658
|
+
CHANNEL: 2,
|
|
659
|
+
PATH: 20,
|
|
661
660
|
VISION_OFF_AREA: 2,
|
|
662
|
-
TIME_LIMIT_OBSTACLE:
|
|
661
|
+
TIME_LIMIT_OBSTACLE: 1,
|
|
663
662
|
};
|
|
664
663
|
/**
|
|
665
664
|
* 默认透明度设置
|
|
666
665
|
*/
|
|
667
666
|
const DEFAULT_OPACITIES = {
|
|
668
667
|
FULL: 1.0,
|
|
669
|
-
HIGH: 0.
|
|
668
|
+
HIGH: 0.7,
|
|
669
|
+
LOW: 0.4};
|
|
670
670
|
/**
|
|
671
671
|
* 默认半径设置
|
|
672
672
|
*/
|
|
@@ -769,6 +769,12 @@ class ChannelLayer extends BaseLayer {
|
|
|
769
769
|
this.scale = 1;
|
|
770
770
|
this.type = LAYER_DEFAULT_TYPE.CHANNEL;
|
|
771
771
|
}
|
|
772
|
+
/**
|
|
773
|
+
* 获取元素
|
|
774
|
+
*/
|
|
775
|
+
getElements() {
|
|
776
|
+
return this.elements;
|
|
777
|
+
}
|
|
772
778
|
/**
|
|
773
779
|
* SVG渲染方法
|
|
774
780
|
*/
|
|
@@ -861,9 +867,9 @@ class ChannelLayer extends BaseLayer {
|
|
|
861
867
|
for (let i = 1; i < coordinates.length; i++) {
|
|
862
868
|
pathData += ` L ${coordinates[i][0]} ${coordinates[i][1]}`;
|
|
863
869
|
}
|
|
864
|
-
const topLineWidth = dp2px(
|
|
865
|
-
const bottomLineWidth = dp2px(
|
|
866
|
-
const dashLength = dp2px(
|
|
870
|
+
const topLineWidth = dp2px(style.lineWidth).toString();
|
|
871
|
+
const bottomLineWidth = dp2px(style.bottomLineWidth).toString();
|
|
872
|
+
const dashLength = dp2px(style.lineWidth);
|
|
867
873
|
// 1. 创建底层path(宽度20,boundaryBorder颜色)
|
|
868
874
|
const bottomPath = document.createElementNS('http://www.w3.org/2000/svg', 'path');
|
|
869
875
|
bottomPath.setAttribute('d', pathData);
|
|
@@ -893,16 +899,8 @@ class ChannelLayer extends BaseLayer {
|
|
|
893
899
|
topPath.style.clipPath = `url(#${clipPathIdsMap[element.originalData?.id.toString()]})`;
|
|
894
900
|
}
|
|
895
901
|
// 支持两种虚线格式:lineDash数组和strokeDasharray字符串
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
}
|
|
899
|
-
else if (style.strokeDasharray) {
|
|
900
|
-
topPath.setAttribute('stroke-dasharray', style.strokeDasharray);
|
|
901
|
-
}
|
|
902
|
-
else {
|
|
903
|
-
// 默认虚线样式
|
|
904
|
-
topPath.setAttribute('stroke-dasharray', `${dashLength * 2}, ${dashLength}`);
|
|
905
|
-
}
|
|
902
|
+
// 默认虚线样式
|
|
903
|
+
topPath.setAttribute('stroke-dasharray', `${dashLength * 2}, ${dashLength}`);
|
|
906
904
|
topPath.classList.add('vector-path-top');
|
|
907
905
|
svgGroup.appendChild(topPath);
|
|
908
906
|
}
|
|
@@ -942,9 +940,9 @@ class PathLayer extends BaseLayer {
|
|
|
942
940
|
Object.values(subBoundaryBorder).forEach((item) => {
|
|
943
941
|
const bCoords = item.coordinates;
|
|
944
942
|
if (bCoords.length >= 3) {
|
|
945
|
-
d += `M ${
|
|
943
|
+
d += `M ${bCoords[0][0]} ${bCoords[0][1]}`;
|
|
946
944
|
for (let i = 1; i < bCoords.length; i++) {
|
|
947
|
-
d += ` L ${
|
|
945
|
+
d += ` L ${bCoords[i][0]} ${bCoords[i][1]}`;
|
|
948
946
|
}
|
|
949
947
|
d += ' Z ';
|
|
950
948
|
}
|
|
@@ -989,9 +987,9 @@ class PathLayer extends BaseLayer {
|
|
|
989
987
|
return;
|
|
990
988
|
const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
|
|
991
989
|
// 构建路径数据
|
|
992
|
-
let pathData = `M ${
|
|
990
|
+
let pathData = `M ${coordinates[0][0]} ${coordinates[0][1]}`;
|
|
993
991
|
for (let i = 1; i < coordinates.length; i++) {
|
|
994
|
-
pathData += ` L ${
|
|
992
|
+
pathData += ` L ${coordinates[i][0]} ${coordinates[i][1]}`;
|
|
995
993
|
}
|
|
996
994
|
path.style.mixBlendMode = 'normal';
|
|
997
995
|
// 设置路径属性
|
|
@@ -1059,7 +1057,7 @@ class BoundaryLayer extends BaseLayer {
|
|
|
1059
1057
|
const polygon = document.createElementNS('http://www.w3.org/2000/svg', 'polygon');
|
|
1060
1058
|
// 构建点集合,使用整数坐标(只取x,y坐标)
|
|
1061
1059
|
const points = coordinates
|
|
1062
|
-
.map((coord) => `${
|
|
1060
|
+
.map((coord) => `${coord[0]},${coord[1]}`)
|
|
1063
1061
|
.join(' ');
|
|
1064
1062
|
const fillColor = style.fillColor;
|
|
1065
1063
|
polygon.setAttribute('points', points);
|
|
@@ -1105,11 +1103,11 @@ class ObstacleLayer extends BaseLayer {
|
|
|
1105
1103
|
const polygon = document.createElementNS('http://www.w3.org/2000/svg', 'polygon');
|
|
1106
1104
|
// 构建点集合,使用整数坐标
|
|
1107
1105
|
const points = coordinates
|
|
1108
|
-
.map((coord) => `${
|
|
1106
|
+
.map((coord) => `${coord[0]},${coord[1]}`)
|
|
1109
1107
|
.join(' ');
|
|
1110
1108
|
polygon.setAttribute('points', points);
|
|
1111
1109
|
polygon.setAttribute('fill', style.fillColor || 'rgba(220, 53, 69, 0.2)');
|
|
1112
|
-
polygon.setAttribute('stroke', style.
|
|
1110
|
+
polygon.setAttribute('stroke', style.lineColor || '#dc3545');
|
|
1113
1111
|
// 确保最小线条宽度
|
|
1114
1112
|
const lineWidth = Math.max(style.lineWidth || 2, 0.5);
|
|
1115
1113
|
polygon.setAttribute('stroke-width', lineWidth.toString());
|
|
@@ -1163,8 +1161,8 @@ class ChargingPileLayer extends BaseLayer {
|
|
|
1163
1161
|
const rotationDegree = 270 - angle; // 坐标系转换
|
|
1164
1162
|
const image = document.createElementNS('http://www.w3.org/2000/svg', 'image');
|
|
1165
1163
|
// 图片居中定位
|
|
1166
|
-
const x =
|
|
1167
|
-
const y =
|
|
1164
|
+
const x = center[0];
|
|
1165
|
+
const y = center[1];
|
|
1168
1166
|
image.setAttribute('x', x.toString());
|
|
1169
1167
|
image.setAttribute('y', y.toString());
|
|
1170
1168
|
image.setAttribute('width', `${size}px`);
|
|
@@ -1234,8 +1232,8 @@ class PointLayer extends BaseLayer {
|
|
|
1234
1232
|
const coordinate = coordinates[0];
|
|
1235
1233
|
const radius = style.radius || 4;
|
|
1236
1234
|
const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
|
|
1237
|
-
circle.setAttribute('cx',
|
|
1238
|
-
circle.setAttribute('cy',
|
|
1235
|
+
circle.setAttribute('cx', coordinate[0].toString());
|
|
1236
|
+
circle.setAttribute('cy', coordinate[1].toString());
|
|
1239
1237
|
circle.setAttribute('r', radius.toString());
|
|
1240
1238
|
circle.setAttribute('fill', style.fillColor || style.strokeColor || '#000000');
|
|
1241
1239
|
circle.setAttribute('stroke', style.strokeColor || '#000000');
|
|
@@ -1299,31 +1297,31 @@ class SvgElementLayer extends BaseLayer {
|
|
|
1299
1297
|
const svgElement = svgDoc.documentElement;
|
|
1300
1298
|
if (svgElement.tagName === 'svg') {
|
|
1301
1299
|
// 获取原始SVG尺寸
|
|
1302
|
-
const
|
|
1303
|
-
const
|
|
1300
|
+
const originalWidth = parseFloat(svgElement.getAttribute('width') || '139');
|
|
1301
|
+
const originalHeight = parseFloat(svgElement.getAttribute('height') || '138');
|
|
1304
1302
|
// 计算变换参数
|
|
1305
1303
|
const userScale = metadata.scale || 1;
|
|
1306
1304
|
const direction = metadata.direction || 0;
|
|
1305
|
+
// 设置原始SVG的实际尺寸(限制大小)
|
|
1306
|
+
svgElement.setAttribute('width', originalWidth.toString());
|
|
1307
|
+
svgElement.setAttribute('height', originalHeight.toString());
|
|
1307
1308
|
// 创建变换组
|
|
1308
1309
|
const transformGroup = document.createElementNS('http://www.w3.org/2000/svg', 'g');
|
|
1309
|
-
//
|
|
1310
|
+
// 在transformGroup上应用变换:平移到中心,旋转,缩放,然后居中SVG
|
|
1310
1311
|
const transform = [
|
|
1311
1312
|
`translate(${center[0]}, ${center[1]})`,
|
|
1312
1313
|
`rotate(${(direction * 180) / Math.PI})`,
|
|
1313
1314
|
`scale(${userScale})`,
|
|
1314
|
-
`translate(${-
|
|
1315
|
+
`translate(${-originalWidth / 2}, ${-originalHeight / 2})`,
|
|
1315
1316
|
].join(' ');
|
|
1316
1317
|
transformGroup.setAttribute('transform', transform);
|
|
1317
|
-
// 复制SVG内容
|
|
1318
|
-
while (svgElement.firstChild) {
|
|
1319
|
-
const child = svgElement.firstChild;
|
|
1320
|
-
svgElement.removeChild(child);
|
|
1321
|
-
transformGroup.appendChild(child);
|
|
1322
|
-
}
|
|
1323
1318
|
// 设置样式
|
|
1324
1319
|
if (style.opacity !== undefined) {
|
|
1325
1320
|
transformGroup.setAttribute('opacity', style.opacity.toString());
|
|
1326
1321
|
}
|
|
1322
|
+
// 将限制好尺寸的原始SVG添加到transformGroup中
|
|
1323
|
+
transformGroup.appendChild(svgElement);
|
|
1324
|
+
// 将transformGroup添加到svgGroup中
|
|
1327
1325
|
svgGroup.appendChild(transformGroup);
|
|
1328
1326
|
}
|
|
1329
1327
|
else {
|
|
@@ -1341,14 +1339,15 @@ class SvgElementLayer extends BaseLayer {
|
|
|
1341
1339
|
renderSvgPlaceholder(svgGroup, center, metadata, style) {
|
|
1342
1340
|
const size = (metadata?.scale || 1) * 20;
|
|
1343
1341
|
const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
|
|
1344
|
-
|
|
1345
|
-
rect.setAttribute('
|
|
1342
|
+
console.log('style==', style);
|
|
1343
|
+
rect.setAttribute('x', ((center[0] - size / 2) / 50).toString());
|
|
1344
|
+
rect.setAttribute('y', ((center[1] - size / 2) / 50).toString());
|
|
1346
1345
|
rect.setAttribute('width', size.toString());
|
|
1347
1346
|
rect.setAttribute('height', size.toString());
|
|
1348
|
-
rect.setAttribute('fill', style.fillColor
|
|
1349
|
-
rect.setAttribute('stroke', style.
|
|
1350
|
-
rect.setAttribute('stroke-width',
|
|
1351
|
-
rect.setAttribute('opacity',
|
|
1347
|
+
rect.setAttribute('fill', style.fillColor);
|
|
1348
|
+
rect.setAttribute('stroke', style.lineColor);
|
|
1349
|
+
rect.setAttribute('stroke-width', style.lineWidth.toString());
|
|
1350
|
+
rect.setAttribute('opacity', style.opacity.toString());
|
|
1352
1351
|
svgGroup.appendChild(rect);
|
|
1353
1352
|
}
|
|
1354
1353
|
}
|
|
@@ -1387,12 +1386,12 @@ class VisionOffLayer extends BaseLayer {
|
|
|
1387
1386
|
const polygon = document.createElementNS('http://www.w3.org/2000/svg', 'polygon');
|
|
1388
1387
|
// 构建点集合,使用整数坐标
|
|
1389
1388
|
const points = coordinates
|
|
1390
|
-
.map((coord) => `${
|
|
1389
|
+
.map((coord) => `${coord[0]},${coord[1]}`)
|
|
1391
1390
|
.join(' ');
|
|
1392
1391
|
const fillColor = style.fillColor || 'rgba(0, 255, 0, 0.4)';
|
|
1393
1392
|
polygon.setAttribute('points', points);
|
|
1394
1393
|
polygon.setAttribute('fill', fillColor);
|
|
1395
|
-
polygon.setAttribute('stroke', style.
|
|
1394
|
+
polygon.setAttribute('stroke', style.lineColor);
|
|
1396
1395
|
// 确保最小线条宽度
|
|
1397
1396
|
const lineWidth = Math.max(style.lineWidth || 2, 0.5);
|
|
1398
1397
|
polygon.setAttribute('stroke-width', lineWidth.toString());
|
|
@@ -1409,66 +1408,65 @@ class VisionOffLayer extends BaseLayer {
|
|
|
1409
1408
|
* 边界相关样式配置
|
|
1410
1409
|
*/
|
|
1411
1410
|
const BOUNDARY_STYLES = {
|
|
1412
|
-
|
|
1411
|
+
lineColor: '#ffffff',
|
|
1413
1412
|
fillColor: 'rgba(239, 255, 237, 0.15)', // 更鲜艳的绿色半透明填充,增强可见性
|
|
1414
1413
|
lineWidth: 2,
|
|
1415
|
-
opacity: DEFAULT_OPACITIES.FULL
|
|
1416
|
-
};
|
|
1417
|
-
const BOUNDARY_BORDER_STYLES = {
|
|
1418
|
-
strokeColor: '#ffffff',
|
|
1419
|
-
fillColor: 'rgba(239, 255, 237, 0.15)', // 更鲜艳的绿色半透明填充,增强可见性
|
|
1420
|
-
lineWidth: DEFAULT_LINE_WIDTHS.BOUNDARY,
|
|
1421
|
-
opacity: DEFAULT_OPACITIES.FULL
|
|
1414
|
+
opacity: DEFAULT_OPACITIES.FULL,
|
|
1422
1415
|
};
|
|
1423
1416
|
const VISION_OFF_AREA_STYLES = {
|
|
1424
|
-
|
|
1417
|
+
lineColor: 'rgba(108, 167, 255, 1)',
|
|
1425
1418
|
fillColor: 'rgba(43, 128, 255, 0.45)', // 浅蓝色半透明填充
|
|
1426
1419
|
lineWidth: DEFAULT_LINE_WIDTHS.VISION_OFF_AREA,
|
|
1427
|
-
opacity: DEFAULT_OPACITIES.HIGH
|
|
1420
|
+
opacity: DEFAULT_OPACITIES.HIGH,
|
|
1428
1421
|
};
|
|
1429
1422
|
const OBSTACLE_STYLES = {
|
|
1430
|
-
|
|
1423
|
+
lineColor: 'rgba(255, 122, 51, 1)',
|
|
1431
1424
|
fillColor: 'rgba(255, 113, 51, 0.2)', // 红色半透明填充
|
|
1432
1425
|
lineWidth: DEFAULT_LINE_WIDTHS.OBSTACLE,
|
|
1433
|
-
opacity: DEFAULT_OPACITIES.FULL
|
|
1426
|
+
opacity: DEFAULT_OPACITIES.FULL,
|
|
1434
1427
|
};
|
|
1435
1428
|
const CHARGING_PILE_STYLES = {
|
|
1436
|
-
|
|
1429
|
+
lineColor: 'blue',
|
|
1437
1430
|
fillColor: 'blue',
|
|
1438
1431
|
lineWidth: DEFAULT_LINE_WIDTHS.CHARGING_PILE,
|
|
1439
1432
|
radius: DEFAULT_RADII.CHARGING_PILE,
|
|
1440
|
-
opacity: DEFAULT_OPACITIES.FULL
|
|
1433
|
+
opacity: DEFAULT_OPACITIES.FULL,
|
|
1441
1434
|
};
|
|
1442
1435
|
const DOODLE_STYLES = {
|
|
1443
|
-
|
|
1444
|
-
fillColor: '
|
|
1436
|
+
lineColor: '#ff5722',
|
|
1437
|
+
fillColor: '#ff9800', // 粉色半透明填充
|
|
1445
1438
|
lineWidth: DEFAULT_LINE_WIDTHS.TIME_LIMIT_OBSTACLE,
|
|
1446
|
-
opacity: DEFAULT_OPACITIES.HIGH
|
|
1439
|
+
opacity: DEFAULT_OPACITIES.HIGH,
|
|
1447
1440
|
};
|
|
1448
1441
|
const PATH_EDGE_STYLES = {
|
|
1449
|
-
strokeColor: 'red',
|
|
1450
|
-
lineWidth: DEFAULT_LINE_WIDTHS.PATH};
|
|
1451
|
-
const CHANNEL_STYLES = {
|
|
1452
|
-
strokeColor: 'purple',
|
|
1453
1442
|
lineWidth: DEFAULT_LINE_WIDTHS.PATH,
|
|
1454
|
-
opacity: DEFAULT_OPACITIES.
|
|
1443
|
+
opacity: DEFAULT_OPACITIES.LOW,
|
|
1444
|
+
edgeLineColor: 'rgba(194, 203, 212)',
|
|
1445
|
+
transLineColor: 'transparent',
|
|
1446
|
+
mowingLineColor: 'rgba(194, 203, 212)',
|
|
1447
|
+
};
|
|
1448
|
+
const CHANNEL_STYLES = {
|
|
1449
|
+
lineColor: 'purple',
|
|
1450
|
+
lineWidth: DEFAULT_LINE_WIDTHS.CHANNEL,
|
|
1451
|
+
bottomLineWidth: 20,
|
|
1452
|
+
bottomLineColor: '#8498A9',
|
|
1453
|
+
opacity: DEFAULT_OPACITIES.FULL,
|
|
1455
1454
|
};
|
|
1456
1455
|
const ANTENNA_STYLES = {
|
|
1457
|
-
|
|
1456
|
+
lineColor: 'transparent',
|
|
1458
1457
|
fillColor: 'transparent',
|
|
1459
1458
|
radius: 12, // 默认24px大小
|
|
1460
|
-
opacity: DEFAULT_OPACITIES.FULL
|
|
1459
|
+
opacity: DEFAULT_OPACITIES.FULL,
|
|
1461
1460
|
};
|
|
1462
1461
|
const DEFAULT_STYLES = {
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
ANTENNA: ANTENNA_STYLES
|
|
1462
|
+
boundary: BOUNDARY_STYLES,
|
|
1463
|
+
visionOffArea: VISION_OFF_AREA_STYLES,
|
|
1464
|
+
obstacle: OBSTACLE_STYLES,
|
|
1465
|
+
chargingPile: CHARGING_PILE_STYLES,
|
|
1466
|
+
doodle: DOODLE_STYLES,
|
|
1467
|
+
path: PATH_EDGE_STYLES,
|
|
1468
|
+
channel: CHANNEL_STYLES,
|
|
1469
|
+
antenna: ANTENNA_STYLES,
|
|
1472
1470
|
};
|
|
1473
1471
|
|
|
1474
1472
|
/**
|
|
@@ -2216,18 +2214,20 @@ const handleRealTimeData = ({ realTimeData, isMowing, pathData, partitionBoundar
|
|
|
2216
2214
|
else if (item.type === REAL_TIME_DATA_TYPE.PROCESS) {
|
|
2217
2215
|
// 割草进度
|
|
2218
2216
|
const { mapWorkPosition } = item;
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
newPathData[currentPartitionId]
|
|
2229
|
-
|
|
2230
|
-
|
|
2217
|
+
if (mapWorkPosition) {
|
|
2218
|
+
// 解析mapWorkPosition数据,获取到当前的割草状态,割草进度,割草边界id
|
|
2219
|
+
const { isMowing, currentMowBoundaryId, currentMowProgress } = parseMapWorkPosition(mapWorkPosition);
|
|
2220
|
+
// const { isMowing, currentMowBoundaryId, currentMowProgress } = parseMapWorkPosition(
|
|
2221
|
+
// '000000060000000000000001000000030000001BA5A5A5A5A5A5A5A5240000A024010D50FFFFFFED000000000000000000000000000000010000000000000000'
|
|
2222
|
+
// );
|
|
2223
|
+
console.log('isMowing===', isMowing, currentMowBoundaryId, currentMowProgress);
|
|
2224
|
+
mowingStatus = isMowing;
|
|
2225
|
+
const currentPartitionId = currentMowBoundaryId ? currentMowBoundaryId.toString() : null;
|
|
2226
|
+
if (currentMowProgress && currentPartitionId && newPathData?.[currentPartitionId]) {
|
|
2227
|
+
newPathData[currentPartitionId].partitionPercentage = currentMowProgress / 100;
|
|
2228
|
+
newPathData[currentPartitionId].finishedArea =
|
|
2229
|
+
(newPathData[currentPartitionId].area * currentMowProgress) / 10000;
|
|
2230
|
+
}
|
|
2231
2231
|
}
|
|
2232
2232
|
}
|
|
2233
2233
|
});
|
|
@@ -2279,61 +2279,2486 @@ function getDisabledMowerImageByModal(mowerModal) {
|
|
|
2279
2279
|
}
|
|
2280
2280
|
return iDisabled;
|
|
2281
2281
|
}
|
|
2282
|
-
function getNoPositionMowerImageByModal(mowerModal) {
|
|
2283
|
-
if (mowerModal.includes('i')) {
|
|
2284
|
-
return iNoPosition;
|
|
2285
|
-
}
|
|
2286
|
-
else if (mowerModal.includes('h')) {
|
|
2287
|
-
return hNoPosition;
|
|
2288
|
-
}
|
|
2289
|
-
else if (mowerModal.includes('x3')) {
|
|
2290
|
-
return x3NoPosition;
|
|
2291
|
-
}
|
|
2292
|
-
return iNoPosition;
|
|
2282
|
+
function getNoPositionMowerImageByModal(mowerModal) {
|
|
2283
|
+
if (mowerModal.includes('i')) {
|
|
2284
|
+
return iNoPosition;
|
|
2285
|
+
}
|
|
2286
|
+
else if (mowerModal.includes('h')) {
|
|
2287
|
+
return hNoPosition;
|
|
2288
|
+
}
|
|
2289
|
+
else if (mowerModal.includes('x3')) {
|
|
2290
|
+
return x3NoPosition;
|
|
2291
|
+
}
|
|
2292
|
+
return iNoPosition;
|
|
2293
|
+
}
|
|
2294
|
+
function getMowerImage(positonConfig) {
|
|
2295
|
+
const model = positonConfig.vehicleModel || '';
|
|
2296
|
+
const state = positonConfig.vehicleState;
|
|
2297
|
+
const mowerImage = getMowerImageByModal(model);
|
|
2298
|
+
const disabledImage = getDisabledMowerImageByModal(model);
|
|
2299
|
+
const noPositionImage = getNoPositionMowerImageByModal(model);
|
|
2300
|
+
const positonOutOfRange = isOutOfRange(positonConfig);
|
|
2301
|
+
const positionValid = isInvalidPosition(positonConfig);
|
|
2302
|
+
const isOffLine = state === RobotStatus.DISCONNECTED;
|
|
2303
|
+
if (isOffLine) {
|
|
2304
|
+
return disabledImage;
|
|
2305
|
+
}
|
|
2306
|
+
else if (positionValid || positonOutOfRange) {
|
|
2307
|
+
return noPositionImage;
|
|
2308
|
+
}
|
|
2309
|
+
else {
|
|
2310
|
+
return mowerImage;
|
|
2311
|
+
}
|
|
2312
|
+
}
|
|
2313
|
+
function isNoPosture(posture) {
|
|
2314
|
+
if (posture == null || posture == undefined) {
|
|
2315
|
+
return true;
|
|
2316
|
+
}
|
|
2317
|
+
if (posture == 0) {
|
|
2318
|
+
return true;
|
|
2319
|
+
}
|
|
2320
|
+
else if (posture == -99999) {
|
|
2321
|
+
return true;
|
|
2322
|
+
}
|
|
2323
|
+
return false;
|
|
2324
|
+
}
|
|
2325
|
+
function isInvalidPosition(positonConfig) {
|
|
2326
|
+
return (isNoPosture(positonConfig.postureX) &&
|
|
2327
|
+
isNoPosture(positonConfig.postureY) &&
|
|
2328
|
+
isNoPosture(positonConfig.postureTheta));
|
|
2329
|
+
}
|
|
2330
|
+
function isOutOfRange(positonConfig) {
|
|
2331
|
+
return (positonConfig.postureX != null &&
|
|
2332
|
+
Math.abs(positonConfig.postureX) > 1000 * SCALE_FACTOR &&
|
|
2333
|
+
positonConfig.postureY != null &&
|
|
2334
|
+
Math.abs(positonConfig.postureY) > 1000 * SCALE_FACTOR);
|
|
2335
|
+
}
|
|
2336
|
+
|
|
2337
|
+
/** Detect free variable `global` from Node.js. */
|
|
2338
|
+
var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
|
|
2339
|
+
|
|
2340
|
+
/** Detect free variable `self`. */
|
|
2341
|
+
var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
|
|
2342
|
+
|
|
2343
|
+
/** Used as a reference to the global object. */
|
|
2344
|
+
var root = freeGlobal || freeSelf || Function('return this')();
|
|
2345
|
+
|
|
2346
|
+
/** Built-in value references. */
|
|
2347
|
+
var Symbol = root.Symbol;
|
|
2348
|
+
|
|
2349
|
+
/** Used for built-in method references. */
|
|
2350
|
+
var objectProto$9 = Object.prototype;
|
|
2351
|
+
|
|
2352
|
+
/** Used to check objects for own properties. */
|
|
2353
|
+
var hasOwnProperty$7 = objectProto$9.hasOwnProperty;
|
|
2354
|
+
|
|
2355
|
+
/**
|
|
2356
|
+
* Used to resolve the
|
|
2357
|
+
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
|
|
2358
|
+
* of values.
|
|
2359
|
+
*/
|
|
2360
|
+
var nativeObjectToString$1 = objectProto$9.toString;
|
|
2361
|
+
|
|
2362
|
+
/** Built-in value references. */
|
|
2363
|
+
var symToStringTag$1 = Symbol ? Symbol.toStringTag : undefined;
|
|
2364
|
+
|
|
2365
|
+
/**
|
|
2366
|
+
* A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
|
|
2367
|
+
*
|
|
2368
|
+
* @private
|
|
2369
|
+
* @param {*} value The value to query.
|
|
2370
|
+
* @returns {string} Returns the raw `toStringTag`.
|
|
2371
|
+
*/
|
|
2372
|
+
function getRawTag(value) {
|
|
2373
|
+
var isOwn = hasOwnProperty$7.call(value, symToStringTag$1),
|
|
2374
|
+
tag = value[symToStringTag$1];
|
|
2375
|
+
|
|
2376
|
+
try {
|
|
2377
|
+
value[symToStringTag$1] = undefined;
|
|
2378
|
+
var unmasked = true;
|
|
2379
|
+
} catch (e) {}
|
|
2380
|
+
|
|
2381
|
+
var result = nativeObjectToString$1.call(value);
|
|
2382
|
+
if (unmasked) {
|
|
2383
|
+
if (isOwn) {
|
|
2384
|
+
value[symToStringTag$1] = tag;
|
|
2385
|
+
} else {
|
|
2386
|
+
delete value[symToStringTag$1];
|
|
2387
|
+
}
|
|
2388
|
+
}
|
|
2389
|
+
return result;
|
|
2390
|
+
}
|
|
2391
|
+
|
|
2392
|
+
/** Used for built-in method references. */
|
|
2393
|
+
var objectProto$8 = Object.prototype;
|
|
2394
|
+
|
|
2395
|
+
/**
|
|
2396
|
+
* Used to resolve the
|
|
2397
|
+
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
|
|
2398
|
+
* of values.
|
|
2399
|
+
*/
|
|
2400
|
+
var nativeObjectToString = objectProto$8.toString;
|
|
2401
|
+
|
|
2402
|
+
/**
|
|
2403
|
+
* Converts `value` to a string using `Object.prototype.toString`.
|
|
2404
|
+
*
|
|
2405
|
+
* @private
|
|
2406
|
+
* @param {*} value The value to convert.
|
|
2407
|
+
* @returns {string} Returns the converted string.
|
|
2408
|
+
*/
|
|
2409
|
+
function objectToString(value) {
|
|
2410
|
+
return nativeObjectToString.call(value);
|
|
2411
|
+
}
|
|
2412
|
+
|
|
2413
|
+
/** `Object#toString` result references. */
|
|
2414
|
+
var nullTag = '[object Null]',
|
|
2415
|
+
undefinedTag = '[object Undefined]';
|
|
2416
|
+
|
|
2417
|
+
/** Built-in value references. */
|
|
2418
|
+
var symToStringTag = Symbol ? Symbol.toStringTag : undefined;
|
|
2419
|
+
|
|
2420
|
+
/**
|
|
2421
|
+
* The base implementation of `getTag` without fallbacks for buggy environments.
|
|
2422
|
+
*
|
|
2423
|
+
* @private
|
|
2424
|
+
* @param {*} value The value to query.
|
|
2425
|
+
* @returns {string} Returns the `toStringTag`.
|
|
2426
|
+
*/
|
|
2427
|
+
function baseGetTag(value) {
|
|
2428
|
+
if (value == null) {
|
|
2429
|
+
return value === undefined ? undefinedTag : nullTag;
|
|
2430
|
+
}
|
|
2431
|
+
return (symToStringTag && symToStringTag in Object(value))
|
|
2432
|
+
? getRawTag(value)
|
|
2433
|
+
: objectToString(value);
|
|
2434
|
+
}
|
|
2435
|
+
|
|
2436
|
+
/**
|
|
2437
|
+
* Checks if `value` is object-like. A value is object-like if it's not `null`
|
|
2438
|
+
* and has a `typeof` result of "object".
|
|
2439
|
+
*
|
|
2440
|
+
* @static
|
|
2441
|
+
* @memberOf _
|
|
2442
|
+
* @since 4.0.0
|
|
2443
|
+
* @category Lang
|
|
2444
|
+
* @param {*} value The value to check.
|
|
2445
|
+
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
|
|
2446
|
+
* @example
|
|
2447
|
+
*
|
|
2448
|
+
* _.isObjectLike({});
|
|
2449
|
+
* // => true
|
|
2450
|
+
*
|
|
2451
|
+
* _.isObjectLike([1, 2, 3]);
|
|
2452
|
+
* // => true
|
|
2453
|
+
*
|
|
2454
|
+
* _.isObjectLike(_.noop);
|
|
2455
|
+
* // => false
|
|
2456
|
+
*
|
|
2457
|
+
* _.isObjectLike(null);
|
|
2458
|
+
* // => false
|
|
2459
|
+
*/
|
|
2460
|
+
function isObjectLike(value) {
|
|
2461
|
+
return value != null && typeof value == 'object';
|
|
2462
|
+
}
|
|
2463
|
+
|
|
2464
|
+
/** `Object#toString` result references. */
|
|
2465
|
+
var symbolTag = '[object Symbol]';
|
|
2466
|
+
|
|
2467
|
+
/**
|
|
2468
|
+
* Checks if `value` is classified as a `Symbol` primitive or object.
|
|
2469
|
+
*
|
|
2470
|
+
* @static
|
|
2471
|
+
* @memberOf _
|
|
2472
|
+
* @since 4.0.0
|
|
2473
|
+
* @category Lang
|
|
2474
|
+
* @param {*} value The value to check.
|
|
2475
|
+
* @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
|
|
2476
|
+
* @example
|
|
2477
|
+
*
|
|
2478
|
+
* _.isSymbol(Symbol.iterator);
|
|
2479
|
+
* // => true
|
|
2480
|
+
*
|
|
2481
|
+
* _.isSymbol('abc');
|
|
2482
|
+
* // => false
|
|
2483
|
+
*/
|
|
2484
|
+
function isSymbol(value) {
|
|
2485
|
+
return typeof value == 'symbol' ||
|
|
2486
|
+
(isObjectLike(value) && baseGetTag(value) == symbolTag);
|
|
2487
|
+
}
|
|
2488
|
+
|
|
2489
|
+
/**
|
|
2490
|
+
* A specialized version of `_.map` for arrays without support for iteratee
|
|
2491
|
+
* shorthands.
|
|
2492
|
+
*
|
|
2493
|
+
* @private
|
|
2494
|
+
* @param {Array} [array] The array to iterate over.
|
|
2495
|
+
* @param {Function} iteratee The function invoked per iteration.
|
|
2496
|
+
* @returns {Array} Returns the new mapped array.
|
|
2497
|
+
*/
|
|
2498
|
+
function arrayMap(array, iteratee) {
|
|
2499
|
+
var index = -1,
|
|
2500
|
+
length = array == null ? 0 : array.length,
|
|
2501
|
+
result = Array(length);
|
|
2502
|
+
|
|
2503
|
+
while (++index < length) {
|
|
2504
|
+
result[index] = iteratee(array[index], index, array);
|
|
2505
|
+
}
|
|
2506
|
+
return result;
|
|
2507
|
+
}
|
|
2508
|
+
|
|
2509
|
+
/**
|
|
2510
|
+
* Checks if `value` is classified as an `Array` object.
|
|
2511
|
+
*
|
|
2512
|
+
* @static
|
|
2513
|
+
* @memberOf _
|
|
2514
|
+
* @since 0.1.0
|
|
2515
|
+
* @category Lang
|
|
2516
|
+
* @param {*} value The value to check.
|
|
2517
|
+
* @returns {boolean} Returns `true` if `value` is an array, else `false`.
|
|
2518
|
+
* @example
|
|
2519
|
+
*
|
|
2520
|
+
* _.isArray([1, 2, 3]);
|
|
2521
|
+
* // => true
|
|
2522
|
+
*
|
|
2523
|
+
* _.isArray(document.body.children);
|
|
2524
|
+
* // => false
|
|
2525
|
+
*
|
|
2526
|
+
* _.isArray('abc');
|
|
2527
|
+
* // => false
|
|
2528
|
+
*
|
|
2529
|
+
* _.isArray(_.noop);
|
|
2530
|
+
* // => false
|
|
2531
|
+
*/
|
|
2532
|
+
var isArray = Array.isArray;
|
|
2533
|
+
|
|
2534
|
+
/** Used to convert symbols to primitives and strings. */
|
|
2535
|
+
var symbolProto = Symbol ? Symbol.prototype : undefined,
|
|
2536
|
+
symbolToString = symbolProto ? symbolProto.toString : undefined;
|
|
2537
|
+
|
|
2538
|
+
/**
|
|
2539
|
+
* The base implementation of `_.toString` which doesn't convert nullish
|
|
2540
|
+
* values to empty strings.
|
|
2541
|
+
*
|
|
2542
|
+
* @private
|
|
2543
|
+
* @param {*} value The value to process.
|
|
2544
|
+
* @returns {string} Returns the string.
|
|
2545
|
+
*/
|
|
2546
|
+
function baseToString(value) {
|
|
2547
|
+
// Exit early for strings to avoid a performance hit in some environments.
|
|
2548
|
+
if (typeof value == 'string') {
|
|
2549
|
+
return value;
|
|
2550
|
+
}
|
|
2551
|
+
if (isArray(value)) {
|
|
2552
|
+
// Recursively convert values (susceptible to call stack limits).
|
|
2553
|
+
return arrayMap(value, baseToString) + '';
|
|
2554
|
+
}
|
|
2555
|
+
if (isSymbol(value)) {
|
|
2556
|
+
return symbolToString ? symbolToString.call(value) : '';
|
|
2557
|
+
}
|
|
2558
|
+
var result = (value + '');
|
|
2559
|
+
return (result == '0' && (1 / value) == -Infinity) ? '-0' : result;
|
|
2560
|
+
}
|
|
2561
|
+
|
|
2562
|
+
/** Used to match a single whitespace character. */
|
|
2563
|
+
var reWhitespace = /\s/;
|
|
2564
|
+
|
|
2565
|
+
/**
|
|
2566
|
+
* Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace
|
|
2567
|
+
* character of `string`.
|
|
2568
|
+
*
|
|
2569
|
+
* @private
|
|
2570
|
+
* @param {string} string The string to inspect.
|
|
2571
|
+
* @returns {number} Returns the index of the last non-whitespace character.
|
|
2572
|
+
*/
|
|
2573
|
+
function trimmedEndIndex(string) {
|
|
2574
|
+
var index = string.length;
|
|
2575
|
+
|
|
2576
|
+
while (index-- && reWhitespace.test(string.charAt(index))) {}
|
|
2577
|
+
return index;
|
|
2578
|
+
}
|
|
2579
|
+
|
|
2580
|
+
/** Used to match leading whitespace. */
|
|
2581
|
+
var reTrimStart = /^\s+/;
|
|
2582
|
+
|
|
2583
|
+
/**
|
|
2584
|
+
* The base implementation of `_.trim`.
|
|
2585
|
+
*
|
|
2586
|
+
* @private
|
|
2587
|
+
* @param {string} string The string to trim.
|
|
2588
|
+
* @returns {string} Returns the trimmed string.
|
|
2589
|
+
*/
|
|
2590
|
+
function baseTrim(string) {
|
|
2591
|
+
return string
|
|
2592
|
+
? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, '')
|
|
2593
|
+
: string;
|
|
2594
|
+
}
|
|
2595
|
+
|
|
2596
|
+
/**
|
|
2597
|
+
* Checks if `value` is the
|
|
2598
|
+
* [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
|
|
2599
|
+
* of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
|
|
2600
|
+
*
|
|
2601
|
+
* @static
|
|
2602
|
+
* @memberOf _
|
|
2603
|
+
* @since 0.1.0
|
|
2604
|
+
* @category Lang
|
|
2605
|
+
* @param {*} value The value to check.
|
|
2606
|
+
* @returns {boolean} Returns `true` if `value` is an object, else `false`.
|
|
2607
|
+
* @example
|
|
2608
|
+
*
|
|
2609
|
+
* _.isObject({});
|
|
2610
|
+
* // => true
|
|
2611
|
+
*
|
|
2612
|
+
* _.isObject([1, 2, 3]);
|
|
2613
|
+
* // => true
|
|
2614
|
+
*
|
|
2615
|
+
* _.isObject(_.noop);
|
|
2616
|
+
* // => true
|
|
2617
|
+
*
|
|
2618
|
+
* _.isObject(null);
|
|
2619
|
+
* // => false
|
|
2620
|
+
*/
|
|
2621
|
+
function isObject(value) {
|
|
2622
|
+
var type = typeof value;
|
|
2623
|
+
return value != null && (type == 'object' || type == 'function');
|
|
2624
|
+
}
|
|
2625
|
+
|
|
2626
|
+
/** Used as references for various `Number` constants. */
|
|
2627
|
+
var NAN = 0 / 0;
|
|
2628
|
+
|
|
2629
|
+
/** Used to detect bad signed hexadecimal string values. */
|
|
2630
|
+
var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
|
|
2631
|
+
|
|
2632
|
+
/** Used to detect binary string values. */
|
|
2633
|
+
var reIsBinary = /^0b[01]+$/i;
|
|
2634
|
+
|
|
2635
|
+
/** Used to detect octal string values. */
|
|
2636
|
+
var reIsOctal = /^0o[0-7]+$/i;
|
|
2637
|
+
|
|
2638
|
+
/** Built-in method references without a dependency on `root`. */
|
|
2639
|
+
var freeParseInt = parseInt;
|
|
2640
|
+
|
|
2641
|
+
/**
|
|
2642
|
+
* Converts `value` to a number.
|
|
2643
|
+
*
|
|
2644
|
+
* @static
|
|
2645
|
+
* @memberOf _
|
|
2646
|
+
* @since 4.0.0
|
|
2647
|
+
* @category Lang
|
|
2648
|
+
* @param {*} value The value to process.
|
|
2649
|
+
* @returns {number} Returns the number.
|
|
2650
|
+
* @example
|
|
2651
|
+
*
|
|
2652
|
+
* _.toNumber(3.2);
|
|
2653
|
+
* // => 3.2
|
|
2654
|
+
*
|
|
2655
|
+
* _.toNumber(Number.MIN_VALUE);
|
|
2656
|
+
* // => 5e-324
|
|
2657
|
+
*
|
|
2658
|
+
* _.toNumber(Infinity);
|
|
2659
|
+
* // => Infinity
|
|
2660
|
+
*
|
|
2661
|
+
* _.toNumber('3.2');
|
|
2662
|
+
* // => 3.2
|
|
2663
|
+
*/
|
|
2664
|
+
function toNumber(value) {
|
|
2665
|
+
if (typeof value == 'number') {
|
|
2666
|
+
return value;
|
|
2667
|
+
}
|
|
2668
|
+
if (isSymbol(value)) {
|
|
2669
|
+
return NAN;
|
|
2670
|
+
}
|
|
2671
|
+
if (isObject(value)) {
|
|
2672
|
+
var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
|
|
2673
|
+
value = isObject(other) ? (other + '') : other;
|
|
2674
|
+
}
|
|
2675
|
+
if (typeof value != 'string') {
|
|
2676
|
+
return value === 0 ? value : +value;
|
|
2677
|
+
}
|
|
2678
|
+
value = baseTrim(value);
|
|
2679
|
+
var isBinary = reIsBinary.test(value);
|
|
2680
|
+
return (isBinary || reIsOctal.test(value))
|
|
2681
|
+
? freeParseInt(value.slice(2), isBinary ? 2 : 8)
|
|
2682
|
+
: (reIsBadHex.test(value) ? NAN : +value);
|
|
2683
|
+
}
|
|
2684
|
+
|
|
2685
|
+
/** Used as references for various `Number` constants. */
|
|
2686
|
+
var INFINITY = 1 / 0,
|
|
2687
|
+
MAX_INTEGER = 1.7976931348623157e+308;
|
|
2688
|
+
|
|
2689
|
+
/**
|
|
2690
|
+
* Converts `value` to a finite number.
|
|
2691
|
+
*
|
|
2692
|
+
* @static
|
|
2693
|
+
* @memberOf _
|
|
2694
|
+
* @since 4.12.0
|
|
2695
|
+
* @category Lang
|
|
2696
|
+
* @param {*} value The value to convert.
|
|
2697
|
+
* @returns {number} Returns the converted number.
|
|
2698
|
+
* @example
|
|
2699
|
+
*
|
|
2700
|
+
* _.toFinite(3.2);
|
|
2701
|
+
* // => 3.2
|
|
2702
|
+
*
|
|
2703
|
+
* _.toFinite(Number.MIN_VALUE);
|
|
2704
|
+
* // => 5e-324
|
|
2705
|
+
*
|
|
2706
|
+
* _.toFinite(Infinity);
|
|
2707
|
+
* // => 1.7976931348623157e+308
|
|
2708
|
+
*
|
|
2709
|
+
* _.toFinite('3.2');
|
|
2710
|
+
* // => 3.2
|
|
2711
|
+
*/
|
|
2712
|
+
function toFinite(value) {
|
|
2713
|
+
if (!value) {
|
|
2714
|
+
return value === 0 ? value : 0;
|
|
2715
|
+
}
|
|
2716
|
+
value = toNumber(value);
|
|
2717
|
+
if (value === INFINITY || value === -INFINITY) {
|
|
2718
|
+
var sign = (value < 0 ? -1 : 1);
|
|
2719
|
+
return sign * MAX_INTEGER;
|
|
2720
|
+
}
|
|
2721
|
+
return value === value ? value : 0;
|
|
2722
|
+
}
|
|
2723
|
+
|
|
2724
|
+
/**
|
|
2725
|
+
* Converts `value` to an integer.
|
|
2726
|
+
*
|
|
2727
|
+
* **Note:** This method is loosely based on
|
|
2728
|
+
* [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).
|
|
2729
|
+
*
|
|
2730
|
+
* @static
|
|
2731
|
+
* @memberOf _
|
|
2732
|
+
* @since 4.0.0
|
|
2733
|
+
* @category Lang
|
|
2734
|
+
* @param {*} value The value to convert.
|
|
2735
|
+
* @returns {number} Returns the converted integer.
|
|
2736
|
+
* @example
|
|
2737
|
+
*
|
|
2738
|
+
* _.toInteger(3.2);
|
|
2739
|
+
* // => 3
|
|
2740
|
+
*
|
|
2741
|
+
* _.toInteger(Number.MIN_VALUE);
|
|
2742
|
+
* // => 0
|
|
2743
|
+
*
|
|
2744
|
+
* _.toInteger(Infinity);
|
|
2745
|
+
* // => 1.7976931348623157e+308
|
|
2746
|
+
*
|
|
2747
|
+
* _.toInteger('3.2');
|
|
2748
|
+
* // => 3
|
|
2749
|
+
*/
|
|
2750
|
+
function toInteger(value) {
|
|
2751
|
+
var result = toFinite(value),
|
|
2752
|
+
remainder = result % 1;
|
|
2753
|
+
|
|
2754
|
+
return result === result ? (remainder ? result - remainder : result) : 0;
|
|
2755
|
+
}
|
|
2756
|
+
|
|
2757
|
+
/**
|
|
2758
|
+
* This method returns the first argument it receives.
|
|
2759
|
+
*
|
|
2760
|
+
* @static
|
|
2761
|
+
* @since 0.1.0
|
|
2762
|
+
* @memberOf _
|
|
2763
|
+
* @category Util
|
|
2764
|
+
* @param {*} value Any value.
|
|
2765
|
+
* @returns {*} Returns `value`.
|
|
2766
|
+
* @example
|
|
2767
|
+
*
|
|
2768
|
+
* var object = { 'a': 1 };
|
|
2769
|
+
*
|
|
2770
|
+
* console.log(_.identity(object) === object);
|
|
2771
|
+
* // => true
|
|
2772
|
+
*/
|
|
2773
|
+
function identity(value) {
|
|
2774
|
+
return value;
|
|
2775
|
+
}
|
|
2776
|
+
|
|
2777
|
+
/** `Object#toString` result references. */
|
|
2778
|
+
var asyncTag = '[object AsyncFunction]',
|
|
2779
|
+
funcTag$1 = '[object Function]',
|
|
2780
|
+
genTag = '[object GeneratorFunction]',
|
|
2781
|
+
proxyTag = '[object Proxy]';
|
|
2782
|
+
|
|
2783
|
+
/**
|
|
2784
|
+
* Checks if `value` is classified as a `Function` object.
|
|
2785
|
+
*
|
|
2786
|
+
* @static
|
|
2787
|
+
* @memberOf _
|
|
2788
|
+
* @since 0.1.0
|
|
2789
|
+
* @category Lang
|
|
2790
|
+
* @param {*} value The value to check.
|
|
2791
|
+
* @returns {boolean} Returns `true` if `value` is a function, else `false`.
|
|
2792
|
+
* @example
|
|
2793
|
+
*
|
|
2794
|
+
* _.isFunction(_);
|
|
2795
|
+
* // => true
|
|
2796
|
+
*
|
|
2797
|
+
* _.isFunction(/abc/);
|
|
2798
|
+
* // => false
|
|
2799
|
+
*/
|
|
2800
|
+
function isFunction(value) {
|
|
2801
|
+
if (!isObject(value)) {
|
|
2802
|
+
return false;
|
|
2803
|
+
}
|
|
2804
|
+
// The use of `Object#toString` avoids issues with the `typeof` operator
|
|
2805
|
+
// in Safari 9 which returns 'object' for typed arrays and other constructors.
|
|
2806
|
+
var tag = baseGetTag(value);
|
|
2807
|
+
return tag == funcTag$1 || tag == genTag || tag == asyncTag || tag == proxyTag;
|
|
2808
|
+
}
|
|
2809
|
+
|
|
2810
|
+
/** Used to detect overreaching core-js shims. */
|
|
2811
|
+
var coreJsData = root['__core-js_shared__'];
|
|
2812
|
+
|
|
2813
|
+
/** Used to detect methods masquerading as native. */
|
|
2814
|
+
var maskSrcKey = (function() {
|
|
2815
|
+
var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
|
|
2816
|
+
return uid ? ('Symbol(src)_1.' + uid) : '';
|
|
2817
|
+
}());
|
|
2818
|
+
|
|
2819
|
+
/**
|
|
2820
|
+
* Checks if `func` has its source masked.
|
|
2821
|
+
*
|
|
2822
|
+
* @private
|
|
2823
|
+
* @param {Function} func The function to check.
|
|
2824
|
+
* @returns {boolean} Returns `true` if `func` is masked, else `false`.
|
|
2825
|
+
*/
|
|
2826
|
+
function isMasked(func) {
|
|
2827
|
+
return !!maskSrcKey && (maskSrcKey in func);
|
|
2828
|
+
}
|
|
2829
|
+
|
|
2830
|
+
/** Used for built-in method references. */
|
|
2831
|
+
var funcProto$2 = Function.prototype;
|
|
2832
|
+
|
|
2833
|
+
/** Used to resolve the decompiled source of functions. */
|
|
2834
|
+
var funcToString$2 = funcProto$2.toString;
|
|
2835
|
+
|
|
2836
|
+
/**
|
|
2837
|
+
* Converts `func` to its source code.
|
|
2838
|
+
*
|
|
2839
|
+
* @private
|
|
2840
|
+
* @param {Function} func The function to convert.
|
|
2841
|
+
* @returns {string} Returns the source code.
|
|
2842
|
+
*/
|
|
2843
|
+
function toSource(func) {
|
|
2844
|
+
if (func != null) {
|
|
2845
|
+
try {
|
|
2846
|
+
return funcToString$2.call(func);
|
|
2847
|
+
} catch (e) {}
|
|
2848
|
+
try {
|
|
2849
|
+
return (func + '');
|
|
2850
|
+
} catch (e) {}
|
|
2851
|
+
}
|
|
2852
|
+
return '';
|
|
2853
|
+
}
|
|
2854
|
+
|
|
2855
|
+
/**
|
|
2856
|
+
* Used to match `RegExp`
|
|
2857
|
+
* [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
|
|
2858
|
+
*/
|
|
2859
|
+
var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
|
|
2860
|
+
|
|
2861
|
+
/** Used to detect host constructors (Safari). */
|
|
2862
|
+
var reIsHostCtor = /^\[object .+?Constructor\]$/;
|
|
2863
|
+
|
|
2864
|
+
/** Used for built-in method references. */
|
|
2865
|
+
var funcProto$1 = Function.prototype,
|
|
2866
|
+
objectProto$7 = Object.prototype;
|
|
2867
|
+
|
|
2868
|
+
/** Used to resolve the decompiled source of functions. */
|
|
2869
|
+
var funcToString$1 = funcProto$1.toString;
|
|
2870
|
+
|
|
2871
|
+
/** Used to check objects for own properties. */
|
|
2872
|
+
var hasOwnProperty$6 = objectProto$7.hasOwnProperty;
|
|
2873
|
+
|
|
2874
|
+
/** Used to detect if a method is native. */
|
|
2875
|
+
var reIsNative = RegExp('^' +
|
|
2876
|
+
funcToString$1.call(hasOwnProperty$6).replace(reRegExpChar, '\\$&')
|
|
2877
|
+
.replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
|
|
2878
|
+
);
|
|
2879
|
+
|
|
2880
|
+
/**
|
|
2881
|
+
* The base implementation of `_.isNative` without bad shim checks.
|
|
2882
|
+
*
|
|
2883
|
+
* @private
|
|
2884
|
+
* @param {*} value The value to check.
|
|
2885
|
+
* @returns {boolean} Returns `true` if `value` is a native function,
|
|
2886
|
+
* else `false`.
|
|
2887
|
+
*/
|
|
2888
|
+
function baseIsNative(value) {
|
|
2889
|
+
if (!isObject(value) || isMasked(value)) {
|
|
2890
|
+
return false;
|
|
2891
|
+
}
|
|
2892
|
+
var pattern = isFunction(value) ? reIsNative : reIsHostCtor;
|
|
2893
|
+
return pattern.test(toSource(value));
|
|
2894
|
+
}
|
|
2895
|
+
|
|
2896
|
+
/**
|
|
2897
|
+
* Gets the value at `key` of `object`.
|
|
2898
|
+
*
|
|
2899
|
+
* @private
|
|
2900
|
+
* @param {Object} [object] The object to query.
|
|
2901
|
+
* @param {string} key The key of the property to get.
|
|
2902
|
+
* @returns {*} Returns the property value.
|
|
2903
|
+
*/
|
|
2904
|
+
function getValue(object, key) {
|
|
2905
|
+
return object == null ? undefined : object[key];
|
|
2906
|
+
}
|
|
2907
|
+
|
|
2908
|
+
/**
|
|
2909
|
+
* Gets the native function at `key` of `object`.
|
|
2910
|
+
*
|
|
2911
|
+
* @private
|
|
2912
|
+
* @param {Object} object The object to query.
|
|
2913
|
+
* @param {string} key The key of the method to get.
|
|
2914
|
+
* @returns {*} Returns the function if it's native, else `undefined`.
|
|
2915
|
+
*/
|
|
2916
|
+
function getNative(object, key) {
|
|
2917
|
+
var value = getValue(object, key);
|
|
2918
|
+
return baseIsNative(value) ? value : undefined;
|
|
2919
|
+
}
|
|
2920
|
+
|
|
2921
|
+
/** Built-in value references. */
|
|
2922
|
+
var objectCreate = Object.create;
|
|
2923
|
+
|
|
2924
|
+
/**
|
|
2925
|
+
* The base implementation of `_.create` without support for assigning
|
|
2926
|
+
* properties to the created object.
|
|
2927
|
+
*
|
|
2928
|
+
* @private
|
|
2929
|
+
* @param {Object} proto The object to inherit from.
|
|
2930
|
+
* @returns {Object} Returns the new object.
|
|
2931
|
+
*/
|
|
2932
|
+
var baseCreate = (function() {
|
|
2933
|
+
function object() {}
|
|
2934
|
+
return function(proto) {
|
|
2935
|
+
if (!isObject(proto)) {
|
|
2936
|
+
return {};
|
|
2937
|
+
}
|
|
2938
|
+
if (objectCreate) {
|
|
2939
|
+
return objectCreate(proto);
|
|
2940
|
+
}
|
|
2941
|
+
object.prototype = proto;
|
|
2942
|
+
var result = new object;
|
|
2943
|
+
object.prototype = undefined;
|
|
2944
|
+
return result;
|
|
2945
|
+
};
|
|
2946
|
+
}());
|
|
2947
|
+
|
|
2948
|
+
/**
|
|
2949
|
+
* A faster alternative to `Function#apply`, this function invokes `func`
|
|
2950
|
+
* with the `this` binding of `thisArg` and the arguments of `args`.
|
|
2951
|
+
*
|
|
2952
|
+
* @private
|
|
2953
|
+
* @param {Function} func The function to invoke.
|
|
2954
|
+
* @param {*} thisArg The `this` binding of `func`.
|
|
2955
|
+
* @param {Array} args The arguments to invoke `func` with.
|
|
2956
|
+
* @returns {*} Returns the result of `func`.
|
|
2957
|
+
*/
|
|
2958
|
+
function apply(func, thisArg, args) {
|
|
2959
|
+
switch (args.length) {
|
|
2960
|
+
case 0: return func.call(thisArg);
|
|
2961
|
+
case 1: return func.call(thisArg, args[0]);
|
|
2962
|
+
case 2: return func.call(thisArg, args[0], args[1]);
|
|
2963
|
+
case 3: return func.call(thisArg, args[0], args[1], args[2]);
|
|
2964
|
+
}
|
|
2965
|
+
return func.apply(thisArg, args);
|
|
2966
|
+
}
|
|
2967
|
+
|
|
2968
|
+
/**
|
|
2969
|
+
* Copies the values of `source` to `array`.
|
|
2970
|
+
*
|
|
2971
|
+
* @private
|
|
2972
|
+
* @param {Array} source The array to copy values from.
|
|
2973
|
+
* @param {Array} [array=[]] The array to copy values to.
|
|
2974
|
+
* @returns {Array} Returns `array`.
|
|
2975
|
+
*/
|
|
2976
|
+
function copyArray(source, array) {
|
|
2977
|
+
var index = -1,
|
|
2978
|
+
length = source.length;
|
|
2979
|
+
|
|
2980
|
+
array || (array = Array(length));
|
|
2981
|
+
while (++index < length) {
|
|
2982
|
+
array[index] = source[index];
|
|
2983
|
+
}
|
|
2984
|
+
return array;
|
|
2985
|
+
}
|
|
2986
|
+
|
|
2987
|
+
/** Used to detect hot functions by number of calls within a span of milliseconds. */
|
|
2988
|
+
var HOT_COUNT = 800,
|
|
2989
|
+
HOT_SPAN = 16;
|
|
2990
|
+
|
|
2991
|
+
/* Built-in method references for those with the same name as other `lodash` methods. */
|
|
2992
|
+
var nativeNow = Date.now;
|
|
2993
|
+
|
|
2994
|
+
/**
|
|
2995
|
+
* Creates a function that'll short out and invoke `identity` instead
|
|
2996
|
+
* of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`
|
|
2997
|
+
* milliseconds.
|
|
2998
|
+
*
|
|
2999
|
+
* @private
|
|
3000
|
+
* @param {Function} func The function to restrict.
|
|
3001
|
+
* @returns {Function} Returns the new shortable function.
|
|
3002
|
+
*/
|
|
3003
|
+
function shortOut(func) {
|
|
3004
|
+
var count = 0,
|
|
3005
|
+
lastCalled = 0;
|
|
3006
|
+
|
|
3007
|
+
return function() {
|
|
3008
|
+
var stamp = nativeNow(),
|
|
3009
|
+
remaining = HOT_SPAN - (stamp - lastCalled);
|
|
3010
|
+
|
|
3011
|
+
lastCalled = stamp;
|
|
3012
|
+
if (remaining > 0) {
|
|
3013
|
+
if (++count >= HOT_COUNT) {
|
|
3014
|
+
return arguments[0];
|
|
3015
|
+
}
|
|
3016
|
+
} else {
|
|
3017
|
+
count = 0;
|
|
3018
|
+
}
|
|
3019
|
+
return func.apply(undefined, arguments);
|
|
3020
|
+
};
|
|
3021
|
+
}
|
|
3022
|
+
|
|
3023
|
+
/**
|
|
3024
|
+
* Creates a function that returns `value`.
|
|
3025
|
+
*
|
|
3026
|
+
* @static
|
|
3027
|
+
* @memberOf _
|
|
3028
|
+
* @since 2.4.0
|
|
3029
|
+
* @category Util
|
|
3030
|
+
* @param {*} value The value to return from the new function.
|
|
3031
|
+
* @returns {Function} Returns the new constant function.
|
|
3032
|
+
* @example
|
|
3033
|
+
*
|
|
3034
|
+
* var objects = _.times(2, _.constant({ 'a': 1 }));
|
|
3035
|
+
*
|
|
3036
|
+
* console.log(objects);
|
|
3037
|
+
* // => [{ 'a': 1 }, { 'a': 1 }]
|
|
3038
|
+
*
|
|
3039
|
+
* console.log(objects[0] === objects[1]);
|
|
3040
|
+
* // => true
|
|
3041
|
+
*/
|
|
3042
|
+
function constant(value) {
|
|
3043
|
+
return function() {
|
|
3044
|
+
return value;
|
|
3045
|
+
};
|
|
3046
|
+
}
|
|
3047
|
+
|
|
3048
|
+
var defineProperty = (function() {
|
|
3049
|
+
try {
|
|
3050
|
+
var func = getNative(Object, 'defineProperty');
|
|
3051
|
+
func({}, '', {});
|
|
3052
|
+
return func;
|
|
3053
|
+
} catch (e) {}
|
|
3054
|
+
}());
|
|
3055
|
+
|
|
3056
|
+
/**
|
|
3057
|
+
* The base implementation of `setToString` without support for hot loop shorting.
|
|
3058
|
+
*
|
|
3059
|
+
* @private
|
|
3060
|
+
* @param {Function} func The function to modify.
|
|
3061
|
+
* @param {Function} string The `toString` result.
|
|
3062
|
+
* @returns {Function} Returns `func`.
|
|
3063
|
+
*/
|
|
3064
|
+
var baseSetToString = !defineProperty ? identity : function(func, string) {
|
|
3065
|
+
return defineProperty(func, 'toString', {
|
|
3066
|
+
'configurable': true,
|
|
3067
|
+
'enumerable': false,
|
|
3068
|
+
'value': constant(string),
|
|
3069
|
+
'writable': true
|
|
3070
|
+
});
|
|
3071
|
+
};
|
|
3072
|
+
|
|
3073
|
+
/**
|
|
3074
|
+
* Sets the `toString` method of `func` to return `string`.
|
|
3075
|
+
*
|
|
3076
|
+
* @private
|
|
3077
|
+
* @param {Function} func The function to modify.
|
|
3078
|
+
* @param {Function} string The `toString` result.
|
|
3079
|
+
* @returns {Function} Returns `func`.
|
|
3080
|
+
*/
|
|
3081
|
+
var setToString = shortOut(baseSetToString);
|
|
3082
|
+
|
|
3083
|
+
/** Used as references for various `Number` constants. */
|
|
3084
|
+
var MAX_SAFE_INTEGER$1 = 9007199254740991;
|
|
3085
|
+
|
|
3086
|
+
/** Used to detect unsigned integer values. */
|
|
3087
|
+
var reIsUint = /^(?:0|[1-9]\d*)$/;
|
|
3088
|
+
|
|
3089
|
+
/**
|
|
3090
|
+
* Checks if `value` is a valid array-like index.
|
|
3091
|
+
*
|
|
3092
|
+
* @private
|
|
3093
|
+
* @param {*} value The value to check.
|
|
3094
|
+
* @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
|
|
3095
|
+
* @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
|
|
3096
|
+
*/
|
|
3097
|
+
function isIndex(value, length) {
|
|
3098
|
+
var type = typeof value;
|
|
3099
|
+
length = length == null ? MAX_SAFE_INTEGER$1 : length;
|
|
3100
|
+
|
|
3101
|
+
return !!length &&
|
|
3102
|
+
(type == 'number' ||
|
|
3103
|
+
(type != 'symbol' && reIsUint.test(value))) &&
|
|
3104
|
+
(value > -1 && value % 1 == 0 && value < length);
|
|
3105
|
+
}
|
|
3106
|
+
|
|
3107
|
+
/**
|
|
3108
|
+
* The base implementation of `assignValue` and `assignMergeValue` without
|
|
3109
|
+
* value checks.
|
|
3110
|
+
*
|
|
3111
|
+
* @private
|
|
3112
|
+
* @param {Object} object The object to modify.
|
|
3113
|
+
* @param {string} key The key of the property to assign.
|
|
3114
|
+
* @param {*} value The value to assign.
|
|
3115
|
+
*/
|
|
3116
|
+
function baseAssignValue(object, key, value) {
|
|
3117
|
+
if (key == '__proto__' && defineProperty) {
|
|
3118
|
+
defineProperty(object, key, {
|
|
3119
|
+
'configurable': true,
|
|
3120
|
+
'enumerable': true,
|
|
3121
|
+
'value': value,
|
|
3122
|
+
'writable': true
|
|
3123
|
+
});
|
|
3124
|
+
} else {
|
|
3125
|
+
object[key] = value;
|
|
3126
|
+
}
|
|
3127
|
+
}
|
|
3128
|
+
|
|
3129
|
+
/**
|
|
3130
|
+
* Performs a
|
|
3131
|
+
* [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
|
|
3132
|
+
* comparison between two values to determine if they are equivalent.
|
|
3133
|
+
*
|
|
3134
|
+
* @static
|
|
3135
|
+
* @memberOf _
|
|
3136
|
+
* @since 4.0.0
|
|
3137
|
+
* @category Lang
|
|
3138
|
+
* @param {*} value The value to compare.
|
|
3139
|
+
* @param {*} other The other value to compare.
|
|
3140
|
+
* @returns {boolean} Returns `true` if the values are equivalent, else `false`.
|
|
3141
|
+
* @example
|
|
3142
|
+
*
|
|
3143
|
+
* var object = { 'a': 1 };
|
|
3144
|
+
* var other = { 'a': 1 };
|
|
3145
|
+
*
|
|
3146
|
+
* _.eq(object, object);
|
|
3147
|
+
* // => true
|
|
3148
|
+
*
|
|
3149
|
+
* _.eq(object, other);
|
|
3150
|
+
* // => false
|
|
3151
|
+
*
|
|
3152
|
+
* _.eq('a', 'a');
|
|
3153
|
+
* // => true
|
|
3154
|
+
*
|
|
3155
|
+
* _.eq('a', Object('a'));
|
|
3156
|
+
* // => false
|
|
3157
|
+
*
|
|
3158
|
+
* _.eq(NaN, NaN);
|
|
3159
|
+
* // => true
|
|
3160
|
+
*/
|
|
3161
|
+
function eq(value, other) {
|
|
3162
|
+
return value === other || (value !== value && other !== other);
|
|
3163
|
+
}
|
|
3164
|
+
|
|
3165
|
+
/** Used for built-in method references. */
|
|
3166
|
+
var objectProto$6 = Object.prototype;
|
|
3167
|
+
|
|
3168
|
+
/** Used to check objects for own properties. */
|
|
3169
|
+
var hasOwnProperty$5 = objectProto$6.hasOwnProperty;
|
|
3170
|
+
|
|
3171
|
+
/**
|
|
3172
|
+
* Assigns `value` to `key` of `object` if the existing value is not equivalent
|
|
3173
|
+
* using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
|
|
3174
|
+
* for equality comparisons.
|
|
3175
|
+
*
|
|
3176
|
+
* @private
|
|
3177
|
+
* @param {Object} object The object to modify.
|
|
3178
|
+
* @param {string} key The key of the property to assign.
|
|
3179
|
+
* @param {*} value The value to assign.
|
|
3180
|
+
*/
|
|
3181
|
+
function assignValue(object, key, value) {
|
|
3182
|
+
var objValue = object[key];
|
|
3183
|
+
if (!(hasOwnProperty$5.call(object, key) && eq(objValue, value)) ||
|
|
3184
|
+
(value === undefined && !(key in object))) {
|
|
3185
|
+
baseAssignValue(object, key, value);
|
|
3186
|
+
}
|
|
3187
|
+
}
|
|
3188
|
+
|
|
3189
|
+
/**
|
|
3190
|
+
* Copies properties of `source` to `object`.
|
|
3191
|
+
*
|
|
3192
|
+
* @private
|
|
3193
|
+
* @param {Object} source The object to copy properties from.
|
|
3194
|
+
* @param {Array} props The property identifiers to copy.
|
|
3195
|
+
* @param {Object} [object={}] The object to copy properties to.
|
|
3196
|
+
* @param {Function} [customizer] The function to customize copied values.
|
|
3197
|
+
* @returns {Object} Returns `object`.
|
|
3198
|
+
*/
|
|
3199
|
+
function copyObject(source, props, object, customizer) {
|
|
3200
|
+
var isNew = !object;
|
|
3201
|
+
object || (object = {});
|
|
3202
|
+
|
|
3203
|
+
var index = -1,
|
|
3204
|
+
length = props.length;
|
|
3205
|
+
|
|
3206
|
+
while (++index < length) {
|
|
3207
|
+
var key = props[index];
|
|
3208
|
+
|
|
3209
|
+
var newValue = undefined;
|
|
3210
|
+
|
|
3211
|
+
if (newValue === undefined) {
|
|
3212
|
+
newValue = source[key];
|
|
3213
|
+
}
|
|
3214
|
+
if (isNew) {
|
|
3215
|
+
baseAssignValue(object, key, newValue);
|
|
3216
|
+
} else {
|
|
3217
|
+
assignValue(object, key, newValue);
|
|
3218
|
+
}
|
|
3219
|
+
}
|
|
3220
|
+
return object;
|
|
3221
|
+
}
|
|
3222
|
+
|
|
3223
|
+
/* Built-in method references for those with the same name as other `lodash` methods. */
|
|
3224
|
+
var nativeMax = Math.max;
|
|
3225
|
+
|
|
3226
|
+
/**
|
|
3227
|
+
* A specialized version of `baseRest` which transforms the rest array.
|
|
3228
|
+
*
|
|
3229
|
+
* @private
|
|
3230
|
+
* @param {Function} func The function to apply a rest parameter to.
|
|
3231
|
+
* @param {number} [start=func.length-1] The start position of the rest parameter.
|
|
3232
|
+
* @param {Function} transform The rest array transform.
|
|
3233
|
+
* @returns {Function} Returns the new function.
|
|
3234
|
+
*/
|
|
3235
|
+
function overRest(func, start, transform) {
|
|
3236
|
+
start = nativeMax(start === undefined ? (func.length - 1) : start, 0);
|
|
3237
|
+
return function() {
|
|
3238
|
+
var args = arguments,
|
|
3239
|
+
index = -1,
|
|
3240
|
+
length = nativeMax(args.length - start, 0),
|
|
3241
|
+
array = Array(length);
|
|
3242
|
+
|
|
3243
|
+
while (++index < length) {
|
|
3244
|
+
array[index] = args[start + index];
|
|
3245
|
+
}
|
|
3246
|
+
index = -1;
|
|
3247
|
+
var otherArgs = Array(start + 1);
|
|
3248
|
+
while (++index < start) {
|
|
3249
|
+
otherArgs[index] = args[index];
|
|
3250
|
+
}
|
|
3251
|
+
otherArgs[start] = transform(array);
|
|
3252
|
+
return apply(func, this, otherArgs);
|
|
3253
|
+
};
|
|
3254
|
+
}
|
|
3255
|
+
|
|
3256
|
+
/**
|
|
3257
|
+
* The base implementation of `_.rest` which doesn't validate or coerce arguments.
|
|
3258
|
+
*
|
|
3259
|
+
* @private
|
|
3260
|
+
* @param {Function} func The function to apply a rest parameter to.
|
|
3261
|
+
* @param {number} [start=func.length-1] The start position of the rest parameter.
|
|
3262
|
+
* @returns {Function} Returns the new function.
|
|
3263
|
+
*/
|
|
3264
|
+
function baseRest(func, start) {
|
|
3265
|
+
return setToString(overRest(func, start, identity), func + '');
|
|
3266
|
+
}
|
|
3267
|
+
|
|
3268
|
+
/** Used as references for various `Number` constants. */
|
|
3269
|
+
var MAX_SAFE_INTEGER = 9007199254740991;
|
|
3270
|
+
|
|
3271
|
+
/**
|
|
3272
|
+
* Checks if `value` is a valid array-like length.
|
|
3273
|
+
*
|
|
3274
|
+
* **Note:** This method is loosely based on
|
|
3275
|
+
* [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
|
|
3276
|
+
*
|
|
3277
|
+
* @static
|
|
3278
|
+
* @memberOf _
|
|
3279
|
+
* @since 4.0.0
|
|
3280
|
+
* @category Lang
|
|
3281
|
+
* @param {*} value The value to check.
|
|
3282
|
+
* @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
|
|
3283
|
+
* @example
|
|
3284
|
+
*
|
|
3285
|
+
* _.isLength(3);
|
|
3286
|
+
* // => true
|
|
3287
|
+
*
|
|
3288
|
+
* _.isLength(Number.MIN_VALUE);
|
|
3289
|
+
* // => false
|
|
3290
|
+
*
|
|
3291
|
+
* _.isLength(Infinity);
|
|
3292
|
+
* // => false
|
|
3293
|
+
*
|
|
3294
|
+
* _.isLength('3');
|
|
3295
|
+
* // => false
|
|
3296
|
+
*/
|
|
3297
|
+
function isLength(value) {
|
|
3298
|
+
return typeof value == 'number' &&
|
|
3299
|
+
value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
|
|
3300
|
+
}
|
|
3301
|
+
|
|
3302
|
+
/**
|
|
3303
|
+
* Checks if `value` is array-like. A value is considered array-like if it's
|
|
3304
|
+
* not a function and has a `value.length` that's an integer greater than or
|
|
3305
|
+
* equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
|
|
3306
|
+
*
|
|
3307
|
+
* @static
|
|
3308
|
+
* @memberOf _
|
|
3309
|
+
* @since 4.0.0
|
|
3310
|
+
* @category Lang
|
|
3311
|
+
* @param {*} value The value to check.
|
|
3312
|
+
* @returns {boolean} Returns `true` if `value` is array-like, else `false`.
|
|
3313
|
+
* @example
|
|
3314
|
+
*
|
|
3315
|
+
* _.isArrayLike([1, 2, 3]);
|
|
3316
|
+
* // => true
|
|
3317
|
+
*
|
|
3318
|
+
* _.isArrayLike(document.body.children);
|
|
3319
|
+
* // => true
|
|
3320
|
+
*
|
|
3321
|
+
* _.isArrayLike('abc');
|
|
3322
|
+
* // => true
|
|
3323
|
+
*
|
|
3324
|
+
* _.isArrayLike(_.noop);
|
|
3325
|
+
* // => false
|
|
3326
|
+
*/
|
|
3327
|
+
function isArrayLike(value) {
|
|
3328
|
+
return value != null && isLength(value.length) && !isFunction(value);
|
|
3329
|
+
}
|
|
3330
|
+
|
|
3331
|
+
/**
|
|
3332
|
+
* Checks if the given arguments are from an iteratee call.
|
|
3333
|
+
*
|
|
3334
|
+
* @private
|
|
3335
|
+
* @param {*} value The potential iteratee value argument.
|
|
3336
|
+
* @param {*} index The potential iteratee index or key argument.
|
|
3337
|
+
* @param {*} object The potential iteratee object argument.
|
|
3338
|
+
* @returns {boolean} Returns `true` if the arguments are from an iteratee call,
|
|
3339
|
+
* else `false`.
|
|
3340
|
+
*/
|
|
3341
|
+
function isIterateeCall(value, index, object) {
|
|
3342
|
+
if (!isObject(object)) {
|
|
3343
|
+
return false;
|
|
3344
|
+
}
|
|
3345
|
+
var type = typeof index;
|
|
3346
|
+
if (type == 'number'
|
|
3347
|
+
? (isArrayLike(object) && isIndex(index, object.length))
|
|
3348
|
+
: (type == 'string' && index in object)
|
|
3349
|
+
) {
|
|
3350
|
+
return eq(object[index], value);
|
|
3351
|
+
}
|
|
3352
|
+
return false;
|
|
3353
|
+
}
|
|
3354
|
+
|
|
3355
|
+
/**
|
|
3356
|
+
* Creates a function like `_.assign`.
|
|
3357
|
+
*
|
|
3358
|
+
* @private
|
|
3359
|
+
* @param {Function} assigner The function to assign values.
|
|
3360
|
+
* @returns {Function} Returns the new assigner function.
|
|
3361
|
+
*/
|
|
3362
|
+
function createAssigner(assigner) {
|
|
3363
|
+
return baseRest(function(object, sources) {
|
|
3364
|
+
var index = -1,
|
|
3365
|
+
length = sources.length,
|
|
3366
|
+
customizer = length > 1 ? sources[length - 1] : undefined,
|
|
3367
|
+
guard = length > 2 ? sources[2] : undefined;
|
|
3368
|
+
|
|
3369
|
+
customizer = (assigner.length > 3 && typeof customizer == 'function')
|
|
3370
|
+
? (length--, customizer)
|
|
3371
|
+
: undefined;
|
|
3372
|
+
|
|
3373
|
+
if (guard && isIterateeCall(sources[0], sources[1], guard)) {
|
|
3374
|
+
customizer = length < 3 ? undefined : customizer;
|
|
3375
|
+
length = 1;
|
|
3376
|
+
}
|
|
3377
|
+
object = Object(object);
|
|
3378
|
+
while (++index < length) {
|
|
3379
|
+
var source = sources[index];
|
|
3380
|
+
if (source) {
|
|
3381
|
+
assigner(object, source, index, customizer);
|
|
3382
|
+
}
|
|
3383
|
+
}
|
|
3384
|
+
return object;
|
|
3385
|
+
});
|
|
3386
|
+
}
|
|
3387
|
+
|
|
3388
|
+
/** Used for built-in method references. */
|
|
3389
|
+
var objectProto$5 = Object.prototype;
|
|
3390
|
+
|
|
3391
|
+
/**
|
|
3392
|
+
* Checks if `value` is likely a prototype object.
|
|
3393
|
+
*
|
|
3394
|
+
* @private
|
|
3395
|
+
* @param {*} value The value to check.
|
|
3396
|
+
* @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
|
|
3397
|
+
*/
|
|
3398
|
+
function isPrototype(value) {
|
|
3399
|
+
var Ctor = value && value.constructor,
|
|
3400
|
+
proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto$5;
|
|
3401
|
+
|
|
3402
|
+
return value === proto;
|
|
3403
|
+
}
|
|
3404
|
+
|
|
3405
|
+
/**
|
|
3406
|
+
* The base implementation of `_.times` without support for iteratee shorthands
|
|
3407
|
+
* or max array length checks.
|
|
3408
|
+
*
|
|
3409
|
+
* @private
|
|
3410
|
+
* @param {number} n The number of times to invoke `iteratee`.
|
|
3411
|
+
* @param {Function} iteratee The function invoked per iteration.
|
|
3412
|
+
* @returns {Array} Returns the array of results.
|
|
3413
|
+
*/
|
|
3414
|
+
function baseTimes(n, iteratee) {
|
|
3415
|
+
var index = -1,
|
|
3416
|
+
result = Array(n);
|
|
3417
|
+
|
|
3418
|
+
while (++index < n) {
|
|
3419
|
+
result[index] = iteratee(index);
|
|
3420
|
+
}
|
|
3421
|
+
return result;
|
|
3422
|
+
}
|
|
3423
|
+
|
|
3424
|
+
/** `Object#toString` result references. */
|
|
3425
|
+
var argsTag$1 = '[object Arguments]';
|
|
3426
|
+
|
|
3427
|
+
/**
|
|
3428
|
+
* The base implementation of `_.isArguments`.
|
|
3429
|
+
*
|
|
3430
|
+
* @private
|
|
3431
|
+
* @param {*} value The value to check.
|
|
3432
|
+
* @returns {boolean} Returns `true` if `value` is an `arguments` object,
|
|
3433
|
+
*/
|
|
3434
|
+
function baseIsArguments(value) {
|
|
3435
|
+
return isObjectLike(value) && baseGetTag(value) == argsTag$1;
|
|
3436
|
+
}
|
|
3437
|
+
|
|
3438
|
+
/** Used for built-in method references. */
|
|
3439
|
+
var objectProto$4 = Object.prototype;
|
|
3440
|
+
|
|
3441
|
+
/** Used to check objects for own properties. */
|
|
3442
|
+
var hasOwnProperty$4 = objectProto$4.hasOwnProperty;
|
|
3443
|
+
|
|
3444
|
+
/** Built-in value references. */
|
|
3445
|
+
var propertyIsEnumerable = objectProto$4.propertyIsEnumerable;
|
|
3446
|
+
|
|
3447
|
+
/**
|
|
3448
|
+
* Checks if `value` is likely an `arguments` object.
|
|
3449
|
+
*
|
|
3450
|
+
* @static
|
|
3451
|
+
* @memberOf _
|
|
3452
|
+
* @since 0.1.0
|
|
3453
|
+
* @category Lang
|
|
3454
|
+
* @param {*} value The value to check.
|
|
3455
|
+
* @returns {boolean} Returns `true` if `value` is an `arguments` object,
|
|
3456
|
+
* else `false`.
|
|
3457
|
+
* @example
|
|
3458
|
+
*
|
|
3459
|
+
* _.isArguments(function() { return arguments; }());
|
|
3460
|
+
* // => true
|
|
3461
|
+
*
|
|
3462
|
+
* _.isArguments([1, 2, 3]);
|
|
3463
|
+
* // => false
|
|
3464
|
+
*/
|
|
3465
|
+
var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {
|
|
3466
|
+
return isObjectLike(value) && hasOwnProperty$4.call(value, 'callee') &&
|
|
3467
|
+
!propertyIsEnumerable.call(value, 'callee');
|
|
3468
|
+
};
|
|
3469
|
+
|
|
3470
|
+
/**
|
|
3471
|
+
* This method returns `false`.
|
|
3472
|
+
*
|
|
3473
|
+
* @static
|
|
3474
|
+
* @memberOf _
|
|
3475
|
+
* @since 4.13.0
|
|
3476
|
+
* @category Util
|
|
3477
|
+
* @returns {boolean} Returns `false`.
|
|
3478
|
+
* @example
|
|
3479
|
+
*
|
|
3480
|
+
* _.times(2, _.stubFalse);
|
|
3481
|
+
* // => [false, false]
|
|
3482
|
+
*/
|
|
3483
|
+
function stubFalse() {
|
|
3484
|
+
return false;
|
|
3485
|
+
}
|
|
3486
|
+
|
|
3487
|
+
/** Detect free variable `exports`. */
|
|
3488
|
+
var freeExports$2 = typeof exports == 'object' && exports && !exports.nodeType && exports;
|
|
3489
|
+
|
|
3490
|
+
/** Detect free variable `module`. */
|
|
3491
|
+
var freeModule$2 = freeExports$2 && typeof module == 'object' && module && !module.nodeType && module;
|
|
3492
|
+
|
|
3493
|
+
/** Detect the popular CommonJS extension `module.exports`. */
|
|
3494
|
+
var moduleExports$2 = freeModule$2 && freeModule$2.exports === freeExports$2;
|
|
3495
|
+
|
|
3496
|
+
/** Built-in value references. */
|
|
3497
|
+
var Buffer$1 = moduleExports$2 ? root.Buffer : undefined;
|
|
3498
|
+
|
|
3499
|
+
/* Built-in method references for those with the same name as other `lodash` methods. */
|
|
3500
|
+
var nativeIsBuffer = Buffer$1 ? Buffer$1.isBuffer : undefined;
|
|
3501
|
+
|
|
3502
|
+
/**
|
|
3503
|
+
* Checks if `value` is a buffer.
|
|
3504
|
+
*
|
|
3505
|
+
* @static
|
|
3506
|
+
* @memberOf _
|
|
3507
|
+
* @since 4.3.0
|
|
3508
|
+
* @category Lang
|
|
3509
|
+
* @param {*} value The value to check.
|
|
3510
|
+
* @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
|
|
3511
|
+
* @example
|
|
3512
|
+
*
|
|
3513
|
+
* _.isBuffer(new Buffer(2));
|
|
3514
|
+
* // => true
|
|
3515
|
+
*
|
|
3516
|
+
* _.isBuffer(new Uint8Array(2));
|
|
3517
|
+
* // => false
|
|
3518
|
+
*/
|
|
3519
|
+
var isBuffer = nativeIsBuffer || stubFalse;
|
|
3520
|
+
|
|
3521
|
+
/** `Object#toString` result references. */
|
|
3522
|
+
var argsTag = '[object Arguments]',
|
|
3523
|
+
arrayTag = '[object Array]',
|
|
3524
|
+
boolTag = '[object Boolean]',
|
|
3525
|
+
dateTag = '[object Date]',
|
|
3526
|
+
errorTag = '[object Error]',
|
|
3527
|
+
funcTag = '[object Function]',
|
|
3528
|
+
mapTag = '[object Map]',
|
|
3529
|
+
numberTag = '[object Number]',
|
|
3530
|
+
objectTag$1 = '[object Object]',
|
|
3531
|
+
regexpTag = '[object RegExp]',
|
|
3532
|
+
setTag = '[object Set]',
|
|
3533
|
+
stringTag = '[object String]',
|
|
3534
|
+
weakMapTag = '[object WeakMap]';
|
|
3535
|
+
|
|
3536
|
+
var arrayBufferTag = '[object ArrayBuffer]',
|
|
3537
|
+
dataViewTag = '[object DataView]',
|
|
3538
|
+
float32Tag = '[object Float32Array]',
|
|
3539
|
+
float64Tag = '[object Float64Array]',
|
|
3540
|
+
int8Tag = '[object Int8Array]',
|
|
3541
|
+
int16Tag = '[object Int16Array]',
|
|
3542
|
+
int32Tag = '[object Int32Array]',
|
|
3543
|
+
uint8Tag = '[object Uint8Array]',
|
|
3544
|
+
uint8ClampedTag = '[object Uint8ClampedArray]',
|
|
3545
|
+
uint16Tag = '[object Uint16Array]',
|
|
3546
|
+
uint32Tag = '[object Uint32Array]';
|
|
3547
|
+
|
|
3548
|
+
/** Used to identify `toStringTag` values of typed arrays. */
|
|
3549
|
+
var typedArrayTags = {};
|
|
3550
|
+
typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
|
|
3551
|
+
typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
|
|
3552
|
+
typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
|
|
3553
|
+
typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
|
|
3554
|
+
typedArrayTags[uint32Tag] = true;
|
|
3555
|
+
typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
|
|
3556
|
+
typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
|
|
3557
|
+
typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =
|
|
3558
|
+
typedArrayTags[errorTag] = typedArrayTags[funcTag] =
|
|
3559
|
+
typedArrayTags[mapTag] = typedArrayTags[numberTag] =
|
|
3560
|
+
typedArrayTags[objectTag$1] = typedArrayTags[regexpTag] =
|
|
3561
|
+
typedArrayTags[setTag] = typedArrayTags[stringTag] =
|
|
3562
|
+
typedArrayTags[weakMapTag] = false;
|
|
3563
|
+
|
|
3564
|
+
/**
|
|
3565
|
+
* The base implementation of `_.isTypedArray` without Node.js optimizations.
|
|
3566
|
+
*
|
|
3567
|
+
* @private
|
|
3568
|
+
* @param {*} value The value to check.
|
|
3569
|
+
* @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
|
|
3570
|
+
*/
|
|
3571
|
+
function baseIsTypedArray(value) {
|
|
3572
|
+
return isObjectLike(value) &&
|
|
3573
|
+
isLength(value.length) && !!typedArrayTags[baseGetTag(value)];
|
|
3574
|
+
}
|
|
3575
|
+
|
|
3576
|
+
/**
|
|
3577
|
+
* The base implementation of `_.unary` without support for storing metadata.
|
|
3578
|
+
*
|
|
3579
|
+
* @private
|
|
3580
|
+
* @param {Function} func The function to cap arguments for.
|
|
3581
|
+
* @returns {Function} Returns the new capped function.
|
|
3582
|
+
*/
|
|
3583
|
+
function baseUnary(func) {
|
|
3584
|
+
return function(value) {
|
|
3585
|
+
return func(value);
|
|
3586
|
+
};
|
|
3587
|
+
}
|
|
3588
|
+
|
|
3589
|
+
/** Detect free variable `exports`. */
|
|
3590
|
+
var freeExports$1 = typeof exports == 'object' && exports && !exports.nodeType && exports;
|
|
3591
|
+
|
|
3592
|
+
/** Detect free variable `module`. */
|
|
3593
|
+
var freeModule$1 = freeExports$1 && typeof module == 'object' && module && !module.nodeType && module;
|
|
3594
|
+
|
|
3595
|
+
/** Detect the popular CommonJS extension `module.exports`. */
|
|
3596
|
+
var moduleExports$1 = freeModule$1 && freeModule$1.exports === freeExports$1;
|
|
3597
|
+
|
|
3598
|
+
/** Detect free variable `process` from Node.js. */
|
|
3599
|
+
var freeProcess = moduleExports$1 && freeGlobal.process;
|
|
3600
|
+
|
|
3601
|
+
/** Used to access faster Node.js helpers. */
|
|
3602
|
+
var nodeUtil = (function() {
|
|
3603
|
+
try {
|
|
3604
|
+
// Use `util.types` for Node.js 10+.
|
|
3605
|
+
var types = freeModule$1 && freeModule$1.require && freeModule$1.require('util').types;
|
|
3606
|
+
|
|
3607
|
+
if (types) {
|
|
3608
|
+
return types;
|
|
3609
|
+
}
|
|
3610
|
+
|
|
3611
|
+
// Legacy `process.binding('util')` for Node.js < 10.
|
|
3612
|
+
return freeProcess && freeProcess.binding && freeProcess.binding('util');
|
|
3613
|
+
} catch (e) {}
|
|
3614
|
+
}());
|
|
3615
|
+
|
|
3616
|
+
/* Node.js helper references. */
|
|
3617
|
+
var nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;
|
|
3618
|
+
|
|
3619
|
+
/**
|
|
3620
|
+
* Checks if `value` is classified as a typed array.
|
|
3621
|
+
*
|
|
3622
|
+
* @static
|
|
3623
|
+
* @memberOf _
|
|
3624
|
+
* @since 3.0.0
|
|
3625
|
+
* @category Lang
|
|
3626
|
+
* @param {*} value The value to check.
|
|
3627
|
+
* @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
|
|
3628
|
+
* @example
|
|
3629
|
+
*
|
|
3630
|
+
* _.isTypedArray(new Uint8Array);
|
|
3631
|
+
* // => true
|
|
3632
|
+
*
|
|
3633
|
+
* _.isTypedArray([]);
|
|
3634
|
+
* // => false
|
|
3635
|
+
*/
|
|
3636
|
+
var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;
|
|
3637
|
+
|
|
3638
|
+
/**
|
|
3639
|
+
* Creates an array of the enumerable property names of the array-like `value`.
|
|
3640
|
+
*
|
|
3641
|
+
* @private
|
|
3642
|
+
* @param {*} value The value to query.
|
|
3643
|
+
* @param {boolean} inherited Specify returning inherited property names.
|
|
3644
|
+
* @returns {Array} Returns the array of property names.
|
|
3645
|
+
*/
|
|
3646
|
+
function arrayLikeKeys(value, inherited) {
|
|
3647
|
+
var isArr = isArray(value),
|
|
3648
|
+
isArg = !isArr && isArguments(value),
|
|
3649
|
+
isBuff = !isArr && !isArg && isBuffer(value),
|
|
3650
|
+
isType = !isArr && !isArg && !isBuff && isTypedArray(value),
|
|
3651
|
+
skipIndexes = isArr || isArg || isBuff || isType,
|
|
3652
|
+
result = skipIndexes ? baseTimes(value.length, String) : [],
|
|
3653
|
+
length = result.length;
|
|
3654
|
+
|
|
3655
|
+
for (var key in value) {
|
|
3656
|
+
if (!(skipIndexes && (
|
|
3657
|
+
// Safari 9 has enumerable `arguments.length` in strict mode.
|
|
3658
|
+
key == 'length' ||
|
|
3659
|
+
// Node.js 0.10 has enumerable non-index properties on buffers.
|
|
3660
|
+
(isBuff && (key == 'offset' || key == 'parent')) ||
|
|
3661
|
+
// PhantomJS 2 has enumerable non-index properties on typed arrays.
|
|
3662
|
+
(isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||
|
|
3663
|
+
// Skip index properties.
|
|
3664
|
+
isIndex(key, length)
|
|
3665
|
+
))) {
|
|
3666
|
+
result.push(key);
|
|
3667
|
+
}
|
|
3668
|
+
}
|
|
3669
|
+
return result;
|
|
3670
|
+
}
|
|
3671
|
+
|
|
3672
|
+
/**
|
|
3673
|
+
* Creates a unary function that invokes `func` with its argument transformed.
|
|
3674
|
+
*
|
|
3675
|
+
* @private
|
|
3676
|
+
* @param {Function} func The function to wrap.
|
|
3677
|
+
* @param {Function} transform The argument transform.
|
|
3678
|
+
* @returns {Function} Returns the new function.
|
|
3679
|
+
*/
|
|
3680
|
+
function overArg(func, transform) {
|
|
3681
|
+
return function(arg) {
|
|
3682
|
+
return func(transform(arg));
|
|
3683
|
+
};
|
|
3684
|
+
}
|
|
3685
|
+
|
|
3686
|
+
/**
|
|
3687
|
+
* This function is like
|
|
3688
|
+
* [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
|
|
3689
|
+
* except that it includes inherited enumerable properties.
|
|
3690
|
+
*
|
|
3691
|
+
* @private
|
|
3692
|
+
* @param {Object} object The object to query.
|
|
3693
|
+
* @returns {Array} Returns the array of property names.
|
|
3694
|
+
*/
|
|
3695
|
+
function nativeKeysIn(object) {
|
|
3696
|
+
var result = [];
|
|
3697
|
+
if (object != null) {
|
|
3698
|
+
for (var key in Object(object)) {
|
|
3699
|
+
result.push(key);
|
|
3700
|
+
}
|
|
3701
|
+
}
|
|
3702
|
+
return result;
|
|
3703
|
+
}
|
|
3704
|
+
|
|
3705
|
+
/** Used for built-in method references. */
|
|
3706
|
+
var objectProto$3 = Object.prototype;
|
|
3707
|
+
|
|
3708
|
+
/** Used to check objects for own properties. */
|
|
3709
|
+
var hasOwnProperty$3 = objectProto$3.hasOwnProperty;
|
|
3710
|
+
|
|
3711
|
+
/**
|
|
3712
|
+
* The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.
|
|
3713
|
+
*
|
|
3714
|
+
* @private
|
|
3715
|
+
* @param {Object} object The object to query.
|
|
3716
|
+
* @returns {Array} Returns the array of property names.
|
|
3717
|
+
*/
|
|
3718
|
+
function baseKeysIn(object) {
|
|
3719
|
+
if (!isObject(object)) {
|
|
3720
|
+
return nativeKeysIn(object);
|
|
3721
|
+
}
|
|
3722
|
+
var isProto = isPrototype(object),
|
|
3723
|
+
result = [];
|
|
3724
|
+
|
|
3725
|
+
for (var key in object) {
|
|
3726
|
+
if (!(key == 'constructor' && (isProto || !hasOwnProperty$3.call(object, key)))) {
|
|
3727
|
+
result.push(key);
|
|
3728
|
+
}
|
|
3729
|
+
}
|
|
3730
|
+
return result;
|
|
3731
|
+
}
|
|
3732
|
+
|
|
3733
|
+
/**
|
|
3734
|
+
* Creates an array of the own and inherited enumerable property names of `object`.
|
|
3735
|
+
*
|
|
3736
|
+
* **Note:** Non-object values are coerced to objects.
|
|
3737
|
+
*
|
|
3738
|
+
* @static
|
|
3739
|
+
* @memberOf _
|
|
3740
|
+
* @since 3.0.0
|
|
3741
|
+
* @category Object
|
|
3742
|
+
* @param {Object} object The object to query.
|
|
3743
|
+
* @returns {Array} Returns the array of property names.
|
|
3744
|
+
* @example
|
|
3745
|
+
*
|
|
3746
|
+
* function Foo() {
|
|
3747
|
+
* this.a = 1;
|
|
3748
|
+
* this.b = 2;
|
|
3749
|
+
* }
|
|
3750
|
+
*
|
|
3751
|
+
* Foo.prototype.c = 3;
|
|
3752
|
+
*
|
|
3753
|
+
* _.keysIn(new Foo);
|
|
3754
|
+
* // => ['a', 'b', 'c'] (iteration order is not guaranteed)
|
|
3755
|
+
*/
|
|
3756
|
+
function keysIn(object) {
|
|
3757
|
+
return isArrayLike(object) ? arrayLikeKeys(object) : baseKeysIn(object);
|
|
3758
|
+
}
|
|
3759
|
+
|
|
3760
|
+
/* Built-in method references that are verified to be native. */
|
|
3761
|
+
var nativeCreate = getNative(Object, 'create');
|
|
3762
|
+
|
|
3763
|
+
/**
|
|
3764
|
+
* Removes all key-value entries from the hash.
|
|
3765
|
+
*
|
|
3766
|
+
* @private
|
|
3767
|
+
* @name clear
|
|
3768
|
+
* @memberOf Hash
|
|
3769
|
+
*/
|
|
3770
|
+
function hashClear() {
|
|
3771
|
+
this.__data__ = nativeCreate ? nativeCreate(null) : {};
|
|
3772
|
+
this.size = 0;
|
|
3773
|
+
}
|
|
3774
|
+
|
|
3775
|
+
/**
|
|
3776
|
+
* Removes `key` and its value from the hash.
|
|
3777
|
+
*
|
|
3778
|
+
* @private
|
|
3779
|
+
* @name delete
|
|
3780
|
+
* @memberOf Hash
|
|
3781
|
+
* @param {Object} hash The hash to modify.
|
|
3782
|
+
* @param {string} key The key of the value to remove.
|
|
3783
|
+
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
|
|
3784
|
+
*/
|
|
3785
|
+
function hashDelete(key) {
|
|
3786
|
+
var result = this.has(key) && delete this.__data__[key];
|
|
3787
|
+
this.size -= result ? 1 : 0;
|
|
3788
|
+
return result;
|
|
3789
|
+
}
|
|
3790
|
+
|
|
3791
|
+
/** Used to stand-in for `undefined` hash values. */
|
|
3792
|
+
var HASH_UNDEFINED$1 = '__lodash_hash_undefined__';
|
|
3793
|
+
|
|
3794
|
+
/** Used for built-in method references. */
|
|
3795
|
+
var objectProto$2 = Object.prototype;
|
|
3796
|
+
|
|
3797
|
+
/** Used to check objects for own properties. */
|
|
3798
|
+
var hasOwnProperty$2 = objectProto$2.hasOwnProperty;
|
|
3799
|
+
|
|
3800
|
+
/**
|
|
3801
|
+
* Gets the hash value for `key`.
|
|
3802
|
+
*
|
|
3803
|
+
* @private
|
|
3804
|
+
* @name get
|
|
3805
|
+
* @memberOf Hash
|
|
3806
|
+
* @param {string} key The key of the value to get.
|
|
3807
|
+
* @returns {*} Returns the entry value.
|
|
3808
|
+
*/
|
|
3809
|
+
function hashGet(key) {
|
|
3810
|
+
var data = this.__data__;
|
|
3811
|
+
if (nativeCreate) {
|
|
3812
|
+
var result = data[key];
|
|
3813
|
+
return result === HASH_UNDEFINED$1 ? undefined : result;
|
|
3814
|
+
}
|
|
3815
|
+
return hasOwnProperty$2.call(data, key) ? data[key] : undefined;
|
|
3816
|
+
}
|
|
3817
|
+
|
|
3818
|
+
/** Used for built-in method references. */
|
|
3819
|
+
var objectProto$1 = Object.prototype;
|
|
3820
|
+
|
|
3821
|
+
/** Used to check objects for own properties. */
|
|
3822
|
+
var hasOwnProperty$1 = objectProto$1.hasOwnProperty;
|
|
3823
|
+
|
|
3824
|
+
/**
|
|
3825
|
+
* Checks if a hash value for `key` exists.
|
|
3826
|
+
*
|
|
3827
|
+
* @private
|
|
3828
|
+
* @name has
|
|
3829
|
+
* @memberOf Hash
|
|
3830
|
+
* @param {string} key The key of the entry to check.
|
|
3831
|
+
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
|
|
3832
|
+
*/
|
|
3833
|
+
function hashHas(key) {
|
|
3834
|
+
var data = this.__data__;
|
|
3835
|
+
return nativeCreate ? (data[key] !== undefined) : hasOwnProperty$1.call(data, key);
|
|
3836
|
+
}
|
|
3837
|
+
|
|
3838
|
+
/** Used to stand-in for `undefined` hash values. */
|
|
3839
|
+
var HASH_UNDEFINED = '__lodash_hash_undefined__';
|
|
3840
|
+
|
|
3841
|
+
/**
|
|
3842
|
+
* Sets the hash `key` to `value`.
|
|
3843
|
+
*
|
|
3844
|
+
* @private
|
|
3845
|
+
* @name set
|
|
3846
|
+
* @memberOf Hash
|
|
3847
|
+
* @param {string} key The key of the value to set.
|
|
3848
|
+
* @param {*} value The value to set.
|
|
3849
|
+
* @returns {Object} Returns the hash instance.
|
|
3850
|
+
*/
|
|
3851
|
+
function hashSet(key, value) {
|
|
3852
|
+
var data = this.__data__;
|
|
3853
|
+
this.size += this.has(key) ? 0 : 1;
|
|
3854
|
+
data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
|
|
3855
|
+
return this;
|
|
3856
|
+
}
|
|
3857
|
+
|
|
3858
|
+
/**
|
|
3859
|
+
* Creates a hash object.
|
|
3860
|
+
*
|
|
3861
|
+
* @private
|
|
3862
|
+
* @constructor
|
|
3863
|
+
* @param {Array} [entries] The key-value pairs to cache.
|
|
3864
|
+
*/
|
|
3865
|
+
function Hash(entries) {
|
|
3866
|
+
var index = -1,
|
|
3867
|
+
length = entries == null ? 0 : entries.length;
|
|
3868
|
+
|
|
3869
|
+
this.clear();
|
|
3870
|
+
while (++index < length) {
|
|
3871
|
+
var entry = entries[index];
|
|
3872
|
+
this.set(entry[0], entry[1]);
|
|
3873
|
+
}
|
|
3874
|
+
}
|
|
3875
|
+
|
|
3876
|
+
// Add methods to `Hash`.
|
|
3877
|
+
Hash.prototype.clear = hashClear;
|
|
3878
|
+
Hash.prototype['delete'] = hashDelete;
|
|
3879
|
+
Hash.prototype.get = hashGet;
|
|
3880
|
+
Hash.prototype.has = hashHas;
|
|
3881
|
+
Hash.prototype.set = hashSet;
|
|
3882
|
+
|
|
3883
|
+
/**
|
|
3884
|
+
* Removes all key-value entries from the list cache.
|
|
3885
|
+
*
|
|
3886
|
+
* @private
|
|
3887
|
+
* @name clear
|
|
3888
|
+
* @memberOf ListCache
|
|
3889
|
+
*/
|
|
3890
|
+
function listCacheClear() {
|
|
3891
|
+
this.__data__ = [];
|
|
3892
|
+
this.size = 0;
|
|
3893
|
+
}
|
|
3894
|
+
|
|
3895
|
+
/**
|
|
3896
|
+
* Gets the index at which the `key` is found in `array` of key-value pairs.
|
|
3897
|
+
*
|
|
3898
|
+
* @private
|
|
3899
|
+
* @param {Array} array The array to inspect.
|
|
3900
|
+
* @param {*} key The key to search for.
|
|
3901
|
+
* @returns {number} Returns the index of the matched value, else `-1`.
|
|
3902
|
+
*/
|
|
3903
|
+
function assocIndexOf(array, key) {
|
|
3904
|
+
var length = array.length;
|
|
3905
|
+
while (length--) {
|
|
3906
|
+
if (eq(array[length][0], key)) {
|
|
3907
|
+
return length;
|
|
3908
|
+
}
|
|
3909
|
+
}
|
|
3910
|
+
return -1;
|
|
3911
|
+
}
|
|
3912
|
+
|
|
3913
|
+
/** Used for built-in method references. */
|
|
3914
|
+
var arrayProto = Array.prototype;
|
|
3915
|
+
|
|
3916
|
+
/** Built-in value references. */
|
|
3917
|
+
var splice = arrayProto.splice;
|
|
3918
|
+
|
|
3919
|
+
/**
|
|
3920
|
+
* Removes `key` and its value from the list cache.
|
|
3921
|
+
*
|
|
3922
|
+
* @private
|
|
3923
|
+
* @name delete
|
|
3924
|
+
* @memberOf ListCache
|
|
3925
|
+
* @param {string} key The key of the value to remove.
|
|
3926
|
+
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
|
|
3927
|
+
*/
|
|
3928
|
+
function listCacheDelete(key) {
|
|
3929
|
+
var data = this.__data__,
|
|
3930
|
+
index = assocIndexOf(data, key);
|
|
3931
|
+
|
|
3932
|
+
if (index < 0) {
|
|
3933
|
+
return false;
|
|
3934
|
+
}
|
|
3935
|
+
var lastIndex = data.length - 1;
|
|
3936
|
+
if (index == lastIndex) {
|
|
3937
|
+
data.pop();
|
|
3938
|
+
} else {
|
|
3939
|
+
splice.call(data, index, 1);
|
|
3940
|
+
}
|
|
3941
|
+
--this.size;
|
|
3942
|
+
return true;
|
|
3943
|
+
}
|
|
3944
|
+
|
|
3945
|
+
/**
|
|
3946
|
+
* Gets the list cache value for `key`.
|
|
3947
|
+
*
|
|
3948
|
+
* @private
|
|
3949
|
+
* @name get
|
|
3950
|
+
* @memberOf ListCache
|
|
3951
|
+
* @param {string} key The key of the value to get.
|
|
3952
|
+
* @returns {*} Returns the entry value.
|
|
3953
|
+
*/
|
|
3954
|
+
function listCacheGet(key) {
|
|
3955
|
+
var data = this.__data__,
|
|
3956
|
+
index = assocIndexOf(data, key);
|
|
3957
|
+
|
|
3958
|
+
return index < 0 ? undefined : data[index][1];
|
|
3959
|
+
}
|
|
3960
|
+
|
|
3961
|
+
/**
|
|
3962
|
+
* Checks if a list cache value for `key` exists.
|
|
3963
|
+
*
|
|
3964
|
+
* @private
|
|
3965
|
+
* @name has
|
|
3966
|
+
* @memberOf ListCache
|
|
3967
|
+
* @param {string} key The key of the entry to check.
|
|
3968
|
+
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
|
|
3969
|
+
*/
|
|
3970
|
+
function listCacheHas(key) {
|
|
3971
|
+
return assocIndexOf(this.__data__, key) > -1;
|
|
3972
|
+
}
|
|
3973
|
+
|
|
3974
|
+
/**
|
|
3975
|
+
* Sets the list cache `key` to `value`.
|
|
3976
|
+
*
|
|
3977
|
+
* @private
|
|
3978
|
+
* @name set
|
|
3979
|
+
* @memberOf ListCache
|
|
3980
|
+
* @param {string} key The key of the value to set.
|
|
3981
|
+
* @param {*} value The value to set.
|
|
3982
|
+
* @returns {Object} Returns the list cache instance.
|
|
3983
|
+
*/
|
|
3984
|
+
function listCacheSet(key, value) {
|
|
3985
|
+
var data = this.__data__,
|
|
3986
|
+
index = assocIndexOf(data, key);
|
|
3987
|
+
|
|
3988
|
+
if (index < 0) {
|
|
3989
|
+
++this.size;
|
|
3990
|
+
data.push([key, value]);
|
|
3991
|
+
} else {
|
|
3992
|
+
data[index][1] = value;
|
|
3993
|
+
}
|
|
3994
|
+
return this;
|
|
3995
|
+
}
|
|
3996
|
+
|
|
3997
|
+
/**
|
|
3998
|
+
* Creates an list cache object.
|
|
3999
|
+
*
|
|
4000
|
+
* @private
|
|
4001
|
+
* @constructor
|
|
4002
|
+
* @param {Array} [entries] The key-value pairs to cache.
|
|
4003
|
+
*/
|
|
4004
|
+
function ListCache(entries) {
|
|
4005
|
+
var index = -1,
|
|
4006
|
+
length = entries == null ? 0 : entries.length;
|
|
4007
|
+
|
|
4008
|
+
this.clear();
|
|
4009
|
+
while (++index < length) {
|
|
4010
|
+
var entry = entries[index];
|
|
4011
|
+
this.set(entry[0], entry[1]);
|
|
4012
|
+
}
|
|
4013
|
+
}
|
|
4014
|
+
|
|
4015
|
+
// Add methods to `ListCache`.
|
|
4016
|
+
ListCache.prototype.clear = listCacheClear;
|
|
4017
|
+
ListCache.prototype['delete'] = listCacheDelete;
|
|
4018
|
+
ListCache.prototype.get = listCacheGet;
|
|
4019
|
+
ListCache.prototype.has = listCacheHas;
|
|
4020
|
+
ListCache.prototype.set = listCacheSet;
|
|
4021
|
+
|
|
4022
|
+
/* Built-in method references that are verified to be native. */
|
|
4023
|
+
var Map$1 = getNative(root, 'Map');
|
|
4024
|
+
|
|
4025
|
+
/**
|
|
4026
|
+
* Removes all key-value entries from the map.
|
|
4027
|
+
*
|
|
4028
|
+
* @private
|
|
4029
|
+
* @name clear
|
|
4030
|
+
* @memberOf MapCache
|
|
4031
|
+
*/
|
|
4032
|
+
function mapCacheClear() {
|
|
4033
|
+
this.size = 0;
|
|
4034
|
+
this.__data__ = {
|
|
4035
|
+
'hash': new Hash,
|
|
4036
|
+
'map': new (Map$1 || ListCache),
|
|
4037
|
+
'string': new Hash
|
|
4038
|
+
};
|
|
4039
|
+
}
|
|
4040
|
+
|
|
4041
|
+
/**
|
|
4042
|
+
* Checks if `value` is suitable for use as unique object key.
|
|
4043
|
+
*
|
|
4044
|
+
* @private
|
|
4045
|
+
* @param {*} value The value to check.
|
|
4046
|
+
* @returns {boolean} Returns `true` if `value` is suitable, else `false`.
|
|
4047
|
+
*/
|
|
4048
|
+
function isKeyable(value) {
|
|
4049
|
+
var type = typeof value;
|
|
4050
|
+
return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
|
|
4051
|
+
? (value !== '__proto__')
|
|
4052
|
+
: (value === null);
|
|
4053
|
+
}
|
|
4054
|
+
|
|
4055
|
+
/**
|
|
4056
|
+
* Gets the data for `map`.
|
|
4057
|
+
*
|
|
4058
|
+
* @private
|
|
4059
|
+
* @param {Object} map The map to query.
|
|
4060
|
+
* @param {string} key The reference key.
|
|
4061
|
+
* @returns {*} Returns the map data.
|
|
4062
|
+
*/
|
|
4063
|
+
function getMapData(map, key) {
|
|
4064
|
+
var data = map.__data__;
|
|
4065
|
+
return isKeyable(key)
|
|
4066
|
+
? data[typeof key == 'string' ? 'string' : 'hash']
|
|
4067
|
+
: data.map;
|
|
4068
|
+
}
|
|
4069
|
+
|
|
4070
|
+
/**
|
|
4071
|
+
* Removes `key` and its value from the map.
|
|
4072
|
+
*
|
|
4073
|
+
* @private
|
|
4074
|
+
* @name delete
|
|
4075
|
+
* @memberOf MapCache
|
|
4076
|
+
* @param {string} key The key of the value to remove.
|
|
4077
|
+
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
|
|
4078
|
+
*/
|
|
4079
|
+
function mapCacheDelete(key) {
|
|
4080
|
+
var result = getMapData(this, key)['delete'](key);
|
|
4081
|
+
this.size -= result ? 1 : 0;
|
|
4082
|
+
return result;
|
|
4083
|
+
}
|
|
4084
|
+
|
|
4085
|
+
/**
|
|
4086
|
+
* Gets the map value for `key`.
|
|
4087
|
+
*
|
|
4088
|
+
* @private
|
|
4089
|
+
* @name get
|
|
4090
|
+
* @memberOf MapCache
|
|
4091
|
+
* @param {string} key The key of the value to get.
|
|
4092
|
+
* @returns {*} Returns the entry value.
|
|
4093
|
+
*/
|
|
4094
|
+
function mapCacheGet(key) {
|
|
4095
|
+
return getMapData(this, key).get(key);
|
|
4096
|
+
}
|
|
4097
|
+
|
|
4098
|
+
/**
|
|
4099
|
+
* Checks if a map value for `key` exists.
|
|
4100
|
+
*
|
|
4101
|
+
* @private
|
|
4102
|
+
* @name has
|
|
4103
|
+
* @memberOf MapCache
|
|
4104
|
+
* @param {string} key The key of the entry to check.
|
|
4105
|
+
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
|
|
4106
|
+
*/
|
|
4107
|
+
function mapCacheHas(key) {
|
|
4108
|
+
return getMapData(this, key).has(key);
|
|
4109
|
+
}
|
|
4110
|
+
|
|
4111
|
+
/**
|
|
4112
|
+
* Sets the map `key` to `value`.
|
|
4113
|
+
*
|
|
4114
|
+
* @private
|
|
4115
|
+
* @name set
|
|
4116
|
+
* @memberOf MapCache
|
|
4117
|
+
* @param {string} key The key of the value to set.
|
|
4118
|
+
* @param {*} value The value to set.
|
|
4119
|
+
* @returns {Object} Returns the map cache instance.
|
|
4120
|
+
*/
|
|
4121
|
+
function mapCacheSet(key, value) {
|
|
4122
|
+
var data = getMapData(this, key),
|
|
4123
|
+
size = data.size;
|
|
4124
|
+
|
|
4125
|
+
data.set(key, value);
|
|
4126
|
+
this.size += data.size == size ? 0 : 1;
|
|
4127
|
+
return this;
|
|
4128
|
+
}
|
|
4129
|
+
|
|
4130
|
+
/**
|
|
4131
|
+
* Creates a map cache object to store key-value pairs.
|
|
4132
|
+
*
|
|
4133
|
+
* @private
|
|
4134
|
+
* @constructor
|
|
4135
|
+
* @param {Array} [entries] The key-value pairs to cache.
|
|
4136
|
+
*/
|
|
4137
|
+
function MapCache(entries) {
|
|
4138
|
+
var index = -1,
|
|
4139
|
+
length = entries == null ? 0 : entries.length;
|
|
4140
|
+
|
|
4141
|
+
this.clear();
|
|
4142
|
+
while (++index < length) {
|
|
4143
|
+
var entry = entries[index];
|
|
4144
|
+
this.set(entry[0], entry[1]);
|
|
4145
|
+
}
|
|
4146
|
+
}
|
|
4147
|
+
|
|
4148
|
+
// Add methods to `MapCache`.
|
|
4149
|
+
MapCache.prototype.clear = mapCacheClear;
|
|
4150
|
+
MapCache.prototype['delete'] = mapCacheDelete;
|
|
4151
|
+
MapCache.prototype.get = mapCacheGet;
|
|
4152
|
+
MapCache.prototype.has = mapCacheHas;
|
|
4153
|
+
MapCache.prototype.set = mapCacheSet;
|
|
4154
|
+
|
|
4155
|
+
/**
|
|
4156
|
+
* Converts `value` to a string. An empty string is returned for `null`
|
|
4157
|
+
* and `undefined` values. The sign of `-0` is preserved.
|
|
4158
|
+
*
|
|
4159
|
+
* @static
|
|
4160
|
+
* @memberOf _
|
|
4161
|
+
* @since 4.0.0
|
|
4162
|
+
* @category Lang
|
|
4163
|
+
* @param {*} value The value to convert.
|
|
4164
|
+
* @returns {string} Returns the converted string.
|
|
4165
|
+
* @example
|
|
4166
|
+
*
|
|
4167
|
+
* _.toString(null);
|
|
4168
|
+
* // => ''
|
|
4169
|
+
*
|
|
4170
|
+
* _.toString(-0);
|
|
4171
|
+
* // => '-0'
|
|
4172
|
+
*
|
|
4173
|
+
* _.toString([1, 2, 3]);
|
|
4174
|
+
* // => '1,2,3'
|
|
4175
|
+
*/
|
|
4176
|
+
function toString(value) {
|
|
4177
|
+
return value == null ? '' : baseToString(value);
|
|
4178
|
+
}
|
|
4179
|
+
|
|
4180
|
+
/** Built-in value references. */
|
|
4181
|
+
var getPrototype = overArg(Object.getPrototypeOf, Object);
|
|
4182
|
+
|
|
4183
|
+
/** `Object#toString` result references. */
|
|
4184
|
+
var objectTag = '[object Object]';
|
|
4185
|
+
|
|
4186
|
+
/** Used for built-in method references. */
|
|
4187
|
+
var funcProto = Function.prototype,
|
|
4188
|
+
objectProto = Object.prototype;
|
|
4189
|
+
|
|
4190
|
+
/** Used to resolve the decompiled source of functions. */
|
|
4191
|
+
var funcToString = funcProto.toString;
|
|
4192
|
+
|
|
4193
|
+
/** Used to check objects for own properties. */
|
|
4194
|
+
var hasOwnProperty = objectProto.hasOwnProperty;
|
|
4195
|
+
|
|
4196
|
+
/** Used to infer the `Object` constructor. */
|
|
4197
|
+
var objectCtorString = funcToString.call(Object);
|
|
4198
|
+
|
|
4199
|
+
/**
|
|
4200
|
+
* Checks if `value` is a plain object, that is, an object created by the
|
|
4201
|
+
* `Object` constructor or one with a `[[Prototype]]` of `null`.
|
|
4202
|
+
*
|
|
4203
|
+
* @static
|
|
4204
|
+
* @memberOf _
|
|
4205
|
+
* @since 0.8.0
|
|
4206
|
+
* @category Lang
|
|
4207
|
+
* @param {*} value The value to check.
|
|
4208
|
+
* @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
|
|
4209
|
+
* @example
|
|
4210
|
+
*
|
|
4211
|
+
* function Foo() {
|
|
4212
|
+
* this.a = 1;
|
|
4213
|
+
* }
|
|
4214
|
+
*
|
|
4215
|
+
* _.isPlainObject(new Foo);
|
|
4216
|
+
* // => false
|
|
4217
|
+
*
|
|
4218
|
+
* _.isPlainObject([1, 2, 3]);
|
|
4219
|
+
* // => false
|
|
4220
|
+
*
|
|
4221
|
+
* _.isPlainObject({ 'x': 0, 'y': 0 });
|
|
4222
|
+
* // => true
|
|
4223
|
+
*
|
|
4224
|
+
* _.isPlainObject(Object.create(null));
|
|
4225
|
+
* // => true
|
|
4226
|
+
*/
|
|
4227
|
+
function isPlainObject(value) {
|
|
4228
|
+
if (!isObjectLike(value) || baseGetTag(value) != objectTag) {
|
|
4229
|
+
return false;
|
|
4230
|
+
}
|
|
4231
|
+
var proto = getPrototype(value);
|
|
4232
|
+
if (proto === null) {
|
|
4233
|
+
return true;
|
|
4234
|
+
}
|
|
4235
|
+
var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;
|
|
4236
|
+
return typeof Ctor == 'function' && Ctor instanceof Ctor &&
|
|
4237
|
+
funcToString.call(Ctor) == objectCtorString;
|
|
4238
|
+
}
|
|
4239
|
+
|
|
4240
|
+
/* Built-in method references for those with the same name as other `lodash` methods. */
|
|
4241
|
+
var nativeIsFinite = root.isFinite,
|
|
4242
|
+
nativeMin = Math.min;
|
|
4243
|
+
|
|
4244
|
+
/**
|
|
4245
|
+
* Creates a function like `_.round`.
|
|
4246
|
+
*
|
|
4247
|
+
* @private
|
|
4248
|
+
* @param {string} methodName The name of the `Math` method to use when rounding.
|
|
4249
|
+
* @returns {Function} Returns the new round function.
|
|
4250
|
+
*/
|
|
4251
|
+
function createRound(methodName) {
|
|
4252
|
+
var func = Math[methodName];
|
|
4253
|
+
return function(number, precision) {
|
|
4254
|
+
number = toNumber(number);
|
|
4255
|
+
precision = precision == null ? 0 : nativeMin(toInteger(precision), 292);
|
|
4256
|
+
if (precision && nativeIsFinite(number)) {
|
|
4257
|
+
// Shift with exponential notation to avoid floating-point issues.
|
|
4258
|
+
// See [MDN](https://mdn.io/round#Examples) for more details.
|
|
4259
|
+
var pair = (toString(number) + 'e').split('e'),
|
|
4260
|
+
value = func(pair[0] + 'e' + (+pair[1] + precision));
|
|
4261
|
+
|
|
4262
|
+
pair = (toString(value) + 'e').split('e');
|
|
4263
|
+
return +(pair[0] + 'e' + (+pair[1] - precision));
|
|
4264
|
+
}
|
|
4265
|
+
return func(number);
|
|
4266
|
+
};
|
|
4267
|
+
}
|
|
4268
|
+
|
|
4269
|
+
/**
|
|
4270
|
+
* Removes all key-value entries from the stack.
|
|
4271
|
+
*
|
|
4272
|
+
* @private
|
|
4273
|
+
* @name clear
|
|
4274
|
+
* @memberOf Stack
|
|
4275
|
+
*/
|
|
4276
|
+
function stackClear() {
|
|
4277
|
+
this.__data__ = new ListCache;
|
|
4278
|
+
this.size = 0;
|
|
4279
|
+
}
|
|
4280
|
+
|
|
4281
|
+
/**
|
|
4282
|
+
* Removes `key` and its value from the stack.
|
|
4283
|
+
*
|
|
4284
|
+
* @private
|
|
4285
|
+
* @name delete
|
|
4286
|
+
* @memberOf Stack
|
|
4287
|
+
* @param {string} key The key of the value to remove.
|
|
4288
|
+
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
|
|
4289
|
+
*/
|
|
4290
|
+
function stackDelete(key) {
|
|
4291
|
+
var data = this.__data__,
|
|
4292
|
+
result = data['delete'](key);
|
|
4293
|
+
|
|
4294
|
+
this.size = data.size;
|
|
4295
|
+
return result;
|
|
4296
|
+
}
|
|
4297
|
+
|
|
4298
|
+
/**
|
|
4299
|
+
* Gets the stack value for `key`.
|
|
4300
|
+
*
|
|
4301
|
+
* @private
|
|
4302
|
+
* @name get
|
|
4303
|
+
* @memberOf Stack
|
|
4304
|
+
* @param {string} key The key of the value to get.
|
|
4305
|
+
* @returns {*} Returns the entry value.
|
|
4306
|
+
*/
|
|
4307
|
+
function stackGet(key) {
|
|
4308
|
+
return this.__data__.get(key);
|
|
4309
|
+
}
|
|
4310
|
+
|
|
4311
|
+
/**
|
|
4312
|
+
* Checks if a stack value for `key` exists.
|
|
4313
|
+
*
|
|
4314
|
+
* @private
|
|
4315
|
+
* @name has
|
|
4316
|
+
* @memberOf Stack
|
|
4317
|
+
* @param {string} key The key of the entry to check.
|
|
4318
|
+
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
|
|
4319
|
+
*/
|
|
4320
|
+
function stackHas(key) {
|
|
4321
|
+
return this.__data__.has(key);
|
|
4322
|
+
}
|
|
4323
|
+
|
|
4324
|
+
/** Used as the size to enable large array optimizations. */
|
|
4325
|
+
var LARGE_ARRAY_SIZE = 200;
|
|
4326
|
+
|
|
4327
|
+
/**
|
|
4328
|
+
* Sets the stack `key` to `value`.
|
|
4329
|
+
*
|
|
4330
|
+
* @private
|
|
4331
|
+
* @name set
|
|
4332
|
+
* @memberOf Stack
|
|
4333
|
+
* @param {string} key The key of the value to set.
|
|
4334
|
+
* @param {*} value The value to set.
|
|
4335
|
+
* @returns {Object} Returns the stack cache instance.
|
|
4336
|
+
*/
|
|
4337
|
+
function stackSet(key, value) {
|
|
4338
|
+
var data = this.__data__;
|
|
4339
|
+
if (data instanceof ListCache) {
|
|
4340
|
+
var pairs = data.__data__;
|
|
4341
|
+
if (!Map$1 || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
|
|
4342
|
+
pairs.push([key, value]);
|
|
4343
|
+
this.size = ++data.size;
|
|
4344
|
+
return this;
|
|
4345
|
+
}
|
|
4346
|
+
data = this.__data__ = new MapCache(pairs);
|
|
4347
|
+
}
|
|
4348
|
+
data.set(key, value);
|
|
4349
|
+
this.size = data.size;
|
|
4350
|
+
return this;
|
|
4351
|
+
}
|
|
4352
|
+
|
|
4353
|
+
/**
|
|
4354
|
+
* Creates a stack cache object to store key-value pairs.
|
|
4355
|
+
*
|
|
4356
|
+
* @private
|
|
4357
|
+
* @constructor
|
|
4358
|
+
* @param {Array} [entries] The key-value pairs to cache.
|
|
4359
|
+
*/
|
|
4360
|
+
function Stack(entries) {
|
|
4361
|
+
var data = this.__data__ = new ListCache(entries);
|
|
4362
|
+
this.size = data.size;
|
|
4363
|
+
}
|
|
4364
|
+
|
|
4365
|
+
// Add methods to `Stack`.
|
|
4366
|
+
Stack.prototype.clear = stackClear;
|
|
4367
|
+
Stack.prototype['delete'] = stackDelete;
|
|
4368
|
+
Stack.prototype.get = stackGet;
|
|
4369
|
+
Stack.prototype.has = stackHas;
|
|
4370
|
+
Stack.prototype.set = stackSet;
|
|
4371
|
+
|
|
4372
|
+
/** Detect free variable `exports`. */
|
|
4373
|
+
var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;
|
|
4374
|
+
|
|
4375
|
+
/** Detect free variable `module`. */
|
|
4376
|
+
var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;
|
|
4377
|
+
|
|
4378
|
+
/** Detect the popular CommonJS extension `module.exports`. */
|
|
4379
|
+
var moduleExports = freeModule && freeModule.exports === freeExports;
|
|
4380
|
+
|
|
4381
|
+
/** Built-in value references. */
|
|
4382
|
+
var Buffer = moduleExports ? root.Buffer : undefined;
|
|
4383
|
+
Buffer ? Buffer.allocUnsafe : undefined;
|
|
4384
|
+
|
|
4385
|
+
/**
|
|
4386
|
+
* Creates a clone of `buffer`.
|
|
4387
|
+
*
|
|
4388
|
+
* @private
|
|
4389
|
+
* @param {Buffer} buffer The buffer to clone.
|
|
4390
|
+
* @param {boolean} [isDeep] Specify a deep clone.
|
|
4391
|
+
* @returns {Buffer} Returns the cloned buffer.
|
|
4392
|
+
*/
|
|
4393
|
+
function cloneBuffer(buffer, isDeep) {
|
|
4394
|
+
{
|
|
4395
|
+
return buffer.slice();
|
|
4396
|
+
}
|
|
4397
|
+
}
|
|
4398
|
+
|
|
4399
|
+
/** Built-in value references. */
|
|
4400
|
+
var Uint8Array$1 = root.Uint8Array;
|
|
4401
|
+
|
|
4402
|
+
/**
|
|
4403
|
+
* Creates a clone of `arrayBuffer`.
|
|
4404
|
+
*
|
|
4405
|
+
* @private
|
|
4406
|
+
* @param {ArrayBuffer} arrayBuffer The array buffer to clone.
|
|
4407
|
+
* @returns {ArrayBuffer} Returns the cloned array buffer.
|
|
4408
|
+
*/
|
|
4409
|
+
function cloneArrayBuffer(arrayBuffer) {
|
|
4410
|
+
var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
|
|
4411
|
+
new Uint8Array$1(result).set(new Uint8Array$1(arrayBuffer));
|
|
4412
|
+
return result;
|
|
4413
|
+
}
|
|
4414
|
+
|
|
4415
|
+
/**
|
|
4416
|
+
* Creates a clone of `typedArray`.
|
|
4417
|
+
*
|
|
4418
|
+
* @private
|
|
4419
|
+
* @param {Object} typedArray The typed array to clone.
|
|
4420
|
+
* @param {boolean} [isDeep] Specify a deep clone.
|
|
4421
|
+
* @returns {Object} Returns the cloned typed array.
|
|
4422
|
+
*/
|
|
4423
|
+
function cloneTypedArray(typedArray, isDeep) {
|
|
4424
|
+
var buffer = cloneArrayBuffer(typedArray.buffer) ;
|
|
4425
|
+
return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
|
|
4426
|
+
}
|
|
4427
|
+
|
|
4428
|
+
/**
|
|
4429
|
+
* Initializes an object clone.
|
|
4430
|
+
*
|
|
4431
|
+
* @private
|
|
4432
|
+
* @param {Object} object The object to clone.
|
|
4433
|
+
* @returns {Object} Returns the initialized clone.
|
|
4434
|
+
*/
|
|
4435
|
+
function initCloneObject(object) {
|
|
4436
|
+
return (typeof object.constructor == 'function' && !isPrototype(object))
|
|
4437
|
+
? baseCreate(getPrototype(object))
|
|
4438
|
+
: {};
|
|
4439
|
+
}
|
|
4440
|
+
|
|
4441
|
+
/**
|
|
4442
|
+
* Creates a base function for methods like `_.forIn` and `_.forOwn`.
|
|
4443
|
+
*
|
|
4444
|
+
* @private
|
|
4445
|
+
* @param {boolean} [fromRight] Specify iterating from right to left.
|
|
4446
|
+
* @returns {Function} Returns the new base function.
|
|
4447
|
+
*/
|
|
4448
|
+
function createBaseFor(fromRight) {
|
|
4449
|
+
return function(object, iteratee, keysFunc) {
|
|
4450
|
+
var index = -1,
|
|
4451
|
+
iterable = Object(object),
|
|
4452
|
+
props = keysFunc(object),
|
|
4453
|
+
length = props.length;
|
|
4454
|
+
|
|
4455
|
+
while (length--) {
|
|
4456
|
+
var key = props[++index];
|
|
4457
|
+
if (iteratee(iterable[key], key, iterable) === false) {
|
|
4458
|
+
break;
|
|
4459
|
+
}
|
|
4460
|
+
}
|
|
4461
|
+
return object;
|
|
4462
|
+
};
|
|
4463
|
+
}
|
|
4464
|
+
|
|
4465
|
+
/**
|
|
4466
|
+
* The base implementation of `baseForOwn` which iterates over `object`
|
|
4467
|
+
* properties returned by `keysFunc` and invokes `iteratee` for each property.
|
|
4468
|
+
* Iteratee functions may exit iteration early by explicitly returning `false`.
|
|
4469
|
+
*
|
|
4470
|
+
* @private
|
|
4471
|
+
* @param {Object} object The object to iterate over.
|
|
4472
|
+
* @param {Function} iteratee The function invoked per iteration.
|
|
4473
|
+
* @param {Function} keysFunc The function to get the keys of `object`.
|
|
4474
|
+
* @returns {Object} Returns `object`.
|
|
4475
|
+
*/
|
|
4476
|
+
var baseFor = createBaseFor();
|
|
4477
|
+
|
|
4478
|
+
/**
|
|
4479
|
+
* This function is like `assignValue` except that it doesn't assign
|
|
4480
|
+
* `undefined` values.
|
|
4481
|
+
*
|
|
4482
|
+
* @private
|
|
4483
|
+
* @param {Object} object The object to modify.
|
|
4484
|
+
* @param {string} key The key of the property to assign.
|
|
4485
|
+
* @param {*} value The value to assign.
|
|
4486
|
+
*/
|
|
4487
|
+
function assignMergeValue(object, key, value) {
|
|
4488
|
+
if ((value !== undefined && !eq(object[key], value)) ||
|
|
4489
|
+
(value === undefined && !(key in object))) {
|
|
4490
|
+
baseAssignValue(object, key, value);
|
|
4491
|
+
}
|
|
4492
|
+
}
|
|
4493
|
+
|
|
4494
|
+
/**
|
|
4495
|
+
* This method is like `_.isArrayLike` except that it also checks if `value`
|
|
4496
|
+
* is an object.
|
|
4497
|
+
*
|
|
4498
|
+
* @static
|
|
4499
|
+
* @memberOf _
|
|
4500
|
+
* @since 4.0.0
|
|
4501
|
+
* @category Lang
|
|
4502
|
+
* @param {*} value The value to check.
|
|
4503
|
+
* @returns {boolean} Returns `true` if `value` is an array-like object,
|
|
4504
|
+
* else `false`.
|
|
4505
|
+
* @example
|
|
4506
|
+
*
|
|
4507
|
+
* _.isArrayLikeObject([1, 2, 3]);
|
|
4508
|
+
* // => true
|
|
4509
|
+
*
|
|
4510
|
+
* _.isArrayLikeObject(document.body.children);
|
|
4511
|
+
* // => true
|
|
4512
|
+
*
|
|
4513
|
+
* _.isArrayLikeObject('abc');
|
|
4514
|
+
* // => false
|
|
4515
|
+
*
|
|
4516
|
+
* _.isArrayLikeObject(_.noop);
|
|
4517
|
+
* // => false
|
|
4518
|
+
*/
|
|
4519
|
+
function isArrayLikeObject(value) {
|
|
4520
|
+
return isObjectLike(value) && isArrayLike(value);
|
|
4521
|
+
}
|
|
4522
|
+
|
|
4523
|
+
/**
|
|
4524
|
+
* Gets the value at `key`, unless `key` is "__proto__" or "constructor".
|
|
4525
|
+
*
|
|
4526
|
+
* @private
|
|
4527
|
+
* @param {Object} object The object to query.
|
|
4528
|
+
* @param {string} key The key of the property to get.
|
|
4529
|
+
* @returns {*} Returns the property value.
|
|
4530
|
+
*/
|
|
4531
|
+
function safeGet(object, key) {
|
|
4532
|
+
if (key === 'constructor' && typeof object[key] === 'function') {
|
|
4533
|
+
return;
|
|
4534
|
+
}
|
|
4535
|
+
|
|
4536
|
+
if (key == '__proto__') {
|
|
4537
|
+
return;
|
|
4538
|
+
}
|
|
4539
|
+
|
|
4540
|
+
return object[key];
|
|
2293
4541
|
}
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
4542
|
+
|
|
4543
|
+
/**
|
|
4544
|
+
* Converts `value` to a plain object flattening inherited enumerable string
|
|
4545
|
+
* keyed properties of `value` to own properties of the plain object.
|
|
4546
|
+
*
|
|
4547
|
+
* @static
|
|
4548
|
+
* @memberOf _
|
|
4549
|
+
* @since 3.0.0
|
|
4550
|
+
* @category Lang
|
|
4551
|
+
* @param {*} value The value to convert.
|
|
4552
|
+
* @returns {Object} Returns the converted plain object.
|
|
4553
|
+
* @example
|
|
4554
|
+
*
|
|
4555
|
+
* function Foo() {
|
|
4556
|
+
* this.b = 2;
|
|
4557
|
+
* }
|
|
4558
|
+
*
|
|
4559
|
+
* Foo.prototype.c = 3;
|
|
4560
|
+
*
|
|
4561
|
+
* _.assign({ 'a': 1 }, new Foo);
|
|
4562
|
+
* // => { 'a': 1, 'b': 2 }
|
|
4563
|
+
*
|
|
4564
|
+
* _.assign({ 'a': 1 }, _.toPlainObject(new Foo));
|
|
4565
|
+
* // => { 'a': 1, 'b': 2, 'c': 3 }
|
|
4566
|
+
*/
|
|
4567
|
+
function toPlainObject(value) {
|
|
4568
|
+
return copyObject(value, keysIn(value));
|
|
4569
|
+
}
|
|
4570
|
+
|
|
4571
|
+
/**
|
|
4572
|
+
* A specialized version of `baseMerge` for arrays and objects which performs
|
|
4573
|
+
* deep merges and tracks traversed objects enabling objects with circular
|
|
4574
|
+
* references to be merged.
|
|
4575
|
+
*
|
|
4576
|
+
* @private
|
|
4577
|
+
* @param {Object} object The destination object.
|
|
4578
|
+
* @param {Object} source The source object.
|
|
4579
|
+
* @param {string} key The key of the value to merge.
|
|
4580
|
+
* @param {number} srcIndex The index of `source`.
|
|
4581
|
+
* @param {Function} mergeFunc The function to merge values.
|
|
4582
|
+
* @param {Function} [customizer] The function to customize assigned values.
|
|
4583
|
+
* @param {Object} [stack] Tracks traversed source values and their merged
|
|
4584
|
+
* counterparts.
|
|
4585
|
+
*/
|
|
4586
|
+
function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
|
|
4587
|
+
var objValue = safeGet(object, key),
|
|
4588
|
+
srcValue = safeGet(source, key),
|
|
4589
|
+
stacked = stack.get(srcValue);
|
|
4590
|
+
|
|
4591
|
+
if (stacked) {
|
|
4592
|
+
assignMergeValue(object, key, stacked);
|
|
4593
|
+
return;
|
|
4594
|
+
}
|
|
4595
|
+
var newValue = customizer
|
|
4596
|
+
? customizer(objValue, srcValue, (key + ''), object, source, stack)
|
|
4597
|
+
: undefined;
|
|
4598
|
+
|
|
4599
|
+
var isCommon = newValue === undefined;
|
|
4600
|
+
|
|
4601
|
+
if (isCommon) {
|
|
4602
|
+
var isArr = isArray(srcValue),
|
|
4603
|
+
isBuff = !isArr && isBuffer(srcValue),
|
|
4604
|
+
isTyped = !isArr && !isBuff && isTypedArray(srcValue);
|
|
4605
|
+
|
|
4606
|
+
newValue = srcValue;
|
|
4607
|
+
if (isArr || isBuff || isTyped) {
|
|
4608
|
+
if (isArray(objValue)) {
|
|
4609
|
+
newValue = objValue;
|
|
4610
|
+
}
|
|
4611
|
+
else if (isArrayLikeObject(objValue)) {
|
|
4612
|
+
newValue = copyArray(objValue);
|
|
4613
|
+
}
|
|
4614
|
+
else if (isBuff) {
|
|
4615
|
+
isCommon = false;
|
|
4616
|
+
newValue = cloneBuffer(srcValue);
|
|
4617
|
+
}
|
|
4618
|
+
else if (isTyped) {
|
|
4619
|
+
isCommon = false;
|
|
4620
|
+
newValue = cloneTypedArray(srcValue);
|
|
4621
|
+
}
|
|
4622
|
+
else {
|
|
4623
|
+
newValue = [];
|
|
4624
|
+
}
|
|
4625
|
+
}
|
|
4626
|
+
else if (isPlainObject(srcValue) || isArguments(srcValue)) {
|
|
4627
|
+
newValue = objValue;
|
|
4628
|
+
if (isArguments(objValue)) {
|
|
4629
|
+
newValue = toPlainObject(objValue);
|
|
4630
|
+
}
|
|
4631
|
+
else if (!isObject(objValue) || isFunction(objValue)) {
|
|
4632
|
+
newValue = initCloneObject(srcValue);
|
|
4633
|
+
}
|
|
2308
4634
|
}
|
|
2309
4635
|
else {
|
|
2310
|
-
|
|
2311
|
-
}
|
|
4636
|
+
isCommon = false;
|
|
4637
|
+
}
|
|
4638
|
+
}
|
|
4639
|
+
if (isCommon) {
|
|
4640
|
+
// Recursively merge objects and arrays (susceptible to call stack limits).
|
|
4641
|
+
stack.set(srcValue, newValue);
|
|
4642
|
+
mergeFunc(newValue, srcValue, srcIndex, customizer, stack);
|
|
4643
|
+
stack['delete'](srcValue);
|
|
4644
|
+
}
|
|
4645
|
+
assignMergeValue(object, key, newValue);
|
|
2312
4646
|
}
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
4647
|
+
|
|
4648
|
+
/**
|
|
4649
|
+
* The base implementation of `_.merge` without support for multiple sources.
|
|
4650
|
+
*
|
|
4651
|
+
* @private
|
|
4652
|
+
* @param {Object} object The destination object.
|
|
4653
|
+
* @param {Object} source The source object.
|
|
4654
|
+
* @param {number} srcIndex The index of `source`.
|
|
4655
|
+
* @param {Function} [customizer] The function to customize merged values.
|
|
4656
|
+
* @param {Object} [stack] Tracks traversed source values and their merged
|
|
4657
|
+
* counterparts.
|
|
4658
|
+
*/
|
|
4659
|
+
function baseMerge(object, source, srcIndex, customizer, stack) {
|
|
4660
|
+
if (object === source) {
|
|
4661
|
+
return;
|
|
4662
|
+
}
|
|
4663
|
+
baseFor(source, function(srcValue, key) {
|
|
4664
|
+
stack || (stack = new Stack);
|
|
4665
|
+
if (isObject(srcValue)) {
|
|
4666
|
+
baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
|
|
2319
4667
|
}
|
|
2320
|
-
else
|
|
2321
|
-
|
|
4668
|
+
else {
|
|
4669
|
+
var newValue = customizer
|
|
4670
|
+
? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack)
|
|
4671
|
+
: undefined;
|
|
4672
|
+
|
|
4673
|
+
if (newValue === undefined) {
|
|
4674
|
+
newValue = srcValue;
|
|
4675
|
+
}
|
|
4676
|
+
assignMergeValue(object, key, newValue);
|
|
2322
4677
|
}
|
|
2323
|
-
|
|
2324
|
-
}
|
|
2325
|
-
function isInvalidPosition(positonConfig) {
|
|
2326
|
-
return (isNoPosture(positonConfig.postureX) &&
|
|
2327
|
-
isNoPosture(positonConfig.postureY) &&
|
|
2328
|
-
isNoPosture(positonConfig.postureTheta));
|
|
2329
|
-
}
|
|
2330
|
-
function isOutOfRange(positonConfig) {
|
|
2331
|
-
return (positonConfig.postureX != null &&
|
|
2332
|
-
Math.abs(positonConfig.postureX) > 1000 * SCALE_FACTOR &&
|
|
2333
|
-
positonConfig.postureY != null &&
|
|
2334
|
-
Math.abs(positonConfig.postureY) > 1000 * SCALE_FACTOR);
|
|
4678
|
+
}, keysIn);
|
|
2335
4679
|
}
|
|
2336
4680
|
|
|
4681
|
+
/**
|
|
4682
|
+
* Computes `number` rounded down to `precision`.
|
|
4683
|
+
*
|
|
4684
|
+
* @static
|
|
4685
|
+
* @memberOf _
|
|
4686
|
+
* @since 3.10.0
|
|
4687
|
+
* @category Math
|
|
4688
|
+
* @param {number} number The number to round down.
|
|
4689
|
+
* @param {number} [precision=0] The precision to round down to.
|
|
4690
|
+
* @returns {number} Returns the rounded down number.
|
|
4691
|
+
* @example
|
|
4692
|
+
*
|
|
4693
|
+
* _.floor(4.006);
|
|
4694
|
+
* // => 4
|
|
4695
|
+
*
|
|
4696
|
+
* _.floor(0.046, 2);
|
|
4697
|
+
* // => 0.04
|
|
4698
|
+
*
|
|
4699
|
+
* _.floor(4060, -2);
|
|
4700
|
+
* // => 4000
|
|
4701
|
+
*/
|
|
4702
|
+
var floor = createRound('floor');
|
|
4703
|
+
|
|
4704
|
+
/**
|
|
4705
|
+
* This method is like `_.assign` except that it recursively merges own and
|
|
4706
|
+
* inherited enumerable string keyed properties of source objects into the
|
|
4707
|
+
* destination object. Source properties that resolve to `undefined` are
|
|
4708
|
+
* skipped if a destination value exists. Array and plain object properties
|
|
4709
|
+
* are merged recursively. Other objects and value types are overridden by
|
|
4710
|
+
* assignment. Source objects are applied from left to right. Subsequent
|
|
4711
|
+
* sources overwrite property assignments of previous sources.
|
|
4712
|
+
*
|
|
4713
|
+
* **Note:** This method mutates `object`.
|
|
4714
|
+
*
|
|
4715
|
+
* @static
|
|
4716
|
+
* @memberOf _
|
|
4717
|
+
* @since 0.5.0
|
|
4718
|
+
* @category Object
|
|
4719
|
+
* @param {Object} object The destination object.
|
|
4720
|
+
* @param {...Object} [sources] The source objects.
|
|
4721
|
+
* @returns {Object} Returns `object`.
|
|
4722
|
+
* @example
|
|
4723
|
+
*
|
|
4724
|
+
* var object = {
|
|
4725
|
+
* 'a': [{ 'b': 2 }, { 'd': 4 }]
|
|
4726
|
+
* };
|
|
4727
|
+
*
|
|
4728
|
+
* var other = {
|
|
4729
|
+
* 'a': [{ 'c': 3 }, { 'e': 5 }]
|
|
4730
|
+
* };
|
|
4731
|
+
*
|
|
4732
|
+
* _.merge(object, other);
|
|
4733
|
+
* // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }
|
|
4734
|
+
*/
|
|
4735
|
+
var merge = createAssigner(function(object, source, srcIndex) {
|
|
4736
|
+
baseMerge(object, source, srcIndex);
|
|
4737
|
+
});
|
|
4738
|
+
|
|
4739
|
+
/**
|
|
4740
|
+
* Computes `number` rounded to `precision`.
|
|
4741
|
+
*
|
|
4742
|
+
* @static
|
|
4743
|
+
* @memberOf _
|
|
4744
|
+
* @since 3.10.0
|
|
4745
|
+
* @category Math
|
|
4746
|
+
* @param {number} number The number to round.
|
|
4747
|
+
* @param {number} [precision=0] The precision to round to.
|
|
4748
|
+
* @returns {number} Returns the rounded number.
|
|
4749
|
+
* @example
|
|
4750
|
+
*
|
|
4751
|
+
* _.round(4.006);
|
|
4752
|
+
* // => 4
|
|
4753
|
+
*
|
|
4754
|
+
* _.round(4.006, 2);
|
|
4755
|
+
* // => 4.01
|
|
4756
|
+
*
|
|
4757
|
+
* _.round(4060, -2);
|
|
4758
|
+
* // => 4100
|
|
4759
|
+
*/
|
|
4760
|
+
var round = createRound('round');
|
|
4761
|
+
|
|
2337
4762
|
/**
|
|
2338
4763
|
* 默认航向相对于canvas的偏移角度: 航向默认是东
|
|
2339
4764
|
*/
|
|
@@ -2654,7 +5079,7 @@ class BoundaryBorderLayer extends BaseLayer {
|
|
|
2654
5079
|
* 创建直接路径(type=2)
|
|
2655
5080
|
*/
|
|
2656
5081
|
createDirectPath(svgGroup, points, style) {
|
|
2657
|
-
const strokeColor = style.
|
|
5082
|
+
const strokeColor = style.lineColor;
|
|
2658
5083
|
const lineWidth = dp2px(style.lineWidth || 3);
|
|
2659
5084
|
const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
|
|
2660
5085
|
// 构建路径数据
|
|
@@ -2683,7 +5108,7 @@ class BoundaryBorderLayer extends BaseLayer {
|
|
|
2683
5108
|
* 使用PathMeasure逻辑创建平行路径(type=1)
|
|
2684
5109
|
*/
|
|
2685
5110
|
createParallelPathsWithMeasure(svgGroup, points, style) {
|
|
2686
|
-
const strokeColor = style.
|
|
5111
|
+
const strokeColor = style.lineColor;
|
|
2687
5112
|
const lineWidth = dp2px(style.lineWidth || 3);
|
|
2688
5113
|
// 获取当前SVG的缩放级别,计算固定屏幕像素间距
|
|
2689
5114
|
const fixedScreenDistance = lineWidth; // 固定的屏幕像素距离
|
|
@@ -2849,8 +5274,8 @@ class AntennaLayer extends BaseLayer {
|
|
|
2849
5274
|
}
|
|
2850
5275
|
const image = document.createElementNS('http://www.w3.org/2000/svg', 'image');
|
|
2851
5276
|
// 图片居中定位
|
|
2852
|
-
const x =
|
|
2853
|
-
const y =
|
|
5277
|
+
const x = center[0] - size / 2;
|
|
5278
|
+
const y = center[1] - size / 2;
|
|
2854
5279
|
image.setAttribute('x', x.toString());
|
|
2855
5280
|
image.setAttribute('y', y.toString());
|
|
2856
5281
|
image.setAttribute('width', `${size}px`);
|
|
@@ -3031,19 +5456,19 @@ class BoundaryDataBuilder {
|
|
|
3031
5456
|
/**
|
|
3032
5457
|
* 从地图元素创建边界数据
|
|
3033
5458
|
*/
|
|
3034
|
-
static fromMapElement(element) {
|
|
5459
|
+
static fromMapElement(element, style) {
|
|
3035
5460
|
const convertedPoints = convertPointsFormat(element.points);
|
|
3036
5461
|
if (!convertedPoints || convertedPoints.length < 3)
|
|
3037
5462
|
return null;
|
|
3038
|
-
const drawElement = this.create('boundary', convertedPoints,
|
|
5463
|
+
const drawElement = this.create('boundary', convertedPoints, style);
|
|
3039
5464
|
drawElement.originalData = element; // 保存完整的原始数据
|
|
3040
5465
|
return drawElement;
|
|
3041
5466
|
}
|
|
3042
|
-
static createBoundaryBorder(element) {
|
|
5467
|
+
static createBoundaryBorder(element, style) {
|
|
3043
5468
|
const convertedPoints = convertPointsFormat(element.points);
|
|
3044
5469
|
if (!convertedPoints || convertedPoints.length < 3)
|
|
3045
5470
|
return null;
|
|
3046
|
-
const drawElement = this.create('boundary_border', convertedPoints,
|
|
5471
|
+
const drawElement = this.create('boundary_border', convertedPoints, style);
|
|
3047
5472
|
drawElement.originalData = element; // 保存完整的原始数据
|
|
3048
5473
|
return drawElement;
|
|
3049
5474
|
}
|
|
@@ -3066,27 +5491,22 @@ class ObstacleDataBuilder {
|
|
|
3066
5491
|
/**
|
|
3067
5492
|
* 从地图元素创建障碍物数据
|
|
3068
5493
|
*/
|
|
3069
|
-
static fromMapElement(element) {
|
|
5494
|
+
static fromMapElement(element, style) {
|
|
3070
5495
|
const convertedPoints = convertPointsFormat(element.points);
|
|
3071
5496
|
if (!convertedPoints || convertedPoints.length < 3)
|
|
3072
5497
|
return null;
|
|
3073
|
-
const drawElement = this.create(convertedPoints,
|
|
5498
|
+
const drawElement = this.create(convertedPoints, style);
|
|
3074
5499
|
drawElement.originalData = element; // 保存完整的原始数据
|
|
3075
5500
|
return drawElement;
|
|
3076
5501
|
}
|
|
3077
5502
|
/**
|
|
3078
5503
|
* 创建时间限制障碍物多边形数据
|
|
3079
5504
|
*/
|
|
3080
|
-
static createTimeLimitObstacle(element) {
|
|
5505
|
+
static createTimeLimitObstacle(element, style) {
|
|
3081
5506
|
const convertedPoints = convertPointsFormat(element.points);
|
|
3082
5507
|
if (!convertedPoints || convertedPoints.length < 3)
|
|
3083
5508
|
return null;
|
|
3084
|
-
const drawElement = this.create(convertedPoints,
|
|
3085
|
-
strokeColor: DEFAULT_STYLES.OBSTACLE.strokeColor,
|
|
3086
|
-
fillColor: 'rgba(255, 192, 203, 0.3)', // 粉色半透明填充
|
|
3087
|
-
lineWidth: 2,
|
|
3088
|
-
opacity: 0.8,
|
|
3089
|
-
});
|
|
5509
|
+
const drawElement = this.create(convertedPoints, style);
|
|
3090
5510
|
drawElement.originalData = element; // 保存完整的原始数据
|
|
3091
5511
|
return drawElement;
|
|
3092
5512
|
}
|
|
@@ -3109,12 +5529,12 @@ class ChargingPileDataBuilder {
|
|
|
3109
5529
|
/**
|
|
3110
5530
|
* 从地图元素创建充电桩数据
|
|
3111
5531
|
*/
|
|
3112
|
-
static fromMapElement(element) {
|
|
5532
|
+
static fromMapElement(element, style) {
|
|
3113
5533
|
const elements = [];
|
|
3114
5534
|
// 创建充电桩本体
|
|
3115
5535
|
const point = convertPositionFormat(element.position);
|
|
3116
5536
|
if (point) {
|
|
3117
|
-
const mainPileElement = this.create([point.x, point.y],
|
|
5537
|
+
const mainPileElement = this.create([point.x, point.y], style);
|
|
3118
5538
|
mainPileElement.originalData = element; // 保存完整的原始数据
|
|
3119
5539
|
elements.push(mainPileElement);
|
|
3120
5540
|
}
|
|
@@ -3142,7 +5562,7 @@ class AntennaDataBuilder {
|
|
|
3142
5562
|
* 1. 如果副天线位置数据的相对坐标都是0,则需要展示在主天线旁边
|
|
3143
5563
|
* 2. 否则,副天线有自己的独立位置
|
|
3144
5564
|
*/
|
|
3145
|
-
static fromAntennaData(antennas) {
|
|
5565
|
+
static fromAntennaData(antennas, style) {
|
|
3146
5566
|
const elements = [];
|
|
3147
5567
|
const size = 30;
|
|
3148
5568
|
// 查找主天线(ID=1)和副天线(ID=2)
|
|
@@ -3157,7 +5577,7 @@ class AntennaDataBuilder {
|
|
|
3157
5577
|
online: antenna1.status === 1,
|
|
3158
5578
|
size
|
|
3159
5579
|
};
|
|
3160
|
-
const element1 = this.create([point1.x, point1.y],
|
|
5580
|
+
const element1 = this.create([point1.x, point1.y], style, metadata1);
|
|
3161
5581
|
element1.originalData = antenna1;
|
|
3162
5582
|
elements.push(element1);
|
|
3163
5583
|
}
|
|
@@ -3172,7 +5592,7 @@ class AntennaDataBuilder {
|
|
|
3172
5592
|
online: antenna2.status === 2,
|
|
3173
5593
|
size
|
|
3174
5594
|
};
|
|
3175
|
-
const element2 = this.create([point2.x, point2.y],
|
|
5595
|
+
const element2 = this.create([point2.x, point2.y], style, metadata2);
|
|
3176
5596
|
element2.originalData = antenna2;
|
|
3177
5597
|
elements.push(element2);
|
|
3178
5598
|
}
|
|
@@ -3199,7 +5619,7 @@ class SvgElementDataBuilder {
|
|
|
3199
5619
|
/**
|
|
3200
5620
|
* 从地图元素创建SVG数据(用于时间限制障碍物)
|
|
3201
5621
|
*/
|
|
3202
|
-
static fromMapElement(element) {
|
|
5622
|
+
static fromMapElement(element, style) {
|
|
3203
5623
|
if (!element.svg ||
|
|
3204
5624
|
!element.center ||
|
|
3205
5625
|
element.scale === undefined ||
|
|
@@ -3213,7 +5633,7 @@ class SvgElementDataBuilder {
|
|
|
3213
5633
|
svg: element.svg,
|
|
3214
5634
|
scale: element.scale,
|
|
3215
5635
|
direction: element.direction,
|
|
3216
|
-
},
|
|
5636
|
+
}, style);
|
|
3217
5637
|
drawElement.originalData = element; // 保存完整的原始数据
|
|
3218
5638
|
return drawElement;
|
|
3219
5639
|
}
|
|
@@ -3247,11 +5667,11 @@ class VisionOffDataBuilder {
|
|
|
3247
5667
|
/**
|
|
3248
5668
|
* 创建视觉盲区元素数据(使用边界样式)
|
|
3249
5669
|
*/
|
|
3250
|
-
static createVisionOffArea(element) {
|
|
5670
|
+
static createVisionOffArea(element, style) {
|
|
3251
5671
|
const convertedPoints = convertPointsFormat(element.points);
|
|
3252
5672
|
if (!convertedPoints || convertedPoints.length < 3)
|
|
3253
5673
|
return null;
|
|
3254
|
-
const drawElement = this.create(convertedPoints,
|
|
5674
|
+
const drawElement = this.create(convertedPoints, style);
|
|
3255
5675
|
drawElement.originalData = element; // 保存完整的原始数据
|
|
3256
5676
|
return drawElement;
|
|
3257
5677
|
}
|
|
@@ -3274,33 +5694,18 @@ class ChannelDataBuilder {
|
|
|
3274
5694
|
/**
|
|
3275
5695
|
* 创建隧道元素数据
|
|
3276
5696
|
*/
|
|
3277
|
-
static createTunnel(element) {
|
|
5697
|
+
static createTunnel(element, style) {
|
|
3278
5698
|
const convertedPoints = convertPointsFormat(element.tunnel?.points || element.points);
|
|
3279
5699
|
if (!convertedPoints || convertedPoints.length < 2)
|
|
3280
5700
|
return null;
|
|
3281
|
-
const drawElement = this.create(convertedPoints,
|
|
3282
|
-
drawElement.originalData = element; // 保存完整的原始数据
|
|
3283
|
-
return drawElement;
|
|
3284
|
-
}
|
|
3285
|
-
/**
|
|
3286
|
-
* 创建充电桩隧道元素数据
|
|
3287
|
-
*/
|
|
3288
|
-
static createTunnelToChargingPile(element) {
|
|
3289
|
-
const convertedPoints = convertPointsFormat(element.points);
|
|
3290
|
-
if (!convertedPoints || convertedPoints.length < 2)
|
|
3291
|
-
return null;
|
|
3292
|
-
const drawElement = this.create(convertedPoints, {
|
|
3293
|
-
strokeColor: DEFAULT_STYLES.CHANNEL.strokeColor,
|
|
3294
|
-
lineWidth: 2,
|
|
3295
|
-
opacity: 1.0,
|
|
3296
|
-
});
|
|
5701
|
+
const drawElement = this.create(convertedPoints, style);
|
|
3297
5702
|
drawElement.originalData = element; // 保存完整的原始数据
|
|
3298
5703
|
return drawElement;
|
|
3299
5704
|
}
|
|
3300
5705
|
/**
|
|
3301
5706
|
* 创建充电桩内部隧道路径(用于CHARGING_PILE元素中的tunnel.points)
|
|
3302
5707
|
*/
|
|
3303
|
-
static createChargingPileTunnelPath(element) {
|
|
5708
|
+
static createChargingPileTunnelPath(element, style) {
|
|
3304
5709
|
if (!element.tunnel || !element.tunnel.points)
|
|
3305
5710
|
return null;
|
|
3306
5711
|
// 对应android代码逻辑modules/deviceModule/src/main/java/com/segway/mower/device/map/data/MapDataManager.java
|
|
@@ -3314,45 +5719,10 @@ class ChannelDataBuilder {
|
|
|
3314
5719
|
]);
|
|
3315
5720
|
if (!convertedTunnelPoints || convertedTunnelPoints.length < 2)
|
|
3316
5721
|
return null;
|
|
3317
|
-
const drawElement = this.create(convertedTunnelPoints,
|
|
3318
|
-
strokeColor: DEFAULT_STYLES.CHANNEL.strokeColor,
|
|
3319
|
-
lineWidth: 2,
|
|
3320
|
-
opacity: 1.0,
|
|
3321
|
-
});
|
|
5722
|
+
const drawElement = this.create(convertedTunnelPoints, style);
|
|
3322
5723
|
drawElement.originalData = element; // 保存完整的原始数据
|
|
3323
5724
|
return drawElement;
|
|
3324
5725
|
}
|
|
3325
|
-
/**
|
|
3326
|
-
* 创建边缘路径
|
|
3327
|
-
*/
|
|
3328
|
-
static createEdgePath(points, config) {
|
|
3329
|
-
return this.create(points, {
|
|
3330
|
-
strokeColor: config?.color || DEFAULT_STYLES.PATH_EDGE.strokeColor,
|
|
3331
|
-
lineWidth: config?.lineWidth || 2,
|
|
3332
|
-
opacity: config?.opacity || 1.0,
|
|
3333
|
-
});
|
|
3334
|
-
}
|
|
3335
|
-
/**
|
|
3336
|
-
* 创建割草路径
|
|
3337
|
-
*/
|
|
3338
|
-
static createMowingPath(points, config) {
|
|
3339
|
-
return this.create(points, {
|
|
3340
|
-
strokeColor: config?.color || DEFAULT_STYLES.PATH_EDGE.strokeColor,
|
|
3341
|
-
lineWidth: config?.lineWidth || 2,
|
|
3342
|
-
opacity: config?.opacity || 1.0,
|
|
3343
|
-
});
|
|
3344
|
-
}
|
|
3345
|
-
/**
|
|
3346
|
-
* 创建传输路径
|
|
3347
|
-
*/
|
|
3348
|
-
static createTransPath(points, config) {
|
|
3349
|
-
return this.create(points, {
|
|
3350
|
-
strokeColor: config?.color || DEFAULT_STYLES.PATH_EDGE.strokeColor,
|
|
3351
|
-
lineWidth: config?.lineWidth || 1,
|
|
3352
|
-
lineDash: [5, 5], // 虚线样式
|
|
3353
|
-
opacity: config?.opacity || 1.0,
|
|
3354
|
-
});
|
|
3355
|
-
}
|
|
3356
5726
|
}
|
|
3357
5727
|
|
|
3358
5728
|
/**
|
|
@@ -3363,7 +5733,8 @@ class MapDataProcessor {
|
|
|
3363
5733
|
/**
|
|
3364
5734
|
* 处理地图数据,返回绘制图层
|
|
3365
5735
|
*/
|
|
3366
|
-
static processMapData(mapData) {
|
|
5736
|
+
static processMapData(mapData, mapConfig) {
|
|
5737
|
+
this.mapConfig = mapConfig;
|
|
3367
5738
|
// 收集所有地图元素
|
|
3368
5739
|
const allElements = [];
|
|
3369
5740
|
// 处理子地图中的元素
|
|
@@ -3454,10 +5825,10 @@ class MapDataProcessor {
|
|
|
3454
5825
|
switch (element.type) {
|
|
3455
5826
|
case 'BOUNDARY': {
|
|
3456
5827
|
try {
|
|
3457
|
-
const boundaryElement = BoundaryDataBuilder.fromMapElement(element);
|
|
5828
|
+
const boundaryElement = BoundaryDataBuilder.fromMapElement(element, this.mapConfig.boundary);
|
|
3458
5829
|
if (boundaryElement)
|
|
3459
5830
|
result.push(boundaryElement);
|
|
3460
|
-
const boundaryBorderElement = BoundaryDataBuilder.createBoundaryBorder(element);
|
|
5831
|
+
const boundaryBorderElement = BoundaryDataBuilder.createBoundaryBorder(element, this.mapConfig.boundary);
|
|
3461
5832
|
if (boundaryBorderElement) {
|
|
3462
5833
|
result.push(boundaryBorderElement);
|
|
3463
5834
|
// 将边界边框存储到 store 中,以分区ID为key
|
|
@@ -3478,7 +5849,7 @@ class MapDataProcessor {
|
|
|
3478
5849
|
try {
|
|
3479
5850
|
// 为ObstacleData创建兼容的MapElement接口
|
|
3480
5851
|
const mapElement = element;
|
|
3481
|
-
const obstacleElement = ObstacleDataBuilder.fromMapElement(mapElement);
|
|
5852
|
+
const obstacleElement = ObstacleDataBuilder.fromMapElement(mapElement, this.mapConfig.obstacle);
|
|
3482
5853
|
if (obstacleElement)
|
|
3483
5854
|
result.push(obstacleElement);
|
|
3484
5855
|
}
|
|
@@ -3489,10 +5860,10 @@ class MapDataProcessor {
|
|
|
3489
5860
|
}
|
|
3490
5861
|
case 'CHARGING_PILE': {
|
|
3491
5862
|
try {
|
|
3492
|
-
const chargingPileElements = ChargingPileDataBuilder.fromMapElement(element);
|
|
5863
|
+
const chargingPileElements = ChargingPileDataBuilder.fromMapElement(element, this.mapConfig.chargingPile);
|
|
3493
5864
|
result.push(...chargingPileElements);
|
|
3494
5865
|
// 有充电桩通道时再连接到充电桩
|
|
3495
|
-
const tunnelPath = ChannelDataBuilder.createChargingPileTunnelPath(element);
|
|
5866
|
+
const tunnelPath = ChannelDataBuilder.createChargingPileTunnelPath(element, this.mapConfig.channel);
|
|
3496
5867
|
if (tunnelPath)
|
|
3497
5868
|
result.push(tunnelPath);
|
|
3498
5869
|
// 创建导航位置(如果存在)
|
|
@@ -3505,7 +5876,7 @@ class MapDataProcessor {
|
|
|
3505
5876
|
case 'VISION_OFF_AREA': {
|
|
3506
5877
|
try {
|
|
3507
5878
|
const mapElement = element;
|
|
3508
|
-
const visionOffElement = VisionOffDataBuilder.createVisionOffArea(mapElement);
|
|
5879
|
+
const visionOffElement = VisionOffDataBuilder.createVisionOffArea(mapElement, this.mapConfig.visionOffArea);
|
|
3509
5880
|
if (visionOffElement)
|
|
3510
5881
|
result.push(visionOffElement);
|
|
3511
5882
|
}
|
|
@@ -3517,7 +5888,7 @@ class MapDataProcessor {
|
|
|
3517
5888
|
case 'TUNNEL': {
|
|
3518
5889
|
try {
|
|
3519
5890
|
const mapElement = element;
|
|
3520
|
-
const tunnelElement = ChannelDataBuilder.createTunnel(mapElement);
|
|
5891
|
+
const tunnelElement = ChannelDataBuilder.createTunnel(mapElement, this.mapConfig.channel);
|
|
3521
5892
|
if (tunnelElement)
|
|
3522
5893
|
result.push({
|
|
3523
5894
|
...tunnelElement,
|
|
@@ -3540,7 +5911,8 @@ class MapDataProcessor {
|
|
|
3540
5911
|
'direction' in element &&
|
|
3541
5912
|
element.direction !== undefined) {
|
|
3542
5913
|
const mapElement = element;
|
|
3543
|
-
const svgElement = SvgElementDataBuilder.fromMapElement(mapElement);
|
|
5914
|
+
const svgElement = SvgElementDataBuilder.fromMapElement(mapElement, this.mapConfig.doodle);
|
|
5915
|
+
console.log('svgElement==', svgElement);
|
|
3544
5916
|
if (svgElement)
|
|
3545
5917
|
result.push(svgElement);
|
|
3546
5918
|
}
|
|
@@ -3550,7 +5922,7 @@ class MapDataProcessor {
|
|
|
3550
5922
|
Array.isArray(element.points) &&
|
|
3551
5923
|
element.points.length >= 3) {
|
|
3552
5924
|
const mapElement = element;
|
|
3553
|
-
const polygonElement = ObstacleDataBuilder.createTimeLimitObstacle(mapElement);
|
|
5925
|
+
const polygonElement = ObstacleDataBuilder.createTimeLimitObstacle(mapElement, this.mapConfig.obstacle);
|
|
3554
5926
|
if (polygonElement)
|
|
3555
5927
|
result.push(polygonElement);
|
|
3556
5928
|
}
|
|
@@ -3560,21 +5932,6 @@ class MapDataProcessor {
|
|
|
3560
5932
|
}
|
|
3561
5933
|
break;
|
|
3562
5934
|
}
|
|
3563
|
-
// case 'TUNNEL_TO_CHARGING_PILE': {
|
|
3564
|
-
// try {
|
|
3565
|
-
// // const chargingPileElement = elements.find(e => e.type === 'CHARGING_PILE');
|
|
3566
|
-
// // if (chargingPileElement) {
|
|
3567
|
-
// // const tunnelToChargingPileElement = ChannelDataBuilder.createTunnelToChargingPile(chargingPileElement);
|
|
3568
|
-
// // if (tunnelToChargingPileElement) result.push(tunnelToChargingPileElement);
|
|
3569
|
-
// // }
|
|
3570
|
-
// const tunnelToChargingPileElement =
|
|
3571
|
-
// ChannelDataBuilder.createTunnelToChargingPile(element);
|
|
3572
|
-
// if (tunnelToChargingPileElement) result.push(tunnelToChargingPileElement);
|
|
3573
|
-
// } catch (error) {
|
|
3574
|
-
// console.warn(`Error processing TUNNEL_TO_CHARGING_PILE element:`, element, error);
|
|
3575
|
-
// }
|
|
3576
|
-
// break;
|
|
3577
|
-
// }
|
|
3578
5935
|
default: {
|
|
3579
5936
|
console.warn(`Unknown element type: ${element.type}`, element);
|
|
3580
5937
|
break;
|
|
@@ -3621,18 +5978,6 @@ class PathDataBuilder {
|
|
|
3621
5978
|
// return this.create(convertedPoints, DEFAULT_STYLES.PATH_EDGE);
|
|
3622
5979
|
// }
|
|
3623
5980
|
// /**
|
|
3624
|
-
// * 创建充电桩隧道元素数据
|
|
3625
|
-
// */
|
|
3626
|
-
// static createTunnelToChargingPile(element: MapElement): DrawElement | null {
|
|
3627
|
-
// const convertedPoints = convertPointsFormat(element.points);
|
|
3628
|
-
// if (!convertedPoints || convertedPoints.length < 2) return null;
|
|
3629
|
-
// return this.create(convertedPoints, {
|
|
3630
|
-
// strokeColor: DEFAULT_STYLES.CHANNEL.strokeColor,
|
|
3631
|
-
// lineWidth: 2,
|
|
3632
|
-
// opacity: 1.0
|
|
3633
|
-
// });
|
|
3634
|
-
// }
|
|
3635
|
-
// /**
|
|
3636
5981
|
// * 创建充电桩内部隧道路径(用于CHARGING_PILE元素中的tunnel.points)
|
|
3637
5982
|
// */
|
|
3638
5983
|
// static createChargingPileTunnelPath(element: MapElement): DrawElement | null {
|
|
@@ -3692,7 +6037,7 @@ class PathDataProcessor {
|
|
|
3692
6037
|
/**
|
|
3693
6038
|
* 处理路径数据,创建路径绘制图层
|
|
3694
6039
|
*/
|
|
3695
|
-
static processPathData(pathData,
|
|
6040
|
+
static processPathData(pathData, mapConfig) {
|
|
3696
6041
|
if (!pathData || typeof pathData !== 'object') {
|
|
3697
6042
|
return [];
|
|
3698
6043
|
}
|
|
@@ -3704,62 +6049,45 @@ class PathDataProcessor {
|
|
|
3704
6049
|
return acc;
|
|
3705
6050
|
}, []);
|
|
3706
6051
|
// 合并配置
|
|
3707
|
-
const config =
|
|
3708
|
-
lineWidth: pathConfig?.lineWidth ?? 6,
|
|
3709
|
-
showEdgePaths: pathConfig?.showEdgePaths ?? false,
|
|
3710
|
-
showTransPaths: pathConfig?.showTransPaths ?? false,
|
|
3711
|
-
showMowingPaths: pathConfig?.showMowingPaths ?? true,
|
|
3712
|
-
edgePathColor: pathConfig?.edgePathColor,
|
|
3713
|
-
transPathColor: pathConfig?.transPathColor,
|
|
3714
|
-
mowingPathColor: pathConfig?.mowingPathColor,
|
|
3715
|
-
edgePathOpacity: pathConfig?.edgePathOpacity ?? 1.0,
|
|
3716
|
-
transPathOpacity: pathConfig?.transPathOpacity ?? 1.0,
|
|
3717
|
-
mowingPathOpacity: pathConfig?.mowingPathOpacity ?? 1.0,
|
|
3718
|
-
};
|
|
6052
|
+
const config = mapConfig.path;
|
|
3719
6053
|
// 使用Python相同的逻辑:按线段分组而不是按点分组
|
|
3720
6054
|
const pathSegments = createPathSegmentsByType(allPathItems);
|
|
3721
6055
|
const elements = [];
|
|
3722
|
-
//
|
|
3723
|
-
|
|
3724
|
-
|
|
3725
|
-
|
|
3726
|
-
|
|
3727
|
-
|
|
3728
|
-
|
|
3729
|
-
|
|
3730
|
-
|
|
3731
|
-
|
|
3732
|
-
|
|
3733
|
-
|
|
3734
|
-
|
|
3735
|
-
|
|
3736
|
-
|
|
3737
|
-
|
|
3738
|
-
|
|
3739
|
-
|
|
3740
|
-
|
|
3741
|
-
|
|
3742
|
-
|
|
3743
|
-
|
|
3744
|
-
|
|
3745
|
-
});
|
|
3746
|
-
element.originalData = points;
|
|
3747
|
-
elements.push(element);
|
|
3748
|
-
}
|
|
6056
|
+
// 处理边缘路径段
|
|
6057
|
+
for (const segment of pathSegments.edge) {
|
|
6058
|
+
// 转换 Point[] 为 number[][]
|
|
6059
|
+
const points = segment.points.map((point) => [point.x, point.y]);
|
|
6060
|
+
const element = PathDataBuilder.createEdgePath(points, {
|
|
6061
|
+
lineWidth: config.lineWidth,
|
|
6062
|
+
color: config.edgeLineColor,
|
|
6063
|
+
opacity: config.opacity,
|
|
6064
|
+
});
|
|
6065
|
+
element.originalData = points;
|
|
6066
|
+
elements.push(element);
|
|
6067
|
+
}
|
|
6068
|
+
// 处理割草路径段
|
|
6069
|
+
for (const segment of pathSegments.mowing) {
|
|
6070
|
+
// 转换 Point[] 为 number[][]
|
|
6071
|
+
const points = segment.points.map((point) => [point.x, point.y]);
|
|
6072
|
+
const element = PathDataBuilder.createMowingPath(points, {
|
|
6073
|
+
lineWidth: config.lineWidth,
|
|
6074
|
+
color: config.mowingLineColor,
|
|
6075
|
+
opacity: config.opacity,
|
|
6076
|
+
});
|
|
6077
|
+
element.originalData = points;
|
|
6078
|
+
elements.push(element);
|
|
3749
6079
|
}
|
|
3750
6080
|
// 处理传输路径段(只有在showTransPaths为true时才添加)
|
|
3751
|
-
|
|
3752
|
-
|
|
3753
|
-
|
|
3754
|
-
|
|
3755
|
-
|
|
3756
|
-
|
|
3757
|
-
|
|
3758
|
-
|
|
3759
|
-
|
|
3760
|
-
|
|
3761
|
-
elements.push(element);
|
|
3762
|
-
}
|
|
6081
|
+
for (const segment of pathSegments.trans) {
|
|
6082
|
+
// 转换 Point[] 为 number[][]
|
|
6083
|
+
const points = segment.points.map((point) => [point.x, point.y]);
|
|
6084
|
+
const element = PathDataBuilder.createTransPath(points, {
|
|
6085
|
+
lineWidth: config.lineWidth,
|
|
6086
|
+
color: config.transLineColor,
|
|
6087
|
+
opacity: config.opacity,
|
|
6088
|
+
});
|
|
6089
|
+
element.originalData = points;
|
|
6090
|
+
elements.push(element);
|
|
3763
6091
|
}
|
|
3764
6092
|
return elements;
|
|
3765
6093
|
}
|
|
@@ -3774,6 +6102,8 @@ class BoundaryLabelsManager {
|
|
|
3774
6102
|
this.container = null;
|
|
3775
6103
|
this.overlayDiv = null;
|
|
3776
6104
|
this.globalClickHandler = null;
|
|
6105
|
+
// 当前展开的边界id
|
|
6106
|
+
this.currentExpandedBoundaryId = null;
|
|
3777
6107
|
this.svgView = svgView;
|
|
3778
6108
|
this.boundaryData = boundaryData;
|
|
3779
6109
|
this.initializeContainer();
|
|
@@ -3872,7 +6202,7 @@ class BoundaryLabelsManager {
|
|
|
3872
6202
|
extendedContent.style.marginTop = '6px';
|
|
3873
6203
|
extendedContent.style.fontSize = '11px';
|
|
3874
6204
|
extendedContent.style.opacity = '0.9';
|
|
3875
|
-
extendedContent.style.display = 'none';
|
|
6205
|
+
extendedContent.style.display = this.currentExpandedBoundaryId === boundary.id ? 'block' : 'none';
|
|
3876
6206
|
extendedContent.style.borderTop = '1px solid rgba(255,255,255,0.2)';
|
|
3877
6207
|
extendedContent.style.paddingTop = '6px';
|
|
3878
6208
|
// 面积信息
|
|
@@ -3897,17 +6227,17 @@ class BoundaryLabelsManager {
|
|
|
3897
6227
|
labelDiv.addEventListener('click', (e) => {
|
|
3898
6228
|
e.stopPropagation();
|
|
3899
6229
|
this.elevateLabelZIndex();
|
|
3900
|
-
this.expandLabel(
|
|
3901
|
-
});
|
|
3902
|
-
// 添加悬停效果
|
|
3903
|
-
labelDiv.addEventListener('mouseenter', () => {
|
|
3904
|
-
labelDiv.style.backgroundColor = 'rgba(30, 30, 31, 0.6)';
|
|
3905
|
-
labelDiv.style.transform = 'translate(-50%, -50%) scale(1.05)';
|
|
3906
|
-
});
|
|
3907
|
-
labelDiv.addEventListener('mouseleave', () => {
|
|
3908
|
-
labelDiv.style.backgroundColor = 'rgba(30, 30, 31, 0.3)';
|
|
3909
|
-
labelDiv.style.transform = 'translate(-50%, -50%) scale(1)';
|
|
6230
|
+
this.expandLabel(boundary.id);
|
|
3910
6231
|
});
|
|
6232
|
+
// // 添加悬停效果
|
|
6233
|
+
// labelDiv.addEventListener('mouseenter', () => {
|
|
6234
|
+
// labelDiv.style.backgroundColor = 'rgba(30, 30, 31, 0.6)';
|
|
6235
|
+
// labelDiv.style.transform = 'translate(-50%, -50%) scale(1.05)';
|
|
6236
|
+
// });
|
|
6237
|
+
// labelDiv.addEventListener('mouseleave', () => {
|
|
6238
|
+
// labelDiv.style.backgroundColor = 'rgba(30, 30, 31, 0.3)';
|
|
6239
|
+
// labelDiv.style.transform = 'translate(-50%, -50%) scale(1)';
|
|
6240
|
+
// });
|
|
3911
6241
|
this.container.appendChild(labelDiv);
|
|
3912
6242
|
return labelDiv;
|
|
3913
6243
|
}
|
|
@@ -3932,25 +6262,30 @@ class BoundaryLabelsManager {
|
|
|
3932
6262
|
/**
|
|
3933
6263
|
* 展开标签
|
|
3934
6264
|
*/
|
|
3935
|
-
expandLabel(
|
|
6265
|
+
expandLabel(boundaryId) {
|
|
6266
|
+
const labelDiv = this.getLabelElement(boundaryId);
|
|
6267
|
+
if (!labelDiv)
|
|
6268
|
+
return;
|
|
3936
6269
|
const extendedContent = labelDiv.querySelector('.boundary-label-extended');
|
|
3937
6270
|
if (!extendedContent)
|
|
3938
6271
|
return;
|
|
3939
6272
|
// 关闭其他展开的标签
|
|
3940
|
-
this.collapseOtherLabels(
|
|
6273
|
+
this.collapseOtherLabels(boundaryId);
|
|
3941
6274
|
// 展开当前标签
|
|
3942
6275
|
extendedContent.style.display = 'block';
|
|
3943
6276
|
labelDiv.style.whiteSpace = 'normal';
|
|
6277
|
+
this.currentExpandedBoundaryId = boundaryId;
|
|
3944
6278
|
}
|
|
3945
6279
|
/**
|
|
3946
6280
|
* 关闭其他展开的标签
|
|
3947
6281
|
*/
|
|
3948
|
-
collapseOtherLabels(
|
|
6282
|
+
collapseOtherLabels(boundaryId) {
|
|
3949
6283
|
if (!this.container)
|
|
3950
6284
|
return;
|
|
3951
6285
|
const allLabels = this.container.querySelectorAll('.boundary-label');
|
|
3952
6286
|
allLabels.forEach(label => {
|
|
3953
|
-
|
|
6287
|
+
const labelBoundaryId = label.getAttribute('data-boundary-id');
|
|
6288
|
+
if (labelBoundaryId && labelBoundaryId !== boundaryId.toString()) {
|
|
3954
6289
|
const extendedContent = label.querySelector('.boundary-label-extended');
|
|
3955
6290
|
if (extendedContent) {
|
|
3956
6291
|
extendedContent.style.display = 'none';
|
|
@@ -3966,6 +6301,7 @@ class BoundaryLabelsManager {
|
|
|
3966
6301
|
this.boundaryData.forEach((boundary) => {
|
|
3967
6302
|
this.addElement(boundary);
|
|
3968
6303
|
});
|
|
6304
|
+
this.updatePositionsWithPrecomputedData();
|
|
3969
6305
|
}
|
|
3970
6306
|
/**
|
|
3971
6307
|
* 获取容器元素
|
|
@@ -3973,28 +6309,6 @@ class BoundaryLabelsManager {
|
|
|
3973
6309
|
getElement() {
|
|
3974
6310
|
return this.container;
|
|
3975
6311
|
}
|
|
3976
|
-
/**
|
|
3977
|
-
* 更新所有边界标签位置
|
|
3978
|
-
*/
|
|
3979
|
-
updatePositions() {
|
|
3980
|
-
if (!this.container || !this.overlayDiv)
|
|
3981
|
-
return;
|
|
3982
|
-
const labels = this.container.querySelectorAll('.boundary-label');
|
|
3983
|
-
labels.forEach((label, index) => {
|
|
3984
|
-
const boundary = this.boundaryData[index];
|
|
3985
|
-
if (!boundary)
|
|
3986
|
-
return;
|
|
3987
|
-
// 计算边界中心点
|
|
3988
|
-
const center = this.calculateBoundaryCenter(boundary);
|
|
3989
|
-
if (!center) {
|
|
3990
|
-
console.warn(`BoundaryLabelsManager: 无法计算边界 ${boundary.name} (ID: ${boundary.id}) 的中心点`);
|
|
3991
|
-
return;
|
|
3992
|
-
}
|
|
3993
|
-
// 设置标签位置
|
|
3994
|
-
label.style.left = `${center.x}px`;
|
|
3995
|
-
label.style.top = `${center.y}px`;
|
|
3996
|
-
});
|
|
3997
|
-
}
|
|
3998
6312
|
/**
|
|
3999
6313
|
* 使用预计算的数据更新边界标签位置(优化版本)
|
|
4000
6314
|
* @param divWidth 叠加层div的宽度
|
|
@@ -4002,8 +6316,11 @@ class BoundaryLabelsManager {
|
|
|
4002
6316
|
* @param viewBox SVG的viewBox信息
|
|
4003
6317
|
*/
|
|
4004
6318
|
updatePositionsWithPrecomputedData(divWidth, divHeight, viewBox) {
|
|
4005
|
-
if (!this.container)
|
|
6319
|
+
if (!this.container || !this.svgView)
|
|
4006
6320
|
return;
|
|
6321
|
+
const dw = parseFloat(this.svgView.getSVG().getAttribute('width')) || divWidth;
|
|
6322
|
+
const dh = parseFloat(this.svgView.getSVG().getAttribute('height')) || divHeight;
|
|
6323
|
+
const vb = this.svgView.getSVG().viewBox.baseVal || viewBox;
|
|
4007
6324
|
const labels = this.container.querySelectorAll('.boundary-label');
|
|
4008
6325
|
labels.forEach((label, index) => {
|
|
4009
6326
|
const boundary = this.boundaryData[index];
|
|
@@ -4016,7 +6333,7 @@ class BoundaryLabelsManager {
|
|
|
4016
6333
|
return;
|
|
4017
6334
|
}
|
|
4018
6335
|
// 直接使用预计算的数据进行坐标转换
|
|
4019
|
-
const center = this.convertMapCoordinateToPixelWithPrecomputedData(mapCenter.x, mapCenter.y,
|
|
6336
|
+
const center = this.convertMapCoordinateToPixelWithPrecomputedData(mapCenter.x, mapCenter.y, dw, dh, vb);
|
|
4020
6337
|
if (!center)
|
|
4021
6338
|
return;
|
|
4022
6339
|
// 设置标签位置
|
|
@@ -4213,6 +6530,7 @@ class BoundaryLabelsManager {
|
|
|
4213
6530
|
if (!this.container)
|
|
4214
6531
|
return;
|
|
4215
6532
|
const allLabels = this.container.querySelectorAll('.boundary-label');
|
|
6533
|
+
this.currentExpandedBoundaryId = null;
|
|
4216
6534
|
allLabels.forEach(label => {
|
|
4217
6535
|
const extendedContent = label.querySelector('.boundary-label-extended');
|
|
4218
6536
|
if (extendedContent) {
|
|
@@ -4267,8 +6585,7 @@ class BoundaryLabelsManager {
|
|
|
4267
6585
|
const allLabels = this.container.querySelectorAll('.boundary-label');
|
|
4268
6586
|
allLabels.forEach((label, index) => {
|
|
4269
6587
|
const labelElement = label;
|
|
4270
|
-
|
|
4271
|
-
console.log(`Label ${index} z-index: ${currentZIndex}`);
|
|
6588
|
+
labelElement.style.zIndex;
|
|
4272
6589
|
});
|
|
4273
6590
|
}
|
|
4274
6591
|
}
|
|
@@ -4329,7 +6646,6 @@ class ChargingPileManager {
|
|
|
4329
6646
|
pileDiv.style.position = 'absolute';
|
|
4330
6647
|
pileDiv.style.width = `${size}px`;
|
|
4331
6648
|
pileDiv.style.height = `${size}px`;
|
|
4332
|
-
pileDiv.style.transform = 'translate(-50%, -50%)';
|
|
4333
6649
|
pileDiv.style.pointerEvents = 'auto';
|
|
4334
6650
|
pileDiv.style.zIndex = ChargingPileManager.Z_INDEX.CHARGING_PILE.toString();
|
|
4335
6651
|
// 创建图片元素
|
|
@@ -4338,13 +6654,14 @@ class ChargingPileManager {
|
|
|
4338
6654
|
imgElement.style.width = '100%';
|
|
4339
6655
|
imgElement.style.height = '100%';
|
|
4340
6656
|
imgElement.style.objectFit = 'contain';
|
|
4341
|
-
imgElement.style.opacity = '
|
|
6657
|
+
imgElement.style.opacity = '1'; // 初始透明
|
|
4342
6658
|
pileDiv.appendChild(imgElement);
|
|
4343
6659
|
// 将弧度转换为角度
|
|
4344
6660
|
const angle = (direction * 180) / Math.PI;
|
|
4345
6661
|
const rotationDegree = 270 - angle; // 坐标系转换
|
|
6662
|
+
pileDiv.style.transform = `translate(-50%, -50%) rotate(${rotationDegree}deg)`;
|
|
4346
6663
|
// 添加动画
|
|
4347
|
-
this.addChargingPileAnimation(pileDiv, imgElement, rotationDegree);
|
|
6664
|
+
// this.addChargingPileAnimation(pileDiv, imgElement, rotationDegree);
|
|
4348
6665
|
// 生成唯一ID
|
|
4349
6666
|
const pileId = `pile_${center[0]}_${center[1]}`;
|
|
4350
6667
|
this.pileElements.set(pileId, pileDiv);
|
|
@@ -4965,31 +7282,6 @@ const EDIT_STYLES = {
|
|
|
4965
7282
|
const EDIT_BEHAVIOR = {
|
|
4966
7283
|
SUCCESS_MESSAGE_DURATION_MS: 3000,
|
|
4967
7284
|
};
|
|
4968
|
-
// 默认配置
|
|
4969
|
-
const DEFAULT_MAP_CONFIG = {
|
|
4970
|
-
showScale: true,
|
|
4971
|
-
fitToView: true,
|
|
4972
|
-
initialZoom: 1,
|
|
4973
|
-
enableDrag: true,
|
|
4974
|
-
width: 800,
|
|
4975
|
-
height: 600,
|
|
4976
|
-
backgroundColor: '#f5f5f5',
|
|
4977
|
-
borderRadius: '8px',
|
|
4978
|
-
border: '1px solid #ddd',
|
|
4979
|
-
useGoogleMaps: true,
|
|
4980
|
-
};
|
|
4981
|
-
const DEFAULT_PATH_CONFIG = {
|
|
4982
|
-
lineWidth: 20,
|
|
4983
|
-
showEdgePaths: true,
|
|
4984
|
-
showTransPaths: true,
|
|
4985
|
-
showMowingPaths: true,
|
|
4986
|
-
edgePathColor: 'rgba(194, 203, 212)',
|
|
4987
|
-
transPathColor: 'transparent',
|
|
4988
|
-
mowingPathColor: 'rgba(194, 203, 212)',
|
|
4989
|
-
edgePathOpacity: 1,
|
|
4990
|
-
transPathOpacity: 0.6,
|
|
4991
|
-
mowingPathOpacity: 1,
|
|
4992
|
-
};
|
|
4993
7285
|
|
|
4994
7286
|
class MowerPostionManager {
|
|
4995
7287
|
constructor(svgView, mowerPositonConfig, overlayDiv, onAnimationComplete) {
|
|
@@ -5046,8 +7338,8 @@ class MowerPostionManager {
|
|
|
5046
7338
|
this.mowerElement = document.createElement('div');
|
|
5047
7339
|
this.mowerElement.className = 'mower-position';
|
|
5048
7340
|
this.mowerElement.style.position = 'absolute';
|
|
5049
|
-
this.mowerElement.style.width = '
|
|
5050
|
-
this.mowerElement.style.height = '
|
|
7341
|
+
this.mowerElement.style.width = '30px';
|
|
7342
|
+
this.mowerElement.style.height = '30px';
|
|
5051
7343
|
this.mowerElement.style.transform = 'translate(-50%, -50%)';
|
|
5052
7344
|
this.mowerElement.style.pointerEvents = 'none';
|
|
5053
7345
|
this.mowerElement.style.zIndex = '1';
|
|
@@ -5297,7 +7589,7 @@ class MowerPostionManager {
|
|
|
5297
7589
|
|
|
5298
7590
|
// Google Maps 叠加层类 - 带编辑功能
|
|
5299
7591
|
class MowerMapOverlay {
|
|
5300
|
-
constructor(bounds, mapData, mowerPositonConfig, pathData, isEditMode = false, mapConfig = {},
|
|
7592
|
+
constructor(bounds, mapData, mowerPositonConfig, pathData, isEditMode = false, mapConfig = {}, antennaConfig = {}, onMapLoad, onPathLoad, dragCallbacks) {
|
|
5301
7593
|
this.div = null;
|
|
5302
7594
|
this.svgMapView = null;
|
|
5303
7595
|
this.offscreenContainer = null;
|
|
@@ -5339,7 +7631,6 @@ class MowerMapOverlay {
|
|
|
5339
7631
|
this.pathData = pathData;
|
|
5340
7632
|
this.isEditMode = isEditMode;
|
|
5341
7633
|
this.mapConfig = mapConfig;
|
|
5342
|
-
this.pathConfig = pathConfig;
|
|
5343
7634
|
this.antennaConfig = antennaConfig;
|
|
5344
7635
|
this.onMapLoad = onMapLoad;
|
|
5345
7636
|
this.onPathLoad = onPathLoad;
|
|
@@ -5363,6 +7654,7 @@ class MowerMapOverlay {
|
|
|
5363
7654
|
this.boundaryData = generateBoundaryData(mapData, pathData);
|
|
5364
7655
|
}
|
|
5365
7656
|
updatePosition(positonConfig, animationTime = 2200) {
|
|
7657
|
+
console.log('updatePosition==', positonConfig, animationTime);
|
|
5366
7658
|
// 保存当前动画时长
|
|
5367
7659
|
this.currentAnimationTime = animationTime;
|
|
5368
7660
|
// 标记是否为用户动画(大于0表示用户主动触发的动画)
|
|
@@ -5523,12 +7815,6 @@ class MowerMapOverlay {
|
|
|
5523
7815
|
this.div.appendChild(container);
|
|
5524
7816
|
}
|
|
5525
7817
|
}
|
|
5526
|
-
// 更新边界标签位置
|
|
5527
|
-
updateBoundaryLabelsPosition() {
|
|
5528
|
-
if (this.boundaryLabelsManager) {
|
|
5529
|
-
this.boundaryLabelsManager.updatePositions();
|
|
5530
|
-
}
|
|
5531
|
-
}
|
|
5532
7818
|
// 使用优化版本更新边界标签位置
|
|
5533
7819
|
updateBoundaryLabelsPositionOptimized(width, height) {
|
|
5534
7820
|
if (!this.boundaryLabelsManager || !this.div)
|
|
@@ -6074,7 +8360,6 @@ class MowerMapOverlay {
|
|
|
6074
8360
|
try {
|
|
6075
8361
|
// 创建SvgMapView实例
|
|
6076
8362
|
this.svgMapView = new SvgMapView(this.offscreenContainer, 800, 600);
|
|
6077
|
-
this.svgMapView.setShowScale(this.mapConfig.showScale !== false);
|
|
6078
8363
|
// 加载地图数据
|
|
6079
8364
|
this.loadMapData();
|
|
6080
8365
|
// 加载路径数据
|
|
@@ -6101,7 +8386,7 @@ class MowerMapOverlay {
|
|
|
6101
8386
|
return;
|
|
6102
8387
|
try {
|
|
6103
8388
|
// 使用现有的MapDataProcessor处理地图数据
|
|
6104
|
-
const elements = MapDataProcessor.processMapData(this.mapData);
|
|
8389
|
+
const elements = MapDataProcessor.processMapData(this.mapData, this.mapConfig);
|
|
6105
8390
|
// 分离充电桩和天线元素,其他元素添加到SVG图层
|
|
6106
8391
|
// const svgElements = elements.filter(element =>
|
|
6107
8392
|
// element.type !== 'charging_pile' && element.type !== 'antenna'
|
|
@@ -6150,7 +8435,7 @@ class MowerMapOverlay {
|
|
|
6150
8435
|
loadPathData(pathData) {
|
|
6151
8436
|
try {
|
|
6152
8437
|
// 使用现有的PathDataProcessor处理路径数据
|
|
6153
|
-
const pathElements = PathDataProcessor.processPathData(pathData, this.
|
|
8438
|
+
const pathElements = PathDataProcessor.processPathData(pathData, this.mapConfig);
|
|
6154
8439
|
const pathLayer = new PathLayer();
|
|
6155
8440
|
pathLayer.addElements(pathElements);
|
|
6156
8441
|
// 添加图层到SvgMapView
|
|
@@ -6176,6 +8461,7 @@ class MowerMapOverlay {
|
|
|
6176
8461
|
if (!pathJson)
|
|
6177
8462
|
return;
|
|
6178
8463
|
const boundaryData = generateBoundaryData(this.mapData, pathJson);
|
|
8464
|
+
console.log('boundaryData==', boundaryData);
|
|
6179
8465
|
this.boundaryLabelsManager?.updateBoundaryData(boundaryData);
|
|
6180
8466
|
}
|
|
6181
8467
|
draw() {
|
|
@@ -6368,11 +8654,9 @@ const getValidGpsBounds = (mapData) => {
|
|
|
6368
8654
|
};
|
|
6369
8655
|
};
|
|
6370
8656
|
// 默认配置
|
|
6371
|
-
const defaultMapConfig =
|
|
6372
|
-
const defaultPathConfig = DEFAULT_PATH_CONFIG;
|
|
8657
|
+
const defaultMapConfig = DEFAULT_STYLES;
|
|
6373
8658
|
// 地图渲染器组件
|
|
6374
|
-
const MowerMapRenderer = forwardRef(({ mapRef, mapJson, pathJson, realTimeData,
|
|
6375
|
-
const containerRef = useRef(null);
|
|
8659
|
+
const MowerMapRenderer = forwardRef(({ mapConfig, modelType, mapRef, mapJson, pathJson, realTimeData, currentPositionData, antennaConfig, onMapLoad, onPathLoad, onZoomChange, onError, className, style, googleMapInstance, isEditMode = false, dragCallbacks, }, ref) => {
|
|
6376
8660
|
const svgMapViewRef = useRef(null);
|
|
6377
8661
|
const [elementCount, setElementCount] = useState(0);
|
|
6378
8662
|
const [pathCount, setPathCount] = useState(0);
|
|
@@ -6402,25 +8686,21 @@ const MowerMapRenderer = forwardRef(({ mapRef, mapJson, pathJson, realTimeData,
|
|
|
6402
8686
|
}, [mapJson]);
|
|
6403
8687
|
// 合并配置
|
|
6404
8688
|
const mergedMapConfig = useMemo(() => {
|
|
6405
|
-
|
|
6406
|
-
// return defaultMapConfig;
|
|
6407
|
-
// }
|
|
6408
|
-
return { ...defaultMapConfig, ...(mapConfig || {}) };
|
|
8689
|
+
return merge(defaultMapConfig, mapConfig);
|
|
6409
8690
|
}, [mapConfig]);
|
|
6410
|
-
const mergedPathConfig = useMemo(() => {
|
|
6411
|
-
return { ...defaultPathConfig, ...(pathConfig || {}) };
|
|
6412
|
-
}, [pathConfig]);
|
|
6413
8691
|
const mergedAntennaConfig = useMemo(() => antennaConfig, [antennaConfig]);
|
|
6414
8692
|
const mowerPositionData = useMemo(() => {
|
|
6415
8693
|
return {
|
|
6416
|
-
postureTheta:
|
|
6417
|
-
|
|
6418
|
-
|
|
6419
|
-
|
|
6420
|
-
|
|
8694
|
+
postureTheta: currentPositionData?.postureTheta
|
|
8695
|
+
? Number(currentPositionData.postureTheta)
|
|
8696
|
+
: 0,
|
|
8697
|
+
postureX: currentPositionData?.postureX ? Number(currentPositionData.postureX) : 0,
|
|
8698
|
+
postureY: currentPositionData?.postureY ? Number(currentPositionData.postureY) : 0,
|
|
8699
|
+
vehicleState: currentPositionData?.vehicleState || RobotStatus.STANDBY,
|
|
8700
|
+
vehicleModel: modelType,
|
|
6421
8701
|
};
|
|
6422
|
-
}, [
|
|
6423
|
-
console.log('mowerPositionData==', mowerPositionData);
|
|
8702
|
+
}, [currentPositionData, modelType]);
|
|
8703
|
+
console.log('mowerPositionData==', currentPositionData, mowerPositionData);
|
|
6424
8704
|
// 处理错误
|
|
6425
8705
|
const handleError = (error) => {
|
|
6426
8706
|
setCurrentError(error);
|
|
@@ -6428,7 +8708,7 @@ const MowerMapRenderer = forwardRef(({ mapRef, mapJson, pathJson, realTimeData,
|
|
|
6428
8708
|
};
|
|
6429
8709
|
// 初始化Google Maps叠加层
|
|
6430
8710
|
const initializeGoogleMapsOverlay = async () => {
|
|
6431
|
-
if (!mapJson
|
|
8711
|
+
if (!mapJson)
|
|
6432
8712
|
return;
|
|
6433
8713
|
try {
|
|
6434
8714
|
// 等待Google Maps API加载
|
|
@@ -6468,7 +8748,7 @@ const MowerMapRenderer = forwardRef(({ mapRef, mapJson, pathJson, realTimeData,
|
|
|
6468
8748
|
overlayRef.current = null;
|
|
6469
8749
|
}
|
|
6470
8750
|
// 创建叠加层
|
|
6471
|
-
const overlay = new MowerMapOverlay(googleBounds, mapJson, mowerPositionData, pathJson || {}, isEditMode, mergedMapConfig,
|
|
8751
|
+
const overlay = new MowerMapOverlay(googleBounds, mapJson, mowerPositionData, pathJson || {}, isEditMode, mergedMapConfig, mergedAntennaConfig, (count) => {
|
|
6472
8752
|
setElementCount(count);
|
|
6473
8753
|
onMapLoad?.(count);
|
|
6474
8754
|
}, (count) => {
|
|
@@ -6479,7 +8759,7 @@ const MowerMapRenderer = forwardRef(({ mapRef, mapJson, pathJson, realTimeData,
|
|
|
6479
8759
|
overlay.setMap(mapInstance);
|
|
6480
8760
|
overlayRef.current = overlay;
|
|
6481
8761
|
// 只在首次初始化时自适应视图
|
|
6482
|
-
if (
|
|
8762
|
+
if (!hasInitializedBounds) {
|
|
6483
8763
|
mapInstance.fitBounds(googleBounds);
|
|
6484
8764
|
setHasInitializedBounds(true);
|
|
6485
8765
|
}
|
|
@@ -6489,87 +8769,27 @@ const MowerMapRenderer = forwardRef(({ mapRef, mapJson, pathJson, realTimeData,
|
|
|
6489
8769
|
handleError(`初始化Google Maps叠加层失败: ${error instanceof Error ? error.message : String(error)}`);
|
|
6490
8770
|
}
|
|
6491
8771
|
};
|
|
6492
|
-
|
|
6493
|
-
|
|
6494
|
-
|
|
6495
|
-
|
|
6496
|
-
|
|
6497
|
-
|
|
6498
|
-
|
|
6499
|
-
|
|
6500
|
-
|
|
6501
|
-
|
|
6502
|
-
|
|
6503
|
-
|
|
6504
|
-
|
|
6505
|
-
|
|
6506
|
-
}
|
|
6507
|
-
// 初始缩放
|
|
6508
|
-
setZoom(mergedMapConfig.initialZoom || 1);
|
|
6509
|
-
svgView.setZoom(mergedMapConfig.initialZoom || 1);
|
|
6510
|
-
// 自适应视图
|
|
6511
|
-
if (mergedMapConfig.fitToView) {
|
|
6512
|
-
const bounds = calculateMapBounds(mapJson);
|
|
6513
|
-
if (bounds) {
|
|
6514
|
-
svgView.fitToView(bounds);
|
|
6515
|
-
}
|
|
6516
|
-
}
|
|
6517
|
-
}
|
|
6518
|
-
catch (error) {
|
|
6519
|
-
handleError(`初始化SVG视图失败: ${error instanceof Error ? error.message : String(error)}`);
|
|
6520
|
-
}
|
|
6521
|
-
};
|
|
6522
|
-
// 加载地图数据
|
|
6523
|
-
const loadMapData = (svgView) => {
|
|
6524
|
-
if (!mapJson)
|
|
6525
|
-
return;
|
|
6526
|
-
try {
|
|
6527
|
-
const elements = MapDataProcessor.processMapData(mapJson);
|
|
6528
|
-
const drawLayer = new DrawLayer();
|
|
6529
|
-
drawLayer.addElements(elements);
|
|
6530
|
-
// 处理天线数据
|
|
6531
|
-
if (mapJson.antennas && mapJson.antennas.length > 0) {
|
|
6532
|
-
const antennaElements = AntennaDataBuilder.fromAntennaData(mapJson.antennas);
|
|
6533
|
-
drawLayer.addElements(antennaElements);
|
|
6534
|
-
}
|
|
6535
|
-
const layers = drawLayer.getLayers();
|
|
6536
|
-
svgView.clear();
|
|
6537
|
-
layers.forEach((layer) => {
|
|
6538
|
-
svgView.addLayer(layer);
|
|
6539
|
-
});
|
|
6540
|
-
const count = elements.length;
|
|
6541
|
-
setElementCount(count);
|
|
6542
|
-
onMapLoad?.(count);
|
|
6543
|
-
}
|
|
6544
|
-
catch (error) {
|
|
6545
|
-
handleError(`加载地图数据失败: ${error instanceof Error ? error.message : String(error)}`);
|
|
6546
|
-
}
|
|
6547
|
-
};
|
|
6548
|
-
// 加载路径数据
|
|
6549
|
-
const loadPathData = (svgView) => {
|
|
6550
|
-
if (!pathJson)
|
|
6551
|
-
return;
|
|
6552
|
-
try {
|
|
6553
|
-
const pathElements = PathDataProcessor.processPathData(pathJson, mergedPathConfig);
|
|
6554
|
-
const pathLayer = new DrawLayer();
|
|
6555
|
-
pathLayer.addElements(pathElements);
|
|
6556
|
-
svgView.addLayer(pathLayer);
|
|
6557
|
-
const count = pathElements.length;
|
|
6558
|
-
setPathCount(count);
|
|
6559
|
-
onPathLoad?.(count);
|
|
6560
|
-
}
|
|
6561
|
-
catch (error) {
|
|
6562
|
-
handleError(`加载路径数据失败: ${error instanceof Error ? error.message : String(error)}`);
|
|
8772
|
+
const formatRealTimeData = async (realTimeData) => {
|
|
8773
|
+
// await sleep(1000);
|
|
8774
|
+
const newRealTimeData = handleRealTimeData({
|
|
8775
|
+
realTimeData,
|
|
8776
|
+
isMowing: currentProcessMowingStatusRef.current,
|
|
8777
|
+
pathData: pathJson,
|
|
8778
|
+
partitionBoundary,
|
|
8779
|
+
});
|
|
8780
|
+
console.log('newRealTimeData==', newRealTimeData);
|
|
8781
|
+
// currentProcessMowingStatusRef.current = newRealTimeData.isMowing;
|
|
8782
|
+
currentProcessMowingStatusRef.current = true;
|
|
8783
|
+
// 调用overlay的updatePathData方法,更新历史路径数据
|
|
8784
|
+
if (overlayRef.current) {
|
|
8785
|
+
overlayRef.current.updatePathData(newRealTimeData.pathData);
|
|
6563
8786
|
}
|
|
8787
|
+
overlayRef.current.updateBoundaryLabelInfo(newRealTimeData.pathData);
|
|
6564
8788
|
};
|
|
6565
8789
|
// 初始化效果
|
|
6566
8790
|
useEffect(() => {
|
|
6567
|
-
|
|
6568
|
-
|
|
6569
|
-
}
|
|
6570
|
-
else {
|
|
6571
|
-
initializeSvgView();
|
|
6572
|
-
}
|
|
8791
|
+
initializeGoogleMapsOverlay();
|
|
8792
|
+
console.log('init mow map');
|
|
6573
8793
|
// 清理函数
|
|
6574
8794
|
return () => {
|
|
6575
8795
|
clearSubBoundaryBorder();
|
|
@@ -6583,7 +8803,7 @@ const MowerMapRenderer = forwardRef(({ mapRef, mapJson, pathJson, realTimeData,
|
|
|
6583
8803
|
svgMapViewRef.current = null;
|
|
6584
8804
|
}
|
|
6585
8805
|
};
|
|
6586
|
-
}, [mapJson, pathJson, mergedMapConfig,
|
|
8806
|
+
}, [mapJson, pathJson, mergedMapConfig, mergedAntennaConfig]);
|
|
6587
8807
|
// 监听编辑模式变化
|
|
6588
8808
|
useEffect(() => {
|
|
6589
8809
|
if (overlayRef.current) {
|
|
@@ -6599,9 +8819,9 @@ const MowerMapRenderer = forwardRef(({ mapRef, mapJson, pathJson, realTimeData,
|
|
|
6599
8819
|
useEffect(() => {
|
|
6600
8820
|
if (!mapJson)
|
|
6601
8821
|
return;
|
|
6602
|
-
const elements = MapDataProcessor.processMapData(mapJson);
|
|
8822
|
+
const elements = MapDataProcessor.processMapData(mapJson, mergedMapConfig);
|
|
6603
8823
|
const chargingPiles = elements.find((element) => element.type === 'charging_pile');
|
|
6604
|
-
console.log('chargingPiles==', chargingPiles,
|
|
8824
|
+
console.log('chargingPiles==', chargingPiles, currentPositionData);
|
|
6605
8825
|
if (!mowerPositionData || !overlayRef.current)
|
|
6606
8826
|
return;
|
|
6607
8827
|
const inChargingPiles = [RobotStatus.CHARGING, RobotStatus.PARKED];
|
|
@@ -6632,7 +8852,7 @@ const MowerMapRenderer = forwardRef(({ mapRef, mapJson, pathJson, realTimeData,
|
|
|
6632
8852
|
overlayRef.current.updatePosition(mowerPositionData, isStandyBy ? 0 : 2200);
|
|
6633
8853
|
}
|
|
6634
8854
|
}
|
|
6635
|
-
}, [
|
|
8855
|
+
}, [currentPositionData]);
|
|
6636
8856
|
useEffect(() => {
|
|
6637
8857
|
if (!mapJson ||
|
|
6638
8858
|
!pathJson ||
|
|
@@ -6643,19 +8863,7 @@ const MowerMapRenderer = forwardRef(({ mapRef, mapJson, pathJson, realTimeData,
|
|
|
6643
8863
|
// 根据后端推送的实时数据,进行不同处理
|
|
6644
8864
|
// TODO:需要根据返回的数据,处理车辆的移动位置
|
|
6645
8865
|
// 这里是根据返回的数据,处理实时轨迹
|
|
6646
|
-
|
|
6647
|
-
realTimeData,
|
|
6648
|
-
isMowing: currentProcessMowingStatusRef.current,
|
|
6649
|
-
pathData: pathJson,
|
|
6650
|
-
partitionBoundary,
|
|
6651
|
-
});
|
|
6652
|
-
console.log('newRealTimeData==', newRealTimeData);
|
|
6653
|
-
// currentProcessMowingStatusRef.current = newRealTimeData.isMowing;
|
|
6654
|
-
currentProcessMowingStatusRef.current = true;
|
|
6655
|
-
// 调用overlay的updatePathData方法,更新历史路径数据
|
|
6656
|
-
if (overlayRef.current) {
|
|
6657
|
-
overlayRef.current.updatePathData(newRealTimeData.pathData);
|
|
6658
|
-
}
|
|
8866
|
+
formatRealTimeData(realTimeData);
|
|
6659
8867
|
}, [realTimeData, mapJson, pathJson]);
|
|
6660
8868
|
// 提供ref方法
|
|
6661
8869
|
useImperativeHandle(ref, () => ({
|
|
@@ -6724,21 +8932,8 @@ const MowerMapRenderer = forwardRef(({ mapRef, mapJson, pathJson, realTimeData,
|
|
|
6724
8932
|
if (currentError) {
|
|
6725
8933
|
return (jsx("div", { className: className, style: style, children: jsxs("div", { style: { color: 'red', padding: '10px' }, children: ["\u9519\u8BEF: ", currentError] }) }));
|
|
6726
8934
|
}
|
|
6727
|
-
//
|
|
6728
|
-
|
|
6729
|
-
return null;
|
|
6730
|
-
}
|
|
6731
|
-
// 渲染普通SVG容器
|
|
6732
|
-
return (jsx("div", { ref: containerRef, className: className, style: {
|
|
6733
|
-
width: mergedMapConfig.width || 800,
|
|
6734
|
-
height: mergedMapConfig.height || 600,
|
|
6735
|
-
backgroundColor: mergedMapConfig.backgroundColor || '#f5f5f5',
|
|
6736
|
-
borderRadius: mergedMapConfig.borderRadius || '8px',
|
|
6737
|
-
border: mergedMapConfig.border || '1px solid #ddd',
|
|
6738
|
-
position: 'relative',
|
|
6739
|
-
overflow: 'hidden',
|
|
6740
|
-
...style,
|
|
6741
|
-
} }));
|
|
8935
|
+
// 使用goole maps自定义叠加层,不需要实际返回组件内容
|
|
8936
|
+
return null;
|
|
6742
8937
|
});
|
|
6743
8938
|
MowerMapRenderer.displayName = 'MowerMapRenderer';
|
|
6744
8939
|
|