@takuhon/ui 0.15.1 → 0.16.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.
@@ -220,6 +220,8 @@ var EN = {
220
220
  "field.avatarUrl": "Avatar URL",
221
221
  "field.avatarUpload": "Upload image",
222
222
  "field.avatarAlt": "Avatar alternative text",
223
+ "field.gravatarEmail": "Gravatar email",
224
+ "field.gravatarApply": "Use Gravatar",
223
225
  "field.location.country": "Country",
224
226
  "field.location.region": "Region",
225
227
  "field.location.locality": "Locality",
@@ -263,6 +265,7 @@ var EN = {
263
265
  "empty.skills": "No skills yet.",
264
266
  "hint.avatarNoUpload": "Paste an image URL. Uploading image files is not available yet.",
265
267
  "hint.avatarUpload": "Paste an image URL, or upload a JPEG, PNG, WebP, or GIF.",
268
+ "hint.gravatar": "Enter an email to generate a Gravatar avatar URL. The email is not saved \u2014 only the resulting URL is stored.",
266
269
  "hint.month": "Format: YYYY-MM (e.g. 2024-03).",
267
270
  "hint.country": "ISO 3166-1 alpha-2 code, e.g. US.",
268
271
  "hint.tags": "Comma-separated.",
@@ -353,10 +356,58 @@ function ImageField({
353
356
  ] }) });
354
357
  }
355
358
 
