"""

<!DOCTYPE html>
<html lang="ru">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Маршрут A-B - OpenLayers</title>

  <!-- OpenLayers Integration -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ol@10.3.1/ol.css" />
  <script src="https://cdn.jsdelivr.net/npm/ol@10.3.1/dist/ol.js"></script>

<style>
  /* General Layout */
  html, body {
    margin: 0;
    padding: 0;
    width: 100%;
    height: 100%;
    font-family: Arial, sans-serif;
  }

  #map {
    width: 100%;
    height: calc(100vh - 18px);
  }

  /* Inputs Wrapper */
  #inputs-wrapper {
    position: absolute;
    top: 10px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 1000;
    display: flex;
    gap: 12px;
    background: rgba(255, 255, 255, 0.95);
    padding: 15px;
    border-radius: 8px;
    box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.15);
    flex-wrap: wrap;
  }

  /* Responsive for Mobile */
  @media (max-width: 768px) {
    #inputs-wrapper {
      flex-direction: column;
      gap: 8px;
      width: calc(100% - 20px);
    }

    .input-group {
      width: 100%;
    }
  }

  .input-group {
    display: flex;
    align-items: center;
    flex: 1;
    position: relative; /* Added to ensure relative positioning for autocomplete dropdowns */
  }

  .input-group > input {
    width: calc(100% - 40px); /* Adjust for button */
    padding: 10px;
    border-radius: 4px;
    border: 1px solid #ccc;
    box-sizing: border-box;
    z-index: 2; /* Ensure input box is above any other element */
    position: relative;
  }

  .input-group > button {
    width: 35px;
    height: 35px;
    margin-left: 5px;
    border: 1px solid #ccc;
    border-radius: 4px;
    background-color: #007bff;
    color: #fff;
    font-size: 16px;
    cursor: pointer;
    z-index: 2; /* Ensure button remains above other elements */
    position: relative;
  }

  button:disabled {
    background-color: #ccc;
    cursor: not-allowed;
  }

  /* Autocomplete Container */
  .autocomplete-container {
    position: absolute;
    top: 105%;
    left: 0;
    width: 100%;
    background: white;
    border: 1px solid #ccc;
    box-shadow: 0px 2px 6px rgba(0, 0, 0, 0.1);
    z-index: 5; /* Ensure autocomplete is above input and map */
    display: none; /* Hidden initially */
    pointer-events: auto; /* Allow dropdown to be fully clickable */
  }

  .autocomplete-item {
    padding: 8px;
    cursor: pointer;
    z-index: 5;
  }

  .autocomplete-item:hover {
    background-color: #e9f5ff;
  }

  /* To ensure inputs remain clickable when the dropdown is active */
  .input-group input:focus + .autocomplete-container {
    display: block;
  }

  /* Route Info Bar */
  #route-info {
    position: absolute;
    bottom: 0;
    left: 0;
    width: 100%;
    background: rgba(255, 255, 255, 0.9);
    text-align: center;
    border-top: 1px solid #ccc;
  }
</style>
</head>
<body>
  <!-- Inputs for A and B -->
  <div id="inputs-wrapper">
    <!-- Input A -->
    <div class="input-group" id="start-group">
      <input id="start" placeholder="Точка A" value="" />
      <button id="pickup-a" title="Выбрать A">A</button>
      <div id="start-autocomplete" class="autocomplete-container"></div>
    </div>

    <!-- Input B -->
    <div class="input-group" id="end-group">
      <input id="end" placeholder="Точка B" value="" />
      <button id="pickup-b" title="Выбрать B">B</button>
      <div id="end-autocomplete" class="autocomplete-container"></div>
    </div>
  </div>

  <!-- Map Container -->
  <div id="map"></div>

  <!-- Route Information -->
  <div id="route-info">
    <b>Дистанция:</b> <span id="distance">Ожидание...</span> |
    <b>ETA:</b> <span id="eta">00:00:00</span>
  </div>

  <script>
    // ==== Map Setup ====
    const map = new ol.Map({
      target: "map",
      layers: [
        new ol.layer.Tile({
          source: new ol.source.OSM({ transition: 0 }),
        }),
      ],
      view: new ol.View({
        center: ol.proj.fromLonLat([37.6173, 55.7558]), // Moscow
        zoom: 12,
      }),
    });

    // Active Pickup: Tracks whether selecting A or B
    let activePickup = null;
    let startCoords = null; // A coordinates
    let endCoords = null; // B coordinates

    // Marker Styles
    const createMarkerStyle = (color) =>
      new ol.style.Style({
        image: new ol.style.Circle({
          radius: 8,
          fill: new ol.style.Fill({ color }),
          stroke: new ol.style.Stroke({ color: "white", width: 2 }),
        }),
      });

    const startMarker = new ol.Feature();
    const endMarker = new ol.Feature();
    const markerLayer = new ol.layer.Vector({
      source: new ol.source.Vector({ features: [startMarker, endMarker] }),
      style: (feature) =>
        feature === startMarker ? createMarkerStyle("blue") : createMarkerStyle("green"),
    });
    map.addLayer(markerLayer);

    // Route Layer
    const routeLayer = new ol.layer.Vector({
      source: new ol.source.Vector(),
      style: new ol.style.Style({
        stroke: new ol.style.Stroke({
          color: "red",
          width: 3,
        }),
      }),
    });
    map.addLayer(routeLayer);

    // ==== Map Click Events ====
    map.on("click", async (event) => {
      const coord = ol.proj.toLonLat(event.coordinate);
      if (activePickup === "A") {
        startCoords = coord;
        startMarker.setGeometry(new ol.geom.Point(event.coordinate));
        document.getElementById("start").value = await reverseGeocode(coord);
        activePickup = null;
      } else if (activePickup === "B") {
        endCoords = coord;
        endMarker.setGeometry(new ol.geom.Point(event.coordinate));
        document.getElementById("end").value = await reverseGeocode(coord);
        activePickup = null;
      }
      drawRoute();
    });

    // ==== Reverse Geocoding ====
    async function reverseGeocode([lon, lat]) {
      const url = `https://nominatim.openstreetmap.org/reverse?format=json&lat=${lat}&lon=${lon}&accept-language=ru`;
      const res = await fetch(url);
      const json = await res.json();
      return json.display_name || "Неизвестное место";
    }

    // ==== Autocomplete ====
    function setupAutocomplete(inputId, containerId, callback) {
      const input = document.getElementById(inputId);
      const container = document.getElementById(containerId);

      input.addEventListener("input", async () => {
        const query = input.value.trim();
        if (!query) {
          container.style.display = "none";
          return;
        }

        const url = `https://nominatim.openstreetmap.org/search?format=json&q=${encodeURIComponent(
          query
        )}&limit=5&accept-language=ru`;
        const results = await fetch(url).then((res) => res.json());

        container.innerHTML = results
          .map((result) => `<div class="autocomplete-item">${result.display_name}</div>`)
          .join("");
        container.style.display = "block";

        Array.from(container.children).forEach((item, index) => {
          item.addEventListener("click", () => {
            callback(results[index]);
            container.style.display = "none";
          });
        });
      });

      input.addEventListener("blur", () => {
        setTimeout(() => {
          container.style.display = "none";
        }, 100);
      });
    }

    setupAutocomplete("start", "start-autocomplete", (result) => {
      startCoords = [parseFloat(result.lon), parseFloat(result.lat)];
      startMarker.setGeometry(new ol.geom.Point(ol.proj.fromLonLat(startCoords)));
      document.getElementById("start").value = result.display_name;
      drawRoute();
    });

    setupAutocomplete("end", "end-autocomplete", (result) => {
      endCoords = [parseFloat(result.lon), parseFloat(result.lat)];
      endMarker.setGeometry(new ol.geom.Point(ol.proj.fromLonLat(endCoords)));
      document.getElementById("end").value = result.display_name;
      drawRoute();
    });

    // ==== Draw Route ====
    async function drawRoute() {
      if (!startCoords || !endCoords) return;
      const url = `https://router.project-osrm.org/route/v1/driving/${startCoords.join(
        ","
      )};${endCoords.join(",")}?overview=full&geometries=geojson`;
      const res = await fetch(url);
      const json = await res.json();

      if (json.code === "Ok") {
        const coords = json.routes[0].geometry.coordinates.map(([lon, lat]) =>
          ol.proj.fromLonLat([lon, lat])
        );
        const routeFeature = new ol.Feature(new ol.geom.LineString(coords));
        routeLayer.getSource().clear();
        routeLayer.getSource().addFeature(routeFeature);

        document.getElementById("distance").textContent =
          (json.routes[0].distance / 1000).toFixed(2) + " км";
        document.getElementById("eta").textContent = new Date(
          json.routes[0].duration * 1000
        )
          .toISOString()
          .substr(11, 8);
      }
    }

    // ==== Buttons for Picking Points ====
    document.getElementById("pickup-a").addEventListener("click", () => {
      activePickup = "A";
    });

    document.getElementById("pickup-b").addEventListener("click", () => {
      activePickup = "B";
    });
  </script>
</body>
</html>

""".



