xref: /webtrees/app/Services/RelationshipService.php (revision 82566d1a9ac066737216c0ba8de6fc580d88120c)
16fcafd02SGreg Roach<?php
26fcafd02SGreg Roach
36fcafd02SGreg Roach/**
46fcafd02SGreg Roach * webtrees: online genealogy
56fcafd02SGreg Roach * Copyright (C) 2021 webtrees development team
66fcafd02SGreg Roach * This program is free software: you can redistribute it and/or modify
76fcafd02SGreg Roach * it under the terms of the GNU General Public License as published by
86fcafd02SGreg Roach * the Free Software Foundation, either version 3 of the License, or
96fcafd02SGreg Roach * (at your option) any later version.
106fcafd02SGreg Roach * This program is distributed in the hope that it will be useful,
116fcafd02SGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of
126fcafd02SGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
136fcafd02SGreg Roach * GNU General Public License for more details.
146fcafd02SGreg Roach * You should have received a copy of the GNU General Public License
156fcafd02SGreg Roach * along with this program. If not, see <https://www.gnu.org/licenses/>.
166fcafd02SGreg Roach */
176fcafd02SGreg Roach
186fcafd02SGreg Roachdeclare(strict_types=1);
196fcafd02SGreg Roach
206fcafd02SGreg Roachnamespace Fisharebest\Webtrees\Services;
216fcafd02SGreg Roach
226fcafd02SGreg Roachuse Fisharebest\Webtrees\Auth;
236fcafd02SGreg Roachuse Fisharebest\Webtrees\Fact;
246fcafd02SGreg Roachuse Fisharebest\Webtrees\Family;
256fcafd02SGreg Roachuse Fisharebest\Webtrees\I18N;
266fcafd02SGreg Roachuse Fisharebest\Webtrees\Individual;
276fcafd02SGreg Roachuse Fisharebest\Webtrees\Module\ModuleLanguageInterface;
286fcafd02SGreg Roachuse Fisharebest\Webtrees\Relationship;
296fcafd02SGreg Roach
306fcafd02SGreg Roachuse function abs;
316fcafd02SGreg Roachuse function array_key_exists;
326fcafd02SGreg Roachuse function array_merge;
336fcafd02SGreg Roachuse function array_reduce;
346fcafd02SGreg Roachuse function array_slice;
356fcafd02SGreg Roachuse function count;
366fcafd02SGreg Roachuse function implode;
376fcafd02SGreg Roachuse function intdiv;
386fcafd02SGreg Roachuse function min;
396fcafd02SGreg Roachuse function preg_match;
406fcafd02SGreg Roachuse function sprintf;
416fcafd02SGreg Roachuse function strlen;
426fcafd02SGreg Roachuse function substr;
436fcafd02SGreg Roach
446fcafd02SGreg Roach/**
456fcafd02SGreg Roach * Names for relationships.
466fcafd02SGreg Roach */
476fcafd02SGreg Roachclass RelationshipService
486fcafd02SGreg Roach{
496fcafd02SGreg Roach    private const COMPONENTS = [
506fcafd02SGreg Roach        'CHIL' => [
516fcafd02SGreg Roach            'CHIL' => Relationship::SIBLINGS,
526fcafd02SGreg Roach            'HUSB' => Relationship::PARENTS,
536fcafd02SGreg Roach            'WIFE' => Relationship::PARENTS,
546fcafd02SGreg Roach        ],
556fcafd02SGreg Roach        'HUSB' => [
566fcafd02SGreg Roach            'CHIL' => Relationship::CHILDREN,
576fcafd02SGreg Roach            'HUSB' => Relationship::SPOUSES,
586fcafd02SGreg Roach            'WIFE' => Relationship::SPOUSES,
596fcafd02SGreg Roach        ],
606fcafd02SGreg Roach        'WIFE' => [
616fcafd02SGreg Roach            'CHIL' => Relationship::CHILDREN,
626fcafd02SGreg Roach            'HUSB' => Relationship::SPOUSES,
636fcafd02SGreg Roach            'WIFE' => Relationship::SPOUSES,
646fcafd02SGreg Roach        ],
656fcafd02SGreg Roach    ];
666fcafd02SGreg Roach
676fcafd02SGreg Roach    /**
686fcafd02SGreg Roach     * For close family relationships, such as the families tab, associates, and the family navigator.
696fcafd02SGreg Roach     *
706fcafd02SGreg Roach     * @param Individual $individual1
716fcafd02SGreg Roach     * @param Individual $individual2
726fcafd02SGreg Roach     *
736fcafd02SGreg Roach     * @return string
746fcafd02SGreg Roach     */
756fcafd02SGreg Roach    public function getCloseRelationshipName(Individual $individual1, Individual $individual2): string
766fcafd02SGreg Roach    {
776fcafd02SGreg Roach        $language = app(ModuleService::class)
786fcafd02SGreg Roach            ->findByInterface(ModuleLanguageInterface::class, true)
796fcafd02SGreg Roach            ->first(fn (ModuleLanguageInterface $language): bool => $language->locale()->languageTag() === I18N::languageTag());
806fcafd02SGreg Roach
816fcafd02SGreg Roach        $path = $this->getCloseRelationship($individual1, $individual2);
826fcafd02SGreg Roach
836fcafd02SGreg Roach        // No relationship found?
846fcafd02SGreg Roach        if ($path === []) {
856fcafd02SGreg Roach            return '';
866fcafd02SGreg Roach        }
876fcafd02SGreg Roach
886fcafd02SGreg Roach        return $this->nameFromPath($path, $language);
896fcafd02SGreg Roach    }
906fcafd02SGreg Roach
916fcafd02SGreg Roach    /**
926fcafd02SGreg Roach     * Get relationship between two individuals in the gedcom.  This function
936fcafd02SGreg Roach     * takes account of pending changes, so we can display names of newly added
946fcafd02SGreg Roach     * relations.
956fcafd02SGreg Roach     *
966fcafd02SGreg Roach     * @param Individual $individual1
976fcafd02SGreg Roach     * @param Individual $individual2
986fcafd02SGreg Roach     * @param int        $maxlength
996fcafd02SGreg Roach     *
1006fcafd02SGreg Roach     * @return array<Individual|Family> An array of nodes on the relationship path
1016fcafd02SGreg Roach     */
1026fcafd02SGreg Roach    private function getCloseRelationship(Individual $individual1, Individual $individual2, int $maxlength = 4): array
1036fcafd02SGreg Roach    {
1046fcafd02SGreg Roach        if ($individual1 === $individual2) {
1056fcafd02SGreg Roach            return [$individual1];
1066fcafd02SGreg Roach        }
1076fcafd02SGreg Roach
1086fcafd02SGreg Roach        // Only examine each individual once
1096fcafd02SGreg Roach        $visited = [
1106fcafd02SGreg Roach            $individual1->xref() => true,
1116fcafd02SGreg Roach        ];
1126fcafd02SGreg Roach
1136fcafd02SGreg Roach        // Build paths out from the first individual
1146fcafd02SGreg Roach        $paths = [
1156fcafd02SGreg Roach            [$individual1],
1166fcafd02SGreg Roach        ];
1176fcafd02SGreg Roach
1186fcafd02SGreg Roach        // Loop over paths of length 1, 2, 3, ...
1196fcafd02SGreg Roach        while ($maxlength >= 0) {
1206fcafd02SGreg Roach            $maxlength--;
1216fcafd02SGreg Roach
1226fcafd02SGreg Roach            foreach ($paths as $i => $path) {
1236fcafd02SGreg Roach                // Try each new relation from the end of the path
1246fcafd02SGreg Roach                $indi = $path[count($path) - 1];
1256fcafd02SGreg Roach
1266fcafd02SGreg Roach                // Parents and siblings
1276fcafd02SGreg Roach                foreach ($indi->childFamilies(Auth::PRIV_HIDE) as $family) {
1286fcafd02SGreg Roach                    $visited[$family->xref()] = true;
1296fcafd02SGreg Roach                    foreach ($family->spouses(Auth::PRIV_HIDE) as $spouse) {
1306fcafd02SGreg Roach                        if (!isset($visited[$spouse->xref()])) {
1316fcafd02SGreg Roach                            $new_path   = $path;
1326fcafd02SGreg Roach                            $new_path[] = $family;
1336fcafd02SGreg Roach                            $new_path[] = $spouse;
1346fcafd02SGreg Roach                            if ($spouse === $individual2) {
1356fcafd02SGreg Roach                                return $new_path;
1366fcafd02SGreg Roach                            }
1376fcafd02SGreg Roach
1386fcafd02SGreg Roach                            $paths[]                  = $new_path;
1396fcafd02SGreg Roach                            $visited[$spouse->xref()] = true;
1406fcafd02SGreg Roach                        }
1416fcafd02SGreg Roach                    }
1426fcafd02SGreg Roach                    foreach ($family->children(Auth::PRIV_HIDE) as $child) {
1436fcafd02SGreg Roach                        if (!isset($visited[$child->xref()])) {
1446fcafd02SGreg Roach                            $new_path   = $path;
1456fcafd02SGreg Roach                            $new_path[] = $family;
1466fcafd02SGreg Roach                            $new_path[] = $child;
1476fcafd02SGreg Roach                            if ($child === $individual2) {
1486fcafd02SGreg Roach                                return $new_path;
1496fcafd02SGreg Roach                            }
1506fcafd02SGreg Roach
1516fcafd02SGreg Roach                            $paths[]                 = $new_path;
1526fcafd02SGreg Roach                            $visited[$child->xref()] = true;
1536fcafd02SGreg Roach                        }
1546fcafd02SGreg Roach                    }
1556fcafd02SGreg Roach                }
1566fcafd02SGreg Roach
1576fcafd02SGreg Roach                // Spouses and children
1586fcafd02SGreg Roach                foreach ($indi->spouseFamilies(Auth::PRIV_HIDE) as $family) {
1596fcafd02SGreg Roach                    $visited[$family->xref()] = true;
1606fcafd02SGreg Roach                    foreach ($family->spouses(Auth::PRIV_HIDE) as $spouse) {
1616fcafd02SGreg Roach                        if (!isset($visited[$spouse->xref()])) {
1626fcafd02SGreg Roach                            $new_path   = $path;
1636fcafd02SGreg Roach                            $new_path[] = $family;
1646fcafd02SGreg Roach                            $new_path[] = $spouse;
1656fcafd02SGreg Roach                            if ($spouse === $individual2) {
1666fcafd02SGreg Roach                                return $new_path;
1676fcafd02SGreg Roach                            }
1686fcafd02SGreg Roach
1696fcafd02SGreg Roach                            $paths[]                  = $new_path;
1706fcafd02SGreg Roach                            $visited[$spouse->xref()] = true;
1716fcafd02SGreg Roach                        }
1726fcafd02SGreg Roach                    }
1736fcafd02SGreg Roach                    foreach ($family->children(Auth::PRIV_HIDE) as $child) {
1746fcafd02SGreg Roach                        if (!isset($visited[$child->xref()])) {
1756fcafd02SGreg Roach                            $new_path   = $path;
1766fcafd02SGreg Roach                            $new_path[] = $family;
1776fcafd02SGreg Roach                            $new_path[] = $child;
1786fcafd02SGreg Roach                            if ($child === $individual2) {
1796fcafd02SGreg Roach                                return $new_path;
1806fcafd02SGreg Roach                            }
1816fcafd02SGreg Roach
1826fcafd02SGreg Roach                            $paths[]                 = $new_path;
1836fcafd02SGreg Roach                            $visited[$child->xref()] = true;
1846fcafd02SGreg Roach                        }
1856fcafd02SGreg Roach                    }
1866fcafd02SGreg Roach                }
1876fcafd02SGreg Roach                unset($paths[$i]);
1886fcafd02SGreg Roach            }
1896fcafd02SGreg Roach        }
1906fcafd02SGreg Roach
1916fcafd02SGreg Roach        return [];
1926fcafd02SGreg Roach    }
1936fcafd02SGreg Roach
1946fcafd02SGreg Roach    /**
1956fcafd02SGreg Roach     * @param array<Individual|Family> $nodes
1966fcafd02SGreg Roach     * @param ModuleLanguageInterface  $language
1976fcafd02SGreg Roach     *
1986fcafd02SGreg Roach     * @return string
1996fcafd02SGreg Roach     */
2006fcafd02SGreg Roach    public function nameFromPath(array $nodes, ModuleLanguageInterface $language): string
2016fcafd02SGreg Roach    {
2026fcafd02SGreg Roach        // The relationship matching algorithm could be used for this, but it is more efficient to check it here.
2036fcafd02SGreg Roach        if (count($nodes) === 1) {
2046fcafd02SGreg Roach            return $this->reflexivePronoun($nodes[0]);
2056fcafd02SGreg Roach        }
2066fcafd02SGreg Roach
2076fcafd02SGreg Roach        // The relationship definitions for the language.
2086fcafd02SGreg Roach        $relationships = $language->relationships();
2096fcafd02SGreg Roach
2106fcafd02SGreg Roach        // We don't strictly need this, as all the information is contained in the nodes.
2116fcafd02SGreg Roach        // But it gives us simpler code and better performance.
2126fcafd02SGreg Roach        // It is also needed for the legacy algorithm.
2136fcafd02SGreg Roach        $pattern = $this->components($nodes);
2146fcafd02SGreg Roach
2156fcafd02SGreg Roach        // No definitions for this language?  Use the legacy algorithm.
2166fcafd02SGreg Roach        if ($relationships === []) {
2176fcafd02SGreg Roach            return $this->legacyNameAlgorithm(implode('', $pattern), $nodes[0], $nodes[count($nodes) - 1]);
2186fcafd02SGreg Roach        }
2196fcafd02SGreg Roach
2206fcafd02SGreg Roach        // Match the relationship, using a longest-substring algorithm.
2216fcafd02SGreg Roach        $relationships = $this->matchRelationships($nodes, $pattern, $relationships);
2226fcafd02SGreg Roach
2236fcafd02SGreg Roach        // Reduce the genitive-nominative chain to a single string.
2246fcafd02SGreg Roach        return array_reduce($relationships, static function (array $carry, array $item): array {
2256fcafd02SGreg Roach            return [sprintf($carry[1], $item[0]), sprintf($carry[1], $item[1])];
226b6adeac8SJonathan Jaubart        }, [0 => '', 1 => '%s'])[0];
2276fcafd02SGreg Roach    }
2286fcafd02SGreg Roach
2296fcafd02SGreg Roach    /**
2306fcafd02SGreg Roach     * Generate a reflexive pronoun for an individual
2316fcafd02SGreg Roach     *
2326fcafd02SGreg Roach     * @param Individual $individual
2336fcafd02SGreg Roach     *
2346fcafd02SGreg Roach     * @return string
2356fcafd02SGreg Roach     */
2366fcafd02SGreg Roach    protected function reflexivePronoun(Individual $individual): string
2376fcafd02SGreg Roach    {
2386fcafd02SGreg Roach        switch ($individual->sex()) {
2396fcafd02SGreg Roach            case 'M':
2406fcafd02SGreg Roach                /* I18N: reflexive pronoun */
2416fcafd02SGreg Roach                return I18N::translate('himself');
2426fcafd02SGreg Roach            case 'F':
2436fcafd02SGreg Roach                /* I18N: reflexive pronoun */
2446fcafd02SGreg Roach                return I18N::translate('herself');
2456fcafd02SGreg Roach            default:
2466fcafd02SGreg Roach                /* I18N: reflexive pronoun - gender neutral version of himself/herself */
2476fcafd02SGreg Roach                return I18N::translate('themself');
2486fcafd02SGreg Roach        }
2496fcafd02SGreg Roach    }
2506fcafd02SGreg Roach
2516fcafd02SGreg Roach    /**
2526fcafd02SGreg Roach     * Convert a relationship path into its component pieces; brother, wife, mother, daughter, etc.
2536fcafd02SGreg Roach     *
2546fcafd02SGreg Roach     * @param array<Individual|Family> $nodes - Alternating list of Individual and Family objects
2556fcafd02SGreg Roach     *
2566fcafd02SGreg Roach     * @return array<string>
2576fcafd02SGreg Roach     */
2586fcafd02SGreg Roach    private function components(array $nodes): array
2596fcafd02SGreg Roach    {
2606fcafd02SGreg Roach        $pattern = [];
2616fcafd02SGreg Roach
2626fcafd02SGreg Roach        $count = count($nodes);
2636fcafd02SGreg Roach
2646fcafd02SGreg Roach        for ($i = 1; $i < $count; $i += 2) {
2656fcafd02SGreg Roach            $prev   = $nodes[$i - 1];
2666fcafd02SGreg Roach            $family = $nodes[$i];
2676fcafd02SGreg Roach            $next   = $nodes[$i + 1];
2686fcafd02SGreg Roach
2696fcafd02SGreg Roach            preg_match('/\n1 (HUSB|WIFE|CHIL) @' . $prev->xref() . '@/', $family->gedcom(), $match);
2706fcafd02SGreg Roach            $rel1 = $match[1] ?? 'xxx';
2716fcafd02SGreg Roach
2726fcafd02SGreg Roach            preg_match('/\n1 (HUSB|WIFE|CHIL) @' . $next->xref() . '@/', $family->gedcom(), $match);
2736fcafd02SGreg Roach            $rel2 = $match[1] ?? 'xxx';
2746fcafd02SGreg Roach
2756fcafd02SGreg Roach            $pattern[] = self::COMPONENTS[$rel1][$rel2][$next->sex()] ?? 'xxx';
2766fcafd02SGreg Roach        }
2776fcafd02SGreg Roach
2786fcafd02SGreg Roach        return $pattern;
2796fcafd02SGreg Roach    }
2806fcafd02SGreg Roach
2816fcafd02SGreg Roach    /**
2826fcafd02SGreg Roach     * @param array<Individual|Family> $nodes
2836fcafd02SGreg Roach     * @param array<string>            $pattern
2846fcafd02SGreg Roach     * @param array<Relationship>      $relationships
2856fcafd02SGreg Roach     *
2866fcafd02SGreg Roach     * @return array<Relationship>
2876fcafd02SGreg Roach     */
2886fcafd02SGreg Roach    protected function matchRelationships(array $nodes, array $pattern, array $relationships): array
2896fcafd02SGreg Roach    {
2906fcafd02SGreg Roach        $count = count($pattern);
2916fcafd02SGreg Roach
2926fcafd02SGreg Roach        // Look for the longest matchable series of components
2936fcafd02SGreg Roach        for ($length = $count; $length > 0; $length--) {
2946fcafd02SGreg Roach            for ($start = $count - $length; $start >= 0; $start--) {
2956fcafd02SGreg Roach                foreach ($relationships as $relationship) {
2966fcafd02SGreg Roach                    $path_slice    = array_slice($nodes, $start * 2, $length * 2 + 1);
2976fcafd02SGreg Roach                    $pattern_slice = array_slice($pattern, $start, $length);
2986fcafd02SGreg Roach                    $result        = $relationship->match($path_slice, $pattern_slice);
2996fcafd02SGreg Roach
3006fcafd02SGreg Roach                    if ($result !== null) {
3016fcafd02SGreg Roach                        $nodes_before   = array_slice($nodes, 0, $start * 2 + 1);
3026fcafd02SGreg Roach                        $pattern_before = array_slice($pattern, 0, $start);
3036fcafd02SGreg Roach                        $result_before  = $this->matchRelationships($nodes_before, $pattern_before, $relationships);
3046fcafd02SGreg Roach
3056fcafd02SGreg Roach                        $nodes_after   = array_slice($nodes, ($start + $length) * 2);
3066fcafd02SGreg Roach                        $pattern_after = array_slice($pattern, $start + $length);
3076fcafd02SGreg Roach                        $result_after  = $this->matchRelationships($nodes_after, $pattern_after, $relationships);
3086fcafd02SGreg Roach
3096fcafd02SGreg Roach                        return array_merge($result_before, [$result], $result_after);
3106fcafd02SGreg Roach                    }
3116fcafd02SGreg Roach                }
3126fcafd02SGreg Roach            }
3136fcafd02SGreg Roach        }
3146fcafd02SGreg Roach
3156fcafd02SGreg Roach        return [];
3166fcafd02SGreg Roach    }
3176fcafd02SGreg Roach
3186fcafd02SGreg Roach    /**
31973d58381SGreg Roach     * @param string          $path
32073d58381SGreg Roach     * @param Individual|null $person1
32173d58381SGreg Roach     * @param Individual|null $person2
3226fcafd02SGreg Roach     *
3236fcafd02SGreg Roach     * @return string
3246fcafd02SGreg Roach     *
3256fcafd02SGreg Roach     * @deprecated This code was originally Functions::getRelationshipNameFromPath
3266fcafd02SGreg Roach     */
3276fcafd02SGreg Roach    public function legacyNameAlgorithm(string $path, Individual $person1 = null, Individual $person2 = null): string
3286fcafd02SGreg Roach    {
3296fcafd02SGreg Roach        // The path does not include the starting person. In some languages, the
3306fcafd02SGreg Roach        // translation for a man’s (relative) is different from a woman’s (relative),
3316fcafd02SGreg Roach        // due to inflection.
3326fcafd02SGreg Roach        $sex1 = $person1 ? $person1->sex() : 'U';
3336fcafd02SGreg Roach
3346fcafd02SGreg Roach        // The sex of the last person in the relationship determines the name in
3356fcafd02SGreg Roach        // many cases. e.g. great-aunt / great-uncle
3366fcafd02SGreg Roach        if (preg_match('/(fat|hus|son|bro)$/', $path)) {
3376fcafd02SGreg Roach            $sex2 = 'M';
3386fcafd02SGreg Roach        } elseif (preg_match('/(mot|wif|dau|sis)$/', $path)) {
3396fcafd02SGreg Roach            $sex2 = 'F';
3406fcafd02SGreg Roach        } else {
3416fcafd02SGreg Roach            $sex2 = 'U';
3426fcafd02SGreg Roach        }
3436fcafd02SGreg Roach
3446fcafd02SGreg Roach        switch ($path) {
3456fcafd02SGreg Roach            case '':
3466fcafd02SGreg Roach                return I18N::translate('self');
3476fcafd02SGreg Roach            //  Level One relationships
3486fcafd02SGreg Roach            case 'mot':
3496fcafd02SGreg Roach                return I18N::translate('mother');
3506fcafd02SGreg Roach            case 'fat':
3516fcafd02SGreg Roach                return I18N::translate('father');
3526fcafd02SGreg Roach            case 'par':
3536fcafd02SGreg Roach                return I18N::translate('parent');
3546fcafd02SGreg Roach            case 'hus':
3556fcafd02SGreg Roach                if ($person1 instanceof Individual && $person2 instanceof Individual) {
3566fcafd02SGreg Roach                    // We had the linking family earlier, but lost it.  Find it again.
3576fcafd02SGreg Roach                    foreach ($person1->spouseFamilies(Auth::PRIV_HIDE) as $family) {
3586fcafd02SGreg Roach                        if ($person2 === $family->spouse($person1)) {
3596fcafd02SGreg Roach                            $event = $family->facts(['ANUL', 'DIV', 'ENGA', 'MARR'], true, Auth::PRIV_HIDE, true)->last();
3606fcafd02SGreg Roach
3616fcafd02SGreg Roach                            if ($event instanceof Fact) {
3626fcafd02SGreg Roach                                switch ($event->tag()) {
3636fcafd02SGreg Roach                                    case 'FAM:ANUL':
3646fcafd02SGreg Roach                                    case 'FAM:DIV':
3656fcafd02SGreg Roach                                        return I18N::translate('ex-husband');
3666fcafd02SGreg Roach                                    case 'FAM:MARR':
3676fcafd02SGreg Roach                                        return I18N::translate('husband');
3686fcafd02SGreg Roach                                    case 'FAM:ENGA':
3696fcafd02SGreg Roach                                        return I18N::translate('fiancé');
3706fcafd02SGreg Roach                                }
3716fcafd02SGreg Roach                            }
3726fcafd02SGreg Roach                        }
3736fcafd02SGreg Roach                    }
3746fcafd02SGreg Roach                }
3756fcafd02SGreg Roach
3766fcafd02SGreg Roach                return I18N::translateContext('MALE', 'partner');
3776fcafd02SGreg Roach
3786fcafd02SGreg Roach            case 'wif':
3796fcafd02SGreg Roach                if ($person1 instanceof Individual && $person2 instanceof Individual) {
3806fcafd02SGreg Roach                    // We had the linking family earlier, but lost it.  Find it again.
3816fcafd02SGreg Roach                    foreach ($person1->spouseFamilies(Auth::PRIV_HIDE) as $family) {
3826fcafd02SGreg Roach                        if ($person2 === $family->spouse($person1)) {
3836fcafd02SGreg Roach                            $event = $family->facts(['ANUL', 'DIV', 'ENGA', 'MARR'], true, Auth::PRIV_HIDE, true)->last();
3846fcafd02SGreg Roach
3856fcafd02SGreg Roach                            if ($event instanceof Fact) {
3866fcafd02SGreg Roach                                switch ($event->tag()) {
3876fcafd02SGreg Roach                                    case 'FAM:ANUL':
3886fcafd02SGreg Roach                                    case 'FAM:DIV':
3896fcafd02SGreg Roach                                        return I18N::translate('ex-wife');
3906fcafd02SGreg Roach                                    case 'FAM:MARR':
3916fcafd02SGreg Roach                                        return I18N::translate('wife');
3926fcafd02SGreg Roach                                    case 'FAM:ENGA':
3936fcafd02SGreg Roach                                        return I18N::translate('fiancée');
3946fcafd02SGreg Roach                                }
3956fcafd02SGreg Roach                            }
3966fcafd02SGreg Roach                        }
3976fcafd02SGreg Roach                    }
3986fcafd02SGreg Roach                }
3996fcafd02SGreg Roach
4006fcafd02SGreg Roach                return I18N::translateContext('FEMALE', 'partner');
4016fcafd02SGreg Roach            case 'spo':
4026fcafd02SGreg Roach                if ($person1 instanceof Individual && $person2 instanceof Individual) {
4036fcafd02SGreg Roach                    // We had the linking family earlier, but lost it.  Find it again.
4046fcafd02SGreg Roach                    foreach ($person1->spouseFamilies(Auth::PRIV_HIDE) as $family) {
4056fcafd02SGreg Roach                        if ($person2 === $family->spouse($person1)) {
4066fcafd02SGreg Roach                            $event = $family->facts(['ANUL', 'DIV', 'ENGA', 'MARR'], true, Auth::PRIV_HIDE, true)->last();
4076fcafd02SGreg Roach
4086fcafd02SGreg Roach                            if ($event instanceof Fact) {
4096fcafd02SGreg Roach                                switch ($event->tag()) {
4106fcafd02SGreg Roach                                    case 'FAM:ANUL':
4116fcafd02SGreg Roach                                    case 'FAM:DIV':
4126fcafd02SGreg Roach                                        return I18N::translate('ex-spouse');
4136fcafd02SGreg Roach                                    case 'FAM:MARR':
4146fcafd02SGreg Roach                                        return I18N::translate('spouse');
4156fcafd02SGreg Roach                                    case 'FAM:ENGA':
4166fcafd02SGreg Roach                                        return I18N::translate('fiancé(e)');
4176fcafd02SGreg Roach                                }
4186fcafd02SGreg Roach                            }
4196fcafd02SGreg Roach                        }
4206fcafd02SGreg Roach                    }
4216fcafd02SGreg Roach                }
4226fcafd02SGreg Roach
4236fcafd02SGreg Roach                return I18N::translate('partner');
4246fcafd02SGreg Roach
4256fcafd02SGreg Roach            case 'son':
4266fcafd02SGreg Roach                return I18N::translate('son');
4276fcafd02SGreg Roach            case 'dau':
4286fcafd02SGreg Roach                return I18N::translate('daughter');
4296fcafd02SGreg Roach            case 'chi':
4306fcafd02SGreg Roach                return I18N::translate('child');
4316fcafd02SGreg Roach            case 'bro':
4326fcafd02SGreg Roach                if ($person1 && $person2) {
4336fcafd02SGreg Roach                    $dob1 = $person1->getBirthDate();
4346fcafd02SGreg Roach                    $dob2 = $person2->getBirthDate();
4356fcafd02SGreg Roach                    if ($dob1->isOK() && $dob2->isOK()) {
4366fcafd02SGreg Roach                        if (abs($dob1->julianDay() - $dob2->julianDay()) < 2 && $dob1->minimumDate()->day > 0 && $dob2->minimumDate()->day > 0) {
4376fcafd02SGreg Roach                            // Exclude BEF, AFT, etc.
4386fcafd02SGreg Roach                            return I18N::translate('twin brother');
4396fcafd02SGreg Roach                        }
4406fcafd02SGreg Roach
4416fcafd02SGreg Roach                        if ($dob1->maximumJulianDay() < $dob2->minimumJulianDay()) {
4426fcafd02SGreg Roach                            return I18N::translate('younger brother');
4436fcafd02SGreg Roach                        }
4446fcafd02SGreg Roach
4456fcafd02SGreg Roach                        if ($dob1->minimumJulianDay() > $dob2->maximumJulianDay()) {
4466fcafd02SGreg Roach                            return I18N::translate('elder brother');
4476fcafd02SGreg Roach                        }
4486fcafd02SGreg Roach                    }
4496fcafd02SGreg Roach                }
4506fcafd02SGreg Roach
4516fcafd02SGreg Roach                return I18N::translate('brother');
4526fcafd02SGreg Roach            case 'sis':
4536fcafd02SGreg Roach                if ($person1 && $person2) {
4546fcafd02SGreg Roach                    $dob1 = $person1->getBirthDate();
4556fcafd02SGreg Roach                    $dob2 = $person2->getBirthDate();
4566fcafd02SGreg Roach                    if ($dob1->isOK() && $dob2->isOK()) {
4576fcafd02SGreg Roach                        if (abs($dob1->julianDay() - $dob2->julianDay()) < 2 && $dob1->minimumDate()->day > 0 && $dob2->minimumDate()->day > 0) {
4586fcafd02SGreg Roach                            // Exclude BEF, AFT, etc.
4596fcafd02SGreg Roach                            return I18N::translate('twin sister');
4606fcafd02SGreg Roach                        }
4616fcafd02SGreg Roach
4626fcafd02SGreg Roach                        if ($dob1->maximumJulianDay() < $dob2->minimumJulianDay()) {
4636fcafd02SGreg Roach                            return I18N::translate('younger sister');
4646fcafd02SGreg Roach                        }
4656fcafd02SGreg Roach
4666fcafd02SGreg Roach                        if ($dob1->minimumJulianDay() > $dob2->maximumJulianDay()) {
4676fcafd02SGreg Roach                            return I18N::translate('elder sister');
4686fcafd02SGreg Roach                        }
4696fcafd02SGreg Roach                    }
4706fcafd02SGreg Roach                }
4716fcafd02SGreg Roach
4726fcafd02SGreg Roach                return I18N::translate('sister');
4736fcafd02SGreg Roach            case 'sib':
4746fcafd02SGreg Roach                if ($person1 && $person2) {
4756fcafd02SGreg Roach                    $dob1 = $person1->getBirthDate();
4766fcafd02SGreg Roach                    $dob2 = $person2->getBirthDate();
4776fcafd02SGreg Roach                    if ($dob1->isOK() && $dob2->isOK()) {
4786fcafd02SGreg Roach                        if (abs($dob1->julianDay() - $dob2->julianDay()) < 2 && $dob1->minimumDate()->day > 0 && $dob2->minimumDate()->day > 0) {
4796fcafd02SGreg Roach                            // Exclude BEF, AFT, etc.
4806fcafd02SGreg Roach                            return I18N::translate('twin sibling');
4816fcafd02SGreg Roach                        }
4826fcafd02SGreg Roach
4836fcafd02SGreg Roach                        if ($dob1->maximumJulianDay() < $dob2->minimumJulianDay()) {
4846fcafd02SGreg Roach                            return I18N::translate('younger sibling');
4856fcafd02SGreg Roach                        }
4866fcafd02SGreg Roach
4876fcafd02SGreg Roach                        if ($dob1->minimumJulianDay() > $dob2->maximumJulianDay()) {
4886fcafd02SGreg Roach                            return I18N::translate('elder sibling');
4896fcafd02SGreg Roach                        }
4906fcafd02SGreg Roach                    }
4916fcafd02SGreg Roach                }
4926fcafd02SGreg Roach
4936fcafd02SGreg Roach                return I18N::translate('sibling');
4946fcafd02SGreg Roach
4956fcafd02SGreg Roach            // Level Two relationships
4966fcafd02SGreg Roach            case 'brochi':
4976fcafd02SGreg Roach                return I18N::translateContext('brother’s child', 'nephew/niece');
4986fcafd02SGreg Roach            case 'brodau':
4996fcafd02SGreg Roach                return I18N::translateContext('brother’s daughter', 'niece');
5006fcafd02SGreg Roach            case 'broson':
5016fcafd02SGreg Roach                return I18N::translateContext('brother’s son', 'nephew');
5026fcafd02SGreg Roach            case 'browif':
5036fcafd02SGreg Roach                return I18N::translateContext('brother’s wife', 'sister-in-law');
5046fcafd02SGreg Roach            case 'chichi':
5056fcafd02SGreg Roach                return I18N::translateContext('child’s child', 'grandchild');
5066fcafd02SGreg Roach            case 'chidau':
5076fcafd02SGreg Roach                return I18N::translateContext('child’s daughter', 'granddaughter');
5086fcafd02SGreg Roach            case 'chihus':
5096fcafd02SGreg Roach                return I18N::translateContext('child’s husband', 'son-in-law');
5106fcafd02SGreg Roach            case 'chison':
5116fcafd02SGreg Roach                return I18N::translateContext('child’s son', 'grandson');
5126fcafd02SGreg Roach            case 'chispo':
5136fcafd02SGreg Roach                return I18N::translateContext('child’s spouse', 'son/daughter-in-law');
5146fcafd02SGreg Roach            case 'chiwif':
5156fcafd02SGreg Roach                return I18N::translateContext('child’s wife', 'daughter-in-law');
5166fcafd02SGreg Roach            case 'dauchi':
5176fcafd02SGreg Roach                return I18N::translateContext('daughter’s child', 'grandchild');
5186fcafd02SGreg Roach            case 'daudau':
5196fcafd02SGreg Roach                return I18N::translateContext('daughter’s daughter', 'granddaughter');
5206fcafd02SGreg Roach            case 'dauhus':
5216fcafd02SGreg Roach                return I18N::translateContext('daughter’s husband', 'son-in-law');
5226fcafd02SGreg Roach            case 'dauson':
5236fcafd02SGreg Roach                return I18N::translateContext('daughter’s son', 'grandson');
5246fcafd02SGreg Roach            case 'fatbro':
5256fcafd02SGreg Roach                return I18N::translateContext('father’s brother', 'uncle');
5266fcafd02SGreg Roach            case 'fatchi':
5276fcafd02SGreg Roach                return I18N::translateContext('father’s child', 'half-sibling');
5286fcafd02SGreg Roach            case 'fatdau':
5296fcafd02SGreg Roach                return I18N::translateContext('father’s daughter', 'half-sister');
5306fcafd02SGreg Roach            case 'fatfat':
5316fcafd02SGreg Roach                return I18N::translateContext('father’s father', 'paternal grandfather');
5326fcafd02SGreg Roach            case 'fatmot':
5336fcafd02SGreg Roach                return I18N::translateContext('father’s mother', 'paternal grandmother');
5346fcafd02SGreg Roach            case 'fatpar':
5356fcafd02SGreg Roach                return I18N::translateContext('father’s parent', 'paternal grandparent');
5366fcafd02SGreg Roach            case 'fatsib':
5376fcafd02SGreg Roach                return I18N::translateContext('father’s sibling', 'aunt/uncle');
5386fcafd02SGreg Roach            case 'fatsis':
5396fcafd02SGreg Roach                return I18N::translateContext('father’s sister', 'aunt');
5406fcafd02SGreg Roach            case 'fatson':
5416fcafd02SGreg Roach                return I18N::translateContext('father’s son', 'half-brother');
5426fcafd02SGreg Roach            case 'fatwif':
5436fcafd02SGreg Roach                return I18N::translateContext('father’s wife', 'step-mother');
5446fcafd02SGreg Roach            case 'husbro':
5456fcafd02SGreg Roach                return I18N::translateContext('husband’s brother', 'brother-in-law');
5466fcafd02SGreg Roach            case 'huschi':
5476fcafd02SGreg Roach                return I18N::translateContext('husband’s child', 'step-child');
5486fcafd02SGreg Roach            case 'husdau':
5496fcafd02SGreg Roach                return I18N::translateContext('husband’s daughter', 'step-daughter');
5506fcafd02SGreg Roach            case 'husfat':
5516fcafd02SGreg Roach                return I18N::translateContext('husband’s father', 'father-in-law');
5526fcafd02SGreg Roach            case 'husmot':
5536fcafd02SGreg Roach                return I18N::translateContext('husband’s mother', 'mother-in-law');
5546fcafd02SGreg Roach            case 'hussib':
5556fcafd02SGreg Roach                return I18N::translateContext('husband’s sibling', 'brother/sister-in-law');
5566fcafd02SGreg Roach            case 'hussis':
5576fcafd02SGreg Roach                return I18N::translateContext('husband’s sister', 'sister-in-law');
5586fcafd02SGreg Roach            case 'husson':
5596fcafd02SGreg Roach                return I18N::translateContext('husband’s son', 'step-son');
5606fcafd02SGreg Roach            case 'motbro':
5616fcafd02SGreg Roach                return I18N::translateContext('mother’s brother', 'uncle');
5626fcafd02SGreg Roach            case 'motchi':
5636fcafd02SGreg Roach                return I18N::translateContext('mother’s child', 'half-sibling');
5646fcafd02SGreg Roach            case 'motdau':
5656fcafd02SGreg Roach                return I18N::translateContext('mother’s daughter', 'half-sister');
5666fcafd02SGreg Roach            case 'motfat':
5676fcafd02SGreg Roach                return I18N::translateContext('mother’s father', 'maternal grandfather');
5686fcafd02SGreg Roach            case 'mothus':
5696fcafd02SGreg Roach                return I18N::translateContext('mother’s husband', 'step-father');
5706fcafd02SGreg Roach            case 'motmot':
5716fcafd02SGreg Roach                return I18N::translateContext('mother’s mother', 'maternal grandmother');
5726fcafd02SGreg Roach            case 'motpar':
5736fcafd02SGreg Roach                return I18N::translateContext('mother’s parent', 'maternal grandparent');
5746fcafd02SGreg Roach            case 'motsib':
5756fcafd02SGreg Roach                return I18N::translateContext('mother’s sibling', 'aunt/uncle');
5766fcafd02SGreg Roach            case 'motsis':
5776fcafd02SGreg Roach                return I18N::translateContext('mother’s sister', 'aunt');
5786fcafd02SGreg Roach            case 'motson':
5796fcafd02SGreg Roach                return I18N::translateContext('mother’s son', 'half-brother');
5806fcafd02SGreg Roach            case 'parbro':
5816fcafd02SGreg Roach                return I18N::translateContext('parent’s brother', 'uncle');
5826fcafd02SGreg Roach            case 'parchi':
5836fcafd02SGreg Roach                return I18N::translateContext('parent’s child', 'half-sibling');
5846fcafd02SGreg Roach            case 'pardau':
5856fcafd02SGreg Roach                return I18N::translateContext('parent’s daughter', 'half-sister');
5866fcafd02SGreg Roach            case 'parfat':
5876fcafd02SGreg Roach                return I18N::translateContext('parent’s father', 'grandfather');
5886fcafd02SGreg Roach            case 'parmot':
5896fcafd02SGreg Roach                return I18N::translateContext('parent’s mother', 'grandmother');
5906fcafd02SGreg Roach            case 'parpar':
5916fcafd02SGreg Roach                return I18N::translateContext('parent’s parent', 'grandparent');
5926fcafd02SGreg Roach            case 'parsib':
5936fcafd02SGreg Roach                return I18N::translateContext('parent’s sibling', 'aunt/uncle');
5946fcafd02SGreg Roach            case 'parsis':
5956fcafd02SGreg Roach                return I18N::translateContext('parent’s sister', 'aunt');
5966fcafd02SGreg Roach            case 'parson':
5976fcafd02SGreg Roach                return I18N::translateContext('parent’s son', 'half-brother');
5986fcafd02SGreg Roach            case 'parspo':
5996fcafd02SGreg Roach                return I18N::translateContext('parent’s spouse', 'step-parent');
6006fcafd02SGreg Roach            case 'sibchi':
6016fcafd02SGreg Roach                return I18N::translateContext('sibling’s child', 'nephew/niece');
6026fcafd02SGreg Roach            case 'sibdau':
6036fcafd02SGreg Roach                return I18N::translateContext('sibling’s daughter', 'niece');
6046fcafd02SGreg Roach            case 'sibson':
6056fcafd02SGreg Roach                return I18N::translateContext('sibling’s son', 'nephew');
6066fcafd02SGreg Roach            case 'sibspo':
6076fcafd02SGreg Roach                return I18N::translateContext('sibling’s spouse', 'brother/sister-in-law');
6086fcafd02SGreg Roach            case 'sischi':
6096fcafd02SGreg Roach                return I18N::translateContext('sister’s child', 'nephew/niece');
6106fcafd02SGreg Roach            case 'sisdau':
6116fcafd02SGreg Roach                return I18N::translateContext('sister’s daughter', 'niece');
6126fcafd02SGreg Roach            case 'sishus':
6136fcafd02SGreg Roach                return I18N::translateContext('sister’s husband', 'brother-in-law');
6146fcafd02SGreg Roach            case 'sisson':
6156fcafd02SGreg Roach                return I18N::translateContext('sister’s son', 'nephew');
6166fcafd02SGreg Roach            case 'sonchi':
6176fcafd02SGreg Roach                return I18N::translateContext('son’s child', 'grandchild');
6186fcafd02SGreg Roach            case 'sondau':
6196fcafd02SGreg Roach                return I18N::translateContext('son’s daughter', 'granddaughter');
6206fcafd02SGreg Roach            case 'sonson':
6216fcafd02SGreg Roach                return I18N::translateContext('son’s son', 'grandson');
6226fcafd02SGreg Roach            case 'sonwif':
6236fcafd02SGreg Roach                return I18N::translateContext('son’s wife', 'daughter-in-law');
6246fcafd02SGreg Roach            case 'spobro':
6256fcafd02SGreg Roach                return I18N::translateContext('spouse’s brother', 'brother-in-law');
6266fcafd02SGreg Roach            case 'spochi':
6276fcafd02SGreg Roach                return I18N::translateContext('spouse’s child', 'step-child');
6286fcafd02SGreg Roach            case 'spodau':
6296fcafd02SGreg Roach                return I18N::translateContext('spouse’s daughter', 'step-daughter');
6306fcafd02SGreg Roach            case 'spofat':
6316fcafd02SGreg Roach                return I18N::translateContext('spouse’s father', 'father-in-law');
6326fcafd02SGreg Roach            case 'spomot':
6336fcafd02SGreg Roach                return I18N::translateContext('spouse’s mother', 'mother-in-law');
6346fcafd02SGreg Roach            case 'sposis':
6356fcafd02SGreg Roach                return I18N::translateContext('spouse’s sister', 'sister-in-law');
6366fcafd02SGreg Roach            case 'sposon':
6376fcafd02SGreg Roach                return I18N::translateContext('spouse’s son', 'step-son');
6386fcafd02SGreg Roach            case 'spopar':
6396fcafd02SGreg Roach                return I18N::translateContext('spouse’s parent', 'mother/father-in-law');
6406fcafd02SGreg Roach            case 'sposib':
6416fcafd02SGreg Roach                return I18N::translateContext('spouse’s sibling', 'brother/sister-in-law');
6426fcafd02SGreg Roach            case 'wifbro':
6436fcafd02SGreg Roach                return I18N::translateContext('wife’s brother', 'brother-in-law');
6446fcafd02SGreg Roach            case 'wifchi':
6456fcafd02SGreg Roach                return I18N::translateContext('wife’s child', 'step-child');
6466fcafd02SGreg Roach            case 'wifdau':
6476fcafd02SGreg Roach                return I18N::translateContext('wife’s daughter', 'step-daughter');
6486fcafd02SGreg Roach            case 'wiffat':
6496fcafd02SGreg Roach                return I18N::translateContext('wife’s father', 'father-in-law');
6506fcafd02SGreg Roach            case 'wifmot':
6516fcafd02SGreg Roach                return I18N::translateContext('wife’s mother', 'mother-in-law');
6526fcafd02SGreg Roach            case 'wifsib':
6536fcafd02SGreg Roach                return I18N::translateContext('wife’s sibling', 'brother/sister-in-law');
6546fcafd02SGreg Roach            case 'wifsis':
6556fcafd02SGreg Roach                return I18N::translateContext('wife’s sister', 'sister-in-law');
6566fcafd02SGreg Roach            case 'wifson':
6576fcafd02SGreg Roach                return I18N::translateContext('wife’s son', 'step-son');
6586fcafd02SGreg Roach
6596fcafd02SGreg Roach            // Level Three relationships
6606fcafd02SGreg Roach            case 'brochichi':
6616fcafd02SGreg Roach                if ($sex1 === 'M') {
6626fcafd02SGreg Roach                    return I18N::translateContext('(a man’s) brother’s child’s child', 'great-nephew/niece');
6636fcafd02SGreg Roach                }
6646fcafd02SGreg Roach
6656fcafd02SGreg Roach                return I18N::translateContext('(a woman’s) brother’s child’s child', 'great-nephew/niece');
6666fcafd02SGreg Roach            case 'brochidau':
6676fcafd02SGreg Roach                if ($sex1 === 'M') {
6686fcafd02SGreg Roach                    return I18N::translateContext('(a man’s) brother’s child’s daughter', 'great-niece');
6696fcafd02SGreg Roach                }
6706fcafd02SGreg Roach
6716fcafd02SGreg Roach                return I18N::translateContext('(a woman’s) brother’s child’s daughter', 'great-niece');
6726fcafd02SGreg Roach            case 'brochison':
6736fcafd02SGreg Roach                if ($sex1 === 'M') {
6746fcafd02SGreg Roach                    return I18N::translateContext('(a man’s) brother’s child’s son', 'great-nephew');
6756fcafd02SGreg Roach                }
6766fcafd02SGreg Roach
6776fcafd02SGreg Roach                return I18N::translateContext('(a woman’s) brother’s child’s son', 'great-nephew');
6786fcafd02SGreg Roach            case 'brodauchi':
6796fcafd02SGreg Roach                if ($sex1 === 'M') {
6806fcafd02SGreg Roach                    return I18N::translateContext('(a man’s) brother’s daughter’s child', 'great-nephew/niece');
6816fcafd02SGreg Roach                }
6826fcafd02SGreg Roach
6836fcafd02SGreg Roach                return I18N::translateContext('(a woman’s) brother’s daughter’s child', 'great-nephew/niece');
6846fcafd02SGreg Roach            case 'brodaudau':
6856fcafd02SGreg Roach                if ($sex1 === 'M') {
6866fcafd02SGreg Roach                    return I18N::translateContext('(a man’s) brother’s daughter’s daughter', 'great-niece');
6876fcafd02SGreg Roach                }
6886fcafd02SGreg Roach
6896fcafd02SGreg Roach                return I18N::translateContext('(a woman’s) brother’s daughter’s daughter', 'great-niece');
6906fcafd02SGreg Roach            case 'brodauhus':
6916fcafd02SGreg Roach                return I18N::translateContext('brother’s daughter’s husband', 'nephew-in-law');
6926fcafd02SGreg Roach            case 'brodauson':
6936fcafd02SGreg Roach                if ($sex1 === 'M') {
6946fcafd02SGreg Roach                    return I18N::translateContext('(a man’s) brother’s daughter’s son', 'great-nephew');
6956fcafd02SGreg Roach                }
6966fcafd02SGreg Roach
6976fcafd02SGreg Roach                return I18N::translateContext('(a woman’s) brother’s daughter’s son', 'great-nephew');
6986fcafd02SGreg Roach            case 'brosonchi':
6996fcafd02SGreg Roach                if ($sex1 === 'M') {
7006fcafd02SGreg Roach                    return I18N::translateContext('(a man’s) brother’s son’s child', 'great-nephew/niece');
7016fcafd02SGreg Roach                }
7026fcafd02SGreg Roach
7036fcafd02SGreg Roach                return I18N::translateContext('(a woman’s) brother’s son’s child', 'great-nephew/niece');
7046fcafd02SGreg Roach            case 'brosondau':
7056fcafd02SGreg Roach                if ($sex1 === 'M') {
7066fcafd02SGreg Roach                    return I18N::translateContext('(a man’s) brother’s son’s daughter', 'great-niece');
7076fcafd02SGreg Roach                }
7086fcafd02SGreg Roach
7096fcafd02SGreg Roach                return I18N::translateContext('(a woman’s) brother’s son’s daughter', 'great-niece');
7106fcafd02SGreg Roach            case 'brosonson':
7116fcafd02SGreg Roach                if ($sex1 === 'M') {
7126fcafd02SGreg Roach                    return I18N::translateContext('(a man’s) brother’s son’s son', 'great-nephew');
7136fcafd02SGreg Roach                }
7146fcafd02SGreg Roach
7156fcafd02SGreg Roach                return I18N::translateContext('(a woman’s) brother’s son’s son', 'great-nephew');
7166fcafd02SGreg Roach            case 'brosonwif':
7176fcafd02SGreg Roach                return I18N::translateContext('brother’s son’s wife', 'niece-in-law');
7186fcafd02SGreg Roach            case 'browifbro':
7196fcafd02SGreg Roach                return I18N::translateContext('brother’s wife’s brother', 'brother-in-law');
7206fcafd02SGreg Roach            case 'browifsib':
7216fcafd02SGreg Roach                return I18N::translateContext('brother’s wife’s sibling', 'brother/sister-in-law');
7226fcafd02SGreg Roach            case 'browifsis':
7236fcafd02SGreg Roach                return I18N::translateContext('brother’s wife’s sister', 'sister-in-law');
7246fcafd02SGreg Roach            case 'chichichi':
7256fcafd02SGreg Roach                return I18N::translateContext('child’s child’s child', 'great-grandchild');
7266fcafd02SGreg Roach            case 'chichidau':
7276fcafd02SGreg Roach                return I18N::translateContext('child’s child’s daughter', 'great-granddaughter');
7286fcafd02SGreg Roach            case 'chichison':
7296fcafd02SGreg Roach                return I18N::translateContext('child’s child’s son', 'great-grandson');
7306fcafd02SGreg Roach            case 'chidauchi':
7316fcafd02SGreg Roach                return I18N::translateContext('child’s daughter’s child', 'great-grandchild');
7326fcafd02SGreg Roach            case 'chidaudau':
7336fcafd02SGreg Roach                return I18N::translateContext('child’s daughter’s daughter', 'great-granddaughter');
7346fcafd02SGreg Roach            case 'chidauhus':
7356fcafd02SGreg Roach                return I18N::translateContext('child’s daughter’s husband', 'granddaughter’s husband');
7366fcafd02SGreg Roach            case 'chidauson':
7376fcafd02SGreg Roach                return I18N::translateContext('child’s daughter’s son', 'great-grandson');
7386fcafd02SGreg Roach            case 'chisonchi':
7396fcafd02SGreg Roach                return I18N::translateContext('child’s son’s child', 'great-grandchild');
7406fcafd02SGreg Roach            case 'chisondau':
7416fcafd02SGreg Roach                return I18N::translateContext('child’s son’s daughter', 'great-granddaughter');
7426fcafd02SGreg Roach            case 'chisonson':
7436fcafd02SGreg Roach                return I18N::translateContext('child’s son’s son', 'great-grandson');
7446fcafd02SGreg Roach            case 'chisonwif':
7456fcafd02SGreg Roach                return I18N::translateContext('child’s son’s wife', 'grandson’s wife');
7466fcafd02SGreg Roach            case 'dauchichi':
7476fcafd02SGreg Roach                return I18N::translateContext('daughter’s child’s child', 'great-grandchild');
7486fcafd02SGreg Roach            case 'dauchidau':
7496fcafd02SGreg Roach                return I18N::translateContext('daughter’s child’s daughter', 'great-granddaughter');
7506fcafd02SGreg Roach            case 'dauchison':
7516fcafd02SGreg Roach                return I18N::translateContext('daughter’s child’s son', 'great-grandson');
7526fcafd02SGreg Roach            case 'daudauchi':
7536fcafd02SGreg Roach                return I18N::translateContext('daughter’s daughter’s child', 'great-grandchild');
7546fcafd02SGreg Roach            case 'daudaudau':
7556fcafd02SGreg Roach                return I18N::translateContext('daughter’s daughter’s daughter', 'great-granddaughter');
7566fcafd02SGreg Roach            case 'daudauhus':
7576fcafd02SGreg Roach                return I18N::translateContext('daughter’s daughter’s husband', 'granddaughter’s husband');
7586fcafd02SGreg Roach            case 'daudauson':
7596fcafd02SGreg Roach                return I18N::translateContext('daughter’s daughter’s son', 'great-grandson');
7606fcafd02SGreg Roach            case 'dauhusfat':
7616fcafd02SGreg Roach                return I18N::translateContext('daughter’s husband’s father', 'son-in-law’s father');
7626fcafd02SGreg Roach            case 'dauhusmot':
7636fcafd02SGreg Roach                return I18N::translateContext('daughter’s husband’s mother', 'son-in-law’s mother');
7646fcafd02SGreg Roach            case 'dauhuspar':
7656fcafd02SGreg Roach                return I18N::translateContext('daughter’s husband’s parent', 'son-in-law’s parent');
7666fcafd02SGreg Roach            case 'dausonchi':
7676fcafd02SGreg Roach                return I18N::translateContext('daughter’s son’s child', 'great-grandchild');
7686fcafd02SGreg Roach            case 'dausondau':
7696fcafd02SGreg Roach                return I18N::translateContext('daughter’s son’s daughter', 'great-granddaughter');
7706fcafd02SGreg Roach            case 'dausonson':
7716fcafd02SGreg Roach                return I18N::translateContext('daughter’s son’s son', 'great-grandson');
7726fcafd02SGreg Roach            case 'dausonwif':
7736fcafd02SGreg Roach                return I18N::translateContext('daughter’s son’s wife', 'grandson’s wife');
7746fcafd02SGreg Roach            case 'fatbrochi':
7756fcafd02SGreg Roach                return I18N::translateContext('father’s brother’s child', 'first cousin');
7766fcafd02SGreg Roach            case 'fatbrodau':
7776fcafd02SGreg Roach                return I18N::translateContext('father’s brother’s daughter', 'first cousin');
7786fcafd02SGreg Roach            case 'fatbroson':
7796fcafd02SGreg Roach                return I18N::translateContext('father’s brother’s son', 'first cousin');
7806fcafd02SGreg Roach            case 'fatbrowif':
7816fcafd02SGreg Roach                return I18N::translateContext('father’s brother’s wife', 'aunt');
7826fcafd02SGreg Roach            case 'fatfatbro':
7836fcafd02SGreg Roach                return I18N::translateContext('father’s father’s brother', 'great-uncle');
7846fcafd02SGreg Roach            case 'fatfatfat':
7856fcafd02SGreg Roach                return I18N::translateContext('father’s father’s father', 'great-grandfather');
7866fcafd02SGreg Roach            case 'fatfatmot':
7876fcafd02SGreg Roach                return I18N::translateContext('father’s father’s mother', 'great-grandmother');
7886fcafd02SGreg Roach            case 'fatfatpar':
7896fcafd02SGreg Roach                return I18N::translateContext('father’s father’s parent', 'great-grandparent');
7906fcafd02SGreg Roach            case 'fatfatsib':
7916fcafd02SGreg Roach                return I18N::translateContext('father’s father’s sibling', 'great-aunt/uncle');
7926fcafd02SGreg Roach            case 'fatfatsis':
7936fcafd02SGreg Roach                return I18N::translateContext('father’s father’s sister', 'great-aunt');
7946fcafd02SGreg Roach            case 'fatmotbro':
7956fcafd02SGreg Roach                return I18N::translateContext('father’s mother’s brother', 'great-uncle');
7966fcafd02SGreg Roach            case 'fatmotfat':
7976fcafd02SGreg Roach                return I18N::translateContext('father’s mother’s father', 'great-grandfather');
7986fcafd02SGreg Roach            case 'fatmotmot':
7996fcafd02SGreg Roach                return I18N::translateContext('father’s mother’s mother', 'great-grandmother');
8006fcafd02SGreg Roach            case 'fatmotpar':
8016fcafd02SGreg Roach                return I18N::translateContext('father’s mother’s parent', 'great-grandparent');
8026fcafd02SGreg Roach            case 'fatmotsib':
8036fcafd02SGreg Roach                return I18N::translateContext('father’s mother’s sibling', 'great-aunt/uncle');
8046fcafd02SGreg Roach            case 'fatmotsis':
8056fcafd02SGreg Roach                return I18N::translateContext('father’s mother’s sister', 'great-aunt');
8066fcafd02SGreg Roach            case 'fatparbro':
8076fcafd02SGreg Roach                return I18N::translateContext('father’s parent’s brother', 'great-uncle');
8086fcafd02SGreg Roach            case 'fatparfat':
8096fcafd02SGreg Roach                return I18N::translateContext('father’s parent’s father', 'great-grandfather');
8106fcafd02SGreg Roach            case 'fatparmot':
8116fcafd02SGreg Roach                return I18N::translateContext('father’s parent’s mother', 'great-grandmother');
8126fcafd02SGreg Roach            case 'fatparpar':
8136fcafd02SGreg Roach                return I18N::translateContext('father’s parent’s parent', 'great-grandparent');
8146fcafd02SGreg Roach            case 'fatparsib':
8156fcafd02SGreg Roach                return I18N::translateContext('father’s parent’s sibling', 'great-aunt/uncle');
8166fcafd02SGreg Roach            case 'fatparsis':
8176fcafd02SGreg Roach                return I18N::translateContext('father’s parent’s sister', 'great-aunt');
8186fcafd02SGreg Roach            case 'fatsischi':
8196fcafd02SGreg Roach                return I18N::translateContext('father’s sister’s child', 'first cousin');
8206fcafd02SGreg Roach            case 'fatsisdau':
8216fcafd02SGreg Roach                return I18N::translateContext('father’s sister’s daughter', 'first cousin');
8226fcafd02SGreg Roach            case 'fatsishus':
8236fcafd02SGreg Roach                return I18N::translateContext('father’s sister’s husband', 'uncle');
8246fcafd02SGreg Roach            case 'fatsisson':
8256fcafd02SGreg Roach                return I18N::translateContext('father’s sister’s son', 'first cousin');
8266fcafd02SGreg Roach            case 'fatwifchi':
8276fcafd02SGreg Roach                return I18N::translateContext('father’s wife’s child', 'step-sibling');
8286fcafd02SGreg Roach            case 'fatwifdau':
8296fcafd02SGreg Roach                return I18N::translateContext('father’s wife’s daughter', 'step-sister');
8306fcafd02SGreg Roach            case 'fatwifson':
8316fcafd02SGreg Roach                return I18N::translateContext('father’s wife’s son', 'step-brother');
8326fcafd02SGreg Roach            case 'husbrowif':
8336fcafd02SGreg Roach                return I18N::translateContext('husband’s brother’s wife', 'sister-in-law');
8346fcafd02SGreg Roach            case 'hussishus':
8356fcafd02SGreg Roach                return I18N::translateContext('husband’s sister’s husband', 'brother-in-law');
8366fcafd02SGreg Roach            case 'hussibchi':
8376fcafd02SGreg Roach                return I18N::translateContext('husband’s sibling’s child', 'nephew/niece');
8386fcafd02SGreg Roach            case 'hussischi':
8396fcafd02SGreg Roach                return I18N::translateContext('husband’s sister’s child', 'nephew/niece');
8406fcafd02SGreg Roach            case 'husbrochi':
8416fcafd02SGreg Roach                return I18N::translateContext('husband’s brother’s child', 'nephew/niece');
8426fcafd02SGreg Roach            case 'hussibdau':
8436fcafd02SGreg Roach                return I18N::translateContext('husband’s sibling’s daughter', 'niece');
8446fcafd02SGreg Roach            case 'hussisdau':
8456fcafd02SGreg Roach                return I18N::translateContext('husband’s sister’s daughter', 'niece');
8466fcafd02SGreg Roach            case 'husbrodau':
8476fcafd02SGreg Roach                return I18N::translateContext('husband’s brother’s daughter', 'niece');
8486fcafd02SGreg Roach            case 'hussibson':
8496fcafd02SGreg Roach                return I18N::translateContext('husband’s sibling’s son', 'nephew');
8506fcafd02SGreg Roach            case 'hussisson':
8516fcafd02SGreg Roach                return I18N::translateContext('husband’s sister’s son', 'nephew');
8526fcafd02SGreg Roach            case 'husbroson':
8536fcafd02SGreg Roach                return I18N::translateContext('husband’s brother’s son', 'nephew');
8546fcafd02SGreg Roach            case 'motbrochi':
8556fcafd02SGreg Roach                return I18N::translateContext('mother’s brother’s child', 'first cousin');
8566fcafd02SGreg Roach            case 'motbrodau':
8576fcafd02SGreg Roach                return I18N::translateContext('mother’s brother’s daughter', 'first cousin');
8586fcafd02SGreg Roach            case 'motbroson':
8596fcafd02SGreg Roach                return I18N::translateContext('mother’s brother’s son', 'first cousin');
8606fcafd02SGreg Roach            case 'motbrowif':
8616fcafd02SGreg Roach                return I18N::translateContext('mother’s brother’s wife', 'aunt');
8626fcafd02SGreg Roach            case 'motfatbro':
8636fcafd02SGreg Roach                return I18N::translateContext('mother’s father’s brother', 'great-uncle');
8646fcafd02SGreg Roach            case 'motfatfat':
8656fcafd02SGreg Roach                return I18N::translateContext('mother’s father’s father', 'great-grandfather');
8666fcafd02SGreg Roach            case 'motfatmot':
8676fcafd02SGreg Roach                return I18N::translateContext('mother’s father’s mother', 'great-grandmother');
8686fcafd02SGreg Roach            case 'motfatpar':
8696fcafd02SGreg Roach                return I18N::translateContext('mother’s father’s parent', 'great-grandparent');
8706fcafd02SGreg Roach            case 'motfatsib':
8716fcafd02SGreg Roach                return I18N::translateContext('mother’s father’s sibling', 'great-aunt/uncle');
8726fcafd02SGreg Roach            case 'motfatsis':
8736fcafd02SGreg Roach                return I18N::translateContext('mother’s father’s sister', 'great-aunt');
8746fcafd02SGreg Roach            case 'mothuschi':
8756fcafd02SGreg Roach                return I18N::translateContext('mother’s husband’s child', 'step-sibling');
8766fcafd02SGreg Roach            case 'mothusdau':
8776fcafd02SGreg Roach                return I18N::translateContext('mother’s husband’s daughter', 'step-sister');
8786fcafd02SGreg Roach            case 'mothusson':
8796fcafd02SGreg Roach                return I18N::translateContext('mother’s husband’s son', 'step-brother');
8806fcafd02SGreg Roach            case 'motmotbro':
8816fcafd02SGreg Roach                return I18N::translateContext('mother’s mother’s brother', 'great-uncle');
8826fcafd02SGreg Roach            case 'motmotfat':
8836fcafd02SGreg Roach                return I18N::translateContext('mother’s mother’s father', 'great-grandfather');
8846fcafd02SGreg Roach            case 'motmotmot':
8856fcafd02SGreg Roach                return I18N::translateContext('mother’s mother’s mother', 'great-grandmother');
8866fcafd02SGreg Roach            case 'motmotpar':
8876fcafd02SGreg Roach                return I18N::translateContext('mother’s mother’s parent', 'great-grandparent');
8886fcafd02SGreg Roach            case 'motmotsib':
8896fcafd02SGreg Roach                return I18N::translateContext('mother’s mother’s sibling', 'great-aunt/uncle');
8906fcafd02SGreg Roach            case 'motmotsis':
8916fcafd02SGreg Roach                return I18N::translateContext('mother’s mother’s sister', 'great-aunt');
8926fcafd02SGreg Roach            case 'motparbro':
8936fcafd02SGreg Roach                return I18N::translateContext('mother’s parent’s brother', 'great-uncle');
8946fcafd02SGreg Roach            case 'motparfat':
8956fcafd02SGreg Roach                return I18N::translateContext('mother’s parent’s father', 'great-grandfather');
8966fcafd02SGreg Roach            case 'motparmot':
8976fcafd02SGreg Roach                return I18N::translateContext('mother’s parent’s mother', 'great-grandmother');
8986fcafd02SGreg Roach            case 'motparpar':
8996fcafd02SGreg Roach                return I18N::translateContext('mother’s parent’s parent', 'great-grandparent');
9006fcafd02SGreg Roach            case 'motparsib':
9016fcafd02SGreg Roach                return I18N::translateContext('mother’s parent’s sibling', 'great-aunt/uncle');
9026fcafd02SGreg Roach            case 'motparsis':
9036fcafd02SGreg Roach                return I18N::translateContext('mother’s parent’s sister', 'great-aunt');
9046fcafd02SGreg Roach            case 'motsischi':
9056fcafd02SGreg Roach                return I18N::translateContext('mother’s sister’s child', 'first cousin');
9066fcafd02SGreg Roach            case 'motsisdau':
9076fcafd02SGreg Roach                return I18N::translateContext('mother’s sister’s daughter', 'first cousin');
9086fcafd02SGreg Roach            case 'motsishus':
9096fcafd02SGreg Roach                return I18N::translateContext('mother’s sister’s husband', 'uncle');
9106fcafd02SGreg Roach            case 'motsisson':
9116fcafd02SGreg Roach                return I18N::translateContext('mother’s sister’s son', 'first cousin');
9126fcafd02SGreg Roach            case 'parbrowif':
9136fcafd02SGreg Roach                return I18N::translateContext('parent’s brother’s wife', 'aunt');
9146fcafd02SGreg Roach            case 'parfatbro':
9156fcafd02SGreg Roach                return I18N::translateContext('parent’s father’s brother', 'great-uncle');
9166fcafd02SGreg Roach            case 'parfatfat':
9176fcafd02SGreg Roach                return I18N::translateContext('parent’s father’s father', 'great-grandfather');
9186fcafd02SGreg Roach            case 'parfatmot':
9196fcafd02SGreg Roach                return I18N::translateContext('parent’s father’s mother', 'great-grandmother');
9206fcafd02SGreg Roach            case 'parfatpar':
9216fcafd02SGreg Roach                return I18N::translateContext('parent’s father’s parent', 'great-grandparent');
9226fcafd02SGreg Roach            case 'parfatsib':
9236fcafd02SGreg Roach                return I18N::translateContext('parent’s father’s sibling', 'great-aunt/uncle');
9246fcafd02SGreg Roach            case 'parfatsis':
9256fcafd02SGreg Roach                return I18N::translateContext('parent’s father’s sister', 'great-aunt');
9266fcafd02SGreg Roach            case 'parmotbro':
9276fcafd02SGreg Roach                return I18N::translateContext('parent’s mother’s brother', 'great-uncle');
9286fcafd02SGreg Roach            case 'parmotfat':
9296fcafd02SGreg Roach                return I18N::translateContext('parent’s mother’s father', 'great-grandfather');
9306fcafd02SGreg Roach            case 'parmotmot':
9316fcafd02SGreg Roach                return I18N::translateContext('parent’s mother’s mother', 'great-grandmother');
9326fcafd02SGreg Roach            case 'parmotpar':
9336fcafd02SGreg Roach                return I18N::translateContext('parent’s mother’s parent', 'great-grandparent');
9346fcafd02SGreg Roach            case 'parmotsib':
9356fcafd02SGreg Roach                return I18N::translateContext('parent’s mother’s sibling', 'great-aunt/uncle');
9366fcafd02SGreg Roach            case 'parmotsis':
9376fcafd02SGreg Roach                return I18N::translateContext('parent’s mother’s sister', 'great-aunt');
9386fcafd02SGreg Roach            case 'parparbro':
9396fcafd02SGreg Roach                return I18N::translateContext('parent’s parent’s brother', 'great-uncle');
9406fcafd02SGreg Roach            case 'parparfat':
9416fcafd02SGreg Roach                return I18N::translateContext('parent’s parent’s father', 'great-grandfather');
9426fcafd02SGreg Roach            case 'parparmot':
9436fcafd02SGreg Roach                return I18N::translateContext('parent’s parent’s mother', 'great-grandmother');
9446fcafd02SGreg Roach            case 'parparpar':
9456fcafd02SGreg Roach                return I18N::translateContext('parent’s parent’s parent', 'great-grandparent');
9466fcafd02SGreg Roach            case 'parparsib':
9476fcafd02SGreg Roach                return I18N::translateContext('parent’s parent’s sibling', 'great-aunt/uncle');
9486fcafd02SGreg Roach            case 'parparsis':
9496fcafd02SGreg Roach                return I18N::translateContext('parent’s parent’s sister', 'great-aunt');
9506fcafd02SGreg Roach            case 'parsishus':
9516fcafd02SGreg Roach                return I18N::translateContext('parent’s sister’s husband', 'uncle');
9526fcafd02SGreg Roach            case 'parspochi':
9536fcafd02SGreg Roach                return I18N::translateContext('parent’s spouse’s child', 'step-sibling');
9546fcafd02SGreg Roach            case 'parspodau':
9556fcafd02SGreg Roach                return I18N::translateContext('parent’s spouse’s daughter', 'step-sister');
9566fcafd02SGreg Roach            case 'parsposon':
9576fcafd02SGreg Roach                return I18N::translateContext('parent’s spouse’s son', 'step-brother');
9586fcafd02SGreg Roach            case 'sibchichi':
9596fcafd02SGreg Roach                return I18N::translateContext('sibling’s child’s child', 'great-nephew/niece');
9606fcafd02SGreg Roach            case 'sibchidau':
9616fcafd02SGreg Roach                return I18N::translateContext('sibling’s child’s daughter', 'great-niece');
9626fcafd02SGreg Roach            case 'sibchison':
9636fcafd02SGreg Roach                return I18N::translateContext('sibling’s child’s son', 'great-nephew');
9646fcafd02SGreg Roach            case 'sibdauchi':
9656fcafd02SGreg Roach                return I18N::translateContext('sibling’s daughter’s child', 'great-nephew/niece');
9666fcafd02SGreg Roach            case 'sibdaudau':
9676fcafd02SGreg Roach                return I18N::translateContext('sibling’s daughter’s daughter', 'great-niece');
9686fcafd02SGreg Roach            case 'sibdauhus':
9696fcafd02SGreg Roach                return I18N::translateContext('sibling’s daughter’s husband', 'nephew-in-law');
9706fcafd02SGreg Roach            case 'sibdauson':
9716fcafd02SGreg Roach                return I18N::translateContext('sibling’s daughter’s son', 'great-nephew');
9726fcafd02SGreg Roach            case 'sibsonchi':
9736fcafd02SGreg Roach                return I18N::translateContext('sibling’s son’s child', 'great-nephew/niece');
9746fcafd02SGreg Roach            case 'sibsondau':
9756fcafd02SGreg Roach                return I18N::translateContext('sibling’s son’s daughter', 'great-niece');
9766fcafd02SGreg Roach            case 'sibsonson':
9776fcafd02SGreg Roach                return I18N::translateContext('sibling’s son’s son', 'great-nephew');
9786fcafd02SGreg Roach            case 'sibsonwif':
9796fcafd02SGreg Roach                return I18N::translateContext('sibling’s son’s wife', 'niece-in-law');
9806fcafd02SGreg Roach            case 'sischichi':
9816fcafd02SGreg Roach                if ($sex1 === 'M') {
9826fcafd02SGreg Roach                    return I18N::translateContext('(a man’s) sister’s child’s child', 'great-nephew/niece');
9836fcafd02SGreg Roach                }
9846fcafd02SGreg Roach
9856fcafd02SGreg Roach                return I18N::translateContext('(a woman’s) sister’s child’s child', 'great-nephew/niece');
9866fcafd02SGreg Roach            case 'sischidau':
9876fcafd02SGreg Roach                if ($sex1 === 'M') {
9886fcafd02SGreg Roach                    return I18N::translateContext('(a man’s) sister’s child’s daughter', 'great-niece');
9896fcafd02SGreg Roach                }
9906fcafd02SGreg Roach
9916fcafd02SGreg Roach                return I18N::translateContext('(a woman’s) sister’s child’s daughter', 'great-niece');
9926fcafd02SGreg Roach            case 'sischison':
9936fcafd02SGreg Roach                if ($sex1 === 'M') {
9946fcafd02SGreg Roach                    return I18N::translateContext('(a man’s) sister’s child’s son', 'great-nephew');
9956fcafd02SGreg Roach                }
9966fcafd02SGreg Roach
9976fcafd02SGreg Roach                return I18N::translateContext('(a woman’s) sister’s child’s son', 'great-nephew');
9986fcafd02SGreg Roach            case 'sisdauchi':
9996fcafd02SGreg Roach                if ($sex1 === 'M') {
10006fcafd02SGreg Roach                    return I18N::translateContext('(a man’s) sister’s daughter’s child', 'great-nephew/niece');
10016fcafd02SGreg Roach                }
10026fcafd02SGreg Roach
10036fcafd02SGreg Roach                return I18N::translateContext('(a woman’s) sister’s daughter’s child', 'great-nephew/niece');
10046fcafd02SGreg Roach            case 'sisdaudau':
10056fcafd02SGreg Roach                if ($sex1 === 'M') {
10066fcafd02SGreg Roach                    return I18N::translateContext('(a man’s) sister’s daughter’s daughter', 'great-niece');
10076fcafd02SGreg Roach                }
10086fcafd02SGreg Roach
10096fcafd02SGreg Roach                return I18N::translateContext('(a woman’s) sister’s daughter’s daughter', 'great-niece');
10106fcafd02SGreg Roach            case 'sisdauhus':
10116fcafd02SGreg Roach                return I18N::translateContext('sisters’s daughter’s husband', 'nephew-in-law');
10126fcafd02SGreg Roach            case 'sisdauson':
10136fcafd02SGreg Roach                if ($sex1 === 'M') {
10146fcafd02SGreg Roach                    return I18N::translateContext('(a man’s) sister’s daughter’s son', 'great-nephew');
10156fcafd02SGreg Roach                }
10166fcafd02SGreg Roach
10176fcafd02SGreg Roach                return I18N::translateContext('(a woman’s) sister’s daughter’s son', 'great-nephew');
10186fcafd02SGreg Roach            case 'sishusbro':
10196fcafd02SGreg Roach                return I18N::translateContext('sister’s husband’s brother', 'brother-in-law');
10206fcafd02SGreg Roach            case 'sishussib':
10216fcafd02SGreg Roach                return I18N::translateContext('sister’s husband’s sibling', 'brother/sister-in-law');
10226fcafd02SGreg Roach            case 'sishussis':
10236fcafd02SGreg Roach                return I18N::translateContext('sister’s husband’s sister', 'sister-in-law');
10246fcafd02SGreg Roach            case 'sissonchi':
10256fcafd02SGreg Roach                if ($sex1 === 'M') {
10266fcafd02SGreg Roach                    return I18N::translateContext('(a man’s) sister’s son’s child', 'great-nephew/niece');
10276fcafd02SGreg Roach                }
10286fcafd02SGreg Roach
10296fcafd02SGreg Roach                return I18N::translateContext('(a woman’s) sister’s son’s child', 'great-nephew/niece');
10306fcafd02SGreg Roach            case 'sissondau':
10316fcafd02SGreg Roach                if ($sex1 === 'M') {
10326fcafd02SGreg Roach                    return I18N::translateContext('(a man’s) sister’s son’s daughter', 'great-niece');
10336fcafd02SGreg Roach                }
10346fcafd02SGreg Roach
10356fcafd02SGreg Roach                return I18N::translateContext('(a woman’s) sister’s son’s daughter', 'great-niece');
10366fcafd02SGreg Roach            case 'sissonson':
10376fcafd02SGreg Roach                if ($sex1 === 'M') {
10386fcafd02SGreg Roach                    return I18N::translateContext('(a man’s) sister’s son’s son', 'great-nephew');
10396fcafd02SGreg Roach                }
10406fcafd02SGreg Roach
10416fcafd02SGreg Roach                return I18N::translateContext('(a woman’s) sister’s son’s son', 'great-nephew');
10426fcafd02SGreg Roach            case 'sissonwif':
10436fcafd02SGreg Roach                return I18N::translateContext('sisters’s son’s wife', 'niece-in-law');
10446fcafd02SGreg Roach            case 'sonchichi':
10456fcafd02SGreg Roach                return I18N::translateContext('son’s child’s child', 'great-grandchild');
10466fcafd02SGreg Roach            case 'sonchidau':
10476fcafd02SGreg Roach                return I18N::translateContext('son’s child’s daughter', 'great-granddaughter');
10486fcafd02SGreg Roach            case 'sonchison':
10496fcafd02SGreg Roach                return I18N::translateContext('son’s child’s son', 'great-grandson');
10506fcafd02SGreg Roach            case 'sondauchi':
10516fcafd02SGreg Roach                return I18N::translateContext('son’s daughter’s child', 'great-grandchild');
10526fcafd02SGreg Roach            case 'sondaudau':
10536fcafd02SGreg Roach                return I18N::translateContext('son’s daughter’s daughter', 'great-granddaughter');
10546fcafd02SGreg Roach            case 'sondauhus':
10556fcafd02SGreg Roach                return I18N::translateContext('son’s daughter’s husband', 'granddaughter’s husband');
10566fcafd02SGreg Roach            case 'sondauson':
10576fcafd02SGreg Roach                return I18N::translateContext('son’s daughter’s son', 'great-grandson');
10586fcafd02SGreg Roach            case 'sonsonchi':
10596fcafd02SGreg Roach                return I18N::translateContext('son’s son’s child', 'great-grandchild');
10606fcafd02SGreg Roach            case 'sonsondau':
10616fcafd02SGreg Roach                return I18N::translateContext('son’s son’s daughter', 'great-granddaughter');
10626fcafd02SGreg Roach            case 'sonsonson':
10636fcafd02SGreg Roach                return I18N::translateContext('son’s son’s son', 'great-grandson');
10646fcafd02SGreg Roach            case 'sonsonwif':
10656fcafd02SGreg Roach                return I18N::translateContext('son’s son’s wife', 'grandson’s wife');
10666fcafd02SGreg Roach            case 'sonwiffat':
10676fcafd02SGreg Roach                return I18N::translateContext('son’s wife’s father', 'daughter-in-law’s father');
10686fcafd02SGreg Roach            case 'sonwifmot':
10696fcafd02SGreg Roach                return I18N::translateContext('son’s wife’s mother', 'daughter-in-law’s mother');
10706fcafd02SGreg Roach            case 'sonwifpar':
10716fcafd02SGreg Roach                return I18N::translateContext('son’s wife’s parent', 'daughter-in-law’s parent');
10726fcafd02SGreg Roach            case 'wifbrowif':
10736fcafd02SGreg Roach                return I18N::translateContext('wife’s brother’s wife', 'sister-in-law');
10746fcafd02SGreg Roach            case 'wifsishus':
10756fcafd02SGreg Roach                return I18N::translateContext('wife’s sister’s husband', 'brother-in-law');
10766fcafd02SGreg Roach            case 'wifsibchi':
10776fcafd02SGreg Roach                return I18N::translateContext('wife’s sibling’s child', 'nephew/niece');
10786fcafd02SGreg Roach            case 'wifsischi':
10796fcafd02SGreg Roach                return I18N::translateContext('wife’s sister’s child', 'nephew/niece');
10806fcafd02SGreg Roach            case 'wifbrochi':
10816fcafd02SGreg Roach                return I18N::translateContext('wife’s brother’s child', 'nephew/niece');
10826fcafd02SGreg Roach            case 'wifsibdau':
10836fcafd02SGreg Roach                return I18N::translateContext('wife’s sibling’s daughter', 'niece');
10846fcafd02SGreg Roach            case 'wifsisdau':
10856fcafd02SGreg Roach                return I18N::translateContext('wife’s sister’s daughter', 'niece');
10866fcafd02SGreg Roach            case 'wifbrodau':
10876fcafd02SGreg Roach                return I18N::translateContext('wife’s brother’s daughter', 'niece');
10886fcafd02SGreg Roach            case 'wifsibson':
10896fcafd02SGreg Roach                return I18N::translateContext('wife’s sibling’s son', 'nephew');
10906fcafd02SGreg Roach            case 'wifsisson':
10916fcafd02SGreg Roach                return I18N::translateContext('wife’s sister’s son', 'nephew');
10926fcafd02SGreg Roach            case 'wifbroson':
10936fcafd02SGreg Roach                return I18N::translateContext('wife’s brother’s son', 'nephew');
10946fcafd02SGreg Roach
10956fcafd02SGreg Roach            // Some “special case” level four relationships that have specific names in certain languages
10966fcafd02SGreg Roach            case 'fatfatbrowif':
10976fcafd02SGreg Roach                return I18N::translateContext('father’s father’s brother’s wife', 'great-aunt');
10986fcafd02SGreg Roach            case 'fatfatsibspo':
10996fcafd02SGreg Roach                return I18N::translateContext('father’s father’s sibling’s spouse', 'great-aunt/uncle');
11006fcafd02SGreg Roach            case 'fatfatsishus':
11016fcafd02SGreg Roach                return I18N::translateContext('father’s father’s sister’s husband', 'great-uncle');
11026fcafd02SGreg Roach            case 'fatmotbrowif':
11036fcafd02SGreg Roach                return I18N::translateContext('father’s mother’s brother’s wife', 'great-aunt');
11046fcafd02SGreg Roach            case 'fatmotsibspo':
11056fcafd02SGreg Roach                return I18N::translateContext('father’s mother’s sibling’s spouse', 'great-aunt/uncle');
11066fcafd02SGreg Roach            case 'fatmotsishus':
11076fcafd02SGreg Roach                return I18N::translateContext('father’s mother’s sister’s husband', 'great-uncle');
11086fcafd02SGreg Roach            case 'fatparbrowif':
11096fcafd02SGreg Roach                return I18N::translateContext('father’s parent’s brother’s wife', 'great-aunt');
11106fcafd02SGreg Roach            case 'fatparsibspo':
11116fcafd02SGreg Roach                return I18N::translateContext('father’s parent’s sibling’s spouse', 'great-aunt/uncle');
11126fcafd02SGreg Roach            case 'fatparsishus':
11136fcafd02SGreg Roach                return I18N::translateContext('father’s parent’s sister’s husband', 'great-uncle');
11146fcafd02SGreg Roach            case 'motfatbrowif':
11156fcafd02SGreg Roach                return I18N::translateContext('mother’s father’s brother’s wife', 'great-aunt');
11166fcafd02SGreg Roach            case 'motfatsibspo':
11176fcafd02SGreg Roach                return I18N::translateContext('mother’s father’s sibling’s spouse', 'great-aunt/uncle');
11186fcafd02SGreg Roach            case 'motfatsishus':
11196fcafd02SGreg Roach                return I18N::translateContext('mother’s father’s sister’s husband', 'great-uncle');
11206fcafd02SGreg Roach            case 'motmotbrowif':
11216fcafd02SGreg Roach                return I18N::translateContext('mother’s mother’s brother’s wife', 'great-aunt');
11226fcafd02SGreg Roach            case 'motmotsibspo':
11236fcafd02SGreg Roach                return I18N::translateContext('mother’s mother’s sibling’s spouse', 'great-aunt/uncle');
11246fcafd02SGreg Roach            case 'motmotsishus':
11256fcafd02SGreg Roach                return I18N::translateContext('mother’s mother’s sister’s husband', 'great-uncle');
11266fcafd02SGreg Roach            case 'motparbrowif':
11276fcafd02SGreg Roach                return I18N::translateContext('mother’s parent’s brother’s wife', 'great-aunt');
11286fcafd02SGreg Roach            case 'motparsibspo':
11296fcafd02SGreg Roach                return I18N::translateContext('mother’s parent’s sibling’s spouse', 'great-aunt/uncle');
11306fcafd02SGreg Roach            case 'motparsishus':
11316fcafd02SGreg Roach                return I18N::translateContext('mother’s parent’s sister’s husband', 'great-uncle');
11326fcafd02SGreg Roach            case 'parfatbrowif':
11336fcafd02SGreg Roach                return I18N::translateContext('parent’s father’s brother’s wife', 'great-aunt');
11346fcafd02SGreg Roach            case 'parfatsibspo':
11356fcafd02SGreg Roach                return I18N::translateContext('parent’s father’s sibling’s spouse', 'great-aunt/uncle');
11366fcafd02SGreg Roach            case 'parfatsishus':
11376fcafd02SGreg Roach                return I18N::translateContext('parent’s father’s sister’s husband', 'great-uncle');
11386fcafd02SGreg Roach            case 'parmotbrowif':
11396fcafd02SGreg Roach                return I18N::translateContext('parent’s mother’s brother’s wife', 'great-aunt');
11406fcafd02SGreg Roach            case 'parmotsibspo':
11416fcafd02SGreg Roach                return I18N::translateContext('parent’s mother’s sibling’s spouse', 'great-aunt/uncle');
11426fcafd02SGreg Roach            case 'parmotsishus':
11436fcafd02SGreg Roach                return I18N::translateContext('parent’s mother’s sister’s husband', 'great-uncle');
11446fcafd02SGreg Roach            case 'parparbrowif':
11456fcafd02SGreg Roach                return I18N::translateContext('parent’s parent’s brother’s wife', 'great-aunt');
11466fcafd02SGreg Roach            case 'parparsibspo':
11476fcafd02SGreg Roach                return I18N::translateContext('parent’s parent’s sibling’s spouse', 'great-aunt/uncle');
11486fcafd02SGreg Roach            case 'parparsishus':
11496fcafd02SGreg Roach                return I18N::translateContext('parent’s parent’s sister’s husband', 'great-uncle');
11506fcafd02SGreg Roach            case 'fatfatbrodau':
11516fcafd02SGreg Roach                return I18N::translateContext('father’s father’s brother’s daughter', 'first cousin once removed ascending');
11526fcafd02SGreg Roach            case 'fatfatbroson':
11536fcafd02SGreg Roach                return I18N::translateContext('father’s father’s brother’s son', 'first cousin once removed ascending');
11546fcafd02SGreg Roach            case 'fatfatbrochi':
11556fcafd02SGreg Roach                return I18N::translateContext('father’s father’s brother’s child', 'first cousin once removed ascending');
11566fcafd02SGreg Roach            case 'fatfatsisdau':
11576fcafd02SGreg Roach                return I18N::translateContext('father’s father’s sister’s daughter', 'first cousin once removed ascending');
11586fcafd02SGreg Roach            case 'fatfatsisson':
11596fcafd02SGreg Roach                return I18N::translateContext('father’s father’s sister’s son', 'first cousin once removed ascending');
11606fcafd02SGreg Roach            case 'fatfatsischi':
11616fcafd02SGreg Roach                return I18N::translateContext('father’s father’s sister’s child', 'first cousin once removed ascending');
11626fcafd02SGreg Roach            case 'fatmotbrodau':
11636fcafd02SGreg Roach                return I18N::translateContext('father’s mother’s brother’s daughter', 'first cousin once removed ascending');
11646fcafd02SGreg Roach            case 'fatmotbroson':
11656fcafd02SGreg Roach                return I18N::translateContext('father’s mother’s brother’s son', 'first cousin once removed ascending');
11666fcafd02SGreg Roach            case 'fatmotbrochi':
11676fcafd02SGreg Roach                return I18N::translateContext('father’s mother’s brother’s child', 'first cousin once removed ascending');
11686fcafd02SGreg Roach            case 'fatmotsisdau':
11696fcafd02SGreg Roach                return I18N::translateContext('father’s mother’s sister’s daughter', 'first cousin once removed ascending');
11706fcafd02SGreg Roach            case 'fatmotsisson':
11716fcafd02SGreg Roach                return I18N::translateContext('father’s mother’s sister’s son', 'first cousin once removed ascending');
11726fcafd02SGreg Roach            case 'fatmotsischi':
11736fcafd02SGreg Roach                return I18N::translateContext('father’s mother’s sister’s child', 'first cousin once removed ascending');
11746fcafd02SGreg Roach            case 'motfatbrodau':
11756fcafd02SGreg Roach                return I18N::translateContext('mother’s father’s brother’s daughter', 'first cousin once removed ascending');
11766fcafd02SGreg Roach            case 'motfatbroson':
11776fcafd02SGreg Roach                return I18N::translateContext('mother’s father’s brother’s son', 'first cousin once removed ascending');
11786fcafd02SGreg Roach            case 'motfatbrochi':
11796fcafd02SGreg Roach                return I18N::translateContext('mother’s father’s brother’s child', 'first cousin once removed ascending');
11806fcafd02SGreg Roach            case 'motfatsisdau':
11816fcafd02SGreg Roach                return I18N::translateContext('mother’s father’s sister’s daughter', 'first cousin once removed ascending');
11826fcafd02SGreg Roach            case 'motfatsisson':
11836fcafd02SGreg Roach                return I18N::translateContext('mother’s father’s sister’s son', 'first cousin once removed ascending');
11846fcafd02SGreg Roach            case 'motfatsischi':
11856fcafd02SGreg Roach                return I18N::translateContext('mother’s father’s sister’s child', 'first cousin once removed ascending');
11866fcafd02SGreg Roach            case 'motmotbrodau':
11876fcafd02SGreg Roach                return I18N::translateContext('mother’s mother’s brother’s daughter', 'first cousin once removed ascending');
11886fcafd02SGreg Roach            case 'motmotbroson':
11896fcafd02SGreg Roach                return I18N::translateContext('mother’s mother’s brother’s son', 'first cousin once removed ascending');
11906fcafd02SGreg Roach            case 'motmotbrochi':
11916fcafd02SGreg Roach                return I18N::translateContext('mother’s mother’s brother’s child', 'first cousin once removed ascending');
11926fcafd02SGreg Roach            case 'motmotsisdau':
11936fcafd02SGreg Roach                return I18N::translateContext('mother’s mother’s sister’s daughter', 'first cousin once removed ascending');
11946fcafd02SGreg Roach            case 'motmotsisson':
11956fcafd02SGreg Roach                return I18N::translateContext('mother’s mother’s sister’s son', 'first cousin once removed ascending');
11966fcafd02SGreg Roach            case 'motmotsischi':
11976fcafd02SGreg Roach                return I18N::translateContext('mother’s mother’s sister’s child', 'first cousin once removed ascending');
11986fcafd02SGreg Roach        }
11996fcafd02SGreg Roach
12006fcafd02SGreg Roach        // Some “special case” level five relationships that have specific names in certain languages
12016fcafd02SGreg Roach        if (preg_match('/^(mot|fat|par)fatbro(son|dau|chi)dau$/', $path)) {
12026fcafd02SGreg Roach            return I18N::translateContext('grandfather’s brother’s granddaughter', 'second cousin');
12036fcafd02SGreg Roach        }
12046fcafd02SGreg Roach
12056fcafd02SGreg Roach        if (preg_match('/^(mot|fat|par)fatbro(son|dau|chi)son$/', $path)) {
12066fcafd02SGreg Roach            return I18N::translateContext('grandfather’s brother’s grandson', 'second cousin');
12076fcafd02SGreg Roach        }
12086fcafd02SGreg Roach
12096fcafd02SGreg Roach        if (preg_match('/^(mot|fat|par)fatbro(son|dau|chi)chi$/', $path)) {
12106fcafd02SGreg Roach            return I18N::translateContext('grandfather’s brother’s grandchild', 'second cousin');
12116fcafd02SGreg Roach        }
12126fcafd02SGreg Roach
12136fcafd02SGreg Roach        if (preg_match('/^(mot|fat|par)fatsis(son|dau|chi)dau$/', $path)) {
12146fcafd02SGreg Roach            return I18N::translateContext('grandfather’s sister’s granddaughter', 'second cousin');
12156fcafd02SGreg Roach        }
12166fcafd02SGreg Roach
12176fcafd02SGreg Roach        if (preg_match('/^(mot|fat|par)fatsis(son|dau|chi)son$/', $path)) {
12186fcafd02SGreg Roach            return I18N::translateContext('grandfather’s sister’s grandson', 'second cousin');
12196fcafd02SGreg Roach        }
12206fcafd02SGreg Roach
12216fcafd02SGreg Roach        if (preg_match('/^(mot|fat|par)fatsis(son|dau|chi)chi$/', $path)) {
12226fcafd02SGreg Roach            return I18N::translateContext('grandfather’s sister’s grandchild', 'second cousin');
12236fcafd02SGreg Roach        }
12246fcafd02SGreg Roach
12256fcafd02SGreg Roach        if (preg_match('/^(mot|fat|par)fatsib(son|dau|chi)dau$/', $path)) {
12266fcafd02SGreg Roach            return I18N::translateContext('grandfather’s sibling’s granddaughter', 'second cousin');
12276fcafd02SGreg Roach        }
12286fcafd02SGreg Roach
12296fcafd02SGreg Roach        if (preg_match('/^(mot|fat|par)fatsib(son|dau|chi)son$/', $path)) {
12306fcafd02SGreg Roach            return I18N::translateContext('grandfather’s sibling’s grandson', 'second cousin');
12316fcafd02SGreg Roach        }
12326fcafd02SGreg Roach
12336fcafd02SGreg Roach        if (preg_match('/^(mot|fat|par)fatsib(son|dau|chi)chi$/', $path)) {
12346fcafd02SGreg Roach            return I18N::translateContext('grandfather’s sibling’s grandchild', 'second cousin');
12356fcafd02SGreg Roach        }
12366fcafd02SGreg Roach
12376fcafd02SGreg Roach        if (preg_match('/^(mot|fat|par)motbro(son|dau|chi)dau$/', $path)) {
12386fcafd02SGreg Roach            return I18N::translateContext('grandmother’s brother’s granddaughter', 'second cousin');
12396fcafd02SGreg Roach        }
12406fcafd02SGreg Roach
12416fcafd02SGreg Roach        if (preg_match('/^(mot|fat|par)motbro(son|dau|chi)son$/', $path)) {
12426fcafd02SGreg Roach            return I18N::translateContext('grandmother’s brother’s grandson', 'second cousin');
12436fcafd02SGreg Roach        }
12446fcafd02SGreg Roach
12456fcafd02SGreg Roach        if (preg_match('/^(mot|fat|par)motbro(son|dau|chi)chi$/', $path)) {
12466fcafd02SGreg Roach            return I18N::translateContext('grandmother’s brother’s grandchild', 'second cousin');
12476fcafd02SGreg Roach        }
12486fcafd02SGreg Roach
12496fcafd02SGreg Roach        if (preg_match('/^(mot|fat|par)motsis(son|dau|chi)dau$/', $path)) {
12506fcafd02SGreg Roach            return I18N::translateContext('grandmother’s sister’s granddaughter', 'second cousin');
12516fcafd02SGreg Roach        }
12526fcafd02SGreg Roach
12536fcafd02SGreg Roach        if (preg_match('/^(mot|fat|par)motsis(son|dau|chi)son$/', $path)) {
12546fcafd02SGreg Roach            return I18N::translateContext('grandmother’s sister’s grandson', 'second cousin');
12556fcafd02SGreg Roach        }
12566fcafd02SGreg Roach
12576fcafd02SGreg Roach        if (preg_match('/^(mot|fat|par)motsis(son|dau|chi)chi$/', $path)) {
12586fcafd02SGreg Roach            return I18N::translateContext('grandmother’s sister’s grandchild', 'second cousin');
12596fcafd02SGreg Roach        }
12606fcafd02SGreg Roach
12616fcafd02SGreg Roach        if (preg_match('/^(mot|fat|par)motsib(son|dau|chi)dau$/', $path)) {
12626fcafd02SGreg Roach            return I18N::translateContext('grandmother’s sibling’s granddaughter', 'second cousin');
12636fcafd02SGreg Roach        }
12646fcafd02SGreg Roach
12656fcafd02SGreg Roach        if (preg_match('/^(mot|fat|par)motsib(son|dau|chi)son$/', $path)) {
12666fcafd02SGreg Roach            return I18N::translateContext('grandmother’s sibling’s grandson', 'second cousin');
12676fcafd02SGreg Roach        }
12686fcafd02SGreg Roach
12696fcafd02SGreg Roach        if (preg_match('/^(mot|fat|par)motsib(son|dau|chi)chi$/', $path)) {
12706fcafd02SGreg Roach            return I18N::translateContext('grandmother’s sibling’s grandchild', 'second cousin');
12716fcafd02SGreg Roach        }
12726fcafd02SGreg Roach
12736fcafd02SGreg Roach        if (preg_match('/^(mot|fat|par)parbro(son|dau|chi)dau$/', $path)) {
12746fcafd02SGreg Roach            return I18N::translateContext('grandparent’s brother’s granddaughter', 'second cousin');
12756fcafd02SGreg Roach        }
12766fcafd02SGreg Roach
12776fcafd02SGreg Roach        if (preg_match('/^(mot|fat|par)parbro(son|dau|chi)son$/', $path)) {
12786fcafd02SGreg Roach            return I18N::translateContext('grandparent’s brother’s grandson', 'second cousin');
12796fcafd02SGreg Roach        }
12806fcafd02SGreg Roach
12816fcafd02SGreg Roach        if (preg_match('/^(mot|fat|par)parbro(son|dau|chi)chi$/', $path)) {
12826fcafd02SGreg Roach            return I18N::translateContext('grandparent’s brother’s grandchild', 'second cousin');
12836fcafd02SGreg Roach        }
12846fcafd02SGreg Roach
12856fcafd02SGreg Roach        if (preg_match('/^(mot|fat|par)parsis(son|dau|chi)dau$/', $path)) {
12866fcafd02SGreg Roach            return I18N::translateContext('grandparent’s sister’s granddaughter', 'second cousin');
12876fcafd02SGreg Roach        }
12886fcafd02SGreg Roach
12896fcafd02SGreg Roach        if (preg_match('/^(mot|fat|par)parsis(son|dau|chi)son$/', $path)) {
12906fcafd02SGreg Roach            return I18N::translateContext('grandparent’s sister’s grandson', 'second cousin');
12916fcafd02SGreg Roach        }
12926fcafd02SGreg Roach
12936fcafd02SGreg Roach        if (preg_match('/^(mot|fat|par)parsis(son|dau|chi)chi$/', $path)) {
12946fcafd02SGreg Roach            return I18N::translateContext('grandparent’s sister’s grandchild', 'second cousin');
12956fcafd02SGreg Roach        }
12966fcafd02SGreg Roach
12976fcafd02SGreg Roach        if (preg_match('/^(mot|fat|par)parsib(son|dau|chi)dau$/', $path)) {
12986fcafd02SGreg Roach            return I18N::translateContext('grandparent’s sibling’s granddaughter', 'second cousin');
12996fcafd02SGreg Roach        }
13006fcafd02SGreg Roach
13016fcafd02SGreg Roach        if (preg_match('/^(mot|fat|par)parsib(son|dau|chi)son$/', $path)) {
13026fcafd02SGreg Roach            return I18N::translateContext('grandparent’s sibling’s grandson', 'second cousin');
13036fcafd02SGreg Roach        }
13046fcafd02SGreg Roach
13056fcafd02SGreg Roach        if (preg_match('/^(mot|fat|par)parsib(son|dau|chi)chi$/', $path)) {
13066fcafd02SGreg Roach            return I18N::translateContext('grandparent’s sibling’s grandchild', 'second cousin');
13076fcafd02SGreg Roach        }
13086fcafd02SGreg Roach
13096fcafd02SGreg Roach        // Look for generic/pattern relationships.
13106fcafd02SGreg Roach        if (preg_match('/^((?:mot|fat|par)+)(bro|sis|sib)$/', $path, $match)) {
13116fcafd02SGreg Roach            // siblings of direct ancestors
13126fcafd02SGreg Roach            $up       = intdiv(strlen($match[1]), 3);
13136fcafd02SGreg Roach            $bef_last = substr($path, -6, 3);
13146fcafd02SGreg Roach            switch ($up) {
13156fcafd02SGreg Roach                case 3:
13166fcafd02SGreg Roach                    if ($sex2 === 'M') {
13176fcafd02SGreg Roach                        if ($bef_last === 'fat') {
13186fcafd02SGreg Roach                            return I18N::translateContext('great-grandfather’s brother', 'great-great-uncle');
13196fcafd02SGreg Roach                        }
13206fcafd02SGreg Roach
13216fcafd02SGreg Roach                        if ($bef_last === 'mot') {
13226fcafd02SGreg Roach                            return I18N::translateContext('great-grandmother’s brother', 'great-great-uncle');
13236fcafd02SGreg Roach                        }
13246fcafd02SGreg Roach
13256fcafd02SGreg Roach                        return I18N::translateContext('great-grandparent’s brother', 'great-great-uncle');
13266fcafd02SGreg Roach                    }
13276fcafd02SGreg Roach
13286fcafd02SGreg Roach                    if ($sex2 === 'F') {
13296fcafd02SGreg Roach                        return I18N::translate('great-great-aunt');
13306fcafd02SGreg Roach                    }
13316fcafd02SGreg Roach
13326fcafd02SGreg Roach                    return I18N::translate('great-great-aunt/uncle');
13336fcafd02SGreg Roach
13346fcafd02SGreg Roach                case 4:
13356fcafd02SGreg Roach                    if ($sex2 === 'M') {
13366fcafd02SGreg Roach                        if ($bef_last === 'fat') {
13376fcafd02SGreg Roach                            return I18N::translateContext('great-great-grandfather’s brother', 'great-great-great-uncle');
13386fcafd02SGreg Roach                        }
13396fcafd02SGreg Roach
13406fcafd02SGreg Roach                        if ($bef_last === 'mot') {
13416fcafd02SGreg Roach                            return I18N::translateContext('great-great-grandmother’s brother', 'great-great-great-uncle');
13426fcafd02SGreg Roach                        }
13436fcafd02SGreg Roach
13446fcafd02SGreg Roach                        return I18N::translateContext('great-great-grandparent’s brother', 'great-great-great-uncle');
13456fcafd02SGreg Roach                    }
13466fcafd02SGreg Roach
13476fcafd02SGreg Roach                    if ($sex2 === 'F') {
13486fcafd02SGreg Roach                        return I18N::translate('great-great-great-aunt');
13496fcafd02SGreg Roach                    }
13506fcafd02SGreg Roach
13516fcafd02SGreg Roach                    return I18N::translate('great-great-great-aunt/uncle');
13526fcafd02SGreg Roach
13536fcafd02SGreg Roach                case 5:
13546fcafd02SGreg Roach                    if ($sex2 === 'M') {
13556fcafd02SGreg Roach                        if ($bef_last === 'fat') {
13566fcafd02SGreg Roach                            return I18N::translateContext('great-great-great-grandfather’s brother', 'great ×4 uncle');
13576fcafd02SGreg Roach                        }
13586fcafd02SGreg Roach
13596fcafd02SGreg Roach                        if ($bef_last === 'mot') {
13606fcafd02SGreg Roach                            return I18N::translateContext('great-great-great-grandmother’s brother', 'great ×4 uncle');
13616fcafd02SGreg Roach                        }
13626fcafd02SGreg Roach
13636fcafd02SGreg Roach                        return I18N::translateContext('great-great-great-grandparent’s brother', 'great ×4 uncle');
13646fcafd02SGreg Roach                    }
13656fcafd02SGreg Roach
13666fcafd02SGreg Roach                    if ($sex2 === 'F') {
13676fcafd02SGreg Roach                        return I18N::translate('great ×4 aunt');
13686fcafd02SGreg Roach                    }
13696fcafd02SGreg Roach
13706fcafd02SGreg Roach                    return I18N::translate('great ×4 aunt/uncle');
13716fcafd02SGreg Roach
13726fcafd02SGreg Roach                case 6:
13736fcafd02SGreg Roach                    if ($sex2 === 'M') {
13746fcafd02SGreg Roach                        if ($bef_last === 'fat') {
13756fcafd02SGreg Roach                            return I18N::translateContext('great ×4 grandfather’s brother', 'great ×5 uncle');
13766fcafd02SGreg Roach                        }
13776fcafd02SGreg Roach
13786fcafd02SGreg Roach                        if ($bef_last === 'mot') {
13796fcafd02SGreg Roach                            return I18N::translateContext('great ×4 grandmother’s brother', 'great ×5 uncle');
13806fcafd02SGreg Roach                        }
13816fcafd02SGreg Roach
13826fcafd02SGreg Roach                        return I18N::translateContext('great ×4 grandparent’s brother', 'great ×5 uncle');
13836fcafd02SGreg Roach                    }
13846fcafd02SGreg Roach
13856fcafd02SGreg Roach                    if ($sex2 === 'F') {
13866fcafd02SGreg Roach                        return I18N::translate('great ×5 aunt');
13876fcafd02SGreg Roach                    }
13886fcafd02SGreg Roach
13896fcafd02SGreg Roach                    return I18N::translate('great ×5 aunt/uncle');
13906fcafd02SGreg Roach
13916fcafd02SGreg Roach                case 7:
13926fcafd02SGreg Roach                    if ($sex2 === 'M') {
13936fcafd02SGreg Roach                        if ($bef_last === 'fat') {
13946fcafd02SGreg Roach                            return I18N::translateContext('great ×5 grandfather’s brother', 'great ×6 uncle');
13956fcafd02SGreg Roach                        }
13966fcafd02SGreg Roach
13976fcafd02SGreg Roach                        if ($bef_last === 'mot') {
13986fcafd02SGreg Roach                            return I18N::translateContext('great ×5 grandmother’s brother', 'great ×6 uncle');
13996fcafd02SGreg Roach                        }
14006fcafd02SGreg Roach
14016fcafd02SGreg Roach                        return I18N::translateContext('great ×5 grandparent’s brother', 'great ×6 uncle');
14026fcafd02SGreg Roach                    }
14036fcafd02SGreg Roach
14046fcafd02SGreg Roach                    if ($sex2 === 'F') {
14056fcafd02SGreg Roach                        return I18N::translate('great ×6 aunt');
14066fcafd02SGreg Roach                    }
14076fcafd02SGreg Roach
14086fcafd02SGreg Roach                    return I18N::translate('great ×6 aunt/uncle');
14096fcafd02SGreg Roach
14106fcafd02SGreg Roach                case 8:
14116fcafd02SGreg Roach                    if ($sex2 === 'M') {
14126fcafd02SGreg Roach                        if ($bef_last === 'fat') {
14136fcafd02SGreg Roach                            return I18N::translateContext('great ×6 grandfather’s brother', 'great ×7 uncle');
14146fcafd02SGreg Roach                        }
14156fcafd02SGreg Roach
14166fcafd02SGreg Roach                        if ($bef_last === 'mot') {
14176fcafd02SGreg Roach                            return I18N::translateContext('great ×6 grandmother’s brother', 'great ×7 uncle');
14186fcafd02SGreg Roach                        }
14196fcafd02SGreg Roach
14206fcafd02SGreg Roach                        return I18N::translateContext('great ×6 grandparent’s brother', 'great ×7 uncle');
14216fcafd02SGreg Roach                    }
14226fcafd02SGreg Roach
14236fcafd02SGreg Roach                    if ($sex2 === 'F') {
14246fcafd02SGreg Roach                        return I18N::translate('great ×7 aunt');
14256fcafd02SGreg Roach                    }
14266fcafd02SGreg Roach
14276fcafd02SGreg Roach                    return I18N::translate('great ×7 aunt/uncle');
14286fcafd02SGreg Roach
14296fcafd02SGreg Roach                default:
14306fcafd02SGreg Roach                    // Different languages have different rules for naming generations.
14316fcafd02SGreg Roach                    // An English great ×12 uncle is a Danish great ×10 uncle.
14326fcafd02SGreg Roach                    //
14336fcafd02SGreg Roach                    // Need to find out which languages use which rules.
14346fcafd02SGreg Roach                    switch (I18N::languageTag()) {
14356fcafd02SGreg Roach                        case 'da':
14366fcafd02SGreg Roach                            if ($sex2 === 'M') {
14376fcafd02SGreg Roach                                return I18N::translate('great ×%s uncle', I18N::number($up - 4));
14386fcafd02SGreg Roach                            }
14396fcafd02SGreg Roach
14406fcafd02SGreg Roach                            if ($sex2 === 'F') {
14416fcafd02SGreg Roach                                return I18N::translate('great ×%s aunt', I18N::number($up - 4));
14426fcafd02SGreg Roach                            }
14436fcafd02SGreg Roach
14446fcafd02SGreg Roach                            return I18N::translate('great ×%s aunt/uncle', I18N::number($up - 4));
14456fcafd02SGreg Roach
14466fcafd02SGreg Roach                        case 'pl':
14476fcafd02SGreg Roach                            if ($sex2 === 'M') {
14486fcafd02SGreg Roach                                if ($bef_last === 'fat') {
14496fcafd02SGreg Roach                                    return I18N::translateContext('great ×(%s-1) grandfather’s brother', 'great ×%s uncle', I18N::number($up - 2));
14506fcafd02SGreg Roach                                }
14516fcafd02SGreg Roach
14526fcafd02SGreg Roach                                if ($bef_last === 'mot') {
14536fcafd02SGreg Roach                                    return I18N::translateContext('great ×(%s-1) grandmother’s brother', 'great ×%s uncle', I18N::number($up - 2));
14546fcafd02SGreg Roach                                }
14556fcafd02SGreg Roach
14566fcafd02SGreg Roach                                return I18N::translateContext('great ×(%s-1) grandparent’s brother', 'great ×%s uncle', I18N::number($up - 2));
14576fcafd02SGreg Roach                            }
14586fcafd02SGreg Roach
14596fcafd02SGreg Roach                            if ($sex2 === 'F') {
14606fcafd02SGreg Roach                                return I18N::translate('great ×%s aunt', I18N::number($up - 2));
14616fcafd02SGreg Roach                            }
14626fcafd02SGreg Roach
14636fcafd02SGreg Roach                            return I18N::translate('great ×%s aunt/uncle', I18N::number($up - 2));
14646fcafd02SGreg Roach
1465*82566d1aSGreg Roach                        case 'ko': // Source : Jeongwan Nam (jeongwann@gmail.com)
1466*82566d1aSGreg Roach                            if ($sex2 === 'M') {
1467*82566d1aSGreg Roach                                // I18N: if you need a different number for %s, contact the developers, as a code-change is required
1468*82566d1aSGreg Roach                                return I18N::translate('great ×%s uncle', I18N::number($up + 1));
1469*82566d1aSGreg Roach                            }
1470*82566d1aSGreg Roach
1471*82566d1aSGreg Roach                            if ($sex2 === 'F') {
1472*82566d1aSGreg Roach                                return I18N::translate('great ×%s aunt', I18N::number($up + 1));
1473*82566d1aSGreg Roach                            }
1474*82566d1aSGreg Roach
1475*82566d1aSGreg Roach                            return I18N::translate('great ×%s aunt/uncle', I18N::number($up + 1));
1476*82566d1aSGreg Roach
14776fcafd02SGreg Roach                        case 'hi': // Source: MrQD
14786fcafd02SGreg Roach                            if ($sex2 === 'M') {
14796fcafd02SGreg Roach                                // I18N: if you need a different number for %s, contact the developers, as a code-change is required
14806fcafd02SGreg Roach                                return I18N::translate('great ×%s uncle', I18N::number($up - 2));
14816fcafd02SGreg Roach                            }
14826fcafd02SGreg Roach
14836fcafd02SGreg Roach                            if ($sex2 === 'F') {
14846fcafd02SGreg Roach                                return I18N::translate('great ×%s aunt', I18N::number($up - 2));
14856fcafd02SGreg Roach                            }
14866fcafd02SGreg Roach
14876fcafd02SGreg Roach                            return I18N::translate('great ×%s aunt/uncle', I18N::number($up - 2));
14886fcafd02SGreg Roach
14896fcafd02SGreg Roach                        case 'zh-Hans': // Source: xmlf
14906fcafd02SGreg Roach                        case 'zh-Hant':
14916fcafd02SGreg Roach                            if ($sex2 === 'M') {
14926fcafd02SGreg Roach                                return I18N::translate('great ×%s uncle', I18N::number($up));
14936fcafd02SGreg Roach                            }
14946fcafd02SGreg Roach                            if ($sex2 === 'F') {
14956fcafd02SGreg Roach                                return I18N::translate('great ×%s aunt', I18N::number($up));
14966fcafd02SGreg Roach                            }
14976fcafd02SGreg Roach
14986fcafd02SGreg Roach                            return I18N::translate('great ×%s aunt/uncle', I18N::number($up));
14996fcafd02SGreg Roach
15006fcafd02SGreg Roach                        case 'it': // Source: Michele Locati
15016fcafd02SGreg Roach                        case 'en_AU':
15026fcafd02SGreg Roach                        case 'en_GB':
15036fcafd02SGreg Roach                        case 'en_US':
15046fcafd02SGreg Roach                        default:
15056fcafd02SGreg Roach                            if ($sex2 === 'M') {
15066fcafd02SGreg Roach                                // I18N: if you need a different number for %s, contact the developers, as a code-change is required
15076fcafd02SGreg Roach                                return I18N::translate('great ×%s uncle', I18N::number($up - 1));
15086fcafd02SGreg Roach                            }
15096fcafd02SGreg Roach
15106fcafd02SGreg Roach                            if ($sex2 === 'F') {
15116fcafd02SGreg Roach                                return I18N::translate('great ×%s aunt', I18N::number($up - 1));
15126fcafd02SGreg Roach                            }
15136fcafd02SGreg Roach
15146fcafd02SGreg Roach                            return I18N::translate('great ×%s aunt/uncle', I18N::number($up - 1));
15156fcafd02SGreg Roach                    }
15166fcafd02SGreg Roach            }
15176fcafd02SGreg Roach        }
15186fcafd02SGreg Roach        if (preg_match('/^(?:bro|sis|sib)((?:son|dau|chi)+)$/', $path, $match)) {
15196fcafd02SGreg Roach            // direct descendants of siblings
15206fcafd02SGreg Roach            $down  = intdiv(strlen($match[1]), 3) + 1; // Add one, as we count generations from the common ancestor
15216fcafd02SGreg Roach            $first = substr($path, 0, 3);
15226fcafd02SGreg Roach            switch ($down) {
15236fcafd02SGreg Roach                case 4:
15246fcafd02SGreg Roach                    if ($sex2 === 'M') {
15256fcafd02SGreg Roach                        if ($first === 'bro' && $sex1 === 'M') {
15266fcafd02SGreg Roach                            return I18N::translateContext('(a man’s) brother’s great-grandson', 'great-great-nephew');
15276fcafd02SGreg Roach                        }
15286fcafd02SGreg Roach
15296fcafd02SGreg Roach                        if ($first === 'sis' && $sex1 === 'M') {
15306fcafd02SGreg Roach                            return I18N::translateContext('(a man’s) sister’s great-grandson', 'great-great-nephew');
15316fcafd02SGreg Roach                        }
15326fcafd02SGreg Roach
15336fcafd02SGreg Roach                        return I18N::translateContext('(a woman’s) great-great-nephew', 'great-great-nephew');
15346fcafd02SGreg Roach                    }
15356fcafd02SGreg Roach
15366fcafd02SGreg Roach                    if ($sex2 === 'F') {
15376fcafd02SGreg Roach                        if ($first === 'bro' && $sex1 === 'M') {
15386fcafd02SGreg Roach                            return I18N::translateContext('(a man’s) brother’s great-granddaughter', 'great-great-niece');
15396fcafd02SGreg Roach                        }
15406fcafd02SGreg Roach
15416fcafd02SGreg Roach                        if ($first === 'sis' && $sex1 === 'M') {
15426fcafd02SGreg Roach                            return I18N::translateContext('(a man’s) sister’s great-granddaughter', 'great-great-niece');
15436fcafd02SGreg Roach                        }
15446fcafd02SGreg Roach
15456fcafd02SGreg Roach                        return I18N::translateContext('(a woman’s) great-great-niece', 'great-great-niece');
15466fcafd02SGreg Roach                    }
15476fcafd02SGreg Roach
15486fcafd02SGreg Roach                    if ($first === 'bro' && $sex1 === 'M') {
15496fcafd02SGreg Roach                        return I18N::translateContext('(a man’s) brother’s great-grandchild', 'great-great-nephew/niece');
15506fcafd02SGreg Roach                    }
15516fcafd02SGreg Roach
15526fcafd02SGreg Roach                    if ($first === 'sis' && $sex1 === 'M') {
15536fcafd02SGreg Roach                        return I18N::translateContext('(a man’s) sister’s great-grandchild', 'great-great-nephew/niece');
15546fcafd02SGreg Roach                    }
15556fcafd02SGreg Roach
15566fcafd02SGreg Roach                    return I18N::translateContext('(a woman’s) great-great-nephew/niece', 'great-great-nephew/niece');
15576fcafd02SGreg Roach
15586fcafd02SGreg Roach                case 5:
15596fcafd02SGreg Roach                    if ($sex2 === 'M') {
15606fcafd02SGreg Roach                        if ($first === 'bro' && $sex1 === 'M') {
15616fcafd02SGreg Roach                            return I18N::translateContext('(a man’s) brother’s great-great-grandson', 'great-great-great-nephew');
15626fcafd02SGreg Roach                        }
15636fcafd02SGreg Roach
15646fcafd02SGreg Roach                        if ($first === 'sis' && $sex1 === 'M') {
15656fcafd02SGreg Roach                            return I18N::translateContext('(a man’s) sister’s great-great-grandson', 'great-great-great-nephew');
15666fcafd02SGreg Roach                        }
15676fcafd02SGreg Roach
15686fcafd02SGreg Roach                        return I18N::translateContext('(a woman’s) great-great-great-nephew', 'great-great-great-nephew');
15696fcafd02SGreg Roach                    }
15706fcafd02SGreg Roach
15716fcafd02SGreg Roach                    if ($sex2 === 'F') {
15726fcafd02SGreg Roach                        if ($first === 'bro' && $sex1 === 'M') {
15736fcafd02SGreg Roach                            return I18N::translateContext('(a man’s) brother’s great-great-granddaughter', 'great-great-great-niece');
15746fcafd02SGreg Roach                        }
15756fcafd02SGreg Roach
15766fcafd02SGreg Roach                        if ($first === 'sis' && $sex1 === 'M') {
15776fcafd02SGreg Roach                            return I18N::translateContext('(a man’s) sister’s great-great-granddaughter', 'great-great-great-niece');
15786fcafd02SGreg Roach                        }
15796fcafd02SGreg Roach
15806fcafd02SGreg Roach                        return I18N::translateContext('(a woman’s) great-great-great-niece', 'great-great-great-niece');
15816fcafd02SGreg Roach                    }
15826fcafd02SGreg Roach
15836fcafd02SGreg Roach                    if ($first === 'bro' && $sex1 === 'M') {
15846fcafd02SGreg Roach                        return I18N::translateContext('(a man’s) brother’s great-great-grandchild', 'great-great-great-nephew/niece');
15856fcafd02SGreg Roach                    }
15866fcafd02SGreg Roach
15876fcafd02SGreg Roach                    if ($first === 'sis' && $sex1 === 'M') {
15886fcafd02SGreg Roach                        return I18N::translateContext('(a man’s) sister’s great-great-grandchild', 'great-great-great-nephew/niece');
15896fcafd02SGreg Roach                    }
15906fcafd02SGreg Roach
15916fcafd02SGreg Roach                    return I18N::translateContext('(a woman’s) great-great-great-nephew/niece', 'great-great-great-nephew/niece');
15926fcafd02SGreg Roach
15936fcafd02SGreg Roach                case 6:
15946fcafd02SGreg Roach                    if ($sex2 === 'M') {
15956fcafd02SGreg Roach                        if ($first === 'bro' && $sex1 === 'M') {
15966fcafd02SGreg Roach                            return I18N::translateContext('(a man’s) brother’s great-great-great-grandson', 'great ×4 nephew');
15976fcafd02SGreg Roach                        }
15986fcafd02SGreg Roach
15996fcafd02SGreg Roach                        if ($first === 'sis' && $sex1 === 'M') {
16006fcafd02SGreg Roach                            return I18N::translateContext('(a man’s) sister’s great-great-great-grandson', 'great ×4 nephew');
16016fcafd02SGreg Roach                        }
16026fcafd02SGreg Roach
16036fcafd02SGreg Roach                        return I18N::translateContext('(a woman’s) great ×4 nephew', 'great ×4 nephew');
16046fcafd02SGreg Roach                    }
16056fcafd02SGreg Roach
16066fcafd02SGreg Roach                    if ($sex2 === 'F') {
16076fcafd02SGreg Roach                        if ($first === 'bro' && $sex1 === 'M') {
16086fcafd02SGreg Roach                            return I18N::translateContext('(a man’s) brother’s great-great-great-granddaughter', 'great ×4 niece');
16096fcafd02SGreg Roach                        }
16106fcafd02SGreg Roach
16116fcafd02SGreg Roach                        if ($first === 'sis' && $sex1 === 'M') {
16126fcafd02SGreg Roach                            return I18N::translateContext('(a man’s) sister’s great-great-great-granddaughter', 'great ×4 niece');
16136fcafd02SGreg Roach                        }
16146fcafd02SGreg Roach
16156fcafd02SGreg Roach                        return I18N::translateContext('(a woman’s) great ×4 niece', 'great ×4 niece');
16166fcafd02SGreg Roach                    }
16176fcafd02SGreg Roach
16186fcafd02SGreg Roach                    if ($first === 'bro' && $sex1 === 'M') {
16196fcafd02SGreg Roach                        return I18N::translateContext('(a man’s) brother’s great-great-great-grandchild', 'great ×4 nephew/niece');
16206fcafd02SGreg Roach                    }
16216fcafd02SGreg Roach
16226fcafd02SGreg Roach                    if ($first === 'sis' && $sex1 === 'M') {
16236fcafd02SGreg Roach                        return I18N::translateContext('(a man’s) sister’s great-great-great-grandchild', 'great ×4 nephew/niece');
16246fcafd02SGreg Roach                    }
16256fcafd02SGreg Roach
16266fcafd02SGreg Roach                    return I18N::translateContext('(a woman’s) great ×4 nephew/niece', 'great ×4 nephew/niece');
16276fcafd02SGreg Roach
16286fcafd02SGreg Roach                case 7:
16296fcafd02SGreg Roach                    if ($sex2 === 'M') {
16306fcafd02SGreg Roach                        if ($first === 'bro' && $sex1 === 'M') {
16316fcafd02SGreg Roach                            return I18N::translateContext('(a man’s) brother’s great ×4 grandson', 'great ×5 nephew');
16326fcafd02SGreg Roach                        }
16336fcafd02SGreg Roach
16346fcafd02SGreg Roach                        if ($first === 'sis' && $sex1 === 'M') {
16356fcafd02SGreg Roach                            return I18N::translateContext('(a man’s) sister’s great ×4 grandson', 'great ×5 nephew');
16366fcafd02SGreg Roach                        }
16376fcafd02SGreg Roach
16386fcafd02SGreg Roach                        return I18N::translateContext('(a woman’s) great ×5 nephew', 'great ×5 nephew');
16396fcafd02SGreg Roach                    }
16406fcafd02SGreg Roach
16416fcafd02SGreg Roach                    if ($sex2 === 'F') {
16426fcafd02SGreg Roach                        if ($first === 'bro' && $sex1 === 'M') {
16436fcafd02SGreg Roach                            return I18N::translateContext('(a man’s) brother’s great ×4 granddaughter', 'great ×5 niece');
16446fcafd02SGreg Roach                        }
16456fcafd02SGreg Roach
16466fcafd02SGreg Roach                        if ($first === 'sis' && $sex1 === 'M') {
16476fcafd02SGreg Roach                            return I18N::translateContext('(a man’s) sister’s great ×4 granddaughter', 'great ×5 niece');
16486fcafd02SGreg Roach                        }
16496fcafd02SGreg Roach
16506fcafd02SGreg Roach                        return I18N::translateContext('(a woman’s) great ×5 niece', 'great ×5 niece');
16516fcafd02SGreg Roach                    }
16526fcafd02SGreg Roach
16536fcafd02SGreg Roach                    if ($first === 'bro' && $sex1 === 'M') {
16546fcafd02SGreg Roach                        return I18N::translateContext('(a man’s) brother’s great ×4 grandchild', 'great ×5 nephew/niece');
16556fcafd02SGreg Roach                    }
16566fcafd02SGreg Roach
16576fcafd02SGreg Roach                    if ($first === 'sis' && $sex1 === 'M') {
16586fcafd02SGreg Roach                        return I18N::translateContext('(a man’s) sister’s great ×4 grandchild', 'great ×5 nephew/niece');
16596fcafd02SGreg Roach                    }
16606fcafd02SGreg Roach
16616fcafd02SGreg Roach                    return I18N::translateContext('(a woman’s) great ×5 nephew/niece', 'great ×5 nephew/niece');
16626fcafd02SGreg Roach
16636fcafd02SGreg Roach                default:
16646fcafd02SGreg Roach                    // Different languages have different rules for naming generations.
16656fcafd02SGreg Roach                    // An English great ×12 nephew is a Polish great ×11 nephew.
16666fcafd02SGreg Roach                    //
16676fcafd02SGreg Roach                    // Need to find out which languages use which rules.
16686fcafd02SGreg Roach                    switch (I18N::languageTag()) {
16696fcafd02SGreg Roach                        case 'pl': // Source: Lukasz Wilenski
16706fcafd02SGreg Roach                            if ($sex2 === 'M') {
16716fcafd02SGreg Roach                                if ($first === 'bro' && $sex1 === 'M') {
16726fcafd02SGreg Roach                                    return I18N::translateContext('(a man’s) brother’s great ×(%s-1) grandson', 'great ×%s nephew', I18N::number($down - 3));
16736fcafd02SGreg Roach                                }
16746fcafd02SGreg Roach
16756fcafd02SGreg Roach                                if ($first === 'sis' && $sex1 === 'M') {
16766fcafd02SGreg Roach                                    return I18N::translateContext('(a man’s) sister’s great ×(%s-1) grandson', 'great ×%s nephew', I18N::number($down - 3));
16776fcafd02SGreg Roach                                }
16786fcafd02SGreg Roach
16796fcafd02SGreg Roach                                return I18N::translateContext('(a woman’s) great ×%s nephew', 'great ×%s nephew', I18N::number($down - 3));
16806fcafd02SGreg Roach                            }
16816fcafd02SGreg Roach
16826fcafd02SGreg Roach                            if ($sex2 === 'F') {
16836fcafd02SGreg Roach                                if ($first === 'bro' && $sex1 === 'M') {
16846fcafd02SGreg Roach                                    return I18N::translateContext('(a man’s) brother’s great ×(%s-1) granddaughter', 'great ×%s niece', I18N::number($down - 3));
16856fcafd02SGreg Roach                                }
16866fcafd02SGreg Roach
16876fcafd02SGreg Roach                                if ($first === 'sis' && $sex1 === 'M') {
16886fcafd02SGreg Roach                                    return I18N::translateContext('(a man’s) sister’s great ×(%s-1) granddaughter', 'great ×%s niece', I18N::number($down - 3));
16896fcafd02SGreg Roach                                }
16906fcafd02SGreg Roach
16916fcafd02SGreg Roach                                return I18N::translateContext('(a woman’s) great ×%s niece', 'great ×%s niece', I18N::number($down - 3));
16926fcafd02SGreg Roach                            }
16936fcafd02SGreg Roach
16946fcafd02SGreg Roach                            if ($first === 'bro' && $sex1 === 'M') {
16956fcafd02SGreg Roach                                return I18N::translateContext('(a man’s) brother’s great ×(%s-1) grandchild', 'great ×%s nephew/niece', I18N::number($down - 3));
16966fcafd02SGreg Roach                            }
16976fcafd02SGreg Roach
16986fcafd02SGreg Roach                            if ($first === 'sis' && $sex1 === 'M') {
16996fcafd02SGreg Roach                                return I18N::translateContext('(a man’s) sister’s great ×(%s-1) grandchild', 'great ×%s nephew/niece', I18N::number($down - 3));
17006fcafd02SGreg Roach                            }
17016fcafd02SGreg Roach
17026fcafd02SGreg Roach                            return I18N::translateContext('(a woman’s) great ×%s nephew/niece', 'great ×%s nephew/niece', I18N::number($down - 3));
17036fcafd02SGreg Roach
1704*82566d1aSGreg Roach                        case 'ko': // Source: Jeongwan Nam (jeongwann@gmail.com)
1705*82566d1aSGreg Roach                            if ($sex2 === 'M') {
1706*82566d1aSGreg Roach                                if ($first === 'bro' && $sex1 === 'M') {
1707*82566d1aSGreg Roach                                    return I18N::translateContext('(a man’s) brother’s great ×(%s-1) grandson', 'great ×%s nephew', I18N::number($down - 0));
1708*82566d1aSGreg Roach                                }
1709*82566d1aSGreg Roach
1710*82566d1aSGreg Roach                                if ($first === 'sis' && $sex1 === 'M') {
1711*82566d1aSGreg Roach                                    return I18N::translateContext('(a man’s) sister’s great ×(%s-1) grandson', 'great ×%s nephew', I18N::number($down - 0));
1712*82566d1aSGreg Roach                                }
1713*82566d1aSGreg Roach
1714*82566d1aSGreg Roach                                return I18N::translateContext('(a woman’s) great ×%s nephew', 'great ×%s nephew', I18N::number($down - 0));
1715*82566d1aSGreg Roach                            }
1716*82566d1aSGreg Roach
1717*82566d1aSGreg Roach                            if ($sex2 === 'F') {
1718*82566d1aSGreg Roach                                if ($first === 'bro' && $sex1 === 'M') {
1719*82566d1aSGreg Roach                                    return I18N::translateContext('(a man’s) brother’s great ×(%s-1) granddaughter', 'great ×%s niece', I18N::number($down - 3));
1720*82566d1aSGreg Roach                                }
1721*82566d1aSGreg Roach
1722*82566d1aSGreg Roach                                if ($first === 'sis' && $sex1 === 'M') {
1723*82566d1aSGreg Roach                                    return I18N::translateContext('(a man’s) sister’s great ×(%s-1) granddaughter', 'great ×%s niece', I18N::number($down - 3));
1724*82566d1aSGreg Roach                                }
1725*82566d1aSGreg Roach
1726*82566d1aSGreg Roach                                return I18N::translateContext('(a woman’s) great ×%s niece', 'great ×%s niece', I18N::number($down - 3));
1727*82566d1aSGreg Roach                            }
1728*82566d1aSGreg Roach
1729*82566d1aSGreg Roach                            if ($first === 'bro' && $sex1 === 'M') {
1730*82566d1aSGreg Roach                                return I18N::translateContext('(a man’s) brother’s great ×(%s-1) grandchild', 'great ×%s nephew/niece', I18N::number($down - 3));
1731*82566d1aSGreg Roach                            }
1732*82566d1aSGreg Roach
1733*82566d1aSGreg Roach                            if ($first === 'sis' && $sex1 === 'M') {
1734*82566d1aSGreg Roach                                return I18N::translateContext('(a man’s) sister’s great ×(%s-1) grandchild', 'great ×%s nephew/niece', I18N::number($down - 3));
1735*82566d1aSGreg Roach                            }
1736*82566d1aSGreg Roach
1737*82566d1aSGreg Roach                            return I18N::translateContext('(a woman’s) great ×%s nephew/niece', 'great ×%s nephew/niece', I18N::number($down - 3));
1738*82566d1aSGreg Roach
17396fcafd02SGreg Roach                        case 'zh-Hans': // Source: xmlf
17406fcafd02SGreg Roach                        case 'zh-Hant':
17416fcafd02SGreg Roach                            if ($sex2 === 'M') {
17426fcafd02SGreg Roach                                if ($first === 'bro' && $sex1 === 'M') {
17436fcafd02SGreg Roach                                    return I18N::translateContext('(a man’s) brother’s great ×(%s-1) grandson', 'great ×%s nephew', I18N::number($down - 1));
17446fcafd02SGreg Roach                                }
17456fcafd02SGreg Roach                                if ($first === 'sis' && $sex1 === 'M') {
17466fcafd02SGreg Roach                                    return I18N::translateContext('(a man’s) sister’s great ×(%s-1) grandson', 'great ×%s nephew', I18N::number($down - 1));
17476fcafd02SGreg Roach                                }
17486fcafd02SGreg Roach
17496fcafd02SGreg Roach                                return I18N::translateContext('(a woman’s) great ×%s nephew', 'great ×%s nephew', I18N::number($down - 1));
17506fcafd02SGreg Roach                            }
17516fcafd02SGreg Roach                            if ($sex2 === 'F') {
17526fcafd02SGreg Roach                                if ($first === 'bro' && $sex1 === 'M') {
17536fcafd02SGreg Roach                                    return I18N::translateContext('(a man’s) brother’s great ×(%s-1) granddaughter', 'great ×%s niece', I18N::number($down - 1));
17546fcafd02SGreg Roach                                }
17556fcafd02SGreg Roach                                if ($first === 'sis' && $sex1 === 'M') {
17566fcafd02SGreg Roach                                    return I18N::translateContext('(a man’s) sister’s great ×(%s-1) granddaughter', 'great ×%s niece', I18N::number($down - 1));
17576fcafd02SGreg Roach                                }
17586fcafd02SGreg Roach
17596fcafd02SGreg Roach                                return I18N::translateContext('(a woman’s) great ×%s niece', 'great ×%s niece', I18N::number($down - 1));
17606fcafd02SGreg Roach                            }
17616fcafd02SGreg Roach                            if ($first === 'bro' && $sex1 === 'M') {
17626fcafd02SGreg Roach                                return I18N::translateContext('(a man’s) brother’s great ×(%s-1) grandchild', 'great ×%s nephew/niece', I18N::number($down - 1));
17636fcafd02SGreg Roach                            }
17646fcafd02SGreg Roach                            if ($first === 'sis' && $sex1 === 'M') {
17656fcafd02SGreg Roach                                return I18N::translateContext('(a man’s) sister’s great ×(%s-1) grandchild', 'great ×%s nephew/niece', I18N::number($down - 1));
17666fcafd02SGreg Roach                            }
17676fcafd02SGreg Roach
17686fcafd02SGreg Roach                            return I18N::translateContext('(a woman’s) great ×%s nephew/niece', 'great ×%s nephew/niece', I18N::number($down - 1));
17696fcafd02SGreg Roach
17706fcafd02SGreg Roach                        case 'he': // Source: Meliza Amity
17716fcafd02SGreg Roach                            if ($sex2 === 'M') {
17726fcafd02SGreg Roach                                return I18N::translate('great ×%s nephew', I18N::number($down - 1));
17736fcafd02SGreg Roach                            }
17746fcafd02SGreg Roach
17756fcafd02SGreg Roach                            if ($sex2 === 'F') {
17766fcafd02SGreg Roach                                return I18N::translate('great ×%s niece', I18N::number($down - 1));
17776fcafd02SGreg Roach                            }
17786fcafd02SGreg Roach
17796fcafd02SGreg Roach                            return I18N::translate('great ×%s nephew/niece', I18N::number($down - 1));
17806fcafd02SGreg Roach
17816fcafd02SGreg Roach                        case 'hi': // Source: MrQD.
17826fcafd02SGreg Roach                            if ($sex2 === 'M') {
17836fcafd02SGreg Roach                                // I18N: if you need a different number for %s, contact the developers, as a code-change is required
17846fcafd02SGreg Roach                                return I18N::translate('great ×%s nephew', I18N::number($down - 3));
17856fcafd02SGreg Roach                            }
17866fcafd02SGreg Roach
17876fcafd02SGreg Roach                            if ($sex2 === 'F') {
17886fcafd02SGreg Roach                                return I18N::translate('great ×%s niece', I18N::number($down - 3));
17896fcafd02SGreg Roach                            }
17906fcafd02SGreg Roach
17916fcafd02SGreg Roach                            return I18N::translate('great ×%s nephew/niece', I18N::number($down - 3));
17926fcafd02SGreg Roach
17936fcafd02SGreg Roach                        case 'it': // Source: Michele Locati.
17946fcafd02SGreg Roach                        case 'en_AU':
17956fcafd02SGreg Roach                        case 'en_GB':
17966fcafd02SGreg Roach                        case 'en_US':
17976fcafd02SGreg Roach                        default:
17986fcafd02SGreg Roach                            if ($sex2 === 'M') {
17996fcafd02SGreg Roach                                // I18N: if you need a different number for %s, contact the developers, as a code-change is required
18006fcafd02SGreg Roach                                return I18N::translate('great ×%s nephew', I18N::number($down - 2));
18016fcafd02SGreg Roach                            }
18026fcafd02SGreg Roach
18036fcafd02SGreg Roach                            if ($sex2 === 'F') {
18046fcafd02SGreg Roach                                return I18N::translate('great ×%s niece', I18N::number($down - 2));
18056fcafd02SGreg Roach                            }
18066fcafd02SGreg Roach
18076fcafd02SGreg Roach                            return I18N::translate('great ×%s nephew/niece', I18N::number($down - 2));
18086fcafd02SGreg Roach                    }
18096fcafd02SGreg Roach            }
18106fcafd02SGreg Roach        }
18116fcafd02SGreg Roach        if (preg_match('/^((?:mot|fat|par)*)$/', $path, $match)) {
18126fcafd02SGreg Roach            // direct ancestors
18136fcafd02SGreg Roach            $up = intdiv(strlen($match[1]), 3);
18146fcafd02SGreg Roach            switch ($up) {
18156fcafd02SGreg Roach                case 4:
18166fcafd02SGreg Roach                    if ($sex2 === 'M') {
18176fcafd02SGreg Roach                        return I18N::translate('great-great-grandfather');
18186fcafd02SGreg Roach                    }
18196fcafd02SGreg Roach
18206fcafd02SGreg Roach                    if ($sex2 === 'F') {
18216fcafd02SGreg Roach                        return I18N::translate('great-great-grandmother');
18226fcafd02SGreg Roach                    }
18236fcafd02SGreg Roach
18246fcafd02SGreg Roach                    return I18N::translate('great-great-grandparent');
18256fcafd02SGreg Roach
18266fcafd02SGreg Roach                case 5:
18276fcafd02SGreg Roach                    if ($sex2 === 'M') {
18286fcafd02SGreg Roach                        return I18N::translate('great-great-great-grandfather');
18296fcafd02SGreg Roach                    }
18306fcafd02SGreg Roach
18316fcafd02SGreg Roach                    if ($sex2 === 'F') {
18326fcafd02SGreg Roach                        return I18N::translate('great-great-great-grandmother');
18336fcafd02SGreg Roach                    }
18346fcafd02SGreg Roach
18356fcafd02SGreg Roach                    return I18N::translate('great-great-great-grandparent');
18366fcafd02SGreg Roach
18376fcafd02SGreg Roach                case 6:
18386fcafd02SGreg Roach                    if ($sex2 === 'M') {
18396fcafd02SGreg Roach                        return I18N::translate('great ×4 grandfather');
18406fcafd02SGreg Roach                    }
18416fcafd02SGreg Roach
18426fcafd02SGreg Roach                    if ($sex2 === 'F') {
18436fcafd02SGreg Roach                        return I18N::translate('great ×4 grandmother');
18446fcafd02SGreg Roach                    }
18456fcafd02SGreg Roach
18466fcafd02SGreg Roach                    return I18N::translate('great ×4 grandparent');
18476fcafd02SGreg Roach
18486fcafd02SGreg Roach                case 7:
18496fcafd02SGreg Roach                    if ($sex2 === 'M') {
18506fcafd02SGreg Roach                        return I18N::translate('great ×5 grandfather');
18516fcafd02SGreg Roach                    }
18526fcafd02SGreg Roach
18536fcafd02SGreg Roach                    if ($sex2 === 'F') {
18546fcafd02SGreg Roach                        return I18N::translate('great ×5 grandmother');
18556fcafd02SGreg Roach                    }
18566fcafd02SGreg Roach
18576fcafd02SGreg Roach                    return I18N::translate('great ×5 grandparent');
18586fcafd02SGreg Roach
18596fcafd02SGreg Roach                case 8:
18606fcafd02SGreg Roach                    if ($sex2 === 'M') {
18616fcafd02SGreg Roach                        return I18N::translate('great ×6 grandfather');
18626fcafd02SGreg Roach                    }
18636fcafd02SGreg Roach
18646fcafd02SGreg Roach                    if ($sex2 === 'F') {
18656fcafd02SGreg Roach                        return I18N::translate('great ×6 grandmother');
18666fcafd02SGreg Roach                    }
18676fcafd02SGreg Roach
18686fcafd02SGreg Roach                    return I18N::translate('great ×6 grandparent');
18696fcafd02SGreg Roach
18706fcafd02SGreg Roach                case 9:
18716fcafd02SGreg Roach                    if ($sex2 === 'M') {
18726fcafd02SGreg Roach                        return I18N::translate('great ×7 grandfather');
18736fcafd02SGreg Roach                    }
18746fcafd02SGreg Roach
18756fcafd02SGreg Roach                    if ($sex2 === 'F') {
18766fcafd02SGreg Roach                        return I18N::translate('great ×7 grandmother');
18776fcafd02SGreg Roach                    }
18786fcafd02SGreg Roach
18796fcafd02SGreg Roach                    return I18N::translate('great ×7 grandparent');
18806fcafd02SGreg Roach
18816fcafd02SGreg Roach                default:
18826fcafd02SGreg Roach                    // Different languages have different rules for naming generations.
18836fcafd02SGreg Roach                    // An English great ×12 grandfather is a Danish great ×11 grandfather.
18846fcafd02SGreg Roach                    //
18856fcafd02SGreg Roach                    // Need to find out which languages use which rules.
18866fcafd02SGreg Roach                    switch (I18N::languageTag()) {
18876fcafd02SGreg Roach                        case 'da': // Source: Patrick Sorensen
18886fcafd02SGreg Roach                            if ($sex2 === 'M') {
18896fcafd02SGreg Roach                                return I18N::translate('great ×%s grandfather', I18N::number($up - 3));
18906fcafd02SGreg Roach                            }
18916fcafd02SGreg Roach
18926fcafd02SGreg Roach                            if ($sex2 === 'F') {
18936fcafd02SGreg Roach                                return I18N::translate('great ×%s grandmother', I18N::number($up - 3));
18946fcafd02SGreg Roach                            }
18956fcafd02SGreg Roach
18966fcafd02SGreg Roach                            return I18N::translate('great ×%s grandparent', I18N::number($up - 3));
18976fcafd02SGreg Roach
18986fcafd02SGreg Roach                        case 'it': // Source: Michele Locati
18996fcafd02SGreg Roach                        case 'zh-Hans': // Source: xmlf
19006fcafd02SGreg Roach                        case 'zh-Hant':
19016fcafd02SGreg Roach                        case 'es': // Source: Wes Groleau
19026fcafd02SGreg Roach                            if ($sex2 === 'M') {
19036fcafd02SGreg Roach                                return I18N::translate('great ×%s grandfather', I18N::number($up));
19046fcafd02SGreg Roach                            }
19056fcafd02SGreg Roach
19066fcafd02SGreg Roach                            if ($sex2 === 'F') {
19076fcafd02SGreg Roach                                return I18N::translate('great ×%s grandmother', I18N::number($up));
19086fcafd02SGreg Roach                            }
19096fcafd02SGreg Roach
19106fcafd02SGreg Roach                            return I18N::translate('great ×%s grandparent', I18N::number($up));
19116fcafd02SGreg Roach
19126fcafd02SGreg Roach                        case 'fr': // Source: Jacqueline Tetreault
19136fcafd02SGreg Roach                        case 'fr_CA':
19146fcafd02SGreg Roach                            if ($sex2 === 'M') {
19156fcafd02SGreg Roach                                return I18N::translate('great ×%s grandfather', I18N::number($up - 1));
19166fcafd02SGreg Roach                            }
19176fcafd02SGreg Roach
19186fcafd02SGreg Roach                            if ($sex2 === 'F') {
19196fcafd02SGreg Roach                                return I18N::translate('great ×%s grandmother', I18N::number($up - 1));
19206fcafd02SGreg Roach                            }
19216fcafd02SGreg Roach
19226fcafd02SGreg Roach                            return I18N::translate('great ×%s grandparent', I18N::number($up - 1));
19236fcafd02SGreg Roach
1924*82566d1aSGreg Roach                        case 'ko': // Source : Jeongwan Nam (jeongwann@gmail.com)
1925*82566d1aSGreg Roach                            if ($sex2 === 'M') {
1926*82566d1aSGreg Roach                                return I18N::translate('great ×%s grandfather', I18N::number($up + 1));
1927*82566d1aSGreg Roach                            }
1928*82566d1aSGreg Roach
1929*82566d1aSGreg Roach                            if ($sex2 === 'F') {
1930*82566d1aSGreg Roach                                return I18N::translate('great ×%s grandmother', I18N::number($up + 1));
1931*82566d1aSGreg Roach                            }
1932*82566d1aSGreg Roach
1933*82566d1aSGreg Roach                            return I18N::translate('great ×%s grandparent', I18N::number($up + 1));
1934*82566d1aSGreg Roach
19356fcafd02SGreg Roach                        case 'nn': // Source: Hogne Røed Nilsen (https://bugs.launchpad.net/webtrees/+bug/1168553)
19366fcafd02SGreg Roach                        case 'nb':
19376fcafd02SGreg Roach                            if ($sex2 === 'M') {
19386fcafd02SGreg Roach                                // I18N: if you need a different number for %s, contact the developers, as a code-change is required
19396fcafd02SGreg Roach                                return I18N::translate('great ×%s grandfather', I18N::number($up - 3));
19406fcafd02SGreg Roach                            }
19416fcafd02SGreg Roach
19426fcafd02SGreg Roach                            if ($sex2 === 'F') {
19436fcafd02SGreg Roach                                // I18N: if you need a different number for %s, contact the developers, as a code-change is required
19446fcafd02SGreg Roach                                return I18N::translate('great ×%s grandmother', I18N::number($up - 3));
19456fcafd02SGreg Roach                            }
19466fcafd02SGreg Roach
19476fcafd02SGreg Roach                            // I18N: if you need a different number for %s, contact the developers, as a code-change is required
19486fcafd02SGreg Roach                            return I18N::translate('great ×%s grandparent', I18N::number($up - 3));
19496fcafd02SGreg Roach                        case 'en_AU':
19506fcafd02SGreg Roach                        case 'en_GB':
19516fcafd02SGreg Roach                        case 'en_US':
19526fcafd02SGreg Roach                        default:
19536fcafd02SGreg Roach                            if ($sex2 === 'M') {
19546fcafd02SGreg Roach                                // I18N: if you need a different number for %s, contact the developers, as a code-change is required
19556fcafd02SGreg Roach                                return I18N::translate('great ×%s grandfather', I18N::number($up - 2));
19566fcafd02SGreg Roach                            }
19576fcafd02SGreg Roach
19586fcafd02SGreg Roach                            if ($sex2 === 'F') {
19596fcafd02SGreg Roach                                // I18N: if you need a different number for %s, contact the developers, as a code-change is required
19606fcafd02SGreg Roach                                return I18N::translate('great ×%s grandmother', I18N::number($up - 2));
19616fcafd02SGreg Roach                            }
19626fcafd02SGreg Roach
19636fcafd02SGreg Roach                            // I18N: if you need a different number for %s, contact the developers, as a code-change is required
19646fcafd02SGreg Roach                            return I18N::translate('great ×%s grandparent', I18N::number($up - 2));
19656fcafd02SGreg Roach                    }
19666fcafd02SGreg Roach            }
19676fcafd02SGreg Roach        }
19686fcafd02SGreg Roach        if (preg_match('/^((?:son|dau|chi)*)$/', $path, $match)) {
19696fcafd02SGreg Roach            // direct descendants
19706fcafd02SGreg Roach            $up = intdiv(strlen($match[1]), 3);
19716fcafd02SGreg Roach            switch ($up) {
19726fcafd02SGreg Roach                case 4:
19736fcafd02SGreg Roach                    if ($sex2 === 'M') {
19746fcafd02SGreg Roach                        return I18N::translate('great-great-grandson');
19756fcafd02SGreg Roach                    }
19766fcafd02SGreg Roach
19776fcafd02SGreg Roach                    if ($sex2 === 'F') {
19786fcafd02SGreg Roach                        return I18N::translate('great-great-granddaughter');
19796fcafd02SGreg Roach                    }
19806fcafd02SGreg Roach
19816fcafd02SGreg Roach                    return I18N::translate('great-great-grandchild');
19826fcafd02SGreg Roach
19836fcafd02SGreg Roach                case 5:
19846fcafd02SGreg Roach                    if ($sex2 === 'M') {
19856fcafd02SGreg Roach                        return I18N::translate('great-great-great-grandson');
19866fcafd02SGreg Roach                    }
19876fcafd02SGreg Roach
19886fcafd02SGreg Roach                    if ($sex2 === 'F') {
19896fcafd02SGreg Roach                        return I18N::translate('great-great-great-granddaughter');
19906fcafd02SGreg Roach                    }
19916fcafd02SGreg Roach
19926fcafd02SGreg Roach                    return I18N::translate('great-great-great-grandchild');
19936fcafd02SGreg Roach
19946fcafd02SGreg Roach                case 6:
19956fcafd02SGreg Roach                    if ($sex2 === 'M') {
19966fcafd02SGreg Roach                        return I18N::translate('great ×4 grandson');
19976fcafd02SGreg Roach                    }
19986fcafd02SGreg Roach
19996fcafd02SGreg Roach                    if ($sex2 === 'F') {
20006fcafd02SGreg Roach                        return I18N::translate('great ×4 granddaughter');
20016fcafd02SGreg Roach                    }
20026fcafd02SGreg Roach
20036fcafd02SGreg Roach                    return I18N::translate('great ×4 grandchild');
20046fcafd02SGreg Roach
20056fcafd02SGreg Roach                case 7:
20066fcafd02SGreg Roach                    if ($sex2 === 'M') {
20076fcafd02SGreg Roach                        return I18N::translate('great ×5 grandson');
20086fcafd02SGreg Roach                    }
20096fcafd02SGreg Roach
20106fcafd02SGreg Roach                    if ($sex2 === 'F') {
20116fcafd02SGreg Roach                        return I18N::translate('great ×5 granddaughter');
20126fcafd02SGreg Roach                    }
20136fcafd02SGreg Roach
20146fcafd02SGreg Roach                    return I18N::translate('great ×5 grandchild');
20156fcafd02SGreg Roach
20166fcafd02SGreg Roach                case 8:
20176fcafd02SGreg Roach                    if ($sex2 === 'M') {
20186fcafd02SGreg Roach                        return I18N::translate('great ×6 grandson');
20196fcafd02SGreg Roach                    }
20206fcafd02SGreg Roach
20216fcafd02SGreg Roach                    if ($sex2 === 'F') {
20226fcafd02SGreg Roach                        return I18N::translate('great ×6 granddaughter');
20236fcafd02SGreg Roach                    }
20246fcafd02SGreg Roach
20256fcafd02SGreg Roach                    return I18N::translate('great ×6 grandchild');
20266fcafd02SGreg Roach
20276fcafd02SGreg Roach                case 9:
20286fcafd02SGreg Roach                    if ($sex2 === 'M') {
20296fcafd02SGreg Roach                        return I18N::translate('great ×7 grandson');
20306fcafd02SGreg Roach                    }
20316fcafd02SGreg Roach
20326fcafd02SGreg Roach                    if ($sex2 === 'F') {
20336fcafd02SGreg Roach                        return I18N::translate('great ×7 granddaughter');
20346fcafd02SGreg Roach                    }
20356fcafd02SGreg Roach
20366fcafd02SGreg Roach                    return I18N::translate('great ×7 grandchild');
20376fcafd02SGreg Roach
20386fcafd02SGreg Roach                default:
20396fcafd02SGreg Roach                    // Different languages have different rules for naming generations.
20406fcafd02SGreg Roach                    // An English great ×12 grandson is a Danish great ×11 grandson.
20416fcafd02SGreg Roach                    //
20426fcafd02SGreg Roach                    // Need to find out which languages use which rules.
20436fcafd02SGreg Roach                    switch (I18N::languageTag()) {
20446fcafd02SGreg Roach                        case 'nn': // Source: Hogne Røed Nilsen
20456fcafd02SGreg Roach                        case 'nb':
20466fcafd02SGreg Roach                        case 'da': // Source: Patrick Sorensen
20476fcafd02SGreg Roach                            if ($sex2 === 'M') {
20486fcafd02SGreg Roach                                return I18N::translate('great ×%s grandson', I18N::number($up - 3));
20496fcafd02SGreg Roach                            }
20506fcafd02SGreg Roach
20516fcafd02SGreg Roach                            if ($sex2 === 'F') {
20526fcafd02SGreg Roach                                return I18N::translate('great ×%s granddaughter', I18N::number($up - 3));
20536fcafd02SGreg Roach                            }
20546fcafd02SGreg Roach
20556fcafd02SGreg Roach                            return I18N::translate('great ×%s grandchild', I18N::number($up - 3));
20566fcafd02SGreg Roach
2057*82566d1aSGreg Roach                        case 'ko': // Source : Jeongwan Nam (jeongwann@gmail.com)
2058*82566d1aSGreg Roach                            if ($sex2 === 'M') {
2059*82566d1aSGreg Roach                                return I18N::translate('great ×%s grandson', I18N::number($up + 1));
2060*82566d1aSGreg Roach                            }
2061*82566d1aSGreg Roach
2062*82566d1aSGreg Roach                            if ($sex2 === 'F') {
2063*82566d1aSGreg Roach                                return I18N::translate('great ×%s granddaughter', I18N::number($up + 1));
2064*82566d1aSGreg Roach                            }
2065*82566d1aSGreg Roach
2066*82566d1aSGreg Roach                            return I18N::translate('great ×%s grandchild', I18N::number($up + 1));
2067*82566d1aSGreg Roach
20686fcafd02SGreg Roach                        case 'zh-Hans': // Source: xmlf
20696fcafd02SGreg Roach                        case 'zh-Hant':
20706fcafd02SGreg Roach                            if ($sex2 === 'M') {
20716fcafd02SGreg Roach                                return I18N::translate('great ×%s grandson', I18N::number($up));
20726fcafd02SGreg Roach                            }
20736fcafd02SGreg Roach                            if ($sex2 === 'F') {
20746fcafd02SGreg Roach                                return I18N::translate('great ×%s granddaughter', I18N::number($up));
20756fcafd02SGreg Roach                            }
20766fcafd02SGreg Roach
20776fcafd02SGreg Roach                            return I18N::translate('great ×%s grandchild', I18N::number($up));
20786fcafd02SGreg Roach
20796fcafd02SGreg Roach                        case 'it':
20806fcafd02SGreg Roach                            // Source: Michele Locati
20816fcafd02SGreg Roach                        case 'es':
20826fcafd02SGreg Roach                            // Source: Wes Groleau (adding doesn’t change behavior, but needs to be better researched)
20836fcafd02SGreg Roach                        case 'en_AU':
20846fcafd02SGreg Roach                        case 'en_GB':
20856fcafd02SGreg Roach                        case 'en_US':
20866fcafd02SGreg Roach                        default:
20876fcafd02SGreg Roach                            if ($sex2 === 'M') {
20886fcafd02SGreg Roach                                // I18N: if you need a different number for %s, contact the developers, as a code-change is required
20896fcafd02SGreg Roach                                return I18N::translate('great ×%s grandson', I18N::number($up - 2));
20906fcafd02SGreg Roach                            }
20916fcafd02SGreg Roach
20926fcafd02SGreg Roach                            if ($sex2 === 'F') {
20936fcafd02SGreg Roach                                // I18N: if you need a different number for %s, contact the developers, as a code-change is required
20946fcafd02SGreg Roach                                return I18N::translate('great ×%s granddaughter', I18N::number($up - 2));
20956fcafd02SGreg Roach                            }
20966fcafd02SGreg Roach
20976fcafd02SGreg Roach                            // I18N: if you need a different number for %s, contact the developers, as a code-change is required
20986fcafd02SGreg Roach                            return I18N::translate('great ×%s grandchild', I18N::number($up - 2));
20996fcafd02SGreg Roach                    }
21006fcafd02SGreg Roach            }
21016fcafd02SGreg Roach        }
21026fcafd02SGreg Roach        if (preg_match('/^((?:mot|fat|par)+)(?:bro|sis|sib)((?:son|dau|chi)+)$/', $path, $match)) {
21036fcafd02SGreg Roach            // cousins in English
21046fcafd02SGreg Roach            $ascent  = $match[1];
21056fcafd02SGreg Roach            $descent = $match[2];
21066fcafd02SGreg Roach            $up      = intdiv(strlen($ascent), 3);
21076fcafd02SGreg Roach            $down    = intdiv(strlen($descent), 3);
21086fcafd02SGreg Roach            $cousin  = min($up, $down); // Moved out of switch (en/default case) so that
21096fcafd02SGreg Roach            $removed = abs($down - $up); // Spanish (and other languages) can use it, too.
21106fcafd02SGreg Roach
21116fcafd02SGreg Roach            // Different languages have different rules for naming cousins. For example,
21126fcafd02SGreg Roach            // an English “second cousin once removed” is a Polish “cousin of 7th degree”.
21136fcafd02SGreg Roach            //
21146fcafd02SGreg Roach            // Need to find out which languages use which rules.
21156fcafd02SGreg Roach            switch (I18N::languageTag()) {
21166fcafd02SGreg Roach                case 'pl': // Source: Lukasz Wilenski
21176fcafd02SGreg Roach                    return self::legacyCousinName($up + $down + 2, $sex2);
21186fcafd02SGreg Roach                case 'it':
21196fcafd02SGreg Roach                    // Source: Michele Locati. See italian_cousins_names.zip
21206fcafd02SGreg Roach                    // https://webtrees.net/forums/8-translation/1200-great-xn-grandparent?limit=6&start=6
21216fcafd02SGreg Roach                    return self::legacyCousinName($up + $down - 3, $sex2);
21226fcafd02SGreg Roach                case 'es':
21236fcafd02SGreg Roach                    if ($down === $up) {
21246fcafd02SGreg Roach                        return self::legacyCousinName($cousin, $sex2);
21256fcafd02SGreg Roach                    }
21266fcafd02SGreg Roach
21276fcafd02SGreg Roach                    if ($down < $up) {
21286fcafd02SGreg Roach                        return self::legacyCousinName2($cousin + 1, $sex2, $this->legacyNameAlgorithm('sib' . $descent));
21296fcafd02SGreg Roach                    }
21306fcafd02SGreg Roach
21316fcafd02SGreg Roach                    if ($sex2 === 'M') {
21326fcafd02SGreg Roach                        return self::legacyCousinName2($cousin + 1, $sex2, $this->legacyNameAlgorithm('bro' . $descent));
21336fcafd02SGreg Roach                    }
21346fcafd02SGreg Roach
21356fcafd02SGreg Roach                    if ($sex2 === 'F') {
21366fcafd02SGreg Roach                        return self::legacyCousinName2($cousin + 1, $sex2, $this->legacyNameAlgorithm('sis' . $descent));
21376fcafd02SGreg Roach                    }
21386fcafd02SGreg Roach
21396fcafd02SGreg Roach                    return self::legacyCousinName2($cousin + 1, $sex2, $this->legacyNameAlgorithm('sib' . $descent));
21406fcafd02SGreg Roach
2141ad3143ccSGreg Roach                case 'en_AU': // See: https://en.wikipedia.org/wiki/File:CousinTree.svg
21426fcafd02SGreg Roach                case 'en_GB':
21436fcafd02SGreg Roach                case 'en_US':
21446fcafd02SGreg Roach                default:
21456fcafd02SGreg Roach                    switch ($removed) {
21466fcafd02SGreg Roach                        case 0:
21476fcafd02SGreg Roach                            return self::legacyCousinName($cousin, $sex2);
21486fcafd02SGreg Roach                        case 1:
21496fcafd02SGreg Roach                            if ($up > $down) {
2150ad3143ccSGreg Roach                                /* I18N: %s=“fifth cousin”, etc. */
21516fcafd02SGreg Roach                                return I18N::translate('%s once removed ascending', self::legacyCousinName($cousin, $sex2));
21526fcafd02SGreg Roach                            }
21536fcafd02SGreg Roach
2154ad3143ccSGreg Roach                            /* I18N: %s=“fifth cousin”, etc. */
21556fcafd02SGreg Roach
21566fcafd02SGreg Roach                            return I18N::translate('%s once removed descending', self::legacyCousinName($cousin, $sex2));
21576fcafd02SGreg Roach                        case 2:
21586fcafd02SGreg Roach                            if ($up > $down) {
21596fcafd02SGreg Roach                                /* I18N: %s=“fifth cousin”, etc. */
21606fcafd02SGreg Roach                                return I18N::translate('%s twice removed ascending', self::legacyCousinName($cousin, $sex2));
21616fcafd02SGreg Roach                            }
21626fcafd02SGreg Roach
21636fcafd02SGreg Roach                            /* I18N: %s=“fifth cousin”, etc. */
21646fcafd02SGreg Roach
21656fcafd02SGreg Roach                            return I18N::translate('%s twice removed descending', self::legacyCousinName($cousin, $sex2));
21666fcafd02SGreg Roach                        case 3:
21676fcafd02SGreg Roach                            if ($up > $down) {
21686fcafd02SGreg Roach                                /* I18N: %s=“fifth cousin”, etc. */
21696fcafd02SGreg Roach                                return I18N::translate('%s three times removed ascending', self::legacyCousinName($cousin, $sex2));
21706fcafd02SGreg Roach                            }
21716fcafd02SGreg Roach
21726fcafd02SGreg Roach                            /* I18N: %s=“fifth cousin”, etc. */
21736fcafd02SGreg Roach
21746fcafd02SGreg Roach                            return I18N::translate('%s three times removed descending', self::legacyCousinName($cousin, $sex2));
21756fcafd02SGreg Roach                        default:
21766fcafd02SGreg Roach                            if ($up > $down) {
21776fcafd02SGreg Roach                                /* I18N: %1$s=“fifth cousin”, etc., %2$s>=4 */
21786fcafd02SGreg Roach                                return I18N::translate('%1$s %2$s times removed ascending', self::legacyCousinName($cousin, $sex2), I18N::number($removed));
21796fcafd02SGreg Roach                            }
21806fcafd02SGreg Roach
21816fcafd02SGreg Roach                            /* I18N: %1$s=“fifth cousin”, etc., %2$s>=4 */
21826fcafd02SGreg Roach
21836fcafd02SGreg Roach                            return I18N::translate('%1$s %2$s times removed descending', self::legacyCousinName($cousin, $sex2), I18N::number($removed));
21846fcafd02SGreg Roach                    }
21856fcafd02SGreg Roach            }
21866fcafd02SGreg Roach        }
21876fcafd02SGreg Roach
21886fcafd02SGreg Roach        // Split the relationship into sub-relationships, e.g., third-cousin’s great-uncle.
21896fcafd02SGreg Roach        // Try splitting at every point, and choose the path with the shorted translated name.
21906fcafd02SGreg Roach        // But before starting to recursively go through all combinations, do a cache look-up
21916fcafd02SGreg Roach
21926fcafd02SGreg Roach        static $relationshipsCache;
21936fcafd02SGreg Roach        $relationshipsCache ??= [];
21946fcafd02SGreg Roach        if (array_key_exists($path, $relationshipsCache)) {
21956fcafd02SGreg Roach            return $relationshipsCache[$path];
21966fcafd02SGreg Roach        }
21976fcafd02SGreg Roach
219803c56546SGreg Roach        $relationship = '';
21996fcafd02SGreg Roach        $path1        = substr($path, 0, 3);
22006fcafd02SGreg Roach        $path2        = substr($path, 3);
220103c56546SGreg Roach        while ($path2 !== '') {
22026fcafd02SGreg Roach            // I18N: A complex relationship, such as “third-cousin’s great-uncle”
22036fcafd02SGreg Roach            $tmp = I18N::translate(
22046fcafd02SGreg Roach                '%1$s’s %2$s',
22056fcafd02SGreg Roach                $this->legacyNameAlgorithm($path1),
22066fcafd02SGreg Roach                $this->legacyNameAlgorithm($path2)
22076fcafd02SGreg Roach            );
220803c56546SGreg Roach            if ($relationship === '' || strlen($tmp) < strlen($relationship)) {
22096fcafd02SGreg Roach                $relationship = $tmp;
22106fcafd02SGreg Roach            }
22116fcafd02SGreg Roach            $path1 .= substr($path2, 0, 3);
22126fcafd02SGreg Roach            $path2 = substr($path2, 3);
22136fcafd02SGreg Roach        }
22146fcafd02SGreg Roach        // and store the result in the cache
22156fcafd02SGreg Roach        $relationshipsCache[$path] = $relationship;
22166fcafd02SGreg Roach
22176fcafd02SGreg Roach        return $relationship;
22186fcafd02SGreg Roach    }
22196fcafd02SGreg Roach
22206fcafd02SGreg Roach    /**
22216fcafd02SGreg Roach     * Calculate the name of a cousin.
22226fcafd02SGreg Roach     *
22236fcafd02SGreg Roach     * @param int    $n
22246fcafd02SGreg Roach     * @param string $sex
22256fcafd02SGreg Roach     *
22266fcafd02SGreg Roach     * @return string
22276fcafd02SGreg Roach     *
22286fcafd02SGreg Roach     * @deprecated
22296fcafd02SGreg Roach     */
22306fcafd02SGreg Roach    private static function legacyCousinName(int $n, string $sex): string
22316fcafd02SGreg Roach    {
22326fcafd02SGreg Roach        if ($sex === 'M') {
22336fcafd02SGreg Roach            switch ($n) {
22346fcafd02SGreg Roach                case 1:
22356fcafd02SGreg Roach                    /* I18N: Note that for Italian and Polish, “N’th cousins” are different from English “N’th cousins”, and the software has already generated the correct “N” for your language. You only need to translate - you do not need to convert. For other languages, if your cousin rules are different from English, please contact the developers. */
22366fcafd02SGreg Roach                    return I18N::translateContext('MALE', 'first cousin');
22376fcafd02SGreg Roach                case 2:
22386fcafd02SGreg Roach                    /* I18N: Note that for Italian and Polish, “N’th cousins” are different from English “N’th cousins”, and the software has already generated the correct “N” for your language. You only need to translate - you do not need to convert. For other languages, if your cousin rules are different from English, please contact the developers. */
22396fcafd02SGreg Roach                    return I18N::translateContext('MALE', 'second cousin');
22406fcafd02SGreg Roach                case 3:
22416fcafd02SGreg Roach                    /* I18N: Note that for Italian and Polish, “N’th cousins” are different from English “N’th cousins”, and the software has already generated the correct “N” for your language. You only need to translate - you do not need to convert. For other languages, if your cousin rules are different from English, please contact the developers. */
22426fcafd02SGreg Roach                    return I18N::translateContext('MALE', 'third cousin');
22436fcafd02SGreg Roach                case 4:
22446fcafd02SGreg Roach                    /* I18N: Note that for Italian and Polish, “N’th cousins” are different from English “N’th cousins”, and the software has already generated the correct “N” for your language. You only need to translate - you do not need to convert. For other languages, if your cousin rules are different from English, please contact the developers. */
22456fcafd02SGreg Roach                    return I18N::translateContext('MALE', 'fourth cousin');
22466fcafd02SGreg Roach                case 5:
22476fcafd02SGreg Roach                    /* I18N: Note that for Italian and Polish, “N’th cousins” are different from English “N’th cousins”, and the software has already generated the correct “N” for your language. You only need to translate - you do not need to convert. For other languages, if your cousin rules are different from English, please contact the developers. */
22486fcafd02SGreg Roach                    return I18N::translateContext('MALE', 'fifth cousin');
22496fcafd02SGreg Roach                case 6:
22506fcafd02SGreg Roach                    /* I18N: Note that for Italian and Polish, “N’th cousins” are different from English “N’th cousins”, and the software has already generated the correct “N” for your language. You only need to translate - you do not need to convert. For other languages, if your cousin rules are different from English, please contact the developers. */
22516fcafd02SGreg Roach                    return I18N::translateContext('MALE', 'sixth cousin');
22526fcafd02SGreg Roach                case 7:
22536fcafd02SGreg Roach                    /* I18N: Note that for Italian and Polish, “N’th cousins” are different from English “N’th cousins”, and the software has already generated the correct “N” for your language. You only need to translate - you do not need to convert. For other languages, if your cousin rules are different from English, please contact the developers. */
22546fcafd02SGreg Roach                    return I18N::translateContext('MALE', 'seventh cousin');
22556fcafd02SGreg Roach                case 8:
22566fcafd02SGreg Roach                    /* I18N: Note that for Italian and Polish, “N’th cousins” are different from English “N’th cousins”, and the software has already generated the correct “N” for your language. You only need to translate - you do not need to convert. For other languages, if your cousin rules are different from English, please contact the developers. */
22576fcafd02SGreg Roach                    return I18N::translateContext('MALE', 'eighth cousin');
22586fcafd02SGreg Roach                case 9:
22596fcafd02SGreg Roach                    /* I18N: Note that for Italian and Polish, “N’th cousins” are different from English “N’th cousins”, and the software has already generated the correct “N” for your language. You only need to translate - you do not need to convert. For other languages, if your cousin rules are different from English, please contact the developers. */
22606fcafd02SGreg Roach                    return I18N::translateContext('MALE', 'ninth cousin');
22616fcafd02SGreg Roach                case 10:
22626fcafd02SGreg Roach                    /* I18N: Note that for Italian and Polish, “N’th cousins” are different from English “N’th cousins”, and the software has already generated the correct “N” for your language. You only need to translate - you do not need to convert. For other languages, if your cousin rules are different from English, please contact the developers. */
22636fcafd02SGreg Roach                    return I18N::translateContext('MALE', 'tenth cousin');
22646fcafd02SGreg Roach                case 11:
22656fcafd02SGreg Roach                    /* I18N: Note that for Italian and Polish, “N’th cousins” are different from English “N’th cousins”, and the software has already generated the correct “N” for your language. You only need to translate - you do not need to convert. For other languages, if your cousin rules are different from English, please contact the developers. */
22666fcafd02SGreg Roach                    return I18N::translateContext('MALE', 'eleventh cousin');
22676fcafd02SGreg Roach                case 12:
22686fcafd02SGreg Roach                    /* I18N: Note that for Italian and Polish, “N’th cousins” are different from English “N’th cousins”, and the software has already generated the correct “N” for your language. You only need to translate - you do not need to convert. For other languages, if your cousin rules are different from English, please contact the developers. */
22696fcafd02SGreg Roach                    return I18N::translateContext('MALE', 'twelfth cousin');
22706fcafd02SGreg Roach                case 13:
22716fcafd02SGreg Roach                    /* I18N: Note that for Italian and Polish, “N’th cousins” are different from English “N’th cousins”, and the software has already generated the correct “N” for your language. You only need to translate - you do not need to convert. For other languages, if your cousin rules are different from English, please contact the developers. */
22726fcafd02SGreg Roach                    return I18N::translateContext('MALE', 'thirteenth cousin');
22736fcafd02SGreg Roach                case 14:
22746fcafd02SGreg Roach                    /* I18N: Note that for Italian and Polish, “N’th cousins” are different from English “N’th cousins”, and the software has already generated the correct “N” for your language. You only need to translate - you do not need to convert. For other languages, if your cousin rules are different from English, please contact the developers. */
22756fcafd02SGreg Roach                    return I18N::translateContext('MALE', 'fourteenth cousin');
22766fcafd02SGreg Roach                case 15:
22776fcafd02SGreg Roach                    /* I18N: Note that for Italian and Polish, “N’th cousins” are different from English “N’th cousins”, and the software has already generated the correct “N” for your language. You only need to translate - you do not need to convert. For other languages, if your cousin rules are different from English, please contact the developers. */
22786fcafd02SGreg Roach                    return I18N::translateContext('MALE', 'fifteenth cousin');
22796fcafd02SGreg Roach                default:
22806fcafd02SGreg Roach                    /* I18N: Note that for Italian and Polish, “N’th cousins” are different from English “N’th cousins”, and the software has already generated the correct “N” for your language. You only need to translate - you do not need to convert. For other languages, if your cousin rules are different from English, please contact the developers. */
22816fcafd02SGreg Roach                    return I18N::translateContext('MALE', '%s × cousin', I18N::number($n));
22826fcafd02SGreg Roach            }
22836fcafd02SGreg Roach        }
22846fcafd02SGreg Roach
22856fcafd02SGreg Roach        if ($sex === 'F') {
22866fcafd02SGreg Roach            switch ($n) {
22876fcafd02SGreg Roach                case 1:
22886fcafd02SGreg Roach                    return I18N::translateContext('FEMALE', 'first cousin');
22896fcafd02SGreg Roach                case 2:
22906fcafd02SGreg Roach                    return I18N::translateContext('FEMALE', 'second cousin');
22916fcafd02SGreg Roach                case 3:
22926fcafd02SGreg Roach                    return I18N::translateContext('FEMALE', 'third cousin');
22936fcafd02SGreg Roach                case 4:
22946fcafd02SGreg Roach                    return I18N::translateContext('FEMALE', 'fourth cousin');
22956fcafd02SGreg Roach                case 5:
22966fcafd02SGreg Roach                    return I18N::translateContext('FEMALE', 'fifth cousin');
22976fcafd02SGreg Roach                case 6:
22986fcafd02SGreg Roach                    return I18N::translateContext('FEMALE', 'sixth cousin');
22996fcafd02SGreg Roach                case 7:
23006fcafd02SGreg Roach                    return I18N::translateContext('FEMALE', 'seventh cousin');
23016fcafd02SGreg Roach                case 8:
23026fcafd02SGreg Roach                    return I18N::translateContext('FEMALE', 'eighth cousin');
23036fcafd02SGreg Roach                case 9:
23046fcafd02SGreg Roach                    return I18N::translateContext('FEMALE', 'ninth cousin');
23056fcafd02SGreg Roach                case 10:
23066fcafd02SGreg Roach                    return I18N::translateContext('FEMALE', 'tenth cousin');
23076fcafd02SGreg Roach                case 11:
23086fcafd02SGreg Roach                    return I18N::translateContext('FEMALE', 'eleventh cousin');
23096fcafd02SGreg Roach                case 12:
23106fcafd02SGreg Roach                    return I18N::translateContext('FEMALE', 'twelfth cousin');
23116fcafd02SGreg Roach                case 13:
23126fcafd02SGreg Roach                    return I18N::translateContext('FEMALE', 'thirteenth cousin');
23136fcafd02SGreg Roach                case 14:
23146fcafd02SGreg Roach                    return I18N::translateContext('FEMALE', 'fourteenth cousin');
23156fcafd02SGreg Roach                case 15:
23166fcafd02SGreg Roach                    return I18N::translateContext('FEMALE', 'fifteenth cousin');
23176fcafd02SGreg Roach                default:
23186fcafd02SGreg Roach                    return I18N::translateContext('FEMALE', '%s × cousin', I18N::number($n));
23196fcafd02SGreg Roach            }
23206fcafd02SGreg Roach        }
23216fcafd02SGreg Roach
23226fcafd02SGreg Roach        switch ($n) {
23236fcafd02SGreg Roach            case 1:
23246fcafd02SGreg Roach                return I18N::translate('first cousin');
23256fcafd02SGreg Roach            case 2:
23266fcafd02SGreg Roach                return I18N::translate('second cousin');
23276fcafd02SGreg Roach            case 3:
23286fcafd02SGreg Roach                return I18N::translate('third cousin');
23296fcafd02SGreg Roach            case 4:
23306fcafd02SGreg Roach                return I18N::translate('fourth cousin');
23316fcafd02SGreg Roach            case 5:
23326fcafd02SGreg Roach                return I18N::translate('fifth cousin');
23336fcafd02SGreg Roach            case 6:
23346fcafd02SGreg Roach                return I18N::translate('sixth cousin');
23356fcafd02SGreg Roach            case 7:
23366fcafd02SGreg Roach                return I18N::translate('seventh cousin');
23376fcafd02SGreg Roach            case 8:
23386fcafd02SGreg Roach                return I18N::translate('eighth cousin');
23396fcafd02SGreg Roach            case 9:
23406fcafd02SGreg Roach                return I18N::translate('ninth cousin');
23416fcafd02SGreg Roach            case 10:
23426fcafd02SGreg Roach                return I18N::translate('tenth cousin');
23436fcafd02SGreg Roach            case 11:
23446fcafd02SGreg Roach                return I18N::translate('eleventh cousin');
23456fcafd02SGreg Roach            case 12:
23466fcafd02SGreg Roach                return I18N::translate('twelfth cousin');
23476fcafd02SGreg Roach            case 13:
23486fcafd02SGreg Roach                return I18N::translate('thirteenth cousin');
23496fcafd02SGreg Roach            case 14:
23506fcafd02SGreg Roach                return I18N::translate('fourteenth cousin');
23516fcafd02SGreg Roach            case 15:
23526fcafd02SGreg Roach                return I18N::translate('fifteenth cousin');
23536fcafd02SGreg Roach            default:
23546fcafd02SGreg Roach                return I18N::translate('%s × cousin', I18N::number($n));
23556fcafd02SGreg Roach        }
23566fcafd02SGreg Roach    }
23576fcafd02SGreg Roach
23586fcafd02SGreg Roach    /**
23596fcafd02SGreg Roach     * A variation on cousin_name(), for constructs such as “sixth great-nephew”
23606fcafd02SGreg Roach     * Currently used only by Spanish relationship names.
23616fcafd02SGreg Roach     *
23626fcafd02SGreg Roach     * @param int    $n
23636fcafd02SGreg Roach     * @param string $sex
23646fcafd02SGreg Roach     * @param string $relation
23656fcafd02SGreg Roach     *
23666fcafd02SGreg Roach     * @return string
23676fcafd02SGreg Roach     *
23686fcafd02SGreg Roach     * @deprecated
23696fcafd02SGreg Roach     */
23706fcafd02SGreg Roach    private static function legacyCousinName2(int $n, string $sex, string $relation): string
23716fcafd02SGreg Roach    {
23726fcafd02SGreg Roach        if ($sex === 'M') {
23736fcafd02SGreg Roach            switch ($n) {
23746fcafd02SGreg Roach                case 1:
23756fcafd02SGreg Roach                    /* I18N: A Spanish relationship name, such as third great-nephew */
23766fcafd02SGreg Roach                    return I18N::translateContext('MALE', 'first %s', $relation);
23776fcafd02SGreg Roach                case 2:
23786fcafd02SGreg Roach                    /* I18N: A Spanish relationship name, such as third great-nephew */
23796fcafd02SGreg Roach                    return I18N::translateContext('MALE', 'second %s', $relation);
23806fcafd02SGreg Roach                case 3:
23816fcafd02SGreg Roach                    /* I18N: A Spanish relationship name, such as third great-nephew */
23826fcafd02SGreg Roach                    return I18N::translateContext('MALE', 'third %s', $relation);
23836fcafd02SGreg Roach                case 4:
23846fcafd02SGreg Roach                    /* I18N: A Spanish relationship name, such as third great-nephew */
23856fcafd02SGreg Roach                    return I18N::translateContext('MALE', 'fourth %s', $relation);
23866fcafd02SGreg Roach                case 5:
23876fcafd02SGreg Roach                    /* I18N: A Spanish relationship name, such as third great-nephew */
23886fcafd02SGreg Roach                    return I18N::translateContext('MALE', 'fifth %s', $relation);
23896fcafd02SGreg Roach                default:
23906fcafd02SGreg Roach                    /* I18N: A Spanish relationship name, such as third great-nephew */
23916fcafd02SGreg Roach                    return I18N::translateContext('MALE', '%1$s × %2$s', I18N::number($n), $relation);
23926fcafd02SGreg Roach            }
23936fcafd02SGreg Roach        }
23946fcafd02SGreg Roach
23956fcafd02SGreg Roach        if ($sex === 'F') {
23966fcafd02SGreg Roach            switch ($n) {
23976fcafd02SGreg Roach                case 1:
23986fcafd02SGreg Roach                    /* I18N: A Spanish relationship name, such as third great-nephew */
23996fcafd02SGreg Roach                    return I18N::translateContext('FEMALE', 'first %s', $relation);
24006fcafd02SGreg Roach                case 2:
24016fcafd02SGreg Roach                    /* I18N: A Spanish relationship name, such as third great-nephew */
24026fcafd02SGreg Roach                    return I18N::translateContext('FEMALE', 'second %s', $relation);
24036fcafd02SGreg Roach                case 3:
24046fcafd02SGreg Roach                    /* I18N: A Spanish relationship name, such as third great-nephew */
24056fcafd02SGreg Roach                    return I18N::translateContext('FEMALE', 'third %s', $relation);
24066fcafd02SGreg Roach                case 4:
24076fcafd02SGreg Roach                    /* I18N: A Spanish relationship name, such as third great-nephew */
24086fcafd02SGreg Roach                    return I18N::translateContext('FEMALE', 'fourth %s', $relation);
24096fcafd02SGreg Roach                case 5:
24106fcafd02SGreg Roach                    /* I18N: A Spanish relationship name, such as third great-nephew */
24116fcafd02SGreg Roach                    return I18N::translateContext('FEMALE', 'fifth %s', $relation);
24126fcafd02SGreg Roach                default:
24136fcafd02SGreg Roach                    /* I18N: A Spanish relationship name, such as third great-nephew */
24146fcafd02SGreg Roach                    return I18N::translateContext('FEMALE', '%1$s × %2$s', I18N::number($n), $relation);
24156fcafd02SGreg Roach            }
24166fcafd02SGreg Roach        }
24176fcafd02SGreg Roach
24186fcafd02SGreg Roach        switch ($n) {
24196fcafd02SGreg Roach            case 1:
24206fcafd02SGreg Roach                /* I18N: A Spanish relationship name, such as third great-nephew */
24216fcafd02SGreg Roach                return I18N::translate('first %s', $relation);
24226fcafd02SGreg Roach            case 2:
24236fcafd02SGreg Roach                /* I18N: A Spanish relationship name, such as third great-nephew */
24246fcafd02SGreg Roach                return I18N::translate('second %s', $relation);
24256fcafd02SGreg Roach            case 3:
24266fcafd02SGreg Roach                /* I18N: A Spanish relationship name, such as third great-nephew */
24276fcafd02SGreg Roach                return I18N::translate('third %s', $relation);
24286fcafd02SGreg Roach            case 4:
24296fcafd02SGreg Roach                /* I18N: A Spanish relationship name, such as third great-nephew */
24306fcafd02SGreg Roach                return I18N::translate('fourth %s', $relation);
24316fcafd02SGreg Roach            case 5:
24326fcafd02SGreg Roach                /* I18N: A Spanish relationship name, such as third great-nephew */
24336fcafd02SGreg Roach                return I18N::translate('fifth %s', $relation);
24346fcafd02SGreg Roach            default:
24356fcafd02SGreg Roach                /* I18N: A Spanish relationship name, such as third great-nephew */
24366fcafd02SGreg Roach                return I18N::translate('%1$s × %2$s', I18N::number($n), $relation);
24376fcafd02SGreg Roach        }
24386fcafd02SGreg Roach    }
24396fcafd02SGreg Roach}
2440