File Coverage

File:lib/Genealogy/Relationship/Name.pm
Coverage:96.4%

linestmtbrancondsubtimecode
1package Genealogy::Relationship::Name;
2
3# Genealogy::Relationship::Name - Return the name of a genealogical relationship
4# given step counts to and from a common ancestor, the sex of person B, and a language.
5#
6# Author: Nigel Horne <njh@nigelhorne.com>
7# Licence: GPL v2
8
9
7
7
7
679917
363
14
use utf8;
10
7
7
7
54
3
35
use strict;
11
7
7
7
5
4
109
use warnings;
12
7
7
7
281
8852
11
use autodie qw(:all);
13
14
7
7
7
18508
3
140
use Carp qw(croak carp);
15
7
7
7
1579
144029
82
use Object::Configure;
16
7
7
7
13
6
108
use Params::Get;
17
7
7
7
11
45
65
use Params::Validate::Strict 0.31;
18
7
7
7
7
3
14576
use Readonly;
19
20our $VERSION = '0.04';
21
22# ---------------------------------------------------------------------------
23# Constants – relationship table keys
24# ---------------------------------------------------------------------------
25
26# Supported language codes
27Readonly::Array my @SUPPORTED_LANGUAGES => qw(de de_ch en es fa fr la);
28
29# Default language when none supplied
30Readonly::Scalar my $DEFAULT_LANGUAGE => 'en';
31
32# Sex constants
33Readonly::Scalar my $SEX_MALE   => 'M';
34Readonly::Scalar my $SEX_FEMALE => 'F';
35
36# ---------------------------------------------------------------------------
37# English relationship tables
38# Key: "$steps1,$steps2"  where steps1 = steps from A to ancestor,
39#                                steps2 = steps from B to ancestor
40# ---------------------------------------------------------------------------
41
42Readonly::Hash my %EN_MALE_RELATIONSHIPS => (
43        '0,0' => 'self',
44        '0,1' => 'son',
45        '0,2' => 'grandson',
46        '0,3' => 'great-grandson',
47        '0,4' => 'great-great-grandson',
48        '0,5' => 'great-great-great-grandson',
49        '0,6' => 'great-great-great-great-grandson',
50        '0,7' => 'great-great-great-great-great-grandson',
51        '0,8' => 'great-great-great-great-great-great-grandson',
52        '0,9' => 'great-great-great-great-great-great-great-grandson',
53        '0,10' => 'great-great-great-great-great-great-great-great-grandson',
54        '1,0' => 'father',
55        '1,1' => 'brother',
56        '1,2' => 'nephew',
57        '1,3' => 'great-nephew',
58        '1,4' => 'great-great-nephew',
59        '1,5' => 'great-great-great-nephew',
60        '1,6' => 'great-great-great-great-nephew',
61        '1,7' => 'great-great-great-great-great-nephew',
62        '1,8' => 'great-great-great-great-great-great-nephew',
63        '1,9' => 'great-great-great-great-great-great-great-nephew',
64        '1,10' => 'great-great-great-great-great-great-great-great-nephew',
65        '2,0' => 'grandfather',
66        '2,1' => 'uncle',
67        '2,2' => 'first cousin',
68        '2,3' => 'first cousin once-removed',
69        '2,4' => 'first cousin twice-removed',
70        '2,5' => 'first cousin three-times-removed',
71        '2,6' => 'first cousin four-times-removed',
72        '2,7' => 'first cousin five-times-removed',
73        '2,8' => 'first cousin six-times-removed',
74        '2,9' => 'first cousin seven-times-removed',
75        '2,10' => 'first cousin eight-times-removed',
76        '3,0' => 'great-grandfather',
77        '3,1' => 'great-uncle',
78        '3,2' => 'first cousin once-removed',
79        '3,3' => 'second cousin',
80        '3,4' => 'second cousin once-removed',
81        '3,5' => 'second cousin twice-removed',
82        '3,6' => 'second cousin three-times-removed',
83        '3,7' => 'second cousin four-times-removed',
84        '3,8' => 'second cousin five-times-removed',
85        '3,9' => 'second cousin six-times-removed',
86        '3,10' => 'second cousin seven-times-removed',
87        '4,0' => 'great-great-grandfather',
88        '4,1' => 'great-great-uncle',
89        '4,2' => 'first cousin twice-removed',
90        '4,3' => 'second cousin once-removed',
91        '4,4' => 'third cousin',
92        '4,5' => 'third cousin once-removed',
93        '4,6' => 'third cousin twice-removed',
94        '4,7' => 'third cousin three-times-removed',
95        '4,8' => 'third cousin four-times-removed',
96        '4,9' => 'third cousin five-times-removed',
97        '4,10' => 'third cousin six-times-removed',
98        '5,0' => 'great-great-great-grandfather',
99        '5,1' => 'great-great-great-uncle',
100        '5,2' => 'first cousin three-times-removed',
101        '5,3' => 'second cousin twice-removed',
102        '5,4' => 'third cousin once-removed',
103        '5,5' => 'fourth cousin',
104        '5,6' => 'fourth cousin once-removed',
105        '5,7' => 'fourth cousin twice-removed',
106        '5,8' => 'fourth cousin three-times-removed',
107        '5,9' => 'fourth cousin four-times-removed',
108        '5,10' => 'fourth cousin five-times-removed',
109        '6,0' => 'great-great-great-great-grandfather',
110        '6,1' => 'great-great-great-great-uncle',
111        '6,2' => 'first cousin four-times-removed',
112        '6,3' => 'second cousin three-times-removed',
113        '6,4' => 'third cousin twice-removed',
114        '6,5' => 'fourth cousin once-removed',
115        '6,6' => 'fifth cousin',
116        '6,7' => 'fifth cousin once-removed',
117        '6,8' => 'fifth cousin twice-removed',
118        '6,9' => 'fifth cousin three-times-removed',
119        '6,10' => 'fifth cousin four-times-removed',
120        '7,0' => 'great-great-great-great-great-grandfather',
121        '7,1' => 'great-great-great-great-great-uncle',
122        '7,2' => 'first cousin five-times-removed',
123        '7,3' => 'second cousin four-times-removed',
124        '7,4' => 'third cousin three-times-removed',
125        '7,5' => 'fourth cousin twice-removed',
126        '7,6' => 'fifth cousin once-removed',
127        '7,7' => 'sixth cousin',
128        '7,8' => 'sixth cousin once-removed',
129        '7,9' => 'sixth cousin twice-removed',
130        '7,10' => 'sixth cousin three-times-removed',
131        '8,0' => 'great-great-great-great-great-great-grandfather',
132        '8,1' => 'great-great-great-great-great-great-uncle',
133        '8,2' => 'first cousin six-times-removed',
134        '8,3' => 'second cousin five-times-removed',
135        '8,4' => 'third cousin four-times-removed',
136        '8,5' => 'fourth cousin three-times-removed',
137        '8,6' => 'fifth cousin twice-removed',
138        '8,7' => 'sixth cousin once-removed',
139        '8,8' => 'seventh cousin',
140        '8,9' => 'seventh cousin once-removed',
141        '8,10' => 'seventh cousin twice-removed',
142        '9,0' => 'great-great-great-great-great-great-great-grandfather',
143        '9,1' => 'great-great-great-great-great-great-great-uncle',
144        '9,2' => 'first cousin seven-times-removed',
145        '9,3' => 'second cousin six-times-removed',
146        '9,4' => 'third cousin five-times-removed',
147        '9,5' => 'fourth cousin four-times-removed',
148        '9,6' => 'fifth cousin three-times-removed',
149        '9,7' => 'sixth cousin twice-removed',
150        '9,8' => 'seventh cousin once-removed',
151        '9,9' => 'eighth cousin',
152        '9,10' => 'eighth cousin once-removed',
153        '10,0' => 'great-great-great-great-great-great-great-great-grandfather',
154        '10,1' => 'great-great-great-great-great-great-great-great-uncle',
155        '10,2' => 'first cousin eight-times-removed',
156        '10,3' => 'second cousin seven-times-removed',
157        '10,4' => 'third cousin six-times-removed',
158        '10,5' => 'fourth cousin five-times-removed',
159        '10,6' => 'fifth cousin four-times-removed',
160        '10,7' => 'sixth cousin three-times-removed',
161        '10,8' => 'seventh cousin twice-removed',
162        '10,9' => 'eighth cousin once-removed',
163        '10,10' => 'ninth cousin',
164        '11,1' => 'eighth great-uncle',
165        '12,1' => 'ninth great-uncle',
166        '12,2' => 'first cousin ten-times-removed',
167        '13,1' => 'tenth great-uncle',
168        '13,2' => 'first cousin eleven-times-removed',
169        '14,1' => 'eleventh great-uncle',
170        '15,1' => 'twelfth great-uncle',
171        '16,1' => 'thirteenth great-uncle',
172        '17,1' => 'fourteenth great-uncle',
173        '18,1' => 'fifteenth great-uncle',
174);
175
176Readonly::Hash my %EN_FEMALE_RELATIONSHIPS => (
177        '0,0' => 'self',
178        '0,1' => 'daughter',
179        '0,2' => 'granddaughter',
180        '0,3' => 'great-granddaughter',
181        '0,4' => 'great-great-granddaughter',
182        '0,5' => 'great-great-great-granddaughter',
183        '0,6' => 'great-great-great-great-granddaughter',
184        '0,7' => 'great-great-great-great-great-granddaughter',
185        '0,8' => 'great-great-great-great-great-great-granddaughter',
186        '0,9' => 'great-great-great-great-great-great-great-granddaughter',
187        '0,10' => 'great-great-great-great-great-great-great-great-granddaughter',
188        '1,0' => 'mother',
189        '1,1' => 'sister',
190        '1,2' => 'niece',
191        '1,3' => 'great-niece',
192        '1,4' => 'great-great-niece',
193        '1,5' => 'great-great-great-niece',
194        '1,6' => 'great-great-great-great-niece',
195        '1,7' => 'great-great-great-great-great-niece',
196        '1,8' => 'great-great-great-great-great-great-niece',
197        '1,9' => 'great-great-great-great-great-great-great-niece',
198        '1,10' => 'great-great-great-great-great-great-great-great-niece',
199        '2,0' => 'grandmother',
200        '2,1' => 'aunt',
201        '2,2' => 'first cousin',
202        '2,3' => 'first cousin once-removed',
203        '2,4' => 'first cousin twice-removed',
204        '2,5' => 'first cousin three-times-removed',
205        '2,6' => 'first cousin four-times-removed',
206        '2,7' => 'first cousin five-times-removed',
207        '2,8' => 'first cousin six-times-removed',
208        '2,9' => 'first cousin seven-times-removed',
209        '2,10' => 'first cousin eight-times-removed',
210        '3,0' => 'great-grandmother',
211        '3,1' => 'great-aunt',
212        '3,2' => 'first cousin once-removed',
213        '3,3' => 'second cousin',
214        '3,4' => 'second cousin once-removed',
215        '3,5' => 'second cousin twice-removed',
216        '3,6' => 'second cousin three-times-removed',
217        '3,7' => 'second cousin four-times-removed',
218        '3,8' => 'second cousin five-times-removed',
219        '3,9' => 'second cousin six-times-removed',
220        '3,10' => 'second cousin seven-times-removed',
221        '4,0' => 'great-great-grandmother',
222        '4,1' => 'great-great-aunt',
223        '4,2' => 'first cousin twice-removed',
224        '4,3' => 'second cousin once-removed',
225        '4,4' => 'third cousin',
226        '4,5' => 'third cousin once-removed',
227        '4,6' => 'third cousin twice-removed',
228        '4,7' => 'third cousin three-times-removed',
229        '4,8' => 'third cousin four-times-removed',
230        '4,9' => 'third cousin five-times-removed',
231        '4,10' => 'third cousin six-times-removed',
232        '5,0' => 'great-great-great-grandmother',
233        '5,1' => 'great-great-great-aunt',
234        '5,2' => 'first cousin three-times-removed',
235        '5,3' => 'second cousin twice-removed',
236        '5,4' => 'third cousin once-removed',
237        '5,5' => 'fourth cousin',
238        '5,6' => 'fourth cousin once-removed',
239        '5,7' => 'fourth cousin twice-removed',
240        '5,8' => 'fourth cousin three-times-removed',
241        '5,9' => 'fourth cousin four-times-removed',
242        '5,10' => 'fourth cousin five-times-removed',
243        '6,0' => 'great-great-great-great-grandmother',
244        '6,1' => 'great-great-great-great-aunt',
245        '6,2' => 'first cousin four-times-removed',
246        '6,3' => 'second cousin three-times-removed',
247        '6,4' => 'third cousin twice-removed',
248        '6,5' => 'fourth cousin once-removed',
249        '6,6' => 'fifth cousin',
250        '6,7' => 'fifth cousin once-removed',
251        '6,8' => 'fifth cousin twice-removed',
252        '6,9' => 'fifth cousin three-times-removed',
253        '6,10' => 'fifth cousin four-times-removed',
254        '7,0' => 'great-great-great-great-great-grandmother',
255        '7,1' => 'great-great-great-great-great-aunt',
256        '7,2' => 'first cousin five-times-removed',
257        '7,3' => 'second cousin four-times-removed',
258        '7,4' => 'third cousin three-times-removed',
259        '7,5' => 'fourth cousin twice-removed',
260        '7,6' => 'fifth cousin once-removed',
261        '7,7' => 'sixth cousin',
262        '7,8' => 'sixth cousin once-removed',
263        '7,9' => 'sixth cousin twice-removed',
264        '7,10' => 'sixth cousin three-times-removed',
265        '8,0' => 'great-great-great-great-great-great-grandmother',
266        '8,1' => 'great-great-great-great-great-great-aunt',
267        '8,2' => 'first cousin six-times-removed',
268        '8,3' => 'second cousin five-times-removed',
269        '8,4' => 'third cousin four-times-removed',
270        '8,5' => 'fourth cousin three-times-removed',
271        '8,6' => 'fifth cousin twice-removed',
272        '8,7' => 'sixth cousin once-removed',
273        '8,8' => 'seventh cousin',
274        '8,9' => 'seventh cousin once-removed',
275        '8,10' => 'seventh cousin twice-removed',
276        '9,0' => 'great-great-great-great-great-great-great-grandmother',
277        '9,1' => 'great-great-great-great-great-great-great-aunt',
278        '9,2' => 'first cousin seven-times-removed',
279        '9,3' => 'second cousin six-times-removed',
280        '9,4' => 'third cousin five-times-removed',
281        '9,5' => 'fourth cousin four-times-removed',
282        '9,6' => 'fifth cousin three-times-removed',
283        '9,7' => 'sixth cousin twice-removed',
284        '9,8' => 'seventh cousin once-removed',
285        '9,9' => 'eighth cousin',
286        '9,10' => 'eighth cousin once-removed',
287        '10,0' => 'great-great-great-great-great-great-great-great-grandmother',
288        '10,1' => 'great-great-great-great-great-great-great-great-aunt',
289        '10,2' => 'first cousin eight-times-removed',
290        '10,3' => 'second cousin seven-times-removed',
291        '10,4' => 'third cousin six-times-removed',
292        '10,5' => 'fourth cousin five-times-removed',
293        '10,6' => 'fifth cousin four-times-removed',
294        '10,7' => 'sixth cousin three-times-removed',
295        '10,8' => 'seventh cousin twice-removed',
296        '10,9' => 'eighth cousin once-removed',
297        '10,10' => 'ninth cousin',
298        '11,1' => 'eighth great-aunt',
299        '12,1' => 'ninth great-aunt',
300        '12,2' => 'first cousin ten-times-removed',
301        '13,1' => 'tenth great-aunt',
302        '13,2' => 'first cousin eleven-times-removed',
303        '14,1' => 'eleventh great-aunt',
304        '15,1' => 'twelfth great-aunt',
305        '16,1' => 'thirteenth great-aunt',
306        '17,1' => 'fourteenth great-aunt',
307        '18,1' => 'fifteenth great-aunt',
308);
309
310# ---------------------------------------------------------------------------
311# French relationship tables
312# ---------------------------------------------------------------------------
313
314Readonly::Hash my %FR_MALE_RELATIONSHIPS => (
315        '0,0' => 'soi-meme',
316        '0,1' => 'fils',
317        '0,2' => 'petit-fils',
318        '0,3' => 'arriere-petit-fils',
319        '0,4' => 'arriere-arriere-petit-fils',
320        '0,5' => 'arriere-arriere-arriere-petit-fils',
321        '0,6' => 'arriere-arriere-arriere-arriere-petit-fils',
322        '0,7' => 'arriere-arriere-arriere-arriere-arriere-petit-fils',
323        '0,8' => 'arriere-arriere-arriere-arriere-arriere-arriere-petit-fils',
324        '0,9' => 'arriere-arriere-arriere-arriere-arriere-arriere-arriere-petit-fils',
325        '0,10' => 'arriere-arriere-arriere-arriere-arriere-arriere-arriere-arriere-petit-fils',
326        '1,0' => 'pere',
327        '1,1' => "fr\N{U+00E8}re",
328        '1,2' => 'neveu',
329        '1,3' => 'grand-neveu',
330        '1,4' => 'arriere-grand-neveu',
331        '1,5' => 'arriere-arriere-grand-neveu',
332        '1,6' => 'arriere-arriere-arriere-grand-neveu',
333        '1,7' => 'arriere-arriere-arriere-arriere-grand-neveu',
334        '1,8' => 'arriere-arriere-arriere-arriere-arriere-grand-neveu',
335        '1,9' => 'arriere-arriere-arriere-arriere-arriere-arriere-grand-neveu',
336        '1,10' => 'arriere-arriere-arriere-arriere-arriere-arriere-arriere-grand-neveu',
337        '2,0' => 'grand-pere',
338        '2,1' => 'oncle',
339        '2,2' => 'cousin germain',
340        '2,3' => "cousin germain \N{U+00E9}loign\N{U+00E9} au 1er degr\N{U+00E9}",
341        '2,4' => 'cousin germain deux fois eloigne',
342        '2,5' => 'cousin germain trois fois eloigne',
343        '2,6' => 'cousin germain quatre fois eloigne',
344        '2,7' => 'cousin germain cinq fois eloigne',
345        '2,8' => 'cousin germain six fois eloigne',
346        '2,9' => 'cousin germain sept fois eloigne',
347        '2,10' => 'cousin germain huit fois eloigne',
348        '3,0' => 'arriere-grand-pere',
349        '3,1' => 'grand-oncle',
350        '3,2' => "cousin germain \N{U+00E9}loign\N{U+00E9} au 1er degr\N{U+00E9}",
351        '3,3' => 'cousin issu de germain',
352        '3,4' => 'cousin issu de germain une fois eloigne',
353        '3,5' => "cousin issu de germains \N{U+00E9}loign\N{U+00E9} au 2e degr\N{U+00E9}",
354        '3,6' => 'cousin issu de germain trois fois eloigne',
355        '3,7' => 'cousin issu de germain quatre fois eloigne',
356        '3,8' => 'cousin issu de germain cinq fois eloigne',
357        '3,9' => 'cousin issu de germain six fois eloigne',
358        '3,10' => 'cousin issu de germain sept fois eloigne',
359        '4,0' => 'arriere-arriere-grand-pere',
360        '4,1' => 'arriere-grand-oncle',
361        '4,2' => 'cousin germain deux fois eloigne',
362        '4,3' => 'cousin issu de germain une fois eloigne',
363        '4,4' => 'cousin au quatrieme degre',
364        '4,5' => 'cousin au quatrieme degre une fois eloigne',
365        '4,6' => 'cousin au quatrieme degre deux fois eloigne',
366        '4,7' => "petit-cousin \N{U+00E9}loign\N{U+00E9} au 3e degr\N{U+00E9}",
367        '4,8' => 'cousin au quatrieme degre quatre fois eloigne',
368        '4,9' => 'cousin au quatrieme degre cinq fois eloigne',
369        '4,10' => 'cousin au quatrieme degre six fois eloigne',
370        '5,0' => 'arriere-arriere-arriere-grand-pere',
371        '5,1' => 'arriere-arriere-grand-oncle',
372        '5,2' => 'cousin germain trois fois eloigne',
373        '5,3' => "cousin issu de germains \N{U+00E9}loign\N{U+00E9} au 2e degr\N{U+00E9}",
374        '5,4' => 'cousin au quatrieme degre une fois eloigne',
375        '5,5' => 'cousin au cinquieme degre',
376        '5,6' => "arri\N{U+00E8}re-petit-cousin \N{U+00E9}loign\N{U+00E9} au 1er degr\N{U+00E9}",
377        '5,7' => "arri\N{U+00E8}re-petit-cousin \N{U+00E9}loign\N{U+00E9} au 2e degr\N{U+00E9}",
378        '5,8' => 'cousin au cinquieme degre trois fois eloigne',
379        '5,9' => 'cousin au cinquieme degre quatre fois eloigne',
380        '5,10' => 'cousin au cinquieme degre cinq fois eloigne',
381        '6,0' => 'arriere-arriere-arriere-arriere-grand-pere',
382        '6,1' => 'arriere-arriere-arriere-grand-oncle',
383        '6,2' => 'cousin germain quatre fois eloigne',
384        '6,3' => 'cousin issu de germain trois fois eloigne',
385        '6,4' => 'cousin au quatrieme degre deux fois eloigne',
386        '6,5' => "arri\N{U+00E8}re-petit-cousin \N{U+00E9}loign\N{U+00E9} au 1er degr\N{U+00E9}",
387        '6,6' => "arri\N{U+00E8}re-arri\N{U+00E8}re-petit-cousin",
388        '6,7' => 'cousin au sixieme degre une fois eloigne',
389        '6,8' => 'cousin au sixieme degre deux fois eloigne',
390        '6,9' => 'cousin au sixieme degre trois fois eloigne',
391        '6,10' => 'cousin au sixieme degre quatre fois eloigne',
392        '7,0' => 'arriere-arriere-arriere-arriere-arriere-grand-pere',
393        '7,1' => 'arriere-arriere-arriere-arriere-grand-oncle',
394        '7,2' => 'cousin germain cinq fois eloigne',
395        '7,3' => 'cousin issu de germain quatre fois eloigne',
396        '7,4' => "petit-cousin \N{U+00E9}loign\N{U+00E9} au 3e degr\N{U+00E9}",
397        '7,5' => "arri\N{U+00E8}re-petit-cousin \N{U+00E9}loign\N{U+00E9} au 2e degr\N{U+00E9}",
398        '7,6' => 'cousin au sixieme degre une fois eloigne',
399        '7,7' => "sixi\N{U+00E8}me cousin",
400        '7,8' => "sixi\N{U+00E8}me cousin une fois \N{U+00E9}loign\N{U+00E9}",
401        '7,9' => 'cousin au septieme degre deux fois eloigne',
402        '7,10' => 'cousin au septieme degre trois fois eloigne',
403        '8,0' => 'arriere-arriere-arriere-arriere-arriere-arriere-grand-pere',
404        '8,1' => 'arriere-arriere-arriere-arriere-arriere-grand-oncle',
405        '8,2' => 'cousin germain six fois eloigne',
406        '8,3' => 'cousin issu de germain cinq fois eloigne',
407        '8,4' => 'cousin au quatrieme degre quatre fois eloigne',
408        '8,5' => 'cousin au cinquieme degre trois fois eloigne',
409        '8,6' => 'cousin au sixieme degre deux fois eloigne',
410        '8,7' => "sixi\N{U+00E8}me cousin une fois \N{U+00E9}loign\N{U+00E9}",
411        '8,8' => 'cousin au huitieme degre',
412        '8,9' => 'cousin au huitieme degre une fois eloigne',
413        '8,10' => 'cousin au huitieme degre deux fois eloigne',
414        '9,0' => 'arriere-arriere-arriere-arriere-arriere-arriere-arriere-grand-pere',
415        '9,1' => 'arriere-arriere-arriere-arriere-arriere-arriere-grand-oncle',
416        '9,2' => 'cousin germain sept fois eloigne',
417        '9,3' => 'cousin issu de germain six fois eloigne',
418        '9,4' => 'cousin au quatrieme degre cinq fois eloigne',
419        '9,5' => 'cousin au cinquieme degre quatre fois eloigne',
420        '9,6' => 'cousin au sixieme degre trois fois eloigne',
421        '9,7' => 'cousin au septieme degre deux fois eloigne',
422        '9,8' => 'cousin au huitieme degre une fois eloigne',
423        '9,9' => 'cousin au neuvieme degre',
424        '9,10' => 'cousin au neuvieme degre une fois eloigne',
425        '10,0' => 'arriere-arriere-arriere-arriere-arriere-arriere-arriere-arriere-grand-pere',
426        '10,1' => 'arriere-arriere-arriere-arriere-arriere-arriere-arriere-grand-oncle',
427        '10,2' => 'cousin germain huit fois eloigne',
428        '10,3' => 'cousin issu de germain sept fois eloigne',
429        '10,4' => 'cousin au quatrieme degre six fois eloigne',
430        '10,5' => 'cousin au cinquieme degre cinq fois eloigne',
431        '10,6' => 'cousin au sixieme degre quatre fois eloigne',
432        '10,7' => 'cousin au septieme degre trois fois eloigne',
433        '10,8' => 'cousin au huitieme degre deux fois eloigne',
434        '10,9' => 'cousin au neuvieme degre une fois eloigne',
435        '10,10' => 'cousin au dixieme degre',
436        '11,1' => "huiti\N{U+00E8}me grand-oncle",
437        '12,1' => "neuvi\N{U+00E8}me grand-oncle",
438        '13,1' => "dixi\N{U+00E8}me grand-oncle",
439        '14,1' => "onzi\N{U+00E8}me grand-oncle",
440        '15,1' => "douzi\N{U+00E8}me grand-oncle",
441        '16,1' => "treizi\N{U+00E8}me grand-oncle",
442        '17,1' => "quatorzi\N{U+00E8}me grand-oncle",
443        '18,1' => "quinzi\N{U+00E8}me grand-oncle",
444);
445
446Readonly::Hash my %FR_FEMALE_RELATIONSHIPS => (
447        '0,0' => 'soi-meme',
448        '0,1' => 'fille',
449        '0,2' => 'petite-fille',
450        '0,3' => 'arriere-petite-fille',
451        '0,4' => 'arriere-arriere-petite-fille',
452        '0,5' => 'arriere-arriere-arriere-petite-fille',
453        '0,6' => 'arriere-arriere-arriere-arriere-petite-fille',
454        '0,7' => 'arriere-arriere-arriere-arriere-arriere-petite-fille',
455        '0,8' => 'arriere-arriere-arriere-arriere-arriere-arriere-petite-fille',
456        '0,9' => 'arriere-arriere-arriere-arriere-arriere-arriere-arriere-petite-fille',
457        '0,10' => 'arriere-arriere-arriere-arriere-arriere-arriere-arriere-arriere-petite-fille',
458        '1,0' => 'mere',
459        '1,1' => "s\N{U+0153}ur",
460        '1,2' => "ni\N{U+00E8}ce",
461        '1,3' => 'grand-niece',
462        '1,4' => 'arriere-grand-niece',
463        '1,5' => 'arriere-arriere-grand-niece',
464        '1,6' => 'arriere-arriere-arriere-grand-niece',
465        '1,7' => 'arriere-arriere-arriere-arriere-grand-niece',
466        '1,8' => 'arriere-arriere-arriere-arriere-arriere-grand-niece',
467        '1,9' => 'arriere-arriere-arriere-arriere-arriere-arriere-grand-niece',
468        '1,10' => 'arriere-arriere-arriere-arriere-arriere-arriere-arriere-grand-niece',
469        '2,0' => 'grand-mere',
470        '2,1' => 'tante',
471        '2,2' => 'cousine germaine',
472        '2,3' => "cousine germaine \N{U+00E9}loign\N{U+00E9}e au 1er degr\N{U+00E9}",
473        '2,4' => 'cousine germaine deux fois eloignee',
474        '2,5' => 'cousine germaine trois fois eloignee',
475        '2,6' => 'cousine germaine quatre fois eloignee',
476        '2,7' => 'cousine germaine cinq fois eloignee',
477        '2,8' => 'cousine germaine six fois eloignee',
478        '2,9' => 'cousine germaine sept fois eloignee',
479        '2,10' => 'cousine germaine huit fois eloignee',
480        '3,0' => 'arriere-grand-mere',
481        '3,1' => 'grand-tante',
482        '3,2' => "cousine germaine \N{U+00E9}loign\N{U+00E9}e au 1er degr\N{U+00E9}",
483        '3,3' => 'cousine issue de germaine',
484        '3,4' => 'cousine issue de germaine une fois eloignee',
485        '3,5' => "cousine issue de germains \N{U+00E9}loign\N{U+00E9}e au 2e degr\N{U+00E9}",
486        '3,6' => 'cousine issue de germaine trois fois eloignee',
487        '3,7' => 'cousine issue de germaine quatre fois eloignee',
488        '3,8' => 'cousine issue de germaine cinq fois eloignee',
489        '3,9' => 'cousine issue de germaine six fois eloignee',
490        '3,10' => 'cousine issue de germaine sept fois eloignee',
491        '4,0' => 'arriere-arriere-grand-mere',
492        '4,1' => 'arriere-grand-tante',
493        '4,2' => 'cousine germaine deux fois eloignee',
494        '4,3' => 'cousine issue de germaine une fois eloignee',
495        '4,4' => 'cousine au quatrieme degre',
496        '4,5' => 'cousine au quatrieme degre une fois eloignee',
497        '4,6' => 'cousine au quatrieme degre deux fois eloignee',
498        '4,7' => "petite-cousine \N{U+00E9}loign\N{U+00E9}e au 3e degr\N{U+00E9}",
499        '4,8' => 'cousine au quatrieme degre quatre fois eloignee',
500        '4,9' => 'cousine au quatrieme degre cinq fois eloignee',
501        '4,10' => 'cousine au quatrieme degre six fois eloignee',
502        '5,0' => 'arriere-arriere-arriere-grand-mere',
503        '5,1' => 'arriere-arriere-grand-tante',
504        '5,2' => 'cousine germaine trois fois eloignee',
505        '5,3' => "cousine issue de germains \N{U+00E9}loign\N{U+00E9}e au 2e degr\N{U+00E9}",
506        '5,4' => 'cousine au quatrieme degre une fois eloignee',
507        '5,5' => 'cousine au cinquieme degre',
508        '5,6' => "arri\N{U+00E8}re-petite-cousine \N{U+00E9}loign\N{U+00E9}e au 1er degr\N{U+00E9}",
509        '5,7' => "arri\N{U+00E8}re-petite-cousine \N{U+00E9}loign\N{U+00E9}e au 2e degr\N{U+00E9}",
510        '5,8' => 'cousine au cinquieme degre trois fois eloignee',
511        '5,9' => 'cousine au cinquieme degre quatre fois eloignee',
512        '5,10' => 'cousine au cinquieme degre cinq fois eloignee',
513        '6,0' => 'arriere-arriere-arriere-arriere-grand-mere',
514        '6,1' => 'arriere-arriere-arriere-grand-tante',
515        '6,2' => 'cousine germaine quatre fois eloignee',
516        '6,3' => 'cousine issue de germaine trois fois eloignee',
517        '6,4' => 'cousine au quatrieme degre deux fois eloignee',
518        '6,5' => "arri\N{U+00E8}re-petite-cousine \N{U+00E9}loign\N{U+00E9}e au 1er degr\N{U+00E9}",
519        '6,6' => "arri\N{U+00E8}re-arri\N{U+00E8}re-petite-cousine",
520        '6,7' => 'cousine au sixieme degre une fois eloignee',
521        '6,8' => 'cousine au sixieme degre deux fois eloignee',
522        '6,9' => 'cousine au sixieme degre trois fois eloignee',
523        '6,10' => 'cousine au sixieme degre quatre fois eloignee',
524        '7,0' => 'arriere-arriere-arriere-arriere-arriere-grand-mere',
525        '7,1' => 'arriere-arriere-arriere-arriere-grand-tante',
526        '7,2' => 'cousine germaine cinq fois eloignee',
527        '7,3' => 'cousine issue de germaine quatre fois eloignee',
528        '7,4' => "petite-cousine \N{U+00E9}loign\N{U+00E9}e au 3e degr\N{U+00E9}",
529        '7,5' => "arri\N{U+00E8}re-petite-cousine \N{U+00E9}loign\N{U+00E9}e au 2e degr\N{U+00E9}",
530        '7,6' => 'cousine au sixieme degre une fois eloignee',
531        '7,7' => "sixi\N{U+00E8}me cousine",
532        '7,8' => "sixi\N{U+00E8}me cousine une fois \N{U+00E9}loign\N{U+00E9}e",
533        '7,9' => 'cousine au septieme degre deux fois eloignee',
534        '7,10' => 'cousine au septieme degre trois fois eloignee',
535        '8,0' => 'arriere-arriere-arriere-arriere-arriere-arriere-grand-mere',
536        '8,1' => 'arriere-arriere-arriere-arriere-arriere-grand-tante',
537        '8,2' => 'cousine germaine six fois eloignee',
538        '8,3' => 'cousine issue de germaine cinq fois eloignee',
539        '8,4' => 'cousine au quatrieme degre quatre fois eloignee',
540        '8,5' => 'cousine au cinquieme degre trois fois eloignee',
541        '8,6' => 'cousine au sixieme degre deux fois eloignee',
542        '8,7' => "sixi\N{U+00E8}me cousine une fois \N{U+00E9}loign\N{U+00E9}e",
543        '8,8' => 'cousine au huitieme degre',
544        '8,9' => 'cousine au huitieme degre une fois eloignee',
545        '8,10' => 'cousine au huitieme degre deux fois eloignee',
546        '9,0' => 'arriere-arriere-arriere-arriere-arriere-arriere-arriere-grand-mere',
547        '9,1' => 'arriere-arriere-arriere-arriere-arriere-arriere-grand-tante',
548        '9,2' => 'cousine germaine sept fois eloignee',
549        '9,3' => 'cousine issue de germaine six fois eloignee',
550        '9,4' => 'cousine au quatrieme degre cinq fois eloignee',
551        '9,5' => 'cousine au cinquieme degre quatre fois eloignee',
552        '9,6' => 'cousine au sixieme degre trois fois eloignee',
553        '9,7' => 'cousine au septieme degre deux fois eloignee',
554        '9,8' => 'cousine au huitieme degre une fois eloignee',
555        '9,9' => 'cousine au neuvieme degre',
556        '9,10' => 'cousine au neuvieme degre une fois eloignee',
557        '10,0' => 'arriere-arriere-arriere-arriere-arriere-arriere-arriere-arriere-grand-mere',
558        '10,1' => 'arriere-arriere-arriere-arriere-arriere-arriere-arriere-grand-tante',
559        '10,2' => 'cousine germaine huit fois eloignee',
560        '10,3' => 'cousine issue de germaine sept fois eloignee',
561        '10,4' => 'cousine au quatrieme degre six fois eloignee',
562        '10,5' => 'cousine au cinquieme degre cinq fois eloignee',
563        '10,6' => 'cousine au sixieme degre quatre fois eloignee',
564        '10,7' => 'cousine au septieme degre trois fois eloignee',
565        '10,8' => 'cousine au huitieme degre deux fois eloignee',
566        '10,9' => 'cousine au neuvieme degre une fois eloignee',
567        '10,10' => 'cousine au dixieme degre',
568        '11,1' => "huiti\N{U+00E8}me grand-tante",
569        '12,1' => "neuvi\N{U+00E8}me grand-tante",
570        '13,1' => "dixi\N{U+00E8}me grand-tante",
571        '14,1' => "onzi\N{U+00E8}me grand-tante",
572        '15,1' => "douzi\N{U+00E8}me grand-tante",
573        '16,1' => "treizi\N{U+00E8}me grand-tante",
574        '17,1' => "quatorzi\N{U+00E8}me grand-tante",
575        '18,1' => "quinzi\N{U+00E8}me grand-tante",
576);
577
578# ---------------------------------------------------------------------------
579# German relationship tables
580# ---------------------------------------------------------------------------
581
582Readonly::Hash my %DE_MALE_RELATIONSHIPS => (
583        '0,0' => 'sich selbst',
584        '0,1' => 'Sohn',
585        '0,2' => 'Enkel',
586        '0,3' => 'Urenkel',
587        '0,4' => 'Ururenkel',
588        '0,5' => 'Urururenkel',
589        '0,6' => 'Ururururenkel',
590        '0,7' => 'Urururururenkel',
591        '0,8' => 'Ururururururenkel',
592        '0,9' => 'Urururururururenkel',
593        '0,10' => 'Ururururururururenkel',
594        '1,0' => 'Vater',
595        '1,1' => 'Bruder',
596        '1,2' => 'Neffe',
597        '1,3' => "Gro\N{U+00DF}neffe",
598        '1,4' => 'Urgrossneffe',
599        '1,5' => 'Ururgrossneffe',
600        '1,6' => 'Urururgrossneffe',
601        '1,7' => 'Ururururgrossneffe',
602        '1,8' => 'Urururururgrossneffe',
603        '1,9' => 'Ururururururgrossneffe',
604        '1,10' => 'Urururururururgrossneffe',
605        '2,0' => "Gro\N{U+00DF}vater",
606        '2,1' => 'Onkel',
607        '2,2' => 'Cousin',
608        '2,3' => 'Cousin einmal entfernt',
609        '2,4' => 'Cousin zweimal entfernt',
610        '2,5' => 'Cousin dreimal entfernt',
611        '2,6' => 'Cousin viermal entfernt',
612        '2,7' => 'Cousin fuenfmal entfernt',
613        '2,8' => 'Cousin sechsmal entfernt',
614        '2,9' => 'Cousin siebenmal entfernt',
615        '2,10' => 'Cousin achtmal entfernt',
616        '3,0' => 'Urgrossvater',
617        '3,1' => "Gro\N{U+00DF}onkel",
618        '3,2' => 'Cousin einmal entfernt',
619        '3,3' => 'Cousin zweiten Grades',
620        '3,4' => 'Cousin zweiten Grades einmal entfernt',
621        '3,5' => 'Cousin zweiten Grades zweimal entfernt',
622        '3,6' => 'Cousin zweiten Grades dreimal entfernt',
623        '3,7' => 'Cousin zweiten Grades viermal entfernt',
624        '3,8' => 'Cousin zweiten Grades fuenfmal entfernt',
625        '3,9' => 'Cousin zweiten Grades sechsmal entfernt',
626        '3,10' => 'Cousin zweiten Grades siebenmal entfernt',
627        '4,0' => 'Ururgrossvater',
628        '4,1' => 'Urgrossonkel',
629        '4,2' => 'Cousin zweimal entfernt',
630        '4,3' => 'Cousin zweiten Grades einmal entfernt',
631        '4,4' => 'Cousin dritten Grades',
632        '4,5' => 'Cousin dritten Grades einmal entfernt',
633        '4,6' => 'Cousin dritten Grades zweimal entfernt',
634        '4,7' => 'Cousin dritten Grades dreimal entfernt',
635        '4,8' => 'Cousin dritten Grades viermal entfernt',
636        '4,9' => 'Cousin dritten Grades fuenfmal entfernt',
637        '4,10' => 'Cousin dritten Grades sechsmal entfernt',
638        '5,0' => 'Urururgrossvater',
639        '5,1' => 'Ururgrossonkel',
640        '5,2' => 'Cousin dreimal entfernt',
641        '5,3' => 'Cousin zweiten Grades zweimal entfernt',
642        '5,4' => 'Cousin dritten Grades einmal entfernt',
643        '5,5' => 'Cousin vierten Grades',
644        '5,6' => 'Cousin vierten Grades einmal entfernt',
645        '5,7' => 'Cousin vierten Grades zweimal entfernt',
646        '5,8' => 'Cousin vierten Grades dreimal entfernt',
647        '5,9' => 'Cousin vierten Grades viermal entfernt',
648        '5,10' => 'Cousin vierten Grades fuenfmal entfernt',
649        '6,0' => 'Ururururgrossvater',
650        '6,1' => 'Urururgrossonkel',
651        '6,2' => 'Cousin viermal entfernt',
652        '6,3' => 'Cousin zweiten Grades dreimal entfernt',
653        '6,4' => 'Cousin dritten Grades zweimal entfernt',
654        '6,5' => 'Cousin vierten Grades einmal entfernt',
655        '6,6' => 'Cousin fuenften Grades',
656        '6,7' => 'Cousin fuenften Grades einmal entfernt',
657        '6,8' => 'Cousin fuenften Grades zweimal entfernt',
658        '6,9' => 'Cousin fuenften Grades dreimal entfernt',
659        '6,10' => 'Cousin fuenften Grades viermal entfernt',
660        '7,0' => 'Urururururgrossvater',
661        '7,1' => 'Ururururgrossonkel',
662        '7,2' => 'Cousin fuenfmal entfernt',
663        '7,3' => 'Cousin zweiten Grades viermal entfernt',
664        '7,4' => 'Cousin dritten Grades dreimal entfernt',
665        '7,5' => 'Cousin vierten Grades zweimal entfernt',
666        '7,6' => 'Cousin fuenften Grades einmal entfernt',
667        '7,7' => 'Cousin sechsten Grades',
668        '7,8' => 'Cousin sechsten Grades einmal entfernt',
669        '7,9' => 'Cousin sechsten Grades zweimal entfernt',
670        '7,10' => 'Cousin sechsten Grades dreimal entfernt',
671        '8,0' => 'Ururururururgrossvater',
672        '8,1' => 'Urururururgrossonkel',
673        '8,2' => 'Cousin sechsmal entfernt',
674        '8,3' => 'Cousin zweiten Grades fuenfmal entfernt',
675        '8,4' => 'Cousin dritten Grades viermal entfernt',
676        '8,5' => 'Cousin vierten Grades dreimal entfernt',
677        '8,6' => 'Cousin fuenften Grades zweimal entfernt',
678        '8,7' => 'Cousin sechsten Grades einmal entfernt',
679        '8,8' => 'Cousin siebten Grades',
680        '8,9' => 'Cousin siebten Grades einmal entfernt',
681        '8,10' => 'Cousin siebten Grades zweimal entfernt',
682        '9,0' => 'Urururururururgrossvater',
683        '9,1' => 'Ururururururgrossonkel',
684        '9,2' => 'Cousin siebenmal entfernt',
685        '9,3' => 'Cousin zweiten Grades sechsmal entfernt',
686        '9,4' => 'Cousin dritten Grades fuenfmal entfernt',
687        '9,5' => 'Cousin vierten Grades viermal entfernt',
688        '9,6' => 'Cousin fuenften Grades dreimal entfernt',
689        '9,7' => 'Cousin sechsten Grades zweimal entfernt',
690        '9,8' => 'Cousin siebten Grades einmal entfernt',
691        '9,9' => 'Cousin achten Grades',
692        '9,10' => 'Cousin achten Grades einmal entfernt',
693        '10,0' => 'Ururururururururgrossvater',
694        '10,1' => 'Urururururururgrossonkel',
695        '10,2' => 'Cousin achtmal entfernt',
696        '10,3' => 'Cousin zweiten Grades siebenmal entfernt',
697        '10,4' => 'Cousin dritten Grades sechsmal entfernt',
698        '10,5' => 'Cousin vierten Grades fuenfmal entfernt',
699        '10,6' => 'Cousin fuenften Grades viermal entfernt',
700        '10,7' => 'Cousin sechsten Grades dreimal entfernt',
701        '10,8' => 'Cousin siebten Grades zweimal entfernt',
702        '10,9' => 'Cousin achten Grades einmal entfernt',
703        '10,10' => 'Cousin neunten Grades',
704        '11,1' => 'achtens grossonkel',
705        '12,1' => 'neuntens grossonkel',
706        '13,1' => 'zehntens grossonkel',
707        '14,1' => 'elftens grossonkel',
708        '15,1' => 'zwoelftens grossonkel',
709        '16,1' => 'dreizehntens grossonkel',
710        '17,1' => 'vierzehntens grossonkel',
711        '18,1' => 'fuenfzehntens grossonkel',
712);
713
714Readonly::Hash my %DE_FEMALE_RELATIONSHIPS => (
715        '0,0' => 'sich selbst',
716        '0,1' => 'Tochter',
717        '0,2' => 'Enkelin',
718        '0,3' => 'Urenkelin',
719        '0,4' => 'Ururenkelin',
720        '0,5' => 'Urururenkelin',
721        '0,6' => 'Ururururenkelin',
722        '0,7' => 'Urururururenkelin',
723        '0,8' => 'Ururururururenkelin',
724        '0,9' => 'Urururururururenkelin',
725        '0,10' => 'Ururururururururenkelin',
726        '1,0' => 'Mutter',
727        '1,1' => 'Schwester',
728        '1,2' => 'Nichte',
729        '1,3' => "Gro\N{U+00DF}nichte",
730        '1,4' => 'Urgrossnichte',
731        '1,5' => 'Ururgrossnichte',
732        '1,6' => 'Urururgrossnichte',
733        '1,7' => 'Ururururgrossnichte',
734        '1,8' => 'Urururururgrossnichte',
735        '1,9' => 'Ururururururgrossnichte',
736        '1,10' => 'Urururururururgrossnichte',
737        '2,0' => "Gro\N{U+00DF}mutter",
738        '2,1' => 'Tante',
739        '2,2' => 'Cousine',
740        '2,3' => 'Cousine einmal entfernt',
741        '2,4' => 'Cousine zweimal entfernt',
742        '2,5' => 'Cousine dreimal entfernt',
743        '2,6' => 'Cousine viermal entfernt',
744        '2,7' => 'Cousine fuenfmal entfernt',
745        '2,8' => 'Cousine sechsmal entfernt',
746        '2,9' => 'Cousine siebenmal entfernt',
747        '2,10' => 'Cousine achtmal entfernt',
748        '3,0' => 'Urgrossmutter',
749        '3,1' => "Gro\N{U+00DF}tante",
750        '3,2' => 'Cousine einmal entfernt',
751        '3,3' => 'Cousine zweiten Grades',
752        '3,4' => 'Cousine zweiten Grades einmal entfernt',
753        '3,5' => 'Cousine zweiten Grades zweimal entfernt',
754        '3,6' => 'Cousine zweiten Grades dreimal entfernt',
755        '3,7' => 'Cousine zweiten Grades viermal entfernt',
756        '3,8' => 'Cousine zweiten Grades fuenfmal entfernt',
757        '3,9' => 'Cousine zweiten Grades sechsmal entfernt',
758        '3,10' => 'Cousine zweiten Grades siebenmal entfernt',
759        '4,0' => 'Ururgrossmutter',
760        '4,1' => 'Urgrosstante',
761        '4,2' => 'Cousine zweimal entfernt',
762        '4,3' => 'Cousine zweiten Grades einmal entfernt',
763        '4,4' => 'Cousine dritten Grades',
764        '4,5' => 'Cousine dritten Grades einmal entfernt',
765        '4,6' => 'Cousine dritten Grades zweimal entfernt',
766        '4,7' => 'Cousine dritten Grades dreimal entfernt',
767        '4,8' => 'Cousine dritten Grades viermal entfernt',
768        '4,9' => 'Cousine dritten Grades fuenfmal entfernt',
769        '4,10' => 'Cousine dritten Grades sechsmal entfernt',
770        '5,0' => 'Urururgrossmutter',
771        '5,1' => 'Ururgrosstante',
772        '5,2' => 'Cousine dreimal entfernt',
773        '5,3' => 'Cousine zweiten Grades zweimal entfernt',
774        '5,4' => 'Cousine dritten Grades einmal entfernt',
775        '5,5' => 'Cousine vierten Grades',
776        '5,6' => 'Cousine vierten Grades einmal entfernt',
777        '5,7' => 'Cousine vierten Grades zweimal entfernt',
778        '5,8' => 'Cousine vierten Grades dreimal entfernt',
779        '5,9' => 'Cousine vierten Grades viermal entfernt',
780        '5,10' => 'Cousine vierten Grades fuenfmal entfernt',
781        '6,0' => 'Ururururgrossmutter',
782        '6,1' => 'Urururgrosstante',
783        '6,2' => 'Cousine viermal entfernt',
784        '6,3' => 'Cousine zweiten Grades dreimal entfernt',
785        '6,4' => 'Cousine dritten Grades zweimal entfernt',
786        '6,5' => 'Cousine vierten Grades einmal entfernt',
787        '6,6' => 'Cousine fuenften Grades',
788        '6,7' => 'Cousine fuenften Grades einmal entfernt',
789        '6,8' => 'Cousine fuenften Grades zweimal entfernt',
790        '6,9' => 'Cousine fuenften Grades dreimal entfernt',
791        '6,10' => 'Cousine fuenften Grades viermal entfernt',
792        '7,0' => 'Urururururgrossmutter',
793        '7,1' => 'Ururururgrosstante',
794        '7,2' => 'Cousine fuenfmal entfernt',
795        '7,3' => 'Cousine zweiten Grades viermal entfernt',
796        '7,4' => 'Cousine dritten Grades dreimal entfernt',
797        '7,5' => 'Cousine vierten Grades zweimal entfernt',
798        '7,6' => 'Cousine fuenften Grades einmal entfernt',
799        '7,7' => 'Cousine sechsten Grades',
800        '7,8' => 'Cousine sechsten Grades einmal entfernt',
801        '7,9' => 'Cousine sechsten Grades zweimal entfernt',
802        '7,10' => 'Cousine sechsten Grades dreimal entfernt',
803        '8,0' => 'Ururururururgrossmutter',
804        '8,1' => 'Urururururgrosstante',
805        '8,2' => 'Cousine sechsmal entfernt',
806        '8,3' => 'Cousine zweiten Grades fuenfmal entfernt',
807        '8,4' => 'Cousine dritten Grades viermal entfernt',
808        '8,5' => 'Cousine vierten Grades dreimal entfernt',
809        '8,6' => 'Cousine fuenften Grades zweimal entfernt',
810        '8,7' => 'Cousine sechsten Grades einmal entfernt',
811        '8,8' => 'Cousine siebten Grades',
812        '8,9' => 'Cousine siebten Grades einmal entfernt',
813        '8,10' => 'Cousine siebten Grades zweimal entfernt',
814        '9,0' => 'Urururururururgrossmutter',
815        '9,1' => 'Ururururururgrosstante',
816        '9,2' => 'Cousine siebenmal entfernt',
817        '9,3' => 'Cousine zweiten Grades sechsmal entfernt',
818        '9,4' => 'Cousine dritten Grades fuenfmal entfernt',
819        '9,5' => 'Cousine vierten Grades viermal entfernt',
820        '9,6' => 'Cousine fuenften Grades dreimal entfernt',
821        '9,7' => 'Cousine sechsten Grades zweimal entfernt',
822        '9,8' => 'Cousine siebten Grades einmal entfernt',
823        '9,9' => 'Cousine achten Grades',
824        '9,10' => 'Cousine achten Grades einmal entfernt',
825        '10,0' => 'Ururururururururgrossmutter',
826        '10,1' => 'Urururururururgrosstante',
827        '10,2' => 'Cousine achtmal entfernt',
828        '10,3' => 'Cousine zweiten Grades siebenmal entfernt',
829        '10,4' => 'Cousine dritten Grades sechsmal entfernt',
830        '10,5' => 'Cousine vierten Grades fuenfmal entfernt',
831        '10,6' => 'Cousine fuenften Grades viermal entfernt',
832        '10,7' => 'Cousine sechsten Grades dreimal entfernt',
833        '10,8' => 'Cousine siebten Grades zweimal entfernt',
834        '10,9' => 'Cousine achten Grades einmal entfernt',
835        '10,10' => 'Cousine neunten Grades',
836        '11,1' => 'achtens grosstante',
837        '12,1' => 'neuntens grosstante',
838        '13,1' => 'zehntens grosstante',
839        '14,1' => 'elftens grosstante',
840        '15,1' => 'zwoelftens grosstante',
841        '16,1' => 'dreizehntens grosstante',
842        '17,1' => 'vierzehntens grosstante',
843        '18,1' => 'fuenfzehntens grosstante',
844);
845
846# ---------------------------------------------------------------------------
847# Swiss German (de-CH) relationship tables
848# Uses 'ss' instead of Eszett (\N{U+00DF}); Switzerland abolished ß in 1934
849# ---------------------------------------------------------------------------
850
851Readonly::Hash my %DE_CH_MALE_RELATIONSHIPS => (
852        '0,0' => 'sich selbst',
853        '0,1' => 'Sohn',
854        '0,2' => 'Enkel',
855        '0,3' => 'Urenkel',
856        '0,4' => 'Ururenkel',
857        '0,5' => 'Urururenkel',
858        '0,6' => 'Ururururenkel',
859        '0,7' => 'Urururururenkel',
860        '0,8' => 'Ururururururenkel',
861        '0,9' => 'Urururururururenkel',
862        '0,10' => 'Ururururururururenkel',
863        '1,0' => 'Vater',
864        '1,1' => 'Bruder',
865        '1,2' => 'Neffe',
866        '1,3' => 'Grossneffe',
867        '1,4' => 'Urgrossneffe',
868        '1,5' => 'Ururgrossneffe',
869        '1,6' => 'Urururgrossneffe',
870        '1,7' => 'Ururururgrossneffe',
871        '1,8' => 'Urururururgrossneffe',
872        '1,9' => 'Ururururururgrossneffe',
873        '1,10' => 'Urururururururgrossneffe',
874        '2,0' => 'Grossvater',
875        '2,1' => 'Onkel',
876        '2,2' => 'Cousin',
877        '2,3' => 'Cousin einmal entfernt',
878        '2,4' => 'Cousin zweimal entfernt',
879        '2,5' => 'Cousin dreimal entfernt',
880        '2,6' => 'Cousin viermal entfernt',
881        '2,7' => 'Cousin fuenfmal entfernt',
882        '2,8' => 'Cousin sechsmal entfernt',
883        '2,9' => 'Cousin siebenmal entfernt',
884        '2,10' => 'Cousin achtmal entfernt',
885        '3,0' => 'Urgrossvater',
886        '3,1' => 'Grossonkel',
887        '3,2' => 'Cousin einmal entfernt',
888        '3,3' => 'Cousin zweiten Grades',
889        '3,4' => 'Cousin zweiten Grades einmal entfernt',
890        '3,5' => 'Cousin zweiten Grades zweimal entfernt',
891        '3,6' => 'Cousin zweiten Grades dreimal entfernt',
892        '3,7' => 'Cousin zweiten Grades viermal entfernt',
893        '3,8' => 'Cousin zweiten Grades fuenfmal entfernt',
894        '3,9' => 'Cousin zweiten Grades sechsmal entfernt',
895        '3,10' => 'Cousin zweiten Grades siebenmal entfernt',
896        '4,0' => 'Ururgrossvater',
897        '4,1' => 'Urgrossonkel',
898        '4,2' => 'Cousin zweimal entfernt',
899        '4,3' => 'Cousin zweiten Grades einmal entfernt',
900        '4,4' => 'Cousin dritten Grades',
901        '4,5' => 'Cousin dritten Grades einmal entfernt',
902        '4,6' => 'Cousin dritten Grades zweimal entfernt',
903        '4,7' => 'Cousin dritten Grades dreimal entfernt',
904        '4,8' => 'Cousin dritten Grades viermal entfernt',
905        '4,9' => 'Cousin dritten Grades fuenfmal entfernt',
906        '4,10' => 'Cousin dritten Grades sechsmal entfernt',
907        '5,0' => 'Urururgrossvater',
908        '5,1' => 'Ururgrossonkel',
909        '5,2' => 'Cousin dreimal entfernt',
910        '5,3' => 'Cousin zweiten Grades zweimal entfernt',
911        '5,4' => 'Cousin dritten Grades einmal entfernt',
912        '5,5' => 'Cousin vierten Grades',
913        '5,6' => 'Cousin vierten Grades einmal entfernt',
914        '5,7' => 'Cousin vierten Grades zweimal entfernt',
915        '5,8' => 'Cousin vierten Grades dreimal entfernt',
916        '5,9' => 'Cousin vierten Grades viermal entfernt',
917        '5,10' => 'Cousin vierten Grades fuenfmal entfernt',
918        '6,0' => 'Ururururgrossvater',
919        '6,1' => 'Urururgrossonkel',
920        '6,2' => 'Cousin viermal entfernt',
921        '6,3' => 'Cousin zweiten Grades dreimal entfernt',
922        '6,4' => 'Cousin dritten Grades zweimal entfernt',
923        '6,5' => 'Cousin vierten Grades einmal entfernt',
924        '6,6' => 'Cousin fuenften Grades',
925        '6,7' => 'Cousin fuenften Grades einmal entfernt',
926        '6,8' => 'Cousin fuenften Grades zweimal entfernt',
927        '6,9' => 'Cousin fuenften Grades dreimal entfernt',
928        '6,10' => 'Cousin fuenften Grades viermal entfernt',
929        '7,0' => 'Urururururgrossvater',
930        '7,1' => 'Ururururgrossonkel',
931        '7,2' => 'Cousin fuenfmal entfernt',
932        '7,3' => 'Cousin zweiten Grades viermal entfernt',
933        '7,4' => 'Cousin dritten Grades dreimal entfernt',
934        '7,5' => 'Cousin vierten Grades zweimal entfernt',
935        '7,6' => 'Cousin fuenften Grades einmal entfernt',
936        '7,7' => 'Cousin sechsten Grades',
937        '7,8' => 'Cousin sechsten Grades einmal entfernt',
938        '7,9' => 'Cousin sechsten Grades zweimal entfernt',
939        '7,10' => 'Cousin sechsten Grades dreimal entfernt',
940        '8,0' => 'Ururururururgrossvater',
941        '8,1' => 'Urururururgrossonkel',
942        '8,2' => 'Cousin sechsmal entfernt',
943        '8,3' => 'Cousin zweiten Grades fuenfmal entfernt',
944        '8,4' => 'Cousin dritten Grades viermal entfernt',
945        '8,5' => 'Cousin vierten Grades dreimal entfernt',
946        '8,6' => 'Cousin fuenften Grades zweimal entfernt',
947        '8,7' => 'Cousin sechsten Grades einmal entfernt',
948        '8,8' => 'Cousin siebten Grades',
949        '8,9' => 'Cousin siebten Grades einmal entfernt',
950        '8,10' => 'Cousin siebten Grades zweimal entfernt',
951        '9,0' => 'Urururururururgrossvater',
952        '9,1' => 'Ururururururgrossonkel',
953        '9,2' => 'Cousin siebenmal entfernt',
954        '9,3' => 'Cousin zweiten Grades sechsmal entfernt',
955        '9,4' => 'Cousin dritten Grades fuenfmal entfernt',
956        '9,5' => 'Cousin vierten Grades viermal entfernt',
957        '9,6' => 'Cousin fuenften Grades dreimal entfernt',
958        '9,7' => 'Cousin sechsten Grades zweimal entfernt',
959        '9,8' => 'Cousin siebten Grades einmal entfernt',
960        '9,9' => 'Cousin achten Grades',
961        '9,10' => 'Cousin achten Grades einmal entfernt',
962        '10,0' => 'Ururururururururgrossvater',
963        '10,1' => 'Urururururururgrossonkel',
964        '10,2' => 'Cousin achtmal entfernt',
965        '10,3' => 'Cousin zweiten Grades siebenmal entfernt',
966        '10,4' => 'Cousin dritten Grades sechsmal entfernt',
967        '10,5' => 'Cousin vierten Grades fuenfmal entfernt',
968        '10,6' => 'Cousin fuenften Grades viermal entfernt',
969        '10,7' => 'Cousin sechsten Grades dreimal entfernt',
970        '10,8' => 'Cousin siebten Grades zweimal entfernt',
971        '10,9' => 'Cousin achten Grades einmal entfernt',
972        '10,10' => 'Cousin neunten Grades',
973        '11,1' => 'achtens grossonkel',
974        '12,1' => 'neuntens grossonkel',
975        '13,1' => 'zehntens grossonkel',
976        '14,1' => 'elftens grossonkel',
977        '15,1' => 'zwoelftens grossonkel',
978        '16,1' => 'dreizehntens grossonkel',
979        '17,1' => 'vierzehntens grossonkel',
980        '18,1' => 'fuenfzehntens grossonkel',
981);
982
983Readonly::Hash my %DE_CH_FEMALE_RELATIONSHIPS => (
984        '0,0' => 'sich selbst',
985        '0,1' => 'Tochter',
986        '0,2' => 'Enkelin',
987        '0,3' => 'Urenkelin',
988        '0,4' => 'Ururenkelin',
989        '0,5' => 'Urururenkelin',
990        '0,6' => 'Ururururenkelin',
991        '0,7' => 'Urururururenkelin',
992        '0,8' => 'Ururururururenkelin',
993        '0,9' => 'Urururururururenkelin',
994        '0,10' => 'Ururururururururenkelin',
995        '1,0' => 'Mutter',
996        '1,1' => 'Schwester',
997        '1,2' => 'Nichte',
998        '1,3' => 'Grossnichte',
999        '1,4' => 'Urgrossnichte',
1000        '1,5' => 'Ururgrossnichte',
1001        '1,6' => 'Urururgrossnichte',
1002        '1,7' => 'Ururururgrossnichte',
1003        '1,8' => 'Urururururgrossnichte',
1004        '1,9' => 'Ururururururgrossnichte',
1005        '1,10' => 'Urururururururgrossnichte',
1006        '2,0' => 'Grossmutter',
1007        '2,1' => 'Tante',
1008        '2,2' => 'Cousine',
1009        '2,3' => 'Cousine einmal entfernt',
1010        '2,4' => 'Cousine zweimal entfernt',
1011        '2,5' => 'Cousine dreimal entfernt',
1012        '2,6' => 'Cousine viermal entfernt',
1013        '2,7' => 'Cousine fuenfmal entfernt',
1014        '2,8' => 'Cousine sechsmal entfernt',
1015        '2,9' => 'Cousine siebenmal entfernt',
1016        '2,10' => 'Cousine achtmal entfernt',
1017        '3,0' => 'Urgrossmutter',
1018        '3,1' => 'Grosstante',
1019        '3,2' => 'Cousine einmal entfernt',
1020        '3,3' => 'Cousine zweiten Grades',
1021        '3,4' => 'Cousine zweiten Grades einmal entfernt',
1022        '3,5' => 'Cousine zweiten Grades zweimal entfernt',
1023        '3,6' => 'Cousine zweiten Grades dreimal entfernt',
1024        '3,7' => 'Cousine zweiten Grades viermal entfernt',
1025        '3,8' => 'Cousine zweiten Grades fuenfmal entfernt',
1026        '3,9' => 'Cousine zweiten Grades sechsmal entfernt',
1027        '3,10' => 'Cousine zweiten Grades siebenmal entfernt',
1028        '4,0' => 'Ururgrossmutter',
1029        '4,1' => 'Urgrosstante',
1030        '4,2' => 'Cousine zweimal entfernt',
1031        '4,3' => 'Cousine zweiten Grades einmal entfernt',
1032        '4,4' => 'Cousine dritten Grades',
1033        '4,5' => 'Cousine dritten Grades einmal entfernt',
1034        '4,6' => 'Cousine dritten Grades zweimal entfernt',
1035        '4,7' => 'Cousine dritten Grades dreimal entfernt',
1036        '4,8' => 'Cousine dritten Grades viermal entfernt',
1037        '4,9' => 'Cousine dritten Grades fuenfmal entfernt',
1038        '4,10' => 'Cousine dritten Grades sechsmal entfernt',
1039        '5,0' => 'Urururgrossmutter',
1040        '5,1' => 'Ururgrosstante',
1041        '5,2' => 'Cousine dreimal entfernt',
1042        '5,3' => 'Cousine zweiten Grades zweimal entfernt',
1043        '5,4' => 'Cousine dritten Grades einmal entfernt',
1044        '5,5' => 'Cousine vierten Grades',
1045        '5,6' => 'Cousine vierten Grades einmal entfernt',
1046        '5,7' => 'Cousine vierten Grades zweimal entfernt',
1047        '5,8' => 'Cousine vierten Grades dreimal entfernt',
1048        '5,9' => 'Cousine vierten Grades viermal entfernt',
1049        '5,10' => 'Cousine vierten Grades fuenfmal entfernt',
1050        '6,0' => 'Ururururgrossmutter',
1051        '6,1' => 'Urururgrosstante',
1052        '6,2' => 'Cousine viermal entfernt',
1053        '6,3' => 'Cousine zweiten Grades dreimal entfernt',
1054        '6,4' => 'Cousine dritten Grades zweimal entfernt',
1055        '6,5' => 'Cousine vierten Grades einmal entfernt',
1056        '6,6' => 'Cousine fuenften Grades',
1057        '6,7' => 'Cousine fuenften Grades einmal entfernt',
1058        '6,8' => 'Cousine fuenften Grades zweimal entfernt',
1059        '6,9' => 'Cousine fuenften Grades dreimal entfernt',
1060        '6,10' => 'Cousine fuenften Grades viermal entfernt',
1061        '7,0' => 'Urururururgrossmutter',
1062        '7,1' => 'Ururururgrosstante',
1063        '7,2' => 'Cousine fuenfmal entfernt',
1064        '7,3' => 'Cousine zweiten Grades viermal entfernt',
1065        '7,4' => 'Cousine dritten Grades dreimal entfernt',
1066        '7,5' => 'Cousine vierten Grades zweimal entfernt',
1067        '7,6' => 'Cousine fuenften Grades einmal entfernt',
1068        '7,7' => 'Cousine sechsten Grades',
1069        '7,8' => 'Cousine sechsten Grades einmal entfernt',
1070        '7,9' => 'Cousine sechsten Grades zweimal entfernt',
1071        '7,10' => 'Cousine sechsten Grades dreimal entfernt',
1072        '8,0' => 'Ururururururgrossmutter',
1073        '8,1' => 'Urururururgrosstante',
1074        '8,2' => 'Cousine sechsmal entfernt',
1075        '8,3' => 'Cousine zweiten Grades fuenfmal entfernt',
1076        '8,4' => 'Cousine dritten Grades viermal entfernt',
1077        '8,5' => 'Cousine vierten Grades dreimal entfernt',
1078        '8,6' => 'Cousine fuenften Grades zweimal entfernt',
1079        '8,7' => 'Cousine sechsten Grades einmal entfernt',
1080        '8,8' => 'Cousine siebten Grades',
1081        '8,9' => 'Cousine siebten Grades einmal entfernt',
1082        '8,10' => 'Cousine siebten Grades zweimal entfernt',
1083        '9,0' => 'Urururururururgrossmutter',
1084        '9,1' => 'Ururururururgrosstante',
1085        '9,2' => 'Cousine siebenmal entfernt',
1086        '9,3' => 'Cousine zweiten Grades sechsmal entfernt',
1087        '9,4' => 'Cousine dritten Grades fuenfmal entfernt',
1088        '9,5' => 'Cousine vierten Grades viermal entfernt',
1089        '9,6' => 'Cousine fuenften Grades dreimal entfernt',
1090        '9,7' => 'Cousine sechsten Grades zweimal entfernt',
1091        '9,8' => 'Cousine siebten Grades einmal entfernt',
1092        '9,9' => 'Cousine achten Grades',
1093        '9,10' => 'Cousine achten Grades einmal entfernt',
1094        '10,0' => 'Ururururururururgrossmutter',
1095        '10,1' => 'Urururururururgrosstante',
1096        '10,2' => 'Cousine achtmal entfernt',
1097        '10,3' => 'Cousine zweiten Grades siebenmal entfernt',
1098        '10,4' => 'Cousine dritten Grades sechsmal entfernt',
1099        '10,5' => 'Cousine vierten Grades fuenfmal entfernt',
1100        '10,6' => 'Cousine fuenften Grades viermal entfernt',
1101        '10,7' => 'Cousine sechsten Grades dreimal entfernt',
1102        '10,8' => 'Cousine siebten Grades zweimal entfernt',
1103        '10,9' => 'Cousine achten Grades einmal entfernt',
1104        '10,10' => 'Cousine neunten Grades',
1105        '11,1' => 'achtens grosstante',
1106        '12,1' => 'neuntens grosstante',
1107        '13,1' => 'zehntens grosstante',
1108        '14,1' => 'elftens grosstante',
1109        '15,1' => 'zwoelftens grosstante',
1110        '16,1' => 'dreizehntens grosstante',
1111        '17,1' => 'vierzehntens grosstante',
1112        '18,1' => 'fuenfzehntens grosstante',
1113);
1114
1115# ---------------------------------------------------------------------------
1116# Spanish relationship tables
1117# ---------------------------------------------------------------------------
1118
1119Readonly::Hash my %ES_MALE_RELATIONSHIPS => (
1120        '0,0' => 'uno mismo',
1121        '0,1' => 'hijo',
1122        '0,2' => 'nieto',
1123        '0,3' => 'bisnieto',
1124        '0,4' => 'tataranieto',
1125        '0,5' => 'chozno',
1126        '0,6' => 'bisnieto quinto',
1127        '0,7' => 'descendiente lejano',
1128        '0,8' => 'descendiente lejano',
1129        '0,9' => 'descendiente lejano',
1130        '0,10' => 'descendiente lejano',
1131        '1,0' => 'padre',
1132        '1,1' => 'hermano',
1133        '1,2' => 'sobrino',
1134        '1,3' => 'sobrino nieto',
1135        '1,4' => 'sobrino bisnieto',
1136        '1,5' => 'sobrino tataranieto',
1137        '1,6' => 'sobrino lejano',
1138        '1,7' => 'sobrino lejano',
1139        '1,8' => 'sobrino lejano',
1140        '1,9' => 'sobrino lejano',
1141        '1,10' => 'sobrino lejano',
1142        '2,0' => 'abuelo',
1143        '2,1' => 'tio',
1144        '2,2' => 'primo hermano',
1145        '2,3' => 'primo hermano una vez removido',
1146        '2,4' => 'primo hermano dos veces removido',
1147        '2,5' => 'primo hermano tres veces removido',
1148        '2,6' => 'primo hermano cuatro veces removido',
1149        '2,7' => 'primo hermano cinco veces removido',
1150        '2,8' => 'primo hermano seis veces removido',
1151        '2,9' => 'primo hermano siete veces removido',
1152        '2,10' => 'primo hermano ocho veces removido',
1153        '3,0' => 'bisabuelo',
1154        '3,1' => 'tio abuelo',
1155        '3,2' => 'primo hermano una vez removido',
1156        '3,3' => 'primo segundo',
1157        '3,4' => 'primo segundo una vez removido',
1158        '3,5' => 'primo segundo dos veces removido',
1159        '3,6' => 'primo segundo tres veces removido',
1160        '3,7' => 'primo segundo cuatro veces removido',
1161        '3,8' => 'primo segundo cinco veces removido',
1162        '3,9' => 'primo segundo seis veces removido',
1163        '3,10' => 'primo segundo siete veces removido',
1164        '4,0' => 'tatarabuelo',
1165        '4,1' => 'tio bisabuelo',
1166        '4,2' => 'primo hermano dos veces removido',
1167        '4,3' => 'primo segundo una vez removido',
1168        '4,4' => 'primo tercero',
1169        '4,5' => 'primo tercero una vez removido',
1170        '4,6' => 'primo tercero dos veces removido',
1171        '4,7' => 'primo tercero tres veces removido',
1172        '4,8' => 'primo tercero cuatro veces removido',
1173        '4,9' => 'primo tercero cinco veces removido',
1174        '4,10' => 'primo tercero seis veces removido',
1175        '5,0' => 'chozno',
1176        '5,1' => 'tio tatarabuelo',
1177        '5,2' => 'primo hermano tres veces removido',
1178        '5,3' => 'primo segundo dos veces removido',
1179        '5,4' => 'primo tercero una vez removido',
1180        '5,5' => 'primo cuarto',
1181        '5,6' => 'primo cuarto una vez removido',
1182        '5,7' => 'primo cuarto dos veces removido',
1183        '5,8' => 'primo cuarto tres veces removido',
1184        '5,9' => 'primo cuarto cuatro veces removido',
1185        '5,10' => 'primo cuarto cinco veces removido',
1186        '6,0' => 'bisabuelo quinto',
1187        '6,1' => 'tio lejano',
1188        '6,2' => 'primo hermano cuatro veces removido',
1189        '6,3' => 'primo segundo tres veces removido',
1190        '6,4' => 'primo tercero dos veces removido',
1191        '6,5' => 'primo cuarto una vez removido',
1192        '6,6' => 'primo quinto',
1193        '6,7' => 'primo quinto una vez removido',
1194        '6,8' => 'primo quinto dos veces removido',
1195        '6,9' => 'primo quinto tres veces removido',
1196        '6,10' => 'primo quinto cuatro veces removido',
1197        '7,0' => 'antepasado lejano',
1198        '7,1' => 'tio lejano',
1199        '7,2' => 'primo hermano cinco veces removido',
1200        '7,3' => 'primo segundo cuatro veces removido',
1201        '7,4' => 'primo tercero tres veces removido',
1202        '7,5' => 'primo cuarto dos veces removido',
1203        '7,6' => 'primo quinto una vez removido',
1204        '7,7' => 'primo sexto',
1205        '7,8' => 'primo sexto una vez removido',
1206        '7,9' => 'primo sexto dos veces removido',
1207        '7,10' => 'primo sexto tres veces removido',
1208        '8,0' => 'antepasado lejano',
1209        '8,1' => 'tio lejano',
1210        '8,2' => 'primo hermano seis veces removido',
1211        '8,3' => 'primo segundo cinco veces removido',
1212        '8,4' => 'primo tercero cuatro veces removido',
1213        '8,5' => 'primo cuarto tres veces removido',
1214        '8,6' => 'primo quinto dos veces removido',
1215        '8,7' => 'primo sexto una vez removido',
1216        '8,8' => 'primo septimo',
1217        '8,9' => 'primo septimo una vez removido',
1218        '8,10' => 'primo septimo dos veces removido',
1219        '9,0' => 'antepasado lejano',
1220        '9,1' => 'tio lejano',
1221        '9,2' => 'primo hermano siete veces removido',
1222        '9,3' => 'primo segundo seis veces removido',
1223        '9,4' => 'primo tercero cinco veces removido',
1224        '9,5' => 'primo cuarto cuatro veces removido',
1225        '9,6' => 'primo quinto tres veces removido',
1226        '9,7' => 'primo sexto dos veces removido',
1227        '9,8' => 'primo septimo una vez removido',
1228        '9,9' => 'primo octavo',
1229        '9,10' => 'primo octavo una vez removido',
1230        '10,0' => 'antepasado lejano',
1231        '10,1' => 'tio lejano',
1232        '10,2' => 'primo hermano ocho veces removido',
1233        '10,3' => 'primo segundo siete veces removido',
1234        '10,4' => 'primo tercero seis veces removido',
1235        '10,5' => 'primo cuarto cinco veces removido',
1236        '10,6' => 'primo quinto cuatro veces removido',
1237        '10,7' => 'primo sexto tres veces removido',
1238        '10,8' => 'primo septimo dos veces removido',
1239        '10,9' => 'primo octavo una vez removido',
1240        '10,10' => 'primo noveno',
1241        '11,1' => 'tio lejano',
1242        '12,1' => 'tio lejano',
1243        '13,1' => 'tio lejano',
1244        '14,1' => 'tio lejano',
1245        '15,1' => 'tio lejano',
1246        '16,1' => 'tio lejano',
1247        '17,1' => 'tio lejano',
1248        '18,1' => 'tio lejano',
1249);
1250
1251Readonly::Hash my %ES_FEMALE_RELATIONSHIPS => (
1252        '0,0' => 'una misma',
1253        '0,1' => 'hija',
1254        '0,2' => 'nieta',
1255        '0,3' => 'bisnieta',
1256        '0,4' => 'tataranieta',
1257        '0,5' => 'chozna',
1258        '0,6' => 'bisnieta quinta',
1259        '0,7' => 'descendiente lejana',
1260        '0,8' => 'descendiente lejana',
1261        '0,9' => 'descendiente lejana',
1262        '0,10' => 'descendiente lejana',
1263        '1,0' => 'madre',
1264        '1,1' => 'hermana',
1265        '1,2' => 'sobrina',
1266        '1,3' => 'sobrina nieta',
1267        '1,4' => 'sobrina bisnieta',
1268        '1,5' => 'sobrina tataranieta',
1269        '1,6' => 'sobrina lejana',
1270        '1,7' => 'sobrina lejana',
1271        '1,8' => 'sobrina lejana',
1272        '1,9' => 'sobrina lejana',
1273        '1,10' => 'sobrina lejana',
1274        '2,0' => 'abuela',
1275        '2,1' => 'tia',
1276        '2,2' => 'prima hermana',
1277        '2,3' => 'prima hermana una vez removida',
1278        '2,4' => 'prima hermana dos veces removida',
1279        '2,5' => 'prima hermana tres veces removida',
1280        '2,6' => 'prima hermana cuatro veces removida',
1281        '2,7' => 'prima hermana cinco veces removida',
1282        '2,8' => 'prima hermana seis veces removida',
1283        '2,9' => 'prima hermana siete veces removida',
1284        '2,10' => 'prima hermana ocho veces removida',
1285        '3,0' => 'bisabuela',
1286        '3,1' => 'tia abuela',
1287        '3,2' => 'prima hermana una vez removida',
1288        '3,3' => 'prima segunda',
1289        '3,4' => 'prima segunda una vez removida',
1290        '3,5' => 'prima segunda dos veces removida',
1291        '3,6' => 'prima segunda tres veces removida',
1292        '3,7' => 'prima segunda cuatro veces removida',
1293        '3,8' => 'prima segunda cinco veces removida',
1294        '3,9' => 'prima segunda seis veces removida',
1295        '3,10' => 'prima segunda siete veces removida',
1296        '4,0' => 'tatarabuela',
1297        '4,1' => 'tia bisabuela',
1298        '4,2' => 'prima hermana dos veces removida',
1299        '4,3' => 'prima segunda una vez removida',
1300        '4,4' => 'prima tercera',
1301        '4,5' => 'prima tercera una vez removida',
1302        '4,6' => 'prima tercera dos veces removida',
1303        '4,7' => 'prima tercera tres veces removida',
1304        '4,8' => 'prima tercera cuatro veces removida',
1305        '4,9' => 'prima tercera cinco veces removida',
1306        '4,10' => 'prima tercera seis veces removida',
1307        '5,0' => 'chozna',
1308        '5,1' => 'tia tatarabuela',
1309        '5,2' => 'prima hermana tres veces removida',
1310        '5,3' => 'prima segunda dos veces removida',
1311        '5,4' => 'prima tercera una vez removida',
1312        '5,5' => 'prima cuarta',
1313        '5,6' => 'prima cuarta una vez removida',
1314        '5,7' => 'prima cuarta dos veces removida',
1315        '5,8' => 'prima cuarta tres veces removida',
1316        '5,9' => 'prima cuarta cuatro veces removida',
1317        '5,10' => 'prima cuarta cinco veces removida',
1318        '6,0' => 'bisabuela quinta',
1319        '6,1' => 'tia lejana',
1320        '6,2' => 'prima hermana cuatro veces removida',
1321        '6,3' => 'prima segunda tres veces removida',
1322        '6,4' => 'prima tercera dos veces removida',
1323        '6,5' => 'prima cuarta una vez removida',
1324        '6,6' => 'prima quinta',
1325        '6,7' => 'prima quinta una vez removida',
1326        '6,8' => 'prima quinta dos veces removida',
1327        '6,9' => 'prima quinta tres veces removida',
1328        '6,10' => 'prima quinta cuatro veces removida',
1329        '7,0' => 'antepasada lejana',
1330        '7,1' => 'tia lejana',
1331        '7,2' => 'prima hermana cinco veces removida',
1332        '7,3' => 'prima segunda cuatro veces removida',
1333        '7,4' => 'prima tercera tres veces removida',
1334        '7,5' => 'prima cuarta dos veces removida',
1335        '7,6' => 'prima quinta una vez removida',
1336        '7,7' => 'prima sexta',
1337        '7,8' => 'prima sexta una vez removida',
1338        '7,9' => 'prima sexta dos veces removida',
1339        '7,10' => 'prima sexta tres veces removida',
1340        '8,0' => 'antepasada lejana',
1341        '8,1' => 'tia lejana',
1342        '8,2' => 'prima hermana seis veces removida',
1343        '8,3' => 'prima segunda cinco veces removida',
1344        '8,4' => 'prima tercera cuatro veces removida',
1345        '8,5' => 'prima cuarta tres veces removida',
1346        '8,6' => 'prima quinta dos veces removida',
1347        '8,7' => 'prima sexta una vez removida',
1348        '8,8' => 'prima septima',
1349        '8,9' => 'prima septima una vez removida',
1350        '8,10' => 'prima septima dos veces removida',
1351        '9,0' => 'antepasada lejana',
1352        '9,1' => 'tia lejana',
1353        '9,2' => 'prima hermana siete veces removida',
1354        '9,3' => 'prima segunda seis veces removida',
1355        '9,4' => 'prima tercera cinco veces removida',
1356        '9,5' => 'prima cuarta cuatro veces removida',
1357        '9,6' => 'prima quinta tres veces removida',
1358        '9,7' => 'prima sexta dos veces removida',
1359        '9,8' => 'prima septima una vez removida',
1360        '9,9' => 'prima octava',
1361        '9,10' => 'prima octava una vez removida',
1362        '10,0' => 'antepasada lejana',
1363        '10,1' => 'tia lejana',
1364        '10,2' => 'prima hermana ocho veces removida',
1365        '10,3' => 'prima segunda siete veces removida',
1366        '10,4' => 'prima tercera seis veces removida',
1367        '10,5' => 'prima cuarta cinco veces removida',
1368        '10,6' => 'prima quinta cuatro veces removida',
1369        '10,7' => 'prima sexta tres veces removida',
1370        '10,8' => 'prima septima dos veces removida',
1371        '10,9' => 'prima octava una vez removida',
1372        '10,10' => 'prima novena',
1373        '11,1' => 'tia lejana',
1374        '12,1' => 'tia lejana',
1375        '13,1' => 'tia lejana',
1376        '14,1' => 'tia lejana',
1377        '15,1' => 'tia lejana',
1378        '16,1' => 'tia lejana',
1379        '17,1' => 'tia lejana',
1380        '18,1' => 'tia lejana',
1381);
1382
1383# ---------------------------------------------------------------------------
1384# Farsi (Persian) relationship tables
1385# Values use \N{U+XXXX} Unicode escapes (right-to-left script)
1386# Side-specific keys: "s1,s2,paternal" / "s1,s2,maternal"
1387# ---------------------------------------------------------------------------
1388
1389Readonly::Hash my %FA_MALE_RELATIONSHIPS => (
1390        '0,0' => "\N{U+062E}\N{U+0648}\N{U+062F}",
1391        '0,1' => "\N{U+067E}\N{U+0633}\N{U+0631}",
1392        '0,2' => "\N{U+0646}\N{U+0648}\N{U+0647}",
1393        '0,3' => "\N{U+0646}\N{U+0648}\N{U+0647}",
1394        '0,4' => "\N{U+0646}\N{U+0648}\N{U+0647}",
1395        '0,5' => "\N{U+0646}\N{U+0648}\N{U+0647}",
1396        '0,6' => "\N{U+0646}\N{U+0648}\N{U+0647}",
1397        '0,7' => "\N{U+0646}\N{U+0648}\N{U+0647}",
1398        '0,8' => "\N{U+0646}\N{U+0648}\N{U+0647}",
1399        '0,9' => "\N{U+0646}\N{U+0648}\N{U+0647}",
1400        '0,10' => "\N{U+0646}\N{U+0648}\N{U+0647}",
1401        '1,0' => "\N{U+067E}\N{U+062F}\N{U+0631}",
1402        '1,1' => "\N{U+0628}\N{U+0631}\N{U+0627}\N{U+062F}\N{U+0631}",
1403        '1,2' => "\N{U+0628}\N{U+0631}\N{U+0627}\N{U+062F}\N{U+0631}\N{U+0632}\N{U+0627}\N{U+062F}\N{U+0647}",
1404        '1,3' => "\N{U+0628}\N{U+0631}\N{U+0627}\N{U+062F}\N{U+0631}\N{U+0632}\N{U+0627}\N{U+062F}\N{U+0647}",
1405        '1,4' => "\N{U+0628}\N{U+0631}\N{U+0627}\N{U+062F}\N{U+0631}\N{U+0632}\N{U+0627}\N{U+062F}\N{U+0647}",
1406        '1,5' => "\N{U+0628}\N{U+0631}\N{U+0627}\N{U+062F}\N{U+0631}\N{U+0632}\N{U+0627}\N{U+062F}\N{U+0647}",
1407        '1,6' => "\N{U+0628}\N{U+0631}\N{U+0627}\N{U+062F}\N{U+0631}\N{U+0632}\N{U+0627}\N{U+062F}\N{U+0647}",
1408        '1,7' => "\N{U+0628}\N{U+0631}\N{U+0627}\N{U+062F}\N{U+0631}\N{U+0632}\N{U+0627}\N{U+062F}\N{U+0647}",
1409        '1,8' => "\N{U+0628}\N{U+0631}\N{U+0627}\N{U+062F}\N{U+0631}\N{U+0632}\N{U+0627}\N{U+062F}\N{U+0647}",
1410        '1,9' => "\N{U+0628}\N{U+0631}\N{U+0627}\N{U+062F}\N{U+0631}\N{U+0632}\N{U+0627}\N{U+062F}\N{U+0647}",
1411        '1,10' => "\N{U+0628}\N{U+0631}\N{U+0627}\N{U+062F}\N{U+0631}\N{U+0632}\N{U+0627}\N{U+062F}\N{U+0647}",
1412        '2,0' => "\N{U+067E}\N{U+062F}\N{U+0631}\N{U+0628}\N{U+0632}\N{U+0631}\N{U+06AF}",
1413        '2,1' => "\N{U+0639}\N{U+0645}\N{U+0648}",
1414        '2,2' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1415        '2,3' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1416        '2,4' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1417        '2,5' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1418        '2,6' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1419        '2,7' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1420        '2,8' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1421        '2,9' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1422        '2,10' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1423        '3,0' => "\N{U+067E}\N{U+062F}\N{U+0631}\N{U+0628}\N{U+0632}\N{U+0631}\N{U+06AF}",
1424        '3,1' => "\N{U+0639}\N{U+0645}\N{U+0648}",
1425        '3,2' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1426        '3,3' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1427        '3,4' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1428        '3,5' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1429        '3,6' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1430        '3,7' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1431        '3,8' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1432        '3,9' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1433        '3,10' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1434        '4,0' => "\N{U+067E}\N{U+062F}\N{U+0631}\N{U+0628}\N{U+0632}\N{U+0631}\N{U+06AF}",
1435        '4,1' => "\N{U+0639}\N{U+0645}\N{U+0648}",
1436        '4,2' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1437        '4,3' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1438        '4,4' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1439        '4,5' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1440        '4,6' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1441        '4,7' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1442        '4,8' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1443        '4,9' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1444        '4,10' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1445        '5,0' => "\N{U+067E}\N{U+062F}\N{U+0631}\N{U+0628}\N{U+0632}\N{U+0631}\N{U+06AF}",
1446        '5,1' => "\N{U+0639}\N{U+0645}\N{U+0648}",
1447        '5,2' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1448        '5,3' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1449        '5,4' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1450        '5,5' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1451        '5,6' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1452        '5,7' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1453        '5,8' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1454        '5,9' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1455        '5,10' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1456        '6,0' => "\N{U+067E}\N{U+062F}\N{U+0631}\N{U+0628}\N{U+0632}\N{U+0631}\N{U+06AF}",
1457        '6,1' => "\N{U+0639}\N{U+0645}\N{U+0648}",
1458        '6,2' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1459        '6,3' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1460        '6,4' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1461        '6,5' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1462        '6,6' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1463        '6,7' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1464        '6,8' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1465        '6,9' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1466        '6,10' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1467        '7,0' => "\N{U+067E}\N{U+062F}\N{U+0631}\N{U+0628}\N{U+0632}\N{U+0631}\N{U+06AF}",
1468        '7,1' => "\N{U+0639}\N{U+0645}\N{U+0648}",
1469        '7,2' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1470        '7,3' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1471        '7,4' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1472        '7,5' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1473        '7,6' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1474        '7,7' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1475        '7,8' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1476        '7,9' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1477        '7,10' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1478        '8,0' => "\N{U+067E}\N{U+062F}\N{U+0631}\N{U+0628}\N{U+0632}\N{U+0631}\N{U+06AF}",
1479        '8,1' => "\N{U+0639}\N{U+0645}\N{U+0648}",
1480        '8,2' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1481        '8,3' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1482        '8,4' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1483        '8,5' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1484        '8,6' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1485        '8,7' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1486        '8,8' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1487        '8,9' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1488        '8,10' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1489        '9,0' => "\N{U+067E}\N{U+062F}\N{U+0631}\N{U+0628}\N{U+0632}\N{U+0631}\N{U+06AF}",
1490        '9,1' => "\N{U+0639}\N{U+0645}\N{U+0648}",
1491        '9,2' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1492        '9,3' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1493        '9,4' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1494        '9,5' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1495        '9,6' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1496        '9,7' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1497        '9,8' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1498        '9,9' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1499        '9,10' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1500        '10,0' => "\N{U+067E}\N{U+062F}\N{U+0631}\N{U+0628}\N{U+0632}\N{U+0631}\N{U+06AF}",
1501        '10,1' => "\N{U+0639}\N{U+0645}\N{U+0648}",
1502        '10,2' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1503        '10,3' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1504        '10,4' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1505        '10,5' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1506        '10,6' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1507        '10,7' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1508        '10,8' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1509        '10,9' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1510        '10,10' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1511        '11,1' => "\N{U+0639}\N{U+0645}\N{U+0648}",
1512        '12,1' => "\N{U+0639}\N{U+0645}\N{U+0648}",
1513        '13,1' => "\N{U+0639}\N{U+0645}\N{U+0648}",
1514        '14,1' => "\N{U+0639}\N{U+0645}\N{U+0648}",
1515        '15,1' => "\N{U+0639}\N{U+0645}\N{U+0648}",
1516        '16,1' => "\N{U+0639}\N{U+0645}\N{U+0648}",
1517        '17,1' => "\N{U+0639}\N{U+0645}\N{U+0648}",
1518        '18,1' => "\N{U+0639}\N{U+0645}\N{U+0648}",
1519        '2,1,maternal' => "\N{U+062F}\N{U+0627}\N{U+06CC}\N{U+06CC}",
1520        '2,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0648}",
1521        '3,1,maternal' => "\N{U+062F}\N{U+0627}\N{U+06CC}\N{U+06CC}",
1522        '3,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0648}",
1523        '4,1,maternal' => "\N{U+062F}\N{U+0627}\N{U+06CC}\N{U+06CC}",
1524        '4,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0648}",
1525        '5,1,maternal' => "\N{U+062F}\N{U+0627}\N{U+06CC}\N{U+06CC}",
1526        '5,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0648}",
1527        '6,1,maternal' => "\N{U+062F}\N{U+0627}\N{U+06CC}\N{U+06CC}",
1528        '6,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0648}",
1529        '7,1,maternal' => "\N{U+062F}\N{U+0627}\N{U+06CC}\N{U+06CC}",
1530        '7,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0648}",
1531        '8,1,maternal' => "\N{U+062F}\N{U+0627}\N{U+06CC}\N{U+06CC}",
1532        '8,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0648}",
1533        '9,1,maternal' => "\N{U+062F}\N{U+0627}\N{U+06CC}\N{U+06CC}",
1534        '9,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0648}",
1535        '10,1,maternal' => "\N{U+062F}\N{U+0627}\N{U+06CC}\N{U+06CC}",
1536        '10,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0648}",
1537        '11,1,maternal' => "\N{U+062F}\N{U+0627}\N{U+06CC}\N{U+06CC}",
1538        '11,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0648}",
1539        '12,1,maternal' => "\N{U+062F}\N{U+0627}\N{U+06CC}\N{U+06CC}",
1540        '12,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0648}",
1541        '13,1,maternal' => "\N{U+062F}\N{U+0627}\N{U+06CC}\N{U+06CC}",
1542        '13,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0648}",
1543        '14,1,maternal' => "\N{U+062F}\N{U+0627}\N{U+06CC}\N{U+06CC}",
1544        '14,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0648}",
1545        '15,1,maternal' => "\N{U+062F}\N{U+0627}\N{U+06CC}\N{U+06CC}",
1546        '15,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0648}",
1547        '16,1,maternal' => "\N{U+062F}\N{U+0627}\N{U+06CC}\N{U+06CC}",
1548        '16,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0648}",
1549        '17,1,maternal' => "\N{U+062F}\N{U+0627}\N{U+06CC}\N{U+06CC}",
1550        '17,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0648}",
1551        '18,1,maternal' => "\N{U+062F}\N{U+0627}\N{U+06CC}\N{U+06CC}",
1552        '18,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0648}",
1553);
1554
1555Readonly::Hash my %FA_FEMALE_RELATIONSHIPS => (
1556        '0,0' => "\N{U+062E}\N{U+0648}\N{U+062F}",
1557        '0,1' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}",
1558        '0,2' => "\N{U+0646}\N{U+0648}\N{U+0647}",
1559        '0,3' => "\N{U+0646}\N{U+0648}\N{U+0647}",
1560        '0,4' => "\N{U+0646}\N{U+0648}\N{U+0647}",
1561        '0,5' => "\N{U+0646}\N{U+0648}\N{U+0647}",
1562        '0,6' => "\N{U+0646}\N{U+0648}\N{U+0647}",
1563        '0,7' => "\N{U+0646}\N{U+0648}\N{U+0647}",
1564        '0,8' => "\N{U+0646}\N{U+0648}\N{U+0647}",
1565        '0,9' => "\N{U+0646}\N{U+0648}\N{U+0647}",
1566        '0,10' => "\N{U+0646}\N{U+0648}\N{U+0647}",
1567        '1,0' => "\N{U+0645}\N{U+0627}\N{U+062F}\N{U+0631}",
1568        '1,1' => "\N{U+062E}\N{U+0648}\N{U+0627}\N{U+0647}\N{U+0631}",
1569        '1,2' => "\N{U+062E}\N{U+0648}\N{U+0627}\N{U+0647}\N{U+0631}\N{U+0632}\N{U+0627}\N{U+062F}\N{U+0647}",
1570        '1,3' => "\N{U+062E}\N{U+0648}\N{U+0627}\N{U+0647}\N{U+0631}\N{U+0632}\N{U+0627}\N{U+062F}\N{U+0647}",
1571        '1,4' => "\N{U+062E}\N{U+0648}\N{U+0627}\N{U+0647}\N{U+0631}\N{U+0632}\N{U+0627}\N{U+062F}\N{U+0647}",
1572        '1,5' => "\N{U+062E}\N{U+0648}\N{U+0627}\N{U+0647}\N{U+0631}\N{U+0632}\N{U+0627}\N{U+062F}\N{U+0647}",
1573        '1,6' => "\N{U+062E}\N{U+0648}\N{U+0627}\N{U+0647}\N{U+0631}\N{U+0632}\N{U+0627}\N{U+062F}\N{U+0647}",
1574        '1,7' => "\N{U+062E}\N{U+0648}\N{U+0627}\N{U+0647}\N{U+0631}\N{U+0632}\N{U+0627}\N{U+062F}\N{U+0647}",
1575        '1,8' => "\N{U+062E}\N{U+0648}\N{U+0627}\N{U+0647}\N{U+0631}\N{U+0632}\N{U+0627}\N{U+062F}\N{U+0647}",
1576        '1,9' => "\N{U+062E}\N{U+0648}\N{U+0627}\N{U+0647}\N{U+0631}\N{U+0632}\N{U+0627}\N{U+062F}\N{U+0647}",
1577        '1,10' => "\N{U+062E}\N{U+0648}\N{U+0627}\N{U+0647}\N{U+0631}\N{U+0632}\N{U+0627}\N{U+062F}\N{U+0647}",
1578        '2,0' => "\N{U+0645}\N{U+0627}\N{U+062F}\N{U+0631}\N{U+0628}\N{U+0632}\N{U+0631}\N{U+06AF}",
1579        '2,1' => "\N{U+0639}\N{U+0645}\N{U+0647}",
1580        '2,2' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1581        '2,3' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1582        '2,4' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1583        '2,5' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1584        '2,6' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1585        '2,7' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1586        '2,8' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1587        '2,9' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1588        '2,10' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1589        '3,0' => "\N{U+0645}\N{U+0627}\N{U+062F}\N{U+0631}\N{U+0628}\N{U+0632}\N{U+0631}\N{U+06AF}",
1590        '3,1' => "\N{U+0639}\N{U+0645}\N{U+0647}",
1591        '3,2' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1592        '3,3' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1593        '3,4' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1594        '3,5' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1595        '3,6' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1596        '3,7' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1597        '3,8' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1598        '3,9' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1599        '3,10' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1600        '4,0' => "\N{U+0645}\N{U+0627}\N{U+062F}\N{U+0631}\N{U+0628}\N{U+0632}\N{U+0631}\N{U+06AF}",
1601        '4,1' => "\N{U+0639}\N{U+0645}\N{U+0647}",
1602        '4,2' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1603        '4,3' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1604        '4,4' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1605        '4,5' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1606        '4,6' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1607        '4,7' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1608        '4,8' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1609        '4,9' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1610        '4,10' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1611        '5,0' => "\N{U+0645}\N{U+0627}\N{U+062F}\N{U+0631}\N{U+0628}\N{U+0632}\N{U+0631}\N{U+06AF}",
1612        '5,1' => "\N{U+0639}\N{U+0645}\N{U+0647}",
1613        '5,2' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1614        '5,3' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1615        '5,4' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1616        '5,5' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1617        '5,6' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1618        '5,7' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1619        '5,8' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1620        '5,9' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1621        '5,10' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1622        '6,0' => "\N{U+0645}\N{U+0627}\N{U+062F}\N{U+0631}\N{U+0628}\N{U+0632}\N{U+0631}\N{U+06AF}",
1623        '6,1' => "\N{U+0639}\N{U+0645}\N{U+0647}",
1624        '6,2' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1625        '6,3' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1626        '6,4' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1627        '6,5' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1628        '6,6' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1629        '6,7' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1630        '6,8' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1631        '6,9' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1632        '6,10' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1633        '7,0' => "\N{U+0645}\N{U+0627}\N{U+062F}\N{U+0631}\N{U+0628}\N{U+0632}\N{U+0631}\N{U+06AF}",
1634        '7,1' => "\N{U+0639}\N{U+0645}\N{U+0647}",
1635        '7,2' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1636        '7,3' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1637        '7,4' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1638        '7,5' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1639        '7,6' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1640        '7,7' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1641        '7,8' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1642        '7,9' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1643        '7,10' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1644        '8,0' => "\N{U+0645}\N{U+0627}\N{U+062F}\N{U+0631}\N{U+0628}\N{U+0632}\N{U+0631}\N{U+06AF}",
1645        '8,1' => "\N{U+0639}\N{U+0645}\N{U+0647}",
1646        '8,2' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1647        '8,3' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1648        '8,4' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1649        '8,5' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1650        '8,6' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1651        '8,7' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1652        '8,8' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1653        '8,9' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1654        '8,10' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1655        '9,0' => "\N{U+0645}\N{U+0627}\N{U+062F}\N{U+0631}\N{U+0628}\N{U+0632}\N{U+0631}\N{U+06AF}",
1656        '9,1' => "\N{U+0639}\N{U+0645}\N{U+0647}",
1657        '9,2' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1658        '9,3' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1659        '9,4' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1660        '9,5' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1661        '9,6' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1662        '9,7' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1663        '9,8' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1664        '9,9' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1665        '9,10' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1666        '10,0' => "\N{U+0645}\N{U+0627}\N{U+062F}\N{U+0631}\N{U+0628}\N{U+0632}\N{U+0631}\N{U+06AF}",
1667        '10,1' => "\N{U+0639}\N{U+0645}\N{U+0647}",
1668        '10,2' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1669        '10,3' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1670        '10,4' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1671        '10,5' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1672        '10,6' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1673        '10,7' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1674        '10,8' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1675        '10,9' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1676        '10,10' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}",
1677        '11,1' => "\N{U+0639}\N{U+0645}\N{U+0647}",
1678        '12,1' => "\N{U+0639}\N{U+0645}\N{U+0647}",
1679        '13,1' => "\N{U+0639}\N{U+0645}\N{U+0647}",
1680        '14,1' => "\N{U+0639}\N{U+0645}\N{U+0647}",
1681        '15,1' => "\N{U+0639}\N{U+0645}\N{U+0647}",
1682        '16,1' => "\N{U+0639}\N{U+0645}\N{U+0647}",
1683        '17,1' => "\N{U+0639}\N{U+0645}\N{U+0647}",
1684        '18,1' => "\N{U+0639}\N{U+0645}\N{U+0647}",
1685        '2,1,maternal' => "\N{U+062E}\N{U+0627}\N{U+0644}\N{U+0647}",
1686        '2,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0647}",
1687        '3,1,maternal' => "\N{U+062E}\N{U+0627}\N{U+0644}\N{U+0647}",
1688        '3,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0647}",
1689        '4,1,maternal' => "\N{U+062E}\N{U+0627}\N{U+0644}\N{U+0647}",
1690        '4,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0647}",
1691        '5,1,maternal' => "\N{U+062E}\N{U+0627}\N{U+0644}\N{U+0647}",
1692        '5,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0647}",
1693        '6,1,maternal' => "\N{U+062E}\N{U+0627}\N{U+0644}\N{U+0647}",
1694        '6,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0647}",
1695        '7,1,maternal' => "\N{U+062E}\N{U+0627}\N{U+0644}\N{U+0647}",
1696        '7,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0647}",
1697        '8,1,maternal' => "\N{U+062E}\N{U+0627}\N{U+0644}\N{U+0647}",
1698        '8,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0647}",
1699        '9,1,maternal' => "\N{U+062E}\N{U+0627}\N{U+0644}\N{U+0647}",
1700        '9,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0647}",
1701        '10,1,maternal' => "\N{U+062E}\N{U+0627}\N{U+0644}\N{U+0647}",
1702        '10,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0647}",
1703        '11,1,maternal' => "\N{U+062E}\N{U+0627}\N{U+0644}\N{U+0647}",
1704        '11,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0647}",
1705        '12,1,maternal' => "\N{U+062E}\N{U+0627}\N{U+0644}\N{U+0647}",
1706        '12,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0647}",
1707        '13,1,maternal' => "\N{U+062E}\N{U+0627}\N{U+0644}\N{U+0647}",
1708        '13,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0647}",
1709        '14,1,maternal' => "\N{U+062E}\N{U+0627}\N{U+0644}\N{U+0647}",
1710        '14,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0647}",
1711        '15,1,maternal' => "\N{U+062E}\N{U+0627}\N{U+0644}\N{U+0647}",
1712        '15,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0647}",
1713        '16,1,maternal' => "\N{U+062E}\N{U+0627}\N{U+0644}\N{U+0647}",
1714        '16,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0647}",
1715        '17,1,maternal' => "\N{U+062E}\N{U+0627}\N{U+0644}\N{U+0647}",
1716        '17,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0647}",
1717        '18,1,maternal' => "\N{U+062E}\N{U+0627}\N{U+0644}\N{U+0647}",
1718        '18,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0647}",
1719);
1720
1721# ---------------------------------------------------------------------------
1722# Classical Latin relationship tables
1723# Many step-count combinations have no classical term; those keys are absent.
1724# Side-specific keys: "s1,s2,paternal" / "s1,s2,maternal"
1725# ---------------------------------------------------------------------------
1726
1727Readonly::Hash my %LA_MALE_RELATIONSHIPS => (
1728        '0,0' => 'ipse',
1729        '0,1' => 'filius',
1730        '0,2' => 'nepos',
1731        '0,3' => 'pronepos',
1732        '0,4' => 'abnepos',
1733        '0,5' => 'atnepos',
1734        '0,6' => 'trinepos',
1735        '1,0' => 'pater',
1736        '1,1' => 'frater',
1737        '1,2' => 'nepos',
1738        '2,0' => 'avus',
1739        '2,1' => 'patruus',
1740        '2,2' => 'consobrinus',
1741        '3,0' => 'proavus',
1742        '3,1' => 'patruus magnus',
1743        '4,0' => 'abavus',
1744        '4,1' => 'patruus maior',
1745        '5,0' => 'atavus',
1746        '5,1' => 'patruus maximus',
1747        '6,0' => 'tritavus',
1748        '2,1,maternal' => 'avunculus',
1749        '2,1,paternal' => 'patruus',
1750        '2,2,maternal' => 'consobrinus',
1751        '2,2,paternal' => 'patruelis',
1752        '3,1,maternal' => 'avunculus magnus',
1753        '3,1,paternal' => 'patruus magnus',
1754        '4,1,maternal' => 'avunculus maior',
1755        '4,1,paternal' => 'patruus maior',
1756        '5,1,maternal' => 'avunculus maximus',
1757        '5,1,paternal' => 'patruus maximus',
1758);
1759
1760Readonly::Hash my %LA_FEMALE_RELATIONSHIPS => (
1761        '0,0' => 'ipsa',
1762        '0,1' => 'filia',
1763        '0,2' => 'neptis',
1764        '0,3' => 'proneptis',
1765        '0,4' => 'abneptis',
1766        '0,5' => 'atneptis',
1767        '0,6' => 'trineptis',
1768        '1,0' => 'mater',
1769        '1,1' => 'soror',
1770        '1,2' => 'neptis',
1771        '2,0' => 'avia',
1772        '2,1' => 'amita',
1773        '2,2' => 'consobrina',
1774        '3,0' => 'proavia',
1775        '3,1' => 'amita magna',
1776        '4,0' => 'abavia',
1777        '4,1' => 'amita maior',
1778        '5,0' => 'atavia',
1779        '5,1' => 'amita maxima',
1780        '6,0' => 'tritavia',
1781        '2,1,maternal' => 'matertera',
1782        '2,1,paternal' => 'amita',
1783        '2,2,maternal' => 'consobrina',
1784        '2,2,paternal' => 'patruelis',
1785        '3,1,maternal' => 'matertera magna',
1786        '3,1,paternal' => 'amita magna',
1787        '4,1,maternal' => 'matertera maior',
1788        '4,1,paternal' => 'amita maior',
1789        '5,1,maternal' => 'matertera maxima',
1790        '5,1,paternal' => 'amita maxima',
1791);
1792
1793# ---------------------------------------------------------------------------
1794# Master dispatch table: lang -> sex -> hashref
1795# ---------------------------------------------------------------------------
1796
1797Readonly::Hash my %RELATIONSHIP_TABLES => (
1798        'en' => {
1799                $SEX_MALE   => \%EN_MALE_RELATIONSHIPS,
1800                $SEX_FEMALE => \%EN_FEMALE_RELATIONSHIPS,
1801        }, 'es' => {
1802                $SEX_MALE   => \%ES_MALE_RELATIONSHIPS,
1803                $SEX_FEMALE => \%ES_FEMALE_RELATIONSHIPS,
1804        }, 'fa' => {
1805                $SEX_MALE   => \%FA_MALE_RELATIONSHIPS,
1806                $SEX_FEMALE => \%FA_FEMALE_RELATIONSHIPS,
1807        }, 'fr' => {
1808                $SEX_MALE   => \%FR_MALE_RELATIONSHIPS,
1809                $SEX_FEMALE => \%FR_FEMALE_RELATIONSHIPS,
1810        }, 'de' => {
1811                $SEX_MALE   => \%DE_MALE_RELATIONSHIPS,
1812                $SEX_FEMALE => \%DE_FEMALE_RELATIONSHIPS,
1813        }, 'de_ch' => {
1814                $SEX_MALE   => \%DE_CH_MALE_RELATIONSHIPS,
1815                $SEX_FEMALE => \%DE_CH_FEMALE_RELATIONSHIPS,
1816        }, 'la' => {
1817                $SEX_MALE   => \%LA_MALE_RELATIONSHIPS,
1818                $SEX_FEMALE => \%LA_FEMALE_RELATIONSHIPS,
1819        },
1820);
1821# ---------------------------------------------------------------------------
1822# Constructor
1823# ---------------------------------------------------------------------------
1824
1825 - 1975
=head1 NAME

