diff --git a/public/.buildinfo b/public/.buildinfo
index a2c9a413b6ce7b07490e5151f9e3d29246b0e4a5..8ad5672749daad6fe54c5ad9791f1ad735ec2171 100644
--- a/public/.buildinfo
+++ b/public/.buildinfo
@@ -1,4 +1,4 @@
 # Sphinx build info version 1
 # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
-config: c73cd0e1ac8a8c304acd5706bcab5918
+config: a121d25e499fa04be7ffb415e1360810
 tags: 645f666f9bcd5a90fca523b33c5a78b7
diff --git a/public/Ohmpi.html b/public/Ohmpi.html
index 4efb23ca3d4bc504cd65d567a6565eb8cc5e17b1..348923bdba86240f2535dfcbd8f5a6c13d9bee50 100644
--- a/public/Ohmpi.html
+++ b/public/Ohmpi.html
@@ -4,7 +4,8 @@
 <html class="writer-html5" lang="en" >
 <head>
   <meta charset="utf-8">
-  
+  <meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
+
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   
   <title>OhmPi project &mdash; Ohmpi: open hardware resistivity-meter documentation</title>
@@ -13,6 +14,8 @@
   
   <link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
   <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+  <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+  <link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
 
   
   
@@ -26,11 +29,10 @@
   
     
       <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
+        <script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
         <script src="_static/jquery.js"></script>
         <script src="_static/underscore.js"></script>
         <script src="_static/doctools.js"></script>
-        <script src="_static/language_data.js"></script>
-        <script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
     
     <script type="text/javascript" src="_static/js/theme.js"></script>
 
@@ -94,6 +96,7 @@
 </li>
 <li class="toctree-l1"><a class="reference internal" href="V1_01.html">OhmPi V 1.01 (limited to 32 electrodes)</a></li>
 <li class="toctree-l1"><a class="reference internal" href="V1_02.html">OhmPi V 1.02 (limited to 32 electrodes)</a></li>
+<li class="toctree-l1"><a class="reference internal" href="V2_00.html">OhmPi V 2.00 (64 or 128 électrodes)</a></li>
 </ul>
 
             
@@ -159,9 +162,9 @@
           <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
            <div itemprop="articleBody">
             
-  <div class="section" id="ohmpi-project">
+  <section id="ohmpi-project">
 <h1>OhmPi project<a class="headerlink" href="#ohmpi-project" title="Permalink to this headline">¶</a></h1>
-<div class="section" id="partenaires">
+<section id="partenaires">
 <h2><strong>Partenaires</strong><a class="headerlink" href="#partenaires" title="Permalink to this headline">¶</a></h2>
 <a class="reference internal image-reference" href="_images/logo_ohmpi.JPG"><img alt="Logo OhmPi" class="align-center" src="_images/logo_ohmpi.JPG" style="width: 350px; height: 250px;" /></a>
 <p>Authors:</p>
@@ -194,13 +197,13 @@
 <p>Creation date : Juillet 2020.</p>
 <p>Update : 21 août 2020.</p>
 <p>Status of document: In progress.</p>
-<div class="section" id="citing-ohmpi">
+<section id="citing-ohmpi">
 <h3><strong>Citing OhmPi</strong><a class="headerlink" href="#citing-ohmpi" title="Permalink to this headline">¶</a></h3>
 <p><em>Rémi Clement, Yannick Fargier, Vivien Dubois, Julien Gance, Emile Gros, et al.. OhmPi: An open</em>
 <em>source data logger for dedicated applications of electrical resistivity imaging at the small and laboratory</em>
 <em>scale. HardwareX, Elsevier, 2020, 8, 24 p. ff10.1016/j.ohx.2020.e00122ff.</em></p>
-</div>
-<div class="section" id="introduction-to-ohmpi">
+</section>
+<section id="introduction-to-ohmpi">
 <h3><strong>Introduction to OhmPi</strong><a class="headerlink" href="#introduction-to-ohmpi" title="Permalink to this headline">¶</a></h3>
 <p>This documentation presents the development of a low-cost, open hardware resistivity meter to provide the scientific community with a robust and flexible tool for small-scale experiments. Called OhmPi, this basic resistivity meterfeatures current injection and measurement functions associated with a multiplexer that allows performing automatic measurements with up to 32 electrodes.OhmPi’s philosophy is to provide a fully open source and open hardware tool /
 to the near surface scientific community.</p>
@@ -208,9 +211,9 @@ to the near surface scientific community.</p>
 <p class="admonition-title">Note</p>
 <p>Everyone willing to get involved is  welcome in OhmPi Project!.</p>
 </div>
-</div>
-</div>
-</div>
+</section>
+</section>
+</section>
 
 
            </div>
diff --git a/public/V1_01.html b/public/V1_01.html
index d7df85db1ca68819766e510a7cf83526c9950235..4953570bfad29de2931abd55123d779a27c54be6 100644
--- a/public/V1_01.html
+++ b/public/V1_01.html
@@ -4,7 +4,8 @@
 <html class="writer-html5" lang="en" >
 <head>
   <meta charset="utf-8">
-  
+  <meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
+
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   
   <title>OhmPi V 1.01 (limited to 32 electrodes) &mdash; Ohmpi: open hardware resistivity-meter documentation</title>
@@ -13,6 +14,8 @@
   
   <link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
   <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+  <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+  <link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
 
   
   
@@ -26,11 +29,11 @@
   
     
       <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
+        <script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
         <script src="_static/jquery.js"></script>
         <script src="_static/underscore.js"></script>
         <script src="_static/doctools.js"></script>
-        <script src="_static/language_data.js"></script>
-        <script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
+        <script async="async" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
     
     <script type="text/javascript" src="_static/js/theme.js"></script>
 
@@ -116,6 +119,7 @@
 </ul>
 </li>
 <li class="toctree-l1"><a class="reference internal" href="V1_02.html">OhmPi V 1.02 (limited to 32 electrodes)</a></li>
+<li class="toctree-l1"><a class="reference internal" href="V2_00.html">OhmPi V 2.00 (64 or 128 électrodes)</a></li>
 </ul>
 
             
@@ -181,21 +185,21 @@
           <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
            <div itemprop="articleBody">
             
-  <div class="section" id="ohmpi-v-1-01-limited-to-32-electrodes">
+  <section id="ohmpi-v-1-01-limited-to-32-electrodes">
 <h1>OhmPi V 1.01 (limited to 32 electrodes)<a class="headerlink" href="#ohmpi-v-1-01-limited-to-32-electrodes" title="Permalink to this headline">¶</a></h1>
 <div class="admonition warning">
 <p class="admonition-title">Warning</p>
 <p>This version corresponds to the version published in the Hardware X journal.
 However, we have corrected the bugs that existed on this version and explained the missing mounting points in detail below.
-We invite you to refer to this document to assemble Ohmpi.</p>
+We invite you to refer to this document to assemble Ohmpi V1.01.</p>
 </div>
-<div class="section" id="the-philosophy-of-ohmpi">
+<section id="the-philosophy-of-ohmpi">
 <h2>The philosophy of Ohmpi<a class="headerlink" href="#the-philosophy-of-ohmpi" title="Permalink to this headline">¶</a></h2>
 <p>The philosophy of Ohmpi V1.01 is to offer a multi electrode resistivity meter, from a set of commercially available
 electronic cards it is a resistivity meter limited to 32 electrodes only. It is limited to low-current injection,
 but suitable for small laboratory experiments and small field time monitoring</p>
-</div>
-<div class="section" id="technical-data">
+</section>
+<section id="technical-data">
 <h2>Technical data<a class="headerlink" href="#technical-data" title="Permalink to this headline">¶</a></h2>
 <table class="docutils align-default">
 <colgroup>
@@ -251,10 +255,10 @@ control system</p></td>
 </tr>
 </tbody>
 </table>
-</div>
-<div class="section" id="raspberry-pi-configuration">
+</section>
+<section id="raspberry-pi-configuration">
 <h2>Raspberry Pi  configuration<a class="headerlink" href="#raspberry-pi-configuration" title="Permalink to this headline">¶</a></h2>
-<div class="section" id="os-installation">
+<section id="os-installation">
 <h3>OS installation<a class="headerlink" href="#os-installation" title="Permalink to this headline">¶</a></h3>
 <p>The first step is to start up the Raspberry Pi board, including installation of an OS (operating system).
 For this step, the installation instructions are well described on the Raspberry website</p>
@@ -265,9 +269,9 @@ For this step, the installation instructions are well described on the Raspberry
 <div class="admonition note">
 <p class="admonition-title">Note</p>
 <p>All the development tests were performed on Raspberry Pi 3 Model B, we used the following version of Raspbian:</p>
-<div class="align-center figure">
+<figure class="align-center">
 <a class="reference internal image-reference" href="_images/raspbian_version.jpg"><img alt="alternate text" src="_images/raspbian_version.jpg" style="width: 800px; height: 400px;" /></a>
-</div>
+</figure>
 </div>
 <div class="admonition warning">
 <p class="admonition-title">Warning</p>
@@ -303,8 +307,8 @@ To ensure that the GPIOs are in Low position, you will need to modify the /boot/
 <li><p>Press Ctrl +x to escap and return to the terminal</p></li>
 <li><p>Close the terminal</p></li>
 </ol>
-</div>
-<div class="section" id="virtual-environnement-and-packages">
+</section>
+<section id="virtual-environnement-and-packages">
 <h3>Virtual Environnement and packages<a class="headerlink" href="#virtual-environnement-and-packages" title="Permalink to this headline">¶</a></h3>
 <p>All dependencies are specified in requirements.txt</p>
 <div class="admonition note">
@@ -337,38 +341,38 @@ to leave the virtual environment simply type:</p>
 <div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">deactivate</span>
 </pre></div>
 </div>
-</div>
-<div class="section" id="activate-virtual-environnement-on-thonny-python-ide-on-rapberry-pi">
+</section>
+<section id="activate-virtual-environnement-on-thonny-python-ide-on-rapberry-pi">
 <h3>Activate virtual environnement on Thonny (Python IDE)  (on Rapberry Pi)<a class="headerlink" href="#activate-virtual-environnement-on-thonny-python-ide-on-rapberry-pi" title="Permalink to this headline">¶</a></h3>
 <p>If you decided to use a virtual environment, it is necessary to setup Thonny Python IDE the first time you use it.</p>
 <p>1- Run the Thonny Python IDE software, Click on raspebrry acces <strong>menu &gt; programming&gt; Thonny pythonIDE</strong></p>
 <p>2- Thonny’s interface opens, Python runs on the Root (Python 3.7.3 (/usr/bin/python3))</p>
-<div class="align-center figure">
+<figure class="align-center">
 <a class="reference internal image-reference" href="_images/thonny_first_interface.jpg"><img alt="alternate text" src="_images/thonny_first_interface.jpg" style="width: 600px; height: 450px;" /></a>
-</div>
+</figure>
 <p>3-Click on <strong>Run&gt;select interpreter</strong>, a new window opens click on interpret</p>
-<div class="align-center figure">
+<figure class="align-center">
 <a class="reference internal image-reference" href="_images/thonny_option.jpg"><img alt="alternate text" src="_images/thonny_option.jpg" style="width: 600px; height: 450px;" /></a>
-</div>
+</figure>
 <p>4-On the new open windows select <strong>alternative Pyhton3 or virtual environnement</strong></p>
-<div class="align-center figure">
+<figure class="align-center">
 <a class="reference internal image-reference" href="_images/thonny_interpreter.jpg"><img alt="alternate text" src="_images/thonny_interpreter.jpg" style="width: 600px; height: 450px;" /></a>
-</div>
+</figure>
 <p>5- New buttons appeared, selected <strong>“locate another python executable “</strong></p>
 <p>6- A new window opens, find the folder where there is the python 3 file in the virtual environment folder previously created <strong>/home/pi/ohmpi/bin/python3</strong>.</p>
 <p>7- In the <strong>known interpreter</strong> tab the path of the virtual environnementshould appear</p>
-<div class="align-center figure">
+<figure class="align-center">
 <a class="reference internal image-reference" href="_images/thonny_interpreter_folder.jpg"><img alt="alternate text" src="_images/thonny_interpreter_folder.jpg" style="width: 600px; height: 450px;" /></a>
-</div>
+</figure>
 <p>8- Close the window by clicking on <strong>ok</strong>.</p>
 <p>9- Close thonny to save modifications</p>
-</div>
-</div>
-<div class="section" id="assembly-of-the-measuring-current-injection-cards-and-connection-with-the-raspberry-pi">
+</section>
+</section>
+<section id="assembly-of-the-measuring-current-injection-cards-and-connection-with-the-raspberry-pi">
 <h2>Assembly of the measuring/current injection cards, and connection with the Raspberry Pi<a class="headerlink" href="#assembly-of-the-measuring-current-injection-cards-and-connection-with-the-raspberry-pi" title="Permalink to this headline">¶</a></h2>
-<div class="section" id="electrical-resistivity-measurements-board">
+<section id="electrical-resistivity-measurements-board">
 <h3>Electrical resistivity measurements board<a class="headerlink" href="#electrical-resistivity-measurements-board" title="Permalink to this headline">¶</a></h3>
-<div class="section" id="a-description">
+<section id="a-description">
 <h4>a) Description<a class="headerlink" href="#a-description" title="Permalink to this headline">¶</a></h4>
 <p>To measure electrical resistivity with Raspberry Pi, an ADS1115 was introduced, as proposed by Florsch [7]. The ADS1115
 is a 16-bit ADC (Analog-to-Digital Converter), with an adaptable gain. Its value has been set at 2/3 in this study. The
@@ -401,12 +405,14 @@ electric field in the ground, with the total input impedance value being estimat
 A shortcut between Electrodes A and B will generate excessive currents, whose intensities depend on the type of battery used.
 A lithium ion battery or automobile-type lead-acid battery can deliver a strong enough current to damage the board and, as such,
 constitutes a potential hazard. We therefore recommend adding a 1.5-A fuse between the battery and resistor R9.</p>
-<div class="align-center figure" id="id1">
+<figure class="align-center" id="id1">
 <a class="reference internal image-reference" href="_images/schema_measurement_board.jpg"><img alt="alternate text" src="_images/schema_measurement_board.jpg" style="width: 800px; height: 400px;" /></a>
-<p class="caption"><span class="caption-text">Measurement board</span><a class="headerlink" href="#id1" title="Permalink to this image">¶</a></p>
-</div>
-</div>
-<div class="section" id="b-implementation">
+<figcaption>
+<p><span class="caption-text">Measurement board</span><a class="headerlink" href="#id1" title="Permalink to this image">¶</a></p>
+</figcaption>
+</figure>
+</section>
+<section id="b-implementation">
 <h4>b) Implementation<a class="headerlink" href="#b-implementation" title="Permalink to this headline">¶</a></h4>
 <p>The measurement board must be printed using the PCB file (Source file repository), with components soldered onto
 it by following the steps described below and illustrated in the following figure :</p>
@@ -422,23 +428,16 @@ it by following the steps described below and illustrated in the following figur
 \[coeff p2 = (R7 + R6) / R7\]</div>
 <div class="math notranslate nohighlight">
 \[coeff p3 = (R9 + R8) / R9\]</div>
-<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>36
-37
-38
-39
-40
-41
-42
-43</pre></div></td><td class="code"><div class="highlight"><pre><span></span> <span class="sd">&quot;&quot;&quot;</span>
-<span class="sd"> hardware parameters</span>
-<span class="sd"> &quot;&quot;&quot;</span>
- <span class="n">R_ref</span> <span class="o">=</span> <span class="mi">50</span> <span class="c1"># reference resistance value in ohm</span>
- <span class="n">coef_p0</span> <span class="o">=</span> <span class="mf">2.5</span> <span class="c1"># slope for current conversion for ADS.P0, measurement in V/V</span>
- <span class="n">coef_p1</span> <span class="o">=</span> <span class="mf">2.5</span> <span class="c1"># slope for current conversion for ADS.P1, measurement in V/V</span>
- <span class="n">coef_p2</span> <span class="o">=</span> <span class="mf">2.5</span> <span class="c1"># slope for current conversion for ADS.P2, measurement in V/V</span>
- <span class="n">coef_p3</span> <span class="o">=</span> <span class="mf">2.5</span> <span class="c1"># slope for current conversion for ADS.P3, measurement in V/V</span>
+<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="linenos">36</span> <span class="sd">&quot;&quot;&quot;</span>
+<span class="linenos">37</span><span class="sd"> hardware parameters</span>
+<span class="linenos">38</span><span class="sd"> &quot;&quot;&quot;</span>
+<span class="linenos">39</span> <span class="n">R_ref</span> <span class="o">=</span> <span class="mi">50</span> <span class="c1"># reference resistance value in ohm</span>
+<span class="linenos">40</span> <span class="n">coef_p0</span> <span class="o">=</span> <span class="mf">2.5</span> <span class="c1"># slope for current conversion for ADS.P0, measurement in V/V</span>
+<span class="linenos">41</span> <span class="n">coef_p1</span> <span class="o">=</span> <span class="mf">2.5</span> <span class="c1"># slope for current conversion for ADS.P1, measurement in V/V</span>
+<span class="linenos">42</span> <span class="n">coef_p2</span> <span class="o">=</span> <span class="mf">2.5</span> <span class="c1"># slope for current conversion for ADS.P2, measurement in V/V</span>
+<span class="linenos">43</span> <span class="n">coef_p3</span> <span class="o">=</span> <span class="mf">2.5</span> <span class="c1"># slope for current conversion for ADS.P3, measurement in V/V</span>
 </pre></div>
-</td></tr></table></div>
+</div>
 <p>The coefficient parameters can be adjusted in lines 40 to 43 of the ohmpi.py code.</p>
 </div></blockquote>
 </dd>
@@ -455,17 +454,21 @@ or stronger power supply, it would be possible to adjust the divider bridge valu
 Once all the components have been soldered together, the measurement board can be connected to the Raspberry Pi and the
 battery terminal, according to Figure 9. Between the battery and the TX+ terminal of the measurement board, remember to
 place a fuse holder with a 1.5-A fuse for safety purposes.</p>
-<div class="align-center figure" id="id2">
+<figure class="align-center" id="id2">
 <a class="reference internal image-reference" href="_images/measurement_board.jpg"><img alt="alternate text" src="_images/measurement_board.jpg" style="width: 800px; height: 500px;" /></a>
-<p class="caption"><span class="caption-text">Measurement circuit board assembly: a) printed circuit board, b) adding the 1-Kohm resistors ± 1%, c)adding the 1.5-Kohm resistors ± 1%, d) adding the black female 1 x 10 header and the 7-blue screw terminal block(2 pin, 3.5-mm pitch), e) adding the 50-ohm reference resistor ± 0.1%, and f) adding the ADS1115 and the LM358N low-power dual operational amplifiers</span><a class="headerlink" href="#id2" title="Permalink to this image">¶</a></p>
-</div>
-<div class="align-center figure" id="id3">
+<figcaption>
+<p><span class="caption-text">Measurement circuit board assembly: a) printed circuit board, b) adding the 1-Kohm resistors ± 1%, c)adding the 1.5-Kohm resistors ± 1%, d) adding the black female 1 x 10 header and the 7-blue screw terminal block(2 pin, 3.5-mm pitch), e) adding the 50-ohm reference resistor ± 0.1%, and f) adding the ADS1115 and the LM358N low-power dual operational amplifiers</span><a class="headerlink" href="#id2" title="Permalink to this image">¶</a></p>
+</figcaption>
+</figure>
+<figure class="align-center" id="id3">
 <a class="reference internal image-reference" href="_images/measurement_board-2.jpg"><img alt="alternate text" src="_images/measurement_board-2.jpg" style="width: 800px; height: 700px;" /></a>
-<p class="caption"><span class="caption-text">Measurement board installation with Raspberry Pi</span><a class="headerlink" href="#id3" title="Permalink to this image">¶</a></p>
-</div>
-</div>
-</div>
-<div class="section" id="current-injection-board">
+<figcaption>
+<p><span class="caption-text">Measurement board installation with Raspberry Pi</span><a class="headerlink" href="#id3" title="Permalink to this image">¶</a></p>
+</figcaption>
+</figure>
+</section>
+</section>
+<section id="current-injection-board">
 <h3>Current injection board<a class="headerlink" href="#current-injection-board" title="Permalink to this headline">¶</a></h3>
 <p>To carry out the electrical resistivity measurement, the first step consists of injecting current into the ground.
 In our case, a simple 9-V lead-acid battery is used to create an electrical potential difference that results
@@ -478,10 +481,12 @@ to the GPIO 7 on the Raspberry Pi and therefore activate simultaneously. The rol
 the polarity at electrodes A and B. Thus, when relays 3 and 4 are energized by the GPIO 8 in the open position,
 the positive battery pole is connected to electrode A and the negative pole to electrode B. When not energized,
 they remain in the normally closed position. This set-up offers a simple and robust solution to inject current.</p>
-<div class="align-center figure" id="id4">
+<figure class="align-center" id="id4">
 <a class="reference internal image-reference" href="_images/current_board.jpg"><img alt="alternate text" src="_images/current_board.jpg" style="width: 800px; height: 400px;" /></a>
-<p class="caption"><span class="caption-text">Wiring of the 4-channel relay module board for current injection management</span><a class="headerlink" href="#id4" title="Permalink to this image">¶</a></p>
-</div>
+<figcaption>
+<p><span class="caption-text">Wiring of the 4-channel relay module board for current injection management</span><a class="headerlink" href="#id4" title="Permalink to this image">¶</a></p>
+</figcaption>
+</figure>
 <p>The next step consists of featuring the 4-channel relay module used for current injection and its assembly. The wiring
 between the relays must be carried out in strict accordance with Fig. 10. This card must then be connected to the Raspberry
 Pi and the measurement card. On the Raspberry Pi, it is necessary to connect inputs In1 and In2 to the same GPIO. For this
@@ -489,20 +494,22 @@ purpose, it is necessary to solder together the two pins on the 4-channel relay
 the relay card’s 4 channels respectively to the GND pin and 5Vcc of the Raspberry Pi. Now connect relays 1, 2, 3 and 4, as
 shown in the diagram, using 1-mm2 cables (red and black in Fig. 10). Lastly, connect the inputs of relay 1 and 2 respectively
 to terminals B and A of the measurement board.</p>
-<div class="align-center figure" id="id5">
+<figure class="align-center" id="id5">
 <a class="reference internal image-reference" href="_images/installation_current_board.jpg"><img alt="alternate text" src="_images/installation_current_board.jpg" style="width: 800px; height: 700px;" /></a>
-<p class="caption"><span class="caption-text">Current injection board installation with Raspberry Pi</span><a class="headerlink" href="#id5" title="Permalink to this image">¶</a></p>
-</div>
+<figcaption>
+<p><span class="caption-text">Current injection board installation with Raspberry Pi</span><a class="headerlink" href="#id5" title="Permalink to this image">¶</a></p>
+</figcaption>
+</figure>
 <p>Congratulations, you have build a 4 electrodes resistivity-meter.</p>
-</div>
-<div class="section" id="frist-four-electrodes-resistivity-mesurement">
+</section>
+<section id="frist-four-electrodes-resistivity-mesurement">
 <h3>Frist four electrodes resistivity mesurement<a class="headerlink" href="#frist-four-electrodes-resistivity-mesurement" title="Permalink to this headline">¶</a></h3>
 <p>Under construction !</p>
 <p>Describe the way to valide the first part of the instruction.
 Electrical resistivity measurement on test circuit</p>
-</div>
-</div>
-<div class="section" id="multiplexer-implentation">
+</section>
+</section>
+<section id="multiplexer-implentation">
 <h2>Multiplexer implentation<a class="headerlink" href="#multiplexer-implentation" title="Permalink to this headline">¶</a></h2>
 <p>The resistivity measurement is conducted on four terminals (A, B, M and N). The user could perform each measurement
 by manually plugging four electrodes into the four channel terminals. In practice, ERT requires several tens or thousands
@@ -513,10 +520,12 @@ modules with 16 channels each. On the first board, on each MUX, 15 relays out of
 configuration enables making smaller multiplexers (8 or 16 electrodes only). On the other hand, if you prefer upping to 64 electrodes,
 which is entirely possible, a GPIO channel multiplier will have to be used.
 To prepare the multiplexer, the channels of the two relay boards must be connected according to the wiring diagram shown below.</p>
-<div class="align-center figure" id="id6">
+<figure class="align-center" id="id6">
 <a class="reference internal image-reference" href="_images/multiplexer_implementation.jpg"><img alt="alternate text" src="_images/multiplexer_implementation.jpg" style="width: 800px; height: 500px;" /></a>
-<p class="caption"><span class="caption-text">Schematic diagram of the wiring of two 16-channel relay shields</span><a class="headerlink" href="#id6" title="Permalink to this image">¶</a></p>
-</div>
+<figcaption>
+<p><span class="caption-text">Schematic diagram of the wiring of two 16-channel relay shields</span><a class="headerlink" href="#id6" title="Permalink to this image">¶</a></p>
+</figcaption>
+</figure>
 <p>For this purpose, 0.5-mm² cables with end caps are used and their length adjusted for each connection in order to produce a clean assembly.
 The length was adjusted so that the distance between the two points to be connected could be directly measured on the board once they had
 been assembled one above the other, in adding an extra 3 cm. The wires at the ends need to be stripped and the end caps added.
@@ -525,10 +534,12 @@ As a final step, connect the cables to the correct connectors. This operation mu
 for activating each relay (Fig. 12). However, we will be activating several relays with a single GPIO (to limit the number of GPIOs used on Raspberry Pi,
 see Section 2.4). To execute this step, it will be necessary to follow the protocol presented in Figure.</p>
 <blockquote>
-<div><div class="align-center figure" id="id7">
+<div><figure class="align-center" id="id7">
 <a class="reference internal image-reference" href="_images/connection.jpg"><img alt="alternate text" src="_images/connection.jpg" style="width: 800px; height: 400px;" /></a>
-<p class="caption"><span class="caption-text">Connection to the 16-channel relay shield</span><a class="headerlink" href="#id7" title="Permalink to this image">¶</a></p>
-</div>
+<figcaption>
+<p><span class="caption-text">Connection to the 16-channel relay shield</span><a class="headerlink" href="#id7" title="Permalink to this image">¶</a></p>
+</figcaption>
+</figure>
 </div></blockquote>
 <p>For the 16-channel relay shield no. 1, these steps must be followed:
 *       Position a test circuit with 10 horizontal and 10 vertical holes on the pins of the 16-channel relay shield board.
@@ -590,39 +601,43 @@ The next step consists of connecting the relay card inputs to the Raspberry Pi a
 <blockquote>
 <div><p>Connection of the GPIOs to each multiplexer</p>
 </div></blockquote>
-</div>
-<div class="section" id="electrode-connection">
+</section>
+<section id="electrode-connection">
 <h2>Electrode connection<a class="headerlink" href="#electrode-connection" title="Permalink to this headline">¶</a></h2>
 <p>At this point, all that remains is to connect the electrodes of each multiplexer to a terminal block (Fig. 13). In our set-up, screw terminals assembled on a din rail were used.
 According to the chosen multiplexer configuration, all the relays of each multiplexer will be connected to an electrode and, consequently, each electrode will have four incoming
 connections. Instead of having four cables connecting an electrode terminal to each multiplexer, we recommend using the cable assembly shown in the following Figure.</p>
-<div class="align-center figure" id="id8">
+<figure class="align-center" id="id8">
 <a class="reference internal image-reference" href="_images/cable.jpg"><img alt="alternate text" src="_images/cable.jpg" style="width: 800px; height: 300px;" /></a>
-<p class="caption"><span class="caption-text">Wire cabling for multiplexer and terminal screw connection</span><a class="headerlink" href="#id8" title="Permalink to this image">¶</a></p>
-</div>
+<figcaption>
+<p><span class="caption-text">Wire cabling for multiplexer and terminal screw connection</span><a class="headerlink" href="#id8" title="Permalink to this image">¶</a></p>
+</figcaption>
+</figure>
 <p>the next figure provides an example of multiplexer relay connections for electrode no. 1: this electrode of multiplexer MUX A must be connected to electrode no. 1 of MUX B. Moreover, electrode no. 1 of MUX B
 must be connected to electrode no. 1 of MUX N, which in turn must be connected to electrode no. 1 of MUX M. Lastly, electrode no. 1 of MUX M is connected to the terminal block.
 This operation must be repeated for all 32 electrodes.</p>
-<div class="align-center figure" id="id9">
+<figure class="align-center" id="id9">
 <a class="reference internal image-reference" href="_images/electrode_cable.jpg"><img alt="alternate text" src="_images/electrode_cable.jpg" style="width: 800px; height: 800px;" /></a>
-<p class="caption"><span class="caption-text">Example of a multiplexer connection to the screw terminal for electrode no. 1.</span><a class="headerlink" href="#id9" title="Permalink to this image">¶</a></p>
-</div>
+<figcaption>
+<p><span class="caption-text">Example of a multiplexer connection to the screw terminal for electrode no. 1.</span><a class="headerlink" href="#id9" title="Permalink to this image">¶</a></p>
+</figcaption>
+</figure>
 <div class="admonition warning">
 <p class="admonition-title">Warning</p>
 <p>The 16 channel relay cards exist in 5-V and 12-V , in the bottom figure we have 12-V cards that we will directly connect to the battery.
 In case you bought 16 channel relay 5-V cards, you will need to add a DC/DC 12-V/5-V converter. You can use a STEP DOWN MODULE DC-DC (Velleman WPM404) and set the voltage to 5V with the potentiometer.</p>
 </div>
-</div>
-<div class="section" id="operating-instruction">
+</section>
+<section id="operating-instruction">
 <h2>Operating instruction<a class="headerlink" href="#operating-instruction" title="Permalink to this headline">¶</a></h2>
