@hagicode/hagilight 0.1.2-dev.5.1.c41051d → 0.1.2-dev.7.1.c02207e
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/Analytics51LA.astro +17 -0
- package/GoogleAnalytics.astro +21 -0
- package/PromotoBanner.astro +37 -13
- package/logo.png +0 -0
- package/package.json +9 -3
- package/promoto-banner.ts +1 -0
- package/related-sites.json +226 -0
- package/site-links.ts +400 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
interface Props {
|
|
3
|
+
siteId: string;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
const { siteId } = Astro.props;
|
|
7
|
+
if (!siteId?.trim()) throw new Error('Analytics51LA requires a siteId prop.');
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
{import.meta.env.PROD && (
|
|
11
|
+
<>
|
|
12
|
+
<script is:inline charset="UTF-8" id="LA_COLLECT" src="https://sdk.51.la/js-sdk-pro.min.js"></script>
|
|
13
|
+
<script is:inline define:vars={{ siteId }}>
|
|
14
|
+
LA.init({ id: siteId, ck: siteId, autoTrack: true, hashMode: true, screenRecord: true });
|
|
15
|
+
</script>
|
|
16
|
+
</>
|
|
17
|
+
)}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
interface Props {
|
|
3
|
+
measurementId: string;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
const { measurementId } = Astro.props;
|
|
7
|
+
if (!measurementId?.trim()) throw new Error('GoogleAnalytics requires a measurementId prop.');
|
|
8
|
+
const scriptUrl = `https://www.googletagmanager.com/gtag/js?id=${encodeURIComponent(measurementId)}`;
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
{import.meta.env.PROD && (
|
|
12
|
+
<>
|
|
13
|
+
<script async src={scriptUrl}></script>
|
|
14
|
+
<script is:inline define:vars={{ measurementId }}>
|
|
15
|
+
window.dataLayer = window.dataLayer || [];
|
|
16
|
+
function gtag(){dataLayer.push(arguments);}
|
|
17
|
+
gtag('js', new Date());
|
|
18
|
+
gtag('config', measurementId);
|
|
19
|
+
</script>
|
|
20
|
+
</>
|
|
21
|
+
)}
|
package/PromotoBanner.astro
CHANGED
|
@@ -112,11 +112,15 @@ const { fallback, locale = Astro.currentLocale ?? 'en' } = Astro.props;
|
|
|
112
112
|
|
|
113
113
|
.hagilight-promoto__title,
|
|
114
114
|
.hagilight-promoto__description {
|
|
115
|
+
display: -webkit-box;
|
|
116
|
+
overflow: hidden;
|
|
115
117
|
margin: 0;
|
|
116
118
|
color: var(--sl-color-text-high, #111827);
|
|
117
119
|
font-size: var(--sl-text-sm);
|
|
118
120
|
font-weight: 600;
|
|
119
121
|
line-height: 1.35;
|
|
122
|
+
-webkit-box-orient: vertical;
|
|
123
|
+
-webkit-line-clamp: 2;
|
|
120
124
|
}
|
|
121
125
|
|
|
122
126
|
.hagilight-promoto__description {
|
|
@@ -230,13 +234,14 @@ const { fallback, locale = Astro.currentLocale ?? 'en' } = Astro.props;
|
|
|
230
234
|
}
|
|
231
235
|
|
|
232
236
|
.hagilight-promoto__slide {
|
|
233
|
-
grid-template-columns: minmax(0, 1fr)
|
|
234
|
-
gap: 0.
|
|
235
|
-
padding: 0.
|
|
237
|
+
grid-template-columns: minmax(0, 1fr) auto;
|
|
238
|
+
gap: 0.5rem;
|
|
239
|
+
padding: 0.65rem 3.25rem 0.65rem 0.75rem;
|
|
236
240
|
}
|
|
237
241
|
|
|
238
242
|
.hagilight-promoto__copy {
|
|
239
|
-
grid-column: 1
|
|
243
|
+
grid-column: 1;
|
|
244
|
+
grid-row: 1 / 3;
|
|
240
245
|
}
|
|
241
246
|
|
|
242
247
|
.hagilight-promoto__title {
|
|
@@ -244,31 +249,50 @@ const { fallback, locale = Astro.currentLocale ?? 'en' } = Astro.props;
|
|
|
244
249
|
}
|
|
245
250
|
|
|
246
251
|
.hagilight-promoto__description {
|
|
247
|
-
display: -webkit-box;
|
|
248
|
-
overflow: hidden;
|
|
249
252
|
font-size: var(--sl-text-xs);
|
|
250
253
|
font-weight: 500;
|
|
251
|
-
-webkit-box-orient: vertical;
|
|
252
|
-
-webkit-line-clamp: 2;
|
|
253
254
|
}
|
|
254
255
|
|
|
255
256
|
.hagilight-promoto__image {
|
|
256
257
|
grid-column: 2;
|
|
257
258
|
grid-row: 1;
|
|
258
|
-
width:
|
|
259
|
+
width: 3rem;
|
|
259
260
|
}
|
|
260
261
|
|
|
261
262
|
.hagilight-promoto__cta {
|
|
262
|
-
grid-column:
|
|
263
|
-
|
|
264
|
-
min-
|
|
263
|
+
grid-column: 2;
|
|
264
|
+
grid-row: 2;
|
|
265
|
+
min-width: 4rem;
|
|
266
|
+
min-height: 1.9rem;
|
|
267
|
+
padding-inline: 0.5rem;
|
|
268
|
+
font-size: var(--sl-text-xs);
|
|
269
|
+
overflow-wrap: anywhere;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
.hagilight-promoto__slide[data-has-image='false'] {
|
|
273
|
+
grid-template-rows: auto;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
.hagilight-promoto__slide[data-has-image='false'] .hagilight-promoto__copy,
|
|
277
|
+
.hagilight-promoto__slide[data-has-image='false'] .hagilight-promoto__cta {
|
|
278
|
+
grid-row: 1;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
.hagilight-promoto__slide[data-has-image='false'] .hagilight-promoto__cta {
|
|
282
|
+
min-width: 4.5rem;
|
|
265
283
|
}
|
|
266
284
|
|
|
267
285
|
.hagilight-promoto__controls {
|
|
268
286
|
justify-content: flex-start;
|
|
269
287
|
flex-wrap: wrap;
|
|
270
288
|
gap: 0.35rem;
|
|
271
|
-
padding: 0 0.
|
|
289
|
+
padding: 0 0.75rem 0.6rem;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
.hagilight-promoto__control {
|
|
293
|
+
min-width: 2rem;
|
|
294
|
+
min-height: 2rem;
|
|
295
|
+
padding-inline: 0.5rem;
|
|
272
296
|
}
|
|
273
297
|
}
|
|
274
298
|
|
package/logo.png
ADDED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hagicode/hagilight",
|
|
3
|
-
"version": "0.1.2-dev.
|
|
3
|
+
"version": "0.1.2-dev.7.1.c02207e",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Shared Astro components for HagiCode sites",
|
|
6
6
|
"repository": {
|
|
@@ -14,11 +14,17 @@
|
|
|
14
14
|
},
|
|
15
15
|
"exports": {
|
|
16
16
|
"./Copyright": "./Copyright.astro",
|
|
17
|
-
"./PromotoBanner": "./PromotoBanner.astro"
|
|
17
|
+
"./PromotoBanner": "./PromotoBanner.astro",
|
|
18
|
+
"./logo.png": "./logo.png",
|
|
19
|
+
"./site-links": "./site-links.ts",
|
|
20
|
+
"./GoogleAnalytics": "./GoogleAnalytics.astro",
|
|
21
|
+
"./Analytics51LA": "./Analytics51LA.astro"
|
|
18
22
|
},
|
|
19
23
|
"files": [
|
|
20
24
|
"*.astro",
|
|
21
|
-
"*.
|
|
25
|
+
"*.png",
|
|
26
|
+
"*.ts",
|
|
27
|
+
"*.json"
|
|
22
28
|
],
|
|
23
29
|
"peerDependencies": {
|
|
24
30
|
"astro": "^7.3.5"
|
package/promoto-banner.ts
CHANGED
|
@@ -216,6 +216,7 @@ export function definePromotoBannerElement(): void {
|
|
|
216
216
|
this.cards.forEach((card, index) => {
|
|
217
217
|
const slide = document.createElement('article');
|
|
218
218
|
slide.className = 'hagilight-promoto__slide';
|
|
219
|
+
slide.dataset.hasImage = String(Boolean(card.image));
|
|
219
220
|
slide.setAttribute('aria-hidden', index === this.currentIndex ? 'false' : 'true');
|
|
220
221
|
if (index !== this.currentIndex) slide.setAttribute('inert', '');
|
|
221
222
|
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"id": "hagicode-main",
|
|
4
|
+
"name": {
|
|
5
|
+
"zh-CN": "HagiCode 主站",
|
|
6
|
+
"zh-Hant": "HagiCode 主站",
|
|
7
|
+
"en-US": "HagiCode Main Site",
|
|
8
|
+
"ja-JP": "HagiCode 公式サイト",
|
|
9
|
+
"ko-KR": "HagiCode 메인 사이트",
|
|
10
|
+
"de-DE": "HagiCode Hauptseite",
|
|
11
|
+
"fr-FR": "Site principal HagiCode",
|
|
12
|
+
"es-ES": "Sitio principal de HagiCode",
|
|
13
|
+
"pt-BR": "Site principal da HagiCode",
|
|
14
|
+
"ru-RU": "Главный сайт HagiCode"
|
|
15
|
+
},
|
|
16
|
+
"description": {
|
|
17
|
+
"zh-CN": "产品入口",
|
|
18
|
+
"zh-Hant": "產品入口",
|
|
19
|
+
"en-US": "Primary product entry.",
|
|
20
|
+
"ja-JP": "製品全体の入口です。",
|
|
21
|
+
"ko-KR": "제품으로 들어가는 기본 진입점입니다.",
|
|
22
|
+
"de-DE": "Zentraler Einstieg zum Produkt.",
|
|
23
|
+
"fr-FR": "Point d'entrée principal du produit.",
|
|
24
|
+
"es-ES": "Entrada principal al producto.",
|
|
25
|
+
"pt-BR": "Entrada principal do produto.",
|
|
26
|
+
"ru-RU": "Основной вход в продукт."
|
|
27
|
+
},
|
|
28
|
+
"url": "https://www.hagicode.com/"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"id": "newbe-blog",
|
|
32
|
+
"name": {
|
|
33
|
+
"zh-CN": "newbe",
|
|
34
|
+
"zh-Hant": "newbe",
|
|
35
|
+
"en-US": "newbe",
|
|
36
|
+
"ja-JP": "newbe",
|
|
37
|
+
"ko-KR": "newbe",
|
|
38
|
+
"de-DE": "newbe",
|
|
39
|
+
"fr-FR": "newbe",
|
|
40
|
+
"es-ES": "newbe",
|
|
41
|
+
"pt-BR": "newbe",
|
|
42
|
+
"ru-RU": "newbe"
|
|
43
|
+
},
|
|
44
|
+
"description": {
|
|
45
|
+
"zh-CN": "作者博客",
|
|
46
|
+
"zh-Hant": "作者部落格",
|
|
47
|
+
"en-US": "Author blog.",
|
|
48
|
+
"ja-JP": "作者ブログです。",
|
|
49
|
+
"ko-KR": "작성자 블로그입니다.",
|
|
50
|
+
"de-DE": "Blog des Autors.",
|
|
51
|
+
"fr-FR": "Blog de l'auteur.",
|
|
52
|
+
"es-ES": "Blog del autor.",
|
|
53
|
+
"pt-BR": "Blog do autor.",
|
|
54
|
+
"ru-RU": "Блог автора."
|
|
55
|
+
},
|
|
56
|
+
"url": "https://newbe.hagicode.com/"
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"id": "index-data",
|
|
60
|
+
"name": {
|
|
61
|
+
"zh-CN": "Index Data Mirror",
|
|
62
|
+
"zh-Hant": "Index Data Mirror",
|
|
63
|
+
"en-US": "Index Data Mirror",
|
|
64
|
+
"ja-JP": "Index Data Mirror",
|
|
65
|
+
"ko-KR": "Index Data Mirror",
|
|
66
|
+
"de-DE": "Index Data Mirror",
|
|
67
|
+
"fr-FR": "Index Data Mirror",
|
|
68
|
+
"es-ES": "Index Data Mirror",
|
|
69
|
+
"pt-BR": "Index Data Mirror",
|
|
70
|
+
"ru-RU": "Index Data Mirror"
|
|
71
|
+
},
|
|
72
|
+
"description": {
|
|
73
|
+
"zh-CN": "公开数据",
|
|
74
|
+
"zh-Hant": "公開資料",
|
|
75
|
+
"en-US": "Public data mirror.",
|
|
76
|
+
"ja-JP": "公開データミラーです。",
|
|
77
|
+
"ko-KR": "공개 데이터 미러입니다.",
|
|
78
|
+
"de-DE": "Öffentlicher Daten-Spiegel.",
|
|
79
|
+
"fr-FR": "Miroir de données public.",
|
|
80
|
+
"es-ES": "Espejo de datos público.",
|
|
81
|
+
"pt-BR": "Espelho público de dados.",
|
|
82
|
+
"ru-RU": "Публичное зеркало данных."
|
|
83
|
+
},
|
|
84
|
+
"url": "https://index.hagicode.com/data/"
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"id": "compose-builder",
|
|
88
|
+
"name": {
|
|
89
|
+
"zh-CN": "Docker Compose Builder",
|
|
90
|
+
"zh-Hant": "Docker Compose Builder",
|
|
91
|
+
"en-US": "Docker Compose Builder",
|
|
92
|
+
"ja-JP": "Docker Compose Builder",
|
|
93
|
+
"ko-KR": "Docker Compose Builder",
|
|
94
|
+
"de-DE": "Docker Compose Builder",
|
|
95
|
+
"fr-FR": "Docker Compose Builder",
|
|
96
|
+
"es-ES": "Docker Compose Builder",
|
|
97
|
+
"pt-BR": "Docker Compose Builder",
|
|
98
|
+
"ru-RU": "Docker Compose Builder"
|
|
99
|
+
},
|
|
100
|
+
"description": {
|
|
101
|
+
"zh-CN": "Docker 部署 Hagicode",
|
|
102
|
+
"zh-Hant": "使用 Docker 部署 Hagicode",
|
|
103
|
+
"en-US": "Deploy HagiCode with Docker.",
|
|
104
|
+
"ja-JP": "Docker で HagiCode をデプロイします。",
|
|
105
|
+
"ko-KR": "Docker로 HagiCode를 배포합니다.",
|
|
106
|
+
"de-DE": "HagiCode mit Docker bereitstellen.",
|
|
107
|
+
"fr-FR": "Déployer HagiCode avec Docker.",
|
|
108
|
+
"es-ES": "Despliega HagiCode con Docker.",
|
|
109
|
+
"pt-BR": "Implante a HagiCode com Docker.",
|
|
110
|
+
"ru-RU": "Развёртывание HagiCode через Docker."
|
|
111
|
+
},
|
|
112
|
+
"url": "https://builder.hagicode.com/"
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
"id": "status-page",
|
|
116
|
+
"name": {
|
|
117
|
+
"zh-CN": "HagiCode Status",
|
|
118
|
+
"zh-Hant": "HagiCode Status",
|
|
119
|
+
"en-US": "HagiCode Status",
|
|
120
|
+
"ja-JP": "HagiCode Status",
|
|
121
|
+
"ko-KR": "HagiCode Status",
|
|
122
|
+
"de-DE": "HagiCode Status",
|
|
123
|
+
"fr-FR": "HagiCode Status",
|
|
124
|
+
"es-ES": "HagiCode Status",
|
|
125
|
+
"pt-BR": "HagiCode Status",
|
|
126
|
+
"ru-RU": "HagiCode Status"
|
|
127
|
+
},
|
|
128
|
+
"description": {
|
|
129
|
+
"zh-CN": "服务状态",
|
|
130
|
+
"zh-Hant": "服務狀態",
|
|
131
|
+
"en-US": "Service status.",
|
|
132
|
+
"ja-JP": "サービス状態の確認ページです。",
|
|
133
|
+
"ko-KR": "서비스 상태를 확인하는 페이지입니다.",
|
|
134
|
+
"de-DE": "Dienststatus.",
|
|
135
|
+
"fr-FR": "État des services.",
|
|
136
|
+
"es-ES": "Estado del servicio.",
|
|
137
|
+
"pt-BR": "Status do serviço.",
|
|
138
|
+
"ru-RU": "Статус сервисов."
|
|
139
|
+
},
|
|
140
|
+
"url": "https://status.hagicode.com/"
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
"id": "awesome-design-gallery",
|
|
144
|
+
"name": {
|
|
145
|
+
"zh-CN": "Awesome Design MD",
|
|
146
|
+
"zh-Hant": "Awesome Design MD",
|
|
147
|
+
"en-US": "Awesome Design MD",
|
|
148
|
+
"ja-JP": "Awesome Design MD",
|
|
149
|
+
"ko-KR": "Awesome Design MD",
|
|
150
|
+
"de-DE": "Awesome Design MD",
|
|
151
|
+
"fr-FR": "Awesome Design MD",
|
|
152
|
+
"es-ES": "Awesome Design MD",
|
|
153
|
+
"pt-BR": "Awesome Design MD",
|
|
154
|
+
"ru-RU": "Awesome Design MD"
|
|
155
|
+
},
|
|
156
|
+
"description": {
|
|
157
|
+
"zh-CN": "超酷的AI Web 设计",
|
|
158
|
+
"zh-Hant": "超酷的 AI Web 設計",
|
|
159
|
+
"en-US": "A gallery of standout AI web design work.",
|
|
160
|
+
"ja-JP": "印象的な AI Web デザインを集めたギャラリーです。",
|
|
161
|
+
"ko-KR": "인상적인 AI 웹 디자인을 모아 둔 갤러리입니다.",
|
|
162
|
+
"de-DE": "Galerie mit markanten AI-Webdesigns.",
|
|
163
|
+
"fr-FR": "Galerie de designs web IA remarquables.",
|
|
164
|
+
"es-ES": "Galería de diseños web de IA destacados.",
|
|
165
|
+
"pt-BR": "Galeria com designs web de IA de destaque.",
|
|
166
|
+
"ru-RU": "Галерея выразительных AI web-дизайнов."
|
|
167
|
+
},
|
|
168
|
+
"url": "https://design.hagicode.com/"
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
"id": "soul-builder",
|
|
172
|
+
"name": {
|
|
173
|
+
"zh-CN": "Soul Builder",
|
|
174
|
+
"zh-Hant": "Soul Builder",
|
|
175
|
+
"en-US": "Soul Builder",
|
|
176
|
+
"ja-JP": "Soul Builder",
|
|
177
|
+
"ko-KR": "Soul Builder",
|
|
178
|
+
"de-DE": "Soul Builder",
|
|
179
|
+
"fr-FR": "Soul Builder",
|
|
180
|
+
"es-ES": "Soul Builder",
|
|
181
|
+
"pt-BR": "Soul Builder",
|
|
182
|
+
"ru-RU": "Soul Builder"
|
|
183
|
+
},
|
|
184
|
+
"description": {
|
|
185
|
+
"zh-CN": "Agent之魂",
|
|
186
|
+
"zh-Hant": "Agent 之魂",
|
|
187
|
+
"en-US": "Define the soul of an agent.",
|
|
188
|
+
"ja-JP": "Agent の魂を形にする体験です。",
|
|
189
|
+
"ko-KR": "에이전트의 영혼을 설계하는 경험입니다.",
|
|
190
|
+
"de-DE": "Forme die Seele eines Agenten.",
|
|
191
|
+
"fr-FR": "Façonnez l'âme d'un agent.",
|
|
192
|
+
"es-ES": "Define el alma de un agente.",
|
|
193
|
+
"pt-BR": "Defina a alma de um agente.",
|
|
194
|
+
"ru-RU": "Определите душу агента."
|
|
195
|
+
},
|
|
196
|
+
"url": "https://soul.hagicode.com/"
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
"id": "trait-builder",
|
|
200
|
+
"name": {
|
|
201
|
+
"zh-CN": "Trait Builder",
|
|
202
|
+
"zh-Hant": "Trait Builder",
|
|
203
|
+
"en-US": "Trait Builder",
|
|
204
|
+
"ja-JP": "Trait Builder",
|
|
205
|
+
"ko-KR": "Trait Builder",
|
|
206
|
+
"de-DE": "Trait Builder",
|
|
207
|
+
"fr-FR": "Trait Builder",
|
|
208
|
+
"es-ES": "Trait Builder",
|
|
209
|
+
"pt-BR": "Trait Builder",
|
|
210
|
+
"ru-RU": "Trait Builder"
|
|
211
|
+
},
|
|
212
|
+
"description": {
|
|
213
|
+
"zh-CN": "Agent之能",
|
|
214
|
+
"zh-Hant": "Agent 之能",
|
|
215
|
+
"en-US": "Shape what an agent can do.",
|
|
216
|
+
"ja-JP": "Agent の能力を組み立てる体験です。",
|
|
217
|
+
"ko-KR": "에이전트의 능력을 설계하는 경험입니다.",
|
|
218
|
+
"de-DE": "Definiere, was ein Agent kann.",
|
|
219
|
+
"fr-FR": "Définissez ce qu'un agent peut faire.",
|
|
220
|
+
"es-ES": "Define lo que un agente puede hacer.",
|
|
221
|
+
"pt-BR": "Defina o que um agente pode fazer.",
|
|
222
|
+
"ru-RU": "Соберите способности агента."
|
|
223
|
+
},
|
|
224
|
+
"url": "https://trait.hagicode.com/"
|
|
225
|
+
}
|
|
226
|
+
]
|
package/site-links.ts
ADDED
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
import docsRelatedSites from './related-sites.json' with { type: 'json' };
|
|
2
|
+
|
|
3
|
+
export type SiteLinkKey =
|
|
4
|
+
| 'home'
|
|
5
|
+
| 'blog'
|
|
6
|
+
| 'support'
|
|
7
|
+
| 'downloadClient'
|
|
8
|
+
| 'about'
|
|
9
|
+
| 'dockerCompose'
|
|
10
|
+
| 'productDocs'
|
|
11
|
+
| 'blogPosts'
|
|
12
|
+
| 'rss'
|
|
13
|
+
| 'costCalculator'
|
|
14
|
+
| 'github'
|
|
15
|
+
| 'discord'
|
|
16
|
+
| 'issueFeedback'
|
|
17
|
+
| 'contactEmail'
|
|
18
|
+
| 'qqGroup'
|
|
19
|
+
| 'steam'
|
|
20
|
+
| 'icpFiling'
|
|
21
|
+
| 'publicSecurityFiling';
|
|
22
|
+
|
|
23
|
+
export type LinkGroup = 'header' | 'quick' | 'community' | 'filings';
|
|
24
|
+
type LocalizedText = string | Readonly<Record<string, string>>;
|
|
25
|
+
|
|
26
|
+
export interface SiteLink {
|
|
27
|
+
id: SiteLinkKey | string;
|
|
28
|
+
label: string;
|
|
29
|
+
href: string;
|
|
30
|
+
ariaLabel?: string;
|
|
31
|
+
target?: '_blank';
|
|
32
|
+
rel?: 'noopener noreferrer';
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface SiteLinkOverride {
|
|
36
|
+
href?: LocalizedText;
|
|
37
|
+
label?: LocalizedText;
|
|
38
|
+
external?: boolean;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface ExtraSiteLink extends SiteLinkOverride {
|
|
42
|
+
href: LocalizedText;
|
|
43
|
+
label: LocalizedText;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface RelatedSite {
|
|
47
|
+
id: string;
|
|
48
|
+
name: LocalizedText;
|
|
49
|
+
url: string;
|
|
50
|
+
description?: LocalizedText;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface SiteLinksOptions {
|
|
54
|
+
overrides?: Partial<Record<SiteLinkKey, SiteLinkOverride>>;
|
|
55
|
+
extraLinks?: Partial<Record<LinkGroup, readonly ExtraSiteLink[]>>;
|
|
56
|
+
relatedSites?: readonly RelatedSite[];
|
|
57
|
+
siteId?: string;
|
|
58
|
+
siteUrl?: string;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
interface LinkDefinition {
|
|
62
|
+
label: LocalizedText;
|
|
63
|
+
href: string | ((locale: string) => string);
|
|
64
|
+
external?: boolean;
|
|
65
|
+
ariaLabel?: LocalizedText;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const translations = {
|
|
69
|
+
home: {
|
|
70
|
+
'zh-CN': '首页', 'zh-Hant': '首頁', 'en-US': 'Home', 'ja-JP': 'ホーム',
|
|
71
|
+
'ko-KR': '홈', 'de-DE': 'Startseite', 'fr-FR': 'Accueil', 'es-ES': 'Inicio',
|
|
72
|
+
'pt-BR': 'Início', 'ru-RU': 'Главная',
|
|
73
|
+
},
|
|
74
|
+
blog: {
|
|
75
|
+
'zh-CN': '博客', 'zh-Hant': '部落格', 'en-US': 'Blog', 'ja-JP': 'ブログ',
|
|
76
|
+
'ko-KR': '블로그', 'de-DE': 'Blog', 'fr-FR': 'Blog', 'es-ES': 'Blog',
|
|
77
|
+
'pt-BR': 'Blog', 'ru-RU': 'Блог',
|
|
78
|
+
},
|
|
79
|
+
support: {
|
|
80
|
+
'zh-CN': '获取技术支持', 'zh-Hant': '獲取技術支援', 'en-US': 'Get Support',
|
|
81
|
+
'ja-JP': 'サポート', 'ko-KR': '기술 지원', 'de-DE': 'Support',
|
|
82
|
+
'fr-FR': 'Assistance', 'es-ES': 'Soporte', 'pt-BR': 'Suporte', 'ru-RU': 'Поддержка',
|
|
83
|
+
},
|
|
84
|
+
downloadClient: {
|
|
85
|
+
'zh-CN': '下载客户端', 'zh-Hant': '下載客戶端', 'en-US': 'Download Client',
|
|
86
|
+
'ja-JP': 'クライアントをダウンロード', 'ko-KR': '클라이언트 다운로드',
|
|
87
|
+
'de-DE': 'Client herunterladen', 'fr-FR': 'Télécharger le client',
|
|
88
|
+
'es-ES': 'Descargar cliente', 'pt-BR': 'Baixar cliente', 'ru-RU': 'Скачать клиент',
|
|
89
|
+
},
|
|
90
|
+
about: {
|
|
91
|
+
'zh-CN': '关于 HagiCode', 'zh-Hant': '關於 HagiCode', 'en-US': 'About HagiCode',
|
|
92
|
+
'ja-JP': 'HagiCode について', 'ko-KR': 'HagiCode 소개', 'de-DE': 'Über HagiCode',
|
|
93
|
+
'fr-FR': 'À propos de HagiCode', 'es-ES': 'Acerca de HagiCode',
|
|
94
|
+
'pt-BR': 'Sobre a HagiCode', 'ru-RU': 'О HagiCode',
|
|
95
|
+
},
|
|
96
|
+
dockerCompose: {
|
|
97
|
+
'zh-CN': 'Docker Compose 安装', 'zh-Hant': 'Docker Compose 安裝',
|
|
98
|
+
'en-US': 'Docker Compose Installation', 'ja-JP': 'Docker Compose インストール',
|
|
99
|
+
'ko-KR': 'Docker Compose 설치', 'de-DE': 'Docker-Compose-Installation',
|
|
100
|
+
'fr-FR': 'Installation de Docker Compose', 'es-ES': 'Instalación de Docker Compose',
|
|
101
|
+
'pt-BR': 'Instalação do Docker Compose', 'ru-RU': 'Установка Docker Compose',
|
|
102
|
+
},
|
|
103
|
+
productDocs: {
|
|
104
|
+
'zh-CN': '产品文档', 'zh-Hant': '產品文件', 'en-US': 'Product Docs',
|
|
105
|
+
'ja-JP': '製品ドキュメント', 'ko-KR': '제품 문서', 'de-DE': 'Produktdokumentation',
|
|
106
|
+
'fr-FR': 'Documentation produit', 'es-ES': 'Documentación del producto',
|
|
107
|
+
'pt-BR': 'Documentação do produto', 'ru-RU': 'Документация продукта',
|
|
108
|
+
},
|
|
109
|
+
blogPosts: {
|
|
110
|
+
'zh-CN': '博客文章', 'zh-Hant': '部落格文章', 'en-US': 'Blog Posts',
|
|
111
|
+
'ja-JP': 'ブログ記事', 'ko-KR': '블로그 글', 'de-DE': 'Blogbeiträge',
|
|
112
|
+
'fr-FR': 'Articles du blog', 'es-ES': 'Artículos del blog',
|
|
113
|
+
'pt-BR': 'Posts do blog', 'ru-RU': 'Статьи блога',
|
|
114
|
+
},
|
|
115
|
+
rss: {
|
|
116
|
+
'zh-CN': 'RSS 订阅', 'zh-Hant': 'RSS 訂閱', 'en-US': 'RSS Feed',
|
|
117
|
+
'ja-JP': 'RSS 配信', 'ko-KR': 'RSS 구독', 'de-DE': 'RSS-Feed',
|
|
118
|
+
'fr-FR': 'Flux RSS', 'es-ES': 'RSS', 'pt-BR': 'Feed RSS', 'ru-RU': 'RSS-лента',
|
|
119
|
+
},
|
|
120
|
+
costCalculator: {
|
|
121
|
+
'zh-CN': '算一算,AI会不会淘汰我', 'zh-Hant': '算一算,AI 會不會淘汰我',
|
|
122
|
+
'en-US': 'Will AI Replace Me?', 'ja-JP': 'AI に置き換えられるか診断',
|
|
123
|
+
'ko-KR': 'AI가 나를 대체할까?', 'de-DE': 'Wird KI mich ersetzen?',
|
|
124
|
+
'fr-FR': "L'IA va-t-elle me remplacer ?", 'es-ES': 'Me reemplazará la IA?',
|
|
125
|
+
'pt-BR': 'A IA vai me substituir?', 'ru-RU': 'Заменит ли меня ИИ?',
|
|
126
|
+
},
|
|
127
|
+
github: {
|
|
128
|
+
'zh-CN': 'GitHub', 'zh-Hant': 'GitHub', 'en-US': 'GitHub', 'ja-JP': 'GitHub',
|
|
129
|
+
'ko-KR': 'GitHub', 'de-DE': 'GitHub', 'fr-FR': 'GitHub', 'es-ES': 'GitHub',
|
|
130
|
+
'pt-BR': 'GitHub', 'ru-RU': 'GitHub',
|
|
131
|
+
},
|
|
132
|
+
discord: {
|
|
133
|
+
'zh-CN': 'Discord', 'zh-Hant': 'Discord', 'en-US': 'Discord', 'ja-JP': 'Discord',
|
|
134
|
+
'ko-KR': 'Discord', 'de-DE': 'Discord', 'fr-FR': 'Discord', 'es-ES': 'Discord',
|
|
135
|
+
'pt-BR': 'Discord', 'ru-RU': 'Discord',
|
|
136
|
+
},
|
|
137
|
+
issueFeedback: {
|
|
138
|
+
'zh-CN': '问题反馈', 'zh-Hant': '問題回饋', 'en-US': 'Issue Feedback',
|
|
139
|
+
'ja-JP': '問題の報告', 'ko-KR': '문제 신고', 'de-DE': 'Probleme melden',
|
|
140
|
+
'fr-FR': 'Signaler un problème', 'es-ES': 'Reportar un problema',
|
|
141
|
+
'pt-BR': 'Relatar problema', 'ru-RU': 'Сообщить о проблеме',
|
|
142
|
+
},
|
|
143
|
+
contactEmail: {
|
|
144
|
+
'zh-CN': '联系邮箱', 'zh-Hant': '聯絡信箱', 'en-US': 'Contact Email',
|
|
145
|
+
'ja-JP': '連絡先メール', 'ko-KR': '문의 이메일', 'de-DE': 'Kontakt-E-Mail',
|
|
146
|
+
'fr-FR': 'E-mail de contact', 'es-ES': 'Correo de contacto',
|
|
147
|
+
'pt-BR': 'E-mail de contato', 'ru-RU': 'Контактный email',
|
|
148
|
+
},
|
|
149
|
+
qqGroup: {
|
|
150
|
+
'zh-CN': 'QQ 群 610394020', 'zh-Hant': 'QQ 群 610394020',
|
|
151
|
+
'en-US': 'QQ Group 610394020', 'ja-JP': 'QQ グループ 610394020',
|
|
152
|
+
'ko-KR': 'QQ 그룹 610394020', 'de-DE': 'QQ-Gruppe 610394020',
|
|
153
|
+
'fr-FR': 'Groupe QQ 610394020', 'es-ES': 'Grupo QQ 610394020',
|
|
154
|
+
'pt-BR': 'Grupo QQ 610394020', 'ru-RU': 'Группа QQ 610394020',
|
|
155
|
+
},
|
|
156
|
+
steam: {
|
|
157
|
+
'zh-CN': 'Steam', 'zh-Hant': 'Steam', 'en-US': 'Steam', 'ja-JP': 'Steam',
|
|
158
|
+
'ko-KR': 'Steam', 'de-DE': 'Steam', 'fr-FR': 'Steam', 'es-ES': 'Steam',
|
|
159
|
+
'pt-BR': 'Steam', 'ru-RU': 'Steam',
|
|
160
|
+
},
|
|
161
|
+
icpFiling: '闽ICP备2026004153号-1',
|
|
162
|
+
publicSecurityFiling: '闽公网安备35011102351148号',
|
|
163
|
+
} satisfies Record<SiteLinkKey, LocalizedText>;
|
|
164
|
+
|
|
165
|
+
const defaultLinks: Record<SiteLinkKey, LinkDefinition> = {
|
|
166
|
+
home: { label: translations.home, href: (locale) => marketingPath(locale, '/') },
|
|
167
|
+
blog: { label: translations.blog, href: (locale) => docsPath(locale, '/blog/') },
|
|
168
|
+
support: { label: translations.support, href: (locale) => marketingPath(locale, '/about/') },
|
|
169
|
+
downloadClient: { label: translations.downloadClient, href: (locale) => marketingPath(locale, '/desktop/') },
|
|
170
|
+
about: { label: translations.about, href: (locale) => marketingPath(locale, '/about/') },
|
|
171
|
+
dockerCompose: { label: translations.dockerCompose, href: (locale) => docsPath(locale, '/installation/docker-compose/') },
|
|
172
|
+
productDocs: { label: translations.productDocs, href: (locale) => docsPath(locale, '/product-overview/') },
|
|
173
|
+
blogPosts: { label: translations.blogPosts, href: (locale) => docsPath(locale, '/blog/') },
|
|
174
|
+
rss: { label: translations.rss, href: (locale) => `https://docs.hagicode.com/blog/rss.${locale}.xml` },
|
|
175
|
+
costCalculator: { label: translations.costCalculator, href: 'https://cost.hagicode.com', external: true },
|
|
176
|
+
github: { label: translations.github, href: 'https://github.com/HagiCode-org/site', external: true },
|
|
177
|
+
discord: { label: translations.discord, href: 'https://discord.gg/qY662sJK', external: true },
|
|
178
|
+
issueFeedback: { label: translations.issueFeedback, href: 'https://github.com/HagiCode-org/site/issues', external: true },
|
|
179
|
+
contactEmail: { label: translations.contactEmail, href: 'mailto:support@hagicode.com' },
|
|
180
|
+
qqGroup: { label: translations.qqGroup, href: 'https://qm.qq.com/q/Fwb0o094kw', external: true },
|
|
181
|
+
steam: { label: translations.steam, href: 'https://store.steampowered.com/app/4625540/Hagicode/', external: true },
|
|
182
|
+
icpFiling: {
|
|
183
|
+
label: translations.icpFiling,
|
|
184
|
+
href: 'https://beian.miit.gov.cn/',
|
|
185
|
+
external: true,
|
|
186
|
+
ariaLabel: {
|
|
187
|
+
'zh-CN': '查看 ICP 备案信息', 'zh-Hant': '查看 ICP 備案資訊',
|
|
188
|
+
'en-US': 'View ICP filing information', 'ja-JP': 'ICP 登録情報を表示',
|
|
189
|
+
'ko-KR': 'ICP 등록 정보 보기', 'de-DE': 'ICP-Registrierungsinformationen anzeigen',
|
|
190
|
+
'fr-FR': 'Voir les informations de dépôt ICP', 'es-ES': 'Ver la información de registro ICP',
|
|
191
|
+
'pt-BR': 'Ver informações de registro ICP', 'ru-RU': 'Показать информацию о регистрации ICP',
|
|
192
|
+
},
|
|
193
|
+
},
|
|
194
|
+
publicSecurityFiling: {
|
|
195
|
+
label: translations.publicSecurityFiling,
|
|
196
|
+
href: 'http://www.beian.gov.cn/portal/registerSystemInfo',
|
|
197
|
+
external: true,
|
|
198
|
+
ariaLabel: {
|
|
199
|
+
'zh-CN': '查看公安备案信息', 'zh-Hant': '查看公安備案資訊',
|
|
200
|
+
'en-US': 'View public security filing information', 'ja-JP': '公安登録情報を表示',
|
|
201
|
+
'ko-KR': '공안 등록 정보 보기', 'de-DE': 'Informationen zur Sicherheitsregistrierung anzeigen',
|
|
202
|
+
'fr-FR': 'Voir les informations de dépôt de sécurité publique',
|
|
203
|
+
'es-ES': 'Ver la información de registro de seguridad pública',
|
|
204
|
+
'pt-BR': 'Ver informações de registro de segurança pública',
|
|
205
|
+
'ru-RU': 'Показать информацию о регистрации в органах общественной безопасности',
|
|
206
|
+
},
|
|
207
|
+
},
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
const groups: Record<LinkGroup, readonly SiteLinkKey[]> = {
|
|
211
|
+
header: ['home', 'blog', 'support'],
|
|
212
|
+
quick: ['downloadClient', 'about', 'dockerCompose', 'productDocs', 'blogPosts', 'rss'],
|
|
213
|
+
community: ['github', 'discord', 'issueFeedback', 'contactEmail', 'qqGroup', 'costCalculator', 'steam'],
|
|
214
|
+
filings: ['icpFiling', 'publicSecurityFiling'],
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
function normalizeLocale(locale?: string | null): string {
|
|
218
|
+
const normalized = locale?.trim().replaceAll('_', '-').toLowerCase();
|
|
219
|
+
if (normalized === 'zh' || normalized === 'zh-cn' || normalized === 'zh-hans' || normalized === 'root') {
|
|
220
|
+
return 'zh-CN';
|
|
221
|
+
}
|
|
222
|
+
if (normalized === 'zh-hant' || normalized === 'zh-tw' || normalized === 'zh-hk') {
|
|
223
|
+
return 'zh-Hant';
|
|
224
|
+
}
|
|
225
|
+
if (normalized === 'en' || normalized === 'en-us' || !normalized) {
|
|
226
|
+
return 'en-US';
|
|
227
|
+
}
|
|
228
|
+
const canonical = ['ja-JP', 'ko-KR', 'de-DE', 'fr-FR', 'es-ES', 'pt-BR', 'ru-RU']
|
|
229
|
+
.find((candidate) => candidate.toLowerCase() === normalized);
|
|
230
|
+
if (canonical) return canonical;
|
|
231
|
+
return 'en-US';
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
function docsPath(locale: string, pathname: string): string {
|
|
235
|
+
const routePrefix = locale === 'zh-CN' ? '' : `/${locale}`;
|
|
236
|
+
return `https://docs.hagicode.com${routePrefix}${pathname}`;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
function marketingPath(locale: string, pathname: string): string {
|
|
240
|
+
return `https://www.hagicode.com/${locale}${pathname}`;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
function resolveLocalized(value: LocalizedText, locale: string, fallback: string): string {
|
|
244
|
+
if (typeof value === 'string') return value;
|
|
245
|
+
for (const candidate of [locale, ...(locale === 'zh-Hant' ? ['zh-CN', 'en-US'] : ['en-US'])]) {
|
|
246
|
+
const text = value[candidate];
|
|
247
|
+
if (typeof text === 'string' && text.trim()) return text;
|
|
248
|
+
}
|
|
249
|
+
const firstValue = Object.values(value).find((text) => typeof text === 'string' && text.trim());
|
|
250
|
+
return firstValue ?? fallback;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
function normalizeUrl(value: string): string {
|
|
254
|
+
const input = value.trim();
|
|
255
|
+
if (!input) throw new TypeError('Link destinations must not be empty.');
|
|
256
|
+
const url = new URL(input, 'https://hagilight.invalid');
|
|
257
|
+
if (!['http:', 'https:', 'mailto:', 'tel:'].includes(url.protocol)) {
|
|
258
|
+
throw new TypeError(`Unsupported link protocol: ${url.protocol}`);
|
|
259
|
+
}
|
|
260
|
+
url.hash = '';
|
|
261
|
+
url.search = '';
|
|
262
|
+
url.pathname = url.pathname.replace(/\/+$/u, '') || '/';
|
|
263
|
+
return url.origin === 'https://hagilight.invalid' ? url.pathname : url.toString();
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
function resolveLink(
|
|
267
|
+
key: SiteLinkKey | string,
|
|
268
|
+
locale: string,
|
|
269
|
+
definition: LinkDefinition,
|
|
270
|
+
override?: SiteLinkOverride,
|
|
271
|
+
): SiteLink {
|
|
272
|
+
const defaultHref = typeof definition.href === 'function' ? definition.href(locale) : definition.href;
|
|
273
|
+
const href = override?.href === undefined ? defaultHref : resolveLocalized(override.href, locale, defaultHref);
|
|
274
|
+
const label = override?.label === undefined
|
|
275
|
+
? resolveLocalized(definition.label, locale, key)
|
|
276
|
+
: resolveLocalized(override.label, locale, resolveLocalized(definition.label, locale, key));
|
|
277
|
+
normalizeUrl(href);
|
|
278
|
+
const external = override?.external ?? definition.external ?? false;
|
|
279
|
+
return {
|
|
280
|
+
id: key,
|
|
281
|
+
label,
|
|
282
|
+
href,
|
|
283
|
+
...(definition.ariaLabel
|
|
284
|
+
? { ariaLabel: resolveLocalized(definition.ariaLabel, locale, label) }
|
|
285
|
+
: {}),
|
|
286
|
+
...(external ? { target: '_blank', rel: 'noopener noreferrer' } : {}),
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
export function resolveSiteLinks(localeInput?: string | null, options: SiteLinksOptions = {}) {
|
|
291
|
+
const locale = normalizeLocale(localeInput);
|
|
292
|
+
const resolvedGroups = Object.fromEntries(
|
|
293
|
+
(Object.keys(groups) as LinkGroup[]).map((group) => {
|
|
294
|
+
const catalogLinks = groups[group].map((key) => {
|
|
295
|
+
const override = options.overrides?.[key]
|
|
296
|
+
?? (key === 'blogPosts' ? options.overrides?.blog : undefined);
|
|
297
|
+
return resolveLink(key, locale, defaultLinks[key], override);
|
|
298
|
+
});
|
|
299
|
+
const extraLinks = (options.extraLinks?.[group] ?? []).map((entry, index) => {
|
|
300
|
+
const definition: LinkDefinition = {
|
|
301
|
+
label: entry.label,
|
|
302
|
+
href: resolveLocalized(entry.href, locale, ''),
|
|
303
|
+
external: entry.external,
|
|
304
|
+
};
|
|
305
|
+
return resolveLink(`${group}-custom-${index + 1}`, locale, definition);
|
|
306
|
+
});
|
|
307
|
+
return [group, [...catalogLinks, ...extraLinks]];
|
|
308
|
+
}),
|
|
309
|
+
) as Record<LinkGroup, SiteLink[]>;
|
|
310
|
+
|
|
311
|
+
const renderedUrls = new Set(
|
|
312
|
+
[...resolvedGroups.quick, ...resolvedGroups.community, ...resolvedGroups.filings]
|
|
313
|
+
.map((link) => normalizeUrl(link.href)),
|
|
314
|
+
);
|
|
315
|
+
if (options.siteUrl) renderedUrls.add(normalizeUrl(options.siteUrl));
|
|
316
|
+
|
|
317
|
+
const relatedIds = new Set<string>();
|
|
318
|
+
const relatedUrls = new Set<string>();
|
|
319
|
+
const relatedSites = (options.relatedSites ?? docsRelatedSites).flatMap((site) => {
|
|
320
|
+
const href = site.id === 'hagicode-main' && !options.relatedSites
|
|
321
|
+
? marketingPath(locale, '/')
|
|
322
|
+
: site.url;
|
|
323
|
+
const normalizedUrl = normalizeUrl(href);
|
|
324
|
+
if (site.id === options.siteId || renderedUrls.has(normalizedUrl)
|
|
325
|
+
|| relatedIds.has(site.id) || relatedUrls.has(normalizedUrl)) {
|
|
326
|
+
return [];
|
|
327
|
+
}
|
|
328
|
+
relatedIds.add(site.id);
|
|
329
|
+
relatedUrls.add(normalizedUrl);
|
|
330
|
+
return [{
|
|
331
|
+
id: site.id,
|
|
332
|
+
name: resolveLocalized(site.name, locale, site.id),
|
|
333
|
+
description: site.description
|
|
334
|
+
? resolveLocalized(site.description, locale, '')
|
|
335
|
+
: undefined,
|
|
336
|
+
href,
|
|
337
|
+
target: '_blank' as const,
|
|
338
|
+
rel: 'noopener noreferrer' as const,
|
|
339
|
+
}];
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
return {
|
|
343
|
+
locale,
|
|
344
|
+
labels: {
|
|
345
|
+
relatedSites: resolveLocalized({
|
|
346
|
+
'zh-CN': '生态站点', 'zh-Hant': '生態站點', 'en-US': 'Ecosystem Sites',
|
|
347
|
+
'ja-JP': 'エコシステムサイト', 'ko-KR': '에코시스템 사이트',
|
|
348
|
+
'de-DE': 'Ökosystem-Seiten', 'fr-FR': "Sites de l'écosystème",
|
|
349
|
+
'es-ES': 'Sitios del ecosistema', 'pt-BR': 'Sites do ecossistema',
|
|
350
|
+
'ru-RU': 'Сайты экосистемы',
|
|
351
|
+
}, locale, 'Ecosystem Sites'),
|
|
352
|
+
quickLinks: resolveLocalized({
|
|
353
|
+
'zh-CN': '快速链接', 'zh-Hant': '快速連結', 'en-US': 'Quick Links',
|
|
354
|
+
'ja-JP': 'クイックリンク', 'ko-KR': '빠른 링크', 'de-DE': 'Schnellzugriffe',
|
|
355
|
+
'fr-FR': 'Liens rapides', 'es-ES': 'Enlaces rápidos',
|
|
356
|
+
'pt-BR': 'Links rápidos', 'ru-RU': 'Быстрые ссылки',
|
|
357
|
+
}, locale, 'Quick Links'),
|
|
358
|
+
community: resolveLocalized({
|
|
359
|
+
'zh-CN': '社区', 'zh-Hant': '社群', 'en-US': 'Community',
|
|
360
|
+
'ja-JP': 'コミュニティ', 'ko-KR': '커뮤니티', 'de-DE': 'Community',
|
|
361
|
+
'fr-FR': 'Communauté', 'es-ES': 'Comunidad',
|
|
362
|
+
'pt-BR': 'Comunidade', 'ru-RU': 'Сообщество',
|
|
363
|
+
}, locale, 'Community'),
|
|
364
|
+
navigation: {
|
|
365
|
+
relatedSites: resolveLocalized({
|
|
366
|
+
'zh-CN': '生态站点链接', 'zh-Hant': '生態站點連結', 'en-US': 'Ecosystem site links',
|
|
367
|
+
'ja-JP': 'エコシステムサイトへのリンク', 'ko-KR': '에코시스템 사이트 링크',
|
|
368
|
+
'de-DE': 'Links zu Ökosystem-Seiten', 'fr-FR': "Liens vers les sites de l'écosystème",
|
|
369
|
+
'es-ES': 'Enlaces de sitios del ecosistema', 'pt-BR': 'Links dos sites do ecossistema',
|
|
370
|
+
'ru-RU': 'Ссылки на сайты экосистемы',
|
|
371
|
+
}, locale, 'Ecosystem site links'),
|
|
372
|
+
quickLinks: resolveLocalized({
|
|
373
|
+
'zh-CN': '快速链接', 'zh-Hant': '快速連結', 'en-US': 'Quick links',
|
|
374
|
+
'ja-JP': 'クイックリンク', 'ko-KR': '빠른 링크', 'de-DE': 'Schnellzugriffe',
|
|
375
|
+
'fr-FR': 'Liens rapides', 'es-ES': 'Enlaces rápidos',
|
|
376
|
+
'pt-BR': 'Links rápidos', 'ru-RU': 'Быстрые ссылки',
|
|
377
|
+
}, locale, 'Quick links'),
|
|
378
|
+
community: resolveLocalized({
|
|
379
|
+
'zh-CN': '社区链接', 'zh-Hant': '社群連結', 'en-US': 'Community links',
|
|
380
|
+
'ja-JP': 'コミュニティリンク', 'ko-KR': '커뮤니티 링크',
|
|
381
|
+
'de-DE': 'Community-Links', 'fr-FR': 'Liens communautaires',
|
|
382
|
+
'es-ES': 'Enlaces de la comunidad', 'pt-BR': 'Links da comunidade',
|
|
383
|
+
'ru-RU': 'Ссылки сообщества',
|
|
384
|
+
}, locale, 'Community links'),
|
|
385
|
+
filings: resolveLocalized({
|
|
386
|
+
'zh-CN': '查看备案信息', 'zh-Hant': '查看備案資訊',
|
|
387
|
+
'en-US': 'View filing information', 'ja-JP': '登録情報を表示',
|
|
388
|
+
'ko-KR': '등록 정보 보기', 'de-DE': 'Registrierungsinformationen anzeigen',
|
|
389
|
+
'fr-FR': 'Voir les informations de dépôt', 'es-ES': 'Ver información de registro',
|
|
390
|
+
'pt-BR': 'Ver informações de registro', 'ru-RU': 'Показать информацию о регистрации',
|
|
391
|
+
}, locale, 'View filing information'),
|
|
392
|
+
},
|
|
393
|
+
},
|
|
394
|
+
header: resolvedGroups.header,
|
|
395
|
+
quick: resolvedGroups.quick,
|
|
396
|
+
community: resolvedGroups.community,
|
|
397
|
+
filings: resolvedGroups.filings,
|
|
398
|
+
relatedSites,
|
|
399
|
+
};
|
|
400
|
+
}
|