@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.
Files changed (40) hide show
  1. package/dist/classes/common.d.ts +6 -1
  2. package/dist/classes/common.d.ts.map +1 -1
  3. package/dist/classes/fam.d.ts +9 -1
  4. package/dist/classes/fam.d.ts.map +1 -1
  5. package/dist/classes/gedcom.d.ts +6 -2
  6. package/dist/classes/gedcom.d.ts.map +1 -1
  7. package/dist/classes/index.js +495 -50
  8. package/dist/classes/indi.d.ts +6 -0
  9. package/dist/classes/indi.d.ts.map +1 -1
  10. package/dist/cli/index.js +3383 -2932
  11. package/dist/constants/constants.d.ts +7 -0
  12. package/dist/constants/constants.d.ts.map +1 -1
  13. package/dist/constants/index.js +1287 -916
  14. package/dist/factories/index.js +409 -39
  15. package/dist/index.d.ts +2 -0
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +5327 -4777
  18. package/dist/interfaces/fam.d.ts +7 -1
  19. package/dist/interfaces/fam.d.ts.map +1 -1
  20. package/dist/interfaces/gedcom.d.ts +4 -0
  21. package/dist/interfaces/gedcom.d.ts.map +1 -1
  22. package/dist/interfaces/indi.d.ts +5 -1
  23. package/dist/interfaces/indi.d.ts.map +1 -1
  24. package/dist/kinship-translator/index.js +409 -39
  25. package/dist/structures/gedcom.d.ts +1 -0
  26. package/dist/structures/gedcom.d.ts.map +1 -1
  27. package/dist/types/types.d.ts +10 -0
  28. package/dist/types/types.d.ts.map +1 -1
  29. package/dist/utils/fact-edit.d.ts +22 -0
  30. package/dist/utils/fact-edit.d.ts.map +1 -0
  31. package/dist/utils/family-edit.d.ts +23 -0
  32. package/dist/utils/family-edit.d.ts.map +1 -0
  33. package/dist/utils/gedcom-trailer.d.ts +6 -0
  34. package/dist/utils/gedcom-trailer.d.ts.map +1 -0
  35. package/dist/utils/index.d.ts +4 -1
  36. package/dist/utils/index.d.ts.map +1 -1
  37. package/dist/utils/index.js +605 -55
  38. package/dist/utils/parser.d.ts +3 -0
  39. package/dist/utils/parser.d.ts.map +1 -1
  40. package/package.json +1 -1
@@ -8,11 +8,13 @@ var __export = (target, all) => {
8
8
  };
9
9
 
10
10
  // src/constants/constants.ts
11
+ var APP_BRANDING = "TreeViz - The Family Tree Visualiser & Editor";
11
12
  var REF_LINE_REG = /^0 (?:(@[_a-zA-Z0-9]*@) )?(?<type>_[_A-Z][_a-zA-Z]{2,}|_?[A-Z][a-zA-Z]{2,}) ?(?<value>.*)/gm;
12
13
  var LINE_REG = /(?<indent>^[0-9]) (?:(@[_a-zA-Z0-9]*@) )?(?<type>_[_A-Z][_a-zA-Z]{2,}|_?[A-Z][a-zA-Z]{2,}) ?(?<value>.*)/;
13
14
  var ID_REG = /^@[_a-zA-Z0-9]+@/;
14
15
  var ID_GETTER_REG = /^(?<at>@)?(?<letter>[A-Z])?/i;
15
16
  var ID_SPLIT_REG = /^@[_a-zA-Z0-9]+@:/;
17
+ var ORIG_HEAD_TAG = "_ORIGHEAD";
16
18
  var MAX_FILE_SIZE_TO_SYNC = 1024 * 1024 * 20;
17
19
 
18
20
  // src/constants/filters.ts
@@ -543,1050 +545,1317 @@ var dateFormatter = (indi, showMarriages = false, showDays = false, showPlaces =
543
545
  } : {}
544
546
  };
545
547
  };
