@jjlmoya/utils-aquarium 1.59.0 → 1.61.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 +2 -1
- package/src/entries.ts +4 -1
- package/src/index.ts +2 -0
- package/src/tests/i18n_coverage.test.ts +1 -1
- package/src/tests/registry_contract.test.ts +67 -0
- package/src/tests/tool_validation.test.ts +4 -3
- package/src/tool/aquariumEvaporationTopOffPlanner/aquarium-evaporation-top-off-planner.css +490 -0
- package/src/tool/aquariumEvaporationTopOffPlanner/bibliography.astro +6 -0
- package/src/tool/aquariumEvaporationTopOffPlanner/bibliography.ts +10 -0
- package/src/tool/aquariumEvaporationTopOffPlanner/component.astro +61 -0
- package/src/tool/aquariumEvaporationTopOffPlanner/controller.ts +232 -0
- package/src/tool/aquariumEvaporationTopOffPlanner/dom-views.ts +39 -0
- package/src/tool/aquariumEvaporationTopOffPlanner/entry.ts +27 -0
- package/src/tool/aquariumEvaporationTopOffPlanner/evaluator.ts +9 -0
- package/src/tool/aquariumEvaporationTopOffPlanner/i18n/de.ts +3 -0
- package/src/tool/aquariumEvaporationTopOffPlanner/i18n/en.ts +179 -0
- package/src/tool/aquariumEvaporationTopOffPlanner/i18n/es.ts +3 -0
- package/src/tool/aquariumEvaporationTopOffPlanner/i18n/fr.ts +3 -0
- package/src/tool/aquariumEvaporationTopOffPlanner/i18n/id.ts +3 -0
- package/src/tool/aquariumEvaporationTopOffPlanner/i18n/it.ts +3 -0
- package/src/tool/aquariumEvaporationTopOffPlanner/i18n/ja.ts +3 -0
- package/src/tool/aquariumEvaporationTopOffPlanner/i18n/ko.ts +3 -0
- package/src/tool/aquariumEvaporationTopOffPlanner/i18n/nl.ts +3 -0
- package/src/tool/aquariumEvaporationTopOffPlanner/i18n/pl.ts +3 -0
- package/src/tool/aquariumEvaporationTopOffPlanner/i18n/pt.ts +3 -0
- package/src/tool/aquariumEvaporationTopOffPlanner/i18n/ru.ts +3 -0
- package/src/tool/aquariumEvaporationTopOffPlanner/i18n/shared.ts +79 -0
- package/src/tool/aquariumEvaporationTopOffPlanner/i18n/sv.ts +3 -0
- package/src/tool/aquariumEvaporationTopOffPlanner/i18n/tr.ts +3 -0
- package/src/tool/aquariumEvaporationTopOffPlanner/i18n/translations.ts +509 -0
- package/src/tool/aquariumEvaporationTopOffPlanner/i18n/zh.ts +3 -0
- package/src/tool/aquariumEvaporationTopOffPlanner/index.ts +11 -0
- package/src/tool/aquariumEvaporationTopOffPlanner/logic.test.ts +61 -0
- package/src/tool/aquariumEvaporationTopOffPlanner/logic.ts +102 -0
- package/src/tool/aquariumEvaporationTopOffPlanner/seo.astro +13 -0
- package/src/tool/aquariumEvaporationTopOffPlanner/storage.ts +28 -0
- package/src/tool/aquariumEvaporationTopOffPlanner/ui.ts +49 -0
- package/src/tool/aquariumLightingPhotoperiodPlanner/aquarium-lighting-photoperiod-planner.css +9 -9
- package/src/tool/aquariumLightingPhotoperiodPlanner/component.astro +3 -1
- package/src/tool/aquariumLightingPhotoperiodPlanner/controller.ts +21 -9
- package/src/tool/aquariumLightingPhotoperiodPlanner/dom-views.test.ts +2 -1
- package/src/tool/aquariumLightingPhotoperiodPlanner/dom-views.ts +20 -8
- package/src/tool/aquariumLightingPhotoperiodPlanner/i18n/de.ts +2 -0
- package/src/tool/aquariumLightingPhotoperiodPlanner/i18n/en.ts +2 -0
- package/src/tool/aquariumLightingPhotoperiodPlanner/i18n/es.ts +2 -0
- package/src/tool/aquariumLightingPhotoperiodPlanner/i18n/fr.ts +2 -0
- package/src/tool/aquariumLightingPhotoperiodPlanner/i18n/id.ts +2 -0
- package/src/tool/aquariumLightingPhotoperiodPlanner/i18n/it.ts +2 -0
- package/src/tool/aquariumLightingPhotoperiodPlanner/i18n/ja.ts +2 -0
- package/src/tool/aquariumLightingPhotoperiodPlanner/i18n/ko.ts +2 -0
- package/src/tool/aquariumLightingPhotoperiodPlanner/i18n/nl.ts +2 -0
- package/src/tool/aquariumLightingPhotoperiodPlanner/i18n/pl.ts +2 -0
- package/src/tool/aquariumLightingPhotoperiodPlanner/i18n/pt.ts +2 -0
- package/src/tool/aquariumLightingPhotoperiodPlanner/i18n/ru.ts +2 -0
- package/src/tool/aquariumLightingPhotoperiodPlanner/i18n/sv.ts +2 -0
- package/src/tool/aquariumLightingPhotoperiodPlanner/i18n/tr.ts +2 -0
- package/src/tool/aquariumLightingPhotoperiodPlanner/i18n/zh.ts +4 -2
- package/src/tool/aquariumLightingPhotoperiodPlanner/logic.test.ts +10 -0
- package/src/tool/aquariumLightingPhotoperiodPlanner/logic.ts +10 -0
- package/src/tool/aquariumLightingPhotoperiodPlanner/storage.ts +12 -8
- package/src/tool/aquariumLightingPhotoperiodPlanner/ui.ts +2 -0
- package/src/tool/aquariumTankVolumeWaterChangeCalculator/i18n/fr.ts +1 -1
- package/src/tool/aquariumTankVolumeWaterChangeCalculator/i18n/it.ts +1 -1
- package/src/tools.ts +6 -0
|
@@ -29,6 +29,7 @@ const ui = {
|
|
|
29
29
|
plantProfileHigh: 'Plantas exigentes em luz',
|
|
30
30
|
startTimeLabel: 'Hora de início do ciclo',
|
|
31
31
|
photoperiodLabel: 'Fotoperíodo total',
|
|
32
|
+
intensityLabel: 'Potência definida da luminária',
|
|
32
33
|
rampUpLabel: 'Rampa de amanhecer acendimento',
|
|
33
34
|
rampDownLabel: 'Rampa de anoitecer desligamento',
|
|
34
35
|
optionalRampsLabel: 'Rampas de regulação opcionais',
|
|
@@ -41,6 +42,7 @@ const ui = {
|
|
|
41
42
|
targetBandLabel: 'Faixa de referência',
|
|
42
43
|
lightWindowLabel: 'Janela de iluminação',
|
|
43
44
|
fullIntensityLabel: 'Intensidade total',
|
|
45
|
+
fixtureLevelLabel: 'Nível da luminária',
|
|
44
46
|
lightsOnLabel: 'acendimento',
|
|
45
47
|
fullLightLabel: 'luz total',
|
|
46
48
|
lightsOffLabel: 'desligamento',
|
|
@@ -29,6 +29,7 @@ const ui = {
|
|
|
29
29
|
plantProfileHigh: 'Светолюбивые растения',
|
|
30
30
|
startTimeLabel: 'Время начала светового дня',
|
|
31
31
|
photoperiodLabel: 'Общий фотопериод',
|
|
32
|
+
intensityLabel: 'Настройка мощности светильника',
|
|
32
33
|
rampUpLabel: 'Рассвет (плавное включение)',
|
|
33
34
|
rampDownLabel: 'Закат (плавное выключение)',
|
|
34
35
|
optionalRampsLabel: 'Фазы рассвета и заката (опционально)',
|
|
@@ -41,6 +42,7 @@ const ui = {
|
|
|
41
42
|
targetBandLabel: 'Рекомендуемый диапазон',
|
|
42
43
|
lightWindowLabel: 'График освещения',
|
|
43
44
|
fullIntensityLabel: 'Полная мощность света',
|
|
45
|
+
fixtureLevelLabel: 'Уровень светильника',
|
|
44
46
|
lightsOnLabel: 'включение',
|
|
45
47
|
fullLightLabel: 'полный свет',
|
|
46
48
|
lightsOffLabel: 'выключение',
|
|
@@ -29,6 +29,7 @@ const ui = {
|
|
|
29
29
|
plantProfileHigh: 'Ljuskrävande växter',
|
|
30
30
|
startTimeLabel: 'Starttid för cykeln',
|
|
31
31
|
photoperiodLabel: 'Total fotoperiod',
|
|
32
|
+
intensityLabel: 'Inställd lampeffekt',
|
|
32
33
|
rampUpLabel: 'Soluppgång (uppdimning)',
|
|
33
34
|
rampDownLabel: 'Solnedgång (neddimning)',
|
|
34
35
|
optionalRampsLabel: 'Valfria dimningsfaser',
|
|
@@ -41,6 +42,7 @@ const ui = {
|
|
|
41
42
|
targetBandLabel: 'Rekommenderat intervall',
|
|
42
43
|
lightWindowLabel: 'Belysningsfönster',
|
|
43
44
|
fullIntensityLabel: 'Full ljusstyrka',
|
|
45
|
+
fixtureLevelLabel: 'Lampnivå',
|
|
44
46
|
lightsOnLabel: 'tändning',
|
|
45
47
|
fullLightLabel: 'fullt ljus',
|
|
46
48
|
lightsOffLabel: 'släckning',
|
|
@@ -29,6 +29,7 @@ const ui = {
|
|
|
29
29
|
plantProfileHigh: 'Yüksek ışık isteyen bitkiler',
|
|
30
30
|
startTimeLabel: 'Döngü başlangıç saati',
|
|
31
31
|
photoperiodLabel: 'Toplam fotoperiyod',
|
|
32
|
+
intensityLabel: 'Armatür güç ayarı',
|
|
32
33
|
rampUpLabel: 'Gün doğumu geçişi (açılış)',
|
|
33
34
|
rampDownLabel: 'Gün batımı geçişi (kapanış)',
|
|
34
35
|
optionalRampsLabel: 'İsteğe bağlı karartma geçişleri',
|
|
@@ -41,6 +42,7 @@ const ui = {
|
|
|
41
42
|
targetBandLabel: 'Hedef zaman aralığı',
|
|
42
43
|
lightWindowLabel: 'Aydınlatma penceresi',
|
|
43
44
|
fullIntensityLabel: 'Tam ışık gücü',
|
|
45
|
+
fixtureLevelLabel: 'Armatür seviyesi',
|
|
44
46
|
lightsOnLabel: 'ışıklar açık',
|
|
45
47
|
fullLightLabel: 'tam ışık',
|
|
46
48
|
lightsOffLabel: 'ışıklar kapalı',
|
|
@@ -29,6 +29,7 @@ const ui = {
|
|
|
29
29
|
plantProfileHigh: '高光照水草(阳性草)',
|
|
30
30
|
startTimeLabel: '光照周期起始时间',
|
|
31
31
|
photoperiodLabel: '光照总时长',
|
|
32
|
+
intensityLabel: '灯具输出设置',
|
|
32
33
|
rampUpLabel: '日出渐进(开灯调光)',
|
|
33
34
|
rampDownLabel: '日落渐进(关灯调光)',
|
|
34
35
|
optionalRampsLabel: '可选渐变调光设置',
|
|
@@ -41,6 +42,7 @@ const ui = {
|
|
|
41
42
|
targetBandLabel: '建议光照范围',
|
|
42
43
|
lightWindowLabel: '光照时间窗口',
|
|
43
44
|
fullIntensityLabel: '全功率光照时长',
|
|
45
|
+
fixtureLevelLabel: '灯具档位',
|
|
44
46
|
lightsOnLabel: '开始开灯',
|
|
45
47
|
fullLightLabel: '全光照',
|
|
46
48
|
lightsOffLabel: '完全关灯',
|
|
@@ -65,7 +67,7 @@ const softwareApplicationSchema: WithContext<SoftwareApplication> = {
|
|
|
65
67
|
name: '水族箱灯光光照周期规划器',
|
|
66
68
|
applicationCategory: 'UtilitiesApplication',
|
|
67
69
|
operatingSystem: 'Web',
|
|
68
|
-
description: '
|
|
70
|
+
description: '根据水族箱类型、水草需求及调光功能,计算并规划水族灯自动定时时间表,方便日常维护和安排。',
|
|
69
71
|
offers: { '@type': 'Offer', price: '0', priceCurrency: 'CNY' },
|
|
70
72
|
};
|
|
71
73
|
|
|
@@ -85,7 +87,7 @@ const howToSchema: WithContext<HowTo> = {
|
|
|
85
87
|
export const content: AquariumLightingPhotoperiodPlannerLocaleContent = {
|
|
86
88
|
slug: 'aquarium-lighting-photoperiod-schedule-planner',
|
|
87
89
|
title: '水族箱灯光与光照周期(Photoperiod)规划器',
|
|
88
|
-
description: '
|
|
90
|
+
description: '结合水族箱类型、水草环境、开灯时间及调光渐变,制定稳定高效的水族箱定时开灯时间表,帮助安排日常养护。',
|
|
89
91
|
ui,
|
|
90
92
|
seo: [
|
|
91
93
|
{ type: 'title', level: 2, text: '为什么规律的光照周期至关重要' },
|
|
@@ -16,6 +16,7 @@ describe("aquarium lighting photoperiod planner logic", () => {
|
|
|
16
16
|
expect(result.band).toEqual({ low: 7, high: 9 });
|
|
17
17
|
expect(result.photoperiodMinutes).toBe(480);
|
|
18
18
|
expect(result.fullIntensityMinutes).toBe(420);
|
|
19
|
+
expect(result.input.intensityPercent).toBe(70);
|
|
19
20
|
expect(result.phases.map((phase) => phase.phase)).toEqual([
|
|
20
21
|
"ramp-up",
|
|
21
22
|
"full",
|
|
@@ -112,4 +113,13 @@ describe("aquarium lighting photoperiod planner logic", () => {
|
|
|
112
113
|
expect(formatHours(8)).toBe("8");
|
|
113
114
|
expect(formatHours(8.5)).toBe("8.5");
|
|
114
115
|
});
|
|
116
|
+
|
|
117
|
+
it("normalizes the fixture output setting to safe five percent steps", () => {
|
|
118
|
+
const result = calculateSchedule({
|
|
119
|
+
...DEFAULT_INPUT,
|
|
120
|
+
intensityPercent: 73,
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
expect(result.input.intensityPercent).toBe(75);
|
|
124
|
+
});
|
|
115
125
|
});
|
|
@@ -8,6 +8,7 @@ export interface LightingInput {
|
|
|
8
8
|
plantProfile: PlantProfile;
|
|
9
9
|
startTime: string;
|
|
10
10
|
photoperiodHours: number;
|
|
11
|
+
intensityPercent: number;
|
|
11
12
|
rampUpMinutes: number;
|
|
12
13
|
rampDownMinutes: number;
|
|
13
14
|
}
|
|
@@ -66,6 +67,7 @@ export const DEFAULT_INPUT: LightingInput = {
|
|
|
66
67
|
plantProfile: "low",
|
|
67
68
|
startTime: "08:00",
|
|
68
69
|
photoperiodHours: 8,
|
|
70
|
+
intensityPercent: 70,
|
|
69
71
|
rampUpMinutes: 30,
|
|
70
72
|
rampDownMinutes: 30,
|
|
71
73
|
};
|
|
@@ -76,6 +78,7 @@ export const PRESETS: Record<string, LightingInput> = {
|
|
|
76
78
|
aquariumType: "tropical",
|
|
77
79
|
plantProfile: "none",
|
|
78
80
|
photoperiodHours: 7,
|
|
81
|
+
intensityPercent: 55,
|
|
79
82
|
rampUpMinutes: 15,
|
|
80
83
|
rampDownMinutes: 15,
|
|
81
84
|
},
|
|
@@ -86,6 +89,7 @@ export const PRESETS: Record<string, LightingInput> = {
|
|
|
86
89
|
plantProfile: "none",
|
|
87
90
|
startTime: "10:00",
|
|
88
91
|
photoperiodHours: 8,
|
|
92
|
+
intensityPercent: 80,
|
|
89
93
|
rampUpMinutes: 60,
|
|
90
94
|
rampDownMinutes: 60,
|
|
91
95
|
},
|
|
@@ -124,6 +128,11 @@ function normalizePlantProfile(value: string): PlantProfile {
|
|
|
124
128
|
|
|
125
129
|
function normalizeInput(input: LightingInput): LightingInput {
|
|
126
130
|
const photoperiodHours = clamp(Number(input.photoperiodHours) || 8, 6, 12);
|
|
131
|
+
const intensityPercent = clamp(
|
|
132
|
+
Math.round((Number(input.intensityPercent) || 70) / 5) * 5,
|
|
133
|
+
10,
|
|
134
|
+
100,
|
|
135
|
+
);
|
|
127
136
|
const photoperiodMinutes = Math.round(photoperiodHours * 60);
|
|
128
137
|
const rampUpMinutes = clamp(Number(input.rampUpMinutes) || 0, 0, 180);
|
|
129
138
|
const rampDownMinutes = clamp(Number(input.rampDownMinutes) || 0, 0, 180);
|
|
@@ -138,6 +147,7 @@ function normalizeInput(input: LightingInput): LightingInput {
|
|
|
138
147
|
plantProfile: normalizePlantProfile(input.plantProfile),
|
|
139
148
|
startTime: formatClock(parseClock(input.startTime)),
|
|
140
149
|
photoperiodHours,
|
|
150
|
+
intensityPercent,
|
|
141
151
|
rampUpMinutes: Math.round(rampUpMinutes * scale),
|
|
142
152
|
rampDownMinutes: Math.round(rampDownMinutes * scale),
|
|
143
153
|
};
|
|
@@ -2,17 +2,21 @@ import type { LightingInput } from "./logic";
|
|
|
2
2
|
|
|
3
3
|
const STORAGE_KEY = "jjlmoya-aquarium-lighting-photoperiod-planner";
|
|
4
4
|
|
|
5
|
+
function hasLightingValues(candidate: Partial<LightingInput>): boolean {
|
|
6
|
+
const strings = [candidate.aquariumType, candidate.plantProfile, candidate.startTime];
|
|
7
|
+
const numbers = [
|
|
8
|
+
candidate.photoperiodHours,
|
|
9
|
+
candidate.intensityPercent,
|
|
10
|
+
candidate.rampUpMinutes,
|
|
11
|
+
candidate.rampDownMinutes,
|
|
12
|
+
];
|
|
13
|
+
return strings.every((value) => typeof value === "string") && numbers.every((value) => typeof value === "number");
|
|
14
|
+
}
|
|
15
|
+
|
|
5
16
|
function isLightingInput(value: unknown): value is LightingInput {
|
|
6
17
|
if (!value || typeof value !== "object") return false;
|
|
7
18
|
const candidate = value as Partial<LightingInput>;
|
|
8
|
-
return (
|
|
9
|
-
typeof candidate.aquariumType === "string" &&
|
|
10
|
-
typeof candidate.plantProfile === "string" &&
|
|
11
|
-
typeof candidate.startTime === "string" &&
|
|
12
|
-
typeof candidate.photoperiodHours === "number" &&
|
|
13
|
-
typeof candidate.rampUpMinutes === "number" &&
|
|
14
|
-
typeof candidate.rampDownMinutes === "number"
|
|
15
|
-
);
|
|
19
|
+
return hasLightingValues(candidate);
|
|
16
20
|
}
|
|
17
21
|
|
|
18
22
|
export function loadInput(): LightingInput | undefined {
|
|
@@ -13,6 +13,7 @@ export interface AquariumLightingPhotoperiodPlannerUI extends Record<
|
|
|
13
13
|
plantProfileHigh: string;
|
|
14
14
|
startTimeLabel: string;
|
|
15
15
|
photoperiodLabel: string;
|
|
16
|
+
intensityLabel: string;
|
|
16
17
|
rampUpLabel: string;
|
|
17
18
|
rampDownLabel: string;
|
|
18
19
|
optionalRampsLabel: string;
|
|
@@ -25,6 +26,7 @@ export interface AquariumLightingPhotoperiodPlannerUI extends Record<
|
|
|
25
26
|
targetBandLabel: string;
|
|
26
27
|
lightWindowLabel: string;
|
|
27
28
|
fullIntensityLabel: string;
|
|
29
|
+
fixtureLevelLabel: string;
|
|
28
30
|
lightsOnLabel: string;
|
|
29
31
|
fullLightLabel: string;
|
|
30
32
|
lightsOffLabel: string;
|
|
@@ -4,7 +4,7 @@ export const content = createAquariumContent({
|
|
|
4
4
|
locale: 'fr',
|
|
5
5
|
slug: 'calculateur-volume-aquarium-changement-eau',
|
|
6
6
|
title: "Calculateur du volume d'aquarium et du changement d'eau",
|
|
7
|
-
description: "Calculez le volume d'eau utile, le déplacement du substrat et la quantité d'eau à remplacer à partir des dimensions intérieures de votre aquarium.",
|
|
7
|
+
description: "Calculez le volume d'eau utile, le déplacement du substrat et la quantité d'eau à remplacer à partir des dimensions intérieures de votre aquarium pour planifier l'entretien.",
|
|
8
8
|
faq: [
|
|
9
9
|
{ question: "Le calculateur utilise-t-il la capacité indiquée sur l'aquarium ?", answer: "Non. Il retire la hauteur du substrat du volume géométrique et fournit une estimation de l'eau réellement disponible." },
|
|
10
10
|
{ question: "Comment fonctionne l'option façade bombée ?", answer: "Elle ajoute un segment circulaire approximatif à une base rectangulaire. Le résultat reste indicatif, car les profils de verre varient selon les aquariums." },
|
|
@@ -4,7 +4,7 @@ export const content = createAquariumContent({
|
|
|
4
4
|
locale: 'it',
|
|
5
5
|
slug: 'calcolatore-volume-acquario-cambio-acqua',
|
|
6
6
|
title: "Calcolatore del volume dell'acquario e del cambio d'acqua",
|
|
7
|
-
description: "Calcola il volume d'acqua utile, lo spazio occupato dal substrato e la quantità da sostituire usando le misure interne del tuo acquario.",
|
|
7
|
+
description: "Calcola il volume d'acqua utile, lo spazio occupato dal substrato e la quantità da sostituire usando le misure interne del tuo acquario per pianificare la manutenzione.",
|
|
8
8
|
faq: [
|
|
9
9
|
{ question: "Il calcolatore usa la capacità indicata sulla confezione?", answer: "No. Sottrae l'altezza del substrato dal volume geometrico e fornisce una stima dell'acqua effettivamente disponibile." },
|
|
10
10
|
{ question: "Come funziona l'opzione con fronte curvo?", answer: "Aggiunge un segmento circolare approssimato alla base rettangolare. Il risultato è indicativo perché i profili del vetro curvo cambiano da una vasca all'altra." },
|
package/src/tools.ts
CHANGED
|
@@ -2,6 +2,7 @@ export { ALL_ENTRIES } from './entries';
|
|
|
2
2
|
import { aquariumTankVolumeWaterChangeCalculator } from './tool/aquariumTankVolumeWaterChangeCalculator/entry';
|
|
3
3
|
import { aquariumFilterTurnoverStockingPlanner } from './tool/aquariumFilterTurnoverStockingPlanner/entry';
|
|
4
4
|
import { aquariumLightingPhotoperiodPlanner } from './tool/aquariumLightingPhotoperiodPlanner/entry';
|
|
5
|
+
import { aquariumEvaporationTopOffPlanner } from './tool/aquariumEvaporationTopOffPlanner/entry';
|
|
5
6
|
|
|
6
7
|
export const ALL_TOOLS = [{
|
|
7
8
|
entry: aquariumTankVolumeWaterChangeCalculator,
|
|
@@ -18,4 +19,9 @@ export const ALL_TOOLS = [{
|
|
|
18
19
|
Component: () => import('./tool/aquariumLightingPhotoperiodPlanner/component.astro'),
|
|
19
20
|
SEOComponent: () => import('./tool/aquariumLightingPhotoperiodPlanner/seo.astro'),
|
|
20
21
|
BibliographyComponent: () => import('./tool/aquariumLightingPhotoperiodPlanner/bibliography.astro'),
|
|
22
|
+
}, {
|
|
23
|
+
entry: aquariumEvaporationTopOffPlanner,
|
|
24
|
+
Component: () => import('./tool/aquariumEvaporationTopOffPlanner/component.astro'),
|
|
25
|
+
SEOComponent: () => import('./tool/aquariumEvaporationTopOffPlanner/seo.astro'),
|
|
26
|
+
BibliographyComponent: () => import('./tool/aquariumEvaporationTopOffPlanner/bibliography.astro'),
|
|
21
27
|
}];
|