-<div class="section" id="preliminary-procedure-only-for-the-initial-operation">
+<section id="preliminary-procedure-only-for-the-initial-operation">
 <h3>Preliminary procedure (Only for the initial operation)<a class="headerlink" href="#preliminary-procedure-only-for-the-initial-operation" title="Permalink to this headline">¶</a></h3>
 <p>The open source code must be downloaded at the Open Science Framework source file repository for this manuscript (<a class="reference external" href="https://osf.io/dzwb4/">https://osf.io/dzwb4/</a>)
 or at the following Gitlab repository address: <a class="reference external" href="https://gitlab.irstea.fr/reversaal/OhmPi">https://gitlab.irstea.fr/reversaal/OhmPi</a>. The code must be then unzipped into a selected folder (e.g. OhmPi-master). A “readme” file
 is proposed in the directory to assist with installation of the software and required python packages. It is strongly recommended to create a python virtual environment for installing
 the required packages and running the code.</p>
-</div>
-<div class="section" id="startup-procedure">
+</section>
+<section id="startup-procedure">
 <h3>Startup procedure<a class="headerlink" href="#startup-procedure" title="Permalink to this headline">¶</a></h3>
 <p>As an initial operating instruction, all batteries must be disconnected before any hardware handling. Ensure that the battery is charged at full capacity. Plug all the electrodes (32 or fewer)
 into the screw terminals. The Raspberry Pi must be plugged into a computer screen, with a mouse and keyboard accessed remotely. The Raspberry Pi must then be plugged into the power supply
@@ -632,30 +647,23 @@ function may be adjusted/optimized depending on the measurement attributes. For
 plugged into the hardware; the “ohmpi.py” source code must be run within a python3 environment (or a virtual environment if one has been created) either in the terminal or using Thonny. You should now
 hear the characteristic sound of a relay switching as a result of electrode permutation. After each quadrupole measurement, the potential difference as well as the current intensity and resistance
 are displayed on the screen. A measurement file is automatically created and named “measure.csv”; it will be placed in the same folder.</p>
-</div>
-<div class="section" id="electrical-resistivity-measurement-parameters-description">
+</section>
+<section id="electrical-resistivity-measurement-parameters-description">
 <h3>Electrical resistivity measurement parameters description<a class="headerlink" href="#electrical-resistivity-measurement-parameters-description" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>27
-28
-29
-30
-31
-32
-33
-34</pre></div></td><td class="code"><div class="highlight"><pre><span></span> <span class="sd">&quot;&quot;&quot;</span>
-<span class="sd"> measurement parameters</span>
-<span class="sd"> &quot;&quot;&quot;</span>
- <span class="n">nb_electrodes</span> <span class="o">=</span> <span class="mi">32</span> <span class="c1"># maximum number of electrodes on the resistivity meter</span>
- <span class="n">injection_duration</span> <span class="o">=</span> <span class="mf">0.5</span> <span class="c1"># Current injection duration in second</span>
- <span class="n">nbr_meas</span><span class="o">=</span> <span class="mi">1</span> <span class="c1"># Number of times the quadripole sequence is repeated</span>
- <span class="n">sequence_delay</span><span class="o">=</span> <span class="mi">30</span> <span class="c1"># Delay in seconds between 2 sequences</span>
- <span class="n">stack</span><span class="o">=</span> <span class="mi">1</span> <span class="c1"># repetition of the current injection for each quadripole</span>
+<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="linenos">27</span> <span class="sd">&quot;&quot;&quot;</span>
+<span class="linenos">28</span><span class="sd"> measurement parameters</span>
+<span class="linenos">29</span><span class="sd"> &quot;&quot;&quot;</span>
+<span class="linenos">30</span> <span class="n">nb_electrodes</span> <span class="o">=</span> <span class="mi">32</span> <span class="c1"># maximum number of electrodes on the resistivity meter</span>
+<span class="linenos">31</span> <span class="n">injection_duration</span> <span class="o">=</span> <span class="mf">0.5</span> <span class="c1"># Current injection duration in second</span>
+<span class="linenos">32</span> <span class="n">nbr_meas</span><span class="o">=</span> <span class="mi">1</span> <span class="c1"># Number of times the quadripole sequence is repeated</span>
+<span class="linenos">33</span> <span class="n">sequence_delay</span><span class="o">=</span> <span class="mi">30</span> <span class="c1"># Delay in seconds between 2 sequences</span>
+<span class="linenos">34</span> <span class="n">stack</span><span class="o">=</span> <span class="mi">1</span> <span class="c1"># repetition of the current injection for each quadripole</span>
 </pre></div>
-</td></tr></table></div>
-<p>The measurement parameters can be adjusted in lines 27 to 30 of the ohmpi.py code.</p>
-</div>
 </div>
-<div class="section" id="complete-list-of-components">
+<p>The measurement parameters can be adjusted in lines 27 to 30 of the ohmpi.py code.</p>
+</section>
+</section>
+<section id="complete-list-of-components">
 <h2>Complete list of components<a class="headerlink" href="#complete-list-of-components" title="Permalink to this headline">¶</a></h2>
 <div class="admonition warning">
 <p class="admonition-title">Warning</p>
@@ -823,8 +831,8 @@ are displayed on the screen. A measurement file is automatically created and nam
 </tr>
 </tbody>
 </table>
-</div>
-</div>
+</section>
+</section>
 
 
            </div>
diff --git a/public/V1_02.html b/public/V1_02.html
index 69f5cc21c795fbb42e94ea8671f63d7ed3070b39..1d1ce83c11b2a24d5433cb2563d22e0d4cb95c0c 100644
--- a/public/V1_02.html
+++ b/public/V1_02.html
@@ -4,7 +4,8 @@
 <html class="writer-html5" lang="en" >
 <head>
   <meta charset="utf-8">
-  
+  <meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
+
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   
   <title>OhmPi V 1.02 (limited to 32 electrodes) &mdash; Ohmpi: open hardware resistivity-meter documentation</title>
@@ -13,6 +14,8 @@
   
   <link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
   <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+  <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+  <link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
 
   
   
@@ -26,17 +29,18 @@
   
     
       <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
+        <script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
         <script src="_static/jquery.js"></script>
         <script src="_static/underscore.js"></script>
         <script src="_static/doctools.js"></script>
-        <script src="_static/language_data.js"></script>
-        <script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
+        <script async="async" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
     
     <script type="text/javascript" src="_static/js/theme.js"></script>
 
     
     <link rel="index" title="Index" href="genindex.html" />
     <link rel="search" title="Search" href="search.html" />
+    <link rel="next" title="OhmPi V 2.00 (64 or 128 électrodes)" href="V2_00.html" />
     <link rel="prev" title="OhmPi V 1.01 (limited to 32 electrodes)" href="V1_01.html" /> 
 </head>
 
@@ -115,6 +119,7 @@
 <li class="toctree-l2"><a class="reference internal" href="#complete-list-of-components">Complete list of components</a></li>
 </ul>
 </li>
+<li class="toctree-l1"><a class="reference internal" href="V2_00.html">OhmPi V 2.00 (64 or 128 électrodes)</a></li>
 </ul>
 
             
@@ -180,19 +185,19 @@
           <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
            <div itemprop="articleBody">
             
-  <div class="section" id="ohmpi-v-1-02-limited-to-32-electrodes">
+  <section id="ohmpi-v-1-02-limited-to-32-electrodes">
 <h1>OhmPi V 1.02 (limited to 32 electrodes)<a class="headerlink" href="#ohmpi-v-1-02-limited-to-32-electrodes" title="Permalink to this headline">¶</a></h1>
 <div class="admonition note">
 <p class="admonition-title">Note</p>
 <p>In this version, we have improved the electronic measurement board. To upgrade from version 1.01 to 1.02, you just have to replace the measurement board by the new one proposed here.</p>
 </div>
-<div class="section" id="the-philosophy-of-ohmpi">
+<section id="the-philosophy-of-ohmpi">
 <h2>The philosophy of Ohmpi<a class="headerlink" href="#the-philosophy-of-ohmpi" title="Permalink to this headline">¶</a></h2>
 <p>The philosophy of Ohmpi V1.01 is to offer a multi electrode resistivity meter, from a set of commercially available
 electronic cards it is a resistivity meter limited to 32 electrodes only. It is limited to low-current injection,
 but suitable for small laboratory experiments and small field time monitoring</p>
-</div>
-<div class="section" id="technical-data">
+</section>
+<section id="technical-data">
 <h2>Technical data<a class="headerlink" href="#technical-data" title="Permalink to this headline">¶</a></h2>
 <table class="docutils align-default">
 <colgroup>
@@ -248,10 +253,10 @@ control system</p></td>
 </tr>
 </tbody>
 </table>
-</div>
-<div class="section" id="raspberry-pi-configuration">
+</section>
+<section id="raspberry-pi-configuration">
 <h2>Raspberry Pi  configuration<a class="headerlink" href="#raspberry-pi-configuration" title="Permalink to this headline">¶</a></h2>
-<div class="section" id="os-installation">
+<section id="os-installation">
 <h3>OS installation<a class="headerlink" href="#os-installation" title="Permalink to this headline">¶</a></h3>
 <p>The first step is to start up the Raspberry Pi board, including installation of an OS (operating system).
 For this step, the installation instructions are well described on the Raspberry website</p>
@@ -262,9 +267,9 @@ For this step, the installation instructions are well described on the Raspberry
 <div class="admonition note">
 <p class="admonition-title">Note</p>
 <p>All the development tests were performed on Raspberry Pi 3 Model B, we used the following version of Raspbian:</p>
-<div class="align-center figure">
+<figure class="align-center">
 <a class="reference internal image-reference" href="_images/raspbian_version.jpg"><img alt="alternate text" src="_images/raspbian_version.jpg" style="width: 800px; height: 400px;" /></a>
-</div>
+</figure>
 </div>
 <div class="admonition warning">
 <p class="admonition-title">Warning</p>
@@ -300,8 +305,8 @@ To ensure that the GPIOs are in Low position, you will need to modify the /boot/
 <li><p>Press Ctrl +x to escap and return to the terminal</p></li>
 <li><p>Close the terminal</p></li>
 </ol>
-</div>
-<div class="section" id="virtual-environnement-and-packages">
+</section>
+<section id="virtual-environnement-and-packages">
 <h3>Virtual Environnement and packages<a class="headerlink" href="#virtual-environnement-and-packages" title="Permalink to this headline">¶</a></h3>
 <p>All dependencies are specified in requirements.txt</p>
 <div class="admonition note">
@@ -334,38 +339,38 @@ to leave the virtual environment simply type:</p>
 <div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">deactivate</span>
 </pre></div>
 </div>
-</div>
-<div class="section" id="activate-virtual-environnement-on-thonny-python-ide-on-rapberry-pi">
+</section>
+<section id="activate-virtual-environnement-on-thonny-python-ide-on-rapberry-pi">
 <h3>Activate virtual environnement on Thonny (Python IDE)  (on Rapberry Pi)<a class="headerlink" href="#activate-virtual-environnement-on-thonny-python-ide-on-rapberry-pi" title="Permalink to this headline">¶</a></h3>
 <p>If you decided to use a virtual environment, it is necessary to setup Thonny Python IDE the first time you use it.</p>
 <p>1- Run the Thonny Python IDE software, Click on raspebrry acces <strong>menu &gt; programming&gt; Thonny pythonIDE</strong></p>
 <p>2- Thonny’s interface opens, Python runs on the Root (Python 3.7.3 (/usr/bin/python3))</p>
-<div class="align-center figure">
+<figure class="align-center">
 <a class="reference internal image-reference" href="_images/thonny_first_interface.jpg"><img alt="alternate text" src="_images/thonny_first_interface.jpg" style="width: 600px; height: 450px;" /></a>
-</div>
+</figure>
 <p>3-Click on <strong>Run&gt;select interpreter</strong>, a new window opens click on interpret</p>
-<div class="align-center figure">
+<figure class="align-center">
 <a class="reference internal image-reference" href="_images/thonny_option.jpg"><img alt="alternate text" src="_images/thonny_option.jpg" style="width: 600px; height: 450px;" /></a>
-</div>
+</figure>
 <p>4-On the new open windows select <strong>alternative Pyhton3 or virtual environnement</strong></p>
-<div class="align-center figure">
+<figure class="align-center">
 <a class="reference internal image-reference" href="_images/thonny_interpreter.jpg"><img alt="alternate text" src="_images/thonny_interpreter.jpg" style="width: 600px; height: 450px;" /></a>
-</div>
+</figure>
 <p>5- New buttons appeared, selected <strong>“locate another python executable “</strong></p>
 <p>6- A new window opens, find the folder where there is the python 3 file in the virtual environment folder previously created <strong>/home/pi/ohmpi/bin/python3</strong>.</p>
 <p>7- In the <strong>known interpreter</strong> tab the path of the virtual environnementshould appear</p>
-<div class="align-center figure">
+<figure class="align-center">
 <a class="reference internal image-reference" href="_images/thonny_interpreter_folder.jpg"><img alt="alternate text" src="_images/thonny_interpreter_folder.jpg" style="width: 600px; height: 450px;" /></a>
-</div>
+</figure>
 <p>8- Close the window by clicking on <strong>ok</strong>.</p>
 <p>9- Close thonny to save modifications</p>
-</div>
-</div>
-<div class="section" id="assembly-of-the-measuring-current-injection-cards-and-connection-with-the-raspberry-pi">
+</section>
+</section>
+<section id="assembly-of-the-measuring-current-injection-cards-and-connection-with-the-raspberry-pi">
 <h2>Assembly of the measuring/current injection cards, and connection with the Raspberry Pi<a class="headerlink" href="#assembly-of-the-measuring-current-injection-cards-and-connection-with-the-raspberry-pi" title="Permalink to this headline">¶</a></h2>
-<div class="section" id="electrical-resistivity-measurements-board">
+<section id="electrical-resistivity-measurements-board">
 <h3>Electrical resistivity measurements board<a class="headerlink" href="#electrical-resistivity-measurements-board" title="Permalink to this headline">¶</a></h3>
-<div class="section" id="a-description">
+<section id="a-description">
 <h4>a) Description<a class="headerlink" href="#a-description" title="Permalink to this headline">¶</a></h4>
 <p>To measure electrical resistivity with Raspberry Pi, an ADS1115 was introduced, as proposed by Florsch [7]. The ADS1115
 is a 16-bit ADC (Analog-to-Digital Converter), with an adaptable gain. Its value has been set at 2/3 in this study. The
@@ -403,16 +408,18 @@ In version 1.02, we have improved the electronic board of measurement. we have a
 We also added 4 capacitors on the +12v inputs of the fast operational amplifiers. These are decoupling capacitors (typically 100nF ceramic)
 between each power supply terminal and ground. The last point, we have added a four very high resistances of 10 MOhm, between the ground and
 the signal input on the operational amplifiers. This prevents the operational amplifiers from overheating.</p>
-<div class="align-center figure" id="id1">
+<figure class="align-center" id="id1">
 <a class="reference internal image-reference" href="_images/schema_measurement_board1_02.png"><img alt="alternate text" src="_images/schema_measurement_board1_02.png" style="width: 800px; height: 400px;" /></a>
-<p class="caption"><span class="caption-text">Measurement board (Ohmpi version 1.02)</span><a class="headerlink" href="#id1" title="Permalink to this image">¶</a></p>
-</div>
+<figcaption>
+<p><span class="caption-text">Measurement board (Ohmpi version 1.02)</span><a class="headerlink" href="#id1" title="Permalink to this image">¶</a></p>
+</figcaption>
+</figure>
 <div class="admonition note">
 <p class="admonition-title">Note</p>
 <p>If you want to have very accurate measurements you can replace the resistors with a tolerance of 1% by resistors with a tolerance of 0.01% which will improve the measurement, but the cost will be higher.</p>
 </div>
-</div>
-<div class="section" id="b-implementation">
+</section>
+<section id="b-implementation">
 <h4>b) Implementation<a class="headerlink" href="#b-implementation" title="Permalink to this headline">¶</a></h4>
 <p>The measurement board must be printed using the PCB file (Source file repository), with components soldered onto
 it by following the steps described below and illustrated in the following figure :</p>
@@ -428,23 +435,16 @@ it by following the steps described below and illustrated in the following figur
 \[coeff p2 = (R7 + R6) / R7\]</div>
 <div class="math notranslate nohighlight">
 \[coeff p3 = (R9 + R8) / R9\]</div>
-<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>36
-37
-38
-39
-40
-41
-42
-43</pre></div></td><td class="code"><div class="highlight"><pre><span></span> <span class="sd">&quot;&quot;&quot;</span>
-<span class="sd"> hardware parameters</span>
-<span class="sd"> &quot;&quot;&quot;</span>
- <span class="n">R_ref</span> <span class="o">=</span> <span class="mi">50</span> <span class="c1"># reference resistance value in ohm</span>
- <span class="n">coef_p0</span> <span class="o">=</span> <span class="mf">2.5</span> <span class="c1"># slope for current conversion for ADS.P0, measurement in V/V</span>
- <span class="n">coef_p1</span> <span class="o">=</span> <span class="mf">2.5</span> <span class="c1"># slope for current conversion for ADS.P1, measurement in V/V</span>
- <span class="n">coef_p2</span> <span class="o">=</span> <span class="mf">2.5</span> <span class="c1"># slope for current conversion for ADS.P2, measurement in V/V</span>
- <span class="n">coef_p3</span> <span class="o">=</span> <span class="mf">2.5</span> <span class="c1"># slope for current conversion for ADS.P3, measurement in V/V</span>
+<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="linenos">36</span> <span class="sd">&quot;&quot;&quot;</span>
+<span class="linenos">37</span><span class="sd"> hardware parameters</span>
+<span class="linenos">38</span><span class="sd"> &quot;&quot;&quot;</span>
+<span class="linenos">39</span> <span class="n">R_ref</span> <span class="o">=</span> <span class="mi">50</span> <span class="c1"># reference resistance value in ohm</span>
+<span class="linenos">40</span> <span class="n">coef_p0</span> <span class="o">=</span> <span class="mf">2.5</span> <span class="c1"># slope for current conversion for ADS.P0, measurement in V/V</span>
+<span class="linenos">41</span> <span class="n">coef_p1</span> <span class="o">=</span> <span class="mf">2.5</span> <span class="c1"># slope for current conversion for ADS.P1, measurement in V/V</span>
+<span class="linenos">42</span> <span class="n">coef_p2</span> <span class="o">=</span> <span class="mf">2.5</span> <span class="c1"># slope for current conversion for ADS.P2, measurement in V/V</span>
+<span class="linenos">43</span> <span class="n">coef_p3</span> <span class="o">=</span> <span class="mf">2.5</span> <span class="c1"># slope for current conversion for ADS.P3, measurement in V/V</span>
 </pre></div>
-</td></tr></table></div>
+</div>
 <p>The coefficient parameters can be adjusted in lines 40 to 43 of the ohmpi.py code.</p>
 </div></blockquote>
 </dd>
@@ -463,17 +463,21 @@ it by following the steps described below and illustrated in the following figur
 Once all the components have been soldered together, the measurement board can be connected to the Raspberry Pi and the
 battery terminal, according to Figure 9. Between the battery and the TX+ terminal of the measurement board, remember to
 place a fuse holder with a 1.5-A fuse for safety purposes.</p>
-<div class="align-center figure" id="id2">
+<figure class="align-center" id="id2">
 <a class="reference internal image-reference" href="_images/measurement_board1-02.jpg"><img alt="alternate text" src="_images/measurement_board1-02.jpg" style="width: 800px; height: 700px;" /></a>
-<p class="caption"><span class="caption-text">Measurement circuit board assembly: a) printed circuit board, b) adding the 1-Kohm resistors ± 1%, c)adding the 1.5-Kohm resistors ± 1%, d) adding the black female 1 x 10 header and the 7-blue screw terminal block(2 pin, 3.5-mm pitch), e) adding the 50-ohm reference resistor ± 0.1%, and f) adding the ADS1115 and the LM358N low-power dual operational amplifiers</span><a class="headerlink" href="#id2" title="Permalink to this image">¶</a></p>
-</div>
-<div class="align-center figure" id="id3">
+<figcaption>
+<p><span class="caption-text">Measurement circuit board assembly: a) printed circuit board, b) adding the 1-Kohm resistors ± 1%, c)adding the 1.5-Kohm resistors ± 1%, d) adding the black female 1 x 10 header and the 7-blue screw terminal block(2 pin, 3.5-mm pitch), e) adding the 50-ohm reference resistor ± 0.1%, and f) adding the ADS1115 and the LM358N low-power dual operational amplifiers</span><a class="headerlink" href="#id2" title="Permalink to this image">¶</a></p>
+</figcaption>
+</figure>
+<figure class="align-center" id="id3">
 <a class="reference internal image-reference" href="_images/measurement_board-2-V1-02.jpg"><img alt="alternate text" src="_images/measurement_board-2-V1-02.jpg" style="width: 800px; height: 700px;" /></a>
-<p class="caption"><span class="caption-text">Measurement board installation with Raspberry Pi</span><a class="headerlink" href="#id3" title="Permalink to this image">¶</a></p>
-</div>
-</div>
-</div>
-<div class="section" id="current-injection-board">
+<figcaption>
+<p><span class="caption-text">Measurement board installation with Raspberry Pi</span><a class="headerlink" href="#id3" title="Permalink to this image">¶</a></p>
+</figcaption>
+</figure>
+</section>
+</section>
+<section id="current-injection-board">
 <h3>Current injection board<a class="headerlink" href="#current-injection-board" title="Permalink to this headline">¶</a></h3>
 <p>To carry out the electrical resistivity measurement, the first step consists of injecting current into the ground.
 In our case, a simple 9-V lead-acid battery is used to create an electrical potential difference that results
@@ -486,10 +490,12 @@ to the GPIO 7 on the Raspberry Pi and therefore activate simultaneously. The rol
 the polarity at electrodes A and B. Thus, when relays 3 and 4 are energized by the GPIO 8 in the open position,
 the positive battery pole is connected to electrode A and the negative pole to electrode B. When not energized,
 they remain in the normally closed position. This set-up offers a simple and robust solution to inject current.</p>
-<div class="align-center figure" id="id4">
+<figure class="align-center" id="id4">
 <a class="reference internal image-reference" href="_images/current_board.jpg"><img alt="alternate text" src="_images/current_board.jpg" style="width: 800px; height: 400px;" /></a>
-<p class="caption"><span class="caption-text">Wiring of the 4-channel relay module board for current injection management</span><a class="headerlink" href="#id4" title="Permalink to this image">¶</a></p>
-</div>
+<figcaption>
+<p><span class="caption-text">Wiring of the 4-channel relay module board for current injection management</span><a class="headerlink" href="#id4" title="Permalink to this image">¶</a></p>
+</figcaption>
+</figure>
 <p>The next step consists of featuring the 4-channel relay module used for current injection and its assembly. The wiring
 between the relays must be carried out in strict accordance with Fig. 10. This card must then be connected to the Raspberry
 Pi and the measurement card. On the Raspberry Pi, it is necessary to connect inputs In1 and In2 to the same GPIO. For this
@@ -497,20 +503,22 @@ purpose, it is necessary to solder together the two pins on the 4-channel relay
 the relay card’s 4 channels respectively to the GND pin and 5Vcc of the Raspberry Pi. Now connect relays 1, 2, 3 and 4, as
 shown in the diagram, using 1-mm2 cables (red and black in Fig. 10). Lastly, connect the inputs of relay 1 and 2 respectively
 to terminals B and A of the measurement board.</p>
-<div class="align-center figure" id="id5">
+<figure class="align-center" id="id5">
 <a class="reference internal image-reference" href="_images/installation_current_board_1_02.jpg"><img alt="alternate text" src="_images/installation_current_board_1_02.jpg" style="width: 800px; height: 700px;" /></a>
-<p class="caption"><span class="caption-text">Current injection board installation with Raspberry Pi</span><a class="headerlink" href="#id5" title="Permalink to this image">¶</a></p>
-</div>
+<figcaption>
+<p><span class="caption-text">Current injection board installation with Raspberry Pi</span><a class="headerlink" href="#id5" title="Permalink to this image">¶</a></p>
+</figcaption>
+</figure>
 <p>Congratulations, you have build a 4 electrodes resistivity-meter.</p>
-</div>
-<div class="section" id="frist-four-electrodes-resistivity-mesurement">
+</section>
+<section id="frist-four-electrodes-resistivity-mesurement">
 <h3>Frist four electrodes resistivity mesurement<a class="headerlink" href="#frist-four-electrodes-resistivity-mesurement" title="Permalink to this headline">¶</a></h3>
 <p>Under construction !</p>
 <p>Describe the way to valide the first part of the instruction.
 Electrical resistivity measurement on test circuit</p>
-</div>
-</div>
-<div class="section" id="multiplexer-implentation">
+</section>
+</section>
+<section id="multiplexer-implentation">
 <h2>Multiplexer implentation<a class="headerlink" href="#multiplexer-implentation" title="Permalink to this headline">¶</a></h2>
 <p>The resistivity measurement is conducted on four terminals (A, B, M and N). The user could perform each measurement
 by manually plugging four electrodes into the four channel terminals. In practice, ERT requires several tens or thousands
@@ -521,10 +529,12 @@ modules with 16 channels each. On the first board, on each MUX, 15 relays out of
 configuration enables making smaller multiplexers (8 or 16 electrodes only). On the other hand, if you prefer upping to 64 electrodes,
 which is entirely possible, a GPIO channel multiplier will have to be used.
 To prepare the multiplexer, the channels of the two relay boards must be connected according to the wiring diagram shown below.</p>
-<div class="align-center figure" id="id6">
+<figure class="align-center" id="id6">
 <a class="reference internal image-reference" href="_images/multiplexer_implementation.jpg"><img alt="alternate text" src="_images/multiplexer_implementation.jpg" style="width: 800px; height: 500px;" /></a>
-<p class="caption"><span class="caption-text">Schematic diagram of the wiring of two 16-channel relay shields</span><a class="headerlink" href="#id6" title="Permalink to this image">¶</a></p>
-</div>
+<figcaption>
+<p><span class="caption-text">Schematic diagram of the wiring of two 16-channel relay shields</span><a class="headerlink" href="#id6" title="Permalink to this image">¶</a></p>
+</figcaption>
+</figure>
 <p>For this purpose, 0.5-mm² cables with end caps are used and their length adjusted for each connection in order to produce a clean assembly.
 The length was adjusted so that the distance between the two points to be connected could be directly measured on the board once they had
 been assembled one above the other, in adding an extra 3 cm. The wires at the ends need to be stripped and the end caps added.
@@ -533,10 +543,12 @@ As a final step, connect the cables to the correct connectors. This operation mu
 for activating each relay (Fig. 12). However, we will be activating several relays with a single GPIO (to limit the number of GPIOs used on Raspberry Pi,
 see Section 2.4). To execute this step, it will be necessary to follow the protocol presented in Figure.</p>
 <blockquote>
-<div><div class="align-center figure" id="id7">
+<div><figure class="align-center" id="id7">
 <a class="reference internal image-reference" href="_images/connection.jpg"><img alt="alternate text" src="_images/connection.jpg" style="width: 800px; height: 400px;" /></a>
-<p class="caption"><span class="caption-text">Connection to the 16-channel relay shield</span><a class="headerlink" href="#id7" title="Permalink to this image">¶</a></p>
-</div>
+<figcaption>
+<p><span class="caption-text">Connection to the 16-channel relay shield</span><a class="headerlink" href="#id7" title="Permalink to this image">¶</a></p>
+</figcaption>
+</figure>
 </div></blockquote>
 <p>For the 16-channel relay shield no. 1, these steps must be followed:
 *       Position a test circuit with 10 horizontal and 10 vertical holes on the pins of the 16-channel relay shield board.
@@ -598,39 +610,43 @@ The next step consists of connecting the relay card inputs to the Raspberry Pi a
 <blockquote>
 <div><p>Connection of the GPIOs to each multiplexer</p>
 </div></blockquote>
-</div>
-<div class="section" id="electrode-connection">
+</section>
+<section id="electrode-connection">
 <h2>Electrode connection<a class="headerlink" href="#electrode-connection" title="Permalink to this headline">¶</a></h2>
 <p>At this point, all that remains is to connect the electrodes of each multiplexer to a terminal block (Fig. 13). In our set-up, screw terminals assembled on a din rail were used.
 According to the chosen multiplexer configuration, all the relays of each multiplexer will be connected to an electrode and, consequently, each electrode will have four incoming
 connections. Instead of having four cables connecting an electrode terminal to each multiplexer, we recommend using the cable assembly shown in the following Figure.</p>
-<div class="align-center figure" id="id8">
+<figure class="align-center" id="id8">
 <a class="reference internal image-reference" href="_images/cable.jpg"><img alt="alternate text" src="_images/cable.jpg" style="width: 800px; height: 300px;" /></a>
-<p class="caption"><span class="caption-text">Wire cabling for multiplexer and terminal screw connection</span><a class="headerlink" href="#id8" title="Permalink to this image">¶</a></p>
-</div>
+<figcaption>
+<p><span class="caption-text">Wire cabling for multiplexer and terminal screw connection</span><a class="headerlink" href="#id8" title="Permalink to this image">¶</a></p>
+</figcaption>
+</figure>
 <p>the next figure provides an example of multiplexer relay connections for electrode no. 1: this electrode of multiplexer MUX A must be connected to electrode no. 1 of MUX B. Moreover, electrode no. 1 of MUX B
 must be connected to electrode no. 1 of MUX N, which in turn must be connected to electrode no. 1 of MUX M. Lastly, electrode no. 1 of MUX M is connected to the terminal block.
 This operation must be repeated for all 32 electrodes.</p>
-<div class="align-center figure" id="id9">
+<figure class="align-center" id="id9">
 <a class="reference internal image-reference" href="_images/electrode_cable.jpg"><img alt="alternate text" src="_images/electrode_cable.jpg" style="width: 800px; height: 800px;" /></a>
-<p class="caption"><span class="caption-text">Example of a multiplexer connection to the screw terminal for electrode no. 1.</span><a class="headerlink" href="#id9" title="Permalink to this image">¶</a></p>
-</div>
+<figcaption>
+<p><span class="caption-text">Example of a multiplexer connection to the screw terminal for electrode no. 1.</span><a class="headerlink" href="#id9" title="Permalink to this image">¶</a></p>
+</figcaption>
+</figure>
 <div class="admonition warning">
 <p class="admonition-title">Warning</p>
 <p>The 16 channel relay cards exist in 5-V and 12-V , in the bottom figure we have 12-V cards that we will directly connect to the battery.
 In case you bought 16 channel relay 5-V cards, you will need to add a DC/DC 12-V/5-V converter. You can use a STEP DOWN MODULE DC-DC (Velleman WPM404) and set the voltage to 5V with the potentiometer.</p>
 </div>
-</div>
-<div class="section" id="operating-instruction">
+</section>
+<section id="operating-instruction">
 <h2>Operating instruction<a class="headerlink" href="#operating-instruction" title="Permalink to this headline">¶</a></h2>
