@treeviz/gedcom-parser 2.1.9 → 2.1.12

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.
Files changed (43) hide show
  1. package/dist/classes/common.d.ts.map +1 -1
  2. package/dist/classes/gedcom.d.ts +5 -0
  3. package/dist/classes/gedcom.d.ts.map +1 -1
  4. package/dist/classes/index.js +860 -464
  5. package/dist/classes/indi.d.ts.map +1 -1
  6. package/dist/classes/obje.d.ts.map +1 -1
  7. package/dist/cli/index.js +850 -454
  8. package/dist/constants/index.js +818 -448
  9. package/dist/factories/index.js +818 -448
  10. package/dist/index.js +865 -474
  11. package/dist/interfaces/indi.d.ts +1 -0
  12. package/dist/interfaces/indi.d.ts.map +1 -1
  13. package/dist/kinship-translator/index.js +818 -448
  14. package/dist/kinship-translator/kinship-translator.de.d.ts +2 -3
  15. package/dist/kinship-translator/kinship-translator.de.d.ts.map +1 -1
  16. package/dist/kinship-translator/kinship-translator.en.d.ts.map +1 -1
  17. package/dist/kinship-translator/kinship-translator.es.d.ts +2 -3
  18. package/dist/kinship-translator/kinship-translator.es.d.ts.map +1 -1
  19. package/dist/kinship-translator/kinship-translator.fr.d.ts +2 -3
  20. package/dist/kinship-translator/kinship-translator.fr.d.ts.map +1 -1
  21. package/dist/kinship-translator/kinship-translator.hu.d.ts.map +1 -1
  22. package/dist/kinship-translator/kinship-translator.ja.d.ts.map +1 -1
  23. package/dist/kinship-translator/kinship-translator.ru.d.ts +1 -1
  24. package/dist/kinship-translator/kinship-translator.ru.d.ts.map +1 -1
  25. package/dist/kinship-translator/kinship-translator.zh.d.ts.map +1 -1
  26. package/dist/kinship-translator/patterns.de.d.ts +1 -0
  27. package/dist/kinship-translator/patterns.de.d.ts.map +1 -1
  28. package/dist/kinship-translator/patterns.es.d.ts +1 -0
  29. package/dist/kinship-translator/patterns.es.d.ts.map +1 -1
  30. package/dist/kinship-translator/patterns.fr.d.ts +1 -0
  31. package/dist/kinship-translator/patterns.fr.d.ts.map +1 -1
  32. package/dist/kinship-translator/patterns.hu.d.ts.map +1 -1
  33. package/dist/kinship-translator/patterns.ru.d.ts +1 -0
  34. package/dist/kinship-translator/patterns.ru.d.ts.map +1 -1
  35. package/dist/kinship-translator/patterns.zh.d.ts.map +1 -1
  36. package/dist/utils/cache.d.ts.map +1 -1
  37. package/dist/utils/gedzip.d.ts.map +1 -1
  38. package/dist/utils/index.js +865 -474
  39. package/dist/utils/local-media.d.ts +7 -3
  40. package/dist/utils/local-media.d.ts.map +1 -1
  41. package/dist/utils/media-utils.d.ts +20 -0
  42. package/dist/utils/media-utils.d.ts.map +1 -1
  43. package/package.json +1 -1
@@ -464,7 +464,7 @@ var KinshipTranslatorHU = class extends KinshipTranslatorBasic {
464
464
  }
465
465
  return `${hungarianOrdinalize(
466
466
  degree
467
- )}unokatestv\xE9r ${level}x elt\xE1vol\xEDtva`;
467
+ )}unokatestv\xE9r ${Math.abs(level)}x elt\xE1vol\xEDtva`;
468
468
  }
469
469
  auncle() {
470
470
  const level = this.pathN?.level ?? 0;
@@ -508,14 +508,25 @@ var KinshipTranslatorHU = class extends KinshipTranslatorBasic {
508
508
  return `${ordinalized ? `${ordinalized}unoka` : ""}testv\xE9r ${origPrefix.replace(/nagy$/, "")}unok\xE1ja`;
509
509
  }
510
510
  parent() {
511
+ const level = Math.abs(this.pathN?.level ?? 0);
512
+ if (level <= 1) {
513
+ if (this.personN?.isMale()) {
514
+ return "apa";
515
+ }
516
+ if (this.personN?.isFemale()) {
517
+ return "anya";
518
+ }
519
+ return "sz\xFCl\u0151";
520
+ }
511
521
  const prefix = this.directPrefix();
522
+ const gen = prefix === "nagy" ? "" : prefix;
512
523
  if (this.personN?.isMale()) {
513
- return `${prefix}apa`;
524
+ return `${gen}nagyapa`;
514
525
  }
515
526
  if (this.personN?.isFemale()) {
516
- return `${prefix}anya`;
527
+ return `${gen}nagyanya`;
517
528
  }
518
- return `${prefix}sz\xFCl\u0151`;
529
+ return `${gen}nagysz\xFCl\u0151`;
519
530
  }
520
531
  child() {
521
532
  const level = Math.abs(this.pathN?.level ?? 0);
@@ -709,27 +720,30 @@ var KinshipTranslatorEn = class extends KinshipTranslatorBasic {
709
720
  if (!degree) {
710
721
  return level < 0 ? this.nibling() : this.auncle();
711
722
  }
712
- return `${ordinalize(degree)} cousin ${level}x removed`;
723
+ return `${ordinalize(degree)} cousin ${Math.abs(level)}x removed`;
713
724
  }
714
725
  auncle() {
715
- const prefix = this.directPrefix();
726
+ const level = Math.abs(this.pathN?.level ?? 0);
727
+ const greats = level <= 1 ? "" : "great-".repeat(level - 1);
716
728
  if (this.personN?.isMale()) {
717
- return `${prefix}uncle`;
729
+ return `${greats}uncle`;
718
730
  }
719
731
  if (this.personN?.isFemale()) {
720
- return `${prefix}aunt`;
732
+ return `${greats}aunt`;
721
733
  }
722
- return `${prefix}auncle`;
734
+ return greats ? `${greats}uncle/${greats}aunt` : "uncle/aunt";
723
735
  }
724
736
  nibling() {
725
- const prefix = this.directPrefix();
737
+ const level = Math.abs(this.pathN?.level ?? 0);
738
+ const greats = level <= 2 ? "" : "great-".repeat(level - 2);
739
+ const grand = level <= 1 ? "" : "grand";
726
740
  if (this.personN?.isMale()) {
727
- return `${prefix}nephew`;
741
+ return `${greats}${grand}nephew`;
728
742
  }
729
743
  if (this.personN?.isFemale()) {
730
- return `${prefix}niece`;
744
+ return `${greats}${grand}niece`;
731
745
  }
732
- return `${prefix}nibling`;
746
+ return greats || grand ? `${greats}${grand}nephew/${greats}${grand}niece` : "nephew/niece";
733
747
  }
734
748
  parent() {
735
749
  const prefix = this.directPrefix();
@@ -857,45 +871,70 @@ var KinshipTranslatorEn = class extends KinshipTranslatorBasic {
857
871
  };
858
872
 
859
873
  // src/kinship-translator/patterns.fr.ts
874
+ var parentRelationsFr = {
875
+ step: "step",
876
+ foster: "foster",
877
+ adopted: "adopted"
878
+ };
860
879
  var InLawsFr = {
861
880
  "conjoint de (enfant|fille|fils)": "beau-fils/belle-fille",
862
881
  "\xE9pouse de (enfant|fille|fils)": "belle-fille",
863
882
  "mari de (enfant|fille|fils)": "gendre",
864
- "m\xE8re du (conjoint|\xE9pouse|mari)": "belle-m\xE8re",
865
- "p\xE8re du (conjoint|\xE9pouse|mari)": "beau-p\xE8re",
866
- "parent du (conjoint|\xE9pouse|mari)": "beau-parent",
883
+ "m\xE8re (du mari|du conjoint|de l'\xE9pouse)": "belle-m\xE8re",
884
+ "p\xE8re (du mari|du conjoint|de l'\xE9pouse)": "beau-p\xE8re",
885
+ "parent (du mari|du conjoint|de l'\xE9pouse)": "beau-parent",
867
886
  "\xE9pouse de (demi-)?(fr\xE8re/s\u0153ur|s\u0153ur|fr\xE8re)": "belle-s\u0153ur",
868
887
  "mari de (demi-)?(fr\xE8re/s\u0153ur|s\u0153ur|fr\xE8re)": "beau-fr\xE8re",
869
888
  "conjoint de (demi-)?(fr\xE8re/s\u0153ur|s\u0153ur|fr\xE8re)": "beau-fr\xE8re/belle-s\u0153ur",
870
- "(demi-)?s\u0153ur du (conjoint|\xE9pouse|mari)": "belle-s\u0153ur",
871
- "(demi-)?fr\xE8re du (conjoint|\xE9pouse|mari)": "beau-fr\xE8re",
872
- "(demi-)?fr\xE8re/s\u0153ur du (conjoint|\xE9pouse|mari)": "beau-fr\xE8re/belle-s\u0153ur"
889
+ "(demi-)?s\u0153ur (du mari|du conjoint|de l'\xE9pouse)": "belle-s\u0153ur",
890
+ "(demi-)?fr\xE8re (du mari|du conjoint|de l'\xE9pouse)": "beau-fr\xE8re",
891
+ "(demi-)?fr\xE8re/s\u0153ur (du mari|du conjoint|de l'\xE9pouse)": "beau-fr\xE8re/belle-s\u0153ur"
873
892
  };
874
893
 
875
894
  // src/kinship-translator/kinship-translator.fr.ts
876
- var KinshipTranslatorFr = class extends KinshipTranslatorBasic {
877
- directPrefix() {
878
- const level = Math.abs(this.pathN?.level ?? 0);
879
- if (level <= 1) {
880
- return "";
881
- }
882
- if (level === 2) {
883
- return "grand-";
884
- }
885
- if (level === 3) {
886
- return "arri\xE8re-grand-";
887
- }
888
- return `arri\xE8re${level - 2}-grand-`;
895
+ var sexOf = (person) => {
896
+ if (person?.isMale?.()) {
897
+ return "m";
898
+ }
899
+ if (person?.isFemale?.()) {
900
+ return "f";
901
+ }
902
+ return "n";
903
+ };
904
+ var pick = (sex, male, female, neutral) => {
905
+ if (sex === "m") {
906
+ return male;
889
907
  }
908
+ if (sex === "f") {
909
+ return female;
910
+ }
911
+ return neutral;
912
+ };
913
+ var arriere = (count) => count > 0 ? "arri\xE8re-".repeat(count) : "";
914
+ var frenchOrdinal = (n) => n === 1 ? "1er" : `${n}e`;
915
+ var isFeminineRelation = (relation) => /mère|fille|sœur|tante|nièce|cousine|épouse/.test(relation);
916
+ var ofSpousePrep = (spouseType) => {
917
+ if (spouseType === "\xE9pouse") {
918
+ return "de l'";
919
+ }
920
+ return "du ";
921
+ };
922
+ var KinshipTranslatorFr = class extends KinshipTranslatorBasic {
890
923
  indirect() {
891
924
  let degree = Math.abs(this.pathN?.degree ?? 0);
892
925
  if (degree > 0) {
893
926
  degree = degree - 1;
894
927
  }
895
- if (degree === 1) {
896
- return `cousin`;
928
+ const cousin = pick(
929
+ sexOf(this.personN),
930
+ "cousin",
931
+ "cousine",
932
+ "cousin/cousine"
933
+ );
934
+ if (degree <= 1) {
935
+ return cousin;
897
936
  }
898
- return `cousin au ${ordinalize(degree)} degr\xE9`;
937
+ return `${cousin} au ${frenchOrdinal(degree)} degr\xE9`;
899
938
  }
900
939
  removal() {
901
940
  const level = this.pathN?.level ?? 0;
@@ -906,56 +945,57 @@ var KinshipTranslatorFr = class extends KinshipTranslatorBasic {
906
945
  if (!degree) {
907
946
  return level < 0 ? this.nibling() : this.auncle();
908
947
  }
909
- return `cousin au ${ordinalize(degree)} degr\xE9 ${Math.abs(level)}\xD7 \xE9loign\xE9`;
948
+ return `${this.indirect()} ${Math.abs(level)}\xD7 \xE9loign\xE9`;
910
949
  }
911
950
  auncle() {
912
- const prefix = this.directPrefix();
913
- if (this.personN?.isMale()) {
914
- return `${prefix}oncle`;
915
- }
916
- if (this.personN?.isFemale()) {
917
- return `${prefix}tante`;
951
+ const level = Math.abs(this.pathN?.level ?? 0);
952
+ const sex = sexOf(this.personN);
953
+ const base = pick(sex, "oncle", "tante", "oncle/tante");
954
+ if (level <= 1) {
955
+ return base;
918
956
  }
919
- return `${prefix}oncle/tante`;
957
+ const grands = pick(
958
+ sex,
959
+ "grand-oncle",
960
+ "grand-tante",
961
+ "grand-oncle/tante"
962
+ );
963
+ return `${arriere(level - 2)}${grands}`;
920
964
  }
921
965
  nibling() {
922
- const prefix = this.directPrefix();
923
- if (this.personN?.isMale()) {
924
- return `${prefix}neveu`;
925
- }
926
- if (this.personN?.isFemale()) {
927
- return `${prefix}ni\xE8ce`;
966
+ const level = Math.abs(this.pathN?.level ?? 0);
967
+ const sex = sexOf(this.personN);
968
+ if (level <= 1) {
969
+ return pick(sex, "neveu", "ni\xE8ce", "neveu/ni\xE8ce");
928
970
  }
929
- return `${prefix}neveu/ni\xE8ce`;
971
+ const grands = pick(
972
+ sex,
973
+ "grand-neveu",
974
+ "grande-ni\xE8ce",
975
+ "grand-neveu/grande-ni\xE8ce"
976
+ );
977
+ return `${arriere(level - 2)}${grands}`;
930
978
  }
931
979
  parent() {
932
- const prefix = this.directPrefix();
933
- if (this.personN?.isMale()) {
934
- return `${prefix}p\xE8re`;
935
- }
936
- if (this.personN?.isFemale()) {
937
- return `${prefix}m\xE8re`;
980
+ const level = Math.abs(this.pathN?.level ?? 0);
981
+ const sex = sexOf(this.personN);
982
+ if (level <= 1) {
983
+ return pick(sex, "p\xE8re", "m\xE8re", "parent");
938
984
  }
939
- return `${prefix}parent`;
985
+ const grands = pick(sex, "grand-p\xE8re", "grand-m\xE8re", "grand-parent");
986
+ return `${arriere(level - 2)}${grands}`;
940
987
  }
941
988
  child() {
942
- const prefix = this.directPrefix();
943
- if (this.personN?.isMale()) {
944
- return `${prefix}fils`;
945
- }
946
- if (this.personN?.isFemale()) {
947
- return `${prefix}fille`;
989
+ const level = Math.abs(this.pathN?.level ?? 0);
990
+ const sex = sexOf(this.personN);
991
+ if (level <= 1) {
992
+ return pick(sex, "fils", "fille", "enfant");
948
993
  }
949
- return `${prefix}enfant`;
994
+ const petits = pick(sex, "petit-fils", "petite-fille", "petit-enfant");
995
+ return `${arriere(level - 2)}${petits}`;
950
996
  }
951
997
  sibling() {
952
- if (this.personN?.isMale()) {
953
- return "fr\xE8re";
954
- }
955
- if (this.personN?.isFemale()) {
956
- return "s\u0153ur";
957
- }
958
- return "fr\xE8re/s\u0153ur";
998
+ return pick(sexOf(this.personN), "fr\xE8re", "s\u0153ur", "fr\xE8re/s\u0153ur");
959
999
  }
960
1000
  halfBlood(relation) {
961
1001
  if (!relation || !this.isHalfBlood) {
@@ -964,40 +1004,30 @@ var KinshipTranslatorFr = class extends KinshipTranslatorBasic {
964
1004
  return `demi-${relation}`;
965
1005
  }
966
1006
  spouse() {
967
- if (this.personN?.isMale()) {
968
- return "mari";
969
- }
970
- if (this.personN?.isFemale()) {
971
- return "\xE9pouse";
972
- }
973
- return "conjoint";
1007
+ return pick(sexOf(this.personN), "mari", "\xE9pouse", "conjoint");
974
1008
  }
975
1009
  ofSpouse(relation) {
976
1010
  if (!relation) {
977
1011
  return "";
978
1012
  }
979
- const spouse = this.path?.[1].indi;
980
- let spouseType = "conjoint";
981
- if (spouse?.isMale()) {
982
- spouseType = "mari";
983
- }
984
- if (spouse?.isFemale()) {
985
- spouseType = "\xE9pouse";
986
- }
987
- return `${relation} du ${spouseType}`;
1013
+ const spouseType = pick(
1014
+ sexOf(this.path?.[1].indi),
1015
+ "mari",
1016
+ "\xE9pouse",
1017
+ "conjoint"
1018
+ );
1019
+ return `${relation} ${ofSpousePrep(spouseType)}${spouseType}`;
988
1020
  }
989
1021
  spouseOf(relation) {
990
1022
  if (!relation) {
991
1023
  return "";
992
1024
  }
993
- const spouse = this.path?.[this.path.length - 1].indi;
994
- let spouseType = "conjoint";
995
- if (spouse?.isMale()) {
996
- spouseType = "mari";
997
- }
998
- if (spouse?.isFemale()) {
999
- spouseType = "\xE9pouse";
1000
- }
1025
+ const spouseType = pick(
1026
+ sexOf(this.path?.[this.path.length - 1].indi),
1027
+ "mari",
1028
+ "\xE9pouse",
1029
+ "conjoint"
1030
+ );
1001
1031
  return `${spouseType} de ${relation}`;
1002
1032
  }
1003
1033
  of(relation) {
@@ -1018,6 +1048,9 @@ var KinshipTranslatorFr = class extends KinshipTranslatorBasic {
1018
1048
  if (relation.includes(" du ") || relation.includes(" de ")) {
1019
1049
  return relation.replace(/ (du|de) /, ` $1 ${name} `);
1020
1050
  }
1051
+ if (relation.includes(" de l'")) {
1052
+ return relation.replace(" de l'", ` de ${name} l'`);
1053
+ }
1021
1054
  return `${relation} de ${name}`;
