xref: /webtrees/app/Statistics.php (revision 945057ae27f0640a8c2c773443dca9f2cb0bf56c)
1<?php
2/**
3 * webtrees: online genealogy
4 * Copyright (C) 2019 webtrees development team
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16declare(strict_types=1);
17
18namespace Fisharebest\Webtrees;
19
20use Fisharebest\Webtrees\Module\ModuleBlockInterface;
21use Fisharebest\Webtrees\Module\ModuleInterface;
22use Fisharebest\Webtrees\Services\ModuleService;
23use Fisharebest\Webtrees\Services\UserService;
24use Fisharebest\Webtrees\Statistics\Repository\BrowserRepository;
25use Fisharebest\Webtrees\Statistics\Repository\ContactRepository;
26use Fisharebest\Webtrees\Statistics\Repository\EventRepository;
27use Fisharebest\Webtrees\Statistics\Repository\FamilyDatesRepository;
28use Fisharebest\Webtrees\Statistics\Repository\FamilyRepository;
29use Fisharebest\Webtrees\Statistics\Repository\FavoritesRepository;
30use Fisharebest\Webtrees\Statistics\Repository\GedcomRepository;
31use Fisharebest\Webtrees\Statistics\Repository\HitCountRepository;
32use Fisharebest\Webtrees\Statistics\Repository\IndividualRepository;
33use Fisharebest\Webtrees\Statistics\Repository\Interfaces\BrowserRepositoryInterface;
34use Fisharebest\Webtrees\Statistics\Repository\Interfaces\ContactRepositoryInterface;
35use Fisharebest\Webtrees\Statistics\Repository\Interfaces\EventRepositoryInterface;
36use Fisharebest\Webtrees\Statistics\Repository\Interfaces\FamilyDatesRepositoryInterface;
37use Fisharebest\Webtrees\Statistics\Repository\Interfaces\FavoritesRepositoryInterface;
38use Fisharebest\Webtrees\Statistics\Repository\Interfaces\GedcomRepositoryInterface;
39use Fisharebest\Webtrees\Statistics\Repository\Interfaces\HitCountRepositoryInterface;
40use Fisharebest\Webtrees\Statistics\Repository\Interfaces\IndividualRepositoryInterface;
41use Fisharebest\Webtrees\Statistics\Repository\Interfaces\LatestUserRepositoryInterface;
42use Fisharebest\Webtrees\Statistics\Repository\Interfaces\MediaRepositoryInterface;
43use Fisharebest\Webtrees\Statistics\Repository\Interfaces\MessageRepositoryInterface;
44use Fisharebest\Webtrees\Statistics\Repository\Interfaces\NewsRepositoryInterface;
45use Fisharebest\Webtrees\Statistics\Repository\Interfaces\PlaceRepositoryInterface;
46use Fisharebest\Webtrees\Statistics\Repository\Interfaces\ServerRepositoryInterface;
47use Fisharebest\Webtrees\Statistics\Repository\Interfaces\UserRepositoryInterface;
48use Fisharebest\Webtrees\Statistics\Repository\LatestUserRepository;
49use Fisharebest\Webtrees\Statistics\Repository\MediaRepository;
50use Fisharebest\Webtrees\Statistics\Repository\MessageRepository;
51use Fisharebest\Webtrees\Statistics\Repository\NewsRepository;
52use Fisharebest\Webtrees\Statistics\Repository\PlaceRepository;
53use Fisharebest\Webtrees\Statistics\Repository\ServerRepository;
54use Fisharebest\Webtrees\Statistics\Repository\UserRepository;
55use Illuminate\Database\Query\Builder;
56use ReflectionMethod;
57
58/**
59 * A selection of pre-formatted statistical queries.
60 * These are primarily used for embedded keywords on HTML blocks, but
61 * are also used elsewhere in the code.
62 */
63class Statistics implements
64    GedcomRepositoryInterface,
65    IndividualRepositoryInterface,
66    EventRepositoryInterface,
67    MediaRepositoryInterface,
68    UserRepositoryInterface,
69    ServerRepositoryInterface,
70    BrowserRepositoryInterface,
71    HitCountRepositoryInterface,
72    LatestUserRepositoryInterface,
73    FavoritesRepositoryInterface,
74    NewsRepositoryInterface,
75    MessageRepositoryInterface,
76    ContactRepositoryInterface,
77    FamilyDatesRepositoryInterface,
78    PlaceRepositoryInterface
79{
80    /**
81     * Generate statistics for a specified tree.
82     *
83     * @var Tree
84     */
85    private $tree;
86
87    /**
88     * All public functions are available as keywords - except these ones
89     *
90     * @var string[]
91     */
92    private static $public_but_not_allowed = [
93        '__construct',
94        'embedTags',
95        'iso3166',
96        'getAllCountries',
97        'getAllTagsTable',
98        'getAllTagsText',
99        'statsPlaces',
100        'statsAgeQuery',
101        'monthFirstChildQuery',
102        'statsChildrenQuery',
103        'statsMarrAgeQuery',
104    ];
105
106    /**
107     * @var GedcomRepository
108     */
109    private $gedcomRepository;
110
111    /**
112     * @var IndividualRepository
113     */
114    private $individualRepository;
115
116    /**
117     * @var FamilyRepository
118     */
119    private $familyRepository;
120
121    /**
122     * @var MediaRepository
123     */
124    private $mediaRepository;
125
126    /**
127     * @var EventRepository
128     */
129    private $eventRepository;
130
131    /**
132     * @var UserRepository
133     */
134    private $userRepository;
135
136    /**
137     * @var ServerRepository
138     */
139    private $serverRepository;
140
141    /**
142     * @var BrowserRepository
143     */
144    private $browserRepository;
145
146    /**
147     * @var HitCountRepository
148     */
149    private $hitCountRepository;
150
151    /**
152     * @var LatestUserRepository
153     */
154    private $latestUserRepository;
155
156    /**
157     * @var FavoritesRepository
158     */
159    private $favoritesRepository;
160
161    /**
162     * @var NewsRepository
163     */
164    private $newsRepository;
165
166    /**
167     * @var MessageRepository
168     */
169    private $messageRepository;
170
171    /**
172     * @var ContactRepository
173     */
174    private $contactRepository;
175
176    /**
177     * @var FamilyDatesRepository
178     */
179    private $familyDatesRepository;
180
181    /**
182     * @var PlaceRepository
183     */
184    private $placeRepository;
185
186    /**
187     * @var ModuleService
188     */
189    private $module_service;
190
191    /**
192     * Create the statistics for a tree.
193     *
194     * @param ModuleService $module_service
195     * @param Tree          $tree Generate statistics for this tree
196     * @param UserService   $user_service
197     */
198    public function __construct(
199        ModuleService $module_service,
200        Tree $tree,
201        UserService $user_service
202    ) {
203        $this->tree                  = $tree;
204        $this->gedcomRepository      = new GedcomRepository($tree);
205        $this->individualRepository  = new IndividualRepository($tree);
206        $this->familyRepository      = new FamilyRepository($tree);
207        $this->familyDatesRepository = new FamilyDatesRepository($tree);
208        $this->mediaRepository       = new MediaRepository($tree);
209        $this->eventRepository       = new EventRepository($tree);
210        $this->userRepository        = new UserRepository($tree, $user_service);
211        $this->serverRepository      = new ServerRepository();
212        $this->browserRepository     = new BrowserRepository();
213        $this->hitCountRepository    = new HitCountRepository($tree, $user_service);
214        $this->latestUserRepository  = new LatestUserRepository($user_service);
215        $this->favoritesRepository   = new FavoritesRepository($tree, $module_service);
216        $this->newsRepository        = new NewsRepository($tree);
217        $this->messageRepository     = new MessageRepository();
218        $this->contactRepository     = new ContactRepository($tree, $user_service);
219        $this->placeRepository       = new PlaceRepository($tree);
220        $this->module_service        = $module_service;
221    }
222
223    /**
224     * Return a string of all supported tags and an example of its output in table row form.
225     *
226     * @return string
227     */
228    public function getAllTagsTable(): string
229    {
230        $examples = [];
231
232        foreach (get_class_methods($this) as $method) {
233            $reflection = new ReflectionMethod($this, $method);
234            if ($reflection->isPublic() && !\in_array($method, self::$public_but_not_allowed, true) && (string) $reflection->getReturnType() !== Builder::class) {
235                $examples[$method] = $this->$method();
236            }
237        }
238
239        ksort($examples);
240
241        $html = '';
242        foreach ($examples as $tag => $value) {
243            $html .= '<dt>#' . $tag . '#</dt>';
244            $html .= '<dd>' . $value . '</dd>';
245        }
246
247        return '<dl>' . $html . '</dl>';
248    }
249
250    /**
251     * Return a string of all supported tags in plain text.
252     *
253     * @return string
254     */
255    public function getAllTagsText(): string
256    {
257        $examples = [];
258
259        foreach (get_class_methods($this) as $method) {
260            $reflection = new ReflectionMethod($this, $method);
261            if ($reflection->isPublic() && !\in_array($method, self::$public_but_not_allowed, true) && (string) $reflection->getReturnType() !== Builder::class) {
262                $examples[$method] = $method;
263            }
264        }
265
266        ksort($examples);
267
268        return implode('<br>', $examples);
269    }
270
271    /**
272     * Get tags and their parsed results.
273     *
274     * @param string $text
275     *
276     * @return string[]
277     */
278    private function getTags(string $text): array
279    {
280        $tags    = [];
281        $matches = [];
282
283        preg_match_all('/#([^#]+)#/', $text, $matches, PREG_SET_ORDER);
284
285        foreach ($matches as $match) {
286            $params = explode(':', $match[1]);
287            $method = array_shift($params);
288
289            if (method_exists($this, $method)) {
290                $tags[$match[0]] = $this->$method(...$params);
291            }
292        }
293
294        return $tags;
295    }
296
297    /**
298     * Embed tags in text
299     *
300     * @param string $text
301     *
302     * @return string
303     */
304    public function embedTags(string $text): string
305    {
306        if (strpos($text, '#') !== false) {
307            $text = strtr($text, $this->getTags($text));
308        }
309
310        return $text;
311    }
312
313    /**
314     * @inheritDoc
315     */
316    public function gedcomFilename(): string
317    {
318        return $this->gedcomRepository->gedcomFilename();
319    }
320
321    /**
322     * @inheritDoc
323     */
324    public function gedcomId(): int
325    {
326        return $this->gedcomRepository->gedcomId();
327    }
328
329    /**
330     * @inheritDoc
331     */
332    public function gedcomTitle(): string
333    {
334        return $this->gedcomRepository->gedcomTitle();
335    }
336
337    /**
338     * @inheritDoc
339     */
340    public function gedcomCreatedSoftware(): string
341    {
342        return $this->gedcomRepository->gedcomCreatedSoftware();
343    }
344
345    /**
346     * @inheritDoc
347     */
348    public function gedcomCreatedVersion(): string
349    {
350        return $this->gedcomRepository->gedcomCreatedVersion();
351    }
352
353    /**
354     * @inheritDoc
355     */
356    public function gedcomDate(): string
357    {
358        return $this->gedcomRepository->gedcomDate();
359    }
360
361    /**
362     * @inheritDoc
363     */
364    public function gedcomUpdated(): string
365    {
366        return $this->gedcomRepository->gedcomUpdated();
367    }
368
369    /**
370     * @inheritDoc
371     */
372    public function gedcomRootId(): string
373    {
374        return $this->gedcomRepository->gedcomRootId();
375    }
376
377    /**
378     * @inheritDoc
379     */
380    public function totalRecords(): string
381    {
382        return $this->individualRepository->totalRecords();
383    }
384
385    /**
386     * @inheritDoc
387     */
388    public function totalIndividuals(): string
389    {
390        return $this->individualRepository->totalIndividuals();
391    }
392
393    /**
394     * @inheritDoc
395     */
396    public function totalIndisWithSources(): string
397    {
398        return $this->individualRepository->totalIndisWithSources();
399    }
400
401    /**
402     * @inheritDoc
403     */
404    public function chartIndisWithSources(
405        string $color_from = null,
406        string $color_to = null
407    ): string {
408        return $this->individualRepository->chartIndisWithSources($color_from, $color_to);
409    }
410
411    /**
412     * @inheritDoc
413     */
414    public function totalIndividualsPercentage(): string
415    {
416        return $this->individualRepository->totalIndividualsPercentage();
417    }
418
419    /**
420     * @inheritDoc
421     */
422    public function totalFamilies(): string
423    {
424        return $this->individualRepository->totalFamilies();
425    }
426
427    /**
428     * @inheritDoc
429     */
430    public function totalFamiliesPercentage(): string
431    {
432        return $this->individualRepository->totalFamiliesPercentage();
433    }
434
435    /**
436     * @inheritDoc
437     */
438    public function totalFamsWithSources(): string
439    {
440        return $this->individualRepository->totalFamsWithSources();
441    }
442
443    /**
444     * @inheritDoc
445     */
446    public function chartFamsWithSources(
447        string $color_from = null,
448        string $color_to = null
449    ): string {
450        return $this->individualRepository->chartFamsWithSources($color_from, $color_to);
451    }
452
453    /**
454     * @inheritDoc
455     */
456    public function totalSources(): string
457    {
458        return $this->individualRepository->totalSources();
459    }
460
461    /**
462     * @inheritDoc
463     */
464    public function totalSourcesPercentage(): string
465    {
466        return $this->individualRepository->totalSourcesPercentage();
467    }
468
469    /**
470     * @inheritDoc
471     */
472    public function totalNotes(): string
473    {
474        return $this->individualRepository->totalNotes();
475    }
476
477    /**
478     * @inheritDoc
479     */
480    public function totalNotesPercentage(): string
481    {
482        return $this->individualRepository->totalNotesPercentage();
483    }
484
485    /**
486     * @inheritDoc
487     */
488    public function totalRepositories(): string
489    {
490        return $this->individualRepository->totalRepositories();
491    }
492
493    /**
494     * @inheritDoc
495     */
496    public function totalRepositoriesPercentage(): string
497    {
498        return $this->individualRepository->totalRepositoriesPercentage();
499    }
500
501    /**
502     * @inheritDoc
503     */
504    public function totalSurnames(...$params): string
505    {
506        return $this->individualRepository->totalSurnames(...$params);
507    }
508
509    /**
510     * @inheritDoc
511     */
512    public function totalGivennames(...$params): string
513    {
514        return $this->individualRepository->totalGivennames(...$params);
515    }
516
517    /**
518     * @inheritDoc
519     */
520    public function totalEvents(array $events = []): string
521    {
522        return $this->eventRepository->totalEvents($events);
523    }
524
525    /**
526     * @inheritDoc
527     */
528    public function totalEventsBirth(): string
529    {
530        return $this->eventRepository->totalEventsBirth();
531    }
532
533    /**
534     * @inheritDoc
535     */
536    public function totalBirths(): string
537    {
538        return $this->eventRepository->totalBirths();
539    }
540
541    /**
542     * @inheritDoc
543     */
544    public function totalEventsDeath(): string
545    {
546        return $this->eventRepository->totalEventsDeath();
547    }
548
549    /**
550     * @inheritDoc
551     */
552    public function totalDeaths(): string
553    {
554        return $this->eventRepository->totalDeaths();
555    }
556
557    /**
558     * @inheritDoc
559     */
560    public function totalEventsMarriage(): string
561    {
562        return $this->eventRepository->totalEventsMarriage();
563    }
564
565    /**
566     * @inheritDoc
567     */
568    public function totalMarriages(): string
569    {
570        return $this->eventRepository->totalMarriages();
571    }
572
573    /**
574     * @inheritDoc
575     */
576    public function totalEventsDivorce(): string
577    {
578        return $this->eventRepository->totalEventsDivorce();
579    }
580
581    /**
582     * @inheritDoc
583     */
584    public function totalDivorces(): string
585    {
586        return $this->eventRepository->totalDivorces();
587    }
588
589    /**
590     * @inheritDoc
591     */
592    public function totalEventsOther(): string
593    {
594        return $this->eventRepository->totalEventsOther();
595    }
596
597    /**
598     * @inheritDoc
599     */
600    public function totalSexMales(): string
601    {
602        return $this->individualRepository->totalSexMales();
603    }
604
605    /**
606     * @inheritDoc
607     */
608    public function totalSexMalesPercentage(): string
609    {
610        return $this->individualRepository->totalSexMalesPercentage();
611    }
612
613    /**
614     * @inheritDoc
615     */
616    public function totalSexFemales(): string
617    {
618        return $this->individualRepository->totalSexFemales();
619    }
620
621    /**
622     * @inheritDoc
623     */
624    public function totalSexFemalesPercentage(): string
625    {
626        return $this->individualRepository->totalSexFemalesPercentage();
627    }
628
629    /**
630     * @inheritDoc
631     */
632    public function totalSexUnknown(): string
633    {
634        return $this->individualRepository->totalSexUnknown();
635    }
636
637    /**
638     * @inheritDoc
639     */
640    public function totalSexUnknownPercentage(): string
641    {
642        return $this->individualRepository->totalSexUnknownPercentage();
643    }
644
645    /**
646     * @inheritDoc
647     */
648    public function chartSex(
649        string $color_female = null,
650        string $color_male = null,
651        string $color_unknown = null
652    ): string {
653        return $this->individualRepository->chartSex($color_female, $color_male, $color_unknown);
654    }
655
656    /**
657     * @inheritDoc
658     */
659    public function totalLiving(): string
660    {
661        return $this->individualRepository->totalLiving();
662    }
663
664    /**
665     * @inheritDoc
666     */
667    public function totalLivingPercentage(): string
668    {
669        return $this->individualRepository->totalLivingPercentage();
670    }
671
672    /**
673     * @inheritDoc
674     */
675    public function totalDeceased(): string
676    {
677        return $this->individualRepository->totalDeceased();
678    }
679
680    /**
681     * @inheritDoc
682     */
683    public function totalDeceasedPercentage(): string
684    {
685        return $this->individualRepository->totalDeceasedPercentage();
686    }
687
688    /**
689     * @inheritDoc
690     */
691    public function chartMortality(string $color_living = null, string $color_dead = null): string
692    {
693        return $this->individualRepository->chartMortality($color_living, $color_dead);
694    }
695
696    /**
697     * @inheritDoc
698     */
699    public function totalMedia(): string
700    {
701        return $this->mediaRepository->totalMedia();
702    }
703
704    /**
705     * @inheritDoc
706     */
707    public function totalMediaAudio(): string
708    {
709        return $this->mediaRepository->totalMediaAudio();
710    }
711
712    /**
713     * @inheritDoc
714     */
715    public function totalMediaBook(): string
716    {
717        return $this->mediaRepository->totalMediaBook();
718    }
719
720    /**
721     * @inheritDoc
722     */
723    public function totalMediaCard(): string
724    {
725        return $this->mediaRepository->totalMediaCard();
726    }
727
728    /**
729     * @inheritDoc
730     */
731    public function totalMediaCertificate(): string
732    {
733        return $this->mediaRepository->totalMediaCertificate();
734    }
735
736    /**
737     * @inheritDoc
738     */
739    public function totalMediaCoatOfArms(): string
740    {
741        return $this->mediaRepository->totalMediaCoatOfArms();
742    }
743
744    /**
745     * @inheritDoc
746     */
747    public function totalMediaDocument(): string
748    {
749        return $this->mediaRepository->totalMediaDocument();
750    }
751
752    /**
753     * @inheritDoc
754     */
755    public function totalMediaElectronic(): string
756    {
757        return $this->mediaRepository->totalMediaElectronic();
758    }
759
760    /**
761     * @inheritDoc
762     */
763    public function totalMediaMagazine(): string
764    {
765        return $this->mediaRepository->totalMediaMagazine();
766    }
767
768    /**
769     * @inheritDoc
770     */
771    public function totalMediaManuscript(): string
772    {
773        return $this->mediaRepository->totalMediaManuscript();
774    }
775
776    /**
777     * @inheritDoc
778     */
779    public function totalMediaMap(): string
780    {
781        return $this->mediaRepository->totalMediaMap();
782    }
783
784    /**
785     * @inheritDoc
786     */
787    public function totalMediaFiche(): string
788    {
789        return $this->mediaRepository->totalMediaFiche();
790    }
791
792    /**
793     * @inheritDoc
794     */
795    public function totalMediaFilm(): string
796    {
797        return $this->mediaRepository->totalMediaFilm();
798    }
799
800    /**
801     * @inheritDoc
802     */
803    public function totalMediaNewspaper(): string
804    {
805        return $this->mediaRepository->totalMediaNewspaper();
806    }
807
808    /**
809     * @inheritDoc
810     */
811    public function totalMediaPainting(): string
812    {
813        return $this->mediaRepository->totalMediaPainting();
814    }
815
816    /**
817     * @inheritDoc
818     */
819    public function totalMediaPhoto(): string
820    {
821        return $this->mediaRepository->totalMediaPhoto();
822    }
823
824    /**
825     * @inheritDoc
826     */
827    public function totalMediaTombstone(): string
828    {
829        return $this->mediaRepository->totalMediaTombstone();
830    }
831
832    /**
833     * @inheritDoc
834     */
835    public function totalMediaVideo(): string
836    {
837        return $this->mediaRepository->totalMediaVideo();
838    }
839
840    /**
841     * @inheritDoc
842     */
843    public function totalMediaOther(): string
844    {
845        return $this->mediaRepository->totalMediaOther();
846    }
847
848    /**
849     * @inheritDoc
850     */
851    public function totalMediaUnknown(): string
852    {
853        return $this->mediaRepository->totalMediaUnknown();
854    }
855
856    /**
857     * @inheritDoc
858     */
859    public function chartMedia(string $color_from = null, string $color_to = null): string
860    {
861        return $this->mediaRepository->chartMedia($color_from, $color_to);
862    }
863
864    /**
865     * @inheritDoc
866     */
867    public function statsPlaces(string $what = 'ALL', string $fact = '', int $parent = 0, bool $country = false): array
868    {
869        return $this->placeRepository->statsPlaces($what, $fact, $parent, $country);
870    }
871
872    /**
873     * @inheritDoc
874     */
875    public function totalPlaces(): string
876    {
877        return $this->placeRepository->totalPlaces();
878    }
879
880    /**
881     * @inheritDoc
882     */
883    public function chartDistribution(
884        string $chart_shows = 'world',
885        string $chart_type = '',
886        string $surname = ''
887    ): string {
888        return $this->placeRepository->chartDistribution($chart_shows, $chart_type, $surname);
889    }
890
891    /**
892     * @inheritDoc
893     */
894    public function commonCountriesList(): string
895    {
896        return $this->placeRepository->commonCountriesList();
897    }
898
899    /**
900     * @inheritDoc
901     */
902    public function commonBirthPlacesList(): string
903    {
904        return $this->placeRepository->commonBirthPlacesList();
905    }
906
907    /**
908     * @inheritDoc
909     */
910    public function commonDeathPlacesList(): string
911    {
912        return $this->placeRepository->commonDeathPlacesList();
913    }
914
915    /**
916     * @inheritDoc
917     */
918    public function commonMarriagePlacesList(): string
919    {
920        return $this->placeRepository->commonMarriagePlacesList();
921    }
922
923    /**
924     * @inheritDoc
925     */
926    public function firstBirth(): string
927    {
928        return $this->familyDatesRepository->firstBirth();
929    }
930
931    /**
932     * @inheritDoc
933     */
934    public function firstBirthYear(): string
935    {
936        return $this->familyDatesRepository->firstBirthYear();
937    }
938
939    /**
940     * @inheritDoc
941     */
942    public function firstBirthName(): string
943    {
944        return $this->familyDatesRepository->firstBirthName();
945    }
946
947    /**
948     * @inheritDoc
949     */
950    public function firstBirthPlace(): string
951    {
952        return $this->familyDatesRepository->firstBirthPlace();
953    }
954
955    /**
956     * @inheritDoc
957     */
958    public function lastBirth(): string
959    {
960        return $this->familyDatesRepository->lastBirth();
961    }
962
963    /**
964     * @inheritDoc
965     */
966    public function lastBirthYear(): string
967    {
968        return $this->familyDatesRepository->lastBirthYear();
969    }
970
971    /**
972     * @inheritDoc
973     */
974    public function lastBirthName(): string
975    {
976        return $this->familyDatesRepository->lastBirthName();
977    }
978
979    /**
980     * @inheritDoc
981     */
982    public function lastBirthPlace(): string
983    {
984        return $this->familyDatesRepository->lastBirthPlace();
985    }
986
987    /**
988     * @inheritDoc
989     */
990    public function statsBirthQuery(int $year1 = -1, int $year2 = -1): Builder
991    {
992        return $this->individualRepository->statsBirthQuery($year1, $year2);
993    }
994
995    /**
996     * @inheritDoc
997     */
998    public function statsBirthBySexQuery(int $year1 = -1, int $year2 = -1): Builder
999    {
1000        return $this->individualRepository->statsBirthBySexQuery($year1, $year2);
1001    }
1002
1003    /**
1004     * @inheritDoc
1005     */
1006    public function statsBirth(string $color_from = null, string $color_to = null): string
1007    {
1008        return $this->individualRepository->statsBirth($color_from, $color_to);
1009    }
1010
1011    /**
1012     * @inheritDoc
1013     */
1014    public function firstDeath(): string
1015    {
1016        return $this->familyDatesRepository->firstDeath();
1017    }
1018
1019    /**
1020     * @inheritDoc
1021     */
1022    public function firstDeathYear(): string
1023    {
1024        return $this->familyDatesRepository->firstDeathYear();
1025    }
1026
1027    /**
1028     * @inheritDoc
1029     */
1030    public function firstDeathName(): string
1031    {
1032        return $this->familyDatesRepository->firstDeathName();
1033    }
1034
1035    /**
1036     * @inheritDoc
1037     */
1038    public function firstDeathPlace(): string
1039    {
1040        return $this->familyDatesRepository->firstDeathPlace();
1041    }
1042
1043    /**
1044     * @inheritDoc
1045     */
1046    public function lastDeath(): string
1047    {
1048        return $this->familyDatesRepository->lastDeath();
1049    }
1050
1051    /**
1052     * @inheritDoc
1053     */
1054    public function lastDeathYear(): string
1055    {
1056        return $this->familyDatesRepository->lastDeathYear();
1057    }
1058
1059    /**
1060     * @inheritDoc
1061     */
1062    public function lastDeathName(): string
1063    {
1064        return $this->familyDatesRepository->lastDeathName();
1065    }
1066
1067    /**
1068     * @inheritDoc
1069     */
1070    public function lastDeathPlace(): string
1071    {
1072        return $this->familyDatesRepository->lastDeathPlace();
1073    }
1074
1075    /**
1076     * @inheritDoc
1077     */
1078    public function statsDeathQuery(int $year1 = -1, int $year2 = -1): Builder
1079    {
1080        return $this->individualRepository->statsDeathQuery($year1, $year2);
1081    }
1082
1083    /**
1084     * @inheritDoc
1085     */
1086    public function statsDeathBySexQuery(int $year1 = -1, int $year2 = -1): Builder
1087    {
1088        return $this->individualRepository->statsDeathBySexQuery($year1, $year2);
1089    }
1090
1091    /**
1092     * @inheritDoc
1093     */
1094    public function statsDeath(string $color_from = null, string $color_to = null): string
1095    {
1096        return $this->individualRepository->statsDeath($color_from, $color_to);
1097    }
1098
1099    /**
1100     * @inheritDoc
1101     */
1102    public function statsAgeQuery(string $related = 'BIRT', string $sex = 'BOTH', int $year1 = -1, int $year2 = -1)
1103    {
1104        return $this->individualRepository->statsAgeQuery($related, $sex, $year1, $year2);
1105    }
1106
1107    /**
1108     * @inheritDoc
1109     */
1110    public function statsAge(): string
1111    {
1112        return $this->individualRepository->statsAge();
1113    }
1114
1115    /**
1116     * @inheritDoc
1117     */
1118    public function longestLife(): string
1119    {
1120        return $this->individualRepository->longestLife();
1121    }
1122
1123    /**
1124     * @inheritDoc
1125     */
1126    public function longestLifeAge(): string
1127    {
1128        return $this->individualRepository->longestLifeAge();
1129    }
1130
1131    /**
1132     * @inheritDoc
1133     */
1134    public function longestLifeName(): string
1135    {
1136        return $this->individualRepository->longestLifeName();
1137    }
1138
1139    /**
1140     * @inheritDoc
1141     */
1142    public function longestLifeFemale(): string
1143    {
1144        return $this->individualRepository->longestLifeFemale();
1145    }
1146
1147    /**
1148     * @inheritDoc
1149     */
1150    public function longestLifeFemaleAge(): string
1151    {
1152        return $this->individualRepository->longestLifeFemaleAge();
1153    }
1154
1155    /**
1156     * @inheritDoc
1157     */
1158    public function longestLifeFemaleName(): string
1159    {
1160        return $this->individualRepository->longestLifeFemaleName();
1161    }
1162
1163    /**
1164     * @inheritDoc
1165     */
1166    public function longestLifeMale(): string
1167    {
1168        return $this->individualRepository->longestLifeMale();
1169    }
1170
1171    /**
1172     * @inheritDoc
1173     */
1174    public function longestLifeMaleAge(): string
1175    {
1176        return $this->individualRepository->longestLifeMaleAge();
1177    }
1178
1179    /**
1180     * @inheritDoc
1181     */
1182    public function longestLifeMaleName(): string
1183    {
1184        return $this->individualRepository->longestLifeMaleName();
1185    }
1186
1187    /**
1188     * @inheritDoc
1189     */
1190    public function topTenOldest(string $total = '10'): string
1191    {
1192        return $this->individualRepository->topTenOldest((int) $total);
1193    }
1194
1195    /**
1196     * @inheritDoc
1197     */
1198    public function topTenOldestList(string $total = '10'): string
1199    {
1200        return $this->individualRepository->topTenOldestList((int) $total);
1201    }
1202
1203    /**
1204     * @inheritDoc
1205     */
1206    public function topTenOldestFemale(string $total = '10'): string
1207    {
1208        return $this->individualRepository->topTenOldestFemale((int) $total);
1209    }
1210
1211    /**
1212     * @inheritDoc
1213     */
1214    public function topTenOldestFemaleList(string $total = '10'): string
1215    {
1216        return $this->individualRepository->topTenOldestFemaleList((int) $total);
1217    }
1218
1219    /**
1220     * @inheritDoc
1221     */
1222    public function topTenOldestMale(string $total = '10'): string
1223    {
1224        return $this->individualRepository->topTenOldestMale((int) $total);
1225    }
1226
1227    /**
1228     * @inheritDoc
1229     */
1230    public function topTenOldestMaleList(string $total = '10'): string
1231    {
1232        return $this->individualRepository->topTenOldestMaleList((int) $total);
1233    }
1234
1235    /**
1236     * @inheritDoc
1237     */
1238    public function topTenOldestAlive(string $total = '10'): string
1239    {
1240        return $this->individualRepository->topTenOldestAlive((int) $total);
1241    }
1242
1243    /**
1244     * @inheritDoc
1245     */
1246    public function topTenOldestListAlive(string $total = '10'): string
1247    {
1248        return $this->individualRepository->topTenOldestListAlive((int) $total);
1249    }
1250
1251    /**
1252     * @inheritDoc
1253     */
1254    public function topTenOldestFemaleAlive(string $total = '10'): string
1255    {
1256        return $this->individualRepository->topTenOldestFemaleAlive((int) $total);
1257    }
1258
1259    /**
1260     * @inheritDoc
1261     */
1262    public function topTenOldestFemaleListAlive(string $total = '10'): string
1263    {
1264        return $this->individualRepository->topTenOldestFemaleListAlive((int) $total);
1265    }
1266
1267    /**
1268     * @inheritDoc
1269     */
1270    public function topTenOldestMaleAlive(string $total = '10'): string
1271    {
1272        return $this->individualRepository->topTenOldestMaleAlive((int) $total);
1273    }
1274
1275    /**
1276     * @inheritDoc
1277     */
1278    public function topTenOldestMaleListAlive(string $total = '10'): string
1279    {
1280        return $this->individualRepository->topTenOldestMaleListAlive((int) $total);
1281    }
1282
1283    /**
1284     * @inheritDoc
1285     */
1286    public function averageLifespan(bool $show_years = false): string
1287    {
1288        return $this->individualRepository->averageLifespan($show_years);
1289    }
1290
1291    /**
1292     * @inheritDoc
1293     */
1294    public function averageLifespanFemale(bool $show_years = false): string
1295    {
1296        return $this->individualRepository->averageLifespanFemale($show_years);
1297    }
1298
1299    /**
1300     * @inheritDoc
1301     */
1302    public function averageLifespanMale(bool $show_years = false): string
1303    {
1304        return $this->individualRepository->averageLifespanMale($show_years);
1305    }
1306
1307    /**
1308     * @inheritDoc
1309     */
1310    public function firstEvent(): string
1311    {
1312        return $this->eventRepository->firstEvent();
1313    }
1314
1315    /**
1316     * @inheritDoc
1317     */
1318    public function firstEventYear(): string
1319    {
1320        return $this->eventRepository->firstEventYear();
1321    }
1322
1323    /**
1324     * @inheritDoc
1325     */
1326    public function firstEventType(): string
1327    {
1328        return $this->eventRepository->firstEventType();
1329    }
1330
1331    /**
1332     * @inheritDoc
1333     */
1334    public function firstEventName(): string
1335    {
1336        return $this->eventRepository->firstEventName();
1337    }
1338
1339    /**
1340     * @inheritDoc
1341     */
1342    public function firstEventPlace(): string
1343    {
1344        return $this->eventRepository->firstEventPlace();
1345    }
1346
1347    /**
1348     * @inheritDoc
1349     */
1350    public function lastEvent(): string
1351    {
1352        return $this->eventRepository->lastEvent();
1353    }
1354
1355    /**
1356     * @inheritDoc
1357     */
1358    public function lastEventYear(): string
1359    {
1360        return $this->eventRepository->lastEventYear();
1361    }
1362
1363    /**
1364     * @inheritDoc
1365     */
1366    public function lastEventType(): string
1367    {
1368        return $this->eventRepository->lastEventType();
1369    }
1370
1371    /**
1372     * @inheritDoc
1373     */
1374    public function lastEventName(): string
1375    {
1376        return $this->eventRepository->lastEventName();
1377    }
1378
1379    /**
1380     * @inheritDoc
1381     */
1382    public function lastEventPlace(): string
1383    {
1384        return $this->eventRepository->lastEventType();
1385    }
1386
1387    /**
1388     * @inheritDoc
1389     */
1390    public function firstMarriage(): string
1391    {
1392        return $this->familyDatesRepository->firstMarriage();
1393    }
1394
1395    /**
1396     * @inheritDoc
1397     */
1398    public function firstMarriageYear(): string
1399    {
1400        return $this->familyDatesRepository->firstMarriageYear();
1401    }
1402
1403    /**
1404     * @inheritDoc
1405     */
1406    public function firstMarriageName(): string
1407    {
1408        return $this->familyDatesRepository->firstMarriageName();
1409    }
1410
1411    /**
1412     * @inheritDoc
1413     */
1414    public function firstMarriagePlace(): string
1415    {
1416        return $this->familyDatesRepository->firstMarriagePlace();
1417    }
1418
1419    /**
1420     * @inheritDoc
1421     */
1422    public function lastMarriage(): string
1423    {
1424        return $this->familyDatesRepository->lastMarriage();
1425    }
1426
1427    /**
1428     * @inheritDoc
1429     */
1430    public function lastMarriageYear(): string
1431    {
1432        return $this->familyDatesRepository->lastMarriageYear();
1433    }
1434
1435    /**
1436     * @inheritDoc
1437     */
1438    public function lastMarriageName(): string
1439    {
1440        return $this->familyDatesRepository->lastMarriageName();
1441    }
1442
1443    /**
1444     * @inheritDoc
1445     */
1446    public function lastMarriagePlace(): string
1447    {
1448        return $this->familyDatesRepository->lastMarriagePlace();
1449    }
1450
1451    /**
1452     * @inheritDoc
1453     */
1454    public function statsMarriageQuery(int $year1 = -1, int $year2 = -1): Builder
1455    {
1456        return $this->familyRepository->statsMarriageQuery($year1, $year2);
1457    }
1458
1459    /**
1460     * @inheritDoc
1461     */
1462    public function statsFirstMarriageQuery(int $year1 = -1, int $year2 = -1): Builder
1463    {
1464        return $this->familyRepository->statsFirstMarriageQuery($year1, $year2);
1465    }
1466
1467    /**
1468     * @inheritDoc
1469     */
1470    public function statsMarr(string $color_from = null, string $color_to = null): string
1471    {
1472        return $this->familyRepository->statsMarr($color_from, $color_to);
1473    }
1474
1475    /**
1476     * @inheritDoc
1477     */
1478    public function firstDivorce(): string
1479    {
1480        return $this->familyDatesRepository->firstDivorce();
1481    }
1482
1483    /**
1484     * @inheritDoc
1485     */
1486    public function firstDivorceYear(): string
1487    {
1488        return $this->familyDatesRepository->firstDivorceYear();
1489    }
1490
1491    /**
1492     * @inheritDoc
1493     */
1494    public function firstDivorceName(): string
1495    {
1496        return $this->familyDatesRepository->firstDivorceName();
1497    }
1498
1499    /**
1500     * @inheritDoc
1501     */
1502    public function firstDivorcePlace(): string
1503    {
1504        return $this->familyDatesRepository->firstDivorcePlace();
1505    }
1506
1507    /**
1508     * @inheritDoc
1509     */
1510    public function lastDivorce(): string
1511    {
1512        return $this->familyDatesRepository->lastDivorce();
1513    }
1514
1515    /**
1516     * @inheritDoc
1517     */
1518    public function lastDivorceYear(): string
1519    {
1520        return $this->familyDatesRepository->lastDivorceYear();
1521    }
1522
1523    /**
1524     * @inheritDoc
1525     */
1526    public function lastDivorceName(): string
1527    {
1528        return $this->familyDatesRepository->lastDivorceName();
1529    }
1530
1531    /**
1532     * @inheritDoc
1533     */
1534    public function lastDivorcePlace(): string
1535    {
1536        return $this->familyDatesRepository->lastDivorcePlace();
1537    }
1538
1539    /**
1540     * @inheritDoc
1541     */
1542    public function statsDiv(string $color_from = null, string $color_to = null): string
1543    {
1544        return $this->familyRepository->statsDiv($color_from, $color_to);
1545    }
1546
1547    /**
1548     * @inheritDoc
1549     */
1550    public function youngestMarriageFemale(): string
1551    {
1552        return $this->familyRepository->youngestMarriageFemale();
1553    }
1554
1555    /**
1556     * @inheritDoc
1557     */
1558    public function youngestMarriageFemaleName(): string
1559    {
1560        return $this->familyRepository->youngestMarriageFemaleName();
1561    }
1562
1563    /**
1564     * @inheritDoc
1565     */
1566    public function youngestMarriageFemaleAge(string $show_years = ''): string
1567    {
1568        return $this->familyRepository->youngestMarriageFemaleAge($show_years);
1569    }
1570
1571    /**
1572     * @inheritDoc
1573     */
1574    public function oldestMarriageFemale(): string
1575    {
1576        return $this->familyRepository->oldestMarriageFemale();
1577    }
1578
1579    /**
1580     * @inheritDoc
1581     */
1582    public function oldestMarriageFemaleName(): string
1583    {
1584        return $this->familyRepository->oldestMarriageFemaleName();
1585    }
1586
1587    /**
1588     * @inheritDoc
1589     */
1590    public function oldestMarriageFemaleAge(string $show_years = ''): string
1591    {
1592        return $this->familyRepository->oldestMarriageFemaleAge($show_years);
1593    }
1594
1595    /**
1596     * @inheritDoc
1597     */
1598    public function youngestMarriageMale(): string
1599    {
1600        return $this->familyRepository->youngestMarriageMale();
1601    }
1602
1603    /**
1604     * @inheritDoc
1605     */
1606    public function youngestMarriageMaleName(): string
1607    {
1608        return $this->familyRepository->youngestMarriageMaleName();
1609    }
1610
1611    /**
1612     * @inheritDoc
1613     */
1614    public function youngestMarriageMaleAge(string $show_years = ''): string
1615    {
1616        return $this->familyRepository->youngestMarriageMaleAge($show_years);
1617    }
1618
1619    /**
1620     * @inheritDoc
1621     */
1622    public function oldestMarriageMale(): string
1623    {
1624        return $this->familyRepository->oldestMarriageMale();
1625    }
1626
1627    /**
1628     * @inheritDoc
1629     */
1630    public function oldestMarriageMaleName(): string
1631    {
1632        return $this->familyRepository->oldestMarriageMaleName();
1633    }
1634
1635    /**
1636     * @inheritDoc
1637     */
1638    public function oldestMarriageMaleAge(string $show_years = ''): string
1639    {
1640        return $this->familyRepository->oldestMarriageMaleAge($show_years);
1641    }
1642
1643    /**
1644     * @inheritDoc
1645     */
1646    public function statsMarrAgeQuery(string $sex, int $year1 = -1, int $year2 = -1): array
1647    {
1648        return $this->familyRepository->statsMarrAgeQuery($sex, $year1, $year2);
1649    }
1650
1651    /**
1652     * @inheritDoc
1653     */
1654    public function statsMarrAge(): string
1655    {
1656        return $this->familyRepository->statsMarrAge();
1657    }
1658
1659    /**
1660     * @inheritDoc
1661     */
1662    public function ageBetweenSpousesMF(string $total = '10'): string
1663    {
1664        return $this->familyRepository->ageBetweenSpousesMF((int) $total);
1665    }
1666
1667    /**
1668     * @inheritDoc
1669     */
1670    public function ageBetweenSpousesMFList(string $total = '10'): string
1671    {
1672        return $this->familyRepository->ageBetweenSpousesMFList((int) $total);
1673    }
1674
1675    /**
1676     * @inheritDoc
1677     */
1678    public function ageBetweenSpousesFM(string $total = '10'): string
1679    {
1680        return $this->familyRepository->ageBetweenSpousesFM((int) $total);
1681    }
1682
1683    /**
1684     * @inheritDoc
1685     */
1686    public function ageBetweenSpousesFMList(string $total = '10'): string
1687    {
1688        return $this->familyRepository->ageBetweenSpousesFMList((int) $total);
1689    }
1690
1691    /**
1692     * @inheritDoc
1693     */
1694    public function topAgeOfMarriageFamily(): string
1695    {
1696        return $this->familyRepository->topAgeOfMarriageFamily();
1697    }
1698
1699    /**
1700     * @inheritDoc
1701     */
1702    public function topAgeOfMarriage(): string
1703    {
1704        return $this->familyRepository->topAgeOfMarriage();
1705    }
1706
1707    /**
1708     * @inheritDoc
1709     */
1710    public function topAgeOfMarriageFamilies(string $total = '10'): string
1711    {
1712        return $this->familyRepository->topAgeOfMarriageFamilies((int) $total);
1713    }
1714
1715    /**
1716     * @inheritDoc
1717     */
1718    public function topAgeOfMarriageFamiliesList(string $total = '10'): string
1719    {
1720        return $this->familyRepository->topAgeOfMarriageFamiliesList((int) $total);
1721    }
1722
1723    /**
1724     * @inheritDoc
1725     */
1726    public function minAgeOfMarriageFamily(): string
1727    {
1728        return $this->familyRepository->minAgeOfMarriageFamily();
1729    }
1730
1731    /**
1732     * @inheritDoc
1733     */
1734    public function minAgeOfMarriage(): string
1735    {
1736        return $this->familyRepository->minAgeOfMarriage();
1737    }
1738
1739    /**
1740     * @inheritDoc
1741     */
1742    public function minAgeOfMarriageFamilies(string $total = '10'): string
1743    {
1744        return $this->familyRepository->minAgeOfMarriageFamilies((int) $total);
1745    }
1746
1747    /**
1748     * @inheritDoc
1749     */
1750    public function minAgeOfMarriageFamiliesList(string $total = '10'): string
1751    {
1752        return $this->familyRepository->minAgeOfMarriageFamiliesList((int) $total);
1753    }
1754
1755    /**
1756     * @inheritDoc
1757     */
1758    public function youngestMother(): string
1759    {
1760        return $this->familyRepository->youngestMother();
1761    }
1762
1763    /**
1764     * @inheritDoc
1765     */
1766    public function youngestMotherName(): string
1767    {
1768        return $this->familyRepository->youngestMotherName();
1769    }
1770
1771    /**
1772     * @inheritDoc
1773     */
1774    public function youngestMotherAge(string $show_years = ''): string
1775    {
1776        return $this->familyRepository->youngestMotherAge($show_years);
1777    }
1778
1779    /**
1780     * @inheritDoc
1781     */
1782    public function oldestMother(): string
1783    {
1784        return $this->familyRepository->oldestMother();
1785    }
1786
1787    /**
1788     * @inheritDoc
1789     */
1790    public function oldestMotherName(): string
1791    {
1792        return $this->familyRepository->oldestMotherName();
1793    }
1794
1795    /**
1796     * @inheritDoc
1797     */
1798    public function oldestMotherAge(string $show_years = ''): string
1799    {
1800        return $this->familyRepository->oldestMotherAge($show_years);
1801    }
1802
1803    /**
1804     * @inheritDoc
1805     */
1806    public function youngestFather(): string
1807    {
1808        return $this->familyRepository->youngestFather();
1809    }
1810
1811    /**
1812     * @inheritDoc
1813     */
1814    public function youngestFatherName(): string
1815    {
1816        return $this->familyRepository->youngestFatherName();
1817    }
1818
1819    /**
1820     * @inheritDoc
1821     */
1822    public function youngestFatherAge(string $show_years = ''): string
1823    {
1824        return $this->familyRepository->youngestFatherAge($show_years);
1825    }
1826
1827    /**
1828     * @inheritDoc
1829     */
1830    public function oldestFather(): string
1831    {
1832        return $this->familyRepository->oldestFather();
1833    }
1834
1835    /**
1836     * @inheritDoc
1837     */
1838    public function oldestFatherName(): string
1839    {
1840        return $this->familyRepository->oldestFatherName();
1841    }
1842
1843    /**
1844     * @inheritDoc
1845     */
1846    public function oldestFatherAge(string $show_years = ''): string
1847    {
1848        return $this->familyRepository->oldestFatherAge($show_years);
1849    }
1850
1851    /**
1852     * @inheritDoc
1853     */
1854    public function totalMarriedMales(): string
1855    {
1856        return $this->familyRepository->totalMarriedMales();
1857    }
1858
1859    /**
1860     * @inheritDoc
1861     */
1862    public function totalMarriedFemales(): string
1863    {
1864        return $this->familyRepository->totalMarriedFemales();
1865    }
1866
1867    /**
1868     * @inheritDoc
1869     */
1870    public function monthFirstChildQuery(bool $sex = false): array
1871    {
1872        return $this->familyRepository->monthFirstChildQuery($sex);
1873    }
1874
1875    /**
1876     * @inheritDoc
1877     */
1878    public function largestFamily(): string
1879    {
1880        return $this->familyRepository->largestFamily();
1881    }
1882
1883    /**
1884     * @inheritDoc
1885     */
1886    public function largestFamilySize(): string
1887    {
1888        return $this->familyRepository->largestFamilySize();
1889    }
1890
1891    /**
1892     * @inheritDoc
1893     */
1894    public function largestFamilyName(): string
1895    {
1896        return $this->familyRepository->largestFamilyName();
1897    }
1898
1899    /**
1900     * @inheritDoc
1901     */
1902    public function topTenLargestFamily(string $total = '10'): string
1903    {
1904        return $this->familyRepository->topTenLargestFamily((int) $total);
1905    }
1906
1907    /**
1908     * @inheritDoc
1909     */
1910    public function topTenLargestFamilyList(string $total = '10'): string
1911    {
1912        return $this->familyRepository->topTenLargestFamilyList((int) $total);
1913    }
1914
1915    /**
1916     * @inheritDoc
1917     */
1918    public function chartLargestFamilies(
1919        string $color_from = null,
1920        string $color_to = null,
1921        string $total = '10'
1922    ): string {
1923        return $this->familyRepository->chartLargestFamilies($color_from, $color_to, (int) $total);
1924    }
1925
1926    /**
1927     * @inheritDoc
1928     */
1929    public function totalChildren(): string
1930    {
1931        return $this->familyRepository->totalChildren();
1932    }
1933
1934    /**
1935     * @inheritDoc
1936     */
1937    public function averageChildren(): string
1938    {
1939        return $this->familyRepository->averageChildren();
1940    }
1941
1942    /**
1943     * @inheritDoc
1944     */
1945    public function statsChildrenQuery(int $year1 = -1, int $year2 = -1): array
1946    {
1947        return $this->familyRepository->statsChildrenQuery($year1, $year2);
1948    }
1949
1950    /**
1951     * @inheritDoc
1952     */
1953    public function statsChildren(): string
1954    {
1955        return $this->familyRepository->statsChildren();
1956    }
1957
1958    /**
1959     * @inheritDoc
1960     */
1961    public function topAgeBetweenSiblingsName(string $total = '10'): string
1962    {
1963        return $this->familyRepository->topAgeBetweenSiblingsName((int) $total);
1964    }
1965
1966    /**
1967     * @inheritDoc
1968     */
1969    public function topAgeBetweenSiblings(string $total = '10'): string
1970    {
1971        return $this->familyRepository->topAgeBetweenSiblings((int) $total);
1972    }
1973
1974    /**
1975     * @inheritDoc
1976     */
1977    public function topAgeBetweenSiblingsFullName(string $total = '10'): string
1978    {
1979        return $this->familyRepository->topAgeBetweenSiblingsFullName((int) $total);
1980    }
1981
1982    /**
1983     * @inheritDoc
1984     */
1985    public function topAgeBetweenSiblingsList(string $total = '10', string $one = ''): string
1986    {
1987        return $this->familyRepository->topAgeBetweenSiblingsList((int) $total, $one);
1988    }
1989
1990    /**
1991     * @inheritDoc
1992     */
1993    public function noChildrenFamilies(): string
1994    {
1995        return $this->familyRepository->noChildrenFamilies();
1996    }
1997
1998    /**
1999     * @inheritDoc
2000     */
2001    public function noChildrenFamiliesList(string $type = 'list'): string
2002    {
2003        return $this->familyRepository->noChildrenFamiliesList($type);
2004    }
2005
2006    /**
2007     * @inheritDoc
2008     */
2009    public function chartNoChildrenFamilies(
2010        string $year1 = '-1',
2011        string $year2 = '-1'
2012    ): string {
2013        return $this->familyRepository->chartNoChildrenFamilies((int) $year1, (int) $year2);
2014    }
2015
2016    /**
2017     * @inheritDoc
2018     */
2019    public function topTenLargestGrandFamily(string $total = '10'): string
2020    {
2021        return $this->familyRepository->topTenLargestGrandFamily((int) $total);
2022    }
2023
2024    /**
2025     * @inheritDoc
2026     */
2027    public function topTenLargestGrandFamilyList(string $total = '10'): string
2028    {
2029        return $this->familyRepository->topTenLargestGrandFamilyList((int) $total);
2030    }
2031
2032    /**
2033     * @inheritDoc
2034     */
2035    public function getCommonSurname(): string
2036    {
2037        return $this->individualRepository->getCommonSurname();
2038    }
2039
2040    /**
2041     * @inheritDoc
2042     */
2043    public function commonSurnames(
2044        string $threshold = '1',
2045        string $number_of_surnames = '10',
2046        string $sorting = 'alpha'
2047    ): string {
2048        return $this->individualRepository->commonSurnames((int) $threshold, (int) $number_of_surnames, $sorting);
2049    }
2050
2051    /**
2052     * @inheritDoc
2053     */
2054    public function commonSurnamesTotals(
2055        string $threshold = '1',
2056        string $number_of_surnames = '10',
2057        string $sorting = 'rcount'
2058    ): string {
2059        return $this->individualRepository->commonSurnamesTotals((int) $threshold, (int) $number_of_surnames, $sorting);
2060    }
2061
2062    /**
2063     * @inheritDoc
2064     */
2065    public function commonSurnamesList(
2066        string $threshold = '1',
2067        string $number_of_surnames = '10',
2068        string $sorting = 'alpha'
2069    ): string {
2070        return $this->individualRepository->commonSurnamesList((int) $threshold, (int) $number_of_surnames, $sorting);
2071    }
2072
2073    /**
2074     * @inheritDoc
2075     */
2076    public function commonSurnamesListTotals(
2077        string $threshold = '1',
2078        string $number_of_surnames = '10',
2079        string $sorting = 'rcount'
2080    ): string {
2081        return $this->individualRepository
2082            ->commonSurnamesListTotals((int) $threshold, (int) $number_of_surnames, $sorting);
2083    }
2084
2085    /**
2086     * @inheritDoc
2087     */
2088    public function chartCommonSurnames(
2089        string $color_from = null,
2090        string $color_to = null,
2091        string $number_of_surnames = '10'
2092    ): string {
2093        return $this->individualRepository
2094            ->chartCommonSurnames($color_from, $color_to, (int) $number_of_surnames);
2095    }
2096
2097    /**
2098     * @inheritDoc
2099     */
2100    public function commonGiven(string $threshold = '1', string $maxtoshow = '10'): string
2101    {
2102        return $this->individualRepository->commonGiven((int) $threshold, (int) $maxtoshow);
2103    }
2104
2105    /**
2106     * @inheritDoc
2107     */
2108    public function commonGivenTotals(string $threshold = '1', string $maxtoshow = '10'): string
2109    {
2110        return $this->individualRepository->commonGivenTotals((int) $threshold, (int) $maxtoshow);
2111    }
2112
2113    /**
2114     * @inheritDoc
2115     */
2116    public function commonGivenList(string $threshold = '1', string $maxtoshow = '10'): string
2117    {
2118        return $this->individualRepository->commonGivenList((int) $threshold, (int) $maxtoshow);
2119    }
2120
2121    /**
2122     * @inheritDoc
2123     */
2124    public function commonGivenListTotals(string $threshold = '1', string $maxtoshow = '10'): string
2125    {
2126        return $this->individualRepository->commonGivenListTotals((int) $threshold, (int) $maxtoshow);
2127    }
2128
2129    /**
2130     * @inheritDoc
2131     */
2132    public function commonGivenTable(string $threshold = '1', string $maxtoshow = '10'): string
2133    {
2134        return $this->individualRepository->commonGivenTable((int) $threshold, (int) $maxtoshow);
2135    }
2136
2137    /**
2138     * @inheritDoc
2139     */
2140    public function commonGivenFemale(string $threshold = '1', string $maxtoshow = '10'): string
2141    {
2142        return $this->individualRepository->commonGivenFemale((int) $threshold, (int) $maxtoshow);
2143    }
2144
2145    /**
2146     * @inheritDoc
2147     */
2148    public function commonGivenFemaleTotals(string $threshold = '1', string $maxtoshow = '10'): string
2149    {
2150        return $this->individualRepository->commonGivenFemaleTotals((int) $threshold, (int) $maxtoshow);
2151    }
2152
2153    /**
2154     * @inheritDoc
2155     */
2156    public function commonGivenFemaleList(string $threshold = '1', string $maxtoshow = '10'): string
2157    {
2158        return $this->individualRepository->commonGivenFemaleList((int) $threshold, (int) $maxtoshow);
2159    }
2160
2161    /**
2162     * @inheritDoc
2163     */
2164    public function commonGivenFemaleListTotals(string $threshold = '1', string $maxtoshow = '10'): string
2165    {
2166        return $this->individualRepository->commonGivenFemaleListTotals((int) $threshold, (int) $maxtoshow);
2167    }
2168
2169    /**
2170     * @inheritDoc
2171     */
2172    public function commonGivenFemaleTable(string $threshold = '1', string $maxtoshow = '10'): string
2173    {
2174        return $this->individualRepository->commonGivenFemaleTable((int) $threshold, (int) $maxtoshow);
2175    }
2176
2177    /**
2178     * @inheritDoc
2179     */
2180    public function commonGivenMale(string $threshold = '1', string $maxtoshow = '10'): string
2181    {
2182        return $this->individualRepository->commonGivenMale((int) $threshold, (int) $maxtoshow);
2183    }
2184
2185    /**
2186     * @inheritDoc
2187     */
2188    public function commonGivenMaleTotals(string $threshold = '1', string $maxtoshow = '10'): string
2189    {
2190        return $this->individualRepository->commonGivenMaleTotals((int) $threshold, (int) $maxtoshow);
2191    }
2192
2193    /**
2194     * @inheritDoc
2195     */
2196    public function commonGivenMaleList(string $threshold = '1', string $maxtoshow = '10'): string
2197    {
2198        return $this->individualRepository->commonGivenMaleList((int) $threshold, (int) $maxtoshow);
2199    }
2200
2201    /**
2202     * @inheritDoc
2203     */
2204    public function commonGivenMaleListTotals(string $threshold = '1', string $maxtoshow = '10'): string
2205    {
2206        return $this->individualRepository->commonGivenMaleListTotals((int) $threshold, (int) $maxtoshow);
2207    }
2208
2209    /**
2210     * @inheritDoc
2211     */
2212    public function commonGivenMaleTable(string $threshold = '1', string $maxtoshow = '10'): string
2213    {
2214        return $this->individualRepository->commonGivenMaleTable((int) $threshold, (int) $maxtoshow);
2215    }
2216
2217    /**
2218     * @inheritDoc
2219     */
2220    public function commonGivenUnknown(string $threshold = '1', string $maxtoshow = '10'): string
2221    {
2222        return $this->individualRepository->commonGivenUnknown((int) $threshold, (int) $maxtoshow);
2223    }
2224
2225    /**
2226     * @inheritDoc
2227     */
2228    public function commonGivenUnknownTotals(string $threshold = '1', string $maxtoshow = '10'): string
2229    {
2230        return $this->individualRepository->commonGivenUnknownTotals((int) $threshold, (int) $maxtoshow);
2231    }
2232
2233    /**
2234     * @inheritDoc
2235     */
2236    public function commonGivenUnknownList(string $threshold = '1', string $maxtoshow = '10'): string
2237    {
2238        return $this->individualRepository->commonGivenUnknownList((int) $threshold, (int) $maxtoshow);
2239    }
2240
2241    /**
2242     * @inheritDoc
2243     */
2244    public function commonGivenUnknownListTotals(string $threshold = '1', string $maxtoshow = '10'): string
2245    {
2246        return $this->individualRepository->commonGivenUnknownListTotals((int) $threshold, (int) $maxtoshow);
2247    }
2248
2249    /**
2250     * @inheritDoc
2251     */
2252    public function commonGivenUnknownTable(string $threshold = '1', string $maxtoshow = '10'): string
2253    {
2254        return $this->individualRepository->commonGivenUnknownTable((int) $threshold, (int) $maxtoshow);
2255    }
2256
2257    /**
2258     * @inheritDoc
2259     */
2260    public function chartCommonGiven(
2261        string $color_from = null,
2262        string $color_to = null,
2263        string $maxtoshow = '7'
2264    ): string {
2265        return $this->individualRepository->chartCommonGiven($color_from, $color_to, (int) $maxtoshow);
2266    }
2267
2268    /**
2269     * @inheritDoc
2270     */
2271    public function usersLoggedIn(): string
2272    {
2273        return $this->userRepository->usersLoggedIn();
2274    }
2275
2276    /**
2277     * @inheritDoc
2278     */
2279    public function usersLoggedInList(): string
2280    {
2281        return $this->userRepository->usersLoggedInList();
2282    }
2283
2284    /**
2285     * @inheritDoc
2286     */
2287    public function usersLoggedInTotal(): int
2288    {
2289        return $this->userRepository->usersLoggedInTotal();
2290    }
2291
2292    /**
2293     * @inheritDoc
2294     */
2295    public function usersLoggedInTotalAnon(): int
2296    {
2297        return $this->userRepository->usersLoggedInTotalAnon();
2298    }
2299
2300    /**
2301     * @inheritDoc
2302     */
2303    public function usersLoggedInTotalVisible(): int
2304    {
2305        return $this->userRepository->usersLoggedInTotalVisible();
2306    }
2307
2308    /**
2309     * @inheritDoc
2310     */
2311    public function userId(): string
2312    {
2313        return $this->userRepository->userId();
2314    }
2315
2316    /**
2317     * @inheritDoc
2318     */
2319    public function userName(string $visitor_text = ''): string
2320    {
2321        return $this->userRepository->userName();
2322    }
2323
2324    /**
2325     * @inheritDoc
2326     */
2327    public function userFullName(): string
2328    {
2329        return $this->userRepository->userFullName();
2330    }
2331
2332    /**
2333     * @inheritDoc
2334     */
2335    public function totalUsers(): string
2336    {
2337        return $this->userRepository->totalUsers();
2338    }
2339
2340    /**
2341     * @inheritDoc
2342     */
2343    public function totalAdmins(): string
2344    {
2345        return $this->userRepository->totalAdmins();
2346    }
2347
2348    /**
2349     * @inheritDoc
2350     */
2351    public function totalNonAdmins(): string
2352    {
2353        return $this->userRepository->totalNonAdmins();
2354    }
2355
2356    /**
2357     * @inheritDoc
2358     */
2359    public function latestUserId(): string
2360    {
2361        return $this->latestUserRepository->latestUserId();
2362    }
2363
2364    /**
2365     * @inheritDoc
2366     */
2367    public function latestUserName(): string
2368    {
2369        return $this->latestUserRepository->latestUserName();
2370    }
2371
2372    /**
2373     * @inheritDoc
2374     */
2375    public function latestUserFullName(): string
2376    {
2377        return $this->latestUserRepository->latestUserFullName();
2378    }
2379
2380    /**
2381     * @inheritDoc
2382     */
2383    public function latestUserRegDate(string $format = null): string
2384    {
2385        return $this->latestUserRepository->latestUserRegDate();
2386    }
2387
2388    /**
2389     * @inheritDoc
2390     */
2391    public function latestUserRegTime(string $format = null): string
2392    {
2393        return $this->latestUserRepository->latestUserRegTime();
2394    }
2395
2396    /**
2397     * @inheritDoc
2398     */
2399    public function latestUserLoggedin(string $yes = null, string $no = null): string
2400    {
2401        return $this->latestUserRepository->latestUserLoggedin();
2402    }
2403
2404    /**
2405     * @inheritDoc
2406     */
2407    public function contactWebmaster(): string
2408    {
2409        return $this->contactRepository->contactWebmaster();
2410    }
2411
2412    /**
2413     * @inheritDoc
2414     */
2415    public function contactGedcom(): string
2416    {
2417        return $this->contactRepository->contactGedcom();
2418    }
2419
2420    /**
2421     * @inheritDoc
2422     */
2423    public function serverDate(): string
2424    {
2425        return $this->serverRepository->serverDate();
2426    }
2427
2428    /**
2429     * @inheritDoc
2430     */
2431    public function serverTime(): string
2432    {
2433        return $this->serverRepository->serverTime();
2434    }
2435
2436    /**
2437     * @inheritDoc
2438     */
2439    public function serverTime24(): string
2440    {
2441        return $this->serverRepository->serverTime24();
2442    }
2443
2444    /**
2445     * What is the timezone of the server.
2446     *
2447     * @return string
2448     */
2449    public function serverTimezone(): string
2450    {
2451        return $this->serverRepository->serverTimezone();
2452    }
2453
2454    /**
2455     * @inheritDoc
2456     */
2457    public function browserDate(): string
2458    {
2459        return $this->browserRepository->browserDate();
2460    }
2461
2462    /**
2463     * @inheritDoc
2464     */
2465    public function browserTime(): string
2466    {
2467        return $this->browserRepository->browserTime();
2468    }
2469
2470    /**
2471     * @inheritDoc
2472     */
2473    public function browserTimezone(): string
2474    {
2475        return $this->browserRepository->browserTimezone();
2476    }
2477
2478    /**
2479     * @inheritDoc
2480     */
2481    public function hitCount(string $page_parameter = ''): string
2482    {
2483        return $this->hitCountRepository->hitCount($page_parameter);
2484    }
2485
2486    /**
2487     * @inheritDoc
2488     */
2489    public function hitCountUser(string $page_parameter = ''): string
2490    {
2491        return $this->hitCountRepository->hitCountUser($page_parameter);
2492    }
2493
2494    /**
2495     * @inheritDoc
2496     */
2497    public function hitCountIndi(string $page_parameter = ''): string
2498    {
2499        return $this->hitCountRepository->hitCountIndi($page_parameter);
2500    }
2501
2502    /**
2503     * @inheritDoc
2504     */
2505    public function hitCountFam(string $page_parameter = ''): string
2506    {
2507        return $this->hitCountRepository->hitCountFam($page_parameter);
2508    }
2509
2510    /**
2511     * @inheritDoc
2512     */
2513    public function hitCountSour(string $page_parameter = ''): string
2514    {
2515        return $this->hitCountRepository->hitCountSour($page_parameter);
2516    }
2517
2518    /**
2519     * @inheritDoc
2520     */
2521    public function hitCountRepo(string $page_parameter = ''): string
2522    {
2523        return $this->hitCountRepository->hitCountRepo($page_parameter);
2524    }
2525
2526    /**
2527     * @inheritDoc
2528     */
2529    public function hitCountNote(string $page_parameter = ''): string
2530    {
2531        return $this->hitCountRepository->hitCountNote($page_parameter);
2532    }
2533
2534    /**
2535     * @inheritDoc
2536     */
2537    public function hitCountObje(string $page_parameter = ''): string
2538    {
2539        return $this->hitCountRepository->hitCountObje($page_parameter);
2540    }
2541
2542    /**
2543     * @inheritDoc
2544     */
2545    public function gedcomFavorites(): string
2546    {
2547        return $this->favoritesRepository->gedcomFavorites();
2548    }
2549
2550    /**
2551     * @inheritDoc
2552     */
2553    public function userFavorites(): string
2554    {
2555        return $this->favoritesRepository->userFavorites();
2556    }
2557
2558    /**
2559     * @inheritDoc
2560     */
2561    public function totalGedcomFavorites(): string
2562    {
2563        return $this->favoritesRepository->totalGedcomFavorites();
2564    }
2565
2566    /**
2567     * @inheritDoc
2568     */
2569    public function totalUserFavorites(): string
2570    {
2571        return $this->favoritesRepository->totalUserFavorites();
2572    }
2573
2574    /**
2575     * @inheritDoc
2576     */
2577    public function totalUserMessages(): string
2578    {
2579        return $this->messageRepository->totalUserMessages();
2580    }
2581
2582    /**
2583     * @inheritDoc
2584     */
2585    public function totalUserJournal(): string
2586    {
2587        return $this->newsRepository->totalUserJournal();
2588    }
2589
2590    /**
2591     * @inheritDoc
2592     */
2593    public function totalGedcomNews(): string
2594    {
2595        return $this->newsRepository->totalGedcomNews();
2596    }
2597
2598    /**
2599     * Create any of the other blocks.
2600     * Use as #callBlock:block_name#
2601     *
2602     * @param string $block
2603     * @param string ...$params
2604     *
2605     * @return null|string
2606     */
2607    public function callBlock(string $block = '', ...$params): ?string
2608    {
2609        /** @var ModuleBlockInterface $module */
2610        $module = $this->module_service
2611            ->findByComponent('block', $this->tree, Auth::user())
2612            ->filter(function (ModuleInterface $module) use ($block): bool {
2613                return $module->name() === $block && $module->name() !== 'html';
2614            })
2615            ->first();
2616
2617        if ($module === null) {
2618            return '';
2619        }
2620
2621        // Build the config array
2622        $cfg = [];
2623        foreach ($params as $config) {
2624            $bits = explode('=', $config);
2625
2626            if (\count($bits) < 2) {
2627                continue;
2628            }
2629
2630            $v       = array_shift($bits);
2631            $cfg[$v] = implode('=', $bits);
2632        }
2633
2634        return $module->getBlock($this->tree, 0, '', $cfg);
2635    }
2636
2637    /**
2638     * What is the current version of webtrees.
2639     *
2640     * @return string
2641     */
2642    public function webtreesVersion(): string
2643    {
2644        return Webtrees::VERSION;
2645    }
2646}
2647