TER1 (Statement): 100.00%
TER2 (Branch): 94.44%
TER3 (LCSAJ): 100.0% (3/3)
Approximate LCSAJ segments: 19
● Covered — this LCSAJ path was executed during testing.
● Not covered — this LCSAJ path was never executed. These are the paths to focus on.
Multiple dots on a line indicate that multiple control-flow paths begin at that line. Hovering over any dot shows:
start → end → jump
Uncovered paths show [NOT COVERED] in the tooltip.
1: package 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: use utf8; 10: use strict; 11: use warnings; 12: use autodie qw(:all); 13: 14: use Carp qw(croak carp); 15: use Object::Configure; 16: use Params::Get; 17: use Params::Validate::Strict 0.31; 18: use Readonly; 19: 20: our $VERSION = '0.04'; 21: 22: # --------------------------------------------------------------------------- 23: # Constants â relationship table keys 24: # --------------------------------------------------------------------------- 25: 26: # Supported language codes 27: Readonly::Array my @SUPPORTED_LANGUAGES => qw(de de_ch en es fa fr la); 28: 29: # Default language when none supplied 30: Readonly::Scalar my $DEFAULT_LANGUAGE => 'en'; 31: 32: # Sex constants 33: Readonly::Scalar my $SEX_MALE => 'M'; 34: Readonly::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: 42: Readonly::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: 176: Readonly::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: 314: Readonly::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: 446: Readonly::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: 582: Readonly::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: 714: Readonly::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: 851: Readonly::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: 983: Readonly::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: 1119: Readonly::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: 1251: Readonly::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: 1389: Readonly::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: 1555: Readonly::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: 1727: Readonly::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: 1760: Readonly::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: 1797: Readonly::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: =head1 NAME 1826: 1827: Genealogy::Relationship::Name - Return a genealogical relationship name from step counts 1828: 1829: =head1 VERSION 1830: 1831: Version 0.04 1832: 1833: =head1 SYNOPSIS 1834: 1835: use Genealogy::Relationship::Name; 1836: 1837: my $namer = Genealogy::Relationship::Name->new(); 1838: 1839: my $name = $namer->name( 1840: steps_to_ancestor => 2, 1841: steps_from_ancestor => 3, 1842: sex => 'F', 1843: ); 1844: # Returns 'first cousin once-removed' 1845: 1846: # With language 1847: my $name_fr = $namer->name( 1848: steps_to_ancestor => 2, 1849: steps_from_ancestor => 2, 1850: sex => 'M', 1851: language => 'fr', 1852: ); 1853: # Returns 'cousin germain' 1854: 1855: =head1 DESCRIPTION 1856: 1857: C<Genealogy::Relationship::Name> maps a pair of step-counts (person A to common 1858: ancestor, common ancestor to person B) plus the sex of person B and an optional 1859: language code to a human-readable relationship name string. 1860: 1861: The relationship tables were originally embedded in the C<gedcom> and C<ged2site> 1862: distributions inside C<Gedcom::Individual::relationship_up()>; this module 1863: extracts them into a reusable, installable CPAN distribution. 1864: 1865: Supported languages: C<en> (English, default), C<de> (German), C<de_ch> (Swiss 1866: German), C<es> (Spanish), C<fa> (Farsi/Persian), C<fr> (French), C<la> (Classical Latin). 1867: 1868: =head1 METHODS 1869: 1870: =head2 new 1871: 1872: Constructor. Creates and returns a blessed C<Genealogy::Relationship::Name> 1873: object. 1874: 1875: =head3 PURPOSE 1876: 1877: Initialises the object with optional configuration: a default language for 1878: subsequent C<name()> calls, and an optional L<Log::Abstraction> object to 1879: use as the error logger. Configuration may also be loaded from an INI-style 1880: file via L<Object::Configure>. 1881: 1882: =head3 ARGUMENTS 1883: 1884: =over 4 1885: 1886: =item C<language> (string, optional) 1887: 1888: Default BCP-47 language tag (primary subtag only) for all C<name()> calls 1889: on this object. Supported values: C<en> (default), C<de>, C<de_ch> (Swiss 1890: German), C<es>, C<fa> (Farsi/Persian), C<fr>, C<la> (Classical Latin). May be 1891: overridden per-call by passing C<language> to C<name()>. 1892: 1893: =item C<logger> 1894: 1895: A pre-constructed loggining object. When a required argument is 1896: passed as C<undef> to C<name()>, the error is reported via 1897: C<< $logger->error($msg) >> rather than C<croak>. This allows 1898: programs to route errors through their own 1899: infrastructure with full C<ctx> context. 1900: 1901: See L<Log::Abstraction> and the L</CONFIGURATION> section for the 1902: recommended construction pattern. 1903: 1904: =item C<config_file> (string, optional) 1905: 1906: Path to an INI-style configuration file processed by L<Object::Configure>. 1907: Any keys it sets may be overridden by arguments passed directly to C<new()>. 1908: 1909: =back 1910: 1911: =head3 RETURNS 1912: 1913: A blessed C<Genealogy::Relationship::Name> object. 1914: 1915: =head3 SIDE EFFECTS 1916: 1917: Calls L<Object::Configure> C<configure()>, which may read from a 1918: configuration file on disk if C<config_file> is supplied or if a default 1919: configuration file exists for the class. 1920: 1921: =head3 NOTES 1922: 1923: L<Object::Configure> cannot handle object or coderef values (it treats 1924: unknown scalar values as configuration file paths). The C<logger> key is 1925: therefore stashed before the C<configure()> call and restored afterward. 1926: Any future object-valued constructor arguments must follow the same pattern. 1927: 1928: The C<language> argument is stored without validation at construction time. 1929: Validation (regex match + table lookup) occurs at the first C<name()> call. 1930: An invalid language passed to C<new()> will therefore not be detected until 1931: C<name()> is called. To catch the error earlier, call 1932: C<< $namer->name(..., language => $lang) >> with a test pair immediately 1933: after construction. 1934: 1935: =head3 EXAMPLE 1936: 1937: use Genealogy::Relationship::Name; 1938: use Log::Abstraction; 1939: 1940: # Minimal construction 1941: my $namer = Genealogy::Relationship::Name->new(); 1942: 1943: # With a default language 1944: my $namer_fr = Genealogy::Relationship::Name->new(language => 'fr'); 1945: 1946: # With a Log::Abstraction logger 1947: my $la = Log::Abstraction->new( 1948: logger => sub { 1949: my $args = shift; 1950: my $msg = $args->{ctx} 1951: ? $args->{ctx}->as_string() . ': ' . join('', @{$args->{message}}) 1952: : join('', @{$args->{message}}); 1953: complain({ message => $msg, person => $args->{ctx} }); 1954: }, 1955: ctx => $individual, 1956: ); 1957: my $namer = Genealogy::Relationship::Name->new(language => 'en', logger => $la); 1958: 1959: =head3 API SPECIFICATION 1960: 1961: =head4 Input 1962: 1963: { 1964: language => { type => 'string', regex => qr/^(?:en|de(?:[-_]ch)?|es|fa|fr|la)/, optional => 1 }, 1965: logger => { type => 'object', optional => 1 }, 1966: } 1967: 1968: =head4 Output 1969: 1970: { 1971: type => 'object', 1972: class => 'Genealogy::Relationship::Name', 1973: } 1974: 1975: =cut 1976: 1977: sub new { 1978: # Create and return a blessed object ●1979 → 1987 → 1993 1979: my $class = shift; 1980: 1981: # Handle hash or hashref arguments 1982: 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: my %stash; 1987: for my $key (qw(logger)) { 1988: next unless exists $params->{$key}; 1989: $stash{$key} = delete $params->{$key}; 1990: } 1991: 1992: # Load the configuration from a config file, if provided 1993: $params = Object::Configure::configure($class, $params); 1994: 1995: # Restore the stashed coderefs and objects after configure() 1996: @{$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 {Mutants (Total: 2, Killed: 2, Survived: 0)
2001: # Store any constructor-time config for Object::Configure compatibility 2002: %{$params}, 2003: }, ref($class) || $class; 2004: } 2005: 2006: =head2 name 2007: 2008: Returns the name of the relationship between person A and person B. 2009: 2010: Given the number of steps from person A up to the nearest common ancestor 2011: (C<steps_to_ancestor>) and the number of steps from that ancestor down to 2012: person B (C<steps_from_ancestor>), plus the sex of person B and a language 2013: code, returns a localised relationship-name string. 2014: 2015: =head3 ARGUMENTS 2016: 2017: =over 4 2018: 2019: =item C<steps_to_ancestor> (integer, required) 2020: 2021: Number of generational steps from person A up to the common ancestor. 2022: Must be a non-negative integer. Zero means person A I<is> the ancestor. 2023: 2024: =item C<steps_from_ancestor> (integer, required) 2025: 2026: Number of generational steps from the common ancestor down to person B. 2027: Must be a non-negative integer. 2028: 2029: =item C<sex> (string, required) 2030: 2031: Sex of person B. Must be C<'M'> (male) or C<'F'> (female). 2032: 2033: =item C<language> (string, optional) 2034: 2035: BCP-47-style language tag. 2036: Supported values: C<en> (default), C<de>, C<de_ch> (Swiss German, may also 2037: be supplied as the BCP-47 tag C<de-CH>), C<es>, C<fa>, C<fr>, C<la>. 2038: 2039: Note: C<fa> (Farsi/Persian) values are stored as C<\N{U+XXXX}> Unicode 2040: escapes and render correctly in any Unicode-aware context. C<la> 2041: (Classical Latin) has a sparse table; many step-count combinations have 2042: no classical term and return C<undef>. 2043: 2044: =item C<person> (object, optional) 2045: 2046: An optional person object (e.g. a C<Gedcom::Individual> instance) passed 2047: through to the error handler when an error occurs. Takes priority over the 2048: C<ctx> set at construction time. The handler receives it as C<ctx> (logger 2049: path) or C<person> (on_error path), matching the C<complain()> interface 2050: in C<gedcom>/C<ged2site>. 2051: 2052: =item C<family_side> (string, optional) 2053: 2054: C<'paternal'> or C<'maternal'>. Used by languages that distinguish the 2055: paternal from the maternal line for the same step counts. Currently 2056: relevant for: 2057: 2058: =over 4 2059: 2060: =item * C<la> (Latin) -- uncle/aunt (C<patruus>/C<avunculus>, 2061: C<amita>/C<matertera>) and first cousin (C<patruelis>/C<consobrinus>) 2062: 2063: =item * C<fa> (Farsi) -- uncle (C<amoo>/C<dayi>) and aunt 2064: (C<ammeh>/C<khaleh>) 2065: 2066: =back 2067: 2068: When C<family_side> is not supplied, the table falls back to the generic 2069: (non-side-specific) entry for that step-count pair. 2070: 2071: =back 2072: 2073: =head3 RETURNS 2074: 2075: A string containing the relationship name, or C<undef> if the combination 2076: is not found in the lookup table. 2077: 2078: =head3 EXAMPLE 2079: 2080: my $namer = Genealogy::Relationship::Name->new(); 2081: 2082: # Person A is the grandparent (2 steps up) of the common ancestor, 2083: # and person B is 3 steps below the ancestor; B is female => first cousin once-removed 2084: my $rel = $namer->name( 2085: steps_to_ancestor => 2, 2086: steps_from_ancestor => 3, 2087: sex => 'F', 2088: ); 2089: 2090: =head3 API SPECIFICATION 2091: 2092: =head4 Input 2093: 2094: { 2095: steps_to_ancestor => { type => 'integer', minimum => 0 }, 2096: steps_from_ancestor => { type => 'integer', minimum => 0 }, 2097: sex => { type => 'string', memberof => ['M', 'F'] }, 2098: language => { type => 'string', regex => qr/^(?:en|de(?:[-_]ch)?|es|fa|fr|la)/, optional => 1 }, 2099: # person is handled before validate_strict (PVS infers constraints from objects) 2100: family_side => { type => 'string', memberof => ['paternal','maternal'], optional => 1 }, 2101: } 2102: 2103: =head4 Output 2104: 2105: { 2106: type => 'string', 2107: optional => 1, # undef when the combination is not tabulated 2108: } 2109: 2110: =cut 2111: 2112: sub name { ●2113 → 2136 → 2145 2113: my $self = shift; 2114: 2115: # Validate and extract the remaining parameters; capture the return value 2116: 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: my $person = $args->{person}; 2132: 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: foreach my $arg (qw(steps_to_ancestor steps_from_ancestor sex)) { 2137: next if defined $args->{$arg}; 2138: if(my $logger = $self->{logger}) {
Mutants (Total: 1, Killed: 1, Survived: 0)
2139: # Pass person as ctx so caller's complain() handler can attach it 2140: my @ctx = defined $person ? (ctx => $person) : (); 2141: $logger->error("$arg not given", @ctx); 2142: } 2143: croak("$arg not given"); 2144: } ●2145 → 2154 → 2163 2145: my $steps1 = $args->{steps_to_ancestor}; 2146: my $steps2 = $args->{steps_from_ancestor}; 2147: my $sex = $args->{sex}; 2148: 2149: # Fall back to constructor default or hard default if no per-call language given 2150: 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: if($lang eq 'de-ch') {
Mutants (Total: 1, Killed: 1, Survived: 0)
2155: $lang = 'de_ch'; 2156: } else { 2157: # Strip any region subtag (e.g. 'en-GB' -> 'en') after lowercasing 2158: ($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: my $key = "${steps1},${steps2}"; 2164: my $side_key = defined($family_side) ? "${key},${family_side}" : undef; 2165: 2166: # Retrieve the correct gender-specific table for the chosen language 2167: 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: : $table->{$key}; 2173: 2174: return $result;
Mutants (Total: 2, Killed: 2, Survived: 0)
2175: } 2176: 2177: # --------------------------------------------------------------------------- 2178: # Public method: supported_languages() 2179: # --------------------------------------------------------------------------- 2180: 2181: =head2 supported_languages 2182: 2183: Returns a sorted list of the language codes that the module supports. 2184: 2185: =head3 PURPOSE 2186: 2187: Allows calling code to enumerate the languages available for C<name()> 2188: without hard-coding them. 2189: 2190: =head3 ARGUMENTS 2191: 2192: None. 2193: 2194: =head3 RETURNS 2195: 2196: A list (or array-ref in scalar context) of language code strings, 2197: currently C<('de', 'de_ch', 'en', 'es', 'fa', 'fr', 'la')>. 2198: 2199: =head3 EXAMPLE 2200: 2201: my @langs = $namer->supported_languages(); 2202: # ( 'de', 'de_ch', 'en', 'es', 'fa', 'fr', 'la' ) 2203: 2204: =head3 API SPECIFICATION 2205: 2206: =head4 Input 2207: 2208: {} # no arguments 2209: 2210: =head4 Output 2211: 2212: { 2213: type => ARRAYREF, # sorted list of language codes 2214: } 2215: 2216: =cut 2217: 2218: sub supported_languages { 2219: my $self = shift; 2220: 2221: # Return the sorted set of keys from the master dispatch table 2222: my @langs = sort keys %RELATIONSHIP_TABLES; 2223: return wantarray ? @langs : \@langs;
Mutants (Total: 2, Killed: 2, Survived: 0)
2224: } 2225: 2226: # --------------------------------------------------------------------------- 2227: # Public method: known_sexes() 2228: # --------------------------------------------------------------------------- 2229: 2230: =head2 known_sexes 2231: 2232: Returns the list of sex codes accepted by C<name()>. 2233: 2234: =head3 PURPOSE 2235: 2236: Documents and exposes the set of valid C<sex> values so that callers can 2237: validate their own input without duplicating knowledge. 2238: 2239: =head3 ARGUMENTS 2240: 2241: None. 2242: 2243: =head3 RETURNS 2244: 2245: A list (or array-ref in scalar context) of valid sex code strings: C<('F', 'M')>. 2246: 2247: =head3 SIDE EFFECTS 2248: 2249: None. 2250: 2251: =head3 EXAMPLE 2252: 2253: my @sexes = $namer->known_sexes(); 2254: # ( 'F', 'M' ) 2255: 2256: =head3 API SPECIFICATION 2257: 2258: =head4 Input 2259: 2260: {} # no arguments 2261: 2262: =head4 Output 2263: 2264: { 2265: type => ARRAYREF, 2266: } 2267: 2268: =cut 2269: 2270: sub known_sexes { 2271: my $self = shift; 2272: 2273: # Return the two valid sex codes in sorted order 2274: my @sexes = sort($SEX_FEMALE, $SEX_MALE); 2275: return wantarray ? @sexes : \@sexes;
Mutants (Total: 2, Killed: 2, Survived: 0)
2276: } 2277: 2278: 1; 2279: 2280: __END__ 2281: 2282: =head1 CONFIGURATION 2283: 2284: The constructor accepts an optional C<language> key which sets the default 2285: language for all subsequent calls to C<name()>: 2286: 2287: my $namer = Genealogy::Relationship::Name->new(language => 'fr'); 2288: 2289: This default can be overridden per-call by passing C<language> to C<name()>. 2290: The object is also compatible with C<Object::Configure> for runtime 2291: reconfiguration. 2292: 2293: =head2 Error handling 2294: 2295: Errors are dispatched through the following priority chain: 2296: 2297: =over 4 2298: 2299: =item 1. L<Log::Abstraction> object (preferred) 2300: 2301: Construct a C<Log::Abstraction> object with the desired logger coderef and 2302: C<ctx> (typically a C<Gedcom::Individual>), then pass it as C<logger> to 2303: C<new()>. On error, this module simply calls C<< $logger->error($msg) >> 2304: and Log::Abstraction handles ctx forwarding, formatting, and dispatch. 2305: 2306: use Log::Abstraction; 2307: 2308: my $logger = Log::Abstraction->new( 2309: logger => sub { 2310: my $args = shift; 2311: my $msg = $args->{ctx} 2312: ? $args->{ctx}->as_string() . ': ' . join('', @{$args->{message}}) 2313: : join('', @{$args->{message}}); 2314: complain({ message => $msg, person => $args->{ctx} }); 2315: }, 2316: ctx => $individual, 2317: ); 2318: 2319: my $namer = Genealogy::Relationship::Name->new(logger => $logger); 2320: 2321: =back 2322: 2323: If any handler returns without dying (e.g. a warning-only handler in 2324: L<Log::Abstraction>), C<name()> returns C<undef>. 2325: 2326: =head1 DIAGNOSTICS 2327: 2328: =over 4 2329: 2330: =item steps_to_ancestor not given 2331: 2332: C<steps_to_ancestor> was passed as C<undef>. Passing C<undef> explicitly is 2333: distinct from omitting the argument; use a defined non-negative integer. 2334: 2335: =item steps_from_ancestor not given 2336: 2337: As above, for C<steps_from_ancestor>. 2338: 2339: =item sex not given 2340: 2341: C<sex> was passed as C<undef>. Supply C<'M'> or C<'F'>. 2342: 2343: =back 2344: 2345: =head1 DEPENDENCIES 2346: 2347: L<Carp>, L<Object::Configure> 2348: 2349: Optionally L<Log::Abstraction> (E<gt>= 0.28) for the C<logger>/C<ctx> error 2350: dispatch path. 2351: L<Params::Get>, L<Params::Validate::Strict>, L<Readonly> 2352: 2353: =encoding UTF-8 2354: 2355: =head1 BUGS AND LIMITATIONS 2356: 2357: The direct-line and cousin tables cover steps 0-10 in both directions. 2358: Some language tables have sparser coverage at high step counts (e.g. Latin 2359: has no classical term beyond 6th-degree ancestors, and returns C<undef>). 2360: The French tables use two overlapping naming conventions (I<arrière-petit-cousin> 2361: vs I<cousin au N-ième degré>) that are not applied fully consistently; a 2362: native-French genealogist's review of the higher-step entries would be welcome. 2363: The C<person> argument to C<name()> is forwarded to the logger as C<ctx> 2364: when an error occurs, but Log::Abstraction's per-call C<ctx> override 2365: API may not be available in all versions; test your logger integration 2366: if you rely on this behaviour. 2367: 2368: =head1 TODO 2369: 2370: =over 4 2371: 2372: =item * Add Readme section documenting the French dual-naming convention 2373: (I<arrière-petit-cousin> vs I<cousin au N-ième degré>) and the depth at which 2374: each language's table becomes sparse. 2375: 2376: =back 2377: 2378: =head1 SEE ALSO 2379: 2380: =over 4 2381: 2382: =item * L<Configure an Object at Runtime|Object::Configure> 2383: 2384: =item * L<Test Dashboard|https://nigelhorne.github.io/Genealogy-Relationship-Name/coverage/> 2385: 2386: =item * L<Gedcom::Individual>, L<Genealogy::Relationship>, L<https://www.tfcg.ca/tableau-des-liens-de-parente>, 2387: 2388: =back 2389: 2390: =head1 AUTHOR 2391: 2392: Nigel Horne C<< <njh@nigelhorne.com> >> 2393: 2394: =head1 REPOSITORY 2395: 2396: L<https://github.com/nigelhorne/Genealogy-Relationship-Name> 2397: 2398: =head1 SUPPORT 2399: 2400: This module is provided as-is without any warranty. 2401: 2402: Please report any bugs or feature requests to C<bug-genealogy-relationship-name at rt.cpan.org>, 2403: or through the web interface at 2404: L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Genealogy-Relationship-Name>. 2405: I will be notified, and then you'll 2406: automatically be notified of progress on your bug as I make changes. 2407: 2408: You can find documentation for this module with the perldoc command. 2409: 2410: perldoc Genealogy::Relationship::Name 2411: 2412: You can also look for information at: 2413: 2414: =over 4 2415: 2416: =item * MetaCPAN 2417: 2418: L<https://metacpan.org/dist/Genealogy-Relationship-Name> 2419: 2420: =item * RT: CPAN's request tracker 2421: 2422: L<https://rt.cpan.org/NoAuth/Bugs.html?Dist=Genealogy-Relationship-Name> 2423: 2424: =item * CPAN Testers' Matrix 2425: 2426: L<http://matrix.cpantesters.org/?dist=Genealogy-Relationship-Name> 2427: 2428: =item * CPAN Testers Dependencies 2429: 2430: L<http://deps.cpantesters.org/?module=Genealogy::Relationship::Name> 2431: 2432: =back 2433: 2434: =head1 FORMAL SPECIFICATION 2435: 2436: =head2 new 2437: 2438: new ________________________________________________________ 2439: [In] class : String (class name or object) 2440: language : {en, es, fa, fr, de, la}? (optional default language 2441: logger : Log::Abstraction? (optional error logger) 2442: [Out] self : Genealogy::Relationship::Name 2443: 2444: Let params == get_params(args) 2445: Let params' == configure(class, params \ {logger}) 2446: union {logger -> params.logger} if logger in dom params 2447: self == bless(params', class) 2448: 2449: post: self.language == params.language if language in dom params 2450: self.logger == params.logger if logger in dom params 2451: ref(self) == 'Genealogy::Relationship::Name' 2452: 2453: =head2 name 2454: 2455: name ______________________________________________________ 2456: [In] steps_to_ancestor : N0 2457: steps_from_ancestor : N0 2458: sex : {M, F} 2459: language : {en, es, fa, fr, de, de_ch, la}? (default en) 2460: person : Object? 2461: family_side : {paternal, maternal}? 2462: [Out] result : String | undef 2463: 2464: Let key == steps_to_ancestor ++ "," ++ steps_from_ancestor 2465: Let side_key == key ++ "," ++ family_side if family_side defined 2466: Let table == RELATIONSHIP_TABLES(language)(sex) 2467: result == table(side_key) if family_side defined and side_key in dom table 2468: == table(key) if key in dom table 2469: == undef otherwise 2470: 2471: =head2 supported_languages 2472: 2473: supported_languages ______________________________________ 2474: [In] (none) 2475: [Out] result : seq String 2476: 2477: result == sort(dom RELATIONSHIP_TABLES) 2478: 2479: =head2 known_sexes 2480: 2481: known_sexes ______________________________________________ 2482: [In] (none) 2483: [Out] result : seq String 2484: 2485: result == sort { $SEX_FEMALE, $SEX_MALE } 2486: 2487: =head1 LICENCE AND COPYRIGHT 2488: 2489: Copyright 2026 Nigel Horne. 2490: 2491: Usage is subject to the GPL2 licence terms. 2492: If you use it, 2493: please let me know. 2494: 2495: =cut