Genealogy::Relationship::Name - Return a genealogical relationship name from step counts

=head1 VERSION

Version 0.04

=head1 SYNOPSIS

    use Genealogy::Relationship::Name;

    my $namer = Genealogy::Relationship::Name->new();

    my $name = $namer->name(
        steps_to_ancestor  => 2,
        steps_from_ancestor => 3,
        sex                 => 'F',
    );
    # Returns 'first cousin once-removed'

    # With language
    my $name_fr = $namer->name(
        steps_to_ancestor   => 2,
        steps_from_ancestor => 2,
        sex                 => 'M',
        language            => 'fr',
    );
    # Returns 'cousin germain'

=head1 DESCRIPTION

C<Genealogy::Relationship::Name> maps a pair of step-counts (person A to common
ancestor, common ancestor to person B) plus the sex of person B and an optional
language code to a human-readable relationship name string.

The relationship tables were originally embedded in the C<gedcom> and C<ged2site>
distributions inside C<Gedcom::Individual::relationship_up()>; this module
extracts them into a reusable, installable CPAN distribution.

Supported languages: C<en> (English, default), C<de> (German), C<de_ch> (Swiss
German), C<es> (Spanish), C<fa> (Farsi/Persian), C<fr> (French), C<la> (Classical Latin).

=head1 METHODS

