@smartnet360/svelte-components 0.0.84 → 0.0.86

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 (122) hide show
  1. package/dist/apps/antenna-pattern/components/AntennaControls.svelte +1 -106
  2. package/dist/apps/antenna-pattern/components/AntennaDiagrams.svelte +0 -36
  3. package/dist/apps/antenna-pattern/components/AntennaSettingsModal.svelte +0 -2
  4. package/dist/apps/antenna-pattern/components/PlotlyRadarChart.svelte +0 -22
  5. package/dist/apps/antenna-pattern/components/chart-engines/PolarAreaChart.svelte +0 -2
  6. package/dist/apps/antenna-pattern/components/chart-engines/PolarBarChart.svelte +0 -2
  7. package/dist/apps/antenna-pattern/components/chart-engines/PolarLineChart.svelte +0 -2
  8. package/dist/apps/site-check/SiteCheck.svelte +60 -80
  9. package/dist/apps/site-check/data-loader.d.ts +9 -6
  10. package/dist/apps/site-check/data-loader.js +2 -11
  11. package/dist/apps/site-check/helper.d.ts +3 -2
  12. package/dist/apps/site-check/helper.js +7 -5
  13. package/dist/apps/site-check/index.d.ts +1 -1
  14. package/dist/apps/site-check/transforms.d.ts +4 -2
  15. package/dist/apps/site-check/transforms.js +49 -10
  16. package/dist/core/Charts/GlobalControls.svelte +0 -4
  17. package/dist/core/Desktop/Grid/ResizeHandle.svelte +0 -7
  18. package/dist/core/Desktop/Grid/resizeStore.js +0 -1
  19. package/dist/index.d.ts +1 -0
  20. package/dist/index.js +2 -0
  21. package/dist/map-v2/demo/DemoMap.svelte +0 -2
  22. package/dist/map-v2/demo/demo-cells.js +0 -1
  23. package/dist/map-v2/features/cells/layers/CellsLayer.svelte +7 -26
  24. package/dist/map-v2/features/cells/utils/cellTree.js +0 -29
  25. package/dist/map-v2/features/repeaters/layers/RepeaterLabelsLayer.svelte +3 -27
  26. package/dist/map-v2/features/repeaters/layers/RepeatersLayer.svelte +8 -25
  27. package/dist/map-v2/features/repeaters/utils/repeaterTree.js +0 -6
  28. package/dist/map-v2/features/sites/controls/SiteFilterControl.svelte +0 -8
  29. package/dist/map-v2/features/sites/utils/siteTreeUtils.js +0 -6
  30. package/dist/map-v3/core/components/Map.svelte +89 -0
  31. package/dist/map-v3/core/components/Map.svelte.d.ts +13 -0
  32. package/dist/map-v3/core/controls/FeatureSettingsControl.svelte +103 -0
  33. package/dist/map-v3/core/controls/FeatureSettingsControl.svelte.d.ts +15 -0
  34. package/dist/map-v3/core/controls/MapStyleControl.svelte +271 -0
  35. package/dist/map-v3/core/controls/MapStyleControl.svelte.d.ts +28 -0
  36. package/dist/map-v3/core/index.d.ts +3 -0
  37. package/dist/map-v3/core/index.js +3 -0
  38. package/dist/map-v3/core/stores/map.store.svelte.d.ts +8 -0
  39. package/dist/map-v3/core/stores/map.store.svelte.js +29 -0
  40. package/dist/map-v3/core/stores/viewport.store.svelte.d.ts +38 -0
  41. package/dist/map-v3/core/stores/viewport.store.svelte.js +107 -0
  42. package/dist/map-v3/demo/DemoMap.svelte +104 -0
  43. package/dist/map-v3/demo/DemoMap.svelte.d.ts +6 -0
  44. package/dist/map-v3/demo/demo-cells.d.ts +13 -0
  45. package/dist/map-v3/demo/demo-cells.js +130 -0
  46. package/dist/map-v3/demo/demo-data.d.ts +8 -0
  47. package/dist/map-v3/demo/demo-data.js +104 -0
  48. package/dist/map-v3/demo/demo-repeaters.d.ts +13 -0
  49. package/dist/map-v3/demo/demo-repeaters.js +73 -0
  50. package/dist/map-v3/features/cells/components/CellFilterControl.svelte +208 -0
  51. package/dist/map-v3/features/cells/components/CellFilterControl.svelte.d.ts +12 -0
  52. package/dist/map-v3/features/cells/components/CellSettingsPanel.svelte +229 -0
  53. package/dist/map-v3/features/cells/components/CellSettingsPanel.svelte.d.ts +7 -0
  54. package/dist/map-v3/features/cells/constants.d.ts +18 -0
  55. package/dist/map-v3/features/cells/constants.js +37 -0
  56. package/dist/map-v3/features/cells/layers/CellLabelsLayer.svelte +230 -0
  57. package/dist/map-v3/features/cells/layers/CellLabelsLayer.svelte.d.ts +11 -0
  58. package/dist/map-v3/features/cells/layers/CellsLayer.svelte +194 -0
  59. package/dist/map-v3/features/cells/layers/CellsLayer.svelte.d.ts +11 -0
  60. package/dist/map-v3/features/cells/layers/index.d.ts +2 -0
  61. package/dist/map-v3/features/cells/layers/index.js +2 -0
  62. package/dist/map-v3/features/cells/logic/geometry.d.ts +12 -0
  63. package/dist/map-v3/features/cells/logic/geometry.js +35 -0
  64. package/dist/map-v3/features/cells/logic/grouping.d.ts +18 -0
  65. package/dist/map-v3/features/cells/logic/grouping.js +30 -0
  66. package/dist/map-v3/features/cells/logic/tree-adapter.d.ts +11 -0
  67. package/dist/map-v3/features/cells/logic/tree-adapter.js +53 -0
  68. package/dist/map-v3/features/cells/stores/cell.data.svelte.d.ts +9 -0
  69. package/dist/map-v3/features/cells/stores/cell.data.svelte.js +16 -0
  70. package/dist/map-v3/features/cells/stores/cell.display.svelte.d.ts +25 -0
  71. package/dist/map-v3/features/cells/stores/cell.display.svelte.js +67 -0
  72. package/dist/map-v3/features/cells/stores/cell.registry.svelte.d.ts +23 -0
  73. package/dist/map-v3/features/cells/stores/cell.registry.svelte.js +68 -0
  74. package/dist/map-v3/features/cells/types.d.ts +62 -0
  75. package/dist/map-v3/features/cells/types.js +6 -0
  76. package/dist/map-v3/features/repeaters/components/RepeaterFilterControl.svelte +148 -0
  77. package/dist/map-v3/features/repeaters/components/RepeaterFilterControl.svelte.d.ts +12 -0
  78. package/dist/map-v3/features/repeaters/components/RepeaterSettingsPanel.svelte +209 -0
  79. package/dist/map-v3/features/repeaters/components/RepeaterSettingsPanel.svelte.d.ts +7 -0
  80. package/dist/map-v3/features/repeaters/layers/RepeaterLabelsLayer.svelte +177 -0
  81. package/dist/map-v3/features/repeaters/layers/RepeaterLabelsLayer.svelte.d.ts +11 -0
  82. package/dist/map-v3/features/repeaters/layers/RepeatersLayer.svelte +163 -0
  83. package/dist/map-v3/features/repeaters/layers/RepeatersLayer.svelte.d.ts +11 -0
  84. package/dist/map-v3/features/repeaters/logic/geometry.d.ts +3 -0
  85. package/dist/map-v3/features/repeaters/logic/geometry.js +23 -0
  86. package/dist/map-v3/features/repeaters/logic/grouping.d.ts +8 -0
  87. package/dist/map-v3/features/repeaters/logic/grouping.js +20 -0
  88. package/dist/map-v3/features/repeaters/logic/tree-adapter.d.ts +8 -0
  89. package/dist/map-v3/features/repeaters/logic/tree-adapter.js +43 -0
  90. package/dist/map-v3/features/repeaters/stores/repeater.data.svelte.d.ts +8 -0
  91. package/dist/map-v3/features/repeaters/stores/repeater.data.svelte.js +13 -0
  92. package/dist/map-v3/features/repeaters/stores/repeater.display.svelte.d.ts +21 -0
  93. package/dist/map-v3/features/repeaters/stores/repeater.display.svelte.js +64 -0
  94. package/dist/map-v3/features/repeaters/stores/repeater.registry.svelte.d.ts +23 -0
  95. package/dist/map-v3/features/repeaters/stores/repeater.registry.svelte.js +68 -0
  96. package/dist/map-v3/features/repeaters/types.d.ts +18 -0
  97. package/dist/map-v3/features/repeaters/types.js +1 -0
  98. package/dist/map-v3/features/sites/components/SiteFilterControl.svelte +119 -0
  99. package/dist/map-v3/features/sites/components/SiteFilterControl.svelte.d.ts +12 -0
  100. package/dist/map-v3/features/sites/components/SiteSettingsPanel.svelte +241 -0
  101. package/dist/map-v3/features/sites/components/SiteSettingsPanel.svelte.d.ts +7 -0
  102. package/dist/map-v3/features/sites/layers/SiteLabelsLayer.svelte +152 -0
  103. package/dist/map-v3/features/sites/layers/SiteLabelsLayer.svelte.d.ts +11 -0
  104. package/dist/map-v3/features/sites/layers/SitesLayer.svelte +132 -0
  105. package/dist/map-v3/features/sites/layers/SitesLayer.svelte.d.ts +11 -0
  106. package/dist/map-v3/features/sites/logic/tree-adapter.d.ts +9 -0
  107. package/dist/map-v3/features/sites/logic/tree-adapter.js +75 -0
  108. package/dist/map-v3/features/sites/stores/site.data.svelte.d.ts +8 -0
  109. package/dist/map-v3/features/sites/stores/site.data.svelte.js +40 -0
  110. package/dist/map-v3/features/sites/stores/site.display.svelte.d.ts +20 -0
  111. package/dist/map-v3/features/sites/stores/site.display.svelte.js +63 -0
  112. package/dist/map-v3/features/sites/stores/site.registry.svelte.d.ts +13 -0
  113. package/dist/map-v3/features/sites/stores/site.registry.svelte.js +83 -0
  114. package/dist/map-v3/features/sites/types.d.ts +12 -0
  115. package/dist/map-v3/features/sites/types.js +1 -0
  116. package/dist/map-v3/index.d.ts +26 -0
  117. package/dist/map-v3/index.js +31 -0
  118. package/dist/map-v3/shared/controls/MapControl.svelte +242 -0
  119. package/dist/map-v3/shared/controls/MapControl.svelte.d.ts +27 -0
  120. package/dist/map-v3/shared/index.d.ts +1 -0
  121. package/dist/map-v3/shared/index.js +1 -0
  122. package/package.json +1 -1
