Repository: MetaCell/NetPyNE-UI (language: python)

Issue:
Typo fix in version
@filippomc Minor edit, will make it easy to see which version gets deployed...
Osb2 dev

Add menu items in UI for loading NeuroML/LEMS 
@filippomc @ddelpiano I've added 2 helper methods in this script [here](https://github.com/OpenSourceBrain/NetPyNEShowcase/blob/master/NetPyNE/UI/helpers.py):`convertAndImportNeuroML2(nml2FileName)` and `convertAndImportLEMSSimulation(lemsFileName)`, which are self contained methods for loading in A) a NeuroML file, or B) a [LEMS Simulation file](https://docs.neuroml.org/Userdocs/LEMSSimulation.html), converting them to the NetPyNE equivalent, including mod file, compiling the mods and generating the JSON equivalent which I've tested can easily be loaded using the current JSON loader. They also return the `netParams` and `simConfig`.

Hopefully these should be sufficient for adding to NetPyNE-UI (as `neuroml_utlis.py` in [here](https://github.com/MetaCell/NetPyNE-UI/tree/master/netpyne_ui)?), and then 2 extra options added to the menu:

<img width="593" alt="Screenshot 2022-06-15 at 13 28 27" src="https://user-images.githubusercontent.com/1556687/173826884-4c965e31-c935-45cf-b1cf-78fcc4e50be1.png">

**From NeuroML2...** (opening a dialog to find any file *.net.nml) 
**From LEMS Simulation...** (finding any file *.xml) 

which ultimately call these methods in Python, and load the model. 

How would that sound? The helper methods could eventually be moved to core netpyne, but keeping them here for now would just aid testing/deployment etc.

Add menu items in UI for loading NeuroML/LEMS 
@filippomc @ddelpiano I've added 2 helper methods in this script [here](https://github.com/OpenSourceBrain/NetPyNEShowcase/blob/master/NetPyNE/UI/helpers.py):`convertAndImportNeuroML2(nml2FileName)` and `convertAndImportLEMSSimulation(lemsFileName)`, which are self contained methods for loading in A) a NeuroML file, or B) a [LEMS Simulation file](https://docs.neuroml.org/Userdocs/LEMSSimulation.html), converting them to the NetPyNE equivalent, including mod file, compiling the mods and generating the JSON equivalent which I've tested can easily be loaded using the current JSON loader. They also return the `netParams` and `simConfig`.

Hopefully these should be sufficient for adding to NetPyNE-UI (as `neuroml_utlis.py` in [here](https://github.com/MetaCell/NetPyNE-UI/tree/master/netpyne_ui)?), and then 2 extra options added to the menu:

<img width="593" alt="Screenshot 2022-06-15 at 13 28 27" src="https://user-images.githubusercontent.com/1556687/173826884-4c965e31-c935-45cf-b1cf-78fcc4e50be1.png">

**From NeuroML2...** (opening a dialog to find any file *.net.nml) 
**From LEMS Simulation...** (finding any file *.xml) 

which ultimately call these methods in Python, and load the model. 

How would that sound? The helper methods could eventually be moved to core netpyne, but keeping them here for now would just aid testing/deployment etc.

Add menu items in UI for loading NeuroML/LEMS 
@filippomc @ddelpiano I've added 2 helper methods in this script [here](https://github.com/OpenSourceBrain/NetPyNEShowcase/blob/master/NetPyNE/UI/helpers.py):`convertAndImportNeuroML2(nml2FileName)` and `convertAndImportLEMSSimulation(lemsFileName)`, which are self contained methods for loading in A) a NeuroML file, or B) a [LEMS Simulation file](https://docs.neuroml.org/Userdocs/LEMSSimulation.html), converting them to the NetPyNE equivalent, including mod file, compiling the mods and generating the JSON equivalent which I've tested can easily be loaded using the current JSON loader. They also return the `netParams` and `simConfig`.

Hopefully these should be sufficient for adding to NetPyNE-UI (as `neuroml_utlis.py` in [here](https://github.com/MetaCell/NetPyNE-UI/tree/master/netpyne_ui)?), and then 2 extra options added to the menu:

<img width="593" alt="Screenshot 2022-06-15 at 13 28 27" src="https://user-images.githubusercontent.com/1556687/173826884-4c965e31-c935-45cf-b1cf-78fcc4e50be1.png">

**From NeuroML2...** (opening a dialog to find any file *.net.nml) 
**From LEMS Simulation...** (finding any file *.xml) 

which ultimately call these methods in Python, and load the model. 

How would that sound? The helper methods could eventually be moved to core netpyne, but keeping them here for now would just aid testing/deployment etc.

Add menu items in UI for loading NeuroML/LEMS 
@filippomc @ddelpiano I've added 2 helper methods in this script [here](https://github.com/OpenSourceBrain/NetPyNEShowcase/blob/master/NetPyNE/UI/helpers.py):`convertAndImportNeuroML2(nml2FileName)` and `convertAndImportLEMSSimulation(lemsFileName)`, which are self contained methods for loading in A) a NeuroML file, or B) a [LEMS Simulation file](https://docs.neuroml.org/Userdocs/LEMSSimulation.html), converting them to the NetPyNE equivalent, including mod file, compiling the mods and generating the JSON equivalent which I've tested can easily be loaded using the current JSON loader. They also return the `netParams` and `simConfig`.

Hopefully these should be sufficient for adding to NetPyNE-UI (as `neuroml_utlis.py` in [here](https://github.com/MetaCell/NetPyNE-UI/tree/master/netpyne_ui)?), and then 2 extra options added to the menu:

<img width="593" alt="Screenshot 2022-06-15 at 13 28 27" src="https://user-images.githubusercontent.com/1556687/173826884-4c965e31-c935-45cf-b1cf-78fcc4e50be1.png">

**From NeuroML2...** (opening a dialog to find any file *.net.nml) 
**From LEMS Simulation...** (finding any file *.xml) 

which ultimately call these methods in Python, and load the model. 

How would that sound? The helper methods could eventually be moved to core netpyne, but keeping them here for now would just aid testing/deployment etc.

Usability - avoid model initialization, part 2 of the issue 311
**New button**
- In the edit view, add a button to go to the explorer view, same styling and position of the button "back to edit" that we have when we are in the explorer view.
- That button should only let the UI transit to the other view, not initialise or simulate anything.
- If the modelState in the redux store is not instatiated the button above should be disabled (since there won't be anything in that view), put a tooltip in the button that says "the model needs to be instantiated in order to display the results in the next view", this text can be tweaked later.
![scrnli_07_03_2022_14-39-30.png](https://images.zenhubusercontent.com/5b0293e84b5806bc2bd3f170/c3c7c460-f723-4ba3-96ab-fd0861090fa6)


**Regarding the existing pink button that allow us to simulate and/or instantiate the network:**
- when the modelState is instantiated or simulated change the default nomenclature we show for the button, from 'create the network' to 'update the network'.
![scrnli_07_03_2022_14-40-38.png](https://images.zenhubusercontent.com/5b0293e84b5806bc2bd3f170/26348a1b-f5a0-4be8-9d46-300ea2896bd5)
Add Java to Dockerfile so NeuroML import will work 
The NML import feature requires java to be present to run processes in jNeuroML for importing NeuroML files.

<img width="1631" alt="Screenshot 2022-08-30 at 11 06 42" src="https://user-images.githubusercontent.com/1556687/187410125-64d3d0f6-1553-4e2e-a778-5416ad74a90d.png">

Osb2 dev



Discussion / hints:

Fix patch:
diff --git a/.gitignore b/.gitignore
index db126a77..4c34a154 100644
--- a/.gitignore
+++ b/.gitignore
@@ -27,4 +27,7 @@ utilities/x86_64
 x86_64
 .jupyter-config
 venv
+webapp/build
+webapp/.yalc
 node_modules
+sa_nyhead.mat
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
index a08b23a9..5a3531cb 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -20,6 +20,8 @@ ENV NB_UID=jovyan
 ENV FOLDER=netpyne
 ARG GEPPETTO_VERSION=development
 ARG BUILD_ARGS=""
+ARG NETPYNE_VERSION=master
+ARG WORKSPACE_VERSION=master
 
 ENV FOLDER=/home/jovyan/work/NetPyNE-UI
 
@@ -27,7 +29,7 @@ USER root
 
 RUN rm -rf /var/lib/apt/lists
 RUN apt-get update -qq &&\
-    apt-get install python3-tk vim nano unzip git make libtool g++ -qq pkg-config libfreetype6-dev libpng-dev libopenmpi-dev -y
+    apt-get install python3-tk vim nano unzip git make libtool g++ -qq pkg-config libfreetype6-dev libpng-dev libopenmpi-dev  openjdk-11-jre-headless -y -y
 RUN conda install python=3.7 -y
 
 
@@ -44,7 +46,7 @@ RUN jupyter nbextension enable --py --sys-prefix jupyter_geppetto
 RUN jupyter nbextension enable --py --sys-prefix widgetsnbextension
 RUN jupyter serverextension enable --py --sys-prefix jupyter_geppetto
 
-RUN python utilities/install.py ${BUILD_ARGS} --geppetto ${GEPPETTO_VERSION} --npm-skip
+RUN python utilities/install.py ${BUILD_ARGS} --geppetto ${GEPPETTO_VERSION} --netpyne $NETPYNE_VERSION --workspace WORKSPACE_VERSION --npm-skip
 
 RUN jupyter labextension disable @jupyterlab/hub-extension
 
@@ -52,6 +54,7 @@ RUN chown  $NB_UID .
 RUN chown -R $NB_UID workspace
 
 # Temp fixes for eeg plots
+ENV NEURON_HOME=/opt/conda
 # For lfpykit 0.4
 # RUN wget -P $(pip show LFPykit | grep "Location:" | awk '{print $2"/lfpykit"}') https://www.parralab.org/nyhead/sa_nyhead.mat
 # For lpfykit 0.5
@@ -59,10 +62,6 @@ RUN wget --no-check-certificate -P ${FOLDER}/workspace https://www.parralab.org/
 
 USER $NB_UID
 
-
 EXPOSE 8888
 
 
-
-
-
diff --git a/NetPyNE-UI b/NetPyNE-UI
index abfedaeb..c7a58998 100755
--- a/NetPyNE-UI
+++ b/NetPyNE-UI
@@ -1,4 +1,4 @@
 #!/bin/sh
 CONFIG=$(pwd)/.jupyter-config
 export JUPYTER_CONFIG_DIR=$CONFIG
-exec jupyter notebook --NotebookApp.default_url=/geppetto --NotebookApp.token='' --library=netpyne_ui --NotebookApp.disable_check_xsrf=True
+exec jupyter notebook --NotebookApp.default_url=/geppetto --NotebookApp.token='' --NotebookApp.notebook_dir=workspace --library=netpyne_ui --NotebookApp.disable_check_xsrf=True
diff --git a/netpyne_ui/api.py b/netpyne_ui/api.py
index 44a65a9c..75580c53 100644
--- a/netpyne_ui/api.py
+++ b/netpyne_ui/api.py
@@ -19,7 +19,8 @@ def allowed_file(filename, allowed_extensions=ALLOWED_EXTENSIONS):
 def send_files(handler, file_path, filename):
     with open(file_path, "rb") as f:
         handler.set_header('Content-Type', 'application/force-download')
-        handler.set_header('Content-Disposition', f"attachment; filename={filename}")
+        handler.set_header('Content-Disposition',
+                           f"attachment; filename={filename}")
 
         try:
             while True:
@@ -36,7 +37,8 @@ def get_file_paths(handler):
     file_paths = False
     if 'uri' in handler.request.arguments:
         file_paths = []
-        tmp_file_paths = [path.decode('utf-8') for path in handler.request.arguments['uri']]
+        tmp_file_paths = [path.decode('utf-8')
+                          for path in handler.request.arguments['uri']]
         for path in tmp_file_paths:
             if os.path.exists(path):
                 file_paths.append(path)
@@ -69,12 +71,14 @@ def uploads(handler: IPythonHandler):
         files_saved = 0
 
         if len(files) == 0 or 'file' not in files:
-            handler.set_status(400, f"Can't find 'file' or filename is empty. Files received {len(files)}")
+            handler.set_status(
+                400, f"Can't find 'file' or filename is empty. Files received {len(files)}")
         else:
 
             for f in files['file']:
                 if not allowed_file(f.filename):
-                    logging.warn(f"Can't store file {f.filename}. Extension not allowed")
+                    logging.warn(
+                        f"Can't store file {f.filename}. Extension not allowed")
                     continue
 
                 # Save to file
@@ -120,8 +124,42 @@ def downloads(handler: IPythonHandler):
                     tar_gz_file_path = os.path.join(dir_path, tar_gz_file_name)
                     with tarfile.open(tar_gz_file_path, mode='w:gz') as tar:
                         for file_path in file_paths:
-                            tar.add(file_path, os.path.join('download', file_path.split('/')[-1]))
+                            tar.add(file_path, os.path.join(
+                                'download', file_path.split('/')[-1]))
 
                     send_files(handler, tar_gz_file_path, tar_gz_file_name)
 
         handler.finish()
+
+
+def create_notebook(filename):
+    import nbformat as nbf
+    from nbformat.v4.nbbase import new_notebook
+    from nbformat import sign
+    import codecs
+
+    directory = os.path.dirname(filename)
+    if not os.path.exists(directory):
+        os.makedirs(directory)
+    nb0 = new_notebook(cells=[nbf.v4.new_markdown_cell("""# Welcome to the NetPyNE-ui!
+    
+    """),
+                              nbf.v4.new_code_cell(
+                                  'netpyne_geppetto.netParams'),
+                              nbf.v4.new_code_cell(
+                                  'netpyne_geppetto.simConfig')
+                              ], metadata={"kernelspec": {
+                                  "display_name": "Python 3",
+                                  "language": "python",
+                                  "name": "python3"
+                              }})
+
+    f = codecs.open(filename, encoding='utf-8', mode='w')
+
+    nbf.write(nb0, filename)
+    f.close()
+
+
+# TODO move to jupyter geppetto, using notebook dir path
+if os.path.exists('workspace') and not os.path.exists('workspace/notebook.ipynb'):
+    create_notebook('workspace/notebook.ipynb')
diff --git a/netpyne_ui/constants.py b/netpyne_ui/constants.py
index 3b6c3efc..96fe3ee6 100644
--- a/netpyne_ui/constants.py
+++ b/netpyne_ui/constants.py
@@ -11,7 +11,7 @@
 TEMPLATE_FILENAME_BATCH_RUN = "batch_run_single.py"
 TEMPLATE_FILENAME_BATCH = "batch.py"
 
-ALLOWED_EXTENSIONS = ["py", "zip", "gz", ".tar.gz", "pdf", "txt", "xls", "png", "jpeg", "hoc", "json"]
+ALLOWED_EXTENSIONS = ["py", "zip", "gz", ".tar.gz", "pdf", "txt", "xls", "png", "jpeg", "hoc", "json", "xml", "nml"]
 HERE = os.path.dirname(os.path.abspath(__file__))
 ROOT = os.path.dirname(HERE)
 UPLOAD_FOLDER_PATH = os.path.join(ROOT, NETPYNE_WORKDIR, UPLOAD_FOLDER_NAME)
diff --git a/netpyne_ui/helpers/neuroml.py b/netpyne_ui/helpers/neuroml.py
new file mode 100644
index 00000000..6de12bcb
--- /dev/null
+++ b/netpyne_ui/helpers/neuroml.py
@@ -0,0 +1,117 @@
+import os
+import sys
+import logging
+from netpyne.specs import simConfig
+
+from pyneuroml import pynml
+from pyneuroml.lems import generate_lems_file_for_neuroml
+from pyneuroml.pynml import read_neuroml2_file
+
+from netpyne_ui.mod_utils import loadModMechFiles
+
+
+def convertLEMSSimulation(lemsFileName, compileMod=True):
+    """Converts a LEMS Simulation file
+
+    Converts a LEMS Simulation file (https://docs.neuroml.org/Userdocs/LEMSSimulation.html)
+    pointing to a NeuroML 2 file into the equivalent in NetPyNE
+    Returns:
+        simConfig, netParams for the model in NetPyNE
+    """
+    current_path = os.getcwd()
+    try:
+        
+        fullLemsFileName = os.path.abspath(lemsFileName)
+        tmp_path = os.path.dirname(fullLemsFileName) 
+        if tmp_path:
+            os.chdir(tmp_path)
+        logging.info(
+            "Importing LEMSSimulation with NeuroML 2 network from: %s"
+            % fullLemsFileName
+        )
+
+        result = pynml.run_lems_with_jneuroml_netpyne(
+            lemsFileName, only_generate_json=True, exit_on_fail=False)
+        
+        if result == False:
+            raise Exception("Error loading lems file")
+        lems = pynml.read_lems_file(lemsFileName)
+
+        np_json_fname = fullLemsFileName.replace('.xml','_netpyne_data.json')
+    
+        return np_json_fname
+    finally:
+        os.chdir(current_path)
+
+
+
+
+def convertNeuroML2(nml2FileName,  compileMod=True):
+    """Loads a NeuroML 2 file into NetPyNE
+    Loads a NeuroML 2 file into NetPyNE by creating a new LEMS Simulation
+    file (https://docs.neuroml.org/Userdocs/LEMSSimulation.html) and using jNeuroML
+    to convert it.
+
+    Returns:
+        simConfig, netParams for the model in NetPyNE
+    """
+    current_path = os.getcwd()
+    try:
+        fullNmlFileName = os.path.abspath(nml2FileName)
+        work_path = os.path.dirname(fullNmlFileName) 
+        if not os.path.exists(work_path):
+            os.makedirs(work_path)
+        os.chdir(work_path)
+        sys.path.append(work_path)
+        
+
+        logging.info(
+                "Importing NeuroML 2 network from: %s"
+                % fullNmlFileName
+            )
+        nml_model = read_neuroml2_file(fullNmlFileName)
+
+        target = nml_model.networks[0].id
+        sim_id = "Sim_%s" % target
+        duration = 1000
+        dt = 0.025
+        lems_file_name = os.path.join(os.path.dirname(fullNmlFileName), "LEMS_%s.xml" % sim_id)
+        lems_file_name = "LEMS_%s.xml" % sim_id
+        target_dir = os.path.dirname(fullNmlFileName)
+        target_dir = "."
+
+        generate_lems_file_for_neuroml(
+            sim_id,
+            fullNmlFileName,
+            target,
+            duration,
+            dt,
+            lems_file_name,
+            target_dir,
+            include_extra_files=["PyNN.xml"],
+            gen_plots_for_all_v=True,
+            plot_all_segments=False,
+            gen_plots_for_quantities={},  # Dict with displays vs lists of quantity paths
+            gen_plots_for_only_populations=[],  # List of populations, all pops if = []
+            gen_saves_for_all_v=True,
+            save_all_segments=False,
+            gen_saves_for_only_populations=[],  # List of populations, all pops if = []
+            gen_saves_for_quantities={},  # Dict with file names vs lists of quantity paths
+            gen_spike_saves_for_all_somas=True,
+            report_file_name="report.txt",
+            copy_neuroml=True,
+            verbose=True,
+        )
+        os.chdir(work_path)
+        res = convertLEMSSimulation(lems_file_name, compileMod=compileMod)
+    finally:
+        os.chdir(current_path)
+    return res
+
+
+if __name__ == "__main__":
+
+    if '-nml' in sys.argv:
+        convertNeuroML2("../../NeuroML2/Spikers.net.nml")
+    else:
+        convertLEMSSimulation("LEMS_HHSimple.xml")
diff --git a/netpyne_ui/mod_utils.py b/netpyne_ui/mod_utils.py
index f3f09975..a727808c 100644
--- a/netpyne_ui/mod_utils.py
+++ b/netpyne_ui/mod_utils.py
@@ -26,7 +26,7 @@ def is_loaded_mechanisms():
         return True
 
 
-def compileModMechFiles(compileMod, modFolder):
+def loadModMechFiles(compileMod, modFolder):
     # Create Symbolic link
     if compileMod:
         modPath = os.path.join(str(modFolder), "x86_64")
@@ -38,7 +38,7 @@ def compileModMechFiles(compileMod, modFolder):
         subprocess.call(["nrnivmodl"])
         os.chdir('..')
 
-        try:
-            neuron.load_mechanisms(str(modFolder))
-        except:
-            raise
+    try:
+        neuron.load_mechanisms(str(modFolder))
+    except:
+        raise
diff --git a/netpyne_ui/netpyne_geppetto.py b/netpyne_ui/netpyne_geppetto.py
index 0a46e358..bdcc89ad 100644
--- a/netpyne_ui/netpyne_geppetto.py
+++ b/netpyne_ui/netpyne_geppetto.py
@@ -3,12 +3,17 @@
 
 Initialise NetPyNE Geppetto, this class contains methods to connect NetPyNE with the Geppetto based UI
 """
+import json
+import os
+from os.path import join, dirname
+from glob import glob
 import copy
 import dataclasses
 import importlib
 import json
 import logging
 import os
+import pprint
 import re
 import sys
 from shutil import copyfile
@@ -36,13 +41,12 @@
 from jupyter_geppetto import jupyter_geppetto, synchronization, utils
 from contextlib import redirect_stdout
 from netpyne_ui.constants import NETPYNE_WORKDIR_PATH, NUM_CONN_LIMIT
-from netpyne_ui.mod_utils import compileModMechFiles
+from netpyne_ui.mod_utils import loadModMechFiles
 
 os.chdir(constants.NETPYNE_WORKDIR_PATH)
 
 neuron.nrn_dll_loaded.append(os.path.join(NETPYNE_WORKDIR_PATH, 'mod'))  # Avoids to load workspace modfiles twice
 
-
 class NetPyNEGeppetto:
 
     def __init__(self):
@@ -180,13 +184,7 @@ def stopExperiment(self, experiment_name):
         }
 
     def find_tutorials(self):
-        only_files = [f for f in os.listdir(constants.NETPYNE_WORKDIR_PATH) if
-                      os.path.isfile(os.path.join(constants.NETPYNE_WORKDIR_PATH, f))]
-
-        def _filter(_file):
-            return '.py' in _file and 'tut' in _file and 'gui' in _file
-
-        return list(filter(_filter, only_files))
+        return glob(join(NETPYNE_WORKDIR_PATH, "**/gui_tut*.py"), recursive=True)
 
     def instantiateNetPyNEModelInGeppetto(self, args):
         try:
@@ -209,7 +207,7 @@ def simulate_experiment_trials(self, experiment: model.Experiment):
         except OSError:
             experiment.state = model.ExperimentState.ERROR
             return utils.getJSONError("The specified folder already exists", "")
-
+        logging.info("Running experiment %s combinations", experiment.name)
         try:
             simulations.run(
                 platform="local",
@@ -222,6 +220,7 @@ def simulate_experiment_trials(self, experiment: model.Experiment):
             )
         except InvalidConfigError as e:
             experiment.state = model.ExperimentState.ERROR
+            logging.error("Error running experiment %s: %s", experiment.name, str(e))
             return utils.getJSONError(str(e), "")
 
         if self.run_config.asynchronous:
@@ -432,7 +431,7 @@ def loadModel(self, args):
 
         try:
             owd = os.getcwd()
-            compileModMechFiles(args['compileMod'], args['modFolder'])
+            loadModMechFiles(args['compileMod'], args['modFolder'])
         except Exception:
             message = "Error while importing/compiling mods"
             logging.exception(message)
@@ -512,6 +511,8 @@ def _create3D_shapes(self, json_path: str):
                 # Load again because gatherData removed simData
                 sim.loadSimData(json_path)
 
+
+
     def importModel(self, modelParameters):
         """ Imports a model stored in form of Python files.
 
@@ -522,13 +523,16 @@ def importModel(self, modelParameters):
             # TODO: this must be integrated into the general lifecycle of "model change -> simulate"
             #   Shouldn't be specific to Import
             sim.clearAll()
-
+        try:
+            loadModMechFiles(modelParameters['compileMod'], modelParameters['modFolder'])
+        except Exception:
+            message = "Error while importing/compiling mods"
+            logging.exception(message)
+            return utils.getJSONError(message, sys.exc_info())
         try:
             # Get Current dir
             owd = os.getcwd()
 
-            compileModMechFiles(modelParameters['compileMod'], modelParameters['modFolder'])
-
             with redirect_stdout(sys.__stdout__):
                 # NetParams
                 net_params_path = str(modelParameters["netParamsPath"])
@@ -569,6 +573,66 @@ def importModel(self, modelParameters):
         finally:
             os.chdir(owd)
 
+    def importNeuroML(self, modelParameters):
+        from netpyne_ui.helpers import neuroml
+       
+
+        try:
+            # Get Current dir
+            owd = os.getcwd()
+
+            with redirect_stdout(sys.__stdout__):
+                # NetParams
+                filename = str(modelParameters["fileName"])
+               
+                json_fname = neuroml.convertNeuroML2(filename, compileMod=modelParameters["compileMod"])
+                   
+            return self.loadModel(args=dict(
+                compileMod=True,
+                modFolder=os.path.dirname(json_fname),
+                jsonModelFolder=json_fname,
+                loadNet=True,
+                loadSimData=True,
+                loadSimCfg=True,
+                loadNetParams=True
+            ))
+        except:
+            message = "Error while importing the NetPyNE model"
+            logging.exception(message)
+            return utils.getJSONError(message, sys.exc_info())
+        finally:
+            os.chdir(owd)
+
+    def importLEMS(self, modelParameters):
+        from netpyne_ui.helpers import neuroml
+       
+
+        try:
+            # Get Current dir
+            owd = os.getcwd()
+
+            with redirect_stdout(sys.__stdout__):
+                # NetParams
+                filename = str(modelParameters["fileName"])
+               
+                json_fname =  neuroml.convertLEMSSimulation(filename)
+
+            return self.loadModel(args=dict(
+                compileMod=True,
+                modFolder=os.path.dirname(json_fname),
+                jsonModelFolder=json_fname,
+                loadNet=True,
+                loadSimData=True,
+                loadSimCfg=True,
+                loadNetParams=True
+            ))
+        except Exception:
+            message = "Error while importing the NetPyNE model"
+            logging.exception(message)
+            return utils.getJSONError(message, sys.exc_info())
+        finally:
+            os.chdir(owd)
+
     def importCellTemplate(self, modelParameters):
         try:
             with redirect_stdout(sys.__stdout__):
@@ -578,7 +642,7 @@ def importCellTemplate(self, modelParameters):
 
                 conds = {} if rule not in self.netParams.cellParams else self.netParams.cellParams[rule]['conds']
 
-                compileModMechFiles(modelParameters["compileMod"], modelParameters["modFolder"])
+                loadModMechFiles(modelParameters["compileMod"], modelParameters["modFolder"])
 
                 del modelParameters["modFolder"]
                 del modelParameters["compileMod"]
@@ -627,7 +691,7 @@ def exportNeuroML(self, modelParams):
             logging.exception(message)
             return utils.getJSONError(message, sys.exc_info())
 
-    def importNeuroML(self, modelParams):
+    def importNeuroMLOLD(self, modelParams):
         try:
             with redirect_stdout(sys.__stdout__):
                 sim.initialize()
diff --git a/netpyne_ui/simulations.py b/netpyne_ui/simulations.py
index a2e0fe90..df19464a 100644
--- a/netpyne_ui/simulations.py
+++ b/netpyne_ui/simulations.py
@@ -41,7 +41,7 @@ def run(self, parallel, cores, method="", batch=False, asynchronous=False, worki
             raise InvalidConfigError(
                 f"Specified {cores} cores, but only {self.cpus} are available")
 
-        logging.info(f"Scheduling simulation on {cores} cores ...")
+        logging.info(f"Scheduling simulation on {cores} cores with {method} ...")
 
         if batch or asynchronous or parallel:
             if method == MPI_DIRECT:
@@ -91,7 +91,8 @@ def _run_in_subprocess(self, cmds, asynchronous=False, working_directory: str =
         if self.is_running():
             logging.info("Another simulation is still running")
             return False
-
+        logging.info("Running simulations on subprocess inside directory %s", working_directory)
+        logging.info("Running commands: \n%s", "\n".join(cmds))
         if working_directory:
             with open(os.path.join(working_directory, 'sim.log'), 'w') as f:
                 self.subprocess = subprocess.Popen(cmds, stdout=f, stderr=f)
diff --git a/netpyne_ui/templates/batch.py b/netpyne_ui/templates/batch.py
index eba6702d..d3811e83 100644
--- a/netpyne_ui/templates/batch.py
+++ b/netpyne_ui/templates/batch.py
@@ -9,8 +9,13 @@
 from netpyne import specs
 from netpyne.batch import Batch
 
-os.chdir(os.path.dirname(__file__))
+CURRENT_DIR = "."
+try:
+    CURRENT_DIR = os.path.dirname(__file__)
+except:
+    pass
 
+os.chdir(CURRENT_DIR)
 
 def is_error():
     """Validates if Experiment failed or succeeded.
@@ -19,9 +24,9 @@ def is_error():
     """
 
     data_files = list(pathlib.Path(
-        os.path.dirname(__file__)).glob(f"*_data.json"))
+        CURRENT_DIR).glob(f"*_data.json"))
     cfg_files = list(pathlib.Path(
-        os.path.dirname(__file__)).glob(f"*_cfg.json"))
+        CURRENT_DIR).glob(f"*_cfg.json"))
 
     if len(data_files) != len(cfg_files):
         print(
diff --git a/requirements.txt b/requirements.txt
index eb061906..fb0fd5c7 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,4 +1,4 @@
-airspeed==0.5.4dev-20150515
+airspeed==0.5.20
 alembic==1.4.2
 async-generator==1.10
 attrs==19.3.0
@@ -29,11 +29,12 @@ jupyter-core==4.9.1
 jupyter-server==1.11.2
 jupyterhub==1.5.0
 jupyterlab==3.2.4
+neuromllite==0.5.1
 jupyterthemes==0.20.0
 kiwisolver==1.2.0
 lesscpy==0.14.0
+libNeuroML==0.4.0
 lfpykit==0.5
-libNeuroML==0.2.50
 lxml==4.5.1
 Mako==1.1.0
 MarkupSafe==1.1.1
@@ -43,7 +44,6 @@ mistune==0.8.4
 multimethod==1.3
 nbconvert==5.6.1
 nbformat==5.0.6
-neuromllite==0.1.9
 netpyne==1.0.3.1
 NEURON==8.0.2
 numpy==1.18.5
@@ -64,10 +64,14 @@ pycosat==0.6.3
 pycparser==2.20
 pyecore==0.11.7
 pygeppetto==0.8.1
+PyLEMS==0.5.9
+pyNeuroML==0.7.1
+sentry_sdk==1.5.2
+dacite==1.6.0
+h5py==3.7.0
+jsonpickle==2.1.0
 Pygments==2.6.1
 PyJWT==1.7.1
-PyLEMS==0.4.9.3
-pyNeuroML==0.3.15
 pyOpenSSL==19.1.0
 pyparsing==2.4.7
 pyrsistent==0.16.0
@@ -85,7 +89,6 @@ ruamel-yaml==0.15.80
 ruamel.yaml.clib==0.2.0
 scipy==1.4.1
 Send2Trash==1.5.0
-sentry_sdk==1.5.2
 terminado==0.8.3
 testpath==0.4.4
 tornado==6.1.0
@@ -95,5 +98,4 @@ urllib3==1.25.9
 webencodings==0.5.1
 widgetsnbextension==3.5.1
 wrapt==1.12.1
-zipp==3.1.0
-dacite==1.6.0
+zipp==3.1.0
\ No newline at end of file
diff --git a/run.py b/run.py
index bd3d26d2..5da5f591 100644
--- a/run.py
+++ b/run.py
@@ -9,14 +9,15 @@
 
 os.environ['JUPYTER_CONFIG_DIR'] = os.path.join(os.path.dirname(os.path.abspath(__file__)), '.jupyter-config')
 
-settings.debug = True
+settings.debug = False
 
 if __name__ == '__main__':
     sys.argv.append('--NotebookApp.default_url=/geppetto')
     sys.argv.append("--NotebookApp.token=''")
     sys.argv.append('--library=netpyne_ui')
+    sys.argv.append('--no-browser')
     sys.argv.append('--NotebookApp.disable_check_xsrf=True')
-
+    
     app = NotebookApp.instance()
     app.initialize(sys.argv)
     app.file_to_run = ''
diff --git a/setup.py b/setup.py
index cb35c63f..61c62c72 100644
--- a/setup.py
+++ b/setup.py
@@ -3,11 +3,14 @@
 import os
 from glob import glob
 
-#This block copies resources to the server so we avoid jupyter nbextension install --py --sys-prefix jupyter_geppetto
+# This block copies resources to the server so we avoid jupyter nbextension install --py --sys-prefix jupyter_geppetto
 data_files = []
-data_files.append(('geppetto/src/main/webapp/build/', glob('src/jupyter_geppetto/geppetto/src/main/webapp/build/*.js')))
-data_files.append(('geppetto/src/main/webapp/build/', glob('src/jupyter_geppetto/geppetto/src/main/webapp/build/*.vm')))
-data_files.append(('geppetto/geppetto/src/main/webapp/build/', glob('src/jupyter_geppetto/geppetto/src/main/webapp/build/fonts/*')))
+data_files.append(('geppetto/src/main/webapp/build/',
+                  glob('src/jupyter_geppetto/geppetto/src/main/webapp/build/*.js')))
+data_files.append(('geppetto/src/main/webapp/build/',
+                  glob('src/jupyter_geppetto/geppetto/src/main/webapp/build/*.vm')))
+data_files.append(('geppetto/geppetto/src/main/webapp/build/',
+                  glob('src/jupyter_geppetto/geppetto/src/main/webapp/build/fonts/*')))
 for root, dirnames, filenames in os.walk('src/jupyter_geppetto/geppetto/src/main/webapp/js/'):
     for filename in fnmatch.filter(filenames, '*'):
         data_files.append((root[3:], [os.path.join(root, filename)]))
@@ -38,7 +41,13 @@
     ],
     install_requires=[
         'jupyter-geppetto>=1.0.0',
-        'NEURON>=8.0.2'
-        'netpyne>=1.0.2.1'
+        'NEURON>=8.0.2',
+        'netpyne>=1.0.2.1',
+        'neuromllite==0.5.1',
+        'pyNeuroML>=0.7.1',
+        'sentry_sdk>=1.5.2',
+        'dacite>=1.6.0',
+        'h5py>=3.7.0',
+        'jsonpickle>=2.1.0'
     ],
 )
diff --git a/utilities/install.py b/utilities/install.py
index 08ec5323..d47e3b58 100644
--- a/utilities/install.py
+++ b/utilities/install.py
@@ -87,6 +87,7 @@ def compile_mod():
 def main(netpyne_branch, workspace_branch, geppetto_branch=None, skipNpm=False,
          skipTest=False, development=False):
     cprint("Installing requirements")
+    print(workspace_branch)
     execute(cmd=['pip', 'install', '-r', 'requirements.txt'], cwd=ROOT_DIR)
 
     if not os.path.exists(DEPS_DIR):
@@ -126,10 +127,11 @@ def main(netpyne_branch, workspace_branch, geppetto_branch=None, skipNpm=False,
         execute(cmd=['pip', 'install', '-e', '.', '--no-deps'], cwd=ROOT_DIR)
 
     os.chdir(ROOT_DIR)
-    cprint("Cloning workspace")
-    clone(repository=WORKSPACE, branch_or_tag=workspace_branch, folder=WORKSPACE_DIR, cwdp=ROOT_DIR)
-    cprint("Compiling workspace modules")
-    compile_mod()
+    if workspace_branch:
+      cprint("Cloning workspace")
+      clone(repository=WORKSPACE, branch_or_tag=workspace_branch, folder=WORKSPACE_DIR, cwdp=ROOT_DIR)
+      cprint("Compiling workspace modules")
+      compile_mod()
 
     if not skipNpm and os.path.exists(os.path.join(DEPS_DIR, META_DIR, JUPYTER_DIR)):
         cprint("Building Jupyter Geppetto extension...")
diff --git a/webapp/Main.js b/webapp/Main.js
index 47623feb..9d878fac 100644
--- a/webapp/Main.js
+++ b/webapp/Main.js
@@ -13,8 +13,7 @@ import '@metacell/geppetto-meta-ui/flex-layout/style/dark.scss';
 global.GEPPETTO_CONFIGURATION = require('./GeppettoConfiguration.json');
 const { initGeppetto } = require('@metacell/geppetto-meta-client/GEPPETTO');
 
-if (process.env.NODE_ENV == 'production')
-{
+if (process.env.NODE_ENV === 'production') {
   Sentry.init({
     dsn: 'https://d8bf7e40eec34cb9891f6dd8207b5e83@sentry.metacell.us/6',
     integrations: [
@@ -26,7 +25,7 @@ if (process.env.NODE_ENV == 'production')
   });
 }
 
-
+window.$ = Array; // TODO Temporary fix -- remove upon https://github.com/MetaCell/geppetto-meta/issues/380 
 initGeppetto();
 require('./css/netpyne.less');
 require('./css/material.less');
diff --git a/webapp/components/general/NetPyNEPythonConsole.js b/webapp/components/general/NetPyNEPythonConsole.js
index b8f4de25..90135e00 100644
--- a/webapp/components/general/NetPyNEPythonConsole.js
+++ b/webapp/components/general/NetPyNEPythonConsole.js
@@ -3,8 +3,6 @@ import React, { Component } from 'react';
 import { PythonConsole } from '@metacell/geppetto-meta-ui/python-console/PythonConsole';
 
 export class NetPyNEPythonConsole extends Component {
-  componentDidMount () {
-  }
 
   shouldComponentUpdate (nextProps) {
     if (this.props.extensionLoaded !== nextProps.extensionLoaded) {
@@ -13,12 +11,17 @@ export class NetPyNEPythonConsole extends Component {
     return false;
   }
 
-  componentWillUnmount () {
-    console.info('unmounting python console');
+  componentWillUnmount() {
+    console.info("unmounting python console");
+  }
+
+  componentDidMount() {
+
   }
 
-  render () {
-    return <PythonConsole pythonNotebookPath="notebooks/notebook.ipynb" extensionLoaded={this.props.extensionLoaded} />;
+  render() {
+    const notebookName = GEPPETTO_CONFIGURATION.notebookName || "notebook.ipynb";
+    return <PythonConsole pythonNotebookPath={`notebooks/${notebookName}`} extensionLoaded={this.props.extensionLoaded} />
   }
 }
 
diff --git a/webapp/components/topbar/Topbar.js b/webapp/components/topbar/Topbar.js
index 372630ff..3a0cf405 100644
--- a/webapp/components/topbar/Topbar.js
+++ b/webapp/components/topbar/Topbar.js
@@ -13,6 +13,7 @@ import toolbarConfig, {
 import { bgRegular } from '../../theme';
 import Splash from '../general/Splash';
 
+import ImportFileDialog from './dialogs/ImportFileDialog';
 import LoadFileDialog from './dialogs/LoadFile';
 import SaveFileDialog from './dialogs/SaveFile';
 import NewModelDialog from './dialogs/NewModel';
@@ -20,7 +21,7 @@ import ImportExportHLSDialog from './dialogs/ImportExportHLS';
 import ImportCellParamsDialog from './dialogs/ImportCellParams';
 import UploadDownloadFilesDialog from './dialogs/UploadDownloadFiles';
 
-import { TOPBAR_CONSTANTS, MODEL_STATE, DEFAULT_CONFIRMATION_DIALOG_MESSAGE } from '../../constants';
+import { TOPBAR_CONSTANTS, MODEL_STATE, DEFAULT_CONFIRMATION_DIALOG_MESSAGE, NETPYNE_COMMANDS } from '../../constants';
 import { LOAD_TUTORIAL } from '../../redux/actions/general';
 
 const styles = () => ({
@@ -209,6 +210,32 @@ class Topbar extends Component {
             />
           );
           break;
+          case TOPBAR_CONSTANTS.IMPORT_NEUROML:
+            content = (
+              <ImportFileDialog
+                open={dialogOpen}
+                onRequestClose={() => this.handleClose()}
+                title="Import from NeuroML 2"
+                command={NETPYNE_COMMANDS.importNeuroML}
+                modelState={modelState}
+                extension=".net.nml"
+                openConfirmationDialog={(payload) => openConfirmationDialog(payload)}
+              />
+            );
+            break;
+            case TOPBAR_CONSTANTS.IMPORT_LEMS:
+              content = (
+                <ImportFileDialog
+                  open={dialogOpen}
+                  onRequestClose={() => this.handleClose()}
+                  command={NETPYNE_COMMANDS.importLEMS}
+                  title="Import simulation from LEMS"
+                  modelState={modelState}
+                  extension=".xml"
+                  openConfirmationDialog={(payload) => openConfirmationDialog(payload)}
+                />
+              );
+              break;
         default:
           content = <div />;
           break;
diff --git a/webapp/components/topbar/dialogs/ImportFileDialog.js b/webapp/components/topbar/dialogs/ImportFileDialog.js
new file mode 100644
index 00000000..40855b28
--- /dev/null
+++ b/webapp/components/topbar/dialogs/ImportFileDialog.js
@@ -0,0 +1,237 @@
+import React from 'react';
+import TextField from '@material-ui/core/TextField';
+import InputAdornment from '@material-ui/core/InputAdornment';
+import Icon from '@material-ui/core/Icon';
+import Box from '@material-ui/core/Box';
+
+import { withStyles } from '@material-ui/core/styles';
+
+import { ActionDialog, Tooltip } from 'netpyne/components';
+import { NETPYNE_COMMANDS, MODEL_STATE, DEFAULT_CONFIRMATION_DIALOG_MESSAGE } from '../../../constants';
+import { PYTHON_CALL } from '../../../redux/actions/general';
+import FileBrowser from '../../general/FileBrowser';
+import Checkbox from '../../general/Checkbox';
+
+const styles = ({
+  spacing,
+  typography,
+  zIndex,
+}) => ({
+  container: {
+    marginTop: spacing(2),
+    display: 'flex',
+    flexDirection: 'row',
+    alignItems: 'baseline',
+    width: '100%',
+  },
+  selectField: {
+    marginTop: spacing(3),
+    width: '100%',
+  },
+  selectFieldLabel: { top: -spacing(2) },
+  icon: {
+    '&:hover': { backgroundColor: 'inherit' },
+    flex: '0 0 4%',
+    marginRight: spacing(2),
+    width: typography.h3.fontSize,
+    height: typography.h3.fontSize,
+    padding: '0px!important',
+    zIndex: zIndex.modal,
+  },
+});
+
+class ImportFileDialog extends React.Component {
+  constructor(props) {
+    super(props);
+    this.state = this.initialState();
+
+    this.isFormValid = this.isFormValid.bind(this);
+  }
+
+  initialState() {
+    return {
+      fileName: null,
+      modFolder: '',
+      loadMod: false,
+      compileMod: true,
+      explorerDialogOpen: false,
+      explorerParameter: '',
+      exploreOnlyDirs: false,
+      filterFiles: false,
+    };
+  }
+
+  isFormValid() {
+
+    // FIXME: Set to undefine to show error text. No particularly elegant
+    if (this.state.loadMod === '') {
+      this.setState({ loadMod: undefined });
+    }
+    return this.state.loadMod !== undefined && this.state.loadMod !== '';
+  }
+
+
+
+  showExplorerDialog(explorerParameter, exploreOnlyDirs, filterFiles) {
+    this.setState({
+      explorerDialogOpen: true,
+      explorerParameter,
+      exploreOnlyDirs,
+      filterFiles,
+    });
+  }
+
+  closeExplorerDialog(fieldValue) {
+    const newState = { explorerDialogOpen: false };
+    if (fieldValue) {
+      /*
+       * var fileName = fieldValue.path.replace(/^.*[\\\/]/, '');
+       * var fileNameNoExtension = fileName.replace(/\.[^/.]+$/, "");
+       * var path = fieldValue.path.split(fileName).slice(0, -1).join('');
+       */
+      const {
+        dirPath,
+        moduleName,
+      } = this.getDirAndModuleFromPath(fieldValue.path);
+      switch (this.state.explorerParameter) {
+        case 'file':
+          newState.fileName=fieldValue?.path
+          newState.modFolder = dirPath;
+          break;
+        case 'modFolder':
+          newState.modFolder = fieldValue.path;
+          newState.loadMod = true;
+          break;
+        default:
+          throw Error('Not a valid parameter!');
+      }
+    }
+    this.setState({ ...newState });
+  }
+
+  getDirAndModuleFromPath(fullpath) {
+    const fileName = fullpath.replace(/^.*[\\/]/, '');
+    const moduleName = fileName.replace(/\.[^/.]+$/, '');
+    const dirPath = fullpath.split(fileName)
+      .slice(0, -1)
+      .join('');
+
+    return {
+      dirPath,
+      moduleName,
+    };
+  }
+
+  onFilePathChange(fullpath) {
+    this.setState({ fileName: fullpath });
+  }
+
+
+  onModFolderPathChange(fullpath) {
+    if (fullpath !== '') {
+      this.setState({
+        modFolder: fullpath,
+        loadMod: true,
+      });
+    } else {
+      this.setState({
+        modFolder: fullpath,
+        loadMod: false,
+      });
+    }
+  }
+
+  handleConfirmation(command, args) {
+    this.props.openConfirmationDialog({
+      title: 'Warning',
+      message: DEFAULT_CONFIRMATION_DIALOG_MESSAGE,
+      onConfirm: {
+        type: PYTHON_CALL,
+        cmd: command,
+        args,
+      },
+    });
+  }
+
+  render() {
+    const { classes, modelState, extension, title, command, modFileSelector=false } = this.props;
+    const message = 'IMPORTING MODEL';
+    const buttonLabel = 'Import';
+
+
+
+    return (
+      <ActionDialog
+        command={command}
+        message={message}
+        buttonLabel={buttonLabel}
+        args={this.state}
+        title={title}
+        isFormValid={this.isFormValid}
+        callback={modelState === MODEL_STATE.INSTANTIATED || modelState === MODEL_STATE.SIMULATED ? (command, args) => { this.handleConfirmation(command, args); } : undefined}
+        {...this.props}
+      >
+        <Box>
+          <TextField
+            variant="filled"
+            fullWidth
+            value={this.state.fileName}
+            onChange={(event) => this.onFilePathChange(event.target.value)}
+            label="Choose file"
+            helperText={`Only ${extension} files`}
+            InputProps={{
+              startAdornment: (
+                <InputAdornment position="start">
+                  <Tooltip title="File explorer" placement="top">
+                    <Icon
+                      className="fa fa-folder hovered"
+                      style={{ cursor: 'pointer' }}
+                      onClick={() => this.showExplorerDialog('file', false, extension)}
+                    />
+                  </Tooltip>
+                </InputAdornment>
+              ),
+            }}
+          />
+          { modFileSelector && <TextField
+              variant="filled"
+              fullWidth
+              label="Path to mod files"
+              value={this.state.modFolder}
+              onChange={(event) => this.onModFolderPathChange(event.target.value)}
+              helperText="Important: if external mod files are required please select the mod folder path"
+              InputProps={{
+                startAdornment: (
+                  <InputAdornment position="start">
+                    <Tooltip title="File explorer" placement="top">
+                      <Icon
+                        onClick={() => this.showExplorerDialog('modFolder', true, false)}
+                        className="fa fa-folder hovered"
+                        style={{ cursor: 'pointer' }}
+                      />
+                    </Tooltip>
+                  </InputAdornment>
+                ),
+              }}
+            /> }
+            <Checkbox
+              fullWidth
+              noBackground
+              label="Compile mod files"
+              checked={this.state.compileMod}
+              onChange={() => this.setState((oldState) => ({ compileMod: !oldState.compileMod }))}
+            />
+        </Box>
+        <FileBrowser
+          open={this.state.explorerDialogOpen}
+          exploreOnlyDirs={this.state.exploreOnlyDirs}
+          filterFiles={this.state.filterFiles}
+          onRequestClose={(selection) => this.closeExplorerDialog(selection)}
+        />
+      </ActionDialog>
+    )
+      ;
+  }
+}
+
+export default withStyles(styles)(ImportFileDialog);
diff --git a/webapp/components/topbar/menuConfiguration.js b/webapp/components/topbar/menuConfiguration.js
index 12a06906..1c8ee950 100644
--- a/webapp/components/topbar/menuConfiguration.js
+++ b/webapp/components/topbar/menuConfiguration.js
@@ -76,7 +76,7 @@ export const getTutorials = () => {
   }
   return tuts.sort()
     .map((tutFile) => {
-      const tutName = tutFile.replace('.py', '')
+      const tutName = tutFile.split("/").pop().replace('.py', '')
         .replace('gui', '')
         .replace('_', '');
       const tutLabel = TUTORIALS_LIST[tutName] !== undefined ? TUTORIALS_LIST[tutName] : tutName;
@@ -186,6 +186,22 @@ export default {
                 parameters: [openTopbarDialog, TOPBAR_CONSTANTS.IMPORT_HLS],
               },
             },
+            {
+              label: 'From NeuroML2 (beta)...',
+              icon: '',
+              action: {
+                handlerAction: 'redux',
+                parameters: [openTopbarDialog, TOPBAR_CONSTANTS.IMPORT_NEUROML],
+              },
+            },
+            {
+              label: 'From LEMS Simulation  (beta)...',
+              icon: '',
+              action: {
+                handlerAction: 'redux',
+                parameters: [openTopbarDialog, TOPBAR_CONSTANTS.IMPORT_LEMS],
+              },
+            },
           ],
         },
         {
diff --git a/webapp/constants.js b/webapp/constants.js
index f1cb2278..0115ab07 100644
--- a/webapp/constants.js
+++ b/webapp/constants.js
@@ -36,6 +36,8 @@ export const NETPYNE_COMMANDS = {
   getExperiments: 'netpyne_geppetto.experiments.get_experiments',
   cloneExperiment: 'netpyne_geppetto.cloneExperiment',
   viewExperimentResults: 'netpyne_geppetto.viewExperimentResult',
+  importNeuroML: 'netpyne_geppetto.importNeuroML',
+  importLEMS: 'netpyne_geppetto.importLEMS',
 };
 
 export const REAL_TYPE = {
@@ -84,6 +86,8 @@ export const TOPBAR_CONSTANTS = {
   BACK_TO_EDITION: 'BACK TO EDIT',
   NEW_PAGE: 'NEW_PAGE',
   NETWORK_MODEL: 'NETWORK_MODEL',
+  IMPORT_NEUROML: 'IMPORT_NEUROML',
+  IMPORT_LEMS: 'IMPORT_LEMS'
 };
 
 /*
diff --git a/webapp/package.bak b/webapp/package.bak
index 925a50ca..f9c0f976 100644
--- a/webapp/package.bak
+++ b/webapp/package.bak
@@ -1,12 +1,12 @@
 {
   "name": "geppetto-netpyne",
-  "version": "0.8.1",
+  "version": "0.9.0",
   "description": "Geppetto NetPyNE-UI frontend.",
   "repository": "https://github.com/MetaCell/NetPyNE-UI",
   "license": "MIT",
   "scripts": {
     "lint": "eslint . --color --fix",
-    "build": "webpack --mode development -p --progress --devtool source-map",
+    "build": "webpack --mode production -p --progress --devtool source-map",
     "build-dev": "webpack --mode development --devtool source-map",
     "build-dev-noTest": "webpack --mode development --devtool source-map --env.noTest=true",
     "build-dev-noTest:watch": "webpack --mode development --devtool source-map --env.noTest=true --progress --watch",
@@ -19,9 +19,9 @@
     "@material-ui/core": "4.12.1",
     "@material-ui/icons": "^4.11.2",
     "@material-ui/lab": "^4.0.0-alpha.60",
-    "@metacell/geppetto-meta-client": "1.0.0-final",
-    "@metacell/geppetto-meta-core": "1.0.0-final",
-    "@metacell/geppetto-meta-ui": "1.0.0-final",
+    "@metacell/geppetto-meta-client": "1.1.0",
+    "@metacell/geppetto-meta-core": "1.1.0",
+    "@metacell/geppetto-meta-ui": "1.1.0",
     "@nosferatu500/react-sortable-tree": "3.0.5",
     "@sentry/integrations": "^6.16.1",
     "@sentry/react": "^6.16.1",
@@ -37,7 +37,7 @@
     "react-json-view": "^1.21.3",
     "react-redux": "^7.2.0",
     "react-sortable-tree": "^2.8.0",
-    "redux": "^4.1.0",
+    "redux": "4.1.2",
     "sass": "^1.49.0",
     "sass-loader": "^7.2.0",
     "three": "0.111.0"
@@ -110,4 +110,4 @@
       ]
     }
   }
-}
+}
\ No newline at end of file
diff --git a/webapp/package.json b/webapp/package.json
index 998fdbe0..2c5165cd 100644
--- a/webapp/package.json
+++ b/webapp/package.json
@@ -110,4 +110,4 @@
       ]
     }
   }
-}
+}
\ No newline at end of file
diff --git a/webapp/redux/middleware/middleware.js b/webapp/redux/middleware/middleware.js
index eb8ea814..b0b67d8a 100644
--- a/webapp/redux/middleware/middleware.js
+++ b/webapp/redux/middleware/middleware.js
@@ -8,7 +8,7 @@ import {
   VIEW_EXPERIMENTS_RESULTS,
   TRIAL_LOAD_MODEL_SPEC
 } from 'root/redux/actions/experiments';
-import { NETPYNE_COMMANDS, EDIT_WIDGETS } from 'root/constants';
+import { NETPYNE_COMMANDS, EDIT_WIDGETS } from '../../constants';
 import * as GeppettoActions from '@metacell/geppetto-meta-client/common/actions';
 import * as ExperimentsApi from '../../api/experiments';
 
@@ -374,25 +374,39 @@ export default (store) => (next) => (action) => {
         }
         next(closeDrawerDialogBox);
       };
+
+      switch (action.cmd) {
+        case NETPYNE_COMMANDS.importNeuroML:
+          case NETPYNE_COMMANDS.importModel:
+            case NETPYNE_COMMANDS.importNeuroML:
+              next(GeppettoActions.waitData('Importing Model...', "RECEIVE_PYTHON_MESSAGE"));
+              break;
+        default:
+          break;
+      }
+      
       pythonCall(action)
         .then(callback, pythonErrorCallback);
       next(action);
       break;
     }
     case LOAD_TUTORIAL: {
-      const tutName = action.payload.replace('.py', '');
+      const path = action.payload.split("/");
+      const filename  = path.pop()
+      const dirname = path.join("/")
+      const tutName = filename.replace('.py', '');
       next(GeppettoActions.waitData(`Importing ${tutName}...`, LOAD_TUTORIAL));
 
       const params = {
-        modFolder: 'mod',
+        modFolder: dirname + '/mod',
         loadMod: false,
-        compileMod: false,
+        compileMod: true,
 
-        netParamsPath: '.',
+        netParamsPath: dirname,
         netParamsModuleName: tutName,
         netParamsVariable: 'netParams',
 
-        simConfigPath: '.',
+        simConfigPath: dirname,
         simConfigModuleName: tutName,
         simConfigVariable: 'simConfig',
       };
diff --git a/webapp/webpack.config.js b/webapp/webpack.config.js
index f5589c0d..4dd9fc52 100644
--- a/webapp/webpack.config.js
+++ b/webapp/webpack.config.js
@@ -108,6 +108,7 @@ module.exports = function (env) {
 
   return {
     entry: entries,
+    devtool: 'source-map',
 
     optimization: {
       splitChunks: {
diff --git a/webapp/yarn.lock b/webapp/yarn.lock
index 416f762a..96d7cb87 100644
--- a/webapp/yarn.lock
+++ b/webapp/yarn.lock
@@ -24,38 +24,38 @@
   dependencies:
     "@babel/highlight" "^7.18.6"
 
-"@babel/compat-data@^7.17.7", "@babel/compat-data@^7.20.0", "@babel/compat-data@^7.20.1":
-  version "7.20.5"
-  resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.20.5.tgz#86f172690b093373a933223b4745deeb6049e733"
-  integrity sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g==
+"@babel/compat-data@^7.17.7", "@babel/compat-data@^7.20.1", "@babel/compat-data@^7.20.5":
+  version "7.20.10"
+  resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.20.10.tgz#9d92fa81b87542fff50e848ed585b4212c1d34ec"
+  integrity sha512-sEnuDPpOJR/fcafHMjpcpGN5M2jbUGUHwmuWKM/YdPzeEDJg8bgmbcWQFUfE32MQjti1koACvoPVsDe8Uq+idg==
 
 "@babel/core@^7.4.5":
-  version "7.20.5"
-  resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.20.5.tgz#45e2114dc6cd4ab167f81daf7820e8fa1250d113"
-  integrity sha512-UdOWmk4pNWTm/4DlPUl/Pt4Gz4rcEMb7CY0Y3eJl5Yz1vI8ZJGmHWaVE55LoxRjdpx0z259GE9U5STA9atUinQ==
+  version "7.20.7"
+  resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.20.7.tgz#37072f951bd4d28315445f66e0ec9f6ae0c8c35f"
+  integrity sha512-t1ZjCluspe5DW24bn2Rr1CDb2v9rn/hROtg9a2tmd0+QYf4bsloYfLQzjG4qHPNMhWtKdGC33R5AxGR2Af2cBw==
   dependencies:
     "@ampproject/remapping" "^2.1.0"
     "@babel/code-frame" "^7.18.6"
-    "@babel/generator" "^7.20.5"
-    "@babel/helper-compilation-targets" "^7.20.0"
-    "@babel/helper-module-transforms" "^7.20.2"
-    "@babel/helpers" "^7.20.5"
-    "@babel/parser" "^7.20.5"
-    "@babel/template" "^7.18.10"
-    "@babel/traverse" "^7.20.5"
-    "@babel/types" "^7.20.5"
+    "@babel/generator" "^7.20.7"
+    "@babel/helper-compilation-targets" "^7.20.7"
+    "@babel/helper-module-transforms" "^7.20.7"
+    "@babel/helpers" "^7.20.7"
+    "@babel/parser" "^7.20.7"
+    "@babel/template" "^7.20.7"
+    "@babel/traverse" "^7.20.7"
+    "@babel/types" "^7.20.7"
     convert-source-map "^1.7.0"
     debug "^4.1.0"
     gensync "^1.0.0-beta.2"
     json5 "^2.2.1"
     semver "^6.3.0"
 
-"@babel/generator@^7.20.5":
-  version "7.20.5"
-  resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.20.5.tgz#cb25abee3178adf58d6814b68517c62bdbfdda95"
-  integrity sha512-jl7JY2Ykn9S0yj4DQP82sYvPU+T3g0HFcWTqDLqiuA9tGRNIj9VfbtXGAYTTkyNEnQk1jkMGOdYka8aG/lulCA==
+"@babel/generator@^7.20.7":
+  version "7.20.7"
+  resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.20.7.tgz#f8ef57c8242665c5929fe2e8d82ba75460187b4a"
+  integrity sha512-7wqMOJq8doJMZmP4ApXTzLxSr7+oO2jroJURrVEp6XShrQUObV8Tq/D0NCcoYg2uHqUrjzO0zwBjoYzelxK+sw==
   dependencies:
-    "@babel/types" "^7.20.5"
+    "@babel/types" "^7.20.7"
     "@jridgewell/gen-mapping" "^0.3.2"
     jsesc "^2.5.1"
 
@@ -74,27 +74,28 @@
     "@babel/helper-explode-assignable-expression" "^7.18.6"
     "@babel/types" "^7.18.9"
 
-"@babel/helper-compilation-targets@^7.17.7", "@babel/helper-compilation-targets@^7.18.9", "@babel/helper-compilation-targets@^7.20.0":
-  version "7.20.0"
-  resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz#6bf5374d424e1b3922822f1d9bdaa43b1a139d0a"
-  integrity sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==
+"@babel/helper-compilation-targets@^7.17.7", "@babel/helper-compilation-targets@^7.18.9", "@babel/helper-compilation-targets@^7.20.0", "@babel/helper-compilation-targets@^7.20.7":
+  version "7.20.7"
+  resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz#a6cd33e93629f5eb473b021aac05df62c4cd09bb"
+  integrity sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==
   dependencies:
-    "@babel/compat-data" "^7.20.0"
+    "@babel/compat-data" "^7.20.5"
     "@babel/helper-validator-option" "^7.18.6"
     browserslist "^4.21.3"
+    lru-cache "^5.1.1"
     semver "^6.3.0"
 
-"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.20.2", "@babel/helper-create-class-features-plugin@^7.20.5":
-  version "7.20.5"
-  resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.5.tgz#327154eedfb12e977baa4ecc72e5806720a85a06"
-  integrity sha512-3RCdA/EmEaikrhayahwToF0fpweU/8o2p8vhc1c/1kftHOdTKuC65kik/TLc+qfbS8JKw4qqJbne4ovICDhmww==
+"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.20.5", "@babel/helper-create-class-features-plugin@^7.20.7":
+  version "7.20.7"
+  resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.7.tgz#d0e1f8d7e4ed5dac0389364d9c0c191d948ade6f"
+  integrity sha512-LtoWbDXOaidEf50hmdDqn9g8VEzsorMexoWMQdQODbvmqYmaF23pBP5VNPAGIFHsFQCIeKokDiz3CH5Y2jlY6w==
   dependencies:
     "@babel/helper-annotate-as-pure" "^7.18.6"
     "@babel/helper-environment-visitor" "^7.18.9"
     "@babel/helper-function-name" "^7.19.0"
-    "@babel/helper-member-expression-to-functions" "^7.18.9"
+    "@babel/helper-member-expression-to-functions" "^7.20.7"
     "@babel/helper-optimise-call-expression" "^7.18.6"
-    "@babel/helper-replace-supers" "^7.19.1"
+    "@babel/helper-replace-supers" "^7.20.7"
     "@babel/helper-split-export-declaration" "^7.18.6"
 
 "@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.20.5":
@@ -144,12 +145,12 @@
   dependencies:
     "@babel/types" "^7.18.6"
 
-"@babel/helper-member-expression-to-functions@^7.18.9":
-  version "7.18.9"
-  resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz#1531661e8375af843ad37ac692c132841e2fd815"
-  integrity sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg==
+"@babel/helper-member-expression-to-functions@^7.20.7":
+  version "7.20.7"
+  resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.20.7.tgz#a6f26e919582275a93c3aa6594756d71b0bb7f05"
+  integrity sha512-9J0CxJLq315fEdi4s7xK5TQaNYjZw+nDVpVqr1axNGKzdrdwYBD5b4uKv3n75aABG0rCCTK8Im8Ww7eYfMrZgw==
   dependencies:
-    "@babel/types" "^7.18.9"
+    "@babel/types" "^7.20.7"
 
 "@babel/helper-module-imports@^7.18.6":
   version "7.18.6"
@@ -158,19 +159,19 @@
   dependencies:
     "@babel/types" "^7.18.6"
 
-"@babel/helper-module-transforms@^7.18.6", "@babel/helper-module-transforms@^7.19.6", "@babel/helper-module-transforms@^7.20.2":
-  version "7.20.2"
-  resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.20.2.tgz#ac53da669501edd37e658602a21ba14c08748712"
-  integrity sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA==
+"@babel/helper-module-transforms@^7.18.6", "@babel/helper-module-transforms@^7.19.6", "@babel/helper-module-transforms@^7.20.7":
+  version "7.20.7"
+  resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.20.7.tgz#7a6c9a1155bef55e914af574153069c9d9470c43"
+  integrity sha512-FNdu7r67fqMUSVuQpFQGE6BPdhJIhitoxhGzDbAXNcA07uoVG37fOiMk3OSV8rEICuyG6t8LGkd9EE64qIEoIA==
   dependencies:
     "@babel/helper-environment-visitor" "^7.18.9"
     "@babel/helper-module-imports" "^7.18.6"
     "@babel/helper-simple-access" "^7.20.2"
     "@babel/helper-split-export-declaration" "^7.18.6"
     "@babel/helper-validator-identifier" "^7.19.1"
-    "@babel/template" "^7.18.10"
-    "@babel/traverse" "^7.20.1"
-    "@babel/types" "^7.20.2"
+    "@babel/template" "^7.20.7"
+    "@babel/traverse" "^7.20.7"
+    "@babel/types" "^7.20.7"
 
 "@babel/helper-optimise-call-expression@^7.18.6":
   version "7.18.6"
@@ -184,7 +185,7 @@
   resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz#d1b9000752b18d0877cff85a5c376ce5c3121629"
   integrity sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==
 
-"@babel/helper-remap-async-to-generator@^7.18.6", "@babel/helper-remap-async-to-generator@^7.18.9":
+"@babel/helper-remap-async-to-generator@^7.18.9":
   version "7.18.9"
   resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz#997458a0e3357080e54e1d79ec347f8a8cd28519"
   integrity sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==
@@ -194,25 +195,26 @@
     "@babel/helper-wrap-function" "^7.18.9"
     "@babel/types" "^7.18.9"
 
-"@babel/helper-replace-supers@^7.18.6", "@babel/helper-replace-supers@^7.19.1":
-  version "7.19.1"
-  resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.19.1.tgz#e1592a9b4b368aa6bdb8784a711e0bcbf0612b78"
-  integrity sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw==
+"@babel/helper-replace-supers@^7.18.6", "@babel/helper-replace-supers@^7.20.7":
+  version "7.20.7"
+  resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.20.7.tgz#243ecd2724d2071532b2c8ad2f0f9f083bcae331"
+  integrity sha512-vujDMtB6LVfNW13jhlCrp48QNslK6JXi7lQG736HVbHz/mbf4Dc7tIRh1Xf5C0rF7BP8iiSxGMCmY6Ci1ven3A==
   dependencies:
     "@babel/helper-environment-visitor" "^7.18.9"
-    "@babel/helper-member-expression-to-functions" "^7.18.9"
+    "@babel/helper-member-expression-to-functions" "^7.20.7"
     "@babel/helper-optimise-call-expression" "^7.18.6"
-    "@babel/traverse" "^7.19.1"
-    "@babel/types" "^7.19.0"
+    "@babel/template" "^7.20.7"
+    "@babel/traverse" "^7.20.7"
+    "@babel/types" "^7.20.7"
 
-"@babel/helper-simple-access@^7.19.4", "@babel/helper-simple-access@^7.20.2":
+"@babel/helper-simple-access@^7.20.2":
   version "7.20.2"
   resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz#0ab452687fe0c2cfb1e2b9e0015de07fc2d62dd9"
   integrity sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==
   dependencies:
     "@babel/types" "^7.20.2"
 
-"@babel/helper-skip-transparent-expression-wrappers@^7.18.9":
+"@babel/helper-skip-transparent-expression-wrappers@^7.20.0":
   version "7.20.0"
   resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz#fbe4c52f60518cab8140d77101f0e63a8a230684"
   integrity sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==
@@ -251,14 +253,14 @@
     "@babel/traverse" "^7.20.5"
     "@babel/types" "^7.20.5"
 
-"@babel/helpers@^7.20.5":
-  version "7.20.6"
-  resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.20.6.tgz#e64778046b70e04779dfbdf924e7ebb45992c763"
-  integrity sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w==
+"@babel/helpers@^7.20.7":
+  version "7.20.7"
+  resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.20.7.tgz#04502ff0feecc9f20ecfaad120a18f011a8e6dce"
+  integrity sha512-PBPjs5BppzsGaxHQCDKnZ6Gd9s6xl8bBCluz3vEInLGRJmnZan4F6BYCeqtyXqkk4W5IlPmjK4JlOuZkpJ3xZA==
   dependencies:
-    "@babel/template" "^7.18.10"
-    "@babel/traverse" "^7.20.5"
-    "@babel/types" "^7.20.5"
+    "@babel/template" "^7.20.7"
+    "@babel/traverse" "^7.20.7"
+    "@babel/types" "^7.20.7"
 
 "@babel/highlight@^7.10.4", "@babel/highlight@^7.18.6":
   version "7.18.6"
@@ -269,10 +271,10 @@
     chalk "^2.0.0"
     js-tokens "^4.0.0"
 
-"@babel/parser@^7.18.10", "@babel/parser@^7.20.5", "@babel/parser@^7.7.0":
-  version "7.20.5"
-  resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.20.5.tgz#7f3c7335fe417665d929f34ae5dceae4c04015e8"
-  integrity sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==
+"@babel/parser@^7.20.7", "@babel/parser@^7.7.0":
+  version "7.20.7"
+  resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.20.7.tgz#66fe23b3c8569220817d5feb8b9dcdc95bb4f71b"
+  integrity sha512-T3Z9oHybU+0vZlY9CiDSJQTD5ZapcW18ZctFMi0MOAl/4BjFF4ul7NVSARLdbGO5vDqy9eQiGTV0LtKfvCYvcg==
 
 "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.18.6":
   version "7.18.6"
@@ -282,21 +284,21 @@
     "@babel/helper-plugin-utils" "^7.18.6"
 
 "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.18.9":
-  version "7.18.9"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.18.9.tgz#a11af19aa373d68d561f08e0a57242350ed0ec50"
-  integrity sha512-AHrP9jadvH7qlOj6PINbgSuphjQUAK7AOT7DPjBo9EHoLhQTnnK5u45e1Hd4DbSQEO9nqPWtQ89r+XEOWFScKg==
+  version "7.20.7"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.20.7.tgz#d9c85589258539a22a901033853101a6198d4ef1"
+  integrity sha512-sbr9+wNE5aXMBBFBICk01tt7sBf2Oc9ikRFEcem/ZORup9IMUdNhW7/wVLEbbtlWOsEubJet46mHAL2C8+2jKQ==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.18.9"
-    "@babel/helper-skip-transparent-expression-wrappers" "^7.18.9"
-    "@babel/plugin-proposal-optional-chaining" "^7.18.9"
+    "@babel/helper-plugin-utils" "^7.20.2"
+    "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0"
+    "@babel/plugin-proposal-optional-chaining" "^7.20.7"
 
 "@babel/plugin-proposal-async-generator-functions@^7.20.1":
-  version "7.20.1"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.1.tgz#352f02baa5d69f4e7529bdac39aaa02d41146af9"
-  integrity sha512-Gh5rchzSwE4kC+o/6T8waD0WHEQIsDmjltY8WnWRXHUdH8axZhuH86Ov9M72YhJfDrZseQwuuWaaIT/TmePp3g==
+  version "7.20.7"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.7.tgz#bfb7276d2d573cb67ba379984a2334e262ba5326"
+  integrity sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA==
   dependencies:
     "@babel/helper-environment-visitor" "^7.18.9"
-    "@babel/helper-plugin-utils" "^7.19.0"
+    "@babel/helper-plugin-utils" "^7.20.2"
     "@babel/helper-remap-async-to-generator" "^7.18.9"
     "@babel/plugin-syntax-async-generators" "^7.8.4"
 
@@ -309,12 +311,12 @@
     "@babel/helper-plugin-utils" "^7.18.6"
 
 "@babel/plugin-proposal-class-static-block@^7.18.6":
-  version "7.18.6"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.18.6.tgz#8aa81d403ab72d3962fc06c26e222dacfc9b9020"
-  integrity sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw==
+  version "7.20.7"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.20.7.tgz#92592e9029b13b15be0f7ce6a7aedc2879ca45a7"
+  integrity sha512-AveGOoi9DAjUYYuUAG//Ig69GlazLnoyzMw68VCDux+c1tsnnH/OkYcpz/5xzMkEFC6UxjR5Gw1c+iY2wOGVeQ==
   dependencies:
-    "@babel/helper-create-class-features-plugin" "^7.18.6"
-    "@babel/helper-plugin-utils" "^7.18.6"
+    "@babel/helper-create-class-features-plugin" "^7.20.7"
+    "@babel/helper-plugin-utils" "^7.20.2"
     "@babel/plugin-syntax-class-static-block" "^7.14.5"
 
 "@babel/plugin-proposal-dynamic-import@^7.18.6":
@@ -342,11 +344,11 @@
     "@babel/plugin-syntax-json-strings" "^7.8.3"
 
 "@babel/plugin-proposal-logical-assignment-operators@^7.18.9":
-  version "7.18.9"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.18.9.tgz#8148cbb350483bf6220af06fa6db3690e14b2e23"
-  integrity sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q==
+  version "7.20.7"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.20.7.tgz#dfbcaa8f7b4d37b51e8bfb46d94a5aea2bb89d83"
+  integrity sha512-y7C7cZgpMIjWlKE5T7eJwp+tnRYM89HmRvWM5EQuB5BoHEONjmQ8lSNmBUwOyy/GFRsohJED51YBF79hE1djug==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.18.9"
+    "@babel/helper-plugin-utils" "^7.20.2"
     "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4"
 
 "@babel/plugin-proposal-nullish-coalescing-operator@^7.18.6":
@@ -366,15 +368,15 @@
     "@babel/plugin-syntax-numeric-separator" "^7.10.4"
 
 "@babel/plugin-proposal-object-rest-spread@^7.20.2":
-  version "7.20.2"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.2.tgz#a556f59d555f06961df1e572bb5eca864c84022d"
-  integrity sha512-Ks6uej9WFK+fvIMesSqbAto5dD8Dz4VuuFvGJFKgIGSkJuRGcrwGECPA1fDgQK3/DbExBJpEkTeYeB8geIFCSQ==
+  version "7.20.7"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz#aa662940ef425779c75534a5c41e9d936edc390a"
+  integrity sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==
   dependencies:
-    "@babel/compat-data" "^7.20.1"
-    "@babel/helper-compilation-targets" "^7.20.0"
+    "@babel/compat-data" "^7.20.5"
+    "@babel/helper-compilation-targets" "^7.20.7"
     "@babel/helper-plugin-utils" "^7.20.2"
     "@babel/plugin-syntax-object-rest-spread" "^7.8.3"
-    "@babel/plugin-transform-parameters" "^7.20.1"
+    "@babel/plugin-transform-parameters" "^7.20.7"
 
 "@babel/plugin-proposal-optional-catch-binding@^7.18.6":
   version "7.18.6"
@@ -384,13 +386,13 @@
     "@babel/helper-plugin-utils" "^7.18.6"
     "@babel/plugin-syntax-optional-catch-binding" "^7.8.3"
 
-"@babel/plugin-proposal-optional-chaining@^7.18.9":
-  version "7.18.9"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.18.9.tgz#e8e8fe0723f2563960e4bf5e9690933691915993"
-  integrity sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w==
+"@babel/plugin-proposal-optional-chaining@^7.18.9", "@babel/plugin-proposal-optional-chaining@^7.20.7":
+  version "7.20.7"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.20.7.tgz#49f2b372519ab31728cc14115bb0998b15bfda55"
+  integrity sha512-T+A7b1kfjtRM51ssoOfS1+wbyCVqorfyZhT99TvxxLMirPShD8CzKMRepMlCBGM5RpHMbn8s+5MMHnPstJH6mQ==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.18.9"
-    "@babel/helper-skip-transparent-expression-wrappers" "^7.18.9"
+    "@babel/helper-plugin-utils" "^7.20.2"
+    "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0"
     "@babel/plugin-syntax-optional-chaining" "^7.8.3"
 
 "@babel/plugin-proposal-private-methods@^7.18.6":
@@ -539,20 +541,20 @@
     "@babel/helper-plugin-utils" "^7.19.0"
 
 "@babel/plugin-transform-arrow-functions@^7.18.6":
-  version "7.18.6"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.18.6.tgz#19063fcf8771ec7b31d742339dac62433d0611fe"
-  integrity sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ==
+  version "7.20.7"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.20.7.tgz#bea332b0e8b2dab3dafe55a163d8227531ab0551"
+  integrity sha512-3poA5E7dzDomxj9WXWwuD6A5F3kc7VXwIJO+E+J8qtDtS+pXPAhrgEyh+9GBwBgPq1Z+bB+/JD60lp5jsN7JPQ==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.18.6"
+    "@babel/helper-plugin-utils" "^7.20.2"
 
 "@babel/plugin-transform-async-to-generator@^7.18.6":
-  version "7.18.6"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.18.6.tgz#ccda3d1ab9d5ced5265fdb13f1882d5476c71615"
-  integrity sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag==
+  version "7.20.7"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.20.7.tgz#dfee18623c8cb31deb796aa3ca84dda9cea94354"
+  integrity sha512-Uo5gwHPT9vgnSXQxqGtpdufUiWp96gk7yiP4Mp5bm1QMkEmLXBO7PAGYbKoJ6DhAwiNkcHFBol/x5zZZkL/t0Q==
   dependencies:
     "@babel/helper-module-imports" "^7.18.6"
-    "@babel/helper-plugin-utils" "^7.18.6"
-    "@babel/helper-remap-async-to-generator" "^7.18.6"
+    "@babel/helper-plugin-utils" "^7.20.2"
+    "@babel/helper-remap-async-to-generator" "^7.18.9"
 
 "@babel/plugin-transform-block-scoped-functions@^7.18.6":
   version "7.18.6"
@@ -562,38 +564,39 @@
     "@babel/helper-plugin-utils" "^7.18.6"
 
 "@babel/plugin-transform-block-scoping@^7.20.2":
-  version "7.20.5"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.5.tgz#401215f9dc13dc5262940e2e527c9536b3d7f237"
-  integrity sha512-WvpEIW9Cbj9ApF3yJCjIEEf1EiNJLtXagOrL5LNWEZOo3jv8pmPoYTSNJQvqej8OavVlgOoOPw6/htGZro6IkA==
+  version "7.20.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.9.tgz#2034307073e243fd476dddb5472ec35d13802853"
+  integrity sha512-hwZN0kr16UkIF/kR9F9x8gd1kTkQl1vyAF2lkUmlTuCtTKOGLE5blQctuxEeKXwz0dkArQ9RYL8+HLb/75KGMA==
   dependencies:
     "@babel/helper-plugin-utils" "^7.20.2"
 
 "@babel/plugin-transform-classes@^7.20.2":
-  version "7.20.2"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.20.2.tgz#c0033cf1916ccf78202d04be4281d161f6709bb2"
-  integrity sha512-9rbPp0lCVVoagvtEyQKSo5L8oo0nQS/iif+lwlAz29MccX2642vWDlSZK+2T2buxbopotId2ld7zZAzRfz9j1g==
+  version "7.20.7"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.20.7.tgz#f438216f094f6bb31dc266ebfab8ff05aecad073"
+  integrity sha512-LWYbsiXTPKl+oBlXUGlwNlJZetXD5Am+CyBdqhPsDVjM9Jc8jwBJFrKhHf900Kfk2eZG1y9MAG3UNajol7A4VQ==
   dependencies:
     "@babel/helper-annotate-as-pure" "^7.18.6"
-    "@babel/helper-compilation-targets" "^7.20.0"
+    "@babel/helper-compilation-targets" "^7.20.7"
     "@babel/helper-environment-visitor" "^7.18.9"
     "@babel/helper-function-name" "^7.19.0"
     "@babel/helper-optimise-call-expression" "^7.18.6"
     "@babel/helper-plugin-utils" "^7.20.2"
-    "@babel/helper-replace-supers" "^7.19.1"
+    "@babel/helper-replace-supers" "^7.20.7"
     "@babel/helper-split-export-declaration" "^7.18.6"
     globals "^11.1.0"
 
 "@babel/plugin-transform-computed-properties@^7.18.9":
-  version "7.18.9"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.9.tgz#2357a8224d402dad623caf6259b611e56aec746e"
-  integrity sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw==
+  version "7.20.7"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.20.7.tgz#704cc2fd155d1c996551db8276d55b9d46e4d0aa"
+  integrity sha512-Lz7MvBK6DTjElHAmfu6bfANzKcxpyNPeYBGEafyA6E5HtRpjpZwU+u7Qrgz/2OR0z+5TvKYbPdphfSaAcZBrYQ==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.18.9"
+    "@babel/helper-plugin-utils" "^7.20.2"
+    "@babel/template" "^7.20.7"
 
 "@babel/plugin-transform-destructuring@^7.20.2":
-  version "7.20.2"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.20.2.tgz#c23741cfa44ddd35f5e53896e88c75331b8b2792"
-  integrity sha512-mENM+ZHrvEgxLTBXUiQ621rRXZes3KWUv6NdQlrnr1TkWVw+hUjQBZuP2X32qKlrlG2BzgR95gkuCRSkJl8vIw==
+  version "7.20.7"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.20.7.tgz#8bda578f71620c7de7c93af590154ba331415454"
+  integrity sha512-Xwg403sRrZb81IVB79ZPqNQME23yhugYVqgTxAhT99h485F4f+GMELFhhOsscDUB7HCswepKeCKLn/GZvUKoBA==
   dependencies:
     "@babel/helper-plugin-utils" "^7.20.2"
 
@@ -651,21 +654,21 @@
     "@babel/helper-plugin-utils" "^7.18.6"
 
 "@babel/plugin-transform-modules-amd@^7.19.6":
-  version "7.19.6"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.19.6.tgz#aca391801ae55d19c4d8d2ebfeaa33df5f2a2cbd"
-  integrity sha512-uG3od2mXvAtIFQIh0xrpLH6r5fpSQN04gIVovl+ODLdUMANokxQLZnPBHcjmv3GxRjnqwLuHvppjjcelqUFZvg==
+  version "7.20.7"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.20.7.tgz#1e5cfeb4e5f9b392e86f85698896336b442f8760"
+  integrity sha512-+1IVLD+dHOzRZWNFFSoyPZz4ffsVmOP+OhhjeahLKpU97v/52LcCb9RabRl5eHM1/HAuH5Dl0q9Pyzrq1v2otQ==
   dependencies:
-    "@babel/helper-module-transforms" "^7.19.6"
-    "@babel/helper-plugin-utils" "^7.19.0"
+    "@babel/helper-module-transforms" "^7.20.7"
+    "@babel/helper-plugin-utils" "^7.20.2"
 
 "@babel/plugin-transform-modules-commonjs@^7.19.6":
-  version "7.19.6"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.19.6.tgz#25b32feef24df8038fc1ec56038917eacb0b730c"
-  integrity sha512-8PIa1ym4XRTKuSsOUXqDG0YaOlEuTVvHMe5JCfgBMOtHvJKw/4NGovEGN33viISshG/rZNVrACiBmPQLvWN8xQ==
+  version "7.20.7"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.20.7.tgz#abb5f84695e74d46acf48244082f6cbf8bb23120"
+  integrity sha512-76jqqFiFdCD+RJwEdtBHUG2/rEKQAmpejPbAKyQECEE3/y4U5CMPc9IXvipS990vgQhzq+ZRw6WJ+q4xJ/P24w==
   dependencies:
-    "@babel/helper-module-transforms" "^7.19.6"
-    "@babel/helper-plugin-utils" "^7.19.0"
-    "@babel/helper-simple-access" "^7.19.4"
+    "@babel/helper-module-transforms" "^7.20.7"
+    "@babel/helper-plugin-utils" "^7.20.2"
+    "@babel/helper-simple-access" "^7.20.2"
 
 "@babel/plugin-transform-modules-systemjs@^7.19.6":
   version "7.19.6"
@@ -708,10 +711,10 @@
     "@babel/helper-plugin-utils" "^7.18.6"
     "@babel/helper-replace-supers" "^7.18.6"
 
-"@babel/plugin-transform-parameters@^7.20.1":
-  version "7.20.5"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.5.tgz#f8f9186c681d10c3de7620c916156d893c8a019e"
-  integrity sha512-h7plkOmcndIUWXZFLgpbrh2+fXAi47zcUX7IrOQuZdLD0I0KvjJ6cvo3BEcAOsDOcZhVKGJqv07mkSqK0y2isQ==
+"@babel/plugin-transform-parameters@^7.20.1", "@babel/plugin-transform-parameters@^7.20.7":
+  version "7.20.7"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.7.tgz#0ee349e9d1bc96e78e3b37a7af423a4078a7083f"
+  integrity sha512-WiWBIkeHKVOSYPO0pWkxGPfKeWrCJyD3NJ53+Lrp/QMSZbsVPovrVl2aWZ19D/LTVnaDv5Ap7GJ/B2CTOZdrfA==
   dependencies:
     "@babel/helper-plugin-utils" "^7.20.2"
 
@@ -737,15 +740,15 @@
     "@babel/plugin-transform-react-jsx" "^7.18.6"
 
 "@babel/plugin-transform-react-jsx@^7.18.6":
-  version "7.19.0"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.19.0.tgz#b3cbb7c3a00b92ec8ae1027910e331ba5c500eb9"
-  integrity sha512-UVEvX3tXie3Szm3emi1+G63jyw1w5IcMY0FSKM+CRnKRI5Mr1YbCNgsSTwoTwKphQEG9P+QqmuRFneJPZuHNhg==
+  version "7.20.7"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.20.7.tgz#025d85a1935fd7e19dfdcb1b1d4df34d4da484f7"
+  integrity sha512-Tfq7qqD+tRj3EoDhY00nn2uP2hsRxgYGi5mLQ5TimKav0a9Lrpd4deE+fcLXU8zFYRjlKPHZhpCvfEA6qnBxqQ==
   dependencies:
     "@babel/helper-annotate-as-pure" "^7.18.6"
     "@babel/helper-module-imports" "^7.18.6"
-    "@babel/helper-plugin-utils" "^7.19.0"
+    "@babel/helper-plugin-utils" "^7.20.2"
     "@babel/plugin-syntax-jsx" "^7.18.6"
-    "@babel/types" "^7.19.0"
+    "@babel/types" "^7.20.7"
 
 "@babel/plugin-transform-react-pure-annotations@^7.18.6":
   version "7.18.6"
@@ -790,12 +793,12 @@
     "@babel/helper-plugin-utils" "^7.18.6"
 
 "@babel/plugin-transform-spread@^7.19.0":
-  version "7.19.0"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.19.0.tgz#dd60b4620c2fec806d60cfaae364ec2188d593b6"
-  integrity sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w==
+  version "7.20.7"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.20.7.tgz#c2d83e0b99d3bf83e07b11995ee24bf7ca09401e"
+  integrity sha512-ewBbHQ+1U/VnH1fxltbJqDeWBU1oNLG8Dj11uIv3xVf7nrQu0bPGe5Rf716r7K5Qz+SqtAOVswoVunoiBtGhxw==
   dependencies:
-    "@babel/helper-plugin-utils" "^7.19.0"
-    "@babel/helper-skip-transparent-expression-wrappers" "^7.18.9"
+    "@babel/helper-plugin-utils" "^7.20.2"
+    "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0"
 
 "@babel/plugin-transform-sticky-regex@^7.18.6":
   version "7.18.6"
@@ -819,11 +822,11 @@
     "@babel/helper-plugin-utils" "^7.18.9"
 
 "@babel/plugin-transform-typescript@^7.18.6":
-  version "7.20.2"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.20.2.tgz#91515527b376fc122ba83b13d70b01af8fe98f3f"
-  integrity sha512-jvS+ngBfrnTUBfOQq8NfGnSbF9BrqlR6hjJ2yVxMkmO5nL/cdifNbI30EfjRlN4g5wYWNnMPyj5Sa6R1pbLeag==
+  version "7.20.7"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.20.7.tgz#673f49499cd810ae32a1ea5f3f8fab370987e055"
+  integrity sha512-m3wVKEvf6SoszD8pu4NZz3PvfKRCMgk6D6d0Qi9hNnlM5M6CFS92EgF4EiHVLKbU0r/r7ty1hg7NPZwE7WRbYw==
   dependencies:
-    "@babel/helper-create-class-features-plugin" "^7.20.2"
+    "@babel/helper-create-class-features-plugin" "^7.20.7"
     "@babel/helper-plugin-utils" "^7.20.2"
     "@babel/plugin-syntax-typescript" "^7.20.0"
 
@@ -961,49 +964,49 @@
     "@babel/plugin-transform-typescript" "^7.18.6"
 
 "@babel/runtime-corejs3@^7.10.2":
-  version "7.20.6"
-  resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.20.6.tgz#63dae945963539ab0ad578efbf3eff271e7067ae"
-  integrity sha512-tqeujPiuEfcH067mx+7otTQWROVMKHXEaOQcAeNV5dDdbPWvPcFA8/W9LXw2NfjNmOetqLl03dfnG2WALPlsRQ==
+  version "7.20.7"
+  resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.20.7.tgz#a1e5ea3d758ba6beb715210142912e3f29981d84"
+  integrity sha512-jr9lCZ4RbRQmCR28Q8U8Fu49zvFqLxTY9AMOUz+iyMohMoAgpEcVxY+wJNay99oXOpOcCTODkk70NDN2aaJEeg==
   dependencies:
     core-js-pure "^3.25.1"
     regenerator-runtime "^0.13.11"
 
 "@babel/runtime@^7.10.2", "@babel/runtime@^7.15.4", "@babel/runtime@^7.17.8", "@babel/runtime@^7.18.9", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2":
-  version "7.20.6"
-  resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.6.tgz#facf4879bfed9b5326326273a64220f099b0fce3"
-  integrity sha512-Q+8MqP7TiHMWzSfwiJwXCjyf4GYA4Dgw3emg/7xmwsdLJOZUp+nMqcOwOzzYheuM1rhDu8FSj2l0aoMygEuXuA==
+  version "7.20.7"
+  resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.7.tgz#fcb41a5a70550e04a7b708037c7c32f7f356d8fd"
+  integrity sha512-UF0tvkUtxwAgZ5W/KrkHf0Rn0fdnLDU9ScxBrEVNUprE/MzirjK4MJUX1/BVDv00Sv8cljtukVK1aky++X1SjQ==
   dependencies:
     regenerator-runtime "^0.13.11"
 
-"@babel/template@^7.18.10":
-  version "7.18.10"
-  resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.10.tgz#6f9134835970d1dbf0835c0d100c9f38de0c5e71"
-  integrity sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==
+"@babel/template@^7.18.10", "@babel/template@^7.20.7":
+  version "7.20.7"
+  resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.20.7.tgz#a15090c2839a83b02aa996c0b4994005841fd5a8"
+  integrity sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==
   dependencies:
     "@babel/code-frame" "^7.18.6"
-    "@babel/parser" "^7.18.10"
-    "@babel/types" "^7.18.10"
+    "@babel/parser" "^7.20.7"
+    "@babel/types" "^7.20.7"
 
-"@babel/traverse@^7.19.1", "@babel/traverse@^7.20.1", "@babel/traverse@^7.20.5", "@babel/traverse@^7.7.0":
-  version "7.20.5"
-  resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.20.5.tgz#78eb244bea8270fdda1ef9af22a5d5e5b7e57133"
-  integrity sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ==
+"@babel/traverse@^7.20.5", "@babel/traverse@^7.20.7", "@babel/traverse@^7.7.0":
+  version "7.20.10"
+  resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.20.10.tgz#2bf98239597fcec12f842756f186a9dde6d09230"
+  integrity sha512-oSf1juCgymrSez8NI4A2sr4+uB/mFd9MXplYGPEBnfAuWmmyeVcHa6xLPiaRBcXkcb/28bgxmQLTVwFKE1yfsg==
   dependencies:
     "@babel/code-frame" "^7.18.6"
-    "@babel/generator" "^7.20.5"
+    "@babel/generator" "^7.20.7"
     "@babel/helper-environment-visitor" "^7.18.9"
     "@babel/helper-function-name" "^7.19.0"
     "@babel/helper-hoist-variables" "^7.18.6"
     "@babel/helper-split-export-declaration" "^7.18.6"
-    "@babel/parser" "^7.20.5"
-    "@babel/types" "^7.20.5"
+    "@babel/parser" "^7.20.7"
+    "@babel/types" "^7.20.7"
     debug "^4.1.0"
     globals "^11.1.0"
 
-"@babel/types@^7.18.10", "@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.19.0", "@babel/types@^7.20.0", "@babel/types@^7.20.2", "@babel/types@^7.20.5", "@babel/types@^7.4.4", "@babel/types@^7.7.0":
-  version "7.20.5"
-  resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.20.5.tgz#e206ae370b5393d94dfd1d04cd687cace53efa84"
-  integrity sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg==
+"@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.19.0", "@babel/types@^7.20.0", "@babel/types@^7.20.2", "@babel/types@^7.20.5", "@babel/types@^7.20.7", "@babel/types@^7.4.4", "@babel/types@^7.7.0":
+  version "7.20.7"
+  resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.20.7.tgz#54ec75e252318423fc07fb644dc6a58a64c09b7f"
+  integrity sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==
   dependencies:
     "@babel/helper-string-parser" "^7.19.4"
     "@babel/helper-validator-identifier" "^7.19.1"
@@ -2577,9 +2580,9 @@ camelcase@^5.0.0, camelcase@^5.3.1:
   integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
 
 caniuse-lite@^1.0.30001400:
-  version "1.0.30001439"
-  resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001439.tgz#ab7371faeb4adff4b74dad1718a6fd122e45d9cb"
-  integrity sha512-1MgUzEkoMO6gKfXflStpYgZDlFM7M/ck/bgfVCACO5vnAf0fXoNVHdWtqGU+MYca+4bL9Z5bpOVmR33cWW9G2A==
+  version "1.0.30001441"
+  resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001441.tgz#987437b266260b640a23cd18fbddb509d7f69f3e"
+  integrity sha512-OyxRR4Vof59I3yGWXws6i908EtGbMzVUi3ganaZQHmydk1iwDhRnvaPG2WaR0KcqrDFKrxVZHULT396LEPhXfg==
 
 caseless@~0.12.0:
   version "0.12.0"
@@ -4856,9 +4859,9 @@ immediate@~3.0.5:
   integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==
 
 immutable@^4.0.0:
-  version "4.1.0"
-  resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.1.0.tgz#f795787f0db780183307b9eb2091fcac1f6fafef"
-  integrity sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==
+  version "4.2.0"
+  resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.2.0.tgz#c91f09108ed7504c2f0faec7222f40178ff97b11"
+  integrity sha512-h4ujZ0OZ3kpvdFcwJAHXEdvawH7J8TYTB62e8xI03OSZhuGpuPY9DPXnonMN8s+uQ56gMUqMK71mXU8ob20xfA==
 
 import-fresh@^3.0.0, import-fresh@^3.2.1:
   version "3.3.0"
@@ -5315,9 +5318,9 @@ jasmine@^3.2.0:
     jasmine-core "~3.99.0"
 
 jquery@^3.6.0:
-  version "3.6.2"
-  resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.6.2.tgz#8302bbc9160646f507bdf59d136a478b312783c4"
-  integrity sha512-/e7ulNIEEYk1Z/l4X0vpxGt+B/dNsV8ghOPAWZaJs8pkGvsSC0tm33aMGylXcj/U7y4IcvwtMXPMyBFZn/gK9A==
+  version "3.6.3"
+  resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.6.3.tgz#23ed2ffed8a19e048814f13391a19afcdba160e6"
+  integrity sha512-bZ5Sy3YzKo9Fyc8wH2iIQK4JImJ6R0GWI9kL1/k7Z91ZBNgkRXE6U0JfHIizZbort8ZunhSI3jw9I6253ahKfg==
 
 js-base64@*, js-base64@^3.6.1:
   version "3.7.3"
@@ -8388,9 +8391,9 @@ tiny-warning@^1.0.2:
   integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==
 
 tinycolor2@^1.4.1:
-  version "1.4.2"
-  resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.4.2.tgz#3f6a4d1071ad07676d7fa472e1fac40a719d8803"
-  integrity sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA==
+  version "1.5.1"
+  resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.5.1.tgz#df11c5f14e6b7fdd8a9c27c2c6a5f2565fb776b7"
+  integrity sha512-BHlrsGeYN2OpkRpfAgkEwCMu6w8Quq8JkK/mp4c55NZP7OwceJObR1CPZt62TqiA0Y3J5pwuDX+fXDqc35REtg==
 
 to-arraybuffer@^1.0.0:
   version "1.0.1"


Test patch:
diff --git a/tests/backend/utils_test.py b/tests/backend/utils_test.py
index c200c565..8f49a740 100644
--- a/tests/backend/utils_test.py
+++ b/tests/backend/utils_test.py
@@ -8,4 +8,4 @@
 sentry_sdk.init()
 
 def test_compile_mod():
-    mod_utils.compileModMechFiles(True, NETPYNE_WORKDIR_PATH)
+    mod_utils.loadModMechFiles(True, NETPYNE_WORKDIR_PATH)