rendered html struct:


"""

<html lang="en"><head>
                    <meta charset="UTF-8">
                    <style>h1 { color: limegreen; text-align: center; font-family: Arial; }</style>
                </head>
                <body>


  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Маршрут A-B - OpenLayers</title>

  <!-- OpenLayers Integration -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ol@10.3.1/ol.css">
  <script src="https://cdn.jsdelivr.net/npm/ol@10.3.1/dist/ol.js"></script>

<style>
  /* General Layout */
  html, body {
    margin: 0;
    padding: 0;
    width: 100%;
    height: 100%;
    font-family: Arial, sans-serif;
  }

  #map {
    width: 100%;
    height: calc(100vh - 18px);
  }

  /* Inputs Wrapper */
  #inputs-wrapper {
    position: absolute;
    top: 10px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 1000;
    display: flex;
    gap: 12px;
    background: rgba(255, 255, 255, 0.95);
    padding: 15px;
    border-radius: 8px;
    box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.15);
    flex-wrap: wrap;
  }

  /* Responsive for Mobile */
  @media (max-width: 768px) {
    #inputs-wrapper {
      flex-direction: column;
      gap: 8px;
      width: calc(100% - 20px);
    }

    .input-group {
      width: 100%;
    }
  }

  .input-group {
    display: flex;
    align-items: center;
    flex: 1;
    position: relative; /* Added to ensure relative positioning for autocomplete dropdowns */
  }

  .input-group > input {
    width: calc(100% - 40px); /* Adjust for button */
    padding: 10px;
    border-radius: 4px;
    border: 1px solid #ccc;
    box-sizing: border-box;
    z-index: 2; /* Ensure input box is above any other element */
    position: relative;
  }

  .input-group > button {
    width: 35px;
    height: 35px;
    margin-left: 5px;
    border: 1px solid #ccc;
    border-radius: 4px;
    background-color: #007bff;
    color: #fff;
    font-size: 16px;
    cursor: pointer;
    z-index: 2; /* Ensure button remains above other elements */
    position: relative;
  }

  button:disabled {
    background-color: #ccc;
    cursor: not-allowed;
  }

  /* Autocomplete Container */
  .autocomplete-container {
    position: absolute;
    top: 105%;
    left: 0;
    width: 100%;
    background: white;
    border: 1px solid #ccc;
    box-shadow: 0px 2px 6px rgba(0, 0, 0, 0.1);
    z-index: 5; /* Ensure autocomplete is above input and map */
    display: none; /* Hidden initially */
    pointer-events: auto; /* Allow dropdown to be fully clickable */
  }

  .autocomplete-item {
    padding: 8px;
    cursor: pointer;
    z-index: 5;
  }

  .autocomplete-item:hover {
    background-color: #e9f5ff;
  }

  /* To ensure inputs remain clickable when the dropdown is active */
  .input-group input:focus + .autocomplete-container {
    display: block;
  }

  /* Route Info Bar */
  #route-info {
    position: absolute;
    bottom: 0;
    left: 0;
    width: 100%;
    background: rgba(255, 255, 255, 0.9);
    text-align: center;
    border-top: 1px solid #ccc;
  }
</style>


  <!-- Inputs for A and B -->
  <div id="inputs-wrapper">
    <!-- Input A -->
    <div class="input-group" id="start-group">
      <input id="start" placeholder="Точка A" value="">
      <button id="pickup-a" title="Выбрать A">A</button>
      <div id="start-autocomplete" class="autocomplete-container" style="display: none;"></div>
    </div>

    <!-- Input B -->
    <div class="input-group" id="end-group">
      <input id="end" placeholder="Точка B" value="">
      <button id="pickup-b" title="Выбрать B">B</button>
      <div id="end-autocomplete" class="autocomplete-container"></div>
    </div>
  </div>

  <!-- Map Container -->
  <div id="map"><div class="ol-viewport" style="position: relative; overflow: hidden; width: 100%; height: 100%;"><div style="position: absolute; width: 100%; height: 100%; z-index: 0;" class="ol-unselectable ol-layers"><div class="ol-layer" style="position: absolute; width: 100%; height: 100%;"><canvas style="position: absolute; left: 0px; transform-origin: left top 0px; transform: matrix(0.5, 0, 0, 0.5, 0, 0);" width="2400" height="1164"></canvas></div></div><div style="position: absolute; z-index: 0; width: 100%; height: 100%; pointer-events: none;" class="ol-overlaycontainer"></div><div style="position: absolute; z-index: 0; width: 100%; height: 100%; pointer-events: none;" class="ol-overlaycontainer-stopevent"><div style="pointer-events: auto;" class="ol-zoom ol-unselectable ol-control"><button class="ol-zoom-in" type="button" title="Zoom in">+</button><button class="ol-zoom-out" type="button" title="Zoom out">–</button></div><div style="pointer-events: auto;" class="ol-rotate ol-unselectable ol-control ol-hidden"><button class="ol-rotate-reset" type="button" title="Reset rotation"><span class="ol-compass" style="transform: rotate(0rad);">⇧</span></button></div><div style="pointer-events: auto;" class="ol-attribution ol-unselectable ol-control ol-uncollapsible"><button type="button" aria-expanded="true" title="Attributions"><span class="ol-attribution-collapse">›</span></button><ul><li>© <a href="https://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a> contributors.</li></ul></div></div></div></div>

  <!-- Route Information -->
  <div id="route-info">
    <b>Дистанция:</b> <span id="distance">0.33 км</span> |
    <b>ETA:</b> <span id="eta">00:00:48</span>
  </div>

  <script>
    // ==== Map Setup ====
    const map = new ol.Map({
      target: "map",
      layers: [
        new ol.layer.Tile({
          source: new ol.source.OSM({ transition: 0 }),
        }),
      ],
      view: new ol.View({
        center: ol.proj.fromLonLat([37.6173, 55.7558]), // Moscow
        zoom: 12,
      }),
    });

    // Active Pickup: Tracks whether selecting A or B
    let activePickup = null;
    let startCoords = null; // A coordinates
    let endCoords = null; // B coordinates

    // Marker Styles
    const createMarkerStyle = (color) =>
      new ol.style.Style({
        image: new ol.style.Circle({
          radius: 8,
          fill: new ol.style.Fill({ color }),
          stroke: new ol.style.Stroke({ color: "white", width: 2 }),
        }),
      });

    const startMarker = new ol.Feature();
    const endMarker = new ol.Feature();
    const markerLayer = new ol.layer.Vector({
      source: new ol.source.Vector({ features: [startMarker, endMarker] }),
      style: (feature) =>
        feature === startMarker ? createMarkerStyle("blue") : createMarkerStyle("green"),
    });
    map.addLayer(markerLayer);

    // Route Layer
    const routeLayer = new ol.layer.Vector({
      source: new ol.source.Vector(),
      style: new ol.style.Style({
        stroke: new ol.style.Stroke({
          color: "red",
          width: 3,
        }),
      }),
    });
    map.addLayer(routeLayer);

    // ==== Map Click Events ====
    map.on("click", async (event) => {
      const coord = ol.proj.toLonLat(event.coordinate);
      if (activePickup === "A") {
        startCoords = coord;
        startMarker.setGeometry(new ol.geom.Point(event.coordinate));
        document.getElementById("start").value = await reverseGeocode(coord);
        activePickup = null;
      } else if (activePickup === "B") {
        endCoords = coord;
        endMarker.setGeometry(new ol.geom.Point(event.coordinate));
        document.getElementById("end").value = await reverseGeocode(coord);
        activePickup = null;
      }
      drawRoute();
    });

    // ==== Reverse Geocoding ====
    async function reverseGeocode([lon, lat]) {
      const url = `https://nominatim.openstreetmap.org/reverse?format=json&lat=${lat}&lon=${lon}&accept-language=ru`;
      const res = await fetch(url);
      const json = await res.json();
      return json.display_name || "Неизвестное место";
    }

    // ==== Autocomplete ====
    function setupAutocomplete(inputId, containerId, callback) {
      const input = document.getElementById(inputId);
      const container = document.getElementById(containerId);

      input.addEventListener("input", async () => {
        const query = input.value.trim();
        if (!query) {
          container.style.display = "none";
          return;
        }

        const url = `https://nominatim.openstreetmap.org/search?format=json&q=${encodeURIComponent(
          query
        )}&limit=5&accept-language=ru`;
        const results = await fetch(url).then((res) => res.json());

        container.innerHTML = results
          .map((result) => `<div class="autocomplete-item">${result.display_name}</div>`)
          .join("");
        container.style.display = "block";

        Array.from(container.children).forEach((item, index) => {
          item.addEventListener("click", () => {
            callback(results[index]);
            container.style.display = "none";
          });
        });
      });

      input.addEventListener("blur", () => {
        setTimeout(() => {
          container.style.display = "none";
        }, 100);
      });
    }

    setupAutocomplete("start", "start-autocomplete", (result) => {
      startCoords = [parseFloat(result.lon), parseFloat(result.lat)];
      startMarker.setGeometry(new ol.geom.Point(ol.proj.fromLonLat(startCoords)));
      document.getElementById("start").value = result.display_name;
      drawRoute();
    });

    setupAutocomplete("end", "end-autocomplete", (result) => {
      endCoords = [parseFloat(result.lon), parseFloat(result.lat)];
      endMarker.setGeometry(new ol.geom.Point(ol.proj.fromLonLat(endCoords)));
      document.getElementById("end").value = result.display_name;
      drawRoute();
    });

    // ==== Draw Route ====
    async function drawRoute() {
      if (!startCoords || !endCoords) return;
      const url = `https://router.project-osrm.org/route/v1/driving/${startCoords.join(
        ","
      )};${endCoords.join(",")}?overview=full&geometries=geojson`;
      const res = await fetch(url);
      const json = await res.json();

      if (json.code === "Ok") {
        const coords = json.routes[0].geometry.coordinates.map(([lon, lat]) =>
          ol.proj.fromLonLat([lon, lat])
        );
        const routeFeature = new ol.Feature(new ol.geom.LineString(coords));
        routeLayer.getSource().clear();
        routeLayer.getSource().addFeature(routeFeature);

        document.getElementById("distance").textContent =
          (json.routes[0].distance / 1000).toFixed(2) + " км";
        document.getElementById("eta").textContent = new Date(
          json.routes[0].duration * 1000
        )
          .toISOString()
          .substr(11, 8);
      }
    }

    // ==== Buttons for Picking Points ====
    document.getElementById("pickup-a").addEventListener("click", () => {
      activePickup = "A";
    });

    document.getElementById("pickup-b").addEventListener("click", () => {
      activePickup = "B";
    });
  </script>


                <script>console.log('IPCE is ready!');</script>
                
                </body></html>

""".


need somehow very unnoticebly to remove that "class="ol-attribution ol-unselectable ol-control ol-uncollapsible"".