@smartnet360/svelte-components 0.0.124 → 0.0.126
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/apps/antenna-tools/components/AntennaSettingsModal.svelte +4 -174
- package/dist/apps/antenna-tools/components/DatabaseViewer.svelte +2 -2
- package/dist/apps/antenna-tools/components/MSIConverter.svelte +302 -43
- package/dist/apps/antenna-tools/db.js +4 -0
- package/dist/apps/antenna-tools/utils/db-utils.d.ts +19 -0
- package/dist/apps/antenna-tools/utils/db-utils.js +108 -0
- package/dist/core/Auth/LoginForm.svelte +397 -0
- package/dist/core/Auth/LoginForm.svelte.d.ts +16 -0
- package/dist/core/Auth/auth.svelte.d.ts +22 -0
- package/dist/core/Auth/auth.svelte.js +229 -0
- package/dist/core/Auth/config.d.ts +25 -0
- package/dist/core/Auth/config.js +256 -0
- package/dist/core/Auth/index.d.ts +4 -0
- package/dist/core/Auth/index.js +5 -0
- package/dist/core/Auth/types.d.ts +140 -0
- package/dist/core/Auth/types.js +2 -0
- package/dist/core/LandingPage/App.svelte +102 -0
- package/dist/core/LandingPage/App.svelte.d.ts +20 -0
- package/dist/core/LandingPage/LandingPage.svelte +480 -0
- package/dist/core/LandingPage/LandingPage.svelte.d.ts +21 -0
- package/dist/core/LandingPage/index.d.ts +2 -0
- package/dist/core/LandingPage/index.js +3 -0
- package/dist/core/index.d.ts +2 -0
- package/dist/core/index.js +4 -0
- package/dist/map-v3/demo/DemoMap.svelte +18 -0
- package/dist/map-v3/demo/demo-custom-cells.d.ts +21 -0
- package/dist/map-v3/demo/demo-custom-cells.js +48 -0
- package/dist/map-v3/features/cells/custom/components/CustomCellFilterControl.svelte +220 -0
- package/dist/map-v3/features/cells/custom/components/CustomCellFilterControl.svelte.d.ts +15 -0
- package/dist/map-v3/features/cells/custom/components/CustomCellSetManager.svelte +306 -0
- package/dist/map-v3/features/cells/custom/components/CustomCellSetManager.svelte.d.ts +10 -0
- package/dist/map-v3/features/cells/custom/components/index.d.ts +5 -0
- package/dist/map-v3/features/cells/custom/components/index.js +5 -0
- package/dist/map-v3/features/cells/custom/index.d.ts +32 -0
- package/dist/map-v3/features/cells/custom/index.js +35 -0
- package/dist/map-v3/features/cells/custom/layers/CustomCellsLayer.svelte +262 -0
- package/dist/map-v3/features/cells/custom/layers/CustomCellsLayer.svelte.d.ts +10 -0
- package/dist/map-v3/features/cells/custom/layers/index.d.ts +4 -0
- package/dist/map-v3/features/cells/custom/layers/index.js +4 -0
- package/dist/map-v3/features/cells/custom/logic/csv-parser.d.ts +20 -0
- package/dist/map-v3/features/cells/custom/logic/csv-parser.js +164 -0
- package/dist/map-v3/features/cells/custom/logic/index.d.ts +5 -0
- package/dist/map-v3/features/cells/custom/logic/index.js +5 -0
- package/dist/map-v3/features/cells/custom/logic/tree-adapter.d.ts +24 -0
- package/dist/map-v3/features/cells/custom/logic/tree-adapter.js +67 -0
- package/dist/map-v3/features/cells/custom/stores/custom-cell-sets.svelte.d.ts +78 -0
- package/dist/map-v3/features/cells/custom/stores/custom-cell-sets.svelte.js +242 -0
- package/dist/map-v3/features/cells/custom/stores/index.d.ts +4 -0
- package/dist/map-v3/features/cells/custom/stores/index.js +4 -0
- package/dist/map-v3/features/cells/custom/types.d.ts +83 -0
- package/dist/map-v3/features/cells/custom/types.js +23 -0
- package/dist/map-v3/shared/controls/MapControl.svelte +27 -3
- package/package.json +1 -1
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom Cell Sets Store
|
|
3
|
+
*
|
|
4
|
+
* Manages multiple custom cell sets, each loaded from a CSV file.
|
|
5
|
+
* Resolves cell data from the parent CellDataStore.
|
|
6
|
+
*/
|
|
7
|
+
import { browser } from '$app/environment';
|
|
8
|
+
import { CUSTOM_CELL_PALETTE } from '../types';
|
|
9
|
+
import { parseCustomCellsCsv, buildCellLookup } from '../logic/csv-parser';
|
|
10
|
+
/**
|
|
11
|
+
* Generate a unique ID for a new set
|
|
12
|
+
*/
|
|
13
|
+
function generateSetId() {
|
|
14
|
+
return `set-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Store for managing custom cell sets
|
|
18
|
+
*/
|
|
19
|
+
export class CustomCellSetsStore {
|
|
20
|
+
/** All custom cell sets */
|
|
21
|
+
sets = $state([]);
|
|
22
|
+
/** Version counter for reactivity */
|
|
23
|
+
version = $state(0);
|
|
24
|
+
/** Reference to parent cell data store */
|
|
25
|
+
cellDataStore;
|
|
26
|
+
/** Storage key for persistence */
|
|
27
|
+
storageKey;
|
|
28
|
+
constructor(cellDataStore, namespace = 'default') {
|
|
29
|
+
this.cellDataStore = cellDataStore;
|
|
30
|
+
this.storageKey = `${namespace}:custom-cell-sets`;
|
|
31
|
+
if (browser) {
|
|
32
|
+
this.load();
|
|
33
|
+
// Auto-save on changes
|
|
34
|
+
$effect(() => {
|
|
35
|
+
// Read version to trigger on changes
|
|
36
|
+
const _v = this.version;
|
|
37
|
+
this.save();
|
|
38
|
+
});
|
|
39
|
+
// Re-resolve cells when main cell data changes
|
|
40
|
+
$effect(() => {
|
|
41
|
+
const cellCount = this.cellDataStore.rawCells.length;
|
|
42
|
+
if (cellCount > 0 && this.sets.length > 0) {
|
|
43
|
+
// Check if any cells need resolution
|
|
44
|
+
const needsResolution = this.sets.some(set => set.cells.some(c => !c.resolvedCell));
|
|
45
|
+
if (needsResolution) {
|
|
46
|
+
console.log('[CustomCellSetsStore] Re-resolving cells after main data loaded');
|
|
47
|
+
this.refreshResolutions();
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Import a CSV file and create a new custom cell set
|
|
55
|
+
*/
|
|
56
|
+
importFromCsv(csvContent, fileName) {
|
|
57
|
+
// Build lookup from all cells (unfiltered)
|
|
58
|
+
const cellLookup = buildCellLookup(this.cellDataStore.rawCells);
|
|
59
|
+
// Parse CSV
|
|
60
|
+
const result = parseCustomCellsCsv(csvContent, cellLookup);
|
|
61
|
+
return result;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Create a new set from import result
|
|
65
|
+
*/
|
|
66
|
+
createSet(name, importResult) {
|
|
67
|
+
const id = generateSetId();
|
|
68
|
+
// Assign default colors to groups
|
|
69
|
+
const groupColors = {};
|
|
70
|
+
importResult.groups.forEach((group, idx) => {
|
|
71
|
+
groupColors[group] = CUSTOM_CELL_PALETTE[idx % CUSTOM_CELL_PALETTE.length];
|
|
72
|
+
});
|
|
73
|
+
const newSet = {
|
|
74
|
+
id,
|
|
75
|
+
name,
|
|
76
|
+
cells: importResult.cells,
|
|
77
|
+
unmatchedTxIds: importResult.unmatchedTxIds,
|
|
78
|
+
groups: importResult.groups,
|
|
79
|
+
extraColumns: importResult.extraColumns,
|
|
80
|
+
baseSize: 50,
|
|
81
|
+
opacity: 0.7,
|
|
82
|
+
defaultColor: CUSTOM_CELL_PALETTE[0],
|
|
83
|
+
groupColors,
|
|
84
|
+
visible: true,
|
|
85
|
+
visibleGroups: new Set(importResult.groups)
|
|
86
|
+
};
|
|
87
|
+
this.sets.push(newSet);
|
|
88
|
+
this.version++;
|
|
89
|
+
return newSet;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Remove a set by ID
|
|
93
|
+
*/
|
|
94
|
+
removeSet(setId) {
|
|
95
|
+
const index = this.sets.findIndex(s => s.id === setId);
|
|
96
|
+
if (index !== -1) {
|
|
97
|
+
// Use filter to create a new array for proper reactivity
|
|
98
|
+
this.sets = this.sets.filter(s => s.id !== setId);
|
|
99
|
+
this.version++;
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Get a set by ID
|
|
106
|
+
*/
|
|
107
|
+
getSet(setId) {
|
|
108
|
+
return this.sets.find(s => s.id === setId);
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Toggle set visibility
|
|
112
|
+
*/
|
|
113
|
+
toggleSetVisibility(setId) {
|
|
114
|
+
const set = this.getSet(setId);
|
|
115
|
+
if (set) {
|
|
116
|
+
set.visible = !set.visible;
|
|
117
|
+
this.version++;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Toggle group visibility within a set
|
|
122
|
+
*/
|
|
123
|
+
toggleGroupVisibility(setId, group) {
|
|
124
|
+
const set = this.getSet(setId);
|
|
125
|
+
if (set) {
|
|
126
|
+
if (set.visibleGroups.has(group)) {
|
|
127
|
+
set.visibleGroups.delete(group);
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
set.visibleGroups.add(group);
|
|
131
|
+
}
|
|
132
|
+
this.version++;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Set group color
|
|
137
|
+
*/
|
|
138
|
+
setGroupColor(setId, group, color) {
|
|
139
|
+
const set = this.getSet(setId);
|
|
140
|
+
if (set) {
|
|
141
|
+
set.groupColors[group] = color;
|
|
142
|
+
this.version++;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Update set display settings
|
|
147
|
+
*/
|
|
148
|
+
updateSetSettings(setId, settings) {
|
|
149
|
+
const set = this.getSet(setId);
|
|
150
|
+
if (set) {
|
|
151
|
+
if (settings.baseSize !== undefined)
|
|
152
|
+
set.baseSize = settings.baseSize;
|
|
153
|
+
if (settings.opacity !== undefined)
|
|
154
|
+
set.opacity = settings.opacity;
|
|
155
|
+
if (settings.defaultColor !== undefined)
|
|
156
|
+
set.defaultColor = settings.defaultColor;
|
|
157
|
+
this.version++;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Rename a set
|
|
162
|
+
*/
|
|
163
|
+
renameSet(setId, newName) {
|
|
164
|
+
const set = this.getSet(setId);
|
|
165
|
+
if (set) {
|
|
166
|
+
set.name = newName;
|
|
167
|
+
this.version++;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Get visible cells for a set (filtered by visible groups)
|
|
172
|
+
*/
|
|
173
|
+
getVisibleCells(setId) {
|
|
174
|
+
const set = this.getSet(setId);
|
|
175
|
+
if (!set || !set.visible)
|
|
176
|
+
return [];
|
|
177
|
+
return set.cells.filter(c => c.resolvedCell && set.visibleGroups.has(c.customGroup));
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Re-resolve cells after main cell data changes
|
|
181
|
+
*/
|
|
182
|
+
refreshResolutions() {
|
|
183
|
+
const cellLookup = buildCellLookup(this.cellDataStore.rawCells);
|
|
184
|
+
for (const set of this.sets) {
|
|
185
|
+
for (const cell of set.cells) {
|
|
186
|
+
cell.resolvedCell = cellLookup.get(cell.txId);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
this.version++;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Load from localStorage
|
|
193
|
+
*/
|
|
194
|
+
load() {
|
|
195
|
+
try {
|
|
196
|
+
const stored = localStorage.getItem(this.storageKey);
|
|
197
|
+
if (stored) {
|
|
198
|
+
const data = JSON.parse(stored);
|
|
199
|
+
// Reconstruct sets with proper Set objects
|
|
200
|
+
this.sets = data.map((setData) => ({
|
|
201
|
+
...setData,
|
|
202
|
+
visibleGroups: new Set(setData.visibleGroups || []),
|
|
203
|
+
cells: setData.cells || []
|
|
204
|
+
}));
|
|
205
|
+
// Re-resolve cells
|
|
206
|
+
this.refreshResolutions();
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
catch (e) {
|
|
210
|
+
console.warn('[CustomCellSetsStore] Failed to load from storage', e);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Save to localStorage
|
|
215
|
+
*/
|
|
216
|
+
save() {
|
|
217
|
+
try {
|
|
218
|
+
// Convert Sets to arrays for JSON serialization
|
|
219
|
+
const data = this.sets.map(set => ({
|
|
220
|
+
...set,
|
|
221
|
+
visibleGroups: Array.from(set.visibleGroups),
|
|
222
|
+
// Don't persist resolved cells - will re-resolve on load
|
|
223
|
+
cells: set.cells.map(c => ({
|
|
224
|
+
txId: c.txId,
|
|
225
|
+
customGroup: c.customGroup,
|
|
226
|
+
sizeFactor: c.sizeFactor,
|
|
227
|
+
extraFields: c.extraFields
|
|
228
|
+
}))
|
|
229
|
+
}));
|
|
230
|
+
localStorage.setItem(this.storageKey, JSON.stringify(data));
|
|
231
|
+
}
|
|
232
|
+
catch (e) {
|
|
233
|
+
console.warn('[CustomCellSetsStore] Failed to save to storage', e);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Factory function to create a custom cell sets store
|
|
239
|
+
*/
|
|
240
|
+
export function createCustomCellSetsStore(cellDataStore, namespace = 'default') {
|
|
241
|
+
return new CustomCellSetsStore(cellDataStore, namespace);
|
|
242
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom Cells Feature - Type Definitions
|
|
3
|
+
*
|
|
4
|
+
* Types for ad-hoc cell layers loaded from CSV files.
|
|
5
|
+
* Custom cells reference existing cells by txId and add custom grouping/sizing.
|
|
6
|
+
*/
|
|
7
|
+
import type { Cell } from '../../../../shared/demo';
|
|
8
|
+
/**
|
|
9
|
+
* A custom cell entry from CSV import
|
|
10
|
+
*/
|
|
11
|
+
export interface CustomCell {
|
|
12
|
+
/** Required: Reference to cell in main data store */
|
|
13
|
+
txId: string;
|
|
14
|
+
/** Grouping field for TreeView (defaults to 'default' if not in CSV) */
|
|
15
|
+
customGroup: string;
|
|
16
|
+
/** Size multiplier for arc radius (defaults to 1) */
|
|
17
|
+
sizeFactor: number;
|
|
18
|
+
/** Any additional columns from CSV for tooltips */
|
|
19
|
+
extraFields: Record<string, string | number>;
|
|
20
|
+
/** Resolved cell data from main store (populated after import) */
|
|
21
|
+
resolvedCell?: Cell;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Import result from CSV parsing
|
|
25
|
+
*/
|
|
26
|
+
export interface CustomCellImportResult {
|
|
27
|
+
/** Successfully parsed and matched cells */
|
|
28
|
+
cells: CustomCell[];
|
|
29
|
+
/** Cell IDs that weren't found in main data store */
|
|
30
|
+
unmatchedTxIds: string[];
|
|
31
|
+
/** Discovered custom groups */
|
|
32
|
+
groups: string[];
|
|
33
|
+
/** Extra column names found in CSV */
|
|
34
|
+
extraColumns: string[];
|
|
35
|
+
/** Total rows in CSV */
|
|
36
|
+
totalRows: number;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* A custom cell set - represents one uploaded CSV
|
|
40
|
+
*/
|
|
41
|
+
export interface CustomCellSet {
|
|
42
|
+
/** Unique identifier for this set */
|
|
43
|
+
id: string;
|
|
44
|
+
/** Display name (from filename or user input) */
|
|
45
|
+
name: string;
|
|
46
|
+
/** Cells in this set with resolved data */
|
|
47
|
+
cells: CustomCell[];
|
|
48
|
+
/** Cell IDs that weren't found during import */
|
|
49
|
+
unmatchedTxIds: string[];
|
|
50
|
+
/** All custom groups in this set */
|
|
51
|
+
groups: string[];
|
|
52
|
+
/** Extra column names for tooltip display */
|
|
53
|
+
extraColumns: string[];
|
|
54
|
+
/** Base arc radius in pixels (multiplied by sizeFactor per cell) */
|
|
55
|
+
baseSize: number;
|
|
56
|
+
/** Layer opacity (0-1) */
|
|
57
|
+
opacity: number;
|
|
58
|
+
/** Default color for groups without override */
|
|
59
|
+
defaultColor: string;
|
|
60
|
+
/** Per-group color overrides */
|
|
61
|
+
groupColors: Record<string, string>;
|
|
62
|
+
/** Whether this set's layer is visible */
|
|
63
|
+
visible: boolean;
|
|
64
|
+
/** Which groups are currently visible */
|
|
65
|
+
visibleGroups: Set<string>;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Configuration for creating a new custom cell set
|
|
69
|
+
*/
|
|
70
|
+
export interface CustomCellSetConfig {
|
|
71
|
+
name: string;
|
|
72
|
+
cells: CustomCell[];
|
|
73
|
+
unmatchedTxIds?: string[];
|
|
74
|
+
groups?: string[];
|
|
75
|
+
extraColumns?: string[];
|
|
76
|
+
baseSize?: number;
|
|
77
|
+
opacity?: number;
|
|
78
|
+
defaultColor?: string;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Default color palette for custom cell groups
|
|
82
|
+
*/
|
|
83
|
+
export declare const CUSTOM_CELL_PALETTE: string[];
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom Cells Feature - Type Definitions
|
|
3
|
+
*
|
|
4
|
+
* Types for ad-hoc cell layers loaded from CSV files.
|
|
5
|
+
* Custom cells reference existing cells by txId and add custom grouping/sizing.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Default color palette for custom cell groups
|
|
9
|
+
*/
|
|
10
|
+
export const CUSTOM_CELL_PALETTE = [
|
|
11
|
+
'#e41a1c', // Red
|
|
12
|
+
'#377eb8', // Blue
|
|
13
|
+
'#4daf4a', // Green
|
|
14
|
+
'#984ea3', // Purple
|
|
15
|
+
'#ff7f00', // Orange
|
|
16
|
+
'#ffff33', // Yellow
|
|
17
|
+
'#a65628', // Brown
|
|
18
|
+
'#f781bf', // Pink
|
|
19
|
+
'#999999', // Gray
|
|
20
|
+
'#66c2a5', // Teal
|
|
21
|
+
'#fc8d62', // Coral
|
|
22
|
+
'#8da0cb', // Periwinkle
|
|
23
|
+
];
|
|
@@ -60,6 +60,7 @@
|
|
|
60
60
|
let controlElement: HTMLDivElement;
|
|
61
61
|
let collapsed = $state(initiallyCollapsed);
|
|
62
62
|
let control: IControl | null = null;
|
|
63
|
+
let isAdded = false;
|
|
63
64
|
|
|
64
65
|
// Reactively add/remove control when map becomes available/unavailable
|
|
65
66
|
$effect(() => {
|
|
@@ -67,13 +68,29 @@
|
|
|
67
68
|
if (map && controlElement) {
|
|
68
69
|
addControl(map);
|
|
69
70
|
return () => {
|
|
71
|
+
console.log(`[MapControl] Effect cleanup called for: ${title}`);
|
|
70
72
|
removeControl(map);
|
|
71
73
|
};
|
|
72
74
|
}
|
|
73
75
|
});
|
|
74
76
|
|
|
77
|
+
// Ensure control is removed when component is destroyed
|
|
78
|
+
onDestroy(() => {
|
|
79
|
+
console.log(`[MapControl] onDestroy called for: ${title}`);
|
|
80
|
+
const map = mapStore?.map;
|
|
81
|
+
if (map) {
|
|
82
|
+
removeControl(map);
|
|
83
|
+
}
|
|
84
|
+
// Also explicitly remove from DOM as fallback
|
|
85
|
+
// (Mapbox moves the element to its own container)
|
|
86
|
+
if (controlElement?.parentNode) {
|
|
87
|
+
controlElement.parentNode.removeChild(controlElement);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
|
|
75
91
|
function addControl(map: MapboxMap) {
|
|
76
|
-
if (control) return;
|
|
92
|
+
if (control || isAdded) return;
|
|
93
|
+
isAdded = true;
|
|
77
94
|
|
|
78
95
|
// Create a custom Mapbox control
|
|
79
96
|
control = {
|
|
@@ -81,7 +98,7 @@
|
|
|
81
98
|
return controlElement;
|
|
82
99
|
},
|
|
83
100
|
onRemove: () => {
|
|
84
|
-
//
|
|
101
|
+
// Mapbox will remove the element from its container
|
|
85
102
|
}
|
|
86
103
|
};
|
|
87
104
|
|
|
@@ -90,12 +107,19 @@
|
|
|
90
107
|
|
|
91
108
|
function removeControl(map: MapboxMap) {
|
|
92
109
|
if (control) {
|
|
110
|
+
console.log(`[MapControl] Removing control: ${title}`);
|
|
93
111
|
try {
|
|
94
112
|
map.removeControl(control);
|
|
95
113
|
} catch (e) {
|
|
96
|
-
|
|
114
|
+
console.log(`[MapControl] Error removing control (may already be removed): ${title}`, e);
|
|
97
115
|
}
|
|
98
116
|
control = null;
|
|
117
|
+
isAdded = false;
|
|
118
|
+
}
|
|
119
|
+
// Fallback: ensure element is removed from DOM
|
|
120
|
+
if (controlElement?.parentNode) {
|
|
121
|
+
console.log(`[MapControl] Fallback DOM removal for: ${title}`);
|
|
122
|
+
controlElement.parentNode.removeChild(controlElement);
|
|
99
123
|
}
|
|
100
124
|
}
|
|
101
125
|
|