@yunlefun-home/air-conditioner-core 0.2.0 → 0.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.
package/dist/index.d.cts CHANGED
@@ -1,6 +1,24 @@
1
1
  //#region src/types.d.ts
2
- type AcMode = 'cold' | 'hot';
3
- interface AcState {
2
+ export type AcMode = 'cold' | 'hot';
3
+ /**
4
+ * Sound mode: `normal` plays everything, `sleep` lowers the volume,
5
+ * `mute` silences the air conditioner.
6
+ */
7
+ export type AcSoundMode = 'normal' | 'sleep' | 'mute';
8
+ /**
9
+ * Temperature range a device supports. Real devices (e.g. Home Assistant
10
+ * climate entities) report their own range and step.
11
+ */
12
+ export interface AcLimits {
13
+ min: number;
14
+ max: number;
15
+ step: number;
16
+ }
17
+ /**
18
+ * Visual tone of the unit: idle when off, otherwise follows the mode.
19
+ */
20
+ export type AcTone = 'idle' | 'cool' | 'heat';
21
+ export interface AcState {
4
22
  /**
5
23
  * Whether the air conditioner is powered on.
6
24
  */
@@ -13,72 +31,136 @@ interface AcState {
13
31
  * Target temperature in Celsius.
14
32
  */
15
33
  temperature: number;
34
+ /**
35
+ * Sound mode. States saved before this field existed fall back to `normal`.
36
+ */
37
+ sound: AcSoundMode;
16
38
  }
17
- type AcAction = {
18
- type: 'increment' | 'decrement' | 'toggleStatus';
39
+ export type AcAction = {
40
+ type: 'increment' | 'decrement' | 'toggleStatus' | 'cycleSound';
19
41
  } | {
20
42
  type: 'status';
21
43
  status: AcState['status'];
22
44
  } | {
23
45
  type: 'mode';
24
46
  mode: AcState['mode'];
47
+ } | {
48
+ type: 'sound';
49
+ sound: AcState['sound'];
25
50
  } | {
26
51
  type: 'update';
27
52
  payload: Partial<AcState>;
28
53
  };
29
- type AcNotificationSeverity = 'success' | 'error' | 'info';
30
- interface AcNotification {
54
+ export type AcNotificationSeverity = 'success' | 'error' | 'info';
55
+ export interface AcNotification {
31
56
  message: string;
32
57
  severity: AcNotificationSeverity;
33
58
  }
34
- interface AcChangeEvent {
59
+ export interface AcChangeEvent {
35
60
  action: AcAction;
36
61
  previousState: AcState;
37
62
  state: AcState;
38
63
  notification?: AcNotification;
39
64
  }
40
- type AcStoreListener = (event: AcChangeEvent) => void;
41
- interface AcStorage {
65
+ export type AcStoreListener = (event: AcChangeEvent) => void;
66
+ export interface AcStorage {
42
67
  getItem: (key: string) => string | null;
43
68
  setItem: (key: string, value: string) => void;
44
69
  removeItem?: (key: string) => void;
45
70
  }
46
- interface CreateAirConditionerStoreOptions {
71
+ export interface CreateAirConditionerStoreOptions {
47
72
  initialState?: Partial<AcState>;
73
+ /**
74
+ * Device temperature limits. Defaults to 16–31 °C with a step of 1.
75
+ */
76
+ limits?: AcLimits;
48
77
  storage?: AcStorage | null;
49
78
  storageKey?: string;
50
79
  onNotify?: (notification: AcNotification, event: AcChangeEvent) => void;
51
80
  }
52
- interface AirConditionerStore {
81
+ export interface AirConditionerStore {
53
82
  getState: () => AcState;
54
83
  dispatch: (action: AcAction) => AcChangeEvent;
55
84
  subscribe: (listener: AcStoreListener) => () => void;
56
85
  }
57
- interface AcAudioElement {
86
+ /**
87
+ * The subset of `HTMLAudioElement` the audio controller uses. The optional
88
+ * members let it pause, loop and set volume when they exist.
89
+ */
90
+ export interface AcAudioElement {
58
91
  currentTime: number;
59
92
  load: () => void;
60
93
  play: () => Promise<unknown> | unknown;
94
+ pause?: () => void;
95
+ volume?: number;
96
+ muted?: boolean;
97
+ loop?: boolean;
98
+ /** Used to fetch the file for Web Audio playback. */
99
+ src?: string;
100
+ currentSrc?: string;
61
101
  }
62
- interface AcAudioElements {
102
+ export interface AcAudioElements {
63
103
  start: AcAudioElement | null;
64
104
  work: AcAudioElement | null;
65
105
  beep?: AcAudioElement | null;
66
106
  }
67
- interface AcAudioController {
107
+ export interface AcAudioController {
68
108
  beep: () => void;
69
109
  toggleStatusAudio: (previousStatus: boolean) => void;
110
+ /**
111
+ * Change the volume of everything, including sounds already playing.
112
+ */
113
+ setSoundMode: (mode: AcSoundMode) => void;
70
114
  dispose: () => void;
71
115
  }
116
+ export interface CreateAcAudioControllerOptions {
117
+ /**
118
+ * Initial sound mode.
119
+ * @default 'normal'
120
+ */
121
+ soundMode?: AcSoundMode;
122
+ /**
123
+ * Play through the Web Audio API for a gapless loop and smooth fades.
124
+ * Falls back to the `<audio>` elements when the API is missing or the
125
+ * files cannot be fetched (for example across origins without CORS).
126
+ * @default true
127
+ */
128
+ webAudio?: boolean;
129
+ /**
130
+ * Create the `AudioContext`. Defaults to `new AudioContext()`.
131
+ */
132
+ createAudioContext?: () => AudioContext;
133
+ /**
134
+ * Fetch an audio file. Defaults to `fetch(url)`.
135
+ */
136
+ loadAudioData?: (url: string) => Promise<ArrayBuffer>;
137
+ /**
138
+ * Random source for the fan's quiet / busy cycle. Defaults to `Math.random`.
139
+ */
140
+ random?: () => number;
141
+ }
72
142
  //#endregion
73
143
  //#region src/audio.d.ts
74
- declare function createAcAudioController(elements: AcAudioElements): AcAudioController;
144
+ /**
145
+ * 空调音效:按键「嘀」声、开机启动声与持续的风声。
146
+ *
147
+ * 默认通过 Web Audio API 播放:风声无缝循环,开关机淡入淡出,运行一段时间后
148
+ * 风声变小、并不定时随压缩机发力起伏。环境不支持或音频无法获取时退回
149
+ * `<audio>` 元素。
150
+ *
151
+ * 需在用户交互(点击遥控器)里首次调用,浏览器才允许发声。
152
+ *
153
+ * @param elements 三个音频元素;Web Audio 会从它们的 `src` 获取音频
154
+ * @param options 声音模式与可替换的环境依赖
155
+ */
156
+ export declare function createAcAudioController(elements: AcAudioElements, options?: CreateAcAudioControllerOptions): AcAudioController;
75
157
  //#endregion
76
158
  //#region src/constants.d.ts
77
- declare const acStorageKey = "ac:state";
159
+ export declare const acStorageKey = "ac:state";
78
160
  /**
79
161
  * 各模式对应的显示图标(供各框架视图层复用)。
80
162
  */
81
- declare const acModeIcons: Record<AcMode, string>;
163
+ export declare const acModeIcons: Record<AcMode, string>;
82
164
  /**
83
165
  * 默认音频资源文件名(不含扩展名)。
84
166
  *
@@ -86,20 +168,55 @@ declare const acModeIcons: Record<AcMode, string>;
86
168
  * - `start` 空调启动声
87
169
  * - `work` 持续工作(出风)声
88
170
  */
89
- declare const acAudioFileNames: {
171
+ export declare const acAudioFileNames: {
90
172
  readonly beep: "di";
91
173
  readonly start: "ac-work";
92
174
  readonly work: "air-extractor-fan";
93
175
  };
94
- declare const minTemperature = 16;
95
- declare const maxTemperature = 31;
96
- declare const recommendedColdTemperature = 26;
97
- declare const recommendedHotTemperature = 20;
98
- declare const defaultAcState: AcState;
99
- declare const soundTimings: {
176
+ export declare const minTemperature = 16;
177
+ export declare const maxTemperature = 31;
178
+ export declare const defaultAcLimits: AcLimits;
179
+ export declare const recommendedColdTemperature = 26;
180
+ export declare const recommendedHotTemperature = 20;
181
+ export declare const defaultAcState: AcState;
182
+ /**
183
+ * 遥控器「声音」键依次切换的顺序。
184
+ */
185
+ export declare const acSoundModes: readonly AcSoundMode[];
186
+ export declare const acSoundModeLabels: Record<AcSoundMode, string>;
187
+ /**
188
+ * 各声音模式的总音量(0–1)。
189
+ */
190
+ export declare const acSoundVolumes: Record<AcSoundMode, number>;
191
+ export declare function isAcSoundMode(value: unknown): value is AcSoundMode;
192
+ /**
193
+ * 声音键的下一个模式:标准 → 睡眠 → 静音 → 标准。
194
+ */
195
+ export declare function nextAcSoundMode(mode: AcSoundMode | undefined): AcSoundMode;
196
+ /**
197
+ * 音效时序。时长单位为毫秒,`*Level` 是风声相对音量(0–1)。
198
+ */
199
+ export declare const soundTimings: {
200
+ /** 开机后多久接上持续的风声(启动声约 9 秒) */
100
201
  readonly startDelayMs: 8000;
101
- readonly noiseStartTime: 2;
102
- readonly noiseDuration: 56;
202
+ /** 风声循环首尾的交叉淡化时长 */
203
+ readonly loopCrossfadeMs: 1500;
204
+ /** 关机时声音淡出时长 */
205
+ readonly stopFadeMs: 600;
206
+ /** 开机运行多久后室温达标、风声降下来 */
207
+ readonly settleAfterMs: 90000;
208
+ /** 风声降下来的渐变时长 */
209
+ readonly settleRampMs: 20000;
210
+ /** 达标后的安静风声 */
211
+ readonly settleLevel: 0.5;
212
+ /** 室温回升、压缩机重新发力时的风声 */
213
+ readonly surgeLevel: 0.85;
214
+ /** 两次发力之间安静运行的时长范围 */
215
+ readonly quietDurationMs: readonly [180000, 360000];
216
+ /** 每次发力持续的时长范围 */
217
+ readonly surgeDurationMs: readonly [60000, 120000];
218
+ /** 发力 / 回落的渐变时长 */
219
+ readonly surgeRampMs: 10000;
103
220
  };
104
221
  /**
105
222
  * 根据基础路径解析出三个音频文件的完整 URL。
@@ -109,26 +226,297 @@ declare const soundTimings: {
109
226
  * @param baseUrl 音频目录,如 `/assets/audio`
110
227
  * @param ext 文件扩展名,默认 `m4a`
111
228
  */
112
- declare function resolveAcAudioAssets(baseUrl?: string, ext?: string): {
229
+ export declare function resolveAcAudioAssets(baseUrl?: string, ext?: string): {
113
230
  beep: string;
114
231
  start: string;
115
232
  work: string;
116
233
  };
117
234
  //#endregion
235
+ //#region src/layout.d.ts
236
+ /**
237
+ * 机身的设计尺寸(px),约 3:1,接近真实壁挂机(如 800–900mm × 280–300mm)的比例。
238
+ * 窄容器下按比例整体缩放,保持「长款」外观不被压扁。
239
+ *
240
+ * - `compact`:Vue / React 组件库 / Web Component 使用的 360 × 128 机身
241
+ * - `wide`:React 主站使用的 600 × 200 机身
242
+ */
243
+ export declare const acShellSize: {
244
+ readonly compact: {
245
+ readonly width: 360;
246
+ readonly height: 128;
247
+ };
248
+ readonly wide: {
249
+ readonly width: 600;
250
+ readonly height: 200;
251
+ };
252
+ };
253
+ /**
254
+ * 根据可用宽度计算机身缩放比例:只缩小、不放大。
255
+ */
256
+ export declare function getAcScale(availableWidth: number, designWidth: number): number;
257
+ /**
258
+ * 监听容器宽度变化并回调缩放比例。
259
+ *
260
+ * 不支持 `ResizeObserver` 的环境(如 SSR)直接返回空的清理函数,保持 1 倍显示。
261
+ *
262
+ * @param target 被测量宽度的容器(不要传被缩放的元素本身)
263
+ * @param designWidth 机身的设计宽度
264
+ * @param onScale 比例变化时的回调
265
+ * @returns 停止监听的清理函数
266
+ */
267
+ export declare function observeAcScale(target: Element, designWidth: number, onScale: (scale: number) => void): () => void;
268
+ /** 指针跟随倾斜的最大角度(deg) */
269
+ export declare const acMaxTilt = 4;
270
+ /**
271
+ * 指针在元素上移动时回调轻微的 3D 倾斜角度(`rotateX` / `rotateY`,单位 deg),离开时回到 0。
272
+ *
273
+ * 仅在有悬停能力的精细指针(鼠标 / 触控板)上启用;`prefers-reduced-motion: reduce`、
274
+ * 触屏或 SSR 下直接返回空的清理函数。
275
+ *
276
+ * @returns 停止监听的清理函数
277
+ */
278
+ export declare function observeAcTilt(target: HTMLElement, onTilt: (rotateX: number, rotateY: number) => void, maxTilt?: number): () => void;
279
+ //#endregion
280
+ //#region src/motion.d.ts
281
+ /**
282
+ * 动效 token:各框架视图层共用的时长与缓动曲线。
283
+ *
284
+ * 样式里统一通过 CSS 变量(`--acw-motion-*`)引用,
285
+ * 需要在 JS 里计时的地方(如 React 过渡组件)直接读取 `acMotion`。
286
+ */
287
+ export declare const acMotion: {
288
+ readonly duration: {
289
+ /** 按下反馈 */
290
+ readonly instant: 90;
291
+ /** 悬停、指示灯、图标 */
292
+ readonly fast: 160;
293
+ /** 显示屏、数字切换、提示 */
294
+ readonly base: 240;
295
+ /** 导风板、出风淡入淡出 */
296
+ readonly slow: 420;
297
+ /** 出风气流单次循环 */
298
+ readonly flow: 1800;
299
+ };
300
+ readonly easing: {
301
+ /** 常规状态切换 */
302
+ readonly standard: "cubic-bezier(0.2, 0, 0, 1)";
303
+ /** 进入:快起慢停 */
304
+ readonly enter: "cubic-bezier(0, 0, 0, 1)";
305
+ /** 退出:慢起快走 */
306
+ readonly exit: "cubic-bezier(0.3, 0, 1, 1)";
307
+ /** 轻微回弹(按钮松开、图标弹出) */
308
+ readonly spring: "cubic-bezier(0.34, 1.56, 0.64, 1)";
309
+ };
310
+ };
311
+ export type AcMotionDuration = keyof typeof acMotion.duration;
312
+ export type AcMotionEasing = keyof typeof acMotion.easing;
313
+ /**
314
+ * `prefers-reduced-motion: reduce` 时使用的时长:
315
+ * 保留短促的淡入淡出(不涉及位移),去掉较长的过渡;循环动画由各样式表自行关闭。
316
+ */
317
+ export declare const acReducedMotionDuration: Record<AcMotionDuration, number>;
318
+ export declare const acReducedMotionQuery = "(prefers-reduced-motion: reduce)";
319
+ /**
320
+ * 当前环境是否要求减少动效(SSR / 无 matchMedia 时返回 `false`)。
321
+ */
322
+ export declare function prefersReducedMotion(): boolean;
323
+ /**
324
+ * 生成动效 CSS 变量声明(含 reduced-motion 覆盖),供 Shadow DOM 注入或样式表同步使用。
325
+ *
326
+ * @param selector 变量挂载的选择器,如 `:root`、`:host`
327
+ */
328
+ export declare function renderAcMotionCssVars(selector?: string): string;
329
+ //#endregion
118
330
  //#region src/reducer.d.ts
119
- declare function normalizeAcState(state: Partial<AcState> | undefined): AcState;
120
- declare function clampTemperature(temperature: number): number;
121
- declare function acReducer(state: AcState, action: AcAction): AcState;
122
- declare function getRecommendedTemperatureMessage(mode: AcState['mode'], temperature: number): string;
123
- declare function getAcActionNotification(previousState: AcState, nextState: AcState, action: AcAction): AcNotification | undefined;
331
+ /**
332
+ * Merge a partial state over the defaults and clamp its temperature.
333
+ *
334
+ * @param state - Partial or stored state
335
+ * @param limits - Device limits; omit to keep the default 16–31 °C range
336
+ */
337
+ export declare function normalizeAcState(state: Partial<AcState> | undefined, limits?: AcLimits): AcState;
338
+ /**
339
+ * Clamp a temperature into range. When `limits` are given the value also
340
+ * snaps to the device step, measured from `limits.min`.
341
+ *
342
+ * @param temperature - Requested temperature in Celsius
343
+ * @param limits - Device limits; omit to clamp to 16–31 °C without snapping
344
+ */
345
+ export declare function clampTemperature(temperature: number, limits?: AcLimits): number;
346
+ /**
347
+ * Apply an action to the state.
348
+ *
349
+ * @param state - Current state
350
+ * @param action - Action to apply
351
+ * @param limits - Device limits; increments use `limits.step`
352
+ */
353
+ export declare function acReducer(state: AcState, action: AcAction, limits?: AcLimits): AcState;
354
+ export declare function getRecommendedTemperatureMessage(mode: AcState['mode'], temperature: number): string;
355
+ export declare function getSoundModeMessage(sound: AcState['sound']): string;
356
+ /**
357
+ * Visual tone for a state: `idle` when off, otherwise `cool` or `heat`.
358
+ *
359
+ * @param state - Current state
360
+ */
361
+ export declare function acTone(state: Pick<AcState, 'status' | 'mode'>): AcTone;
362
+ export declare function getAcActionNotification(previousState: AcState, nextState: AcState, action: AcAction, limits?: AcLimits): AcNotification | undefined;
124
363
  //#endregion
125
364
  //#region src/storage.d.ts
126
- declare function readAcState(storage: AcStorage | null | undefined, storageKey: string): AcState;
127
- declare function writeAcState(storage: AcStorage | null | undefined, storageKey: string, state: AcState): void;
128
- declare function createMemoryStorage(initialValue?: Record<string, string>): AcStorage;
129
- declare function getBrowserStorage(): AcStorage | null;
365
+ export declare function readAcState(storage: AcStorage | null | undefined, storageKey: string): AcState;
366
+ export declare function writeAcState(storage: AcStorage | null | undefined, storageKey: string, state: AcState): void;
367
+ export declare function createMemoryStorage(initialValue?: Record<string, string>): AcStorage;
368
+ export declare function getBrowserStorage(): AcStorage | null;
130
369
  //#endregion
131
370
  //#region src/store.d.ts
132
- declare function createAirConditionerStore(options?: CreateAirConditionerStoreOptions): AirConditionerStore;
371
+ export declare function createAirConditionerStore(options?: CreateAirConditionerStoreOptions): AirConditionerStore;
372
+ //#endregion
373
+ //#region src/thermal/types.d.ts
374
+ /**
375
+ * Heat levels shared by the browser Compute Pressure API and macOS
376
+ * `ProcessInfo.ThermalState`, so web and native hosts speak the same language.
377
+ */
378
+ export type HeatLevel = 'nominal' | 'fair' | 'serious' | 'critical';
379
+ export interface HeatReading {
380
+ level: HeatLevel;
381
+ /** Real temperature, only when the source can measure one */
382
+ celsius?: number;
383
+ /** Identifier of the source that produced the reading */
384
+ source: string;
385
+ /** Epoch milliseconds */
386
+ at: number;
387
+ }
388
+ /**
389
+ * Something that reports how hot a computer is.
390
+ */
391
+ export interface HeatSource {
392
+ id: string;
393
+ /** Whether the current environment can provide readings */
394
+ isSupported: () => boolean;
395
+ /**
396
+ * Start delivering readings.
397
+ *
398
+ * @returns A function that stops the source
399
+ */
400
+ start: (listener: (reading: HeatReading) => void) => () => void;
401
+ }
402
+ /**
403
+ * What the virtual air conditioner should do for a heat level.
404
+ */
405
+ export interface CoolingPlan {
406
+ status: true;
407
+ mode: 'cold';
408
+ temperature: number;
409
+ /** 0–1, drives airflow intensity */
410
+ airflow: number;
411
+ }
412
+ //#endregion
413
+ //#region src/thermal/levels.d.ts
414
+ export declare const heatLevels: readonly HeatLevel[];
415
+ /** Default Celsius thresholds for fair, serious and critical. */
416
+ export declare const defaultHeatThresholds: readonly [number, number, number];
417
+ /**
418
+ * @param level - A heat level
419
+ * @returns Its rank from 0 (nominal) to 3 (critical)
420
+ */
421
+ export declare function heatLevelRank(level: HeatLevel): number;
422
+ export declare function isHeatLevel(value: unknown): value is HeatLevel;
423
+ /**
424
+ * Convert a temperature to a heat level. With a previous level, the value
425
+ * must fall `hysteresis` degrees below a threshold before dropping a level,
426
+ * which keeps readings near a threshold from flickering.
427
+ *
428
+ * @param celsius - Measured temperature
429
+ * @param thresholds - Lower bounds for fair, serious and critical
430
+ * @param previous - Level from the previous reading
431
+ * @param hysteresis - Degrees required below a threshold to step down
432
+ */
433
+ export declare function celsiusToHeatLevel(celsius: number, thresholds?: readonly [number, number, number], previous?: HeatLevel, hysteresis?: number): HeatLevel;
434
+ /**
435
+ * Create a filter that raises the level immediately but only lowers it after
436
+ * lower readings persist for `dwellMs`, measured with `reading.at`.
437
+ *
438
+ * @param options - Governor options
439
+ * @param options.dwellMs - Time a lower level must persist; defaults to 30 seconds
440
+ * @returns A function that maps each reading to the settled level
441
+ */
442
+ export declare function createHeatGovernor(options?: {
443
+ dwellMs?: number;
444
+ }): (reading: HeatReading) => HeatLevel;
133
445
  //#endregion
134
- export { AcAction, AcAudioController, AcAudioElement, AcAudioElements, AcChangeEvent, AcMode, AcNotification, AcNotificationSeverity, AcState, AcStorage, AcStoreListener, AirConditionerStore, CreateAirConditionerStoreOptions, acAudioFileNames, acModeIcons, acReducer, acStorageKey, clampTemperature, createAcAudioController, createAirConditionerStore, createMemoryStorage, defaultAcState, getAcActionNotification, getBrowserStorage, getRecommendedTemperatureMessage, maxTemperature, minTemperature, normalizeAcState, readAcState, recommendedColdTemperature, recommendedHotTemperature, resolveAcAudioAssets, soundTimings, writeAcState };
446
+ //#region src/thermal/plan.d.ts
447
+ /**
448
+ * Decide how the virtual air conditioner should respond to a heat level.
449
+ *
450
+ * @param level - Settled heat level
451
+ * @param limits - Device limits used to clamp the target temperature
452
+ * @returns A cooling plan, or `null` at `nominal` so the user keeps control
453
+ */
454
+ export declare function planCooling(level: HeatLevel, limits?: AcLimits): CoolingPlan | null;
455
+ //#endregion
456
+ //#region src/thermal/pressure.d.ts
457
+ export interface ComputePressureSourceOptions {
458
+ /** Requested sample interval; browsers may deliver less often */
459
+ sampleIntervalMs?: number;
460
+ /** Called when observing fails, e.g. blocked by permissions policy */
461
+ onError?: (error: unknown) => void;
462
+ }
463
+ /**
464
+ * Heat source backed by the browser Compute Pressure API. It reports CPU
465
+ * load levels, not temperatures; browsers expose no CPU temperature.
466
+ *
467
+ * Supported in Chromium-based browsers on secure origins. The API is only
468
+ * touched when the source is started.
469
+ *
470
+ * @param options - Sampling and error handling options
471
+ */
472
+ export declare function createComputePressureSource(options?: ComputePressureSourceOptions): HeatSource;
473
+ //#endregion
474
+ //#region src/ui.d.ts
475
+ /**
476
+ * 各框架视图层共用的界面数据:遥控器图标与能效标签的点阵布局。
477
+ * 保证 Vue / React / Web Component 渲染出完全一致的空调外观。
478
+ */
479
+ /**
480
+ * 遥控器按钮图标(24 × 24 viewBox 的 SVG path)。
481
+ */
482
+ export declare const acIconPaths: {
483
+ readonly cold: "m22 11h-4.17l3.24-3.24l-1.41-1.42L15 11h-2V9l4.66-4.66l-1.42-1.41L13 6.17V2h-2v4.17L7.76 2.93L6.34 4.34L11 9v2H9L4.34 6.34L2.93 7.76L6.17 11H2v2h4.17l-3.24 3.24l1.41 1.42L9 13h2v2l-4.66 4.66l1.42 1.41L11 17.83V22h2v-4.17l3.24 3.24l1.42-1.41L13 15v-2h2l4.66 4.66l1.41-1.42L17.83 13H22z";
484
+ readonly power: "M13 3h-2v10h2zm4.83 2.17l-1.42 1.42A6.92 6.92 0 0 1 19 12a7 7 0 0 1-14 0a6.92 6.92 0 0 1 2.58-5.42L6.17 5.17A9 9 0 1 0 21 12a8.94 8.94 0 0 0-3.17-6.83";
485
+ readonly hot: "M12 7a5 5 0 1 0 5 5a5 5 0 0 0-5-5m0-5a1 1 0 0 0-1 1v2a1 1 0 0 0 2 0V3a1 1 0 0 0-1-1m0 17a1 1 0 0 0-1 1v2a1 1 0 0 0 2 0v-2a1 1 0 0 0-1-1M5.64 6.05L4.22 4.64a1 1 0 0 0-1.41 1.41l1.41 1.42a1 1 0 0 0 1.42 0a1 1 0 0 0 0-1.42M21 11h-2a1 1 0 0 0 0 2h2a1 1 0 0 0 0-2M5 12a1 1 0 0 0-1-1H2a1 1 0 0 0 0 2h2a1 1 0 0 0 1-1m13.36-5.95a1 1 0 0 0 .7-.29l1.42-1.42a1 1 0 1 0-1.41-1.41l-1.42 1.41a1 1 0 0 0 0 1.42a1 1 0 0 0 .71.29m0 11.9a1 1 0 0 0-1.42 1.41l1.42 1.42a1 1 0 0 0 1.41 0a1 1 0 0 0 0-1.41ZM5.64 17.95l-1.42 1.42a1 1 0 0 0 0 1.41a1 1 0 0 0 1.41 0l1.42-1.42a1 1 0 0 0-1.41-1.41";
486
+ readonly increase: "m12 8l6 8H6z";
487
+ readonly decrease: "m12 16l-6-8h12z";
488
+ readonly soundNormal: "M3 10v4c0 .55.45 1 1 1h3l3.29 3.29c.63.63 1.71.18 1.71-.71V6.41c0-.89-1.08-1.34-1.71-.71L7 9H4c-.55 0-1 .45-1 1m13.5 2A4.5 4.5 0 0 0 14 7.97v8.05c1.48-.73 2.5-2.25 2.5-4.02M14 4.45v.2c0 .38.25.71.6.85C17.18 6.53 19 9.06 19 12s-1.82 5.47-4.4 6.5c-.36.14-.6.47-.6.85v.2c0 .63.63 1.07 1.21.85C18.6 19.11 21 15.84 21 12s-2.4-7.11-5.79-8.4c-.58-.23-1.21.22-1.21.85";
489
+ readonly soundSleep: "M11.65 3.46c.27-.71-.36-1.45-1.12-1.34c-5.52.8-9.47 6.07-8.34 11.88c.78 4.02 4.09 7.21 8.14 7.87c3.74.61 7.16-.87 9.32-3.44c.48-.57.19-1.48-.55-1.62c-6.02-1.15-9.68-7.54-7.45-13.35";
490
+ readonly soundMute: "M3.63 3.63a.996.996 0 0 0 0 1.41L7.29 8.7L7 9H4c-.55 0-1 .45-1 1v4c0 .55.45 1 1 1h3l3.29 3.29c.63.63 1.71.18 1.71-.71v-4.17l4.18 4.18c-.49.37-1.02.68-1.6.91c-.36.15-.58.53-.58.92c0 .72.73 1.18 1.39.91c.8-.33 1.55-.77 2.22-1.31l1.34 1.34a.996.996 0 1 0 1.41-1.41L5.05 3.63c-.39-.39-1.02-.39-1.42 0M19 12c0 .82-.15 1.61-.41 2.34l1.53 1.53c.56-1.17.88-2.48.88-3.87c0-3.83-2.4-7.11-5.78-8.4c-.59-.23-1.22.23-1.22.86v.19c0 .38.25.71.61.85C17.18 6.54 19 9.06 19 12m-8.71-6.29l-.17.17L12 7.76V6.41c0-.89-1.08-1.33-1.71-.7M16.5 12A4.5 4.5 0 0 0 14 7.97v1.79l2.48 2.48c.01-.08.02-.16.02-.24";
491
+ };
492
+ export type AcIconName = keyof typeof acIconPaths;
493
+ /**
494
+ * 声音键在各声音模式下显示的图标。
495
+ */
496
+ export declare const acSoundIcons: Record<AcSoundMode, AcIconName>;
497
+ /**
498
+ * 一行「黑点 / 白点」文字占位,模拟能效标签上的细密文字。
499
+ */
500
+ export interface AcDotRow {
501
+ num: number;
502
+ /** 点的直径(px) */
503
+ size: number;
504
+ /** 水平外边距(px) */
505
+ mx: number;
506
+ /** 垂直外边距(px) */
507
+ my: number;
508
+ color: string;
509
+ }
510
+ /**
511
+ * 能效标签的点阵与等级条布局。
512
+ */
513
+ export declare const acEnergyLabel: {
514
+ top: AcDotRow[];
515
+ detail: AcDotRow[];
516
+ footer: AcDotRow;
517
+ levels: {
518
+ background: string;
519
+ width: string;
520
+ }[];
521
+ };
522
+ //#endregion