@smartnet360/svelte-components 0.0.102 → 0.0.103

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.
Files changed (65) hide show
  1. package/dist/apps/antenna-pattern/index.d.ts +1 -0
  2. package/dist/apps/antenna-pattern/index.js +1 -0
  3. package/dist/apps/antenna-pattern/utils/load-static-antennas.d.ts +17 -0
  4. package/dist/apps/antenna-pattern/utils/load-static-antennas.js +83 -0
  5. package/dist/apps/site-check/SiteCheck.svelte +4 -6
  6. package/dist/core/Charts/ChartCard.svelte +122 -12
  7. package/dist/core/Charts/ChartCard.svelte.d.ts +2 -0
  8. package/dist/core/Charts/ChartComponent.svelte +8 -6
  9. package/dist/core/CoverageMap/ai/AITools.d.ts +117 -0
  10. package/dist/core/CoverageMap/ai/AITools.js +380 -0
  11. package/dist/core/CoverageMap/core/CoverageCalculator.d.ts +138 -0
  12. package/dist/core/CoverageMap/core/CoverageCalculator.js +375 -0
  13. package/dist/core/CoverageMap/core/GridCalculator.d.ts +115 -0
  14. package/dist/core/CoverageMap/core/GridCalculator.js +484 -0
  15. package/dist/core/CoverageMap/core/PathLossModels.d.ts +253 -0
  16. package/dist/core/CoverageMap/core/PathLossModels.js +380 -0
  17. package/dist/core/CoverageMap/core/SignalProcessor.d.ts +288 -0
  18. package/dist/core/CoverageMap/core/SignalProcessor.js +424 -0
  19. package/dist/core/CoverageMap/data/AntennaStore.d.ts +165 -0
  20. package/dist/core/CoverageMap/data/AntennaStore.js +327 -0
  21. package/dist/core/CoverageMap/data/SiteStore.d.ts +155 -0
  22. package/dist/core/CoverageMap/data/SiteStore.js +355 -0
  23. package/dist/core/CoverageMap/index.d.ts +74 -0
  24. package/dist/core/CoverageMap/index.js +103 -0
  25. package/dist/core/CoverageMap/types.d.ts +252 -0
  26. package/dist/core/CoverageMap/types.js +7 -0
  27. package/dist/core/CoverageMap/utils/geoUtils.d.ts +223 -0
  28. package/dist/core/CoverageMap/utils/geoUtils.js +374 -0
  29. package/dist/core/CoverageMap/utils/rfUtils.d.ts +329 -0
  30. package/dist/core/CoverageMap/utils/rfUtils.js +434 -0
  31. package/dist/core/CoverageMap/visualization/ColorSchemes.d.ts +149 -0
  32. package/dist/core/CoverageMap/visualization/ColorSchemes.js +377 -0
  33. package/dist/core/TreeView/index.d.ts +4 -4
  34. package/dist/core/TreeView/index.js +5 -5
  35. package/dist/core/TreeView/tree-utils.d.ts +12 -0
  36. package/dist/core/TreeView/tree-utils.js +115 -6
  37. package/dist/core/TreeView/tree.store.svelte.d.ts +94 -0
  38. package/dist/core/TreeView/tree.store.svelte.js +274 -0
  39. package/dist/map-v2/features/cells/controls/CellFilterControl.svelte +16 -27
  40. package/dist/map-v2/features/repeaters/controls/RepeaterFilterControl.svelte +33 -42
  41. package/dist/map-v2/features/sites/controls/SiteFilterControl.svelte +12 -19
  42. package/dist/map-v3/core/components/Map.svelte +4 -0
  43. package/dist/map-v3/core/stores/map.store.svelte.js +2 -0
  44. package/dist/map-v3/features/cells/components/CellFilterControl.svelte +24 -30
  45. package/dist/map-v3/features/coverage/index.d.ts +12 -0
  46. package/dist/map-v3/features/coverage/index.js +16 -0
  47. package/dist/map-v3/features/coverage/layers/CoverageLayer.svelte +198 -0
  48. package/dist/map-v3/features/coverage/layers/CoverageLayer.svelte.d.ts +10 -0
  49. package/dist/map-v3/features/coverage/logic/coloring.d.ts +28 -0
  50. package/dist/map-v3/features/coverage/logic/coloring.js +77 -0
  51. package/dist/map-v3/features/coverage/logic/geometry.d.ts +33 -0
  52. package/dist/map-v3/features/coverage/logic/geometry.js +112 -0
  53. package/dist/map-v3/features/coverage/stores/coverage.data.svelte.d.ts +46 -0
  54. package/dist/map-v3/features/coverage/stores/coverage.data.svelte.js +95 -0
  55. package/dist/map-v3/features/coverage/stores/coverage.display.svelte.d.ts +33 -0
  56. package/dist/map-v3/features/coverage/stores/coverage.display.svelte.js +90 -0
  57. package/dist/map-v3/features/coverage/types.d.ts +52 -0
  58. package/dist/map-v3/features/coverage/types.js +7 -0
  59. package/dist/map-v3/features/repeaters/components/RepeaterFilterControl.svelte +14 -20
  60. package/dist/map-v3/features/sites/components/SiteFilterControl.svelte +23 -33
  61. package/dist/map-v3/index.d.ts +4 -0
  62. package/dist/map-v3/index.js +5 -0
  63. package/package.json +2 -2
  64. package/dist/core/TreeView/tree.store.d.ts +0 -10
  65. package/dist/core/TreeView/tree.store.js +0 -320