1022
1055
  }
1023
1056
  inLaw(relation) {
@@ -1046,50 +1079,118 @@ var KinshipTranslatorFr = class extends KinshipTranslatorBasic {
1046
1079
  if (!relation || !this.pathN?.relation) {
1047
1080
  return relation ?? "";
1048
1081
  }
1049
- return `${this.pathN.relation} ${relation}`;
1082
+ const kind = parentRelationsFr[this.pathN.relation];
1083
+ if (!kind) {
1084
+ return relation;
1085
+ }
1086
+ if (kind === "step") {
1087
+ return `${isFeminineRelation(relation) ? "belle-" : "beau-"}${relation}`;
1088
+ }
1089
+ if (kind === "adopted") {
1090
+ return `${relation} ${isFeminineRelation(relation) ? "adoptive" : "adoptif"}`;
1091
+ }
1092
+ if (kind === "foster") {
1093
+ return `${relation} d'accueil`;
1094
+ }
1095
+ return relation;
1050
1096
  }
1051
1097
  };
1052
1098
 
1053
1099
  // src/kinship-translator/patterns.es.ts
1100
+ var parentRelationsEs = {
1101
+ step: {
1102
+ padre: "padrastro",
1103
+ madre: "madrastra",
1104
+ hijo: "hijastro",
1105
+ hija: "hijastra",
1106
+ hermano: "hermanastro",
1107
+ hermana: "hermanastra",
1108
+ abuelo: "abuelastro",
1109
+ abuela: "abuelastra"
1110
+ }
1111
+ };
1054
1112
  var InLawsEs = {
1055
1113
  "c\xF3nyuge de (hijo/hija|hija|hijo)": "yerno/nuera",
1056
1114
  "esposa de (hijo/hija|hija|hijo)": "nuera",
1057
1115
  "esposo de (hijo/hija|hija|hijo)": "yerno",
1058
- "madre del (c\xF3nyuge|esposa|esposo)": "suegra",
1059
- "padre del (c\xF3nyuge|esposa|esposo)": "suegro",
1060
- "padre/madre del (c\xF3nyuge|esposa|esposo)": "suegro/suegra",
1116
+ "madre (del c\xF3nyuge|del esposo|de la esposa)": "suegra",
1117
+ "padre (del c\xF3nyuge|del esposo|de la esposa)": "suegro",
1118
+ "padre/madre (del c\xF3nyuge|del esposo|de la esposa)": "suegro/suegra",
1061
1119
  "esposa de (medio |media |medio/a )?(hermano/hermana|hermana|hermano)": "cu\xF1ada",
1062
1120
  "esposo de (medio |media |medio/a )?(hermano/hermana|hermana|hermano)": "cu\xF1ado",
1063
1121
  "c\xF3nyuge de (medio |media |medio/a )?(hermano/hermana|hermana|hermano)": "cu\xF1ado/cu\xF1ada",
1064
- "(medio |media |medio/a )?hermana del (c\xF3nyuge|esposa|esposo)": "cu\xF1ada",
1065
- "(medio |media |medio/a )?hermano del (c\xF3nyuge|esposa|esposo)": "cu\xF1ado",
1066
- "(medio |media |medio/a )?hermano/hermana del (c\xF3nyuge|esposa|esposo)": "cu\xF1ado/cu\xF1ada"
1122
+ "(medio |media |medio/a )?hermana (del c\xF3nyuge|del esposo|de la esposa)": "cu\xF1ada",
1123
+ "(medio |media |medio/a )?hermano (del c\xF3nyuge|del esposo|de la esposa)": "cu\xF1ado",
1124
+ "(medio |media |medio/a )?hermano/hermana (del c\xF3nyuge|del esposo|de la esposa)": "cu\xF1ado/cu\xF1ada"
1067
1125
  };
1068
1126
 
1069
1127
  // src/kinship-translator/kinship-translator.es.ts
