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