1<?php 2/** 3 * webtrees: online genealogy 4 * Copyright (C) 2015 webtrees development team 5 * This program is free software: you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation, either version 3 of the License, or 8 * (at your option) any later version. 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * You should have received a copy of the GNU General Public License 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 */ 16namespace Fisharebest\Webtrees\Module; 17 18use Fisharebest\Webtrees\Controller\SimpleController; 19use Fisharebest\Webtrees\Family; 20use Fisharebest\Webtrees\Filter; 21use Fisharebest\Webtrees\Functions\FunctionsDb; 22use Fisharebest\Webtrees\GedcomRecord; 23use Fisharebest\Webtrees\GedcomTag; 24use Fisharebest\Webtrees\I18N; 25use Fisharebest\Webtrees\Individual; 26use Fisharebest\Webtrees\Note; 27 28/** 29 * Class CensusAssistantModule 30 */ 31class CensusAssistantModule extends AbstractModule { 32 /** {@inheritdoc} */ 33 public function getTitle() { 34 return /* I18N: Name of a module */ I18N::translate('Census assistant'); 35 } 36 37 /** {@inheritdoc} */ 38 public function getDescription() { 39 return /* I18N: Description of the “Census assistant” module */ I18N::translate('An alternative way to enter census transcripts and link them to individuals.'); 40 } 41 42 /** 43 * This is a general purpose hook, allowing modules to respond to routes 44 * of the form module.php?mod=FOO&mod_action=BAR 45 * 46 * @param string $mod_action 47 */ 48 public function modAction($mod_action) { 49 switch ($mod_action) { 50 case 'census_find': 51 self::censusFind(); 52 break; 53 case 'media_find': 54 self::mediaFind(); 55 break; 56 case 'media_query_3a': 57 self::mediaQuery(); 58 break; 59 default: 60 http_response_code(404); 61 } 62 } 63 64 /** 65 * Find an individual. 66 */ 67 private static function censusFind() { 68 global $WT_TREE; 69 70 $controller = new SimpleController; 71 72 $filter = Filter::get('filter'); 73 $action = Filter::get('action'); 74 $callback = Filter::get('callback'); 75 $multiple = Filter::getBool('multiple'); 76 77 $controller 78 ->setPageTitle(I18N::translate('Find an individual')) 79 ->pageHeader(); 80 81 ?> 82 <script> 83 function pasterow(id, nam, mnam, label, gend, cond, dom, dob, dod, occu, age, birthpl, fbirthpl, mbirthpl, chilBLD) { 84 window.opener.insertRowToTable(id, nam, mnam, label, gend, cond, dom, dob, dod, occu, age, birthpl, fbirthpl, mbirthpl, chilBLD); 85 <?php if (!$multiple) echo "window.close();"; ?> 86 } 87 88 function pasteid(id, name, thumb) { 89 if (thumb) { 90 window.opener.<?php echo $callback; ?>(id, name, thumb); 91 <?php if (!$multiple) echo "window.close();"; ?> 92 } else { 93 // GEDFact_assistant ======================== 94 if (window.opener.document.getElementById('addlinkQueue')) { 95 window.opener.insertRowToTable(id, name); 96 } 97 window.opener.<?php echo $callback; ?>(id); 98 if (window.opener.pastename) { 99 window.opener.pastename(name); 100 } 101 <?php if (!$multiple) echo "window.close();"; ?> 102 } 103 } 104 </script> 105 <?php 106 107 echo "<div align=\"center\">"; 108 echo "<table class=\"list_table width90\" border=\"0\">"; 109 echo "<tr><td style=\"padding: 10px;\" valign=\"top\" class=\"facts_label03 width90\">"; 110 echo I18N::translate('Find an individual'); 111 echo "</td>"; 112 echo "</table>"; 113 echo "<br>"; 114 115 if ($action == "filter") { 116 $filter = trim($filter); 117 $filter_array = explode(' ', preg_replace('/ {2,}/', ' ', $filter)); 118 119 // Output Individual for GEDFact Assistant ====================== 120 echo "<table class=\"tabs_table width90\">"; 121 $myindilist = FunctionsDb::searchIndividualNames($filter_array, array($WT_TREE)); 122 if ($myindilist) { 123 echo "<tr><td class=\"list_value_wrap\"><ul>"; 124 usort($myindilist, '\Fisharebest\Webtrees\GedcomRecord::compare'); 125 foreach ($myindilist as $indi) { 126 $nam = $indi->getAllNames(); 127 $wholename = rtrim($nam[0]['givn'], '*') . " " . $nam[0]['surname']; 128 $fulln = rtrim($nam[0]['givn'], '*') . " " . $nam[0]['surname']; 129 $fulln = str_replace('"', '\'', $fulln); // Replace double quotes 130 $fulln = str_replace("@N.N.", "(" . I18N::translate('unknown') . ")", $fulln); 131 $fulln = str_replace("@P.N.", "(" . I18N::translate('unknown') . ")", $fulln); 132 $givn = rtrim($nam[0]['givn'], '*'); 133 $surn = $nam[0]['surname']; 134 if (isset($nam[1])) { 135 $fulmn = rtrim($nam[1]['givn'], '*') . " " . $nam[1]['surname']; 136 $fulmn = str_replace('"', '\'', $fulmn); // Replace double quotes 137 $fulmn = str_replace("@N.N.", "(" . I18N::translate('unknown') . ")", $fulmn); 138 $fulmn = str_replace("@P.N.", "(" . I18N::translate('unknown') . ")", $fulmn); 139 $marn = $nam[1]['surname']; 140 } else { 141 $fulmn = $fulln; 142 } 143 144 //-- Build Indi Parents Family to get FBP and MBP ----------- 145 foreach ($indi->getChildFamilies() as $family) { 146 $father = $family->getHusband(); 147 $mother = $family->getWife(); 148 if (!is_null($father)) { 149 $FBP = $father->getBirthPlace(); 150 } 151 if (!is_null($mother)) { 152 $MBP = $mother->getBirthPlace(); 153 } 154 } 155 if (!isset($FBP)) { $FBP = "UNK, UNK, UNK, UNK"; } 156 if (!isset($MBP)) { $MBP = "UNK, UNK, UNK, UNK"; } 157 158 //-- Build Indi Spouse Family to get marriage Date ---------- 159 foreach ($indi->getSpouseFamilies() as $family) { 160 $marrdate = $family->getMarriageDate(); 161 $marrdate = ($marrdate->minimumJulianDay() + $marrdate->maximumJulianDay()) / 2; // Julian 162 $children = $family->getChildren(); 163 } 164 if (!isset($marrdate)) { $marrdate = ""; } 165 166 //-- Get Children’s Name, DOB, DOD -------------------------- 167 $chBLDarray = array(); 168 if (isset($children)) { 169 foreach ($children as $key => $child) { 170 $chnam = $child->getAllNames(); 171 $chfulln = rtrim($chnam[0]['givn'], '*') . " " . $chnam[0]['surname']; 172 $chfulln = str_replace('"', "", $chfulln); // Must remove quotes completely here 173 $chfulln = str_replace("@N.N.", "(" . I18N::translate('unknown') . ")", $chfulln); 174 $chfulln = str_replace("@P.N.", "(" . I18N::translate('unknown') . ")", $chfulln); // Child’s Full Name 175 $chdob = ($child->getBirthDate()->minimumJulianDay() + $child->getBirthDate()->maximumJulianDay()) / 2; // Child’s Date of Birth (Julian) 176 if (!isset($chdob)) { $chdob = ""; } 177 $chdod = ($child->getDeathDate()->minimumJulianDay() + $child->getDeathDate()->maximumJulianDay()) / 2; // Child’s Date of Death (Julian) 178 if (!isset($chdod)) { $chdod = ""; } 179 $chBLD = ($chfulln . ", " . $chdob . ", " . $chdod); 180 array_push($chBLDarray, $chBLD); 181 } 182 } 183 if ($chBLDarray && $indi->getSex() == "F") { 184 $chBLDarray = implode("::", $chBLDarray); 185 } else { 186 $chBLDarray = ''; 187 } 188 189 echo "<li>"; 190 echo "<a href=\"#\" onclick=\"window.opener.insertRowToTable("; 191 echo "'" . $indi->getXref() . "', "; // id - Indi Id 192 echo "'" . addslashes(strip_tags($fulln)) . "', "; // nam - Name 193 echo "'" . addslashes(strip_tags($fulmn)) . "', "; // mnam - Married Name 194 echo "'-', "; // label - Relation to Head of Household 195 echo "'" . $indi->getSex() . "', "; // gend - Sex 196 echo "'S', "; // cond - Marital Condition 197 echo "'" . $marrdate . "', "; // dom - Date of Marriage 198 echo "'" . (($indi->getBirthDate()->minimumJulianDay() + $indi->getBirthDate()->maximumJulianDay()) / 2) . "' ,"; // dob - Date of Birth 199 echo "'" . (1901 - $indi->getbirthyear()) . "' ,"; // ~age~ - Census Date minus YOB (Preliminary) 200 echo "'" . (($indi->getDeathDate()->minimumJulianDay() + $indi->getDeathDate()->maximumJulianDay()) / 2) . "' ,"; // dod - Date of Death 201 echo "'', "; // occu - Occupation 202 echo "'" . Filter::escapeHtml($indi->getbirthplace()) . "', "; // birthpl - Birthplace 203 echo "'" . $FBP . "', "; // fbirthpl - Father’s Birthplace 204 echo "'" . $MBP . "', "; // mbirthpl - Mother’s Birthplace 205 echo "'" . $chBLDarray . "'"; // chilBLD - Array of Children (name, birthdate, deathdate) 206 echo ");"; 207 echo "return false;\">"; 208 echo "<b>" . $indi->getFullName() . "</b> "; // Name Link 209 echo "</span><br><span class=\"list_item\">", GedcomTag::getLabel('BIRT', $indi), " ", $indi->getbirthyear(), " ", $indi->getbirthplace(), "</span>"; 210 echo "</a>"; 211 echo "</li>"; 212 echo "<hr>"; 213 } 214 echo '</ul></td></tr>'; 215 } else { 216 echo "<tr><td class=\"list_value_wrap\">"; 217 echo I18N::translate('No results found.'); 218 echo "</td></tr>"; 219 } 220 echo "</table>"; 221 } 222 echo '<button onclick="window.close();">', I18N::translate('close'), '</button>'; 223 echo "</div>"; // Close div that centers table 224 } 225 226 /** 227 * Find a media object. 228 */ 229 private static function mediaFind() { 230 global $WT_TREE; 231 232 $controller = new SimpleController; 233 $filter = Filter::get('filter'); 234 $multiple = Filter::getBool('multiple'); 235 236 $controller 237 ->setPageTitle(I18N::translate('Find an individual')) 238 ->pageHeader(); 239 240 echo '<script>'; 241 ?> 242 243 function pasterow(id, name, gend, yob, age, bpl) { 244 window.opener.opener.insertRowToTable(id, name, '', gend, '', yob, age, 'Y', '', bpl); 245 } 246 247 function pasteid(id, name, thumb) { 248 if (thumb) { 249 window.opener.paste_id(id, name, thumb); 250 <?php if (!$multiple) echo "window.close();"; ?> 251 } else { 252 // GEDFact_assistant ======================== 253 if (window.opener.document.getElementById('addlinkQueue')) { 254 window.opener.insertRowToTable(id, name); 255 } 256 window.opener.paste_id(id); 257 if (window.opener.pastename) { 258 window.opener.pastename(name); 259 } 260 <?php if (!$multiple) echo "window.close();"; ?> 261 } 262 } 263 function checknames(frm) { 264 if (document.forms[0].subclick) { 265 button = document.forms[0].subclick.value; 266 } else { 267 button = ""; 268 } 269 if (frm.filter.value.length<2&button!="all") { 270 alert("<?php echo I18N::translate('Please enter more than one character.'); ?>"); 271 frm.filter.focus(); 272 return false; 273 } 274 if (button=="all") { 275 frm.filter.value = ""; 276 } 277 return true; 278 } 279 <?php 280 echo '</script>'; 281 282 echo "<div align=\"center\">"; 283 echo "<table class=\"list_table width90\" border=\"0\">"; 284 echo "<tr><td style=\"padding: 10px;\" valign=\"top\" class=\"facts_label03 width90\">"; // start column for find text header 285 echo $controller->getPageTitle(); 286 echo "</td>"; 287 echo "</tr>"; 288 echo "</table>"; 289 echo "<br>"; 290 echo '<button onclick="window.close();">', I18N::translate('close'), '</button>'; 291 echo "<br>"; 292 293 $filter = trim($filter); 294 $filter_array = explode(' ', preg_replace('/ {2,}/', ' ', $filter)); 295 echo "<table class=\"tabs_table width90\"><tr>"; 296 $myindilist = FunctionsDb::searchIndividualNames($filter_array, array($WT_TREE)); 297 if ($myindilist) { 298 echo "<td class=\"list_value_wrap\"><ul>"; 299 usort($myindilist, '\Fisharebest\Webtrees\GedcomRecord::compare'); 300 foreach ($myindilist as $indi) { 301 $nam = Filter::escapeHtml($indi->getFullName()); 302 echo "<li><a href=\"#\" onclick=\"pasterow( 303 '" . $indi->getXref() . "' , 304 '" . $nam . "' , 305 '" . $indi->getSex() . "' , 306 '" . $indi->getbirthyear() . "' , 307 '" . (1901 - $indi->getbirthyear()) . "' , 308 '" . $indi->getbirthplace() . "'); return false;\"> 309 <b>" . $indi->getFullName() . "</b> "; 310 311 $born = GedcomTag::getLabel('BIRT'); 312 echo "</span><br><span class=\"list_item\">", $born, " ", $indi->getbirthyear(), " ", $indi->getbirthplace(), "</span></a></li>"; 313 echo "<hr>"; 314 } 315 echo '</ul></td></tr><tr><td class="list_label">', I18N::translate('Total individuals: %s', count($myindilist)), '</tr></td>'; 316 } else { 317 echo "<td class=\"list_value_wrap\">"; 318 echo I18N::translate('No results found.'); 319 echo "</td></tr>"; 320 } 321 echo "</table>"; 322 echo '</div>'; 323 } 324 325 /** 326 * Search for a media object. 327 */ 328 private static function mediaQuery() { 329 global $WT_TREE; 330 331 $iid2 = Filter::get('iid', WT_REGEX_XREF); 332 333 $controller = new SimpleController; 334 $controller 335 ->setPageTitle(I18N::translate('Link to an existing media object')) 336 ->pageHeader(); 337 338 $record = GedcomRecord::getInstance($iid2, $WT_TREE); 339 if ($record) { 340 $headjs = ''; 341 if ($record instanceof Family) { 342 if ($record->getHusband()) { 343 $headjs = $record->getHusband()->getXref(); 344 } elseif ($record->getWife()) { 345 $headjs = $record->getWife()->getXref(); 346 } 347 } 348 ?> 349 <script> 350 function insertId() { 351 if (window.opener.document.getElementById('addlinkQueue')) { 352 // alert('Please move this alert window and examine the contents of the pop-up window, then click OK') 353 window.opener.insertRowToTable('<?php echo $record->getXref(); ?>', '<?php echo htmlSpecialChars($record->getFullName()); ?>', '<?php echo $headjs; ?>'); 354 window.close(); 355 } 356 } 357 </script> 358 <?php 359 360 } else { 361 ?> 362 <script> 363 function insertId() { 364 window.opener.alert('<?php echo $iid2; ?> - <?php echo I18N::translate('Not a valid individual, family, or source ID'); ?>'); 365 window.close(); 366 } 367 </script> 368 <?php 369 } 370 ?> 371 <script>window.onLoad = insertId();</script> 372 <?php 373 } 374 375 /** 376 * Convert custom markup into HTML 377 * 378 * @param Note $note 379 * 380 * @return string 381 */ 382 public static function formatCensusNote(Note $note) { 383 global $WT_TREE; 384 385 $headers = array( 386 'AgM' => 'Age at first marriage', 387 'Age' => 'Age at last birthday', 388 'Assets' => 'Assets = Owned,Rented - Value,Rent - Radio - Farm', 389 'BIC' => 'Born in County', 390 'BOE' => 'Born outside England', 391 'BP' => 'Birthplace - (Chapman format)', 392 'Birthplace' => 'Birthplace (Full format)', 393 'Bmth' => 'Month of birth - If born within Census year', 394 'ChB' => 'Children born alive', 395 'ChD' => 'Children who have died', 396 'ChL' => 'Children still living', 397 'DOB' => 'Date of birth', 398 'Edu' => 'Education - At School, Can Read, Can Write', // or "Cannot Read, Cannot Write" ?? 399 'EmD' => 'Employed?', 400 'EmN' => 'Unemployed?', 401 'EmR' => 'Employer?', 402 'Employ' => 'Employment', 403 'Eng?' => 'English spoken?', 404 'EngL' => 'English spoken?, if not, Native Language', 405 'FBP' => 'Father’s Birthplace - (Chapman format)', 406 'Health' => 'Health - 1.Blind, 2.Deaf & Dumb, 3.Idiotic, 4.Insane, 5.Disabled etc', 407 'Home' => 'Home Ownership - Owned/Rented-Free/Mortgaged-Farm/House-Farm Schedule number', 408 'Industry' => 'Industry', 409 'Infirm' => 'Infirmities - 1. Deaf & Dumb, 2. Blind, 3. Lunatic, 4. Imbecile/feeble-minded', 410 'Lang' => 'If Foreign Born - Native Language', 411 'MBP' => 'Mother’s Birthplace - (Chapman format)', 412 'MC' => 'Marital Condition - Married, Single, Unmarried, Widowed or Divorced', 413 'Mmth' => 'Month of marriage - If married during Census Year', 414 'MnsE' => 'Months employed during Census Year', 415 'MnsU' => 'Months unemployed during Census Year', 416 'N/A' => 'If Foreign Born - Naturalized, Alien', 417 'NL' => 'If Foreign Born - Native Language', 418 'Name' => 'Full Name or Married name if married', 419 'Occupation' => 'Occupation', 420 'Par' => 'Parentage - Father if foreign born, Mother if foreign born', 421 'Race' => 'Race or Color - Black, White, Mulatto, Asian, Indian, Chinese etc', 422 'Relation' => 'Relationship to Head of Household', 423 'Sex' => 'Male or Female', 424 'Situ' => 'Situation - Disease, Infirmity, Convict, Pauper etc', 425 'Ten' => 'Tenure - Owned/Rented, (if owned)Free/Morgaged', 426 'Vet' => 'War Veteran?', 427 'WH' => 'Working at Home?', 428 'War' => 'War or Expedition', 429 'WksU' => 'Weeks unemployed during Census Year', 430 'YOI' => 'If Foreign Born - Year of immigration', 431 'YON' => 'If Foreign Born - Year of naturalization', 432 'YUS' => 'If Foreign Born - Years in the USA', 433 'YrsM' => 'Years Married, or Y if married in Census Year', 434 ); 435 436 if (preg_match('/(.*)((?:\n.*)*)\n\.start_formatted_area\.\n(.*)((?:\n.*)*)\n.end_formatted_area\.((?:\n.*)*)/', $note->getNote(), $match)) { 437 // This looks like a census-assistant shared note 438 $title = Filter::escapeHtml($match[1]); 439 $preamble = Filter::escapeHtml($match[2]); 440 $header = Filter::escapeHtml($match[3]); 441 $data = Filter::escapeHtml($match[4]); 442 $postamble = Filter::escapeHtml($match[5]); 443 444 $fmt_headers = array(); 445 foreach ($headers as $key => $value) { 446 $fmt_headers['.b.' . $key] = '<span title="' . Filter::escapeHtml($value) . '">' . $key . '</span>'; 447 } 448 449 // Substitue header labels and format as HTML 450 $thead = '<tr><th>' . strtr(str_replace('|', '</th><th>', $header), $fmt_headers) . '</th></tr>'; 451 452 // Format data as HTML 453 $tbody = ''; 454 foreach (explode("\n", $data) as $row) { 455 $tbody .= '<tr>'; 456 foreach (explode('|', $row) as $column) { 457 $tbody .= '<td>' . $column . '</td>'; 458 } 459 $tbody .= '</tr>'; 460 } 461 462 return 463 $title . "\n" . // The newline allows the framework to expand the details and turn the first line into a link 464 '<p>' . $preamble . '</p>' . 465 '<table class="table-census-assistant">' . 466 '<thead>' . $thead . '</thead>' . 467 '<tbody>' . $tbody . '</tbody>' . 468 '</table>' . 469 '<p>' . $postamble . '</p>'; 470 } else { 471 // Not a census-assistant shared note - apply default formatting 472 return Filter::formatText($note->getNote(), $WT_TREE); 473 } 474 } 475 476 /** 477 * Modify the “add shared note” field, to create a note using the assistant 478 * 479 * @param string $element_id 480 * @param string $xref 481 * @param string $action 482 * 483 * @return string 484 */ 485 public static function addNoteWithAssistantLink($element_id, $xref, $action) { 486 global $controller, $WT_TREE; 487 488 // We do not yet support family records 489 if (!GedcomRecord::getInstance($xref, $WT_TREE) instanceof Individual) { 490 return ''; 491 } 492 493 // Only modify “add shared note” links on the add/edit actions. 494 // TODO: does the “edit” action work? 495 if ($action != 'add' && $action != 'edit') { 496 return ''; 497 } 498 499 $controller->addInlineJavascript(' 500 var pid_array=jQuery("#pid_array"); 501 function set_pid_array(pa) { 502 pid_array.val(pa); 503 } 504 '); 505 506 return 507 '<br>' . 508 '<input type="hidden" name="pid_array" id="pid_array" value="">' . 509 '<a href="#" onclick="return addnewnote_assisted(document.getElementById(\'' . $element_id . '\'), \'' . $xref . '\');">' . 510 I18N::translate('Create a new shared note using assistant') . 511 '</a>'; 512 } 513 514 /** 515 * Add a selector containing UK/US/FR census dates 516 * 517 * @param string $action 518 * @param string $tag 519 * @param string $element_id 520 * 521 * @return string 522 */ 523 public static function censusDateSelector($action, $tag, $element_id) { 524 global $controller; 525 526 if ($action == 'add' && $tag == 'CENS') { 527 $controller->addInlineJavascript(' 528 function addDate(theCensDate) { 529 var ddate = theCensDate.split(", "); 530 document.getElementById("setctry").value = ddate[3]; 531 document.getElementById("setyear").value = ddate[0]; 532 cal_setDateField("' . $element_id . '", parseInt(ddate[0]), parseInt(ddate[1]), parseInt(ddate[2])); 533 return false; 534 } 535 function pasteAsstDate(setcy, setyr) { 536 document.getElementById(setcy+setyr).selected = true; 537 addDate(document.getElementById("selcensdate").options[document.getElementById(\'selcensdate\').selectedIndex].value); 538 return false; 539 } 540 '); 541 542 return ' 543 <select id="selcensdate" name="selcensdate" onchange = "if (this.options[this.selectedIndex].value!=\'\') { 544 addDate(this.options[this.selectedIndex].value); 545 }"> 546 <option id="defdate" value="" selected>' . I18N::translate('Census date') . '</option> 547 <option value=""></option> 548 <option id="UK1911" class="UK" value="1911, 3, 02, UK">UK 1911</option> 549 <option id="UK1901" class="UK" value="1901, 2, 31, UK">UK 1901</option> 550 <option id="UK1891" class="UK" value="1891, 3, 05, UK">UK 1891</option> 551 <option id="UK1881" class="UK" value="1881, 3, 03, UK">UK 1881</option> 552 <option id="UK1871" class="UK" value="1871, 3, 02, UK">UK 1871</option> 553 <option id="UK1861" class="UK" value="1861, 3, 07, UK">UK 1861</option> 554 <option id="UK1851" class="UK" value="1851, 2, 30, UK">UK 1851</option> 555 <option id="UK1841" class="UK" value="1841, 5, 06, UK">UK 1841</option> 556 <option value=""></option> 557 <option id="USA1940" class="USA" value="1940, 3, 01, USA">US 1940</option> 558 <option id="USA1930" class="USA" value="1930, 3, 01, USA">US 1930</option> 559 <option id="USA1920" class="USA" value="1920, 0, 01, USA">US 1920</option> 560 <option id="USA1910" class="USA" value="1910, 3, 15, USA">US 1910</option> 561 <option id="USA1900" class="USA" value="1900, 5, 01, USA">US 1900</option> 562 <option id="USA1890" class="USA" value="1890, 5, 01, USA">US 1890</option> 563 <option id="USA1880" class="USA" value="1880, 5, 01, USA">US 1880</option> 564 <option id="USA1870" class="USA" value="1870, 5, 01, USA">US 1870</option> 565 <option id="USA1860" class="USA" value="1860, 5, 01, USA">US 1860</option> 566 <option id="USA1850" class="USA" value="1850, 5, 01, USA">US 1850</option> 567 <option id="USA1840" class="USA" value="1840, 5, 01, USA">US 1840</option> 568 <option id="USA1830" class="USA" value="1830, 5, 01, USA">US 1830</option> 569 <option id="USA1820" class="USA" value="1820, 7, 07, USA">US 1820</option> 570 <option id="USA1810" class="USA" value="1810, 7, 06, USA">US 1810</option> 571 <option id="USA1800" class="USA" value="1800, 7, 04, USA">US 1800</option> 572 <option id="USA1790" class="USA" value="1790, 7, 02, USA">US 1790</option> 573 <option value=""></option> 574 <option id="FR1951" class="FR" value="1951, 0, 01, FR">FR 1951</option> 575 <option id="FR1946" class="FR" value="1946, 0, 01, FR">FR 1946</option> 576 <option id="FR1941" class="FR" value="1941, 0, 01, FR">FR 1941</option> 577 <option id="FR1936" class="FR" value="1936, 0, 01, FR">FR 1936</option> 578 <option id="FR1931" class="FR" value="1931, 0, 01, FR">FR 1931</option> 579 <option id="FR1926" class="FR" value="1926, 0, 01, FR">FR 1926</option> 580 <option id="FR1921" class="FR" value="1921, 0, 01, FR">FR 1921</option> 581 <option id="FR1916" class="FR" value="1916, 0, 01, FR">FR 1916</option> 582 <option id="FR1911" class="FR" value="1911, 0, 01, FR">FR 1911</option> 583 <option id="FR1906" class="FR" value="1906, 0, 01, FR">FR 1906</option> 584 <option id="FR1901" class="FR" value="1901, 0, 01, FR">FR 1901</option> 585 <option id="FR1896" class="FR" value="1896, 0, 01, FR">FR 1896</option> 586 <option id="FR1891" class="FR" value="1891, 0, 01, FR">FR 1891</option> 587 <option id="FR1886" class="FR" value="1886, 0, 01, FR">FR 1886</option> 588 <option id="FR1881" class="FR" value="1881, 0, 01, FR">FR 1881</option> 589 <option id="FR1876" class="FR" value="1876, 0, 01, FR">FR 1876</option> 590 <option value=""></option> 591 </select> 592 593 <input type="hidden" id="setctry" name="setctry" value=""> 594 <input type="hidden" id="setyear" name="setyear" value=""> 595 '; 596 } else { 597 return ''; 598 } 599 } 600} 601