summaryrefslogtreecommitdiff
path: root/public/js/webtrees.min.js
diff options
context:
space:
mode:
authorGreg Roach <greg@subaqua.co.uk>2022-01-03 13:21:07 +0000
committerGreg Roach <greg@subaqua.co.uk>2022-01-03 13:21:07 +0000
commitd1a8402e9ca2ba8e58bd30cfd5a35f2d81ec931b (patch)
treef2843d1760474c4dd1439b98dd8527b9aea7a554 /public/js/webtrees.min.js
parent95edec1e3126cc06c267710e8935a03b0130d171 (diff)
downloadwebtrees-d1a8402e9ca2ba8e58bd30cfd5a35f2d81ec931b.tar.gz
webtrees-d1a8402e9ca2ba8e58bd30cfd5a35f2d81ec931b.tar.bz2
webtrees-d1a8402e9ca2ba8e58bd30cfd5a35f2d81ec931b.zip
Fix: #4144 - CSS for markdown
Diffstat (limited to 'public/js/webtrees.min.js')
-rw-r--r--public/js/webtrees.min.js1599
1 files changed, 1598 insertions, 1 deletions
diff --git a/public/js/webtrees.min.js b/public/js/webtrees.min.js
index 7056268798..60eccbc1d0 100644
--- a/public/js/webtrees.min.js
+++ b/public/js/webtrees.min.js
@@ -1 +1,1598 @@
-"use strict";function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _defineProperties(e,t){for(var a=0;a<t.length;a++){var n=t[a];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}function _createClass(e,t,a){return t&&_defineProperties(e.prototype,t),a&&_defineProperties(e,a),e}function _slicedToArray(e,t){return _arrayWithHoles(e)||_iterableToArrayLimit(e,t)||_unsupportedIterableToArray(e,t)||_nonIterableRest()}function _nonIterableRest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _unsupportedIterableToArray(e,t){if(e){if("string"==typeof e)return _arrayLikeToArray(e,t);var a=Object.prototype.toString.call(e).slice(8,-1);return"Object"===a&&e.constructor&&(a=e.constructor.name),"Map"===a||"Set"===a?Array.from(e):"Arguments"===a||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(a)?_arrayLikeToArray(e,t):void 0}}function _arrayLikeToArray(e,t){(null==t||t>e.length)&&(t=e.length);for(var a=0,n=new Array(t);a<t;a++)n[a]=e[a];return n}function _iterableToArrayLimit(e,t){var a=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=a){var n,o,r=[],i=!0,s=!1;try{for(a=a.call(e);!(i=(n=a.next()).done)&&(r.push(n.value),!t||r.length!==t);i=!0);}catch(e){s=!0,o=e}finally{try{i||null==a.return||a.return()}finally{if(s)throw o}}return r}}function _arrayWithHoles(e){if(Array.isArray(e))return e}!function(e){var t=document.documentElement.lang,a={Han:/[\u3400-\u9FCC]/,Grek:/[\u0370-\u03FF]/,Cyrl:/[\u0400-\u04FF]/,Hebr:/[\u0590-\u05FF]/,Arab:/[\u0600-\u06FF]/};function n(e){return e.replace(/\s+/g," ").trim()}e.detectScript=function(e){for(var t in a)if(e.match(a[t]))return t;return"Latn"},e.buildNameFromParts=function(a,o,r,i,s,l){var c="Han"===e.detectScript(a+o+r+o+i+s),d=c?"":" ",u=c||-1!==["hu","jp","ko","vi","zh-Hans","zh-Hant"].indexOf(t),p=-1!==["is"].indexOf(t)?"":"/";a=n(a),o=n(o.replace(/,/g,d)),r=n(r),i=function(e,a){return"pl"===t&&"F"===a?e.replace(/ski$/,"ska").replace(/cki$/,"cka").replace(/dzki$/,"dzka").replace(/żki$/,"żka"):e}(n(i.replace(/,/g,d)),l),s=n(s);var h=r.endsWith("'")||r.endsWith("‘")?"":" ",g=n(r+h+i);return n(a+d+(u?p+g+p+d+o:o+d+p+g+p)+d+s)},e.pasteAtCursor=function(e,t){if(null!==e){var a=e.selectionStart+t.length,n=e.value.substring(0,e.selectionStart),o=e.value.substring(e.selectionEnd);e.value=n+t+o,e.setSelectionRange(a,a),e.focus()}},e.reformatDate=function(e,t){var a=["JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC"],n=e.value,o=n.split("("),r="";o.length>1&&(n=o[0],r=o[1]),(n=(n=(n=(n=(n=n.toUpperCase()).replace(/\s+/g," ")).replace(/(^\s)|(\s$)/,"")).replace(/(\d)([A-Z])/g,"$1 $2")).replace(/([A-Z])(\d)/g,"$1 $2")).match(/^Q ([1-4]) (\d\d\d\d)$/)&&(n="BET "+a[3*RegExp.$1-3]+" "+RegExp.$2+" AND "+a[3*RegExp.$1-1]+" "+RegExp.$2),n.match(/^(@#DHIJRI@|HIJRI)( \d?\d )(\d?\d)( \d?\d?\d?\d)$/)&&(n="@#DHIJRI@"+RegExp.$2+["MUHAR","SAFAR","RABIA","RABIT","JUMAA","JUMAT","RAJAB","SHAAB","RAMAD","SHAWW","DHUAQ","DHUAH"][parseInt(RegExp.$3,10)-1]+RegExp.$4),n.match(/^(@#DJALALI@|JALALI)( \d?\d )(\d?\d)( \d?\d?\d?\d)$/)&&(n="@#DJALALI@"+RegExp.$2+["FARVA","ORDIB","KHORD","TIR","MORDA","SHAHR","MEHR","ABAN","AZAR","DEY","BAHMA","ESFAN"][parseInt(RegExp.$3,10)-1]+RegExp.$4),n.match(/^(@#DHEBREW@|HEBREW)( \d?\d )(\d?\d)( \d?\d?\d?\d)$/)&&(n="@#DHEBREW@"+RegExp.$2+["TSH","CSH","KSL","TVT","SHV","ADR","ADS","NSN","IYR","SVN","TMZ","AAV","ELL"][parseInt(RegExp.$3,10)-1]+RegExp.$4),n.match(/^(@#DFRENCH R@|FRENCH)( \d?\d )(\d?\d)( \d?\d?\d?\d)$/)&&(n="@#DFRENCH R@"+RegExp.$2+["VEND","BRUM","FRIM","NIVO","PLUV","VENT","GERM","FLOR","PRAI","MESS","THER","FRUC","COMP"][parseInt(RegExp.$3,10)-1]+RegExp.$4),n=(n=(n=n.replace(/(\d\d)(\d\d)(\d\d)(\d\d)/g,(function(){return RegExp.$1>"12"&&RegExp.$3<="12"&&RegExp.$4<="31"?RegExp.$4+" "+a[RegExp.$3-1]+" "+RegExp.$1+RegExp.$2:RegExp.$1<="31"&&RegExp.$2<="12"&&RegExp.$3>"12"?RegExp.$1+" "+a[RegExp.$2-1]+" "+RegExp.$3+RegExp.$4:RegExp.$1+RegExp.$2+RegExp.$3+RegExp.$4}))).replace(/(\d+)([ ./-])(\d+)(\2)(\d+)/g,(function(){var e=parseInt(RegExp.$1,10),n=parseInt(RegExp.$3,10),o=parseInt(RegExp.$5,10),r=(new Date).getFullYear(),i=r%100,s=r-i;return("DMY"===t||e>13&&o>31)&&e<=31&&n<=12?e+" "+a[n-1]+" "+(o>=100?o:o<=i?o+s:o+s-100):("MDY"===t||n>13&&o>31)&&e<=12&&n<=31?n+" "+a[e-1]+" "+(o>=100?o:o<=i?o+s:o+s-100):("YMD"===t||e>31)&&n<=12&&o<=31?o+" "+a[n-1]+" "+(e>=100?e:e<=i?e+s:e+s-100):RegExp.$1+RegExp.$2+RegExp.$3+RegExp.$4+RegExp.$5}))).replace(/^[>]([\w ]+)$/,"AFT $1").replace(/^[<]([\w ]+)$/,"BEF $1").replace(/^([\w ]+)[-]$/,"FROM $1").replace(/^[-]([\w ]+)$/,"TO $1").replace(/^[~]([\w ]+)$/,"ABT $1").replace(/^[*]([\w ]+)$/,"EST $1").replace(/^[#]([\w ]+)$/,"CAL $1").replace(/^([\w ]+) ?- ?([\w ]+)$/,"BET $1 AND $2").replace(/^([\w ]+) ?~ ?([\w ]+)$/,"FROM $1 TO $2").replace(/JANUARY/g,"JAN").replace(/FEBRUARY/g,"FEB").replace(/MARCH/g,"MAR").replace(/APRIL/g,"APR").replace(/JUNE/g,"JUN").replace(/JULY/g,"JUL").replace(/AUGUST/g,"AUG").replace(/SEPTEMBER/g,"SEP").replace(/OCTOBER/,"OCT").replace(/NOVEMBER/g,"NOV").replace(/DECEMBER/g,"DEC").replace(/(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)\.? (\d\d?)[, ]+(\d\d\d\d)/g,"$2 $1 $3").replace(/(^| )(\d [A-Z]{3,5} \d{4})/g,"$10$2"),r&&(n=n+" ("+r),e.value!==n&&(e.value=n)};var o=[];o[1]="January",o[2]="February",o[3]="March",o[4]="April",o[5]="May",o[6]="June",o[7]="July",o[8]="August",o[9]="September",o[10]="October",o[11]="November",o[12]="December";var r=[];r[1]="JAN",r[2]="FEB",r[3]="MAR",r[4]="APR",r[5]="MAY",r[6]="JUN",r[7]="JUL",r[8]="AUG",r[9]="SEP",r[10]="OCT",r[11]="NOV",r[12]="DEC";var i=[];i[0]="S",i[1]="M",i[2]="T",i[3]="W",i[4]="T",i[5]="F",i[6]="S";var s=0;function l(e,t,a){var n,r,l='<table border="1"><tr>';for(l+='<td><select class="form-control" id="'+e+'_daySelect" onchange="return webtrees.calUpdateCalendar(\''+e+"', '"+t+"');\">",n=1;n<32;n++)l+='<option value="'+n+'"',a.getDate()===n&&(l+=' selected="selected"'),l+=">"+n+"</option>";for(l+="</select></td>",l+='<td><select class="form-control" id="'+e+'_monSelect" onchange="return webtrees.calUpdateCalendar(\''+e+"', '"+t+"');\">",n=1;n<13;n++)l+='<option value="'+n+'"',a.getMonth()+1===n&&(l+=' selected="selected"'),l+=">"+o[n]+"</option>";for(l+="</select></td>",l+='<td><input class="form-control" type="text" id="'+e+'_yearInput" size="5" value="'+a.getFullYear()+'" onchange="return webtrees.calUpdateCalendar(\''+e+"', '"+t+"');\" /></td></tr>",l+='<tr><td colspan="3">',l+='<table width="100%">',l+="<tr>",r=s,n=0;n<7;n++)l+="<td ",l+='class="descriptionbox"',l+=">",l+=i[r],l+="</td>",++r>6&&(r=0);l+="</tr>";var c=new Date(a.getFullYear(),a.getMonth(),1),d=c.getDay();d-=s;var u=864e5;for(c=c.getTime()-d*u+432e5,c=new Date(c),r=0;r<6;r++){for(l+="<tr>",n=0;n<7;n++){l+="<td ",c.getMonth()===a.getMonth()?c.getDate()===a.getDate()?l+='class="descriptionbox"':l+='class="optionbox"':l+='style="background-color:#EAEAEA; border: solid #AAAAAA 1px;"',l+='><a href="#" onclick="return webtrees.calDateClicked(\''+e+"', '"+t+"', "+c.getFullYear()+", "+c.getMonth()+", "+c.getDate()+');">',l+=c.getDate(),l+="</a></td>";var p=c.getTime()+u;c=new Date(p)}l+="</tr>"}return l+="</table>",l+="</td></tr>",l+="</table>"}function c(e,t,a,n){return document.getElementById(e).value=(n<10?"0":"")+n+" "+r[a+1]+" "+t,!1}function d(e,t,a){var n=e.value.toUpperCase();(n=(n=(n=(n=(n=(n=(n=(n=(n=(n=n.replace(/(^\s*)|(\s*$)/g,"")).replace(/ /g,":")).replace(/\+/g,"")).replace(/-/g,a)).replace(/,/g,".")).replace(/\u00b0/g,":")).replace(/\u0027/g,":")).replace(/^([0-9]+):([0-9]+):([0-9.]+)(.*)/g,(function(e,t,a,n,o){var r=parseFloat(t);return r+=a/60,r+=n/3600,o+(r=Math.round(1e4*r)/1e4)}))).replace(/^([0-9]+):([0-9]+)(.*)/g,(function(e,t,a,n){var o=parseFloat(t);return o+=a/60,n+(o=Math.round(1e4*o)/1e4)}))).replace(/(.*)(NSEW])$/g,"$2$1"))&&n.charAt(0)!==a&&n.charAt(0)!==t&&(n=t+n),e.value=n}e.calLocalize=function(e,t,a,n,r,l,c,d,u,p,h,g,f,v,m,b,w,y,x,E){o[1]=e,o[2]=t,o[3]=a,o[4]=n,o[5]=r,o[6]=l,o[7]=c,o[8]=d,o[9]=u,o[10]=p,o[11]=h,o[12]=g,i[0]=f,i[1]=v,i[2]=m,i[3]=b,i[4]=w,i[5]=y,i[6]=x,E>=0&&E<7&&(s=E)},e.calendarWidget=function(e,t){var a=document.getElementById(e),n=document.getElementById(t);if("visible"===a.style.visibility)return a.style.visibility="hidden",!1;if("show"===a.style.visibility)return a.style.visibility="hide",!1;var o;if(/(?:(\d*) ?(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC) )?(\d+)/i.exec(n.value)){var r=RegExp.$1||"1",i=RegExp.$2||"JAN",s=RegExp.$3;o=new Date(r+" "+i+" "+s)}else o=new Date;return a.innerHTML=l(t,e,o),"hidden"===a.style.visibility?(a.style.visibility="visible",!1):"hide"===a.style.visibility&&(a.style.visibility="show",!1)},e.calUpdateCalendar=function(e,t){var a=document.getElementById(e+"_daySelect");if(!a)return!1;var n=document.getElementById(e+"_monSelect");if(!n)return!1;var o=document.getElementById(e+"_yearInput");if(!o)return!1;var r=parseInt(n.options[n.selectedIndex].value,10);r-=1;var i=new Date(o.value,r,a.options[a.selectedIndex].value);c(e,i.getFullYear(),i.getMonth(),i.getDate());var s=document.getElementById(t);return s?(s.innerHTML=l(e,t,i),!1):(alert("no dateDiv "+t),!1)},e.calDateClicked=function(t,a,n,o,r){return c(t,n,o,r),e.calendarWidget(a,t),!1},e.persistentToggle=function(e){if(e instanceof HTMLInputElement&&"checkbox"===e.type){var t="state-of-"+e.dataset.wtPersist;"true"===localStorage.getItem(t)&&e.click(),e.addEventListener("change",(function(){localStorage.setItem(t,e.checked.toString())}))}},e.reformatLatitude=function(e){return d(e,"N","S")},e.reformatLongitude=function(e){return d(e,"E","W")},e.autocomplete=function(e){$(e).each((function(){var e=this;$(this).typeahead(null,{display:"value",limit:10,minLength:2,source:new Bloodhound({datumTokenizer:Bloodhound.tokenizers.obj.whitespace("value"),queryTokenizer:Bloodhound.tokenizers.whitespace,remote:{url:this.dataset.wtAutocompleteUrl,replace:function(t,a){var n=t.indexOf("?")>0?"&":"?";if("SOUR"===e.dataset.wtAutocompleteExtra){for(var o=e.closest(".form-group").previousElementSibling;null===o.querySelector("select");)o=o.previousElementSibling;var r=o.querySelector("select"),i=r.options[r.selectedIndex].value.replace(/@/g,"");return t+n+"query="+a+"&extra="+encodeURIComponent(i)}return t+n+"query="+a}}})})}))},e.buildLeafletJsMap=function(e,t){for(var a=new L.control.zoom({zoomInTitle:t.i18n.zoomIn,zoomoutTitle:t.i18n.zoomOut}),n=null,o=0,r=Object.entries(t.mapProviders);o<r.length;o++)for(var i=_slicedToArray(r[o],2)[1],s=0,l=Object.entries(i.children);s<l.length;s++){var c=_slicedToArray(l[s],2)[1];c.layer="bingMapsKey"in c?L.tileLayer.bing(c):L.tileLayer(c.url,c),i.default&&c.default&&(n=c.layer)}if(null===n){console.log("No default map layer defined - using the first one.");t.mapProviders[0].children[0].layer}return L.map(e,{zoomControl:!1}).addControl(a).addLayer(n).addControl(L.control.layers.tree(t.mapProviders,null,{closedSymbol:t.icons.expand,openedSymbol:t.icons.collapse}))}}(window.webtrees=window.webtrees||{}),$.ajaxSetup({headers:{"X-CSRF-TOKEN":$("meta[name=csrf]").attr("content")}}),$((function(){$("[data-wt-ajax-url]").each((function(){$(this).load(this.dataset.wtAjaxUrl)})),webtrees.autocomplete("input[data-wt-autocomplete-url]");var e,t=document.documentElement.lang;$("select.select2").select2({language:{"zh-Hans":"zh-CN","zh-Hant":"zh-TW"}[t]||t,width:"100%",escapeMarkup:function(e){return e}}),$("select.select2:not([multiple])").on("select2:unselect",(function(e){$(e.delegateTarget).html('<option value="" selected></option>')})),$.fn.dataTableExt.oSort["text-asc"]=function(e,t){return e.localeCompare(t,document.documentElement.lang,{sensitivity:"base"})},$.fn.dataTableExt.oSort["text-desc"]=function(e,t){return t.localeCompare(e,document.documentElement.lang,{sensitivity:"base"})},$("table.datatables").each((function(){$(this).DataTable(),$(this).removeClass("d-none")})),document.querySelectorAll("[data-wt-persist]").forEach((function(e){return webtrees.persistentToggle(e)})),$(".wt-osk-trigger").click((function(){(e=document.getElementById(this.dataset.wtId)).focus(),$(".wt-osk").show()})),$(".wt-osk-script-button").change((function(){$(".wt-osk-script").prop("hidden",!0),$(".wt-osk-script-"+this.dataset.wtOskScript).prop("hidden",!1)})),$(".wt-osk-shift-button").click((function(){document.querySelector(".wt-osk-keys").classList.toggle("shifted")})),$(".wt-osk-keys").on("click",".wt-osk-key",(function(){var t=$(this).contents().get(0).nodeValue,a=$(".wt-osk-shift-button").hasClass("active"),n=$("sup",this)[0];a&&void 0!==n&&(t=n.innerText),webtrees.pasteAtCursor(e,t),!1===$(".wt-osk-pin-button").hasClass("active")&&$(".wt-osk").hide(),e.dispatchEvent(new Event("input"))})),$(".wt-osk-close").on("click",(function(){$(".wt-osk").hide()})),$("input[type=password]").each((function(){$(this).hideShowPassword("infer",!0,{states:{shown:{toggle:{content:this.dataset.wtHidePasswordText,attr:{title:this.dataset.wtHidePasswordTitle,"aria-label":this.dataset.wtHidePasswordTitle}}},hidden:{toggle:{content:this.dataset.wtShowPasswordText,attr:{title:this.dataset.wtShowPasswordTitle,"aria-label":this.dataset.wtShowPasswordTitle}}}}})}))})),document.addEventListener("submit",(function(e){var t=e.target;t.reportValidity()&&t.addEventListener("submit",(function(e){t.classList.contains("form-is-submitting")&&e.preventDefault(),t.classList.add("form-is-submitting")}))})),document.addEventListener("click",(function(e){var t=e.target.closest("a,button");if(null!==t&&("wtConfirm"in t.dataset&&!confirm(t.dataset.wtConfirm)&&e.preventDefault(),"wtPostUrl"in t.dataset)){var a=document.querySelector("meta[name=csrf]").content;fetch(t.dataset.wtPostUrl,{method:"POST",headers:{"X-CSRF-TOKEN":a,"X-Requested-with":"XMLHttpRequest"}}).then((function(){"wtReloadUrl"in t.dataset?document.location=t.dataset.wtReloadUrl:document.location.reload()})).catch((function(e){alert(e)}))}}));var GOOGLE_CHARTS_LIB="https://www.gstatic.com/charts/loader.js",Statistics=function(){function e(){return _classCallCheck(this,e),e.instance||(e.instance=this,this.callbacks=[],this.initialized=!1,this.loading=!1),e.instance}return _createClass(e,[{key:"init",value:function(e){if(!this.loading&&!this.initialized){var t=this;Promise.all([this.load(GOOGLE_CHARTS_LIB)]).then((function(){google.charts.load("current",{packages:["corechart","geochart","bar"],language:e,mapsApiKey:""}),google.charts.setOnLoadCallback((function(){t.callbacks.forEach((function(e){e()}))})),t.initialized=!0})).catch((function(e){console.log(e)}))}}},{key:"load",value:function(e){if(!this.loading)return this.loading=!0,new Promise((function(t,a){var n=document.createElement("script");n.async=!0,n.onload=function(){t(e)},n.onerror=function(){a(e)},n.src=e,document.body.appendChild(n)}))}},{key:"addCallback",value:function(e){this.initialized?google.charts.setOnLoadCallback(e):this.callbacks.push(e),$(window).resize((function(){e()}))}},{key:"drawChart",value:function(e,t,a,n){var o=google.visualization.arrayToDataTable(a);new google.visualization.ChartWrapper({chartType:t,dataTable:o,options:n,containerId:e}).draw()}},{key:"drawPieChart",value:function(e,t,a){a=Object.assign({title:"",height:"100%",width:"100%",pieStartAngle:0,pieSliceText:"none",pieSliceTextStyle:{color:"#777"},pieHole:.4,legend:{alignment:"center",labeledValueText:"value",position:"labeled"},chartArea:{left:0,top:"5%",height:"90%",width:"100%"},tooltip:{trigger:"none",text:"both"},backgroundColor:"transparent",colors:[]},a),this.drawChart(e,"PieChart",t,a)}},{key:"drawColumnChart",value:function(e,t,a){a=Object.assign({title:"",subtitle:"",titleTextStyle:{color:"#757575",fontName:"Roboto",fontSize:"16px",bold:!1,italic:!1},height:"100%",width:"100%",vAxis:{title:""},hAxis:{title:""},legend:{position:"none"},backgroundColor:"transparent"},a),this.drawChart(e,"ColumnChart",t,a)}},{key:"drawComboChart",value:function(e,t,a){a=Object.assign({title:"",subtitle:"",titleTextStyle:{color:"#757575",fontName:"Roboto",fontSize:"16px",bold:!1,italic:!1},height:"100%",width:"100%",vAxis:{title:""},hAxis:{title:""},legend:{position:"none"},seriesType:"bars",series:{2:{type:"line"}},colors:[],backgroundColor:"transparent"},a),this.drawChart(e,"ComboChart",t,a)}},{key:"drawGeoChart",value:function(e,t,a){a=Object.assign({title:"",subtitle:"",height:"100%",width:"100%"},a),this.drawChart(e,"GeoChart",t,a)}}]),e}(),statistics=new Statistics;function TreeViewHandler(e,t){var a,n,o,r=this;this.treeview=$("#"+e+"_in"),this.loadingImage=$("#"+e+"_loading"),this.toolbox=$("#tv_tools"),this.buttons=$(".tv_button:first",this.toolbox),this.zoom=100,this.boxWidth=180,this.boxExpandedWidth=250,this.cookieDays=3,this.ajaxDetails=document.getElementById(e+"_out").dataset.urlDetails+"&instance="+encodeURIComponent(e),this.ajaxPersons=document.getElementById(e+"_out").dataset.urlIndividuals+"&instance="+encodeURIComponent(e),this.container=this.treeview.parent(),this.auto_box_width=!1,this.updating=!1,"true"===readCookie("compact")&&r.compact(),o=!1,r.treeview.on("mousedown touchstart",(function(e){e.preventDefault();var t="touchstart"===e.type?e.touches[0].pageX:e.pageX,i="touchstart"===e.type?e.touches[0].pageY:e.pageY;a=r.treeview.offset().left-t,n=r.treeview.offset().top-i,o=!0})),$(document).on("mousemove touchmove",(function(e){if(o){e.preventDefault();var t="touchmove"===e.type?e.touches[0].pageX:e.pageX,i="touchmove"===e.type?e.touches[0].pageY:e.pageY;r.treeview.offset({left:t+a,top:i+n})}})),$(document).on("mouseup touchend",(function(e){o&&(e.preventDefault(),o=!1,r.updateTree())})),r.toolbox.find("#tvbCompact").each((function(e,t){t.onclick=function(){r.compact()}})),r.toolbox.find("#tvbAllPartners").each((function(e,t){t.onclick=function(){createCookie("allPartners","true"===readCookie("allPartners")?"false":"true",r.cookieDays),document.location=document.location}})),r.toolbox.find("#tvbOpen").each((function(e,t){var a=$(t,r.toolbox);t.onclick=function(){a.addClass("tvPressed"),r.setLoading();var e=jQuery.Event("click");r.treeview.find(".tv_box:not(.boxExpanded)").each((function(t,a){var n=$(a,r.treeview).offset();n.left>=r.leftMin&&n.left<=r.leftMax&&n.top>=r.topMin&&n.top<=r.topMax&&r.expandBox(a,e)})),a.removeClass("tvPressed"),r.setComplete()}})),r.toolbox.find("#tvbClose").each((function(e,t){var a=$(t,r.toolbox);t.onclick=function(){a.addClass("tvPressed"),r.setLoading(),r.treeview.find(".tv_box.boxExpanded").each((function(e,t){$(t).css("display","none").removeClass("boxExpanded").parent().find(".tv_box.collapsedContent").css("display","block")})),a.removeClass("tvPressed"),r.setComplete()}})),r.centerOnRoot()}function createCookie(e,t,a){if(a){var n=new Date;n.setTime(n.getTime()+24*a*60*60*1e3),document.cookie=e+"="+t+"; expires="+n.toGMTString()+"; path=/"}else document.cookie=e+"="+t+"; path=/"}function readCookie(e){for(var t=e+"=",a=document.cookie.split(";"),n=0;n<a.length;n++){for(var o=a[n];" "===o.charAt(0);)o=o.substring(1,o.length);if(0===o.indexOf(t))return o.substring(t.length,o.length)}return null}TreeViewHandler.prototype.setLoading=function(){this.treeview.css("cursor","wait"),this.loadingImage.css("display","block")},TreeViewHandler.prototype.setComplete=function(){this.treeview.css("cursor","move"),this.loadingImage.css("display","none")},TreeViewHandler.prototype.getSize=function(){var e=this,t=e.container.parent(),a=t.offset();e.leftMin=a.left,e.leftMax=e.leftMin+t.innerWidth(),e.topMin=a.top,e.topMax=e.topMin+t.innerHeight()},TreeViewHandler.prototype.updateTree=function(e,t){var a=this,n=[],o=[];return this.getSize(),a.treeview.find("td[abbr]").each((function(e,t){var r=(t=$(t,a.treeview)).offset();r.left>=a.leftMin&&r.left<=a.leftMax&&r.top>=a.topMin&&r.top<=a.topMax&&(n.push(t.attr("abbr")),o.push(t))})),n.length>0?(a.updating=!0,a.setLoading(),jQuery.ajax({url:a.ajaxPersons,dataType:"json",data:"q="+n.join(";"),success:function(e){for(var t=o.length,n=($(".rootPerson",this.treeview).offset().left,0);n<t;n++)o[n].removeAttr("abbr").html(e[n]);a.getSize()},complete:function(){a.treeview.find("td[abbr]").length&&a.updateTree(e,t),a.auto_box_width&&a.treeview.find(".tv_box").css("width","auto"),a.updating=!0,e&&a.centerOnRoot(),t&&t.removeClass("tvPressed"),a.setComplete(),a.updating=!1},timeout:function(){t&&t.removeClass("tvPressed"),a.updating=!1,a.setComplete()}})):(t&&t.removeClass("tvPressed"),a.setComplete()),!1},TreeViewHandler.prototype.compact=function(){var e=this,t=$("#tvbCompact",e.toolbox);if(e.setLoading(),e.auto_box_width){var a=e.boxWidth*(e.zoom/100)+"px",n=e.boxExpandedWidth*(e.zoom/100)+"px";e.treeview.find(".tv_box:not(boxExpanded)",e.treeview).css("width",a),e.treeview.find(".boxExpanded",e.treeview).css("width",n),e.auto_box_width=!1,readCookie("compact")&&createCookie("compact",!1,e.cookieDays),t.removeClass("tvPressed")}else e.treeview.find(".tv_box").css("width","auto"),e.auto_box_width=!0,readCookie("compact")||createCookie("compact",!0,e.cookieDays),e.updating||e.updateTree(),t.addClass("tvPressed");return e.setComplete(),!1},TreeViewHandler.prototype.centerOnRoot=function(){this.loadingImage.css("display","block");var e=this.container,t=e.innerWidth()/2;if(Number.isNaN(t))return!1;e.innerHeight(),$(".rootPerson",this.treeview);return this.updating||this.setComplete(),!1},TreeViewHandler.prototype.expandBox=function(e,t){if($(t.target).hasClass("tv_link"))return!1;var a,n,o=(e=$(e,this.treeview)).parent(),r=e.attr("abbr"),i=this;if(o.hasClass("detailsLoaded"))n=o.find(".collapsedContent"),a=o.find(".tv_box:not(.collapsedContent)");else{a=e,n=e.clone(),o.append(n.addClass("collapsedContent").css("display","none"));var s=this.loadingImage.find("img").clone().addClass("tv_box_loading").css("display","block");e.prepend(s),i.updating=!0,i.setLoading(),e.load(i.ajaxDetails+"&pid="+encodeURIComponent(r),(function(){"function"==typeof CB_Init&&CB_Init(),e.css("width",i.boxExpandedWidth*(i.zoom/100)+"px"),s.remove(),o.addClass("detailsLoaded"),i.setComplete(),i.updating=!1}))}return e.hasClass("boxExpanded")?(a.css("display","none"),n.css("display","block"),e.removeClass("boxExpanded")):(a.css("display","block"),n.css("display","none"),a.addClass("boxExpanded")),this.getSize(),!1};
+/**
+ * webtrees: online genealogy
+ * Copyright (C) 2021 webtrees development team
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+'use strict';
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
+
+function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
+
+function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
+
+function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
+
+function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
+
+function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
+
+function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
+
+function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
+
+(function (webtrees) {
+ var lang = document.documentElement.lang; // Identify the script used by some text.
+
+ var scriptRegexes = {
+ Han: /[\u3400-\u9FCC]/,
+ Grek: /[\u0370-\u03FF]/,
+ Cyrl: /[\u0400-\u04FF]/,
+ Hebr: /[\u0590-\u05FF]/,
+ Arab: /[\u0600-\u06FF]/
+ };
+ /**
+ * Tidy the whitespace in a string.
+ * @param {string} str
+ * @returns {string}
+ */
+
+ function trim(str) {
+ return str.replace(/\s+/g, ' ').trim();
+ }
+ /**
+ * Look for non-latin characters in a string.
+ * @param {string} str
+ * @returns {string}
+ */
+
+
+ webtrees.detectScript = function (str) {
+ for (var script in scriptRegexes) {
+ if (str.match(scriptRegexes[script])) {
+ return script;
+ }
+ }
+
+ return 'Latn';
+ };
+ /**
+ * In some languages, the SURN uses a male/default form, but NAME uses a gender-inflected form.
+ * @param {string} surname
+ * @param {string} sex
+ * @returns {string}
+ */
+
+
+ function inflectSurname(surname, sex) {
+ if (lang === 'pl' && sex === 'F') {
+ return surname.replace(/ski$/, 'ska').replace(/cki$/, 'cka').replace(/dzki$/, 'dzka').replace(/żki$/, 'żka');
+ }
+
+ return surname;
+ }
+ /**
+ * Build a NAME from a NPFX, GIVN, SPFX, SURN and NSFX parts.
+ * Assumes the language of the document is the same as the language of the name.
+ * @param {string} npfx
+ * @param {string} givn
+ * @param {string} spfx
+ * @param {string} surn
+ * @param {string} nsfx
+ * @param {string} sex
+ * @returns {string}
+ */
+
+
+ webtrees.buildNameFromParts = function (npfx, givn, spfx, surn, nsfx, sex) {
+ var usesCJK = webtrees.detectScript(npfx + givn + spfx + givn + surn + nsfx) === 'Han';
+ var separator = usesCJK ? '' : ' ';
+ var surnameFirst = usesCJK || ['hu', 'jp', 'ko', 'vi', 'zh-Hans', 'zh-Hant'].indexOf(lang) !== -1;
+ var patronym = ['is'].indexOf(lang) !== -1;
+ var slash = patronym ? '' : '/'; // GIVN and SURN may be a comma-separated lists.
+
+ npfx = trim(npfx);
+ givn = trim(givn.replace(/,/g, separator));
+ spfx = trim(spfx);
+ surn = inflectSurname(trim(surn.replace(/,/g, separator)), sex);
+ nsfx = trim(nsfx);
+ var surname_separator = spfx.endsWith('\'') || spfx.endsWith('‘') ? '' : ' ';
+ var surname = trim(spfx + surname_separator + surn);
+ var name = surnameFirst ? slash + surname + slash + separator + givn : givn + separator + slash + surname + slash;
+ return trim(npfx + separator + name + separator + nsfx);
+ }; // Insert text at the current cursor position in a text field.
+
+
+ webtrees.pasteAtCursor = function (element, text) {
+ if (element !== null) {
+ var caret_pos = element.selectionStart + text.length;
+ var textBefore = element.value.substring(0, element.selectionStart);
+ var textAfter = element.value.substring(element.selectionEnd);
+ element.value = textBefore + text + textAfter;
+ element.setSelectionRange(caret_pos, caret_pos);
+ element.focus();
+ }
+ };
+ /**
+ * @param {Element} datefield
+ * @param {string} dmy
+ */
+
+
+ webtrees.reformatDate = function (datefield, dmy) {
+ var months = ['JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC'];
+ var hijri_months = ['MUHAR', 'SAFAR', 'RABIA', 'RABIT', 'JUMAA', 'JUMAT', 'RAJAB', 'SHAAB', 'RAMAD', 'SHAWW', 'DHUAQ', 'DHUAH'];
+ var hebrew_months = ['TSH', 'CSH', 'KSL', 'TVT', 'SHV', 'ADR', 'ADS', 'NSN', 'IYR', 'SVN', 'TMZ', 'AAV', 'ELL'];
+ var french_months = ['VEND', 'BRUM', 'FRIM', 'NIVO', 'PLUV', 'VENT', 'GERM', 'FLOR', 'PRAI', 'MESS', 'THER', 'FRUC', 'COMP'];
+ var jalali_months = ['FARVA', 'ORDIB', 'KHORD', 'TIR', 'MORDA', 'SHAHR', 'MEHR', 'ABAN', 'AZAR', 'DEY', 'BAHMA', 'ESFAN'];
+ var datestr = datefield.value; // if a date has a date phrase marked by () this has to be excluded from altering
+
+ var datearr = datestr.split('(');
+ var datephrase = '';
+
+ if (datearr.length > 1) {
+ datestr = datearr[0];
+ datephrase = datearr[1];
+ } // Gedcom dates are upper case
+
+
+ datestr = datestr.toUpperCase(); // Gedcom dates have no leading/trailing/repeated whitespace
+
+ datestr = datestr.replace(/\s+/g, ' ');
+ datestr = datestr.replace(/(^\s)|(\s$)/, ''); // Gedcom dates have spaces between letters and digits, e.g. "01JAN2000" => "01 JAN 2000"
+
+ datestr = datestr.replace(/(\d)([A-Z])/g, '$1 $2');
+ datestr = datestr.replace(/([A-Z])(\d)/g, '$1 $2'); // Shortcut for quarter format, "Q1 1900" => "BET JAN 1900 AND MAR 1900".
+
+ if (datestr.match(/^Q ([1-4]) (\d\d\d\d)$/)) {
+ datestr = 'BET ' + months[RegExp.$1 * 3 - 3] + ' ' + RegExp.$2 + ' AND ' + months[RegExp.$1 * 3 - 1] + ' ' + RegExp.$2;
+ } // Shortcut for @#Dxxxxx@ 01 01 1400, etc.
+
+
+ if (datestr.match(/^(@#DHIJRI@|HIJRI)( \d?\d )(\d?\d)( \d?\d?\d?\d)$/)) {
+ datestr = '@#DHIJRI@' + RegExp.$2 + hijri_months[parseInt(RegExp.$3, 10) - 1] + RegExp.$4;
+ }
+
+ if (datestr.match(/^(@#DJALALI@|JALALI)( \d?\d )(\d?\d)( \d?\d?\d?\d)$/)) {
+ datestr = '@#DJALALI@' + RegExp.$2 + jalali_months[parseInt(RegExp.$3, 10) - 1] + RegExp.$4;
+ }
+
+ if (datestr.match(/^(@#DHEBREW@|HEBREW)( \d?\d )(\d?\d)( \d?\d?\d?\d)$/)) {
+ datestr = '@#DHEBREW@' + RegExp.$2 + hebrew_months[parseInt(RegExp.$3, 10) - 1] + RegExp.$4;
+ }
+
+ if (datestr.match(/^(@#DFRENCH R@|FRENCH)( \d?\d )(\d?\d)( \d?\d?\d?\d)$/)) {
+ datestr = '@#DFRENCH R@' + RegExp.$2 + french_months[parseInt(RegExp.$3, 10) - 1] + RegExp.$4;
+ } // All digit dates
+
+
+ datestr = datestr.replace(/(\d\d)(\d\d)(\d\d)(\d\d)/g, function () {
+ if (RegExp.$1 > '12' && RegExp.$3 <= '12' && RegExp.$4 <= '31') {
+ return RegExp.$4 + ' ' + months[RegExp.$3 - 1] + ' ' + RegExp.$1 + RegExp.$2;
+ }
+
+ if (RegExp.$1 <= '31' && RegExp.$2 <= '12' && RegExp.$3 > '12') {
+ return RegExp.$1 + ' ' + months[RegExp.$2 - 1] + ' ' + RegExp.$3 + RegExp.$4;
+ }
+
+ return RegExp.$1 + RegExp.$2 + RegExp.$3 + RegExp.$4;
+ }); // e.g. 17.11.1860, 2 4 1987, 3/4/2005, 1999-12-31. Use locale settings since DMY order is ambiguous.
+
+ datestr = datestr.replace(/(\d+)([ ./-])(\d+)(\2)(\d+)/g, function () {
+ var f1 = parseInt(RegExp.$1, 10);
+ var f2 = parseInt(RegExp.$3, 10);
+ var f3 = parseInt(RegExp.$5, 10);
+ var yyyy = new Date().getFullYear();
+ var yy = yyyy % 100;
+ var cc = yyyy - yy;
+
+ if ((dmy === 'DMY' || f1 > 13 && f3 > 31) && f1 <= 31 && f2 <= 12) {
+ return f1 + ' ' + months[f2 - 1] + ' ' + (f3 >= 100 ? f3 : f3 <= yy ? f3 + cc : f3 + cc - 100);
+ }
+
+ if ((dmy === 'MDY' || f2 > 13 && f3 > 31) && f1 <= 12 && f2 <= 31) {
+ return f2 + ' ' + months[f1 - 1] + ' ' + (f3 >= 100 ? f3 : f3 <= yy ? f3 + cc : f3 + cc - 100);
+ }
+
+ if ((dmy === 'YMD' || f1 > 31) && f2 <= 12 && f3 <= 31) {
+ return f3 + ' ' + months[f2 - 1] + ' ' + (f1 >= 100 ? f1 : f1 <= yy ? f1 + cc : f1 + cc - 100);
+ }
+
+ return RegExp.$1 + RegExp.$2 + RegExp.$3 + RegExp.$4 + RegExp.$5;
+ });
+ datestr = datestr // Shortcuts for date ranges
+ .replace(/^[>]([\w ]+)$/, 'AFT $1').replace(/^[<]([\w ]+)$/, 'BEF $1').replace(/^([\w ]+)[-]$/, 'FROM $1').replace(/^[-]([\w ]+)$/, 'TO $1').replace(/^[~]([\w ]+)$/, 'ABT $1').replace(/^[*]([\w ]+)$/, 'EST $1').replace(/^[#]([\w ]+)$/, 'CAL $1').replace(/^([\w ]+) ?- ?([\w ]+)$/, 'BET $1 AND $2').replace(/^([\w ]+) ?~ ?([\w ]+)$/, 'FROM $1 TO $2') // Convert full months to short months
+ .replace(/JANUARY/g, 'JAN').replace(/FEBRUARY/g, 'FEB').replace(/MARCH/g, 'MAR').replace(/APRIL/g, 'APR').replace(/JUNE/g, 'JUN').replace(/JULY/g, 'JUL').replace(/AUGUST/g, 'AUG').replace(/SEPTEMBER/g, 'SEP').replace(/OCTOBER/, 'OCT').replace(/NOVEMBER/g, 'NOV').replace(/DECEMBER/g, 'DEC') // Americans enter dates as SEP 20, 1999
+ .replace(/(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)\.? (\d\d?)[, ]+(\d\d\d\d)/g, '$2 $1 $3') // Apply leading zero to day numbers
+ .replace(/(^| )(\d [A-Z]{3,5} \d{4})/g, '$10$2');
+
+ if (datephrase) {
+ datestr = datestr + ' (' + datephrase;
+ } // Only update it if is has been corrected - otherwise input focus
+ // moves to the end of the field unnecessarily
+
+
+ if (datefield.value !== datestr) {
+ datefield.value = datestr;
+ }
+ };
+
+ var monthLabels = [];
+ monthLabels[1] = 'January';
+ monthLabels[2] = 'February';
+ monthLabels[3] = 'March';
+ monthLabels[4] = 'April';
+ monthLabels[5] = 'May';
+ monthLabels[6] = 'June';
+ monthLabels[7] = 'July';
+ monthLabels[8] = 'August';
+ monthLabels[9] = 'September';
+ monthLabels[10] = 'October';
+ monthLabels[11] = 'November';
+ monthLabels[12] = 'December';
+ var monthShort = [];
+ monthShort[1] = 'JAN';
+ monthShort[2] = 'FEB';
+ monthShort[3] = 'MAR';
+ monthShort[4] = 'APR';
+ monthShort[5] = 'MAY';
+ monthShort[6] = 'JUN';
+ monthShort[7] = 'JUL';
+ monthShort[8] = 'AUG';
+ monthShort[9] = 'SEP';
+ monthShort[10] = 'OCT';
+ monthShort[11] = 'NOV';
+ monthShort[12] = 'DEC';
+ var daysOfWeek = [];
+ daysOfWeek[0] = 'S';
+ daysOfWeek[1] = 'M';
+ daysOfWeek[2] = 'T';
+ daysOfWeek[3] = 'W';
+ daysOfWeek[4] = 'T';
+ daysOfWeek[5] = 'F';
+ daysOfWeek[6] = 'S';
+ var weekStart = 0;
+ /**
+ * @param {string} jan
+ * @param {string} feb
+ * @param {string} mar
+ * @param {string} apr
+ * @param {string} may
+ * @param {string} jun
+ * @param {string} jul
+ * @param {string} aug
+ * @param {string} sep
+ * @param {string} oct
+ * @param {string} nov
+ * @param {string} dec
+ * @param {string} sun
+ * @param {string} mon
+ * @param {string} tue
+ * @param {string} wed
+ * @param {string} thu
+ * @param {string} fri
+ * @param {string} sat
+ * @param {number} day
+ */
+
+ webtrees.calLocalize = function (jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec, sun, mon, tue, wed, thu, fri, sat, day) {
+ monthLabels[1] = jan;
+ monthLabels[2] = feb;
+ monthLabels[3] = mar;
+ monthLabels[4] = apr;
+ monthLabels[5] = may;
+ monthLabels[6] = jun;
+ monthLabels[7] = jul;
+ monthLabels[8] = aug;
+ monthLabels[9] = sep;
+ monthLabels[10] = oct;
+ monthLabels[11] = nov;
+ monthLabels[12] = dec;
+ daysOfWeek[0] = sun;
+ daysOfWeek[1] = mon;
+ daysOfWeek[2] = tue;
+ daysOfWeek[3] = wed;
+ daysOfWeek[4] = thu;
+ daysOfWeek[5] = fri;
+ daysOfWeek[6] = sat;
+
+ if (day >= 0 && day < 7) {
+ weekStart = day;
+ }
+ };
+ /**
+ * @param {string} dateDivId
+ * @param {string} dateFieldId
+ * @returns {boolean}
+ */
+
+
+ webtrees.calendarWidget = function (dateDivId, dateFieldId) {
+ var dateDiv = document.getElementById(dateDivId);
+ var dateField = document.getElementById(dateFieldId);
+
+ if (dateDiv.style.visibility === 'visible') {
+ dateDiv.style.visibility = 'hidden';
+ return false;
+ }
+
+ if (dateDiv.style.visibility === 'show') {
+ dateDiv.style.visibility = 'hide';
+ return false;
+ }
+ /* Javascript calendar functions only work with precise gregorian dates "D M Y" or "Y" */
+
+
+ var greg_regex = /(?:(\d*) ?(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC) )?(\d+)/i;
+ var date;
+
+ if (greg_regex.exec(dateField.value)) {
+ var day = RegExp.$1 || '1';
+ var month = RegExp.$2 || 'JAN';
+ var year = RegExp.$3;
+ date = new Date(day + ' ' + month + ' ' + year);
+ } else {
+ date = new Date();
+ }
+
+ dateDiv.innerHTML = calGenerateSelectorContent(dateFieldId, dateDivId, date);
+
+ if (dateDiv.style.visibility === 'hidden') {
+ dateDiv.style.visibility = 'visible';
+ return false;
+ }
+
+ if (dateDiv.style.visibility === 'hide') {
+ dateDiv.style.visibility = 'show';
+ return false;
+ }
+
+ return false;
+ };
+ /**
+ * @param {string} dateFieldId
+ * @param {string} dateDivId
+ * @param {Date} date
+ * @returns {string}
+ */
+
+
+ function calGenerateSelectorContent(dateFieldId, dateDivId, date) {
+ var i, j;
+ var content = '<table border="1"><tr>';
+ content += '<td><select class="form-control" id="' + dateFieldId + '_daySelect" onchange="return webtrees.calUpdateCalendar(\'' + dateFieldId + '\', \'' + dateDivId + '\');">';
+
+ for (i = 1; i < 32; i++) {
+ content += '<option value="' + i + '"';
+
+ if (date.getDate() === i) {
+ content += ' selected="selected"';
+ }
+
+ content += '>' + i + '</option>';
+ }
+
+ content += '</select></td>';
+ content += '<td><select class="form-control" id="' + dateFieldId + '_monSelect" onchange="return webtrees.calUpdateCalendar(\'' + dateFieldId + '\', \'' + dateDivId + '\');">';
+
+ for (i = 1; i < 13; i++) {
+ content += '<option value="' + i + '"';
+
+ if (date.getMonth() + 1 === i) {
+ content += ' selected="selected"';
+ }
+
+ content += '>' + monthLabels[i] + '</option>';
+ }
+
+ content += '</select></td>';
+ content += '<td><input class="form-control" type="text" id="' + dateFieldId + '_yearInput" size="5" value="' + date.getFullYear() + '" onchange="return webtrees.calUpdateCalendar(\'' + dateFieldId + '\', \'' + dateDivId + '\');" /></td></tr>';
+ content += '<tr><td colspan="3">';
+ content += '<table width="100%">';
+ content += '<tr>';
+ j = weekStart;
+
+ for (i = 0; i < 7; i++) {
+ content += '<td ';
+ content += 'class="descriptionbox"';
+ content += '>';
+ content += daysOfWeek[j];
+ content += '</td>';
+ j++;
+
+ if (j > 6) {
+ j = 0;
+ }
+ }
+
+ content += '</tr>';
+ var tdate = new Date(date.getFullYear(), date.getMonth(), 1);
+ var day = tdate.getDay();
+ day = day - weekStart;
+ var daymilli = 1000 * 60 * 60 * 24;
+ tdate = tdate.getTime() - day * daymilli + daymilli / 2;
+ tdate = new Date(tdate);
+
+ for (j = 0; j < 6; j++) {
+ content += '<tr>';
+
+ for (i = 0; i < 7; i++) {
+ content += '<td ';
+
+ if (tdate.getMonth() === date.getMonth()) {
+ if (tdate.getDate() === date.getDate()) {
+ content += 'class="descriptionbox"';
+ } else {
+ content += 'class="optionbox"';
+ }
+ } else {
+ content += 'style="background-color:#EAEAEA; border: solid #AAAAAA 1px;"';
+ }
+
+ content += '><a href="#" onclick="return webtrees.calDateClicked(\'' + dateFieldId + '\', \'' + dateDivId + '\', ' + tdate.getFullYear() + ', ' + tdate.getMonth() + ', ' + tdate.getDate() + ');">';
+ content += tdate.getDate();
+ content += '</a></td>';
+ var datemilli = tdate.getTime() + daymilli;
+ tdate = new Date(datemilli);
+ }
+
+ content += '</tr>';
+ }
+
+ content += '</table>';
+ content += '</td></tr>';
+ content += '</table>';
+ return content;
+ }
+ /**
+ * @param {string} dateFieldId
+ * @param {number} year
+ * @param {number} month
+ * @param {number} day
+ * @returns {boolean}
+ */
+
+
+ function calSetDateField(dateFieldId, year, month, day) {
+ var dateField = document.getElementById(dateFieldId);
+ dateField.value = (day < 10 ? '0' : '') + day + ' ' + monthShort[month + 1] + ' ' + year;
+ return false;
+ }
+ /**
+ * @param {string} dateFieldId
+ * @param {string} dateDivId
+ * @returns {boolean}
+ */
+
+
+ webtrees.calUpdateCalendar = function (dateFieldId, dateDivId) {
+ var dateSel = document.getElementById(dateFieldId + '_daySelect');
+
+ if (!dateSel) {
+ return false;
+ }
+
+ var monthSel = document.getElementById(dateFieldId + '_monSelect');
+
+ if (!monthSel) {
+ return false;
+ }
+
+ var yearInput = document.getElementById(dateFieldId + '_yearInput');
+
+ if (!yearInput) {
+ return false;
+ }
+
+ var month = parseInt(monthSel.options[monthSel.selectedIndex].value, 10);
+ month = month - 1;
+ var date = new Date(yearInput.value, month, dateSel.options[dateSel.selectedIndex].value);
+ calSetDateField(dateFieldId, date.getFullYear(), date.getMonth(), date.getDate());
+ var dateDiv = document.getElementById(dateDivId);
+
+ if (!dateDiv) {
+ alert('no dateDiv ' + dateDivId);
+ return false;
+ }
+
+ dateDiv.innerHTML = calGenerateSelectorContent(dateFieldId, dateDivId, date);
+ return false;
+ };
+ /**
+ * @param {string} dateFieldId
+ * @param {string} dateDivId
+ * @param {number} year
+ * @param {number} month
+ * @param {number} day
+ * @returns {boolean}
+ */
+
+
+ webtrees.calDateClicked = function (dateFieldId, dateDivId, year, month, day) {
+ calSetDateField(dateFieldId, year, month, day);
+ webtrees.calendarWidget(dateDivId, dateFieldId);
+ return false;
+ };
+ /**
+ * Persistent checkbox options to hide/show extra data.
+ * @param {HTMLInputElement} element
+ */
+
+
+ webtrees.persistentToggle = function (element) {
+ if (element instanceof HTMLInputElement && element.type === 'checkbox') {
+ var key = 'state-of-' + element.dataset.wtPersist;
+ var state = localStorage.getItem(key); // Previously selected? Select again now.
+
+ if (state === 'true') {
+ element.click();
+ } // Remember state for the next page load.
+
+
+ element.addEventListener('change', function () {
+ localStorage.setItem(key, element.checked.toString());
+ });
+ }
+ };
+ /**
+ * @param {Element} field
+ * @param {string} pos
+ * @param {string} neg
+ */
+
+
+ function reformatLatLong(field, pos, neg) {
+ // valid LATI or LONG according to Gedcom standard
+ // pos (+) : N or E
+ // neg (-) : S or W
+ var txt = field.value.toUpperCase();
+ txt = txt.replace(/(^\s*)|(\s*$)/g, ''); // trim
+
+ txt = txt.replace(/ /g, ':'); // N12 34 ==> N12.34
+
+ txt = txt.replace(/\+/g, ''); // +17.1234 ==> 17.1234
+
+ txt = txt.replace(/-/g, neg); // -0.5698 ==> W0.5698
+
+ txt = txt.replace(/,/g, '.'); // 0,5698 ==> 0.5698
+ // 0°34'11 ==> 0:34:11
+
+ txt = txt.replace(/\u00b0/g, ':'); // °
+
+ txt = txt.replace(/\u0027/g, ':'); // '
+ // 0:34:11.2W ==> W0.5698
+
+ txt = txt.replace(/^([0-9]+):([0-9]+):([0-9.]+)(.*)/g, function ($0, $1, $2, $3, $4) {
+ var n = parseFloat($1);
+ n += $2 / 60;
+ n += $3 / 3600;
+ n = Math.round(n * 1E4) / 1E4;
+ return $4 + n;
+ }); // 0:34W ==> W0.5667
+
+ txt = txt.replace(/^([0-9]+):([0-9]+)(.*)/g, function ($0, $1, $2, $3) {
+ var n = parseFloat($1);
+ n += $2 / 60;
+ n = Math.round(n * 1E4) / 1E4;
+ return $3 + n;
+ }); // 0.5698W ==> W0.5698
+
+ txt = txt.replace(/(.*)(NSEW])$/g, '$2$1'); // 17.1234 ==> N17.1234
+
+ if (txt && txt.charAt(0) !== neg && txt.charAt(0) !== pos) {
+ txt = pos + txt;
+ }
+
+ field.value = txt;
+ }
+ /**
+ * @param {Element} field
+ */
+
+
+ webtrees.reformatLatitude = function (field) {
+ return reformatLatLong(field, 'N', 'S');
+ };
+ /**
+ * @param {Element} field
+ */
+
+
+ webtrees.reformatLongitude = function (field) {
+ return reformatLatLong(field, 'E', 'W');
+ };
+ /**
+ * Initialize autocomplete elements.
+ * @param {string} selector
+ */
+
+
+ webtrees.autocomplete = function (selector) {
+ // Use typeahead/bloodhound for autocomplete
+ $(selector).each(function () {
+ var that = this;
+ $(this).typeahead(null, {
+ display: 'value',
+ limit: 10,
+ minLength: 2,
+ source: new Bloodhound({
+ datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
+ queryTokenizer: Bloodhound.tokenizers.whitespace,
+ remote: {
+ url: this.dataset.wtAutocompleteUrl,
+ replace: function replace(url, uriEncodedQuery) {
+ var symbol = url.indexOf("?") > 0 ? '&' : '?';
+
+ if (that.dataset.wtAutocompleteExtra === 'SOUR') {
+ var row_group = that.closest('.form-group').previousElementSibling;
+
+ while (row_group.querySelector('select') === null) {
+ row_group = row_group.previousElementSibling;
+ }
+
+ var element = row_group.querySelector('select');
+ var extra = element.options[element.selectedIndex].value.replace(/@/g, '');
+ return url + symbol + "query=" + uriEncodedQuery + '&extra=' + encodeURIComponent(extra);
+ }
+
+ return url + symbol + "query=" + uriEncodedQuery;
+ }
+ }
+ })
+ });
+ });
+ };
+ /**
+ * Create a LeafletJS map from a list of providers/layers.
+ * @param {string} id
+ * @param {object} config
+ * @returns Map
+ */
+
+
+ webtrees.buildLeafletJsMap = function (id, config) {
+ var zoomControl = new L.control.zoom({
+ zoomInTitle: config.i18n.zoomIn,
+ zoomoutTitle: config.i18n.zoomOut
+ });
+ var defaultLayer = null;
+
+ for (var _i = 0, _Object$entries = Object.entries(config.mapProviders); _i < _Object$entries.length; _i++) {
+ var _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2),
+ provider = _Object$entries$_i[1];
+
+ for (var _i2 = 0, _Object$entries2 = Object.entries(provider.children); _i2 < _Object$entries2.length; _i2++) {
+ var _Object$entries2$_i = _slicedToArray(_Object$entries2[_i2], 2),
+ child = _Object$entries2$_i[1];
+
+ if ('bingMapsKey' in child) {
+ child.layer = L.tileLayer.bing(child);
+ } else {
+ child.layer = L.tileLayer(child.url, child);
+ }
+
+ if (provider["default"] && child["default"]) {
+ defaultLayer = child.layer;
+ }
+ }
+ }
+
+ if (defaultLayer === null) {
+ console.log('No default map layer defined - using the first one.');
+ var _defaultLayer = config.mapProviders[0].children[0].layer;
+ } // Create the map with all controls and layers
+
+
+ return L.map(id, {
+ zoomControl: false
+ }).addControl(zoomControl).addLayer(defaultLayer).addControl(L.control.layers.tree(config.mapProviders, null, {
+ closedSymbol: config.icons.expand,
+ openedSymbol: config.icons.collapse
+ }));
+ };
+})(window.webtrees = window.webtrees || {}); // Send the CSRF token on all AJAX requests
+
+
+$.ajaxSetup({
+ headers: {
+ 'X-CSRF-TOKEN': $('meta[name=csrf]').attr('content')
+ }
+});
+/**
+ * Initialisation
+ */
+
+$(function () {
+ // Page elements that load automatically via AJAX.
+ // This prevents bad robots from crawling resource-intensive pages.
+ $('[data-wt-ajax-url]').each(function () {
+ $(this).load(this.dataset.wtAjaxUrl);
+ }); // Autocomplete
+
+ webtrees.autocomplete('input[data-wt-autocomplete-url]'); // Select2 - activate autocomplete fields
+
+ var lang = document.documentElement.lang;
+ var select2_languages = {
+ 'zh-Hans': 'zh-CN',
+ 'zh-Hant': 'zh-TW'
+ };
+ $('select.select2').select2({
+ language: select2_languages[lang] || lang,
+ // Needed for elements that are initially hidden.
+ width: '100%',
+ // Do not escape - we do it on the server.
+ escapeMarkup: function escapeMarkup(x) {
+ return x;
+ }
+ }); // If we clear the select (using the "X" button), we need an empty value
+ // (rather than no value at all) for (non-multiple) selects with name="array[]"
+
+ $('select.select2:not([multiple])').on('select2:unselect', function (evt) {
+ $(evt.delegateTarget).html('<option value="" selected></option>');
+ }); // Datatables - locale aware sorting
+
+ $.fn.dataTableExt.oSort['text-asc'] = function (x, y) {
+ return x.localeCompare(y, document.documentElement.lang, {
+ sensitivity: 'base'
+ });
+ };
+
+ $.fn.dataTableExt.oSort['text-desc'] = function (x, y) {
+ return y.localeCompare(x, document.documentElement.lang, {
+ sensitivity: 'base'
+ });
+ }; // DataTables - start hidden to prevent FOUC.
+
+
+ $('table.datatables').each(function () {
+ $(this).DataTable();
+ $(this).removeClass('d-none');
+ }); // Save button/checkbox state between pages
+
+ document.querySelectorAll('[data-wt-persist]').forEach(function (element) {
+ return webtrees.persistentToggle(element);
+ }); // Activate the on-screen keyboard
+
+ var osk_focus_element;
+ $('.wt-osk-trigger').click(function () {
+ // When a user clicks the icon, set focus to the corresponding input
+ osk_focus_element = document.getElementById(this.dataset.wtId);
+ osk_focus_element.focus();
+ $('.wt-osk').show();
+ });
+ $('.wt-osk-script-button').change(function () {
+ $('.wt-osk-script').prop('hidden', true);
+ $('.wt-osk-script-' + this.dataset.wtOskScript).prop('hidden', false);
+ });
+ $('.wt-osk-shift-button').click(function () {
+ document.querySelector('.wt-osk-keys').classList.toggle('shifted');
+ });
+ $('.wt-osk-keys').on('click', '.wt-osk-key', function () {
+ var key = $(this).contents().get(0).nodeValue;
+ var shift_state = $('.wt-osk-shift-button').hasClass('active');
+ var shift_key = $('sup', this)[0];
+
+ if (shift_state && shift_key !== undefined) {
+ key = shift_key.innerText;
+ }
+
+ webtrees.pasteAtCursor(osk_focus_element, key);
+
+ if ($('.wt-osk-pin-button').hasClass('active') === false) {
+ $('.wt-osk').hide();
+ }
+
+ osk_focus_element.dispatchEvent(new Event('input'));
+ });
+ $('.wt-osk-close').on('click', function () {
+ $('.wt-osk').hide();
+ }); // Hide/Show password fields
+
+ $('input[type=password]').each(function () {
+ $(this).hideShowPassword('infer', true, {
+ states: {
+ shown: {
+ toggle: {
+ content: this.dataset.wtHidePasswordText,
+ attr: {
+ title: this.dataset.wtHidePasswordTitle,
+ 'aria-label': this.dataset.wtHidePasswordTitle
+ }
+ }
+ },
+ hidden: {
+ toggle: {
+ content: this.dataset.wtShowPasswordText,
+ attr: {
+ title: this.dataset.wtShowPasswordTitle,
+ 'aria-label': this.dataset.wtShowPasswordTitle
+ }
+ }
+ }
+ }
+ });
+ });
+}); // Prevent form re-submission via accidental double-click.
+
+document.addEventListener('submit', function (event) {
+ var form = event.target;
+
+ if (form.reportValidity()) {
+ form.addEventListener('submit', function (event) {
+ if (form.classList.contains('form-is-submitting')) {
+ event.preventDefault();
+ }
+
+ form.classList.add('form-is-submitting');
+ });
+ }
+}); // Convert data-wt-confirm and data-wt-post-url/data-wt-reload-url attributes into useful behavior.
+
+document.addEventListener('click', function (event) {
+ var target = event.target.closest('a,button');
+
+ if (target === null) {
+ return;
+ }
+
+ if ('wtConfirm' in target.dataset && !confirm(target.dataset.wtConfirm)) {
+ event.preventDefault();
+ }
+
+ if ('wtPostUrl' in target.dataset) {
+ var token = document.querySelector('meta[name=csrf]').content;
+ fetch(target.dataset.wtPostUrl, {
+ method: 'POST',
+ headers: {
+ 'X-CSRF-TOKEN': token,
+ 'X-Requested-with': 'XMLHttpRequest'
+ }
+ }).then(function () {
+ if ('wtReloadUrl' in target.dataset) {
+ // Go somewhere else. e.g. the home page after logout.
+ document.location = target.dataset.wtReloadUrl;
+ } else {
+ // Reload the current page. e.g. change language.
+ document.location.reload();
+ }
+ })["catch"](function (error) {
+ alert(error);
+ });
+ }
+});
+/**
+ * webtrees: online genealogy
+ * Copyright (C) 2021 webtrees development team
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+'use strict';
+
+var GOOGLE_CHARTS_LIB = 'https://www.gstatic.com/charts/loader.js';
+/**
+ * Statistics class.
+ */
+
+var Statistics = /*#__PURE__*/function () {
+ /**
+ * Constructor.
+ *
+ * @returns {Statistics}
+ */
+ function Statistics() {
+ _classCallCheck(this, Statistics);
+
+ // Create singleton instance
+ if (!Statistics.instance) {
+ Statistics.instance = this;
+ this.callbacks = [];
+ this.initialized = false;
+ this.loading = false;
+ }
+
+ return Statistics.instance;
+ }
+ /**
+ * Initializes the google chart engine. Loads the chart lib only once.
+ *
+ * @param {String} locale - Locale, e.g. en, de, ...
+ */
+
+
+ _createClass(Statistics, [{
+ key: "init",
+ value: function init(locale) {
+ if (this.loading || this.initialized) {
+ return;
+ }
+
+ var that = this;
+ Promise.all([this.load(GOOGLE_CHARTS_LIB)]).then(function () {
+ google.charts.load('current', {
+ packages: ['corechart', 'geochart', 'bar'],
+ language: locale,
+ // Note: you will need to get a mapsApiKey for your project.
+ // See: https://developers.google.com/chart/interactive/docs/basic_load_libs#load-settings
+ mapsApiKey: ''
+ });
+ google.charts.setOnLoadCallback(function () {
+ that.callbacks.forEach(function (element) {
+ element();
+ });
+ });
+ that.initialized = true;
+ })["catch"](function (error) {
+ console.log(error);
+ });
+ }
+ /**
+ * Dynamically loads a script by the given URL.
+ *
+ * @param {String} url
+ * @returns {Promise}
+ */
+
+ }, {
+ key: "load",
+ value: function load(url) {
+ if (this.loading) {
+ return;
+ }
+
+ this.loading = true;
+ return new Promise(function (resolve, reject) {
+ var script = document.createElement('script');
+ script.async = true;
+
+ script.onload = function () {
+ resolve(url);
+ };
+
+ script.onerror = function () {
+ reject(url);
+ };
+
+ script.src = url;
+ document.body.appendChild(script);
+ });
+ }
+ /**
+ * Adds the given callback method to the callback stack or add it directly to
+ * the google charts interface once the chart engine is up and running.
+ *
+ * @param {Function} callback
+ */
+
+ }, {
+ key: "addCallback",
+ value: function addCallback(callback) {
+ if (this.initialized) {
+ google.charts.setOnLoadCallback(callback);
+ } else {
+ this.callbacks.push(callback);
+ }
+
+ $(window).resize(function () {
+ callback();
+ });
+ }
+ /**
+ * Draws a google chart.
+ *
+ * @param {String} containerId
+ * @param {String} chartType
+ * @param {Array} data
+ * @param {Object} options
+ */
+
+ }, {
+ key: "drawChart",
+ value: function drawChart(containerId, chartType, data, options) {
+ var dataTable = google.visualization.arrayToDataTable(data);
+ var wrapper = new google.visualization.ChartWrapper({
+ chartType: chartType,
+ dataTable: dataTable,
+ options: options,
+ containerId: containerId
+ });
+ wrapper.draw();
+ }
+ /**
+ * Draws a pie chart.
+ *
+ * @param {String} elementId - The element id of the HTML element the chart is rendered too
+ * @param {Array} data - The chart data array
+ * @param {Object} options - The chart specific options to overwrite the default ones
+ */
+
+ }, {
+ key: "drawPieChart",
+ value: function drawPieChart(elementId, data, options) {
+ // Default chart options
+ var defaults = {
+ title: '',
+ height: '100%',
+ width: '100%',
+ pieStartAngle: 0,
+ pieSliceText: 'none',
+ pieSliceTextStyle: {
+ color: '#777'
+ },
+ pieHole: 0.4,
+ // Donut
+ // is3D: true, // 3D (not together with pieHole)
+ legend: {
+ alignment: 'center',
+ // Flickers on mouseover :(
+ labeledValueText: 'value',
+ position: 'labeled'
+ },
+ chartArea: {
+ left: 0,
+ top: '5%',
+ height: '90%',
+ width: '100%'
+ },
+ tooltip: {
+ trigger: 'none',
+ text: 'both'
+ },
+ backgroundColor: 'transparent',
+ colors: []
+ }; // Merge default with provided options
+
+ options = Object.assign(defaults, options); // Create and draw the chart
+
+ this.drawChart(elementId, 'PieChart', data, options);
+ }
+ /**
+ * Draws a column chart.
+ *
+ * @param {String} elementId - The element id of the HTML element the chart is rendered too
+ * @param {Array} data - The chart data array
+ * @param {Object} options - The chart specific options to overwrite the default ones
+ */
+
+ }, {
+ key: "drawColumnChart",
+ value: function drawColumnChart(elementId, data, options) {
+ // Default chart options
+ var defaults = {
+ title: '',
+ subtitle: '',
+ titleTextStyle: {
+ color: '#757575',
+ fontName: 'Roboto',
+ fontSize: '16px',
+ bold: false,
+ italic: false
+ },
+ height: '100%',
+ width: '100%',
+ vAxis: {
+ title: ''
+ },
+ hAxis: {
+ title: ''
+ },
+ legend: {
+ position: 'none'
+ },
+ backgroundColor: 'transparent'
+ }; // Merge default with provided options
+
+ options = Object.assign(defaults, options); // Create and draw the chart
+
+ this.drawChart(elementId, 'ColumnChart', data, options);
+ }
+ /**
+ * Draws a combo chart.
+ *
+ * @param {String} elementId - The element id of the HTML element the chart is rendered too
+ * @param {Array} data - The chart data array
+ * @param {Object} options - The chart specific options to overwrite the default ones
+ */
+
+ }, {
+ key: "drawComboChart",
+ value: function drawComboChart(elementId, data, options) {
+ // Default chart options
+ var defaults = {
+ title: '',
+ subtitle: '',
+ titleTextStyle: {
+ color: '#757575',
+ fontName: 'Roboto',
+ fontSize: '16px',
+ bold: false,
+ italic: false
+ },
+ height: '100%',
+ width: '100%',
+ vAxis: {
+ title: ''
+ },
+ hAxis: {
+ title: ''
+ },
+ legend: {
+ position: 'none'
+ },
+ seriesType: 'bars',
+ series: {
+ 2: {
+ type: 'line'
+ }
+ },
+ colors: [],
+ backgroundColor: 'transparent'
+ }; // Merge default with provided options
+
+ options = Object.assign(defaults, options); // Create and draw the chart
+
+ this.drawChart(elementId, 'ComboChart', data, options);
+ }
+ /**
+ * Draws a geo chart.
+ *
+ * @param {String} elementId - The element id of the HTML element the chart is rendered too
+ * @param {Array} data - The chart data array
+ * @param {Object} options - The chart specific options to overwrite the default ones
+ */
+
+ }, {
+ key: "drawGeoChart",
+ value: function drawGeoChart(elementId, data, options) {
+ // Default chart options
+ var defaults = {
+ title: '',
+ subtitle: '',
+ height: '100%',
+ width: '100%'
+ }; // Merge default with provided options
+
+ options = Object.assign(defaults, options); // Create and draw the chart
+
+ this.drawChart(elementId, 'GeoChart', data, options);
+ }
+ }]);
+
+ return Statistics;
+}(); // Create singleton instance of class
+
+
+var statistics = new Statistics();
+/**
+ * webtrees: online genealogy
+ * Copyright (C) 2021 webtrees development team
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+function TreeViewHandler(treeview_instance, ged) {
+ var tv = this; // Store "this" for usage within jQuery functions where "this" is not this ;-)
+
+ this.treeview = $('#' + treeview_instance + '_in');
+ this.loadingImage = $('#' + treeview_instance + '_loading');
+ this.toolbox = $('#tv_tools');
+ this.buttons = $('.tv_button:first', this.toolbox);
+ this.zoom = 100; // in percent
+
+ this.boxWidth = 180; // default family box width
+
+ this.boxExpandedWidth = 250; // default expanded family box width
+
+ this.cookieDays = 3; // lifetime of preferences memory, in days
+
+ this.ajaxDetails = document.getElementById(treeview_instance + '_out').dataset.urlDetails + '&instance=' + encodeURIComponent(treeview_instance);
+ this.ajaxPersons = document.getElementById(treeview_instance + '_out').dataset.urlIndividuals + '&instance=' + encodeURIComponent(treeview_instance);
+ this.container = this.treeview.parent(); // Store the container element ("#" + treeview_instance + "_out")
+
+ this.auto_box_width = false;
+ this.updating = false; // Restore user preferences
+
+ if (readCookie('compact') === 'true') {
+ tv.compact();
+ } // Drag handlers for the treeview canvas
+
+
+ (function () {
+ var dragging = false;
+ var drag_start_x;
+ var drag_start_y;
+ tv.treeview.on('mousedown touchstart', function (event) {
+ event.preventDefault();
+ var pageX = event.type === 'touchstart' ? event.touches[0].pageX : event.pageX;
+ var pageY = event.type === 'touchstart' ? event.touches[0].pageY : event.pageY;
+ drag_start_x = tv.treeview.offset().left - pageX;
+ drag_start_y = tv.treeview.offset().top - pageY;
+ dragging = true;
+ });
+ $(document).on('mousemove touchmove', function (event) {
+ if (dragging) {
+ event.preventDefault();
+ var pageX = event.type === 'touchmove' ? event.touches[0].pageX : event.pageX;
+ var pageY = event.type === 'touchmove' ? event.touches[0].pageY : event.pageY;
+ tv.treeview.offset({
+ left: pageX + drag_start_x,
+ top: pageY + drag_start_y
+ });
+ }
+ });
+ $(document).on('mouseup touchend', function (event) {
+ if (dragging) {
+ event.preventDefault();
+ dragging = false;
+ tv.updateTree();
+ }
+ });
+ })(); // Add click handlers to buttons
+
+
+ tv.toolbox.find('#tvbCompact').each(function (index, tvCompact) {
+ tvCompact.onclick = function () {
+ tv.compact();
+ };
+ }); // If we click the "hide/show all partners" button, toggle the setting before reloading the page
+
+ tv.toolbox.find('#tvbAllPartners').each(function (index, tvAllPartners) {
+ tvAllPartners.onclick = function () {
+ createCookie('allPartners', readCookie('allPartners') === 'true' ? 'false' : 'true', tv.cookieDays);
+ document.location = document.location;
+ };
+ });
+ tv.toolbox.find('#tvbOpen').each(function (index, tvbOpen) {
+ var b = $(tvbOpen, tv.toolbox);
+
+ tvbOpen.onclick = function () {
+ b.addClass('tvPressed');
+ tv.setLoading();
+ var e = jQuery.Event('click');
+ tv.treeview.find('.tv_box:not(.boxExpanded)').each(function (index, box) {
+ var pos = $(box, tv.treeview).offset();
+
+ if (pos.left >= tv.leftMin && pos.left <= tv.leftMax && pos.top >= tv.topMin && pos.top <= tv.topMax) {
+ tv.expandBox(box, e);
+ }
+ });
+ b.removeClass('tvPressed');
+ tv.setComplete();
+ };
+ });
+ tv.toolbox.find('#tvbClose').each(function (index, tvbClose) {
+ var b = $(tvbClose, tv.toolbox);
+
+ tvbClose.onclick = function () {
+ b.addClass('tvPressed');
+ tv.setLoading();
+ tv.treeview.find('.tv_box.boxExpanded').each(function (index, box) {
+ $(box).css('display', 'none').removeClass('boxExpanded').parent().find('.tv_box.collapsedContent').css('display', 'block');
+ });
+ b.removeClass('tvPressed');
+ tv.setComplete();
+ };
+ });
+ tv.centerOnRoot(); // fire ajax update if needed, which call setComplete() when all is loaded
+}
+/**
+ * Class TreeView setLoading method
+ */
+
+
+TreeViewHandler.prototype.setLoading = function () {
+ this.treeview.css('cursor', 'wait');
+ this.loadingImage.css('display', 'block');
+};
+/**
+ * Class TreeView setComplete method
+ */
+
+
+TreeViewHandler.prototype.setComplete = function () {
+ this.treeview.css('cursor', 'move');
+ this.loadingImage.css('display', 'none');
+};
+/**
+ * Class TreeView getSize method
+ * Store the viewport current size
+ */
+
+
+TreeViewHandler.prototype.getSize = function () {
+ var tv = this; // retrieve the current container bounding box
+
+ var container = tv.container.parent();
+ var offset = container.offset();
+ tv.leftMin = offset.left;
+ tv.leftMax = tv.leftMin + container.innerWidth();
+ tv.topMin = offset.top;
+ tv.topMax = tv.topMin + container.innerHeight();
+ /*
+ var frm = $("#tvTreeBorder");
+ tv.treeview.css("width", frm.width());
+ tv.treeview.css("height", frm.height()); */
+};
+/**
+ * Class TreeView updateTree method
+ * Perform ajax requests to complete the tree after drag
+ * param boolean @center center on root person when done
+ */
+
+
+TreeViewHandler.prototype.updateTree = function (center, button) {
+ var tv = this; // Store "this" for usage within jQuery functions where "this" is not this ;-)
+
+ var to_load = [];
+ var elts = [];
+ this.getSize(); // check which td with datafld attribute are within the container bounding box
+ // and therefore need to be dynamically loaded
+
+ tv.treeview.find('td[abbr]').each(function (index, el) {
+ el = $(el, tv.treeview);
+ var pos = el.offset();
+
+ if (pos.left >= tv.leftMin && pos.left <= tv.leftMax && pos.top >= tv.topMin && pos.top <= tv.topMax) {
+ to_load.push(el.attr('abbr'));
+ elts.push(el);
+ }
+ }); // if some boxes need update, we perform an ajax request
+
+ if (to_load.length > 0) {
+ tv.updating = true;
+ tv.setLoading();
+ jQuery.ajax({
+ url: tv.ajaxPersons,
+ dataType: 'json',
+ data: 'q=' + to_load.join(';'),
+ success: function success(ret) {
+ var nb = elts.length;
+ var root_element = $('.rootPerson', this.treeview);
+ var l = root_element.offset().left;
+
+ for (var i = 0; i < nb; i++) {
+ elts[i].removeAttr('abbr').html(ret[i]);
+ } // we now ajust the draggable treeview size to its content size
+
+
+ tv.getSize();
+ },
+ complete: function complete() {
+ if (tv.treeview.find('td[abbr]').length) {
+ tv.updateTree(center, button); // recursive call
+ } // the added boxes need that in mode compact boxes
+
+
+ if (tv.auto_box_width) {
+ tv.treeview.find('.tv_box').css('width', 'auto');
+ }
+
+ tv.updating = true; // avoid an unuseful recursive call when all requested persons are loaded
+
+ if (center) {
+ tv.centerOnRoot();
+ }
+
+ if (button) {
+ button.removeClass('tvPressed');
+ }
+
+ tv.setComplete();
+ tv.updating = false;
+ },
+ timeout: function timeout() {
+ if (button) {
+ button.removeClass('tvPressed');
+ }
+
+ tv.updating = false;
+ tv.setComplete();
+ }
+ });
+ } else {
+ if (button) {
+ button.removeClass('tvPressed');
+ }
+
+ tv.setComplete();
+ }
+
+ return false;
+};
+/**
+ * Class TreeView compact method
+ */
+
+
+TreeViewHandler.prototype.compact = function () {
+ var tv = this;
+ var b = $('#tvbCompact', tv.toolbox);
+ tv.setLoading();
+
+ if (tv.auto_box_width) {
+ var w = tv.boxWidth * (tv.zoom / 100) + 'px';
+ var ew = tv.boxExpandedWidth * (tv.zoom / 100) + 'px';
+ tv.treeview.find('.tv_box:not(boxExpanded)', tv.treeview).css('width', w);
+ tv.treeview.find('.boxExpanded', tv.treeview).css('width', ew);
+ tv.auto_box_width = false;
+
+ if (readCookie('compact')) {
+ createCookie('compact', false, tv.cookieDays);
+ }
+
+ b.removeClass('tvPressed');
+ } else {
+ tv.treeview.find('.tv_box').css('width', 'auto');
+ tv.auto_box_width = true;
+
+ if (!readCookie('compact')) {
+ createCookie('compact', true, tv.cookieDays);
+ }
+
+ if (!tv.updating) {
+ tv.updateTree();
+ }
+
+ b.addClass('tvPressed');
+ }
+
+ tv.setComplete();
+ return false;
+};
+/**
+ * Class TreeView centerOnRoot method
+ */
+
+
+TreeViewHandler.prototype.centerOnRoot = function () {
+ this.loadingImage.css('display', 'block');
+ var tv = this;
+ var tvc = this.container;
+ var tvc_width = tvc.innerWidth() / 2;
+
+ if (Number.isNaN(tvc_width)) {
+ return false;
+ }
+
+ var tvc_height = tvc.innerHeight() / 2;
+ var root_person = $('.rootPerson', this.treeview);
+
+ if (!this.updating) {
+ tv.setComplete();
+ }
+
+ return false;
+};
+/**
+ * Class TreeView expandBox method
+ * Called ONLY for elements which have NOT the class tv_link to avoid un-useful requests to the server
+ * @param {string} box - the person box element
+ * @param {string} event - the call event
+ */
+
+
+TreeViewHandler.prototype.expandBox = function (box, event) {
+ var t = $(event.target);
+
+ if (t.hasClass('tv_link')) {
+ return false;
+ }
+
+ var box = $(box, this.treeview);
+ var bc = box.parent(); // bc is Box Container
+
+ var pid = box.attr('abbr');
+ var tv = this; // Store "this" for usage within jQuery functions where "this" is not this ;-)
+
+ var expanded;
+ var collapsed;
+
+ if (bc.hasClass('detailsLoaded')) {
+ collapsed = bc.find('.collapsedContent');
+ expanded = bc.find('.tv_box:not(.collapsedContent)');
+ } else {
+ // Cache the box content as an hidden person's box in the box's parent element
+ expanded = box;
+ collapsed = box.clone();
+ bc.append(collapsed.addClass('collapsedContent').css('display', 'none')); // we add a waiting image at the right side of the box
+
+ var loading_image = this.loadingImage.find('img').clone().addClass('tv_box_loading').css('display', 'block');
+ box.prepend(loading_image);
+ tv.updating = true;
+ tv.setLoading(); // perform the Ajax request and load the result in the box
+
+ box.load(tv.ajaxDetails + '&pid=' + encodeURIComponent(pid), function () {
+ // If Lightbox module is active, we reinitialize it for the new links
+ if (typeof CB_Init === 'function') {
+ CB_Init();
+ }
+
+ box.css('width', tv.boxExpandedWidth * (tv.zoom / 100) + 'px');
+ loading_image.remove();
+ bc.addClass('detailsLoaded');
+ tv.setComplete();
+ tv.updating = false;
+ });
+ }
+
+ if (box.hasClass('boxExpanded')) {
+ expanded.css('display', 'none');
+ collapsed.css('display', 'block');
+ box.removeClass('boxExpanded');
+ } else {
+ expanded.css('display', 'block');
+ collapsed.css('display', 'none');
+ expanded.addClass('boxExpanded');
+ } // we must ajust the draggable treeview size to its content size
+
+
+ this.getSize();
+ return false;
+};
+/**
+ * @param {string} name
+ * @param {string} value
+ * @param {number} days
+ */
+
+
+function createCookie(name, value, days) {
+ if (days) {
+ var date = new Date();
+ date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
+ document.cookie = name + '=' + value + '; expires=' + date.toGMTString() + '; path=/';
+ } else {
+ document.cookie = name + '=' + value + '; path=/';
+ }
+}
+/**
+ * @param {string} name
+ * @returns {string|null}
+ */
+
+
+function readCookie(name) {
+ var name_equals = name + '=';
+ var ca = document.cookie.split(';');
+
+ for (var i = 0; i < ca.length; i++) {
+ var c = ca[i];
+
+ while (c.charAt(0) === ' ') {
+ c = c.substring(1, c.length);
+ }
+
+ if (c.indexOf(name_equals) === 0) {
+ return c.substring(name_equals.length, c.length);
+ }
+ }
+
+ return null;
+}