xref: /webtrees/app/Gedcom.php (revision 864236f581376fe3af796027f148a38f6f877b35)
10f471f91SGreg Roach<?php
23976b470SGreg Roach
30f471f91SGreg Roach/**
40f471f91SGreg Roach * webtrees: online genealogy
55bfc6897SGreg Roach * Copyright (C) 2022 webtrees development team
60f471f91SGreg Roach * This program is free software: you can redistribute it and/or modify
70f471f91SGreg Roach * it under the terms of the GNU General Public License as published by
80f471f91SGreg Roach * the Free Software Foundation, either version 3 of the License, or
90f471f91SGreg Roach * (at your option) any later version.
100f471f91SGreg Roach * This program is distributed in the hope that it will be useful,
110f471f91SGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of
120f471f91SGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
130f471f91SGreg Roach * GNU General Public License for more details.
140f471f91SGreg Roach * You should have received a copy of the GNU General Public License
1589f7189bSGreg Roach * along with this program. If not, see <https://www.gnu.org/licenses/>.
160f471f91SGreg Roach */
17fcfa147eSGreg Roach
18e7f56f2aSGreg Roachdeclare(strict_types=1);
19e7f56f2aSGreg Roach
200f471f91SGreg Roachnamespace Fisharebest\Webtrees;
210f471f91SGreg Roach
22e669bb4bSGreg Roachuse Fisharebest\Webtrees\Contracts\ElementFactoryInterface;
2300c92694SGreg Roachuse Fisharebest\Webtrees\Contracts\ElementInterface;
24*864236f5SGreg Roachuse Fisharebest\Webtrees\CustomTags\Aldfaer;
25*864236f5SGreg Roachuse Fisharebest\Webtrees\CustomTags\Ancestry;
26*864236f5SGreg Roachuse Fisharebest\Webtrees\CustomTags\BrothersKeeper;
27*864236f5SGreg Roachuse Fisharebest\Webtrees\CustomTags\FamilySearch;
28*864236f5SGreg Roachuse Fisharebest\Webtrees\CustomTags\FamilyTreeBuilder;
29*864236f5SGreg Roachuse Fisharebest\Webtrees\CustomTags\FamilyTreeMaker;
30*864236f5SGreg Roachuse Fisharebest\Webtrees\CustomTags\Gedcom7;
31*864236f5SGreg Roachuse Fisharebest\Webtrees\CustomTags\GedcomL;
32*864236f5SGreg Roachuse Fisharebest\Webtrees\CustomTags\Geneatique;
33*864236f5SGreg Roachuse Fisharebest\Webtrees\CustomTags\GenPlusWin;
34*864236f5SGreg Roachuse Fisharebest\Webtrees\CustomTags\Heredis;
35*864236f5SGreg Roachuse Fisharebest\Webtrees\CustomTags\Legacy;
36*864236f5SGreg Roachuse Fisharebest\Webtrees\CustomTags\MyHeritage;
37*864236f5SGreg Roachuse Fisharebest\Webtrees\CustomTags\PersonalAncestralFile;
38*864236f5SGreg Roachuse Fisharebest\Webtrees\CustomTags\PhpGedView;
39*864236f5SGreg Roachuse Fisharebest\Webtrees\CustomTags\ProGen;
40*864236f5SGreg Roachuse Fisharebest\Webtrees\CustomTags\Reunion;
41*864236f5SGreg Roachuse Fisharebest\Webtrees\CustomTags\RootsMagic;
4200c92694SGreg Roachuse Fisharebest\Webtrees\Elements\AddressCity;
4300c92694SGreg Roachuse Fisharebest\Webtrees\Elements\AddressCountry;
4400c92694SGreg Roachuse Fisharebest\Webtrees\Elements\AddressEmail;
4500c92694SGreg Roachuse Fisharebest\Webtrees\Elements\AddressFax;
4600c92694SGreg Roachuse Fisharebest\Webtrees\Elements\AddressLine;
4700c92694SGreg Roachuse Fisharebest\Webtrees\Elements\AddressLine1;
4800c92694SGreg Roachuse Fisharebest\Webtrees\Elements\AddressLine2;
4900c92694SGreg Roachuse Fisharebest\Webtrees\Elements\AddressLine3;
5000c92694SGreg Roachuse Fisharebest\Webtrees\Elements\AddressPostalCode;
5100c92694SGreg Roachuse Fisharebest\Webtrees\Elements\AddressState;
5200c92694SGreg Roachuse Fisharebest\Webtrees\Elements\AddressWebPage;
5300c92694SGreg Roachuse Fisharebest\Webtrees\Elements\AdoptedByWhichParent;
5400c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Adoption;
5500c92694SGreg Roachuse Fisharebest\Webtrees\Elements\AdultChristening;
5600c92694SGreg Roachuse Fisharebest\Webtrees\Elements\AgeAtEvent;
5700c92694SGreg Roachuse Fisharebest\Webtrees\Elements\AncestralFileNumber;
5800c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Annulment;
5900c92694SGreg Roachuse Fisharebest\Webtrees\Elements\ApprovedSystemId;
6000c92694SGreg Roachuse Fisharebest\Webtrees\Elements\AutomatedRecordId;
6100c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Baptism;
6200c92694SGreg Roachuse Fisharebest\Webtrees\Elements\BarMitzvah;
6300c92694SGreg Roachuse Fisharebest\Webtrees\Elements\BasMitzvah;
6400c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Birth;
6500c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Blessing;
6600c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Burial;
6700c92694SGreg Roachuse Fisharebest\Webtrees\Elements\CasteName;
6800c92694SGreg Roachuse Fisharebest\Webtrees\Elements\CauseOfEvent;
6900c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Census;
7000c92694SGreg Roachuse Fisharebest\Webtrees\Elements\CertaintyAssessment;
7100c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Change;
7200c92694SGreg Roachuse Fisharebest\Webtrees\Elements\ChangeDate;
7300c92694SGreg Roachuse Fisharebest\Webtrees\Elements\CharacterSet;
7400c92694SGreg Roachuse Fisharebest\Webtrees\Elements\ChildLinkageStatus;
7500c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Christening;
7600c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Confirmation;
7700c92694SGreg Roachuse Fisharebest\Webtrees\Elements\ContentDescription;
7800c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Coordinates;
7900c92694SGreg Roachuse Fisharebest\Webtrees\Elements\CopyrightFile;
8000c92694SGreg Roachuse Fisharebest\Webtrees\Elements\CopyrightSourceData;
8100c92694SGreg Roachuse Fisharebest\Webtrees\Elements\CountOfChildren;
8200c92694SGreg Roachuse Fisharebest\Webtrees\Elements\CountOfMarriages;
83701f5d18SGreg Roachuse Fisharebest\Webtrees\Elements\Creation;
8400c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Cremation;
8500c92694SGreg Roachuse Fisharebest\Webtrees\Elements\CustomElement;
8600c92694SGreg Roachuse Fisharebest\Webtrees\Elements\CustomEvent;
8700c92694SGreg Roachuse Fisharebest\Webtrees\Elements\CustomFact;
8800c92694SGreg Roachuse Fisharebest\Webtrees\Elements\CustomFamilyEvent;
8900c92694SGreg Roachuse Fisharebest\Webtrees\Elements\CustomIndividualEvent;
9000c92694SGreg Roachuse Fisharebest\Webtrees\Elements\DateLdsOrd;
9100c92694SGreg Roachuse Fisharebest\Webtrees\Elements\DateValue;
92099c152eSGreg Roachuse Fisharebest\Webtrees\Elements\DateValueExact;
93099c152eSGreg Roachuse Fisharebest\Webtrees\Elements\DateValueToday;
9400c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Death;
9500c92694SGreg Roachuse Fisharebest\Webtrees\Elements\DescriptiveTitle;
9600c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Divorce;
9700c92694SGreg Roachuse Fisharebest\Webtrees\Elements\DivorceFiled;
9800c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Emigration;
9900c92694SGreg Roachuse Fisharebest\Webtrees\Elements\EmptyElement;
10000c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Engagement;
10100c92694SGreg Roachuse Fisharebest\Webtrees\Elements\EventAttributeType;
10200c92694SGreg Roachuse Fisharebest\Webtrees\Elements\EventOrFactClassification;
10300c92694SGreg Roachuse Fisharebest\Webtrees\Elements\EventsRecorded;
10400c92694SGreg Roachuse Fisharebest\Webtrees\Elements\EventTypeCitedFrom;
105701f5d18SGreg Roachuse Fisharebest\Webtrees\Elements\ExternalIdentifier;
106701f5d18SGreg Roachuse Fisharebest\Webtrees\Elements\ExternalIdentifierType;
10700c92694SGreg Roachuse Fisharebest\Webtrees\Elements\FamilyCensus;
1085d2c6313SGreg Roachuse Fisharebest\Webtrees\Elements\FamilyEvent;
1095d2c6313SGreg Roachuse Fisharebest\Webtrees\Elements\FamilyFact;
11000c92694SGreg Roachuse Fisharebest\Webtrees\Elements\FamilyRecord;
11100c92694SGreg Roachuse Fisharebest\Webtrees\Elements\FamilyResidence;
11200c92694SGreg Roachuse Fisharebest\Webtrees\Elements\FamilySearchFamilyTreeId;
11300c92694SGreg Roachuse Fisharebest\Webtrees\Elements\FamilyStatusText;
11400c92694SGreg Roachuse Fisharebest\Webtrees\Elements\FileName;
11500c92694SGreg Roachuse Fisharebest\Webtrees\Elements\FirstCommunion;
11600c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Form;
11700c92694SGreg Roachuse Fisharebest\Webtrees\Elements\GedcomElement;
11800c92694SGreg Roachuse Fisharebest\Webtrees\Elements\GenerationsOfAncestors;
11900c92694SGreg Roachuse Fisharebest\Webtrees\Elements\GenerationsOfDescendants;
12000c92694SGreg Roachuse Fisharebest\Webtrees\Elements\GovIdentifier;
12100c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Graduation;
12200c92694SGreg Roachuse Fisharebest\Webtrees\Elements\HeaderRecord;
12300c92694SGreg Roachuse Fisharebest\Webtrees\Elements\HierarchicalRelationship;
12400c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Immigration;
1255d2c6313SGreg Roachuse Fisharebest\Webtrees\Elements\IndividualEvent;
1265d2c6313SGreg Roachuse Fisharebest\Webtrees\Elements\IndividualFact;
12700c92694SGreg Roachuse Fisharebest\Webtrees\Elements\IndividualRecord;
12800c92694SGreg Roachuse Fisharebest\Webtrees\Elements\LanguageId;
12900c92694SGreg Roachuse Fisharebest\Webtrees\Elements\LdsBaptism;
13000c92694SGreg Roachuse Fisharebest\Webtrees\Elements\LdsBaptismDateStatus;
13100c92694SGreg Roachuse Fisharebest\Webtrees\Elements\LdsChildSealing;
13200c92694SGreg Roachuse Fisharebest\Webtrees\Elements\LdsChildSealingDateStatus;
13300c92694SGreg Roachuse Fisharebest\Webtrees\Elements\LdsConfirmation;
13400c92694SGreg Roachuse Fisharebest\Webtrees\Elements\LdsEndowment;
13500c92694SGreg Roachuse Fisharebest\Webtrees\Elements\LdsEndowmentDateStatus;
136701f5d18SGreg Roachuse Fisharebest\Webtrees\Elements\LdsInitiatory;
137701f5d18SGreg Roachuse Fisharebest\Webtrees\Elements\LdsOrdinanceStatus;
13800c92694SGreg Roachuse Fisharebest\Webtrees\Elements\LdsSpouseSealing;
13900c92694SGreg Roachuse Fisharebest\Webtrees\Elements\LdsSpouseSealingDateStatus;
14000c92694SGreg Roachuse Fisharebest\Webtrees\Elements\LocationRecord;
14100c92694SGreg Roachuse Fisharebest\Webtrees\Elements\MaidenheadLocator;
14200c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Marriage;
14300c92694SGreg Roachuse Fisharebest\Webtrees\Elements\MarriageBanns;
14400c92694SGreg Roachuse Fisharebest\Webtrees\Elements\MarriageContract;
14500c92694SGreg Roachuse Fisharebest\Webtrees\Elements\MarriageLicence;
14600c92694SGreg Roachuse Fisharebest\Webtrees\Elements\MarriageSettlement;
14700c92694SGreg Roachuse Fisharebest\Webtrees\Elements\MarriageType;
14800c92694SGreg Roachuse Fisharebest\Webtrees\Elements\MediaRecord;
14900c92694SGreg Roachuse Fisharebest\Webtrees\Elements\MultimediaFileReference;
15000c92694SGreg Roachuse Fisharebest\Webtrees\Elements\MultimediaFormat;
15100c92694SGreg Roachuse Fisharebest\Webtrees\Elements\NameOfBusiness;
15200c92694SGreg Roachuse Fisharebest\Webtrees\Elements\NameOfFamilyFile;
15300c92694SGreg Roachuse Fisharebest\Webtrees\Elements\NameOfProduct;
15400c92694SGreg Roachuse Fisharebest\Webtrees\Elements\NameOfRepository;
15500c92694SGreg Roachuse Fisharebest\Webtrees\Elements\NameOfSourceData;
15600c92694SGreg Roachuse Fisharebest\Webtrees\Elements\NamePersonal;
15700c92694SGreg Roachuse Fisharebest\Webtrees\Elements\NamePhoneticVariation;
15800c92694SGreg Roachuse Fisharebest\Webtrees\Elements\NamePieceGiven;
15900c92694SGreg Roachuse Fisharebest\Webtrees\Elements\NamePieceNickname;
16000c92694SGreg Roachuse Fisharebest\Webtrees\Elements\NamePiecePrefix;
16100c92694SGreg Roachuse Fisharebest\Webtrees\Elements\NamePieceSuffix;
16200c92694SGreg Roachuse Fisharebest\Webtrees\Elements\NamePieceSurname;
16300c92694SGreg Roachuse Fisharebest\Webtrees\Elements\NamePieceSurnamePrefix;
16400c92694SGreg Roachuse Fisharebest\Webtrees\Elements\NameRomanizedVariation;
16500c92694SGreg Roachuse Fisharebest\Webtrees\Elements\NameType;
16600c92694SGreg Roachuse Fisharebest\Webtrees\Elements\NationalIdNumber;
167f15544dcSGreg Roachuse Fisharebest\Webtrees\Elements\NationalOrTribalOrigin;
16800c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Naturalization;
16900c92694SGreg Roachuse Fisharebest\Webtrees\Elements\NobilityTypeTitle;
170701f5d18SGreg Roachuse Fisharebest\Webtrees\Elements\NonEvent;
17100c92694SGreg Roachuse Fisharebest\Webtrees\Elements\NoteRecord;
17200c92694SGreg Roachuse Fisharebest\Webtrees\Elements\NoteStructure;
17300c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Occupation;
17400c92694SGreg Roachuse Fisharebest\Webtrees\Elements\OrdinanceProcessFlag;
17500c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Ordination;
17600c92694SGreg Roachuse Fisharebest\Webtrees\Elements\PafUid;
17700c92694SGreg Roachuse Fisharebest\Webtrees\Elements\PedigreeLinkageType;
17800c92694SGreg Roachuse Fisharebest\Webtrees\Elements\PermanentRecordFileNumber;
17900c92694SGreg Roachuse Fisharebest\Webtrees\Elements\PhoneNumber;
18000c92694SGreg Roachuse Fisharebest\Webtrees\Elements\PhoneticType;
18100c92694SGreg Roachuse Fisharebest\Webtrees\Elements\PhysicalDescription;
18200c92694SGreg Roachuse Fisharebest\Webtrees\Elements\PlaceHierarchy;
18300c92694SGreg Roachuse Fisharebest\Webtrees\Elements\PlaceLatitude;
18400c92694SGreg Roachuse Fisharebest\Webtrees\Elements\PlaceLivingOrdinance;
18500c92694SGreg Roachuse Fisharebest\Webtrees\Elements\PlaceLongtitude;
18600c92694SGreg Roachuse Fisharebest\Webtrees\Elements\PlaceName;
18700c92694SGreg Roachuse Fisharebest\Webtrees\Elements\PlacePhoneticVariation;
18800c92694SGreg Roachuse Fisharebest\Webtrees\Elements\PlaceRomanizedVariation;
18900c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Possessions;
19000c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Probate;
19100c92694SGreg Roachuse Fisharebest\Webtrees\Elements\PublicationDate;
19200c92694SGreg Roachuse Fisharebest\Webtrees\Elements\ReceivingSystemName;
19300c92694SGreg Roachuse Fisharebest\Webtrees\Elements\RelationIsDescriptor;
19400c92694SGreg Roachuse Fisharebest\Webtrees\Elements\ReligiousAffiliation;
19500c92694SGreg Roachuse Fisharebest\Webtrees\Elements\RepositoryRecord;
19600c92694SGreg Roachuse Fisharebest\Webtrees\Elements\ResearchTask;
19700c92694SGreg Roachuse Fisharebest\Webtrees\Elements\ResearchTaskPriority;
19800c92694SGreg Roachuse Fisharebest\Webtrees\Elements\ResearchTaskStatus;
19900c92694SGreg Roachuse Fisharebest\Webtrees\Elements\ResearchTaskType;
20000c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Residence;
20100c92694SGreg Roachuse Fisharebest\Webtrees\Elements\ResponsibleAgency;
20200c92694SGreg Roachuse Fisharebest\Webtrees\Elements\RestrictionNotice;
20300c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Retirement;
20400c92694SGreg Roachuse Fisharebest\Webtrees\Elements\RoleInEvent;
20500c92694SGreg Roachuse Fisharebest\Webtrees\Elements\RomanizedType;
20600c92694SGreg Roachuse Fisharebest\Webtrees\Elements\ScholasticAchievement;
20700c92694SGreg Roachuse Fisharebest\Webtrees\Elements\SexValue;
20800c92694SGreg Roachuse Fisharebest\Webtrees\Elements\SexXValue;
20900c92694SGreg Roachuse Fisharebest\Webtrees\Elements\SocialSecurityNumber;
21000c92694SGreg Roachuse Fisharebest\Webtrees\Elements\SourceCallNumber;
21100c92694SGreg Roachuse Fisharebest\Webtrees\Elements\SourceData;
21200c92694SGreg Roachuse Fisharebest\Webtrees\Elements\SourceFiledByEntry;
21300c92694SGreg Roachuse Fisharebest\Webtrees\Elements\SourceJurisdictionPlace;
21400c92694SGreg Roachuse Fisharebest\Webtrees\Elements\SourceMediaType;
21500c92694SGreg Roachuse Fisharebest\Webtrees\Elements\SourceOriginator;
21600c92694SGreg Roachuse Fisharebest\Webtrees\Elements\SourcePublicationFacts;
21700c92694SGreg Roachuse Fisharebest\Webtrees\Elements\SourceRecord;
21800c92694SGreg Roachuse Fisharebest\Webtrees\Elements\SubmissionRecord;
21900c92694SGreg Roachuse Fisharebest\Webtrees\Elements\SubmitterName;
22000c92694SGreg Roachuse Fisharebest\Webtrees\Elements\SubmitterRecord;
22100c92694SGreg Roachuse Fisharebest\Webtrees\Elements\SubmitterRegisteredRfn;
22200c92694SGreg Roachuse Fisharebest\Webtrees\Elements\SubmitterText;
22300c92694SGreg Roachuse Fisharebest\Webtrees\Elements\TempleCode;
22400c92694SGreg Roachuse Fisharebest\Webtrees\Elements\TextFromSource;
22500c92694SGreg Roachuse Fisharebest\Webtrees\Elements\TimeValue;
226099c152eSGreg Roachuse Fisharebest\Webtrees\Elements\TimeValueNow;
22700c92694SGreg Roachuse Fisharebest\Webtrees\Elements\TransmissionDate;
228701f5d18SGreg Roachuse Fisharebest\Webtrees\Elements\Uid;
22900c92694SGreg Roachuse Fisharebest\Webtrees\Elements\UserReferenceNumber;
23000c92694SGreg Roachuse Fisharebest\Webtrees\Elements\UserReferenceType;
23100c92694SGreg Roachuse Fisharebest\Webtrees\Elements\VersionNumber;
23200c92694SGreg Roachuse Fisharebest\Webtrees\Elements\WebtreesUser;
23300c92694SGreg Roachuse Fisharebest\Webtrees\Elements\WhereWithinSource;
23400c92694SGreg Roachuse Fisharebest\Webtrees\Elements\Will;
23500c92694SGreg Roachuse Fisharebest\Webtrees\Elements\XrefAssociate;
23600c92694SGreg Roachuse Fisharebest\Webtrees\Elements\XrefFamily;
23700c92694SGreg Roachuse Fisharebest\Webtrees\Elements\XrefIndividual;
23800c92694SGreg Roachuse Fisharebest\Webtrees\Elements\XrefLocation;
23900c92694SGreg Roachuse Fisharebest\Webtrees\Elements\XrefMedia;
24000c92694SGreg Roachuse Fisharebest\Webtrees\Elements\XrefRepository;
241701f5d18SGreg Roachuse Fisharebest\Webtrees\Elements\XrefSharedNote;
24200c92694SGreg Roachuse Fisharebest\Webtrees\Elements\XrefSource;
24300c92694SGreg Roachuse Fisharebest\Webtrees\Elements\XrefSubmission;
24400c92694SGreg Roachuse Fisharebest\Webtrees\Elements\XrefSubmitter;
24500c92694SGreg Roach
2460f471f91SGreg Roach/**
2470f471f91SGreg Roach * GEDCOM 5.5.1 specification
2480f471f91SGreg Roach */
249c1010edaSGreg Roachclass Gedcom
250c1010edaSGreg Roach{
2510f471f91SGreg Roach    // 255 less the EOL character.
25216d6367aSGreg Roach    public const LINE_LENGTH = 253;
2538d0ebef0SGreg Roach
2548d0ebef0SGreg Roach    // Gedcom tags which indicate the start of life.
25569d5bee2SGreg Roach    public const BIRTH_EVENTS = ['BIRT', 'CHR', 'BAPM'];
2568d0ebef0SGreg Roach
2578d0ebef0SGreg Roach    // Gedcom tags which indicate the end of life.
25816d6367aSGreg Roach    public const DEATH_EVENTS = ['DEAT', 'BURI', 'CREM'];
2598d0ebef0SGreg Roach
2608d0ebef0SGreg Roach    // Gedcom tags which indicate the start of a relationship.
26116d6367aSGreg Roach    public const MARRIAGE_EVENTS = ['MARR', '_NMR'];
2628d0ebef0SGreg Roach
2638d0ebef0SGreg Roach    // Gedcom tags which indicate the end of a relationship.
26416d6367aSGreg Roach    public const DIVORCE_EVENTS = ['DIV', 'ANUL', '_SEPR'];
2658d0ebef0SGreg Roach
2668d0ebef0SGreg Roach    // Regular expression to match a GEDCOM tag.
26716d6367aSGreg Roach    public const REGEX_TAG = '[_A-Z][_A-Z0-9]*';
2688d0ebef0SGreg Roach
2698d0ebef0SGreg Roach    // Regular expression to match a GEDCOM XREF.
270f81cefe9SGreg Roach    public const REGEX_XREF = '[A-Za-z0-9:_.-]{1,20}';
2718d0ebef0SGreg Roach
272c67b9b50SGreg Roach    // Regular expression to match a GEDCOM fact/event for editing raw GEDCOM.
2738c21b414SGreg Roach    private const REGEX_VALUE   = '( .+)?';
2748c21b414SGreg Roach    private const REGEX_LEVEL_9 = '\n9 ' . self::REGEX_TAG . self::REGEX_VALUE;
2758c21b414SGreg Roach    private const REGEX_LEVEL_8 = '\n8 ' . self::REGEX_TAG . self::REGEX_VALUE . '(' . self::REGEX_LEVEL_9 . ')*';
2768c21b414SGreg Roach    private const REGEX_LEVEL_7 = '\n7 ' . self::REGEX_TAG . self::REGEX_VALUE . '(' . self::REGEX_LEVEL_8 . ')*';
2778c21b414SGreg Roach    private const REGEX_LEVEL_6 = '\n6 ' . self::REGEX_TAG . self::REGEX_VALUE . '(' . self::REGEX_LEVEL_7 . ')*';
2788c21b414SGreg Roach    private const REGEX_LEVEL_5 = '\n5 ' . self::REGEX_TAG . self::REGEX_VALUE . '(' . self::REGEX_LEVEL_6 . ')*';
2798c21b414SGreg Roach    private const REGEX_LEVEL_4 = '\n4 ' . self::REGEX_TAG . self::REGEX_VALUE . '(' . self::REGEX_LEVEL_5 . ')*';
2808c21b414SGreg Roach    private const REGEX_LEVEL_3 = '\n3 ' . self::REGEX_TAG . self::REGEX_VALUE . '(' . self::REGEX_LEVEL_4 . ')*';
2818c21b414SGreg Roach    private const REGEX_LEVEL_2 = '\n2 ' . self::REGEX_TAG . self::REGEX_VALUE . '(' . self::REGEX_LEVEL_3 . ')*';
282c67b9b50SGreg Roach    public const REGEX_FACT     = '1 ' . self::REGEX_TAG . self::REGEX_VALUE . '(' . self::REGEX_LEVEL_2 . ')*\n?';
2838c21b414SGreg Roach
2841c6adce8SGreg Roach    // Separates the parts of a place name.
285ead61980SGreg Roach    public const PLACE_SEPARATOR = ', ';
286392561bbSGreg Roach
287392561bbSGreg Roach    // Regex to match a (badly formed) GEDCOM place separator.
28890949315SGreg Roach    public const PLACE_SEPARATOR_REGEX = '/ *,[, ]*/';
28990949315SGreg Roach
29090949315SGreg Roach    // LATI and LONG tags
29190949315SGreg Roach    public const LATITUDE_NORTH = 'N';
29290949315SGreg Roach    public const LATITUDE_SOUTH = 'S';
29390949315SGreg Roach    public const LONGITUDE_EAST = 'E';
29490949315SGreg Roach    public const LONGITUDE_WEST = 'W';
29571f696adSGreg Roach
29671f696adSGreg Roach    // Not all record types allow a CHAN event.
29771f696adSGreg Roach    public const RECORDS_WITH_CHAN = [
29871f696adSGreg Roach        Family::RECORD_TYPE,
29971f696adSGreg Roach        Individual::RECORD_TYPE,
30071f696adSGreg Roach        Media::RECORD_TYPE,
30171f696adSGreg Roach        Note::RECORD_TYPE,
30271f696adSGreg Roach        Repository::RECORD_TYPE,
30371f696adSGreg Roach        Source::RECORD_TYPE,
30471f696adSGreg Roach        Submitter::RECORD_TYPE,
30571f696adSGreg Roach    ];
306c8183f29SGreg Roach
307c8183f29SGreg Roach    // These preferences control multiple tag definitions
308c8183f29SGreg Roach    public const HIDDEN_TAGS = [
309c8183f29SGreg Roach        // Individual names
310c8183f29SGreg Roach        'NAME_NPFX'  => ['INDI:NAME:NPFX', 'INDI:NAME:FONE:NPFX', 'INDI:NAME:ROMN:NPFX'],
311c8183f29SGreg Roach        'NAME_SPFX'  => ['INDI:NAME:SPFX', 'INDI:NAME:FONE:SPFX', 'INDI:NAME:ROMN:SPFX'],
312c8183f29SGreg Roach        'NAME_NSFX'  => ['INDI:NAME:NSFX', 'INDI:NAME:FONE:NSFX', 'INDI:NAME:ROMN:NSFX'],
313c8183f29SGreg Roach        'NAME_NICK'  => ['INDI:NAME:NICK', 'INDI:NAME:FONE:NICK', 'INDI:NAME:ROMN:NICK'],
314c8183f29SGreg Roach        'NAME_FONE'  => ['INDI:NAME:FONE'],
315c8183f29SGreg Roach        'NAME_ROMN'  => ['INDI:NAME:ROMN'],
31603c55594SGreg Roach        'NAME_NOTE'  => ['INDI:NAME:NOTE', 'INDI:NAME:FONE:NOTE', 'INDI:NAME:ROMN:NOTE'],
31703c55594SGreg Roach        'NAME_SOUR'  => ['INDI:NAME:SOUR', 'INDI:NAME:FONE:SOUR', 'INDI:NAME:ROMN:SOUR'],
318c8183f29SGreg Roach        // Places
319302fdb8dSGreg Roach        'PLAC_MAP'   => [':PLAC:MAP'],
320302fdb8dSGreg Roach        'PLAC_FONE'  => [':PLAC:FONE'],
321302fdb8dSGreg Roach        'PLAC_ROMN'  => [':PLAC:ROMN'],
322302fdb8dSGreg Roach        'PLAC_FORM'  => [':PLAC:FORM', 'HEAD:PLAC'],
323302fdb8dSGreg Roach        'PLAC_NOTE'  => [':PLAC:NOTE'],
324c8183f29SGreg Roach        // Addresses
325302fdb8dSGreg Roach        'ADDR_EMAIL' => [':EMAIL'],
326302fdb8dSGreg Roach        'ADDR_PHON'  => [':PHON'],
327302fdb8dSGreg Roach        'ADDR_WWW'   => [':WWW'],
328c8183f29SGreg Roach        // Source citations
329c8183f29SGreg Roach        'SOUR_EVEN'  => [':SOUR:EVEN'],
330c8183f29SGreg Roach        'SOUR_DATE'  => [':SOUR:DATA:DATE'],
331c8183f29SGreg Roach        'SOUR_NOTE'  => [':SOUR:NOTE'],
332c8183f29SGreg Roach        'SOUR_QUAY'  => [':SOUR:QUAY'],
333c8183f29SGreg Roach        // Sources
33440c249dcSGreg Roach        'SOUR_DATA'  => ['SOUR:DATA:EVEN', 'SOUR:DATA:AGNC', 'SOUR:DATA:NOTE'],
335c8183f29SGreg Roach        // Individuals
336c8183f29SGreg Roach        'BIRT_FAMC'  => ['INDI:BIRT:FAMC'],
337c8183f29SGreg Roach        'RELI'       => ['INDI:RELI'],
338c8183f29SGreg Roach        'BAPM'       => ['INDI:BAPM'],
339c8183f29SGreg Roach        'CHR'        => ['INDI:CHR', 'INDI:CHRA'],
340c8183f29SGreg Roach        'FCOM'       => ['INDI:FCOM', 'INDI:CONF'],
341c8183f29SGreg Roach        'ORDN'       => ['INDI:ORDN'],
342c8183f29SGreg Roach        'BARM'       => ['INDI:BARM', 'INDI:BASM'],
343c8183f29SGreg Roach        'ALIA'       => ['INDI:ALIA'],
344c8183f29SGreg Roach        'ASSO'       => ['INDI:ASSO'],
345c8183f29SGreg Roach        // Families
346c8183f29SGreg Roach        'ENGA'       => ['FAM:ENGA'],
347c8183f29SGreg Roach        'MARB'       => ['FAM:MARB'],
348c8183f29SGreg Roach        'MARC'       => ['FAM:MARC'],
349c8183f29SGreg Roach        'MARL'       => ['FAM:MARL'],
350c8183f29SGreg Roach        'MARS'       => ['FAM:MARS'],
351c8183f29SGreg Roach        'ANUL'       => ['FAM:ANUL'],
352c8183f29SGreg Roach        'DIVF'       => ['FAM:DIVF'],
353c8183f29SGreg Roach        'FAM_RESI'   => ['FAM:RESI'],
354c8183f29SGreg Roach        'FAM_CENS'   => ['FAM:CENS'],
355c8183f29SGreg Roach        // LDS church
356c8183f29SGreg Roach        'LDS'        => ['INDI:BAPL', 'INDI:CONL', 'INDI:ENDL', 'INDI:SLGC', 'FAM:SLGS', 'HEAD:SUBN'],
357c8183f29SGreg Roach        // Identifiers
358c8183f29SGreg Roach        'AFN'        => ['INDI:AFN'],
359c8183f29SGreg Roach        'IDNO'       => ['INDI:IDNO'],
360c8183f29SGreg Roach        'SSN'        => ['INDI:SSN'],
361302fdb8dSGreg Roach        'RFN'        => [':RFN'],
362302fdb8dSGreg Roach        'REFN'       => [':REFN'],
363302fdb8dSGreg Roach        'RIN'        => [':RIN'],
364c8183f29SGreg Roach        // Submitters
365c8183f29SGreg Roach        'SUBM'       => ['INDI:SUBM', 'FAM:SUBM'],
366c8183f29SGreg Roach        'ANCI'       => ['INDI:ANCI', 'INDI:DESI'],
367c8183f29SGreg Roach    ];
36800c92694SGreg Roach
36900c92694SGreg Roach    // Custom GEDCOM tags that can be created in webtrees.
37000c92694SGreg Roach    public const CUSTOM_FAMILY_TAGS = [
37138f085bcSGreg Roach        'FACT',
37200c92694SGreg Roach        '_COML',
37300c92694SGreg Roach        '_MARI',
37400c92694SGreg Roach        '_MBON',
37500c92694SGreg Roach        '_NMR',
37600c92694SGreg Roach        '_SEPR',
37700c92694SGreg Roach    ];
37800c92694SGreg Roach
37900c92694SGreg Roach    public const CUSTOM_INDIVIDUAL_TAGS = [
38000c92694SGreg Roach        '_BRTM',
38100c92694SGreg Roach        '_CIRC',
38200c92694SGreg Roach        '_DEG',
38300c92694SGreg Roach        '_DNA',
38400c92694SGreg Roach        '_EXCM',
38500c92694SGreg Roach        '_EYEC',
38600c92694SGreg Roach        '_FNRL',
38700c92694SGreg Roach        '_FSFTID',
38800c92694SGreg Roach        '_HAIR',
38900c92694SGreg Roach        '_HEIG',
39000c92694SGreg Roach        '_INTE',
39100c92694SGreg Roach        '_MDCL',
39200c92694SGreg Roach        '_MEDC',
39300c92694SGreg Roach        '_MILI',
39400c92694SGreg Roach        '_MILT',
39500c92694SGreg Roach        '_NAMS',
396a49c80d4SGreg Roach        '_NMAR',
39700c92694SGreg Roach        '_PRMN',
39800c92694SGreg Roach        '_WEIG',
39900c92694SGreg Roach        '_YART',
40000c92694SGreg Roach    ];
40100c92694SGreg Roach
402356588a1SGreg Roach    // Some applications create GEDCOM files containing records without XREFS.
403356588a1SGreg Roach    // We cannot process these.
404356588a1SGreg Roach    public const CUSTOM_RECORDS_WITHOUT_XREFS = [
405356588a1SGreg Roach        'EMOTIONALRELATIONSHIP', // GenoPro
406356588a1SGreg Roach        'GENOMAP', // GenoPro
407356588a1SGreg Roach        'GLOBAL', // GenoPro
408356588a1SGreg Roach        'LABEL', // GenoPro
409356588a1SGreg Roach        'PEDIGREELINK', // GenoPro
410356588a1SGreg Roach        'SOCIALRELATIONSHIP', // GenoPro
411356588a1SGreg Roach        '_EVDEF', // RootsMagic
412356588a1SGreg Roach        '_EVENT_DEFN', // PAF and Legacy
413356588a1SGreg Roach        '_HASHTAG_DEFN', // Legacy
41454671e98SGreg Roach        '_PUBLISH', // MyHeritage
4150e542193SGreg Roach        '_TASK', // Ages
416356588a1SGreg Roach        '_TODO', // Legacy
417356588a1SGreg Roach    ];
418356588a1SGreg Roach
41900c92694SGreg Roach    /**
42000c92694SGreg Roach     * Definitions for GEDCOM 5.5.1.
42100c92694SGreg Roach     *
42200c92694SGreg Roach     * @return array<string,ElementInterface>
42300c92694SGreg Roach     */
42400c92694SGreg Roach    private function gedcom551Tags(): array
42500c92694SGreg Roach    {
42600c92694SGreg Roach        return [
42700c92694SGreg Roach            'FAM'                        => new FamilyRecord(I18N::translate('Family')),
42800c92694SGreg Roach            'FAM:*:ADDR'                 => new AddressLine(I18N::translate('Address')),
42900c92694SGreg Roach            'FAM:*:ADDR:ADR1'            => new AddressLine1(I18N::translate('Address line 1')),
43000c92694SGreg Roach            'FAM:*:ADDR:ADR2'            => new AddressLine2(I18N::translate('Address line 2')),
43100c92694SGreg Roach            'FAM:*:ADDR:ADR3'            => new AddressLine3(I18N::translate('Address line 3')),
43200c92694SGreg Roach            'FAM:*:ADDR:CITY'            => new AddressCity(I18N::translate('City')),
43300c92694SGreg Roach            'FAM:*:ADDR:CTRY'            => new AddressCountry(I18N::translate('Country')),
43400c92694SGreg Roach            'FAM:*:ADDR:POST'            => new AddressPostalCode(I18N::translate('Postal code')),
43500c92694SGreg Roach            'FAM:*:ADDR:STAE'            => new AddressState(I18N::translate('State')),
43600c92694SGreg Roach            'FAM:*:AGNC'                 => new ResponsibleAgency(I18N::translate('Agency')),
43700c92694SGreg Roach            'FAM:*:CAUS'                 => new CauseOfEvent(I18N::translate('Cause')),
43800c92694SGreg Roach            'FAM:*:DATE'                 => new DateValue(I18N::translate('Date')),
43900c92694SGreg Roach            'FAM:*:EMAIL'                => new AddressEmail(I18N::translate('Email address')),
44000c92694SGreg Roach            'FAM:*:FAX'                  => new AddressFax(I18N::translate('Fax')),
44100c92694SGreg Roach            'FAM:*:HUSB'                 => new EmptyElement(I18N::translate('Husband'), ['AGE' => '0:1']),
44200c92694SGreg Roach            'FAM:*:HUSB:AGE'             => new AgeAtEvent(I18N::translate('Husband’s age')),
44300c92694SGreg Roach            'FAM:*:NOTE'                 => new NoteStructure(I18N::translate('Note')),
44400c92694SGreg Roach            'FAM:*:OBJE'                 => new XrefMedia(I18N::translate('Media object')),
44500c92694SGreg Roach            'FAM:*:PHON'                 => new PhoneNumber(I18N::translate('Phone')),
44600c92694SGreg Roach            'FAM:*:PLAC'                 => new PlaceName(I18N::translate('Place')),
44700c92694SGreg Roach            'FAM:*:PLAC:FONE'            => new PlacePhoneticVariation(I18N::translate('Phonetic place')),
44800c92694SGreg Roach            'FAM:*:PLAC:FONE:TYPE'       => new PhoneticType(I18N::translate('Type')),
44900c92694SGreg Roach            'FAM:*:PLAC:FORM'            => new PlaceHierarchy(I18N::translate('Format')),
45000c92694SGreg Roach            'FAM:*:PLAC:MAP'             => new Coordinates(I18N::translate('Coordinates')),
45100c92694SGreg Roach            'FAM:*:PLAC:MAP:LATI'        => new PlaceLatitude(I18N::translate('Latitude')),
45200c92694SGreg Roach            'FAM:*:PLAC:MAP:LONG'        => new PlaceLongtitude(I18N::translate('Longitude')),
453d64c51bcSGreg Roach            'FAM:*:PLAC:NOTE'            => new NoteStructure(I18N::translate('Note on place')),
45400c92694SGreg Roach            'FAM:*:PLAC:ROMN'            => new PlaceRomanizedVariation(I18N::translate('Romanized place')),
45500c92694SGreg Roach            'FAM:*:PLAC:ROMN:TYPE'       => new RomanizedType(I18N::translate('Type')),
45600c92694SGreg Roach            'FAM:*:RELI'                 => new ReligiousAffiliation(I18N::translate('Religion'), []),
45700c92694SGreg Roach            'FAM:*:RESN'                 => new RestrictionNotice(I18N::translate('Restriction')),
45800c92694SGreg Roach            'FAM:*:SOUR'                 => new XrefSource(I18N::translate('Source citation')),
45900c92694SGreg Roach            'FAM:*:SOUR:DATA'            => new SourceData(I18N::translate('Data')),
460352bd396SGreg Roach            'FAM:*:SOUR:DATA:DATE'       => new DateValue(I18N::translate('Date of entry in original source')),
46100c92694SGreg Roach            'FAM:*:SOUR:DATA:TEXT'       => new TextFromSource(I18N::translate('Text')),
46200c92694SGreg Roach            'FAM:*:SOUR:EVEN'            => new EventTypeCitedFrom(I18N::translate('Event')),
46300c92694SGreg Roach            'FAM:*:SOUR:EVEN:ROLE'       => new RoleInEvent(I18N::translate('Role')),
464d64c51bcSGreg Roach            'FAM:*:SOUR:NOTE'            => new NoteStructure(I18N::translate('Note on source citation')),
46500c92694SGreg Roach            'FAM:*:SOUR:OBJE'            => new XrefMedia(I18N::translate('Media object')),
46600c92694SGreg Roach            'FAM:*:SOUR:PAGE'            => new WhereWithinSource(I18N::translate('Citation details')),
46700c92694SGreg Roach            'FAM:*:SOUR:QUAY'            => new CertaintyAssessment(I18N::translate('Quality of data')),
46800c92694SGreg Roach            'FAM:*:TYPE'                 => new EventOrFactClassification(I18N::translate('Type')),
46900c92694SGreg Roach            'FAM:*:WIFE'                 => new EmptyElement(I18N::translate('Wife'), ['AGE' => '0:1']),
47000c92694SGreg Roach            'FAM:*:WIFE:AGE'             => new AgeAtEvent(I18N::translate('Wife’s age')),
47100c92694SGreg Roach            'FAM:*:WWW'                  => new AddressWebPage(I18N::translate('URL')),
47200c92694SGreg Roach            'FAM:ANUL'                   => new Annulment(I18N::translate('Annulment')),
47300c92694SGreg Roach            'FAM:CENS'                   => new FamilyCensus(I18N::translate('Family census')),
47400c92694SGreg Roach            'FAM:CHAN'                   => new Change(I18N::translate('Last change')),
47500c92694SGreg Roach            'FAM:CHAN:DATE'              => new ChangeDate(I18N::translate('Date of last change')),
476099c152eSGreg Roach            'FAM:CHAN:DATE:TIME'         => new TimeValueNow(I18N::translate('Time of last change')),
477d64c51bcSGreg Roach            'FAM:CHAN:NOTE'              => new NoteStructure(I18N::translate('Note on last change')),
47800c92694SGreg Roach            'FAM:CHIL'                   => new XrefIndividual(I18N::translate('Child')),
47900c92694SGreg Roach            'FAM:DIV'                    => new Divorce(I18N::translate('Divorce')),
48000c92694SGreg Roach            'FAM:DIV:DATE'               => new DateValue(I18N::translate('Date of divorce')),
48100c92694SGreg Roach            'FAM:DIVF'                   => new DivorceFiled(I18N::translate('Divorce filed')),
48200c92694SGreg Roach            'FAM:ENGA'                   => new Engagement(I18N::translate('Engagement')),
48300c92694SGreg Roach            'FAM:ENGA:DATE'              => new DateValue(I18N::translate('Date of engagement')),
48400c92694SGreg Roach            'FAM:ENGA:PLAC'              => new PlaceName(I18N::translate('Place of engagement')),
4855d2c6313SGreg Roach            'FAM:EVEN'                   => new FamilyEvent(I18N::translate('Event')),
4865d2c6313SGreg Roach            'FAM:EVEN:TYPE'              => new EventOrFactClassification(I18N::translate('Type of event')),
48700c92694SGreg Roach            'FAM:HUSB'                   => new XrefIndividual(I18N::translate('Husband')),
48800c92694SGreg Roach            'FAM:MARB'                   => new MarriageBanns(I18N::translate('Marriage banns')),
48900c92694SGreg Roach            'FAM:MARB:DATE'              => new DateValue(I18N::translate('Date of marriage banns')),
49000c92694SGreg Roach            'FAM:MARB:PLAC'              => new PlaceName(I18N::translate('Place of marriage banns')),
49100c92694SGreg Roach            'FAM:MARC'                   => new MarriageContract(I18N::translate('Marriage contract')),
49200c92694SGreg Roach            'FAM:MARL'                   => new MarriageLicence(I18N::translate('Marriage license')),
49300c92694SGreg Roach            'FAM:MARR'                   => new Marriage(I18N::translate('Marriage')),
49400c92694SGreg Roach            'FAM:MARR:DATE'              => new DateValue(I18N::translate('Date of marriage')),
49500c92694SGreg Roach            'FAM:MARR:PLAC'              => new PlaceName(I18N::translate('Place of marriage')),
49600c92694SGreg Roach            'FAM:MARR:TYPE'              => new MarriageType(I18N::translate('Type of marriage')),
49700c92694SGreg Roach            'FAM:MARS'                   => new MarriageSettlement(I18N::translate('Marriage settlement')),
49800c92694SGreg Roach            'FAM:NCHI'                   => new CountOfChildren(I18N::translate('Number of children')),
49900c92694SGreg Roach            'FAM:NOTE'                   => new NoteStructure(I18N::translate('Note')),
50000c92694SGreg Roach            'FAM:OBJE'                   => new XrefMedia(I18N::translate('Media object')),
50100c92694SGreg Roach            'FAM:REFN'                   => new UserReferenceNumber(I18N::translate('Reference number')),
50200c92694SGreg Roach            'FAM:REFN:TYPE'              => new UserReferenceType(I18N::translate('Type of reference number')),
50300c92694SGreg Roach            'FAM:RESI'                   => new FamilyResidence(I18N::translate('Family residence')),
50400c92694SGreg Roach            'FAM:RESN'                   => new RestrictionNotice(I18N::translate('Restriction')),
50500c92694SGreg Roach            'FAM:RIN'                    => new AutomatedRecordId(I18N::translate('Record ID number')),
50600c92694SGreg Roach            'FAM:SLGS'                   => new LdsSpouseSealing(I18N::translate('LDS spouse sealing')),
50700c92694SGreg Roach            'FAM:SLGS:DATE'              => new DateLdsOrd(I18N::translate('Date of LDS spouse sealing')),
50800c92694SGreg Roach            'FAM:SLGS:PLAC'              => new PlaceLivingOrdinance(I18N::translate('Place of LDS spouse sealing')),
50900c92694SGreg Roach            'FAM:SLGS:STAT'              => new LdsSpouseSealingDateStatus(I18N::translate('Status')),
510099c152eSGreg Roach            'FAM:SLGS:STAT:DATE'         => new DateValueExact(I18N::translate('Status change date')),
51100c92694SGreg Roach            'FAM:SLGS:TEMP'              => new TempleCode(I18N::translate('Temple')),
51200c92694SGreg Roach            'FAM:SOUR'                   => new XrefSource(I18N::translate('Source citation')),
51300c92694SGreg Roach            'FAM:SOUR:DATA'              => new SourceData(I18N::translate('Data')),
514352bd396SGreg Roach            'FAM:SOUR:DATA:DATE'         => new DateValue(I18N::translate('Date of entry in original source')),
51500c92694SGreg Roach            'FAM:SOUR:DATA:TEXT'         => new TextFromSource(I18N::translate('Text')),
51600c92694SGreg Roach            'FAM:SOUR:EVEN'              => new EventTypeCitedFrom(I18N::translate('Event')),
51700c92694SGreg Roach            'FAM:SOUR:EVEN:ROLE'         => new RoleInEvent(I18N::translate('Role')),
518d64c51bcSGreg Roach            'FAM:SOUR:NOTE'              => new NoteStructure(I18N::translate('Note on source citation')),
51900c92694SGreg Roach            'FAM:SOUR:OBJE'              => new XrefMedia(I18N::translate('Media object')),
52000c92694SGreg Roach            'FAM:SOUR:PAGE'              => new WhereWithinSource(I18N::translate('Citation details')),
52100c92694SGreg Roach            'FAM:SOUR:QUAY'              => new CertaintyAssessment(I18N::translate('Quality of data')),
52200c92694SGreg Roach            'FAM:SUBM'                   => new XrefSubmitter(I18N::translate('Submitter')),
52300c92694SGreg Roach            'FAM:WIFE'                   => new XrefIndividual(I18N::translate('Wife')),
52400c92694SGreg Roach            'HEAD'                       => new HeaderRecord(I18N::translate('Header')),
52500c92694SGreg Roach            'HEAD:CHAR'                  => new CharacterSet(I18N::translate('Character set')),
52600c92694SGreg Roach            'HEAD:CHAR:VERS'             => new VersionNumber(I18N::translate('Version')),
52700c92694SGreg Roach            'HEAD:COPR'                  => new CopyrightFile(I18N::translate('Copyright')),
52800c92694SGreg Roach            'HEAD:DATE'                  => new TransmissionDate(I18N::translate('Date')),
529099c152eSGreg Roach            'HEAD:DATE:TIME'             => new TimeValueNow(I18N::translate('Time')),
53000c92694SGreg Roach            'HEAD:DEST'                  => new ReceivingSystemName(I18N::translate('Destination')),
53100c92694SGreg Roach            'HEAD:FILE'                  => new FileName(I18N::translate('Filename')),
53200c92694SGreg Roach            'HEAD:GEDC'                  => new GedcomElement(I18N::translate('GEDCOM')),
53300c92694SGreg Roach            'HEAD:GEDC:FORM'             => new Form(I18N::translate('Format')),
53400c92694SGreg Roach            'HEAD:GEDC:VERS'             => new VersionNumber(I18N::translate('Version')),
53500c92694SGreg Roach            'HEAD:LANG'                  => new LanguageId(I18N::translate('Language')),
53600c92694SGreg Roach            'HEAD:NOTE'                  => new ContentDescription(I18N::translate('Note')),
53700c92694SGreg Roach            'HEAD:PLAC'                  => new EmptyElement(I18N::translate('Place hierarchy'), ['FORM' => '1:1']),
53800c92694SGreg Roach            'HEAD:PLAC:FORM'             => new PlaceHierarchy(I18N::translate('Format')),
5394c10b11dSGreg Roach            'HEAD:SOUR'                  => new ApprovedSystemId(I18N::translate('Application ID')),
54000c92694SGreg Roach            'HEAD:SOUR:CORP'             => new NameOfBusiness(I18N::translate('Corporation')),
54100c92694SGreg Roach            'HEAD:SOUR:CORP:ADDR'        => new AddressLine(I18N::translate('Address')),
54200c92694SGreg Roach            'HEAD:SOUR:CORP:ADDR:ADR1'   => new AddressLine1(I18N::translate('Address line 1')),
54300c92694SGreg Roach            'HEAD:SOUR:CORP:ADDR:ADR2'   => new AddressLine2(I18N::translate('Address line 2')),
54400c92694SGreg Roach            'HEAD:SOUR:CORP:ADDR:ADR3'   => new AddressLine3(I18N::translate('Address line 3')),
54500c92694SGreg Roach            'HEAD:SOUR:CORP:ADDR:CITY'   => new AddressCity(I18N::translate('City')),
54600c92694SGreg Roach            'HEAD:SOUR:CORP:ADDR:CTRY'   => new AddressCountry(I18N::translate('Country')),
54700c92694SGreg Roach            'HEAD:SOUR:CORP:ADDR:POST'   => new AddressPostalCode(I18N::translate('Postal code')),
54800c92694SGreg Roach            'HEAD:SOUR:CORP:ADDR:STAE'   => new AddressState(I18N::translate('State')),
54900c92694SGreg Roach            'HEAD:SOUR:CORP:EMAIL'       => new AddressEmail(I18N::translate('Email address')),
55000c92694SGreg Roach            'HEAD:SOUR:CORP:FAX'         => new AddressFax(I18N::translate('Fax')),
55100c92694SGreg Roach            'HEAD:SOUR:CORP:PHON'        => new PhoneNumber(I18N::translate('Phone')),
55200c92694SGreg Roach            'HEAD:SOUR:CORP:WWW'         => new AddressWebPage(I18N::translate('URL')),
5534c10b11dSGreg Roach            'HEAD:SOUR:DATA'             => new NameOfSourceData(I18N::translate('Data')),
55400c92694SGreg Roach            'HEAD:SOUR:DATA:COPR'        => new CopyrightSourceData(I18N::translate('Copyright')),
55500c92694SGreg Roach            'HEAD:SOUR:DATA:DATE'        => new PublicationDate(I18N::translate('Date')),
5564c10b11dSGreg Roach            'HEAD:SOUR:NAME'             => new NameOfProduct(I18N::translate('Application name')),
55700c92694SGreg Roach            'HEAD:SOUR:VERS'             => new VersionNumber(I18N::translate('Version')),
55800c92694SGreg Roach            'HEAD:SUBM'                  => new XrefSubmitter(I18N::translate('Submitter')),
55900c92694SGreg Roach            'HEAD:SUBN'                  => new XrefSubmission(I18N::translate('Submission')),
56000c92694SGreg Roach            'INDI'                       => new IndividualRecord(I18N::translate('Individual')),
56100c92694SGreg Roach            'INDI:*:ADDR'                => new AddressLine(I18N::translate('Address')),
56200c92694SGreg Roach            'INDI:*:ADDR:ADR1'           => new AddressLine1(I18N::translate('Address line 1')),
56300c92694SGreg Roach            'INDI:*:ADDR:ADR2'           => new AddressLine2(I18N::translate('Address line 2')),
56400c92694SGreg Roach            'INDI:*:ADDR:ADR3'           => new AddressLine3(I18N::translate('Address line 3')),
56500c92694SGreg Roach            'INDI:*:ADDR:CITY'           => new AddressCity(I18N::translate('City')),
56600c92694SGreg Roach            'INDI:*:ADDR:CTRY'           => new AddressCountry(I18N::translate('Country')),
56700c92694SGreg Roach            'INDI:*:ADDR:POST'           => new AddressPostalCode(I18N::translate('Postal code')),
56800c92694SGreg Roach            'INDI:*:ADDR:STAE'           => new AddressState(I18N::translate('State')),
56900c92694SGreg Roach            'INDI:*:AGE'                 => new AgeAtEvent(I18N::translate('Age')),
57000c92694SGreg Roach            'INDI:*:AGNC'                => new ResponsibleAgency(I18N::translate('Agency')),
57100c92694SGreg Roach            'INDI:*:CAUS'                => new CauseOfEvent(I18N::translate('Cause')),
57200c92694SGreg Roach            'INDI:*:DATE'                => new DateValue(I18N::translate('Date')),
57300c92694SGreg Roach            'INDI:*:EMAIL'               => new AddressEmail(I18N::translate('Email address')),
57400c92694SGreg Roach            'INDI:*:FAX'                 => new AddressFax(I18N::translate('Fax')),
57500c92694SGreg Roach            'INDI:*:NOTE'                => new NoteStructure(I18N::translate('Note')),
57600c92694SGreg Roach            'INDI:*:OBJE'                => new XrefMedia(I18N::translate('Media object')),
57700c92694SGreg Roach            'INDI:*:PHON'                => new PhoneNumber(I18N::translate('Phone')),
57800c92694SGreg Roach            'INDI:*:PLAC'                => new PlaceName(I18N::translate('Place')),
57900c92694SGreg Roach            'INDI:*:PLAC:FONE'           => new PlacePhoneticVariation(I18N::translate('Phonetic place')),
58000c92694SGreg Roach            'INDI:*:PLAC:FONE:TYPE'      => new PhoneticType(I18N::translate('Type')),
58100c92694SGreg Roach            'INDI:*:PLAC:FORM'           => new PlaceHierarchy(I18N::translate('Format')),
58200c92694SGreg Roach            'INDI:*:PLAC:MAP'            => new Coordinates(I18N::translate('Coordinates')),
58300c92694SGreg Roach            'INDI:*:PLAC:MAP:LATI'       => new PlaceLatitude(I18N::translate('Latitude')),
58400c92694SGreg Roach            'INDI:*:PLAC:MAP:LONG'       => new PlaceLongtitude(I18N::translate('Longitude')),
585d64c51bcSGreg Roach            'INDI:*:PLAC:NOTE'           => new NoteStructure(I18N::translate('Note on place')),
58600c92694SGreg Roach            'INDI:*:PLAC:ROMN'           => new PlaceRomanizedVariation(I18N::translate('Romanized place')),
58700c92694SGreg Roach            'INDI:*:PLAC:ROMN:TYPE'      => new RomanizedType(I18N::translate('Type')),
58800c92694SGreg Roach            'INDI:*:RELI'                => new ReligiousAffiliation(I18N::translate('Religion'), []),
58900c92694SGreg Roach            'INDI:*:RESN'                => new RestrictionNotice(I18N::translate('Restriction')),
59000c92694SGreg Roach            'INDI:*:SOUR'                => new XrefSource(I18N::translate('Source citation')),
59100c92694SGreg Roach            'INDI:*:SOUR:DATA'           => new SourceData(I18N::translate('Data')),
592352bd396SGreg Roach            'INDI:*:SOUR:DATA:DATE'      => new DateValue(I18N::translate('Date of entry in original source')),
59300c92694SGreg Roach            'INDI:*:SOUR:DATA:TEXT'      => new TextFromSource(I18N::translate('Text')),
59400c92694SGreg Roach            'INDI:*:SOUR:EVEN'           => new EventTypeCitedFrom(I18N::translate('Event')),
59500c92694SGreg Roach            'INDI:*:SOUR:EVEN:ROLE'      => new RoleInEvent(I18N::translate('Role')),
596d64c51bcSGreg Roach            'INDI:*:SOUR:NOTE'           => new NoteStructure(I18N::translate('Note on source citation')),
59700c92694SGreg Roach            'INDI:*:SOUR:OBJE'           => new XrefMedia(I18N::translate('Media object')),
59800c92694SGreg Roach            'INDI:*:SOUR:PAGE'           => new WhereWithinSource(I18N::translate('Citation details')),
59900c92694SGreg Roach            'INDI:*:SOUR:QUAY'           => new CertaintyAssessment(I18N::translate('Quality of data')),
60000c92694SGreg Roach            'INDI:*:TYPE'                => new EventOrFactClassification(I18N::translate('Type')),
60100c92694SGreg Roach            'INDI:*:WWW'                 => new AddressWebPage(I18N::translate('URL')),
60200c92694SGreg Roach            'INDI:ADOP'                  => new Adoption(I18N::translate('Adoption')),
60300c92694SGreg Roach            'INDI:ADOP:DATE'             => new DateValue(I18N::translate('Date of adoption')),
60400c92694SGreg Roach            'INDI:ADOP:FAMC'             => new XrefFamily(I18N::translate('Adoptive parents')),
60500c92694SGreg Roach            'INDI:ADOP:FAMC:ADOP'        => new AdoptedByWhichParent(I18N::translate('Adoption')),
60600c92694SGreg Roach            'INDI:ADOP:PLAC'             => new PlaceName(I18N::translate('Place of adoption')),
60700c92694SGreg Roach            'INDI:AFN'                   => new AncestralFileNumber(I18N::translate('Ancestral file number')),
60800c92694SGreg Roach            'INDI:ALIA'                  => new XrefIndividual(I18N::translate('Alias')),
60900c92694SGreg Roach            'INDI:ANCI'                  => new XrefSubmitter(I18N::translate('Ancestors interest')),
61000c92694SGreg Roach            'INDI:ASSO'                  => new XrefAssociate(I18N::translate('Associate')),
61100c92694SGreg Roach            'INDI:ASSO:RELA'             => new RelationIsDescriptor(I18N::translate('Relationship')),
61200c92694SGreg Roach            'INDI:BAPL'                  => new LdsBaptism(I18N::translate('LDS baptism')),
61300c92694SGreg Roach            'INDI:BAPL:DATE'             => new DateLdsOrd(I18N::translate('Date of LDS baptism')),
61400c92694SGreg Roach            'INDI:BAPL:PLAC'             => new PlaceLivingOrdinance(I18N::translate('Place of LDS baptism')),
61500c92694SGreg Roach            'INDI:BAPL:STAT'             => new LdsBaptismDateStatus(I18N::translate('Status')),
616099c152eSGreg Roach            'INDI:BAPL:STAT:DATE'        => new DateValueExact(I18N::translate('Status change date')),
61700c92694SGreg Roach            'INDI:BAPL:TEMP'             => new TempleCode(I18N::translate('Temple')),
61800c92694SGreg Roach            'INDI:BAPM'                  => new Baptism(I18N::translate('Baptism')),
61900c92694SGreg Roach            'INDI:BAPM:DATE'             => new DateValue(I18N::translate('Date of baptism')),
62000c92694SGreg Roach            'INDI:BAPM:PLAC'             => new PlaceName(I18N::translate('Place of baptism')),
62100c92694SGreg Roach            'INDI:BARM'                  => new BarMitzvah(I18N::translate('Bar mitzvah')),
62200c92694SGreg Roach            'INDI:BARM:DATE'             => new DateValue(I18N::translate('Date of bar mitzvah')),
62300c92694SGreg Roach            'INDI:BARM:PLAC'             => new PlaceName(I18N::translate('Place of bar mitzvah')),
62400c92694SGreg Roach            'INDI:BASM'                  => new BasMitzvah(I18N::translate('Bat mitzvah')),
62500c92694SGreg Roach            'INDI:BASM:DATE'             => new BasMitzvah(I18N::translate('Date of bat mitzvah')),
62600c92694SGreg Roach            'INDI:BASM:PLAC'             => new DateValue(I18N::translate('Place of bat mitzvah')),
62700c92694SGreg Roach            'INDI:BIRT'                  => new Birth(I18N::translate('Birth')),
62800c92694SGreg Roach            'INDI:BIRT:DATE'             => new DateValue(I18N::translate('Date of birth')),
62900c92694SGreg Roach            'INDI:BIRT:FAMC'             => new XrefFamily(I18N::translate('Birth parents')),
63000c92694SGreg Roach            'INDI:BIRT:PLAC'             => new PlaceName(I18N::translate('Place of birth')),
63100c92694SGreg Roach            'INDI:BLES'                  => new Blessing(I18N::translate('Blessing')),
63200c92694SGreg Roach            'INDI:BLES:DATE'             => new DateValue(I18N::translate('Date of blessing')),
63300c92694SGreg Roach            'INDI:BLES:PLAC'             => new PlaceName(I18N::translate('Place of blessing')),
63400c92694SGreg Roach            'INDI:BURI'                  => new Burial(I18N::translate('Burial')),
63500c92694SGreg Roach            'INDI:BURI:DATE'             => new DateValue(I18N::translate('Date of burial')),
63600c92694SGreg Roach            'INDI:BURI:PLAC'             => new PlaceName(I18N::translate('Place of burial')),
63700c92694SGreg Roach            'INDI:CAST'                  => new CasteName(I18N::translate('Caste')),
63800c92694SGreg Roach            'INDI:CENS'                  => new Census(I18N::translate('Census')),
63900c92694SGreg Roach            'INDI:CENS:DATE'             => new DateValue(I18N::translate('Census date')),
64000c92694SGreg Roach            'INDI:CENS:PLAC'             => new PlaceName(I18N::translate('Census place')),
64100c92694SGreg Roach            'INDI:CHAN'                  => new Change(I18N::translate('Last change')),
64200c92694SGreg Roach            'INDI:CHAN:DATE'             => new ChangeDate(I18N::translate('Date of last change')),
643099c152eSGreg Roach            'INDI:CHAN:DATE:TIME'        => new TimeValueNow(I18N::translate('Time of last change')),
644d64c51bcSGreg Roach            'INDI:CHAN:NOTE'             => new NoteStructure(I18N::translate('Note on last change')),
64500c92694SGreg Roach            'INDI:CHR'                   => new Christening(I18N::translate('Christening')),
64600c92694SGreg Roach            'INDI:CHR:DATE'              => new DateValue(I18N::translate('Date of christening')),
64700c92694SGreg Roach            'INDI:CHR:FAMC'              => new XrefFamily(I18N::translate('Godparents')),
64800c92694SGreg Roach            'INDI:CHR:PLAC'              => new PlaceName(I18N::translate('Place of christening')),
64900c92694SGreg Roach            'INDI:CHRA'                  => new AdultChristening(I18N::translate('Adult christening')),
65000c92694SGreg Roach            'INDI:CHRA:PLAC'             => new PlaceName(I18N::translate('Place of christening')),
65100c92694SGreg Roach            'INDI:CONF'                  => new Confirmation(I18N::translate('Confirmation')),
65200c92694SGreg Roach            'INDI:CONF:DATE'             => new DateValue(I18N::translate('Date of confirmation')),
65300c92694SGreg Roach            'INDI:CONF:PLAC'             => new PlaceName(I18N::translate('Place of confirmation')),
65400c92694SGreg Roach            'INDI:CONL'                  => new LdsConfirmation(I18N::translate('LDS confirmation')),
65500c92694SGreg Roach            'INDI:CONL:DATE'             => new DateLdsOrd(I18N::translate('Date of LDS confirmation')),
65600c92694SGreg Roach            'INDI:CONL:PLAC'             => new PlaceLivingOrdinance(I18N::translate('Place of LDS confirmation')),
657701f5d18SGreg Roach            'INDI:CONL:STAT'             => new LdsBaptismDateStatus(I18N::translate('Status')),
658099c152eSGreg Roach            'INDI:CONL:STAT:DATE'        => new DateValueExact(I18N::translate('Status change date')),
65900c92694SGreg Roach            'INDI:CONL:TEMP'             => new TempleCode(I18N::translate('Temple')),
66000c92694SGreg Roach            'INDI:CREM'                  => new Cremation(I18N::translate('Cremation')),
66100c92694SGreg Roach            'INDI:CREM:DATE'             => new DateValue(I18N::translate('Date of cremation')),
66200c92694SGreg Roach            'INDI:CREM:PLAC'             => new PlaceName(I18N::translate('Place of cremation')),
66300c92694SGreg Roach            'INDI:DEAT'                  => new Death(I18N::translate('Death')),
66400c92694SGreg Roach            'INDI:DEAT:CAUS'             => new CauseOfEvent(I18N::translate('Cause of death')),
66500c92694SGreg Roach            'INDI:DEAT:DATE'             => new DateValue(I18N::translate('Date of death')),
66600c92694SGreg Roach            'INDI:DEAT:PLAC'             => new PlaceName(I18N::translate('Place of death')),
66700c92694SGreg Roach            'INDI:DESI'                  => new XrefSubmitter(I18N::translate('Descendants interest')),
66800c92694SGreg Roach            'INDI:DSCR'                  => new PhysicalDescription(I18N::translate('Description')),
66900c92694SGreg Roach            'INDI:EDUC'                  => new ScholasticAchievement(I18N::translate('Education')),
67000c92694SGreg Roach            'INDI:EDUC:AGNC'             => new ResponsibleAgency(I18N::translate('School or college')),
67100c92694SGreg Roach            'INDI:EMIG'                  => new Emigration(I18N::translate('Emigration')),
67200c92694SGreg Roach            'INDI:EMIG:DATE'             => new DateValue(I18N::translate('Date of emigration')),
67300c92694SGreg Roach            'INDI:EMIG:PLAC'             => new PlaceName(I18N::translate('Place of emigration')),
67400c92694SGreg Roach            'INDI:ENDL'                  => new LdsEndowment(I18N::translate('LDS endowment')),
67500c92694SGreg Roach            'INDI:ENDL:DATE'             => new DateLdsOrd(I18N::translate('Date of LDS endowment')),
67600c92694SGreg Roach            'INDI:ENDL:PLAC'             => new PlaceLivingOrdinance(I18N::translate('Place of LDS endowment')),
67700c92694SGreg Roach            'INDI:ENDL:STAT'             => new LdsEndowmentDateStatus(I18N::translate('Status')),
678099c152eSGreg Roach            'INDI:ENDL:STAT:DATE'        => new DateValueExact(I18N::translate('Status change date')),
67900c92694SGreg Roach            'INDI:ENDL:TEMP'             => new TempleCode(I18N::translate('Temple')),
6805d2c6313SGreg Roach            'INDI:EVEN'                  => new IndividualEvent(I18N::translate('Event')),
68100c92694SGreg Roach            'INDI:EVEN:DATE'             => new DateValue(I18N::translate('Date of event')),
68200c92694SGreg Roach            'INDI:EVEN:PLAC'             => new PlaceName(I18N::translate('Place of event')),
6835d2c6313SGreg Roach            'INDI:EVEN:TYPE'             => new EventOrFactClassification(I18N::translate('Type of event')),
6845d2c6313SGreg Roach            'INDI:FACT'                  => new IndividualFact(I18N::translate('Fact')),
6855d2c6313SGreg Roach            'INDI:FACT:TYPE'             => new EventOrFactClassification(I18N::translate('Type of fact')),
68600c92694SGreg Roach            'INDI:FAMC'                  => new XrefFamily(I18N::translate('Family as a child'), ['NOTE' => '0:1', 'PEDI' => '0:1', 'STAT' => '0:1']),
68700c92694SGreg Roach            'INDI:FAMC:PEDI'             => new PedigreeLinkageType(I18N::translate('Relationship to parents')),
68800c92694SGreg Roach            'INDI:FAMC:STAT'             => new ChildLinkageStatus(I18N::translate('Status')),
68900c92694SGreg Roach            'INDI:FAMS'                  => new XrefFamily(I18N::translate('Family as a spouse')),
69000c92694SGreg Roach            'INDI:FCOM'                  => new FirstCommunion(I18N::translate('First communion')),
69100c92694SGreg Roach            'INDI:FCOM:DATE'             => new DateValue(I18N::translate('Date of first communion')),
69200c92694SGreg Roach            'INDI:FCOM:PLAC'             => new PlaceName(I18N::translate('Place of first communion')),
69300c92694SGreg Roach            'INDI:GRAD'                  => new Graduation(I18N::translate('Graduation')),
69400c92694SGreg Roach            'INDI:GRAD:AGNC'             => new ResponsibleAgency(I18N::translate('School or college')),
69500c92694SGreg Roach            'INDI:IDNO'                  => new NationalIdNumber(I18N::translate('Identification number')),
6965d2c6313SGreg Roach            'INDI:IDNO:TYPE'             => new EventOrFactClassification(I18N::translate('Type of identification number')),
69700c92694SGreg Roach            'INDI:IMMI'                  => new Immigration(I18N::translate('Immigration')),
69800c92694SGreg Roach            'INDI:IMMI:DATE'             => new DateValue(I18N::translate('Date of immigration')),
69900c92694SGreg Roach            'INDI:IMMI:PLAC'             => new PlaceName(I18N::translate('Place of immigration')),
70000c92694SGreg Roach            'INDI:NAME'                  => new NamePersonal(I18N::translate('Name')),
70103c55594SGreg Roach            'INDI:NAME:*:SOUR'           => new XrefSource(I18N::translate('Source citation')),
70203c55594SGreg Roach            'INDI:NAME:*:SOUR:DATA'      => new SourceData(I18N::translate('Data')),
70303c55594SGreg Roach            'INDI:NAME:*:SOUR:DATA:DATE' => new DateValue(I18N::translate('Date of entry in original source')),
70403c55594SGreg Roach            'INDI:NAME:*:SOUR:DATA:TEXT' => new TextFromSource(I18N::translate('Text')),
70503c55594SGreg Roach            'INDI:NAME:*:SOUR:EVEN'      => new EventTypeCitedFrom(I18N::translate('Event')),
70603c55594SGreg Roach            'INDI:NAME:*:SOUR:EVEN:ROLE' => new RoleInEvent(I18N::translate('Role')),
707d64c51bcSGreg Roach            'INDI:NAME:*:SOUR:NOTE'      => new NoteStructure(I18N::translate('Note on source citation')),
70803c55594SGreg Roach            'INDI:NAME:*:SOUR:OBJE'      => new XrefMedia(I18N::translate('Media object')),
70903c55594SGreg Roach            'INDI:NAME:*:SOUR:PAGE'      => new WhereWithinSource(I18N::translate('Citation details')),
71003c55594SGreg Roach            'INDI:NAME:*:SOUR:QUAY'      => new CertaintyAssessment(I18N::translate('Quality of data')),
71100c92694SGreg Roach            'INDI:NAME:FONE'             => new NamePhoneticVariation(I18N::translate('Phonetic name')),
71200c92694SGreg Roach            'INDI:NAME:FONE:GIVN'        => new NamePieceGiven(I18N::translate('Given names')),
71300c92694SGreg Roach            'INDI:NAME:FONE:NICK'        => new NamePieceNickname(I18N::translate('Nickname')),
714d64c51bcSGreg Roach            'INDI:NAME:FONE:NOTE'        => new NoteStructure(I18N::translate('Note on phonetic name')),
71500c92694SGreg Roach            'INDI:NAME:FONE:NPFX'        => new NamePiecePrefix(I18N::translate('Name prefix')),
71600c92694SGreg Roach            'INDI:NAME:FONE:NSFX'        => new NamePieceSuffix(I18N::translate('Name suffix')),
71703c55594SGreg Roach            'INDI:NAME:FONE:SOUR'        => new XrefSource(I18N::translate('Source citation')),
71800c92694SGreg Roach            'INDI:NAME:FONE:SPFX'        => new NamePieceSurnamePrefix(I18N::translate('Surname prefix')),
71900c92694SGreg Roach            'INDI:NAME:FONE:SURN'        => new NamePieceSurname(I18N::translate('Surname')),
72000c92694SGreg Roach            'INDI:NAME:FONE:TYPE'        => new PhoneticType(I18N::translate('Phonetic type')),
72100c92694SGreg Roach            'INDI:NAME:GIVN'             => new NamePieceGiven(I18N::translate('Given names')),
72200c92694SGreg Roach            'INDI:NAME:NICK'             => new NamePieceNickname(I18N::translate('Nickname')),
72300c92694SGreg Roach            'INDI:NAME:NPFX'             => new NamePiecePrefix(I18N::translate('Name prefix')),
72400c92694SGreg Roach            'INDI:NAME:NSFX'             => new NamePieceSuffix(I18N::translate('Name suffix')),
72500c92694SGreg Roach            'INDI:NAME:ROMN'             => new NameRomanizedVariation(I18N::translate('Romanized name')),
72600c92694SGreg Roach            'INDI:NAME:ROMN:GIVN'        => new NamePieceGiven(I18N::translate('Given names')),
72700c92694SGreg Roach            'INDI:NAME:ROMN:NICK'        => new NamePieceNickname(I18N::translate('Nickname')),
728d64c51bcSGreg Roach            'INDI:NAME:ROMN:NOTE'        => new NoteStructure(I18N::translate('Note on romanized name')),
72900c92694SGreg Roach            'INDI:NAME:ROMN:NPFX'        => new NamePiecePrefix(I18N::translate('Name prefix')),
73000c92694SGreg Roach            'INDI:NAME:ROMN:NSFX'        => new NamePieceSuffix(I18N::translate('Name suffix')),
73103c55594SGreg Roach            'INDI:NAME:ROMN:SOUR'        => new XrefSource(I18N::translate('Source citation')),
73200c92694SGreg Roach            'INDI:NAME:ROMN:SPFX'        => new NamePieceSurnamePrefix(I18N::translate('Surname prefix')),
73300c92694SGreg Roach            'INDI:NAME:ROMN:SURN'        => new NamePieceSurname(I18N::translate('Surname')),
73400c92694SGreg Roach            'INDI:NAME:ROMN:TYPE'        => new RomanizedType(I18N::translate('Romanized type')),
73500c92694SGreg Roach            'INDI:NAME:SPFX'             => new NamePieceSurnamePrefix(I18N::translate('Surname prefix')),
73600c92694SGreg Roach            'INDI:NAME:SURN'             => new NamePieceSurname(I18N::translate('Surname')),
73700c92694SGreg Roach            'INDI:NAME:TYPE'             => new NameType(I18N::translate('Type of name')),
738f15544dcSGreg Roach            'INDI:NATI'                  => new NationalOrTribalOrigin(I18N::translate('Nationality')),
73900c92694SGreg Roach            'INDI:NATU'                  => new Naturalization(I18N::translate('Naturalization')),
74000c92694SGreg Roach            'INDI:NATU:DATE'             => new DateValue(I18N::translate('Date of naturalization')),
74100c92694SGreg Roach            'INDI:NATU:PLAC'             => new PlaceName(I18N::translate('Place of naturalization')),
74200c92694SGreg Roach            'INDI:NCHI'                  => new CountOfChildren(I18N::translate('Number of children')),
74300c92694SGreg Roach            'INDI:NMR'                   => new CountOfMarriages(I18N::translate('Number of marriages')),
74400c92694SGreg Roach            'INDI:NOTE'                  => new NoteStructure(I18N::translate('Note')),
74500c92694SGreg Roach            'INDI:OBJE'                  => new XrefMedia(I18N::translate('Media object')),
74600c92694SGreg Roach            'INDI:OCCU'                  => new Occupation(I18N::translate('Occupation')),
74700c92694SGreg Roach            'INDI:OCCU:AGNC'             => new ResponsibleAgency(I18N::translate('Employer')),
74800c92694SGreg Roach            'INDI:ORDN'                  => new Ordination(I18N::translate('Ordination')),
74900c92694SGreg Roach            'INDI:ORDN:AGNC'             => new Ordination(I18N::translate('Religious institution')),
75000c92694SGreg Roach            'INDI:ORDN:DATE'             => new Ordination(I18N::translate('Date of ordination')),
75100c92694SGreg Roach            'INDI:ORDN:PLAC'             => new Ordination(I18N::translate('Place of ordination')),
75200c92694SGreg Roach            'INDI:PROB'                  => new Probate(I18N::translate('Probate')),
75300c92694SGreg Roach            'INDI:PROP'                  => new Possessions(I18N::translate('Property')),
75400c92694SGreg Roach            'INDI:REFN'                  => new UserReferenceNumber(I18N::translate('Reference number')),
75500c92694SGreg Roach            'INDI:REFN:TYPE'             => new UserReferenceType(I18N::translate('Type of reference number')),
75600c92694SGreg Roach            'INDI:RELI'                  => new ReligiousAffiliation(I18N::translate('Religion')),
75700c92694SGreg Roach            'INDI:RESI'                  => new Residence(I18N::translate('Residence')),
75800c92694SGreg Roach            'INDI:RESI:DATE'             => new DateValue(I18N::translate('Date of residence')),
75900c92694SGreg Roach            'INDI:RESI:PLAC'             => new PlaceName(I18N::translate('Place of residence')),
76000c92694SGreg Roach            'INDI:RESN'                  => new RestrictionNotice(I18N::translate('Restriction')),
76100c92694SGreg Roach            'INDI:RETI'                  => new Retirement(I18N::translate('Retirement')),
76200c92694SGreg Roach            'INDI:RETI:AGNC'             => new ResponsibleAgency(I18N::translate('Employer')),
76300c92694SGreg Roach            'INDI:RFN'                   => new PermanentRecordFileNumber(I18N::translate('Record file number')),
76400c92694SGreg Roach            'INDI:RIN'                   => new AutomatedRecordId(I18N::translate('Record ID number')),
76500c92694SGreg Roach            'INDI:SEX'                   => new SexValue(I18N::translate('Gender')),
76600c92694SGreg Roach            'INDI:SLGC'                  => new LdsChildSealing(I18N::translate('LDS child sealing')),
76700c92694SGreg Roach            'INDI:SLGC:DATE'             => new DateLdsOrd(I18N::translate('Date of LDS child sealing')),
76800c92694SGreg Roach            'INDI:SLGC:FAMC'             => new XrefFamily(I18N::translate('Parents')),
76900c92694SGreg Roach            'INDI:SLGC:PLAC'             => new PlaceLivingOrdinance(I18N::translate('Place of LDS child sealing')),
77000c92694SGreg Roach            'INDI:SLGC:STAT'             => new LdsChildSealingDateStatus(I18N::translate('Status')),
771099c152eSGreg Roach            'INDI:SLGC:STAT:DATE'        => new DateValueExact(I18N::translate('Status change date')),
77200c92694SGreg Roach            'INDI:SLGC:TEMP'             => new TempleCode(I18N::translate('Temple')),
77300c92694SGreg Roach            'INDI:SOUR'                  => new XrefSource(I18N::translate('Source citation')),
77400c92694SGreg Roach            'INDI:SOUR:DATA'             => new SourceData(I18N::translate('Data')),
775352bd396SGreg Roach            'INDI:SOUR:DATA:DATE'        => new DateValue(I18N::translate('Date of entry in original source')),
77600c92694SGreg Roach            'INDI:SOUR:DATA:TEXT'        => new TextFromSource(I18N::translate('Text')),
77700c92694SGreg Roach            'INDI:SOUR:EVEN'             => new EventTypeCitedFrom(I18N::translate('Event')),
77800c92694SGreg Roach            'INDI:SOUR:EVEN:ROLE'        => new RoleInEvent(I18N::translate('Role')),
779d64c51bcSGreg Roach            'INDI:SOUR:NOTE'             => new NoteStructure(I18N::translate('Note on source citation')),
78000c92694SGreg Roach            'INDI:SOUR:OBJE'             => new XrefMedia(I18N::translate('Media object')),
78100c92694SGreg Roach            'INDI:SOUR:PAGE'             => new WhereWithinSource(I18N::translate('Citation details')),
78200c92694SGreg Roach            'INDI:SOUR:QUAY'             => new CertaintyAssessment(I18N::translate('Quality of data')),
78300c92694SGreg Roach            'INDI:SSN'                   => new SocialSecurityNumber(I18N::translate('Social security number')),
78400c92694SGreg Roach            'INDI:SUBM'                  => new XrefSubmitter(I18N::translate('Submitter')),
78500c92694SGreg Roach            'INDI:TITL'                  => new NobilityTypeTitle(I18N::translate('Title')),
78600c92694SGreg Roach            'INDI:WILL'                  => new Will(I18N::translate('Will')),
78700c92694SGreg Roach            'NOTE'                       => new NoteRecord(I18N::translate('Shared note')),
78800c92694SGreg Roach            'NOTE:CHAN'                  => new Change(I18N::translate('Last change')),
78900c92694SGreg Roach            'NOTE:CHAN:DATE'             => new ChangeDate(I18N::translate('Date of last change')),
790099c152eSGreg Roach            'NOTE:CHAN:DATE:TIME'        => new TimeValueNow(I18N::translate('Time of last change')),
791d64c51bcSGreg Roach            'NOTE:CHAN:NOTE'             => new NoteStructure(I18N::translate('Note on last change')),
79278c3bcf9SGreg Roach            'NOTE:CONC'                  => new SubmitterText(I18N::translate('Note')),
7936e233fa7SGreg Roach            'NOTE:CONT'                  => new SubmitterText(I18N::translate('Continuation')),
79400c92694SGreg Roach            'NOTE:REFN'                  => new UserReferenceNumber(I18N::translate('Reference number')),
79500c92694SGreg Roach            'NOTE:REFN:TYPE'             => new UserReferenceType(I18N::translate('Type of reference number')),
79600c92694SGreg Roach            'NOTE:RIN'                   => new AutomatedRecordId(I18N::translate('Record ID number')),
79700c92694SGreg Roach            'NOTE:SOUR'                  => new XrefSource(I18N::translate('Source citation')),
79800c92694SGreg Roach            'NOTE:SOUR:DATA'             => new SourceData(I18N::translate('Data')),
799352bd396SGreg Roach            'NOTE:SOUR:DATA:DATE'        => new DateValue(I18N::translate('Date of entry in original source')),
80000c92694SGreg Roach            'NOTE:SOUR:DATA:TEXT'        => new TextFromSource(I18N::translate('Text')),
80100c92694SGreg Roach            'NOTE:SOUR:EVEN'             => new EventTypeCitedFrom(I18N::translate('Event')),
80200c92694SGreg Roach            'NOTE:SOUR:EVEN:ROLE'        => new RoleInEvent(I18N::translate('Role')),
803d64c51bcSGreg Roach            'NOTE:SOUR:NOTE'             => new NoteStructure(I18N::translate('Note on source citation')),
80400c92694SGreg Roach            'NOTE:SOUR:OBJE'             => new XrefMedia(I18N::translate('Media object')),
80500c92694SGreg Roach            'NOTE:SOUR:PAGE'             => new WhereWithinSource(I18N::translate('Citation details')),
80600c92694SGreg Roach            'NOTE:SOUR:QUAY'             => new CertaintyAssessment(I18N::translate('Quality of data')),
80700c92694SGreg Roach            'OBJE'                       => new MediaRecord(I18N::translate('Media object')),
80800c92694SGreg Roach            'OBJE:BLOB'                  => new CustomElement(I18N::translate('Binary data object')),
80900c92694SGreg Roach            'OBJE:CHAN'                  => new Change(I18N::translate('Last change')),
81000c92694SGreg Roach            'OBJE:CHAN:DATE'             => new ChangeDate(I18N::translate('Date of last change')),
811099c152eSGreg Roach            'OBJE:CHAN:DATE:TIME'        => new TimeValueNow(I18N::translate('Time of last change')),
812d64c51bcSGreg Roach            'OBJE:CHAN:NOTE'             => new NoteStructure(I18N::translate('Note on last change')),
81300c92694SGreg Roach            'OBJE:FILE'                  => new MultimediaFileReference(I18N::translate('Filename')),
81400c92694SGreg Roach            'OBJE:FILE:FORM'             => new MultimediaFormat(I18N::translate('Format')),
81500c92694SGreg Roach            'OBJE:FILE:FORM:TYPE'        => new SourceMediaType(I18N::translate('Media type')),
81600c92694SGreg Roach            'OBJE:FILE:TITL'             => new DescriptiveTitle(I18N::translate('Title')),
81700c92694SGreg Roach            'OBJE:NOTE'                  => new NoteStructure(I18N::translate('Note')),
81800c92694SGreg Roach            'OBJE:REFN'                  => new UserReferenceNumber(I18N::translate('Reference number')),
81900c92694SGreg Roach            'OBJE:REFN:TYPE'             => new UserReferenceType(I18N::translate('Type of reference number')),
82000c92694SGreg Roach            'OBJE:RIN'                   => new AutomatedRecordId(I18N::translate('Record ID number')),
82100c92694SGreg Roach            'OBJE:SOUR'                  => new XrefSource(I18N::translate('Source citation')),
82200c92694SGreg Roach            'OBJE:SOUR:DATA'             => new SourceData(I18N::translate('Data')),
823352bd396SGreg Roach            'OBJE:SOUR:DATA:DATE'        => new DateValue(I18N::translate('Date of entry in original source')),
82400c92694SGreg Roach            'OBJE:SOUR:DATA:TEXT'        => new TextFromSource(I18N::translate('Text')),
82500c92694SGreg Roach            'OBJE:SOUR:EVEN'             => new EventTypeCitedFrom(I18N::translate('Event')),
82600c92694SGreg Roach            'OBJE:SOUR:EVEN:ROLE'        => new RoleInEvent(I18N::translate('Role')),
827d64c51bcSGreg Roach            'OBJE:SOUR:NOTE'             => new NoteStructure(I18N::translate('Note on source citation')),
82800c92694SGreg Roach            'OBJE:SOUR:OBJE'             => new XrefMedia(I18N::translate('Media object')),
82900c92694SGreg Roach            'OBJE:SOUR:PAGE'             => new WhereWithinSource(I18N::translate('Citation details')),
83000c92694SGreg Roach            'OBJE:SOUR:QUAY'             => new CertaintyAssessment(I18N::translate('Quality of data')),
83100c92694SGreg Roach            'REPO'                       => new RepositoryRecord(I18N::translate('Repository')),
83200c92694SGreg Roach            'REPO:ADDR'                  => new AddressLine(I18N::translate('Address')),
83300c92694SGreg Roach            'REPO:ADDR:ADR1'             => new AddressLine1(I18N::translate('Address line 1')),
83400c92694SGreg Roach            'REPO:ADDR:ADR2'             => new AddressLine2(I18N::translate('Address line 2')),
83500c92694SGreg Roach            'REPO:ADDR:ADR3'             => new AddressLine3(I18N::translate('Address line 3')),
83600c92694SGreg Roach            'REPO:ADDR:CITY'             => new AddressCity(I18N::translate('City')),
83700c92694SGreg Roach            'REPO:ADDR:CTRY'             => new AddressCountry(I18N::translate('Country')),
83800c92694SGreg Roach            'REPO:ADDR:POST'             => new AddressPostalCode(I18N::translate('Postal code')),
83900c92694SGreg Roach            'REPO:ADDR:STAE'             => new AddressState(I18N::translate('State')),
84000c92694SGreg Roach            'REPO:CHAN'                  => new Change(I18N::translate('Last change')),
84100c92694SGreg Roach            'REPO:CHAN:DATE'             => new ChangeDate(I18N::translate('Date of last change')),
842099c152eSGreg Roach            'REPO:CHAN:DATE:TIME'        => new TimeValueNow(I18N::translate('Time of last change')),
843d64c51bcSGreg Roach            'REPO:CHAN:NOTE'             => new NoteStructure(I18N::translate('Note on last change')),
84400c92694SGreg Roach            'REPO:EMAIL'                 => new AddressEmail(I18N::translate('Email address')),
84500c92694SGreg Roach            'REPO:FAX'                   => new AddressFax(I18N::translate('Fax')),
84600c92694SGreg Roach            'REPO:NAME'                  => new NameOfRepository(I18N::translateContext('Repository', 'Name')),
84700c92694SGreg Roach            'REPO:NOTE'                  => new NoteStructure(I18N::translate('Note')),
84800c92694SGreg Roach            'REPO:PHON'                  => new PhoneNumber(I18N::translate('Phone')),
84900c92694SGreg Roach            'REPO:REFN'                  => new UserReferenceNumber(I18N::translate('Reference number')),
85000c92694SGreg Roach            'REPO:REFN:TYPE'             => new UserReferenceType(I18N::translate('Type of reference number')),
85100c92694SGreg Roach            'REPO:RIN'                   => new AutomatedRecordId(I18N::translate('Record ID number')),
85200c92694SGreg Roach            'REPO:WWW'                   => new AddressWebPage(I18N::translate('URL')),
85300c92694SGreg Roach            'SOUR'                       => new SourceRecord(I18N::translate('Source')),
85400c92694SGreg Roach            'SOUR:ABBR'                  => new SourceFiledByEntry(I18N::translate('Abbreviation')),
85500c92694SGreg Roach            'SOUR:AUTH'                  => new SourceOriginator(I18N::translate('Author')),
85600c92694SGreg Roach            'SOUR:CHAN'                  => new Change(I18N::translate('Last change')),
85700c92694SGreg Roach            'SOUR:CHAN:DATE'             => new ChangeDate(I18N::translate('Date of last change')),
858099c152eSGreg Roach            'SOUR:CHAN:DATE:TIME'        => new TimeValueNow(I18N::translate('Time of last change')),
859d64c51bcSGreg Roach            'SOUR:CHAN:NOTE'             => new NoteStructure(I18N::translate('Note on last change')),
86000c92694SGreg Roach            'SOUR:DATA'                  => new EmptyElement(I18N::translate('Data'), ['EVEN' => '0:M', 'AGNC' => '0:1', 'NOTE' => '0:M']),
86100c92694SGreg Roach            'SOUR:DATA:AGNC'             => new ResponsibleAgency(I18N::translate('Agency')),
86200c92694SGreg Roach            'SOUR:DATA:EVEN'             => new EventsRecorded(I18N::translate('Events')),
86300c92694SGreg Roach            'SOUR:DATA:EVEN:DATE'        => new DateValue(I18N::translate('Date range')),
86400c92694SGreg Roach            'SOUR:DATA:EVEN:PLAC'        => new SourceJurisdictionPlace(I18N::translate('Place'), []),
865d64c51bcSGreg Roach            'SOUR:DATA:NOTE'             => new NoteStructure(I18N::translate('Note on source data')),
866d64c51bcSGreg Roach            'SOUR:NOTE'                  => new NoteStructure(I18N::translate('Note on source')),
86700c92694SGreg Roach            'SOUR:OBJE'                  => new XrefMedia(I18N::translate('Media object')),
86800c92694SGreg Roach            'SOUR:PUBL'                  => new SourcePublicationFacts(I18N::translate('Publication')),
86900c92694SGreg Roach            'SOUR:REFN'                  => new UserReferenceNumber(I18N::translate('Reference number')),
87000c92694SGreg Roach            'SOUR:REFN:TYPE'             => new UserReferenceType(I18N::translate('Type of reference number')),
87100c92694SGreg Roach            'SOUR:REPO'                  => new XrefRepository(I18N::translate('Repository')),
87200c92694SGreg Roach            'SOUR:REPO:CALN'             => new SourceCallNumber(I18N::translate('Call number')),
87300c92694SGreg Roach            'SOUR:REPO:CALN:MEDI'        => new SourceMediaType(I18N::translate('Media type')),
874d64c51bcSGreg Roach            'SOUR:REPO:NOTE'             => new NoteStructure(I18N::translate('Note on repository reference')),
87500c92694SGreg Roach            'SOUR:RIN'                   => new AutomatedRecordId(I18N::translate('Record ID number')),
87600c92694SGreg Roach            'SOUR:TEXT'                  => new TextFromSource(I18N::translate('Text')),
87700c92694SGreg Roach            'SOUR:TITL'                  => new DescriptiveTitle(I18N::translate('Title')),
87800c92694SGreg Roach            'SUBM'                       => new SubmitterRecord(I18N::translate('Submitter')),
87900c92694SGreg Roach            'SUBM:ADDR'                  => new AddressLine(I18N::translate('Address')),
88000c92694SGreg Roach            'SUBM:ADDR:ADR1'             => new AddressLine1(I18N::translate('Address line 1')),
88100c92694SGreg Roach            'SUBM:ADDR:ADR2'             => new AddressLine2(I18N::translate('Address line 2')),
88200c92694SGreg Roach            'SUBM:ADDR:ADR3'             => new AddressLine3(I18N::translate('Address line 3')),
88300c92694SGreg Roach            'SUBM:ADDR:CITY'             => new AddressCity(I18N::translate('City')),
88400c92694SGreg Roach            'SUBM:ADDR:CTRY'             => new AddressCountry(I18N::translate('Country')),
88500c92694SGreg Roach            'SUBM:ADDR:POST'             => new AddressPostalCode(I18N::translate('Postal code')),
88600c92694SGreg Roach            'SUBM:ADDR:STAE'             => new AddressState(I18N::translate('State')),
88700c92694SGreg Roach            'SUBM:CHAN'                  => new Change(I18N::translate('Last change')),
88800c92694SGreg Roach            'SUBM:CHAN:DATE'             => new ChangeDate(I18N::translate('Date of last change')),
889099c152eSGreg Roach            'SUBM:CHAN:DATE:TIME'        => new TimeValueNow(I18N::translate('Time of last change')),
890d64c51bcSGreg Roach            'SUBM:CHAN:NOTE'             => new NoteStructure(I18N::translate('Note on last change')),
89100c92694SGreg Roach            'SUBM:EMAIL'                 => new AddressEmail(I18N::translate('Email address')),
89200c92694SGreg Roach            'SUBM:FAX'                   => new AddressFax(I18N::translate('Fax')),
89300c92694SGreg Roach            'SUBM:LANG'                  => new LanguageId(I18N::translate('Language')),
89400c92694SGreg Roach            'SUBM:NAME'                  => new SubmitterName(I18N::translate('Name')),
89500c92694SGreg Roach            'SUBM:NOTE'                  => new NoteStructure(I18N::translate('Note')),
89600c92694SGreg Roach            'SUBM:OBJE'                  => new XrefMedia(I18N::translate('Media object')),
89700c92694SGreg Roach            'SUBM:PHON'                  => new PhoneNumber(I18N::translate('Phone')),
89800c92694SGreg Roach            'SUBM:RFN'                   => new SubmitterRegisteredRfn(I18N::translate('Record file number')),
89900c92694SGreg Roach            'SUBM:RIN'                   => new AutomatedRecordId(I18N::translate('Record ID number')),
90000c92694SGreg Roach            'SUBM:WWW'                   => new AddressWebPage(I18N::translate('URL')),
90100c92694SGreg Roach            'SUBN'                       => new SubmissionRecord(I18N::translate('Submission')),
90200c92694SGreg Roach            'SUBN:ANCE'                  => new GenerationsOfAncestors(I18N::translate('Generations of ancestors')),
90300c92694SGreg Roach            'SUBN:CHAN'                  => new Change(I18N::translate('Last change')),
90400c92694SGreg Roach            'SUBN:CHAN:DATE'             => new ChangeDate(I18N::translate('Date of last change')),
905099c152eSGreg Roach            'SUBN:CHAN:DATE:TIME'        => new TimeValueNow(I18N::translate('Time of last change')),
906d64c51bcSGreg Roach            'SUBN:CHAN:NOTE'             => new NoteStructure(I18N::translate('Note on last change')),
90700c92694SGreg Roach            'SUBN:DESC'                  => new GenerationsOfDescendants(I18N::translate('Generations of descendants')),
90800c92694SGreg Roach            'SUBN:FAMF'                  => new NameOfFamilyFile(I18N::translate('Family file')),
90900c92694SGreg Roach            'SUBN:NOTE'                  => new NoteStructure(I18N::translate('Note')),
91000c92694SGreg Roach            'SUBN:ORDI'                  => new OrdinanceProcessFlag(I18N::translate('Ordinance')),
91100c92694SGreg Roach            'SUBN:RIN'                   => new AutomatedRecordId(I18N::translate('Record ID number')),
91200c92694SGreg Roach            'SUBN:SUBM'                  => new XrefSubmitter(I18N::translate('Submitter')),
91300c92694SGreg Roach            'SUBN:TEMP'                  => new TempleCode(/* I18N: https://en.wikipedia.org/wiki/Temple_(LDS_Church)*/ I18N::translate('Temple')),
91400c92694SGreg Roach            'TRLR'                       => new EmptyElement(I18N::translate('Trailer')),
91500c92694SGreg Roach        ];
91600c92694SGreg Roach    }
91700c92694SGreg Roach
91800c92694SGreg Roach    /**
91900c92694SGreg Roach     * Custom tags for webtrees.
92000c92694SGreg Roach     *
92100c92694SGreg Roach     * @return array<string,ElementInterface>
92200c92694SGreg Roach     */
92300c92694SGreg Roach    private function webtreesTags(): array
92400c92694SGreg Roach    {
92500c92694SGreg Roach        return [
92600c92694SGreg Roach            'FAM:CHAN:_WT_USER'           => new WebtreesUser(I18N::translate('Author of last change')),
9275d2c6313SGreg Roach            'FAM:FACT'                    => new FamilyFact(I18N::translate('Fact')),
9285d2c6313SGreg Roach            'FAM:FACT:TYPE'               => new EventOrFactClassification(I18N::translate('Type of fact')),
92900c92694SGreg Roach            'FAM:*:_ASSO'                 => new XrefAssociate(I18N::translate('Associate')),
930d64c51bcSGreg Roach            'FAM:*:_ASSO:NOTE'            => new NoteStructure(I18N::translate('Note on association')),
93100c92694SGreg Roach            'FAM:*:_ASSO:RELA'            => new RelationIsDescriptor(I18N::translate('Relationship')),
93200c92694SGreg Roach            'FAM:*:_ASSO:SOUR'            => new XrefSource(I18N::translate('Source citation')),
93300c92694SGreg Roach            'FAM:*:_ASSO:SOUR:DATA'       => new SourceData(I18N::translate('Data')),
934352bd396SGreg Roach            'FAM:*:_ASSO:SOUR:DATA:DATE'  => new DateValue(I18N::translate('Date of entry in original source')),
93500c92694SGreg Roach            'FAM:*:_ASSO:SOUR:DATA:TEXT'  => new TextFromSource(I18N::translate('Text')),
93600c92694SGreg Roach            'FAM:*:_ASSO:SOUR:EVEN'       => new EventTypeCitedFrom(I18N::translate('Event')),
93700c92694SGreg Roach            'FAM:*:_ASSO:SOUR:EVEN:ROLE'  => new RoleInEvent(I18N::translate('Role')),
938d64c51bcSGreg Roach            'FAM:*:_ASSO:SOUR:NOTE'       => new NoteStructure(I18N::translate('Note on source citation')),
93900c92694SGreg Roach            'FAM:*:_ASSO:SOUR:OBJE'       => new XrefMedia(I18N::translate('Media object')),
94000c92694SGreg Roach            'FAM:*:_ASSO:SOUR:PAGE'       => new WhereWithinSource(I18N::translate('Citation details')),
94100c92694SGreg Roach            'FAM:*:_ASSO:SOUR:QUAY'       => new CertaintyAssessment(I18N::translate('Quality of data')),
94200c92694SGreg Roach            'INDI:CHAN:_WT_USER'          => new WebtreesUser(I18N::translate('Author of last change')),
94300c92694SGreg Roach            'INDI:*:_ASSO'                => new XrefAssociate(I18N::translate('Associate')),
944d64c51bcSGreg Roach            'INDI:*:_ASSO:NOTE'           => new NoteStructure(I18N::translate('Note on association')),
94500c92694SGreg Roach            'INDI:*:_ASSO:RELA'           => new RelationIsDescriptor(I18N::translate('Relationship')),
94600c92694SGreg Roach            'INDI:*:_ASSO:SOUR'           => new XrefSource(I18N::translate('Source citation')),
94700c92694SGreg Roach            'INDI:*:_ASSO:SOUR:DATA'      => new SourceData(I18N::translate('Data')),
948352bd396SGreg Roach            'INDI:*:_ASSO:SOUR:DATA:DATE' => new DateValue(I18N::translate('Date of entry in original source')),
94900c92694SGreg Roach            'INDI:*:_ASSO:SOUR:DATA:TEXT' => new TextFromSource(I18N::translate('Text')),
95000c92694SGreg Roach            'INDI:*:_ASSO:SOUR:EVEN'      => new EventTypeCitedFrom(I18N::translate('Event')),
95100c92694SGreg Roach            'INDI:*:_ASSO:SOUR:EVEN:ROLE' => new RoleInEvent(I18N::translate('Role')),
952d64c51bcSGreg Roach            'INDI:*:_ASSO:SOUR:NOTE'      => new NoteStructure(I18N::translate('Note on source citation')),
95300c92694SGreg Roach            'INDI:*:_ASSO:SOUR:OBJE'      => new XrefMedia(I18N::translate('Media object')),
95400c92694SGreg Roach            'INDI:*:_ASSO:SOUR:PAGE'      => new WhereWithinSource(I18N::translate('Citation details')),
95500c92694SGreg Roach            'INDI:*:_ASSO:SOUR:QUAY'      => new CertaintyAssessment(I18N::translate('Quality of data')),
95600c92694SGreg Roach            'NOTE:CHAN:_WT_USER'          => new WebtreesUser(I18N::translate('Author of last change')),
95700c92694SGreg Roach            'NOTE:RESN'                   => new RestrictionNotice(I18N::translate('Restriction')),
95800c92694SGreg Roach            'OBJE:CHAN:_WT_USER'          => new WebtreesUser(I18N::translate('Author of last change')),
95900c92694SGreg Roach            'OBJE:RESN'                   => new RestrictionNotice(I18N::translate('Restriction')),
96000c92694SGreg Roach            'REPO:CHAN:_WT_USER'          => new WebtreesUser(I18N::translate('Author of last change')),
96100c92694SGreg Roach            'REPO:RESN'                   => new RestrictionNotice(I18N::translate('Restriction')),
96200c92694SGreg Roach            'SOUR:CHAN:_WT_USER'          => new WebtreesUser(I18N::translate('Author of last change')),
96300c92694SGreg Roach            'SOUR:RESN'                   => new RestrictionNotice(I18N::translate('Restriction')),
96400c92694SGreg Roach            'SUBM:CHAN:_WT_USER'          => new WebtreesUser(I18N::translate('Author of last change')),
96500c92694SGreg Roach            'SUBM:RESN'                   => new RestrictionNotice(I18N::translate('Restriction')),
96600c92694SGreg Roach            '_LOC:CHAN:_WT_USER'          => new WebtreesUser(I18N::translate('Author of last change')),
96700c92694SGreg Roach            '_LOC:RESN'                   => new RestrictionNotice(I18N::translate('Restriction')),
96800c92694SGreg Roach        ];
96900c92694SGreg Roach    }
97000c92694SGreg Roach
97100c92694SGreg Roach    /**
97200c92694SGreg Roach     * @return array<string,array<int,array<int,string>>>
97300c92694SGreg Roach     */
97400c92694SGreg Roach    private function webtreesSubTags(): array
97500c92694SGreg Roach    {
97600c92694SGreg Roach        return [
97700c92694SGreg Roach            'FAM'              => [['_UID', '0:M']],
97800c92694SGreg Roach            'FAM:*:SOUR:DATA'  => [['TEXT', '0:1']],
97900c92694SGreg Roach            'FAM:ANUL'         => [['_ASSO', '0:M', 'NOTE']],
98000c92694SGreg Roach            'FAM:CENS'         => [['_ASSO', '0:M', 'NOTE']],
98100c92694SGreg Roach            'FAM:CHAN'         => [['_WT_USER', '0:1']],
98200c92694SGreg Roach            'FAM:DIV'          => [['_ASSO', '0:M', 'NOTE']],
98300c92694SGreg Roach            'FAM:DIVF'         => [['_ASSO', '0:M', 'NOTE']],
98400c92694SGreg Roach            'FAM:ENGA'         => [['_ASSO', '0:M', 'NOTE']],
98500c92694SGreg Roach            'FAM:EVEN'         => [['_ASSO', '0:M', 'NOTE']],
98600c92694SGreg Roach            'FAM:MARB'         => [['_ASSO', '0:M', 'NOTE']],
98700c92694SGreg Roach            'FAM:MARC'         => [['_ASSO', '0:M', 'NOTE']],
98800c92694SGreg Roach            'FAM:MARL'         => [['_ASSO', '0:M', 'NOTE']],
98900c92694SGreg Roach            'FAM:MARR'         => [['_ASSO', '2:M', 'NOTE']],
99000c92694SGreg Roach            'FAM:MARS'         => [['_ASSO', '0:M', 'NOTE']],
99100c92694SGreg Roach            'FAM:SLGS'         => [['_ASSO', '0:M', 'NOTE']],
99200c92694SGreg Roach            'FAM:SOUR:DATA'    => [['TEXT', '0:1']],
99300c92694SGreg Roach            'INDI'             => [['_UID', '0:M']],
99400c92694SGreg Roach            'INDI:*:SOUR:DATA' => [['TEXT', '0:1']],
99500c92694SGreg Roach            'INDI:ADOP'        => [['_ASSO', '0:M', 'NOTE']],
99600c92694SGreg Roach            'INDI:BAPL'        => [['_ASSO', '0:M', 'NOTE']],
99700c92694SGreg Roach            'INDI:BAPM'        => [['_ASSO', '2:M', 'NOTE']],
99800c92694SGreg Roach            'INDI:BARM'        => [['_ASSO', '0:M', 'NOTE']],
99900c92694SGreg Roach            'INDI:BASM'        => [['_ASSO', '0:M', 'NOTE']],
100000c92694SGreg Roach            'INDI:BIRT'        => [['_ASSO', '0:M', 'NOTE'], ['FAMC', '0:0']],
100100c92694SGreg Roach            'INDI:BURI'        => [['_ASSO', '0:M', 'NOTE']],
100200c92694SGreg Roach            'INDI:CENS'        => [['_ASSO', '0:M', 'NOTE']],
100300c92694SGreg Roach            'INDI:CHAN'        => [['_WT_USER', '0:1']],
100400c92694SGreg Roach            'INDI:CHR'         => [['_ASSO', '2:M', 'NOTE']],
100500c92694SGreg Roach            'INDI:CHRA'        => [['_ASSO', '0:M', 'NOTE']],
100600c92694SGreg Roach            'INDI:CONF'        => [['_ASSO', '0:M', 'NOTE']],
100700c92694SGreg Roach            'INDI:CONL'        => [['_ASSO', '0:M', 'NOTE']],
100800c92694SGreg Roach            'INDI:CREM'        => [['_ASSO', '0:M', 'NOTE']],
100900c92694SGreg Roach            'INDI:DEAT'        => [['_ASSO', '0:M', 'NOTE']],
101000c92694SGreg Roach            'INDI:EDUC'        => [['_ASSO', '0:M', 'NOTE']],
101100c92694SGreg Roach            'INDI:EMIG'        => [['_ASSO', '0:M', 'NOTE']],
101200c92694SGreg Roach            'INDI:ENDL'        => [['_ASSO', '0:M', 'NOTE']],
101300c92694SGreg Roach            'INDI:EVEN'        => [['_ASSO', '0:M', 'NOTE']],
101400c92694SGreg Roach            'INDI:GRAD'        => [['_ASSO', '0:M', 'NOTE']],
101500c92694SGreg Roach            'INDI:IMMI'        => [['_ASSO', '0:M', 'NOTE']],
101600c92694SGreg Roach            'INDI:NATU'        => [['_ASSO', '0:M', 'NOTE']],
101700c92694SGreg Roach            'INDI:OCCU'        => [['_ASSO', '0:M', 'NOTE']],
101800c92694SGreg Roach            'INDI:ORDN'        => [['_ASSO', '0:M', 'NOTE']],
101900c92694SGreg Roach            'INDI:PROB'        => [['_ASSO', '0:M', 'NOTE']],
102000c92694SGreg Roach            'INDI:PROP'        => [['_ASSO', '0:M', 'NOTE']],
102100c92694SGreg Roach            'INDI:RESI'        => [['_ASSO', '0:M', 'NOTE']],
102200c92694SGreg Roach            'INDI:RETI'        => [['_ASSO', '0:M', 'NOTE']],
102300c92694SGreg Roach            'INDI:SLGC'        => [['_ASSO', '0:M', 'NOTE']],
102400c92694SGreg Roach            'INDI:SOUR:DATA'   => [['TEXT', '0:1']],
102500c92694SGreg Roach            'INDI:TITL'        => [['_ASSO', '0:M', 'NOTE']],
102600c92694SGreg Roach            'INDI:WILL'        => [['_ASSO', '0:M', 'NOTE']],
102700c92694SGreg Roach            'NOTE'             => [['RESN', '0:1', 'CHAN']],
102800c92694SGreg Roach            'NOTE:CHAN'        => [['_WT_USER', '0:1']],
102900c92694SGreg Roach            'NOTE:SOUR:DATA'   => [['TEXT', '0:1']],
103000c92694SGreg Roach            'OBJE'             => [['RESN', '0:1', 'CHAN'], ['_UID', '0:M']],
103100c92694SGreg Roach            'OBJE:CHAN'        => [['_WT_USER', '0:1']],
103200c92694SGreg Roach            'OBJE:SOUR:DATA'   => [['TEXT', '0:1']],
103300c92694SGreg Roach            'REPO'             => [['RESN', '0:1', 'CHAN'], ['_UID', '0:M']],
103400c92694SGreg Roach            'REPO:CHAN'        => [['_WT_USER', '0:1']],
103500c92694SGreg Roach            'SOUR'             => [['RESN', '0:1', 'CHAN'], ['_UID', '0:M']],
103600c92694SGreg Roach            'SOUR:CHAN'        => [['_WT_USER', '0:1']],
103700c92694SGreg Roach            'SUBM'             => [['RESN', '0:1', 'CHAN']],
103800c92694SGreg Roach            'SUBM:CHAN'        => [['_WT_USER', '0:1']],
103900c92694SGreg Roach        ];
104000c92694SGreg Roach    }
104100c92694SGreg Roach
104200c92694SGreg Roach    /**
104300c92694SGreg Roach     * @return array<string,array<int,array<int,string>>>
104400c92694SGreg Roach     */
104500c92694SGreg Roach    private function customSubTags(): array
104600c92694SGreg Roach    {
104700c92694SGreg Roach        $custom_family_tags     = array_filter(explode(',', Site::getPreference('CUSTOM_FAMILY_TAGS')));
104800c92694SGreg Roach        $custom_individual_tags = array_filter(explode(',', Site::getPreference('CUSTOM_INDIVIDUAL_TAGS')));
104900c92694SGreg Roach
105000c92694SGreg Roach        $subtags = [
105100c92694SGreg Roach            'FAM'  => array_map(static fn (string $tag): array => [$tag, '0:M'], $custom_family_tags),
105200c92694SGreg Roach            'INDI' => array_map(static fn (string $tag): array => [$tag, '0:M'], $custom_individual_tags),
105300c92694SGreg Roach        ];
105400c92694SGreg Roach
1055d4193d5fSGreg Roach        if (Site::getPreference('CUSTOM_TIME_TAGS') === '1') {
1056d4193d5fSGreg Roach            $subtags['INDI:BIRT:DATE'][] = ['TIME', '0:1'];
1057d4193d5fSGreg Roach            $subtags['INDI:DEAT:DATE'][] = ['TIME', '0:1'];
1058d4193d5fSGreg Roach        }
1059d4193d5fSGreg Roach
106000c92694SGreg Roach        if (Site::getPreference('CUSTOM_GEDCOM_L_TAGS') === '1') {
106100c92694SGreg Roach            $subtags['FAM'][]               = ['_ASSO', '0:M'];
106200c92694SGreg Roach            $subtags['FAM'][]               = ['_STAT', '0:1'];
106300c92694SGreg Roach            $subtags['FAM'][]               = ['_UID', '0:M'];
1064f91876f3SGreg Roach            $subtags['FAM:*:ADDR']          = [['_NAME', '0:1:?', 'ADR1']];
106500c92694SGreg Roach            $subtags['FAM:*:PLAC']          = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
106600c92694SGreg Roach            $subtags['FAM:ENGA:PLAC']       = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
106700c92694SGreg Roach            $subtags['FAM:MARB:PLAC']       = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
10681c2da29dSRichard Cissée            $subtags['FAM:MARR']            = [['_WITN', '0:1']];
106900c92694SGreg Roach            $subtags['FAM:MARR:PLAC']       = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
107000c92694SGreg Roach            $subtags['FAM:SLGS:PLAC']       = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
107100c92694SGreg Roach            $subtags['INDI'][]              = ['_UID', '0:M'];
1072f91876f3SGreg Roach            $subtags['INDI:*:ADDR']         = [['_NAME', '0:1:?', 'ADR1']];
107300c92694SGreg Roach            $subtags['INDI:*:PLAC']         = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
107400c92694SGreg Roach            $subtags['INDI:ADOP:PLAC']      = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
107500c92694SGreg Roach            $subtags['INDI:BAPL:PLAC']      = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
10761c2da29dSRichard Cissée            $subtags['INDI:BAPM']           = [['_GODP', '0:1'], ['_WITN', '0:1']];
107700c92694SGreg Roach            $subtags['INDI:BAPM:PLAC']      = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
107800c92694SGreg Roach            $subtags['INDI:BARM:PLAC']      = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
107900c92694SGreg Roach            $subtags['INDI:BASM:PLAC']      = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
108000c92694SGreg Roach            $subtags['INDI:BIRT:PLAC']      = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
108100c92694SGreg Roach            $subtags['INDI:BLES:PLAC']      = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
108200c92694SGreg Roach            $subtags['INDI:BURI:PLAC']      = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
108300c92694SGreg Roach            $subtags['INDI:CENS:PLAC']      = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
10841c2da29dSRichard Cissée            $subtags['INDI:CHR']            = [['_GODP', '0:1'], ['_WITN', '0:1']];
108500c92694SGreg Roach            $subtags['INDI:CHR:PLAC']       = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
108600c92694SGreg Roach            $subtags['INDI:CHRA:PLAC']      = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
108700c92694SGreg Roach            $subtags['INDI:CONF:PLAC']      = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
108800c92694SGreg Roach            $subtags['INDI:CONL:PLAC']      = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
108900c92694SGreg Roach            $subtags['INDI:CREM:PLAC']      = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
109000c92694SGreg Roach            $subtags['INDI:DEAT:PLAC']      = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
109100c92694SGreg Roach            $subtags['INDI:EMIG:PLAC']      = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
109200c92694SGreg Roach            $subtags['INDI:ENDL:PLAC']      = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
109300c92694SGreg Roach            $subtags['INDI:EVEN:PLAC']      = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
109400c92694SGreg Roach            $subtags['INDI:FCOM:PLAC']      = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
109500c92694SGreg Roach            $subtags['INDI:IMMI:PLAC']      = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
109678fee3e8SGreg Roach            $subtags['INDI:NAME']           = [['_RUFNAME', '0:1', 'SPFX']];
109700c92694SGreg Roach            $subtags['INDI:NATU:PLAC']      = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
109800c92694SGreg Roach            $subtags['INDI:ORDN:PLAC']      = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
109900c92694SGreg Roach            $subtags['INDI:RESI:PLAC']      = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
110000c92694SGreg Roach            $subtags['INDI:SLGC:PLAC']      = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
110100c92694SGreg Roach            $subtags['NOTE']                = [['_UID', '0:M']];
110200c92694SGreg Roach            $subtags['OBJE']                = [['_PRIM', '0:1:?'], ['_UID', '0:M']];
110300c92694SGreg Roach            $subtags['REPO']                = [['_UID', '0:M']];
110400c92694SGreg Roach            $subtags['REPO:ADDR']           = [['_NAME', '0:1', 'ADR1']];
110500c92694SGreg Roach            $subtags['SOUR']                = [['_UID', '0:M']];
110600c92694SGreg Roach            $subtags['SOUR:DATA:EVEN:PLAC'] = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1']];
110700c92694SGreg Roach            $subtags['SUBM']                = [['_UID', '0:M']];
110800c92694SGreg Roach            $subtags['SUBM:ADDR']           = [['_NAME', '0:1', 'ADR1']];
110900c92694SGreg Roach        }
111000c92694SGreg Roach
111100c92694SGreg Roach        return $subtags;
111200c92694SGreg Roach    }
111300c92694SGreg Roach
11149e97502fSGreg Roach    /**
11159e97502fSGreg Roach     * @param ElementFactoryInterface $element_factory
11169e97502fSGreg Roach     * @param bool                    $include_custom_tags
11179e97502fSGreg Roach     *
11189e97502fSGreg Roach     * @return void
11199e97502fSGreg Roach     */
1120e669bb4bSGreg Roach    public function registerTags(ElementFactoryInterface $element_factory, bool $include_custom_tags): void
112100c92694SGreg Roach    {
112200c92694SGreg Roach        // Standard GEDCOM.
1123e669bb4bSGreg Roach        $element_factory->registerTags($this->gedcom551Tags());
112400c92694SGreg Roach
112500c92694SGreg Roach        // webtrees extensions.
1126e669bb4bSGreg Roach        $element_factory->registerTags($this->webtreesTags());
1127e669bb4bSGreg Roach
1128e669bb4bSGreg Roach        if ($include_custom_tags) {
1129e669bb4bSGreg Roach            // webtrees extensions.
1130e669bb4bSGreg Roach            $element_factory->registerSubTags($this->webtreesSubTags());
113100c92694SGreg Roach
1132*864236f5SGreg Roach            $custom_tags = [
1133*864236f5SGreg Roach                new Aldfaer(),
1134*864236f5SGreg Roach                new Ancestry(),
1135*864236f5SGreg Roach                new BrothersKeeper(),
1136*864236f5SGreg Roach                new FamilySearch(),
1137*864236f5SGreg Roach                new FamilyTreeBuilder(),
1138*864236f5SGreg Roach                new FamilyTreeMaker(),
1139*864236f5SGreg Roach                new Gedcom7(),
1140*864236f5SGreg Roach                new GedcomL(),
1141*864236f5SGreg Roach                new Geneatique(),
1142*864236f5SGreg Roach                new GenPlusWin(),
1143*864236f5SGreg Roach                new Heredis(),
1144*864236f5SGreg Roach                new Legacy(),
1145*864236f5SGreg Roach                new MyHeritage(),
1146*864236f5SGreg Roach                new PersonalAncestralFile(),
1147*864236f5SGreg Roach                new PhpGedView(),
1148*864236f5SGreg Roach                new ProGen(),
1149*864236f5SGreg Roach                new Reunion(),
1150*864236f5SGreg Roach                new RootsMagic(),
1151*864236f5SGreg Roach            ];
1152*864236f5SGreg Roach
1153*864236f5SGreg Roach            foreach ($custom_tags as $custom_tag) {
1154*864236f5SGreg Roach                $element_factory->registerTags($custom_tag->tags());
1155*864236f5SGreg Roach            }
115600c92694SGreg Roach
115700c92694SGreg Roach            // Creating tags from all the above are grouped into one place
1158e669bb4bSGreg Roach            $element_factory->registerSubTags($this->customSubTags());
1159e669bb4bSGreg Roach        }
116000c92694SGreg Roach    }
11610f471f91SGreg Roach}
1162