1070
- var KinshipTranslatorEs = class extends KinshipTranslatorBasic {
1071
- directPrefix() {
1072
- const level = Math.abs(this.pathN?.level ?? 0);
1073
- if (level <= 1) {
1074
- return "";
1075
- }
1076
- if (level === 2) {
1077
- return "bisabuel";
1078
- }
1079
- if (level === 3) {
1080
- return "tatarabuel";
1081
- }
1082
- return `t\xE1tara${level - 2}-abuel`;
1128
+ var sexOf2 = (person) => {
1129
+ if (person?.isMale?.()) {
1130
+ return "m";
1083
1131
  }
1132
+ if (person?.isFemale?.()) {
1133
+ return "f";
1134
+ }
1135
+ return "n";
1136
+ };
1137
+ var pick2 = (sex, male, female, neutral) => {
1138
+ if (sex === "m") {
1139
+ return male;
1140
+ }
1141
+ if (sex === "f") {
1142
+ return female;
1143
+ }
1144
+ return neutral;
1145
+ };
1146
+ var SPANISH_ORDINALS_M = [
1147
+ "",
1148
+ "",
1149
+ "segundo",
1150
+ "tercero",
1151
+ "cuarto",
1152
+ "quinto",
1153
+ "sexto",
1154
+ "s\xE9ptimo",
1155
+ "octavo",
1156
+ "noveno",
1157
+ "d\xE9cimo"
1158
+ ];
1159
+ var SPANISH_ORDINALS_F = [
1160
+ "",
1161
+ "",
1162
+ "segunda",
1163
+ "tercera",
1164
+ "cuarta",
1165
+ "quinta",
1166
+ "sexta",
1167
+ "s\xE9ptima",
1168
+ "octava",
1169
+ "novena",
1170
+ "d\xE9cima"
1171
+ ];
1172
+ var spanishOrdinal = (n, sex) => {
1173
+ const list = sex === "f" ? SPANISH_ORDINALS_F : SPANISH_ORDINALS_M;
1174
+ return list[n] ?? `${n}.\xBA`;
1175
+ };
1176
+ var ofSpousePrep2 = (spouseType) => {
1177
+ if (spouseType === "esposa") {
1178
+ return "de la ";
1179
+ }
1180
+ return "del ";
1181
+ };
1182
+ var KinshipTranslatorEs = class extends KinshipTranslatorBasic {
1084
1183
  indirect() {
1085
1184
  let degree = Math.abs(this.pathN?.degree ?? 0);
1086
1185
  if (degree > 0) {
1087
1186
  degree = degree - 1;
1088
1187
  }
1089
- if (degree === 1) {
1090
- return `primo`;
1188
+ const sex = sexOf2(this.personN);
1189
+ const cousin = pick2(sex, "primo", "prima", "primo/prima");
1190
+ if (degree <= 1) {
1191
+ return cousin;
1091
1192
  }
1092
- return `primo ${ordinalize(degree)}`;
1193
+ return `${cousin} ${spanishOrdinal(degree, sex)}`;
1093
1194
  }
1094
1195
  removal() {
1095
1196
  const level = this.pathN?.level ?? 0;
@@ -1100,56 +1201,133 @@ var KinshipTranslatorEs = class extends KinshipTranslatorBasic {
1100
1201
  if (!degree) {
1101
1202
  return level < 0 ? this.nibling() : this.auncle();
1102
1203
  }
1103
- return `primo ${ordinalize(degree)} ${Math.abs(level)}\xD7 separado`;
1204
+ return `${this.indirect()} ${Math.abs(level)}\xD7 separado`;
1104
1205
  }
1105
1206
  auncle() {
1106
- const prefix = this.directPrefix();
1107
- if (this.personN?.isMale()) {
1108
- return `${prefix}t\xEDo`;
1207
+ const level = Math.abs(this.pathN?.level ?? 0);
1208
+ const sex = sexOf2(this.personN);
1209
+ if (level <= 1) {
1210
+ return pick2(sex, "t\xEDo", "t\xEDa", "t\xEDo/t\xEDa");
1109
1211
  }
1110
- if (this.personN?.isFemale()) {
1111
- return `${prefix}t\xEDa`;
1212
+ if (level === 2) {
1213
+ return pick2(sex, "t\xEDo abuelo", "t\xEDa abuela", "t\xEDo/t\xEDa abuelo");
1214
+ }
1215
+ if (level === 3) {
1216
+ return pick2(
1217
+ sex,
1218
+ "t\xEDo bisabuelo",
1219
+ "t\xEDa bisabuela",
1220
+ "t\xEDo/t\xEDa bisabuelo"
1221
+ );
1112
1222
  }
1113
- return `${prefix}t\xEDo/t\xEDa`;
1223
+ return pick2(
1224
+ sex,
1225
+ `t\xEDo abuelo (${level - 1}.\xBA)`,
1226
+ `t\xEDa abuela (${level - 1}.\xAA)`,
1227
+ `t\xEDo/t\xEDa abuelo (${level - 1}.\xBA)`
1228
+ );
1114
1229
  }
1115
1230
  nibling() {
1116
- const prefix = this.directPrefix();
1117
- if (this.personN?.isMale()) {
1118
- return `${prefix}sobrino`;
1231
+ const level = Math.abs(this.pathN?.level ?? 0);
1232
+ const sex = sexOf2(this.personN);
1233
+ if (level <= 1) {
1234
+ return pick2(sex, "sobrino", "sobrina", "sobrino/sobrina");
1119
1235
  }
1120
- if (this.personN?.isFemale()) {
1121
- return `${prefix}sobrina`;
1236
+ if (level === 2) {
1237
+ return pick2(
1238
+ sex,
1239
+ "sobrino nieto",
1240
+ "sobrina nieta",
1241
+ "sobrino/sobrina nieto"
1242
+ );
1243
+ }
1244
+ if (level === 3) {
1245
+ return pick2(
1246
+ sex,
1247
+ "sobrino bisnieto",
1248
+ "sobrina bisnieta",
1249
+ "sobrino/sobrina bisnieto"
1250
+ );
1122
1251
  }
1123
- return `${prefix}sobrino/sobrina`;
1252
+ return pick2(
1253
+ sex,
1254
+ `sobrino nieto (${level - 1}.\xBA)`,
1255
+ `sobrina nieta (${level - 1}.\xAA)`,
1256
+ `sobrino/sobrina nieto (${level - 1}.\xBA)`
1257
+ );
1124
1258
  }
1125
1259
  parent() {
1126
- const prefix = this.directPrefix();
1127
- if (this.personN?.isMale()) {
1128
- return `${prefix}padre`;
1260
+ const level = Math.abs(this.pathN?.level ?? 0);
1261
+ const sex = sexOf2(this.personN);
1262
+ if (level <= 1) {
1263
+ return pick2(sex, "padre", "madre", "padre/madre");
1129
1264
  }
1130
- if (this.personN?.isFemale()) {
1131
- return `${prefix}madre`;
1265
+ if (level === 2) {
1266
+ return pick2(sex, "abuelo", "abuela", "abuelo/abuela");
1132
1267
  }
1133
- return `${prefix}padre/madre`;
1268
+ if (level === 3) {
1269
+ return pick2(sex, "bisabuelo", "bisabuela", "bisabuelo/bisabuela");
1270
+ }
1271
+ if (level === 4) {
1272
+ return pick2(
1273
+ sex,
1274
+ "tatarabuelo",
1275
+ "tatarabuela",
1276
+ "tatarabuelo/tatarabuela"
1277
+ );
1278
+ }
1279
+ if (level === 5) {
1280
+ return pick2(
1281
+ sex,
1282
+ "trastatarabuelo",
1283
+ "trastatarabuela",
1284
+ "trastatarabuelo/trastatarabuela"
1285
+ );
1286
+ }
1287
+ return pick2(
1288
+ sex,
1289
+ `abuelo (${level}.\xBA)`,
1290
+ `abuela (${level}.\xAA)`,
1291
+ `abuelo/abuela (${level}.\xBA)`
1292
+ );
1134
1293
  }
1135
1294
  child() {
1136
- const prefix = this.directPrefix();
1137
- if (this.personN?.isMale()) {
1138
- return `${prefix}hijo`;
1295
+ const level = Math.abs(this.pathN?.level ?? 0);
1296
+ const sex = sexOf2(this.personN);
1297
+ if (level <= 1) {
1298
+ return pick2(sex, "hijo", "hija", "hijo/hija");
1139
1299
  }
1140
- if (this.personN?.isFemale()) {
1141
- return `${prefix}hija`;
1300
+ if (level === 2) {
1301
+ return pick2(sex, "nieto", "nieta", "nieto/nieta");
1142
1302
  }
1143
- return `${prefix}hijo/hija`;
1144
- }
1145
- sibling() {
1146
- if (this.personN?.isMale()) {
1147
- return "hermano";
1303
+ if (level === 3) {
1304
+ return pick2(sex, "bisnieto", "bisnieta", "bisnieto/bisnieta");
1148
1305
  }
1149
- if (this.personN?.isFemale()) {
1150
- return "hermana";
1306
+ if (level === 4) {
1307
+ return pick2(
1308
+ sex,
1309
+ "tataranieto",
1310
+ "tataranieta",
1311
+ "tataranieto/tataranieta"
1312
+ );
1313
+ }
1314
+ if (level === 5) {
1315
+ return pick2(
1316
+ sex,
1317
+ "trastataranieto",
1318
+ "trastataranieta",
1319
+ "trastataranieto/trastataranieta"
1320
+ );
1151
1321
  }
1152
- return "hermano/hermana";
1322
+ return pick2(
1323
+ sex,
1324
+ `nieto (${level}.\xBA)`,
1325
+ `nieta (${level}.\xAA)`,
1326
+ `nieto/nieta (${level}.\xBA)`
1327
+ );
1328
+ }
1329
+ sibling() {
1330
+ return pick2(sexOf2(this.personN), "hermano", "hermana", "hermano/hermana");
1153
1331
  }
1154
1332
  halfBlood(relation) {
1155
1333
  if (!relation || !this.isHalfBlood) {
@@ -1164,40 +1342,30 @@ var KinshipTranslatorEs = class extends KinshipTranslatorBasic {
1164
1342
  return `medio/a ${relation}`;
1165
1343
  }
1166
1344
  spouse() {
1167
- if (this.personN?.isMale()) {
1168
- return "esposo";
1169
- }
1170
- if (this.personN?.isFemale()) {
1171
- return "esposa";
1172
- }
1173
- return "c\xF3nyuge";
1345
+ return pick2(sexOf2(this.personN), "esposo", "esposa", "c\xF3nyuge");
1174
1346
  }
1175
1347
  ofSpouse(relation) {
1176
1348
  if (!relation) {
1177
1349
  return "";
1178
1350
  }
1179
- const spouse = this.path?.[1].indi;
1180
- let spouseType = "c\xF3nyuge";
1181
- if (spouse?.isMale()) {
1182
- spouseType = "esposo";
1183
- }
1184
- if (spouse?.isFemale()) {
1185
- spouseType = "esposa";
1186
- }
1187
- return `${relation} del ${spouseType}`;
1351
+ const spouseType = pick2(
1352
+ sexOf2(this.path?.[1].indi),
1353
+ "esposo",
1354
+ "esposa",
1355
+ "c\xF3nyuge"
1356
+ );
1357
+ return `${relation} ${ofSpousePrep2(spouseType)}${spouseType}`;
1188
1358
  }
1189
1359
  spouseOf(relation) {
1190
1360
  if (!relation) {
1191
1361
  return "";
1192
1362
  }
1193
- const spouse = this.path?.[this.path.length - 1].indi;
1194
- let spouseType = "c\xF3nyuge";
1195
- if (spouse?.isMale()) {
1196
- spouseType = "esposo";
1197
- }
1198
- if (spouse?.isFemale()) {
1199
- spouseType = "esposa";
1200
- }
1363
+ const spouseType = pick2(
1364
+ sexOf2(this.path?.[this.path.length - 1].indi),
1365
+ "esposo",
1366
+ "esposa",
1367
+ "c\xF3nyuge"
1368
+ );
1201
1369
  return `${spouseType} de ${relation}`;
1202
1370
  }
1203
1371
  of(relation) {
@@ -1215,8 +1383,8 @@ var KinshipTranslatorEs = class extends KinshipTranslatorBasic {
1215
1383
  if (!name || !relation) {
1216
1384
  return relation ?? "";
1217
1385
  }
1218
- if (relation.includes(" del ") || relation.includes(" de ")) {
1219
- return relation.replace(/ (del|de) /, ` $1 ${name} `);
1386
+ if (relation.includes(" del ") || relation.includes(" de la ") || relation.includes(" de ")) {
1387
+ return relation.replace(/ (del|de la|de) /, ` $1 ${name} `);
1220
1388
  }
1221
1389
  return `${relation} de ${name}`;
1222
1390
  }
@@ -1246,7 +1414,20 @@ var KinshipTranslatorEs = class extends KinshipTranslatorBasic {
1246
1414
  if (!relation || !this.pathN?.relation) {
1247
1415
  return relation ?? "";
1248
1416
  }
1249
- return `${this.pathN.relation} ${relation}`;
1417
+ const mapped = parentRelationsEs[this.pathN.relation]?.[relation];
1418
+ if (mapped) {
1419
+ return mapped;
1420
+ }
1421
+ if (this.pathN.relation === "step") {
1422
+ return `${relation} pol\xEDtico`;
1423
+ }
1424
+ if (this.pathN.relation === "adopted") {
1425
+ return `${relation} adoptivo`;
1426
+ }
1427
+ if (this.pathN.relation === "foster") {
1428
+ return `${relation} de acogida`;
1429
+ }
1430
+ return relation;
1250
1431
  }
1251
1432
  };
1252
1433
 
@@ -1255,15 +1436,35 @@ var InLawsRu = {
1255
1436
  "\u0441\u0443\u043F\u0440\u0443\u0433(?:\u0430)? (\u0440\u0435\u0431\u0451\u043D\u043A\u0430|\u0434\u043E\u0447\u0435\u0440\u0438|\u0441\u044B\u043D\u0430)": "\u0437\u044F\u0442\u044C/\u043D\u0435\u0432\u0435\u0441\u0442\u043A\u0430",
1256
1437
  "\u0436\u0435\u043D\u0430 (\u0440\u0435\u0431\u0451\u043D\u043A\u0430|\u0434\u043E\u0447\u0435\u0440\u0438|\u0441\u044B\u043D\u0430)": "\u043D\u0435\u0432\u0435\u0441\u0442\u043A\u0430",
1257
1438
  "\u043C\u0443\u0436 (\u0440\u0435\u0431\u0451\u043D\u043A\u0430|\u0434\u043E\u0447\u0435\u0440\u0438|\u0441\u044B\u043D\u0430)": "\u0437\u044F\u0442\u044C",
1258
- "\u043C\u0430\u0442\u044C (\u0441\u0443\u043F\u0440\u0443\u0433\u0430|\u0436\u0435\u043D\u044B|\u043C\u0443\u0436\u0430)": "\u0442\u0451\u0449\u0430",
1259
- "\u043E\u0442\u0435\u0446 (\u0441\u0443\u043F\u0440\u0443\u0433\u0430|\u0436\u0435\u043D\u044B|\u043C\u0443\u0436\u0430)": "\u0442\u0435\u0441\u0442\u044C",
1260
- "\u0440\u043E\u0434\u0438\u0442\u0435\u043B\u044C (\u0441\u0443\u043F\u0440\u0443\u0433\u0430|\u0436\u0435\u043D\u044B|\u043C\u0443\u0436\u0430)": "\u0442\u0435\u0441\u0442\u044C/\u0442\u0451\u0449\u0430",
1439
+ "\u043C\u0430\u0442\u044C \u0436\u0435\u043D\u044B": "\u0442\u0451\u0449\u0430",
1440
+ "\u043C\u0430\u0442\u044C \u043C\u0443\u0436\u0430": "\u0441\u0432\u0435\u043A\u0440\u043E\u0432\u044C",
1441
+ "\u043C\u0430\u0442\u044C \u0441\u0443\u043F\u0440\u0443\u0433\u0430": "\u0442\u0451\u0449\u0430/\u0441\u0432\u0435\u043A\u0440\u043E\u0432\u044C",
1442
+ "\u043E\u0442\u0435\u0446 \u0436\u0435\u043D\u044B": "\u0442\u0435\u0441\u0442\u044C",
1443
+ "\u043E\u0442\u0435\u0446 \u043C\u0443\u0436\u0430": "\u0441\u0432\u0451\u043A\u043E\u0440",
1444
+ "\u043E\u0442\u0435\u0446 \u0441\u0443\u043F\u0440\u0443\u0433\u0430": "\u0442\u0435\u0441\u0442\u044C/\u0441\u0432\u0451\u043A\u043E\u0440",
1445
+ "\u0440\u043E\u0434\u0438\u0442\u0435\u043B\u044C \u0436\u0435\u043D\u044B": "\u0442\u0435\u0441\u0442\u044C/\u0442\u0451\u0449\u0430",
1446
+ "\u0440\u043E\u0434\u0438\u0442\u0435\u043B\u044C \u043C\u0443\u0436\u0430": "\u0441\u0432\u0451\u043A\u043E\u0440/\u0441\u0432\u0435\u043A\u0440\u043E\u0432\u044C",
1447
+ "\u0440\u043E\u0434\u0438\u0442\u0435\u043B\u044C \u0441\u0443\u043F\u0440\u0443\u0433\u0430": "\u0442\u0435\u0441\u0442\u044C/\u0442\u0451\u0449\u0430",
1261
1448
  "\u0436\u0435\u043D\u0430 (\u0441\u0432\u043E\u0434\u043D(?:\u044B\u0439|\u0430\u044F) )?(\u0431\u0440\u0430\u0442\u0430|\u0441\u0435\u0441\u0442\u0440\u044B|\u0441\u0438\u0431\u043B\u0438\u043D\u0433\u0430)": "\u043D\u0435\u0432\u0435\u0441\u0442\u043A\u0430",
1262
1449
  "\u043C\u0443\u0436 (\u0441\u0432\u043E\u0434\u043D(?:\u044B\u0439|\u0430\u044F) )?(\u0431\u0440\u0430\u0442\u0430|\u0441\u0435\u0441\u0442\u0440\u044B|\u0441\u0438\u0431\u043B\u0438\u043D\u0433\u0430)": "\u0437\u044F\u0442\u044C",
1263
1450
  "\u0441\u0443\u043F\u0440\u0443\u0433(?:\u0430)? (\u0441\u0432\u043E\u0434\u043D(?:\u044B\u0439|\u0430\u044F) )?(\u0431\u0440\u0430\u0442\u0430|\u0441\u0435\u0441\u0442\u0440\u044B|\u0441\u0438\u0431\u043B\u0438\u043D\u0433\u0430)": "\u0437\u044F\u0442\u044C/\u043D\u0435\u0432\u0435\u0441\u0442\u043A\u0430",
1264
- "(\u0441\u0432\u043E\u0434\u043D(?:\u044B\u0439|\u0430\u044F) )?\u0441\u0435\u0441\u0442\u0440\u0430 (\u0441\u0443\u043F\u0440\u0443\u0433\u0430|\u0436\u0435\u043D\u044B|\u043C\u0443\u0436\u0430)": "\u0437\u043E\u043B\u043E\u0432\u043A\u0430",
1265
- "(\u0441\u0432\u043E\u0434\u043D(?:\u044B\u0439|\u0430\u044F) )?\u0431\u0440\u0430\u0442 (\u0441\u0443\u043F\u0440\u0443\u0433\u0430|\u0436\u0435\u043D\u044B|\u043C\u0443\u0436\u0430)": "\u0448\u0443\u0440\u0438\u043D",
1266
- "(\u0441\u0432\u043E\u0434\u043D(?:\u044B\u0439|\u0430\u044F) )?\u0441\u0438\u0431\u043B\u0438\u043D\u0433 (\u0441\u0443\u043F\u0440\u0443\u0433\u0430|\u0436\u0435\u043D\u044B|\u043C\u0443\u0436\u0430)": "\u0448\u0443\u0440\u0438\u043D/\u0437\u043E\u043B\u043E\u0432\u043A\u0430"
1451
+ "(\u0441\u0432\u043E\u0434\u043D(?:\u044B\u0439|\u0430\u044F) )?\u0441\u0435\u0441\u0442\u0440\u0430 \u0436\u0435\u043D\u044B": "\u0441\u0432\u043E\u044F\u0447\u0435\u043D\u0438\u0446\u0430",
1452
+ "(\u0441\u0432\u043E\u0434\u043D(?:\u044B\u0439|\u0430\u044F) )?\u0441\u0435\u0441\u0442\u0440\u0430 \u043C\u0443\u0436\u0430": "\u0437\u043E\u043B\u043E\u0432\u043A\u0430",
1453
+ "(\u0441\u0432\u043E\u0434\u043D(?:\u044B\u0439|\u0430\u044F) )?\u0441\u0435\u0441\u0442\u0440\u0430 \u0441\u0443\u043F\u0440\u0443\u0433\u0430": "\u0441\u0432\u043E\u044F\u0447\u0435\u043D\u0438\u0446\u0430/\u0437\u043E\u043B\u043E\u0432\u043A\u0430",
1454
+ "(\u0441\u0432\u043E\u0434\u043D(?:\u044B\u0439|\u0430\u044F) )?\u0431\u0440\u0430\u0442 \u0436\u0435\u043D\u044B": "\u0448\u0443\u0440\u0438\u043D",
1455
+ "(\u0441\u0432\u043E\u0434\u043D(?:\u044B\u0439|\u0430\u044F) )?\u0431\u0440\u0430\u0442 \u043C\u0443\u0436\u0430": "\u0434\u0435\u0432\u0435\u0440\u044C",
1456
+ "(\u0441\u0432\u043E\u0434\u043D(?:\u044B\u0439|\u0430\u044F) )?\u0431\u0440\u0430\u0442 \u0441\u0443\u043F\u0440\u0443\u0433\u0430": "\u0448\u0443\u0440\u0438\u043D/\u0434\u0435\u0432\u0435\u0440\u044C",
1457
+ "(\u0441\u0432\u043E\u0434\u043D(?:\u044B\u0439|\u0430\u044F) )?\u0441\u0438\u0431\u043B\u0438\u043D\u0433 \u0436\u0435\u043D\u044B": "\u0448\u0443\u0440\u0438\u043D/\u0441\u0432\u043E\u044F\u0447\u0435\u043D\u0438\u0446\u0430",
1458
+ "(\u0441\u0432\u043E\u0434\u043D(?:\u044B\u0439|\u0430\u044F) )?\u0441\u0438\u0431\u043B\u0438\u043D\u0433 \u043C\u0443\u0436\u0430": "\u0434\u0435\u0432\u0435\u0440\u044C/\u0437\u043E\u043B\u043E\u0432\u043A\u0430",
1459
+ "(\u0441\u0432\u043E\u0434\u043D(?:\u044B\u0439|\u0430\u044F) )?\u0441\u0438\u0431\u043B\u0438\u043D\u0433 \u0441\u0443\u043F\u0440\u0443\u0433\u0430": "\u0448\u0443\u0440\u0438\u043D/\u0437\u043E\u043B\u043E\u0432\u043A\u0430"
1460
+ };
1461
+ var parentRelationsRu = {
1462
+ step: {
1463
+ \u043E\u0442\u0435\u0446: "\u043E\u0442\u0447\u0438\u043C",
1464
+ \u043C\u0430\u0442\u044C: "\u043C\u0430\u0447\u0435\u0445\u0430",
1465
+ \u0441\u044B\u043D: "\u043F\u0430\u0441\u044B\u043D\u043E\u043A",
1466
+ \u0434\u043E\u0447\u044C: "\u043F\u0430\u0434\u0447\u0435\u0440\u0438\u0446\u0430"
1467
+ }
1267
1468
  };
1268
1469
 
1269
1470
  // src/kinship-translator/kinship-translator.ru.ts
@@ -1294,7 +1495,7 @@ var cousinWord = (degree, sex) => {
1294
1495
  return `${stem}\u044B\u0439 \u0431\u0440\u0430\u0442/\u0441\u0435\u0441\u0442\u0440\u0430`;
1295
1496
  };
1296
1497
  var praRepeat = (count) => count > 0 ? "\u043F\u0440\u0430".repeat(count) : "";
1297
- var sexOf = (person) => {
1498
+ var sexOf3 = (person) => {
1298
1499
  if (person?.isMale?.()) {
1299
1500
  return "m";
1300
1501
  }
@@ -1309,7 +1510,7 @@ var KinshipTranslatorRu = class extends KinshipTranslatorBasic {
1309
1510
  if (degree > 0) {
1310
1511
  degree = degree - 1;
1311
1512
  }
1312
- return cousinWord(degree, sexOf(this.personN));
1513
+ return cousinWord(degree, sexOf3(this.personN));
1313
1514
  }
1314
1515
  removal() {
1315
1516
  const level = this.pathN?.level ?? 0;
@@ -1321,35 +1522,53 @@ var KinshipTranslatorRu = class extends KinshipTranslatorBasic {
1321
1522
  return level < 0 ? this.nibling() : this.auncle();
1322
1523
  }
1323
1524
  const removed = Math.abs(level);
1324
- return `${cousinWord(degree, sexOf(this.personN))} (${removed}\xD7 \u0447\u0435\u0440\u0435\u0437 \u043F\u043E\u043A\u043E\u043B\u0435\u043D\u0438\u0435)`;
1525
+ return `${cousinWord(degree, sexOf3(this.personN))} (${removed}\xD7 \u0447\u0435\u0440\u0435\u0437 \u043F\u043E\u043A\u043E\u043B\u0435\u043D\u0438\u0435)`;
1325
1526
  }
1326
1527
  auncle() {
1327
1528
  const level = Math.abs(this.pathN?.level ?? 0);
1328
- const pra = praRepeat(Math.max(0, level - 2));
1329
- const sex = sexOf(this.personN);
1529
+ const sex = sexOf3(this.personN);
1530
+ if (level <= 1) {
1531
+ if (sex === "m") {
1532
+ return "\u0434\u044F\u0434\u044F";
1533
+ }
1534
+ if (sex === "f") {
1535
+ return "\u0442\u0451\u0442\u044F";
1536
+ }
1537
+ return "\u0434\u044F\u0434\u044F/\u0442\u0451\u0442\u044F";
1538
+ }
1539
+ const pra = praRepeat(level - 2);
1330
1540
  if (sex === "m") {
1331
- return `${pra}\u0434\u044F\u0434\u044F`;
1541
+ return `\u0434\u0432\u043E\u044E\u0440\u043E\u0434\u043D\u044B\u0439 ${pra}\u0434\u0435\u0434`;
1332
1542
  }
1333
1543
  if (sex === "f") {
1334
- return `${pra}\u0442\u0451\u0442\u044F`;
1544
+ return `\u0434\u0432\u043E\u044E\u0440\u043E\u0434\u043D\u0430\u044F ${pra}\u0431\u0430\u0431\u0443\u0448\u043A\u0430`;
1335
1545
  }
1336
- return `${pra}\u0434\u044F\u0434\u044F/\u0442\u0451\u0442\u044F`;
1546
+ return `\u0434\u0432\u043E\u044E\u0440\u043E\u0434\u043D\u044B\u0439 ${pra}\u0434\u0435\u0434/\u0431\u0430\u0431\u0443\u0448\u043A\u0430`;
1337
1547
  }
1338
1548
  nibling() {
1339
1549
  const level = Math.abs(this.pathN?.level ?? 0);
1340
- const pra = praRepeat(Math.max(0, level - 2));
1341
- const sex = sexOf(this.personN);
1550
+ const sex = sexOf3(this.personN);
1551
+ if (level <= 1) {
1552
+ if (sex === "m") {
1553
+ return "\u043F\u043B\u0435\u043C\u044F\u043D\u043D\u0438\u043A";
1554
+ }
1555
+ if (sex === "f") {
1556
+ return "\u043F\u043B\u0435\u043C\u044F\u043D\u043D\u0438\u0446\u0430";
1557
+ }
1558
+ return "\u043F\u043B\u0435\u043C\u044F\u043D\u043D\u0438\u043A/\u043F\u043B\u0435\u043C\u044F\u043D\u043D\u0438\u0446\u0430";
1559
+ }
1560
+ const pra = praRepeat(level - 2);
1342
1561
  if (sex === "m") {
1343
- return `${pra}\u043F\u043B\u0435\u043C\u044F\u043D\u043D\u0438\u043A`;
1562
+ return `${pra}\u0432\u043D\u0443\u0447\u0430\u0442\u044B\u0439 \u043F\u043B\u0435\u043C\u044F\u043D\u043D\u0438\u043A`;
1344
1563
  }
1345
1564
  if (sex === "f") {
1346
- return `${pra}\u043F\u043B\u0435\u043C\u044F\u043D\u043D\u0438\u0446\u0430`;
1565
+ return `${pra}\u0432\u043D\u0443\u0447\u0430\u0442\u0430\u044F \u043F\u043B\u0435\u043C\u044F\u043D\u043D\u0438\u0446\u0430`;
1347
1566
  }
1348
- return `${pra}\u043F\u043B\u0435\u043C\u044F\u043D\u043D\u0438\u043A/\u043F\u043B\u0435\u043C\u044F\u043D\u043D\u0438\u0446\u0430`;
1567
+ return `${pra}\u0432\u043D\u0443\u0447\u0430\u0442\u044B\u0439 \u043F\u043B\u0435\u043C\u044F\u043D\u043D\u0438\u043A/\u043F\u043B\u0435\u043C\u044F\u043D\u043D\u0438\u0446\u0430`;
1349
1568
  }
1350
1569
  parent() {
1351
1570
  const level = Math.abs(this.pathN?.level ?? 0);
1352
- const sex = sexOf(this.personN);
1571
+ const sex = sexOf3(this.personN);
1353
1572
  if (level <= 1) {
1354
1573
  if (sex === "m") {
1355
1574
  return "\u043E\u0442\u0435\u0446";
@@ -1379,7 +1598,7 @@ var KinshipTranslatorRu = class extends KinshipTranslatorBasic {
1379
1598
  }
1380
1599
  child() {
1381
1600
  const level = Math.abs(this.pathN?.level ?? 0);
1382
- const sex = sexOf(this.personN);
1601
+ const sex = sexOf3(this.personN);
1383
1602
  if (level <= 1) {
1384
1603
  if (sex === "m") {
1385
1604
  return "\u0441\u044B\u043D";
@@ -1408,14 +1627,14 @@ var KinshipTranslatorRu = class extends KinshipTranslatorBasic {
1408
1627
  return `${pra}\u0432\u043D\u0443\u043A/\u0432\u043D\u0443\u0447\u043A\u0430`;
1409
1628
  }
1410
1629
  sibling() {
1411
- const sex = sexOf(this.personN);
1630
+ const sex = sexOf3(this.personN);
1412
1631
  if (sex === "m") {
1413
1632
  return "\u0431\u0440\u0430\u0442";
1414
1633
  }
1415
1634
  if (sex === "f") {
1416
1635
  return "\u0441\u0435\u0441\u0442\u0440\u0430";
1417
1636
  }
1418
- return "\u0441\u0438\u0431\u043B\u0438\u043D\u0433";
1637
+ return "\u0431\u0440\u0430\u0442/\u0441\u0435\u0441\u0442\u0440\u0430";
1419
1638
  }
1420
1639
  halfBlood(relation) {
1421
1640
  if (!relation || !this.isHalfBlood) {
@@ -1429,7 +1648,7 @@ var KinshipTranslatorRu = class extends KinshipTranslatorBasic {
1429
1648
  return `\u0441\u0432\u043E\u0434\u043D\u044B\u0439 ${relation}`;
1430
1649
  }
1431
1650
  spouse() {
1432
- const sex = sexOf(this.personN);
1651
+ const sex = sexOf3(this.personN);
1433
1652
  if (sex === "m") {
1434
1653
  return "\u043C\u0443\u0436";
1435
1654
  }
@@ -1443,7 +1662,7 @@ var KinshipTranslatorRu = class extends KinshipTranslatorBasic {
1443
1662
  return "";
1444
1663
  }
1445
1664
  const spouse = this.path?.[1].indi;
1446
- const sex = sexOf(spouse);
1665
+ const sex = sexOf3(spouse);
1447
1666
  const spouseType = sex === "m" ? "\u043C\u0443\u0436" : sex === "f" ? "\u0436\u0435\u043D\u0430" : "\u0441\u0443\u043F\u0440\u0443\u0433";
1448
1667
  return `${relation} ${toGenitive(spouseType)}`;
1449
1668
  }
@@ -1452,7 +1671,7 @@ var KinshipTranslatorRu = class extends KinshipTranslatorBasic {
1452
1671
  return "";
1453
1672
  }
1454
1673
  const spouse = this.path?.[this.path.length - 1].indi;
1455
- const sex = sexOf(spouse);
1674
+ const sex = sexOf3(spouse);
1456
1675
  const spouseType = sex === "m" ? "\u043C\u0443\u0436" : sex === "f" ? "\u0436\u0435\u043D\u0430" : "\u0441\u0443\u043F\u0440\u0443\u0433";
1457
1676
  return `${spouseType} ${toGenitive(relation)}`;
1458
1677
  }
@@ -1489,7 +1708,22 @@ var KinshipTranslatorRu = class extends KinshipTranslatorBasic {
1489
1708
  if (!relation || !this.pathN?.relation) {
1490
1709
  return relation ?? "";
1491
1710
  }
1492
- return `${this.pathN.relation} ${relation}`;
1711
+ const mapped = parentRelationsRu[this.pathN.relation]?.[relation];
1712
+ if (mapped) {
1713
+ return mapped;
1714
+ }
1715
+ if (this.pathN.relation === "step") {
1716
+ return `\u043D\u0435\u0440\u043E\u0434\u043D\u043E\u0439 ${relation}`;
1717
+ }
1718
+ if (this.pathN.relation === "adopted") {
1719
+ return /сестра|дочь|мать|тётя|бабушка|жена|племянница|внучка/.test(
1720
+ relation
1721
+ ) ? `\u043F\u0440\u0438\u0451\u043C\u043D\u0430\u044F ${relation}` : `\u043F\u0440\u0438\u0451\u043C\u043D\u044B\u0439 ${relation}`;
1722
+ }
1723
+ if (this.pathN.relation === "foster") {
1724
+ return `\u043F\u0440\u0438\u0451\u043C\u043D\u044B\u0439 ${relation}`;
1725
+ }
1726
+ return relation;
1493
1727
  }
1494
1728
  };
1495
1729
 
@@ -1513,7 +1747,7 @@ var InLawsJa = {
1513
1747
  };
1514
1748
 
1515
1749
  // src/kinship-translator/kinship-translator.ja.ts
1516
- var sexOf2 = (person) => {
1750
+ var sexOf4 = (person) => {
1517
1751
  if (person?.isMale?.()) {
1518
1752
  return "m";
1519
1753
  }
@@ -1522,7 +1756,7 @@ var sexOf2 = (person) => {
1522
1756
  }
1523
1757
  return "n";
1524
1758
  };
1525
- var pick = (sex, male, female, neutral) => {
1759
+ var pick3 = (sex, male, female, neutral) => {
1526
1760
  if (sex === "m") {
1527
1761
  return male;
1528
1762
  }
@@ -1535,18 +1769,18 @@ var lineal = (level, sex, kind) => {
1535
1769
  const L = Math.max(1, level);
1536
1770
  if (kind === "asc") {
1537
1771
  if (L <= 1) {
1538
- return pick(sex, "\u7236", "\u6BCD", "\u89AA");
1772
+ return pick3(sex, "\u7236", "\u6BCD", "\u89AA");
1539
1773
  }
1540
1774
  if (L === 2) {
1541
- return pick(sex, "\u7956\u7236", "\u7956\u6BCD", "\u7956\u7236\u6BCD");
1775
+ return pick3(sex, "\u7956\u7236", "\u7956\u6BCD", "\u7956\u7236\u6BCD");
1542
1776
  }
1543
1777
  if (L === 3) {
1544
- return pick(sex, "\u66FE\u7956\u7236", "\u66FE\u7956\u6BCD", "\u66FE\u7956\u7236\u6BCD");
1778
+ return pick3(sex, "\u66FE\u7956\u7236", "\u66FE\u7956\u6BCD", "\u66FE\u7956\u7236\u6BCD");
1545
1779
  }
1546
1780
  if (L === 4) {
1547
- return pick(sex, "\u9AD8\u7956\u7236", "\u9AD8\u7956\u6BCD", "\u9AD8\u7956\u7236\u6BCD");
1781
+ return pick3(sex, "\u9AD8\u7956\u7236", "\u9AD8\u7956\u6BCD", "\u9AD8\u7956\u7236\u6BCD");
1548
1782
  }
1549
- return pick(
1783
+ return pick3(
1550
1784
  sex,
1551
1785
  `${L - 1}\u4E16\u306E\u7956\u7236`,
1552
1786
  `${L - 1}\u4E16\u306E\u7956\u6BCD`,
@@ -1554,7 +1788,7 @@ var lineal = (level, sex, kind) => {
1554
1788
  );
1555
1789
  }
1556
1790
  if (L <= 1) {
1557
- return pick(sex, "\u606F\u5B50", "\u5A18", "\u5B50");
1791
+ return pick3(sex, "\u606F\u5B50", "\u5A18", "\u5B50");
1558
1792
  }
1559
1793
  if (L === 2) {
1560
1794
  return "\u5B6B";
@@ -1601,52 +1835,52 @@ var KinshipTranslatorJa = class extends KinshipTranslatorBasic {
1601
1835
  }
1602
1836
  auncle() {
1603
1837
  const level = Math.abs(this.pathN?.level ?? 0);
1604
- const sex = sexOf2(this.personN);
1605
- if (level <= 2) {
1606
- return pick(sex, "\u304A\u3058", "\u304A\u3070", "\u304A\u3058/\u304A\u3070");
1838
+ const sex = sexOf4(this.personN);
1839
+ if (level <= 1) {
1840
+ return pick3(sex, "\u304A\u3058", "\u304A\u3070", "\u304A\u3058/\u304A\u3070");
1607
1841
  }
1608
- if (level === 3) {
1609
- return pick(sex, "\u5927\u304A\u3058", "\u5927\u304A\u3070", "\u5927\u304A\u3058/\u5927\u304A\u3070");
1842
+ if (level === 2) {
1843
+ return pick3(sex, "\u5927\u304A\u3058", "\u5927\u304A\u3070", "\u5927\u304A\u3058/\u5927\u304A\u3070");
1610
1844
  }
1611
- return pick(
1845
+ return pick3(
1612
1846
  sex,
1613
- `${level - 2}\u4EE3\u524D\u306E\u304A\u3058`,
1614
- `${level - 2}\u4EE3\u524D\u306E\u304A\u3070`,
1615
- `${level - 2}\u4EE3\u524D\u306E\u304A\u3058/\u304A\u3070`
1847
+ `${level - 1}\u4EE3\u524D\u306E\u304A\u3058`,
1848
+ `${level - 1}\u4EE3\u524D\u306E\u304A\u3070`,
1849
+ `${level - 1}\u4EE3\u524D\u306E\u304A\u3058/\u304A\u3070`
1616
1850
  );
1617
1851
  }
1618
1852
  nibling() {
1619
1853
  const level = Math.abs(this.pathN?.level ?? 0);
1620
- const sex = sexOf2(this.personN);
1621
- if (level <= 2) {
1622
- return pick(sex, "\u7525", "\u59EA", "\u7525/\u59EA");
1854
+ const sex = sexOf4(this.personN);
1855
+ if (level <= 1) {
1856
+ return pick3(sex, "\u7525", "\u59EA", "\u7525/\u59EA");
1623
1857
  }
1624
- if (level === 3) {
1625
- return pick(sex, "\u5927\u7525", "\u5927\u59EA", "\u5927\u7525/\u5927\u59EA");
1858
+ if (level === 2) {
1859
+ return pick3(sex, "\u5927\u7525", "\u5927\u59EA", "\u5927\u7525/\u5927\u59EA");
1626
1860
  }
1627
- return pick(
1861
+ return pick3(
1628
1862
  sex,
1629
- `${level - 2}\u4EE3\u4E0B\u306E\u7525`,
1630
- `${level - 2}\u4EE3\u4E0B\u306E\u59EA`,
1631
- `${level - 2}\u4EE3\u4E0B\u306E\u7525/\u59EA`
1863
+ `${level - 1}\u4EE3\u4E0B\u306E\u7525`,
1864
+ `${level - 1}\u4EE3\u4E0B\u306E\u59EA`,
1865
+ `${level - 1}\u4EE3\u4E0B\u306E\u7525/\u59EA`
1632
1866
  );
1633
1867
  }
1634
1868
  parent() {
1635
1869
  return lineal(
1636
1870
  Math.abs(this.pathN?.level ?? 0),
1637
- sexOf2(this.personN),
1871
+ sexOf4(this.personN),
1638
1872
  "asc"
1639
1873
  );
1640
1874
  }
1641
1875
  child() {
1642
1876
  return lineal(
1643
1877
  Math.abs(this.pathN?.level ?? 0),
1644
- sexOf2(this.personN),
1878
+ sexOf4(this.personN),
1645
1879
  "desc"
1646
1880
  );
1647
1881
  }
1648
1882
  sibling() {
1649
- return pick(sexOf2(this.personN), "\u5144\u5F1F", "\u59C9\u59B9", "\u5144\u5F1F\u59C9\u59B9");
1883
+ return pick3(sexOf4(this.personN), "\u5144\u5F1F", "\u59C9\u59B9", "\u5144\u5F1F\u59C9\u59B9");
1650
1884
  }
1651
1885
  halfBlood(relation) {
1652
1886
  if (!relation || !this.isHalfBlood) {
@@ -1655,14 +1889,14 @@ var KinshipTranslatorJa = class extends KinshipTranslatorBasic {
1655
1889
  return `\u7570\u7236\u6BCD\u306E${relation}`;
1656
1890
  }
1657
1891
  spouse() {
1658
- return pick(sexOf2(this.personN), "\u592B", "\u59BB", "\u914D\u5076\u8005");
1892
+ return pick3(sexOf4(this.personN), "\u592B", "\u59BB", "\u914D\u5076\u8005");
1659
1893
  }
1660
1894
  ofSpouse(relation) {
1661
1895
  if (!relation) {
1662
1896
  return "";
1663
1897
  }
1664
- const spouseType = pick(
1665
- sexOf2(this.path?.[1].indi),
1898
+ const spouseType = pick3(
1899
+ sexOf4(this.path?.[1].indi),
1666
1900
  "\u592B",
1667
1901
  "\u59BB",
1668
1902
  "\u914D\u5076\u8005"
@@ -1674,7 +1908,7 @@ var KinshipTranslatorJa = class extends KinshipTranslatorBasic {
1674
1908
  return "";
1675
1909
  }
1676
1910
  const spouse = this.path?.[this.path.length - 1].indi;
1677
- const spouseType = pick(sexOf2(spouse), "\u592B", "\u59BB", "\u914D\u5076\u8005");
1911
+ const spouseType = pick3(sexOf4(spouse), "\u592B", "\u59BB", "\u914D\u5076\u8005");
1678
1912
  return `${relation}\u306E${spouseType}`;
1679
1913
  }
1680
1914
  of(relation) {
@@ -1710,7 +1944,28 @@ var KinshipTranslatorJa = class extends KinshipTranslatorBasic {
1710
1944
  if (!relation || !this.pathN?.relation) {
1711
1945
  return relation ?? "";
1712
1946
  }
1713
- return `${this.pathN.relation}\u306E${relation}`;
1947
+ if (this.pathN.relation === "step") {
1948
+ if (relation === "\u7236") {
1949
+ return "\u7EE7\u7236";
1950
+ }
1951
+ if (relation === "\u6BCD") {
1952
+ return "\u7D99\u6BCD";
1953
+ }
1954
+ if (relation === "\u606F\u5B50") {
1955
+ return "\u7D99\u5B50";
1956
+ }
1957
+ if (relation === "\u5A18") {
1958
+ return "\u7D99\u5A18";
1959
+ }
1960
+ return `\u7D99${relation}`;
1961
+ }
1962
+ if (this.pathN.relation === "adopted") {
1963
+ return `\u990A\u5B50\u306E${relation}`;
1964
+ }
1965
+ if (this.pathN.relation === "foster") {
1966
+ return `\u91CC\u89AA\u306E${relation}`;
1967
+ }
1968
+ return relation;
1714
1969
  }
1715
1970
  };
1716
1971
 
@@ -1719,22 +1974,32 @@ var InLawsZh = {
1719
1974
  "(\u5B50\u5973|\u5973\u513F|\u513F\u5B50)\u7684\u914D\u5076": "\u513F\u5AB3/\u5973\u5A7F",
1720
1975
  "(\u5B50\u5973|\u5973\u513F|\u513F\u5B50)\u7684\u59BB\u5B50": "\u513F\u5AB3",
1721
1976
  "(\u5B50\u5973|\u5973\u513F|\u513F\u5B50)\u7684\u4E08\u592B": "\u5973\u5A7F",
1722
- "(\u914D\u5076|\u59BB\u5B50|\u4E08\u592B)\u7684\u6BCD\u4EB2": "\u5CB3\u6BCD/\u5A46\u5A46",
1723
- "(\u914D\u5076|\u59BB\u5B50|\u4E08\u592B)\u7684\u7236\u4EB2": "\u5CB3\u7236/\u516C\u516C",
1724
- "(\u914D\u5076|\u59BB\u5B50|\u4E08\u592B)\u7684\u7236\u6BCD": "\u5CB3\u7236\u5CB3\u6BCD/\u516C\u516C\u5A46\u5A46",
1977
+ "\u59BB\u5B50\u7684\u6BCD\u4EB2": "\u5CB3\u6BCD",
1978
+ "\u4E08\u592B\u7684\u6BCD\u4EB2": "\u5A46\u5A46",
1979
+ "(\u914D\u5076)\u7684\u6BCD\u4EB2": "\u5CB3\u6BCD/\u5A46\u5A46",
1980
+ "\u59BB\u5B50\u7684\u7236\u4EB2": "\u5CB3\u7236",
1981
+ "\u4E08\u592B\u7684\u7236\u4EB2": "\u516C\u516C",
1982
+ "(\u914D\u5076)\u7684\u7236\u4EB2": "\u5CB3\u7236/\u516C\u516C",
1983
+ "\u59BB\u5B50\u7684\u7236\u6BCD": "\u5CB3\u7236\u5CB3\u6BCD",
1984
+ "\u4E08\u592B\u7684\u7236\u6BCD": "\u516C\u516C\u5A46\u5A46",
1985
+ "(\u914D\u5076)\u7684\u7236\u6BCD": "\u5CB3\u7236\u5CB3\u6BCD/\u516C\u516C\u5A46\u5A46",
1725
1986
  "(\u5F02\u7236\u6BCD\u7684)?(\u5144\u5F1F\u59D0\u59B9|\u59D0\u59B9|\u5144\u5F1F)\u7684\u59BB\u5B50": "\u5AC2\u5B50/\u5F1F\u59B9",
1726
1987
  "(\u5F02\u7236\u6BCD\u7684)?(\u5144\u5F1F\u59D0\u59B9|\u59D0\u59B9|\u5144\u5F1F)\u7684\u4E08\u592B": "\u59D0\u592B/\u59B9\u592B",
1727
1988
  "(\u5F02\u7236\u6BCD\u7684)?(\u5144\u5F1F\u59D0\u59B9|\u59D0\u59B9|\u5144\u5F1F)\u7684\u914D\u5076": "\u59FB\u4EB2\u5144\u5F1F\u59D0\u59B9",
1728
1989
  "(\u5F02\u7236\u6BCD\u7684)?\u59D0\u59B9\u7684(\u914D\u5076|\u59BB\u5B50|\u4E08\u592B)": "\u59D0\u592B/\u59B9\u592B",
1729
1990
  "(\u5F02\u7236\u6BCD\u7684)?\u5144\u5F1F\u7684(\u914D\u5076|\u59BB\u5B50|\u4E08\u592B)": "\u5AC2\u5B50/\u5F1F\u59B9",
1730
1991
  "(\u5F02\u7236\u6BCD\u7684)?\u5144\u5F1F\u59D0\u59B9\u7684(\u914D\u5076|\u59BB\u5B50|\u4E08\u592B)": "\u59FB\u4EB2\u5144\u5F1F\u59D0\u59B9",
1731
- "(\u5F02\u7236\u6BCD\u7684)?(\u914D\u5076|\u59BB\u5B50|\u4E08\u592B)\u7684\u59D0\u59B9": "\u59D1\u5B50/\u59E8\u5B50",
1732
- "(\u5F02\u7236\u6BCD\u7684)?(\u914D\u5076|\u59BB\u5B50|\u4E08\u592B)\u7684\u5144\u5F1F": "\u5927\u4F2F/\u5C0F\u53D4/\u5185\u5144/\u5185\u5F1F",
1992
+ "(\u5F02\u7236\u6BCD\u7684)?\u59BB\u5B50\u7684\u59D0\u59B9": "\u59E8\u5B50",
1993
+ "(\u5F02\u7236\u6BCD\u7684)?\u4E08\u592B\u7684\u59D0\u59B9": "\u59D1\u5B50",
1994
+ "(\u5F02\u7236\u6BCD\u7684)?(\u914D\u5076)\u7684\u59D0\u59B9": "\u59D1\u5B50/\u59E8\u5B50",
1995
+ "(\u5F02\u7236\u6BCD\u7684)?\u59BB\u5B50\u7684\u5144\u5F1F": "\u5185\u5144/\u5185\u5F1F",
1996
+ "(\u5F02\u7236\u6BCD\u7684)?\u4E08\u592B\u7684\u5144\u5F1F": "\u5927\u4F2F/\u5C0F\u53D4",
1997
+ "(\u5F02\u7236\u6BCD\u7684)?(\u914D\u5076)\u7684\u5144\u5F1F": "\u5927\u4F2F/\u5C0F\u53D4/\u5185\u5144/\u5185\u5F1F",
1733
1998
  "(\u5F02\u7236\u6BCD\u7684)?(\u914D\u5076|\u59BB\u5B50|\u4E08\u592B)\u7684\u5144\u5F1F\u59D0\u59B9": "\u59FB\u4EB2\u5144\u5F1F\u59D0\u59B9"
1734
1999
  };
1735
2000
 
1736
2001
  // src/kinship-translator/kinship-translator.zh.ts
1737
- var sexOf3 = (person) => {
2002
+ var sexOf5 = (person) => {
1738
2003
  if (person?.isMale?.()) {
1739
2004
  return "m";
1740
2005
  }
@@ -1743,7 +2008,7 @@ var sexOf3 = (person) => {
1743
2008
  }
1744
2009
  return "n";
1745
2010
  };
1746
- var pick2 = (sex, male, female, neutral) => {
2011
+ var pick4 = (sex, male, female, neutral) => {
1747
2012
  if (sex === "m") {
1748
2013
  return male;
1749
2014
  }
@@ -1756,41 +2021,41 @@ var lineal2 = (level, sex, kind) => {
1756
2021
  const L = Math.max(1, level);
1757
2022
  if (kind === "asc") {
1758
2023
  if (L <= 1) {
1759
- return pick2(sex, "\u7236\u4EB2", "\u6BCD\u4EB2", "\u7236\u6BCD");
2024
+ return pick4(sex, "\u7236\u4EB2", "\u6BCD\u4EB2", "\u7236\u6BCD");
1760
2025
  }
1761
2026
  if (L === 2) {
1762
- return pick2(sex, "\u7956\u7236", "\u7956\u6BCD", "\u7956\u7236\u6BCD");
2027
+ return pick4(sex, "\u7956\u7236", "\u7956\u6BCD", "\u7956\u7236\u6BCD");
1763
2028
  }
1764
2029
  if (L === 3) {
1765
- return pick2(sex, "\u66FE\u7956\u7236", "\u66FE\u7956\u6BCD", "\u66FE\u7956\u7236\u6BCD");
2030
+ return pick4(sex, "\u66FE\u7956\u7236", "\u66FE\u7956\u6BCD", "\u66FE\u7956\u7236\u6BCD");
1766
2031
  }
1767
2032
  if (L === 4) {
1768
- return pick2(sex, "\u9AD8\u7956\u7236", "\u9AD8\u7956\u6BCD", "\u9AD8\u7956\u7236\u6BCD");
2033
+ return pick4(sex, "\u9AD8\u7956\u7236", "\u9AD8\u7956\u6BCD", "\u9AD8\u7956\u7236\u6BCD");
1769
2034
  }
1770
- return pick2(sex, `${L}\u4E16\u7956`, `${L}\u4E16\u7956\u6BCD`, `${L}\u4E16\u7956\u7236\u6BCD`);
2035
+ return pick4(sex, `${L}\u4E16\u7956`, `${L}\u4E16\u7956\u6BCD`, `${L}\u4E16\u7956\u7236\u6BCD`);
1771
2036
  }
1772
2037
  if (L <= 1) {
1773
- return pick2(sex, "\u513F\u5B50", "\u5973\u513F", "\u5B50\u5973");
2038
+ return pick4(sex, "\u513F\u5B50", "\u5973\u513F", "\u5B50\u5973");
1774
2039
  }
1775
2040
  if (L === 2) {
1776
- return pick2(sex, "\u5B59\u5B50", "\u5B59\u5973", "\u5B59\u5B50\u5973");
2041
+ return pick4(sex, "\u5B59\u5B50", "\u5B59\u5973", "\u5B59\u5B50\u5973");
1777
2042
  }
1778
2043
  if (L === 3) {
1779
- return pick2(sex, "\u66FE\u5B59", "\u66FE\u5B59\u5973", "\u66FE\u5B59\u5B50\u5973");
2044
+ return pick4(sex, "\u66FE\u5B59", "\u66FE\u5B59\u5973", "\u66FE\u5B59\u5B50\u5973");
1780
2045
  }
1781
2046
  if (L === 4) {
1782
- return pick2(sex, "\u7384\u5B59", "\u7384\u5B59\u5973", "\u7384\u5B59\u5B50\u5973");
2047
+ return pick4(sex, "\u7384\u5B59", "\u7384\u5B59\u5973", "\u7384\u5B59\u5B50\u5973");
1783
2048
  }
1784
- return pick2(sex, `${L}\u4E16\u5B59`, `${L}\u4E16\u5B59\u5973`, `${L}\u4E16\u5B59\u5B50\u5973`);
2049
+ return pick4(sex, `${L}\u4E16\u5B59`, `${L}\u4E16\u5B59\u5973`, `${L}\u4E16\u5B59\u5B50\u5973`);
1785
2050
  };
1786
2051
  var cousinPlain2 = (degree, sex) => {
1787
2052
  if (degree <= 1) {
1788
- return pick2(sex, "\u5802\u8868\u5144\u5F1F", "\u5802\u8868\u59D0\u59B9", "\u5802\u8868\u4EB2");
2053
+ return pick4(sex, "\u5802\u8868\u5144\u5F1F", "\u5802\u8868\u59D0\u59B9", "\u5802\u8868\u4EB2");
1789
2054
  }
1790
2055
  if (degree === 2) {
1791
- return pick2(sex, "\u4ECE\u5802\u8868\u5144\u5F1F", "\u4ECE\u5802\u8868\u59D0\u59B9", "\u4ECE\u5802\u8868\u4EB2");
2056
+ return pick4(sex, "\u4ECE\u5802\u8868\u5144\u5F1F", "\u4ECE\u5802\u8868\u59D0\u59B9", "\u4ECE\u5802\u8868\u4EB2");
1792
2057
  }
1793
- return pick2(
2058
+ return pick4(
1794
2059
  sex,
1795
2060
  `${degree}\u4EE3\u5802\u8868\u5144\u5F1F`,
1796
2061
  `${degree}\u4EE3\u5802\u8868\u59D0\u59B9`,
@@ -1803,7 +2068,7 @@ var KinshipTranslatorZh = class extends KinshipTranslatorBasic {
1803
2068
  if (degree > 0) {
1804
2069
  degree = degree - 1;
1805
2070
  }
1806
- return cousinPlain2(degree, sexOf3(this.personN));
2071
+ return cousinPlain2(degree, sexOf5(this.personN));
1807
2072
  }
1808
2073
  removal() {
1809
2074
  const level = this.pathN?.level ?? 0;
@@ -1815,56 +2080,56 @@ var KinshipTranslatorZh = class extends KinshipTranslatorBasic {
1815
2080
  return level < 0 ? this.nibling() : this.auncle();
1816
2081
  }
1817
2082
  const removed = Math.abs(level);
1818
- return `${cousinPlain2(degree, sexOf3(this.personN))}\uFF08\u9694${removed}\u4EE3\uFF09`;
2083
+ return `${cousinPlain2(degree, sexOf5(this.personN))}\uFF08\u9694${removed}\u4EE3\uFF09`;
1819
2084
  }
1820
2085
  auncle() {
1821
2086
  const level = Math.abs(this.pathN?.level ?? 0);
1822
- const sex = sexOf3(this.personN);
1823
- if (level <= 2) {
1824
- return pick2(sex, "\u53D4\u53D4", "\u963F\u59E8", "\u53D4\u4F2F/\u59D1\u59E8");
2087
+ const sex = sexOf5(this.personN);
2088
+ if (level <= 1) {
2089
+ return pick4(sex, "\u53D4\u53D4", "\u963F\u59E8", "\u53D4\u4F2F/\u59D1\u59E8");
1825
2090
  }
1826
- if (level === 3) {
1827
- return pick2(sex, "\u4F2F\u53D4\u7956\u7236", "\u59D1\u7956\u6BCD", "\u4F2F\u53D4\u7956\u7236\u6BCD");
2091
+ if (level === 2) {
2092
+ return pick4(sex, "\u4F2F\u53D4\u7956\u7236", "\u59D1\u7956\u6BCD", "\u4F2F\u53D4\u7956\u7236\u6BCD");
1828
2093
  }
1829
- return pick2(
2094
+ return pick4(
1830
2095
  sex,
1831
- `${level - 2}\u4EE3\u524D\u7684\u53D4\u53D4`,
1832
- `${level - 2}\u4EE3\u524D\u7684\u963F\u59E8`,
1833
- `${level - 2}\u4EE3\u524D\u7684\u53D4\u4F2F/\u59D1\u59E8`
2096
+ `${level - 1}\u4EE3\u524D\u7684\u53D4\u53D4`,
2097
+ `${level - 1}\u4EE3\u524D\u7684\u963F\u59E8`,
2098
+ `${level - 1}\u4EE3\u524D\u7684\u53D4\u4F2F/\u59D1\u59E8`
1834
2099
  );
1835
2100
  }
1836
2101
  nibling() {
1837
2102
  const level = Math.abs(this.pathN?.level ?? 0);
1838
- const sex = sexOf3(this.personN);
1839
- if (level <= 2) {
1840
- return pick2(sex, "\u4F84\u5B50", "\u4F84\u5973", "\u4F84\u5B50\u5973");
2103
+ const sex = sexOf5(this.personN);
2104
+ if (level <= 1) {
2105
+ return pick4(sex, "\u4F84\u5B50", "\u4F84\u5973", "\u4F84\u5B50\u5973");
1841
2106
  }
1842
- if (level === 3) {
1843
- return pick2(sex, "\u4F84\u5B59", "\u4F84\u5B59\u5973", "\u4F84\u5B59\u5B50\u5973");
2107
+ if (level === 2) {
2108
+ return pick4(sex, "\u4F84\u5B59", "\u4F84\u5B59\u5973", "\u4F84\u5B59\u5B50\u5973");
1844
2109
  }
1845
- return pick2(
2110
+ return pick4(
1846
2111
  sex,
1847
- `${level - 2}\u4EE3\u4E0B\u7684\u4F84\u5B50`,
1848
- `${level - 2}\u4EE3\u4E0B\u7684\u4F84\u5973`,
1849
- `${level - 2}\u4EE3\u4E0B\u7684\u4F84\u5B50\u5973`
2112
+ `${level - 1}\u4EE3\u4E0B\u7684\u4F84\u5B50`,
2113
+ `${level - 1}\u4EE3\u4E0B\u7684\u4F84\u5973`,
2114
+ `${level - 1}\u4EE3\u4E0B\u7684\u4F84\u5B50\u5973`
1850
2115
  );
1851
2116
  }
1852
2117
  parent() {
1853
2118
  return lineal2(
1854
2119
  Math.abs(this.pathN?.level ?? 0),
1855
- sexOf3(this.personN),
2120
+ sexOf5(this.personN),
1856
2121
  "asc"
1857
2122
  );
1858
2123
  }
1859
2124
  child() {
1860
2125
  return lineal2(
1861
2126
  Math.abs(this.pathN?.level ?? 0),
1862
- sexOf3(this.personN),
2127
+ sexOf5(this.personN),
1863
2128
  "desc"
1864
2129
  );
1865
2130
  }
1866
2131
  sibling() {
1867
- return pick2(sexOf3(this.personN), "\u5144\u5F1F", "\u59D0\u59B9", "\u5144\u5F1F\u59D0\u59B9");
2132
+ return pick4(sexOf5(this.personN), "\u5144\u5F1F", "\u59D0\u59B9", "\u5144\u5F1F\u59D0\u59B9");
1868
2133
  }
1869
2134
  halfBlood(relation) {
1870
2135
  if (!relation || !this.isHalfBlood) {
@@ -1873,14 +2138,14 @@ var KinshipTranslatorZh = class extends KinshipTranslatorBasic {
1873
2138
  return `\u5F02\u7236\u6BCD\u7684${relation}`;
1874
2139
  }
1875
2140
  spouse() {
1876
- return pick2(sexOf3(this.personN), "\u4E08\u592B", "\u59BB\u5B50", "\u914D\u5076");
2141
+ return pick4(sexOf5(this.personN), "\u4E08\u592B", "\u59BB\u5B50", "\u914D\u5076");
1877
2142
  }
1878
2143
  ofSpouse(relation) {
1879
2144
  if (!relation) {
1880
2145
  return "";
1881
2146
  }
1882
- const spouseType = pick2(
1883
- sexOf3(this.path?.[1].indi),
2147
+ const spouseType = pick4(
2148
+ sexOf5(this.path?.[1].indi),
1884
2149
  "\u4E08\u592B",
1885
2150
  "\u59BB\u5B50",
1886
2151
  "\u914D\u5076"
@@ -1892,7 +2157,7 @@ var KinshipTranslatorZh = class extends KinshipTranslatorBasic {
1892
2157
  return "";
1893
2158
  }
1894
2159
  const spouse = this.path?.[this.path.length - 1].indi;
1895
- const spouseType = pick2(sexOf3(spouse), "\u4E08\u592B", "\u59BB\u5B50", "\u914D\u5076");
2160
+ const spouseType = pick4(sexOf5(spouse), "\u4E08\u592B", "\u59BB\u5B50", "\u914D\u5076");
1896
2161
  return `${relation}\u7684${spouseType}`;
1897
2162
  }
1898
2163
  of(relation) {
@@ -1928,7 +2193,40 @@ var KinshipTranslatorZh = class extends KinshipTranslatorBasic {
1928
2193
  if (!relation || !this.pathN?.relation) {
1929
2194
  return relation ?? "";
1930
2195
  }
1931
- return `${this.pathN.relation}${relation}`;
2196
+ if (this.pathN.relation === "step") {
2197
+ if (relation === "\u7236\u4EB2") {
2198
+ return "\u7EE7\u7236";
2199
+ }
2200
+ if (relation === "\u6BCD\u4EB2") {
2201
+ return "\u7EE7\u6BCD";
2202
+ }
2203
+ if (relation === "\u513F\u5B50") {
2204
+ return "\u7EE7\u5B50";
2205
+ }
2206
+ if (relation === "\u5973\u513F") {
2207
+ return "\u7EE7\u5973";
2208
+ }
2209
+ return `\u7EE7${relation}`;
2210
+ }
2211
+ if (this.pathN.relation === "adopted") {
2212
+ if (relation === "\u7236\u4EB2") {
2213
+ return "\u517B\u7236";
2214
+ }
2215
+ if (relation === "\u6BCD\u4EB2") {
2216
+ return "\u517B\u6BCD";
2217
+ }
2218
+ if (relation === "\u513F\u5B50") {
2219
+ return "\u517B\u5B50";
2220
+ }
2221
+ if (relation === "\u5973\u513F") {
2222
+ return "\u517B\u5973";
2223
+ }
2224
+ return `\u517B${relation}`;
2225
+ }
2226
+ if (this.pathN.relation === "foster") {
2227
+ return `\u5BC4\u517B${relation}`;
2228
+ }
2229
+ return relation;
1932
2230
  }
1933
2231
  };
1934
2232
 
@@ -2292,6 +2590,82 @@ var ORIG_HEAD_TAG = "_ORIGHEAD";
2292
2590
  // src/utils/gedcom-trailer.ts
2293
2591
  var GEDCOM_TRAILER_TAG = "TRLR";
2294
2592
  var isGedcomTrailerTag = (tag) => tag === GEDCOM_TRAILER_TAG;
2593
+
2594
+ // src/utils/media-utils.ts
2595
+ var getFileExtension = (filename) => {
2596
+ if (!filename) {
2597
+ return "";
2598
+ }
2599
+ if (filename.startsWith("data:")) {
2600
+ const mime = filename.slice(5).split(";")[0] || "";
2601
+ const subtype = (mime.split("/")[1] || "").toLowerCase();
2602
+ if (subtype === "jpeg") {
2603
+ return "jpg";
2604
+ }
2605
+ return subtype.split("+")[0] || "";
2606
+ }
2607
+ const withoutQuery = filename.split(/[?#]/)[0] || filename;
2608
+ const match = withoutQuery.match(/\.([^.]+)$/);
2609
+ return match ? match[1].toLowerCase() : "";
2610
+ };
2611
+ var isImageFormat = (format2) => {
2612
+ if (!format2) {
2613
+ return false;
2614
+ }
2615
+ let normalized = format2.toLowerCase().trim();
2616
+ if (normalized.startsWith("data:")) {
2617
+ normalized = getFileExtension(normalized);
2618
+ } else if (normalized.includes("/")) {
2619
+ normalized = normalized.split("/")[1]?.split("+")[0] || "";
2620
+ if (normalized === "jpeg") {
2621
+ normalized = "jpg";
2622
+ }
2623
+ }
2624
+ const imageFormats = [
2625
+ "jpg",
2626
+ "jpeg",
2627
+ "png",
2628
+ "gif",
2629
+ "bmp",
2630
+ "webp",
2631
+ "svg",
2632
+ "tiff",
2633
+ "tif"
2634
+ ];
2635
+ return imageFormats.includes(normalized);
2636
+ };
2637
+ var resolveObjeForm = (obje) => {
2638
+ const value = obje?.get?.("FILE.FORM")?.toValue?.() ?? obje?.get?.("FORM")?.toValue?.();
2639
+ return typeof value === "string" && value.trim() ? value.trim() : void 0;
2640
+ };
2641
+ var mediaIdValue = (obje, path) => {
2642
+ const value = obje?.get?.(path)?.toValue?.();
2643
+ return typeof value === "string" && value.trim() ? value.trim() : void 0;
2644
+ };
2645
+ var resolveObjeMediaId = (obje) => mediaIdValue(obje, "RIN") || mediaIdValue(obje, "_CLON._OID") || mediaIdValue(obje, "_MSER._LKID") || mediaIdValue(obje, "_OID") || mediaIdValue(obje, "_LKID");
2646
+ var ANCESTRY_MEDIA_RETRIEVAL_PREFIX = "https://www.ancestry.com/api/media/retrieval/v2/image";
2647
+ var ANCESTRY_MEDIA_QUERY = "client=trees-mediaservice&imageQuality=hq";
2648
+ var ancestryMediaPath = (namespace, imgId) => `/namespaces/${namespace}/media/${imgId}?${ANCESTRY_MEDIA_QUERY}`;
2649
+ var ancestryMediaFileUrl = (namespace, imgId) => {
2650
+ if (!namespace || !imgId) {
2651
+ return void 0;
2652
+ }
2653
+ return `${ANCESTRY_MEDIA_RETRIEVAL_PREFIX}${ancestryMediaPath(namespace, imgId)}`;
2654
+ };
2655
+ var objeXrefKey = (obje, fallback = 0) => {
2656
+ if (typeof obje?.id === "string" && obje.id) {
2657
+ return obje.id;
2658
+ }
2659
+ const value = obje?.toValue?.();
2660
+ if (typeof value === "string" && value.trim()) {
2661
+ return value.trim();
2662
+ }
2663
+ if (typeof fallback === "string" && fallback.trim()) {
2664
+ return fallback.trim();
2665
+ }
2666
+ return `@O${fallback}@`;
2667
+ };
2668
+ var objeNoteValue = (obje) => mediaIdValue(obje, "FILE.NOTE") || mediaIdValue(obje, "NOTE") || "";
2295
2669
  var List = class _List {
2296
2670
  // length = 0;
2297
2671
  constructor(items) {
@@ -2941,7 +3315,7 @@ var Common = class _Common {
2941
3315
  this,
2942
3316
  options.obje.namespace,
2943
3317
  options.obje.override,
2944
- void 0,
3318
+ this.isAncestry() ? ancestryMediaFileUrl : void 0,
2945
3319
  options.gedcomVersion
2946
3320
  );
2947
3321
  }
@@ -3872,11 +4246,8 @@ var storeCache = {
3872
4246
  getCacheDbs().relativesOnDegreeCache.setItem(value);
3873
4247
  }
3874
4248
  }, 50),
3875
- // profilePictureCache IS persisted to IndexedDB
4249
+ // Image bytes are stored as one IndexedDB record per photo.
3876
4250
  profilePictureCache: debounce((value) => {
3877
- if (value) {
3878
- getCacheDbs().profilePictureCache.setItem(value);
3879
- }
3880
4251
  }, 100)
3881
4252
  };
3882
4253
  var resetRelativesCache = () => {
@@ -4563,65 +4934,23 @@ var isRemoteOrEmbeddedMediaUrl = (path) => {
4563
4934
  }
4564
4935
  return path.startsWith("data:") || path.startsWith("blob:") || /^https?:\/\//i.test(path);
4565
4936
  };
4566
- var resolveLocalMediaUrl = async (path) => {
4937
+ var resolveLocalMediaUrl = async (path, context) => {
4567
4938
  if (!path) {
4568
4939
  return void 0;
4569
4940
  }
4570
- if (isRemoteOrEmbeddedMediaUrl(path)) {
4941
+ if (path.startsWith("data:") || path.startsWith("blob:")) {
4571
4942
  return path;
4572
4943
  }
4573
- const resolved = await localMediaResolver?.(path);
4574
- return resolved;
4575
- };
4576
- var implemented = (type, ...args) => {
4577
- };
4578
-
4579
- // src/utils/media-utils.ts
4580
- var getFileExtension = (filename) => {
4581
- if (!filename) {
4582
- return "";
4583
- }
4584
- if (filename.startsWith("data:")) {
4585
- const mime = filename.slice(5).split(";")[0] || "";
4586
- const subtype = (mime.split("/")[1] || "").toLowerCase();
4587
- if (subtype === "jpeg") {
4588
- return "jpg";
4589
- }
4590
- return subtype.split("+")[0] || "";
4591
- }
4592
- const withoutQuery = filename.split(/[?#]/)[0] || filename;
4593
- const match = withoutQuery.match(/\.([^.]+)$/);
4594
- return match ? match[1].toLowerCase() : "";
4595
- };
4596
- var isImageFormat = (format2) => {
4597
- if (!format2) {
4598
- return false;
4944
+ const resolved = await localMediaResolver?.(path, context);
4945
+ if (resolved) {
4946
+ return resolved;
4599
4947
  }
4600
- let normalized = format2.toLowerCase().trim();
4601
- if (normalized.startsWith("data:")) {
4602
- normalized = getFileExtension(normalized);
4603
- } else if (normalized.includes("/")) {
4604
- normalized = normalized.split("/")[1]?.split("+")[0] || "";
4605
- if (normalized === "jpeg") {
4606
- normalized = "jpg";
4607
- }
4948
+ if (/^https?:\/\//i.test(path)) {
4949
+ return path;
4608
4950
  }
4609
- const imageFormats = [
4610
- "jpg",
4611
- "jpeg",
4612
- "png",
4613
- "gif",
4614
- "bmp",
4615
- "webp",
4616
- "svg",
4617
- "tiff",
4618
- "tif"
4619
- ];
4620
- return imageFormats.includes(normalized);
4951
+ return void 0;
4621
4952
  };
4622
- var resolveObjeForm = (obje) => {
4623
- const value = obje?.get?.("FILE.FORM")?.toValue?.() ?? obje?.get?.("FORM")?.toValue?.();
4624
- return typeof value === "string" && value.trim() ? value.trim() : void 0;
4953
+ var implemented = (type, ...args) => {
4625
4954
  };
4626
4955
  var uniqueItemsCache = /* @__PURE__ */ new WeakMap();
4627
4956
  var setNestedGroup = (obj, key, value, uniqueCounting = true) => {
@@ -5899,22 +6228,19 @@ var Indi = class extends Common {
5899
6228
  if (objeList) {
5900
6229
  await Promise.all(
5901
6230
  objeList.map(async (objeRef) => {
5902
- const key = objeRef?.id;
6231
+ const key = objeXrefKey(objeRef, 0);
5903
6232
  const obje = objeRef?.standardizeMedia(
5904
6233
  namespace,
5905
6234
  true,
5906
- (ns, iId) => {
5907
- return ns && iId ? `https://mediasvc.ancestry.com/v2/image/namespaces/${ns}/media/${iId}?client=trees-mediaservice&imageQuality=hq` : void 0;
5908
- }
6235
+ ancestryMediaFileUrl
5909
6236
  );
5910
6237
  const isPrimary = obje?.get("_PRIM")?.toValue() === "Y";
5911
- const media = obje?.RIN?.toValue() || obje?.get("_OID")?.toValue();
5912
- const clone = obje?.get("_CLON._OID")?.toValue();
5913
- const mser = obje?.get("_MSER._LKID")?.toValue();
6238
+ const media = resolveObjeMediaId(obje);
5914
6239
  let url = obje?.get("FILE")?.toValue();
5915
6240
  const title = obje?.get("FILE.TITL")?.toValue() ?? obje?.get("TITL")?.toValue() ?? "";
6241
+ const note = objeNoteValue(obje);
5916
6242
  const type = resolveObjeForm(obje) ?? (url ? getFileExtension(url) : void 0) ?? "raw";
5917
- let imgId = clone || mser;
6243
+ let imgId = media;
5918
6244
  const hasEmbeddedOrLocalFile = !!url && (url.startsWith("data:") || url.startsWith("blob:") || !/^https?:\/\//i.test(url));
5919
6245
  if (!hasEmbeddedOrLocalFile && (!www || !tree || !this.id)) {
5920
6246
  return;
@@ -5950,6 +6276,7 @@ var Indi = class extends Common {
5950
6276
  imgId,
5951
6277
  person: this.id,
5952
6278
  title,
6279
+ note,
5953
6280
  url,
5954
6281
  contentType: type,
5955
6282
  downloadName: `${this.id.replaceAll("@", "")}_${this.toNaturalName()?.replaceAll(" ", "-") || ""}_${(title || key.replaceAll("@", "").toString()).replaceAll(" ", "-")}`
@@ -5988,7 +6315,7 @@ var Indi = class extends Common {
5988
6315
  return;
5989
6316
  }
5990
6317
  const obje = o;
5991
- const key = `@O${index}@`;
6318
+ const key = objeXrefKey(obje, index);
5992
6319
  obje.standardizeMedia();
5993
6320
  const isPrimary = obje?.get("_PRIM")?.toValue() === "Y";
5994
6321
  const url = obje?.get("FILE")?.toValue();
@@ -6007,6 +6334,7 @@ var Indi = class extends Common {
6007
6334
  imgId,
6008
6335
  person: this.id,
6009
6336
  title,
6337
+ note: objeNoteValue(obje),
6010
6338
  url,
6011
6339
  contentType: type,
6012
6340
  downloadName: `${this.id.replaceAll("@", "")}_${this.toNaturalName()?.replaceAll(" ", "-") || ""}_${(title || key.replaceAll("@", "").toString()).replaceAll(" ", "-")}`
@@ -6115,7 +6443,7 @@ var Indi = class extends Common {
6115
6443
  if (!obje) {
6116
6444
  return;
6117
6445
  }
6118
- const key = `@O${index}@`;
6446
+ const key = objeXrefKey(obje, index);
6119
6447
  const isPrimary = obje?.get("_PRIM")?.toValue() === "Y";
6120
6448
  const url = obje?.get("FILE")?.toValue();
6121
6449
  const title = obje?.get("TITL")?.toValue() ?? "";
@@ -6132,6 +6460,7 @@ var Indi = class extends Common {
6132
6460
  imgId,
6133
6461
  person: this.id,
6134
6462
  title,
6463
+ note: objeNoteValue(obje),
6135
6464
  url,
6136
6465
  contentType: type,
6137
6466
  downloadName: `${this.id.replaceAll("@", "")}_${this.toNaturalName()?.replaceAll(" ", "-") || ""}_${(title || key.replaceAll("@", "").toString()).replaceAll(" ", "-")}`
@@ -6155,7 +6484,7 @@ var Indi = class extends Common {
6155
6484
  if (!obje) {
6156
6485
  return;
6157
6486
  }
6158
- const key = `@O${index}@`;
6487
+ const key = objeXrefKey(obje, index);
6159
6488
  obje.standardizeMedia();
6160
6489
  const isPrimary = obje?.get("_PRIM")?.toValue() === "Y";
6161
6490
  const url = obje?.get("FILE")?.toValue();
@@ -6172,6 +6501,7 @@ var Indi = class extends Common {
6172
6501
  imgId,
6173
6502
  person: this.id,
6174
6503
  title,
6504
+ note: objeNoteValue(obje),
6175
6505
  url,
6176
6506
  contentType: type,
6177
6507
  downloadName: `${this.id.replaceAll("@", "")}_${this.toNaturalName()?.replaceAll(" ", "-") || ""}_${(title || key.replaceAll("@", "").toString()).replaceAll(" ", "-")}`
@@ -6203,7 +6533,12 @@ var Indi = class extends Common {
6203
6533
  );
6204
6534
  if (cached !== void 0) {
6205
6535
  if (cached?.file && !isRemoteOrEmbeddedMediaUrl(cached.file)) {
6206
- const resolvedCached = await resolveLocalMediaUrl(cached.file);
6536
+ const resolvedCached = await resolveLocalMediaUrl(cached.file, {
6537
+ url: cached.file,
6538
+ person: this.id,
6539
+ tree: this.getTreeId?.(),
6540
+ treeName: this.getTreeName?.()
6541
+ });
6207
6542
  if (resolvedCached && isRemoteOrEmbeddedMediaUrl(resolvedCached)) {
6208
6543
  const refreshed = { ...cached, file: resolvedCached };
6209
6544
  profilePictureCache(
@@ -6228,7 +6563,16 @@ var Indi = class extends Common {
6228
6563
  }
6229
6564
  const mediaArray = Object.values(mediaList);
6230
6565
  const toDisplayableProfile = async (media, isPrimary) => {
6231
- const resolvedFile = await resolveLocalMediaUrl(media.url);
6566
+ const resolvedFile = await resolveLocalMediaUrl(media.url, {
6567
+ url: media.url,
6568
+ id: media.id,
6569
+ imgId: media.imgId,
6570
+ key: media.key,
6571
+ contentType: media.contentType,
6572
+ person: media.person || this.id,
6573
+ tree: media.tree || this.getTreeId?.(),
6574
+ treeName: this.getTreeName?.()
6575
+ });
6232
6576
  if (!resolvedFile || !isRemoteOrEmbeddedMediaUrl(resolvedFile)) {
6233
6577
  return void 0;
6234
6578
  }
@@ -7810,45 +8154,64 @@ var nameFormatter = (indiName, settings, letterOnAll = true, indi, debug) => {
7810
8154
  };
7811
8155
 
7812
8156
  // src/kinship-translator/patterns.de.ts
8157
+ var parentRelationsDe = {
8158
+ step: "Stief",
8159
+ foster: "Pflege",
8160
+ adopted: "Adoptiv"
8161
+ };
7813
8162
  var InLawsDe = {
7814
- "Ehepartner von (kind|tochter|sohn)": "Schwiegerkind",
7815
- "Ehefrau von (kind|tochter|sohn)": "Schwiegertochter",
7816
- "Ehemann von (kind|tochter|sohn)": "Schwiegersohn",
7817
- "mutter des (Ehepartner|Ehefrau|Ehemann)s": "Schwiegermutter",
7818
- "vater des (Ehepartner|Ehefrau|Ehemann)s": "Schwiegervater",
7819
- "elternteil des (Ehepartner|Ehefrau|Ehemann)s": "Schwiegerelternteil",
7820
- "Ehefrau von (Halb)?(geschwister|schwester|bruder)": "Schw\xE4gerin",
7821
- "Ehemann von (Halb)?(geschwister|schwester|bruder)": "Schwager",
7822
- "Ehepartner von (Halb)?(geschwister|schwester|bruder)": "Schwager/Schw\xE4gerin",
7823
- "(Halb)?schwester des (Ehepartner|Ehefrau|Ehemann)s": "Schw\xE4gerin",
7824
- "(Halb)?bruder des (Ehepartner|Ehefrau|Ehemann)s": "Schwager",
7825
- "(Halb)?geschwister des (Ehepartner|Ehefrau|Ehemann)s": "Schwager/Schw\xE4gerin"
8163
+ "Ehepartner von (Kind|Tochter|Sohn)": "Schwiegerkind",
8164
+ "Ehefrau von (Kind|Tochter|Sohn)": "Schwiegertochter",
8165
+ "Ehemann von (Kind|Tochter|Sohn)": "Schwiegersohn",
8166
+ "Mutter (des Ehepartners|des Ehemanns|der Ehefrau)": "Schwiegermutter",
8167
+ "Vater (des Ehepartners|des Ehemanns|der Ehefrau)": "Schwiegervater",
8168
+ "Elternteil (des Ehepartners|des Ehemanns|der Ehefrau)": "Schwiegerelternteil",
8169
+ "Ehefrau von (Halb)?-?(Geschwister|Schwester|Bruder)": "Schw\xE4gerin",
8170
+ "Ehemann von (Halb)?-?(Geschwister|Schwester|Bruder)": "Schwager",
8171
+ "Ehepartner von (Halb)?-?(Geschwister|Schwester|Bruder)": "Schwager/Schw\xE4gerin",
8172
+ "(Halb)?-?(Schwester|schwester) (des Ehepartners|des Ehemanns|der Ehefrau)": "Schw\xE4gerin",
8173
+ "(Halb)?-?(Bruder|bruder) (des Ehepartners|des Ehemanns|der Ehefrau)": "Schwager",
8174
+ "(Halb)?-?(Geschwister|geschwister) (des Ehepartners|des Ehemanns|der Ehefrau)": "Schwager/Schw\xE4gerin"
7826
8175
  };
7827
8176
 
7828
8177
  // src/kinship-translator/kinship-translator.de.ts
7829
- var KinshipTranslatorDe = class extends KinshipTranslatorBasic {
7830
- directPrefix() {
7831
- const level = Math.abs(this.pathN?.level ?? 0);
7832
- if (level <= 1) {
7833
- return "";
7834
- }
7835
- if (level === 2) {
7836
- return "Gro\xDF";
7837
- }
7838
- if (level === 3) {
7839
- return "Urgro\xDF";
7840
- }
7841
- return `Ur${level - 2}-gro\xDF`;
8178
+ var sexOf6 = (person) => {
8179
+ if (person?.isMale?.()) {
8180
+ return "m";
8181
+ }
8182
+ if (person?.isFemale?.()) {
8183
+ return "f";
8184
+ }
8185
+ return "n";
8186
+ };
8187
+ var pick5 = (sex, male, female, neutral) => {
8188
+ if (sex === "m") {
8189
+ return male;
7842
8190
  }
8191
+ if (sex === "f") {
8192
+ return female;
8193
+ }
8194
+ return neutral;
8195
+ };
8196
+ var ur = (count) => count > 0 ? "Ur".repeat(count) : "";
8197
+ var genitiveArticle = (spouseType) => {
8198
+ if (spouseType === "Ehefrau") {
8199
+ return `der ${spouseType}`;
8200
+ }
8201
+ return `des ${spouseType}s`;
8202
+ };
8203
+ var KinshipTranslatorDe = class extends KinshipTranslatorBasic {
7843
8204
  indirect() {
7844
8205
  let degree = Math.abs(this.pathN?.degree ?? 0);
7845
8206
  if (degree > 0) {
7846
8207
  degree = degree - 1;
7847
8208
  }
7848
- if (degree === 1) {
7849
- return `Cousin`;
8209
+ const sex = sexOf6(this.personN);
8210
+ const cousin = pick5(sex, "Cousin", "Cousine", "Cousin/Cousine");
8211
+ if (degree <= 1) {
8212
+ return cousin;
7850
8213
  }
7851
- return `Cousin ${degree}. Grades`;
8214
+ return `${cousin} ${degree}. Grades`;
7852
8215
  }
7853
8216
  removal() {
7854
8217
  const level = this.pathN?.level ?? 0;
@@ -7859,101 +8222,101 @@ var KinshipTranslatorDe = class extends KinshipTranslatorBasic {
7859
8222
  if (!degree) {
7860
8223
  return level < 0 ? this.nibling() : this.auncle();
7861
8224
  }
7862
- return `Cousin ${degree}. Grades ${Math.abs(level)}\xD7 entfernt`;
8225
+ return `${this.indirect()} ${Math.abs(level)}\xD7 entfernt`;
7863
8226
  }
7864
8227
  auncle() {
7865
- const prefix = this.directPrefix();
7866
- if (this.personN?.isMale()) {
7867
- return `${prefix}onkel`;
7868
- }
7869
- if (this.personN?.isFemale()) {
7870
- return `${prefix}tante`;
8228
+ const level = Math.abs(this.pathN?.level ?? 0);
8229
+ const sex = sexOf6(this.personN);
8230
+ if (level <= 1) {
8231
+ return pick5(sex, "Onkel", "Tante", "Onkel/Tante");
7871
8232
  }
7872
- return `${prefix}onkel/tante`;
8233
+ const prefix = `${ur(level - 2)}Gro\xDF`;
8234
+ return pick5(
8235
+ sex,
8236
+ `${prefix}onkel`,
8237
+ `${prefix}tante`,
8238
+ `${prefix}onkel/tante`
8239
+ );
7873
8240
  }
7874
8241
  nibling() {
7875
- const prefix = this.directPrefix();
7876
- if (this.personN?.isMale()) {
7877
- return `${prefix}neffe`;
7878
- }
7879
- if (this.personN?.isFemale()) {
7880
- return `${prefix}nichte`;
8242
+ const level = Math.abs(this.pathN?.level ?? 0);
8243
+ const sex = sexOf6(this.personN);
8244
+ if (level <= 1) {
8245
+ return pick5(sex, "Neffe", "Nichte", "Neffe/Nichte");
7881
8246
  }
7882
- return `${prefix}neffe/nichte`;
8247
+ const prefix = `${ur(level - 2)}Gro\xDF`;
8248
+ return pick5(
8249
+ sex,
8250
+ `${prefix}neffe`,
8251
+ `${prefix}nichte`,
8252
+ `${prefix}neffe/nichte`
8253
+ );
7883
8254
  }
7884
8255
  parent() {
7885
- const prefix = this.directPrefix();
7886
- if (this.personN?.isMale()) {
7887
- return `${prefix}vater`;
7888
- }
7889
- if (this.personN?.isFemale()) {
7890
- return `${prefix}mutter`;
8256
+ const level = Math.abs(this.pathN?.level ?? 0);
8257
+ const sex = sexOf6(this.personN);
8258
+ if (level <= 1) {
8259
+ return pick5(sex, "Vater", "Mutter", "Elternteil");
7891
8260
  }
7892
- return `${prefix}elternteil`;
8261
+ const prefix = `${ur(level - 2)}Gro\xDF`;
8262
+ return pick5(
8263
+ sex,
8264
+ `${prefix}vater`,
8265
+ `${prefix}mutter`,
8266
+ `${prefix}elternteil`
8267
+ );
7893
8268
  }
7894
8269
  child() {
7895
- const prefix = this.directPrefix();
7896
- if (this.personN?.isMale()) {
7897
- return `${prefix}sohn`;
7898
- }
7899
- if (this.personN?.isFemale()) {
7900
- return `${prefix}tochter`;
8270
+ const level = Math.abs(this.pathN?.level ?? 0);
8271
+ const sex = sexOf6(this.personN);
8272
+ if (level <= 1) {
8273
+ return pick5(sex, "Sohn", "Tochter", "Kind");
7901
8274
  }
7902
- return `${prefix}kind`;
8275
+ const prefix = ur(level - 2);
8276
+ return pick5(
8277
+ sex,
8278
+ `${prefix}Enkel`,
8279
+ `${prefix}Enkelin`,
8280
+ `${prefix}Enkelkind`
8281
+ );
7903
8282
  }
7904
8283
  sibling() {
7905
- if (this.personN?.isMale()) {
7906
- return "bruder";
7907
- }
7908
- if (this.personN?.isFemale()) {
7909
- return "schwester";
7910
- }
7911
- return "geschwister";
8284
+ return pick5(sexOf6(this.personN), "Bruder", "Schwester", "Geschwister");
7912
8285
  }
7913
8286
  halfBlood(relation) {
7914
8287
  if (!relation || !this.isHalfBlood) {
7915
8288
  return relation ?? "";
7916
8289
  }
7917
- if (/^[A-ZÄÖÜ]/.test(relation) || /[-\s]/.test(relation)) {
8290
+ if (/[\s-]/.test(relation) || /^(Groß|Ur)/.test(relation)) {
7918
8291
  return `Halb-${relation}`;
7919
8292
  }
7920
- return `Halb${relation}`;
8293
+ return `Halb${relation.charAt(0).toLowerCase()}${relation.slice(1)}`;
7921
8294
  }
7922
8295
  spouse() {
7923
- if (this.personN?.isMale()) {
7924
- return "Ehemann";
7925
- }
7926
- if (this.personN?.isFemale()) {
7927
- return "Ehefrau";
7928
- }
7929
- return "Ehepartner";
8296
+ return pick5(sexOf6(this.personN), "Ehemann", "Ehefrau", "Ehepartner");
7930
8297
  }
7931
8298
  ofSpouse(relation) {
7932
8299
  if (!relation) {
7933
8300
  return "";
7934
8301
  }
7935
- const spouse = this.path?.[1].indi;
7936
- let spouseType = "Ehepartner";
7937
- if (spouse?.isMale()) {
7938
- spouseType = "Ehemann";
7939
- }
7940
- if (spouse?.isFemale()) {
7941
- spouseType = "Ehefrau";
7942
- }
7943
- return `${relation} des ${spouseType}s`;
8302
+ const spouseType = pick5(
8303
+ sexOf6(this.path?.[1].indi),
8304
+ "Ehemann",
8305
+ "Ehefrau",
8306
+ "Ehepartner"
8307
+ );
8308
+ return `${relation} ${genitiveArticle(spouseType)}`;
7944
8309
  }
7945
8310
  spouseOf(relation) {
7946
8311
  if (!relation) {
7947
8312
  return "";
7948
8313
  }
7949
- const spouse = this.path?.[this.path.length - 1].indi;
7950
- let spouseType = "Ehepartner";
7951
- if (spouse?.isMale()) {
7952
- spouseType = "Ehemann";
7953
- }
7954
- if (spouse?.isFemale()) {
7955
- spouseType = "Ehefrau";
7956
- }
8314
+ const spouseType = pick5(
8315
+ sexOf6(this.path?.[this.path.length - 1].indi),
8316
+ "Ehemann",
8317
+ "Ehefrau",
8318
+ "Ehepartner"
8319
+ );
7957
8320
  return `${spouseType} von ${relation}`;
7958
8321
  }
7959
8322
  of(relation) {
@@ -7971,8 +8334,8 @@ var KinshipTranslatorDe = class extends KinshipTranslatorBasic {
7971
8334
  if (!name || !relation) {
7972
8335
  return relation ?? "";
7973
8336
  }
7974
- if (relation.includes(" des ") || relation.includes(" von ")) {
7975
- return relation.replace(/ (des|von) /, ` $1 ${name}s `);
8337
+ if (relation.includes(" des ") || relation.includes(" der ") || relation.includes(" von ")) {
8338
+ return relation.replace(/ (des|der|von) /, ` $1 ${name}s `);
7976
8339
  }
7977
8340
  return `${name}s ${relation}`;
7978
8341
  }
@@ -8002,7 +8365,14 @@ var KinshipTranslatorDe = class extends KinshipTranslatorBasic {
8002
8365
  if (!relation || !this.pathN?.relation) {
8003
8366
  return relation ?? "";
8004
8367
  }
8005
- return `${this.pathN.relation} ${relation}`;
8368
+ const prefix = parentRelationsDe[this.pathN.relation];
8369
+ if (!prefix) {
8370
+ return relation;
8371
+ }
8372
+ if (prefix.endsWith("-") || prefix.endsWith(" ")) {
8373
+ return `${prefix}${relation}`;
8374
+ }
8375
+ return `${prefix}${relation.charAt(0).toLowerCase()}${relation.slice(1)}`;
8006
8376
  }
8007
8377
  };
8008
8378