@@ -6,11 +6,12 @@ import { createStyledKPI, sortCellsByBandFrequency, assignStackGroups } from './
6
6
  * @param baseLayout - The base layout configuration from JSON
7
7
  * @param data - Filtered cell traffic records for selected cells
8
8
  * @param grouping - Current tree grouping configuration (determines label format)
9
+ * @param colorDimension - Which field to use for coloring (site or band)
9
10
  * @param stylingConfig - Optional cell styling configuration (band colors, sector line styles)
10
11
  * @param stackGroupMode - Optional stackgroup strategy for stacked charts (default: 'none' = single stack)
11
12
  * @returns Expanded layout with cell-specific KPIs
12
13
  */
13
- export function expandLayoutForCells(baseLayout, data, grouping, stylingConfig, stackGroupMode = 'none') {
14
+ export function expandLayoutForCells(baseLayout, data, grouping, colorDimension, stylingConfig, stackGroupMode = 'none') {
14
15
  // Get unique cells and their metadata, sorted by band frequency
15
16
  const cellMap = new Map();
16
17
  data.forEach((record) => {
@@ -38,8 +39,8 @@ export function expandLayoutForCells(baseLayout, data, grouping, stylingConfig,
38
39
  ...section,
39
40
  charts: section.charts.map((chart) => ({
40
41
  ...chart,
41
- yLeft: expandKPIs(chart.yLeft, cells, grouping, effectiveStyling, stackGroupMode),
42
- yRight: expandKPIs(chart.yRight, cells, grouping, effectiveStyling, stackGroupMode)
42
+ yLeft: expandKPIs(chart.yLeft, cells, grouping, colorDimension, effectiveStyling, stackGroupMode),
43
+ yRight: expandKPIs(chart.yRight, cells, grouping, colorDimension, effectiveStyling, stackGroupMode)
43
44
  }))
44
45
  };
45
46
  })
@@ -54,17 +55,18 @@ export function expandLayoutForCells(baseLayout, data, grouping, stylingConfig,
54
55
  * @param baseKPIs - Array of base KPIs from layout
55
56
  * @param cells - Array of [cellName, record] tuples
56
57
  * @param grouping - Current tree grouping configuration (determines label format)
58
+ * @param colorDimension - Which field to use for coloring (site or band)
57
59
  * @param stylingConfig - Optional cell styling configuration
58
60
  * @param stackGroupMode - Stackgroup strategy for this set of KPIs
59
61
  * @returns Expanded array of KPIs (styled or default, with stackgroups assigned)
60
62
  */
61
- function expandKPIs(baseKPIs, cells, grouping, stylingConfig, stackGroupMode = 'none') {
63
+ function expandKPIs(baseKPIs, cells, grouping, colorDimension, stylingConfig, stackGroupMode = 'none') {
62
64
  let expandedKPIs = [];
63
65
  baseKPIs.forEach((baseKPI) => {
64
66
  cells.forEach(([cellName, record]) => {
65
67
  if (stylingConfig) {
66
68
  // Apply custom styling (band colors, sector line styles)
67
- const styledKPI = createStyledKPI(baseKPI.rawName, record, baseKPI.unit, grouping, stylingConfig);
69
+ const styledKPI = createStyledKPI(baseKPI.rawName, record, baseKPI.unit, grouping, colorDimension, stylingConfig);
68
70
  expandedKPIs.push({
69
71
  ...styledKPI,
70
72
  stackGroup: undefined // Initialize for treeshake-safe property assignment
@@ -3,7 +3,7 @@
3
3
  * Public API exports for cell traffic KPI visualization
4
4
  */
5
5
  export { default as SiteCheck } from './SiteCheck.svelte';
6
- export { loadCellTrafficData, getUniqueSites, getUniqueCells, groupDataByCell, defaultTreeGrouping, type CellTrafficRecord, type TreeGroupingConfig, type TreeGroupField } from './data-loader.js';
6
+ export { loadCellTrafficData, getUniqueSites, getUniqueCells, groupDataByCell, defaultTreeGrouping, type CellTrafficRecord, type TreeGroupingConfig, type TreeGroupField, type ColorDimension } from './data-loader.js';
7
7
  export { buildTreeNodes, filterChartData, transformChartData, createStyledKPI, extractBandFromCell, getBandFrequency, sortCellsByBandFrequency, assignStackGroups, createStackGroupId, type StackGroupMode } from './transforms.js';
8
8
  export { expandLayoutForCells, extractBaseMetrics } from './helper.js';
9
9
  export { defaultCellStyling } from './default-cell-styling.js';
@@ -4,7 +4,7 @@
4
4
  */
5
5
  import type { TreeNode } from '../../core/TreeView';
6
6
  import type { KPI, CellStylingConfig } from '../../core/Charts';
7
- import type { CellTrafficRecord, TreeGroupingConfig } from './data-loader';
7
+ import type { CellTrafficRecord, TreeGroupingConfig, ColorDimension } from './data-loader';
8
8
  /**
9
9
  * Stackgroup mode types for dynamic stacking strategies
10
10
  */
@@ -75,11 +75,13 @@ export declare function transformChartData(data: CellTrafficRecord[], baseMetric
75
75
  /**
76
76
  * Create a styled KPI with band colors and sector line styles
77
77
  * Label format adapts to tree grouping configuration
78
+ * Color assignment adapts to colorDimension selection
78
79
  * @param metricName - Base metric name (e.g., 'DL_GBYTES')
79
80
  * @param cellRecord - Cell traffic record with metadata
80
81
  * @param unit - Unit string (e.g., 'GB', '%')
81
82
  * @param grouping - Current tree grouping configuration (determines label format)
83
+ * @param colorDimension - Which field to use for coloring (site or band)
82
84
  * @param stylingConfig - Optional styling configuration
83
85
  * @returns KPI with cell-specific styling applied
84
86
  */
85
- export declare function createStyledKPI(metricName: string, cellRecord: CellTrafficRecord, unit: string, grouping: TreeGroupingConfig, stylingConfig?: CellStylingConfig): KPI;
87
+ export declare function createStyledKPI(metricName: string, cellRecord: CellTrafficRecord, unit: string, grouping: TreeGroupingConfig, colorDimension: ColorDimension, stylingConfig?: CellStylingConfig): KPI;
@@ -154,7 +154,7 @@ export function sortCellsByBandFrequency(items) {
154
154
  * @param data - Cell traffic records
155
155
  * @param grouping - Tree grouping configuration (defaults to Site → Azimuth → Cell)
156
156
  */
157
- export function buildTreeNodes(data, grouping = { level0: 'site', level1: 'azimuth', level2: 'cell' }) {
157
+ export function buildTreeNodes(data, grouping = { level0: 'site', level1: 'azimuth' }) {
158
158
  log('🔄 Building tree nodes', {
159
159
  recordCount: data.length,
160
160
  grouping,
@@ -441,20 +441,60 @@ export function transformChartData(data, baseMetrics) {
441
441
  });
442
442
  return pivotedData;
443
443
  }
444
+ /**
445
+ * Generate a consistent color for a site name using a hash function
446
+ * Same site will always get the same color
447
+ * @param siteName - Site name to generate color for
448
+ * @returns Hex color string
449
+ */
450
+ function generateSiteColor(siteName) {
451
+ // Modern color palette for sites
452
+ const siteColors = [
453
+ '#3B82F6', // Blue
454
+ '#EF4444', // Red
455
+ '#10B981', // Emerald
456
+ '#F59E0B', // Amber
457
+ '#8B5CF6', // Violet
458
+ '#06B6D4', // Cyan
459
+ '#F97316', // Orange
460
+ '#84CC16', // Lime
461
+ '#EC4899', // Pink
462
+ '#14B8A6', // Teal
463
+ '#F43F5E', // Rose
464
+ '#A855F7' // Purple
465
+ ];
466
+ // Simple hash function for consistent color assignment
467
+ let hash = 0;
468
+ for (let i = 0; i < siteName.length; i++) {
469
+ hash = siteName.charCodeAt(i) + ((hash << 5) - hash);
470
+ }
471
+ hash = Math.abs(hash);
472
+ return siteColors[hash % siteColors.length];
473
+ }
444
474
  /**
445
475
  * Create a styled KPI with band colors and sector line styles
446
476
  * Label format adapts to tree grouping configuration
477
+ * Color assignment adapts to colorDimension selection
447
478
  * @param metricName - Base metric name (e.g., 'DL_GBYTES')
448
479
  * @param cellRecord - Cell traffic record with metadata
449
480
  * @param unit - Unit string (e.g., 'GB', '%')
450
481
  * @param grouping - Current tree grouping configuration (determines label format)
482
+ * @param colorDimension - Which field to use for coloring (site or band)
451
483
  * @param stylingConfig - Optional styling configuration
452
484
  * @returns KPI with cell-specific styling applied
453
485
  */
454
- export function createStyledKPI(metricName, cellRecord, unit, grouping, stylingConfig) {
486
+ export function createStyledKPI(metricName, cellRecord, unit, grouping, colorDimension, stylingConfig) {
455
487
  const { band, sector, azimuth, cellName, siteName } = cellRecord;
456
- // Get color from band (if config provided)
457
- const color = stylingConfig?.bandColors?.[band];
488
+ // Determine color based on colorDimension
489
+ let color;
490
+ if (colorDimension === 'band') {
491
+ // Get color from band colors config
492
+ color = stylingConfig?.bandColors?.[band];
493
+ }
494
+ else if (colorDimension === 'site') {
495
+ // Generate consistent color for site
496
+ color = generateSiteColor(siteName);
497
+ }
458
498
  // Get line style from sector (if config provided)
459
499
  const lineStyle = stylingConfig?.sectorLineStyles?.[sector.toString()];
460
500
  // Generate label based on tree grouping configuration
@@ -475,6 +515,7 @@ export function createStyledKPI(metricName, cellRecord, unit, grouping, stylingC
475
515
  band,
476
516
  sector,
477
517
  azimuth,
518
+ colorDimension,
478
519
  color,
479
520
  lineStyle
480
521
  });
@@ -489,7 +530,7 @@ export function createStyledKPI(metricName, cellRecord, unit, grouping, stylingC
489
530
  * @returns Formatted label string matching complete tree hierarchy (only non-null levels)
490
531
  */
491
532
  function generateAdaptiveLabel(record, grouping) {
492
- const { level0, level1, level2 } = grouping;
533
+ const { level0, level1 } = grouping;
493
534
  // Helper to format field values exactly as shown in tree
494
535
  const formatField = (field, value) => {
495
536
  if (field === 'cell') {
@@ -532,10 +573,8 @@ function generateAdaptiveLabel(record, grouping) {
532
573
  if (level1 !== null) {
533
574
  parts.push(formatField(level1, getFieldValue(level1)));
534
575
  }
535
- // Level 2 (optional)
536
- if (level2 !== null) {
537
- parts.push(formatField(level2, getFieldValue(level2)));
538
- }
576
+ // Cell is always the final leaf node
577
+ parts.push(record.cellName);
539
578
  // Join with arrow separator
540
- return parts.join('_');
579
+ return parts.join('');
541
580
  }
@@ -35,14 +35,10 @@
35
35
  function saveSettings(updatedControls: GlobalChartControls) {
36
36
  if (persistSettings && typeof window !== 'undefined') {
37
37
  try {
38
- console.log('💾 Saving chart controls to localStorage:', updatedControls);
39
38
  localStorage.setItem(STORAGE_KEY, JSON.stringify(updatedControls));
40
- console.log('✅ Saved successfully');
41
39
  } catch (error) {
42
40
  console.warn('Failed to save chart controls to localStorage:', error);
43
41
  }
44
- } else {
45
- console.log('⚠️ Not saving: persistSettings =', persistSettings);
46
42
  }
47
43
  }
48
44
 
@@ -19,8 +19,6 @@
19
19
  startHorizontalSize = horizontalSize;
20
20
  startVerticalSize = verticalSize;
21
21
 
22
- console.log('MouseDown:', { startX, startY, startHorizontalSize, startVerticalSize });
23
-
24
22
  document.addEventListener('mousemove', handleMouseMove);
25
23
  document.addEventListener('mouseup', handleMouseUp);
26
24
 
@@ -33,14 +31,10 @@
33
31
  const deltaX = event.clientX - startX;
34
32
  const deltaY = event.clientY - startY;
35
33
 
36
- console.log('MouseMove:', { deltaX, deltaY });
37
-
38
34
  // Always calculate both dimensions - let the layout decide what to do
39
35
  const newHorizontalSize = Math.max(10, Math.min(90, startHorizontalSize + (deltaX / 4)));
40
36
  const newVerticalSize = Math.max(10, Math.min(90, startVerticalSize + (deltaY / 4)));
41
37
 
42
- console.log('Resize:', { newHorizontalSize, newVerticalSize });
43
-
44
38
  dispatch('resize', {
45
39
  horizontalSize: newHorizontalSize,
46
40
  verticalSize: newVerticalSize
@@ -48,7 +42,6 @@
48
42
  }
49
43
 
50
44
  function handleMouseUp() {
51
- console.log('MouseUp - stopping drag');
52
45
  isDragging = false;
53
46
  document.removeEventListener('mousemove', handleMouseMove);
54
47
  document.removeEventListener('mouseup', handleMouseUp);
@@ -31,7 +31,6 @@ function createResizeStore() {
31
31
  topHeight: Math.max(10, Math.min(90, verticalSize)),
32
32
  bottomHeight: 100 - Math.max(10, Math.min(90, verticalSize))
33
33
  };
34
- console.log('Store update2D:', { horizontalSize, verticalSize, newState });
35
34
  return newState;
36
35
  })
37
36
  };
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export * from './core/index.js';
2
2
  export * from './map-v2/index.js';
3
+ export * as MapV3 from './map-v3/index.js';
3
4
  export * from './apps/index.js';
package/dist/index.js CHANGED
@@ -4,5 +4,7 @@
4
4
  export * from './core/index.js';
5
5
  // Map components (Mapbox cellular visualization - v2)
6
6
  export * from './map-v2/index.js';
7
+ // Map components (Mapbox cellular visualization - v3)
8
+ export * as MapV3 from './map-v3/index.js';
7
9
  // Complete applications
8
10
  export * from './apps/index.js';
@@ -81,7 +81,6 @@
81
81
 
82
82
  // Handler for site selection action button
83
83
  function handleAnalyzeSites(siteIds: string[]) {
84
- console.log('Analyze sites:', siteIds);
85
84
  // Example: Navigate to SiteCheck page with selected sites
86
85
  // window.location.href = `/site-check?sites=${siteIds.join(',')}`;
87
86
  // Or use SvelteKit navigate, or open modal, etc.
@@ -90,7 +89,6 @@
90
89
 
91
90
  // Handler for generic feature selection action button
92
91
  function handleProcessFeatures(featureIds: string[]) {
93
- console.log('Process features:', featureIds);
94
92
  alert(`Selected ${featureIds.length} features:\n${featureIds.join(', ')}`);
95
93
  }
96
94
 
@@ -129,4 +129,3 @@ for (let siteIndex = 0; siteIndex < NUM_SITES; siteIndex++) {
129
129
  });
130
130
  });
131
131
  }
132
- console.log(`Generated ${demoCells.length} demo cells across ${NUM_SITES} sites (${AZIMUTHS.length} sectors × ${TECH_BANDS.length} tech-bands per site)`);
@@ -15,6 +15,7 @@
15
15
  import { useMapbox } from '../../../core/hooks/useMapbox';
16
16
  import { cellsToGeoJSON } from '../utils/cellGeoJSON';
17
17
  import { CELL_FILL_Z_INDEX, CELL_LINE_Z_INDEX, Z_INDEX_BY_BAND } from '../constants/zIndex';
18
+ import { log } from '../../../../core/logger';
18
19
 
19
20
  interface Props {
20
21
  /** Cell store context */
@@ -56,7 +57,7 @@
56
57
  viewportUpdateTimer = setTimeout(() => {
57
58
  if (!map) return;
58
59
  const newZoom = map.getZoom();
59
- console.log('CellsLayer: Viewport changed (zoom/pan), updating to zoom:', newZoom);
60
+ log('CellsLayer: Viewport changed (zoom/pan), updating to zoom:', newZoom);
60
61
  // Update zoom if changed
61
62
  store.setCurrentZoom(newZoom);
62
63
  // Force $effect to re-run by incrementing version (triggers on pan without zoom change)
@@ -71,8 +72,6 @@
71
72
  function initializeLayer() {
72
73
  if (!map) return;
73
74
 
74
- console.log('CellsLayer: initializeLayer called');
75
-
76
75
  // Set initial zoom
77
76
  store.setCurrentZoom(map.getZoom());
78
77
 
@@ -91,12 +90,9 @@
91
90
  }
92
91
 
93
92
  onMount(() => {
94
- console.log('CellsLayer: onMount, waiting for map...');
95
-
96
93
  // Subscribe to map store
97
94
  const unsubscribe = mapStore.subscribe((mapInstance) => {
98
95
  if (mapInstance && !map) {
99
- console.log('CellsLayer: Map available, initializing...');
100
96
  map = mapInstance;
101
97
 
102
98
  // Initial layer setup
@@ -142,14 +138,12 @@
142
138
  // Track viewportVersion to force re-run on pan (even without zoom change)
143
139
  viewportVersion;
144
140
 
145
- console.log('CellsLayer $effect triggered:', {
141
+ log('CellsLayer update:', {
146
142
  mounted,
147
143
  hasMap: !!map,
148
144
  showCells: store.showCells,
149
145
  filteredCellsCount: store.filteredCells.length,
150
- currentZoom: store.currentZoom,
151
- baseRadius: store.baseRadius,
152
- viewportVersion
146
+ currentZoom: store.currentZoom
153
147
  });
154
148
 
155
149
  if (!mounted || !map) {
@@ -180,15 +174,9 @@
180
174
  bounds.contains([cell.longitude, cell.latitude])
181
175
  );
182
176
 
183
- console.log('CellsLayer: Viewport filtering:', {
177
+ log('CellsLayer viewport filter:', {
184
178
  totalFiltered: store.filteredCells.length,
185
- visibleInViewport: visibleCells.length,
186
- bounds: {
187
- north: bounds.getNorth(),
188
- south: bounds.getSouth(),
189
- east: bounds.getEast(),
190
- west: bounds.getWest()
191
- }
179
+ visibleInViewport: visibleCells.length
192
180
  });
193
181
 
194
182
  // Generate GeoJSON from visible cells only
@@ -200,18 +188,13 @@
200
188
  store.cellGroupMap // Pass lookup map for O(1) color lookup
201
189
  );
202
190
 
203
- console.log('CellsLayer: Generated GeoJSON:', {
204
- featureCount: geoJSON.features.length,
205
- firstFeature: geoJSON.features[0]
206
- });
191
+ log('CellsLayer GeoJSON generated:', geoJSON.features.length, 'features');
207
192
 
208
193
  // Update or create source
209
194
  const source = map.getSource(SOURCE_ID);
210
195
  if (source && source.type === 'geojson') {
211
- console.log('CellsLayer: Updating existing source');
212
196
  source.setData(geoJSON);
213
197
  } else {
214
- console.log('CellsLayer: Creating new source');
215
198
  map.addSource(SOURCE_ID, {
216
199
  type: 'geojson',
217
200
  data: geoJSON
@@ -235,7 +218,6 @@
235
218
 
236
219
  // Add fill layer if not exists
237
220
  if (!map.getLayer(fillLayerId)) {
238
- console.log(`CellsLayer: Creating fill layer for z-index ${zIndex}`);
239
221
  map.addLayer({
240
222
  id: fillLayerId,
241
223
  type: 'fill',
@@ -261,7 +243,6 @@
261
243
 
262
244
  // Add line layer if not exists
263
245
  if (!map.getLayer(lineLayerId)) {
264
- console.log(`CellsLayer: Creating line layer for z-index ${zIndex}`);
265
246
  map.addLayer({
266
247
  id: lineLayerId,
267
248
  type: 'line',
@@ -211,30 +211,16 @@ function buildNestedTree(cells, level1, level2, colorMap, labelMap) {
211
211
  * @returns Filtered array of cells
212
212
  */
213
213
  export function getFilteredCells(checkedPaths, allCells) {
214
- console.log('=== getFilteredCells START ===');
215
- console.log('Checked paths:', Array.from(checkedPaths));
216
- console.log('Total cells:', allCells.length);
217
214
  // If root is checked (or no specific filters), return all cells
218
215
  if (checkedPaths.has('root') && checkedPaths.size === 1) {
219
- console.log('Root only checked, returning all cells');
220
216
  return allCells;
221
217
  }
222
- // Sample first 3 cells for detailed logging
223
- const sampleSize = 3;
224
- let processedCount = 0;
225
218
  // Filter cells that match any of the checked paths
226
219
  const filtered = allCells.filter((cell) => {
227
- const shouldLog = processedCount < sampleSize;
228
- if (shouldLog) {
229
- console.log(`\n--- Sample Cell ${processedCount + 1}: ${cell.id} ---`);
230
- console.log(` Properties: tech="${cell.tech}", frq="${cell.frq}", status="${cell.status}"`);
231
- }
232
220
  // Check if this cell belongs to any checked path
233
221
  const matched = Array.from(checkedPaths).some((path) => {
234
222
  // Match cell properties against path segments
235
223
  if (path === 'root') {
236
- if (shouldLog)
237
- console.log(` Path "root": MATCH`);
238
224
  return true;
239
225
  }
240
226
  // Parse path and filter out "root" prefix and deduplicate consecutive segments
@@ -248,9 +234,6 @@ export function getFilteredCells(checkedPaths, allCells) {
248
234
  prevSegment = segment;
249
235
  }
250
236
  }
251
- if (shouldLog) {
252
- console.log(` Checking path "${path}" (raw: [${allSegments.join(', ')}], filtered: [${segments.join(', ')}])`);
253
- }
254
237
  // Match filtered segments against cell properties
255
238
  const segmentMatches = segments.every((segment) => {
256
239
  const matches = (cell.tech === segment ||
@@ -260,23 +243,11 @@ export function getFilteredCells(checkedPaths, allCells) {
260
243
  cell.customSubgroup === segment ||
261
244
  cell.type === segment ||
262
245
  cell.planner === segment);
263
- if (shouldLog) {
264
- console.log(` Segment "${segment}": ${matches ? '✓ MATCH' : '✗ NO MATCH'}`);
265
- }
266
246
  return matches;
267
247
  });
268
- if (shouldLog) {
269
- console.log(` Path "${path}": ${segmentMatches ? '✓ MATCHED' : '✗ NOT MATCHED'}`);
270
- }
271
248
  return segmentMatches;
272
249
  });
273
- if (shouldLog) {
274
- console.log(` Final result: ${matched ? '✓ INCLUDE' : '✗ EXCLUDE'}`);
275
- }
276
- processedCount++;
277
250
  return matched;
278
251
  });
279
- console.log(`\nFiltered result: ${filtered.length} of ${allCells.length} cells`);
280
- console.log('=== getFilteredCells END ===\n');
281
252
  return filtered;
282
253
  }
@@ -16,6 +16,7 @@
16
16
  import type { RepeaterStoreContext } from '../stores/repeaterStoreContext.svelte';
17
17
  import type { Repeater } from '../types';
18
18
  import * as turf from '@turf/turf';
19
+ import { log } from '../../../../core/logger';
19
20
 
20
21
  interface Props {
21
22
  /** Repeater store context */
@@ -66,18 +67,7 @@
66
67
  function buildLabelFeatures(): GeoJSON.FeatureCollection {
67
68
  const features: GeoJSON.Feature[] = [];
68
69
 
69
- console.log('RepeaterLabelsLayer: Building label features', {
70
- showLabels: store.showLabels,
71
- filteredRepeatersCount: store.filteredRepeaters.length,
72
- hasMap: !!map
73
- });
74
-
75
70
  if (!store.showLabels || store.filteredRepeaters.length === 0 || !map) {
76
- console.log('RepeaterLabelsLayer: Skipping labels -', {
77
- showLabels: store.showLabels,
78
- hasRepeaters: store.filteredRepeaters.length > 0,
79
- hasMap: !!map
80
- });
81
71
  return { type: 'FeatureCollection', features: [] };
82
72
  }
83
73
 
@@ -134,11 +124,7 @@
134
124
  });
135
125
  });
136
126
 
137
- console.log('RepeaterLabelsLayer: Built features', {
138
- totalRepeaters: store.filteredRepeaters.length,
139
- visibleInViewport: visibleRepeaters.length,
140
- featuresGenerated: features.length
141
- });
127
+ log('RepeaterLabelsLayer features:', features.length, 'of', visibleRepeaters.length, 'visible repeaters');
142
128
 
143
129
  return { type: 'FeatureCollection', features };
144
130
  }
@@ -151,15 +137,7 @@
151
137
 
152
138
  const geojson = buildLabelFeatures();
153
139
 
154
- console.log('RepeaterLabelsLayer: Updating labels', {
155
- sourceExists: !!map.getSource(sourceId),
156
- layerExists: !!map.getLayer(layerId),
157
- featureCount: geojson.features.length,
158
- currentZoom: map.getZoom(),
159
- minLabelZoom: store.minLabelZoom,
160
- labelSize: store.labelSize,
161
- labelColor: store.labelColor
162
- });
140
+ log('RepeaterLabelsLayer: Updating', geojson.features.length, 'labels');
163
141
 
164
142
  const source = map.getSource(sourceId) as mapboxgl.GeoJSONSource;
165
143
  source.setData(geojson);
@@ -171,8 +149,6 @@
171
149
  map.setPaintProperty(layerId, 'text-halo-color', store.labelHaloColor);
172
150
  map.setPaintProperty(layerId, 'text-halo-width', store.labelHaloWidth);
173
151
  map.setLayerZoomRange(layerId, store.minLabelZoom, 24);
174
-
175
- console.log('RepeaterLabelsLayer: Updated layer properties');
176
152
  }
177
153
  }
178
154
 
@@ -18,6 +18,7 @@
18
18
  import { repeatersToGeoJSON } from '../utils/repeaterGeoJSON';
19
19
  import { REPEATER_FILL_Z_INDEX, REPEATER_LINE_Z_INDEX } from '../constants/zIndex';
20
20
  import { Z_INDEX_BY_BAND } from '../constants/techBandZOrder';
21
+ import { log } from '../../../../core/logger';
21
22
 
22
23
  interface Props {
23
24
  /** Repeater store context */
@@ -59,7 +60,7 @@
59
60
  viewportUpdateTimer = setTimeout(() => {
60
61
  if (!map) return;
61
62
  const newZoom = map.getZoom();
62
- console.log('RepeatersLayer: Viewport changed, updating to zoom:', newZoom);
63
+ log('RepeatersLayer: Viewport changed, updating to zoom:', newZoom);
63
64
  // Update zoom
64
65
  store.setCurrentZoom(newZoom);
65
66
  // Force $effect to re-run
@@ -74,8 +75,6 @@
74
75
  function initializeLayer() {
75
76
  if (!map) return;
76
77
 
77
- console.log('RepeatersLayer: initializeLayer called');
78
-
79
78
  // Set initial zoom
80
79
  store.setCurrentZoom(map.getZoom());
81
80
 
@@ -91,12 +90,9 @@
91
90
  }
92
91
 
93
92
  onMount(() => {
94
- console.log('RepeatersLayer: onMount, waiting for map...');
95
-
96
93
  // Subscribe to map store
97
94
  const unsubscribe = mapStore.subscribe((mapInstance) => {
98
95
  if (mapInstance && !map) {
99
- console.log('RepeatersLayer: Map available, initializing...');
100
96
  map = mapInstance;
101
97
 
102
98
  // Initial layer setup
@@ -137,19 +133,16 @@
137
133
  }
138
134
  });
139
135
 
140
- // Reactive: Update GeoJSON when repeaters/zoom/settings change
136
+ // Reactive: Update GeoJSON when repeaters/zoom/filters/settings change
141
137
  $effect(() => {
142
- // Track viewportVersion to force re-run on pan
138
+ // Track viewportVersion to force re-run on viewport changes
143
139
  viewportVersion;
144
140
 
145
- console.log('RepeatersLayer $effect triggered:', {
141
+ log('RepeatersLayer update:', {
146
142
  mounted,
147
143
  hasMap: !!map,
148
144
  showRepeaters: store.showRepeaters,
149
- filteredRepeatersCount: store.filteredRepeaters.length,
150
- currentZoom: store.currentZoom,
151
- baseRadius: store.baseRadius,
152
- viewportVersion
145
+ filteredCount: store.filteredRepeaters.length
153
146
  });
154
147
 
155
148
  if (!mounted || !map) {
@@ -180,10 +173,7 @@
180
173
  bounds.contains([repeater.longitude, repeater.latitude])
181
174
  );
182
175
 
183
- console.log('RepeatersLayer: Viewport filtering:', {
184
- totalFiltered: store.filteredRepeaters.length,
185
- visibleInViewport: visibleRepeaters.length
186
- });
176
+ log('RepeatersLayer viewport filter:', visibleRepeaters.length, 'of', store.filteredRepeaters.length);
187
177
 
188
178
  // Generate GeoJSON from visible repeaters only
189
179
  const geoJSON = repeatersToGeoJSON(
@@ -193,18 +183,13 @@
193
183
  store.techBandColorMap
194
184
  );
195
185
 
196
- console.log('RepeatersLayer: Generated GeoJSON:', {
197
- featureCount: geoJSON.features.length,
198
- firstFeature: geoJSON.features[0]
199
- });
186
+ log('RepeatersLayer GeoJSON:', geoJSON.features.length, 'features');
200
187
 
201
188
  // Update or create source
202
189
  const source = map.getSource(SOURCE_ID);
203
190
  if (source && source.type === 'geojson') {
204
- console.log('RepeatersLayer: Updating existing source');
205
191
  source.setData(geoJSON);
206
192
  } else {
207
- console.log('RepeatersLayer: Creating new source');
208
193
  map.addSource(SOURCE_ID, {
209
194
  type: 'geojson',
210
195
  data: geoJSON
@@ -228,7 +213,6 @@
228
213
 
229
214
  // Add fill layer if not exists
230
215
  if (!map.getLayer(fillLayerId)) {
231
- console.log(`RepeatersLayer: Creating fill layer for z-index ${zIndex}`);
232
216
  map.addLayer({
233
217
  id: fillLayerId,
234
218
  type: 'fill',
@@ -249,7 +233,6 @@
249
233
 
250
234
  // Add line layer if not exists
251
235
  if (!map.getLayer(lineLayerId)) {
252
- console.log(`RepeatersLayer: Creating line layer for z-index ${zIndex}`);
253
236
  map.addLayer({
254
237
  id: lineLayerId,
255
238
  type: 'line',
@@ -75,10 +75,8 @@ export function buildRepeaterTree(repeaters, colorMap) {
75
75
  */
76
76
  export function getFilteredRepeaters(checkedPaths) {
77
77
  const selected = new Set();
78
- console.log('getFilteredRepeaters - checkedPaths:', Array.from(checkedPaths));
79
78
  // If only root is checked, all tech:fbands are visible
80
79
  if (checkedPaths.has('root') && checkedPaths.size === 1) {
81
- console.log('Only root checked - returning empty set for "all visible"');
82
80
  return selected;
83
81
  }
84
82
  // Check each path - leaf nodes have tech:fband in their ID
@@ -86,14 +84,12 @@ export function getFilteredRepeaters(checkedPaths) {
86
84
  // Paths are like "root:2G:2G:GSM900" where the node ID is the last segment
87
85
  // The node ID for leaf nodes is "tech:fband" format
88
86
  const parts = path.split(':');
89
- console.log('Processing path:', path, 'parts:', parts);
90
87
  // Check if this is a leaf node (contains tech:fband format)
91
88
  // Leaf node IDs are like "2G:GSM900", "4G:LTE1800"
92
89
  // The path would be "root:2G:2G:GSM900" (root -> tech -> tech:fband)
93
90
  if (parts.length === 4 && parts[0] === 'root') {
94
91
  // This is a leaf node: root:tech:tech:fband
95
92
  const techBandKey = `${parts[2]}:${parts[3]}`;
96
- console.log('Adding tech:fband key:', techBandKey);
97
93
  selected.add(techBandKey);
98
94
  }
99
95
  else if (parts.length === 3 && parts[0] === 'root') {
@@ -101,11 +97,9 @@ export function getFilteredRepeaters(checkedPaths) {
101
97
  const nodeId = parts[2];
102
98
  if (nodeId && nodeId.includes(':')) {
103
99
  // This is already in tech:fband format
104
- console.log('Adding tech:fband key (alternative format):', nodeId);
105
100
  selected.add(nodeId);
106
101
  }
107
102
  }
108
103
  }
109
- console.log('getFilteredRepeaters - selected tech:bands:', Array.from(selected));
110
104
  return selected;
111
105
  }