@jjlmoya/utils-drones 1.39.0 → 1.40.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.
Files changed (39) hide show
  1. package/package.json +1 -1
  2. package/src/category/index.ts +2 -0
  3. package/src/entries.ts +4 -0
  4. package/src/index.ts +1 -0
  5. package/src/tests/locale_completeness.test.ts +2 -2
  6. package/src/tests/tool_validation.test.ts +2 -2
  7. package/src/tool/fpv-drone-lap-timer/audio.ts +160 -0
  8. package/src/tool/fpv-drone-lap-timer/bibliography.astro +6 -0
  9. package/src/tool/fpv-drone-lap-timer/bibliography.ts +14 -0
  10. package/src/tool/fpv-drone-lap-timer/bootstrap.ts +20 -0
  11. package/src/tool/fpv-drone-lap-timer/component.astro +136 -0
  12. package/src/tool/fpv-drone-lap-timer/contract.test.ts +24 -0
  13. package/src/tool/fpv-drone-lap-timer/controller.ts +304 -0
  14. package/src/tool/fpv-drone-lap-timer/dom-views.ts +213 -0
  15. package/src/tool/fpv-drone-lap-timer/entry.ts +27 -0
  16. package/src/tool/fpv-drone-lap-timer/export.ts +41 -0
  17. package/src/tool/fpv-drone-lap-timer/fpv-drone-lap-timer.css +705 -0
  18. package/src/tool/fpv-drone-lap-timer/i18n/de.ts +216 -0
  19. package/src/tool/fpv-drone-lap-timer/i18n/en.ts +216 -0
  20. package/src/tool/fpv-drone-lap-timer/i18n/es.ts +216 -0
  21. package/src/tool/fpv-drone-lap-timer/i18n/fr.ts +216 -0
  22. package/src/tool/fpv-drone-lap-timer/i18n/id.ts +216 -0
  23. package/src/tool/fpv-drone-lap-timer/i18n/it.ts +216 -0
  24. package/src/tool/fpv-drone-lap-timer/i18n/ja.ts +216 -0
  25. package/src/tool/fpv-drone-lap-timer/i18n/ko.ts +216 -0
  26. package/src/tool/fpv-drone-lap-timer/i18n/nl.ts +216 -0
  27. package/src/tool/fpv-drone-lap-timer/i18n/pl.ts +216 -0
  28. package/src/tool/fpv-drone-lap-timer/i18n/pt.ts +216 -0
  29. package/src/tool/fpv-drone-lap-timer/i18n/ru.ts +216 -0
  30. package/src/tool/fpv-drone-lap-timer/i18n/sv.ts +216 -0
  31. package/src/tool/fpv-drone-lap-timer/i18n/tr.ts +216 -0
  32. package/src/tool/fpv-drone-lap-timer/i18n/zh.ts +216 -0
  33. package/src/tool/fpv-drone-lap-timer/index.ts +10 -0
  34. package/src/tool/fpv-drone-lap-timer/logic.test.ts +152 -0
  35. package/src/tool/fpv-drone-lap-timer/logic.ts +228 -0
  36. package/src/tool/fpv-drone-lap-timer/seo.astro +16 -0
  37. package/src/tool/fpv-drone-lap-timer/storage.ts +52 -0
  38. package/src/tool/fpv-drone-lap-timer/ui.ts +58 -0
  39. package/src/tools.ts +3 -0