-<div class="section" id="preliminary-procedure-only-for-the-initial-operation">
+<section id="preliminary-procedure-only-for-the-initial-operation">
 <h3>Preliminary procedure (Only for the initial operation)<a class="headerlink" href="#preliminary-procedure-only-for-the-initial-operation" title="Permalink to this headline">¶</a></h3>
 <p>The open source code must be downloaded at the Open Science Framework source file repository for this manuscript (<a class="reference external" href="https://osf.io/dzwb4/">https://osf.io/dzwb4/</a>)
 or at the following Gitlab repository address: <a class="reference external" href="https://gitlab.irstea.fr/reversaal/OhmPi">https://gitlab.irstea.fr/reversaal/OhmPi</a>. The code must be then unzipped into a selected folder (e.g. OhmPi-master). A “readme” file
 is proposed in the directory to assist with installation of the software and required python packages. It is strongly recommended to create a python virtual environment for installing
 the required packages and running the code.</p>
-</div>
-<div class="section" id="startup-procedure">
+</section>
+<section id="startup-procedure">
 <h3>Startup procedure<a class="headerlink" href="#startup-procedure" title="Permalink to this headline">¶</a></h3>
 <p>As an initial operating instruction, all batteries must be disconnected before any hardware handling. Ensure that the battery is charged at full capacity. Plug all the electrodes (32 or fewer)
 into the screw terminals. The Raspberry Pi must be plugged into a computer screen, with a mouse and keyboard accessed remotely. The Raspberry Pi must then be plugged into the power supply
@@ -640,26 +656,21 @@ function may be adjusted/optimized depending on the measurement attributes. For
 plugged into the hardware; the “ohmpi.py” source code must be run within a python3 environment (or a virtual environment if one has been created) either in the terminal or using Thonny. You should now
 hear the characteristic sound of a relay switching as a result of electrode permutation. After each quadrupole measurement, the potential difference as well as the current intensity and resistance
 are displayed on the screen. A measurement file is automatically created and named “measure.csv”; it will be placed in the same folder.</p>
-</div>
-<div class="section" id="electrical-resistivity-measurement-parameters-description">
+</section>
+<section id="electrical-resistivity-measurement-parameters-description">
 <h3>Electrical resistivity measurement parameters description<a class="headerlink" href="#electrical-resistivity-measurement-parameters-description" title="Permalink to this headline">¶</a></h3>
 <p>In the version 1.02, the measurement parameters are in the Jason file (ohmpi_param.json).</p>
-<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1
-2
-3
-4
-5
-6</pre></div></td><td class="code"><div class="highlight"><pre><span></span> <span class="n">nb_electrodes</span> <span class="o">=</span> <span class="mi">32</span> <span class="c1"># maximum number of electrodes on the resistivity meter</span>
- <span class="n">injection_duration</span> <span class="o">=</span> <span class="mf">0.5</span> <span class="c1"># Current injection duration in second</span>
- <span class="n">nbr_meas</span><span class="o">=</span> <span class="mi">1</span> <span class="c1"># Number of times the quadripole sequence is repeated</span>
- <span class="n">sequence_delay</span><span class="o">=</span> <span class="mi">30</span> <span class="c1"># Delay in seconds between 2 sequences</span>
- <span class="n">stack</span><span class="o">=</span> <span class="mi">1</span> <span class="c1"># repetition of the current injection for each quadripole</span>
- <span class="n">export_path</span><span class="o">=</span> <span class="s2">&quot;home/pi/Desktop/measurement.csv&quot;</span>
+<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="linenos">1</span> <span class="n">nb_electrodes</span> <span class="o">=</span> <span class="mi">32</span> <span class="c1"># maximum number of electrodes on the resistivity meter</span>
+<span class="linenos">2</span> <span class="n">injection_duration</span> <span class="o">=</span> <span class="mf">0.5</span> <span class="c1"># Current injection duration in second</span>
+<span class="linenos">3</span> <span class="n">nbr_meas</span><span class="o">=</span> <span class="mi">1</span> <span class="c1"># Number of times the quadripole sequence is repeated</span>
+<span class="linenos">4</span> <span class="n">sequence_delay</span><span class="o">=</span> <span class="mi">30</span> <span class="c1"># Delay in seconds between 2 sequences</span>
+<span class="linenos">5</span> <span class="n">stack</span><span class="o">=</span> <span class="mi">1</span> <span class="c1"># repetition of the current injection for each quadripole</span>
+<span class="linenos">6</span> <span class="n">export_path</span><span class="o">=</span> <span class="s2">&quot;home/pi/Desktop/measurement.csv&quot;</span>
 </pre></div>
-</td></tr></table></div>
 </div>
-</div>
-<div class="section" id="complete-list-of-components">
+</section>
+</section>
+<section id="complete-list-of-components">
 <h2>Complete list of components<a class="headerlink" href="#complete-list-of-components" title="Permalink to this headline">¶</a></h2>
 <div class="admonition warning">
 <p class="admonition-title">Warning</p>
@@ -834,8 +845,8 @@ are displayed on the screen. A measurement file is automatically created and nam
 </tr>
 </tbody>
 </table>
-</div>
-</div>
+</section>
+</section>
 
 
            </div>
@@ -845,6 +856,8 @@ are displayed on the screen. A measurement file is automatically created and nam
   
     <div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
       
+        <a href="V2_00.html" class="btn btn-neutral float-right" title="OhmPi V 2.00 (64 or 128 électrodes)" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right"></span></a>
+      
       
         <a href="V1_01.html" class="btn btn-neutral float-left" title="OhmPi V 1.01 (limited to 32 electrodes)" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left"></span> Previous</a>
       
diff --git a/public/V2_00.html b/public/V2_00.html
new file mode 100644
index 0000000000000000000000000000000000000000..f4a2747bdab9505f61baabc391c9f66c8f5abba4
--- /dev/null
+++ b/public/V2_00.html
@@ -0,0 +1,603 @@
+
+
+<!DOCTYPE html>
+<html class="writer-html5" lang="en" >
+<head>
+  <meta charset="utf-8">
+  <meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
+
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  
+  <title>OhmPi V 2.00 (64 or 128 électrodes) &mdash; Ohmpi: open hardware resistivity-meter documentation</title>
+  
+
+  
+  <link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
+  <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+  <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+  <link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
+
+  
+  
+  
+  
+
+  
+  <!--[if lt IE 9]>
+    <script src="_static/js/html5shiv.min.js"></script>
+  <![endif]-->
+  
+    
+      <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
+        <script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
+        <script src="_static/jquery.js"></script>
+        <script src="_static/underscore.js"></script>
+        <script src="_static/doctools.js"></script>
+    
+    <script type="text/javascript" src="_static/js/theme.js"></script>
+
+    
+    <link rel="index" title="Index" href="genindex.html" />
+    <link rel="search" title="Search" href="search.html" />
+    <link rel="prev" title="OhmPi V 1.02 (limited to 32 electrodes)" href="V1_02.html" /> 
+</head>
+
+<body class="wy-body-for-nav">
+
+   
+  <div class="wy-grid-for-nav">
+    
+    <nav data-toggle="wy-nav-shift" class="wy-nav-side">
+      <div class="wy-side-scroll">
+        <div class="wy-side-nav-search" >
+          
+
+          
+            <a href="index.html" class="icon icon-home" alt="Documentation Home"> Ohmpi:
+          
+
+          
+          </a>
+
+          
+            
+            
+          
+
+          
+<div role="search">
+  <form id="rtd-search-form" class="wy-form" action="search.html" method="get">
+    <input type="text" name="q" placeholder="Search docs" />
+    <input type="hidden" name="check_keywords" value="yes" />
+    <input type="hidden" name="area" value="default" />
+  </form>
+</div>
+
+          
+        </div>
+
+        
+        <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
+          
+            
+            
+              
+            
+            
+              <ul class="current">
+<li class="toctree-l1"><a class="reference internal" href="Ohmpi.html">OhmPi project</a></li>
+<li class="toctree-l1"><a class="reference internal" href="V1_01.html">OhmPi V 1.01 (limited to 32 electrodes)</a></li>
+<li class="toctree-l1"><a class="reference internal" href="V1_02.html">OhmPi V 1.02 (limited to 32 electrodes)</a></li>
+<li class="toctree-l1 current"><a class="current reference internal" href="#">OhmPi V 2.00 (64 or 128 électrodes)</a><ul>
+<li class="toctree-l2"><a class="reference internal" href="#the-philosophy-of-ohmpi">The philosophy of Ohmpi</a></li>
+<li class="toctree-l2"><a class="reference internal" href="#technical-data">Technical data</a></li>
+<li class="toctree-l2"><a class="reference internal" href="#step-n1-raspberry-pi-configuration"><strong>STEP n°1</strong> : Raspberry Pi  configuration</a><ul>
+<li class="toctree-l3"><a class="reference internal" href="#os-installation">OS installation</a></li>
+<li class="toctree-l3"><a class="reference internal" href="#virtual-environnement-and-packages">Virtual Environnement and packages</a></li>
+<li class="toctree-l3"><a class="reference internal" href="#activate-virtual-environnement-on-thonny-python-ide-on-rapberry-pi">Activate virtual environnement on Thonny (Python IDE)  (on Rapberry Pi)</a></li>
+</ul>
+</li>
+<li class="toctree-l2"><a class="reference internal" href="#step-n2-assembly-of-the-measurement-board"><strong>STEP n°2</strong>: Assembly of the measurement board</a><ul>
+<li class="toctree-l3"><a class="reference internal" href="#description">Description</a></li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+
+            
+          
+        </div>
+        
+      </div>
+    </nav>
+
+    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
+
+      
+      <nav class="wy-nav-top" aria-label="top navigation">
+        
+          <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
+          <a href="index.html">Ohmpi:</a>
+        
+      </nav>
+
+
+      <div class="wy-nav-content">
+        
+        <div class="rst-content">
+        
+          
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<div role="navigation" aria-label="breadcrumbs navigation">
+
+  <ul class="wy-breadcrumbs">
+    
+      <li><a href="index.html" class="icon icon-home"></a> &raquo;</li>
+        
+      <li>OhmPi V 2.00 (64 or 128 électrodes)</li>
+    
+    
+      <li class="wy-breadcrumbs-aside">
+        
+            
+            <a href="_sources/V2_00.rst.txt" rel="nofollow"> View page source</a>
+          
+        
+      </li>
+    
+  </ul>
+
+  
+  <hr/>
+</div>
+          <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
+           <div itemprop="articleBody">
+            
+  <section id="ohmpi-v-2-00-64-or-128-electrodes">
+<h1>OhmPi V 2.00 (64 or 128 électrodes)<a class="headerlink" href="#ohmpi-v-2-00-64-or-128-electrodes" title="Permalink to this headline">¶</a></h1>
+<figure class="align-center">
+<a class="reference internal image-reference" href="_images/Under-Construction.png"><img alt="Ohmpi 2" src="_images/Under-Construction.png" style="width: 500px; height: 250px;" /></a>
+</figure>
+<figure class="align-center">
+<a class="reference internal image-reference" href="_images/image_ohmpi_2.jpg"><img alt="Ohmpi 2" src="_images/image_ohmpi_2.jpg" style="width: 800px; height: 600px;" /></a>
+</figure>
+<div class="admonition note">
+<p class="admonition-title">Note</p>
+<p>In this version, we have developed two new board types that allow the assembly of Ohmpi v2.00, a measurement board and a multiplexer board.
+This new version is made up of:</p>
+<ol class="arabic simple">
+<li><p>A measurement board for four-point measurement</p></li>
+<li><p>4 multiplexer cards</p></li>
+<li><p>A box</p></li>
+</ol>
+</div>
+<section id="the-philosophy-of-ohmpi">
+<h2>The philosophy of Ohmpi<a class="headerlink" href="#the-philosophy-of-ohmpi" title="Permalink to this headline">¶</a></h2>
+<p>The philosophy of Ohmpi V2.00 is to offer a new DIY multielectrode resistivity meter. It is a resistivity meter with 64 electrodes , which can be upgraded to 128 electrodes.
+It is limited to low-current injection,but suitable for small laboratory experiments and small field time-lapse monitoring.
+Ohmpi, is developed by a team that seeks to share all its experience and wishes to improve and offer a more and more robust tool to the community.Ohmpi V2.00 is a completely different version from the previous one.
+We will stop the development on the previous version, to dedicate our efforts on this new version.</p>
+</section>
+<section id="technical-data">
+<h2>Technical data<a class="headerlink" href="#technical-data" title="Permalink to this headline">¶</a></h2>
+<table class="docutils align-default">
+<colgroup>
+<col style="width: 33%" />
+<col style="width: 22%" />
+<col style="width: 12%" />
+<col style="width: 22%" />
+<col style="width: 12%" />
+</colgroup>
+<tbody>
+<tr class="row-odd"><td><p><strong>Parameter</strong></p></td>
+<td><dl class="simple">
+<dt><strong>Specifications</strong></dt><dd><p><strong>V1</strong></p>
+</dd>
+</dl>
+</td>
+<td><p>Units</p></td>
+<td><dl class="simple">
+<dt><strong>Specifications</strong></dt><dd><p><strong>V2</strong></p>
+</dd>
+</dl>
+</td>
+<td><p>Units</p></td>
+</tr>
+<tr class="row-even"><td><p>Electrodes</p></td>
+<td><p>32</p></td>
+<td></td>
+<td><p>64 to 128</p></td>
+<td></td>
+</tr>
+<tr class="row-odd"><td><p>Operating temperature</p></td>
+<td><p>-0 to 50</p></td>
+<td><p>°c</p></td>
+<td><p>-25 to 50</p></td>
+<td><p>°c</p></td>
+</tr>
+<tr class="row-even"><td><p>Power consumption of CPU and
+control system</p></td>
+<td><p>18.5</p></td>
+<td><p>W</p></td>
+<td><p>18.5</p></td>
+<td><p>W</p></td>
+</tr>
+<tr class="row-odd"><td><p>Voltage injection</p></td>
+<td><p>12</p></td>
+<td><p>V</p></td>
+<td><p>12</p></td>
+<td><p>V</p></td>
+</tr>
+<tr class="row-even"><td><p>Battery</p></td>
+<td><p>9</p></td>
+<td><p>V</p></td>
+<td><p>12</p></td>
+<td><p>V</p></td>
+</tr>
+<tr class="row-odd"><td><p>Current</p></td>
+<td><p>0 to 40</p></td>
+<td><p>mA</p></td>
+<td><p>0 to 40</p></td>
+<td><p>mA</p></td>
+</tr>
+<tr class="row-even"><td><p>Min pulse duration</p></td>
+<td><p>150</p></td>
+<td><p>mS</p></td>
+<td><p>150</p></td>
+<td><p>mS</p></td>
+</tr>
+<tr class="row-odd"><td><p>Input impedance</p></td>
+<td><p>80</p></td>
+<td><p>Mohm</p></td>
+<td><p>80</p></td>
+<td><p>Mohm</p></td>
+</tr>
+<tr class="row-even"><td><p>Data storage</p></td>
+<td><p>micro SD card</p></td>
+<td></td>
+<td><p>micro SD card</p></td>
+<td></td>
+</tr>
+<tr class="row-odd"><td><p>Resolution</p></td>
+<td><p>O.O1</p></td>
+<td><p>ohm</p></td>
+<td><p>O.O1</p></td>
+<td><p>ohm</p></td>
+</tr>
+</tbody>
+</table>
+</section>
+<section id="step-n1-raspberry-pi-configuration">
+<h2><strong>STEP n°1</strong> : Raspberry Pi  configuration<a class="headerlink" href="#step-n1-raspberry-pi-configuration" title="Permalink to this headline">¶</a></h2>
+<section id="os-installation">
+<h3>OS installation<a class="headerlink" href="#os-installation" title="Permalink to this headline">¶</a></h3>
+<table class="docutils align-default">
+<colgroup>
+<col style="width: 78%" />
+<col style="width: 22%" />
+</colgroup>
+<tbody>
+<tr class="row-odd"><td><p><strong>Required components</strong></p></td>
+<td><p><strong>Quantity</strong></p></td>
+</tr>
+<tr class="row-even"><td><p>Raspberry Pi 4 Model B</p></td>
+<td><p>1</p></td>
+</tr>
+<tr class="row-odd"><td><p>Micro SD 32 Go</p></td>
+<td><p>1</p></td>
+</tr>
+<tr class="row-even"><td><p>HDMI Cable</p></td>
+<td><p>1</p></td>
+</tr>
+<tr class="row-odd"><td><p>Computer mouse</p></td>
+<td><p>1</p></td>
+</tr>
+<tr class="row-even"><td><p>Computer Keyboard</p></td>
+<td><p>1</p></td>
+</tr>
+</tbody>
+</table>
+<p>The first step is to start up the Raspberry Pi board, including installation of an OS (operating system).
+For this step, the installation instructions are well described on the Raspberry website</p>
+<ol class="arabic simple">
+<li><p>Watch the vidéo “how to set up your raspberry Pi” (<a class="reference external" href="https://www.youtube.com/watch?v=wjWZhV1v3Pk">https://www.youtube.com/watch?v=wjWZhV1v3Pk</a>)</p></li>
+<li><p>The authors recommend installing the latest stable and complete version of Raspbian by using NOOBS (a simple-to-use operating system installer).</p></li>
+<li><p>or you can visit this website : (<a class="reference external" href="https://projects.raspberrypi.org/en/projects/raspberry-pi-setting-up">https://projects.raspberrypi.org/en/projects/raspberry-pi-setting-up</a>)</p></li>
+</ol>
+<div class="admonition note">
+<p class="admonition-title">Note</p>
+<p>All the development tests were performed on Raspberry Pi 3 Model B, we used the following version of Raspbian:</p>
+<figure class="align-center">
+<a class="reference internal image-reference" href="_images/raspbian_version.jpg"><img alt="alternate text" src="_images/raspbian_version.jpg" style="width: 800px; height: 400px;" /></a>
+</figure>
+</div>
+<div class="admonition warning">
+<p class="admonition-title">Warning</p>
+<p>Once the OS has been installed,  <strong>1-wire, spi and GPIO remote option</strong> must be deactivated via the Raspbian GUI settings menu. Failure to carry out this task may cause damage to the relay shield cards during measurements.</p>
+</div>
+<p>3. When the relays are connected to the GPIO, make sure that all the GPIOs are in the low position when the raspberry starts up. If not, the relays will activate unexpectedly.
+To ensure that the GPIOs are in Low position, you will need to modify the /boot/config.txt file.</p>
+<blockquote>
+<div><p>Run the terminal, and write</p>
+<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">cd</span> <span class="o">/</span><span class="n">boot</span><span class="o">/</span>
+</pre></div>
+</div>
+</div></blockquote>
+<ol class="arabic simple" start="4">
+<li><p>Open config.txt with GNU nano editor</p></li>
+</ol>
+<blockquote>
+<div><div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">sudo</span> <span class="n">nano</span> <span class="n">config</span><span class="o">.</span><span class="n">txt</span>
+</pre></div>
+</div>
+</div></blockquote>
+<ol class="arabic simple" start="5">
+<li><p>At the end of the file write :</p></li>
+</ol>
+<blockquote>
+<div><div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">gpio</span><span class="o">=</span><span class="mi">8</span><span class="o">=</span><span class="n">op</span><span class="p">,</span><span class="n">dl</span>
+<span class="n">gpio</span><span class="o">=</span><span class="mi">7</span><span class="o">=</span><span class="n">op</span><span class="p">,</span><span class="n">dl</span>
+</pre></div>
+</div>
+</div></blockquote>
+<ol class="arabic simple" start="6">
+<li><p>Press Ctrl +O to save the modifications and press enter</p></li>
+<li><p>Press Ctrl +x to escap and return to the terminal</p></li>
+<li><p>Close the terminal</p></li>
+</ol>
+</section>
+<section id="virtual-environnement-and-packages">
+<h3>Virtual Environnement and packages<a class="headerlink" href="#virtual-environnement-and-packages" title="Permalink to this headline">¶</a></h3>
+<p>A virtual environment is a way to have multiple, parallel instances of the Python interpreter, each with different package sets and different configurations.
+Each virtual environment contains a discrete copy of the Python interpreter, including copies of its support utilities. It also protects your system in case of problems with the packages.</p>
+<p>All dependencies are specified in requirements.txt</p>
+<div class="admonition note">
+<p class="admonition-title">Note</p>
+<p>All instructions below should be typed in the terminal</p>
+</div>
+<p>It is first necessary to ensure that the libatlas-base-dev library is installed:</p>
+<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">sudo</span> <span class="n">apt</span><span class="o">-</span><span class="n">get</span> <span class="n">install</span> <span class="n">libatlas</span><span class="o">-</span><span class="n">base</span><span class="o">-</span><span class="n">dev</span>
+</pre></div>
+</div>
+<p>We strongly recommend users to create a virtual environment to run the code and installed all required dependencies. It can be done either in a directory gathering all virtual environments used on the computer or within the ohmpy directory.</p>
+<p>Create the virtual environment:</p>
+<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">python3</span> <span class="o">-</span><span class="n">m</span> <span class="n">venv</span> <span class="n">ohmpy</span>
+</pre></div>
+</div>
+<p>Activate it using the following command:</p>
+<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">source</span> <span class="n">ohmpy</span><span class="o">/</span><span class="nb">bin</span><span class="o">/</span><span class="n">activate</span>
+</pre></div>
+</div>
+<p>Install packages within the virtual environment. Installing the following package should be sufficient to meet dependencies:</p>
+<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">pip</span> <span class="n">install</span> <span class="n">RPi</span><span class="o">.</span><span class="n">GPIO</span> <span class="n">adafruit</span><span class="o">-</span><span class="n">blinka</span> <span class="n">numpy</span> <span class="n">adafruit</span><span class="o">-</span><span class="n">circuitpython</span><span class="o">-</span><span class="n">ads1x15</span> <span class="n">pandas</span>
+</pre></div>
+</div>
+<p>Check that requirements are met using</p>
+<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">pip</span> <span class="nb">list</span>
+</pre></div>
+</div>
+<p>You should run you code within the virtual environment
+to leave the virtual environment simply type:</p>
+<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">deactivate</span>
+</pre></div>
+</div>
+</section>
+<section id="activate-virtual-environnement-on-thonny-python-ide-on-rapberry-pi">
+<h3>Activate virtual environnement on Thonny (Python IDE)  (on Rapberry Pi)<a class="headerlink" href="#activate-virtual-environnement-on-thonny-python-ide-on-rapberry-pi" title="Permalink to this headline">¶</a></h3>
+<p>If you decided to use a virtual environment, it is necessary to setup Thonny Python IDE the first time you use it.</p>
+<p>1- Run the Thonny Python IDE software, Click on raspebrry acces <strong>menu &gt; programming&gt; Thonny pythonIDE</strong></p>
+<p>2- Thonny’s interface opens, Python runs on the Root (Python 3.7.3 (/usr/bin/python3))</p>
+<figure class="align-center">
+<a class="reference internal image-reference" href="_images/thonny_first_interface.jpg"><img alt="alternate text" src="_images/thonny_first_interface.jpg" style="width: 600px; height: 450px;" /></a>
+</figure>
+<p>3-Click on <strong>Run&gt;select interpreter</strong>, a new window opens click on interpret</p>
+<figure class="align-center">
+<a class="reference internal image-reference" href="_images/thonny_option.jpg"><img alt="alternate text" src="_images/thonny_option.jpg" style="width: 600px; height: 450px;" /></a>
+</figure>
+<p>4-On the new open windows select <strong>alternative Pyhton3 or virtual environnement</strong></p>
+<figure class="align-center">
+<a class="reference internal image-reference" href="_images/thonny_interpreter.jpg"><img alt="alternate text" src="_images/thonny_interpreter.jpg" style="width: 600px; height: 450px;" /></a>
+</figure>
+<p>5- New buttons appeared, selected <strong>“locate another python executable “</strong></p>
+<p>6- A new window opens, find the folder where there is the python 3 file in the virtual environment folder previously created <strong>/home/pi/ohmpi/bin/python3</strong>.</p>
+<p>7- In the <strong>known interpreter</strong> tab the path of the virtual environnementshould appear</p>
+<figure class="align-center">
+<a class="reference internal image-reference" href="_images/thonny_interpreter_folder.jpg"><img alt="alternate text" src="_images/thonny_interpreter_folder.jpg" style="width: 600px; height: 450px;" /></a>
+</figure>
+<p>8- Close the window by clicking on <strong>ok</strong>.</p>
+<p>9- Close thonny to save modifications</p>
+</section>
+</section>
+<section id="step-n2-assembly-of-the-measurement-board">
+<h2><strong>STEP n°2</strong>: Assembly of the measurement board<a class="headerlink" href="#step-n2-assembly-of-the-measurement-board" title="Permalink to this headline">¶</a></h2>
+<table class="docutils align-default">
+<colgroup>
+<col style="width: 100%" />
+</colgroup>
+<tbody>
+<tr class="row-odd"><td><p><strong>Required components</strong></p></td>
+</tr>
+</tbody>
+</table>
+<figure class="align-center">
+<a class="reference internal image-reference" href="_images/00_mes_board_components.jpg"><img alt="alternate text" src="_images/00_mes_board_components.jpg" style="width: 600px; height: 450px;" /></a>
+</figure>
+<section id="description">
+<h3>Description<a class="headerlink" href="#description" title="Permalink to this headline">¶</a></h3>
+<figure class="align-center">
+<a class="reference internal image-reference" href="_images/schema_measurement_board.jpg"><img alt="alternate text" src="_images/schema_measurement_board.jpg" style="width: 600px; height: 450px;" /></a>
+</figure>
+<p>Figure  shows the general diagram for the electronic measurement board developed.
+We have developed a complete measurement board. To measure electrical resistivity with Raspberry Pi, two ADS1115 were used,one for the voltage measurement one for the current measurement, as proposed by Florsch [7]. The ADS1115
+is a 16-bit ADC (Analog-to-Digital Converter), with an adaptable gain. The advantage of ADS1115 is that the
+input signal value could lie between - to + 6.114 V. Pour la mesure du current nous avons intégré directement le composant ina282, qui permet de réaliser des mesure de courant de précision autour d’une resistance de shunt</p>
+<table class="docutils align-center">
+<colgroup>
+<col style="width: 50%" />
+<col style="width: 50%" />
+</colgroup>
+<tbody>
+<tr class="row-odd"><td><img alt="_images/01_mes_board.jpg" src="_images/01_mes_board.jpg" />
+</td>
+<td></td>
+</tr>
+</tbody>
+</table>
+<table class="docutils align-center">
+<colgroup>
+<col style="width: 50%" />
+<col style="width: 50%" />
+</colgroup>
+<tbody>
+<tr class="row-odd"><td></td>
+<td><img alt="_images/02_mes_board.jpg" src="_images/02_mes_board.jpg" />
+</td>
+</tr>
+</tbody>
+</table>
+<table class="docutils align-center">
+<colgroup>
+<col style="width: 50%" />
+<col style="width: 50%" />
+</colgroup>
+<tbody>
+<tr class="row-odd"><td><img alt="_images/03_mes_board.jpg" src="_images/03_mes_board.jpg" />
+</td>
+<td></td>
+</tr>
+</tbody>
+</table>
+<table class="docutils align-center">
+<colgroup>
+<col style="width: 50%" />
+<col style="width: 50%" />
+</colgroup>
+<tbody>
+<tr class="row-odd"><td></td>
+<td><img alt="_images/04_mes_board.jpg" src="_images/04_mes_board.jpg" />
+</td>
+</tr>
+</tbody>
+</table>
+<table class="docutils align-center">
+<colgroup>
+<col style="width: 50%" />
+<col style="width: 50%" />
+</colgroup>
+<tbody>
+<tr class="row-odd"><td><img alt="_images/05_mes_board.jpg" src="_images/05_mes_board.jpg" />
+</td>
+<td></td>
+</tr>
+</tbody>
+</table>
+<table class="docutils align-center">
+<colgroup>
+<col style="width: 50%" />
+<col style="width: 50%" />
+</colgroup>
+<tbody>
+<tr class="row-odd"><td></td>
+<td><img alt="_images/06_mes_board.jpg" src="_images/06_mes_board.jpg" />
+</td>
+</tr>
+</tbody>
+</table>
+<table class="docutils align-center">
+<colgroup>
+<col style="width: 50%" />
+<col style="width: 50%" />
+</colgroup>
+<tbody>
+<tr class="row-odd"><td><img alt="_images/07_mes_board.jpg" src="_images/07_mes_board.jpg" />
+</td>
+<td></td>
+</tr>
+</tbody>
+</table>
+<table class="docutils align-center">
+<colgroup>
+<col style="width: 50%" />
+<col style="width: 50%" />
+</colgroup>
+<tbody>
+<tr class="row-odd"><td></td>
+<td><img alt="_images/08_mes_board.jpg" src="_images/08_mes_board.jpg" />
+</td>
+</tr>
+</tbody>
+</table>
+</section>
+</section>
+</section>
+
+
+           </div>
+           
+          </div>
+          <footer>
+  
+    <div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
+      
+      
+        <a href="V1_02.html" class="btn btn-neutral float-left" title="OhmPi V 1.02 (limited to 32 electrodes)" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left"></span> Previous</a>
+      
+    </div>
+  
+
+  <hr/>
+
+  <div role="contentinfo">
+    <p>
+        
+        &copy; Copyright 2020, INRAE, Rémi CLEMENT
+
+    </p>
+  </div>
+    
+    
+    
+    Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a
+    
+    <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a>
+    
+    provided by <a href="https://readthedocs.org">Read the Docs</a>. 
+
+</footer>
+
+        </div>
+      </div>
+
+    </section>
+
+  </div>
+  
+
+  <script type="text/javascript">
+      jQuery(function () {
+          SphinxRtdTheme.Navigation.enable(true);
+      });
+  </script>
+
+  
+  
+    
+   
+
+</body>
+</html>
\ No newline at end of file
diff --git a/public/_images/00_mes_board_components.jpg b/public/_images/00_mes_board_components.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..0aa99066a6382bf8fe09444a0e602e0e171a748c
Binary files /dev/null and b/public/_images/00_mes_board_components.jpg differ
diff --git a/public/_images/01_mes_board.jpg b/public/_images/01_mes_board.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..2baa894bd38ab71c7a2f03bfca10a382ce93a0b9
Binary files /dev/null and b/public/_images/01_mes_board.jpg differ
diff --git a/public/_images/02_mes_board.jpg b/public/_images/02_mes_board.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..fa737e27b5801333012abc9831195b5ae573139c
Binary files /dev/null and b/public/_images/02_mes_board.jpg differ
diff --git a/public/_images/03_mes_board.jpg b/public/_images/03_mes_board.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..41381d5341aed8952dab89fa31ed7c0303e50205
Binary files /dev/null and b/public/_images/03_mes_board.jpg differ
diff --git a/public/_images/04_mes_board.jpg b/public/_images/04_mes_board.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..988d238ad7fc61d9fb594467729879635deec63b
Binary files /dev/null and b/public/_images/04_mes_board.jpg differ
diff --git a/public/_images/05_mes_board.jpg b/public/_images/05_mes_board.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..a88db4242f13c04286aa763f6818252421aa6839
Binary files /dev/null and b/public/_images/05_mes_board.jpg differ
diff --git a/public/_images/06_mes_board.jpg b/public/_images/06_mes_board.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..94a903f0c942832b86d2f074b95ea5c65a58553b
Binary files /dev/null and b/public/_images/06_mes_board.jpg differ
diff --git a/public/_images/07_mes_board.jpg b/public/_images/07_mes_board.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..954aabf761288a96221d98914011a337cd6664ad
Binary files /dev/null and b/public/_images/07_mes_board.jpg differ
diff --git a/public/_images/08_mes_board.jpg b/public/_images/08_mes_board.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..645ed57a8f2c9118f57500a4aa575913770acdad
Binary files /dev/null and b/public/_images/08_mes_board.jpg differ
diff --git a/public/_images/Under-Construction.png b/public/_images/Under-Construction.png
new file mode 100644
index 0000000000000000000000000000000000000000..52b5e449c814895d1cf90a37e92152e96cf3548a
Binary files /dev/null and b/public/_images/Under-Construction.png differ
diff --git a/public/_images/image_ohmpi_2.jpg b/public/_images/image_ohmpi_2.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..d496aff74e226f6b0c683b983230273f7dd078ec
Binary files /dev/null and b/public/_images/image_ohmpi_2.jpg differ
diff --git a/public/_images/measurement_board_requirement.jpg b/public/_images/measurement_board_requirement.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..e011a8de2fb7801b07f29db11b0c7679b1dc680b
Binary files /dev/null and b/public/_images/measurement_board_requirement.jpg differ
diff --git a/public/_images/schema_measurement_board.jpg b/public/_images/schema_measurement_board.jpg
index 067f79537545338f96b3db86198f8ecbabb3e6e4..a4d73a9656272e18ec6a3341eba40956e568ae48 100644
Binary files a/public/_images/schema_measurement_board.jpg and b/public/_images/schema_measurement_board.jpg differ
diff --git a/public/_sources/V1_01.rst.txt b/public/_sources/V1_01.rst.txt
index ecec806040574eeb9978b35f6ab1f155e2dee0b6..d40b2a5e04e40cb7b9b234b654c0c4ba90c67eeb 100644
--- a/public/_sources/V1_01.rst.txt
+++ b/public/_sources/V1_01.rst.txt
@@ -5,7 +5,7 @@ OhmPi V 1.01 (limited to 32 electrodes)
 .. warning::
 	This version corresponds to the version published in the Hardware X journal.
 	However, we have corrected the bugs that existed on this version and explained the missing mounting points in detail below.
-	We invite you to refer to this document to assemble Ohmpi.
+	We invite you to refer to this document to assemble Ohmpi V1.01.
 	
 	
 
@@ -521,7 +521,7 @@ Complete list of components
 
 
 .. csv-table:: Table Title
-   :file: C:\Users\remi.clement\Documents\28_ohmpi_all_git\sphinx\source\list.csv
+   :file: C:\Users\remi.clement\Documents\28_ohmpi_all_git\master\sphinx\source\list.csv
    :widths: 30, 70, 70, 70, 70,70
    :header-rows: 1
 
diff --git a/public/_sources/V1_02.rst.txt b/public/_sources/V1_02.rst.txt
index 8bc01da4892f617a14194c87ecf17301d9b720c8..8de1fa10f904aff510a9a3217225d6589169367b 100644
--- a/public/_sources/V1_02.rst.txt
+++ b/public/_sources/V1_02.rst.txt
@@ -533,7 +533,7 @@ Complete list of components
 
 
 .. csv-table:: List of components
-   :file: C:\Users\remi.clement\Documents\28_ohmpi_all_git\sphinx\source\list - 1_02.csv
+   :file: C:\Users\remi.clement\Documents\28_ohmpi_all_git\master\sphinx\source\list - 1_02.csv
    :widths: 30, 70, 70, 70, 70,70
    :header-rows: 1
 
diff --git a/public/_sources/V2_00.rst.txt b/public/_sources/V2_00.rst.txt
new file mode 100644
index 0000000000000000000000000000000000000000..5740028e48f7848c117a3d44076a44865a3afc89
--- /dev/null
+++ b/public/_sources/V2_00.rst.txt
@@ -0,0 +1,323 @@
+*****************************************
+OhmPi V 2.00 (64 or 128 électrodes)
+***************************************** 
+
+.. figure:: Under-Construction.png
+	   :width: 500px
+	   :align: center
+	   :height: 250px
+	   :alt: Ohmpi 2
+	   :figclass: align-center
+
+.. figure:: image_ohmpi_2.jpg
+	   :width: 800px
+	   :align: center
+	   :height: 600px
+	   :alt: Ohmpi 2
+	   :figclass: align-center
+
+.. note::
+	 In this version, we have developed two new board types that allow the assembly of Ohmpi v2.00, a measurement board and a multiplexer board.
+	 This new version is made up of: 
+	 
+	 1. A measurement board for four-point measurement
+	 
+	 2. 4 multiplexer cards
+	 
+	 3. A box 
+
+The philosophy of Ohmpi 
+**************************
+The philosophy of Ohmpi V2.00 is to offer a new DIY multielectrode resistivity meter. It is a resistivity meter with 64 electrodes , which can be upgraded to 128 electrodes. 
+It is limited to low-current injection,but suitable for small laboratory experiments and small field time-lapse monitoring.
+Ohmpi, is developed by a team that seeks to share all its experience and wishes to improve and offer a more and more robust tool to the community.Ohmpi V2.00 is a completely different version from the previous one. 
+We will stop the development on the previous version, to dedicate our efforts on this new version. 
+
+Technical data
+***************
+
++-------------------------------+--------------------+-----------+--------------------+-----------+
+| **Parameter**                 | **Specifications** | Units     | **Specifications** | Units     |
+|                               |       **V1**       |           |       **V2**       |           |
++-------------------------------+--------------------+-----------+--------------------+-----------+
+|Electrodes                     |32                  |           |64 to 128           |           |
++-------------------------------+--------------------+-----------+--------------------+-----------+
+|Operating temperature          |-0 to 50            |°c         |-25 to 50           |°c         |
++-------------------------------+--------------------+-----------+--------------------+-----------+
+|Power consumption of CPU and   |18.5                |W          |18.5                |W          |              
+|control system                 |                    |           |                    |           |
++-------------------------------+--------------------+-----------+--------------------+-----------+
+|Voltage injection              |12                  |V          |12                  |V          |
++-------------------------------+--------------------+-----------+--------------------+-----------+
+|Battery                        |9                   |V          |12                  |V          |
++-------------------------------+--------------------+-----------+--------------------+-----------+
+|Current                        |0 to 40             |mA         |0 to 40             |mA         |
++-------------------------------+--------------------+-----------+--------------------+-----------+
+|Min pulse duration             |150                 |mS         |150                 |mS         |
++-------------------------------+--------------------+-----------+--------------------+-----------+
+|Input impedance                |80                  |Mohm       |80                  |Mohm       |
++-------------------------------+--------------------+-----------+--------------------+-----------+
+|Data storage                   |micro SD card       |           |micro SD card       |           |
++-------------------------------+--------------------+-----------+--------------------+-----------+
+|Resolution                     |O.O1                |ohm        |O.O1                |ohm        |
++-------------------------------+--------------------+-----------+--------------------+-----------+
+
+**STEP n°1** : Raspberry Pi  configuration
+*******************************************
+
+
+OS installation  
+================
+
++----------------------------------------------------+---------------+
+| **Required components**                            | **Quantity**  | 
++----------------------------------------------------+---------------+
+|Raspberry Pi 4 Model B                              |              1|
++----------------------------------------------------+---------------+
+|Micro SD 32 Go                                      |              1|
++----------------------------------------------------+---------------+
+|HDMI Cable                                          |              1|
++----------------------------------------------------+---------------+
+|Computer mouse                                      |              1|
++----------------------------------------------------+---------------+
+|Computer Keyboard                                   |              1|
++----------------------------------------------------+---------------+
+
+The first step is to start up the Raspberry Pi board, including installation of an OS (operating system). 
+For this step, the installation instructions are well described on the Raspberry website 
+
+1. Watch the vidéo "how to set up your raspberry Pi" (https://www.youtube.com/watch?v=wjWZhV1v3Pk)
+
+2. The authors recommend installing the latest stable and complete version of Raspbian by using NOOBS (a simple-to-use operating system installer).
+
+3. or you can visit this website : (https://projects.raspberrypi.org/en/projects/raspberry-pi-setting-up)  
+
+.. note:: 
+	 All the development tests were performed on Raspberry Pi 3 Model B, we used the following version of Raspbian:
+	 
+	 .. figure:: raspbian_version.jpg
+	   :width: 800px
+	   :align: center
+	   :height: 400px
+	   :alt: alternate text
+	   :figclass: align-center
+
+
+
+.. warning::
+	 Once the OS has been installed,  **1-wire, spi and GPIO remote option** must be deactivated via the Raspbian GUI settings menu. Failure to carry out this task may cause damage to the relay shield cards during measurements.
+
+3. When the relays are connected to the GPIO, make sure that all the GPIOs are in the low position when the raspberry starts up. If not, the relays will activate unexpectedly. 
+To ensure that the GPIOs are in Low position, you will need to modify the /boot/config.txt file.
+
+ Run the terminal, and write
+
+ .. code-block:: python
+
+	 cd /boot/
+
+4. Open config.txt with GNU nano editor
+
+ .. code-block:: python
+
+	 sudo nano config.txt
+
+5. At the end of the file write : 
+
+ .. code-block:: python
+	 
+	 gpio=8=op,dl
+	 gpio=7=op,dl
+
+6. Press Ctrl +O to save the modifications and press enter
+7. Press Ctrl +x to escap and return to the terminal
+8. Close the terminal
+
+
+Virtual Environnement and packages
+==================================
+
+A virtual environment is a way to have multiple, parallel instances of the Python interpreter, each with different package sets and different configurations. 
+Each virtual environment contains a discrete copy of the Python interpreter, including copies of its support utilities. It also protects your system in case of problems with the packages.
+
+All dependencies are specified in requirements.txt
+
+.. note:: 
+	 All instructions below should be typed in the terminal
+
+It is first necessary to ensure that the libatlas-base-dev library is installed:
+
+.. code-block:: python
+	
+	 sudo apt-get install libatlas-base-dev
+
+We strongly recommend users to create a virtual environment to run the code and installed all required dependencies. It can be done either in a directory gathering all virtual environments used on the computer or within the ohmpy directory.
+
+Create the virtual environment:
+
+.. code-block:: python
+	 
+	 python3 -m venv ohmpy
+
+Activate it using the following command:
+
+.. code-block:: python
+	 
+	 source ohmpy/bin/activate
+
+Install packages within the virtual environment. Installing the following package should be sufficient to meet dependencies:
+
+.. code-block:: python
+	 
+	 pip install RPi.GPIO adafruit-blinka numpy adafruit-circuitpython-ads1x15 pandas
+
+Check that requirements are met using 
+
+.. code-block:: python
+	 
+	 pip list
+
+You should run you code within the virtual environment
+to leave the virtual environment simply type:
+
+.. code-block:: python
+	  
+	 deactivate
+
+
+Activate virtual environnement on Thonny (Python IDE)  (on Rapberry Pi) 
+========================================================================
+
+If you decided to use a virtual environment, it is necessary to setup Thonny Python IDE the first time you use it.
+
+1- Run the Thonny Python IDE software, Click on raspebrry acces **menu > programming> Thonny pythonIDE**
+
+2- Thonny's interface opens, Python runs on the Root (Python 3.7.3 (/usr/bin/python3))
+
+.. figure:: thonny_first_interface.jpg
+	   :width: 600px
+	   :align: center
+	   :height: 450px
+	   :alt: alternate text
+	   :figclass: align-center
+
+3-Click on **Run>select interpreter**, a new window opens click on interpret
+
+.. figure:: thonny_option.jpg
+	   :width: 600px
+	   :align: center
+	   :height: 450px
+	   :alt: alternate text
+	   :figclass: align-center
+
+4-On the new open windows select **alternative Pyhton3 or virtual environnement**
+
+.. figure:: thonny_interpreter.jpg
+	   :width: 600px
+	   :align: center
+	   :height: 450px
+	   :alt: alternate text
+	   :figclass: align-center
+	   
+5- New buttons appeared, selected **"locate another python executable "**
+
+6- A new window opens, find the folder where there is the python 3 file in the virtual environment folder previously created **/home/pi/ohmpi/bin/python3**.
+
+7- In the **known interpreter** tab the path of the virtual environnementshould appear
+
+.. figure:: thonny_interpreter_folder.jpg
+	   :width: 600px
+	   :align: center
+	   :height: 450px
+	   :alt: alternate text
+	   :figclass: align-center 
+
+8- Close the window by clicking on **ok**.
+
+9- Close thonny to save modifications
+
+ 
+**STEP n°2**: Assembly of the measurement board
+****************************************************
+
++----------------------------------------------------+
+| **Required components**                            | 
++----------------------------------------------------+
+
+.. figure:: mesure/00_mes_board_components.jpg       
+	   :width: 600px
+	   :align: center
+	   :height: 450px
+	   :alt: alternate text
+	   :figclass: align-center 
+
+
+Description
+==========================================
+
+
+.. figure:: schema_measurement_board.jpg       
+	   :width: 600px
+	   :align: center
+	   :height: 450px
+	   :alt: alternate text
+	   :figclass: align-center 
+
+Figure  shows the general diagram for the electronic measurement board developed.
+We have developed a complete measurement board. To measure electrical resistivity with Raspberry Pi, two ADS1115 were used,one for the voltage measurement one for the current measurement, as proposed by Florsch [7]. The ADS1115
+is a 16-bit ADC (Analog-to-Digital Converter), with an adaptable gain. The advantage of ADS1115 is that the 
+input signal value could lie between - to + 6.114 V. Pour la mesure du current nous avons intégré directement le composant ina282, qui permet de réaliser des mesure de courant de précision autour d'une resistance de shunt 
+
+.. table::
+   :align: center
+  
+   +---------------------------------------+---------------------------------------+
+   |   .. image:: mesure/01_mes_board.jpg  |                                       |
+   +---------------------------------------+---------------------------------------+
+   
+.. table::
+   :align: center
+  
+   +---------------------------------------+---------------------------------------+
+   |                                       |    .. image:: mesure/02_mes_board.jpg |
+   +---------------------------------------+---------------------------------------+
+.. table::
+   :align: center
+  
+   +---------------------------------------+---------------------------------------+
+   |   .. image:: mesure/03_mes_board.jpg  |                                       |
+   +---------------------------------------+---------------------------------------+
+   
+.. table::
+   :align: center
+  
+   +---------------------------------------+---------------------------------------+
+   |                                       |    .. image:: mesure/04_mes_board.jpg |
+   +---------------------------------------+---------------------------------------+  
+.. table::
+   :align: center
+  
+   +---------------------------------------+---------------------------------------+
+   |   .. image:: mesure/05_mes_board.jpg  |                                       |
+   +---------------------------------------+---------------------------------------+
+   
+.. table::
+   :align: center
+  
+   +---------------------------------------+---------------------------------------+
+   |                                       |    .. image:: mesure/06_mes_board.jpg |
+   +---------------------------------------+---------------------------------------+  
+
+.. table::
+   :align: center
+  
+   +---------------------------------------+---------------------------------------+
+   |   .. image:: mesure/07_mes_board.jpg  |                                       |
+   +---------------------------------------+---------------------------------------+
+   
+.. table::
+   :align: center
+  
+   +---------------------------------------+---------------------------------------+
+   |                                       |    .. image:: mesure/08_mes_board.jpg |
+   +---------------------------------------+---------------------------------------+     
diff --git a/public/_static/basic.css b/public/_static/basic.css
index 56f5efc61ec4910592264c70ea1ae538fa83522d..912859b55d96750bff001bb79037a83a6c02332c 100644
--- a/public/_static/basic.css
+++ b/public/_static/basic.css
@@ -4,7 +4,7 @@
  *
  * Sphinx stylesheet -- basic theme.
  *
- * :copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
+ * :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
  * :license: BSD, see LICENSE for details.
  *
  */
@@ -15,6 +15,12 @@ div.clearer {
     clear: both;
 }
 
+div.section::after {
+    display: block;
+    content: '';
+    clear: left;
+}
+
 /* -- relbar ---------------------------------------------------------------- */
 
 div.related {
@@ -124,7 +130,7 @@ ul.search li a {
     font-weight: bold;
 }
 
-ul.search li div.context {
+ul.search li p.context {
     color: #888;
     margin: 2px 0 0 30px;
     text-align: left;
@@ -271,25 +277,25 @@ p.rubric {
     font-weight: bold;
 }
 
-img.align-left, .figure.align-left, object.align-left {
+img.align-left, figure.align-left, .figure.align-left, object.align-left {
     clear: left;
     float: left;
     margin-right: 1em;
 }
 
-img.align-right, .figure.align-right, object.align-right {
+img.align-right, figure.align-right, .figure.align-right, object.align-right {
     clear: right;
     float: right;
     margin-left: 1em;
 }
 
-img.align-center, .figure.align-center, object.align-center {
+img.align-center, figure.align-center, .figure.align-center, object.align-center {
   display: block;
   margin-left: auto;
   margin-right: auto;
 }
 
-img.align-default, .figure.align-default {
+img.align-default, figure.align-default, .figure.align-default {
   display: block;
   margin-left: auto;
   margin-right: auto;
@@ -313,7 +319,8 @@ img.align-default, .figure.align-default {
 
 /* -- sidebars -------------------------------------------------------------- */
 
-div.sidebar {
+div.sidebar,
+aside.sidebar {
     margin: 0 0 0.5em 1em;
     border: 1px solid #ddb;
     padding: 7px;
@@ -328,8 +335,8 @@ p.sidebar-title {
     font-weight: bold;
 }
 
-div.admonition, div.topic, pre, div[class|="highlight"] {
-    clear: both;
+div.admonition, div.topic, blockquote {
+    clear: left;
 }
 
 /* -- topics ---------------------------------------------------------------- */
@@ -338,7 +345,6 @@ div.topic {
     border: 1px solid #ccc;
     padding: 7px;
     margin: 10px 0 10px 0;
-    overflow-x: auto;
 }
 
 p.topic-title {
@@ -353,7 +359,6 @@ div.admonition {
     margin-top: 10px;
     margin-bottom: 10px;
     padding: 7px;
-    overflow-x: auto;
 }
 
 div.admonition dt {
@@ -373,11 +378,22 @@ div.body p.centered {
 /* -- content of sidebars/topics/admonitions -------------------------------- */
 
 div.sidebar > :last-child,
+aside.sidebar > :last-child,
 div.topic > :last-child,
 div.admonition > :last-child {
     margin-bottom: 0;
 }
 
+div.sidebar::after,
+aside.sidebar::after,
+div.topic::after,
+div.admonition::after,
+blockquote::after {
+    display: block;
+    content: '';
+    clear: both;
+}
+
 /* -- tables ---------------------------------------------------------------- */
 
 table.docutils {
@@ -442,20 +458,22 @@ td > :last-child {
 
 /* -- figures --------------------------------------------------------------- */
 
-div.figure {
+div.figure, figure {
     margin: 0.5em;
     padding: 0.5em;
 }
 
-div.figure p.caption {
+div.figure p.caption, figcaption {
     padding: 0.3em;
 }
 
-div.figure p.caption span.caption-number {
+div.figure p.caption span.caption-number,
+figcaption span.caption-number {
     font-style: italic;
 }
 
-div.figure p.caption span.caption-text {
+div.figure p.caption span.caption-text,
+figcaption span.caption-text {
 }
 
 /* -- field list styles ----------------------------------------------------- */
@@ -490,6 +508,63 @@ table.hlist td {
     vertical-align: top;
 }
 
+/* -- object description styles --------------------------------------------- */
+
+.sig {
+	font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
+}
+
+.sig-name, code.descname {
+    background-color: transparent;
+    font-weight: bold;
+}
+
+.sig-name {
+	font-size: 1.1em;
+}
+
+code.descname {
+    font-size: 1.2em;
+}
+
+.sig-prename, code.descclassname {
+    background-color: transparent;
+}
+
+.optional {
+    font-size: 1.3em;
+}
+
+.sig-paren {
+    font-size: larger;
+}
+
+.sig-param.n {
+	font-style: italic;
+}
+
+/* C++ specific styling */
+
+.sig-inline.c-texpr,
+.sig-inline.cpp-texpr {
+	font-family: unset;
+}
+
+.sig.c   .k, .sig.c   .kt,
+.sig.cpp .k, .sig.cpp .kt {
+	color: #0033B3;
+}
+
+.sig.c   .m,
+.sig.cpp .m {
+	color: #1750EB;
+}
+
+.sig.c   .s, .sig.c   .sc,
+.sig.cpp .s, .sig.cpp .sc {
+	color: #067D17;
+}
+
 
 /* -- other body styles ----------------------------------------------------- */
 
@@ -513,28 +588,31 @@ ol.upperroman {
     list-style: upper-roman;
 }
 
-ol > li:first-child > :first-child,
-ul > li:first-child > :first-child {
+:not(li) > ol > li:first-child > :first-child,
+:not(li) > ul > li:first-child > :first-child {
     margin-top: 0px;
 }
 
-ol ol > li:first-child > :first-child,
-ol ul > li:first-child > :first-child,
-ul ol > li:first-child > :first-child,
-ul ul > li:first-child > :first-child {
-    margin-top: revert;
+:not(li) > ol > li:last-child > :last-child,
+:not(li) > ul > li:last-child > :last-child {
+    margin-bottom: 0px;
 }
 
-ol > li:last-child > :last-child,
-ul > li:last-child > :last-child {
-    margin-bottom: 0px;
+ol.simple ol p,
+ol.simple ul p,
+ul.simple ol p,
+ul.simple ul p {
+    margin-top: 0;
 }
 
-ol ol > li:last-child > :last-child,
-ol ul > li:last-child > :last-child,
-ul ol > li:last-child > :last-child,
-ul ul > li:last-child > :last-child {
-    margin-bottom: revert;
+ol.simple > li:not(:first-child) > p,
+ul.simple > li:not(:first-child) > p {
+    margin-top: 0;
+}
+
+ol.simple p,
+ul.simple p {
+    margin-bottom: 0;
 }
 
 dl.footnote > dt,
@@ -613,14 +691,6 @@ dl.glossary dt {
     font-size: 1.1em;
 }
 
-.optional {
-    font-size: 1.3em;
-}
-
-.sig-paren {
-    font-size: larger;
-}
-
 .versionmodified {
     font-style: italic;
 }
@@ -677,6 +747,10 @@ pre {
     overflow-y: hidden;  /* fixes display issues on Chrome browsers */
 }
 
+pre, div[class*="highlight-"] {
+    clear: both;
+}
+
 span.pre {
     -moz-hyphens: none;
     -ms-hyphens: none;
@@ -684,7 +758,7 @@ span.pre {
     hyphens: none;
 }
 
-div[class^="highlight-"] {
+div[class*="highlight-"] {
     margin: 1em 0;
 }
 
@@ -744,8 +818,13 @@ div.code-block-caption code {
 }
 
 table.highlighttable td.linenos,
-div.doctest > div.highlight span.gp {  /* gp: Generic.Prompt */
-    user-select: none;
+span.linenos,
+div.highlight span.gp {  /* gp: Generic.Prompt */
+  user-select: none;
+  -webkit-user-select: text; /* Safari fallback only */
+  -webkit-user-select: none; /* Chrome/Safari */
+  -moz-user-select: none; /* Firefox */
+  -ms-user-select: none; /* IE10+ */
 }
 
 div.code-block-caption span.caption-number {
@@ -760,16 +839,6 @@ div.literal-block-wrapper {
     margin: 1em 0;
 }
 
-code.descname {
-    background-color: transparent;
-    font-weight: bold;
-    font-size: 1.2em;
-}
-
-code.descclassname {
-    background-color: transparent;
-}
-
 code.xref, a code {
     background-color: transparent;
     font-weight: bold;
diff --git a/public/_static/doctools.js b/public/_static/doctools.js
index daccd209dab05a75f5627390e37a6b764e93f547..8cbf1b161a6527c8c6ad1c4f1fdc156e065ab262 100644
--- a/public/_static/doctools.js
+++ b/public/_static/doctools.js
@@ -4,7 +4,7 @@
  *
  * Sphinx JavaScript utilities for all documentation.
  *
- * :copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
+ * :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
  * :license: BSD, see LICENSE for details.
  *
  */
@@ -29,9 +29,14 @@ if (!window.console || !console.firebug) {
 
 /**
  * small helper function to urldecode strings
+ *
+ * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL
  */
 jQuery.urldecode = function(x) {
-  return decodeURIComponent(x).replace(/\+/g, ' ');
+  if (!x) {
+    return x
+  }
+  return decodeURIComponent(x.replace(/\+/g, ' '));
 };
 
 /**
@@ -285,9 +290,10 @@ var Documentation = {
   initOnKeyListeners: function() {
     $(document).keydown(function(event) {
       var activeElementType = document.activeElement.tagName;
-      // don't navigate when in search box or textarea
+      // don't navigate when in search box, textarea, dropdown or button
       if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT'
-          && !event.altKey && !event.ctrlKey && !event.metaKey && !event.shiftKey) {
+          && activeElementType !== 'BUTTON' && !event.altKey && !event.ctrlKey && !event.metaKey
+          && !event.shiftKey) {
         switch (event.keyCode) {
           case 37: // left
             var prevHref = $('link[rel="prev"]').prop('href');
@@ -295,12 +301,14 @@ var Documentation = {
               window.location.href = prevHref;
               return false;
             }
+            break;
           case 39: // right
             var nextHref = $('link[rel="next"]').prop('href');
             if (nextHref) {
               window.location.href = nextHref;
               return false;
             }
+            break;
         }
       }
     });
diff --git a/public/_static/language_data.js b/public/_static/language_data.js
index d2b4ee91b0da7308cf5693804779c7b18c26252a..863704b310d1539241ef20e26ccce6af27f0ffce 100644
--- a/public/_static/language_data.js
+++ b/public/_static/language_data.js
@@ -5,7 +5,7 @@
  * This script contains the language-specific data used by searchtools.js,
  * namely the list of stopwords, stemmer, scorer and splitter.
  *
- * :copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
+ * :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
  * :license: BSD, see LICENSE for details.
  *
  */
@@ -13,7 +13,8 @@
 var stopwords = ["a","and","are","as","at","be","but","by","for","if","in","into","is","it","near","no","not","of","on","or","such","that","the","their","then","there","these","they","this","to","was","will","with"];
 
 
-/* Non-minified version JS is _stemmer.js if file is provided */ 
+/* Non-minified version is copied as a separate JS file, is available */
+
 /**
  * Porter Stemmer
  */
@@ -199,7 +200,6 @@ var Stemmer = function() {
 
 
 
-
 var splitChars = (function() {
     var result = {};
     var singles = [96, 180, 187, 191, 215, 247, 749, 885, 903, 907, 909, 930, 1014, 1648,
diff --git a/public/_static/pygments.css b/public/_static/pygments.css
index 631bc92ffa57bc202c1dac78d96bbeaea624571e..582d5c3adaddbab2178a4e1ea270afe51e5437d2 100644
--- a/public/_static/pygments.css
+++ b/public/_static/pygments.css
@@ -1,5 +1,10 @@
+pre { line-height: 125%; }
+td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
+span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
+td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
+span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
 .highlight .hll { background-color: #ffffcc }
-.highlight  { background: #f8f8f8; }
+.highlight { background: #f8f8f8; }
 .highlight .c { color: #408080; font-style: italic } /* Comment */
 .highlight .err { border: 1px solid #FF0000 } /* Error */
 .highlight .k { color: #008000; font-weight: bold } /* Keyword */
diff --git a/public/_static/searchtools.js b/public/_static/searchtools.js
index ab56499655111429619df63a1dc6687646d22a3e..8eb14218b5a6f434c93949dabf10df694d392876 100644
--- a/public/_static/searchtools.js
+++ b/public/_static/searchtools.js
@@ -4,7 +4,7 @@
  *
  * Sphinx JavaScript utilities for the full-text search.
  *
- * :copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
+ * :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
  * :license: BSD, see LICENSE for details.
  *
  */
@@ -59,10 +59,10 @@ var Search = {
   _pulse_status : -1,
 
   htmlToText : function(htmlString) {
-      var htmlElement = document.createElement('span');
-      htmlElement.innerHTML = htmlString;
-      $(htmlElement).find('.headerlink').remove();
-      docContent = $(htmlElement).find('[role=main]')[0];
+      var virtualDocument = document.implementation.createHTMLDocument('virtual');
+      var htmlElement = $(htmlString, virtualDocument);
+      htmlElement.find('.headerlink').remove();
+      docContent = htmlElement.find('[role=main]')[0];
       if(docContent === undefined) {
           console.warn("Content block not found. Sphinx search tries to obtain it " +
                        "via '[role=main]'. Could you check your theme or template.");
@@ -166,8 +166,7 @@ var Search = {
           objectterms.push(tmp[i].toLowerCase());
       }
 
-      if ($u.indexOf(stopwords, tmp[i].toLowerCase()) != -1 || tmp[i].match(/^\d+$/) ||
-          tmp[i] === "") {
+      if ($u.indexOf(stopwords, tmp[i].toLowerCase()) != -1 || tmp[i] === "") {
         // skip this "word"
         continue;
       }
@@ -249,7 +248,7 @@ var Search = {
       // results left, load the summary and display it
       if (results.length) {
         var item = results.pop();
-        var listItem = $('<li style="display:none"></li>');
+        var listItem = $('<li></li>');
         var requestUrl = "";
         var linkUrl = "";
         if (DOCUMENTATION_OPTIONS.BUILDER === 'dirhtml') {
@@ -274,10 +273,10 @@ var Search = {
         if (item[3]) {
           listItem.append($('<span> (' + item[3] + ')</span>'));
           Search.output.append(listItem);
-          listItem.slideDown(5, function() {
+          setTimeout(function() {
             displayNextItem();
-          });
-        } else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) {
+          }, 5);
+        } else {
           $.ajax({url: requestUrl,
                   dataType: "text",
                   complete: function(jqxhr, textstatus) {
@@ -286,16 +285,10 @@ var Search = {
                       listItem.append(Search.makeSearchSummary(data, searchterms, hlterms));
                     }
                     Search.output.append(listItem);
-                    listItem.slideDown(5, function() {
+                    setTimeout(function() {
                       displayNextItem();
-                    });
+                    }, 5);
                   }});
-        } else {
-          // no source available, just display title
-          Search.output.append(listItem);
-          listItem.slideDown(5, function() {
-            displayNextItem();
-          });
         }
       }
       // search finished, update title and status message
@@ -380,6 +373,13 @@ var Search = {
     return results;
   },
 
+  /**
+   * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions
+   */
+  escapeRegExp : function(string) {
+    return string.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
+  },
+
   /**
    * search for full-text terms in the index
    */
@@ -403,13 +403,14 @@ var Search = {
       ];
       // add support for partial matches
       if (word.length > 2) {
+        var word_regex = this.escapeRegExp(word);
         for (var w in terms) {
-          if (w.match(word) && !terms[word]) {
+          if (w.match(word_regex) && !terms[word]) {
             _o.push({files: terms[w], score: Scorer.partialTerm})
           }
         }
         for (var w in titleterms) {
-          if (w.match(word) && !titleterms[word]) {
+          if (w.match(word_regex) && !titleterms[word]) {
               _o.push({files: titleterms[w], score: Scorer.partialTitle})
           }
         }
@@ -502,7 +503,7 @@ var Search = {
     var excerpt = ((start > 0) ? '...' : '') +
       $.trim(text.substr(start, 240)) +
       ((start + 240 - text.length) ? '...' : '');
-    var rv = $('<div class="context"></div>').text(excerpt);
+    var rv = $('<p class="context"></p>').text(excerpt);
     $.each(hlwords, function() {
       rv = rv.highlightText(this, 'highlighted');
     });
diff --git a/public/_static/underscore-1.13.1.js b/public/_static/underscore-1.13.1.js
new file mode 100644
index 0000000000000000000000000000000000000000..ffd77af9648a47d389f2d6976d4aa1c44d7ce7ce
--- /dev/null
+++ b/public/_static/underscore-1.13.1.js
@@ -0,0 +1,2042 @@
+(function (global, factory) {
+  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+  typeof define === 'function' && define.amd ? define('underscore', factory) :
+  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, (function () {
+    var current = global._;
+    var exports = global._ = factory();
+    exports.noConflict = function () { global._ = current; return exports; };
+  }()));
+}(this, (function () {
+  //     Underscore.js 1.13.1
+  //     https://underscorejs.org
+  //     (c) 2009-2021 Jeremy Ashkenas, Julian Gonggrijp, and DocumentCloud and Investigative Reporters & Editors
+  //     Underscore may be freely distributed under the MIT license.
+
+  // Current version.
+  var VERSION = '1.13.1';
+
+  // Establish the root object, `window` (`self`) in the browser, `global`
+  // on the server, or `this` in some virtual machines. We use `self`
+  // instead of `window` for `WebWorker` support.
+  var root = typeof self == 'object' && self.self === self && self ||
+            typeof global == 'object' && global.global === global && global ||
+            Function('return this')() ||
+            {};
+
+  // Save bytes in the minified (but not gzipped) version:
+  var ArrayProto = Array.prototype, ObjProto = Object.prototype;
+  var SymbolProto = typeof Symbol !== 'undefined' ? Symbol.prototype : null;
+
+  // Create quick reference variables for speed access to core prototypes.
+  var push = ArrayProto.push,
+      slice = ArrayProto.slice,
+      toString = ObjProto.toString,
+      hasOwnProperty = ObjProto.hasOwnProperty;
+
+  // Modern feature detection.
+  var supportsArrayBuffer = typeof ArrayBuffer !== 'undefined',
+      supportsDataView = typeof DataView !== 'undefined';
+
+  // All **ECMAScript 5+** native function implementations that we hope to use
+  // are declared here.
+  var nativeIsArray = Array.isArray,
+      nativeKeys = Object.keys,
+      nativeCreate = Object.create,
+      nativeIsView = supportsArrayBuffer && ArrayBuffer.isView;
+
+  // Create references to these builtin functions because we override them.
+  var _isNaN = isNaN,
+      _isFinite = isFinite;
+
+  // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed.
+  var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString');
+  var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString',
+    'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];
+
+  // The largest integer that can be represented exactly.
+  var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1;
+
+  // Some functions take a variable number of arguments, or a few expected
+  // arguments at the beginning and then a variable number of values to operate
+  // on. This helper accumulates all remaining arguments past the function’s
+  // argument length (or an explicit `startIndex`), into an array that becomes
+  // the last argument. Similar to ES6’s "rest parameter".
+  function restArguments(func, startIndex) {
+    startIndex = startIndex == null ? func.length - 1 : +startIndex;
+    return function() {
+      var length = Math.max(arguments.length - startIndex, 0),
+          rest = Array(length),
+          index = 0;
+      for (; index < length; index++) {
+        rest[index] = arguments[index + startIndex];
+      }
+      switch (startIndex) {
+        case 0: return func.call(this, rest);
+        case 1: return func.call(this, arguments[0], rest);
+        case 2: return func.call(this, arguments[0], arguments[1], rest);
+      }
+      var args = Array(startIndex + 1);
+      for (index = 0; index < startIndex; index++) {
+        args[index] = arguments[index];
+      }
+      args[startIndex] = rest;
+      return func.apply(this, args);
+    };
+  }
+
+  // Is a given variable an object?
+  function isObject(obj) {
+    var type = typeof obj;
+    return type === 'function' || type === 'object' && !!obj;
+  }
+
+  // Is a given value equal to null?
+  function isNull(obj) {
+    return obj === null;
+  }
+
+  // Is a given variable undefined?
+  function isUndefined(obj) {
+    return obj === void 0;
+  }
+
+  // Is a given value a boolean?
+  function isBoolean(obj) {
+    return obj === true || obj === false || toString.call(obj) === '[object Boolean]';
+  }
+
+  // Is a given value a DOM element?
+  function isElement(obj) {
+    return !!(obj && obj.nodeType === 1);
+  }
+
+  // Internal function for creating a `toString`-based type tester.
+  function tagTester(name) {
+    var tag = '[object ' + name + ']';
+    return function(obj) {
+      return toString.call(obj) === tag;
+    };
+  }
+
+  var isString = tagTester('String');
+
+  var isNumber = tagTester('Number');
+
+  var isDate = tagTester('Date');
+
+  var isRegExp = tagTester('RegExp');
+
+  var isError = tagTester('Error');
+
+  var isSymbol = tagTester('Symbol');
+
+  var isArrayBuffer = tagTester('ArrayBuffer');
+
+  var isFunction = tagTester('Function');
+
+  // Optimize `isFunction` if appropriate. Work around some `typeof` bugs in old
+  // v8, IE 11 (#1621), Safari 8 (#1929), and PhantomJS (#2236).
+  var nodelist = root.document && root.document.childNodes;
+  if (typeof /./ != 'function' && typeof Int8Array != 'object' && typeof nodelist != 'function') {
+    isFunction = function(obj) {
+      return typeof obj == 'function' || false;
+    };
+  }
+
+  var isFunction$1 = isFunction;
+
+  var hasObjectTag = tagTester('Object');
+
+  // In IE 10 - Edge 13, `DataView` has string tag `'[object Object]'`.
+  // In IE 11, the most common among them, this problem also applies to
+  // `Map`, `WeakMap` and `Set`.
+  var hasStringTagBug = (
+        supportsDataView && hasObjectTag(new DataView(new ArrayBuffer(8)))
+      ),
+      isIE11 = (typeof Map !== 'undefined' && hasObjectTag(new Map));
+
+  var isDataView = tagTester('DataView');
+
+  // In IE 10 - Edge 13, we need a different heuristic
+  // to determine whether an object is a `DataView`.
+  function ie10IsDataView(obj) {
+    return obj != null && isFunction$1(obj.getInt8) && isArrayBuffer(obj.buffer);
+  }
+
+  var isDataView$1 = (hasStringTagBug ? ie10IsDataView : isDataView);
+
+  // Is a given value an array?
+  // Delegates to ECMA5's native `Array.isArray`.
+  var isArray = nativeIsArray || tagTester('Array');
+
+  // Internal function to check whether `key` is an own property name of `obj`.
+  function has$1(obj, key) {
+    return obj != null && hasOwnProperty.call(obj, key);
+  }
+
+  var isArguments = tagTester('Arguments');
+
+  // Define a fallback version of the method in browsers (ahem, IE < 9), where
+  // there isn't any inspectable "Arguments" type.
+  (function() {
+    if (!isArguments(arguments)) {
+      isArguments = function(obj) {
+        return has$1(obj, 'callee');
+      };
+    }
+  }());
+
+  var isArguments$1 = isArguments;
+
+  // Is a given object a finite number?
+  function isFinite$1(obj) {
+    return !isSymbol(obj) && _isFinite(obj) && !isNaN(parseFloat(obj));
+  }
+
+  // Is the given value `NaN`?
+  function isNaN$1(obj) {
+    return isNumber(obj) && _isNaN(obj);
+  }
+
+  // Predicate-generating function. Often useful outside of Underscore.
+  function constant(value) {
+    return function() {
+      return value;
+    };
+  }
+
+  // Common internal logic for `isArrayLike` and `isBufferLike`.
+  function createSizePropertyCheck(getSizeProperty) {
+    return function(collection) {
+      var sizeProperty = getSizeProperty(collection);
+      return typeof sizeProperty == 'number' && sizeProperty >= 0 && sizeProperty <= MAX_ARRAY_INDEX;
+    }
+  }
+
+  // Internal helper to generate a function to obtain property `key` from `obj`.
+  function shallowProperty(key) {
+    return function(obj) {
+      return obj == null ? void 0 : obj[key];
+    };
+  }
+
+  // Internal helper to obtain the `byteLength` property of an object.
+  var getByteLength = shallowProperty('byteLength');
+
+  // Internal helper to determine whether we should spend extensive checks against
+  // `ArrayBuffer` et al.
+  var isBufferLike = createSizePropertyCheck(getByteLength);
+
+  // Is a given value a typed array?
+  var typedArrayPattern = /\[object ((I|Ui)nt(8|16|32)|Float(32|64)|Uint8Clamped|Big(I|Ui)nt64)Array\]/;
+  function isTypedArray(obj) {
+    // `ArrayBuffer.isView` is the most future-proof, so use it when available.
+    // Otherwise, fall back on the above regular expression.
+    return nativeIsView ? (nativeIsView(obj) && !isDataView$1(obj)) :
+                  isBufferLike(obj) && typedArrayPattern.test(toString.call(obj));
+  }
+
+  var isTypedArray$1 = supportsArrayBuffer ? isTypedArray : constant(false);
+
+  // Internal helper to obtain the `length` property of an object.
+  var getLength = shallowProperty('length');
+
+  // Internal helper to create a simple lookup structure.
+  // `collectNonEnumProps` used to depend on `_.contains`, but this led to
+  // circular imports. `emulatedSet` is a one-off solution that only works for
+  // arrays of strings.
+  function emulatedSet(keys) {
+    var hash = {};
+    for (var l = keys.length, i = 0; i < l; ++i) hash[keys[i]] = true;
+    return {
+      contains: function(key) { return hash[key]; },
+      push: function(key) {
+        hash[key] = true;
+        return keys.push(key);
+      }
+    };
+  }
+
+  // Internal helper. Checks `keys` for the presence of keys in IE < 9 that won't
+  // be iterated by `for key in ...` and thus missed. Extends `keys` in place if
+  // needed.
+  function collectNonEnumProps(obj, keys) {
+    keys = emulatedSet(keys);
+    var nonEnumIdx = nonEnumerableProps.length;
+    var constructor = obj.constructor;
+    var proto = isFunction$1(constructor) && constructor.prototype || ObjProto;
+
+    // Constructor is a special case.
+    var prop = 'constructor';
+    if (has$1(obj, prop) && !keys.contains(prop)) keys.push(prop);
+
+    while (nonEnumIdx--) {
+      prop = nonEnumerableProps[nonEnumIdx];
+      if (prop in obj && obj[prop] !== proto[prop] && !keys.contains(prop)) {
+        keys.push(prop);
+      }
+    }
+  }
+
+  // Retrieve the names of an object's own properties.
+  // Delegates to **ECMAScript 5**'s native `Object.keys`.
+  function keys(obj) {
+    if (!isObject(obj)) return [];
+    if (nativeKeys) return nativeKeys(obj);
+    var keys = [];
+    for (var key in obj) if (has$1(obj, key)) keys.push(key);
+    // Ahem, IE < 9.
+    if (hasEnumBug) collectNonEnumProps(obj, keys);
+    return keys;
+  }
+
+  // Is a given array, string, or object empty?
+  // An "empty" object has no enumerable own-properties.
+  function isEmpty(obj) {
+    if (obj == null) return true;
+    // Skip the more expensive `toString`-based type checks if `obj` has no
+    // `.length`.
+    var length = getLength(obj);
+    if (typeof length == 'number' && (
+      isArray(obj) || isString(obj) || isArguments$1(obj)
+    )) return length === 0;
+    return getLength(keys(obj)) === 0;
+  }
+
+  // Returns whether an object has a given set of `key:value` pairs.
+  function isMatch(object, attrs) {
+    var _keys = keys(attrs), length = _keys.length;
+    if (object == null) return !length;
+    var obj = Object(object);
+    for (var i = 0; i < length; i++) {
+      var key = _keys[i];
+      if (attrs[key] !== obj[key] || !(key in obj)) return false;
+    }
+    return true;
+  }
+
+  // If Underscore is called as a function, it returns a wrapped object that can
+  // be used OO-style. This wrapper holds altered versions of all functions added
+  // through `_.mixin`. Wrapped objects may be chained.
+  function _$1(obj) {
+    if (obj instanceof _$1) return obj;
+    if (!(this instanceof _$1)) return new _$1(obj);
+    this._wrapped = obj;
+  }
+
+  _$1.VERSION = VERSION;
+
+  // Extracts the result from a wrapped and chained object.
+  _$1.prototype.value = function() {
+    return this._wrapped;
+  };
+
+  // Provide unwrapping proxies for some methods used in engine operations
+  // such as arithmetic and JSON stringification.
+  _$1.prototype.valueOf = _$1.prototype.toJSON = _$1.prototype.value;
+
+  _$1.prototype.toString = function() {
+    return String(this._wrapped);
+  };
+
+  // Internal function to wrap or shallow-copy an ArrayBuffer,
+  // typed array or DataView to a new view, reusing the buffer.
+  function toBufferView(bufferSource) {
+    return new Uint8Array(
+      bufferSource.buffer || bufferSource,
+      bufferSource.byteOffset || 0,
+      getByteLength(bufferSource)
+    );
+  }
+
+  // We use this string twice, so give it a name for minification.
+  var tagDataView = '[object DataView]';
+
+  // Internal recursive comparison function for `_.isEqual`.
+  function eq(a, b, aStack, bStack) {
+    // Identical objects are equal. `0 === -0`, but they aren't identical.
+    // See the [Harmony `egal` proposal](https://wiki.ecmascript.org/doku.php?id=harmony:egal).
+    if (a === b) return a !== 0 || 1 / a === 1 / b;
+    // `null` or `undefined` only equal to itself (strict comparison).
+    if (a == null || b == null) return false;
+    // `NaN`s are equivalent, but non-reflexive.
+    if (a !== a) return b !== b;
+    // Exhaust primitive checks
+    var type = typeof a;
+    if (type !== 'function' && type !== 'object' && typeof b != 'object') return false;
+    return deepEq(a, b, aStack, bStack);
+  }
+
+  // Internal recursive comparison function for `_.isEqual`.
+  function deepEq(a, b, aStack, bStack) {
+    // Unwrap any wrapped objects.
+    if (a instanceof _$1) a = a._wrapped;
+    if (b instanceof _$1) b = b._wrapped;
+    // Compare `[[Class]]` names.
+    var className = toString.call(a);
+    if (className !== toString.call(b)) return false;
+    // Work around a bug in IE 10 - Edge 13.
+    if (hasStringTagBug && className == '[object Object]' && isDataView$1(a)) {
+      if (!isDataView$1(b)) return false;
+      className = tagDataView;
+    }
+    switch (className) {
+      // These types are compared by value.
+      case '[object RegExp]':
+        // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')
+      case '[object String]':
+        // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
+        // equivalent to `new String("5")`.
+        return '' + a === '' + b;
+      case '[object Number]':
+        // `NaN`s are equivalent, but non-reflexive.
+        // Object(NaN) is equivalent to NaN.
+        if (+a !== +a) return +b !== +b;
+        // An `egal` comparison is performed for other numeric values.
+        return +a === 0 ? 1 / +a === 1 / b : +a === +b;
+      case '[object Date]':
+      case '[object Boolean]':
+        // Coerce dates and booleans to numeric primitive values. Dates are compared by their
+        // millisecond representations. Note that invalid dates with millisecond representations
+        // of `NaN` are not equivalent.
+        return +a === +b;
+      case '[object Symbol]':
+        return SymbolProto.valueOf.call(a) === SymbolProto.valueOf.call(b);
+      case '[object ArrayBuffer]':
+      case tagDataView:
+        // Coerce to typed array so we can fall through.
+        return deepEq(toBufferView(a), toBufferView(b), aStack, bStack);
+    }
+
+    var areArrays = className === '[object Array]';
+    if (!areArrays && isTypedArray$1(a)) {
+        var byteLength = getByteLength(a);
+        if (byteLength !== getByteLength(b)) return false;
+        if (a.buffer === b.buffer && a.byteOffset === b.byteOffset) return true;
+        areArrays = true;
+    }
+    if (!areArrays) {
+      if (typeof a != 'object' || typeof b != 'object') return false;
+
+      // Objects with different constructors are not equivalent, but `Object`s or `Array`s
+      // from different frames are.
+      var aCtor = a.constructor, bCtor = b.constructor;
+      if (aCtor !== bCtor && !(isFunction$1(aCtor) && aCtor instanceof aCtor &&
+                               isFunction$1(bCtor) && bCtor instanceof bCtor)
+                          && ('constructor' in a && 'constructor' in b)) {
+        return false;
+      }
+    }
+    // Assume equality for cyclic structures. The algorithm for detecting cyclic
+    // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
+
+    // Initializing stack of traversed objects.
+    // It's done here since we only need them for objects and arrays comparison.
+    aStack = aStack || [];
+    bStack = bStack || [];
+    var length = aStack.length;
+    while (length--) {
+      // Linear search. Performance is inversely proportional to the number of
+      // unique nested structures.
+      if (aStack[length] === a) return bStack[length] === b;
+    }
+
+    // Add the first object to the stack of traversed objects.
+    aStack.push(a);
+    bStack.push(b);
+
+    // Recursively compare objects and arrays.
+    if (areArrays) {
+      // Compare array lengths to determine if a deep comparison is necessary.
+      length = a.length;
+      if (length !== b.length) return false;
+      // Deep compare the contents, ignoring non-numeric properties.
+      while (length--) {
+        if (!eq(a[length], b[length], aStack, bStack)) return false;
+      }
+    } else {
+      // Deep compare objects.
+      var _keys = keys(a), key;
+      length = _keys.length;
+      // Ensure that both objects contain the same number of properties before comparing deep equality.
+      if (keys(b).length !== length) return false;
+      while (length--) {
+        // Deep compare each member
+        key = _keys[length];
+        if (!(has$1(b, key) && eq(a[key], b[key], aStack, bStack))) return false;
+      }
+    }
+    // Remove the first object from the stack of traversed objects.
+    aStack.pop();
+    bStack.pop();
+    return true;
+  }
+
+  // Perform a deep comparison to check if two objects are equal.
+  function isEqual(a, b) {
+    return eq(a, b);
+  }
+
+  // Retrieve all the enumerable property names of an object.
+  function allKeys(obj) {
+    if (!isObject(obj)) return [];
+    var keys = [];
+    for (var key in obj) keys.push(key);
+    // Ahem, IE < 9.
+    if (hasEnumBug) collectNonEnumProps(obj, keys);
+    return keys;
+  }
+
+  // Since the regular `Object.prototype.toString` type tests don't work for
+  // some types in IE 11, we use a fingerprinting heuristic instead, based
+  // on the methods. It's not great, but it's the best we got.
+  // The fingerprint method lists are defined below.
+  function ie11fingerprint(methods) {
+    var length = getLength(methods);
+    return function(obj) {
+      if (obj == null) return false;
+      // `Map`, `WeakMap` and `Set` have no enumerable keys.
+      var keys = allKeys(obj);
+      if (getLength(keys)) return false;
+      for (var i = 0; i < length; i++) {
+        if (!isFunction$1(obj[methods[i]])) return false;
+      }
+      // If we are testing against `WeakMap`, we need to ensure that
+      // `obj` doesn't have a `forEach` method in order to distinguish
+      // it from a regular `Map`.
+      return methods !== weakMapMethods || !isFunction$1(obj[forEachName]);
+    };
+  }
+
+  // In the interest of compact minification, we write
+  // each string in the fingerprints only once.
+  var forEachName = 'forEach',
+      hasName = 'has',
+      commonInit = ['clear', 'delete'],
+      mapTail = ['get', hasName, 'set'];
+
+  // `Map`, `WeakMap` and `Set` each have slightly different
+  // combinations of the above sublists.
+  var mapMethods = commonInit.concat(forEachName, mapTail),
+      weakMapMethods = commonInit.concat(mapTail),
+      setMethods = ['add'].concat(commonInit, forEachName, hasName);
+
+  var isMap = isIE11 ? ie11fingerprint(mapMethods) : tagTester('Map');
+
+  var isWeakMap = isIE11 ? ie11fingerprint(weakMapMethods) : tagTester('WeakMap');
+
+  var isSet = isIE11 ? ie11fingerprint(setMethods) : tagTester('Set');
+
+  var isWeakSet = tagTester('WeakSet');
+
+  // Retrieve the values of an object's properties.
+  function values(obj) {
+    var _keys = keys(obj);
+    var length = _keys.length;
+    var values = Array(length);
+    for (var i = 0; i < length; i++) {
+      values[i] = obj[_keys[i]];
+    }
+    return values;
+  }
+
+  // Convert an object into a list of `[key, value]` pairs.
+  // The opposite of `_.object` with one argument.
+  function pairs(obj) {
+    var _keys = keys(obj);
+    var length = _keys.length;
+    var pairs = Array(length);
+    for (var i = 0; i < length; i++) {
+      pairs[i] = [_keys[i], obj[_keys[i]]];
+    }
+    return pairs;
+  }
+
+  // Invert the keys and values of an object. The values must be serializable.
+  function invert(obj) {
+    var result = {};
+    var _keys = keys(obj);
+    for (var i = 0, length = _keys.length; i < length; i++) {
+      result[obj[_keys[i]]] = _keys[i];
+    }
+    return result;
+  }
+
+  // Return a sorted list of the function names available on the object.
+  function functions(obj) {
+    var names = [];
+    for (var key in obj) {
+      if (isFunction$1(obj[key])) names.push(key);
+    }
+    return names.sort();
+  }
+
+  // An internal function for creating assigner functions.
+  function createAssigner(keysFunc, defaults) {
+    return function(obj) {
+      var length = arguments.length;
+      if (defaults) obj = Object(obj);
+      if (length < 2 || obj == null) return obj;
+      for (var index = 1; index < length; index++) {
+        var source = arguments[index],
+            keys = keysFunc(source),
+            l = keys.length;
+        for (var i = 0; i < l; i++) {
+          var key = keys[i];
+          if (!defaults || obj[key] === void 0) obj[key] = source[key];
+        }
+      }
+      return obj;
+    };
+  }
+
+  // Extend a given object with all the properties in passed-in object(s).
+  var extend = createAssigner(allKeys);
+
+  // Assigns a given object with all the own properties in the passed-in
+  // object(s).
+  // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)
+  var extendOwn = createAssigner(keys);
+
+  // Fill in a given object with default properties.
+  var defaults = createAssigner(allKeys, true);
+
+  // Create a naked function reference for surrogate-prototype-swapping.
+  function ctor() {
+    return function(){};
+  }
+
+  // An internal function for creating a new object that inherits from another.
+  function baseCreate(prototype) {
+    if (!isObject(prototype)) return {};
+    if (nativeCreate) return nativeCreate(prototype);
+    var Ctor = ctor();
+    Ctor.prototype = prototype;
+    var result = new Ctor;
+    Ctor.prototype = null;
+    return result;
+  }
+
+  // Creates an object that inherits from the given prototype object.
+  // If additional properties are provided then they will be added to the
+  // created object.
+  function create(prototype, props) {
+    var result = baseCreate(prototype);
+    if (props) extendOwn(result, props);
+    return result;
+  }
+
+  // Create a (shallow-cloned) duplicate of an object.
+  function clone(obj) {
+    if (!isObject(obj)) return obj;
+    return isArray(obj) ? obj.slice() : extend({}, obj);
+  }
+
+  // Invokes `interceptor` with the `obj` and then returns `obj`.
+  // The primary purpose of this method is to "tap into" a method chain, in
+  // order to perform operations on intermediate results within the chain.
+  function tap(obj, interceptor) {
+    interceptor(obj);
+    return obj;
+  }
+
+  // Normalize a (deep) property `path` to array.
+  // Like `_.iteratee`, this function can be customized.
+  function toPath$1(path) {
+    return isArray(path) ? path : [path];
+  }
+  _$1.toPath = toPath$1;
+
+  // Internal wrapper for `_.toPath` to enable minification.
+  // Similar to `cb` for `_.iteratee`.
+  function toPath(path) {
+    return _$1.toPath(path);
+  }
+
+  // Internal function to obtain a nested property in `obj` along `path`.
+  function deepGet(obj, path) {
+    var length = path.length;
+    for (var i = 0; i < length; i++) {
+      if (obj == null) return void 0;
+      obj = obj[path[i]];
+    }
+    return length ? obj : void 0;
+  }
+
+  // Get the value of the (deep) property on `path` from `object`.
+  // If any property in `path` does not exist or if the value is
+  // `undefined`, return `defaultValue` instead.
+  // The `path` is normalized through `_.toPath`.
+  function get(object, path, defaultValue) {
+    var value = deepGet(object, toPath(path));
+    return isUndefined(value) ? defaultValue : value;
+  }
+
+  // Shortcut function for checking if an object has a given property directly on
+  // itself (in other words, not on a prototype). Unlike the internal `has`
+  // function, this public version can also traverse nested properties.
+  function has(obj, path) {
+    path = toPath(path);
+    var length = path.length;
+    for (var i = 0; i < length; i++) {
+      var key = path[i];
+      if (!has$1(obj, key)) return false;
+      obj = obj[key];
+    }
+    return !!length;
+  }
+
+  // Keep the identity function around for default iteratees.
+  function identity(value) {
+    return value;
+  }
+
+  // Returns a predicate for checking whether an object has a given set of
+  // `key:value` pairs.
+  function matcher(attrs) {
+    attrs = extendOwn({}, attrs);
+    return function(obj) {
+      return isMatch(obj, attrs);
+    };
+  }
+
+  // Creates a function that, when passed an object, will traverse that object’s
+  // properties down the given `path`, specified as an array of keys or indices.
+  function property(path) {
+    path = toPath(path);
+    return function(obj) {
+      return deepGet(obj, path);
+    };
+  }
+
+  // Internal function that returns an efficient (for current engines) version
+  // of the passed-in callback, to be repeatedly applied in other Underscore
+  // functions.
+  function optimizeCb(func, context, argCount) {
+    if (context === void 0) return func;
+    switch (argCount == null ? 3 : argCount) {
+      case 1: return function(value) {
+        return func.call(context, value);
+      };
+      // The 2-argument case is omitted because we’re not using it.
+      case 3: return function(value, index, collection) {
+        return func.call(context, value, index, collection);
+      };
+      case 4: return function(accumulator, value, index, collection) {
+        return func.call(context, accumulator, value, index, collection);
+      };
+    }
+    return function() {
+      return func.apply(context, arguments);
+    };
+  }
+
+  // An internal function to generate callbacks that can be applied to each
+  // element in a collection, returning the desired result — either `_.identity`,
+  // an arbitrary callback, a property matcher, or a property accessor.
+  function baseIteratee(value, context, argCount) {
+    if (value == null) return identity;
+    if (isFunction$1(value)) return optimizeCb(value, context, argCount);
+    if (isObject(value) && !isArray(value)) return matcher(value);
+    return property(value);
+  }
+
+  // External wrapper for our callback generator. Users may customize
+  // `_.iteratee` if they want additional predicate/iteratee shorthand styles.
+  // This abstraction hides the internal-only `argCount` argument.
+  function iteratee(value, context) {
+    return baseIteratee(value, context, Infinity);
+  }
+  _$1.iteratee = iteratee;
+
+  // The function we call internally to generate a callback. It invokes
+  // `_.iteratee` if overridden, otherwise `baseIteratee`.
+  function cb(value, context, argCount) {
+    if (_$1.iteratee !== iteratee) return _$1.iteratee(value, context);
+    return baseIteratee(value, context, argCount);
+  }
+
+  // Returns the results of applying the `iteratee` to each element of `obj`.
+  // In contrast to `_.map` it returns an object.
+  function mapObject(obj, iteratee, context) {
+    iteratee = cb(iteratee, context);
+    var _keys = keys(obj),
+        length = _keys.length,
+        results = {};
+    for (var index = 0; index < length; index++) {
+      var currentKey = _keys[index];
+      results[currentKey] = iteratee(obj[currentKey], currentKey, obj);
+    }
+    return results;
+  }
+
+  // Predicate-generating function. Often useful outside of Underscore.
+  function noop(){}
+
+  // Generates a function for a given object that returns a given property.
+  function propertyOf(obj) {
+    if (obj == null) return noop;
+    return function(path) {
+      return get(obj, path);
+    };
+  }
+
+  // Run a function **n** times.
+  function times(n, iteratee, context) {
+    var accum = Array(Math.max(0, n));
+    iteratee = optimizeCb(iteratee, context, 1);
+    for (var i = 0; i < n; i++) accum[i] = iteratee(i);
+    return accum;
+  }
+
+  // Return a random integer between `min` and `max` (inclusive).
+  function random(min, max) {
+    if (max == null) {
+      max = min;
+      min = 0;
+    }
+    return min + Math.floor(Math.random() * (max - min + 1));
+  }
+
+  // A (possibly faster) way to get the current timestamp as an integer.
+  var now = Date.now || function() {
+    return new Date().getTime();
+  };
+
+  // Internal helper to generate functions for escaping and unescaping strings
+  // to/from HTML interpolation.
+  function createEscaper(map) {
+    var escaper = function(match) {
+      return map[match];
+    };
+    // Regexes for identifying a key that needs to be escaped.
+    var source = '(?:' + keys(map).join('|') + ')';
+    var testRegexp = RegExp(source);
+    var replaceRegexp = RegExp(source, 'g');
+    return function(string) {
+      string = string == null ? '' : '' + string;
+      return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;
+    };
+  }
+
+  // Internal list of HTML entities for escaping.
+  var escapeMap = {
+    '&': '&amp;',
+    '<': '&lt;',
+    '>': '&gt;',
+    '"': '&quot;',
+    "'": '&#x27;',
+    '`': '&#x60;'
+  };
+
+  // Function for escaping strings to HTML interpolation.
+  var _escape = createEscaper(escapeMap);
+
+  // Internal list of HTML entities for unescaping.
+  var unescapeMap = invert(escapeMap);
+
+  // Function for unescaping strings from HTML interpolation.
+  var _unescape = createEscaper(unescapeMap);
+
+  // By default, Underscore uses ERB-style template delimiters. Change the
+  // following template settings to use alternative delimiters.
+  var templateSettings = _$1.templateSettings = {
+    evaluate: /<%([\s\S]+?)%>/g,
+    interpolate: /<%=([\s\S]+?)%>/g,
+    escape: /<%-([\s\S]+?)%>/g
+  };
+
+  // When customizing `_.templateSettings`, if you don't want to define an
+  // interpolation, evaluation or escaping regex, we need one that is
+  // guaranteed not to match.
+  var noMatch = /(.)^/;
+
+  // Certain characters need to be escaped so that they can be put into a
+  // string literal.
+  var escapes = {
+    "'": "'",
+    '\\': '\\',
+    '\r': 'r',
+    '\n': 'n',
+    '\u2028': 'u2028',
+    '\u2029': 'u2029'
+  };
+
+  var escapeRegExp = /\\|'|\r|\n|\u2028|\u2029/g;
+
+  function escapeChar(match) {
+    return '\\' + escapes[match];
+  }
+
+  // In order to prevent third-party code injection through
+  // `_.templateSettings.variable`, we test it against the following regular
+  // expression. It is intentionally a bit more liberal than just matching valid
+  // identifiers, but still prevents possible loopholes through defaults or
+  // destructuring assignment.
+  var bareIdentifier = /^\s*(\w|\$)+\s*$/;
+
+  // JavaScript micro-templating, similar to John Resig's implementation.
+  // Underscore templating handles arbitrary delimiters, preserves whitespace,
+  // and correctly escapes quotes within interpolated code.
+  // NB: `oldSettings` only exists for backwards compatibility.
+  function template(text, settings, oldSettings) {
+    if (!settings && oldSettings) settings = oldSettings;
+    settings = defaults({}, settings, _$1.templateSettings);
+
+    // Combine delimiters into one regular expression via alternation.
+    var matcher = RegExp([
+      (settings.escape || noMatch).source,
+      (settings.interpolate || noMatch).source,
+      (settings.evaluate || noMatch).source
+    ].join('|') + '|$', 'g');
+
+    // Compile the template source, escaping string literals appropriately.
+    var index = 0;
+    var source = "__p+='";
+    text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
+      source += text.slice(index, offset).replace(escapeRegExp, escapeChar);
+      index = offset + match.length;
+
+      if (escape) {
+        source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
+      } else if (interpolate) {
+        source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
+      } else if (evaluate) {
+        source += "';\n" + evaluate + "\n__p+='";
+      }
+
+      // Adobe VMs need the match returned to produce the correct offset.
+      return match;
+    });
+    source += "';\n";
+
+    var argument = settings.variable;
+    if (argument) {
+      // Insure against third-party code injection. (CVE-2021-23358)
+      if (!bareIdentifier.test(argument)) throw new Error(
+        'variable is not a bare identifier: ' + argument
+      );
+    } else {
+      // If a variable is not specified, place data values in local scope.
+      source = 'with(obj||{}){\n' + source + '}\n';
+      argument = 'obj';
+    }
+
+    source = "var __t,__p='',__j=Array.prototype.join," +
+      "print=function(){__p+=__j.call(arguments,'');};\n" +
+      source + 'return __p;\n';
+
+    var render;
+    try {
+      render = new Function(argument, '_', source);
+    } catch (e) {
+      e.source = source;
+      throw e;
+    }
+
+    var template = function(data) {
+      return render.call(this, data, _$1);
+    };
+
+    // Provide the compiled source as a convenience for precompilation.
+    template.source = 'function(' + argument + '){\n' + source + '}';
+
+    return template;
+  }
+
+  // Traverses the children of `obj` along `path`. If a child is a function, it
+  // is invoked with its parent as context. Returns the value of the final
+  // child, or `fallback` if any child is undefined.
+  function result(obj, path, fallback) {
+    path = toPath(path);
+    var length = path.length;
+    if (!length) {
+      return isFunction$1(fallback) ? fallback.call(obj) : fallback;
+    }
+    for (var i = 0; i < length; i++) {
+      var prop = obj == null ? void 0 : obj[path[i]];
+      if (prop === void 0) {
+        prop = fallback;
+        i = length; // Ensure we don't continue iterating.
+      }
+      obj = isFunction$1(prop) ? prop.call(obj) : prop;
+    }
+    return obj;
+  }
+
+  // Generate a unique integer id (unique within the entire client session).
+  // Useful for temporary DOM ids.
+  var idCounter = 0;
+  function uniqueId(prefix) {
+    var id = ++idCounter + '';
+    return prefix ? prefix + id : id;
+  }
+
+  // Start chaining a wrapped Underscore object.
+  function chain(obj) {
+    var instance = _$1(obj);
+    instance._chain = true;
+    return instance;
+  }
+
+  // Internal function to execute `sourceFunc` bound to `context` with optional
+  // `args`. Determines whether to execute a function as a constructor or as a
+  // normal function.
+  function executeBound(sourceFunc, boundFunc, context, callingContext, args) {
+    if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args);
+    var self = baseCreate(sourceFunc.prototype);
+    var result = sourceFunc.apply(self, args);
+    if (isObject(result)) return result;
+    return self;
+  }
+
+  // Partially apply a function by creating a version that has had some of its
+  // arguments pre-filled, without changing its dynamic `this` context. `_` acts
+  // as a placeholder by default, allowing any combination of arguments to be
+  // pre-filled. Set `_.partial.placeholder` for a custom placeholder argument.
+  var partial = restArguments(function(func, boundArgs) {
+    var placeholder = partial.placeholder;
+    var bound = function() {
+      var position = 0, length = boundArgs.length;
+      var args = Array(length);
+      for (var i = 0; i < length; i++) {
+        args[i] = boundArgs[i] === placeholder ? arguments[position++] : boundArgs[i];
+      }
+      while (position < arguments.length) args.push(arguments[position++]);
+      return executeBound(func, bound, this, this, args);
+    };
+    return bound;
+  });
+
+  partial.placeholder = _$1;
+
+  // Create a function bound to a given object (assigning `this`, and arguments,
+  // optionally).
+  var bind = restArguments(function(func, context, args) {
+    if (!isFunction$1(func)) throw new TypeError('Bind must be called on a function');
+    var bound = restArguments(function(callArgs) {
+      return executeBound(func, bound, context, this, args.concat(callArgs));
+    });
+    return bound;
+  });
+
+  // Internal helper for collection methods to determine whether a collection
+  // should be iterated as an array or as an object.
+  // Related: https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength
+  // Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094
+  var isArrayLike = createSizePropertyCheck(getLength);
+
+  // Internal implementation of a recursive `flatten` function.
+  function flatten$1(input, depth, strict, output) {
+    output = output || [];
+    if (!depth && depth !== 0) {
+      depth = Infinity;
+    } else if (depth <= 0) {
+      return output.concat(input);
+    }
+    var idx = output.length;
+    for (var i = 0, length = getLength(input); i < length; i++) {
+      var value = input[i];
+      if (isArrayLike(value) && (isArray(value) || isArguments$1(value))) {
+        // Flatten current level of array or arguments object.
+        if (depth > 1) {
+          flatten$1(value, depth - 1, strict, output);
+          idx = output.length;
+        } else {
+          var j = 0, len = value.length;
+          while (j < len) output[idx++] = value[j++];
+        }
+      } else if (!strict) {
+        output[idx++] = value;
+      }
+    }
+    return output;
+  }
+
+  // Bind a number of an object's methods to that object. Remaining arguments
+  // are the method names to be bound. Useful for ensuring that all callbacks
+  // defined on an object belong to it.
+  var bindAll = restArguments(function(obj, keys) {
+    keys = flatten$1(keys, false, false);
+    var index = keys.length;
+    if (index < 1) throw new Error('bindAll must be passed function names');
+    while (index--) {
+      var key = keys[index];
+      obj[key] = bind(obj[key], obj);
+    }
+    return obj;
+  });
+
+  // Memoize an expensive function by storing its results.
+  function memoize(func, hasher) {
+    var memoize = function(key) {
+      var cache = memoize.cache;
+      var address = '' + (hasher ? hasher.apply(this, arguments) : key);
+      if (!has$1(cache, address)) cache[address] = func.apply(this, arguments);
+      return cache[address];
+    };
+    memoize.cache = {};
+    return memoize;
+  }
+
+  // Delays a function for the given number of milliseconds, and then calls
+  // it with the arguments supplied.
+  var delay = restArguments(function(func, wait, args) {
+    return setTimeout(function() {
+      return func.apply(null, args);
+    }, wait);
+  });
+
+  // Defers a function, scheduling it to run after the current call stack has
+  // cleared.
+  var defer = partial(delay, _$1, 1);
+
+  // Returns a function, that, when invoked, will only be triggered at most once
+  // during a given window of time. Normally, the throttled function will run
+  // as much as it can, without ever going more than once per `wait` duration;
+  // but if you'd like to disable the execution on the leading edge, pass
+  // `{leading: false}`. To disable execution on the trailing edge, ditto.
+  function throttle(func, wait, options) {
+    var timeout, context, args, result;
+    var previous = 0;
+    if (!options) options = {};
+
+    var later = function() {
+      previous = options.leading === false ? 0 : now();
+      timeout = null;
+      result = func.apply(context, args);
+      if (!timeout) context = args = null;
+    };
+
+    var throttled = function() {
+      var _now = now();
+      if (!previous && options.leading === false) previous = _now;
+      var remaining = wait - (_now - previous);
+      context = this;
+      args = arguments;
+      if (remaining <= 0 || remaining > wait) {
+        if (timeout) {
+          clearTimeout(timeout);
+          timeout = null;
+        }
+        previous = _now;
+        result = func.apply(context, args);
+        if (!timeout) context = args = null;
+      } else if (!timeout && options.trailing !== false) {
+        timeout = setTimeout(later, remaining);
+      }
+      return result;
+    };
+
+    throttled.cancel = function() {
+      clearTimeout(timeout);
+      previous = 0;
+      timeout = context = args = null;
+    };
+
+    return throttled;
+  }
+
+  // When a sequence of calls of the returned function ends, the argument
+  // function is triggered. The end of a sequence is defined by the `wait`
+  // parameter. If `immediate` is passed, the argument function will be
+  // triggered at the beginning of the sequence instead of at the end.
+  function debounce(func, wait, immediate) {
+    var timeout, previous, args, result, context;
+
+    var later = function() {
+      var passed = now() - previous;
+      if (wait > passed) {
+        timeout = setTimeout(later, wait - passed);
+      } else {
+        timeout = null;
+        if (!immediate) result = func.apply(context, args);
+        // This check is needed because `func` can recursively invoke `debounced`.
+        if (!timeout) args = context = null;
+      }
+    };
+
+    var debounced = restArguments(function(_args) {
+      context = this;
+      args = _args;
+      previous = now();
+      if (!timeout) {
+        timeout = setTimeout(later, wait);
+        if (immediate) result = func.apply(context, args);
+      }
+      return result;
+    });
+
+    debounced.cancel = function() {
+      clearTimeout(timeout);
+      timeout = args = context = null;
+    };
+
+    return debounced;
+  }
+
+  // Returns the first function passed as an argument to the second,
+  // allowing you to adjust arguments, run code before and after, and
+  // conditionally execute the original function.
+  function wrap(func, wrapper) {
+    return partial(wrapper, func);
+  }
+
+  // Returns a negated version of the passed-in predicate.
+  function negate(predicate) {
+    return function() {
+      return !predicate.apply(this, arguments);
+    };
+  }
+
+  // Returns a function that is the composition of a list of functions, each
+  // consuming the return value of the function that follows.
+  function compose() {
+    var args = arguments;
+    var start = args.length - 1;
+    return function() {
+      var i = start;
+      var result = args[start].apply(this, arguments);
+      while (i--) result = args[i].call(this, result);
+      return result;
+    };
+  }
+
+  // Returns a function that will only be executed on and after the Nth call.
+  function after(times, func) {
+    return function() {
+      if (--times < 1) {
+        return func.apply(this, arguments);
+      }
+    };
+  }
+
+  // Returns a function that will only be executed up to (but not including) the
+  // Nth call.
+  function before(times, func) {
+    var memo;
+    return function() {
+      if (--times > 0) {
+        memo = func.apply(this, arguments);
+      }
+      if (times <= 1) func = null;
+      return memo;
+    };
+  }
+
+  // Returns a function that will be executed at most one time, no matter how
+  // often you call it. Useful for lazy initialization.
+  var once = partial(before, 2);
+
+  // Returns the first key on an object that passes a truth test.
+  function findKey(obj, predicate, context) {
+    predicate = cb(predicate, context);
+    var _keys = keys(obj), key;
+    for (var i = 0, length = _keys.length; i < length; i++) {
+      key = _keys[i];
+      if (predicate(obj[key], key, obj)) return key;
+    }
+  }
+
+  // Internal function to generate `_.findIndex` and `_.findLastIndex`.
+  function createPredicateIndexFinder(dir) {
+    return function(array, predicate, context) {
+      predicate = cb(predicate, context);
+      var length = getLength(array);
+      var index = dir > 0 ? 0 : length - 1;
+      for (; index >= 0 && index < length; index += dir) {
+        if (predicate(array[index], index, array)) return index;
+      }
+      return -1;
+    };
+  }
+
+  // Returns the first index on an array-like that passes a truth test.
+  var findIndex = createPredicateIndexFinder(1);
+
+  // Returns the last index on an array-like that passes a truth test.
+  var findLastIndex = createPredicateIndexFinder(-1);
+
+  // Use a comparator function to figure out the smallest index at which
+  // an object should be inserted so as to maintain order. Uses binary search.
+  function sortedIndex(array, obj, iteratee, context) {
+    iteratee = cb(iteratee, context, 1);
+    var value = iteratee(obj);
+    var low = 0, high = getLength(array);
+    while (low < high) {
+      var mid = Math.floor((low + high) / 2);
+      if (iteratee(array[mid]) < value) low = mid + 1; else high = mid;
+    }
+    return low;
+  }
+
+  // Internal function to generate the `_.indexOf` and `_.lastIndexOf` functions.
+  function createIndexFinder(dir, predicateFind, sortedIndex) {
+    return function(array, item, idx) {
+      var i = 0, length = getLength(array);
+      if (typeof idx == 'number') {
+        if (dir > 0) {
+          i = idx >= 0 ? idx : Math.max(idx + length, i);
+        } else {
+          length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1;
+        }
+      } else if (sortedIndex && idx && length) {
+        idx = sortedIndex(array, item);
+        return array[idx] === item ? idx : -1;
+      }
+      if (item !== item) {
+        idx = predicateFind(slice.call(array, i, length), isNaN$1);
+        return idx >= 0 ? idx + i : -1;
+      }
+      for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) {
+        if (array[idx] === item) return idx;
+      }
+      return -1;
+    };
+  }
+
+  // Return the position of the first occurrence of an item in an array,
+  // or -1 if the item is not included in the array.
+  // If the array is large and already in sort order, pass `true`
+  // for **isSorted** to use binary search.
+  var indexOf = createIndexFinder(1, findIndex, sortedIndex);
+
+  // Return the position of the last occurrence of an item in an array,
+  // or -1 if the item is not included in the array.
+  var lastIndexOf = createIndexFinder(-1, findLastIndex);
+
+  // Return the first value which passes a truth test.
+  function find(obj, predicate, context) {
+    var keyFinder = isArrayLike(obj) ? findIndex : findKey;
+    var key = keyFinder(obj, predicate, context);
+    if (key !== void 0 && key !== -1) return obj[key];
+  }
+
+  // Convenience version of a common use case of `_.find`: getting the first
+  // object containing specific `key:value` pairs.
+  function findWhere(obj, attrs) {
+    return find(obj, matcher(attrs));
+  }
+
+  // The cornerstone for collection functions, an `each`
+  // implementation, aka `forEach`.
+  // Handles raw objects in addition to array-likes. Treats all
+  // sparse array-likes as if they were dense.
+  function each(obj, iteratee, context) {
+    iteratee = optimizeCb(iteratee, context);
+    var i, length;
+    if (isArrayLike(obj)) {
+      for (i = 0, length = obj.length; i < length; i++) {
+        iteratee(obj[i], i, obj);
+      }
+    } else {
+      var _keys = keys(obj);
+      for (i = 0, length = _keys.length; i < length; i++) {
+        iteratee(obj[_keys[i]], _keys[i], obj);
+      }
+    }
+    return obj;
+  }
+
+  // Return the results of applying the iteratee to each element.
+  function map(obj, iteratee, context) {
+    iteratee = cb(iteratee, context);
+    var _keys = !isArrayLike(obj) && keys(obj),
+        length = (_keys || obj).length,
+        results = Array(length);
+    for (var index = 0; index < length; index++) {
+      var currentKey = _keys ? _keys[index] : index;
+      results[index] = iteratee(obj[currentKey], currentKey, obj);
+    }
+    return results;
+  }
+
+  // Internal helper to create a reducing function, iterating left or right.
+  function createReduce(dir) {
+    // Wrap code that reassigns argument variables in a separate function than
+    // the one that accesses `arguments.length` to avoid a perf hit. (#1991)
+    var reducer = function(obj, iteratee, memo, initial) {
+      var _keys = !isArrayLike(obj) && keys(obj),
+          length = (_keys || obj).length,
+          index = dir > 0 ? 0 : length - 1;
+      if (!initial) {
+        memo = obj[_keys ? _keys[index] : index];
+        index += dir;
+      }
+      for (; index >= 0 && index < length; index += dir) {
+        var currentKey = _keys ? _keys[index] : index;
+        memo = iteratee(memo, obj[currentKey], currentKey, obj);
+      }
+      return memo;
+    };
+
+    return function(obj, iteratee, memo, context) {
+      var initial = arguments.length >= 3;
+      return reducer(obj, optimizeCb(iteratee, context, 4), memo, initial);
+    };
+  }
+
+  // **Reduce** builds up a single result from a list of values, aka `inject`,
+  // or `foldl`.
+  var reduce = createReduce(1);
+
+  // The right-associative version of reduce, also known as `foldr`.
+  var reduceRight = createReduce(-1);
+
+  // Return all the elements that pass a truth test.
+  function filter(obj, predicate, context) {
+    var results = [];
+    predicate = cb(predicate, context);
+    each(obj, function(value, index, list) {
+      if (predicate(value, index, list)) results.push(value);
+    });
+    return results;
+  }
+
+  // Return all the elements for which a truth test fails.
+  function reject(obj, predicate, context) {
+    return filter(obj, negate(cb(predicate)), context);
+  }
+
+  // Determine whether all of the elements pass a truth test.
+  function every(obj, predicate, context) {
+    predicate = cb(predicate, context);
+    var _keys = !isArrayLike(obj) && keys(obj),
+        length = (_keys || obj).length;
+    for (var index = 0; index < length; index++) {
+      var currentKey = _keys ? _keys[index] : index;
+      if (!predicate(obj[currentKey], currentKey, obj)) return false;
+    }
+    return true;
+  }
+
+  // Determine if at least one element in the object passes a truth test.
+  function some(obj, predicate, context) {
+    predicate = cb(predicate, context);
+    var _keys = !isArrayLike(obj) && keys(obj),
+        length = (_keys || obj).length;
+    for (var index = 0; index < length; index++) {
+      var currentKey = _keys ? _keys[index] : index;
+      if (predicate(obj[currentKey], currentKey, obj)) return true;
+    }
+    return false;
+  }
+
+  // Determine if the array or object contains a given item (using `===`).
+  function contains(obj, item, fromIndex, guard) {
+    if (!isArrayLike(obj)) obj = values(obj);
+    if (typeof fromIndex != 'number' || guard) fromIndex = 0;
+    return indexOf(obj, item, fromIndex) >= 0;
+  }
+
+  // Invoke a method (with arguments) on every item in a collection.
+  var invoke = restArguments(function(obj, path, args) {
+    var contextPath, func;
+    if (isFunction$1(path)) {
+      func = path;
+    } else {
+      path = toPath(path);
+      contextPath = path.slice(0, -1);
+      path = path[path.length - 1];
+    }
+    return map(obj, function(context) {
+      var method = func;
+      if (!method) {
+        if (contextPath && contextPath.length) {
+          context = deepGet(context, contextPath);
+        }
+        if (context == null) return void 0;
+        method = context[path];
+      }
+      return method == null ? method : method.apply(context, args);
+    });
+  });
+
+  // Convenience version of a common use case of `_.map`: fetching a property.
+  function pluck(obj, key) {
+    return map(obj, property(key));
+  }
+
+  // Convenience version of a common use case of `_.filter`: selecting only
+  // objects containing specific `key:value` pairs.
+  function where(obj, attrs) {
+    return filter(obj, matcher(attrs));
+  }
+
+  // Return the maximum element (or element-based computation).
+  function max(obj, iteratee, context) {
+    var result = -Infinity, lastComputed = -Infinity,
+        value, computed;
+    if (iteratee == null || typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null) {
+      obj = isArrayLike(obj) ? obj : values(obj);
+      for (var i = 0, length = obj.length; i < length; i++) {
+        value = obj[i];
+        if (value != null && value > result) {
+          result = value;
+        }
+      }
+    } else {
+      iteratee = cb(iteratee, context);
+      each(obj, function(v, index, list) {
+        computed = iteratee(v, index, list);
+        if (computed > lastComputed || computed === -Infinity && result === -Infinity) {
+          result = v;
+          lastComputed = computed;
+        }
+      });
+    }
+    return result;
+  }
+
+  // Return the minimum element (or element-based computation).
+  function min(obj, iteratee, context) {
+    var result = Infinity, lastComputed = Infinity,
+        value, computed;
+    if (iteratee == null || typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null) {
+      obj = isArrayLike(obj) ? obj : values(obj);
+      for (var i = 0, length = obj.length; i < length; i++) {
+        value = obj[i];
+        if (value != null && value < result) {
+          result = value;
+        }
+      }
+    } else {
+      iteratee = cb(iteratee, context);
+      each(obj, function(v, index, list) {
+        computed = iteratee(v, index, list);
+        if (computed < lastComputed || computed === Infinity && result === Infinity) {
+          result = v;
+          lastComputed = computed;
+        }
+      });
+    }
+    return result;
+  }
+
+  // Sample **n** random values from a collection using the modern version of the
+  // [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
+  // If **n** is not specified, returns a single random element.
+  // The internal `guard` argument allows it to work with `_.map`.
+  function sample(obj, n, guard) {
+    if (n == null || guard) {
+      if (!isArrayLike(obj)) obj = values(obj);
+      return obj[random(obj.length - 1)];
+    }
+    var sample = isArrayLike(obj) ? clone(obj) : values(obj);
+    var length = getLength(sample);
+    n = Math.max(Math.min(n, length), 0);
+    var last = length - 1;
+    for (var index = 0; index < n; index++) {
+      var rand = random(index, last);
+      var temp = sample[index];
+      sample[index] = sample[rand];
+      sample[rand] = temp;
+    }
+    return sample.slice(0, n);
+  }
+
+  // Shuffle a collection.
+  function shuffle(obj) {
+    return sample(obj, Infinity);
+  }
+
+  // Sort the object's values by a criterion produced by an iteratee.
+  function sortBy(obj, iteratee, context) {
+    var index = 0;
+    iteratee = cb(iteratee, context);
+    return pluck(map(obj, function(value, key, list) {
+      return {
+        value: value,
+        index: index++,
+        criteria: iteratee(value, key, list)
+      };
+    }).sort(function(left, right) {
+      var a = left.criteria;
+      var b = right.criteria;
+      if (a !== b) {
+        if (a > b || a === void 0) return 1;
+        if (a < b || b === void 0) return -1;
+      }
+      return left.index - right.index;
+    }), 'value');
+  }
+
+  // An internal function used for aggregate "group by" operations.
+  function group(behavior, partition) {
+    return function(obj, iteratee, context) {
+      var result = partition ? [[], []] : {};
+      iteratee = cb(iteratee, context);
+      each(obj, function(value, index) {
+        var key = iteratee(value, index, obj);
+        behavior(result, value, key);
+      });
+      return result;
+    };
+  }
+
+  // Groups the object's values by a criterion. Pass either a string attribute
+  // to group by, or a function that returns the criterion.
+  var groupBy = group(function(result, value, key) {
+    if (has$1(result, key)) result[key].push(value); else result[key] = [value];
+  });
+
+  // Indexes the object's values by a criterion, similar to `_.groupBy`, but for
+  // when you know that your index values will be unique.
+  var indexBy = group(function(result, value, key) {
+    result[key] = value;
+  });
+
+  // Counts instances of an object that group by a certain criterion. Pass
+  // either a string attribute to count by, or a function that returns the
+  // criterion.
+  var countBy = group(function(result, value, key) {
+    if (has$1(result, key)) result[key]++; else result[key] = 1;
+  });
+
+  // Split a collection into two arrays: one whose elements all pass the given
+  // truth test, and one whose elements all do not pass the truth test.
+  var partition = group(function(result, value, pass) {
+    result[pass ? 0 : 1].push(value);
+  }, true);
+
+  // Safely create a real, live array from anything iterable.
+  var reStrSymbol = /[^\ud800-\udfff]|[\ud800-\udbff][\udc00-\udfff]|[\ud800-\udfff]/g;
+  function toArray(obj) {
+    if (!obj) return [];
+    if (isArray(obj)) return slice.call(obj);
+    if (isString(obj)) {
+      // Keep surrogate pair characters together.
+      return obj.match(reStrSymbol);
+    }
+    if (isArrayLike(obj)) return map(obj, identity);
+    return values(obj);
+  }
+
+  // Return the number of elements in a collection.
+  function size(obj) {
+    if (obj == null) return 0;
+    return isArrayLike(obj) ? obj.length : keys(obj).length;
+  }
+
+  // Internal `_.pick` helper function to determine whether `key` is an enumerable
+  // property name of `obj`.
+  function keyInObj(value, key, obj) {
+    return key in obj;
+  }
+
+  // Return a copy of the object only containing the allowed properties.
+  var pick = restArguments(function(obj, keys) {
+    var result = {}, iteratee = keys[0];
+    if (obj == null) return result;
+    if (isFunction$1(iteratee)) {
+      if (keys.length > 1) iteratee = optimizeCb(iteratee, keys[1]);
+      keys = allKeys(obj);
+    } else {
+      iteratee = keyInObj;
+      keys = flatten$1(keys, false, false);
+      obj = Object(obj);
+    }
+    for (var i = 0, length = keys.length; i < length; i++) {
+      var key = keys[i];
+      var value = obj[key];
+      if (iteratee(value, key, obj)) result[key] = value;
+    }
+    return result;
+  });
+
+  // Return a copy of the object without the disallowed properties.
+  var omit = restArguments(function(obj, keys) {
+    var iteratee = keys[0], context;
+    if (isFunction$1(iteratee)) {
+      iteratee = negate(iteratee);
+      if (keys.length > 1) context = keys[1];
+    } else {
+      keys = map(flatten$1(keys, false, false), String);
+      iteratee = function(value, key) {
+        return !contains(keys, key);
+      };
+    }
+    return pick(obj, iteratee, context);
+  });
+
+  // Returns everything but the last entry of the array. Especially useful on
+  // the arguments object. Passing **n** will return all the values in
+  // the array, excluding the last N.
+  function initial(array, n, guard) {
+    return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n)));
+  }
+
+  // Get the first element of an array. Passing **n** will return the first N
+  // values in the array. The **guard** check allows it to work with `_.map`.
+  function first(array, n, guard) {
+    if (array == null || array.length < 1) return n == null || guard ? void 0 : [];
+    if (n == null || guard) return array[0];
+    return initial(array, array.length - n);
+  }
+
+  // Returns everything but the first entry of the `array`. Especially useful on
+  // the `arguments` object. Passing an **n** will return the rest N values in the
+  // `array`.
+  function rest(array, n, guard) {
+    return slice.call(array, n == null || guard ? 1 : n);
+  }
+
+  // Get the last element of an array. Passing **n** will return the last N
+  // values in the array.
+  function last(array, n, guard) {
+    if (array == null || array.length < 1) return n == null || guard ? void 0 : [];
+    if (n == null || guard) return array[array.length - 1];
+    return rest(array, Math.max(0, array.length - n));
+  }
+
+  // Trim out all falsy values from an array.
+  function compact(array) {
+    return filter(array, Boolean);
+  }
+
+  // Flatten out an array, either recursively (by default), or up to `depth`.
+  // Passing `true` or `false` as `depth` means `1` or `Infinity`, respectively.
+  function flatten(array, depth) {
+    return flatten$1(array, depth, false);
+  }
+
+  // Take the difference between one array and a number of other arrays.
+  // Only the elements present in just the first array will remain.
+  var difference = restArguments(function(array, rest) {
+    rest = flatten$1(rest, true, true);
+    return filter(array, function(value){
+      return !contains(rest, value);
+    });
+  });
+
+  // Return a version of the array that does not contain the specified value(s).
+  var without = restArguments(function(array, otherArrays) {
+    return difference(array, otherArrays);
+  });
+
+  // Produce a duplicate-free version of the array. If the array has already
+  // been sorted, you have the option of using a faster algorithm.
+  // The faster algorithm will not work with an iteratee if the iteratee
+  // is not a one-to-one function, so providing an iteratee will disable
+  // the faster algorithm.
+  function uniq(array, isSorted, iteratee, context) {
+    if (!isBoolean(isSorted)) {
+      context = iteratee;
+      iteratee = isSorted;
+      isSorted = false;
+    }
+    if (iteratee != null) iteratee = cb(iteratee, context);
+    var result = [];
+    var seen = [];
+    for (var i = 0, length = getLength(array); i < length; i++) {
+      var value = array[i],
+          computed = iteratee ? iteratee(value, i, array) : value;
+      if (isSorted && !iteratee) {
+        if (!i || seen !== computed) result.push(value);
+        seen = computed;
+      } else if (iteratee) {
+        if (!contains(seen, computed)) {
+          seen.push(computed);
+          result.push(value);
+        }
+      } else if (!contains(result, value)) {
+        result.push(value);
+      }
+    }
+    return result;
+  }
+
+  // Produce an array that contains the union: each distinct element from all of
+  // the passed-in arrays.
+  var union = restArguments(function(arrays) {
+    return uniq(flatten$1(arrays, true, true));
+  });
+
+  // Produce an array that contains every item shared between all the
+  // passed-in arrays.
+  function intersection(array) {
+    var result = [];
+    var argsLength = arguments.length;
+    for (var i = 0, length = getLength(array); i < length; i++) {
+      var item = array[i];
+      if (contains(result, item)) continue;
+      var j;
+      for (j = 1; j < argsLength; j++) {
+        if (!contains(arguments[j], item)) break;
+      }
+      if (j === argsLength) result.push(item);
+    }
+    return result;
+  }
+
+  // Complement of zip. Unzip accepts an array of arrays and groups
+  // each array's elements on shared indices.
+  function unzip(array) {
+    var length = array && max(array, getLength).length || 0;
+    var result = Array(length);
+
+    for (var index = 0; index < length; index++) {
+      result[index] = pluck(array, index);
+    }
+    return result;
+  }
+
+  // Zip together multiple lists into a single array -- elements that share
+  // an index go together.
+  var zip = restArguments(unzip);
+
+  // Converts lists into objects. Pass either a single array of `[key, value]`
+  // pairs, or two parallel arrays of the same length -- one of keys, and one of
+  // the corresponding values. Passing by pairs is the reverse of `_.pairs`.
+  function object(list, values) {
+    var result = {};
+    for (var i = 0, length = getLength(list); i < length; i++) {
+      if (values) {
+        result[list[i]] = values[i];
+      } else {
+        result[list[i][0]] = list[i][1];
+      }
+    }
+    return result;
+  }
+
+  // Generate an integer Array containing an arithmetic progression. A port of
+  // the native Python `range()` function. See
+  // [the Python documentation](https://docs.python.org/library/functions.html#range).
+  function range(start, stop, step) {
+    if (stop == null) {
+      stop = start || 0;
+      start = 0;
+    }
+    if (!step) {
+      step = stop < start ? -1 : 1;
+    }
+
+    var length = Math.max(Math.ceil((stop - start) / step), 0);
+    var range = Array(length);
+
+    for (var idx = 0; idx < length; idx++, start += step) {
+      range[idx] = start;
+    }
+
+    return range;
+  }
+
+  // Chunk a single array into multiple arrays, each containing `count` or fewer
+  // items.
+  function chunk(array, count) {
+    if (count == null || count < 1) return [];
+    var result = [];
+    var i = 0, length = array.length;
+    while (i < length) {
+      result.push(slice.call(array, i, i += count));
+    }
+    return result;
+  }
+
+  // Helper function to continue chaining intermediate results.
+  function chainResult(instance, obj) {
+    return instance._chain ? _$1(obj).chain() : obj;
+  }
+
+  // Add your own custom functions to the Underscore object.
+  function mixin(obj) {
+    each(functions(obj), function(name) {
+      var func = _$1[name] = obj[name];
+      _$1.prototype[name] = function() {
+        var args = [this._wrapped];
+        push.apply(args, arguments);
+        return chainResult(this, func.apply(_$1, args));
+      };
+    });
+    return _$1;
+  }
+
+  // Add all mutator `Array` functions to the wrapper.
+  each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
+    var method = ArrayProto[name];
+    _$1.prototype[name] = function() {
+      var obj = this._wrapped;
+      if (obj != null) {
+        method.apply(obj, arguments);
+        if ((name === 'shift' || name === 'splice') && obj.length === 0) {
+          delete obj[0];
+        }
+      }
+      return chainResult(this, obj);
+    };
+  });
+
+  // Add all accessor `Array` functions to the wrapper.
+  each(['concat', 'join', 'slice'], function(name) {
+    var method = ArrayProto[name];
+    _$1.prototype[name] = function() {
+      var obj = this._wrapped;
+      if (obj != null) obj = method.apply(obj, arguments);
+      return chainResult(this, obj);
+    };
+  });
+
+  // Named Exports
+
+  var allExports = {
+    __proto__: null,
+    VERSION: VERSION,
+    restArguments: restArguments,
+    isObject: isObject,
+    isNull: isNull,
+    isUndefined: isUndefined,
+    isBoolean: isBoolean,
+    isElement: isElement,
+    isString: isString,
+    isNumber: isNumber,
+    isDate: isDate,
+    isRegExp: isRegExp,
+    isError: isError,
+    isSymbol: isSymbol,
+    isArrayBuffer: isArrayBuffer,
+    isDataView: isDataView$1,
+    isArray: isArray,
+    isFunction: isFunction$1,
+    isArguments: isArguments$1,
+    isFinite: isFinite$1,
+    isNaN: isNaN$1,
+    isTypedArray: isTypedArray$1,
+    isEmpty: isEmpty,
+    isMatch: isMatch,
+    isEqual: isEqual,
+    isMap: isMap,
+    isWeakMap: isWeakMap,
+    isSet: isSet,
+    isWeakSet: isWeakSet,
+    keys: keys,
+    allKeys: allKeys,
+    values: values,
+    pairs: pairs,
+    invert: invert,
+    functions: functions,
+    methods: functions,
+    extend: extend,
+    extendOwn: extendOwn,
+    assign: extendOwn,
+    defaults: defaults,
+    create: create,
+    clone: clone,
+    tap: tap,
+    get: get,
+    has: has,
+    mapObject: mapObject,
+    identity: identity,
+    constant: constant,
+    noop: noop,
+    toPath: toPath$1,
+    property: property,
+    propertyOf: propertyOf,
+    matcher: matcher,
+    matches: matcher,
+    times: times,
+    random: random,
+    now: now,
+    escape: _escape,
+    unescape: _unescape,
+    templateSettings: templateSettings,
+    template: template,
+    result: result,
+    uniqueId: uniqueId,
+    chain: chain,
+    iteratee: iteratee,
+    partial: partial,
+    bind: bind,
+    bindAll: bindAll,
+    memoize: memoize,
+    delay: delay,
+    defer: defer,
+    throttle: throttle,
+    debounce: debounce,
+    wrap: wrap,
+    negate: negate,
+    compose: compose,
+    after: after,
+    before: before,
+    once: once,
+    findKey: findKey,
+    findIndex: findIndex,
+    findLastIndex: findLastIndex,
+    sortedIndex: sortedIndex,
+    indexOf: indexOf,
+    lastIndexOf: lastIndexOf,
+    find: find,
+    detect: find,
+    findWhere: findWhere,
+    each: each,
+    forEach: each,
+    map: map,
+    collect: map,
+    reduce: reduce,
+    foldl: reduce,
+    inject: reduce,
+    reduceRight: reduceRight,
+    foldr: reduceRight,
+    filter: filter,
+    select: filter,
+    reject: reject,
+    every: every,
+    all: every,
+    some: some,
+    any: some,
+    contains: contains,
+    includes: contains,
+    include: contains,
+    invoke: invoke,
+    pluck: pluck,
+    where: where,
+    max: max,
+    min: min,
+    shuffle: shuffle,
+    sample: sample,
+    sortBy: sortBy,
+    groupBy: groupBy,
+    indexBy: indexBy,
+    countBy: countBy,
+    partition: partition,
+    toArray: toArray,
+    size: size,
+    pick: pick,
+    omit: omit,
+    first: first,
+    head: first,
+    take: first,
+    initial: initial,
+    last: last,
+    rest: rest,
+    tail: rest,
+    drop: rest,
+    compact: compact,
+    flatten: flatten,
+    without: without,
+    uniq: uniq,
+    unique: uniq,
+    union: union,
+    intersection: intersection,
+    difference: difference,
+    unzip: unzip,
+    transpose: unzip,
+    zip: zip,
+    object: object,
+    range: range,
+    chunk: chunk,
+    mixin: mixin,
+    'default': _$1
+  };
+
+  // Default Export
+
+  // Add all of the Underscore functions to the wrapper object.
+  var _ = mixin(allExports);
+  // Legacy Node.js API.
+  _._ = _;
+
+  return _;
+
+})));
+//# sourceMappingURL=underscore-umd.js.map
diff --git a/public/_static/underscore.js b/public/_static/underscore.js
index 5b55f32beaca186f84cca115514f02cddbd1bbd5..cf177d4285ab55fbc16406a5ec827b80e7eecd53 100644
--- a/public/_static/underscore.js
+++ b/public/_static/underscore.js
@@ -1,31 +1,6 @@
-// Underscore.js 1.3.1
-// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
-// Underscore is freely distributable under the MIT license.
-// Portions of Underscore are inspired or borrowed from Prototype,
-// Oliver Steele's Functional, and John Resig's Micro-Templating.
-// For all details and documentation:
-// http://documentcloud.github.com/underscore
-(function(){function q(a,c,d){if(a===c)return a!==0||1/a==1/c;if(a==null||c==null)return a===c;if(a._chain)a=a._wrapped;if(c._chain)c=c._wrapped;if(a.isEqual&&b.isFunction(a.isEqual))return a.isEqual(c);if(c.isEqual&&b.isFunction(c.isEqual))return c.isEqual(a);var e=l.call(a);if(e!=l.call(c))return false;switch(e){case "[object String]":return a==String(c);case "[object Number]":return a!=+a?c!=+c:a==0?1/a==1/c:a==+c;case "[object Date]":case "[object Boolean]":return+a==+c;case "[object RegExp]":return a.source==
-c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if(typeof a!="object"||typeof c!="object")return false;for(var f=d.length;f--;)if(d[f]==a)return true;d.push(a);var f=0,g=true;if(e=="[object Array]"){if(f=a.length,g=f==c.length)for(;f--;)if(!(g=f in a==f in c&&q(a[f],c[f],d)))break}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return false;for(var h in a)if(b.has(a,h)&&(f++,!(g=b.has(c,h)&&q(a[h],c[h],d))))break;if(g){for(h in c)if(b.has(c,
-h)&&!f--)break;g=!f}}d.pop();return g}var r=this,G=r._,n={},k=Array.prototype,o=Object.prototype,i=k.slice,H=k.unshift,l=o.toString,I=o.hasOwnProperty,w=k.forEach,x=k.map,y=k.reduce,z=k.reduceRight,A=k.filter,B=k.every,C=k.some,p=k.indexOf,D=k.lastIndexOf,o=Array.isArray,J=Object.keys,s=Function.prototype.bind,b=function(a){return new m(a)};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports)exports=module.exports=b;exports._=b}else r._=b;b.VERSION="1.3.1";var j=b.each=
-b.forEach=function(a,c,d){if(a!=null)if(w&&a.forEach===w)a.forEach(c,d);else if(a.length===+a.length)for(var e=0,f=a.length;e<f;e++){if(e in a&&c.call(d,a[e],e,a)===n)break}else for(e in a)if(b.has(a,e)&&c.call(d,a[e],e,a)===n)break};b.map=b.collect=function(a,c,b){var e=[];if(a==null)return e;if(x&&a.map===x)return a.map(c,b);j(a,function(a,g,h){e[e.length]=c.call(b,a,g,h)});if(a.length===+a.length)e.length=a.length;return e};b.reduce=b.foldl=b.inject=function(a,c,d,e){var f=arguments.length>2;a==
-null&&(a=[]);if(y&&a.reduce===y)return e&&(c=b.bind(c,e)),f?a.reduce(c,d):a.reduce(c);j(a,function(a,b,i){f?d=c.call(e,d,a,b,i):(d=a,f=true)});if(!f)throw new TypeError("Reduce of empty array with no initial value");return d};b.reduceRight=b.foldr=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(z&&a.reduceRight===z)return e&&(c=b.bind(c,e)),f?a.reduceRight(c,d):a.reduceRight(c);var g=b.toArray(a).reverse();e&&!f&&(c=b.bind(c,e));return f?b.reduce(g,c,d,e):b.reduce(g,c)};b.find=b.detect=
-function(a,c,b){var e;E(a,function(a,g,h){if(c.call(b,a,g,h))return e=a,true});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(A&&a.filter===A)return a.filter(c,b);j(a,function(a,g,h){c.call(b,a,g,h)&&(e[e.length]=a)});return e};b.reject=function(a,c,b){var e=[];if(a==null)return e;j(a,function(a,g,h){c.call(b,a,g,h)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=true;if(a==null)return e;if(B&&a.every===B)return a.every(c,b);j(a,function(a,g,h){if(!(e=
-e&&c.call(b,a,g,h)))return n});return e};var E=b.some=b.any=function(a,c,d){c||(c=b.identity);var e=false;if(a==null)return e;if(C&&a.some===C)return a.some(c,d);j(a,function(a,b,h){if(e||(e=c.call(d,a,b,h)))return n});return!!e};b.include=b.contains=function(a,c){var b=false;if(a==null)return b;return p&&a.indexOf===p?a.indexOf(c)!=-1:b=E(a,function(a){return a===c})};b.invoke=function(a,c){var d=i.call(arguments,2);return b.map(a,function(a){return(b.isFunction(c)?c||a:a[c]).apply(a,d)})};b.pluck=
-function(a,c){return b.map(a,function(a){return a[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);if(!c&&b.isEmpty(a))return-Infinity;var e={computed:-Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b<e.computed&&(e={value:a,computed:b})});
-return e.value};b.shuffle=function(a){var b=[],d;j(a,function(a,f){f==0?b[0]=a:(d=Math.floor(Math.random()*(f+1)),b[f]=b[d],b[d]=a)});return b};b.sortBy=function(a,c,d){return b.pluck(b.map(a,function(a,b,g){return{value:a,criteria:c.call(d,a,b,g)}}).sort(function(a,b){var c=a.criteria,d=b.criteria;return c<d?-1:c>d?1:0}),"value")};b.groupBy=function(a,c){var d={},e=b.isFunction(c)?c:function(a){return a[c]};j(a,function(a,b){var c=e(a,b);(d[c]||(d[c]=[])).push(a)});return d};b.sortedIndex=function(a,
-c,d){d||(d=b.identity);for(var e=0,f=a.length;e<f;){var g=e+f>>1;d(a[g])<d(c)?e=g+1:f=g}return e};b.toArray=function(a){return!a?[]:a.toArray?a.toArray():b.isArray(a)?i.call(a):b.isArguments(a)?i.call(a):b.values(a)};b.size=function(a){return b.toArray(a).length};b.first=b.head=function(a,b,d){return b!=null&&!d?i.call(a,0,b):a[0]};b.initial=function(a,b,d){return i.call(a,0,a.length-(b==null||d?1:b))};b.last=function(a,b,d){return b!=null&&!d?i.call(a,Math.max(a.length-b,0)):a[a.length-1]};b.rest=
-b.tail=function(a,b,d){return i.call(a,b==null||d?1:b)};b.compact=function(a){return b.filter(a,function(a){return!!a})};b.flatten=function(a,c){return b.reduce(a,function(a,e){if(b.isArray(e))return a.concat(c?e:b.flatten(e));a[a.length]=e;return a},[])};b.without=function(a){return b.difference(a,i.call(arguments,1))};b.uniq=b.unique=function(a,c,d){var d=d?b.map(a,d):a,e=[];b.reduce(d,function(d,g,h){if(0==h||(c===true?b.last(d)!=g:!b.include(d,g)))d[d.length]=g,e[e.length]=a[h];return d},[]);
-return e};b.union=function(){return b.uniq(b.flatten(arguments,true))};b.intersection=b.intersect=function(a){var c=i.call(arguments,1);return b.filter(b.uniq(a),function(a){return b.every(c,function(c){return b.indexOf(c,a)>=0})})};b.difference=function(a){var c=b.flatten(i.call(arguments,1));return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=i.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e<c;e++)d[e]=b.pluck(a,""+e);return d};b.indexOf=function(a,c,
-d){if(a==null)return-1;var e;if(d)return d=b.sortedIndex(a,c),a[d]===c?d:-1;if(p&&a.indexOf===p)return a.indexOf(c);for(d=0,e=a.length;d<e;d++)if(d in a&&a[d]===c)return d;return-1};b.lastIndexOf=function(a,b){if(a==null)return-1;if(D&&a.lastIndexOf===D)return a.lastIndexOf(b);for(var d=a.length;d--;)if(d in a&&a[d]===b)return d;return-1};b.range=function(a,b,d){arguments.length<=1&&(b=a||0,a=0);for(var d=arguments[2]||1,e=Math.max(Math.ceil((b-a)/d),0),f=0,g=Array(e);f<e;)g[f++]=a,a+=d;return g};
-var F=function(){};b.bind=function(a,c){var d,e;if(a.bind===s&&s)return s.apply(a,i.call(arguments,1));if(!b.isFunction(a))throw new TypeError;e=i.call(arguments,2);return d=function(){if(!(this instanceof d))return a.apply(c,e.concat(i.call(arguments)));F.prototype=a.prototype;var b=new F,g=a.apply(b,e.concat(i.call(arguments)));return Object(g)===g?g:b}};b.bindAll=function(a){var c=i.call(arguments,1);c.length==0&&(c=b.functions(a));j(c,function(c){a[c]=b.bind(a[c],a)});return a};b.memoize=function(a,
-c){var d={};c||(c=b.identity);return function(){var e=c.apply(this,arguments);return b.has(d,e)?d[e]:d[e]=a.apply(this,arguments)}};b.delay=function(a,b){var d=i.call(arguments,2);return setTimeout(function(){return a.apply(a,d)},b)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(i.call(arguments,1)))};b.throttle=function(a,c){var d,e,f,g,h,i=b.debounce(function(){h=g=false},c);return function(){d=this;e=arguments;var b;f||(f=setTimeout(function(){f=null;h&&a.apply(d,e);i()},c));g?h=true:
-a.apply(d,e);i();g=true}};b.debounce=function(a,b){var d;return function(){var e=this,f=arguments;clearTimeout(d);d=setTimeout(function(){d=null;a.apply(e,f)},b)}};b.once=function(a){var b=false,d;return function(){if(b)return d;b=true;return d=a.apply(this,arguments)}};b.wrap=function(a,b){return function(){var d=[a].concat(i.call(arguments,0));return b.apply(this,d)}};b.compose=function(){var a=arguments;return function(){for(var b=arguments,d=a.length-1;d>=0;d--)b=[a[d].apply(this,b)];return b[0]}};
-b.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=J||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var c=[],d;for(d in a)b.has(a,d)&&(c[c.length]=d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&c.push(d);return c.sort()};b.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]=b[d]});return a};b.defaults=function(a){j(i.call(arguments,
-1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,b){return q(a,b,[])};b.isEmpty=function(a){if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(b.has(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=o||function(a){return l.call(a)=="[object Array]"};b.isObject=function(a){return a===Object(a)};
-b.isArguments=function(a){return l.call(a)=="[object Arguments]"};if(!b.isArguments(arguments))b.isArguments=function(a){return!(!a||!b.has(a,"callee"))};b.isFunction=function(a){return l.call(a)=="[object Function]"};b.isString=function(a){return l.call(a)=="[object String]"};b.isNumber=function(a){return l.call(a)=="[object Number]"};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||l.call(a)=="[object Boolean]"};b.isDate=function(a){return l.call(a)=="[object Date]"};
-b.isRegExp=function(a){return l.call(a)=="[object RegExp]"};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.has=function(a,b){return I.call(a,b)};b.noConflict=function(){r._=G;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e<a;e++)b.call(d,e)};b.escape=function(a){return(""+a).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#x27;").replace(/\//g,"&#x2F;")};b.mixin=function(a){j(b.functions(a),
-function(c){K(c,b[c]=a[c])})};var L=0;b.uniqueId=function(a){var b=L++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var t=/.^/,u=function(a){return a.replace(/\\\\/g,"\\").replace(/\\'/g,"'")};b.template=function(a,c){var d=b.templateSettings,d="var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('"+a.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(d.escape||t,function(a,b){return"',_.escape("+
-u(b)+"),'"}).replace(d.interpolate||t,function(a,b){return"',"+u(b)+",'"}).replace(d.evaluate||t,function(a,b){return"');"+u(b).replace(/[\r\n\t]/g," ")+";__p.push('"}).replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t")+"');}return __p.join('');",e=new Function("obj","_",d);return c?e(c,b):function(a){return e.call(this,a,b)}};b.chain=function(a){return b(a).chain()};var m=function(a){this._wrapped=a};b.prototype=m.prototype;var v=function(a,c){return c?b(a).chain():a},K=function(a,c){m.prototype[a]=
-function(){var a=i.call(arguments);H.call(a,this._wrapped);return v(c.apply(b,a),this._chain)}};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=k[a];m.prototype[a]=function(){var d=this._wrapped;b.apply(d,arguments);var e=d.length;(a=="shift"||a=="splice")&&e===0&&delete d[0];return v(d,this._chain)}});j(["concat","join","slice"],function(a){var b=k[a];m.prototype[a]=function(){return v(b.apply(this._wrapped,arguments),this._chain)}});m.prototype.chain=function(){this._chain=
-true;return this};m.prototype.value=function(){return this._wrapped}}).call(this);
+!function(n,r){"object"==typeof exports&&"undefined"!=typeof module?module.exports=r():"function"==typeof define&&define.amd?define("underscore",r):(n="undefined"!=typeof globalThis?globalThis:n||self,function(){var t=n._,e=n._=r();e.noConflict=function(){return n._=t,e}}())}(this,(function(){
+//     Underscore.js 1.13.1
+//     https://underscorejs.org
+//     (c) 2009-2021 Jeremy Ashkenas, Julian Gonggrijp, and DocumentCloud and Investigative Reporters & Editors
+//     Underscore may be freely distributed under the MIT license.
+var n="1.13.1",r="object"==typeof self&&self.self===self&&self||"object"==typeof global&&global.global===global&&global||Function("return this")()||{},t=Array.prototype,e=Object.prototype,u="undefined"!=typeof Symbol?Symbol.prototype:null,o=t.push,i=t.slice,a=e.toString,f=e.hasOwnProperty,c="undefined"!=typeof ArrayBuffer,l="undefined"!=typeof DataView,s=Array.isArray,p=Object.keys,v=Object.create,h=c&&ArrayBuffer.isView,y=isNaN,d=isFinite,g=!{toString:null}.propertyIsEnumerable("toString"),b=["valueOf","isPrototypeOf","toString","propertyIsEnumerable","hasOwnProperty","toLocaleString"],m=Math.pow(2,53)-1;function j(n,r){return r=null==r?n.length-1:+r,function(){for(var t=Math.max(arguments.length-r,0),e=Array(t),u=0;u<t;u++)e[u]=arguments[u+r];switch(r){case 0:return n.call(this,e);case 1:return n.call(this,arguments[0],e);case 2:return n.call(this,arguments[0],arguments[1],e)}var o=Array(r+1);for(u=0;u<r;u++)o[u]=arguments[u];return o[r]=e,n.apply(this,o)}}function _(n){var r=typeof n;return"function"===r||"object"===r&&!!n}function w(n){return void 0===n}function A(n){return!0===n||!1===n||"[object Boolean]"===a.call(n)}function x(n){var r="[object "+n+"]";return function(n){return a.call(n)===r}}var S=x("String"),O=x("Number"),M=x("Date"),E=x("RegExp"),B=x("Error"),N=x("Symbol"),I=x("ArrayBuffer"),T=x("Function"),k=r.document&&r.document.childNodes;"function"!=typeof/./&&"object"!=typeof Int8Array&&"function"!=typeof k&&(T=function(n){return"function"==typeof n||!1});var D=T,R=x("Object"),F=l&&R(new DataView(new ArrayBuffer(8))),V="undefined"!=typeof Map&&R(new Map),P=x("DataView");var q=F?function(n){return null!=n&&D(n.getInt8)&&I(n.buffer)}:P,U=s||x("Array");function W(n,r){return null!=n&&f.call(n,r)}var z=x("Arguments");!function(){z(arguments)||(z=function(n){return W(n,"callee")})}();var L=z;function $(n){return O(n)&&y(n)}function C(n){return function(){return n}}function K(n){return function(r){var t=n(r);return"number"==typeof t&&t>=0&&t<=m}}function J(n){return function(r){return null==r?void 0:r[n]}}var G=J("byteLength"),H=K(G),Q=/\[object ((I|Ui)nt(8|16|32)|Float(32|64)|Uint8Clamped|Big(I|Ui)nt64)Array\]/;var X=c?function(n){return h?h(n)&&!q(n):H(n)&&Q.test(a.call(n))}:C(!1),Y=J("length");function Z(n,r){r=function(n){for(var r={},t=n.length,e=0;e<t;++e)r[n[e]]=!0;return{contains:function(n){return r[n]},push:function(t){return r[t]=!0,n.push(t)}}}(r);var t=b.length,u=n.constructor,o=D(u)&&u.prototype||e,i="constructor";for(W(n,i)&&!r.contains(i)&&r.push(i);t--;)(i=b[t])in n&&n[i]!==o[i]&&!r.contains(i)&&r.push(i)}function nn(n){if(!_(n))return[];if(p)return p(n);var r=[];for(var t in n)W(n,t)&&r.push(t);return g&&Z(n,r),r}function rn(n,r){var t=nn(r),e=t.length;if(null==n)return!e;for(var u=Object(n),o=0;o<e;o++){var i=t[o];if(r[i]!==u[i]||!(i in u))return!1}return!0}function tn(n){return n instanceof tn?n:this instanceof tn?void(this._wrapped=n):new tn(n)}function en(n){return new Uint8Array(n.buffer||n,n.byteOffset||0,G(n))}tn.VERSION=n,tn.prototype.value=function(){return this._wrapped},tn.prototype.valueOf=tn.prototype.toJSON=tn.prototype.value,tn.prototype.toString=function(){return String(this._wrapped)};var un="[object DataView]";function on(n,r,t,e){if(n===r)return 0!==n||1/n==1/r;if(null==n||null==r)return!1;if(n!=n)return r!=r;var o=typeof n;return("function"===o||"object"===o||"object"==typeof r)&&function n(r,t,e,o){r instanceof tn&&(r=r._wrapped);t instanceof tn&&(t=t._wrapped);var i=a.call(r);if(i!==a.call(t))return!1;if(F&&"[object Object]"==i&&q(r)){if(!q(t))return!1;i=un}switch(i){case"[object RegExp]":case"[object String]":return""+r==""+t;case"[object Number]":return+r!=+r?+t!=+t:0==+r?1/+r==1/t:+r==+t;case"[object Date]":case"[object Boolean]":return+r==+t;case"[object Symbol]":return u.valueOf.call(r)===u.valueOf.call(t);case"[object ArrayBuffer]":case un:return n(en(r),en(t),e,o)}var f="[object Array]"===i;if(!f&&X(r)){if(G(r)!==G(t))return!1;if(r.buffer===t.buffer&&r.byteOffset===t.byteOffset)return!0;f=!0}if(!f){if("object"!=typeof r||"object"!=typeof t)return!1;var c=r.constructor,l=t.constructor;if(c!==l&&!(D(c)&&c instanceof c&&D(l)&&l instanceof l)&&"constructor"in r&&"constructor"in t)return!1}o=o||[];var s=(e=e||[]).length;for(;s--;)if(e[s]===r)return o[s]===t;if(e.push(r),o.push(t),f){if((s=r.length)!==t.length)return!1;for(;s--;)if(!on(r[s],t[s],e,o))return!1}else{var p,v=nn(r);if(s=v.length,nn(t).length!==s)return!1;for(;s--;)if(p=v[s],!W(t,p)||!on(r[p],t[p],e,o))return!1}return e.pop(),o.pop(),!0}(n,r,t,e)}function an(n){if(!_(n))return[];var r=[];for(var t in n)r.push(t);return g&&Z(n,r),r}function fn(n){var r=Y(n);return function(t){if(null==t)return!1;var e=an(t);if(Y(e))return!1;for(var u=0;u<r;u++)if(!D(t[n[u]]))return!1;return n!==hn||!D(t[cn])}}var cn="forEach",ln="has",sn=["clear","delete"],pn=["get",ln,"set"],vn=sn.concat(cn,pn),hn=sn.concat(pn),yn=["add"].concat(sn,cn,ln),dn=V?fn(vn):x("Map"),gn=V?fn(hn):x("WeakMap"),bn=V?fn(yn):x("Set"),mn=x("WeakSet");function jn(n){for(var r=nn(n),t=r.length,e=Array(t),u=0;u<t;u++)e[u]=n[r[u]];return e}function _n(n){for(var r={},t=nn(n),e=0,u=t.length;e<u;e++)r[n[t[e]]]=t[e];return r}function wn(n){var r=[];for(var t in n)D(n[t])&&r.push(t);return r.sort()}function An(n,r){return function(t){var e=arguments.length;if(r&&(t=Object(t)),e<2||null==t)return t;for(var u=1;u<e;u++)for(var o=arguments[u],i=n(o),a=i.length,f=0;f<a;f++){var c=i[f];r&&void 0!==t[c]||(t[c]=o[c])}return t}}var xn=An(an),Sn=An(nn),On=An(an,!0);function Mn(n){if(!_(n))return{};if(v)return v(n);var r=function(){};r.prototype=n;var t=new r;return r.prototype=null,t}function En(n){return _(n)?U(n)?n.slice():xn({},n):n}function Bn(n){return U(n)?n:[n]}function Nn(n){return tn.toPath(n)}function In(n,r){for(var t=r.length,e=0;e<t;e++){if(null==n)return;n=n[r[e]]}return t?n:void 0}function Tn(n,r,t){var e=In(n,Nn(r));return w(e)?t:e}function kn(n){return n}function Dn(n){return n=Sn({},n),function(r){return rn(r,n)}}function Rn(n){return n=Nn(n),function(r){return In(r,n)}}function Fn(n,r,t){if(void 0===r)return n;switch(null==t?3:t){case 1:return function(t){return n.call(r,t)};case 3:return function(t,e,u){return n.call(r,t,e,u)};case 4:return function(t,e,u,o){return n.call(r,t,e,u,o)}}return function(){return n.apply(r,arguments)}}function Vn(n,r,t){return null==n?kn:D(n)?Fn(n,r,t):_(n)&&!U(n)?Dn(n):Rn(n)}function Pn(n,r){return Vn(n,r,1/0)}function qn(n,r,t){return tn.iteratee!==Pn?tn.iteratee(n,r):Vn(n,r,t)}function Un(){}function Wn(n,r){return null==r&&(r=n,n=0),n+Math.floor(Math.random()*(r-n+1))}tn.toPath=Bn,tn.iteratee=Pn;var zn=Date.now||function(){return(new Date).getTime()};function Ln(n){var r=function(r){return n[r]},t="(?:"+nn(n).join("|")+")",e=RegExp(t),u=RegExp(t,"g");return function(n){return n=null==n?"":""+n,e.test(n)?n.replace(u,r):n}}var $n={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;","`":"&#x60;"},Cn=Ln($n),Kn=Ln(_n($n)),Jn=tn.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g},Gn=/(.)^/,Hn={"'":"'","\\":"\\","\r":"r","\n":"n","\u2028":"u2028","\u2029":"u2029"},Qn=/\\|'|\r|\n|\u2028|\u2029/g;function Xn(n){return"\\"+Hn[n]}var Yn=/^\s*(\w|\$)+\s*$/;var Zn=0;function nr(n,r,t,e,u){if(!(e instanceof r))return n.apply(t,u);var o=Mn(n.prototype),i=n.apply(o,u);return _(i)?i:o}var rr=j((function(n,r){var t=rr.placeholder,e=function(){for(var u=0,o=r.length,i=Array(o),a=0;a<o;a++)i[a]=r[a]===t?arguments[u++]:r[a];for(;u<arguments.length;)i.push(arguments[u++]);return nr(n,e,this,this,i)};return e}));rr.placeholder=tn;var tr=j((function(n,r,t){if(!D(n))throw new TypeError("Bind must be called on a function");var e=j((function(u){return nr(n,e,r,this,t.concat(u))}));return e})),er=K(Y);function ur(n,r,t,e){if(e=e||[],r||0===r){if(r<=0)return e.concat(n)}else r=1/0;for(var u=e.length,o=0,i=Y(n);o<i;o++){var a=n[o];if(er(a)&&(U(a)||L(a)))if(r>1)ur(a,r-1,t,e),u=e.length;else for(var f=0,c=a.length;f<c;)e[u++]=a[f++];else t||(e[u++]=a)}return e}var or=j((function(n,r){var t=(r=ur(r,!1,!1)).length;if(t<1)throw new Error("bindAll must be passed function names");for(;t--;){var e=r[t];n[e]=tr(n[e],n)}return n}));var ir=j((function(n,r,t){return setTimeout((function(){return n.apply(null,t)}),r)})),ar=rr(ir,tn,1);function fr(n){return function(){return!n.apply(this,arguments)}}function cr(n,r){var t;return function(){return--n>0&&(t=r.apply(this,arguments)),n<=1&&(r=null),t}}var lr=rr(cr,2);function sr(n,r,t){r=qn(r,t);for(var e,u=nn(n),o=0,i=u.length;o<i;o++)if(r(n[e=u[o]],e,n))return e}function pr(n){return function(r,t,e){t=qn(t,e);for(var u=Y(r),o=n>0?0:u-1;o>=0&&o<u;o+=n)if(t(r[o],o,r))return o;return-1}}var vr=pr(1),hr=pr(-1);function yr(n,r,t,e){for(var u=(t=qn(t,e,1))(r),o=0,i=Y(n);o<i;){var a=Math.floor((o+i)/2);t(n[a])<u?o=a+1:i=a}return o}function dr(n,r,t){return function(e,u,o){var a=0,f=Y(e);if("number"==typeof o)n>0?a=o>=0?o:Math.max(o+f,a):f=o>=0?Math.min(o+1,f):o+f+1;else if(t&&o&&f)return e[o=t(e,u)]===u?o:-1;if(u!=u)return(o=r(i.call(e,a,f),$))>=0?o+a:-1;for(o=n>0?a:f-1;o>=0&&o<f;o+=n)if(e[o]===u)return o;return-1}}var gr=dr(1,vr,yr),br=dr(-1,hr);function mr(n,r,t){var e=(er(n)?vr:sr)(n,r,t);if(void 0!==e&&-1!==e)return n[e]}function jr(n,r,t){var e,u;if(r=Fn(r,t),er(n))for(e=0,u=n.length;e<u;e++)r(n[e],e,n);else{var o=nn(n);for(e=0,u=o.length;e<u;e++)r(n[o[e]],o[e],n)}return n}function _r(n,r,t){r=qn(r,t);for(var e=!er(n)&&nn(n),u=(e||n).length,o=Array(u),i=0;i<u;i++){var a=e?e[i]:i;o[i]=r(n[a],a,n)}return o}function wr(n){var r=function(r,t,e,u){var o=!er(r)&&nn(r),i=(o||r).length,a=n>0?0:i-1;for(u||(e=r[o?o[a]:a],a+=n);a>=0&&a<i;a+=n){var f=o?o[a]:a;e=t(e,r[f],f,r)}return e};return function(n,t,e,u){var o=arguments.length>=3;return r(n,Fn(t,u,4),e,o)}}var Ar=wr(1),xr=wr(-1);function Sr(n,r,t){var e=[];return r=qn(r,t),jr(n,(function(n,t,u){r(n,t,u)&&e.push(n)})),e}function Or(n,r,t){r=qn(r,t);for(var e=!er(n)&&nn(n),u=(e||n).length,o=0;o<u;o++){var i=e?e[o]:o;if(!r(n[i],i,n))return!1}return!0}function Mr(n,r,t){r=qn(r,t);for(var e=!er(n)&&nn(n),u=(e||n).length,o=0;o<u;o++){var i=e?e[o]:o;if(r(n[i],i,n))return!0}return!1}function Er(n,r,t,e){return er(n)||(n=jn(n)),("number"!=typeof t||e)&&(t=0),gr(n,r,t)>=0}var Br=j((function(n,r,t){var e,u;return D(r)?u=r:(r=Nn(r),e=r.slice(0,-1),r=r[r.length-1]),_r(n,(function(n){var o=u;if(!o){if(e&&e.length&&(n=In(n,e)),null==n)return;o=n[r]}return null==o?o:o.apply(n,t)}))}));function Nr(n,r){return _r(n,Rn(r))}function Ir(n,r,t){var e,u,o=-1/0,i=-1/0;if(null==r||"number"==typeof r&&"object"!=typeof n[0]&&null!=n)for(var a=0,f=(n=er(n)?n:jn(n)).length;a<f;a++)null!=(e=n[a])&&e>o&&(o=e);else r=qn(r,t),jr(n,(function(n,t,e){((u=r(n,t,e))>i||u===-1/0&&o===-1/0)&&(o=n,i=u)}));return o}function Tr(n,r,t){if(null==r||t)return er(n)||(n=jn(n)),n[Wn(n.length-1)];var e=er(n)?En(n):jn(n),u=Y(e);r=Math.max(Math.min(r,u),0);for(var o=u-1,i=0;i<r;i++){var a=Wn(i,o),f=e[i];e[i]=e[a],e[a]=f}return e.slice(0,r)}function kr(n,r){return function(t,e,u){var o=r?[[],[]]:{};return e=qn(e,u),jr(t,(function(r,u){var i=e(r,u,t);n(o,r,i)})),o}}var Dr=kr((function(n,r,t){W(n,t)?n[t].push(r):n[t]=[r]})),Rr=kr((function(n,r,t){n[t]=r})),Fr=kr((function(n,r,t){W(n,t)?n[t]++:n[t]=1})),Vr=kr((function(n,r,t){n[t?0:1].push(r)}),!0),Pr=/[^\ud800-\udfff]|[\ud800-\udbff][\udc00-\udfff]|[\ud800-\udfff]/g;function qr(n,r,t){return r in t}var Ur=j((function(n,r){var t={},e=r[0];if(null==n)return t;D(e)?(r.length>1&&(e=Fn(e,r[1])),r=an(n)):(e=qr,r=ur(r,!1,!1),n=Object(n));for(var u=0,o=r.length;u<o;u++){var i=r[u],a=n[i];e(a,i,n)&&(t[i]=a)}return t})),Wr=j((function(n,r){var t,e=r[0];return D(e)?(e=fr(e),r.length>1&&(t=r[1])):(r=_r(ur(r,!1,!1),String),e=function(n,t){return!Er(r,t)}),Ur(n,e,t)}));function zr(n,r,t){return i.call(n,0,Math.max(0,n.length-(null==r||t?1:r)))}function Lr(n,r,t){return null==n||n.length<1?null==r||t?void 0:[]:null==r||t?n[0]:zr(n,n.length-r)}function $r(n,r,t){return i.call(n,null==r||t?1:r)}var Cr=j((function(n,r){return r=ur(r,!0,!0),Sr(n,(function(n){return!Er(r,n)}))})),Kr=j((function(n,r){return Cr(n,r)}));function Jr(n,r,t,e){A(r)||(e=t,t=r,r=!1),null!=t&&(t=qn(t,e));for(var u=[],o=[],i=0,a=Y(n);i<a;i++){var f=n[i],c=t?t(f,i,n):f;r&&!t?(i&&o===c||u.push(f),o=c):t?Er(o,c)||(o.push(c),u.push(f)):Er(u,f)||u.push(f)}return u}var Gr=j((function(n){return Jr(ur(n,!0,!0))}));function Hr(n){for(var r=n&&Ir(n,Y).length||0,t=Array(r),e=0;e<r;e++)t[e]=Nr(n,e);return t}var Qr=j(Hr);function Xr(n,r){return n._chain?tn(r).chain():r}function Yr(n){return jr(wn(n),(function(r){var t=tn[r]=n[r];tn.prototype[r]=function(){var n=[this._wrapped];return o.apply(n,arguments),Xr(this,t.apply(tn,n))}})),tn}jr(["pop","push","reverse","shift","sort","splice","unshift"],(function(n){var r=t[n];tn.prototype[n]=function(){var t=this._wrapped;return null!=t&&(r.apply(t,arguments),"shift"!==n&&"splice"!==n||0!==t.length||delete t[0]),Xr(this,t)}})),jr(["concat","join","slice"],(function(n){var r=t[n];tn.prototype[n]=function(){var n=this._wrapped;return null!=n&&(n=r.apply(n,arguments)),Xr(this,n)}}));var Zr=Yr({__proto__:null,VERSION:n,restArguments:j,isObject:_,isNull:function(n){return null===n},isUndefined:w,isBoolean:A,isElement:function(n){return!(!n||1!==n.nodeType)},isString:S,isNumber:O,isDate:M,isRegExp:E,isError:B,isSymbol:N,isArrayBuffer:I,isDataView:q,isArray:U,isFunction:D,isArguments:L,isFinite:function(n){return!N(n)&&d(n)&&!isNaN(parseFloat(n))},isNaN:$,isTypedArray:X,isEmpty:function(n){if(null==n)return!0;var r=Y(n);return"number"==typeof r&&(U(n)||S(n)||L(n))?0===r:0===Y(nn(n))},isMatch:rn,isEqual:function(n,r){return on(n,r)},isMap:dn,isWeakMap:gn,isSet:bn,isWeakSet:mn,keys:nn,allKeys:an,values:jn,pairs:function(n){for(var r=nn(n),t=r.length,e=Array(t),u=0;u<t;u++)e[u]=[r[u],n[r[u]]];return e},invert:_n,functions:wn,methods:wn,extend:xn,extendOwn:Sn,assign:Sn,defaults:On,create:function(n,r){var t=Mn(n);return r&&Sn(t,r),t},clone:En,tap:function(n,r){return r(n),n},get:Tn,has:function(n,r){for(var t=(r=Nn(r)).length,e=0;e<t;e++){var u=r[e];if(!W(n,u))return!1;n=n[u]}return!!t},mapObject:function(n,r,t){r=qn(r,t);for(var e=nn(n),u=e.length,o={},i=0;i<u;i++){var a=e[i];o[a]=r(n[a],a,n)}return o},identity:kn,constant:C,noop:Un,toPath:Bn,property:Rn,propertyOf:function(n){return null==n?Un:function(r){return Tn(n,r)}},matcher:Dn,matches:Dn,times:function(n,r,t){var e=Array(Math.max(0,n));r=Fn(r,t,1);for(var u=0;u<n;u++)e[u]=r(u);return e},random:Wn,now:zn,escape:Cn,unescape:Kn,templateSettings:Jn,template:function(n,r,t){!r&&t&&(r=t),r=On({},r,tn.templateSettings);var e=RegExp([(r.escape||Gn).source,(r.interpolate||Gn).source,(r.evaluate||Gn).source].join("|")+"|$","g"),u=0,o="__p+='";n.replace(e,(function(r,t,e,i,a){return o+=n.slice(u,a).replace(Qn,Xn),u=a+r.length,t?o+="'+\n((__t=("+t+"))==null?'':_.escape(__t))+\n'":e?o+="'+\n((__t=("+e+"))==null?'':__t)+\n'":i&&(o+="';\n"+i+"\n__p+='"),r})),o+="';\n";var i,a=r.variable;if(a){if(!Yn.test(a))throw new Error("variable is not a bare identifier: "+a)}else o="with(obj||{}){\n"+o+"}\n",a="obj";o="var __t,__p='',__j=Array.prototype.join,"+"print=function(){__p+=__j.call(arguments,'');};\n"+o+"return __p;\n";try{i=new Function(a,"_",o)}catch(n){throw n.source=o,n}var f=function(n){return i.call(this,n,tn)};return f.source="function("+a+"){\n"+o+"}",f},result:function(n,r,t){var e=(r=Nn(r)).length;if(!e)return D(t)?t.call(n):t;for(var u=0;u<e;u++){var o=null==n?void 0:n[r[u]];void 0===o&&(o=t,u=e),n=D(o)?o.call(n):o}return n},uniqueId:function(n){var r=++Zn+"";return n?n+r:r},chain:function(n){var r=tn(n);return r._chain=!0,r},iteratee:Pn,partial:rr,bind:tr,bindAll:or,memoize:function(n,r){var t=function(e){var u=t.cache,o=""+(r?r.apply(this,arguments):e);return W(u,o)||(u[o]=n.apply(this,arguments)),u[o]};return t.cache={},t},delay:ir,defer:ar,throttle:function(n,r,t){var e,u,o,i,a=0;t||(t={});var f=function(){a=!1===t.leading?0:zn(),e=null,i=n.apply(u,o),e||(u=o=null)},c=function(){var c=zn();a||!1!==t.leading||(a=c);var l=r-(c-a);return u=this,o=arguments,l<=0||l>r?(e&&(clearTimeout(e),e=null),a=c,i=n.apply(u,o),e||(u=o=null)):e||!1===t.trailing||(e=setTimeout(f,l)),i};return c.cancel=function(){clearTimeout(e),a=0,e=u=o=null},c},debounce:function(n,r,t){var e,u,o,i,a,f=function(){var c=zn()-u;r>c?e=setTimeout(f,r-c):(e=null,t||(i=n.apply(a,o)),e||(o=a=null))},c=j((function(c){return a=this,o=c,u=zn(),e||(e=setTimeout(f,r),t&&(i=n.apply(a,o))),i}));return c.cancel=function(){clearTimeout(e),e=o=a=null},c},wrap:function(n,r){return rr(r,n)},negate:fr,compose:function(){var n=arguments,r=n.length-1;return function(){for(var t=r,e=n[r].apply(this,arguments);t--;)e=n[t].call(this,e);return e}},after:function(n,r){return function(){if(--n<1)return r.apply(this,arguments)}},before:cr,once:lr,findKey:sr,findIndex:vr,findLastIndex:hr,sortedIndex:yr,indexOf:gr,lastIndexOf:br,find:mr,detect:mr,findWhere:function(n,r){return mr(n,Dn(r))},each:jr,forEach:jr,map:_r,collect:_r,reduce:Ar,foldl:Ar,inject:Ar,reduceRight:xr,foldr:xr,filter:Sr,select:Sr,reject:function(n,r,t){return Sr(n,fr(qn(r)),t)},every:Or,all:Or,some:Mr,any:Mr,contains:Er,includes:Er,include:Er,invoke:Br,pluck:Nr,where:function(n,r){return Sr(n,Dn(r))},max:Ir,min:function(n,r,t){var e,u,o=1/0,i=1/0;if(null==r||"number"==typeof r&&"object"!=typeof n[0]&&null!=n)for(var a=0,f=(n=er(n)?n:jn(n)).length;a<f;a++)null!=(e=n[a])&&e<o&&(o=e);else r=qn(r,t),jr(n,(function(n,t,e){((u=r(n,t,e))<i||u===1/0&&o===1/0)&&(o=n,i=u)}));return o},shuffle:function(n){return Tr(n,1/0)},sample:Tr,sortBy:function(n,r,t){var e=0;return r=qn(r,t),Nr(_r(n,(function(n,t,u){return{value:n,index:e++,criteria:r(n,t,u)}})).sort((function(n,r){var t=n.criteria,e=r.criteria;if(t!==e){if(t>e||void 0===t)return 1;if(t<e||void 0===e)return-1}return n.index-r.index})),"value")},groupBy:Dr,indexBy:Rr,countBy:Fr,partition:Vr,toArray:function(n){return n?U(n)?i.call(n):S(n)?n.match(Pr):er(n)?_r(n,kn):jn(n):[]},size:function(n){return null==n?0:er(n)?n.length:nn(n).length},pick:Ur,omit:Wr,first:Lr,head:Lr,take:Lr,initial:zr,last:function(n,r,t){return null==n||n.length<1?null==r||t?void 0:[]:null==r||t?n[n.length-1]:$r(n,Math.max(0,n.length-r))},rest:$r,tail:$r,drop:$r,compact:function(n){return Sr(n,Boolean)},flatten:function(n,r){return ur(n,r,!1)},without:Kr,uniq:Jr,unique:Jr,union:Gr,intersection:function(n){for(var r=[],t=arguments.length,e=0,u=Y(n);e<u;e++){var o=n[e];if(!Er(r,o)){var i;for(i=1;i<t&&Er(arguments[i],o);i++);i===t&&r.push(o)}}return r},difference:Cr,unzip:Hr,transpose:Hr,zip:Qr,object:function(n,r){for(var t={},e=0,u=Y(n);e<u;e++)r?t[n[e]]=r[e]:t[n[e][0]]=n[e][1];return t},range:function(n,r,t){null==r&&(r=n||0,n=0),t||(t=r<n?-1:1);for(var e=Math.max(Math.ceil((r-n)/t),0),u=Array(e),o=0;o<e;o++,n+=t)u[o]=n;return u},chunk:function(n,r){if(null==r||r<1)return[];for(var t=[],e=0,u=n.length;e<u;)t.push(i.call(n,e,e+=r));return t},mixin:Yr,default:tn});return Zr._=Zr,Zr}));
\ No newline at end of file
diff --git a/public/genindex.html b/public/genindex.html
index a36aeebe725209c6247072beda87796a27fae559..672b424b4b3542d0efeeb07707a0e565ebe7e2ea 100644
--- a/public/genindex.html
+++ b/public/genindex.html
@@ -13,6 +13,8 @@
   
   <link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
   <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+  <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+  <link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
 
   
   
@@ -26,11 +28,10 @@
   
     
       <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
+        <script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
         <script src="_static/jquery.js"></script>
         <script src="_static/underscore.js"></script>
         <script src="_static/doctools.js"></script>
-        <script src="_static/language_data.js"></script>
-        <script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
     
     <script type="text/javascript" src="_static/js/theme.js"></script>
 
@@ -85,6 +86,7 @@
 <li class="toctree-l1"><a class="reference internal" href="Ohmpi.html">OhmPi project</a></li>
 <li class="toctree-l1"><a class="reference internal" href="V1_01.html">OhmPi V 1.01 (limited to 32 electrodes)</a></li>
 <li class="toctree-l1"><a class="reference internal" href="V1_02.html">OhmPi V 1.02 (limited to 32 electrodes)</a></li>
+<li class="toctree-l1"><a class="reference internal" href="V2_00.html">OhmPi V 2.00 (64 or 128 électrodes)</a></li>
 </ul>
 
             
diff --git a/public/index.html b/public/index.html
index a6f0bead716a16397ad7ed42b71cc7cf12e50b7e..205714867bba948a44e81ba892bb8b64fb6d6a20 100644
--- a/public/index.html
+++ b/public/index.html
@@ -4,7 +4,8 @@
 <html class="writer-html5" lang="en" >
 <head>
   <meta charset="utf-8">
-  
+  <meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
+
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   
   <title>OHMPI: Open source and open hardware resitivity-meter &mdash; Ohmpi: open hardware resistivity-meter documentation</title>
@@ -13,6 +14,8 @@
   
   <link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
   <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+  <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+  <link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
 
   
   
@@ -26,11 +29,10 @@
   
     
       <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
+        <script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
         <script src="_static/jquery.js"></script>
         <script src="_static/underscore.js"></script>
         <script src="_static/doctools.js"></script>
-        <script src="_static/language_data.js"></script>
-        <script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
     
     <script type="text/javascript" src="_static/js/theme.js"></script>
 
@@ -86,6 +88,7 @@
 <li class="toctree-l1"><a class="reference internal" href="Ohmpi.html">OhmPi project</a></li>
 <li class="toctree-l1"><a class="reference internal" href="V1_01.html">OhmPi V 1.01 (limited to 32 electrodes)</a></li>
 <li class="toctree-l1"><a class="reference internal" href="V1_02.html">OhmPi V 1.02 (limited to 32 electrodes)</a></li>
+<li class="toctree-l1"><a class="reference internal" href="V2_00.html">OhmPi V 2.00 (64 or 128 électrodes)</a></li>
 </ul>
 
             
@@ -151,16 +154,16 @@
           <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
            <div itemprop="articleBody">
             
-  <div class="section" id="ohmpi-open-source-and-open-hardware-resitivity-meter">
+  <section id="ohmpi-open-source-and-open-hardware-resitivity-meter">
 <h1>OHMPI: Open source and open hardware resitivity-meter<a class="headerlink" href="#ohmpi-open-source-and-open-hardware-resitivity-meter" title="Permalink to this headline">¶</a></h1>
-<div class="sidebar">
+<aside class="sidebar">
 <p class="sidebar-title">Summary</p>
 <dl class="field-list simple">
 <dt class="field-odd">Release</dt>
 <dd class="field-odd"><p>open hardware resistivity-meter</p>
 </dd>
 <dt class="field-even">Date</dt>
-<dd class="field-even"><p>Dec 21, 2020</p>
+<dd class="field-even"><p>Jul 14, 2021</p>
 </dd>
 <dt class="field-odd">Date start</dt>
 <dd class="field-odd"><p>July 2016</p>
@@ -175,7 +178,7 @@
 <dd class="field-even"><p>some mature, some in progress</p>
 </dd>
 </dl>
-</div>
+</aside>
 <div class="topic">
 <p class="topic-title">OhmPi Document Center</p>
 <ul class="simple">
@@ -214,9 +217,16 @@
 <li class="toctree-l2"><a class="reference internal" href="V1_02.html#complete-list-of-components">Complete list of components</a></li>
 </ul>
 </li>
+<li class="toctree-l1"><a class="reference internal" href="V2_00.html">OhmPi V 2.00 (64 or 128 électrodes)</a><ul>
+<li class="toctree-l2"><a class="reference internal" href="V2_00.html#the-philosophy-of-ohmpi">The philosophy of Ohmpi</a></li>
+<li class="toctree-l2"><a class="reference internal" href="V2_00.html#technical-data">Technical data</a></li>
+<li class="toctree-l2"><a class="reference internal" href="V2_00.html#step-n1-raspberry-pi-configuration"><strong>STEP n°1</strong> : Raspberry Pi  configuration</a></li>
+<li class="toctree-l2"><a class="reference internal" href="V2_00.html#step-n2-assembly-of-the-measurement-board"><strong>STEP n°2</strong>: Assembly of the measurement board</a></li>
+</ul>
+</li>
 </ul>
 </div>
-</div>
+</section>
 
 
            </div>
diff --git a/public/objects.inv b/public/objects.inv
index 24b41f4783bf0e931ce294070d61de4d320b133a..b9fc38a78a04c5cbb3ecb4ffbc562fc21525e4af 100644
Binary files a/public/objects.inv and b/public/objects.inv differ
diff --git a/public/search.html b/public/search.html
index e7bba42211069dcc0ef77a3fcd07538eb9a0d4d0..1b855133ac20a0841c8f41bd7e3080ccbf63c43b 100644
--- a/public/search.html
+++ b/public/search.html
@@ -13,6 +13,8 @@
   
   <link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
   <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+  <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+  <link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
 
   
   
@@ -27,11 +29,10 @@
   
     
       <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
+        <script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
         <script src="_static/jquery.js"></script>
         <script src="_static/underscore.js"></script>
         <script src="_static/doctools.js"></script>
-        <script src="_static/language_data.js"></script>
-        <script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
     
     <script type="text/javascript" src="_static/js/theme.js"></script>
 
@@ -87,6 +88,7 @@
 <li class="toctree-l1"><a class="reference internal" href="Ohmpi.html">OhmPi project</a></li>
 <li class="toctree-l1"><a class="reference internal" href="V1_01.html">OhmPi V 1.01 (limited to 32 electrodes)</a></li>
 <li class="toctree-l1"><a class="reference internal" href="V1_02.html">OhmPi V 1.02 (limited to 32 electrodes)</a></li>
+<li class="toctree-l1"><a class="reference internal" href="V2_00.html">OhmPi V 2.00 (64 or 128 électrodes)</a></li>
 </ul>
 
             
diff --git a/public/searchindex.js b/public/searchindex.js
index 97ec4d7972e224644f214529682a81c1eadc925f..9d6839628f172706742555c263ab6283721ba356 100644
--- a/public/searchindex.js
+++ b/public/searchindex.js
@@ -1 +1 @@
-Search.setIndex({docnames:["Ohmpi","V1_01","V1_02","index"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":3,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":2,"sphinx.domains.rst":2,"sphinx.domains.std":1,sphinx:56},filenames:["Ohmpi.rst","V1_01.rst","V1_02.rst","index.rst"],objects:{},objnames:{},objtypes:{},terms:{"100nf":2,"10v":2,"12v":[1,2],"1x0":[1,2],"1x1":[1,2],"1x10":[1,2],"24v":2,"50vdc":2,"5vcc":[1,2],"5vdc":[1,2],"7ah":[1,2],"ao\u00fbt":0,"case":[1,2],"final":[1,2],"function":[0,1,2],"h\u00e9l\u00e8ne":[0,3],"mm\u00b2":[1,2],"new":[1,2],"orl\u00e9an":0,"public":[1,2],"r\u00e9mi":[0,3],"return":[1,2],"switch":[1,2],"universit\u00e9":0,"vid\u00e9o":[1,2],ADS:[1,2],CMS:[1,2],For:[1,2],IGE:0,Its:[1,2],The:3,These:[1,2],With:[1,2],abmn:[1,2],abov:[1,2],acc:[1,2],access:[1,2],accord:[1,2],accur:[1,2],accuraci:[1,2],acid:[1,2],actual:[1,2],adafruit:[1,2],adapt:[1,2],adc:[1,2],add:[1,2],added:[1,2],adding:[1,2],addit:[1,2],address:[1,2],adjust:[1,2],ads1115:[1,2],ads115:[1,2],ads1x15:[1,2],after:[1,2],all:[1,2],allow:[0,1,2],alp:0,also:[1,2],altern:[1,2],amp:[1,2],amplifi:[1,2],analog:[1,2],ani:[1,2],anoth:[1,2],appear:[1,2],appli:[1,2],applic:0,apt:[1,2],arduino:1,arm:1,arrai:[1,2],articl:[1,2],asler:[1,2],assembl:3,assist:[1,2],associ:0,attent:[1,2],attribut:[1,2],author:[0,1,2,3],automat:[0,1,2],automobil:[1,2],avail:[1,2],avr:1,bank:[1,2],base:[1,2],basic:0,batteri:[1,2],been:[1,2],befor:[1,2],behavior:[1,2],being:[1,2],below:[1,2],between:[1,2],bin:[1,2],bit:[1,2],black:[1,2],blinka:[1,2],block:[1,2],blue:[1,2],boot:[1,2],both:[1,2],bottom:[1,2],bought:[1,2],bridg:[1,2],bug:1,build:[1,2],button:[1,2],c320c104k1:2,cabl:[1,2],calcul:[1,2],calibr:[1,2],call:0,can:[1,2],canal:1,cap:[1,2],capac:[1,2],capacitor:2,car:1,card:3,carri:[1,2],caus:[1,2],cedex:0,ceram:2,channel:[1,2],characterist:[1,2],charg:[1,2],check:[1,2],chosen:[1,2],circuit:[1,2],circuitpython:[1,2],circul:[1,2],clean:[1,2],clement:[0,3],click:[1,2],close:[1,2],code:[1,2],coef_p0:[1,2],coef_p1:[1,2],coef_p2:[1,2],coef_p3:[1,2],coeff:[1,2],coeffici:[1,2],com:[1,2],command:[1,2],commerci:[1,2],common:[1,2],commun:0,complet:3,compon:3,comput:[1,2],conduct:[1,2],config:[1,2],configur:3,congratul:[1,2],connect:3,connector:[1,2],consequ:[1,2],consist:[1,2],constitut:[1,2],construct:[1,2],consumpt:[1,2],contact:[1,2],contain:[1,2],content:3,control:[1,2],convers:[1,2],convert:[1,2],correct:[1,2],correspond:1,cost:[0,1,2],could:[1,2],cpu:[1,2],creat:[1,2],creation:0,crimp:[1,2],csv:[1,2],ctrl:[1,2],current:[0,3],damag:[1,2],data:[0,3],date:[0,1,2,3],dcconvert:2,deactiv:[1,2],dec:3,decid:[1,2],decoupl:2,dedic:0,delai:[1,2],deliv:[1,2],depend:[1,2],describ:[1,2],design:[1,2],desktop:2,despit:[1,2],detail:1,dev:[1,2],develop:[0,1,2,3],diagram:[1,2],differ:[1,2],digit:[1,2],din:[1,2],direct:[1,2],directli:[1,2],directori:[1,2],disconnect:[1,2],displai:[1,2],distanc:[1,2],disturb:[1,2],divid:[1,2],document:[0,1],done:[1,2],down:[1,2],download:[1,2],dsp:1,dual:[1,2],duboi:[0,3],durat:[1,2],dure:[1,2],dzwb4:[1,2],e00122ff:0,each:[1,2],editor:[1,2],eiffel:0,either:[1,2],electr:0,electrod:[0,3],electron:[1,2],elsevi:0,emil:0,enabl:[1,2],end:[1,2],energ:[1,2],enough:[1,2],ensur:[1,2],enter:[1,2],entir:[1,2],environ:[1,2],environnementshould:[1,2],equal:[1,2],equival:[1,2],ert:[1,2],escap:[1,2],estim:[1,2],everyon:0,evolv:[1,2],exampl:[1,2],excess:[1,2],execut:[1,2],exist:[1,2],experi:[0,1,2],explain:1,export_path:2,extra:[1,2],failur:[1,2],fargier:[0,3],fast:2,featur:[1,2],femal:[1,2],ferrul:[1,2],fewer:[1,2],ff10:0,fhac0002zxj:1,field:[1,2],fig:[1,2],figur:[1,2],file:[1,2],find:[1,2],first:[1,2],flexibl:0,florsch:[1,2],flow:[1,2],folder:[1,2],follow:[1,2],forquet:[0,3],framework:[1,2],franc:0,from:[1,2],full:[1,2],fulli:0,fuse:[1,2],gain:[1,2],ganc:[0,3],gather:[1,2],gener:[1,2,3],ger:0,get:[0,1,2],gitlab:[1,2],gnd:[1,2],gnu:[1,2],gpio:[1,2],grenobl:0,gro:0,ground:[1,2],gui:[1,2],guidelin:3,gustav:0,guyard:[0,3],h81k0bya:[1,2],h81k5bya:[1,2],had:[1,2],hand:[1,2],handl:[1,2],hardwar:[0,1,2],hardwarex:0,has:[1,2],have:[1,2],hazard:[1,2],header:[1,2],hear:[1,2],here:2,high:[1,2],higher:2,holder:[1,2],hole:[1,2],home:[1,2],horizont:[1,2],hous:[1,2],how:[1,2],howev:[1,2],http:[1,2],ifsttar:0,illustr:[1,2],imag:0,imped:[1,2],implent:3,improv:2,in1:[1,2],in2:[1,2],in3:[1,2],in4:[1,2],includ:[1,2],incom:[1,2],increas:[1,2],inde:[1,2],inject:[0,3],injection_dur:[1,2],input:[1,2],inra:0,insert:[1,2],insid:[1,2],instead:[1,2],instruct:3,instrument:[0,1,2],intens:[1,2],interfac:[1,2],interpret:[1,2],introduc:[1,2],invit:1,involv:0,ion:[1,2],iri:0,irstea:[1,2],its:[1,2],jason:2,journal:1,json:2,juillet:0,juli:3,julien:[0,3],just:2,kemet:2,keyboard:[1,2],known:[1,2],kohm:[1,2],laboratori:[0,1,2],last:2,lastli:[1,2],latest:[1,2],lead:[1,2],leav:[1,2],length:[1,2],less:[1,2],let:[1,2],libatla:[1,2],librari:[1,2],lie:[1,2],limit:3,line:[1,2],list:3,lithium:[1,2],littelfus:[1,2],littl:[1,2],lm358an:[1,2],lm358n:[1,2],locat:[1,2],logger:[0,1,2],low:[0,1,2],lr20:[1,2],lying:[1,2],lyon:0,made:[1,2],mai:[1,2],main:[1,2],make:[1,2],manag:[1,2],manual:[1,2],manufactur:[1,2],manuscript:[1,2],master:[1,2],matur:3,maximum:[1,2],measur:[0,3],mechan:[1,2],meet:[1,2],mega:[1,2],menu:[1,2],met:[1,2],meter:[0,1,2],meterfeatur:0,micro:[1,2],mimic:[1,2],min:[1,2],miss:1,mm2:[1,2],model:[1,2],modif:[1,2],modifi:[1,2],modul:[1,2],mohm:[1,2],monitor:[1,2],moreov:[1,2],mount:[1,2],mous:[1,2],multi:[1,2],multiplex:[0,3],multipli:[1,2],must:[1,2],mux:[1,2],name:[1,2],nano:[1,2],nb_electrod:[1,2],nbr_mea:[1,2],necessari:[1,2],need:[1,2],neg:[1,2],next:[1,2],nicola:[0,3],noob:[1,2],nopb:[1,2],normal:[1,2],note:[1,2],now:[1,2],number:[1,2],numer:[1,2],numpi:[1,2],obtain:[1,2],offcial:3,offer:[1,2],ohm:[1,2],ohmmet:[1,2],ohmpi_param:2,ohx:0,onc:[1,2],one:[1,2],onto:[1,2],open:[0,1,2],oper:3,optim:[1,2],option:[1,2],order:[1,2],orient:2,osf:[1,2],other:[1,2],our:[1,2],out:[1,2],output:[1,2],overh:2,pai:[1,2],panda:[1,2],part:[1,2],parten:0,partenair:3,pat1l:2,path:[1,2],pcb:[1,2],per:[1,2],perform:[0,1,2],permut:[1,2],philosophi:[0,3],pic:1,piec:[1,2],pin:[1,2],pip:[1,2],pitch:[1,2],place:[1,2],pleas:[1,2],plug:[1,2],point:[1,2],polar:[1,2],pole:[1,2],posit:[1,2],possibl:[1,2],potenti:[1,2],potentiomet:[1,2],pour:1,power:[1,2],practic:[1,2],precis:[1,2],prefer:[1,2],prepar:[1,2],present:[0,1,2],press:[1,2],prevent:2,previous:[1,2],print:[1,2],pro:[1,2],produc:[1,2],program:[1,2],progress:[0,3],project:3,propos:[1,2],protocol:[1,2],provid:[0,1,2],publish:1,puls:[1,2],purpos:[1,2],pyhton3:[1,2],python3:[1,2],pythonid:[1,2],quadripol:[1,2],quadrupol:[1,2],quantiti:[1,2],r10:[1,2],r11:[1,2],r12:[1,2],r_ref:[1,2],rail:[1,2],rang:[1,2],raspberri:3,raspbian:[1,2],raspebrri:[1,2],readm:[1,2],recommend:[1,2],red:[1,2],reduct:[1,2],refer:[1,2],relai:[1,2],releas:3,remain:[1,2],rememb:[1,2],remot:[1,2],repeat:[1,2],repetit:[1,2],replac:2,repositori:[1,2],repres:[1,2],requir:[1,2],research:3,resist:[0,3],resistor:[1,2],resolut:[1,2],respect:[1,2],result:[1,2],revers:[1,2],reversa:[0,1,2],robust:[0,1,2],role:[1,2],root:[1,2],rpi:[1,2],rro:0,run:[1,2],safeti:[1,2],sain:[1,2],sainsmart:[1,2],same:[1,2],samtec:[1,2],save:[1,2],scale:0,schemat:[1,2],scienc:[1,2],scientif:0,screen:[1,2],screw:[1,2],second:[1,2],section:[1,2],see:[1,2],select:[1,2],sequenc:[1,2],sequence_delai:[1,2],seri:[1,2],serv:[1,2],set:[1,2],setp:2,setup:[1,2],sever:[1,2],shield:[1,2],shortcut:[1,2],should:[1,2],show:[1,2],shown:[1,2],signal:[1,2],simpl:[1,2],simpli:[1,2],simultan:[1,2],singl:[1,2],slope:[1,2],small:[0,1,2],smaller:[1,2],smart:[1,2],softwar:[1,2],soil:[1,2],solder:[1,2],solut:[1,2],some:[1,2,3],sound:[1,2],sourc:[0,1,2],specif:[1,2],specifi:[1,2],spi:[1,2],ssw:[1,2],stabl:[1,2],stack:[1,2],stainless:[1,2],start:[1,2,3],statu:[0,3],steel:[1,2],step:[1,2],still:[1,2],storag:[1,2],strict:[1,2],strip:[1,2],strong:[1,2],stronger:[1,2],strongli:[1,2],stuck:[1,2],studi:[1,2],subject:[1,2],sudo:[1,2],suffici:[1,2],suggest:[1,2],suitabl:[1,2],sum:[1,2],suppli:[1,2],suppress:2,sure:[1,2],surfac:0,system:[1,2],tab:[1,2],tabl:2,target:3,task:[1,2],technic:3,temperatur:[1,2],ten:[1,2],termin:[1,2],test:[1,2],texa:[1,2],than:[1,2],the9:[1,2],thei:[1,2],them:[1,2],therefor:[1,2],thi:[0,1,2],thousand:[1,2],three:[1,2],through:[1,2],thu:[1,2],time:[1,2],togeth:[1,2],toler:2,tool:0,total:[1,2],track:[1,2],traco:2,tracopow:2,trn3:2,trn:2,tru:[1,2],turn:[1,2],tutori:3,two:[1,2],txt:[1,2],type:[1,2],typic:[1,2],under:[1,2],unexpectedli:[1,2],unit:[1,2],univ:0,unzip:[1,2],updat:0,upgrad:2,upping:[1,2],upw50b50rv:[1,2],use:[1,2],used:[1,2],user:[1,2,3],using:[1,2],usr:[1,2],valid:[1,2],valu:[1,2],variou:[1,2],velleman:[1,2],venv:[1,2],veri:2,version:[1,2],vertic:[1,2],via:[1,2],villeurbann:0,vivien:[0,3],voltag:[1,2],voltmet:[1,2],wai:[1,2],want:2,watch:[1,2],weaker:1,websit:[1,2],weidmul:[1,2],welcom:0,well:[1,2],were:[1,2],when:[1,2],where:[1,2],which:[1,2],whose:[1,2],willing:0,window:[1,2],wire:[1,2],within:[1,2],without:[1,2],wjwzhv1v3pk:[1,2],would:[1,2],wpm404:[1,2],write:[1,2],www:[1,2],yannick:[0,3],you:[1,2],your:[1,2],youtub:[1,2]},titles:["OhmPi project","OhmPi V 1.01 (limited to 32 electrodes)","OhmPi V 1.02 (limited to 32 electrodes)","OHMPI: Open source and open hardware resitivity-meter"],titleterms:{IDE:[1,2],The:[1,2],activ:[1,2],assembl:[1,2],board:[1,2],card:[1,2],center:3,cite:0,complet:[1,2],compon:[1,2],configur:[1,2],connect:[1,2],current:[1,2],data:[1,2],descript:[1,2],document:3,electr:[1,2],electrod:[1,2],environn:[1,2],four:[1,2],frist:[1,2],hardwar:3,implement:[1,2],implent:[1,2],initi:[1,2],inject:[1,2],instal:[1,2],instruct:[1,2],introduct:0,limit:[1,2],list:[1,2],measur:[1,2],mesur:[1,2],meter:3,multiplex:[1,2],ohmpi:[0,1,2,3],onli:[1,2],open:3,oper:[1,2],packag:[1,2],paramet:[1,2],partenair:0,philosophi:[1,2],preliminari:[1,2],procedur:[1,2],project:0,python:[1,2],rapberri:[1,2],raspberri:[1,2],resist:[1,2],resit:3,sourc:3,startup:[1,2],summari:3,tabl:1,technic:[1,2],thonni:[1,2],titl:1,virtual:[1,2]}})
\ No newline at end of file
+Search.setIndex({docnames:["Ohmpi","V1_01","V1_02","V2_00","index"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":4,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":3,"sphinx.domains.rst":2,"sphinx.domains.std":2,sphinx:56},filenames:["Ohmpi.rst","V1_01.rst","V1_02.rst","V2_00.rst","index.rst"],objects:{},objnames:{},objtypes:{},terms:{"0":[1,2,3],"00":4,"000":[1,2],"01":[2,4],"018":[1,2],"02":[1,4],"0251001":2,"04":[1,2],"05":[1,2],"06":[1,2],"09":[1,2],"1":4,"10":[1,2],"100":[1,2],"100nf":2,"101":[1,2],"1016":0,"103":[1,2],"1083":[1,2],"10v":2,"11":[1,2],"110":[1,2],"1115":[1,2],"114":[1,2,3],"12":[1,2,3],"1215":2,"128":4,"12v":[1,2],"13":[1,2],"1332":[1,2],"14":4,"15":[1,2],"150":[1,2,3],"1565235":[1,2],"1568649":[1,2],"16":[1,2,3],"17":[1,2],"18":[1,2,3],"185":[1,2],"19":[1,2],"199":[1,2],"1x0":[1,2],"1x1":[1,2],"1x10":[1,2],"2":[1,2,4],"20":[1,2],"2016":4,"2020":0,"2021":4,"21":[0,1,2],"22":[1,2],"23":[1,2],"24":[0,1,2],"24v":2,"25":[1,2,3],"26":[1,2],"27":[1,2],"29":[1,2],"2a":[1,2],"3":[1,2,3],"30":[1,2],"32":[0,3,4],"36":[1,2],"37":[1,2],"38":[1,2],"39":[1,2],"4":[1,2,3],"40":[1,2,3],"43":[1,2],"44":[1,2],"45100":0,"4686":[1,2],"48":[1,2],"5":[1,2,3],"50":[1,2,3],"500":[1,2],"50vdc":2,"52":[1,2],"53":2,"537":[1,2],"5488":[1,2],"55":[1,2],"576":1,"58":[1,2],"5v":[1,2],"5vcc":[1,2],"5vdc":[1,2],"5w":[1,2],"6":[1,2,3],"627":[1,2],"64":[1,2,4],"648":[1,2],"66":[1,2],"68":[1,2],"69626":0,"69675":0,"7":[1,2,3],"70":[1,2],"71":[1,2],"72":2,"7ah":[1,2],"8":[0,1,2,3],"80":3,"858":[1,2],"897":[1,2],"9":[1,2,3],"9004330000":[1,2],"92":[1,2],"96":1,"966067":[1,2],"99":[1,2],"9v":[1,2],"\u00e9lectrod":4,"ao\u00fbt":0,"case":[1,2,3],"final":[1,2],"function":[0,1,2],"h\u00e9l\u00e8ne":[0,4],"int\u00e9gr\u00e9":3,"mm\u00b2":[1,2],"new":[1,2,3],"orl\u00e9an":0,"pr\u00e9cision":3,"public":[1,2],"r\u00e9alis":3,"r\u00e9mi":[0,4],"return":[1,2,3],"switch":[1,2],"universit\u00e9":0,"vid\u00e9o":[1,2,3],A:[1,2,3],As:[1,2],At:[1,2,3],For:[1,2,3],If:[1,2,3],In:[0,1,2,3],It:[1,2,3],Its:[1,2],On:[1,2,3],The:4,These:[1,2],To:[1,2,3],With:[1,2],a0:[1,2],a1:[1,2],a2:[1,2],a3:[1,2],abmn:[1,2],abov:[1,2],acc:[1,2,3],access:[1,2],accord:[1,2],accur:[1,2],accuraci:[1,2],acid:[1,2],actual:[1,2],ad:[1,2],adafruit:[1,2,3],adapt:[1,2,3],adc:[1,2,3],add:[1,2],addit:[1,2],address:[1,2],adjust:[1,2],ads1115:[1,2,3],ads115:[1,2],ads1x15:[1,2,3],advantag:3,after:[1,2],al:0,all:[1,2,3],allow:[0,1,2,3],alp:0,also:[1,2,3],altern:[1,2,3],amp:[1,2],amplifi:[1,2],an:[0,1,2,3],analog:[1,2,3],ani:[1,2],anoth:[1,2,3],appear:[1,2,3],appli:[1,2],applic:0,apt:[1,2,3],ar:[1,2,3],arduino:1,arm:1,arrai:[1,2],articl:[1,2],asler:[1,2],assembl:4,assist:[1,2],associ:0,attent:[1,2],attribut:[1,2],author:[0,1,2,3,4],automat:[0,1,2],automobil:[1,2],autour:3,avail:[1,2],avon:3,avr:1,b:3,bank:[1,2],base:[1,2,3],basic:0,batteri:[1,2,3],been:[1,2,3],befor:[1,2],behavior:[1,2],being:[1,2],below:[1,2,3],between:[1,2,3],bin:[1,2,3],bit:[1,2,3],black:[1,2],blinka:[1,2,3],block:[1,2],blue:[1,2],board:4,boot:[1,2,3],both:[1,2],bottom:[1,2],bought:[1,2],box:3,bridg:[1,2],bug:1,build:[1,2],button:[1,2,3],c320c104k1:2,c:[1,2,3],cabl:[1,2,3],calcul:[1,2],calibr:[1,2],call:0,can:[1,2,3],canal:1,cap:[1,2],capac:[1,2],capacitor:2,car:1,card:[3,4],carri:[1,2,3],caus:[1,2,3],cd:[1,2,3],cedex:0,ceram:2,channel:[1,2],characterist:[1,2],charg:[1,2],check:[1,2,3],chosen:[1,2],circuit:[1,2],circuitpython:[1,2,3],circul:[1,2],clean:[1,2],clement:[0,4],click:[1,2,3],close:[1,2,3],cm:[1,2],code:[1,2,3],coef_p0:[1,2],coef_p1:[1,2],coef_p2:[1,2],coef_p3:[1,2],coeff:[1,2],coeffici:[1,2],com:[1,2,3],command:[1,2,3],commerci:[1,2],common:[1,2],commun:[0,3],complet:[3,4],compon:[3,4],compos:3,comput:[1,2,3],conduct:[1,2],config:[1,2,3],configur:4,congratul:[1,2],connect:[3,4],connector:[1,2],consequ:[1,2],consist:[1,2],constitut:[1,2],construct:[1,2],consumpt:[1,2,3],contact:[1,2],contain:[1,2,3],content:4,control:[1,2,3],convers:[1,2],convert:[1,2,3],copi:3,correct:[1,2],correspond:1,cost:[0,1,2],could:[1,2,3],courant:3,cpu:[1,2,3],creat:[1,2,3],creation:0,crimp:[1,2],csv:[1,2],ctrl:[1,2,3],current:[0,3,4],d:[1,2,3],damag:[1,2,3],data:[0,4],date:[0,1,2,4],dc:[1,2],dcconvert:2,de:3,deactiv:[1,2,3],decid:[1,2,3],decoupl:2,dedic:[0,3],delai:[1,2],deliv:[1,2],depend:[1,2,3],describ:[1,2,3],design:[1,2],desktop:2,despit:[1,2],detail:1,dev:[1,2,3],develop:[0,1,2,3,4],diagram:[1,2,3],differ:[1,2,3],digit:[1,2,3],dii:3,din:[1,2],direct:[1,2,3],directli:[1,2],directori:[1,2,3],disconnect:[1,2],discret:3,displai:[1,2],distanc:[1,2],disturb:[1,2],divid:[1,2],dl:[1,2,3],document:[0,1],done:[1,2,3],down:[1,2],download:[1,2],dsp:1,du:3,dual:[1,2],duboi:[0,4],durat:[1,2,3],dure:[1,2,3],dzwb4:[1,2],e00122ff:0,e:[1,2],each:[1,2,3],editor:[1,2,3],effort:3,eiffel:0,either:[1,2,3],electr:[0,3],electrod:[0,3,4],electron:[1,2,3],elsevi:0,emil:0,en:3,enabl:[1,2],end:[1,2,3],energ:[1,2],enough:[1,2],ensur:[1,2,3],enter:[1,2,3],entir:[1,2],environ:[1,2,3],environnementshould:[1,2,3],equal:[1,2],equival:[1,2],ert:[1,2],escap:[1,2,3],estim:[1,2],et:0,everyon:0,evolv:[1,2],exampl:[1,2],excess:[1,2],execut:[1,2,3],exist:[1,2],experi:[0,1,2,3],explain:1,export_path:2,extra:[1,2],f:[0,1,2],failur:[1,2,3],fargier:[0,4],fast:2,featur:[1,2],femal:[1,2],ferrul:[1,2],fewer:[1,2],ff10:0,fhac0002zxj:1,field:[1,2,3],fig:[1,2],figur:[1,2,3],file:[1,2,3],find:[1,2,3],first:[1,2,3],flexibl:0,florsch:[1,2,3],flow:[1,2],folder:[1,2,3],follow:[1,2,3],forquet:[0,4],four:3,fr:[1,2],framework:[1,2],franc:0,from:[1,2,3],full:[1,2],fulli:0,fuse:[1,2],g:[1,2],gain:[1,2,3],ganc:[0,4],gather:[1,2,3],gener:[1,2,3,4],ger:0,get:[0,1,2,3],gitlab:[1,2],gnd:[1,2],gnu:[1,2,3],go:3,gpio:[1,2,3],grenobl:0,gro:0,ground:[1,2],gui:[1,2,3],guidelin:4,gustav:0,guyard:[0,4],h81k0bya:[1,2],h81k5bya:[1,2],h:2,ha:[1,2,3],had:[1,2],hand:[1,2],handl:[1,2],hardwar:[0,1,2],hardwarex:0,have:[1,2,3],hazard:[1,2],hdmi:3,header:[1,2],hear:[1,2],here:2,high:[1,2],higher:2,holder:[1,2],hole:[1,2],home:[1,2,3],horizont:[1,2],hous:[1,2],how:[1,2,3],howev:[1,2],http:[1,2,3],i:[1,2],ifsttar:0,ig:0,illustr:[1,2],imag:0,imped:[1,2,3],implent:4,improv:[2,3],in1:[1,2],in2:[1,2],in3:[1,2],in4:[1,2],ina282:3,includ:[1,2,3],incom:[1,2],increas:[1,2],inde:[1,2],inject:[0,3,4],injection_dur:[1,2],input:[1,2,3],inra:0,insert:[1,2],insid:[1,2],instanc:3,instead:[1,2],instruct:[3,4],instrument:[0,1,2],intens:[1,2],interfac:[1,2,3],interpret:[1,2,3],introduc:[1,2],invit:1,involv:0,io:[1,2],ion:[1,2],iri:0,irstea:[1,2],its:[1,2,3],j:0,jason:2,journal:1,json:2,juillet:0,jul:4,juli:4,julien:[0,4],just:2,kemet:2,keyboard:[1,2,3],known:[1,2,3],kohm:[1,2],la:3,laboratori:[0,1,2,3],laps:3,last:2,lastli:[1,2],latest:[1,2,3],le:3,lead:[1,2],leav:[1,2,3],length:[1,2],less:[1,2],let:[1,2],libatla:[1,2,3],librari:[1,2,3],lie:[1,2,3],limit:[3,4],line:[1,2],list:[3,4],lithium:[1,2],littelfus:[1,2],littl:[1,2],ll:[1,2],lm358an:[1,2],lm358n:[1,2],locat:[1,2,3],logger:[0,1,2],low:[0,1,2,3],lr20:[1,2],ly:[1,2],lyon:0,m:[1,2,3],ma:[1,2,3],made:[1,2,3],mai:[1,2,3],main:[1,2],make:[1,2,3],manag:[1,2],manual:[1,2],manufactur:[1,2],manuscript:[1,2],master:[1,2],matur:4,maximum:[1,2],measur:[0,4],mechan:[1,2],meet:[1,2,3],mega:[1,2],menu:[1,2,3],mesur:3,met:[1,2,3],meter:[0,1,2,3],meterfeatur:0,micro:[1,2,3],mimic:[1,2],min:[1,2,3],miss:1,mm2:[1,2],mm:[1,2],model:[1,2,3],modif:[1,2,3],modifi:[1,2,3],modul:[1,2],mohm:[1,2,3],monitor:[1,2,3],more:3,moreov:[1,2],mount:[1,2],mous:[1,2,3],ms:[1,2,3],multi:[1,2],multielectrod:3,multipl:3,multiplex:[0,3,4],multipli:[1,2],must:[1,2,3],mux:[1,2],n:[1,2,4],name:[1,2],nano:[1,2,3],nb_electrod:[1,2],nbr_mea:[1,2],necessari:[1,2,3],need:[1,2,3],neg:[1,2],next:[1,2],nf:2,nicola:[0,4],noob:[1,2,3],nopb:[1,2],normal:[1,2],note:[1,2],nou:3,now:[1,2],number:[1,2],numer:[1,2],numpi:[1,2,3],o1:[1,2,3],o:[1,2,3],obtain:[1,2],offcial:4,offer:[1,2,3],ohm:[1,2,3],ohmmet:[1,2],ohmpi_param:2,ohx:0,ok:[1,2,3],onc:[1,2,3],one:[1,2,3],onto:[1,2],op:[1,2,3],open:[0,1,2,3],oper:[3,4],optim:[1,2],option:[1,2,3],order:[1,2],org:3,orient:2,osf:[1,2],other:[1,2],our:[1,2,3],out:[1,2,3],output:[1,2],overh:2,p0:[1,2],p1:[1,2],p2:[1,2],p3:[1,2],p:0,pai:[1,2],panda:[1,2,3],parallel:3,paramet:3,part:[1,2],parten:0,partenair:4,pat1l:2,path:[1,2,3],pcb:[1,2],per:[1,2],perform:[0,1,2,3],permet:3,permut:[1,2],philosophi:[0,4],pi:4,pic:1,piec:[1,2],pin:[1,2],pip:[1,2,3],pitch:[1,2],place:[1,2],pleas:[1,2],plug:[1,2],po:[1,2],point:[1,2,3],polar:[1,2],pole:[1,2],posit:[1,2,3],possibl:[1,2],potenti:[1,2],potentiomet:[1,2],pour:[1,3],power:[1,2,3],practic:[1,2],precis:[1,2],prefer:[1,2],prepar:[1,2],present:[0,1,2],press:[1,2,3],prevent:2,previou:3,previous:[1,2,3],print:[1,2],pro:[1,2],problem:3,produc:[1,2],program:[1,2,3],progress:[0,4],project:[3,4],propos:[1,2,3],protect:3,protocol:[1,2],provid:[0,1,2],publish:1,puls:[1,2,3],purpos:[1,2],py:[1,2],pyhton3:[1,2,3],python3:[1,2,3],pythonid:[1,2,3],quadripol:[1,2],quadrupol:[1,2],quantiti:[1,2,3],qui:3,r10:[1,2],r11:[1,2],r12:[1,2],r1:[1,2],r2:[1,2],r3:[1,2],r4:[1,2],r5:[1,2],r6:[1,2],r7:[1,2],r8:[1,2],r9:[1,2],r_ref:[1,2],rail:[1,2],rang:[1,2],raspberri:4,raspberrypi:3,raspbian:[1,2,3],raspebrri:[1,2,3],readm:[1,2],recommend:[1,2,3],red:[1,2],reduct:[1,2],refer:[1,2],relai:[1,2,3],releas:4,remain:[1,2],rememb:[1,2],remot:[1,2,3],repeat:[1,2],repetit:[1,2],replac:2,repositori:[1,2],repres:[1,2],requir:[1,2,3],research:4,resist:[0,3,4],resistor:[1,2],resolut:[1,2,3],respect:[1,2],result:[1,2],revers:[1,2],reversa:[0,1,2],robust:[0,1,2,3],role:[1,2],root:[1,2,3],rpi:[1,2,3],rro:0,rs:[1,2],rubric:[],run:[1,2,3],s:[0,1,2,3],safeti:[1,2],sain:[1,2],sainsmart:[1,2],same:[1,2],samtec:[1,2],save:[1,2,3],scale:0,schemat:[1,2],scienc:[1,2],scientif:0,screen:[1,2],screw:[1,2],sd:[1,2,3],second:[1,2],section:[1,2],see:[1,2],seek:3,select:[1,2,3],sequenc:[1,2],sequence_delai:[1,2],seri:[1,2],serv:[1,2],set:[1,2,3],setp:2,setup:[1,2,3],sever:[1,2],share:3,shield:[1,2,3],shortcut:[1,2],should:[1,2,3],show:[1,2,3],shown:[1,2],shunt:3,signal:[1,2,3],simpl:[1,2,3],simpli:[1,2,3],simultan:[1,2],singl:[1,2],slope:[1,2],small:[0,1,2,3],smaller:[1,2],smart:[1,2],so:[1,2],softwar:[1,2,3],soil:[1,2],solder:[1,2],solut:[1,2],some:[1,2,4],sound:[1,2],sourc:[0,1,2,3],specif:[1,2,3],specifi:[1,2,3],spi:[1,2,3],ssw:[1,2],stabl:[1,2,3],stack:[1,2],stainless:[1,2],start:[1,2,3,4],statu:[0,4],steel:[1,2],step:[1,2,4],still:[1,2],stop:3,storag:[1,2,3],strict:[1,2],strip:[1,2],strong:[1,2],stronger:[1,2],strongli:[1,2,3],stuck:[1,2],studi:[1,2],subject:[1,2],sudo:[1,2,3],suffici:[1,2,3],suggest:[1,2],suitabl:[1,2,3],sum:[1,2],suppli:[1,2],support:3,suppress:2,sure:[1,2,3],surfac:0,system:[1,2,3],tab:[1,2,3],tabl:2,target:4,task:[1,2,3],te:[1,2],team:3,technic:4,temperatur:[1,2,3],ten:[1,2],termin:[1,2,3],test:[1,2,3],texa:[1,2],than:[1,2],the9:[1,2],thei:[1,2],them:[1,2],therefor:[1,2],thi:[0,1,2,3],thousand:[1,2],three:[1,2],through:[1,2],thu:[1,2],time:[1,2,3],togeth:[1,2],toler:2,tool:[0,3],total:[1,2],track:[1,2],traco:2,tracopow:2,trn3:2,trn:2,tru:[1,2],turn:[1,2],tutori:4,two:[1,2,3],tx:[1,2],txt:[1,2,3],type:[1,2,3],typic:[1,2],un:3,under:[1,2],unexpectedli:[1,2,3],unit:[1,2,3],univ:0,unzip:[1,2],up:[0,1,2,3],updat:0,upgrad:[2,3],upw50b50rv:[1,2],us:[1,2,3],user:[1,2,3,4],usr:[1,2,3],util:3,v1:[1,2,3],v2:3,v:4,valid:[1,2],valu:[1,2,3],variou:[1,2],velleman:[1,2],venv:[1,2,3],veri:2,version:[1,2,3],vertic:[1,2],via:[1,2,3],villeurbann:0,visit:3,vivien:[0,4],voltag:[1,2,3],voltmet:[1,2],w:[1,2,3],wa:[1,2],wai:[1,2,3],want:2,watch:[1,2,3],we:[1,2,3],weaker:1,websit:[1,2,3],weidmul:[1,2],welcom:0,well:[1,2,3],were:[1,2,3],when:[1,2,3],where:[1,2,3],which:[1,2,3],whose:[1,2],willing:0,window:[1,2,3],wire:[1,2,3],wish:3,within:[1,2,3],without:[1,2],wjwzhv1v3pk:[1,2,3],would:[1,2],wpm404:[1,2],write:[1,2,3],www:[1,2,3],x:[1,2,3],yannick:[0,4],you:[1,2,3],your:[1,2,3],youtub:[1,2,3]},titles:["OhmPi project","OhmPi V 1.01 (limited to 32 electrodes)","OhmPi V 1.02 (limited to 32 electrodes)","OhmPi V 2.00 (64 or 128 \u00e9lectrodes)","OHMPI: Open source and open hardware resitivity-meter"],titleterms:{"00":3,"01":1,"02":2,"1":[1,2,3],"128":3,"2":3,"32":[1,2],"64":3,"\u00e9lectrod":3,The:[1,2,3],activ:[1,2,3],assembl:[1,2,3],b:[1,2],board:[1,2,3],card:[1,2],center:4,cite:0,complet:[1,2],compon:[1,2],configur:[1,2,3],connect:[1,2],current:[1,2],data:[1,2,3],descript:[1,2,3],document:4,electr:[1,2],electrod:[1,2],environn:[1,2,3],four:[1,2],frist:[1,2],hardwar:4,id:[1,2,3],implement:[1,2],implent:[1,2],initi:[1,2],inject:[1,2],instal:[1,2,3],instruct:[1,2],introduct:0,limit:[1,2],list:[1,2],measur:[1,2,3],mesur:[1,2],meter:4,multiplex:[1,2],n:3,ohmpi:[0,1,2,3,4],onli:[1,2],open:4,oper:[1,2],os:[1,2,3],packag:[1,2,3],paramet:[1,2],partenair:0,philosophi:[1,2,3],pi:[1,2,3],preliminari:[1,2],procedur:[1,2],project:0,python:[1,2,3],rapberri:[1,2,3],raspberri:[1,2,3],resist:[1,2],resit:4,sourc:4,startup:[1,2],step:3,summari:4,tabl:1,technic:[1,2,3],thonni:[1,2,3],titl:1,v:[1,2,3],virtual:[1,2,3]}})
\ No newline at end of file
diff --git a/sphinx/build/doctrees/V2_00.doctree b/sphinx/build/doctrees/V2_00.doctree
index 1a62a6a5cd4ad5aba18fd44b7715834e7464b18c..3e1ea2703421e0bcd5c3be591260171af6edb6f6 100644
Binary files a/sphinx/build/doctrees/V2_00.doctree and b/sphinx/build/doctrees/V2_00.doctree differ
diff --git a/sphinx/build/doctrees/environment.pickle b/sphinx/build/doctrees/environment.pickle
index bb73d0795aba895993f96ca70e9446aa533088eb..69a8d6ea404e88276bf15f15d850ab44ba543005 100644
Binary files a/sphinx/build/doctrees/environment.pickle and b/sphinx/build/doctrees/environment.pickle differ
diff --git a/sphinx/build/html/V2_00.html b/sphinx/build/html/V2_00.html
index 407daa82692e56528a5379382c906f2b20b856e6..f4a2747bdab9505f61baabc391c9f66c8f5abba4 100644
--- a/sphinx/build/html/V2_00.html
+++ b/sphinx/build/html/V2_00.html
@@ -518,6 +518,30 @@ input signal value could lie between - to + 6.114 V. Pour la mesure du current n
 </tr>
 </tbody>
 </table>
+<table class="docutils align-center">
+<colgroup>
+<col style="width: 50%" />
+<col style="width: 50%" />
+</colgroup>
+<tbody>
+<tr class="row-odd"><td><img alt="_images/07_mes_board.jpg" src="_images/07_mes_board.jpg" />
+</td>
+<td></td>
+</tr>
+</tbody>
+</table>
+<table class="docutils align-center">
+<colgroup>
+<col style="width: 50%" />
+<col style="width: 50%" />
+</colgroup>
+<tbody>
+<tr class="row-odd"><td></td>
+<td><img alt="_images/08_mes_board.jpg" src="_images/08_mes_board.jpg" />
+</td>
+</tr>
+</tbody>
+</table>
 </section>
 </section>
 </section>
diff --git a/sphinx/build/html/_images/07_mes_board.jpg b/sphinx/build/html/_images/07_mes_board.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..954aabf761288a96221d98914011a337cd6664ad
Binary files /dev/null and b/sphinx/build/html/_images/07_mes_board.jpg differ
diff --git a/sphinx/build/html/_images/08_mes_board.jpg b/sphinx/build/html/_images/08_mes_board.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..645ed57a8f2c9118f57500a4aa575913770acdad
Binary files /dev/null and b/sphinx/build/html/_images/08_mes_board.jpg differ
diff --git a/sphinx/build/html/_sources/V2_00.rst.txt b/sphinx/build/html/_sources/V2_00.rst.txt
index 6a511baef4a0479a24a3b106c5fa23f41975688d..5740028e48f7848c117a3d44076a44865a3afc89 100644
--- a/sphinx/build/html/_sources/V2_00.rst.txt
+++ b/sphinx/build/html/_sources/V2_00.rst.txt
@@ -306,4 +306,18 @@ input signal value could lie between - to + 6.114 V. Pour la mesure du current n
   
    +---------------------------------------+---------------------------------------+
    |                                       |    .. image:: mesure/06_mes_board.jpg |
-   +---------------------------------------+---------------------------------------+   
+   +---------------------------------------+---------------------------------------+  
+
+.. table::
+   :align: center
+  
+   +---------------------------------------+---------------------------------------+
+   |   .. image:: mesure/07_mes_board.jpg  |                                       |
+   +---------------------------------------+---------------------------------------+
+   
+.. table::
+   :align: center
+  
+   +---------------------------------------+---------------------------------------+
+   |                                       |    .. image:: mesure/08_mes_board.jpg |
+   +---------------------------------------+---------------------------------------+