{"id":231,"date":"2026-09-19T11:06:45","date_gmt":"2026-09-19T21:06:45","guid":{"rendered":"https:\/\/mana-corp.com\/?page_id=231"},"modified":"2026-09-19T11:07:21","modified_gmt":"2026-09-19T21:07:21","slug":"elementor-231","status":"publish","type":"page","link":"https:\/\/mana-corp.com\/?page_id=231","title":{"rendered":"Elementor #231"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-post\" data-elementor-id=\"231\" class=\"elementor elementor-231\">\n\t\t\t\t<div class=\"elementor-element elementor-element-46ccf2d e-flex e-con-boxed e-con e-parent\" data-id=\"46ccf2d\" 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-39b7b85 elementor-widget elementor-widget-html\" data-id=\"39b7b85\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n<title>Tahiti Driver - MapCN Booking<\/title>\n<script src=\"https:\/\/unpkg.com\/maplibre-gl@4.7.1\/dist\/maplibre-gl.js\"><\/script>\n<link href=\"https:\/\/unpkg.com\/maplibre-gl@4.7.1\/dist\/maplibre-gl.css\" rel=\"stylesheet\">\n<style>\n:root{--red:#E61E1E;--bg:#faf7f2;--dark:#111}\n*{box-sizing:border-box;margin:0;padding:0;font-family:system-ui,-apple-system,Segoe UI,Roboto}\nbody{background:var(--bg);color:var(--dark)}\nheader{display:flex;gap:8px;padding:10px;background:var(--red);color:white;position:sticky;top:0;z-index:10}\nheader button{flex:1;padding:10px;border:0;border-radius:10px;background:rgba(255,255,255,.2);color:white;font-weight:700}\nheader button.active{background:white;color:var(--red)}\n.topbar{display:flex;flex-wrap:wrap;gap:6px;padding:10px;background:white;border-bottom:1px solid #eee}\n.topbar select,input{padding:8px 10px;border-radius:8px;border:1px solid #ddd}\n#search{flex:1 1 200px}\n.map{width:100%;height:62vh}\n.card{padding:10px;background:white;margin:10px;border-radius:14px;box-shadow:0 4px 12px rgba(0,0,0,.08)}\n.popup-btn{display:flex;gap:6px;margin-top:8px}\n.popup-btn button{flex:1;padding:8px;border-radius:8px;border:0;font-weight:700;cursor:pointer}\n.btn-chat{background:#25D366;color:white}\n.btn-visio{background:#111;color:white}\n.btn-go{background:var(--red);color:white}\n.fare-row{display:flex;gap:6px;align-items:center;padding:8px;border:1px solid #eee;border-radius:8px;margin:6px 0;background:white}\n.fare-row input{width:90px}\n.small{font-size:12px;color:#666}\n#toast{position:fixed;bottom:20px;left:50%;transform:translateX(-50%);background:#111;color:white;padding:10px 14px;border-radius:20px;display:none;z-index:99}\n<\/style>\n<\/head>\n<body>\n<header>\n<button id=\"tabClient\" class=\"active\">\ud83c\udf3a CLIENT BOOKING<\/button>\n<button id=\"tabAdmin\">\u2699\ufe0f FARES SIMULATOR (Admin)<\/button>\n<\/header>\n\n<!-- PAGE 1 -->\n<div id=\"pageClient\">\n<div class=\"topbar\">\n<select id=\"service\">\n<option value=\"taxi\">Taxi - Quick Ride<\/option>\n<option value=\"private\">Private Ride - Hourly<\/option>\n<option value=\"half_morning\">Circle Island HALF - 9AM-1PM<\/option>\n<option value=\"half_afternoon\">Circle Island HALF - 1PM-5PM<\/option>\n<option value=\"full\">Circle Island FULL - 9AM-5PM<\/option>\n<\/select>\n<select id=\"pax\"><option>1 pax<\/option><option>2 pax<\/option><option>3 pax<\/option><option>4 pax<\/option><option>5 pax<\/option><option>6 pax<\/option><option>7 pax<\/option><option selected>8 pax max<\/option><\/select>\n<input id=\"search\" placeholder=\"Search place, hotel, beach... (Nominatim)\">\n<button id=\"btnLocate\" style=\"padding:8px 12px;border-radius:8px;border:0;background:var(--red);color:white\">\ud83d\udccd My location<\/button>\n<\/div>\n<div id=\"map\" class=\"map\"><\/div>\n<div class=\"card small\">Tap any location on map \u2192 popup shows Chat \/ Visio \/ GO. All tiles are loaded via MapLibre (OpenFreeMap). Amenities auto-loaded around you.<\/div>\n<div class=\"card\" id=\"selectedInfo\">No location selected yet.<\/div>\n<\/div>\n\n<!-- PAGE 2 -->\n<div id=\"pageAdmin\" style=\"display:none\">\n<div class=\"topbar\">\n<input id=\"fareName\" placeholder=\"Fare name e.g. Airport->Papeete\">\n<input id=\"fareFlat\" type=\"number\" placeholder=\"Flat $\" value=\"0\">\n<input id=\"farePerKm\" type=\"number\" placeholder=\"$\/km\" value=\"0\">\n<input id=\"farePerHour\" type=\"number\" placeholder=\"$\/h\" value=\"100\">\n<input id=\"fareMin\" type=\"number\" placeholder=\"Min $\" value=\"400\">\n<button id=\"btnAddFare\" style=\"padding:8px 12px;background:var(--red);color:white;border:0;border-radius:8px\">+ Add Fare<\/button>\n<\/div>\n<div id=\"map2\" class=\"map\" style=\"height:50vh\"><\/div>\n<div class=\"card\">\n<b>Fares List (stored locally in browser)<\/b>\n<div id=\"faresList\"><\/div>\n<div class=\"small\" style=\"margin-top:8px\">Click 2 points on admin map to simulate route. It will calculate OSRM driving distance + duration, then apply ALL fares and show MINIMUM client pays.<\/div>\n<div id=\"simResult\" class=\"card\" style=\"background:#fff7ed\"><\/div>\n<\/div>\n<\/div>\n\n<div id=\"toast\"><\/div>\n\n<script>\n\/\/ --- HIDDEN WHATSAPP (never displayed) ---\nconst _w = atob(\"Njg5ODk2NjAwMDM=\"); \/\/ your number encoded\nconst WA_BASE = \"https:\/\/wa.me\/\" + _w;\nconst styleUrl = \"https:\/\/tiles.openfreemap.org\/styles\/liberty\";\nlet selectedLngLat = null;\nlet selectedAddress = \"Custom location\";\n\nconst map = new maplibregl.Map({ container: 'map', style: styleUrl, center: [-149.4068, -17.6509], zoom: 11 });\nmap.addControl(new maplibregl.NavigationControl(), 'top-right');\nconst map2 = new maplibregl.Map({ container: 'map2', style: styleUrl, center: [-149.4068, -17.6509], zoom: 11 });\nmap2.addControl(new maplibregl.NavigationControl(), 'top-right');\n\nfunction toast(m){ const t=document.getElementById('toast'); t.textContent=m; t.style.display='block'; setTimeout(()=>t.style.display='none',3000); }\n\nasync function searchPlace(q){\n if(!q) return;\n const url = `https:\/\/nominatim.openstreetmap.org\/search?format=json&q=${encodeURIComponent(q)}&limit=5&viewbox=-149.9,-17.3,-149.0,-18.0&bounded=1`;\n const r = await fetch(url); const data = await r.json();\n if(data[0]){ const lon=parseFloat(data[0].lon), lat=parseFloat(data[0].lat); map.flyTo({center:[lon,lat], zoom:14}); selectedLngLat=[lon,lat]; selectedAddress=data[0].display_name; showPopup(lon,lat,selectedAddress); document.getElementById('selectedInfo').innerHTML = `<b>Selected:<\/b> ${selectedAddress}`; }\n}\ndocument.getElementById('search').addEventListener('change', e=>searchPlace(e.target.value));\ndocument.getElementById('search').addEventListener('keydown', e=>{ if(e.key==='Enter') searchPlace(e.target.value); });\n\nasync function reverse(lng,lat){\n try{ const url=`https:\/\/nominatim.openstreetmap.org\/reverse?format=json&lon=${lng}&lat=${lat}`; const r=await fetch(url); const j=await r.json(); return j.display_name || `${lat.toFixed(5)}, ${lng.toFixed(5)}`; }catch{ return `${lat.toFixed(5)}, ${lng.toFixed(5)}`; }\n}\n\nfunction buildCard(mode, locName){\n const svc=document.getElementById('service').value;\n const pax=document.getElementById('pax').value;\n const svcLabel=document.getElementById('service').options[document.getElementById('service').selectedIndex].text;\n return `\ud83c\udf3a NEW RIDE REQUEST - Tahiti Driver\n\ud83d\udccd Location: ${locName}\n\ud83d\udd17 https:\/\/maps.google.com\/?q=${selectedLngLat[1]},${selectedLngLat[0]}\n\ud83d\ude95 Service: ${svcLabel}\n\ud83d\udc65 Pax: ${pax}\n\u23f0 Time: ${svc.includes('half')?'4H (9-13 or 13-17)':svc==='full'?'8H (9-17)':'ASAP \/ On demand'}\n\ud83d\udcb0 Rate: $100\/h min 4H = $400 min | Drinks + fruits free\nMode: ${mode}`.trim();\n}\nfunction openWA(text){ const url = WA_BASE + \"?text=\" + encodeURIComponent(text); window.open(url, \"_blank\"); }\n\nfunction showPopup(lng,lat,addr){\n selectedLngLat=[lng,lat]; selectedAddress=addr;\n const html = `<div style=\"min-width:200px\"><b>${addr.slice(0,80)}<\/b><div class=\"popup-btn\">\n <button class=\"btn-chat\" id=\"bChat\">\ud83d\udcac CHAT<\/button>\n <button class=\"btn-visio\" id=\"bVisio\">\ud83d\udcf9 VISIO<\/button>\n <button class=\"btn-go\" id=\"bGo\">GO \ud83d\ude80<\/button>\n <\/div><\/div>`;\n new maplibregl.Popup().setLngLat([lng,lat]).setHTML(html).addTo(map);\n setTimeout(()=>{\n   document.getElementById('bChat')?.addEventListener('click',()=>{ openWA(buildCard(\"CHAT request\", addr)); });\n   document.getElementById('bVisio')?.addEventListener('click',()=>{\n     const room=\"TahitiDriver-\"+Math.random().toString(36).slice(2,8);\n     const jitsi=`https:\/\/meet.jit.si\/${room}`;\n     openWA(buildCard(`VISIO request - Join: ${jitsi}`, addr)); window.open(jitsi,\"_blank\");\n   });\n   document.getElementById('bGo')?.addEventListener('click',()=>{ openWA(buildCard(\"GO - BOOKING CARD\", addr)); toast(\"Booking card sent!\"); });\n },200);\n}\n\nmap.on('click', async (e)=>{\n const lng=e.lngLat.lng, lat=e.lngLat.lat; const addr=await reverse(lng,lat);\n document.getElementById('selectedInfo').innerHTML = `<b>Selected:<\/b> ${addr}<br><small>${lat.toFixed(5)}, ${lng.toFixed(5)}<\/small>`;\n showPopup(lng,lat,addr); loadAmenities(lng,lat);\n});\ndocument.getElementById('btnLocate').addEventListener('click',()=>{\n navigator.geolocation.getCurrentPosition(pos=>{\n   const lng=pos.coords.longitude, lat=pos.coords.latitude;\n   map.flyTo({center:[lng,lat], zoom:15});\n   reverse(lng,lat).then(a=>{ showPopup(lng,lat,a); });\n });\n});\n\nlet amenityMarkers=[];\nasync function loadAmenities(lng,lat){\n const query = `[out:json][timeout:25];(node[\"tourism\"~\"viewpoint|attraction|museum\"](around:3000,${lat},${lng});node[\"natural\"~\"beach|waterfall\"](around:3000,${lat},${lng}););out 15;`;\n try{\n   const r=await fetch(\"https:\/\/overpass-api.de\/api\/interpreter\",{method:\"POST\", body:query});\n   const j=await r.json(); amenityMarkers.forEach(m=>m.remove()); amenityMarkers=[];\n   j.elements.forEach(el=>{\n     if(!el.lat) return;\n     const m=new maplibregl.Marker({color:\"#E61E1E\"}).setLngLat([el.lon,el.lat]).addTo(map);\n     const name=el.tags.name||\"POI\";\n     m.getElement().addEventListener('click', async()=>{ const addr=await reverse(el.lon,el.lat); showPopup(el.lon,el.lat, `${name} - ${addr}`); });\n     amenityMarkers.push(m);\n   });\n }catch(e){}\n}\n\ndocument.getElementById('tabClient').onclick=()=>{\n document.getElementById('pageClient').style.display='block';\n document.getElementById('pageAdmin').style.display='none';\n document.getElementById('tabClient').classList.add('active');\n document.getElementById('tabAdmin').classList.remove('active');\n map.resize();\n};\ndocument.getElementById('tabAdmin').onclick=()=>{\n const pass=prompt(\"Admin password? (hint: tiki)\"); if(pass!==\"tiki\"){ toast(\"Wrong password\"); return; }\n document.getElementById('pageClient').style.display='none';\n document.getElementById('pageAdmin').style.display='block';\n document.getElementById('tabAdmin').classList.add('active');\n document.getElementById('tabClient').classList.remove('active');\n map2.resize(); renderFares();\n};\n\nlet fares = JSON.parse(localStorage.getItem(\"tahiti_fares_v1\")||\"[]\");\nif(fares.length===0){\n fares=[{id:1,name:\"Circle Half Day (4h)\",flat:0,perKm:0,perHour:100,min:400},{id:2,name:\"Circle Full Day (8h)\",flat:0,perKm:0,perHour:100,min:800},{id:3,name:\"Taxi Base Papeete\",flat:25,perKm:2.5,perHour:0,min:25}];\n localStorage.setItem(\"tahiti_fares_v1\", JSON.stringify(fares));\n}\nfunction renderFares(){\n const c=document.getElementById('faresList'); c.innerHTML=\"\";\n fares.forEach(f=>{\n   const d=document.createElement('div'); d.className='fare-row';\n   d.innerHTML=`<b style=\"flex:1\">${f.name}<\/b><span>flat $${f.flat} + $${f.perKm}\/km + $${f.perHour}\/h | min $${f.min}<\/span><button style=\"background:#111;color:white;border:0;border-radius:6px;padding:4px 8px\" onclick=\"delFare(${f.id})\">Delete<\/button>`;\n   c.appendChild(d);\n });\n}\nwindow.delFare=(id)=>{ fares=fares.filter(f=>f.id!==id); localStorage.setItem(\"tahiti_fares_v1\", JSON.stringify(fares)); renderFares(); };\ndocument.getElementById('btnAddFare').onclick=()=>{\n const name=document.getElementById('fareName').value||\"Custom fare\";\n const flat=parseFloat(document.getElementById('fareFlat').value)||0;\n const perKm=parseFloat(document.getElementById('farePerKm').value)||0;\n const perHour=parseFloat(document.getElementById('farePerHour').value)||0;\n const min=parseFloat(document.getElementById('fareMin').value)||0;\n fares.push({id:Date.now(),name,flat,perKm,perHour,min});\n localStorage.setItem(\"tahiti_fares_v1\", JSON.stringify(fares)); renderFares(); toast(\"Fare added\");\n};\n\nlet simPoints=[];\nmap2.on('click', async e=>{\n simPoints.push([e.lngLat.lng, e.lngLat.lat]);\n if(simPoints.length===1){ new maplibregl.Marker({color:\"#111\"}).setLngLat(simPoints[0]).addTo(map2); toast(\"Click destination\"); }\n else if(simPoints.length===2){\n   new maplibregl.Marker({color:\"#E61E1E\"}).setLngLat(simPoints[1]).addTo(map2);\n   const url=`https:\/\/router.project-osrm.org\/route\/v1\/driving\/${simPoints[0][0]},${simPoints[0][1]};${simPoints[1][0]},${simPoints[1][1]}?overview=full&geometries=geojson`;\n   try{\n     const r=await fetch(url); const j=await r.json();\n     if(j.routes && j.routes[0]){\n       const route=j.routes[0]; const distKm=route.distance\/1000; const durH=route.duration\/3600;\n       if(map2.getSource('route')){ map2.removeLayer('route'); map2.removeSource('route'); }\n       map2.addSource('route',{type:'geojson',data:{type:'Feature',geometry:route.geometry}});\n       map2.addLayer({id:'route',type:'line',source:'route',paint:{'line-color':'#E61E1E','line-width':4}});\n       let results=fares.map(f=>{\n         let price=f.flat + (f.perKm*distKm) + (f.perHour*durH);\n         if(f.min) price=Math.max(price,f.min);\n         if(f.name.toLowerCase().includes(\"half\")) price=Math.max(price,400);\n         if(f.name.toLowerCase().includes(\"full\")) price=Math.max(price,800);\n         return {...f, calc:price};\n       });\n       let minFare=Math.min(...results.map(r=>r.calc));\n       document.getElementById('simResult').innerHTML=`<b>Distance:<\/b> ${distKm.toFixed(1)} km | <b>Duration:<\/b> ${(durH*60).toFixed(0)} min<br><br>`+results.map(r=>`\u2022 ${r.name}: $${r.calc.toFixed(2)}`).join(\"<br>\")+`<br><br><b style=\"font-size:18px\">MINIMUM CLIENT PAYS: $${minFare.toFixed(2)} USD<\/b>`;\n     }\n   }catch(err){ toast(\"Routing failed\"); }\n   simPoints=[];\n }\n});\n<\/script>\n<\/body>\n<\/html>\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":"<p>Tahiti Driver &#8211; MapCN Booking \ud83c\udf3a CLIENT BOOKING \u2699\ufe0f FARES SIMULATOR (Admin) Taxi &#8211; Quick RidePrivate Ride &#8211; HourlyCircle Island HALF &#8211; 9AM-1PMCircle Island HALF &#8211; 1PM-5PMCircle Island FULL &#8211; 9AM-5PM 1 pax2 pax3 pax4 pax5 pax6 pax7 pax8 pax max \ud83d\udccd My location Tap any location on map \u2192 popup shows Chat \/ Visio [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-231","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/mana-corp.com\/index.php?rest_route=\/wp\/v2\/pages\/231","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mana-corp.com\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/mana-corp.com\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/mana-corp.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mana-corp.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=231"}],"version-history":[{"count":4,"href":"https:\/\/mana-corp.com\/index.php?rest_route=\/wp\/v2\/pages\/231\/revisions"}],"predecessor-version":[{"id":235,"href":"https:\/\/mana-corp.com\/index.php?rest_route=\/wp\/v2\/pages\/231\/revisions\/235"}],"wp:attachment":[{"href":"https:\/\/mana-corp.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=231"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}