=head2 new

Constructor.  Creates and returns a blessed C<Genealogy::Relationship::Name>
object.

=head3 PURPOSE

Initialises the object with optional configuration: a default language for
subsequent C<name()> calls, and an optional L<Log::Abstraction> object to
use as the error logger.  Configuration may also be loaded from an INI-style
file via L<Object::Configure>.

=head3 ARGUMENTS

=over 4

=item C<language> (string, optional)

Default BCP-47 language tag (primary subtag only) for all C<name()> calls
on this object.  Supported values: C<en> (default), C<de>, C<de_ch> (Swiss
German), C<es>, C<fa> (Farsi/Persian), C<fr>, C<la> (Classical Latin).  May be
overridden per-call by passing C<language> to C<name()>.

=item C<logger>

A pre-constructed loggining object.  When a required argument is
passed as C<undef> to C<name()>, the error is reported via
C<< $logger->error($msg) >> rather than C<croak>.  This allows
programs to route errors through their own
infrastructure with full C<ctx> context.

See L<Log::Abstraction> and the L</CONFIGURATION> section for the
recommended construction pattern.

=item C<config_file> (string, optional)

Path to an INI-style configuration file processed by L<Object::Configure>.
Any keys it sets may be overridden by arguments passed directly to C<new()>.

=back

