summaryrefslogtreecommitdiff
path: root/searx/static/themes/simple/js/searxng.min.js.map
blob: 00d2dc93a4cd7fbf653e58652d3ac59e249884d2 (plain)
1
{"version":3,"file":"searxng.min.js","sources":["../../../../../client/simple/src/js/main/00_toolkit.js","../../../../../client/simple/src/js/main/infinite_scroll.js","../../../../../client/simple/src/js/main/keyboard.js","../../../../../client/simple/src/js/main/mapresult.js","../../../../../client/simple/src/js/main/preferences.js","../../../../../client/simple/node_modules/swiped-events/src/swiped-events.js","../../../../../client/simple/src/js/main/results.js","../../../../../client/simple/src/js/main/search.js"],"sourcesContent":["/**\n * @license\n * (C) Copyright Contributors to the SearXNG project.\n * (C) Copyright Contributors to the searx project (2014 - 2021).\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\nwindow.searxng = ((w, d) => {\n  // not invented here toolkit with bugs fixed elsewhere\n  // purposes : be just good enough and as small as possible\n\n  // from https://plainjs.com/javascript/events/live-binding-event-handlers-14/\n  if (w.Element) {\n    ((ElementPrototype) => {\n      ElementPrototype.matches =\n        ElementPrototype.matches ||\n        ElementPrototype.matchesSelector ||\n        ElementPrototype.webkitMatchesSelector ||\n        ElementPrototype.msMatchesSelector ||\n        function (selector) {\n          const nodes = (this.parentNode || this.document).querySelectorAll(selector);\n          let i = -1;\n          while (nodes[++i] && nodes[i] !== this);\n          return !!nodes[i];\n        };\n    })(Element.prototype);\n  }\n\n  function callbackSafe(callback, el, e) {\n    try {\n      callback.call(el, e);\n    } catch (exception) {\n      console.log(exception);\n    }\n  }\n\n  const searxng = window.searxng || {};\n\n  searxng.on = (obj, eventType, callback, useCapture) => {\n    useCapture = useCapture || false;\n    if (typeof obj !== \"string\") {\n      // obj HTMLElement, HTMLDocument\n      obj.addEventListener(eventType, callback, useCapture);\n    } else {\n      // obj is a selector\n      d.addEventListener(\n        eventType,\n        (e) => {\n          let el = e.target || e.srcElement;\n          let found = false;\n\n          while (el?.matches && el !== d) {\n            found = el.matches(obj);\n\n            if (found) break;\n\n            el = el.parentElement;\n          }\n\n          if (found) {\n            callbackSafe(callback, el, e);\n          }\n        },\n        useCapture\n      );\n    }\n  };\n\n  searxng.ready = (callback) => {\n    if (document.readyState !== \"loading\") {\n      callback.call(w);\n    } else {\n      w.addEventListener(\"DOMContentLoaded\", callback.bind(w));\n    }\n  };\n\n  searxng.http = (method, url, data = null) =>\n    new Promise((resolve, reject) => {\n      try {\n        const req = new XMLHttpRequest();\n        req.open(method, url, true);\n        req.timeout = 20000;\n\n        // On load\n        req.onload = () => {\n          if (req.status === 200) {\n            resolve(req.response, req.responseType);\n          } else {\n            reject(Error(req.statusText));\n          }\n        };\n\n        // Handle network errors\n        req.onerror = () => {\n          reject(Error(\"Network Error\"));\n        };\n\n        req.onabort = () => {\n          reject(Error(\"Transaction is aborted\"));\n        };\n\n        req.ontimeout = () => {\n          reject(Error(\"Timeout\"));\n        };\n\n        // Make the request\n        if (data) {\n          req.send(data);\n        } else {\n          req.send();\n        }\n      } catch (ex) {\n        reject(ex);\n      }\n    });\n\n  searxng.loadStyle = (src) => {\n    const path = `${searxng.settings.theme_static_path}/${src}`;\n    const id = `style_${src.replace(\".\", \"_\")}`;\n    let s = d.getElementById(id);\n    if (s === null) {\n      s = d.createElement(\"link\");\n      s.setAttribute(\"id\", id);\n      s.setAttribute(\"rel\", \"stylesheet\");\n      s.setAttribute(\"type\", \"text/css\");\n      s.setAttribute(\"href\", path);\n      d.body.appendChild(s);\n    }\n  };\n\n  searxng.loadScript = (src, callback) => {\n    const path = `${searxng.settings.theme_static_path}/${src}`;\n    const id = `script_${src.replace(\".\", \"_\")}`;\n    let s = d.getElementById(id);\n    if (s === null) {\n      s = d.createElement(\"script\");\n      s.setAttribute(\"id\", id);\n      s.setAttribute(\"src\", path);\n      s.onload = callback;\n      s.onerror = () => {\n        s.setAttribute(\"error\", \"1\");\n      };\n      d.body.appendChild(s);\n    } else if (!s.hasAttribute(\"error\")) {\n      try {\n        callback.apply(s, []);\n      } catch (exception) {\n        console.log(exception);\n      }\n    } else {\n      console.log(`callback not executed : script '${path}' not loaded.`);\n    }\n  };\n\n  searxng.insertBefore = (newNode, referenceNode) => {\n    referenceNode.parentNode.insertBefore(newNode, referenceNode);\n  };\n\n  searxng.insertAfter = (newNode, referenceNode) => {\n    referenceNode.parentNode.insertAfter(newNode, referenceNode.nextSibling);\n  };\n\n  searxng.on(\".close\", \"click\", function () {\n    this.parentNode.classList.add(\"invisible\");\n  });\n\n  function getEndpoint() {\n    for (const className of d.getElementsByTagName(\"body\")[0].classList.values()) {\n      if (className.endsWith(\"_endpoint\")) {\n        return className.split(\"_\")[0];\n      }\n    }\n    return \"\";\n  }\n\n  searxng.endpoint = getEndpoint();\n\n  return searxng;\n})(window, document);\n","// SPDX-License-Identifier: AGPL-3.0-or-later\n\n/* global searxng */\n\nsearxng.ready(() => {\n  searxng.infinite_scroll_supported =\n    \"IntersectionObserver\" in window &&\n    \"IntersectionObserverEntry\" in window &&\n    \"intersectionRatio\" in window.IntersectionObserverEntry.prototype;\n\n  if (searxng.endpoint !== \"results\") {\n    return;\n  }\n\n  if (!searxng.infinite_scroll_supported) {\n    console.log(\"IntersectionObserver not supported\");\n    return;\n  }\n\n  const d = document;\n  const onlyImages = d.getElementById(\"results\").classList.contains(\"only_template_images\");\n\n  function newLoadSpinner() {\n    const loader = d.createElement(\"div\");\n    loader.classList.add(\"loader\");\n    return loader;\n  }\n\n  function replaceChildrenWith(element, children) {\n    element.textContent = \"\";\n    children.forEach((child) => element.appendChild(child));\n  }\n\n  function loadNextPage(callback) {\n    const form = d.querySelector(\"#pagination form.next_page\");\n    if (!form) {\n      return;\n    }\n    replaceChildrenWith(d.querySelector(\"#pagination\"), [newLoadSpinner()]);\n    const formData = new FormData(form);\n    searxng\n      .http(\"POST\", d.querySelector(\"#search\").getAttribute(\"action\"), formData)\n      .then((response) => {\n        const nextPageDoc = new DOMParser().parseFromString(response, \"text/html\");\n        const articleList = nextPageDoc.querySelectorAll(\"#urls article\");\n        const paginationElement = nextPageDoc.querySelector(\"#pagination\");\n        d.querySelector(\"#pagination\").remove();\n        if (articleList.length > 0 && !onlyImages) {\n          // do not add <hr> element when there are only images\n          d.querySelector(\"#urls\").appendChild(d.createElement(\"hr\"));\n        }\n        articleList.forEach((articleElement) => {\n          d.querySelector(\"#urls\").appendChild(articleElement);\n        });\n        if (paginationElement) {\n          d.querySelector(\"#results\").appendChild(paginationElement);\n          callback();\n        }\n      })\n      .catch((err) => {\n        console.log(err);\n        const e = d.createElement(\"div\");\n        e.textContent = searxng.settings.translations.error_loading_next_page;\n        e.classList.add(\"dialog-error\");\n        e.setAttribute(\"role\", \"alert\");\n        replaceChildrenWith(d.querySelector(\"#pagination\"), [e]);\n      });\n  }\n\n  if (searxng.settings.infinite_scroll && searxng.infinite_scroll_supported) {\n    const intersectionObserveOptions = {\n      rootMargin: \"20rem\"\n    };\n    const observedSelector = \"article.result:last-child\";\n    const observer = new IntersectionObserver((entries) => {\n      const paginationEntry = entries[0];\n      if (paginationEntry.isIntersecting) {\n        observer.unobserve(paginationEntry.target);\n        loadNextPage(() => observer.observe(d.querySelector(observedSelector), intersectionObserveOptions));\n      }\n    });\n    observer.observe(d.querySelector(observedSelector), intersectionObserveOptions);\n  }\n});\n","/* SPDX-License-Identifier: AGPL-3.0-or-later */\n/* global searxng */\n\nsearxng.ready(() => {\n  function isElementInDetail(el) {\n    while (el !== undefined) {\n      if (el.classList.contains(\"detail\")) {\n        return true;\n      }\n      if (el.classList.contains(\"result\")) {\n        // we found a result, no need to go to the root of the document:\n        // el is not inside a <div class=\"detail\"> element\n        return false;\n      }\n      el = el.parentNode;\n    }\n    return false;\n  }\n\n  function getResultElement(el) {\n    while (el !== undefined) {\n      if (el.classList.contains(\"result\")) {\n        return el;\n      }\n      el = el.parentNode;\n    }\n    return undefined;\n  }\n\n  function isImageResult(resultElement) {\n    return resultElement?.classList.contains(\"result-images\");\n  }\n\n  searxng.on(\".result\", \"click\", function (e) {\n    if (!isElementInDetail(e.target)) {\n      highlightResult(this)(true, true);\n      const resultElement = getResultElement(e.target);\n      if (isImageResult(resultElement)) {\n        e.preventDefault();\n        searxng.selectImage(resultElement);\n      }\n    }\n  });\n\n  searxng.on(\n    \".result a\",\n    \"focus\",\n    (e) => {\n      if (!isElementInDetail(e.target)) {\n        const resultElement = getResultElement(e.target);\n        if (resultElement && resultElement.getAttribute(\"data-vim-selected\") === null) {\n          highlightResult(resultElement)(true);\n        }\n        if (isImageResult(resultElement)) {\n          searxng.selectImage(resultElement);\n        }\n      }\n    },\n    true\n  );\n\n  /* common base for layouts */\n  const baseKeyBinding = {\n    Escape: {\n      key: \"ESC\",\n      fun: removeFocus,\n      des: \"remove focus from the focused input\",\n      cat: \"Control\"\n    },\n    c: {\n      key: \"c\",\n      fun: copyURLToClipboard,\n      des: \"copy url of the selected result to the clipboard\",\n      cat: \"Results\"\n    },\n    h: {\n      key: \"h\",\n      fun: toggleHelp,\n      des: \"toggle help window\",\n      cat: \"Other\"\n    },\n    i: {\n      key: \"i\",\n      fun: searchInputFocus,\n      des: \"focus on the search input\",\n      cat: \"Control\"\n    },\n    n: {\n      key: \"n\",\n      fun: GoToNextPage(),\n      des: \"go to next page\",\n      cat: \"Results\"\n    },\n    o: {\n      key: \"o\",\n      fun: openResult(false),\n      des: \"open search result\",\n      cat: \"Results\"\n    },\n    p: {\n      key: \"p\",\n      fun: GoToPreviousPage(),\n      des: \"go to previous page\",\n      cat: \"Results\"\n    },\n    r: {\n      key: \"r\",\n      fun: reloadPage,\n      des: \"reload page from the server\",\n      cat: \"Control\"\n    },\n    t: {\n      key: \"t\",\n      fun: openResult(true),\n      des: \"open the result in a new tab\",\n      cat: \"Results\"\n    }\n  };\n  const keyBindingLayouts = {\n    default: Object.assign(\n      {\n        /* SearXNG layout */\n        ArrowLeft: {\n          key: \"←\",\n          fun: highlightResult(\"up\"),\n          des: \"select previous search result\",\n          cat: \"Results\"\n        },\n        ArrowRight: {\n          key: \"→\",\n          fun: highlightResult(\"down\"),\n          des: \"select next search result\",\n          cat: \"Results\"\n        }\n      },\n      baseKeyBinding\n    ),\n\n    vim: Object.assign(\n      {\n        /* Vim-like Key Layout. */\n        b: {\n          key: \"b\",\n          fun: scrollPage(-window.innerHeight),\n          des: \"scroll one page up\",\n          cat: \"Navigation\"\n        },\n        f: {\n          key: \"f\",\n          fun: scrollPage(window.innerHeight),\n          des: \"scroll one page down\",\n          cat: \"Navigation\"\n        },\n        u: {\n          key: \"u\",\n          fun: scrollPage(-window.innerHeight / 2),\n          des: \"scroll half a page up\",\n          cat: \"Navigation\"\n        },\n        d: {\n          key: \"d\",\n          fun: scrollPage(window.innerHeight / 2),\n          des: \"scroll half a page down\",\n          cat: \"Navigation\"\n        },\n        g: {\n          key: \"g\",\n          fun: scrollPageTo(-document.body.scrollHeight, \"top\"),\n          des: \"scroll to the top of the page\",\n          cat: \"Navigation\"\n        },\n        v: {\n          key: \"v\",\n          fun: scrollPageTo(document.body.scrollHeight, \"bottom\"),\n          des: \"scroll to the bottom of the page\",\n          cat: \"Navigation\"\n        },\n        k: {\n          key: \"k\",\n          fun: highlightResult(\"up\"),\n          des: \"select previous search result\",\n          cat: \"Results\"\n        },\n        j: {\n          key: \"j\",\n          fun: highlightResult(\"down\"),\n          des: \"select next search result\",\n          cat: \"Results\"\n        },\n        y: {\n          key: \"y\",\n          fun: copyURLToClipboard,\n          des: \"copy url of the selected result to the clipboard\",\n          cat: \"Results\"\n        }\n      },\n      baseKeyBinding\n    )\n  };\n\n  const keyBindings = keyBindingLayouts[searxng.settings.hotkeys] || keyBindingLayouts.default;\n\n  searxng.on(document, \"keydown\", (e) => {\n    // check for modifiers so we don't break browser's hotkeys\n    if (\n      // biome-ignore lint/suspicious/noPrototypeBuiltins: FIXME: support for Chromium 93-87, Firefox 92-78, Safari 15.4-14\n      Object.prototype.hasOwnProperty.call(keyBindings, e.key) &&\n      !e.ctrlKey &&\n      !e.altKey &&\n      !e.shiftKey &&\n      !e.metaKey\n    ) {\n      const tagName = e.target.tagName.toLowerCase();\n      if (e.key === \"Escape\") {\n        keyBindings[e.key].fun(e);\n      } else {\n        if (e.target === document.body || tagName === \"a\" || tagName === \"button\") {\n          e.preventDefault();\n          keyBindings[e.key].fun();\n        }\n      }\n    }\n  });\n\n  function highlightResult(which) {\n    return (noScroll, keepFocus) => {\n      let current = document.querySelector(\".result[data-vim-selected]\"),\n        effectiveWhich = which;\n      if (current === null) {\n        // no selection : choose the first one\n        current = document.querySelector(\".result\");\n        if (current === null) {\n          // no first one : there are no results\n          return;\n        }\n        // replace up/down actions by selecting first one\n        if (which === \"down\" || which === \"up\") {\n          effectiveWhich = current;\n        }\n      }\n\n      let next,\n        results = document.querySelectorAll(\".result\");\n      results = Array.from(results); // convert NodeList to Array for further use\n\n      if (typeof effectiveWhich !== \"string\") {\n        next = effectiveWhich;\n      } else {\n        switch (effectiveWhich) {\n          case \"visible\": {\n            const top = document.documentElement.scrollTop || document.body.scrollTop;\n            const bot = top + document.documentElement.clientHeight;\n\n            for (let i = 0; i < results.length; i++) {\n              next = results[i];\n              const etop = next.offsetTop;\n              const ebot = etop + next.clientHeight;\n\n              if (ebot <= bot && etop > top) {\n                break;\n              }\n            }\n            break;\n          }\n          case \"down\":\n            next = results[results.indexOf(current) + 1] || current;\n            break;\n          case \"up\":\n            next = results[results.indexOf(current) - 1] || current;\n            break;\n          case \"bottom\":\n            next = results[results.length - 1];\n            break;\n          // biome-ignore lint/complexity/noUselessSwitchCase: fallthrough is intended\n          case \"top\":\n          /* falls through */\n          default:\n            next = results[0];\n        }\n      }\n\n      if (next) {\n        current.removeAttribute(\"data-vim-selected\");\n        next.setAttribute(\"data-vim-selected\", \"true\");\n        if (!keepFocus) {\n          const link = next.querySelector(\"h3 a\") || next.querySelector(\"a\");\n          if (link !== null) {\n            link.focus();\n          }\n        }\n        if (!noScroll) {\n          scrollPageToSelected();\n        }\n      }\n    };\n  }\n\n  function reloadPage() {\n    document.location.reload(true);\n  }\n\n  function removeFocus(e) {\n    const tagName = e.target.tagName.toLowerCase();\n    if (document.activeElement && (tagName === \"input\" || tagName === \"select\" || tagName === \"textarea\")) {\n      document.activeElement.blur();\n    } else {\n      searxng.closeDetail();\n    }\n  }\n\n  function pageButtonClick(css_selector) {\n    return () => {\n      const button = document.querySelector(css_selector);\n      if (button) {\n        button.click();\n      }\n    };\n  }\n\n  function GoToNextPage() {\n    return pageButtonClick('nav#pagination .next_page button[type=\"submit\"]');\n  }\n\n  function GoToPreviousPage() {\n    return pageButtonClick('nav#pagination .previous_page button[type=\"submit\"]');\n  }\n\n  function scrollPageToSelected() {\n    const sel = document.querySelector(\".result[data-vim-selected]\");\n    if (sel === null) {\n      return;\n    }\n    const wtop = document.documentElement.scrollTop || document.body.scrollTop,\n      wheight = document.documentElement.clientHeight,\n      etop = sel.offsetTop,\n      ebot = etop + sel.clientHeight,\n      offset = 120;\n    // first element ?\n    if (sel.previousElementSibling === null && ebot < wheight) {\n      // set to the top of page if the first element\n      // is fully included in the viewport\n      window.scroll(window.scrollX, 0);\n      return;\n    }\n    if (wtop > etop - offset) {\n      window.scroll(window.scrollX, etop - offset);\n    } else {\n      const wbot = wtop + wheight;\n      if (wbot < ebot + offset) {\n        window.scroll(window.scrollX, ebot - wheight + offset);\n      }\n    }\n  }\n\n  function scrollPage(amount) {\n    return () => {\n      window.scrollBy(0, amount);\n      highlightResult(\"visible\")();\n    };\n  }\n\n  function scrollPageTo(position, nav) {\n    return () => {\n      window.scrollTo(0, position);\n      highlightResult(nav)();\n    };\n  }\n\n  function searchInputFocus() {\n    window.scrollTo(0, 0);\n    const q = document.querySelector(\"#q\");\n    q.focus();\n    if (q.setSelectionRange) {\n      const len = q.value.length;\n      q.setSelectionRange(len, len);\n    }\n  }\n\n  function openResult(newTab) {\n    return () => {\n      let link = document.querySelector(\".result[data-vim-selected] h3 a\");\n      if (link === null) {\n        link = document.querySelector(\".result[data-vim-selected] > a\");\n      }\n      if (link !== null) {\n        const url = link.getAttribute(\"href\");\n        if (newTab) {\n          window.open(url);\n        } else {\n          window.location.href = url;\n        }\n      }\n    };\n  }\n\n  function initHelpContent(divElement) {\n    const categories = {};\n\n    for (const k in keyBindings) {\n      const key = keyBindings[k];\n      categories[key.cat] = categories[key.cat] || [];\n      categories[key.cat].push(key);\n    }\n\n    const sorted = Object.keys(categories).sort((a, b) => categories[b].length - categories[a].length);\n\n    if (sorted.length === 0) {\n      return;\n    }\n\n    let html = '<a href=\"#\" class=\"close\" aria-label=\"close\" title=\"close\">×</a>';\n    html += \"<h3>How to navigate SearXNG with hotkeys</h3>\";\n    html += \"<table>\";\n\n    for (let i = 0; i < sorted.length; i++) {\n      const cat = categories[sorted[i]];\n\n      const lastCategory = i === sorted.length - 1;\n      const first = i % 2 === 0;\n\n      if (first) {\n        html += \"<tr>\";\n      }\n      html += \"<td>\";\n\n      html += `<h4>${cat[0].cat}</h4>`;\n      html += '<ul class=\"list-unstyled\">';\n\n      for (const cj in cat) {\n        html += `<li><kbd>${cat[cj].key}</kbd> ${cat[cj].des}</li>`;\n      }\n\n      html += \"</ul>\";\n      html += \"</td>\"; // col-sm-*\n\n      if (!first || lastCategory) {\n        html += \"</tr>\"; // row\n      }\n    }\n\n    html += \"</table>\";\n\n    divElement.innerHTML = html;\n  }\n\n  function toggleHelp() {\n    let helpPanel = document.querySelector(\"#vim-hotkeys-help\");\n    if (helpPanel === undefined || helpPanel === null) {\n      // first call\n      helpPanel = document.createElement(\"div\");\n      helpPanel.id = \"vim-hotkeys-help\";\n      helpPanel.className = \"dialog-modal\";\n      initHelpContent(helpPanel);\n      const body = document.getElementsByTagName(\"body\")[0];\n      body.appendChild(helpPanel);\n    } else {\n      // toggle hidden\n      helpPanel.classList.toggle(\"invisible\");\n    }\n  }\n\n  function copyURLToClipboard() {\n    const currentUrlElement = document.querySelector(\".result[data-vim-selected] h3 a\");\n    if (currentUrlElement === null) return;\n\n    const url = currentUrlElement.getAttribute(\"href\");\n    navigator.clipboard.writeText(url);\n  }\n\n  searxng.scrollPageToSelected = scrollPageToSelected;\n  searxng.selectNext = highlightResult(\"down\");\n  searxng.selectPrevious = highlightResult(\"up\");\n});\n","/* SPDX-License-Identifier: AGPL-3.0-or-later */\n/* global L */\n((_w, _d, searxng) => {\n  searxng.ready(() => {\n    searxng.on(\".searxng_init_map\", \"click\", function (event) {\n      // no more request\n      this.classList.remove(\"searxng_init_map\");\n\n      //\n      const leaflet_target = this.dataset.leafletTarget;\n      const map_lon = parseFloat(this.dataset.mapLon);\n      const map_lat = parseFloat(this.dataset.mapLat);\n      const map_zoom = parseFloat(this.dataset.mapZoom);\n      const map_boundingbox = JSON.parse(this.dataset.mapBoundingbox);\n      const map_geojson = JSON.parse(this.dataset.mapGeojson);\n\n      searxng.loadStyle(\"css/leaflet.css\");\n      searxng.loadScript(\"js/leaflet.js\", () => {\n        let map_bounds = null;\n        if (map_boundingbox) {\n          const southWest = L.latLng(map_boundingbox[0], map_boundingbox[2]);\n          const northEast = L.latLng(map_boundingbox[1], map_boundingbox[3]);\n          map_bounds = L.latLngBounds(southWest, northEast);\n        }\n\n        // init map\n        const map = L.map(leaflet_target);\n        // create the tile layer with correct attribution\n        const osmMapnikUrl = \"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png\";\n        const osmMapnikAttrib = 'Map data © <a href=\"https://openstreetmap.org\">OpenStreetMap</a> contributors';\n        const osmMapnik = new L.TileLayer(osmMapnikUrl, { minZoom: 1, maxZoom: 19, attribution: osmMapnikAttrib });\n        const osmWikimediaUrl = \"https://maps.wikimedia.org/osm-intl/{z}/{x}/{y}.png\";\n        const osmWikimediaAttrib =\n          'Wikimedia maps | Maps data © <a href=\"https://openstreetmap.org\">OpenStreetMap contributors</a>';\n        const osmWikimedia = new L.TileLayer(osmWikimediaUrl, {\n          minZoom: 1,\n          maxZoom: 19,\n          attribution: osmWikimediaAttrib\n        });\n        // init map view\n        if (map_bounds) {\n          // TODO hack: https://github.com/Leaflet/Leaflet/issues/2021\n          // Still useful ?\n          setTimeout(() => {\n            map.fitBounds(map_bounds, {\n              maxZoom: 17\n            });\n          }, 0);\n        } else if (map_lon && map_lat) {\n          if (map_zoom) {\n            map.setView(new L.LatLng(map_lat, map_lon), map_zoom);\n          } else {\n            map.setView(new L.LatLng(map_lat, map_lon), 8);\n          }\n        }\n\n        map.addLayer(osmMapnik);\n\n        const baseLayers = {\n          \"OSM Mapnik\": osmMapnik,\n          \"OSM Wikimedia\": osmWikimedia\n        };\n\n        L.control.layers(baseLayers).addTo(map);\n\n        if (map_geojson) {\n          L.geoJson(map_geojson).addTo(map);\n        } /* else if(map_bounds) {\n          L.rectangle(map_bounds, {color: \"#ff7800\", weight: 3, fill:false}).addTo(map);\n        } */\n      });\n\n      // this event occur only once per element\n      event.preventDefault();\n    });\n  });\n})(window, document, window.searxng);\n","/* SPDX-License-Identifier: AGPL-3.0-or-later */\n((_w, d, searxng) => {\n  if (searxng.endpoint !== \"preferences\") {\n    return;\n  }\n\n  searxng.ready(() => {\n    let engine_descriptions = null;\n\n    function load_engine_descriptions() {\n      if (engine_descriptions == null) {\n        searxng.http(\"GET\", \"engine_descriptions.json\").then((content) => {\n          engine_descriptions = JSON.parse(content);\n          for (const [engine_name, description] of Object.entries(engine_descriptions)) {\n            const elements = d.querySelectorAll(`[data-engine-name=\"${engine_name}\"] .engine-description`);\n            for (const element of elements) {\n              const source = ` (<i>${searxng.settings.translations.Source}:&nbsp;${description[1]}</i>)`;\n              element.innerHTML = description[0] + source;\n            }\n          }\n        });\n      }\n    }\n\n    for (const el of d.querySelectorAll(\"[data-engine-name]\")) {\n      searxng.on(el, \"mouseenter\", load_engine_descriptions);\n    }\n\n    const enableAllEngines = d.querySelectorAll(\".enable-all-engines\");\n    const disableAllEngines = d.querySelectorAll(\".disable-all-engines\");\n    const engineToggles = d.querySelectorAll(\"tbody input[type=checkbox][class~=checkbox-onoff]\");\n    const toggleEngines = (enable) => {\n      for (const el of engineToggles) {\n        // check if element visible, so that only engines of the current category are modified\n        if (el.offsetParent !== null) el.checked = !enable;\n      }\n    };\n    for (const el of enableAllEngines) {\n      searxng.on(el, \"click\", () => toggleEngines(true));\n    }\n    for (const el of disableAllEngines) {\n      searxng.on(el, \"click\", () => toggleEngines(false));\n    }\n\n    const copyHashButton = d.querySelector(\"#copy-hash\");\n    searxng.on(copyHashButton, \"click\", (e) => {\n      e.preventDefault();\n      navigator.clipboard.writeText(copyHashButton.dataset.hash);\n      copyHashButton.innerText = copyHashButton.dataset.copiedText;\n    });\n  });\n})(window, document, window.searxng);\n","/*!\n * swiped-events.js - v@version@\n * Pure JavaScript swipe events\n * https://github.com/john-doherty/swiped-events\n * @inspiration https://stackoverflow.com/questions/16348031/disable-scrolling-when-touch-moving-certain-element\n * @author John Doherty <www.johndoherty.info>\n * @license MIT\n */\n(function (window, document) {\n\n    'use strict';\n\n    // patch CustomEvent to allow constructor creation (IE/Chrome)\n    if (typeof window.CustomEvent !== 'function') {\n\n        window.CustomEvent = function (event, params) {\n\n            params = params || { bubbles: false, cancelable: false, detail: undefined };\n\n            var evt = document.createEvent('CustomEvent');\n            evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);\n            return evt;\n        };\n\n        window.CustomEvent.prototype = window.Event.prototype;\n    }\n\n    document.addEventListener('touchstart', handleTouchStart, false);\n    document.addEventListener('touchmove', handleTouchMove, false);\n    document.addEventListener('touchend', handleTouchEnd, false);\n\n    var xDown = null;\n    var yDown = null;\n    var xDiff = null;\n    var yDiff = null;\n    var timeDown = null;\n    var startEl = null;\n    var touchCount = 0;\n\n    /**\n     * Fires swiped event if swipe detected on touchend\n     * @param {object} e - browser event object\n     * @returns {void}\n     */\n    function handleTouchEnd(e) {\n\n        // if the user released on a different target, cancel!\n        if (startEl !== e.target) return;\n\n        var swipeThreshold = parseInt(getNearestAttribute(startEl, 'data-swipe-threshold', '20'), 10); // default 20 units\n        var swipeUnit = getNearestAttribute(startEl, 'data-swipe-unit', 'px'); // default px\n        var swipeTimeout = parseInt(getNearestAttribute(startEl, 'data-swipe-timeout', '500'), 10);    // default 500ms\n        var timeDiff = Date.now() - timeDown;\n        var eventType = '';\n        var changedTouches = e.changedTouches || e.touches || [];\n\n        if (swipeUnit === 'vh') {\n            swipeThreshold = Math.round((swipeThreshold / 100) * document.documentElement.clientHeight); // get percentage of viewport height in pixels\n        }\n        if (swipeUnit === 'vw') {\n            swipeThreshold = Math.round((swipeThreshold / 100) * document.documentElement.clientWidth); // get percentage of viewport height in pixels\n        }\n\n        if (Math.abs(xDiff) > Math.abs(yDiff)) { // most significant\n            if (Math.abs(xDiff) > swipeThreshold && timeDiff < swipeTimeout) {\n                if (xDiff > 0) {\n                    eventType = 'swiped-left';\n                }\n                else {\n                    eventType = 'swiped-right';\n                }\n            }\n        }\n        else if (Math.abs(yDiff) > swipeThreshold && timeDiff < swipeTimeout) {\n            if (yDiff > 0) {\n                eventType = 'swiped-up';\n            }\n            else {\n                eventType = 'swiped-down';\n            }\n        }\n\n        if (eventType !== '') {\n\n            var eventData = {\n                dir: eventType.replace(/swiped-/, ''),\n                touchType: (changedTouches[0] || {}).touchType || 'direct',\n                fingers: touchCount, // Number of fingers used\n                xStart: parseInt(xDown, 10),\n                xEnd: parseInt((changedTouches[0] || {}).clientX || -1, 10),\n                yStart: parseInt(yDown, 10),\n                yEnd: parseInt((changedTouches[0] || {}).clientY || -1, 10)\n            };\n\n            // fire `swiped` event event on the element that started the swipe\n            startEl.dispatchEvent(new CustomEvent('swiped', { bubbles: true, cancelable: true, detail: eventData }));\n\n            // fire `swiped-dir` event on the element that started the swipe\n            startEl.dispatchEvent(new CustomEvent(eventType, { bubbles: true, cancelable: true, detail: eventData }));\n        }\n\n        // reset values\n        xDown = null;\n        yDown = null;\n        timeDown = null;\n    }\n    /**\n     * Records current location on touchstart event\n     * @param {object} e - browser event object\n     * @returns {void}\n     */\n    function handleTouchStart(e) {\n\n        // if the element has data-swipe-ignore=\"true\" we stop listening for swipe events\n        if (e.target.getAttribute('data-swipe-ignore') === 'true') return;\n\n        startEl = e.target;\n\n        timeDown = Date.now();\n        xDown = e.touches[0].clientX;\n        yDown = e.touches[0].clientY;\n        xDiff = 0;\n        yDiff = 0;\n        touchCount = e.touches.length;\n    }\n\n    /**\n     * Records location diff in px on touchmove event\n     * @param {object} e - browser event object\n     * @returns {void}\n     */\n    function handleTouchMove(e) {\n\n        if (!xDown || !yDown) return;\n\n        var xUp = e.touches[0].clientX;\n        var yUp = e.touches[0].clientY;\n\n        xDiff = xDown - xUp;\n        yDiff = yDown - yUp;\n    }\n\n    /**\n     * Gets attribute off HTML element or nearest parent\n     * @param {object} el - HTML element to retrieve attribute from\n     * @param {string} attributeName - name of the attribute\n     * @param {any} defaultValue - default value to return if no match found\n     * @returns {any} attribute value or defaultValue\n     */\n    function getNearestAttribute(el, attributeName, defaultValue) {\n\n        // walk up the dom tree looking for attributeName\n        while (el && el !== document.documentElement) {\n\n            var attributeValue = el.getAttribute(attributeName);\n\n            if (attributeValue) {\n                return attributeValue;\n            }\n\n            el = el.parentNode;\n        }\n\n        return defaultValue;\n    }\n\n}(window, document));\n","/* SPDX-License-Identifier: AGPL-3.0-or-later */\n\nimport \"../../../node_modules/swiped-events/src/swiped-events.js\";\n\n((w, d, searxng) => {\n  if (searxng.endpoint !== \"results\") {\n    return;\n  }\n\n  searxng.ready(() => {\n    d.querySelectorAll(\"#urls img\").forEach((img) =>\n      img.addEventListener(\n        \"error\",\n        () => {\n          // console.log(\"ERROR can't load: \" + img.src);\n          img.src = `${window.searxng.settings.theme_static_path}/img/img_load_error.svg`;\n        },\n        { once: true }\n      )\n    );\n\n    if (d.querySelector(\"#search_url button#copy_url\")) {\n      d.querySelector(\"#search_url button#copy_url\").style.display = \"block\";\n    }\n\n    searxng.on(\".btn-collapse\", \"click\", function () {\n      const btnLabelCollapsed = this.getAttribute(\"data-btn-text-collapsed\");\n      const btnLabelNotCollapsed = this.getAttribute(\"data-btn-text-not-collapsed\");\n      const target = this.getAttribute(\"data-target\");\n      const targetElement = d.querySelector(target);\n      let html = this.innerHTML;\n      if (this.classList.contains(\"collapsed\")) {\n        html = html.replace(btnLabelCollapsed, btnLabelNotCollapsed);\n      } else {\n        html = html.replace(btnLabelNotCollapsed, btnLabelCollapsed);\n      }\n      this.innerHTML = html;\n      this.classList.toggle(\"collapsed\");\n      targetElement.classList.toggle(\"invisible\");\n    });\n\n    searxng.on(\".media-loader\", \"click\", function () {\n      const target = this.getAttribute(\"data-target\");\n      const iframe_load = d.querySelector(`${target} > iframe`);\n      const srctest = iframe_load.getAttribute(\"src\");\n      if (srctest === null || srctest === undefined || srctest === false) {\n        iframe_load.setAttribute(\"src\", iframe_load.getAttribute(\"data-src\"));\n      }\n    });\n\n    searxng.on(\"#copy_url\", \"click\", function () {\n      const target = this.parentElement.querySelector(\"pre\");\n      navigator.clipboard.writeText(target.innerText);\n      this.innerText = this.dataset.copiedText;\n    });\n\n    // searxng.selectImage (gallery)\n    // -----------------------------\n\n    // setTimeout() ID, needed to cancel *last* loadImage\n    let imgTimeoutID;\n\n    // progress spinner, while an image is loading\n    const imgLoaderSpinner = d.createElement(\"div\");\n    imgLoaderSpinner.classList.add(\"loader\");\n\n    // singleton image object, which is used for all loading processes of a\n    // detailed image\n    const imgLoader = new Image();\n\n    const loadImage = (imgSrc, onSuccess) => {\n      // if defered image load exists, stop defered task.\n      if (imgTimeoutID) clearTimeout(imgTimeoutID);\n\n      // defer load of the detail image for 1 sec\n      imgTimeoutID = setTimeout(() => {\n        imgLoader.src = imgSrc;\n      }, 1000);\n\n      // set handlers in the on-properties\n      imgLoader.onload = () => {\n        onSuccess();\n        imgLoaderSpinner.remove();\n      };\n      imgLoader.onerror = () => {\n        imgLoaderSpinner.remove();\n      };\n    };\n\n    searxng.selectImage = (resultElement) => {\n      // add a class that can be evaluated in the CSS and indicates that the\n      // detail view is open\n      d.getElementById(\"results\").classList.add(\"image-detail-open\");\n\n      // add a hash to the browser history so that pressing back doesn't return\n      // to the previous page this allows us to dismiss the image details on\n      // pressing the back button on mobile devices\n      window.location.hash = \"#image-viewer\";\n\n      searxng.scrollPageToSelected();\n\n      // if there is none element given by the caller, stop here\n      if (!resultElement) return;\n\n      // find <img> object in the element, if there is none, stop here.\n      const img = resultElement.querySelector(\".result-images-source img\");\n      if (!img) return;\n\n      // <img src=\"\" data-src=\"http://example.org/image.jpg\">\n      const src = img.getAttribute(\"data-src\");\n\n      // already loaded high-res image or no high-res image available\n      if (!src) return;\n\n      // use the image thumbnail until the image is fully loaded\n      const thumbnail = resultElement.querySelector(\".image_thumbnail\");\n      img.src = thumbnail.src;\n\n      // show a progress spinner\n      const detailElement = resultElement.querySelector(\".detail\");\n      detailElement.appendChild(imgLoaderSpinner);\n\n      // load full size image in background\n      loadImage(src, () => {\n        // after the singelton loadImage has loaded the detail image into the\n        // cache, it can be used in the origin <img> as src property.\n        img.src = src;\n        img.removeAttribute(\"data-src\");\n      });\n    };\n\n    searxng.closeDetail = () => {\n      d.getElementById(\"results\").classList.remove(\"image-detail-open\");\n      // remove #image-viewer hash from url by navigating back\n      if (window.location.hash === \"#image-viewer\") window.history.back();\n      searxng.scrollPageToSelected();\n    };\n    searxng.on(\".result-detail-close\", \"click\", (e) => {\n      e.preventDefault();\n      searxng.closeDetail();\n    });\n    searxng.on(\".result-detail-previous\", \"click\", (e) => {\n      e.preventDefault();\n      searxng.selectPrevious(false);\n    });\n    searxng.on(\".result-detail-next\", \"click\", (e) => {\n      e.preventDefault();\n      searxng.selectNext(false);\n    });\n\n    // listen for the back button to be pressed and dismiss the image details when called\n    window.addEventListener(\"hashchange\", () => {\n      if (window.location.hash !== \"#image-viewer\") searxng.closeDetail();\n    });\n\n    d.querySelectorAll(\".swipe-horizontal\").forEach((obj) => {\n      obj.addEventListener(\"swiped-left\", () => {\n        searxng.selectNext(false);\n      });\n      obj.addEventListener(\"swiped-right\", () => {\n        searxng.selectPrevious(false);\n      });\n    });\n\n    w.addEventListener(\n      \"scroll\",\n      () => {\n        const e = d.getElementById(\"backToTop\"),\n          scrollTop = document.documentElement.scrollTop || document.body.scrollTop,\n          results = d.getElementById(\"results\");\n        if (e !== null) {\n          if (scrollTop >= 100) {\n            results.classList.add(\"scrolling\");\n          } else {\n            results.classList.remove(\"scrolling\");\n          }\n        }\n      },\n      true\n    );\n  });\n})(window, document, window.searxng);\n","/* SPDX-License-Identifier: AGPL-3.0-or-later */\n/* exported AutoComplete */\n\n((_w, d, searxng) => {\n  const qinput_id = \"q\";\n  let qinput;\n\n  const isMobile = window.matchMedia(\"only screen and (max-width: 50em)\").matches;\n  const isResultsPage = document.querySelector(\"main\").id === \"main_results\";\n\n  function submitIfQuery() {\n    if (qinput.value.length > 0) {\n      const search = document.getElementById(\"search\");\n      setTimeout(search.submit.bind(search), 0);\n    }\n  }\n\n  function createClearButton(qinput) {\n    const cs = document.getElementById(\"clear_search\");\n    const updateClearButton = () => {\n      if (qinput.value.length === 0) {\n        cs.classList.add(\"empty\");\n      } else {\n        cs.classList.remove(\"empty\");\n      }\n    };\n\n    // update status, event listener\n    updateClearButton();\n    cs.addEventListener(\"click\", (ev) => {\n      qinput.value = \"\";\n      qinput.focus();\n      updateClearButton();\n      ev.preventDefault();\n    });\n    qinput.addEventListener(\"input\", updateClearButton, false);\n  }\n\n  const fetchResults = async (query) => {\n    let request;\n    if (searxng.settings.method === \"GET\") {\n      const reqParams = new URLSearchParams();\n      reqParams.append(\"q\", query);\n      request = fetch(`./autocompleter?${reqParams.toString()}`);\n    } else {\n      const formData = new FormData();\n      formData.append(\"q\", query);\n      request = fetch(\"./autocompleter\", {\n        method: \"POST\",\n        body: formData\n      });\n    }\n\n    request.then(async (response) => {\n      const results = await response.json();\n\n      if (!results) return;\n\n      const autocomplete = d.querySelector(\".autocomplete\");\n      const autocompleteList = d.querySelector(\".autocomplete ul\");\n      autocomplete.classList.add(\"open\");\n      autocompleteList.innerHTML = \"\";\n\n      // show an error message that no result was found\n      if (!results[1] || results[1].length === 0) {\n        const noItemFoundMessage = document.createElement(\"li\");\n        noItemFoundMessage.classList.add(\"no-item-found\");\n        noItemFoundMessage.innerHTML = searxng.settings.translations.no_item_found;\n        autocompleteList.appendChild(noItemFoundMessage);\n        return;\n      }\n\n      for (const result of results[1]) {\n        const li = document.createElement(\"li\");\n        li.innerText = result;\n\n        searxng.on(li, \"mousedown\", () => {\n          qinput.value = result;\n          const form = d.querySelector(\"#search\");\n          form.submit();\n          autocomplete.classList.remove(\"open\");\n        });\n        autocompleteList.appendChild(li);\n      }\n    });\n  };\n\n  searxng.ready(() => {\n    // focus search input on large screens\n    if (!isMobile && !isResultsPage) document.getElementById(\"q\").focus();\n\n    qinput = d.getElementById(qinput_id);\n    const autocomplete = d.querySelector(\".autocomplete\");\n    const autocompleteList = d.querySelector(\".autocomplete ul\");\n\n    if (qinput !== null) {\n      // clear button\n      createClearButton(qinput);\n\n      // autocompleter\n      if (searxng.settings.autocomplete) {\n        searxng.on(qinput, \"input\", () => {\n          const query = qinput.value;\n          if (query.length < searxng.settings.autocomplete_min) return;\n\n          setTimeout(() => {\n            if (query === qinput.value) fetchResults(query);\n          }, 300);\n        });\n\n        searxng.on(qinput, \"keyup\", (e) => {\n          let currentIndex = -1;\n          const listItems = autocompleteList.children;\n          for (let i = 0; i < listItems.length; i++) {\n            if (listItems[i].classList.contains(\"active\")) {\n              currentIndex = i;\n              break;\n            }\n          }\n\n          let newCurrentIndex = -1;\n          if (e.key === \"ArrowUp\") {\n            if (currentIndex >= 0) listItems[currentIndex].classList.remove(\"active\");\n            // we need to add listItems.length to the index calculation here because the JavaScript modulos\n            // operator doesn't work with negative numbers\n            newCurrentIndex = (currentIndex - 1 + listItems.length) % listItems.length;\n          } else if (e.key === \"ArrowDown\") {\n            if (currentIndex >= 0) listItems[currentIndex].classList.remove(\"active\");\n            newCurrentIndex = (currentIndex + 1) % listItems.length;\n          } else if (e.key === \"Tab\" || e.key === \"Enter\") {\n            autocomplete.classList.remove(\"open\");\n          }\n\n          if (newCurrentIndex !== -1) {\n            const selectedItem = listItems[newCurrentIndex];\n            selectedItem.classList.add(\"active\");\n\n            if (!selectedItem.classList.contains(\"no-item-found\")) qinput.value = selectedItem.innerText;\n          }\n        });\n      }\n    }\n\n    // Additionally to searching when selecting a new category, we also\n    // automatically start a new search request when the user changes a search\n    // filter (safesearch, time range or language) (this requires JavaScript\n    // though)\n    if (\n      qinput !== null &&\n      searxng.settings.search_on_category_select &&\n      // If .search_filters is undefined (invisible) we are on the homepage and\n      // hence don't have to set any listeners\n      d.querySelector(\".search_filters\") != null\n    ) {\n      searxng.on(d.getElementById(\"safesearch\"), \"change\", submitIfQuery);\n      searxng.on(d.getElementById(\"time_range\"), \"change\", submitIfQuery);\n      searxng.on(d.getElementById(\"language\"), \"change\", submitIfQuery);\n    }\n\n    const categoryButtons = d.querySelectorAll(\"button.category_button\");\n    for (const button of categoryButtons) {\n      searxng.on(button, \"click\", (event) => {\n        if (event.shiftKey) {\n          event.preventDefault();\n          button.classList.toggle(\"selected\");\n          return;\n        }\n\n        // manually deselect the old selection when a new category is selected\n        const selectedCategories = d.querySelectorAll(\"button.category_button.selected\");\n        for (const categoryButton of selectedCategories) {\n          categoryButton.classList.remove(\"selected\");\n        }\n        button.classList.add(\"selected\");\n      });\n    }\n\n    // override form submit action to update the actually selected categories\n    const form = d.querySelector(\"#search\");\n    if (form != null) {\n      searxng.on(form, \"submit\", (event) => {\n        event.preventDefault();\n        const categoryValuesInput = d.querySelector(\"#selected-categories\");\n        if (categoryValuesInput) {\n          const categoryValues = [];\n          for (const categoryButton of categoryButtons) {\n            if (categoryButton.classList.contains(\"selected\")) {\n              categoryValues.push(categoryButton.name.replace(\"category_\", \"\"));\n            }\n          }\n          categoryValuesInput.value = categoryValues.join(\",\");\n        }\n        form.submit();\n      });\n    }\n  });\n})(window, document, window.searxng);\n"],"names":["w","d","ElementPrototype","selector","nodes","i","callbackSafe","callback","el","e","exception","searxng","obj","eventType","useCapture","found","method","url","data","resolve","reject","req","ex","src","path","id","s","newNode","referenceNode","getEndpoint","className","onlyImages","newLoadSpinner","loader","replaceChildrenWith","element","children","child","loadNextPage","form","formData","response","nextPageDoc","articleList","paginationElement","articleElement","err","intersectionObserveOptions","observedSelector","observer","entries","paginationEntry","isElementInDetail","getResultElement","isImageResult","resultElement","highlightResult","baseKeyBinding","removeFocus","copyURLToClipboard","toggleHelp","searchInputFocus","GoToNextPage","openResult","GoToPreviousPage","reloadPage","keyBindingLayouts","scrollPage","scrollPageTo","keyBindings","tagName","which","noScroll","keepFocus","current","effectiveWhich","next","results","top","bot","etop","link","scrollPageToSelected","pageButtonClick","css_selector","button","sel","wtop","wheight","ebot","offset","amount","position","nav","q","len","newTab","initHelpContent","divElement","categories","key","sorted","a","html","cat","lastCategory","first","cj","helpPanel","currentUrlElement","_w","_d","event","leaflet_target","map_lon","map_lat","map_zoom","map_boundingbox","map_geojson","map_bounds","southWest","northEast","map","osmMapnikUrl","osmMapnikAttrib","osmMapnik","osmWikimediaUrl","osmWikimediaAttrib","osmWikimedia","baseLayers","engine_descriptions","load_engine_descriptions","content","engine_name","description","elements","source","enableAllEngines","disableAllEngines","engineToggles","toggleEngines","enable","copyHashButton","window","document","params","evt","handleTouchStart","handleTouchMove","handleTouchEnd","xDown","yDown","xDiff","yDiff","timeDown","startEl","touchCount","swipeThreshold","getNearestAttribute","swipeUnit","swipeTimeout","timeDiff","changedTouches","eventData","xUp","yUp","attributeName","defaultValue","attributeValue","img","btnLabelCollapsed","btnLabelNotCollapsed","target","targetElement","iframe_load","srctest","imgTimeoutID","imgLoaderSpinner","imgLoader","loadImage","imgSrc","onSuccess","thumbnail","scrollTop","qinput_id","qinput","isMobile","isResultsPage","submitIfQuery","search","createClearButton","cs","updateClearButton","ev","fetchResults","query","request","reqParams","autocomplete","autocompleteList","noItemFoundMessage","result","li","currentIndex","listItems","newCurrentIndex","selectedItem","categoryButtons","selectedCategories","categoryButton","categoryValuesInput","categoryValues"],"mappings":"AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAMA,OAAO,SAAW,CAACA,EAAGC,IAAM,CAKtBD,EAAE,UACFE,GAAqB,CACrBA,EAAiB,QACfA,EAAiB,SACjBA,EAAiB,iBACjBA,EAAiB,uBACjBA,EAAiB,mBACjB,SAAUC,EAAU,CAClB,MAAMC,GAAS,KAAK,YAAc,KAAK,UAAU,iBAAiBD,CAAQ,EAC1E,IAAIE,EAAI,GACR,KAAOD,EAAM,EAAEC,CAAC,GAAKD,EAAMC,CAAC,IAAM,MAAK,CACvC,MAAO,CAAC,CAACD,EAAMC,CAAC,CAC1B,CACA,GAAO,QAAQ,SAAS,EAGtB,SAASC,EAAaC,EAAUC,EAAIC,EAAG,CACrC,GAAI,CACFF,EAAS,KAAKC,EAAIC,CAAC,CACzB,OAAaC,EAAW,CAClB,QAAQ,IAAIA,CAAS,CAC3B,CACA,CAEE,MAAMC,EAAU,OAAO,SAAW,CAAA,EAElCA,EAAQ,GAAK,CAACC,EAAKC,EAAWN,EAAUO,IAAe,CACrDA,EAAaA,GAAc,GACvB,OAAOF,GAAQ,SAEjBA,EAAI,iBAAiBC,EAAWN,EAAUO,CAAU,EAGpDb,EAAE,iBACAY,EACCJ,GAAM,CACL,IAAID,EAAKC,EAAE,QAAUA,EAAE,WACnBM,EAAQ,GAEZ,KAAOP,GAAA,MAAAA,EAAI,SAAWA,IAAOP,IAC3Bc,EAAQP,EAAG,QAAQI,CAAG,EAElB,CAAAG,IAEJP,EAAKA,EAAG,cAGNO,GACFT,EAAaC,EAAUC,EAAIC,CAAC,CAExC,EACQK,CACR,CAEA,EAEEH,EAAQ,MAASJ,GAAa,CACxB,SAAS,aAAe,UAC1BA,EAAS,KAAKP,CAAC,EAEfA,EAAE,iBAAiB,mBAAoBO,EAAS,KAAKP,CAAC,CAAC,CAE7D,EAEEW,EAAQ,KAAO,CAACK,EAAQC,EAAKC,EAAO,OAClC,IAAI,QAAQ,CAACC,EAASC,IAAW,CAC/B,GAAI,CACF,MAAMC,EAAM,IAAI,eAChBA,EAAI,KAAKL,EAAQC,EAAK,EAAI,EAC1BI,EAAI,QAAU,IAGdA,EAAI,OAAS,IAAM,CACbA,EAAI,SAAW,IACjBF,EAAQE,EAAI,SAAUA,EAAI,YAAY,EAEtCD,EAAO,MAAMC,EAAI,UAAU,CAAC,CAExC,EAGQA,EAAI,QAAU,IAAM,CAClBD,EAAO,MAAM,eAAe,CAAC,CACvC,EAEQC,EAAI,QAAU,IAAM,CAClBD,EAAO,MAAM,wBAAwB,CAAC,CAChD,EAEQC,EAAI,UAAY,IAAM,CACpBD,EAAO,MAAM,SAAS,CAAC,CACjC,EAGYF,EACFG,EAAI,KAAKH,CAAI,EAEbG,EAAI,KAAI,CAElB,OAAeC,EAAI,CACXF,EAAOE,CAAE,CACjB,CACA,CAAK,EAEHX,EAAQ,UAAaY,GAAQ,CAC3B,MAAMC,EAAO,GAAGb,EAAQ,SAAS,iBAAiB,IAAIY,CAAG,GACnDE,EAAK,SAASF,EAAI,QAAQ,IAAK,GAAG,CAAC,GACzC,IAAI,EAAItB,EAAE,eAAewB,CAAE,EACvB,IAAM,OACR,EAAIxB,EAAE,cAAc,MAAM,EAC1B,EAAE,aAAa,KAAMwB,CAAE,EACvB,EAAE,aAAa,MAAO,YAAY,EAClC,EAAE,aAAa,OAAQ,UAAU,EACjC,EAAE,aAAa,OAAQD,CAAI,EAC3BvB,EAAE,KAAK,YAAY,CAAC,EAE1B,EAEEU,EAAQ,WAAa,CAACY,EAAKhB,IAAa,CACtC,MAAMiB,EAAO,GAAGb,EAAQ,SAAS,iBAAiB,IAAIY,CAAG,GACnDE,EAAK,UAAUF,EAAI,QAAQ,IAAK,GAAG,CAAC,GAC1C,IAAIG,EAAIzB,EAAE,eAAewB,CAAE,EAC3B,GAAIC,IAAM,KACRA,EAAIzB,EAAE,cAAc,QAAQ,EAC5ByB,EAAE,aAAa,KAAMD,CAAE,EACvBC,EAAE,aAAa,MAAOF,CAAI,EAC1BE,EAAE,OAASnB,EACXmB,EAAE,QAAU,IAAM,CAChBA,EAAE,aAAa,QAAS,GAAG,CACnC,EACMzB,EAAE,KAAK,YAAYyB,CAAC,UACVA,EAAE,aAAa,OAAO,EAOhC,QAAQ,IAAI,mCAAmCF,CAAI,eAAe,MANlE,IAAI,CACFjB,EAAS,MAAMmB,EAAG,EAAE,CAC5B,OAAehB,EAAW,CAClB,QAAQ,IAAIA,CAAS,CAC7B,CAIA,EAEEC,EAAQ,aAAe,CAACgB,EAASC,IAAkB,CACjDA,EAAc,WAAW,aAAaD,EAASC,CAAa,CAChE,EAEEjB,EAAQ,YAAc,CAACgB,EAASC,IAAkB,CAChDA,EAAc,WAAW,YAAYD,EAASC,EAAc,WAAW,CAC3E,EAEEjB,EAAQ,GAAG,SAAU,QAAS,UAAY,CACxC,KAAK,WAAW,UAAU,IAAI,WAAW,CAC7C,CAAG,EAED,SAASkB,GAAc,CACrB,UAAWC,KAAa7B,EAAE,qBAAqB,MAAM,EAAE,CAAC,EAAE,UAAU,SAClE,GAAI6B,EAAU,SAAS,WAAW,EAChC,OAAOA,EAAU,MAAM,GAAG,EAAE,CAAC,EAGjC,MAAO,EACX,CAEE,OAAAnB,EAAQ,SAAWkB,EAAW,EAEvBlB,CACT,GAAG,OAAQ,QAAQ,EC7KnB,QAAQ,MAAM,IAAM,CAMlB,GALA,QAAQ,0BACN,yBAA0B,QAC1B,8BAA+B,QAC/B,sBAAuB,OAAO,0BAA0B,UAEtD,QAAQ,WAAa,UACvB,OAGF,GAAI,CAAC,QAAQ,0BAA2B,CACtC,QAAQ,IAAI,oCAAoC,EAChD,MACJ,CAEE,MAAMV,EAAI,SACJ8B,EAAa9B,EAAE,eAAe,SAAS,EAAE,UAAU,SAAS,sBAAsB,EAExF,SAAS+B,GAAiB,CACxB,MAAMC,EAAShC,EAAE,cAAc,KAAK,EACpC,OAAAgC,EAAO,UAAU,IAAI,QAAQ,EACtBA,CACX,CAEE,SAASC,EAAoBC,EAASC,EAAU,CAC9CD,EAAQ,YAAc,GACtBC,EAAS,QAASC,GAAUF,EAAQ,YAAYE,CAAK,CAAC,CAC1D,CAEE,SAASC,EAAa/B,EAAU,CAC9B,MAAMgC,EAAOtC,EAAE,cAAc,4BAA4B,EACzD,GAAI,CAACsC,EACH,OAEFL,EAAoBjC,EAAE,cAAc,aAAa,EAAG,CAAC+B,EAAc,CAAE,CAAC,EACtE,MAAMQ,EAAW,IAAI,SAASD,CAAI,EAClC,QACG,KAAK,OAAQtC,EAAE,cAAc,SAAS,EAAE,aAAa,QAAQ,EAAGuC,CAAQ,EACxE,KAAMC,GAAa,CAClB,MAAMC,EAAc,IAAI,UAAS,EAAG,gBAAgBD,EAAU,WAAW,EACnEE,EAAcD,EAAY,iBAAiB,eAAe,EAC1DE,EAAoBF,EAAY,cAAc,aAAa,EACjEzC,EAAE,cAAc,aAAa,EAAE,OAAM,EACjC0C,EAAY,OAAS,GAAK,CAACZ,GAE7B9B,EAAE,cAAc,OAAO,EAAE,YAAYA,EAAE,cAAc,IAAI,CAAC,EAE5D0C,EAAY,QAASE,GAAmB,CACtC5C,EAAE,cAAc,OAAO,EAAE,YAAY4C,CAAc,CAC7D,CAAS,EACGD,IACF3C,EAAE,cAAc,UAAU,EAAE,YAAY2C,CAAiB,EACzDrC,EAAQ,EAElB,CAAO,EACA,MAAOuC,GAAQ,CACd,QAAQ,IAAIA,CAAG,EACf,MAAMrC,EAAIR,EAAE,cAAc,KAAK,EAC/BQ,EAAE,YAAc,QAAQ,SAAS,aAAa,wBAC9CA,EAAE,UAAU,IAAI,cAAc,EAC9BA,EAAE,aAAa,OAAQ,OAAO,EAC9ByB,EAAoBjC,EAAE,cAAc,aAAa,EAAG,CAACQ,CAAC,CAAC,CAC/D,CAAO,CACP,CAEE,GAAI,QAAQ,SAAS,iBAAmB,QAAQ,0BAA2B,CACzE,MAAMsC,EAA6B,CACjC,WAAY,OAClB,EACUC,EAAmB,4BACnBC,EAAW,IAAI,qBAAsBC,GAAY,CACrD,MAAMC,EAAkBD,EAAQ,CAAC,EAC7BC,EAAgB,iBAClBF,EAAS,UAAUE,EAAgB,MAAM,EACzCb,EAAa,IAAMW,EAAS,QAAQhD,EAAE,cAAc+C,CAAgB,EAAGD,CAA0B,CAAC,EAE1G,CAAK,EACDE,EAAS,QAAQhD,EAAE,cAAc+C,CAAgB,EAAGD,CAA0B,CAClF,CACA,CAAC,EChFD,QAAQ,MAAM,IAAM,CAClB,SAASK,EAAkB5C,EAAI,CAC7B,KAAOA,IAAO,QAAW,CACvB,GAAIA,EAAG,UAAU,SAAS,QAAQ,EAChC,MAAO,GAET,GAAIA,EAAG,UAAU,SAAS,QAAQ,EAGhC,MAAO,GAETA,EAAKA,EAAG,UACd,CACI,MAAO,EACX,CAEE,SAAS6C,EAAiB7C,EAAI,CAC5B,KAAOA,IAAO,QAAW,CACvB,GAAIA,EAAG,UAAU,SAAS,QAAQ,EAChC,OAAOA,EAETA,EAAKA,EAAG,UACd,CAEA,CAEE,SAAS8C,EAAcC,EAAe,CACpC,OAAOA,GAAA,YAAAA,EAAe,UAAU,SAAS,gBAC7C,CAEE,QAAQ,GAAG,UAAW,QAAS,SAAU,EAAG,CAC1C,GAAI,CAACH,EAAkB,EAAE,MAAM,EAAG,CAChCI,EAAgB,IAAI,EAAE,GAAM,EAAI,EAChC,MAAMD,EAAgBF,EAAiB,EAAE,MAAM,EAC3CC,EAAcC,CAAa,IAC7B,EAAE,eAAc,EAChB,QAAQ,YAAYA,CAAa,EAEzC,CACA,CAAG,EAED,QAAQ,GACN,YACA,QACC,GAAM,CACL,GAAI,CAACH,EAAkB,EAAE,MAAM,EAAG,CAChC,MAAMG,EAAgBF,EAAiB,EAAE,MAAM,EAC3CE,GAAiBA,EAAc,aAAa,mBAAmB,IAAM,MACvEC,EAAgBD,CAAa,EAAE,EAAI,EAEjCD,EAAcC,CAAa,GAC7B,QAAQ,YAAYA,CAAa,CAE3C,CACA,EACI,EACJ,EAGE,MAAME,EAAiB,CACrB,OAAQ,CACN,IAAK,MACL,IAAKC,EACL,IAAK,sCACL,IAAK,SACX,EACI,EAAG,CACD,IAAK,IACL,IAAKC,EACL,IAAK,mDACL,IAAK,SACX,EACI,EAAG,CACD,IAAK,IACL,IAAKC,EACL,IAAK,qBACL,IAAK,OACX,EACI,EAAG,CACD,IAAK,IACL,IAAKC,EACL,IAAK,4BACL,IAAK,SACX,EACI,EAAG,CACD,IAAK,IACL,IAAKC,EAAY,EACjB,IAAK,kBACL,IAAK,SACX,EACI,EAAG,CACD,IAAK,IACL,IAAKC,EAAW,EAAK,EACrB,IAAK,qBACL,IAAK,SACX,EACI,EAAG,CACD,IAAK,IACL,IAAKC,EAAgB,EACrB,IAAK,sBACL,IAAK,SACX,EACI,EAAG,CACD,IAAK,IACL,IAAKC,EACL,IAAK,8BACL,IAAK,SACX,EACI,EAAG,CACD,IAAK,IACL,IAAKF,EAAW,EAAI,EACpB,IAAK,+BACL,IAAK,SACX,CACA,EACQG,EAAoB,CACxB,QAAS,OAAO,OACd,CAEE,UAAW,CACT,IAAK,IACL,IAAKV,EAAgB,IAAI,EACzB,IAAK,gCACL,IAAK,SACf,EACQ,WAAY,CACV,IAAK,IACL,IAAKA,EAAgB,MAAM,EAC3B,IAAK,4BACL,IAAK,SACf,CACA,EACMC,CACN,EAEI,IAAK,OAAO,OACV,CAEE,EAAG,CACD,IAAK,IACL,IAAKU,EAAW,CAAC,OAAO,WAAW,EACnC,IAAK,qBACL,IAAK,YACf,EACQ,EAAG,CACD,IAAK,IACL,IAAKA,EAAW,OAAO,WAAW,EAClC,IAAK,uBACL,IAAK,YACf,EACQ,EAAG,CACD,IAAK,IACL,IAAKA,EAAW,CAAC,OAAO,YAAc,CAAC,EACvC,IAAK,wBACL,IAAK,YACf,EACQ,EAAG,CACD,IAAK,IACL,IAAKA,EAAW,OAAO,YAAc,CAAC,EACtC,IAAK,0BACL,IAAK,YACf,EACQ,EAAG,CACD,IAAK,IACL,IAAKC,EAAa,CAAC,SAAS,KAAK,aAAc,KAAK,EACpD,IAAK,gCACL,IAAK,YACf,EACQ,EAAG,CACD,IAAK,IACL,IAAKA,EAAa,SAAS,KAAK,aAAc,QAAQ,EACtD,IAAK,mCACL,IAAK,YACf,EACQ,EAAG,CACD,IAAK,IACL,IAAKZ,EAAgB,IAAI,EACzB,IAAK,gCACL,IAAK,SACf,EACQ,EAAG,CACD,IAAK,IACL,IAAKA,EAAgB,MAAM,EAC3B,IAAK,4BACL,IAAK,SACf,EACQ,EAAG,CACD,IAAK,IACL,IAAKG,EACL,IAAK,mDACL,IAAK,SACf,CACA,EACMF,CACN,CACA,EAEQY,EAAcH,EAAkB,QAAQ,SAAS,OAAO,GAAKA,EAAkB,QAErF,QAAQ,GAAG,SAAU,UAAY,GAAM,CAErC,GAEE,OAAO,UAAU,eAAe,KAAKG,EAAa,EAAE,GAAG,GACvD,CAAC,EAAE,SACH,CAAC,EAAE,QACH,CAAC,EAAE,UACH,CAAC,EAAE,QACH,CACA,MAAMC,EAAU,EAAE,OAAO,QAAQ,YAAW,EACxC,EAAE,MAAQ,SACZD,EAAY,EAAE,GAAG,EAAE,IAAI,CAAC,GAEpB,EAAE,SAAW,SAAS,MAAQC,IAAY,KAAOA,IAAY,YAC/D,EAAE,eAAc,EAChBD,EAAY,EAAE,GAAG,EAAE,IAAG,EAGhC,CACA,CAAG,EAED,SAASb,EAAgBe,EAAO,CAC9B,MAAO,CAACC,EAAUC,IAAc,CAC9B,IAAIC,EAAU,SAAS,cAAc,4BAA4B,EAC/DC,EAAiBJ,EACnB,GAAIG,IAAY,KAAM,CAGpB,GADAA,EAAU,SAAS,cAAc,SAAS,EACtCA,IAAY,KAEd,QAGEH,IAAU,QAAUA,IAAU,QAChCI,EAAiBD,EAE3B,CAEM,IAAIE,EACFC,EAAU,SAAS,iBAAiB,SAAS,EAG/C,GAFAA,EAAU,MAAM,KAAKA,CAAO,EAExB,OAAOF,GAAmB,SAC5BC,EAAOD,MAEP,QAAQA,EAAc,CACpB,IAAK,UAAW,CACd,MAAMG,EAAM,SAAS,gBAAgB,WAAa,SAAS,KAAK,UAC1DC,EAAMD,EAAM,SAAS,gBAAgB,aAE3C,QAASzE,EAAI,EAAGA,EAAIwE,EAAQ,OAAQxE,IAAK,CACvCuE,EAAOC,EAAQxE,CAAC,EAChB,MAAM2E,EAAOJ,EAAK,UAGlB,GAFaI,EAAOJ,EAAK,cAEbG,GAAOC,EAAOF,EACxB,KAEhB,CACY,KACZ,CACU,IAAK,OACHF,EAAOC,EAAQA,EAAQ,QAAQH,CAAO,EAAI,CAAC,GAAKA,EAChD,MACF,IAAK,KACHE,EAAOC,EAAQA,EAAQ,QAAQH,CAAO,EAAI,CAAC,GAAKA,EAChD,MACF,IAAK,SACHE,EAAOC,EAAQA,EAAQ,OAAS,CAAC,EACjC,MAEF,IAAK,MAEL,QACED,EAAOC,EAAQ,CAAC,CAC5B,CAGM,GAAID,EAAM,CAGR,GAFAF,EAAQ,gBAAgB,mBAAmB,EAC3CE,EAAK,aAAa,oBAAqB,MAAM,EACzC,CAACH,EAAW,CACd,MAAMQ,EAAOL,EAAK,cAAc,MAAM,GAAKA,EAAK,cAAc,GAAG,EAC7DK,IAAS,MACXA,EAAK,MAAK,CAEtB,CACaT,GACHU,EAAoB,CAE9B,CACA,CACA,CAEE,SAASjB,GAAa,CACpB,SAAS,SAAS,OAAO,EAAI,CACjC,CAEE,SAASP,EAAY,EAAG,CACtB,MAAMY,EAAU,EAAE,OAAO,QAAQ,YAAW,EACxC,SAAS,gBAAkBA,IAAY,SAAWA,IAAY,UAAYA,IAAY,YACxF,SAAS,cAAc,KAAI,EAE3B,QAAQ,YAAW,CAEzB,CAEE,SAASa,EAAgBC,EAAc,CACrC,MAAO,IAAM,CACX,MAAMC,EAAS,SAAS,cAAcD,CAAY,EAC9CC,GACFA,EAAO,MAAK,CAEpB,CACA,CAEE,SAASvB,GAAe,CACtB,OAAOqB,EAAgB,iDAAiD,CAC5E,CAEE,SAASnB,GAAmB,CAC1B,OAAOmB,EAAgB,qDAAqD,CAChF,CAEE,SAASD,GAAuB,CAC9B,MAAMI,EAAM,SAAS,cAAc,4BAA4B,EAC/D,GAAIA,IAAQ,KACV,OAEF,MAAMC,EAAO,SAAS,gBAAgB,WAAa,SAAS,KAAK,UAC/DC,EAAU,SAAS,gBAAgB,aACnCR,EAAOM,EAAI,UACXG,EAAOT,EAAOM,EAAI,aAClBI,EAAS,IAEX,GAAIJ,EAAI,yBAA2B,MAAQG,EAAOD,EAAS,CAGzD,OAAO,OAAO,OAAO,QAAS,CAAC,EAC/B,MACN,CACQD,EAAOP,EAAOU,EAChB,OAAO,OAAO,OAAO,QAASV,EAAOU,CAAM,EAE9BH,EAAOC,EACTC,EAAOC,GAChB,OAAO,OAAO,OAAO,QAASD,EAAOD,EAAUE,CAAM,CAG7D,CAEE,SAASvB,EAAWwB,EAAQ,CAC1B,MAAO,IAAM,CACX,OAAO,SAAS,EAAGA,CAAM,EACzBnC,EAAgB,SAAS,EAAC,CAChC,CACA,CAEE,SAASY,EAAawB,EAAUC,EAAK,CACnC,MAAO,IAAM,CACX,OAAO,SAAS,EAAGD,CAAQ,EAC3BpC,EAAgBqC,CAAG,EAAC,CAC1B,CACA,CAEE,SAAShC,GAAmB,CAC1B,OAAO,SAAS,EAAG,CAAC,EACpB,MAAMiC,EAAI,SAAS,cAAc,IAAI,EAErC,GADAA,EAAE,MAAK,EACHA,EAAE,kBAAmB,CACvB,MAAMC,EAAMD,EAAE,MAAM,OACpBA,EAAE,kBAAkBC,EAAKA,CAAG,CAClC,CACA,CAEE,SAAShC,EAAWiC,EAAQ,CAC1B,MAAO,IAAM,CACX,IAAIf,EAAO,SAAS,cAAc,iCAAiC,EAInE,GAHIA,IAAS,OACXA,EAAO,SAAS,cAAc,gCAAgC,GAE5DA,IAAS,KAAM,CACjB,MAAMhE,EAAMgE,EAAK,aAAa,MAAM,EAChCe,EACF,OAAO,KAAK/E,CAAG,EAEf,OAAO,SAAS,KAAOA,CAEjC,CACA,CACA,CAEE,SAASgF,EAAgBC,EAAY,CACnC,MAAMC,EAAa,CAAA,EAEnB,UAAW,KAAK9B,EAAa,CAC3B,MAAM+B,EAAM/B,EAAY,CAAC,EACzB8B,EAAWC,EAAI,GAAG,EAAID,EAAWC,EAAI,GAAG,GAAK,CAAA,EAC7CD,EAAWC,EAAI,GAAG,EAAE,KAAKA,CAAG,CAClC,CAEI,MAAMC,EAAS,OAAO,KAAKF,CAAU,EAAE,KAAK,CAACG,EAAG,IAAMH,EAAW,CAAC,EAAE,OAASA,EAAWG,CAAC,EAAE,MAAM,EAEjG,GAAID,EAAO,SAAW,EACpB,OAGF,IAAIE,EAAO,mEACXA,GAAQ,gDACRA,GAAQ,UAER,QAASlG,EAAI,EAAGA,EAAIgG,EAAO,OAAQhG,IAAK,CACtC,MAAMmG,EAAML,EAAWE,EAAOhG,CAAC,CAAC,EAE1BoG,EAAepG,IAAMgG,EAAO,OAAS,EACrCK,EAAQrG,EAAI,IAAM,EAEpBqG,IACFH,GAAQ,QAEVA,GAAQ,OAERA,GAAQ,OAAOC,EAAI,CAAC,EAAE,GAAG,QACzBD,GAAQ,6BAER,UAAWI,KAAMH,EACfD,GAAQ,YAAYC,EAAIG,CAAE,EAAE,GAAG,UAAUH,EAAIG,CAAE,EAAE,GAAG,QAGtDJ,GAAQ,QACRA,GAAQ,SAEJ,CAACG,GAASD,KACZF,GAAQ,QAEhB,CAEIA,GAAQ,WAERL,EAAW,UAAYK,CAC3B,CAEE,SAAS3C,GAAa,CACpB,IAAIgD,EAAY,SAAS,cAAc,mBAAmB,EAC3BA,GAAc,MAE3CA,EAAY,SAAS,cAAc,KAAK,EACxCA,EAAU,GAAK,mBACfA,EAAU,UAAY,eACtBX,EAAgBW,CAAS,EACZ,SAAS,qBAAqB,MAAM,EAAE,CAAC,EAC/C,YAAYA,CAAS,GAG1BA,EAAU,UAAU,OAAO,WAAW,CAE5C,CAEE,SAASjD,GAAqB,CAC5B,MAAMkD,EAAoB,SAAS,cAAc,iCAAiC,EAClF,GAAIA,IAAsB,KAAM,OAEhC,MAAM5F,EAAM4F,EAAkB,aAAa,MAAM,EACjD,UAAU,UAAU,UAAU5F,CAAG,CACrC,CAEE,QAAQ,qBAAuBiE,EAC/B,QAAQ,WAAa1B,EAAgB,MAAM,EAC3C,QAAQ,eAAiBA,EAAgB,IAAI,CAC/C,CAAC,GCtdA,CAACsD,EAAIC,EAAIpG,IAAY,CACpBA,EAAQ,MAAM,IAAM,CAClBA,EAAQ,GAAG,oBAAqB,QAAS,SAAUqG,EAAO,CAExD,KAAK,UAAU,OAAO,kBAAkB,EAGxC,MAAMC,EAAiB,KAAK,QAAQ,cAC9BC,EAAU,WAAW,KAAK,QAAQ,MAAM,EACxCC,EAAU,WAAW,KAAK,QAAQ,MAAM,EACxCC,EAAW,WAAW,KAAK,QAAQ,OAAO,EAC1CC,EAAkB,KAAK,MAAM,KAAK,QAAQ,cAAc,EACxDC,EAAc,KAAK,MAAM,KAAK,QAAQ,UAAU,EAEtD3G,EAAQ,UAAU,iBAAiB,EACnCA,EAAQ,WAAW,gBAAiB,IAAM,CACxC,IAAI4G,EAAa,KACjB,GAAIF,EAAiB,CACnB,MAAMG,EAAY,EAAE,OAAOH,EAAgB,CAAC,EAAGA,EAAgB,CAAC,CAAC,EAC3DI,EAAY,EAAE,OAAOJ,EAAgB,CAAC,EAAGA,EAAgB,CAAC,CAAC,EACjEE,EAAa,EAAE,aAAaC,EAAWC,CAAS,CAC1D,CAGQ,MAAMC,EAAM,EAAE,IAAIT,CAAc,EAE1BU,EAAe,qDACfC,EAAkB,gFAClBC,EAAY,IAAI,EAAE,UAAUF,EAAc,CAAE,QAAS,EAAG,QAAS,GAAI,YAAaC,CAAe,CAAE,EACnGE,EAAkB,sDAClBC,EACJ,kGACIC,EAAe,IAAI,EAAE,UAAUF,EAAiB,CACpD,QAAS,EACT,QAAS,GACT,YAAaC,CACvB,CAAS,EAEGR,EAGF,WAAW,IAAM,CACfG,EAAI,UAAUH,EAAY,CACxB,QAAS,EACvB,CAAa,CACb,EAAa,CAAC,EACKL,GAAWC,IAChBC,EACFM,EAAI,QAAQ,IAAI,EAAE,OAAOP,EAASD,CAAO,EAAGE,CAAQ,EAEpDM,EAAI,QAAQ,IAAI,EAAE,OAAOP,EAASD,CAAO,EAAG,CAAC,GAIjDQ,EAAI,SAASG,CAAS,EAEtB,MAAMI,EAAa,CACjB,aAAcJ,EACd,gBAAiBG,CAC3B,EAEQ,EAAE,QAAQ,OAAOC,CAAU,EAAE,MAAMP,CAAG,EAElCJ,GACF,EAAE,QAAQA,CAAW,EAAE,MAAMI,CAAG,CAI1C,CAAO,EAGDV,EAAM,eAAc,CAC1B,CAAK,CACL,CAAG,CACH,GAAG,OAAQ,SAAU,OAAO,OAAO,GC3ElC,CAACF,EAAI7G,EAAGU,IAAY,CACfA,EAAQ,WAAa,eAIzBA,EAAQ,MAAM,IAAM,CAClB,IAAIuH,EAAsB,KAE1B,SAASC,GAA2B,CAC9BD,GAAuB,MACzBvH,EAAQ,KAAK,MAAO,0BAA0B,EAAE,KAAMyH,GAAY,CAChEF,EAAsB,KAAK,MAAME,CAAO,EACxC,SAAW,CAACC,EAAaC,CAAW,IAAK,OAAO,QAAQJ,CAAmB,EAAG,CAC5E,MAAMK,EAAWtI,EAAE,iBAAiB,sBAAsBoI,CAAW,wBAAwB,EAC7F,UAAWlG,KAAWoG,EAAU,CAC9B,MAAMC,EAAS,QAAQ7H,EAAQ,SAAS,aAAa,MAAM,UAAU2H,EAAY,CAAC,CAAC,QACnFnG,EAAQ,UAAYmG,EAAY,CAAC,EAAIE,CACnD,CACA,CACA,CAAS,CAET,CAEI,UAAWhI,KAAMP,EAAE,iBAAiB,oBAAoB,EACtDU,EAAQ,GAAGH,EAAI,aAAc2H,CAAwB,EAGvD,MAAMM,EAAmBxI,EAAE,iBAAiB,qBAAqB,EAC3DyI,EAAoBzI,EAAE,iBAAiB,sBAAsB,EAC7D0I,EAAgB1I,EAAE,iBAAiB,mDAAmD,EACtF2I,EAAiBC,GAAW,CAChC,UAAWrI,KAAMmI,EAEXnI,EAAG,eAAiB,OAAMA,EAAG,QAAU,CAACqI,EAEpD,EACI,UAAWrI,KAAMiI,EACf9H,EAAQ,GAAGH,EAAI,QAAS,IAAMoI,EAAc,EAAI,CAAC,EAEnD,UAAWpI,KAAMkI,EACf/H,EAAQ,GAAGH,EAAI,QAAS,IAAMoI,EAAc,EAAK,CAAC,EAGpD,MAAME,EAAiB7I,EAAE,cAAc,YAAY,EACnDU,EAAQ,GAAGmI,EAAgB,QAAUrI,GAAM,CACzCA,EAAE,eAAc,EAChB,UAAU,UAAU,UAAUqI,EAAe,QAAQ,IAAI,EACzDA,EAAe,UAAYA,EAAe,QAAQ,UACxD,CAAK,CACL,CAAG,CACH,GAAG,OAAQ,SAAU,OAAO,OAAO,ECnDnC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQC,SAAUC,EAAQC,EAAU,CAKrB,OAAOD,EAAO,aAAgB,aAE9BA,EAAO,YAAc,SAAU/B,EAAOiC,EAAQ,CAE1CA,EAASA,GAAU,CAAE,QAAS,GAAO,WAAY,GAAO,OAAQ,MAAS,EAEzE,IAAIC,EAAMF,EAAS,YAAY,aAAa,EAC5C,OAAAE,EAAI,gBAAgBlC,EAAOiC,EAAO,QAASA,EAAO,WAAYA,EAAO,MAAM,EACpEC,CACnB,EAEQH,EAAO,YAAY,UAAYA,EAAO,MAAM,WAGhDC,EAAS,iBAAiB,aAAcG,EAAkB,EAAK,EAC/DH,EAAS,iBAAiB,YAAaI,EAAiB,EAAK,EAC7DJ,EAAS,iBAAiB,WAAYK,EAAgB,EAAK,EAE3D,IAAIC,EAAQ,KACRC,EAAQ,KACRC,EAAQ,KACRC,EAAQ,KACRC,EAAW,KACXC,EAAU,KACVC,EAAa,EAOjB,SAASP,EAAe5I,EAAG,CAGvB,GAAIkJ,IAAYlJ,EAAE,OAElB,KAAIoJ,EAAiB,SAASC,EAAoBH,EAAS,uBAAwB,IAAI,EAAG,EAAE,EACxFI,EAAYD,EAAoBH,EAAS,kBAAmB,IAAI,EAChEK,EAAe,SAASF,EAAoBH,EAAS,qBAAsB,KAAK,EAAG,EAAE,EACrFM,EAAW,KAAK,IAAG,EAAKP,EACxB7I,EAAY,GACZqJ,EAAiBzJ,EAAE,gBAAkBA,EAAE,SAAW,CAAA,EA4BtD,GA1BIsJ,IAAc,OACdF,EAAiB,KAAK,MAAOA,EAAiB,IAAOb,EAAS,gBAAgB,YAAY,GAE1Fe,IAAc,OACdF,EAAiB,KAAK,MAAOA,EAAiB,IAAOb,EAAS,gBAAgB,WAAW,GAGzF,KAAK,IAAIQ,CAAK,EAAI,KAAK,IAAIC,CAAK,EAC5B,KAAK,IAAID,CAAK,EAAIK,GAAkBI,EAAWD,IAC3CR,EAAQ,EACR3I,EAAY,cAGZA,EAAY,gBAIf,KAAK,IAAI4I,CAAK,EAAII,GAAkBI,EAAWD,IAChDP,EAAQ,EACR5I,EAAY,YAGZA,EAAY,eAIhBA,IAAc,GAAI,CAElB,IAAIsJ,EAAY,CACZ,IAAKtJ,EAAU,QAAQ,UAAW,EAAE,EACpC,WAAYqJ,EAAe,CAAC,GAAK,CAAA,GAAI,WAAa,SAClD,QAASN,EACT,OAAQ,SAASN,EAAO,EAAE,EAC1B,KAAM,UAAUY,EAAe,CAAC,GAAK,IAAI,SAAW,GAAI,EAAE,EAC1D,OAAQ,SAASX,EAAO,EAAE,EAC1B,KAAM,UAAUW,EAAe,CAAC,GAAK,IAAI,SAAW,GAAI,EAAE,CAC1E,EAGYP,EAAQ,cAAc,IAAI,YAAY,SAAU,CAAE,QAAS,GAAM,WAAY,GAAM,OAAQQ,CAAS,CAAE,CAAC,EAGvGR,EAAQ,cAAc,IAAI,YAAY9I,EAAW,CAAE,QAAS,GAAM,WAAY,GAAM,OAAQsJ,CAAS,CAAE,CAAC,CACpH,CAGQb,EAAQ,KACRC,EAAQ,KACRG,EAAW,KACnB,CAMI,SAASP,EAAiB1I,EAAG,CAGrBA,EAAE,OAAO,aAAa,mBAAmB,IAAM,SAEnDkJ,EAAUlJ,EAAE,OAEZiJ,EAAW,KAAK,IAAG,EACnBJ,EAAQ7I,EAAE,QAAQ,CAAC,EAAE,QACrB8I,EAAQ9I,EAAE,QAAQ,CAAC,EAAE,QACrB+I,EAAQ,EACRC,EAAQ,EACRG,EAAanJ,EAAE,QAAQ,OAC/B,CAOI,SAAS2I,EAAgB3I,EAAG,CAExB,GAAI,GAAC6I,GAAS,CAACC,GAEf,KAAIa,EAAM3J,EAAE,QAAQ,CAAC,EAAE,QACnB4J,EAAM5J,EAAE,QAAQ,CAAC,EAAE,QAEvB+I,EAAQF,EAAQc,EAChBX,EAAQF,EAAQc,EACxB,CASI,SAASP,EAAoBtJ,EAAI8J,EAAeC,EAAc,CAG1D,KAAO/J,GAAMA,IAAOwI,EAAS,iBAAiB,CAE1C,IAAIwB,EAAiBhK,EAAG,aAAa8J,CAAa,EAElD,GAAIE,EACA,OAAOA,EAGXhK,EAAKA,EAAG,UACpB,CAEQ,OAAO+J,CACf,CAEA,GAAE,OAAQ,QAAQ,GClKjB,CAACvK,EAAGC,EAAGU,IAAY,CACdA,EAAQ,WAAa,WAIzBA,EAAQ,MAAM,IAAM,CAClBV,EAAE,iBAAiB,WAAW,EAAE,QAASwK,GACvCA,EAAI,iBACF,QACA,IAAM,CAEJA,EAAI,IAAM,GAAG,OAAO,QAAQ,SAAS,iBAAiB,yBAChE,EACQ,CAAE,KAAM,EAAI,CACpB,CACA,EAEQxK,EAAE,cAAc,6BAA6B,IAC/CA,EAAE,cAAc,6BAA6B,EAAE,MAAM,QAAU,SAGjEU,EAAQ,GAAG,gBAAiB,QAAS,UAAY,CAC/C,MAAM+J,EAAoB,KAAK,aAAa,yBAAyB,EAC/DC,EAAuB,KAAK,aAAa,6BAA6B,EACtEC,EAAS,KAAK,aAAa,aAAa,EACxCC,EAAgB5K,EAAE,cAAc2K,CAAM,EAC5C,IAAIrE,EAAO,KAAK,UACZ,KAAK,UAAU,SAAS,WAAW,EACrCA,EAAOA,EAAK,QAAQmE,EAAmBC,CAAoB,EAE3DpE,EAAOA,EAAK,QAAQoE,EAAsBD,CAAiB,EAE7D,KAAK,UAAYnE,EACjB,KAAK,UAAU,OAAO,WAAW,EACjCsE,EAAc,UAAU,OAAO,WAAW,CAChD,CAAK,EAEDlK,EAAQ,GAAG,gBAAiB,QAAS,UAAY,CAC/C,MAAMiK,EAAS,KAAK,aAAa,aAAa,EACxCE,EAAc7K,EAAE,cAAc,GAAG2K,CAAM,WAAW,EAClDG,EAAUD,EAAY,aAAa,KAAK,GAC1CC,GAAY,MAAiCA,IAAY,KAC3DD,EAAY,aAAa,MAAOA,EAAY,aAAa,UAAU,CAAC,CAE5E,CAAK,EAEDnK,EAAQ,GAAG,YAAa,QAAS,UAAY,CAC3C,MAAMiK,EAAS,KAAK,cAAc,cAAc,KAAK,EACrD,UAAU,UAAU,UAAUA,EAAO,SAAS,EAC9C,KAAK,UAAY,KAAK,QAAQ,UACpC,CAAK,EAMD,IAAII,EAGJ,MAAMC,EAAmBhL,EAAE,cAAc,KAAK,EAC9CgL,EAAiB,UAAU,IAAI,QAAQ,EAIvC,MAAMC,EAAY,IAAI,MAEhBC,EAAY,CAACC,EAAQC,IAAc,CAEnCL,GAAc,aAAaA,CAAY,EAG3CA,EAAe,WAAW,IAAM,CAC9BE,EAAU,IAAME,CACxB,EAAS,GAAI,EAGPF,EAAU,OAAS,IAAM,CACvBG,EAAS,EACTJ,EAAiB,OAAM,CAC/B,EACMC,EAAU,QAAU,IAAM,CACxBD,EAAiB,OAAM,CAC/B,CACA,EAEItK,EAAQ,YAAe4C,GAAkB,CAavC,GAVAtD,EAAE,eAAe,SAAS,EAAE,UAAU,IAAI,mBAAmB,EAK7D,OAAO,SAAS,KAAO,gBAEvBU,EAAQ,qBAAoB,EAGxB,CAAC4C,EAAe,OAGpB,MAAMkH,EAAMlH,EAAc,cAAc,2BAA2B,EACnE,GAAI,CAACkH,EAAK,OAGV,MAAMlJ,EAAMkJ,EAAI,aAAa,UAAU,EAGvC,GAAI,CAAClJ,EAAK,OAGV,MAAM+J,EAAY/H,EAAc,cAAc,kBAAkB,EAChEkH,EAAI,IAAMa,EAAU,IAGE/H,EAAc,cAAc,SAAS,EAC7C,YAAY0H,CAAgB,EAG1CE,EAAU5J,EAAK,IAAM,CAGnBkJ,EAAI,IAAMlJ,EACVkJ,EAAI,gBAAgB,UAAU,CACtC,CAAO,CACP,EAEI9J,EAAQ,YAAc,IAAM,CAC1BV,EAAE,eAAe,SAAS,EAAE,UAAU,OAAO,mBAAmB,EAE5D,OAAO,SAAS,OAAS,iBAAiB,OAAO,QAAQ,KAAI,EACjEU,EAAQ,qBAAoB,CAClC,EACIA,EAAQ,GAAG,uBAAwB,QAAUF,GAAM,CACjDA,EAAE,eAAc,EAChBE,EAAQ,YAAW,CACzB,CAAK,EACDA,EAAQ,GAAG,0BAA2B,QAAUF,GAAM,CACpDA,EAAE,eAAc,EAChBE,EAAQ,eAAe,EAAK,CAClC,CAAK,EACDA,EAAQ,GAAG,sBAAuB,QAAUF,GAAM,CAChDA,EAAE,eAAc,EAChBE,EAAQ,WAAW,EAAK,CAC9B,CAAK,EAGD,OAAO,iBAAiB,aAAc,IAAM,CACtC,OAAO,SAAS,OAAS,iBAAiBA,EAAQ,YAAW,CACvE,CAAK,EAEDV,EAAE,iBAAiB,mBAAmB,EAAE,QAASW,GAAQ,CACvDA,EAAI,iBAAiB,cAAe,IAAM,CACxCD,EAAQ,WAAW,EAAK,CAChC,CAAO,EACDC,EAAI,iBAAiB,eAAgB,IAAM,CACzCD,EAAQ,eAAe,EAAK,CACpC,CAAO,CACP,CAAK,EAEDX,EAAE,iBACA,SACA,IAAM,CACJ,MAAMS,EAAIR,EAAE,eAAe,WAAW,EACpCsL,EAAY,SAAS,gBAAgB,WAAa,SAAS,KAAK,UAChE1G,EAAU5E,EAAE,eAAe,SAAS,EAClCQ,IAAM,OACJ8K,GAAa,IACf1G,EAAQ,UAAU,IAAI,WAAW,EAEjCA,EAAQ,UAAU,OAAO,WAAW,EAGhD,EACM,EACN,CACA,CAAG,CACH,GAAG,OAAQ,SAAU,OAAO,OAAO,GClLlC,CAACiC,EAAI7G,EAAGU,IAAY,CACnB,MAAM6K,EAAY,IAClB,IAAIC,EAEJ,MAAMC,EAAW,OAAO,WAAW,mCAAmC,EAAE,QAClEC,EAAgB,SAAS,cAAc,MAAM,EAAE,KAAO,eAE5D,SAASC,GAAgB,CACvB,GAAIH,EAAO,MAAM,OAAS,EAAG,CAC3B,MAAMI,EAAS,SAAS,eAAe,QAAQ,EAC/C,WAAWA,EAAO,OAAO,KAAKA,CAAM,EAAG,CAAC,CAC9C,CACA,CAEE,SAASC,EAAkBL,EAAQ,CACjC,MAAMM,EAAK,SAAS,eAAe,cAAc,EAC3CC,EAAoB,IAAM,CAC1BP,EAAO,MAAM,SAAW,EAC1BM,EAAG,UAAU,IAAI,OAAO,EAExBA,EAAG,UAAU,OAAO,OAAO,CAEnC,EAGIC,EAAiB,EACjBD,EAAG,iBAAiB,QAAUE,GAAO,CACnCR,EAAO,MAAQ,GACfA,EAAO,MAAK,EACZO,EAAiB,EACjBC,EAAG,eAAc,CACvB,CAAK,EACDR,EAAO,iBAAiB,QAASO,EAAmB,EAAK,CAC7D,CAEE,MAAME,EAAe,MAAOC,GAAU,CACpC,IAAIC,EACJ,GAAIzL,EAAQ,SAAS,SAAW,MAAO,CACrC,MAAM0L,EAAY,IAAI,gBACtBA,EAAU,OAAO,IAAKF,CAAK,EAC3BC,EAAU,MAAM,mBAAmBC,EAAU,SAAQ,CAAE,EAAE,CAC/D,KAAW,CACL,MAAM7J,EAAW,IAAI,SACrBA,EAAS,OAAO,IAAK2J,CAAK,EAC1BC,EAAU,MAAM,kBAAmB,CACjC,OAAQ,OACR,KAAM5J,CACd,CAAO,CACP,CAEI4J,EAAQ,KAAK,MAAO3J,GAAa,CAC/B,MAAMoC,EAAU,MAAMpC,EAAS,KAAI,EAEnC,GAAI,CAACoC,EAAS,OAEd,MAAMyH,EAAerM,EAAE,cAAc,eAAe,EAC9CsM,EAAmBtM,EAAE,cAAc,kBAAkB,EAK3D,GAJAqM,EAAa,UAAU,IAAI,MAAM,EACjCC,EAAiB,UAAY,GAGzB,CAAC1H,EAAQ,CAAC,GAAKA,EAAQ,CAAC,EAAE,SAAW,EAAG,CAC1C,MAAM2H,EAAqB,SAAS,cAAc,IAAI,EACtDA,EAAmB,UAAU,IAAI,eAAe,EAChDA,EAAmB,UAAY7L,EAAQ,SAAS,aAAa,cAC7D4L,EAAiB,YAAYC,CAAkB,EAC/C,MACR,CAEM,UAAWC,KAAU5H,EAAQ,CAAC,EAAG,CAC/B,MAAM6H,EAAK,SAAS,cAAc,IAAI,EACtCA,EAAG,UAAYD,EAEf9L,EAAQ,GAAG+L,EAAI,YAAa,IAAM,CAChCjB,EAAO,MAAQgB,EACFxM,EAAE,cAAc,SAAS,EACjC,OAAM,EACXqM,EAAa,UAAU,OAAO,MAAM,CAC9C,CAAS,EACDC,EAAiB,YAAYG,CAAE,CACvC,CACA,CAAK,CACL,EAEE/L,EAAQ,MAAM,IAAM,CAEd,CAAC+K,GAAY,CAACC,GAAe,SAAS,eAAe,GAAG,EAAE,MAAK,EAEnEF,EAASxL,EAAE,eAAeuL,CAAS,EACnC,MAAMc,EAAerM,EAAE,cAAc,eAAe,EAC9CsM,EAAmBtM,EAAE,cAAc,kBAAkB,EAEvDwL,IAAW,OAEbK,EAAkBL,CAAM,EAGpB9K,EAAQ,SAAS,eACnBA,EAAQ,GAAG8K,EAAQ,QAAS,IAAM,CAChC,MAAMU,EAAQV,EAAO,MACjBU,EAAM,OAASxL,EAAQ,SAAS,kBAEpC,WAAW,IAAM,CACXwL,IAAUV,EAAO,OAAOS,EAAaC,CAAK,CAC1D,EAAa,GAAG,CAChB,CAAS,EAEDxL,EAAQ,GAAG8K,EAAQ,QAAUhL,GAAM,CACjC,IAAIkM,EAAe,GACnB,MAAMC,EAAYL,EAAiB,SACnC,QAASlM,EAAI,EAAGA,EAAIuM,EAAU,OAAQvM,IACpC,GAAIuM,EAAUvM,CAAC,EAAE,UAAU,SAAS,QAAQ,EAAG,CAC7CsM,EAAetM,EACf,KACd,CAGU,IAAIwM,EAAkB,GAatB,GAZIpM,EAAE,MAAQ,WACRkM,GAAgB,GAAGC,EAAUD,CAAY,EAAE,UAAU,OAAO,QAAQ,EAGxEE,GAAmBF,EAAe,EAAIC,EAAU,QAAUA,EAAU,QAC3DnM,EAAE,MAAQ,aACfkM,GAAgB,GAAGC,EAAUD,CAAY,EAAE,UAAU,OAAO,QAAQ,EACxEE,GAAmBF,EAAe,GAAKC,EAAU,SACxCnM,EAAE,MAAQ,OAASA,EAAE,MAAQ,UACtC6L,EAAa,UAAU,OAAO,MAAM,EAGlCO,IAAoB,GAAI,CAC1B,MAAMC,EAAeF,EAAUC,CAAe,EAC9CC,EAAa,UAAU,IAAI,QAAQ,EAE9BA,EAAa,UAAU,SAAS,eAAe,IAAGrB,EAAO,MAAQqB,EAAa,UAC/F,CACA,CAAS,IASHrB,IAAW,MACX9K,EAAQ,SAAS,2BAGjBV,EAAE,cAAc,iBAAiB,GAAK,OAEtCU,EAAQ,GAAGV,EAAE,eAAe,YAAY,EAAG,SAAU2L,CAAa,EAClEjL,EAAQ,GAAGV,EAAE,eAAe,YAAY,EAAG,SAAU2L,CAAa,EAClEjL,EAAQ,GAAGV,EAAE,eAAe,UAAU,EAAG,SAAU2L,CAAa,GAGlE,MAAMmB,EAAkB9M,EAAE,iBAAiB,wBAAwB,EACnE,UAAWoF,KAAU0H,EACnBpM,EAAQ,GAAG0E,EAAQ,QAAU2B,GAAU,CACrC,GAAIA,EAAM,SAAU,CAClBA,EAAM,eAAc,EACpB3B,EAAO,UAAU,OAAO,UAAU,EAClC,MACV,CAGQ,MAAM2H,EAAqB/M,EAAE,iBAAiB,iCAAiC,EAC/E,UAAWgN,KAAkBD,EAC3BC,EAAe,UAAU,OAAO,UAAU,EAE5C5H,EAAO,UAAU,IAAI,UAAU,CACvC,CAAO,EAIH,MAAM9C,EAAOtC,EAAE,cAAc,SAAS,EAClCsC,GAAQ,MACV5B,EAAQ,GAAG4B,EAAM,SAAWyE,GAAU,CACpCA,EAAM,eAAc,EACpB,MAAMkG,EAAsBjN,EAAE,cAAc,sBAAsB,EAClE,GAAIiN,EAAqB,CACvB,MAAMC,EAAiB,CAAA,EACvB,UAAWF,KAAkBF,EACvBE,EAAe,UAAU,SAAS,UAAU,GAC9CE,EAAe,KAAKF,EAAe,KAAK,QAAQ,YAAa,EAAE,CAAC,EAGpEC,EAAoB,MAAQC,EAAe,KAAK,GAAG,CAC7D,CACQ5K,EAAK,OAAM,CACnB,CAAO,CAEP,CAAG,CACH,GAAG,OAAQ,SAAU,OAAO,OAAO","x_google_ignoreList":[5]}