blob: ec7f7640f1423a4556ee7f900aa063588e9225f1 [file] [log] [blame]
<!doctype html>
<html class="no-js" lang="en" data-content_root="./">
<head><meta charset="utf-8"/>
<meta name="viewport" content="width=device-width,initial-scale=1"/>
<meta name="color-scheme" content="light dark"><meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="Arrow Flight RPC" href="flight.html" /><link rel="prev" title="Reading/Writing IPC formats" href="ipc.html" />
<!-- Generated with Sphinx 8.1.3 and Furo 2024.08.06 -->
<title>Java Algorithms - arrow-java 18.1.0 documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=8f2a1f02" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?v=354aac6f" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo-extensions.css?v=302659d7" />
<style>
body {
--color-code-background: #f8f8f8;
--color-code-foreground: black;
}
@media not print {
body[data-theme="dark"] {
--color-code-background: #202020;
--color-code-foreground: #d0d0d0;
}
@media (prefers-color-scheme: dark) {
body:not([data-theme="light"]) {
--color-code-background: #202020;
--color-code-foreground: #d0d0d0;
}
}
}
</style></head>
<body>
<script>
document.body.dataset.theme = localStorage.getItem("theme") || "auto";
</script>
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="svg-toc" viewBox="0 0 24 24">
<title>Contents</title>
<svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 1024 1024">
<path d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM115.4 518.9L271.7 642c5.8 4.6 14.4.5 14.4-6.9V388.9c0-7.4-8.5-11.5-14.4-6.9L115.4 505.1a8.74 8.74 0 0 0 0 13.8z"/>
</svg>
</symbol>
<symbol id="svg-menu" viewBox="0 0 24 24">
<title>Menu</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather-menu">
<line x1="3" y1="12" x2="21" y2="12"></line>
<line x1="3" y1="6" x2="21" y2="6"></line>
<line x1="3" y1="18" x2="21" y2="18"></line>
</svg>
</symbol>
<symbol id="svg-arrow-right" viewBox="0 0 24 24">
<title>Expand</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather-chevron-right">
<polyline points="9 18 15 12 9 6"></polyline>
</svg>
</symbol>
<symbol id="svg-sun" viewBox="0 0 24 24">
<title>Light mode</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="1" stroke-linecap="round" stroke-linejoin="round" class="feather-sun">
<circle cx="12" cy="12" r="5"></circle>
<line x1="12" y1="1" x2="12" y2="3"></line>
<line x1="12" y1="21" x2="12" y2="23"></line>
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
<line x1="1" y1="12" x2="3" y2="12"></line>
<line x1="21" y1="12" x2="23" y2="12"></line>
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
</svg>
</symbol>
<symbol id="svg-moon" viewBox="0 0 24 24">
<title>Dark mode</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="1" stroke-linecap="round" stroke-linejoin="round" class="icon-tabler-moon">
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1 -8.313 -12.454z" />
</svg>
</symbol>
<symbol id="svg-sun-with-moon" viewBox="0 0 24 24">
<title>Auto light/dark, in light mode</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="1" stroke-linecap="round" stroke-linejoin="round"
class="icon-custom-derived-from-feather-sun-and-tabler-moon">
<path style="opacity: 50%" d="M 5.411 14.504 C 5.471 14.504 5.532 14.504 5.591 14.504 C 3.639 16.319 4.383 19.569 6.931 20.352 C 7.693 20.586 8.512 20.551 9.25 20.252 C 8.023 23.207 4.056 23.725 2.11 21.184 C 0.166 18.642 1.702 14.949 4.874 14.536 C 5.051 14.512 5.231 14.5 5.411 14.5 L 5.411 14.504 Z"/>
<line x1="14.5" y1="3.25" x2="14.5" y2="1.25"/>
<line x1="14.5" y1="15.85" x2="14.5" y2="17.85"/>
<line x1="10.044" y1="5.094" x2="8.63" y2="3.68"/>
<line x1="19" y1="14.05" x2="20.414" y2="15.464"/>
<line x1="8.2" y1="9.55" x2="6.2" y2="9.55"/>
<line x1="20.8" y1="9.55" x2="22.8" y2="9.55"/>
<line x1="10.044" y1="14.006" x2="8.63" y2="15.42"/>
<line x1="19" y1="5.05" x2="20.414" y2="3.636"/>
<circle cx="14.5" cy="9.55" r="3.6"/>
</svg>
</symbol>
<symbol id="svg-moon-with-sun" viewBox="0 0 24 24">
<title>Auto light/dark, in dark mode</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="1" stroke-linecap="round" stroke-linejoin="round"
class="icon-custom-derived-from-feather-sun-and-tabler-moon">
<path d="M 8.282 7.007 C 8.385 7.007 8.494 7.007 8.595 7.007 C 5.18 10.184 6.481 15.869 10.942 17.24 C 12.275 17.648 13.706 17.589 15 17.066 C 12.851 22.236 5.91 23.143 2.505 18.696 C -0.897 14.249 1.791 7.786 7.342 7.063 C 7.652 7.021 7.965 7 8.282 7 L 8.282 7.007 Z"/>
<line style="opacity: 50%" x1="18" y1="3.705" x2="18" y2="2.5"/>
<line style="opacity: 50%" x1="18" y1="11.295" x2="18" y2="12.5"/>
<line style="opacity: 50%" x1="15.316" y1="4.816" x2="14.464" y2="3.964"/>
<line style="opacity: 50%" x1="20.711" y1="10.212" x2="21.563" y2="11.063"/>
<line style="opacity: 50%" x1="14.205" y1="7.5" x2="13.001" y2="7.5"/>
<line style="opacity: 50%" x1="21.795" y1="7.5" x2="23" y2="7.5"/>
<line style="opacity: 50%" x1="15.316" y1="10.184" x2="14.464" y2="11.036"/>
<line style="opacity: 50%" x1="20.711" y1="4.789" x2="21.563" y2="3.937"/>
<circle style="opacity: 50%" cx="18" cy="7.5" r="2.169"/>
</svg>
</symbol>
<symbol id="svg-pencil" viewBox="0 0 24 24">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="1" stroke-linecap="round" stroke-linejoin="round" class="icon-tabler-pencil-code">
<path d="M4 20h4l10.5 -10.5a2.828 2.828 0 1 0 -4 -4l-10.5 10.5v4" />
<path d="M13.5 6.5l4 4" />
<path d="M20 21l2 -2l-2 -2" />
<path d="M17 17l-2 2l2 2" />
</svg>
</symbol>
<symbol id="svg-eye" viewBox="0 0 24 24">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="1" stroke-linecap="round" stroke-linejoin="round" class="icon-tabler-eye-code">
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M10 12a2 2 0 1 0 4 0a2 2 0 0 0 -4 0" />
<path
d="M11.11 17.958c-3.209 -.307 -5.91 -2.293 -8.11 -5.958c2.4 -4 5.4 -6 9 -6c3.6 0 6.6 2 9 6c-.21 .352 -.427 .688 -.647 1.008" />
<path d="M20 21l2 -2l-2 -2" />
<path d="M17 17l-2 2l2 2" />
</svg>
</symbol>
</svg>
<input type="checkbox" class="sidebar-toggle" name="__navigation" id="__navigation">
<input type="checkbox" class="sidebar-toggle" name="__toc" id="__toc">
<label class="overlay sidebar-overlay" for="__navigation">
<div class="visually-hidden">Hide navigation sidebar</div>
</label>
<label class="overlay toc-overlay" for="__toc">
<div class="visually-hidden">Hide table of contents sidebar</div>
</label>
<a class="skip-to-content muted-link" href="#furo-main-content">Skip to content</a>
<div class="page">
<header class="mobile-header">
<div class="header-left">
<label class="nav-overlay-icon" for="__navigation">
<div class="visually-hidden">Toggle site navigation sidebar</div>
<i class="icon"><svg><use href="#svg-menu"></use></svg></i>
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">arrow-java 18.1.0 documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
<button class="theme-toggle">
<div class="visually-hidden">Toggle Light / Dark / Auto color theme</div>
<svg class="theme-icon-when-auto-light"><use href="#svg-sun-with-moon"></use></svg>
<svg class="theme-icon-when-auto-dark"><use href="#svg-moon-with-sun"></use></svg>
<svg class="theme-icon-when-dark"><use href="#svg-moon"></use></svg>
<svg class="theme-icon-when-light"><use href="#svg-sun"></use></svg>
</button>
</div>
<label class="toc-overlay-icon toc-header-icon" for="__toc">
<div class="visually-hidden">Toggle table of contents sidebar</div>
<i class="icon"><svg><use href="#svg-toc"></use></svg></i>
</label>
</div>
</header>
<aside class="sidebar-drawer">
<div class="sidebar-container">
<div class="sidebar-sticky"><a class="sidebar-brand" href="index.html">
<span class="sidebar-brand-text">arrow-java 18.1.0 documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder="Search" name="q" aria-label="Search">
<input type="hidden" name="check_keywords" value="yes">
<input type="hidden" name="area" value="default">
</form>
<div id="searchbox"></div><div class="sidebar-scroll"><div class="sidebar-tree">
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="quickstartguide.html">Quick Start Guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="overview.html">High-Level Overview</a></li>
<li class="toctree-l1"><a class="reference internal" href="install.html">Installing Java Modules</a></li>
<li class="toctree-l1 has-children"><a class="reference internal" href="developers/index.html">Java Development</a><input class="toctree-checkbox" id="toctree-checkbox-1" name="toctree-checkbox-1" role="switch" type="checkbox"/><label for="toctree-checkbox-1"><div class="visually-hidden">Toggle navigation of Java Development</div><i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i></label><ul>
<li class="toctree-l2"><a class="reference internal" href="developers/building.html">Building Arrow Java</a></li>
<li class="toctree-l2"><a class="reference internal" href="developers/development.html">Development Guidelines</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="memory.html">Memory Management</a></li>
<li class="toctree-l1"><a class="reference internal" href="vector.html">ValueVector</a></li>
<li class="toctree-l1"><a class="reference internal" href="vector_schema_root.html">Tabular Data</a></li>
<li class="toctree-l1"><a class="reference internal" href="table.html">Table</a></li>
<li class="toctree-l1"><a class="reference internal" href="ipc.html">Reading/Writing IPC formats</a></li>
<li class="toctree-l1 current current-page"><a class="current reference internal" href="#">Java Algorithms</a></li>
<li class="toctree-l1"><a class="reference internal" href="flight.html">Arrow Flight RPC</a></li>
<li class="toctree-l1"><a class="reference internal" href="flight_sql.html">Arrow Flight SQL</a></li>
<li class="toctree-l1"><a class="reference internal" href="flight_sql_jdbc_driver.html">Arrow Flight SQL JDBC Driver</a></li>
<li class="toctree-l1"><a class="reference internal" href="dataset.html">Dataset</a></li>
<li class="toctree-l1"><a class="reference internal" href="substrait.html">Substrait</a></li>
<li class="toctree-l1"><a class="reference internal" href="cdata.html">C Data Interface</a></li>
<li class="toctree-l1"><a class="reference internal" href="jdbc.html">Arrow JDBC Adapter</a></li>
<li class="toctree-l1"><a class="reference internal" href="reference/index.html">Reference (javadoc)</a></li>
<li class="toctree-l1"><a class="reference external" href="https://arrow.apache.org/cookbook/java/">Cookbook</a></li>
</ul>
</div>
</div>
</div>
</div>
</aside>
<div class="main">
<div class="content">
<div class="article-container">
<a href="#" class="back-to-top muted-link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8v12z"></path>
</svg>
<span>Back to top</span>
</a>
<div class="content-icon-container">
<div class="view-this-page">
<a class="muted-link" href="_sources/algorithm.rst.txt" title="View this page">
<svg><use href="#svg-eye"></use></svg>
<span class="visually-hidden">View this page</span>
</a>
</div>
<div class="theme-toggle-container theme-toggle-content">
<button class="theme-toggle">
<div class="visually-hidden">Toggle Light / Dark / Auto color theme</div>
<svg class="theme-icon-when-auto-light"><use href="#svg-sun-with-moon"></use></svg>
<svg class="theme-icon-when-auto-dark"><use href="#svg-moon-with-sun"></use></svg>
<svg class="theme-icon-when-dark"><use href="#svg-moon"></use></svg>
<svg class="theme-icon-when-light"><use href="#svg-sun"></use></svg>
</button>
</div>
<label class="toc-overlay-icon toc-content-icon" for="__toc">
<div class="visually-hidden">Toggle table of contents sidebar</div>
<i class="icon"><svg><use href="#svg-toc"></use></svg></i>
</label>
</div>
<article role="main" id="furo-main-content">
<section id="java-algorithms">
<h1>Java Algorithms<a class="headerlink" href="#java-algorithms" title="Link to this heading"></a></h1>
<p>Arrow’s Java library provides algorithms for some commonly-used
functionalities. The algorithms are provided in the <code class="docutils literal notranslate"><span class="pre">org.apache.arrow.algorithm</span></code>
package of the <code class="docutils literal notranslate"><span class="pre">algorithm</span></code> module.</p>
<section id="comparing-vector-elements">
<h2>Comparing Vector Elements<a class="headerlink" href="#comparing-vector-elements" title="Link to this heading"></a></h2>
<p>Comparing vector elements is the basic for many algorithms. Vector
elements can be compared in one of the two ways:</p>
<p>1. <strong>Equality comparison</strong>: there are two possible results for this type of comparisons: <code class="docutils literal notranslate"><span class="pre">equal</span></code> and <code class="docutils literal notranslate"><span class="pre">unequal</span></code>.
Currently, this type of comparison is supported through the <code class="docutils literal notranslate"><span class="pre">org.apache.arrow.vector.compare.VectorValueEqualizer</span></code>
interface.</p>
<p>2. <strong>Ordering comparison</strong>: there are three possible results for this type of comparisons: <code class="docutils literal notranslate"><span class="pre">less</span> <span class="pre">than</span></code>, <code class="docutils literal notranslate"><span class="pre">equal</span> <span class="pre">to</span></code>
and <code class="docutils literal notranslate"><span class="pre">greater</span> <span class="pre">than</span></code>. This comparison is supported by the abstract class <code class="docutils literal notranslate"><span class="pre">org.apache.arrow.algorithm.sort.VectorValueComparator</span></code>.</p>
<p>We provide default implementations to compare vector elements. However, users can also define ways
for customized comparisons.</p>
</section>
<section id="vector-element-search">
<h2>Vector Element Search<a class="headerlink" href="#vector-element-search" title="Link to this heading"></a></h2>
<p>A search algorithm tries to find a particular value in a vector. When successful, a vector index is
returned; otherwise, a <code class="docutils literal notranslate"><span class="pre">-1</span></code> is returned. The following search algorithms are provided:</p>
<p>1. <strong>Linear search</strong>: this algorithm simply traverses the vector from the beginning, until a match is
found, or the end of the vector is reached. So it takes <code class="docutils literal notranslate"><span class="pre">O(n)</span></code> time, where <code class="docutils literal notranslate"><span class="pre">n</span></code> is the number of elements
in the vector. This algorithm is implemented in <code class="docutils literal notranslate"><span class="pre">org.apache.arrow.algorithm.search.VectorSearcher#linearSearch</span></code>.</p>
<p>2. <strong>Binary search</strong>: this represents a more efficient search algorithm, as it runs in <code class="docutils literal notranslate"><span class="pre">O(log(n))</span></code> time.
However, it is only applicable to sorted vectors. To get a sorted vector,
one can use one of our sorting algorithms, which will be discussed in the next section. This algorithm
is implemented in <code class="docutils literal notranslate"><span class="pre">org.apache.arrow.algorithm.search.VectorSearcher#binarySearch</span></code>.</p>
<p>3. <strong>Parallel search</strong>: when the vector is large, it takes a long time to traverse the elements to search
for a value. To make this process faster, one can split the vector into multiple partitions, and perform the
search for each partition in parallel. This is supported by <code class="docutils literal notranslate"><span class="pre">org.apache.arrow.algorithm.search.ParallelSearcher</span></code>.</p>
<p>4. <strong>Range search</strong>: for many scenarios, there can be multiple matching values in the vector.
If the vector is sorted, the matching values reside in a contiguous region in the vector. The
range search algorithm tries to find the upper/lower bound of the region in <code class="docutils literal notranslate"><span class="pre">O(log(n))</span></code> time.
An implementation is provided in <code class="docutils literal notranslate"><span class="pre">org.apache.arrow.algorithm.search.VectorRangeSearcher</span></code>.</p>
</section>
<section id="vector-sorting">
<h2>Vector Sorting<a class="headerlink" href="#vector-sorting" title="Link to this heading"></a></h2>
<p>Given a vector, a sorting algorithm turns it into a sorted one. The sorting criteria must
be specified by some ordering comparison operation. The sorting algorithms can be
classified into the following categories:</p>
<p>1. <strong>In-place sorter</strong>: an in-place sorter performs the sorting by manipulating the original
vector, without creating any new vector. So it just returns the original vector after the sorting operations.
Currently, we have <code class="docutils literal notranslate"><span class="pre">org.apache.arrow.algorithm.sort.FixedWidthInPlaceVectorSorter</span></code> for in-place
sorting in <code class="docutils literal notranslate"><span class="pre">O(nlog(n))</span></code> time. As the name suggests, it only supports fixed width vectors.</p>
<p>2. <strong>Out-of-place sorter</strong>: an out-of-place sorter does not mutate the original vector. Instead,
it copies vector elements to a new vector in sorted order, and returns the new vector.
We have <code class="docutils literal notranslate"><span class="pre">org.apache.arrow.algorithm.sort.FixedWidthInPlaceVectorSorter.FixedWidthOutOfPlaceVectorSorter</span></code>
and <code class="docutils literal notranslate"><span class="pre">org.apache.arrow.algorithm.sort.FixedWidthInPlaceVectorSorter.VariableWidthOutOfPlaceVectorSorter</span></code>
for fixed width and variable width vectors, respectively. Both algorithms run in <code class="docutils literal notranslate"><span class="pre">O(nlog(n))</span></code> time.</p>
<p>3. <strong>Index sorter</strong>: this sorter does not actually sort the vector. Instead, it returns an integer
vector, which correspond to indices of vector elements in sorted order. With the index vector, one can
easily construct a sorted vector. In addition, some other tasks can be easily achieved, like finding the <code class="docutils literal notranslate"><span class="pre">k</span></code> th
smallest value in the vector. Index sorting is supported by <code class="docutils literal notranslate"><span class="pre">org.apache.arrow.algorithm.sort.IndexSorter</span></code>,
which runs in <code class="docutils literal notranslate"><span class="pre">O(nlog(n))</span></code> time. It is applicable to vectors of any type.</p>
</section>
<section id="other-algorithms">
<h2>Other Algorithms<a class="headerlink" href="#other-algorithms" title="Link to this heading"></a></h2>
<p>Other algorithms include vector deduplication, dictionary encoding, etc., in the <code class="docutils literal notranslate"><span class="pre">algorithm</span></code> module.</p>
</section>
</section>
</article>
</div>
<footer>
<div class="related-pages">
<a class="next-page" href="flight.html">
<div class="page-info">
<div class="context">
<span>Next</span>
</div>
<div class="title">Arrow Flight RPC</div>
</div>
<svg class="furo-related-icon"><use href="#svg-arrow-right"></use></svg>
</a>
<a class="prev-page" href="ipc.html">
<svg class="furo-related-icon"><use href="#svg-arrow-right"></use></svg>
<div class="page-info">
<div class="context">
<span>Previous</span>
</div>
<div class="title">Reading/Writing IPC formats</div>
</div>
</a>
</div>
<div class="bottom-of-page">
<div class="left-details">
<div class="copyright">
Copyright &#169; 2025, Apache Arrow Developers
</div>
Made with <a href="https://www.sphinx-doc.org/">Sphinx</a> and <a class="muted-link" href="https://pradyunsg.me">@pradyunsg</a>'s
<a href="https://github.com/pradyunsg/furo">Furo</a>
</div>
<div class="right-details">
</div>
</div>
</footer>
</div>
<aside class="toc-drawer">
<div class="toc-sticky toc-scroll">
<div class="toc-title-container">
<span class="toc-title">
On this page
</span>
</div>
<div class="toc-tree-container">
<div class="toc-tree">
<ul>
<li><a class="reference internal" href="#">Java Algorithms</a><ul>
<li><a class="reference internal" href="#comparing-vector-elements">Comparing Vector Elements</a></li>
<li><a class="reference internal" href="#vector-element-search">Vector Element Search</a></li>
<li><a class="reference internal" href="#vector-sorting">Vector Sorting</a></li>
<li><a class="reference internal" href="#other-algorithms">Other Algorithms</a></li>
</ul>
</li>
</ul>
</div>
</div>
</div>
</aside>
</div>
</div><script src="_static/documentation_options.js?v=c4c92189"></script>
<script src="_static/doctools.js?v=9bcbadda"></script>
<script src="_static/sphinx_highlight.js?v=dc90522c"></script>
<script src="_static/scripts/furo.js?v=5fa4622c"></script>
</body>
</html>