Completed
Push — develop ( 0d6c46...c341e4 )
by Greg
15:25 queued 09:07
created

ElementFactory::elements()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 525
Code Lines 510

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 510
c 1
b 0
f 0
nc 2
nop 0
dl 0
loc 525
rs 8

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * webtrees: online genealogy
5
 * Copyright (C) 2020 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 <http://www.gnu.org/licenses/>.
16
 */
17
18
declare(strict_types=1);
19
20
namespace Fisharebest\Webtrees\Factories;
21
22
use Fisharebest\Webtrees\Contracts\ElementFactoryInterface;
23
use Fisharebest\Webtrees\GedcomElements\AddressCity;
24
use Fisharebest\Webtrees\GedcomElements\AddressCountry;
25
use Fisharebest\Webtrees\GedcomElements\AddressEmail;
26
use Fisharebest\Webtrees\GedcomElements\AddressFax;
27
use Fisharebest\Webtrees\GedcomElements\AddressLine;
28
use Fisharebest\Webtrees\GedcomElements\AddressLine1;
29
use Fisharebest\Webtrees\GedcomElements\AddressLine2;
30
use Fisharebest\Webtrees\GedcomElements\AddressLine3;
31
use Fisharebest\Webtrees\GedcomElements\AddressPostalCode;
32
use Fisharebest\Webtrees\GedcomElements\AddressState;
33
use Fisharebest\Webtrees\GedcomElements\AddressWebPage;
34
use Fisharebest\Webtrees\GedcomElements\AdoptedByWhichParent;
35
use Fisharebest\Webtrees\GedcomElements\Adoption;
36
use Fisharebest\Webtrees\GedcomElements\AdultChristening;
37
use Fisharebest\Webtrees\GedcomElements\AgeAtEvent;
38
use Fisharebest\Webtrees\GedcomElements\AncestralFileNumber;
39
use Fisharebest\Webtrees\GedcomElements\Annulment;
40
use Fisharebest\Webtrees\GedcomElements\ApprovedSystemId;
41
use Fisharebest\Webtrees\GedcomElements\AttributeDescriptor;
42
use Fisharebest\Webtrees\GedcomElements\AutomatedRecordId;
43
use Fisharebest\Webtrees\GedcomElements\Baptism;
44
use Fisharebest\Webtrees\GedcomElements\BasMitzvah;
45
use Fisharebest\Webtrees\GedcomElements\Birth;
46
use Fisharebest\Webtrees\GedcomElements\Blessing;
47
use Fisharebest\Webtrees\GedcomElements\Burial;
48
use Fisharebest\Webtrees\GedcomElements\CasteName;
49
use Fisharebest\Webtrees\GedcomElements\CauseOfEvent;
50
use Fisharebest\Webtrees\GedcomElements\Census;
51
use Fisharebest\Webtrees\GedcomElements\CertaintyAssessment;
52
use Fisharebest\Webtrees\GedcomElements\Change;
53
use Fisharebest\Webtrees\GedcomElements\ChangeDate;
54
use Fisharebest\Webtrees\GedcomElements\CharacterSet;
55
use Fisharebest\Webtrees\GedcomElements\ChildLinkageStatus;
56
use Fisharebest\Webtrees\GedcomElements\Christening;
57
use Fisharebest\Webtrees\GedcomElements\Confirmation;
58
use Fisharebest\Webtrees\GedcomElements\CopyrightFile;
59
use Fisharebest\Webtrees\GedcomElements\CopyrightSourceData;
60
use Fisharebest\Webtrees\GedcomElements\CountOfChildren;
61
use Fisharebest\Webtrees\GedcomElements\CountOfMarriages;
62
use Fisharebest\Webtrees\GedcomElements\Cremation;
63
use Fisharebest\Webtrees\GedcomElements\DateLdsOrd;
64
use Fisharebest\Webtrees\GedcomElements\DateValue;
65
use Fisharebest\Webtrees\GedcomElements\Death;
66
use Fisharebest\Webtrees\GedcomElements\DescriptiveTitle;
67
use Fisharebest\Webtrees\GedcomElements\Divorce;
68
use Fisharebest\Webtrees\GedcomElements\DivorceFiled;
69
use Fisharebest\Webtrees\GedcomElements\Emigration;
70
use Fisharebest\Webtrees\GedcomElements\EmptyElement;
71
use Fisharebest\Webtrees\GedcomElements\Engagement;
72
use Fisharebest\Webtrees\GedcomElements\EntryRecordingDate;
73
use Fisharebest\Webtrees\GedcomElements\EventAttributeType;
74
use Fisharebest\Webtrees\GedcomElements\EventDescriptor;
75
use Fisharebest\Webtrees\GedcomElements\EventOrFactClassification;
76
use Fisharebest\Webtrees\GedcomElements\EventsRecorded;
77
use Fisharebest\Webtrees\GedcomElements\EventTypeCitedFrom;
78
use Fisharebest\Webtrees\GedcomElements\FileName;
79
use Fisharebest\Webtrees\GedcomElements\FirstCommunion;
80
use Fisharebest\Webtrees\GedcomElements\Gedcom;
81
use Fisharebest\Webtrees\GedcomElements\ContentDescription;
82
use Fisharebest\Webtrees\GedcomElements\GedcomElementInterface;
83
use Fisharebest\Webtrees\GedcomElements\Form;
84
use Fisharebest\Webtrees\GedcomElements\GenerationsOfAncestors;
85
use Fisharebest\Webtrees\GedcomElements\GenerationsOfDescendants;
86
use Fisharebest\Webtrees\GedcomElements\Graduation;
87
use Fisharebest\Webtrees\GedcomElements\Immigration;
88
use Fisharebest\Webtrees\GedcomElements\LanguageId;
89
use Fisharebest\Webtrees\GedcomElements\LdsBaptism;
90
use Fisharebest\Webtrees\GedcomElements\LdsBaptismDateStatus;
91
use Fisharebest\Webtrees\GedcomElements\LdsChildSealing;
92
use Fisharebest\Webtrees\GedcomElements\LdsChildSealingDateStatus;
93
use Fisharebest\Webtrees\GedcomElements\LdsConfirmation;
94
use Fisharebest\Webtrees\GedcomElements\LdsEndowment;
95
use Fisharebest\Webtrees\GedcomElements\LdsEndowmentDateStatus;
96
use Fisharebest\Webtrees\GedcomElements\LdsSpouseSealing;
97
use Fisharebest\Webtrees\GedcomElements\LdsSpouseSealingDateStatus;
98
use Fisharebest\Webtrees\GedcomElements\Marriage;
99
use Fisharebest\Webtrees\GedcomElements\MarriageBanns;
100
use Fisharebest\Webtrees\GedcomElements\MarriageContract;
101
use Fisharebest\Webtrees\GedcomElements\MarriageLicence;
102
use Fisharebest\Webtrees\GedcomElements\MarriageSettlement;
103
use Fisharebest\Webtrees\GedcomElements\MarriageType;
104
use Fisharebest\Webtrees\GedcomElements\MultimediaFileReference;
105
use Fisharebest\Webtrees\GedcomElements\MultimediaFormat;
106
use Fisharebest\Webtrees\GedcomElements\NameOfBusiness;
107
use Fisharebest\Webtrees\GedcomElements\NameOfFamilyFile;
108
use Fisharebest\Webtrees\GedcomElements\NameOfProduct;
109
use Fisharebest\Webtrees\GedcomElements\NameOfRepository;
110
use Fisharebest\Webtrees\GedcomElements\NameOfSourceData;
111
use Fisharebest\Webtrees\GedcomElements\NamePersonal;
112
use Fisharebest\Webtrees\GedcomElements\NamePhoneticVariation;
113
use Fisharebest\Webtrees\GedcomElements\NamePieceGiven;
114
use Fisharebest\Webtrees\GedcomElements\NamePieceNickname;
115
use Fisharebest\Webtrees\GedcomElements\NamePiecePrefix;
116
use Fisharebest\Webtrees\GedcomElements\NamePieceSuffix;
117
use Fisharebest\Webtrees\GedcomElements\NamePieceSurname;
118
use Fisharebest\Webtrees\GedcomElements\NamePieceSurnamePrefix;
119
use Fisharebest\Webtrees\GedcomElements\NameRomanizedVariation;
120
use Fisharebest\Webtrees\GedcomElements\NameType;
121
use Fisharebest\Webtrees\GedcomElements\NationalIdNumber;
122
use Fisharebest\Webtrees\GedcomElements\NationOrTribalOrigin;
123
use Fisharebest\Webtrees\GedcomElements\Naturalization;
124
use Fisharebest\Webtrees\GedcomElements\NobilityTypeTitle;
125
use Fisharebest\Webtrees\GedcomElements\NoteRecord;
126
use Fisharebest\Webtrees\GedcomElements\NoteStructure;
127
use Fisharebest\Webtrees\GedcomElements\Occupation;
128
use Fisharebest\Webtrees\GedcomElements\OrdinanceProcessFlag;
129
use Fisharebest\Webtrees\GedcomElements\Ordination;
130
use Fisharebest\Webtrees\GedcomElements\PafUid;
131
use Fisharebest\Webtrees\GedcomElements\PedigreeLinkageType;
132
use Fisharebest\Webtrees\GedcomElements\PermanentRecordFileNumber;
133
use Fisharebest\Webtrees\GedcomElements\PhoneNumber;
134
use Fisharebest\Webtrees\GedcomElements\PhoneticType;
135
use Fisharebest\Webtrees\GedcomElements\PhysicalDescription;
136
use Fisharebest\Webtrees\GedcomElements\PlaceHierarchy;
137
use Fisharebest\Webtrees\GedcomElements\PlaceLatitude;
138
use Fisharebest\Webtrees\GedcomElements\PlaceLivingOrdinance;
139
use Fisharebest\Webtrees\GedcomElements\PlaceLongtitude;
140
use Fisharebest\Webtrees\GedcomElements\PlaceName;
141
use Fisharebest\Webtrees\GedcomElements\PlacePhoneticVariation;
142
use Fisharebest\Webtrees\GedcomElements\PlaceRomanizedVariation;
143
use Fisharebest\Webtrees\GedcomElements\Possessions;
144
use Fisharebest\Webtrees\GedcomElements\Probate;
145
use Fisharebest\Webtrees\GedcomElements\PublicationDate;
146
use Fisharebest\Webtrees\GedcomElements\ReceivingSystemName;
147
use Fisharebest\Webtrees\GedcomElements\RelationIsDescriptor;
148
use Fisharebest\Webtrees\GedcomElements\ReligiousAffiliation;
149
use Fisharebest\Webtrees\GedcomElements\RepositoryRecord;
150
use Fisharebest\Webtrees\GedcomElements\Residence;
151
use Fisharebest\Webtrees\GedcomElements\ResponsibleAgency;
152
use Fisharebest\Webtrees\GedcomElements\RestrictionNotice;
153
use Fisharebest\Webtrees\GedcomElements\Retirement;
154
use Fisharebest\Webtrees\GedcomElements\RoleInEvent;
155
use Fisharebest\Webtrees\GedcomElements\RomanizedType;
156
use Fisharebest\Webtrees\GedcomElements\ScholasticAchievement;
157
use Fisharebest\Webtrees\GedcomElements\SexValue;
158
use Fisharebest\Webtrees\GedcomElements\SocialSecurityNumber;
159
use Fisharebest\Webtrees\GedcomElements\SourceCallNumber;
160
use Fisharebest\Webtrees\GedcomElements\SourceData;
161
use Fisharebest\Webtrees\GedcomElements\SourceFiledByEntry;
162
use Fisharebest\Webtrees\GedcomElements\SourceJurisdictionPlace;
163
use Fisharebest\Webtrees\GedcomElements\SourceMediaType;
164
use Fisharebest\Webtrees\GedcomElements\SourceOriginator;
165
use Fisharebest\Webtrees\GedcomElements\SourcePublicationFacts;
166
use Fisharebest\Webtrees\GedcomElements\SourceRecord;
167
use Fisharebest\Webtrees\GedcomElements\SubmitterName;
168
use Fisharebest\Webtrees\GedcomElements\SubmitterRecord;
169
use Fisharebest\Webtrees\GedcomElements\SubmitterRegisteredRfn;
170
use Fisharebest\Webtrees\GedcomElements\SubmitterText;
171
use Fisharebest\Webtrees\GedcomElements\TempleCode;
172
use Fisharebest\Webtrees\GedcomElements\TextFromSource;
173
use Fisharebest\Webtrees\GedcomElements\TimeValue;
174
use Fisharebest\Webtrees\GedcomElements\TransmissionDate;
175
use Fisharebest\Webtrees\GedcomElements\UnknownElement;
176
use Fisharebest\Webtrees\GedcomElements\UserReferenceNumber;
177
use Fisharebest\Webtrees\GedcomElements\UserReferenceType;
178
use Fisharebest\Webtrees\GedcomElements\VersionNumber;
179
use Fisharebest\Webtrees\GedcomElements\WebtreesUser;
180
use Fisharebest\Webtrees\GedcomElements\WhereWithinSource;
181
use Fisharebest\Webtrees\GedcomElements\Will;
182
use Fisharebest\Webtrees\GedcomElements\XrefFamily;
183
use Fisharebest\Webtrees\GedcomElements\XrefIndividual;
184
use Fisharebest\Webtrees\GedcomElements\XrefMedia;
185
use Fisharebest\Webtrees\GedcomElements\XrefRepository;
186
use Fisharebest\Webtrees\GedcomElements\XrefSource;
187
use Fisharebest\Webtrees\GedcomElements\XrefSubmitter;
188
use Fisharebest\Webtrees\GedcomElements\XrefSubmission;
189
use Fisharebest\Webtrees\I18N;
190
191
use function preg_match;
192
use function strpos;
193
194
/**
195
 * Make a GEDCOM element.
196
 */
