@smartnet360/svelte-components 0.0.118 → 0.0.120
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-pattern/components/AntennaDiagramsV2.svelte +412 -0
- package/dist/apps/antenna-pattern/components/AntennaDiagramsV2.svelte.d.ts +8 -0
- package/dist/apps/antenna-pattern/index.d.ts +3 -0
- package/dist/apps/antenna-pattern/index.js +4 -0
- package/dist/apps/antenna-pattern/types.d.ts +87 -0
- package/dist/apps/antenna-pattern/types.js +5 -0
- package/dist/apps/antenna-pattern/utils/antenna-helpers.d.ts +57 -0
- package/dist/apps/antenna-pattern/utils/antenna-helpers.js +140 -0
- package/dist/apps/antenna-tools/band-config.d.ts +53 -0
- package/dist/apps/antenna-tools/band-config.js +112 -0
- package/dist/apps/antenna-tools/components/AntennaControls.svelte +558 -0
- package/dist/apps/antenna-tools/components/AntennaControls.svelte.d.ts +16 -0
- package/dist/apps/antenna-tools/components/AntennaSettingsModal.svelte +304 -0
- package/dist/apps/antenna-tools/components/AntennaSettingsModal.svelte.d.ts +8 -0
- package/dist/apps/antenna-tools/components/AntennaTools.svelte +597 -0
- package/dist/apps/antenna-tools/components/AntennaTools.svelte.d.ts +42 -0
- package/dist/apps/antenna-tools/components/DatabaseViewer.svelte +278 -0
- package/dist/apps/antenna-tools/components/DatabaseViewer.svelte.d.ts +3 -0
- package/dist/apps/antenna-tools/components/DbNotification.svelte +67 -0
- package/dist/apps/antenna-tools/components/DbNotification.svelte.d.ts +18 -0
- package/dist/apps/antenna-tools/components/JsonImporter.svelte +115 -0
- package/dist/apps/antenna-tools/components/JsonImporter.svelte.d.ts +6 -0
- package/dist/apps/antenna-tools/components/MSIConverter.svelte +282 -0
- package/dist/apps/antenna-tools/components/MSIConverter.svelte.d.ts +6 -0
- package/dist/apps/antenna-tools/components/chart-engines/PolarAreaChart.svelte +123 -0
- package/dist/apps/antenna-tools/components/chart-engines/PolarAreaChart.svelte.d.ts +16 -0
- package/dist/apps/antenna-tools/components/chart-engines/PolarLineChart.svelte +123 -0
- package/dist/apps/antenna-tools/components/chart-engines/PolarLineChart.svelte.d.ts +16 -0
- package/dist/apps/antenna-tools/components/chart-engines/index.d.ts +9 -0
- package/dist/apps/antenna-tools/components/chart-engines/index.js +9 -0
- package/dist/apps/antenna-tools/components/index.d.ts +8 -0
- package/dist/apps/antenna-tools/components/index.js +10 -0
- package/dist/apps/antenna-tools/db.d.ts +28 -0
- package/dist/apps/antenna-tools/db.js +45 -0
- package/dist/apps/antenna-tools/index.d.ts +26 -0
- package/dist/apps/antenna-tools/index.js +40 -0
- package/dist/apps/antenna-tools/stores/antennas.d.ts +13 -0
- package/dist/apps/antenna-tools/stores/antennas.js +25 -0
- package/dist/apps/antenna-tools/stores/db-status.d.ts +32 -0
- package/dist/apps/antenna-tools/stores/db-status.js +38 -0
- package/dist/apps/antenna-tools/stores/index.d.ts +5 -0
- package/dist/apps/antenna-tools/stores/index.js +5 -0
- package/dist/apps/antenna-tools/types.d.ts +137 -0
- package/dist/apps/antenna-tools/types.js +16 -0
- package/dist/apps/antenna-tools/utils/antenna-helpers.d.ts +83 -0
- package/dist/apps/antenna-tools/utils/antenna-helpers.js +198 -0
- package/dist/apps/antenna-tools/utils/chart-engines/index.d.ts +5 -0
- package/dist/apps/antenna-tools/utils/chart-engines/index.js +5 -0
- package/dist/apps/antenna-tools/utils/chart-engines/polar-area-utils.d.ts +94 -0
- package/dist/apps/antenna-tools/utils/chart-engines/polar-area-utils.js +151 -0
- package/dist/apps/antenna-tools/utils/chart-engines/polar-line-utils.d.ts +93 -0
- package/dist/apps/antenna-tools/utils/chart-engines/polar-line-utils.js +139 -0
- package/dist/apps/antenna-tools/utils/db-utils.d.ts +50 -0
- package/dist/apps/antenna-tools/utils/db-utils.js +266 -0
- package/dist/apps/antenna-tools/utils/index.d.ts +7 -0
- package/dist/apps/antenna-tools/utils/index.js +7 -0
- package/dist/apps/antenna-tools/utils/msi-parser.d.ts +21 -0
- package/dist/apps/antenna-tools/utils/msi-parser.js +215 -0
- package/dist/apps/antenna-tools/utils/recent-antennas.d.ts +24 -0
- package/dist/apps/antenna-tools/utils/recent-antennas.js +64 -0
- package/package.json +1 -1
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Antenna Tools Module
|
|
3
|
+
*
|
|
4
|
+
* A comprehensive antenna pattern visualization and management module.
|
|
5
|
+
*
|
|
6
|
+
* Two operating modes:
|
|
7
|
+
* 1. External Data Mode: Parent provides antenna specs, selection hidden
|
|
8
|
+
* 2. Standalone Mode: User selects from database, full UI
|
|
9
|
+
*
|
|
10
|
+
* Features:
|
|
11
|
+
* - MSI/PNT file parsing
|
|
12
|
+
* - Automatic frequency band purging on import
|
|
13
|
+
* - Polar chart visualization (line & area)
|
|
14
|
+
* - Electrical and mechanical tilt adjustment
|
|
15
|
+
* - Single and compare view modes
|
|
16
|
+
* - IndexedDB persistence with Dexie
|
|
17
|
+
*/
|
|
18
|
+
export { default as AntennaTools } from './components/AntennaTools.svelte';
|
|
19
|
+
export { AntennaControls, AntennaSettingsModal, DatabaseViewer, DbNotification, JsonImporter, MSIConverter, } from './components/index';
|
|
20
|
+
export { PolarLineChart, PolarAreaChart } from './components/chart-engines/index';
|
|
21
|
+
export type { Antenna, RawAntenna, ExternalAntennaInput, BandDefinition, ViewMode, PatternType, ChartEngineType, PatternDisplayMode, AntennaSearchResult, } from './types';
|
|
22
|
+
export { STANDARD_BANDS } from './types';
|
|
23
|
+
export { db as antennaToolsDB } from './db';
|
|
24
|
+
export { antennas, selectedAntenna, searchQuery, filteredAntennas, dbStatus, dataOperationStatus, updateDbStatus, trackDataOperation, } from './stores/index';
|
|
25
|
+
export { loadAntennas, saveAntennasWithPurge, saveAntennas, importFromJson, exportAntennas, clearAllAntennas, hasImportedData, parseMSIFile, parseFolder, findAntennaByName, findAntennaBySpec, collectAvailableTilts, collectAvailableFrequencies, findTiltIndex, getTiltValue, findAntennaWithTilt, findAntennaExact, getUniqueAntennaModels, getUniqueAntennas, getRecentAntennas, addToRecentAntennas, clearRecentAntennas, sortAntennasWithRecent, } from './utils/index';
|
|
26
|
+
export { purgeAntennas, getBandCenterFrequency, findBandForFrequency, isFrequencyInStandardBand, calculatePurgeStats, type PurgeStats, } from './band-config';
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Antenna Tools Module
|
|
3
|
+
*
|
|
4
|
+
* A comprehensive antenna pattern visualization and management module.
|
|
5
|
+
*
|
|
6
|
+
* Two operating modes:
|
|
7
|
+
* 1. External Data Mode: Parent provides antenna specs, selection hidden
|
|
8
|
+
* 2. Standalone Mode: User selects from database, full UI
|
|
9
|
+
*
|
|
10
|
+
* Features:
|
|
11
|
+
* - MSI/PNT file parsing
|
|
12
|
+
* - Automatic frequency band purging on import
|
|
13
|
+
* - Polar chart visualization (line & area)
|
|
14
|
+
* - Electrical and mechanical tilt adjustment
|
|
15
|
+
* - Single and compare view modes
|
|
16
|
+
* - IndexedDB persistence with Dexie
|
|
17
|
+
*/
|
|
18
|
+
// === Main Component ===
|
|
19
|
+
export { default as AntennaTools } from './components/AntennaTools.svelte';
|
|
20
|
+
// === UI Components ===
|
|
21
|
+
export { AntennaControls, AntennaSettingsModal, DatabaseViewer, DbNotification, JsonImporter, MSIConverter, } from './components/index';
|
|
22
|
+
// === Chart Components ===
|
|
23
|
+
export { PolarLineChart, PolarAreaChart } from './components/chart-engines/index';
|
|
24
|
+
export { STANDARD_BANDS } from './types';
|
|
25
|
+
// === Database ===
|
|
26
|
+
export { db as antennaToolsDB } from './db';
|
|
27
|
+
// === Stores ===
|
|
28
|
+
export { antennas, selectedAntenna, searchQuery, filteredAntennas, dbStatus, dataOperationStatus, updateDbStatus, trackDataOperation, } from './stores/index';
|
|
29
|
+
// === Utilities ===
|
|
30
|
+
export {
|
|
31
|
+
// DB operations
|
|
32
|
+
loadAntennas, saveAntennasWithPurge, saveAntennas, importFromJson, exportAntennas, clearAllAntennas, hasImportedData,
|
|
33
|
+
// MSI parsing
|
|
34
|
+
parseMSIFile, parseFolder,
|
|
35
|
+
// Antenna helpers
|
|
36
|
+
findAntennaByName, findAntennaBySpec, collectAvailableTilts, collectAvailableFrequencies, findTiltIndex, getTiltValue, findAntennaWithTilt, findAntennaExact, getUniqueAntennaModels, getUniqueAntennas,
|
|
37
|
+
// Recent antennas
|
|
38
|
+
getRecentAntennas, addToRecentAntennas, clearRecentAntennas, sortAntennasWithRecent, } from './utils/index';
|
|
39
|
+
// === Band Configuration ===
|
|
40
|
+
export { purgeAntennas, getBandCenterFrequency, findBandForFrequency, isFrequencyInStandardBand, calculatePurgeStats, } from './band-config';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Antenna Tools - Stores
|
|
3
|
+
* Svelte stores for antenna data and UI state
|
|
4
|
+
*/
|
|
5
|
+
import type { Antenna } from '../types';
|
|
6
|
+
/** All loaded antennas */
|
|
7
|
+
export declare const antennas: import("svelte/store").Writable<Antenna[]>;
|
|
8
|
+
/** Currently selected antenna (for single mode) */
|
|
9
|
+
export declare const selectedAntenna: import("svelte/store").Writable<Antenna | null>;
|
|
10
|
+
/** Search query for filtering antennas */
|
|
11
|
+
export declare const searchQuery: import("svelte/store").Writable<string>;
|
|
12
|
+
/** Filtered antennas based on search query */
|
|
13
|
+
export declare const filteredAntennas: import("svelte/store").Readable<Antenna[]>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Antenna Tools - Stores
|
|
3
|
+
* Svelte stores for antenna data and UI state
|
|
4
|
+
*/
|
|
5
|
+
import { writable, derived } from 'svelte/store';
|
|
6
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
7
|
+
// ANTENNA DATA STORES
|
|
8
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
9
|
+
/** All loaded antennas */
|
|
10
|
+
export const antennas = writable([]);
|
|
11
|
+
/** Currently selected antenna (for single mode) */
|
|
12
|
+
export const selectedAntenna = writable(null);
|
|
13
|
+
/** Search query for filtering antennas */
|
|
14
|
+
export const searchQuery = writable('');
|
|
15
|
+
/** Filtered antennas based on search query */
|
|
16
|
+
export const filteredAntennas = derived([antennas, searchQuery], ([$antennas, $searchQuery]) => {
|
|
17
|
+
if (!$searchQuery)
|
|
18
|
+
return $antennas;
|
|
19
|
+
const query = $searchQuery.toLowerCase();
|
|
20
|
+
return $antennas.filter(antenna => antenna.name?.toLowerCase().includes(query) ||
|
|
21
|
+
antenna.frequency?.toString().includes(query) ||
|
|
22
|
+
antenna.tilt?.toString().includes(query) ||
|
|
23
|
+
antenna.comment?.toLowerCase().includes(query) ||
|
|
24
|
+
antenna.polarization?.toLowerCase().includes(query));
|
|
25
|
+
});
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Antenna Tools - Database Status Store
|
|
3
|
+
* Tracks database initialization and data operations
|
|
4
|
+
*/
|
|
5
|
+
export interface DbStatusState {
|
|
6
|
+
initialized: boolean;
|
|
7
|
+
antennaCount: number;
|
|
8
|
+
lastUpdated: Date | null;
|
|
9
|
+
loading: boolean;
|
|
10
|
+
error: string | null;
|
|
11
|
+
}
|
|
12
|
+
/** Database status store */
|
|
13
|
+
export declare const dbStatus: import("svelte/store").Writable<DbStatusState>;
|
|
14
|
+
/** Helper function to update database status */
|
|
15
|
+
export declare function updateDbStatus(status: Partial<DbStatusState>): void;
|
|
16
|
+
export interface DataOperationState {
|
|
17
|
+
operation: 'import' | 'export' | 'clear' | 'purge' | null;
|
|
18
|
+
inProgress: boolean;
|
|
19
|
+
success: boolean;
|
|
20
|
+
error: string | null;
|
|
21
|
+
message: string;
|
|
22
|
+
timestamp: Date | null;
|
|
23
|
+
}
|
|
24
|
+
/** Data operation status store */
|
|
25
|
+
export declare const dataOperationStatus: import("svelte/store").Writable<DataOperationState>;
|
|
26
|
+
/** Helper function to track data operations */
|
|
27
|
+
export declare function trackDataOperation(operation: 'import' | 'export' | 'clear' | 'purge', status: {
|
|
28
|
+
inProgress: boolean;
|
|
29
|
+
success?: boolean;
|
|
30
|
+
error?: string | null;
|
|
31
|
+
message?: string;
|
|
32
|
+
}): void;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Antenna Tools - Database Status Store
|
|
3
|
+
* Tracks database initialization and data operations
|
|
4
|
+
*/
|
|
5
|
+
import { writable } from 'svelte/store';
|
|
6
|
+
/** Database status store */
|
|
7
|
+
export const dbStatus = writable({
|
|
8
|
+
initialized: false,
|
|
9
|
+
antennaCount: 0,
|
|
10
|
+
lastUpdated: null,
|
|
11
|
+
loading: false,
|
|
12
|
+
error: null
|
|
13
|
+
});
|
|
14
|
+
/** Helper function to update database status */
|
|
15
|
+
export function updateDbStatus(status) {
|
|
16
|
+
dbStatus.update(current => ({ ...current, ...status }));
|
|
17
|
+
}
|
|
18
|
+
/** Data operation status store */
|
|
19
|
+
export const dataOperationStatus = writable({
|
|
20
|
+
operation: null,
|
|
21
|
+
inProgress: false,
|
|
22
|
+
success: false,
|
|
23
|
+
error: null,
|
|
24
|
+
message: '',
|
|
25
|
+
timestamp: null
|
|
26
|
+
});
|
|
27
|
+
/** Helper function to track data operations */
|
|
28
|
+
export function trackDataOperation(operation, status) {
|
|
29
|
+
dataOperationStatus.update(current => ({
|
|
30
|
+
...current,
|
|
31
|
+
operation,
|
|
32
|
+
inProgress: status.inProgress,
|
|
33
|
+
success: status.success !== undefined ? status.success : current.success,
|
|
34
|
+
error: status.error !== undefined ? status.error : current.error,
|
|
35
|
+
message: status.message || current.message,
|
|
36
|
+
timestamp: new Date()
|
|
37
|
+
}));
|
|
38
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Antenna Tools - Stores Index
|
|
3
|
+
*/
|
|
4
|
+
export { antennas, selectedAntenna, searchQuery, filteredAntennas } from './antennas';
|
|
5
|
+
export { dbStatus, dataOperationStatus, updateDbStatus, trackDataOperation, type DbStatusState, type DataOperationState } from './db-status';
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Antenna Tools - Type Definitions
|
|
3
|
+
* Clean, centralized type definitions for the antenna-tools module
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Frequency band definition for filtering antennas
|
|
7
|
+
*/
|
|
8
|
+
export interface BandDefinition {
|
|
9
|
+
/** Simple band name: "700", "800", "900", "1800", "2100", "2600" */
|
|
10
|
+
name: string;
|
|
11
|
+
/** Downlink minimum frequency (MHz) */
|
|
12
|
+
dlMin: number;
|
|
13
|
+
/** Downlink maximum frequency (MHz) */
|
|
14
|
+
dlMax: number;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Standard frequency bands - fixed preset
|
|
18
|
+
* Only downlink frequencies are considered
|
|
19
|
+
*/
|
|
20
|
+
export declare const STANDARD_BANDS: BandDefinition[];
|
|
21
|
+
/**
|
|
22
|
+
* Antenna record stored in the database
|
|
23
|
+
* After purge: frequency = band name (700, 800, etc.), originalFrequency = actual MHz
|
|
24
|
+
*/
|
|
25
|
+
export interface Antenna {
|
|
26
|
+
/** Database ID (auto-generated) */
|
|
27
|
+
id?: number;
|
|
28
|
+
/** Antenna model name (e.g., "ADU4515R17v06") */
|
|
29
|
+
name: string;
|
|
30
|
+
/** Band name as number: 700, 800, 900, 1800, 2100, 2600 */
|
|
31
|
+
frequency: number;
|
|
32
|
+
/** Original frequency from MSI file in MHz (e.g., 763, 796) */
|
|
33
|
+
originalFrequency: number;
|
|
34
|
+
/** Antenna gain in dBd */
|
|
35
|
+
gain_dBd: number;
|
|
36
|
+
/** Electrical tilt value as string (e.g., "3", "4", "5") */
|
|
37
|
+
tilt: string;
|
|
38
|
+
/** Comment from MSI file */
|
|
39
|
+
comment?: string;
|
|
40
|
+
/** Number of horizontal pattern points (typically 360) */
|
|
41
|
+
horizontal: number;
|
|
42
|
+
/** Horizontal radiation pattern - 360 attenuation values */
|
|
43
|
+
pattern: number[];
|
|
44
|
+
/** Vertical radiation pattern - 360 attenuation values */
|
|
45
|
+
vertical_pattern: number[];
|
|
46
|
+
/** Polarization (e.g., "-45") */
|
|
47
|
+
polarization?: string;
|
|
48
|
+
/** Cross-polarization indicator */
|
|
49
|
+
x_pol?: string;
|
|
50
|
+
/** Co-polar indicator */
|
|
51
|
+
co?: string;
|
|
52
|
+
/** Tilt extracted from filename */
|
|
53
|
+
tilt_from_filename?: string;
|
|
54
|
+
/** Source file path */
|
|
55
|
+
sourcePath?: string;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Raw antenna data from MSI parsing (before purge)
|
|
59
|
+
* frequency = actual MHz value from file
|
|
60
|
+
*/
|
|
61
|
+
export interface RawAntenna {
|
|
62
|
+
id?: number;
|
|
63
|
+
name: string;
|
|
64
|
+
/** Actual frequency in MHz from MSI file */
|
|
65
|
+
frequency: number;
|
|
66
|
+
gain_dBd: number;
|
|
67
|
+
tilt: string;
|
|
68
|
+
comment?: string;
|
|
69
|
+
horizontal: number;
|
|
70
|
+
pattern: number[];
|
|
71
|
+
vertical_pattern: number[];
|
|
72
|
+
polarization?: string;
|
|
73
|
+
x_pol?: string;
|
|
74
|
+
co?: string;
|
|
75
|
+
tilt_from_filename?: string;
|
|
76
|
+
sourcePath?: string;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Input for external mode - when antenna data is provided by parent component
|
|
80
|
+
*/
|
|
81
|
+
export interface ExternalAntennaInput {
|
|
82
|
+
/** Antenna model name */
|
|
83
|
+
name: string;
|
|
84
|
+
/** Frequency band (700, 800, 900, 1800, 2100, 2600) */
|
|
85
|
+
frequency: number;
|
|
86
|
+
/** Electrical tilt in degrees */
|
|
87
|
+
electricalTilt: number;
|
|
88
|
+
/** Mechanical tilt in degrees */
|
|
89
|
+
mechanicalTilt: number;
|
|
90
|
+
/** Optional display label (e.g., "Cell A1", "Sector 2") */
|
|
91
|
+
label?: string;
|
|
92
|
+
}
|
|
93
|
+
/** View mode for antenna diagrams */
|
|
94
|
+
export type ViewMode = 'single' | 'compare';
|
|
95
|
+
/** Pattern type for radiation display */
|
|
96
|
+
export type PatternType = 'horizontal' | 'vertical';
|
|
97
|
+
/** Display mode for pattern visualization */
|
|
98
|
+
export type PatternDisplayMode = 'normalized' | 'gain-adjusted';
|
|
99
|
+
/** Chart engine type (polar-bar removed) */
|
|
100
|
+
export type ChartEngineType = 'polar-line' | 'polar-area';
|
|
101
|
+
/** Color theme for antenna controls */
|
|
102
|
+
export type ColorTheme = 'primary' | 'warning' | 'success' | 'info' | 'secondary';
|
|
103
|
+
/**
|
|
104
|
+
* Antenna selection state - tracks antenna, tilts, and available options
|
|
105
|
+
*/
|
|
106
|
+
export interface AntennaSelection {
|
|
107
|
+
/** The selected antenna record */
|
|
108
|
+
antenna: Antenna | null;
|
|
109
|
+
/** Index into availableTilts array for electrical tilt */
|
|
110
|
+
electricalTiltIndex: number;
|
|
111
|
+
/** Mechanical tilt value in degrees */
|
|
112
|
+
mechanicalTilt: number;
|
|
113
|
+
/** Available electrical tilt values for this antenna model */
|
|
114
|
+
availableTilts: string[];
|
|
115
|
+
/** Available frequencies (bands) for this antenna model */
|
|
116
|
+
availableFrequencies: number[];
|
|
117
|
+
/** Custom label for display (e.g., cell name) */
|
|
118
|
+
label?: string;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Result of finding an antenna by name
|
|
122
|
+
*/
|
|
123
|
+
export interface AntennaSearchResult {
|
|
124
|
+
antenna: Antenna | null;
|
|
125
|
+
matchType: 'exact' | 'case-insensitive' | 'partial' | 'not-found';
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Props for initializing AntennaTools from external sources
|
|
129
|
+
*/
|
|
130
|
+
export interface AntennaToolsInit {
|
|
131
|
+
/** Antenna 1 specification (external mode) */
|
|
132
|
+
antenna1?: ExternalAntennaInput;
|
|
133
|
+
/** Antenna 2 specification (external mode) */
|
|
134
|
+
antenna2?: ExternalAntennaInput;
|
|
135
|
+
/** Initial view mode */
|
|
136
|
+
viewMode?: ViewMode;
|
|
137
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Antenna Tools - Type Definitions
|
|
3
|
+
* Clean, centralized type definitions for the antenna-tools module
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Standard frequency bands - fixed preset
|
|
7
|
+
* Only downlink frequencies are considered
|
|
8
|
+
*/
|
|
9
|
+
export const STANDARD_BANDS = [
|
|
10
|
+
{ name: '700', dlMin: 758, dlMax: 768 }, // LTE B28
|
|
11
|
+
{ name: '800', dlMin: 791, dlMax: 801 }, // LTE B20
|
|
12
|
+
{ name: '900', dlMin: 935, dlMax: 960 }, // GSM 900
|
|
13
|
+
{ name: '1800', dlMin: 1805, dlMax: 1880 }, // GSM 1800 / LTE B3
|
|
14
|
+
{ name: '2100', dlMin: 2110, dlMax: 2170 }, // LTE B1
|
|
15
|
+
{ name: '2600', dlMin: 2620, dlMax: 2690 }, // LTE B7
|
|
16
|
+
];
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Antenna Tools - Antenna Helpers
|
|
3
|
+
* Utility functions for working with antenna data, tilts, and searches
|
|
4
|
+
*/
|
|
5
|
+
import type { Antenna, AntennaSearchResult, ExternalAntennaInput } from '../types';
|
|
6
|
+
/**
|
|
7
|
+
* Find an antenna by name with fallback matching strategies
|
|
8
|
+
* @param antennas - Array of all antennas
|
|
9
|
+
* @param name - Name pattern to search for
|
|
10
|
+
* @returns Search result with antenna and match type
|
|
11
|
+
*/
|
|
12
|
+
export declare function findAntennaByName(antennas: Antenna[], name: string): AntennaSearchResult;
|
|
13
|
+
/**
|
|
14
|
+
* Find antenna by external specification (name, frequency, tilt)
|
|
15
|
+
* Used for external mode when parent provides antenna specs
|
|
16
|
+
* @param antennas - Array of all antennas
|
|
17
|
+
* @param spec - External antenna specification
|
|
18
|
+
* @returns Matching antenna or null
|
|
19
|
+
*/
|
|
20
|
+
export declare function findAntennaBySpec(antennas: Antenna[], spec: Partial<ExternalAntennaInput> & {
|
|
21
|
+
name: string;
|
|
22
|
+
}): Antenna | null;
|
|
23
|
+
/**
|
|
24
|
+
* Collect all available electrical tilts for an antenna model
|
|
25
|
+
* Searches all antennas with the same name and extracts unique tilt values
|
|
26
|
+
* @param antennas - Array of all antennas
|
|
27
|
+
* @param antennaName - The antenna model name
|
|
28
|
+
* @param frequency - Optional frequency (band) to filter by
|
|
29
|
+
* @returns Sorted array of tilt values as strings
|
|
30
|
+
*/
|
|
31
|
+
export declare function collectAvailableTilts(antennas: Antenna[], antennaName: string, frequency?: number | null): string[];
|
|
32
|
+
/**
|
|
33
|
+
* Collect all available frequencies (bands) for an antenna model
|
|
34
|
+
* @param antennas - Array of all antennas
|
|
35
|
+
* @param antennaName - The antenna model name
|
|
36
|
+
* @returns Sorted array of unique frequency bands (700, 800, 900, etc.)
|
|
37
|
+
*/
|
|
38
|
+
export declare function collectAvailableFrequencies(antennas: Antenna[], antennaName: string): number[];
|
|
39
|
+
/**
|
|
40
|
+
* Find the index of a tilt value in the available tilts array
|
|
41
|
+
* @param availableTilts - Array of available tilt values
|
|
42
|
+
* @param tiltValue - The tilt value to find (as number)
|
|
43
|
+
* @returns Index in the array, or 0 if not found
|
|
44
|
+
*/
|
|
45
|
+
export declare function findTiltIndex(availableTilts: string[], tiltValue: number): number;
|
|
46
|
+
/**
|
|
47
|
+
* Get the tilt value at a given index
|
|
48
|
+
* @param availableTilts - Array of available tilt values
|
|
49
|
+
* @param index - Index to retrieve
|
|
50
|
+
* @returns Tilt value as number
|
|
51
|
+
*/
|
|
52
|
+
export declare function getTiltValue(availableTilts: string[], index: number): number;
|
|
53
|
+
/**
|
|
54
|
+
* Find an antenna with specific name, frequency (band), and tilt
|
|
55
|
+
* @param antennas - Array of all antennas
|
|
56
|
+
* @param name - Antenna model name
|
|
57
|
+
* @param frequency - Target frequency band (700, 800, etc.) - optional
|
|
58
|
+
* @param tiltValue - Target tilt value as string
|
|
59
|
+
* @returns Matching antenna or null
|
|
60
|
+
*/
|
|
61
|
+
export declare function findAntennaWithTilt(antennas: Antenna[], name: string, frequency: number | null, tiltValue: string): Antenna | null;
|
|
62
|
+
/**
|
|
63
|
+
* Find antenna by exact match on name, frequency band, and electrical tilt
|
|
64
|
+
* Used for external mode lookup
|
|
65
|
+
* @param antennas - Array of all antennas
|
|
66
|
+
* @param name - Antenna model name
|
|
67
|
+
* @param frequency - Frequency band (700, 800, etc.)
|
|
68
|
+
* @param electricalTilt - Electrical tilt value
|
|
69
|
+
* @returns Matching antenna or null
|
|
70
|
+
*/
|
|
71
|
+
export declare function findAntennaExact(antennas: Antenna[], name: string, frequency: number, electricalTilt: number): Antenna | null;
|
|
72
|
+
/**
|
|
73
|
+
* Get unique antenna models (by name)
|
|
74
|
+
* @param antennas - Array of all antennas
|
|
75
|
+
* @returns Array of unique antenna names
|
|
76
|
+
*/
|
|
77
|
+
export declare function getUniqueAntennaModels(antennas: Antenna[]): string[];
|
|
78
|
+
/**
|
|
79
|
+
* Get a sample antenna for each unique model (for dropdown display)
|
|
80
|
+
* @param antennas - Array of all antennas
|
|
81
|
+
* @returns Array of unique antennas (one per model name)
|
|
82
|
+
*/
|
|
83
|
+
export declare function getUniqueAntennas(antennas: Antenna[]): Antenna[];
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Antenna Tools - Antenna Helpers
|
|
3
|
+
* Utility functions for working with antenna data, tilts, and searches
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Find an antenna by name with fallback matching strategies
|
|
7
|
+
* @param antennas - Array of all antennas
|
|
8
|
+
* @param name - Name pattern to search for
|
|
9
|
+
* @returns Search result with antenna and match type
|
|
10
|
+
*/
|
|
11
|
+
export function findAntennaByName(antennas, name) {
|
|
12
|
+
if (!name || antennas.length === 0) {
|
|
13
|
+
return { antenna: null, matchType: 'not-found' };
|
|
14
|
+
}
|
|
15
|
+
// Strategy 1: Exact match
|
|
16
|
+
let found = antennas.find(a => a.name === name);
|
|
17
|
+
if (found) {
|
|
18
|
+
return { antenna: found, matchType: 'exact' };
|
|
19
|
+
}
|
|
20
|
+
// Strategy 2: Case-insensitive match
|
|
21
|
+
const lowerName = name.toLowerCase();
|
|
22
|
+
found = antennas.find(a => a.name.toLowerCase() === lowerName);
|
|
23
|
+
if (found) {
|
|
24
|
+
return { antenna: found, matchType: 'case-insensitive' };
|
|
25
|
+
}
|
|
26
|
+
// Strategy 3: Partial match (name contains search term)
|
|
27
|
+
found = antennas.find(a => a.name.toLowerCase().includes(lowerName));
|
|
28
|
+
if (found) {
|
|
29
|
+
return { antenna: found, matchType: 'partial' };
|
|
30
|
+
}
|
|
31
|
+
return { antenna: null, matchType: 'not-found' };
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Find antenna by external specification (name, frequency, tilt)
|
|
35
|
+
* Used for external mode when parent provides antenna specs
|
|
36
|
+
* @param antennas - Array of all antennas
|
|
37
|
+
* @param spec - External antenna specification
|
|
38
|
+
* @returns Matching antenna or null
|
|
39
|
+
*/
|
|
40
|
+
export function findAntennaBySpec(antennas, spec) {
|
|
41
|
+
if (!spec.name || antennas.length === 0) {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
// Strategy 1: Exact match with all criteria
|
|
45
|
+
if (spec.frequency !== undefined && spec.electricalTilt !== undefined) {
|
|
46
|
+
const exact = antennas.find(a => a.name === spec.name &&
|
|
47
|
+
a.frequency === spec.frequency &&
|
|
48
|
+
a.tilt === String(spec.electricalTilt));
|
|
49
|
+
if (exact)
|
|
50
|
+
return exact;
|
|
51
|
+
}
|
|
52
|
+
// Strategy 2: Match name and frequency (any tilt)
|
|
53
|
+
if (spec.frequency !== undefined) {
|
|
54
|
+
const byFreq = antennas.find(a => a.name === spec.name &&
|
|
55
|
+
a.frequency === spec.frequency);
|
|
56
|
+
if (byFreq)
|
|
57
|
+
return byFreq;
|
|
58
|
+
}
|
|
59
|
+
// Strategy 3: Match by name only with fallback strategies
|
|
60
|
+
const { antenna } = findAntennaByName(antennas, spec.name);
|
|
61
|
+
return antenna;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Collect all available electrical tilts for an antenna model
|
|
65
|
+
* Searches all antennas with the same name and extracts unique tilt values
|
|
66
|
+
* @param antennas - Array of all antennas
|
|
67
|
+
* @param antennaName - The antenna model name
|
|
68
|
+
* @param frequency - Optional frequency (band) to filter by
|
|
69
|
+
* @returns Sorted array of tilt values as strings
|
|
70
|
+
*/
|
|
71
|
+
export function collectAvailableTilts(antennas, antennaName, frequency) {
|
|
72
|
+
if (!antennaName)
|
|
73
|
+
return ['0'];
|
|
74
|
+
// Find all antennas with the same name
|
|
75
|
+
let sameModel = antennas.filter(a => a.name === antennaName);
|
|
76
|
+
// Optionally filter by frequency (band)
|
|
77
|
+
if (frequency) {
|
|
78
|
+
sameModel = sameModel.filter(a => a.frequency === frequency);
|
|
79
|
+
}
|
|
80
|
+
// Collect all unique tilts
|
|
81
|
+
const allTilts = new Set();
|
|
82
|
+
for (const antenna of sameModel) {
|
|
83
|
+
if (antenna.tilt) {
|
|
84
|
+
const tiltStr = antenna.tilt.toString();
|
|
85
|
+
if (tiltStr.includes(',')) {
|
|
86
|
+
tiltStr.split(',').forEach(t => allTilts.add(t.trim()));
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
allTilts.add(tiltStr.trim());
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// Return sorted array (numerically)
|
|
94
|
+
const sorted = Array.from(allTilts).sort((a, b) => parseFloat(a) - parseFloat(b));
|
|
95
|
+
return sorted.length > 0 ? sorted : ['0'];
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Collect all available frequencies (bands) for an antenna model
|
|
99
|
+
* @param antennas - Array of all antennas
|
|
100
|
+
* @param antennaName - The antenna model name
|
|
101
|
+
* @returns Sorted array of unique frequency bands (700, 800, 900, etc.)
|
|
102
|
+
*/
|
|
103
|
+
export function collectAvailableFrequencies(antennas, antennaName) {
|
|
104
|
+
if (!antennaName)
|
|
105
|
+
return [];
|
|
106
|
+
const sameModel = antennas.filter(a => a.name === antennaName);
|
|
107
|
+
const frequencies = new Set();
|
|
108
|
+
for (const antenna of sameModel) {
|
|
109
|
+
if (antenna.frequency) {
|
|
110
|
+
frequencies.add(antenna.frequency);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return Array.from(frequencies).sort((a, b) => a - b);
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Find the index of a tilt value in the available tilts array
|
|
117
|
+
* @param availableTilts - Array of available tilt values
|
|
118
|
+
* @param tiltValue - The tilt value to find (as number)
|
|
119
|
+
* @returns Index in the array, or 0 if not found
|
|
120
|
+
*/
|
|
121
|
+
export function findTiltIndex(availableTilts, tiltValue) {
|
|
122
|
+
const index = availableTilts.findIndex(t => parseInt(t, 10) === tiltValue);
|
|
123
|
+
return index >= 0 ? index : 0;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Get the tilt value at a given index
|
|
127
|
+
* @param availableTilts - Array of available tilt values
|
|
128
|
+
* @param index - Index to retrieve
|
|
129
|
+
* @returns Tilt value as number
|
|
130
|
+
*/
|
|
131
|
+
export function getTiltValue(availableTilts, index) {
|
|
132
|
+
const tilt = availableTilts[index];
|
|
133
|
+
return tilt ? parseInt(tilt, 10) : 0;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Find an antenna with specific name, frequency (band), and tilt
|
|
137
|
+
* @param antennas - Array of all antennas
|
|
138
|
+
* @param name - Antenna model name
|
|
139
|
+
* @param frequency - Target frequency band (700, 800, etc.) - optional
|
|
140
|
+
* @param tiltValue - Target tilt value as string
|
|
141
|
+
* @returns Matching antenna or null
|
|
142
|
+
*/
|
|
143
|
+
export function findAntennaWithTilt(antennas, name, frequency, tiltValue) {
|
|
144
|
+
return antennas.find(antenna => {
|
|
145
|
+
if (antenna.name !== name)
|
|
146
|
+
return false;
|
|
147
|
+
if (frequency && antenna.frequency !== frequency)
|
|
148
|
+
return false;
|
|
149
|
+
if (antenna.tilt) {
|
|
150
|
+
const tiltStr = antenna.tilt.toString();
|
|
151
|
+
const antennaTilts = tiltStr.includes(',')
|
|
152
|
+
? tiltStr.split(',').map(t => t.trim())
|
|
153
|
+
: [tiltStr.trim()];
|
|
154
|
+
return antennaTilts.includes(tiltValue);
|
|
155
|
+
}
|
|
156
|
+
return tiltValue === '0';
|
|
157
|
+
}) || null;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Find antenna by exact match on name, frequency band, and electrical tilt
|
|
161
|
+
* Used for external mode lookup
|
|
162
|
+
* @param antennas - Array of all antennas
|
|
163
|
+
* @param name - Antenna model name
|
|
164
|
+
* @param frequency - Frequency band (700, 800, etc.)
|
|
165
|
+
* @param electricalTilt - Electrical tilt value
|
|
166
|
+
* @returns Matching antenna or null
|
|
167
|
+
*/
|
|
168
|
+
export function findAntennaExact(antennas, name, frequency, electricalTilt) {
|
|
169
|
+
return antennas.find(a => a.name === name &&
|
|
170
|
+
a.frequency === frequency &&
|
|
171
|
+
a.tilt === String(electricalTilt)) || null;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Get unique antenna models (by name)
|
|
175
|
+
* @param antennas - Array of all antennas
|
|
176
|
+
* @returns Array of unique antenna names
|
|
177
|
+
*/
|
|
178
|
+
export function getUniqueAntennaModels(antennas) {
|
|
179
|
+
const names = new Set();
|
|
180
|
+
for (const antenna of antennas) {
|
|
181
|
+
names.add(antenna.name);
|
|
182
|
+
}
|
|
183
|
+
return Array.from(names).sort();
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Get a sample antenna for each unique model (for dropdown display)
|
|
187
|
+
* @param antennas - Array of all antennas
|
|
188
|
+
* @returns Array of unique antennas (one per model name)
|
|
189
|
+
*/
|
|
190
|
+
export function getUniqueAntennas(antennas) {
|
|
191
|
+
const seen = new Map();
|
|
192
|
+
for (const antenna of antennas) {
|
|
193
|
+
if (!seen.has(antenna.name)) {
|
|
194
|
+
seen.set(antenna.name, antenna);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return Array.from(seen.values()).sort((a, b) => a.name.localeCompare(b.name));
|
|
198
|
+
}
|