=head3 RETURNS

A blessed C<Genealogy::Relationship::Name> object.

=head3 SIDE EFFECTS

Calls L<Object::Configure> C<configure()>, which may read from a
configuration file on disk if C<config_file> is supplied or if a default
configuration file exists for the class.

=head3 NOTES

L<Object::Configure> cannot handle object or coderef values (it treats
unknown scalar values as configuration file paths).  The C<logger> key is
therefore stashed before the C<configure()> call and restored afterward.
Any future object-valued constructor arguments must follow the same pattern.

The C<language> argument is stored without validation at construction time.
Validation (regex match + table lookup) occurs at the first C<name()> call.
An invalid language passed to C<new()> will therefore not be detected until
C<name()> is called.  To catch the error earlier, call
C<< $namer->name(..., language => $lang) >> with a test pair immediately
after construction.

=head3 EXAMPLE

    use Genealogy::Relationship::Name;
    use Log::Abstraction;

    # Minimal construction
    my $namer = Genealogy::Relationship::Name->new();

    # With a default language
    my $namer_fr = Genealogy::Relationship::Name->new(language => 'fr');

    # With a Log::Abstraction logger
    my $la = Log::Abstraction->new(
        logger => sub {
            my $args = shift;
            my $msg = $args->{ctx}
                ? $args->{ctx}->as_string() . ': ' . join('', @{$args->{message}})
                : join('', @{$args->{message}});
            complain({ message => $msg, person => $args->{ctx} });
        },
        ctx => $individual,
    );
    my $namer = Genealogy::Relationship::Name->new(language => 'en', logger => $la);

