@treeviz/gedcom-parser 2.0.8 → 2.0.9

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 (27) hide show
  1. package/dist/classes/index.js +382 -158
  2. package/dist/classes/indi.d.ts.map +1 -1
  3. package/dist/cli/index.js +382 -158
  4. package/dist/constants/index.js +381 -157
  5. package/dist/factories/index.js +381 -157
  6. package/dist/index.js +383 -159
  7. package/dist/kinship-translator/index.js +381 -157
  8. package/dist/kinship-translator/kinship-translator.basic.d.ts +11 -0
  9. package/dist/kinship-translator/kinship-translator.basic.d.ts.map +1 -1
  10. package/dist/kinship-translator/kinship-translator.d.ts.map +1 -1
  11. package/dist/kinship-translator/kinship-translator.de.d.ts +2 -1
  12. package/dist/kinship-translator/kinship-translator.de.d.ts.map +1 -1
  13. package/dist/kinship-translator/kinship-translator.en.d.ts +2 -1
  14. package/dist/kinship-translator/kinship-translator.en.d.ts.map +1 -1
  15. package/dist/kinship-translator/kinship-translator.es.d.ts +2 -1
  16. package/dist/kinship-translator/kinship-translator.es.d.ts.map +1 -1
  17. package/dist/kinship-translator/kinship-translator.fr.d.ts +2 -1
  18. package/dist/kinship-translator/kinship-translator.fr.d.ts.map +1 -1
  19. package/dist/kinship-translator/kinship-translator.hu.d.ts +8 -1
  20. package/dist/kinship-translator/kinship-translator.hu.d.ts.map +1 -1
  21. package/dist/kinship-translator/kinship-translator.interface.d.ts +1 -0
  22. package/dist/kinship-translator/kinship-translator.interface.d.ts.map +1 -1
  23. package/dist/kinship-translator/patterns.es.d.ts.map +1 -1
  24. package/dist/utils/cache.d.ts +14 -1
  25. package/dist/utils/cache.d.ts.map +1 -1
  26. package/dist/utils/index.js +383 -159
  27. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1332,6 +1332,135 @@ var profilePictureCache = (gedcom, key, value) => {
1332
1332
  const cached = caches.profilePictureCache?.[fullKey];
1333
1333
  return cached;
1334
1334
  };
