{"id":10,"date":"2025-09-30T21:50:40","date_gmt":"2025-09-30T21:50:40","guid":{"rendered":"https:\/\/fuck-em.com\/?page_id=10"},"modified":"2025-10-04T18:56:20","modified_gmt":"2025-10-04T18:56:20","slug":"10-2","status":"publish","type":"page","link":"https:\/\/fuck-em.com\/?page_id=10","title":{"rendered":"KML"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"10\" class=\"elementor elementor-10\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-be37612 e-flex e-con-boxed e-con e-parent\" data-id=\"be37612\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-541618f elementor-widget elementor-widget-shortcode\" data-id=\"541618f\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"shortcode.default\">\n\t\t\t\t\t\t\t<div class=\"elementor-shortcode\">        <div id=\"kfs_7c720651-4063-4059-afbf-539ab25d6678\" data-ajax=\"https:\/\/fuck-em.com\/wp-admin\/admin-ajax.php\" data-nonce=\"9899da343e\">\n            <style>\n                #kfs_7c720651-4063-4059-afbf-539ab25d6678 .drop{border:2px dashed #9aa7b0;border-radius:10px;padding:24px;text-align:center;cursor:pointer;background:#fafbfd;transition:all .15s}\n                #kfs_7c720651-4063-4059-afbf-539ab25d6678 .drop.is-over{border-color:#2271b1;background:#f0f7ff}\n                #kfs_7c720651-4063-4059-afbf-539ab25d6678 .queue{list-style:none;padding:0;margin:12px 0 0}\n                #kfs_7c720651-4063-4059-afbf-539ab25d6678 .item{border:1px solid #e2e8f0;border-radius:8px;padding:10px;margin:8px 0;background:#fff}\n                #kfs_7c720651-4063-4059-afbf-539ab25d6678 .name{font-weight:600}\n                #kfs_7c720651-4063-4059-afbf-539ab25d6678 .status{opacity:.85}\n                #kfs_7c720651-4063-4059-afbf-539ab25d6678 .bad{color:#b00020} #kfs_7c720651-4063-4059-afbf-539ab25d6678 .good{color:#155724}\n                #kfs_7c720651-4063-4059-afbf-539ab25d6678 .results{margin-top:6px;font-size:13px;line-height:1.5}\n                #kfs_7c720651-4063-4059-afbf-539ab25d6678 .grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:8px}\n            <\/style>\n            <div class=\"drop\" tabindex=\"0\"><strong>Drag & Drop<\/strong> .kml files here, or click to browse<br><small>(Max 20 MB each)<\/small><\/div>\n            <input type=\"file\" class=\"inp\" accept=\".kml\" multiple hidden>\n            <details style=\"margin-top:10px\"><summary>Options<\/summary>\n                <div class=\"grid\" style=\"margin-top:8px\">\n                    <label>Temp unit (source)\n                        <select class=\"opt-temp\">\n                            <option value=\"C\"  selected='selected'>Celsius<\/option>\n                            <option value=\"F\" >Fahrenheit<\/option>\n                        <\/select>\n                    <\/label>\n                    <label>Move threshold (m\/s)<input type=\"number\" step=\"0.1\" class=\"opt-move\" value=\"0.5\"><\/label>\n                    <label>Landing speed \u2264 (m\/s)<input type=\"number\" step=\"0.1\" class=\"opt-landspd\" value=\"1.5\"><\/label>\n                    <label>Ground window (m)<input type=\"number\" step=\"0.1\" class=\"opt-ground\" value=\"10\"><\/label>\n                    <label>Distance decimals<input type=\"number\" min=\"0\" step=\"1\" class=\"opt-prec\" value=\"1\"><\/label>\n                    <label>Speed decimals<input type=\"number\" min=\"0\" step=\"1\" class=\"opt-sd\" value=\"1\"><\/label>\n                <\/div>\n            <\/details>\n            <ul class=\"queue\"><\/ul>\n        <\/div>\n        <script>\n        (function(){\n            const root=document.getElementById('kfs_7c720651-4063-4059-afbf-539ab25d6678');\n            const drop=root.querySelector('.drop'), inp=root.querySelector('.inp'), list=root.querySelector('.queue');\n            const ajax=root.dataset.ajax, nonce=root.dataset.nonce, maxMB=20;\n            const $=(s)=>root.querySelector(s);\n            const human=(b)=>{const u=['B','KB','MB','GB'];let i=0,n=b;while(n>=1024&&i<u.length-1){n\/=1024;i++;}return n.toFixed(n>=10?0:1)+' '+u[i];};\n            function add(file){const li=document.createElement('li'); li.className='item'; li.innerHTML='<div class=\"name\"><\/div><div class=\"status\">Queued<\/div><div class=\"results\"><\/div>'; li.querySelector('.name').textContent=file.name+' ('+human(file.size)+')'; list.appendChild(li); return li;}\n            function ok(li,html){const el=li.querySelector('.status'); el.innerHTML=html; el.className='status good';}\n            function bad(li,html){const el=li.querySelector('.status'); el.innerHTML=html; el.className='status bad';}\n            const fmtHMS=(s)=>{if(s==null)return'\u2014';s=parseInt(s,10);const h=Math.floor(s\/3600),m=Math.floor((s%3600)\/60),x=s%60;return(`${h}`.padStart(2,'0')+':'+`${m}`.padStart(2,'0')+':'+`${x}`.padStart(2,'0'));};\n            const fmtDate=(s)=>{if(!s)return '\u2014'; const d=new Date(Number(s)*1000); return isNaN(d.getTime()) ? '\u2014' : d.toLocaleString();};\n            function render(li,item,opts){\n                if(!item||!item.stats) return;\n                const s=item.stats, p=parseInt(opts.precision||1,10), sd=parseInt(opts.speed_decimals||1,10);\n                const fmt=(v,d)=> (v==null?'\u2014':Number(v).toLocaleString(undefined,{maximumFractionDigits:d,minimumFractionDigits:d}));\n                const spd=(o)=>(!o||o.mph==null?'\u2014':`${fmt(o.mph,sd)} mph (${fmt(o.kt,sd)} kt \/ ${fmt(o.kph,sd)} km\/h)`);\n                const mlink=(la,lo)=> la==null||lo==null ? '' : ` <a href=\"https:\/\/www.google.com\/maps\/search\/?api=1&query=${encodeURIComponent(la+','+lo)}\" target=\"_blank\" rel=\"noopener\">Map<\/a>`;\n                const earth=item.url?{\n                    earth_ios:`comgoogleearth:\/\/?url=${encodeURIComponent(item.url)}`,\n                    earth_android:`googleearth:\/\/?url=${encodeURIComponent(item.url)}`,\n                    maps_web:`https:\/\/www.google.com\/maps?q=${encodeURIComponent(item.url)}`\n                }:null;\n\n                let link=item.link?`<a href=\"${item.link}\">Attachment #${item.id}<\/a>`:`Attachment #${item.id}`; if(item.url) link+=` &middot; <a href=\"${item.url}\" target=\"_blank\" rel=\"noopener\">Download<\/a>`;\n                if(earth){ link+=` &middot; <a href=\"${earth.maps_web}\" target=\"_blank\" rel=\"noopener\">Maps<\/a> &middot; <a href=\"${earth.earth_ios}\">Earth iOS<\/a> &middot; <a href=\"${earth.earth_android}\">Earth Android<\/a>`; }\n\n                li.querySelector('.results').innerHTML=`\n                    <div><strong>${link}<\/strong><\/div>\n                    <div>Duration: ${fmtHMS(s.duration_s)} ${s.duration_h==null?'':'('+fmt(s.duration_h,2)+' h)'}<\/div>\n                    <div>Start: ${(s.start_place||s.start_name||(`${s.start_lat}, ${s.start_lon}`))}${mlink(s.start_lat,s.start_lon)}<\/div>\n                    <div>Launch Detected: ${s.launch_detected?'Yes':'No'}<\/div>\n                    ${s.launch_detected?`<div>Launch: ${(s.launch_place||s.launch_name||(`${s.launch_lat}, ${s.launch_lon}`))}${mlink(s.launch_lat,s.launch_lon)} at ${fmtDate(s.launch_ts)}, ${fmt(s.launch_alt_ft,0)} ft (${fmt(s.launch_alt_m,0)} m)<\/div>`:''}\n                    <div>End: ${(s.end_place||s.end_name||(`${s.end_lat}, ${s.end_lon}`))}${mlink(s.end_lat,s.end_lon)}<\/div>\n                    <div>Max Altitude: ${fmt(s.max_alt_ft,0)} ft (${fmt(s.max_alt_m,0)} m)<\/div>\n                    <div>Total Distance: ${fmt(s.total_mi,p)} mi (${fmt(s.total_km,p)} km)<\/div>\n                    <div>Max TOPT: ${s.max_topt_f==null?'\u2014':fmt(s.max_topt_f,1)+' \u00b0F ('+fmt(s.max_topt_c,1)+' \u00b0C)'}<\/div>\n                    <div>Avg AMBT: ${s.avg_ambient_f==null?'\u2014':fmt(s.avg_ambient_f,1)+' \u00b0F ('+fmt(s.avg_ambient_c,1)+' \u00b0C)'}<\/div>\n                    <div>Max Speed: ${spd(s.max_speed)}<\/div>\n                    <div>Takeoff Speed: ${spd(s.takeoff_speed)}<\/div>\n                    <div>Last Landing Speed: ${spd(s.last_landing_speed)}<\/div>\n                    <div>Landings: ${s.landing_count??'\u2014'}<\/div>\n                    <div>Max Ascending: ${s.max_climb_fpm==null?'\u2014':Number(s.max_climb_fpm).toLocaleString(undefined,{maximumFractionDigits:0})+' fpm'}<\/div>\n                    <div>Max Descending: ${s.max_sink_fpm==null?'\u2014':Number(s.max_sink_fpm).toLocaleString(undefined,{maximumFractionDigits:0})+' fpm'}<\/div>\n                    <div>Avg Vertical: ${s.avg_vertical_fpm==null?'\u2014':Number(s.avg_vertical_fpm).toLocaleString(undefined,{maximumFractionDigits:0})+' fpm'}<\/div>\n                    <div>Points: ${s.points??'\u2014'}<\/div>`;\n            }\n            async function uploadOne(file){\n                const li=add(file), ext=file.name.split('.').pop().toLowerCase();\n                if(ext!=='kml'){bad(li,'Only .kml files are allowed.'); return;}\n                if(file.size>maxMB*1024*1024){bad(li,'File exceeds max size.'); return;}\n                const opts={ temp_unit:$('.opt-temp')?.value||'C', move_thresh:$('.opt-move')?.value||'0.5', landing_speed_thresh:$('.opt-landspd')?.value||'1.5', landing_alt_window:$('.opt-ground')?.value||'10', precision:$('.opt-prec')?.value||'1', speed_decimals:$('.opt-sd')?.value||'1' };\n                const fd=new FormData(); fd.append('action','kfs_multi_upload'); fd.append('nonce','9899da343e');\n                fd.append('temp_unit',opts.temp_unit); fd.append('move_thresh',opts.move_thresh); fd.append('landing_speed_thresh',opts.landing_speed_thresh); fd.append('landing_alt_window',opts.landing_alt_window); fd.append('files[]',file,file.name);\n                try{\n                    const xhr=new XMLHttpRequest(); const done=new Promise((res,rej)=>{xhr.onreadystatechange=function(){if(xhr.readyState===4){if(xhr.status>=200&&xhr.status<300)res(xhr.responseText);else rej(new Error('HTTP '+xhr.status));}}});\n                    xhr.open('POST',ajax,true); xhr.send(fd); const text=await done; const data=JSON.parse(text);\n                    if(!data.success){bad(li,data.data?String(data.data):'Upload failed.');return;}\n                    const item=(data.data.items&&data.data.items[0])?data.data.items[0]:null;\n                    if(!item){bad(li,'No result.');return;} if(item.error){bad(li,item.error);return;}\n                    ok(li,'Parsed & saved.'); render(li,item,opts);\n                }catch(err){bad(li,'Error: '+(err?.message||'Unknown'));}\n            }\n            function handle(files){[...files].reduce((p,f)=>p.then(()=>uploadOne(f)), Promise.resolve());}\n            ['dragenter','dragover'].forEach(ev=>drop.addEventListener(ev,e=>{e.preventDefault();e.stopPropagation();drop.classList.add('is-over');}));\n            ['dragleave','drop'].forEach(ev=>drop.addEventListener(ev,e=>{e.preventDefault();e.stopPropagation();drop.classList.remove('is-over');}));\n            drop.addEventListener('drop',e=>{const dt=e.dataTransfer; if(dt?.files?.length) handle(dt.files);});\n            drop.addEventListener('click',()=>inp.click()); inp.addEventListener('change',()=>{if(inp.files?.length) handle(inp.files); inp.value='';});\n            drop.addEventListener('keydown',e=>{if(e.key==='Enter'||e.key===' '){e.preventDefault();inp.click();}});\n        })();\n        <\/script>\n        <\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-10","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/fuck-em.com\/index.php?rest_route=\/wp\/v2\/pages\/10","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fuck-em.com\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/fuck-em.com\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/fuck-em.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fuck-em.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=10"}],"version-history":[{"count":13,"href":"https:\/\/fuck-em.com\/index.php?rest_route=\/wp\/v2\/pages\/10\/revisions"}],"predecessor-version":[{"id":419,"href":"https:\/\/fuck-em.com\/index.php?rest_route=\/wp\/v2\/pages\/10\/revisions\/419"}],"wp:attachment":[{"href":"https:\/\/fuck-em.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=10"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}