{"id":255,"date":"2021-03-03T04:30:46","date_gmt":"2021-03-03T04:30:46","guid":{"rendered":"https:\/\/trubianvillage.com\/researchcenter\/home\/"},"modified":"2026-07-30T18:22:07","modified_gmt":"2026-07-30T18:22:07","slug":"home","status":"publish","type":"page","link":"https:\/\/trubianvillage.com\/researchcenter\/","title":{"rendered":"Home"},"content":{"rendered":"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<title>People of the Record Ancestral Research Center<\/title>\n<style>\n:root{\n  --green:#173a2d;\n  --green2:#2f654e;\n  --gold:#b8893b;\n  --cream:#f5efe2;\n  --paper:#fffdf8;\n  --ink:#1f2924;\n  --muted:#67726c;\n  --line:#d9cfbd;\n  --red:#9e3131;\n  --shadow:0 12px 28px rgba(21,42,31,.12);\n}\n*{box-sizing:border-box}\nbody{margin:0;font-family:Georgia,\"Times New Roman\",serif;background:var(--cream);color:var(--ink)}\nbutton,input,select,textarea{font:inherit}\nbutton{cursor:pointer}\n.hidden{display:none!important}\n.topbar{position:sticky;top:0;z-index:20;background:var(--green);color:#fff;padding:14px 5vw;display:flex;justify-content:space-between;align-items:center;gap:18px;box-shadow:0 4px 16px rgba(0,0,0,.2)}\n.brand{font-weight:700}\n.nav{display:flex;gap:8px;flex-wrap:wrap}\n.nav button{border:0;background:transparent;color:#fff;padding:8px 10px;border-radius:8px}\n.nav button:hover{background:rgba(255,255,255,.12)}\n.hero{padding:82px 7vw;background:linear-gradient(135deg,#142f24,#315b49);color:#fff;display:grid;grid-template-columns:1.4fr .8fr;gap:32px;align-items:center}\n.hero h1{font-size:clamp(2.5rem,6vw,5rem);line-height:.98;margin:0 0 20px}\n.hero p{font-size:1.15rem;line-height:1.7;max-width:760px}\n.hero-card{background:rgba(255,255,255,.1);border:1px solid rgba(255,255,255,.25);padding:24px;border-radius:18px}\n.section{padding:58px 6vw}\n.section h2{font-size:2.25rem;margin:0 0 12px}\n.lead{color:var(--muted);max-width:900px;line-height:1.7}\n.grid{display:grid;gap:20px}\n.three{grid-template-columns:repeat(3,1fr)}\n.card,.panel{background:var(--paper);border:1px solid var(--line);border-radius:16px;padding:22px;box-shadow:var(--shadow)}\n.price{font-size:2.35rem;font-weight:700;color:var(--green2)}\n.btn{border:0;border-radius:9px;padding:11px 17px;background:var(--green2);color:#fff;font-weight:700}\n.btn.alt{background:#fff;color:var(--green);border:1px solid var(--green)}\n.btn.gold{background:var(--gold)}\n.btn.red{background:var(--red)}\n.btn.ghost{background:transparent;border:1px solid var(--green2);color:var(--green2)}\n.notice{padding:13px;border-radius:9px;background:#fff4d5;border:1px solid #e4c76e;margin:12px 0}\n.success{padding:13px;border-radius:9px;background:#e7f5ec;border:1px solid #9dc9ad;color:#195c38;margin:12px 0}\n.warning{color:#8d2b2b;font-weight:700}\n.searchrow{display:grid;grid-template-columns:2fr 1fr 1fr auto;gap:10px}\ninput,select,textarea{width:100%;padding:10px 11px;border:1px solid #cfc4b3;border-radius:8px;background:#fff}\ntextarea{min-height:100px;resize:vertical}\nlabel{display:block;font-weight:700;margin-bottom:6px}\n.results{display:grid;gap:12px;margin-top:18px}\n.result{background:#fff;border:1px solid var(--line);border-left:5px solid var(--gold);padding:15px;border-radius:11px}\n.badge{display:inline-block;font-size:.78rem;padding:4px 8px;border-radius:999px;background:#e7f1eb;color:#214c39;margin:0 5px 5px 0}\n.loginwrap{min-height:72vh;display:grid;place-items:center;padding:35px}\n.loginbox{max-width:430px;width:100%}\n.dashboard{display:grid;grid-template-columns:250px 1fr;min-height:760px}\n.side{background:#122b21;color:#fff;padding:23px}\n.side h3{margin-top:0}\n.side button{width:100%;border:0;background:transparent;color:#fff;text-align:left;padding:10px;border-radius:7px;margin:3px 0}\n.side button:hover,.side button.active{background:#294838}\n.workspace{padding:27px;background:#f7f2e8}\n.formgrid{display:grid;grid-template-columns:repeat(2,1fr);gap:13px}\n.full{grid-column:1\/-1}\n.kpis{display:grid;grid-template-columns:repeat(6,1fr);gap:12px}\n.kpi{background:#fff;border:1px solid var(--line);border-radius:13px;padding:17px}\n.kpi strong{display:block;font-size:1.8rem;color:var(--green2)}\ntable{width:100%;border-collapse:collapse}\nth,td{text-align:left;padding:10px;border-bottom:1px solid #e5ddcf;vertical-align:top}\nth{background:#f0eadf}\n.audio-controls{display:flex;gap:9px;flex-wrap:wrap}\n.backup-grid{display:grid;grid-template-columns:1fr 1fr;gap:18px}\n.backup-card{border:1px solid var(--line);border-radius:14px;padding:18px;background:#fff}\n.footer{padding:30px 6vw;background:#10261d;color:#e9f0ec}\n@media(max-width:950px){\n  .hero{grid-template-columns:1fr}\n  .three,.kpis{grid-template-columns:1fr 1fr}\n  .dashboard{grid-template-columns:1fr}\n  .searchrow,.formgrid,.backup-grid{grid-template-columns:1fr}\n}\n@media(max-width:620px){\n  .three,.kpis{grid-template-columns:1fr}\n  .topbar{align-items:flex-start;flex-direction:column}\n}\n<\/style>\n<\/head>\n<body>\n\n<header class=\"topbar\">\n  <div class=\"brand\">People of the Record Ancestral Research Center<\/div>\n  <nav class=\"nav\">\n    <button onclick=\"showPublic('home')\">Home<\/button>\n    <button onclick=\"showPublic('plans')\">Membership<\/button>\n    <button onclick=\"showPublic('academy')\">Audio Introduction<\/button>\n    <button onclick=\"showPublic('search')\">Archive Search<\/button>\n    <button onclick=\"showLogin()\">Administration<\/button>\n  <\/nav>\n<\/header>\n\n<main id=\"publicApp\">\n  <section id=\"homeView\">\n    <div class=\"hero\">\n      <div>\n        <span class=\"badge\">Genealogy \u2022 Archive \u2022 Registry \u2022 Research<\/span>\n        <h1>Preserve the Record. Reconnect the Family.<\/h1>\n        <p>A unified ancestral research platform for historical documents, family trees, member registry, professional genealogy, audio education, searchable names, and protected administrative records.<\/p>\n        <button class=\"btn gold\" onclick=\"showPublic('academy')\">Hear the Introduction<\/button>\n        <button class=\"btn alt\" onclick=\"showPublic('search')\">Search the Archive<\/button>\n      <\/div>\n      <div class=\"hero-card\">\n        <h3>Daily Database Protection<\/h3>\n        <p>Authorized Super Administrators can download a complete dated database backup and restore it by uploading the backup file.<\/p>\n      <\/div>\n    <\/div>\n    <section class=\"section\">\n      <h2>One Unified Research System<\/h2>\n      <p class=\"lead\">The platform combines indexed historical records, family archive tools, registry review, membership administration, fee waivers, editable pricing, professional research services, and daily database backups.<\/p>\n      <div class=\"grid three\">\n        <div class=\"card\"><h3>Historical Depository<\/h3><p>Index census, military, probate, land, vital, church, court, newspaper, tribal, and family records.<\/p><\/div>\n        <div class=\"card\"><h3>Family and Registry<\/h3><p>Connect members, evidence, ancestral lines, document vaults, and registry applications.<\/p><\/div>\n        <div class=\"card\"><h3>Protected Administration<\/h3><p>Two Super Administrators control staff accounts, pricing, waivers, records, and database backups.<\/p><\/div>\n      <\/div>\n    <\/section>\n  <\/section>\n\n  <section id=\"plansView\" class=\"section hidden\">\n    <h2>Membership Plans<\/h2>\n    <div class=\"grid three\">\n      <div class=\"card\"><h3>Research Access<\/h3><div class=\"price\" id=\"pricePublicResearch\">$13.99<\/div><p>per month<\/p><p>Archive search, research notebook, saved searches, audio academy, and basic research assistance.<\/p><\/div>\n      <div class=\"card\"><h3>Family Tree &#038; Archive<\/h3><div class=\"price\" id=\"pricePublicFamily\">$23.99<\/div><p>per month<\/p><p>Everything in Research Access plus family trees, family matching, timelines, and document vaults.<\/p><\/div>\n      <div class=\"card\"><h3>Professional Research<\/h3><div class=\"price\" id=\"pricePublicProfessional\">$33.99<\/div><p>per month<\/p><p>Everything in Family Tree &#038; Archive plus a researcher profile, projects, reports, and marketplace access.<\/p><\/div>\n    <\/div>\n    <div class=\"panel\" style=\"margin-top:22px\">\n      <h3>Apply a Fee-Waiver Code<\/h3>\n      <div class=\"searchrow\">\n        <input id=\"publicWaiverCode\" placeholder=\"Waiver code\">\n        <select id=\"publicWaiverPlan\"><option value=\"research\">Research Access<\/option><option value=\"family\">Family Tree &#038; Archive<\/option><option value=\"professional\">Professional Research<\/option><\/select>\n        <input id=\"publicWaiverEmail\" placeholder=\"Member email\">\n        <button class=\"btn\" onclick=\"applyPublicWaiver()\">Apply<\/button>\n      <\/div>\n      <div id=\"publicWaiverResult\"><\/div>\n    <\/div>\n  <\/section>\n\n  <section id=\"academyView\" class=\"section hidden\">\n    <h2>Audio Introduction and Research Academy<\/h2>\n    <p class=\"lead\">Select an episode and use the built-in browser voice reader. The transcript remains visible for read-along access.<\/p>\n    <div class=\"panel\">\n      <label>Episode<\/label>\n      <select id=\"episodeSelect\" onchange=\"loadEpisode()\"><\/select>\n      <div class=\"audio-controls\" style=\"margin:15px 0\">\n        <button class=\"btn\" onclick=\"playEpisode()\">Play<\/button>\n        <button class=\"btn alt\" onclick=\"pauseEpisode()\">Pause or Resume<\/button>\n        <button class=\"btn red\" onclick=\"stopEpisode()\">Stop<\/button>\n        <select id=\"speechRate\" style=\"max-width:150px\"><option value=\"0.8\">0.8\u00d7<\/option><option value=\"1\" selected>1\u00d7<\/option><option value=\"1.2\">1.2\u00d7<\/option><option value=\"1.5\">1.5\u00d7<\/option><\/select>\n      <\/div>\n      <h3 id=\"episodeTitle\"><\/h3>\n      <div id=\"episodeTranscript\" class=\"result\"><\/div>\n    <\/div>\n  <\/section>\n\n  <section id=\"searchView\" class=\"section hidden\">\n    <h2>Search the Internal Archive<\/h2>\n    <div class=\"panel\">\n      <div class=\"searchrow\">\n        <input id=\"publicSearchQuery\" placeholder=\"Name, place, collection, or keyword\">\n        <input id=\"publicSearchYear\" placeholder=\"Year\">\n        <select id=\"publicSearchCategory\"><\/select>\n        <button class=\"btn\" onclick=\"runPublicSearch()\">Search<\/button>\n      <\/div>\n      <div id=\"publicSearchResults\" class=\"results\"><\/div>\n    <\/div>\n  <\/section>\n<\/main>\n\n<section id=\"loginView\" class=\"loginwrap hidden\">\n  <div class=\"card loginbox\">\n    <h2>Administrative Login<\/h2>\n    <div class=\"notice\"><b>Super Administrator 1:<\/b> superadmin1 \/ records2026<br><b>Super Administrator 2:<\/b> superadmin2 \/ records2026<\/div>\n    <label>Username<\/label><input id=\"loginUsername\">\n    <label style=\"margin-top:12px\">Password<\/label><input id=\"loginPassword\" type=\"password\">\n    <button class=\"btn\" style=\"margin-top:15px;width:100%\" onclick=\"login()\">Log In<\/button>\n    <p id=\"loginMessage\"><\/p>\n  <\/div>\n<\/section>\n\n<section id=\"adminApp\" class=\"hidden\">\n  <div class=\"dashboard\">\n    <aside class=\"side\">\n      <h3>Administrative Center<\/h3>\n      <button class=\"active\" onclick=\"openAdminTab('dashboard',this)\">Dashboard<\/button>\n      <button onclick=\"openAdminTab('documents',this)\">Documents<\/button>\n      <button onclick=\"openAdminTab('registry',this)\">Registry<\/button>\n      <button onclick=\"openAdminTab('audio',this)\">Audio Academy<\/button>\n      <button class=\"super-only\" onclick=\"openAdminTab('admins',this)\">Administrators<\/button>\n      <button class=\"super-only\" onclick=\"openAdminTab('pricing',this)\">Pricing<\/button>\n      <button class=\"super-only\" onclick=\"openAdminTab('waivers',this)\">Fee Waivers<\/button>\n      <button class=\"super-only\" onclick=\"openAdminTab('backup',this)\">Backup &#038; Restore<\/button>\n      <button onclick=\"logout()\">Log Out<\/button>\n    <\/aside>\n\n    <div class=\"workspace\">\n      <div id=\"dashboardTab\" class=\"admin-tab\">\n        <h2>Dashboard<\/h2>\n        <div class=\"kpis\">\n          <div class=\"kpi\">Documents<strong id=\"kpiDocuments\">0<\/strong><\/div>\n          <div class=\"kpi\">Indexed People<strong id=\"kpiPeople\">0<\/strong><\/div>\n          <div class=\"kpi\">Registry Entries<strong id=\"kpiRegistry\">0<\/strong><\/div>\n          <div class=\"kpi\">Administrators<strong id=\"kpiAdmins\">0<\/strong><\/div>\n          <div class=\"kpi\">Active Waivers<strong id=\"kpiWaivers\">0<\/strong><\/div>\n          <div class=\"kpi\">Last Backup<strong id=\"kpiBackup\" style=\"font-size:1rem\">Never<\/strong><\/div>\n        <\/div>\n        <div class=\"panel\" style=\"margin-top:18px\">\n          <p>Signed in as <strong id=\"signedInName\"><\/strong> <span id=\"signedInRole\" class=\"badge\"><\/span><\/p>\n          <div id=\"backupDueNotice\"><\/div>\n        <\/div>\n      <\/div>\n\n      <div id=\"documentsTab\" class=\"admin-tab hidden\">\n        <h2>Document Intake and Search Index<\/h2>\n        <div class=\"panel\">\n          <div class=\"formgrid\">\n            <div class=\"full\"><label>Files<\/label><input id=\"documentFiles\" type=\"file\" multiple><\/div>\n            <div><label>Collection<\/label><input id=\"documentCollection\" placeholder=\"1880 Federal Census\"><\/div>\n            <div><label>Category<\/label><select id=\"documentCategory\"><\/select><\/div>\n            <div><label>Year<\/label><input id=\"documentYear\"><\/div>\n            <div><label>Location<\/label><input id=\"documentLocation\"><\/div>\n            <div class=\"full\"><label>People named in the record, one per line<\/label><textarea id=\"documentPeople\"><\/textarea><\/div>\n            <div class=\"full\"><label>Aliases and search terms<\/label><textarea id=\"documentAliases\"><\/textarea><\/div>\n            <div class=\"full\"><label>Notes<\/label><textarea id=\"documentNotes\"><\/textarea><\/div>\n          <\/div>\n          <button class=\"btn\" onclick=\"saveDocuments()\">Index Documents<\/button>\n          <p id=\"documentMessage\"><\/p>\n        <\/div>\n        <div class=\"panel\" style=\"overflow:auto\">\n          <table><thead><tr><th>Archive ID<\/th><th>File<\/th><th>Collection<\/th><th>People<\/th><th>Action<\/th><\/tr><\/thead><tbody id=\"documentsTable\"><\/tbody><\/table>\n        <\/div>\n      <\/div>\n\n      <div id=\"registryTab\" class=\"admin-tab hidden\">\n        <h2>People of the Record Registry<\/h2>\n        <div class=\"panel\">\n          <div class=\"formgrid\">\n            <div><label>Full name<\/label><input id=\"registryName\"><\/div>\n            <div><label>Email<\/label><input id=\"registryEmail\"><\/div>\n            <div><label>Family line<\/label><input id=\"registryFamily\"><\/div>\n            <div><label>Status<\/label><select id=\"registryStatus\"><option>Pending Review<\/option><option>Verified<\/option><option>Verified With Limitations<\/option><option>Rejected<\/option><\/select><\/div>\n            <div class=\"full\"><label>Evidence notes<\/label><textarea id=\"registryEvidence\"><\/textarea><\/div>\n          <\/div>\n          <button class=\"btn\" onclick=\"saveRegistryEntry()\">Save Registry Entry<\/button>\n        <\/div>\n        <div class=\"panel\" style=\"overflow:auto\"><table><thead><tr><th>Name<\/th><th>Family<\/th><th>Status<\/th><th>Action<\/th><\/tr><\/thead><tbody id=\"registryTable\"><\/tbody><\/table><\/div>\n      <\/div>\n\n      <div id=\"audioTab\" class=\"admin-tab hidden\">\n        <h2>Audio Academy Editor<\/h2>\n        <div class=\"panel\">\n          <label>Episode title<\/label><input id=\"newEpisodeTitle\">\n          <label style=\"margin-top:12px\">Transcript<\/label><textarea id=\"newEpisodeText\"><\/textarea>\n          <button class=\"btn\" onclick=\"saveEpisode()\">Add Episode<\/button>\n        <\/div>\n        <div id=\"adminEpisodes\" class=\"grid\"><\/div>\n      <\/div>\n\n      <div id=\"adminsTab\" class=\"admin-tab hidden\">\n        <h2>Administrator Management<\/h2>\n        <div class=\"panel\">\n          <div class=\"formgrid\">\n            <div><label>Name<\/label><input id=\"adminName\"><\/div>\n            <div><label>Username<\/label><input id=\"adminUsername\"><\/div>\n            <div><label>Password<\/label><input id=\"adminPassword\" type=\"password\"><\/div>\n            <div><label>Role<\/label><select id=\"adminRole\"><option value=\"admin\">Administrator<\/option><option value=\"superadmin\">Super Administrator<\/option><\/select><\/div>\n          <\/div>\n          <button class=\"btn\" onclick=\"saveAdministrator()\">Create Administrator<\/button>\n          <p id=\"adminMessage\"><\/p>\n        <\/div>\n        <div class=\"panel\" style=\"overflow:auto\"><table><thead><tr><th>Name<\/th><th>Username<\/th><th>Role<\/th><th>Status<\/th><th>Action<\/th><\/tr><\/thead><tbody id=\"adminsTable\"><\/tbody><\/table><\/div>\n      <\/div>\n\n      <div id=\"pricingTab\" class=\"admin-tab hidden\">\n        <h2>Membership Pricing<\/h2>\n        <div class=\"panel\">\n          <div class=\"formgrid\">\n            <div><label>Research Access<\/label><input id=\"priceResearch\" type=\"number\" step=\"0.01\"><\/div>\n            <div><label>Family Tree &#038; Archive<\/label><input id=\"priceFamily\" type=\"number\" step=\"0.01\"><\/div>\n            <div><label>Professional Research<\/label><input id=\"priceProfessional\" type=\"number\" step=\"0.01\"><\/div>\n          <\/div>\n          <button class=\"btn\" onclick=\"savePricing()\">Save Prices<\/button>\n          <p id=\"pricingMessage\"><\/p>\n        <\/div>\n      <\/div>\n\n      <div id=\"waiversTab\" class=\"admin-tab hidden\">\n        <h2>Fee-Waiver Administration<\/h2>\n        <div class=\"panel\">\n          <div class=\"formgrid\">\n            <div><label>Code<\/label><input id=\"waiverCode\"><\/div>\n            <div><label>Applicable plan<\/label><select id=\"waiverPlan\"><option value=\"all\">All Plans<\/option><option value=\"research\">Research Access<\/option><option value=\"family\">Family Tree &#038; Archive<\/option><option value=\"professional\">Professional Research<\/option><\/select><\/div>\n            <div><label>Type<\/label><select id=\"waiverType\"><option value=\"full\">Full Waiver<\/option><option value=\"percent\">Percentage<\/option><option value=\"fixed\">Fixed Dollar Amount<\/option><\/select><\/div>\n            <div><label>Amount<\/label><input id=\"waiverAmount\" type=\"number\" value=\"100\"><\/div>\n            <div><label>Maximum uses<\/label><input id=\"waiverMaxUses\" type=\"number\" value=\"1\"><\/div>\n            <div><label>Expiration<\/label><input id=\"waiverExpiration\" type=\"date\"><\/div>\n            <div><label>Email restriction<\/label><input id=\"waiverEmail\"><\/div>\n            <div><label>Status<\/label><select id=\"waiverStatus\"><option value=\"active\">Active<\/option><option value=\"inactive\">Inactive<\/option><\/select><\/div>\n          <\/div>\n          <button class=\"btn\" onclick=\"saveWaiver()\">Create Waiver<\/button>\n          <p id=\"waiverMessage\"><\/p>\n        <\/div>\n        <div class=\"panel\" style=\"overflow:auto\"><table><thead><tr><th>Code<\/th><th>Plan<\/th><th>Benefit<\/th><th>Uses<\/th><th>Status<\/th><th>Action<\/th><\/tr><\/thead><tbody id=\"waiversTable\"><\/tbody><\/table><\/div>\n      <\/div>\n\n      <div id=\"backupTab\" class=\"admin-tab hidden\">\n        <h2>Daily Database Backup and Restore<\/h2>\n        <div class=\"notice\">Download one backup each day and store it somewhere separate from the website, such as an external drive or protected cloud folder.<\/div>\n        <div class=\"backup-grid\">\n          <div class=\"backup-card\">\n            <h3>Download Complete Database<\/h3>\n            <p>This exports documents, indexed people, registry records, administrators, prices, waiver codes, waiver history, audio episodes, and system settings into one dated JSON file.<\/p>\n            <button class=\"btn gold\" onclick=\"downloadDatabaseBackup()\">Download Today&#8217;s Backup<\/button>\n            <p id=\"downloadBackupMessage\"><\/p>\n          <\/div>\n          <div class=\"backup-card\">\n            <h3>Restore Database<\/h3>\n            <p>Select a previous JSON backup. Restoring replaces the current browser database with the information stored in that backup.<\/p>\n            <input id=\"restoreBackupFile\" type=\"file\" accept=\".json\">\n            <button class=\"btn red\" style=\"margin-top:12px\" onclick=\"restoreDatabaseBackup()\">Restore Uploaded Backup<\/button>\n            <p id=\"restoreBackupMessage\"><\/p>\n          <\/div>\n        <\/div>\n        <div class=\"panel\" style=\"margin-top:18px\">\n          <h3>Backup History<\/h3>\n          <div id=\"backupHistory\"><\/div>\n        <\/div>\n      <\/div>\n    <\/div>\n  <\/div>\n<\/section>\n\n<footer class=\"footer\">\n  <strong>People of the Record Ancestral Research Center<\/strong>\n  <p>Preview system with archive search, administration, audio education, pricing, waivers, and database backup and restore.<\/p>\n<\/footer>\n\n<script>\nconst categories=[\"All Categories\",\"Census Records\",\"Military Records\",\"Probate and Estate Records\",\"Land and Property Records\",\"Birth Records\",\"Death Records\",\"Marriage Records\",\"Court Records\",\"Church Records\",\"Freedmen's Bureau Records\",\"Freedman's Bank Records\",\"Newspapers\",\"Tribal and Enrollment Records\",\"Family Records\",\"Other Historical Records\"];\n\nlet database=JSON.parse(localStorage.getItem(\"por_complete_database\")||\"null\")||{\n  version:\"1.0\",\n  documents:[{\n    id:\"POR-CEN-1880-000001\",file:\"lincoln_parish_1880_page_12.pdf\",collection:\"1880 Louisiana Federal Census\",\n    category:\"Census Records\",year:\"1880\",location:\"Lincoln Parish, Louisiana\",\n    people:[\"Robert French | age 39\",\"Peggy French | age 35\",\"William French | age 12\"],\n    aliases:\"Robt. French, Peggie French\",notes:\"Household 122\"\n  }],\n  registry:[],\n  administrators:[\n    {id:\"ADM-0001\",name:\"Primary Super Administrator\",username:\"superadmin1\",password:\"records2026\",role:\"superadmin\",active:true},\n    {id:\"ADM-0002\",name:\"Second Super Administrator\",username:\"superadmin2\",password:\"records2026\",role:\"superadmin\",active:true}\n  ],\n  prices:{research:13.99,family:23.99,professional:33.99},\n  waivers:[],\n  waiverUses:[],\n  episodes:[\n    {title:\"Welcome to the People of the Record Ancestral Research Center\",text:\"Welcome to the People of the Record Ancestral Research Center. This platform was created to preserve family records, reconnect bloodlines, organize historical documents, and provide a growing research system for people seeking evidence of their ancestors. The archive brings documents, family trees, registry applications, research notes, and professional genealogy services into one connected system.\"},\n    {title:\"How the Internal Archive Works\",text:\"Every approved document entered into the archive may be indexed by name, year, place, collection, record type, family relationship, and alternate spelling. A single census page may create many searchable person entries. Members can search the internal archive and discover possible records connected to their ancestors.\"},\n    {title:\"The Registry and Evidence Review\",text:\"The People of the Record Registry is evidence based. Technology may help organize documents and identify possible connections, but authorized human reviewers make registry decisions. Records may be marked pending review, verified, verified with limitations, restricted, or rejected.\"}\n  ],\n  backupHistory:[],\n  lastBackup:null\n};\n\nlet currentAdmin=null;\nlet speech=null;\n\nfunction saveDatabase(){\n  localStorage.setItem(\"por_complete_database\",JSON.stringify(database));\n}\nfunction money(v){return \"$\"+Number(v||0).toFixed(2)}\nfunction esc(v){return String(v??\"\").replace(\/[&<>\"']\/g,m=>({\"&\":\"&amp;\",\"<\":\"&lt;\",\">\":\"&gt;\",'\"':\"&quot;\",\"'\":\"&#039;\"}[m]))}\n\nfunction initialize(){\n  documentCategory.innerHTML=categories.slice(1).map(c=>`<option>${esc(c)}<\/option>`).join(\"\");\n  publicSearchCategory.innerHTML=categories.map((c,i)=>`<option value=\"${i?esc(c):\"\"}\">${esc(c)}<\/option>`).join(\"\");\n  episodeSelect.innerHTML=database.episodes.map((e,i)=>`<option value=\"${i}\">Episode ${i+1}: ${esc(e.title)}<\/option>`).join(\"\");\n  loadEpisode();applyPrices();refreshAdmin();showPublic(\"home\");\n}\nfunction showPublic(name){\n  publicApp.classList.remove(\"hidden\");loginView.classList.add(\"hidden\");adminApp.classList.add(\"hidden\");\n  [\"home\",\"plans\",\"academy\",\"search\"].forEach(x=>document.getElementById(x+\"View\").classList.toggle(\"hidden\",x!==name));\n  if(name===\"plans\")applyPrices();\n}\nfunction showLogin(){publicApp.classList.add(\"hidden\");adminApp.classList.add(\"hidden\");loginView.classList.remove(\"hidden\")}\nfunction login(){\n  const user=database.administrators.find(a=>a.active&&a.username===loginUsername.value.trim()&&a.password===loginPassword.value);\n  if(!user){loginMessage.textContent=\"Incorrect login or inactive account.\";return}\n  currentAdmin=user;loginView.classList.add(\"hidden\");publicApp.classList.add(\"hidden\");adminApp.classList.remove(\"hidden\");applyRole();refreshAdmin();\n}\nfunction logout(){currentAdmin=null;showPublic(\"home\")}\nfunction applyRole(){\n  document.querySelectorAll(\".super-only\").forEach(x=>x.classList.toggle(\"hidden\",!currentAdmin||currentAdmin.role!==\"superadmin\"));\n  signedInName.textContent=currentAdmin?currentAdmin.name:\"\";\n  signedInRole.textContent=currentAdmin?(currentAdmin.role===\"superadmin\"?\"Super Administrator\":\"Administrator\"):\"\";\n}\nfunction openAdminTab(name,button){\n  const protectedTabs=[\"admins\",\"pricing\",\"waivers\",\"backup\"];\n  if(protectedTabs.includes(name)&&(!currentAdmin||currentAdmin.role!==\"superadmin\")){alert(\"Super Administrator access is required.\");return}\n  document.querySelectorAll(\".admin-tab\").forEach(x=>x.classList.add(\"hidden\"));\n  document.getElementById(name+\"Tab\").classList.remove(\"hidden\");\n  document.querySelectorAll(\".side button\").forEach(x=>x.classList.remove(\"active\"));\n  if(button)button.classList.add(\"active\");\n  refreshAdmin();\n}\nfunction applyPrices(){\n  pricePublicResearch.textContent=money(database.prices.research);\n  pricePublicFamily.textContent=money(database.prices.family);\n  pricePublicProfessional.textContent=money(database.prices.professional);\n  priceResearch.value=database.prices.research;priceFamily.value=database.prices.family;priceProfessional.value=database.prices.professional;\n}\nfunction savePricing(){\n  database.prices={research:Number(priceResearch.value),family:Number(priceFamily.value),professional:Number(priceProfessional.value)};\n  saveDatabase();applyPrices();pricingMessage.textContent=\"Prices updated.\";\n}\nfunction loadEpisode(){\n  const e=database.episodes[Number(episodeSelect.value)||0];\n  if(!e)return;\n  episodeTitle.textContent=e.title;episodeTranscript.textContent=e.text;\n}\nfunction playEpisode(){\n  stopEpisode();\n  const e=database.episodes[Number(episodeSelect.value)||0];if(!e)return;\n  speech=new SpeechSynthesisUtterance(e.text);speech.rate=Number(speechRate.value);speechSynthesis.speak(speech);\n}\nfunction pauseEpisode(){if(speechSynthesis.paused)speechSynthesis.resume();else speechSynthesis.pause()}\nfunction stopEpisode(){speechSynthesis.cancel();speech=null}\nfunction saveEpisode(){\n  if(!newEpisodeTitle.value.trim()||!newEpisodeText.value.trim())return;\n  database.episodes.push({title:newEpisodeTitle.value.trim(),text:newEpisodeText.value.trim()});saveDatabase();\n  newEpisodeTitle.value=\"\";newEpisodeText.value=\"\";initialize();openAdminTab(\"audio\");\n}\nfunction saveDocuments(){\n  const files=[...documentFiles.files];if(!files.length){documentMessage.textContent=\"Select at least one file.\";return}\n  const people=documentPeople.value.split(\/\\r?\\n\/).map(x=>x.trim()).filter(Boolean);\n  files.forEach(file=>database.documents.push({\n    id:\"POR-\"+String(database.documents.length+1).padStart(6,\"0\"),\n    file:file.name,collection:documentCollection.value||\"Unassigned Collection\",category:documentCategory.value,\n    year:documentYear.value,location:documentLocation.value,people,aliases:documentAliases.value,notes:documentNotes.value\n  }));\n  saveDatabase();documentMessage.textContent=files.length+\" document(s) indexed.\";documentFiles.value=\"\";refreshAdmin();\n}\nfunction deleteDocument(i){if(confirm(\"Delete this record?\")){database.documents.splice(i,1);saveDatabase();refreshAdmin()}}\nfunction saveRegistryEntry(){\n  if(!registryName.value.trim())return;\n  database.registry.push({name:registryName.value.trim(),email:registryEmail.value.trim(),family:registryFamily.value.trim(),status:registryStatus.value,evidence:registryEvidence.value.trim()});\n  saveDatabase();registryName.value=\"\";registryEmail.value=\"\";registryFamily.value=\"\";registryEvidence.value=\"\";refreshAdmin();\n}\nfunction deleteRegistry(i){if(confirm(\"Delete this registry entry?\")){database.registry.splice(i,1);saveDatabase();refreshAdmin()}}\nfunction saveAdministrator(){\n  if(!adminName.value.trim()||!adminUsername.value.trim()||!adminPassword.value){adminMessage.textContent=\"Complete every required field.\";return}\n  if(database.administrators.some(a=>a.username.toLowerCase()===adminUsername.value.trim().toLowerCase())){adminMessage.textContent=\"Username already exists.\";return}\n  database.administrators.push({id:\"ADM-\"+String(database.administrators.length+1).padStart(4,\"0\"),name:adminName.value.trim(),username:adminUsername.value.trim(),password:adminPassword.value,role:adminRole.value,active:true});\n  saveDatabase();adminMessage.textContent=\"Administrator created.\";adminName.value=\"\";adminUsername.value=\"\";adminPassword.value=\"\";refreshAdmin();\n}\nfunction toggleAdmin(i){\n  const a=database.administrators[i];\n  if(currentAdmin&&a.id===currentAdmin.id){alert(\"You cannot deactivate your current account.\");return}\n  const activeSupers=database.administrators.filter(x=>x.active&&x.role===\"superadmin\").length;\n  if(a.active&&a.role===\"superadmin\"&&activeSupers<=2){alert(\"At least two active Super Administrators must remain.\");return}\n  a.active=!a.active;saveDatabase();refreshAdmin();\n}\nfunction saveWaiver(){\n  const code=(waiverCode.value.trim()||(\"POR-\"+Math.random().toString(36).slice(2,8))).toUpperCase();\n  if(database.waivers.some(w=>w.code===code)){waiverMessage.textContent=\"That code already exists.\";return}\n  database.waivers.push({code,plan:waiverPlan.value,type:waiverType.value,amount:Number(waiverAmount.value)||0,maxUses:Math.max(1,Number(waiverMaxUses.value)||1),uses:0,expiration:waiverExpiration.value,email:waiverEmail.value.trim().toLowerCase(),status:waiverStatus.value});\n  saveDatabase();waiverMessage.textContent=\"Waiver created: \"+code;waiverCode.value=\"\";refreshAdmin();\n}\nfunction toggleWaiver(i){database.waivers[i].status=database.waivers[i].status===\"active\"?\"inactive\":\"active\";saveDatabase();refreshAdmin()}\nfunction applyPublicWaiver(){\n  const code=publicWaiverCode.value.trim().toUpperCase(),plan=publicWaiverPlan.value,email=publicWaiverEmail.value.trim().toLowerCase();\n  const w=database.waivers.find(x=>x.code===code);\n  if(!w){publicWaiverResult.innerHTML='<p class=\"warning\">Code not found.<\/p>';return}\n  if(w.status!==\"active\"||(w.plan!==\"all\"&&w.plan!==plan)||(w.expiration&&new Date(w.expiration+\"T23:59:59\")<new Date())||w.uses>=w.maxUses||(w.email&&w.email!==email)){\n    publicWaiverResult.innerHTML='<p class=\"warning\">This waiver is not valid for this enrollment.<\/p>';return\n  }\n  const base=database.prices[plan];let discount=0;\n  if(w.type===\"full\")discount=base;else if(w.type===\"percent\")discount=base*(w.amount\/100);else discount=w.amount;\n  discount=Math.min(base,discount);const due=Math.max(0,base-discount);\n  publicWaiverResult.innerHTML=`<div class=\"success\">Code accepted. Regular price: <b>${money(base)}<\/b>. Discount: <b>${money(discount)}<\/b>. Amount due: <b>${money(due)}<\/b>.<br><button class=\"btn\" style=\"margin-top:10px\" onclick=\"redeemWaiver('${esc(w.code)}','${esc(plan)}','${esc(email)}')\">Confirm Waiver<\/button><\/div>`;\n}\nfunction redeemWaiver(code,plan,email){\n  const w=database.waivers.find(x=>x.code===code);if(!w||w.uses>=w.maxUses)return;\n  const base=database.prices[plan];let discount=w.type===\"full\"?base:w.type===\"percent\"?base*(w.amount\/100):w.amount;discount=Math.min(base,discount);\n  w.uses++;database.waiverUses.unshift({code,plan,email,regularPrice:base,discount,amountDue:base-discount,date:new Date().toISOString()});saveDatabase();\n  publicWaiverResult.innerHTML='<div class=\"success\">Waiver successfully recorded.<\/div>';refreshAdmin();\n}\nfunction runPublicSearch(){\n  const q=publicSearchQuery.value.trim().toLowerCase(),year=publicSearchYear.value.trim(),cat=publicSearchCategory.value;\n  const matches=database.documents.filter(r=>{\n    const hay=[r.id,r.file,r.collection,r.category,r.year,r.location,r.aliases,r.notes,...(r.people||[])].join(\" \").toLowerCase();\n    return(!q||hay.includes(q))&&(!year||String(r.year).includes(year))&&(!cat||r.category===cat);\n  });\n  publicSearchResults.innerHTML=matches.length?matches.map(r=>`<div class=\"result\"><span class=\"badge\">${esc(r.category)}<\/span><h3>${esc(r.id)} \u2014 ${esc(r.file)}<\/h3><p><b>Collection:<\/b> ${esc(r.collection)}<br><b>Year:<\/b> ${esc(r.year||\"Unknown\")} &nbsp; <b>Location:<\/b> ${esc(r.location||\"Unknown\")}<\/p><p><b>Indexed people:<\/b> ${esc((r.people||[]).join(\"; \")||\"None\")}<\/p><\/div>`).join(\"\"):'<div class=\"result\">No matching records found.<\/div>';\n}\nfunction downloadDatabaseBackup(){\n  const now=new Date();\n  database.lastBackup=now.toISOString();\n  database.backupHistory.unshift({date:database.lastBackup,by:currentAdmin?currentAdmin.username:\"unknown\",documents:database.documents.length,registry:database.registry.length});\n  database.backupHistory=database.backupHistory.slice(0,100);\n  saveDatabase();\n  const backup={application:\"People of the Record Ancestral Research Center\",exportedAt:now.toISOString(),database};\n  const blob=new Blob([JSON.stringify(backup,null,2)],{type:\"application\/json\"});\n  const url=URL.createObjectURL(blob);const a=document.createElement(\"a\");\n  const stamp=now.getFullYear()+\"-\"+String(now.getMonth()+1).padStart(2,\"0\")+\"-\"+String(now.getDate()).padStart(2,\"0\")+\"_\"+String(now.getHours()).padStart(2,\"0\")+\"-\"+String(now.getMinutes()).padStart(2,\"0\");\n  a.href=url;a.download=\"people-of-the-record-backup_\"+stamp+\".json\";document.body.appendChild(a);a.click();a.remove();URL.revokeObjectURL(url);\n  downloadBackupMessage.textContent=\"Backup downloaded and recorded.\";refreshAdmin();\n}\nfunction restoreDatabaseBackup(){\n  const file=restoreBackupFile.files[0];if(!file){restoreBackupMessage.textContent=\"Select a JSON backup file.\";return}\n  const reader=new FileReader();\n  reader.onload=()=>{\n    try{\n      const parsed=JSON.parse(reader.result);const restored=parsed.database||parsed;\n      const required=[\"documents\",\"registry\",\"administrators\",\"prices\",\"waivers\",\"episodes\"];\n      if(!required.every(k=>Object.prototype.hasOwnProperty.call(restored,k)))throw new Error(\"Invalid backup structure\");\n      if(!confirm(\"Restore this backup? Current browser data will be replaced.\"))return;\n      database=restored;database.backupHistory=database.backupHistory||[];database.lastBackup=database.lastBackup||null;\n      saveDatabase();restoreBackupMessage.textContent=\"Database restored successfully.\";initialize();showLogin();\n    }catch(e){restoreBackupMessage.textContent=\"The selected file is not a valid system backup.\"}\n  };\n  reader.readAsText(file);\n}\nfunction refreshAdmin(){\n  applyRole();applyPrices();\n  kpiDocuments.textContent=database.documents.length;\n  kpiPeople.textContent=database.documents.reduce((n,r)=>n+(r.people||[]).length,0);\n  kpiRegistry.textContent=database.registry.length;\n  kpiAdmins.textContent=database.administrators.filter(a=>a.active).length;\n  kpiWaivers.textContent=database.waivers.filter(w=>w.status===\"active\"&&w.uses<w.maxUses).length;\n  kpiBackup.textContent=database.lastBackup?new Date(database.lastBackup).toLocaleDateString():\"Never\";\n  const today=new Date().toDateString(),last=database.lastBackup?new Date(database.lastBackup).toDateString():\"\";\n  backupDueNotice.innerHTML=last===today?'<div class=\"success\">Today\u2019s database backup has been downloaded.<\/div>':'<div class=\"notice\"><b>Daily backup due.<\/b> Open Backup & Restore and download today\u2019s database copy.<\/div>';\n  documentsTable.innerHTML=database.documents.map((r,i)=>`<tr><td>${esc(r.id)}<\/td><td>${esc(r.file)}<\/td><td>${esc(r.collection)}<\/td><td>${(r.people||[]).length}<\/td><td><button class=\"btn red\" onclick=\"deleteDocument(${i})\">Delete<\/button><\/td><\/tr>`).join(\"\");\n  registryTable.innerHTML=database.registry.map((r,i)=>`<tr><td>${esc(r.name)}<\/td><td>${esc(r.family)}<\/td><td>${esc(r.status)}<\/td><td><button class=\"btn red\" onclick=\"deleteRegistry(${i})\">Delete<\/button><\/td><\/tr>`).join(\"\");\n  adminsTable.innerHTML=database.administrators.map((a,i)=>`<tr><td>${esc(a.name)}<\/td><td>${esc(a.username)}<\/td><td>${a.role===\"superadmin\"?\"Super Administrator\":\"Administrator\"}<\/td><td>${a.active?\"Active\":\"Inactive\"}<\/td><td><button class=\"btn ${a.active?\"red\":\"ghost\"}\" onclick=\"toggleAdmin(${i})\">${a.active?\"Deactivate\":\"Activate\"}<\/button><\/td><\/tr>`).join(\"\");\n  waiversTable.innerHTML=database.waivers.map((w,i)=>`<tr><td><b>${esc(w.code)}<\/b><\/td><td>${esc(w.plan)}<\/td><td>${w.type===\"full\"?\"Full waiver\":w.type===\"percent\"?w.amount+\"%\":money(w.amount)}<\/td><td>${w.uses}\/${w.maxUses}<\/td><td>${esc(w.status)}<\/td><td><button class=\"btn ghost\" onclick=\"toggleWaiver(${i})\">${w.status===\"active\"?\"Deactivate\":\"Activate\"}<\/button><\/td><\/tr>`).join(\"\");\n  adminEpisodes.innerHTML=database.episodes.map((e,i)=>`<div class=\"card\"><h3>${esc(e.title)}<\/h3><p>${esc(e.text.slice(0,240))}${e.text.length>240?\"...\":\"\"}<\/p><\/div>`).join(\"\");\n  backupHistory.innerHTML=database.backupHistory.length?database.backupHistory.map(b=>`<div class=\"result\"><b>${new Date(b.date).toLocaleString()}<\/b> by ${esc(b.by)}<br>${b.documents} documents and ${b.registry} registry entries<\/div>`).join(\"\"):\"<p>No backups recorded yet.<\/p>\";\n}\ninitialize();\n<\/script>\n<\/body>\n<\/html>\n\n\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1122,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"pagelayer_contact_templates":[],"_pagelayer_content":"","footnotes":""},"class_list":["post-255","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/trubianvillage.com\/researchcenter\/wp-json\/wp\/v2\/pages\/255","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/trubianvillage.com\/researchcenter\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/trubianvillage.com\/researchcenter\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/trubianvillage.com\/researchcenter\/wp-json\/wp\/v2\/users\/1122"}],"replies":[{"embeddable":true,"href":"https:\/\/trubianvillage.com\/researchcenter\/wp-json\/wp\/v2\/comments?post=255"}],"version-history":[{"count":316,"href":"https:\/\/trubianvillage.com\/researchcenter\/wp-json\/wp\/v2\/pages\/255\/revisions"}],"predecessor-version":[{"id":2224,"href":"https:\/\/trubianvillage.com\/researchcenter\/wp-json\/wp\/v2\/pages\/255\/revisions\/2224"}],"wp:attachment":[{"href":"https:\/\/trubianvillage.com\/researchcenter\/wp-json\/wp\/v2\/media?parent=255"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}