@treeviz/gedcom-parser 2.1.18 → 2.1.23

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/cli/index.js CHANGED
@@ -973,7 +973,7 @@ var Common = class _Common {
973
973
  return this.sourStartsWith("ahnenblatt");
974
974
  }
975
975
  isGeni() {
976
- return this.sourStartsWith("geni");
976
+ return this.sourStartsWith("geni.com");
977
977
  }
978
978
  isAncestry() {
979
979
  return this.sourStartsWith("ancestry");
@@ -1318,7 +1318,257 @@ var getCacheManagerFactory = () => {
1318
1318
  return cacheFactory;
1319
1319
  };
1320
1320
 
1321
- // src/utils/cache.ts
1321
+ // src/factories/date-locale-factory.ts
1322
+ var dateLocaleProvider = () => void 0;
1323
+ var getDateLocale = () => {
1324
+ const result = dateLocaleProvider();
1325
+ return result;
1326
+ };
1327
+
1328
+ // src/factories/i18n-factory.ts
1329
+ var i18nProvider = (key) => key;
1330
+ var i18n = {
1331
+ t: (key, options) => i18nProvider(key)
1332
+ };
1333
+
1334
+ // src/kinship-translator/translators.ts
1335
+ var translators_exports = {};
1336
+ __export(translators_exports, {
1337
+ de: () => KinshipTranslatorDe,
1338
+ en: () => KinshipTranslatorEn,
1339
+ es: () => KinshipTranslatorEs,
1340
+ fr: () => KinshipTranslatorFr,
1341
+ hu: () => KinshipTranslatorHU,
1342
+ ja: () => KinshipTranslatorJa,
1343
+ ru: () => KinshipTranslatorRu,
1344
+ zh: () => KinshipTranslatorZh
1345
+ });
1346
+
1347
+ // src/constants/filters.ts
1348
+ var FEMALE = {
1349
+ SEX: "F"
1350
+ };
1351
+ var MALE = {
1352
+ SEX: "M"
1353
+ };
1354
+ var ADOPTED = {
1355
+ PEDI: "adopted" /* ADOPTED */
1356
+ };
1357
+ var BIRTH = {
1358
+ PEDI: "birth" /* BIRTH */
1359
+ };
1360
+ var FOSTER = {
1361
+ PEDI: "foster" /* FOSTER */
1362
+ };
1363
+ var SEALING = {
1364
+ PEDI: "sealing" /* SEALING */
1365
+ };
1366
+ var STEP = {
1367
+ PEDI: "step" /* STEP */
1368
+ };
1369
+ var BIOLOGICAL = {
1370
+ PEDI: "biological" /* BIOLOGICAL */
1371
+ };
1372
+ var FRIEND = {
1373
+ PART: "friend" /* FRIEND */
1374
+ };
1375
+ var PARTNER = {
1376
+ PART: "partner" /* PARTNER */
1377
+ };
1378
+ var SPOUSE = {
1379
+ PART: "spouse" /* SPOUSE */
1380
+ };
1381
+
1382
+ // src/utils/get-family-with.ts
1383
+ var getFamilyWith = (person1, person2, famType = "FAMS") => {
1384
+ return person1?.get(famType)?.toValueList().find((fam) => {
1385
+ const family = fam;
1386
+ return famType === "FAMC" || family?.HUSB?.value === person2 || family?.WIFE?.value === person2;
1387
+ });
1388
+ };
1389
+
1390
+ // src/constants/orders.ts
1391
+ var BIRTH_ASC = {
1392
+ "BIRT.DATE": {
1393
+ direction: "ASC",
1394
+ getter: (value, raw) => {
1395
+ if (isCommonDate(raw) && raw.rawValue) {
1396
+ return raw.rawValue.getTime();
1397
+ }
1398
+ return new Date(value).getTime();
1399
+ }
1400
+ }
1401
+ };
1402
+ var BIRTH_DESC = {
1403
+ "BIRT.DATE": {
1404
+ direction: "DESC",
1405
+ getter: (value, raw) => {
1406
+ if (isCommonDate(raw) && raw.rawValue) {
1407
+ return raw.rawValue.getTime();
1408
+ }
1409
+ return new Date(value).getTime();
1410
+ }
1411
+ }
1412
+ };
1413
+ var DEATH_ASC = {
1414
+ "DEAT.DATE": {
1415
+ direction: "ASC",
1416
+ getter: (value, raw) => {
1417
+ if (isCommonDate(raw) && raw.rawValue) {
1418
+ return raw.rawValue.getTime();
1419
+ }
1420
+ return new Date(value).getTime();
1421
+ }
1422
+ }
1423
+ };
1424
+ var DEATH_DESC = {
1425
+ "DEAT.DATE": {
1426
+ direction: "DESC",
1427
+ getter: (value, raw) => {
1428
+ if (isCommonDate(raw) && raw.rawValue) {
1429
+ return raw.rawValue.getTime();
1430
+ }
1431
+ return new Date(value).getTime();
1432
+ }
1433
+ }
1434
+ };
1435
+ var DATE_ASC = {
1436
+ DATE: {
1437
+ direction: "ASC",
1438
+ getter: (value, raw) => {
1439
+ if (isCommonDate(raw) && raw.rawValue) {
1440
+ return raw.rawValue.getTime();
1441
+ }
1442
+ return new Date(value).getTime();
1443
+ }
1444
+ }
1445
+ };
1446
+ var chars = [
1447
+ "a",
1448
+ "\xE0",
1449
+ "\xE1",
1450
+ "\xE2",
1451
+ "\xE4",
1452
+ "\xE6",
1453
+ "\xE3",
1454
+ "\xE5",
1455
+ "\u0101",
1456
+ "b",
1457
+ "c",
1458
+ "\xE7",
1459
+ "\u0107",
1460
+ "\u010D",
1461
+ "cs",
1462
+ "d",
1463
+ "dz",
1464
+ "dzs",
1465
+ "e",
1466
+ "\xE8",
1467
+ "\xE9",
1468
+ "\xEA",
1469
+ "\xEB",
1470
+ "\u0113",
1471
+ "\u0117",
1472
+ "\u0119",
1473
+ "f",
1474
+ "g",
1475
+ "gy",
1476
+ "h",
1477
+ "i",
1478
+ "\xEE",
1479
+ "\xEF",
1480
+ "\xED",
1481
+ "\u012B",
1482
+ "\u012F",
1483
+ "\xEC",
1484
+ "j",
1485
+ "k",
1486
+ "l",
1487
+ "\u0142",
1488
+ "ly",
1489
+ "m",
1490
+ "n",
1491
+ "\xF1",
1492
+ "\u0144",
1493
+ "ny",
1494
+ "o",
1495
+ "\xF3",
1496
+ "\xF6",
1497
+ "\u0151",
1498
+ "\xF4",
1499
+ "\xF2",
1500
+ "\xF5",
1501
+ "\u0153",
1502
+ "\xF8",
1503
+ "\u014D",
1504
+ "p",
1505
+ "q",
1506
+ "r",
1507
+ "s",
1508
+ "\u015B",
1509
+ "\u0161",
1510
+ "\xDF",
1511
+ "sz",
1512
+ "t",
1513
+ "ty",
1514
+ "u",
1515
+ "\xFA",
1516
+ "\xFC",
1517
+ "\u0171",
1518
+ "\xFB",
1519
+ "\xF9",
1520
+ "\u016B",
1521
+ "v",
1522
+ "w",
1523
+ "x",
1524
+ "y",
1525
+ "z",
1526
+ "zs"
1527
+ ];
1528
+ chars.reduce((acc, curr, idx) => {
1529
+ acc[curr] = idx;
1530
+ return acc;
1531
+ }, {});
1532
+ var getBirthAsc = (itemA, _keyA, itemB, _keyB) => {
1533
+ const birthA = itemA?.BIRT?.index(0);
1534
+ const birthB = itemB?.BIRT?.index(0);
1535
+ const valueA = birthA?.DATE?.rawValue;
1536
+ const valueB = birthB?.DATE?.rawValue;
1537
+ if (valueA?.getTime() === valueB?.getTime()) {
1538
+ return 0;
1539
+ }
1540
+ if (!valueA || valueB && valueA > valueB) {
1541
+ return 1;
1542
+ }
1543
+ return -1;
1544
+ };
1545
+ var getMarriageAsc = (person, famType = "FAMS") => (itemA, _keyA, itemB, _keyB) => {
1546
+ if (!person && famType === "FAMS") {
1547
+ return 0;
1548
+ }
1549
+ const familyA = getFamilyWith(itemA, person);
1550
+ const familyB = getFamilyWith(itemB, person);
1551
+ const marriageA = familyA?.MARR?.DATE?.rawValue;
1552
+ const marriageB = familyB?.MARR?.DATE?.rawValue;
1553
+ if (marriageA?.getTime() === marriageB?.getTime()) {
1554
+ return 0;
1555
+ }
1556
+ if (!marriageA || marriageB && marriageA > marriageB) {
1557
+ return 1;
1558
+ }
1559
+ return -1;
1560
+ };
1561
+ var getMarriageAscAndChildBirth = (person) => (itemA, keyA, itemB, keyB) => {
1562
+ const marriageSort = getMarriageAsc(person)(itemA, keyA, itemB, keyB);
1563
+ if (marriageSort !== 0) {
1564
+ return marriageSort;
1565
+ }
1566
+ const familyA = getFamilyWith(itemA, person);
1567
+ const familyB = getFamilyWith(itemB, person);
1568
+ const childA = familyA?.getChildren().orderBy(BIRTH_ASC).index(0);
1569
+ const childB = familyB?.getChildren().orderBy(BIRTH_ASC).index(0);
1570
+ return getBirthAsc(childA, keyA, childB);
1571
+ };
1322
1572
  var getGedcomId = (gedcom) => {
1323
1573
  if (!gedcom) {
1324
1574
  return "unknown";
@@ -1570,612 +1820,6 @@ var cacheDiscoveredPath = (gedcom, path) => {
1570
1820
  }
1571
1821
  };
1572
1822
 
1573
- // src/utils/family-edit.ts
1574
- var refTypeForTag = (tag) => {
1575
- if (tag === "FAMS" || tag === "FAMC") return "FAM";
1576
- return "INDI";
1577
- };
1578
- var normalizeSinglePointer = (owner, tag) => {
1579
- const node = owner.get(tag);
1580
- if (!node) return;
1581
- if (node instanceof List && node.length === 1) {
1582
- const only = node.index(0);
1583
- if (only) {
1584
- owner.set(tag, only);
1585
- return;
1586
- }
1587
- const raw = node.values()[0];
1588
- if (typeof raw === "string") {
1589
- const gedcom = owner.getGedcom?.();
1590
- if (gedcom) {
1591
- owner.set(tag, makePointer(gedcom, owner, raw, refTypeForTag(tag)));
1592
- }
1593
- }
1594
- }
1595
- };
1596
- var PEDIGREE_VALUES = [
1597
- "birth" /* BIRTH */,
1598
- "adopted" /* ADOPTED */,
1599
- "foster" /* FOSTER */,
1600
- "step" /* STEP */,
1601
- "sealing" /* SEALING */
1602
- ];
1603
- var toGedcomPedigree = (value) => {
1604
- const normalized = String(value || "birth" /* BIRTH */).toLowerCase();
1605
- if (normalized === "biological" /* BIOLOGICAL */ || normalized === "birth" /* BIRTH */) {
1606
- return "birth" /* BIRTH */;
1607
- }
1608
- const match = PEDIGREE_VALUES.find((item) => item === normalized);
1609
- return match ?? "birth" /* BIRTH */;
1610
- };
1611
- var pointerIds = (tag) => {
1612
- if (!tag) {
1613
- return [];
1614
- }
1615
- if (tag instanceof List) {
1616
- return tag.values().map((item) => item?.toValue?.()).filter((value2) => !!value2);
1617
- }
1618
- const value = tag.toValue?.();
1619
- return value ? [String(value)] : [];
1620
- };
1621
- var firstPointerId = (tag) => pointerIds(tag)[0];
1622
- var makePointer = (gedcom, parent, value, refType) => {
1623
- const pointer = createCommon(gedcom, void 0, parent);
1624
- pointer.value = value;
1625
- pointer.refType = refType;
1626
- return pointer;
1627
- };
1628
- var nextRecordId = (ids, prefix) => {
1629
- let max = 0;
1630
- ids.forEach((id) => {
1631
- const match = String(id).match(/(\d+)/);
1632
- const n = match ? Number.parseInt(match[1], 10) : 0;
1633
- if (n > max) {
1634
- max = n;
1635
- }
1636
- });
1637
- return `@${prefix}${max + 1}@`;
1638
- };
1639
- var familyHasParent = (fam, indiId) => pointerIds(fam.get("HUSB")).includes(indiId) || pointerIds(fam.get("WIFE")).includes(indiId);
1640
- var familyHasChild = (fam, indiId) => pointerIds(fam.get("CHIL")).includes(indiId);
1641
- var spouseTagFor = (indi, fam) => {
1642
- const husbId = firstPointerId(fam.get("HUSB"));
1643
- const wifeId = firstPointerId(fam.get("WIFE"));
1644
- if (husbId === indi.id) {
1645
- return "HUSB";
1646
- }
1647
- if (wifeId === indi.id) {
1648
- return "WIFE";
1649
- }
1650
- if (indi.isFemale()) {
1651
- return wifeId && wifeId !== indi.id ? "HUSB" : "WIFE";
1652
- }
1653
- if (indi.isMale()) {
1654
- return husbId && husbId !== indi.id ? "WIFE" : "HUSB";
1655
- }
1656
- return husbId ? "WIFE" : "HUSB";
1657
- };
1658
- var canAttachAsSpouse = (fam, indi) => {
1659
- if (!indi.id) {
1660
- return false;
1661
- }
1662
- if (familyHasParent(fam, indi.id)) {
1663
- return true;
1664
- }
1665
- const tag = spouseTagFor(indi, fam);
1666
- const occupied = firstPointerId(fam.get(tag));
1667
- return !occupied || occupied === indi.id;
1668
- };
1669
- var pointerByValue = (tag, id) => {
1670
- if (!tag) {
1671
- return void 0;
1672
- }
1673
- const fromValues = tag.toValueList?.().item(id);
1674
- if (fromValues) {
1675
- return fromValues;
1676
- }
1677
- return tag.toList()?.values().find((item) => item?.toValue?.() === id);
1678
- };
1679
- var setChildPedigree = (fam, child, pedigree, parent) => {
1680
- if (!fam.id || !child.id) {
1681
- return;
1682
- }
1683
- const pedi = toGedcomPedigree(pedigree);
1684
- const famc = pointerByValue(child.get("FAMC"), fam.id);
1685
- if (famc) {
1686
- famc.set("PEDI", pedi);
1687
- }
1688
- const chil = pointerByValue(fam.get("CHIL"), child.id);
1689
- if (!chil) {
1690
- return;
1691
- }
1692
- const setFather = !parent || parent.isMale() || parent.isUnknownSex();
1693
- const setMother = !parent || parent.isFemale() || parent.isUnknownSex();
1694
- if (setFather) {
1695
- chil.set("_FREL", pedi);
1696
- }
1697
- if (setMother) {
1698
- chil.set("_MREL", pedi);
1699
- }
1700
- };
1701
- var attachSpouseToFamily = (fam, indi) => {
1702
- const gedcom = fam.getGedcom() ?? indi.getGedcom();
1703
- if (!indi.id || !fam.id || !gedcom) {
1704
- return false;
1705
- }
1706
- if (!canAttachAsSpouse(fam, indi)) {
1707
- return false;
1708
- }
1709
- const tag = spouseTagFor(indi, fam);
1710
- if (firstPointerId(fam.get(tag)) !== indi.id) {
1711
- fam.set(tag, makePointer(gedcom, fam, indi.id, "INDI"));
1712
- }
1713
- indi.assign("FAMS", makePointer(gedcom, indi, fam.id, "FAM"), true);
1714
- normalizeSinglePointer(indi, "FAMS");
1715
- normalizeSinglePointer(fam, spouseTagFor(indi, fam));
1716
- resetRelativesCache();
1717
- return true;
1718
- };
1719
- var attachChildToFamily = (fam, child, pedigree, parent) => {
1720
- const gedcom = fam.getGedcom() ?? child.getGedcom();
1721
- if (!child.id || !fam.id || !gedcom) {
1722
- return false;
1723
- }
1724
- if (!familyHasChild(fam, child.id)) {
1725
- fam.assign("CHIL", makePointer(gedcom, fam, child.id, "INDI"), true);
1726
- }
1727
- const existingFamc = pointerByValue(child.get("FAMC"), fam.id);
1728
- if (!existingFamc) {
1729
- child.assign("FAMC", makePointer(gedcom, child, fam.id, "FAM"), true);
1730
- }
1731
- setChildPedigree(fam, child, pedigree, parent);
1732
- normalizeSinglePointer(child, "FAMC");
1733
- normalizeSinglePointer(fam, "CHIL");
1734
- resetRelativesCache();
1735
- return true;
1736
- };
1737
- var removePointerByValue = (owner, tag, targetId) => {
1738
- const node = owner.get(tag);
1739
- if (!node) {
1740
- return false;
1741
- }
1742
- if (node instanceof List) {
1743
- const keysToRemove = [];
1744
- node.entries().forEach(([key, item]) => {
1745
- if (item?.toValue?.() === targetId || item?.id === targetId || String(key) === targetId) {
1746
- keysToRemove.push(key);
1747
- }
1748
- });
1749
- keysToRemove.forEach((key) => {
1750
- node.removeItem(key);
1751
- });
1752
- if (node.length === 0) {
1753
- owner.remove(tag);
1754
- }
1755
- return keysToRemove.length > 0;
1756
- }
1757
- if (node.toValue?.() === targetId) {
1758
- owner.remove(tag);
1759
- return true;
1760
- }
1761
- const asList = node.toList?.();
1762
- if (asList && asList.length > 0) {
1763
- const keysToRemove = [];
1764
- asList.entries().forEach(([key, item]) => {
1765
- if (item?.toValue?.() === targetId || item?.id === targetId) {
1766
- keysToRemove.push(key);
1767
- }
1768
- });
1769
- if (keysToRemove.length === asList.length) {
1770
- owner.remove(tag);
1771
- return true;
1772
- }
1773
- if (keysToRemove.length > 0) {
1774
- const remaining = asList.values().filter((item) => item?.toValue?.() !== targetId);
1775
- if (remaining.length === 1 && remaining[0]) {
1776
- owner.set(tag, remaining[0]);
1777
- } else {
1778
- owner.set(tag, new List(remaining));
1779
- }
1780
- return true;
1781
- }
1782
- }
1783
- return false;
1784
- };
1785
- var familyMemberCount = (fam) => {
1786
- let count = 0;
1787
- if (firstPointerId(fam.get("HUSB"))) {
1788
- count += 1;
1789
- }
1790
- if (firstPointerId(fam.get("WIFE"))) {
1791
- count += 1;
1792
- }
1793
- count += pointerIds(fam.get("CHIL")).length;
1794
- return count;
1795
- };
1796
- var isDegenerateFamily = (fam) => familyMemberCount(fam) <= 1;
1797
- var pruneEmptyFamilies = (gedcom) => {
1798
- const emptyIds = [];
1799
- gedcom.fams()?.forEach((fam, id) => {
1800
- if (fam && isDegenerateFamily(fam) && id) {
1801
- emptyIds.push(id);
1802
- }
1803
- });
1804
- if (emptyIds.length === 0) {
1805
- return [];
1806
- }
1807
- gedcom.indis()?.forEach((indi) => {
1808
- if (!indi) {
1809
- return;
1810
- }
1811
- emptyIds.forEach((famId) => {
1812
- removePointerByValue(indi, "FAMS", famId);
1813
- removePointerByValue(indi, "FAMC", famId);
1814
- });
1815
- });
1816
- emptyIds.forEach((famId) => {
1817
- gedcom.fams()?.removeItem(famId);
1818
- });
1819
- return emptyIds;
1820
- };
1821
- var findSharedSpouseFamily = (parent, coParentId) => {
1822
- let found;
1823
- parent.getFamilies("FAMS")?.forEach((fam) => {
1824
- if (!found && fam && familyHasParent(fam, coParentId)) {
1825
- found = fam;
1826
- }
1827
- });
1828
- return found;
1829
- };
1830
- var findReusableParentChildFamily = (parent, child, options) => {
1831
- if (!parent.id || !child.id) {
1832
- return void 0;
1833
- }
1834
- const reuseParentFamilies = options?.reuseParentFamilies !== false;
1835
- const gedcom = parent.getGedcom() ?? child.getGedcom();
1836
- let reusableFamc;
1837
- let coupleFam;
1838
- let already = false;
1839
- const noteCoupleWith = (coParentId) => {
1840
- if (!coParentId || coParentId === parent.id || coupleFam || !parent.id) {
1841
- return;
1842
- }
1843
- const shared = findSharedSpouseFamily(parent, coParentId);
1844
- if (shared) {
1845
- coupleFam = shared;
1846
- }
1847
- };
1848
- child.getFamilies("FAMC")?.forEach((fam) => {
1849
- if (!fam) {
1850
- return;
1851
- }
1852
- if (familyHasParent(fam, parent.id) && familyHasChild(fam, child.id)) {
1853
- already = true;
1854
- return;
1855
- }
1856
- pointerIds(fam.get("HUSB")).forEach(noteCoupleWith);
1857
- pointerIds(fam.get("WIFE")).forEach(noteCoupleWith);
1858
- if (!reusableFamc && canAttachAsSpouse(fam, parent)) {
1859
- reusableFamc = fam;
1860
- }
1861
- });
1862
- if (already) {
1863
- return "already";
1864
- }
1865
- if (coupleFam) {
1866
- return coupleFam;
1867
- }
1868
- if (reusableFamc) {
1869
- return reusableFamc;
1870
- }
1871
- if (options?.targetFamilyId && gedcom) {
1872
- const target = gedcom.fam(options.targetFamilyId);
1873
- if (target && (familyHasParent(target, parent.id) || canAttachAsSpouse(target, parent))) {
1874
- return target;
1875
- }
1876
- }
1877
- if (!reuseParentFamilies) {
1878
- return void 0;
1879
- }
1880
- const parentFams = [];
1881
- parent.getFamilies("FAMS")?.forEach((fam) => {
1882
- if (fam) {
1883
- parentFams.push(fam);
1884
- }
1885
- });
1886
- if (parentFams.length === 1) {
1887
- return parentFams[0];
1888
- }
1889
- return void 0;
1890
- };
1891
- var consolidateChildIntoFamily = (child, keep) => {
1892
- if (!child.id || !keep.id) {
1893
- return [];
1894
- }
1895
- const keepParentIds = /* @__PURE__ */ new Set([
1896
- ...pointerIds(keep.get("HUSB")),
1897
- ...pointerIds(keep.get("WIFE"))
1898
- ]);
1899
- const removed = [];
1900
- child.getFamilies("FAMC")?.forEach((fam) => {
1901
- if (!fam?.id || fam.id === keep.id) {
1902
- return;
1903
- }
1904
- const famParentIds = [
1905
- ...pointerIds(fam.get("HUSB")),
1906
- ...pointerIds(fam.get("WIFE"))
1907
- ];
1908
- if (famParentIds.length === 0 || !famParentIds.every((id) => keepParentIds.has(id))) {
1909
- return;
1910
- }
1911
- removePointerByValue(fam, "CHIL", child.id);
1912
- normalizeSinglePointer(fam, "CHIL");
1913
- removePointerByValue(child, "FAMC", fam.id);
1914
- normalizeSinglePointer(child, "FAMC");
1915
- removed.push(fam.id);
1916
- });
1917
- const gedcom = child.getGedcom() ?? keep.getGedcom();
1918
- if (gedcom && removed.length > 0) {
1919
- pruneEmptyFamilies(gedcom);
1920
- }
1921
- if (removed.length > 0) {
1922
- resetRelativesCache();
1923
- }
1924
- return removed;
1925
- };
1926
-
1927
- // src/factories/date-locale-factory.ts
1928
- var dateLocaleProvider = () => void 0;
1929
- var getDateLocale = () => {
1930
- const result = dateLocaleProvider();
1931
- return result;
1932
- };
1933
-
1934
- // src/factories/i18n-factory.ts
1935
- var i18nProvider = (key) => key;
1936
- var i18n = {
1937
- t: (key, options) => i18nProvider(key)
1938
- };
1939
-
1940
- // src/kinship-translator/translators.ts
1941
- var translators_exports = {};
1942
- __export(translators_exports, {
1943
- de: () => KinshipTranslatorDe,
1944
- en: () => KinshipTranslatorEn,
1945
- es: () => KinshipTranslatorEs,
1946
- fr: () => KinshipTranslatorFr,
1947
- hu: () => KinshipTranslatorHU,
1948
- ja: () => KinshipTranslatorJa,
1949
- ru: () => KinshipTranslatorRu,
1950
- zh: () => KinshipTranslatorZh
1951
- });
1952
-
1953
- // src/constants/filters.ts
1954
- var FEMALE = {
1955
- SEX: "F"
1956
- };
1957
- var MALE = {
1958
- SEX: "M"
1959
- };
1960
- var ADOPTED = {
1961
- PEDI: "adopted" /* ADOPTED */
1962
- };
1963
- var BIRTH = {
1964
- PEDI: "birth" /* BIRTH */
1965
- };
1966
- var FOSTER = {
1967
- PEDI: "foster" /* FOSTER */
1968
- };
1969
- var SEALING = {
1970
- PEDI: "sealing" /* SEALING */
1971
- };
1972
- var STEP = {
1973
- PEDI: "step" /* STEP */
1974
- };
1975
- var BIOLOGICAL = {
1976
- PEDI: "biological" /* BIOLOGICAL */
1977
- };
1978
- var FRIEND = {
1979
- PART: "friend" /* FRIEND */
1980
- };
1981
- var PARTNER = {
1982
- PART: "partner" /* PARTNER */
1983
- };
1984
- var SPOUSE = {
1985
- PART: "spouse" /* SPOUSE */
1986
- };
1987
-
1988
- // src/utils/get-family-with.ts
1989
- var getFamilyWith = (person1, person2, famType = "FAMS") => {
1990
- return person1?.get(famType)?.toValueList().find((fam) => {
1991
- const family = fam;
1992
- return famType === "FAMC" || family?.HUSB?.value === person2 || family?.WIFE?.value === person2;
1993
- });
1994
- };
1995
-
1996
- // src/constants/orders.ts
1997
- var BIRTH_ASC = {
1998
- "BIRT.DATE": {
1999
- direction: "ASC",
2000
- getter: (value, raw) => {
2001
- if (isCommonDate(raw) && raw.rawValue) {
2002
- return raw.rawValue.getTime();
2003
- }
2004
- return new Date(value).getTime();
2005
- }
2006
- }
2007
- };
2008
- var BIRTH_DESC = {
2009
- "BIRT.DATE": {
2010
- direction: "DESC",
2011
- getter: (value, raw) => {
2012
- if (isCommonDate(raw) && raw.rawValue) {
2013
- return raw.rawValue.getTime();
2014
- }
2015
- return new Date(value).getTime();
2016
- }
2017
- }
2018
- };
2019
- var DEATH_ASC = {
2020
- "DEAT.DATE": {
2021
- direction: "ASC",
2022
- getter: (value, raw) => {
2023
- if (isCommonDate(raw) && raw.rawValue) {
2024
- return raw.rawValue.getTime();
2025
- }
2026
- return new Date(value).getTime();
2027
- }
2028
- }
2029
- };
2030
- var DEATH_DESC = {
2031
- "DEAT.DATE": {
2032
- direction: "DESC",
2033
- getter: (value, raw) => {
2034
- if (isCommonDate(raw) && raw.rawValue) {
2035
- return raw.rawValue.getTime();
2036
- }
2037
- return new Date(value).getTime();
2038
- }
2039
- }
2040
- };
2041
- var DATE_ASC = {
2042
- DATE: {
2043
- direction: "ASC",
2044
- getter: (value, raw) => {
2045
- if (isCommonDate(raw) && raw.rawValue) {
2046
- return raw.rawValue.getTime();
2047
- }
2048
- return new Date(value).getTime();
2049
- }
2050
- }
2051
- };
2052
- var chars = [
2053
- "a",
2054
- "\xE0",
2055
- "\xE1",
2056
- "\xE2",
2057
- "\xE4",
2058
- "\xE6",
2059
- "\xE3",
2060
- "\xE5",
2061
- "\u0101",
2062
- "b",
2063
- "c",
2064
- "\xE7",
2065
- "\u0107",
2066
- "\u010D",
2067
- "cs",
2068
- "d",
2069
- "dz",
2070
- "dzs",
2071
- "e",
2072
- "\xE8",
2073
- "\xE9",
2074
- "\xEA",
2075
- "\xEB",
2076
- "\u0113",
2077
- "\u0117",
2078
- "\u0119",
2079
- "f",
2080
- "g",
2081
- "gy",
2082
- "h",
2083
- "i",
2084
- "\xEE",
2085
- "\xEF",
2086
- "\xED",
2087
- "\u012B",
2088
- "\u012F",
2089
- "\xEC",
2090
- "j",
2091
- "k",
2092
- "l",
2093
- "\u0142",
2094
- "ly",
2095
- "m",
2096
- "n",
2097
- "\xF1",
2098
- "\u0144",
2099
- "ny",
2100
- "o",
2101
- "\xF3",
2102
- "\xF6",
2103
- "\u0151",
2104
- "\xF4",
2105
- "\xF2",
2106
- "\xF5",
2107
- "\u0153",
2108
- "\xF8",
2109
- "\u014D",
2110
- "p",
2111
- "q",
2112
- "r",
2113
- "s",
2114
- "\u015B",
2115
- "\u0161",
2116
- "\xDF",
2117
- "sz",
2118
- "t",
2119
- "ty",
2120
- "u",
2121
- "\xFA",
2122
- "\xFC",
2123
- "\u0171",
2124
- "\xFB",
2125
- "\xF9",
2126
- "\u016B",
2127
- "v",
2128
- "w",
2129
- "x",
2130
- "y",
2131
- "z",
2132
- "zs"
2133
- ];
2134
- chars.reduce((acc, curr, idx) => {
2135
- acc[curr] = idx;
2136
- return acc;
2137
- }, {});
2138
- var getBirthAsc = (itemA, _keyA, itemB, _keyB) => {
2139
- const birthA = itemA?.BIRT?.index(0);
2140
- const birthB = itemB?.BIRT?.index(0);
2141
- const valueA = birthA?.DATE?.rawValue;
2142
- const valueB = birthB?.DATE?.rawValue;
2143
- if (valueA?.getTime() === valueB?.getTime()) {
2144
- return 0;
2145
- }
2146
- if (!valueA || valueB && valueA > valueB) {
2147
- return 1;
2148
- }
2149
- return -1;
2150
- };
2151
- var getMarriageAsc = (person, famType = "FAMS") => (itemA, _keyA, itemB, _keyB) => {
2152
- if (!person && famType === "FAMS") {
2153
- return 0;
2154
- }
2155
- const familyA = getFamilyWith(itemA, person);
2156
- const familyB = getFamilyWith(itemB, person);
2157
- const marriageA = familyA?.MARR?.DATE?.rawValue;
2158
- const marriageB = familyB?.MARR?.DATE?.rawValue;
2159
- if (marriageA?.getTime() === marriageB?.getTime()) {
2160
- return 0;
2161
- }
2162
- if (!marriageA || marriageB && marriageA > marriageB) {
2163
- return 1;
2164
- }
2165
- return -1;
2166
- };
2167
- var getMarriageAscAndChildBirth = (person) => (itemA, keyA, itemB, keyB) => {
2168
- const marriageSort = getMarriageAsc(person)(itemA, keyA, itemB, keyB);
2169
- if (marriageSort !== 0) {
2170
- return marriageSort;
2171
- }
2172
- const familyA = getFamilyWith(itemA, person);
2173
- const familyB = getFamilyWith(itemB, person);
2174
- const childA = familyA?.getChildren().orderBy(BIRTH_ASC).index(0);
2175
- const childB = familyB?.getChildren().orderBy(BIRTH_ASC).index(0);
2176
- return getBirthAsc(childA, keyA, childB);
2177
- };
2178
-
2179
1823
  // src/utils/get-all-prop.ts
2180
1824
  var getAllProp = (indi, prop) => {
2181
1825
  return prop && (indi?.get(prop)?.toList().values() ?? []).filter(Boolean) || [];
@@ -2396,6 +2040,96 @@ var dateFormatter = (indi, showMarriages = false, showDays = false, showPlaces =
2396
2040
  };
2397
2041
  };
2398
2042
 
2043
+ // src/utils/fact-edit.ts
2044
+ var SINGLETON_TAGS = /* @__PURE__ */ new Set(["BIRT", "DEAT", "SSN", "SEX", "DSCR"]);
2045
+ var firstRecord = (node) => {
2046
+ if (!node) {
2047
+ return void 0;
2048
+ }
2049
+ if (node instanceof List) {
2050
+ return node.index(0);
2051
+ }
2052
+ return node.index(0) ?? node;
2053
+ };
2054
+ var setDateOn = (gedcom, owner, parent, date) => {
2055
+ const trimmed = date.trim();
2056
+ if (!trimmed) {
2057
+ return;
2058
+ }
2059
+ let dateNode = parent.get("DATE");
2060
+ if (!dateNode || dateNode instanceof List) {
2061
+ dateNode = createCommonDate(gedcom, void 0, owner, parent);
2062
+ dateNode.type = "DATE";
2063
+ parent.set("DATE", dateNode);
2064
+ }
2065
+ dateNode.value = trimmed;
2066
+ };
2067
+ var fillFact = (gedcom, owner, event, input) => {
2068
+ if (input.value?.trim()) {
2069
+ event.value = input.value.trim();
2070
+ }
2071
+ if (input.type?.trim()) {
2072
+ event.set("TYPE", input.type.trim());
2073
+ }
2074
+ if (input.date) {
2075
+ setDateOn(gedcom, owner, event, input.date);
2076
+ }
2077
+ if (input.place?.trim()) {
2078
+ event.set("PLAC", input.place.trim());
2079
+ }
2080
+ if (input.note?.trim()) {
2081
+ event.set("NOTE", input.note.trim());
2082
+ }
2083
+ };
2084
+ var addIndividualFact = (indi, input) => {
2085
+ const gedcom = indi.getGedcom();
2086
+ if (!gedcom) {
2087
+ return void 0;
2088
+ }
2089
+ const tag = input.tag;
2090
+ let event = SINGLETON_TAGS.has(tag) ? firstRecord(indi.get(tag)) : void 0;
2091
+ if (!event) {
2092
+ event = createCommon(gedcom, void 0, indi);
2093
+ event.type = tag;
2094
+ if (SINGLETON_TAGS.has(tag)) {
2095
+ indi.set(tag, event);
2096
+ } else {
2097
+ indi.assign(tag, event);
2098
+ }
2099
+ }
2100
+ fillFact(gedcom, indi, event, input);
2101
+ return event;
2102
+ };
2103
+ var addFamilyFact = (fam, input) => {
2104
+ const gedcom = fam.getGedcom();
2105
+ if (!gedcom) {
2106
+ return void 0;
2107
+ }
2108
+ const event = createCommon(gedcom, void 0, fam);
2109
+ event.type = input.tag;
2110
+ fam.assign(input.tag, event);
2111
+ fillFact(gedcom, fam, event, input);
2112
+ return event;
2113
+ };
2114
+ var addNonEvent = (owner, input) => {
2115
+ const gedcom = owner.getGedcom();
2116
+ const eventType = input.event?.trim().toUpperCase();
2117
+ if (!gedcom || !eventType) {
2118
+ return void 0;
2119
+ }
2120
+ const no = createCommon(gedcom, void 0, owner);
2121
+ no.type = "NO";
2122
+ no.value = eventType;
2123
+ if (input.date?.trim()) {
2124
+ setDateOn(gedcom, owner, no, input.date);
2125
+ }
2126
+ if (input.note?.trim()) {
2127
+ no.set("NOTE", input.note.trim());
2128
+ }
2129
+ owner.assign("NO", no);
2130
+ return no;
2131
+ };
2132
+
2399
2133
  // src/utils/get-places.ts
2400
2134
  var getPlaces = (common, type = ["ALL" /* All */], maxLevel = 1, level = 0, mainKey) => {
2401
2135
  const types = Array.isArray(type) ? type : [type];
@@ -3197,10 +2931,12 @@ var relativesOnLevelCache = relativesCache("relativesOnLevelCache");
3197
2931
  var relativesOnDegreeCache = relativesCache("relativesOnDegreeCache");
3198
2932
  var Indi = class extends Common {
3199
2933
  toName() {
3200
- return this.get("NAME")?.toValue();
2934
+ const name = this.get("NAME");
2935
+ const value = name?.index(0)?.toValue() ?? name?.toValue();
2936
+ return typeof value === "string" ? value : void 0;
3201
2937
  }
3202
2938
  toNaturalName() {
3203
- return this.get("NAME")?.toValue()?.replaceAll("/", "");
2939
+ return this.toName()?.replaceAll("/", "");
3204
2940
  }
3205
2941
  toList() {
3206
2942
  return new Individuals().concat(
@@ -3745,17 +3481,25 @@ var Indi = class extends Common {
3745
3481
  }
3746
3482
  return list;
3747
3483
  }
3748
- myheritageLink(poolId = 0) {
3484
+ myheritageLink(poolId = 0, treeToken) {
3749
3485
  let www = (this.getFromSourceHeads("SOUR.CORP.value") || this._gedcom?.HEAD?.SOUR?.CORP?.value)?.toLowerCase().replace(/^www\./gi, "");
3750
3486
  if (!www || /treeviz/i.test(www)) {
3751
3487
  www = "myheritage.com";
3752
3488
  }
3489
+ if (!this.id) {
3490
+ return;
3491
+ }
3492
+ const id = Number(this.id.replace(/@|I/g, "")) + poolId;
3493
+ if (!Number.isFinite(id)) {
3494
+ return;
3495
+ }
3496
+ const slug = this.toNaturalName()?.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || String(id);
3497
+ if (treeToken) {
3498
+ return `https://www.${www}/profile-${treeToken}-${id}/${slug}`;
3499
+ }
3753
3500
  const site = this.getMyHeritageTreeId();
3754
- const file = (this.getFromSourceHeads("FILE.value") || this._gedcom?.HEAD?.get("FILE")?.toValue())?.match(/Exported by MyHeritage.com from .+ in (?<site>.+) on .+$/)?.groups?.site;
3755
- const normalizedFile = file?.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase().replace(/[^a-z0-9]+/g, "-");
3756
- if (normalizedFile && this.id) {
3757
- const id = Number(this.id.replace(/@|I/g, "")) + poolId;
3758
- return `https://www.${www}/site-family-tree-${site}/${normalizedFile}#!profile-${id}-info`;
3501
+ if (site) {
3502
+ return `https://www.${www}/person-${id}_${site}_${site}/${slug}`;
3759
3503
  }
3760
3504
  }
3761
3505
  myheritageMedia() {
@@ -3804,6 +3548,14 @@ var Indi = class extends Common {
3804
3548
  });
3805
3549
  return list;
3806
3550
  }
3551
+ geniLink() {
3552
+ if (!this.id) {
3553
+ return;
3554
+ }
3555
+ const id = this.id.replace(/@|I/g, "");
3556
+ const given = this.toNaturalName()?.trim().split(/\s+/)[0] || id;
3557
+ return `https://www.geni.com/people/${given}/${id}`;
3558
+ }
3807
3559
  familySearchLink() {
3808
3560
  const wwwTags = this.get("WWW")?.toList();
3809
3561
  const wwwTag = wwwTags?.find((wwwTag2) => {
@@ -4084,12 +3836,15 @@ var Indi = class extends Common {
4084
3836
  );
4085
3837
  return void 0;
4086
3838
  }
4087
- link(poolId) {
3839
+ link(poolId, treeToken) {
4088
3840
  if (this?.isAncestry()) {
4089
3841
  return this.ancestryLink();
4090
3842
  }
4091
3843
  if (this?.isMyHeritage()) {
4092
- return this.myheritageLink(poolId);
3844
+ return this.myheritageLink(poolId, treeToken);
3845
+ }
3846
+ if (this?.isGeni()) {
3847
+ return this.geniLink();
4093
3848
  }
4094
3849
  if (this?.isFamilySearch()) {
4095
3850
  return this.familySearchLink();
@@ -5842,11 +5597,28 @@ var KinshipTranslatorBasic = class {
5842
5597
  // src/kinship-translator/patterns.hu.ts
5843
5598
  var parentRelationsHu = {
5844
5599
  step: "mostoha",
5845
- foster: "nevelt",
5600
+ foster: { ancestor: "nevel\u0151", other: "nevelt" },
5846
5601
  birth: "v\xE9rszerinti",
5847
5602
  biological: "v\xE9rszerinti",
5848
- adopted: "\xF6r\xF6kbefogadott"
5603
+ adopted: { ancestor: "\xF6r\xF6kbefogad\xF3", other: "\xF6r\xF6kbefogadott" }
5604
+ };
5605
+ var parentRelationPrefix = (relation, ancestor) => {
5606
+ const label = parentRelationsHu[relation];
5607
+ if (!label) {
5608
+ return;
5609
+ }
5610
+ if (typeof label === "string") {
5611
+ return label;
5612
+ }
5613
+ return ancestor ? label.ancestor : label.other;
5849
5614
  };
5615
+ var parentRelationModifiers = [
5616
+ ...new Set(
5617
+ Object.values(parentRelationsHu).flatMap(
5618
+ (label) => typeof label === "string" ? [label] : [label.ancestor, label.other]
5619
+ )
5620
+ )
5621
+ ].join("|");
5850
5622
  var nominativus = {
5851
5623
  apa: { nominativus: "apa", dativus: "apj\xE1nak", possessivus: "apja" },
5852
5624
  anya: { nominativus: "anya", dativus: "anyj\xE1nak", possessivus: "anyja" },
@@ -5924,15 +5696,9 @@ var casesHu = {
5924
5696
  var InLawsHu = {
5925
5697
  "gyermek feles\xE9ge": "meny",
5926
5698
  "gyermek f\xE9rje": "v\u0151",
5927
- [`(f\xE9rj|feles\xE9g) (?<mod1>(${Object.values(parentRelationsHu).join(
5928
- "|"
5929
- )}) )?anyja`]: "any\xF3s",
5930
- [`(f\xE9rj|feles\xE9g) (?<mod1>(${Object.values(parentRelationsHu).join(
5931
- "|"
5932
- )}) )?apja`]: "ap\xF3s",
5933
- [`(f\xE9rj|feles\xE9g) (?<mod1>(${Object.values(parentRelationsHu).join(
5934
- "|"
5935
- )}) )?(f\xE9l)?testv\xE9re`]: (indi) => {
5699
+ [`(f\xE9rj|feles\xE9g) (?<mod1>(${parentRelationModifiers}) )?anyja`]: "any\xF3s",
5700
+ [`(f\xE9rj|feles\xE9g) (?<mod1>(${parentRelationModifiers}) )?apja`]: "ap\xF3s",
5701
+ [`(f\xE9rj|feles\xE9g) (?<mod1>(${parentRelationModifiers}) )?(f\xE9l)?testv\xE9re`]: (indi) => {
5936
5702
  if (indi?.isMale()) {
5937
5703
  return "s\xF3gor";
5938
5704
  }
@@ -6209,7 +5975,12 @@ var KinshipTranslatorHU = class extends KinshipTranslatorBasic {
6209
5975
  if (!relation || !this.pathN?.relation) {
6210
5976
  return relation ?? "";
6211
5977
  }
6212
- return `${parentRelationsHu[this.pathN.relation]} ${relation}`;
5978
+ const isAncestor = (this.pathN.level ?? 0) > 0 && (this.pathN.degree ?? 0) === 0;
5979
+ const prefix = parentRelationPrefix(this.pathN.relation, isAncestor);
5980
+ if (!prefix) {
5981
+ return relation;
5982
+ }
5983
+ return `${prefix} ${relation}`;
6213
5984
  }
6214
5985
  };
6215
5986
 
@@ -6409,6 +6180,10 @@ var KinshipTranslatorEn = class extends KinshipTranslatorBasic {
6409
6180
  if (!relation || !this.pathN?.relation) {
6410
6181
  return relation ?? "";
6411
6182
  }
6183
+ if (this.pathN.relation === "adopted") {
6184
+ const isAncestor = (this.pathN.level ?? 0) > 0 && (this.pathN.degree ?? 0) === 0;
6185
+ return `${isAncestor ? "adoptive" : "adopted"} ${relation}`;
6186
+ }
6412
6187
  return `${this.pathN.relation} ${relation}`;
6413
6188
  }
6414
6189
  };
@@ -7567,6 +7342,39 @@ var lineal = (level, sex, kind) => {
7567
7342
  }
7568
7343
  return `${L - 1}\u4E16\u306E\u5B6B`;
7569
7344
  };
7345
+ var adoptedRelation = (relation) => {
7346
+ if (relation === "\u7236") {
7347
+ return "\u990A\u7236";
7348
+ }
7349
+ if (relation === "\u6BCD") {
7350
+ return "\u990A\u6BCD";
7351
+ }
7352
+ if (relation === "\u89AA") {
7353
+ return "\u990A\u89AA";
7354
+ }
7355
+ if (relation === "\u606F\u5B50" || relation === "\u5B50") {
7356
+ return "\u990A\u5B50";
7357
+ }
7358
+ if (relation === "\u5A18") {
7359
+ return "\u990A\u5973";
7360
+ }
7361
+ return `\u990A${relation}`;
7362
+ };
7363
+ var fosterRelation = (relation) => {
7364
+ if (relation === "\u7236") {
7365
+ return "\u91CC\u7236";
7366
+ }
7367
+ if (relation === "\u6BCD") {
7368
+ return "\u91CC\u6BCD";
7369
+ }
7370
+ if (relation === "\u89AA") {
7371
+ return "\u91CC\u89AA";
7372
+ }
7373
+ if (relation === "\u606F\u5B50" || relation === "\u5A18" || relation === "\u5B50") {
7374
+ return "\u91CC\u5B50";
7375
+ }
7376
+ return `\u91CC${relation}`;
7377
+ };
7570
7378
  var cousinPlain = (degree) => {
7571
7379
  if (degree <= 1) {
7572
7380
  return "\u3044\u3068\u3053";
@@ -7726,10 +7534,10 @@ var KinshipTranslatorJa = class extends KinshipTranslatorBasic {
7726
7534
  return `\u7D99${relation}`;
7727
7535
  }
7728
7536
  if (this.pathN.relation === "adopted") {
7729
- return `\u990A\u5B50\u306E${relation}`;
7537
+ return adoptedRelation(relation);
7730
7538
  }
7731
7539
  if (this.pathN.relation === "foster") {
7732
- return `\u91CC\u89AA\u306E${relation}`;
7540
+ return fosterRelation(relation);
7733
7541
  }
7734
7542
  return relation;
7735
7543
  }
@@ -8389,107 +8197,396 @@ var CommonDate = class extends Common {
8389
8197
  );
8390
8198
  return super.toGedcomLines(tag, level, options).filter((line) => !internal.test(line));
8391
8199
  }
8392
- inRange(range, trueIfNoYear = false) {
8393
- return inRange(this.YEAR?.value, range, trueIfNoYear);
8200
+ inRange(range, trueIfNoYear = false) {
8201
+ return inRange(this.YEAR?.value, range, trueIfNoYear);
8202
+ }
8203
+ };
8204
+ var createCommonDate = (gedcom, id, main, parent) => {
8205
+ return createProxy(
8206
+ new CommonDate(gedcom, id, main, parent)
8207
+ );
8208
+ };
8209
+ var isCommonDate = (value) => {
8210
+ return !!value && value !== null && typeof value === "object" && "_date" in value;
8211
+ };
8212
+
8213
+ // src/utils/family-edit.ts
8214
+ var GEDCOM_MONTHS2 = [
8215
+ "JAN",
8216
+ "FEB",
8217
+ "MAR",
8218
+ "APR",
8219
+ "MAY",
8220
+ "JUN",
8221
+ "JUL",
8222
+ "AUG",
8223
+ "SEP",
8224
+ "OCT",
8225
+ "NOV",
8226
+ "DEC"
8227
+ ];
8228
+ var CREATED_AT_TAG = "_CREATED_AT";
8229
+ var stampCreatedAt = (gedcom, indi, when = /* @__PURE__ */ new Date()) => {
8230
+ const existing = indi.get(CREATED_AT_TAG);
8231
+ if (isCommonDate(existing) && existing.rawValue instanceof Date && !Number.isNaN(existing.rawValue.getTime())) {
8232
+ return;
8233
+ }
8234
+ const dateNode = createCommonDate(gedcom, void 0, indi, indi);
8235
+ dateNode.type = CREATED_AT_TAG;
8236
+ dateNode.value = `${when.getDate()} ${GEDCOM_MONTHS2[when.getMonth()]} ${when.getFullYear()}`;
8237
+ indi.set(CREATED_AT_TAG, dateNode);
8238
+ };
8239
+ var refTypeForTag = (tag) => {
8240
+ if (tag === "FAMS" || tag === "FAMC") return "FAM";
8241
+ return "INDI";
8242
+ };
8243
+ var normalizeSinglePointer = (owner, tag) => {
8244
+ const node = owner.get(tag);
8245
+ if (!node) return;
8246
+ if (node instanceof List && node.length === 1) {
8247
+ const only = node.index(0);
8248
+ if (only) {
8249
+ owner.set(tag, only);
8250
+ return;
8251
+ }
8252
+ const raw = node.values()[0];
8253
+ if (typeof raw === "string") {
8254
+ const gedcom = owner.getGedcom?.();
8255
+ if (gedcom) {
8256
+ owner.set(tag, makePointer(gedcom, owner, raw, refTypeForTag(tag)));
8257
+ }
8258
+ }
8259
+ }
8260
+ };
8261
+ var PEDIGREE_VALUES = [
8262
+ "birth" /* BIRTH */,
8263
+ "adopted" /* ADOPTED */,
8264
+ "foster" /* FOSTER */,
8265
+ "step" /* STEP */,
8266
+ "sealing" /* SEALING */
8267
+ ];
8268
+ var toGedcomPedigree = (value) => {
8269
+ const normalized = String(value || "birth" /* BIRTH */).toLowerCase();
8270
+ if (normalized === "biological" /* BIOLOGICAL */ || normalized === "birth" /* BIRTH */) {
8271
+ return "birth" /* BIRTH */;
8272
+ }
8273
+ const match = PEDIGREE_VALUES.find((item) => item === normalized);
8274
+ return match ?? "birth" /* BIRTH */;
8275
+ };
8276
+ var pointerIds = (tag) => {
8277
+ if (!tag) {
8278
+ return [];
8279
+ }
8280
+ if (tag instanceof List) {
8281
+ return tag.values().map((item) => item?.toValue?.()).filter((value2) => !!value2);
8282
+ }
8283
+ const value = tag.toValue?.();
8284
+ return value ? [String(value)] : [];
8285
+ };
8286
+ var firstPointerId = (tag) => pointerIds(tag)[0];
8287
+ var makePointer = (gedcom, parent, value, refType) => {
8288
+ const pointer = createCommon(gedcom, void 0, parent);
8289
+ pointer.value = value;
8290
+ pointer.refType = refType;
8291
+ return pointer;
8292
+ };
8293
+ var nextRecordId = (ids, prefix) => {
8294
+ let max = 0;
8295
+ ids.forEach((id) => {
8296
+ const match = String(id).match(/(\d+)/);
8297
+ const n = match ? Number.parseInt(match[1], 10) : 0;
8298
+ if (n > max) {
8299
+ max = n;
8300
+ }
8301
+ });
8302
+ return `@${prefix}${max + 1}@`;
8303
+ };
8304
+ var familyHasParent = (fam, indiId) => pointerIds(fam.get("HUSB")).includes(indiId) || pointerIds(fam.get("WIFE")).includes(indiId);
8305
+ var familyHasChild = (fam, indiId) => pointerIds(fam.get("CHIL")).includes(indiId);
8306
+ var spouseTagFor = (indi, fam) => {
8307
+ const husbId = firstPointerId(fam.get("HUSB"));
8308
+ const wifeId = firstPointerId(fam.get("WIFE"));
8309
+ if (husbId === indi.id) {
8310
+ return "HUSB";
8311
+ }
8312
+ if (wifeId === indi.id) {
8313
+ return "WIFE";
8314
+ }
8315
+ if (indi.isFemale()) {
8316
+ return wifeId && wifeId !== indi.id ? "HUSB" : "WIFE";
8317
+ }
8318
+ if (indi.isMale()) {
8319
+ return husbId && husbId !== indi.id ? "WIFE" : "HUSB";
8320
+ }
8321
+ return husbId ? "WIFE" : "HUSB";
8322
+ };
8323
+ var canAttachAsSpouse = (fam, indi) => {
8324
+ if (!indi.id) {
8325
+ return false;
8326
+ }
8327
+ if (familyHasParent(fam, indi.id)) {
8328
+ return true;
8329
+ }
8330
+ const tag = spouseTagFor(indi, fam);
8331
+ const occupied = firstPointerId(fam.get(tag));
8332
+ return !occupied || occupied === indi.id;
8333
+ };
8334
+ var pointerByValue = (tag, id) => {
8335
+ if (!tag) {
8336
+ return void 0;
8337
+ }
8338
+ const fromValues = tag.toValueList?.().item(id);
8339
+ if (fromValues) {
8340
+ return fromValues;
8341
+ }
8342
+ return tag.toList()?.values().find((item) => item?.toValue?.() === id);
8343
+ };
8344
+ var setChildPedigree = (fam, child, pedigree, parent) => {
8345
+ if (!fam.id || !child.id) {
8346
+ return;
8347
+ }
8348
+ const pedi = toGedcomPedigree(pedigree);
8349
+ const famc = pointerByValue(child.get("FAMC"), fam.id);
8350
+ if (famc) {
8351
+ famc.set("PEDI", pedi);
8352
+ }
8353
+ const chil = pointerByValue(fam.get("CHIL"), child.id);
8354
+ if (!chil) {
8355
+ return;
8356
+ }
8357
+ const setFather = !parent || parent.isMale() || parent.isUnknownSex();
8358
+ const setMother = !parent || parent.isFemale() || parent.isUnknownSex();
8359
+ if (setFather) {
8360
+ chil.set("_FREL", pedi);
8361
+ }
8362
+ if (setMother) {
8363
+ chil.set("_MREL", pedi);
8364
+ }
8365
+ };
8366
+ var attachSpouseToFamily = (fam, indi) => {
8367
+ const gedcom = fam.getGedcom() ?? indi.getGedcom();
8368
+ if (!indi.id || !fam.id || !gedcom) {
8369
+ return false;
8370
+ }
8371
+ if (!canAttachAsSpouse(fam, indi)) {
8372
+ return false;
8373
+ }
8374
+ const tag = spouseTagFor(indi, fam);
8375
+ if (firstPointerId(fam.get(tag)) !== indi.id) {
8376
+ fam.set(tag, makePointer(gedcom, fam, indi.id, "INDI"));
8377
+ }
8378
+ indi.assign("FAMS", makePointer(gedcom, indi, fam.id, "FAM"), true);
8379
+ normalizeSinglePointer(indi, "FAMS");
8380
+ normalizeSinglePointer(fam, spouseTagFor(indi, fam));
8381
+ resetRelativesCache();
8382
+ return true;
8383
+ };
8384
+ var attachChildToFamily = (fam, child, pedigree, parent) => {
8385
+ const gedcom = fam.getGedcom() ?? child.getGedcom();
8386
+ if (!child.id || !fam.id || !gedcom) {
8387
+ return false;
8388
+ }
8389
+ if (!familyHasChild(fam, child.id)) {
8390
+ fam.assign("CHIL", makePointer(gedcom, fam, child.id, "INDI"), true);
8391
+ }
8392
+ const existingFamc = pointerByValue(child.get("FAMC"), fam.id);
8393
+ if (!existingFamc) {
8394
+ child.assign("FAMC", makePointer(gedcom, child, fam.id, "FAM"), true);
8394
8395
  }
8396
+ setChildPedigree(fam, child, pedigree, parent);
8397
+ normalizeSinglePointer(child, "FAMC");
8398
+ normalizeSinglePointer(fam, "CHIL");
8399
+ resetRelativesCache();
8400
+ return true;
8395
8401
  };
8396
- var createCommonDate = (gedcom, id, main, parent) => {
8397
- return createProxy(
8398
- new CommonDate(gedcom, id, main, parent)
8399
- );
8400
- };
8401
- var isCommonDate = (value) => {
8402
- return !!value && value !== null && typeof value === "object" && "_date" in value;
8403
- };
8404
-
8405
- // src/utils/fact-edit.ts
8406
- var SINGLETON_TAGS = /* @__PURE__ */ new Set(["BIRT", "DEAT", "SSN", "SEX", "DSCR"]);
8407
- var firstRecord = (node) => {
8402
+ var removePointerByValue = (owner, tag, targetId) => {
8403
+ const node = owner.get(tag);
8408
8404
  if (!node) {
8409
- return void 0;
8405
+ return false;
8410
8406
  }
8411
8407
  if (node instanceof List) {
8412
- return node.index(0);
8408
+ const keysToRemove = [];
8409
+ node.entries().forEach(([key, item]) => {
8410
+ if (item?.toValue?.() === targetId || item?.id === targetId || String(key) === targetId) {
8411
+ keysToRemove.push(key);
8412
+ }
8413
+ });
8414
+ keysToRemove.forEach((key) => {
8415
+ node.removeItem(key);
8416
+ });
8417
+ if (node.length === 0) {
8418
+ owner.remove(tag);
8419
+ }
8420
+ return keysToRemove.length > 0;
8413
8421
  }
8414
- return node.index(0) ?? node;
8415
- };
8416
- var setDateOn = (gedcom, owner, parent, date) => {
8417
- const trimmed = date.trim();
8418
- if (!trimmed) {
8419
- return;
8422
+ if (node.toValue?.() === targetId) {
8423
+ owner.remove(tag);
8424
+ return true;
8420
8425
  }
8421
- let dateNode = parent.get("DATE");
8422
- if (!dateNode || dateNode instanceof List) {
8423
- dateNode = createCommonDate(gedcom, void 0, owner, parent);
8424
- dateNode.type = "DATE";
8425
- parent.set("DATE", dateNode);
8426
+ const asList = node.toList?.();
8427
+ if (asList && asList.length > 0) {
8428
+ const keysToRemove = [];
8429
+ asList.entries().forEach(([key, item]) => {
8430
+ if (item?.toValue?.() === targetId || item?.id === targetId) {
8431
+ keysToRemove.push(key);
8432
+ }
8433
+ });
8434
+ if (keysToRemove.length === asList.length) {
8435
+ owner.remove(tag);
8436
+ return true;
8437
+ }
8438
+ if (keysToRemove.length > 0) {
8439
+ const remaining = asList.values().filter((item) => item?.toValue?.() !== targetId);
8440
+ if (remaining.length === 1 && remaining[0]) {
8441
+ owner.set(tag, remaining[0]);
8442
+ } else {
8443
+ owner.set(tag, new List(remaining));
8444
+ }
8445
+ return true;
8446
+ }
8426
8447
  }
8427
- dateNode.value = trimmed;
8448
+ return false;
8428
8449
  };
8429
- var fillFact = (gedcom, owner, event, input) => {
8430
- if (input.value?.trim()) {
8431
- event.value = input.value.trim();
8432
- }
8433
- if (input.type?.trim()) {
8434
- event.set("TYPE", input.type.trim());
8435
- }
8436
- if (input.date) {
8437
- setDateOn(gedcom, owner, event, input.date);
8450
+ var familyMemberCount = (fam) => {
8451
+ let count = 0;
8452
+ if (firstPointerId(fam.get("HUSB"))) {
8453
+ count += 1;
8438
8454
  }
8439
- if (input.place?.trim()) {
8440
- event.set("PLAC", input.place.trim());
8455
+ if (firstPointerId(fam.get("WIFE"))) {
8456
+ count += 1;
8441
8457
  }
8442
- if (input.note?.trim()) {
8443
- event.set("NOTE", input.note.trim());
8458
+ count += pointerIds(fam.get("CHIL")).length;
8459
+ return count;
8460
+ };
8461
+ var isDegenerateFamily = (fam) => familyMemberCount(fam) <= 1;
8462
+ var pruneEmptyFamilies = (gedcom) => {
8463
+ const emptyIds = [];
8464
+ gedcom.fams()?.forEach((fam, id) => {
8465
+ if (fam && isDegenerateFamily(fam) && id) {
8466
+ emptyIds.push(id);
8467
+ }
8468
+ });
8469
+ if (emptyIds.length === 0) {
8470
+ return [];
8444
8471
  }
8472
+ gedcom.indis()?.forEach((indi) => {
8473
+ if (!indi) {
8474
+ return;
8475
+ }
8476
+ emptyIds.forEach((famId) => {
8477
+ removePointerByValue(indi, "FAMS", famId);
8478
+ removePointerByValue(indi, "FAMC", famId);
8479
+ });
8480
+ });
8481
+ emptyIds.forEach((famId) => {
8482
+ gedcom.fams()?.removeItem(famId);
8483
+ });
8484
+ return emptyIds;
8445
8485
  };
8446
- var addIndividualFact = (indi, input) => {
8447
- const gedcom = indi.getGedcom();
8448
- if (!gedcom) {
8486
+ var findSharedSpouseFamily = (parent, coParentId) => {
8487
+ let found;
8488
+ parent.getFamilies("FAMS")?.forEach((fam) => {
8489
+ if (!found && fam && familyHasParent(fam, coParentId)) {
8490
+ found = fam;
8491
+ }
8492
+ });
8493
+ return found;
8494
+ };
8495
+ var findReusableParentChildFamily = (parent, child, options) => {
8496
+ if (!parent.id || !child.id) {
8449
8497
  return void 0;
8450
8498
  }
8451
- const tag = input.tag;
8452
- let event = SINGLETON_TAGS.has(tag) ? firstRecord(indi.get(tag)) : void 0;
8453
- if (!event) {
8454
- event = createCommon(gedcom, void 0, indi);
8455
- event.type = tag;
8456
- if (SINGLETON_TAGS.has(tag)) {
8457
- indi.set(tag, event);
8458
- } else {
8459
- indi.assign(tag, event);
8499
+ const reuseParentFamilies = options?.reuseParentFamilies !== false;
8500
+ const gedcom = parent.getGedcom() ?? child.getGedcom();
8501
+ let reusableFamc;
8502
+ let coupleFam;
8503
+ let already = false;
8504
+ const noteCoupleWith = (coParentId) => {
8505
+ if (!coParentId || coParentId === parent.id || coupleFam || !parent.id) {
8506
+ return;
8507
+ }
8508
+ const shared = findSharedSpouseFamily(parent, coParentId);
8509
+ if (shared) {
8510
+ coupleFam = shared;
8511
+ }
8512
+ };
8513
+ child.getFamilies("FAMC")?.forEach((fam) => {
8514
+ if (!fam) {
8515
+ return;
8516
+ }
8517
+ if (familyHasParent(fam, parent.id) && familyHasChild(fam, child.id)) {
8518
+ already = true;
8519
+ return;
8460
8520
  }
8521
+ pointerIds(fam.get("HUSB")).forEach(noteCoupleWith);
8522
+ pointerIds(fam.get("WIFE")).forEach(noteCoupleWith);
8523
+ if (!reusableFamc && canAttachAsSpouse(fam, parent)) {
8524
+ reusableFamc = fam;
8525
+ }
8526
+ });
8527
+ if (already) {
8528
+ return "already";
8461
8529
  }
8462
- fillFact(gedcom, indi, event, input);
8463
- return event;
8464
- };
8465
- var addFamilyFact = (fam, input) => {
8466
- const gedcom = fam.getGedcom();
8467
- if (!gedcom) {
8530
+ if (coupleFam) {
8531
+ return coupleFam;
8532
+ }
8533
+ if (reusableFamc) {
8534
+ return reusableFamc;
8535
+ }
8536
+ if (options?.targetFamilyId && gedcom) {
8537
+ const target = gedcom.fam(options.targetFamilyId);
8538
+ if (target && (familyHasParent(target, parent.id) || canAttachAsSpouse(target, parent))) {
8539
+ return target;
8540
+ }
8541
+ }
8542
+ if (!reuseParentFamilies) {
8468
8543
  return void 0;
8469
8544
  }
8470
- const event = createCommon(gedcom, void 0, fam);
8471
- event.type = input.tag;
8472
- fam.assign(input.tag, event);
8473
- fillFact(gedcom, fam, event, input);
8474
- return event;
8545
+ const parentFams = [];
8546
+ parent.getFamilies("FAMS")?.forEach((fam) => {
8547
+ if (fam) {
8548
+ parentFams.push(fam);
8549
+ }
8550
+ });
8551
+ if (parentFams.length === 1) {
8552
+ return parentFams[0];
8553
+ }
8554
+ return void 0;
8475
8555
  };
8476
- var addNonEvent = (owner, input) => {
8477
- const gedcom = owner.getGedcom();
8478
- const eventType = input.event?.trim().toUpperCase();
8479
- if (!gedcom || !eventType) {
8480
- return void 0;
8556
+ var consolidateChildIntoFamily = (child, keep) => {
8557
+ if (!child.id || !keep.id) {
8558
+ return [];
8481
8559
  }
8482
- const no = createCommon(gedcom, void 0, owner);
8483
- no.type = "NO";
8484
- no.value = eventType;
8485
- if (input.date?.trim()) {
8486
- setDateOn(gedcom, owner, no, input.date);
8560
+ const keepParentIds = /* @__PURE__ */ new Set([
8561
+ ...pointerIds(keep.get("HUSB")),
8562
+ ...pointerIds(keep.get("WIFE"))
8563
+ ]);
8564
+ const removed = [];
8565
+ child.getFamilies("FAMC")?.forEach((fam) => {
8566
+ if (!fam?.id || fam.id === keep.id) {
8567
+ return;
8568
+ }
8569
+ const famParentIds = [
8570
+ ...pointerIds(fam.get("HUSB")),
8571
+ ...pointerIds(fam.get("WIFE"))
8572
+ ];
8573
+ if (famParentIds.length === 0 || !famParentIds.every((id) => keepParentIds.has(id))) {
8574
+ return;
8575
+ }
8576
+ removePointerByValue(fam, "CHIL", child.id);
8577
+ normalizeSinglePointer(fam, "CHIL");
8578
+ removePointerByValue(child, "FAMC", fam.id);
8579
+ normalizeSinglePointer(child, "FAMC");
8580
+ removed.push(fam.id);
8581
+ });
8582
+ const gedcom = child.getGedcom() ?? keep.getGedcom();
8583
+ if (gedcom && removed.length > 0) {
8584
+ pruneEmptyFamilies(gedcom);
8487
8585
  }
8488
- if (input.note?.trim()) {
8489
- no.set("NOTE", input.note.trim());
8586
+ if (removed.length > 0) {
8587
+ resetRelativesCache();
8490
8588
  }
8491
- owner.assign("NO", no);
8492
- return no;
8589
+ return removed;
8493
8590
  };
8494
8591
 
8495
8592
  // src/classes/fam.ts
@@ -8927,7 +9024,7 @@ var createGedcomUid = () => {
8927
9024
  };
8928
9025
 
8929
9026
  // src/utils/gedcom7-metadata.ts
8930
- var GEDCOM_MONTHS2 = [
9027
+ var GEDCOM_MONTHS3 = [
8931
9028
  "JAN",
8932
9029
  "FEB",
8933
9030
  "MAR",
@@ -8943,7 +9040,7 @@ var GEDCOM_MONTHS2 = [
8943
9040
  ];
8944
9041
  var formatGedcom7Timestamp = (date = /* @__PURE__ */ new Date()) => {
8945
9042
  const day = String(date.getUTCDate());
8946
- const month = GEDCOM_MONTHS2[date.getUTCMonth()];
9043
+ const month = GEDCOM_MONTHS3[date.getUTCMonth()];
8947
9044
  const year = String(date.getUTCFullYear());
8948
9045
  const hh = String(date.getUTCHours()).padStart(2, "0");
8949
9046
  const mm = String(date.getUTCMinutes()).padStart(2, "0");
@@ -9021,6 +9118,7 @@ var TREEVIZ_EXTENSION_URIS = {
9021
9118
  _MTTAG: `${TREEVIZ_EXTENSION_BASE_URI}#_MTTAG`,
9022
9119
  _MTCAT: `${TREEVIZ_EXTENSION_BASE_URI}#_MTCAT`,
9023
9120
  _CLON: `${TREEVIZ_EXTENSION_BASE_URI}#_CLON`,
9121
+ _CREATED_AT: `${TREEVIZ_EXTENSION_BASE_URI}#_CREATED_AT`,
9024
9122
  _MSER: `${TREEVIZ_EXTENSION_BASE_URI}#_MSER`,
9025
9123
  _OID: `${TREEVIZ_EXTENSION_BASE_URI}#_OID`,
9026
9124
  _LKID: `${TREEVIZ_EXTENSION_BASE_URI}#_LKID`,
@@ -9160,7 +9258,7 @@ var ensureExtensionSchema = (gedcom, extraTags) => {
9160
9258
 
9161
9259
  // package.json
9162
9260
  var package_default = {
9163
- version: "2.1.18"};
9261
+ version: "2.1.23"};
9164
9262
 
9165
9263
  // src/utils/get-product-details.ts
9166
9264
  var isDevelopment = () => {
@@ -10387,6 +10485,7 @@ var mergeGedcoms = (targetGedcom, sourceGedcom, strategy = "id") => {
10387
10485
  }
10388
10486
  } else {
10389
10487
  if (clonedIndi.id) {
10488
+ stampCreatedAt(mergedGedcom, clonedIndi);
10390
10489
  mergedGedcom.indis()?.item(clonedIndi.id, clonedIndi);
10391
10490
  }
10392
10491
  }
@@ -10511,7 +10610,7 @@ var create = (gedcom, type, id, nodes) => {
10511
10610
  prevNode = createSour(gedcom, void 0, mainNode, curNode);
10512
10611
  } else if (type === "OBJE") {
10513
10612
  prevNode = createObje(gedcom, void 0, mainNode, curNode);
10514
- } else if (type === "DATE") {
10613
+ } else if (type === "DATE" || type === "_CREATED_AT") {
10515
10614
  prevNode = createCommonDate(gedcom, void 0, mainNode, curNode);
10516
10615
  } else if (type === "NOTE" || type === "SNOTE" || type === "_TREEVIZ_LIFE_STORY" || type === "_TREEVIZ_FAMILY_STORY") {
10517
10616
  prevNode = createCommonNote(gedcom, void 0, mainNode, curNode);
@@ -10537,6 +10636,7 @@ var GedcomTree = {
10537
10636
  return this.parseHierarchy(content, options);
10538
10637
  },
10539
10638
  parseHierarchy: function(content, options) {
10639
+ content = content.replace(/^\uFEFF+/, "");
10540
10640
  const { settings, filename = "" } = options ?? {};
10541
10641
  const { linkedPersons = "skip", linkingKey } = settings ?? {};
10542
10642
  const gedcom = createGedCom();