text: 
  
  /* web/extensions/TDoA/TDoA.min.js */
  var tdoa={ext_name:"TDoA",first_time:!0,hostname:"tdoa.kiwisdr.com",old_algorithm:!1,prev_ui:!1,spiderfied:!1,spiderfy_deferred:!1,ii:0,leaflet:!0,w_data:1024,h_data:465,pkgs_maps_js:["pkgs_maps/pkgs_maps.js","pkgs_maps/pkgs_maps.css"],gmap_js:["http://maps.googleapis.com/maps/api/js?key=","pkgs_maps/gmaps/daynightoverlay.js","pkgs_maps/gmaps/markerwithlabel.js","pkgs_maps/gmaps/v3_ll_grat.js","pkgs_maps/gmaps/markerclusterer.js"],hosts:[],hosts_dither:[],tfields:6,ngood:0,field:[],list:[],results:[],heatmap:[],cur_map:null,kiwi_map:null,result_map:null,map_layers:[],init_lat:20,init_lon:15,init_zoom:2,mapZoom_nom:17,hosts_clusterer:null,refs_clusterer:null,heatmap_visible:!0,show_hosts:!0,show_refs:!0,rerun:0,FIRST_REF:2,known_location:"",quick_zoom:[{n:"World",lat:20,lon:0,z:2},{n:"Europe",lat:52,lon:10,z:4},{n:"N.Amer",lat:40,lon:-90,z:3},{n:"S.Amer",lat:-20,lon:-50,z:3},{n:"Asia",lat:40,lon:120,z:3},{n:"Japan",lat:40,lon:140,z:4},{n:"Aus/NZ",lat:-30,lon:150,z:3}],sample_status:[{s:"sampling complete",retry:0},{s:"connection failed",retry:0},{s:"all channels in use",retry:1},{s:"no recent GPS timestamps",retry:0},{s:"",retry:0}],SAMPLE_STATUS_BLANK:4,submit_status:[{n:0,f:0,m:"TDoA complete"},{n:1,f:1,m:"Octave"},{n:2,f:0,m:"some Kiwis had a sampling error"},{n:3,f:0,m:"some Kiwis had no GPS timestamps at all"},{n:4,f:0,m:"some Kiwis had no recent GPS timestamps"},{n:5,f:1,m:"pair map"},{n:6,f:1,m:"combined map"},{n:7,f:1,m:"dt plot"},{n:8,f:0,m:"out of memory: use fewer Kiwis or check signal quality"},{n:9,f:1,m:"combined contour"},{n:10,f:1,m:"map plot"},{n:11,f:0,m:"reposition map not to span 180 deg meridian"},{n:12,f:0,m:"files for rerun no longer exist"}],KIWI_MAP:0,TDOA_MAP:1,COMBINED_MAP:2,SINGLE_MAPS:3,state:0,READY_SAMPLE:0,READY_COMPUTE:1,RUNNING:2,RETRY:3,RESULT:4,ERROR:5,key:"",select:void 0};function TDoA_main(){ext_switch_to_client(tdoa.ext_name,tdoa.first_time,tdoa_recv),tdoa.first_time||tdoa_controls_setup(),tdoa.first_time=!1}function tdoa_recv(t){if("DAT"!=arrayBufferToStringLen(t,3))for(var e=arrayBufferToString(t).substring(4).split(" "),o=0;o<e.length;o++){var a=e[o].split("=");switch(a[0]){case"ready":tdoa.a=decodeURIComponent(a[1]).split(","),tdoa.a[0]=enc(tdoa.a[0]),tdoa.a[1]=enc(tdoa.a[1]),tdoa.params=ext_param(),tdoa.params&&tdoa.params.includes("gmap:")&&(tdoa.leaflet=!1,tdoa.gmap_param=!0),kiwi_load_js(tdoa.leaflet?tdoa.pkgs_maps_js:tdoa.gmap_js,"tdoa_controls_setup");break;default:console.log("tdoa_recv: UNKNOWN CMD "+a[0])}}else new Uint8Array(t,4)[0]}function tdoa_controls_setup(){var t;for(t=0;t<tdoa.tfields;t++)tdoa.field[t]={};var e="width:"+px(tdoa.w_data)+"; height:"+px(tdoa.h_data),o="w3-label-inline w3-label-not-bold",a="w3-margin-left//"+o,i=time_display_html("tdoa")+w3_div("id-tdoa-data w3-display-container|left:0px; "+e,w3_div("|"+e+'|id="id-tdoa-map-kiwi"',""),w3_div("w3-hide|"+e+'|id="id-tdoa-map-result"',""),w3_div("id-tdoa-png w3-display-topleft w3-scroll-y w3-hide|left:0px; "+e,""),w3_inline("id-tdoa-sorry w3-hide w3-display-topleft|left:0px",w3_div("w3-show-inline w3-padding-LR-8 w3-yellow","Our current map provider is unavailable and we must switch back to using broken Google maps")))+w3_div("id-tdoa-options w3-display-right w3-text-white w3-light-greyx|top:230px; right:0px; width:200px; height:200px",w3_text("w3-text-aqua w3-bold","TDoA options"),w3_checkbox(o,"Show heatmap","tdoa.heatmap_visible",!0,"tdoa_heatmap_visible_cb"),w3_checkbox(o,"Show day/night","tdoa.day_night_visible",!0,"tdoa_day_night_visible_cb"),w3_checkbox(o,"Show graticule","tdoa.graticule_visible",!0,"tdoa_graticule_visible_cb"),w3_checkbox(o,"Old algorithm","tdoa.old_algorithm",!1,"tdoa_old_algorithm_cb"),w3_checkbox("w3-margin-T-10//"+o,"Kiwi hosts","tdoa.hosts_visible",!0,"tdoa_hosts_visible_cb"),w3_checkbox(o,"Reference locations","tdoa.refs_visible",!0,"tdoa_refs_visible_cb"),w3_checkbox(a,"VLF/LF","tdoa.refs_v",!0,"tdoa_refs_cb"),w3_checkbox(a,"Milcom","tdoa.refs_m",!0,"tdoa_refs_cb"),w3_checkbox(a,"Radar","tdoa.refs_r",!0,"tdoa_refs_cb"),w3_checkbox(a,"Aero","tdoa.refs_a",!0,"tdoa_refs_cb"),w3_checkbox(a,"Marine","tdoa.refs_w",!0,"tdoa_refs_cb"),w3_checkbox(a,"Broadcast","tdoa.refs_b",!0,"tdoa_refs_cb"),w3_checkbox(a,"Utility","tdoa.refs_u",!0,"tdoa_refs_cb"),w3_checkbox(a,"Time/Freq","tdoa.refs_t",!0,"tdoa_refs_cb"));tdoa.ref_ids=["v","m","r","a","w","b","u","t"];var s=w3_divs("w3-tspace-8",w3_inline("w3-halign-space-between|width:86%/",w3_div("id-tdoa-controls w3-medium w3-text-aqua",'<b><a href="https://www.rtl-sdr.com/kiwisdr-tdoa-direction-finding-now-freely-available-for-public-use" target="_blank">TDoA</a> direction finding service</b>'),w3_div("",w3_div("id-tdoa-info w3-small|color: hsl(0, 0%, 70%)"),w3_inline("",w3_div("id-tdoa-result w3-small|color: hsl(0, 0%, 70%)","most likely:"),w3_div("id-tdoa-gmap-link w3-margin-L-4"))),w3_div("id-tdoa-bookmark")),w3_div("id-tdoa-hosts-container"),w3_inline("",w3_button("id-tdoa-submit-button w3-padding-smaller w3-css-yellow","Submit","tdoa_submit_button_cb"),w3_div("id-tdoa-submit-icon-c w3-margin-left"),w3_div("id-tdoa-results-select w3-margin-left w3-hide"),w3_div("id-tdoa-results-options w3-margin-left w3-hide"),w3_div("id-tdoa-submit-status w3-margin-left"),w3_button('id-tdoa-rerun-button w3-margin-left w3-padding-smaller w3-css-yellow w3-hide||title="rerun TDoA using same samples"',"Rerun","tdoa_rerun_button_cb"),w3_div('id-tdoa-download-KML w3-margin-left w3-hide||title="download KML file"'),w3_div('id-tdoa-download-MAT w3-margin-left w3-hide||title="download MAT file"')),w3_inline_percent("",w3_select("w3-text-red","","quick zoom","tdoa.quick_zoom",-1,tdoa.quick_zoom,"tdoa_quick_zoom_cb"),20,w3_input("id-tdoa-known-location w3-padding-tiny","","tdoa.known_location","","tdoa_edit_known_location_cb","Map ref location: type lat, lon and name or click green map markers")));ext_panel_show(s,i,null),time_display_setup("tdoa"),ext_set_controls_width_height(650,270),ext_set_data_height(tdoa.h_data);var d="";for(t=0;t<tdoa.tfields;t++)d+=w3_inline(t?"w3-margin-T-3":"",w3_input("w3-padding-tiny||size=10","","tdoa.id_field-"+t,""),w3_input("w3-margin-L-3 w3-padding-tiny||size=28","","tdoa.url_field-"+t,"","tdoa_edit_url_field_cb"),w3_icon("w3-margin-L-8 id-tdoa-clear-icon-"+t,"fa-cut",20,"red","tdoa_clear_cb",t),w3_div("w3-margin-L-8 id-tdoa-listen-icon-c"+t),w3_div("w3-margin-L-8 id-tdoa-sample-icon-c"+t),w3_div("w3-margin-L-8 id-tdoa-download-icon-c"+t),w3_div("w3-margin-L-8 id-tdoa-sample-status-"+t));if(w3_innerHTML("id-tdoa-hosts-container",d),tdoa.leaflet){var r,l=19,n={MapTiler_Vector:0,MapTiler_Raster_512:1,MapTiler_Raster_256:2,OSM_Raster:3},_=n.OSM_Raster;if(_==n.MapTiler_Vector&&(r=function(t){return L.mapboxGL({attribution:'<a href="https://www.maptiler.com/license/maps/" target="_blank">&copy; MapTiler</a> <a href="https://www.openstreetmap.org/copyright" target="_blank">&copy; OpenStreetMap contributors</a>',accessToken:"not-needed",style:"https://api.maptiler.com/maps/"+t+"/style.json"+tdoa.a[1]})}),_==n.MapTiler_Raster_512||_==n.MapTiler_Raster_256){var c=_==n.MapTiler_Raster_256?"/256":"";r=function(t){return L.tileLayer("hybrid"==t?"https://api.maptiler.com/maps/"+t+c+"/{z}/{x}/{y}{r}.jpg"+tdoa.a[1]:"https://api.maptiler.com/maps/"+t+c+"/{z}/{x}/{y}.png"+tdoa.a[1],{tileSize:_==n.MapTiler_Raster_256?256:512,zoomOffset:_==n.MapTiler_Raster_256?0:-1,attribution:'<a href="https://www.maptiler.com/copyright/" target="_blank">&copy; MapTiler</a> <a href="https://www.openstreetmap.org/copyright" target="_blank">&copy; OpenStreetMap contributors</a>',crossOrigin:!0})}}_==n.OSM_Raster&&(r=function(){return l=18,L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",{tileSize:256,zoomOffset:0,attribution:'<a href="https://www.openstreetmap.org/copyright" target="_blank">&copy; OpenStreetMap contributors</a>',crossOrigin:!0})});var m=r("hybrid"),u=L.map("id-tdoa-map-kiwi",{maxZoom:l,minZoom:1,doubleClickZoom:!1,zoomControl:!1}).setView([tdoa.init_lat,tdoa.init_lon],tdoa.init_zoom);u.on("baselayerchange",function(t){var e=t.target,o=e.getCenter();tdoa_pan_zoom(e,[o.lat+.1,o.lng],-1),tdoa_pan_zoom(e,[o.lat,o.lng],-1)}),u.on("click",tdoa_click_info_cb),u.on("moveend",function(t){tdoa_pan_end(t)}),u.on("zoomend",function(t){tdoa_zoom_end(t)}),L.control.zoom_TDoA().addTo(u),m.addTo(u),_!=n.OSM_Raster&&L.control.layers({Satellite:m,Basic:r("basic"),Bright:r("bright"),Positron:r("positron"),Street:r("streets"),Topo:r("topo")},null).addTo(u),tdoa.cur_map=tdoa.kiwi_map=u,dbgUs&&(m.getPane()._jks="MAP");var p=L.control.scale();p.addTo(u),p.setPosition("bottomright"),L.control.ruler({position:"bottomright"}).addTo(u);var f=new Terminator;f.setStyle({fillOpacity:.35}),f.addTo(u),setInterval(function(){var t=new Terminator;f.setLatLngs(t.getLatLngs()),f.redraw()},6e4),tdoa.day_night=f,dbgUs&&(f.getPane()._jks="Terminator"),tdoa.graticule=L.latlngGraticule(),tdoa.graticule.addTo(u),tdoa.map_layers.push(tdoa.graticule),u.on("zoom",tdoa_info_cb),u.on("move",tdoa_info_cb)}else{tdoa.kiwi_map=new google.maps.Map(w3_el("id-tdoa-map-kiwi"),{zoom:tdoa.init_zoom,center:new google.maps.LatLng(tdoa.init_lat,tdoa.init_lon),navigationControl:!1,mapTypeControl:!0,streetViewControl:!1,draggable:!0,scaleControl:!0,gestureHandling:"greedy",mapTypeId:google.maps.MapTypeId.SATELLITE}),tdoa.cur_map=tdoa.kiwi_map,tdoa.gmap_param||w3_show("id-tdoa-sorry"),tdoa.day_night=new DayNightOverlay({map:tdoa.kiwi_map,fillColor:"rgba(0,0,0,0.35)"});new Graticule(tdoa.kiwi_map,!1);tdoa.kiwi_map.addListener("zoom_changed",tdoa_info_cb),tdoa.kiwi_map.addListener("center_changed",tdoa_info_cb),tdoa.kiwi_map.addListener("maptypeid_changed",tdoa_info_cb)}kiwi_ajax(tdoa.url+"refs.cjson","tdoa_get_refs_cb"),tdoa_ui_reset(!0),TDoA_environment_changed({resize:1}),tdoa.state=tdoa.WAIT_HOSTS}function tdoa_reset_spiderfied(){tdoa.spiderfied&&tdoa.spiderfied.unspiderfy(),tdoa.spiderfied=!1}function tdoa_zoom_end(t){tdoa_reset_spiderfied();for(var e=tdoa.cur_map,o=0;o<tdoa.hosts_dither.length;o++){var a=tdoa.hosts_dither[o],i=e.latLngToLayerPoint(L.latLng(a.lat,a.lon));i.y-=20*a.dither_idx,a.mkr.setLatLng(e.layerPointToLatLng(i))}tdoa_ref_marker_offset(!0)}function tdoa_pan_end(t){tdoa_reset_spiderfied()}function tdoa_lat(t){return tdoa.leaflet?t.lat:t.lat()}function tdoa_lon(t){return tdoa.leaflet?t.lng:t.lng()}function tdoa_info_cb(){var t=tdoa.cur_map,e=t.getCenter();w3_innerHTML("id-tdoa-info","map center: "+tdoa_lat(e).toFixed(2)+", "+tdoa_lon(e).toFixed(2)+" z"+t.getZoom()),tdoa_update_link(),tdoa.leaflet||(tdoa_gmap_update("id-tdoa-map-kiwi"),tdoa_gmap_update("id-tdoa-map-result"))}function tdoa_click_info_cb(t){tdoa_reset_spiderfied()}function tdoa_update_link(){var t=kiwi_url_origin()+"/?f="+ext_get_freq_kHz()+"iqz"+ext_get_zoom(),e=ext_get_passband();t+="&pbw="+(2*e.high).toFixed(0)+"&ext=tdoa";var o=tdoa.cur_map;if(o){var a=o.getCenter();t+=",lat:"+tdoa_lat(a).toFixed(2)+",lon:"+tdoa_lon(a).toFixed(2)+",z:"+o.getZoom(),tdoa.leaflet||"satellite"==o.getMapTypeId()||(t+=",map:1"),tdoa.field.forEach(function(e,o){e.good&&(t+=","+w3_get_value("tdoa.id_field-"+o))});var i=w3_get_value("id-tdoa-known-location");i&&""!=i&&(i=i.replace(/\s+/g," ").split(/[ ,]/g)).length>=2&&(t+=","+i[2].replace(/[^0-9A-Za-z]/g,"")),tdoa.old_algorithm&&(t+=",old:"),tdoa.devl&&(t+=",devl:"),tdoa.kml&&(t+=",kml:"),w3_innerHTML("id-tdoa-bookmark",w3_link("",t,w3_icon("w3-text-css-lime","fa-external-link-square",16)))}}function tdoa_marker_click(t){!0!==tdoa.click_pending&&(tdoa.click_pending=!0,tdoa.click_timeout=setTimeout(function(t){tdoa.click_pending=!1,t.kiwi_mkr_2_ref_or_host.click(t)},300,t))}function tdoa_marker_dblclick(t){kiwi_clearTimeout(tdoa.click_timeout),tdoa.click_pending=!1,t.kiwi_mkr_2_ref_or_host.dblclick(t)}function tdoa_place_host_marker(t,e){t.hp=t.h+":"+t.p,t.call=t.id.replace(/\-/g,"/");var o=t.n+"\nUsers: "+t.u+"/"+t.um;if(t.tc){if(t.tc<=0)return console.log("TDoA OPT-OUT: "+t.tc+" "+t.id+" "+t.h),null;o+="\nTDoA channels: "+t.tc}if(o+="\nAntenna: "+t.a+"\n"+t.fm+" GPS fixes/min",tdoa.leaflet){var a=L.divIcon({className:"",iconAnchor:[12,12],labelAnchor:[-6,0],popupAnchor:[0,-36],html:""}),i=L.marker([t.lat,t.lon],{icon:a,opacity:1});t.title=o,e!=tdoa.kiwi_map&&(i.kiwi_mkr_2_ref_or_host=t,tdoa_style_marker(t.mkr,t.idx,t.id,"host",e))}else{var s=new google.maps.LatLng(t.lat,t.lon);i=new MarkerWithLabel({position:s,draggable:!1,raiseOnDrag:!1,map:e,labelContent:t.call,labelAnchor:new google.maps.Point(3.6*t.call.length,36),labelClass:e==tdoa.kiwi_map?"cl-tdoa-gmap-host-label":"cl-tdoa-gmap-selected-label",labelStyle:{opacity:1},title:o,icon:kiwi_mapPinSymbol("red","white")});google.maps.event.addListener(i,"click",function(){tdoa_marker_click(i)}),google.maps.event.addListener(i,"dblclick",function(){tdoa_marker_dblclick(i)})}return t.type_host=!0,t.click=tdoa_host_marker_click,t.dblclick=tdoa_host_marker_dblclick,i.kiwi_mkr_2_ref_or_host=t,i}function tdoa_host_marker_click(t){for(var e=t.kiwi_mkr_2_ref_or_host,o=0;o<tdoa.tfields;o++)if(w3_get_value("tdoa.id_field-"+o)==e.call)return;for(o=0;o<tdoa.tfields;o++){var a=tdoa.field[o];if(!a.inuse){var i=e.hp;a.inuse=!0,a.good=!0,a.use=!0,a.mkr=t,a.host=e,w3_set_value("tdoa.id_field-"+o,e.call),w3_set_value("tdoa.url_field-"+o,i),tdoa_set_icon("sample",o,"fa-refresh fa-spin",20,"lightGrey"),tdoa_rerun_clear();var s=dbgUs&&"kiwisdr.jks.com:8073"==i?"www:8073":i;kiwi_ajax("http://"+s+"/status","tdoa_host_click_status_cb",o,5e3);break}}}function tdoa_open_window(t){var e="http://"+t.hp+"/?f="+ext_get_freq_kHz()+ext_get_mode()+"z"+ext_get_zoom();e+="&pbw="+(2*ext_get_passband().high).toFixed(0),console.log("tdoa_open_window "+e);var o=window.open(e,"_blank");o&&o.focus()}function tdoa_listen_cb(t,e,o){var a=+e,i=tdoa.field[a];i&&i.mkr&&i.mkr.kiwi_mkr_2_ref_or_host&&tdoa_open_window(i.mkr.kiwi_mkr_2_ref_or_host)}function tdoa_host_marker_dblclick(t){kiwi_clearTimeout(tdoa.click_timeout),tdoa.click_pending=!1,tdoa_open_window(t.kiwi_mkr_2_ref_or_host)}function tdoa_place_ref_marker(t,e){var o,a=tdoa.refs[t];if(a.idx=t,o=""!=a.t?a.t+(a.f?", "+a.f+" kHz":""):"",tdoa.leaflet){var i=L.divIcon({className:"",iconAnchor:[12,12],labelAnchor:[-6,0],popupAnchor:[0,-36],html:""}),s=L.marker([a.lat,a.lon],{icon:i,opacity:1});a.title=o,e&&(s.kiwi_mkr_2_ref_or_host=a,tdoa_style_marker(s,a.idx,a.id,"ref",e))}else{var d=new google.maps.LatLng(a.lat,a.lon);s=new MarkerWithLabel({position:d,draggable:!1,raiseOnDrag:!1,map:e,labelContent:a.id,labelAnchor:new google.maps.Point(3.6*a.id.length,36),labelClass:"cl-tdoa-gmap-ref-label",labelStyle:{opacity:1},title:o,icon:kiwi_mapPinSymbol("lime","black")});if(e!=tdoa.kiwi_map&&null!=e)return s;google.maps.event.addListener(s,"click",function(){tdoa_marker_click(s)}),google.maps.event.addListener(s,"dblclick",function(){tdoa_marker_dblclick(s)})}return a.type_host=!1,a.click=tdoa_ref_marker_click,a.dblclick=tdoa_ref_marker_dblclick,s.kiwi_mkr_2_ref_or_host=a,s}function tdoa_ref_marker_offset(t){if(tdoa.leaflet&&tdoa.known_location_idx){var e=tdoa.refs[tdoa.known_location_idx];e.mkr.setLatLng([e.lat,e.lon])}}function tdoa_ref_marker_click(t){if(tdoa.cur_map==tdoa.kiwi_map){var e=t.kiwi_mkr_2_ref_or_host,o=e.t.replace("\n"," "),a=e.lat.toFixed(2)+" "+e.lon.toFixed(2)+" "+e.id+" "+o+(e.f?" "+e.f+" kHz":"");if(w3_set_value("id-tdoa-known-location",a),tdoa.known_location_idx){var i=tdoa.refs[tdoa.known_location_idx];i.selected=!1,console.log("ref_click: deselect ref "+i.id),tdoa_ref_marker_offset(!1)}tdoa.known_location_idx=e.idx,e.selected=!0,console.log("ref_click: select ref "+e.id),tdoa_rebuild_refs(),e.f&&ext_tune(e.f,"iq",ext_zoom.ABS,e.z,-e.p/2,e.p/2),tdoa_update_link(),tdoa_ref_marker_offset(!0)}}function tdoa_ref_marker_dblclick(t){var e=t.kiwi_mkr_2_ref_or_host,o=tdoa.cur_map;if(o.getZoom()>=(e.mz||tdoa.mapZoom_nom))tdoa.last_center&&tdoa.last_zoom?tdoa_pan_zoom(o,tdoa.last_center,tdoa.last_zoom):tdoa_pan_zoom(o,[tdoa.init_lat,tdoa.init_lon],tdoa.init_zoom);else{tdoa.last_center=o.getCenter(),tdoa.last_zoom=o.getZoom();var a=e.mz||tdoa.mapZoom_nom;tdoa_pan_zoom(o,[e.lat,e.lon],a)}}function tdoa_style_marker(t,e,o,a,i){t.bindTooltip(o,{className:"id-tdoa-"+a+" id-tdoa-"+a+"-"+e,permanent:!0,direction:"right"}),t.on("add",function(t){var e=t.sourceTarget.kiwi_mkr_2_ref_or_host;w3_iterate_classname("id-tdoa-"+a+"-"+e.idx,function(t){t&&(e.type_host&&(e.selected?w3_color(t,"black","yellow"):w3_color(t,"white","blue")),t.title=e.title,t.kiwi_mkr_2_ref_or_host=e,t.addEventListener("click",function(t){tdoa_marker_click(t.target)}),t.addEventListener("dblclick",function(t){tdoa_marker_dblclick(t.target)}),t.addEventListener("mouseenter",function(o){e.selected||w3_color(t,"black","yellow")}),t.addEventListener("mouseleave",function(o){e.selected||(e.type_host?w3_color(t,"white","blue"):w3_color(t,"black","lime"))}))})}),i&&(t.addTo(i),tdoa.map_layers.push(t))}function tdoa_change_marker_style(t,e,o,a){tdoa.leaflet||(t.setMap(null),t.labelClass=a,t.icon=kiwi_mapPinSymbol(e,o),t.setMap(tdoa.kiwi_map))}function tdoa_get_refs_cb(t){if(t){tdoa.refs=t;var e=[];for(i=tdoa.FIRST_REF;i<tdoa.refs.length-1;i++){var o=tdoa.refs[i];o.id_lcase=o.id.toLowerCase();var a=tdoa_place_ref_marker(i,null);e.push(a),o.mkr=a}tdoa.refs_markers=e,tdoa_rebuild_refs(),kiwi_ajax(tdoa.url_files+"kiwi.gps.json","tdoa_get_hosts_cb")}else console.log("tdoa_get_refs_cb refs="+t)}function tdoa_get_hosts_cb(t){if(t){tdoa.hosts=t;for(var e,o,a,i,s,d=[],r=0;r<t.length;r++){var l=t[r];if(l.idx=r,""!=l.h){for(var n=0;n<r;n++){var _=t[n];if(tdoa.leaflet){var c=L.latLng(l.lat,l.lon),m=L.latLng(_.lat,_.lon),u=c.distanceTo(m);u<2e3&&(null==_.dither_idx&&(_.dither_idx=1),l.dither_idx=_.dither_idx++,tdoa.hosts_dither.push(l),console.log(_.id+" "+l.id+" spacing="+u))}_.id==l.id&&(console.log("TDoA duplicate ID: #"+l.i+" "+l.id+" #"+_.i+" "+_.id),null==_.dup&&(_.dup=0),_.dup++,l.id+="/"+_.dup)}l.id_lcase=l.id.toLowerCase();var p=tdoa_place_host_marker(l,tdoa.kiwi_map);p&&d.push(p),l.mkr=p}else console.log("TDoA WARNING: hosts.h empty?"),console.log(l)}if(tdoa.params){var f=tdoa.params.split(",");tdoa.params=null;r=0;for(var h=f.length;r<h;r++){var w=f[r];if(console.log("TDoA: param <"+w+">"),w.includes(":"))w.startsWith("lat:")?e=parseFloat(w.substring(4)):w.startsWith("lon:")||w.startsWith("lng:")?o=parseFloat(w.substring(4)):w.startsWith("z:")?a=parseInt(w.substring(2)):w.startsWith("zoom:")?a=parseInt(w.substring(5)):w.startsWith("map:")?i=parseInt(w.substring(4)):w.startsWith("submit:")?s=!0:w.startsWith("leaflet:")?tdoa.leaflet=!0:w.startsWith("google:")?tdoa.leaflet=!1:w.startsWith("prev_ui:")?tdoa.prev_ui=!0:w.startsWith("help:")?extint_help_click():w.startsWith("kml:")?tdoa.kml=!0:w.startsWith("old:")?(tdoa.old_algorithm=!0,w3_checkbox_set("tdoa.old_algorithm",!0)):w.startsWith("new:")?(tdoa.old_algorithm=!1,w3_checkbox_set("tdoa.old_algorithm",!1)):w.startsWith("devl:")&&(tdoa.devl=!0);else{w=w.toLowerCase();var g=!1;tdoa.refs.forEach(function(t){!g&&t.id_lcase&&t.id_lcase.includes(w)&&(console.log("TDoA refs match: "+w),t.selected=!0,tdoa_ref_marker_click(t.mkr),g=!0)}),g=!1,tdoa.hosts.forEach(function(t){!g&&t.id_lcase&&t.id_lcase.includes(w)&&(console.log("TDoA hosts match: "+w),t.selected=!0,tdoa_host_marker_click(t.mkr),g=!0)})}}}tdoa_rebuild_hosts(),tdoa_rebuild_refs(),tdoa_pan_zoom(tdoa.kiwi_map,e&&o?[e,o]:null,a||-1),tdoa.leaflet||1!=i||tdoa.kiwi_map.setMapTypeId("roadmap"),tdoa.state=tdoa.READY_SAMPLE,1==s&&(tdoa.init_submit_timeout=setTimeout(tdoa_submit_button_cb2,6e3))}else console.log("tdoa_get_hosts_cb hosts="+t)}function TDoA_environment_changed(t){if(t.resize){var e=w3_el("id-tdoa-data");if(!e)return;var o=Math.max(0,(window.innerWidth-tdoa.w_data-time_display_width())/2);e.style.left=px(o)}else tdoa_update_link()}function tdoa_gmap_update(t,e){var o=w3_el(t);if(o)if(e=e||0,o.childElementCount<2){if(e>=50)return;setTimeout(function(){tdoa_gmap_update(t,e+1)},200)}else{o.removeChild(o.children[1]),new MutationObserver(function(){tdoa.mo_w++}).observe(o,{attributes:!0,childList:!0,subtree:!0}),setInterval(function(){var t=tdoa.mo_w;tdoa.mo_r!=t&&(tdoa.mo_r=t,w3_iterateDeep_children(o,function(t){"SPAN"==t.tagName&&t.innerHTML.endsWith("nly")&&(t.parentElement.parentElement.style.backgroundColor="")}))},250)}}function tdoa_show_maps(t){tdoa.leaflet?(tdoa_rebuild_hosts({show:!t.result&&tdoa.show_hosts}),tdoa_rebuild_refs({show:!t.result&&tdoa.show_refs}),w3_show_hide("id-tdoa-map-kiwi",t.kiwi||t.result)):(w3_show_hide("id-tdoa-map-kiwi",t.kiwi),w3_show_hide("id-tdoa-map-result",t.result)),tdoa.leaflet||(tdoa_gmap_update("id-tdoa-map-kiwi"),tdoa_gmap_update("id-tdoa-map-result"))}function tdoa_ui_reset(t){tdoa_set_icon("submit",-1,"fa-refresh",20,"lightGrey"),tdoa_submit_state(tdoa.READY_SAMPLE,""),tdoa_info_cb(),w3_innerHTML("id-tdoa-result","most likely:"),w3_innerHTML("id-tdoa-gmap-link",""),w3_hide("id-tdoa-results-select"),w3_hide("id-tdoa-results-options"),t&&(tdoa_show_maps({kiwi:!0,result:!1}),w3_hide("id-tdoa-png"))}function tdoa_set_icon(t,e,o,a,i,s,d){e=e>=0?e:"",w3_innerHTML("id-tdoa-"+t+"-icon-c"+e,""==o?"":w3_icon("id-tdoa-"+t+"-icon"+e,o,a,i,s,d))}function tdoa_submit_state(t,e){t==tdoa.ERROR&&tdoa_set_icon("submit",-1,"fa-times-circle",20,"red"),w3_innerHTML("id-tdoa-submit-status",e),w3_show_hide("id-tdoa-rerun-button",t==tdoa.RESULT),w3_show_hide("id-tdoa-download-KML",t==tdoa.RESULT&&tdoa.leaflet),w3_show_hide("id-tdoa-download-MAT",t==tdoa.RESULT),tdoa.state=t}function tdoa_rerun_clear(){w3_hide("id-tdoa-rerun-button"),w3_hide("id-tdoa-download-KML"),w3_hide("id-tdoa-download-MAT"),tdoa.rerun=0}function tdoa_edit_url_field_cb(t,e,o){var a=+t.match(/\d+/).shift(),i=tdoa.field[a];if(w3_innerHTML("id-tdoa-sample-status-"+a,""),i.mkr&&(i.host&&(i.host.selected=!1),tdoa_change_marker_style(i.mkr,"red","white","cl-tdoa-gmap-host-label")),i.mkr=void 0,i.host=void 0,i.inuse=!0,i.good=!0,i.use=!0,tdoa_set_icon("download",a,""),""==e)return tdoa_set_icon("sample",a,""),void tdoa_set_icon("listen",a,"");tdoa_set_icon("sample",a,"fa-refresh fa-spin",20,"lightGrey"),tdoa_rerun_clear();var s=dbgUs&&"kiwisdr.jks.com:8073"==e?"www:8073":e;kiwi_ajax("http://"+s+"/status","tdoa_host_click_status_cb",a,5e3),tdoa_rebuild_hosts()}function tdoa_clear_cb(t,e,o){if(tdoa.state!=tdoa.RUNNING){var a=+e,i=tdoa.field[a];i.inuse=!1,i.good=!1,i.use=!1,w3_set_value("tdoa.id_field-"+a,""),w3_set_value("tdoa.url_field-"+a,""),tdoa_set_icon("sample",a,""),tdoa_set_icon("listen",a,""),tdoa_set_icon("download",a,""),w3_innerHTML("id-tdoa-sample-status-"+a,""),i.mkr&&(i.host&&(i.host.selected=!1),tdoa_change_marker_style(i.mkr,"red","white","cl-tdoa-gmap-host-label")),i.mkr=void 0,i.host=void 0,tdoa_rebuild_hosts(),tdoa_update_link()}}function tdoa_edit_known_location_cb(t,e,o){if(tdoa.known_location_idx){var a=tdoa.refs[tdoa.known_location_idx];a.selected=!1,tdoa_ref_marker_offset(!1),console.log("edit_known_location: deselect ref "+a.id)}tdoa.known_location_idx=void 0,tdoa_update_link(),tdoa_rebuild_refs()}function tdoa_host_click_status_cb(t,e){var o,a=tdoa.field[e];if(t.response){for(var i=t.response.split("\n"),s=auth=users=users_max=fixes_min=null,d=0;d<i.length;d++){var r=i[d];r.startsWith("offline=")&&(s=r.split("=")[1]),r.startsWith("auth=")&&(auth=r.split("=")[1]),r.startsWith("users=")&&(users=r.split("=")[1]),r.startsWith("users_max=")&&(users_max=r.split("=")[1]),r.startsWith("fixes_min=")&&(fixes_min=r.split("=")[1])}if(null==fixes_min)return;if("yes"==s)o="Kiwi is offline";else if("password"==auth)o="Kiwi requires password";else if(0==fixes_min)o="no recent GPS timestamps";else{if(null==users_max)return;if(users<users_max){tdoa_set_icon("sample",e,"fa-refresh",20,"lime"),tdoa_set_icon("listen",e,"fa-volume-up",20,"lime","tdoa_listen_cb",e);var l=fixes_min?fixes_min+" GPS fixes/min":"channel available";return w3_innerHTML("id-tdoa-sample-status-"+e,l),a.host.selected=!0,tdoa_rebuild_hosts(),a.mkr&&tdoa_change_marker_style(a.mkr,"red","white","cl-tdoa-gmap-selected-label"),void tdoa_update_link()}o="all channels in use"}}else console.log(t),o="no response";tdoa_set_icon("sample",e,"fa-times-circle",20,"red"),tdoa_set_icon("listen",e,"fa-volume-up",20,"red"),w3_innerHTML("id-tdoa-sample-status-"+e,o),a.good=!1,a.mkr=void 0,a.host&&(a.host.selected=!1),a.host=void 0,tdoa_rebuild_hosts()}function tdoa_submit_button_cb(){kiwi_clearTimeout(tdoa.init_submit_timeout);var t=tdoa.state;if(tdoa_ui_reset(!1),t!=tdoa.RUNNING&&t!=tdoa.RETRY)setTimeout(tdoa_submit_button_cb2,1e3);else{tdoa.response.key=0;for(var e=0;e<tdoa.tfields;e++){var o=tdoa.field[e];o.good&&(o.use=!0,tdoa_set_icon("sample",e,"fa-refresh",20,"lightGrey"),tdoa_set_icon("download",e,""),w3_innerHTML("id-tdoa-sample-status-"+e,"stopped"))}w3_button_text("id-tdoa-submit-button","Submit","w3-css-yellow","w3-red")}}function tdoa_use_cb(t,e,o){var a=parseInt(t);tdoa.field[a].use=e}function tdoa_submit_button_cb2(){var t,e,o,a;if(tdoa.ngood=0,tdoa.field.forEach(function(t,e){t.good&&!tdoa.rerun&&(t.use=!0),t.good&&t.use&&tdoa.ngood++}),tdoa.ngood<2)return tdoa_submit_state(tdoa.ERROR,"at least 2 available hosts needed"),void(tdoa.rerun=0);if(tdoa.cur_map.getZoom()<3)return tdoa_submit_state(tdoa.ERROR,"must be zoomed in further"),void(tdoa.rerun=0);var i="&h=",s="&p=",d="&id=",r=0;for(tdoa.list=[],t=0;t<tdoa.tfields;t++){var l=tdoa.field[t];if(l.good&&l.use){tdoa.list[r]={};var n=tdoa.list[r],_=w3_get_value("tdoa.url_field-"+t);""!=_&&2==(_=_.split(":")).length&&""!=_[0]&&""!=_[1]?(r&&(i+=",",s+=",",d+=","),e=_[0],n.h=e,i+=e,o=_[1],n.p=o,s+=o,""==(a=w3_get_value("tdoa.id_field-"+t))&&(a="id_"+t,w3_set_value("tdoa.id_field-"+t,a)),a=a.replace(/[^0-9A-Za-z\-\/]/g,""),n.call=a,a=a.replace(/\//g,"-"),n.id=a,d+=a,n.field_idx=t,r++):l.good=!1}}if(r<2)return tdoa_submit_state(tdoa.ERROR,"at least 2 available hosts needed"),void(tdoa.rerun=0);var c=i+s+d;c+="&f="+(ext_get_passband_center_freq()/1e3).toFixed(2),c+="&w="+ext_get_passband().high.toFixed(0),null==tdoa.cur_map&&(tdoa.cur_map=tdoa.kiwi_map);var m=tdoa.cur_map.getBounds(),u=m.getNorthEast(),p=m.getSouthWest(),f=Math.round(tdoa_lat(u)+1),h=Math.round(tdoa_lat(p)-1),w=Math.round(tdoa_lon(u)+1);c+="&pi=struct('lat_range',\\["+h+","+f+"\\],'lon_range',\\["+Math.round(tdoa_lon(p)-1)+","+w+"\\]";var g=w3_get_value("id-tdoa-known-location");if(g&&""!=g&&(g=g.replace(/\s+/g," ").split(/[ ,]/g)).length>=3){var k=parseFloat(g[0]),b=parseFloat(g[1]);if(!isNaN(k)&&!isNaN(b)){var v=g[2].replace(/[^0-9A-Za-z]/g,"");c+=",'known_location',struct('coord',\\["+k+","+b+"\\],'name',"+sq(v)+")"}}tdoa.old_algorithm||(c+=",'new',true"),tdoa.kml&&(c+=",'kml',1"),c+=")",tdoa.rerun&&(c+="&rerun="+tdoa.response.key),tdoa.devl&&(c+="&devl=1"),tdoa.last_menu_select=void 0,tdoa.response={},tdoa.response.seq=0,kiwi_ajax_progress(tdoa.url_base+"php/tdoa.php"+tdoa.a[0]+c,function(t){tdoa_protocol_response_cb(t)},0,0,function(t){tdoa_protocol_response_cb(t)},0),tdoa.rerun?(tdoa_submit_state(tdoa.RUNNING,"rerun using same samples"),tdoa.rerun=0):(tdoa.field.forEach(function(t,e){t.good&&(w3_innerHTML("id-tdoa-sample-icon-c"+e,kiwi_pie("id-tdoa-pie",tdoa.pie_size,"#eeeeee","deepSkyBlue")),tdoa_set_icon("download",e,""),w3_innerHTML("id-tdoa-sample-status-"+e,"sampling started"))}),tdoa_submit_state(tdoa.RUNNING,"sampling started")),w3_button_text("id-tdoa-submit-button","Stop","w3-red","w3-css-yellow"),w3_color("id-tdoa-submit-icon","lime"),tdoa.leaflet||(tdoa.gmap_map_type=tdoa.cur_map.getMapTypeId()),tdoa.map_zoom=tdoa.cur_map.getZoom(),tdoa.map_center=tdoa.cur_map.getCenter()}function tdoa_rerun_button_cb(){tdoa.rerun=1,tdoa_submit_button_cb()}function tdoa_sample_status_cb(t){for(var e=!1,o=0;o<tdoa.ngood;o++){var a=tdoa.list[o].field_idx,i=t>>2*o&3;if(i)tdoa_set_icon("sample",a,"fa-times-circle",20,"red"),e=!0;else if(0!=t||""==tdoa.response.files)tdoa_set_icon("sample",a,"fa-refresh",20,"lime"),i=tdoa.SAMPLE_STATUS_BLANK;else{var s=tdoa.field[a];w3_innerHTML("id-tdoa-sample-icon-c"+a,w3_checkbox("","",a+"-tdoa-use",s.use,"tdoa_use_cb"));var d=tdoa.response.files[o].replace(/^\.\.\/files/,tdoa.rep_files);w3_innerHTML("id-tdoa-download-icon-c"+a,w3_link("",d,w3_icon("w3-text-aqua","fa-download",18)))}var r=i>=tdoa.sample_status.length?"recording error":tdoa.sample_status[i].s;tdoa.sample_status[i].retry,w3_innerHTML("id-tdoa-sample-status-"+a,r)}if(e)w3_button_text("id-tdoa-submit-button","Submit","w3-css-yellow","w3-red"),tdoa_submit_state(tdoa.ERROR,"sampling error");else{tdoa_set_icon("submit",-1,"fa-refresh fa-spin",20,"lime");var l="TDoA";tdoa.old_algorithm?l+="-old":tdoa.devl&&(l+="-devl"),tdoa_submit_state(tdoa.RUNNING,l+" algorithm running")}}function tdoa_submit_status_new_cb(t){t?tdoa_submit_status_old_cb(t):kiwi_ajax(tdoa.url_files+tdoa.response.key+"/status.json",function(t){var e,o,a,i=0,s=void 0,d="unknown status returned";if(t.AJAX_error)if("status"==t.AJAX_error)d="status file missing",i=1;else try{var r=t.response;r=r.replace(/\n/g,""),t=JSON.parse(r),i=0}catch(t){d="status JSON parse error",i=2}if(0==i){try{o=t.octave_error.identifier}catch(t){o=void 0}try{a=t.octave_error.message}catch(t){a=void 0}o?(d=o,a&&console.log(a),i=3):i=0}if(0==i){try{e=t.input.per_file}catch(t){e=void 0}e&&e.forEach(function(t,e){if("BAD"==t.status){var o=t.name.toLowerCase();tdoa.field.forEach(function(t,e){t.good&&t.host.id_lcase==o&&(tdoa_set_icon("sample",e,"fa-times-circle",20,"red"),w3_innerHTML("id-tdoa-sample-status-"+e,"unused, poor data quality"))})}})}if(0==i){try{o=t.input.result.status}catch(t){o=void 0}try{a=t.input.result.message}catch(t){a=void 0}o&&("OK"==o||"GOOD"==o?i=0:"BAD"==o?(i=4,d=a.endsWith("< 2")?"after errors less than 2 hosts remain":"FIXME: "+a):(d="unknown result: "+o,i=5))}if(0==i){try{o=t.constraints.result.status}catch(t){o=void 0}try{a=t.constraints.result.message}catch(t){a=void 0}o?"OK"==o||"GOOD"==o?i=0:"BAD"==o?(i=6,d=a.endsWith("< 2")?"after errors less than 2 hosts remain":"FIXME: "+a):(d="unknown constraint: "+o,i=7):null!=o&&(s="no reasonable solution")}t.likely_position&&(tdoa.response.likely_lat=parseFloat(t.likely_position.lat).toFixed(2),tdoa.response.likely_lon=parseFloat(t.likely_position.lng).toFixed(2)),t.position&&t.position.likely_position&&(tdoa.response.likely_lat=parseFloat(t.position.likely_position.lat).toFixed(2),tdoa.response.likely_lon=parseFloat(t.position.likely_position.lng).toFixed(2)),0==i?tdoa_submit_status_old_cb(0,s):(w3_button_text("id-tdoa-submit-button","Submit","w3-css-yellow","w3-red"),tdoa_submit_state(tdoa.ERROR,d))})}function tdoa_submit_status_old_cb(t,e){if(0!=t){var o=t>=tdoa.submit_status.length?"unknown":tdoa.submit_status[t].m;1==tdoa.submit_status[t].f&&(o+=" error: zoom map in or check reception"),tdoa_submit_state(tdoa.ERROR,o)}else{var a,i;tdoa_set_icon("submit",-1,"fa-check-circle",20,"lime"),tdoa.results=[],tdoa.results[0]={},tdoa.results[1]={},tdoa.results[2]={},tdoa.results[0].menu="Kiwi map",tdoa.results[1].menu="TDoA map",tdoa.results[2].menu="TDoA combined",tdoa.results[0].file="Kiwi map",tdoa.results[1].file="TDoA map",tdoa.results[2].file="TDoA combined",tdoa.results[1].ids="TDoA map",tdoa.results[2].ids="TDoA combined";var s=tdoa.SINGLE_MAPS,d=tdoa.ngood*(tdoa.ngood-1)/2;for(a=0;a<tdoa.ngood;a++)for(i=a+1;i<tdoa.ngood;i++){var r=tdoa.list[a],l=tdoa.list[i];tdoa.results[s]={},tdoa.results[s].menu=r.call+"-"+l.call+" map",tdoa.results[s].file=r.id+"-"+l.id+" map",tdoa.results[s].ids=r.id+"-"+l.id,tdoa.results[s].list1=a,tdoa.results[s].list2=i,tdoa.results[s+d]={},tdoa.results[s+d].menu=r.call+"-"+l.call+" dt",tdoa.results[s+d].file=r.id+"-"+l.id+" dt",s++}w3_innerHTML("id-tdoa-results-select",w3_select("w3-text-red","","TDoA results","tdoa.result_select",-1,tdoa.results,"tdoa_result_menu_click_cb")),w3_show("id-tdoa-results-select"),w3_show("id-tdoa-results-options"),tdoa_result_menu_click_cb("",tdoa.TDOA_MAP),w3_select_value("tdoa.result_select",tdoa.TDOA_MAP);var n="TDoA";tdoa.old_algorithm?n+="-old":tdoa.devl&&(n+="-devl"),tdoa_submit_state(tdoa.RESULT,e||n+" complete")}w3_button_text("id-tdoa-submit-button","Submit","w3-css-yellow","w3-red")}function tdoa_KML_link(t){w3_innerHTML("id-tdoa-download-KML",w3_link("",t,w3_icon("w3-text-aqua","fa-download",18))+" KML")}function tdoa_protocol_response_cb(t){if(isString(t)){var e=(t=t.trim()).length;e&&"{"==t[0]&&"}"!=t[e-1]&&(t+="}");try{var o=JSON.parse(t)}catch(e){console.log("JSON parse error"),console.log(e),console.log(t)}}else o=t;tdoa.response.seq>0&&o.key&&o.key!=tdoa.response.key||(0==tdoa.response.seq&&null!=o.key&&(tdoa.response.key=o.key,tdoa.response.seq++),1==tdoa.response.seq&&null!=o.files&&(tdoa.response.files=o.files,tdoa.response.seq++),2==tdoa.response.seq&&null!=o.status0&&(tdoa_sample_status_cb(o.status0),tdoa.response.seq++),3==tdoa.response.seq&&null!=o.done&&(tdoa_submit_status_new_cb(o.done),tdoa.response.seq++))}function tdoa_result_menu_click_cb(t,e,o){var a;if(e=+e,tdoa.last_menu_select=e,tdoa_KML_link(""),tdoa.leaflet&&(tdoa.map_layers&&(tdoa.map_layers.forEach(function(t){t&&t.remove()}),tdoa.map_layers=[]),tdoa_day_night_visible_cb("tdoa.day_night_visible"),tdoa_graticule_visible_cb("tdoa.graticule_visible")),e==tdoa.KIWI_MAP)tdoa_show_maps({kiwi:!0,result:!1}),w3_hide("id-tdoa-png"),tdoa_info_cb(),tdoa.cur_map=tdoa.kiwi_map;else{var i=tdoa.ngood*(tdoa.ngood-1)/2;if(e<tdoa.SINGLE_MAPS+i){if(w3_hide("id-tdoa-png"),tdoa.leaflet)tdoa.result_map=tdoa.cur_map;else{tdoa.result_map=new google.maps.Map(w3_el("id-tdoa-map-result"),{zoom:tdoa.map_zoom,center:tdoa.map_center,navigationControl:!1,mapTypeControl:!0,streetViewControl:!1,draggable:!0,scaleControl:!0,gestureHandling:"greedy",mapTypeId:tdoa.gmap_map_type}),tdoa.cur_map=tdoa.result_map;new Graticule(tdoa.result_map,!1);tdoa.result_map.addListener("zoom_changed",tdoa_info_cb),tdoa.result_map.addListener("center_changed",tdoa_info_cb),tdoa.result_map.addListener("maptypeid_changed",tdoa_info_cb)}tdoa_show_maps({kiwi:!1,result:!0});var s,d,r=tdoa.url_files+tdoa.response.key+"/tdoa_data.mat";w3_innerHTML("id-tdoa-download-MAT",w3_link("",r,w3_icon("w3-text-aqua","fa-download",18))+" MAT"),e==tdoa.COMBINED_MAP?(s=tdoa.SINGLE_MAPS,d=tdoa.SINGLE_MAPS+i):d=(s=e)+1;for(var l=s;l<d;l++){var n=tdoa.kml?"kml":"json",_=tdoa.url_files+tdoa.response.key+"/"+tdoa.results[l].ids+"_contour_for_map."+n;tdoa.kml&&(e!=tdoa.COMBINED_MAP&&tdoa_KML_link(_),console.log("TDoA KML test: mi="+l+" "+_)),kiwi_ajax(_,function(t,e){if(t.AJAX_error)console.log(t);else if(tdoa.leaflet)if(tdoa.heatmap[e]=L.imageOverlay(tdoa.url_files+tdoa.response.key+"/"+tdoa.results[e].ids+"_for_map.png",[[t.imgBounds.north,t.imgBounds.west],[t.imgBounds.south,t.imgBounds.east]],{opacity:.5}),tdoa.heatmap_visible&&(tdoa.heatmap[e].addTo(tdoa.result_map),tdoa.map_layers.push(tdoa.heatmap[e])),tdoa.kml){if(console.log("TDoA start KML "+_),!t.XML)return void console.log(t);parser=new DOMParser,kml=parser.parseFromString(t.text,"text/xml"),track=new L.KML(kml),tdoa.result_map.addLayer(track)}else{if(t.polygons&&t.polygons.length){var o=new Array(t.polygons.length);for(p=0;p<t.polygons.length;++p){var i=t.polygons[p],s=[];for(a=0;a<i.length;a++)s[a]=[i[a].lat,i[a].lng];o[p]=L.polygon(s,{color:t.polygon_colors[p],opacity:1,weight:1,fillOpacity:0}),o[p].addTo(tdoa.result_map),tdoa.map_layers.push(o[p])}}if(t.polylines&&t.polylines.length){var d=new Array(t.polylines.length);for(p=0;p<t.polylines.length;++p){i=t.polylines[p],s=[];for(a=0;a<i.length;a++)s[a]=[i[a].lat,i[a].lng];d[p]=L.polyline(s,{color:t.polyline_colors[p],opacity:1,weight:1,fillOpacity:0}),d[p].addTo(tdoa.result_map),tdoa.map_layers.push(d[p])}}}else{if(tdoa.heatmap[e]=new google.maps.GroundOverlay(tdoa.url_files+t.filename,t.imgBounds,{opacity:.5}),tdoa.heatmap[e].setMap(tdoa.heatmap_visible?tdoa.result_map:null),t.polygons&&t.polygons.length){o=new Array(t.polygons.length);for(p=0;p<t.polygons.length;++p)o[p]=new google.maps.Polygon({paths:t.polygons[p],strokeColor:t.polygon_colors[p],strokeOpacity:1,strokeWeight:1,fillOpacity:0}),o[p].setMap(tdoa.result_map)}if(t.polylines&&t.polylines.length){d=new Array(t.polylines.length);for(p=0;p<t.polylines.length;++p)d[p]=new google.maps.Polyline({path:t.polylines[p],strokeColor:t.polyline_colors[p],strokeOpacity:1,strokeWeight:1,fillOpacity:0}),d[p].setMap(tdoa.result_map)}}},l)}var c=[];e==tdoa.TDOA_MAP||e==tdoa.COMBINED_MAP?(s=tdoa.SINGLE_MAPS,d=tdoa.SINGLE_MAPS+i):d=(s=e)+1;for(l=s;l<d;l++){var m=tdoa.results[l].list1,u=tdoa.results[l].list2;c[m]=tdoa.list[m].field_idx,c[u]=tdoa.list[u].field_idx}for(var p=0;p<c.length;p++){var f=c[p];if(null!=f){var h=tdoa.field[f];h.mkr&&h.host&&tdoa_place_host_marker(h.host,tdoa.result_map)}}if(null!=tdoa.known_location_idx)tdoa_place_ref_marker(tdoa.known_location_idx,tdoa.result_map);else{var w=w3_get_value("id-tdoa-known-location");if(w&&""!=w&&(w=w.replace(/\s+/g," ").split(/[ ,]/g)).length>=2){var g,k=parseFloat(w[0]),b=parseFloat(w[1]);if(!isNaN(k)&&!isNaN(b))(g=tdoa.refs[0]).id=w[2].replace(/[^0-9A-Za-z]/g,""),g.lat=k,g.lon=b,w.shift(),w.shift(),w.shift(),g.t=w.join(" "),g.f=void 0,tdoa_place_ref_marker(0,tdoa.result_map)}}if(null!=tdoa.response.likely_lat&&null!=tdoa.response.likely_lon)(g=tdoa.refs[1]).id=tdoa.response.likely_lat+", "+tdoa.response.likely_lon,g.lat=tdoa.response.likely_lat,g.lon=tdoa.response.likely_lon,g.t="Most likely position",tdoa_place_ref_marker(1,tdoa.result_map)}else{tdoa_show_maps({kiwi:!1,result:!1}),v=e==tdoa.COMBINED_MAP?"Available only for new map option":'<img src="'+tdoa.url_files+tdoa.response.key+"/"+tdoa.results[e].file+'.png" alt="Image not available"/>',w3_innerHTML("id-tdoa-png",w3_div("w3-text-yellow",v)),w3_show("id-tdoa-png"),tdoa.cur_map=tdoa.kiwi_map}if(null!=tdoa.response.likely_lat&&null!=tdoa.response.likely_lon){var v="most likely: "+tdoa.response.likely_lat+", "+tdoa.response.likely_lon;w3_innerHTML("id-tdoa-result",w3_text("|color: hsl(0, 0%, 70%)",v));r="https://google.com/maps/place/"+tdoa.response.likely_lat+","+tdoa.response.likely_lon;w3_innerHTML("id-tdoa-gmap-link",w3_link("",r,w3_icon("w3-text-aqua","fa-map-marker",18)))}}}function tdoa_old_algorithm_cb(t,e){tdoa.old_algorithm=e}function tdoa_heatmap_visible_cb(t,e){if(tdoa.heatmap_visible=e,tdoa.last_menu_select){var o,a;if(tdoa.last_menu_select==tdoa.COMBINED_MAP){var i=tdoa.ngood*(tdoa.ngood-1)/2;o=tdoa.SINGLE_MAPS,a=tdoa.SINGLE_MAPS+i}else a=(o=tdoa.last_menu_select)+1;for(var s=o;s<a;s++){var d=tdoa.heatmap[s];d&&(tdoa.leaflet?tdoa.heatmap_visible?(d.addTo(tdoa.result_map),tdoa.map_layers.push(d)):d.remove():d.setMap(tdoa.heatmap_visible?tdoa.result_map:null))}}}function tdoa_day_night_visible_cb(t,e,o){if(!o&&tdoa.day_night){e=w3_checkbox_get(t);tdoa.leaflet?e?(tdoa.day_night.addTo(tdoa.kiwi_map),tdoa.map_layers.push(tdoa.day_night)):tdoa.day_night.remove():tdoa.day_night.setMap(e?tdoa.kiwi_map:null)}}function tdoa_graticule_visible_cb(t,e,o){o||tdoa.graticule&&(e=w3_checkbox_get(t),tdoa.leaflet?e?(tdoa.graticule.addTo(tdoa.cur_map),tdoa.map_layers.push(tdoa.graticule)):tdoa.graticule.remove():tdoa.graticule.setMap(e?tdoa.cur_map:null))}function tdoa_hosts_visible_cb(t,e,o){o||(tdoa.show_hosts=e,tdoa_rebuild_hosts())}function tdoa_refs_visible_cb(t,e,o){o||(tdoa.ref_ids.forEach(function(t){w3_checkbox_set("tdoa.refs_"+t,!!e)}),tdoa.show_refs=e,tdoa_rebuild_refs())}function tdoa_refs_cb(t,e,o){o||tdoa_rebuild_refs()}function tdoa_create_cluster_list(t){var e="";t.getAllChildMarkers().forEach(function(t){var o=t.kiwi_mkr_2_ref_or_host;e+=(""!=e?"\n":"")+o.id}),t._icon.title=e}function tdoa_rebuild_hosts(t){if(tdoa.hosts){tdoa.cur_host_markers&&(tdoa.hosts.forEach(function(t){tdoa.leaflet?(t.mkr.unbindTooltip(),t.mkr.remove(),t.mkr.off()):t.mkr.setMap(null)}),tdoa.leaflet&&tdoa.hosts_clusterer?tdoa.hosts_clusterer.clearLayers():tdoa.hosts_clusterer.clearMarkers());var e=null==t?tdoa.show_hosts:t.show;tdoa.cur_host_markers=[];for(var o=0;o<tdoa.hosts.length;o++){var a=tdoa.hosts[o];a.mkr&&(a.selected?tdoa.leaflet?tdoa_style_marker(a.mkr,a.idx,a.id,"host",tdoa.kiwi_map):a.mkr.setMap(tdoa.kiwi_map):e&&(tdoa.leaflet&&tdoa_style_marker(a.mkr,a.idx,a.id,"host"),tdoa.cur_host_markers.push(a.mkr)))}if(console.log("tdoa_rebuild_hosts cur_host_markers="+tdoa.cur_host_markers.length),tdoa.leaflet){var i=L.markerClusterGroup({maxClusterRadius:tdoa.prev_ui?30:80,spiderLegPolylineOptions:{weight:1.5,color:"white",opacity:1},iconCreateFunction:function(t){return new L.DivIcon({html:"<div><span>"+t.getChildCount()+"</span></div>",className:"marker-cluster id-tdoa-marker-cluster-hosts",iconSize:new L.Point(40,40)})}});i.addLayers(tdoa.cur_host_markers),tdoa.prev_ui?i.on("clustermouseover",function(t){tdoa_create_cluster_list(t.layer)}):(i.on("clustermouseover",function(t){if(tdoa.spiderfied){if(tdoa.spiderfied==t.layer)return;tdoa.spiderfied.unspiderfy(),tdoa.spiderfy_deferred=t.layer}else t.layer.spiderfy(),tdoa.spiderfied=t.layer}),i.on("unspiderfied",function(t){tdoa.spiderfy_deferred?(tdoa.spiderfy_deferred.spiderfy(),tdoa.spiderfied=tdoa.spiderfy_deferred,tdoa.spiderfy_deferred=!1):tdoa.spiderfied=!1})),tdoa.kiwi_map.addLayer(i),tdoa.hosts_clusterer=i}else tdoa.hosts_clusterer=new MarkerClusterer(tdoa.kiwi_map,tdoa.cur_host_markers,{averageCenter:!0,gridSize:30,cssClass:"cl-tdoa-cluster-base cl-tdoa-cluster-kiwi",onMouseoverCluster:function(t,e){var o="";t.cluster_.markers_.forEach(function(t){o+=(""!=o?"\n":"")+t.labelContent}),t.div_.title=o}})}}function tdoa_rebuild_refs(t){if(tdoa.refs){tdoa.cur_ref_markers&&(tdoa.refs_markers.forEach(function(t){tdoa.leaflet?(t.unbindTooltip(),t.remove(),t.off()):t.setMap(null)}),tdoa.leaflet&&tdoa.refs_clusterer?tdoa.refs_clusterer.clearLayers():tdoa.refs_clusterer.clearMarkers());var e=[];if(tdoa.ref_ids.forEach(function(t){w3_checkbox_get("tdoa.refs_"+t)&&e.push(t)}),tdoa.cur_ref_markers=[],null==t?tdoa.show_refs:t.show)for(var o=tdoa.FIRST_REF;o<tdoa.refs.length-1;o++){var a=tdoa.refs[o],i=!1;e.forEach(function(t){a.r.includes(t)&&!i&&(a.selected?tdoa.leaflet?tdoa_style_marker(a.mkr,a.idx,a.id,"ref",tdoa.kiwi_map):a.mkr.setMap(tdoa.kiwi_map):(tdoa.leaflet&&tdoa_style_marker(a.mkr,a.idx,a.id,"ref"),tdoa.cur_ref_markers.push(a.mkr)),i=!0)})}if(tdoa.leaflet){var s=L.markerClusterGroup({maxClusterRadius:tdoa.prev_ui?30:80,spiderLegPolylineOptions:{weight:1.5,color:"white",opacity:1},iconCreateFunction:function(t){return new L.DivIcon({html:"<div><span>"+t.getChildCount()+"</span></div>",className:"marker-cluster id-tdoa-marker-cluster-refs",iconSize:new L.Point(40,40)})}});s.addLayers(tdoa.cur_ref_markers),tdoa.prev_ui?s.on("clustermouseover",function(t){tdoa_create_cluster_list(t.layer)}):(s.on("clustermouseover",function(t){if(tdoa.spiderfied){if(tdoa.spiderfied==t.layer)return;tdoa.spiderfied.unspiderfy(),tdoa.spiderfy_deferred=t.layer}else t.layer.spiderfy(),tdoa.spiderfied=t.layer}),s.on("unspiderfied",function(t){tdoa.spiderfy_deferred?(tdoa.spiderfy_deferred.spiderfy(),tdoa.spiderfied=tdoa.spiderfy_deferred,tdoa.spiderfy_deferred=!1):tdoa.spiderfied=!1})),tdoa.kiwi_map.addLayer(s),tdoa.refs_clusterer=s}else tdoa.refs_clusterer=new MarkerClusterer(tdoa.kiwi_map,tdoa.cur_ref_markers,{averageCenter:!0,gridSize:30,cssClass:"cl-tdoa-cluster-base cl-tdoa-cluster-refs",onMouseoverCluster:function(t,e){var o="";t.cluster_.markers_.forEach(function(t){o+=(""!=o?"\n":"")+t.labelContent}),t.div_.title=o}})}}function tdoa_pan_zoom(t,e,o){tdoa.leaflet?(null==e&&(e=t.getCenter()),-1==o&&(o=t.getZoom()),t.setView(e,o,{duration:0,animate:!1})):(null!=e&&(isArray(e)&&(e=new google.maps.LatLng(e[0],e[1])),t.panTo(e)),-1!=o&&t.setZoom(o))}function tdoa_quick_zoom_cb(t,e,o){if(!o){var a=tdoa.quick_zoom[+e];tdoa_pan_zoom(tdoa.kiwi_map,[a.lat+.1,a.lon],a.z),tdoa_pan_zoom(tdoa.kiwi_map,[a.lat,a.lon],-1)}}function TDoA_help(t){if(t){var e=w3_text("w3-medium w3-bold w3-text-aqua","TDoA Help")+'<br>See the <a href="http://valentfx.com/vanilla/categories/kiwisdr-tdoa-topics" target="_blank">Kiwi forum</a> for more information. If you are getting errors check these <br> common problems:<ul><li>Not zoomed-in far enough. The TDoA process will run out of memory or have problems plotting the maps.</li><li>Not all Kiwis used for sampling have good reception of target signal. Open a connection to each Kiwi by double clicking on its marker to check the reception or by clicking on the speaker icon in the sampling station list.</li><li>Don\'t use Kiwis that are spaced too far apart (i.e. many thousands of km).</li><li>Use minimum IQ-mode passband. Just enough to capture the signal. Use the "p" and "P" keys to narrow/widen the passband. For AM broadcast signals try a narrow passband that only passes the carrier.</li> </ul>Once you configure this extension, and click the "Submit" button, information is sent to the kiwisdr.com server. The server then records 30 seconds of IQ data from the two to six sampling Kiwis specified. The frequency and passband of <b><i>this</i></b> Kiwi will be used for all recording. So make sure it is set correctly before proceeding. Always use the minimum necessary passband and make sure it is symmetrical about the carrier. The current mode (e.g. AM) is ignored as all recording is automatically done in IQ mode. After sampling, the TDoA process will be run on the server. After it finishes a result map will appear. Additional maps may be viewed with the TDoA result menu. You can pan and zoom the resulting maps and click submit again after making any changes. Or use the rerun button to get new maps without resampling. The checkboxes exclude stations during a rerun.<br><br>To begin zoom into the general area of interest on the Kiwi map (note the "quick zoom" menu). Click on the desired blue Kiwi sampling stations. If they are not responding or have had no recent GPS solutions an error message will appear. <br><b>Important:</b> the position and zooming of the Kiwi map determines the same for the resulting TDoA maps. Double click on the blue markers (or speaker icon) to open that Kiwi in a new tab to check if it is receiving the target signal well. You can also manually edit the sampling station list (white fields). <br><br>You can click on the green map markers to set the frequency/passband of some well-known reference stations. The known locations of these stations will be shown in the result maps so you can see how well it agrees with the TDoA solution. Practice with VLF/LF references stations as their ground-wave signals usually give good results. Start with only two sampling stations and check the quality of the solution before adding more. Of course you need three or more stations to generate a localized solution. <br><br>URL parameters: <br>lat:<i>num</i> lon:<i>num</i> z|zoom:<i>num</i> (map control) <br>List of sampling stations and/or reference station IDs. Case-insensitive and can be abbreviated (e.g. "dcf" matches "DCF77", "cyp2" matches "OTHR/CYP2") <br>submit: (start TDoA process) <br>Example: <i>&ext=tdoa,lat:35,lon:35,z:6,cyp2,iu8cri,ur5vib,kuwait,submit:</i> <br>';confirmation_show_content(e,850,650)}return!0}function TDoA_focus(){tdoa.optbar=ext_get_optbar(),ext_set_optbar("optbar-off"),tdoa.pie_size=10,tdoa.pie_cnt=0,tdoa.pie_max=30,tdoa.pie_interval=setInterval(function(){w3_el("id-tdoa-pie")?(kiwi_draw_pie("id-tdoa-pie",tdoa.pie_size,tdoa.pie_cnt/tdoa.pie_max),tdoa.pie_cnt=Math.min(tdoa.pie_cnt+1,tdoa.pie_max)):tdoa.pie_cnt=0},1e3)}function TDoA_blur(){ext_set_data_height(),"optbar-off"==ext_get_optbar()&&ext_set_optbar(tdoa.optbar),kiwi_clearInterval(tdoa.pie_interval)}function TDoA_config_focus(){admin_set_decoded_value("tdoa_id")}function TDoA_config_blur(){}function TDoA_config_html(){var t=ext_get_cfg_param("tdoa_nchans",-1);-1==t&&(t=rx_chans),tdoa.nchans=Math.min(t,rx_chans),tdoa.chans_u={0:"none"};for(var e=1;e<=rx_chans;e++)tdoa.chans_u[e]=e.toFixed(0);var o=w3_inline_percent("w3-container",w3_div("w3-center",w3_select("","Number of simultaneous channels available<br>for connection by the TDoA service","","tdoa_nchans",tdoa.nchans,tdoa.chans_u,"admin_select_cb"),w3_div("w3-margin-T-8 w3-text-black",'If you want to limit incoming connections from the <br> kiwisdr.com TDoA service set this value.<br>These connections are identified in the user lists and logs as: "TDoA_service"')),40,w3_div("w3-text-black"),15,w3_div("",w3_input("||size=12","TDoA ID (alphanumeric and '/', 12 char max)","cfg.tdoa_id","","tdoa_id_cb","TDoA map marker id (e.g. callsign)"),w3_div("w3-margin-T-8 w3-text-black",'When this Kiwi is used as a measurement station for the TDoA service it displays an identifier on a map pin and in the first column of the TDoA extension control panel (when selected). <br><br>You can customize that identifier by setting this field. By default the identifier will be one of two items. Either what appears to be a ham callsign in the the "name" field on the admin page Public tab or the grid square computed from your Kiwis lat/lon.')),40,w3_div("w3-text-black"),5);ext_config_html(tdoa,"tdoa","TDoA","TDoA configuration",o)}function tdoa_id_cb(t,e){e=(e=e.replace(/[^a-zA-Z0-9\/]/g,"")).substr(0,12),w3_set_value(t,e),w3_string_set_cfg_cb(t,e)}function tdoa_chans_cb(t,e,o){o||(tdoa.nchans=+e)}tdoa.url_base="http://"+tdoa.hostname+"/",tdoa.url=tdoa.url_base+"tdoa/",tdoa.url_files=tdoa.url+"files/",tdoa.rep_files=tdoa.hostname+"/tdoa/files";