@treeviz/gedcom-parser 2.0.10 → 2.0.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.
- package/dist/classes/common.d.ts +6 -1
- package/dist/classes/common.d.ts.map +1 -1
- package/dist/classes/fam.d.ts +9 -1
- package/dist/classes/fam.d.ts.map +1 -1
- package/dist/classes/gedcom.d.ts +6 -2
- package/dist/classes/gedcom.d.ts.map +1 -1
- package/dist/classes/index.js +495 -50
- package/dist/classes/indi.d.ts +6 -0
- package/dist/classes/indi.d.ts.map +1 -1
- package/dist/cli/index.js +3383 -2932
- package/dist/constants/constants.d.ts +7 -0
- package/dist/constants/constants.d.ts.map +1 -1
- package/dist/constants/index.js +1287 -916
- package/dist/factories/index.js +409 -39
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5327 -4777
- package/dist/interfaces/fam.d.ts +7 -1
- package/dist/interfaces/fam.d.ts.map +1 -1
- package/dist/interfaces/gedcom.d.ts +4 -0
- package/dist/interfaces/gedcom.d.ts.map +1 -1
- package/dist/interfaces/indi.d.ts +5 -1
- package/dist/interfaces/indi.d.ts.map +1 -1
- package/dist/kinship-translator/index.js +409 -39
- package/dist/structures/gedcom.d.ts +1 -0
- package/dist/structures/gedcom.d.ts.map +1 -1
- package/dist/types/types.d.ts +10 -0
- package/dist/types/types.d.ts.map +1 -1
- package/dist/utils/fact-edit.d.ts +22 -0
- package/dist/utils/fact-edit.d.ts.map +1 -0
- package/dist/utils/family-edit.d.ts +23 -0
- package/dist/utils/family-edit.d.ts.map +1 -0
- package/dist/utils/gedcom-trailer.d.ts +6 -0
- package/dist/utils/gedcom-trailer.d.ts.map +1 -0
- package/dist/utils/index.d.ts +4 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +605 -55
- package/dist/utils/parser.d.ts +3 -0
- package/dist/utils/parser.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/classes/index.js
CHANGED
|
@@ -82,8 +82,28 @@ __export(translators_exports, {
|
|
|
82
82
|
});
|
|
83
83
|
|
|
84
84
|
// src/constants/constants.ts
|
|
85
|
+
var APP_BRANDING = "TreeViz - The Family Tree Visualiser & Editor";
|
|
85
86
|
var ID_REG = /^@[_a-zA-Z0-9]+@/;
|
|
86
87
|
var ID_GETTER_REG = /^(?<at>@)?(?<letter>[A-Z])?/i;
|
|
88
|
+
var ORIG_HEAD_TAG = "_ORIGHEAD";
|
|
89
|
+
|
|
90
|
+
// src/utils/gedcom-trailer.ts
|
|
91
|
+
var TRAILER_LINE = /^0 TRLR\s*$/i;
|
|
92
|
+
var GEDCOM_TRAILER_TAG = "TRLR";
|
|
93
|
+
var isGedcomTrailerTag = (tag) => tag === GEDCOM_TRAILER_TAG;
|
|
94
|
+
var isGedcomTrailerLine = (line) => TRAILER_LINE.test(line);
|
|
95
|
+
var appendGedcomTrailer = (serialized) => {
|
|
96
|
+
const newline = serialized.includes("\r\n") ? "\r\n" : "\n";
|
|
97
|
+
const trimmed = serialized.replace(/(?:\r?\n)+$/, "");
|
|
98
|
+
if (!trimmed) {
|
|
99
|
+
return "0 TRLR";
|
|
100
|
+
}
|
|
101
|
+
const lastLine = trimmed.split(/\r?\n/).at(-1) ?? "";
|
|
102
|
+
if (isGedcomTrailerLine(lastLine)) {
|
|
103
|
+
return trimmed;
|
|
104
|
+
}
|
|
105
|
+
return `${trimmed}${newline}0 TRLR`;
|
|
106
|
+
};
|
|
87
107
|
var List = class _List {
|
|
88
108
|
// length = 0;
|
|
89
109
|
constructor(items) {
|
|
@@ -594,6 +614,9 @@ var Common = class _Common {
|
|
|
594
614
|
delete this._value;
|
|
595
615
|
}
|
|
596
616
|
set(name, value) {
|
|
617
|
+
if (isGedcomTrailerTag(name)) {
|
|
618
|
+
return void 0;
|
|
619
|
+
}
|
|
597
620
|
if (typeof value === "string") {
|
|
598
621
|
const usedValue = createCommon(this._gedcom, void 0, this.main);
|
|
599
622
|
usedValue.value = value;
|
|
@@ -604,6 +627,9 @@ var Common = class _Common {
|
|
|
604
627
|
return get(this, name);
|
|
605
628
|
}
|
|
606
629
|
assign(name, value, unique = false) {
|
|
630
|
+
if (isGedcomTrailerTag(name)) {
|
|
631
|
+
return void 0;
|
|
632
|
+
}
|
|
607
633
|
let curValue = this.get(name);
|
|
608
634
|
if (curValue?.isListable) {
|
|
609
635
|
if (curValue instanceof _Common) {
|
|
@@ -826,30 +852,47 @@ var Common = class _Common {
|
|
|
826
852
|
});
|
|
827
853
|
return gedcom;
|
|
828
854
|
}
|
|
855
|
+
getHeadRecord() {
|
|
856
|
+
return get(this, "HEAD") || get(this.getGedcom(), "HEAD");
|
|
857
|
+
}
|
|
858
|
+
getOriginalHeadRecord() {
|
|
859
|
+
return get(this, ORIG_HEAD_TAG) || get(this.getGedcom(), ORIG_HEAD_TAG) || get(this.getHeadRecord(), ORIG_HEAD_TAG);
|
|
860
|
+
}
|
|
861
|
+
getSourceHeads() {
|
|
862
|
+
const heads = [this.getOriginalHeadRecord(), this.getHeadRecord()];
|
|
863
|
+
return heads.filter((head, index) => {
|
|
864
|
+
return Boolean(head && heads.indexOf(head) === index);
|
|
865
|
+
});
|
|
866
|
+
}
|
|
867
|
+
getFromSourceHeads(path) {
|
|
868
|
+
for (const head of this.getSourceHeads()) {
|
|
869
|
+
const value = get(head, path);
|
|
870
|
+
if (value !== void 0 && value !== null && value !== "") {
|
|
871
|
+
return value;
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
return void 0;
|
|
875
|
+
}
|
|
876
|
+
sourStartsWith(prefix) {
|
|
877
|
+
return this.getSourceHeads().some((head) => {
|
|
878
|
+
const sour = get(head, "SOUR.value");
|
|
879
|
+
return !!sour?.toLowerCase()?.startsWith(prefix);
|
|
880
|
+
});
|
|
881
|
+
}
|
|
829
882
|
isGenoPro() {
|
|
830
|
-
|
|
831
|
-
const sour = get(head, "SOUR.value");
|
|
832
|
-
return !!sour?.toLowerCase()?.startsWith("genopro");
|
|
883
|
+
return this.sourStartsWith("genopro");
|
|
833
884
|
}
|
|
834
885
|
isAhnenblatt() {
|
|
835
|
-
|
|
836
|
-
const sour = get(head, "SOUR.value");
|
|
837
|
-
return !!sour?.toLowerCase()?.startsWith("ahnenblatt");
|
|
886
|
+
return this.sourStartsWith("ahnenblatt");
|
|
838
887
|
}
|
|
839
888
|
isGeni() {
|
|
840
|
-
|
|
841
|
-
const sour = get(head, "SOUR.value");
|
|
842
|
-
return !!sour?.toLowerCase()?.startsWith("geni");
|
|
889
|
+
return this.sourStartsWith("geni");
|
|
843
890
|
}
|
|
844
891
|
isAncestry() {
|
|
845
|
-
|
|
846
|
-
const sour = get(head, "SOUR.value");
|
|
847
|
-
return !!sour?.toLowerCase()?.startsWith("ancestry");
|
|
892
|
+
return this.sourStartsWith("ancestry");
|
|
848
893
|
}
|
|
849
894
|
isMyHeritage() {
|
|
850
|
-
|
|
851
|
-
const sour = get(head, "SOUR.value");
|
|
852
|
-
return !!sour?.toLowerCase()?.startsWith("myheritage");
|
|
895
|
+
return this.sourStartsWith("myheritage");
|
|
853
896
|
}
|
|
854
897
|
/**
|
|
855
898
|
* Get the source type as a string (for prefixing tree IDs and names)
|
|
@@ -866,22 +909,22 @@ var Common = class _Common {
|
|
|
866
909
|
return void 0;
|
|
867
910
|
}
|
|
868
911
|
isFamilySearch() {
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
912
|
+
return this.getSourceHeads().some((head) => {
|
|
913
|
+
const sourName = get(head, "SOUR.NAME.value");
|
|
914
|
+
return sourName === "FamilySearch API";
|
|
915
|
+
});
|
|
872
916
|
}
|
|
873
917
|
isGNO2GED() {
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
918
|
+
return this.getSourceHeads().some((head) => {
|
|
919
|
+
const sour = get(head, "SOUR.value");
|
|
920
|
+
return sour === "GNO2GED";
|
|
921
|
+
});
|
|
877
922
|
}
|
|
878
923
|
getAncestryTreeId() {
|
|
879
|
-
|
|
880
|
-
return get(this, path) || get(this.getGedcom(), path);
|
|
924
|
+
return this.getFromSourceHeads("SOUR._TREE.RIN.value") || (get(this, "HEAD.SOUR._TREE.RIN.value") || get(this.getGedcom(), "HEAD.SOUR._TREE.RIN.value"));
|
|
881
925
|
}
|
|
882
926
|
getMyHeritageTreeId() {
|
|
883
|
-
|
|
884
|
-
return get(this, path) || get(this.getGedcom(), path);
|
|
927
|
+
return this.getFromSourceHeads("_EXPORTED_FROM_SITE_ID.value") || (get(this, "HEAD._EXPORTED_FROM_SITE_ID.value") || get(this.getGedcom(), "HEAD._EXPORTED_FROM_SITE_ID.value"));
|
|
885
928
|
}
|
|
886
929
|
getTreeId() {
|
|
887
930
|
if (this?.isAncestry()) {
|
|
@@ -915,8 +958,7 @@ var Common = class _Common {
|
|
|
915
958
|
return this.getUniversalTreeId();
|
|
916
959
|
}
|
|
917
960
|
getAncestryTreeName() {
|
|
918
|
-
|
|
919
|
-
return get(this, path) || get(this.getGedcom(), path);
|
|
961
|
+
return this.getFromSourceHeads("SOUR._TREE.value") || (get(this, "HEAD.SOUR._TREE.value") || get(this.getGedcom(), "HEAD.SOUR._TREE.value"));
|
|
920
962
|
}
|
|
921
963
|
getMyHeritageTreeName() {
|
|
922
964
|
const path = "HEAD.FILE.value";
|
|
@@ -926,14 +968,14 @@ var Common = class _Common {
|
|
|
926
968
|
)?.groups?.tree;
|
|
927
969
|
}
|
|
928
970
|
getFamilySearchTreeId() {
|
|
929
|
-
const rin = get(this, "HEAD.SOUR._TREE.RIN.value") || get(this.getGedcom(), "HEAD.SOUR._TREE.RIN.value");
|
|
971
|
+
const rin = this.getFromSourceHeads("SOUR._TREE.RIN.value") || get(this, "HEAD.SOUR._TREE.RIN.value") || get(this.getGedcom(), "HEAD.SOUR._TREE.RIN.value");
|
|
930
972
|
if (rin) {
|
|
931
973
|
return rin;
|
|
932
974
|
}
|
|
933
975
|
return "familysearch";
|
|
934
976
|
}
|
|
935
977
|
getFamilySearchTreeName() {
|
|
936
|
-
const treeName = get(this, "HEAD.SOUR._TREE.value") || get(this.getGedcom(), "HEAD.SOUR._TREE.value");
|
|
978
|
+
const treeName = this.getFromSourceHeads("SOUR._TREE.value") || get(this, "HEAD.SOUR._TREE.value") || get(this.getGedcom(), "HEAD.SOUR._TREE.value");
|
|
937
979
|
if (treeName) {
|
|
938
980
|
return treeName;
|
|
939
981
|
}
|
|
@@ -1025,11 +1067,11 @@ var Common = class _Common {
|
|
|
1025
1067
|
const cleanName = fileName.replace(/\.ged$/i, "").replace(/_/g, " ");
|
|
1026
1068
|
return `${prefix}${cleanName}`;
|
|
1027
1069
|
}
|
|
1028
|
-
const sourName = get(this, "HEAD.SOUR.NAME.value") || get(this.getGedcom(), "HEAD.SOUR.NAME.value");
|
|
1070
|
+
const sourName = this.getFromSourceHeads("SOUR.NAME.value") || get(this, "HEAD.SOUR.NAME.value") || get(this.getGedcom(), "HEAD.SOUR.NAME.value");
|
|
1029
1071
|
if (sourName) {
|
|
1030
1072
|
return `${prefix}${sourName}`;
|
|
1031
1073
|
}
|
|
1032
|
-
const sourValue = get(this, "HEAD.SOUR.value") || get(this.getGedcom(), "HEAD.SOUR.value");
|
|
1074
|
+
const sourValue = this.getFromSourceHeads("SOUR.value") || get(this, "HEAD.SOUR.value") || get(this.getGedcom(), "HEAD.SOUR.value");
|
|
1033
1075
|
if (sourValue) {
|
|
1034
1076
|
return `${prefix}${sourValue}`;
|
|
1035
1077
|
}
|
|
@@ -1095,7 +1137,7 @@ var isOnlyMainProp = (key) => {
|
|
|
1095
1137
|
};
|
|
1096
1138
|
var isValidKey = (common, key) => {
|
|
1097
1139
|
const prop = get(common, key);
|
|
1098
|
-
return key !== "_gedcom" && key !== "_main" && key !== "_parent" && key !== "_uniqueId" && key !== "_refs" && key !== "_type" && (key === "id" || key === "_id" || key === "value" || key === "_value" || prop instanceof Common || prop instanceof List);
|
|
1140
|
+
return key !== "_gedcom" && key !== "_main" && key !== "_parent" && key !== "_uniqueId" && key !== "_refs" && key !== "_type" && !(typeof key === "string" && isGedcomTrailerTag(key)) && (key === "id" || key === "_id" || key === "value" || key === "_value" || prop instanceof Common || prop instanceof List);
|
|
1099
1141
|
};
|
|
1100
1142
|
var getValidKeys = (common) => {
|
|
1101
1143
|
return Object.keys(common).filter((key) => {
|
|
@@ -3810,6 +3852,250 @@ var cacheDiscoveredPath = (gedcom, path) => {
|
|
|
3810
3852
|
}
|
|
3811
3853
|
};
|
|
3812
3854
|
|
|
3855
|
+
// src/utils/fact-edit.ts
|
|
3856
|
+
var SINGLETON_TAGS = /* @__PURE__ */ new Set(["BIRT", "DEAT", "SSN", "SEX", "DSCR"]);
|
|
3857
|
+
var firstRecord = (node) => {
|
|
3858
|
+
if (!node) {
|
|
3859
|
+
return void 0;
|
|
3860
|
+
}
|
|
3861
|
+
if (node instanceof List) {
|
|
3862
|
+
return node.index(0);
|
|
3863
|
+
}
|
|
3864
|
+
return node.index(0) ?? node;
|
|
3865
|
+
};
|
|
3866
|
+
var setDateOn = (gedcom, owner, parent, date) => {
|
|
3867
|
+
const trimmed = date.trim();
|
|
3868
|
+
if (!trimmed) {
|
|
3869
|
+
return;
|
|
3870
|
+
}
|
|
3871
|
+
let dateNode = parent.get("DATE");
|
|
3872
|
+
if (!dateNode || dateNode instanceof List) {
|
|
3873
|
+
dateNode = createCommonDate(gedcom, void 0, owner, parent);
|
|
3874
|
+
dateNode.type = "DATE";
|
|
3875
|
+
parent.set("DATE", dateNode);
|
|
3876
|
+
}
|
|
3877
|
+
dateNode.value = trimmed;
|
|
3878
|
+
};
|
|
3879
|
+
var fillFact = (gedcom, owner, event, input) => {
|
|
3880
|
+
if (input.value?.trim()) {
|
|
3881
|
+
event.value = input.value.trim();
|
|
3882
|
+
}
|
|
3883
|
+
if (input.type?.trim()) {
|
|
3884
|
+
event.set("TYPE", input.type.trim());
|
|
3885
|
+
}
|
|
3886
|
+
if (input.date) {
|
|
3887
|
+
setDateOn(gedcom, owner, event, input.date);
|
|
3888
|
+
}
|
|
3889
|
+
if (input.place?.trim()) {
|
|
3890
|
+
event.set("PLAC", input.place.trim());
|
|
3891
|
+
}
|
|
3892
|
+
if (input.note?.trim()) {
|
|
3893
|
+
event.set("NOTE", input.note.trim());
|
|
3894
|
+
}
|
|
3895
|
+
};
|
|
3896
|
+
var addIndividualFact = (indi, input) => {
|
|
3897
|
+
const gedcom = indi.getGedcom();
|
|
3898
|
+
if (!gedcom) {
|
|
3899
|
+
return void 0;
|
|
3900
|
+
}
|
|
3901
|
+
const tag = input.tag;
|
|
3902
|
+
let event = SINGLETON_TAGS.has(tag) ? firstRecord(indi.get(tag)) : void 0;
|
|
3903
|
+
if (!event) {
|
|
3904
|
+
event = createCommon(gedcom, void 0, indi);
|
|
3905
|
+
event.type = tag;
|
|
3906
|
+
if (SINGLETON_TAGS.has(tag)) {
|
|
3907
|
+
indi.set(tag, event);
|
|
3908
|
+
} else {
|
|
3909
|
+
indi.assign(tag, event);
|
|
3910
|
+
}
|
|
3911
|
+
}
|
|
3912
|
+
fillFact(gedcom, indi, event, input);
|
|
3913
|
+
return event;
|
|
3914
|
+
};
|
|
3915
|
+
var addFamilyFact = (fam, input) => {
|
|
3916
|
+
const gedcom = fam.getGedcom();
|
|
3917
|
+
if (!gedcom) {
|
|
3918
|
+
return void 0;
|
|
3919
|
+
}
|
|
3920
|
+
const event = createCommon(gedcom, void 0, fam);
|
|
3921
|
+
event.type = input.tag;
|
|
3922
|
+
fam.assign(input.tag, event);
|
|
3923
|
+
fillFact(gedcom, fam, event, input);
|
|
3924
|
+
return event;
|
|
3925
|
+
};
|
|
3926
|
+
|
|
3927
|
+
// src/utils/family-edit.ts
|
|
3928
|
+
var PEDIGREE_VALUES = [
|
|
3929
|
+
"birth" /* BIRTH */,
|
|
3930
|
+
"adopted" /* ADOPTED */,
|
|
3931
|
+
"foster" /* FOSTER */,
|
|
3932
|
+
"step" /* STEP */,
|
|
3933
|
+
"sealing" /* SEALING */
|
|
3934
|
+
];
|
|
3935
|
+
var toGedcomPedigree = (value) => {
|
|
3936
|
+
const normalized = String(value || "birth" /* BIRTH */).toLowerCase();
|
|
3937
|
+
if (normalized === "biological" /* BIOLOGICAL */ || normalized === "birth" /* BIRTH */) {
|
|
3938
|
+
return "birth" /* BIRTH */;
|
|
3939
|
+
}
|
|
3940
|
+
const match = PEDIGREE_VALUES.find((item) => item === normalized);
|
|
3941
|
+
return match ?? "birth" /* BIRTH */;
|
|
3942
|
+
};
|
|
3943
|
+
var pointerIds = (tag) => {
|
|
3944
|
+
if (!tag) {
|
|
3945
|
+
return [];
|
|
3946
|
+
}
|
|
3947
|
+
if (tag instanceof List) {
|
|
3948
|
+
return tag.values().map((item) => item?.toValue?.()).filter((value2) => !!value2);
|
|
3949
|
+
}
|
|
3950
|
+
const value = tag.toValue?.();
|
|
3951
|
+
return value ? [String(value)] : [];
|
|
3952
|
+
};
|
|
3953
|
+
var firstPointerId = (tag) => pointerIds(tag)[0];
|
|
3954
|
+
var makePointer = (gedcom, parent, value, refType) => {
|
|
3955
|
+
const pointer = createCommon(gedcom, void 0, parent);
|
|
3956
|
+
pointer.value = value;
|
|
3957
|
+
pointer.refType = refType;
|
|
3958
|
+
return pointer;
|
|
3959
|
+
};
|
|
3960
|
+
var nextRecordId = (ids, prefix) => {
|
|
3961
|
+
let max = 0;
|
|
3962
|
+
ids.forEach((id) => {
|
|
3963
|
+
const match = String(id).match(/(\d+)/);
|
|
3964
|
+
const n = match ? Number.parseInt(match[1], 10) : 0;
|
|
3965
|
+
if (n > max) {
|
|
3966
|
+
max = n;
|
|
3967
|
+
}
|
|
3968
|
+
});
|
|
3969
|
+
return `@${prefix}${max + 1}@`;
|
|
3970
|
+
};
|
|
3971
|
+
var familyHasParent = (fam, indiId) => pointerIds(fam.get("HUSB")).includes(indiId) || pointerIds(fam.get("WIFE")).includes(indiId);
|
|
3972
|
+
var familyHasChild = (fam, indiId) => pointerIds(fam.get("CHIL")).includes(indiId);
|
|
3973
|
+
var spouseTagFor = (indi, fam) => {
|
|
3974
|
+
const husbId = firstPointerId(fam.get("HUSB"));
|
|
3975
|
+
const wifeId = firstPointerId(fam.get("WIFE"));
|
|
3976
|
+
if (husbId === indi.id) {
|
|
3977
|
+
return "HUSB";
|
|
3978
|
+
}
|
|
3979
|
+
if (wifeId === indi.id) {
|
|
3980
|
+
return "WIFE";
|
|
3981
|
+
}
|
|
3982
|
+
if (indi.isFemale()) {
|
|
3983
|
+
return wifeId && wifeId !== indi.id ? "HUSB" : "WIFE";
|
|
3984
|
+
}
|
|
3985
|
+
if (indi.isMale()) {
|
|
3986
|
+
return husbId && husbId !== indi.id ? "WIFE" : "HUSB";
|
|
3987
|
+
}
|
|
3988
|
+
return husbId ? "WIFE" : "HUSB";
|
|
3989
|
+
};
|
|
3990
|
+
var canAttachAsSpouse = (fam, indi) => {
|
|
3991
|
+
if (!indi.id) {
|
|
3992
|
+
return false;
|
|
3993
|
+
}
|
|
3994
|
+
if (familyHasParent(fam, indi.id)) {
|
|
3995
|
+
return true;
|
|
3996
|
+
}
|
|
3997
|
+
const tag = spouseTagFor(indi, fam);
|
|
3998
|
+
const occupied = firstPointerId(fam.get(tag));
|
|
3999
|
+
return !occupied || occupied === indi.id;
|
|
4000
|
+
};
|
|
4001
|
+
var pointerByValue = (tag, id) => {
|
|
4002
|
+
if (!tag) {
|
|
4003
|
+
return void 0;
|
|
4004
|
+
}
|
|
4005
|
+
const fromValues = tag.toValueList?.().item(id);
|
|
4006
|
+
if (fromValues) {
|
|
4007
|
+
return fromValues;
|
|
4008
|
+
}
|
|
4009
|
+
return tag.toList()?.values().find((item) => item?.toValue?.() === id);
|
|
4010
|
+
};
|
|
4011
|
+
var setChildPedigree = (fam, child, pedigree, parent) => {
|
|
4012
|
+
if (!fam.id || !child.id) {
|
|
4013
|
+
return;
|
|
4014
|
+
}
|
|
4015
|
+
const pedi = toGedcomPedigree(pedigree);
|
|
4016
|
+
const famc = pointerByValue(child.get("FAMC"), fam.id);
|
|
4017
|
+
if (famc) {
|
|
4018
|
+
famc.set("PEDI", pedi);
|
|
4019
|
+
}
|
|
4020
|
+
const chil = pointerByValue(fam.get("CHIL"), child.id);
|
|
4021
|
+
if (!chil) {
|
|
4022
|
+
return;
|
|
4023
|
+
}
|
|
4024
|
+
const setFather = !parent || parent.isMale() || parent.isUnknownSex();
|
|
4025
|
+
const setMother = !parent || parent.isFemale() || parent.isUnknownSex();
|
|
4026
|
+
if (setFather) {
|
|
4027
|
+
chil.set("_FREL", pedi);
|
|
4028
|
+
}
|
|
4029
|
+
if (setMother) {
|
|
4030
|
+
chil.set("_MREL", pedi);
|
|
4031
|
+
}
|
|
4032
|
+
};
|
|
4033
|
+
var attachSpouseToFamily = (fam, indi) => {
|
|
4034
|
+
const gedcom = fam.getGedcom() ?? indi.getGedcom();
|
|
4035
|
+
if (!indi.id || !fam.id || !gedcom) {
|
|
4036
|
+
return false;
|
|
4037
|
+
}
|
|
4038
|
+
if (!canAttachAsSpouse(fam, indi)) {
|
|
4039
|
+
return false;
|
|
4040
|
+
}
|
|
4041
|
+
const tag = spouseTagFor(indi, fam);
|
|
4042
|
+
if (firstPointerId(fam.get(tag)) !== indi.id) {
|
|
4043
|
+
fam.set(tag, makePointer(gedcom, fam, indi.id, "INDI"));
|
|
4044
|
+
}
|
|
4045
|
+
indi.assign("FAMS", makePointer(gedcom, indi, fam.id, "FAM"), true);
|
|
4046
|
+
return true;
|
|
4047
|
+
};
|
|
4048
|
+
var attachChildToFamily = (fam, child, pedigree, parent) => {
|
|
4049
|
+
const gedcom = fam.getGedcom() ?? child.getGedcom();
|
|
4050
|
+
if (!child.id || !fam.id || !gedcom) {
|
|
4051
|
+
return false;
|
|
4052
|
+
}
|
|
4053
|
+
if (!familyHasChild(fam, child.id)) {
|
|
4054
|
+
fam.assign("CHIL", makePointer(gedcom, fam, child.id, "INDI"), true);
|
|
4055
|
+
}
|
|
4056
|
+
const existingFamc = pointerByValue(child.get("FAMC"), fam.id);
|
|
4057
|
+
if (!existingFamc) {
|
|
4058
|
+
child.assign("FAMC", makePointer(gedcom, child, fam.id, "FAM"), true);
|
|
4059
|
+
}
|
|
4060
|
+
setChildPedigree(fam, child, pedigree, parent);
|
|
4061
|
+
return true;
|
|
4062
|
+
};
|
|
4063
|
+
var findReusableParentChildFamily = (parent, child) => {
|
|
4064
|
+
if (!parent.id || !child.id) {
|
|
4065
|
+
return void 0;
|
|
4066
|
+
}
|
|
4067
|
+
let reusableFamc;
|
|
4068
|
+
let already = false;
|
|
4069
|
+
child.getFamilies("FAMC")?.forEach((fam) => {
|
|
4070
|
+
if (!fam) {
|
|
4071
|
+
return;
|
|
4072
|
+
}
|
|
4073
|
+
if (familyHasParent(fam, parent.id) && familyHasChild(fam, child.id)) {
|
|
4074
|
+
already = true;
|
|
4075
|
+
return;
|
|
4076
|
+
}
|
|
4077
|
+
if (!reusableFamc && canAttachAsSpouse(fam, parent)) {
|
|
4078
|
+
reusableFamc = fam;
|
|
4079
|
+
}
|
|
4080
|
+
});
|
|
4081
|
+
if (already) {
|
|
4082
|
+
return "already";
|
|
4083
|
+
}
|
|
4084
|
+
if (reusableFamc) {
|
|
4085
|
+
return reusableFamc;
|
|
4086
|
+
}
|
|
4087
|
+
const parentFams = [];
|
|
4088
|
+
parent.getFamilies("FAMS")?.forEach((fam) => {
|
|
4089
|
+
if (fam) {
|
|
4090
|
+
parentFams.push(fam);
|
|
4091
|
+
}
|
|
4092
|
+
});
|
|
4093
|
+
if (parentFams.length === 1) {
|
|
4094
|
+
return parentFams[0];
|
|
4095
|
+
}
|
|
4096
|
+
return void 0;
|
|
4097
|
+
};
|
|
4098
|
+
|
|
3813
4099
|
// src/utils/get-places.ts
|
|
3814
4100
|
var getPlaces = (common, type = ["ALL" /* All */], maxLevel = 1, level = 0, mainKey) => {
|
|
3815
4101
|
const types = Array.isArray(type) ? type : [type];
|
|
@@ -4440,6 +4726,31 @@ var Fam = class extends Common {
|
|
|
4440
4726
|
getParents() {
|
|
4441
4727
|
return this.getHusband().copy().merge(this.getWife());
|
|
4442
4728
|
}
|
|
4729
|
+
hasParent(indi) {
|
|
4730
|
+
const indiId = typeof indi === "string" ? indi : indi?.id;
|
|
4731
|
+
return !!indiId && familyHasParent(this, indiId);
|
|
4732
|
+
}
|
|
4733
|
+
hasChild(indi) {
|
|
4734
|
+
const indiId = typeof indi === "string" ? indi : indi?.id;
|
|
4735
|
+
return !!indiId && familyHasChild(this, indiId);
|
|
4736
|
+
}
|
|
4737
|
+
canAddSpouse(indi) {
|
|
4738
|
+
return canAttachAsSpouse(this, indi);
|
|
4739
|
+
}
|
|
4740
|
+
addSpouse(indi) {
|
|
4741
|
+
return attachSpouseToFamily(this, indi);
|
|
4742
|
+
}
|
|
4743
|
+
addChild(child, pedigree, parent) {
|
|
4744
|
+
return attachChildToFamily(
|
|
4745
|
+
this,
|
|
4746
|
+
child,
|
|
4747
|
+
pedigree,
|
|
4748
|
+
parent
|
|
4749
|
+
);
|
|
4750
|
+
}
|
|
4751
|
+
addFact(input) {
|
|
4752
|
+
return addFamilyFact(this, input);
|
|
4753
|
+
}
|
|
4443
4754
|
toList() {
|
|
4444
4755
|
return new Families().concat(
|
|
4445
4756
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -4512,19 +4823,51 @@ var ALLOWED_FACTS = [
|
|
|
4512
4823
|
"OCCU",
|
|
4513
4824
|
"OCCUPATIONS",
|
|
4514
4825
|
"RESI",
|
|
4826
|
+
"BIRT",
|
|
4827
|
+
"DEAT",
|
|
4515
4828
|
"BAPT",
|
|
4829
|
+
"BAPM",
|
|
4516
4830
|
"CHRI",
|
|
4517
4831
|
"CHR",
|
|
4832
|
+
"CHRA",
|
|
4518
4833
|
"BURI",
|
|
4519
|
-
"
|
|
4834
|
+
"CREM",
|
|
4835
|
+
"ADOP",
|
|
4836
|
+
"BARM",
|
|
4837
|
+
"BASM",
|
|
4838
|
+
"BLES",
|
|
4839
|
+
"CONF",
|
|
4840
|
+
"FCOM",
|
|
4841
|
+
"ORDN",
|
|
4842
|
+
"NATU",
|
|
4843
|
+
"EMIG",
|
|
4844
|
+
"IMMI",
|
|
4845
|
+
"CENS",
|
|
4846
|
+
"PROB",
|
|
4847
|
+
"WILL",
|
|
4520
4848
|
"GRAD",
|
|
4849
|
+
"RETI",
|
|
4850
|
+
"EDUC",
|
|
4521
4851
|
"DIV",
|
|
4522
|
-
"IMMI",
|
|
4523
4852
|
"RELI",
|
|
4853
|
+
"CAST",
|
|
4854
|
+
"DSCR",
|
|
4855
|
+
"NATI",
|
|
4856
|
+
"PROP",
|
|
4857
|
+
"SSN",
|
|
4858
|
+
"TITL",
|
|
4859
|
+
"ADDR",
|
|
4860
|
+
"BAPL",
|
|
4861
|
+
"CONL",
|
|
4862
|
+
"ENDL",
|
|
4863
|
+
"SLGC",
|
|
4524
4864
|
"_MILT",
|
|
4525
4865
|
"_MILTID",
|
|
4526
4866
|
"FACT",
|
|
4527
|
-
"_ORIG"
|
|
4867
|
+
"_ORIG",
|
|
4868
|
+
"_WLNK",
|
|
4869
|
+
"WWW",
|
|
4870
|
+
"URL"
|
|
4528
4871
|
];
|
|
4529
4872
|
var DISALLOWED_CUSTOM_FACTS = ["DNA Test", "Newspaper"];
|
|
4530
4873
|
var CustomFactRenderers = {
|
|
@@ -5068,7 +5411,7 @@ var Indi = class extends Common {
|
|
|
5068
5411
|
return result;
|
|
5069
5412
|
}
|
|
5070
5413
|
ancestryLink() {
|
|
5071
|
-
const www = this._gedcom?.HEAD?.SOUR?.CORP?.WWW?.value;
|
|
5414
|
+
const www = this.getFromSourceHeads("SOUR.CORP.WWW.value") || this._gedcom?.HEAD?.SOUR?.CORP?.WWW?.value;
|
|
5072
5415
|
const tree = this.getAncestryTreeId();
|
|
5073
5416
|
if (this.id) {
|
|
5074
5417
|
return `https://${www}/family-tree/person/tree/${tree}/person/${this.id.replace(
|
|
@@ -5080,7 +5423,7 @@ var Indi = class extends Common {
|
|
|
5080
5423
|
async ancestryMedia(namespace) {
|
|
5081
5424
|
const list = {};
|
|
5082
5425
|
const objeList = this.get("OBJE")?.toList().copy();
|
|
5083
|
-
const www = this._gedcom?.HEAD?.SOUR?.CORP?.WWW?.value;
|
|
5426
|
+
const www = this.getFromSourceHeads("SOUR.CORP.WWW.value") || this._gedcom?.HEAD?.SOUR?.CORP?.WWW?.value;
|
|
5084
5427
|
const tree = this.getAncestryTreeId();
|
|
5085
5428
|
if (objeList) {
|
|
5086
5429
|
await Promise.all(
|
|
@@ -5140,7 +5483,7 @@ var Indi = class extends Common {
|
|
|
5140
5483
|
return list;
|
|
5141
5484
|
}
|
|
5142
5485
|
myheritageLink(poolId = 0) {
|
|
5143
|
-
const www = this._gedcom?.HEAD?.SOUR?.CORP?.value?.toLowerCase().replace(/^www\./gi, "");
|
|
5486
|
+
const www = (this.getFromSourceHeads("SOUR.CORP.value") || this._gedcom?.HEAD?.SOUR?.CORP?.value)?.toLowerCase().replace(/^www\./gi, "");
|
|
5144
5487
|
const site = this.getMyHeritageTreeId();
|
|
5145
5488
|
const file = this._gedcom?.HEAD?.get("FILE")?.toValue()?.match(/Exported by MyHeritage.com from .+ in (?<site>.+) on .+$/)?.groups?.site;
|
|
5146
5489
|
const normalizedFile = file?.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase().replace(/[^a-z0-9]+/g, "-");
|
|
@@ -5661,6 +6004,57 @@ var Indi = class extends Common {
|
|
|
5661
6004
|
isUnknownSex() {
|
|
5662
6005
|
return !this.isMale() && !this.isFemale();
|
|
5663
6006
|
}
|
|
6007
|
+
addSpouse(other) {
|
|
6008
|
+
if (!this.id || !other?.id || this.id === other.id || !this._gedcom) {
|
|
6009
|
+
return void 0;
|
|
6010
|
+
}
|
|
6011
|
+
const existing = getFamilyWith(this, other.id);
|
|
6012
|
+
if (existing) {
|
|
6013
|
+
return existing;
|
|
6014
|
+
}
|
|
6015
|
+
const fam = this._gedcom.createFamily();
|
|
6016
|
+
if (!fam.addSpouse(this) || !fam.addSpouse(other)) {
|
|
6017
|
+
return void 0;
|
|
6018
|
+
}
|
|
6019
|
+
return fam;
|
|
6020
|
+
}
|
|
6021
|
+
addChild(child, pedigree) {
|
|
6022
|
+
if (!this.id || !child?.id || this.id === child.id || !this._gedcom) {
|
|
6023
|
+
return void 0;
|
|
6024
|
+
}
|
|
6025
|
+
const existing = findReusableParentChildFamily(
|
|
6026
|
+
this,
|
|
6027
|
+
child
|
|
6028
|
+
);
|
|
6029
|
+
if (existing === "already") {
|
|
6030
|
+
const fam2 = child.getFamilies("FAMC")?.find(
|
|
6031
|
+
(item) => !!item && item.hasParent(this.id) && item.hasChild(child.id)
|
|
6032
|
+
);
|
|
6033
|
+
if (fam2) {
|
|
6034
|
+
setChildPedigree(
|
|
6035
|
+
fam2,
|
|
6036
|
+
child,
|
|
6037
|
+
pedigree,
|
|
6038
|
+
this
|
|
6039
|
+
);
|
|
6040
|
+
}
|
|
6041
|
+
return fam2;
|
|
6042
|
+
}
|
|
6043
|
+
const fam = existing ?? this._gedcom.createFamily();
|
|
6044
|
+
if (!fam.addSpouse(this)) {
|
|
6045
|
+
return void 0;
|
|
6046
|
+
}
|
|
6047
|
+
if (!fam.addChild(child, pedigree, this)) {
|
|
6048
|
+
return void 0;
|
|
6049
|
+
}
|
|
6050
|
+
return fam;
|
|
6051
|
+
}
|
|
6052
|
+
addParent(parent, pedigree) {
|
|
6053
|
+
return parent.addChild(this, pedigree);
|
|
6054
|
+
}
|
|
6055
|
+
addFact(input) {
|
|
6056
|
+
return addIndividualFact(this, input);
|
|
6057
|
+
}
|
|
5664
6058
|
getParentType(id) {
|
|
5665
6059
|
let indi;
|
|
5666
6060
|
if (typeof id === "string" || typeof id === "number") {
|
|
@@ -5861,7 +6255,9 @@ var Indi = class extends Common {
|
|
|
5861
6255
|
}
|
|
5862
6256
|
}
|
|
5863
6257
|
if (kinship !== "child" || !breakAfterSpouse) {
|
|
5864
|
-
indi.getBiologicalFathers().copy().merge(indi.getBiologicalMothers()).merge(
|
|
6258
|
+
indi.getBiologicalFathers().copy().merge(indi.getBiologicalMothers()).merge(
|
|
6259
|
+
indi.getFathers().copy().merge(indi.getMothers())
|
|
6260
|
+
).forEach((relative) => {
|
|
5865
6261
|
if (!visited.has(relative)) {
|
|
5866
6262
|
const currentRelation = indi.getParentType(relative);
|
|
5867
6263
|
const isNonBiological = !!currentRelation && currentRelation !== "biological" /* BIOLOGICAL */;
|
|
@@ -6762,7 +7158,7 @@ var createIndi = (gedcom, id, main, parent) => {
|
|
|
6762
7158
|
|
|
6763
7159
|
// package.json
|
|
6764
7160
|
var package_default = {
|
|
6765
|
-
version: "2.0.
|
|
7161
|
+
version: "2.0.12"};
|
|
6766
7162
|
|
|
6767
7163
|
// src/utils/get-product-details.ts
|
|
6768
7164
|
var getVersion = () => package_default.version;
|
|
@@ -6962,6 +7358,44 @@ var GedCom = class extends Common {
|
|
|
6962
7358
|
fams() {
|
|
6963
7359
|
return this.getList("@@FAM");
|
|
6964
7360
|
}
|
|
7361
|
+
nextIndiKey() {
|
|
7362
|
+
const ids = [];
|
|
7363
|
+
this.indis()?.forEach((_indi, id) => {
|
|
7364
|
+
ids.push(String(id));
|
|
7365
|
+
});
|
|
7366
|
+
return nextRecordId(ids, "I");
|
|
7367
|
+
}
|
|
7368
|
+
nextFamKey() {
|
|
7369
|
+
const ids = [];
|
|
7370
|
+
this.fams()?.forEach((_fam, id) => {
|
|
7371
|
+
ids.push(String(id));
|
|
7372
|
+
});
|
|
7373
|
+
return nextRecordId(ids, "F");
|
|
7374
|
+
}
|
|
7375
|
+
createIndividual() {
|
|
7376
|
+
const existing = this.indis();
|
|
7377
|
+
const indis = existing ?? new Individuals();
|
|
7378
|
+
if (!existing) {
|
|
7379
|
+
this.set("@@INDI", indis);
|
|
7380
|
+
}
|
|
7381
|
+
const id = this.nextIndiKey();
|
|
7382
|
+
const indi = createIndi(this, id);
|
|
7383
|
+
indi.type = "INDI";
|
|
7384
|
+
indis.item(id, indi);
|
|
7385
|
+
return indi;
|
|
7386
|
+
}
|
|
7387
|
+
createFamily() {
|
|
7388
|
+
const existing = this.fams();
|
|
7389
|
+
const fams = existing ?? new Families();
|
|
7390
|
+
if (!existing) {
|
|
7391
|
+
this.set("@@FAM", fams);
|
|
7392
|
+
}
|
|
7393
|
+
const id = this.nextFamKey();
|
|
7394
|
+
const fam = createFam(this, id);
|
|
7395
|
+
fam.type = "FAM";
|
|
7396
|
+
fams.item(id, fam);
|
|
7397
|
+
return fam;
|
|
7398
|
+
}
|
|
6965
7399
|
objes() {
|
|
6966
7400
|
return this.getList("@@OBJE");
|
|
6967
7401
|
}
|
|
@@ -7049,15 +7483,24 @@ var GedCom = class extends Common {
|
|
|
7049
7483
|
getDownloadHeader() {
|
|
7050
7484
|
const newHead = createCommon();
|
|
7051
7485
|
Object.assign(newHead, this.get("HEAD") ?? {});
|
|
7486
|
+
const existingSour = this.get("HEAD")?.get("SOUR");
|
|
7487
|
+
const existingTreeName = existingSour?.get("_TREE")?.toValue();
|
|
7488
|
+
const existingTreeUniqueId = existingSour?.get("_TID")?.toValue();
|
|
7052
7489
|
const newSour = createCommon();
|
|
7053
|
-
newSour.
|
|
7054
|
-
newSour.set("
|
|
7055
|
-
newSour.set("
|
|
7056
|
-
|
|
7057
|
-
|
|
7058
|
-
|
|
7059
|
-
|
|
7060
|
-
|
|
7490
|
+
newSour.value = APP_BRANDING;
|
|
7491
|
+
newSour.set("NAME", APP_BRANDING);
|
|
7492
|
+
newSour.set("VERS", getVersion());
|
|
7493
|
+
if (typeof existingTreeName === "string" && existingTreeName.trim()) {
|
|
7494
|
+
newSour.set("_TREE", existingTreeName.trim());
|
|
7495
|
+
}
|
|
7496
|
+
if (typeof existingTreeUniqueId === "string" && existingTreeUniqueId.trim()) {
|
|
7497
|
+
newSour.set("_TID", existingTreeUniqueId.trim());
|
|
7498
|
+
}
|
|
7499
|
+
const corp = createCommon();
|
|
7500
|
+
corp.value = APP_BRANDING;
|
|
7501
|
+
corp.set("WWW", "treeviz.com");
|
|
7502
|
+
corp.set("EMAIL", "info@treeviz.com");
|
|
7503
|
+
newSour.set("CORP", corp);
|
|
7061
7504
|
newHead.set("SOUR", newSour);
|
|
7062
7505
|
return newHead;
|
|
7063
7506
|
}
|
|
@@ -7086,15 +7529,17 @@ var GedCom = class extends Common {
|
|
|
7086
7529
|
}
|
|
7087
7530
|
toGedcom(tag, level, options) {
|
|
7088
7531
|
if (options?.super) {
|
|
7089
|
-
return
|
|
7532
|
+
return appendGedcomTrailer(
|
|
7533
|
+
super.toGedcom(tag, level, options)
|
|
7534
|
+
);
|
|
7090
7535
|
}
|
|
7091
7536
|
const newGedcom = createGedCom();
|
|
7537
|
+
Object.assign(newGedcom, this);
|
|
7092
7538
|
if (!options?.original) {
|
|
7093
7539
|
Object.assign(newGedcom, {
|
|
7094
7540
|
HEAD: this.getDownloadHeader()
|
|
7095
7541
|
});
|
|
7096
7542
|
}
|
|
7097
|
-
Object.assign(newGedcom, this);
|
|
7098
7543
|
if (options?.indis?.length) {
|
|
7099
7544
|
const newContent = this.getIndiRelatedLists(options.indis);
|
|
7100
7545
|
Object.assign(newGedcom, newContent);
|