@jjlmoya/utils-drones 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -31,35 +31,22 @@ const { ui } = Astro.props;
31
31
  </div>
32
32
  </div>
33
33
 
34
- <script is:inline lang="ts">
35
- interface GMSObject {
36
- g: number;
37
- m: number;
38
- s: number;
39
- h: string;
40
- mDec: number;
41
- }
42
-
43
- interface HistoryItem {
44
- id: number;
45
- lat: string;
46
- lng: string;
47
- time: string;
48
- }
49
-
50
- let mode: string = 'DD';
51
-
52
- const elements: Record<string, HTMLElement | null> = {
53
- latDD: document.getElementById('latDD') as HTMLInputElement,
54
- lngDD: document.getElementById('lngDD') as HTMLInputElement,
55
- latG: document.getElementById('latG') as HTMLInputElement,
56
- latM: document.getElementById('latM') as HTMLInputElement,
57
- latS: document.getElementById('latS') as HTMLInputElement,
58
- latH: document.getElementById('latH') as HTMLSelectElement,
59
- lngG: document.getElementById('lngG') as HTMLInputElement,
60
- lngM: document.getElementById('lngM') as HTMLInputElement,
61
- lngS: document.getElementById('lngS') as HTMLInputElement,
62
- lngH: document.getElementById('lngH') as HTMLSelectElement,
34
+ <script>
35
+ let mode = 'DD';
36
+ let mapInstance = null;
37
+ let L = null;
38
+
39
+ const elements = {
40
+ latDD: document.getElementById('latDD'),
41
+ lngDD: document.getElementById('lngDD'),
42
+ latG: document.getElementById('latG'),
43
+ latM: document.getElementById('latM'),
44
+ latS: document.getElementById('latS'),
45
+ latH: document.getElementById('latH'),
46
+ lngG: document.getElementById('lngG'),
47
+ lngM: document.getElementById('lngM'),
48
+ lngS: document.getElementById('lngS'),
49
+ lngH: document.getElementById('lngH'),
63
50
  valDD: document.getElementById('valDD'),
64
51
  valGMS: document.getElementById('valGMS'),
65
52
  valDM: document.getElementById('valDM'),
@@ -71,7 +58,7 @@ const { ui } = Astro.props;
71
58
  gmsInputs: document.getElementById('gms-inputs'),
72
59
  btnMyLocation: document.getElementById('btnMyLocation'),
73
60
  };
74
- const container: HTMLElement | null = document.querySelector('.gps-converter-ui');
61
+ const container = document.querySelector('.gps-converter-ui');
75
62
  const uiLocal = {
76
63
  copied: container?.dataset.uiCopied || 'Copied',
77
64
  noHistory: container?.dataset.uiNoHistory || 'No history',
@@ -79,28 +66,41 @@ const { ui } = Astro.props;
79
66
  delete: container?.dataset.uiDelete || 'Delete'
80
67
  };
81
68
 
82
- function init(): void {
83
- initMap();
84
- setupListeners();
85
- loadHistory();
86
- updateFromDD(40.4168, -3.7038);
69
+ function init() {
70
+ import('leaflet').then(module => {
71
+ L = module.default;
72
+ initMap();
73
+ setupListeners();
74
+ loadHistory();
75
+ updateFromDD(40.4168, -3.7038);
76
+ });
87
77
  }
88
78
 
89
- function initMap(): void {
79
+ function initMap() {
90
80
  const mapContainer = document.getElementById('gpsMap');
91
81
  if (!mapContainer) return;
82
+
83
+ mapInstance = L.map('gpsMap').setView([40.4168, -3.7038], 13);
84
+ L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
85
+ attribution: '© OpenStreetMap contributors',
86
+ maxZoom: 19
87
+ }).addTo(mapInstance);
88
+
89
+ mapInstance.on('click', (e) => {
90
+ updateFromDD(e.latlng.lat, e.latlng.lng);
91
+ });
92
92
  }
93
93
 
94
- function parseCoordValue(val: string): number {
94
+ function parseCoordValue(val) {
95
95
  return parseFloat(val.replace(',', '.'));
96
96
  }
97
97
 
98
- function setupModeListeners(): void {
98
+ function setupModeListeners() {
99
99
  elements.modeDD?.addEventListener('click', () => switchMode('DD'));
100
100
  elements.modeGMS?.addEventListener('click', () => switchMode('GMS'));
101
101
  }
102
102
 
103
- function setupLocationListener(): void {
103
+ function setupLocationListener() {
104
104
  elements.btnMyLocation?.addEventListener('click', () => {
105
105
  if ("geolocation" in navigator) {
106
106
  navigator.geolocation.getCurrentPosition((position) => {
@@ -110,7 +110,7 @@ const { ui } = Astro.props;
110
110
  });
111
111
  }
112
112
 
113
- function setupDDInputListeners(): void {
113
+ function setupDDInputListeners() {
114
114
  [elements.latDD, elements.lngDD].forEach(el => {
115
115
  el?.addEventListener('input', () => {
116
116
  if (mode === 'DD') {
@@ -122,7 +122,7 @@ const { ui } = Astro.props;
122
122
  });
123
123
  }
124
124
 
125
- function setupGMSInputListeners(): void {
125
+ function setupGMSInputListeners() {
126
126
  const gmsElements = [elements.latG, elements.latM, elements.latS, elements.latH,
127
127
  elements.lngG, elements.lngM, elements.lngS, elements.lngH];
128
128
  gmsElements.forEach(el => {
@@ -146,11 +146,11 @@ const { ui } = Astro.props;
146
146
  });
147
147
  }
148
148
 
149
- function setupCopyListeners(): void {
149
+ function setupCopyListeners() {
150
150
  document.querySelectorAll('.copy-btn').forEach(btn => {
151
151
  btn.addEventListener('click', () => {
152
152
  const targetId = btn.getAttribute('data-copy');
153
- const text = document.getElementById(targetId!)?.textContent;
153
+ const text = document.getElementById(targetId)?.textContent;
154
154
  if (text) {
155
155
  navigator.clipboard.writeText(text);
156
156
  const original = btn.innerHTML;
@@ -161,14 +161,14 @@ const { ui } = Astro.props;
161
161
  });
162
162
  }
163
163
 
164
- function setupClearHistoryListener(): void {
164
+ function setupClearHistoryListener() {
165
165
  document.getElementById('clearHistory')?.addEventListener('click', () => {
166
166
  localStorage.removeItem('gps_history');
167
167
  loadHistory();
168
168
  });
169
169
  }
170
170
 
171
- function setupListeners(): void {
171
+ function setupListeners() {
172
172
  setupModeListeners();
173
173
  setupLocationListener();
174
174
  setupDDInputListeners();
@@ -177,7 +177,7 @@ const { ui } = Astro.props;
177
177
  setupClearHistoryListener();
178
178
  }
179
179
 
180
- function setSwitchModeDisplay(isDD: boolean): void {
180
+ function setSwitchModeDisplay(isDD) {
181
181
  if (isDD) {
182
182
  if (elements.ddInputs) elements.ddInputs.style.display = 'grid';
183
183
  if (elements.gmsInputs) elements.gmsInputs.style.display = 'none';
@@ -187,7 +187,7 @@ const { ui } = Astro.props;
187
187
  }
188
188
  }
189
189
 
190
- function setSwitchModeActive(isDD: boolean): void {
190
+ function setSwitchModeActive(isDD) {
191
191
  if (isDD) {
192
192
  elements.modeDD?.classList.add('active');
193
193
  elements.modeGMS?.classList.remove('active');
@@ -197,14 +197,14 @@ const { ui } = Astro.props;
197
197
  }
198
198
  }
199
199
 
200
- function switchMode(newMode: string): void {
200
+ function switchMode(newMode) {
201
201
  mode = newMode;
202
202
  const isDD = mode === 'DD';
203
203
  setSwitchModeActive(isDD);
204
204
  setSwitchModeDisplay(isDD);
205
205
  }
206
206
 
207
- function updateGMSInputs(lat: number, lng: number): void {
207
+ function updateGMSInputs(lat, lng) {
208
208
  const latGMS = decimalToGMS(lat, true);
209
209
  const lngGMS = decimalToGMS(lng, false);
210
210
  elements.latG.value = latGMS.g.toString();
@@ -217,7 +217,7 @@ const { ui } = Astro.props;
217
217
  elements.lngH.value = lngGMS.h;
218
218
  }
219
219
 
220
- function updateResultsDisplay(lat: number, lng: number): void {
220
+ function updateResultsDisplay(lat, lng) {
221
221
  const latGMS = decimalToGMS(lat, true);
222
222
  const lngGMS = decimalToGMS(lng, false);
223
223
  if (elements.valDD) elements.valDD.textContent = `${lat.toFixed(6)}, ${lng.toFixed(6)}`;
@@ -226,7 +226,7 @@ const { ui } = Astro.props;
226
226
  if (elements.valMaps) elements.valMaps.textContent = `${lat.toFixed(6)},${lng.toFixed(6)}`;
227
227
  }
228
228
 
229
- function updateFromDD(lat: number, lng: number, updateInputs: boolean = true): void {
229
+ function updateFromDD(lat, lng, updateInputs = true) {
230
230
  if (isNaN(lat) || isNaN(lng)) return;
231
231
 
232
232
  if (updateInputs) {
@@ -241,12 +241,12 @@ const { ui } = Astro.props;
241
241
  saveToHistory(lat, lng);
242
242
  }
243
243
 
244
- function getHemisphere(value: number, isLat: boolean): string {
244
+ function getHemisphere(value, isLat) {
245
245
  if (value >= 0) return isLat ? 'N' : 'E';
246
246
  return isLat ? 'S' : 'W';
247
247
  }
248
248
 
249
- function decimalToGMS(d: number, isLat: boolean): GMSObject {
249
+ function decimalToGMS(d, isLat) {
250
250
  const h = getHemisphere(d, isLat);
251
251
  const absD = Math.abs(d);
252
252
  const g = Math.floor(absD);
@@ -256,23 +256,23 @@ const { ui } = Astro.props;
256
256
  return { g, m, s, h, mDec: mDecimal };
257
257
  }
258
258
 
259
- function gmsToDecimal(g: number, m: number, s: number, h: string): number {
259
+ function gmsToDecimal(g, m, s, h) {
260
260
  let d = g + (m / 60) + (s / 3600);
261
261
  if (h === 'S' || h === 'W') d = -d;
262
262
  return d;
263
263
  }
264
264
 
265
- function formatGMS(obj: GMSObject): string {
265
+ function formatGMS(obj) {
266
266
  return `${obj.g}° ${obj.m}' ${obj.s.toFixed(2)}" ${obj.h}`;
267
267
  }
268
268
 
269
- function formatDM(obj: GMSObject): string {
269
+ function formatDM(obj) {
270
270
  return `${obj.g}° ${obj.mDec.toFixed(3)}' ${obj.h}`;
271
271
  }
272
272
 
273
- function saveToHistory(lat: number, lng: number): void {
274
- let history: HistoryItem[] = JSON.parse(localStorage.getItem('gps_history') || '[]');
275
- const entry: HistoryItem = {
273
+ function saveToHistory(lat, lng) {
274
+ let history = JSON.parse(localStorage.getItem('gps_history') || '[]');
275
+ const entry = {
276
276
  id: Date.now(),
277
277
  lat: lat.toFixed(5),
278
278
  lng: lng.toFixed(5),
@@ -287,12 +287,12 @@ const { ui } = Astro.props;
287
287
  renderHistory(history);
288
288
  }
289
289
 
290
- function loadHistory(): void {
291
- const history: HistoryItem[] = JSON.parse(localStorage.getItem('gps_history') || '[]');
290
+ function loadHistory() {
291
+ const history = JSON.parse(localStorage.getItem('gps_history') || '[]');
292
292
  renderHistory(history);
293
293
  }
294
294
 
295
- function renderHistoryHTML(history: HistoryItem[]): string {
295
+ function renderHistoryHTML(history) {
296
296
  return history.map(item => `
297
297
  <div class="history-item" data-id="${item.id}">
298
298
  <div class="hist-info" data-lat="${item.lat}" data-lng="${item.lng}">
@@ -311,7 +311,7 @@ const { ui } = Astro.props;
311
311
  `).join('');
312
312
  }
313
313
 
314
- function setupHistoryEventListeners(): void {
314
+ function setupHistoryEventListeners() {
315
315
  document.querySelectorAll('.load-btn').forEach(btn => {
316
316
  btn.addEventListener('click', (e) => {
317
317
  e.stopPropagation();
@@ -325,7 +325,7 @@ const { ui } = Astro.props;
325
325
  btn.addEventListener('click', (e) => {
326
326
  e.stopPropagation();
327
327
  const id = parseInt(btn.getAttribute('data-id')!);
328
- let history: HistoryItem[] = JSON.parse(localStorage.getItem('gps_history') || '[]');
328
+ let history = JSON.parse(localStorage.getItem('gps_history') || '[]');
329
329
  history = history.filter((item) => item.id !== id);
330
330
  localStorage.setItem('gps_history', JSON.stringify(history));
331
331
  renderHistory(history);
@@ -341,7 +341,7 @@ const { ui } = Astro.props;
341
341
  });
342
342
  }
343
343
 
344
- function renderHistory(history: HistoryItem[]) {
344
+ function renderHistory(history) {
345
345
  if (!elements.historyList) return;
346
346
  if (history.length === 0) {
347
347
  elements.historyList.innerHTML = `<div class="no-history">${uiLocal.noHistory}</div>`;
@@ -1,4 +1,5 @@
1
1
  ---
2
+ import 'leaflet/dist/leaflet.css';
2
3
  ---
3
4
 
4
5
  <div class="tech-section">
@@ -7,8 +8,6 @@
7
8
  <small class="hint">Haz clic en el mapa para capturar coordenadas directamente.</small>
8
9
  </div>
9
10
 
10
- <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
11
-
12
11
  <style>
13
12
  .hint {
14
13
  font-size: 0.75rem;