=head3 API SPECIFICATION

=head4 Input

    {
        language => { type => 'string', regex => qr/^(?:en|de(?:[-_]ch)?|es|fa|fr|la)/, optional => 1 },
        logger   => { type => 'object', optional => 1 },
    }

=head4 Output

    {
        type  => 'object',
        class => 'Genealogy::Relationship::Name',
    }

=cut
1976
1977sub new {
1978        # Create and return a blessed object
1979
129
588994
        my $class = shift;
1980
1981        # Handle hash or hashref arguments
1982
129
173
        my $params = Params::Get::get_params(undef, \@_);
1983
1984        # Stash keys that are coderefs or objects before passing to Object::Configure,
1985        # which cannot handle them (it treats unknown scalar values as config file paths)
1986
129
1157
        my %stash;
1987
129
107
        for my $key (qw(logger)) {
1988
129
164
                next unless exists $params->{$key};
1989
11
12
                $stash{$key} = delete $params->{$key};
1990        }
1991
1992        # Load the configuration from a config file, if provided
1993
129
129
        $params = Object::Configure::configure($class, $params);
1994
1995        # Restore the stashed coderefs and objects after configure()
1996
129
129
277686
87
        @{$params}{keys %stash} = values %stash;
1997
1998        # Bless and return the object; logger/ctx/level keys from params
1999        # are stored directly and accessed via $self->{logger} etc.
2000        return bless {
2001                # Store any constructor-time config for Object::Configure compatibility
2002
129
129
170
333
                %{$params},
2003        }, ref($class) || $class;
2004}
2005
2006 - 2110
=head2 name