1335
+ var isNonBiologicalPath = (path) => path.some(
1336
+ (item) => item.relation && item.relation !== "biological" /* BIOLOGICAL */
1337
+ );
1338
+ var invertHop = (kinship) => {
1339
+ if (kinship === "parent") {
1340
+ return "child";
1341
+ }
1342
+ if (kinship === "child") {
1343
+ return "parent";
1344
+ }
1345
+ return kinship;
1346
+ };
1347
+ var hopRelation = (from, toIndi, kinship, inherited) => {
1348
+ if (kinship === "parent" || kinship === "child") {
1349
+ const parent = kinship === "parent" ? toIndi : from.indi;
1350
+ const child = kinship === "parent" ? from.indi : toIndi;
1351
+ const currentRelation = child.getParentType(parent);
1352
+ if (currentRelation && currentRelation !== "biological" /* BIOLOGICAL */) {
1353
+ return currentRelation;
1354
+ }
1355
+ }
1356
+ if (inherited && inherited !== "biological" /* BIOLOGICAL */) {
1357
+ return inherited;
1358
+ }
1359
+ return void 0;
1360
+ };
1361
+ var rebuildPathFromHops = (hops, skipRelation = false) => {
1362
+ if (hops.length === 0) {
1363
+ return [];
1364
+ }
1365
+ const path = [
1366
+ {
1367
+ indi: hops[0].indi,
1368
+ kinship: "self",
1369
+ level: 0,
1370
+ levelUp: 0,
1371
+ levelDown: 0,
1372
+ degree: 0
1373
+ }
1374
+ ];
1375
+ for (let i = 1; i < hops.length; i++) {
1376
+ const prev = path[i - 1];
1377
+ const { indi, kinship } = hops[i];
1378
+ const relation = skipRelation ? void 0 : hopRelation(prev, indi, kinship, prev.relation);
1379
+ if (kinship === "parent") {
1380
+ path.push({
1381
+ indi,
1382
+ kinship,
1383
+ relation,
1384
+ level: prev.level + 1,
1385
+ levelUp: prev.levelUp + 1,
1386
+ levelDown: prev.levelDown,
1387
+ degree: prev.degree
1388
+ });
1389
+ continue;
1390
+ }
1391
+ if (kinship === "child") {
1392
+ path.push({
1393
+ indi,
1394
+ kinship,
1395
+ relation,
1396
+ level: prev.level - 1,
1397
+ levelUp: prev.levelUp,
1398
+ levelDown: prev.levelDown + 1,
1399
+ degree: prev.levelUp ? prev.level > 0 ? prev.levelUp - prev.level + 1 : prev.levelDown - Math.abs(prev.level) : 0
1400
+ });
1401
+ continue;
1402
+ }
1403
+ path.push({
1404
+ indi,
1405
+ kinship,
1406
+ relation,
1407
+ level: prev.level,
1408
+ levelUp: prev.levelUp,
1409
+ levelDown: prev.levelDown,
1410
+ degree: prev.degree
1411
+ });
1412
+ }
1413
+ return path;
1414
+ };
1415
+ var storePathIfBetter = (gedcom, fromId, toId, path) => {
1416
+ const key = `${fromId}|${toId}`;
1417
+ const existing = pathCache(gedcom, key);
1418
+ if (existing && (!isNonBiologicalPath(existing) || isNonBiologicalPath(path))) {
1419
+ return;
1420
+ }
1421
+ pathCache(gedcom, key, path);
1422
+ };
1423
+ var cacheDiscoveredPath = (gedcom, path) => {
1424
+ const n = path.length;
1425
+ if (n < 2) {
1426
+ return;
1427
+ }
1428
+ for (let i = 0; i < n; i++) {
1429
+ const fromId = path[i].indi.id;
1430
+ if (!fromId) {
1431
+ continue;
1432
+ }
1433
+ for (let j = i + 1; j < n; j++) {
1434
+ const toId = path[j].indi.id;
1435
+ if (!toId) {
1436
+ continue;
1437
+ }
1438
+ const isOriginalPair = i === 0 && j === n - 1;
1439
+ const isDirectHop = j === i + 1;
1440
+ const slice = path.slice(i, j + 1);
1441
+ const sliceMixed = isNonBiologicalPath(slice);
1442
+ if (!isOriginalPair && !isDirectHop && sliceMixed) {
1443
+ continue;
1444
+ }
1445
+ const forward = i === 0 ? slice : rebuildPathFromHops(slice, !sliceMixed);
1446
+ const reverseHops = [
1447
+ {
1448
+ indi: slice[slice.length - 1].indi,
1449
+ kinship: "self"
1450
+ }
1451
+ ];
1452
+ for (let k = slice.length - 2; k >= 0; k--) {
1453
+ reverseHops.push({
1454
+ indi: slice[k].indi,
1455
+ kinship: invertHop(slice[k + 1].kinship)
1456
+ });
1457
+ }
1458
+ const reverse = rebuildPathFromHops(reverseHops, !sliceMixed);
1459
+ storePathIfBetter(gedcom, fromId, toId, forward);
1460
+ storePathIfBetter(gedcom, toId, fromId, reverse);
1461
+ }
1462
+ }
1463
+ };
1335
1464
 
1336
1465
  // src/utils/get-all-prop.ts
