xref: /webtrees/app/Module/LanguageEnglishUnitedStates.php (revision 92a78a2f1d314ef404e1445d7916cbee426ce636)
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\Module;
21
22use Fisharebest\Localization\Locale\LocaleEnUs;
23use Fisharebest\Localization\Locale\LocaleInterface;
24use Fisharebest\Webtrees\Relationship;
25
26use function abs;
27use function min;
28use function str_repeat;
29
30/**
31 * Class LanguageEnglishUnitedStates.
32 */
33class LanguageEnglishUnitedStates extends AbstractModule implements ModuleLanguageInterface
34{
35    use ModuleLanguageTrait;
36
37    protected const COUSIN = [
38        'sibling',
39        'first cousin',
40        'second cousin',
41        'third cousin',
42        'fourth cousin',
43        'fifth cousin',
44        'sixth cousin',
45        'seventh cousin',
46        'eighth cousin',
47        'ninth cousin',
48        'tenth cousin',
49        'eleventh cousin',
50        'twelfth cousin',
51        'thirteenth cousin',
52        'fourteenth cousin',
53        'fifteenth cousin',
54        'sixteenth cousin',
55        'seventeenth cousin',
56        'eighteenth cousin',
57        'nineteenth cousin',
58        'twentieth cousin',
59        'twenty-first cousin',
60        'twenty-second cousin',
61        'twenty-third cousin',
62        'twenty-fourth cousin',
63        'twenty-fifth cousin',
64        'twenty-sixth cousin',
65        'twenty-seventh cousin',
66        'twenty-eighth cousin',
67        'twenty-ninth cousin',
68        'thirtieth cousin',
69    ];
70
71    protected const REMOVED = [
72        '',
73        ' once removed',
74        ' twice removed',
75        ' three times removed',
76        ' four times removed',
77        ' five times removed',
78        ' six times removed',
79        ' seven times removed',
80        ' eight times removed',
81        ' nine times removed',
82        ' ten times removed',
83        ' eleven removed',
84        ' twelve removed',
85        ' thirteen removed',
86        ' fourteen times removed',
87        ' fifteen times removed',
88        ' sixteen times removed',
89        ' seventeen times removed',
90        ' eighteen times removed',
91        ' nineteen times removed',
92        ' twenty times removed',
93        ' twenty-one times removed',
94        ' twenty-two times removed',
95        ' twenty-three times removed',
96        ' twenty-four times removed',
97        ' twenty-five times removed',
98        ' twenty-six times removed',
99        ' twenty-seven times removed',
100        ' twenty-eight times removed',
101        ' twenty-nine times removed',
102    ];
103
104    protected const DIRECTION = [
105        -1 => ' descending',
106        0  => '',
107        1  => ' ascending',
108    ];
109
110    /**
111     * @return LocaleInterface
112     */
113    public function locale(): LocaleInterface
114    {
115        return new LocaleEnUs();
116    }
117
118    /**
119     * @return array<Relationship>
120     */
121    public function relationships(): array
122    {
123        // Genitive forms in English are simple/regular, as no relationship name ends in "s".
124        $genitive = static fn (string $s): array => [$s, $s . '’s %s'];
125
126        $cousin = fn (int $up, int $down): array => $genitive(
127            (static::COUSIN[min($up, $down)] ?? 'distant cousin') .
128            (static::REMOVED[abs($up - $down)] ?? ' many times removed') .
129            static::DIRECTION[$up <=> $down]
130        );
131
132        $great = static fn (int $n, string $prefix, string $suffix): array => $genitive(
133            $prefix . ($n > 3 ? 'great ×' . $n . ' ' : str_repeat('great-', $n)) . $suffix
134        );
135
136        return [
137            // Adopted
138            Relationship::fixed('adoptive-mother', 'adoptive-mother’s %s')->adoptive()->mother(),
139            Relationship::fixed('adoptive-father', 'adoptive-father’s %s')->adoptive()->father(),
140            Relationship::fixed('adoptive-parent', 'adoptive-parent’s %s')->adoptive()->parent(),
141            Relationship::fixed('adopted-daughter', 'adopted-daughter’s %s')->adopted()->daughter(),
142            Relationship::fixed('adopted-son', 'adopted-son’s %s')->adopted()->son(),
143            Relationship::fixed('adopted-child', 'adopted-child’s %s')->adopted()->child(),
144            // Fostered
145            Relationship::fixed('foster-mother', 'foster-mother’s %s')->fostering()->mother(),
146            Relationship::fixed('foster-father', 'foster-father’s %s')->fostering()->father(),
147            Relationship::fixed('foster-parent', 'foster-parent’s %s')->fostering()->parent(),
148            Relationship::fixed('foster-daughter', 'foster-daughter’s %s')->fostered()->daughter(),
149            Relationship::fixed('foster-son', 'foster-son’s %s')->fostered()->son(),
150            Relationship::fixed('foster-child', 'foster-child’s %s')->fostered()->child(),
151            // Parents
152            Relationship::fixed('mother', 'mother’s %s')->mother(),
153            Relationship::fixed('father', 'father’s %s')->father(),
154            Relationship::fixed('parent', 'parent’s %s')->parent(),
155            // Children
156            Relationship::fixed('daughter', 'daughter’s %s')->daughter(),
157            Relationship::fixed('son', 'son’s %s')->son(),
158            Relationship::fixed('child', 'child’s %s')->child(),
159            // Siblings
160            Relationship::fixed('twin sister', 'twin sister’s %s')->twin()->sister(),
161            Relationship::fixed('twin brother', 'twin brother’s %s')->twin()->brother(),
162            Relationship::fixed('twin sibling', 'twin sibling’s %s')->twin()->sibling(),
163            Relationship::fixed('elder sister', 'elder sister’s %s')->older()->sister(),
164            Relationship::fixed('elder brother', 'elder brother’s %s')->older()->brother(),
165            Relationship::fixed('elder sibling', 'elder sibling’s %s')->older()->sibling(),
166            Relationship::fixed('younger sister', 'younger sister’s %s')->younger()->sister(),
167            Relationship::fixed('younger brother', 'younger brother’s %s')->younger()->brother(),
168            Relationship::fixed('younger sibling', 'younger sibling’s %s')->younger()->sibling(),
169            Relationship::fixed('sister', 'sister’s %s')->sister(),
170            Relationship::fixed('brother', 'brother’s %s')->brother(),
171            Relationship::fixed('sibling', 'sibling’s %s')->sibling(),
172            // Half-siblings
173            Relationship::fixed('half-sister', 'half-sister’s %s')->parent()->daughter(),
174            Relationship::fixed('half-brother', 'half-brother’s %s')->parent()->son(),
175            Relationship::fixed('half-sibling', 'half-sibling’s %s')->parent()->child(),
176            // Stepfamily
177            Relationship::fixed('stepmother', 'stepmother’s %s')->parent()->wife(),
178            Relationship::fixed('stepfather', 'stepfather’s %s')->parent()->husband(),
179            Relationship::fixed('stepparent', 'stepparent’s %s')->parent()->married()->spouse(),
180            Relationship::fixed('stepdaughter', 'stepdaughter’s %s')->married()->spouse()->daughter(),
181            Relationship::fixed('stepson', 'stepson’s %s')->married()->spouse()->son(),
182            Relationship::fixed('stepchild', 'stepchild’s %s')->married()->spouse()->child(),
183            Relationship::fixed('stepsister', 'stepsister’s %s')->parent()->spouse()->daughter(),
184            Relationship::fixed('stepbrother', 'stepbrother’s %s')->parent()->spouse()->son(),
185            Relationship::fixed('stepsibling', 'stepsibling’s %s')->parent()->spouse()->child(),
186            // Partners
187            Relationship::fixed('ex-wife', 'ex-wife’s %s')->divorced()->partner()->female(),
188            Relationship::fixed('ex-husband', 'ex-husband’s %s')->divorced()->partner()->male(),
189            Relationship::fixed('ex-spouse', 'ex-spouse’s %s')->divorced()->partner(),
190            Relationship::fixed('fiancée', 'fiancée’s %s')->engaged()->partner()->female(),
191            Relationship::fixed('fiancé', 'fiancé’s %s')->engaged()->partner()->male(),
192            Relationship::fixed('wife', 'wife’s %s')->wife(),
193            Relationship::fixed('husband', 'husband’s %s')->husband(),
194            Relationship::fixed('spouse', 'spouse’s %s')->spouse(),
195            Relationship::fixed('partner', 'partner’s %s')->partner(),
196            // In-laws
197            Relationship::fixed('mother-in-law', 'mother-in-law’s %s')->married()->spouse()->mother(),
198            Relationship::fixed('father-in-law', 'father-in-law’s %s')->married()->spouse()->father(),
199            Relationship::fixed('parent-in-law', 'parent-in-law’s %s')->married()->spouse()->parent(),
200            Relationship::fixed('daughter-in-law', 'daughter-in-law’s %s')->child()->wife(),
201            Relationship::fixed('son-in-law', 'son-in-law’s %s')->child()->husband(),
202            Relationship::fixed('child-in-law', 'child-in-law’s %s')->child()->married()->spouse(),
203            Relationship::fixed('sister-in-law', 'sister-in-law’s %s')->sibling()->spouse()->sister(),
204            Relationship::fixed('brother-in-law', 'brother-in-law’s %s')->sibling()->spouse()->brother(),
205            Relationship::fixed('sibling-in-law', 'sibling-in-law’s %s')->sibling()->spouse()->sibling(),
206            Relationship::fixed('sister-in-law', 'sister-in-law’s %s')->spouse()->sister(),
207            Relationship::fixed('brother-in-law', 'brother-in-law’s %s')->spouse()->brother(),
208            Relationship::fixed('sibling-in-law', 'sibling-in-law’s %s')->spouse()->sibling(),
209            Relationship::fixed('sister-in-law', 'sister-in-law’s %s')->sibling()->wife(),
210            Relationship::fixed('brother-in-law', 'brother-in-law’s %s')->sibling()->husband(),
211            Relationship::fixed('sibling-in-law', 'sibling-in-law’s %s')->sibling()->spouse(),
212            // Grandparents
213            Relationship::fixed('maternal-grandmother', 'maternal-grandmother’s %s')->mother()->mother(),
214            Relationship::fixed('maternal-grandfather', 'maternal-grandfather’s %s')->mother()->father(),
215            Relationship::fixed('maternal-grandparent', 'maternal-grandfather’s %s')->mother()->parent(),
216            Relationship::fixed('paternal-grandmother', 'paternal-grandmother’s %s')->father()->mother(),
217            Relationship::fixed('paternal-grandfather', 'paternal-grandfather’s %s')->father()->father(),
218            Relationship::fixed('paternal-grandparent', 'paternal-grandfather’s %s')->father()->parent(),
219            Relationship::fixed('grandmother', 'grandmother’s %s')->parent()->mother(),
220            Relationship::fixed('grandfather', 'grandfather’s %s')->parent()->father(),
221            Relationship::fixed('grandparent', 'grandparent’s %s')->parent()->parent(),
222            // Grandchildren
223            Relationship::fixed('granddaughter', 'granddaughter’s %s')->child()->daughter(),
224            Relationship::fixed('grandson', 'grandson’s %s')->child()->son(),
225            Relationship::fixed('grandchild', 'grandchild’s %s')->child()->child(),
226            // Relationships with dynamically generated names
227            Relationship::dynamic(fn (int $n) => $great($n - 1, '', 'aunt'))->ancestor()->sister(),
228            Relationship::dynamic(fn (int $n) => $great($n - 1, '', 'aunt'))->ancestor()->sibling()->wife(),
229            Relationship::dynamic(fn (int $n) => $great($n - 1, '', 'uncle'))->ancestor()->brother(),
230            Relationship::dynamic(fn (int $n) => $great($n - 1, '', 'uncle'))->ancestor()->sibling()->husband(),
231            Relationship::dynamic(fn (int $n) => $great($n - 1, '', 'niece'))->sibling()->descendant()->female(),
232            Relationship::dynamic(fn (int $n) => $great($n - 1, '', 'niece'))->married()->spouse()->sibling()->descendant()->female(),
233            Relationship::dynamic(fn (int $n) => $great($n - 1, '', 'nephew'))->sibling()->descendant()->male(),
234            Relationship::dynamic(fn (int $n) => $great($n - 1, '', 'nephew'))->married()->spouse()->sibling()->descendant()->male(),
235            Relationship::dynamic(fn (int $n) => $great($n - 2, 'maternal ', 'grandmother'))->mother()->ancestor()->female(),
236            Relationship::dynamic(fn (int $n) => $great($n - 1, 'maternal ', 'grandfather'))->mother()->ancestor()->male(),
237            Relationship::dynamic(fn (int $n) => $great($n - 1, 'paternal ', 'grandmother'))->father()->ancestor()->female(),
238            Relationship::dynamic(fn (int $n) => $great($n - 1, 'paternal ', 'grandfather'))->father()->ancestor()->male(),
239            Relationship::dynamic(fn (int $n) => $great($n - 1, '', 'grandparent'))->ancestor(),
240            Relationship::dynamic(fn (int $n) => $great($n - 2, '', 'granddaughter'))->descendant()->female(),
241            Relationship::dynamic(fn (int $n) => $great($n - 2, '', 'grandson'))->descendant()->male(),
242            Relationship::dynamic(fn (int $n) => $great($n - 2, '', 'grandchild'))->descendant(),
243            Relationship::dynamic($cousin)->ancestor()->sibling()->descendant(),
244        ];
245    }
246}
247