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