{"id":1572,"date":"2026-11-05T20:08:14","date_gmt":"2026-11-05T20:08:14","guid":{"rendered":"https:\/\/timeless-airporttaxi.de\/cleaning\/?page_id=1572"},"modified":"2026-11-07T17:36:24","modified_gmt":"2026-11-07T17:36:24","slug":"book-online","status":"publish","type":"page","link":"https:\/\/timeless-airporttaxi.de\/cleaning\/book-online\/","title":{"rendered":"Book Online"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"1572\" class=\"elementor elementor-1572\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-ce65efd e-flex e-con-boxed e-con e-parent\" data-id=\"ce65efd\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;,&quot;ekit_has_onepagescroll_dot&quot;:&quot;yes&quot;}\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-5b953d8 elementor-widget elementor-widget-html\" data-id=\"5b953d8\" data-element_type=\"widget\" data-e-type=\"widget\" data-settings=\"{&quot;ekit_we_effect_on&quot;:&quot;none&quot;}\" data-widget_type=\"html.default\">\n\t\t\t\t\t\r\n<!-- =========================================================\r\n AMSTERDAM PREMIUM TRAVEL\r\n TAXI FARE CALCULATOR + OPENSTREETMAP + OSRM\r\n + FLUENT FORMS ID 9\r\n GOOGLE TRANSLATE COMPATIBLE FIELD MAPPING\r\n========================================================= -->\r\n\r\n<link rel=\"stylesheet\"\r\n      href=\"https:\/\/cdn.jsdelivr.net\/npm\/leaflet@1.9.4\/dist\/leaflet.css\">\r\n\r\n<link rel=\"stylesheet\"\r\n      href=\"https:\/\/fonts.googleapis.com\/css2?family=Montserrat:wght@400;500;600;700&display=swap\">\r\n\r\n<style>\r\n#apt-calculator {\r\n  --gold:#D0A368;\r\n  --light-gold:#D0A368;\r\n  --black:#0B0B0C;\r\n  --charcoal:#202124;\r\n  --grey:#A8A8A8;\r\n  background:var(--black);\r\n  color:#fff;\r\n  font:400 16px\/1.65 Montserrat,Arial,sans-serif;\r\n  padding:70px 22px;\r\n  width:100%;\r\n  box-sizing:border-box;\r\n}\r\n\r\n#apt-calculator *,\r\n#apt-calculator *:before,\r\n#apt-calculator *:after {\r\n  box-sizing:border-box;\r\n}\r\n\r\n#apt-calculator .apt-in {\r\n  max-width:1280px;\r\n  margin:auto;\r\n}\r\n\r\n#apt-calculator .apt-eye {\r\n  display:flex;\r\n  align-items:center;\r\n  gap:14px;\r\n  color:var(--gold);\r\n  font-size:11px;\r\n  font-weight:600;\r\n  letter-spacing:.24em;\r\n  text-transform:uppercase;\r\n  margin-bottom:20px;\r\n}\r\n\r\n#apt-calculator .apt-eye:before {\r\n  content:\"\";\r\n  width:38px;\r\n  height:1px;\r\n  background:var(--gold);\r\n}\r\n\r\n#apt-calculator h2 {\r\n  font:400 clamp(36px,5vw,58px)\/1.08 'Montserrat',Arial,sans-serif;\r\n  color:#fff;\r\n  margin:0 0 14px;\r\n}\r\n\r\n#apt-calculator h2 em {\r\n  color:var(--light-gold);\r\n}\r\n\r\n#apt-calculator .apt-lead {\r\n  color:var(--grey);\r\n  max-width:58ch;\r\n  margin:0 0 38px;\r\n}\r\n\r\n#apt-calculator .apt-grid {\r\n  display:grid;\r\n  grid-template-columns:minmax(320px,430px) minmax(0,1fr);\r\n  border:1px solid rgba(208,163,104,.35);\r\n  width:100%;\r\n  align-items:stretch;\r\n}\r\n\r\n#apt-calculator .apt-form {\r\n  background:var(--charcoal);\r\n  padding:clamp(22px,3vw,40px);\r\n  display:grid;\r\n  gap:20px;\r\n  align-content:start;\r\n  margin:0;\r\n  min-width:0;\r\n}\r\n\r\n#apt-calculator label,\r\n#apt-calculator legend {\r\n  display:block;\r\n  color:var(--light-gold);\r\n  font-size:11px;\r\n  font-weight:600;\r\n  letter-spacing:.15em;\r\n  text-transform:uppercase;\r\n  margin:0 0 9px;\r\n  padding:0;\r\n}\r\n\r\n#apt-calculator fieldset {\r\n  border:0;\r\n  padding:0;\r\n  margin:0;\r\n  min-width:0;\r\n}\r\n\r\n#apt-calculator .apt-row {\r\n  display:flex;\r\n  width:100%;\r\n  min-width:0;\r\n}\r\n\r\n#apt-calculator .apt-address-input,\r\n#apt-calculator input[type=\"datetime-local\"] {\r\n  display:block;\r\n  width:100%;\r\n  max-width:100%;\r\n  min-width:0;\r\n  background:var(--black);\r\n  color:#fff;\r\n  border:1px solid #505056;\r\n  border-radius:0;\r\n  padding:13px 14px;\r\n  font:400 14px\/1.5 Montserrat,Arial,sans-serif;\r\n  color-scheme:dark;\r\n}\r\n\r\n#apt-calculator .apt-address-input {\r\n  min-height:48px;\r\n  height:48px;\r\n  max-height:140px;\r\n  resize:none;\r\n  overflow-x:hidden;\r\n  overflow-y:hidden;\r\n  white-space:pre-wrap;\r\n  overflow-wrap:anywhere;\r\n  word-break:break-word;\r\n}\r\n\r\n#apt-calculator input:focus-visible,\r\n#apt-calculator textarea:focus-visible,\r\n#apt-calculator button:focus-visible,\r\n#apt-calculator a:focus-visible {\r\n  outline:2px solid var(--gold);\r\n  outline-offset:2px;\r\n}\r\n\r\n#apt-calculator .apt-find {\r\n  flex:0 0 auto;\r\n  background:var(--gold);\r\n  color:var(--black);\r\n  border:1px solid var(--gold);\r\n  padding:0 15px;\r\n  font:600 11px Montserrat,Arial,sans-serif;\r\n  letter-spacing:.1em;\r\n  text-transform:uppercase;\r\n  cursor:pointer;\r\n}\r\n\r\n#apt-calculator .apt-find:disabled {\r\n  opacity:.55;\r\n  cursor:wait;\r\n}\r\n\r\n#apt-calculator .apt-sug {\r\n  list-style:none;\r\n  margin:6px 0 0;\r\n  padding:0;\r\n  border:1px solid #505056;\r\n  background:var(--black);\r\n  max-height:230px;\r\n  overflow:auto;\r\n}\r\n\r\n#apt-calculator .apt-sug:empty {\r\n  display:none;\r\n}\r\n\r\n#apt-calculator .apt-sug button {\r\n  display:block;\r\n  width:100%;\r\n  text-align:left;\r\n  background:transparent;\r\n  border:0;\r\n  border-bottom:1px solid #303035;\r\n  color:#fff;\r\n  padding:12px 14px;\r\n  font:400 13px\/1.5 Montserrat,Arial,sans-serif;\r\n  cursor:pointer;\r\n  overflow-wrap:anywhere;\r\n  word-break:break-word;\r\n}\r\n\r\n#apt-calculator .apt-sug button:hover {\r\n  background:rgba(208,163,104,.15);\r\n}\r\n\r\n#apt-calculator .apt-sug .apt-none {\r\n  padding:12px 14px;\r\n  color:var(--grey);\r\n  font-size:13px;\r\n}\r\n\r\n#apt-calculator .apt-ok {\r\n  display:none;\r\n  color:var(--light-gold);\r\n  font-size:12px;\r\n  margin-top:7px;\r\n}\r\n\r\n#apt-calculator .apt-help {\r\n  color:var(--grey);\r\n  font-size:12px;\r\n  margin:-10px 0 0;\r\n}\r\n\r\n#apt-calculator .apt-vehicles {\r\n  display:grid;\r\n  grid-template-columns:repeat(3,minmax(0,1fr));\r\n  gap:9px;\r\n}\r\n\r\n#apt-calculator .apt-vehicles label {\r\n  margin:0;\r\n  cursor:pointer;\r\n  letter-spacing:0;\r\n  text-transform:none;\r\n}\r\n\r\n#apt-calculator .apt-vehicles input {\r\n  position:absolute;\r\n  opacity:0;\r\n  pointer-events:none;\r\n}\r\n\r\n#apt-calculator .apt-vehicles span {\r\n  display:block;\r\n  height:100%;\r\n  border:1px solid #505056;\r\n  padding:13px 8px;\r\n  text-align:center;\r\n  color:#fff;\r\n  font-size:12px;\r\n  font-weight:600;\r\n  line-height:1.35;\r\n  transition:.2s;\r\n}\r\n\r\n#apt-calculator .apt-vehicles small {\r\n  display:block;\r\n  margin-top:5px;\r\n  color:var(--grey);\r\n  font-size:10px;\r\n  font-weight:400;\r\n}\r\n\r\n#apt-calculator .apt-vehicles input:checked + span {\r\n  border-color:var(--gold);\r\n  background:rgba(208,163,104,.13);\r\n  color:var(--light-gold);\r\n}\r\n\r\n#apt-calculator .apt-vehicles input:focus-visible + span {\r\n  outline:2px solid var(--gold);\r\n  outline-offset:2px;\r\n}\r\n\r\n#apt-calculator .apt-btn {\r\n  display:block;\r\n  width:100%;\r\n  padding:17px 22px;\r\n  border:1px solid var(--gold);\r\n  background:var(--gold);\r\n  color:var(--black);\r\n  font:600 11px Montserrat,Arial,sans-serif;\r\n  letter-spacing:.16em;\r\n  text-transform:uppercase;\r\n  text-align:center;\r\n  text-decoration:none;\r\n  cursor:pointer;\r\n  transition:.2s;\r\n}\r\n\r\n#apt-calculator .apt-btn:hover {\r\n  background:var(--light-gold);\r\n  border-color:var(--light-gold);\r\n}\r\n\r\n#apt-calculator .apt-btn:disabled {\r\n  opacity:.55;\r\n  cursor:wait;\r\n}\r\n\r\n#apt-calculator .apt-btn.apt-ghost {\r\n  background:transparent;\r\n  color:#fff;\r\n}\r\n\r\n#apt-calculator .apt-btn.apt-ghost:hover {\r\n  background:var(--gold);\r\n  color:var(--black);\r\n}\r\n\r\n#apt-calculator .apt-message {\r\n  min-height:20px;\r\n  color:#f0c1a9;\r\n  font-size:13px;\r\n  margin:0;\r\n  overflow-wrap:anywhere;\r\n}\r\n\r\n#apt-calculator .apt-result {\r\n  display:none;\r\n  border-top:1px solid rgba(208,163,104,.35);\r\n  padding-top:22px;\r\n}\r\n\r\n#apt-calculator .apt-result.is-visible {\r\n  display:block;\r\n}\r\n\r\n#apt-calculator .apt-price-label {\r\n  font-size:10px;\r\n  font-weight:600;\r\n  letter-spacing:.16em;\r\n  color:var(--gold);\r\n}\r\n\r\n#apt-calculator .apt-price {\r\n  font:italic 500 clamp(40px,5vw,54px)\/1.1 'Montserrat',Arial,sans-serif;\r\n  color:var(--light-gold);\r\n  margin:7px 0 12px;\r\n}\r\n\r\n#apt-calculator .apt-meta {\r\n  display:flex;\r\n  flex-wrap:wrap;\r\n  gap:10px 24px;\r\n  color:var(--grey);\r\n  font-size:13px;\r\n  margin-bottom:18px;\r\n}\r\n\r\n#apt-calculator .apt-meta strong {\r\n  color:#fff;\r\n  font-weight:500;\r\n}\r\n\r\n#apt-calculator .apt-note {\r\n  color:#999;\r\n  font-size:11px;\r\n  margin:12px 0 0;\r\n}\r\n\r\n\/* MAP *\/\r\n\r\n#apt-calculator .apt-map {\r\n  position:relative;\r\n  display:block;\r\n  width:100%;\r\n  height:620px;\r\n  min-height:620px;\r\n  background:#151517;\r\n  overflow:hidden;\r\n}\r\n\r\n#apt-calculator #apt-map {\r\n  position:absolute;\r\n  top:0;\r\n  right:0;\r\n  bottom:0;\r\n  left:0;\r\n  display:block;\r\n  width:100%;\r\n  height:100%;\r\n  min-height:0;\r\n  background:#151517;\r\n  z-index:1;\r\n}\r\n\r\n#apt-calculator .apt-pin {\r\n  width:18px;\r\n  height:18px;\r\n  border-radius:50%;\r\n  background:var(--gold);\r\n  border:3px solid #0B0B0C;\r\n  box-shadow:0 0 0 1px var(--gold);\r\n}\r\n\r\n#apt-calculator .apt-pin.apt-destination {\r\n  background:#fff;\r\n}\r\n\r\n#apt-calculator .leaflet-container {\r\n  font-family:Montserrat,Arial,sans-serif;\r\n  background:#151517;\r\n}\r\n\r\n#apt-calculator .leaflet-control-attribution {\r\n  font-size:10px;\r\n}\r\n\r\n\/* FLUENT FORMS *\/\r\n\r\n#fluentform_9 {\r\n  font-family:Montserrat,Arial,sans-serif !important;\r\n}\r\n\r\n#fluentform_9 .apt-journey-readonly {\r\n  background:#f3eadc !important;\r\n  color:#252525 !important;\r\n  border-color:#D0A368 !important;\r\n  cursor:not-allowed !important;\r\n  opacity:1 !important;\r\n  font-family:Montserrat,Arial,sans-serif !important;\r\n}\r\n\r\n@media(max-width:960px) {\r\n  #apt-calculator .apt-grid {\r\n    grid-template-columns:1fr;\r\n  }\r\n\r\n  #apt-calculator .apt-map {\r\n    height:400px;\r\n    min-height:400px;\r\n  }\r\n\r\n  #apt-calculator #apt-map {\r\n    height:100%;\r\n    min-height:0;\r\n  }\r\n}\r\n\r\n@media(max-width:480px) {\r\n  #apt-calculator {\r\n    padding:48px 14px;\r\n  }\r\n\r\n  #apt-calculator .apt-row {\r\n    display:grid;\r\n    grid-template-columns:minmax(0,1fr) auto;\r\n  }\r\n\r\n  #apt-calculator .apt-find {\r\n    padding:0 10px;\r\n  }\r\n\r\n  #apt-calculator .apt-vehicles {\r\n    gap:6px;\r\n  }\r\n\r\n  #apt-calculator .apt-vehicles span {\r\n    padding:11px 5px;\r\n    font-size:11px;\r\n  }\r\n}\r\n<\/style>\r\n\r\n\r\n<section id=\"apt-calculator\" aria-labelledby=\"apt-heading\">\r\n\r\n  <div class=\"apt-in\">\r\n\r\n    <div class=\"apt-eye\">Instant estimate<\/div>\r\n\r\n    <h2 id=\"apt-heading\">\r\n      Plan Your Ride &amp; <em>See the Price<\/em>\r\n    <\/h2>\r\n\r\n    <p class=\"apt-lead\">\r\n      Enter your pickup and destination to view the driving route,\r\n      estimated journey time and an indicative taxi fare.\r\n    <\/p>\r\n\r\n    <div class=\"apt-grid\">\r\n\r\n      <form class=\"apt-form\" id=\"apt-form\" novalidate>\r\n\r\n        <div>\r\n          <label for=\"apt-pickup-input\">Pickup address<\/label>\r\n\r\n          <div class=\"apt-row\">\r\n            <textarea\r\n              id=\"apt-pickup-input\"\r\n              class=\"apt-address-input\"\r\n              rows=\"1\"\r\n              wrap=\"soft\"\r\n              autocomplete=\"off\"\r\n              placeholder=\"Street, number, city\"\r\n            ><\/textarea>\r\n\r\n            <button\r\n              type=\"button\"\r\n              class=\"apt-find\"\r\n              data-search=\"pickup\"\r\n            >Search<\/button>\r\n          <\/div>\r\n\r\n          <ul\r\n            class=\"apt-sug\"\r\n            id=\"apt-pickup-results\"\r\n            aria-label=\"Pickup address suggestions\"\r\n          ><\/ul>\r\n\r\n          <div class=\"apt-ok\" id=\"apt-pickup-selected\">\r\n            \u2713 Pickup address selected\r\n          <\/div>\r\n        <\/div>\r\n\r\n\r\n        <div>\r\n          <label for=\"apt-destination-input\">Destination<\/label>\r\n\r\n          <div class=\"apt-row\">\r\n            <textarea\r\n              id=\"apt-destination-input\"\r\n              class=\"apt-address-input\"\r\n              rows=\"1\"\r\n              wrap=\"soft\"\r\n              autocomplete=\"off\"\r\n              placeholder=\"Street, number, city\"\r\n            ><\/textarea>\r\n\r\n            <button\r\n              type=\"button\"\r\n              class=\"apt-find\"\r\n              data-search=\"destination\"\r\n            >Search<\/button>\r\n          <\/div>\r\n\r\n          <ul\r\n            class=\"apt-sug\"\r\n            id=\"apt-destination-results\"\r\n            aria-label=\"Destination address suggestions\"\r\n          ><\/ul>\r\n\r\n          <div class=\"apt-ok\" id=\"apt-destination-selected\">\r\n            \u2713 Destination address selected\r\n          <\/div>\r\n        <\/div>\r\n\r\n\r\n        <p class=\"apt-help\">\r\n          Enter an address and click Search. Select the correct\r\n          location from the search results.\r\n        <\/p>\r\n\r\n\r\n        <div>\r\n          <label for=\"apt-datetime\">Date and time (optional)<\/label>\r\n\r\n          <input\r\n            type=\"datetime-local\"\r\n            id=\"apt-datetime\"\r\n          >\r\n        <\/div>\r\n\r\n\r\n        <fieldset>\r\n          <legend>Choose your taxi<\/legend>\r\n\r\n          <div class=\"apt-vehicles\">\r\n\r\n            <label>\r\n              <input\r\n                type=\"radio\"\r\n                name=\"apt-vehicle\"\r\n                value=\"t14\"\r\n                checked\r\n              >\r\n              <span>\r\n                1\u20134 persons\r\n                <small>Meter taxi<\/small>\r\n              <\/span>\r\n            <\/label>\r\n\r\n            <label>\r\n              <input\r\n                type=\"radio\"\r\n                name=\"apt-vehicle\"\r\n                value=\"t57\"\r\n              >\r\n              <span>\r\n                5\u20137 persons\r\n                <small>Meter taxi van<\/small>\r\n              <\/span>\r\n            <\/label>\r\n\r\n            <label>\r\n              <input\r\n                type=\"radio\"\r\n                name=\"apt-vehicle\"\r\n                value=\"fixed\"\r\n              >\r\n              <span>\r\n                Fixed price\r\n                <small>Request a quote<\/small>\r\n              <\/span>\r\n            <\/label>\r\n\r\n          <\/div>\r\n        <\/fieldset>\r\n\r\n\r\n        <button\r\n          class=\"apt-btn\"\r\n          type=\"submit\"\r\n          id=\"apt-calculate\"\r\n        >\r\n          Calculate price\r\n        <\/button>\r\n\r\n\r\n        <p\r\n          class=\"apt-message\"\r\n          id=\"apt-message\"\r\n          role=\"status\"\r\n          aria-live=\"polite\"\r\n        ><\/p>\r\n\r\n\r\n        <div class=\"apt-result\" id=\"apt-result\">\r\n\r\n          <div class=\"apt-price-label\" id=\"apt-price-label\">\r\n            ESTIMATED FARE\r\n          <\/div>\r\n\r\n          <div class=\"apt-price\" id=\"apt-price\">\u2014<\/div>\r\n\r\n          <div class=\"apt-meta\">\r\n\r\n            <span>\r\n              Distance:\r\n              <strong id=\"apt-distance\">\u2014<\/strong>\r\n            <\/span>\r\n\r\n            <span>\r\n              Duration:\r\n              <strong id=\"apt-duration\">\u2014<\/strong>\r\n            <\/span>\r\n\r\n          <\/div>\r\n\r\n          <a\r\n            class=\"apt-btn apt-ghost\"\r\n            id=\"apt-book\"\r\n            href=\"#\"\r\n          >\r\n            Continue to booking\r\n          <\/a>\r\n\r\n          <p class=\"apt-note\" id=\"apt-disclaimer\">\r\n            Indicative estimate only. Actual meter fare may vary\r\n            with traffic, waiting time and other applicable charges.\r\n          <\/p>\r\n\r\n        <\/div>\r\n\r\n      <\/form>\r\n\r\n\r\n      <div class=\"apt-map\">\r\n        <div\r\n          id=\"apt-map\"\r\n          role=\"region\"\r\n          aria-label=\"Taxi journey map\"\r\n        ><\/div>\r\n      <\/div>\r\n\r\n    <\/div>\r\n\r\n  <\/div>\r\n\r\n<\/section>\r\n\r\n\r\n<script>\r\n(function () {\r\n  'use strict';\r\n\r\n  \/* CONFIGURATION *\/\r\n\r\n  var CONFIG = {\r\n\r\n    currency: 'EUR',\r\n    locale: 'nl-NL',\r\n\r\n    countryCodes: 'nl',\r\n\r\n    geocodingUrl:\r\n      'https:\/\/nominatim.openstreetmap.org\/search',\r\n\r\n    routingUrl:\r\n      'https:\/\/router.project-osrm.org',\r\n\r\n    tileUrl:\r\n      'https:\/\/tile.openstreetmap.org\/{z}\/{x}\/{y}.png',\r\n\r\n    fluentFormId: 9,\r\n\r\n    \/\/ Permanent Fluent Forms field IDs.\r\n    \/\/ These do not depend on translated labels.\r\n    fluentPickupFieldId: 'ff_9_input_text_1',\r\n    fluentDestinationFieldId: 'ff_9_input_text_2',\r\n\r\n    tariffs: {\r\n\r\n      t14: {\r\n        label: '1\u20134 persons',\r\n        base: 4.03,\r\n        perKm: 2.96,\r\n        perMinute: 0.49\r\n      },\r\n\r\n      t57: {\r\n        label: '5\u20137 persons',\r\n        base: 8.17,\r\n        perKm: 3.72,\r\n        perMinute: 0.55\r\n      }\r\n\r\n    }\r\n\r\n  };\r\n\r\n\r\n  \/* INITIALIZATION *\/\r\n\r\n  var root = document.getElementById('apt-calculator');\r\n\r\n  if (!root || root.dataset.aptInitialized === 'true') {\r\n    return;\r\n  }\r\n\r\n  root.dataset.aptInitialized = 'true';\r\n\r\n  function byId(id) {\r\n    return root.querySelector('#' + id);\r\n  }\r\n\r\n  var pickupInput = byId('apt-pickup-input');\r\n  var destinationInput = byId('apt-destination-input');\r\n\r\n  var pickupResults = byId('apt-pickup-results');\r\n  var destinationResults = byId('apt-destination-results');\r\n\r\n  var message = byId('apt-message');\r\n  var calculateButton = byId('apt-calculate');\r\n  var resultBox = byId('apt-result');\r\n\r\n  var state = {\r\n    pickup: null,\r\n    destination: null,\r\n    route: null,\r\n    routeLayer: null,\r\n    markers: {},\r\n    bookingDetails: null,\r\n    lastGeocodeRequest: 0,\r\n    searchCache: Object.create(null)\r\n  };\r\n\r\n\r\n  \/* GENERAL HELPERS *\/\r\n\r\n  function setMessage(text) {\r\n    message.textContent = text || '';\r\n  }\r\n\r\n  function resizeAddressField(field) {\r\n    if (!field) return;\r\n\r\n    field.style.height = '48px';\r\n\r\n    var nextHeight = Math.min(field.scrollHeight, 140);\r\n\r\n    field.style.height = Math.max(48, nextHeight) + 'px';\r\n\r\n    field.style.overflowY =\r\n      field.scrollHeight > 140 ? 'auto' : 'hidden';\r\n  }\r\n\r\n  function showResult(show) {\r\n    resultBox.classList.toggle('is-visible', !!show);\r\n  }\r\n\r\n  function clearList(list) {\r\n    while (list.firstChild) {\r\n      list.removeChild(list.firstChild);\r\n    }\r\n  }\r\n\r\n  function addListMessage(list, text) {\r\n    clearList(list);\r\n\r\n    var li = document.createElement('li');\r\n    li.className = 'apt-none';\r\n    li.textContent = text;\r\n\r\n    list.appendChild(li);\r\n  }\r\n\r\n  function formatMoney(amount) {\r\n    return new Intl.NumberFormat(CONFIG.locale, {\r\n      style: 'currency',\r\n      currency: CONFIG.currency\r\n    }).format(amount);\r\n  }\r\n\r\n  function getSelectedVehicle() {\r\n    var checked = root.querySelector(\r\n      'input[name=\"apt-vehicle\"]:checked'\r\n    );\r\n\r\n    return checked ? checked.value : 't14';\r\n  }\r\n\r\n\r\n  \/* LEAFLET LOADER WITH CDN FALLBACK *\/\r\n\r\n  function loadLeaflet() {\r\n\r\n    return new Promise(function (resolve, reject) {\r\n\r\n      if (window.L && window.L.map) {\r\n        resolve();\r\n        return;\r\n      }\r\n\r\n      var sources = [\r\n        'https:\/\/cdn.jsdelivr.net\/npm\/leaflet@1.9.4\/dist\/leaflet.js',\r\n        'https:\/\/unpkg.com\/leaflet@1.9.4\/dist\/leaflet.js'\r\n      ];\r\n\r\n      var index = 0;\r\n\r\n      function loadNext() {\r\n\r\n        if (window.L && window.L.map) {\r\n          resolve();\r\n          return;\r\n        }\r\n\r\n        if (index >= sources.length) {\r\n          reject(\r\n            new Error(\r\n              'Leaflet could not be loaded from either CDN.'\r\n            )\r\n          );\r\n          return;\r\n        }\r\n\r\n        var script = document.createElement('script');\r\n\r\n        script.src = sources[index++];\r\n        script.async = true;\r\n\r\n        script.onload = function () {\r\n\r\n          if (window.L && window.L.map) {\r\n            resolve();\r\n          } else {\r\n            loadNext();\r\n          }\r\n\r\n        };\r\n\r\n        script.onerror = function () {\r\n          loadNext();\r\n        };\r\n\r\n        document.head.appendChild(script);\r\n\r\n      }\r\n\r\n      loadNext();\r\n\r\n    });\r\n\r\n  }\r\n\r\n\r\n  \/* MAP INITIALIZATION *\/\r\n\r\n  var map = null;\r\n\r\n  function initializeMap() {\r\n\r\n    if (!window.L || !window.L.map) {\r\n      throw new Error('Leaflet map library is unavailable.');\r\n    }\r\n\r\n    if (map) {\r\n      return;\r\n    }\r\n\r\n    var mapElement = byId('apt-map');\r\n\r\n    if (!mapElement) {\r\n      throw new Error('Map container #apt-map was not found.');\r\n    }\r\n\r\n    map = L.map(mapElement, {\r\n      scrollWheelZoom: false\r\n    }).setView([52.3676, 4.9041], 11);\r\n\r\n    L.tileLayer(CONFIG.tileUrl, {\r\n      maxZoom: 19,\r\n      attribution:\r\n        '&copy; <a href=\"https:\/\/www.openstreetmap.org\/copyright\" target=\"_blank\" rel=\"noopener\">OpenStreetMap<\/a> contributors'\r\n    }).addTo(map);\r\n\r\n    function refreshMapSize() {\r\n\r\n      if (!map) return;\r\n\r\n      map.invalidateSize({\r\n        pan: false\r\n      });\r\n\r\n    }\r\n\r\n    window.setTimeout(refreshMapSize, 200);\r\n    window.setTimeout(refreshMapSize, 700);\r\n    window.setTimeout(refreshMapSize, 1500);\r\n\r\n    window.addEventListener('resize', refreshMapSize);\r\n\r\n    if (window.ResizeObserver) {\r\n\r\n      var observer = new ResizeObserver(function () {\r\n        refreshMapSize();\r\n      });\r\n\r\n      observer.observe(mapElement.parentElement);\r\n\r\n    }\r\n\r\n  }\r\n\r\n\r\n  \/* MAP MARKERS AND ROUTES *\/\r\n\r\n  function removeRoute() {\r\n\r\n    if (state.routeLayer && map) {\r\n      map.removeLayer(state.routeLayer);\r\n      state.routeLayer = null;\r\n    }\r\n\r\n  }\r\n\r\n  function addMarker(which, place) {\r\n\r\n    if (!map) return;\r\n\r\n    if (state.markers[which]) {\r\n      map.removeLayer(state.markers[which]);\r\n    }\r\n\r\n    var icon = L.divIcon({\r\n\r\n      className: '',\r\n\r\n      html:\r\n        '<div class=\"apt-pin' +\r\n        (which === 'destination' ? ' apt-destination' : '') +\r\n        '\"><\/div>',\r\n\r\n      iconSize: [18, 18],\r\n      iconAnchor: [9, 9]\r\n\r\n    });\r\n\r\n    state.markers[which] = L.marker(\r\n      [place.lat, place.lon],\r\n      { icon: icon }\r\n    ).addTo(map);\r\n\r\n  }\r\n\r\n  function fitSelectedMarkers() {\r\n\r\n    if (!map) return;\r\n\r\n    var points = [];\r\n\r\n    if (state.pickup) {\r\n      points.push([\r\n        state.pickup.lat,\r\n        state.pickup.lon\r\n      ]);\r\n    }\r\n\r\n    if (state.destination) {\r\n      points.push([\r\n        state.destination.lat,\r\n        state.destination.lon\r\n      ]);\r\n    }\r\n\r\n    if (points.length === 1) {\r\n      map.setView(points[0], 14);\r\n    }\r\n\r\n    if (points.length === 2) {\r\n      map.fitBounds(points, {\r\n        padding: [45, 45]\r\n      });\r\n    }\r\n\r\n  }\r\n\r\n\r\n  \/* ADDRESS SEARCH FALLBACK *\/\r\n\r\n  function buildSearchQueries(original) {\r\n\r\n    var query = original.trim();\r\n\r\n    var parts = query.split(',').map(function (part) {\r\n      return part.trim();\r\n    }).filter(Boolean);\r\n\r\n    var queries = [query];\r\n\r\n    var withoutPostcode = query\r\n      .replace(\/\\b\\d{4}\\s?[A-Za-z]{2}\\b\/g, '')\r\n      .replace(\/\\s+\/g, ' ')\r\n      .replace(\/,\\s*,\/g, ',')\r\n      .replace(\/^,\\s*|\\s*,$\/g, '')\r\n      .trim();\r\n\r\n    if (\r\n      withoutPostcode &&\r\n      withoutPostcode.toLowerCase() !== query.toLowerCase()\r\n    ) {\r\n      queries.push(withoutPostcode);\r\n    }\r\n\r\n    if (parts.length >= 2) {\r\n\r\n      var first = parts[0];\r\n\r\n      var last = parts[parts.length - 1]\r\n        .replace(\/\\b\\d{4}\\s?[A-Za-z]{2}\\b\/g, '')\r\n        .trim();\r\n\r\n      if (first && last) {\r\n        queries.push(first + ', ' + last);\r\n      }\r\n\r\n      queries.push(first);\r\n\r\n    }\r\n\r\n    return queries.filter(function (item, index, array) {\r\n\r\n      return item.length >= 3 &&\r\n        array.findIndex(function (other) {\r\n          return other.toLowerCase() === item.toLowerCase();\r\n        }) === index;\r\n\r\n    });\r\n\r\n  }\r\n\r\n\r\n  \/* NOMINATIM REQUEST *\/\r\n\r\n  async function requestGeocoding(query) {\r\n\r\n    var key = query.toLowerCase();\r\n\r\n    if (\r\n      Object.prototype.hasOwnProperty.call(\r\n        state.searchCache,\r\n        key\r\n      )\r\n    ) {\r\n      return state.searchCache[key];\r\n    }\r\n\r\n    var delay = Math.max(\r\n      0,\r\n      1100 - (Date.now() - state.lastGeocodeRequest)\r\n    );\r\n\r\n    if (delay) {\r\n      await new Promise(function (resolve) {\r\n        window.setTimeout(resolve, delay);\r\n      });\r\n    }\r\n\r\n    state.lastGeocodeRequest = Date.now();\r\n\r\n    var params = new URLSearchParams({\r\n      format: 'jsonv2',\r\n      addressdetails: '1',\r\n      limit: '5',\r\n      q: query\r\n    });\r\n\r\n    if (CONFIG.countryCodes) {\r\n      params.set('countrycodes', CONFIG.countryCodes);\r\n    }\r\n\r\n    var response = await fetch(\r\n      CONFIG.geocodingUrl + '?' + params.toString(),\r\n      {\r\n        method: 'GET',\r\n        headers: {\r\n          'Accept': 'application\/json'\r\n        }\r\n      }\r\n    );\r\n\r\n    if (!response.ok) {\r\n\r\n      if (response.status === 429) {\r\n        throw new Error(\r\n          'Address search is temporarily busy. Please wait and try again.'\r\n        );\r\n      }\r\n\r\n      throw new Error(\r\n        'Address search failed. Server response: HTTP ' +\r\n        response.status\r\n      );\r\n\r\n    }\r\n\r\n    var data = await response.json();\r\n\r\n    if (!Array.isArray(data)) {\r\n      throw new Error('Unexpected address-search response.');\r\n    }\r\n\r\n    state.searchCache[key] = data;\r\n\r\n    return data;\r\n\r\n  }\r\n\r\n\r\n  \/* SEARCH AND SELECT ADDRESS *\/\r\n\r\n  async function searchAddress(which) {\r\n\r\n    var input = which === 'pickup'\r\n      ? pickupInput\r\n      : destinationInput;\r\n\r\n    var list = which === 'pickup'\r\n      ? pickupResults\r\n      : destinationResults;\r\n\r\n    var button = root.querySelector(\r\n      '[data-search=\"' + which + '\"]'\r\n    );\r\n\r\n    var query = input.value.trim();\r\n\r\n    if (query.length < 3) {\r\n\r\n      addListMessage(\r\n        list,\r\n        'Please enter at least 3 characters.'\r\n      );\r\n\r\n      return;\r\n\r\n    }\r\n\r\n    button.disabled = true;\r\n    button.textContent = 'Searching\u2026';\r\n\r\n    addListMessage(list, 'Searching for addresses\u2026');\r\n\r\n    try {\r\n\r\n      var queries = buildSearchQueries(query);\r\n      var data = [];\r\n      var successfulQuery = '';\r\n\r\n      for (var i = 0; i < queries.length; i++) {\r\n\r\n        data = await requestGeocoding(queries[i]);\r\n\r\n        if (data.length) {\r\n          successfulQuery = queries[i];\r\n          break;\r\n        }\r\n\r\n      }\r\n\r\n      clearList(list);\r\n\r\n      if (!data.length) {\r\n\r\n        addListMessage(\r\n          list,\r\n          'No address found. Try a shorter place name and city.'\r\n        );\r\n\r\n        return;\r\n\r\n      }\r\n\r\n      data.forEach(function (item) {\r\n\r\n        var lat = Number(item.lat);\r\n        var lon = Number(item.lon);\r\n\r\n        if (\r\n          !Number.isFinite(lat) ||\r\n          !Number.isFinite(lon)\r\n        ) {\r\n          return;\r\n        }\r\n\r\n        var li = document.createElement('li');\r\n        var choice = document.createElement('button');\r\n\r\n        choice.type = 'button';\r\n\r\n        choice.textContent =\r\n          item.display_name || successfulQuery;\r\n\r\n        choice.addEventListener('click', function () {\r\n\r\n          var place = {\r\n            lat: lat,\r\n            lon: lon,\r\n            name: item.display_name || successfulQuery\r\n          };\r\n\r\n          state[which] = place;\r\n          state.route = null;\r\n          state.bookingDetails = null;\r\n\r\n          input.value = place.name;\r\n          resizeAddressField(input);\r\n\r\n          clearList(list);\r\n\r\n          byId(\r\n            which === 'pickup'\r\n              ? 'apt-pickup-selected'\r\n              : 'apt-destination-selected'\r\n          ).style.display = 'block';\r\n\r\n          showResult(false);\r\n          removeRoute();\r\n\r\n          addMarker(which, place);\r\n          fitSelectedMarkers();\r\n\r\n          setMessage('');\r\n\r\n        });\r\n\r\n        li.appendChild(choice);\r\n        list.appendChild(li);\r\n\r\n      });\r\n\r\n      if (!list.children.length) {\r\n        addListMessage(\r\n          list,\r\n          'No usable address result was found.'\r\n        );\r\n      }\r\n\r\n      if (\r\n        successfulQuery.toLowerCase() !== query.toLowerCase()\r\n      ) {\r\n        setMessage(\r\n          'We found results using a shorter search. Please select the correct address.'\r\n        );\r\n      } else {\r\n        setMessage('');\r\n      }\r\n\r\n    } catch (error) {\r\n\r\n      console.error(\r\n        '[Taxi Calculator] Address search error:',\r\n        error\r\n      );\r\n\r\n      addListMessage(\r\n        list,\r\n        error.message || 'Address search failed.'\r\n      );\r\n\r\n    } finally {\r\n\r\n      button.disabled = false;\r\n      button.textContent = 'Search';\r\n\r\n    }\r\n\r\n  }\r\n\r\n\r\n  \/* ADDRESS INPUT EVENTS *\/\r\n\r\n  pickupInput.addEventListener('input', function () {\r\n\r\n    resizeAddressField(pickupInput);\r\n\r\n    if (state.pickup) {\r\n      state.pickup = null;\r\n      state.route = null;\r\n      state.bookingDetails = null;\r\n\r\n      byId('apt-pickup-selected').style.display = 'none';\r\n\r\n      if (state.markers.pickup && map) {\r\n        map.removeLayer(state.markers.pickup);\r\n        state.markers.pickup = null;\r\n      }\r\n\r\n      removeRoute();\r\n      showResult(false);\r\n    }\r\n\r\n    clearList(pickupResults);\r\n\r\n  });\r\n\r\n\r\n  destinationInput.addEventListener('input', function () {\r\n\r\n    resizeAddressField(destinationInput);\r\n\r\n    if (state.destination) {\r\n      state.destination = null;\r\n      state.route = null;\r\n      state.bookingDetails = null;\r\n\r\n      byId('apt-destination-selected').style.display = 'none';\r\n\r\n      if (state.markers.destination && map) {\r\n        map.removeLayer(state.markers.destination);\r\n        state.markers.destination = null;\r\n      }\r\n\r\n      removeRoute();\r\n      showResult(false);\r\n    }\r\n\r\n    clearList(destinationResults);\r\n\r\n  });\r\n\r\n\r\n  pickupInput.addEventListener('keydown', function (event) {\r\n\r\n    if (event.key === 'Enter') {\r\n      event.preventDefault();\r\n      searchAddress('pickup');\r\n    }\r\n\r\n  });\r\n\r\n\r\n  destinationInput.addEventListener('keydown', function (event) {\r\n\r\n    if (event.key === 'Enter') {\r\n      event.preventDefault();\r\n      searchAddress('destination');\r\n    }\r\n\r\n  });\r\n\r\n\r\n  root.querySelectorAll('.apt-find').forEach(function (button) {\r\n\r\n    button.addEventListener('click', function () {\r\n\r\n      searchAddress(\r\n        button.getAttribute('data-search')\r\n      );\r\n\r\n    });\r\n\r\n  });\r\n\r\n\r\n  \/* VEHICLE SELECTION *\/\r\n\r\n  root.querySelectorAll(\r\n    'input[name=\"apt-vehicle\"]'\r\n  ).forEach(function (radio) {\r\n\r\n    radio.addEventListener('change', function () {\r\n\r\n      if (state.route) {\r\n        displayFare();\r\n      }\r\n\r\n    });\r\n\r\n  });\r\n\r\n\r\n  \/* FARE CALCULATION *\/\r\n\r\n  function displayFare() {\r\n\r\n    if (!state.route) return;\r\n\r\n    var vehicleId = getSelectedVehicle();\r\n\r\n    var km = state.route.distance \/ 1000;\r\n    var minutes = state.route.duration \/ 60;\r\n\r\n    byId('apt-distance').textContent =\r\n      km.toFixed(1) + ' km';\r\n\r\n    byId('apt-duration').textContent =\r\n      Math.round(minutes) + ' min';\r\n\r\n    var fare;\r\n\r\n    if (vehicleId === 'fixed') {\r\n\r\n      fare = 'Request a quote';\r\n\r\n      byId('apt-price-label').textContent =\r\n        'FIXED-PRICE QUOTE';\r\n\r\n      byId('apt-price').textContent = fare;\r\n\r\n      byId('apt-disclaimer').textContent =\r\n        'Fixed fares depend on your destination. Please contact us to confirm the price.';\r\n\r\n    } else {\r\n\r\n      var tariff = CONFIG.tariffs[vehicleId];\r\n\r\n      var total =\r\n        tariff.base +\r\n        km * tariff.perKm +\r\n        minutes * tariff.perMinute;\r\n\r\n      total = Math.round(\r\n        (total + Number.EPSILON) * 100\r\n      ) \/ 100;\r\n\r\n      fare = formatMoney(total);\r\n\r\n      byId('apt-price-label').textContent =\r\n        'ESTIMATED METER FARE';\r\n\r\n      byId('apt-price').textContent = fare;\r\n\r\n      byId('apt-disclaimer').textContent =\r\n        'Indicative estimate based on distance and estimated driving time. Actual meter fare may vary due to traffic, waiting time and other applicable charges.';\r\n\r\n    }\r\n\r\n    state.bookingDetails = {\r\n\r\n      pickup: state.pickup.name,\r\n\r\n      destination: state.destination.name,\r\n\r\n      distance: byId('apt-distance').textContent,\r\n\r\n      duration: byId('apt-duration').textContent,\r\n\r\n      fare: fare,\r\n\r\n      vehicle: vehicleId === 'fixed'\r\n        ? 'Fixed price - request a quote'\r\n        : CONFIG.tariffs[vehicleId].label\r\n\r\n    };\r\n\r\n    showResult(true);\r\n\r\n  }\r\n\r\n\r\n  \/* =========================================================\r\n     FLUENT FORMS 9 INTEGRATION\r\n     GOOGLE TRANSLATE COMPATIBLE\r\n     USES PERMANENT HTML FIELD IDS\r\n  ========================================================= *\/\r\n\r\n\r\n  \/*\r\n   * IMPORTANT:\r\n   * We no longer search for the visible labels.\r\n   * Google Translate can change the labels, but these\r\n   * HTML IDs remain the identifiers used by this code.\r\n   *\/\r\n\r\n  function findFluentField(form, fieldId) {\r\n\r\n    if (!form || !fieldId) {\r\n      return null;\r\n    }\r\n\r\n    var field = form.querySelector(\r\n      '#' + fieldId\r\n    );\r\n\r\n    return field || null;\r\n\r\n  }\r\n\r\n\r\n  \/*\r\n   * Set field value while keeping the field READ-ONLY.\r\n   * Read-only fields are submitted with Fluent Forms.\r\n   *\/\r\n\r\n  function setFluentFieldValue(field, value) {\r\n\r\n    if (!field) {\r\n      return false;\r\n    }\r\n\r\n    var prototype;\r\n\r\n    if (field.tagName === 'TEXTAREA') {\r\n\r\n      prototype = window.HTMLTextAreaElement.prototype;\r\n\r\n    } else if (field.tagName === 'INPUT') {\r\n\r\n      prototype = window.HTMLInputElement.prototype;\r\n\r\n    } else {\r\n\r\n      return false;\r\n\r\n    }\r\n\r\n    var valueSetter = Object.getOwnPropertyDescriptor(\r\n      prototype,\r\n      'value'\r\n    );\r\n\r\n    if (valueSetter && valueSetter.set) {\r\n\r\n      valueSetter.set.call(field, value);\r\n\r\n    } else {\r\n\r\n      field.value = value;\r\n\r\n    }\r\n\r\n    field.readOnly = true;\r\n\r\n    field.setAttribute(\r\n      'aria-readonly',\r\n      'true'\r\n    );\r\n\r\n    field.classList.add(\r\n      'apt-journey-readonly'\r\n    );\r\n\r\n    field.dispatchEvent(\r\n      new Event('input', { bubbles: true })\r\n    );\r\n\r\n    field.dispatchEvent(\r\n      new Event('change', { bubbles: true })\r\n    );\r\n\r\n    return true;\r\n\r\n  }\r\n\r\n\r\n  \/*\r\n   * Populate the two Fluent Forms fields.\r\n   * No visible label matching is used.\r\n   *\/\r\n\r\n  function populateFluentForm(details) {\r\n\r\n    var form = document.getElementById(\r\n      'fluentform_' + CONFIG.fluentFormId\r\n    );\r\n\r\n    if (!form) {\r\n\r\n      return {\r\n        success: false,\r\n        message:\r\n          'Fluent Forms form 9 was not found. Please check that [fluentform id=\"9\"] is on this page.'\r\n      };\r\n\r\n    }\r\n\r\n    var pickupField = findFluentField(\r\n      form,\r\n      CONFIG.fluentPickupFieldId\r\n    );\r\n\r\n    var destinationField = findFluentField(\r\n      form,\r\n      CONFIG.fluentDestinationFieldId\r\n    );\r\n\r\n    if (!pickupField || !destinationField) {\r\n\r\n      console.error(\r\n        '[Taxi Calculator] Fluent Forms fields not found.',\r\n        {\r\n          pickupFound: !!pickupField,\r\n          destinationFound: !!destinationField,\r\n          pickupId: CONFIG.fluentPickupFieldId,\r\n          destinationId: CONFIG.fluentDestinationFieldId\r\n        }\r\n      );\r\n\r\n      return {\r\n        success: false,\r\n        message:\r\n          'The booking address fields could not be found. Please check the Fluent Forms field IDs.'\r\n      };\r\n\r\n    }\r\n\r\n    var pickupSuccess = setFluentFieldValue(\r\n      pickupField,\r\n      details.pickup\r\n    );\r\n\r\n    var destinationSuccess = setFluentFieldValue(\r\n      destinationField,\r\n      details.destination\r\n    );\r\n\r\n    if (!pickupSuccess || !destinationSuccess) {\r\n\r\n      return {\r\n        success: false,\r\n        message:\r\n          'Could not populate both booking address fields.'\r\n      };\r\n\r\n    }\r\n\r\n    return {\r\n      success: true,\r\n      form: form\r\n    };\r\n\r\n  }\r\n\r\n\r\n  \/* CONTINUE TO BOOKING *\/\r\n\r\n  byId('apt-book').addEventListener(\r\n    'click',\r\n    function (event) {\r\n\r\n      event.preventDefault();\r\n\r\n      if (!state.bookingDetails) {\r\n\r\n        setMessage(\r\n          'Please calculate your journey before continuing.'\r\n        );\r\n\r\n        return;\r\n\r\n      }\r\n\r\n      var result = populateFluentForm(\r\n        state.bookingDetails\r\n      );\r\n\r\n      if (!result.success) {\r\n\r\n        setMessage(result.message);\r\n\r\n        console.error(\r\n          '[Taxi Calculator] Fluent Forms error:',\r\n          result.message\r\n        );\r\n\r\n        return;\r\n\r\n      }\r\n\r\n      setMessage(\r\n        'Your journey details have been added. Please complete your contact details and submit your booking request.'\r\n      );\r\n\r\n      result.form.scrollIntoView({\r\n        behavior: 'smooth',\r\n        block: 'start'\r\n      });\r\n\r\n    }\r\n  );\r\n\r\n\r\n  \/* ROUTE CALCULATION - OSRM *\/\r\n\r\n  byId('apt-form').addEventListener(\r\n    'submit',\r\n    async function (event) {\r\n\r\n      event.preventDefault();\r\n\r\n      if (!state.pickup || !state.destination) {\r\n\r\n        setMessage(\r\n          'Please search for and select both pickup and destination addresses.'\r\n        );\r\n\r\n        return;\r\n\r\n      }\r\n\r\n      if (\r\n        state.pickup.lat === state.destination.lat &&\r\n        state.pickup.lon === state.destination.lon\r\n      ) {\r\n\r\n        setMessage(\r\n          'Pickup and destination cannot be the same location.'\r\n        );\r\n\r\n        return;\r\n\r\n      }\r\n\r\n      calculateButton.disabled = true;\r\n      calculateButton.textContent = 'Calculating\u2026';\r\n\r\n      setMessage(\r\n        'Calculating the driving route\u2026'\r\n      );\r\n\r\n      showResult(false);\r\n\r\n      try {\r\n\r\n        var routeUrl =\r\n          CONFIG.routingUrl +\r\n          '\/route\/v1\/driving\/' +\r\n          state.pickup.lon + ',' + state.pickup.lat +\r\n          ';' +\r\n          state.destination.lon + ',' + state.destination.lat +\r\n          '?overview=full&geometries=geojson&steps=false';\r\n\r\n        var response = await fetch(\r\n          routeUrl,\r\n          {\r\n            method: 'GET',\r\n            headers: {\r\n              'Accept': 'application\/json'\r\n            }\r\n          }\r\n        );\r\n\r\n        if (!response.ok) {\r\n\r\n          throw new Error(\r\n            'Routing service returned HTTP ' +\r\n            response.status\r\n          );\r\n\r\n        }\r\n\r\n        var routeData = await response.json();\r\n\r\n        if (\r\n          routeData.code !== 'Ok' ||\r\n          !routeData.routes ||\r\n          !routeData.routes.length\r\n        ) {\r\n\r\n          throw new Error(\r\n            'No driving route found. Please check the selected addresses.'\r\n          );\r\n\r\n        }\r\n\r\n        var bestRoute = routeData.routes[0];\r\n\r\n        state.route = {\r\n\r\n          distance: bestRoute.distance,\r\n\r\n          duration: bestRoute.duration\r\n\r\n        };\r\n\r\n        if (state.routeLayer) {\r\n          map.removeLayer(state.routeLayer);\r\n        }\r\n\r\n        state.routeLayer = L.geoJSON(\r\n          bestRoute.geometry,\r\n          {\r\n            style: {\r\n              color: '#D0A368',\r\n              weight: 5,\r\n              opacity: .95\r\n            }\r\n          }\r\n        ).addTo(map);\r\n\r\n        map.fitBounds(\r\n          state.routeLayer.getBounds(),\r\n          {\r\n            padding: [45, 45]\r\n          }\r\n        );\r\n\r\n        displayFare();\r\n\r\n        setMessage('');\r\n\r\n      } catch (error) {\r\n\r\n        console.error(\r\n          '[Taxi Calculator] Route error:',\r\n          error\r\n        );\r\n\r\n        setMessage(\r\n          error.message ||\r\n          'The route could not be calculated. Please try again.'\r\n        );\r\n\r\n      } finally {\r\n\r\n        calculateButton.disabled = false;\r\n        calculateButton.textContent = 'Calculate price';\r\n\r\n      }\r\n\r\n    }\r\n  );\r\n\r\n\r\n  \/* START MAP AND CALCULATOR *\/\r\n\r\n  loadLeaflet()\r\n    .then(function () {\r\n\r\n      initializeMap();\r\n\r\n      console.log(\r\n        '[Taxi Calculator] Map initialized successfully.'\r\n      );\r\n\r\n    })\r\n    .catch(function (error) {\r\n\r\n      console.error(\r\n        '[Taxi Calculator] Map loading failed:',\r\n        error\r\n      );\r\n\r\n      setMessage(\r\n        'The map could not load. Please refresh the page or check your website connection.'\r\n      );\r\n\r\n    });\r\n\r\n})();\r\n<\/script>\r\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-3fd5ecf e-flex e-con-boxed e-con e-parent\" data-id=\"3fd5ecf\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;,&quot;ekit_has_onepagescroll_dot&quot;:&quot;yes&quot;}\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-58aa321 elementor-widget elementor-widget-text-editor\" data-id=\"58aa321\" data-element_type=\"widget\" data-e-type=\"widget\" data-settings=\"{&quot;ekit_we_effect_on&quot;:&quot;none&quot;}\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<div class='fluentform ff-default fluentform_wrapper_9 ffs_default_wrap'><form data-form_id=\"9\" id=\"fluentform_9\" class=\"frm-fluent-form fluent_form_9 ff-el-form-top ff_form_instance_9_1 ff-form-loading ffs_default\" data-form_instance=\"ff_form_instance_9_1\" method=\"POST\" ><fieldset  style=\"border: none!important;margin: 0!important;padding: 0!important;background-color: transparent!important;box-shadow: none!important;outline: none!important; min-inline-size: 100%;\">\n                    <legend class=\"ff_screen_reader_title\" style=\"display: block; margin: 0!important;padding: 0!important;height: 0!important;text-indent: -999999px;width: 0!important;overflow:hidden;\">Blank Form (#9)<\/legend><input type='hidden' name='__fluent_form_embded_post_id' value='1572' \/><input type=\"hidden\" id=\"_fluentform_9_fluentformnonce\" name=\"_fluentform_9_fluentformnonce\" value=\"e389e8a1fd\" \/><input type=\"hidden\" name=\"_wp_http_referer\" value=\"\/cleaning\/wp-json\/wp\/v2\/pages\/1572\" \/><div data-name=\"ff_cn_id_1\"  class='ff-t-container ff-column-container ff_columns_total_2 '><div class='ff-t-cell ff-t-column-1' style='flex-basis: 50%;'><div class='ff-el-group'><div class=\"ff-el-input--label asterisk-right\"><label for='ff_9_input_text_1' id='label_ff_9_input_text_1'>Pickup Address<\/label><\/div><div class='ff-el-input--content'><input type=\"text\" name=\"input_text_1\" class=\"ff-el-form-control\" data-name=\"input_text_1\" id=\"ff_9_input_text_1\"  aria-invalid=\"false\" aria-required=false><\/div><\/div><\/div><div class='ff-t-cell ff-t-column-2' style='flex-basis: 50%;'><div class='ff-el-group'><div class=\"ff-el-input--label asterisk-right\"><label for='ff_9_input_text_2' id='label_ff_9_input_text_2'>Drop-off Location<\/label><\/div><div class='ff-el-input--content'><input type=\"text\" name=\"input_text_2\" class=\"ff-el-form-control\" data-name=\"input_text_2\" id=\"ff_9_input_text_2\"  aria-invalid=\"false\" aria-required=false><\/div><\/div><\/div><\/div><div data-name=\"ff_cn_id_2\"  class='ff-t-container ff-column-container ff_columns_total_2 '><div class='ff-t-cell ff-t-column-1' style='flex-basis: 50%;'><div class='ff-el-group'><div class=\"ff-el-input--label asterisk-right\"><label for='ff_9_datetime' id='label_ff_9_datetime'>Date<\/label><\/div><div class='ff-el-input--content'><input  aria-label='Date Use arrow keys to navigate dates. Press enter to select a date.'  aria-haspopup='dialog' data-type-datepicker data-format='d\/m\/Y' type=\"text\" name=\"datetime\" id=\"ff_9_datetime\" class=\"ff-el-form-control ff-el-datepicker\" data-name=\"datetime\"  aria-invalid='false' aria-required=false><\/div><\/div><\/div><div class='ff-t-cell ff-t-column-2' style='flex-basis: 50%;'><div class='ff-el-group'><div class=\"ff-el-input--label asterisk-right\"><label for='ff_9_datetime_1' id='label_ff_9_datetime_1'>Time<\/label><\/div><div class='ff-el-input--content'><input  aria-label='Time Use arrow keys to navigate dates. Press enter to select a date.'  aria-haspopup='dialog' data-type-datepicker data-format='h:i K' type=\"text\" name=\"datetime_1\" id=\"ff_9_datetime_1\" class=\"ff-el-form-control ff-el-datepicker\" data-name=\"datetime_1\"  aria-invalid='false' aria-required=false><\/div><\/div><\/div><\/div><div data-type=\"name-element\" data-name=\"names\" class=\" ff-field_container ff-name-field-wrapper\" ><div class='ff-t-container'><div class='ff-t-cell '><div class='ff-el-group ff-el-form-top'><div class=\"ff-el-input--label asterisk-right\"><label for='ff_9_names_first_name_' id='label_ff_9_names_first_name_'>First Name<\/label><\/div><div class='ff-el-input--content'><input type=\"text\" name=\"names[first_name]\" id=\"ff_9_names_first_name_\" class=\"ff-el-form-control\" placeholder=\"Enter Your First Name\" autocomplete=\"given-name\" aria-invalid=\"false\" aria-required=false><\/div><\/div><\/div><div class='ff-t-cell '><div class='ff-el-group ff-el-form-top'><div class=\"ff-el-input--label asterisk-right\"><label for='ff_9_names_last_name_' id='label_ff_9_names_last_name_'>Last Name<\/label><\/div><div class='ff-el-input--content'><input type=\"text\" name=\"names[last_name]\" id=\"ff_9_names_last_name_\" class=\"ff-el-form-control\" placeholder=\"Enter Your Last Name\" autocomplete=\"family-name\" aria-invalid=\"false\" aria-required=false><\/div><\/div><\/div><\/div><\/div><div class='ff-el-group'><div class=\"ff-el-input--label asterisk-right\"><label for='ff_9_phone' id='label_ff_9_phone'>Phone\/Mobile<\/label><\/div><div class='ff-el-input--content'><input name=\"phone\" class=\"ff-el-form-control ff-el-phone\" type=\"tel\" autocomplete=\"tel\" placeholder=\"Mobile Number\" data-name=\"phone\" id=\"ff_9_phone\" inputmode=\"tel\"  aria-invalid='false' aria-required=false><\/div><\/div><div class='ff-el-group'><div class=\"ff-el-input--label asterisk-right\"><label for='ff_9_email' id='label_ff_9_email'>Email<\/label><\/div><div class='ff-el-input--content'><input autocomplete=\"email\" type=\"email\" name=\"email\" id=\"ff_9_email\" class=\"ff-el-form-control\" placeholder=\"Email Address\" data-name=\"email\"  aria-invalid=\"false\" aria-required=false><\/div><\/div><div class='ff-el-group'><div class=\"ff-el-input--label asterisk-right\"><label for='ff_9_input_text_7' id='label_ff_9_input_text_7'>Flight Number<\/label><\/div><div class='ff-el-input--content'><input type=\"text\" name=\"input_text_7\" class=\"ff-el-form-control\" data-name=\"input_text_7\" id=\"ff_9_input_text_7\"  aria-invalid=\"false\" aria-required=false><\/div><\/div><div data-name=\"ff_cn_id_3\"  class='ff-t-container ff-column-container ff_columns_total_2 '><div class='ff-t-cell ff-t-column-1' style='flex-basis: 50%;'><div class='ff-el-group'><div class=\"ff-el-input--label asterisk-right\"><label for='ff_9_input_text_8' id='label_ff_9_input_text_8'>Number of Large Suitcases<\/label><\/div><div class='ff-el-input--content'><input type=\"text\" name=\"input_text_8\" class=\"ff-el-form-control\" data-name=\"input_text_8\" id=\"ff_9_input_text_8\"  aria-invalid=\"false\" aria-required=false><\/div><\/div><\/div><div class='ff-t-cell ff-t-column-2' style='flex-basis: 50%;'><div class='ff-el-group'><div class=\"ff-el-input--label asterisk-right\"><label for='ff_9_input_text_9' id='label_ff_9_input_text_9'>Number of Small Bags<\/label><\/div><div class='ff-el-input--content'><input type=\"text\" name=\"input_text_9\" class=\"ff-el-form-control\" data-name=\"input_text_9\" id=\"ff_9_input_text_9\"  aria-invalid=\"false\" aria-required=false><\/div><\/div><\/div><\/div><div class='ff-el-group'><div class=\"ff-el-input--label asterisk-right\"><label for='ff_9_description' id='label_ff_9_description'>Message<\/label><\/div><div class='ff-el-input--content'><textarea aria-required=\"false\" aria-labelledby=\"label_ff_9_description\" name=\"description\" id=\"ff_9_description\" class=\"ff-el-form-control\" placeholder=\"Any additional Requirements....\" rows=\"3\" cols=\"2\" data-name=\"description\" ><\/textarea><\/div><\/div><div class='ff-form-inline-style' hidden><style>form.fluent_form_9 .wpf_has_custom_css.ff-btn-submit { background-color:rgba(208, 163, 104, 1);border-color:rgba(208, 163, 104, 1);color:rgba(0, 0, 0, 1); }form.fluent_form_9 .wpf_has_custom_css.ff-btn-submit:hover { background-color:rgba(208, 163, 104, 1);border-color:rgba(208, 163, 104, 1);color:rgba(0, 0, 0, 1); } <\/style><\/div><div class='ff-el-group ff-text-left ff_submit_btn_wrapper'><button type=\"submit\" class=\"ff-btn ff-btn-submit ff-btn-md ff_btn_style wpf_has_custom_css\"  aria-label=\"Send\">Send<\/button><\/div><\/fieldset><\/form><div id='fluentform_9_errors' class='ff-errors-in-stack ff_form_instance_9_1 ff-form-loading_errors ff_form_instance_9_1_errors'><\/div><\/div>            <script type=\"text\/javascript\">\n                window.fluent_form_ff_form_instance_9_1 = {\"id\":\"9\",\"ajaxUrl\":\"https:\\\/\\\/timeless-airporttaxi.de\\\/cleaning\\\/wp-admin\\\/admin-ajax.php\",\"settings\":{\"layout\":{\"labelPlacement\":\"top\",\"asteriskPlacement\":\"asterisk-right\",\"helpMessagePlacement\":\"with_label\",\"errorMessagePlacement\":\"inline\",\"cssClassName\":\"\"},\"restrictions\":{\"denyEmptySubmission\":{\"enabled\":false}}},\"form_instance\":\"ff_form_instance_9_1\",\"form_id_selector\":\"fluentform_9\",\"rules\":{\"input_text_1\":{\"required\":{\"value\":false,\"message\":\"This field is required\",\"global_message\":\"This field is required\",\"global\":true}},\"input_text_2\":{\"required\":{\"value\":false,\"message\":\"This field is required\",\"global_message\":\"This field is required\",\"global\":true}},\"datetime\":{\"required\":{\"value\":false,\"message\":\"This field is required\",\"global_message\":\"This field is required\",\"global\":true}},\"datetime_1\":{\"required\":{\"value\":false,\"message\":\"This field is required\",\"global_message\":\"This field is required\",\"global\":true}},\"names[first_name]\":{\"required\":{\"value\":false,\"message\":\"This field is required\",\"global_message\":\"This field is required\",\"global\":true}},\"names[middle_name]\":{\"required\":{\"value\":false,\"message\":\"This field is required\",\"global_message\":\"This field is required\",\"global\":true}},\"names[last_name]\":{\"required\":{\"value\":false,\"message\":\"This field is required\",\"global_message\":\"This field is required\",\"global\":true}},\"phone\":{\"required\":{\"value\":false,\"global\":true,\"message\":\"This field is required\",\"global_message\":\"This field is required\"},\"valid_phone_number\":{\"value\":false,\"global\":true,\"message\":\"Phone number is not valid\",\"global_message\":\"Phone number is not valid\"}},\"email\":{\"required\":{\"value\":false,\"message\":\"This field is required\",\"global_message\":\"This field is required\",\"global\":true},\"email\":{\"value\":true,\"message\":\"This field must contain a valid email\",\"global_message\":\"This field must contain a valid email\",\"global\":true}},\"input_text_7\":{\"required\":{\"value\":false,\"message\":\"This field is required\",\"global_message\":\"This field is required\",\"global\":true}},\"input_text_8\":{\"required\":{\"value\":false,\"message\":\"This field is required\",\"global_message\":\"This field is required\",\"global\":true}},\"input_text_9\":{\"required\":{\"value\":false,\"message\":\"This field is required\",\"global_message\":\"This field is required\",\"global\":true}},\"description\":{\"required\":{\"value\":false,\"message\":\"This field is required\",\"global_message\":\"This field is required\",\"global\":true}}},\"debounce_time\":300,\"file_upload_settings\":[]};\n                            <\/script>\n            \t\t\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":"<p>Instant estimate Plan Your Ride &amp; See the Price Enter your pickup and destination to view the driving route, estimated journey time and an indicative taxi fare. Pickup address Search \u2713 Pickup address selected Destination Search \u2713 Destination address selected Enter an address and click Search. Select the correct location from the search results. Date [&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-1572","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/timeless-airporttaxi.de\/cleaning\/wp-json\/wp\/v2\/pages\/1572","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/timeless-airporttaxi.de\/cleaning\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/timeless-airporttaxi.de\/cleaning\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/timeless-airporttaxi.de\/cleaning\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/timeless-airporttaxi.de\/cleaning\/wp-json\/wp\/v2\/comments?post=1572"}],"version-history":[{"count":55,"href":"https:\/\/timeless-airporttaxi.de\/cleaning\/wp-json\/wp\/v2\/pages\/1572\/revisions"}],"predecessor-version":[{"id":1688,"href":"https:\/\/timeless-airporttaxi.de\/cleaning\/wp-json\/wp\/v2\/pages\/1572\/revisions\/1688"}],"wp:attachment":[{"href":"https:\/\/timeless-airporttaxi.de\/cleaning\/wp-json\/wp\/v2\/media?parent=1572"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}