@treeviz/gedcom-parser 2.1.8 → 2.1.11

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 (35) 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 +588 -75
  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 +588 -75
  8. package/dist/constants/index.js +557 -70
  9. package/dist/factories/index.js +557 -70
  10. package/dist/index.js +593 -85
  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.d.ts +2 -0
  14. package/dist/kinship-translator/index.d.ts.map +1 -1
  15. package/dist/kinship-translator/index.js +558 -71
  16. package/dist/kinship-translator/kinship-translator.ja.d.ts +18 -0
  17. package/dist/kinship-translator/kinship-translator.ja.d.ts.map +1 -0
  18. package/dist/kinship-translator/kinship-translator.zh.d.ts +18 -0
  19. package/dist/kinship-translator/kinship-translator.zh.d.ts.map +1 -0
  20. package/dist/kinship-translator/patterns.ja.d.ts +2 -0
  21. package/dist/kinship-translator/patterns.ja.d.ts.map +1 -0
  22. package/dist/kinship-translator/patterns.zh.d.ts +2 -0
  23. package/dist/kinship-translator/patterns.zh.d.ts.map +1 -0
  24. package/dist/kinship-translator/translators.d.ts +2 -0
  25. package/dist/kinship-translator/translators.d.ts.map +1 -1
  26. package/dist/kinship-translator/types.d.ts +1 -1
  27. package/dist/kinship-translator/types.d.ts.map +1 -1
  28. package/dist/utils/cache.d.ts.map +1 -1
  29. package/dist/utils/gedzip.d.ts.map +1 -1
  30. package/dist/utils/index.js +593 -85
  31. package/dist/utils/local-media.d.ts +7 -3
  32. package/dist/utils/local-media.d.ts.map +1 -1
  33. package/dist/utils/media-utils.d.ts +20 -0
  34. package/dist/utils/media-utils.d.ts.map +1 -1
  35. package/package.json +1 -1
@@ -64,7 +64,9 @@ __export(translators_exports, {
64
64
  es: () => KinshipTranslatorEs,
65
65
  fr: () => KinshipTranslatorFr,
66
66
  hu: () => KinshipTranslatorHU,
67
- ru: () => KinshipTranslatorRu
67
+ ja: () => KinshipTranslatorJa,
68
+ ru: () => KinshipTranslatorRu,
69
+ zh: () => KinshipTranslatorZh
68
70
  });
69
71
 
70
72
  // src/constants/filters.ts
@@ -348,6 +350,82 @@ var ORIG_HEAD_TAG = "_ORIGHEAD";
348
350
  // src/utils/gedcom-trailer.ts
349
351
  var GEDCOM_TRAILER_TAG = "TRLR";
350
352
  var isGedcomTrailerTag = (tag) => tag === GEDCOM_TRAILER_TAG;
353
+
354
+ // src/utils/media-utils.ts
355
+ var getFileExtension = (filename) => {
356
+ if (!filename) {
357
+ return "";
358
+ }
359
+ if (filename.startsWith("data:")) {
360
+ const mime = filename.slice(5).split(";")[0] || "";
361
+ const subtype = (mime.split("/")[1] || "").toLowerCase();
362
+ if (subtype === "jpeg") {
363
+ return "jpg";
364
+ }
365
+ return subtype.split("+")[0] || "";
366
+ }
367
+ const withoutQuery = filename.split(/[?#]/)[0] || filename;
368
+ const match = withoutQuery.match(/\.([^.]+)$/);
369
+ return match ? match[1].toLowerCase() : "";
370
+ };
371
+ var isImageFormat = (format2) => {
372
+ if (!format2) {
373
+ return false;
374
+ }
375
+ let normalized = format2.toLowerCase().trim();
376
+ if (normalized.startsWith("data:")) {
377
+ normalized = getFileExtension(normalized);
378
+ } else if (normalized.includes("/")) {
379
+ normalized = normalized.split("/")[1]?.split("+")[0] || "";
380
+ if (normalized === "jpeg") {
381
+ normalized = "jpg";
382
+ }
383
+ }
384
+ const imageFormats = [
385
+ "jpg",
386
+ "jpeg",
387
+ "png",
388
+ "gif",
389
+ "bmp",
390
+ "webp",
391
+ "svg",
392
+ "tiff",
393
+ "tif"
394
+ ];
395
+ return imageFormats.includes(normalized);
396
+ };
397
+ var resolveObjeForm = (obje) => {
398
+ const value = obje?.get?.("FILE.FORM")?.toValue?.() ?? obje?.get?.("FORM")?.toValue?.();
399
+ return typeof value === "string" && value.trim() ? value.trim() : void 0;
400
+ };
401
+ var mediaIdValue = (obje, path) => {
402
+ const value = obje?.get?.(path)?.toValue?.();
403
+ return typeof value === "string" && value.trim() ? value.trim() : void 0;
404
+ };
405
+ var resolveObjeMediaId = (obje) => mediaIdValue(obje, "RIN") || mediaIdValue(obje, "_CLON._OID") || mediaIdValue(obje, "_MSER._LKID") || mediaIdValue(obje, "_OID") || mediaIdValue(obje, "_LKID");
406
+ var ANCESTRY_MEDIA_RETRIEVAL_PREFIX = "https://www.ancestry.com/api/media/retrieval/v2/image";
407
+ var ANCESTRY_MEDIA_QUERY = "client=trees-mediaservice&imageQuality=hq";
408
+ var ancestryMediaPath = (namespace, imgId) => `/namespaces/${namespace}/media/${imgId}?${ANCESTRY_MEDIA_QUERY}`;
409
+ var ancestryMediaFileUrl = (namespace, imgId) => {
410
+ if (!namespace || !imgId) {
411
+ return void 0;
412
+ }
413
+ return `${ANCESTRY_MEDIA_RETRIEVAL_PREFIX}${ancestryMediaPath(namespace, imgId)}`;
414
+ };
415
+ var objeXrefKey = (obje, fallback = 0) => {
416
+ if (typeof obje?.id === "string" && obje.id) {
417
+ return obje.id;
418
+ }
419
+ const value = obje?.toValue?.();
420
+ if (typeof value === "string" && value.trim()) {
421
+ return value.trim();
422
+ }
423
+ if (typeof fallback === "string" && fallback.trim()) {
424
+ return fallback.trim();
425
+ }
426
+ return `@O${fallback}@`;
427
+ };
428
+ var objeNoteValue = (obje) => mediaIdValue(obje, "FILE.NOTE") || mediaIdValue(obje, "NOTE") || "";
351
429
  var List = class _List {
352
430
  // length = 0;
353
431
  constructor(items) {
@@ -997,7 +1075,7 @@ var Common = class _Common {
997
1075
  this,
998
1076
  options.obje.namespace,
999
1077
  options.obje.override,
1000
- void 0,
1078
+ this.isAncestry() ? ancestryMediaFileUrl : void 0,
1001
1079
  options.gedcomVersion
1002
1080
  );
1003
1081
  }
@@ -1928,11 +2006,8 @@ var storeCache = {
1928
2006
  getCacheDbs().relativesOnDegreeCache.setItem(value);
1929
2007
  }
1930
2008
  }, 50),
1931
- // profilePictureCache IS persisted to IndexedDB
2009
+ // Image bytes are stored as one IndexedDB record per photo.
1932
2010
  profilePictureCache: debounce((value) => {
1933
- if (value) {
1934
- getCacheDbs().profilePictureCache.setItem(value);
1935
- }
1936
2011
  }, 100)
1937
2012
  };
