From ba782a962d4641a0f4eec7ea0d040104a6f354e4 Mon Sep 17 00:00:00 2001
From: Dilawar Singh <dilawar@users.noreply.github.com>
Date: Tue, 18 Sep 2018 10:48:30 +0530
Subject: [PATCH] Pulled in changes on Sep 17, 2018 (#242)

* Squashed 'moose-core/' changes from d229eba6bb..ec06b242ae

ec06b242ae HotFix: Fix regression in StreadyState solver caused by #293. (#304)
385a5cf0a1 Merge pull request #303 from upibhalla/master
080767c5aa Fixes to rdesigneur due to bad merge. Cleanup on rmoogli
62f8bc89e0 Tweak to Neuron.cpp so it can handle insertion of spines with uniform spacing.
342092829c Update moose_test.py (#301)
f1230f1518 Merge branch 'master' of https://github.com/upibhalla/moose-core
23a2892cc8 Merge branch 'master' of https://github.com/BhallaLab/moose-core
8a835c1332 minor bugfix to rdesigneur
6ef1d567ec Merge branch 'master' into master
a9a2e758ff Merge branch 'master' of https://github.com/BhallaLab/moose-core
5e1294d991 Further updates to rdesigneur for argument handling
a702bded54 Put in kwargs based specification of plotList, stimList and moogList. Folded savePlots into plotList but not yet tested.

git-subtree-dir: moose-core
git-subtree-split: ec06b242ae650f413d50b9c22b76381a94efcba4

* Squashed 'moose-examples/' changes from 2d9849222d..e30d87a637

e30d87a637 Merge pull request #47 from BhallaLab/nml2
e350e8a801 Fixed path in script.
1602f54763 Added missing NML files and removed unneccessary files.
6d6c27e051 nml2 snippets.
3963e7969a Merge pull request #46 from upibhalla/master
4165c53e4a Merge branch 'master' of https://github.com/BhallaLab/moose-examples
2c0afa8fcc Clean up of ephys1 and ephys2 tutorials
9793e59f6c Merge branch 'master' of https://github.com/BhallaLab/moose-examples
2e91700547 Merge pull request #45 from upibhalla/master
7420933455 Added missing image file
70a3b3fc1c Test with python2.7, python3.6 and python3.7 .
bf6c180ee1 Use pypi nightly version to test.
075d01c1af Merge pull request #44 from upibhalla/master
13da78cfc0 Merge branch 'master' of https://github.com/BhallaLab/moose-examples
e3cd31b515 Added Ephys demo for Rall's Law
2e12a9b42a Added squid demo with pyqt5.
410103e36a Use moose.element to get the element.
8f71469d17 Merge pull request #42 from upibhalla/master
77f6694e0e cleanup of some rdesigneur tutorials
9a6f8e214e Merge branch 'master' of https://github.com/BhallaLab/moose-examples
cc44a7e4fb Added demo for uniform spine placement, and putting them in a spiral
3a25620865 First commit for Electrophys tutorial directory
1502a55070 removed old script.
3b7a109b5e Merge branch 'master' of https://github.com/BhallaLab/moose-examples
4336dc3ae8 Fixed passiveDistrib argument list, got rid of unused '.' argument in a few examples
c5e895f30e Updated ex7.5 and README
9f95a87909 Merge branch 'master' of https://github.com/BhallaLab/moose-examples
9ce8913fa5 Added 3 demos for dendritic transport

git-subtree-dir: moose-examples
git-subtree-split: e30d87a6374107d7f0494587dd3d868a22a58e20

* Squashed 'moose-gui/' changes from d226931e0b..c29cede420

c29cede420 hen vertical or horizontal layout is applied for group, compartment size is recalculated
d76d66af1d Function moved to place other than parentpool location its pullback
d03482329c color field is not editable for compartment, enzcplxpool and reaction
0a4b1cab43 compartment boundary is selected if its inside another compartment interior
02b9d3964f comparment size is calculated based on group sceneBoundingRect
8dae832c35 kkitViewcontrol both the groups size are updated if moved from-to is different
44b53bc56d default: addSolver->mooseAddChemSolver, kkitViewcontrol: while rubberbandselection if entire group is selected then delete if partly selected then delete all the items under the selection
80b599f85d mgui: is popup exist then close, objectedit: objectwindowTitle is updated with name when changed, kkit: in positionChange all the neutral is updated with size, kkitViewcontrol:when moose object is moved from Compt/group to group/compartment then mooseobject path is set and for qgraphicalItem and qlineitem objects the parentItem is set which will be grpItem or comptItem

git-subtree-dir: moose-gui
git-subtree-split: c29cede4201bd25dfe868aaaa9d227ea455410ae
---
 moose-core/CMakeLists.txt                     |   1 +
 moose-core/biophysics/Neuron.cpp              |  30 +-
 moose-core/ksolve/Ksolve.cpp                  |  16 +-
 moose-core/ksolve/OdeSystem.h                 |   9 +-
 moose-core/ksolve/SteadyStateBoost.cpp        | 121 +--
 moose-core/ksolve/SteadyStateGsl.cpp          | 138 +--
 moose-core/ksolve/VoxelPools.cpp              | 142 +--
 moose-core/ksolve/VoxelPools.h                |   4 +-
 moose-core/python/rdesigneur/rdesigneur.py    | 448 +++++----
 moose-core/python/rdesigneur/rmoogli.py       |   2 +-
 .../tests/python/chem_models/19085.cspace     |   1 +
 .../python/testdisabled_dose_response.py      | 106 +++
 moose-examples/.travis.yml                    |  15 +-
 moose-examples/.travis_prepare.sh             |  16 -
 .../neuroml2/NML2_SingleCompHHCell.nml        |  90 ++
 moose-examples/neuroml2/converter.py          | 209 +++++
 moose-examples/neuroml2/passiveCell.nml       |  52 ++
 moose-examples/neuroml2/run_cell.py           | 112 +++
 moose-examples/neuroml2/run_hhcell.py         | 151 +++
 moose-examples/squid/squid.py                 |  12 +-
 moose-examples/squid/squid_demo.py            |  19 +-
 moose-examples/squid/squid_demo_qt5.py        | 861 ++++++++++++++++++
 moose-examples/squid/test_squid.py            |   2 +-
 .../Electrophys/CableInjectEquivCkt.png       | Bin 0 -> 31378 bytes
 .../tutorials/Electrophys/README.txt          |  80 ++
 .../tutorials/Electrophys/RallsLaw.png        | Bin 0 -> 41208 bytes
 .../tutorials/Electrophys/ephys1_cable.py     | 212 +++++
 .../tutorials/Electrophys/ephys2_Rall_law.py  | 268 ++++++
 .../tutorials/Rdesigneur/README.txt           |  10 +
 .../Rdesigneur/ex3.2_squid_axon_propgn.py     |   4 +-
 .../Rdesigneur/ex3.3_AP_collision.py          |   2 +-
 .../Rdesigneur/ex3.4_myelinated_axon.py       |   6 -
 .../tutorials/Rdesigneur/ex7.2_CICR.py        |   1 +
 .../Rdesigneur/ex9.3_spiral_spines.py         |  19 +
 moose-gui/objectedit.py                       |  12 +-
 moose-gui/plugins/kkit.py                     |  20 +-
 moose-gui/plugins/kkitUtil.py                 |  31 +-
 moose-gui/plugins/kkitViewcontrol.py          |  26 +-
 38 files changed, 2661 insertions(+), 587 deletions(-)
 create mode 100644 moose-core/tests/python/chem_models/19085.cspace
 create mode 100644 moose-core/tests/python/testdisabled_dose_response.py
 delete mode 100755 moose-examples/.travis_prepare.sh
 create mode 100644 moose-examples/neuroml2/NML2_SingleCompHHCell.nml
 create mode 100644 moose-examples/neuroml2/converter.py
 create mode 100644 moose-examples/neuroml2/passiveCell.nml
 create mode 100644 moose-examples/neuroml2/run_cell.py
 create mode 100644 moose-examples/neuroml2/run_hhcell.py
 create mode 100644 moose-examples/squid/squid_demo_qt5.py
 create mode 100644 moose-examples/tutorials/Electrophys/CableInjectEquivCkt.png
 create mode 100644 moose-examples/tutorials/Electrophys/README.txt
 create mode 100644 moose-examples/tutorials/Electrophys/RallsLaw.png
 create mode 100644 moose-examples/tutorials/Electrophys/ephys1_cable.py
 create mode 100644 moose-examples/tutorials/Electrophys/ephys2_Rall_law.py
 create mode 100644 moose-examples/tutorials/Rdesigneur/ex9.3_spiral_spines.py

diff --git a/moose-core/CMakeLists.txt b/moose-core/CMakeLists.txt
index 9bf8255c..3be4235b 100644
--- a/moose-core/CMakeLists.txt
+++ b/moose-core/CMakeLists.txt
@@ -130,6 +130,7 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR} )
 
 if(WITH_BOOST)
     set(WITH_BOOST_ODE ON)
+    set(WITH_GSL       OFF)
 endif(WITH_BOOST)
 
 # If using BOOST ODE2 library to solve ODE system, then don't use GSL.
diff --git a/moose-core/biophysics/Neuron.cpp b/moose-core/biophysics/Neuron.cpp
index aa867591..3fbab6d0 100644
--- a/moose-core/biophysics/Neuron.cpp
+++ b/moose-core/biophysics/Neuron.cpp
@@ -315,11 +315,17 @@ const Cinfo* Neuron::initCinfo()
         "The expression for the *spacing* field must evaluate to > 0 for "
         "the spine to be installed. For example, if the expresssion is\n"
         "		H(1 - L) \n"
-        "then the systemwill only put spines closer than "
+        "then the system will only put spines closer than "
         "one length constant from the soma, and zero elsewhere. \n"
         "Available spine parameters are: \n"
         "spacing, minSpacing, size, sizeDistrib "
-        "angle, angleDistrib \n",
+        "angle, angleDistrib \n"
+		"minSpacing sets the granularity of sampling (typically about 0.1*"
+	    "spacing) for the usual case where spines are spaced randomly. "
+		"If minSpacing < 0 then the spines are spaced equally at "
+		"'spacing', unless the dendritic segment length is smaller than "
+		"'spacing'. In that case it falls back to the regular random "
+		"placement method.",
         &Neuron::setSpineDistribution,
         &Neuron::getSpineDistribution
     );
@@ -1788,6 +1794,19 @@ static void addPos( unsigned int segIndex, unsigned int eIndex,
                     vector< unsigned int >& elistIndex,
                     vector< double >& pos )
 {
+	if ( minSpacing < 0.0 ) {
+		// Use uniform spacing
+		for ( double position = spacing * 0.5;
+				position < dendLength; position += spacing ) {
+			seglistIndex.push_back( segIndex );
+			elistIndex.push_back( eIndex );
+			pos.push_back( position );
+		}
+		if ( dendLength > spacing * 0.5 )
+			return;
+		// If the dend length is too small for regular placement, 
+		// fall back to using probability to decide if segment gets spine
+	}
     if ( minSpacing < spacing * 0.1 && minSpacing < 1e-7 )
         minSpacing = spacing * 0.1;
     if ( minSpacing > spacing * 0.5 )
@@ -1860,13 +1879,6 @@ void Neuron::makeSpacingDistrib( const vector< ObjId >& elist,
             {
                 double spacing = val[ j + nuParser::EXPR ];
                 double spacingDistrib = parser.eval( val.begin() + j );
-                if ( spacingDistrib > spacing || spacingDistrib < 0 )
-                {
-                    cout << "Warning: Neuron::makeSpacingDistrib: " <<
-                         "0 < " << spacingDistrib << " < " << spacing <<
-                         " fails on " << elist[i].path() << ". Using 0.\n";
-                    spacingDistrib = 0.0;
-                }
                 map< Id, unsigned int>::const_iterator
                 lookupDend = segIndex_.find( elist[i] );
                 if ( lookupDend != segIndex_.end() )
diff --git a/moose-core/ksolve/Ksolve.cpp b/moose-core/ksolve/Ksolve.cpp
index 2277e5ff..81bc118f 100644
--- a/moose-core/ksolve/Ksolve.cpp
+++ b/moose-core/ksolve/Ksolve.cpp
@@ -235,7 +235,7 @@ static const Cinfo* ksolveCinfo = Ksolve::initCinfo();
 
 Ksolve::Ksolve()
     :
-#if USE_GSL
+#ifdef USE_GSL
     method_( "rk5" ),
 #elif USE_BOOST_ODE
     method_( "rk5a" ),
@@ -248,19 +248,12 @@ Ksolve::Ksolve()
     dsolve_(),
     dsolvePtr_( 0 )
 {
+    ;
 }
 
 Ksolve::~Ksolve()
 {
-#if 0
-    char* p = getenv( "MOOSE_SHOW_SOLVER_PERF" );
-    if( p != NULL )
-    {
-        cout << "Info: Ksolve (+Dsolve) took " << totalTime_ << " seconds and took " << numSteps_
-             << " steps." << endl;
-
-    }
-#endif
+    ;
 }
 
 //////////////////////////////////////////////////////////////
@@ -378,6 +371,7 @@ void Ksolve::setStoich( Id stoich )
     assert( stoich.element()->cinfo()->isA( "Stoich" ) );
     stoich_ = stoich;
     stoichPtr_ = reinterpret_cast< Stoich* >( stoich.eref().data() );
+
     if ( !isBuilt_ )
     {
         OdeSystem ode;
@@ -386,6 +380,7 @@ void Ksolve::setStoich( Id stoich )
         // ode.initStepSize = getEstimatedDt();
         ode.initStepSize = 0.01; // This will be overridden at reinit.
         ode.method = method_;
+
 #ifdef USE_GSL
         ode.gslSys.dimension = stoichPtr_->getNumAllPools();
         if ( ode.gslSys.dimension == 0 )
@@ -416,6 +411,7 @@ void Ksolve::setStoich( Id stoich )
 #endif
         isBuilt_ = true;
     }
+
 }
 
 Id Ksolve::getDsolve() const
diff --git a/moose-core/ksolve/OdeSystem.h b/moose-core/ksolve/OdeSystem.h
index 6a3ede6d..511513b5 100644
--- a/moose-core/ksolve/OdeSystem.h
+++ b/moose-core/ksolve/OdeSystem.h
@@ -26,15 +26,16 @@ class OdeSystem {
     {;}
 
         std::string method;
-        // GSL stuff
+
+        double initStepSize;
+        double epsAbs; // Absolute error
+        double epsRel; // Relative error
 
 #ifdef USE_GSL
+        // GSL stuff
         gsl_odeiv2_system gslSys;
         const gsl_odeiv2_step_type* gslStep;
 #endif
-        double initStepSize;
-        double epsAbs; // Absolute error
-        double epsRel; // Relative error
 
 #if  USE_BOOST_ODE
         size_t dimension;
diff --git a/moose-core/ksolve/SteadyStateBoost.cpp b/moose-core/ksolve/SteadyStateBoost.cpp
index a96439ba..5d31165d 100644
--- a/moose-core/ksolve/SteadyStateBoost.cpp
+++ b/moose-core/ksolve/SteadyStateBoost.cpp
@@ -85,27 +85,6 @@ struct reac_info
 
 const Cinfo* SteadyState::initCinfo()
 {
-    /**
-     * This picks up the entire Stoich data structure
-    static Finfo* gslShared[] =
-    {
-    	new SrcFinfo( "reinitSrc", Ftype0() ),
-    	new DestFinfo( "assignStoich",
-    		Ftype1< void* >(),
-    		RFCAST( &SteadyState::assignStoichFunc )
-    		),
-    	new DestFinfo( "setMolN",
-    		Ftype2< double, unsigned int >(),
-    		RFCAST( &SteadyState::setMolN )
-    		),
-    	new SrcFinfo( "requestYsrc", Ftype0() ),
-    	new DestFinfo( "assignY",
-    		Ftype1< double* >(),
-    		RFCAST( &SteadyState::assignY )
-    		),
-    };
-     */
-
     /**
      * These are the fields of the SteadyState class
      */
@@ -207,59 +186,59 @@ const Cinfo* SteadyState::initCinfo()
     // MsgDest definitions
     ///////////////////////////////////////////////////////
     static DestFinfo setupMatrix( "setupMatrix",
-                                  "This function initializes and rebuilds the matrices used "
-                                  "in the calculation.",
-                                  new OpFunc0< SteadyState >(&SteadyState::setupMatrix)
-                                );
+            "This function initializes and rebuilds the matrices used "
+            "in the calculation.",
+            new OpFunc0< SteadyState >(&SteadyState::setupMatrix)
+            );
 
     static DestFinfo settle( "settle",
-                             "Finds the nearest steady state to the current initial "
-                             "conditions. This function rebuilds the entire calculation "
-                             "only if the object has not yet been initialized.",
-                             new OpFunc0< SteadyState >( &SteadyState::settleFunc )
-                           );
+            "Finds the nearest steady state to the current initial "
+            "conditions. This function rebuilds the entire calculation "
+            "only if the object has not yet been initialized.",
+            new OpFunc0< SteadyState >( &SteadyState::settleFunc )
+            );
     static DestFinfo resettle( "resettle",
-                               "Finds the nearest steady state to the current initial "
-                               "conditions. This function rebuilds the entire calculation ",
-                               new OpFunc0< SteadyState >( &SteadyState::resettleFunc )
-                             );
+            "Finds the nearest steady state to the current initial "
+            "conditions. This function rebuilds the entire calculation ",
+            new OpFunc0< SteadyState >( &SteadyState::resettleFunc )
+            );
     static DestFinfo showMatrices( "showMatrices",
-                                   "Utility function to show the matrices derived for the calculations on the reaction system. Shows the Nr, gamma, and total matrices",
-                                   new OpFunc0< SteadyState >( &SteadyState::showMatrices )
-                                 );
+            "Utility function to show the matrices derived for the calculations on the reaction system. Shows the Nr, gamma, and total matrices",
+            new OpFunc0< SteadyState >( &SteadyState::showMatrices )
+            );
     static DestFinfo randomInit( "randomInit",
-                                 "Generate random initial conditions consistent with the mass"
-                                 "conservation rules. Typically invoked in order to scan"
-                                 "states",
-                                 new EpFunc0< SteadyState >(
-                                     &SteadyState::randomizeInitialCondition )
-                               );
+            "Generate random initial conditions consistent with the mass"
+            "conservation rules. Typically invoked in order to scan"
+            "states",
+            new EpFunc0< SteadyState >(
+                &SteadyState::randomizeInitialCondition )
+            );
     ///////////////////////////////////////////////////////
     // Shared definitions
     ///////////////////////////////////////////////////////
 
     static Finfo * steadyStateFinfos[] =
     {
-        &stoich,				// Value
-        &badStoichiometry,		// ReadOnlyValue
-        &isInitialized,			// ReadOnlyValue
-        &nIter,					// ReadOnlyValue
-        &status,				// ReadOnlyValue
-        &maxIter,				// Value
-        &convergenceCriterion,	// ReadOnlyValue
-        &numVarPools,			// ReadOnlyValue
-        &rank,					// ReadOnlyValue
-        &stateType,				// ReadOnlyValue
-        &nNegEigenvalues,		// ReadOnlyValue
-        &nPosEigenvalues,		// ReadOnlyValue
-        &solutionStatus,		// ReadOnlyValue
-        &total,					// LookupValue
-        &eigenvalues,			// ReadOnlyLookupValue
-        &setupMatrix,			// DestFinfo
-        &settle,				// DestFinfo
-        &resettle,				// DestFinfo
-        &showMatrices,			// DestFinfo
-        &randomInit,			// DestFinfo
+        &stoich,                // Value
+        &badStoichiometry,        // ReadOnlyValue
+        &isInitialized,            // ReadOnlyValue
+        &nIter,                    // ReadOnlyValue
+        &status,                // ReadOnlyValue
+        &maxIter,                // Value
+        &convergenceCriterion,    // ReadOnlyValue
+        &numVarPools,            // ReadOnlyValue
+        &rank,                    // ReadOnlyValue
+        &stateType,                // ReadOnlyValue
+        &nNegEigenvalues,        // ReadOnlyValue
+        &nPosEigenvalues,        // ReadOnlyValue
+        &solutionStatus,        // ReadOnlyValue
+        &total,                    // LookupValue
+        &eigenvalues,            // ReadOnlyLookupValue
+        &setupMatrix,            // DestFinfo
+        &settle,                // DestFinfo
+        &resettle,                // DestFinfo
+        &showMatrices,            // DestFinfo
+        &randomInit,            // DestFinfo
 
 
     };
@@ -278,7 +257,7 @@ const Cinfo* SteadyState::initCinfo()
         "Note that the method finds unstable as well as stable fixed "
         "points.\n "
         "The SteadyState class also provides a utility function "
-        "*randomInit()*	to "
+        "*randomInit()*    to "
         "randomly initialize the concentrations, within the constraints "
         "of stoichiometry. This is useful if you are trying to find "
         "the major fixed points of the system. Note that this is "
@@ -368,12 +347,10 @@ void SteadyState::setStoich( Id value )
     numVarPools_ = Field< unsigned int >::get( stoich_, "numVarPools" );
     nReacs_ = Field< unsigned int >::get( stoich_, "numRates" );
     setupSSmatrix();
-    double vol = LookupField< unsigned int, double >::get(
-                     stoichPtr->getCompartment(), "oneVoxelVolume", 0 );
+    double vol = LookupField< unsigned int, double >::get(stoichPtr->getCompartment(), "oneVoxelVolume", 0 );
     pool_.setVolume( vol );
     pool_.setStoich( stoichPtr, 0 );
-    pool_.updateAllRateTerms( stoichPtr->getRateTerms(),
-                              stoichPtr->getNumCoreRates() );
+    pool_.updateAllRateTerms( stoichPtr->getRateTerms(), stoichPtr->getNumCoreRates() );
     isInitialized_ = 1;
 }
 
@@ -513,9 +490,9 @@ void SteadyState::showMatrices()
         return;
     }
     int numConsv = numVarPools_ - rank_;
-    cout << "Totals:	";
+    cout << "Totals:    ";
     for ( int i = 0; i < numConsv; ++i )
-        cout << total_[i] << "	";
+        cout << total_[i] << "    ";
     cout << endl;
     cout << "gamma " << gamma_ << endl;
     cout << "Nr " << Nr_ << endl;
@@ -549,9 +526,7 @@ void SteadyState::setupSSmatrix()
         {
             double x = 0;
             if ( j == colIndex[k] && k < rowStart[i+1] )
-            {
                 x = entry[k++];
-            }
             N(i,j) = x;
             LU_(i,j) = x;
         }
@@ -714,7 +689,7 @@ static bool isSolutionValid( const vector< double >& x )
     for( size_t i = 0; i < x.size(); i++ )
     {
         double v = x[i];
-        if ( std::isnan( v ) or std::isinf( v ) )
+        if ( std::isnan( v ) || std::isinf( v ) )
         {
             cout << "Warning: SteadyState iteration gave nan/inf concs\n";
             return false;
diff --git a/moose-core/ksolve/SteadyStateGsl.cpp b/moose-core/ksolve/SteadyStateGsl.cpp
index 295b5256..5aa0941d 100644
--- a/moose-core/ksolve/SteadyStateGsl.cpp
+++ b/moose-core/ksolve/SteadyStateGsl.cpp
@@ -87,20 +87,20 @@ const Cinfo* SteadyState::initCinfo()
      * This picks up the entire Stoich data structure
     static Finfo* gslShared[] =
     {
-    	new SrcFinfo( "reinitSrc", Ftype0::global() ),
-    	new DestFinfo( "assignStoich",
-    		Ftype1< void* >::global(),
-    		RFCAST( &SteadyState::assignStoichFunc )
-    		),
-    	new DestFinfo( "setMolN",
-    		Ftype2< double, unsigned int >::global(),
-    		RFCAST( &SteadyState::setMolN )
-    		),
-    	new SrcFinfo( "requestYsrc", Ftype0::global() ),
-    	new DestFinfo( "assignY",
-    		Ftype1< double* >::global(),
-    		RFCAST( &SteadyState::assignY )
-    		),
+        new SrcFinfo( "reinitSrc", Ftype0::global() ),
+        new DestFinfo( "assignStoich",
+            Ftype1< void* >::global(),
+            RFCAST( &SteadyState::assignStoichFunc )
+            ),
+        new DestFinfo( "setMolN",
+            Ftype2< double, unsigned int >::global(),
+            RFCAST( &SteadyState::setMolN )
+            ),
+        new SrcFinfo( "requestYsrc", Ftype0::global() ),
+        new DestFinfo( "assignY",
+            Ftype1< double* >::global(),
+            RFCAST( &SteadyState::assignY )
+            ),
     };
      */
 
@@ -205,61 +205,61 @@ const Cinfo* SteadyState::initCinfo()
     // MsgDest definitions
     ///////////////////////////////////////////////////////
     static DestFinfo setupMatrix( "setupMatrix",
-                                  "This function initializes and rebuilds the matrices used "
-                                  "in the calculation.",
-                                  new OpFunc0< SteadyState >(&SteadyState::setupMatrix)
-                                );
+            "This function initializes and rebuilds the matrices used "
+            "in the calculation.",
+            new OpFunc0< SteadyState >(&SteadyState::setupMatrix)
+            );
 
     static DestFinfo settle( "settle",
-                             "Finds the nearest steady state to the current initial "
-                             "conditions. This function rebuilds the entire calculation "
-                             "only if the object has not yet been initialized.",
-                             new OpFunc0< SteadyState >( &SteadyState::settleFunc )
-                           );
+            "Finds the nearest steady state to the current initial "
+            "conditions. This function rebuilds the entire calculation "
+            "only if the object has not yet been initialized.",
+            new OpFunc0< SteadyState >( &SteadyState::settleFunc )
+            );
     static DestFinfo resettle( "resettle",
-                               "Finds the nearest steady state to the current initial "
-                               "conditions. This function rebuilds the entire calculation ",
-                               new OpFunc0< SteadyState >( &SteadyState::resettleFunc )
-                             );
+            "Finds the nearest steady state to the current initial "
+            "conditions. This function rebuilds the entire calculation ",
+            new OpFunc0< SteadyState >( &SteadyState::resettleFunc )
+            );
     static DestFinfo showMatrices( "showMatrices",
-                                   "Utility function to show the matrices derived for the calculations on the reaction system. Shows the Nr, gamma, and total matrices",
-                                   new OpFunc0< SteadyState >( &SteadyState::showMatrices )
-                                 );
+            "Utility function to show the matrices derived for the "
+            "calculations on the reaction system. Shows the Nr, gamma, and total matrices",
+            new OpFunc0< SteadyState >( &SteadyState::showMatrices )
+            );
     static DestFinfo randomInit( "randomInit",
-                                 "Generate random initial conditions consistent with the mass"
-                                 "conservation rules. Typically invoked in order to scan"
-                                 "states",
-                                 new EpFunc0< SteadyState >(
-                                     &SteadyState::randomizeInitialCondition )
-                               );
+            "Generate random initial conditions consistent with the mass"
+            "conservation rules. Typically invoked in order to scan"
+            "states",
+            new EpFunc0< SteadyState >(
+                &SteadyState::randomizeInitialCondition )
+            );
+
     ///////////////////////////////////////////////////////
     // Shared definitions
     ///////////////////////////////////////////////////////
 
     static Finfo * steadyStateFinfos[] =
     {
-        &stoich,				// Value
-        &badStoichiometry,		// ReadOnlyValue
-        &isInitialized,			// ReadOnlyValue
-        &nIter,					// ReadOnlyValue
-        &status,				// ReadOnlyValue
-        &maxIter,				// Value
-        &convergenceCriterion,	// ReadOnlyValue
-        &numVarPools,			// ReadOnlyValue
-        &rank,					// ReadOnlyValue
-        &stateType,				// ReadOnlyValue
-        &nNegEigenvalues,		// ReadOnlyValue
-        &nPosEigenvalues,		// ReadOnlyValue
-        &solutionStatus,		// ReadOnlyValue
-        &total,					// LookupValue
-        &eigenvalues,			// ReadOnlyLookupValue
-        &setupMatrix,			// DestFinfo
-        &settle,				// DestFinfo
-        &resettle,				// DestFinfo
-        &showMatrices,			// DestFinfo
-        &randomInit,			// DestFinfo
-
-
+        &stoich,                  // Value
+        &badStoichiometry,        // ReadOnlyValue
+        &isInitialized,           // ReadOnlyValue
+        &nIter,                   // ReadOnlyValue
+        &status,                  // ReadOnlyValue
+        &maxIter,                 // Value
+        &convergenceCriterion,    // ReadOnlyValue
+        &numVarPools,             // ReadOnlyValue
+        &rank,                    // ReadOnlyValue
+        &stateType,               // ReadOnlyValue
+        &nNegEigenvalues,         // ReadOnlyValue
+        &nPosEigenvalues,         // ReadOnlyValue
+        &solutionStatus,          // ReadOnlyValue
+        &total,                   // LookupValue
+        &eigenvalues,             // ReadOnlyLookupValue
+        &setupMatrix,             // DestFinfo
+        &settle,                  // DestFinfo
+        &resettle,                // DestFinfo
+        &showMatrices,            // DestFinfo
+        &randomInit,              // DestFinfo
     };
 
     static string doc[] =
@@ -276,7 +276,7 @@ const Cinfo* SteadyState::initCinfo()
         "Note that the method finds unstable as well as stable fixed "
         "points.\n "
         "The SteadyState class also provides a utility function "
-        "*randomInit()*	to "
+        "*randomInit()*    to "
         "randomly initialize the concentrations, within the constraints "
         "of stoichiometry. This is useful if you are trying to find "
         "the major fixed points of the system. Note that this is "
@@ -316,7 +316,6 @@ static const Cinfo* steadyStateCinfo = SteadyState::initCinfo();
 ///////////////////////////////////////////////////
 // Class function definitions
 ///////////////////////////////////////////////////
-
 SteadyState::SteadyState()
     :
     nIter_( 0 ),
@@ -382,9 +381,10 @@ void SteadyState::setStoich( Id value )
     double vol = LookupField< unsigned int, double >::get(
                      stoichPtr->getCompartment(), "oneVoxelVolume", 0 );
     pool_.setVolume( vol );
-    pool_.setStoich( stoichPtr, 0 );
-    pool_.updateAllRateTerms( stoichPtr->getRateTerms(),
-                              stoichPtr->getNumCoreRates() );
+
+    pool_.setStoich( stoichPtr, nullptr );
+
+    pool_.updateAllRateTerms( stoichPtr->getRateTerms(), stoichPtr->getNumCoreRates() );
     isInitialized_ = 1;
 }
 
@@ -548,9 +548,9 @@ void SteadyState::showMatrices()
         return;
     }
     int numConsv = numVarPools_ - rank_;
-    cout << "Totals:	";
+    cout << "Totals:    ";
     for ( int i = 0; i < numConsv; ++i )
-        cout << total_[i] << "	";
+        cout << total_[i] << "    ";
     cout << endl;
 #ifdef USE_GSL
     print_gsl_mat( gamma_, "gamma" );
@@ -584,7 +584,7 @@ void SteadyState::setupSSmatrix()
     {
         gsl_matrix_set (LU_, i, i + nReacs_, 1 );
         unsigned int k = rowStart[i];
-        // cout << endl << i << ":	";
+        // cout << endl << i << ":    ";
         for ( unsigned int j = 0; j < nReacs_; ++j )
         {
             double x = 0;
@@ -592,7 +592,7 @@ void SteadyState::setupSSmatrix()
             {
                 x = entry[k++];
             }
-            // cout << "	" << x;
+            // cout << "    " << x;
             gsl_matrix_set (N, i, j, x);
             gsl_matrix_set (LU_, i, j, x );
         }
@@ -637,10 +637,10 @@ void SteadyState::setupSSmatrix()
     /*
     cout << "S = (";
     for ( unsigned int j = 0; j < numVarPools_; ++j )
-    	cout << s_->S()[ j ] << ", ";
+        cout << s_->S()[ j ] << ", ";
     cout << "), Sinit = ( ";
     for ( unsigned int j = 0; j < numVarPools_; ++j )
-    	cout << s_->Sinit()[ j ] << ", ";
+        cout << s_->Sinit()[ j ] << ", ";
     cout << ")\n";
     */
     Id ksolve = Field< Id >::get( stoich_, "ksolve" );
diff --git a/moose-core/ksolve/VoxelPools.cpp b/moose-core/ksolve/VoxelPools.cpp
index ea575304..25e8ac7e 100644
--- a/moose-core/ksolve/VoxelPools.cpp
+++ b/moose-core/ksolve/VoxelPools.cpp
@@ -6,7 +6,8 @@
 ** GNU Lesser General Public License version 2.1
 ** See the file COPYING.LIB for the full notice.
 **********************************************************************/
-#include "header.h"
+
+#include "../basecode/header.h"
 
 #ifdef USE_GSL
 #include <gsl/gsl_errno.h>
@@ -66,9 +67,12 @@ void VoxelPools::reinit( double dt )
 void VoxelPools::setStoich( Stoich* s, const OdeSystem* ode )
 {
     stoichPtr_ = s;
-    absTol_ = ode->epsAbs;
-    relTol_ = ode->epsRel;
-    method_ = ode->method;
+    if( ode )
+    {
+        epsAbs_ = ode->epsAbs;
+        epsRel_ = ode->epsRel;
+        method_ = ode->method;
+    }
 
 #ifdef USE_GSL
     if ( ode )
@@ -77,10 +81,9 @@ void VoxelPools::setStoich( Stoich* s, const OdeSystem* ode )
         if ( driver_ )
             gsl_odeiv2_driver_free( driver_ );
 
-        driver_ = gsl_odeiv2_driver_alloc_y_new(
-                      &sys_, ode->gslStep, ode->initStepSize,
-                      ode->epsAbs, ode->epsRel
-                  );
+        driver_ = gsl_odeiv2_driver_alloc_y_new( &sys_, ode->gslStep
+                  , ode->initStepSize, ode->epsAbs, ode->epsRel
+                                               );
     }
 #endif
     VoxelPoolsBase::reinit();
@@ -89,6 +92,7 @@ void VoxelPools::setStoich( Stoich* s, const OdeSystem* ode )
 void VoxelPools::advance( const ProcInfo* p )
 {
     double t = p->currTime - p->dt;
+
 #ifdef USE_GSL
     int status = gsl_odeiv2_driver_apply( driver_, &t, p->currTime, varS());
     if ( status != GSL_SUCCESS )
@@ -135,114 +139,41 @@ void VoxelPools::advance( const ProcInfo* p )
      * user should provide the stepping size when using fixed dt. This feature
      * can be incredibly useful on large system.
      */
-    const double fixedDt = 0.1;
 
-    if( method_ == "rk2" )
+    // Variout stepper times are listed here:
+    // https://www.boost.org/doc/libs/1_68_0/libs/numeric/odeint/doc/html/boost_numeric_odeint/odeint_in_detail/steppers.html#boost_numeric_odeint.odeint_in_detail.steppers.explicit_steppers
+
+    auto sys = [this](const vector_type_& dy, vector_type_& dydt, const double t) { 
+        VoxelPools::evalRates(this, dy, dydt); };
+
+    // This is usually the default method for boost: Runge Kutta Fehlberg
+    if( method_ == "rk5")
+        odeint::integrate_const( rk_karp_stepper_type_()
+                , sys , Svec() , p->currTime - p->dt, p->currTime, p->dt);
+    else if( method_ == "rk2" )
         odeint::integrate_const( rk_midpoint_stepper_type_()
-                , [this](const vector_type_& dy, vector_type_& dydt, const double t) {
-                        VoxelPools::evalRates(this, dy, dydt ); 
-                    }
-                , Svec()
-                , p->currTime - p->dt, p->currTime, std::min( p->dt, fixedDt )
-                );
+                , sys, Svec(), p->currTime - p->dt, p->currTime, p->dt);
     else if( method_ == "rk4" )
         odeint::integrate_const( rk4_stepper_type_()
-                , [this](const vector_type_& dy, vector_type_& dydt, const double t) { 
-                        VoxelPools::evalRates(this, dy, dydt );
-                    }
-                , Svec()
-                , p->currTime - p->dt, p->currTime, std::min( p->dt, fixedDt )
-                );
-    else if( method_ == "rk5")
-        odeint::integrate_const( rk_karp_stepper_type_()
-                , [this](const vector_type_& dy, vector_type_& dydt, const double t) { 
-                        VoxelPools::evalRates(this, dy, dydt );
-                    }
-                , Svec()
-                , p->currTime - p->dt, p->currTime, std::min( p->dt, fixedDt )
-                );
+                , sys, Svec(), p->currTime - p->dt, p->currTime, p->dt );
     else if( method_ == "rk5a")
-        odeint::integrate_adaptive(
-                odeint::make_controlled<rk_karp_stepper_type_>( absTol_, relTol_ )
-                , [this](const vector_type_& dy, vector_type_& dydt, const double t) { 
-                        VoxelPools::evalRates(this, dy, dydt );
-                    }
-                , Svec()
-                , p->currTime - p->dt
-                , p->currTime
-                , p->dt
-                );
+        odeint::integrate_adaptive( odeint::make_controlled<rk_dopri_stepper_type_>( epsAbs_, epsRel_ )
+                , sys , Svec() , p->currTime - p->dt , p->currTime, p->dt );
     else if ("rk54" == method_ )
         odeint::integrate_const( rk_karp_stepper_type_()
-                , [this](const vector_type_& dy, vector_type_& dydt, const double t) { 
-                        VoxelPools::evalRates(this, dy, dydt );
-                    }
-                , Svec()
-                , p->currTime - p->dt, p->currTime, std::min( p->dt, fixedDt )
-                );
+                 , sys , Svec() , p->currTime - p->dt, p->currTime, p->dt);
     else if ("rk54a" == method_ )
-        odeint::integrate_adaptive(
-                odeint::make_controlled<rk_karp_stepper_type_>( absTol_, relTol_ )
-                , [this](const vector_type_& dy, vector_type_& dydt, const double t) { 
-                        VoxelPools::evalRates(this, dy, dydt );
-                    }
-                , Svec()
-                , p->currTime - p->dt
-                , p->currTime
-                , p->dt
-                );
-    else if ("rk5" == method_ )
-        odeint::integrate_const( rk_dopri_stepper_type_()
-                , [this](const vector_type_& dy, vector_type_& dydt, const double t) { 
-                        VoxelPools::evalRates(this, dy, dydt );
-                    }
-                , Svec()
-                , p->currTime - p->dt
-                , p->currTime
-                , std::min( p->dt, fixedDt )
-                );
-    else if ("rk5a" == method_ )
-        odeint::integrate_adaptive(
-                odeint::make_controlled<rk_dopri_stepper_type_>( absTol_, relTol_ )
-                , [this](const vector_type_& dy, vector_type_& dydt, const double t) { 
-                        VoxelPools::evalRates(this, dy, dydt );
-                    }
-                , Svec()
-                , p->currTime - p->dt
-                , p->currTime
-                , p->dt
-                );
+        odeint::integrate_adaptive( odeint::make_controlled<rk_karp_stepper_type_>( epsAbs_, epsRel_ )
+                , sys, Svec(), p->currTime - p->dt, p->currTime, p->dt);
     else if( method_ == "rk8" )
         odeint::integrate_const( rk_felhberg_stepper_type_()
-                , [this](const vector_type_& dy, vector_type_& dydt, const double t) { 
-                        VoxelPools::evalRates(this, dy, dydt );
-                    }
-                , Svec()
-                , p->currTime - p->dt, p->currTime, std::min( p->dt, fixedDt )
-                );
+                 , sys, Svec(), p->currTime - p->dt, p->currTime, p->dt);
     else if( method_ == "rk8a" )