1337
1466
  var getAllProp = (indi, prop) => {
@@ -2997,7 +3126,6 @@ var Indi = class extends Common {
2997
3126
  if (cache) {
2998
3127
  return cache;
2999
3128
  }
3000
- const visited = new Individuals().append(this);
3001
3129
  const mainItem = {
3002
3130
  indi: this,
3003
3131
  level: 0,
@@ -3006,129 +3134,155 @@ var Indi = class extends Common {
3006
3134
  degree: 0,
3007
3135
  kinship: "self"
3008
3136
  };
3009
- const path = [mainItem];
3137
+ const mainPath = [mainItem];
3010
3138
  if (this.id === usedIndi.id) {
3011
- return path;
3139
+ return mainPath;
3012
3140
  }
3013
- const queue = [
3014
- {
3015
- ...mainItem,
3016
- path
3017
- }
3018
- ];
3019
- let helper = 0;
3020
- while (queue.length > 0) {
3021
- if (helper++ > 1e6) {
3022
- break;
3023
- }
3024
- const {
3025
- indi,
3026
- path: path2,
3027
- kinship,
3028
- relation,
3029
- level,
3030
- levelUp,
3031
- levelDown,
3032
- degree,
3033
- breakOnNext,
3034
- breakAfterNext,
3035
- inLaw
3036
- } = queue.shift();
3037
- if (usedIndi.id === indi.id) {
3038
- if (breakOnNext) {
3039
- return void 0;
3141
+ const bfs = (biologicalOnly) => {
3142
+ const visited = new Individuals().append(this);
3143
+ const queue = [
3144
+ {
3145
+ ...mainItem,
3146
+ path: mainPath
3040
3147
  }
3041
- pathCache(this._gedcom, cacheKey, path2);
3042
- return path2;
3043
- }
3044
- visited.append(indi);
3045
- const additional = {};
3046
- if (breakOnNext || breakAfterNext) {
3047
- additional.breakOnNext = breakOnNext || breakAfterNext;
3048
- }
3049
- if (inLaw) {
3050
- additional.inLaw = inLaw;
3051
- }
3052
- if (kinship === "spouse" && breakAfterSpouse) {
3053
- if (path2.length <= 2) {
3054
- additional.inLaw = true;
3055
- } else {
3056
- additional.breakOnNext = true;
3148
+ ];
3149
+ let helper = 0;
3150
+ while (queue.length > 0) {
3151
+ if (helper++ > 1e6) {
3152
+ break;
3057
3153
  }
3058
- }
3059
- if (kinship !== "child" || !breakAfterSpouse) {
3060
- indi.getBiologicalFathers().copy().merge(indi.getBiologicalMothers()).merge(indi.getFathers().copy().merge(indi.getMothers())).forEach((relative) => {
3154
+ const {
3155
+ indi,
3156
+ path,
3157
+ kinship,
3158
+ relation,
3159
+ level,
3160
+ levelUp,
3161
+ levelDown,
3162
+ degree,
3163
+ breakOnNext,
3164
+ breakAfterNext,
3165
+ inLaw
3166
+ } = queue.shift();
3167
+ if (usedIndi.id === indi.id) {
3168
+ if (breakOnNext) {
3169
+ return void 0;
3170
+ }
3171
+ return path;
3172
+ }
3173
+ visited.append(indi);
3174
+ const additional = {};
3175
+ if (breakOnNext || breakAfterNext) {
3176
+ additional.breakOnNext = breakOnNext || breakAfterNext;
3177
+ }
3178
+ if (inLaw) {
3179
+ additional.inLaw = inLaw;
3180
+ }
3181
+ if (!biologicalOnly && kinship === "spouse" && breakAfterSpouse) {
3182
+ if (path.length <= 2) {
3183
+ additional.inLaw = true;
3184
+ } else {
3185
+ additional.breakOnNext = true;
3186
+ }
3187
+ }
3188
+ if (kinship !== "child" || !breakAfterSpouse) {
3189
+ indi.getBiologicalFathers().copy().merge(indi.getBiologicalMothers()).merge(indi.getFathers().copy().merge(indi.getMothers())).forEach((relative) => {
3190
+ if (!visited.has(relative)) {
3191
+ const currentRelation = indi.getParentType(relative);
3192
+ const isNonBiological = !!currentRelation && currentRelation !== "biological" /* BIOLOGICAL */;
3193
+ if (biologicalOnly && isNonBiological) {
3194
+ return;
3195
+ }
3196
+ if (!biologicalOnly && breakAfterNonBiological && isNonBiological) {
3197
+ additional.breakAfterNext = true;
3198
+ }
3199
+ const newItem = {
3200
+ indi: relative,
3201
+ kinship: "parent",
3202
+ relation: isNonBiological ? currentRelation : relation,
3203
+ level: level + 1,
3204
+ levelUp: levelUp + 1,
3205
+ levelDown,
3206
+ degree,
3207
+ ...additional
3208
+ };
3209
+ queue.push({
3210
+ ...newItem,
3211
+ path: [...path, newItem]
3212
+ });
3213
+ }
3214
+ });
3215
+ }
3216
+ indi.getChildren().forEach((relative) => {
3061
3217
  if (!visited.has(relative)) {
3062
- const currentRelation = indi.getParentType(relative);
3063
- if (breakAfterNonBiological && currentRelation !== "biological" /* BIOLOGICAL */) {
3218
+ const currentRelation = relative.getParentType(indi);
3219
+ const isNonBiological = !!currentRelation && currentRelation !== "biological" /* BIOLOGICAL */;
3220
+ if (biologicalOnly && isNonBiological) {
3221
+ return;
3222
+ }
3223
+ if (!biologicalOnly && breakAfterNonBiological && isNonBiological) {
3064
3224
  additional.breakAfterNext = true;
3065
3225
  }
3066
3226
  const newItem = {
3067
3227
  indi: relative,
3068
- kinship: "parent",
3069
- relation: currentRelation && currentRelation !== "biological" /* BIOLOGICAL */ ? currentRelation : relation,
3070
- level: level + 1,
3071
- levelUp: levelUp + 1,
3072
- levelDown,
3073
- degree,
3228
+ kinship: "child",
3229
+ relation: isNonBiological ? currentRelation : relation,
3230
+ level: level - 1,
3231
+ levelUp,
3232
+ levelDown: levelDown + 1,
3233
+ degree: levelUp ? level > 0 ? levelUp - level + 1 : levelDown - Math.abs(level) : 0,
3074
3234
  ...additional
3075
3235
  };
3076
3236
  queue.push({
3077
3237
  ...newItem,
3078
- path: [...path2, newItem]
3238
+ path: [...path, newItem]
3079
3239
  });
3080
3240
  }
3081
3241
  });
3082
- }
3083
- indi.getChildren().forEach((relative) => {
3084
- if (!visited.has(relative)) {
3085
- const currentRelation = relative.getParentType(indi);
3086
- if (breakAfterNonBiological && currentRelation !== "biological" /* BIOLOGICAL */) {
3087
- additional.breakAfterNext = true;
3088
- }
3089
- const newItem = {
3090
- indi: relative,
3091
- kinship: "child",
3092
- relation: currentRelation && currentRelation !== "biological" /* BIOLOGICAL */ ? currentRelation : relation,
3093
- level: level - 1,
3094
- levelUp,
3095
- levelDown: levelDown + 1,
3096
- degree: levelUp ? level > 0 ? levelUp - level + 1 : levelDown - Math.abs(level) : 0,
3097
- ...additional
3098
- };
3099
- queue.push({
3100
- ...newItem,
3101
- path: [...path2, newItem]
3102
- });
3242
+ if (biologicalOnly) {
3243
+ continue;
3103
3244
  }
3104
- });
3105
- indi.getCoParents().forEach((relative) => {
3106
- if (!visited.has(relative)) {
3107
- const currentAddition = {};
3108
- if (relation && relation !== "biological" /* BIOLOGICAL */) {
3109
- currentAddition.relation = relation;
3110
- }
3111
- if (inLaw) {
3112
- currentAddition.breakOnNext = true;
3245
+ indi.getCoParents().forEach((relative) => {
3246
+ if (!visited.has(relative)) {
3247
+ const currentAddition = {};
3248
+ if (relation && relation !== "biological" /* BIOLOGICAL */) {
3249
+ currentAddition.relation = relation;
3250
+ }
3251
+ if (inLaw) {
3252
+ currentAddition.breakOnNext = true;
3253
+ }
3254
+ const newItem = {
3255
+ indi: relative,
3256
+ kinship: "spouse",
3257
+ level,
3258
+ levelUp,
3259
+ levelDown,
3260
+ degree,
3261
+ ...additional,
3262
+ ...currentAddition
3263
+ };
3264
+ queue.push({
3265
+ ...newItem,
3266
+ path: [...path, newItem]
3267
+ });
3113
3268
  }
3114
- const newItem = {
3115
- indi: relative,
3116
- kinship: "spouse",
3117
- level,
3118
- levelUp,
3119
- levelDown,
3120
- degree,
3121
- ...additional,
3122
- ...currentAddition
3123
- };
3124
- queue.push({
3125
- ...newItem,
3126
- path: [...path2, newItem]
3127
- });
3128
- }
3129
- });
3269
+ });
3270
+ }
3271
+ return void 0;
3272
+ };
3273
+ const foundPath = bfs(false);
3274
+ const lastItem = foundPath?.[foundPath.length - 1];
3275
+ if (lastItem?.relation && lastItem.relation !== "biological" /* BIOLOGICAL */) {
3276
+ const biologicalPath = bfs(true);
3277
+ if (biologicalPath) {
3278
+ cacheDiscoveredPath(this._gedcom, biologicalPath);
3279
+ return biologicalPath;
3280
+ }
3130
3281
  }
3131
- return void 0;
3282
+ if (foundPath) {
3283
+ cacheDiscoveredPath(this._gedcom, foundPath);
3284
+ }
3285
+ return foundPath;
3132
3286
  }
3133
3287
  kinship(other, showMainPerson, lang = "en", entirePath, displayName = "givenname") {
3134
3288
  const KinshipTranslatorClass2 = getKinshipTranslatorClass();
@@ -4107,6 +4261,44 @@ var KinshipTranslatorBasic = class {
4107
4261
  }
4108
4262
  return this.pathN?.indi;
4109
4263
  }
4264
+ /**
4265
+ * True when the path goes through a common ancestor whose two children
4266
+ * (the person we came from and the person we go to) share fewer than two
4267
+ * biological parents — i.e. they are half-siblings, so every collateral
4268
+ * relative on this path is a half-aunt/half-cousin/... too.
4269
+ *
4270
+ * Direct ancestors/descendants and paths that already use a
4271
+ * step/adopted/foster edge are never half-blood.
4272
+ */
4273
+ get isHalfBlood() {
4274
+ const path = this.path;
4275
+ if (!path || path.length < 3) {
4276
+ return false;
4277
+ }
4278
+ if (path.some(
4279
+ (item) => item.relation && item.relation !== "biological" /* BIOLOGICAL */
4280
+ )) {
4281
+ return false;
4282
+ }
4283
+ let peakIndex = -1;
4284
+ for (let i = 1; i < path.length; i++) {
4285
+ if (path[i].kinship === "parent") {
4286
+ peakIndex = i;
4287
+ }
4288
+ }
4289
+ if (peakIndex <= 0 || peakIndex >= path.length - 1) {
4290
+ return false;
4291
+ }
4292
+ if (path[peakIndex + 1].kinship !== "child") {
4293
+ return false;
4294
+ }
4295
+ const siblingA = path[peakIndex - 1].indi;
4296
+ const siblingB = path[peakIndex + 1].indi;
4297
+ const parentsA = siblingA.getBiologicalParents();
4298
+ const parentsB = siblingB.getBiologicalParents();
4299
+ const inter = parentsA.intersection(parentsB);
4300
+ return inter.length === 1 && (parentsA.length > 1 || parentsB.length > 1);
4301
+ }
4110
4302
  indirect() {
4111
4303
  return "";
4112
4304
  }
@@ -4134,6 +4326,9 @@ var KinshipTranslatorBasic = class {
4134
4326
  relationType(relation) {
4135
4327
  return relation ?? "";
4136
4328
  }
4329
+ halfBlood(relation) {
4330
+ return relation ?? "";
4331
+ }
4137
4332
  of(relation) {
4138
4333
  return relation ?? "";
4139
4334
  }
@@ -4372,14 +4567,34 @@ var KinshipTranslatorHU = class extends KinshipTranslatorBasic {
4372
4567
  return `${prefix.replace(/nagy$/, "")}unoka`;
4373
4568
  }
4374
4569
  sibling() {
4375
- const parents1 = this.person1?.getBiologicalParents();
4376
- const parentsN = this.personN?.getBiologicalParents();
4377
- const inter = parents1?.intersection(parentsN);
4378
- if (!inter || inter.length < 2) {
4379
- return "f\xE9ltestv\xE9r";
4380
- }
4381
4570
  return "testv\xE9r";
4382
4571
  }
4572
+ halfBlood(relation) {
4573
+ if (!relation || !this.isHalfBlood) {
4574
+ return relation ?? "";
4575
+ }
4576
+ const [head, ...rest] = relation.split(" ");
4577
+ if (!head) {
4578
+ return relation;
4579
+ }
4580
+ const prefixed = this.prefixHalf(head);
4581
+ return [prefixed, ...rest].join(" ");
4582
+ }
4583
+ /**
4584
+ * AkH. 139: compounds of more than two members stay closed up to 6
4585
+ * syllables; longer ones are hyphenated at the main boundary. A head
4586
+ * that is already hyphenated also takes a hyphenated half- prefix.
4587
+ */
4588
+ prefixHalf(head) {
4589
+ if (head.includes("-") || !/[aáeéiíoóöőuúüű]/i.test(head)) {
4590
+ return `f\xE9l-${head}`;
4591
+ }
4592
+ const syllables = (head.match(/[aáeéiíoóöőuúüű]/gi) ?? []).length + 1;
4593
+ if (syllables > 6) {
4594
+ return `f\xE9l-${head}`;
4595
+ }
4596
+ return `f\xE9l${head}`;
4597
+ }
4383
4598
  spouse() {
4384
4599
  if (this.personN?.isMale()) {
4385
4600
  return "f\xE9rj";
@@ -4578,20 +4793,22 @@ var KinshipTranslatorEn = class extends KinshipTranslatorBasic {
4578
4793
  return `${prefix}child`;
4579
4794
  }
4580
4795
  sibling() {
4581
- const parents1 = this.person1?.getBiologicalParents();
4582
- const parentsN = this.personN?.getBiologicalParents();
4583
- const inter = parents1?.intersection(parentsN);
4584
- let prefix = "";
4585
- if (!inter || inter.length < 2) {
4586
- prefix = "half-";
4587
- }
4588
4796
  if (this.personN?.isMale()) {
4589
- return `${prefix}brother`;
4797
+ return "brother";
4590
4798
  }
4591
4799
  if (this.personN?.isFemale()) {
4592
- return `${prefix}sister`;
4800
+ return "sister";
4801
+ }
4802
+ return "sibling";
4803
+ }
4804
+ halfBlood(relation) {
4805
+ if (!relation || !this.isHalfBlood) {
4806
+ return relation ?? "";
4807
+ }
4808
+ if (relation.includes(" ")) {
4809
+ return `half ${relation}`;
4593
4810
  }
4594
- return `${prefix}sibling`;
4811
+ return `half-${relation}`;
4595
4812
  }
4596
4813
  spouse() {
4597
4814
  if (this.personN?.isMale()) {
@@ -4773,20 +4990,22 @@ var KinshipTranslatorDe = class extends KinshipTranslatorBasic {
4773
4990
  return `${prefix}kind`;
4774
4991
  }
4775
4992
  sibling() {
4776
- const parents1 = this.person1?.getBiologicalParents();
4777
- const parentsN = this.personN?.getBiologicalParents();
4778
- const inter = parents1?.intersection(parentsN);
4779
- let prefix = "";
4780
- if (!inter || inter.length < 2) {
4781
- prefix = "Halb";
4782
- }
4783
4993
  if (this.personN?.isMale()) {
4784
- return `${prefix}bruder`;
4994
+ return "bruder";
4785
4995
  }
4786
4996
  if (this.personN?.isFemale()) {
4787
- return `${prefix}schwester`;
4997
+ return "schwester";
4998
+ }
4999
+ return "geschwister";
5000
+ }
5001
+ halfBlood(relation) {
5002
+ if (!relation || !this.isHalfBlood) {
5003
+ return relation ?? "";
5004
+ }
5005
+ if (/^[A-ZÄÖÜ]/.test(relation) || /[-\s]/.test(relation)) {
5006
+ return `Halb-${relation}`;
4788
5007
  }
4789
- return `${prefix}geschwister`;
5008
+ return `Halb${relation}`;
4790
5009
  }
4791
5010
  spouse() {
4792
5011
  if (this.personN?.isMale()) {
@@ -4968,20 +5187,19 @@ var KinshipTranslatorFr = class extends KinshipTranslatorBasic {
4968
5187
  return `${prefix}enfant`;
4969
5188
  }
4970
5189
  sibling() {
4971
- const parents1 = this.person1?.getBiologicalParents();
4972
- const parentsN = this.personN?.getBiologicalParents();
4973
- const inter = parents1?.intersection(parentsN);
4974
- let prefix = "";
4975
- if (!inter || inter.length < 2) {
4976
- prefix = "demi-";
4977
- }
4978
5190
  if (this.personN?.isMale()) {
4979
- return `${prefix}fr\xE8re`;
5191
+ return "fr\xE8re";
4980
5192
  }
4981
5193
  if (this.personN?.isFemale()) {
4982
- return `${prefix}s\u0153ur`;
5194
+ return "s\u0153ur";
4983
5195
  }
4984
- return `${prefix}fr\xE8re/s\u0153ur`;
5196
+ return "fr\xE8re/s\u0153ur";
5197
+ }
5198
+ halfBlood(relation) {
5199
+ if (!relation || !this.isHalfBlood) {
5200
+ return relation ?? "";
5201
+ }
5202
+ return `demi-${relation}`;
4985
5203
  }
4986
5204
  spouse() {
4987
5205
  if (this.personN?.isMale()) {
@@ -5078,12 +5296,12 @@ var InLawsEs = {
5078
5296
  "madre del (c\xF3nyuge|esposa|esposo)": "suegra",
5079
5297
  "padre del (c\xF3nyuge|esposa|esposo)": "suegro",
5080
5298
  "padre/madre del (c\xF3nyuge|esposa|esposo)": "suegro/suegra",
5081
- "esposa de (medio )?(hermano/hermana|hermana|hermano)": "cu\xF1ada",
5082
- "esposo de (medio )?(hermano/hermana|hermana|hermano)": "cu\xF1ado",
5083
- "c\xF3nyuge de (medio )?(hermano/hermana|hermana|hermano)": "cu\xF1ado/cu\xF1ada",
5084
- "(medio )?hermana del (c\xF3nyuge|esposa|esposo)": "cu\xF1ada",
5085
- "(medio )?hermano del (c\xF3nyuge|esposa|esposo)": "cu\xF1ado",
5086
- "(medio )?hermano/hermana del (c\xF3nyuge|esposa|esposo)": "cu\xF1ado/cu\xF1ada"
5299
+ "esposa de (medio |media |medio/a )?(hermano/hermana|hermana|hermano)": "cu\xF1ada",
5300
+ "esposo de (medio |media |medio/a )?(hermano/hermana|hermana|hermano)": "cu\xF1ado",
5301
+ "c\xF3nyuge de (medio |media |medio/a )?(hermano/hermana|hermana|hermano)": "cu\xF1ado/cu\xF1ada",
5302
+ "(medio |media |medio/a )?hermana del (c\xF3nyuge|esposa|esposo)": "cu\xF1ada",
5303
+ "(medio |media |medio/a )?hermano del (c\xF3nyuge|esposa|esposo)": "cu\xF1ado",
5304
+ "(medio |media |medio/a )?hermano/hermana del (c\xF3nyuge|esposa|esposo)": "cu\xF1ado/cu\xF1ada"
5087
5305
  };
5088
5306
 
5089
5307
  // src/kinship-translator/kinship-translator.es.ts
@@ -5163,20 +5381,25 @@ var KinshipTranslatorEs = class extends KinshipTranslatorBasic {
5163
5381
  return `${prefix}hijo/hija`;
5164
5382
  }
5165
5383
  sibling() {
5166
- const parents1 = this.person1?.getBiologicalParents();
5167
- const parentsN = this.personN?.getBiologicalParents();
5168
- const inter = parents1?.intersection(parentsN);
5169
- let prefix = "";
5170
- if (!inter || inter.length < 2) {
5171
- prefix = "medio ";
5172
- }
5173
5384
  if (this.personN?.isMale()) {
5174
- return `${prefix}hermano`;
5385
+ return "hermano";
5175
5386
  }
5176
5387
  if (this.personN?.isFemale()) {
5177
- return `${prefix}hermana`;
5388
+ return "hermana";
5389
+ }
5390
+ return "hermano/hermana";
5391
+ }
5392
+ halfBlood(relation) {
5393
+ if (!relation || !this.isHalfBlood) {
5394
+ return relation ?? "";
5395
+ }
5396
+ if (this.personN?.isFemale()) {
5397
+ return `media ${relation}`;
5398
+ }
5399
+ if (this.personN?.isMale()) {
5400
+ return `medio ${relation}`;
5178
5401
  }
5179
- return `${prefix}hermano/hermana`;
5402
+ return `medio/a ${relation}`;
5180
5403
  }
5181
5404
  spouse() {
5182
5405
  if (this.personN?.isMale()) {
@@ -5358,6 +5581,7 @@ var KinshipTranslator = class {
5358
5581
  } else if (personN.level !== 0) {
5359
5582
  relation = this.removal();
5360
5583
  }
5584
+ relation = this.translator?.halfBlood(relation);
5361
5585
  relation = this.translator?.relationType(relation);
5362
5586
  if (this.translator?.isOfSpouse) {
5363
5587
  relation = this.translator?.ofSpouse(relation);
@@ -6694,7 +6918,7 @@ var Families = class _Families extends List {
6694
6918
  // package.json
6695
6919
  var package_default = {
6696
6920
  name: "@treeviz/gedcom-parser",
6697
- version: "2.0.8"};
6921
+ version: "2.0.9"};
6698
6922
 
6699
6923
  // src/utils/get-product-details.ts
6700
6924
  var isDevelopment = () => {
@@ -8031,4 +8255,4 @@ if (isDev) {
8031
8255
  }
8032
8256
  var parser_default = GedcomTree;
8033
8257
 
8034
- export { ACCEPTED_DATE_FORMATS, ACCEPTED_DATE_FORMATS_REGEX, ADOPTED, BIOLOGICAL, BIRTH, BIRTH_ASC, BIRTH_DESC, Common, CommonDate, CommonName, CommonNote, CustomTags, DATE_ASC, DATE_DESC, DEATH_ASC, DEATH_DESC, DEFAULT, EVERY, Existed, FEMALE, FOSTER, FRIEND, Fam, Families, GedCom, parser_default as GedcomTree, ID_GETTER_REG, ID_REG, ID_SPLIT_REG, Indi, Individuals, KinshipTranslator, KinshipTranslatorBasic, KinshipTranslatorDe as KinshipTranslatorDE, KinshipTranslatorEn as KinshipTranslatorEN, KinshipTranslatorEs as KinshipTranslatorES, KinshipTranslatorFr as KinshipTranslatorFR, KinshipTranslatorHU, LINE_REG, List, MALE, MAX_FILE_SIZE_TO_SYNC, OTHER, Obje, Objects, PARTNER, PartnerType, PlaceType, REF_LINE_REG, Range, RelationType, Repo, Repositories, SEALING, SINGLE, SPOUSE, STEP, Sour, Sources, Subm, Submitters, UNKOWN, commonDateFormatter, create, createCommon, createCommonDate, createCommonName, createCommonNote, createFam, createGedCom, createIndi, createObje, createProxy, createRepo, createSour, createSubm, dateFormatter, parser_default as default, extractSeparationYears, extractSplitPoints, findMatchingRangeForSplitRange, fromTuple, generateSplitRanges, getAllProp, getBirthAsc, getCacheManagerFactory, getDateLocale, getFamilyWith, getI18n, getKinshipTranslatorClass, getListTag, getMarriageAsc, getMarriageAscAndBirth, getMarriageAscAndChildBirth, getName, getNameAsc, getNameAscAndBirth, getNameDesc, getPlaceParserProvider, getPlaceParts, getPlaceTranslatorProvider, getPlaces, getRawSize, getValidKey, getValidKeys, getValidTag, getVersion, hungarianOrdinalize, i18n, idGetter, implemented, inRange, initializeCache, isCommonDate, isDevelopment, isGedcomString, isId, isIntersectedRange, isOnlyMainProp, isRangeContained, isValidKey, marriageDateFormatter, mergeGedcoms, nameFormatter, notImplemented, noteDateFormatter, ordinalize, parseRangeBounds, pathCache, placeTranslator, profilePictureCache, relativesCache, resetCacheManagerFactory, resetDateLocaleProvider, resetI18nProvider, resetKinshipTranslatorClass, resetPlaceParserProvider, resetPlaceTranslatorProvider, resetRelativesCache, setCacheManagerFactory, setDateLocaleProvider, setI18nProvider, setKinshipTranslatorClass, setNestedGroup, setPlaceParserProvider, setPlaceTranslatorProvider, splitOverlappingRanges, splitRange, translators_exports as translators, validateGedcomContent };
8258
+ export { ACCEPTED_DATE_FORMATS, ACCEPTED_DATE_FORMATS_REGEX, ADOPTED, BIOLOGICAL, BIRTH, BIRTH_ASC, BIRTH_DESC, Common, CommonDate, CommonName, CommonNote, CustomTags, DATE_ASC, DATE_DESC, DEATH_ASC, DEATH_DESC, DEFAULT, EVERY, Existed, FEMALE, FOSTER, FRIEND, Fam, Families, GedCom, parser_default as GedcomTree, ID_GETTER_REG, ID_REG, ID_SPLIT_REG, Indi, Individuals, KinshipTranslator, KinshipTranslatorBasic, KinshipTranslatorDe as KinshipTranslatorDE, KinshipTranslatorEn as KinshipTranslatorEN, KinshipTranslatorEs as KinshipTranslatorES, KinshipTranslatorFr as KinshipTranslatorFR, KinshipTranslatorHU, LINE_REG, List, MALE, MAX_FILE_SIZE_TO_SYNC, OTHER, Obje, Objects, PARTNER, PartnerType, PlaceType, REF_LINE_REG, Range, RelationType, Repo, Repositories, SEALING, SINGLE, SPOUSE, STEP, Sour, Sources, Subm, Submitters, UNKOWN, cacheDiscoveredPath, commonDateFormatter, create, createCommon, createCommonDate, createCommonName, createCommonNote, createFam, createGedCom, createIndi, createObje, createProxy, createRepo, createSour, createSubm, dateFormatter, parser_default as default, extractSeparationYears, extractSplitPoints, findMatchingRangeForSplitRange, fromTuple, generateSplitRanges, getAllProp, getBirthAsc, getCacheManagerFactory, getDateLocale, getFamilyWith, getI18n, getKinshipTranslatorClass, getListTag, getMarriageAsc, getMarriageAscAndBirth, getMarriageAscAndChildBirth, getName, getNameAsc, getNameAscAndBirth, getNameDesc, getPlaceParserProvider, getPlaceParts, getPlaceTranslatorProvider, getPlaces, getRawSize, getValidKey, getValidKeys, getValidTag, getVersion, hungarianOrdinalize, i18n, idGetter, implemented, inRange, initializeCache, isCommonDate, isDevelopment, isGedcomString, isId, isIntersectedRange, isOnlyMainProp, isRangeContained, isValidKey, marriageDateFormatter, mergeGedcoms, nameFormatter, notImplemented, noteDateFormatter, ordinalize, parseRangeBounds, pathCache, placeTranslator, profilePictureCache, relativesCache, resetCacheManagerFactory, resetDateLocaleProvider, resetI18nProvider, resetKinshipTranslatorClass, resetPlaceParserProvider, resetPlaceTranslatorProvider, resetRelativesCache, setCacheManagerFactory, setDateLocaleProvider, setI18nProvider, setKinshipTranslatorClass, setNestedGroup, setPlaceParserProvider, setPlaceTranslatorProvider, splitOverlappingRanges, splitRange, translators_exports as translators, validateGedcomContent };