197
class ElementFactory implements ElementFactoryInterface
198
{
199
    /** @var null|array<string,GedcomElementInterface> */
200
    private $elements;
201
202
    /**
203
     * Create a GEDCOM element that corresponds to a GEDCOM tag.
204
     * Finds the correct element for all valid tags.
205
     * Finds a likely element for custom tags.
206
     *
207
     * @param string $tag - Colon delimited hierarchy, e.g. 'INDI:BIRT:PLAC'
208
     *
209
     * @return GedcomElementInterface
210
     */
211
    public function make(string $tag): GedcomElementInterface
212
    {
213
        return $this->elements()[$tag] ?? $this->findElementByWildcard($tag) ?? new UnknownElement($tag);
214
    }
215
216
    /**
217
     * @param string $tag
218
     *
219
     * @return GedcomElementInterface|null
220
     */
221
    private function findElementByWildcard(string $tag): ?GedcomElementInterface
222
    {
223
        foreach ($this->elements() as $tags => $element) {
224
            if (strpos($tags, '*') !== false) {
225
                $regex = '/^' . strtr($tags, ['*' => '[^:]+']) . '$/';
226
227
                if (preg_match($regex, $tag)) {
228
                    return $element;
229
                }
230
            }
231
        }
232
233
        return null;
234
    }
235
236
    /**
237
     * Register more elements.
238
     *
239
     * @param array<string,GedcomElementInterface> $elements
240
     */
241
    public function register(array $elements): void
242
    {
243
        $this->elements = array_merge($this->elements(), $elements);
244
    }
245
246
    /**
247
     * Association between GEDCOM tags and GEDCOM elements.
248
     * We can't initialise this in the constructor, as the I18N package isn't available then.
249
     *
250
     * @return array<string,GedcomElementInterface>
251
     */
252
    private function elements(): array
253
    {
254
        if ($this->elements === null) {
255
            // Custom tags are indicated with ***
256
            $this->elements = [
257
                'INDI'                     => new EmptyElement(I18N::translate('Individual')),
258
                'INDI:ADOP'                => new Adoption(I18N::translate('Adoption')),
259
                'INDI:ADOP:DATE'           => new DateValue(I18N::translate('Date of adoption')),
260
                'INDI:ADOP:PLAC'           => new PlaceName(I18N::translate('Place of adoption')),
261
                'INDI:ADOP:FAMC'           => new XrefFamily(I18N::translate('Adoptive parents')),
262
                'INDI:ADOP:FAMC:ADOP'      => new AdoptedByWhichParent(I18N::translate('Adoption')),
263
                'INDI:AFN'                 => new AncestralFileNumber(I18N::translate('Ancestral file number')),
264
                'INDI:ASSO'                => new XrefIndividual(I18N::translate('Associate')),
265
                'INDI:ASSO:RELA'           => new RelationIsDescriptor(I18N::translate('Relationship')),
266
                'INDI:ASSO:NOTE'           => new NoteStructure(I18N::translate('Note')),
267
                'INDI:ALIA'                => new XrefIndividual(I18N::translate('Alias')),
268
                'INDI:ANCI'                => new XrefSubmitter(I18N::translate('Ancestors interest')),
269
                'INDI:BAPL'                => new LdsBaptism(I18N::translate('LDS baptism')),
270
                'INDI:BAPL:DATE'           => new DateLdsOrd(I18N::translate('Date of LDS baptism')),
271
                'INDI:BAPL:TEMP'           => new TempleCode(/* I18N: https://en.wikipedia.org/wiki/Temple_(LDS_Church)*/ I18N::translate('Temple')),
272
                'INDI:BAPL:PLAC'           => new PlaceLivingOrdinance(I18N::translate('Place of LDS baptism')),
273
                'INDI:BAPL:STAT'           => new LdsBaptismDateStatus(I18N::translate('Status')),
274
                'INDI:BAPL:STAT:DATE'      => new ChangeDate(I18N::translate('Status change date')),
275
                'INDI:BAPL:NOTE'           => new NoteStructure(I18N::translate('Note')),
276
                'INDI:BAPM'                => new Baptism(I18N::translate('Baptism')),
277
                'INDI:BAPM:DATE'           => new DateValue(I18N::translate('Date of baptism')),
278
                'INDI:BAPM:PLAC'           => new PlaceName(I18N::translate('Place of baptism')),
279
                'INDI:BASM'                => new BasMitzvah(I18N::translate('Bat mitzvah')),
280
                'INDI:BASM:DATE'           => new BasMitzvah(I18N::translate('Date of bat mitzvah')),
281
                'INDI:BASM:PLAC'           => new DateValue(I18N::translate('Place of bat mitzvah')),
282
                'INDI:BARM'                => new PlaceName(I18N::translate('Bar mitzvah')),
283
                'INDI:BARM:DATE'           => new DateValue(I18N::translate('Date of bar mitzvah')),
284
                'INDI:BARM:PLAC'           => new PlaceName(I18N::translate('Place of bar mitzvah')),
285
                'INDI:BIRT'                => new Birth(I18N::translate('Birth')),
286
                'INDI:BIRT:DATE'           => new DateValue(I18N::translate('Date of birth')),
287
                'INDI:BIRT:FAMC'           => new XrefFamily(I18N::translate('Birth parents')),
288
                'INDI:BIRT:PLAC'           => new PlaceName(I18N::translate('Place of birth')),
289
                'INDI:BLES'                => new Blessing(I18N::translate('Blessing')),
290
                'INDI:BLES:DATE'           => new DateValue(I18N::translate('Date of blessing')),
291
                'INDI:BLES:PLAC'           => new PlaceName(I18N::translate('Place of blessing')),
292
                'INDI:BURI'                => new Burial(I18N::translate('Burial')),
293
                'INDI:BURI:DATE'           => new DateValue(I18N::translate('Date of burial')),
294
                'INDI:BURI:PLAC'           => new PlaceName(I18N::translate('Place of burial')),
295
                'INDI:CAST'                => new CasteName(I18N::translate('Caste')),
296
                'INDI:CENS'                => new Census(I18N::translate('Census')),
297
                'INDI:CENS:DATE'           => new DateValue(I18N::translate('Census date')),
298
                'INDI:CENS:PLAC'           => new PlaceName(I18N::translate('Census place')),
299
                'INDI:CHAN'                => new Change(I18N::translate('Last change')),
300
                'INDI:CHAN:DATE'           => new ChangeDate(I18N::translate('Date of last change')),
301
                'INDI:CHAN:DATE:TIME'      => new TimeValue(I18N::translate('Time')),
302
                'INDI:CHAN:_WT_USER'       => new WebtreesUser(I18N::translate('Author of last change')), // *** webtrees
303
                'INDI:CHR'                 => new Christening(I18N::translate('Christening')),
304
                'INDI:CHR:DATE'            => new DateValue(I18N::translate('Date of christening')),
305
                'INDI:CHR:PLAC'            => new PlaceName(I18N::translate('Place of christening')),
306
                'INDI:CHRA'                => new AdultChristening(I18N::translate('Adult christening')),
307
                'INDI:CHR:FAMC'            => new XrefFamily(I18N::translate('Godparents')),
308
                'INDI:CONF'                => new Confirmation(I18N::translate('Confirmation')),
309
                'INDI:CONF:DATE'           => new DateValue(I18N::translate('Date of confirmation')),
310
                'INDI:CONF:PLAC'           => new PlaceName(I18N::translate('Place of confirmation')),
311
                'INDI:CONL'                => new LdsConfirmation(I18N::translate('LDS confirmation')),
312
                'INDI:CONL:DATE'           => new DateLdsOrd(I18N::translate('Date of LDS confirmation')),
313
                'INDI:CONL:TEMP'           => new TempleCode(/* I18N: https://en.wikipedia.org/wiki/Temple_(LDS_Church)*/ I18N::translate('Temple')),
314
                'INDI:CONL:PLAC'           => new PlaceLivingOrdinance(I18N::translate('Place of LDS confirmation')),
315
                'INDI:CONL:STAT'           => new LdsSpouseSealingDateStatus(I18N::translate('Status')),
316
                'INDI:CONL:STAT:DATE'      => new ChangeDate(I18N::translate('Status change date')),
317
                'INDI:CONL:NOTE'           => new NoteStructure(I18N::translate('Note')),
318
                'INDI:CREM'                => new Cremation(I18N::translate('Cremation')),
319
                'INDI:CREM:DATE'           => new Cremation(I18N::translate('Date of cremation')),
320
                'INDI:CREM:PLAC'           => new Cremation(I18N::translate('Place of cremation')),
321
                'INDI:DEAT'                => new Death(I18N::translate('Death')),
322
                'INDI:DEAT:CAUS'           => new CauseOfEvent(I18N::translate('Cause of death')),
323
                'INDI:DEAT:DATE'           => new DateValue(I18N::translate('Date of death')),
324
                'INDI:DEAT:PLAC'           => new PlaceName(I18N::translate('Place of death')),
325
                'INDI:DESI'                => new XrefSubmitter(I18N::translate('Descendants interest')),
326
                'INDI:DSCR'                => new PhysicalDescription(I18N::translate('Description')),
327
                'INDI:EDUC'                => new ScholasticAchievement(I18N::translate('Education')),
328
                'INDI:EDUC:AGNC'           => new ResponsibleAgency(I18N::translate('School or college')),
329
                'INDI:EMIG'                => new Emigration(I18N::translate('Emigration')),
330
                'INDI:EMIG:DATE'           => new DateValue(I18N::translate('Date of emigration')),
331
                'INDI:EMIG:PLAC'           => new PlaceName(I18N::translate('Place of emigration')),
332
                'INDI:ENDL'                => new LdsEndowment(I18N::translate('LDS endowment')),
333
                'INDI:ENDL:DATE'           => new DateLdsOrd(I18N::translate('Date of LDS endowment')),
334
                'INDI:ENDL:TEMP'           => new TempleCode(/* I18N: https://en.wikipedia.org/wiki/Temple_(LDS_Church)*/ I18N::translate('Temple')),
335
                'INDI:ENDL:PLAC'           => new PlaceLivingOrdinance(I18N::translate('Place of LDS endowment')),
336
                'INDI:ENDL:STAT'           => new LdsEndowmentDateStatus(I18N::translate('Status')),
337
                'INDI:ENDL:STAT:DATE'      => new ChangeDate(I18N::translate('Status change date')),
338
                'INDI:ENDL:NOTE'           => new NoteStructure(I18N::translate('Note')),
339
                'INDI:EVEN'                => new EventDescriptor(I18N::translate('Event')),
340
                'INDI:EVEN:DATE'           => new DateValue(I18N::translate('Date of event')),
341
                'INDI:EVEN:PLAC'           => new PlaceName(I18N::translate('Place of event')),
342
                'INDI:EVEN:TYPE'           => new EventAttributeType(I18N::translate('Type of event')),
343
                'INDI:FACT'                => new AttributeDescriptor(I18N::translate('Fact')),
344
                'INDI:FACT:TYPE'           => new EventAttributeType(I18N::translate('Type of fact')),
345
                'INDI:FAMC'                => new XrefFamily(I18N::translate('Family as a child')),
346
                'INDI:FAMC:PEDI'           => new PedigreeLinkageType(I18N::translate('Relationship to parents')),
347
                'INDI:FAMC:STAT'           => new ChildLinkageStatus(I18N::translate('Status')),
348
                'INDI:FAMC:NOTE'           => new NoteStructure(I18N::translate('Note')),
349
                'INDI:FAMS'                => new XrefFamily(I18N::translate('Family as a spouse')),
350
                'INDI:FCOM'                => new FirstCommunion(I18N::translate('First communion')),
351
                'INDI:FCOM:DATE'           => new DateValue(I18N::translate('Date of first communion')),
352
                'INDI:FCOM:PLAC'           => new PlaceName(I18N::translate('Place of first communion')),
353
                'INDI:GRAD'                => new Graduation(I18N::translate('Graduation')),
354
                'INDI:GRAD:AGNC'           => new ResponsibleAgency(I18N::translate('School or college')),
355
                'INDI:IDNO'                => new NationalIdNumber(I18N::translate('Identification number')),
356
                'INDI:IMMI'                => new Immigration(I18N::translate('Immigration')),
357
                'INDI:IMMI:DATE'           => new DateValue(I18N::translate('Date of immigration')),
358
                'INDI:IMMI:PLAC'           => new PlaceName(I18N::translate('Place of immigration')),
359
                'INDI:NAME'                => new NamePersonal(I18N::translate('Name')),
360
                'INDI:NAME:TYPE'           => new NameType(I18N::translate('Type of name')),
361
                'INDI:NAME:NPFX'           => new NamePiecePrefix(I18N::translate('Name prefix')),
362
                'INDI:NAME:GIVN'           => new NamePieceGiven(I18N::translate('Given names')),
363
                'INDI:NAME:NICK'           => new NamePieceNickname(I18N::translate('Nickname')),
364
                'INDI:NAME:SPFX'           => new NamePieceSurnamePrefix(I18N::translate('Surname prefix')),
365
                'INDI:NAME:SURN'           => new NamePieceSurname(I18N::translate('Surname')),
366
                'INDI:NAME:NSFX'           => new NamePieceSuffix(I18N::translate('Name suffix')),
367
                'INDI:NAME:NOTE'           => new NoteStructure(I18N::translate('Note')),
368
                'INDI:NAME:FONE'           => new NamePhoneticVariation(I18N::translate('Phonetic name')),
369
                'INDI:NAME:FONE:TYPE'      => new PhoneticType(I18N::translate('Type of name')),
370
                'INDI:NAME:FONE:NPFX'      => new NamePiecePrefix(I18N::translate('Name prefix')),
371
                'INDI:NAME:FONE:GIVN'      => new NamePieceGiven(I18N::translate('Given names')),
372
                'INDI:NAME:FONE:NICK'      => new NamePieceNickname(I18N::translate('Nickname')),
373
                'INDI:NAME:FONE:SPFX'      => new NamePieceSurnamePrefix(I18N::translate('Surname prefix')),
374
                'INDI:NAME:FONE:SURN'      => new NamePieceSurname(I18N::translate('Surname')),
375
                'INDI:NAME:FONE:NSFX'      => new NamePieceSuffix(I18N::translate('Name suffix')),
376
                'INDI:NAME:ROMN'           => new NameRomanizedVariation(I18N::translate('Romanized name')),
377
                'INDI:NAME:ROMN:TYPE'      => new RomanizedType(I18N::translate('Type')),
378
                'INDI:NAME:ROMN:NPFX'      => new NamePiecePrefix(I18N::translate('Name prefix')),
379
                'INDI:NAME:ROMN:GIVN'      => new NamePieceGiven(I18N::translate('Given names')),
380
                'INDI:NAME:ROMN:NICK'      => new NamePieceNickname(I18N::translate('Nickname')),
381
                'INDI:NAME:ROMN:SPFX'      => new NamePieceSurnamePrefix(I18N::translate('Surname prefix')),
382
                'INDI:NAME:ROMN:SURN'      => new NamePieceSurname(I18N::translate('Surname')),
383
                'INDI:NAME:ROMN:NSFX'      => new NamePieceSuffix(I18N::translate('Name suffix')),
384
                'INDI:NATI'                => new NationOrTribalOrigin(I18N::translate('Nationality')),
385
                'INDI:NATU'                => new Naturalization(I18N::translate('Naturalization')),
386
                'INDI:NATU:DATE'           => new DateValue(I18N::translate('Date of naturalization')),
387
                'INDI:NATU:PLAC'           => new PlaceName(I18N::translate('Place of naturalization')),
388
                'INDI:NCHI'                => new CountOfChildren(I18N::translate('Number of children')),
389
                'INDI:NMR'                 => new CountOfMarriages(I18N::translate('Number of marriages')),
390
                'INDI:NOTE'                => new NoteStructure(I18N::translate('Note')),
391
                'INDI:OBJE'                => new XrefMedia(I18N::translate('Media object')),
392
                'INDI:OCCU'                => new Occupation(I18N::translate('Occupation')),
393
                'INDI:OCCU:AGNC'           => new ResponsibleAgency(I18N::translate('Employer')),
394
                'INDI:ORDN'                => new Ordination(I18N::translate('Ordination')),
395
                'INDI:ORDN:AGNC'           => new Ordination(I18N::translate('Religious institution')),
396
                'INDI:ORDN:DATE'           => new Ordination(I18N::translate('Date of ordination')),
397
                'INDI:ORDN:PLAC'           => new Ordination(I18N::translate('Place of ordination')),
398
                'INDI:PROB'                => new Probate(I18N::translate('Probate')),
399
                'INDI:PROP'                => new Possessions(I18N::translate('Property')),
400
                'INDI:REFN'                => new UserReferenceNumber(I18N::translate('Reference number')),
401
                'INDI:REFN:TYPE'           => new UserReferenceType(I18N::translate('Type')),
402
                'INDI:RELI'                => new ReligiousAffiliation(I18N::translate('Religion')),
403
                'INDI:RESI'                => new Residence(I18N::translate('Residence')),
404
                'INDI:RESI:DATE'           => new DateValue(I18N::translate('Date of residence')),
405
                'INDI:RESI:PLAC'           => new PlaceName(I18N::translate('Place of residence')),
406
                'INDI:RESN'                => new RestrictionNotice(I18N::translate('Restriction')),
407
                'INDI:RETI'                => new Retirement(I18N::translate('Retirement')),
408
                'INDI:RETI:AGNC'           => new ResponsibleAgency(I18N::translate('Employer')),
409
                'INDI:RFN'                 => new PermanentRecordFileNumber(I18N::translate('Record file number')),
410
                'INDI:RIN'                 => new AutomatedRecordId(I18N::translate('Record ID number')),
411
                'INDI:SEX'                 => new SexValue(I18N::translate('Gender')),
412
                'INDI:SLGC'                => new LdsChildSealing(I18N::translate('LDS child sealing')),
413
                'INDI:SLGC:DATE'           => new DateLdsOrd(I18N::translate('Date of LDS child sealing')),
414
                'INDI:SLGC:TEMP'           => new TempleCode(/* I18N: https://en.wikipedia.org/wiki/Temple_(LDS_Church)*/ I18N::translate('Temple')),
415
                'INDI:SLGC:PLAC'           => new PlaceLivingOrdinance(I18N::translate('Place of LDS child sealing')),
416
                'INDI:SLGC:FAMC'           => new XrefFamily(I18N::translate('Parents')),
417
                'INDI:SLGC:STAT'           => new LdsChildSealingDateStatus(I18N::translate('Status')),
418
                'INDI:SLGC:STAT:DATE'      => new ChangeDate(I18N::translate('Status change date')),
419
                'INDI:SLGC:NOTE'           => new NoteStructure(I18N::translate('Note')),
420
                'INDI:SSN'                 => new SocialSecurityNumber(I18N::translate('Social security number')),
421
                'INDI:SUBM'                => new XrefSubmitter(I18N::translate('Submitter')),
422
                'INDI:SOUR'                => new XrefSource(I18N::translate('Source')),
423
                'INDI:SOUR:PAGE'           => new WhereWithinSource(I18N::translate('Citation details')),
424
                'INDI:SOUR:EVEN'           => new EventTypeCitedFrom(I18N::translate('Event')),
425
                'INDI:SOUR:EVEN:ROLE'      => new RoleInEvent(I18N::translate('Role')),
426
                'INDI:SOUR:DATA'           => new SourceData(I18N::translate('Data')),
427
                'INDI:SOUR:DATA:DATE'      => new EntryRecordingDate(I18N::translate('Date of entry in original source')),
428
                'INDI:SOUR:DATA:TEXT'      => new TextFromSource(I18N::translate('Text')),
429
                'INDI:SOUR:OBJE'           => new XrefMedia(I18N::translate('Media object')),
430
                'INDI:SOUR:NOTE'           => new NoteStructure(I18N::translate('Note')),
431
                'INDI:SOUR:QUAY'           => new CertaintyAssessment(I18N::translate('Quality of data')),
432
                'INDI:TITL'                => new NobilityTypeTitle(I18N::translate('Title')),
433
                'INDI:WILL'                => new Will(I18N::translate('Will')),
434
                'INDI:_UID'                => new PafUid(I18N::translate('Unique identifier')), // ***
435
                'INDI:*:ADDR'              => new AddressLine(I18N::translate('Address')),
436
                'INDI:*:ADDR:ADR1'         => new AddressLine1(I18N::translate('Address line 1')),
437
                'INDI:*:ADDR:ADR2'         => new AddressLine2(I18N::translate('Address line 2')),
438
                'INDI:*:ADDR:ADR3'         => new AddressLine3(I18N::translate('Address line 3')),
439
                'INDI:*:ADDR:CITY'         => new AddressCity(I18N::translate('City')),
440
                'INDI:*:ADDR:STAE'         => new AddressState(I18N::translate('State')),
441
                'INDI:*:ADDR:POST'         => new AddressPostalCode(I18N::translate('Postal code')),
442
                'INDI:*:ADDR:CTRY'         => new AddressCountry(I18N::translate('Country')),
443
                'INDI:*:AGE'               => new AgeAtEvent(I18N::translate('Age')),
444
                'INDI:*:AGNC'              => new ResponsibleAgency(I18N::translate('Agency')),
445
                'INDI:*:ASSO'              => new XrefIndividual(I18N::translate('Associate')), // ***
446
                'INDI:*:ASSO:RELA'         => new RelationIsDescriptor(I18N::translate('Relationship')),
447
                'INDI:*:CAUS'              => new CauseOfEvent(I18N::translate('Cause')),
448
                'INDI:*:DATE'              => new DateValue(I18N::translate('Date')),
449
                'INDI:*:EMAIL'             => new AddressEmail(I18N::translate('Email address')),
450
                'INDI:*:FAX'               => new AddressFax(I18N::translate('Fax')),
451
                'INDI:*:NOTE'              => new NoteStructure(I18N::translate('Note')),
452
                'INDI:*:PHON'              => new PhoneNumber(I18N::translate('Phone')),
453
                'INDI:*:PLAC'              => new PlaceName(I18N::translate('Place')),
454
                'INDI:*:PLAC:FORM'         => new PlaceHierarchy(I18N::translate('Format')),
455
                'INDI:*:PLAC:FONE'         => new PlacePhoneticVariation(I18N::translate('Phonetic place')),
456
                'INDI:*:PLAC:FONE:TYPE'    => new PhoneticType(I18N::translate('Type')),
457
                'INDI:*:PLAC:ROMN'         => new PlaceRomanizedVariation(I18N::translate('Romanized place')),
458
                'INDI:*:PLAC:ROMN:TYPE'    => new RomanizedType(I18N::translate('Type')),
459
                'INDI:*:PLAC:MAP'          => new EmptyElement(I18N::translate('Coordinates')),
460
                'INDI:*:PLAC:MAP:LATI'     => new PlaceLatitude(I18N::translate('Latitude')),
461
                'INDI:*:PLAC:MAP:LONG'     => new PlaceLongtitude(I18N::translate('Longitude')),
462
                'INDI:*:PLAC:NOTE'         => new NoteStructure(I18N::translate('Note')),
463
                'INDI:*:PLAC:_HEB'         => new NoteStructure(I18N::translate('Place in Hebrew')), // ***
464
                'INDI:*:OBJE'              => new XrefMedia(I18N::translate('Media object')),
465
                'INDI:*:RELI'              => new ReligiousAffiliation(I18N::translate('Religion')),
466
                'INDI:*:RESN'              => new RestrictionNotice(I18N::translate('Restriction')),
467
                'INDI:*:SOUR'              => new XrefSource(I18N::translate('Source')),
468
                'INDI:*:SOUR:PAGE'         => new WhereWithinSource(I18N::translate('Citation details')),
469
                'INDI:*:SOUR:EVEN'         => new EventTypeCitedFrom(I18N::translate('Event')),
470
                'INDI:*:SOUR:EVEN:ROLE'    => new RoleInEvent(I18N::translate('Role')),
471
                'INDI:*:SOUR:DATA'         => new SourceData(I18N::translate('Data')),
472
                'INDI:*:SOUR:DATA:DATE'    => new EntryRecordingDate(I18N::translate('Date of entry in original source')),
473
                'INDI:*:SOUR:DATA:TEXT'    => new TextFromSource(I18N::translate('Text')),
474
                'INDI:*:SOUR:OBJE'         => new XrefMedia(I18N::translate('Media object')),
475
                'INDI:*:SOUR:NOTE'         => new NoteStructure(I18N::translate('Note')),
476
                'INDI:*:SOUR:QUAY'         => new CertaintyAssessment(I18N::translate('Quality of data')),
477
                'INDI:*:TYPE'              => new EventOrFactClassification(I18N::translate('Type')),
478
                'INDI:*:WWW'               => new AddressWebPage(I18N::translate('URL')),
479
                'INDI:*:_ASSO'             => new XrefIndividual(I18N::translate('Associate')), // ***
480
                'INDI:*:_ASSO:RELA'        => new RelationIsDescriptor(I18N::translate('Relationship')), // ***
481
                'INDI:_TODO'               => new UnknownElement(I18N::translate('Research task')), // *** webtrees
482
                'INDI:_TODO:DATE'          => new DateValue(I18N::translate('Date')), // *** webtrees
483
                'INDI:_TODO:_WT_USER'      => new WebtreesUser(I18N::translate('User')), // *** webtrees
484
                'INDI:_WT_OBJE_SORT'       => new XrefMedia(I18N::translate('Re-order media')), // *** webtrees 1.7
485
486
                'FAM'                     => new EmptyElement(I18N::translate('Family')),
487
                'FAM:ANUL'                => new Annulment(I18N::translate('Annulment')),
488
                'FAM:CENS'                => new Census(I18N::translate('Census')),
489
                'FAM:CHAN'                => new Change(I18N::translate('Last change')),
490
                'FAM:CHAN:DATE'           => new ChangeDate(I18N::translate('Date of last change')),
491
                'FAM:CHAN:DATE:TIME'      => new TimeValue(I18N::translate('Time')),
492
                'FAM:CHAN:_WT_USER'       => new WebtreesUser(I18N::translate('Author of last change')), // *** webtrees
493
                'FAM:CHIL'                => new XrefIndividual(I18N::translate('Child')),
494
                'FAM:DIV'                 => new Divorce(I18N::translate('Divorce')),
495
                'FAM:DIVF'                => new DivorceFiled(I18N::translate('Divorce filed')),
496
                'FAM:ENGA'                => new Engagement(I18N::translate('Engagement')),
497
                'FAM:ENGA:DATE'           => new DateValue(I18N::translate('Date of engagement')),
498
                'FAM:ENGA:PLACE'          => new PlaceName(I18N::translate('Place of engagement')),
499
                'FAM:EVEN'                => new EventDescriptor(I18N::translate('Event')),
500
                'FAM:EVEN:TYPE'           => new EventAttributeType(I18N::translate('Type of event')),
501
                'FAM:HUSB'                => new XrefIndividual(I18N::translate('Husband')),
502
                'FAM:MARB'                => new MarriageBanns(I18N::translate('Marriage banns')),
503
                'FAM:MARB:DATE'           => new DateValue(I18N::translate('Date of marriage banns')),
504
                'FAM:MARB:PLAC'           => new PlaceName(I18N::translate('Place of marriage banns')),
505
                'FAM:MARC'                => new MarriageContract(I18N::translate('Marriage contract')),
506
                'FAM:MARL'                => new MarriageLicence(I18N::translate('Marriage license')),
507
                'FAM:MARS'                => new MarriageSettlement(I18N::translate('Marriage settlement')),
508
                'FAM:MARR'                => new Marriage(I18N::translate('Marriage')),
509
                'FAM:MARR:DATE'           => new DateValue(I18N::translate('Date of marriage')),
510
                'FAM:MARR:PLAC'           => new PlaceName(I18N::translate('Place of marriage')),
511
                'FAM:MARR:TYPE'           => new MarriageType(I18N::translate('Type of marriage')),
512
                'FAM:NCHI'                => new CountOfChildren(I18N::translate('Number of children')),
513
                'FAM:NOTE'                => new NoteStructure(I18N::translate('Note')),
514
                'FAM:OBJE'                => new XrefMedia(I18N::translate('Media object')),
515
                'FAM:REFN'                => new UserReferenceNumber(I18N::translate('Reference number')),
516
                'FAM:REFN:TYPE'           => new UserReferenceType(I18N::translate('Type')),
517
                'FAM:RIN'                 => new AutomatedRecordId(I18N::translate('Record ID number')),
518
                'FAM:RESI'                => new Residence(I18N::translate('Residence')),
519
                'FAM:RESN'                => new RestrictionNotice(I18N::translate('Restriction')),
520
                'FAM:SUBM'                => new XrefSubmitter(I18N::translate('Submitter')),
521
                'FAM:SLGS'                => new LdsSpouseSealing(I18N::translate('LDS spouse sealing')),
522
                'FAM:SLGS:DATE'           => new DateLdsOrd(I18N::translate('Date')),
523
                'FAM:SLGS:TEMP'           => new TempleCode(/* I18N: https://en.wikipedia.org/wiki/Temple_(LDS_Church)*/ I18N::translate('Temple')),
524
                'FAM:SLGS:PLAC'           => new PlaceLivingOrdinance(I18N::translate('Place')),
525
                'FAM:SLGS:STAT'           => new LdsSpouseSealingDateStatus(I18N::translate('Status')),
526
                'FAM:SLGS:STAT:DATE'      => new ChangeDate(I18N::translate('Status change date')),
527
                'FAM:SLGS:NOTE'           => new NoteStructure(I18N::translate('Note')),
528
                'FAM:SLGS:SOUR'           => new XrefSource(I18N::translate('Source')),
529
                'FAM:SLGS:SOUR:PAGE'      => new WhereWithinSource(I18N::translate('Citation details')),
530
                'FAM:SLGS:SOUR:EVEN'      => new EventTypeCitedFrom(I18N::translate('Event')),
531
                'FAM:SLGS:SOUR:EVEN:ROLE' => new RoleInEvent(I18N::translate('Role')),
532
                'FAM:SLGS:SOUR:DATA'      => new SourceData(I18N::translate('Data')),
533
                'FAM:SLGS:SOUR:DATA:DATE' => new EntryRecordingDate(I18N::translate('Date of entry in original source')),
534
                'FAM:SLGS:SOUR:DATA:TEXT' => new TextFromSource(I18N::translate('Text')),
535
                'FAM:SLGS:SOUR:OBJE'      => new XrefMedia(I18N::translate('Media object')),
536
                'FAM:SLGS:SOUR:NOTE'      => new NoteStructure(I18N::translate('Note')),
537
                'FAM:SLGS:SOUR:QUAY'      => new CertaintyAssessment(I18N::translate('Quality of data')),
538
                'FAM:SOUR'                => new XrefSource(I18N::translate('Source')),
539
                'FAM:SOUR:PAGE'           => new WhereWithinSource(I18N::translate('Citation details')),
540
                'FAM:SOUR:EVEN'           => new EventTypeCitedFrom(I18N::translate('Event')),
541
                'FAM:SOUR:EVEN:ROLE'      => new RoleInEvent(I18N::translate('Role')),
542
                'FAM:SOUR:DATA'           => new SourceData(I18N::translate('Data')),
543
                'FAM:SOUR:DATA:DATE'      => new EntryRecordingDate(I18N::translate('Date of entry in original source')),
544
                'FAM:SOUR:DATA:TEXT'      => new TextFromSource(I18N::translate('Text')),
545
                'FAM:SOUR:OBJE'           => new XrefMedia(I18N::translate('Media object')),
546
                'FAM:SOUR:NOTE'           => new NoteStructure(I18N::translate('Note')),
547
                'FAM:SOUR:QUAY'           => new CertaintyAssessment(I18N::translate('Quality of data')),
548
                'FAM:WIFE'                => new XrefIndividual(I18N::translate('Wife')),
549
                'FAM:_UID'                => new PafUid(I18N::translate('Unique identifier')), // ***
550
                'FAM:*:ADDR'              => new AddressLine(I18N::translate('Address')),
551
                'FAM:*:ADDR:ADR1'         => new AddressLine1(I18N::translate('Address line 1')),
552
                'FAM:*:ADDR:ADR2'         => new AddressLine2(I18N::translate('Address line 2')),
553
                'FAM:*:ADDR:ADR3'         => new AddressLine3(I18N::translate('Address line 3')),
554
                'FAM:*:ADDR:CITY'         => new AddressCity(I18N::translate('City')),
555
                'FAM:*:ADDR:STAE'         => new AddressState(I18N::translate('State')),
556
                'FAM:*:ADDR:POST'         => new AddressPostalCode(I18N::translate('Postal code')),
557
                'FAM:*:ADDR:CTRY'         => new AddressCountry(I18N::translate('Country')),
558
                'FAM:*:AGNC'              => new ResponsibleAgency(I18N::translate('Agency')),
559
                'FAM:*:CAUS'              => new CauseOfEvent(I18N::translate('Cause')),
560
                'FAM:*:DATE'              => new DateValue(I18N::translate('Date')),
561
                'FAM:*:EMAIL'             => new AddressEmail(I18N::translate('Email address')),
562
                'FAM:*:FAX'               => new AddressFax(I18N::translate('Fax')),
563
                'FAM:*:HUSB'              => new EmptyElement(I18N::translate('Husband'), ['AGE' => '0:1']),
564
                'FAM:*:HUSB:AGE'          => new AgeAtEvent(I18N::translate('Husband’s age')),
565
                'FAM:*:NOTE'              => new NoteStructure(I18N::translate('Note')),
566
                'FAM:*:PHON'              => new PhoneNumber(I18N::translate('Phone')),
567
                'FAM:*:PLAC'              => new PlaceName(I18N::translate('Place')),
568
                'FAM:*:PLAC:FORM'         => new PlaceHierarchy(I18N::translate('Format')),
569
                'FAM:*:PLAC:FONE'         => new PlacePhoneticVariation(I18N::translate('Phonetic place')),
570
                'FAM:*:PLAC:FONE:TYPE'    => new PhoneticType(I18N::translate('Type')),
571
                'FAM:*:PLAC:ROMN'         => new PlaceRomanizedVariation(I18N::translate('Romanized place')),
572
                'FAM:*:PLAC:ROMN:TYPE'    => new RomanizedType(I18N::translate('Type')),
573
                'FAM:*:PLAC:MAP'          => new EmptyElement(I18N::translate('Coordinates')),
574
                'FAM:*:PLAC:MAP:LATI'     => new PlaceLatitude(I18N::translate('Latitude')),
575
                'FAM:*:PLAC:MAP:LONG'     => new PlaceLongtitude(I18N::translate('Longitude')),
576
                'FAM:*:PLAC:NOTE'         => new NoteStructure(I18N::translate('Note')),
577
                'FAM:*:OBJE'              => new XrefMedia(I18N::translate('Media object')),
578
                'FAM:*:RELI'              => new ReligiousAffiliation(I18N::translate('Religion')),
579
                'FAM:*:RESN'              => new RestrictionNotice(I18N::translate('Restriction')),
580
                'FAM:*:SOUR'              => new XrefSource(I18N::translate('Source')),
581
                'FAM:*:SOUR:PAGE'         => new WhereWithinSource(I18N::translate('Citation details')),
582
                'FAM:*:SOUR:EVEN'         => new EventTypeCitedFrom(I18N::translate('Event')),
583
                'FAM:*:SOUR:EVEN:ROLE'    => new RoleInEvent(I18N::translate('Role')),
584
                'FAM:*:SOUR:DATA'         => new SourceData(I18N::translate('Data')),
585
                'FAM:*:SOUR:DATA:DATE'    => new EntryRecordingDate(I18N::translate('Date of entry in original source')),
586
                'FAM:*:SOUR:DATA:TEXT'    => new TextFromSource(I18N::translate('Text')),
587
                'FAM:*:SOUR:OBJE'         => new XrefMedia(I18N::translate('Media object')),
588
                'FAM:*:SOUR:NOTE'         => new NoteStructure(I18N::translate('Note')),
589
                'FAM:*:SOUR:QUAY'         => new CertaintyAssessment(I18N::translate('Quality of data')),
590
                'FAM:*:TYPE'              => new EventOrFactClassification(I18N::translate('Type')),
591
                'FAM:*:WIFE'              => new EmptyElement(I18N::translate('Wife'), ['AGE' => '0:1']),
592
                'FAM:*:WIFE:AGE'          => new AgeAtEvent(I18N::translate('Wife’s age')),
593
                'FAM:*:WWW'               => new AddressWebPage(I18N::translate('URL')),
594
                'FAM:*:_ASSO'             => new XrefIndividual(I18N::translate('Associate')), // ***
595
                'FAM:*:_ASSO:RELA'        => new RelationIsDescriptor(I18N::translate('Relationship')), // ***
596
597
                'NOTE'                => new NoteRecord(I18N::translate('Note')),
598
                'NOTE:CONC'           => new SubmitterText(I18N::translate('Note')),
599
                'NOTE:CONT'           => new SubmitterText(I18N::translate('Continued')),
600
                'NOTE:REFN'           => new UserReferenceNumber(I18N::translate('Reference number')),
601
                'NOTE:REFN:TYPE'      => new UserReferenceType(I18N::translate('Type')),
602
                'NOTE:RIN'            => new AutomatedRecordId(I18N::translate('Record ID number')),
603
                'NOTE:SOUR'           => new XrefSource(I18N::translate('Source')),
604
                'NOTE:SOUR:PAGE'      => new WhereWithinSource(I18N::translate('Citation details')),
605
                'NOTE:SOUR:EVEN'      => new EventTypeCitedFrom(I18N::translate('Event')),
606
                'NOTE:SOUR:EVEN:ROLE' => new RoleInEvent(I18N::translate('Role')),
607
                'NOTE:SOUR:DATA'      => new SourceData(I18N::translate('Data')),
608
                'NOTE:SOUR:DATA:DATE' => new EntryRecordingDate(I18N::translate('Date of entry in original source')),
609
                'NOTE:SOUR:DATA:TEXT' => new TextFromSource(I18N::translate('Text')),
610
                'NOTE:SOUR:OBJE'      => new XrefMedia(I18N::translate('Media object')),
611
                'NOTE:SOUR:NOTE'      => new NoteStructure(I18N::translate('Note')),
612
                'NOTE:SOUR:QUAY'      => new CertaintyAssessment(I18N::translate('Quality of data')),
613
                'NOTE:CHAN'           => new Change(I18N::translate('Last change')),
614
                'NOTE:CHAN:DATE'      => new ChangeDate(I18N::translate('Date of last change')),
615
                'NOTE:CHAN:DATE:TIME' => new TimeValue(I18N::translate('Time')),
616
                'NOTE:CHAN:_WT_USER'  => new WebtreesUser(I18N::translate('Author of last change')), // *** webtrees
617
                'NOTE:CHAN:NOTE'      => new NoteStructure(I18N::translate('Note')),
618
                'NOTE:_UID'           => new PafUid(I18N::translate('Unique identifier')), // ***
619
620
                'OBJE'                => new EmptyElement(I18N::translate('Media object')),
621
                'OBJE:FILE'           => new MultimediaFileReference(I18N::translate('Filename')),
622
                'OBJE:FILE:FORM'      => new MultimediaFormat(I18N::translate('Format')),
623
                'OBJE:FILE:FORM:TYPE' => new SourceMediaType(I18N::translate('Media type')),
624
                'OBJE:FILE:TITL'      => new DescriptiveTitle(I18N::translate('Title')),
625
                'OBJE:REFN'           => new UserReferenceNumber(I18N::translate('Reference number')),
626
                'OBJE:REFN:TYPE'      => new UserReferenceType(I18N::translate('Type')),
627
                'OBJE:RIN'            => new AutomatedRecordId(I18N::translate('Record ID number')),
628
                'OBJE:NOTE'           => new NoteStructure(I18N::translate('Note')),
629
                'OBJE:SOUR'           => new XrefSource(I18N::translate('Source')),
630
                'OBJE:SOUR:PAGE'      => new WhereWithinSource(I18N::translate('Citation details')),
631
                'OBJE:SOUR:EVEN'      => new EventTypeCitedFrom(I18N::translate('Event')),
632
                'OBJE:SOUR:EVEN:ROLE' => new RoleInEvent(I18N::translate('Role')),
633
                'OBJE:SOUR:DATA'      => new SourceData(I18N::translate('Data')),
634
                'OBJE:SOUR:DATA:DATE' => new EntryRecordingDate(I18N::translate('Date of entry in original source')),
635
                'OBJE:SOUR:DATA:TEXT' => new TextFromSource(I18N::translate('Text')),
636
                'OBJE:SOUR:OBJE'      => new XrefMedia(I18N::translate('Media object')),
637
                'OBJE:SOUR:NOTE'      => new NoteStructure(I18N::translate('Note')),
638
                'OBJE:SOUR:QUAY'      => new CertaintyAssessment(I18N::translate('Quality of data')),
639
                'OBJE:CHAN'           => new Change(I18N::translate('Last change')),
640
                'OBJE:CHAN:DATE'      => new ChangeDate(I18N::translate('Date of last change')),
641
                'OBJE:CHAN:DATE:TIME' => new TimeValue(I18N::translate('Time')),
642
                'OBJE:CHAN:_WT_USER'  => new WebtreesUser(I18N::translate('Author of last change')), // *** webtrees
643
                'OBJE:CHAN:NOTE'      => new NoteStructure(I18N::translate('Note')),
644
                'OBJE:_UID'           => new PafUid(I18N::translate('Unique identifier')), // ***
645
646
                'REPO'                => new RepositoryRecord(I18N::translate('Repository')),
647
                'REPO:NAME'           => new NameOfRepository(I18N::translateContext('Repository', 'Name')),
648
                'REPO:ADDR'           => new AddressLine(I18N::translate('Address')),
649
                'REPO:ADDR:ADR1'      => new AddressLine1(I18N::translate('Address line 1')),
650
                'REPO:ADDR:ADR2'      => new AddressLine2(I18N::translate('Address line 2')),
651
                'REPO:ADDR:ADR3'      => new AddressLine3(I18N::translate('Address line 3')),
652
                'REPO:ADDR:CITY'      => new AddressCity(I18N::translate('City')),
653
                'REPO:ADDR:STAE'      => new AddressState(I18N::translate('State')),
654
                'REPO:ADDR:POST'      => new AddressPostalCode(I18N::translate('Postal code')),
655
                'REPO:ADDR:CTRY'      => new AddressCountry(I18N::translate('Country')),
656
                'REPO:PHON'           => new PhoneNumber(I18N::translate('Phone')),
657
                'REPO:EMAIL'          => new AddressEmail(I18N::translate('Email address')),
658
                'REPO:FAX'            => new AddressFax(I18N::translate('Fax')),
659
                'REPO:WWW'            => new AddressWebPage(I18N::translate('URL')),
660
                'REPO:NOTE'           => new NoteStructure(I18N::translate('Note')),
661
                'REPO:REFN'           => new UserReferenceNumber(I18N::translate('Reference number')),
662
                'REPO:REFN:TYPE'      => new UserReferenceType(I18N::translate('Type')),
663
                'REPO:RIN'            => new AutomatedRecordId(I18N::translate('Record ID number')),
664
                'REPO:CHAN'           => new Change(I18N::translate('Last change')),
665
                'REPO:CHAN:DATE'      => new ChangeDate(I18N::translate('Date of last change')),
666
                'REPO:CHAN:DATE:TIME' => new TimeValue(I18N::translate('Time')),
667
                'REPO:CHAN:_WT_USER'  => new WebtreesUser(I18N::translate('Author of last change')), // *** webtrees
668
                'REPO:CHAN:NOTE'      => new NoteStructure(I18N::translate('Note')),
669
                'REPO:_UID'           => new PafUid(I18N::translate('Unique identifier')), // ***
670
671
                'SOUR'                => new SourceRecord(I18N::translate('Source')),
672
                'SOUR:DATA'           => new EmptyElement(I18N::translate('Data'), ['EVEN' => '0:M', 'AGNC' => '0:1', 'NOTE' => '0:M']),
673
                'SOUR:DATA:EVEN'      => new EventsRecorded(I18N::translate('Events')),
674
                'SOUR:DATA:EVEN:DATE' => new DateValue(I18N::translate('Date range')),
675
                'SOUR:DATA:EVEN:PLAC' => new SourceJurisdictionPlace(I18N::translate('Place')),
676
                'SOUR:DATA:AGNC'      => new ResponsibleAgency(I18N::translate('Agency')),
677
                'SOUR:DATA:NOTE'      => new NoteStructure(I18N::translate('Note')),
678
                'SOUR:AUTH'           => new SourceOriginator(I18N::translate('Author')),
679
                'SOUR:TITL'           => new DescriptiveTitle(I18N::translate('Title')),
680
                'SOUR:ABBR'           => new SourceFiledByEntry(I18N::translate('Abbreviation')),
681
                'SOUR:PUBL'           => new SourcePublicationFacts(I18N::translate('Publication')),
682
                'SOUR:TEXT'           => new TextFromSource(I18N::translate('Text')),
683
                'SOUR:REPO'           => new XrefRepository(I18N::translate('Repository')),
684
                'SOUR:REPO:NOTE'      => new NoteStructure(I18N::translate('Note')),
685
                'SOUR:REPO:CALN'      => new SourceCallNumber(I18N::translate('Call number')),
686
                'SOUR:REPO:CALN:MEDI' => new SourceMediaType(I18N::translate('Media type')),
687
                'SOUR:REFN'           => new UserReferenceNumber(I18N::translate('Reference number')),
688
                'SOUR:REFN:TYPE'      => new UserReferenceType(I18N::translate('Type')),
689
                'SOUR:RIN'            => new AutomatedRecordId(I18N::translate('Record ID number')),
690
                'SOUR:CHAN'           => new Change(I18N::translate('Last change')),
691
                'SOUR:CHAN:DATE'      => new ChangeDate(I18N::translate('Date of last change')),
692
                'SOUR:CHAN:DATE:TIME' => new TimeValue(I18N::translate('Time')),
693
                'SOUR:CHAN:_WT_USER'  => new WebtreesUser(I18N::translate('Author of last change')), // *** webtrees
694
                'SOUR:CHAN:NOTE'      => new NoteStructure(I18N::translate('Note')),
695
                'SOUR:NOTE'           => new NoteStructure(I18N::translate('Note')),
696
                'SOUR:OBJE'           => new XrefMedia(I18N::translate('Media object')),
697
                'SOUR:_UID'           => new PafUid(I18N::translate('Unique identifier')), // ***
698
699
                'SUBM'                => new SubmitterRecord(I18N::translate('Submitter')),
700
                'SUBM:LANG'           => new LanguageId(I18N::translate('Language')),
701
                'SUBM:NAME'           => new SubmitterName(I18N::translate('Name')),
702
                'SUBM:ADDR'           => new AddressLine(I18N::translate('Address')),
703
                'SUBM:ADDR:ADR1'      => new AddressLine1(I18N::translate('Address line 1')),
704
                'SUBM:ADDR:ADR2'      => new AddressLine2(I18N::translate('Address line 2')),
705
                'SUBM:ADDR:ADR3'      => new AddressLine3(I18N::translate('Address line 3')),
706
                'SUBM:ADDR:CITY'      => new AddressCity(I18N::translate('City')),
707
                'SUBM:ADDR:STAE'      => new AddressState(I18N::translate('State')),
708
                'SUBM:ADDR:POST'      => new AddressPostalCode(I18N::translate('Postal code')),
709
                'SUBM:ADDR:CTRY'      => new AddressCountry(I18N::translate('Country')),
710
                'SUBM:PHON'           => new PhoneNumber(I18N::translate('Phone')),
711
                'SUBM:EMAIL'          => new AddressEmail(I18N::translate('Email address')),
712
                'SUBM:FAX'            => new AddressFax(I18N::translate('Fax')),
713
                'SUBM:WWW'            => new AddressWebPage(I18N::translate('URL')),
714
                'SUBM:OBJE'           => new XrefMedia(I18N::translate('Media object')),
715
                'SUBM:RFN'            => new SubmitterRegisteredRfn(I18N::translate('Record file number')),
716
                'SUBM:RIN'            => new AutomatedRecordId(I18N::translate('Record ID number')),
717
                'SUBM:NOTE'           => new NoteStructure(I18N::translate('Note')),
718
                'SUBM:CHAN'           => new Change(I18N::translate('Last change')),
719
                'SUBM:CHAN:DATE'      => new ChangeDate(I18N::translate('Date of last change')),
720
                'SUBM:CHAN:DATE:TIME' => new TimeValue(I18N::translate('Time')),
721
                'SUBM:CHAN:_WT_USER'  => new WebtreesUser(I18N::translate('Author of last change')), // *** webtrees
722
                'SUBM:CHAN:NOTE'      => new NoteStructure(I18N::translate('Note')),
723
                'SUBM:_UID'           => new PafUid(I18N::translate('Unique identifier')), // ***
724
725
                'SUBN'      => new EmptyElement(I18N::translate('Submission')),
726
                'SUBN:SUBM' => new XrefSubmitter(I18N::translate('Submitter')),
727
                'SUBN:FAMF' => new NameOfFamilyFile(I18N::translate('Family file')),
728
                'SUBN:TEMP' => new TempleCode(/* I18N: https://en.wikipedia.org/wiki/Temple_(LDS_Church)*/ I18N::translate('Temple')),
729
                'SUBN:ANCE' => new GenerationsOfAncestors(I18N::translate('Generations of ancestors')),
730
                'SUBN:DESC' => new GenerationsOfDescendants(I18N::translate('Generations of descendants')),
731
                'SUBN:ORDI' => new OrdinanceProcessFlag(I18N::translate('Ordinance')),
732
                'SUBN:RIN'  => new AutomatedRecordId(I18N::translate('Record ID number')),
733
                'SUBN:NOTE' => new NoteStructure(I18N::translate('Note')),
734
                'SUBN:_UID' => new PafUid(I18N::translate('Unique identifier')), // ***
735
736
                'HEAD'                         => new EmptyElement(I18N::translate('Header')),
737
                'HEAD:SOUR'                    => new ApprovedSystemId('Genealogy software'),
738
                'HEAD:SOUR:VERS'               => new VersionNumber(I18N::translate('Version')),
739
                'HEAD:SOUR:NAME'               => new NameOfProduct('Software product'),
740
                'HEAD:SOUR:CORP'               => new NameOfBusiness(I18N::translate('Corporation')),
741
                'HEAD:SOUR:CORP:ADDR'          => new AddressLine(I18N::translate('Address')),
742
                'HEAD:SOUR:CORP:ADDR:ADR1'     => new AddressLine1(I18N::translate('Address line 1')),
743
                'HEAD:SOUR:CORP:ADDR:ADR2'     => new AddressLine2(I18N::translate('Address line 2')),
744
                'HEAD:SOUR:CORP:ADDR:ADR3'     => new AddressLine3(I18N::translate('Address line 3')),
745
                'HEAD:SOUR:CORP:ADDR:CITY'     => new AddressCity(I18N::translate('City')),
746
                'HEAD:SOUR:CORP:ADDR:STAE'     => new AddressState(I18N::translate('State')),
747
                'HEAD:SOUR:CORP:ADDR:POST'     => new AddressPostalCode(I18N::translate('Postal code')),
748
                'HEAD:SOUR:CORP:ADDR:CTRY'     => new AddressCountry(I18N::translate('Country')),
749
                'HEAD:SOUR:CORP:PHON'          => new PhoneNumber(I18N::translate('Phone')),
750
                'HEAD:SOUR:CORP:EMAIL'         => new AddressEmail(I18N::translate('Email address')),
751
                'HEAD:SOUR:CORP:FAX'           => new AddressFax(I18N::translate('Fax')),
752
                'HEAD:SOUR:CORP:WWW'           => new AddressWebPage(I18N::translate('URL')),
753
                'HEAD:SOUR:DATA'               => new NameOfSourceData('Data'),
754
                'HEAD:SOUR:DATA:DATE'          => new PublicationDate(I18N::translate('Date')),
755
                'HEAD:SOUR:DATA:COPR'          => new CopyrightSourceData(I18N::translate('Copyright')),
756
                'HEAD:DEST'                    => new ReceivingSystemName(I18N::translate('Destination')),
757
                'HEAD:DATE'                    => new TransmissionDate(I18N::translate('Date')),
758
                'HEAD:DATE:TIME'               => new TimeValue(I18N::translate('Time')),
759
                'HEAD:SUBM'                    => new XrefSubmitter(I18N::translate('Submitter')),
760
                'HEAD:SUBN'                    => new XrefSubmission(I18N::translate('Submission')),
761
                'HEAD:FILE'                    => new FileName(I18N::translate('Filename')),
762
                'HEAD:COPR'                    => new CopyrightFile(I18N::translate('Copyright')),
763
                'HEAD:GEDC'                    => new Gedcom(I18N::translate('GEDCOM file')),
764
                'HEAD:GEDC:VERS'               => new VersionNumber(I18N::translate('Version')),
765
                'HEAD:GEDC:FORM'               => new Form(I18N::translate('Format')),
766
                'HEAD:CHAR'                    => new CharacterSet(I18N::translate('Character set')),
767
                'HEAD:CHAR:VERS'               => new VersionNumber(I18N::translate('Version')),
768
                'HEAD:PLAC'                    => new EmptyElement(I18N::translate('Place')),
769
                'HEAD:PLAC:FORM'               => new PlaceHierarchy(I18N::translate('Format')),
770
                'HEAD:NOTE'                    => new ContentDescription(I18N::translate('Note')),
771
772
                'TRLR' => new EmptyElement(I18N::translate('Trailer')), // Not used in webtrees
773
            ];
774
        }
775
776
        return $this->elements;
777
    }
778
}
779