-        odeint::integrate_adaptive(
-                odeint::make_controlled<rk_felhberg_stepper_type_>( absTol_, relTol_ )
-                , [this](const vector_type_& dy, vector_type_& dydt, const double t) { 
-                        VoxelPools::evalRates(this, dy, dydt );
-                    }
-                , Svec()
-                , p->currTime - p->dt
-                , p->currTime
-                , p->dt
-                );
-
+        odeint::integrate_adaptive( odeint::make_controlled<rk_felhberg_stepper_type_>( epsAbs_, epsRel_ )
+                , sys, Svec(), p->currTime - p->dt, p->currTime, p->dt);
     else
-        odeint::integrate_adaptive(
-                odeint::make_controlled<rk_karp_stepper_type_>( absTol_, relTol_ )
-                , [this](const vector_type_& dy, vector_type_& dydt, const double t) { 
-                        VoxelPools::evalRates(this, dy, dydt );
-                    }
-                , Svec()
-                , p->currTime - p->dt
-                , p->currTime
-                , p->dt
-                );
+        odeint::integrate_adaptive( odeint::make_controlled<rk_karp_stepper_type_>( epsAbs_, epsRel_ )
+                , sys, Svec(), p->currTime - p->dt, p->currTime, p->dt);
 
 #endif
     if ( !stoichPtr_->getAllowNegative() )   // clean out negatives
@@ -353,8 +284,7 @@ void VoxelPools::updateRates( const double* s, double* yprime ) const
                           stoichPtr_->getNumProxyPools();
     // totVar should include proxyPools if this voxel does not use them
     unsigned int totInvar = stoichPtr_->getNumBufPools();
-    assert( N.nColumns() == 0 ||
-            N.nRows() == stoichPtr_->getNumAllPools() );
+    assert( N.nColumns() == 0 || N.nRows() == stoichPtr_->getNumAllPools() );
     assert( N.nColumns() == rates_.size() );
 
     for ( vector< RateTerm* >::const_iterator
diff --git a/moose-core/ksolve/VoxelPools.h b/moose-core/ksolve/VoxelPools.h
index a39b151c..04c5bb8c 100644
--- a/moose-core/ksolve/VoxelPools.h
+++ b/moose-core/ksolve/VoxelPools.h
@@ -99,8 +99,8 @@ private:
     gsl_odeiv2_system sys_;
 #endif
 
-    double absTol_;
-    double relTol_;
+    double epsAbs_;
+    double epsRel_;
     string method_;
 
 };
diff --git a/moose-core/python/rdesigneur/rdesigneur.py b/moose-core/python/rdesigneur/rdesigneur.py
index 568bac94..447faa11 100644
--- a/moose-core/python/rdesigneur/rdesigneur.py
+++ b/moose-core/python/rdesigneur/rdesigneur.py
@@ -73,6 +73,7 @@ class rdesigneur:
             combineSegments = True,
             stealCellFromLibrary = False,
             verbose = True,
+            benchmark = False,
             addSomaChemCompt = False,  # Put a soma chemCompt on neuroMesh
             addEndoChemCompt = False,  # Put an endo compartment, typically for ER, on each of the NeuroMesh compartments.
             diffusionLength= 2e-6,
@@ -96,8 +97,8 @@ class rdesigneur:
             chemDistrib = [],
             adaptorList= [],
             stimList = [],