@@ -0,0 +1,327 @@
1
+ /**
2
+ * Antenna Store
3
+ *
4
+ * This module manages antenna pattern data for the coverage calculator.
5
+ * It integrates with the existing antenna pattern database and provides
6
+ * a clean API for:
7
+ * - Loading antenna data
8
+ * - Caching frequently used antennas
9
+ * - Converting database format to calculation format
10
+ * - Managing antenna library
11
+ *
12
+ * Integration with existing system:
13
+ * - Reuses antenna-pattern database (Dexie)
14
+ * - Compatible with MSI file format
15
+ * - Shares antenna data across components
16
+ */
17
+ import { db as antennaDB } from '../../../apps/antenna-pattern/db';
18
+ import { dBdTodBi } from '../utils/rfUtils';
19
+ // ============================================================================
20
+ // ANTENNA STORE CLASS
21
+ // ============================================================================
22
+ /**
23
+ * Antenna Store - Manages antenna pattern data
24
+ *
25
+ * Provides caching and convenience methods for accessing
26
+ * antenna data needed for coverage calculations.
27
+ *
28
+ * Features:
29
+ * - Automatic database connection
30
+ * - In-memory caching (reduces DB queries)
31
+ * - Format conversion (DB → AntennaPattern type)
32
+ * - Search and filtering
33
+ */
34
+ export class AntennaStore {
35
+ cache = new Map();
36
+ initialized = false;
37
+ /**
38
+ * Initialize the antenna store
39
+ *
40
+ * Checks database connection and loads frequently used antennas.
41
+ * Call this once before using other methods.
42
+ *
43
+ * @returns Promise resolving to true if initialized successfully
44
+ */
45
+ async initialize() {
46
+ try {
47
+ // Check if database has data
48
+ const hasData = await antennaDB.hasData();
49
+ if (!hasData) {
50
+ console.warn('Antenna database is empty. Load antenna files first.');
51
+ return false;
52
+ }
53
+ this.initialized = true;
54
+ return true;
55
+ }
56
+ catch (error) {
57
+ console.error('Failed to initialize antenna store:', error);
58
+ return false;
59
+ }
60
+ }
61
+ /**
62
+ * Get antenna by name
63
+ *
64
+ * Retrieves antenna pattern from database (or cache if available).
65
+ * Returns null if antenna not found.
66
+ *
67
+ * @param name - Antenna name (e.g., "ADU4515R17v06")
68
+ * @param tilt - Electrical tilt (e.g., "3", "6", "9")
69
+ * @returns Antenna pattern or null
70
+ *
71
+ * @example
72
+ * const antenna = await store.getAntenna("ADU4515R17v06", "3");
73
+ * if (antenna) {
74
+ * console.log(`Gain: ${antenna.gain_dBd} dBd`);
75
+ * }
76
+ */
77
+ async getAntenna(name, tilt) {
78
+ // Check cache first
79
+ const cacheKey = `${name}_${tilt}`;
80
+ if (this.cache.has(cacheKey)) {
81
+ return this.cache.get(cacheKey);
82
+ }
83
+ try {
84
+ // Query database
85
+ const dbAntenna = await antennaDB.antennas
86
+ .where({ name, tilt })
87
+ .first();
88
+ if (!dbAntenna) {
89
+ console.warn(`Antenna not found: ${name} with tilt ${tilt}`);
90
+ return null;
91
+ }
92
+ // Convert to AntennaPattern format
93
+ const antennaPattern = this.convertToAntennaPattern(dbAntenna);
94
+ // Cache for future use
95
+ this.cache.set(cacheKey, antennaPattern);
96
+ return antennaPattern;
97
+ }
98
+ catch (error) {
99
+ console.error(`Error loading antenna ${name}:`, error);
100
+ return null;
101
+ }
102
+ }
103
+ /**
104
+ * Get antenna by ID
105
+ *
106
+ * @param id - Database ID
107
+ * @returns Antenna pattern or null
108
+ */
109
+ async getAntennaById(id) {
110
+ try {
111
+ const dbAntenna = await antennaDB.antennas.get(id);
112
+ if (!dbAntenna) {
113
+ return null;
114
+ }
115
+ return this.convertToAntennaPattern(dbAntenna);
116
+ }
117
+ catch (error) {
118
+ console.error(`Error loading antenna by ID ${id}:`, error);
119
+ return null;
120
+ }
121
+ }
122
+ /**
123
+ * List all available antennas
124
+ *
125
+ * Returns a list of antenna models (without tilt variants).
126
+ * Useful for populating dropdown menus.
127
+ *
128
+ * @returns Array of unique antenna names
129
+ */
130
+ async listAntennaModels() {
131
+ try {
132
+ const allAntennas = await antennaDB.antennas.toArray();
133
+ // Get unique names
134
+ const uniqueNames = new Set(allAntennas.map((a) => a.name));
135
+ return Array.from(uniqueNames).sort();
136
+ }
137
+ catch (error) {
138
+ console.error('Error listing antennas:', error);
139
+ return [];
140
+ }
141
+ }
142
+ /**
143
+ * Get available tilts for an antenna model
144
+ *
145
+ * @param name - Antenna model name
146
+ * @returns Array of available tilts (e.g., ["0", "3", "6", "9"])
147
+ */
148
+ async getAvailableTilts(name) {
149
+ try {
150
+ const antennas = await antennaDB.antennas
151
+ .where({ name })
152
+ .toArray();
153
+ const tilts = antennas
154
+ .map((a) => a.tilt)
155
+ .filter((t) => t) // Remove null/undefined
156
+ .sort((a, b) => parseFloat(a) - parseFloat(b));
157
+ return Array.from(new Set(tilts)); // Remove duplicates
158
+ }
159
+ catch (error) {
160
+ console.error(`Error getting tilts for ${name}:`, error);
161
+ return [];
162
+ }
163
+ }
164
+ /**
165
+ * Search antennas by criteria
166
+ *
167
+ * @param criteria - Search criteria
168
+ * @returns Array of matching antennas
169
+ *
170
+ * @example
171
+ * const antennas = await store.searchAntennas({
172
+ * frequencyMin: 1700,
173
+ * frequencyMax: 1900,
174
+ * gainMin: 15
175
+ * });
176
+ */
177
+ async searchAntennas(criteria) {
178
+ try {
179
+ let query = antennaDB.antennas.toCollection();
180
+ // Apply filters
181
+ const antennas = await query.toArray();
182
+ return antennas
183
+ .filter((a) => {
184
+ if (criteria.namePattern && !a.name.includes(criteria.namePattern)) {
185
+ return false;
186
+ }
187
+ if (criteria.frequencyMin && a.frequency < criteria.frequencyMin) {
188
+ return false;
189
+ }
190
+ if (criteria.frequencyMax && a.frequency > criteria.frequencyMax) {
191
+ return false;
192
+ }
193
+ if (criteria.gainMin && a.gain_dBd < criteria.gainMin) {
194
+ return false;
195
+ }
196
+ if (criteria.gainMax && a.gain_dBd > criteria.gainMax) {
197
+ return false;
198
+ }
199
+ return true;
200
+ })
201
+ .map((a) => this.convertToAntennaPattern(a));
202
+ }
203
+ catch (error) {
204
+ console.error('Error searching antennas:', error);
205
+ return [];
206
+ }
207
+ }
208
+ /**
209
+ * Clear cache
210
+ *
211
+ * Useful if antenna data is updated in database.
212
+ */
213
+ clearCache() {
214
+ this.cache.clear();
215
+ }
216
+ /**
217
+ * Get cache statistics
218
+ *
219
+ * @returns Cache info
220
+ */
221
+ getCacheStats() {
222
+ return {
223
+ size: this.cache.size,
224
+ entries: Array.from(this.cache.keys())
225
+ };
226
+ }
227
+ // ========================================================================
228
+ // PRIVATE HELPER METHODS
229
+ // ========================================================================
230
+ /**
231
+ * Convert database antenna format to AntennaPattern type
232
+ *
233
+ * The database stores antennas in one format (from MSI files),
234
+ * but the coverage calculator needs a specific format.
235
+ * This function does the conversion.
236
+ *
237
+ * @param dbAntenna - Antenna from database
238
+ * @returns AntennaPattern for coverage calculator
239
+ */
240
+ convertToAntennaPattern(dbAntenna) {
241
+ // Extract available tilts from the database
242
+ // For now, we'll use the current tilt as the only available tilt
243
+ // In a full implementation, you'd query all tilts for this model
244
+ const availableTilts = dbAntenna.tilt ? [dbAntenna.tilt] : ['0'];
245
+ // Ensure patterns have 360 values
246
+ const pattern = this.ensurePattern(dbAntenna.pattern);
247
+ const vertical_pattern = this.ensurePattern(dbAntenna.vertical_pattern);
248
+ return {
249
+ name: dbAntenna.name,
250
+ model: dbAntenna.name,
251
+ frequency: dbAntenna.frequency,
252
+ gain_dBd: dbAntenna.gain_dBd,
253
+ gain_dBi: dBdTodBi(dbAntenna.gain_dBd),
254
+ pattern,
255
+ vertical_pattern,
256
+ availableTilts,
257
+ // Optional fields
258
+ beamwidth_horizontal: undefined, // Could calculate from pattern
259
+ beamwidth_vertical: undefined // Could calculate from pattern
260
+ };
261
+ }
262
+ /**
263
+ * Ensure pattern has exactly 360 values
264
+ *
265
+ * Some antenna files might have incomplete data.
266
+ * This function ensures we always have 360 values.
267
+ *
268
+ * @param pattern - Raw pattern data
269
+ * @returns Pattern with 360 values
270
+ */
271
+ ensurePattern(pattern) {
272
+ if (!pattern || pattern.length === 0) {
273
+ // Return zero attenuation pattern (omnidirectional)
274
+ return new Array(360).fill(0);
275
+ }
276
+ if (pattern.length === 360) {
277
+ return pattern;
278
+ }
279
+ if (pattern.length < 360) {
280
+ // Pad with last value
281
+ const padded = [...pattern];
282
+ while (padded.length < 360) {
283
+ padded.push(pattern[pattern.length - 1] || 0);
284
+ }
285
+ return padded;
286
+ }
287
+ // Truncate if too long
288
+ return pattern.slice(0, 360);
289
+ }
290
+ }
291
+ // ============================================================================
292
+ // SINGLETON INSTANCE
293
+ // ============================================================================
294
+ /**
295
+ * Global antenna store instance
296
+ *
297
+ * Use this instead of creating new instances.
298
+ * Ensures cache is shared across the application.
299
+ *
300
+ * @example
301
+ * import { antennaStore } from './AntennaStore';
302
+ *
303
+ * await antennaStore.initialize();
304
+ * const antenna = await antennaStore.getAntenna("ADU4515R17v06", "3");
305
+ */
306
+ export const antennaStore = new AntennaStore();
307
+ // ============================================================================
308
+ // UTILITY FUNCTIONS
309
+ // ============================================================================
310
+ /**
311
+ * Load antenna for a sector configuration
312
+ *
313
+ * Convenience function that loads the correct antenna
314
+ * based on sector configuration.
315
+ *
316
+ * @param sectorConfig - Sector configuration (must include antenna name and tilt)
317
+ * @returns AntennaPattern or null
318
+ */
319
+ export async function loadAntennaForSector(sectorConfig) {
320
+ const antennaName = sectorConfig.antenna || sectorConfig.antennaModel;
321
+ if (!antennaName) {
322
+ console.error('No antenna specified in sector configuration');
323
+ return null;
324
+ }
325
+ const tilt = String(sectorConfig.electricalTilt);
326
+ return antennaStore.getAntenna(antennaName, tilt);
327
+ }
@@ -0,0 +1,155 @@
1
+ /**
2
+ * Site Store
3
+ *
4
+ * This module manages site and cell/sector data for the coverage calculator.
5
+ * It provides integration with existing map cell data and converts it
6
+ * to the format needed for coverage calculations.
7
+ *
8
+ * Integration points:
9
+ * - map-v2 and map-v3 cell data
10
+ * - Antenna store (for loading antenna patterns)
11
+ * - Coverage calculator (for creating configurations)
12
+ */
13
+ import type { SiteConfiguration } from '../types';
14
+ import type { Cell } from '../../../map-v3/features/cells/types';
15
+ /**
16
+ * Site Store - Manages site and sector data
17
+ *
18
+ * Converts cell data from map components into site configurations
19
+ * suitable for coverage calculations.
20
+ */
21
+ export declare class SiteStore {
22
+ /**
23
+ * Create site configuration from cell data
24
+ *
25
+ * Takes an array of cells (sectors) that belong to the same site
26
+ * and creates a complete site configuration for coverage calculation.
27
+ *
28
+ * Process:
29
+ * 1. Group cells by site (use siteName or siteId)
30
+ * 2. For each cell, create sector configuration
31
+ * 3. Load antenna patterns
32
+ * 4. Set RF parameters (power, frequency, tilts)
33
+ * 5. Assign colors for visualization
34
+ *
35
+ * @param cells - Array of cells from map component
36
+ * @param siteId - Optional site ID to filter (if cells from multiple sites)
37
+ * @returns Site configuration ready for coverage calculation
38
+ *
39
+ * @example
40
+ * const cells = getCellsForSite("SITE_001");
41
+ * const siteConfig = await siteStore.createSiteConfiguration(cells);
42
+ *
43
+ * // Use for coverage calculation
44
+ * const calculator = new CoverageCalculator();
45
+ * const result = await calculator.calculate({ site: siteConfig, ... });
46
+ */
47
+ createSiteConfiguration(cells: Cell[], siteId?: string): Promise<SiteConfiguration | null>;
48
+ /**
49
+ * Create sector configuration from a single cell
50
+ *
51
+ * @param cell - Cell data from map
52
+ * @param index - Sector index (for color assignment)
53
+ * @returns Sector configuration
54
+ */
55
+ private createSectorConfig; /**
56
+ * Group cells by site
57
+ *
58
+ * Takes an array of cells and groups them by site for batch processing.
59
+ *
60
+ * @param cells - Array of all cells
61
+ * @returns Map of siteId → cells
62
+ */
63
+ groupCellsBySite(cells: Cell[]): Map<string, Cell[]>;
64
+ /**
65
+ * Create site configurations for multiple sites
66
+ *
67
+ * @param cells - Array of all cells
68
+ * @returns Array of site configurations
69
+ */
70
+ createMultipleSiteConfigurations(cells: Cell[]): Promise<SiteConfiguration[]>;
71
+ /**
72
+ * Parse frequency from band string
73
+ *
74
+ * Examples:
75
+ * "700" → 700 MHz
76
+ * "1800" → 1800 MHz
77
+ * "L700" → 700 MHz
78
+ * "B3" → 1800 MHz (LTE Band 3)
79
+ *
80
+ * @param band - Band identifier
81
+ * @returns Frequency in MHz
82
+ */
83
+ private parseFrequency;
84
+ /**
85
+ * Convert LTE band number to center frequency
86
+ *
87
+ * @param bandNumber - LTE band number
88
+ * @returns Center frequency in MHz
89
+ */
90
+ private bandNumberToFrequency;
91
+ /**
92
+ * Parse mechanical tilt value
93
+ *
94
+ * Handles various formats:
95
+ * - Number: 3 → 3
96
+ * - String: "3" → 3
97
+ * - String with units: "3°" → 3
98
+ *
99
+ * @param tilt - Tilt value (various formats)
100
+ * @returns Tilt as number
101
+ */
102
+ private parseTilt;
103
+ /**
104
+ * Get color for sector visualization
105
+ *
106
+ * Standard sector colors (3-sector site):
107
+ * - Sector 0 (Alpha): Blue
108
+ * - Sector 1 (Beta): Green
109
+ * - Sector 2 (Gamma): Red
110
+ *
111
+ * @param index - Sector index
112
+ * @returns Hex color
113
+ */
114
+ private getSectorColor;
115
+ /**
116
+ * Extract sector name from cell name
117
+ *
118
+ * Examples:
119
+ * "SITE001_Alpha" → "Alpha"
120
+ * "SITE001_A" → "A"
121
+ * "SITE001_1" → "Sector 1"
122
+ *
123
+ * @param cellName - Full cell name
124
+ * @param index - Fallback index
125
+ * @returns Sector name
126
+ */
127
+ private extractSectorName;
128
+ }
129
+ /**
130
+ * Global site store instance
131
+ *
132
+ * @example
133
+ * import { siteStore } from './SiteStore';
134
+ *
135
+ * const siteConfig = await siteStore.createSiteConfiguration(cells);
136
+ */
137
+ export declare const siteStore: SiteStore;
138
+ /**
139
+ * Quick site configuration creation
140
+ *
141
+ * Convenience function for creating a single site configuration.
142
+ *
143
+ * @param cells - Cells for the site
144
+ * @returns Site configuration or null
145
+ */
146
+ export declare function createQuickSiteConfig(cells: Cell[]): Promise<SiteConfiguration | null>;
147
+ /**
148
+ * Get sites from cell array
149
+ *
150
+ * Returns unique site identifiers from an array of cells.
151
+ *
152
+ * @param cells - Array of cells
153
+ * @returns Array of site IDs
154
+ */
155
+ export declare function getSiteIds(cells: Cell[]): string[];