Returns the name of the relationship between person A and person B.

Given the number of steps from person A up to the nearest common ancestor
(C<steps_to_ancestor>) and the number of steps from that ancestor down to
person B (C<steps_from_ancestor>), plus the sex of person B and a language
code, returns a localised relationship-name string.

=head3 ARGUMENTS

=over 4

=item C<steps_to_ancestor> (integer, required)

Number of generational steps from person A up to the common ancestor.
Must be a non-negative integer.  Zero means person A I<is> the ancestor.

=item C<steps_from_ancestor> (integer, required)

Number of generational steps from the common ancestor down to person B.
Must be a non-negative integer.

=item C<sex> (string, required)

Sex of person B.  Must be C<'M'> (male) or C<'F'> (female).

=item C<language> (string, optional)

BCP-47-style language tag.
Supported values: C<en> (default), C<de>, C<de_ch> (Swiss German, may also
be supplied as the BCP-47 tag C<de-CH>), C<es>, C<fa>, C<fr>, C<la>.

Note: C<fa> (Farsi/Persian) values are stored as C<\N{U+XXXX}> Unicode
escapes and render correctly in any Unicode-aware context.  C<la>
(Classical Latin) has a sparse table; many step-count combinations have
no classical term and return C<undef>.

=item C<person> (object, optional)