356
- // src/admin/primitives/LocaleTabs.tsx
357
- import { useId as useId4, useRef as useRef2, useState as useState2 } from "react";
358
- import styles7 from "../LocaleTabs.module-IEEC6Q27.module.css";
359
+ // src/admin/primitives/GravatarField.tsx
360
+ import { gravatarUrl } from "@takuhon/core";
361
+ import { useState as useState2 } from "react";
362
+ import styles7 from "../GravatarField.module-2DD457OD.module.css";
363
+ import controls2 from "../controls.module-CMB7V22N.module.css";
359
364
  import { Fragment as Fragment2, jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
365
+ function GravatarField({ onApply }) {
366
+ const [email, setEmail] = useState2("");
367
+ const trimmed = email.trim();
368
+ const apply = () => {
369
+ if (trimmed === "") return;
370
+ onApply(gravatarUrl(trimmed));
371
+ setEmail("");
372
+ };
373
+ return /* @__PURE__ */ jsx7(Field, { label: getAdminLabel("field.gravatarEmail"), hint: getAdminLabel("hint.gravatar"), children: ({ controlId, describedBy }) => /* @__PURE__ */ jsxs4(Fragment2, { children: [
374
+ /* @__PURE__ */ jsx7(
375
+ "input",
376
+ {
377
+ id: controlId,
378
+ className: controls2.control,
379
+ type: "email",
380
+ value: email,
381
+ autoComplete: "off",
382
+ "aria-describedby": describedBy,
383
+ onChange: (event) => {
384
+ setEmail(event.target.value);
385
+ },
386
+ onKeyDown: (event) => {
387
+ if (event.key === "Enter") {
388
+ event.preventDefault();
389
+ apply();
390
+ }
391
+ }
392
+ }
393
+ ),
394
+ /* @__PURE__ */ jsx7("div", { className: styles7.actionRow, children: /* @__PURE__ */ jsx7(
395
+ "button",
396
+ {
397
+ type: "button",
398
+ className: styles7.applyButton,
399
+ disabled: trimmed === "",
400
+ onClick: apply,
401
+ children: getAdminLabel("field.gravatarApply")
402
+ }
403
+ ) })
404
+ ] }) });
405
+ }
406
+
407
+ // src/admin/primitives/LocaleTabs.tsx
408
+ import { useId as useId4, useRef as useRef2, useState as useState3 } from "react";
409
+ import styles8 from "../LocaleTabs.module-IEEC6Q27.module.css";
410
+ import { Fragment as Fragment3, jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
360
411
  function LocaleTabs({
361
412
  label,
362
413
  value,
@@ -372,14 +423,14 @@ function LocaleTabs({
372
423
  const baseId = useId4();
373
424
  const hintId = useId4();
374
425
  const errorId = useId4();
375
- const [active, setActive] = useState2(() => locales[0] ?? "");
426
+ const [active, setActive] = useState3(() => locales[0] ?? "");
376
427
  const tabRefs = useRef2({});
377
428
  const format = formatLocale ?? ((locale) => locale);
378
429
  const labelId = `${baseId}-label`;
379
430
  if (locales.length === 0) {
380
- return /* @__PURE__ */ jsxs4("div", { className: styles7.group, role: "group", "aria-labelledby": labelId, children: [
381
- /* @__PURE__ */ jsx7("span", { className: styles7.groupLabel, id: labelId, children: label }),
382
- /* @__PURE__ */ jsx7("p", { className: styles7.hint, children: "No locales are configured yet; add one under Settings." })
431
+ return /* @__PURE__ */ jsxs5("div", { className: styles8.group, role: "group", "aria-labelledby": labelId, children: [
432
+ /* @__PURE__ */ jsx8("span", { className: styles8.groupLabel, id: labelId, children: label }),
433
+ /* @__PURE__ */ jsx8("p", { className: styles8.hint, children: "No locales are configured yet; add one under Settings." })
383
434
  ] });
384
435
  }
385
436
  const activeLocale = locales.includes(active) ? active : locales[0];
@@ -424,16 +475,16 @@ function LocaleTabs({
424
475
  }
425
476
  };
426
477
  const controlName = `${label} (${format(activeLocale)})`;
427
- return /* @__PURE__ */ jsxs4("div", { className: styles7.group, role: "group", "aria-labelledby": labelId, children: [
428
- /* @__PURE__ */ jsxs4("span", { className: styles7.groupLabel, id: labelId, children: [
478
+ return /* @__PURE__ */ jsxs5("div", { className: styles8.group, role: "group", "aria-labelledby": labelId, children: [
479
+ /* @__PURE__ */ jsxs5("span", { className: styles8.groupLabel, id: labelId, children: [
429
480
  label,
430
- required ? /* @__PURE__ */ jsx7("span", { "aria-hidden": "true", children: " *" }) : null
481
+ required ? /* @__PURE__ */ jsx8("span", { "aria-hidden": "true", children: " *" }) : null
431
482
  ] }),
432
- hint ? /* @__PURE__ */ jsx7("p", { className: styles7.hint, id: hintId, children: hint }) : null,
433
- /* @__PURE__ */ jsx7("div", { className: styles7.tablist, role: "tablist", "aria-label": label, children: locales.map((locale) => {
483
+ hint ? /* @__PURE__ */ jsx8("p", { className: styles8.hint, id: hintId, children: hint }) : null,
484
+ /* @__PURE__ */ jsx8("div", { className: styles8.tablist, role: "tablist", "aria-label": label, children: locales.map((locale) => {
434
485
  const selected = locale === activeLocale;
435
486
  const tabHasErrors = pointer ? hasErrorsUnder(errors, `${pointer}/${locale}`) : false;
436
- return /* @__PURE__ */ jsxs4(
487
+ return /* @__PURE__ */ jsxs5(
437
488
  "button",
438
489
  {
439
490
  ref: (element) => {
@@ -445,37 +496,37 @@ function LocaleTabs({
445
496
  "aria-selected": selected,
446
497
  "aria-controls": `${baseId}-panel`,
447
498
  tabIndex: selected ? 0 : -1,
448
- className: `${styles7.tab} ${selected ? styles7.tabActive : ""}`,
499
+ className: `${styles8.tab} ${selected ? styles8.tabActive : ""}`,
449
500
  onClick: () => {
450
501
  setActive(locale);
451
502
  },
452
503
  onKeyDown: onTabKeyDown,
453
504
  children: [
454
505
  format(locale),
455
- tabHasErrors ? /* @__PURE__ */ jsxs4(Fragment2, { children: [
456
- /* @__PURE__ */ jsxs4("span", { className: styles7.tabError, "aria-hidden": "true", children: [
506
+ tabHasErrors ? /* @__PURE__ */ jsxs5(Fragment3, { children: [
507
+ /* @__PURE__ */ jsxs5("span", { className: styles8.tabError, "aria-hidden": "true", children: [
457
508
  " ",
458
509
  "\u25CF"
459
510
  ] }),
460
- /* @__PURE__ */ jsx7("span", { className: styles7.srOnly, children: " (has errors)" })
511
+ /* @__PURE__ */ jsx8("span", { className: styles8.srOnly, children: " (has errors)" })
461
512
  ] }) : null
462
513
  ]
463
514
  },
464
515
  locale
465
516
  );
466
517
  }) }),
467
- /* @__PURE__ */ jsxs4(
518
+ /* @__PURE__ */ jsxs5(
468
519
  "div",
469
520
  {
470
521
  role: "tabpanel",
471
522
  id: `${baseId}-panel`,
472
523
  "aria-labelledby": `${baseId}-tab-${activeLocale}`,
473
- className: styles7.panel,
524
+ className: styles8.panel,
474
525
  children: [
475
- multiline ? /* @__PURE__ */ jsx7(
526
+ multiline ? /* @__PURE__ */ jsx8(
476
527
  "textarea",
477
528
  {
478
- className: `${styles7.control} ${styles7.textarea}`,
529
+ className: `${styles8.control} ${styles8.textarea}`,
479
530
  value: text,
480
531
  rows: 4,
481
532
  "aria-label": controlName,
@@ -486,10 +537,10 @@ function LocaleTabs({
486
537
  setText(event.target.value);
487
538
  }
488
539
  }
489
- ) : /* @__PURE__ */ jsx7(
540
+ ) : /* @__PURE__ */ jsx8(
490
541
  "input",
491
542
  {
492
- className: styles7.control,
543
+ className: styles8.control,
493
544
  type: "text",
494
545
  value: text,
495
546
  "aria-label": controlName,
@@ -501,7 +552,7 @@ function LocaleTabs({
501
552
  }
502
553
  }
503
554
  ),
504
- hasErrors ? /* @__PURE__ */ jsx7("ul", { className: styles7.errors, id: errorId, children: shownErrors.map((message, i) => /* @__PURE__ */ jsx7("li", { children: message }, i)) }) : null
555
+ hasErrors ? /* @__PURE__ */ jsx8("ul", { className: styles8.errors, id: errorId, children: shownErrors.map((message, i) => /* @__PURE__ */ jsx8("li", { children: message }, i)) }) : null
505
556
  ]
506
557
  }
507
558
  )
@@ -509,8 +560,8 @@ function LocaleTabs({
509
560
  }
510
561
 
511
562
  // src/admin/primitives/Repeater.tsx
512
- import styles8 from "../Repeater.module-MWSEKS4G.module.css";
513
- import { jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
563
+ import styles9 from "../Repeater.module-MWSEKS4G.module.css";
564
+ import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
514
565
  function Repeater({
515
566
  legend,
516
567
  items,
@@ -542,20 +593,20 @@ function Repeater({
542
593
  copy.splice(to, 0, moved);
543
594
  onChange(copy);
544
595
  };
545
- return /* @__PURE__ */ jsxs5("fieldset", { className: styles8.fieldset, children: [
546
- /* @__PURE__ */ jsx8("legend", { className: styles8.legend, children: legend }),
547
- items.length === 0 && emptyHint ? /* @__PURE__ */ jsx8("p", { className: styles8.empty, children: emptyHint }) : null,
548
- /* @__PURE__ */ jsx8("ol", { className: styles8.list, children: items.map((item, index) => {
596
+ return /* @__PURE__ */ jsxs6("fieldset", { className: styles9.fieldset, children: [
597
+ /* @__PURE__ */ jsx9("legend", { className: styles9.legend, children: legend }),
598
+ items.length === 0 && emptyHint ? /* @__PURE__ */ jsx9("p", { className: styles9.empty, children: emptyHint }) : null,
599
+ /* @__PURE__ */ jsx9("ol", { className: styles9.list, children: items.map((item, index) => {
549
600
  const caption = itemLabel(item, index);
550
- return /* @__PURE__ */ jsx8("li", { className: styles8.item, children: /* @__PURE__ */ jsxs5("div", { role: "group", "aria-label": caption, children: [
551
- /* @__PURE__ */ jsxs5("div", { className: styles8.itemHeader, children: [
552
- /* @__PURE__ */ jsx8("span", { className: styles8.itemCaption, children: caption }),
553
- /* @__PURE__ */ jsxs5("div", { className: styles8.itemActions, children: [
554
- /* @__PURE__ */ jsx8(
601
+ return /* @__PURE__ */ jsx9("li", { className: styles9.item, children: /* @__PURE__ */ jsxs6("div", { role: "group", "aria-label": caption, children: [
602
+ /* @__PURE__ */ jsxs6("div", { className: styles9.itemHeader, children: [
603
+ /* @__PURE__ */ jsx9("span", { className: styles9.itemCaption, children: caption }),
604
+ /* @__PURE__ */ jsxs6("div", { className: styles9.itemActions, children: [
605
+ /* @__PURE__ */ jsx9(
555
606
  "button",
556
607
  {
557
608
  type: "button",
558
- className: styles8.iconButton,
609
+ className: styles9.iconButton,
559
610
  "aria-label": `${moveUpLabel}: ${caption}`,
560
611
  disabled: index === 0,
561
612
  onClick: () => {
@@ -564,11 +615,11 @@ function Repeater({
564
615
  children: "\u2191"
565
616
  }
566
617
  ),
567
- /* @__PURE__ */ jsx8(
618
+ /* @__PURE__ */ jsx9(
568
619
  "button",
569
620
  {
570
621
  type: "button",
571
- className: styles8.iconButton,
622
+ className: styles9.iconButton,
572
623
  "aria-label": `${moveDownLabel}: ${caption}`,
573
624
  disabled: index === items.length - 1,
574
625
  onClick: () => {
@@ -577,11 +628,11 @@ function Repeater({
577
628
  children: "\u2193"
578
629
  }
579
630
  ),
580
- /* @__PURE__ */ jsx8(
631
+ /* @__PURE__ */ jsx9(
581
632
  "button",
582
633
  {
583
634
  type: "button",
584
- className: styles8.removeButton,
635
+ className: styles9.removeButton,
585
636
  "aria-label": `${removeLabel}: ${caption}`,
586
637
  onClick: () => {
587
638
  remove(index);
@@ -591,7 +642,7 @@ function Repeater({
591
642
  )
592
643
  ] })
593
644
  ] }),
594
- /* @__PURE__ */ jsx8("div", { className: styles8.itemBody, children: renderItem(
645
+ /* @__PURE__ */ jsx9("div", { className: styles9.itemBody, children: renderItem(
595
646
  item,
596
647
  (next) => {
597
648
  update(index, next);
@@ -600,11 +651,11 @@ function Repeater({
600
651
  ) })
601
652
  ] }) }, key(item, index));
602
653
  }) }),
603
- /* @__PURE__ */ jsx8(
654
+ /* @__PURE__ */ jsx9(
604
655
  "button",
605
656
  {
606
657
  type: "button",
607
- className: styles8.addButton,
658
+ className: styles9.addButton,
608
659
  onClick: () => {
609
660
  onChange([...items, createItem()]);
610
661
  },
@@ -615,8 +666,8 @@ function Repeater({
615
666
  }
616
667
 
617
668
  // src/admin/sections/ProfileForm.tsx
618
- import styles9 from "../sections.module-ZVBKZHDE.module.css";
619
- import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
669
+ import styles10 from "../sections.module-ZVBKZHDE.module.css";
670
+ import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
620
671
  var POINTER = "/profile";
621
672
  function isEmptyRecord(record) {
622
673
  return !record || Object.keys(record).length === 0;
@@ -640,9 +691,9 @@ function ProfileForm({
640
691
  onChange({ ...value, location: empty ? void 0 : merged });
641
692
  };
642
693
  const headingId = "admin-section-profile";
643
- return /* @__PURE__ */ jsxs6("section", { className: styles9.section, "aria-labelledby": headingId, children: [
644
- /* @__PURE__ */ jsx9("h2", { className: styles9.heading, id: headingId, children: getAdminLabel("section.profile") }),
645
- /* @__PURE__ */ jsx9(
694
+ return /* @__PURE__ */ jsxs7("section", { className: styles10.section, "aria-labelledby": headingId, children: [
695
+ /* @__PURE__ */ jsx10("h2", { className: styles10.heading, id: headingId, children: getAdminLabel("section.profile") }),
696
+ /* @__PURE__ */ jsx10(
646
697
  LocaleTabs,
647
698
  {
648
699
  label: getAdminLabel("field.displayName"),
@@ -657,7 +708,7 @@ function ProfileForm({
657
708
  formatLocale
658
709
  }
659
710
  ),
660
- /* @__PURE__ */ jsx9(
711
+ /* @__PURE__ */ jsx10(
661
712
  LocaleTabs,
662
713
  {
663
714
  label: getAdminLabel("field.tagline"),
@@ -671,8 +722,8 @@ function ProfileForm({
671
722
  formatLocale
672
723
  }
673
724
  ),
674
- /* @__PURE__ */ jsx9("h3", { className: styles9.subheading, children: getAdminLabel("section.about") }),
675
- /* @__PURE__ */ jsx9(
725
+ /* @__PURE__ */ jsx10("h3", { className: styles10.subheading, children: getAdminLabel("section.about") }),
726
+ /* @__PURE__ */ jsx10(
676
727
  LocaleTabs,
677
728
  {
678
729
  label: getAdminLabel("field.bio"),
@@ -687,7 +738,7 @@ function ProfileForm({
687
738
  formatLocale
688
739
  }
689
740
  ),
690
- /* @__PURE__ */ jsx9(
741
+ /* @__PURE__ */ jsx10(
691
742
  ImageField,
692
743
  {
693
744
  label: getAdminLabel("field.avatarUrl"),
@@ -700,7 +751,15 @@ function ProfileForm({
700
751
  uploadAsset
701
752
  }
702
753
  ),
703
- /* @__PURE__ */ jsx9(
754
+ /* @__PURE__ */ jsx10(
755
+ GravatarField,
756
+ {
757
+ onApply: (url) => {
758
+ updateAvatar({ url });
759
+ }
760
+ }
761
+ ),
762
+ /* @__PURE__ */ jsx10(
704
763
  LocaleTabs,
705
764
  {
706
765
  label: getAdminLabel("field.avatarAlt"),
@@ -714,7 +773,7 @@ function ProfileForm({
714
773
  formatLocale
715
774
  }
716
775
  ),
717
- /* @__PURE__ */ jsx9(
776
+ /* @__PURE__ */ jsx10(
718
777
  TextField,
719
778
  {
720
779
  label: getAdminLabel("field.location.country"),
@@ -726,7 +785,7 @@ function ProfileForm({
726
785
  errors: errorsAt(errors, `${POINTER}/location/country`)
727
786
  }
728
787
  ),
729
- /* @__PURE__ */ jsx9(
788
+ /* @__PURE__ */ jsx10(
730
789
  TextField,
731
790
  {
732
791
  label: getAdminLabel("field.location.region"),
@@ -737,7 +796,7 @@ function ProfileForm({
737
796
  errors: errorsAt(errors, `${POINTER}/location/region`)
738
797
  }
739
798
  ),
740
- /* @__PURE__ */ jsx9(
799
+ /* @__PURE__ */ jsx10(
741
800
  LocaleTabs,
742
801
  {
743
802
  label: getAdminLabel("field.location.locality"),
@@ -764,7 +823,7 @@ function makeId(prefix, taken) {
764
823
  }
765
824
 
766
825
  // src/admin/sections/LinksForm.tsx
767
- import { Fragment as Fragment3, jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
826
+ import { Fragment as Fragment4, jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
768
827
  var LINK_TYPES = [
769
828
  "website",
770
829
  "blog",
@@ -816,7 +875,7 @@ function LinksForm({
816
875
  errors = NO_FIELD_ERRORS,
817
876
  formatLocale
818
877
  }) {
819
- return /* @__PURE__ */ jsx10(
878
+ return /* @__PURE__ */ jsx11(
820
879
  Repeater,
821
880
  {
822
881
  legend: getAdminLabel("section.links"),
@@ -839,8 +898,8 @@ function LinksForm({
839
898
  emptyHint: getAdminLabel("empty.links"),
840
899
  renderItem: (link, update, index) => {
841
900
  const at = `/links/${String(index)}`;
842
- return /* @__PURE__ */ jsxs7(Fragment3, { children: [
843
- /* @__PURE__ */ jsx10(
901
+ return /* @__PURE__ */ jsxs8(Fragment4, { children: [
902
+ /* @__PURE__ */ jsx11(
844
903
  SelectField,
845
904
  {
846
905
  label: getAdminLabel("field.link.type"),
@@ -852,7 +911,7 @@ function LinksForm({
852
911
  errors: errorsAt(errors, `${at}/type`)
853
912
  }
854
913
  ),
855
- /* @__PURE__ */ jsx10(
914
+ /* @__PURE__ */ jsx11(
856
915
  TextField,
857
916
  {
858
917
  label: getAdminLabel("field.link.url"),
@@ -865,7 +924,7 @@ function LinksForm({
865
924
  errors: errorsAt(errors, `${at}/url`)
866
925
  }
867
926
  ),
868
- /* @__PURE__ */ jsx10(
927
+ /* @__PURE__ */ jsx11(
869
928
  LocaleTabs,
870
929
  {
871
930
  label: getAdminLabel("field.link.label"),
@@ -879,7 +938,7 @@ function LinksForm({
879
938
  formatLocale
880
939
  }
881
940
  ),
882
- /* @__PURE__ */ jsx10(
941
+ /* @__PURE__ */ jsx11(
883
942
  TextField,
884
943
  {
885
944
  label: getAdminLabel("field.link.iconUrl"),
@@ -892,7 +951,7 @@ function LinksForm({
892
951
  errors: errorsAt(errors, `${at}/iconUrl`)
893
952
  }
894
953
  ),
895
- /* @__PURE__ */ jsx10(
954
+ /* @__PURE__ */ jsx11(
896
955
  CheckboxField,
897
956
  {
898
957
  label: getAdminLabel("field.link.featured"),
@@ -919,7 +978,7 @@ function firstLocalized(record, locales) {
919
978
  }
920
979
 
921
980
  // src/admin/sections/CareersForm.tsx
922
- import { Fragment as Fragment4, jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
981
+ import { Fragment as Fragment5, jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
923
982
  function CareersForm({
924
983
  value,
925
984
  onChange,
@@ -927,7 +986,7 @@ function CareersForm({
927
986
  errors = NO_FIELD_ERRORS,
928
987
  formatLocale
929
988
  }) {
930
- return /* @__PURE__ */ jsx11(
989
+ return /* @__PURE__ */ jsx12(
931
990
  Repeater,
932
991
  {
933
992
  legend: getAdminLabel("section.careers"),
@@ -951,8 +1010,8 @@ function CareersForm({
951
1010
  emptyHint: getAdminLabel("empty.careers"),
952
1011
  renderItem: (career, update, index) => {
953
1012
  const at = `/careers/${String(index)}`;
954
- return /* @__PURE__ */ jsxs8(Fragment4, { children: [
955
- /* @__PURE__ */ jsx11(
1013
+ return /* @__PURE__ */ jsxs9(Fragment5, { children: [
1014
+ /* @__PURE__ */ jsx12(
956
1015
  LocaleTabs,
957
1016
  {
958
1017
  label: getAdminLabel("field.career.organization"),
@@ -967,7 +1026,7 @@ function CareersForm({
967
1026
  formatLocale
968
1027
  }
969
1028
  ),
970
- /* @__PURE__ */ jsx11(
1029
+ /* @__PURE__ */ jsx12(
971
1030
  LocaleTabs,
972
1031
  {
973
1032
  label: getAdminLabel("field.career.role"),
@@ -982,7 +1041,7 @@ function CareersForm({
982
1041
  formatLocale
983
1042
  }
984
1043
  ),
985
- /* @__PURE__ */ jsx11(
1044
+ /* @__PURE__ */ jsx12(
986
1045
  TextField,
987
1046
  {
988
1047
  label: getAdminLabel("field.career.startDate"),
@@ -996,7 +1055,7 @@ function CareersForm({
996
1055
  errors: errorsAt(errors, `${at}/startDate`)
997
1056
  }
998
1057
  ),
999
- /* @__PURE__ */ jsx11(
1058
+ /* @__PURE__ */ jsx12(
1000
1059
  TextField,
1001
1060
  {
1002
1061
  label: getAdminLabel("field.career.endDate"),
@@ -1009,7 +1068,7 @@ function CareersForm({
1009
1068
  errors: errorsAt(errors, `${at}/endDate`)
1010
1069
  }
1011
1070
  ),
1012
- /* @__PURE__ */ jsx11(
1071
+ /* @__PURE__ */ jsx12(
1013
1072
  CheckboxField,
1014
1073
  {
1015
1074
  label: getAdminLabel("field.career.isCurrent"),
@@ -1019,7 +1078,7 @@ function CareersForm({
1019
1078
  }
1020
1079
  }
1021
1080
  ),
1022
- /* @__PURE__ */ jsx11(
1081
+ /* @__PURE__ */ jsx12(
1023
1082
  LocaleTabs,
1024
1083
  {
1025
1084
  label: getAdminLabel("field.career.description"),
@@ -1034,7 +1093,7 @@ function CareersForm({
1034
1093
  formatLocale
1035
1094
  }
1036
1095
  ),
1037
- /* @__PURE__ */ jsx11(
1096
+ /* @__PURE__ */ jsx12(
1038
1097
  TextField,
1039
1098
  {
1040
1099
  label: getAdminLabel("field.career.url"),
@@ -1053,7 +1112,7 @@ function CareersForm({
1053
1112
  }
1054
1113
 
1055
1114
  // src/admin/sections/ProjectsForm.tsx
1056
- import { Fragment as Fragment5, jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
1115
+ import { Fragment as Fragment6, jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
1057
1116
  function parseTags(input) {
1058
1117
  const tags = input.split(",").map((tag) => tag.trim()).filter((tag) => tag !== "");
1059
1118
  return tags.length > 0 ? tags : void 0;
@@ -1065,7 +1124,7 @@ function ProjectsForm({
1065
1124
  errors = NO_FIELD_ERRORS,
1066
1125
  formatLocale
1067
1126
  }) {
1068
- return /* @__PURE__ */ jsx12(
1127
+ return /* @__PURE__ */ jsx13(
1069
1128
  Repeater,
1070
1129
  {
1071
1130
  legend: getAdminLabel("section.projects"),
@@ -1087,8 +1146,8 @@ function ProjectsForm({
1087
1146
  emptyHint: getAdminLabel("empty.projects"),
1088
1147
  renderItem: (project, update, index) => {
1089
1148
  const at = `/projects/${String(index)}`;
1090
- return /* @__PURE__ */ jsxs9(Fragment5, { children: [
1091
- /* @__PURE__ */ jsx12(
1149
+ return /* @__PURE__ */ jsxs10(Fragment6, { children: [
1150
+ /* @__PURE__ */ jsx13(
1092
1151
  LocaleTabs,
1093
1152
  {
1094
1153
  label: getAdminLabel("field.project.title"),
@@ -1103,7 +1162,7 @@ function ProjectsForm({
1103
1162
  formatLocale
1104
1163
  }
1105
1164
  ),
1106
- /* @__PURE__ */ jsx12(
1165
+ /* @__PURE__ */ jsx13(
1107
1166
  LocaleTabs,
1108
1167
  {
1109
1168
  label: getAdminLabel("field.project.description"),
@@ -1118,7 +1177,7 @@ function ProjectsForm({
1118
1177
  formatLocale
1119
1178
  }
1120
1179
  ),
1121
- /* @__PURE__ */ jsx12(
1180
+ /* @__PURE__ */ jsx13(
1122
1181
  TextField,
1123
1182
  {
1124
1183
  label: getAdminLabel("field.project.url"),
@@ -1130,7 +1189,7 @@ function ProjectsForm({
1130
1189
  errors: errorsAt(errors, `${at}/url`)
1131
1190
  }
1132
1191
  ),
1133
- /* @__PURE__ */ jsx12(
1192
+ /* @__PURE__ */ jsx13(
1134
1193
  TextField,
1135
1194
  {
1136
1195
  label: getAdminLabel("field.project.tags"),
@@ -1142,7 +1201,7 @@ function ProjectsForm({
1142
1201
  errors: collectErrorsUnder(errors, `${at}/tags`)
1143
1202
  }
1144
1203
  ),
1145
- /* @__PURE__ */ jsx12(
1204
+ /* @__PURE__ */ jsx13(
1146
1205
  TextField,
1147
1206
  {
1148
1207
  label: getAdminLabel("field.project.startDate"),
@@ -1155,7 +1214,7 @@ function ProjectsForm({
1155
1214
  errors: errorsAt(errors, `${at}/startDate`)
1156
1215
  }
1157
1216
  ),
1158
- /* @__PURE__ */ jsx12(
1217
+ /* @__PURE__ */ jsx13(
1159
1218
  TextField,
1160
1219
  {
1161
1220
  label: getAdminLabel("field.project.endDate"),
@@ -1168,7 +1227,7 @@ function ProjectsForm({
1168
1227
  errors: errorsAt(errors, `${at}/endDate`)
1169
1228
  }
1170
1229
  ),
1171
- /* @__PURE__ */ jsx12(
1230
+ /* @__PURE__ */ jsx13(
1172
1231
  CheckboxField,
1173
1232
  {
1174
1233
  label: getAdminLabel("field.project.highlighted"),
@@ -1185,13 +1244,13 @@ function ProjectsForm({
1185
1244
  }
1186
1245
 
1187
1246
  // src/admin/sections/SkillsForm.tsx
1188
- import { Fragment as Fragment6, jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
1247
+ import { Fragment as Fragment7, jsx as jsx14, jsxs as jsxs11 } from "react/jsx-runtime";
1189
1248
  function SkillsForm({
1190
1249
  value,
1191
1250
  onChange,
1192
1251
  errors = NO_FIELD_ERRORS
1193
1252
  }) {
1194
- return /* @__PURE__ */ jsx13(
1253
+ return /* @__PURE__ */ jsx14(
1195
1254
  Repeater,
1196
1255
  {
1197
1256
  legend: getAdminLabel("section.skills"),
@@ -1213,8 +1272,8 @@ function SkillsForm({
1213
1272
  emptyHint: getAdminLabel("empty.skills"),
1214
1273
  renderItem: (skill, update, index) => {
1215
1274
  const at = `/skills/${String(index)}`;
1216
- return /* @__PURE__ */ jsxs10(Fragment6, { children: [
1217
- /* @__PURE__ */ jsx13(
1275
+ return /* @__PURE__ */ jsxs11(Fragment7, { children: [
1276
+ /* @__PURE__ */ jsx14(
1218
1277
  TextField,
1219
1278
  {
1220
1279
  label: getAdminLabel("field.skill.label"),
@@ -1226,7 +1285,7 @@ function SkillsForm({
1226
1285
  errors: errorsAt(errors, `${at}/label`)
1227
1286
  }
1228
1287
  ),
1229
- /* @__PURE__ */ jsx13(
1288
+ /* @__PURE__ */ jsx14(
1230
1289
  TextField,
1231
1290
  {
1232
1291
  label: getAdminLabel("field.skill.category"),
@@ -1244,8 +1303,8 @@ function SkillsForm({
1244
1303
  }
1245
1304
 
1246
1305
  // src/admin/sections/SettingsForm.tsx
1247
- import styles10 from "../sections.module-ZVBKZHDE.module.css";
1248
- import { jsx as jsx14, jsxs as jsxs11 } from "react/jsx-runtime";
1306
+ import styles11 from "../sections.module-ZVBKZHDE.module.css";
1307
+ import { jsx as jsx15, jsxs as jsxs12 } from "react/jsx-runtime";
1249
1308
  function parseLocales(input) {
1250
1309
  return input.split(",").map((tag) => tag.trim()).filter((tag) => tag !== "");
1251
1310
  }
@@ -1261,9 +1320,9 @@ function SettingsForm({
1261
1320
  label: format(locale)
1262
1321
  }));
1263
1322
  const headingId = "admin-section-settings";
1264
- return /* @__PURE__ */ jsxs11("section", { className: styles10.section, "aria-labelledby": headingId, children: [
1265
- /* @__PURE__ */ jsx14("h2", { className: styles10.heading, id: headingId, children: getAdminLabel("section.settings") }),
1266
- /* @__PURE__ */ jsx14(
1323
+ return /* @__PURE__ */ jsxs12("section", { className: styles11.section, "aria-labelledby": headingId, children: [
1324
+ /* @__PURE__ */ jsx15("h2", { className: styles11.heading, id: headingId, children: getAdminLabel("section.settings") }),
1325
+ /* @__PURE__ */ jsx15(
1267
1326
  TextField,
1268
1327
  {
1269
1328
  label: getAdminLabel("field.settings.availableLocales"),
@@ -1276,7 +1335,7 @@ function SettingsForm({
1276
1335
  errors: collectErrorsUnder(errors, "/settings/availableLocales")
1277
1336
  }
1278
1337
  ),
1279
- /* @__PURE__ */ jsx14(
1338
+ /* @__PURE__ */ jsx15(
1280
1339
  SelectField,
1281
1340
  {
1282
1341
  label: getAdminLabel("field.settings.defaultLocale"),
@@ -1289,7 +1348,7 @@ function SettingsForm({
1289
1348
  errors: errorsAt(errors, "/settings/defaultLocale")
1290
1349
  }
1291
1350
  ),
1292
- /* @__PURE__ */ jsx14(
1351
+ /* @__PURE__ */ jsx15(
1293
1352
  SelectField,
1294
1353
  {
1295
1354
  label: getAdminLabel("field.settings.fallbackLocale"),
@@ -1301,7 +1360,7 @@ function SettingsForm({
1301
1360
  errors: errorsAt(errors, "/settings/fallbackLocale")
1302
1361
  }
1303
1362
  ),
1304
- /* @__PURE__ */ jsx14(
1363
+ /* @__PURE__ */ jsx15(
1305
1364
  TextField,
1306
1365
  {
1307
1366
  label: getAdminLabel("field.settings.theme"),
@@ -1312,7 +1371,7 @@ function SettingsForm({
1312
1371
  errors: errorsAt(errors, "/settings/theme")
1313
1372
  }
1314
1373
  ),
1315
- /* @__PURE__ */ jsx14(
1374
+ /* @__PURE__ */ jsx15(
1316
1375
  CheckboxField,
1317
1376
  {
1318
1377
  label: getAdminLabel("field.settings.showPoweredBy"),
@@ -1322,7 +1381,7 @@ function SettingsForm({
1322
1381
  }
1323
1382
  }
1324
1383
  ),
1325
- /* @__PURE__ */ jsx14(
1384
+ /* @__PURE__ */ jsx15(
1326
1385
  CheckboxField,
1327
1386
  {
1328
1387
  label: getAdminLabel("field.settings.enableJsonLd"),
@@ -1332,7 +1391,7 @@ function SettingsForm({
1332
1391
  }
1333
1392
  }
1334
1393
  ),
1335
- /* @__PURE__ */ jsx14(
1394
+ /* @__PURE__ */ jsx15(
1336
1395
  CheckboxField,
1337
1396
  {
1338
1397
  label: getAdminLabel("field.settings.enableApi"),
@@ -1342,7 +1401,7 @@ function SettingsForm({
1342
1401
  }
1343
1402
  }
1344
1403
  ),
1345
- /* @__PURE__ */ jsx14(
1404
+ /* @__PURE__ */ jsx15(
1346
1405
  CheckboxField,
1347
1406
  {
1348
1407
  label: getAdminLabel("field.settings.enableAnalytics"),
@@ -1357,13 +1416,13 @@ function SettingsForm({
1357
1416
 
1358
1417
  // src/admin/RawJsonEditor.tsx
1359
1418
  import { validate } from "@takuhon/core";
1360
- import { useId as useId5, useState as useState3 } from "react";
1361
- import styles11 from "../RawJsonEditor.module-NGGM3IBY.module.css";
1362
- import { jsx as jsx15, jsxs as jsxs12 } from "react/jsx-runtime";
1419
+ import { useId as useId5, useState as useState4 } from "react";
1420
+ import styles12 from "../RawJsonEditor.module-NGGM3IBY.module.css";
1421
+ import { jsx as jsx16, jsxs as jsxs13 } from "react/jsx-runtime";
1363
1422
  var MAX_SHOWN_PROBLEMS = 50;
1364
1423
  function RawJsonEditor({ value, onChange }) {
1365
- const [text, setText] = useState3(() => JSON.stringify(value, null, 2));
1366
- const [problems, setProblems] = useState3([]);
1424
+ const [text, setText] = useState4(() => JSON.stringify(value, null, 2));
1425
+ const [problems, setProblems] = useState4([]);
1367
1426
  const labelId = useId5();
1368
1427
  const errorId = useId5();
1369
1428
  const apply = (next) => {
@@ -1386,13 +1445,13 @@ function RawJsonEditor({ value, onChange }) {
1386
1445
  onChange(result.data);
1387
1446
  };
1388
1447
  const hasProblems = problems.length > 0;
1389
- return /* @__PURE__ */ jsxs12("section", { className: styles11.wrapper, "aria-labelledby": labelId, children: [
1390
- /* @__PURE__ */ jsx15("h2", { className: styles11.heading, id: labelId, children: getAdminLabel("mode.advanced") }),
1391
- /* @__PURE__ */ jsx15("p", { className: styles11.hint, children: getAdminLabel("advanced.hint") }),
1392
- /* @__PURE__ */ jsx15(
1448
+ return /* @__PURE__ */ jsxs13("section", { className: styles12.wrapper, "aria-labelledby": labelId, children: [
1449
+ /* @__PURE__ */ jsx16("h2", { className: styles12.heading, id: labelId, children: getAdminLabel("mode.advanced") }),
1450
+ /* @__PURE__ */ jsx16("p", { className: styles12.hint, children: getAdminLabel("advanced.hint") }),
1451
+ /* @__PURE__ */ jsx16(
1393
1452
  "textarea",
1394
1453
  {
1395
- className: styles11.textarea,
1454
+ className: styles12.textarea,
1396
1455
  value: text,
1397
1456
  spellCheck: false,
1398
1457
  "aria-label": getAdminLabel("mode.advanced"),
@@ -1403,18 +1462,18 @@ function RawJsonEditor({ value, onChange }) {
1403
1462
  }
1404
1463
  }
1405
1464
  ),
1406
- hasProblems ? /* @__PURE__ */ jsxs12("div", { className: styles11.problems, id: errorId, role: "alert", children: [
1407
- /* @__PURE__ */ jsx15("p", { className: styles11.problemsTitle, children: getAdminLabel("advanced.invalid") }),
1408
- /* @__PURE__ */ jsx15("ul", { children: problems.map((problem, i) => /* @__PURE__ */ jsx15("li", { children: problem }, i)) })
1465
+ hasProblems ? /* @__PURE__ */ jsxs13("div", { className: styles12.problems, id: errorId, role: "alert", children: [
1466
+ /* @__PURE__ */ jsx16("p", { className: styles12.problemsTitle, children: getAdminLabel("advanced.invalid") }),
1467
+ /* @__PURE__ */ jsx16("ul", { children: problems.map((problem, i) => /* @__PURE__ */ jsx16("li", { children: problem }, i)) })
1409
1468
  ] }) : null
1410
1469
  ] });
1411
1470
  }
1412
1471
 
1413
1472
  // src/admin/AdminEditor.tsx
1414
1473
  import { validate as validate2 } from "@takuhon/core";
1415
- import { useRef as useRef3, useState as useState4 } from "react";
1416
- import styles12 from "../AdminEditor.module-ABYQXFN4.module.css";
1417
- import { jsx as jsx16, jsxs as jsxs13 } from "react/jsx-runtime";
1474
+ import { useRef as useRef3, useState as useState5 } from "react";
1475
+ import styles13 from "../AdminEditor.module-ABYQXFN4.module.css";
1476
+ import { jsx as jsx17, jsxs as jsxs14 } from "react/jsx-runtime";
1418
1477
  function AdminEditor({
1419
1478
  initialDocument,
1420
1479
  onSave,
@@ -1424,12 +1483,12 @@ function AdminEditor({
1424
1483
  formatLocale,
1425
1484
  uploadAsset
1426
1485
  }) {
1427
- const [draft, setDraft] = useState4(initialDocument);
1428
- const [mode, setMode] = useState4("form");
1429
- const [errors, setErrors] = useState4(NO_FIELD_ERRORS);
1430
- const [status, setStatus] = useState4(null);
1431
- const [busy, setBusy] = useState4(false);
1432
- const [loadGen, setLoadGen] = useState4(0);
1486
+ const [draft, setDraft] = useState5(initialDocument);
1487
+ const [mode, setMode] = useState5("form");
1488
+ const [errors, setErrors] = useState5(NO_FIELD_ERRORS);
1489
+ const [status, setStatus] = useState5(null);
1490
+ const [busy, setBusy] = useState5(false);
1491
+ const [loadGen, setLoadGen] = useState5(0);
1433
1492
  const intentRef = useRef3(0);
1434
1493
  const locales = draft.settings.availableLocales;
1435
1494
  const updateDraft = (next) => {
@@ -1517,14 +1576,14 @@ function AdminEditor({
1517
1576
  const errorEntries = [...errors].flatMap(
1518
1577
  ([pointer, messages]) => messages.map((message) => ({ pointer, message }))
1519
1578
  );
1520
- return /* @__PURE__ */ jsxs13("div", { className: styles12.editor, children: [
1521
- /* @__PURE__ */ jsxs13("div", { className: styles12.toolbar, role: "toolbar", "aria-label": getAdminLabel("toolbar.label"), children: [
1522
- /* @__PURE__ */ jsxs13("div", { className: styles12.modes, role: "group", "aria-label": getAdminLabel("mode.label"), children: [
1523
- /* @__PURE__ */ jsx16(
1579
+ return /* @__PURE__ */ jsxs14("div", { className: styles13.editor, children: [
1580
+ /* @__PURE__ */ jsxs14("div", { className: styles13.toolbar, role: "toolbar", "aria-label": getAdminLabel("toolbar.label"), children: [
1581
+ /* @__PURE__ */ jsxs14("div", { className: styles13.modes, role: "group", "aria-label": getAdminLabel("mode.label"), children: [
1582
+ /* @__PURE__ */ jsx17(
1524
1583
  "button",
1525
1584
  {
1526
1585
  type: "button",
1527
- className: `${styles12.modeButton} ${mode === "form" ? styles12.modeActive : ""}`,
1586
+ className: `${styles13.modeButton} ${mode === "form" ? styles13.modeActive : ""}`,
1528
1587
  "aria-pressed": mode === "form",
1529
1588
  onClick: () => {
1530
1589
  setMode("form");
@@ -1532,11 +1591,11 @@ function AdminEditor({
1532
1591
  children: getAdminLabel("mode.form")
1533
1592
  }
1534
1593
  ),
1535
- /* @__PURE__ */ jsx16(
1594
+ /* @__PURE__ */ jsx17(
1536
1595
  "button",
1537
1596
  {
1538
1597
  type: "button",
1539
- className: `${styles12.modeButton} ${mode === "advanced" ? styles12.modeActive : ""}`,
1598
+ className: `${styles13.modeButton} ${mode === "advanced" ? styles13.modeActive : ""}`,
1540
1599
  "aria-pressed": mode === "advanced",
1541
1600
  onClick: () => {
1542
1601
  setMode("advanced");
@@ -1545,12 +1604,12 @@ function AdminEditor({
1545
1604
  }
1546
1605
  )
1547
1606
  ] }),
1548
- /* @__PURE__ */ jsxs13("div", { className: styles12.actions, children: [
1549
- /* @__PURE__ */ jsx16(
1607
+ /* @__PURE__ */ jsxs14("div", { className: styles13.actions, children: [
1608
+ /* @__PURE__ */ jsx17(
1550
1609
  "button",
1551
1610
  {
1552
1611
  type: "button",
1553
- className: styles12.primary,
1612
+ className: styles13.primary,
1554
1613
  disabled: busy,
1555
1614
  onClick: () => {
1556
1615
  void handleSave();
@@ -1558,11 +1617,11 @@ function AdminEditor({
1558
1617
  children: getAdminLabel("action.save")
1559
1618
  }
1560
1619
  ),
1561
- onReload ? /* @__PURE__ */ jsx16(
1620
+ onReload ? /* @__PURE__ */ jsx17(
1562
1621
  "button",
1563
1622
  {
1564
1623
  type: "button",
1565
- className: styles12.secondary,
1624
+ className: styles13.secondary,
1566
1625
  disabled: busy,
1567
1626
  onClick: () => {
1568
1627
  void handleReload();
@@ -1570,22 +1629,22 @@ function AdminEditor({
1570
1629
  children: getAdminLabel("action.reload")
1571
1630
  }
1572
1631
  ) : null,
1573
- onExport ? /* @__PURE__ */ jsx16(
1632
+ onExport ? /* @__PURE__ */ jsx17(
1574
1633
  "button",
1575
1634
  {
1576
1635
  type: "button",
1577
- className: styles12.secondary,
1636
+ className: styles13.secondary,
1578
1637
  onClick: () => {
1579
1638
  onExport(draft);
1580
1639
  },
1581
1640
  children: getAdminLabel("action.export")
1582
1641
  }
1583
1642
  ) : null,
1584
- onImport ? /* @__PURE__ */ jsx16(
1643
+ onImport ? /* @__PURE__ */ jsx17(
1585
1644
  "button",
1586
1645
  {
1587
1646
  type: "button",
1588
- className: styles12.secondary,
1647
+ className: styles13.secondary,
1589
1648
  disabled: busy,
1590
1649
  onClick: () => {
1591
1650
  void handleImport();
@@ -1595,13 +1654,13 @@ function AdminEditor({
1595
1654
  ) : null
1596
1655
  ] })
1597
1656
  ] }),
1598
- /* @__PURE__ */ jsx16("p", { className: styles12.status, role: "status", "aria-live": "polite", "data-tone": status?.tone, children: status?.message ?? "" }),
1599
- errorEntries.length > 0 ? /* @__PURE__ */ jsxs13("section", { className: styles12.summary, "aria-labelledby": "admin-error-summary", children: [
1600
- /* @__PURE__ */ jsx16("h2", { className: styles12.summaryHeading, id: "admin-error-summary", children: getAdminLabel("status.fixSummary") }),
1601
- /* @__PURE__ */ jsx16("ul", { children: errorEntries.map((entry, i) => /* @__PURE__ */ jsx16("li", { children: entry.pointer === "" ? entry.message : `${entry.pointer.replace(/^\//, "")}: ${entry.message}` }, i)) })
1657
+ /* @__PURE__ */ jsx17("p", { className: styles13.status, role: "status", "aria-live": "polite", "data-tone": status?.tone, children: status?.message ?? "" }),
1658
+ errorEntries.length > 0 ? /* @__PURE__ */ jsxs14("section", { className: styles13.summary, "aria-labelledby": "admin-error-summary", children: [
1659
+ /* @__PURE__ */ jsx17("h2", { className: styles13.summaryHeading, id: "admin-error-summary", children: getAdminLabel("status.fixSummary") }),
1660
+ /* @__PURE__ */ jsx17("ul", { children: errorEntries.map((entry, i) => /* @__PURE__ */ jsx17("li", { children: entry.pointer === "" ? entry.message : `${entry.pointer.replace(/^\//, "")}: ${entry.message}` }, i)) })
1602
1661
  ] }) : null,
1603
- mode === "form" ? /* @__PURE__ */ jsxs13("div", { className: styles12.sections, children: [
1604
- /* @__PURE__ */ jsx16(
1662
+ mode === "form" ? /* @__PURE__ */ jsxs14("div", { className: styles13.sections, children: [
1663
+ /* @__PURE__ */ jsx17(
1605
1664
  ProfileForm,
1606
1665
  {
1607
1666
  value: draft.profile,
@@ -1614,7 +1673,7 @@ function AdminEditor({
1614
1673
  uploadAsset
1615
1674
  }
1616
1675
  ),
1617
- /* @__PURE__ */ jsx16(
1676
+ /* @__PURE__ */ jsx17(
1618
1677
  LinksForm,
1619
1678
  {
1620
1679
  value: draft.links,
@@ -1626,7 +1685,7 @@ function AdminEditor({
1626
1685
  formatLocale
1627
1686
  }
1628
1687
  ),
1629
- /* @__PURE__ */ jsx16(
1688
+ /* @__PURE__ */ jsx17(
1630
1689
  CareersForm,
1631
1690
  {
1632
1691
  value: draft.careers,
@@ -1638,7 +1697,7 @@ function AdminEditor({
1638
1697
  formatLocale
1639
1698
  }
1640
1699
  ),
1641
- /* @__PURE__ */ jsx16(
1700
+ /* @__PURE__ */ jsx17(
1642
1701
  ProjectsForm,
1643
1702
  {
1644
1703
  value: draft.projects,
@@ -1650,7 +1709,7 @@ function AdminEditor({
1650
1709
  formatLocale
1651
1710
  }
1652
1711
  ),
1653
- /* @__PURE__ */ jsx16(
1712
+ /* @__PURE__ */ jsx17(
1654
1713
  SkillsForm,
1655
1714
  {
1656
1715
  value: draft.skills,
@@ -1660,7 +1719,7 @@ function AdminEditor({
1660
1719
  errors
1661
1720
  }
1662
1721
  ),
1663
- /* @__PURE__ */ jsx16(
1722
+ /* @__PURE__ */ jsx17(
1664
1723
  SettingsForm,
1665
1724
  {
1666
1725
  value: draft.settings,
@@ -1671,7 +1730,7 @@ function AdminEditor({
1671
1730
  formatLocale
1672
1731
  }
1673
1732
  )
1674
- ] }) : /* @__PURE__ */ jsx16(RawJsonEditor, { value: draft, onChange: updateDraft }, loadGen)
1733
+ ] }) : /* @__PURE__ */ jsx17(RawJsonEditor, { value: draft, onChange: updateDraft }, loadGen)
1675
1734
  ] });
1676
1735
  }
1677
1736
  export {
@@ -1679,6 +1738,7 @@ export {
1679
1738
  CareersForm,
1680
1739
  CheckboxField,
1681
1740
  Field,
1741
+ GravatarField,
1682
1742
  ImageField,
1683
1743
  LinksForm,
1684
1744
  LocaleTabs,