@takuhon/ui 0.2.0 → 0.4.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.js CHANGED
@@ -44,7 +44,10 @@ function CareerTimeline({ careers }) {
44
44
  /* @__PURE__ */ jsxs("p", { className: styles.range, children: [
45
45
  /* @__PURE__ */ jsx("time", { dateTime: career.startDate, children: career.startDate }),
46
46
  " \u2013 ",
47
- isOngoing(career) ? "Present" : /* @__PURE__ */ jsx("time", { dateTime: career.endDate, children: career.endDate })
47
+ isOngoing(career) ? (
48
+ // TODO(i18n-phase-2): Localize the 'Present' label via the locale resolver.
49
+ "Present"
50
+ ) : /* @__PURE__ */ jsx("time", { dateTime: career.endDate, children: career.endDate })
48
51
  ] }),
49
52
  career.location?.display ? /* @__PURE__ */ jsx("p", { className: styles.location, children: career.location.display }) : null,
50
53
  career.description ? /* @__PURE__ */ jsx("p", { className: styles.description, children: career.description }) : null
@@ -83,7 +86,10 @@ function Certifications({ certifications }) {
83
86
  /* @__PURE__ */ jsx2("p", { className: styles2.issuer, children: cert.issuingOrganization }),
84
87
  /* @__PURE__ */ jsxs2("p", { className: styles2.range, children: [
85
88
  /* @__PURE__ */ jsx2("time", { dateTime: cert.issueDate, children: cert.issueDate }),
86
- cert.expirationDate === null ? /* @__PURE__ */ jsx2("span", { className: styles2.tag, children: " \xB7 No expiration" }) : cert.expirationDate !== void 0 ? /* @__PURE__ */ jsxs2(Fragment2, { children: [
89
+ cert.expirationDate === null ? (
90
+ // TODO(i18n-phase-2): Localize the 'No expiration' label via the locale resolver.
91
+ /* @__PURE__ */ jsx2("span", { className: styles2.tag, children: " \xB7 No expiration" })
92
+ ) : cert.expirationDate !== void 0 ? /* @__PURE__ */ jsxs2(Fragment2, { children: [
87
93
  " \u2013 ",
88
94
  /* @__PURE__ */ jsx2("time", { dateTime: cert.expirationDate, children: cert.expirationDate })
89
95
  ] }) : null
@@ -116,9 +122,44 @@ function ContactInfo({ contact }) {
116
122
  ] });
117
123
  }
118
124
 
119
- // src/components/EducationTimeline.tsx
120
- import styles4 from "./EducationTimeline.module-7YQTH6QU.module.css";
125
+ // src/components/Courses.tsx
126
+ import styles4 from "./Courses.module-EVDSFNGW.module.css";
121
127
  import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
128
+ function sortCourses(entries) {
129
+ return [...entries].sort((a, b) => {
130
+ const aOrder = a.order ?? Number.POSITIVE_INFINITY;
131
+ const bOrder = b.order ?? Number.POSITIVE_INFINITY;
132
+ if (aOrder !== bOrder) return aOrder - bOrder;
133
+ return (b.completionDate ?? "").localeCompare(a.completionDate ?? "");
134
+ });
135
+ }
136
+ function Courses({ courses }) {
137
+ if (courses.length === 0) return null;
138
+ const ordered = sortCourses(courses);
139
+ return /* @__PURE__ */ jsxs4("section", { className: styles4.section, "aria-labelledby": "takuhon-courses-heading", children: [
140
+ /* @__PURE__ */ jsx4("h2", { id: "takuhon-courses-heading", className: styles4.heading, children: "Courses" }),
141
+ /* @__PURE__ */ jsx4("ul", { className: styles4.list, children: ordered.map((entry) => /* @__PURE__ */ jsxs4("li", { className: styles4.item, children: [
142
+ /* @__PURE__ */ jsx4("p", { className: styles4.title, children: entry.certificateUrl ? /* @__PURE__ */ jsx4(
143
+ "a",
144
+ {
145
+ className: styles4.link,
146
+ href: entry.certificateUrl,
147
+ target: "_blank",
148
+ rel: "noopener noreferrer",
149
+ children: entry.title
150
+ }
151
+ ) : entry.title }),
152
+ entry.provider ? /* @__PURE__ */ jsx4("p", { className: styles4.provider, children: entry.provider }) : null,
153
+ entry.courseNumber ? /* @__PURE__ */ jsx4("p", { className: styles4.courseNumber, children: entry.courseNumber }) : null,
154
+ entry.completionDate ? /* @__PURE__ */ jsx4("p", { className: styles4.date, children: /* @__PURE__ */ jsx4("time", { dateTime: entry.completionDate, children: entry.completionDate }) }) : null,
155
+ entry.description ? /* @__PURE__ */ jsx4("p", { className: styles4.description, children: entry.description }) : null
156
+ ] }, entry.id)) })
157
+ ] });
158
+ }
159
+
160
+ // src/components/EducationTimeline.tsx
161
+ import styles5 from "./EducationTimeline.module-7YQTH6QU.module.css";
162
+ import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
122
163
  function sortEducation(entries) {
123
164
  return [...entries].sort((a, b) => {
124
165
  const aOrder = a.order ?? Number.POSITIVE_INFINITY;
@@ -139,31 +180,34 @@ function composeStudyLine(entry) {
139
180
  function EducationTimeline({ education }) {
140
181
  if (education.length === 0) return null;
141
182
  const ordered = sortEducation(education);
142
- return /* @__PURE__ */ jsxs4("section", { className: styles4.section, "aria-labelledby": "takuhon-education-heading", children: [
143
- /* @__PURE__ */ jsx4("h2", { id: "takuhon-education-heading", className: styles4.heading, children: "Education" }),
144
- /* @__PURE__ */ jsx4("ol", { className: styles4.list, children: ordered.map((entry) => {
183
+ return /* @__PURE__ */ jsxs5("section", { className: styles5.section, "aria-labelledby": "takuhon-education-heading", children: [
184
+ /* @__PURE__ */ jsx5("h2", { id: "takuhon-education-heading", className: styles5.heading, children: "Education" }),
185
+ /* @__PURE__ */ jsx5("ol", { className: styles5.list, children: ordered.map((entry) => {
145
186
  const study = composeStudyLine(entry);
146
- return /* @__PURE__ */ jsxs4("li", { className: styles4.item, children: [
147
- /* @__PURE__ */ jsx4("div", { className: styles4.timelineMarker, "aria-hidden": "true" }),
148
- /* @__PURE__ */ jsxs4("div", { className: styles4.content, children: [
149
- /* @__PURE__ */ jsx4("p", { className: styles4.institution, children: entry.url ? /* @__PURE__ */ jsx4(
187
+ return /* @__PURE__ */ jsxs5("li", { className: styles5.item, children: [
188
+ /* @__PURE__ */ jsx5("div", { className: styles5.timelineMarker, "aria-hidden": "true" }),
189
+ /* @__PURE__ */ jsxs5("div", { className: styles5.content, children: [
190
+ /* @__PURE__ */ jsx5("p", { className: styles5.institution, children: entry.url ? /* @__PURE__ */ jsx5(
150
191
  "a",
151
192
  {
152
- className: styles4.link,
193
+ className: styles5.link,
153
194
  href: entry.url,
154
195
  target: "_blank",
155
196
  rel: "noopener noreferrer",
156
197
  children: entry.institution
157
198
  }
158
199
  ) : entry.institution }),
159
- study ? /* @__PURE__ */ jsx4("p", { className: styles4.study, children: study }) : null,
160
- /* @__PURE__ */ jsxs4("p", { className: styles4.range, children: [
161
- /* @__PURE__ */ jsx4("time", { dateTime: entry.startDate, children: entry.startDate }),
200
+ study ? /* @__PURE__ */ jsx5("p", { className: styles5.study, children: study }) : null,
201
+ /* @__PURE__ */ jsxs5("p", { className: styles5.range, children: [
202
+ /* @__PURE__ */ jsx5("time", { dateTime: entry.startDate, children: entry.startDate }),
162
203
  " \u2013 ",
163
- isOngoing2(entry) ? "Present" : /* @__PURE__ */ jsx4("time", { dateTime: entry.endDate, children: entry.endDate })
204
+ isOngoing2(entry) ? (
205
+ // TODO(i18n-phase-2): Localize the 'Present' label via the locale resolver.
206
+ "Present"
207
+ ) : /* @__PURE__ */ jsx5("time", { dateTime: entry.endDate, children: entry.endDate })
164
208
  ] }),
165
- entry.grade ? /* @__PURE__ */ jsx4("p", { className: styles4.grade, children: entry.grade }) : null,
166
- entry.description ? /* @__PURE__ */ jsx4("p", { className: styles4.description, children: entry.description }) : null
209
+ entry.grade ? /* @__PURE__ */ jsx5("p", { className: styles5.grade, children: entry.grade }) : null,
210
+ entry.description ? /* @__PURE__ */ jsx5("p", { className: styles5.description, children: entry.description }) : null
167
211
  ] })
168
212
  ] }, entry.id);
169
213
  }) })
@@ -171,16 +215,16 @@ function EducationTimeline({ education }) {
171
215
  }
172
216
 
173
217
  // src/components/Footer.tsx
174
- import styles5 from "./Footer.module-HLC5GXVI.module.css";
175
- import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
218
+ import styles6 from "./Footer.module-HLC5GXVI.module.css";
219
+ import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
176
220
  function Footer() {
177
- return /* @__PURE__ */ jsx5("footer", { className: styles5.footer, children: /* @__PURE__ */ jsxs5("p", { className: styles5.line, children: [
221
+ return /* @__PURE__ */ jsx6("footer", { className: styles6.footer, children: /* @__PURE__ */ jsxs6("p", { className: styles6.line, children: [
178
222
  "Powered by",
179
223
  " ",
180
- /* @__PURE__ */ jsx5(
224
+ /* @__PURE__ */ jsx6(
181
225
  "a",
182
226
  {
183
- className: styles5.link,
227
+ className: styles6.link,
184
228
  href: "https://github.com/takuhon-dev/takuhon",
185
229
  target: "_blank",
186
230
  rel: "noopener noreferrer",
@@ -191,8 +235,8 @@ function Footer() {
191
235
  }
192
236
 
193
237
  // src/components/HonorsList.tsx
194
- import styles6 from "./HonorsList.module-AQN3CT7O.module.css";
195
- import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
238
+ import styles7 from "./HonorsList.module-AQN3CT7O.module.css";
239
+ import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
196
240
  function sortHonors(honors) {
197
241
  return [...honors].sort((a, b) => {
198
242
  const aOrder = a.order ?? Number.POSITIVE_INFINITY;
@@ -204,32 +248,32 @@ function sortHonors(honors) {
204
248
  function HonorsList({ honors }) {
205
249
  if (honors.length === 0) return null;
206
250
  const ordered = sortHonors(honors);
207
- return /* @__PURE__ */ jsxs6("section", { className: styles6.section, "aria-labelledby": "takuhon-honors-heading", children: [
208
- /* @__PURE__ */ jsx6("h2", { id: "takuhon-honors-heading", className: styles6.heading, children: "Honors & Awards" }),
209
- /* @__PURE__ */ jsx6("ul", { className: styles6.list, children: ordered.map((honor) => /* @__PURE__ */ jsxs6("li", { className: styles6.item, children: [
210
- /* @__PURE__ */ jsx6("p", { className: styles6.title, children: honor.url ? /* @__PURE__ */ jsx6(
251
+ return /* @__PURE__ */ jsxs7("section", { className: styles7.section, "aria-labelledby": "takuhon-honors-heading", children: [
252
+ /* @__PURE__ */ jsx7("h2", { id: "takuhon-honors-heading", className: styles7.heading, children: "Honors & Awards" }),
253
+ /* @__PURE__ */ jsx7("ul", { className: styles7.list, children: ordered.map((honor) => /* @__PURE__ */ jsxs7("li", { className: styles7.item, children: [
254
+ /* @__PURE__ */ jsx7("p", { className: styles7.title, children: honor.url ? /* @__PURE__ */ jsx7(
211
255
  "a",
212
256
  {
213
- className: styles6.link,
257
+ className: styles7.link,
214
258
  href: honor.url,
215
259
  target: "_blank",
216
260
  rel: "noopener noreferrer",
217
261
  children: honor.title
218
262
  }
219
263
  ) : honor.title }),
220
- /* @__PURE__ */ jsxs6("p", { className: styles6.meta, children: [
264
+ /* @__PURE__ */ jsxs7("p", { className: styles7.meta, children: [
221
265
  honor.issuer,
222
266
  " \xB7 ",
223
- /* @__PURE__ */ jsx6("time", { dateTime: honor.date, children: honor.date })
267
+ /* @__PURE__ */ jsx7("time", { dateTime: honor.date, children: honor.date })
224
268
  ] }),
225
- honor.description ? /* @__PURE__ */ jsx6("p", { className: styles6.description, children: honor.description }) : null
269
+ honor.description ? /* @__PURE__ */ jsx7("p", { className: styles7.description, children: honor.description }) : null
226
270
  ] }, honor.id)) })
227
271
  ] });
228
272
  }
229
273
 
230
274
  // src/components/Languages.tsx
231
- import styles7 from "./Languages.module-X6RQNFRY.module.css";
232
- import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
275
+ import styles8 from "./Languages.module-X6RQNFRY.module.css";
276
+ import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
233
277
  var PROFICIENCY_LABEL = {
234
278
  native: "Native",
235
279
  fluent: "Fluent",
@@ -247,18 +291,18 @@ function sortLanguages(languages) {
247
291
  function Languages({ languages }) {
248
292
  if (languages.length === 0) return null;
249
293
  const ordered = sortLanguages(languages);
250
- return /* @__PURE__ */ jsxs7("section", { className: styles7.section, "aria-labelledby": "takuhon-languages-heading", children: [
251
- /* @__PURE__ */ jsx7("h2", { id: "takuhon-languages-heading", className: styles7.heading, children: "Languages" }),
252
- /* @__PURE__ */ jsx7("ul", { className: styles7.list, children: ordered.map((entry) => /* @__PURE__ */ jsxs7("li", { className: styles7.item, children: [
253
- /* @__PURE__ */ jsx7("span", { className: styles7.name, lang: entry.language, children: entry.displayName ?? entry.language }),
254
- /* @__PURE__ */ jsx7("span", { className: styles7.proficiency, children: PROFICIENCY_LABEL[entry.proficiency] })
294
+ return /* @__PURE__ */ jsxs8("section", { className: styles8.section, "aria-labelledby": "takuhon-languages-heading", children: [
295
+ /* @__PURE__ */ jsx8("h2", { id: "takuhon-languages-heading", className: styles8.heading, children: "Languages" }),
296
+ /* @__PURE__ */ jsx8("ul", { className: styles8.list, children: ordered.map((entry) => /* @__PURE__ */ jsxs8("li", { className: styles8.item, children: [
297
+ /* @__PURE__ */ jsx8("span", { className: styles8.name, lang: entry.language, children: entry.displayName ?? entry.language }),
298
+ /* @__PURE__ */ jsx8("span", { className: styles8.proficiency, children: PROFICIENCY_LABEL[entry.proficiency] })
255
299
  ] }, entry.id)) })
256
300
  ] });
257
301
  }
258
302
 
259
303
  // src/components/LinksList.tsx
260
- import styles8 from "./LinksList.module-QPSFPOF3.module.css";
261
- import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
304
+ import styles9 from "./LinksList.module-QPSFPOF3.module.css";
305
+ import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
262
306
  function sortLinks(links) {
263
307
  return [...links].sort((a, b) => {
264
308
  const aFeatured = a.featured ? 1 : 0;
@@ -277,32 +321,139 @@ function formatLinkLabel(link) {
277
321
  function LinksList({ links }) {
278
322
  if (links.length === 0) return null;
279
323
  const ordered = sortLinks(links);
280
- return /* @__PURE__ */ jsx8("nav", { "aria-label": "Profile links", className: styles8.nav, children: /* @__PURE__ */ jsx8("ul", { className: styles8.list, children: ordered.map((link) => /* @__PURE__ */ jsx8("li", { className: styles8.item, children: /* @__PURE__ */ jsxs8(
324
+ return /* @__PURE__ */ jsx9("nav", { "aria-label": "Profile links", className: styles9.nav, children: /* @__PURE__ */ jsx9("ul", { className: styles9.list, children: ordered.map((link) => /* @__PURE__ */ jsx9("li", { className: styles9.item, children: /* @__PURE__ */ jsxs9(
281
325
  "a",
282
326
  {
283
- className: styles8.link,
327
+ className: styles9.link,
284
328
  href: link.url,
285
329
  target: "_blank",
286
330
  rel: "noopener noreferrer",
287
331
  "data-featured": link.featured ? "true" : void 0,
288
332
  children: [
289
- link.iconUrl ? /* @__PURE__ */ jsx8("img", { className: styles8.icon, src: link.iconUrl, alt: "" }) : null,
290
- /* @__PURE__ */ jsx8("span", { className: styles8.label, children: formatLinkLabel(link) })
333
+ link.iconUrl ? /* @__PURE__ */ jsx9("img", { className: styles9.icon, src: link.iconUrl, alt: "" }) : null,
334
+ /* @__PURE__ */ jsx9("span", { className: styles9.label, children: formatLinkLabel(link) })
291
335
  ]
292
336
  }
293
337
  ) }, link.id)) }) });
294
338
  }
295
339
 
340
+ // src/components/Memberships.tsx
341
+ import styles10 from "./Memberships.module-SMJBJFA2.module.css";
342
+ import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
343
+ function sortMemberships(entries) {
344
+ return [...entries].sort((a, b) => {
345
+ const aOrder = a.order ?? Number.POSITIVE_INFINITY;
346
+ const bOrder = b.order ?? Number.POSITIVE_INFINITY;
347
+ if (aOrder !== bOrder) return aOrder - bOrder;
348
+ return b.startDate.localeCompare(a.startDate);
349
+ });
350
+ }
351
+ function isOngoing3(entry) {
352
+ return entry.isCurrent === true || entry.endDate === null || entry.endDate === void 0;
353
+ }
354
+ function Memberships({ memberships }) {
355
+ if (memberships.length === 0) return null;
356
+ const ordered = sortMemberships(memberships);
357
+ return /* @__PURE__ */ jsxs10("section", { className: styles10.section, "aria-labelledby": "takuhon-memberships-heading", children: [
358
+ /* @__PURE__ */ jsx10("h2", { id: "takuhon-memberships-heading", className: styles10.heading, children: "Memberships" }),
359
+ /* @__PURE__ */ jsx10("ol", { className: styles10.list, children: ordered.map((entry) => /* @__PURE__ */ jsxs10("li", { className: styles10.item, children: [
360
+ /* @__PURE__ */ jsx10("div", { className: styles10.timelineMarker, "aria-hidden": "true" }),
361
+ /* @__PURE__ */ jsxs10("div", { className: styles10.content, children: [
362
+ /* @__PURE__ */ jsx10("p", { className: styles10.organization, children: entry.url ? /* @__PURE__ */ jsx10(
363
+ "a",
364
+ {
365
+ className: styles10.link,
366
+ href: entry.url,
367
+ target: "_blank",
368
+ rel: "noopener noreferrer",
369
+ children: entry.organization
370
+ }
371
+ ) : entry.organization }),
372
+ entry.role ? /* @__PURE__ */ jsx10("p", { className: styles10.role, children: entry.role }) : null,
373
+ /* @__PURE__ */ jsxs10("p", { className: styles10.range, children: [
374
+ /* @__PURE__ */ jsx10("time", { dateTime: entry.startDate, children: entry.startDate }),
375
+ " \u2013 ",
376
+ isOngoing3(entry) ? (
377
+ // TODO(i18n-phase-2): Localize the 'Present' label via the locale resolver.
378
+ "Present"
379
+ ) : /* @__PURE__ */ jsx10("time", { dateTime: entry.endDate, children: entry.endDate })
380
+ ] }),
381
+ entry.description ? /* @__PURE__ */ jsx10("p", { className: styles10.description, children: entry.description }) : null
382
+ ] })
383
+ ] }, entry.id)) })
384
+ ] });
385
+ }
386
+
387
+ // src/components/Patents.tsx
388
+ import styles11 from "./Patents.module-L3GWPB3V.module.css";
389
+ import { Fragment as Fragment3, jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
390
+ var STATUS_LABEL = {
391
+ pending: "Pending",
392
+ issued: "Issued",
393
+ expired: "Expired",
394
+ abandoned: "Abandoned"
395
+ };
396
+ function sortPatents(entries) {
397
+ return [...entries].sort((a, b) => {
398
+ const aOrder = a.order ?? Number.POSITIVE_INFINITY;
399
+ const bOrder = b.order ?? Number.POSITIVE_INFINITY;
400
+ if (aOrder !== bOrder) return aOrder - bOrder;
401
+ const aDate = a.grantDate ?? a.filingDate ?? "";
402
+ const bDate = b.grantDate ?? b.filingDate ?? "";
403
+ return bDate.localeCompare(aDate);
404
+ });
405
+ }
406
+ function Patents({ patents }) {
407
+ if (patents.length === 0) return null;
408
+ const ordered = sortPatents(patents);
409
+ return /* @__PURE__ */ jsxs11("section", { className: styles11.section, "aria-labelledby": "takuhon-patents-heading", children: [
410
+ /* @__PURE__ */ jsx11("h2", { id: "takuhon-patents-heading", className: styles11.heading, children: "Patents" }),
411
+ /* @__PURE__ */ jsx11("ul", { className: styles11.list, children: ordered.map((entry) => /* @__PURE__ */ jsxs11("li", { className: styles11.item, children: [
412
+ /* @__PURE__ */ jsxs11("p", { className: styles11.title, children: [
413
+ entry.url ? /* @__PURE__ */ jsx11(
414
+ "a",
415
+ {
416
+ className: styles11.link,
417
+ href: entry.url,
418
+ target: "_blank",
419
+ rel: "noopener noreferrer",
420
+ children: entry.title
421
+ }
422
+ ) : entry.title,
423
+ /* @__PURE__ */ jsxs11("span", { className: styles11.statusBadge, "data-status": entry.status, children: [
424
+ /* @__PURE__ */ jsx11("span", { className: styles11.srOnly, children: "Status: " }),
425
+ STATUS_LABEL[entry.status]
426
+ ] })
427
+ ] }),
428
+ /* @__PURE__ */ jsx11("p", { className: styles11.patentNumber, children: entry.patentNumber }),
429
+ entry.office ? /* @__PURE__ */ jsx11("p", { className: styles11.office, children: entry.office }) : null,
430
+ entry.filingDate !== void 0 || entry.grantDate !== void 0 ? /* @__PURE__ */ jsxs11("p", { className: styles11.dates, children: [
431
+ entry.filingDate ? /* @__PURE__ */ jsxs11(Fragment3, { children: [
432
+ "Filed ",
433
+ /* @__PURE__ */ jsx11("time", { dateTime: entry.filingDate, children: entry.filingDate })
434
+ ] }) : null,
435
+ entry.filingDate && entry.grantDate ? " \xB7 " : null,
436
+ entry.grantDate ? /* @__PURE__ */ jsxs11(Fragment3, { children: [
437
+ "Granted ",
438
+ /* @__PURE__ */ jsx11("time", { dateTime: entry.grantDate, children: entry.grantDate })
439
+ ] }) : null
440
+ ] }) : null,
441
+ entry.coInventors && entry.coInventors.length > 0 ? /* @__PURE__ */ jsx11(Fragment3, { children: /* @__PURE__ */ jsx11("p", { className: styles11.coInventors, children: `with ${entry.coInventors.join(", ")}` }) }) : null,
442
+ entry.description ? /* @__PURE__ */ jsx11("p", { className: styles11.description, children: entry.description }) : null
443
+ ] }, entry.id)) })
444
+ ] });
445
+ }
446
+
296
447
  // src/components/ProfileHeader.tsx
297
- import styles9 from "./ProfileHeader.module-EK27UTZL.module.css";
298
- import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
448
+ import styles12 from "./ProfileHeader.module-EK27UTZL.module.css";
449
+ import { jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
299
450
  function ProfileHeader({ profile }) {
300
451
  const locationLabel = profile.location?.display ?? profile.location?.locality;
301
- return /* @__PURE__ */ jsxs9("header", { className: styles9.header, children: [
302
- profile.avatar ? /* @__PURE__ */ jsx9(
452
+ return /* @__PURE__ */ jsxs12("header", { className: styles12.header, children: [
453
+ profile.avatar ? /* @__PURE__ */ jsx12(
303
454
  "img",
304
455
  {
305
- className: styles9.avatar,
456
+ className: styles12.avatar,
306
457
  src: profile.avatar.url,
307
458
  alt: profile.avatar.alt ?? "",
308
459
  width: 128,
@@ -311,16 +462,16 @@ function ProfileHeader({ profile }) {
311
462
  decoding: "async"
312
463
  }
313
464
  ) : null,
314
- /* @__PURE__ */ jsx9("h1", { className: styles9.displayName, children: profile.displayName }),
315
- profile.tagline ? /* @__PURE__ */ jsx9("p", { className: styles9.tagline, children: profile.tagline }) : null,
316
- locationLabel ? /* @__PURE__ */ jsx9("p", { className: styles9.location, children: locationLabel }) : null,
317
- profile.bio ? /* @__PURE__ */ jsx9("p", { className: styles9.bio, children: profile.bio }) : null
465
+ /* @__PURE__ */ jsx12("h1", { className: styles12.displayName, children: profile.displayName }),
466
+ profile.tagline ? /* @__PURE__ */ jsx12("p", { className: styles12.tagline, children: profile.tagline }) : null,
467
+ locationLabel ? /* @__PURE__ */ jsx12("p", { className: styles12.location, children: locationLabel }) : null,
468
+ profile.bio ? /* @__PURE__ */ jsx12("p", { className: styles12.bio, children: profile.bio }) : null
318
469
  ] });
319
470
  }
320
471
 
321
472
  // src/components/ProjectsList.tsx
322
- import styles10 from "./ProjectsList.module-JKGGZRKO.module.css";
323
- import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
473
+ import styles13 from "./ProjectsList.module-JKGGZRKO.module.css";
474
+ import { jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
324
475
  function sortProjects(projects) {
325
476
  return [...projects].sort((a, b) => {
326
477
  const aHighlighted = a.highlighted ? 1 : 0;
@@ -334,31 +485,34 @@ function sortProjects(projects) {
334
485
  function ProjectsList({ projects }) {
335
486
  if (projects.length === 0) return null;
336
487
  const ordered = sortProjects(projects);
337
- return /* @__PURE__ */ jsxs10("section", { className: styles10.section, "aria-labelledby": "takuhon-projects-heading", children: [
338
- /* @__PURE__ */ jsx10("h2", { id: "takuhon-projects-heading", className: styles10.heading, children: "Projects" }),
339
- /* @__PURE__ */ jsx10("ul", { className: styles10.list, children: ordered.map((project) => /* @__PURE__ */ jsxs10(
488
+ return /* @__PURE__ */ jsxs13("section", { className: styles13.section, "aria-labelledby": "takuhon-projects-heading", children: [
489
+ /* @__PURE__ */ jsx13("h2", { id: "takuhon-projects-heading", className: styles13.heading, children: "Projects" }),
490
+ /* @__PURE__ */ jsx13("ul", { className: styles13.list, children: ordered.map((project) => /* @__PURE__ */ jsxs13(
340
491
  "li",
341
492
  {
342
- className: styles10.item,
493
+ className: styles13.item,
343
494
  "data-highlighted": project.highlighted ? "true" : void 0,
344
495
  children: [
345
- /* @__PURE__ */ jsx10("p", { className: styles10.title, children: project.url ? /* @__PURE__ */ jsx10(
496
+ /* @__PURE__ */ jsx13("p", { className: styles13.title, children: project.url ? /* @__PURE__ */ jsx13(
346
497
  "a",
347
498
  {
348
- className: styles10.titleLink,
499
+ className: styles13.titleLink,
349
500
  href: project.url,
350
501
  target: "_blank",
351
502
  rel: "noopener noreferrer",
352
503
  children: project.title
353
504
  }
354
505
  ) : project.title }),
355
- project.startDate !== void 0 ? /* @__PURE__ */ jsxs10("p", { className: styles10.range, children: [
356
- /* @__PURE__ */ jsx10("time", { dateTime: project.startDate, children: project.startDate }),
506
+ project.startDate !== void 0 ? /* @__PURE__ */ jsxs13("p", { className: styles13.range, children: [
507
+ /* @__PURE__ */ jsx13("time", { dateTime: project.startDate, children: project.startDate }),
357
508
  " \u2013 ",
358
- project.endDate ? /* @__PURE__ */ jsx10("time", { dateTime: project.endDate, children: project.endDate }) : "Present"
509
+ project.endDate ? /* @__PURE__ */ jsx13("time", { dateTime: project.endDate, children: project.endDate }) : (
510
+ // TODO(i18n-phase-2): Localize the 'Present' label via the locale resolver.
511
+ "Present"
512
+ )
359
513
  ] }) : null,
360
- project.description ? /* @__PURE__ */ jsx10("p", { className: styles10.description, children: project.description }) : null,
361
- project.tags && project.tags.length > 0 ? /* @__PURE__ */ jsx10("ul", { className: styles10.tags, "aria-label": "Tags", children: project.tags.map((tag) => /* @__PURE__ */ jsx10("li", { className: styles10.tag, children: tag }, tag)) }) : null
514
+ project.description ? /* @__PURE__ */ jsx13("p", { className: styles13.description, children: project.description }) : null,
515
+ project.tags && project.tags.length > 0 ? /* @__PURE__ */ jsx13("ul", { className: styles13.tags, "aria-label": "Tags", children: project.tags.map((tag) => /* @__PURE__ */ jsx13("li", { className: styles13.tag, children: tag }, tag)) }) : null
362
516
  ]
363
517
  },
364
518
  project.id
@@ -366,9 +520,60 @@ function ProjectsList({ projects }) {
366
520
  ] });
367
521
  }
368
522
 
523
+ // src/components/Publications.tsx
524
+ import styles14 from "./Publications.module-INRTHJMO.module.css";
525
+ import { jsx as jsx14, jsxs as jsxs14 } from "react/jsx-runtime";
526
+ function sortPublications(entries) {
527
+ return [...entries].sort((a, b) => {
528
+ const aOrder = a.order ?? Number.POSITIVE_INFINITY;
529
+ const bOrder = b.order ?? Number.POSITIVE_INFINITY;
530
+ if (aOrder !== bOrder) return aOrder - bOrder;
531
+ return b.date.localeCompare(a.date);
532
+ });
533
+ }
534
+ function normalizeDoi(doi) {
535
+ return doi.replace(/^https?:\/\/(?:dx\.)?doi\.org\//i, "");
536
+ }
537
+ function Publications({ publications }) {
538
+ if (publications.length === 0) return null;
539
+ const ordered = sortPublications(publications);
540
+ return /* @__PURE__ */ jsxs14("section", { className: styles14.section, "aria-labelledby": "takuhon-publications-heading", children: [
541
+ /* @__PURE__ */ jsx14("h2", { id: "takuhon-publications-heading", className: styles14.heading, children: "Publications" }),
542
+ /* @__PURE__ */ jsx14("ul", { className: styles14.list, children: ordered.map((entry) => /* @__PURE__ */ jsxs14("li", { className: styles14.item, children: [
543
+ /* @__PURE__ */ jsx14("p", { className: styles14.title, children: entry.url ? /* @__PURE__ */ jsx14(
544
+ "a",
545
+ {
546
+ className: styles14.link,
547
+ href: entry.url,
548
+ target: "_blank",
549
+ rel: "noopener noreferrer",
550
+ children: entry.title
551
+ }
552
+ ) : entry.title }),
553
+ entry.publisher ? /* @__PURE__ */ jsx14("p", { className: styles14.publisher, children: entry.publisher }) : null,
554
+ /* @__PURE__ */ jsx14("p", { className: styles14.date, children: /* @__PURE__ */ jsx14("time", { dateTime: entry.date, children: entry.date }) }),
555
+ entry.coAuthors && entry.coAuthors.length > 0 ? /* @__PURE__ */ jsx14("p", { className: styles14.coAuthors, children: `with ${entry.coAuthors.join(", ")}` }) : null,
556
+ entry.doi ? (() => {
557
+ const bare = normalizeDoi(entry.doi);
558
+ return /* @__PURE__ */ jsx14("p", { className: styles14.doi, children: /* @__PURE__ */ jsx14(
559
+ "a",
560
+ {
561
+ className: styles14.link,
562
+ href: `https://doi.org/${bare}`,
563
+ target: "_blank",
564
+ rel: "noopener noreferrer",
565
+ children: `doi:${bare}`
566
+ }
567
+ ) });
568
+ })() : null,
569
+ entry.description ? /* @__PURE__ */ jsx14("p", { className: styles14.description, children: entry.description }) : null
570
+ ] }, entry.id)) })
571
+ ] });
572
+ }
573
+
369
574
  // src/components/SkillsList.tsx
370
- import styles11 from "./SkillsList.module-XIAWE55H.module.css";
371
- import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
575
+ import styles15 from "./SkillsList.module-XIAWE55H.module.css";
576
+ import { jsx as jsx15, jsxs as jsxs15 } from "react/jsx-runtime";
372
577
  function groupSkills(skills) {
373
578
  const sorted = [...skills].sort((a, b) => {
374
579
  const aOrder = a.order ?? Number.POSITIVE_INFINITY;
@@ -390,38 +595,98 @@ function groupSkills(skills) {
390
595
  function SkillsList({ skills }) {
391
596
  if (skills.length === 0) return null;
392
597
  const groups = groupSkills(skills);
393
- return /* @__PURE__ */ jsxs11("section", { className: styles11.section, "aria-labelledby": "takuhon-skills-heading", children: [
394
- /* @__PURE__ */ jsx11("h2", { id: "takuhon-skills-heading", className: styles11.heading, children: "Skills" }),
395
- /* @__PURE__ */ jsx11("div", { className: styles11.groups, children: groups.map((group) => /* @__PURE__ */ jsxs11("div", { className: styles11.group, children: [
396
- /* @__PURE__ */ jsx11("h3", { className: styles11.category, children: group.category }),
397
- /* @__PURE__ */ jsx11("ul", { className: styles11.list, "aria-label": `${group.category} skills`, children: group.skills.map((skill) => /* @__PURE__ */ jsx11("li", { className: styles11.item, children: skill.label }, skill.id)) })
598
+ return /* @__PURE__ */ jsxs15("section", { className: styles15.section, "aria-labelledby": "takuhon-skills-heading", children: [
599
+ /* @__PURE__ */ jsx15("h2", { id: "takuhon-skills-heading", className: styles15.heading, children: "Skills" }),
600
+ /* @__PURE__ */ jsx15("div", { className: styles15.groups, children: groups.map((group) => /* @__PURE__ */ jsxs15("div", { className: styles15.group, children: [
601
+ /* @__PURE__ */ jsx15("h3", { className: styles15.category, children: group.category }),
602
+ /* @__PURE__ */ jsx15("ul", { className: styles15.list, "aria-label": `${group.category} skills`, children: group.skills.map((skill) => /* @__PURE__ */ jsx15("li", { className: styles15.item, children: skill.label }, skill.id)) })
398
603
  ] }, group.category)) })
399
604
  ] });
400
605
  }
401
606
 
402
607
  // src/components/TakuhonProfile.tsx
403
- import styles12 from "./TakuhonProfile.module-QUEORIHA.module.css";
404
- import { jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
608
+ import styles17 from "./TakuhonProfile.module-QUEORIHA.module.css";
609
+
610
+ // src/components/Volunteering.tsx
611
+ import styles16 from "./Volunteering.module-TDRC6QVK.module.css";
612
+ import { jsx as jsx16, jsxs as jsxs16 } from "react/jsx-runtime";
613
+ function sortVolunteering(entries) {
614
+ return [...entries].sort((a, b) => {
615
+ const aOrder = a.order ?? Number.POSITIVE_INFINITY;
616
+ const bOrder = b.order ?? Number.POSITIVE_INFINITY;
617
+ if (aOrder !== bOrder) return aOrder - bOrder;
618
+ return b.startDate.localeCompare(a.startDate);
619
+ });
620
+ }
621
+ function isOngoing4(entry) {
622
+ return entry.isCurrent === true || entry.endDate === null || entry.endDate === void 0;
623
+ }
624
+ function Volunteering({ volunteering }) {
625
+ if (volunteering.length === 0) return null;
626
+ const ordered = sortVolunteering(volunteering);
627
+ return /* @__PURE__ */ jsxs16("section", { className: styles16.section, "aria-labelledby": "takuhon-volunteering-heading", children: [
628
+ /* @__PURE__ */ jsx16("h2", { id: "takuhon-volunteering-heading", className: styles16.heading, children: "Volunteering" }),
629
+ /* @__PURE__ */ jsx16("ol", { className: styles16.list, children: ordered.map((entry) => /* @__PURE__ */ jsxs16("li", { className: styles16.item, children: [
630
+ /* @__PURE__ */ jsx16("div", { className: styles16.timelineMarker, "aria-hidden": "true" }),
631
+ /* @__PURE__ */ jsxs16("div", { className: styles16.content, children: [
632
+ /* @__PURE__ */ jsx16("p", { className: styles16.organization, children: entry.url ? /* @__PURE__ */ jsx16(
633
+ "a",
634
+ {
635
+ className: styles16.link,
636
+ href: entry.url,
637
+ target: "_blank",
638
+ rel: "noopener noreferrer",
639
+ children: entry.organization
640
+ }
641
+ ) : entry.organization }),
642
+ /* @__PURE__ */ jsxs16("p", { className: styles16.role, children: [
643
+ entry.role,
644
+ entry.cause ? /* @__PURE__ */ jsxs16("span", { className: styles16.cause, children: [
645
+ /* @__PURE__ */ jsx16("span", { className: styles16.srOnly, children: "Cause: " }),
646
+ entry.cause
647
+ ] }) : null
648
+ ] }),
649
+ /* @__PURE__ */ jsxs16("p", { className: styles16.range, children: [
650
+ /* @__PURE__ */ jsx16("time", { dateTime: entry.startDate, children: entry.startDate }),
651
+ " \u2013 ",
652
+ isOngoing4(entry) ? (
653
+ // TODO(i18n-phase-2): Localize the 'Present' label via the locale resolver.
654
+ "Present"
655
+ ) : /* @__PURE__ */ jsx16("time", { dateTime: entry.endDate, children: entry.endDate })
656
+ ] }),
657
+ entry.description ? /* @__PURE__ */ jsx16("p", { className: styles16.description, children: entry.description }) : null
658
+ ] })
659
+ ] }, entry.id)) })
660
+ ] });
661
+ }
662
+
663
+ // src/components/TakuhonProfile.tsx
664
+ import { jsx as jsx17, jsxs as jsxs17 } from "react/jsx-runtime";
405
665
  function TakuhonProfile({ data }) {
406
666
  const showFooter = data.settings.showPoweredBy !== false;
407
- return /* @__PURE__ */ jsxs12("article", { className: styles12.root, children: [
408
- /* @__PURE__ */ jsx12(ProfileHeader, { profile: data.profile }),
409
- /* @__PURE__ */ jsx12(LinksList, { links: data.links }),
410
- /* @__PURE__ */ jsx12(EducationTimeline, { education: data.education }),
411
- /* @__PURE__ */ jsx12(CareerTimeline, { careers: data.careers }),
412
- /* @__PURE__ */ jsx12(Certifications, { certifications: data.certifications }),
413
- /* @__PURE__ */ jsx12(ProjectsList, { projects: data.projects }),
414
- /* @__PURE__ */ jsx12(HonorsList, { honors: data.honors }),
415
- /* @__PURE__ */ jsx12(SkillsList, { skills: data.skills }),
416
- /* @__PURE__ */ jsx12(Languages, { languages: data.languages }),
417
- /* @__PURE__ */ jsx12(ContactInfo, { contact: data.contact }),
418
- showFooter ? /* @__PURE__ */ jsx12(Footer, {}) : null
667
+ return /* @__PURE__ */ jsxs17("article", { className: styles17.root, children: [
668
+ /* @__PURE__ */ jsx17(ProfileHeader, { profile: data.profile }),
669
+ /* @__PURE__ */ jsx17(LinksList, { links: data.links }),
670
+ /* @__PURE__ */ jsx17(EducationTimeline, { education: data.education }),
671
+ /* @__PURE__ */ jsx17(Courses, { courses: data.courses }),
672
+ /* @__PURE__ */ jsx17(CareerTimeline, { careers: data.careers }),
673
+ /* @__PURE__ */ jsx17(Memberships, { memberships: data.memberships }),
674
+ /* @__PURE__ */ jsx17(Certifications, { certifications: data.certifications }),
675
+ /* @__PURE__ */ jsx17(Patents, { patents: data.patents }),
676
+ /* @__PURE__ */ jsx17(ProjectsList, { projects: data.projects }),
677
+ /* @__PURE__ */ jsx17(Publications, { publications: data.publications }),
678
+ /* @__PURE__ */ jsx17(HonorsList, { honors: data.honors }),
679
+ /* @__PURE__ */ jsx17(Volunteering, { volunteering: data.volunteering }),
680
+ /* @__PURE__ */ jsx17(SkillsList, { skills: data.skills }),
681
+ /* @__PURE__ */ jsx17(Languages, { languages: data.languages }),
682
+ /* @__PURE__ */ jsx17(ContactInfo, { contact: data.contact }),
683
+ showFooter ? /* @__PURE__ */ jsx17(Footer, {}) : null
419
684
  ] });
420
685
  }
421
686
 
422
687
  // src/components/LocaleSwitcher.tsx
423
- import styles13 from "./LocaleSwitcher.module-QVLPVGLG.module.css";
424
- import { jsx as jsx13 } from "react/jsx-runtime";
688
+ import styles18 from "./LocaleSwitcher.module-QVLPVGLG.module.css";
689
+ import { jsx as jsx18 } from "react/jsx-runtime";
425
690
  var DEFAULT_ARIA_LABEL = "Select language";
426
691
  function LocaleSwitcher({
427
692
  availableLocales,
@@ -432,16 +697,16 @@ function LocaleSwitcher({
432
697
  }) {
433
698
  const label = ariaLabel ?? DEFAULT_ARIA_LABEL;
434
699
  const format = formatLocale ?? ((locale) => locale);
435
- return /* @__PURE__ */ jsx13("div", { className: styles13.wrapper, children: /* @__PURE__ */ jsx13(
700
+ return /* @__PURE__ */ jsx18("div", { className: styles18.wrapper, children: /* @__PURE__ */ jsx18(
436
701
  "select",
437
702
  {
438
- className: styles13.select,
703
+ className: styles18.select,
439
704
  "aria-label": label,
440
705
  value: currentLocale,
441
706
  onChange: (event) => {
442
707
  onSelect(event.target.value);
443
708
  },
444
- children: availableLocales.map((locale) => /* @__PURE__ */ jsx13("option", { value: locale, children: format(locale) }, locale))
709
+ children: availableLocales.map((locale) => /* @__PURE__ */ jsx18("option", { value: locale, children: format(locale) }, locale))
445
710
  }
446
711
  ) });
447
712
  }
@@ -449,23 +714,40 @@ function LocaleSwitcher({
449
714
  // src/components/TakuhonHead.tsx
450
715
  import { generateJsonLd } from "@takuhon/core";
451
716
  import { useEffect } from "react";
452
- import { Fragment as Fragment3, jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
453
- function buildLocaleUrl(pageUrl, locale) {
717
+ import { Fragment as Fragment4, jsx as jsx19, jsxs as jsxs18 } from "react/jsx-runtime";
718
+ function primarySubtag(tag) {
719
+ const dash = tag.indexOf("-");
720
+ return (dash === -1 ? tag : tag.slice(0, dash)).toLowerCase();
721
+ }
722
+ function isLocaleSegment(segment, availableLocales) {
723
+ const lower = segment.toLowerCase();
724
+ const primary = primarySubtag(segment);
725
+ return availableLocales.some(
726
+ (loc) => loc.toLowerCase() === lower || primarySubtag(loc) === primary
727
+ );
728
+ }
729
+ function localeNeutralUrl(pageUrl, availableLocales) {
454
730
  try {
455
731
  const url = new URL(pageUrl);
456
- url.searchParams.set("lang", locale);
732
+ url.searchParams.delete("lang");
733
+ const segments = url.pathname.split("/");
734
+ const first = segments[1];
735
+ if (first !== void 0 && first !== "" && isLocaleSegment(first, availableLocales)) {
736
+ segments.splice(1, 1);
737
+ url.pathname = segments.join("/") || "/";
738
+ }
457
739
  return url.toString();
458
740
  } catch {
459
741
  return pageUrl;
460
742
  }
461
743
  }
462
- function stripLangParam(pageUrl) {
744
+ function withLocalePrefix(neutralUrl, locale) {
463
745
  try {
464
- const url = new URL(pageUrl);
465
- url.searchParams.delete("lang");
746
+ const url = new URL(neutralUrl);
747
+ url.pathname = url.pathname === "/" ? `/${locale}/` : `/${locale}${url.pathname}`;
466
748
  return url.toString();
467
749
  } catch {
468
- return pageUrl;
750
+ return neutralUrl;
469
751
  }
470
752
  }
471
753
  function absolutizeUrl(url, base) {
@@ -483,7 +765,7 @@ function detectSiteUrl(explicit) {
483
765
  return void 0;
484
766
  }
485
767
  function detectPageUrl(explicit, siteUrl) {
486
- if (explicit) return stripLangParam(explicit);
768
+ if (explicit) return explicit;
487
769
  if (typeof window !== "undefined") {
488
770
  return window.location.origin + window.location.pathname;
489
771
  }
@@ -497,12 +779,13 @@ function TakuhonHead({ data, siteUrl, pageUrl }) {
497
779
  const ogDescription = profile.tagline ?? profile.bio;
498
780
  const ogImage = absolutizeUrl(profile.avatar?.url, resolvedSiteUrl);
499
781
  const twitterCard = profile.avatar ? "summary_large_image" : "summary";
500
- const canonical = resolvedPageUrl ? buildLocaleUrl(resolvedPageUrl, resolvedLocale) : void 0;
501
- const alternates = resolvedPageUrl ? settings.availableLocales.map((loc) => ({
782
+ const neutralPageUrl = resolvedPageUrl ? localeNeutralUrl(resolvedPageUrl, settings.availableLocales) : void 0;
783
+ const canonical = neutralPageUrl ? withLocalePrefix(neutralPageUrl, resolvedLocale) : void 0;
784
+ const alternates = neutralPageUrl ? settings.availableLocales.map((loc) => ({
502
785
  locale: loc,
503
- href: buildLocaleUrl(resolvedPageUrl, loc)
786
+ href: withLocalePrefix(neutralPageUrl, loc)
504
787
  })) : [];
505
- const xDefaultHref = resolvedPageUrl ? buildLocaleUrl(resolvedPageUrl, settings.defaultLocale) : void 0;
788
+ const xDefaultHref = neutralPageUrl ? withLocalePrefix(neutralPageUrl, settings.defaultLocale) : void 0;
506
789
  const ogAlternates = settings.availableLocales.filter((loc) => loc !== resolvedLocale);
507
790
  const emitJsonLd = settings.enableJsonLd !== false;
508
791
  const jsonLdPayload = emitJsonLd ? JSON.stringify(generateJsonLd(data)) : null;
@@ -516,36 +799,41 @@ function TakuhonHead({ data, siteUrl, pageUrl }) {
516
799
  script.remove();
517
800
  };
518
801
  }, [jsonLdPayload]);
519
- return /* @__PURE__ */ jsxs13(Fragment3, { children: [
520
- /* @__PURE__ */ jsx14("title", { children: profile.displayName }),
521
- description ? /* @__PURE__ */ jsx14("meta", { name: "description", content: description }) : null,
522
- canonical ? /* @__PURE__ */ jsx14("link", { rel: "canonical", href: canonical }) : null,
523
- /* @__PURE__ */ jsx14("meta", { property: "og:title", content: profile.displayName }),
524
- ogDescription ? /* @__PURE__ */ jsx14("meta", { property: "og:description", content: ogDescription }) : null,
525
- canonical ? /* @__PURE__ */ jsx14("meta", { property: "og:url", content: canonical }) : null,
526
- ogImage ? /* @__PURE__ */ jsx14("meta", { property: "og:image", content: ogImage }) : null,
527
- /* @__PURE__ */ jsx14("meta", { property: "og:type", content: "profile" }),
528
- /* @__PURE__ */ jsx14("meta", { property: "og:locale", content: resolvedLocale }),
529
- ogAlternates.map((loc) => /* @__PURE__ */ jsx14("meta", { property: "og:locale:alternate", content: loc }, loc)),
530
- /* @__PURE__ */ jsx14("meta", { name: "twitter:card", content: twitterCard }),
531
- alternates.map(({ locale, href }) => /* @__PURE__ */ jsx14("link", { rel: "alternate", hrefLang: locale, href }, locale)),
532
- xDefaultHref ? /* @__PURE__ */ jsx14("link", { rel: "alternate", hrefLang: "x-default", href: xDefaultHref }) : null
802
+ return /* @__PURE__ */ jsxs18(Fragment4, { children: [
803
+ /* @__PURE__ */ jsx19("title", { children: profile.displayName }),
804
+ description ? /* @__PURE__ */ jsx19("meta", { name: "description", content: description }) : null,
805
+ canonical ? /* @__PURE__ */ jsx19("link", { rel: "canonical", href: canonical }) : null,
806
+ /* @__PURE__ */ jsx19("meta", { property: "og:title", content: profile.displayName }),
807
+ ogDescription ? /* @__PURE__ */ jsx19("meta", { property: "og:description", content: ogDescription }) : null,
808
+ canonical ? /* @__PURE__ */ jsx19("meta", { property: "og:url", content: canonical }) : null,
809
+ ogImage ? /* @__PURE__ */ jsx19("meta", { property: "og:image", content: ogImage }) : null,
810
+ /* @__PURE__ */ jsx19("meta", { property: "og:type", content: "profile" }),
811
+ /* @__PURE__ */ jsx19("meta", { property: "og:locale", content: resolvedLocale }),
812
+ ogAlternates.map((loc) => /* @__PURE__ */ jsx19("meta", { property: "og:locale:alternate", content: loc }, loc)),
813
+ /* @__PURE__ */ jsx19("meta", { name: "twitter:card", content: twitterCard }),
814
+ alternates.map(({ locale, href }) => /* @__PURE__ */ jsx19("link", { rel: "alternate", hrefLang: locale, href }, locale)),
815
+ xDefaultHref ? /* @__PURE__ */ jsx19("link", { rel: "alternate", hrefLang: "x-default", href: xDefaultHref }) : null
533
816
  ] });
534
817
  }
535
818
  export {
536
819
  CareerTimeline,
537
820
  Certifications,
538
821
  ContactInfo,
822
+ Courses,
539
823
  EducationTimeline,
540
824
  Footer,
541
825
  HonorsList,
542
826
  Languages,
543
827
  LinksList,
544
828
  LocaleSwitcher,
829
+ Memberships,
830
+ Patents,
545
831
  ProfileHeader,
546
832
  ProjectsList,
833
+ Publications,
547
834
  SkillsList,
548
835
  TakuhonHead,
549
- TakuhonProfile
836
+ TakuhonProfile,
837
+ Volunteering
550
838
  };
551
839
  //# sourceMappingURL=index.js.map