An optional person object (e.g. a C<Gedcom::Individual> instance) passed
through to the error handler when an error occurs.  Takes priority over the
C<ctx> set at construction time.  The handler receives it as C<ctx> (logger
path) or C<person> (on_error path), matching the C<complain()> interface
in C<gedcom>/C<ged2site>.

=item C<family_side> (string, optional)

C<'paternal'> or C<'maternal'>.  Used by languages that distinguish the
paternal from the maternal line for the same step counts.  Currently
relevant for:

=over 4

=item * C<la> (Latin) -- uncle/aunt (C<patruus>/C<avunculus>,
C<amita>/C<matertera>) and first cousin (C<patruelis>/C<consobrinus>)

=item * C<fa> (Farsi) -- uncle (C<amoo>/C<dayi>) and aunt
(C<ammeh>/C<khaleh>)

=back

When C<family_side> is not supplied, the table falls back to the generic
(non-side-specific) entry for that step-count pair.

=back

=head3 RETURNS

A string containing the relationship name, or C<undef> if the combination
is not found in the lookup table.

=head3 EXAMPLE

    my $namer = Genealogy::Relationship::Name->new();

    # Person A is the grandparent (2 steps up) of the common ancestor,
    # and person B is 3 steps below the ancestor; B is female => first cousin once-removed
    my $rel = $namer->name(
        steps_to_ancestor   => 2,
        steps_from_ancestor => 3,
        sex                 => 'F',
    );

