@jjlmoya/utils-astronomy 1.40.0 → 1.41.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/astronomy-category-home.css +921 -0
- package/src/category/astronomy-category-home.ts +52 -0
- package/src/category/i18n/es.ts +16 -15
- package/src/layouts/AstronomyCategoryHome.astro +224 -0
- package/src/mfe/category-ui.ts +22 -15
- package/src/pages/[locale]/[utilities]/[categories]/[category].astro +2 -2
- package/src/pages/utilidades/categorias/[category].astro +2 -2
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
const getNodeText = (node: HTMLAnchorElement, selector: string): string =>
|
|
2
|
+
node.querySelector(selector)?.textContent ?? "";
|
|
3
|
+
|
|
4
|
+
const setText = (element: HTMLElement | null, text: string): void => {
|
|
5
|
+
element?.replaceChildren(document.createTextNode(text));
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
interface MissionElements {
|
|
9
|
+
title: HTMLElement | null;
|
|
10
|
+
description: HTMLElement | null;
|
|
11
|
+
status: HTMLElement | null;
|
|
12
|
+
link: HTMLAnchorElement | null;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const updateMission = (node: HTMLAnchorElement, mission: MissionElements, label: string): void => {
|
|
16
|
+
const title = getNodeText(node, "strong");
|
|
17
|
+
setText(mission.title, title);
|
|
18
|
+
setText(mission.description, getNodeText(node, "small"));
|
|
19
|
+
setText(mission.status, title);
|
|
20
|
+
mission.link?.setAttribute("href", node.href);
|
|
21
|
+
mission.link?.setAttribute("aria-label", label);
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export function enhanceAstronomyHome(): void {
|
|
25
|
+
const home = document.querySelector<HTMLElement>("[data-astronomy-home]");
|
|
26
|
+
if (!home) return;
|
|
27
|
+
const nodes = [...home.querySelectorAll<HTMLAnchorElement>("[data-tool-node]")];
|
|
28
|
+
if (nodes.length === 0) return;
|
|
29
|
+
const routeButton = home.querySelector<HTMLButtonElement>("[data-route-button]");
|
|
30
|
+
const missionTitle = home.querySelector<HTMLElement>("[data-mission-title]");
|
|
31
|
+
const missionDescription = home.querySelector<HTMLElement>("[data-mission-description]");
|
|
32
|
+
const missionLink = home.querySelector<HTMLAnchorElement>("[data-mission-link]");
|
|
33
|
+
const missionStatus = home.querySelector<HTMLElement>("[data-mission-status]");
|
|
34
|
+
const labels = nodes.map((node) => node.getAttribute("aria-label") ?? "");
|
|
35
|
+
let activeIndex = 0;
|
|
36
|
+
|
|
37
|
+
const selectNode = (index: number, focus = false): void => {
|
|
38
|
+
const node = nodes[index];
|
|
39
|
+
if (!node) return;
|
|
40
|
+
activeIndex = index;
|
|
41
|
+
nodes.forEach((item, itemIndex) => item.classList.toggle("is-active", itemIndex === index));
|
|
42
|
+
updateMission(node, { title: missionTitle, description: missionDescription, status: missionStatus, link: missionLink }, labels[index] ?? "");
|
|
43
|
+
if (focus) node.focus({ preventScroll: false });
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
nodes.forEach((node, index) => {
|
|
47
|
+
node.addEventListener("focus", () => selectNode(index));
|
|
48
|
+
node.addEventListener("pointerenter", () => selectNode(index));
|
|
49
|
+
});
|
|
50
|
+
selectNode(0);
|
|
51
|
+
routeButton?.addEventListener("click", () => selectNode((activeIndex + 1) % nodes.length, true));
|
|
52
|
+
}
|
package/src/category/i18n/es.ts
CHANGED
|
@@ -5,43 +5,44 @@ export const content: CategoryLocaleContent = {
|
|
|
5
5
|
title: 'Herramientas de Astronomía',
|
|
6
6
|
description: 'Calculadoras y simuladores gratuitos para astrónomos aficionados. Planifica tus sesiones de observación y astrofotografía.',
|
|
7
7
|
seo: [
|
|
8
|
-
{ type: 'title', text: 'Astronomía
|
|
8
|
+
{ type: 'title', text: 'Astronomía amateur: prepara la noche antes de salir', level: 2 },
|
|
9
9
|
{
|
|
10
10
|
type: 'paragraph',
|
|
11
|
-
html: 'La astronomía
|
|
11
|
+
html: 'La astronomía amateur no empieza cuando pegas el ojo al ocular. Empieza al mirar el cielo que tendrás, elegir qué quieres observar y comprobar qué puede hacer tu equipo. Estas <strong>herramientas astronómicas gratuitas</strong> convierten esa preparación en decisiones concretas: cuánto ampliar, qué detalle esperar y cuánto tiempo puedes exponer sin dibujar trazas con las estrellas.',
|
|
12
12
|
},
|
|
13
13
|
{
|
|
14
14
|
type: 'paragraph',
|
|
15
|
-
html: '
|
|
15
|
+
html: 'No prometen un cielo perfecto ni sustituyen la experiencia. Te ayudan a llegar con menos dudas, aprovechar mejor una ventana de observación y entender por qué una noche funciona, o por qué conviene dejar el telescopio en casa y esperar a otra.',
|
|
16
16
|
},
|
|
17
|
-
{ type: 'title', text: '
|
|
17
|
+
{ type: 'title', text: 'Primero, averigua qué cielo tienes', level: 2 },
|
|
18
18
|
{
|
|
19
19
|
type: 'paragraph',
|
|
20
|
-
html: '
|
|
20
|
+
html: 'La <strong>escala de Bortle</strong> pone nombre a algo que cualquier observador reconoce: la diferencia entre un cielo lavado por las farolas y uno donde la Vía Láctea vuelve a aparecer. El simulador de cielo oscuro recorre sus nueve niveles para que compares escenarios y sepas si la siguiente mejora está en el telescopio o en encontrar un lugar más oscuro.',
|
|
21
21
|
},
|
|
22
|
-
{ type: 'title', text: '
|
|
22
|
+
{ type: 'title', text: 'Después, mide lo que puede darte el equipo', level: 2 },
|
|
23
23
|
{
|
|
24
24
|
type: 'paragraph',
|
|
25
|
-
html: '
|
|
25
|
+
html: 'La apertura importa, pero no trabaja sola. La <strong>magnitud límite</strong> estima hasta dónde puede llegar tu telescopio; la resolución de Dawes y Rayleigh ayuda a entender cuándo dos estrellas están demasiado juntas para separarlas. El resultado nunca vence a la atmósfera, al enfoque ni a la turbulencia: sirve para poner expectativas realistas y observar con más criterio.',
|
|
26
26
|
},
|
|
27
27
|
{
|
|
28
28
|
type: 'list',
|
|
29
29
|
items: [
|
|
30
|
-
'<strong>
|
|
31
|
-
'<strong>
|
|
32
|
-
'<strong>
|
|
33
|
-
'<strong>
|
|
30
|
+
'<strong>Cielo oscuro:</strong> Recorre la escala de Bortle y descubre cuánto cambia una misma noche con menos contaminación lumínica.',
|
|
31
|
+
'<strong>Magnitud límite:</strong> Calcula una referencia del alcance visual de tu telescopio a partir de su apertura.',
|
|
32
|
+
'<strong>Resolución:</strong> Usa Dawes y Rayleigh para saber cuándo un sistema doble puede empezar a separarse.',
|
|
33
|
+
'<strong>Oculares:</strong> Relaciona aumento, pupila de salida y campo real antes de cambiar de ocular.',
|
|
34
|
+
'<strong>Astrofotografía:</strong> Ajusta la exposición, la regla de los 500 o NPF y el apilado para mantener estrellas puntuales.',
|
|
34
35
|
],
|
|
35
36
|
},
|
|
36
37
|
{
|
|
37
38
|
type: 'tip',
|
|
38
|
-
title: '
|
|
39
|
-
html: 'Antes de
|
|
39
|
+
title: 'La mejora que no se compra con más apertura',
|
|
40
|
+
html: 'Antes de cambiar de telescopio, prueba el mismo objeto bajo un cielo más oscuro. Pasar de un entorno Bortle 7 a uno Bortle 3 puede revelar contraste, estrellas y estructuras que no faltaban en tu equipo: faltaba oscuridad.',
|
|
40
41
|
},
|
|
41
|
-
{ type: 'title', text: '
|
|
42
|
+
{ type: 'title', text: 'Si haces fotos, calcula antes de disparar', level: 2 },
|
|
42
43
|
{
|
|
43
44
|
type: 'paragraph',
|
|
44
|
-
html: '
|
|
45
|
+
html: 'En una toma fija, la rotación terrestre termina convirtiendo las estrellas en trazas. La regla de los 500 y la NPF ofrecen un tiempo de exposición inicial según la focal y la cámara; el apilado suma señal sin pedirle todo a una sola imagen. Son referencias, no leyes: revisa las esquinas, mira el histograma y ajusta en el campo.',
|
|
45
46
|
},
|
|
46
47
|
{
|
|
47
48
|
type: 'stats',
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { Icon } from "astro-icon/components";
|
|
3
|
+
import { SEORenderer } from "@jjlmoya/utils-shared";
|
|
4
|
+
import ProductionBreadcrumb from "../components/ProductionBreadcrumb.astro";
|
|
5
|
+
import ProductionPage from "./ProductionPage.astro";
|
|
6
|
+
import { getCategoryPath } from "../mfe/routes";
|
|
7
|
+
import { getCategoryUi } from "../mfe/category-ui";
|
|
8
|
+
import type { CategoryLocaleContent, KnownLocale } from "../types";
|
|
9
|
+
import "../category/astronomy-category-home.css";
|
|
10
|
+
|
|
11
|
+
interface CategoryTool {
|
|
12
|
+
id: string;
|
|
13
|
+
icon: string;
|
|
14
|
+
title: string;
|
|
15
|
+
description: string;
|
|
16
|
+
href: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
interface Props {
|
|
20
|
+
locale: KnownLocale;
|
|
21
|
+
category: CategoryLocaleContent;
|
|
22
|
+
tools: CategoryTool[];
|
|
23
|
+
alternates: { language: KnownLocale; url: string }[];
|
|
24
|
+
image?: string | undefined;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const { locale, category, tools, alternates, image } = Astro.props;
|
|
28
|
+
const publicPath = getCategoryPath(locale, category.slug);
|
|
29
|
+
const ui = getCategoryUi(locale);
|
|
30
|
+
const firstTool = tools[0];
|
|
31
|
+
const constellationTools = tools;
|
|
32
|
+
const getToolPointSize = (count: number): string => {
|
|
33
|
+
if (count > 500) return "0.28rem";
|
|
34
|
+
if (count > 80) return "0.4rem";
|
|
35
|
+
return "0.72rem";
|
|
36
|
+
};
|
|
37
|
+
const toolPointSize = getToolPointSize(tools.length);
|
|
38
|
+
const getStarSize = (index: number): string => {
|
|
39
|
+
if (index % 11 === 0) return "0.28rem";
|
|
40
|
+
if (index % 4 === 0) return "0.16rem";
|
|
41
|
+
return "0.1rem";
|
|
42
|
+
};
|
|
43
|
+
const getStarOpacity = (index: number): string => {
|
|
44
|
+
if (index % 7 === 0) return "0.95";
|
|
45
|
+
if (index % 3 === 0) return "0.65";
|
|
46
|
+
return "0.38";
|
|
47
|
+
};
|
|
48
|
+
const stars = Array.from({ length: 72 }, (_, index) => ({
|
|
49
|
+
left: `${((index * 47) % 97) + 1}%`,
|
|
50
|
+
top: `${((index * 61) % 91) + 3}%`,
|
|
51
|
+
size: getStarSize(index),
|
|
52
|
+
opacity: getStarOpacity(index),
|
|
53
|
+
delay: `${index % 9}`,
|
|
54
|
+
}));
|
|
55
|
+
const getConstellationSide = (left: number, top: number): "left" | "right" | "bottom" | "top" => {
|
|
56
|
+
if (left > 62) return "right";
|
|
57
|
+
if (left < 38) return "left";
|
|
58
|
+
return top > 50 ? "bottom" : "top";
|
|
59
|
+
};
|
|
60
|
+
const handPlacedPositions = [
|
|
61
|
+
[55, 12],
|
|
62
|
+
[80, 28],
|
|
63
|
+
[88, 57],
|
|
64
|
+
[69, 81],
|
|
65
|
+
[43, 91],
|
|
66
|
+
[17, 73],
|
|
67
|
+
[11, 43],
|
|
68
|
+
[30, 20],
|
|
69
|
+
[63, 24],
|
|
70
|
+
[83, 73],
|
|
71
|
+
[25, 57],
|
|
72
|
+
[39, 11],
|
|
73
|
+
] as const;
|
|
74
|
+
const constellationPositions = constellationTools.map((_, index) => {
|
|
75
|
+
const count = Math.max(constellationTools.length, 1);
|
|
76
|
+
const handPlaced = handPlacedPositions[index];
|
|
77
|
+
const drift = ((index * 17) % 13) - 6;
|
|
78
|
+
const angle = index * 2.399963 + drift * 0.025;
|
|
79
|
+
const radius = 12 + Math.sqrt((index + 0.5) / count) * 34 + drift * 0.25;
|
|
80
|
+
const left = handPlaced?.[0] ?? 50 + Math.cos(angle) * radius;
|
|
81
|
+
const top = handPlaced?.[1] ?? 50 + Math.sin(angle) * radius;
|
|
82
|
+
return {
|
|
83
|
+
left: `${left.toFixed(2)}%`,
|
|
84
|
+
top: `${top.toFixed(2)}%`,
|
|
85
|
+
side: getConstellationSide(left, top),
|
|
86
|
+
};
|
|
87
|
+
});
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
<ProductionPage
|
|
91
|
+
title={category.title}
|
|
92
|
+
description={category.description}
|
|
93
|
+
{locale}
|
|
94
|
+
{publicPath}
|
|
95
|
+
{alternates}
|
|
96
|
+
{image}
|
|
97
|
+
>
|
|
98
|
+
<div class="astronomy-home" data-astronomy-home>
|
|
99
|
+
<div class="astronomy-page-stars" aria-hidden="true">
|
|
100
|
+
{stars.slice(0, 42).map((star) => (
|
|
101
|
+
<i
|
|
102
|
+
class="astronomy-page-star"
|
|
103
|
+
style={`--star-left: ${star.left}; --star-top: ${star.top}; --star-size: ${star.size}; --star-opacity: ${star.opacity}; --star-delay: ${star.delay}s;`}
|
|
104
|
+
></i>
|
|
105
|
+
))}
|
|
106
|
+
</div>
|
|
107
|
+
<div class="astronomy-shell">
|
|
108
|
+
<ProductionBreadcrumb locale={locale} currentTitle={category.title} />
|
|
109
|
+
|
|
110
|
+
<section class="astronomy-orbit" aria-labelledby="astronomy-title">
|
|
111
|
+
<div id="astronomy-sky" class:list={["astronomy-sky", tools.length > 12 && "astronomy-sky-dense"]} aria-label={category.title}>
|
|
112
|
+
<div class="astronomy-sky-stars" aria-hidden="true">
|
|
113
|
+
{stars.map((star) => (
|
|
114
|
+
<i
|
|
115
|
+
class="astronomy-star"
|
|
116
|
+
style={`--star-left: ${star.left}; --star-top: ${star.top}; --star-size: ${star.size}; --star-opacity: ${star.opacity}; --star-delay: ${star.delay}s;`}
|
|
117
|
+
></i>
|
|
118
|
+
))}
|
|
119
|
+
</div>
|
|
120
|
+
<div class="astronomy-sky-dust" aria-hidden="true"></div>
|
|
121
|
+
<div class="astronomy-sky-coordinates" aria-hidden="true">
|
|
122
|
+
<span>α 05h 55m 10s</span>
|
|
123
|
+
<span>δ +07° 24′ 25″</span>
|
|
124
|
+
</div>
|
|
125
|
+
<div class="astronomy-celestial-scene" aria-hidden="true">
|
|
126
|
+
<div class="astronomy-orbit-track astronomy-orbit-track-one"><span class="astronomy-orbit-body astronomy-orbit-body-one"></span></div>
|
|
127
|
+
<div class="astronomy-orbit-track astronomy-orbit-track-two"><span class="astronomy-orbit-body astronomy-orbit-body-two"></span></div>
|
|
128
|
+
<div class="astronomy-orbit-track astronomy-orbit-track-three"><span class="astronomy-orbit-body astronomy-orbit-body-three"></span></div>
|
|
129
|
+
<div class="astronomy-planet"><span></span></div>
|
|
130
|
+
</div>
|
|
131
|
+
<div class="astronomy-constellation-center" aria-hidden="true">
|
|
132
|
+
<span>ASTRONOMIA</span>
|
|
133
|
+
<b>*</b>
|
|
134
|
+
</div>
|
|
135
|
+
|
|
136
|
+
{constellationTools.map((tool, index) => (
|
|
137
|
+
<a
|
|
138
|
+
class:list={["astronomy-star-link", `astronomy-star-link-${constellationPositions[index]?.side ?? "top"}`]}
|
|
139
|
+
href={tool.href}
|
|
140
|
+
data-tool-node
|
|
141
|
+
data-tool-index={index}
|
|
142
|
+
style={`--node-left: ${constellationPositions[index]?.left}; --node-top: ${constellationPositions[index]?.top}; --node-size: ${toolPointSize};`}
|
|
143
|
+
aria-label={`${tool.title}: ${ui.openTool}`}
|
|
144
|
+
>
|
|
145
|
+
<span class="astronomy-star-link-point" aria-hidden="true"></span>
|
|
146
|
+
<span class="astronomy-star-link-label">
|
|
147
|
+
<span class="astronomy-star-link-icon" aria-hidden="true"><Icon name={tool.icon} /></span>
|
|
148
|
+
<b>{String(index + 1).padStart(2, "0")}</b>
|
|
149
|
+
<strong>{tool.title}</strong>
|
|
150
|
+
<small>{tool.description}</small>
|
|
151
|
+
</span>
|
|
152
|
+
</a>
|
|
153
|
+
))}
|
|
154
|
+
|
|
155
|
+
<p class="astronomy-sky-caption">{String(tools.length).padStart(2, "0")} {ui.catalogLabel}</p>
|
|
156
|
+
</div>
|
|
157
|
+
|
|
158
|
+
<div class="astronomy-editorial">
|
|
159
|
+
<p class="astronomy-overline">{ui.observationEyebrow}</p>
|
|
160
|
+
<h1 id="astronomy-title">{category.title}</h1>
|
|
161
|
+
<p class="astronomy-lede">{category.description}</p>
|
|
162
|
+
|
|
163
|
+
{firstTool && (
|
|
164
|
+
<div class="astronomy-observation" data-mission-panel>
|
|
165
|
+
<div class="astronomy-observation-heading">
|
|
166
|
+
<span class="astronomy-observation-dot" aria-hidden="true"></span>
|
|
167
|
+
<p>{ui.missionLabel}</p>
|
|
168
|
+
</div>
|
|
169
|
+
<h2 data-mission-title>{firstTool.title}</h2>
|
|
170
|
+
<p data-mission-description>{firstTool.description}</p>
|
|
171
|
+
<div class="astronomy-observation-actions">
|
|
172
|
+
<button type="button" data-route-button aria-controls="astronomy-sky">
|
|
173
|
+
{ui.exploreRoute}<span aria-hidden="true">↗</span>
|
|
174
|
+
</button>
|
|
175
|
+
<a data-mission-link href={firstTool.href}>
|
|
176
|
+
{ui.openTool}<span aria-hidden="true">→</span>
|
|
177
|
+
</a>
|
|
178
|
+
</div>
|
|
179
|
+
<p class="astronomy-observation-status" aria-live="polite" data-mission-status>
|
|
180
|
+
{firstTool.title}
|
|
181
|
+
</p>
|
|
182
|
+
</div>
|
|
183
|
+
)}
|
|
184
|
+
|
|
185
|
+
<nav class="astronomy-tool-index" aria-label={category.title}>
|
|
186
|
+
<details open={tools.length <= 12}>
|
|
187
|
+
<summary class="astronomy-tool-index-title">
|
|
188
|
+
<span>{ui.toolIndexLabel}</span>
|
|
189
|
+
<span>{String(tools.length).padStart(2, "0")}</span>
|
|
190
|
+
</summary>
|
|
191
|
+
<ol>
|
|
192
|
+
{tools.map((tool, index) => (
|
|
193
|
+
<li>
|
|
194
|
+
<a href={tool.href} data-tool-index-link data-tool-index={index}>
|
|
195
|
+
<span>{String(index + 1).padStart(2, "0")}</span>
|
|
196
|
+
<strong>{tool.title}</strong>
|
|
197
|
+
<i aria-hidden="true">↗</i>
|
|
198
|
+
</a>
|
|
199
|
+
</li>
|
|
200
|
+
))}
|
|
201
|
+
</ol>
|
|
202
|
+
</details>
|
|
203
|
+
</nav>
|
|
204
|
+
</div>
|
|
205
|
+
</section>
|
|
206
|
+
|
|
207
|
+
<section class="astronomy-field-notes" aria-labelledby="astronomy-notes-title">
|
|
208
|
+
<div class="astronomy-field-notes-title">
|
|
209
|
+
<span class="astronomy-overline">{ui.fieldNotesLabel}</span>
|
|
210
|
+
<h2 id="astronomy-notes-title">{ui.fieldNotesTitle}</h2>
|
|
211
|
+
</div>
|
|
212
|
+
<div class="astronomy-seo">
|
|
213
|
+
<SEORenderer content={{ locale, sections: category.seo }} />
|
|
214
|
+
</div>
|
|
215
|
+
</section>
|
|
216
|
+
</div>
|
|
217
|
+
</div>
|
|
218
|
+
</ProductionPage>
|
|
219
|
+
|
|
220
|
+
<script>
|
|
221
|
+
import { enhanceAstronomyHome } from "../category/astronomy-category-home";
|
|
222
|
+
|
|
223
|
+
enhanceAstronomyHome();
|
|
224
|
+
</script>
|
package/src/mfe/category-ui.ts
CHANGED
|
@@ -3,6 +3,13 @@ import type { KnownLocale } from '../types';
|
|
|
3
3
|
export interface CategoryUi {
|
|
4
4
|
useTool: string;
|
|
5
5
|
openTool: string;
|
|
6
|
+
exploreRoute: string;
|
|
7
|
+
missionLabel: string;
|
|
8
|
+
catalogLabel: string;
|
|
9
|
+
observationEyebrow: string;
|
|
10
|
+
toolIndexLabel: string;
|
|
11
|
+
fieldNotesLabel: string;
|
|
12
|
+
fieldNotesTitle: string;
|
|
6
13
|
relatedEyebrow: string;
|
|
7
14
|
moreToolsIn: string;
|
|
8
15
|
zoom: string;
|
|
@@ -14,21 +21,21 @@ export interface CategoryUi {
|
|
|
14
21
|
}
|
|
15
22
|
|
|
16
23
|
export const CATEGORY_UI: Record<KnownLocale, CategoryUi> = {
|
|
17
|
-
es: { useTool: 'Usar herramienta', openTool: 'Abrir herramienta', relatedEyebrow: 'Sigue explorando', moreToolsIn: 'Más herramientas en', zoom: 'Zoom', zoomControls: 'Controles de zoom', zoomOut: 'Reducir zoom', resetZoom: 'Restablecer zoom', zoomIn: 'Aumentar zoom', breadcrumb: 'Migas de pan' },
|
|
18
|
-
en: { useTool: 'Use tool', openTool: 'Open tool', relatedEyebrow: 'Keep exploring', moreToolsIn: 'More tools in', zoom: 'Zoom', zoomControls: 'Zoom controls', zoomOut: 'Zoom out', resetZoom: 'Reset zoom', zoomIn: 'Zoom in', breadcrumb: 'Breadcrumb' },
|
|
19
|
-
fr: { useTool: "Utiliser l'outil", openTool: "Ouvrir l'outil", relatedEyebrow: 'Continuez à explorer', moreToolsIn: "Plus d'outils dans", zoom: 'Zoom', zoomControls: 'Commandes de zoom', zoomOut: 'Réduire
|
|
20
|
-
de: { useTool: 'Werkzeug verwenden', openTool: 'Werkzeug öffnen', relatedEyebrow: 'Mehr entdecken', moreToolsIn: 'Weitere Werkzeuge in', zoom: 'Zoom', zoomControls: 'Zoom-Steuerung', zoomOut: 'Verkleinern', resetZoom: 'Zoom zurücksetzen', zoomIn: 'Vergrößern', breadcrumb: 'Brotkrümelnavigation' },
|
|
21
|
-
it: { useTool: 'Usa lo strumento', openTool: 'Apri lo strumento', relatedEyebrow: 'Continua a esplorare', moreToolsIn: 'Altri strumenti in', zoom: 'Zoom', zoomControls: 'Controlli zoom', zoomOut: 'Riduci zoom', resetZoom: 'Reimposta zoom', zoomIn: 'Aumenta zoom', breadcrumb: 'Breadcrumb' },
|
|
22
|
-
pt: { useTool: 'Usar ferramenta', openTool: 'Abrir ferramenta', relatedEyebrow: 'Continue a explorar', moreToolsIn: 'Mais ferramentas em', zoom: 'Zoom', zoomControls: 'Controlos de zoom', zoomOut: 'Reduzir zoom', resetZoom: 'Repor zoom', zoomIn: 'Aumentar zoom', breadcrumb: 'Trilho de navegação' },
|
|
23
|
-
nl: { useTool: 'Tool gebruiken', openTool: 'Tool openen', relatedEyebrow: 'Blijf ontdekken', moreToolsIn: 'Meer tools in', zoom: 'Zoom', zoomControls: 'Zoomknoppen', zoomOut: 'Uitzoomen', resetZoom: 'Zoom herstellen', zoomIn: 'Inzoomen', breadcrumb: 'Broodkruimelnavigatie' },
|
|
24
|
-
sv: { useTool: 'Använd verktyget', openTool: 'Öppna verktyget', relatedEyebrow: 'Utforska mer', moreToolsIn: 'Fler verktyg i', zoom: 'Zoom', zoomControls: 'Zoomkontroller', zoomOut: 'Zooma ut', resetZoom: 'Återställ zoom', zoomIn: 'Zooma in', breadcrumb: 'Brödsmulenavigering' },
|
|
25
|
-
pl: { useTool: 'Użyj narzędzia', openTool: 'Otwórz narzędzie', relatedEyebrow: 'Odkrywaj dalej', moreToolsIn: 'Więcej narzędzi w', zoom: 'Powiększenie', zoomControls: 'Sterowanie powiększeniem', zoomOut: 'Pomniejsz', resetZoom: 'Resetuj powiększenie', zoomIn: 'Powiększ', breadcrumb: 'Okruszki nawigacji' },
|
|
26
|
-
id: { useTool: 'Gunakan alat', openTool: 'Buka alat', relatedEyebrow: 'Jelajahi lebih lanjut', moreToolsIn: 'Alat lainnya di', zoom: 'Zoom', zoomControls: 'Kontrol zoom', zoomOut: 'Perkecil', resetZoom: 'Atur ulang zoom', zoomIn: 'Perbesar', breadcrumb: 'Breadcrumb' },
|
|
27
|
-
tr: { useTool: 'Aracı kullan', openTool: 'Aracı aç', relatedEyebrow: 'Keşfetmeye devam edin', moreToolsIn: 'Diğer araçlar:', zoom: 'Yakınlaştırma', zoomControls: 'Yakınlaştırma denetimleri', zoomOut: 'Uzaklaştır', resetZoom: 'Yakınlaştırmayı sıfırla', zoomIn: 'Yakınlaştır', breadcrumb: 'İçerik haritası' },
|
|
28
|
-
ru: { useTool: 'Использовать инструмент', openTool: 'Открыть инструмент', relatedEyebrow: 'Продолжить изучение', moreToolsIn: 'Другие инструменты в', zoom: 'Масштаб', zoomControls: 'Управление масштабом', zoomOut: 'Уменьшить', resetZoom: 'Сбросить масштаб', zoomIn: 'Увеличить', breadcrumb: 'Навигационная цепочка' },
|
|
29
|
-
ja: { useTool: 'ツールを使う', openTool: 'ツールを開く', relatedEyebrow: 'さらに探索', moreToolsIn: 'その他のツール:', zoom: 'ズーム', zoomControls: 'ズーム操作', zoomOut: '縮小', resetZoom: 'ズームをリセット', zoomIn: '拡大', breadcrumb: 'パンくずリスト' },
|
|
30
|
-
ko: { useTool: '도구 사용', openTool: '도구 열기', relatedEyebrow: '더 탐색하기', moreToolsIn: '카테고리의 다른 도구:', zoom: '확대/축소', zoomControls: '확대/축소 컨트롤', zoomOut: '축소', resetZoom: '확대/축소 초기화', zoomIn: '확대', breadcrumb: '탐색 경로' },
|
|
31
|
-
zh: { useTool: '使用工具', openTool: '打开工具', relatedEyebrow: '继续探索', moreToolsIn: '更多工具:', zoom: '缩放', zoomControls: '缩放控件', zoomOut: '缩小', resetZoom: '重置缩放', zoomIn: '放大', breadcrumb: '面包屑导航' },
|
|
24
|
+
es: { useTool: 'Usar herramienta', openTool: 'Abrir herramienta', exploreRoute: 'Apuntar al siguiente', missionLabel: 'Objetivo de observación', catalogLabel: 'estrellas', observationEyebrow: 'Cuaderno de observación · 01', toolIndexLabel: 'Todas las estrellas', fieldNotesLabel: 'Notas de campo', fieldNotesTitle: 'Para cuando el cielo pide más tiempo', relatedEyebrow: 'Sigue explorando', moreToolsIn: 'Más herramientas en', zoom: 'Zoom', zoomControls: 'Controles de zoom', zoomOut: 'Reducir zoom', resetZoom: 'Restablecer zoom', zoomIn: 'Aumentar zoom', breadcrumb: 'Migas de pan' },
|
|
25
|
+
en: { useTool: 'Use tool', openTool: 'Open tool', exploreRoute: 'Point to next', missionLabel: 'Observation target', catalogLabel: 'stars', observationEyebrow: 'Observation log · 01', toolIndexLabel: 'All stars', fieldNotesLabel: 'Field notes', fieldNotesTitle: 'For when the sky asks for more time', relatedEyebrow: 'Keep exploring', moreToolsIn: 'More tools in', zoom: 'Zoom', zoomControls: 'Zoom controls', zoomOut: 'Zoom out', resetZoom: 'Reset zoom', zoomIn: 'Zoom in', breadcrumb: 'Breadcrumb' },
|
|
26
|
+
fr: { useTool: "Utiliser l'outil", openTool: "Ouvrir l'outil", exploreRoute: 'Pointer vers la suivante', missionLabel: "Cible d'observation", catalogLabel: 'étoiles', observationEyebrow: "Carnet d'observation · 01", toolIndexLabel: 'Toutes les étoiles', fieldNotesLabel: 'Notes de terrain', fieldNotesTitle: 'Quand le ciel demande plus de temps', relatedEyebrow: 'Continuez à explorer', moreToolsIn: "Plus d'outils dans", zoom: 'Zoom', zoomControls: 'Commandes de zoom', zoomOut: 'Réduire zoom', resetZoom: 'Réinitialiser le zoom', zoomIn: 'Augmenter zoom', breadcrumb: 'Fil d’Ariane' },
|
|
27
|
+
de: { useTool: 'Werkzeug verwenden', openTool: 'Werkzeug öffnen', exploreRoute: 'Nächsten anpeilen', missionLabel: 'Beobachtungsziel', catalogLabel: 'Sterne', observationEyebrow: 'Beobachtungsnotiz · 01', toolIndexLabel: 'Alle Sterne', fieldNotesLabel: 'Feldnotizen', fieldNotesTitle: 'Wenn der Himmel nach mehr Zeit verlangt', relatedEyebrow: 'Mehr entdecken', moreToolsIn: 'Weitere Werkzeuge in', zoom: 'Zoom', zoomControls: 'Zoom-Steuerung', zoomOut: 'Verkleinern', resetZoom: 'Zoom zurücksetzen', zoomIn: 'Vergrößern', breadcrumb: 'Brotkrümelnavigation' },
|
|
28
|
+
it: { useTool: 'Usa lo strumento', openTool: 'Apri lo strumento', exploreRoute: 'Punta alla prossima', missionLabel: 'Obiettivo di osservazione', catalogLabel: 'stelle', observationEyebrow: 'Diario di osservazione · 01', toolIndexLabel: 'Tutte le stelle', fieldNotesLabel: 'Note di campo', fieldNotesTitle: 'Quando il cielo chiede più tempo', relatedEyebrow: 'Continua a esplorare', moreToolsIn: 'Altri strumenti in', zoom: 'Zoom', zoomControls: 'Controlli zoom', zoomOut: 'Riduci zoom', resetZoom: 'Reimposta zoom', zoomIn: 'Aumenta zoom', breadcrumb: 'Breadcrumb' },
|
|
29
|
+
pt: { useTool: 'Usar ferramenta', openTool: 'Abrir ferramenta', exploreRoute: 'Apontar para a próxima', missionLabel: 'Alvo de observação', catalogLabel: 'estrelas', observationEyebrow: 'Diário de observação · 01', toolIndexLabel: 'Todas as estrelas', fieldNotesLabel: 'Notas de campo', fieldNotesTitle: 'Quando o céu pede mais tempo', relatedEyebrow: 'Continue a explorar', moreToolsIn: 'Mais ferramentas em', zoom: 'Zoom', zoomControls: 'Controlos de zoom', zoomOut: 'Reduzir zoom', resetZoom: 'Repor zoom', zoomIn: 'Aumentar zoom', breadcrumb: 'Trilho de navegação' },
|
|
30
|
+
nl: { useTool: 'Tool gebruiken', openTool: 'Tool openen', exploreRoute: 'Volgende aanwijzen', missionLabel: 'Observatiedoel', catalogLabel: 'sterren', observationEyebrow: 'Observatienotitie · 01', toolIndexLabel: 'Alle sterren', fieldNotesLabel: 'Veldnotities', fieldNotesTitle: 'Wanneer de hemel om meer tijd vraagt', relatedEyebrow: 'Blijf ontdekken', moreToolsIn: 'Meer tools in', zoom: 'Zoom', zoomControls: 'Zoomknoppen', zoomOut: 'Uitzoomen', resetZoom: 'Zoom herstellen', zoomIn: 'Inzoomen', breadcrumb: 'Broodkruimelnavigatie' },
|
|
31
|
+
sv: { useTool: 'Använd verktyget', openTool: 'Öppna verktyget', exploreRoute: 'Peka på nästa', missionLabel: 'Observationsmål', catalogLabel: 'stjärnor', observationEyebrow: 'Observationslogg · 01', toolIndexLabel: 'Alla stjärnor', fieldNotesLabel: 'Fältanteckningar', fieldNotesTitle: 'När himlen ber om mer tid', relatedEyebrow: 'Utforska mer', moreToolsIn: 'Fler verktyg i', zoom: 'Zoom', zoomControls: 'Zoomkontroller', zoomOut: 'Zooma ut', resetZoom: 'Återställ zoom', zoomIn: 'Zooma in', breadcrumb: 'Brödsmulenavigering' },
|
|
32
|
+
pl: { useTool: 'Użyj narzędzia', openTool: 'Otwórz narzędzie', exploreRoute: 'Wskaż następną', missionLabel: 'Cel obserwacji', catalogLabel: 'gwiazd', observationEyebrow: 'Dziennik obserwacji · 01', toolIndexLabel: 'Wszystkie gwiazdy', fieldNotesLabel: 'Notatki terenowe', fieldNotesTitle: 'Gdy niebo prosi o więcej czasu', relatedEyebrow: 'Odkrywaj dalej', moreToolsIn: 'Więcej narzędzi w', zoom: 'Powiększenie', zoomControls: 'Sterowanie powiększeniem', zoomOut: 'Pomniejsz', resetZoom: 'Resetuj powiększenie', zoomIn: 'Powiększ', breadcrumb: 'Okruszki nawigacji' },
|
|
33
|
+
id: { useTool: 'Gunakan alat', openTool: 'Buka alat', exploreRoute: 'Arahkan ke berikutnya', missionLabel: 'Target pengamatan', catalogLabel: 'bintang', observationEyebrow: 'Catatan pengamatan · 01', toolIndexLabel: 'Semua bintang', fieldNotesLabel: 'Catatan lapangan', fieldNotesTitle: 'Saat langit meminta lebih banyak waktu', relatedEyebrow: 'Jelajahi lebih lanjut', moreToolsIn: 'Alat lainnya di', zoom: 'Zoom', zoomControls: 'Kontrol zoom', zoomOut: 'Perkecil', resetZoom: 'Atur ulang zoom', zoomIn: 'Perbesar', breadcrumb: 'Breadcrumb' },
|
|
34
|
+
tr: { useTool: 'Aracı kullan', openTool: 'Aracı aç', exploreRoute: 'Sonrakine yönel', missionLabel: 'Gözlem hedefi', catalogLabel: 'yıldız', observationEyebrow: 'Gözlem günlüğü · 01', toolIndexLabel: 'Tüm yıldızlar', fieldNotesLabel: 'Saha notları', fieldNotesTitle: 'Gökyüzü daha fazla zaman istediğinde', relatedEyebrow: 'Keşfetmeye devam edin', moreToolsIn: 'Diğer araçlar:', zoom: 'Yakınlaştırma', zoomControls: 'Yakınlaştırma denetimleri', zoomOut: 'Uzaklaştır', resetZoom: 'Yakınlaştırmayı sıfırla', zoomIn: 'Yakınlaştır', breadcrumb: 'İçerik haritası' },
|
|
35
|
+
ru: { useTool: 'Использовать инструмент', openTool: 'Открыть инструмент', exploreRoute: 'Навести на следующую', missionLabel: 'Цель наблюдения', catalogLabel: 'звёзд', observationEyebrow: 'Журнал наблюдений · 01', toolIndexLabel: 'Все звёзды', fieldNotesLabel: 'Полевые заметки', fieldNotesTitle: 'Когда небо просит больше времени', relatedEyebrow: 'Продолжить изучение', moreToolsIn: 'Другие инструменты в', zoom: 'Масштаб', zoomControls: 'Управление масштабом', zoomOut: 'Уменьшить', resetZoom: 'Сбросить масштаб', zoomIn: 'Увеличить', breadcrumb: 'Навигационная цепочка' },
|
|
36
|
+
ja: { useTool: 'ツールを使う', openTool: 'ツールを開く', exploreRoute: '次へ向ける', missionLabel: '観測対象', catalogLabel: '星', observationEyebrow: '観測ノート · 01', toolIndexLabel: 'すべての星', fieldNotesLabel: 'フィールドノート', fieldNotesTitle: '空がもっと時間を求めるとき', relatedEyebrow: 'さらに探索', moreToolsIn: 'その他のツール:', zoom: 'ズーム', zoomControls: 'ズーム操作', zoomOut: '縮小', resetZoom: 'ズームをリセット', zoomIn: '拡大', breadcrumb: 'パンくずリスト' },
|
|
37
|
+
ko: { useTool: '도구 사용', openTool: '도구 열기', exploreRoute: '다음 별 가리키기', missionLabel: '관측 대상', catalogLabel: '별', observationEyebrow: '관측 기록 · 01', toolIndexLabel: '모든 별', fieldNotesLabel: '현장 기록', fieldNotesTitle: '하늘이 더 많은 시간을 요구할 때', relatedEyebrow: '더 탐색하기', moreToolsIn: '카테고리의 다른 도구:', zoom: '확대/축소', zoomControls: '확대/축소 컨트롤', zoomOut: '축소', resetZoom: '확대/축소 초기화', zoomIn: '확대', breadcrumb: '탐색 경로' },
|
|
38
|
+
zh: { useTool: '使用工具', openTool: '打开工具', exploreRoute: '指向下一颗', missionLabel: '观测目标', catalogLabel: '颗星', observationEyebrow: '观测记录 · 01', toolIndexLabel: '所有星辰', fieldNotesLabel: '观测笔记', fieldNotesTitle: '当夜空需要更多时间', relatedEyebrow: '继续探索', moreToolsIn: '更多工具:', zoom: '缩放', zoomControls: '缩放控件', zoomOut: '缩小', resetZoom: '重置缩放', zoomIn: '放大', breadcrumb: '面包屑导航' },
|
|
32
39
|
};
|
|
33
40
|
|
|
34
41
|
export const getCategoryUi = (locale: KnownLocale): CategoryUi => CATEGORY_UI[locale];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
import
|
|
2
|
+
import AstronomyCategoryHome from "../../../../layouts/AstronomyCategoryHome.astro";
|
|
3
3
|
import { ALL_TOOLS, astronomyCategory } from "../../../../index";
|
|
4
4
|
import { LANGUAGE_CODES, type Language } from "../../../../i18n/languages";
|
|
5
5
|
import { getCategoryNamespace, getCategoryPath, getUtilityNamespace, getUtilityPath } from "../../../../mfe/routes";
|
|
@@ -41,4 +41,4 @@ const tools = await Promise.all(ALL_TOOLS.map(async ({ entry }) => {
|
|
|
41
41
|
}));
|
|
42
42
|
---
|
|
43
43
|
|
|
44
|
-
<
|
|
44
|
+
<AstronomyCategoryHome locale={locale} {category} {tools} {alternates} image={CATEGORY_OG_IMAGE} />
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
import
|
|
2
|
+
import AstronomyCategoryHome from "../../../layouts/AstronomyCategoryHome.astro";
|
|
3
3
|
import { ALL_TOOLS, astronomyCategory } from "../../../index";
|
|
4
4
|
import { LANGUAGE_CODES, type Language } from "../../../i18n/languages";
|
|
5
5
|
import { getCategoryPath, getUtilityPath } from "../../../mfe/routes";
|
|
@@ -35,4 +35,4 @@ const tools = await Promise.all(ALL_TOOLS.map(async ({ entry }) => {
|
|
|
35
35
|
}));
|
|
36
36
|
---
|
|
37
37
|
|
|
38
|
-
<
|
|
38
|
+
<AstronomyCategoryHome locale="es" {category} {tools} {alternates} image={CATEGORY_OG_IMAGE} />
|