546
- var Common = class _Common {
547
- constructor(gedcom, id, main, parent) {
548
+
549
+ // src/utils/gedcom-trailer.ts
550
+ var GEDCOM_TRAILER_TAG = "TRLR";
551
+ var isGedcomTrailerTag = (tag) => tag === GEDCOM_TRAILER_TAG;
552
+ var List = class _List {
553
+ // length = 0;
554
+ constructor(items) {
555
+ this.items = {};
548
556
  this.isListable = true;
549
- this._gedcom = gedcom;
550
- this._main = main;
551
- this._parent = parent;
552
- this.initUniqueId();
553
- if (id) {
554
- this._id = id;
555
- } else {
556
- delete this._id;
557
+ this.marker = void 0;
558
+ if (items) {
559
+ this.concat(items);
557
560
  }
558
561
  }
559
- set type(type) {
560
- if (type) {
561
- this.uniqueId = this.uniqueId?.replace(/^[^:]+/, `~${type}`);
562
- }
563
- this._type = type;
562
+ get length() {
563
+ return this.values().length;
564
564
  }
565
- get type() {
566
- return this._type;
565
+ has(indi) {
566
+ return !!this.item(
567
+ typeof indi === "string" ? indi : indi?.id ?? ""
568
+ );
567
569
  }
568
- initUniqueId() {
569
- if (this._gedcom) {
570
- this.uniqueId = `~Common:${this._gedcom.refcount++}`;
571
- }
570
+ get(name) {
571
+ const propList = new _List();
572
+ this.entries().forEach(([key, item]) => {
573
+ propList.item(key, item.get(name));
574
+ });
575
+ return propList;
572
576
  }
573
- set uniqueId(id) {
574
- const currentId = this._uniqueId;
575
- if (this._gedcom?.reflist && id) {
576
- this._uniqueId = id;
577
- if (currentId && this._gedcom.reflist[currentId]) {
578
- delete this._gedcom.reflist[currentId];
577
+ getIf(name, condition, name2) {
578
+ const propList = new _List();
579
+ this.entries().forEach(([key, item]) => {
580
+ const passedItem = item.getIf(name, condition, name2);
581
+ if (passedItem) {
582
+ propList.item(key, passedItem);
579
583
  }
580
- this._gedcom.reflist[id] = this;
581
- }
584
+ });
585
+ return propList;
582
586
  }
583
- get uniqueId() {
584
- return this._uniqueId;
587
+ keys() {
588
+ return Object.keys(this.items);
585
589
  }
586
- set id(id) {
587
- this._id = idGetter(id);
590
+ values() {
591
+ return Object.values(this.items);
588
592
  }
589
- get id() {
590
- return idGetter(this._id);
593
+ entries() {
594
+ return Object.entries(this.items);
591
595
  }
592
- set value(value) {
593
- this._value = value;
596
+ setLength(_type) {
594
597
  }
595
- get value() {
596
- return this._value;
598
+ first() {
599
+ return this.index(0);
597
600
  }
598
- /**
599
- * Set the gedcom reference for this object
600
- * @param gedcom - The GedComType to set as the gedcom reference
601
- */
602
- setGedcom(gedcom) {
603
- this._gedcom = gedcom;
601
+ last() {
602
+ return this.index(this.keys().length - 1);
604
603
  }
605
- // avoid to override
606
- get originalValue() {
607
- return this._value;
604
+ index(index) {
605
+ const keys = this.keys();
606
+ const key = keys[index];
607
+ return key && this.items[key];
608
608
  }
609
- get ref() {
610
- if (typeof this.value === "string" && isId(this.value) && this.refType) {
611
- return this._gedcom?.[getListTag(this.refType)]?.item(
612
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
613
- this.value
614
- );
609
+ item(name, value) {
610
+ if (arguments.length > 1) {
611
+ set(this.items, name, value);
612
+ this.setLength();
615
613
  }
616
- return this;
614
+ return get(this.items, name);
617
615
  }
618
- get main() {
619
- return this._main;
616
+ removeItem(name) {
617
+ unset(this.items, name);
618
+ this.setLength();
620
619
  }
621
- get parent() {
622
- return this._parent;
620
+ exclude(excludedList) {
621
+ excludedList.keys().forEach((itemId) => {
622
+ delete this.items[itemId];
623
+ });
624
+ this.setLength();
625
+ return this;
623
626
  }
624
- addRef(refNode) {
625
- if (typeof refNode.value === "string" && isId(refNode.value) && refNode.refType) {
626
- if (!this._refs) {
627
- this._refs = new List();
628
- }
629
- this._refs.item(refNode.value, refNode);
627
+ concat(items) {
628
+ if (Array.isArray(items)) {
629
+ items.forEach((item) => {
630
+ this.append(item);
631
+ });
632
+ } else {
633
+ Object.assign(this.items, items ?? {});
630
634
  }
635
+ this.setLength();
636
+ return this;
631
637
  }
632
- getRefs() {
633
- return this._refs;
634
- }
635
- exportValue() {
636
- return this.value;
638
+ merge(mergedList) {
639
+ this.concat(mergedList?.items);
640
+ return this;
637
641
  }
638
- removeValue() {
639
- delete this._value;
642
+ intersection(mergedList) {
643
+ const inter = intersectionBy(
644
+ this.values(),
645
+ mergedList?.values() ?? [],
646
+ "id"
647
+ );
648
+ return new _List(inter);
640
649
  }
641
- set(name, value) {
642
- if (typeof value === "string") {
643
- const usedValue = createCommon(this._gedcom, void 0, this.main);
644
- usedValue.value = value;
645
- set(this, name, usedValue);
646
- } else {
647
- set(this, name, value);
648
- }
649
- return get(this, name);
650
+ difference(mergedList) {
651
+ const inter = differenceBy(
652
+ this.values(),
653
+ mergedList?.values() ?? [],
654
+ "id"
655
+ );
656
+ return new _List(inter);
650
657
  }
651
- assign(name, value, unique = false) {
652
- let curValue = this.get(name);
653
- if (curValue?.isListable) {
654
- if (curValue instanceof _Common) {
655
- curValue = new List().concat({ ...[curValue] });
656
- this.set(name, curValue);
658
+ prepend(item) {
659
+ if (item.id) {
660
+ let increase = true;
661
+ if (this.items[item.id]) {
662
+ delete this.items[item.id];
663
+ increase = false;
664
+ }
665
+ this.items = Object.assign(
666
+ {
667
+ [item.id]: item
668
+ },
669
+ this.items
670
+ );
671
+ if (increase) {
672
+ this.setLength("increase");
657
673
  }
658
- const values = [
659
- ...curValue.values(),
660
- ...value instanceof List ? value.values() : [value]
661
- ];
662
- curValue.concat({
663
- ...!unique ? values : uniqBy(
664
- values,
665
- (value2) => value2 instanceof _Common ? value2?.value : void 0
666
- )
667
- });
668
- } else {
669
- this.set(name, value);
670
674
  }
671
- return get(this, name);
675
+ return this;
672
676
  }
673
- get(name) {
674
- if (!name.includes(".")) {
675
- return get(this, name);
676
- }
677
- const nameParts = name.split(".");
678
- let last = this;
679
- for (const part of nameParts) {
680
- const indexPart = Number(part);
681
- const itemIndex = part.match(/items\[(?<itemIndex>\d+)\]/)?.groups?.itemIndex;
682
- const itemId = part.match(/items\[(?<itemId>@[A-Z]+\d+@)\]/)?.groups?.itemId;
683
- const usedPart = itemId || itemIndex;
684
- if (last instanceof List) {
685
- if (!isNaN(indexPart)) {
686
- last = last.index(indexPart);
687
- } else {
688
- if (usedPart) {
689
- last = last.item(usedPart);
690
- } else {
691
- last = last?.index(0)?.get(part);
692
- }
693
- }
694
- } else {
695
- const usedIndex = Number(itemIndex ?? indexPart);
696
- if (!isNaN(usedIndex)) {
697
- last = last?.toList().index(usedIndex);
698
- } else {
699
- last = last?.get(itemId ?? part);
700
- }
677
+ append(item) {
678
+ if (item.id) {
679
+ let increase = true;
680
+ if (this.items[item.id]) {
681
+ delete this.items[item.id];
682
+ increase = false;
701
683
  }
702
- if (!last) {
703
- break;
684
+ this.items[item.id] = item;
685
+ if (increase) {
686
+ this.setLength("increase");
704
687
  }
705
688
  }
706
- return last;
689
+ return this;
707
690
  }
708
- remove(name) {
709
- unset(this, name);
691
+ delete(item) {
692
+ if (item.id && this.items[item.id]) {
693
+ delete this.items[item.id];
694
+ this.setLength("decrease");
695
+ }
696
+ return this;
710
697
  }
711
- getGedcom() {
712
- return this._gedcom;
698
+ copy(ClassName = _List) {
699
+ const newList = new ClassName();
700
+ Object.assign(newList.items, this.items);
701
+ newList.setLength();
702
+ return newList;
713
703
  }
714
- getIf(name, condition, name2) {
715
- const nameParts = name.split(".");
716
- const name2Parts = name2.split(".");
717
- if (nameParts.length !== name2Parts.length) {
718
- throw new Error("Tag pathes must be of the same depth");
719
- }
720
- if (nameParts.length > 1 && nameParts[0] !== name2Parts[0]) {
721
- throw new Error("Final tags must be siblings");
722
- }
723
- const valueCommon = this.get(name);
724
- if (valueCommon instanceof _Common) {
725
- return valueCommon?.toValue() !== condition ? void 0 : this.get(name2);
726
- }
727
- const valueCommon2 = this.get(name2)?.toList();
728
- const ifList = new List();
729
- valueCommon?.forEach((item, key) => {
730
- const pair = valueCommon2?.item(key);
731
- ifList.item(key, item?.toValue() !== condition ? void 0 : pair);
732
- });
733
- return ifList;
734
- }
735
- toString() {
736
- return this.value?.toString() || "";
737
- }
738
- toValue() {
739
- return this.value;
740
- }
741
- toProp(tag) {
742
- const prop = this.get(tag);
743
- return prop;
744
- }
745
- toList() {
746
- return new List().concat(
747
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
748
- this.id ? { [this.id]: this } : { ...[this] }
749
- );
750
- }
751
- index(i) {
752
- return this.toList()?.index(i);
704
+ except(item, ClassName = _List) {
705
+ return this.copy(ClassName).delete(item);
753
706
  }
754
- toValueList() {
755
- return new List().concat(
756
- this.value ? { [this.value]: this } : (
757
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
758
- { ...[this] }
759
- )
760
- );
707
+ forEach(iterate) {
708
+ this.entries().forEach(([key, item], index) => {
709
+ iterate(item, key, index);
710
+ });
761
711
  }
762
- standardizeObject(tag, options) {
763
- if (tag === "OBJE" && !options?.original && options?.obje?.standardize && options?.obje?.namespace && "standardizeMedia" in this) {
764
- const standardize = this.standardizeMedia;
765
- return standardize.call(
766
- this,
767
- options.obje.namespace,
768
- options.obje.override
769
- );
770
- }
712
+ map(iterate) {
713
+ return this.entries().map(([key, item], index) => {
714
+ return iterate(item, key, index);
715
+ });
771
716
  }
772
- toJson(tag, options) {
773
- const json = this.toObject(tag, options);
774
- return JSON.stringify(json);
717
+ reduce(iterate, initialValue) {
718
+ return this.entries().reduce((acc, [key, item], index) => {
719
+ return iterate(acc, item, key, index);
720
+ }, initialValue);
775
721
  }
776
- toObject(tag, options) {
777
- this.standardizeObject(tag, options);
778
- const validKeys = getValidKeys(this);
779
- let json = {};
780
- validKeys.forEach((key) => {
781
- if (key === "id" && this.id !== void 0) {
782
- json.id = this.id;
783
- } else if (key === "_id" && this._id !== void 0) {
784
- json.id = this._id;
785
- } else if (key === "value" && this.value !== void 0) {
786
- json.value = this.value;
787
- } else if (key === "_value" && this._value !== void 0) {
788
- json.value = this._value;
789
- } else {
790
- const validKey = key;
791
- const prop = this.get(validKey);
792
- if (typeof prop?.toObject === "function") {
793
- if (prop instanceof _Common) {
794
- json[validKey] = prop.toObject(validKey, options);
795
- } else {
796
- json = {
797
- ...json,
798
- ...prop.toObject(validKey, options)
799
- };
800
- }
722
+ filter(filters, ClassName = _List) {
723
+ const newList = new ClassName();
724
+ const isIterator = typeof filters === "function";
725
+ this.entries().forEach(([itemId, item], index) => {
726
+ if (isIterator) {
727
+ filters(item, itemId, index) && newList.item(itemId, item);
728
+ return;
729
+ }
730
+ if (!Object.keys(filters).length || Object.entries(filters).every(([key, value]) => {
731
+ let itemValue;
732
+ if (key === "id") {
733
+ itemValue = item.toProp("id");
734
+ } else {
735
+ itemValue = item.toProp(key)?.toValue();
736
+ }
737
+ if (Array.isArray(value)) {
738
+ return value.includes(itemValue);
801
739
  }
740
+ return itemValue === value;
741
+ })) {
742
+ newList.item(itemId, item);
802
743
  }
803
744
  });
804
- return json;
745
+ return newList;
805
746
  }
806
- merge(other, override = false, avoidKeys = []) {
807
- if (!other) {
808
- return this;
809
- }
810
- const validKeys = getValidKeys(other);
811
- validKeys.forEach((validKey) => {
812
- if (avoidKeys.includes(validKey)) {
813
- return;
747
+ find(filters, _ClassName = _List) {
748
+ let foundItem;
749
+ const isIterator = typeof filters === "function";
750
+ this.entries().find(([itemId, item], index) => {
751
+ if (isIterator) {
752
+ if (filters(item, itemId, index)) {
753
+ foundItem = item;
754
+ return true;
755
+ }
756
+ return false;
814
757
  }
815
- const current = this.get(validKey);
816
- const mergeValue = other.get(validKey);
817
- if (mergeValue) {
818
- if (current instanceof _Common || current instanceof List) {
819
- this.assign(validKey, mergeValue, true);
820
- } else if (!current || override && validKey !== "id" && validKey !== "_id") {
821
- this.set(validKey, mergeValue);
758
+ if (!Object.keys(filters).length || Object.entries(filters).every(([key, value]) => {
759
+ let itemValue;
760
+ if (key === "id") {
761
+ itemValue = item.toProp("id");
762
+ } else {
763
+ itemValue = item.toProp(key)?.toValue();
764
+ }
765
+ if (Array.isArray(value)) {
766
+ return value.includes(itemValue);
822
767
  }
768
+ return itemValue === value;
769
+ })) {
770
+ foundItem = item;
771
+ return true;
823
772
  }
773
+ return false;
824
774
  });
825
- return this;
775
+ return foundItem;
826
776
  }
827
- clone(newId = false, avoidKeys = []) {
828
- const ctor = this.constructor;
829
- const instance = new ctor(
830
- this._gedcom,
831
- this._id,
832
- this._main,
833
- this._parent
834
- );
835
- if (newId && this._id) {
836
- instance.id = `IFT${this._id.replace(/[^0-9]/g, "")}`;
777
+ orderBy(orders, ClassName = _List) {
778
+ const newList = new ClassName();
779
+ const isIterator = typeof orders === "function";
780
+ if (!isIterator && (!orders || !Object.keys(orders).length)) {
781
+ return newList.merge(this);
837
782
  }
838
- const cloned = createProxy(instance);
839
- cloned.merge(this, true, avoidKeys);
840
- return cloned;
841
- }
842
- // fromGedcom<T = typeof this>(value: string) {
843
- fromGedcom(_value) {
844
- }
845
- toGedcom(tag, level = 0, options) {
846
- const gedcom = this.toGedcomLines(tag, level, options);
847
- return gedcom.join("\n");
848
- }
849
- toGedcomLines(tag, level = 0, options) {
850
- this.standardizeObject(tag, options);
851
- const validKeys = getValidKeys(this);
852
- const gedcom = [];
853
- validKeys.forEach((key) => {
854
- const validKey = key;
855
- const prop = this.get(validKey);
856
- if (typeof prop?.toGedcomLines === "function") {
857
- if (prop instanceof _Common) {
858
- const value = prop.exportValue();
859
- gedcom.push(
860
- `${level} ${validKey}${value ? ` ${value}` : ""}`
861
- );
862
- gedcom.push(
863
- ...prop.toGedcomLines(validKey, level + 1, options)
864
- );
865
- } else {
866
- gedcom.push(
867
- ...prop.toGedcomLines(validKey, level, options)
868
- );
783
+ const sortedItems = this.entries().toSorted(
784
+ ([itemAId, itemA], [itemBId, itemB]) => {
785
+ if (isIterator) {
786
+ return orders(itemA, itemAId, itemB, itemBId);
787
+ }
788
+ const [key, { direction, getter }] = Object.entries(
789
+ typeof orders === "string" ? { [orders]: { direction: "ASC" } } : orders
790
+ )[0];
791
+ const rawA = itemA.get(key);
792
+ const rawB = itemB.get(key);
793
+ let valueA = rawA?.toValue();
794
+ let valueB = rawB?.toValue();
795
+ if (getter && typeof getter === "function") {
796
+ valueA = getter(valueA, rawA);
797
+ valueB = getter(valueB, rawB);
798
+ }
799
+ let sortValue2 = 0;
800
+ if (!valueA && valueA !== 0 && !valueB && valueB !== 0) {
801
+ sortValue2 = 0;
802
+ } else if (!valueB && valueB !== 0) {
803
+ sortValue2 = 1;
804
+ } else if (!valueA && valueA !== 0) {
805
+ sortValue2 = -1;
806
+ } else if (valueA < valueB) {
807
+ sortValue2 = -1;
808
+ } else if (valueA > valueB) {
809
+ sortValue2 = 1;
869
810
  }
811
+ return sortValue2 * (direction === "DESC" ? -1 : 1);
870
812
  }
813
+ );
814
+ sortedItems.forEach(([key, value]) => {
815
+ newList.item(key, value);
871
816
  });
872
- return gedcom;
873
- }
874
- isGenoPro() {
875
- const head = get(this, "HEAD") || get(this.getGedcom(), "HEAD");
876
- const sour = get(head, "SOUR.value");
877
- return !!sour?.toLowerCase()?.startsWith("genopro");
878
- }
879
- isAhnenblatt() {
880
- const head = get(this, "HEAD") || get(this.getGedcom(), "HEAD");
881
- const sour = get(head, "SOUR.value");
882
- return !!sour?.toLowerCase()?.startsWith("ahnenblatt");
883
- }
884
- isGeni() {
885
- const head = get(this, "HEAD") || get(this.getGedcom(), "HEAD");
886
- const sour = get(head, "SOUR.value");
887
- return !!sour?.toLowerCase()?.startsWith("geni");
888
- }
889
- isAncestry() {
890
- const head = get(this, "HEAD") || get(this.getGedcom(), "HEAD");
891
- const sour = get(head, "SOUR.value");
892
- return !!sour?.toLowerCase()?.startsWith("ancestry");
893
- }
894
- isMyHeritage() {
895
- const head = get(this, "HEAD") || get(this.getGedcom(), "HEAD");
896
- const sour = get(head, "SOUR.value");
897
- return !!sour?.toLowerCase()?.startsWith("myheritage");
817
+ return newList;
898
818
  }
899
- /**
900
- * Get the source type as a string (for prefixing tree IDs and names)
901
- * Returns the detected source type or undefined if unknown
902
- */
903
- getSourceType() {
904
- if (this.isAncestry()) return "Ancestry";
905
- if (this.isMyHeritage()) return "MyHeritage";
906
- if (this.isFamilySearch()) return "FamilySearch";
907
- if (this.isGNO2GED()) return "GNO2GED";
908
- if (this.isGenoPro()) return "GenoPro";
909
- if (this.isAhnenblatt()) return "Ahnenblatt";
910
- if (this.isGeni()) return "Geni";
911
- return void 0;
819
+ groupBy(groups, sort, minOccurance = -1, lessOccuranceLabel = "Appearing less than 5 times", ClassName = _List) {
820
+ const groupped = {};
821
+ const isIterator = typeof groups === "function";
822
+ if (!isIterator && (!groups || !Object.keys(groups).length)) {
823
+ groupped.Unknown = new ClassName().merge(this);
824
+ groupped.Unknown.marker = "Unknown";
825
+ return groupped;
826
+ }
827
+ this.forEach((item, itemId) => {
828
+ const group = [];
829
+ if (isIterator) {
830
+ const newGroups = groups(item, itemId);
831
+ group.push(
832
+ ...Array.isArray(newGroups) ? newGroups : [newGroups]
833
+ );
834
+ } else {
835
+ const [key, { getter }] = Object.entries(
836
+ typeof groups === "string" ? { [groups]: {} } : groups
837
+ )[0];
838
+ const raw = item.get(key)?.index(0);
839
+ let value = raw?.toValue();
840
+ if (getter && typeof getter === "function") {
841
+ value = getter(value, raw);
842
+ }
843
+ if (value) {
844
+ group.push(value);
845
+ }
846
+ }
847
+ if (!group.length) {
848
+ group.push("Unknown");
849
+ }
850
+ group.forEach((g) => {
851
+ const newGroup = typeof g === "string" ? { group: g } : g;
852
+ if (!groupped[newGroup.group]) {
853
+ groupped[newGroup.group] = new ClassName();
854
+ groupped[newGroup.group].marker = newGroup.marker ?? newGroup.group;
855
+ }
856
+ groupped[newGroup.group]?.append(item);
857
+ });
858
+ });
859
+ if (sort) {
860
+ return Object.entries(groupped).toSorted(([ak, a], [bk, b]) => {
861
+ if (typeof sort === "function") {
862
+ return sort(a, ak, b, bk);
863
+ }
864
+ if (ak === "Unknown") {
865
+ return 1;
866
+ }
867
+ if (bk === "Unknown") {
868
+ return -1;
869
+ }
870
+ if (sort === "group") {
871
+ return ak.localeCompare(bk);
872
+ }
873
+ return (b?.length ?? 0) - (a?.length ?? 0);
874
+ }).reduce((acc, [key, value]) => {
875
+ if (minOccurance > -1 && (value?.length ?? 0) < minOccurance) {
876
+ const otherKey = lessOccuranceLabel;
877
+ acc[otherKey] = acc[otherKey] && value ? acc[otherKey].merge(value) : value;
878
+ } else {
879
+ acc[key] = value;
880
+ }
881
+ return acc;
882
+ }, {});
883
+ }
884
+ return groupped;
912
885
  }
913
- isFamilySearch() {
914
- const head = get(this, "HEAD") || get(this.getGedcom(), "HEAD");
915
- const sourName = get(head, "SOUR.NAME.value");
916
- return sourName === "FamilySearch API";
886
+ findIndex(item) {
887
+ if (!item?.id) {
888
+ return -1;
889
+ }
890
+ return this.keys().findIndex((key) => key === item.id);
917
891
  }
918
- isGNO2GED() {
919
- const head = get(this, "HEAD") || get(this.getGedcom(), "HEAD");
920
- const sour = get(head, "SOUR.value");
921
- return sour === "GNO2GED";
892
+ getItems() {
893
+ return this.items;
922
894
  }
923
- getAncestryTreeId() {
924
- const path = "HEAD.SOUR._TREE.RIN.value";
925
- return get(this, path) || get(this.getGedcom(), path);
895
+ toJson(tag, options) {
896
+ const json = this.toObject(tag, options);
897
+ return JSON.stringify(json);
926
898
  }
927
- getMyHeritageTreeId() {
928
- const path = "HEAD._EXPORTED_FROM_SITE_ID.value";
929
- return get(this, path) || get(this.getGedcom(), path);
899
+ toObject(tag, options) {
900
+ const json = {};
901
+ this.entries().forEach(([_, item]) => {
902
+ const validTag = getValidTag(tag);
903
+ if (json[validTag]) {
904
+ if (!Array.isArray(json[validTag])) {
905
+ json[validTag] = [json[validTag]];
906
+ }
907
+ json[validTag].push(
908
+ item.toObject(validTag, options)
909
+ );
910
+ } else {
911
+ json[validTag] = item.toObject(
912
+ validTag,
913
+ options
914
+ );
915
+ }
916
+ });
917
+ return json;
930
918
  }
931
- getTreeId() {
932
- if (this?.isAncestry()) {
933
- const id = this.getAncestryTreeId();
934
- if (id !== void 0) return id;
935
- }
936
- if (this?.isMyHeritage()) {
937
- const id = this.getMyHeritageTreeId();
938
- if (id !== void 0) return id;
939
- }
940
- if (this?.isFamilySearch()) {
941
- const id = this.getFamilySearchTreeId();
942
- if (id !== void 0) return id;
943
- }
944
- if (this?.isGNO2GED()) {
945
- const id = this.getGNO2GEDTreeId();
946
- if (id !== void 0) return id;
947
- }
948
- if (this?.isAhnenblatt()) {
949
- const id = this.getAhnenblattTreeId();
950
- if (id !== void 0) return id;
951
- }
952
- if (this?.isGeni()) {
953
- const id = this.getGeniTreeId();
954
- if (id !== void 0) return id;
955
- }
956
- if (this?.isGenoPro()) {
957
- const id = this.getGenoProTreeId();
958
- if (id !== void 0) return id;
959
- }
960
- return this.getUniversalTreeId();
919
+ toGedcom(tag, level = 0, options) {
920
+ const gedcom = this.toGedcomLines(tag, level, options);
921
+ return gedcom.join("\n");
961
922
  }
962
- getAncestryTreeName() {
963
- const path = "HEAD.SOUR._TREE.value";
964
- return get(this, path) || get(this.getGedcom(), path);
923
+ toGedcomLines(tag, level = 0, options) {
924
+ const gedcom = [];
925
+ this.entries().forEach(([_, item]) => {
926
+ const validTag = getValidTag(tag);
927
+ const validKey = item.id;
928
+ const validValue = validKey ? validTag : item.exportValue();
929
+ gedcom.push(
930
+ `${level} ${validKey || validTag}${validValue ? ` ${validValue}` : ""}`
931
+ );
932
+ gedcom.push(
933
+ ...item.toGedcomLines(
934
+ validTag,
935
+ level + 1,
936
+ options
937
+ )
938
+ );
939
+ });
940
+ return gedcom;
965
941
  }
966
- getMyHeritageTreeName() {
967
- const path = "HEAD.FILE.value";
968
- const treeDetails = get(this, path) || get(this.getGedcom(), path);
969
- return treeDetails?.match(
970
- /Exported by MyHeritage.com from (?<tree>.+) in.+$/
971
- )?.groups?.tree;
942
+ toValue() {
943
+ const propList = new _List();
944
+ this.entries().forEach(([key, item]) => {
945
+ propList.item(key, item?.toValue());
946
+ });
947
+ return propList;
972
948
  }
973
- getFamilySearchTreeId() {
974
- const rin = get(this, "HEAD.SOUR._TREE.RIN.value") || get(this.getGedcom(), "HEAD.SOUR._TREE.RIN.value");
975
- if (rin) {
976
- return rin;
977
- }
978
- return "familysearch";
949
+ // @deprecated use get instead
950
+ toProp(tag) {
951
+ return this.get(tag);
979
952
  }
980
- getFamilySearchTreeName() {
981
- const treeName = get(this, "HEAD.SOUR._TREE.value") || get(this.getGedcom(), "HEAD.SOUR._TREE.value");
982
- if (treeName) {
983
- return treeName;
953
+ toList() {
954
+ return new _List().concat(this.items);
955
+ }
956
+ toValueList() {
957
+ const newList = new _List();
958
+ this.values().forEach((value) => {
959
+ value.value && newList.item(value.value, value);
960
+ });
961
+ return newList;
962
+ }
963
+ };
964
+
965
+ // src/classes/common.ts
966
+ var Common = class _Common {
967
+ constructor(gedcom, id, main, parent) {
968
+ this.isListable = true;
969
+ this._gedcom = gedcom;
970
+ this._main = main;
971
+ this._parent = parent;
972
+ this.initUniqueId();
973
+ if (id) {
974
+ this._id = id;
975
+ } else {
976
+ delete this._id;
984
977
  }
985
- const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
986
- return fileName || "FamilySearch Import";
987
978
  }
988
- getAhnenblattTreeId() {
989
- const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
990
- if (fileName) {
991
- const idMatch = fileName.match(/_(\d+)/);
992
- if (idMatch) {
993
- return idMatch[1];
994
- }
979
+ set type(type) {
980
+ if (type) {
981
+ this.uniqueId = this.uniqueId?.replace(/^[^:]+/, `~${type}`);
995
982
  }
996
- return void 0;
983
+ this._type = type;
997
984
  }
998
- getAhnenblattTreeName() {
999
- const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
1000
- return fileName?.replace(/\.ged$/i, "").replace(/_/g, " ");
985
+ get type() {
986
+ return this._type;
1001
987
  }
1002
- getGeniTreeId() {
1003
- const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
1004
- if (fileName) {
1005
- const idMatch = fileName.match(/_(\d+)/);
1006
- if (idMatch) {
1007
- return idMatch[1];
1008
- }
988
+ initUniqueId() {
989
+ if (this._gedcom) {
990
+ this.uniqueId = `~Common:${this._gedcom.refcount++}`;
1009
991
  }
1010
- return void 0;
1011
992
  }
1012
- getGeniTreeName() {
1013
- const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
1014
- return fileName?.replace(/\.ged$/i, "").replace(/_/g, " ");
1015
- }
1016
- getGenoProTreeId() {
1017
- const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
1018
- if (fileName) {
1019
- const idMatch = fileName.match(/_(\d+)/);
1020
- if (idMatch) {
1021
- return idMatch[1];
993
+ set uniqueId(id) {
994
+ const currentId = this._uniqueId;
995
+ if (this._gedcom?.reflist && id) {
996
+ this._uniqueId = id;
997
+ if (currentId && this._gedcom.reflist[currentId]) {
998
+ delete this._gedcom.reflist[currentId];
1022
999
  }
1000
+ this._gedcom.reflist[id] = this;
1023
1001
  }
1024
- return void 0;
1025
1002
  }
1026
- getGenoProTreeName() {
1027
- const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
1028
- return fileName?.replace(/\.ged$/i, "").replace(/_/g, " ");
1003
+ get uniqueId() {
1004
+ return this._uniqueId;
1029
1005
  }
1030
- getGNO2GEDTreeId() {
1031
- const rin = get(this, "HEAD._TREE.RIN.value") || get(this.getGedcom(), "HEAD._TREE.RIN.value");
1032
- if (rin) {
1033
- return rin;
1034
- }
1035
- return `gno_${this._gedcom?.refcount || "unknown"}`;
1006
+ set id(id) {
1007
+ this._id = idGetter(id);
1036
1008
  }
1037
- getGNO2GEDTreeName() {
1038
- const treeName = get(this, "HEAD._TREE.value") || get(this.getGedcom(), "HEAD._TREE.value");
1039
- if (treeName) {
1040
- return treeName;
1041
- }
1042
- const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
1043
- return fileName || "GNO2GED Export";
1009
+ get id() {
1010
+ return idGetter(this._id);
1044
1011
  }
1045
- /**
1046
- * Universal tree ID getter for unknown/unrecognized GEDCOM sources
1047
- * Tries to extract an ID from various common locations
1048
- */
1049
- getUniversalTreeId() {
1050
- const sourceType = this.getSourceType();
1051
- const prefix = sourceType ? sourceType.toLowerCase() : "tree";
1052
- const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
1053
- if (fileName) {
1054
- const idMatch = fileName.match(/_(\d+)/);
1055
- if (idMatch) {
1056
- return `${prefix}_${idMatch[1]}`;
1057
- }
1058
- }
1059
- return `${prefix}_${this._gedcom?.refcount || "unknown"}`;
1012
+ set value(value) {
1013
+ this._value = value;
1014
+ }
1015
+ get value() {
1016
+ return this._value;
1060
1017
  }
1061
1018
  /**
1062
- * Universal tree name getter for unknown/unrecognized GEDCOM sources
1063
- * Tries to extract a name from various common locations
1019
+ * Set the gedcom reference for this object
1020
+ * @param gedcom - The GedComType to set as the gedcom reference
1064
1021
  */
1065
- getUniversalTreeName() {
1066
- const sourceType = this.getSourceType();
1067
- const prefix = sourceType ? `${sourceType}-` : "";
1068
- const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
1069
- if (fileName) {
1070
- const cleanName = fileName.replace(/\.ged$/i, "").replace(/_/g, " ");
1071
- return `${prefix}${cleanName}`;
1072
- }
1073
- const sourName = get(this, "HEAD.SOUR.NAME.value") || get(this.getGedcom(), "HEAD.SOUR.NAME.value");
1074
- if (sourName) {
1075
- return `${prefix}${sourName}`;
1076
- }
1077
- const sourValue = get(this, "HEAD.SOUR.value") || get(this.getGedcom(), "HEAD.SOUR.value");
1078
- if (sourValue) {
1079
- return `${prefix}${sourValue}`;
1080
- }
1081
- return `${prefix}Unknown Tree`;
1022
+ setGedcom(gedcom) {
1023
+ this._gedcom = gedcom;
1082
1024
  }
1083
- getTreeName() {
1084
- if (this?.isAncestry()) {
1085
- const name = this.getAncestryTreeName();
1086
- if (name) return name;
1087
- }
1088
- if (this?.isMyHeritage()) {
1089
- const name = this.getMyHeritageTreeName();
1090
- if (name) return name;
1025
+ // avoid to override
1026
+ get originalValue() {
1027
+ return this._value;
1028
+ }
1029
+ get ref() {
1030
+ if (typeof this.value === "string" && isId(this.value) && this.refType) {
1031
+ return this._gedcom?.[getListTag(this.refType)]?.item(
1032
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1033
+ this.value
1034
+ );
1091
1035
  }
1092
- if (this?.isFamilySearch()) {
1093
- const name = this.getFamilySearchTreeName();
1094
- if (name) return name;
1036
+ return this;
1037
+ }
1038
+ get main() {
1039
+ return this._main;
1040
+ }
1041
+ get parent() {
1042
+ return this._parent;
1043
+ }
1044
+ addRef(refNode) {
1045
+ if (typeof refNode.value === "string" && isId(refNode.value) && refNode.refType) {
1046
+ if (!this._refs) {
1047
+ this._refs = new List();
1048
+ }
1049
+ this._refs.item(refNode.value, refNode);
1095
1050
  }
1096
- if (this?.isGNO2GED()) {
1097
- const name = this.getGNO2GEDTreeName();
1098
- if (name) return name;
1051
+ }
1052
+ getRefs() {
1053
+ return this._refs;
1054
+ }
1055
+ exportValue() {
1056
+ return this.value;
1057
+ }
1058
+ removeValue() {
1059
+ delete this._value;
1060
+ }
1061
+ set(name, value) {
1062
+ if (isGedcomTrailerTag(name)) {
1063
+ return void 0;
1099
1064
  }
1100
- if (this?.isAhnenblatt()) {
1101
- const name = this.getAhnenblattTreeName();
1102
- if (name) return name;
1065
+ if (typeof value === "string") {
1066
+ const usedValue = createCommon(this._gedcom, void 0, this.main);
1067
+ usedValue.value = value;
1068
+ set(this, name, usedValue);
1069
+ } else {
1070
+ set(this, name, value);
1103
1071
  }
1104
- if (this?.isGeni()) {
1105
- const name = this.getGeniTreeName();
1106
- if (name) return name;
1072
+ return get(this, name);
1073
+ }
1074
+ assign(name, value, unique = false) {
1075
+ if (isGedcomTrailerTag(name)) {
1076
+ return void 0;
1107
1077
  }
1108
- if (this?.isGenoPro()) {
1109
- const name = this.getGenoProTreeName();
1110
- if (name) return name;
1078
+ let curValue = this.get(name);
1079
+ if (curValue?.isListable) {
1080
+ if (curValue instanceof _Common) {
1081
+ curValue = new List().concat({ ...[curValue] });
1082
+ this.set(name, curValue);
1083
+ }
1084
+ const values = [
1085
+ ...curValue.values(),
1086
+ ...value instanceof List ? value.values() : [value]
1087
+ ];
1088
+ curValue.concat({
1089
+ ...!unique ? values : uniqBy(
1090
+ values,
1091
+ (value2) => value2 instanceof _Common ? value2?.value : void 0
1092
+ )
1093
+ });
1094
+ } else {
1095
+ this.set(name, value);
1111
1096
  }
1112
- return this.getUniversalTreeName();
1097
+ return get(this, name);
1113
1098
  }
1114
- };
1115
- var createProxy = (target) => {
1116
- return new Proxy(target, {
1117
- get(t, prop, receiver) {
1118
- if (prop === "unwrapped") {
1119
- return target;
1120
- }
1121
- if (prop in t) {
1122
- return Reflect.get(t, prop, receiver);
1123
- }
1124
- if (!isOnlyMainProp(prop)) {
1125
- const ref = t.ref;
1126
- if (ref && prop in ref) {
1127
- return Reflect.get(ref, prop, receiver);
1099
+ get(name) {
1100
+ if (!name.includes(".")) {
1101
+ return get(this, name);
1102
+ }
1103
+ const nameParts = name.split(".");
1104
+ let last = this;
1105
+ for (const part of nameParts) {
1106
+ const indexPart = Number(part);
1107
+ const itemIndex = part.match(/items\[(?<itemIndex>\d+)\]/)?.groups?.itemIndex;
1108
+ const itemId = part.match(/items\[(?<itemId>@[A-Z]+\d+@)\]/)?.groups?.itemId;
1109
+ const usedPart = itemId || itemIndex;
1110
+ if (last instanceof List) {
1111
+ if (!isNaN(indexPart)) {
1112
+ last = last.index(indexPart);
1113
+ } else {
1114
+ if (usedPart) {
1115
+ last = last.item(usedPart);
1116
+ } else {
1117
+ last = last?.index(0)?.get(part);
1118
+ }
1119
+ }
1120
+ } else {
1121
+ const usedIndex = Number(itemIndex ?? indexPart);
1122
+ if (!isNaN(usedIndex)) {
1123
+ last = last?.toList().index(usedIndex);
1124
+ } else {
1125
+ last = last?.get(itemId ?? part);
1128
1126
  }
1129
1127
  }
1128
+ if (!last) {
1129
+ break;
1130
+ }
1130
1131
  }
1131
- });
1132
- };
1133
- var createCommon = (gedcom, id, main, parent) => {
1134
- return createProxy(
1135
- new Common(gedcom, id, main, parent)
1136
- );
1137
- };
1138
- var isOnlyMainProp = (key) => {
1139
- return key === "_gedcom" || key === "_main" || key === "_parent" || key === "_uniqueId" || key === "_type" || key === "_refs" || key === "id" || key === "_id";
1140
- };
1141
- var isValidKey = (common, key) => {
1142
- const prop = get(common, key);
1143
- 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);
1144
- };
1145
- var getValidKeys = (common) => {
1146
- return Object.keys(common).filter((key) => {
1147
- return isValidKey(common, key);
1148
- });
1149
- };
1150
- var getValidTag = (tag) => {
1151
- return tag.replace(/^@@/, "");
1152
- };
1153
- var getListTag = (tag) => {
1154
- return `@@${tag}`;
1155
- };
1156
- var isId = (string) => {
1157
- return ID_REG.test(string);
1158
- };
1159
- var idGetter = (id) => {
1160
- if (id === void 0) {
1161
- return void 0;
1132
+ return last;
1162
1133
  }
1163
- let newId = `${id}`;
1164
- const parts = newId?.match(ID_GETTER_REG)?.groups;
1165
- if (!parts?.at && !parts?.letter) {
1166
- newId = `@U${newId}`;
1167
- } else if (!parts.at) {
1168
- newId = `@${newId}`;
1169
- } else if (!parts.letter) {
1170
- newId = newId.replace(/^@/, "@U");
1134
+ remove(name) {
1135
+ unset(this, name);
1171
1136
  }
1172
- if (!newId.endsWith("@")) {
1173
- newId = `${newId}@`;
1137
+ getGedcom() {
1138
+ return this._gedcom;
1174
1139
  }
1175
- return newId;
1176
- };
1177
-
1178
- // src/classes/list.ts
1179
- var List = class _List {
1180
- // length = 0;
1181
- constructor(items) {
1182
- this.items = {};
1183
- this.isListable = true;
1184
- this.marker = void 0;
1185
- if (items) {
1186
- this.concat(items);
1140
+ getIf(name, condition, name2) {
1141
+ const nameParts = name.split(".");
1142
+ const name2Parts = name2.split(".");
1143
+ if (nameParts.length !== name2Parts.length) {
1144
+ throw new Error("Tag pathes must be of the same depth");
1187
1145
  }
1188
- }
1189
- get length() {
1190
- return this.values().length;
1191
- }
1192
- has(indi) {
1193
- return !!this.item(
1194
- typeof indi === "string" ? indi : indi?.id ?? ""
1195
- );
1196
- }
1197
- get(name) {
1198
- const propList = new _List();
1199
- this.entries().forEach(([key, item]) => {
1200
- propList.item(key, item.get(name));
1201
- });
1202
- return propList;
1203
- }
1204
- getIf(name, condition, name2) {
1205
- const propList = new _List();
1206
- this.entries().forEach(([key, item]) => {
1207
- const passedItem = item.getIf(name, condition, name2);
1208
- if (passedItem) {
1209
- propList.item(key, passedItem);
1210
- }
1146
+ if (nameParts.length > 1 && nameParts[0] !== name2Parts[0]) {
1147
+ throw new Error("Final tags must be siblings");
1148
+ }
1149
+ const valueCommon = this.get(name);
1150
+ if (valueCommon instanceof _Common) {
1151
+ return valueCommon?.toValue() !== condition ? void 0 : this.get(name2);
1152
+ }
1153
+ const valueCommon2 = this.get(name2)?.toList();
1154
+ const ifList = new List();
1155
+ valueCommon?.forEach((item, key) => {
1156
+ const pair = valueCommon2?.item(key);
1157
+ ifList.item(key, item?.toValue() !== condition ? void 0 : pair);
1211
1158
  });
1212
- return propList;
1213
- }
1214
- keys() {
1215
- return Object.keys(this.items);
1159
+ return ifList;
1216
1160
  }
1217
- values() {
1218
- return Object.values(this.items);
1161
+ toString() {
1162
+ return this.value?.toString() || "";
1219
1163
  }
1220
- entries() {
1221
- return Object.entries(this.items);
1164
+ toValue() {
1165
+ return this.value;
1222
1166
  }
1223
- setLength(_type) {
1167
+ toProp(tag) {
1168
+ const prop = this.get(tag);
1169
+ return prop;
1224
1170
  }
1225
- first() {
1226
- return this.index(0);
1171
+ toList() {
1172
+ return new List().concat(
1173
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1174
+ this.id ? { [this.id]: this } : { ...[this] }
1175
+ );
1227
1176
  }
1228
- last() {
1229
- return this.index(this.keys().length - 1);
1177
+ index(i) {
1178
+ return this.toList()?.index(i);
1230
1179
  }
1231
- index(index) {
1232
- const keys = this.keys();
1233
- const key = keys[index];
1234
- return key && this.items[key];
1180
+ toValueList() {
1181
+ return new List().concat(
1182
+ this.value ? { [this.value]: this } : (
1183
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1184
+ { ...[this] }
1185
+ )
1186
+ );
1235
1187
  }
1236
- item(name, value) {
1237
- if (arguments.length > 1) {
1238
- set(this.items, name, value);
1239
- this.setLength();
1188
+ standardizeObject(tag, options) {
1189
+ if (tag === "OBJE" && !options?.original && options?.obje?.standardize && options?.obje?.namespace && "standardizeMedia" in this) {
1190
+ const standardize = this.standardizeMedia;
1191
+ return standardize.call(
1192
+ this,
1193
+ options.obje.namespace,
1194
+ options.obje.override
1195
+ );
1240
1196
  }
1241
- return get(this.items, name);
1242
1197
  }
1243
- removeItem(name) {
1244
- unset(this.items, name);
1245
- this.setLength();
1198
+ toJson(tag, options) {
1199
+ const json = this.toObject(tag, options);
1200
+ return JSON.stringify(json);
1246
1201
  }
1247
- exclude(excludedList) {
1248
- excludedList.keys().forEach((itemId) => {
1249
- delete this.items[itemId];
1202
+ toObject(tag, options) {
1203
+ this.standardizeObject(tag, options);
1204
+ const validKeys = getValidKeys(this);
1205
+ let json = {};
1206
+ validKeys.forEach((key) => {
1207
+ if (key === "id" && this.id !== void 0) {
1208
+ json.id = this.id;
1209
+ } else if (key === "_id" && this._id !== void 0) {
1210
+ json.id = this._id;
1211
+ } else if (key === "value" && this.value !== void 0) {
1212
+ json.value = this.value;
1213
+ } else if (key === "_value" && this._value !== void 0) {
1214
+ json.value = this._value;
1215
+ } else {
1216
+ const validKey = key;
1217
+ const prop = this.get(validKey);
1218
+ if (typeof prop?.toObject === "function") {
1219
+ if (prop instanceof _Common) {
1220
+ json[validKey] = prop.toObject(validKey, options);
1221
+ } else {
1222
+ json = {
1223
+ ...json,
1224
+ ...prop.toObject(validKey, options)
1225
+ };
1226
+ }
1227
+ }
1228
+ }
1250
1229
  });
1251
- this.setLength();
1252
- return this;
1230
+ return json;
1253
1231
  }
1254
- concat(items) {
1255
- if (Array.isArray(items)) {
1256
- items.forEach((item) => {
1257
- this.append(item);
1258
- });
1259
- } else {
1260
- Object.assign(this.items, items ?? {});
1232
+ merge(other, override = false, avoidKeys = []) {
1233
+ if (!other) {
1234
+ return this;
1261
1235
  }
1262
- this.setLength();
1263
- return this;
1264
- }
1265
- merge(mergedList) {
1266
- this.concat(mergedList?.items);
1236
+ const validKeys = getValidKeys(other);
1237
+ validKeys.forEach((validKey) => {
1238
+ if (avoidKeys.includes(validKey)) {
1239
+ return;
1240
+ }
1241
+ const current = this.get(validKey);
1242
+ const mergeValue = other.get(validKey);
1243
+ if (mergeValue) {
1244
+ if (current instanceof _Common || current instanceof List) {
1245
+ this.assign(validKey, mergeValue, true);
1246
+ } else if (!current || override && validKey !== "id" && validKey !== "_id") {
1247
+ this.set(validKey, mergeValue);
1248
+ }
1249
+ }
1250
+ });
1267
1251
  return this;
1268
1252
  }
1269
- intersection(mergedList) {
1270
- const inter = intersectionBy(
1271
- this.values(),
1272
- mergedList?.values() ?? [],
1273
- "id"
1253
+ clone(newId = false, avoidKeys = []) {
1254
+ const ctor = this.constructor;
1255
+ const instance = new ctor(
1256
+ this._gedcom,
1257
+ this._id,
1258
+ this._main,
1259
+ this._parent
1274
1260
  );
1275
- return new _List(inter);
1261
+ if (newId && this._id) {
1262
+ instance.id = `IFT${this._id.replace(/[^0-9]/g, "")}`;
1263
+ }
1264
+ const cloned = createProxy(instance);
1265
+ cloned.merge(this, true, avoidKeys);
1266
+ return cloned;
1276
1267
  }
1277
- difference(mergedList) {
1278
- const inter = differenceBy(
1279
- this.values(),
1280
- mergedList?.values() ?? [],
1281
- "id"
1282
- );
1283
- return new _List(inter);
1268
+ // fromGedcom<T = typeof this>(value: string) {
1269
+ fromGedcom(_value) {
1284
1270
  }
1285
- prepend(item) {
1286
- if (item.id) {
1287
- let increase = true;
1288
- if (this.items[item.id]) {
1289
- delete this.items[item.id];
1290
- increase = false;
1291
- }
1292
- this.items = Object.assign(
1293
- {
1294
- [item.id]: item
1295
- },
1296
- this.items
1297
- );
1298
- if (increase) {
1299
- this.setLength("increase");
1300
- }
1301
- }
1302
- return this;
1271
+ toGedcom(tag, level = 0, options) {
1272
+ const gedcom = this.toGedcomLines(tag, level, options);
1273
+ return gedcom.join("\n");
1303
1274
  }
1304
- append(item) {
1305
- if (item.id) {
1306
- let increase = true;
1307
- if (this.items[item.id]) {
1308
- delete this.items[item.id];
1309
- increase = false;
1310
- }
1311
- this.items[item.id] = item;
1312
- if (increase) {
1313
- this.setLength("increase");
1275
+ toGedcomLines(tag, level = 0, options) {
1276
+ this.standardizeObject(tag, options);
1277
+ const validKeys = getValidKeys(this);
1278
+ const gedcom = [];
1279
+ validKeys.forEach((key) => {
1280
+ const validKey = key;
1281
+ const prop = this.get(validKey);
1282
+ if (typeof prop?.toGedcomLines === "function") {
1283
+ if (prop instanceof _Common) {
1284
+ const value = prop.exportValue();
1285
+ gedcom.push(
1286
+ `${level} ${validKey}${value ? ` ${value}` : ""}`
1287
+ );
1288
+ gedcom.push(
1289
+ ...prop.toGedcomLines(validKey, level + 1, options)
1290
+ );
1291
+ } else {
1292
+ gedcom.push(
1293
+ ...prop.toGedcomLines(validKey, level, options)
1294
+ );
1295
+ }
1314
1296
  }
1315
- }
1316
- return this;
1297
+ });
1298
+ return gedcom;
1317
1299
  }
1318
- delete(item) {
1319
- if (item.id && this.items[item.id]) {
1320
- delete this.items[item.id];
1321
- this.setLength("decrease");
1322
- }
1323
- return this;
1300
+ getHeadRecord() {
1301
+ return get(this, "HEAD") || get(this.getGedcom(), "HEAD");
1324
1302
  }
1325
- copy(ClassName = _List) {
1326
- const newList = new ClassName();
1327
- Object.assign(newList.items, this.items);
1328
- newList.setLength();
1329
- return newList;
1303
+ getOriginalHeadRecord() {
1304
+ return get(this, ORIG_HEAD_TAG) || get(this.getGedcom(), ORIG_HEAD_TAG) || get(this.getHeadRecord(), ORIG_HEAD_TAG);
1330
1305
  }
1331
- except(item, ClassName = _List) {
1332
- return this.copy(ClassName).delete(item);
1306
+ getSourceHeads() {
1307
+ const heads = [this.getOriginalHeadRecord(), this.getHeadRecord()];
1308
+ return heads.filter((head, index) => {
1309
+ return Boolean(head && heads.indexOf(head) === index);
1310
+ });
1333
1311
  }
1334
- forEach(iterate) {
1335
- this.entries().forEach(([key, item], index) => {
1336
- iterate(item, key, index);
1312
+ getFromSourceHeads(path) {
1313
+ for (const head of this.getSourceHeads()) {
1314
+ const value = get(head, path);
1315
+ if (value !== void 0 && value !== null && value !== "") {
1316
+ return value;
1317
+ }
1318
+ }
1319
+ return void 0;
1320
+ }
1321
+ sourStartsWith(prefix) {
1322
+ return this.getSourceHeads().some((head) => {
1323
+ const sour = get(head, "SOUR.value");
1324
+ return !!sour?.toLowerCase()?.startsWith(prefix);
1337
1325
  });
1338
1326
  }
1339
- map(iterate) {
1340
- return this.entries().map(([key, item], index) => {
1341
- return iterate(item, key, index);
1342
- });
1327
+ isGenoPro() {
1328
+ return this.sourStartsWith("genopro");
1343
1329
  }
1344
- reduce(iterate, initialValue) {
1345
- return this.entries().reduce((acc, [key, item], index) => {
1346
- return iterate(acc, item, key, index);
1347
- }, initialValue);
1330
+ isAhnenblatt() {
1331
+ return this.sourStartsWith("ahnenblatt");
1348
1332
  }
1349
- filter(filters, ClassName = _List) {
1350
- const newList = new ClassName();
1351
- const isIterator = typeof filters === "function";
1352
- this.entries().forEach(([itemId, item], index) => {
1353
- if (isIterator) {
1354
- filters(item, itemId, index) && newList.item(itemId, item);
1355
- return;
1356
- }
1357
- if (!Object.keys(filters).length || Object.entries(filters).every(([key, value]) => {
1358
- let itemValue;
1359
- if (key === "id") {
1360
- itemValue = item.toProp("id");
1361
- } else {
1362
- itemValue = item.toProp(key)?.toValue();
1363
- }
1364
- if (Array.isArray(value)) {
1365
- return value.includes(itemValue);
1366
- }
1367
- return itemValue === value;
1368
- })) {
1369
- newList.item(itemId, item);
1370
- }
1333
+ isGeni() {
1334
+ return this.sourStartsWith("geni");
1335
+ }
1336
+ isAncestry() {
1337
+ return this.sourStartsWith("ancestry");
1338
+ }
1339
+ isMyHeritage() {
1340
+ return this.sourStartsWith("myheritage");
1341
+ }
1342
+ /**
1343
+ * Get the source type as a string (for prefixing tree IDs and names)
1344
+ * Returns the detected source type or undefined if unknown
1345
+ */
1346
+ getSourceType() {
1347
+ if (this.isAncestry()) return "Ancestry";
1348
+ if (this.isMyHeritage()) return "MyHeritage";
1349
+ if (this.isFamilySearch()) return "FamilySearch";
1350
+ if (this.isGNO2GED()) return "GNO2GED";
1351
+ if (this.isGenoPro()) return "GenoPro";
1352
+ if (this.isAhnenblatt()) return "Ahnenblatt";
1353
+ if (this.isGeni()) return "Geni";
1354
+ return void 0;
1355
+ }
1356
+ isFamilySearch() {
1357
+ return this.getSourceHeads().some((head) => {
1358
+ const sourName = get(head, "SOUR.NAME.value");
1359
+ return sourName === "FamilySearch API";
1371
1360
  });
1372
- return newList;
1373
1361
  }
1374
- find(filters, _ClassName = _List) {
1375
- let foundItem;
1376
- const isIterator = typeof filters === "function";
1377
- this.entries().find(([itemId, item], index) => {
1378
- if (isIterator) {
1379
- if (filters(item, itemId, index)) {
1380
- foundItem = item;
1381
- return true;
1382
- }
1383
- return false;
1384
- }
1385
- if (!Object.keys(filters).length || Object.entries(filters).every(([key, value]) => {
1386
- let itemValue;
1387
- if (key === "id") {
1388
- itemValue = item.toProp("id");
1389
- } else {
1390
- itemValue = item.toProp(key)?.toValue();
1391
- }
1392
- if (Array.isArray(value)) {
1393
- return value.includes(itemValue);
1394
- }
1395
- return itemValue === value;
1396
- })) {
1397
- foundItem = item;
1398
- return true;
1399
- }
1400
- return false;
1362
+ isGNO2GED() {
1363
+ return this.getSourceHeads().some((head) => {
1364
+ const sour = get(head, "SOUR.value");
1365
+ return sour === "GNO2GED";
1401
1366
  });
1402
- return foundItem;
1403
1367
  }
1404
- orderBy(orders, ClassName = _List) {
1405
- const newList = new ClassName();
1406
- const isIterator = typeof orders === "function";
1407
- if (!isIterator && (!orders || !Object.keys(orders).length)) {
1408
- return newList.merge(this);
1368
+ getAncestryTreeId() {
1369
+ return this.getFromSourceHeads("SOUR._TREE.RIN.value") || (get(this, "HEAD.SOUR._TREE.RIN.value") || get(this.getGedcom(), "HEAD.SOUR._TREE.RIN.value"));
1370
+ }
1371
+ getMyHeritageTreeId() {
1372
+ 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"));
1373
+ }
1374
+ getTreeId() {
1375
+ if (this?.isAncestry()) {
1376
+ const id = this.getAncestryTreeId();
1377
+ if (id !== void 0) return id;
1409
1378
  }
1410
- const sortedItems = this.entries().toSorted(
1411
- ([itemAId, itemA], [itemBId, itemB]) => {
1412
- if (isIterator) {
1413
- return orders(itemA, itemAId, itemB, itemBId);
1414
- }
1415
- const [key, { direction, getter }] = Object.entries(
1416
- typeof orders === "string" ? { [orders]: { direction: "ASC" } } : orders
1417
- )[0];
1418
- const rawA = itemA.get(key);
1419
- const rawB = itemB.get(key);
1420
- let valueA = rawA?.toValue();
1421
- let valueB = rawB?.toValue();
1422
- if (getter && typeof getter === "function") {
1423
- valueA = getter(valueA, rawA);
1424
- valueB = getter(valueB, rawB);
1425
- }
1426
- let sortValue2 = 0;
1427
- if (!valueA && valueA !== 0 && !valueB && valueB !== 0) {
1428
- sortValue2 = 0;
1429
- } else if (!valueB && valueB !== 0) {
1430
- sortValue2 = 1;
1431
- } else if (!valueA && valueA !== 0) {
1432
- sortValue2 = -1;
1433
- } else if (valueA < valueB) {
1434
- sortValue2 = -1;
1435
- } else if (valueA > valueB) {
1436
- sortValue2 = 1;
1437
- }
1438
- return sortValue2 * (direction === "DESC" ? -1 : 1);
1379
+ if (this?.isMyHeritage()) {
1380
+ const id = this.getMyHeritageTreeId();
1381
+ if (id !== void 0) return id;
1382
+ }
1383
+ if (this?.isFamilySearch()) {
1384
+ const id = this.getFamilySearchTreeId();
1385
+ if (id !== void 0) return id;
1386
+ }
1387
+ if (this?.isGNO2GED()) {
1388
+ const id = this.getGNO2GEDTreeId();
1389
+ if (id !== void 0) return id;
1390
+ }
1391
+ if (this?.isAhnenblatt()) {
1392
+ const id = this.getAhnenblattTreeId();
1393
+ if (id !== void 0) return id;
1394
+ }
1395
+ if (this?.isGeni()) {
1396
+ const id = this.getGeniTreeId();
1397
+ if (id !== void 0) return id;
1398
+ }
1399
+ if (this?.isGenoPro()) {
1400
+ const id = this.getGenoProTreeId();
1401
+ if (id !== void 0) return id;
1402
+ }
1403
+ return this.getUniversalTreeId();
1404
+ }
1405
+ getAncestryTreeName() {
1406
+ return this.getFromSourceHeads("SOUR._TREE.value") || (get(this, "HEAD.SOUR._TREE.value") || get(this.getGedcom(), "HEAD.SOUR._TREE.value"));
1407
+ }
1408
+ getMyHeritageTreeName() {
1409
+ const path = "HEAD.FILE.value";
1410
+ const treeDetails = get(this, path) || get(this.getGedcom(), path);
1411
+ return treeDetails?.match(
1412
+ /Exported by MyHeritage.com from (?<tree>.+) in.+$/
1413
+ )?.groups?.tree;
1414
+ }
1415
+ getFamilySearchTreeId() {
1416
+ const rin = this.getFromSourceHeads("SOUR._TREE.RIN.value") || get(this, "HEAD.SOUR._TREE.RIN.value") || get(this.getGedcom(), "HEAD.SOUR._TREE.RIN.value");
1417
+ if (rin) {
1418
+ return rin;
1419
+ }
1420
+ return "familysearch";
1421
+ }
1422
+ getFamilySearchTreeName() {
1423
+ const treeName = this.getFromSourceHeads("SOUR._TREE.value") || get(this, "HEAD.SOUR._TREE.value") || get(this.getGedcom(), "HEAD.SOUR._TREE.value");
1424
+ if (treeName) {
1425
+ return treeName;
1426
+ }
1427
+ const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
1428
+ return fileName || "FamilySearch Import";
1429
+ }
1430
+ getAhnenblattTreeId() {
1431
+ const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
1432
+ if (fileName) {
1433
+ const idMatch = fileName.match(/_(\d+)/);
1434
+ if (idMatch) {
1435
+ return idMatch[1];
1439
1436
  }
1440
- );
1441
- sortedItems.forEach(([key, value]) => {
1442
- newList.item(key, value);
1443
- });
1444
- return newList;
1437
+ }
1438
+ return void 0;
1445
1439
  }
1446
- groupBy(groups, sort, minOccurance = -1, lessOccuranceLabel = "Appearing less than 5 times", ClassName = _List) {
1447
- const groupped = {};
1448
- const isIterator = typeof groups === "function";
1449
- if (!isIterator && (!groups || !Object.keys(groups).length)) {
1450
- groupped.Unknown = new ClassName().merge(this);
1451
- groupped.Unknown.marker = "Unknown";
1452
- return groupped;
1440
+ getAhnenblattTreeName() {
1441
+ const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
1442
+ return fileName?.replace(/\.ged$/i, "").replace(/_/g, " ");
1443
+ }
1444
+ getGeniTreeId() {
1445
+ const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
1446
+ if (fileName) {
1447
+ const idMatch = fileName.match(/_(\d+)/);
1448
+ if (idMatch) {
1449
+ return idMatch[1];
1450
+ }
1453
1451
  }
1454
- this.forEach((item, itemId) => {
1455
- const group = [];
1456
- if (isIterator) {
1457
- const newGroups = groups(item, itemId);
1458
- group.push(
1459
- ...Array.isArray(newGroups) ? newGroups : [newGroups]
1460
- );
1461
- } else {
1462
- const [key, { getter }] = Object.entries(
1463
- typeof groups === "string" ? { [groups]: {} } : groups
1464
- )[0];
1465
- const raw = item.get(key)?.index(0);
1466
- let value = raw?.toValue();
1467
- if (getter && typeof getter === "function") {
1468
- value = getter(value, raw);
1469
- }
1470
- if (value) {
1471
- group.push(value);
1472
- }
1452
+ return void 0;
1453
+ }
1454
+ getGeniTreeName() {
1455
+ const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
1456
+ return fileName?.replace(/\.ged$/i, "").replace(/_/g, " ");
1457
+ }
1458
+ getGenoProTreeId() {
1459
+ const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
1460
+ if (fileName) {
1461
+ const idMatch = fileName.match(/_(\d+)/);
1462
+ if (idMatch) {
1463
+ return idMatch[1];
1473
1464
  }
1474
- if (!group.length) {
1475
- group.push("Unknown");
1465
+ }
1466
+ return void 0;
1467
+ }
1468
+ getGenoProTreeName() {
1469
+ const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
1470
+ return fileName?.replace(/\.ged$/i, "").replace(/_/g, " ");
1471
+ }
1472
+ getGNO2GEDTreeId() {
1473
+ const rin = get(this, "HEAD._TREE.RIN.value") || get(this.getGedcom(), "HEAD._TREE.RIN.value");
1474
+ if (rin) {
1475
+ return rin;
1476
+ }
1477
+ return `gno_${this._gedcom?.refcount || "unknown"}`;
1478
+ }
1479
+ getGNO2GEDTreeName() {
1480
+ const treeName = get(this, "HEAD._TREE.value") || get(this.getGedcom(), "HEAD._TREE.value");
1481
+ if (treeName) {
1482
+ return treeName;
1483
+ }
1484
+ const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
1485
+ return fileName || "GNO2GED Export";
1486
+ }
1487
+ /**
1488
+ * Universal tree ID getter for unknown/unrecognized GEDCOM sources
1489
+ * Tries to extract an ID from various common locations
1490
+ */
1491
+ getUniversalTreeId() {
1492
+ const sourceType = this.getSourceType();
1493
+ const prefix = sourceType ? sourceType.toLowerCase() : "tree";
1494
+ const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
1495
+ if (fileName) {
1496
+ const idMatch = fileName.match(/_(\d+)/);
1497
+ if (idMatch) {
1498
+ return `${prefix}_${idMatch[1]}`;
1476
1499
  }
1477
- group.forEach((g) => {
1478
- const newGroup = typeof g === "string" ? { group: g } : g;
1479
- if (!groupped[newGroup.group]) {
1480
- groupped[newGroup.group] = new ClassName();
1481
- groupped[newGroup.group].marker = newGroup.marker ?? newGroup.group;
1482
- }
1483
- groupped[newGroup.group]?.append(item);
1484
- });
1485
- });
1486
- if (sort) {
1487
- return Object.entries(groupped).toSorted(([ak, a], [bk, b]) => {
1488
- if (typeof sort === "function") {
1489
- return sort(a, ak, b, bk);
1490
- }
1491
- if (ak === "Unknown") {
1492
- return 1;
1493
- }
1494
- if (bk === "Unknown") {
1495
- return -1;
1496
- }
1497
- if (sort === "group") {
1498
- return ak.localeCompare(bk);
1499
- }
1500
- return (b?.length ?? 0) - (a?.length ?? 0);
1501
- }).reduce((acc, [key, value]) => {
1502
- if (minOccurance > -1 && (value?.length ?? 0) < minOccurance) {
1503
- const otherKey = lessOccuranceLabel;
1504
- acc[otherKey] = acc[otherKey] && value ? acc[otherKey].merge(value) : value;
1505
- } else {
1506
- acc[key] = value;
1500
+ }
1501
+ return `${prefix}_${this._gedcom?.refcount || "unknown"}`;
1502
+ }
1503
+ /**
1504
+ * Universal tree name getter for unknown/unrecognized GEDCOM sources
1505
+ * Tries to extract a name from various common locations
1506
+ */
1507
+ getUniversalTreeName() {
1508
+ const sourceType = this.getSourceType();
1509
+ const prefix = sourceType ? `${sourceType}-` : "";
1510
+ const fileName = get(this, "HEAD.FILE.value") || get(this.getGedcom(), "HEAD.FILE.value");
1511
+ if (fileName) {
1512
+ const cleanName = fileName.replace(/\.ged$/i, "").replace(/_/g, " ");
1513
+ return `${prefix}${cleanName}`;
1514
+ }
1515
+ const sourName = this.getFromSourceHeads("SOUR.NAME.value") || get(this, "HEAD.SOUR.NAME.value") || get(this.getGedcom(), "HEAD.SOUR.NAME.value");
1516
+ if (sourName) {
1517
+ return `${prefix}${sourName}`;
1518
+ }
1519
+ const sourValue = this.getFromSourceHeads("SOUR.value") || get(this, "HEAD.SOUR.value") || get(this.getGedcom(), "HEAD.SOUR.value");
1520
+ if (sourValue) {
1521
+ return `${prefix}${sourValue}`;
1522
+ }
1523
+ return `${prefix}Unknown Tree`;
1524
+ }
1525
+ getTreeName() {
1526
+ if (this?.isAncestry()) {
1527
+ const name = this.getAncestryTreeName();
1528
+ if (name) return name;
1529
+ }
1530
+ if (this?.isMyHeritage()) {
1531
+ const name = this.getMyHeritageTreeName();
1532
+ if (name) return name;
1533
+ }
1534
+ if (this?.isFamilySearch()) {
1535
+ const name = this.getFamilySearchTreeName();
1536
+ if (name) return name;
1537
+ }
1538
+ if (this?.isGNO2GED()) {
1539
+ const name = this.getGNO2GEDTreeName();
1540
+ if (name) return name;
1541
+ }
1542
+ if (this?.isAhnenblatt()) {
1543
+ const name = this.getAhnenblattTreeName();
1544
+ if (name) return name;
1545
+ }
1546
+ if (this?.isGeni()) {
1547
+ const name = this.getGeniTreeName();
1548
+ if (name) return name;
1549
+ }
1550
+ if (this?.isGenoPro()) {
1551
+ const name = this.getGenoProTreeName();
1552
+ if (name) return name;
1553
+ }
1554
+ return this.getUniversalTreeName();
1555
+ }
1556
+ };
1557
+ var createProxy = (target) => {
1558
+ return new Proxy(target, {
1559
+ get(t, prop, receiver) {
1560
+ if (prop === "unwrapped") {
1561
+ return target;
1562
+ }
1563
+ if (prop in t) {
1564
+ return Reflect.get(t, prop, receiver);
1565
+ }
1566
+ if (!isOnlyMainProp(prop)) {
1567
+ const ref = t.ref;
1568
+ if (ref && prop in ref) {
1569
+ return Reflect.get(ref, prop, receiver);
1507
1570
  }
1508
- return acc;
1509
- }, {});
1571
+ }
1510
1572
  }
1511
- return groupped;
1573
+ });
1574
+ };
1575
+ var createCommon = (gedcom, id, main, parent) => {
1576
+ return createProxy(
1577
+ new Common(gedcom, id, main, parent)
1578
+ );
1579
+ };
1580
+ var isOnlyMainProp = (key) => {
1581
+ return key === "_gedcom" || key === "_main" || key === "_parent" || key === "_uniqueId" || key === "_type" || key === "_refs" || key === "id" || key === "_id";
1582
+ };
1583
+ var isValidKey = (common, key) => {
1584
+ const prop = get(common, key);
1585
+ 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);
1586
+ };
1587
+ var getValidKeys = (common) => {
1588
+ return Object.keys(common).filter((key) => {
1589
+ return isValidKey(common, key);
1590
+ });
1591
+ };
1592
+ var getValidTag = (tag) => {
1593
+ return tag.replace(/^@@/, "");
1594
+ };
1595
+ var getListTag = (tag) => {
1596
+ return `@@${tag}`;
1597
+ };
1598
+ var isId = (string) => {
1599
+ return ID_REG.test(string);
1600
+ };
1601
+ var idGetter = (id) => {
1602
+ if (id === void 0) {
1603
+ return void 0;
1512
1604
  }
1513
- findIndex(item) {
1514
- if (!item?.id) {
1515
- return -1;
1605
+ let newId = `${id}`;
1606
+ const parts = newId?.match(ID_GETTER_REG)?.groups;
1607
+ if (!parts?.at && !parts?.letter) {
1608
+ newId = `@U${newId}`;
1609
+ } else if (!parts.at) {
1610
+ newId = `@${newId}`;
1611
+ } else if (!parts.letter) {
1612
+ newId = newId.replace(/^@/, "@U");
1613
+ }
1614
+ if (!newId.endsWith("@")) {
1615
+ newId = `${newId}@`;
1616
+ }
1617
+ return newId;
1618
+ };
1619
+
1620
+ // src/utils/fact-edit.ts
1621
+ var SINGLETON_TAGS = /* @__PURE__ */ new Set(["BIRT", "DEAT", "SSN", "SEX", "DSCR"]);
1622
+ var firstRecord = (node) => {
1623
+ if (!node) {
1624
+ return void 0;
1625
+ }
1626
+ if (node instanceof List) {
1627
+ return node.index(0);
1628
+ }
1629
+ return node.index(0) ?? node;
1630
+ };
1631
+ var setDateOn = (gedcom, owner, parent, date) => {
1632
+ const trimmed = date.trim();
1633
+ if (!trimmed) {
1634
+ return;
1635
+ }
1636
+ let dateNode = parent.get("DATE");
1637
+ if (!dateNode || dateNode instanceof List) {
1638
+ dateNode = createCommonDate(gedcom, void 0, owner, parent);
1639
+ dateNode.type = "DATE";
1640
+ parent.set("DATE", dateNode);
1641
+ }
1642
+ dateNode.value = trimmed;
1643
+ };
1644
+ var fillFact = (gedcom, owner, event, input) => {
1645
+ if (input.value?.trim()) {
1646
+ event.value = input.value.trim();
1647
+ }
1648
+ if (input.type?.trim()) {
1649
+ event.set("TYPE", input.type.trim());
1650
+ }
1651
+ if (input.date) {
1652
+ setDateOn(gedcom, owner, event, input.date);
1653
+ }
1654
+ if (input.place?.trim()) {
1655
+ event.set("PLAC", input.place.trim());
1656
+ }
1657
+ if (input.note?.trim()) {
1658
+ event.set("NOTE", input.note.trim());
1659
+ }
1660
+ };
1661
+ var addIndividualFact = (indi, input) => {
1662
+ const gedcom = indi.getGedcom();
1663
+ if (!gedcom) {
1664
+ return void 0;
1665
+ }
1666
+ const tag = input.tag;
1667
+ let event = SINGLETON_TAGS.has(tag) ? firstRecord(indi.get(tag)) : void 0;
1668
+ if (!event) {
1669
+ event = createCommon(gedcom, void 0, indi);
1670
+ event.type = tag;
1671
+ if (SINGLETON_TAGS.has(tag)) {
1672
+ indi.set(tag, event);
1673
+ } else {
1674
+ indi.assign(tag, event);
1516
1675
  }
1517
- return this.keys().findIndex((key) => key === item.id);
1518
1676
  }
1519
- getItems() {
1520
- return this.items;
1677
+ fillFact(gedcom, indi, event, input);
1678
+ return event;
1679
+ };
1680
+ var addFamilyFact = (fam, input) => {
1681
+ const gedcom = fam.getGedcom();
1682
+ if (!gedcom) {
1683
+ return void 0;
1521
1684
  }
1522
- toJson(tag, options) {
1523
- const json = this.toObject(tag, options);
1524
- return JSON.stringify(json);
1685
+ const event = createCommon(gedcom, void 0, fam);
1686
+ event.type = input.tag;
1687
+ fam.assign(input.tag, event);
1688
+ fillFact(gedcom, fam, event, input);
1689
+ return event;
1690
+ };
1691
+
1692
+ // src/utils/family-edit.ts
1693
+ var PEDIGREE_VALUES = [
1694
+ "birth" /* BIRTH */,
1695
+ "adopted" /* ADOPTED */,
1696
+ "foster" /* FOSTER */,
1697
+ "step" /* STEP */,
1698
+ "sealing" /* SEALING */
1699
+ ];
1700
+ var toGedcomPedigree = (value) => {
1701
+ const normalized = String(value || "birth" /* BIRTH */).toLowerCase();
1702
+ if (normalized === "biological" /* BIOLOGICAL */ || normalized === "birth" /* BIRTH */) {
1703
+ return "birth" /* BIRTH */;
1525
1704
  }
1526
- toObject(tag, options) {
1527
- const json = {};
1528
- this.entries().forEach(([_, item]) => {
1529
- const validTag = getValidTag(tag);
1530
- if (json[validTag]) {
1531
- if (!Array.isArray(json[validTag])) {
1532
- json[validTag] = [json[validTag]];
1533
- }
1534
- json[validTag].push(
1535
- item.toObject(validTag, options)
1536
- );
1537
- } else {
1538
- json[validTag] = item.toObject(
1539
- validTag,
1540
- options
1541
- );
1542
- }
1543
- });
1544
- return json;
1705
+ const match = PEDIGREE_VALUES.find((item) => item === normalized);
1706
+ return match ?? "birth" /* BIRTH */;
1707
+ };
1708
+ var pointerIds = (tag) => {
1709
+ if (!tag) {
1710
+ return [];
1545
1711
  }
1546
- toGedcom(tag, level = 0, options) {
1547
- const gedcom = this.toGedcomLines(tag, level, options);
1548
- return gedcom.join("\n");
1712
+ if (tag instanceof List) {
1713
+ return tag.values().map((item) => item?.toValue?.()).filter((value2) => !!value2);
1549
1714
  }
1550
- toGedcomLines(tag, level = 0, options) {
1551
- const gedcom = [];
1552
- this.entries().forEach(([_, item]) => {
1553
- const validTag = getValidTag(tag);
1554
- const validKey = item.id;
1555
- const validValue = validKey ? validTag : item.exportValue();
1556
- gedcom.push(
1557
- `${level} ${validKey || validTag}${validValue ? ` ${validValue}` : ""}`
1558
- );
1559
- gedcom.push(
1560
- ...item.toGedcomLines(
1561
- validTag,
1562
- level + 1,
1563
- options
1564
- )
1565
- );
1566
- });
1567
- return gedcom;
1715
+ const value = tag.toValue?.();
1716
+ return value ? [String(value)] : [];
1717
+ };
1718
+ var firstPointerId = (tag) => pointerIds(tag)[0];
1719
+ var makePointer = (gedcom, parent, value, refType) => {
1720
+ const pointer = createCommon(gedcom, void 0, parent);
1721
+ pointer.value = value;
1722
+ pointer.refType = refType;
1723
+ return pointer;
1724
+ };
1725
+ var familyHasParent = (fam, indiId) => pointerIds(fam.get("HUSB")).includes(indiId) || pointerIds(fam.get("WIFE")).includes(indiId);
1726
+ var familyHasChild = (fam, indiId) => pointerIds(fam.get("CHIL")).includes(indiId);
1727
+ var spouseTagFor = (indi, fam) => {
1728
+ const husbId = firstPointerId(fam.get("HUSB"));
1729
+ const wifeId = firstPointerId(fam.get("WIFE"));
1730
+ if (husbId === indi.id) {
1731
+ return "HUSB";
1568
1732
  }
1569
- toValue() {
1570
- const propList = new _List();
1571
- this.entries().forEach(([key, item]) => {
1572
- propList.item(key, item?.toValue());
1573
- });
1574
- return propList;
1733
+ if (wifeId === indi.id) {
1734
+ return "WIFE";
1575
1735
  }
1576
- // @deprecated use get instead
1577
- toProp(tag) {
1578
- return this.get(tag);
1736
+ if (indi.isFemale()) {
1737
+ return wifeId && wifeId !== indi.id ? "HUSB" : "WIFE";
1579
1738
  }
1580
- toList() {
1581
- return new _List().concat(this.items);
1739
+ if (indi.isMale()) {
1740
+ return husbId && husbId !== indi.id ? "WIFE" : "HUSB";
1582
1741
  }
1583
- toValueList() {
1584
- const newList = new _List();
1585
- this.values().forEach((value) => {
1586
- value.value && newList.item(value.value, value);
1587
- });
1588
- return newList;
1742
+ return husbId ? "WIFE" : "HUSB";
1743
+ };
1744
+ var canAttachAsSpouse = (fam, indi) => {
1745
+ if (!indi.id) {
1746
+ return false;
1747
+ }
1748
+ if (familyHasParent(fam, indi.id)) {
1749
+ return true;
1750
+ }
1751
+ const tag = spouseTagFor(indi, fam);
1752
+ const occupied = firstPointerId(fam.get(tag));
1753
+ return !occupied || occupied === indi.id;
1754
+ };
1755
+ var pointerByValue = (tag, id) => {
1756
+ if (!tag) {
1757
+ return void 0;
1758
+ }
1759
+ const fromValues = tag.toValueList?.().item(id);
1760
+ if (fromValues) {
1761
+ return fromValues;
1762
+ }
1763
+ return tag.toList()?.values().find((item) => item?.toValue?.() === id);
1764
+ };
1765
+ var setChildPedigree = (fam, child, pedigree, parent) => {
1766
+ if (!fam.id || !child.id) {
1767
+ return;
1768
+ }
1769
+ const pedi = toGedcomPedigree(pedigree);
1770
+ const famc = pointerByValue(child.get("FAMC"), fam.id);
1771
+ if (famc) {
1772
+ famc.set("PEDI", pedi);
1773
+ }
1774
+ const chil = pointerByValue(fam.get("CHIL"), child.id);
1775
+ if (!chil) {
1776
+ return;
1777
+ }
1778
+ const setFather = !parent || parent.isMale() || parent.isUnknownSex();
1779
+ const setMother = !parent || parent.isFemale() || parent.isUnknownSex();
1780
+ if (setFather) {
1781
+ chil.set("_FREL", pedi);
1782
+ }
1783
+ if (setMother) {
1784
+ chil.set("_MREL", pedi);
1785
+ }
1786
+ };
1787
+ var attachSpouseToFamily = (fam, indi) => {
1788
+ const gedcom = fam.getGedcom() ?? indi.getGedcom();
1789
+ if (!indi.id || !fam.id || !gedcom) {
1790
+ return false;
1791
+ }
1792
+ if (!canAttachAsSpouse(fam, indi)) {
1793
+ return false;
1794
+ }
1795
+ const tag = spouseTagFor(indi, fam);
1796
+ if (firstPointerId(fam.get(tag)) !== indi.id) {
1797
+ fam.set(tag, makePointer(gedcom, fam, indi.id, "INDI"));
1798
+ }
1799
+ indi.assign("FAMS", makePointer(gedcom, indi, fam.id, "FAM"), true);
1800
+ return true;
1801
+ };
1802
+ var attachChildToFamily = (fam, child, pedigree, parent) => {
1803
+ const gedcom = fam.getGedcom() ?? child.getGedcom();
1804
+ if (!child.id || !fam.id || !gedcom) {
1805
+ return false;
1806
+ }
1807
+ if (!familyHasChild(fam, child.id)) {
1808
+ fam.assign("CHIL", makePointer(gedcom, fam, child.id, "INDI"), true);
1809
+ }
1810
+ const existingFamc = pointerByValue(child.get("FAMC"), fam.id);
1811
+ if (!existingFamc) {
1812
+ child.assign("FAMC", makePointer(gedcom, child, fam.id, "FAM"), true);
1813
+ }
1814
+ setChildPedigree(fam, child, pedigree, parent);
1815
+ return true;
1816
+ };
1817
+ var findReusableParentChildFamily = (parent, child) => {
1818
+ if (!parent.id || !child.id) {
1819
+ return void 0;
1820
+ }
1821
+ let reusableFamc;
1822
+ let already = false;
1823
+ child.getFamilies("FAMC")?.forEach((fam) => {
1824
+ if (!fam) {
1825
+ return;
1826
+ }
1827
+ if (familyHasParent(fam, parent.id) && familyHasChild(fam, child.id)) {
1828
+ already = true;
1829
+ return;
1830
+ }
1831
+ if (!reusableFamc && canAttachAsSpouse(fam, parent)) {
1832
+ reusableFamc = fam;
1833
+ }
1834
+ });
1835
+ if (already) {
1836
+ return "already";
1837
+ }
1838
+ if (reusableFamc) {
1839
+ return reusableFamc;
1840
+ }
1841
+ const parentFams = [];
1842
+ parent.getFamilies("FAMS")?.forEach((fam) => {
1843
+ if (fam) {
1844
+ parentFams.push(fam);
1845
+ }
1846
+ });
1847
+ if (parentFams.length === 1) {
1848
+ return parentFams[0];
1589
1849
  }
1850
+ return void 0;
1851
+ };
1852
+
1853
+ // src/utils/get-family-with.ts
1854
+ var getFamilyWith = (person1, person2, famType = "FAMS") => {
1855
+ return person1?.get(famType)?.toValueList().find((fam) => {
1856
+ const family = fam;
1857
+ return famType === "FAMC" || family?.HUSB?.value === person2 || family?.WIFE?.value === person2;
1858
+ });
1590
1859
  };
1591
1860
 
1592
1861
  // src/utils/get-places.ts
@@ -2219,6 +2488,31 @@ var Fam = class extends Common {
2219
2488
  getParents() {
2220
2489
  return this.getHusband().copy().merge(this.getWife());
2221
2490
  }
2491
+ hasParent(indi) {
2492
+ const indiId = typeof indi === "string" ? indi : indi?.id;
2493
+ return !!indiId && familyHasParent(this, indiId);
2494
+ }
2495
+ hasChild(indi) {
2496
+ const indiId = typeof indi === "string" ? indi : indi?.id;
2497
+ return !!indiId && familyHasChild(this, indiId);
2498
+ }
2499
+ canAddSpouse(indi) {
2500
+ return canAttachAsSpouse(this, indi);
2501
+ }
2502
+ addSpouse(indi) {
2503
+ return attachSpouseToFamily(this, indi);
2504
+ }
2505
+ addChild(child, pedigree, parent) {
2506
+ return attachChildToFamily(
2507
+ this,
2508
+ child,
2509
+ pedigree,
2510
+ parent
2511
+ );
2512
+ }
2513
+ addFact(input) {
2514
+ return addFamilyFact(this, input);
2515
+ }
2222
2516
  toList() {
2223
2517
  return new Families().concat(
2224
2518
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -2319,19 +2613,51 @@ var ALLOWED_FACTS = [
2319
2613
  "OCCU",
2320
2614
  "OCCUPATIONS",
2321
2615
  "RESI",
2616
+ "BIRT",
2617
+ "DEAT",
2322
2618
  "BAPT",
2619
+ "BAPM",
2323
2620
  "CHRI",
2324
2621
  "CHR",
2622
+ "CHRA",
2325
2623
  "BURI",
2326
- "EDUC",
2624
+ "CREM",
2625
+ "ADOP",
2626
+ "BARM",
2627
+ "BASM",
2628
+ "BLES",
2629
+ "CONF",
2630
+ "FCOM",
2631
+ "ORDN",
2632
+ "NATU",
2633
+ "EMIG",
2634
+ "IMMI",
2635
+ "CENS",
2636
+ "PROB",
2637
+ "WILL",
2327
2638
  "GRAD",
2639
+ "RETI",
2640
+ "EDUC",
2328
2641
  "DIV",
2329
- "IMMI",
2330
2642
  "RELI",
2643
+ "CAST",
2644
+ "DSCR",
2645
+ "NATI",
2646
+ "PROP",
2647
+ "SSN",
2648
+ "TITL",
2649
+ "ADDR",
2650
+ "BAPL",
2651
+ "CONL",
2652
+ "ENDL",
2653
+ "SLGC",
2331
2654
  "_MILT",
2332
2655
  "_MILTID",
2333
2656
  "FACT",
2334
- "_ORIG"
2657
+ "_ORIG",
2658
+ "_WLNK",
2659
+ "WWW",
2660
+ "URL"
2335
2661
  ];
2336
2662
  var DISALLOWED_CUSTOM_FACTS = ["DNA Test", "Newspaper"];
2337
2663
  var CustomFactRenderers = {
@@ -2875,7 +3201,7 @@ var Indi = class extends Common {
2875
3201
  return result;
2876
3202
  }
2877
3203
  ancestryLink() {
2878
- const www = this._gedcom?.HEAD?.SOUR?.CORP?.WWW?.value;
3204
+ const www = this.getFromSourceHeads("SOUR.CORP.WWW.value") || this._gedcom?.HEAD?.SOUR?.CORP?.WWW?.value;
2879
3205
  const tree = this.getAncestryTreeId();
2880
3206
  if (this.id) {
2881
3207
  return `https://${www}/family-tree/person/tree/${tree}/person/${this.id.replace(
@@ -2887,7 +3213,7 @@ var Indi = class extends Common {
2887
3213
  async ancestryMedia(namespace) {
2888
3214
  const list = {};
2889
3215
  const objeList = this.get("OBJE")?.toList().copy();
2890
- const www = this._gedcom?.HEAD?.SOUR?.CORP?.WWW?.value;
3216
+ const www = this.getFromSourceHeads("SOUR.CORP.WWW.value") || this._gedcom?.HEAD?.SOUR?.CORP?.WWW?.value;
2891
3217
  const tree = this.getAncestryTreeId();
2892
3218
  if (objeList) {
2893
3219
  await Promise.all(
@@ -2947,7 +3273,7 @@ var Indi = class extends Common {
2947
3273
  return list;
2948
3274
  }
2949
3275
  myheritageLink(poolId = 0) {
2950
- const www = this._gedcom?.HEAD?.SOUR?.CORP?.value?.toLowerCase().replace(/^www\./gi, "");
3276
+ const www = (this.getFromSourceHeads("SOUR.CORP.value") || this._gedcom?.HEAD?.SOUR?.CORP?.value)?.toLowerCase().replace(/^www\./gi, "");
2951
3277
  const site = this.getMyHeritageTreeId();
2952
3278
  const file = this._gedcom?.HEAD?.get("FILE")?.toValue()?.match(/Exported by MyHeritage.com from .+ in (?<site>.+) on .+$/)?.groups?.site;
2953
3279
  const normalizedFile = file?.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase().replace(/[^a-z0-9]+/g, "-");
@@ -3468,6 +3794,57 @@ var Indi = class extends Common {
3468
3794
  isUnknownSex() {
3469
3795
  return !this.isMale() && !this.isFemale();
3470
3796
  }
3797
+ addSpouse(other) {
3798
+ if (!this.id || !other?.id || this.id === other.id || !this._gedcom) {
3799
+ return void 0;
3800
+ }
3801
+ const existing = getFamilyWith(this, other.id);
3802
+ if (existing) {
3803
+ return existing;
3804
+ }
3805
+ const fam = this._gedcom.createFamily();
3806
+ if (!fam.addSpouse(this) || !fam.addSpouse(other)) {
3807
+ return void 0;
3808
+ }
3809
+ return fam;
3810
+ }
3811
+ addChild(child, pedigree) {
3812
+ if (!this.id || !child?.id || this.id === child.id || !this._gedcom) {
3813
+ return void 0;
3814
+ }
3815
+ const existing = findReusableParentChildFamily(
3816
+ this,
3817
+ child
3818
+ );
3819
+ if (existing === "already") {
3820
+ const fam2 = child.getFamilies("FAMC")?.find(
3821
+ (item) => !!item && item.hasParent(this.id) && item.hasChild(child.id)
3822
+ );
3823
+ if (fam2) {
3824
+ setChildPedigree(
3825
+ fam2,
3826
+ child,
3827
+ pedigree,
3828
+ this
3829
+ );
3830
+ }
3831
+ return fam2;
3832
+ }
3833
+ const fam = existing ?? this._gedcom.createFamily();
3834
+ if (!fam.addSpouse(this)) {
3835
+ return void 0;
3836
+ }
3837
+ if (!fam.addChild(child, pedigree, this)) {
3838
+ return void 0;
3839
+ }
3840
+ return fam;
3841
+ }
3842
+ addParent(parent, pedigree) {
3843
+ return parent.addChild(this, pedigree);
3844
+ }
3845
+ addFact(input) {
3846
+ return addIndividualFact(this, input);
3847
+ }
3471
3848
  getParentType(id) {
3472
3849
  let indi;
3473
3850
  if (typeof id === "string" || typeof id === "number") {
@@ -3668,7 +4045,9 @@ var Indi = class extends Common {
3668
4045
  }
3669
4046
  }
3670
4047
  if (kinship !== "child" || !breakAfterSpouse) {
3671
- indi.getBiologicalFathers().copy().merge(indi.getBiologicalMothers()).merge(indi.getFathers().copy().merge(indi.getMothers())).forEach((relative) => {
4048
+ indi.getBiologicalFathers().copy().merge(indi.getBiologicalMothers()).merge(
4049
+ indi.getFathers().copy().merge(indi.getMothers())
4050
+ ).forEach((relative) => {
3672
4051
  if (!visited.has(relative)) {
3673
4052
  const currentRelation = indi.getParentType(relative);
3674
4053
  const isNonBiological = !!currentRelation && currentRelation !== "biological" /* BIOLOGICAL */;
@@ -6562,14 +6941,6 @@ var isCommonDate = (value) => {
6562
6941
  return !!value && value !== null && typeof value === "object" && "_date" in value;
6563
6942
  };
6564
6943
 
6565
- // src/utils/get-family-with.ts
6566
- var getFamilyWith = (person1, person2, famType = "FAMS") => {
6567
- return person1?.get(famType)?.toValueList().find((fam) => {
6568
- const family = fam;
6569
- return famType === "FAMC" || family?.HUSB?.value === person2 || family?.WIFE?.value === person2;
6570
- });
6571
- };
6572
-
6573
6944
  // src/constants/orders.ts
6574
6945
  var DEFAULT = {};
6575
6946
  var BIRTH_ASC = {
@@ -6809,4 +7180,4 @@ var getMarriageAscAndBirth = (person) => (itemA, keyA, itemB, keyB) => {
6809
7180
  return getBirthAsc(itemA, keyA, itemB);
6810
7181
  };
6811
7182
 
6812
- export { ADOPTED, BIOLOGICAL, BIRTH, BIRTH_ASC, BIRTH_DESC, DATE_ASC, DATE_DESC, DEATH_ASC, DEATH_DESC, DEFAULT, EVERY, FEMALE, FOSTER, FRIEND, ID_GETTER_REG, ID_REG, ID_SPLIT_REG, LINE_REG, MALE, MAX_FILE_SIZE_TO_SYNC, OTHER, PARTNER, REF_LINE_REG, SEALING, SINGLE, SPOUSE, STEP, UNKOWN, getBirthAsc, getMarriageAsc, getMarriageAscAndBirth, getMarriageAscAndChildBirth, getNameAsc, getNameAscAndBirth, getNameDesc };
7183
+ export { ADOPTED, APP_BRANDING, BIOLOGICAL, BIRTH, BIRTH_ASC, BIRTH_DESC, DATE_ASC, DATE_DESC, DEATH_ASC, DEATH_DESC, DEFAULT, EVERY, FEMALE, FOSTER, FRIEND, ID_GETTER_REG, ID_REG, ID_SPLIT_REG, LINE_REG, MALE, MAX_FILE_SIZE_TO_SYNC, ORIG_HEAD_TAG, OTHER, PARTNER, REF_LINE_REG, SEALING, SINGLE, SPOUSE, STEP, UNKOWN, getBirthAsc, getMarriageAsc, getMarriageAscAndBirth, getMarriageAscAndChildBirth, getNameAsc, getNameAscAndBirth, getNameDesc };