1938
2013
  var resetRelativesCache = () => {
@@ -2619,65 +2694,23 @@ var isRemoteOrEmbeddedMediaUrl = (path) => {
2619
2694
  }
2620
2695
  return path.startsWith("data:") || path.startsWith("blob:") || /^https?:\/\//i.test(path);
2621
2696
  };
2622
- var resolveLocalMediaUrl = async (path) => {
2697
+ var resolveLocalMediaUrl = async (path, context) => {
2623
2698
  if (!path) {
2624
2699
  return void 0;
2625
2700
  }
2626
- if (isRemoteOrEmbeddedMediaUrl(path)) {
2701
+ if (path.startsWith("data:") || path.startsWith("blob:")) {
2627
2702
  return path;
2628
2703
  }
2629
- const resolved = await localMediaResolver?.(path);
2630
- return resolved;
2631
- };
2632
- var implemented = (type, ...args) => {
2633
- };
2634
-
2635
- // src/utils/media-utils.ts
2636
- var getFileExtension = (filename) => {
2637
- if (!filename) {
2638
- return "";
2639
- }
2640
- if (filename.startsWith("data:")) {
2641
- const mime = filename.slice(5).split(";")[0] || "";
2642
- const subtype = (mime.split("/")[1] || "").toLowerCase();
2643
- if (subtype === "jpeg") {
2644
- return "jpg";
2645
- }
2646
- return subtype.split("+")[0] || "";
2647
- }
2648
- const withoutQuery = filename.split(/[?#]/)[0] || filename;
2649
- const match = withoutQuery.match(/\.([^.]+)$/);
2650
- return match ? match[1].toLowerCase() : "";
2651
- };
2652
- var isImageFormat = (format2) => {
2653
- if (!format2) {
2654
- return false;
2704
+ const resolved = await localMediaResolver?.(path, context);
2705
+ if (resolved) {
2706
+ return resolved;
2655
2707
  }
2656
- let normalized = format2.toLowerCase().trim();
2657
- if (normalized.startsWith("data:")) {
2658
- normalized = getFileExtension(normalized);
2659
- } else if (normalized.includes("/")) {
2660
- normalized = normalized.split("/")[1]?.split("+")[0] || "";
2661
- if (normalized === "jpeg") {
2662
- normalized = "jpg";
2663
- }
2708
+ if (/^https?:\/\//i.test(path)) {
2709
+ return path;
2664
2710
  }
2665
- const imageFormats = [
2666
- "jpg",
2667
- "jpeg",
2668
- "png",
2669
- "gif",
2670
- "bmp",
2671
- "webp",
2672
- "svg",
2673
- "tiff",
2674
- "tif"
2675
- ];
2676
- return imageFormats.includes(normalized);
2711
+ return void 0;
2677
2712
  };
2678
- var resolveObjeForm = (obje) => {
2679
- const value = obje?.get?.("FILE.FORM")?.toValue?.() ?? obje?.get?.("FORM")?.toValue?.();
2680
- return typeof value === "string" && value.trim() ? value.trim() : void 0;
2713
+ var implemented = (type, ...args) => {
2681
2714
  };
2682
2715
 
2683
2716
  // src/factories/place-parser-provider.ts
@@ -3983,22 +4016,19 @@ var Indi = class extends Common {
3983
4016
  if (objeList) {
3984
4017
  await Promise.all(
3985
4018
  objeList.map(async (objeRef) => {
3986
- const key = objeRef?.id;
4019
+ const key = objeXrefKey(objeRef, 0);
3987
4020
  const obje = objeRef?.standardizeMedia(
3988
4021
  namespace,
3989
4022
  true,
3990
- (ns, iId) => {
3991
- return ns && iId ? `https://mediasvc.ancestry.com/v2/image/namespaces/${ns}/media/${iId}?client=trees-mediaservice&imageQuality=hq` : void 0;
3992
- }
4023
+ ancestryMediaFileUrl
3993
4024
  );
3994
4025
  const isPrimary = obje?.get("_PRIM")?.toValue() === "Y";
3995
- const media = obje?.RIN?.toValue() || obje?.get("_OID")?.toValue();
3996
- const clone = obje?.get("_CLON._OID")?.toValue();
3997
- const mser = obje?.get("_MSER._LKID")?.toValue();
4026
+ const media = resolveObjeMediaId(obje);
3998
4027
  let url = obje?.get("FILE")?.toValue();
3999
4028
  const title = obje?.get("FILE.TITL")?.toValue() ?? obje?.get("TITL")?.toValue() ?? "";
4029
+ const note = objeNoteValue(obje);
4000
4030
  const type = resolveObjeForm(obje) ?? (url ? getFileExtension(url) : void 0) ?? "raw";
4001
- let imgId = clone || mser;
4031
+ let imgId = media;
4002
4032
  const hasEmbeddedOrLocalFile = !!url && (url.startsWith("data:") || url.startsWith("blob:") || !/^https?:\/\//i.test(url));
4003
4033
  if (!hasEmbeddedOrLocalFile && (!www || !tree || !this.id)) {
4004
4034
  return;
@@ -4034,6 +4064,7 @@ var Indi = class extends Common {
4034
4064
  imgId,
4035
4065
  person: this.id,
4036
4066
  title,
4067
+ note,
4037
4068
  url,
4038
4069
  contentType: type,
4039
4070
  downloadName: `${this.id.replaceAll("@", "")}_${this.toNaturalName()?.replaceAll(" ", "-") || ""}_${(title || key.replaceAll("@", "").toString()).replaceAll(" ", "-")}`
@@ -4072,7 +4103,7 @@ var Indi = class extends Common {
4072
4103
  return;
4073
4104
  }
4074
4105
  const obje = o;
4075
- const key = `@O${index}@`;
4106
+ const key = objeXrefKey(obje, index);
4076
4107
  obje.standardizeMedia();
4077
4108
  const isPrimary = obje?.get("_PRIM")?.toValue() === "Y";
4078
4109
  const url = obje?.get("FILE")?.toValue();
@@ -4091,6 +4122,7 @@ var Indi = class extends Common {
4091
4122
  imgId,
4092
4123
  person: this.id,
4093
4124
  title,
4125
+ note: objeNoteValue(obje),
4094
4126
  url,
4095
4127
  contentType: type,
4096
4128
  downloadName: `${this.id.replaceAll("@", "")}_${this.toNaturalName()?.replaceAll(" ", "-") || ""}_${(title || key.replaceAll("@", "").toString()).replaceAll(" ", "-")}`
@@ -4199,7 +4231,7 @@ var Indi = class extends Common {
4199
4231
  if (!obje) {
4200
4232
  return;
4201
4233
  }
4202
- const key = `@O${index}@`;
4234
+ const key = objeXrefKey(obje, index);
4203
4235
  const isPrimary = obje?.get("_PRIM")?.toValue() === "Y";
4204
4236
  const url = obje?.get("FILE")?.toValue();
4205
4237
  const title = obje?.get("TITL")?.toValue() ?? "";
@@ -4216,6 +4248,7 @@ var Indi = class extends Common {
4216
4248
  imgId,
4217
4249
  person: this.id,
4218
4250
  title,
4251
+ note: objeNoteValue(obje),
4219
4252
  url,
4220
4253
  contentType: type,
4221
4254
  downloadName: `${this.id.replaceAll("@", "")}_${this.toNaturalName()?.replaceAll(" ", "-") || ""}_${(title || key.replaceAll("@", "").toString()).replaceAll(" ", "-")}`
@@ -4239,7 +4272,7 @@ var Indi = class extends Common {
4239
4272
  if (!obje) {
4240
4273
  return;
4241
4274
  }
4242
- const key = `@O${index}@`;
4275
+ const key = objeXrefKey(obje, index);
4243
4276
  obje.standardizeMedia();
4244
4277
  const isPrimary = obje?.get("_PRIM")?.toValue() === "Y";
4245
4278
  const url = obje?.get("FILE")?.toValue();
@@ -4256,6 +4289,7 @@ var Indi = class extends Common {
4256
4289
  imgId,
4257
4290
  person: this.id,
4258
4291
  title,
4292
+ note: objeNoteValue(obje),
4259
4293
  url,
4260
4294
  contentType: type,
4261
4295
  downloadName: `${this.id.replaceAll("@", "")}_${this.toNaturalName()?.replaceAll(" ", "-") || ""}_${(title || key.replaceAll("@", "").toString()).replaceAll(" ", "-")}`
@@ -4287,7 +4321,12 @@ var Indi = class extends Common {
4287
4321
  );
4288
4322
  if (cached !== void 0) {
4289
4323
  if (cached?.file && !isRemoteOrEmbeddedMediaUrl(cached.file)) {
4290
- const resolvedCached = await resolveLocalMediaUrl(cached.file);
4324
+ const resolvedCached = await resolveLocalMediaUrl(cached.file, {
4325
+ url: cached.file,
4326
+ person: this.id,
4327
+ tree: this.getTreeId?.(),
4328
+ treeName: this.getTreeName?.()
4329
+ });
4291
4330
  if (resolvedCached && isRemoteOrEmbeddedMediaUrl(resolvedCached)) {
4292
4331
  const refreshed = { ...cached, file: resolvedCached };
4293
4332
  profilePictureCache(
@@ -4312,7 +4351,16 @@ var Indi = class extends Common {
4312
4351
  }
4313
4352
  const mediaArray = Object.values(mediaList);
4314
4353
  const toDisplayableProfile = async (media, isPrimary) => {
4315
- const resolvedFile = await resolveLocalMediaUrl(media.url);
4354
+ const resolvedFile = await resolveLocalMediaUrl(media.url, {
4355
+ url: media.url,
4356
+ id: media.id,
4357
+ imgId: media.imgId,
4358
+ key: media.key,
4359
+ contentType: media.contentType,
4360
+ person: media.person || this.id,
4361
+ tree: media.tree || this.getTreeId?.(),
4362
+ treeName: this.getTreeName?.()
4363
+ });
4316
4364
  if (!resolvedFile || !isRemoteOrEmbeddedMediaUrl(resolvedFile)) {
4317
4365
  return void 0;
4318
4366
  }
@@ -7500,6 +7548,445 @@ var KinshipTranslatorRu = class extends KinshipTranslatorBasic {
7500
7548
  }
7501
7549
  };
7502
7550
 
7551
+ // src/kinship-translator/patterns.ja.ts
7552
+ var InLawsJa = {
7553
+ "(\u5B50|\u5A18|\u606F\u5B50)\u306E\u914D\u5076\u8005": "\u7FA9\u7406\u306E\u5B50",
7554
+ "(\u5B50|\u5A18|\u606F\u5B50)\u306E\u59BB": "\u5AC1",
7555
+ "(\u5B50|\u5A18|\u606F\u5B50)\u306E\u592B": "\u5A7F",
7556
+ "(\u914D\u5076\u8005|\u59BB|\u592B)\u306E\u6BCD": "\u7FA9\u6BCD",
7557
+ "(\u914D\u5076\u8005|\u59BB|\u592B)\u306E\u7236": "\u7FA9\u7236",
7558
+ "(\u914D\u5076\u8005|\u59BB|\u592B)\u306E\u89AA": "\u7FA9\u7406\u306E\u89AA",
7559
+ "(\u7570\u7236\u6BCD\u306E)?(\u5144\u5F1F|\u59C9\u59B9|\u5144\u5F1F\u59C9\u59B9)\u306E\u59BB": "\u7FA9\u7406\u306E\u59C9\u59B9",
7560
+ "(\u7570\u7236\u6BCD\u306E)?(\u5144\u5F1F|\u59C9\u59B9|\u5144\u5F1F\u59C9\u59B9)\u306E\u592B": "\u7FA9\u7406\u306E\u5144\u5F1F",
7561
+ "(\u7570\u7236\u6BCD\u306E)?(\u5144\u5F1F|\u59C9\u59B9|\u5144\u5F1F\u59C9\u59B9)\u306E\u914D\u5076\u8005": "\u7FA9\u7406\u306E\u5144\u5F1F\u59C9\u59B9",
7562
+ "(\u7570\u7236\u6BCD\u306E)?\u59C9\u59B9\u306E(\u914D\u5076\u8005|\u59BB|\u592B)": "\u7FA9\u7406\u306E\u59C9\u59B9",
7563
+ "(\u7570\u7236\u6BCD\u306E)?\u5144\u5F1F\u306E(\u914D\u5076\u8005|\u59BB|\u592B)": "\u7FA9\u7406\u306E\u5144\u5F1F",
7564
+ "(\u7570\u7236\u6BCD\u306E)?\u5144\u5F1F\u59C9\u59B9\u306E(\u914D\u5076\u8005|\u59BB|\u592B)": "\u7FA9\u7406\u306E\u5144\u5F1F\u59C9\u59B9",
7565
+ "(\u7570\u7236\u6BCD\u306E)?(\u914D\u5076\u8005|\u59BB|\u592B)\u306E\u59C9\u59B9": "\u7FA9\u7406\u306E\u59C9\u59B9",
7566
+ "(\u7570\u7236\u6BCD\u306E)?(\u914D\u5076\u8005|\u59BB|\u592B)\u306E\u5144\u5F1F": "\u7FA9\u7406\u306E\u5144\u5F1F",
7567
+ "(\u7570\u7236\u6BCD\u306E)?(\u914D\u5076\u8005|\u59BB|\u592B)\u306E\u5144\u5F1F\u59C9\u59B9": "\u7FA9\u7406\u306E\u5144\u5F1F\u59C9\u59B9"
7568
+ };
7569
+
7570
+ // src/kinship-translator/kinship-translator.ja.ts
7571
+ var sexOf2 = (person) => {
7572
+ if (person?.isMale?.()) {
7573
+ return "m";
7574
+ }
7575
+ if (person?.isFemale?.()) {
7576
+ return "f";
7577
+ }
7578
+ return "n";
7579
+ };
7580
+ var pick = (sex, male, female, neutral) => {
7581
+ if (sex === "m") {
7582
+ return male;
7583
+ }
7584
+ if (sex === "f") {
7585
+ return female;
7586
+ }
7587
+ return neutral;
7588
+ };
7589
+ var lineal = (level, sex, kind) => {
7590
+ const L = Math.max(1, level);
7591
+ if (kind === "asc") {
7592
+ if (L <= 1) {
7593
+ return pick(sex, "\u7236", "\u6BCD", "\u89AA");
7594
+ }
7595
+ if (L === 2) {
7596
+ return pick(sex, "\u7956\u7236", "\u7956\u6BCD", "\u7956\u7236\u6BCD");
7597
+ }
7598
+ if (L === 3) {
7599
+ return pick(sex, "\u66FE\u7956\u7236", "\u66FE\u7956\u6BCD", "\u66FE\u7956\u7236\u6BCD");
7600
+ }
7601
+ if (L === 4) {
7602
+ return pick(sex, "\u9AD8\u7956\u7236", "\u9AD8\u7956\u6BCD", "\u9AD8\u7956\u7236\u6BCD");
7603
+ }
7604
+ return pick(
7605
+ sex,
7606
+ `${L - 1}\u4E16\u306E\u7956\u7236`,
7607
+ `${L - 1}\u4E16\u306E\u7956\u6BCD`,
7608
+ `${L - 1}\u4E16\u306E\u7956\u7236\u6BCD`
7609
+ );
7610
+ }
7611
+ if (L <= 1) {
7612
+ return pick(sex, "\u606F\u5B50", "\u5A18", "\u5B50");
7613
+ }
7614
+ if (L === 2) {
7615
+ return "\u5B6B";
7616
+ }
7617
+ if (L === 3) {
7618
+ return "\u66FE\u5B6B";
7619
+ }
7620
+ if (L === 4) {
7621
+ return "\u7384\u5B6B";
7622
+ }
7623
+ return `${L - 1}\u4E16\u306E\u5B6B`;
7624
+ };
7625
+ var cousinPlain = (degree) => {
7626
+ if (degree <= 1) {
7627
+ return "\u3044\u3068\u3053";
7628
+ }
7629
+ if (degree === 2) {
7630
+ return "\u307E\u305F\u3044\u3068\u3053";
7631
+ }
7632
+ if (degree === 3) {
7633
+ return "\u306F\u3068\u3053";
7634
+ }
7635
+ return `${degree}\u89AA\u7B49\u306E\u3044\u3068\u3053`;
7636
+ };
7637
+ var KinshipTranslatorJa = class extends KinshipTranslatorBasic {
7638
+ indirect() {
7639
+ let degree = Math.abs(this.pathN?.degree ?? 0);
7640
+ if (degree > 0) {
7641
+ degree = degree - 1;
7642
+ }
7643
+ return cousinPlain(degree);
7644
+ }
7645
+ removal() {
7646
+ const level = this.pathN?.level ?? 0;
7647
+ let degree = Math.abs(this.pathN?.degree ?? 0);
7648
+ if (degree > 0) {
7649
+ degree = degree - 1;
7650
+ }
7651
+ if (!degree) {
7652
+ return level < 0 ? this.nibling() : this.auncle();
7653
+ }
7654
+ const removed = Math.abs(level);
7655
+ return `${cousinPlain(degree)}\uFF08${removed}\u4E16\u4EE3\u9055\u3044\uFF09`;
7656
+ }
7657
+ auncle() {
7658
+ const level = Math.abs(this.pathN?.level ?? 0);
7659
+ const sex = sexOf2(this.personN);
7660
+ if (level <= 2) {
7661
+ return pick(sex, "\u304A\u3058", "\u304A\u3070", "\u304A\u3058/\u304A\u3070");
7662
+ }
7663
+ if (level === 3) {
7664
+ return pick(sex, "\u5927\u304A\u3058", "\u5927\u304A\u3070", "\u5927\u304A\u3058/\u5927\u304A\u3070");
7665
+ }
7666
+ return pick(
7667
+ sex,
7668
+ `${level - 2}\u4EE3\u524D\u306E\u304A\u3058`,
7669
+ `${level - 2}\u4EE3\u524D\u306E\u304A\u3070`,
7670
+ `${level - 2}\u4EE3\u524D\u306E\u304A\u3058/\u304A\u3070`
7671
+ );
7672
+ }
7673
+ nibling() {
7674
+ const level = Math.abs(this.pathN?.level ?? 0);
7675
+ const sex = sexOf2(this.personN);
7676
+ if (level <= 2) {
7677
+ return pick(sex, "\u7525", "\u59EA", "\u7525/\u59EA");
7678
+ }
7679
+ if (level === 3) {
7680
+ return pick(sex, "\u5927\u7525", "\u5927\u59EA", "\u5927\u7525/\u5927\u59EA");
7681
+ }
7682
+ return pick(
7683
+ sex,
7684
+ `${level - 2}\u4EE3\u4E0B\u306E\u7525`,
7685
+ `${level - 2}\u4EE3\u4E0B\u306E\u59EA`,
7686
+ `${level - 2}\u4EE3\u4E0B\u306E\u7525/\u59EA`
7687
+ );
7688
+ }
7689
+ parent() {
7690
+ return lineal(
7691
+ Math.abs(this.pathN?.level ?? 0),
7692
+ sexOf2(this.personN),
7693
+ "asc"
7694
+ );
7695
+ }
7696
+ child() {
7697
+ return lineal(
7698
+ Math.abs(this.pathN?.level ?? 0),
7699
+ sexOf2(this.personN),
7700
+ "desc"
7701
+ );
7702
+ }
7703
+ sibling() {
7704
+ return pick(sexOf2(this.personN), "\u5144\u5F1F", "\u59C9\u59B9", "\u5144\u5F1F\u59C9\u59B9");
7705
+ }
7706
+ halfBlood(relation) {
7707
+ if (!relation || !this.isHalfBlood) {
7708
+ return relation ?? "";
7709
+ }
7710
+ return `\u7570\u7236\u6BCD\u306E${relation}`;
7711
+ }
7712
+ spouse() {
7713
+ return pick(sexOf2(this.personN), "\u592B", "\u59BB", "\u914D\u5076\u8005");
7714
+ }
7715
+ ofSpouse(relation) {
7716
+ if (!relation) {
7717
+ return "";
7718
+ }
7719
+ const spouseType = pick(
7720
+ sexOf2(this.path?.[1].indi),
7721
+ "\u592B",
7722
+ "\u59BB",
7723
+ "\u914D\u5076\u8005"
7724
+ );
7725
+ return `${spouseType}\u306E${relation}`;
7726
+ }
7727
+ spouseOf(relation) {
7728
+ if (!relation) {
7729
+ return "";
7730
+ }
7731
+ const spouse = this.path?.[this.path.length - 1].indi;
7732
+ const spouseType = pick(sexOf2(spouse), "\u592B", "\u59BB", "\u914D\u5076\u8005");
7733
+ return `${relation}\u306E${spouseType}`;
7734
+ }
7735
+ of(relation) {
7736
+ const formattedName = nameFormatter(this.path?.[0]?.indi, {
7737
+ nameOrder: "last-first"
7738
+ });
7739
+ let name = formattedName.inOrder.filter(Boolean).join(" ");
7740
+ if (this.displayName === "none") {
7741
+ name = "";
7742
+ } else if (this.displayName === "givenname") {
7743
+ name = formattedName.givenname;
7744
+ } else if (this.displayName === "surname") {
7745
+ name = `${formattedName.surname}`;
7746
+ }
7747
+ if (!name || !relation) {
7748
+ return relation ?? "";
7749
+ }
7750
+ return `${name}\u306E${relation}`;
7751
+ }
7752
+ inLaw(relation) {
7753
+ let inLawRelation = relation;
7754
+ Object.keys(InLawsJa).find((pattern) => {
7755
+ const regex = new RegExp(`^${pattern}$`);
7756
+ if (relation?.match(regex)) {
7757
+ inLawRelation = InLawsJa[pattern];
7758
+ return true;
7759
+ }
7760
+ return false;
7761
+ });
7762
+ return inLawRelation ?? "";
7763
+ }
7764
+ relationType(relation) {
7765
+ if (!relation || !this.pathN?.relation) {
7766
+ return relation ?? "";
7767
+ }
7768
+ return `${this.pathN.relation}\u306E${relation}`;
7769
+ }
7770
+ };
7771
+
7772
+ // src/kinship-translator/patterns.zh.ts
7773
+ var InLawsZh = {
7774
+ "(\u5B50\u5973|\u5973\u513F|\u513F\u5B50)\u7684\u914D\u5076": "\u513F\u5AB3/\u5973\u5A7F",
7775
+ "(\u5B50\u5973|\u5973\u513F|\u513F\u5B50)\u7684\u59BB\u5B50": "\u513F\u5AB3",
7776
+ "(\u5B50\u5973|\u5973\u513F|\u513F\u5B50)\u7684\u4E08\u592B": "\u5973\u5A7F",
7777
+ "(\u914D\u5076|\u59BB\u5B50|\u4E08\u592B)\u7684\u6BCD\u4EB2": "\u5CB3\u6BCD/\u5A46\u5A46",
7778
+ "(\u914D\u5076|\u59BB\u5B50|\u4E08\u592B)\u7684\u7236\u4EB2": "\u5CB3\u7236/\u516C\u516C",
7779
+ "(\u914D\u5076|\u59BB\u5B50|\u4E08\u592B)\u7684\u7236\u6BCD": "\u5CB3\u7236\u5CB3\u6BCD/\u516C\u516C\u5A46\u5A46",
7780
+ "(\u5F02\u7236\u6BCD\u7684)?(\u5144\u5F1F\u59D0\u59B9|\u59D0\u59B9|\u5144\u5F1F)\u7684\u59BB\u5B50": "\u5AC2\u5B50/\u5F1F\u59B9",
7781
+ "(\u5F02\u7236\u6BCD\u7684)?(\u5144\u5F1F\u59D0\u59B9|\u59D0\u59B9|\u5144\u5F1F)\u7684\u4E08\u592B": "\u59D0\u592B/\u59B9\u592B",
7782
+ "(\u5F02\u7236\u6BCD\u7684)?(\u5144\u5F1F\u59D0\u59B9|\u59D0\u59B9|\u5144\u5F1F)\u7684\u914D\u5076": "\u59FB\u4EB2\u5144\u5F1F\u59D0\u59B9",
7783
+ "(\u5F02\u7236\u6BCD\u7684)?\u59D0\u59B9\u7684(\u914D\u5076|\u59BB\u5B50|\u4E08\u592B)": "\u59D0\u592B/\u59B9\u592B",
7784
+ "(\u5F02\u7236\u6BCD\u7684)?\u5144\u5F1F\u7684(\u914D\u5076|\u59BB\u5B50|\u4E08\u592B)": "\u5AC2\u5B50/\u5F1F\u59B9",
7785
+ "(\u5F02\u7236\u6BCD\u7684)?\u5144\u5F1F\u59D0\u59B9\u7684(\u914D\u5076|\u59BB\u5B50|\u4E08\u592B)": "\u59FB\u4EB2\u5144\u5F1F\u59D0\u59B9",
7786
+ "(\u5F02\u7236\u6BCD\u7684)?(\u914D\u5076|\u59BB\u5B50|\u4E08\u592B)\u7684\u59D0\u59B9": "\u59D1\u5B50/\u59E8\u5B50",
7787
+ "(\u5F02\u7236\u6BCD\u7684)?(\u914D\u5076|\u59BB\u5B50|\u4E08\u592B)\u7684\u5144\u5F1F": "\u5927\u4F2F/\u5C0F\u53D4/\u5185\u5144/\u5185\u5F1F",
7788
+ "(\u5F02\u7236\u6BCD\u7684)?(\u914D\u5076|\u59BB\u5B50|\u4E08\u592B)\u7684\u5144\u5F1F\u59D0\u59B9": "\u59FB\u4EB2\u5144\u5F1F\u59D0\u59B9"
7789
+ };
7790
+
7791
+ // src/kinship-translator/kinship-translator.zh.ts
7792
+ var sexOf3 = (person) => {
7793
+ if (person?.isMale?.()) {
7794
+ return "m";
7795
+ }
7796
+ if (person?.isFemale?.()) {
7797
+ return "f";
7798
+ }
7799
+ return "n";
7800
+ };
7801
+ var pick2 = (sex, male, female, neutral) => {
7802
+ if (sex === "m") {
7803
+ return male;
7804
+ }
7805
+ if (sex === "f") {
7806
+ return female;
7807
+ }
7808
+ return neutral;
7809
+ };
7810
+ var lineal2 = (level, sex, kind) => {
7811
+ const L = Math.max(1, level);
7812
+ if (kind === "asc") {
7813
+ if (L <= 1) {
7814
+ return pick2(sex, "\u7236\u4EB2", "\u6BCD\u4EB2", "\u7236\u6BCD");
7815
+ }
7816
+ if (L === 2) {
7817
+ return pick2(sex, "\u7956\u7236", "\u7956\u6BCD", "\u7956\u7236\u6BCD");
7818
+ }
7819
+ if (L === 3) {
7820
+ return pick2(sex, "\u66FE\u7956\u7236", "\u66FE\u7956\u6BCD", "\u66FE\u7956\u7236\u6BCD");
7821
+ }
7822
+ if (L === 4) {
7823
+ return pick2(sex, "\u9AD8\u7956\u7236", "\u9AD8\u7956\u6BCD", "\u9AD8\u7956\u7236\u6BCD");
7824
+ }
7825
+ return pick2(sex, `${L}\u4E16\u7956`, `${L}\u4E16\u7956\u6BCD`, `${L}\u4E16\u7956\u7236\u6BCD`);
7826
+ }
7827
+ if (L <= 1) {
7828
+ return pick2(sex, "\u513F\u5B50", "\u5973\u513F", "\u5B50\u5973");
7829
+ }
7830
+ if (L === 2) {
7831
+ return pick2(sex, "\u5B59\u5B50", "\u5B59\u5973", "\u5B59\u5B50\u5973");
7832
+ }
7833
+ if (L === 3) {
7834
+ return pick2(sex, "\u66FE\u5B59", "\u66FE\u5B59\u5973", "\u66FE\u5B59\u5B50\u5973");
7835
+ }
7836
+ if (L === 4) {
7837
+ return pick2(sex, "\u7384\u5B59", "\u7384\u5B59\u5973", "\u7384\u5B59\u5B50\u5973");
7838
+ }
7839
+ return pick2(sex, `${L}\u4E16\u5B59`, `${L}\u4E16\u5B59\u5973`, `${L}\u4E16\u5B59\u5B50\u5973`);
7840
+ };
7841
+ var cousinPlain2 = (degree, sex) => {
7842
+ if (degree <= 1) {
7843
+ return pick2(sex, "\u5802\u8868\u5144\u5F1F", "\u5802\u8868\u59D0\u59B9", "\u5802\u8868\u4EB2");
7844
+ }
7845
+ if (degree === 2) {
7846
+ return pick2(sex, "\u4ECE\u5802\u8868\u5144\u5F1F", "\u4ECE\u5802\u8868\u59D0\u59B9", "\u4ECE\u5802\u8868\u4EB2");
7847
+ }
7848
+ return pick2(
7849
+ sex,
7850
+ `${degree}\u4EE3\u5802\u8868\u5144\u5F1F`,
7851
+ `${degree}\u4EE3\u5802\u8868\u59D0\u59B9`,
7852
+ `${degree}\u4EE3\u5802\u8868\u4EB2`
7853
+ );
7854
+ };
7855
+ var KinshipTranslatorZh = class extends KinshipTranslatorBasic {
7856
+ indirect() {
7857
+ let degree = Math.abs(this.pathN?.degree ?? 0);
7858
+ if (degree > 0) {
7859
+ degree = degree - 1;
7860
+ }
7861
+ return cousinPlain2(degree, sexOf3(this.personN));
7862
+ }
7863
+ removal() {
7864
+ const level = this.pathN?.level ?? 0;
7865
+ let degree = Math.abs(this.pathN?.degree ?? 0);
7866
+ if (degree > 0) {
7867
+ degree = degree - 1;
7868
+ }
7869
+ if (!degree) {
7870
+ return level < 0 ? this.nibling() : this.auncle();
7871
+ }
7872
+ const removed = Math.abs(level);
7873
+ return `${cousinPlain2(degree, sexOf3(this.personN))}\uFF08\u9694${removed}\u4EE3\uFF09`;
7874
+ }
7875
+ auncle() {
7876
+ const level = Math.abs(this.pathN?.level ?? 0);
7877
+ const sex = sexOf3(this.personN);
7878
+ if (level <= 2) {
7879
+ return pick2(sex, "\u53D4\u53D4", "\u963F\u59E8", "\u53D4\u4F2F/\u59D1\u59E8");
7880
+ }
7881
+ if (level === 3) {
7882
+ return pick2(sex, "\u4F2F\u53D4\u7956\u7236", "\u59D1\u7956\u6BCD", "\u4F2F\u53D4\u7956\u7236\u6BCD");
7883
+ }
7884
+ return pick2(
7885
+ sex,
7886
+ `${level - 2}\u4EE3\u524D\u7684\u53D4\u53D4`,
7887
+ `${level - 2}\u4EE3\u524D\u7684\u963F\u59E8`,
7888
+ `${level - 2}\u4EE3\u524D\u7684\u53D4\u4F2F/\u59D1\u59E8`
7889
+ );
7890
+ }
7891
+ nibling() {
7892
+ const level = Math.abs(this.pathN?.level ?? 0);
7893
+ const sex = sexOf3(this.personN);
7894
+ if (level <= 2) {
7895
+ return pick2(sex, "\u4F84\u5B50", "\u4F84\u5973", "\u4F84\u5B50\u5973");
7896
+ }
7897
+ if (level === 3) {
7898
+ return pick2(sex, "\u4F84\u5B59", "\u4F84\u5B59\u5973", "\u4F84\u5B59\u5B50\u5973");
7899
+ }
7900
+ return pick2(
7901
+ sex,
7902
+ `${level - 2}\u4EE3\u4E0B\u7684\u4F84\u5B50`,
7903
+ `${level - 2}\u4EE3\u4E0B\u7684\u4F84\u5973`,
7904
+ `${level - 2}\u4EE3\u4E0B\u7684\u4F84\u5B50\u5973`
7905
+ );
7906
+ }
7907
+ parent() {
7908
+ return lineal2(
7909
+ Math.abs(this.pathN?.level ?? 0),
7910
+ sexOf3(this.personN),
7911
+ "asc"
7912
+ );
7913
+ }
7914
+ child() {
7915
+ return lineal2(
7916
+ Math.abs(this.pathN?.level ?? 0),
7917
+ sexOf3(this.personN),
7918
+ "desc"
7919
+ );
7920
+ }
7921
+ sibling() {
7922
+ return pick2(sexOf3(this.personN), "\u5144\u5F1F", "\u59D0\u59B9", "\u5144\u5F1F\u59D0\u59B9");
7923
+ }
7924
+ halfBlood(relation) {
7925
+ if (!relation || !this.isHalfBlood) {
7926
+ return relation ?? "";
7927
+ }
7928
+ return `\u5F02\u7236\u6BCD\u7684${relation}`;
7929
+ }
7930
+ spouse() {
7931
+ return pick2(sexOf3(this.personN), "\u4E08\u592B", "\u59BB\u5B50", "\u914D\u5076");
7932
+ }
7933
+ ofSpouse(relation) {
7934
+ if (!relation) {
7935
+ return "";
7936
+ }
7937
+ const spouseType = pick2(
7938
+ sexOf3(this.path?.[1].indi),
7939
+ "\u4E08\u592B",
7940
+ "\u59BB\u5B50",
7941
+ "\u914D\u5076"
7942
+ );
7943
+ return `${spouseType}\u7684${relation}`;
7944
+ }
7945
+ spouseOf(relation) {
7946
+ if (!relation) {
7947
+ return "";
7948
+ }
7949
+ const spouse = this.path?.[this.path.length - 1].indi;
7950
+ const spouseType = pick2(sexOf3(spouse), "\u4E08\u592B", "\u59BB\u5B50", "\u914D\u5076");
7951
+ return `${relation}\u7684${spouseType}`;
7952
+ }
7953
+ of(relation) {
7954
+ const formattedName = nameFormatter(this.path?.[0]?.indi, {
7955
+ nameOrder: "last-first"
7956
+ });
7957
+ let name = formattedName.inOrder.filter(Boolean).join(" ");
7958
+ if (this.displayName === "none") {
7959
+ name = "";
7960
+ } else if (this.displayName === "givenname") {
7961
+ name = formattedName.givenname;
7962
+ } else if (this.displayName === "surname") {
7963
+ name = `${formattedName.surname}`;
7964
+ }
7965
+ if (!name || !relation) {
7966
+ return relation ?? "";
7967
+ }
7968
+ return `${name}\u7684${relation}`;
7969
+ }
7970
+ inLaw(relation) {
7971
+ let inLawRelation = relation;
7972
+ Object.keys(InLawsZh).find((pattern) => {
7973
+ const regex = new RegExp(`^${pattern}$`);
7974
+ if (relation?.match(regex)) {
7975
+ inLawRelation = InLawsZh[pattern];
7976
+ return true;
7977
+ }
7978
+ return false;
7979
+ });
7980
+ return inLawRelation ?? "";
7981
+ }
7982
+ relationType(relation) {
7983
+ if (!relation || !this.pathN?.relation) {
7984
+ return relation ?? "";
7985
+ }
7986
+ return `${this.pathN.relation}${relation}`;
7987
+ }
7988
+ };
7989
+
7503
7990
  // src/kinship-translator/kinship-translator.ts
7504
7991
  var KinshipTranslator = class {
7505
7992
  constructor(person1, person2, lang = "en", entirePath, displayName = "givenname") {