=head3 API SPECIFICATION

=head4 Input

    {
        steps_to_ancestor   => { type => 'integer', minimum => 0 },
        steps_from_ancestor => { type => 'integer', minimum => 0 },
        sex                 => { type => 'string', memberof => ['M', 'F'] },
        language => { type => 'string', regex => qr/^(?:en|de(?:[-_]ch)?|es|fa|fr|la)/, optional => 1 },
        # person is handled before validate_strict (PVS infers constraints from objects)
        family_side => { type => 'string', memberof => ['paternal','maternal'], optional => 1 },
    }

=head4 Output

    {
        type     => 'string',
        optional => 1,     # undef when the combination is not tabulated
    }

=cut
2111
2112sub name {
2113
1580
71373
        my $self = shift;
2114
2115        # Validate and extract the remaining parameters; capture the return value
2116
1580
998
        my $args = Params::Validate::Strict::validate_strict(
2117                args   => Params::Get::get_params(undef, \@_) || {},
2118                schema => {
2119                        steps_to_ancestor   => { type => 'integer', minimum => 0 },
2120                        steps_from_ancestor => { type => 'integer', minimum => 0 },
2121                        sex                 => { type => 'string', memberof => ['M', 'F'] },
2122                        language => { type => 'string', regex => qr/^(?:en|de(?:[-_]ch)?|es|fa|fr|la)/, optional => 1 },
2123                        person              => { type => 'object', optional => 1 },
2124                        family_side         => { type => 'string', memberof => ['paternal','maternal'],
2125                                                 optional => 1 },
2126                }
2127        );
2128
2129        # person is extracted early so it can be forwarded to the logger on error;
2130        # it overrides the ctx set at construction time per the POD contract
2131
1550
228980
        my $person      = $args->{person};
2132
1550
545
        my $family_side = $args->{family_side};
2133
2134        # Validate required args; undef means the caller explicitly passed undef
2135        # (distinct from omitting the arg), so report via logger if set, then croak
2136
1550
613
        foreach my $arg (qw(steps_to_ancestor steps_from_ancestor sex)) {
2137
4629
2190
                next if defined $args->{$arg};
2138
11
16
                if(my $logger = $self->{logger}) {
2139                        # Pass person as ctx so caller's complain() handler can attach it
2140
11
11
                        my @ctx = defined $person ? (ctx => $person) : ();
2141
11
26
                        $logger->error("$arg not given", @ctx);
2142                }
2143
11
3247
                croak("$arg not given");
2144        }
2145
1539
498
        my $steps1 = $args->{steps_to_ancestor};
2146
1539
490
        my $steps2 = $args->{steps_from_ancestor};
2147
1539
523
        my $sex    = $args->{sex};
2148
2149        # Fall back to constructor default or hard default if no per-call language given
2150
1539
1309
        my $lang = lc($args->{language} // $self->{language} // $DEFAULT_LANGUAGE);
2151
2152        # Swiss German (de-CH) maps to its own table before subtag stripping,
2153        # because it uses 'ss' where standard German uses Eszett
2154
1539
655
        if($lang eq 'de-ch') {
2155
14
8
                $lang = 'de_ch';
2156        } else {
2157                # Strip any region subtag (e.g. 'en-GB' -> 'en') after lowercasing
2158
1525
805
                ($lang) = split /-/, $lang;
2159        }
2160
2161        # Build lookup key from the two step counts; try side-specific key first
2162        # for languages that distinguish paternal/maternal (Latin, Farsi)
2163
1539
620
        my $key      = "${steps1},${steps2}";
2164
1539
624
        my $side_key = defined($family_side) ? "${key},${family_side}" : undef;
2165
2166        # Retrieve the correct gender-specific table for the chosen language
2167
1539
1243
        my $table = $RELATIONSHIP_TABLES{$lang}{$sex};
2168
2169        # Prefer side-specific entry when family_side is given; fall back to generic key
2170        my $result = (defined($side_key) && exists $table->{$side_key})
2171                     ? $table->{$side_key}
2172
1539
5528
                     : $table->{$key};
2173
2174
1539
3416
        return $result;
2175}
2176
2177# ---------------------------------------------------------------------------
2178# Public method: supported_languages()
2179# ---------------------------------------------------------------------------
2180
2181 - 2216
=head2 supported_languages

Returns a sorted list of the language codes that the module supports.

=head3 PURPOSE

Allows calling code to enumerate the languages available for C<name()>
without hard-coding them.

=head3 ARGUMENTS

None.

=head3 RETURNS

A list (or array-ref in scalar context) of language code strings,
currently C<('de', 'de_ch', 'en', 'es', 'fa', 'fr', 'la')>.

=head3 EXAMPLE

    my @langs = $namer->supported_languages();
    # ( 'de', 'de_ch', 'en', 'es', 'fa', 'fr', 'la' )

=head3 API SPECIFICATION

=head4 Input

    {}   # no arguments

=head4 Output

    {
        type => ARRAYREF,   # sorted list of language codes
    }

=cut
2217
2218sub supported_languages {
2219
12
856
        my $self = shift;
2220
2221        # Return the sorted set of keys from the master dispatch table
2222
12
29
        my @langs = sort keys %RELATIONSHIP_TABLES;
2223
12
188
        return wantarray ? @langs : \@langs;
2224}
2225
2226# ---------------------------------------------------------------------------
2227# Public method: known_sexes()
2228# ---------------------------------------------------------------------------
2229
2230 - 2268
=head2 known_sexes

Returns the list of sex codes accepted by C<name()>.

=head3 PURPOSE

Documents and exposes the set of valid C<sex> values so that callers can
validate their own input without duplicating knowledge.

=head3 ARGUMENTS

None.

=head3 RETURNS

A list (or array-ref in scalar context) of valid sex code strings: C<('F', 'M')>.

=head3 SIDE EFFECTS

None.

=head3 EXAMPLE

    my @sexes = $namer->known_sexes();
    # ( 'F', 'M' )

=head3 API SPECIFICATION

=head4 Input

    {}   # no arguments

=head4 Output

    {
        type => ARRAYREF,
    }

=cut
2269
2270sub known_sexes {
2271
10
653
        my $self = shift;
2272
2273        # Return the two valid sex codes in sorted order
2274
10
14
        my @sexes = sort($SEX_FEMALE, $SEX_MALE);
2275
10
16
        return wantarray ? @sexes : \@sexes;
2276}
2277
22781;
2279