@jjlmoya/utils-hardware 1.2.0 → 1.5.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 (102) hide show
  1. package/package.json +2 -1
  2. package/src/tests/faq_count.test.ts +1 -1
  3. package/src/tests/i18n_coverage.test.ts +36 -0
  4. package/src/tests/locale_completeness.test.ts +1 -1
  5. package/src/tests/slug_uniqueness.test.ts +81 -0
  6. package/src/tests/title_quality.test.ts +1 -1
  7. package/src/tool/batteryHealthEstimator/i18n/de.ts +158 -0
  8. package/src/tool/batteryHealthEstimator/i18n/id.ts +158 -0
  9. package/src/tool/batteryHealthEstimator/i18n/it.ts +158 -0
  10. package/src/tool/batteryHealthEstimator/i18n/ja.ts +158 -0
  11. package/src/tool/batteryHealthEstimator/i18n/ko.ts +158 -0
  12. package/src/tool/batteryHealthEstimator/i18n/nl.ts +158 -0
  13. package/src/tool/batteryHealthEstimator/i18n/pl.ts +158 -0
  14. package/src/tool/batteryHealthEstimator/i18n/pt.ts +158 -0
  15. package/src/tool/batteryHealthEstimator/i18n/ru.ts +158 -0
  16. package/src/tool/batteryHealthEstimator/i18n/sv.ts +158 -0
  17. package/src/tool/batteryHealthEstimator/i18n/tr.ts +158 -0
  18. package/src/tool/batteryHealthEstimator/i18n/zh.ts +158 -0
  19. package/src/tool/batteryHealthEstimator/index.ts +15 -7
  20. package/src/tool/deadPixelTest/i18n/de.ts +218 -0
  21. package/src/tool/deadPixelTest/i18n/id.ts +218 -0
  22. package/src/tool/deadPixelTest/i18n/it.ts +218 -0
  23. package/src/tool/deadPixelTest/i18n/ja.ts +218 -0
  24. package/src/tool/deadPixelTest/i18n/ko.ts +218 -0
  25. package/src/tool/deadPixelTest/i18n/nl.ts +218 -0
  26. package/src/tool/deadPixelTest/i18n/pl.ts +218 -0
  27. package/src/tool/deadPixelTest/i18n/pt.ts +218 -0
  28. package/src/tool/deadPixelTest/i18n/ru.ts +218 -0
  29. package/src/tool/deadPixelTest/i18n/sv.ts +218 -0
  30. package/src/tool/deadPixelTest/i18n/tr.ts +218 -0
  31. package/src/tool/deadPixelTest/i18n/zh.ts +217 -0
  32. package/src/tool/deadPixelTest/index.ts +15 -7
  33. package/src/tool/gamepadTest/i18n/de.ts +186 -0
  34. package/src/tool/gamepadTest/i18n/id.ts +186 -0
  35. package/src/tool/gamepadTest/i18n/it.ts +186 -0
  36. package/src/tool/gamepadTest/i18n/ja.ts +186 -0
  37. package/src/tool/gamepadTest/i18n/ko.ts +186 -0
  38. package/src/tool/gamepadTest/i18n/nl.ts +186 -0
  39. package/src/tool/gamepadTest/i18n/pl.ts +186 -0
  40. package/src/tool/gamepadTest/i18n/pt.ts +186 -0
  41. package/src/tool/gamepadTest/i18n/ru.ts +186 -0
  42. package/src/tool/gamepadTest/i18n/sv.ts +186 -0
  43. package/src/tool/gamepadTest/i18n/tr.ts +186 -0
  44. package/src/tool/gamepadTest/i18n/zh.ts +186 -0
  45. package/src/tool/gamepadTest/index.ts +15 -7
  46. package/src/tool/gamepadVibrationTester/i18n/de.ts +155 -0
  47. package/src/tool/gamepadVibrationTester/i18n/id.ts +155 -0
  48. package/src/tool/gamepadVibrationTester/i18n/it.ts +155 -0
  49. package/src/tool/gamepadVibrationTester/i18n/ja.ts +155 -0
  50. package/src/tool/gamepadVibrationTester/i18n/ko.ts +155 -0
  51. package/src/tool/gamepadVibrationTester/i18n/nl.ts +155 -0
  52. package/src/tool/gamepadVibrationTester/i18n/pl.ts +155 -0
  53. package/src/tool/gamepadVibrationTester/i18n/pt.ts +155 -0
  54. package/src/tool/gamepadVibrationTester/i18n/ru.ts +155 -0
  55. package/src/tool/gamepadVibrationTester/i18n/sv.ts +155 -0
  56. package/src/tool/gamepadVibrationTester/i18n/tr.ts +155 -0
  57. package/src/tool/gamepadVibrationTester/i18n/zh.ts +155 -0
  58. package/src/tool/gamepadVibrationTester/index.ts +15 -7
  59. package/src/tool/keyboardTest/i18n/de.ts +146 -0
  60. package/src/tool/keyboardTest/i18n/id.ts +146 -0
  61. package/src/tool/keyboardTest/i18n/it.ts +146 -0
  62. package/src/tool/keyboardTest/i18n/ja.ts +146 -0
  63. package/src/tool/keyboardTest/i18n/ko.ts +146 -0
  64. package/src/tool/keyboardTest/i18n/nl.ts +146 -0
  65. package/src/tool/keyboardTest/i18n/pl.ts +146 -0
  66. package/src/tool/keyboardTest/i18n/pt.ts +146 -0
  67. package/src/tool/keyboardTest/i18n/ru.ts +146 -0
  68. package/src/tool/keyboardTest/i18n/sv.ts +146 -0
  69. package/src/tool/keyboardTest/i18n/tr.ts +146 -0
  70. package/src/tool/keyboardTest/i18n/zh.ts +146 -0
  71. package/src/tool/keyboardTest/index.ts +15 -7
  72. package/src/tool/mousePollingTest/component.astro +1 -1
  73. package/src/tool/mousePollingTest/i18n/de.ts +135 -0
  74. package/src/tool/mousePollingTest/i18n/id.ts +135 -0
  75. package/src/tool/mousePollingTest/i18n/it.ts +135 -0
  76. package/src/tool/mousePollingTest/i18n/ja.ts +135 -0
  77. package/src/tool/mousePollingTest/i18n/ko.ts +135 -0
  78. package/src/tool/mousePollingTest/i18n/nl.ts +135 -0
  79. package/src/tool/mousePollingTest/i18n/pl.ts +135 -0
  80. package/src/tool/mousePollingTest/i18n/pt.ts +135 -0
  81. package/src/tool/mousePollingTest/i18n/ru.ts +135 -0
  82. package/src/tool/mousePollingTest/i18n/sv.ts +135 -0
  83. package/src/tool/mousePollingTest/i18n/tr.ts +135 -0
  84. package/src/tool/mousePollingTest/i18n/zh.ts +135 -0
  85. package/src/tool/mousePollingTest/index.ts +15 -7
  86. package/src/tool/mousePollingTest/logic/RatonManager.ts +90 -51
  87. package/src/tool/mousePollingTest/logic/StatisticalFilter.ts +17 -25
  88. package/src/tool/toneGenerator/i18n/de.ts +146 -0
  89. package/src/tool/toneGenerator/i18n/id.ts +146 -0
  90. package/src/tool/toneGenerator/i18n/it.ts +146 -0
  91. package/src/tool/toneGenerator/i18n/ja.ts +146 -0
  92. package/src/tool/toneGenerator/i18n/ko.ts +146 -0
  93. package/src/tool/toneGenerator/i18n/nl.ts +146 -0
  94. package/src/tool/toneGenerator/i18n/pl.ts +146 -0
  95. package/src/tool/toneGenerator/i18n/pt.ts +146 -0
  96. package/src/tool/toneGenerator/i18n/ru.ts +146 -0
  97. package/src/tool/toneGenerator/i18n/sv.ts +146 -0
  98. package/src/tool/toneGenerator/i18n/tr.ts +146 -0
  99. package/src/tool/toneGenerator/i18n/zh.ts +146 -0
  100. package/src/tool/toneGenerator/index.ts +15 -7
  101. package/src/types.ts +1 -1
  102. package/src/tool/mousePollingTest/worker/mouseWorker.ts +0 -50
