@jjlmoya/utils-hardware 1.27.0 → 1.29.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.
- package/package.json +1 -1
- package/src/category/index.ts +3 -1
- package/src/entries.ts +7 -1
- package/src/index.ts +2 -0
- package/src/tests/locale_completeness.test.ts +1 -1
- package/src/tests/tool_validation.test.ts +1 -1
- package/src/tool/mobileSensorTest/bibliography.astro +14 -0
- package/src/tool/mobileSensorTest/bibliography.ts +24 -0
- package/src/tool/mobileSensorTest/component.astro +241 -0
- package/src/tool/mobileSensorTest/entry.ts +29 -0
- package/src/tool/mobileSensorTest/i18n/de.ts +186 -0
- package/src/tool/mobileSensorTest/i18n/en.ts +186 -0
- package/src/tool/mobileSensorTest/i18n/es.ts +186 -0
- package/src/tool/mobileSensorTest/i18n/fr.ts +186 -0
- package/src/tool/mobileSensorTest/i18n/id.ts +186 -0
- package/src/tool/mobileSensorTest/i18n/it.ts +186 -0
- package/src/tool/mobileSensorTest/i18n/ja.ts +186 -0
- package/src/tool/mobileSensorTest/i18n/ko.ts +186 -0
- package/src/tool/mobileSensorTest/i18n/nl.ts +186 -0
- package/src/tool/mobileSensorTest/i18n/pl.ts +186 -0
- package/src/tool/mobileSensorTest/i18n/pt.ts +186 -0
- package/src/tool/mobileSensorTest/i18n/ru.ts +186 -0
- package/src/tool/mobileSensorTest/i18n/sv.ts +186 -0
- package/src/tool/mobileSensorTest/i18n/tr.ts +186 -0
- package/src/tool/mobileSensorTest/i18n/zh.ts +186 -0
- package/src/tool/mobileSensorTest/index.ts +11 -0
- package/src/tool/mobileSensorTest/logic.ts +39 -0
- package/src/tool/mobileSensorTest/mobile-sensor-test.css +460 -0
- package/src/tool/mobileSensorTest/seo.astro +15 -0
- package/src/tool/mobileSensorTest/ui.ts +31 -0
- package/src/tool/subwooferCrossoverTest/bibliography.astro +14 -0
- package/src/tool/subwooferCrossoverTest/bibliography.ts +16 -0
- package/src/tool/subwooferCrossoverTest/component.astro +253 -0
- package/src/tool/subwooferCrossoverTest/entry.ts +29 -0
- package/src/tool/subwooferCrossoverTest/i18n/de.ts +188 -0
- package/src/tool/subwooferCrossoverTest/i18n/en.ts +188 -0
- package/src/tool/subwooferCrossoverTest/i18n/es.ts +188 -0
- package/src/tool/subwooferCrossoverTest/i18n/fr.ts +188 -0
- package/src/tool/subwooferCrossoverTest/i18n/id.ts +188 -0
- package/src/tool/subwooferCrossoverTest/i18n/it.ts +188 -0
- package/src/tool/subwooferCrossoverTest/i18n/ja.ts +188 -0
- package/src/tool/subwooferCrossoverTest/i18n/ko.ts +188 -0
- package/src/tool/subwooferCrossoverTest/i18n/nl.ts +188 -0
- package/src/tool/subwooferCrossoverTest/i18n/pl.ts +188 -0
- package/src/tool/subwooferCrossoverTest/i18n/pt.ts +188 -0
- package/src/tool/subwooferCrossoverTest/i18n/ru.ts +188 -0
- package/src/tool/subwooferCrossoverTest/i18n/sv.ts +188 -0
- package/src/tool/subwooferCrossoverTest/i18n/tr.ts +188 -0
- package/src/tool/subwooferCrossoverTest/i18n/zh.ts +188 -0
- package/src/tool/subwooferCrossoverTest/index.ts +11 -0
- package/src/tool/subwooferCrossoverTest/logic.ts +30 -0
- package/src/tool/subwooferCrossoverTest/seo.astro +15 -0
- package/src/tool/subwooferCrossoverTest/subwoofer-crossover-test.css +282 -0
- package/src/tool/subwooferCrossoverTest/ui.ts +20 -0
- package/src/tools.ts +3 -1
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
|
|
2
|
+
import type { ToolLocaleContent } from '../../../types';
|
|
3
|
+
import type { SubwooferCrossoverTestUI } from '../ui';
|
|
4
|
+
import { bibliography } from '../bibliography';
|
|
5
|
+
|
|
6
|
+
const slug = 'subwoofer-crossover-test';
|
|
7
|
+
const title = '低音炮分频测试';
|
|
8
|
+
const description =
|
|
9
|
+
'在浏览器中运行从200Hz到10Hz的正弦波扫描,找到低音炮衰减、中断或交接给主音箱的位置。';
|
|
10
|
+
|
|
11
|
+
const faqData = [
|
|
12
|
+
{
|
|
13
|
+
question: '低音炮分频测试测量什么?',
|
|
14
|
+
answer:
|
|
15
|
+
'它帮助您听到主音箱和低音炮之间低音不再连续的点。间隙、突然的电平变化或缺失的频段可能表明分频频率不正确、相位问题、房间抵消或低音炮的极限。',
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
question: '为什么这个测试从200Hz向下扫描到10Hz?',
|
|
19
|
+
answer:
|
|
20
|
+
'大多数家庭影院分频点设置在60Hz到120Hz之间,而许多紧凑型音箱在此范围之上或之下开始失去输出。从200Hz开始扫描,可以在音调到达深沉次低音之前轻松听到音箱到低音炮的交接。',
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
question: '这个在线低音炮低音测试会损坏音箱吗?',
|
|
24
|
+
answer:
|
|
25
|
+
'是的,高音量下的极低频率可能会使小型音箱过载或给低音炮带来压力。从低音量开始,避免增强的低音模式,如果听到嘎嘎声、敲击声或机械压力声,请立即停止。',
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
question: '标记的衰减频率是我应该使用的确切分频设置吗?',
|
|
29
|
+
answer:
|
|
30
|
+
'不是。请将其视为听力线索,而不是实验室测量。最佳分频设置还取决于音箱规格、房间布置、相位、距离校正和校准目标。',
|
|
31
|
+
},
|
|
32
|
+
];
|
|
33
|
+
|
|
34
|
+
const howToData = [
|
|
35
|
+
{
|
|
36
|
+
name: '设置安全的聆听音量',
|
|
37
|
+
text: '首先降低系统音量。扫描使用生成的正弦波,因此即使浏览器音量看起来适中,低音也可能变得强烈。',
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
name: '启动200Hz至10Hz扫描',
|
|
41
|
+
text: '按下开始扫描,从您通常的座位聆听。音调稳定地穿过低音炮、主音箱和房间声学重叠的低音范围。',
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
name: '聆听衰减或交接',
|
|
45
|
+
text: '注意低音变弱、消失、位置改变或在低音炮和主音箱之间听起来不均匀的时刻。',
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
name: '标记频率',
|
|
49
|
+
text: '在第一个明显的问题点按下标记衰减。使用该频率作为调整分频、相位、摆放或房间校正的线索。',
|
|
50
|
+
},
|
|
51
|
+
];
|
|
52
|
+
|
|
53
|
+
const faqSchema: WithContext<FAQPage> = {
|
|
54
|
+
'@context': 'https://schema.org',
|
|
55
|
+
'@type': 'FAQPage',
|
|
56
|
+
mainEntity: faqData.map((item) => ({
|
|
57
|
+
'@type': 'Question',
|
|
58
|
+
name: item.question,
|
|
59
|
+
acceptedAnswer: { '@type': 'Answer', text: item.answer },
|
|
60
|
+
})),
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const howToSchema: WithContext<HowTo> = {
|
|
64
|
+
'@context': 'https://schema.org',
|
|
65
|
+
'@type': 'HowTo',
|
|
66
|
+
name: title,
|
|
67
|
+
description,
|
|
68
|
+
step: howToData.map((step, index) => ({
|
|
69
|
+
'@type': 'HowToStep',
|
|
70
|
+
position: index + 1,
|
|
71
|
+
name: step.name,
|
|
72
|
+
text: step.text,
|
|
73
|
+
})),
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
const appSchema: WithContext<SoftwareApplication> = {
|
|
77
|
+
'@context': 'https://schema.org',
|
|
78
|
+
'@type': 'SoftwareApplication',
|
|
79
|
+
name: title,
|
|
80
|
+
description,
|
|
81
|
+
applicationCategory: 'UtilityApplication',
|
|
82
|
+
operatingSystem: 'All',
|
|
83
|
+
offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' },
|
|
84
|
+
inLanguage: 'zh',
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
export const content: ToolLocaleContent<SubwooferCrossoverTestUI> = {
|
|
88
|
+
slug,
|
|
89
|
+
title,
|
|
90
|
+
description,
|
|
91
|
+
faq: faqData,
|
|
92
|
+
howTo: howToData,
|
|
93
|
+
schemas: [faqSchema, howToSchema, appSchema],
|
|
94
|
+
bibliography,
|
|
95
|
+
seo: [
|
|
96
|
+
{ type: 'title', text: '找到音箱与低音炮之间的低音间隙', level: 2 },
|
|
97
|
+
{
|
|
98
|
+
type: 'paragraph',
|
|
99
|
+
html: '低音炮不应该听起来像角落里一个单独的箱子。当音符从主音箱移动到低音炮时,低音应保持均匀。此测试从<strong>200Hz扫描到10Hz</strong>,让您能够听到交接变得薄弱、轰鸣、可定位或无声的精确区域。',
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
type: 'table',
|
|
103
|
+
headers: ['您听到的', '通常意味着什么', '首先尝试什么'],
|
|
104
|
+
rows: [
|
|
105
|
+
['低音在70-100Hz附近消失', '低音炮和音箱可能在分频点附近相互抵消。', '反转相位,调整距离/延迟,然后重复扫描。'],
|
|
106
|
+
['低音在一个窄带内轰鸣', '房间模式或音箱与低音炮之间重叠过多。', '稍微降低分频点,或移动低音炮/听音位置。'],
|
|
107
|
+
['低音似乎来自低音炮的位置', '分频点可能太高或低音炮电平太高。', '尝试80Hz或更低,并降低低音炮增益。'],
|
|
108
|
+
['深沉低音在30-40Hz以下衰减', '许多低音炮的正常延伸极限,尤其是紧凑型。', '在追查可能是物理性的问题之前,先检查低音炮规格。'],
|
|
109
|
+
],
|
|
110
|
+
},
|
|
111
|
+
{ type: 'title', text: '衰减频率告诉您什么', level: 3 },
|
|
112
|
+
{
|
|
113
|
+
type: 'diagnostic',
|
|
114
|
+
variant: 'info',
|
|
115
|
+
title: '将标记的频率用作调校线索',
|
|
116
|
+
badge: '听力线索',
|
|
117
|
+
html: '<p>如果标记的点接近您的AVR分频点,问题可能在于整合:相位、距离、极性、电平或滤波器的斜率。如果标记的点低得多,您可能听到的是低音炮达到输出极限。如果移动头部时问题变化很大,则是房间主导了结果。</p>',
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
type: 'title',
|
|
121
|
+
text: '常见的分频范围',
|
|
122
|
+
level: 3,
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
type: 'table',
|
|
126
|
+
headers: ['音箱类型', '典型的分频起始点', '原因'],
|
|
127
|
+
rows: [
|
|
128
|
+
['小型卫星音箱', '100-150 Hz', '小箱体通常无法在影院音量下播放干净的中上低音。'],
|
|
129
|
+
['书架式音箱', '70-100 Hz', '通常有足够的低音进行干净的交接,而不会使低音炮可定位。'],
|
|
130
|
+
['落地式音箱', '50-80 Hz', '较大的低音单元可以处理更多的中低音,但房间可能仍倾向于低音炮低音管理。'],
|
|
131
|
+
['THX风格设置', '80 Hz', '一个实用的默认值,适用于许多系统,并将深沉低音路由到低音炮。'],
|
|
132
|
+
],
|
|
133
|
+
},
|
|
134
|
+
{ type: 'title', text: '分频问题还是房间问题?', level: 3 },
|
|
135
|
+
{
|
|
136
|
+
type: 'comparative',
|
|
137
|
+
columns: 2,
|
|
138
|
+
items: [
|
|
139
|
+
{
|
|
140
|
+
title: '分频或相位问题',
|
|
141
|
+
description: '弱点出现在分频频率附近,并且在改变相位、极性、距离或分频设置后会改善。',
|
|
142
|
+
points: ['通常从同一座位可重复。', '通常集中在60-120Hz左右。'],
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
title: '房间抵消',
|
|
146
|
+
description: '当您移动头部、换座位或将低音炮移动一小段距离时,弱点会发生剧烈变化。',
|
|
147
|
+
points: ['非常依赖位置。', '通常通过摆放而非设置来解决。'],
|
|
148
|
+
},
|
|
149
|
+
],
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
type: 'tip',
|
|
153
|
+
title: '运行测试的最佳方式',
|
|
154
|
+
html: '坐在您实际观看电影或听音乐的位置。不要站在低音炮旁边。在箱体旁边听起来不错的分频,在沙发上仍可能留下间隙。',
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
type: 'summary',
|
|
158
|
+
title: '扫描后要更改什么',
|
|
159
|
+
items: [
|
|
160
|
+
'如果间隙接近当前分频点,尝试10Hz的调整并重复扫描。',
|
|
161
|
+
'如果弱带位于分频点附近,尝试低音炮的相位开关或延迟设置。',
|
|
162
|
+
'如果低音在一个座位上变强而在另一个座位上消失,在更改所有AVR设置之前先移动低音炮。',
|
|
163
|
+
'摆放或分频更改后,重新运行房间校正,以便接收器测量新设置。',
|
|
164
|
+
'使用标记的频率指导调校,然后用音乐、电影和熟悉的低音线确认。',
|
|
165
|
+
],
|
|
166
|
+
},
|
|
167
|
+
],
|
|
168
|
+
ui: {
|
|
169
|
+
sweepLabel: '低音炮低频扫描',
|
|
170
|
+
currentFrequency: '当前频率',
|
|
171
|
+
targetFrequency: '目标',
|
|
172
|
+
elapsed: '已用时间',
|
|
173
|
+
statusReady: '准备低频扫描',
|
|
174
|
+
statusRunning: '正在向下扫描',
|
|
175
|
+
statusStopped: '扫描已停止',
|
|
176
|
+
start: '开始扫描',
|
|
177
|
+
stop: '停止扫描',
|
|
178
|
+
markDropout: '标记衰减',
|
|
179
|
+
reset: '重置',
|
|
180
|
+
volume: '输出电平',
|
|
181
|
+
duration: '扫描时长',
|
|
182
|
+
safeStart: '以低音量开始,然后标记低音变得难以听到的第一个频率。',
|
|
183
|
+
roomNote: '房间位置和相位可能会显著改变结果。',
|
|
184
|
+
dropoutLabel: '标记点',
|
|
185
|
+
dropoutEmpty: '尚未标记',
|
|
186
|
+
crossoverEstimate: '估计衰减点',
|
|
187
|
+
},
|
|
188
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ToolDefinition } from '../../types';
|
|
2
|
+
import { subwooferCrossoverTest } from './entry';
|
|
3
|
+
|
|
4
|
+
export * from './entry';
|
|
5
|
+
|
|
6
|
+
export const SUBWOOFER_CROSSOVER_TEST_TOOL: ToolDefinition = {
|
|
7
|
+
entry: subwooferCrossoverTest,
|
|
8
|
+
Component: () => import('./component.astro'),
|
|
9
|
+
SEOComponent: () => import('./seo.astro'),
|
|
10
|
+
BibliographyComponent: () => import('./bibliography.astro'),
|
|
11
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export interface SweepSnapshot {
|
|
2
|
+
frequencyHz: number;
|
|
3
|
+
progress: number;
|
|
4
|
+
elapsedSeconds: number;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export const SWEEP_START_HZ = 200;
|
|
8
|
+
export const SWEEP_END_HZ = 10;
|
|
9
|
+
|
|
10
|
+
export function getExponentialSweepFrequency(
|
|
11
|
+
elapsedSeconds: number,
|
|
12
|
+
durationSeconds: number,
|
|
13
|
+
startHz = SWEEP_START_HZ,
|
|
14
|
+
endHz = SWEEP_END_HZ,
|
|
15
|
+
): SweepSnapshot {
|
|
16
|
+
const safeDuration = Math.max(1, durationSeconds);
|
|
17
|
+
const progress = Math.min(1, Math.max(0, elapsedSeconds / safeDuration));
|
|
18
|
+
const frequencyHz = startHz * Math.pow(endHz / startHz, progress);
|
|
19
|
+
|
|
20
|
+
return {
|
|
21
|
+
frequencyHz,
|
|
22
|
+
progress,
|
|
23
|
+
elapsedSeconds: Math.max(0, elapsedSeconds),
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function formatFrequency(value: number): string {
|
|
28
|
+
if (value >= 100) return `${Math.round(value)} Hz`;
|
|
29
|
+
return `${value.toFixed(1)} Hz`;
|
|
30
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { SEORenderer } from '@jjlmoya/utils-shared';
|
|
3
|
+
import { subwooferCrossoverTest } from './index';
|
|
4
|
+
import type { KnownLocale } from '../../types';
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
locale?: KnownLocale;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const { locale = 'en' } = Astro.props;
|
|
11
|
+
const content = await subwooferCrossoverTest.i18n[locale]?.();
|
|
12
|
+
if (!content) return null;
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
{content.seo?.length > 0 && <SEORenderer content={{ locale, sections: content.seo }} />}
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
.sct-shell {
|
|
2
|
+
--sct-ink: #111827;
|
|
3
|
+
--sct-muted: #667085;
|
|
4
|
+
--sct-panel: rgba(255, 255, 255, 0.74);
|
|
5
|
+
--sct-panel-strong: rgba(255, 255, 255, 0.94);
|
|
6
|
+
--sct-line: rgba(15, 23, 42, 0.14);
|
|
7
|
+
--sct-a: #00a3ff;
|
|
8
|
+
--sct-b: #ff2e63;
|
|
9
|
+
--sct-c: #f7c948;
|
|
10
|
+
--sct-shadow: rgba(15, 23, 42, 0.16);
|
|
11
|
+
|
|
12
|
+
color: var(--sct-ink);
|
|
13
|
+
width: 100%;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.theme-dark .sct-shell {
|
|
17
|
+
--sct-ink: #f8fafc;
|
|
18
|
+
--sct-muted: #a8b3c7;
|
|
19
|
+
--sct-panel: rgba(15, 23, 42, 0.7);
|
|
20
|
+
--sct-panel-strong: rgba(2, 6, 23, 0.92);
|
|
21
|
+
--sct-line: rgba(226, 232, 240, 0.2);
|
|
22
|
+
--sct-shadow: rgba(0, 0, 0, 0.45);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.sct-console {
|
|
26
|
+
position: relative;
|
|
27
|
+
overflow: hidden;
|
|
28
|
+
border: 1px solid var(--sct-line);
|
|
29
|
+
border-radius: 8px;
|
|
30
|
+
padding: clamp(1rem, 3vw, 1.6rem);
|
|
31
|
+
background:
|
|
32
|
+
radial-gradient(circle at 20% 20%, rgba(0, 163, 255, 0.22), transparent 28%),
|
|
33
|
+
radial-gradient(circle at 84% 10%, rgba(255, 46, 99, 0.18), transparent 26%),
|
|
34
|
+
linear-gradient(135deg, rgba(248, 250, 252, 0.92), rgba(226, 232, 240, 0.56));
|
|
35
|
+
box-shadow: 0 18px 46px var(--sct-shadow);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.theme-dark .sct-console {
|
|
39
|
+
background:
|
|
40
|
+
radial-gradient(circle at 20% 20%, rgba(0, 163, 255, 0.18), transparent 28%),
|
|
41
|
+
radial-gradient(circle at 84% 10%, rgba(255, 46, 99, 0.14), transparent 26%),
|
|
42
|
+
linear-gradient(135deg, rgba(2, 6, 23, 0.96), rgba(15, 23, 42, 0.76));
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.sct-stage {
|
|
46
|
+
display: grid;
|
|
47
|
+
grid-template-columns: minmax(8rem, 0.9fr) minmax(0, 1.4fr);
|
|
48
|
+
gap: clamp(1rem, 4vw, 2rem);
|
|
49
|
+
align-items: stretch;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.sct-orbit,
|
|
53
|
+
.sct-frequency-panel,
|
|
54
|
+
.sct-result,
|
|
55
|
+
.sct-slider-wrap {
|
|
56
|
+
border: 1px solid var(--sct-line);
|
|
57
|
+
background: var(--sct-panel);
|
|
58
|
+
backdrop-filter: blur(18px);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.sct-orbit {
|
|
62
|
+
position: relative;
|
|
63
|
+
min-height: 16rem;
|
|
64
|
+
border-radius: 8px;
|
|
65
|
+
display: grid;
|
|
66
|
+
place-items: center;
|
|
67
|
+
overflow: hidden;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.sct-ring {
|
|
71
|
+
position: absolute;
|
|
72
|
+
border: 2px solid rgba(0, 163, 255, 0.35);
|
|
73
|
+
border-radius: 50%;
|
|
74
|
+
transform: scale(0.7);
|
|
75
|
+
opacity: 0.78;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.sct-ring-a {
|
|
79
|
+
width: 82%;
|
|
80
|
+
aspect-ratio: 1;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.sct-ring-b {
|
|
84
|
+
width: 58%;
|
|
85
|
+
aspect-ratio: 1;
|
|
86
|
+
border-color: rgba(255, 46, 99, 0.34);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.is-running .sct-ring-a {
|
|
90
|
+
animation: sct-pulse 1.3s ease-out infinite;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.is-running .sct-ring-b {
|
|
94
|
+
animation: sct-pulse 1.3s ease-out infinite 0.32s;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.sct-driver {
|
|
98
|
+
z-index: 1;
|
|
99
|
+
width: min(8.2rem, 56%);
|
|
100
|
+
aspect-ratio: 1;
|
|
101
|
+
border: 1px solid var(--sct-line);
|
|
102
|
+
border-radius: 50%;
|
|
103
|
+
display: grid;
|
|
104
|
+
place-items: center;
|
|
105
|
+
background: radial-gradient(circle, var(--sct-panel-strong) 0 45%, rgba(0, 163, 255, 0.16) 46% 65%, rgba(17, 24, 39, 0.1) 66%);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.sct-speaker-icon {
|
|
109
|
+
width: 3.2rem;
|
|
110
|
+
height: 3.2rem;
|
|
111
|
+
color: var(--sct-a);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.sct-frequency-panel {
|
|
115
|
+
border-radius: 8px;
|
|
116
|
+
padding: clamp(1rem, 4vw, 2rem);
|
|
117
|
+
display: flex;
|
|
118
|
+
flex-direction: column;
|
|
119
|
+
justify-content: center;
|
|
120
|
+
gap: 1rem;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.sct-status,
|
|
124
|
+
.sct-result-label {
|
|
125
|
+
color: var(--sct-muted);
|
|
126
|
+
font-size: 0.78rem;
|
|
127
|
+
font-weight: 800;
|
|
128
|
+
letter-spacing: 0.08em;
|
|
129
|
+
text-transform: uppercase;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.sct-frequency {
|
|
133
|
+
display: block;
|
|
134
|
+
font-size: clamp(3.3rem, 16vw, 8.5rem);
|
|
135
|
+
font-weight: 950;
|
|
136
|
+
line-height: 0.9;
|
|
137
|
+
letter-spacing: 0;
|
|
138
|
+
color: var(--sct-ink);
|
|
139
|
+
text-shadow: 0 0 28px rgba(0, 163, 255, 0.22);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.sct-meter {
|
|
143
|
+
height: 0.8rem;
|
|
144
|
+
border-radius: 8px;
|
|
145
|
+
background: rgba(15, 23, 42, 0.12);
|
|
146
|
+
overflow: hidden;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.sct-meter-fill {
|
|
150
|
+
display: block;
|
|
151
|
+
width: 100%;
|
|
152
|
+
height: 100%;
|
|
153
|
+
transform-origin: left center;
|
|
154
|
+
background: linear-gradient(90deg, var(--sct-b), var(--sct-c), var(--sct-a));
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.sct-readouts,
|
|
158
|
+
.sct-controls,
|
|
159
|
+
.sct-tuning {
|
|
160
|
+
display: grid;
|
|
161
|
+
gap: 0.75rem;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.sct-readouts {
|
|
165
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
166
|
+
color: var(--sct-muted);
|
|
167
|
+
font-size: 0.92rem;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
.sct-controls {
|
|
171
|
+
grid-template-columns: 1.1fr 1.1fr 0.72fr;
|
|
172
|
+
margin-top: 1rem;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
.sct-primary,
|
|
176
|
+
.sct-secondary,
|
|
177
|
+
.sct-ghost {
|
|
178
|
+
min-height: 3.2rem;
|
|
179
|
+
border: 1px solid var(--sct-line);
|
|
180
|
+
border-radius: 8px;
|
|
181
|
+
cursor: pointer;
|
|
182
|
+
display: inline-flex;
|
|
183
|
+
align-items: center;
|
|
184
|
+
justify-content: center;
|
|
185
|
+
gap: 0.55rem;
|
|
186
|
+
font-weight: 850;
|
|
187
|
+
color: var(--sct-ink);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
.sct-primary {
|
|
191
|
+
color: #fff;
|
|
192
|
+
background: linear-gradient(135deg, #07f, #00b8ff);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
.sct-primary[data-playing="true"] {
|
|
196
|
+
background: linear-gradient(135deg, #ff2e63, #be123c);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
.sct-secondary {
|
|
200
|
+
background: var(--sct-panel-strong);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
.sct-secondary:disabled {
|
|
204
|
+
cursor: not-allowed;
|
|
205
|
+
opacity: 0.48;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
.sct-ghost {
|
|
209
|
+
background: transparent;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
.sct-button-icon {
|
|
213
|
+
width: 1.25rem;
|
|
214
|
+
height: 1.25rem;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
.sct-tuning {
|
|
218
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
219
|
+
margin-top: 0.75rem;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
.sct-slider-wrap {
|
|
223
|
+
border-radius: 8px;
|
|
224
|
+
padding: 0.85rem;
|
|
225
|
+
color: var(--sct-muted);
|
|
226
|
+
font-weight: 750;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
.sct-slider {
|
|
230
|
+
width: 100%;
|
|
231
|
+
margin-top: 0.6rem;
|
|
232
|
+
accent-color: var(--sct-a);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
.sct-result {
|
|
236
|
+
margin-top: 0.75rem;
|
|
237
|
+
border-radius: 8px;
|
|
238
|
+
padding: 1rem;
|
|
239
|
+
display: grid;
|
|
240
|
+
grid-template-columns: minmax(0, 0.7fr) minmax(0, 1.3fr);
|
|
241
|
+
gap: 1rem;
|
|
242
|
+
align-items: center;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
.sct-result strong {
|
|
246
|
+
display: block;
|
|
247
|
+
margin-top: 0.18rem;
|
|
248
|
+
font-size: 1.45rem;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
.sct-result p {
|
|
252
|
+
margin: 0;
|
|
253
|
+
color: var(--sct-muted);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
@keyframes sct-pulse {
|
|
257
|
+
from {
|
|
258
|
+
opacity: 0.9;
|
|
259
|
+
transform: scale(0.42);
|
|
260
|
+
}
|
|
261
|
+
to {
|
|
262
|
+
opacity: 0;
|
|
263
|
+
transform: scale(1.18);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
@media (max-width: 760px) {
|
|
268
|
+
.sct-stage,
|
|
269
|
+
.sct-controls,
|
|
270
|
+
.sct-tuning,
|
|
271
|
+
.sct-result {
|
|
272
|
+
grid-template-columns: 1fr;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
.sct-orbit {
|
|
276
|
+
min-height: 12rem;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
.sct-readouts {
|
|
280
|
+
grid-template-columns: 1fr;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface SubwooferCrossoverTestUI extends Record<string, string> {
|
|
2
|
+
sweepLabel: string;
|
|
3
|
+
currentFrequency: string;
|
|
4
|
+
targetFrequency: string;
|
|
5
|
+
elapsed: string;
|
|
6
|
+
statusReady: string;
|
|
7
|
+
statusRunning: string;
|
|
8
|
+
statusStopped: string;
|
|
9
|
+
start: string;
|
|
10
|
+
stop: string;
|
|
11
|
+
markDropout: string;
|
|
12
|
+
reset: string;
|
|
13
|
+
volume: string;
|
|
14
|
+
duration: string;
|
|
15
|
+
safeStart: string;
|
|
16
|
+
roomNote: string;
|
|
17
|
+
dropoutLabel: string;
|
|
18
|
+
dropoutEmpty: string;
|
|
19
|
+
crossoverEstimate: string;
|
|
20
|
+
}
|
package/src/tools.ts
CHANGED
|
@@ -18,5 +18,7 @@ import { WEB_BLUETOOTH_BLE_SCANNER_TOOL } from './tool/webBluetoothBleScanner/in
|
|
|
18
18
|
import { KEYBOARD_CHATTER_TEST_TOOL } from './tool/keyboardChatterTest/index';
|
|
19
19
|
import { WEB_USB_SERIAL_MONITOR_TOOL } from './tool/webUsbSerialMonitor/index';
|
|
20
20
|
import { USB_POWER_BUDGET_CALCULATOR_TOOL } from './tool/usbPowerBudgetCalculator/index';
|
|
21
|
+
import { MOBILE_SENSOR_TEST_TOOL } from './tool/mobileSensorTest/index';
|
|
22
|
+
import { SUBWOOFER_CROSSOVER_TEST_TOOL } from './tool/subwooferCrossoverTest/index';
|
|
21
23
|
|
|
22
|
-
export const ALL_TOOLS: ToolDefinition[] = [PIXELES_PANTALLA_TOOL, TEST_TECLADO_TOOL, KEYBOARD_CHATTER_TEST_TOOL, TEST_MANDO_TOOL, PROBADOR_VIBRACION_MANDO_TOOL, TEST_RATON_TOOL, MOUSE_DOUBLE_CLICK_TEST_TOOL, MOUSE_SCROLL_TEST_TOOL, ESTIMADOR_SALUD_BATERIA_TOOL, TONE_GENERATOR_TOOL, REFRESH_RATE_DETECTOR_TOOL, MONITOR_GHOSTING_TEST_TOOL, SPECTRUM_CANVAS_TOOL, UPS_RUNTIME_CALCULATOR_TOOL, USB_POWER_BUDGET_CALCULATOR_TOOL, STEREO_AUDIO_TEST_TOOL, WEB_BLUETOOTH_BLE_SCANNER_TOOL, WEB_USB_SERIAL_MONITOR_TOOL];
|
|
24
|
+
export const ALL_TOOLS: ToolDefinition[] = [PIXELES_PANTALLA_TOOL, TEST_TECLADO_TOOL, KEYBOARD_CHATTER_TEST_TOOL, TEST_MANDO_TOOL, PROBADOR_VIBRACION_MANDO_TOOL, TEST_RATON_TOOL, MOUSE_DOUBLE_CLICK_TEST_TOOL, MOUSE_SCROLL_TEST_TOOL, ESTIMADOR_SALUD_BATERIA_TOOL, TONE_GENERATOR_TOOL, SUBWOOFER_CROSSOVER_TEST_TOOL, REFRESH_RATE_DETECTOR_TOOL, MONITOR_GHOSTING_TEST_TOOL, SPECTRUM_CANVAS_TOOL, UPS_RUNTIME_CALCULATOR_TOOL, USB_POWER_BUDGET_CALCULATOR_TOOL, MOBILE_SENSOR_TEST_TOOL, STEREO_AUDIO_TEST_TOOL, WEB_BLUETOOTH_BLE_SCANNER_TOOL, WEB_USB_SERIAL_MONITOR_TOOL];
|