TER1 (Statement): 100.00%
TER2 (Branch): 93.75%
TER3 (LCSAJ): 100.0% (3/3)
Approximate LCSAJ segments: 17
● 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 strict; 10: use warnings; 11: use autodie qw(:all); 12: 13: use Carp qw(croak carp); 14: use Object::Configure; 15: use Params::Get; 16: use Params::Validate::Strict 0.31; 17: use Readonly; 18: 19: our $VERSION = '0.03'; 20: 21: # --------------------------------------------------------------------------- 22: # Constants â relationship table keys 23: # --------------------------------------------------------------------------- 24: 25: # Supported language codes 26: Readonly::Array my @SUPPORTED_LANGUAGES => qw(de de_ch en es fa fr la); 27: 28: # Default language when none supplied 29: Readonly::Scalar my $DEFAULT_LANGUAGE => 'en'; 30: 31: # Sex constants 32: Readonly::Scalar my $SEX_MALE => 'M'; 33: Readonly::Scalar my $SEX_FEMALE => 'F'; 34: 35: # --------------------------------------------------------------------------- 36: # English relationship tables 37: # Key: "$steps1,$steps2" where steps1 = steps from A to ancestor, 38: # steps2 = steps from B to ancestor 39: # --------------------------------------------------------------------------- 40: 41: Readonly::Hash my %EN_MALE_RELATIONSHIPS => ( 42: '0,0' => 'self', 43: '0,1' => 'son', 44: '0,2' => 'grandson', 45: '0,3' => 'great-grandson', 46: '0,4' => 'great-great-grandson', 47: '0,5' => 'great-great-great-grandson', 48: '0,6' => 'great-great-great-great-grandson', 49: '0,7' => 'great-great-great-great-great-grandson', 50: '0,8' => 'great-great-great-great-great-great-grandson', 51: '0,9' => 'great-great-great-great-great-great-great-grandson', 52: '0,10' => 'great-great-great-great-great-great-great-great-grandson', 53: '1,0' => 'father', 54: '1,1' => 'brother', 55: '1,2' => 'nephew', 56: '1,3' => 'great-nephew', 57: '1,4' => 'great-great-nephew', 58: '1,5' => 'great-great-great-nephew', 59: '1,6' => 'great-great-great-great-nephew', 60: '1,7' => 'great-great-great-great-great-nephew', 61: '1,8' => 'great-great-great-great-great-great-nephew', 62: '1,9' => 'great-great-great-great-great-great-great-nephew', 63: '1,10' => 'great-great-great-great-great-great-great-great-nephew', 64: '2,0' => 'grandfather', 65: '2,1' => 'uncle', 66: '2,2' => 'first cousin', 67: '2,3' => 'first cousin once-removed', 68: '2,4' => 'first cousin twice-removed', 69: '2,5' => 'first cousin three-times-removed', 70: '2,6' => 'first cousin four-times-removed', 71: '2,7' => 'first cousin five-times-removed', 72: '2,8' => 'first cousin six-times-removed', 73: '2,9' => 'first cousin seven-times-removed', 74: '2,10' => 'first cousin eight-times-removed', 75: '3,0' => 'great-grandfather', 76: '3,1' => 'great-uncle', 77: '3,2' => 'first cousin once-removed', 78: '3,3' => 'second cousin', 79: '3,4' => 'second cousin once-removed', 80: '3,5' => 'second cousin twice-removed', 81: '3,6' => 'second cousin three-times-removed', 82: '3,7' => 'second cousin four-times-removed', 83: '3,8' => 'second cousin five-times-removed', 84: '3,9' => 'second cousin six-times-removed', 85: '3,10' => 'second cousin seven-times-removed', 86: '4,0' => 'great-great-grandfather', 87: '4,1' => 'great-great-uncle', 88: '4,2' => 'first cousin twice-removed', 89: '4,3' => 'second cousin once-removed', 90: '4,4' => 'third cousin', 91: '4,5' => 'third cousin once-removed', 92: '4,6' => 'third cousin twice-removed', 93: '4,7' => 'third cousin three-times-removed', 94: '4,8' => 'third cousin four-times-removed', 95: '4,9' => 'third cousin five-times-removed', 96: '4,10' => 'third cousin six-times-removed', 97: '5,0' => 'great-great-great-grandfather', 98: '5,1' => 'great-great-great-uncle', 99: '5,2' => 'first cousin three-times-removed', 100: '5,3' => 'second cousin twice-removed', 101: '5,4' => 'third cousin once-removed', 102: '5,5' => 'fourth cousin', 103: '5,6' => 'fourth cousin once-removed', 104: '5,7' => 'fourth cousin twice-removed', 105: '5,8' => 'fourth cousin three-times-removed', 106: '5,9' => 'fourth cousin four-times-removed', 107: '5,10' => 'fourth cousin five-times-removed', 108: '6,0' => 'great-great-great-great-grandfather', 109: '6,1' => 'great-great-great-great-uncle', 110: '6,2' => 'first cousin four-times-removed', 111: '6,3' => 'second cousin three-times-removed', 112: '6,4' => 'third cousin twice-removed', 113: '6,5' => 'fourth cousin once-removed', 114: '6,6' => 'fifth cousin', 115: '6,7' => 'fifth cousin once-removed', 116: '6,8' => 'fifth cousin twice-removed', 117: '6,9' => 'fifth cousin three-times-removed', 118: '6,10' => 'fifth cousin four-times-removed', 119: '7,0' => 'great-great-great-great-great-grandfather', 120: '7,1' => 'great-great-great-great-great-uncle', 121: '7,2' => 'first cousin five-times-removed', 122: '7,3' => 'second cousin four-times-removed', 123: '7,4' => 'third cousin three-times-removed', 124: '7,5' => 'fourth cousin twice-removed', 125: '7,6' => 'fifth cousin once-removed', 126: '7,7' => 'sixth cousin', 127: '7,8' => 'sixth cousin once-removed', 128: '7,9' => 'sixth cousin twice-removed', 129: '7,10' => 'sixth cousin three-times-removed', 130: '8,0' => 'great-great-great-great-great-great-grandfather', 131: '8,1' => 'great-great-great-great-great-great-uncle', 132: '8,2' => 'first cousin six-times-removed', 133: '8,3' => 'second cousin five-times-removed', 134: '8,4' => 'third cousin four-times-removed', 135: '8,5' => 'fourth cousin three-times-removed', 136: '8,6' => 'fifth cousin twice-removed', 137: '8,7' => 'sixth cousin once-removed', 138: '8,8' => 'seventh cousin', 139: '8,9' => 'seventh cousin once-removed', 140: '8,10' => 'seventh cousin twice-removed', 141: '9,0' => 'great-great-great-great-great-great-great-grandfather', 142: '9,1' => 'great-great-great-great-great-great-great-uncle', 143: '9,2' => 'first cousin seven-times-removed', 144: '9,3' => 'second cousin six-times-removed', 145: '9,4' => 'third cousin five-times-removed', 146: '9,5' => 'fourth cousin four-times-removed', 147: '9,6' => 'fifth cousin three-times-removed', 148: '9,7' => 'sixth cousin twice-removed', 149: '9,8' => 'seventh cousin once-removed', 150: '9,9' => 'eighth cousin', 151: '9,10' => 'eighth cousin once-removed', 152: '10,0' => 'great-great-great-great-great-great-great-great-grandfather', 153: '10,1' => 'great-great-great-great-great-great-great-great-uncle', 154: '10,2' => 'first cousin eight-times-removed', 155: '10,3' => 'second cousin seven-times-removed', 156: '10,4' => 'third cousin six-times-removed', 157: '10,5' => 'fourth cousin five-times-removed', 158: '10,6' => 'fifth cousin four-times-removed', 159: '10,7' => 'sixth cousin three-times-removed', 160: '10,8' => 'seventh cousin twice-removed', 161: '10,9' => 'eighth cousin once-removed', 162: '10,10' => 'ninth cousin', 163: '11,1' => 'eigth great-uncle', 164: '12,1' => 'ninth great-uncle', 165: '13,1' => 'tenth great-uncle', 166: '16,1' => 'thirteenth great-uncle', 167: '17,1' => 'fourteenth great-uncle', 168: ); 169: 170: Readonly::Hash my %EN_FEMALE_RELATIONSHIPS => ( 171: '0,0' => 'self', 172: '0,1' => 'daughter', 173: '0,2' => 'granddaughter', 174: '0,3' => 'great-granddaughter', 175: '0,4' => 'great-great-granddaughter', 176: '0,5' => 'great-great-great-granddaughter', 177: '0,6' => 'great-great-great-great-granddaughter', 178: '0,7' => 'great-great-great-great-great-granddaughter', 179: '0,8' => 'great-great-great-great-great-great-granddaughter', 180: '0,9' => 'great-great-great-great-great-great-great-granddaughter', 181: '0,10' => 'great-great-great-great-great-great-great-great-granddaughter', 182: '1,0' => 'mother', 183: '1,1' => 'sister', 184: '1,2' => 'niece', 185: '1,3' => 'great-niece', 186: '1,4' => 'great-great-niece', 187: '1,5' => 'great-great-great-niece', 188: '1,6' => 'great-great-great-great-niece', 189: '1,7' => 'great-great-great-great-great-niece', 190: '1,8' => 'great-great-great-great-great-great-niece', 191: '1,9' => 'great-great-great-great-great-great-great-niece', 192: '1,10' => 'great-great-great-great-great-great-great-great-niece', 193: '2,0' => 'grandmother', 194: '2,1' => 'aunt', 195: '2,2' => 'first cousin', 196: '2,3' => 'first cousin once-removed', 197: '2,4' => 'first cousin twice-removed', 198: '2,5' => 'first cousin three-times-removed', 199: '2,6' => 'first cousin four-times-removed', 200: '2,7' => 'first cousin five-times-removed', 201: '2,8' => 'first cousin six-times-removed', 202: '2,9' => 'first cousin seven-times-removed', 203: '2,10' => 'first cousin eight-times-removed', 204: '3,0' => 'great-grandmother', 205: '3,1' => 'great-aunt', 206: '3,2' => 'first cousin once-removed', 207: '3,3' => 'second cousin', 208: '3,4' => 'second cousin once-removed', 209: '3,5' => 'second cousin twice-removed', 210: '3,6' => 'second cousin three-times-removed', 211: '3,7' => 'second cousin four-times-removed', 212: '3,8' => 'second cousin five-times-removed', 213: '3,9' => 'second cousin six-times-removed', 214: '3,10' => 'second cousin seven-times-removed', 215: '4,0' => 'great-great-grandmother', 216: '4,1' => 'great-great-aunt', 217: '4,2' => 'first cousin twice-removed', 218: '4,3' => 'second cousin once-removed', 219: '4,4' => 'third cousin', 220: '4,5' => 'third cousin once-removed', 221: '4,6' => 'third cousin twice-removed', 222: '4,7' => 'third cousin three-times-removed', 223: '4,8' => 'third cousin four-times-removed', 224: '4,9' => 'third cousin five-times-removed', 225: '4,10' => 'third cousin six-times-removed', 226: '5,0' => 'great-great-great-grandmother', 227: '5,1' => 'great-great-great-aunt', 228: '5,2' => 'first cousin three-times-removed', 229: '5,3' => 'second cousin twice-removed', 230: '5,4' => 'third cousin once-removed', 231: '5,5' => 'fourth cousin', 232: '5,6' => 'fourth cousin once-removed', 233: '5,7' => 'fourth cousin twice-removed', 234: '5,8' => 'fourth cousin three-times-removed', 235: '5,9' => 'fourth cousin four-times-removed', 236: '5,10' => 'fourth cousin five-times-removed', 237: '6,0' => 'great-great-great-great-grandmother', 238: '6,1' => 'great-great-great-great-aunt', 239: '6,2' => 'first cousin four-times-removed', 240: '6,3' => 'second cousin three-times-removed', 241: '6,4' => 'third cousin twice-removed', 242: '6,5' => 'fourth cousin once-removed', 243: '6,6' => 'fifth cousin', 244: '6,7' => 'fifth cousin once-removed', 245: '6,8' => 'fifth cousin twice-removed', 246: '6,9' => 'fifth cousin three-times-removed', 247: '6,10' => 'fifth cousin four-times-removed', 248: '7,0' => 'great-great-great-great-great-grandmother', 249: '7,1' => 'great-great-great-great-great-aunt', 250: '7,2' => 'first cousin five-times-removed', 251: '7,3' => 'second cousin four-times-removed', 252: '7,4' => 'third cousin three-times-removed', 253: '7,5' => 'fourth cousin twice-removed', 254: '7,6' => 'fifth cousin once-removed', 255: '7,7' => 'sixth cousin', 256: '7,8' => 'sixth cousin once-removed', 257: '7,9' => 'sixth cousin twice-removed', 258: '7,10' => 'sixth cousin three-times-removed', 259: '8,0' => 'great-great-great-great-great-great-grandmother', 260: '8,1' => 'great-great-great-great-great-great-aunt', 261: '8,2' => 'first cousin six-times-removed', 262: '8,3' => 'second cousin five-times-removed', 263: '8,4' => 'third cousin four-times-removed', 264: '8,5' => 'fourth cousin three-times-removed', 265: '8,6' => 'fifth cousin twice-removed', 266: '8,7' => 'sixth cousin once-removed', 267: '8,8' => 'seventh cousin', 268: '8,9' => 'seventh cousin once-removed', 269: '8,10' => 'seventh cousin twice-removed', 270: '9,0' => 'great-great-great-great-great-great-great-grandmother', 271: '9,1' => 'great-great-great-great-great-great-great-aunt', 272: '9,2' => 'first cousin seven-times-removed', 273: '9,3' => 'second cousin six-times-removed', 274: '9,4' => 'third cousin five-times-removed', 275: '9,5' => 'fourth cousin four-times-removed', 276: '9,6' => 'fifth cousin three-times-removed', 277: '9,7' => 'sixth cousin twice-removed', 278: '9,8' => 'seventh cousin once-removed', 279: '9,9' => 'eighth cousin', 280: '9,10' => 'eighth cousin once-removed', 281: '10,0' => 'great-great-great-great-great-great-great-great-grandmother', 282: '10,1' => 'great-great-great-great-great-great-great-great-aunt', 283: '10,2' => 'first cousin eight-times-removed', 284: '10,3' => 'second cousin seven-times-removed', 285: '10,4' => 'third cousin six-times-removed', 286: '10,5' => 'fourth cousin five-times-removed', 287: '10,6' => 'fifth cousin four-times-removed', 288: '10,7' => 'sixth cousin three-times-removed', 289: '10,8' => 'seventh cousin twice-removed', 290: '10,9' => 'eighth cousin once-removed', 291: '10,10' => 'ninth cousin', 292: '11,1' => 'eigth great-aunt', 293: '12,1' => 'ninth great-aunt', 294: '13,1' => 'tenth great-aunt', 295: '16,1' => 'thirteenth great-aunt', 296: '17,1' => 'fourteenth great-aunt', 297: ); 298: 299: # --------------------------------------------------------------------------- 300: # French relationship tables 301: # --------------------------------------------------------------------------- 302: 303: Readonly::Hash my %FR_MALE_RELATIONSHIPS => ( 304: '0,0' => 'soi-meme', 305: '0,1' => 'fils', 306: '0,2' => 'petit-fils', 307: '0,3' => 'arriere-petit-fils', 308: '0,4' => 'arriere-arriere-petit-fils', 309: '0,5' => 'arriere-arriere-arriere-petit-fils', 310: '0,6' => 'arriere-arriere-arriere-arriere-petit-fils', 311: '0,7' => 'arriere-arriere-arriere-arriere-arriere-petit-fils', 312: '0,8' => 'arriere-arriere-arriere-arriere-arriere-arriere-petit-fils', 313: '0,9' => 'arriere-arriere-arriere-arriere-arriere-arriere-arriere-petit-fils', 314: '0,10' => 'arriere-arriere-arriere-arriere-arriere-arriere-arriere-arriere-petit-fils', 315: '1,0' => 'pere', 316: '1,1' => "fr\N{U+00E8}re", 317: '1,2' => 'neveu', 318: '1,3' => 'grand-neveu', 319: '1,4' => 'arriere-grand-neveu', 320: '1,5' => 'arriere-arriere-grand-neveu', 321: '1,6' => 'arriere-arriere-arriere-grand-neveu', 322: '1,7' => 'arriere-arriere-arriere-arriere-grand-neveu', 323: '1,8' => 'arriere-arriere-arriere-arriere-arriere-grand-neveu', 324: '1,9' => 'arriere-arriere-arriere-arriere-arriere-arriere-grand-neveu', 325: '1,10' => 'arriere-arriere-arriere-arriere-arriere-arriere-arriere-grand-neveu', 326: '2,0' => 'grand-pere', 327: '2,1' => 'oncle', 328: '2,2' => 'cousin germain', 329: '2,3' => "cousin germain \N{U+00E9}loign\N{U+00E9} au 1er degr\N{U+00E9}", 330: '2,4' => 'cousin germain deux fois eloigne', 331: '2,5' => 'cousin germain trois fois eloigne', 332: '2,6' => 'cousin germain quatre fois eloigne', 333: '2,7' => 'cousin germain cinq fois eloigne', 334: '2,8' => 'cousin germain six fois eloigne', 335: '2,9' => 'cousin germain sept fois eloigne', 336: '2,10' => 'cousin germain huit fois eloigne', 337: '3,0' => 'arriere-grand-pere', 338: '3,1' => 'grand-oncle', 339: '3,2' => 'cousin germain une fois eloigne', 340: '3,2' => "cousin germain \N{U+00E9}loign\N{U+00E9} au 1er degr\N{U+00E9}", 341: '3,3' => 'cousin issu de germain', 342: '3,4' => 'cousin issu de germain une fois eloigne', 343: '3,5' => "cousin issu de germains \N{U+00E9}loign\N{U+00E9} au 2e degr\N{U+00E9}", 344: '3,6' => 'cousin issu de germain trois fois eloigne', 345: '3,7' => 'cousin issu de germain quatre fois eloigne', 346: '3,8' => 'cousin issu de germain cinq fois eloigne', 347: '3,9' => 'cousin issu de germain six fois eloigne', 348: '3,10' => 'cousin issu de germain sept fois eloigne', 349: '4,0' => 'arriere-arriere-grand-pere', 350: '4,1' => 'arriere-grand-oncle', 351: '4,2' => 'cousin germain deux fois eloigne', 352: '4,3' => 'cousin issu de germain une fois eloigne', 353: '4,4' => 'cousin au quatrieme degre', 354: '4,5' => 'cousin au quatrieme degre une fois eloigne', 355: '4,6' => 'cousin au quatrieme degre deux fois eloigne', 356: '4,7' => "petit-cousin \N{U+00E9}loign\N{U+00E9} au 3e degr\N{U+00E9}", 357: '4,8' => 'cousin au quatrieme degre quatre fois eloigne', 358: '4,9' => 'cousin au quatrieme degre cinq fois eloigne', 359: '4,10' => 'cousin au quatrieme degre six fois eloigne', 360: '5,0' => 'arriere-arriere-arriere-grand-pere', 361: '5,1' => 'arriere-arriere-grand-oncle', 362: '5,2' => 'cousin germain trois fois eloigne', 363: '5,3' => "cousin issu de germains \N{U+00E9}loign\N{U+00E9} au 2e degr\N{U+00E9}", 364: '5,4' => 'cousin au quatrieme degre une fois eloigne', 365: '5,5' => 'cousin au cinquieme degre', 366: '5,6' => "arri\N{U+00E8}re-petit-cousin \N{U+00E9}loign\N{U+00E9} au 1er degr\N{U+00E9}", 367: '5,7' => "arri\N{U+00E8}re-petit-cousin \N{U+00E9}loign\N{U+00E9} au 2e degr\N{U+00E9}", 368: '5,8' => 'cousin au cinquieme degre trois fois eloigne', 369: '5,9' => 'cousin au cinquieme degre quatre fois eloigne', 370: '5,10' => 'cousin au cinquieme degre cinq fois eloigne', 371: '6,0' => 'arriere-arriere-arriere-arriere-grand-pere', 372: '6,1' => 'arriere-arriere-arriere-grand-oncle', 373: '6,2' => 'cousin germain quatre fois eloigne', 374: '6,3' => 'cousin issu de germain trois fois eloigne', 375: '6,4' => 'cousin au quatrieme degre deux fois eloigne', 376: '6,5' => "arri\N{U+00E8}re-petit-cousin \N{U+00E9}loign\N{U+00E9} au 1er degr\N{U+00E9}", 377: '6,6' => "arri\N{U+00E8}re-arri\N{U+00E8}re-petit-cousin", 378: '6,7' => 'cousin au sixieme degre une fois eloigne', 379: '6,8' => 'cousin au sixieme degre deux fois eloigne', 380: '6,9' => 'cousin au sixieme degre trois fois eloigne', 381: '6,10' => 'cousin au sixieme degre quatre fois eloigne', 382: '7,0' => 'arriere-arriere-arriere-arriere-arriere-grand-pere', 383: '7,1' => 'arriere-arriere-arriere-arriere-grand-oncle', 384: '7,2' => 'cousin germain cinq fois eloigne', 385: '7,3' => 'cousin issu de germain quatre fois eloigne', 386: '7,4' => "petit-cousin \N{U+00E9}loign\N{U+00E9} au 3e degr\N{U+00E9}", 387: '7,5' => "arri\N{U+00E8}re-petit-cousin \N{U+00E9}loign\N{U+00E9} au 2e degr\N{U+00E9}", 388: '7,6' => 'cousin au sixieme degre une fois eloigne', 389: '7,7' => "sixi\N{U+00E8}me cousin", 390: '7,8' => "sixi\N{U+00E8}me cousin uns fois eloinge", 391: '7,9' => 'cousin au septieme degre deux fois eloigne', 392: '7,10' => 'cousin au septieme degre trois fois eloigne', 393: '8,0' => 'arriere-arriere-arriere-arriere-arriere-arriere-grand-pere', 394: '8,1' => 'arriere-arriere-arriere-arriere-arriere-grand-oncle', 395: '8,2' => 'cousin germain six fois eloigne', 396: '8,3' => 'cousin issu de germain cinq fois eloigne', 397: '8,4' => 'cousin au quatrieme degre quatre fois eloigne', 398: '8,5' => 'cousin au cinquieme degre trois fois eloigne', 399: '8,6' => 'cousin au sixieme degre deux fois eloigne', 400: '8,7' => "sixi\N{U+00E8}me cousin uns fois eloinge", 401: '8,8' => 'cousin au huitieme degre', 402: '8,9' => 'cousin au huitieme degre une fois eloigne', 403: '8,10' => 'cousin au huitieme degre deux fois eloigne', 404: '9,0' => 'arriere-arriere-arriere-arriere-arriere-arriere-arriere-grand-pere', 405: '9,1' => 'arriere-arriere-arriere-arriere-arriere-arriere-grand-oncle', 406: '9,2' => 'cousin germain sept fois eloigne', 407: '9,3' => 'cousin issu de germain six fois eloigne', 408: '9,4' => 'cousin au quatrieme degre cinq fois eloigne', 409: '9,5' => 'cousin au cinquieme degre quatre fois eloigne', 410: '9,6' => 'cousin au sixieme degre trois fois eloigne', 411: '9,7' => 'cousin au septieme degre deux fois eloigne', 412: '9,8' => 'cousin au huitieme degre une fois eloigne', 413: '9,9' => 'cousin au neuvieme degre', 414: '9,10' => 'cousin au neuvieme degre une fois eloigne', 415: '10,0' => 'arriere-arriere-arriere-arriere-arriere-arriere-arriere-arriere-grand-pere', 416: '10,1' => 'arriere-arriere-arriere-arriere-arriere-arriere-arriere-grand-oncle', 417: '10,2' => 'cousin germain huit fois eloigne', 418: '10,3' => 'cousin issu de germain sept fois eloigne', 419: '10,4' => 'cousin au quatrieme degre six fois eloigne', 420: '10,5' => 'cousin au cinquieme degre cinq fois eloigne', 421: '10,6' => 'cousin au sixieme degre quatre fois eloigne', 422: '10,7' => 'cousin au septieme degre trois fois eloigne', 423: '10,8' => 'cousin au huitieme degre deux fois eloigne', 424: '10,9' => 'cousin au neuvieme degre une fois eloigne', 425: '10,10' => 'cousin au dixieme degre', 426: '11,1' => "huit\N{U+0153}me grand-oncle", 427: '12,1' => "neuvi\N{U+0153}me grand-oncle", 428: '13,1' => "dixi\N{U+0153}me grand-oncle", 429: ); 430: 431: Readonly::Hash my %FR_FEMALE_RELATIONSHIPS => ( 432: '0,0' => 'soi-meme', 433: '0,1' => 'fille', 434: '0,2' => 'petite-fille', 435: '0,3' => 'arriere-petite-fille', 436: '0,4' => 'arriere-arriere-petite-fille', 437: '0,5' => 'arriere-arriere-arriere-petite-fille', 438: '0,6' => 'arriere-arriere-arriere-arriere-petite-fille', 439: '0,7' => 'arriere-arriere-arriere-arriere-arriere-petite-fille', 440: '0,8' => 'arriere-arriere-arriere-arriere-arriere-arriere-petite-fille', 441: '0,9' => 'arriere-arriere-arriere-arriere-arriere-arriere-arriere-petite-fille', 442: '0,10' => 'arriere-arriere-arriere-arriere-arriere-arriere-arriere-arriere-petite-fille', 443: '1,0' => 'mere', 444: '1,1' => "s\N{U+0153}ur", 445: '1,2' => "ni\N{U+00E8}ce", 446: '1,3' => 'grand-niece', 447: '1,4' => 'arriere-grand-niece', 448: '1,5' => 'arriere-arriere-grand-niece', 449: '1,6' => 'arriere-arriere-arriere-grand-niece', 450: '1,7' => 'arriere-arriere-arriere-arriere-grand-niece', 451: '1,8' => 'arriere-arriere-arriere-arriere-arriere-grand-niece', 452: '1,9' => 'arriere-arriere-arriere-arriere-arriere-arriere-grand-niece', 453: '1,10' => 'arriere-arriere-arriere-arriere-arriere-arriere-arriere-grand-niece', 454: '2,0' => 'grand-mere', 455: '2,1' => 'tante', 456: '2,2' => 'cousine germaine', 457: '2,3' => "cousine germaine \N{U+00E9}loign\N{U+00E9}e au 1er degr\N{U+00E9}", 458: '2,4' => 'cousine germaine deux fois eloignee', 459: '2,5' => 'cousine germaine trois fois eloignee', 460: '2,6' => 'cousine germaine quatre fois eloignee', 461: '2,7' => 'cousine germaine cinq fois eloignee', 462: '2,8' => 'cousine germaine six fois eloignee', 463: '2,9' => 'cousine germaine sept fois eloignee', 464: '2,10' => 'cousine germaine huit fois eloignee', 465: '3,0' => 'arriere-grand-mere', 466: '3,1' => 'grand-tante', 467: '3,2' => "cousine germaine \N{U+00E9}loign\N{U+00E9}e au 1er degr\N{U+00E9}", 468: '3,3' => 'cousine issue de germaine', 469: '3,4' => 'cousine issue de germaine une fois eloignee', 470: '3,5' => "cousine issue de germains \N{U+00E9}loign\N{U+00E9}e au 2e degr\N{U+00E9}", 471: '3,6' => 'cousine issue de germaine trois fois eloignee', 472: '3,7' => 'cousine issue de germaine quatre fois eloignee', 473: '3,8' => 'cousine issue de germaine cinq fois eloignee', 474: '3,9' => 'cousine issue de germaine six fois eloignee', 475: '3,10' => 'cousine issue de germaine sept fois eloignee', 476: '4,0' => 'arriere-arriere-grand-mere', 477: '4,1' => 'arriere-grand-tante', 478: '4,2' => 'cousine germaine deux fois eloignee', 479: '4,3' => 'cousine issue de germaine une fois eloignee', 480: '4,4' => 'cousine au quatrieme degre', 481: '4,5' => 'cousine au quatrieme degre une fois eloignee', 482: '4,6' => 'cousine au quatrieme degre deux fois eloignee', 483: '4,7' => "petite-cousine \N{U+00E9}loign\N{U+00E9}e au 3e degr\N{U+00E9}", 484: '4,8' => 'cousine au quatrieme degre quatre fois eloignee', 485: '4,9' => 'cousine au quatrieme degre cinq fois eloignee', 486: '4,10' => 'cousine au quatrieme degre six fois eloignee', 487: '5,0' => 'arriere-arriere-arriere-grand-mere', 488: '5,1' => 'arriere-arriere-grand-tante', 489: '5,2' => 'cousine germaine trois fois eloignee', 490: '5,3' => "cousine issue de germains \N{U+00E9}loign\N{U+00E9}e au 2e degr\N{U+00E9}", 491: '5,4' => 'cousine au quatrieme degre une fois eloignee', 492: '5,5' => 'cousine au cinquieme degre', 493: '5,6' => "arri\N{U+00E8}re-petite-cousine \N{U+00E9}loign\N{U+00E9}e au 1er degr\N{U+00E9}", 494: '5,7' => "arri\N{U+00E8}re-petite-cousine \N{U+00E9}loign\N{U+00E9}e au 2e degr\N{U+00E9}", 495: '5,8' => 'cousine au cinquieme degre trois fois eloignee', 496: '5,9' => 'cousine au cinquieme degre quatre fois eloignee', 497: '5,10' => 'cousine au cinquieme degre cinq fois eloignee', 498: '6,0' => 'arriere-arriere-arriere-arriere-grand-mere', 499: '6,1' => 'arriere-arriere-arriere-grand-tante', 500: '6,2' => 'cousine germaine quatre fois eloignee', 501: '6,3' => 'cousine issue de germaine trois fois eloignee', 502: '6,4' => 'cousine au quatrieme degre deux fois eloignee', 503: '6,6' => "arri\N{U+00E8}re-arri\N{U+00E8}re-petite-cousine", 504: '6,6' => 'cousine au sixieme degre', 505: '6,7' => 'cousine au sixieme degre une fois eloignee', 506: '6,8' => 'cousine au sixieme degre deux fois eloignee', 507: '6,9' => 'cousine au sixieme degre trois fois eloignee', 508: '6,10' => 'cousine au sixieme degre quatre fois eloignee', 509: '7,0' => 'arriere-arriere-arriere-arriere-arriere-grand-mere', 510: '7,1' => 'arriere-arriere-arriere-arriere-grand-tante', 511: '7,2' => 'cousine germaine cinq fois eloignee', 512: '7,3' => 'cousine issue de germaine quatre fois eloignee', 513: '7,4' => "petite-cousine \N{U+00E9}loign\N{U+00E9}e au 3e degr\N{U+00E9}", 514: '7,5' => "arri\N{U+00E8}re-petite-cousine \N{U+00E9}loign\N{U+00E9}e au 2e degr\N{U+00E9}", 515: '7,6' => 'cousine au sixieme degre une fois eloignee', 516: '7,7' => "sixi\N{U+00E8}me cousin", 517: '7,8' => "sixi\N{U+00E8}me cousin once-removed", 518: '7,9' => 'cousine au septieme degre deux fois eloignee', 519: '7,10' => 'cousine au septieme degre trois fois eloignee', 520: '8,0' => 'arriere-arriere-arriere-arriere-arriere-arriere-grand-mere', 521: '8,1' => 'arriere-arriere-arriere-arriere-arriere-grand-tante', 522: '8,2' => 'cousine germaine six fois eloignee', 523: '8,3' => 'cousine issue de germaine cinq fois eloignee', 524: '8,4' => 'cousine au quatrieme degre quatre fois eloignee', 525: '8,5' => 'cousine au cinquieme degre trois fois eloignee', 526: '8,6' => 'cousine au sixieme degre deux fois eloignee', 527: '8,7' => "sixi\N{U+00E8}me cousin once-removed", 528: '8,8' => 'cousine au huitieme degre', 529: '8,9' => 'cousine au huitieme degre une fois eloignee', 530: '8,10' => 'cousine au huitieme degre deux fois eloignee', 531: '9,0' => 'arriere-arriere-arriere-arriere-arriere-arriere-arriere-grand-mere', 532: '9,1' => 'arriere-arriere-arriere-arriere-arriere-arriere-grand-tante', 533: '9,2' => 'cousine germaine sept fois eloignee', 534: '9,3' => 'cousine issue de germaine six fois eloignee', 535: '9,4' => 'cousine au quatrieme degre cinq fois eloignee', 536: '9,5' => 'cousine au cinquieme degre quatre fois eloignee', 537: '9,6' => 'cousine au sixieme degre trois fois eloignee', 538: '9,7' => 'cousine au septieme degre deux fois eloignee', 539: '9,8' => 'cousine au huitieme degre une fois eloignee', 540: '9,9' => 'cousine au neuvieme degre', 541: '9,10' => 'cousine au neuvieme degre une fois eloignee', 542: '10,0' => 'arriere-arriere-arriere-arriere-arriere-arriere-arriere-arriere-grand-mere', 543: '10,1' => 'arriere-arriere-arriere-arriere-arriere-arriere-arriere-grand-tante', 544: '10,2' => 'cousine germaine huit fois eloignee', 545: '10,3' => 'cousine issue de germaine sept fois eloignee', 546: '10,4' => 'cousine au quatrieme degre six fois eloignee', 547: '10,5' => 'cousine au cinquieme degre cinq fois eloignee', 548: '10,6' => 'cousine au sixieme degre quatre fois eloignee', 549: '10,7' => 'cousine au septieme degre trois fois eloignee', 550: '10,8' => 'cousine au huitieme degre deux fois eloignee', 551: '10,9' => 'cousine au neuvieme degre une fois eloignee', 552: '10,10' => 'cousine au dixieme degre', 553: '11,1' => "huit\N{U+0153}me grand-tant", 554: '12,1' => "neuvi\N{U+0153}me grand-tant", 555: '13,1' => "dixi\N{U+0153}me grand-tant", 556: ); 557: 558: # --------------------------------------------------------------------------- 559: # German relationship tables 560: # --------------------------------------------------------------------------- 561: 562: Readonly::Hash my %DE_MALE_RELATIONSHIPS => ( 563: '0,0' => 'sich selbst', 564: '0,1' => 'Sohn', 565: '0,2' => 'Enkel', 566: '0,3' => 'Urenkel', 567: '0,4' => 'Ururenkel', 568: '0,5' => 'Urururenkel', 569: '0,6' => 'Ururururenkel', 570: '0,7' => 'Urururururenkel', 571: '0,8' => 'Ururururururenkel', 572: '0,9' => 'Urururururururenkel', 573: '0,10' => 'Ururururururururenkel', 574: '1,0' => 'Vater', 575: '1,1' => 'Bruder', 576: '1,2' => 'Neffe', 577: '1,3' => "Gro\N{U+00DF}neffe", 578: '1,4' => 'Urgrossneffe', 579: '1,5' => 'Ururgrossneffe', 580: '1,6' => 'Urururgrossneffe', 581: '1,7' => 'Ururururgrossneffe', 582: '1,8' => 'Urururururgrossneffe', 583: '1,9' => 'Ururururururgrossneffe', 584: '1,10' => 'Urururururururgrossneffe', 585: '2,0' => "Gro\N{U+00DF}vater", 586: '2,1' => 'Onkel', 587: '2,2' => 'Cousin', 588: '2,3' => 'Cousin einmal entfernt', 589: '2,4' => 'Cousin zweimal entfernt', 590: '2,5' => 'Cousin dreimal entfernt', 591: '2,6' => 'Cousin viermal entfernt', 592: '2,7' => 'Cousin fuenfmal entfernt', 593: '2,8' => 'Cousin sechsmal entfernt', 594: '2,9' => 'Cousin siebenmal entfernt', 595: '2,10' => 'Cousin achtmal entfernt', 596: '3,0' => 'Urgrossvater', 597: '3,1' => "Gro\N{U+00DF}onkel", 598: '3,2' => 'Cousin einmal entfernt', 599: '3,3' => 'Cousin zweiten Grades', 600: '3,4' => 'Cousin zweiten Grades einmal entfernt', 601: '3,5' => 'Cousin zweiten Grades zweimal entfernt', 602: '3,6' => 'Cousin zweiten Grades dreimal entfernt', 603: '3,7' => 'Cousin zweiten Grades viermal entfernt', 604: '3,8' => 'Cousin zweiten Grades fuenfmal entfernt', 605: '3,9' => 'Cousin zweiten Grades sechsmal entfernt', 606: '3,10' => 'Cousin zweiten Grades siebenmal entfernt', 607: '4,0' => 'Ururgrossvater', 608: '4,1' => 'Urgrossonkel', 609: '4,2' => 'Cousin zweimal entfernt', 610: '4,3' => 'Cousin zweiten Grades einmal entfernt', 611: '4,4' => 'Cousin dritten Grades', 612: '4,5' => 'Cousin dritten Grades einmal entfernt', 613: '4,6' => 'Cousin dritten Grades zweimal entfernt', 614: '4,7' => 'Cousin dritten Grades dreimal entfernt', 615: '4,8' => 'Cousin dritten Grades viermal entfernt', 616: '4,9' => 'Cousin dritten Grades fuenfmal entfernt', 617: '4,10' => 'Cousin dritten Grades sechsmal entfernt', 618: '5,0' => 'Urururgrossvater', 619: '5,1' => 'Ururgrossonkel', 620: '5,2' => 'Cousin dreimal entfernt', 621: '5,3' => 'Cousin zweiten Grades zweimal entfernt', 622: '5,4' => 'Cousin dritten Grades einmal entfernt', 623: '5,5' => 'Cousin vierten Grades', 624: '5,6' => 'Cousin vierten Grades einmal entfernt', 625: '5,7' => 'Cousin vierten Grades zweimal entfernt', 626: '5,8' => 'Cousin vierten Grades dreimal entfernt', 627: '5,9' => 'Cousin vierten Grades viermal entfernt', 628: '5,10' => 'Cousin vierten Grades fuenfmal entfernt', 629: '6,0' => 'Ururururgrossvater', 630: '6,1' => 'Urururgrossonkel', 631: '6,2' => 'Cousin viermal entfernt', 632: '6,3' => 'Cousin zweiten Grades dreimal entfernt', 633: '6,4' => 'Cousin dritten Grades zweimal entfernt', 634: '6,5' => 'Cousin vierten Grades einmal entfernt', 635: '6,6' => 'Cousin fuenften Grades', 636: '6,7' => 'Cousin fuenften Grades einmal entfernt', 637: '6,8' => 'Cousin fuenften Grades zweimal entfernt', 638: '6,9' => 'Cousin fuenften Grades dreimal entfernt', 639: '6,10' => 'Cousin fuenften Grades viermal entfernt', 640: '7,0' => 'Urururururgrossvater', 641: '7,1' => 'Ururururgrossonkel', 642: '7,2' => 'Cousin fuenfmal entfernt', 643: '7,3' => 'Cousin zweiten Grades viermal entfernt', 644: '7,4' => 'Cousin dritten Grades dreimal entfernt', 645: '7,5' => 'Cousin vierten Grades zweimal entfernt', 646: '7,6' => 'Cousin fuenften Grades einmal entfernt', 647: '7,7' => 'Cousin sechsten Grades', 648: '7,8' => 'Cousin sechsten Grades einmal entfernt', 649: '7,9' => 'Cousin sechsten Grades zweimal entfernt', 650: '7,10' => 'Cousin sechsten Grades dreimal entfernt', 651: '8,0' => 'Ururururururgrossvater', 652: '8,1' => 'Urururururgrossonkel', 653: '8,2' => 'Cousin sechsmal entfernt', 654: '8,3' => 'Cousin zweiten Grades fuenfmal entfernt', 655: '8,4' => 'Cousin dritten Grades viermal entfernt', 656: '8,5' => 'Cousin vierten Grades dreimal entfernt', 657: '8,6' => 'Cousin fuenften Grades zweimal entfernt', 658: '8,7' => 'Cousin sechsten Grades einmal entfernt', 659: '8,8' => 'Cousin siebten Grades', 660: '8,9' => 'Cousin siebten Grades einmal entfernt', 661: '8,10' => 'Cousin siebten Grades zweimal entfernt', 662: '9,0' => 'Urururururururgrossvater', 663: '9,1' => 'Ururururururgrossonkel', 664: '9,2' => 'Cousin siebenmal entfernt', 665: '9,3' => 'Cousin zweiten Grades sechsmal entfernt', 666: '9,4' => 'Cousin dritten Grades fuenfmal entfernt', 667: '9,5' => 'Cousin vierten Grades viermal entfernt', 668: '9,6' => 'Cousin fuenften Grades dreimal entfernt', 669: '9,7' => 'Cousin sechsten Grades zweimal entfernt', 670: '9,8' => 'Cousin siebten Grades einmal entfernt', 671: '9,9' => 'Cousin achten Grades', 672: '9,10' => 'Cousin achten Grades einmal entfernt', 673: '10,0' => 'Ururururururururgrossvater', 674: '10,1' => 'Urururururururgrossonkel', 675: '10,2' => 'Cousin achtmal entfernt', 676: '10,3' => 'Cousin zweiten Grades siebenmal entfernt', 677: '10,4' => 'Cousin dritten Grades sechsmal entfernt', 678: '10,5' => 'Cousin vierten Grades fuenfmal entfernt', 679: '10,6' => 'Cousin fuenften Grades viermal entfernt', 680: '10,7' => 'Cousin sechsten Grades dreimal entfernt', 681: '10,8' => 'Cousin siebten Grades zweimal entfernt', 682: '10,9' => 'Cousin achten Grades einmal entfernt', 683: '10,10' => 'Cousin neunten Grades', 684: '11,1' => 'achtens grossonkel', 685: '12,1' => 'neuntens grossonkel', 686: '13,1' => 'zehntens grossonkel', 687: ); 688: 689: Readonly::Hash my %DE_FEMALE_RELATIONSHIPS => ( 690: '0,0' => 'sich selbst', 691: '0,1' => 'Tochter', 692: '0,2' => 'Enkelin', 693: '0,3' => 'Urenkelin', 694: '0,4' => 'Ururenkelin', 695: '0,5' => 'Urururenkelin', 696: '0,6' => 'Ururururenkelin', 697: '0,7' => 'Urururururenkelin', 698: '0,8' => 'Ururururururenkelin', 699: '0,9' => 'Urururururururenkelin', 700: '0,10' => 'Ururururururururenkelin', 701: '1,0' => 'Mutter', 702: '1,1' => 'Schwester', 703: '1,2' => 'Nichte', 704: '1,3' => "Gro\N{U+00DF}nichte", 705: '1,4' => 'Urgrossnichte', 706: '1,5' => 'Ururgrossnichte', 707: '1,6' => 'Urururgrossnichte', 708: '1,7' => 'Ururururgrossnichte', 709: '1,8' => 'Urururururgrossnichte', 710: '1,9' => 'Ururururururgrossnichte', 711: '1,10' => 'Urururururururgrossnichte', 712: '2,0' => "Gro\N{U+00DF}mutter", 713: '2,1' => 'Tante', 714: '2,2' => 'Cousine', 715: '2,3' => 'Cousine einmal entfernt', 716: '2,4' => 'Cousine zweimal entfernt', 717: '2,5' => 'Cousine dreimal entfernt', 718: '2,6' => 'Cousine viermal entfernt', 719: '2,7' => 'Cousine fuenfmal entfernt', 720: '2,8' => 'Cousine sechsmal entfernt', 721: '2,9' => 'Cousine siebenmal entfernt', 722: '2,10' => 'Cousine achtmal entfernt', 723: '3,0' => 'Urgrossmutter', 724: '3,1' => "Gro\N{U+00DF}tante", 725: '3,2' => 'Cousine einmal entfernt', 726: '3,3' => 'Cousine zweiten Grades', 727: '3,4' => 'Cousine zweiten Grades einmal entfernt', 728: '3,5' => 'Cousine zweiten Grades zweimal entfernt', 729: '3,6' => 'Cousine zweiten Grades dreimal entfernt', 730: '3,7' => 'Cousine zweiten Grades viermal entfernt', 731: '3,8' => 'Cousine zweiten Grades fuenfmal entfernt', 732: '3,9' => 'Cousine zweiten Grades sechsmal entfernt', 733: '3,10' => 'Cousine zweiten Grades siebenmal entfernt', 734: '4,0' => 'Ururgrossmutter', 735: '4,1' => 'Urgrosstante', 736: '4,2' => 'Cousine zweimal entfernt', 737: '4,3' => 'Cousine zweiten Grades einmal entfernt', 738: '4,4' => 'Cousine dritten Grades', 739: '4,5' => 'Cousine dritten Grades einmal entfernt', 740: '4,6' => 'Cousine dritten Grades zweimal entfernt', 741: '4,7' => 'Cousine dritten Grades dreimal entfernt', 742: '4,8' => 'Cousine dritten Grades viermal entfernt', 743: '4,9' => 'Cousine dritten Grades fuenfmal entfernt', 744: '4,10' => 'Cousine dritten Grades sechsmal entfernt', 745: '5,0' => 'Urururgrossmutter', 746: '5,1' => 'Ururgrosstante', 747: '5,2' => 'Cousine dreimal entfernt', 748: '5,3' => 'Cousine zweiten Grades zweimal entfernt', 749: '5,4' => 'Cousine dritten Grades einmal entfernt', 750: '5,5' => 'Cousine vierten Grades', 751: '5,6' => 'Cousine vierten Grades einmal entfernt', 752: '5,7' => 'Cousine vierten Grades zweimal entfernt', 753: '5,8' => 'Cousine vierten Grades dreimal entfernt', 754: '5,9' => 'Cousine vierten Grades viermal entfernt', 755: '5,10' => 'Cousine vierten Grades fuenfmal entfernt', 756: '6,0' => 'Ururururgrossmutter', 757: '6,1' => 'Urururgrosstante', 758: '6,2' => 'Cousine viermal entfernt', 759: '6,3' => 'Cousine zweiten Grades dreimal entfernt', 760: '6,4' => 'Cousine dritten Grades zweimal entfernt', 761: '6,5' => 'Cousine vierten Grades einmal entfernt', 762: '6,6' => 'Cousine fuenften Grades', 763: '6,7' => 'Cousine fuenften Grades einmal entfernt', 764: '6,8' => 'Cousine fuenften Grades zweimal entfernt', 765: '6,9' => 'Cousine fuenften Grades dreimal entfernt', 766: '6,10' => 'Cousine fuenften Grades viermal entfernt', 767: '7,0' => 'Urururururgrossmutter', 768: '7,1' => 'Ururururgrosstante', 769: '7,2' => 'Cousine fuenfmal entfernt', 770: '7,3' => 'Cousine zweiten Grades viermal entfernt', 771: '7,4' => 'Cousine dritten Grades dreimal entfernt', 772: '7,5' => 'Cousine vierten Grades zweimal entfernt', 773: '7,6' => 'Cousine fuenften Grades einmal entfernt', 774: '7,7' => 'Cousine sechsten Grades', 775: '7,8' => 'Cousine sechsten Grades einmal entfernt', 776: '7,9' => 'Cousine sechsten Grades zweimal entfernt', 777: '7,10' => 'Cousine sechsten Grades dreimal entfernt', 778: '8,0' => 'Ururururururgrossmutter', 779: '8,1' => 'Urururururgrosstante', 780: '8,2' => 'Cousine sechsmal entfernt', 781: '8,3' => 'Cousine zweiten Grades fuenfmal entfernt', 782: '8,4' => 'Cousine dritten Grades viermal entfernt', 783: '8,5' => 'Cousine vierten Grades dreimal entfernt', 784: '8,6' => 'Cousine fuenften Grades zweimal entfernt', 785: '8,7' => 'Cousine sechsten Grades einmal entfernt', 786: '8,8' => 'Cousine siebten Grades', 787: '8,9' => 'Cousine siebten Grades einmal entfernt', 788: '8,10' => 'Cousine siebten Grades zweimal entfernt', 789: '9,0' => 'Urururururururgrossmutter', 790: '9,1' => 'Ururururururgrosstante', 791: '9,2' => 'Cousine siebenmal entfernt', 792: '9,3' => 'Cousine zweiten Grades sechsmal entfernt', 793: '9,4' => 'Cousine dritten Grades fuenfmal entfernt', 794: '9,5' => 'Cousine vierten Grades viermal entfernt', 795: '9,6' => 'Cousine fuenften Grades dreimal entfernt', 796: '9,7' => 'Cousine sechsten Grades zweimal entfernt', 797: '9,8' => 'Cousine siebten Grades einmal entfernt', 798: '9,9' => 'Cousine achten Grades', 799: '9,10' => 'Cousine achten Grades einmal entfernt', 800: '10,0' => 'Ururururururururgrossmutter', 801: '10,1' => 'Urururururururgrosstante', 802: '10,2' => 'Cousine achtmal entfernt', 803: '10,3' => 'Cousine zweiten Grades siebenmal entfernt', 804: '10,4' => 'Cousine dritten Grades sechsmal entfernt', 805: '10,5' => 'Cousine vierten Grades fuenfmal entfernt', 806: '10,6' => 'Cousine fuenften Grades viermal entfernt', 807: '10,7' => 'Cousine sechsten Grades dreimal entfernt', 808: '10,8' => 'Cousine siebten Grades zweimal entfernt', 809: '10,9' => 'Cousine achten Grades einmal entfernt', 810: '10,10' => 'Cousine neunten Grades', 811: '11,1' => 'achtens grosstante', 812: '12,1' => 'neuntens grosstante', 813: '13,1' => 'zehntens grosstante', 814: ); 815: 816: # --------------------------------------------------------------------------- 817: # Swiss German (de-CH) relationship tables 818: # Uses 'ss' instead of Eszett (\N{U+00DF}); Switzerland abolished à in 1934 819: # --------------------------------------------------------------------------- 820: 821: Readonly::Hash my %DE_CH_MALE_RELATIONSHIPS => ( 822: '0,0' => 'sich selbst', 823: '0,1' => 'Sohn', 824: '0,2' => 'Enkel', 825: '0,3' => 'Urenkel', 826: '0,4' => 'Ururenkel', 827: '0,5' => 'Urururenkel', 828: '0,6' => 'Ururururenkel', 829: '0,7' => 'Urururururenkel', 830: '0,8' => 'Ururururururenkel', 831: '0,9' => 'Urururururururenkel', 832: '0,10' => 'Ururururururururenkel', 833: '1,0' => 'Vater', 834: '1,1' => 'Bruder', 835: '1,2' => 'Neffe', 836: '1,3' => 'Grossneffe', 837: '1,4' => 'Urgrossneffe', 838: '1,5' => 'Ururgrossneffe', 839: '1,6' => 'Urururgrossneffe', 840: '1,7' => 'Ururururgrossneffe', 841: '1,8' => 'Urururururgrossneffe', 842: '1,9' => 'Ururururururgrossneffe', 843: '1,10' => 'Urururururururgrossneffe', 844: '2,0' => 'Grossvater', 845: '2,1' => 'Onkel', 846: '2,2' => 'Cousin', 847: '2,3' => 'Cousin einmal entfernt', 848: '2,4' => 'Cousin zweimal entfernt', 849: '2,5' => 'Cousin dreimal entfernt', 850: '2,6' => 'Cousin viermal entfernt', 851: '2,7' => 'Cousin fuenfmal entfernt', 852: '2,8' => 'Cousin sechsmal entfernt', 853: '2,9' => 'Cousin siebenmal entfernt', 854: '2,10' => 'Cousin achtmal entfernt', 855: '3,0' => 'Urgrossvater', 856: '3,1' => 'Grossonkel', 857: '3,2' => 'Cousin einmal entfernt', 858: '3,3' => 'Cousin zweiten Grades', 859: '3,4' => 'Cousin zweiten Grades einmal entfernt', 860: '3,5' => 'Cousin zweiten Grades zweimal entfernt', 861: '3,6' => 'Cousin zweiten Grades dreimal entfernt', 862: '3,7' => 'Cousin zweiten Grades viermal entfernt', 863: '3,8' => 'Cousin zweiten Grades fuenfmal entfernt', 864: '3,9' => 'Cousin zweiten Grades sechsmal entfernt', 865: '3,10' => 'Cousin zweiten Grades siebenmal entfernt', 866: '4,0' => 'Ururgrossvater', 867: '4,1' => 'Urgrossonkel', 868: '4,2' => 'Cousin zweimal entfernt', 869: '4,3' => 'Cousin zweiten Grades einmal entfernt', 870: '4,4' => 'Cousin dritten Grades', 871: '4,5' => 'Cousin dritten Grades einmal entfernt', 872: '4,6' => 'Cousin dritten Grades zweimal entfernt', 873: '4,7' => 'Cousin dritten Grades dreimal entfernt', 874: '4,8' => 'Cousin dritten Grades viermal entfernt', 875: '4,9' => 'Cousin dritten Grades fuenfmal entfernt', 876: '4,10' => 'Cousin dritten Grades sechsmal entfernt', 877: '5,0' => 'Urururgrossvater', 878: '5,1' => 'Ururgrossonkel', 879: '5,2' => 'Cousin dreimal entfernt', 880: '5,3' => 'Cousin zweiten Grades zweimal entfernt', 881: '5,4' => 'Cousin dritten Grades einmal entfernt', 882: '5,5' => 'Cousin vierten Grades', 883: '5,6' => 'Cousin vierten Grades einmal entfernt', 884: '5,7' => 'Cousin vierten Grades zweimal entfernt', 885: '5,8' => 'Cousin vierten Grades dreimal entfernt', 886: '5,9' => 'Cousin vierten Grades viermal entfernt', 887: '5,10' => 'Cousin vierten Grades fuenfmal entfernt', 888: '6,0' => 'Ururururgrossvater', 889: '6,1' => 'Urururgrossonkel', 890: '6,2' => 'Cousin viermal entfernt', 891: '6,3' => 'Cousin zweiten Grades dreimal entfernt', 892: '6,4' => 'Cousin dritten Grades zweimal entfernt', 893: '6,5' => 'Cousin vierten Grades einmal entfernt', 894: '6,6' => 'Cousin fuenften Grades', 895: '6,7' => 'Cousin fuenften Grades einmal entfernt', 896: '6,8' => 'Cousin fuenften Grades zweimal entfernt', 897: '6,9' => 'Cousin fuenften Grades dreimal entfernt', 898: '6,10' => 'Cousin fuenften Grades viermal entfernt', 899: '7,0' => 'Urururururgrossvater', 900: '7,1' => 'Ururururgrossonkel', 901: '7,2' => 'Cousin fuenfmal entfernt', 902: '7,3' => 'Cousin zweiten Grades viermal entfernt', 903: '7,4' => 'Cousin dritten Grades dreimal entfernt', 904: '7,5' => 'Cousin vierten Grades zweimal entfernt', 905: '7,6' => 'Cousin fuenften Grades einmal entfernt', 906: '7,7' => 'Cousin sechsten Grades', 907: '7,8' => 'Cousin sechsten Grades einmal entfernt', 908: '7,9' => 'Cousin sechsten Grades zweimal entfernt', 909: '7,10' => 'Cousin sechsten Grades dreimal entfernt', 910: '8,0' => 'Ururururururgrossvater', 911: '8,1' => 'Urururururgrossonkel', 912: '8,2' => 'Cousin sechsmal entfernt', 913: '8,3' => 'Cousin zweiten Grades fuenfmal entfernt', 914: '8,4' => 'Cousin dritten Grades viermal entfernt', 915: '8,5' => 'Cousin vierten Grades dreimal entfernt', 916: '8,6' => 'Cousin fuenften Grades zweimal entfernt', 917: '8,7' => 'Cousin sechsten Grades einmal entfernt', 918: '8,8' => 'Cousin siebten Grades', 919: '8,9' => 'Cousin siebten Grades einmal entfernt', 920: '8,10' => 'Cousin siebten Grades zweimal entfernt', 921: '9,0' => 'Urururururururgrossvater', 922: '9,1' => 'Ururururururgrossonkel', 923: '9,2' => 'Cousin siebenmal entfernt', 924: '9,3' => 'Cousin zweiten Grades sechsmal entfernt', 925: '9,4' => 'Cousin dritten Grades fuenfmal entfernt', 926: '9,5' => 'Cousin vierten Grades viermal entfernt', 927: '9,6' => 'Cousin fuenften Grades dreimal entfernt', 928: '9,7' => 'Cousin sechsten Grades zweimal entfernt', 929: '9,8' => 'Cousin siebten Grades einmal entfernt', 930: '9,9' => 'Cousin achten Grades', 931: '9,10' => 'Cousin achten Grades einmal entfernt', 932: '10,0' => 'Ururururururururgrossvater', 933: '10,1' => 'Urururururururgrossonkel', 934: '10,2' => 'Cousin achtmal entfernt', 935: '10,3' => 'Cousin zweiten Grades siebenmal entfernt', 936: '10,4' => 'Cousin dritten Grades sechsmal entfernt', 937: '10,5' => 'Cousin vierten Grades fuenfmal entfernt', 938: '10,6' => 'Cousin fuenften Grades viermal entfernt', 939: '10,7' => 'Cousin sechsten Grades dreimal entfernt', 940: '10,8' => 'Cousin siebten Grades zweimal entfernt', 941: '10,9' => 'Cousin achten Grades einmal entfernt', 942: '10,10' => 'Cousin neunten Grades', 943: '12,1' => 'neuntens grossonkel', 944: '13,1' => 'zehntens grossonkel', 945: ); 946: 947: Readonly::Hash my %DE_CH_FEMALE_RELATIONSHIPS => ( 948: '0,0' => 'sich selbst', 949: '0,1' => 'Tochter', 950: '0,2' => 'Enkelin', 951: '0,3' => 'Urenkelin', 952: '0,4' => 'Ururenkelin', 953: '0,5' => 'Urururenkelin', 954: '0,6' => 'Ururururenkelin', 955: '0,7' => 'Urururururenkelin', 956: '0,8' => 'Ururururururenkelin', 957: '0,9' => 'Urururururururenkelin', 958: '0,10' => 'Ururururururururenkelin', 959: '1,0' => 'Mutter', 960: '1,1' => 'Schwester', 961: '1,2' => 'Nichte', 962: '1,3' => 'Grossnichte', 963: '1,4' => 'Urgrossnichte', 964: '1,5' => 'Ururgrossnichte', 965: '1,6' => 'Urururgrossnichte', 966: '1,7' => 'Ururururgrossnichte', 967: '1,8' => 'Urururururgrossnichte', 968: '1,9' => 'Ururururururgrossnichte', 969: '1,10' => 'Urururururururgrossnichte', 970: '2,0' => 'Grossmutter', 971: '2,1' => 'Tante', 972: '2,2' => 'Cousine', 973: '2,3' => 'Cousine einmal entfernt', 974: '2,4' => 'Cousine zweimal entfernt', 975: '2,5' => 'Cousine dreimal entfernt', 976: '2,6' => 'Cousine viermal entfernt', 977: '2,7' => 'Cousine fuenfmal entfernt', 978: '2,8' => 'Cousine sechsmal entfernt', 979: '2,9' => 'Cousine siebenmal entfernt', 980: '2,10' => 'Cousine achtmal entfernt', 981: '3,0' => 'Urgrossmutter', 982: '3,1' => 'Grosstante', 983: '3,2' => 'Cousine einmal entfernt', 984: '3,3' => 'Cousine zweiten Grades', 985: '3,4' => 'Cousine zweiten Grades einmal entfernt', 986: '3,5' => 'Cousine zweiten Grades zweimal entfernt', 987: '3,6' => 'Cousine zweiten Grades dreimal entfernt', 988: '3,7' => 'Cousine zweiten Grades viermal entfernt', 989: '3,8' => 'Cousine zweiten Grades fuenfmal entfernt', 990: '3,9' => 'Cousine zweiten Grades sechsmal entfernt', 991: '3,10' => 'Cousine zweiten Grades siebenmal entfernt', 992: '4,0' => 'Ururgrossmutter', 993: '4,1' => 'Urgrosstante', 994: '4,2' => 'Cousine zweimal entfernt', 995: '4,3' => 'Cousine zweiten Grades einmal entfernt', 996: '4,4' => 'Cousine dritten Grades', 997: '4,5' => 'Cousine dritten Grades einmal entfernt', 998: '4,6' => 'Cousine dritten Grades zweimal entfernt', 999: '4,7' => 'Cousine dritten Grades dreimal entfernt', 1000: '4,8' => 'Cousine dritten Grades viermal entfernt', 1001: '4,9' => 'Cousine dritten Grades fuenfmal entfernt', 1002: '4,10' => 'Cousine dritten Grades sechsmal entfernt', 1003: '5,0' => 'Urururgrossmutter', 1004: '5,1' => 'Ururgrosstante', 1005: '5,2' => 'Cousine dreimal entfernt', 1006: '5,3' => 'Cousine zweiten Grades zweimal entfernt', 1007: '5,4' => 'Cousine dritten Grades einmal entfernt', 1008: '5,5' => 'Cousine vierten Grades', 1009: '5,6' => 'Cousine vierten Grades einmal entfernt', 1010: '5,7' => 'Cousine vierten Grades zweimal entfernt', 1011: '5,8' => 'Cousine vierten Grades dreimal entfernt', 1012: '5,9' => 'Cousine vierten Grades viermal entfernt', 1013: '5,10' => 'Cousine vierten Grades fuenfmal entfernt', 1014: '6,0' => 'Ururururgrossmutter', 1015: '6,1' => 'Urururgrosstante', 1016: '6,2' => 'Cousine viermal entfernt', 1017: '6,3' => 'Cousine zweiten Grades dreimal entfernt', 1018: '6,4' => 'Cousine dritten Grades zweimal entfernt', 1019: '6,5' => 'Cousine vierten Grades einmal entfernt', 1020: '6,6' => 'Cousine fuenften Grades', 1021: '6,7' => 'Cousine fuenften Grades einmal entfernt', 1022: '6,8' => 'Cousine fuenften Grades zweimal entfernt', 1023: '6,9' => 'Cousine fuenften Grades dreimal entfernt', 1024: '6,10' => 'Cousine fuenften Grades viermal entfernt', 1025: '7,0' => 'Urururururgrossmutter', 1026: '7,1' => 'Ururururgrosstante', 1027: '7,2' => 'Cousine fuenfmal entfernt', 1028: '7,3' => 'Cousine zweiten Grades viermal entfernt', 1029: '7,4' => 'Cousine dritten Grades dreimal entfernt', 1030: '7,5' => 'Cousine vierten Grades zweimal entfernt', 1031: '7,6' => 'Cousine fuenften Grades einmal entfernt', 1032: '7,7' => 'Cousine sechsten Grades', 1033: '7,8' => 'Cousine sechsten Grades einmal entfernt', 1034: '7,9' => 'Cousine sechsten Grades zweimal entfernt', 1035: '7,10' => 'Cousine sechsten Grades dreimal entfernt', 1036: '8,0' => 'Ururururururgrossmutter', 1037: '8,1' => 'Urururururgrosstante', 1038: '8,2' => 'Cousine sechsmal entfernt', 1039: '8,3' => 'Cousine zweiten Grades fuenfmal entfernt', 1040: '8,4' => 'Cousine dritten Grades viermal entfernt', 1041: '8,5' => 'Cousine vierten Grades dreimal entfernt', 1042: '8,6' => 'Cousine fuenften Grades zweimal entfernt', 1043: '8,7' => 'Cousine sechsten Grades einmal entfernt', 1044: '8,8' => 'Cousine siebten Grades', 1045: '8,9' => 'Cousine siebten Grades einmal entfernt', 1046: '8,10' => 'Cousine siebten Grades zweimal entfernt', 1047: '9,0' => 'Urururururururgrossmutter', 1048: '9,1' => 'Ururururururgrosstante', 1049: '9,2' => 'Cousine siebenmal entfernt', 1050: '9,3' => 'Cousine zweiten Grades sechsmal entfernt', 1051: '9,4' => 'Cousine dritten Grades fuenfmal entfernt', 1052: '9,5' => 'Cousine vierten Grades viermal entfernt', 1053: '9,6' => 'Cousine fuenften Grades dreimal entfernt', 1054: '9,7' => 'Cousine sechsten Grades zweimal entfernt', 1055: '9,8' => 'Cousine siebten Grades einmal entfernt', 1056: '9,9' => 'Cousine achten Grades', 1057: '9,10' => 'Cousine achten Grades einmal entfernt', 1058: '10,0' => 'Ururururururururgrossmutter', 1059: '10,1' => 'Urururururururgrosstante', 1060: '10,2' => 'Cousine achtmal entfernt', 1061: '10,3' => 'Cousine zweiten Grades siebenmal entfernt', 1062: '10,4' => 'Cousine dritten Grades sechsmal entfernt', 1063: '10,5' => 'Cousine vierten Grades fuenfmal entfernt', 1064: '10,6' => 'Cousine fuenften Grades viermal entfernt', 1065: '10,7' => 'Cousine sechsten Grades dreimal entfernt', 1066: '10,8' => 'Cousine siebten Grades zweimal entfernt', 1067: '10,9' => 'Cousine achten Grades einmal entfernt', 1068: '10,10' => 'Cousine neunten Grades', 1069: '12,1' => 'neuntens grosstant', 1070: '13,1' => 'zehntens grosstant', 1071: ); 1072: 1073: # --------------------------------------------------------------------------- 1074: # Spanish relationship tables 1075: # --------------------------------------------------------------------------- 1076: 1077: Readonly::Hash my %ES_MALE_RELATIONSHIPS => ( 1078: '0,0' => 'uno mismo', 1079: '0,1' => 'hijo', 1080: '0,2' => 'nieto', 1081: '0,3' => 'bisnieto', 1082: '0,4' => 'tataranieto', 1083: '0,5' => 'chozno', 1084: '0,6' => 'bisnieto quinto', 1085: '0,7' => 'descendiente lejano', 1086: '0,8' => 'descendiente lejano', 1087: '0,9' => 'descendiente lejano', 1088: '0,10' => 'descendiente lejano', 1089: '1,0' => 'padre', 1090: '1,1' => 'hermano', 1091: '1,2' => 'sobrino', 1092: '1,3' => 'sobrino nieto', 1093: '1,4' => 'sobrino bisnieto', 1094: '1,5' => 'sobrino tataranieto', 1095: '1,6' => 'sobrino lejano', 1096: '1,7' => 'sobrino lejano', 1097: '1,8' => 'sobrino lejano', 1098: '1,9' => 'sobrino lejano', 1099: '1,10' => 'sobrino lejano', 1100: '2,0' => 'abuelo', 1101: '2,1' => 'tio', 1102: '2,2' => 'primo hermano', 1103: '2,3' => 'primo hermano una vez removido', 1104: '2,4' => 'primo hermano dos veces removido', 1105: '2,5' => 'primo hermano tres veces removido', 1106: '2,6' => 'primo hermano cuatro veces removido', 1107: '2,7' => 'primo hermano cinco veces removido', 1108: '2,8' => 'primo hermano seis veces removido', 1109: '2,9' => 'primo hermano siete veces removido', 1110: '2,10' => 'primo hermano ocho veces removido', 1111: '3,0' => 'bisabuelo', 1112: '3,1' => 'tio abuelo', 1113: '3,2' => 'primo hermano una vez removido', 1114: '3,3' => 'primo segundo', 1115: '3,4' => 'primo segundo una vez removido', 1116: '3,5' => 'primo segundo dos veces removido', 1117: '3,6' => 'primo segundo tres veces removido', 1118: '3,7' => 'primo segundo cuatro veces removido', 1119: '3,8' => 'primo segundo cinco veces removido', 1120: '3,9' => 'primo segundo seis veces removido', 1121: '3,10' => 'primo segundo siete veces removido', 1122: '4,0' => 'tatarabuelo', 1123: '4,1' => 'tio bisabuelo', 1124: '4,2' => 'primo hermano dos veces removido', 1125: '4,3' => 'primo segundo una vez removido', 1126: '4,4' => 'primo tercero', 1127: '4,5' => 'primo tercero una vez removido', 1128: '4,6' => 'primo tercero dos veces removido', 1129: '4,7' => 'primo tercero tres veces removido', 1130: '4,8' => 'primo tercero cuatro veces removido', 1131: '4,9' => 'primo tercero cinco veces removido', 1132: '4,10' => 'primo tercero seis veces removido', 1133: '5,0' => 'chozno', 1134: '5,1' => 'tio tatarabuelo', 1135: '5,2' => 'primo hermano tres veces removido', 1136: '5,3' => 'primo segundo dos veces removido', 1137: '5,4' => 'primo tercero una vez removido', 1138: '5,5' => 'primo cuarto', 1139: '5,6' => 'primo cuarto una vez removido', 1140: '5,7' => 'primo cuarto dos veces removido', 1141: '5,8' => 'primo cuarto tres veces removido', 1142: '5,9' => 'primo cuarto cuatro veces removido', 1143: '5,10' => 'primo cuarto cinco veces removido', 1144: '6,0' => 'bisabuelo quinto', 1145: '6,1' => 'tio lejano', 1146: '6,2' => 'primo hermano cuatro veces removido', 1147: '6,3' => 'primo segundo tres veces removido', 1148: '6,4' => 'primo tercero dos veces removido', 1149: '6,5' => 'primo cuarto una vez removido', 1150: '6,6' => 'primo quinto', 1151: '6,7' => 'primo quinto una vez removido', 1152: '6,8' => 'primo quinto dos veces removido', 1153: '6,9' => 'primo quinto tres veces removido', 1154: '6,10' => 'primo quinto cuatro veces removido', 1155: '7,0' => 'antepasado lejano', 1156: '7,1' => 'tio lejano', 1157: '7,2' => 'primo hermano cinco veces removido', 1158: '7,3' => 'primo segundo cuatro veces removido', 1159: '7,4' => 'primo tercero tres veces removido', 1160: '7,5' => 'primo cuarto dos veces removido', 1161: '7,6' => 'primo quinto una vez removido', 1162: '7,7' => 'primo sexto', 1163: '7,8' => 'primo sexto una vez removido', 1164: '7,9' => 'primo sexto dos veces removido', 1165: '7,10' => 'primo sexto tres veces removido', 1166: '8,0' => 'antepasado lejano', 1167: '8,1' => 'tio lejano', 1168: '8,2' => 'primo hermano seis veces removido', 1169: '8,3' => 'primo segundo cinco veces removido', 1170: '8,4' => 'primo tercero cuatro veces removido', 1171: '8,5' => 'primo cuarto tres veces removido', 1172: '8,6' => 'primo quinto dos veces removido', 1173: '8,7' => 'primo sexto una vez removido', 1174: '8,8' => 'primo septimo', 1175: '8,9' => 'primo septimo una vez removido', 1176: '8,10' => 'primo septimo dos veces removido', 1177: '9,0' => 'antepasado lejano', 1178: '9,1' => 'tio lejano', 1179: '9,2' => 'primo hermano siete veces removido', 1180: '9,3' => 'primo segundo seis veces removido', 1181: '9,4' => 'primo tercero cinco veces removido', 1182: '9,5' => 'primo cuarto cuatro veces removido', 1183: '9,6' => 'primo quinto tres veces removido', 1184: '9,7' => 'primo sexto dos veces removido', 1185: '9,8' => 'primo septimo una vez removido', 1186: '9,9' => 'primo octavo', 1187: '9,10' => 'primo octavo una vez removido', 1188: '10,0' => 'antepasado lejano', 1189: '10,1' => 'tio lejano', 1190: '10,2' => 'primo hermano ocho veces removido', 1191: '10,3' => 'primo segundo siete veces removido', 1192: '10,4' => 'primo tercero seis veces removido', 1193: '10,5' => 'primo cuarto cinco veces removido', 1194: '10,6' => 'primo quinto cuatro veces removido', 1195: '10,7' => 'primo sexto tres veces removido', 1196: '10,8' => 'primo septimo dos veces removido', 1197: '10,9' => 'primo octavo una vez removido', 1198: '10,10' => 'primo noveno', 1199: ); 1200: 1201: Readonly::Hash my %ES_FEMALE_RELATIONSHIPS => ( 1202: '0,0' => 'una misma', 1203: '0,1' => 'hija', 1204: '0,2' => 'nieta', 1205: '0,3' => 'bisnieta', 1206: '0,4' => 'tataranieta', 1207: '0,5' => 'chozna', 1208: '0,6' => 'bisnieta quinta', 1209: '0,7' => 'descendiente lejana', 1210: '0,8' => 'descendiente lejana', 1211: '0,9' => 'descendiente lejana', 1212: '0,10' => 'descendiente lejana', 1213: '1,0' => 'madre', 1214: '1,1' => 'hermana', 1215: '1,2' => 'sobrina', 1216: '1,3' => 'sobrina nieta', 1217: '1,4' => 'sobrina bisnieta', 1218: '1,5' => 'sobrina tataranieta', 1219: '1,6' => 'sobrina lejana', 1220: '1,7' => 'sobrina lejana', 1221: '1,8' => 'sobrina lejana', 1222: '1,9' => 'sobrina lejana', 1223: '1,10' => 'sobrina lejana', 1224: '2,0' => 'abuela', 1225: '2,1' => 'tia', 1226: '2,2' => 'prima hermana', 1227: '2,3' => 'prima hermana una vez removida', 1228: '2,4' => 'prima hermana dos veces removida', 1229: '2,5' => 'prima hermana tres veces removida', 1230: '2,6' => 'prima hermana cuatro veces removida', 1231: '2,7' => 'prima hermana cinco veces removida', 1232: '2,8' => 'prima hermana seis veces removida', 1233: '2,9' => 'prima hermana siete veces removida', 1234: '2,10' => 'prima hermana ocho veces removida', 1235: '3,0' => 'bisabuela', 1236: '3,1' => 'tia abuela', 1237: '3,2' => 'prima hermana una vez removida', 1238: '3,3' => 'prima segunda', 1239: '3,4' => 'prima segunda una vez removida', 1240: '3,5' => 'prima segunda dos veces removida', 1241: '3,6' => 'prima segunda tres veces removida', 1242: '3,7' => 'prima segunda cuatro veces removida', 1243: '3,8' => 'prima segunda cinco veces removida', 1244: '3,9' => 'prima segunda seis veces removida', 1245: '3,10' => 'prima segunda siete veces removida', 1246: '4,0' => 'tatarabuela', 1247: '4,1' => 'tia bisabuela', 1248: '4,2' => 'prima hermana dos veces removida', 1249: '4,3' => 'prima segunda una vez removida', 1250: '4,4' => 'prima tercera', 1251: '4,5' => 'prima tercera una vez removida', 1252: '4,6' => 'prima tercera dos veces removida', 1253: '4,7' => 'prima tercera tres veces removida', 1254: '4,8' => 'prima tercera cuatro veces removida', 1255: '4,9' => 'prima tercera cinco veces removida', 1256: '4,10' => 'prima tercera seis veces removida', 1257: '5,0' => 'chozna', 1258: '5,1' => 'tia tatarabuela', 1259: '5,2' => 'prima hermana tres veces removida', 1260: '5,3' => 'prima segunda dos veces removida', 1261: '5,4' => 'prima tercera una vez removida', 1262: '5,5' => 'prima cuarta', 1263: '5,6' => 'prima cuarta una vez removida', 1264: '5,7' => 'prima cuarta dos veces removida', 1265: '5,8' => 'prima cuarta tres veces removida', 1266: '5,9' => 'prima cuarta cuatro veces removida', 1267: '5,10' => 'prima cuarta cinco veces removida', 1268: '6,0' => 'bisabuela quinta', 1269: '6,1' => 'tia lejana', 1270: '6,2' => 'prima hermana cuatro veces removida', 1271: '6,3' => 'prima segunda tres veces removida', 1272: '6,4' => 'prima tercera dos veces removida', 1273: '6,5' => 'prima cuarta una vez removida', 1274: '6,6' => 'prima quinta', 1275: '6,7' => 'prima quinta una vez removida', 1276: '6,8' => 'prima quinta dos veces removida', 1277: '6,9' => 'prima quinta tres veces removida', 1278: '6,10' => 'prima quinta cuatro veces removida', 1279: '7,0' => 'antepasada lejana', 1280: '7,1' => 'tia lejana', 1281: '7,2' => 'prima hermana cinco veces removida', 1282: '7,3' => 'prima segunda cuatro veces removida', 1283: '7,4' => 'prima tercera tres veces removida', 1284: '7,5' => 'prima cuarta dos veces removida', 1285: '7,6' => 'prima quinta una vez removida', 1286: '7,7' => 'prima sexta', 1287: '7,8' => 'prima sexta una vez removida', 1288: '7,9' => 'prima sexta dos veces removida', 1289: '7,10' => 'prima sexta tres veces removida', 1290: '8,0' => 'antepasada lejana', 1291: '8,1' => 'tia lejana', 1292: '8,2' => 'prima hermana seis veces removida', 1293: '8,3' => 'prima segunda cinco veces removida', 1294: '8,4' => 'prima tercera cuatro veces removida', 1295: '8,5' => 'prima cuarta tres veces removida', 1296: '8,6' => 'prima quinta dos veces removida', 1297: '8,7' => 'prima sexta una vez removida', 1298: '8,8' => 'prima septima', 1299: '8,9' => 'prima septima una vez removida', 1300: '8,10' => 'prima septima dos veces removida', 1301: '9,0' => 'antepasada lejana', 1302: '9,1' => 'tia lejana', 1303: '9,2' => 'prima hermana siete veces removida', 1304: '9,3' => 'prima segunda seis veces removida', 1305: '9,4' => 'prima tercera cinco veces removida', 1306: '9,5' => 'prima cuarta cuatro veces removida', 1307: '9,6' => 'prima quinta tres veces removida', 1308: '9,7' => 'prima sexta dos veces removida', 1309: '9,8' => 'prima septima una vez removida', 1310: '9,9' => 'prima octava', 1311: '9,10' => 'prima octava una vez removida', 1312: '10,0' => 'antepasada lejana', 1313: '10,1' => 'tia lejana', 1314: '10,2' => 'prima hermana ocho veces removida', 1315: '10,3' => 'prima segunda siete veces removida', 1316: '10,4' => 'prima tercera seis veces removida', 1317: '10,5' => 'prima cuarta cinco veces removida', 1318: '10,6' => 'prima quinta cuatro veces removida', 1319: '10,7' => 'prima sexta tres veces removida', 1320: '10,8' => 'prima septima dos veces removida', 1321: '10,9' => 'prima octava una vez removida', 1322: '10,10' => 'prima novena', 1323: ); 1324: 1325: # --------------------------------------------------------------------------- 1326: # Farsi (Persian) relationship tables 1327: # Values use \N{U+XXXX} Unicode escapes (right-to-left script) 1328: # Side-specific keys: "s1,s2,paternal" / "s1,s2,maternal" 1329: # --------------------------------------------------------------------------- 1330: 1331: Readonly::Hash my %FA_MALE_RELATIONSHIPS => ( 1332: '0,0' => "\N{U+062E}\N{U+0648}\N{U+062F}", 1333: '0,1' => "\N{U+067E}\N{U+0633}\N{U+0631}", 1334: '0,2' => "\N{U+0646}\N{U+0648}\N{U+0647}", 1335: '0,3' => "\N{U+0646}\N{U+0648}\N{U+0647}", 1336: '0,4' => "\N{U+0646}\N{U+0648}\N{U+0647}", 1337: '0,5' => "\N{U+0646}\N{U+0648}\N{U+0647}", 1338: '0,6' => "\N{U+0646}\N{U+0648}\N{U+0647}", 1339: '0,7' => "\N{U+0646}\N{U+0648}\N{U+0647}", 1340: '0,8' => "\N{U+0646}\N{U+0648}\N{U+0647}", 1341: '0,9' => "\N{U+0646}\N{U+0648}\N{U+0647}", 1342: '0,10' => "\N{U+0646}\N{U+0648}\N{U+0647}", 1343: '1,0' => "\N{U+067E}\N{U+062F}\N{U+0631}", 1344: '1,1' => "\N{U+0628}\N{U+0631}\N{U+0627}\N{U+062F}\N{U+0631}", 1345: '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}", 1346: '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}", 1347: '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}", 1348: '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}", 1349: '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}", 1350: '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}", 1351: '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}", 1352: '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}", 1353: '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}", 1354: '2,0' => "\N{U+067E}\N{U+062F}\N{U+0631}\N{U+0628}\N{U+0632}\N{U+0631}\N{U+06AF}", 1355: '2,1' => "\N{U+0639}\N{U+0645}\N{U+0648}", 1356: '2,2' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1357: '2,3' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1358: '2,4' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1359: '2,5' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1360: '2,6' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1361: '2,7' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1362: '2,8' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1363: '2,9' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1364: '2,10' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1365: '3,0' => "\N{U+067E}\N{U+062F}\N{U+0631}\N{U+0628}\N{U+0632}\N{U+0631}\N{U+06AF}", 1366: '3,1' => "\N{U+0639}\N{U+0645}\N{U+0648}", 1367: '3,2' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1368: '3,3' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1369: '3,4' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1370: '3,5' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1371: '3,6' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1372: '3,7' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1373: '3,8' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1374: '3,9' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1375: '3,10' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1376: '4,0' => "\N{U+067E}\N{U+062F}\N{U+0631}\N{U+0628}\N{U+0632}\N{U+0631}\N{U+06AF}", 1377: '4,1' => "\N{U+0639}\N{U+0645}\N{U+0648}", 1378: '4,2' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1379: '4,3' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1380: '4,4' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1381: '4,5' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1382: '4,6' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1383: '4,7' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1384: '4,8' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1385: '4,9' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1386: '4,10' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1387: '5,0' => "\N{U+067E}\N{U+062F}\N{U+0631}\N{U+0628}\N{U+0632}\N{U+0631}\N{U+06AF}", 1388: '5,1' => "\N{U+0639}\N{U+0645}\N{U+0648}", 1389: '5,2' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1390: '5,3' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1391: '5,4' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1392: '5,5' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1393: '5,6' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1394: '5,7' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1395: '5,8' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1396: '5,9' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1397: '5,10' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1398: '6,0' => "\N{U+067E}\N{U+062F}\N{U+0631}\N{U+0628}\N{U+0632}\N{U+0631}\N{U+06AF}", 1399: '6,1' => "\N{U+0639}\N{U+0645}\N{U+0648}", 1400: '6,2' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1401: '6,3' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1402: '6,4' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1403: '6,5' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1404: '6,6' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1405: '6,7' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1406: '6,8' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1407: '6,9' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1408: '6,10' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1409: '7,0' => "\N{U+067E}\N{U+062F}\N{U+0631}\N{U+0628}\N{U+0632}\N{U+0631}\N{U+06AF}", 1410: '7,1' => "\N{U+0639}\N{U+0645}\N{U+0648}", 1411: '7,2' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1412: '7,3' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1413: '7,4' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1414: '7,5' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1415: '7,6' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1416: '7,7' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1417: '7,8' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1418: '7,9' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1419: '7,10' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1420: '8,0' => "\N{U+067E}\N{U+062F}\N{U+0631}\N{U+0628}\N{U+0632}\N{U+0631}\N{U+06AF}", 1421: '8,1' => "\N{U+0639}\N{U+0645}\N{U+0648}", 1422: '8,2' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1423: '8,3' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1424: '8,4' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1425: '8,5' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1426: '8,6' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1427: '8,7' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1428: '8,8' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1429: '8,9' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1430: '8,10' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1431: '9,0' => "\N{U+067E}\N{U+062F}\N{U+0631}\N{U+0628}\N{U+0632}\N{U+0631}\N{U+06AF}", 1432: '9,1' => "\N{U+0639}\N{U+0645}\N{U+0648}", 1433: '9,2' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1434: '9,3' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1435: '9,4' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1436: '9,5' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1437: '9,6' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1438: '9,7' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1439: '9,8' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1440: '9,9' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1441: '9,10' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1442: '10,0' => "\N{U+067E}\N{U+062F}\N{U+0631}\N{U+0628}\N{U+0632}\N{U+0631}\N{U+06AF}", 1443: '10,1' => "\N{U+0639}\N{U+0645}\N{U+0648}", 1444: '10,2' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1445: '10,3' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1446: '10,4' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1447: '10,5' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1448: '10,6' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1449: '10,7' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1450: '10,8' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1451: '10,9' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1452: '10,10' => "\N{U+067E}\N{U+0633}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1453: '2,1,maternal' => "\N{U+062F}\N{U+0627}\N{U+06CC}\N{U+06CC}", 1454: '2,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0648}", 1455: '3,1,maternal' => "\N{U+062F}\N{U+0627}\N{U+06CC}\N{U+06CC}", 1456: '3,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0648}", 1457: '4,1,maternal' => "\N{U+062F}\N{U+0627}\N{U+06CC}\N{U+06CC}", 1458: '4,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0648}", 1459: '5,1,maternal' => "\N{U+062F}\N{U+0627}\N{U+06CC}\N{U+06CC}", 1460: '5,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0648}", 1461: '6,1,maternal' => "\N{U+062F}\N{U+0627}\N{U+06CC}\N{U+06CC}", 1462: '6,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0648}", 1463: '7,1,maternal' => "\N{U+062F}\N{U+0627}\N{U+06CC}\N{U+06CC}", 1464: '7,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0648}", 1465: '8,1,maternal' => "\N{U+062F}\N{U+0627}\N{U+06CC}\N{U+06CC}", 1466: '8,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0648}", 1467: '9,1,maternal' => "\N{U+062F}\N{U+0627}\N{U+06CC}\N{U+06CC}", 1468: '9,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0648}", 1469: '10,1,maternal' => "\N{U+062F}\N{U+0627}\N{U+06CC}\N{U+06CC}", 1470: '10,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0648}", 1471: ); 1472: 1473: Readonly::Hash my %FA_FEMALE_RELATIONSHIPS => ( 1474: '0,0' => "\N{U+062E}\N{U+0648}\N{U+062F}", 1475: '0,1' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}", 1476: '0,2' => "\N{U+0646}\N{U+0648}\N{U+0647}", 1477: '0,3' => "\N{U+0646}\N{U+0648}\N{U+0647}", 1478: '0,4' => "\N{U+0646}\N{U+0648}\N{U+0647}", 1479: '0,5' => "\N{U+0646}\N{U+0648}\N{U+0647}", 1480: '0,6' => "\N{U+0646}\N{U+0648}\N{U+0647}", 1481: '0,7' => "\N{U+0646}\N{U+0648}\N{U+0647}", 1482: '0,8' => "\N{U+0646}\N{U+0648}\N{U+0647}", 1483: '0,9' => "\N{U+0646}\N{U+0648}\N{U+0647}", 1484: '0,10' => "\N{U+0646}\N{U+0648}\N{U+0647}", 1485: '1,0' => "\N{U+0645}\N{U+0627}\N{U+062F}\N{U+0631}", 1486: '1,1' => "\N{U+062E}\N{U+0648}\N{U+0627}\N{U+0647}\N{U+0631}", 1487: '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}", 1488: '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}", 1489: '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}", 1490: '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}", 1491: '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}", 1492: '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}", 1493: '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}", 1494: '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}", 1495: '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}", 1496: '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}", 1497: '2,1' => "\N{U+0639}\N{U+0645}\N{U+0647}", 1498: '2,2' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1499: '2,3' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1500: '2,4' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1501: '2,5' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1502: '2,6' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1503: '2,7' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1504: '2,8' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1505: '2,9' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1506: '2,10' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1507: '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}", 1508: '3,1' => "\N{U+0639}\N{U+0645}\N{U+0647}", 1509: '3,2' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1510: '3,3' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1511: '3,4' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1512: '3,5' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1513: '3,6' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1514: '3,7' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1515: '3,8' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1516: '3,9' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1517: '3,10' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1518: '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}", 1519: '4,1' => "\N{U+0639}\N{U+0645}\N{U+0647}", 1520: '4,2' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1521: '4,3' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1522: '4,4' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1523: '4,5' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1524: '4,6' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1525: '4,7' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1526: '4,8' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1527: '4,9' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1528: '4,10' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1529: '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}", 1530: '5,1' => "\N{U+0639}\N{U+0645}\N{U+0647}", 1531: '5,2' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1532: '5,3' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1533: '5,4' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1534: '5,5' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1535: '5,6' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1536: '5,7' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1537: '5,8' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1538: '5,9' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1539: '5,10' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1540: '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}", 1541: '6,1' => "\N{U+0639}\N{U+0645}\N{U+0647}", 1542: '6,2' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1543: '6,3' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1544: '6,4' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1545: '6,5' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1546: '6,6' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1547: '6,7' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1548: '6,8' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1549: '6,9' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1550: '6,10' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1551: '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}", 1552: '7,1' => "\N{U+0639}\N{U+0645}\N{U+0647}", 1553: '7,2' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1554: '7,3' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1555: '7,4' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1556: '7,5' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1557: '7,6' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1558: '7,7' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1559: '7,8' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1560: '7,9' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1561: '7,10' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1562: '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}", 1563: '8,1' => "\N{U+0639}\N{U+0645}\N{U+0647}", 1564: '8,2' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1565: '8,3' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1566: '8,4' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1567: '8,5' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1568: '8,6' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1569: '8,7' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1570: '8,8' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1571: '8,9' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1572: '8,10' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1573: '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}", 1574: '9,1' => "\N{U+0639}\N{U+0645}\N{U+0647}", 1575: '9,2' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1576: '9,3' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1577: '9,4' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1578: '9,5' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1579: '9,6' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1580: '9,7' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1581: '9,8' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1582: '9,9' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1583: '9,10' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1584: '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}", 1585: '10,1' => "\N{U+0639}\N{U+0645}\N{U+0647}", 1586: '10,2' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1587: '10,3' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1588: '10,4' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1589: '10,5' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1590: '10,6' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1591: '10,7' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1592: '10,8' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1593: '10,9' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1594: '10,10' => "\N{U+062F}\N{U+062E}\N{U+062A}\N{U+0631}\N{U+0639}\N{U+0645}\N{U+0648}", 1595: '2,1,maternal' => "\N{U+062E}\N{U+0627}\N{U+0644}\N{U+0647}", 1596: '2,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0647}", 1597: '3,1,maternal' => "\N{U+062E}\N{U+0627}\N{U+0644}\N{U+0647}", 1598: '3,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0647}", 1599: '4,1,maternal' => "\N{U+062E}\N{U+0627}\N{U+0644}\N{U+0647}", 1600: '4,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0647}", 1601: '5,1,maternal' => "\N{U+062E}\N{U+0627}\N{U+0644}\N{U+0647}", 1602: '5,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0647}", 1603: '6,1,maternal' => "\N{U+062E}\N{U+0627}\N{U+0644}\N{U+0647}", 1604: '6,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0647}", 1605: '7,1,maternal' => "\N{U+062E}\N{U+0627}\N{U+0644}\N{U+0647}", 1606: '7,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0647}", 1607: '8,1,maternal' => "\N{U+062E}\N{U+0627}\N{U+0644}\N{U+0647}", 1608: '8,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0647}", 1609: '9,1,maternal' => "\N{U+062E}\N{U+0627}\N{U+0644}\N{U+0647}", 1610: '9,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0647}", 1611: '10,1,maternal' => "\N{U+062E}\N{U+0627}\N{U+0644}\N{U+0647}", 1612: '10,1,paternal' => "\N{U+0639}\N{U+0645}\N{U+0647}", 1613: ); 1614: 1615: # --------------------------------------------------------------------------- 1616: # Classical Latin relationship tables 1617: # Many step-count combinations have no classical term; those keys are absent. 1618: # Side-specific keys: "s1,s2,paternal" / "s1,s2,maternal" 1619: # --------------------------------------------------------------------------- 1620: 1621: Readonly::Hash my %LA_MALE_RELATIONSHIPS => ( 1622: '0,0' => 'ipse', 1623: '0,1' => 'filius', 1624: '0,2' => 'nepos', 1625: '0,3' => 'pronepos', 1626: '0,4' => 'abnepos', 1627: '0,5' => 'atnepos', 1628: '0,6' => 'trinepos', 1629: '1,0' => 'pater', 1630: '1,1' => 'frater', 1631: '1,2' => 'nepos', 1632: '2,0' => 'avus', 1633: '2,1' => 'patruus', 1634: '2,2' => 'consobrinus', 1635: '3,0' => 'proavus', 1636: '3,1' => 'patruus magnus', 1637: '4,0' => 'abavus', 1638: '4,1' => 'patruus maior', 1639: '5,0' => 'atavus', 1640: '5,1' => 'patruus maximus', 1641: '6,0' => 'tritavus', 1642: '2,1,maternal' => 'avunculus', 1643: '2,1,paternal' => 'patruus', 1644: '2,2,maternal' => 'consobrinus', 1645: '2,2,paternal' => 'patruelis', 1646: '3,1,maternal' => 'avunculus magnus', 1647: '3,1,paternal' => 'patruus magnus', 1648: '4,1,maternal' => 'avunculus maior', 1649: '4,1,paternal' => 'patruus maior', 1650: '5,1,maternal' => 'avunculus maximus', 1651: '5,1,paternal' => 'patruus maximus', 1652: ); 1653: 1654: Readonly::Hash my %LA_FEMALE_RELATIONSHIPS => ( 1655: '0,0' => 'ipsa', 1656: '0,1' => 'filia', 1657: '0,2' => 'neptis', 1658: '0,3' => 'proneptis', 1659: '0,4' => 'abneptis', 1660: '0,5' => 'atneptis', 1661: '0,6' => 'trineptis', 1662: '1,0' => 'mater', 1663: '1,1' => 'soror', 1664: '1,2' => 'neptis', 1665: '2,0' => 'avia', 1666: '2,1' => 'amita', 1667: '2,2' => 'consobrina', 1668: '3,0' => 'proavia', 1669: '3,1' => 'amita magna', 1670: '4,0' => 'abavia', 1671: '4,1' => 'amita maior', 1672: '5,0' => 'atavia', 1673: '5,1' => 'amita maxima', 1674: '6,0' => 'tritavia', 1675: '2,1,maternal' => 'matertera', 1676: '2,1,paternal' => 'amita', 1677: '2,2,maternal' => 'consobrina', 1678: '2,2,paternal' => 'patruelis', 1679: '3,1,maternal' => 'matertera magna', 1680: '3,1,paternal' => 'amita magna', 1681: '4,1,maternal' => 'matertera maior', 1682: '4,1,paternal' => 'amita maior', 1683: '5,1,maternal' => 'matertera maxima', 1684: '5,1,paternal' => 'amita maxima', 1685: ); 1686: 1687: # --------------------------------------------------------------------------- 1688: # Master dispatch table: lang -> sex -> hashref 1689: # --------------------------------------------------------------------------- 1690: 1691: Readonly::Hash my %RELATIONSHIP_TABLES => ( 1692: 'en' => { 1693: $SEX_MALE => \%EN_MALE_RELATIONSHIPS, 1694: $SEX_FEMALE => \%EN_FEMALE_RELATIONSHIPS, 1695: }, 'es' => { 1696: $SEX_MALE => \%ES_MALE_RELATIONSHIPS, 1697: $SEX_FEMALE => \%ES_FEMALE_RELATIONSHIPS, 1698: }, 'fa' => { 1699: $SEX_MALE => \%FA_MALE_RELATIONSHIPS, 1700: $SEX_FEMALE => \%FA_FEMALE_RELATIONSHIPS, 1701: }, 'fr' => { 1702: $SEX_MALE => \%FR_MALE_RELATIONSHIPS, 1703: $SEX_FEMALE => \%FR_FEMALE_RELATIONSHIPS, 1704: }, 'de' => { 1705: $SEX_MALE => \%DE_MALE_RELATIONSHIPS, 1706: $SEX_FEMALE => \%DE_FEMALE_RELATIONSHIPS, 1707: }, 'de_ch' => { 1708: $SEX_MALE => \%DE_CH_MALE_RELATIONSHIPS, 1709: $SEX_FEMALE => \%DE_CH_FEMALE_RELATIONSHIPS, 1710: }, 'la' => { 1711: $SEX_MALE => \%LA_MALE_RELATIONSHIPS, 1712: $SEX_FEMALE => \%LA_FEMALE_RELATIONSHIPS, 1713: }, 1714: ); 1715: # --------------------------------------------------------------------------- 1716: # Constructor 1717: # --------------------------------------------------------------------------- 1718: 1719: =head1 NAME 1720: 1721: Genealogy::Relationship::Name - Return a genealogical relationship name from step counts 1722: 1723: =head1 VERSION 1724: 1725: Version 0.03 1726: 1727: =head1 SYNOPSIS 1728: 1729: use Genealogy::Relationship::Name; 1730: 1731: my $namer = Genealogy::Relationship::Name->new(); 1732: 1733: my $name = $namer->name( 1734: steps_to_ancestor => 2, 1735: steps_from_ancestor => 3, 1736: sex => 'F', 1737: ); 1738: # Returns 'first cousin once-removed' 1739: 1740: # With language 1741: my $name_fr = $namer->name( 1742: steps_to_ancestor => 2, 1743: steps_from_ancestor => 2, 1744: sex => 'M', 1745: language => 'fr', 1746: ); 1747: # Returns 'cousin germain' 1748: 1749: =head1 DESCRIPTION 1750: 1751: C<Genealogy::Relationship::Name> maps a pair of step-counts (person A to common 1752: ancestor, common ancestor to person B) plus the sex of person B and an optional 1753: language code to a human-readable relationship name string. 1754: 1755: The relationship tables were originally embedded in the C<gedcom> and C<ged2site> 1756: distributions inside C<Gedcom::Individual::relationship_up()>; this module 1757: extracts them into a reusable, installable CPAN distribution. 1758: 1759: Supported languages: C<en> (English, default), C<de> (German), C<es> (Spanish), 1760: C<fa> (Farsi/Persian), C<fr> (French), C<la> (Classical Latin). 1761: 1762: =head1 METHODS 1763: 1764: =head2 new 1765: 1766: Constructor. Creates and returns a blessed C<Genealogy::Relationship::Name> 1767: object. 1768: 1769: =head3 PURPOSE 1770: 1771: Initialises the object with optional configuration: a default language for 1772: subsequent C<name()> calls, and an optional L<Log::Abstraction> object to 1773: use as the error logger. Configuration may also be loaded from an INI-style 1774: file via L<Object::Configure>. 1775: 1776: =head3 ARGUMENTS 1777: 1778: =over 4 1779: 1780: =item C<language> (string, optional) 1781: 1782: Default BCP-47 language tag (primary subtag only) for all C<name()> calls 1783: on this object. Supported values: C<en> (default), C<fr>, C<de>. May be 1784: overridden per-call by passing C<language> to C<name()>. 1785: 1786: =item C<logger> 1787: 1788: A pre-constructed loggining object. When a required argument is 1789: passed as C<undef> to C<name()>, the error is reported via 1790: C<< $logger->error($msg) >> rather than C<croak>. This allows 1791: programs to route errors through their own 1792: infrastructure with full C<ctx> context. 1793: 1794: See L<Log::Abstraction> and the L</CONFIGURATION> section for the 1795: recommended construction pattern. 1796: 1797: =item C<config_file> (string, optional) 1798: 1799: Path to an INI-style configuration file processed by L<Object::Configure>. 1800: Any keys it sets may be overridden by arguments passed directly to C<new()>. 1801: 1802: =back 1803: 1804: =head3 RETURNS 1805: 1806: A blessed C<Genealogy::Relationship::Name> object. 1807: 1808: =head3 SIDE EFFECTS 1809: 1810: Calls L<Object::Configure> C<configure()>, which may read from a 1811: configuration file on disk if C<config_file> is supplied or if a default 1812: configuration file exists for the class. 1813: 1814: =head3 NOTES 1815: 1816: L<Object::Configure> cannot handle object or coderef values (it treats 1817: unknown scalar values as configuration file paths). The C<logger> key is 1818: therefore stashed before the C<configure()> call and restored afterward. 1819: Any future object-valued constructor arguments must follow the same pattern. 1820: 1821: =head3 EXAMPLE 1822: 1823: use Genealogy::Relationship::Name; 1824: use Log::Abstraction; 1825: 1826: # Minimal construction 1827: my $namer = Genealogy::Relationship::Name->new(); 1828: 1829: # With a default language 1830: my $namer_fr = Genealogy::Relationship::Name->new(language => 'fr'); 1831: 1832: # With a Log::Abstraction logger 1833: my $la = Log::Abstraction->new( 1834: logger => sub { 1835: my $args = shift; 1836: my $msg = $args->{ctx} 1837: ? $args->{ctx}->as_string() . ': ' . join('', @{$args->{message}}) 1838: : join('', @{$args->{message}}); 1839: complain({ message => $msg, person => $args->{ctx} }); 1840: }, 1841: ctx => $individual, 1842: ); 1843: my $namer = Genealogy::Relationship::Name->new(language => 'en', logger => $la); 1844: 1845: =head3 API SPECIFICATION 1846: 1847: =head4 Input 1848: 1849: { 1850: language => { type => 'string', regex => qr/^(?:en|de(?:-ch)?|es|fa|fr|la)/, optional => 1 }, 1851: logger => { type => 'object', optional => 1 }, 1852: } 1853: 1854: =head4 Output 1855: 1856: { 1857: type => 'object', 1858: class => 'Genealogy::Relationship::Name', 1859: } 1860: 1861: =cut 1862: 1863: sub new { 1864: # Create and return a blessed object ●1865 → 1873 → 1879 1865: my $class = shift; 1866: 1867: # Handle hash or hashref arguments 1868: my $params = Params::Get::get_params(undef, \@_); 1869: 1870: # Stash keys that are coderefs or objects before passing to Object::Configure, 1871: # which cannot handle them (it treats unknown scalar values as config file paths) 1872: my %stash; 1873: for my $key (qw(logger)) { 1874: next unless exists $params->{$key}; 1875: $stash{$key} = delete $params->{$key}; 1876: } 1877: 1878: # Load the configuration from a config file, if provided 1879: $params = Object::Configure::configure($class, $params); 1880: 1881: # Restore the stashed coderefs and objects after configure() 1882: @{$params}{keys %stash} = values %stash; 1883: 1884: # Bless and return the object; logger/ctx/level keys from paramsMutants (Total: 2, Killed: 2, Survived: 0)
1885: # are stored directly and accessed via $self->{logger} etc. 1886: return bless { 1887: # Store any constructor-time config for Object::Configure compatibility 1888: %{$params}, 1889: }, ref($class) || $class; 1890: } 1891: 1892: # --------------------------------------------------------------------------- 1893: # Public method: name() 1894: # --------------------------------------------------------------------------- 1895: 1896: =head2 name 1897: 1898: Returns the name of the relationship between person A and person B. 1899: 1900: =head3 PURPOSE 1901: 1902: Given the number of steps from person A up to the nearest common ancestor 1903: (C<steps_to_ancestor>) and the number of steps from that ancestor down to 1904: person B (C<steps_from_ancestor>), plus the sex of person B and a language 1905: code, returns a localised relationship-name string. 1906: 1907: =head3 ARGUMENTS 1908: 1909: =over 4 1910: 1911: =item C<steps_to_ancestor> (integer, required) 1912: 1913: Number of generational steps from person A up to the common ancestor. 1914: Must be a non-negative integer. Zero means person A I<is> the ancestor. 1915: 1916: =item C<steps_from_ancestor> (integer, required) 1917: 1918: Number of generational steps from the common ancestor down to person B. 1919: Must be a non-negative integer. 1920: 1921: =item C<sex> (string, required) 1922: 1923: Sex of person B. Must be C<'M'> (male) or C<'F'> (female). 1924: 1925: =item C<language> (string, optional) 1926: 1927: BCP-47-style language tag (only the primary subtag is used). 1928: Supported values: C<en> (default), C<de>, C<es>, C<fa>, C<fr>, C<la>. 1929: 1930: Note: C<fa> (Farsi/Persian) values are stored as C<\N{U+XXXX}> Unicode 1931: escapes and render correctly in any Unicode-aware context. C<la> 1932: (Classical Latin) has a sparse table; many step-count combinations have 1933: no classical term and return C<undef>. 1934: 1935: =item C<person> (object, optional) 1936: 1937: An optional person object (e.g. a C<Gedcom::Individual> instance) passed 1938: through to the error handler when an error occurs. Takes priority over the 1939: C<ctx> set at construction time. The handler receives it as C<ctx> (logger 1940: path) or C<person> (on_error path), matching the C<complain()> interface 1941: in C<gedcom>/C<ged2site>. 1942: 1943: =item C<family_side> (string, optional) 1944: 1945: C<'paternal'> or C<'maternal'>. Used by languages that distinguish the 1946: paternal from the maternal line for the same step counts. Currently 1947: relevant for: 1948: 1949: =over 4 1950: 1951: =item * C<la> (Latin) -- uncle/aunt (C<patruus>/C<avunculus>, 1952: C<amita>/C<matertera>) and first cousin (C<patruelis>/C<consobrinus>) 1953: 1954: =item * C<fa> (Farsi) -- uncle (C<amoo>/C<dayi>) and aunt 1955: (C<ammeh>/C<khaleh>) 1956: 1957: =back 1958: 1959: When C<family_side> is not supplied, the table falls back to the generic 1960: (non-side-specific) entry for that step-count pair. 1961: 1962: =back 1963: 1964: =head3 RETURNS 1965: 1966: A string containing the relationship name, or C<undef> if the combination 1967: is not found in the lookup table. 1968: 1969: =head3 EXAMPLE 1970: 1971: my $namer = Genealogy::Relationship::Name->new(); 1972: 1973: # Person A is the grandparent (2 steps up) of the common ancestor, 1974: # and person B is 3 steps below the ancestor; B is female => first cousin once-removed 1975: my $rel = $namer->name( 1976: steps_to_ancestor => 2, 1977: steps_from_ancestor => 3, 1978: sex => 'F', 1979: ); 1980: 1981: =head3 API SPECIFICATION 1982: 1983: =head4 Input 1984: 1985: { 1986: steps_to_ancestor => { type => 'integer', minimum => 0 }, 1987: steps_from_ancestor => { type => 'integer', minimum => 0 }, 1988: sex => { type => 'string', memberof => ['M', 'F'] }, 1989: language => { type => 'string', regex => qr/^(?:en|de(?:-ch)?|es|fa|fr|la)/, optional => 1 }, 1990: # person is handled before validate_strict (PVS infers constraints from objects) 1991: family_side => { type => 'string', memberof => ['paternal','maternal'], optional => 1 }, 1992: } 1993: 1994: =head4 Output 1995: 1996: { 1997: type => 'string', 1998: optional => 1, # undef when the combination is not tabulated 1999: } 2000: 2001: =head3 FORMAL SPECIFICATION 2002: 2003: name ______________________________________________________ 2004: [In] steps_to_ancestor : N0 2005: steps_from_ancestor : N0 2006: sex : {M, F} 2007: language : {en, es, fa, fr, de, la}? (default en) 2008: person : Object? 2009: [Out] result : String | undef 2010: 2011: Let key == steps_to_ancestor ++ "," ++ steps_from_ancestor 2012: Let side_key == key ++ "," ++ family_side if family_side defined 2013: Let table == RELATIONSHIP_TABLES(language)(sex) 2014: result == table(side_key) if family_side defined and side_key in dom table 2015: == table(key) if key in dom table 2016: == undef otherwise 2017: 2018: =cut 2019: 2020: sub name { ●2021 → 2039 → 2047 2021: my $self = shift; 2022: 2023: # Validate and extract the remaining parameters; capture the return value 2024: my $args = Params::Validate::Strict::validate_strict( 2025: args => Params::Get::get_params(undef, \@_) || {}, 2026: schema => { 2027: steps_to_ancestor => { type => 'integer', minimum => 0 }, 2028: steps_from_ancestor => { type => 'integer', minimum => 0 }, 2029: sex => { type => 'string', memberof => ['M', 'F'] }, 2030: language => { type => 'string', regex => qr/^(?:en|de(?:-ch)?|es|fa|fr|la)/, optional => 1 }, 2031: person => { type => 'object', optional => 1 }, 2032: family_side => { type => 'string', memberof => ['paternal','maternal'], 2033: optional => 1 }, 2034: } 2035: ); 2036: 2037: # Extract individual parameters; undef means arg was given as undef, so 2038: # report via logger if set, otherwise croak
Mutants (Total: 1, Killed: 1, Survived: 0)
2039: foreach my $arg(qw(steps_to_ancestor steps_from_ancestor sex)) {
Mutants (Total: 1, Killed: 1, Survived: 0)
2040: if(!defined($args->{$arg})) { 2041: if(my $logger = $self->{logger}) { 2042: $logger->error("$arg not given"); 2043: } 2044: croak("$arg not given"); 2045: } 2046: } ●2047 → 2058 → 2067 2047: my $steps1 = $args->{steps_to_ancestor}; 2048: my $steps2 = $args->{steps_from_ancestor}; 2049: my $sex = $args->{sex}; 2050: my $person = $args->{person}; 2051: my $family_side = $args->{family_side}; 2052: 2053: # Fall back to constructor default or hard default if no per-call language given 2054: my $lang = lc($args->{language} // $self->{language} // $DEFAULT_LANGUAGE); 2055: 2056: # Swiss German (de-CH) maps to its own table before subtag stripping,
Mutants (Total: 1, Killed: 1, Survived: 0)
2057: # because it uses 'ss' where standard German uses Eszett 2058: if($lang eq 'de-ch') { 2059: $lang = 'de_ch'; 2060: } else { 2061: # Strip any region subtag (e.g. 'en-GB' -> 'en') after lowercasing 2062: ($lang) = split /-/, $lang; 2063: } 2064: 2065: # Build lookup key from the two step counts; try side-specific key first 2066: # for languages that distinguish paternal/maternal (Latin, Farsi) 2067: my $key = "${steps1},${steps2}"; 2068: my $side_key = defined($family_side) ? "${key},${family_side}" : undef; 2069: 2070: # Retrieve the correct gender-specific table for the chosen language 2071: my $table = $RELATIONSHIP_TABLES{$lang}{$sex}; 2072: 2073: # Prefer side-specific entry when family_side is given; fall back to generic key 2074: my $result = (defined($side_key) && exists $table->{$side_key}) 2075: ? $table->{$side_key} 2076: : $table->{$key};
Mutants (Total: 2, Killed: 2, Survived: 0)
2077: 2078: return $result; 2079: } 2080: 2081: # --------------------------------------------------------------------------- 2082: # Public method: supported_languages() 2083: # --------------------------------------------------------------------------- 2084: 2085: =head2 supported_languages 2086: 2087: Returns a sorted list of the language codes that the module supports. 2088: 2089: =head3 PURPOSE 2090: 2091: Allows calling code to enumerate the languages available for C<name()> 2092: without hard-coding them. 2093: 2094: =head3 ARGUMENTS 2095: 2096: None. 2097: 2098: =head3 RETURNS 2099: 2100: A list (or array-ref in scalar context) of language code strings, 2101: currently C<('de', 'de_ch', 'en', 'es', 'fa', 'fr', 'la')>. 2102: 2103: =head3 EXAMPLE 2104: 2105: my @langs = $namer->supported_languages(); 2106: # ( 'de', 'de_ch', 'en', 'es', 'fa', 'fr', 'la' ) 2107: 2108: =head3 API SPECIFICATION 2109: 2110: =head4 Input 2111: 2112: {} # no arguments 2113: 2114: =head4 Output 2115: 2116: { 2117: type => ARRAYREF, # sorted list of language codes 2118: } 2119: 2120: =cut 2121: 2122: sub supported_languages { 2123: # Return the sorted set of keys from the master dispatch table
Mutants (Total: 2, Killed: 2, Survived: 0)
2124: my @langs = sort keys %RELATIONSHIP_TABLES; 2125: return wantarray ? @langs : \@langs; 2126: } 2127: 2128: # --------------------------------------------------------------------------- 2129: # Public method: known_sexes() 2130: # --------------------------------------------------------------------------- 2131: 2132: =head2 known_sexes 2133: 2134: Returns the list of sex codes accepted by C<name()>. 2135: 2136: =head3 PURPOSE 2137: 2138: Documents and exposes the set of valid C<sex> values so that callers can 2139: validate their own input without duplicating knowledge. 2140: 2141: =head3 ARGUMENTS 2142: 2143: None. 2144: 2145: =head3 RETURNS 2146: 2147: A list (or array-ref in scalar context) of valid sex code strings: C<('F', 'M')>. 2148: 2149: =head3 SIDE EFFECTS 2150: 2151: None. 2152: 2153: =head3 EXAMPLE 2154: 2155: my @sexes = $namer->known_sexes(); 2156: # ( 'F', 'M' ) 2157: 2158: =head3 API SPECIFICATION 2159: 2160: =head4 Input 2161: 2162: {} # no arguments 2163: 2164: =head4 Output 2165: 2166: { 2167: type => ARRAYREF, 2168: } 2169: 2170: =cut 2171: 2172: sub known_sexes { 2173: # Return the two valid sex codes in sorted order
Mutants (Total: 2, Killed: 2, Survived: 0)
2174: my @sexes = sort($SEX_FEMALE, $SEX_MALE); 2175: return wantarray ? @sexes : \@sexes; 2176: } 2177: 2178: 1; 2179: 2180: __END__ 2181: 2182: =head1 CONFIGURATION 2183: 2184: The constructor accepts an optional C<language> key which sets the default 2185: language for all subsequent calls to C<name()>: 2186: 2187: my $namer = Genealogy::Relationship::Name->new(language => 'fr'); 2188: 2189: This default can be overridden per-call by passing C<language> to C<name()>. 2190: The object is also compatible with C<Object::Configure> for runtime 2191: reconfiguration. 2192: 2193: =head2 Error handling 2194: 2195: Errors are dispatched through the following priority chain: 2196: 2197: =over 4 2198: 2199: =item 1. L<Log::Abstraction> object (preferred) 2200: 2201: Construct a C<Log::Abstraction> object with the desired logger coderef and 2202: C<ctx> (typically a C<Gedcom::Individual>), then pass it as C<logger> to 2203: C<new()>. On error, this module simply calls C<< $logger->error($msg) >> 2204: and Log::Abstraction handles ctx forwarding, formatting, and dispatch. 2205: 2206: use Log::Abstraction; 2207: 2208: my $logger = Log::Abstraction->new( 2209: logger => sub { 2210: my $args = shift; 2211: my $msg = $args->{ctx} 2212: ? $args->{ctx}->as_string() . ': ' . join('', @{$args->{message}}) 2213: : join('', @{$args->{message}}); 2214: complain({ message => $msg, person => $args->{ctx} }); 2215: }, 2216: ctx => $individual, 2217: ); 2218: 2219: my $namer = Genealogy::Relationship::Name->new(logger => $logger); 2220: 2221: =back 2222: 2223: If any handler returns without dying (e.g. a warning-only handler in 2224: L<Log::Abstraction>), C<name()> returns C<undef>. 2225: 2226: =head1 DIAGNOSTICS 2227: 2228: =over 4 2229: 2230: =item steps_to_ancestor not given 2231: 2232: C<steps_to_ancestor> was passed as C<undef>. Passing C<undef> explicitly is 2233: distinct from omitting the argument; use a defined non-negative integer. 2234: 2235: =item steps_from_ancestor not given 2236: 2237: As above, for C<steps_from_ancestor>. 2238: 2239: =item sex not given 2240: 2241: C<sex> was passed as C<undef>. Supply C<'M'> or C<'F'>. 2242: 2243: =back 2244: 2245: =head1 DEPENDENCIES 2246: 2247: L<Carp>, L<Object::Configure> 2248: 2249: Optionally L<Log::Abstraction> (E<gt>= 0.28) for the C<logger>/C<ctx> error 2250: dispatch path. 2251: L<Params::Get>, L<Params::Validate::Strict>, L<Readonly> 2252: 2253: =head1 BUGS AND LIMITATIONS 2254: 2255: The lookup tables currently cover steps 0-6 in both directions. Relationships 2256: further removed (seventh cousin, etc.) return C<undef>. Pull requests adding 2257: deeper tables are welcome. 2258: 2259: =head1 TODO 2260: 2261: =over 4 2262: 2263: =item * Extract and integrate the Latin relationship handling code currently 2264: embedded in the C<gedcom> and C<ged2site> programs, adding C<la> as a 2265: supported language alongside C<en>, C<fr>, and C<de>. 2266: 2267: =back 2268: 2269: =head1 SEE ALSO 2270: 2271: =over 4 2272: 2273: =item * L<Configure an Object at Runtime|Object::Configure> 2274: 2275: =item * L<Test Dashboard|https://nigelhorne.github.io/Genealogy-Relationship-Name/coverage/> 2276: 2277: =item * L<Gedcom::Individual>, L<Genealogy::Relationship>, L<https://www.tfcg.ca/tableau-des-liens-de-parente>, 2278: 2279: =back 2280: 2281: =head1 AUTHOR 2282: 2283: Nigel Horne C<< <njh@nigelhorne.com> >> 2284: 2285: =head1 REPOSITORY 2286: 2287: L<https://github.com/nigelhorne/Genealogy-Relationship-Name> 2288: 2289: =head1 SUPPORT 2290: 2291: This module is provided as-is without any warranty. 2292: 2293: Please report any bugs or feature requests to C<bug-genealogy-relationship-name at rt.cpan.org>, 2294: or through the web interface at 2295: L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Genealogy-Relationship-Name>. 2296: I will be notified, and then you'll 2297: automatically be notified of progress on your bug as I make changes. 2298: 2299: You can find documentation for this module with the perldoc command. 2300: 2301: perldoc Genealogy::Relationship::Name 2302: 2303: You can also look for information at: 2304: 2305: =over 4 2306: 2307: =item * MetaCPAN 2308: 2309: L<https://metacpan.org/dist/Genealogy-Relationship-Name> 2310: 2311: =item * RT: CPAN's request tracker 2312: 2313: L<https://rt.cpan.org/NoAuth/Bugs.html?Dist=Genealogy-Relationship-Name> 2314: 2315: =item * CPAN Testers' Matrix 2316: 2317: L<http://matrix.cpantesters.org/?dist=Genealogy-Relationship-Name> 2318: 2319: =item * CPAN Testers Dependencies 2320: 2321: L<http://deps.cpantesters.org/?module=Genealogy::Relationship::Name> 2322: 2323: =back 2324: 2325: =head1 FORMAL SPECIFICATION 2326: 2327: =head2 new 2328: 2329: new ________________________________________________________ 2330: [In] class : String (class name or object) 2331: language : {en, es, fa, fr, de, la}? (optional default language 2332: logger : Log::Abstraction? (optional error logger) 2333: [Out] self : Genealogy::Relationship::Name 2334: 2335: Let params == get_params(args) 2336: Let params' == configure(class, params \ {logger}) 2337: union {logger -> params.logger} if logger in dom params 2338: self == bless(params', class) 2339: 2340: post: self.language == params.language if language in dom params 2341: self.logger == params.logger if logger in dom params 2342: ref(self) == 'Genealogy::Relationship::Name' 2343: 2344: =head2 name 2345: 2346: name ______________________________________________________ 2347: [In] steps_to_ancestor : N0 2348: steps_from_ancestor : N0 2349: sex : {M, F} 2350: language : {en, fr, de}? (default en) 2351: person : Object? 2352: [Out] result : String | undef 2353: 2354: Let key == steps_to_ancestor ++ "," ++ steps_from_ancestor 2355: Let table == RELATIONSHIP_TABLES(language)(sex) 2356: result == table(key) if key in dom table 2357: == undef otherwise 2358: 2359: =head2 supported_languages 2360: 2361: supported_languages ______________________________________ 2362: [In] (none) 2363: [Out] result : seq String 2364: 2365: result == sort(dom RELATIONSHIP_TABLES) 2366: 2367: =head2 known_sexes 2368: 2369: known_sexes ______________________________________________ 2370: [In] (none) 2371: [Out] result : seq String 2372: 2373: result == sort { $SEX_FEMALE, $SEX_MALE } 2374: 2375: =head1 LICENCE AND COPYRIGHT 2376: 2377: Copyright 2026 Nigel Horne. 2378: 2379: Usage is subject to the GPL2 licence terms. 2380: If you use it, 2381: please let me know. 2382: 2383: =cut