@@ -0,0 +1,146 @@
1
+ import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
2
+ import type { ToolLocaleContent } from '../../../types';
3
+ import type { ToneGeneratorUI } from '../ui';
4
+
5
+ const slug = 'ton-och-frekvensgenerator-online';
6
+ const title = 'Online ton och frekvensgenerator';
7
+ const description =
8
+ 'Generera sinus-, fyrkants-, triangels- och sågtandsvågor. Testa dina högtalare, hörlurar eller subwoofer med frekvenser från 20Hz till 20kHz.';
9
+
10
+ const faqData = [
11
+ {
12
+ question: 'Vad används en frekvensgenerator till?',
13
+ answer:
14
+ 'Den används för att testa frekvensåtergivningen hos högtalare och hörlurar, upptäcka oönskade resonanser i möbler, hitta luckor i ditt hörselområde eller till och med hjälpa till att lindra tinnitus genom notch-terapi.',
15
+ },
16
+ {
17
+ question: 'Vad är skillnaden mellan en sinusvåg och en fyrkantsvåg?',
18
+ answer:
19
+ 'En sinusvåg är en ren ton utan övertoner (mjuk och rund). En fyrkantsvåg är rik på udda övertoner och låter mycket mer aggressiv eller digital. Triangelvågen ligger däremellan och är användbar för ljudsyntes.',
20
+ },
21
+ {
22
+ question: 'Kan jag skada mina högtalare med det här verktyget?',
23
+ answer:
24
+ 'Ja, om du använder mycket höga volymer vid extrema frekvenser (särskilt bas under 30Hz oder diskant över 15kHz). Börja alltid med en låg systemvolym och öka gradvis.',
25
+ },
26
+ {
27
+ question: 'Vilket är det mänskliga hörselområdet?',
28
+ answer:
29
+ 'Teoretiskt 20Hz till 20 000Hz (20kHz). Med åldern är det dock normalt att förlora förmågan att höra över 15kHz. Detta test kan hjälpa dig att verifiera din personliga övre gräns.',
30
+ },
31
+ ];
32
+
33
+ const howToData = [
34
+ {
35
+ name: 'Välj vågtyp',
36
+ text: 'Välj mellan sinus (ren), fyrkant, triangel eller sågtand beroende på vilken typ av test du vill utföra.',
37
+ },
38
+ {
39
+ name: 'Justera frekvensen',
40
+ text: 'Flytta skjutreglaget för att navigera i det hörbara spektrumet. Använd genvägarna för 60Hz, 440Hz eller 1kHz för att snabbt komma åt referensfrekvenser.',
41
+ },
42
+ {
43
+ name: 'Kontrollera volymen',
44
+ text: 'Se till att högtalarvolymen är låg innan du trycker på Play. Du kan justera förstärkningen direkt i verktyget.',
45
+ },
46
+ {
47
+ name: 'Analysera svaret',
48
+ text: 'Lyssna efter eventuella förvrängningar eller moment när ljudet försvinner. Detta indikerar de fysiska begränsningarna hos din ljudhårdvara.',
49
+ },
50
+ ];
51
+
52
+ const faqSchema: WithContext<FAQPage> = {
53
+ '@context': 'https://schema.org',
54
+ '@type': 'FAQPage',
55
+ mainEntity: faqData.map((item) => ({
56
+ '@type': 'Question',
57
+ name: item.question,
58
+ acceptedAnswer: { '@type': 'Answer', text: item.answer },
59
+ })),
60
+ };
61
+
62
+ const howToSchema: WithContext<HowTo> = {
63
+ '@context': 'https://schema.org',
64
+ '@type': 'HowTo',
65
+ name: title,
66
+ description,
67
+ step: howToData.map((step, i) => ({
68
+ '@type': 'HowToStep',
69
+ position: i + 1,
70
+ name: step.name,
71
+ text: step.text,
72
+ })),
73
+ };
74
+
75
+ const appSchema: WithContext<SoftwareApplication> = {
76
+ '@context': 'https://schema.org',
77
+ '@type': 'SoftwareApplication',
78
+ name: title,
79
+ description,
80
+ applicationCategory: 'UtilityApplication',
81
+ operatingSystem: 'All',
82
+ offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' },
83
+ inLanguage: 'sv',
84
+ };
85
+
86
+ export const content: ToolLocaleContent<ToneGeneratorUI> = {
87
+ slug,
88
+ title,
89
+ description,
90
+ faqTitle: 'Vanliga frågor',
91
+ faq: faqData,
92
+ bibliographyTitle: 'Referenser',
93
+ bibliography: [
94
+ {
95
+ name: 'MDN Web Docs — Web Audio API',
96
+ url: 'https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API',
97
+ },
98
+ {
99
+ name: 'ISO 226:2023 — Equal-loudness contours',
100
+ url: 'https://www.iso.org/standard/83117.html',
101
+ },
102
+ ],
103
+ howTo: howToData,
104
+ schemas: [faqSchema, howToSchema, appSchema],
105
+ seo: [
106
+ { type: 'title', text: 'Allt om frekvenser och ljudvågor', level: 2 },
107
+ {
108
+ type: 'paragraph',
109
+ html: 'Ljud är ren fysik i rörelse. Detta verktyg låter dig manipulera ljudvågor i realtid, från den djupaste basen du kan känna i bröstet till de ultraljudshöjder som endast djur kan uppfatta.',
110
+ },
111
+ { type: 'title', text: 'Mänskligt hörselområde och presbyacusis', level: 3 },
112
+ {
113
+ type: 'paragraph',
114
+ html: 'Ett friskt mänskligt öra uppfattar ljud mellan <strong>20Hz och 20kHz</strong>. Med åldern sjunker den övre gränsen: de flesta vuxna över 50 kan inte höra över 12kHz. Tonen på 17,4kHz, känd som "myggtonen", är ett klassiskt test som vanligtvis bara tonåringar klarar.',
115
+ },
116
+ { type: 'title', text: 'Vågtyper och deras användning', level: 3 },
117
+ {
118
+ type: 'paragraph',
119
+ html: '<strong>Sinus:</strong> ren ton utan övertoner, används i medicinska hörseltester och instrumentkalibrering. <strong>Fyrkant:</strong> rik på udda övertoner, låter som retro 8-bitarskonsoler. <strong>Sågtand:</strong> innehåller alla övertoner, basen för elektroniska musik-syntar. <strong>Triangel:</strong> mittpunkt mellan sinus och fyrkant — mjukare än fyrkant men med mer harmoniskt innehåll än sinus.',
120
+ },
121
+ { type: 'title', text: 'Högtalartest och rengöring genom vibration', level: 3 },
122
+ {
123
+ type: 'paragraph',
124
+ html: 'En lågfrekvent våg (vanligtvis <strong>165Hz</strong>) vid maximal volym med en fyrkants- eller sågtandsform tvingar högtalarmembranet att vibrera våldsamt, vilket mekaniskt driver ut vattendroppar som fastnat i gallret. Spela inte extremt höga frekvenser på maximal volym under långa perioder: även om du inte kan höra dem kan energin skada utrustningens diskanthögtalare.',
125
+ },
126
+ ],
127
+ ui: {
128
+ badge: 'Ljudgenerator',
129
+ title: 'Tongenerator',
130
+ description: 'Generera rena frekvenser för ljudtester.',
131
+ freqLabel: 'Frekvens',
132
+ preset60: '60Hz',
133
+ preset440: '440Hz',
134
+ preset1k: '1kHz',
135
+ rangeMin: '20Hz (Sub-bas)',
136
+ rangeMax: '20kHz (Ultraljud)',
137
+ waveLabel: 'Vågform',
138
+ waveSine: 'Sinus',
139
+ waveSquare: 'Fyrkant',
140
+ waveSawtooth: 'Sågtand',
141
+ waveTriangle: 'Triangel',
142
+ volLabel: 'Volym',
143
+ btnPlay: 'SPELA TON',
144
+ btnStop: 'STOPP',
145
+ },
146
+ };
@@ -0,0 +1,146 @@
1
+ import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
2
+ import type { ToolLocaleContent } from '../../../types';
3
+ import type { ToneGeneratorUI } from '../ui';
4
+
5
+ const slug = 'online-ses-ve-frekans-ureteci';
6
+ const title = 'Çevrimiçi Ses ve Frekans Üreteci';
7
+ const description =
8
+ 'Sinüs, kare, üçgen ve testere dişi dalgalar oluşturun. Hoparlörlerinizi, kulaklıklarınızı veya subwoofer\'ınızı 20Hz ile 20kHz arasındaki frekanslarla test edin.';
9
+
10
+ const faqData = [
11
+ {
12
+ question: 'Frekans üreteci ne için kullanılır?',
13
+ answer:
14
+ 'Hoparlörlerin ve kulaklıkların frekans tepkisini test etmek, mobilyalardaki istenmeyen rezonansları tespit etmek, işitme aralığınızdaki boşlukları bulmak ve hatta çentik (notch) terapisi yoluyla kulak çınlamasını sakinleştirmeye yardımcı olmak için kullanılır.',
15
+ },
16
+ {
17
+ question: 'Sinüs dalgası ile kare dalga arasındaki fark nedir?',
18
+ answer:
19
+ 'Sinüs dalgası, harmonik içermeyen saf bir tondur (pürüzsüz ve yuvarlak). Kare dalga tek harmonikler açısından zengindir ve çok daha agresif veya dijital bir sese sahiptir. Üçgen dalga, ses sentezi için yararlı olan ikisinin arasında bir yerdedir.',
20
+ },
21
+ {
22
+ question: 'Bu araçla hoparlörlerime zarar verebilir miyim?',
23
+ answer:
24
+ 'Evet, uç frekanslarda (özellikle 30Hz altındaki baslar veya 15kHz üzerindeki tizler) çok yüksek ses seviyeleri kullanırsanız zarar verebilirsiniz. Her zaman düşük bir sistem sesiyle başlayın ve kademeli olarak artırın.',
25
+ },
26
+ {
27
+ question: 'İnsan işitme aralığı nedir?',
28
+ answer:
29
+ 'Teorik olarak 20Hz ile 20.000Hz (20kHz) arasıdır. Ancak yaşlandıkça 15kHz\'in üzerindeki sesleri duyma yeteneğini kaybetmek normaldir. Bu test, kişisel üst sınırınızı doğrulamanıza yardımcı olabilir.',
30
+ },
31
+ ];
32
+
33
+ const howToData = [
34
+ {
35
+ name: 'Dalga formu türünü seçin',
36
+ text: 'Yapmak istediğiniz testin türüne bağlı olarak Sinüs (saf), Kare, Üçgen veya Testere dişi arasından seçim yapın.',
37
+ },
38
+ {
39
+ name: 'Frekansı ayarlayın',
40
+ text: 'İşitilebilir spektrumda gezinmek için kaydırıcıyı hareket ettirin. Referans frekanslara hızlıca erişmek için 60Hz, 440Hz veya 1kHz kısayollarını kullanın.',
41
+ },
42
+ {
43
+ name: 'Ses seviyesini kontrol edin',
44
+ text: 'Oynat düğmesine basmadan önce hoparlör sesinizin düşük olduğundan emin olun. Kazancı (gain) doğrudan araç üzerinden ayarlayabilirsiniz.',
45
+ },
46
+ {
47
+ name: 'Tepkiyi analiz edin',
48
+ text: 'Olası bozulmaları veya sesin kaybolduğu anları dinleyin. Bu, ses donanımınızın fiziksel sınırlarını gösterecektir.',
49
+ },
50
+ ];
51
+
52
+ const faqSchema: WithContext<FAQPage> = {
53
+ '@context': 'https://schema.org',
54
+ '@type': 'FAQPage',
55
+ mainEntity: faqData.map((item) => ({
56
+ '@type': 'Question',
57
+ name: item.question,
58
+ acceptedAnswer: { '@type': 'Answer', text: item.answer },
59
+ })),
60
+ };
61
+
62
+ const howToSchema: WithContext<HowTo> = {
63
+ '@context': 'https://schema.org',
64
+ '@type': 'HowTo',
65
+ name: title,
66
+ description,
67
+ step: howToData.map((step, i) => ({
68
+ '@type': 'HowToStep',
69
+ position: i + 1,
70
+ name: step.name,
71
+ text: step.text,
72
+ })),
73
+ };
74
+
75
+ const appSchema: WithContext<SoftwareApplication> = {
76
+ '@context': 'https://schema.org',
77
+ '@type': 'SoftwareApplication',
78
+ name: title,
79
+ description,
80
+ applicationCategory: 'UtilityApplication',
81
+ operatingSystem: 'All',
82
+ offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' },
83
+ inLanguage: 'tr',
84
+ };
85
+
86
+ export const content: ToolLocaleContent<ToneGeneratorUI> = {
87
+ slug,
88
+ title,
89
+ description,
90
+ faqTitle: 'Sıkça Sorulan Sorular',
91
+ faq: faqData,
92
+ bibliographyTitle: 'Referanslar',
93
+ bibliography: [
94
+ {
95
+ name: 'MDN Web Docs — Web Audio API',
96
+ url: 'https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API',
97
+ },
98
+ {
99
+ name: 'ISO 226:2023 — Equal-loudness contours',
100
+ url: 'https://www.iso.org/standard/83117.html',
101
+ },
102
+ ],
103
+ howTo: howToData,
104
+ schemas: [faqSchema, howToSchema, appSchema],
105
+ seo: [
106
+ { type: 'title', text: 'Frekanslar ve Ses Dalgaları Hakkında Her Şey', level: 2 },
107
+ {
108
+ type: 'paragraph',
109
+ html: 'Ses, hareket halindeki saf fiziktir. Bu araç, göğsünüzde hissedebileceğiniz en derin baslardan yalnızca hayvanların algılayabileceği ultrasonik tizlere kadar ses dalgalarını gerçek zamanlı olarak manipüle etmenizi sağlar.',
110
+ },
111
+ { type: 'title', text: 'İnsan İşitme Aralığı ve Presbikuzi', level: 3 },
112
+ {
113
+ type: 'paragraph',
114
+ html: 'Sağlıklı bir insan kulağı <strong>20Hz ile 20kHz</strong> arasındaki sesleri algılar. Yaşla birlikte üst sınır düşer: 50 yaşın üzerindeki çoğu yetişkin 12kHz\'in üzerini duyamaz. "Sivrisinek tonu" olarak bilinen 17.4kHz tonu, genellikle sadece gençlerin geçebildiği klasik bir testtir.',
115
+ },
116
+ { type: 'title', text: 'Dalga Türleri ve Kullanımları', level: 3 },
117
+ {
118
+ type: 'paragraph',
119
+ html: '<strong>Sinüs:</strong> Tibbi işitme testlerinde ve enstrüman kalibrasyonunda kullanılan, harmonik içermeyen saf ton. <strong>Kare:</strong> Tek harmonikler açısından zengin, retro 8-bit konsollar gibi ses çıkarır. <strong>Testere dişi:</strong> Elektronik müzik sentezleyicilerinin temeli olan tüm harmonikleri içerir. <strong>Üçgen:</strong> Sinüs ve kare arasındaki orta nokta; kare dalgadan daha pürüzsüz ancak sinüs dalgasından daha fazla harmonik içeriğe sahip.',
120
+ },
121
+ { type: 'title', text: 'Hoparlör Testi ve Titreşimle Temizleme', level: 3 },
122
+ {
123
+ type: 'paragraph',
124
+ html: 'Maksimum ses seviyesinde kare veya testere dişi şeklinde düşük frekanslı bir dalga (genellikle <strong>165Hz</strong>), hoparlör diyaframını şiddetle titremeye zorlayarak ızgarada hapsolmuş su damlacıklarını mekanik olarak dışarı atar. Çok yüksek frekansları uzun süre maksimum seste çalmayın: Duyamasanız bile enerji, ekipmanınızın tweeter\'larına zarar verebilir.',
125
+ },
126
+ ],
127
+ ui: {
128
+ badge: 'Ses Üreteci',
129
+ title: 'Ses Üreteci',
130
+ description: 'Ses testleri için saf frekanslar oluşturun.',
131
+ freqLabel: 'Frekans',
132
+ preset60: '60Hz',
133
+ preset440: '440Hz',
134
+ preset1k: '1kHz',
135
+ rangeMin: '20Hz (Sub-bas)',
136
+ rangeMax: '20kHz (Ultrason)',
137
+ waveLabel: 'Dalga Formu',
138
+ waveSine: 'Sinüs',
139
+ waveSquare: 'Kare',
140
+ waveSawtooth: 'Testere dişi',
141
+ waveTriangle: 'Üçgen',
142
+ volLabel: 'Ses Seviyesi',
143
+ btnPlay: 'SESİ OYNAT',
144
+ btnStop: 'DURDUR',
145
+ },
146
+ };
@@ -0,0 +1,146 @@
1
+ import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
2
+ import type { ToolLocaleContent } from '../../../types';
3
+ import type { ToneGeneratorUI } from '../ui';
4
+
5
+ const slug = 'tone-frequency-generator';
6
+ const title = '在线音频和频率发生器';
7
+ const description =
8
+ '生成正弦波、方波、三角波和锯齿波。使用 20Hz 至 20kHz 的频率测试您的扬声器、耳机或低音炮。';
9
+
10
+ const faqData = [
11
+ {
12
+ question: '频率发生器有什么用途?',
13
+ answer:
14
+ '它用于测试扬声器和耳机的频率响应,检测家具中不必要的共振,查找听力范围内的间隙,甚至通过陷波疗法(Notch Therapy)帮助缓解耳鸣。',
15
+ },
16
+ {
17
+ question: '正弦波与方波有什么区别?',
18
+ answer:
19
+ '正弦波是没有谐波的纯音(平滑且圆润)。方波富含奇次谐波,听起来更具攻击性或更具“数字感”。三角波介于两者之间,对音频合成非常有用。',
20
+ },
21
+ {
22
+ question: '这个工具会损坏我的扬声器吗?',
23
+ answer:
24
+ '是的,如果您在极端频率(特别是 30Hz 以下的低音或 15kHz 以上的高音)下使用极高音量,则可能造成损坏。请始终从较低的系统音量开始并逐渐增加。',
25
+ },
26
+ {
27
+ question: '人类的听力范围是多少?',
28
+ answer:
29
+ '理论上为 20Hz 至 20,000Hz (20kHz)。然而,随着年龄的增长,失去听到 15kHz 以上声音的能力是很正常的。此测试可以帮助您验证个人的听力上限。',
30
+ },
31
+ ];
32
+
33
+ const howToData = [
34
+ {
35
+ name: '选择波形类型',
36
+ text: '根据您要执行的测试类型,在正弦波(纯音)、方波、三角波或锯齿波之间进行选择。',
37
+ },
38
+ {
39
+ name: '调节频率',
40
+ text: '移动滑块以浏览可听频谱。使用 60Hz、440Hz 或 1kHz 快捷键快速访问参考频率。',
41
+ },
42
+ {
43
+ name: '控制音量',
44
+ text: '在按下播放键之前,请确保扬声器音量处于较低水平。您可以直接在工具中调整增益。',
45
+ },
46
+ {
47
+ name: '分析响应',
48
+ text: '留意可能出现的失真或声音消失的时刻。这将显示音频硬件的物理极限。',
49
+ },
50
+ ];
51
+
52
+ const faqSchema: WithContext<FAQPage> = {
53
+ '@context': 'https://schema.org',
54
+ '@type': 'FAQPage',
55
+ mainEntity: faqData.map((item) => ({
56
+ '@type': 'Question',
57
+ name: item.question,
58
+ acceptedAnswer: { '@type': 'Answer', text: item.answer },
59
+ })),
60
+ };
61
+
62
+ const howToSchema: WithContext<HowTo> = {
63
+ '@context': 'https://schema.org',
64
+ '@type': 'HowTo',
65
+ name: title,
66
+ description,
67
+ step: howToData.map((step, i) => ({
68
+ '@type': 'HowToStep',
69
+ position: i + 1,
70
+ name: step.name,
71
+ text: step.text,
72
+ })),
73
+ };
74
+
75
+ const appSchema: WithContext<SoftwareApplication> = {
76
+ '@context': 'https://schema.org',
77
+ '@type': 'SoftwareApplication',
78
+ name: title,
79
+ description,
80
+ applicationCategory: 'UtilityApplication',
81
+ operatingSystem: 'All',
82
+ offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' },
83
+ inLanguage: 'zh',
84
+ };
85
+
86
+ export const content: ToolLocaleContent<ToneGeneratorUI> = {
87
+ slug,
88
+ title,
89
+ description,
90
+ faqTitle: '常见问题',
91
+ faq: faqData,
92
+ bibliographyTitle: '参考资料',
93
+ bibliography: [
94
+ {
95
+ name: 'MDN Web Docs — Web Audio API',
96
+ url: 'https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API',
97
+ },
98
+ {
99
+ name: 'ISO 226:2023 — Equal-loudness contours',
100
+ url: 'https://www.iso.org/standard/83117.html',
101
+ },
102
+ ],
103
+ howTo: howToData,
104
+ schemas: [faqSchema, howToSchema, appSchema],
105
+ seo: [
106
+ { type: 'title', text: '关于频率和声波的一切', level: 2 },
107
+ {
108
+ type: 'paragraph',
109
+ html: '声音是运动中的纯粹物理。此工具可让您实时操控声波,从您能感受到胸腔共鸣的极深沉低音,到只有动物才能感知到的超声波高音。',
110
+ },
111
+ { type: 'title', text: '人类听力范围与老年性耳聋', level: 3 },
112
+ {
113
+ type: 'paragraph',
114
+ html: '健康的成年人能感知 <strong>20Hz 到 20kHz</strong> 之间的声音。随着年龄增长,上限会下降:大多数 50 岁以上的成人听不到 12kHz 以上的声音。17.4kHz 的音调(被称为“蚊音”)是一个经典的测试,通常只有青少年能通过。',
115
+ },
116
+ { type: 'title', text: '波形类型及其用途', level: 3 },
117
+ {
118
+ type: 'paragraph',
119
+ html: '<strong>正弦波:</strong>没有谐波的纯音,用于医疗听力测试和仪器校准。<strong>方波:</strong>富含奇次谐波,听起来像复古 8 位游戏机的声音。<strong>锯齿波:</strong>包含所有谐波,是电子音乐合成器的基础。<strong>三角波:</strong>介于正弦波和方波之间——比方波平滑,但比正弦波具有更多谐波内容。',
120
+ },
121
+ { type: 'title', text: '扬声器测试与振动驱动排水', level: 3 },
122
+ {
123
+ type: 'paragraph',
124
+ html: '以最大音量播放低频波(通常为 <strong>165Hz</strong>)的方波或锯齿波,会迫使扬声器振膜剧烈振动,从而通过机械方式排出积聚在格栅中的水滴。请勿长时间以最大音量播放极高频声音:即使您听不到,能量也可能损坏设备的推特(高音单元)。',
125
+ },
126
+ ],
127
+ ui: {
128
+ badge: '音频发生器',
129
+ title: '频率发生器',
130
+ description: '生成用于音频测试的纯净频率。',
131
+ freqLabel: '频率',
132
+ preset60: '60Hz',
133
+ preset440: '440Hz',
134
+ preset1k: '1kHz',
135
+ rangeMin: '20Hz (超低音)',
136
+ rangeMax: '20kHz (超声波)',
137
+ waveLabel: '波形',
138
+ waveSine: '正弦波',
139
+ waveSquare: '方波',
140
+ waveSawtooth: '锯齿波',
141
+ waveTriangle: '三角波',
142
+ volLabel: '音量',
143
+ btnPlay: '播放音频',
144
+ btnStop: '停止',
145
+ },
146
+ };
@@ -7,10 +7,6 @@ import ToneGeneratorBibliography from './bibliography.astro';
7
7
  import type { ToneGeneratorUI } from './ui';
