1<?php 2 3/** 4 * webtrees: online genealogy 5 * Copyright (C) 2023 webtrees development team 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation, either version 3 of the License, or 9 * (at your option) any later version. 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <https://www.gnu.org/licenses/>. 16 */ 17 18declare(strict_types=1); 19 20namespace Fisharebest\Webtrees; 21 22use Fisharebest\Webtrees\Contracts\ElementFactoryInterface; 23use Fisharebest\Webtrees\Contracts\ElementInterface; 24use Fisharebest\Webtrees\CustomTags\Aldfaer; 25use Fisharebest\Webtrees\CustomTags\Ancestry; 26use Fisharebest\Webtrees\CustomTags\BrothersKeeper; 27use Fisharebest\Webtrees\CustomTags\FamilySearch; 28use Fisharebest\Webtrees\CustomTags\FamilyTreeBuilder; 29use Fisharebest\Webtrees\CustomTags\FamilyTreeMaker; 30use Fisharebest\Webtrees\CustomTags\Gedcom7; 31use Fisharebest\Webtrees\CustomTags\GedcomL; 32use Fisharebest\Webtrees\CustomTags\Geneatique; 33use Fisharebest\Webtrees\CustomTags\GenPlusWin; 34use Fisharebest\Webtrees\CustomTags\Heredis; 35use Fisharebest\Webtrees\CustomTags\Legacy; 36use Fisharebest\Webtrees\CustomTags\MyHeritage; 37use Fisharebest\Webtrees\CustomTags\PersonalAncestralFile; 38use Fisharebest\Webtrees\CustomTags\PhpGedView; 39use Fisharebest\Webtrees\CustomTags\ProGen; 40use Fisharebest\Webtrees\CustomTags\Reunion; 41use Fisharebest\Webtrees\CustomTags\RootsMagic; 42use Fisharebest\Webtrees\CustomTags\TheMasterGenealogist; 43use Fisharebest\Webtrees\CustomTags\TheNextGeneration; 44use Fisharebest\Webtrees\Elements\AddressCity; 45use Fisharebest\Webtrees\Elements\AddressCountry; 46use Fisharebest\Webtrees\Elements\AddressEmail; 47use Fisharebest\Webtrees\Elements\AddressFax; 48use Fisharebest\Webtrees\Elements\AddressLine; 49use Fisharebest\Webtrees\Elements\AddressLine1; 50use Fisharebest\Webtrees\Elements\AddressLine2; 51use Fisharebest\Webtrees\Elements\AddressLine3; 52use Fisharebest\Webtrees\Elements\AddressPostalCode; 53use Fisharebest\Webtrees\Elements\AddressState; 54use Fisharebest\Webtrees\Elements\AddressWebPage; 55use Fisharebest\Webtrees\Elements\AdoptedByWhichParent; 56use Fisharebest\Webtrees\Elements\Adoption; 57use Fisharebest\Webtrees\Elements\AdultChristening; 58use Fisharebest\Webtrees\Elements\AgeAtEvent; 59use Fisharebest\Webtrees\Elements\AncestralFileNumber; 60use Fisharebest\Webtrees\Elements\Annulment; 61use Fisharebest\Webtrees\Elements\ApprovedSystemId; 62use Fisharebest\Webtrees\Elements\AutomatedRecordId; 63use Fisharebest\Webtrees\Elements\Baptism; 64use Fisharebest\Webtrees\Elements\BarMitzvah; 65use Fisharebest\Webtrees\Elements\BasMitzvah; 66use Fisharebest\Webtrees\Elements\Birth; 67use Fisharebest\Webtrees\Elements\Blessing; 68use Fisharebest\Webtrees\Elements\Burial; 69use Fisharebest\Webtrees\Elements\CasteName; 70use Fisharebest\Webtrees\Elements\CauseOfEvent; 71use Fisharebest\Webtrees\Elements\Census; 72use Fisharebest\Webtrees\Elements\CertaintyAssessment; 73use Fisharebest\Webtrees\Elements\Change; 74use Fisharebest\Webtrees\Elements\ChangeDate; 75use Fisharebest\Webtrees\Elements\CharacterSet; 76use Fisharebest\Webtrees\Elements\ChildLinkageStatus; 77use Fisharebest\Webtrees\Elements\Christening; 78use Fisharebest\Webtrees\Elements\Confirmation; 79use Fisharebest\Webtrees\Elements\ContentDescription; 80use Fisharebest\Webtrees\Elements\Coordinates; 81use Fisharebest\Webtrees\Elements\CopyrightFile; 82use Fisharebest\Webtrees\Elements\CopyrightSourceData; 83use Fisharebest\Webtrees\Elements\CountOfChildren; 84use Fisharebest\Webtrees\Elements\CountOfChildrenFam; 85use Fisharebest\Webtrees\Elements\CountOfMarriages; 86use Fisharebest\Webtrees\Elements\Cremation; 87use Fisharebest\Webtrees\Elements\CustomElement; 88use Fisharebest\Webtrees\Elements\DateLdsOrd; 89use Fisharebest\Webtrees\Elements\DateValue; 90use Fisharebest\Webtrees\Elements\DateValueExact; 91use Fisharebest\Webtrees\Elements\Death; 92use Fisharebest\Webtrees\Elements\DescriptiveTitle; 93use Fisharebest\Webtrees\Elements\Divorce; 94use Fisharebest\Webtrees\Elements\DivorceFiled; 95use Fisharebest\Webtrees\Elements\Emigration; 96use Fisharebest\Webtrees\Elements\EmptyElement; 97use Fisharebest\Webtrees\Elements\Engagement; 98use Fisharebest\Webtrees\Elements\EventOrFactClassification; 99use Fisharebest\Webtrees\Elements\EventsRecorded; 100use Fisharebest\Webtrees\Elements\EventTypeCitedFrom; 101use Fisharebest\Webtrees\Elements\FamilyCensus; 102use Fisharebest\Webtrees\Elements\FamilyEvent; 103use Fisharebest\Webtrees\Elements\FamilyRecord; 104use Fisharebest\Webtrees\Elements\FileName; 105use Fisharebest\Webtrees\Elements\FirstCommunion; 106use Fisharebest\Webtrees\Elements\Form; 107use Fisharebest\Webtrees\Elements\GedcomElement; 108use Fisharebest\Webtrees\Elements\GenerationsOfAncestors; 109use Fisharebest\Webtrees\Elements\GenerationsOfDescendants; 110use Fisharebest\Webtrees\Elements\Graduation; 111use Fisharebest\Webtrees\Elements\HeaderRecord; 112use Fisharebest\Webtrees\Elements\Immigration; 113use Fisharebest\Webtrees\Elements\IndividualEvent; 114use Fisharebest\Webtrees\Elements\IndividualFact; 115use Fisharebest\Webtrees\Elements\IndividualRecord; 116use Fisharebest\Webtrees\Elements\LanguageId; 117use Fisharebest\Webtrees\Elements\LdsBaptism; 118use Fisharebest\Webtrees\Elements\LdsBaptismDateStatus; 119use Fisharebest\Webtrees\Elements\LdsChildSealing; 120use Fisharebest\Webtrees\Elements\LdsChildSealingDateStatus; 121use Fisharebest\Webtrees\Elements\LdsConfirmation; 122use Fisharebest\Webtrees\Elements\LdsEndowment; 123use Fisharebest\Webtrees\Elements\LdsEndowmentDateStatus; 124use Fisharebest\Webtrees\Elements\LdsSpouseSealing; 125use Fisharebest\Webtrees\Elements\LdsSpouseSealingDateStatus; 126use Fisharebest\Webtrees\Elements\Marriage; 127use Fisharebest\Webtrees\Elements\MarriageBanns; 128use Fisharebest\Webtrees\Elements\MarriageContract; 129use Fisharebest\Webtrees\Elements\MarriageLicence; 130use Fisharebest\Webtrees\Elements\MarriageSettlement; 131use Fisharebest\Webtrees\Elements\MarriageType; 132use Fisharebest\Webtrees\Elements\MediaRecord; 133use Fisharebest\Webtrees\Elements\MultimediaFileReference; 134use Fisharebest\Webtrees\Elements\MultimediaFormat; 135use Fisharebest\Webtrees\Elements\NameOfBusiness; 136use Fisharebest\Webtrees\Elements\NameOfFamilyFile; 137use Fisharebest\Webtrees\Elements\NameOfProduct; 138use Fisharebest\Webtrees\Elements\NameOfRepository; 139use Fisharebest\Webtrees\Elements\NameOfSourceData; 140use Fisharebest\Webtrees\Elements\NamePersonal; 141use Fisharebest\Webtrees\Elements\NamePhoneticVariation; 142use Fisharebest\Webtrees\Elements\NamePieceGiven; 143use Fisharebest\Webtrees\Elements\NamePieceNickname; 144use Fisharebest\Webtrees\Elements\NamePiecePrefix; 145use Fisharebest\Webtrees\Elements\NamePieceSuffix; 146use Fisharebest\Webtrees\Elements\NamePieceSurname; 147use Fisharebest\Webtrees\Elements\NamePieceSurnamePrefix; 148use Fisharebest\Webtrees\Elements\NameRomanizedVariation; 149use Fisharebest\Webtrees\Elements\NameType; 150use Fisharebest\Webtrees\Elements\NationalIdNumber; 151use Fisharebest\Webtrees\Elements\NationalOrTribalOrigin; 152use Fisharebest\Webtrees\Elements\Naturalization; 153use Fisharebest\Webtrees\Elements\NobilityTypeTitle; 154use Fisharebest\Webtrees\Elements\NoteRecord; 155use Fisharebest\Webtrees\Elements\NoteStructure; 156use Fisharebest\Webtrees\Elements\Occupation; 157use Fisharebest\Webtrees\Elements\OrdinanceProcessFlag; 158use Fisharebest\Webtrees\Elements\Ordination; 159use Fisharebest\Webtrees\Elements\PedigreeLinkageType; 160use Fisharebest\Webtrees\Elements\PermanentRecordFileNumber; 161use Fisharebest\Webtrees\Elements\PhoneNumber; 162use Fisharebest\Webtrees\Elements\PhoneticType; 163use Fisharebest\Webtrees\Elements\PhysicalDescription; 164use Fisharebest\Webtrees\Elements\PlaceHierarchy; 165use Fisharebest\Webtrees\Elements\PlaceLatitude; 166use Fisharebest\Webtrees\Elements\PlaceLivingOrdinance; 167use Fisharebest\Webtrees\Elements\PlaceLongtitude; 168use Fisharebest\Webtrees\Elements\PlaceName; 169use Fisharebest\Webtrees\Elements\PlacePhoneticVariation; 170use Fisharebest\Webtrees\Elements\PlaceRomanizedVariation; 171use Fisharebest\Webtrees\Elements\Possessions; 172use Fisharebest\Webtrees\Elements\Probate; 173use Fisharebest\Webtrees\Elements\PublicationDate; 174use Fisharebest\Webtrees\Elements\ReceivingSystemName; 175use Fisharebest\Webtrees\Elements\RelationIsDescriptor; 176use Fisharebest\Webtrees\Elements\ReligiousAffiliation; 177use Fisharebest\Webtrees\Elements\RepositoryRecord; 178use Fisharebest\Webtrees\Elements\Residence; 179use Fisharebest\Webtrees\Elements\ResidenceWithValue; 180use Fisharebest\Webtrees\Elements\ResponsibleAgency; 181use Fisharebest\Webtrees\Elements\RestrictionNotice; 182use Fisharebest\Webtrees\Elements\Retirement; 183use Fisharebest\Webtrees\Elements\RoleInEvent; 184use Fisharebest\Webtrees\Elements\RomanizedType; 185use Fisharebest\Webtrees\Elements\ScholasticAchievement; 186use Fisharebest\Webtrees\Elements\SexValue; 187use Fisharebest\Webtrees\Elements\SocialSecurityNumber; 188use Fisharebest\Webtrees\Elements\SourceCallNumber; 189use Fisharebest\Webtrees\Elements\SourceData; 190use Fisharebest\Webtrees\Elements\SourceFiledByEntry; 191use Fisharebest\Webtrees\Elements\SourceJurisdictionPlace; 192use Fisharebest\Webtrees\Elements\SourceMediaType; 193use Fisharebest\Webtrees\Elements\SourceOriginator; 194use Fisharebest\Webtrees\Elements\SourcePublicationFacts; 195use Fisharebest\Webtrees\Elements\SourceRecord; 196use Fisharebest\Webtrees\Elements\SubmissionRecord; 197use Fisharebest\Webtrees\Elements\SubmitterName; 198use Fisharebest\Webtrees\Elements\SubmitterRecord; 199use Fisharebest\Webtrees\Elements\SubmitterRegisteredRfn; 200use Fisharebest\Webtrees\Elements\SubmitterText; 201use Fisharebest\Webtrees\Elements\TempleCode; 202use Fisharebest\Webtrees\Elements\TextFromSource; 203use Fisharebest\Webtrees\Elements\TimeValueNow; 204use Fisharebest\Webtrees\Elements\TransmissionDate; 205use Fisharebest\Webtrees\Elements\UserReferenceNumber; 206use Fisharebest\Webtrees\Elements\UserReferenceType; 207use Fisharebest\Webtrees\Elements\VersionNumber; 208use Fisharebest\Webtrees\Elements\WebtreesUser; 209use Fisharebest\Webtrees\Elements\WhereWithinSource; 210use Fisharebest\Webtrees\Elements\Will; 211use Fisharebest\Webtrees\Elements\XrefAssociate; 212use Fisharebest\Webtrees\Elements\XrefFamily; 213use Fisharebest\Webtrees\Elements\XrefIndividual; 214use Fisharebest\Webtrees\Elements\XrefMedia; 215use Fisharebest\Webtrees\Elements\XrefRepository; 216use Fisharebest\Webtrees\Elements\XrefSource; 217use Fisharebest\Webtrees\Elements\XrefSubmission; 218use Fisharebest\Webtrees\Elements\XrefSubmitter; 219 220/** 221 * GEDCOM 5.5.1 specification 222 */ 223class Gedcom 224{ 225 // 255 less the EOL character. 226 public const LINE_LENGTH = 253; 227 228 // Gedcom tags which indicate the start of life. 229 public const BIRTH_EVENTS = ['BIRT', 'CHR', 'BAPM']; 230 231 // Gedcom tags which indicate the end of life. 232 public const DEATH_EVENTS = ['DEAT', 'BURI', 'CREM']; 233 234 // Gedcom tags which indicate the start of a relationship. 235 public const MARRIAGE_EVENTS = ['MARR', '_NMR']; 236 237 // Gedcom tags which indicate the end of a relationship. 238 public const DIVORCE_EVENTS = ['DIV', 'ANUL', '_SEPR']; 239 240 // Regular expression to match a GEDCOM tag. 241 public const REGEX_TAG = '[_A-Z][_A-Z0-9]*'; 242 243 // Regular expression to match a GEDCOM XREF. 244 public const REGEX_XREF = '[A-Za-z0-9:_.-]{1,20}'; 245 246 // Regular expression to match a GEDCOM fact/event for editing raw GEDCOM. 247 private const REGEX_VALUE = '( .+)?'; 248 private const REGEX_LEVEL_9 = '\n9 ' . self::REGEX_TAG . self::REGEX_VALUE; 249 private const REGEX_LEVEL_8 = '\n8 ' . self::REGEX_TAG . self::REGEX_VALUE . '(' . self::REGEX_LEVEL_9 . ')*'; 250 private const REGEX_LEVEL_7 = '\n7 ' . self::REGEX_TAG . self::REGEX_VALUE . '(' . self::REGEX_LEVEL_8 . ')*'; 251 private const REGEX_LEVEL_6 = '\n6 ' . self::REGEX_TAG . self::REGEX_VALUE . '(' . self::REGEX_LEVEL_7 . ')*'; 252 private const REGEX_LEVEL_5 = '\n5 ' . self::REGEX_TAG . self::REGEX_VALUE . '(' . self::REGEX_LEVEL_6 . ')*'; 253 private const REGEX_LEVEL_4 = '\n4 ' . self::REGEX_TAG . self::REGEX_VALUE . '(' . self::REGEX_LEVEL_5 . ')*'; 254 private const REGEX_LEVEL_3 = '\n3 ' . self::REGEX_TAG . self::REGEX_VALUE . '(' . self::REGEX_LEVEL_4 . ')*'; 255 private const REGEX_LEVEL_2 = '\n2 ' . self::REGEX_TAG . self::REGEX_VALUE . '(' . self::REGEX_LEVEL_3 . ')*'; 256 public const REGEX_FACT = '1 ' . self::REGEX_TAG . self::REGEX_VALUE . '(' . self::REGEX_LEVEL_2 . ')*\n?'; 257 258 // Separates the parts of a place name. 259 public const PLACE_SEPARATOR = ', '; 260 261 // Regex to match a (badly formed) GEDCOM place separator. 262 public const PLACE_SEPARATOR_REGEX = '/ *,[, ]*/'; 263 264 // LATI and LONG tags 265 public const LATITUDE_NORTH = 'N'; 266 public const LATITUDE_SOUTH = 'S'; 267 public const LONGITUDE_EAST = 'E'; 268 public const LONGITUDE_WEST = 'W'; 269 270 // Not all record types allow a CHAN event. 271 public const RECORDS_WITH_CHAN = [ 272 Family::RECORD_TYPE, 273 Individual::RECORD_TYPE, 274 Media::RECORD_TYPE, 275 Note::RECORD_TYPE, 276 Repository::RECORD_TYPE, 277 Source::RECORD_TYPE, 278 Submitter::RECORD_TYPE, 279 ]; 280 281 // These preferences control multiple tag definitions 282 public const HIDDEN_TAGS = [ 283 // Individual names 284 'NAME_NPFX' => ['INDI:NAME:NPFX', 'INDI:NAME:FONE:NPFX', 'INDI:NAME:ROMN:NPFX'], 285 'NAME_SPFX' => ['INDI:NAME:SPFX', 'INDI:NAME:FONE:SPFX', 'INDI:NAME:ROMN:SPFX'], 286 'NAME_NSFX' => ['INDI:NAME:NSFX', 'INDI:NAME:FONE:NSFX', 'INDI:NAME:ROMN:NSFX'], 287 'NAME_NICK' => ['INDI:NAME:NICK', 'INDI:NAME:FONE:NICK', 'INDI:NAME:ROMN:NICK'], 288 'NAME_FONE' => ['INDI:NAME:FONE'], 289 'NAME_ROMN' => ['INDI:NAME:ROMN'], 290 'NAME_NOTE' => ['INDI:NAME:NOTE', 'INDI:NAME:FONE:NOTE', 'INDI:NAME:ROMN:NOTE'], 291 'NAME_SOUR' => ['INDI:NAME:SOUR', 'INDI:NAME:FONE:SOUR', 'INDI:NAME:ROMN:SOUR'], 292 // Places 293 'PLAC_MAP' => [':PLAC:MAP'], 294 'PLAC_FONE' => [':PLAC:FONE'], 295 'PLAC_ROMN' => [':PLAC:ROMN'], 296 'PLAC_FORM' => [':PLAC:FORM', 'HEAD:PLAC'], 297 'PLAC_NOTE' => [':PLAC:NOTE'], 298 // Addresses 299 'ADDR_EMAIL' => [':EMAIL'], 300 'ADDR_PHON' => [':PHON'], 301 'ADDR_WWW' => [':WWW'], 302 // Source citations 303 'SOUR_EVEN' => [':SOUR:EVEN'], 304 'SOUR_DATE' => [':SOUR:DATA:DATE'], 305 'SOUR_NOTE' => [':SOUR:NOTE'], 306 'SOUR_QUAY' => [':SOUR:QUAY'], 307 // Sources 308 'SOUR_DATA' => ['SOUR:DATA:EVEN', 'SOUR:DATA:AGNC', 'SOUR:DATA:NOTE'], 309 // Individuals 310 'BIRT_FAMC' => ['INDI:BIRT:FAMC'], 311 'RELI' => ['INDI:RELI'], 312 'BAPM' => ['INDI:BAPM'], 313 'CHR' => ['INDI:CHR', 'INDI:CHRA'], 314 'FCOM' => ['INDI:FCOM', 'INDI:CONF'], 315 'ORDN' => ['INDI:ORDN'], 316 'BARM' => ['INDI:BARM', 'INDI:BASM'], 317 'ALIA' => ['INDI:ALIA'], 318 'ASSO' => ['INDI:ASSO'], 319 // Families 320 'ENGA' => ['FAM:ENGA'], 321 'MARB' => ['FAM:MARB'], 322 'MARC' => ['FAM:MARC'], 323 'MARL' => ['FAM:MARL'], 324 'MARS' => ['FAM:MARS'], 325 'ANUL' => ['FAM:ANUL'], 326 'DIVF' => ['FAM:DIVF'], 327 'FAM_RESI' => ['FAM:RESI'], 328 'FAM_CENS' => ['FAM:CENS'], 329 // LDS church 330 'LDS' => ['INDI:BAPL', 'INDI:CONL', 'INDI:ENDL', 'INDI:SLGC', 'FAM:SLGS', 'HEAD:SUBN'], 331 // Identifiers 332 'AFN' => ['INDI:AFN'], 333 'IDNO' => ['INDI:IDNO'], 334 'SSN' => ['INDI:SSN'], 335 'RFN' => [':RFN'], 336 'REFN' => [':REFN'], 337 'RIN' => [':RIN'], 338 // Submitters 339 'SUBM' => ['INDI:SUBM', 'FAM:SUBM'], 340 'ANCI' => ['INDI:ANCI', 'INDI:DESI'], 341 ]; 342 343 // Custom GEDCOM tags that can be created in webtrees. 344 public const CUSTOM_FAMILY_TAGS = [ 345 'FACT', 346 '_COML', 347 '_MARI', 348 '_MBON', 349 '_NMR', 350 '_SEPR', 351 ]; 352 353 public const CUSTOM_INDIVIDUAL_TAGS = [ 354 '_BRTM', 355 '_CIRC', 356 '_DEG', 357 '_DNA', 358 '_EXCM', 359 '_EYEC', 360 '_FNRL', 361 '_FSFTID', 362 '_HAIR', 363 '_HEIG', 364 '_INTE', 365 '_MDCL', 366 '_MEDC', 367 '_MILI', 368 '_MILT', 369 '_NAMS', 370 '_NMAR', 371 '_PRMN', 372 '_WEIG', 373 '_YART', 374 ]; 375 376 // Some applications create GEDCOM files containing records without XREFS. 377 // We cannot process these. 378 public const CUSTOM_RECORDS_WITHOUT_XREFS = [ 379 'EMOTIONALRELATIONSHIP', // GenoPro 380 'GENOMAP', // GenoPro 381 'GLOBAL', // GenoPro 382 'LABEL', // GenoPro 383 'PEDIGREELINK', // GenoPro 384 'SOCIALRELATIONSHIP', // GenoPro 385 '_EVDEF', // RootsMagic 386 '_EVENT_DEFN', // PAF and Legacy 387 '_HASHTAG_DEFN', // Legacy 388 '_PUBLISH', // MyHeritage 389 '_TASK', // Ages 390 '_TODO', // Legacy 391 ]; 392 393 /** 394 * Definitions for GEDCOM 5.5.1. 395 * 396 * @return array<string,ElementInterface> 397 */ 398 private function gedcom551Tags(): array 399 { 400 return [ 401 'FAM' => new FamilyRecord(I18N::translate('Family')), 402 'FAM:*:ADDR' => new AddressLine(I18N::translate('Address')), 403 'FAM:*:ADDR:ADR1' => new AddressLine1(I18N::translate('Address line 1')), 404 'FAM:*:ADDR:ADR2' => new AddressLine2(I18N::translate('Address line 2')), 405 'FAM:*:ADDR:ADR3' => new AddressLine3(I18N::translate('Address line 3')), 406 'FAM:*:ADDR:CITY' => new AddressCity(I18N::translate('City')), 407 'FAM:*:ADDR:CTRY' => new AddressCountry(I18N::translate('Country')), 408 'FAM:*:ADDR:POST' => new AddressPostalCode(I18N::translate('Postal code')), 409 'FAM:*:ADDR:STAE' => new AddressState(I18N::translate('State')), 410 'FAM:*:AGNC' => new ResponsibleAgency(I18N::translate('Agency')), 411 'FAM:*:CAUS' => new CauseOfEvent(I18N::translate('Cause')), 412 'FAM:*:DATE' => new DateValue(I18N::translate('Date')), 413 'FAM:*:EMAIL' => new AddressEmail(I18N::translate('Email address')), 414 'FAM:*:FAX' => new AddressFax(I18N::translate('Fax')), 415 'FAM:*:HUSB' => new EmptyElement(I18N::translate('Husband'), ['AGE' => '0:1']), 416 'FAM:*:HUSB:AGE' => new AgeAtEvent(I18N::translate('Husband’s age')), 417 'FAM:*:NOTE' => new NoteStructure(I18N::translate('Note')), 418 'FAM:*:OBJE' => new XrefMedia(I18N::translate('Media object')), 419 'FAM:*:PHON' => new PhoneNumber(I18N::translate('Phone')), 420 'FAM:*:PLAC' => new PlaceName(I18N::translate('Place')), 421 'FAM:*:PLAC:FONE' => new PlacePhoneticVariation(I18N::translate('Phonetic place')), 422 'FAM:*:PLAC:FONE:TYPE' => new PhoneticType(I18N::translate('Type')), 423 'FAM:*:PLAC:FORM' => new PlaceHierarchy(I18N::translate('Format')), 424 'FAM:*:PLAC:MAP' => new Coordinates(I18N::translate('Coordinates')), 425 'FAM:*:PLAC:MAP:LATI' => new PlaceLatitude(I18N::translate('Latitude')), 426 'FAM:*:PLAC:MAP:LONG' => new PlaceLongtitude(I18N::translate('Longitude')), 427 'FAM:*:PLAC:NOTE' => new NoteStructure(I18N::translate('Note on place')), 428 'FAM:*:PLAC:ROMN' => new PlaceRomanizedVariation(I18N::translate('Romanized place')), 429 'FAM:*:PLAC:ROMN:TYPE' => new RomanizedType(I18N::translate('Type')), 430 'FAM:*:RELI' => new ReligiousAffiliation(I18N::translate('Religion'), []), 431 'FAM:*:RESN' => new RestrictionNotice(I18N::translate('Restriction')), 432 'FAM:*:SOUR' => new XrefSource(I18N::translate('Source citation')), 433 'FAM:*:SOUR:DATA' => new SourceData(I18N::translate('Data')), 434 'FAM:*:SOUR:DATA:DATE' => new DateValue(I18N::translate('Date of entry in original source')), 435 'FAM:*:SOUR:DATA:TEXT' => new TextFromSource(I18N::translate('Text')), 436 'FAM:*:SOUR:EVEN' => new EventTypeCitedFrom(I18N::translate('Event')), 437 'FAM:*:SOUR:EVEN:ROLE' => new RoleInEvent(I18N::translate('Role')), 438 'FAM:*:SOUR:NOTE' => new NoteStructure(I18N::translate('Note on source citation')), 439 'FAM:*:SOUR:OBJE' => new XrefMedia(I18N::translate('Media object')), 440 'FAM:*:SOUR:PAGE' => new WhereWithinSource(I18N::translate('Citation details')), 441 'FAM:*:SOUR:QUAY' => new CertaintyAssessment(I18N::translate('Quality of data')), 442 'FAM:*:TYPE' => new EventOrFactClassification(I18N::translate('Type')), 443 'FAM:*:WIFE' => new EmptyElement(I18N::translate('Wife'), ['AGE' => '0:1']), 444 'FAM:*:WIFE:AGE' => new AgeAtEvent(I18N::translate('Wife’s age')), 445 'FAM:*:WWW' => new AddressWebPage(I18N::translate('URL')), 446 'FAM:ANUL' => new Annulment(I18N::translate('Annulment')), 447 'FAM:CENS' => new FamilyCensus(I18N::translate('Family census')), 448 'FAM:CHAN' => new Change(I18N::translate('Last change')), 449 'FAM:CHAN:DATE' => new ChangeDate(I18N::translate('Date of last change')), 450 'FAM:CHAN:DATE:TIME' => new TimeValueNow(I18N::translate('Time of last change')), 451 'FAM:CHAN:NOTE' => new NoteStructure(I18N::translate('Note on last change')), 452 'FAM:CHIL' => new XrefIndividual(I18N::translate('Child')), 453 'FAM:DIV' => new Divorce(I18N::translate('Divorce')), 454 'FAM:DIV:DATE' => new DateValue(I18N::translate('Date of divorce')), 455 'FAM:DIVF' => new DivorceFiled(I18N::translate('Divorce filed')), 456 'FAM:ENGA' => new Engagement(I18N::translate('Engagement')), 457 'FAM:ENGA:DATE' => new DateValue(I18N::translate('Date of engagement')), 458 'FAM:ENGA:PLAC' => new PlaceName(I18N::translate('Place of engagement')), 459 'FAM:EVEN' => new FamilyEvent(I18N::translate('Event')), 460 'FAM:EVEN:TYPE' => new EventOrFactClassification(I18N::translate('Type of event')), 461 'FAM:HUSB' => new XrefIndividual(I18N::translate('Husband')), 462 'FAM:MARB' => new MarriageBanns(I18N::translate('Marriage banns')), 463 'FAM:MARB:DATE' => new DateValue(I18N::translate('Date of marriage banns')), 464 'FAM:MARB:PLAC' => new PlaceName(I18N::translate('Place of marriage banns')), 465 'FAM:MARC' => new MarriageContract(I18N::translate('Marriage contract')), 466 'FAM:MARL' => new MarriageLicence(I18N::translate('Marriage license')), 467 'FAM:MARR' => new Marriage(I18N::translate('Marriage')), 468 'FAM:MARR:DATE' => new DateValue(I18N::translate('Date of marriage')), 469 'FAM:MARR:PLAC' => new PlaceName(I18N::translate('Place of marriage')), 470 'FAM:MARR:TYPE' => new MarriageType(I18N::translate('Type of marriage')), 471 'FAM:MARS' => new MarriageSettlement(I18N::translate('Marriage settlement')), 472 'FAM:NCHI' => new CountOfChildrenFam(I18N::translate('Number of children')), 473 'FAM:NOTE' => new NoteStructure(I18N::translate('Note')), 474 'FAM:OBJE' => new XrefMedia(I18N::translate('Media object')), 475 'FAM:REFN' => new UserReferenceNumber(I18N::translate('Reference number')), 476 'FAM:REFN:TYPE' => new UserReferenceType(I18N::translate('Type of reference number')), 477 'FAM:RESI' => new Residence(I18N::translate('Family residence')), 478 'FAM:RESN' => new RestrictionNotice(I18N::translate('Restriction')), 479 'FAM:RIN' => new AutomatedRecordId(I18N::translate('Record ID number')), 480 'FAM:SLGS' => new LdsSpouseSealing(I18N::translate('LDS spouse sealing')), 481 'FAM:SLGS:DATE' => new DateLdsOrd(I18N::translate('Date of LDS spouse sealing')), 482 'FAM:SLGS:PLAC' => new PlaceLivingOrdinance(I18N::translate('Place of LDS spouse sealing')), 483 'FAM:SLGS:STAT' => new LdsSpouseSealingDateStatus(I18N::translate('Status')), 484 'FAM:SLGS:STAT:DATE' => new DateValueExact(I18N::translate('Status change date')), 485 'FAM:SLGS:TEMP' => new TempleCode(I18N::translate('Temple')), 486 'FAM:SOUR' => new XrefSource(I18N::translate('Source citation')), 487 'FAM:SOUR:DATA' => new SourceData(I18N::translate('Data')), 488 'FAM:SOUR:DATA:DATE' => new DateValue(I18N::translate('Date of entry in original source')), 489 'FAM:SOUR:DATA:TEXT' => new TextFromSource(I18N::translate('Text')), 490 'FAM:SOUR:EVEN' => new EventTypeCitedFrom(I18N::translate('Event')), 491 'FAM:SOUR:EVEN:ROLE' => new RoleInEvent(I18N::translate('Role')), 492 'FAM:SOUR:NOTE' => new NoteStructure(I18N::translate('Note on source citation')), 493 'FAM:SOUR:OBJE' => new XrefMedia(I18N::translate('Media object')), 494 'FAM:SOUR:PAGE' => new WhereWithinSource(I18N::translate('Citation details')), 495 'FAM:SOUR:QUAY' => new CertaintyAssessment(I18N::translate('Quality of data')), 496 'FAM:SUBM' => new XrefSubmitter(I18N::translate('Submitter')), 497 'FAM:WIFE' => new XrefIndividual(I18N::translate('Wife')), 498 'HEAD' => new HeaderRecord(I18N::translate('Header')), 499 'HEAD:CHAR' => new CharacterSet(I18N::translate('Character set')), 500 'HEAD:CHAR:VERS' => new VersionNumber(I18N::translate('Version')), 501 'HEAD:COPR' => new CopyrightFile(I18N::translate('Copyright')), 502 'HEAD:DATE' => new TransmissionDate(I18N::translate('Date')), 503 'HEAD:DATE:TIME' => new TimeValueNow(I18N::translate('Time')), 504 'HEAD:DEST' => new ReceivingSystemName(I18N::translate('Destination')), 505 'HEAD:FILE' => new FileName(I18N::translate('Filename')), 506 'HEAD:GEDC' => new GedcomElement(I18N::translate('GEDCOM')), 507 'HEAD:GEDC:FORM' => new Form(I18N::translate('Format')), 508 'HEAD:GEDC:VERS' => new VersionNumber(I18N::translate('Version')), 509 'HEAD:LANG' => new LanguageId(I18N::translate('Language')), 510 'HEAD:NOTE' => new ContentDescription(I18N::translate('Note')), 511 'HEAD:PLAC' => new EmptyElement(I18N::translate('Place hierarchy'), ['FORM' => '1:1']), 512 'HEAD:PLAC:FORM' => new PlaceHierarchy(I18N::translate('Format')), 513 'HEAD:SOUR' => new ApprovedSystemId(I18N::translate('Application ID')), 514 'HEAD:SOUR:CORP' => new NameOfBusiness(I18N::translate('Corporation')), 515 'HEAD:SOUR:CORP:ADDR' => new AddressLine(I18N::translate('Address')), 516 'HEAD:SOUR:CORP:ADDR:ADR1' => new AddressLine1(I18N::translate('Address line 1')), 517 'HEAD:SOUR:CORP:ADDR:ADR2' => new AddressLine2(I18N::translate('Address line 2')), 518 'HEAD:SOUR:CORP:ADDR:ADR3' => new AddressLine3(I18N::translate('Address line 3')), 519 'HEAD:SOUR:CORP:ADDR:CITY' => new AddressCity(I18N::translate('City')), 520 'HEAD:SOUR:CORP:ADDR:CTRY' => new AddressCountry(I18N::translate('Country')), 521 'HEAD:SOUR:CORP:ADDR:POST' => new AddressPostalCode(I18N::translate('Postal code')), 522 'HEAD:SOUR:CORP:ADDR:STAE' => new AddressState(I18N::translate('State')), 523 'HEAD:SOUR:CORP:EMAIL' => new AddressEmail(I18N::translate('Email address')), 524 'HEAD:SOUR:CORP:FAX' => new AddressFax(I18N::translate('Fax')), 525 'HEAD:SOUR:CORP:PHON' => new PhoneNumber(I18N::translate('Phone')), 526 'HEAD:SOUR:CORP:WWW' => new AddressWebPage(I18N::translate('URL')), 527 'HEAD:SOUR:DATA' => new NameOfSourceData(I18N::translate('Data')), 528 'HEAD:SOUR:DATA:COPR' => new CopyrightSourceData(I18N::translate('Copyright')), 529 'HEAD:SOUR:DATA:DATE' => new PublicationDate(I18N::translate('Date')), 530 'HEAD:SOUR:NAME' => new NameOfProduct(I18N::translate('Application name')), 531 'HEAD:SOUR:VERS' => new VersionNumber(I18N::translate('Version')), 532 'HEAD:SUBM' => new XrefSubmitter(I18N::translate('Submitter')), 533 'HEAD:SUBN' => new XrefSubmission(I18N::translate('Submission')), 534 'INDI' => new IndividualRecord(I18N::translate('Individual')), 535 'INDI:*:ADDR' => new AddressLine(I18N::translate('Address')), 536 'INDI:*:ADDR:ADR1' => new AddressLine1(I18N::translate('Address line 1')), 537 'INDI:*:ADDR:ADR2' => new AddressLine2(I18N::translate('Address line 2')), 538 'INDI:*:ADDR:ADR3' => new AddressLine3(I18N::translate('Address line 3')), 539 'INDI:*:ADDR:CITY' => new AddressCity(I18N::translate('City')), 540 'INDI:*:ADDR:CTRY' => new AddressCountry(I18N::translate('Country')), 541 'INDI:*:ADDR:POST' => new AddressPostalCode(I18N::translate('Postal code')), 542 'INDI:*:ADDR:STAE' => new AddressState(I18N::translate('State')), 543 'INDI:*:AGE' => new AgeAtEvent(I18N::translate('Age')), 544 'INDI:*:AGNC' => new ResponsibleAgency(I18N::translate('Agency')), 545 'INDI:*:CAUS' => new CauseOfEvent(I18N::translate('Cause')), 546 'INDI:*:DATE' => new DateValue(I18N::translate('Date')), 547 'INDI:*:EMAIL' => new AddressEmail(I18N::translate('Email address')), 548 'INDI:*:FAX' => new AddressFax(I18N::translate('Fax')), 549 'INDI:*:NOTE' => new NoteStructure(I18N::translate('Note')), 550 'INDI:*:OBJE' => new XrefMedia(I18N::translate('Media object')), 551 'INDI:*:PHON' => new PhoneNumber(I18N::translate('Phone')), 552 'INDI:*:PLAC' => new PlaceName(I18N::translate('Place')), 553 'INDI:*:PLAC:FONE' => new PlacePhoneticVariation(I18N::translate('Phonetic place')), 554 'INDI:*:PLAC:FONE:TYPE' => new PhoneticType(I18N::translate('Type')), 555 'INDI:*:PLAC:FORM' => new PlaceHierarchy(I18N::translate('Format')), 556 'INDI:*:PLAC:MAP' => new Coordinates(I18N::translate('Coordinates')), 557 'INDI:*:PLAC:MAP:LATI' => new PlaceLatitude(I18N::translate('Latitude')), 558 'INDI:*:PLAC:MAP:LONG' => new PlaceLongtitude(I18N::translate('Longitude')), 559 'INDI:*:PLAC:NOTE' => new NoteStructure(I18N::translate('Note on place')), 560 'INDI:*:PLAC:ROMN' => new PlaceRomanizedVariation(I18N::translate('Romanized place')), 561 'INDI:*:PLAC:ROMN:TYPE' => new RomanizedType(I18N::translate('Type')), 562 'INDI:*:RELI' => new ReligiousAffiliation(I18N::translate('Religion'), []), 563 'INDI:*:RESN' => new RestrictionNotice(I18N::translate('Restriction')), 564 'INDI:*:SOUR' => new XrefSource(I18N::translate('Source citation')), 565 'INDI:*:SOUR:DATA' => new SourceData(I18N::translate('Data')), 566 'INDI:*:SOUR:DATA:DATE' => new DateValue(I18N::translate('Date of entry in original source')), 567 'INDI:*:SOUR:DATA:TEXT' => new TextFromSource(I18N::translate('Text')), 568 'INDI:*:SOUR:EVEN' => new EventTypeCitedFrom(I18N::translate('Event')), 569 'INDI:*:SOUR:EVEN:ROLE' => new RoleInEvent(I18N::translate('Role')), 570 'INDI:*:SOUR:NOTE' => new NoteStructure(I18N::translate('Note on source citation')), 571 'INDI:*:SOUR:OBJE' => new XrefMedia(I18N::translate('Media object')), 572 'INDI:*:SOUR:PAGE' => new WhereWithinSource(I18N::translate('Citation details')), 573 'INDI:*:SOUR:QUAY' => new CertaintyAssessment(I18N::translate('Quality of data')), 574 'INDI:*:TYPE' => new EventOrFactClassification(I18N::translate('Type')), 575 'INDI:*:WWW' => new AddressWebPage(I18N::translate('URL')), 576 'INDI:ADOP' => new Adoption(I18N::translate('Adoption')), 577 'INDI:ADOP:DATE' => new DateValue(I18N::translate('Date of adoption')), 578 'INDI:ADOP:FAMC' => new XrefFamily(I18N::translate('Adoptive parents'), ['ADOP' => '0:1']), 579 'INDI:ADOP:FAMC:ADOP' => new AdoptedByWhichParent(I18N::translate('Adoption')), 580 'INDI:ADOP:PLAC' => new PlaceName(I18N::translate('Place of adoption')), 581 'INDI:AFN' => new AncestralFileNumber(I18N::translate('Ancestral file number')), 582 'INDI:ALIA' => new XrefIndividual(I18N::translate('Alias')), 583 'INDI:ANCI' => new XrefSubmitter(I18N::translate('Ancestors interest')), 584 'INDI:ASSO' => new XrefAssociate(I18N::translate('Associate')), 585 'INDI:ASSO:RELA' => new RelationIsDescriptor(I18N::translate('Relationship')), 586 'INDI:BAPL' => new LdsBaptism(I18N::translate('LDS baptism')), 587 'INDI:BAPL:DATE' => new DateLdsOrd(I18N::translate('Date of LDS baptism')), 588 'INDI:BAPL:PLAC' => new PlaceLivingOrdinance(I18N::translate('Place of LDS baptism')), 589 'INDI:BAPL:STAT' => new LdsBaptismDateStatus(I18N::translate('Status')), 590 'INDI:BAPL:STAT:DATE' => new DateValueExact(I18N::translate('Status change date')), 591 'INDI:BAPL:TEMP' => new TempleCode(I18N::translate('Temple')), 592 'INDI:BAPM' => new Baptism(I18N::translate('Baptism')), 593 'INDI:BAPM:DATE' => new DateValue(I18N::translate('Date of baptism')), 594 'INDI:BAPM:PLAC' => new PlaceName(I18N::translate('Place of baptism')), 595 'INDI:BARM' => new BarMitzvah(I18N::translate('Bar mitzvah')), 596 'INDI:BARM:DATE' => new DateValue(I18N::translate('Date of bar mitzvah')), 597 'INDI:BARM:PLAC' => new PlaceName(I18N::translate('Place of bar mitzvah')), 598 'INDI:BASM' => new BasMitzvah(I18N::translate('Bat mitzvah')), 599 'INDI:BASM:DATE' => new DateValue(I18N::translate('Date of bat mitzvah')), 600 'INDI:BASM:PLAC' => new PlaceName(I18N::translate('Place of bat mitzvah')), 601 'INDI:BIRT' => new Birth(I18N::translate('Birth')), 602 'INDI:BIRT:DATE' => new DateValue(I18N::translate('Date of birth')), 603 'INDI:BIRT:FAMC' => new XrefFamily(I18N::translate('Birth parents')), 604 'INDI:BIRT:PLAC' => new PlaceName(I18N::translate('Place of birth')), 605 'INDI:BLES' => new Blessing(I18N::translate('Blessing')), 606 'INDI:BLES:DATE' => new DateValue(I18N::translate('Date of blessing')), 607 'INDI:BLES:PLAC' => new PlaceName(I18N::translate('Place of blessing')), 608 'INDI:BURI' => new Burial(I18N::translate('Burial')), 609 'INDI:BURI:DATE' => new DateValue(I18N::translate('Date of burial')), 610 'INDI:BURI:PLAC' => new PlaceName(I18N::translate('Place of burial')), 611 'INDI:CAST' => new CasteName(I18N::translate('Caste')), 612 'INDI:CENS' => new Census(I18N::translate('Census')), 613 'INDI:CENS:DATE' => new DateValue(I18N::translate('Census date')), 614 'INDI:CENS:PLAC' => new PlaceName(I18N::translate('Census place')), 615 'INDI:CHAN' => new Change(I18N::translate('Last change')), 616 'INDI:CHAN:DATE' => new ChangeDate(I18N::translate('Date of last change')), 617 'INDI:CHAN:DATE:TIME' => new TimeValueNow(I18N::translate('Time of last change')), 618 'INDI:CHAN:NOTE' => new NoteStructure(I18N::translate('Note on last change')), 619 'INDI:CHR' => new Christening(I18N::translate('Christening')), 620 'INDI:CHR:DATE' => new DateValue(I18N::translate('Date of christening')), 621 'INDI:CHR:FAMC' => new XrefFamily(I18N::translate('Godparents')), 622 'INDI:CHR:PLAC' => new PlaceName(I18N::translate('Place of christening')), 623 'INDI:CHRA' => new AdultChristening(I18N::translate('Adult christening')), 624 'INDI:CHRA:PLAC' => new PlaceName(I18N::translate('Place of christening')), 625 'INDI:CONF' => new Confirmation(I18N::translate('Confirmation')), 626 'INDI:CONF:DATE' => new DateValue(I18N::translate('Date of confirmation')), 627 'INDI:CONF:PLAC' => new PlaceName(I18N::translate('Place of confirmation')), 628 'INDI:CONL' => new LdsConfirmation(I18N::translate('LDS confirmation')), 629 'INDI:CONL:DATE' => new DateLdsOrd(I18N::translate('Date of LDS confirmation')), 630 'INDI:CONL:PLAC' => new PlaceLivingOrdinance(I18N::translate('Place of LDS confirmation')), 631 'INDI:CONL:STAT' => new LdsBaptismDateStatus(I18N::translate('Status')), 632 'INDI:CONL:STAT:DATE' => new DateValueExact(I18N::translate('Status change date')), 633 'INDI:CONL:TEMP' => new TempleCode(I18N::translate('Temple')), 634 'INDI:CREM' => new Cremation(I18N::translate('Cremation')), 635 'INDI:CREM:DATE' => new DateValue(I18N::translate('Date of cremation')), 636 'INDI:CREM:PLAC' => new PlaceName(I18N::translate('Place of cremation')), 637 'INDI:DEAT' => new Death(I18N::translate('Death')), 638 'INDI:DEAT:CAUS' => new CauseOfEvent(I18N::translate('Cause of death')), 639 'INDI:DEAT:DATE' => new DateValue(I18N::translate('Date of death')), 640 'INDI:DEAT:PLAC' => new PlaceName(I18N::translate('Place of death')), 641 'INDI:DESI' => new XrefSubmitter(I18N::translate('Descendants interest')), 642 'INDI:DSCR' => new PhysicalDescription(I18N::translate('Description')), 643 'INDI:EDUC' => new ScholasticAchievement(I18N::translate('Education')), 644 'INDI:EDUC:AGNC' => new ResponsibleAgency(I18N::translate('School or college')), 645 'INDI:EMIG' => new Emigration(I18N::translate('Emigration')), 646 'INDI:EMIG:DATE' => new DateValue(I18N::translate('Date of emigration')), 647 'INDI:EMIG:PLAC' => new PlaceName(I18N::translate('Place of emigration')), 648 'INDI:ENDL' => new LdsEndowment(I18N::translate('LDS endowment')), 649 'INDI:ENDL:DATE' => new DateLdsOrd(I18N::translate('Date of LDS endowment')), 650 'INDI:ENDL:PLAC' => new PlaceLivingOrdinance(I18N::translate('Place of LDS endowment')), 651 'INDI:ENDL:STAT' => new LdsEndowmentDateStatus(I18N::translate('Status')), 652 'INDI:ENDL:STAT:DATE' => new DateValueExact(I18N::translate('Status change date')), 653 'INDI:ENDL:TEMP' => new TempleCode(I18N::translate('Temple')), 654 'INDI:EVEN' => new IndividualEvent(I18N::translate('Event')), 655 'INDI:EVEN:DATE' => new DateValue(I18N::translate('Date of event')), 656 'INDI:EVEN:PLAC' => new PlaceName(I18N::translate('Place of event')), 657 'INDI:EVEN:TYPE' => new EventOrFactClassification(I18N::translate('Type of event')), 658 'INDI:FACT' => new IndividualFact(I18N::translate('Fact')), 659 'INDI:FACT:TYPE' => new EventOrFactClassification(I18N::translate('Type of fact')), 660 'INDI:FAMC' => new XrefFamily(I18N::translate('Family as a child'), ['NOTE' => '0:1', 'PEDI' => '0:1', 'STAT' => '0:1']), 661 'INDI:FAMC:PEDI' => new PedigreeLinkageType(I18N::translate('Relationship to parents')), 662 'INDI:FAMC:STAT' => new ChildLinkageStatus(I18N::translate('Status')), 663 'INDI:FAMS' => new XrefFamily(I18N::translate('Family as a spouse')), 664 'INDI:FCOM' => new FirstCommunion(I18N::translate('First communion')), 665 'INDI:FCOM:DATE' => new DateValue(I18N::translate('Date of first communion')), 666 'INDI:FCOM:PLAC' => new PlaceName(I18N::translate('Place of first communion')), 667 'INDI:GRAD' => new Graduation(I18N::translate('Graduation')), 668 'INDI:GRAD:AGNC' => new ResponsibleAgency(I18N::translate('School or college')), 669 'INDI:IDNO' => new NationalIdNumber(I18N::translate('Identification number')), 670 'INDI:IDNO:TYPE' => new EventOrFactClassification(I18N::translate('Type of identification number')), 671 'INDI:IMMI' => new Immigration(I18N::translate('Immigration')), 672 'INDI:IMMI:DATE' => new DateValue(I18N::translate('Date of immigration')), 673 'INDI:IMMI:PLAC' => new PlaceName(I18N::translate('Place of immigration')), 674 'INDI:NAME' => new NamePersonal(I18N::translate('Name')), 675 'INDI:NAME:*:SOUR' => new XrefSource(I18N::translate('Source citation')), 676 'INDI:NAME:*:SOUR:DATA' => new SourceData(I18N::translate('Data')), 677 'INDI:NAME:*:SOUR:DATA:DATE' => new DateValue(I18N::translate('Date of entry in original source')), 678 'INDI:NAME:*:SOUR:DATA:TEXT' => new TextFromSource(I18N::translate('Text')), 679 'INDI:NAME:*:SOUR:EVEN' => new EventTypeCitedFrom(I18N::translate('Event')), 680 'INDI:NAME:*:SOUR:EVEN:ROLE' => new RoleInEvent(I18N::translate('Role')), 681 'INDI:NAME:*:SOUR:NOTE' => new NoteStructure(I18N::translate('Note on source citation')), 682 'INDI:NAME:*:SOUR:OBJE' => new XrefMedia(I18N::translate('Media object')), 683 'INDI:NAME:*:SOUR:PAGE' => new WhereWithinSource(I18N::translate('Citation details')), 684 'INDI:NAME:*:SOUR:QUAY' => new CertaintyAssessment(I18N::translate('Quality of data')), 685 'INDI:NAME:FONE' => new NamePhoneticVariation(I18N::translate('Phonetic name')), 686 'INDI:NAME:FONE:GIVN' => new NamePieceGiven(I18N::translate('Given names')), 687 'INDI:NAME:FONE:NICK' => new NamePieceNickname(I18N::translate('Nickname')), 688 'INDI:NAME:FONE:NOTE' => new NoteStructure(I18N::translate('Note on phonetic name')), 689 'INDI:NAME:FONE:NPFX' => new NamePiecePrefix(I18N::translate('Name prefix')), 690 'INDI:NAME:FONE:NSFX' => new NamePieceSuffix(I18N::translate('Name suffix')), 691 'INDI:NAME:FONE:SOUR' => new XrefSource(I18N::translate('Source citation')), 692 'INDI:NAME:FONE:SPFX' => new NamePieceSurnamePrefix(I18N::translate('Surname prefix')), 693 'INDI:NAME:FONE:SURN' => new NamePieceSurname(I18N::translate('Surname')), 694 'INDI:NAME:FONE:TYPE' => new PhoneticType(I18N::translate('Phonetic type')), 695 'INDI:NAME:GIVN' => new NamePieceGiven(I18N::translate('Given names')), 696 'INDI:NAME:NICK' => new NamePieceNickname(I18N::translate('Nickname')), 697 'INDI:NAME:NPFX' => new NamePiecePrefix(I18N::translate('Name prefix')), 698 'INDI:NAME:NSFX' => new NamePieceSuffix(I18N::translate('Name suffix')), 699 'INDI:NAME:ROMN' => new NameRomanizedVariation(I18N::translate('Romanized name')), 700 'INDI:NAME:ROMN:GIVN' => new NamePieceGiven(I18N::translate('Given names')), 701 'INDI:NAME:ROMN:NICK' => new NamePieceNickname(I18N::translate('Nickname')), 702 'INDI:NAME:ROMN:NOTE' => new NoteStructure(I18N::translate('Note on romanized name')), 703 'INDI:NAME:ROMN:NPFX' => new NamePiecePrefix(I18N::translate('Name prefix')), 704 'INDI:NAME:ROMN:NSFX' => new NamePieceSuffix(I18N::translate('Name suffix')), 705 'INDI:NAME:ROMN:SOUR' => new XrefSource(I18N::translate('Source citation')), 706 'INDI:NAME:ROMN:SPFX' => new NamePieceSurnamePrefix(I18N::translate('Surname prefix')), 707 'INDI:NAME:ROMN:SURN' => new NamePieceSurname(I18N::translate('Surname')), 708 'INDI:NAME:ROMN:TYPE' => new RomanizedType(I18N::translate('Romanized type')), 709 'INDI:NAME:SPFX' => new NamePieceSurnamePrefix(I18N::translate('Surname prefix')), 710 'INDI:NAME:SURN' => new NamePieceSurname(I18N::translate('Surname')), 711 'INDI:NAME:TYPE' => new NameType(I18N::translate('Type of name')), 712 'INDI:NATI' => new NationalOrTribalOrigin(I18N::translate('Nationality')), 713 'INDI:NATU' => new Naturalization(I18N::translate('Naturalization')), 714 'INDI:NATU:DATE' => new DateValue(I18N::translate('Date of naturalization')), 715 'INDI:NATU:PLAC' => new PlaceName(I18N::translate('Place of naturalization')), 716 'INDI:NCHI' => new CountOfChildren(I18N::translate('Number of children')), 717 'INDI:NMR' => new CountOfMarriages(I18N::translate('Number of marriages')), 718 'INDI:NOTE' => new NoteStructure(I18N::translate('Note')), 719 'INDI:OBJE' => new XrefMedia(I18N::translate('Media object')), 720 'INDI:OCCU' => new Occupation(I18N::translate('Occupation')), 721 'INDI:OCCU:AGNC' => new ResponsibleAgency(I18N::translate('Employer')), 722 'INDI:ORDN' => new Ordination(I18N::translate('Ordination')), 723 'INDI:ORDN:AGNC' => new ResponsibleAgency(I18N::translate('Religious institution')), 724 'INDI:ORDN:DATE' => new DateValue(I18N::translate('Date of ordination')), 725 'INDI:ORDN:PLAC' => new PlaceName(I18N::translate('Place of ordination')), 726 'INDI:PROB' => new Probate(I18N::translate('Probate')), 727 'INDI:PROP' => new Possessions(I18N::translate('Property')), 728 'INDI:REFN' => new UserReferenceNumber(I18N::translate('Reference number')), 729 'INDI:REFN:TYPE' => new UserReferenceType(I18N::translate('Type of reference number')), 730 'INDI:RELI' => new ReligiousAffiliation(I18N::translate('Religion')), 731 'INDI:RESI' => new Residence(I18N::translate('Residence')), 732 'INDI:RESI:DATE' => new DateValue(I18N::translate('Date of residence')), 733 'INDI:RESI:PLAC' => new PlaceName(I18N::translate('Place of residence')), 734 'INDI:RESN' => new RestrictionNotice(I18N::translate('Restriction')), 735 'INDI:RETI' => new Retirement(I18N::translate('Retirement')), 736 'INDI:RETI:AGNC' => new ResponsibleAgency(I18N::translate('Employer')), 737 'INDI:RFN' => new PermanentRecordFileNumber(I18N::translate('Record file number')), 738 'INDI:RIN' => new AutomatedRecordId(I18N::translate('Record ID number')), 739 'INDI:SEX' => new SexValue(I18N::translate('Gender')), 740 'INDI:SLGC' => new LdsChildSealing(I18N::translate('LDS child sealing')), 741 'INDI:SLGC:DATE' => new DateLdsOrd(I18N::translate('Date of LDS child sealing')), 742 'INDI:SLGC:FAMC' => new XrefFamily(I18N::translate('Parents')), 743 'INDI:SLGC:PLAC' => new PlaceLivingOrdinance(I18N::translate('Place of LDS child sealing')), 744 'INDI:SLGC:STAT' => new LdsChildSealingDateStatus(I18N::translate('Status')), 745 'INDI:SLGC:STAT:DATE' => new DateValueExact(I18N::translate('Status change date')), 746 'INDI:SLGC:TEMP' => new TempleCode(I18N::translate('Temple')), 747 'INDI:SOUR' => new XrefSource(I18N::translate('Source citation')), 748 'INDI:SOUR:DATA' => new SourceData(I18N::translate('Data')), 749 'INDI:SOUR:DATA:DATE' => new DateValue(I18N::translate('Date of entry in original source')), 750 'INDI:SOUR:DATA:TEXT' => new TextFromSource(I18N::translate('Text')), 751 'INDI:SOUR:EVEN' => new EventTypeCitedFrom(I18N::translate('Event')), 752 'INDI:SOUR:EVEN:ROLE' => new RoleInEvent(I18N::translate('Role')), 753 'INDI:SOUR:NOTE' => new NoteStructure(I18N::translate('Note on source citation')), 754 'INDI:SOUR:OBJE' => new XrefMedia(I18N::translate('Media object')), 755 'INDI:SOUR:PAGE' => new WhereWithinSource(I18N::translate('Citation details')), 756 'INDI:SOUR:QUAY' => new CertaintyAssessment(I18N::translate('Quality of data')), 757 'INDI:SSN' => new SocialSecurityNumber(I18N::translate('Social security number')), 758 'INDI:SUBM' => new XrefSubmitter(I18N::translate('Submitter')), 759 'INDI:TITL' => new NobilityTypeTitle(I18N::translate('Title')), 760 'INDI:WILL' => new Will(I18N::translate('Will')), 761 'NOTE' => new NoteRecord(I18N::translate('Shared note')), 762 'NOTE:CHAN' => new Change(I18N::translate('Last change')), 763 'NOTE:CHAN:DATE' => new ChangeDate(I18N::translate('Date of last change')), 764 'NOTE:CHAN:DATE:TIME' => new TimeValueNow(I18N::translate('Time of last change')), 765 'NOTE:CHAN:NOTE' => new NoteStructure(I18N::translate('Note on last change')), 766 'NOTE:CONC' => new SubmitterText(I18N::translate('Note')), 767 'NOTE:CONT' => new SubmitterText(I18N::translate('Continuation')), 768 'NOTE:REFN' => new UserReferenceNumber(I18N::translate('Reference number')), 769 'NOTE:REFN:TYPE' => new UserReferenceType(I18N::translate('Type of reference number')), 770 'NOTE:RIN' => new AutomatedRecordId(I18N::translate('Record ID number')), 771 'NOTE:SOUR' => new XrefSource(I18N::translate('Source citation')), 772 'NOTE:SOUR:DATA' => new SourceData(I18N::translate('Data')), 773 'NOTE:SOUR:DATA:DATE' => new DateValue(I18N::translate('Date of entry in original source')), 774 'NOTE:SOUR:DATA:TEXT' => new TextFromSource(I18N::translate('Text')), 775 'NOTE:SOUR:EVEN' => new EventTypeCitedFrom(I18N::translate('Event')), 776 'NOTE:SOUR:EVEN:ROLE' => new RoleInEvent(I18N::translate('Role')), 777 'NOTE:SOUR:NOTE' => new NoteStructure(I18N::translate('Note on source citation')), 778 'NOTE:SOUR:OBJE' => new XrefMedia(I18N::translate('Media object')), 779 'NOTE:SOUR:PAGE' => new WhereWithinSource(I18N::translate('Citation details')), 780 'NOTE:SOUR:QUAY' => new CertaintyAssessment(I18N::translate('Quality of data')), 781 'OBJE' => new MediaRecord(I18N::translate('Media object')), 782 'OBJE:BLOB' => new CustomElement(I18N::translate('Binary data object')), 783 'OBJE:CHAN' => new Change(I18N::translate('Last change')), 784 'OBJE:CHAN:DATE' => new ChangeDate(I18N::translate('Date of last change')), 785 'OBJE:CHAN:DATE:TIME' => new TimeValueNow(I18N::translate('Time of last change')), 786 'OBJE:CHAN:NOTE' => new NoteStructure(I18N::translate('Note on last change')), 787 'OBJE:FILE' => new MultimediaFileReference(I18N::translate('Filename')), 788 'OBJE:FILE:FORM' => new MultimediaFormat(I18N::translate('Format')), 789 'OBJE:FILE:FORM:TYPE' => new SourceMediaType(I18N::translate('Media type')), 790 'OBJE:FILE:TITL' => new DescriptiveTitle(I18N::translate('Title')), 791 'OBJE:NOTE' => new NoteStructure(I18N::translate('Note')), 792 'OBJE:REFN' => new UserReferenceNumber(I18N::translate('Reference number')), 793 'OBJE:REFN:TYPE' => new UserReferenceType(I18N::translate('Type of reference number')), 794 'OBJE:RIN' => new AutomatedRecordId(I18N::translate('Record ID number')), 795 'OBJE:SOUR' => new XrefSource(I18N::translate('Source citation')), 796 'OBJE:SOUR:DATA' => new SourceData(I18N::translate('Data')), 797 'OBJE:SOUR:DATA:DATE' => new DateValue(I18N::translate('Date of entry in original source')), 798 'OBJE:SOUR:DATA:TEXT' => new TextFromSource(I18N::translate('Text')), 799 'OBJE:SOUR:EVEN' => new EventTypeCitedFrom(I18N::translate('Event')), 800 'OBJE:SOUR:EVEN:ROLE' => new RoleInEvent(I18N::translate('Role')), 801 'OBJE:SOUR:NOTE' => new NoteStructure(I18N::translate('Note on source citation')), 802 'OBJE:SOUR:OBJE' => new XrefMedia(I18N::translate('Media object')), 803 'OBJE:SOUR:PAGE' => new WhereWithinSource(I18N::translate('Citation details')), 804 'OBJE:SOUR:QUAY' => new CertaintyAssessment(I18N::translate('Quality of data')), 805 'REPO' => new RepositoryRecord(I18N::translate('Repository')), 806 'REPO:ADDR' => new AddressLine(I18N::translate('Address')), 807 'REPO:ADDR:ADR1' => new AddressLine1(I18N::translate('Address line 1')), 808 'REPO:ADDR:ADR2' => new AddressLine2(I18N::translate('Address line 2')), 809 'REPO:ADDR:ADR3' => new AddressLine3(I18N::translate('Address line 3')), 810 'REPO:ADDR:CITY' => new AddressCity(I18N::translate('City')), 811 'REPO:ADDR:CTRY' => new AddressCountry(I18N::translate('Country')), 812 'REPO:ADDR:POST' => new AddressPostalCode(I18N::translate('Postal code')), 813 'REPO:ADDR:STAE' => new AddressState(I18N::translate('State')), 814 'REPO:CHAN' => new Change(I18N::translate('Last change')), 815 'REPO:CHAN:DATE' => new ChangeDate(I18N::translate('Date of last change')), 816 'REPO:CHAN:DATE:TIME' => new TimeValueNow(I18N::translate('Time of last change')), 817 'REPO:CHAN:NOTE' => new NoteStructure(I18N::translate('Note on last change')), 818 'REPO:EMAIL' => new AddressEmail(I18N::translate('Email address')), 819 'REPO:FAX' => new AddressFax(I18N::translate('Fax')), 820 'REPO:NAME' => new NameOfRepository(I18N::translateContext('Repository', 'Name')), 821 'REPO:NOTE' => new NoteStructure(I18N::translate('Note')), 822 'REPO:PHON' => new PhoneNumber(I18N::translate('Phone')), 823 'REPO:REFN' => new UserReferenceNumber(I18N::translate('Reference number')), 824 'REPO:REFN:TYPE' => new UserReferenceType(I18N::translate('Type of reference number')), 825 'REPO:RIN' => new AutomatedRecordId(I18N::translate('Record ID number')), 826 'REPO:WWW' => new AddressWebPage(I18N::translate('URL')), 827 'SOUR' => new SourceRecord(I18N::translate('Source')), 828 'SOUR:ABBR' => new SourceFiledByEntry(I18N::translate('Abbreviation')), 829 'SOUR:AUTH' => new SourceOriginator(I18N::translate('Author')), 830 'SOUR:CHAN' => new Change(I18N::translate('Last change')), 831 'SOUR:CHAN:DATE' => new ChangeDate(I18N::translate('Date of last change')), 832 'SOUR:CHAN:DATE:TIME' => new TimeValueNow(I18N::translate('Time of last change')), 833 'SOUR:CHAN:NOTE' => new NoteStructure(I18N::translate('Note on last change')), 834 'SOUR:DATA' => new EmptyElement(I18N::translate('Data'), ['EVEN' => '0:M', 'AGNC' => '0:1', 'NOTE' => '0:M']), 835 'SOUR:DATA:AGNC' => new ResponsibleAgency(I18N::translate('Agency')), 836 'SOUR:DATA:EVEN' => new EventsRecorded(I18N::translate('Events')), 837 'SOUR:DATA:EVEN:DATE' => new DateValue(I18N::translate('Date range')), 838 'SOUR:DATA:EVEN:PLAC' => new SourceJurisdictionPlace(I18N::translate('Place'), []), 839 'SOUR:DATA:NOTE' => new NoteStructure(I18N::translate('Note on source data')), 840 'SOUR:NOTE' => new NoteStructure(I18N::translate('Note on source')), 841 'SOUR:OBJE' => new XrefMedia(I18N::translate('Media object')), 842 'SOUR:PUBL' => new SourcePublicationFacts(I18N::translate('Publication')), 843 'SOUR:REFN' => new UserReferenceNumber(I18N::translate('Reference number')), 844 'SOUR:REFN:TYPE' => new UserReferenceType(I18N::translate('Type of reference number')), 845 'SOUR:REPO' => new XrefRepository(I18N::translate('Repository')), 846 'SOUR:REPO:CALN' => new SourceCallNumber(I18N::translate('Call number')), 847 'SOUR:REPO:CALN:MEDI' => new SourceMediaType(I18N::translate('Media type')), 848 'SOUR:REPO:NOTE' => new NoteStructure(I18N::translate('Note on repository reference')), 849 'SOUR:RIN' => new AutomatedRecordId(I18N::translate('Record ID number')), 850 'SOUR:TEXT' => new TextFromSource(I18N::translate('Text')), 851 'SOUR:TITL' => new DescriptiveTitle(I18N::translate('Title')), 852 'SUBM' => new SubmitterRecord(I18N::translate('Submitter')), 853 'SUBM:ADDR' => new AddressLine(I18N::translate('Address')), 854 'SUBM:ADDR:ADR1' => new AddressLine1(I18N::translate('Address line 1')), 855 'SUBM:ADDR:ADR2' => new AddressLine2(I18N::translate('Address line 2')), 856 'SUBM:ADDR:ADR3' => new AddressLine3(I18N::translate('Address line 3')), 857 'SUBM:ADDR:CITY' => new AddressCity(I18N::translate('City')), 858 'SUBM:ADDR:CTRY' => new AddressCountry(I18N::translate('Country')), 859 'SUBM:ADDR:POST' => new AddressPostalCode(I18N::translate('Postal code')), 860 'SUBM:ADDR:STAE' => new AddressState(I18N::translate('State')), 861 'SUBM:CHAN' => new Change(I18N::translate('Last change')), 862 'SUBM:CHAN:DATE' => new ChangeDate(I18N::translate('Date of last change')), 863 'SUBM:CHAN:DATE:TIME' => new TimeValueNow(I18N::translate('Time of last change')), 864 'SUBM:CHAN:NOTE' => new NoteStructure(I18N::translate('Note on last change')), 865 'SUBM:EMAIL' => new AddressEmail(I18N::translate('Email address')), 866 'SUBM:FAX' => new AddressFax(I18N::translate('Fax')), 867 'SUBM:LANG' => new LanguageId(I18N::translate('Language')), 868 'SUBM:NAME' => new SubmitterName(I18N::translate('Name')), 869 'SUBM:NOTE' => new NoteStructure(I18N::translate('Note')), 870 'SUBM:OBJE' => new XrefMedia(I18N::translate('Media object')), 871 'SUBM:PHON' => new PhoneNumber(I18N::translate('Phone')), 872 'SUBM:RFN' => new SubmitterRegisteredRfn(I18N::translate('Record file number')), 873 'SUBM:RIN' => new AutomatedRecordId(I18N::translate('Record ID number')), 874 'SUBM:WWW' => new AddressWebPage(I18N::translate('URL')), 875 'SUBN' => new SubmissionRecord(I18N::translate('Submission')), 876 'SUBN:ANCE' => new GenerationsOfAncestors(I18N::translate('Generations of ancestors')), 877 'SUBN:CHAN' => new Change(I18N::translate('Last change')), 878 'SUBN:CHAN:DATE' => new ChangeDate(I18N::translate('Date of last change')), 879 'SUBN:CHAN:DATE:TIME' => new TimeValueNow(I18N::translate('Time of last change')), 880 'SUBN:CHAN:NOTE' => new NoteStructure(I18N::translate('Note on last change')), 881 'SUBN:DESC' => new GenerationsOfDescendants(I18N::translate('Generations of descendants')), 882 'SUBN:FAMF' => new NameOfFamilyFile(I18N::translate('Family file')), 883 'SUBN:NOTE' => new NoteStructure(I18N::translate('Note')), 884 'SUBN:ORDI' => new OrdinanceProcessFlag(I18N::translate('Ordinance')), 885 'SUBN:RIN' => new AutomatedRecordId(I18N::translate('Record ID number')), 886 'SUBN:SUBM' => new XrefSubmitter(I18N::translate('Submitter')), 887 'SUBN:TEMP' => new TempleCode(/* I18N: https://en.wikipedia.org/wiki/Temple_(LDS_Church)*/ I18N::translate('Temple')), 888 'TRLR' => new EmptyElement(I18N::translate('Trailer')), 889 ]; 890 } 891 892 /** 893 * Custom tags for webtrees. 894 * 895 * @return array<string,ElementInterface> 896 */ 897 private function webtreesTags(): array 898 { 899 return [ 900 'FAM:CHAN:_WT_USER' => new WebtreesUser(I18N::translate('Author of last change')), 901 'FAM:*:_ASSO' => new XrefAssociate(I18N::translate('Associate')), 902 'FAM:*:_ASSO:NOTE' => new NoteStructure(I18N::translate('Note on association')), 903 'FAM:*:_ASSO:RELA' => new RelationIsDescriptor(I18N::translate('Relationship')), 904 'FAM:*:_ASSO:SOUR' => new XrefSource(I18N::translate('Source citation')), 905 'FAM:*:_ASSO:SOUR:DATA' => new SourceData(I18N::translate('Data')), 906 'FAM:*:_ASSO:SOUR:DATA:DATE' => new DateValue(I18N::translate('Date of entry in original source')), 907 'FAM:*:_ASSO:SOUR:DATA:TEXT' => new TextFromSource(I18N::translate('Text')), 908 'FAM:*:_ASSO:SOUR:EVEN' => new EventTypeCitedFrom(I18N::translate('Event')), 909 'FAM:*:_ASSO:SOUR:EVEN:ROLE' => new RoleInEvent(I18N::translate('Role')), 910 'FAM:*:_ASSO:SOUR:NOTE' => new NoteStructure(I18N::translate('Note on source citation')), 911 'FAM:*:_ASSO:SOUR:OBJE' => new XrefMedia(I18N::translate('Media object')), 912 'FAM:*:_ASSO:SOUR:PAGE' => new WhereWithinSource(I18N::translate('Citation details')), 913 'FAM:*:_ASSO:SOUR:QUAY' => new CertaintyAssessment(I18N::translate('Quality of data')), 914 'INDI:CHAN:_WT_USER' => new WebtreesUser(I18N::translate('Author of last change')), 915 'INDI:*:_ASSO' => new XrefAssociate(I18N::translate('Associate')), 916 'INDI:*:_ASSO:NOTE' => new NoteStructure(I18N::translate('Note on association')), 917 'INDI:*:_ASSO:RELA' => new RelationIsDescriptor(I18N::translate('Relationship')), 918 'INDI:*:_ASSO:SOUR' => new XrefSource(I18N::translate('Source citation')), 919 'INDI:*:_ASSO:SOUR:DATA' => new SourceData(I18N::translate('Data')), 920 'INDI:*:_ASSO:SOUR:DATA:DATE' => new DateValue(I18N::translate('Date of entry in original source')), 921 'INDI:*:_ASSO:SOUR:DATA:TEXT' => new TextFromSource(I18N::translate('Text')), 922 'INDI:*:_ASSO:SOUR:EVEN' => new EventTypeCitedFrom(I18N::translate('Event')), 923 'INDI:*:_ASSO:SOUR:EVEN:ROLE' => new RoleInEvent(I18N::translate('Role')), 924 'INDI:*:_ASSO:SOUR:NOTE' => new NoteStructure(I18N::translate('Note on source citation')), 925 'INDI:*:_ASSO:SOUR:OBJE' => new XrefMedia(I18N::translate('Media object')), 926 'INDI:*:_ASSO:SOUR:PAGE' => new WhereWithinSource(I18N::translate('Citation details')), 927 'INDI:*:_ASSO:SOUR:QUAY' => new CertaintyAssessment(I18N::translate('Quality of data')), 928 'NOTE:CHAN:_WT_USER' => new WebtreesUser(I18N::translate('Author of last change')), 929 'NOTE:RESN' => new RestrictionNotice(I18N::translate('Restriction')), 930 'OBJE:CHAN:_WT_USER' => new WebtreesUser(I18N::translate('Author of last change')), 931 'OBJE:RESN' => new RestrictionNotice(I18N::translate('Restriction')), 932 'REPO:CHAN:_WT_USER' => new WebtreesUser(I18N::translate('Author of last change')), 933 'REPO:RESN' => new RestrictionNotice(I18N::translate('Restriction')), 934 'SOUR:CHAN:_WT_USER' => new WebtreesUser(I18N::translate('Author of last change')), 935 'SOUR:RESN' => new RestrictionNotice(I18N::translate('Restriction')), 936 'SUBM:CHAN:_WT_USER' => new WebtreesUser(I18N::translate('Author of last change')), 937 'SUBM:RESN' => new RestrictionNotice(I18N::translate('Restriction')), 938 '_LOC:CHAN:_WT_USER' => new WebtreesUser(I18N::translate('Author of last change')), 939 '_LOC:RESN' => new RestrictionNotice(I18N::translate('Restriction')), 940 ]; 941 } 942 943 /** 944 * @return array<string,array<int,array<int,string>>> 945 */ 946 private function webtreesSubTags(): array 947 { 948 return [ 949 'FAM' => [['_UID', '0:M']], 950 'FAM:*:SOUR:DATA' => [['TEXT', '0:1']], 951 'FAM:ANUL' => [['_ASSO', '0:M', 'NOTE']], 952 'FAM:CENS' => [['_ASSO', '0:M', 'NOTE']], 953 'FAM:CHAN' => [['_WT_USER', '0:1']], 954 'FAM:DIV' => [['_ASSO', '0:M', 'NOTE']], 955 'FAM:DIVF' => [['_ASSO', '0:M', 'NOTE']], 956 'FAM:ENGA' => [['_ASSO', '0:M', 'NOTE']], 957 'FAM:EVEN' => [['_ASSO', '0:M', 'NOTE']], 958 'FAM:MARB' => [['_ASSO', '0:M', 'NOTE']], 959 'FAM:MARC' => [['_ASSO', '0:M', 'NOTE']], 960 'FAM:MARL' => [['_ASSO', '0:M', 'NOTE']], 961 'FAM:MARR' => [['_ASSO', '2:M', 'NOTE']], 962 'FAM:MARS' => [['_ASSO', '0:M', 'NOTE']], 963 'FAM:SLGS' => [['_ASSO', '0:M', 'NOTE']], 964 'FAM:SOUR:DATA' => [['TEXT', '0:1']], 965 'INDI' => [['_UID', '0:M']], 966 'INDI:*:SOUR:DATA' => [['TEXT', '0:1']], 967 'INDI:ADOP' => [['_ASSO', '0:M', 'NOTE']], 968 'INDI:BAPL' => [['_ASSO', '0:M', 'NOTE']], 969 'INDI:BAPM' => [['_ASSO', '2:M', 'NOTE']], 970 'INDI:BARM' => [['_ASSO', '0:M', 'NOTE']], 971 'INDI:BASM' => [['_ASSO', '0:M', 'NOTE']], 972 'INDI:BIRT' => [['_ASSO', '0:M', 'NOTE'], ['FAMC', '0:0']], 973 'INDI:BURI' => [['_ASSO', '0:M', 'NOTE']], 974 'INDI:CENS' => [['_ASSO', '0:M', 'NOTE']], 975 'INDI:CHAN' => [['_WT_USER', '0:1']], 976 'INDI:CHR' => [['_ASSO', '2:M', 'NOTE']], 977 'INDI:CHRA' => [['_ASSO', '0:M', 'NOTE']], 978 'INDI:CONF' => [['_ASSO', '0:M', 'NOTE']], 979 'INDI:CONL' => [['_ASSO', '0:M', 'NOTE']], 980 'INDI:CREM' => [['_ASSO', '0:M', 'NOTE']], 981 'INDI:DEAT' => [['_ASSO', '0:M', 'NOTE']], 982 'INDI:EDUC' => [['_ASSO', '0:M', 'NOTE']], 983 'INDI:EMIG' => [['_ASSO', '0:M', 'NOTE']], 984 'INDI:ENDL' => [['_ASSO', '0:M', 'NOTE']], 985 'INDI:EVEN' => [['_ASSO', '0:M', 'NOTE']], 986 'INDI:GRAD' => [['_ASSO', '0:M', 'NOTE']], 987 'INDI:IMMI' => [['_ASSO', '0:M', 'NOTE']], 988 'INDI:NATU' => [['_ASSO', '0:M', 'NOTE']], 989 'INDI:OCCU' => [['_ASSO', '0:M', 'NOTE']], 990 'INDI:ORDN' => [['_ASSO', '0:M', 'NOTE']], 991 'INDI:PROB' => [['_ASSO', '0:M', 'NOTE']], 992 'INDI:PROP' => [['_ASSO', '0:M', 'NOTE']], 993 'INDI:RESI' => [['_ASSO', '0:M', 'NOTE']], 994 'INDI:RETI' => [['_ASSO', '0:M', 'NOTE']], 995 'INDI:SLGC' => [['_ASSO', '0:M', 'NOTE']], 996 'INDI:SOUR:DATA' => [['TEXT', '0:1']], 997 'INDI:TITL' => [['_ASSO', '0:M', 'NOTE']], 998 'INDI:WILL' => [['_ASSO', '0:M', 'NOTE']], 999 'NOTE' => [['RESN', '0:1', 'CHAN']], 1000 'NOTE:CHAN' => [['_WT_USER', '0:1']], 1001 'NOTE:SOUR:DATA' => [['TEXT', '0:1']], 1002 'OBJE' => [['RESN', '0:1', 'CHAN'], ['_UID', '0:M']], 1003 'OBJE:CHAN' => [['_WT_USER', '0:1']], 1004 'OBJE:SOUR:DATA' => [['TEXT', '0:1']], 1005 'REPO' => [['RESN', '0:1', 'CHAN'], ['_UID', '0:M']], 1006 'REPO:CHAN' => [['_WT_USER', '0:1']], 1007 'SOUR' => [['RESN', '0:1', 'CHAN'], ['_UID', '0:M']], 1008 'SOUR:CHAN' => [['_WT_USER', '0:1']], 1009 'SUBM' => [['RESN', '0:1', 'CHAN']], 1010 'SUBM:CHAN' => [['_WT_USER', '0:1']], 1011 ]; 1012 } 1013 1014 /** 1015 * @return array<string,array<int,array<int,string>>> 1016 */ 1017 private function customSubTags(): array 1018 { 1019 $custom_family_tags = array_filter(explode(',', Site::getPreference('CUSTOM_FAMILY_TAGS'))); 1020 $custom_individual_tags = array_filter(explode(',', Site::getPreference('CUSTOM_INDIVIDUAL_TAGS'))); 1021 1022 $subtags = [ 1023 'FAM' => array_map(static fn (string $tag): array => [$tag, '0:M'], $custom_family_tags), 1024 'INDI' => array_map(static fn (string $tag): array => [$tag, '0:M'], $custom_individual_tags), 1025 ]; 1026 1027 // GEDCOM 7 tags 1028 if (Site::getPreference('CUSTOM_FAM_FACT') === '1') { 1029 $subtags['FAM'][] = ['FACT', '0:M']; 1030 } 1031 if (Site::getPreference('CUSTOM_FAM_NCHI') === '1') { 1032 $subtags['FAM:NCHI'] = [ 1033 ['TYPE', '0:1:?'], 1034 ['DATE', '0:1'], 1035 ['PLAC', '0:1:?'], 1036 ['ADDR', '0:1:?'], 1037 ['EMAIL', '0:1:?'], 1038 ['WWW', '0:1:?'], 1039 ['PHON', '0:1:?'], 1040 ['FAX', '0:1:?'], 1041 ['CAUS', '0:1:?'], 1042 ['AGNC', '0:1:?'], 1043 ['RELI', '0:1:?'], 1044 ['NOTE', '0:M'], 1045 ['OBJE', '0:M'], 1046 ['SOUR', '0:M'], 1047 ['RESN', '0:1'], 1048 ]; 1049 } 1050 1051 if (Site::getPreference('CUSTOM_TIME_TAGS') === '1') { 1052 $subtags['INDI:BIRT:DATE'][] = ['TIME', '0:1']; 1053 $subtags['INDI:DEAT:DATE'][] = ['TIME', '0:1']; 1054 } 1055 1056 if (Site::getPreference('CUSTOM_GEDCOM_L_TAGS') === '1') { 1057 $subtags['FAM'][] = ['_ASSO', '0:M']; 1058 $subtags['FAM'][] = ['_STAT', '0:1']; 1059 $subtags['FAM'][] = ['_UID', '0:M']; 1060 $subtags['FAM:*:ADDR'] = [['_NAME', '0:1:?', 'ADR1']]; 1061 $subtags['FAM:*:PLAC'] = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1'], ['_GOV', '0:1']]; 1062 $subtags['FAM:ENGA:PLAC'] = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1'], ['_GOV', '0:1']]; 1063 $subtags['FAM:MARB:PLAC'] = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1'], ['_GOV', '0:1']]; 1064 $subtags['FAM:MARR'] = [['_WITN', '0:1']]; 1065 $subtags['FAM:MARR:PLAC'] = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1'], ['_GOV', '0:1']]; 1066 $subtags['FAM:SLGS:PLAC'] = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1'], ['_GOV', '0:1']]; 1067 $subtags['INDI'][] = ['_UID', '0:M']; 1068 $subtags['INDI:*:ADDR'] = [['_NAME', '0:1:?', 'ADR1']]; 1069 $subtags['INDI:*:PLAC'] = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1'], ['_GOV', '0:1']]; 1070 $subtags['INDI:ADOP:PLAC'] = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1'], ['_GOV', '0:1']]; 1071 $subtags['INDI:BAPL:PLAC'] = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1'], ['_GOV', '0:1']]; 1072 $subtags['INDI:BAPM'] = [['_GODP', '0:1'], ['_WITN', '0:1']]; 1073 $subtags['INDI:BAPM:PLAC'] = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1'], ['_GOV', '0:1']]; 1074 $subtags['INDI:BARM:PLAC'] = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1'], ['_GOV', '0:1']]; 1075 $subtags['INDI:BASM:PLAC'] = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1'], ['_GOV', '0:1']]; 1076 $subtags['INDI:BIRT:PLAC'] = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1'], ['_GOV', '0:1']]; 1077 $subtags['INDI:BLES:PLAC'] = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1'], ['_GOV', '0:1']]; 1078 $subtags['INDI:BURI:PLAC'] = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1'], ['_GOV', '0:1']]; 1079 $subtags['INDI:CENS:PLAC'] = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1'], ['_GOV', '0:1']]; 1080 $subtags['INDI:CHR'] = [['_GODP', '0:1'], ['_WITN', '0:1']]; 1081 $subtags['INDI:CHR:PLAC'] = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1'], ['_GOV', '0:1']]; 1082 $subtags['INDI:CHRA:PLAC'] = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1'], ['_GOV', '0:1']]; 1083 $subtags['INDI:CONF:PLAC'] = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1'], ['_GOV', '0:1']]; 1084 $subtags['INDI:CONL:PLAC'] = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1'], ['_GOV', '0:1']]; 1085 $subtags['INDI:CREM:PLAC'] = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1'], ['_GOV', '0:1']]; 1086 $subtags['INDI:DEAT:PLAC'] = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1'], ['_GOV', '0:1']]; 1087 $subtags['INDI:EMIG:PLAC'] = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1'], ['_GOV', '0:1']]; 1088 $subtags['INDI:ENDL:PLAC'] = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1'], ['_GOV', '0:1']]; 1089 $subtags['INDI:EVEN:PLAC'] = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1'], ['_GOV', '0:1']]; 1090 $subtags['INDI:FCOM:PLAC'] = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1'], ['_GOV', '0:1']]; 1091 $subtags['INDI:IMMI:PLAC'] = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1'], ['_GOV', '0:1']]; 1092 $subtags['INDI:NAME'] = [['_RUFNAME', '0:1', 'SPFX']]; 1093 $subtags['INDI:NATU:PLAC'] = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1'], ['_GOV', '0:1']]; 1094 $subtags['INDI:ORDN:PLAC'] = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1'], ['_GOV', '0:1']]; 1095 $subtags['INDI:RESI:PLAC'] = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1'], ['_GOV', '0:1']]; 1096 $subtags['INDI:SLGC:PLAC'] = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1'], ['_GOV', '0:1']]; 1097 $subtags['NOTE'] = [['_UID', '0:M']]; 1098 $subtags['OBJE'] = [['_PRIM', '0:1:?'], ['_UID', '0:M']]; 1099 $subtags['REPO'] = [['_UID', '0:M']]; 1100 $subtags['REPO:ADDR'] = [['_NAME', '0:1', 'ADR1']]; 1101 $subtags['SOUR'] = [['_UID', '0:M']]; 1102 $subtags['SOUR:DATA:EVEN:PLAC'] = [['_POST', '0:1'], ['_MAIDENHEAD', '0:1:?'], ['_LOC', '0:1'], ['_GOV', '0:1']]; 1103 $subtags['SUBM'] = [['_UID', '0:M']]; 1104 $subtags['SUBM:ADDR'] = [['_NAME', '0:1', 'ADR1']]; 1105 } 1106 1107 return $subtags; 1108 } 1109 1110 /** 1111 * @param ElementFactoryInterface $element_factory 1112 * @param bool $include_custom_tags 1113 * 1114 * @return void 1115 */ 1116 public function registerTags(ElementFactoryInterface $element_factory, bool $include_custom_tags): void 1117 { 1118 // Standard GEDCOM. 1119 $element_factory->registerTags($this->gedcom551Tags()); 1120 1121 // webtrees extensions. 1122 $element_factory->registerTags($this->webtreesTags()); 1123 1124 if ($include_custom_tags) { 1125 // webtrees extensions. 1126 $element_factory->registerSubTags($this->webtreesSubTags()); 1127 1128 $custom_tags = [ 1129 new Aldfaer(), 1130 new Ancestry(), 1131 new BrothersKeeper(), 1132 new FamilySearch(), 1133 new FamilyTreeBuilder(), 1134 new FamilyTreeMaker(), 1135 new Gedcom7(), 1136 new GedcomL(), 1137 new Geneatique(), 1138 new GenPlusWin(), 1139 new Heredis(), 1140 new Legacy(), 1141 new MyHeritage(), 1142 new PersonalAncestralFile(), 1143 new PhpGedView(), 1144 new ProGen(), 1145 new Reunion(), 1146 new RootsMagic(), 1147 new TheMasterGenealogist(), 1148 new TheNextGeneration(), 1149 ]; 1150 1151 foreach ($custom_tags as $custom_tag) { 1152 $element_factory->registerTags($custom_tag->tags()); 1153 } 1154 1155 // Creating tags from all the above are grouped into one place 1156 $element_factory->registerSubTags($this->customSubTags()); 1157 } 1158 } 1159} 1160