@abi-software/flatmapvuer 1.13.5-demo.7 → 1.14.0
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/flatmapvuer.js +1256 -1391
- package/dist/flatmapvuer.umd.cjs +10 -18
- package/dist/style.css +1 -1
- package/package.json +9 -4
- package/src/components/FlatmapVuer.vue +2 -135
- package/src/components/MultiFlatmapVuer.vue +0 -9
- package/src/services/flatmapLoader.js +1 -1
- package/src/services/somaLocationMarkers.js +0 -125
package/package.json
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abi-software/flatmapvuer",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.14.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
|
+
"engines": {
|
|
6
|
+
"node": ">=20"
|
|
7
|
+
},
|
|
5
8
|
"files": [
|
|
6
9
|
"dist/*",
|
|
7
10
|
"src/*",
|
|
@@ -44,9 +47,9 @@
|
|
|
44
47
|
"./src/*": "./src/*"
|
|
45
48
|
},
|
|
46
49
|
"dependencies": {
|
|
47
|
-
"@abi-software/map-utilities": "1.
|
|
50
|
+
"@abi-software/map-utilities": "1.9.0",
|
|
48
51
|
"@abi-software/sparc-annotation": "0.3.2",
|
|
49
|
-
"@abi-software/svg-sprite": "1.0
|
|
52
|
+
"@abi-software/svg-sprite": "1.1.0",
|
|
50
53
|
"@element-plus/icons-vue": "^2.3.1",
|
|
51
54
|
"css-element-queries": "^1.2.2",
|
|
52
55
|
"element-plus": "2.8.4",
|
|
@@ -77,7 +80,9 @@
|
|
|
77
80
|
},
|
|
78
81
|
"optionalDependencies": {
|
|
79
82
|
"@esbuild/linux-x64": "0.25.3",
|
|
80
|
-
"@rollup/rollup-
|
|
83
|
+
"@rollup/rollup-darwin-arm64": "4.59.0",
|
|
84
|
+
"@rollup/rollup-linux-x64-gnu": "4.59.0",
|
|
85
|
+
"@rollup/rollup-win32-x64-msvc": "4.59.0"
|
|
81
86
|
},
|
|
82
87
|
"eslintConfig": {
|
|
83
88
|
"root": true,
|
|
@@ -634,7 +634,6 @@ import { capitalise, normaliseAlertToStringArray } from './utilities.js'
|
|
|
634
634
|
import yellowstar from '../icons/yellowstar'
|
|
635
635
|
import ResizeSensor from 'css-element-queries/src/ResizeSensor'
|
|
636
636
|
import flatmap from '../services/flatmapLoader.js'
|
|
637
|
-
import { attachSomaLocationMarkerMethods } from '../services/somaLocationMarkers.js'
|
|
638
637
|
import { AnnotationService } from '@abi-software/sparc-annotation'
|
|
639
638
|
import { mapState } from 'pinia'
|
|
640
639
|
import { useMainStore } from '@/store/index'
|
|
@@ -1738,9 +1737,6 @@ export default {
|
|
|
1738
1737
|
provenanceTaxonomy: taxons,
|
|
1739
1738
|
alert: featuresAlert
|
|
1740
1739
|
}]
|
|
1741
|
-
if (eventType === 'mouseenter') {
|
|
1742
|
-
this.lastHoveredFeature = data;
|
|
1743
|
-
}
|
|
1744
1740
|
if (eventType === 'click') {
|
|
1745
1741
|
// If multiple paths overlap at the click location,
|
|
1746
1742
|
// `data` is an object with numeric keys for each feature (e.g., {0: {...}, 1: {...}, ..., mapUUID: '...'}).
|
|
@@ -1860,7 +1856,6 @@ export default {
|
|
|
1860
1856
|
// Fallback: remove any existing toolitp on DOM
|
|
1861
1857
|
const tooltips = this.$el.querySelectorAll('.flatmap-tooltip-popup');
|
|
1862
1858
|
tooltips.forEach((tooltip) => tooltip.remove());
|
|
1863
|
-
this.lastHoveredFeature = null;
|
|
1864
1859
|
},
|
|
1865
1860
|
/**
|
|
1866
1861
|
* Function to create tooltip for the provided connectivity data.
|
|
@@ -1904,9 +1899,6 @@ export default {
|
|
|
1904
1899
|
const connectivityData = [];
|
|
1905
1900
|
const errorData = [];
|
|
1906
1901
|
|
|
1907
|
-
// Remove last hovered feature to avoid showing tooltip for the last hovered feature.
|
|
1908
|
-
this.lastHoveredFeature = null;
|
|
1909
|
-
|
|
1910
1902
|
// to keep the highlighted path on map
|
|
1911
1903
|
if (connectivityInfo && connectivityInfo.featureId) {
|
|
1912
1904
|
featuresToHighlight.push(...connectivityInfo.featureId);
|
|
@@ -2310,7 +2302,6 @@ export default {
|
|
|
2310
2302
|
document.querySelectorAll('.maplibregl-popup').forEach((item) => {
|
|
2311
2303
|
item.style.display = 'none'
|
|
2312
2304
|
})
|
|
2313
|
-
this.lastHoveredFeature = null;
|
|
2314
2305
|
},
|
|
2315
2306
|
/**
|
|
2316
2307
|
* @public
|
|
@@ -2846,7 +2837,7 @@ export default {
|
|
|
2846
2837
|
}
|
|
2847
2838
|
)
|
|
2848
2839
|
promise1.then((returnedObject) => {
|
|
2849
|
-
this.mapImp =
|
|
2840
|
+
this.mapImp = returnedObject
|
|
2850
2841
|
this.serverURL = this.mapImp.makeServerUrl('').slice(0, -1)
|
|
2851
2842
|
let mapVersion = this.mapImp.details.version
|
|
2852
2843
|
this.setFlightPathInfo(mapVersion)
|
|
@@ -3115,22 +3106,10 @@ export default {
|
|
|
3115
3106
|
provenanceTaxonomy: feature.taxons,
|
|
3116
3107
|
alert: normaliseAlertToStringArray(feature.alert),
|
|
3117
3108
|
}
|
|
3118
|
-
|
|
3119
3109
|
// Show popup for all modes
|
|
3120
3110
|
this.checkAndCreatePopups([data], mapclick)
|
|
3121
|
-
|
|
3122
|
-
// Check pathway fetures and set lastHoveredFeature for tooltip content replacement.
|
|
3123
|
-
const isPathwayFeature = (feature.id.startsWith('ilxtr:') || feature.id.startsWith('ilx:'));
|
|
3124
|
-
if (isPathwayFeature) {
|
|
3125
|
-
this.lastHoveredFeature = feature;
|
|
3126
|
-
this.lastHoveredFeature.mapUUID = this.mapImp.uuid;
|
|
3127
|
-
} else {
|
|
3128
|
-
this.lastHoveredFeature = null;
|
|
3129
|
-
}
|
|
3130
|
-
|
|
3131
|
-
// flatmap-tooltip-popup is used for custom tooltip content replacement.
|
|
3132
3111
|
this.mapImp.showPopup(featureId, capitalise(feature.label), {
|
|
3133
|
-
className:
|
|
3112
|
+
className: 'custom-popup',
|
|
3134
3113
|
positionAtLastClick: false,
|
|
3135
3114
|
preserveSelection: true,
|
|
3136
3115
|
})
|
|
@@ -3174,62 +3153,6 @@ export default {
|
|
|
3174
3153
|
setConnectionType: function (type) {
|
|
3175
3154
|
this.connectionType = type;
|
|
3176
3155
|
},
|
|
3177
|
-
/**
|
|
3178
|
-
* MutationObserver callback to intercept tooltip popup DOM elements
|
|
3179
|
-
* and customize their content before the browser renders them.
|
|
3180
|
-
*/
|
|
3181
|
-
_handleTooltipMutation: function (mutations) {
|
|
3182
|
-
for (const mutation of mutations) {
|
|
3183
|
-
for (const node of mutation.addedNodes) {
|
|
3184
|
-
if (node.nodeType === 1) {
|
|
3185
|
-
// Check if the added node itself is the tooltip popup
|
|
3186
|
-
if (node.matches && node.matches('.flatmap-tooltip-popup')) {
|
|
3187
|
-
this._applyCustomTooltipContent(node);
|
|
3188
|
-
} else if (node.querySelector) {
|
|
3189
|
-
// Check if it contains a tooltip popup
|
|
3190
|
-
const popup = node.querySelector('.flatmap-tooltip-popup');
|
|
3191
|
-
if (popup) {
|
|
3192
|
-
this._applyCustomTooltipContent(popup);
|
|
3193
|
-
}
|
|
3194
|
-
}
|
|
3195
|
-
}
|
|
3196
|
-
}
|
|
3197
|
-
}
|
|
3198
|
-
},
|
|
3199
|
-
/**
|
|
3200
|
-
* Replace the default tooltip content with custom content from
|
|
3201
|
-
* the tooltipContentProvider prop, if available.
|
|
3202
|
-
*/
|
|
3203
|
-
_applyCustomTooltipContent: function (popupEl) {
|
|
3204
|
-
if (!this.tooltipContentProvider || !this.lastHoveredFeature) return;
|
|
3205
|
-
try {
|
|
3206
|
-
const featureData = this.lastHoveredFeature;
|
|
3207
|
-
// Detect multi-feature data format used by click events when multiple
|
|
3208
|
-
// paths overlap: {0: {...}, 1: {...}, ..., mapUUID: '...'}
|
|
3209
|
-
const isMultiFeature = featureData[0] && typeof featureData[0] === 'object';
|
|
3210
|
-
let customHtml;
|
|
3211
|
-
if (isMultiFeature) {
|
|
3212
|
-
const features = [];
|
|
3213
|
-
const mapUUID = featureData.mapUUID;
|
|
3214
|
-
for (const [key, value] of Object.entries(featureData)) {
|
|
3215
|
-
if (key !== 'mapUUID' && value && typeof value === 'object') {
|
|
3216
|
-
features.push({ ...value, mapUUID });
|
|
3217
|
-
}
|
|
3218
|
-
}
|
|
3219
|
-
customHtml = this.tooltipContentProvider(features.length > 1 ? features : features[0]);
|
|
3220
|
-
} else {
|
|
3221
|
-
customHtml = this.tooltipContentProvider(featureData);
|
|
3222
|
-
}
|
|
3223
|
-
if (customHtml) {
|
|
3224
|
-
const contentEl = popupEl.querySelector('.maplibregl-popup-content');
|
|
3225
|
-
if (contentEl) {
|
|
3226
|
-
contentEl.innerHTML = customHtml;
|
|
3227
|
-
}
|
|
3228
|
-
}
|
|
3229
|
-
} catch (e) {
|
|
3230
|
-
console.warn('[flatmapvuer] Error in tooltipContentProvider:', e);
|
|
3231
|
-
}
|
|
3232
|
-
},
|
|
3233
3156
|
},
|
|
3234
3157
|
props: {
|
|
3235
3158
|
/**
|
|
@@ -3470,17 +3393,6 @@ export default {
|
|
|
3470
3393
|
return []
|
|
3471
3394
|
},
|
|
3472
3395
|
},
|
|
3473
|
-
/**
|
|
3474
|
-
* A function that provides custom tooltip HTML content for path features.
|
|
3475
|
-
* The function receives the feature data from the mouseenter event (including `id`, `label`, etc.)
|
|
3476
|
-
* and should return an HTML string to display in the tooltip, or return null/undefined
|
|
3477
|
-
* to keep the default tooltip.
|
|
3478
|
-
* This is used by mapintegratedvuer to show 'long-label' from connectivity knowledge.
|
|
3479
|
-
*/
|
|
3480
|
-
tooltipContentProvider: {
|
|
3481
|
-
type: Function,
|
|
3482
|
-
default: null,
|
|
3483
|
-
},
|
|
3484
3396
|
},
|
|
3485
3397
|
provide() {
|
|
3486
3398
|
return {
|
|
@@ -3583,8 +3495,6 @@ export default {
|
|
|
3583
3495
|
drawnCreatedEvent: {},
|
|
3584
3496
|
previousEditEvent: {},
|
|
3585
3497
|
previousDeletedEvent: {},
|
|
3586
|
-
lastHoveredFeature: null,
|
|
3587
|
-
tooltipObserver: null,
|
|
3588
3498
|
connectionEntry: {},
|
|
3589
3499
|
existDrawnFeatures: [], // Store all exist drawn features
|
|
3590
3500
|
doubleClickedFeature: false,
|
|
@@ -3783,27 +3693,6 @@ export default {
|
|
|
3783
3693
|
this.createFlatmap()
|
|
3784
3694
|
}
|
|
3785
3695
|
refreshFlatmapKnowledgeCache();
|
|
3786
|
-
|
|
3787
|
-
// Set up MutationObserver to customize tooltip content when
|
|
3788
|
-
// tooltipContentProvider prop is provided.
|
|
3789
|
-
if (this.tooltipContentProvider) {
|
|
3790
|
-
this.$nextTick(() => {
|
|
3791
|
-
const container = this.$refs.flatmapContainer || this.$el;
|
|
3792
|
-
if (container) {
|
|
3793
|
-
this.tooltipObserver = new MutationObserver(this._handleTooltipMutation.bind(this));
|
|
3794
|
-
this.tooltipObserver.observe(container, {
|
|
3795
|
-
childList: true,
|
|
3796
|
-
subtree: true,
|
|
3797
|
-
});
|
|
3798
|
-
}
|
|
3799
|
-
});
|
|
3800
|
-
}
|
|
3801
|
-
},
|
|
3802
|
-
beforeUnmount: function () {
|
|
3803
|
-
if (this.tooltipObserver) {
|
|
3804
|
-
this.tooltipObserver.disconnect();
|
|
3805
|
-
this.tooltipObserver = null;
|
|
3806
|
-
}
|
|
3807
3696
|
},
|
|
3808
3697
|
}
|
|
3809
3698
|
</script>
|
|
@@ -3966,9 +3855,6 @@ export default {
|
|
|
3966
3855
|
|
|
3967
3856
|
:deep(.flatmap-tooltip-popup),
|
|
3968
3857
|
:deep(.custom-popup) {
|
|
3969
|
-
font-family: Asap, sans-serif !important;
|
|
3970
|
-
font-size: 14px !important;
|
|
3971
|
-
|
|
3972
3858
|
&.maplibregl-popup-anchor-bottom {
|
|
3973
3859
|
.maplibregl-popup-content {
|
|
3974
3860
|
margin-bottom: 12px;
|
|
@@ -4563,23 +4449,4 @@ export default {
|
|
|
4563
4449
|
}
|
|
4564
4450
|
}
|
|
4565
4451
|
|
|
4566
|
-
.flatmap-feature-label {
|
|
4567
|
-
padding: 6px !important;
|
|
4568
|
-
font-family: Asap, sans-serif !important;
|
|
4569
|
-
font-size: 14px !important;
|
|
4570
|
-
|
|
4571
|
-
// provided by tooltipContentProvider from mapintegratedvuer
|
|
4572
|
-
&.flatmap-connectivity-label {
|
|
4573
|
-
text-align: left !important;
|
|
4574
|
-
}
|
|
4575
|
-
}
|
|
4576
|
-
|
|
4577
|
-
.id-tag {
|
|
4578
|
-
color: #444;
|
|
4579
|
-
background: #e0e0e0;
|
|
4580
|
-
padding: 2px 4px;
|
|
4581
|
-
border-radius: 4px;
|
|
4582
|
-
font-size: .75rem !important;
|
|
4583
|
-
letter-spacing: 1.05px;
|
|
4584
|
-
}
|
|
4585
4452
|
</style>
|
|
@@ -94,7 +94,6 @@
|
|
|
94
94
|
:showOpenMapButton="showOpenMapButton"
|
|
95
95
|
:showPathwayFilter="showPathwayFilter"
|
|
96
96
|
:externalLegends="externalLegends"
|
|
97
|
-
:tooltipContentProvider="tooltipContentProvider"
|
|
98
97
|
/>
|
|
99
98
|
|
|
100
99
|
<!-- multiflatmap-error -->
|
|
@@ -894,14 +893,6 @@ export default {
|
|
|
894
893
|
return []
|
|
895
894
|
},
|
|
896
895
|
},
|
|
897
|
-
/**
|
|
898
|
-
* A function that provides custom tooltip HTML content for path features.
|
|
899
|
-
* Passed through to each FlatmapVuer instance.
|
|
900
|
-
*/
|
|
901
|
-
tooltipContentProvider: {
|
|
902
|
-
type: Function,
|
|
903
|
-
default: null,
|
|
904
|
-
},
|
|
905
896
|
},
|
|
906
897
|
data: function () {
|
|
907
898
|
return {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* a single source for the flatmap-viewer library import
|
|
3
3
|
*/
|
|
4
|
-
import * as flatmap from 'https://cdn.jsdelivr.net/npm/@
|
|
4
|
+
import * as flatmap from 'https://cdn.jsdelivr.net/npm/@abi-software/flatmap-viewer@4.4.3/+esm';
|
|
5
5
|
|
|
6
6
|
export default flatmap;
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
const SOMA_MARKER_COLOUR = '#1b7f6b'
|
|
2
|
-
const SOMA_MARKER_SECONDARY_COLOUR = '#f4f1de'
|
|
3
|
-
const SOMA_MARKER_TEXT_COLOUR = '#12312b'
|
|
4
|
-
const SOMA_MARKER_MAX_COUNT_LABEL = '99+'
|
|
5
|
-
|
|
6
|
-
const normalizeSomaLocations = function (somaLocations) {
|
|
7
|
-
return (Array.isArray(somaLocations) ? somaLocations : [])
|
|
8
|
-
.map((item) => ({
|
|
9
|
-
label: String(item?.label || '').trim(),
|
|
10
|
-
curie: String(item?.curie || '').trim(),
|
|
11
|
-
count: Number(item?.count || 0),
|
|
12
|
-
}))
|
|
13
|
-
.filter((item) => item.curie && item.count > 0)
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const formatCount = function (count) {
|
|
17
|
-
if (count > 99) return SOMA_MARKER_MAX_COUNT_LABEL
|
|
18
|
-
return String(count)
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const createSomaLocationMarkerElement = function (somaLocation) {
|
|
22
|
-
const wrapper = document.createElement('div')
|
|
23
|
-
wrapper.className = 'flatmapvuer-soma-location-marker'
|
|
24
|
-
wrapper.title = somaLocation.label || somaLocation.curie
|
|
25
|
-
wrapper.style.width = '34px'
|
|
26
|
-
wrapper.style.height = '48px'
|
|
27
|
-
wrapper.style.display = 'flex'
|
|
28
|
-
wrapper.style.alignItems = 'center'
|
|
29
|
-
wrapper.style.justifyContent = 'center'
|
|
30
|
-
wrapper.style.transform = 'translate(-50%, -100%)'
|
|
31
|
-
|
|
32
|
-
const countLabel = formatCount(somaLocation.count)
|
|
33
|
-
wrapper.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="-1 -1 27 42" width="34" height="48" aria-hidden="true">
|
|
34
|
-
<ellipse style="fill: rgb(0, 0, 0); fill-opacity: 0.18;" cx="12" cy="36" rx="8" ry="4"/>
|
|
35
|
-
<path d="M12.25.25a12.254 12.254 0 0 0-12 12.494
|
|
36
|
-
c0 6.444 6.488 12.109 11.059 22.564.549 1.256 1.333 1.256 1.882 0
|
|
37
|
-
C17.762 24.853 24.25 19.186 24.25 12.744A12.254 12.254 0 0 0 12.25.25Z"
|
|
38
|
-
style="fill:${SOMA_MARKER_COLOUR};stroke:${SOMA_MARKER_SECONDARY_COLOUR};stroke-width:1.1"/>
|
|
39
|
-
<circle cx="12.5" cy="12.5" r="8" fill="${SOMA_MARKER_SECONDARY_COLOUR}"/>
|
|
40
|
-
<text x="12.5" y="16.1" text-anchor="middle" style="font-size:7.5px;font-weight:700;fill:${SOMA_MARKER_TEXT_COLOUR};font-family:Arial, sans-serif">${countLabel}</text>
|
|
41
|
-
</svg>`
|
|
42
|
-
|
|
43
|
-
return wrapper
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const resolveMarkerPlacement = function (mapImp, curie) {
|
|
47
|
-
const featureIds = Array.isArray(mapImp?.modelFeatureIds?.(curie)) ? mapImp.modelFeatureIds(curie) : []
|
|
48
|
-
const placements = []
|
|
49
|
-
const seenFeatureUris = new Set()
|
|
50
|
-
|
|
51
|
-
for (const featureId of featureIds) {
|
|
52
|
-
const annotation = mapImp.annotation(featureId)
|
|
53
|
-
const featureUri = String(annotation?.uri || '').trim()
|
|
54
|
-
if (featureUri && !seenFeatureUris.has(featureUri)) {
|
|
55
|
-
seenFeatureUris.add(featureUri)
|
|
56
|
-
placements.push({
|
|
57
|
-
type: 'feature-uri',
|
|
58
|
-
value: featureUri,
|
|
59
|
-
})
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// Fall back to model placement only when no feature URI can be resolved.
|
|
64
|
-
if (!placements.length && featureIds.length) {
|
|
65
|
-
placements.push({
|
|
66
|
-
type: 'model',
|
|
67
|
-
value: curie,
|
|
68
|
-
})
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
return placements
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
export const attachSomaLocationMarkerMethods = function (mapImp) {
|
|
75
|
-
if (!mapImp || mapImp.addSomaLocationMarkers) {
|
|
76
|
-
return mapImp
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
let markerIds = []
|
|
80
|
-
|
|
81
|
-
mapImp.clearSomaLocationMarkers = function () {
|
|
82
|
-
markerIds.forEach((markerId) => {
|
|
83
|
-
mapImp.removeMarker(markerId)
|
|
84
|
-
})
|
|
85
|
-
markerIds = []
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
mapImp.addSomaLocationMarkers = function (somaLocations) {
|
|
89
|
-
const normalizedSomaLocations = normalizeSomaLocations(somaLocations)
|
|
90
|
-
const placedSomaLocations = []
|
|
91
|
-
|
|
92
|
-
mapImp.clearSomaLocationMarkers()
|
|
93
|
-
|
|
94
|
-
normalizedSomaLocations.forEach((somaLocation) => {
|
|
95
|
-
const placements = resolveMarkerPlacement(mapImp, somaLocation.curie)
|
|
96
|
-
if (!placements.length) return
|
|
97
|
-
|
|
98
|
-
let somaLocationPlaced = false
|
|
99
|
-
placements.forEach((placement) => {
|
|
100
|
-
const markerElement = createSomaLocationMarkerElement(somaLocation)
|
|
101
|
-
let addedMarkerIds = []
|
|
102
|
-
|
|
103
|
-
if (placement.type === 'feature-uri') {
|
|
104
|
-
addedMarkerIds = mapImp.addMarkerByFeatureUri(placement.value, { element: markerElement })
|
|
105
|
-
} else if (placement.type === 'model') {
|
|
106
|
-
const markerId = mapImp.addMarker(placement.value, { element: markerElement })
|
|
107
|
-
addedMarkerIds = markerId > -1 ? [markerId] : []
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
if (!addedMarkerIds.length) return
|
|
111
|
-
|
|
112
|
-
markerIds.push(...addedMarkerIds)
|
|
113
|
-
somaLocationPlaced = true
|
|
114
|
-
})
|
|
115
|
-
|
|
116
|
-
if (somaLocationPlaced) {
|
|
117
|
-
placedSomaLocations.push(somaLocation)
|
|
118
|
-
}
|
|
119
|
-
})
|
|
120
|
-
|
|
121
|
-
return placedSomaLocations
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
return mapImp
|
|
125
|
-
}
|