8
8
  export type ToneGeneratorLocaleContent = ToolLocaleContent<ToneGeneratorUI>;
9
9
 
10
- import { content as es } from './i18n/es';
11
- import { content as en } from './i18n/en';
12
- import { content as fr } from './i18n/fr';
13
-
14
10
  export const toneGenerator: HardwareToolEntry<ToneGeneratorUI> = {
15
11
  id: 'generador-tonos',
16
12
  icons: {
@@ -18,9 +14,21 @@ export const toneGenerator: HardwareToolEntry<ToneGeneratorUI> = {
18
14
  fg: 'mdi:waveform',
19
15
  },
20
16
  i18n: {
21
- es: async () => es,
22
- en: async () => en,
23
- fr: async () => fr,
17
+ de: () => import('./i18n/de').then((m) => m.content),
18
+ en: () => import('./i18n/en').then((m) => m.content),
19
+ es: () => import('./i18n/es').then((m) => m.content),
20
+ fr: () => import('./i18n/fr').then((m) => m.content),
21
+ id: () => import('./i18n/id').then((m) => m.content),
22
+ it: () => import('./i18n/it').then((m) => m.content),
23
+ ja: () => import('./i18n/ja').then((m) => m.content),
24
+ ko: () => import('./i18n/ko').then((m) => m.content),
25
+ nl: () => import('./i18n/nl').then((m) => m.content),
26
+ pl: () => import('./i18n/pl').then((m) => m.content),
27
+ pt: () => import('./i18n/pt').then((m) => m.content),
28
+ ru: () => import('./i18n/ru').then((m) => m.content),
29
+ sv: () => import('./i18n/sv').then((m) => m.content),
30
+ tr: () => import('./i18n/tr').then((m) => m.content),
31
+ zh: () => import('./i18n/zh').then((m) => m.content),
24
32
  },
25
33
  };
26
34
 
package/src/types.ts CHANGED
@@ -5,7 +5,7 @@ export type { SEOSection };
5
5
 
6
6
  export type KnownLocale =
7
7
  | 'ar' | 'da' | 'de' | 'en' | 'es' | 'fi'
8
- | 'fr' | 'it' | 'ja' | 'ko' | 'nb' | 'nl'
8
+ | 'fr' | 'id' | 'it' | 'ja' | 'ko' | 'nb' | 'nl'
9
9
  | 'pl' | 'pt' | 'ru' | 'sv' | 'tr' | 'zh';
10
10
 
11
11
  export interface FAQItem {
@@ -1,50 +0,0 @@
1
- import { StatisticalFilter } from '../logic/StatisticalFilter';
2
- import { MovingAverage } from '../logic/MovingAverage';
3
-
4
- const statisticalFilter = new StatisticalFilter();
5
- const smoothingFilter = new MovingAverage(20);
6
-
7
- let lastTime = 0;
8
- let maxHz = 0;
9
- const history: number[] = [];
10
-
11
- self.onmessage = (event: MessageEvent<{ time: number } | 'reset'>) => {
12
- if (event.data === 'reset') {
13
- lastTime = 0;
14
- return;
15
- }
16
-
17
- const { time } = event.data;
18
-
19
- if (lastTime === 0) {
20
- lastTime = time;
21
- return;
22
- }
23
-
24
- const delta = time - lastTime;
25
- lastTime = time;
26
-
27
- if (delta <= 0 || delta > 100) return;
28
-
29
- const hz = 1000 / delta;
30
-
31
- if (statisticalFilter.isOutlier(hz)) {
32
- return;
33
- }
34
-
35
- const smoothedHz = smoothingFilter.next(hz);
36
-
37
- history.push(hz);
38
- if (history.length > 200) history.shift();
39
-
40
- if (hz > maxHz) maxHz = hz;
41
-
42
- const avgHz = history.reduce((a, b) => a + b, 0) / history.length;
43
-
44
- self.postMessage({
45
- hz,
46
- smoothedHz,
47
- avgHz,
48
- maxHz
49
- });
50
- };