-            plotList = [],
-            moogList = [],
+            plotList = [],  # elecpath, geom_expr, object, field, title ['wave' [min max]]
+            moogList = [], 
             params = None
         ):
         """ Constructor of the rdesigner. This just sets up internal fields
@@ -110,6 +111,7 @@ class rdesigneur:
         self.combineSegments = combineSegments
         self.stealCellFromLibrary = stealCellFromLibrary
         self.verbose = verbose
+        self.benchmark = benchmark
         self.addSomaChemCompt = addSomaChemCompt
         self.addEndoChemCompt = addEndoChemCompt
         self.diffusionLength= diffusionLength
@@ -138,11 +140,16 @@ class rdesigneur:
         self.params = params
 
         self.adaptorList = adaptorList
-        self.stimList = stimList
-        self.plotList = plotList
-        self.saveList = plotList                    #ADDED BY Sarthak
+        try:
+            self.stimList = [ rstim.convertArg(i) for i in stimList ]
+            self.plotList = [ rplot.convertArg(i) for i in plotList ]
+            self.moogList = [ rmoog.convertArg(i) for i in moogList ]
+        except BuildError as msg:
+            print("Error: rdesigneur: " + msg)
+            quit()
+
+        #self.saveList = plotList                    #ADDED BY Sarthak
         self.saveAs = []
-        self.moogList = moogList
         self.plotNames = []
         self.wavePlotNames = []
         self.saveNames = []
@@ -166,7 +173,9 @@ class rdesigneur:
 
     ################################################################
     def _printModelStats( self ):
-        print("\n\tRdesigneur: Elec model has",
+        if not self.verbose:
+            return
+        print("\nRdesigneur: Elec model has",
             self.elecid.numCompartments, "compartments and",
             self.elecid.numSpines, "spines on",
             len( self.cellPortionElist ), "compartments.")
@@ -184,17 +193,15 @@ class rdesigneur:
             return
         self.model = moose.Neutral( modelPath )
         self.modelPath = modelPath
-        print( "[INFO ] rdesigneur: Building model. " )
         funcs = [ self.installCellFromProtos, self.buildPassiveDistrib
             , self.buildChanDistrib, self.buildSpineDistrib, self.buildChemDistrib
             , self._configureSolvers, self.buildAdaptors, self._buildStims
             , self._buildPlots, self._buildMoogli, self._configureHSolve
-            , self._configureClocks, self._printModelStats, self._savePlots 
+            , self._configureClocks, self._printModelStats 
             ]
         for i, _func in enumerate( funcs ):
-            if self.verbose:
+            if self.benchmark:
                 print( " + (%d/%d) executing %25s"%(i, len(funcs), _func.__name__), end=' ' )
-                sys.stdout.flush()
             t0 = time.time()
             try:
                 _func( )
@@ -203,11 +210,12 @@ class rdesigneur:
                 moose.delete( self.model )
                 return
             t = time.time() - t0
-            if self.verbose:
+            if self.benchmark:
                 msg = r'    ... DONE'
                 if t > 1:
                     msg += ' %.3f sec' % t
                 print( msg )
+            sys.stdout.flush()
 
     def installCellFromProtos( self ):
         if self.stealCellFromLibrary:
@@ -463,10 +471,10 @@ class rdesigneur:
         # Here we hack geomExpr to use it for the syn weight. We assume it
         # is just a number. In due course
         # it should be possible to actually evaluate it according to geom.
-        synWeight = float( stimInfo[1] )
+        synWeight = float( stimInfo.geom_expr )
         stimObj = []
         for i in dendCompts + spineCompts:
-            path = i.path + '/' + stimInfo[2] + '/sh/synapse[0]'
+            path = i.path + '/' + stimInfo.relpath + '/sh/synapse[0]'
             if moose.exists( path ):
                 synInput = make_synInput( name='synInput', parent=path )
                 synInput.doPeriodic = doPeriodic
@@ -486,6 +494,10 @@ class rdesigneur:
 	# Expression can use p, g, L, len, dia, maxP, maxG, maxL.
         temp = []
         for i in self.passiveDistrib:
+            if (len( i ) < 3) or (len(i) %2 != 1):
+                raise BuildError( "buildPassiveDistrib: Need 3 + N*2 arguments, have {}".format( len(i) ) )
+
+            temp.append( '.' )
             temp.extend( i )
             temp.extend( [""] )
         self.elecid.passiveDistribution = temp
@@ -608,18 +620,17 @@ class rdesigneur:
     #   [ region_wildcard, region_expr, path, field, title]
     def _parseComptField( self, comptList, plotSpec, knownFields ):
         # Put in stuff to go through fields if the target is a chem object
-        field = plotSpec[3]
+        field = plotSpec.field
         if not field in knownFields:
             print("Warning: Rdesigneur::_parseComptField: Unknown field '{}'".format( field ) )
             return (), ""
 
         kf = knownFields[field] # Find the field to decide type.
         if kf[0] in ['CaConcBase', 'ChanBase', 'NMDAChan', 'VClamp']:
-            objList = self._collapseElistToPathAndClass( comptList, plotSpec[2], kf[0] )
+            objList = self._collapseElistToPathAndClass( comptList, plotSpec.relpath, kf[0] )
             return objList, kf[1]
-
         elif field in [ 'n', 'conc', 'volume']:
-            path = plotSpec[2]
+            path = plotSpec.relpath
             pos = path.find( '/' )
             if pos == -1:   # Assume it is in the dend compartment.
                 path  = 'dend/' + path
@@ -640,13 +651,13 @@ class rdesigneur:
 
             voxelVec = [i for i in range(len( em ) ) if em[i] in comptSet ]
             # Here we collapse the voxelVec into objects to plot.
-            allObj = moose.vec( self.modelPath + '/chem/' + plotSpec[2] )
+            allObj = moose.vec( self.modelPath + '/chem/' + plotSpec.relpath )
             #print "####### allObj=", self.modelPath + '/chem/' + plotSpec[2]
             if len( allObj ) >= len( voxelVec ):
                 objList = [ allObj[int(j)] for j in voxelVec]
             else:
                 objList = []
-                print( "Warn: Rdesigneur::_parseComptField: unknown Object: '%s'" % plotSpec[2] )
+                print( "Warning: Rdesigneur::_parseComptField: unknown Object: '", plotSpec.relpath, "'" )
             #print "############", chemCompt, len(objList), kf[1]
             return objList, kf[1]
 
@@ -678,7 +689,7 @@ class rdesigneur:
         dummy = moose.element( '/' )
         k = 0
         for i in self.plotList:
-            pair = i[0] + " " + i[1]
+            pair = i.elecpath + ' ' + i.geom_expr
             dendCompts = self.elecid.compartmentsFromExpression[ pair ]
             spineCompts = self.elecid.spinesFromExpression[ pair ]
             plotObj, plotField = self._parseComptField( dendCompts, i, knownFields )
@@ -686,26 +697,26 @@ class rdesigneur:
             assert( plotField == plotField2 )
             plotObj3 = plotObj + plotObj2
             numPlots = sum( q != dummy for q in plotObj3 )
-            if numPlots == 0:
-                return 
-
-            tabname = graphs.path + '/plot' + str(k)
-            scale = knownFields[i[3]][2]
-            units = knownFields[i[3]][3]
-            ymin = i[6] if len(i) > 7 else 0
-            ymax = i[7] if len(i) > 7 else 0
-            if len( i ) > 5 and i[5] == 'wave':
-                self.wavePlotNames.append( [ tabname, i[4], k, scale, units, i[3], ymin, ymax ] )
-            else:
-                self.plotNames.append( [ tabname, i[4], k, scale, units, i[3], ymin, ymax ] )
-            k += 1
-            if i[3] in [ 'n', 'conc', 'volume', 'Gbar' ]:
-                tabs = moose.Table2( tabname, numPlots )
-            else:
-                tabs = moose.Table( tabname, numPlots )
-                if i[3] == 'spikeTime':
-                    tabs.vec.threshold = -0.02 # Threshold for classifying Vm as a spike.
-                    tabs.vec.useSpikeMode = True # spike detect mode on
+            #print( "PlotList: {0}: numobj={1}, field ={2}, nd={3}, ns={4}".format( pair, numPlots, plotField, len( dendCompts ), len( spineCompts ) ) )
+            if numPlots > 0:
+                tabname = graphs.path + '/plot' + str(k)
+                scale = knownFields[i.field][2]
+                units = knownFields[i.field][3]
+                if i.mode == 'wave':
+                    self.wavePlotNames.append( [ tabname, i.title, k, scale, units, i ] )
+                else:
+                    self.plotNames.append( [ tabname, i.title, k, scale, units, i.field, i.ymin, i.ymax ] )
+                if len( i.saveFile ) > 4 and i.saveFile[-4] == '.xml' or i.saveFile:
+                    self.saveNames.append( [ tabname, len(self.saveNames), scale, units, i ] )
+
+                k += 1
+                if i.field == 'n' or i.field == 'conc' or i.field == 'volume' or i.field == 'Gbar':
+                    tabs = moose.Table2( tabname, numPlots )
+                else:
+                    tabs = moose.Table( tabname, numPlots )
+                    if i.field == 'spikeTime':
+                        tabs.vec.threshold = -0.02 # Threshold for classifying Vm as a spike.
+                        tabs.vec.useSpikeMode = True # spike detect mode on
 
             vtabs = moose.vec( tabs )
             q = 0
@@ -731,8 +742,8 @@ class rdesigneur:
         moogliBase = moose.Neutral( self.modelPath + '/moogli' )
         k = 0
         for i in self.moogList:
-            kf = knownFields[i[3]]
-            pair = i[0] + " " + i[1]
+            kf = knownFields[i.field]
+            pair = i.elecpath + " " + i.geom_expr
             dendCompts = self.elecid.compartmentsFromExpression[ pair ]
             spineCompts = self.elecid.spinesFromExpression[ pair ]
             dendObj, mooField = self._parseComptField( dendCompts, i, knownFields )
@@ -740,13 +751,6 @@ class rdesigneur:
             assert( mooField == mooField2 )
             mooObj3 = dendObj + spineObj
             numMoogli = len( mooObj3 )
-            #dendComptMap = self.dendCompt.elecComptMap
-            #self.moogliViewer = rmoogli.makeMoogli( self, mooObj3, mooField )
-            if len( i ) == 5:
-                i.extend( kf[4:6] )
-            elif len( i ) == 6:
-                i.extend( [kf[5]] )
-            #self.moogliViewer = rmoogli.makeMoogli( self, mooObj3, i, kf )
             self.moogNames.append( rmoogli.makeMoogli( self, mooObj3, i, kf ) )
 
 
@@ -815,10 +819,15 @@ rdesigneur.rmoogli.updateMoogliViewer()
             plt.title( i[1] )
             plt.xlabel( "position (voxels)" )
             plt.ylabel( i[4] )
-            mn = np.min(vpts)
-            mx = np.max(vpts)
-            if mn/mx < 0.3:
-                mn = 0
+            plotinfo = i[5]
+            if plotinfo.ymin == plotinfo.ymax:
+                mn = np.min(vpts)
+                mx = np.max(vpts)
+                if mn/mx < 0.3:
+                    mn = 0
+            else:
+                mn = plotinfo.ymin
+                mx = plotinfo.ymax
             ax.set_ylim( mn, mx )
             line, = plt.plot( range( len( vtab ) ), vpts[0] )
             timeLabel = plt.text( len(vtab ) * 0.05, mn + 0.9*(mx-mn), 'time = 0' )
@@ -847,134 +856,13 @@ rdesigneur.rmoogli.updateMoogliViewer()
     Email address: sarthaks442@gmail.com
     Heavily modified by U.S. Bhalla
     '''
-
-    def _savePlots( self ):
-        if self.verbose:
-            print( 'rdesigneur: Saving plots ...', end = ' ' )
-            sys.stdout.flush()
-
-        knownFields = {
-            'Vm':('CompartmentBase', 'getVm', 1000, 'Memb. Potential (mV)' ),
-            'Cm':('CompartmentBase', 'getCm', 1e12, 'Memb. capacitance (pF)' ),
-            'Rm':('CompartmentBase', 'getRm', 1e-9, 'Memb. Res (GOhm)' ),
-            'Ra':('CompartmentBase', 'getRa', 1e-6, 'Axial Res (MOhm)' ),
-            'spikeTime':('CompartmentBase', 'getVm', 1, 'Spike Times (s)'),
-            'Im':('CompartmentBase', 'getIm', 1e9, 'Memb. current (nA)' ),
-            'inject':('CompartmentBase', 'getInject', 1e9, 'inject current (nA)' ),
-            'Gbar':('ChanBase', 'getGbar', 1e9, 'chan max conductance (nS)' ),
-            'modulation':('ChanBase', 'getModulation', 1, 'chan modulation (unitless)' ),
-            'Gk':('ChanBase', 'getGk', 1e9, 'chan conductance (nS)' ),
-            'Ik':('ChanBase', 'getIk', 1e9, 'chan current (nA)' ),
-            'ICa':('NMDAChan', 'getICa', 1e9, 'Ca current (nA)' ),
-            'Ca':('CaConcBase', 'getCa', 1e3, 'Ca conc (uM)' ),
-            'n':('PoolBase', 'getN', 1, '# of molecules'),
-            'conc':('PoolBase', 'getConc', 1000, 'Concentration (uM)' ),
-            'volume':('PoolBase', 'getVolume', 1e18, 'Volume (um^3)' ),
-            'current':('VClamp', 'getCurrent', 1e9, 'Holding Current (nA)')
-        }
-
-        save_graphs = moose.Neutral( self.modelPath + '/save_graphs' )
-        dummy = moose.element( '/' )
-        k = 0
-
-        for i in self.saveList:
-            pair = i[0] + " " + i[1]
-            dendCompts = self.elecid.compartmentsFromExpression[ pair ]
-            spineCompts = self.elecid.spinesFromExpression[ pair ]
-            plotObj, plotField = self._parseComptField( dendCompts, i, knownFields )
-            plotObj2, plotField2 = self._parseComptField( spineCompts, i, knownFields )
-            assert( plotField == plotField2 )
-            plotObj3 = plotObj + plotObj2
-            numPlots = sum( i != dummy for i in plotObj3 )
-            if numPlots > 0:
-                save_tabname = save_graphs.path + '/save_plot' + str(k)
-                scale = knownFields[i[3]][2]
-                units = knownFields[i[3]][3]
-                self.saveNames.append( ( save_tabname, i[4], k, scale, units ) )
-                k += 1
-                if i[3] in [ 'n', 'conc', 'volume', 'Gbar' ]:
-                    save_tabs = moose.Table2( save_tabname, numPlots )
-                    save_vtabs = moose.vec( save_tabs )
-                else:
-                    save_tabs = moose.Table( save_tabname, numPlots )
-                    save_vtabs = moose.vec( save_tabs )
-                    if i[3] == 'spikeTime':
-                        save_vtabs.threshold = -0.02 # Threshold for classifying Vm as a spike.
-                        save_vtabs.useSpikeMode = True # spike detect mode on
-                q = 0
-                for p in [ x for x in plotObj3 if x != dummy ]:
-                    moose.connect( save_vtabs[q], 'requestOut', p, plotField )
-                    q += 1
-
-        if self.verbose:
-            print( ' ... DONE.' )
-
-    def _getTimeSeriesTable( self ):
-
-        '''
-        This function gets the list with all the details of the simulation
-        required for plotting.
-        This function adds flexibility in terms of the details
-        we wish to store.
-        '''
-
-        knownFields = {
-            'Vm':('CompartmentBase', 'getVm', 1000, 'Memb. Potential (mV)' ),
-            'spikeTime':('CompartmentBase', 'getVm', 1, 'Spike Times (s)'),
-            'Im':('CompartmentBase', 'getIm', 1e9, 'Memb. current (nA)' ),
-            'inject':('CompartmentBase', 'getInject', 1e9, 'inject current (nA)' ),
-            'Gbar':('ChanBase', 'getGbar', 1e9, 'chan max conductance (nS)' ),
-            'Gk':('ChanBase', 'getGk', 1e9, 'chan conductance (nS)' ),
-            'Ik':('ChanBase', 'getIk', 1e9, 'chan current (nA)' ),
-            'ICa':('NMDAChan', 'getICa', 1e9, 'Ca current (nA)' ),
-            'Ca':('CaConcBase', 'getCa', 1e3, 'Ca conc (uM)' ),
-            'n':('PoolBase', 'getN', 1, '# of molecules'),
-            'conc':('PoolBase', 'getConc', 1000, 'Concentration (uM)' ),
-            'volume':('PoolBase', 'getVolume', 1e18, 'Volume (um^3)' )
-        }
-
-        '''
-        This takes data from plotList
-        saveList is exactly like plotList but with a few additional arguments:
-        ->It will have a resolution option, i.e., the number of decimal figures to which the value should be rounded
-        ->There is a list of "saveAs" formats
-        With saveList, the user will able to set what all details he wishes to be saved.
-        '''
-
-        for i,ind in enumerate(self.saveNames):
-            pair = self.saveList[i][0] + " " + self.saveList[i][1]
-            dendCompts = self.elecid.compartmentsFromExpression[ pair ]
-            spineCompts = self.elecid.spinesFromExpression[ pair ]
-            # Here we get the object details from plotList
-            savePlotObj, plotField = self._parseComptField( dendCompts, self.saveList[i], knownFields )
-            savePlotObj2, plotField2 = self._parseComptField( spineCompts, self.saveList[i], knownFields )
-            savePlotObj3 = savePlotObj + savePlotObj2
-
-            rowList = list(ind)
-            save_vtab = moose.vec( ind[0] )
-            t = np.arange( 0, save_vtab[0].vector.size, 1 ) * save_vtab[0].dt
-
-            rowList.append(save_vtab[0].dt)
-            rowList.append(t)
-            rowList.append([jvec.vector * ind[3] for jvec in save_vtab])             #get values
-            rowList.append(self.saveList[i][3])
-            rowList.append(filter(lambda obj: obj.path != '/', savePlotObj3))        #this filters out dummy elements
-
-            if (type(self.saveList[i][-1])==int):
-                rowList.append(self.saveList[i][-1])
-            else:
-                rowList.append(12)
-
-            self.tabForXML.append(rowList)
-            rowList = []
-
-        timeSeriesTable = self.tabForXML                                            # the list with all the details of plot
-        return timeSeriesTable
-
-    def _writeXML( self, filename, timeSeriesData ):                                #to write to XML file
-
-        plotData = timeSeriesData
-        print("[CAUTION] The '%s' file might be very large if all the compartments are to be saved." % filename)
+    def _writeXML( self, plotData, time, vtab ): 
+        tabname = plotData[0]
+        idx = plotData[1]
+        scale = plotData[2]
+        units = plotData[3]
+        rp = plotData[4]
+        filename = rp.saveFile[:-4] + str(idx) + '.xml'
         root = etree.Element("TimeSeriesPlot")
         parameters = etree.SubElement( root, "parameters" )
         if self.params == None:
@@ -987,36 +875,33 @@ rdesigneur.rmoogli.updateMoogliViewer()
 
         #plotData contains all the details of a single plot
         title = etree.SubElement( root, "timeSeries" )
-        title.set( 'title', str(plotData[1]))
-        title.set( 'field', str(plotData[8]))
-        title.set( 'scale', str(plotData[3]))
-        title.set( 'units', str(plotData[4]))
-        title.set( 'dt', str(plotData[5]))
+        title.set( 'title', rp.title)
+        title.set( 'field', rp.field)
+        title.set( 'scale', str(scale) )
+        title.set( 'units', units)
+        title.set( 'dt', str(vtab[0].dt) )
+        res = rp.saveResolution
         p = []
-        assert(len(plotData[7]) == len(plotData[9]))
-
-        res = plotData[10]
-        for ind, jvec in enumerate(plotData[7]):
+        for t, v in zip( time, vtab ):
             p.append( etree.SubElement( title, "data"))
-            p[-1].set( 'path', str(plotData[9][ind].path))
-            p[-1].text = ''.join( str(round(value,res)) + ' ' for value in jvec )
+            p[-1].set( 'path', v.path )
+            p[-1].text = ''.join( str(round(y,res)) + ' ' for y in v.vector )
         tree = etree.ElementTree(root)
         tree.write(filename)
 
-    def _writeCSV(self, filename, timeSeriesData):
-
-        plotData = timeSeriesData
-        dataList = []
-        header = []
-        time = plotData[6]
-        res = plotData[10]
-
-        for ind, jvec in enumerate(plotData[7]):
-            header.append(plotData[9][ind].path)
-            dataList.append([round(value,res) for value in jvec.tolist()])
-        dl = [tuple(lst) for lst in dataList]
-        rows = zip(tuple(time), *dl)
-        header.insert(0, "time")
+    def _writeCSV( self, plotData, time, vtab ): 
+        tabname = plotData[0]
+        idx = plotData[1]
+        scale = plotData[2]
+        units = plotData[3]
+        rp = plotData[4]
+        filename = rp.saveFile[:-4] + str(idx) + '.csv'
+
+        header = ["time",]
+        valMatrix = [time,]
+        header.extend( [ v.path for v in vtab ] )
+        valMatrix.extend( [ v.vector for v in vtab ] )
+        nv = np.array( valMatrix ).T
         with open(filename, 'wb') as f:
             writer = csv.writer(f, quoting=csv.QUOTE_MINIMAL)
             writer.writerow(header)
@@ -1024,42 +909,25 @@ rdesigneur.rmoogli.updateMoogliViewer()
                 writer.writerow(row)
 
     ##########****SAVING*****###############
-    def _saveFormats(self, timeSeriesData, k, *filenames):
-        "This takes in the filenames and writes to corresponding format."
-        if filenames:
-            for filename in filenames:
-                for name in filename:
-                    print (name)
-                    if name[-4:] == '.xml':
-                        self._writeXML(name, timeSeriesData)
-                        print(name, " written")
-                    elif name[-4:] == '.csv':
-                        self._writeCSV(name, timeSeriesData)
-                        print(name, " written")
-                    else:
-                        print("Save format not known")
-                        pass
-        else:
-            pass
 
 
     def _save( self ):
-        timeSeriesTable = self._getTimeSeriesTable()
-        for i,sList in enumerate(self.saveList):
-
-            if (len(sList) >= 6) and (type(sList[5]) != int):
-                    self.saveAs.extend(filter(lambda fmt: type(fmt)!=int, sList[5:]))
-                    try:
-                        timeSeriesData = timeSeriesTable[i]
-                    except IndexError:
-                        print("The object to be plotted has all dummy elements.")
-                        pass
-                    self._saveFormats(timeSeriesData, i, self.saveAs)
-                    self.saveAs=[]
+        for i in self.saveNames:
+            tabname = i[0]
+            idx = i[1]
+            scale = i[2]
+            units = i[3]
+            rp = i[4] # The rplot data structure, it has the setup info.
+
+            vtab = moose.vec( tabname )
+            t = np.arange( 0, vtab[0].vector.size, 1 ) * vtab[0].dt
+            ftype = rp.filename[-4:]
+            if ftype == '.xml':
+                self._writeXML( i, t, vtab )
+            elif ftype == '.csv':
+                self._writeCSV( i, t, vtab )
             else:
-                pass
-        else:
-            pass
+                print("Save format '{}' not known, please use .csv or .xml".format( ftype ) )
 
     ################################################################
     # Here we set up the stims
@@ -1080,17 +948,17 @@ rdesigneur.rmoogli.updateMoogliViewer()
         k = 0
         # Stimlist = [path, geomExpr, relPath, field, expr_string]
         for i in self.stimList:
-            pair = i[0] + " " + i[1]
+            pair = i.elecpath + " " + i.geom_expr
             dendCompts = self.elecid.compartmentsFromExpression[ pair ]
             spineCompts = self.elecid.spinesFromExpression[ pair ]
             #print( "pair = {}, numcompts = {},{} ".format( pair, len( dendCompts), len( spineCompts ) ) )
-            if i[3] == 'vclamp':
+            if i.field == 'vclamp':
                 stimObj3 = self._buildVclampOnCompt( dendCompts, spineCompts, i )
                 stimField = 'commandIn'
-            elif i[3] == 'randsyn':
+            elif i.field == 'randsyn':
                 stimObj3 = self._buildSynInputOnCompt( dendCompts, spineCompts, i )
                 stimField = 'setRate'
-            elif i[3] == 'periodicsyn':
+            elif i.field == 'periodicsyn':
                 stimObj3 = self._buildSynInputOnCompt( dendCompts, spineCompts, i, doPeriodic = True )
                 stimField = 'setRate'
             else:
@@ -1103,7 +971,7 @@ rdesigneur.rmoogli.updateMoogliViewer()
                 funcname = stims.path + '/stim' + str(k)
                 k += 1
                 func = moose.Function( funcname )
-                func.expr = i[4]
+                func.expr = i.expr
                 #if i[3] == 'vclamp': # Hack to clean up initial condition
                 func.doEvalAtReinit = 1
                 for q in stimObj3:
@@ -1619,3 +1487,95 @@ rdesigneur.rmoogli.updateMoogliViewer()
                 for j in range( i[1], i[2] ):
                     moose.connect( i[3], 'requestOut', chemVec[j], chemFieldSrc)
                 msg = moose.connect( i[3], 'output', elObj, elecFieldDest )
+
+
+#######################################################################
+# Some helper classes, used to define argument lists.
+#######################################################################
+
+class baseplot:
+    def __init__( self,
+            elecpath='soma', geom_expr='1', relpath='.', field='Vm' ):
+        self.elecpath = elecpath
+        self.geom_expr = geom_expr
+        self.relpath = relpath
+        self.field = field
+
+class rplot( baseplot ):
+    def __init__( self,
+        elecpath = 'soma', geom_expr = '1', relpath = '.', field = 'Vm', 
+        title = 'Membrane potential', 
+        mode = 'time', 
+        ymin = 0.0, ymax = 0.0, 
+        saveFile = "", saveResolution = 3, show = True ):
+        baseplot.__init__( self, elecpath, geom_expr, relpath, field )
+        self.title = title
+        self.mode = mode # Options: time, wave, wave_still, raster
+        self.ymin = ymin # If ymin == ymax, it autoscales.
+        self.ymax = ymax
+        if len( saveFile ) < 5:
+            self.saveFile = ""
+        else:
+            f = saveFile.split('.')
+            if len(f) < 2 or ( f[-1] != 'xml' and f[-1] != 'csv' ):
+                raise BuildError( "rplot: Filetype is '{}', must be of type .xml or .csv.".format( f[-1] ) )
+        self.saveFile = saveFile
+        self.show = show
+
+    def printme( self ):
+        print( "{}, {}, {}, {}, {}, {}, {}, {}, {}, {}".format( 
+            self.elecpath,
+            self.geom_expr, self.relpath, self.field, self.title,
+            self.mode, self.ymin, self.ymax, self.saveFile, self.show ) )
+
+    @staticmethod
+    def convertArg( arg ):
+        if isinstance( arg, rplot ):
+            return arg
+        elif isinstance( arg, list ):
+            return rplot( *arg )
+        else:
+            raise BuildError( "rplot initialization failed" )
+
+class rmoog( baseplot ):
+    def __init__( self,
+        elecpath = 'soma', geom_expr = '1', relpath = '.', field = 'Vm', 
+        title = 'Membrane potential', 
+        ymin = 0.0, ymax = 0.0, 
+        show = True ): # Could put in other display options.
+        baseplot.__init__( self, elecpath, geom_expr, relpath, field )
+        self.title = title
+        self.ymin = ymin # If ymin == ymax, it autoscales.
+        self.ymax = ymax
+        self.show = show
+
+    @staticmethod
+    def convertArg( arg ):
+        if isinstance( arg, rmoog ):
+            return arg
+        elif isinstance( arg, list ):
+            return rmoog( *arg )
+        else:
+            raise BuildError( "rmoog initialization failed" )
+
+        # Stimlist = [path, geomExpr, relPath, field, expr_string]
+class rstim( baseplot ):
+    def __init__( self,
+            elecpath = 'soma', geom_expr = '1', relpath = '.', field = 'inject', expr = '0'):
+        baseplot.__init__( self, elecpath, geom_expr, relpath, field )
+        self.expr = expr
+
+    def printme( self ):
+        print( "{}, {}, {}, {}, {}, {}, {}, {}, {}, {}".format( 
+            self.elecpath,
+            self.geom_expr, self.relpath, self.field, self.expr ) )
+
+    @staticmethod
+    def convertArg( arg ):
+        if isinstance( arg, rstim ):
+            return arg
+        elif isinstance( arg, list ):
+            return rstim( *arg )
+        else:
+            raise BuildError( "rstim initialization failed" )
+
diff --git a/moose-core/python/rdesigneur/rmoogli.py b/moose-core/python/rdesigneur/rmoogli.py
index 16317b56..f673dad7 100644
--- a/moose-core/python/rdesigneur/rmoogli.py
+++ b/moose-core/python/rdesigneur/rmoogli.py
@@ -29,7 +29,7 @@ def makeMoogli( rd, mooObj, args, fieldInfo ):
     else:
         ymin = fieldInfo[4]
         ymax = fieldInfo[5]
-    print( "fieldinfo = {}, ymin = {}, ymax = {}".format( fieldInfo, ymin, ymax ))
+    #print( "fieldinfo = {}, ymin = {}, ymax = {}".format( fieldInfo, ymin, ymax ))
 
     viewer = moogul.MooView()
     if mooField == 'n' or mooField == 'conc':
diff --git a/moose-core/tests/python/chem_models/19085.cspace b/moose-core/tests/python/chem_models/19085.cspace
new file mode 100644
index 00000000..1d2cf355
--- /dev/null
+++ b/moose-core/tests/python/chem_models/19085.cspace
@@ -0,0 +1 @@
+M101: |DabX|Jbca| 5.59269 0.0157641 0.172865 0.361005 4.72728 1.08558 0.0982933
\ No newline at end of file
diff --git a/moose-core/tests/python/testdisabled_dose_response.py b/moose-core/tests/python/testdisabled_dose_response.py
new file mode 100644
index 00000000..a840565a
--- /dev/null
+++ b/moose-core/tests/python/testdisabled_dose_response.py
@@ -0,0 +1,106 @@
+# -*- coding: utf-8 -*-
+## Makes and plots the dose response curve for bistable models
+## Author: Sahil Moza
+## June 26, 2014
+## Update:
+## Friday 14 September 2018 05:48:42 PM IST
+## Tunrned into a light-weight test by Dilawar Singh 
+
+import os
+import sys
+import moose
+import numpy as np
+
+sdir_ = os.path.dirname( os.path.realpath( __file__ ) )
+
+def setupSteadyState(simdt,plotDt):
+
+    ksolve = moose.Ksolve( '/model/kinetics/ksolve' )
+    stoich = moose.Stoich( '/model/kinetics/stoich' )
+    stoich.compartment = moose.element('/model/kinetics')
+    stoich.ksolve = ksolve
+    stoich.path = "/model/kinetics/##"
+    state = moose.SteadyState( '/model/kinetics/state' )
+    moose.reinit()
+    state.stoich = stoich
+    state.showMatrices()
+    state.convergenceCriterion = 1e-8
+    return ksolve, state
+
+def parseModelName(fileName):
+    pos1=fileName.rfind('/')
+    pos2=fileName.rfind('.')
+    directory=fileName[:pos1]
+    prefix=fileName[pos1+1:pos2]
+    suffix=fileName[pos2+1:len(fileName)]
+    return directory, prefix, suffix
+
+# Solve for the steady state
+def getState( ksolve, state, vol):
+    scale = 1.0 / ( vol * 6.022e23 )
+    moose.reinit()
+    state.randomInit() # Removing random initial condition to systematically make Dose reponse curves.
+    moose.start( 2.0 ) # Run the model for 2 seconds.
+    state.settle()
+    
+    vector = []
+    a = moose.element( '/model/kinetics/a' ).conc
+    for x in ksolve.nVec[0]:
+        vector.append( x * scale)
+    failedSteadyState = any([np.isnan(x) for x in vector])
+    if not (failedSteadyState):
+        return state.stateType, state.solutionStatus, a, vector
+
+
+def main():
+    # Setup parameters for simulation and plotting
+    simdt= 1e-2
+    plotDt= 1
+
+    # Factors to change in the dose concentration in log scale
+    factorExponent = 10  ## Base: ten raised to some power.
+    factorBegin = -10
+    factorEnd = 11
+    factorStepsize = 2
+    factorScale = 10.0 ## To scale up or down the factors
+
+    # Load Model and set up the steady state solver.
+    # model = sys.argv[1] # To load model from a file.
+    model = os.path.join( sdir_, 'chem_models/19085.cspace' )
+    modelPath, modelName, modelType = parseModelName(model)
+    outputDir = modelPath
+    
+    modelId = moose.loadModel(model, 'model', 'ee')
+    dosePath = '/model/kinetics/b/DabX' # The dose entity
+
+    ksolve, state = setupSteadyState( simdt, plotDt)
+    vol = moose.element( '/model/kinetics' ).volume
+    iterInit = 100
+    solutionVector = []
+    factorArr = []
+    
+    enz = moose.element(dosePath)
+    init = float(enz.kcat) # Dose parameter
+    
+    # Change Dose here to .
+    for factor in range(factorBegin, factorEnd, factorStepsize ):
+        scale = factorExponent ** (factor/factorScale) 
+        enz.kcat = init * scale     
+        print( "scale={:.3f}\tkcat={:.3f}".format( scale, enz.kcat) )
+        for num in range(iterInit):
+            stateType, solStatus, a, vector = getState( ksolve, state, vol)
+            if solStatus == 0:
+                #solutionVector.append(vector[0]/sum(vector))
+                solutionVector.append(a)
+                factorArr.append(scale)   
+                
+    joint = np.array([factorArr, solutionVector])
+    joint = joint[:,joint[1,:].argsort()]
+    got = np.mean( joint ), np.std( joint )
+    expected = (1.2247, 2.46)
+    # Close upto 2 decimal place is good enough.
+    assert np.isclose(got, expected, atol=1e-2).all(), "Got %s, expected %s" % (got, expected)
+    print( joint )
+
+if __name__ == '__main__':
+    main()
diff --git a/moose-examples/.travis.yml b/moose-examples/.travis.yml
index 0f209164..46cb8a38 100644
--- a/moose-examples/.travis.yml
+++ b/moose-examples/.travis.yml
@@ -1,4 +1,9 @@
 sudo : required 
+language: python
+python:
+    - "2.7"
+    - "3.6"
+    - "3.7"
 
 notifications:
     email:
@@ -7,16 +12,8 @@ notifications:
             - bhalla@ncbs.res.in
             - hrani@ncbs.res.in
 
-install:
-    - sudo ./.travis_prepare.sh
-
 script:
+    - pip install pymoose --user --pre
     - ./.travis_run.sh
 
 exclude: [vendor]
-
-deploy:
-  provider: pages
-  skip-cleanup: true
-  github-token: $GHI_TOKEN  #
-  keep-history: true
diff --git a/moose-examples/.travis_prepare.sh b/moose-examples/.travis_prepare.sh
deleted file mode 100755
index a2ad83cc..00000000
--- a/moose-examples/.travis_prepare.sh
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/usr/bin/env bash
-# ROOT should run this script.
-VERSION=$(lsb_release -r | cut -f2)
-apt-get -y update
-apt-get install cmake coreutils --force-yes
-apt-get -y --force-yes install python-qt4 python-pip graphviz
-apt-get -y --force-yes install python-h5py python-scipy python-pygraphviz
-wget -nv https://download.opensuse.org/repositories/home:moose/xUbuntu_$VERSION/Release.key -O Release.key
-apt-key add - < Release.key
-cat <<EOF > /etc/apt/sources.list.d/home:moose.list 
-deb http://download.opensuse.org/repositories/home:/moose/xUbuntu_${VERSION}/ /
-EOF
-apt-get update
-apt-get install python-numpy python-matplotlib python-networkx
-apt-get install pymoose
-python -m pip install python-libsbml --user
diff --git a/moose-examples/neuroml2/NML2_SingleCompHHCell.nml b/moose-examples/neuroml2/NML2_SingleCompHHCell.nml
new file mode 100644
index 00000000..1b1d43b9
--- /dev/null
+++ b/moose-examples/neuroml2/NML2_SingleCompHHCell.nml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<neuroml xmlns="http://www.neuroml.org/schema/neuroml2"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://www.neuroml.org/schema/neuroml2 ../Schemas/NeuroML2/NeuroML_v2beta4.xsd"
+         id="NML2_SingleCompHHCell">
+
+    <!-- Single compartment cell with HH channels -->
+     
+    <!-- This is a "pure" NeuroML 2 file. It can be included in a LEMS file for use in a simulaton 
+    by the LEMS interpreter, see LEMS_NML2_Ex5_DetCell.xml -->     
+
+    <ionChannelHH id="passiveChan" conductance="10pS">
+        <notes>Leak conductance</notes>
+    </ionChannelHH>
+
+
+    <ionChannelHH id="naChan" conductance="10pS" species="na">
+        <notes>Na channel</notes>
+
+        <gateHHrates id="m" instances="3">
+            <forwardRate type="HHExpLinearRate" rate="1per_ms" midpoint="-40mV" scale="10mV"/>
+            <reverseRate type="HHExpRate" rate="4per_ms" midpoint="-65mV" scale="-18mV"/>
+        </gateHHrates>
+
+        <gateHHrates id="h" instances="1">
+            <forwardRate type="HHExpRate" rate="0.07per_ms" midpoint="-65mV" scale="-20mV"/>
+            <reverseRate type="HHSigmoidRate" rate="1per_ms" midpoint="-35mV" scale="10mV"/>
+        </gateHHrates>
+
+    </ionChannelHH>
+
+
+    <ionChannelHH id="kChan" conductance="10pS" species="k">
+
+        <gateHHrates id="n" instances="4">
+            <forwardRate type="HHExpLinearRate" rate="0.1per_ms" midpoint="-55mV" scale="10mV"/>
+            <reverseRate type="HHExpRate" rate="0.125per_ms" midpoint="-65mV" scale="-80mV"/>
+        </gateHHrates>
+            
+    </ionChannelHH>
+
+
+
+    <cell id="hhcell">
+
+        <morphology id="morph1">
+            <segment id="0" name="soma">
+                <proximal x="0" y="0" z="0" diameter="17.841242"/> <!--Gives a convenient surface area of 1000.0 um^2-->
+                <distal x="0" y="0" z="0" diameter="17.841242"/>
+            </segment>
+
+            <segmentGroup id="soma_group">
+                <member segment="0"/>
+            </segmentGroup>
+
+        </morphology>
+
+        <biophysicalProperties id="bioPhys1">
+
+            <membraneProperties>
+                        
+                <channelDensity id="leak" ionChannel="passiveChan" condDensity="3.0 S_per_m2" erev="-54.3mV" ion="non_specific"/>
+                <channelDensity id="naChans" ionChannel="naChan" condDensity="120.0 mS_per_cm2" erev="50.0 mV" ion="na"/>
+                <channelDensity id="kChans" ionChannel="kChan" condDensity="360 S_per_m2" erev="-77mV" ion="k"/>
+
+                <spikeThresh value="-20mV"/>
+                <specificCapacitance value="1.0 uF_per_cm2"/>
+                <initMembPotential value="-65mV"/>
+
+            </membraneProperties>
+
+            <intracellularProperties>
+                <resistivity value="0.03 kohm_cm"/>   <!-- Note: not used in single compartment simulations -->
+            </intracellularProperties>
+
+        </biophysicalProperties>
+
+    </cell>
+
+    <pulseGenerator id="pulseGen1" delay="100ms" duration="100ms" amplitude="0.08nA"/>
+
+
+    <network id="net1">
+        <population id="hhpop" component="hhcell" size="1"/>
+        <explicitInput target="hhpop[0]" input="pulseGen1"/>
+    </network>
+
+</neuroml>
+
diff --git a/moose-examples/neuroml2/converter.py b/moose-examples/neuroml2/converter.py
new file mode 100644
index 00000000..0aec54f3
--- /dev/null
+++ b/moose-examples/neuroml2/converter.py
@@ -0,0 +1,209 @@
+# -*- coding: utf-8 -*-
+# converter.py ---
+#
+# Filename: mtoneuroml.py
+# Description:
+# Author:
+# Maintainer:
+# Created: Mon Apr 22 12:15:23 2013 (+0530)
+# Version:
+# Last-Updated: Wed Jul 10 16:36:14 2013 (+0530)
+#           By: subha
+#     Update #: 819
+# URL:
+# Keywords:
+# Compatibility:
+#
+#
+
+# Commentary:
+#
+# Utility for converting a MOOSE model into NeuroML2. This uses Python
+# libNeuroML.
+#
+#
+
+# Change log:
+#
+# Tue May 21 16:58:03 IST 2013 - Subha moved the code for function
+# fitting to hhfit.py.
+
+#
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 3, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+# Floor, Boston, MA 02110-1301, USA.
+#
+#
+
+# Code:
+
+#!!!!! TODO: unit conversion !!!!
+
+try:
+    from future_builtins import zip
+except ImportError:
+    pass
+import traceback
+import warnings
+from collections import deque
+import numpy as np
+from scipy.optimize import curve_fit
+from matplotlib import pyplot as plt
+
+import moose
+from moose.utils import autoposition
+import neuroml
+import hhfit
+
+
+def convert_morphology(root, positions='auto'):
+    """Convert moose neuron morphology contained under `root` into a
+    NeuroML object. The id of the return object is
+    {root.name}_morphology. Each segment object gets the numeric value
+    of the moose id of the object. The name of the segments are same
+    as the corresponding moose compartment.
+
+    Parameters
+    ----------
+    root : a moose element containing a single cell model.
+
+    positions : string
+    flag to indicate if the positions of the end points of the
+    compartments are explicitly available in the compartments or
+    should be automatically generated.  Possible values:
+
+    `auto` - automatically generate z coordinates using length of the
+    compartments.
+
+    `explicit` - model has explicit coordinates for all compartments.
+
+    Return
+    ------
+    a neuroml.Morphology instance.
+
+    """
+    if positions == 'auto':
+        queue = deque([autoposition(root)])
+    elif positions == 'explicit':
+        compartments = moose.wildcardFind('%s/##[TYPE=Compartment]' % (root.path))
+        queue = deque([compartment for compartment in map(moose.element, compartments)
+                  if len(compartment.neighbours['axial']) == 0])
+        if len(queue) != 1:
+            raise Exception('There must be one and only one top level compartment. Found %d' % (len(topcomp_list)))
+    else:
+        raise Exception('allowed values for keyword argument positions=`auto` or `explicit`')
+    comp_seg = {}
+    parent = None
+    while len(queue) > 0:
+        compartment = queue.popleft()
+        proximal = neuroml.Point3DWithDiam(x=compartment.x0,
+                                           y=compartment.y0,
+                                           z=compartment.z0,
+                                           diameter=compartment.diameter)
+        distal = neuroml.Point3DWithDiam(x=compartment.x,
+                                         y=compartment.y,
+                                         z=compartment.z,
+                                         diameter=compartment.diameter)
+        plist = list(map(moose.element, compartment.neighbours['axial']))
+        try:
+            parent = neuroml.SegmentParent(segments=comp_seg[moose.element(plist[0])].id)
+        except (KeyError, IndexError) as e:
+            parent = None
+        segment = neuroml.Segment(id=compartment.id_.value,
+                                  proximal=proximal,
+                                  distal=distal,
+                                  parent=parent)
+        # TODO: For the time being using numerical value of the moose
+        # id for neuroml id.This needs to be updated for handling
+        # array elements
+        segment.name = compartment.name
+        comp_seg[compartment] = segment
+        queue.extend([comp for comp in map(moose.element, compartment.neighbours['raxial'])])
+    morph = neuroml.Morphology(id='%s_morphology' % (root.name))
+    morph.segments.extend(comp_seg.values())
+    return morph
+
+
+def define_vdep_rate(fn, name):
+    """Define new component type with generic expressions for voltage
+    dependent rate.
+
+    """
+    ctype = neuroml.ComponentType(name)
+    # This is going to be ugly ...
+
+
+
+def convert_hhgate(gate):
+    """Convert a MOOSE gate into GateHHRates in NeuroML"""
+    hh_rates = neuroml.GateHHRates(id=gate.id_.value, name=gate.name)
+    alpha = gate.tableA.copy()
+    beta = gate.tableB - alpha
+    vrange = np.linspace(gate.min, gate.max, len(alpha))
+    afn, ap = hhfit.find_ratefn(vrange, alpha)
+    bfn, bp = hhfit.find_ratefn(vrange, beta)
+    if afn is None:
+        raise Exception('could not find a fitting function for `alpha`')
+    if bfn is  None:
+        raise Exception('could not find a fitting function for `alpha`')
+    afn_type = fn_rate_map[afn]
+    afn_component_type = None
+    if afn_type is None:
+        afn_type, afn_component_type = define_component_type(afn)
+    hh_rates.forward_rate = neuroml.HHRate(type=afn_type,
+                                           midpoint='%gmV' % (ap[2]),
+                                           scale='%gmV' % (ap[1]),
+                                           rate='%gper_ms' % (ap[0]))
+    bfn_type = fn_rate_map[bfn]
+    bfn_component_type = None
+    if bfn_type is None:
+        bfn_type, bfn_component_type = define_component_type(bfn)
+    hh_rates.reverse_rate = neuroml.HHRate(type=bfn_type,
+                                           midpoint='%gmV' % (bp[2]),
+                                           scale='%gmV' % (bp[1]),
+                                           rate='%gper_ms' % (bp[0]))
+    return hh_rates, afn_component_type, bfn_component_type
+
+
+def convert_hhchannel(channel):
+    """Convert a moose HHChannel object into a neuroml element.
+
+    TODO: need to check useConcentration option for Ca2+ and V
+    dependent gates. How to handle generic expressions???
+
+    """
+    nml_channel = neuroml.IonChannel(id=channel.id_.value
+            , name=channel.name, type='ionChannelHH'
+            , conductance=channel.Gbar
+            )
+    if channel.Xpower > 0:
+        hh_rate_x = convert_hhgate(channel.gateX[0])
+        hh_rate_x.instances = channel.Xpower
+        nml_channel.gate.append(hh_rate_x)
+
+    if channel.Ypower > 0:
+        hh_rate_y = convert_hhgate(channel.gateY[0])
+        hh_rate_y.instances = channel.Ypower
+        nml_channel.gate.append(hh_rate_y)
+
+    if channel.Zpower > 0:
+        hh_rate_z = convert_hhgate(channel.gateZ[0])
+        hh_rate_y.instances = channel.Zpower
+        nml_channel.gate.append(hh_rate_z)
+    return nml_channel
+
+
+#
+# converter.py ends here
diff --git a/moose-examples/neuroml2/passiveCell.nml b/moose-examples/neuroml2/passiveCell.nml
new file mode 100644
index 00000000..9b91f253
--- /dev/null
+++ b/moose-examples/neuroml2/passiveCell.nml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<neuroml xmlns="http://www.neuroml.org/schema/neuroml2"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://www.neuroml.org/schema/neuroml2 ../Schemas/NeuroML2/NeuroML_v2beta4.xsd"
+         id="NML2_SingleCompHHCell">
+
+    
+    <ionChannel type="ionChannelPassive" id="passiveChan" conductance="10pS">
+        <notes>Leak conductance</notes>
+    </ionChannel>
+    
+    <cell id="passiveCell">
+
+        <morphology id="morph1">
+            <segment id="0" name="soma">
+                <proximal x="0" y="0" z="0" diameter="17.841242"/> <!--Gives a convenient surface area of 1000.0 ?m�-->
+                <distal x="0" y="0" z="0" diameter="17.841242"/>
+            </segment>
+
+            <segmentGroup id="soma_group">
+                <member segment="0"/>
+            </segmentGroup>
+            
+        </morphology>
+
+        <biophysicalProperties id="bioPhys1">
+
+            <membraneProperties>
+                <channelDensity id="leak" ionChannel="passiveChan" condDensity="3.0S_per_m2" erev="-54.3mV" ion="non_specific"/>
+                <spikeThresh value="-20mV"/>
+                <specificCapacitance value="1.0uF_per_cm2"/>
+                <initMembPotential value="-66.6mV"/>
+            </membraneProperties>
+
+            <intracellularProperties>
+                <resistivity value="0.03kohm_cm"/>   <!-- Note: not used in single compartment simulations -->
+            </intracellularProperties>
+
+        </biophysicalProperties>
+
+    </cell>
+    
+    <pulseGenerator id="pulseGen1" delay="50ms" duration="50ms" amplitude="0.08nA"/>
+
+
+    <network id="net1">
+        <population id="pop0" component="passiveCell" size="1"/>
+        <explicitInput target="pop0[0]" input="pulseGen1"/>
+    </network>
+    
+</neuroml>
diff --git a/moose-examples/neuroml2/run_cell.py b/moose-examples/neuroml2/run_cell.py
new file mode 100644
index 00000000..174358d0
--- /dev/null
+++ b/moose-examples/neuroml2/run_cell.py
@@ -0,0 +1,112 @@
+# -*- coding: utf-8 -*-
+# run_cell.py ---
+#
+# Filename: run_cell.py
+# Description:
+# Author:
+# Maintainer: P Gleeson
+# Version:
+# URL:
+# Keywords:
+# Compatibility:
+#
+#
+
+# Commentary:
+#
+#
+#
+#
+
+# Change log:
+#    Sunday 16 September 2018 10:04:24 AM IST
+#      - Tweaked file to to make it compatible with moose.
+#
+#
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 3, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+# Floor, Boston, MA 02110-1301, USA.
+#
+#
+
+# Code:
+
+import moose
+import sys
+import numpy as np
+
+    
+def run(nogui):
+    
+    filename = 'passiveCell.nml'
+    print('Loading: %s'%filename)
+    reader = moose.mooseReadNML2( filename )
+    assert reader
+    reader.read(filename)
+    
+    msoma = reader.getComp(reader.doc.networks[0].populations[0].id,0,0)
+    print(msoma)
+    
+    
+    data = moose.Neutral('/data')
+    
+    pg = reader.getInput('pulseGen1')
+    
+    inj = moose.Table('%s/pulse' % (data.path))
+    moose.connect(inj, 'requestOut', pg, 'getOutputValue')
+    
+    
+    vm = moose.Table('%s/Vm' % (data.path))
+    moose.connect(vm, 'requestOut', msoma, 'getVm')
+    
+    simdt = 1e-6
+    plotdt = 1e-4
+    simtime = 150e-3
+    
+    if (1):
+        #moose.showmsg( '/clock' )
+        for i in range(8):
+            moose.setClock( i, simdt )
+        moose.setClock( 8, plotdt )
+        moose.reinit()
+    else:
+        utils.resetSim([model.path, data.path], simdt, plotdt, simmethod='ee')
+        moose.showmsg( '/clock' )
+        
+    moose.start(simtime)
+    
+    print("Finished simulation!")
+    
+    t = np.linspace(0, simtime, len(vm.vector))
+    
+    if not nogui:
+        import matplotlib.pyplot as plt
+
+        plt.subplot(211)
+        plt.plot(t, vm.vector * 1e3, label='Vm (mV)')
+        plt.legend()
+        plt.title('Vm')
+        plt.subplot(212)
+        plt.title('Input')
+        plt.plot(t, inj.vector * 1e9, label='injected (nA)')
+        #plt.plot(t, gK.vector * 1e6, label='K')
+        #plt.plot(t, gNa.vector * 1e6, label='Na')
+        plt.legend()
+        plt.show()
+        plt.close()
+
+if __name__ == '__main__':
+    nogui = '-nogui' in sys.argv
+    run(nogui)
diff --git a/moose-examples/neuroml2/run_hhcell.py b/moose-examples/neuroml2/run_hhcell.py
new file mode 100644
index 00000000..2b38cd67
--- /dev/null
+++ b/moose-examples/neuroml2/run_hhcell.py
@@ -0,0 +1,151 @@
+# -*- coding: utf-8 -*-
+# run_hhcell.py ---
+#
+# Filename: run_hhcell.py
+# Description:
+# Author:
+# Maintainer: P Gleeson
+# Version:
+# URL:
+# Keywords:
+# Compatibility:
+#
+#
+
+# Commentary:
+#
+#
+#
+#
+
+# Change log:
+#
+#
+#
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 3, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+# Floor, Boston, MA 02110-1301, USA.
+#
+#
+
+# Code:
+
+import moose
+import sys
+import numpy as np
+
+def test_channel_gates():
+    """Creates prototype channels under `/library` and plots the time
+    constants (tau) and activation (minf, hinf, ninf) parameters for the
+    channel gates.
+
+    """
+    import matplotlib.pyplot as plt
+    lib = moose.Neutral('/library')
+    m = moose.element('/library[0]/naChan[0]/gateX')
+    h = moose.element('/library[0]/naChan[0]/gateY')
+    n = moose.element('/library[0]/kChan[0]/gateX')
+    v = np.linspace(n.min,n.max, n.divs+1)
+    
+    plt.subplot(221)
+    plt.plot(v, 1/m.tableB, label='tau_m')
+    plt.plot(v, 1/h.tableB, label='tau_h')
+    plt.plot(v, 1/n.tableB, label='tau_n')
+    plt.legend()
+    
+    plt.subplot(222)
+    plt.plot(v, m.tableA/m.tableB, label='m_inf')
+    plt.plot(v, h.tableA/h.tableB, label='h_inf')
+    plt.plot(v, n.tableA/n.tableB, label='n_inf')
+    plt.legend()
+    
+    plt.subplot(223)
+    plt.plot(v, m.tableA, label='mA(alpha)')
+    plt.plot(v, h.tableA, label='hA(alpha)')
+    plt.plot(v, n.tableA, label='nA(alpha)')
+    plt.legend()
+    plt.subplot(224)
+    
+    plt.plot(v, m.tableB, label='mB')
+    plt.plot(v, m.tableB-m.tableA, label='mB-A(beta)')
+    
+    plt.plot(v, h.tableB, label='hB')
+    plt.plot(v, h.tableB-h.tableA, label='hB-A(beta)')
+    
+    plt.plot(v, n.tableB, label='nB')
+    plt.plot(v, n.tableB-n.tableA, label='nB-nA(beta)')
+    plt.legend()
+    
+    plt.show()
+
+
+def run(nogui):
+    filename = 'NML2_SingleCompHHCell.nml'
+    print('Loading: %s'%filename)
+    reader = moose.mooseReadNML2(filename)
+    msoma = reader.getComp(reader.doc.networks[0].populations[0].id,0,0)
+    print(msoma)
+    data = moose.Neutral('/data')
+    pg = reader.getInput('pulseGen1')
+    inj = moose.Table('%s/pulse' % (data.path))
+    moose.connect(inj, 'requestOut', pg, 'getOutputValue')
+    vm = moose.Table('%s/Vm' % (data.path))
+    moose.connect(vm, 'requestOut', msoma, 'getVm')
+    
+    simdt = 1e-6
+    plotdt = 1e-4
+    simtime = 300e-3
+    if (1):
+        #moose.showmsg( '/clock' )
+        for i in range(8):
+            moose.setClock( i, simdt )
+        moose.setClock( 8, plotdt )
+        moose.reinit()
+    else:
+        utils.resetSim([model.path, data.path], simdt, plotdt, simmethod='ee')
+        moose.showmsg( '/clock' )
+    moose.start(simtime)
+    
+    print("Finished simulation!")
+    
+    t = np.linspace(0, simtime, len(vm.vector))
+    
+    if not nogui:
+        import matplotlib.pyplot as plt
+
+        vfile = open('moose_v_hh.dat','w')
+
+        for i in range(len(t)):
+            vfile.write('%s\t%s\n'%(t[i],vm.vector[i]))
+        vfile.close()
+        plt.subplot(211)
+        plt.plot(t, vm.vector * 1e3, label='Vm (mV)')
+        plt.legend()
+        plt.title('Vm')
+        plt.subplot(212)
+        plt.title('Input')
+        plt.plot(t, inj.vector * 1e9, label='injected (nA)')
+        #plt.plot(t, gK.vector * 1e6, label='K')
+        #plt.plot(t, gNa.vector * 1e6, label='Na')
+        plt.legend()
+        plt.figure()
+        test_channel_gates()
+        plt.show()
+        plt.close()
+        
+    
+if __name__ == '__main__':
+    nogui = '-nogui' in sys.argv
+    run(nogui)
diff --git a/moose-examples/squid/squid.py b/moose-examples/squid/squid.py
index dae8ff9d..de3efc46 100644
--- a/moose-examples/squid/squid.py
+++ b/moose-examples/squid/squid.py
@@ -28,8 +28,6 @@
 
 # Code:
 import sys
-sys.path.append('../../python')
-
 import numpy
 import moose
 
@@ -99,22 +97,24 @@ class IonChannel(moose.HHChannel):
     def alpha_m(self):
         if self.Xpower == 0:
             return numpy.array([])        
-        return numpy.array(moose.HHGate('%s/gateX' % (self.path)).tableA)
+        return numpy.array(moose.element('%s/gateX' % (self.path)).tableA)
     @property
     def beta_m(self):
         if self.Xpower == 0:
             return numpy.array([])        
-        return numpy.array(moose.HHGate('%s/gateX' % (self.path)).tableB) - numpy.array(moose.HHGate('%s/gateX' % (self.path)).tableA)
+        return numpy.array(moose.element('%s/gateX' % (self.path)).tableB) - \
+                numpy.array(moose.element('%s/gateX' % (self.path)).tableA)
     @property
     def alpha_h(self):
         if self.Ypower == 0:
             return numpy.array([])        
-        return numpy.array(moose.HHGate('%s/gateY' % (self.path)).tableA)
+        return numpy.array(moose.element('%s/gateY' % (self.path)).tableA)
     @property
     def beta_h(self):
         if self.Ypower == 0:
             return numpy.array([])        
-        return numpy.array(moose.HHGate('%s/gateY' % (self.path)).tableB) - numpy.array(moose.HHGate('%s/gateY' % (self.path)).tableA)
+        return numpy.array(moose.element('%s/gateY' % (self.path)).tableB) \
+                - numpy.array(moose.element('%s/gateY' % (self.path)).tableA)
 
 class SquidAxon(moose.Compartment):
     EREST_ACT = 0.0 # can be -70 mV if not following original HH convention
diff --git a/moose-examples/squid/squid_demo.py b/moose-examples/squid/squid_demo.py
index d243b0f5..d87d615c 100644
--- a/moose-examples/squid/squid_demo.py
+++ b/moose-examples/squid/squid_demo.py
@@ -1,5 +1,4 @@
-
- # -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
 # squidgui.py --- 
 # 
 # Filename: squidgui.py
@@ -48,18 +47,21 @@
 # Code:
 
 import sys
-sys.path.append('../../python')
 import os
-os.environ['NUMPTHREADS'] = '1'
-
 from collections import defaultdict
 import time
 
-from PyQt4 import QtGui
-from PyQt4 import QtCore
+pyqt_ver_ = 4
+try:
+    from PyQt5 import QtGui, QtCore
+    pyqt_ver_ = 5
+except ImportError as e:
+    from PyQt4 import QtGui
+    from PyQt4 import QtCore
 import numpy
 from matplotlib.figure import Figure
-from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas, NavigationToolbar2QT as NavigationToolbar
+from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
+from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar
 
 import moose
 
@@ -163,7 +165,6 @@ def set_default_line_edit_size(widget):
     widget.setMinimumSize(default_line_edit_size)
     widget.setMaximumSize(default_line_edit_size)
 
-
 class SquidGui(QtGui.QMainWindow):
     defaults = {}
     defaults.update(SquidAxon.defaults)
diff --git a/moose-examples/squid/squid_demo_qt5.py b/moose-examples/squid/squid_demo_qt5.py
new file mode 100644
index 00000000..59979883
--- /dev/null
+++ b/moose-examples/squid/squid_demo_qt5.py
@@ -0,0 +1,861 @@
+# -*- coding: utf-8 -*-
+# Description:  Squid Model
+# Author: Subha
+# Maintainer:  Dilawar Singh <dilawars@ncbs.res.in>
+# Created: Mon Jul  9 18:23:55 2012 (+0530)
+# Version: 
+# Last-Updated: Wednesday 12 September 2018 04:23:52 PM IST
+#       PyQt5 version
+
+import sys
+import os
+from collections import defaultdict
+import time
+
+from PyQt5 import QtGui, QtCore
+from PyQt5.QtWidgets import QMainWindow, QApplication, QGroupBox, QSizePolicy
+from PyQt5.QtWidgets import QLabel, QLineEdit, QGridLayout, QDockWidget
+from PyQt5.QtWidgets import QCheckBox, QTabWidget, QComboBox, QWidget
+from PyQt5.QtWidgets import QVBoxLayout, QFrame, QHBoxLayout, QAction
+from PyQt5.QtWidgets import QToolButton, QScrollArea, QTextBrowser
+
+import numpy
+from matplotlib.figure import Figure
+from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
+from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar
+
+import moose
+
+from squid import *
+from squid_setup import SquidSetup
+from electronics import ClampCircuit
+
+
+tooltip_Nernst = """<h3>Ionic equilibrium potential</h3>
+<p/>
+The equilibrium potential for ion C is given by Nernst equation:
+<p>
+E<sub>C</sub> = (RT/zF) * ln([C]<sub>out</sub> / [C]<sub>in</sub>)
+</p>
+where R is the ideal gas constant (8.3145 J/mol K),<br>
+      T is absolute temperature,<br>
+      z is the valence of the ion,<br>
+      F is Faraday's constant 96480 C/mol,<br>
+      [C]<sub>out</sub> is concentration of C outside the membrane,<br>
+      [C]<sub>in</sub> is concentration of C inside the membrane."""
+
+tooltip_Erest = """<h3>Resting membrane potential</h3>
+<p/>
+The resting membrane potential is determined by the ionic
+concentrations inside and outside the cell membrane and is given by
+the Goldman-Hodgkin-Katz equation:
+<p>
+
+V = (RT/F) * ln((P<sub>K</sub>[K<sup>+</sup>]<sub>out</sub> + P<sub>Na</sub>[Na<sup>+</sup>]<sub>out</sub> + P<sub>Cl</sub>[Cl<sup>-</sup>]<sub>in</sub>) / (P<sub>K</sub>[K<sup>+</sup>]in + P<sub>Na</sub>[Na<sup>+</sup>]<sub>in</sub> + P<sub>Cl</sub>[Cl<sup>-</sup>]<sub>out</sub>))
+
+</p>
+where P<sub>C</sub> is the permeability of the membrane to ion C.
+
+"""
+
+tooltip_NaChan = """<h3>Na+ channel conductance</h3>
+<p/>
+The Na<sup>+</sup> channel conductance in squid giant axon is given by:
+
+<p> G<sub>Na</sub> = GÌ„<sub>Na</sub> * m<sup>3</sup> * h </p>
+
+and the current through this channel is:
+<p>
+I<sub>Na</sub> = G<sub>Na</sub> * (V - E<sub>Na</sub>) = GÌ„<sub>Na</sub> * m<sup>3</sup> * h * (V - E<sub>Na</sub>)
+</p>
+
+where GÌ„<sub>Na</sub> is the peak conductance of Na<sup>+</sup> channel, m is
+the fraction of activation gates open and h is the fraction of
+deactivation gates open. The transition from open to closed state has
+first order kinetics: 
+<p> dm/dt = α<sub>m</sub> * ( 1 - m) - β<sub>m</sub> * m </p> 
+and similarly for h.
+
+The steady state values are:
+<p> m<sub>∞</sub> = α<sub>m</sub>/(α<sub>m</sub> + β<sub>m</sub>) </p>
+and time constant for steady state is:
+<p>τ<sub>m</sub> = 1/ (α<sub>m</sub> + β<sub>m</sub>) </p>
+and similarly for h.
+"""
+
+tooltip_KChan = """<h3>K+ channel conductance</h3>
+<p/>The K+ channel conductance in squid giant axon is given by:
+
+<p> G<sub>K</sub> = GÌ„<sub>K</sub> * n<sup>4</sup></p>
+
+and the current through this channel is:
+<p>
+I<sub>K</sub> = G<sub>K</sub> * (V - E<sub>K</sub>) = GÌ„<sub>K</sub> * n<sup>4</sup> * (V - E<sub>K</sub>) 
+</p>
+where GÌ„<sub>K</sub> is the peak conductance of K<sup>+</sup> channel,
+n is the fraction of activation gates open. The transition from open
+to closed state has first order kinetics: <p> dn/dt = α<sub>n</sub> *
+( 1 - n) - β<sub>n</sub> * n </p>.
+
+The steady state values are:
+<p>
+n<sub>∞</sub> = α<sub>n</sub>/(α<sub>n</sub> + β<sub>n</sub>)
+</p>
+and time constant for steady state is:
+<p>
+τ<sub>n</sub> = 1/ (α<sub>n</sub> + β<sub>n</sub>)
+
+</p>
+and similarly for h.
+"""
+
+tooltip_Im = """<h3>Membrane current</h3>
+<p/>
+The current through the membrane is given by:
+<p>
+I<sub>m</sub> = C<sub>m</sub> dV/dt + I<sub>K</sub> + I<sub>Na</sub> + I<sub>L</sub>
+</p><p>
+ = C<sub>m</sub> dV/dt + G<sub>K</sub>(V, t) * (V - E<sub>K</sub>) + G<sub>Na</sub> * (V - E<sub>Na</sub>) + G<sub>L</sub> * (V - E<sub>L</sub>)
+</p>
+where G<sub>L</sub> is the leak current and E<sub>L</sub> is the leak reversal potential.
+
+"""
+
+default_line_edit_size = QtCore.QSize(80, 25)
+def set_default_line_edit_size(widget):
+    widget.setMinimumSize(default_line_edit_size)
+    widget.setMaximumSize(default_line_edit_size)
+
+class SquidGui( QMainWindow ):
+    defaults = {}
+    defaults.update(SquidAxon.defaults)
+    defaults.update(ClampCircuit.defaults)
+    defaults.update({'runtime': 50.0,
+                  'simdt': 0.01,
+                  'plotdt': 0.1,
+                  'vclamp.holdingV': 0.0,
+                  'vclamp.holdingT': 10.0,
+                  'vclamp.prepulseV': 0.0,
+                  'vclamp.prepulseT': 0.0,
+                  'vclamp.clampV': 50.0,
+                  'vclamp.clampT': 20.0,
+                  'iclamp.baseI': 0.0,
+                  'iclamp.firstI': 0.1,
+                  'iclamp.firstT': 40.0,
+                  'iclamp.firstD': 5.0,
+                  'iclamp.secondI': 0.0,
+                  'iclamp.secondT': 0.0,
+                  'iclamp.secondD': 0.0
+                  })
+    def __init__(self, *args):
+        QMainWindow.__init__(self, *args)
+        self.squid_setup = SquidSetup()
+        self._plotdt = SquidGui.defaults['plotdt']
+        self._plot_dict = defaultdict(list)
+        self.setWindowTitle('Squid Axon simulation')        
+        self.setDockNestingEnabled(True)
+        self._createRunControl()
+        self.addDockWidget(QtCore.Qt.LeftDockWidgetArea, self._runControlDock) 
+        self._runControlDock.setFeatures(QDockWidget.AllDockWidgetFeatures)	 
+        self._createChannelControl()
+        self._channelCtrlBox.setWindowTitle('Channel properties')
+        self._channelControlDock.setFeatures(QDockWidget.AllDockWidgetFeatures)	 
+        self.addDockWidget(QtCore.Qt.LeftDockWidgetArea, self._channelControlDock) 
+        self._createElectronicsControl()
+        self._electronicsDock.setFeatures(QDockWidget.AllDockWidgetFeatures)	 
+        self._electronicsDock.setWindowTitle('Electronics')
+        self.addDockWidget(QtCore.Qt.LeftDockWidgetArea, self._electronicsDock) 
+        self._createPlotWidget()             
+        self.setCentralWidget(self._plotWidget)
+        self._createStatePlotWidget()
+        self._createHelpMessage()
+        self._helpWindow.setVisible(False)
+        self._statePlotWidget.setWindowFlags(QtCore.Qt.Window)
+        self._statePlotWidget.setWindowTitle('State plot')
+        self._initActions()
+        self._createRunToolBar()
+        self._createPlotToolBar()
+
+    def getFloatInput(self, widget, name):
+        try:
+            return float(str(widget.text()))
+        except ValueError:
+            QMessageBox.critical(self, 'Invalid input', 'Please enter a valid number for {}'.format(name))
+            raise
+
+        
+    def _createPlotWidget(self):
+        self._plotWidget = QWidget()
+        self._plotFigure = Figure()
+        self._plotCanvas = FigureCanvas(self._plotFigure)
+        self._plotCanvas.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
+        self._plotCanvas.updateGeometry()
+        self._plotCanvas.setParent(self._plotWidget)
+        self._plotCanvas.mpl_connect('scroll_event', self._onScroll)
+        self._plotFigure.set_canvas(self._plotCanvas)
+        # Vm and command voltage go in the same subplot
+        self._vm_axes = self._plotFigure.add_subplot(2,2,1, title='Membrane potential')
+        self._vm_axes.set_ylim(-20.0, 120.0)
+        # Channel conductances go to the same subplot
+        self._g_axes = self._plotFigure.add_subplot(2,2,2, title='Channel conductance')
+        self._g_axes.set_ylim(0.0, 0.5)
+        # Injection current for Vclamp/Iclamp go to the same subplot
+        self._im_axes = self._plotFigure.add_subplot(2,2,3, title='Injection current')
+        self._im_axes.set_ylim(-0.5, 0.5)
+        # Channel currents go to the same subplot
+        self._i_axes = self._plotFigure.add_subplot(2,2,4, title='Channel current')
+        self._i_axes.set_ylim(-10, 10)
+        for axis in self._plotFigure.axes:
+            axis.set_autoscale_on(False)
+        layout = QVBoxLayout()
+        layout.addWidget(self._plotCanvas)
+        self._plotNavigator = NavigationToolbar(self._plotCanvas, self._plotWidget)
+        layout.addWidget(self._plotNavigator)
+        self._plotWidget.setLayout(layout)
+
+    def _createStatePlotWidget(self):        
+        self._statePlotWidget = QWidget()
+        self._statePlotFigure = Figure()
+        self._statePlotCanvas = FigureCanvas(self._statePlotFigure)
+        self._statePlotCanvas.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
+        self._statePlotCanvas.updateGeometry()
+        self._statePlotCanvas.setParent(self._statePlotWidget)
+        self._statePlotFigure.set_canvas(self._statePlotCanvas)
+        self._statePlotFigure.subplots_adjust(hspace=0.5)
+        self._statePlotAxes = self._statePlotFigure.add_subplot(2,1,1, title='State plot')
+        self._state_plot, = self._statePlotAxes.plot([], [], label='state')
+        self._activationParamAxes = self._statePlotFigure.add_subplot(2,1,2, title='H-H activation parameters vs time')
+        self._activationParamAxes.set_xlabel('Time (ms)')
+        #for axis in self._plotFigure.axes:
+        #    axis.autoscale(False)
+        self._stateplot_xvar_label = QLabel('Variable on X-axis')
+        self._stateplot_xvar_combo = QComboBox()
+        self._stateplot_xvar_combo.addItems(['V', 'm', 'n', 'h'])
+        self._stateplot_xvar_combo.setCurrentIndex(0)
+        self._stateplot_xvar_combo.setEditable(False)
+        #  self.connect(self._stateplot_xvar_combo,
+                     #  QtCore.SIGNAL('currentIndexChanged(const QString&)'),
+                     #  self._statePlotXSlot)
+        self._stateplot_xvar_combo.currentIndexChanged.connect( self._statePlotXSlot )
+        self._stateplot_yvar_label = QLabel('Variable on Y-axis')
+        self._stateplot_yvar_combo = QComboBox()
+        self._stateplot_yvar_combo.addItems(['V', 'm', 'n', 'h'])
+        self._stateplot_yvar_combo.setCurrentIndex(2)
+        self._stateplot_yvar_combo.setEditable(False)
+        self._stateplot_yvar_combo.currentIndexChanged.connect(self._statePlotYSlot)
+        self._statePlotNavigator = NavigationToolbar(self._statePlotCanvas, self._statePlotWidget)
+        frame = QFrame()
+        frame.setFrameStyle(QFrame.StyledPanel + QFrame.Raised)
+        layout = QHBoxLayout()
+        layout.addWidget(self._stateplot_xvar_label)
+        layout.addWidget(self._stateplot_xvar_combo)
+        layout.addWidget(self._stateplot_yvar_label)
+        layout.addWidget(self._stateplot_yvar_combo)
+        frame.setLayout(layout)
+        self._closeStatePlotAction = QAction('Close', self)
+        self._closeStatePlotAction.triggered.connect(self._statePlotWidget.close)
+        self._closeStatePlotButton = QToolButton()
+        self._closeStatePlotButton.setDefaultAction(self._closeStatePlotAction)
+        layout = QVBoxLayout()
+        layout.addWidget(frame)
+        layout.addWidget(self._statePlotCanvas)
+        layout.addWidget(self._statePlotNavigator)
+        layout.addWidget(self._closeStatePlotButton)
+        self._statePlotWidget.setLayout(layout)  
+        # Setting the close event so that when the help window is
+        # closed the ``State plot`` button becomes unchecked
+        self._statePlotWidget.closeEvent = lambda event: self._showStatePlotAction.setChecked(False)
+
+    def _createRunControl(self):
+        self._runControlBox = QGroupBox(self)
+        self._runControlBox.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
+        self._runTimeLabel = QLabel("Run time (ms)", self._runControlBox)
+        self._simTimeStepLabel = QLabel("Simulation time step (ms)", self._runControlBox)
+        self._runTimeEdit = QLineEdit('%g' % (SquidGui.defaults['runtime']), self._runControlBox)
+        set_default_line_edit_size(self._runTimeEdit)
+        self._simTimeStepEdit = QLineEdit('%g' % (SquidGui.defaults['simdt']), self._runControlBox)
+        set_default_line_edit_size(self._simTimeStepEdit)
+        layout = QGridLayout()
+        layout.addWidget(self._runTimeLabel, 0, 0)
+        layout.addWidget(self._runTimeEdit, 0, 1)
+        layout.addWidget(self._simTimeStepLabel, 1, 0)
+        layout.addWidget(self._simTimeStepEdit, 1, 1)
+        layout.setColumnStretch(2, 1.0)
+        layout.setRowStretch(2, 1.0)
+        self._runControlBox.setLayout(layout)
+        self._runControlDock = QDockWidget('Simulation', self)
+        self._runControlDock.setWidget(self._runControlBox)
+
+    def _createChannelControl(self):
+        self._channelControlDock = QDockWidget('Channels', self)
+        self._channelCtrlBox = QGroupBox(self)
+        self._naConductanceToggle = QCheckBox('Block Na+ channel', self._channelCtrlBox)
+        self._naConductanceToggle.setToolTip('<html>%s</html>' % (tooltip_NaChan))
+        self._kConductanceToggle = QCheckBox('Block K+ channel', self._channelCtrlBox)
+        self._kConductanceToggle.setToolTip('<html>%s</html>' % (tooltip_KChan))
+        self._kOutLabel = QLabel('[K+]out (mM)', self._channelCtrlBox)
+        self._kOutEdit = QLineEdit('%g' % (self.squid_setup.squid_axon.K_out), 
+                                         self._channelCtrlBox)
+        self._kOutLabel.setToolTip('<html>%s</html>' % (tooltip_Nernst))
+        self._kOutEdit.setToolTip('<html>%s</html>' % (tooltip_Nernst))
+        set_default_line_edit_size(self._kOutEdit)
+        self._naOutLabel = QLabel('[Na+]out (mM)', self._channelCtrlBox)
+        self._naOutEdit = QLineEdit('%g' % (self.squid_setup.squid_axon.Na_out), 
+                                         self._channelCtrlBox)
+        self._naOutLabel.setToolTip('<html>%s</html>' % (tooltip_Nernst))
+        self._naOutEdit.setToolTip('<html>%s</html>' % (tooltip_Nernst))
+        set_default_line_edit_size(self._naOutEdit)
+        self._kInLabel = QLabel('[K+]in (mM)', self._channelCtrlBox)
+        self._kInEdit = QLineEdit('%g' % (self.squid_setup.squid_axon.K_in), 
+                                         self._channelCtrlBox)
+        self._kInEdit.setToolTip(tooltip_Nernst)
+        self._naInLabel = QLabel('[Na+]in (mM)', self._channelCtrlBox)
+        self._naInEdit = QLineEdit('%g' % (self.squid_setup.squid_axon.Na_in), 
+                                         self._channelCtrlBox)
+        self._naInEdit.setToolTip('<html>%s</html>' % (tooltip_Nernst))
+        self._temperatureLabel = QLabel('Temperature (C)', self._channelCtrlBox)
+        self._temperatureEdit = QLineEdit('%g' % (self.defaults['temperature'] - CELSIUS_TO_KELVIN),
+                                                self._channelCtrlBox)
+        self._temperatureEdit.setToolTip('<html>%s</html>' % (tooltip_Nernst))
+        set_default_line_edit_size(self._temperatureEdit)
+        for child in self._channelCtrlBox.children():
+            if isinstance(child, QLineEdit):
+                set_default_line_edit_size(child)
+        layout = QGridLayout(self._channelCtrlBox)
+        layout.addWidget(self._naConductanceToggle, 0, 0)
+        layout.addWidget(self._kConductanceToggle, 1, 0)
+        layout.addWidget(self._naOutLabel, 2, 0)
+        layout.addWidget(self._naOutEdit, 2, 1)
+        layout.addWidget(self._naInLabel, 3, 0)
+        layout.addWidget(self._naInEdit, 3, 1)
+        layout.addWidget(self._kOutLabel, 4, 0)
+        layout.addWidget(self._kOutEdit, 4, 1)
+        layout.addWidget(self._kInLabel, 5, 0)
+        layout.addWidget(self._kInEdit, 5, 1)
+        layout.addWidget(self._temperatureLabel, 6, 0)
+        layout.addWidget(self._temperatureEdit, 6, 1)
+        layout.setRowStretch(7, 1.0)
+        self._channelCtrlBox.setLayout(layout)
+        self._channelControlDock.setWidget(self._channelCtrlBox)
+        return self._channelCtrlBox        
+
+    def __get_stateplot_data(self, name):
+        data = []
+        if name == 'V':
+            data = self.squid_setup.vm_table.vector
+        elif name == 'm':
+            data = self.squid_setup.m_table.vector
+        elif name == 'h':
+            data = self.squid_setup.h_table.vector
+        elif name == 'n':
+            data = self.squid_setup.n_table.vector
+        else:
+            raise ValueError('Unrecognized selection: %s' % (name))
+        return numpy.asarray(data)
+    
+    def _statePlotYSlot(self, selectedItem):
+        ydata = self.__get_stateplot_data(str(selectedItem))
+        self._state_plot.set_ydata(ydata)
+        self._statePlotAxes.set_ylabel(selectedItem)
+        if str(selectedItem) == 'V':
+            self._statePlotAxes.set_ylim(-20, 120)
+        else:
+            self._statePlotAxes.set_ylim(0, 1)
+        self._statePlotCanvas.draw()
+        
+    def _statePlotXSlot(self, selectedItem):
+        xdata = self.__get_stateplot_data(str(selectedItem))
+        self._state_plot.set_xdata(xdata)
+        self._statePlotAxes.set_xlabel(selectedItem)
+        if str(selectedItem) == 'V':
+            self._statePlotAxes.set_xlim(-20, 120)
+        else:
+            self._statePlotAxes.set_xlim(0, 1)
+        self._statePlotCanvas.draw()
+
+    def _createElectronicsControl(self):
+        """Creates a tabbed widget of voltage clamp and current clamp controls"""
+        self._electronicsTab = QTabWidget(self)
+        self._electronicsTab.addTab(self._getIClampCtrlBox(), 'Current clamp')
+        self._electronicsTab.addTab(self._getVClampCtrlBox(), 'Voltage clamp')
+        self._electronicsDock = QDockWidget(self)
+        self._electronicsDock.setWidget(self._electronicsTab)
+
+    def _getVClampCtrlBox(self):
+        vClampPanel = QGroupBox(self)
+        self._vClampCtrlBox = vClampPanel
+        self._holdingVLabel = QLabel("Holding Voltage (mV)", vClampPanel)
+        self._holdingVEdit = QLineEdit('%g' % (SquidGui.defaults['vclamp.holdingV']), vClampPanel)
+        self._holdingTimeLabel = QLabel("Holding Time (ms)", vClampPanel)
+        self._holdingTimeEdit = QLineEdit('%g' % (SquidGui.defaults['vclamp.holdingT']), vClampPanel)
+        self._prePulseVLabel = QLabel("Pre-pulse Voltage (mV)", vClampPanel)
+        self._prePulseVEdit = QLineEdit('%g' % (SquidGui.defaults['vclamp.prepulseV']), vClampPanel)
+        self._prePulseTimeLabel = QLabel("Pre-pulse Time (ms)", vClampPanel)
+        self._prePulseTimeEdit = QLineEdit('%g' % (SquidGui.defaults['vclamp.prepulseT']), vClampPanel)
+        self._clampVLabel = QLabel("Clamp Voltage (mV)", vClampPanel)
+        self._clampVEdit = QLineEdit('%g' % (SquidGui.defaults['vclamp.clampV']), vClampPanel)
+        self._clampTimeLabel = QLabel("Clamp Time (ms)", vClampPanel)
+        self._clampTimeEdit = QLineEdit('%g' % (SquidGui.defaults['vclamp.clampT']), vClampPanel)
+        for child in vClampPanel.children():
+            if isinstance(child, QLineEdit):
+                set_default_line_edit_size(child)
+        layout = QGridLayout(vClampPanel)
+        layout.addWidget(self._holdingVLabel, 0, 0)
+        layout.addWidget(self._holdingVEdit, 0, 1)
+        layout.addWidget(self._holdingTimeLabel, 1, 0)
+        layout.addWidget(self._holdingTimeEdit, 1, 1)
+        layout.addWidget(self._prePulseVLabel, 2, 0)
+        layout.addWidget(self._prePulseVEdit, 2, 1)
+        layout.addWidget(self._prePulseTimeLabel,3,0)
+        layout.addWidget(self._prePulseTimeEdit, 3, 1)
+        layout.addWidget(self._clampVLabel, 4, 0)
+        layout.addWidget(self._clampVEdit, 4, 1)
+        layout.addWidget(self._clampTimeLabel, 5, 0)
+        layout.addWidget(self._clampTimeEdit, 5, 1)
+        layout.setRowStretch(6, 1.0)
+        vClampPanel.setLayout(layout)
+        return self._vClampCtrlBox
+
+    def _getIClampCtrlBox(self):
+        iClampPanel = QGroupBox(self)
+        self._iClampCtrlBox = iClampPanel
+        self._baseCurrentLabel = QLabel("Base Current Level (uA)",iClampPanel)
+        self._baseCurrentEdit = QLineEdit('%g' % (SquidGui.defaults['iclamp.baseI']),iClampPanel)
+        self._firstPulseLabel = QLabel("First Pulse Current (uA)", iClampPanel)
+        self._firstPulseEdit = QLineEdit('%g' % (SquidGui.defaults['iclamp.firstI']), iClampPanel)
+        self._firstDelayLabel = QLabel("First Onset Delay (ms)", iClampPanel)
+        self._firstDelayEdit = QLineEdit('%g' % (SquidGui.defaults['iclamp.firstD']),iClampPanel)
+        self._firstPulseWidthLabel = QLabel("First Pulse Width (ms)", iClampPanel)
+        self._firstPulseWidthEdit = QLineEdit('%g' % (SquidGui.defaults['iclamp.firstT']), iClampPanel)
+        self._secondPulseLabel = QLabel("Second Pulse Current (uA)", iClampPanel)
+        self._secondPulseEdit = QLineEdit('%g' % (SquidGui.defaults['iclamp.secondI']), iClampPanel)
+        self._secondDelayLabel = QLabel("Second Onset Delay (ms)", iClampPanel)
+        self._secondDelayEdit = QLineEdit('%g' % (SquidGui.defaults['iclamp.secondD']),iClampPanel)
+        self._secondPulseWidthLabel = QLabel("Second Pulse Width (ms)", iClampPanel)
+        self._secondPulseWidthEdit = QLineEdit('%g' % (SquidGui.defaults['iclamp.secondT']), iClampPanel)
+        self._pulseMode = QComboBox(iClampPanel)
+        self._pulseMode.addItem("Single Pulse")
+        self._pulseMode.addItem("Pulse Train")
+        for child in iClampPanel.children():
+            if isinstance(child, QLineEdit):
+                set_default_line_edit_size(child)
+        layout = QGridLayout(iClampPanel)
+        layout.addWidget(self._baseCurrentLabel, 0, 0)
+        layout.addWidget(self._baseCurrentEdit, 0, 1)
+        layout.addWidget(self._firstPulseLabel, 1, 0)
+        layout.addWidget(self._firstPulseEdit, 1, 1)
+        layout.addWidget(self._firstDelayLabel, 2, 0)
+        layout.addWidget(self._firstDelayEdit, 2, 1)
+        layout.addWidget(self._firstPulseWidthLabel, 3, 0)
+        layout.addWidget(self._firstPulseWidthEdit, 3, 1)
+        layout.addWidget(self._secondPulseLabel, 4, 0)
+        layout.addWidget(self._secondPulseEdit, 4, 1)
+        layout.addWidget(self._secondDelayLabel, 5, 0)
+        layout.addWidget(self._secondDelayEdit, 5, 1)
+        layout.addWidget(self._secondPulseWidthLabel, 6, 0)
+        layout.addWidget(self._secondPulseWidthEdit, 6, 1)
+        layout.addWidget(self._pulseMode, 7, 0, 1, 2)
+        layout.setRowStretch(8, 1.0)        
+        # layout.setSizeConstraint(QLayout.SetFixedSize)
+        iClampPanel.setLayout(layout)
+        return self._iClampCtrlBox
+
+    def _overlayPlots(self, overlay):        
+        if not overlay:
+            for axis in (self._plotFigure.axes + self._statePlotFigure.axes):
+                title = axis.get_title()
+                axis.clear()
+                axis.set_title(title)
+            suffix = ''
+        else:
+            suffix = '_%d' % (len(self._plot_dict['vm']))
+        self._vm_axes.set_xlim(0.0, self._runtime)
+        self._g_axes.set_xlim(0.0, self._runtime)
+        self._im_axes.set_xlim(0.0, self._runtime)
+        self._i_axes.set_xlim(0.0, self._runtime)
+        self._vm_plot, = self._vm_axes.plot([], [], label='Vm%s'%(suffix))
+        self._plot_dict['vm'].append(self._vm_plot)
+        self._command_plot, = self._vm_axes.plot([], [], label='command%s'%(suffix))
+        self._plot_dict['command'].append(self._command_plot)
+        # Channel conductances go to the same subplot
+        self._gna_plot, = self._g_axes.plot([], [], label='Na%s'%(suffix))
+        self._plot_dict['gna'].append(self._gna_plot)
+        self._gk_plot, = self._g_axes.plot([], [], label='K%s'%(suffix))
+        self._plot_dict['gk'].append(self._gk_plot)
+        # Injection current for Vclamp/Iclamp go to the same subplot
+        self._iclamp_plot, = self._im_axes.plot([], [], label='Iclamp%s'%(suffix))
+        self._vclamp_plot, = self._im_axes.plot([], [], label='Vclamp%s'%(suffix))
+        self._plot_dict['iclamp'].append(self._iclamp_plot)
+        self._plot_dict['vclamp'].append(self._vclamp_plot)
+        # Channel currents go to the same subplot
+        self._ina_plot, = self._i_axes.plot([], [], label='Na%s'%(suffix))
+        self._plot_dict['ina'].append(self._ina_plot)
+        self._ik_plot, = self._i_axes.plot([], [], label='K%s'%(suffix))
+        self._plot_dict['ik'].append(self._ik_plot)
+        # self._i_axes.legend()
+        # State plots
+        self._state_plot, = self._statePlotAxes.plot([], [], label='state%s'%(suffix))
+        self._plot_dict['state'].append(self._state_plot)
+        self._m_plot, = self._activationParamAxes.plot([],[], label='m%s'%(suffix))
+        self._h_plot, = self._activationParamAxes.plot([], [], label='h%s'%(suffix))
+        self._n_plot, = self._activationParamAxes.plot([], [], label='n%s'%(suffix))
+        self._plot_dict['m'].append(self._m_plot)
+        self._plot_dict['h'].append(self._h_plot)
+        self._plot_dict['n'].append(self._n_plot)
+        if self._showLegendAction.isChecked():
+            for axis in (self._plotFigure.axes + self._statePlotFigure.axes):            
+                axis.legend()
+
+    def _updateAllPlots(self):
+        self._updatePlots()
+        self._updateStatePlot()
+
+    def _updatePlots(self):
+        if len(self.squid_setup.vm_table.vector) <= 0:
+            return        
+        vm = numpy.asarray(self.squid_setup.vm_table.vector)
+        cmd = numpy.asarray(self.squid_setup.cmd_table.vector)
+        ik = numpy.asarray(self.squid_setup.ik_table.vector)
+        ina = numpy.asarray(self.squid_setup.ina_table.vector)
+        iclamp = numpy.asarray(self.squid_setup.iclamp_table.vector)
+        vclamp = numpy.asarray(self.squid_setup.vclamp_table.vector)
+        gk = numpy.asarray(self.squid_setup.gk_table.vector)
+        gna = numpy.asarray(self.squid_setup.gna_table.vector)
+        time_series = numpy.linspace(0, self._plotdt * len(vm), len(vm))        
+        self._vm_plot.set_data(time_series, vm)
+        time_series = numpy.linspace(0, self._plotdt * len(cmd), len(cmd))        
+        self._command_plot.set_data(time_series, cmd)
+        time_series = numpy.linspace(0, self._plotdt * len(ik), len(ik))
+        self._ik_plot.set_data(time_series, ik)
+        time_series = numpy.linspace(0, self._plotdt * len(ina), len(ina))
+        self._ina_plot.set_data(time_series, ina)
+        time_series = numpy.linspace(0, self._plotdt * len(iclamp), len(iclamp))
+        self._iclamp_plot.set_data(time_series, iclamp)
+        time_series = numpy.linspace(0, self._plotdt * len(vclamp), len(vclamp))
+        self._vclamp_plot.set_data(time_series, vclamp)
+        time_series = numpy.linspace(0, self._plotdt * len(gk), len(gk))
+        self._gk_plot.set_data(time_series, gk)
+        time_series = numpy.linspace(0, self._plotdt * len(gna), len(gna))
+        self._gna_plot.set_data(time_series, gna)
+        # self._vm_axes.margins(y=0.1)
+        # self._g_axes.margin(y=0.1)
+        # self._im_axes.margins(y=0.1)
+        # self._i_axes.margins(y=0.1)
+        if self._autoscaleAction.isChecked():
+            for axis in self._plotFigure.axes:
+                axis.relim()
+                axis.margins(0.1, 0.1)
+                axis.autoscale_view(tight=True)
+        else:
+            self._vm_axes.set_ylim(-20.0, 120.0)
+            self._g_axes.set_ylim(0.0, 0.5)
+            self._im_axes.set_ylim(-0.5, 0.5)
+            self._i_axes.set_ylim(-10, 10)
+        self._vm_axes.set_xlim(0.0, time_series[-1])
+        self._g_axes.set_xlim(0.0, time_series[-1])
+        self._im_axes.set_xlim(0.0, time_series[-1])
+        self._i_axes.set_xlim(0.0, time_series[-1])
+        self._plotCanvas.draw()
+
+    def _updateStatePlot(self):
+        if len(self.squid_setup.vm_table.vector) <= 0:
+            return
+        sx = str(self._stateplot_xvar_combo.currentText())
+        sy = str(self._stateplot_yvar_combo.currentText())
+        xdata = self.__get_stateplot_data(sx)
+        ydata = self.__get_stateplot_data(sy)
+        minlen = min(len(xdata), len(ydata))
+        self._state_plot.set_data(xdata[:minlen], ydata[:minlen])
+        self._statePlotAxes.set_xlabel(sx)
+        self._statePlotAxes.set_ylabel(sy)
+        if sx == 'V':
+            self._statePlotAxes.set_xlim(-20, 120)
+        else:
+            self._statePlotAxes.set_xlim(0, 1)
+        if sy == 'V':
+            self._statePlotAxes.set_ylim(-20, 120)
+        else:
+            self._statePlotAxes.set_ylim(0, 1)
+        self._activationParamAxes.set_xlim(0, self._runtime)
+        m = self.__get_stateplot_data('m')
+        n = self.__get_stateplot_data('n')
+        h = self.__get_stateplot_data('h')
+        time_series = numpy.linspace(0, self._plotdt*len(m), len(m))
+        self._m_plot.set_data(time_series, m)
+        time_series = numpy.linspace(0, self._plotdt*len(h), len(h))
+        self._h_plot.set_data(time_series, h)
+        time_series = numpy.linspace(0, self._plotdt*len(n), len(n))
+        self._n_plot.set_data(time_series, n)
+        if self._autoscaleAction.isChecked():
+            for axis in self._statePlotFigure.axes:
+                axis.relim()
+                axis.set_autoscale_on(True)
+                axis.autoscale_view(True)
+        self._statePlotCanvas.draw()
+
+    def _runSlot(self):
+        if moose.isRunning():
+            print('Stopping simulation in progress ...')
+            moose.stop()
+        self._runtime = self.getFloatInput(self._runTimeEdit, self._runTimeLabel.text())
+        self._overlayPlots(self._overlayAction.isChecked())
+        self._simdt = self.getFloatInput(self._simTimeStepEdit, self._simTimeStepLabel.text())
+        clampMode = None
+        singlePulse = True
+        if self._electronicsTab.currentWidget() == self._vClampCtrlBox:
+            clampMode = 'vclamp'
+            baseLevel = self.getFloatInput(self._holdingVEdit, self._holdingVLabel.text())
+            firstDelay = self.getFloatInput(self._holdingTimeEdit, self._holdingTimeLabel.text())
+            firstWidth = self.getFloatInput(self._prePulseTimeEdit, self._prePulseTimeLabel.text())
+            firstLevel = self.getFloatInput(self._prePulseVEdit, self._prePulseVLabel.text())
+            secondDelay = firstWidth
+            secondWidth = self.getFloatInput(self._clampTimeEdit, self._clampTimeLabel.text())
+            secondLevel = self.getFloatInput(self._clampVEdit, self._clampVLabel.text())
+            if not self._autoscaleAction.isChecked():
+                self._im_axes.set_ylim(-10.0, 10.0)
+        else:
+            clampMode = 'iclamp'
+            baseLevel = self.getFloatInput(self._baseCurrentEdit, self._baseCurrentLabel.text())
+            firstDelay = self.getFloatInput(self._firstDelayEdit, self._firstDelayLabel.text())
+            firstWidth = self.getFloatInput(self._firstPulseWidthEdit, self._firstPulseWidthLabel.text())
+            firstLevel = self.getFloatInput(self._firstPulseEdit, self._firstPulseLabel.text())
+            secondDelay = self.getFloatInput(self._secondDelayEdit, self._secondDelayLabel.text())
+            secondLevel = self.getFloatInput(self._secondPulseEdit, self._secondPulseLabel.text())
+            secondWidth = self.getFloatInput(self._secondPulseWidthEdit, self._secondPulseWidthLabel.text())
+            singlePulse = (self._pulseMode.currentIndex() == 0)
+            if not self._autoscaleAction.isChecked():
+                self._im_axes.set_ylim(-0.4, 0.4)
+        self.squid_setup.clamp_ckt.configure_pulses(baseLevel=baseLevel,
+                                                    firstDelay=firstDelay,
+                                                    firstWidth=firstWidth,
+                                                    firstLevel=firstLevel,
+                                                    secondDelay=secondDelay,
+                                                    secondWidth=secondWidth,
+                                                    secondLevel=secondLevel,
+                                                    singlePulse=singlePulse)
+        if self._kConductanceToggle.isChecked():
+            self.squid_setup.squid_axon.specific_gK = 0.0
+        else:
+            self.squid_setup.squid_axon.specific_gK = SquidAxon.defaults['specific_gK']
+        if self._naConductanceToggle.isChecked():
+            self.squid_setup.squid_axon.specific_gNa = 0.0
+        else:
+            self.squid_setup.squid_axon.specific_gNa = SquidAxon.defaults['specific_gNa']
+        self.squid_setup.squid_axon.celsius = self.getFloatInput(self._temperatureEdit, self._temperatureLabel.text())
+        self.squid_setup.squid_axon.K_out = self.getFloatInput(self._kOutEdit, self._kOutLabel.text())
+        self.squid_setup.squid_axon.Na_out = self.getFloatInput(self._naOutEdit, self._naOutLabel.text())
+        self.squid_setup.squid_axon.K_in = self.getFloatInput(self._kInEdit, self._kInLabel.text())
+        self.squid_setup.squid_axon.Na_in = self.getFloatInput(self._naInEdit, self._naInLabel.text())
+        self.squid_setup.squid_axon.updateEk()
+        self.squid_setup.schedule(self._simdt, self._plotdt, clampMode)
+        # The following line is for use with Qthread
+        self.squid_setup.run(self._runtime)
+        self._updateAllPlots()
+
+    def _toggleDocking(self, on):
+        self._channelControlDock.setFloating(on)
+        self._electronicsDock.setFloating(on)
+        self._runControlDock.setFloating(on)
+        
+    def _restoreDocks(self):
+        self._channelControlDock.setVisible(True)
+        self._electronicsDock.setVisible(True)
+        self._runControlDock.setVisible(True)
+
+    def _initActions(self):
+        self._runAction = QAction(self.tr('Run'), self)
+        self._runAction.setShortcut(self.tr('F5'))
+        self._runAction.setToolTip('Run simulation (F5)')
+        self._runAction.triggered.connect( self._runSlot)
+        self._resetToDefaultsAction = QAction(self.tr('Restore defaults'), self)
+        self._resetToDefaultsAction.setToolTip('Reset all settings to their default values')
+        self._resetToDefaultsAction.triggered.connect( self._useDefaults)
+        self._showLegendAction = QAction(self.tr('Display legend'), self)
+        self._showLegendAction.setCheckable(True)
+        self._showLegendAction.toggled.connect(self._showLegend)
+        self._showStatePlotAction = QAction(self.tr('State plot'), self)
+        self._showStatePlotAction.setCheckable(True)
+        self._showStatePlotAction.setChecked(False)
+        self._showStatePlotAction.toggled.connect(self._statePlotWidget.setVisible)
+        self._autoscaleAction  = QAction(self.tr('Auto-scale plots'), self)
+        self._autoscaleAction.setCheckable(True)
+        self._autoscaleAction.setChecked(False)
+        self._autoscaleAction.toggled.connect(self._autoscale)
+        self._overlayAction = QAction('Overlay plots', self)
+        self._overlayAction.setCheckable(True)
+        self._overlayAction.setChecked(False) 
+        self._dockAction = QAction('Undock all', self)
+        self._dockAction.setCheckable(True)
+        self._dockAction.setChecked(False)
+        #  self._dockAction.toggle.connect( self._toggleDocking)
+        self._restoreDocksAction = QAction('Show all', self)
+        self._restoreDocksAction.triggered.connect( self._restoreDocks)
+        self._quitAction = QAction(self.tr('&Quit'), self)
+        self._quitAction.setShortcut(self.tr('Ctrl+Q'))
+        self._quitAction.triggered.connect(qApp.closeAllWindows)
+
+        
+
+    def _createRunToolBar(self):
+        self._simToolBar = self.addToolBar(self.tr('Simulation control'))
+        self._simToolBar.addAction(self._quitAction)
+        self._simToolBar.addAction(self._runAction)
+        self._simToolBar.addAction(self._resetToDefaultsAction)
+        self._simToolBar.addAction(self._dockAction)
+        self._simToolBar.addAction(self._restoreDocksAction)
+
+    def _createPlotToolBar(self):
+        self._plotToolBar = self.addToolBar(self.tr('Plotting control'))
+        self._plotToolBar.addAction(self._showLegendAction)
+        self._plotToolBar.addAction(self._autoscaleAction)
+        self._plotToolBar.addAction(self._overlayAction)
+        self._plotToolBar.addAction(self._showStatePlotAction)
+        self._plotToolBar.addAction(self._helpAction)
+        self._plotToolBar.addAction(self._helpBiophysicsAction)
+
+    def _showLegend(self, on):
+        if on:
+            for axis in (self._plotFigure.axes + self._statePlotFigure.axes):            
+                axis.legend().set_visible(True)
+        else:
+            for axis in (self._plotFigure.axes + self._statePlotFigure.axes):            
+                axis.legend().set_visible(False)
+        self._plotCanvas.draw()
+        self._statePlotCanvas.draw()
+
+    def _autoscale(self, on):
+        if on:
+            for axis in (self._plotFigure.axes + self._statePlotFigure.axes):            
+                axis.relim()
+                axis.set_autoscale_on(True)
+                axis.autoscale_view(True)
+        else:
+            for axis in self._plotFigure.axes:
+                axis.set_autoscale_on(False)            
+            self._vm_axes.set_ylim(-20.0, 120.0)
+            self._g_axes.set_ylim(0.0, 0.5)
+            self._im_axes.set_ylim(-0.5, 0.5)
+            self._i_axes.set_ylim(-10, 10)
+        self._plotCanvas.draw()
+        self._statePlotCanvas.draw()
+        
+    def _useDefaults(self):
+        self._runTimeEdit.setText('%g' % (self.defaults['runtime']))
+        self._simTimeStepEdit.setText('%g' % (self.defaults['simdt']))
+        self._overlayAction.setChecked(False)
+        self._naConductanceToggle.setChecked(False)
+        self._kConductanceToggle.setChecked(False)
+        self._kOutEdit.setText('%g' % (SquidGui.defaults['K_out']))
+        self._naOutEdit.setText('%g' % (SquidGui.defaults['Na_out']))
+        self._kInEdit.setText('%g' % (SquidGui.defaults['K_in']))
+        self._naInEdit.setText('%g' % (SquidGui.defaults['Na_in']))
+        self._temperatureEdit.setText('%g' % (SquidGui.defaults['temperature'] - CELSIUS_TO_KELVIN))
+        self._holdingVEdit.setText('%g' % (SquidGui.defaults['vclamp.holdingV']))
+        self._holdingTimeEdit.setText('%g' % (SquidGui.defaults['vclamp.holdingT']))
+        self._prePulseVEdit.setText('%g' % (SquidGui.defaults['vclamp.prepulseV']))
+        self._prePulseTimeEdit.setText('%g' % (SquidGui.defaults['vclamp.prepulseT']))
+        self._clampVEdit.setText('%g' % (SquidGui.defaults['vclamp.clampV']))
+        self._clampTimeEdit.setText('%g' % (SquidGui.defaults['vclamp.clampT']))
+        self._baseCurrentEdit.setText('%g' % (SquidGui.defaults['iclamp.baseI']))
+        self._firstPulseEdit.setText('%g' % (SquidGui.defaults['iclamp.firstI']))
+        self._firstDelayEdit.setText('%g' % (SquidGui.defaults['iclamp.firstD']))
+        self._firstPulseWidthEdit.setText('%g' % (SquidGui.defaults['iclamp.firstT']))
+        self._secondPulseEdit.setText('%g' % (SquidGui.defaults['iclamp.secondI']))
+        self._secondDelayEdit.setText('%g' % (SquidGui.defaults['iclamp.secondD']))
+        self._secondPulseWidthEdit.setText('%g' % (SquidGui.defaults['iclamp.secondT']))
+        self._pulseMode.setCurrentIndex(0)
+
+    def _onScroll(self, event):
+        if event.inaxes is None:
+            return  
+        axes = event.inaxes
+        zoom = 0.0
+        if event.button == 'up':
+            zoom = -1.0
+        elif event.button == 'down':
+            zoom = 1.0
+        if zoom != 0.0:
+            self._plotNavigator.push_current()
+            axes.get_xaxis().zoom(zoom)
+            axes.get_yaxis().zoom(zoom)        
+        self._plotCanvas.draw()
+
+    def closeEvent(self, event):
+        qApp.closeAllWindows()
+
+    def _showBioPhysicsHelp(self):
+        self._createHelpMessage()
+        self._helpMessageText.setText('<html><p>%s</p><p>%s</p><p>%s</p><p>%s</p><p>%s</p></html>' % 
+                                      (tooltip_Nernst, 
+                                       tooltip_Erest,
+                                       tooltip_KChan,
+                                       tooltip_NaChan,
+                                       tooltip_Im))
+        self._helpWindow.setVisible(True)
+
+    def _showRunningHelp(self):
+        self._createHelpMessage()
+        self._helpMessageText.setSource(QtCore.QUrl(self._helpBaseURL))
+        self._helpWindow.setVisible(True)
+
+    def _createHelpMessage(self):
+        if hasattr(self, '_helpWindow'):
+            return
+        self._helpWindow = QWidget()
+        self._helpWindow.setWindowFlags(QtCore.Qt.Window)
+        layout = QVBoxLayout()
+        self._helpWindow.setLayout(layout)
+        self._helpMessageArea = QScrollArea()
+        self._helpMessageText = QTextBrowser()
+        self._helpMessageText.setOpenExternalLinks(True)
+        self._helpMessageArea.setWidget(self._helpMessageText)
+        layout.addWidget(self._helpMessageText)
+        self._squidGuiPath = os.path.dirname(os.path.abspath(__file__))
+        self._helpBaseURL = os.path.join(self._squidGuiPath,'help.html')
+        self._helpMessageText.setSource(QtCore.QUrl(self._helpBaseURL))
+        self._helpMessageText.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
+        self._helpMessageArea.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
+        self._helpMessageText.setMinimumSize(800, 600)
+        self._closeHelpAction = QAction('Close', self)
+        self._closeHelpAction.triggered.connect(self._helpWindow.close)        
+        # Setting the close event so that the ``Help`` button is
+        # unchecked when the help window is closed
+        self._helpWindow.closeEvent = lambda event: self._helpAction.setChecked(False)
+        self._helpTOCAction = QAction('Help running demo', self)
+        self._helpTOCAction.triggered.connect( self._jumpToHelpTOC)                
+        # This panel is for putting two buttons using horizontal
+        # layout
+        panel = QFrame()
+        panel.setFrameStyle(QFrame.StyledPanel + QFrame.Raised)
+        layout.addWidget(panel)
+        layout = QHBoxLayout()
+        panel.setLayout(layout)
+        self._helpAction = QAction('Help running', self)
+        self._helpAction.triggered.connect(self._showRunningHelp)
+        self._helpBiophysicsAction = QAction('Help biophysics', self)
+        self._helpBiophysicsAction.triggered.connect(self._showBioPhysicsHelp)
+        self._helpTOCButton = QToolButton()
+        self._helpTOCButton.setDefaultAction(self._helpTOCAction)
+        self._helpBiophysicsButton = QToolButton()
+        self._helpBiophysicsButton.setDefaultAction(self._helpBiophysicsAction)
+        layout.addWidget(self._helpTOCButton)
+        layout.addWidget(self._helpBiophysicsButton)
+        self._closeHelpButton = QToolButton()
+        self._closeHelpButton.setDefaultAction(self._closeHelpAction)
+        layout.addWidget(self._closeHelpButton)
+        
+    def _jumpToHelpTOC(self):
+        self._helpMessageText.setSource(QtCore.QUrl(self._helpBaseURL))
+
+if __name__ == '__main__':
+    app = QApplication(sys.argv)
+    #  app.connect(app, QtCore.SIGNAL('lastWindowClosed()'), app, QtCore.SLOT('quit()'))
+    app.quitOnLastWindowClosed( )
+    qApp = app
+    squid_gui = SquidGui()
+    squid_gui.show()
+    print(squid_gui.size())
+    sys.exit(app.exec_())
+
+# 
+# squidgui.py ends here
diff --git a/moose-examples/squid/test_squid.py b/moose-examples/squid/test_squid.py
index 005cb162..5bbef8bc 100644
--- a/moose-examples/squid/test_squid.py
+++ b/moose-examples/squid/test_squid.py
@@ -30,6 +30,7 @@
 
 import unittest
 import pylab
+import numpy
 from squid import SquidModel
 
 class SquidAxonTest(unittest.TestCase):
@@ -112,6 +113,5 @@ class SquidAxonTest(unittest.TestCase):
         self.assertLessEqual(difference, numpy.mean(beta_m)*1e-6)
 
 
-
 # 
 # test_squid.py ends here
diff --git a/moose-examples/tutorials/Electrophys/CableInjectEquivCkt.png b/moose-examples/tutorials/Electrophys/CableInjectEquivCkt.png
new file mode 100644
index 0000000000000000000000000000000000000000..d1938db8fdf25b373a13fce83b704d5edd031040
GIT binary patch
literal 31378
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

literal 0
HcmV?d00001

diff --git a/moose-examples/tutorials/Electrophys/README.txt b/moose-examples/tutorials/Electrophys/README.txt
new file mode 100644
index 00000000..585fd34e
--- /dev/null
+++ b/moose-examples/tutorials/Electrophys/README.txt
@@ -0,0 +1,80 @@
+This is a list of files in the Electrophys tutorials directory
+
+ephys1_cable.py:
+
+This is a model of a simple uniform passive cable. It has two plots: one
+of membrane potential Vm as a function of time, sampled at four locations 
+along the cable, and the other of Vm as a function of position, sampled at
+5 times (intervals of 5 ms) during the simulation.
+The user can use the sliders to scale the following parameters up and down:
+RM
+RA
+CM
+length
+diameter
+
+In addition, the user can toggle between a long (steady-state) current
+injection stimulus, and a brief pulse of 1 ms.
+
+Finally, when the user hits "Quit" the time-series of the soma compartment
+is printed out.
+
+Things to do:
+1. Vary diameter, length, RM, CM, RA. Check that the decay behaves as per
+	cable theory. Get an intuition for these.
+2. Check that lambda (length constant) is according to equations. Check
+	how much decay there is for different L (electrotonic length).
+2a. Note that if the cable is shorter than L, the signal doesn't decay so
+	well. Why?
+2b. Convince yourself that you'll never see a passive signal along a long 
+	axon.
+3. Examine propagation of the depolarization for a brief current pulse.
+	Look for the three signatures of propagation along a dendrite.
+4. Run a simulation of the long stimulus. When you hit Quit, the program will
+	dump the soma potential charging time-course into a file. Check that 
+	the tau (time-constant) of the soma is according to equations when the 
+	L is very small, but deviates when it is longer. Use Rall's expression 
+	for L as a function of the time-courses of soma depolarization.
+ 
+
+
+ephys2_Rall_law.py:
+
+This explores the implication of Rall's Law and cable branching.
+This is a model of a branched cell, compared with the model of a uniform
+cylindrical cell. The sliders vary the parameters of the branches. Two 
+time-points are displayed; 10 ms and 50 ms.
+
+Things to do:
+1. Vary all the passive parameters of branches, see how they affect the
+	propagation past the branch point.
+2. Match up the branched cell (blue plot/dots) to the cylinder (red line).
+	See if the resultant parameters obey Rall's Law.
+
+Todo: - Stimuli in any end or both dend ends.
+
+Neuronal summation
+        - Synaptic input at Y tips and branch point, both I and E.
+        - Vary weights
+        - Vary time since start for each.
+        - Vary taus of I.
+        - Have spiking soma, to set up thresholding as an option.
+
+Channel mixer:
+        - Modulate the conductance of battery of channels
+        - Modulate Ca_conc tau
+        - Plot Ca and Vm
+        - Set different stim pulse amplitude and duration.
+
+NMDA receptor and associativity:
+        - Plot Vm and Ca
+        - Give glu and NMDA input different time and different ampl
+
+AP propagation:
+        - Vary dia
+        - Vary RM, CM, RA
+        - Vary channel densities
+
+Squid demo:
+        - Already have it.
+
diff --git a/moose-examples/tutorials/Electrophys/RallsLaw.png b/moose-examples/tutorials/Electrophys/RallsLaw.png
new file mode 100644
index 0000000000000000000000000000000000000000..21fae9010f07863d14dd3a3cf25720f8dfe6846d
GIT binary patch
literal 41208
zcmdRW_aoK++dmCOBwL8G$x8OjE+H!<dnJy&vZd@@iR_V(oxQU{Lb8rMv-jS<*WvxS
z@Av(^zyHAZ{8BjQyq>S;xUR?bcs#CGfTDs74i*^}8X6kTqlc2pXlNG^XlNHGu42G%
z0{K~K;h#%(;*V6X!prTdkw5%=(_Tu$Ud779-bvrq8103nm4z{@ouRF<v8A1<mHq0)
zS`jp~+h~s@#Z+I#EseNq#Qq%-J>fO$SIv@K&HW<rJUY_Pl4!07Uyzk`<g*!R_Q9<l
zs_TxscWfMK%;U$$rDe61eJ-b)Q*XImq0$%09yZe4vb@$?u9)tVaTizZ@uzquM>3OA
z>BZ^YD`On>4u3H>;&vDL_^y}dPFIM$#d5Pvm^}<8hu1~CvzJf2owzpI`Tqk98>A&s
zFTyX#{D1z;#Dh5dm85<k4*A*dl%fs(|9V^I=0A6+l)bpJ;yYsL*KQ(VWyOxBr>BRe
zmPK^)=FQ*p_IGl_#px^&2n0)y)D6^)HeJZ-4NOU)Mtk7tDVnX8)jS*BZenC?e7S-P
zOC=8f(b+`Na(=>w&(AF^Y<zvD!W@a{GoX+``lDXnEtaJ;OiZnY4fO9@e|L9Z{3J*G
z`6nZV&D#*vpBepW@dMP&|8SAv#BxtwJ)2u4j^dIM@f@|vTl#H3e|irft{Xfh%#Hr%
zT9=NGj}^0e=jP_D5BUNlFI4MLeg4WgY$HpH8m<!Bz_O!hv8IuUi3_67Ydt9<I5_yW
zs&s_c`MN22**iGgxqqL4h=?eEXjx(QvoaGGS%``qj4r9m^hl@KeRpK`DKni9)jvz_
zVNy7tsHqwFG)pbHwpQ0#gqN4Z-QAs$o!u$sB%^=vPQ=3_ozA*9S0X-s#K=**Yf8aX
zRiIBp4X=&VnHdvWI=bZY@@Lix^zZdoN2`&QPOFj^jMUVKKgiPA+Sx@UCQ^mR;1dw&
z!)26|UKbT{6%`j>o)($*M4ZpyQBrL!m2EjiT3TBE0K$9o@87?Cj!UHQ*~_zBWbzN*
zNE5Saa;=X^NJua;GJgO1H0$@!5P81qJJ0;{VZ@+Uj)VpVV!@oGR8~H>7P))(ny|3&
zZ&NO|bV1oPWm<ZAjBM!wbHTp;OjYJwt80e;T=`38YHGvZL5@sStZE(H!U2kn9vP?h
zq&mIvgA$G(A%y{`6?8Ky)=XB*>KYtmcB#qFzabEBX%Me@ySTV`!t-R-lY@)vlAaq?
zDb>;V6-E}8IMOb1GBR;x<#)~IboBJ~rd-s5f`VQ|@7e!3Yx_yb$>`kN+$oDa$|@?!
z-Sd+DnfuS3oOpZ8is!iG#>dbZLc6NV%J{<iS(un!E2O_sW!^T=;d1|H%vEsn*CJ)<
z25&#2#s3f)nOspJaJ%5>{Q!bzX}Fv~GpBFLFin|BKu|CuBI5Pu&z}R7$}){OZw5;n
zDw4@>;Pjs#`SJ<>1}7rsck%Jd_f#8o>GM8q`oeipQo>tutQ>Mcz-~wM)f1BQpw^k1
zWSIM*aweg4Dqehi{6l$p9MfBHqRjhqn+A)`r3h}3e9ry8k+Q6zba0oJMf<OPF03ew
z#G;|EtLsjMl@{OI@C;Sv#-=8IcWhkTL$~;^UzyX*qvgJ!sV@F!8+=*oxgGi8!#J|Q
zkdcWA^A)RR4)M#EFX0^Ah>I28#cv5J*3c=sbxm1aPsczYx29P6chNH3F^QISUE?er
z9i2BGcd@4Mda*zWb4F$+=67{Mw}yrW_&S-4wrJvicKdrcJFsH|cpheEW^%-~bC89g
z<Ic=Mz|dlok&^N;{oWecPcl)tkj~+`&h2gY*lx9PsXR)~&9Zc;!1MGZ;5L407vmlo
zf`?r8@#C(Mk&s`%<lsA_%txt1q*E~+FuQ;Fo}K)w(Wa`*%*>Zm(CP3o;rP3_xP(VW
z68#pSFrS&WEuV`i4`P4rjp$9)_-1mkgMamIN`ExmCd;$Jx_J$VMPI*urI+qA;{22p
zF+Vrw1;c}1qDeOS4sLI6bC6;uvl$K|^L>zWa~XOHmRedA($do6+M0^k*RNyM>>L~%
zC`J(}Nz2G|_4G_{R5cl34w?@S4lb;Z+34sbBvDdRrzn0KKqzLahPVBlTV5uL>uhhA
z($%H<+14gO#?1MclVt2yH32WejdcB66J=g8$ENhJ$8t^rYR{i9_Pk|^lr445l{&ck
z{OMDo5{n_?1x}N<IOIx~?thXCmrX+!y;R9~jE+Vj^vZg&mI&+eOlKndt6x7t$S*f*
zEmKKA@-fZH$$9wrF~P0Z5v@k1FJIP;R=bX1IPSgSO{V659$Y3~(~-XT<?hco>4|K$
zyD*dVBD)_bZ)V~QjgQ~n*w~<U92qo%LqQ$hWFV%aLkYhU*A9H&TDwGu<uhk!SvG-D
zSI|u9%A&^&aWi0kb+s8btCFfJ?cnW5I5&BDxIR8U=y^>;iV>~mf2z2hM#Z)EEoSo|
zn%&ga)+SJS(DdgHL(u0h7Dh&wV9p;tdK3^%`0xoFWT_;Gy7`B9xcK<yw)X#|J(i*(
zp`r?dqnK`p@kU>By$aGs&9|ZD-)6-vzkU%~gmZFo>hZ+FajzFpZ6s;!C(&Q2@=<7p
zJyc-U`!%50Y~|87{Xz{EQ!}#|4bF(DD8GXPm%1^c(Tc4<kEPNdRJhRa<D=qTEuY(7
ze)p{I=|R7?h+}&Ux3?jC_13#Fb2z3k*;!d_#u@&q%s5$!5pk^2rODJae6v+~x3!gK
z>=CA>S7Ujtq&+-pnrE-1=#$^N<s+LWE-j70V=>6JE?v}WR1Yf|{_dSO?7f>~GRcZb
zrKKds#>NR$6ey?=p)03Ti}AqzI7Y(7rD8lj*ZP^CjHF~&GoJdYndD2`jE70iSVWI%
z)39OJXmC*TsBGeQ7r?$rHw+UwV1zSp9+f6G%1<njuw50kw3hCb+cbyXf^EoWGuc?Q
z(mgsFy0hc>IX&Ig!<rO@R6OqO`>pgag&8!~%Uq}68}E;Spd1q$8}Z=-ZG}Qx0mA@n
zoICGZFKGIuD@MFc%L*@S@^3W1!0TYu8iV6qJ)p`=^sTV43sQ5n4*P)sg{a4Ho`b5o
zx@&b&gC56T5%%YA-|$TeZyFjJ;tAu}a`GVVeT6h)FZg=i?QK15HqGbHla({+7hsUE
zJl;(P>kDKCHoNa<A3tXy?&<HpHlzB4q08FZ`uEh)(#0#+%SJ}^H+JQIP0#KtPpz$S
z#KgqV>pYgR7_A8n&9nMObXV=w@o*~{8QGU@AvlJa2Zx7uqS}-+HJK|!va6~nU_N4z
z?^(i!eFEdyBgJ&Gn|e#t6z;;lF>oz(aBz_4Duk?Ne|W(&G~dC=DJV1>P9rupwjKh3
z4L3nbO6sMYxwU@)DGELD4;f<Crvi;yH#juZV0UFCCFoH)Jz-yO?;U>rfmv4w#}cVs
zS3RO37za4LBE-7vxH`J*IGC6^3cFeCbM}<xP>F?vw)U+O%aH}U_><o~J+#q*eEW;4
z%#pCW{lmhXT;pHAMo;e?$<d8<Tg{ZCC-C+2E3i)XOn-d?PiYBI2!vxX35hp)@nmR#
zti<yAE8{QBv5$<5z>KE2R-#WOQ)do1?HR|%loFea`qysNyj77n^)M_+Nx4v7ULM|R
zL}0$pV>OChtQk^L!c)tGFlhZPn}+XFJvy&pYs<OiBCHU{hvz6}UiSl!Cy+FBzhe~P
zVaoXl_VVPWDH6a-foT_YnB7--dIBB<a(w4rYHBJY8{1CVX)|nj#ivhwJddWRM0y1X
zcw%v$K7C5rA952LBX4H2_T*quA<@;$$j{GD`(({{?<yXieE;;ezCkjzOEslQA^&)L
zOuNY&%^b&aywX|;DL1+j-skf2A>D?6c?w>1QrbH@9&od&ELml@9@fh{tXA(HERRM2
z%$CB|oe>ml`D>dvIq8mB!|_SZvR|vWx7S&FHT0ICcSZUj{8Kgh@Q)tHD})<^Zd>fO
z`AQ6@Z`cjIh&%|1fq{Yfj?0=|T}k!z;#=F>^5%i@d4q$4;U7QJ3$%-d!`Zhk=8Z-6
zC^aAOc-{zFP-i5xe9<R4wDn_NuYoxA+qZA@GgmveXh`Mg-_HqhhDxQu?%{LZ_-tAT
zP|>YM*VvdYluA^@X8HJVH%Me<;6);luw{XUBsq1O^1S^Bta=_vqryo-z^5bO^&P+G
z+S>6d!nt1%RcrOv*z)cb-|6`EYwMNn6Zuc<i?e`*OSrkXZnLuDK;-wfgZv9vkzG?$
z)0>!CSyA!EH$^;Mxslj*%hI44-xK?pUpMRSS>aQp(g_(=AoG<ZZ;-nSz~EF2IXzF@
z5F-^tAt50OVfRU~MJ#GG)Ybh42Q|~3T-EY)LLh+D8EVVNyRDSZUTUV;EM(B-<>$Y-
zyu5s8Uu;@KkheTxYs(&Rex2b+$PamoTw->erJWjsc4W`$C*&f;G_Ge*IZWH~11Qro
zdPp6S1jiB}rPwv1N3yb5&KdsfsEn-<y{?^Z=y&}V)|_w?8IRSM=k&C+mr~;V>wH7%
z6Eq5Yk;pmQ_@3RGUE#Wd%vga+6)i0mm!m=RyzK)r1DsIUH2Zrn?7X~X_S~8dfX0cr
z_Z^O7(!YnhAMWtG>%d+8ZHp4THB?}D1yZ^D*EjzD25$_z=K*wdF&&07xsiqZV4CN+
zQBhf`ZP|zu>=!tVxMy%OX?{Vo*}nbVFB}KV>B|t%nBN&3r_<lK@SR9qYhq*FAY?f4
z^yo$2N}3|07LRv=Hy4Fg&L_Jljhjn2w?^FK6Y%e(Zx|mB0=Br#WzrN#l%jhYYgIF^
zatjjo@vwyeYox3`7g^W9KtNAVk5?bwN;35*pSftrZiVNpJ<IQI>DgbOX!z($EG@sz
zTgKgDh4n)ckn6X#wytLeZ1LzdP=$0eB)U=asXco(zwTV8admk-52LGp+uT4t+ECJJ
z!Mss;z~8^6uKP<jKs!`DAS)|-LFX~;+rU>Ftyg5$WV?yuME)MR9$gXL6ML}gy52-`
zE!26Fm(1`upgxXwwQ4U&)WAGlP}Fs_%K3gxY3UJBr|Z_7QhKK_#3`~rDXPp2(pzdd
znt$y(3K+=olrkVd2G%g~adP6XxvD>X%0F`d<EfrQsR#=<HxZ-<>C~>gu1y1KR#nMg
z&kkR16$#%S%>Fw&d&RBtqIw(surbbFg_H^xs%q}$;hyOqIVg^Zz!Q7eCeJ$p)yvpH
zU+JaJ{VA$bz6PuSf9lS)wfz435-Fc5xApM@E|G;`p!QdQdsw4lM5eE+PW_4B<9ow2
z!<q~<G#8~)?=d>~vnE0Tn-X^G)~zOX&;7OsQG`3l{HBbDf!idm%?R7LTG7R-xs)Ii
ztyTNk7l{H6W<PeXm$WW+3CSN44i#G3hCg<5tJ2dnRZ{B0zDr9TDAYX=N*{wn@BlWC
zT5N!VtE<1?4{%htZ(y9=sCvDK>LoOVL^9v~09&|SuTBL|7Cv2N<;mUlf)TvOKX^#7
zA%H8;SiE`j27+nme3$VR9t7b|V~UpO!CdMM)yeqzj!ws7sRv~-0(7PeAAV#ecpSV;
z?`-mZVp+M&Q@2?L6W{a>u&V!|`}mW80HHe$lq(Px@|{+7P^DYZbt`cxwM<H!Ma2mA
z+C7TZnn7=cW0PQt<M-ok9O>^BKE}nd2>dkRAcb(xc@Kw=j?Slj@U-FV4E{O_Vy_|f
zmaQVVyIDBqJbUXbPmxnl5FY&=DYHo(w=w9ZE=LU`5NZ;!cb3_6{|yu&9cO1_ql#e`
z7VKB73F1<mo1T<-$<*-&?R?*?cx#R(?b7Y)5)_zC7W;BUd~%#+lS3U5NXDfAIx;eB
zj4md}?|VIhk+MEtzR=q{Ir-6+i6dO}irPDOjE`fGf<^{o>IE+&hTn(yr;MDVS_9jW
z7@#iHvZPE*zRVru2M1$AoSL(*2=@zQ`BjAn$XFxV+3>+)G^SHB_4hsdKM4s5NpcL^
zl6n2Ez5Y0W0^qocWiYxG=%@PsMj{#cKE8i{@qH`Tdh^lT93vnouedl0Qfv&wU=b!%
z-9f~xSO?(;Ii;h_d^6FB!sV}vG*~=h6PHQT$Zy`nl=X(#-T$S=FdG#qUi~v!QmL@D
z0r@m9_2lK|vccy0to#!BHt<(`>5UBoR@5vNBvS)v0u`g{?h4Kxr9%y}!r?9k1_lg?
zub@O8uw`!U^~2rOW+XCt$Q@zW<ebdr)u`<<pC%&u;`HQLquRv*?JH(=2sy7o_ZNBZ
zDQ9PA%ET;1MoE$~3}qJ=0p`1RFRy-tS+32NS7apg)?KkJcblvo8XCHI!2QJHY81Qf
z%0_`fw{U-+?&`++*wGB{<>mzUoq>$wQhCXOw%%2jg2eT%#sZOSpf9%EEG^lfM*hxg
zgYm;tCi3IQ6cib<61Q37eRp~>JjPuHnX7W~hlCW%7mPSEeBDiLWo7&ict7W56%?dx
zZNJSaV_uQb7?sP`sTN?=cYggH1w@*|s1o}&DV?YBMAawbQIS6O%g2wzi8Hp9=C9EF
z75=WJ?~Zwn&2N7AKo}L~KH)=hsX4cDMIb6HQPi_$yco*7v(1qpp8Nn3($Aki#kFO>
zbMf*5<MgQL+51)_R0`c$86jUYv9QHY(<mfnN~S)J4@*|5eOC1B+S81y`&8sGkZUAt
zjjit)gcWM-6qzGYIew`4>Fb?Ff+w%CORK9#W~F+d7_yA5d%(+UReN00J)8UGF4Q<z
zrEiYN``JfViN;>sHKIu|?K{WkUE9@N|4rMZJRkWG6*UE=c1wFZ&MVfHcZ@W2s?$B;
zm*Jq0&bbJ&NJzER^3lDc{&}>&sr3AL(Bz~6g@_yJ6<o^300IX3FQJT)ve{bY_-!9q
zuLbdUuCK3W<m5ELrVNBcI5A%L2G9|KL#|G><_!zcfu(^$?F4fxD?g}M;CS<`KbFZ<
zH5mA2tWj>8HdgzwmHtVuO@BD0fc-=3U)^)J$6@$DZ73=JsRP0;4d6cSn46vIsggzM
zkdlhZ8(&|HIstAyx394}c`{I!d^f*IM&=CwQ#&04QYw_>ce494<BJo22;Qm$z6O1&
z`;miywnmOh>Zc&`pq|z^NhNxA_9yu!uTNd^@q9WUZ_cTHd(ZHs!oASq3kAC7`^zpC
zwzuu=?H{Bm>zkTBwC=!To@}%A`UDUf&@r9`*=)yi|1|Se?8WxH*XxQAP6Cb-*~dlW
zadPx;q*KKnJ$kfuE!Au4D!CFGoVx~-!U^)RJq&=D>&1EQ?aN%>QMsm&I9t~MD$kSu
zMOlR=Q|kn7DdNTO0}p~uU6L3&fFPE0FVJAg`1%!JNDXm|1h_>$b5qj?fL-SVihFug
zA?PG!s}v3(GBPr(KmBrBH-4O-J-(8!lfLtpB++oKm$>TCPYpG3N83O#Dha23`~k!u
zmKV2qpFd?HMfGYc4)5@Io-NdC7rsIz$s8$bf0rac()-&tPN=`G7#Gg;^{Hj_nsqf!
zKYLfcXR;EnU%k)GLCI`zkK5nUgEiuzqPBJj;M8y{5BWL(Rg7qVy1SLs)ftc+gU=x+
z!#?rI4FsG}3w(^@$}lGIlP)5Hg5)mMB8+!Pv5AsRo8VIqpmqs-`}Ptc5z+ou)#&JG
zMu-DFb;?{<SJ&%5f0Vl-SbzbHS0E|6f$bZp$OTm=;R84h8kLT$qi&n>RlB3EXH_@P
zB`lu{n3$LvC5W3J*>yXlf#|7E=rxmi`7*ODB3sW_?-dqN`NojX!<rh#6bUI{K%wZB
zkTM`8=Se{e3JYsq=*=o{*<MhL5(kV)vm*V?`=<8<ld2IgT7QU)VZ0gN&)K74Ti$m>
zOE-cwFo~Gh*>S~;2}92b#0bVGG|!+Y`n|aQP)-iA(&*bjxBI&azX0sLV(tDbpYbqX
z=Sd*NIbHZL3CIkff>UUoK{OVKzkWt}G+35CSz4W8R;ATe@^ucFsJ=d|a{e))^N*Q|
z1J?xDw=IIDIl&B@XuV@zrGc+%R?Kaq4zFtyo9GUT1%cQ8_@Bq@+xz?w$Z-$Xm?}rE
z=con63pxdcLZN3Ymfn3C;8KoS>RE*S{5EjQNjP-(SLc1zw<xv<#b*aEE-avq+O5`i
zvT0?r39jD6-V>J0Ch%s+@C2iyl|jkW(<JBPGWY<K4J;i@_R*2s+_p=L(KoOD$(PI~
zfD7Fm4-6>=N@L;e>i@i5(a!FEj~O?DC-&?hb(u<9T3UWz)XTUU;c5fLj$tyJH;Uu+
zP6fge_-Eh&iG_7_bV3&v7Lt}Se<<Qnck<Pv)DpsrOOAqOW@bq+fX)}j#&tmK0*ebF
zTJ>#<>-ptUv}9zi0Ndc}>wD>(cgOi4YpiId50|q#pD!t<tX?d@15m|wZ33_bjv8hc
zUqXtJ@Siu_kqP(H$arXG#%wQe3(Cpwig;K==j5f*=gLZQvtmsyRY~dyxus0v>t}WI
zIM#lJ|8*j!yLTlV9Jt}D^#1uO^w@S^Sc?j5qSlTMU!6SMAjOFNpuD<2#ZJ=p84rQ@
zfx;QyKc4bU|FG+e;M!*52>A!9hbYM-xv#Ge188QlX`oi18dOAOJ569DekHhKe#{<#
zVNp{_YB%)luA{pxf2lPXS>{bH*${K9)zi*+jN**3u7a=vrz=W~5_O~V_F|uMN$w_7
zqp<89R>|v1#Ws#(%~$eQ*>NwTb-1|@cUn+2I(@4NJ1h-)f^!?bAy5@KWaDrdj$O3E
zGb#;PZkOJs7-4+bX=<|V<E5&PpGXhhW6JC-JKkhY>0d-i4c<Q)`=sO>c*>u}B6O#2
zbR5sw3LWp=7kj4l7`2KISG<M1g|+jtvaT^l1}0NWq7xF~#AcbaC+`~Hy)L@Rv?Fxr
zx)LM?@5O61DNF_e0^^O?mKzKq=nF(;T?;(nPFN8Vys>;|vpxz1?BGeKp)rXmny@>-
z^RM}w9g2X;+hKZ7`pqpZeSyRt8Do7Xj)DzG-Slq4H<`sJ=u^mftYW$S?k6TR5e$vi
z%?S3CEp{Yg<a5GZr+nHZoW}b#?}E~SGF3ry!WX83tZwDBR3A_(D1|ya^-7IAh#DUA
z_r)*647z+iA-5N$bIn1MNy(pLYM}xBLm(bPz6fk|sjvPBq{*LbehQb9JifvG%YzB-
zuUAt*`%*$$lT6=<l(p#;-sMnjyaLhZA&Cu6tY{3kUvjC)k5wniW~)SmgtWA;ZZ1j(
z<3f@C@M3!-w6VFF+`sr{L;Ajilz+X9Bsby&(MNIO@iUZRbw#3gWY^HWYuTfk2c{!}
zclfe%ixDSji1hT#jBgdOZ{Ur~x{X|j*QR|G9UeRELbdKUZtCg=j2#_xc@0B_>u>t?
z<iz6xKro=;w%nYZ`M+jmz4<ni0P8iuL`_!m0Pg&FV!n2qea3Fh;IJ*OSq_GWZg`f>
zFP`N9m;%6_z%htr`k+2`cZs}2kK6qEYK;xn6`b_7A%>kxfBjIBTGPkS(CbhEVdLOn
zc05W`HsvB?jQp9@Gbx|Z0#d-`w2$)}gv`ni6kJ!z{j7edG-56KvLf4K8d?n#4W29?
zX5_ft7-QEU**YYEN!=>Y%s~-_=H>*#P%B*sktX0trk)SvjAO?c%X|Yhgm?Kiy3%bQ
ziw5GaChZfy(qF6(?})iEEFPA5R_@tfMx7liE-tR5FJGj&T4<p76o_X-h)aE(84Un-
z(_6XCzWf>y=1$)g$=Admah_+y7PszjU!NEbV{7gX6K#+$0okgB0mZIm^`<0K;|Ca}
z6kPRFjA%3`L`e;(1(QQ^BPM#X`L}8iO%pFfni5`khBY=eDn<b@FR9;QQm8-M5zi(e
z1-vP0nSq}<LrK06W}G{ZgfJ>7oo+JY|H{Gj_h!l_E3t;P|G!Q`&tKFIi#9Vie<Pdb
z-OC)8%kZx_A|N1;q?Sb^pla0PLP*>#0b4JchzI96AFuiK7b3zz3?<cX+MP0N`r}1$
z9Qa{OgwjBGp#&GulU!;(f4&5B!WiOnmJKe$9i=?b;6g<F&X(`{A{;11Vq(yrM_!(b
z(qSNA1H_{d_{#w^39-jCM5^d*AjRk=nuy?W!8irPzrMFs`awmo7QZ(=o4PvKfA1_^
z(?ZI^Ra1diLGiKze-(iP0zwo%4Ve)JB6U&0s|Ay&AewAV|I|EX7LIiR<7b@bpLxu$
zOIW!FkF5%Yj)@HT2JgEw=KRMC5FC6y!(s+!S}6LPy4x-&xfO+0^dbA-3ADUpj-;-B
zX1909B$!ZDiTl)PENok<)USd9b_G^G$gQfXs%6+jU5nc-ot?O{tf&up+<A#iNqc6;
zcQ{bHcC;gA<mOK2vAHNCp?w|p_hpo@jmqVU5$Cw;zG~xR_}GTRZ}JjT^FI2+hHlR~
z-CwigO*>KhY^Y`X0GurVQ&hN}`_Q1rON_b-tC$5crTm%QtKAS4K2tuQF_8iW##nuP
zc>g$P&SGiG0Sf%sj)rxLcqvH2B41Wwh$HWtVRH@cDm~x7U89@NcD5@b!i41ce|2{H
zK}M1_1oT6zQ$ji)n8>O6mQnU{nto8)|2h^t=O2t3mPcIy53&gGq{BlWTYS8D5e3L>
z`I0=FtFs>V{0SaMH&0Nx1IsYs3k61D!5Y1)(X+bFd#)>V=y}E!RhX!$8zu{AdE>={
zC>Z@8M}X?Xu?Fmz7S~WFKh2!I;OOjZ7SfO(NjdVngv{@985_KNh{Q6DD};Ok0lucf
zUoS=CNhNr3BM^OY@uZ|pt0lF5KV&E+9334q+U~$8f}ilKW~!2sk>SU^mra9Y55<>Q
zW>fdoF`^BJhpja<01~~+cfuGoFMZa(TQSAsRxr+(t3<2U;Zu0zzVGia(_Q$=U`P<@
z=11l<vfq8SeFzKTEC9>^s#mfz>cfWzsa==2RU3P+>H=n}IyAdBdMt4l&cqSRZJeRs
zzi%u!;EwMLcTU7+%@|7QUtrrG+&`(2Z#3(sY)ZLyzhJRHM5`Yl4xtea4i2goiMNf8
zi9x~P9z{HL8n+01<}<==M+dNi{{`A4b6||fPlon9*Ry;DXx$g7vl-<ch|9VqS&}GS
z7d};|SU$R7(OL8TB|02jvEL&jIK`T*XD0}SS+W)JfW-&g-?bTWgW0yvgKYIAITDqL
ziHqEkpzExU=W+4P9(9I4Wo&qwMSN+hMBidACv5#NzIlC!VQ8-*7?|V-=XihK_NTt1
zBhQwL`)_e6Y>bPb5|T2DOX^^1Hq89)?e)3hkyba6z?*NPLj7?h+Ur?iCyoiG{@>N~
zrB@p(BB~?qqJ1PIlnbZ|B}Ml6b8?tfuz>ul=u$Kb_^24s;7a+urAss*;RPVM)63QR
zcCe)4#txTvoK_loOIaTDRb0~IV&|FVNjzTCedTd@o3o|{zjl8+HJQy1MmzZ|M-7$E
zQd1?i+#Wr`1Y`$%$#-)AhIs9b{K*wI1_sm#ZrPWG^J+ta^O*Cqwm1?p`MtwV4>}bi
z2{{W*5`*dwyRFSSV#`*1|E8$W`ZEfFN^ysc&2qBAh|{NnHYGZ}*9;|z4Q8i(`BIPI
zX)xu&NPD(8H}^nOGsd*gvBO!n?j1LIc#aEKc5Lwz5k7DAn3D09nvs-tO~|kyHT*Dv
zN=cljo+om|QpVi;E_2r1{M-8%TCS0d|I7jnDLcvaUq|26Za%=&1*P<WvXX8H+&Yjj
zcfJD250X@BQ4t})7jHXYHsPd#m*hNDQF~$zTpdz{-vT7u8{hNWYYJOj`(c=vtbcrm
z!i?&=!%H!TzrCADdr}wrMmz{SN@w>`d*0HND@HNufg~v|k<yu94TA>028cuNzHAU`
zKBuJx@R%3Q>UjT^8oI;Y=j%|&W4rYPd1{?$T1X!$3%V<)uLIe5m&K65`2q9G%Tn={
z3_G`8-2`%oRE69oaes>?VMxS()ySP{*NP-@Q$aFWMOQb>VyFZ&)b4EvV;SsBU=Sua
zRe@-u5fv3>L?M6w3wN@~dHgg+{aybBHixa>G0LeveX0*aUdk+h@yjUb{@)?kPb#CO
zDT)=4_*W>WG0Jd>9?8kQ)ybO`;7+;W@9*1wM~!!K#eE>Kq0=o;xbuWEARqv?5~B&u
z_3H+p$63CSLVfMWGp4YqBVJIybm;PI;kR!|-Sa4u!3P&qhE>i4a|$gVFG%_79+fxL
zb#w_oXnt9Ij~hC^T<vmR%7NJ?BR6-3yjk)Nz7o!mQ9%jbZoq4$Bg;cqQ@81RMlW7K
z?n#LT`P!Qy;gz^O*0d@VI~UT=0JN-qe2gk{lko0vgCZW)D*|Q%F0z~6(u4;31Ok&;
z@801b?dPBiWn26RxVT<+`cd6F!=3bn=%ISX<7@tJKfFS4urz(#z!&<qm<)?dsKQpg
zrQBu08Xoe@-MzZo5#7edhF})xnBRkgsG12pG1GtlCV&0<^KZq?peAn+$l+%=1J{`&
zv4A@!1-kN(%-_p%HM7L5ml?hZmML3YYPxAKAD3u9|CAf#@H5TsQ#+XwsXr30B-7v}
z%?i)55=#XKL8Zq?%RHu}7)QAh`VaDAAnT5ntvn?Z6hgcCJwx&Xd}4w_LXwM%iKL`*
z)73$71=mMobF-nnJt1haZ2d#%-%pMYQPq8Z&g%>)yP;CE5BsBM)i-?R*!jB=5^y(<
zy*_e`EqG2b0yMihdjY`0J`w)6^kbPn@=SKH>jrlkUu-$)!0J+Ep~i{>9jmCclm>)>
zx!v5aUu}mN(Wh3AqN1Wu7j0^4vLvTNYiVtL-DD7uLB`0lwYw|976oTd6{x=%lXl0-
zTY%Qj{0Dt(H3&>g<Q@l<Za4bc2P^YR#*Igo;TS>W0sb%uSV<mpNqu@VY2=qcpO7-Y
z(F4-jF=vWe_irJGNjENoL`q~?vu`5iU-$ar6>ouhVn*OX;MD6syVykeBp|3xN4@tS
zI)(Qk4U=l4fy>p@zSJ{hL^zsa^48+32GU<}{p(}vW{H=K2TCFdmd?zO*QIhGktNY}
zI5!}84F5~Pwm#GVKrz)EhWZs~vY_>OH%H6SW8)s~6yBpSOPcG3tASz$%Zyz73K<a#
z3+qe{HL(Es3p@a%aGRjhRCO0z%j2@Zv*-gJ>34tsl@RF$2z0?x77aYlJUm2B_I@tD
zI>{t?o!W}pqH909CHOYy2Na`t3`yGG>!nUGAI)TH9_=y2qTtkJ<oEAhDx1-9alvPr
zs9Lh(gS>vjiFzM2uf4rjh~Y9N`%7!@pNOCqq(aUzv~hC%v8*iWx@pQcKe&MC5Av)p
zl>c?*53ixXbQKDM`cpra<3d~q)77hu0%H5x19~GzezLyW>)m;yA$ty%|91kgI}Tvn
zc&esG&CmbL+HHNZDJ85HNGhqYJgstN>!n|x?&GOklp=9zR{|aZmiJm}7wHFwr`6Tf
zVD@2?P{^&Sxe7``bnRY@S3jqAV*Cl|48zZLmp0Fd!fvW-9VEoW7{&W^DW8HeAr{@c
zhleX#bWLWIOwv-CDdvOK#HSb<zIz;G3x7<ehZfnJdqv|yBF7?veozu989lFYE1z43
z$>^E_`&LRb0Y3hv=9B#=tD|LDeq@XSpo3H*LTT|ap{N5>1}btuBxMw6GHRH)9Vxqh
ze_PGX`bgsFh0bL;L4_n6JKWKQBaWUl`JqVl&Nq`Jm>N!p@_Qqc6I@rR1GRLI7u4Nd
zs<P-8ysxqO&yg{Lr-=tJ@&mT0ARd{4fq}XC`8u#XlECeQaQ0AE7GIke6%ilzA->~~
zQ~iK23|_PDZO{~dr;P>E96C<5v5Szzv9q(w=<4eJE)l&=eHu9LYw^u=(Esqy=WFW?
zejguX<$Y&Axyu*pkFPY|{^>qL58YcS9Kv$g$y&aFd^@U(OG`!>{!su%2+5K8@)7az
zAtXb(;=5T^7i8YAkLQ?F9nHA{$al?nyxAIe?M3oloz-}JZS~vL(?lWUa>P?nJUl5}
zAW(|U`%{vV9u)E0z772F;lrggN(dQBwE7J*;zfwYY5+EDH8V6Vd9|8c&Orb*!izLn
z-@SYH8|oy!D1dQ=1K42i$W$d;(?lVo2!EW|E5HO6bMH=7*G=tpR$*~5jnz*LjsB>#
zio<evsnfQXi_JSKOf^<*Ojl7+A&#mcn!Hw4EFs4N9U{)rCP5tmkTWSSkDbw#!i9kO
z9Y6}eu@nI@s4_tWfvh5&C%0kv+-UelpQ+?S)Odt8t`Dk!2~>uI46)j_{FQ;tdHPn=
zp^W41gQB?RlPd!%K1~`=K392r5wtA;36Pw`9{13uj2kxa;6zm5?ZQmycc*?rZZ23J
znReeg!>t~@!^6Q42td-R<NqY*E9|<X2R_tuaumLq_;c=q4q}?z@VsmP@S{(j;G#-K
z3i6Vh{yiaOn{6ahb^~bNY751;qDb-Zx>OC!Ybd~!QvmJ?fNg;%Iw)=ptZ~44Tzocp
z3FOF+Bo??JM-o^$Rp1caBMU*@IUWLebQ_;{vc_?wKi{BRD_iTm4{*(Am|Z^`5(m7z
zrywZrjyO?q-oGye_4T)J=dLhseCA2Z`<8k_s?%US1drHsBG27lPd-eA%sTq}23`_W
zdhahDh7(IAH7GqCpswvLNGU7P6}GW%-==bgG3&$6Oenr}de&G=z!`~~n9u`Vc}Zmn
z%%DI*|1z;t6qgdR_#w=%It`*0{+i2|#S!)A`KJ@gkQSv=BLITm^Tm1YCHYf&`2P|4
z@O(aj;UwT?C@dh*KtPsi6q`kwW<2!p@c1nurDgHs)}v(VLn=070JQ-E>^+wyE0>lK
z03Zy(cNW=8^eX=)Rc?(j`nNv1@f7EYf(Nhqmh6;Xd6J#1ZJoi|R|Us^ljOATP^YZ*
z4Gk?4-u^Q*6m<C-vA>8K{d?eBF>*4kxk3$8?xFM%d#Ps{c`AZnIe-&uIQN9UYxCK&
zXW-`4N|z>_n*0GTacxN!AY=AIPV|pTZFp-uiV4km=qKOh#ZxVOqpv#r!9>9oS8tVw
zY|y<SDS40W{{8MOhmLbVbX`*!JijPpCDotVj-ot?j)Xu1LRpo7hy!8h995Png!rRb
z%NqUmIg}n&*Ad1I)TPw}Ds;lh^=+%_gc002%v3Vl8-GRwXo?1=rly*m7N(|a$ZX)p
z!Gp+dTCfqS7y<5O)VcmOe)TyiP)7|HYY*rYPL?mC!1rL4Pcj=OiWZqI!JQO*Hr9MR
z<g<7|{3U!jP|&89mKbPji5z$lWq^>-rsN+uI289ECPK{tM%VI@Je5pU@x1=SRJpM8
zqKT<O0SAEeBlRP$f9~j5JM3ED*}Va6xY*<W&<p1|>Hh@D{^o?3(RLHr;eAE_U21;{
zxBAIntYkMXs!vUA6YASuH}oS1qLn>vVJm3(P*V`Ejp0DpW!rU%rTY~0VM(ywWz!tB
z%hwXF*c|lakH<+;i^0MvrhmX!GSY7#2JYNfG0zpPbJh9!m=-tHT`U6eijJIrv9oz&
z@!JgQAu$(EF$wSjVh8j2%TUJFK}AKy@!oAP)B^@KQBFZo9MojZzO2EJ5ROXMPbbxJ
z93CF@NogoWd%gXz7v5uQphs9cbV5l+<%|u9LaaPJ9VO_Pn3zqOln$Y4DS;R|Y3hjY
z2p$?5nua`wdjR<7#*q0^{=mZs?cK%c;6J@@MD)|Tmw8>|?*oC&`Da1}%eN3U5+Ri<
zM=!sxG{E;UmQjQZN#F{<1(ER~?YjV+JUEb`Vxgk}rYC6EHZ%J=#%sL-24oafd_;y?
znf4l*Y~I?F^meSEOfh?yu%qHWQ?B8o82_ptzO41YwoJU%eQ8}bi<3R@!QYsdUJs7a
z8%>GW9Y$j9=m70nOY9c6Ll`8ObL0dEpkQ`;A06!vqDFYg9>DZ(+2fYK;z<q^*_?pO
znA<)`YFEZAo|w?rU?B$k@Z_1^`Xk+knGlPXmR1iXtX9}F{rU6f1{GDzfP@NEA=Gqq
zP4gP(wm`C!z+o_xHr?+OdINHOU_z+|i+9(m^@&RhHxB~uX93>sNyl$Qqx;-`?WE}}
ziK*+3k5~2MmLD)X`QjrP=m`>1fJ?oApuCgu%N1fa__ioPQEryZXaQS<y+C}o?_vTM
z56`6Q*dZlYiK)K-6bkz6+it{p2TDt?#o{9bGNl>iAo#)nXyu7WA17Qi_s_Uxqx*72
z-o&4~qCb9eKigY=Z{eX^ix&KZoQa8P9a*+6d<8acuDDEnveG7SJo)xSK(pTLN~VSl
z0Sena0_H!1gQ)h9#Kh8<-SjBWgh`>Z0W(_wcy&QKjUg@gjQk!_NTbEbJE>5$fIqyh
zNEYbvAuRoQ0v6I8JWJL~$a_E{g@0DX$CC<bY?K5ZoI=o%<#T%sm^{vF^BPqQ=K^B&
zG0mHRS*<%C|5x35?y<Ugzg^Sa{kSNmxD_mE;6^=GRkHut(xO*L{04R-CMc><Yn_3n
z$!3RFQw5#B^G|MEFTR%kVy|0jlNM=OhE?nQm00wob;fHnD1;oZYwPXf)V_1`I)EjA
z`Ug7B?s&E(qzwY-8(W$B(TR*QPlhh0V1|c|JuUcvHUN_VrEoxkIry~Kr<(8a@bIkL
z9PQZ@6&3l5)MR8_y>gx6s!_Qlo*&M0!k?X;%~ZP1w>m|)sjazg?v8C>={UPwg$PC-
ze%K!4&W5%6q#={vYO;d-W6%ly4g-&+q~s`OlytjEp;(R@s)i{oRkuC?jpz1@AUr^7
zSBEaO{LA{&b*TmPX)snodxbc2q;FFF?|coG6dH3VNf@3aNb2j~A!f6`9`vlt`VQ8$
zYc?Cxj~EH-w*&b3`AI3SFOhdhM!bb_wzaf;e;-zyblA&#r?9On|HL8MW1CInWKr~@
zZLL*aErt52HIJHyOz6qUiPx|pr_2=4WRs{3J4J4j4q-hxS<Kq<qY>L5E2aj(lGhh6
zwV;R<FeiZy`8*tr>0H1Dhfee(uej{5UuCW3k`>1T7!uY<sZlP*rP1o=TUshA?{ybw
z0x=Lsg9lKKQF@q?gjR9;4+krwu-ScX8EXT*p4HuojRj}LBWm<T%UaCZq0OqXyeE>9
z5p`z82FruR&>3?>-b+rS0t;}xemt5p5NpB~xZ{yuSYZ|ag@Xw&!&RQK5O-~>f<0JA
zX1g;{lnT^a5{j_`L%%u3STNITX~lInkB=vH@Bep+4epzaygaA!(nNM}i;j;P;4G?w
z#L(@MfZS}7tI1{8ojrFt1M3i{b2q4Ia+{k1<H{9in-Q?dfy4v~3l}%H{G!WrFjK@m
zN#@AO7YjLipIjFAq=yAjgx~IQ4c>0rBa%r!T-Mi)u9rub_6b(T*lO|sfJ!ldtQ-?V
zhFo^6E8k4x{CxLky-Pe9I0bBt#w@!W%%C|16oKi~sN@o>F_F4^KH~QZx++S+49e;<
zY*29Zi%JEjkPvo=G!0VWyAdb<GI}Zal3rR-SuYp&V}&jw3oZh!VmFjjvomP!Z3y;|
z%_6h4D6nn8k#C(xPWQ_~7R~B)K~%}e$P~ElT6S><zpo{M4F|>lLj{E$iR}VE8gPz-
zHsR@Ej)rR<Ycu&kXr=Zq5%5|+20BmvMlE)hTN4LT9bt^_4?W&HIc+64PLl`!ys>SD
zKeE%^H&BwKK=cnVQldHL+&ny3q19kM))C%?aI8^e8qr)m2HtA0FLUG^c&&GVlZ1(H
zw7-9L$JroHC8LBLnx{}^4lZ*QV8kGLR=WRcX}KC06r_#OA!l-KhK`Ep&}j5!{bBs#
z#T3x}zmFGUzjql4y~?`DE_y%-`kg3FUyOV}*<MW8?b;JFOD}mz!ZcE5d{=3irl_Y-
z0>A>QYuWgWBT?RDm)!IjLr(CPr4s%evaFQ1Uh*N)vEF}GFz*Gk(p_^Z2NT<{*x#$i
zQD%`3^`85v0TgEU6-~&1zVh<4Y8=@-7;4%3dZAJlcM6J14@}0^|5<;S=&<17`QZ2l
zHqxu(3^kGH3gs+nI}R9&jL66t8>e*>UobGALK_Eba=coI*WQ-A6HYjiaUzD>+^yn;
znp$6DKds5eN6gXCVc;S8tJMswiqLXnmEO0~3Z%T`iDk%jhTzaOqng_F>M70f^Wo^M
zRgoqx=qCe)T2)P5Pi*6II0@T#C_Q7lxI00meu8kl61%E6l`H7EkS-hG&q#Q#OiA(9
zVt_jgl|K4nbra9MLL9@J@8<Ra21AaG9yl5#dGqECw2|OZlnx+tu7t|*2nhvC1rcM0
zCJH(KdD;F64j-tk<2EpRV3*4pFKaathi;wmGGt<{f$n>x!{XxN<!&^Hlct5V#Dtvh
zMXTM*6Y}z&LjM@_6sh-<WEn2({uD!04}brT)?c{qMT4MazCmt-+Ic*}F#*DPD?h?`
zM(P|aK;V|m>ZLyOkqPQDzp2s)%CgGAUNo^No26UwECUV+Bntr4b5P0_&eVUp|H9jr
z%IZ`NoSwwOY;bWE0~#ZPI_me`cW*WJEnJSx>i;=3pPgI7rmoL6b~w6wsrfpU$Wm{$
zDFr#tM#~tv&1@9=kJ)eNMxHNxOndIbvNAxKHygK01gjg)Z#UyldAd~C`Nct4J>(Pb
z5FH~SR#bbvJ;5FDn${6s8|8bomNbt18F}|uCyaf#T5U8m_&PTB)zE+(G5Z^pW9Nou
zsVQWBME_Aa-fr<?jW1E`jKSX+mZ;4yuuwuM<RiOn+UOSumP+5iSFKNJxJL%==SnY`
zbS5mXm)BU*jN=;67^_^AZmd@n7smNbl^2P;`Wz@gy}a^PDivpPH*wVWcODhvIZZx|
z8V~jRqqvpoCN#34>h+Zlr291h5uZ*s{c(x9Ou2x1z<k!@LTk%Sw%K2M;-J}Y7fCVK
zp7Df{Y>C{eO350rQDbkQ`{eQC#}CXmd_{Hc#<tJ+$+m#m#dMH@+{W{N(ICGU&9%6m
zc!&6At;MFBtxqK)uIm*`N=^qQC*R4|t|Y#E`Ep8kKMC|uK=TjFFT#@vGPaJvC#mVn
z=v9A;E~h`iJoV~;HZQ1vq0Os0#zp3on2HM5NBj<-$Ox-jqqIfij?gs{a0?Q;9luYP
zI$00%BovyhSj@flN}DhqZe9165zPwdC{h#0FZsA<<+Yp|Y-{W!Bnb^r><YAV;ShZi
zw7N6hq-ivBDzqdab)xQ6X`0~=HnuL)M(EVJ$;^4t0OvV)kc)EZN-&nb#9D4Fl#^)N
zcNMMhtB~_r5>nX71-Tu}r^kohCB$OUBCSdNU2}sxEtX<-b@_^O7!LV<uN=?h$<9HW
z%{J}}!@o|`VA;hLhk4+73MNV50fB?bRu(4PNv6)b>FJwLa>csOL(>{18-te@{5EgE
zR3AjS>tJZ69?R}$U=hRKh|jpYJmd!^y1IVazG11a;1;VZKy@u$ifjx;brwr8G)oUd
z;al4!8mygGxxSqRZp(XkQEtm_QJs~Ln#<-$3JX?tVinJ|&g*C>0cvzq2Qc;4&JJhB
zTYpA>6bt*2X!us&Vh_qYj15j^r_<le8fP{`0EW3Lo2k&506SmI?%n(MQ?^fXGeKgJ
z+I^G-M&v`h%>B(-iA+@ii`&%}Lp)u+^f!jCy$#ejIt3Rbqrjx>NgW;!79)@#gE5Ee
zqvJLx5)H-Ity@@4jqoazyLJ30!K&%L9$IB=^uBy8AGmVx;DM>M@EHv?Rtl;}6Zw~U
zGcK8040`_Vy0|s?;;_AuL}hg;-Zl*C7m^EpqDRT&$ex$UvT2;RQA0ttqyq!N|IKCm
zJNkLXPp+&SnyS5q559P@iACvQJGMBV$t$(!=EJe1$IWBjTC8|@=ntw8_mtH!PjBOp
zKr!4OENYnX&>wohf~1FI<>*;7i>}Jc%X^Fdz5;-vr{^uWWxLEvN=yBY=VIRQT3r}+
z9I`;qfh&=taez<(jjvv#ZDLEV31`mdw_RQ9J!@TEN)&w7XaE7hR158i1OTO>uXx&)
zj0M#YFE-mIJ-jb^NZ&VNN5mHHJ6j_HnHjO7&W`JV$#zeb)(yB_Jc!FFv(PQ~7J@ea
za%<$fchnU!H#tVHN)Gl2sOwfXl-6vs){Z=0DvoIT>mL-<kQSvADB*W~e_3axj0`;|
z<z?u9ya4TOZP3{(1$~>)p>1nxdnrtbkq~cJ_&Rs4K25EyoH``$wLJ~kbkO&l(J$=f
zyZs*t*SlMw^lzzF=-a#O;wl5=W#h{H#3nP7@7n&<JKCvHr#y5pYw?CjjNNma9ub`Y
zIukc5u{8Y&PJ@Bj_sly%bNf&(fcRkPam(m=sil;-czuxyHM-up>$;dK3o8^XoMl4l
z(3{b#V>_x@>rp+_#Z<t`cj52e`V?DwQN?BpP1vQRm^o;-+Q<T628HI{R$ME&4ZHty
zjP{%>YhzBeD@Axt;<7?3&NCQsygM(BHm7zQ7Q(Jjr<mHb8o!LD`y{x&4+K3xWx=;Z
z$3s!NZlNa~&A&6pSpKD9etUKeC6z$a9tAXQiU@<<{5nAV;1&}c>qHah&34|yZ5@<#
zSti}PTm%6`Jj&eMKV}8$0r+pFf7$n2*W;C3O$Au`$KPw+iBITwit6Ugx?~BzwaFm%
zN$?+ow-|JJl&MoKS1Vw8dirKR5KuuSB_#o;J0>42IHACb(ml|1+v#NgeOT++<h4)p
ztJ00la`;1VmKy7KU?s(lk=(BqYTWrY{@hl!>p=|r`yb7ryyHHfcqfH7Hwl_Y?~8`D
z-LDCHH82_83k!4sRochL0Q~``Jur5cDX?O*XqDXnRF3>+d~MY8)V&I@D4)yLT;mw!
zzkH``+JV4!)`mXt0UJut+?>H}Z_B}<A$`tIsQXbklIPpEs?duO^%Mc~jgppDaDyN2
z6hKIVF>@L1yXv`(-;CRiHcCyh1Ied49Po?<aAI4H@I!vZXT#LOc8FK9fHXpY^BlyH
zouz@P?oB}f0Z>*313EjQ=c#OAhIMb~FmHU7;fhV0wz}Rx2xc_*p;pzO19Y9CO{PDa
zj&HYr<UnOI0~@cotzu|>U_Oi?w5g4l=J~eiZ*zX&?7-a|aPFoDDZD>ZsRei}%)Y+>
zdZpzC>3nz<0)lNp(W8t7Q})=6NLlXXLpe(Ai(a6cBu?$7i=2E*%gQ$$kk@d`B5t!9
z^ARn1T%f(qth3i%*`jeDSE{y*&`RWxAXqa@q0*9?+7_jLi&dojnnz}AXLM&g=K#fl
zx(PaPO#Od`@Q#vtn=z6V=m!}P2Q{TP)ndFshj7zf5rwSa*6sf$FV9mk_vbGC$)Q^&
zwmOps`aW(f$B_pHC8OJ|yrZ2<fu*_uPJ-rZ6N$S|vfyg?n&A}}piQ0cmf$z5Qn*@D
zoCtR?oJR>Lsi8@Vl`l_~8P#b6JiS-H_;f&%L7leK2pu0KCb_4|G_>Y5LI3TgW-@Ye
zcxD0z4-ZD+01IC&&<}~bYtaG~GvkYlLp{wpw$3r*_fVSmG`Yvy$gk;ZdCwMqZxxD8
zc?We!jn!amEt{`pqVAp*x_^rl_Fy^unh47h3rBr{^Kk*Ea|>uOf)+~Q5fOJ{1~niQ
zc`q<(!aOJgO!cO^4X#|s$8j3Nv5}EJsGd4I?Pb-~z{&_NUFiYf>EcA3O23a3aCmHg
zd~v(lfQD@^Op4U4_pQW}QM!Xr!0r1cJHwCjjoLBN4XJi&eQ^(UHxH{7aGt>#4}P87
zybd;U!T9$NX~7sXx43xiq1VL-cDC}y&5C`nT45l<bx~u19sxp%%H@(FXpN}e(X1;-
zPxKfBvmBYWU37;g&lM|z+o;D66rYaKw5SOO@~>Z8OCQ6MArA0waZ+#T#~c+Zj3&Dz
z-)rv<{$Nxa6RZS*yw|V)>UKZ26;1iH!Bw#sc7r!16I$x=KwO5(?;mmbyz)iW!=3&3
z<O#Y}8hi%aP`lT8P{K1c7GFk;1}E)Te6*;TG!C+foFpk*@vBH04)bRuHX<Hg-r9eW
zF1ph;if9mK*FSAY15@39w>EX`=}4ZScmP#3HG$*h&#*0!NPlRn<S{3_5xk9i5!I#2
z&Q8*}{RH~t0#N-UhR0Krlb8Cfw{t)cu7@HlE_8cmr()#lpY>>H3M>t?0o1u(#y->&
zQ>)%^8;?50dQG93O-$CPWTETja=YU}56AUY=NpM`){<LQ%9(GaQzrztsZ&m&c)h~|
z$rCy=O54fMmY^aArk_C}Zfzl^=EmcD2SZ~gGwaSZ!Eu+(KLAa7bk<!h%<j4)G}q0I
zLNgG^$)VpPrJW4a75~O~l7$Nf+Q3E6ZAslrh!MCF+fL8N<1jd7M56O5c|4j|eyk^?
zAU!nPX6>UtqX6HIiEH)WTKZ7_9g|Av{h!(d-UZWYb%d@$LH^8q7X!?+zZNj$S5ZyR
zJo>ObFJ8PzN>1K@M3O>hQIaZib<GOYDJEJ&utx-@%%S~wD;ipXLlyBh3I3u8;TU=z
z#GNgqVHjp8DEM#+()p0n(?;;0(p01O0o(|1_p?!X)?FsK8hU)Z>bbk11I{Qxw}IFY
z&_^Us>U>$>HcIz{&qzz;WYl#P#|Y(4v@9Qt&8giSvwDyKCmnn>NdUOJ-0y*Z8uc6o
z4Gq#YmjM41^!|Jwe+|`I@#GsgXg1@%$?(-?utg{0L$wu}!Bp8C;8el!n6uybzz}rX
zU}+l9C^$s^urky<7F{aABI6=LjrtvN{N9Euf9OsDoL>zE;4DSC3ck&0Yv9wt?Go`2
z?AjnWH=Bg`o09R>6H^=D#PZ(zvC@~q@6U~>!G9b|3y*G*0s#)}-~E|*c<pH9C5*HY
z4=*(jTim++@hU&;$l5-*uL2q{C!Rktz$4@F9qPbW2&A|qf=~`|T9jEez&A7^z;~~q
zp+4j9>0a3B+B_NDP^HMxnglozE}}tm3V({U<g|=d12Hv;E?C=8q=Aq~=a76!Q(r~-
zAodV2Goh>+`QNh+!FC9e0jNbZf`YN_n%MU~$pL<{JK(b(e~{4@=u8|WwdS4)&unmb
z#&r=!(b&rvt>N-n!pW($zh4*He#Vi9tF`QWu!X5jFTevQ(j~!}2sI`;EI7FJ82G-x
zqgJROl?CdaY((kkx}H5c!GPR>3e_cqI6m0c83V5tye<HTc{M=(IVg%?<o&Pq#vK;{
zT8<j2?>&p;*ce46B?jQZ_`c__jjGSfv()o;4gfL2i;xe7#|Xl_{fBlvj@xu}#s;G{
zva*3sz%g9CJ9?K-O;z<$rfMK?V$l0txBugZw1OY32zV9=;FAdGBm^{~BdU{KXGaG%
zW>!{K_yPKxrhbIzh$fs5F$e@2;HP!C4d4i96d3qC>1ShMX#@j`ut+ZCap;UsHwQa1
zm^1YX^sf;>UT*?M08$D=Ujh>$R!?uQKEORVJQB9H8%4R*F56~c>jSq5lotwGy3m(j
zP=E*DjiMpOYKTF+Wd&3Kk{=PY%=&nHUx0c6+DQB=Sg;D<kq1d%zhXh4ge3#JueiB+
zR-1({J;4y?_X3RC;$nx%82F>Y;wA$*C8ckxk?q&Ib$FrzJW62t>4j1axs&N^^m9W`
zdd$M&qPy&F!qWHG7Zv(9o4HXRkycS5fX5AV7dMqSZx~ry-vDet&>wR&s4(k79AunQ
zlBw$n{uE%w(;Y@0lJEjMO}s$OC~)?`nUzJ+oXpNsosiiGF_`0;)69<bJ<?Bd81V{z
z_4W0)RV9=4I6qyQFh(^aPBsPE^lLknYkQ9U`7^mQ=8G(Tk{}eYuwaIgm#3gtC2rI$
zH!lzM)PO2@mV{M!rHdgDjJH7`ng?$P8u%KZ7s^!leO@(?gn1k2XAPGWou^jls1805
zeyVf(*AIXS)rYP|w!AD==Hy;8JSwWyofC-m$ZFTp=6+<i`67pq(9-(YFZ*0_*7FV&
zj~B(7@br?m;0QQ5T^jM!h~2IhJz*FeRDB*GtWB;iGhaabNB(uf*H!`b1Bq*bz7n&;
zmsf^lg;?n=6L8}uX$ynDr95IF6>^|YJEpK!m?*q;h319#;YVTz?Gy!c2Rc3BwCrN0
zJ~9(t6^D)e)Wq8pHJk5`X7<Z+b)trM<9ClQ3~4#9*Nk=YLP=_<eO;<`qQS4geqOnj
zswyZbNC{S;2MMg|_8^7)Xa`V{%;P3FWk?DWBO^T{Biix)s=dh|5Rx)GP1=QbU;>Xq
z)j?FZF2q1X$!`|QEA|5LC4UQ_U1Y-;19!_ol?j}&=OqZtxfe?(0|zlTDZt`2w;GHr
zt2+{XjC%MBI35hZrEoi{O`n6*KpRU+%)-J#u^(ge&PYFUW#9|cUYDOX7@^ve_B1_1
zI*kC~y|C*Y93)eHGhd?L;Oj;H5wt@uPd0c8){8e!LC~^yDTk+LXl8*s*(|%&W9<#q
z+oM6rdS8^8{DPySMwtig(-MlGtQgr!qP|<?Ps@z@j45Ze*+>A&PTM+b^o=VXnIjO5
zkcc=$L_*isZ8UP!x)y<!ko-TTy>~p9eg8hLqCt|8GNObuXjzrfFhWE__6}vQD65ox
zm5j&^MP(=1WG5lX%BDzm_Wm8GclUjNKKJ+g`{(!TaXlVg_kF$J=leWg=j-(x$Mbj|
z&*o?feQQf~NMUq4$;nYgC=5vODkNOtmpmOLWdX)LA%RlX(&^UeGM%XH&4x7Ptd&)I
zw*zz)DzgDy#4gTmY%sXXa{aS~>!NynAB>`{a{aALg@5iqEusFXXnKXIt?kvLo!_Eg
zFRq3z8Yx0R0No8lO>ZzEdfSgS1qY2%Dcw>5sJ&H<OxB4N>oyb!yUzG_1=XoP^RO`Q
z@@);cLtj}Ny}Ovj%&)gJP+GDQNES>DM15#eLph{PBbhAIRq5NfKQ8}jy9&_9&9JPk
z<=(&oFS?CTt-qLb16HOK#Q-q(#(yWKqCj((TKN#_6Q3DQMk*99@TLps-m~n8DEeM5
zw$nTLz@*?P8j~Txa9G#{kKrd^UEE}n(JC?9za!E9w~;{lVxG6N1wvA`q1yapnur4?
z4eQI92w^J9k6)^J*$}N5y#6E-CeZE6&6hCl>1OkxTsnnRDch%Zq}(G*RI}mhR|%u{
zTF%pr_bT73C9~<WP`a1&l{&-Cf`fsYMH)_P^nn(=nB6=1G&W}k^Qyo1Vk?^O58uFc
zez^YA>9PDPQ{R#G$H2IrwjY&1rx#p%x9zD7l>8IdQZ@K!eoY4k9_zrf7j&*_ul&>|
zuk3W_qxMV1dp(q0Va)H-X~IoX-gAi*Kka7kGS;f|@~3G@iS5LTQ?v8bvqF1$jRL_2
zlL-hca=vjrS&d7W@pGIPr8~#3Fm6Ju2l`yt1RqU0?)e^Y?__>@hK0w%Bo}4b{6a%e
zO<_BP2(6p9Z<pdv=FYzn`f?0V4aHj2oZ9T$F?PvyA+WMp?}P_BC-DbB^jT+T(QUg=
z@#~jJ=IfS9?IrXXS^^E;R1E-;&{NzC|0!4Wa$U6ROjTL4O+W94Pmfj_#`-_2--{?=
zKbKQ}?+%qay9ASLfX0&OC+?YbqKa6XtqTHxEa)B6U%q&u18y3;*<N?2i~YQp#dop0
z%*Ax8@O0_#DN#yoNow|>W+8X{HosshoGGIqFE6RDAJ^;%2dM+BiKsbWzI++XLxFwG
z#cy@vo?N?rUHXR_e9@781xGfQNGY4Qdz_qPBp0cO{VAjud7C{Y@8z=?PMKk!Ln-5T
zI@?SY_7v|cG>nSBWo9M`-43u=!4f!{+{%BfN5yr1qLN+OK;u}?uI52oj~Kd`k+!T&
z?XS@IcJB36)VH~Qz4#;nF|TvVDk?m=uk79c$7f(<l!_sCUKZ6rUC*!L4Q!Q+@kZWa
z{lDtCGWbeAJ!(r+$fLQgnQ_^&)12_7s2NEOm+s|C0dlukK-e<^qpk8qYz;~y`VD8o
z40f5Em>ydm?Z~U|=->@|I4FPi>^iu?eJa<MbV{Wf=stdCGHUknqHC^yu*tG#DaSkY
zNT?mt+p9Mkm;+-tt4wTd`Cl|synXzsYj`)AY1@1Gqm$SaZYPXtpU1^*Xv?ywT$mo(
zpk>rw^Ypsb$>in@z4uv+>Y^fNvi&&(<%CYwihmLBOwul5!)c~pO<f;qm-y<{8P_7q
zM1KRQD8!d{9cCfjKx>c7KU0O>R>Qd#4Bjb{RFZ17-0f;BTd`+9epB>*T~@MhedM)?
z=CtYAS*oy1gf?io^%gWvkE+T2{U(vTvTQ~;{4=V&=u843N-&)F$HtQka>0jbSshoG
zXG>k8am3_bI6e0B>jN-DEYJ536oJRXUbUpvznc#`OJ#W5?6-yaO26$x4TLxHbpz4P
zZZ5t9++~xD@w(-_CDJwV`tJ?ctSMc+1b$cUk_{jS3gVn1y;#b=vPbwmV2reO^(3Zz
zRMwyd^*+T6(X{SsuI-&oKjwYjiCh2J{MqmXYGyH452iaz=&_!%<+;ptcf0SZ>&pDV
zK9?>)FIXv;-t?;1hUeTkSp>rbEiz1tYg6QR_mzs%T+D-AqI{Gk+8n>p<6(8l)ZwIt
z(eqNH${qon!WJf_5OI-g4o+6h;66NSC;YJJm-A3^mPG0_qYCY3pjUf>pP>CrG8Hdk
zhkVx3_vS*zncOljE_p}{rBe3+vqC!)WawNFtJPQB0yP#VP1yF=c5D|V@Lw|4<t_cG
zrl@q=5+?(mHqYTQ!>?|ddECY=3WQ{%kGtZG29>9rp{B=YJA3`e+tI%Yutd8Epa_n4
zqBsw2uqg9eY&h0Y(AW;`xo(x4HxC?UtS(FH`uOpqg#LCKK{GnBZD^?7uriN|n!KZ^
z*3mNN&(th}4om-3R#aI2`m)!wC2bu{42VwztOkewT&WX~7EWK9Zs|tw4L<0l>kNJ+
z)E?PRWTFcf|AJ4tEiQ&h$}<wT9bfy_{q60M{&0(#xrHC<o)fQ!oK$}A<B0v>o;#qH
z{TaRrZ+FQf08yxPGB>4ynb}BLrz%JtA8TtFBOBkUCF|xTWEE7v>w;724@t9^av=-t
z4{Cl|yC+ATA-Ie$UrJhve2MOYsgG6ae~82H%ND(KA{gRzX}S-(nUTDyq-GP9-iaXD
zpJfiC$I8P5p33fc?;#!qZH=^0kvK-#;|55hIO$*=ch*LiwrO7Scu8!4i^5pvovtyQ
zw=$XM=jYK*rIh-pZ2mjB>hO0<mlg#$|ATL|lbXQUJz_dd{^r#yo)^3u;ZR~v<@MhN
zCiz5b7TOG(AA=<3Etu56bb^WaNvpcI?qORG1Xd|3_cQGf{kpjRF`G#DM7S1AV#I5|
za~{OvkkiScbg<z;@%HIfTDpZ%`yyY207cC?`({eb;3izc*+Hf+E<Rho$bQnAb69{v
z5C8AF<@S3=e$NWV?E-1{rm#)_#Sh_{Cj871Cv7T*)H1+;fx;9;=BDtXV}bIYvQw#P
zz1+Tac5WlvD?Oj5!3WTEvy1vE3ti^pHd!3gzfDRR_oK8Og+Su$tX5`aI^0`%&EhC=
zTw_Ai$7{#bC0+ePLPNdd<KvkoysnCXz~PpuqmV$4p3Pk#6CFy;cN>Uyb>VoU6<4nV
zhQqp%2i$_UQRr++)n->T!^X!~93cCno327QaF8{VR5L32#vq=uLt-$mXj2xtNQ+M`
z!U{!G8zBShR@uXzgFQOFFq8_0iGA$t?%q1{#y8ip2jjz+1aIk0Ll%u_+R#n42e-~5
ze`2GS(}ZNiDZ5W`od~=2@KGYy>ayZ)7CU<Mp7`?MCAKzx)H%@X-jk@ke6Vn3I<@YZ
zRLvu5mh#BLLNTaXti%U-@l?P`=ssFVR|(l`xiY+YftT7%TBrl;ARU}`p#?4uS$-$Z
zfL;akGC?9wvH@8h&)u^1;=T8a6a&EH@(9?j^cB9q>HrdQWMvS@^tL-7A#tK9R6kYs
zv(@3I8xG})bR1z@<}PrSiy{&u<W6v`@Q>5g052XNL%IGQlRLBJ{0^MkjXW3YEpBc%
zouMZC+n;mj(By@E+#IsxYaz8UBxyach^$4w!=9>S&fm}8vWK=5mzR}V`|ls2cE+f=
zYFCw1ZJGRMn?b*MIh>!bi|#r-o-MRofpYeEU5A<oeO;v`NasA1;3)RrCq0fLy*w-X
z>e867&>z9h(+kJ@mrLn1(sg9ECQgmMt-j(PoUtWD?#A5s53-e&s!Fzj#f63OZ&xnq
z0@Zh$v*Cz!C|wKt=zeY+1;v$4G#XzxBxGJ1afd2aL$zDXF0v9wQ18VoMg1faP86@v
z{P2(U4GD?+h;ERZi)A9gO>8XbvD{qCCCgLgx!<q%(R*no*>e(GJlFIH=6@myAxVPN
zPkPhI{z;iW+2ZI@OFaE9Qo;eoE;SYap_rSEH-qdS<$=ImqBCK??htQDg!DsaAxlQ|
z(si&*TEE_^`sVmyH5dJ@2dUaGj8O^S9Vg?95Z^Dne@#S737z%JC0<_Kq;Kw>*eUz=
z$AVq9*jVAiZCq6~HSSdg#JZMmT@zysV}x13L!V!G^k&ypMq&If8nL-OP{SdfLaA~s
zPl-2+e;9yn2{c?w6$x{MrGsvPm(emu$+hm@kof^aTu*8H+W$#=&-X0Hk^J%XC_^E1
zB-4nv7EonCM&^Ewc6{Ictz3IKC~4N@2gu2GA$ix}+iCWe8_WP0+Kpr&wt25c`NVKa
zNHmasnHzaBghTG7)YR0JBR^c$s>IU8epyotj@`l+LM8k1>ku=)5NawQN8d9F-i6y{
zU|#!)A2A6Dn}B~z-jP>TB@}DF=${Be-BdVa6w;m7lYG(H89V1674?{YzrtL^4X`0f
zapuP#Svc)`m7bc@&kXN*fs>B#?rzi815%w8RYG~kR^@JH>lFt)`R(_vn(tEi^|yk0
zD<%9+NB;=^dz+<!HH04Z)S*Qrd8Fim&Qh2a%{8=|_JXP)Q$xh@xgyWGT<PNv16V~J
z$VyXHCF+Q~i}zjIINrC`y8XBP`aUSKv8Az*B2%pfPtE~WI1<N?hhARZ5?-^h+qa++
zbVg$vE_6dT51s!W{&~<=uP#ayMakF!`n^HqWSw_%+_9hx${}TtZG>gl<_^56r~I+w
zABa0WfBW{bW%43zrQJ|dv3b@eJ9d(Gabn}a1&5#5&asZE%+fS$+s!<B%k8ol^h=lJ
zW5eCrMs6pmXVngw>ctwbg~C3S(cpF!r9$F~Hb3S0^A7{ljJ_0TDFlyf+#wRwXFy5&
zT|&Ek%k^m6?V*?5>uBYtsi=65=-eDjMHAMTv#Fr^h17k2JWmkX;XeWu63&BHKuBm?
z!2tdFV_i>E)8M@Ii_TFUJfP*NNH-fIg?LjV&S2)#TlG3?TVHa@eyg6Plf@@zO>gjI
z_@@g3o-6l-klW(o1%h)3FxpQa!I0wXhkkiY&CPM}L(lIb$pMu$O|P7?eiAA0mt9dO
zZ8jnpft;_~P-0>t(eEt`Fu^}8?04q2^ss{E^=>?*!~1c6NVPkNuBpXLf4g1HQb5HA
z&k~ZWJExqN-2*ftb2h5Jd5g1$f-LktWwRCOASqycdr4qF0t`2OJ$a%T3Nh1zltBck
z7v$*0jvs1DgBEeakSKgO>_h3F<q3U3_YLgc1h5wk3Gh0PSXA%{(|!0bLj>e3i1zKl
zV`osSudP)8mGK;R;Fj9x_v~<&0-c#+JHKVu^Q#}HQOyeJ32&SANhyL557Fxd4{2((
zy>7H{(Y!dlYh@-&E0rDn#jI^;)_$&f+V+>?1p>bBDiZHDaqb|bAnZHuBy?w|j-?WU
zRw(lEb>H=JA{m<oLbJT7iMRz++o@`WgoMDp^c8dKzXVvb+0G_9x3+I2W&gz2mBnNI
z!i=(mN>+^mhthjixRctm<<kyiSO0V?);R-)Oml0Q!#=@=tLo~f(*;cr`br9y&P9$n
zNn0inEXkyoFDY>6eSLkq*x5aS#1f^;<%H@EgJkU@u~!q?&ePY5(?K3q$YbNU=SN_-
zO3!jM_)u4Nkavox)xTHRRI_g9d2xgnlwq+Be}ob?EC+A=hs{xbt)q78Zo#i4J(1R;
zwdQ=$$7>aW)Az;rgarjX@V+5s)!leq+a2ACz@R0@v=tTi7?YQ?r878keoY3f3=TRO
z-%5vCnoe<<TDDHpiwUa>KAg2{W>W=9+o%vgVb#keJG0dkJyd%|H@;Hj(Sb5}^N{4M
zljFco#--Xh(bO76k!+2F53GIHB^G5|v0aXI6nvYLb8?}af`I$n^otf6Q;`LQnWVqk
zJ&^Y=E&$VUGKgwRLNgs(o6uj)RNZj2-dO&2PYH!Kmtz_L3w>}x{JQDVncnV`ehki&
z=x8gd9+tZ$RxH;nKF1q$9HMt2HipouNBMFqm&_MMx^&ePq=7p1v6A%KzV2QQRGTM^
zkb|yHimyJvg}mY~C=>{FJA3dx@%wQ9bA)#d|F&)0?#d@~QZgE?p=+`2j#=K4EvH$x
z{TLX~pX{%}bw4NuKuMrD{kqnj8@)vcsK{%=Abp*!3gz>#7GGX2E(+hBM?5aS-YWd3
zD;x?m8*L+7F1CKV=l>d86SXa6k|XVHKXKEOhMh5z_ZGCgH27w7M{9O^1eDc^FE@y9
zc`UDB;<P;7OfgVSw=2QgLMsw_=5B6oY2-c^8I4PMW?BZI>$-o%(ZE2$va_u(N+O2P
zUX+kf3JeeT1@Q)`Kb7FO+ovL-JwqVs=Oy#~(S#4w{QO=qkvj~c@s3tg-RqoITK6|B
zuyG9Ls{0TdyI#IHAw%-qix=_nl)Xc|j8w?k)_JAgq&NA~j(<g(wWmdgB|H1<ZGHWH
z(1)<<{~UU=9Hew{@#jOxyUAG`FGY2%<(m#QpnXk08RDQr8VxTHE6d@p)10D7$Zc!p
z0dXWsRw<5?<-29kIZH1V^dr7Enp1+O>YK;L>^YSmkjB$t@g#J3efkW*Po+=tCJ5L-
z7SZ2z9~p~2$`)>Rw~BLneGaWJyuCOxg33@ON3`>ds$bv1rw3nT-jOI=Q^}8ghEPbt
z$Y?+Om_+k)2(f~Q8COss`YYYptlt?%SS328ERk2d!hLe!+#6Bmlv<4k2-<tpe(rX&
z!O=w~gM!=bJkgDf&bp8obc-LEABe6*J7l+-wqxLbCH%#LlYtZsX&p|JHE#NZ${Q5X
zo@=G|KQ@MxD-nuZ%sDRupu9VxwC6*AO*o``{CawNo>xTXhuU*^1~~DKi8<LUYQ6Xr
zOjTPchZT`3Hx=yjmu8y~j=%g`B5tmutm%QK>+-Z#>Q41$L8Dq$*Owd3u+QC!!qI1i
zocKw%+W+{y&ro(jKtw>XiUFvQ+;k5Br$nUZyo`0`Vy|G3M3PeIsYP30|MRTpO*K2!
zEeg2qj(kh+aBKDC-DTh9oCThf-EHPahTr{e(Rq{1r`7owMPj<d-2$!cvc1+h=sW=u
z{a_oHl|_FCT9|}_eq3puzv)clZ`;9Jo}IkJ6dl8fzFj36E>#eEyIw6#4>d1}91)~K
zO_&lDko5FpWIK&|kj+cZUi0NlFFJAMj$9Ed#0HSQ5H5ScGUS5HKWhO;dE}>0vUmm!
z{-81v)Re5eso?Q})2G`kcw}a^>@++BK8I#~FyfIxGe6j&d&c*DU73$wZ5_%vV;G$;
z%BQNRNQOcb*i?r#bH5F+nff~&{-%BKW$Kh%EEIx?vt(6OaO}3adiby5YTK`L8@6zz
zi)n^_iQ!aB7JL)KS!ftj#&#g$AWBrPUb&>pCwDoH72MNiKdgQK0D!=$P!}2g-K4Xg
zvV)QFZpW^+9?LVy%K9C-c4vjSSI)^u`4xDK7Tn68v|ciQ$a;atTZ7L}jmJAnK5oOE
z7u(5h54ZGW-9!V^E(mtY8;Dr{xNv56i+kz^2JH-Ai3Vu9;Z*fT6+KFKgt~rU-~-LP
z+Y}wo=BT(%BFNVI?kbLh&i`X!U(I!%Eo2ByKmPpV<r&~*#>^{7-(L+^a8y{>3k3x4
zk@cjg0w$eMg@Z;n**)XCagGJ*oENk9a#2ctnnO$LS_H~LDRut*1~k`6G^gD#G(-=A
zPm1eg0-Olss!U#0A?)e{KBoKLK<kUXbT!V?xK!Jvf|OE-*t^vmGelnF?3x+t@`E;(
zpFTjqcGpK7q^T=hoSvoYl9h+-^hXGW*7U*?W_oSv9;7#Ew<c*M1DX4(ZZ6VJsWVG7
z_v9EIE}tpfXNA@z0%GZ&gN`Cviy0sI7{_<-^T)djdcvK0R_@ZJoe}n)0S^O$KPu9N
zB>~_OpDU&zue2X+uQGhZ@pvtG3mQjUk0;7EPfAwgAtb(Y4`hi$1fP%)atyBt{#<I;
z#Z!VO^UXi*;^gp$XMxwxv4b@qQi=$?+zQ4F4<fpSD)ek_adENtw5^1H$y%-^>oEE#
zebdH`5*zl!2jUh2LXC>o_pIE$g0H2k#=Yv^N~pkbMIy-sW!*RBEHo_<bRpq6FO$y<
z8~_!$f+*;9mEvW^s?gT_t@<1|$+`^`wp11q^eUG?0^{2=l1?h(HYU*-=1$|q1GoaJ
zP=u7-VMeNZzUrHk)G{eCwBqMyX2~6E$&~CZVou1d%-9}gbPynqdj6~L@rp3(Hrz{G
zX6Ci2B?4G(>}S`j6<PIbF8`E}GU+fdo2(_YDZ2K%_`g!4peZaL<VQf4+L!AAZPO3N
z{2uStSzo`t6YaRDmQf7Q9SHi7tPt32=YW*TXZKpV!>^Bi2K<sEbu$l1ybY=#ihT=m
zuk(?3XNzh3CZ?z|+1Aug)mHNoKRfr$PRo){RCG6Y;DHyJt`ZEVNZ08D40b-D!CPv&
z+Tb{>T)k+^QhM76UY^!@nUrgt_y1{6-m+WvcqH*15z=?|p%z10z=5AXiw%x@n|~Vd
z1KM!-8WT)E{Zw}Sk0U`Za&wshK^=SbkFg=i<eeaioikE%`Cs6Ka)cp|x1S<iVAaFn
z;bETZQv5cgnJgvcHE||5A?IZfU4yd8Fryf-20OMV6DegXDfL_y-{!gDR_1pT9_U+c
zLB7{=Ugq+RYX6rD+H1E<UFH4p^xEx8Tp>!+=)a)mf_@J%ALOnEk#47vF652uq9wz~
zuUR#{y<G!R_D=+#5;-mf>0J5KAY~_lqYOO&9)Hv22U<l0WI{>4wi9B>{z`7yDjz;^
zf*wLqFQ(OrTh%800>wvIE*yq}0?oexr}LMgEFyR9Bt0=@K&t97QZfd~uc_=RI@zxl
zH$ULKLNAePFXcAU&upIy-*IIvub?~-^nw(#5kEtE%7z{b<-^~m)v+wlYD5aXmJ|L!
zq3(XczyLlMwvqHf-EI?Q(^ErPFkOmTTHEqE_=H1vVmS35>;K9U0ay{c{qJ4TyJqOc
zq;y$}yR?4!LKafZB^-^<jj2VK>eST%F<>D7d%-5mM?ji$>JS=R_s^J91s7EwX|TAe
z`?JCf?;-#LDL{$Bk}r#|8FVj>4<Ij)Qadaw_=%8PBT7~2L<$vc&mOE%#P=dMu3Vc(
z=9N6J(p%E@VK|HaXS|6u_(oe<*#njJ3opMuub}1(;*`7QQT=k_^pzbK{(gt#gBU2V
z5QyQBkGt6*xJ9A_!sl7P(^t;PusMwvKMz-nH6Y1m^2kOg>_;6IC5B(~`S~I^3&?9W
z38Y|S-=S)N72SYEls!Xwgjk{yfySa*9|ZV_7Lm;(@g^g^@bZ6<*AQB$Nh+l5f0t|t
z3~0~a|N5k~=bl>f46`gMRO{pFVOwdpa>ay_rZ6e78Y7@pPMl_zg)AWf@JwYBziUeR
z-QI@{gJn^ojygwoNz@JW_rrW)V$+FNR(Kyl*?)h4>2D4_zTI2mc)E)mhd;SM3P~CI
z(j~uN^AcOQ?j#P$MBE)pBakP>e=TqVBqkJ*05h`%gobW`?!(uAF28*k0H-l7lrT<v
z86Q3V_gz%7ZrcR=1oEilnvPUz^Cr=_AHct~w1_PvOhR;c))DGniH&*=4l0%k2cM#s
z7!xDNMa_}yzf()DQw%V9YTq588sdKW_SFbfHif>k-Qd~6#YNg!TS|7b_3{QuK=AqX
z>jN(o=^hl{LyJDAEl<_B2_uk{4<<a`Xmiok)!lk<ALVY+F(HSR9~!VF&&%BNJs}HU
zp-aOhQ{DP7^=Ak0q*xwOq#yL$$=&nf{{BvFo+^~yo&;wcco7y?ex1jgM5{e7!?Txk
z4rF!Kj#RCQ!v!=4UgW+aaZV<su80OzBMMckDFh6JMCKaMR*s%kcuxtL57!+&+UkuO
zo#T-K8inp9ydEp>wb)B3V0<SV-L21}=ViR~NWh^|04y%ZdeYaghy0pXGzx-kVE8+<
zDc~w}NU<$hx9N^o*cz_=CsEQ~2zb^o_z**$Ajc~j9TKt$mUL=r>UkwrQ0d1SXvPt?
z4t?8D4>HE>kiM%*`mW)2tR=|T_2W-K{R5@s7_osFq)9ud=IDPJ*9!>PN)+h0f_|WG
zxogn*?34%===<MKD?-Z!o)8WLtS}(cZfwohTVy!g1M(Z^IRWF-M(Fcwk)$WR9;W|^
zTG`mxfPDNUG?Z!0>Jf-3kyE+B?8O*ob2d=`2L>vP*cQ{MHm^WtUuvlnP!rqiJ1C87
z?}I#3^N?<)nk0)~R1_O32}Ft%JJjIxsO{S~av)pZhaa&yQhUnJmblCvs5j(c(>OkK
z9QXtE(7Q#6<}QrpIs5wR-HzUSJgmZNQ7eNKib}C2MX2pPKtWM*xbSb3RGGe}_4wv_
z1)ArH(`~$gbV|JP^Yfoq*yd=^_ua)_xcpRC_pY*HpHv(0T8F$Lnba6g*f&Ve!W9NE
zt)<3Z0rx-=sTPKR#Ke{D^5@^JfjUr*W7Lf9e}o-~@fmj=9VNpHCXJ*mUkrBDx2;^k
z?Q6Y2)!$<=9Jh`jhGFMU$VstdQdRwt#{rCgw?Bw6V|Mz(iohf>EiEPkSi<=c#7Kx=
zpO1y2Yy!k4^?)zR;N7c2E_Ej7^hKVXuvmw(=jNY`4}LA=0p<a_EY)Paw;L%+=DCk0
zhkyqMhdvy>u8z(be(L%`Thymf?e;Mb8<B$x28&XHo=4m+Qrcqik`-=QlAgJ*{6EEY
z6%yiu{i?x-@p`^W?m>r1`-cl-&Gs@dFgyoEJ9ZYa0rG5OS*W?v*8mgPZ(VAxlc(FG
z$749*1CUFqB?n`-V%!dK+O`+~mcW}tm2oo<#c>S+ltU<vNR;`F-qBrYrme?Q!wntd
z5S>Cz3DerVC3>w!2?h)Nm{p7Ik=kuwU$0yU%Q{Nk)n2&sq`Npn2SdB5Akj^nnJKWb
zQ7M+hz6d%)P)!y#8>HQQ67y$TIIgtk45;oHFY{S3-~dkTUl<|i12O_+T#A5YG95n|
z9LE9c8Sg2L^*cedo-pJWBYN2T_wL`I&<>pP<0qe*l^alJMusm5>T9=^R6@g+NCiUt
z$98-ptVQ8pM|GbV)`l7j5HTgktzQXMY~(I?oFnStlfb@%^Lo`y4S%ayMkF~Lwcwb6
zk}$Zky}SfW0m%kt{hF@6e*j_vje@tKxrKP>%SDpO_A04Z7LLP)jj$1BZOOl5^QD+&
zR59TG{reATxN<U=nBW8yN$*Wbg_Ibl`knA#&L^OC>@0M3bDHv0nO2GXU|891^34y1
zWj%=j<;8JsE$2NmWmPdqZh`Xtoyc;zAjJUpK~<H64o^gy@O06CFD?NVS1(#dux7ar
zFyYP)sbitxM0*S;Flw(M#Q;(nnw>G8Do_mOm27SMbNH+$!J^pu-eR>a?d@B0G#>Z&
z_dl<g7Vw>&H;V3#3{khlOGo-B82M-4t<DmDu(A4uf;d~EsktzOg4j|F0tgeZ2hX5S
zl)xF_uPbuxhIF#p9xyj+^LS4W%1*ssWkBJUDre@x<WAXG<wQb4c&g5Wj^*!-9Q-%D
zo-2744iB`LG?Qk&Y>kwAl?Yj0IHsN=AOve`_;R;}R>fYDW0E))vxW`=SBAi@Xe|lJ
z+_QiGCgfCSAF*8Esghe9yELa5fLRP40iVf82AwA!jUY!+Su80zS9}sps1UhEYnCwU
z<9n4;J7xd$RK>~A%hH+ZP;vd8XU9MUM4-H(NmGKD$(4UPsLWJwlfdZ3&0Jdq(%k7b
z{CyA>)Wcxg5gx(gLzn!#OuP<{%pcP2G7xy36pX&2E7(8`LvQuZLE{IyR)m!ZD#MQC
z3qgKyEXaToJO*}Rc^Rz0V8P~<nf3JIIE089dzt9bQluk8DTC;xIWGfh!MDE~LF3SY
z1I3_6;y1_#5OzRGC;iSO>Y5je6$5^d&IA(qi`?fy^+em~;qN*`sg5rM6S~L+%-^~b
zP{tX{s2EOf-Ww5hwuDPjT5px3K{RtA@c(s+*Ztf&Oy<j7so807>6s;cxWQVG2wr35
zmGY4{v02!Q4%+S3!l1Z+q~eSl<R(a-oR*6d>x^PWDm5tfgqN3WE}H*}$~J=G1+Skt
z0|XXT|DwWySbm4N5v6)Nhkut%=|3O5yhIA8B(@|YoIe$*@U9pIG}In>4j!bubrES9
zTr`pkuc*J})OEzgCWu|EIb@SIyQE>eTZ<H8x<z@v`1N-OZK;ECPH4E(p>i4$7u<m|
zwpYxx5eVS*!6-@8Y1_*kJ1!XjNMJr=pF`rLOzO}$fr1y>GqCe@pjw@xvXhXphH5kJ
zHml3!GzPm^{`g26A?n!Fx0J45Nz}YPhY3)DyIg@P+Ir^MFq4$~QgQeHQ?9)eA&ye5
zLSgHpd2QL!9aO;&M;5mv{4JvOqO!>z#rmO3e7>d6359u75RJa~GLXC@&miCy!1rDr
z0S^~=o+AL~YECVkzB9{ZK!j(-gAEA}w8o_U|5~hofTE3wFJ6!%@f!Yjee=n!$HDdb
zsXb4F*&UP2Fj+7*-1~~D6+0*vKEi;@Ac*y1@w~)@Ja-^mBt2$RVpN#hB+><JK-Djc
zfdHNKfX~52yAh>~xYZ(-ag;Lt?bTX?;@=h(iAyy;Ir8@ezD9Dg<{VW@vHm2e3iOS2
zerOlKX@*aNmKU$^D)z#!&cq5ZvLxUli=X<YPS2?gPbm3_l8jH#6jlR~6cGS4r%X>x
z5r-cV1+OY3Nn`bZ8QNaTu-7st_z}$yD^#po{2ZJLYzM#Yx^|9)*>c1(fep{1oOsQ4
zB<w$h7CVbh^otN?^<#B4eZ*pT!@8k{r*nO-jlCuFHVtpYH5A(Xx~GCXlGD<T5|3up
zn$~e8SK!rwn<z$c#Oh#bDDjB4=gmka1|f*=Mqh_MtrN{nP29PLqu<m$>kF<w>S;dQ
z@Wwe;Y;~A^N?k;VybjzN=XVVSMZ3!t+67EE3~cME?z&53?=+@9XV+$vPH3Hac?AUF
z6ocSG5E+ENnVXrp6UaVOme2&7tTpiV;)~i4yy!j!WwIO%Hd`Jl_v;#@i*-lO>P@_z
z&t9B(di0sC!>`JAyGY`S97fgvfbEQdLL<0B<bcxqIzJ}FWXN|Nntz`>a9LToUn$N}
zG}>`!eY&Aw81j-mFYOID=M1w@snp-<%k}<5<b9uTkD898oSH~+7In7egPkkg6i$nI
z6c>~C63gO+phfJwjHzJTyYn(-GmgHud1Nfw;@Gr-si68p_5qYu1PTA3@_L6qA>F*C
zL>F@*(XN-yw~y1RK26@NiMvfD>~W&G6Z<E1Wqk(+;oLPj`1*f{7!z7<NTBOCRwHMI
zpw3?R0MwJp_=A4H2<)<9ofL*bL-)TR<oeD|J_pU?{HCMv{Iuoyx|5AbIXAkvOXD{&
z_PlRvj!j6|f9mhGuU)?E2ARaT7cV3%YkMsBAeIE<2$y$g`*=DahLhkWVV8<L##t!A
zmR>Wd4v{A>PGzsckUVeRTM_t7(DXjPiMibI%jq>vqNAyYi|H?kvGsf+7T-7?#eN`i
zB`D_mhlU;y?rLlls2?UTZI<c`gcqsxke4ocS*)Mjej`NFLwt3<4zQC;c&$W~ZX&=p
zgv?3R&w`%`m=@y~YzFG21`Ao=6*!U22ATiNB}lv+KH0!*Qp5H0^v7)ANHbd3vo#d>
zXEom1p?PAKIA_N?Sb|Z?5^ZL4nbU2*JCwYxK#Z2<Jt^Si9L~+G()*g`{xwNnStW-x
z`r}4_$Dy$2@iA-Dd(UBfu_Ah>P!FoNGseb2B?ws>N|0L}G~hB48-Je&`e9!&=FTeH
zYgU&@Xq<T{na)_gmAKVHlzSioi{jx!nfp`we^a;Fh6`kckIfx#3aTyr{>bM!hcbi(
z77!>_R8|I#($Ln3AUG$SF;U+<^$wa(h{Dk<vQZ!<RWSgZ(c%SLE-kZpD+EF-Ga5jG
zP!FD3xEp$r``NXv2_P(?a?1{iC_&C8(Lj&!^D}&PfP-dqCcpghvV7LJXWq9;8B+{v
zc$YmWS{AZd%V!ySTZ4^C1o_|<Y5k92&50S1f8#&sHDKhYi{gO+;O(#s&mB|M()_}N
z?hogn0_Bua?E7u_J8Fq=ERcJL+WDztEQaYS#H?lvpMs37{Gu3qJ(eyu{Mmk=S5S^O
zZ)#7`;3>X6Nj=wkB5z{ZHBV@`Z>`(J8x=OR(`pG-MzPA$U7T@)-OtL4+R77T@H@%`
z7^}1&TcpZmR3kuS6it!2bZJ&4aetGrLNh4f?@e2Kg>us0zh}fTPf&=Y927%LjRC-C
zl$Dh)r26ety4k{klTZ_7bHIl!xNo?<d1Bh4li{09DdFfO8jjtu8Gh|YlRGO+#TjH^
zeMP8aZQJ1WxXk8tA&9{o5+=-ZNP7ov&P}~!j8*dbxK$lp-5-Xk357h9dSZwSjw%Mr
zJapM={nks!)ZZKu=@pvV#lQ0gbVib8TSjJHwFeSMV{>-)wh<z_9r}XdAPB0Er2qN>
z@{|-Z%WenYY;l!Z^c^-Mpd*u69&5dvtV}hUP;dMsJe;cAm%41MKq&uG8sy39Lj@j5
zJs^N{ffDfCWBtMxG6>?~Mj`)~|43Ul+VVr=zm|1%vsvEiraXHw9}A1ZeZOb-6J{$k
z88csp*o?5YQgK##SIkjD$kEsangh0c>gz{qAOJJM&e(wg-ixI~Jmc`^RizaY4w#Ka
zCo_!FLfXf{d~`jTTC(z&w440Q1cW?9g@y&A7R=Rz%Idp&V~!+ZXK|kj1aQuME|E0#
z;8jLB_pp{AyS;cJ-NwLeG|MV;!$*icsKhz1=Gh<Bqn2g9d-(QZnKGH4$tP}v*w!n<
zUe8rGkU^6&^kV-BGD+@0$s4NvEyH0736po1{amKvE(8Z|=lGgd{#Ml{{Isj!dy$1}
z`OC#rb2Ii-*;T|q30ldgj=RGgMO&@{yay#>qGkPafPC=!VwKa4TNTj6Av$3klZtuP
z8S+VHz6|NFT%OAQw2435%4V@uvW4ZngYo||)th!CLhK(g?KbqGpxBPs&CSkOFOc$7
zWbK$~^AANd>e3a*{ez=T%qdRM%p=oqiul?^?%~*f<g$EQB|GNgF<x-f=MZ_nOGekM
zr8imCrn*qxL!RbviCI=E<TfrPt?9wXGQIlC0y%i_&z;E9p7Hr--3F9yi~Z;S#RYI*
zk1$%;d4V5MFwweA#Nd|EXSn&=*X<w8wCmw+O7o_8eKFIZD&Rs;;L(z%v~rV-{`Z{w
zcC>wN?pygpCo=J)@2@L1+=Dy{H6bWVL^p@l7#6jWT?D-AkNP-FZv7WJZEAJAeiR?`
z&G(*3-x2J=+X(}gGielOtG(^Jme@T<*(__#wW0OpWfm@zEJe+8lzX-WtCaS;BprXE
zT4ed`w0#PAm1p<Im`6k&j_*k0lFblQ)%|Jh#K9slnrtEw2MdWm950cCKfiGbW&|3D
zo2x}HMF{syWJ<+_Zszm04JvB8c3qQ87&;R}vv$R%5t0AIH>PpvW%S>k+^t;^_VtcR
zp3>fyp0#j*hYnc`<V!XbY9%zd-*77yEe$4B{E2;=ypE$vo%scN1J#fExpOC~#uOg)
z$3soAFzO8Tg~ZK8ox3VJesuKUidNFvoSIlpEQ!^^)J-IH-iBp8mLJTsHe?Ia_nW7{
zKcd3}{aN)*O@bqiSwLda(k#FCU6e+j5PCpG9y2|Xs(+M0a7rPFAd&bk`{{8pF)_Ab
z-+&m^@Zkn3*Ge04rgJmmDdlx5`r4#Tz#%IO@+yFi?X1nl{BTB<K06L^r+{-mz99Sq
zWjv?RF2P1{y$QDT8vSWY`i(PR{3N*5(JGZOpy3ni`BV7xtew+xxRB(H5PQOj#)cAO
zI$tFw(z6PM*Wlu3(C+|j8ok}e`kGU6D6pLR8G@}sqYISEU80*zEUqbBlp}Qr&JoSN
z%#XOchsv4rLpi%Wcw4bxL&`@U{*K|w?sM!aNo|YrU7N!JShUjMIK?+FLWmq4luEC7
zTqwS!)dU&VnEkKN?djhw$TLV>97fI9)HFgx4z+utCkb-0|M>Y`O1c?dwdC>m^E*Sc
zHxC|_W=}1rcDF{a9>3*yl}PX)4B}$gVt5x%%_7%e)%a-a{GIAs^}Bn$dEOJ#(HVIX
zUc9ipf1I|Qx=<X`%N)#FT9TaiE($UUil%MO>L?U^t~uz<a|(?}iV*i7I_~8~KDQzv
z(ZlgQZHGkxy?AHF26oq}o9~9a)&DE@8M5};40zAaZi|FO?7zM<==z7pfRBrL^zM$}
z%Fg1P*%ii-+}^M4^BGFHM>d%qVgDfdQoYAIM^BTk{-0~w+B6xhtpE8@&hKe26B6{t
z`Y!eU3P1m`T3NrSUw-LrKaT?SW68Y2?5qC{UYL>atAw2A?}PIt5WA)u+iACqFME5H
z)ENEp0)?q4Wb8u~eZoX4#VM6rmtrP5wes)G*}nVjt1i?vaU<zKq-Q3}4s_HL@9abg
zMnHfDpUwBst9M&hv=`6i^_{|bNVQz=+H7~Et`WB5*+J8_LZ>yjt2klj3R~4eui64N
zRob-GNuRL;Wf{D6Wl(^BApmL~D1!zD21jo^^6I4|uJm=ic}qLShE6zDQl%9vow78g
zU|W8?qo{3`Z^inyVah<Rbqsl1jZn8y-EhV1>PRP^Dkx|Te)IBo46L~TNx50CJ_Q+>
zP+=ilAKXHSsskl{{`@%^;7a($SbZ={;tC7dNHNiU)C9n0Kw#EaxRK)zZ~NG#iSaQp
zwp)8*kIZ!lx3PPc-j5EQ=@k#(*3EuhF5SxU6r<DpAIruNMVHm#=n11CE{DQCdo;6Q
zfAZYCxROSuv9#wMoGl7Tn+W26WzOTrkJI?AfknE}=mOy&2$Sf-Yi@>PL`n-<kRJLj
z5HpCe`~Myttw3*0-~0c*7jn^3!KW9wOGm>zCq}<)Su(l5ZBf9YcVLG_Po#JhwY2k=
zpDgyy6p3R|4>Ge3LcJgTluDO>Bh*1-8ECk%E@SAQjAmCRgZd~YHPZpmhAfD0*Ysf)
zK~qe0aXr^~MxvKvdWC^zb+j*LV{GWH@6_SpK%D{ODntoC@+{Q$6c@8wM{Qr=cKwu8
ziJk95%Z}gfilXnx|3|{cbKpNXB(3w-uhC~p$<Y8qOs5!9#Tlb}vyo%r9DiqYZ%>!A
z$hR~6SKO0z!;{j|w!1nEUK5%9JozDghr`@V$oSWc(i4XJM$4=F`$j9Tm*{-$iDAE9
zft~XZN_*x!3_dC$$BLJGOr4xqVGYDm8;$wV?nsWfxySYtWDj_<E6^2Uz?rRWUVffh
zf}vwJ!C}sxokn1L4L|M8mUhIZ6TS&*I*#+xOj)$EICSYh>r;D2XtX|L6{&x~)T4kh
zXf#xMW`Mi#oERLX_EeSv<rH-6kexxFAA|w<7S!ix#Fvi7V7vVC@pPS?P~1>|k)htB
z#*EvdtRS6#_w|lBv7oG^it%wv80*-Z7=g22IZ0)&aG}$@b^Va*R2;iEn|9vq<n9)D
z{fMIi+m&p~ON$mAUfnm2_mM5_7rY|WTl;^w{@Cpuwhi*Jl~=A@k@TznX<gs9*7LO3
z*0tX8&mLm;{^xdfG(u}U6k`|y{<&&;Lfdcgklc7#pkE~vv?+^23a4H^Pnn%L+mD#?
z!Y^hop4@-GnerrEn{XLuy&=DSxoG`m=FhtJE4fdHzI)MqZqKpN*F2~3?TkeIj(=^K
zgZ<Rug!^}yxJq?b+nK6W`*M%WG|SwLn)(-8c@89LJicV`;A4RuHS0F%zn&{rc!v;m
zc-zHRuf_h;h5rb=oJ_kNw;n$IueJB;RRl0#enNNOD9PViGjv_?GE$H7{_8y$jC$Ye
zh98C~PT~J)8i*K7!isY*vtX7%hnM3_gq+e;8mrMj;p0@-Np9iDT9uHsk4RYUi6MPv
z@&7nPYi^@l<(#0Yc~v&;tX<;HbJJg-%35I2(`;5(PRNksk59})^A>Ko_($10kA(Z>
zv1@O6Ami!jqQL~aPyFGL3W(RWkqds5Jy09{h}X|$hlT6-`oiUo_2zHU)&fv%1D9rL
zfAC=zD~rSOmDhv{X@2r19upB^{nrJ2E@Nj`>T62yXKU~gY5_)>+pec(um2RAXoX{#
z&UZ*BVPoa^P;|a;#r~*s7)$uCCFZ&Co$38+I_G_(TuiT93=7$2uLnail-<wnB-uSs
zSzk5&RtY&P@#Cpl^5c&UTbx$+#X9VKJuB{0$aJEVJD!k8s1Ox)_+_8{GljqXm6{vE
zxyszbMc=6_(`;R~MJ@SBL5KKNm#c%ru7Al#f9@^<34Z|b0-46v_%|sjQg`nzysPM2
zWT)lwu`F6u8vgtXhXmi4u88i<dB0lH+{9ZF7R#kF{<B(NGx$=f$Sm9A-78y1iWYbc
zj;mfBJvsfrhh>$LRw>`wRmX~I`T<qfsuxfF!=YtAJwNI;PGC8!ty4u4D(80xFE>0@
zx$=%2E*O`(UTP6l>N<Av{_3RfZRkNrkBVuDy~>_Q-A-Gc_?lg%ef@HG$*ees?9~S6
z)wsE0j~ZXp#Y7gKv4v>3tn=YuGFP#;OOm6T4$0tK>b<}2U%{SA<;?6^cih6AMbh_g
zo3_(!Vi6R-d-v{mL*<l1+^k;<;G1jV!8+J^xD(GyN0xTiEgNiZUCm|`U-WZsVDn?Y
z3P1$HeCs~o7Q&QTvdfE@0_m9ENVNRl_Up|@%?%9?ApbhfAT1F@);{J)ysc0VOe^<0
zVS3hDm~}4n=8=_*L9!LAOa_*$gvx7Ys!qF#`0lJRnsALWKW}K*|E>a!1xP5V_vw1`
z+(ZNs2Tl$uL2Q-tE7B5GwQY;+<v`^3`V2hEuKV99qW<^3c|0ufYE$!hb7`g?P!cae
zNq%<OuXhv6`=h8ERbFCuBsUTh-g2Y9F*|1uZxdHfpPyK{D;_)RVBsTASG~>E&pO4j
z$N#nd=a!$ZEkA$H-PO1j{ZdA$37oUy3SEtbmFwffb*@bB<=-c`SoUZ`FXZ|t&EcK}
z(ia$dT<`@*e6O2$Pix;b#_G@)!X7hneRX#e`JUNLA;?BO%`QT(Mh)1lgxIU`Wk0W8
z%@>`kJPRC6X*V;~!0+<Yhak-vwXm^D3S^-ZpAMyV6C~8vR}ys41XgcMXxR}uh=-Ju
zyd-jHX)j^24>N0Ns_P#<=4b~>6y}b-zQ1<D-RQ4V6I!=t&)%=If~-TDe&yq|Z@c6t
z(r9NZ*`0k74s})(s8>%sSX{aOZ45%Y_*3j1?%YDiFAJKG0UiNUkHy`mgg~wTUqY!&
z=6;xuug)ip9p}kL4|Gt59CDcnz?eq-iODu@!HfY2bg_<4qgxUZ1%5h`{`52~Ry&pX
zD)+xV`=c{=<2KKIw`RGB&&PI`NtP;KyT&El)Y7sURRxl;K=C|ighWX_F5m0IrAw7Z
zqHdiXOSIU#D0figwabR0q?0~2W6Qh;XN%?^AJLZ|6iMoMbp~@Su8tBD9f@bUQ!2>M
zPY%IetBYu~1BLj4e8H|Ss9zB?BpgPNhs0ji=Y%-RaLS!sW7{G>6fyov)1KsZ(VAfF
zobPM(>N@?uaVQQKapHzKC>1`lyoc_KlI3vi=`m<Hp_`sGf!pgF0~LxA*u}zkdimKF
zTz0R_eWT!SpQc0*>ix?(^}oQS*x9uU#&$paMsybIL%9TfDny2ZKZ-!;pv3&VGVD~|
zMzZRVBRg5u-x<?FFQhv&MuhQZMk~g`(*=wBLx;ypJb&t7lw<#$?iNZBr$sr3!B$<T
zrTPTgoUY-MA+f)7PuA8t@77-Jmj|JYHiu@-n^5e3<za@951<tA0Ulo7NaOb)6e9m4
zgtKzlYIdf3)TmFnDk}$fw-9BGTx|}pNh<Iv?vMOz-fMH9-m*C{O=L!)tSQI2FC|rH
zy2B=IMwx5)wxh)8T8&2HK2^3ZA)$_DRC32e`D^OxR3Ii@Nl>8RH$;DJ4#8P_b&O64
z?s`USh4XRY$%px-0y8F^Wk*aN_kQbEX&JNoujo#fJ$h}Yuit4|s;sHWdy0j-0;NIQ
z<d!)5E9{ODrYlSHZu;I43{04Q?BjZ*>we&Vg+6U6+q7>{=lTi?940LtjF|q*KQ^VW
zW%E3i>xiMc^0tQZ*fS7hL7a@n4v1v!;b)frAhbHy=eHsCn=c`t`KuYhpLbZo;(le0
zg8ysaM%<>}p64DTuM?u^SR0J_fgqyKvb-!Ep&Znj=OehnFDB`#zcuh~9!kybr7TV_
zTKaipUB@9+$-DbTAH5vR{#`K}lYc`1RLj!i+@!b0{oF&|^tL=oXay_M;tNW@b|_uo
z$f32LF*|O0SBKU-&zTpdKVBO;W%xr;W>Lz`*qD0xbw2mW^*h;5{$n)3HYC2=|GSr?
zjMTyRp{bS2Pq`d=t13&cLa`Em=6kbr=^ag#4r{r-Im6}~K>#7oQf;fi_)m4yM{mT-
zuEoz1{%{PVORYQ|ArIb%&~!(AO<o&X0<cLpV@Y#QQyR+eMH?2?eER|HP{<uV86X0n
zJ{AEsqN-OXMvF_cR<~ufKlNa_CU?|+Ww^UCQR8vxrP*G&>j}O2lYyJBUL=ljPY@6g
zkbuyLdNxLJ4@S{8aVgz%`!0OC9nD9$uMx5`y1hGj)fk$>0#t>CdbP4{oRnQXfB(=<
z%2jqkDM`s`aB%ScTH~jrg2FbSnb@95)v;uAW-Vog#bq;>!Vf-ql;NEGfd0gB4yTAQ
z_LUxXH|7l&9;>VlZf=%p9~3(LfkxeC;^n(L*|xVYI=Zge05^zM;Bp|PL7ipZ|M+Oa
z5ax6he|;%OQMoK|Nbf!?Ec$l-n@I26R5Q`5;#C_#VZ%$20HoGWEWVN}MEhRs1rL@c
z&E4ZB;sxXOtURt1m5X)7)6I1pDqO^ia1Y1Sc9i&%s`ngO5;VQ%FexA`{40G^n*ms#
zvM(=NY9#3<rlv|`Zgk}_(1|XDv66VjqK{u+J&2j?bBChc#)q_5nSYO{Pt4YdOZF7G
zQYQ-X7Q-fNocexVTzp-4x%;)QV>+O8KRiU3<JdDA!miu&AKP1v)=3|`JM4$1RVBYk
z7&YZYMBKes&(x)ZwYFsqATs%j50PtpsCdLeQCTMV+vVre>*STA5Z1jncK-eysNGJ4
z*tnK!M@DxSZMBH~{eGuTs|k(qzR_v*klxx&tLsu%|G4%nwSH;fAr2sq6QRK&S#2TF
zpPM&PGvYXrnZIa>eq8QaG-HD@z<sas^*zHDi1ZOQN;m}roVB#Xjy1s4Kg6t&)Z)E*
zCrt0n#XSafADw8@m_pIabXsiNpe7V~$jGO|=`hMWM`P6Lu=BLIzWE!5goV@Tz5R)n
zi?gZaZb!67Z6Z!oil4jka`(-|Ed2=|b+;pH%2XV;rdmwW#75?K8K97lYQNr<?RR!4
zmTvSC&)s#{f;v3Q<8ufavQ4`Roz<o}Git(xHjqJpXT6I&IQ0Pa_7_Hh!2@C!@igN^
zksR&+R>QNaEZY8cl^%Ji#R%!|?jAyrBAGGD!{^VFwiIj@<GPPH1q`$WBjV+tY|(3@
zbsaR|UCI)A>mSdwrR#4Z?9v8bQK`X4=VH!4arr|tJ|bu$hPL*Yf`Z*(ztNvCyALJd
z*|}4^i|@S${}6oTcM<X`uB%6mjfFXmCyKIn`&+P2U=9(o&lqP8Ds2T<7U!bZB?Hk`
zMMNnp)`6p1qi-UUU`BEMkW*A022uODlqn3PNmJ5<V}}7sGlZyxBk=g$r(MN~CW6(r
z=+`xxzZ<J1Q}a&QP@Au;MxE)8S6hlX@AIZ@Ti=%>kNfbjJ2Vm(iZfLl2f8Lcp(<vf
zApIe8jRax9n_XdZVC(D+-%IPn=}v;>yParShw3o?L2Eh@4ng!*rN~8;Y@(92Kop-r
zwMT2AXrx2aSbdhMaw7WqPMP!E=`Uq+O|@Ds3&kiFX>iW8=v{eK!}8HCCHQE&;ZaZe
zUmr?!g_AS+6Zh(VbV#G}<qqG}n)bcp9c>wdA!V&BtC4TAZ)3WClS*QU4s+!j`LBo7
zGkt4QAjuy$t3SB7PWxAV*D1e=N3Jfl^Q+R*c7tEJYU=6^?b`b3=+?&O=0uP~2Wx}o
zKL7af0?nPhx9I8VgQIS!7qR@JQ7AOKnN_(cXU}gxBHt0pcI}a)XZw+>p;0#B(T|PO
z9Az&FtZKB~ZdRF-AtNJGG`5Jgt}N($HLx`#BWXR$@X(i-^C%i-^+E;4jJPIyOO$w|
zOE1$<{r*D>NBNUzDpp@4&}9E`iIL5Vx}8$6sx$AubVUAB=Hin#ziDnvwc@HD#n*=~
z)3$uN5Igw&;Grw;H8!XxjhCIKTs6C(J=dFH&Au$#ezx7!Y1)Hv=bLxU%Ng0cH`d{1
zG{^-PtA8;Gwy3`uXgq!=n3w&{@4^I&<sY*P*3KcF^BoC)TxK;j3wAZdd9F74X>}xq
zJ@8!^3Xi;-{Z{2$A%6MZqla76LoWzusy{XV6kNBZ?e1*IsPW7ni_BexDINp%gKgqV
zZx~nYw0F8#U8!?gy>`-`yR(}d-*hj1ShMmh?dg_7^zZa8wd#qEet&Hwn)+&@+=g;B
zPPyomNJ_m>f8$DZg6(8SL+<kIk~_)}WY0B@>K@vl9B-0%S-zF>q^|mrnLVTXi&nDD
z>pB|)>#{S)PDfJYapRM{$8<BqxlM2E39M2*kYJjwN7H-TIqtlA;gmp)#<t(T*|omL
zT~e0qV8ds1s4ljA`m!Js+Nf=HY`>|u#OUW+qu*K7RF^JvIi(l9YTigj_DbSn%kWtG
zWg)U8>(TZ&+-p!SHNN{nFq?}Gf0LQ|e89)Z$OI*IHV}V@bEILB$?nP1wh;gGL;Pk_
z;%}WR<buTCX$RJ`5P!EY+$SzWX8Jqbv=HidH=Ud`FlHg7Yb=EGjtE=hw{OM>DNjLP
zK0?7ri-iIoy(b%}q!S(*S`R#)Ve3ZuF^UJp*$ZF3JV99|!qJnsnqti1P4B^Kg=($Z
zN;kSGja^){aIjSc*6#6X?bj2gR8&+<?wQxB;;o2p+?zT~@gCyp&u+2#Ne2c7`bfp$
zA50d#0!sHyO~~eP_+J=}T#t{Qakr9)t2h2Gxy|#nppZ}k(7-DNnVF6J*Yd1?`oNu9
z8`FoXtS-JCKcq0{To=t&rG5!tON-9Bl+&lBzMMx}9(cP%@WcuIH%uP>N0VeOOG|sc
zzK!Pk&!>r{yGI!!m<C!J2!vGwldlsJq;X5AJjpcgr?jrFu2vO*iXOLTDedfz&E%I|
z>K3NG;~xZkYi<s)?I<a6TYvxFV|H;q&(auRws#7&(8k2Il%&Y>0-_h0@85swvHXR?
zC?)xNH5HYQzX#S9q^g9^A7Vsx#*Qm__G4kUph;Mhlt_mUokCxihS~H-C<16PdBkKG
z)qNVYJxJ&M5qFlAC1hUEHKu(!+8m9Z7*(%Pzpx1ppeT0O>{I||C~di7HapreUwHAX
zLxI*674^EY*+js9{ud-*)8o_LN41S8^Dule3dfho4oYZkP#0!x!dtyK?YubibMiPv
zAfHq6pT%YC9F1VV!{c`ga^4Xe;Q6_q0%?&@Ke;+N?__-{az6iJv1X3-jgf3O1WG|B
z)TLkA+aqG@Uj+vTPeD*5yovn5S@+VObD31cw=e$WO}kUjnK|%Y4@9<sAv(!p=-aU;
zhuU+dloXwX#n^-c|Iwpq@9TXU2Cw4Xh_LzH9D!yaWrO89=Y?q3kleMqi2cb$T<2jH
zy;i=160v-hTt47`NF%z4UqBN9U5e}c&k*`1`jOaqs64la$w8uw?`O)h^f7#dYdHe_
zw-p6iD_*bnU{~ezMo+Swuf5N!s-iBsUS}T~rd><!zEwXJC>ovxV&jz&^!>LA1y>-Y
z{`2<sa!>#4%E_m8Yg;SpV`OV~Gs}&*53+$*bmSPDww8V|Ni7JjmJWedjfj8!g27qy
z>R{e^<I1;S0XH@^#cN(yS5JhF_KUIRZ{Nxaw4N0N+gM<E(h~f{yt=B|KXnE26eev@
zf0HJ7^yrf-S6;roGueMR>xlp?tgT7Yr55uphf7%&`5{-diEl-F9`end4>_YT0(D5P
z-y2^W>}a{%u~GF?8l$&_?Cp`uazZ!cgfs(R01+DL$P-Foq+C&(6>}0lB8oHhe2OjQ
z@bBMW4u~!o+(_=X&as{PRsU7M{l)QZrU<sTl!ny}9QtJT1iPQ2s6y)LEjPm(>xrpP
zsC88|;=8w|+AmG7MAy-`<7NcYK1Ql`<T8HyXyIZCzI9Pi*SmGQhkMd5GDe@a=j$nM
z5sSVAYjDTp;8Q>G72!e0ry{z6V$pBq6%;BOlP@+aqX+jDHY$|39wm0=i@XRA@%+<t
z2$vp)Hj(>a*dx`bG@Pr!mUR92yL(I3VvRmwuLYz;M@GsoXuZ6^FH>!>Q)Vz@!x!q(
zkJsgh1$vEQFE#bVr8}oH7+N^|y`V-XZ|7He<x7=X><4I?hg$|<rGDJbqiU*_N?%cZ
ze=*)99o2t+5s}ZvtXLvYviR`0x6tds7n1mGWDkYh{gI{l$t^?Z^%+&{H_*mPsS0EP
zEqOSNDxQ03H2ZH>N_R*BMKub1QW}=vZ5UKb!fn8oyoTTa;>(9ZFgMhne_FrJ$x$_`
zjUd{=vd)@szZtFTE5WfPTK&+*goXp9M}N#N_WgD#>bhDwpqF6Uda+p#H)D7E_M421
z6YR-^o&R{|`v*uwsQn`ra0)8#KP?S+c|b=p*m7sJY+$tkVdL+Kz9`_bc5=$!<;;l+
z(v9!aM`@$$5}>I(TD)9@tr(GDf{&5O9vXRAv#sF`xS6=cn@~**;nP$L&xZK{O^XOf
z&{|cdxn_!8PR7<7zxyUne2?t&;poyebH>B>U(V(Kr*HcEb>rAH8vKlcjKtZi|6kqQ
df8WUh`=Qej$FG&P6cJA#BdH*fa!$wX{{bi`A;$m!

literal 0
HcmV?d00001

diff --git a/moose-examples/tutorials/Electrophys/ephys1_cable.py b/moose-examples/tutorials/Electrophys/ephys1_cable.py
new file mode 100644
index 00000000..515ea4fd
--- /dev/null
+++ b/moose-examples/tutorials/Electrophys/ephys1_cable.py
@@ -0,0 +1,212 @@
+########################################################################
+# This example demonstrates a cable
+# Copyright (C) Upinder S. Bhalla NCBS 2018
+# Released under the terms of the GNU Public License V3.
+########################################################################
+import matplotlib.pyplot as plt
+import matplotlib.image as mpimg
+from matplotlib.widgets import Slider, Button
+import numpy as np
+import warnings
+import moose
+import rdesigneur as rd
+
+numDendSeg = 50
+interval = 0.005
+lines = []
+tplot = []
+RM = 1.0
+RA = 1.0
+CM = 0.01
+length = 0.002
+dia = 1e-6
+stimStr = "2e-10"
+runtime = 50e-3
+elecPlotDt = 0.001
+
+def makeModel():
+    segLen = length / numDendSeg
+    rdes = rd.rdesigneur(
+        stealCellFromLibrary = True,
+        elecPlotDt = elecPlotDt,
+        verbose = False,
+        # cellProto syntax: ['ballAndStick', 'name', somaDia, somaLength, dendDia, dendLength, numDendSegments ]
+        # The numerical arguments are all optional
+        cellProto = 
+            [['ballAndStick', 'soma', dia, segLen, dia, length, numDendSeg]],
+        passiveDistrib = [[ '#', 'RM', str(RM), 'CM', str(CM), 'RA', str(RA) ]],
+        stimList = [['soma', '1', '.', 'inject', stimStr ]],
+        plotList = [['dend3,dend18,dend33,dend49', '1', '.', 'Vm' ]],
+    )
+    rdes.buildModel()
+
+def main():
+    global vec
+    warnings.filterwarnings("ignore", category=UserWarning, module="matplotlib")
+    makeDisplay()
+    quit()
+
+def updateRM(RM_):
+    global RM
+    RM = RM_
+    updateDisplay()
+
+def updateCM(CM_):
+    global CM
+    CM = CM_
+    updateDisplay()
+
+def updateRA(RA_):
+    global RA
+    RA = RA_
+    updateDisplay()
+
+def updateLen(val): # This does the length of the entire cell.
+    global length
+    length = val * 0.001
+    updateDisplay()
+
+def updateDia(val):
+    global dia
+    dia = val * 1e-6
+    updateDisplay()
+
+class stimToggle():
+    def __init__( self, toggle, ax ):
+        self.duration = 1
+        self.toggle = toggle
+        self.ax = ax
+
+    def click( self, event ):
+        global stimStr
+        if self.duration < 0.5:
+            self.duration = 1.0
+            self.toggle.label.set_text( "Long Stim" )
+            self.toggle.color = "yellow"
+            self.toggle.hovercolor = "yellow"
+            stimStr = "2e-10"
+        else:
+            self.duration = 0.001
+            self.toggle.label.set_text( "Short Stim" )
+            self.toggle.color = "orange"
+            self.toggle.hovercolor = "orange"
+            stimStr = "1e-9*(t<0.001)"
+            #stimStr = "10e-9*(t<0.001)-9e-9*(t>0.001&&t<0.002)"
+        updateDisplay()
+
+def updateDisplay():
+    makeModel()
+    vec = moose.wildcardFind( '/model/elec/#[ISA=CompartmentBase]' )
+    tabvec = moose.wildcardFind( '/model/graphs/plot#' )
+    #vec[0].inject = 1e-10
+    moose.reinit()
+    initdt = 0.0001
+    dt = initdt
+    currtime = 0.0
+    for i in lines:
+        moose.start( dt )
+        currtime += dt
+        i.set_ydata( [v.Vm * 1000 for v in vec] )
+        dt = interval
+        #print( "inRunSim v0={}, v10={}".format( vec[0].Vm, vec[10].Vm ) )
+    moose.start( runtime - currtime )
+    for i,tab in zip( tplot, tabvec ):
+        i.set_ydata( tab.vector * 1000 )
+
+    moose.delete( '/model' )
+    moose.delete( '/library' )
+    # Put in something here for the time-series on soma
+
+def doQuit( event ):
+    tab = []
+    makeModel()
+    soma = moose.element( '/model/elec/soma' )
+    moose.reinit()
+    with open('output.txt', 'w') as file: 
+        file.write( "0.000  {:.2f}\n".format( soma.Vm * 1000 ) )
+        for t in np.arange( 0, 0.1, 0.001 ):
+            moose.start(0.001)
+            file.write( "{:.3f} {:.2f}\n".format( t+0.001, soma.Vm*1000 ) )
+    quit()
+
+def makeDisplay():
+    global tplot
+    global lines
+    #img = mpimg.imread( 'CableEquivCkt.png' )
+    img = mpimg.imread( 'CableInjectEquivCkt.png' )
+    #plt.ion()
+    fig = plt.figure( figsize=(10,12) )
+    png = fig.add_subplot(321)
+    imgplot = plt.imshow( img )
+    plt.axis('off')
+    ax1 = fig.add_subplot(322)
+    plt.ylabel( 'Vm (mV)' )
+    plt.ylim( -80, 40 )
+    plt.xlabel( 'time (ms)' )
+    plt.title( "Membrane potential vs time at 4 positions." )
+    t = np.arange( 0.0, runtime + elecPlotDt / 2.0, elecPlotDt ) * 1000 #ms
+    for i,col,name in zip( range( 4 ), ['b-', 'g-', 'r-', 'm-' ], ['a', 'b', 'c', 'd'] ):
+        ln, = ax1.plot( t, np.zeros(len(t)), col, label='pos= ' + name )
+        tplot.append(ln)
+    plt.legend()
+
+    ax2 = fig.add_subplot(312)
+    #ax2.margins( 0.05 )
+    #ax.set_ylim( 0, 0.1 )
+    plt.ylabel( 'Vm (mV)' )
+    plt.ylim( -80, 50 )
+    plt.xlabel( 'Position (microns)' )
+    #ax2.autoscale( enable = True, axis = 'y' )
+    plt.title( "Membrane potential vs position, at 5 times." )
+    t = np.arange( 0, numDendSeg+1, 1 ) #sec
+    for i,col in zip( range( 5 ), ['k-', 'b-', 'g-', 'y-', 'm-' ] ):
+        ln, = ax2.plot( t, np.zeros(numDendSeg+1), col, label="t={}".format(i*interval) )
+        lines.append(ln)
+    plt.legend()
+    ax = fig.add_subplot(313)
+    #ax.margins( 0.05 )
+    plt.axis('off')
+    axcolor = 'palegreen'
+    axStim = plt.axes( [0.02,0.05, 0.20,0.03], facecolor='green' )
+    axReset = plt.axes( [0.25,0.05, 0.30,0.03], facecolor='blue' )
+    axQuit = plt.axes( [0.60,0.05, 0.30,0.03], facecolor='blue' )
+    axRM = plt.axes( [0.25,0.1, 0.65,0.03], facecolor=axcolor )
+    axCM = plt.axes( [0.25,0.15, 0.65,0.03], facecolor=axcolor )
+    axRA = plt.axes( [0.25,0.20, 0.65,0.03], facecolor=axcolor )
+    axLen = plt.axes( [0.25,0.25, 0.65,0.03], facecolor=axcolor )
+    axDia = plt.axes( [0.25,0.30, 0.65,0.03], facecolor=axcolor )
+    #aInit = Slider( axAinit, 'A init conc', 0, 10, valinit=1.0, valstep=0.2)
+    stim = Button( axStim, 'Long Stim', color = 'yellow' )
+    stimObj = stimToggle( stim, axStim )
+    
+    reset = Button( axReset, 'Reset', color = 'cyan' )
+    q = Button( axQuit, 'Quit', color = 'pink' )
+    RM = Slider( axRM, 'RM ( ohm.m^2 )', 0.1, 10, valinit=1.0 )
+    CM = Slider( axCM, 'CM ( Farad/m^2)', 0.001, 0.1, valinit=0.01 )
+    RA = Slider( axRA, 'RA ( ohm.m', 0.1, 10, valinit=1.0 )
+    length = Slider( axLen, 'Total length of cell (mm)', 0.1, 10, valinit=2.0 )
+    dia = Slider( axDia, 'Diameter of cell (um)', 0.1, 10, valinit=1.0 )
+    def resetParms( event ):
+        RM.reset()
+        CM.reset()
+        RA.reset()
+        length.reset()
+        dia.reset()
+
+
+    stim.on_clicked( stimObj.click )
+    reset.on_clicked( resetParms )
+    q.on_clicked( doQuit )
+    RM.on_changed( updateRM )
+    CM.on_changed( updateCM )
+    RA.on_changed( updateRA )
+    length.on_changed( updateLen )
+    dia.on_changed( updateDia )
+    plt.tight_layout()
+
+    updateDisplay()
+    plt.show()
+
+# Run the 'main' if this script is executed standalone.
+if __name__ == '__main__':
+        main()
diff --git a/moose-examples/tutorials/Electrophys/ephys2_Rall_law.py b/moose-examples/tutorials/Electrophys/ephys2_Rall_law.py
new file mode 100644
index 00000000..a5f6e90d
--- /dev/null
+++ b/moose-examples/tutorials/Electrophys/ephys2_Rall_law.py
@@ -0,0 +1,268 @@
+########################################################################
+# This example demonstrates a cable
+# Copyright (C) Upinder S. Bhalla NCBS 2018
+# Released under the terms of the GNU Public License V3.
+########################################################################
+import moose
+import matplotlib.pyplot as plt
+import matplotlib.image as mpimg
+from matplotlib.widgets import Slider, Button
+import numpy as np
+import rdesigneur as rd
+
+numDendSeg = 10 # Applies both to dend and to branches.
+interval1 = 0.010
+interval2 = 0.05 - interval1
+lines = []
+# These 5 params vary only for the branches.
+RM = 1.0
+RA = 1.0
+CM = 0.01
+length = 0.001
+dia = 2e-6
+# The params below are fixed, apply to the soma and dend.
+dendRM = 2.0
+dendRA = 1.5
+dendCM = 0.02
+dendLength = 0.001
+dendDia = 2e-6
+
+# Stimulus in Amps applied to soma.
+stimStr = "2e-10"
+
+class lineWrapper():
+    def __init__( self ):
+        self.YdendLines = 0
+        self.Ybranch1Lines = 0
+        self.Ybranch2Lines = 0
+        self.CylLines = 0
+
+def makeYmodel():
+    segLen = dendLength / numDendSeg
+    rdes = rd.rdesigneur(
+        stealCellFromLibrary = True,
+        verbose = False,
+        # cellProto syntax: ['ballAndStick', 'name', somaDia, somaLength, dendDia, dendLength, numDendSegments ]
+        # The numerical arguments are all optional
+        cellProto = 
+            [['ballAndStick', 'cellBase', dendDia, segLen, dendDia, dendLength, numDendSeg]],
+        passiveDistrib = [[ '#', 'RM', str(dendRM), 'CM', str(dendCM), 'RA', str(dendRA) ]],
+        stimList = [['soma', '1', '.', 'inject', stimStr ]],
+    )
+    # Build the arms of the Y for a branching cell.
+    pa = moose.element( '/library/cellBase' )
+    x = length
+    y = 0.0
+    dx = length / ( numDendSeg * np.sqrt(2.0) )
+    dy = 0.0
+    prevc1 = moose.element( '/library/cellBase/dend{}'.format( numDendSeg-1 ) )
+    prevc2 = prevc1
+    for i in range( numDendSeg ):
+        c1 = rd.buildCompt( pa, 'branch1_{}'.format(i), RM = RM, CM = CM, RA = RA, dia = dia, x=x, y=y, dx = dx, dy = dy )
+        c2 = rd.buildCompt( pa, 'branch2_{}'.format(i), RM = RM, CM = CM, RA = RA, dia = dia, x=x, y=-y, dx = dx, dy = -dy )
+        moose.connect( prevc1, 'axial', c1, 'raxial' )
+        moose.connect( prevc2, 'axial', c2, 'raxial' )
+        prevc1 = c1
+        prevc2 = c2
+        x += dx
+        y += dy
+    rdes.buildModel()
+
+def makeCylModel():
+    segLen = dendLength / numDendSeg
+    rdes = rd.rdesigneur(
+        stealCellFromLibrary = True,
+        verbose = False,
+        # cellProto syntax: ['ballAndStick', 'name', somaDia, somaLength, dendDia, dendLength, numDendSegments ]
+        # The numerical arguments are all optional
+        cellProto = 
+            [['ballAndStick', 'soma', dendDia, segLen, dendDia, 2*dendLength, 2*numDendSeg]],
+        passiveDistrib = [[ '#', 'RM', str(dendRM), 'CM', str(dendCM), 'RA', str(dendRA) ]],
+        stimList = [['soma', '1', '.', 'inject', stimStr ]],
+    )
+    rdes.buildModel()
+
+def main():
+    global vec
+    makeDisplay()
+    quit()
+
+def updateRM(RM_):
+    global RM
+    RM = RM_
+    updateDisplay()
+
+def updateCM(CM_):
+    global CM
+    CM = CM_
+    updateDisplay()
+
+def updateRA(RA_):
+    global RA
+    RA = RA_
+    updateDisplay()
+
+def updateLen(val): # This does the length of the entire cell.
+    global length
+    length = val * 0.001
+    updateDisplay()
+
+def updateDia(val):
+    global dia
+    dia = val * 1e-6
+    updateDisplay()
+
+class stimToggle():
+    def __init__( self, toggle, ax ):
+        self.duration = 1
+        self.toggle = toggle
+        self.ax = ax
+
+    def click( self, event ):
+        global stimStr
+        if self.duration < 0.5:
+            self.duration = 1.0
+            self.toggle.label.set_text( "Long Stim" )
+            self.toggle.color = "yellow"
+            self.toggle.hovercolor = "yellow"
+            stimStr = "2e-10"
+        else:
+            self.duration = 0.001
+            self.toggle.label.set_text( "Short Stim" )
+            self.toggle.color = "orange"
+            self.toggle.hovercolor = "orange"
+            stimStr = "40e-9*(t<0.001)-36e-9*(t>0.001&&t<0.002)"
+        updateDisplay()
+        #self.ax.update()
+        #self.ax.redraw_in_frame()
+        #self.ax.draw()
+
+def printSomaVm():
+    print("This is somaVm" )
+
+def updateDisplay():
+    makeCylModel()
+    moose.element( '/model/elec/' ).name = 'Cyl'
+    moose.element( '/model' ).name = 'model1'
+    makeYmodel()
+    moose.element( '/model/elec/' ).name = 'Y'
+    moose.move( '/model1/Cyl', '/model' )
+    #moose.le( '/model/Y' )
+    #print "################################################"
+    #moose.le( '/model/Cyl' )
+    vecYdend = moose.wildcardFind( '/model/Y/soma,/model/Y/dend#' )
+    vecYbranch1 = moose.wildcardFind( '/model/Y/branch1#' )
+    vecYbranch2 = moose.wildcardFind( '/model/Y/branch2#' )
+    vecCyl = moose.wildcardFind( '/model/Cyl/#[ISA=CompartmentBase]' )
+    #vec[0].inject = 1e-10
+    moose.reinit()
+    dt = interval1
+    for i in lines:
+        moose.start( dt )
+        #print( len(vecCyl), len(vecYdend), len(vecYbranch1), len(vecYbranch2) )
+        i.CylLines.set_ydata( [v.Vm*1000 for v in vecCyl] )
+        i.YdendLines.set_ydata( [v.Vm*1000 for v in vecYdend] )
+        i.Ybranch1Lines.set_ydata( [v.Vm*1000 for v in vecYbranch1] )
+        i.Ybranch2Lines.set_ydata( [v.Vm*1000 for v in vecYbranch2] )
+        dt = interval2
+
+    moose.delete( '/model' )
+    moose.delete( '/model1' )
+    moose.delete( '/library' )
+    # Put in something here for the time-series on soma
+
+def doQuit( event ):
+    cylLength = 2*dendLength*float(2*numDendSeg+1)/(2*numDendSeg)
+    print( "The cylinder parameters were:\n"
+    "Length = {} microns\n"
+    "Diameter = {} microns\n"
+    "RM = {} Ohms.m^2\n"
+    "RA = {} Ohms.m\n"
+    "CM = {} Farads/m^2\n"
+    "Your branch parameters were:\n"
+    "Length = {:.2f} microns\n"
+    "Diameter = {:.2f} microns\n"
+    "RM = {:.2f} Ohms.m^2\n"
+    "RA = {:.2f} Ohms.m\n"
+    "CM = {:.3f} Farads/m^2\n".format( 
+        cylLength*1e6, dendDia*1e6, dendRM, dendRA, dendCM,
+        length*1e6, dia*1e6, RM, RA, CM ) )
+    print( "The branch point was at 1100 microns from the left" )
+
+    quit()
+
+def makeDisplay():
+    global lines
+    #img = mpimg.imread( 'CableEquivCkt.png' )
+    img = mpimg.imread( 'RallsLaw.png' )
+    #plt.ion()
+    fig = plt.figure( figsize=(10,12) )
+    png = fig.add_subplot(311)
+    imgplot = plt.imshow( img )
+    plt.axis('off')
+    ax2 = fig.add_subplot(312)
+    #ax.set_ylim( 0, 0.1 )
+    plt.ylabel( 'Vm (mV)' )
+    plt.ylim( -70, 0.0 )
+    plt.xlabel( 'Position (microns)' )
+    #ax2.autoscale( enable = True, axis = 'y' )
+    plt.title( "Membrane potential as a function of position along cell." )
+    #for i,col in zip( range( 5 ), ['k', 'b', 'g', 'y', 'm' ] ):
+    for i,col in zip( range( 2 ), ['b', 'k' ] ):
+        lw = lineWrapper()
+        lw.YdendLines, = ax2.plot( np.arange(0, numDendSeg+1, 1 ),
+                np.zeros(numDendSeg+1), col + '.' )
+        lw.Ybranch1Lines, = ax2.plot( np.arange(0, numDendSeg, 1) + numDendSeg + 1, 
+                np.zeros(numDendSeg), col + ':' )
+        lw.Ybranch2Lines, = ax2.plot( np.arange(0, numDendSeg, 1) + numDendSeg + 1, 
+                np.zeros(numDendSeg) + numDendSeg + 1, col + '.' )
+        lw.CylLines, = ax2.plot( np.arange(0, numDendSeg*2+1, 1), 
+                np.zeros(numDendSeg*2+1), 'r-' )
+        lines.append( lw )
+
+    ax = fig.add_subplot(313)
+    plt.axis('off')
+    axcolor = 'palegreen'
+    axStim = plt.axes( [0.02,0.05, 0.20,0.03], facecolor='green' )
+    axReset = plt.axes( [0.25,0.05, 0.30,0.03], facecolor='blue' )
+    axQuit = plt.axes( [0.60,0.05, 0.30,0.03], facecolor='blue' )
+    axRM = plt.axes( [0.25,0.1, 0.65,0.03], facecolor=axcolor )
+    axCM = plt.axes( [0.25,0.15, 0.65,0.03], facecolor=axcolor )
+    axRA = plt.axes( [0.25,0.20, 0.65,0.03], facecolor=axcolor )
+    axLen = plt.axes( [0.25,0.25, 0.65,0.03], facecolor=axcolor )
+    axDia = plt.axes( [0.25,0.30, 0.65,0.03], facecolor=axcolor )
+    #aInit = Slider( axAinit, 'A init conc', 0, 10, valinit=1.0, valstep=0.2)
+    stim = Button( axStim, 'Long Stim', color = 'yellow' )
+    stimObj = stimToggle( stim, axStim )
+    
+    reset = Button( axReset, 'Reset', color = 'cyan' )
+    q = Button( axQuit, 'Quit', color = 'pink' )
+    RM = Slider( axRM, 'RM ( ohm.m^2 )', 0.1, 10, valinit=1.0 )
+    CM = Slider( axCM, 'CM ( Farad/m^2)', 0.001, 0.05, valinit=0.01, valfmt = '%0.3f' )
+    RA = Slider( axRA, 'RA ( ohm.m', 0.1, 10, valinit=1.0 )
+    length = Slider( axLen, 'Length of branches (mm)', 0.1, 10, valinit=2.0 )
+    dia = Slider( axDia, 'Diameter of branches (um)', 0.1, 10, valinit=1.0 )
+    def resetParms( event ):
+        RM.reset()
+        CM.reset()
+        RA.reset()
+        length.reset()
+        dia.reset()
+
+
+    stim.on_clicked( stimObj.click )
+    reset.on_clicked( resetParms )
+    q.on_clicked( doQuit )
+    RM.on_changed( updateRM )
+    CM.on_changed( updateCM )
+    RA.on_changed( updateRA )
+    length.on_changed( updateLen )
+    dia.on_changed( updateDia )
+
+    updateDisplay()
+
+    plt.show()
+
+# Run the 'main' if this script is executed standalone.
+if __name__ == '__main__':
+        main()
diff --git a/moose-examples/tutorials/Rdesigneur/README.txt b/moose-examples/tutorials/Rdesigneur/README.txt
index b64d89a9..e7684568 100644
--- a/moose-examples/tutorials/Rdesigneur/README.txt
+++ b/moose-examples/tutorials/Rdesigneur/README.txt
@@ -291,6 +291,16 @@ ex9.2_spines_in_neuronal_morpho.py: Add spines to a neuron built from a
 	- See if you can deliver the current injection to the spine. Hint: the
 	name of the spine compartments is 'head#' where # is the index of the
 	spine.
+
+
+ex9.3_spiral_spines.py: Just for fun. Illustrates how to place spines in a
+spiral around the dendrite. For good measure the spines get bigger the further
+they are from the soma. Note that the uniform spacing of spines is signified 
+by the negative minSpacing term, the fourth argument to spineDistrib.
+	Suggestions:
+	- Play with expressions for spine size and angular placement.
+	- See what happens if the segment size gets smaller than the
+  	spine spacing.
 	
 To come:
 rdes_ex10.py: Build a spiny neuron, and insert the oscillatory chemical model
diff --git a/moose-examples/tutorials/Rdesigneur/ex3.2_squid_axon_propgn.py b/moose-examples/tutorials/Rdesigneur/ex3.2_squid_axon_propgn.py
index 9729a0d6..cb3e0a55 100644
--- a/moose-examples/tutorials/Rdesigneur/ex3.2_squid_axon_propgn.py
+++ b/moose-examples/tutorials/Rdesigneur/ex3.2_squid_axon_propgn.py
@@ -43,7 +43,7 @@ rdes = rd.rdesigneur(
     chanDistrib = [
         ['Na', '#', 'Gbar', '1200' ],
         ['K', '#', 'Gbar', '360' ]],
-    stimList = [['soma', '1', '.', 'inject', '(t>0.01 && t<0.2) * 2e-11' ]],
+    stimList = [['soma', '1', '.', 'inject', '(t>0.005 && t<0.2) * 2e-11' ]],
     plotList = [['soma', '1', '.', 'Vm', 'Membrane potential']],
     moogList = [['#', '1', '.', 'Vm', 'Vm (mV)']]
 )
@@ -51,4 +51,4 @@ rdes = rd.rdesigneur(
 rdes.buildModel()
 moose.reinit()
 
-rdes.displayMoogli( 0.00005, 0.05, 0.0 )
+rdes.displayMoogli( 0.00005, 0.04, 0.0 )
diff --git a/moose-examples/tutorials/Rdesigneur/ex3.3_AP_collision.py b/moose-examples/tutorials/Rdesigneur/ex3.3_AP_collision.py
index b6a8ce2a..dfe4e8cd 100644
--- a/moose-examples/tutorials/Rdesigneur/ex3.3_AP_collision.py
+++ b/moose-examples/tutorials/Rdesigneur/ex3.3_AP_collision.py
@@ -52,4 +52,4 @@ rdes = rd.rdesigneur(
 rdes.buildModel()
 moose.reinit()
 
-rdes.displayMoogli( 0.00005, 0.05, 0.0 )
+rdes.displayMoogli( 0.00005, 0.03, 0.0 )
diff --git a/moose-examples/tutorials/Rdesigneur/ex3.4_myelinated_axon.py b/moose-examples/tutorials/Rdesigneur/ex3.4_myelinated_axon.py
index e91f7898..c609529d 100644
--- a/moose-examples/tutorials/Rdesigneur/ex3.4_myelinated_axon.py
+++ b/moose-examples/tutorials/Rdesigneur/ex3.4_myelinated_axon.py
@@ -58,12 +58,6 @@ rdes = rd.rdesigneur(
     moogList = [['#', '1', '.', 'Vm', 'Vm (mV)']]
 )
 
-
 rdes.buildModel()
-
-for i in moose.wildcardFind( "/model/elec/#/Na" ):
-    print(i.parent.name, i.Gbar)
-
 moose.reinit()
-
 rdes.displayMoogli( 0.00005, 0.05, 0.0 )
diff --git a/moose-examples/tutorials/Rdesigneur/ex7.2_CICR.py b/moose-examples/tutorials/Rdesigneur/ex7.2_CICR.py
index a44e4a1a..38447a8d 100644
--- a/moose-examples/tutorials/Rdesigneur/ex7.2_CICR.py
+++ b/moose-examples/tutorials/Rdesigneur/ex7.2_CICR.py
@@ -15,6 +15,7 @@ rdes = rd.rdesigneur(
     turnOffElec = True,
     chemDt = 0.005,
     chemPlotDt = 0.02,
+    numWaveFrames = 200,
     diffusionLength = 1e-6,
     useGssa = False,
     addSomaChemCompt = False,
diff --git a/moose-examples/tutorials/Rdesigneur/ex9.3_spiral_spines.py b/moose-examples/tutorials/Rdesigneur/ex9.3_spiral_spines.py
new file mode 100644
index 00000000..fe5c39c5
--- /dev/null
+++ b/moose-examples/tutorials/Rdesigneur/ex9.3_spiral_spines.py
@@ -0,0 +1,19 @@
+##########################################################################
+# This illustrates some of the capabilities for spine placement.
+# It has spines whose size increase with distance from the soma.
+# Further, the angular direction of the spines spirals around the dendrite.
+##########################################################################
+import moose
+import rdesigneur as rd
+rdes = rd.rdesigneur(
+    cellProto = [['ballAndStick', 'elec', 10e-6, 10e-6, 2e-6, 300e-6, 50]],
+    spineProto = [['makePassiveSpine()', 'spine']],
+    spineDistrib = [['spine', '#dend#', '3e-6', '-1e-6', '1+p*2e4', '0', 'p*6.28e7', '0']],
+    stimList = [['soma', '1', '.', 'inject', '(t>0.02) * 1e-9' ]],
+    moogList = [['#', '1', '.', 'Vm', 'Soma potential']]
+)
+
+rdes.buildModel()
+
+moose.reinit()
+rdes.displayMoogli( 0.0002, 0.025, 0.02 )
diff --git a/moose-gui/objectedit.py b/moose-gui/objectedit.py
index cbc8c22b..d5d66b60 100644
--- a/moose-gui/objectedit.py
+++ b/moose-gui/objectedit.py
@@ -175,10 +175,14 @@ class ObjectEditModel(QtCore.QAbstractTableModel):
             self.fields.append(fieldName)
         #harsha: For signalling models will be pulling out notes field from Annotator
         #        can updates if exist for other types also
-        if ( isinstance(self.mooseObject, moose.PoolBase)
-           or isinstance(self.mooseObject,moose.EnzBase) 
-           or isinstance(self.mooseObject,moose.Neutral)) :
-            self.fields.append("Color")
+        if (isinstance (self.mooseObject,moose.ChemCompt) or \
+            isinstance(self.mooseObject,moose.ReacBase)  or \
+            isinstance(moose.element(moose.element(self.mooseObject).parent),moose.EnzBase) \
+           ):
+            pass
+        else:
+             self.fields.append("Color")
+        
         flag = QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEditable
         self.fieldFlags[fieldName] = flag
 
diff --git a/moose-gui/plugins/kkit.py b/moose-gui/plugins/kkit.py
index 4870a71d..3cd531bb 100644
--- a/moose-gui/plugins/kkit.py
+++ b/moose-gui/plugins/kkit.py
@@ -6,13 +6,14 @@ __version__     =   "1.0.0"
 __maintainer__  =   "HarshaRani"
 __email__       =   "hrani@ncbs.res.in"
 __status__      =   "Development"
-__updated__     =   "Sep 7 2018"
+__updated__     =   "Sep 11 2018"
 
 #Change log:
 # 2018 
-#Jun 18: update the color of the group from objecteditor
+#sep 11: comparment size is calculated based on group sceneBoundingRect size
 #Sep 07: in positionChange all the group's boundingRect is calculated
 #        and when group is moved the children's position are stored
+#Jun 18: update the color of the group from objecteditor
 #code
 
 import math
@@ -908,7 +909,16 @@ class  KineticsWidget(EditorWidgetBase):
                         # rectcompt = calculateChildBoundingRect(grpcompt)
                 rectgrp = calculateChildBoundingRect(v)
                 v.setRect(rectgrp.x()-10,rectgrp.y()-10,(rectgrp.width()+20),(rectgrp.height()+20))
-            
+                for k, v in self.qGraCompt.items():
+                    #rectcompt = v.childrenBoundingRect()
+                    rectcompt = calculateChildBoundingRect(v)
+                    comptBoundingRect = v.boundingRect()
+                    if not comptBoundingRect.contains(rectcompt):
+                        self.updateCompartmentSize(v)
+                    
+                    else:
+                        rectcompt = calculateChildBoundingRect(v)
+                        v.setRect(rectcompt.x()-10,rectcompt.y()-10,(rectcompt.width()+20),(rectcompt.height()+20))
         else:
             mobj = self.mooseId_GObj[element(mooseObject)]
             self.updateArrow(mobj)
@@ -938,11 +948,11 @@ class  KineticsWidget(EditorWidgetBase):
                 comptBoundingRect = v.boundingRect()
                 if not comptBoundingRect.contains(rectcompt):
                     self.updateCompartmentSize(v)
+                    
                 else:
                     rectcompt = calculateChildBoundingRect(v)
                     v.setRect(rectcompt.x()-10,rectcompt.y()-10,(rectcompt.width()+20),(rectcompt.height()+20))
-                    pass
-        
+                    
     def updateGrpSize(self,grp):
         compartmentBoundary = grp.rect()
         
diff --git a/moose-gui/plugins/kkitUtil.py b/moose-gui/plugins/kkitUtil.py
index 71859880..b7dde1b7 100644
--- a/moose-gui/plugins/kkitUtil.py
+++ b/moose-gui/plugins/kkitUtil.py
@@ -5,12 +5,16 @@ __version__     =   "1.0.0"
 __maintainer__  =   "HarshaRani"
 __email__       =   "hrani@ncbs.res.in"
 __status__      =   "Development"
-__updated__     =   "Oct 18 2017"
+__updated__     =   "Sep 17 2018"
 
 '''
+2018
+Sep 17: when vertical or horizontal layout is applied for group, compartment size is recalculated
+Sep 11: group size is calculated based on sceneBoundingRect for compartment size
+2017
 Oct 18  some of the function moved to this file from kkitOrdinateUtils
 '''
-from moose import Annotator,element
+from moose import Annotator,element,ChemCompt
 from kkitQGraphics import PoolItem, ReacItem,EnzItem,CplxItem,GRPItem,ComptItem
 from PyQt4 import QtCore,QtGui,QtSvg
 from PyQt4.QtGui import QColor
@@ -127,9 +131,10 @@ def moveX(reference, collider, layoutPt, margin):
     layoutPt.drawLine_arrow(itemignoreZooming=False)
 
 def handleCollisions(compartments, moveCallback, layoutPt,margin = 5.0):
-    
+    print " handelCollision"
     if len(compartments) is 0 : return
     compartments = sorted(compartments, key = lambda c: c.sceneBoundingRect().center().x())
+    print " compartment ",compartments
     reference = compartments.pop(0);
     print (reference.name)
     referenceRect = reference.sceneBoundingRect()
@@ -138,6 +143,18 @@ def handleCollisions(compartments, moveCallback, layoutPt,margin = 5.0):
                       )
     for collider in colliders:
         moveCallback(reference, collider, layoutPt,margin)
+    #print (reference.mobj).parent
+    if isinstance(element(((reference.mobj).parent)),ChemCompt):
+        v = layoutPt.qGraCompt[element(((reference.mobj).parent))]
+        #layoutPt.updateCompartmentSize(x)
+        rectcompt = calculateChildBoundingRect(v)
+        comptBoundingRect = v.boundingRect()
+        if not comptBoundingRect.contains(rectcompt):
+            layoutPt.updateCompartmentSize(v)
+                    
+        else:
+            rectcompt = calculateChildBoundingRect(v)
+            v.setRect(rectcompt.x()-10,rectcompt.y()-10,(rectcompt.width()+20),(rectcompt.height()+20))
     return handleCollisions(compartments, moveCallback, layoutPt,margin)
 
 def calculateChildBoundingRect(compt):
@@ -149,7 +166,6 @@ def calculateChildBoundingRect(compt):
     ypos = []
     xpos = []
     for l in compt.childItems():
-
         ''' All the children including pool,reac,enz,polygon(arrow),table '''
         if not isinstance(l,QtSvg.QGraphicsSvgItem):
             if (not isinstance(l,QtGui.QGraphicsPolygonItem)):
@@ -158,11 +174,18 @@ def calculateChildBoundingRect(compt):
                     xpos.append(l.pos().x())
                     ypos.append(l.pos().y()+l.boundingRect().bottomRight().y())
                     ypos.append(l.pos().y())
+
                 else:
+                    xpos.append(l.sceneBoundingRect().x())
+                    xpos.append(l.sceneBoundingRect().bottomRight().x())
+                    ypos.append(l.sceneBoundingRect().y())
+                    ypos.append(l.sceneBoundingRect().bottomRight().y())
+                    '''
                     xpos.append(l.rect().x())
                     xpos.append(l.boundingRect().bottomRight().x())
                     ypos.append(l.rect().y())
                     ypos.append(l.boundingRect().bottomRight().y())
+                    '''
         if (isinstance(l,PoolItem) or isinstance(l,EnzItem)):
             ''' For Enz cplx height and for pool function height needs to be taken'''
             for ll in l.childItems():
diff --git a/moose-gui/plugins/kkitViewcontrol.py b/moose-gui/plugins/kkitViewcontrol.py
index a813bffe..06fa8b7f 100644
--- a/moose-gui/plugins/kkitViewcontrol.py
+++ b/moose-gui/plugins/kkitViewcontrol.py
@@ -144,13 +144,14 @@ class GraphicalView(QtGui.QGraphicsView):
                     elif gsolution[1] == GROUP_INTERIOR:
                         groupInteriorfound = True
                         groupList.append(gsolution)
-
                 if item.name == COMPARTMENT:
                     csolution = (item, self.resolveCompartmentInteriorAndBoundary(item, position))
                     if csolution[1] == COMPARTMENT_BOUNDARY:
-                        comptInteriorfound = True
-                        comptBoundary.append(csolution)
-
+                        return csolution
+                    # elif csolution[1] == COMPARTMENT_INTERIOR:
+                    #     comptInteriorfound = True
+                    #     comptBoundary.append(csolution)
+        
         if groupInteriorfound:
             if comptInteriorfound:
                 return comptBoundary[0]
@@ -181,7 +182,6 @@ class GraphicalView(QtGui.QGraphicsView):
                 ##This is kept for reference, so that if object (P,R,E,Tab,Fun) is moved outside the compartment,
                 #then it need to be pull back to original position
                 self.state["press"]["scenepos"]  = item.parent().scenePos() 
-            
             if itemType == COMPARTMENT_INTERIOR or itemType == GROUP_BOUNDARY  or itemType == GROUP_INTERIOR:
                 self.removeConnector()
                 
@@ -194,6 +194,9 @@ class GraphicalView(QtGui.QGraphicsView):
             if itemType == GROUP_BOUNDARY:
                 popupmenu = QtGui.QMenu('PopupMenu', self)
                 popupmenu.addAction("DeleteGroup", lambda : self.deleteGroup(item,self.layoutPt))
+                popupmenu.addAction("LinearLayout", lambda : handleCollisions(list(self.layoutPt.qGraGrp.values()), moveX, self.layoutPt))
+                popupmenu.addAction("VerticalLayout" ,lambda : handleCollisions(list(self.layoutPt.qGraGrp.values()), moveMin, self.layoutPt ))
+                        
                 #popupmenu.addAction("CloneGroup" ,lambda : handleCollisions(comptList, moveMin, self.layoutPt ))
                 popupmenu.exec_(self.mapToGlobal(event.pos()))
             
@@ -361,6 +364,12 @@ class GraphicalView(QtGui.QGraphicsView):
                     grpCmpt = self.findGraphic_groupcompt(item)
                     if movedGraphObj.parentItem() != grpCmpt:
                         '''Not same compartment/group to which it belonged to '''
+                        if isinstance(movedGraphObj,FuncItem):
+                            funcPool = moose.element((movedGraphObj.mobj.neighbors['valueOut'])[0])
+                            parentGrapItem = self.layoutPt.mooseId_GObj[moose.element(funcPool)]
+                            if parentGrapItem.parentItem() != grpCmpt:
+                                self.objectpullback("Functionparent",grpCmpt,movedGraphObj,xx,yy)
+                            
                         if isinstance(movedGraphObj,(EnzItem,MMEnzItem)):
                             parentPool = moose.element((movedGraphObj.mobj.neighbors['enzDest'])[0])
                             if isinstance(parentPool,PoolBase):
@@ -558,16 +567,21 @@ class GraphicalView(QtGui.QGraphicsView):
         if messgtype.lower() == "all":
             messgstr = "The object name  \'{0}\' exist in \'{1}\' {2}".format(movedGraphObj.mobj.name,item.mobj.name,desObj)
         elif messgtype.lower() =="enzymeparent":
-            messgstr = "The Enzyme parent  \'{0}\' doesn't exist in \'{2}\' {1} \n If you need to move the enzyme to {1} first parent pool needs to be moved".format(movedGraphObj.mobj.parent.name,desObj,item.mobj.name)
+            messgstr = "The Enzyme parent  \'{0}\' doesn't exist in \'{2}\' {1} \n If you need to move the enzyme to {1} first move the parent pool".format(movedGraphObj.mobj.parent.name,desObj,item.mobj.name)
         elif messgtype.lower() == "enzyme":
             messgstr = "The Enzyme \'{0}\' already exist in \'{2}\' {1}".format(movedGraphObj.mobj.name,desObj,item.mobj.name)        
         elif messgtype.lower() == "empty":
             messgstr = "The object can't be moved to empty space"
+        elif messgtype.lower() =="functionparent":
+            messgstr = "The Function parent  \'{0}\' doesn't exist in \'{2}\' {1} \n If you need to move the function to {1} first move the parent pool".format(movedGraphObj.mobj.parent.name,desObj,item.mobj.name)
+        
         QtGui.QMessageBox.warning(None,'Could not move the object', messgstr )
         QtGui.QApplication.setOverrideCursor(QtGui.QCursor(Qt.Qt.ArrowCursor))
 
     def moveObjSceneParent(self,item,movedGraphObj,itempos,eventpos):
         ''' Scene parent object needs to be updated '''
+        if isinstance(movedGraphObj,FuncItem):
+            return
         prevPar = movedGraphObj.parentItem()
         movedGraphObj.setParentItem(item)
 
-- 
GitLab