microboard-temp 0.5.75 → 0.5.77
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/cjs/browser.js +116 -99
- package/dist/cjs/index.js +116 -99
- package/dist/cjs/node.js +116 -99
- package/dist/esm/browser.js +116 -99
- package/dist/esm/index.js +116 -99
- package/dist/esm/node.js +116 -99
- package/dist/types/Settings.d.ts +1 -0
- package/package.json +1 -1
package/dist/cjs/browser.js
CHANGED
|
@@ -7073,7 +7073,8 @@ var conf = {
|
|
|
7073
7073
|
DECK_VERTICAL_OFFSET: 2,
|
|
7074
7074
|
CARD_DIMENSIONS: { width: 250, height: 400 },
|
|
7075
7075
|
DEFAULT_GAME_ITEM_DIMENSIONS: { width: 200, height: 200 },
|
|
7076
|
-
MAX_CARD_SIZE: 500
|
|
7076
|
+
MAX_CARD_SIZE: 500,
|
|
7077
|
+
CONNECTOR_ITEM_OFFSET: 20
|
|
7077
7078
|
};
|
|
7078
7079
|
initDefaultI18N();
|
|
7079
7080
|
|
|
@@ -36669,7 +36670,6 @@ function radiansBetweenPoints(point1, point22) {
|
|
|
36669
36670
|
}
|
|
36670
36671
|
|
|
36671
36672
|
// src/Items/Connector/getLine/findOrthogonalPath.ts
|
|
36672
|
-
var ITEM_OFFSET = 1;
|
|
36673
36673
|
function getDirection(from, to) {
|
|
36674
36674
|
if (!to) {
|
|
36675
36675
|
return null;
|
|
@@ -36710,9 +36710,9 @@ function getNeighbors(node2, grid, obstacles) {
|
|
|
36710
36710
|
{ x: node2.xGrid, y: node2.yGrid + 1 }
|
|
36711
36711
|
];
|
|
36712
36712
|
for (const pos of potentialNeighbors) {
|
|
36713
|
-
if (pos.x >= 0 && pos.x < grid.length && pos.y >= 0) {
|
|
36713
|
+
if (pos.x >= 0 && pos.x < grid.length && pos.y >= 0 && grid[pos.x] && grid[pos.x][pos.y]) {
|
|
36714
36714
|
const newPoint = grid[pos.x][pos.y];
|
|
36715
|
-
if (newPoint && !obstacles.some((obstacle) => obstacle.isAlmostInside(newPoint,
|
|
36715
|
+
if (newPoint && !obstacles.some((obstacle) => obstacle.isAlmostInside(newPoint, conf.CONNECTOR_ITEM_OFFSET - 1))) {
|
|
36716
36716
|
neighbors.push({
|
|
36717
36717
|
point: newPoint,
|
|
36718
36718
|
costSoFar: 0,
|
|
@@ -36740,16 +36740,20 @@ function findCenterLine(grid, start, end, middle) {
|
|
|
36740
36740
|
}
|
|
36741
36741
|
if (width > height) {
|
|
36742
36742
|
const centerIdx = grid.findIndex((row2) => row2[0].x === middlePoint.x || Math.abs(row2[0].x - middlePoint.x) < 0.01);
|
|
36743
|
-
|
|
36744
|
-
|
|
36745
|
-
|
|
36743
|
+
if (centerIdx !== -1) {
|
|
36744
|
+
for (let y = 0;y < grid[0].length; y++) {
|
|
36745
|
+
if (grid[centerIdx][y] && grid[centerIdx][y].x >= min2.x - 0.01 && grid[centerIdx][y].x <= max2.x + 0.01 && grid[centerIdx][y].y >= min2.y - 0.01 && grid[centerIdx][y].y <= max2.y + 0.01) {
|
|
36746
|
+
centerLine.push(grid[centerIdx][y]);
|
|
36747
|
+
}
|
|
36746
36748
|
}
|
|
36747
36749
|
}
|
|
36748
36750
|
} else {
|
|
36749
36751
|
const centerIdx = grid[0].findIndex((point5) => point5.y === middlePoint.y || Math.abs(point5.y - middlePoint.y) < 0.01);
|
|
36750
|
-
|
|
36751
|
-
|
|
36752
|
-
|
|
36752
|
+
if (centerIdx !== -1) {
|
|
36753
|
+
for (let x = 0;x < grid.length; x++) {
|
|
36754
|
+
if (grid[x][centerIdx] && grid[x][centerIdx].x >= min2.x - 0.01 && grid[x][centerIdx].x <= max2.x + 0.01 && grid[x][centerIdx].y >= min2.y - 0.01 && grid[x][centerIdx].y <= max2.y + 0.01) {
|
|
36755
|
+
centerLine.push(grid[x][centerIdx]);
|
|
36756
|
+
}
|
|
36753
36757
|
}
|
|
36754
36758
|
}
|
|
36755
36759
|
}
|
|
@@ -36760,69 +36764,24 @@ function createGrid(start, end, toVisitPoints = []) {
|
|
|
36760
36764
|
const endDir = getPointerDirection(end);
|
|
36761
36765
|
const revertMapDir = { top: 0, bottom: 1, right: 2, left: 3 };
|
|
36762
36766
|
const offsetMap = {
|
|
36763
|
-
top: { x: 0, y: -
|
|
36764
|
-
bottom: { x: 0, y:
|
|
36765
|
-
right: { x:
|
|
36766
|
-
left: { x: -
|
|
36767
|
+
top: { x: 0, y: -conf.CONNECTOR_ITEM_OFFSET },
|
|
36768
|
+
bottom: { x: 0, y: conf.CONNECTOR_ITEM_OFFSET },
|
|
36769
|
+
right: { x: conf.CONNECTOR_ITEM_OFFSET, y: 0 },
|
|
36770
|
+
left: { x: -conf.CONNECTOR_ITEM_OFFSET, y: 0 }
|
|
36767
36771
|
};
|
|
36768
36772
|
const horizontalLines = [];
|
|
36769
36773
|
const verticalLines = [];
|
|
36770
|
-
if (start.pointType !== "Board") {
|
|
36771
|
-
const itemMbr = start.item.getMbr();
|
|
36772
|
-
verticalLines.push(itemMbr.left - ITEM_OFFSET, itemMbr.left, itemMbr.right, itemMbr.right + ITEM_OFFSET);
|
|
36773
|
-
horizontalLines.push(itemMbr.top - ITEM_OFFSET, itemMbr.top, itemMbr.bottom, itemMbr.bottom + ITEM_OFFSET);
|
|
36774
|
-
}
|
|
36775
|
-
if (end.pointType !== "Board") {
|
|
36776
|
-
const itemMbr = end.item.getMbr();
|
|
36777
|
-
verticalLines.push(itemMbr.left - ITEM_OFFSET, itemMbr.left, itemMbr.right, itemMbr.right + ITEM_OFFSET);
|
|
36778
|
-
horizontalLines.push(itemMbr.top - ITEM_OFFSET, itemMbr.top, itemMbr.bottom, itemMbr.bottom + ITEM_OFFSET);
|
|
36779
|
-
}
|
|
36780
|
-
const tempStart = start;
|
|
36781
|
-
const tempEnd = end;
|
|
36782
|
-
const middle = new Point((tempStart.x + tempEnd.x) / 2, (tempStart.y + tempEnd.y) / 2);
|
|
36783
|
-
horizontalLines.push(middle.y, tempStart.y, tempEnd.y);
|
|
36784
|
-
verticalLines.push(middle.x, tempStart.x, tempEnd.x);
|
|
36785
|
-
toVisitPoints.forEach((p3) => {
|
|
36786
|
-
horizontalLines.push(p3.y);
|
|
36787
|
-
verticalLines.push(p3.x);
|
|
36788
|
-
});
|
|
36789
|
-
const uniqueHorizontalLines = Array.from(new Set(horizontalLines)).sort((a2, b) => a2 - b);
|
|
36790
|
-
const uniqueVerticalLines = Array.from(new Set(verticalLines)).sort((a2, b) => a2 - b);
|
|
36791
36774
|
let newStart;
|
|
36792
36775
|
let newEnd;
|
|
36793
36776
|
const processPoint = (point5, dir2) => {
|
|
36794
36777
|
const itemMbr = point5.item.getMbr();
|
|
36795
|
-
const
|
|
36778
|
+
const mbrFloored = new Mbr(Math.floor(itemMbr.left), Math.floor(itemMbr.top), Math.floor(itemMbr.right), Math.floor(itemMbr.bottom));
|
|
36779
|
+
const pointOnMbr = mbrFloored.getLines()[revertMapDir[dir2]].getNearestPointOnLineSegment(point5);
|
|
36796
36780
|
const newPoint = Object.create(Object.getPrototypeOf(point5), Object.getOwnPropertyDescriptors(point5));
|
|
36797
|
-
|
|
36798
|
-
|
|
36799
|
-
|
|
36800
|
-
|
|
36801
|
-
newPoint.y = uniqueHorizontalLines[nextYIndex];
|
|
36802
|
-
newPoint.x = pointOnMbr.x;
|
|
36803
|
-
}
|
|
36804
|
-
} else if (dir2 === "bottom") {
|
|
36805
|
-
const currentYIndex = uniqueHorizontalLines.findIndex((y) => Math.abs(y - pointOnMbr.y) < 0.01);
|
|
36806
|
-
const nextYIndex = currentYIndex + 1;
|
|
36807
|
-
if (nextYIndex < uniqueHorizontalLines.length) {
|
|
36808
|
-
newPoint.y = uniqueHorizontalLines[nextYIndex];
|
|
36809
|
-
newPoint.x = pointOnMbr.x;
|
|
36810
|
-
}
|
|
36811
|
-
} else if (dir2 === "left") {
|
|
36812
|
-
const currentXIndex = uniqueVerticalLines.findIndex((x) => Math.abs(x - pointOnMbr.x) < 0.01);
|
|
36813
|
-
const nextXIndex = currentXIndex - 1;
|
|
36814
|
-
if (nextXIndex >= 0) {
|
|
36815
|
-
newPoint.x = uniqueVerticalLines[nextXIndex];
|
|
36816
|
-
newPoint.y = pointOnMbr.y;
|
|
36817
|
-
}
|
|
36818
|
-
} else if (dir2 === "right") {
|
|
36819
|
-
const currentXIndex = uniqueVerticalLines.findIndex((x) => Math.abs(x - pointOnMbr.x) < 0.01);
|
|
36820
|
-
const nextXIndex = currentXIndex + 1;
|
|
36821
|
-
if (nextXIndex < uniqueVerticalLines.length) {
|
|
36822
|
-
newPoint.x = uniqueVerticalLines[nextXIndex];
|
|
36823
|
-
newPoint.y = pointOnMbr.y;
|
|
36824
|
-
}
|
|
36825
|
-
}
|
|
36781
|
+
newPoint.x = pointOnMbr.x + offsetMap[dir2].x;
|
|
36782
|
+
newPoint.y = pointOnMbr.y + offsetMap[dir2].y;
|
|
36783
|
+
verticalLines.push(mbrFloored.left - conf.CONNECTOR_ITEM_OFFSET, mbrFloored.left, pointOnMbr.x, mbrFloored.right, mbrFloored.right + conf.CONNECTOR_ITEM_OFFSET);
|
|
36784
|
+
horizontalLines.push(mbrFloored.top - conf.CONNECTOR_ITEM_OFFSET, mbrFloored.top, pointOnMbr.y, mbrFloored.bottom, mbrFloored.bottom + conf.CONNECTOR_ITEM_OFFSET);
|
|
36826
36785
|
return newPoint;
|
|
36827
36786
|
};
|
|
36828
36787
|
if (start.pointType !== "Board" && startDir) {
|
|
@@ -36831,6 +36790,17 @@ function createGrid(start, end, toVisitPoints = []) {
|
|
|
36831
36790
|
if (end.pointType !== "Board" && endDir) {
|
|
36832
36791
|
newEnd = processPoint(end, endDir);
|
|
36833
36792
|
}
|
|
36793
|
+
const finalStart = newStart || start;
|
|
36794
|
+
const finalEnd = newEnd || end;
|
|
36795
|
+
const middle = new Point((finalStart.x + finalEnd.x) / 2, (finalStart.y + finalEnd.y) / 2);
|
|
36796
|
+
horizontalLines.push(middle.y, finalStart.y, finalEnd.y);
|
|
36797
|
+
verticalLines.push(middle.x, finalStart.x, finalEnd.x);
|
|
36798
|
+
toVisitPoints.forEach((p3) => {
|
|
36799
|
+
horizontalLines.push(p3.y);
|
|
36800
|
+
verticalLines.push(p3.x);
|
|
36801
|
+
});
|
|
36802
|
+
const uniqueHorizontalLines = Array.from(new Set(horizontalLines)).sort((a2, b) => a2 - b);
|
|
36803
|
+
const uniqueVerticalLines = Array.from(new Set(verticalLines)).sort((a2, b) => a2 - b);
|
|
36834
36804
|
const grid = uniqueVerticalLines.map((x) => uniqueHorizontalLines.map((y) => new Point(x, y)));
|
|
36835
36805
|
return {
|
|
36836
36806
|
grid,
|
|
@@ -36839,18 +36809,27 @@ function createGrid(start, end, toVisitPoints = []) {
|
|
|
36839
36809
|
middlePoint: middle
|
|
36840
36810
|
};
|
|
36841
36811
|
}
|
|
36842
|
-
function findPath(start, end, grid, obstacles, newStart, newEnd) {
|
|
36843
|
-
const
|
|
36844
|
-
|
|
36845
|
-
|
|
36846
|
-
|
|
36812
|
+
function findPath(start, end, grid, obstacles, existingPath, newStart, newEnd) {
|
|
36813
|
+
const startRowIndex = grid.findIndex((row2) => row2.some((point5) => point5.barelyEqual(start)));
|
|
36814
|
+
if (startRowIndex === -1) {
|
|
36815
|
+
throw new Error("Start point not found in the grid row");
|
|
36816
|
+
}
|
|
36817
|
+
const startPointIndex = grid[startRowIndex].findIndex((point5) => point5.barelyEqual(start));
|
|
36818
|
+
if (startPointIndex === -1) {
|
|
36819
|
+
throw new Error("Start point not found in the grid column");
|
|
36820
|
+
}
|
|
36821
|
+
const endRowIndex = grid.findIndex((row2) => row2.some((point5) => point5.barelyEqual(end)));
|
|
36822
|
+
if (endRowIndex === -1) {
|
|
36823
|
+
throw new Error("End point not found in the grid row");
|
|
36824
|
+
}
|
|
36825
|
+
const endPointIndex = grid[endRowIndex].findIndex((point5) => point5.barelyEqual(end));
|
|
36826
|
+
if (endPointIndex === -1) {
|
|
36827
|
+
throw new Error("End point not found in the grid column");
|
|
36847
36828
|
}
|
|
36848
|
-
const startPointIdx = grid[startIdx].findIndex((point5) => point5.barelyEqual(start));
|
|
36849
|
-
const endPointIdx = grid[endIdx].findIndex((point5) => point5.barelyEqual(end));
|
|
36850
36829
|
const endNode = {
|
|
36851
36830
|
point: end,
|
|
36852
|
-
xGrid:
|
|
36853
|
-
yGrid:
|
|
36831
|
+
xGrid: endRowIndex,
|
|
36832
|
+
yGrid: endPointIndex,
|
|
36854
36833
|
costSoFar: 0,
|
|
36855
36834
|
heuristic: 0,
|
|
36856
36835
|
toFinish: 0
|
|
@@ -36858,53 +36837,72 @@ function findPath(start, end, grid, obstacles, newStart, newEnd) {
|
|
|
36858
36837
|
const startNode = {
|
|
36859
36838
|
point: start,
|
|
36860
36839
|
costSoFar: 0,
|
|
36861
|
-
heuristic: heuristic({ point: start, xGrid:
|
|
36862
|
-
toFinish: heuristic({ point: start, xGrid:
|
|
36863
|
-
xGrid:
|
|
36864
|
-
yGrid:
|
|
36840
|
+
heuristic: heuristic({ point: start, xGrid: startRowIndex, yGrid: startPointIndex }, endNode),
|
|
36841
|
+
toFinish: heuristic({ point: start, xGrid: startRowIndex, yGrid: startPointIndex }, endNode),
|
|
36842
|
+
xGrid: startRowIndex,
|
|
36843
|
+
yGrid: startPointIndex
|
|
36865
36844
|
};
|
|
36866
36845
|
const openSet = [startNode];
|
|
36867
36846
|
const closedSet = new Set;
|
|
36868
36847
|
while (openSet.length > 0) {
|
|
36869
36848
|
openSet.sort((aa, bb) => aa.toFinish - bb.toFinish);
|
|
36870
36849
|
const current = openSet.shift();
|
|
36850
|
+
const currentKey = `${current.point.x},${current.point.y}`;
|
|
36871
36851
|
if (current.point.barelyEqual(end)) {
|
|
36872
36852
|
const path2 = reconstructPath(current);
|
|
36873
36853
|
return path2;
|
|
36874
36854
|
}
|
|
36875
|
-
closedSet.add(
|
|
36855
|
+
closedSet.add(currentKey);
|
|
36876
36856
|
const neighbors = getNeighbors(current, grid, obstacles);
|
|
36877
36857
|
for (const neighbor of neighbors) {
|
|
36878
|
-
|
|
36858
|
+
const neighborKey = `${neighbor.point.x},${neighbor.point.y}`;
|
|
36859
|
+
if (closedSet.has(neighborKey) || existingPath.has(neighborKey) && !neighbor.point.barelyEqual(end)) {
|
|
36879
36860
|
continue;
|
|
36880
36861
|
}
|
|
36881
36862
|
const extraCost = isChangingDirection(current, neighbor, newStart, newEnd);
|
|
36882
|
-
const
|
|
36883
|
-
|
|
36884
|
-
|
|
36885
|
-
|
|
36886
|
-
|
|
36887
|
-
|
|
36863
|
+
const pathOverlapCost = existingPath.has(neighborKey) ? 1000 : 0;
|
|
36864
|
+
const tentativeCost = current.costSoFar + 1 + pathOverlapCost;
|
|
36865
|
+
let existingNodeInOpenSet = openSet.find((node2) => node2.point.barelyEqual(neighbor.point));
|
|
36866
|
+
if (!existingNodeInOpenSet || tentativeCost < existingNodeInOpenSet.costSoFar) {
|
|
36867
|
+
if (existingNodeInOpenSet) {
|
|
36868
|
+
existingNodeInOpenSet.costSoFar = tentativeCost + extraCost;
|
|
36869
|
+
existingNodeInOpenSet.heuristic = heuristic(neighbor, endNode);
|
|
36870
|
+
existingNodeInOpenSet.toFinish = existingNodeInOpenSet.costSoFar + existingNodeInOpenSet.heuristic;
|
|
36871
|
+
existingNodeInOpenSet.parent = current;
|
|
36872
|
+
} else {
|
|
36873
|
+
neighbor.costSoFar = tentativeCost + extraCost;
|
|
36874
|
+
neighbor.heuristic = heuristic(neighbor, endNode);
|
|
36875
|
+
neighbor.toFinish = neighbor.costSoFar + neighbor.heuristic;
|
|
36876
|
+
openSet.push(neighbor);
|
|
36877
|
+
}
|
|
36888
36878
|
}
|
|
36889
36879
|
}
|
|
36890
36880
|
}
|
|
36891
36881
|
return;
|
|
36892
36882
|
}
|
|
36893
36883
|
function findPathPoints(points, grid, obstacles, newStart, newEnd) {
|
|
36894
|
-
const
|
|
36884
|
+
const finalPath = [];
|
|
36885
|
+
const existingPathSegments = new Set;
|
|
36886
|
+
if (points.length > 0) {
|
|
36887
|
+
finalPath.push(points[0]);
|
|
36888
|
+
const startKey = `${points[0].x},${points[0].y}`;
|
|
36889
|
+
existingPathSegments.add(startKey);
|
|
36890
|
+
}
|
|
36895
36891
|
for (let i = 0;i < points.length - 1; i += 1) {
|
|
36896
|
-
const segmentPath = findPath(points[i], points[i + 1], grid, obstacles, newStart, newEnd);
|
|
36897
|
-
if (segmentPath) {
|
|
36898
|
-
|
|
36892
|
+
const segmentPath = findPath(points[i], points[i + 1], grid, obstacles, existingPathSegments, newStart, newEnd);
|
|
36893
|
+
if (segmentPath && segmentPath.length > 0) {
|
|
36894
|
+
for (let j = 1;j < segmentPath.length; j++) {
|
|
36895
|
+
const point5 = segmentPath[j];
|
|
36896
|
+
const key = `${point5.x},${point5.y}`;
|
|
36897
|
+
finalPath.push(point5);
|
|
36898
|
+
existingPathSegments.add(key);
|
|
36899
|
+
}
|
|
36899
36900
|
} else {
|
|
36900
36901
|
points.splice(i + 1, 1);
|
|
36901
36902
|
i--;
|
|
36902
36903
|
}
|
|
36903
36904
|
}
|
|
36904
|
-
|
|
36905
|
-
pathPoints.push(points[points.length - 1]);
|
|
36906
|
-
}
|
|
36907
|
-
return pathPoints;
|
|
36905
|
+
return finalPath;
|
|
36908
36906
|
}
|
|
36909
36907
|
function reducePoints(points) {
|
|
36910
36908
|
const uniquePoints = new Map;
|
|
@@ -36915,6 +36913,12 @@ function reducePoints(points) {
|
|
|
36915
36913
|
if (uniquePoints.has(key)) {
|
|
36916
36914
|
const loopStartIndex = uniquePoints.get(key);
|
|
36917
36915
|
result.splice(loopStartIndex + 1);
|
|
36916
|
+
const removedPoints = points.slice(loopStartIndex + 1, i + 1);
|
|
36917
|
+
removedPoints.forEach((p3) => {
|
|
36918
|
+
uniquePoints.delete(`${p3.x},${p3.y}`);
|
|
36919
|
+
});
|
|
36920
|
+
uniquePoints.set(key, result.length);
|
|
36921
|
+
result.push(point5);
|
|
36918
36922
|
} else {
|
|
36919
36923
|
uniquePoints.set(key, result.length);
|
|
36920
36924
|
result.push(point5);
|
|
@@ -36924,19 +36928,32 @@ function reducePoints(points) {
|
|
|
36924
36928
|
}
|
|
36925
36929
|
function getLines(pathPoints) {
|
|
36926
36930
|
const lines = [];
|
|
36931
|
+
if (pathPoints.length < 2) {
|
|
36932
|
+
return [];
|
|
36933
|
+
}
|
|
36927
36934
|
const reducedPoints = reducePoints(pathPoints);
|
|
36935
|
+
if (reducedPoints.length < 2) {
|
|
36936
|
+
return [];
|
|
36937
|
+
}
|
|
36928
36938
|
let startPoint = reducedPoints[0];
|
|
36929
|
-
for (let i = 1;i < reducedPoints.length
|
|
36939
|
+
for (let i = 1;i < reducedPoints.length; i += 1) {
|
|
36930
36940
|
const prevPoint = reducedPoints[i - 1];
|
|
36931
36941
|
const currPoint = reducedPoints[i];
|
|
36932
|
-
const nextPoint = reducedPoints[i + 1];
|
|
36933
|
-
if (prevPoint.x !== nextPoint.x && prevPoint.y !== nextPoint.y) {
|
|
36942
|
+
const nextPoint = i + 1 < reducedPoints.length ? reducedPoints[i + 1] : null;
|
|
36943
|
+
if (!nextPoint || prevPoint.x !== nextPoint.x && prevPoint.y !== nextPoint.y) {
|
|
36934
36944
|
lines.push(new Line(startPoint, currPoint));
|
|
36935
36945
|
startPoint = currPoint;
|
|
36936
36946
|
}
|
|
36937
36947
|
}
|
|
36938
|
-
if (lines.length >
|
|
36939
|
-
lines.push(new Line(
|
|
36948
|
+
if (lines.length === 0 && reducedPoints.length > 1) {
|
|
36949
|
+
lines.push(new Line(reducedPoints[0], reducedPoints[reducedPoints.length - 1]));
|
|
36950
|
+
} else if (lines.length > 0) {
|
|
36951
|
+
const lastLine = lines[lines.length - 1];
|
|
36952
|
+
const lastPointInLines = lastLine.getEndPoint();
|
|
36953
|
+
const lastPointInReduced = reducedPoints[reducedPoints.length - 1];
|
|
36954
|
+
if (!lastPointInLines.barelyEqual(lastPointInReduced)) {
|
|
36955
|
+
lines.push(new Line(lastPointInLines, lastPointInReduced));
|
|
36956
|
+
}
|
|
36940
36957
|
}
|
|
36941
36958
|
return lines;
|
|
36942
36959
|
}
|