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