@@ -0,0 +1,216 @@
1
+ import type { FpvDroneLapTimerLocaleContent } from '../entry';
2
+ import type { WithContext, SoftwareApplication, FAQPage, HowTo } from 'schema-dts';
3
+ import type { SEOSection } from '../../../types';
4
+ import { BIBLIOGRAPHY_ITEMS } from '../bibliography';
5
+
6
+ const slug = 'stoper-okrazen-wyscigow-dronow-fpv';
7
+ const title = 'Stoper Okrążeń i Międzyczasów do Wyścigów Dronów FPV';
8
+ const description = 'Interaktywny stoper do wyścigów dronów FPV z akustyczną procedurą startową FAI, analizą międzyczasów, powiadomieniami o rekordzie, wskaźnikiem powtarzalności i telemetrią prędkości.';
9
+
10
+ const ui = {
11
+ setupHeading: 'Konfiguracja Toru i Sesji',
12
+ trackLengthLabel: 'Długość Toru',
13
+ trackLengthUnit: 'metry',
14
+ targetLapsLabel: 'Liczba Okrążeń',
15
+ targetLapsUnit: 'okrążenia (0 = trening otwarty)',
16
+ batteryCapacityLabel: 'Pojemność Akumulatora',
17
+ batteryCapacityUnit: 'mAh',
18
+ soundEnabledLabel: 'Włącz Sygnały Dźwiękowe',
19
+ debounceThresholdLabel: 'Czas Ochronny Przed Podwójnym Kliknięciem',
20
+ debounceThresholdUnit: 'sekundy',
21
+ presetMultiGpLabel: 'Specyfikacja MultiGP (250m / 3 Okrążenia)',
22
+ presetWhoopLabel: 'Tiny Whoop (65m / 5 Okrążeń)',
23
+ presetSprintLabel: 'Sprint Szybkościowy (400m / 2 Okrążenia)',
24
+ startCountdownButton: 'Rozpocznij Odliczanie FAI',
25
+ pauseTimerButton: 'Wstrzymaj Sesję',
26
+ resumeTimerButton: 'Wznów Pomiar',
27
+ resetTimerButton: 'Zresetuj Sesję',
28
+ recordLapButton: 'ZAPISZ OKRĄŻENIE',
29
+ spacebarHint: 'Naciśnij SPACJĘ lub dotknij wielkiego przycisku, aby zarejestrować przelot przez bramkę',
30
+ statusIdle: 'Gotowy do Startu',
31
+ statusCountdown: 'Odliczanie FAI w Toku',
32
+ statusRunning: 'Pomiar Wyścigu Aktywny',
33
+ statusPaused: 'Sesja Wstrzymana',
34
+ statusFinished: 'Wyścig Zakończony',
35
+ currentLapHeading: 'Czas Bieżącego Okrążenia',
36
+ lapNumberPrefix: 'Okrążenie',
37
+ lastLapHeading: 'Ostatnie Okrążenie',
38
+ fastestLapHeading: 'Najszybsze Okrążenie',
39
+ averageLapHeading: 'Średnie Okrążenie',
40
+ deltaBestHeading: 'Różnica do Rekordu',
41
+ consistencyIndexHeading: 'Wskaźnik Powtarzalności',
42
+ estimatedSpeedHeading: 'Szacowana Prędkość Średnia',
43
+ estimatedBatteryHeading: 'Szacowane Zużycie Baterii',
44
+ speedUnitKmh: 'km/h',
45
+ speedUnitMph: 'mph',
46
+ batteryUsedUnit: 'mAh',
47
+ batteryRemainingUnit: 'mAh pozostało',
48
+ lapHistoryHeading: 'Czasy Okrążeń i Porównanie Tempa',
49
+ lapColumnHeader: 'Okr. #',
50
+ timeColumnHeader: 'Czas',
51
+ splitColumnHeader: 'Różnica',
52
+ speedColumnHeader: 'Śr. Prędkość',
53
+ batteryColumnHeader: 'Zużycie Akumulatora',
54
+ noLapsRecordedNotice: 'Brak zarejestrowanych okrążeń. Rozpocznij odliczanie i naciśnij spację, aby zapisać pierwsze okrążenie.',
55
+ consistencyRatingElite: 'Powtarzalność Elitarna',
56
+ consistencyRatingPro: 'Powtarzalność Zawodowca',
57
+ consistencyRatingClub: 'Powtarzalność Klubowa',
58
+ consistencyRatingNovice: 'Powtarzalność Treningowa',
59
+ fastestLapBadge: 'NAJSZYBSZE OKRĄŻENIE',
60
+ sessionSummaryHeading: 'Podsumowanie Sesji i Eksport',
61
+ totalTimeLabel: 'Całkowity Czas Wyścigu',
62
+ completedLapsLabel: 'Ukończone Okrążenia',
63
+ exportCsvButton: 'Eksportuj Okrążenia do CSV',
64
+ copySummaryButton: 'Kopiuj Raport Tekstowy',
65
+ copiedNotice: 'Podsumowanie sesji skopiowane do schowka!',
66
+ };
67
+
68
+ const faqItems = [
69
+ {
70
+ question: 'Jak działa akustyczna procedura startowa FAI w tym stoperze?',
71
+ answer: 'Sekwencja startowa odzwierciedla oficjalne przepisy FAI CIAM F9U dla wyścigów dronów. Rozlega się seria czterech sygnałów ostrzegawczych w odstępach jednosekundowych, a następnie wysoki dźwięk startowy, włączający stoper w punkcie zero.',
72
+ },
73
+ {
74
+ question: 'Jak obliczany jest Wskaźnik Powtarzalności Okrążeń?',
75
+ answer: 'Wskaźnik mierzy odchylenie standardowe ukończonych czasów w odniesieniu do średniej sesji. Wynik powyżej 95 procent świadczy o wzorcowej powtarzalności toru lotu i operowania przepustnicą.',
76
+ },
77
+ {
78
+ question: 'Czy mogę używać pedału nożnego lub przełącznika aparatury RC?',
79
+ answer: 'Tak. Dowolna klawiatura bezprzewodowa, pedał Bluetooth lub przycisk nadajnika przypisany do spacji zarejestruje okrążenie natychmiast bez odrywania wzroku od gogli FPV.',
80
+ },
81
+ {
82
+ question: 'Po co wprowadzono czas ochronny przed podwójnym kliknięciem?',
83
+ answer: 'Bramki mijane są z dużą prędkością. Przypadkowe podwójne dotknięcie mogłoby zapisać fałszywe ułamkowe okrążenie. Filtr odrzuca sygnały pojawiające się poniżej ustalonego progu (domyślnie 3 sekundy).',
84
+ },
85
+ {
86
+ question: 'Na ile dokładna jest szacowana prędkość średnia?',
87
+ answer: 'Prędkość obliczana jest jako stosunek zadeklarowanej długości toru do uzyskanego czasu. Faktyczna prędkość w zakrętach różni się w zależności od promienia łuku i kąta przechyłu drona.',
88
+ },
89
+ ];
90
+
91
+ const howToSteps = [
92
+ {
93
+ name: 'Ustaw długość toru i liczbę okrążeń',
94
+ text: 'Wprowadź długość pętli toru w metrach i cel okrążeń lub wybierz gotowy profil, np. MultiGP Spec.',
95
+ },
96
+ {
97
+ name: 'Uruchom akustyczne odliczanie startowe FAI',
98
+ text: 'Kliknij przycisk odliczania. Wysłuchaj tonów przygotowawczych oraz wysokiego sygnału startu.',
99
+ },
100
+ {
101
+ name: 'Zapisuj okrążenia po minięciu bramki mety',
102
+ text: 'Naciskaj spację lub dotykaj dużego przycisku za każdym razem, gdy dron pokona bramkę start/meta.',
103
+ },
104
+ {
105
+ name: 'Analizuj telemetrię, różnice i powtarzalność',
106
+ text: 'Sprawdzaj wykres słupkowy, delty czasowe i wskaźnik powtarzalności, a następnie eksportuj wyniki do CSV.',
107
+ },
108
+ ];
109
+
110
+ const seoSections: SEOSection[] = [
111
+ {
112
+ type: 'title',
113
+ text: 'Zasady precyzyjnego pomiaru czasu w wyścigach dronów wielowirnikowych FPV',
114
+ level: 2,
115
+ },
116
+ {
117
+ type: 'paragraph',
118
+ html: 'Wyścigi dronów FPV wymagają precyzji co do milisekundy i bezwzględnej powtarzalności toru lotu. Maszyny 5-calowe osiągają ponad 140 km/h, manewrując w ciasnych bramkach 3D i flagach. Skuteczny trening wymaga dźwiękowego startu, natychmiastowej rejestracji przelotów i kontroli tempa na przestrzeni kolejnych okrążeń.',
119
+ },
120
+ {
121
+ type: 'title',
122
+ text: 'Zestawienie klas wyścigowych dronów i parametrów pomiarowych',
123
+ level: 2,
124
+ },
125
+ {
126
+ type: 'table',
127
+ headers: ['Klasa / Standard', 'Typowa Długość Toru', 'Liczba Okrążeń', 'Średni Czas Okrążenia', 'Zakres Prędkości', 'Zalecany Czas Ochronny'],
128
+ rows: [
129
+ ['Tiny Whoop (65mm 1S)', 'od 50m do 80m', '5 okrążeń', 'od 8.5s do 13.0s', '35 do 55 km/h', '2.0 sekundy'],
130
+ ['Micro 3.5 Cala (4S)', 'od 120m do 180m', '4 okrążenia', 'od 12.0s do 18.0s', '70 do 110 km/h', '2.5 sekundy'],
131
+ ['MultiGP Spec 5 Cali (6S)', 'od 200m do 300m', '3 okrążenia', 'od 14.0s do 22.0s', '100 do 150 km/h', '3.0 sekundy'],
132
+ ['Sprint na Otwartym Polu (6S/8S)', 'od 350m do 500m', '2 okrążenia', 'od 20.0s do 32.0s', '130 do 180 km/h', '4.0 sekundy'],
133
+ ],
134
+ },
135
+ {
136
+ type: 'title',
137
+ text: 'Sygnały dźwiękowe procedury startowej i przepisy sportowe FAI F9U',
138
+ level: 2,
139
+ },
140
+ {
141
+ type: 'paragraph',
142
+ html: 'Zgodnie z sekcją 4 przepisów FAI CIAM dla wyścigów dronów, biegi rozpoczynają się sygnałami akustycznymi zamiast flag, aby zapewnić równe szanse reakcji pilotom w goglach. Procedura składa się z dźwięków 440 Hz co sekundę oraz sygnału 880 Hz oznaczającego start.',
143
+ },
144
+ {
145
+ type: 'list',
146
+ items: [
147
+ 'Tony przygotowawcze: Ostrzeżenia akustyczne pozwalające ustabilizować manetkę gazu i skupić wzrok.',
148
+ 'Sygnał startu (Go): Natychmiastowy impuls, od którego czas mierzony jest od t = 0.',
149
+ 'Potwierdzenie dźwiękowe: Sygnał potwierdzający zapis okrążenia bez odrywania wzroku od obrazu.',
150
+ 'Dźwięk rekordu: Wyraźny akord w momencie poprawienia najlepszego czasu sesji.',
151
+ ],
152
+ },
153
+ {
154
+ type: 'title',
155
+ text: 'Znaczenie Wskaźnika Powtarzalności i strategia wyścigowa',
156
+ level: 2,
157
+ },
158
+ {
159
+ type: 'paragraph',
160
+ html: 'Pojedyncze rekordowe okrążenie robi wrażenie, ale zawody wygrywa regularność. Wskaźnik mierzy wahania: pilot o odchyleniach poniżej 0.3 sekundy unika błędów, nie traci energii w zawirowaniach powietrza i oszczędza napięcie akumulatora na ostatnią prostą.',
161
+ },
162
+ {
163
+ type: 'tip',
164
+ title: 'Wskazówka na trening w terenie',
165
+ html: 'Umieść telefon lub tablet w słyszalnym miejscu w strefie pilotów. Podłącz bezprzewodowy przycisk nożny Bluetooth, aby rejestrować okrążenia stopą bez zdejmowania rąk z drążków aparatury.',
166
+ },
167
+ ];
168
+
169
+ const schemas: FpvDroneLapTimerLocaleContent['schemas'] = [
170
+ {
171
+ '@context': 'https://schema.org',
172
+ '@type': 'FAQPage',
173
+ mainEntity: faqItems.map((item) => ({
174
+ '@type': 'Question',
175
+ name: item.question,
176
+ acceptedAnswer: { '@type': 'Answer', text: item.answer },
177
+ })),
178
+ } as WithContext<FAQPage>,
179
+ {
180
+ '@context': 'https://schema.org',
181
+ '@type': 'HowTo',
182
+ name: title,
183
+ description,
184
+ step: howToSteps.map((s, index) => ({
185
+ '@type': 'HowToStep',
186
+ position: index + 1,
187
+ name: s.name,
188
+ text: s.text,
189
+ })),
190
+ } as WithContext<HowTo>,
191
+ {
192
+ '@context': 'https://schema.org',
193
+ '@type': 'SoftwareApplication',
194
+ name: title,
195
+ description,
196
+ applicationCategory: 'UtilityApplication',
197
+ operatingSystem: 'All',
198
+ offers: {
199
+ '@type': 'Offer',
200
+ price: '0',
201
+ priceCurrency: 'PLN',
202
+ },
203
+ } as WithContext<SoftwareApplication>,
204
+ ];
205
+
206
+ export const content: FpvDroneLapTimerLocaleContent = {
207
+ slug,
208
+ title,
209
+ description,
210
+ ui,
211
+ seo: seoSections,
212
+ faq: faqItems,
213
+ howTo: howToSteps,
214
+ bibliography: BIBLIOGRAPHY_ITEMS,
215
+ schemas,
216
+ };
@@ -0,0 +1,216 @@
1
+ import type { FpvDroneLapTimerLocaleContent } from '../entry';
2
+ import type { WithContext, SoftwareApplication, FAQPage, HowTo } from 'schema-dts';
3
+ import type { SEOSection } from '../../../types';
4
+ import { BIBLIOGRAPHY_ITEMS } from '../bibliography';
5
+
6
+ const slug = 'cronometro-voltas-corrida-drone-fpv';
7
+ const title = 'Cronômetro de Voltas e Parciais para Corrida de Drone FPV';
8
+ const description = 'Cronômetro interativo para corridas de drones FPV com contagem acústica FAI, deltas de volta rápida, índice de consistência e telemetria de velocidade.';
9
+
10
+ const ui = {
11
+ setupHeading: 'Configuração de Pista e Sessão',
12
+ trackLengthLabel: 'Extensão da Pista',
13
+ trackLengthUnit: 'metros',
14
+ targetLapsLabel: 'Meta de Voltas',
15
+ targetLapsUnit: 'voltas (0 para treino livre)',
16
+ batteryCapacityLabel: 'Capacidade da Bateria',
17
+ batteryCapacityUnit: 'mAh',
18
+ soundEnabledLabel: 'Ativar Sinais Acústicos',
19
+ debounceThresholdLabel: 'Filtro Anti-rebote de Volta',
20
+ debounceThresholdUnit: 'segundos',
21
+ presetMultiGpLabel: 'Especificação MultiGP (250m / 3 Voltas)',
22
+ presetWhoopLabel: 'Tiny Whoop (65m / 5 Voltas)',
23
+ presetSprintLabel: 'Sprint de Alta Velocidade (400m / 2 Voltas)',
24
+ startCountdownButton: 'Iniciar Contagem FAI',
25
+ pauseTimerButton: 'Pausar Sessão',
26
+ resumeTimerButton: 'Retomar Cronômetro',
27
+ resetTimerButton: 'Zerar Sessão',
28
+ recordLapButton: 'MARCAR VOLTA',
29
+ spacebarHint: 'Pressione a BARRA DE ESPAÇO ou toque no botão gigante ao passar pela linha de chegada',
30
+ statusIdle: 'Pronto para a Largada',
31
+ statusCountdown: 'Contagem FAI em Andamento',
32
+ statusRunning: 'Cronômetro de Corrida Ativo',
33
+ statusPaused: 'Sessão Pausada',
34
+ statusFinished: 'Corrida Concluída',
35
+ currentLapHeading: 'Tempo da Volta Atual',
36
+ lapNumberPrefix: 'Volta',
37
+ lastLapHeading: 'Última Volta',
38
+ fastestLapHeading: 'Melhor Volta',
39
+ averageLapHeading: 'Volta Média',
40
+ deltaBestHeading: 'Diferença para o Recorde',
41
+ consistencyIndexHeading: 'Índice de Consistência',
42
+ estimatedSpeedHeading: 'Velocidade Média Estimada',
43
+ estimatedBatteryHeading: 'Consumo Estimado de Bateria',
44
+ speedUnitKmh: 'km/h',
45
+ speedUnitMph: 'mph',
46
+ batteryUsedUnit: 'mAh',
47
+ batteryRemainingUnit: 'mAh restantes',
48
+ lapHistoryHeading: 'Tempos de Volta e Comparativo de Ritmo',
49
+ lapColumnHeader: 'Volta #',
50
+ timeColumnHeader: 'Tempo',
51
+ splitColumnHeader: 'Diferença Melhor',
52
+ speedColumnHeader: 'Velocidade Média',
53
+ batteryColumnHeader: 'Consumo Bateria',
54
+ noLapsRecordedNotice: 'Nenhuma volta registrada. Inicie a contagem e aperte Espaço ou o botão para marcar a primeira volta.',
55
+ consistencyRatingElite: 'Consistência de Elite',
56
+ consistencyRatingPro: 'Consistência Profissional',
57
+ consistencyRatingClub: 'Consistência de Clube',
58
+ consistencyRatingNovice: 'Consistência em Treinamento',
59
+ fastestLapBadge: 'MELHOR VOLTA',
60
+ sessionSummaryHeading: 'Resumo da Sessão e Exportação',
61
+ totalTimeLabel: 'Duração Total da Corrida',
62
+ completedLapsLabel: 'Voltas Concluídas',
63
+ exportCsvButton: 'Exportar Voltas em CSV',
64
+ copySummaryButton: 'Copiar Resumo em Texto',
65
+ copiedNotice: 'Resumo da sessão copiado para a área de transferência!',
66
+ };
67
+
68
+ const faqItems = [
69
+ {
70
+ question: 'Como funciona a sequência acústica de largada FAI neste cronômetro?',
71
+ answer: 'A sequência segue as regras oficiais de corrida de drones F9U da Federação Aeronáutica Internacional (FAI). São emitidos quatro beeps preparatórios com intervalo de um segundo, seguidos por um tom agudo contínuo que autoriza a largada e dispara o cronômetro no zero exato.',
72
+ },
73
+ {
74
+ question: 'Como o Índice de Consistência de Volta é apurado?',
75
+ answer: 'A pontuação calcula o desvio-padrão dos tempos completados em relação à média da sessão. Valores acima de 95 por cento representam uma pilotagem com controle de aceleração e traçado consistentes.',
76
+ },
77
+ {
78
+ question: 'Posso usar um pedal físico ou chave do rádio para marcar voltas?',
79
+ answer: 'Sim. Qualquer teclado sem fio, pedal Bluetooth ou botão mapeado para disparar a barra de espaço registrará a volta sem necessidade de olhar para a tela.',
80
+ },
81
+ {
82
+ question: 'Para que serve a proteção de anti-rebote no botão?',
83
+ answer: 'Os gates são cruzados em fração de segundos, mas toques acidentais poderiam registrar voltas falsas instantâneas. O filtro anti-rebote descarta acionamentos ocorridos antes do intervalo mínimo (padrão de 3 segundos).',
84
+ },
85
+ {
86
+ question: 'Qual a precisão do cálculo de velocidade média estimada?',
87
+ answer: 'A velocidade resulta da divisão da distância longitudinal declarada pelo tempo de volta. A velocidade real em curvas pode sofrer variações em função do raio da curva e do ângulo de inclinação do drone.',
88
+ },
89
+ ];
90
+
91
+ const howToSteps = [
92
+ {
93
+ name: 'Defina a distância da pista e a meta de voltas',
94
+ text: 'Informe a extensão do circuito em metros e a quantidade de voltas ou selecione uma predefinição como MultiGP Spec.',
95
+ },
96
+ {
97
+ name: 'Dispare a contagem regressiva acústica FAI',
98
+ text: 'Clique em Iniciar Contagem. Ouça os avisos sonoros preliminares e o tom de largada que dá início à cronometragem.',
99
+ },
100
+ {
101
+ name: 'Registre as voltas a cada passagem pelo gate',
102
+ text: 'Pressione a barra de espaço ou toque no botão grande sempre que o drone cruzar a linha de chegada.',
103
+ },
104
+ {
105
+ name: 'Analise telemetria, parciais e consistência',
106
+ text: 'Verifique o gráfico de ritmo, os deltas em relação à melhor volta e o índice de consistência, exportando os dados para CSV.',
107
+ },
108
+ ];
109
+
110
+ const seoSections: SEOSection[] = [
111
+ {
112
+ type: 'title',
113
+ text: 'Fundamentos de cronometragem de alta precisão em corridas de drones FPV',
114
+ level: 2,
115
+ },
116
+ {
117
+ type: 'paragraph',
118
+ html: 'A pilotagem em corridas de drones FPV de alta velocidade requer precisão cirúrgica ao milissegundo e constância nas curvas. Quadricópteros de 5 polegadas atingem mais de 140 km/h ultrapassando gates e bandeiras em três dimensões. Um treino qualificado exige largada padronizada com retorno sonoro, marcação rápida de voltas e diagnóstico de degradação de ritmo nas baterias.',
119
+ },
120
+ {
121
+ type: 'title',
122
+ text: 'Comparativo de categorias de pistas e parâmetros de cronometragem',
123
+ level: 2,
124
+ },
125
+ {
126
+ type: 'table',
127
+ headers: ['Categoria / Padrão', 'Extensão Típica de Pista', 'Voltas por Bateria', 'Tempo Médio por Volta', 'Velocidade Máxima', 'Anti-rebote Recomendado'],
128
+ rows: [
129
+ ['Tiny Whoop (65mm 1S)', '50m a 80m', '5 voltas', '8.5s a 13.0s', '35 a 55 km/h', '2.0 segundos'],
130
+ ['Micro 3.5 Polegadas (4S)', '120m a 180m', '4 voltas', '12.0s a 18.0s', '70 a 110 km/h', '2.5 segundos'],
131
+ ['MultiGP Spec 5 Polegadas (6S)', '200m a 300m', '3 voltas', '14.0s a 22.0s', '100 a 150 km/h', '3.0 segundos'],
132
+ ['Sprint Aberto em Campo (6S/8S)', '350m a 500m', '2 voltas', '20.0s a 32.0s', '130 a 180 km/h', '4.0 segundos'],
133
+ ],
134
+ },
135
+ {
136
+ type: 'title',
137
+ text: 'Sinais sonoros de largada e normas desportivas FAI F9U',
138
+ level: 2,
139
+ },
140
+ {
141
+ type: 'paragraph',
142
+ html: 'Segundo o regulamento FAI CIAM Seção 4 para corridas de drones, as baterias são iniciadas com avisos acústicos padronizados para garantir igualdade no tempo de reação dos pilotos com óculos FPV. A sequência utiliza beeps de 440 Hz a cada segundo e finaliza com um tom contínuo de 880 Hz para partida imediata.',
143
+ },
144
+ {
145
+ type: 'list',
146
+ items: [
147
+ 'Tons de preparação: Sinais para firmar aceleração e garantir foco visual na primeira curva.',
148
+ 'Tom de partida (Go): Sinal instantâneo que ativa o cronômetro exatamente em t = 0.',
149
+ 'Confirmação auditiva: Beep de retorno indicando registro de volta sem tirar o foco da câmera.',
150
+ 'Tom de melhor volta: Alerta com harmonia diferenciada ao superar o recorde da sessão.',
151
+ ],
152
+ },
153
+ {
154
+ type: 'title',
155
+ text: 'Entendendo o Índice de Consistência e a tática de corrida',
156
+ level: 2,
157
+ },
158
+ {
159
+ type: 'paragraph',
160
+ html: 'Embora uma volta isolada muito rápida seja empolgante, campeonatos de drone racing são decididos pela constância. O índice mede a variação entre voltas: pilotos regulares com dispersão menor que 0.3 segundos preservam tensão na bateria e chegam com velocidade no sprint final.',
161
+ },
162
+ {
163
+ type: 'tip',
164
+ title: 'Dica prática para os dias de treino',
165
+ html: 'Deixe seu tablet ou celular com volume alto perto do seu ponto de pilotagem. Conecte um pedal Bluetooth ou use um mini teclado sem fio perto da sua maleta para marcar as voltas com os pés sem soltar os sticks.',
166
+ },
167
+ ];
168
+
169
+ const schemas: FpvDroneLapTimerLocaleContent['schemas'] = [
170
+ {
171
+ '@context': 'https://schema.org',
172
+ '@type': 'FAQPage',
173
+ mainEntity: faqItems.map((item) => ({
174
+ '@type': 'Question',
175
+ name: item.question,
176
+ acceptedAnswer: { '@type': 'Answer', text: item.answer },
177
+ })),
178
+ } as WithContext<FAQPage>,
179
+ {
180
+ '@context': 'https://schema.org',
181
+ '@type': 'HowTo',
182
+ name: title,
183
+ description,
184
+ step: howToSteps.map((s, index) => ({
185
+ '@type': 'HowToStep',
186
+ position: index + 1,
187
+ name: s.name,
188
+ text: s.text,
189
+ })),
190
+ } as WithContext<HowTo>,
191
+ {
192
+ '@context': 'https://schema.org',
193
+ '@type': 'SoftwareApplication',
194
+ name: title,
195
+ description,
196
+ applicationCategory: 'UtilityApplication',
197
+ operatingSystem: 'All',
198
+ offers: {
199
+ '@type': 'Offer',
200
+ price: '0',
201
+ priceCurrency: 'EUR',
202
+ },
203
+ } as WithContext<SoftwareApplication>,
204
+ ];
205
+
206
+ export const content: FpvDroneLapTimerLocaleContent = {
207
+ slug,
208
+ title,
209
+ description,
210
+ ui,
211
+ seo: seoSections,
212
+ faq: faqItems,
213
+ howTo: howToSteps,
214
+ bibliography: BIBLIOGRAPHY_ITEMS,
215
+ schemas,
216
+ };
@@ -0,0 +1,216 @@
1
+ import type { FpvDroneLapTimerLocaleContent } from '../entry';
2
+ import type { WithContext, SoftwareApplication, FAQPage, HowTo } from 'schema-dts';
3
+ import type { SEOSection } from '../../../types';
4
+ import { BIBLIOGRAPHY_ITEMS } from '../bibliography';
5
+
6
+ const slug = 'sekundomer-krugov-gonok-fpv-dronov';
7
+ const title = 'Секундомер Кругов и Сплитов для Гонок FPV Дронов';
8
+ const description = 'Интерактивный таймер кругов для гонок FPV квадрокоптеров со звуковым стартом FAI, расчетом сплитов, фиксацией рекордов, индексом стабильности и телеметрией скорости.';
9
+
10
+ const ui = {
11
+ setupHeading: 'Параметры Трассы и Заезда',
12
+ trackLengthLabel: 'Длина Трассы',
13
+ trackLengthUnit: 'метров',
14
+ targetLapsLabel: 'Целевое Число Кругов',
15
+ targetLapsUnit: 'кругов (0 для свободной тренировки)',
16
+ batteryCapacityLabel: 'Емкость Аккумулятора',
17
+ batteryCapacityUnit: 'мАч',
18
+ soundEnabledLabel: 'Включить Звуковые Сигналы',
19
+ debounceThresholdLabel: 'Защита от Повторного Срабатывания',
20
+ debounceThresholdUnit: 'секунд',
21
+ presetMultiGpLabel: 'Спецификация MultiGP (250м / 3 Круга)',
22
+ presetWhoopLabel: 'Tiny Whoop (65м / 5 Кругов)',
23
+ presetSprintLabel: 'Скоростной Спринт (400м / 2 Круга)',
24
+ startCountdownButton: 'Запустить Обратный Отсчет FAI',
25
+ pauseTimerButton: 'Пауза Заезда',
26
+ resumeTimerButton: 'Возобновить Таймер',
27
+ resetTimerButton: 'Сбросить Заезд',
28
+ recordLapButton: 'ОТМЕТИТЬ КРУГ',
29
+ spacebarHint: 'Нажмите ПРОБЕЛ или коснитесь большой кнопки при пересечении финишных ворот',
30
+ statusIdle: 'Готов к Старту',
31
+ statusCountdown: 'Идет Отсчет FAI',
32
+ statusRunning: 'Таймер Гоночного Заезда',
33
+ statusPaused: 'Заезд Приостановлен',
34
+ statusFinished: 'Заезд Завершен',
35
+ currentLapHeading: 'Время Текущего Круга',
36
+ lapNumberPrefix: 'Круг',
37
+ lastLapHeading: 'Последний Круг',
38
+ fastestLapHeading: 'Лучший Круг',
39
+ averageLapHeading: 'Средний Круг',
40
+ deltaBestHeading: 'Отставание от Рекорда',
41
+ consistencyIndexHeading: 'Индекс Стабильности',
42
+ estimatedSpeedHeading: 'Расчетная Средняя Скорость',
43
+ estimatedBatteryHeading: 'Расчетный Расход Батареи',
44
+ speedUnitKmh: 'км/ч',
45
+ speedUnitMph: 'миль/ч',
46
+ batteryUsedUnit: 'мАч',
47
+ batteryRemainingUnit: 'мАч осталось',
48
+ lapHistoryHeading: 'Время Кругов и Сравнение Темпа',
49
+ lapColumnHeader: 'Круг #',
50
+ timeColumnHeader: 'Время',
51
+ splitColumnHeader: 'Отставание',
52
+ speedColumnHeader: 'Средняя Скорость',
53
+ batteryColumnHeader: 'Расход Батареи',
54
+ noLapsRecordedNotice: 'Круги еще не зафиксированы. Запустите обратный отсчет и нажмите Пробел при пересечении финиша.',
55
+ consistencyRatingElite: 'Элитная Стабильность',
56
+ consistencyRatingPro: 'Профессиональная Стабильность',
57
+ consistencyRatingClub: 'Клубная Стабильность',
58
+ consistencyRatingNovice: 'Тренировочная Стабильность',
59
+ fastestLapBadge: 'ЛУЧШИЙ КРУГ',
60
+ sessionSummaryHeading: 'Итоги Заезда и Экспорт',
61
+ totalTimeLabel: 'Общее Время Гонки',
62
+ completedLapsLabel: 'Пройдено Кругов',
63
+ exportCsvButton: 'Экспортировать Круги в CSV',
64
+ copySummaryButton: 'Копировать Сводку Текстом',
65
+ copiedNotice: 'Итоги заезда скопированы в буфер обмена!',
66
+ };
67
+
68
+ const faqItems = [
69
+ {
70
+ question: 'Как работает акустическая процедура старта FAI в таймере?',
71
+ answer: 'Стартовая последовательность моделирует регламент соревнований дронов FAI CIAM F9U. Пилот слышит серию из четырех звуковых сигналов с интервалом в одну секунду, после чего звучит высокий сигнал вылета, обнуляющий и запускающий таймер.',
72
+ },
73
+ {
74
+ question: 'Как рассчитывается Индекс Стабильности Круга?',
75
+ answer: 'Показатель анализирует среднеквадратичное отклонение времени пройденных кругов от среднего времени заезда. Показатель выше 95 процентов свидетельствует об идеальном удержании гоночной траектории и точном управлении газом.',
76
+ },
77
+ {
78
+ question: 'Можно ли использовать ножную педаль или тумблер аппаратуры?',
79
+ answer: 'Да. Любая беспроводная клавиатура, Bluetooth-педаль или тумблер пульта радиоуправления, отправляющий нажатие клавиши Пробел, фиксирует круг мгновенно без необходимости касаться экрана.',
80
+ },
81
+ {
82
+ question: 'Зачем нужен защитный интервал от повторного нажатия?',
83
+ answer: 'Гоночные ворота проходятся на высокой скорости, однако случайное двойное касание может записать ошибочный круг в доли секунды. Фильтр игнорирует повторные импульсы ранее заданного времени (по умолчанию 3 секунды).',
84
+ },
85
+ {
86
+ question: 'Насколько точна расчетная средняя скорость?',
87
+ answer: 'Скорость вычисляется делением введенной длины центральной линии трека на время прохождения круга. Реальная скорость на виражах зависит от траектории и угла крена квадрокоптера.',
88
+ },
89
+ ];
90
+
91
+ const howToSteps = [
92
+ {
93
+ name: 'Задайте дистанцию трассы и количество кругов',
94
+ text: 'Введите длину круга в метрах и целевое число кругов или выберите готовый шаблон, например MultiGP Spec.',
95
+ },
96
+ {
97
+ name: 'Запустите звуковой обратный отсчет FAI',
98
+ text: 'Нажмите кнопку старта. Прослушайте подготовительные тона и стартовый сигнал вылета.',
99
+ },
100
+ {
101
+ name: 'Фиксируйте круги при пролете ворот финиша',
102
+ text: 'Нажимайте Пробел на клавиатуре или большую кнопку на экране при каждом пересечении створа ворот.',
103
+ },
104
+ {
105
+ name: 'Анализируйте сплиты, телеметрию и стабильность',
106
+ text: 'Изучайте гистограмму темпа, разницу с лучшим кругом и рейтинг стабильности, сохраняя результаты в CSV.',
107
+ },
108
+ ];
109
+
110
+ const seoSections: SEOSection[] = [
111
+ {
112
+ type: 'title',
113
+ text: 'Принципы высокоточного хронометража в гонках FPV квадрокоптеров',
114
+ level: 2,
115
+ },
116
+ {
117
+ type: 'paragraph',
118
+ html: 'Соревнования гоночных дронов FPV требуют миллисекундной точности и исключительной повторяемости маневров. 5-дюймовые квадрокоптеры развивают свыше 140 км/ч, пролетая сквозь пространственные ворота, флаги и дайв-лупы. Качественная тренировка требует акустического старта, мгновенной фиксации кругов и наглядного контроля падения темпа на дистанции.',
119
+ },
120
+ {
121
+ type: 'title',
122
+ text: 'Сравнение классов гоночных коптеров и параметров замера времени',
123
+ level: 2,
124
+ },
125
+ {
126
+ type: 'table',
127
+ headers: ['Класс / Стандарт', 'Обычная Длина Трассы', 'Кругов в Вылете', 'Среднее Время Круга', 'Диапазон Скоростей', 'Рекомендуемый Фильтр'],
128
+ rows: [
129
+ ['Tiny Whoop (65мм 1S)', 'от 50м до 80м', '5 кругов', 'от 8.5с до 13.0с', 'от 35 до 55 км/ч', '2.0 секунды'],
130
+ ['Micro 3.5 Дюйма (4S)', 'от 120м до 180м', '4 круга', 'от 12.0с до 18.0с', 'от 70 до 110 км/ч', '2.5 секунды'],
131
+ ['MultiGP Spec 5 Дюймов (6S)', 'от 200м до 300м', '3 круга', 'от 14.0с до 22.0с', 'от 100 до 150 км/ч', '3.0 секунды'],
132
+ ['Полевой Спринт (6S/8S)', 'от 350м до 500м', '2 круга', 'от 20.0с до 32.0с', 'от 130 до 180 км/ч', '4.0 секунды'],
133
+ ],
134
+ },
135
+ {
136
+ type: 'title',
137
+ text: 'Звуковая процедура старта и спортивный регламент FAI F9U',
138
+ level: 2,
139
+ },
140
+ {
141
+ type: 'paragraph',
142
+ html: 'По правилам FAI CIAM Секция 4 для гонок дронов, старты осуществляются по звуковому сигналу, исключая визуальные флаги ради равной реакции пилотов в видеошлемах. Процедура включает сигналы 440 Гц с интервалом в секунду и завершается стартовым тоном 880 Гц для запуска двигателей.',
143
+ },
144
+ {
145
+ type: 'list',
146
+ items: [
147
+ 'Подготовительные тона: Акустические сигналы для установки газа и концентрации взгляда на первом вираже.',
148
+ 'Стартовый сигнал (Go): Мгновенный сигнал, запускающий таймер гонки ровно в t = 0.',
149
+ 'Звуковое подтверждение: Четкий звуковой щелчок подтверждает фиксацию круга без отвлечения от полета.',
150
+ 'Сигнал лучшего круга: Характерный гармоничный аккорд при обновлении рекорда текущего заезда.',
151
+ ],
152
+ },
153
+ {
154
+ type: 'title',
155
+ text: 'Роль Индекса Стабильности и стратегия пилотирования',
156
+ level: 2,
157
+ },
158
+ {
159
+ type: 'paragraph',
160
+ html: 'Один быстрый круг производит впечатление, но титулы завоевываются стабильностью. Индекс оценивает разброс темпа: пилот с отклонениями менее 0.3 секунды избегает просадок напряжения аккумулятора и сохраняет ресурс для финального ускорения.',
161
+ },
162
+ {
163
+ type: 'tip',
164
+ title: 'Совет для полевых тренировок',
165
+ html: 'Разместите планшет с включенным звуком возле места пилота. Подключите ножную Bluetooth-педаль или компактную клавиатуру, чтобы фиксировать круги ногой, не снимая пальцы со стиков управления.',
166
+ },
167
+ ];
168
+
169
+ const schemas: FpvDroneLapTimerLocaleContent['schemas'] = [
170
+ {
171
+ '@context': 'https://schema.org',
172
+ '@type': 'FAQPage',
173
+ mainEntity: faqItems.map((item) => ({
174
+ '@type': 'Question',
175
+ name: item.question,
176
+ acceptedAnswer: { '@type': 'Answer', text: item.answer },
177
+ })),
178
+ } as WithContext<FAQPage>,
179
+ {
180
+ '@context': 'https://schema.org',
181
+ '@type': 'HowTo',
182
+ name: title,
183
+ description,
184
+ step: howToSteps.map((s, index) => ({
185
+ '@type': 'HowToStep',
186
+ position: index + 1,
187
+ name: s.name,
188
+ text: s.text,
189
+ })),
190
+ } as WithContext<HowTo>,
191
+ {
192
+ '@context': 'https://schema.org',
193
+ '@type': 'SoftwareApplication',
194
+ name: title,
195
+ description,
196
+ applicationCategory: 'UtilityApplication',
197
+ operatingSystem: 'All',
198
+ offers: {
199
+ '@type': 'Offer',
200
+ price: '0',
201
+ priceCurrency: 'RUB',
202
+ },
203
+ } as WithContext<SoftwareApplication>,
204
+ ];
205
+
206
+ export const content: FpvDroneLapTimerLocaleContent = {
207
+ slug,
208
+ title,
209
+ description,
210
+ ui,
211
+ seo: seoSections,
212
+ faq: faqItems,
213
+ howTo: howToSteps,
214
+ bibliography: BIBLIOGRAPHY_ITEMS,
215
+ schemas,
216
+ };