{ "metadata": { "name": "" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "ModelicaRes Tutorial" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This tutorial shows how to use [ModelicaRes](http://kdavies4.github.io/ModelicaRes) to run [Modelica](https://www.modelica.org/) model experiments and analyze the results." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Table of contents:**\n", "- [Running model experiments](#Running-model-experiments)\n", "- [Analyzing results](#Analyzing-results)\n", " - [Simulation results](#Simulation-results)\n", " - [Linearization results](#Linearization-results)\n", " - [Groups of results](#Groups-of-results)\n", " - [Simulations](#Simulations)\n", " - [Linearizations](#Linearizations)\n", "- [Further information](#Further-information)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Before we get started, we'll load some standard modules and establish settings for this IPython notebook." ] }, { "cell_type": "code", "collapsed": false, "input": [ "import numpy as np\n", "import matplotlib.pyplot as plt \n", "import pandas; pandas.set_option('display.max_rows', 5)\n", "%matplotlib inline\n", "%precision 4" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 1, "text": [ "u'%.4f'" ] } ], "prompt_number": 1 }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Running model experiments" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[ModelicaRes](http://kdavies4.github.io/ModelicaRes) can help run sets of model simulations or linearizations. The usage is based on special context managers called [simulators](http://kdavies4.github.io/ModelicaRes/modelicares.exps.simulators.html). For example, to run a dymosim executable model several times with different settings:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "from modelicares.exps.simulators import dymosim\n", "\n", "model = \"ChuaCircuit/dymosim\"\n", "with dymosim(results_dir='ChuaCircuit', StopTime=2500) as simulator:\n", " simulator.run(model, {'L.L': 15})\n", " simulator.run(model, {'L.L': 18})\n", " simulator.run(model, {'L.L': 21})" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 2 }, { "cell_type": "markdown", "metadata": {}, "source": [ "This simulates the model three times with the desired parameters and places the results in three subfolders. Each folder contains an initialization file, a final values file, full results (\\*.mat), and a log file. In the base folder there is a tab-separated values file (runs.tsv) with a summary of the simulations. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Currently, two other simulators are available: [dymola_script](http://kdavies4.github.io/ModelicaRes/modelicares.exps.simulators.html#modelicares.exps.simulators.dymola_script) to write a Dymola-formatted simulation script (\\*.mos) to perform the same actions as above and [fmi](http://kdavies4.github.io/ModelicaRes/modelicares.exps.simulators.html#modelicares.exps.simulators.fmi) to run FMUs in a similar manner via [PyFMI](http://www.pyfmi.org). With the [dymosim](http://kdavies4.github.io/ModelicaRes/modelicares.exps.simulators.html#modelicares.exps.simulators.dymosim) and [fmi](http://kdavies4.github.io/ModelicaRes/modelicares.exps.simulators.html#modelicares.exps.simulators.fmi) simulators, one can continue a previous simulation by using continue_run() instead of run(). " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In order to easily build a large set of simulations with varying parameters, we can use the design of experiments module ([doe](http://kdavies4.github.io/ModelicaRes/modelicares.exps.doe.html)). For example, to run a full-factorial study:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "from modelicares import doe\n", "\n", "with dymosim(results_dir='ChuaCircuit', StopTime=2500) as simulator:\n", " for params in doe.fullfact({'C1.C': [8, 10], 'L.L': [18, 20]}):\n", " simulator.run(model, params)" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 3 }, { "cell_type": "markdown", "metadata": {}, "source": [ "This runs the model four times and places the results in four subfolders. In the \"Initial values & parameters\" column of the summary file (runs.tsv) we see:\n", "- C1(C=8), L(L=18)\n", "- C1(C=10), L(L=18)\n", "- C1(C=8), L(L=20)\n", "- C1(C=10), L(L=20)" ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Analyzing results" ] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "Simulation results" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "First, we'll load a simulation result of [Modelica.Electrical.Analog.Examples.ChuaCircuit](http://reference.wolfram.com/system-modeler/libraries/Modelica/Modelica_Electrical_Analog_Examples_ChuaCircuit.html):" ] }, { "cell_type": "code", "collapsed": false, "input": [ "from modelicares import SimRes\n", "sim = SimRes('ChuaCircuit.mat')" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 4 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we'll explore the simulation results using the methods in\n", "[SimRes](http://kdavies4.github.io/ModelicaRes/modelicares.simres.html#modelicares.simres.SimRes). To get the start and stop times of the simulation, we can look up the initial and final values of time:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "sim['Time'].IV" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 5, "text": [ "0 s" ] } ], "prompt_number": 5 }, { "cell_type": "code", "collapsed": false, "input": [ "sim['Time'].FV" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 6, "text": [ "2500 s" ] } ], "prompt_number": 6 }, { "cell_type": "markdown", "metadata": {}, "source": [ "There are many other properties. For example," ] }, { "cell_type": "code", "collapsed": false, "input": [ "Lv = sim['L.v']\n", "dict(description=Lv.description,\n", " display_unit=Lv.display_unit,\n", " maximum=Lv.max, \n", " mean=Lv.mean, \n", " minimum=Lv.min,\n", " rms=Lv.RMS)" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 7, "text": [ "{'description': u'Voltage drop between the two pins (= p.v - n.v)',\n", " 'display_unit': V,\n", " 'maximum': 0.773441 V,\n", " 'mean': 0.0147338 V,\n", " 'minimum': -0.945017 V,\n", " 'rms': 0.366374 V}" ] } ], "prompt_number": 7 }, { "cell_type": "markdown", "metadata": {}, "source": [ "The display unit was loaded from the result, but we can change it:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "Lv.display_unit = 'mV'\n", "dict(maximum=Lv.max, \n", " mean=Lv.mean, \n", " minimum=Lv.min,\n", " rms=Lv.RMS)" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 25, "text": [ "{'maximum': 773.441 mV,\n", " 'mean': 14.7338 mV,\n", " 'minimum': -945.017 mV,\n", " 'rms': 366.374 mV}" ] } ], "prompt_number": 25 }, { "cell_type": "markdown", "metadata": {}, "source": [ "To retrieve the values of a variable, use [values](http://kdavies4.github.io/ModelicaRes/modelicares.simres.html#modelicares.simres.SimRes.__getitem__)():" ] }, { "cell_type": "code", "collapsed": false, "input": [ "from natu.units import s # The unit second\n", "Lv.values(t=(20*s,))" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 9, "text": [ "[ 0. 109.235 210.835 304.6235 390.4008] mV" ] } ], "prompt_number": 9 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here we've only included the first 20 seconds, but all of the values are returned by default. To return the sample times, use \n", "[times](http://kdavies4.github.io/ModelicaRes/modelicares.simres.html#modelicares.simres.SimRes.__getitem__)():" ] }, { "cell_type": "code", "collapsed": false, "input": [ "Lv.times(t=(20*s,))" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 10, "text": [ "[ 0. 5. 10. 15. 20.] s" ] } ], "prompt_number": 10 }, { "cell_type": "markdown", "metadata": {}, "source": [ "These values have been extracted directly, but it's also possible to interpolate at a specified time:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "Lv.values(t=2.5*s)" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 11, "text": [ "54.6175 mV" ] } ], "prompt_number": 11 }, { "cell_type": "markdown", "metadata": {}, "source": [ "or at a specified list of times:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "Lv.values(t=[2.5*s, 7.5*s, 12.5*s, 17.5*s]) # TODO: return as array" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 12, "text": [ "[54.6175 mV, 160.035 mV, 257.729 mV, 347.512 mV]" ] } ], "prompt_number": 12 }, { "cell_type": "markdown", "metadata": {}, "source": [ "or to return only every *n*th sample (here, *n* = 100): " ] }, { "cell_type": "code", "collapsed": false, "input": [ "t = (None, None, 100)\n", "zip(Lv.times(t), Lv.values(t))" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 13, "text": [ "[(0 s, 0 mV),\n", " (480 s, 234.305 mV),\n", " (960 s, -522.736 mV),\n", " (1440 s, 127.059 mV),\n", " (1940 s, -138.497 mV),\n", " (2440 s, 138.457 mV)]" ] } ], "prompt_number": 13 }, { "cell_type": "code", "collapsed": false, "input": [ "x=sim['Ro.R']" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 14 }, { "cell_type": "markdown", "metadata": {}, "source": [ "To check if a variable is included in the results, we can use Python's [in operator](https://docs.python.org/2/library/operator.html#operator.__contains__)." ] }, { "cell_type": "code", "collapsed": false, "input": [ "'L.v' in sim" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 15, "text": [ "True" ] } ], "prompt_number": 15 }, { "cell_type": "markdown", "metadata": {}, "source": [ "To see how many variables are in a simulation, use Python's\n", "[len](https://docs.python.org/2/library/functions.html#len)() function:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "len(sim)" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 16, "text": [ "62" ] } ], "prompt_number": 16 }, { "cell_type": "markdown", "metadata": {}, "source": [ "To search for variable names, use [names](http://kdavies4.github.io/ModelicaRes/modelicares.simres.html#modelicares.simres.SimRes.names)() with wildcards:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "sim.find('L*v')" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 17, "text": [ "['L.n.v', 'L.p.v', 'L.v']" ] } ], "prompt_number": 17 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Regular expressions can also be used:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "voltages = sim.find('^[^.]*.v\$', re=True)\n", "voltages" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 18, "text": [ "['C1.v', 'C2.v', 'G.v', 'L.v', 'Nr.v', 'Ro.v']" ] } ], "prompt_number": 18 }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can access information about all these variables at once:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "sim(voltages).IV" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 19, "text": [ "[4 V, 0 V, -4 V, 0 mV, 4 V, 0 V]" ] } ], "prompt_number": 19 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Notice that we used parentheses; sim[] only accepts one variable and would have produced an error. Also notice that millivolts are used to display the value of *L.v*, but the other display units have not changed. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can plot these voltages using [plot](http://kdavies4.github.io/ModelicaRes/modelicares.simres.html#modelicares.simres.SimRes.plot)():" ] }, { "cell_type": "code", "collapsed": false, "input": [ "sim.plot(voltages);" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "display_data", "png": "iVBORw0KGgoAAAANSUhEUgAAAY0AAAEbCAYAAAAmmNiPAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzsnXdYU9cbx783CXtvUBFxgFtcFTdqq1Zt3dpaR621S2vb\nX7dt1e5prbV2uVrrXnWLWwHFgeIAFATZe8+EjPv+/riKC0hCbhKs5/M8PEruOed+cxPue8857+CI\niMBgMBgMhg5IzC2AwWAwGA8PzGgwGAwGQ2eY0WAwGAyGzjCjwWAwGAydYUaDwWAwGDrDjAaDwWAw\ndIYZDQaDwWDoDDMaDAaDwdAZrUbjtddeQ0REhCm0MBgMBqORo9VoBAQE4N1334Wfnx/ee+89REdH\nm0IXg8FgMBohnK5pRFJSUrBp0yZs3rwZVVVVmDJlCp599lkEBAQYWyODwWAwGgk6G427iY6OxsyZ\nM3H16lVoNBpj6GIwGAxGI0TnjXC1Wo3du3djypQpGD58ONq2bYsdO3YYUxuDwWAwGhlajcahQ4fw\nwgsvoGnTplixYgVGjRqFpKQkbNq0CaNHjzaFRgajwSxatAjTpk0zy7nXr1+PYcOGiT5uWloaHBwc\nwBJUM8yBVqPxzTffoHfv3rh27Rr27NmDKVOmwN7e3hTaGAyd2bBhA3r06AEHBwc0adIEI0aMwKlT\np8BxnFHPe/DgQQwYMACOjo7w9PRESEgI9uzZAwB47rnncPDgQdHP2bx5c5SXl9e8t5CQEKxatUr0\n8zAYtSHT1uDYsWOm0MFgNJgff/wR3377Lf744w8MGzYMlpaWCA0Nxe7du2Fra2u0827btg2zZs3C\nkiVLMHHiRDg4OCAsLAzr1q3DU089VW9ftVoNmUzrn59OGNswMhj3QAzGQ0xJSQnZ29vTtm3baj2+\naNEimjRpEk2fPp0cHByoQ4cOFBUVVXOc4zhKSkqq+X3GjBn08ccfExFRUVERjRw5kjw8PMjFxYVG\njRpFGRkZRETE8zz5+vrSDz/8UKe2NWvWUL9+/e451/Lly6l169bUsmVLIiLauXMndenShRwdHalV\nq1Z08OBBIiLy8/OjI0eO1PRduHAhTZ06lYiIkpOTieM4UqvVNH/+fJJKpWRtbU329vb0+uuv63X9\nGAx9YRHhjIeayMhIKBQKjB07ttbjRITdu3fj2WefRWlpKZ5++mnMnTu3zvE4jqt5cicizJo1C2lp\naUhLS4ONjU1N3/j4eGRkZGDChAl66d21axfOnz+PuLg4nDt3DjNmzMDixYtRWlqKsLAw+Pn5PaDj\n9u+1af3yyy/Rv39/LF++HOXl5fj555/10sNg6AszGoyHmsLCQri7u0Miqfur3L9/fwwfPhwcx2Hq\n1Km4fPlyvWPSrQ1mV1dXjB07FtbW1rC3t8f8+fNx8uTJmvMCgI+Pj156P/zwQzg7O8PKygqrVq3C\nrFmzMGTIEABAkyZNEBgYWK8mbZoZDGOj1WicPn2afSEZjRY3NzcUFBSA5/k623h5edX839bWFgqF\not72t6mqqsLLL7+MFi1awMnJCQMHDkRpaSmICG5ubgCA7OxsvfT6+vrW/D8jIwOtWrXSq39dsH0N\nhqnQajTWrl2Lbt26YfLkyfjrr7+Qk5NjCl0Mhk707t0bVlZW+Pfff2s9ru1mamtri6qqqprfs7Oz\na/osXrwYCQkJOHfuHEpLS3Hy5EkQEYgIgYGB8PX1xbZt2/TSe7ceX19fJCYm1trOzs4OlZWVNb/X\n93fHDAbDlGg1Gr///juio6OxaNEiFBUV4fnnn0dwcDDmz5+PsLAwFhHOMCtOTk747LPPMGfOHOza\ntQtVVVVQqVQ4cOAA3n//fa39g4KCsH79emg0GoSGhiIsLKzmWEVFBWxsbODk5ISioiJ8+umnNcc4\njsOPP/6Izz//HH/99RfKysrA8zwiIiLw8ssv66R91qxZWLNmDY4dOwae55GZmYn4+PgaXZs2bYJa\nrUZUVBS2b99ep3Hw8vJCUlKSTudkMAymIbvnlZWVtHfvXpozZw5169ZNpD15BqPhrF+/nnr06EF2\ndnbk7e1No0aNosjISFq0aBFNmzatpl1ycjJJJBLSaDRERBQVFUUdOnQgBwcHmjZtGk2ZMoU++eQT\nIiLKysqikJAQsre3p8DAQPrjjz/u6UtEFBoaSv379yd7e3vy8PCgQYMG0f79+4mI6K+//qL+/fvX\ntJVIJPd4ahER/fvvv9S5c2dycHCg1q1b06FDh4iI6ObNm9SrVy+yt7enkSNH0htvvFHzPu5/D5GR\nkRQQEEAuLi70xhtviH1pGYx7aFDuKQaDwWA8mjDvKQaDwWDoDDMaDAaDwdAZvY2GQqFAdXW1MbQw\nGAwGo5GjNfkNz/PYuXMnNm7ciNOnT4PneRARpFIpevfujeeeew5jxowxidtfUFCQ1sAsBoPBYNxL\nly5dcOnSJVHG0jrTCAkJwYULF/DOO+/g5s2byM7ORk5ODm7evIl33nkH58+fx8CBA0URo43Lly/X\n+Mk/6j8LFy40u4bG8sOuBbsW7FrU/yPmw7bWmcbhw4dhZWX1wOtWVlYIDg5GcHAwW65iMBiMRwSt\nM43bBmPx4sXIzMystw2DwWAw/tvovBFeXl6OoUOHol+/fvjll1+Qm5trTF0MLYSEhJhbQqOBXYs7\nsGtxB3YtjIPewX2XL1/Gli1bsG3bNjRr1gxHjx41lrYH4DgOesplMBiMRx4x7516u9x6enrC29sb\nbm5uyM/PF0UEg8FgMB4OdDYav/76K0JCQjBkyBAUFBRg5cqVuHLlijG1MRgMBqORoXOR4vT0dPz0\n008ICgoyph4Gg8FgNGIMSliYk5MDb29vMfXUC9vTYDAYDP0x657G3cyaNUsUEcYgP1mFlc1jcYAL\nw2q3y0iNYrEkDAaDYSgGGY19+/aJpUNUVAoe+7tcBRws0PV6MLiOjojofwVVJaxgFIPBYBjCfzLL\n7aYJGdBYSPHC1TbwDrTEjOMtoHC2xtbJGeaWxmAwGA81Om+EKxQKbN++HSkpKVCr1QCEdbIFCxYY\nTVxDSDylgNP+NAQe6Q6JREiiKJFw6LO2FW4Mi0ZZXjM4ekrNrJLBYDAeTnSeaYwePRq7d++GhYUF\n7O3tYW9vDzs7O2NqaxAn5qSjoKcPAgfb3PN6uydskefthP1vsUh2BoPBaCg6zzQyMzNx8OBBY2ox\nmIJUFbyu5KLT2R61Hm/2kg9yF6cCaGJaYQwGg/EfQeeZRp8+fRp9MN+BOdnIbe6KFj2taz0+6D0X\nOFfKcSNCbmJlDAaD8d9AZ6MRHh6O7t27IyAgAJ06dUKnTp3QuXNn0QVpNBp07doVTz31lF79VAoe\nNqGZ6PRZszrbWNlKkO/viqjlRYbKZDAYjEcSnZenDhw4YEwdNSxduhTt27dHeXm5Xv32vV+ACjtr\n9JruWG87txGuKNqaB6CpASoZDAbj0UTnmUaLFi1q/RGTjIwM7N+/Hy+++KJe0Ys8TyhblQ6P1+qe\nZdymzzxX+OSWsJgNBoPBaACNKk7jrbfewvfffw+JRD9Zp1eUwbpahWGfumtt69XGAgX2djj9e2lD\nZTIYDMYji87LU8Zm79698PT0RNeuXXHixIk62y1atKjm/yEhIQgJCcH1zzNgO7oZZJacTufSdHNB\n2s5i4ANXA1UzGAxG4+PEiRP13kcNoUEJC42RqHD+/Pn4559/IJPJoFAoUFZWhvHjx2Pt2rV3xHIc\nyvLVcHC/E5yXECbH9ZALGJgVDCdv3Wzg4a+LkPltKp4v6Srqe2AwGIzGiJgJCxtkNLp164aLFy+K\nIqA2Tp48iR9++AF79uy553WO43Dwi0IM/ejODGFlwHVIvawwM9xf5/GL0tQ463cagyv7wcq2Ua3Q\nMRgMhuiYPcutKdKTc1ztS01pa+5EdF/dWwmPxEKMXu+r19iuzWUosrZB9NYKgzQyGAzGo0aDjMbs\n2bPF1nEPAwcOxO7du2s95n2zEGkXq6FRE87PSETZk75wba7/1ozc3xFJu8oMlcpgMBiPFAYVYTI1\nHMdh9YCbkF4ogtLRClK5GlOzO8PCWn/bt/2lHBSHFuLFtA5GUMpgMBiNB7MvT5mTaYdbwGqMD6y6\nOWJSUqcGGQwAaDvWEU7Z+gUQMhgMxqPOQzfTEEuuRk04aBGBnjeD4eFvIcqYDAaD0Rgxy0xj8eLF\nyMzMFOWkjQGpjEO+gx2u7mCb4QwGg6ErOhuN8vJyDB06FP369cMvv/yC3NyHvy6FqoUDMk8wo8Fg\nMBi6orPRWLRoEWJjY7F8+XJkZ2djwIABGDJkiDG1GR2nHvaojmH7Gg81sbFAYqK5VTAYjwx6+6p6\nenrC29sbbm5uyM/PN4Ymk+E/zB43NqSbWwajIezdC0RFAc2bA87OQGkp0K0bUEd8D4PBEAedN8J/\n/fVXbNmyBXl5eZg4cSImT56M9u3bG1vfPYi5mQMAigoeJxwi0De/7z2pSRiNnJgYwN1dMBSBgQDP\nA08/DaxcCYic3obB+C9glo3w9PR0/PTTT4iLi8Onn35qcoNhDKztJSi0tkHsvkpzS2How+rVQHy8\nYDAAQCIRZh4rVwIpKWaVxmD81zHI5dYYiQvrQ+yZBgCsbBEH58ddMGGlj6jjPlRUVQF79gBXrgCz\nZwvLPc7O5lZVO9u3A+3aAbU9tOzdC3TvDvg8wp8lg1ELjSa4b9asWaKIMCcWAXYovVxlbhnmIzkZ\nePxxYPhw4M03hZvyrl3mVlU3CkXd+xYjRwIzZwIZGabVxGA8QhhkNPbt2yeWDrPh3sMOSH1El6cS\nEoD0dGDfPsDJCfDwAN5+GwgOBqZNM7e6B9m4EZBKhZlGbXAcsHix8D4YDIZR0NloyOVyLF68GGPH\njsW4ceOwZMkSKBQKY2ozCa2G2MKp6BE1Gjk5wkzDxeXe11u1At54Q9hobkx07w507lx/Gx8foEMH\nQMPK+TIYxkDnPY2JEyfC0dERU6dOBRFhw4YNKC0txdatW42tsQZj7GmolYQjVuHond1H5yJO/wk2\nbxaMwksv1X48MVGYbZw+3TjcWM+cAZYvB/75R3vb0lJAqWQzDgbjFmYpwtS+fXvExcVpfc2YGMNo\nAMA62yi0Wh6A3jMdRR+7UaLRANnZQFlZ7RvKtykqEvYHtD3dmwKFAsjKAlq21N52wwbg3Dngp5+M\nr4vBMAPZ15Q4viAP1dlKeA10xNCFbvWWuzbLRni3bt0QGRlZ8/uZM2fQvXt3UUSYG4W3HTLCH6El\nqm3bgG++qd9gAIJb6+rVptFUH0RAUBDg4KBb+2efBebOBcpZtD/jv0fookKc63AeVdHl4GQcCpam\nYoNbNDJjlCY5v84zjbZt2yIhIQG+vr7gOA5paWkIDAyETCYDx3G4cuWKsbUababx97BUqAtVmBXV\nWvSxGx1EQF4eYGEBuLpqb3/pElBZCfTta3xtdVFeDqhUuum9zSuvAM8/L2zqMxj/EXa9lQfNz4nw\n+q0D+r7kBEDI2L02JBmWFwrx+JUgeLV5MGu3mPdOnRfxQ0NDRTlhY8Sjhx1y/swytwzTkJICPPOM\nsEegC7m5gFxuVEla+f57wM1N2JzXlR9/FJaoGAwdKM1RI3xJMcpTlfDqaYsBrzvXu9xjDqI2l4Nb\negPNN3ZGj8l3Zt1SGYcZYf5Y04PH3r7XMDOnEyQS42l/ZOtp3E38MTlihl7CeHVv0cdudERHCy6r\n1ta691myBJgwAfDVrxa7KBABmZlCehCZHo4KhYXAvHnAunWNYyOf0WjZ/XYeaMkNFLrag/ewhnVq\nOSQ8j/Yb2yNorL255QEQUh7tcI+C9Qt+GPerV51ttnlehOXEJpj0d5N7jjWa4L7/Cq0HWMNOo0Jx\nhtrcUowLEbBgAVBSol8/Hx/z3Xjz8oCnnhLiM/TBzU0IVoyJMY4uxn+CvwalQPHzTXiu6oQXCrrg\nxWuBmFLRHVbTmyNt/GUc/a7I3BIBAJvHpUPuZI0xv3jW2cbaXoKO69vC+p9k5CWpjKaFGQ0I07sC\nG1tcP/gfjwyPixOWevRN/TJsGLBwoXE0aUMuB06caJjRunlTmKUwTEp5gQbrxqRjjeslbLI8izWu\nl7BlRhaqShpX7Mz6cRmwPpWLfpe63eM5KZFwGP+nN5yWdkDFB9dwYYt5a+6kXayG65F0DNjeRuuy\nU9BYe+S1dceeyalG08OMxi0UnrbIjDSiB1VUFFBcbLzxdSEmRtjY1hdnZ2DUKCGbrKlZuxY4eLBh\nfUePZrU2TEzEH6U45H0OiqhS+MzzRfttHeH5SjNU7MvHTu+LuLyrcXgphv9aArtdqehxvAuadLCs\ntc3A153Bz2mNpOdiUJpjvlWIQ9NTkdfdB2362ejUftiGFvC8mIPks8YJvtbLaBw7dgwAcPToUaOI\nMScWrW1RdtUIM40//hAC6XbsENJ2XL0q/jl0QS4Xgt6eeUb/vhwn9F+2THxd9aHRAIMGAZMmNay/\npaUw01AZb6puCtRKwv6PCrCyUwJWNonByjbXsePVHFQWNa4n9z3v5qPw1RjYfRyAFzM6YvgiN3R+\n2g4jv3LH83mdYfFsMySPvYQzf5eZVWdRmhq5867B6qNAtO5b/97e2GVeKGvuhK1DbppI3b0khMnh\nGZeHket030/0DbJCXjdvHHvNODnY9DIab7/9NgDgnXfeMYoYc+La1Q6UKrLRyMwUbnrBwcBXXwFt\n2gDvvCO4sJqa0lKgoKDh/fv3B8aPF0+PLuTlAb/80vD+EomQjPHECdEkmZrw30qx1fE8CpamwqqF\nDbymesG+pwOKt+ch1PMcdr+dZ26JAIBDXxRCszgBTTd2xvBFbg8cl0g4TFzjA8uPApEz8ypi9ptv\nxrFj5E2UtHbFk5+569R+3PE2cL1egFN/mj6tTti8DBQ85gPvwNpnQ3Ux5Ldm8IzOMcreBlueuoVf\nf1vYF4lsNObMEaKu/fyE311dgdBQ4OOPBVdWU7JjhxD01lB8fYGpU4GkJPE0aSMzE/jhB8PGsLIS\nfh5C1o9NR+HcGDi84Y+pZd0wbY8vnvrOA89saIpZeZ3htbw9FD/fxKruidCozecEGX9MDvmC63D/\nreM9rqC1MeJzdyint8TVsbFmcTyJXFUGt7gCPL1Ph8wCt3BtLgPNbomk/5n2OhelqeF1JReDlzXV\nu2+LntbIbeWOA6+KH0rAjMYtAgbbwEWlgLxMpHX7yEghV1KPHve+znFASAhgo9v6pGjY2AB2doaN\nsXatUF7VVJw6Bdy4YdgYwcHAli0PXQLDNQOSIdmfjc4R3THqW49aN0D7veyEQQndIU0sx5oO8WYx\nHJVFGkSNjEHVhBbo97KTTn0m/eWDypZO2D7QwM9WT3iekPBmIjQz/eHZ6sEAuPoY84sXwHHY9brp\nHvb2v56NXF9XtOiph3v8XXRZ1BT2x7KgVor7vWBG4xbW9hIUWVoj/qhIs42ICCC1Dg+G0aOFjeX4\neHHOpY3DhwV3W8+63fV0IjcXePJJcTRpQ6EQEg4OHmzYODIZ0LOnkMDwIWH9uAxYn81HyKUgtOxd\n/w3Dw98CY+M7wSK7Cn/3Nf26+8b+SZB72mHypibaG9/FxOOt4JRWitBFhUZS9iD7PyyATK3BmF/1\nLxwnlXHw/dQfqlWpUCmM7xCiUvCw3peBDouaNXiMns85oNLaEoc+FfcaM6NxF5WutkgNF8FoJCYK\n+xd9+tTdZutW/QLsDMHfX0gXbihduwpFmkwRIV5cLF6MhaurcL0fAva8mw+bXWnoeawzfNrpto7t\n5C3DsPMdYX8xH9tfyjGywjsc/7EYLvGFGBceoHcEspO3DO7fBqLyiwQUpBrfUaG6ikfFkpvw+Khl\ngyO9B/3PBVV2Vtj5mvFnG6GfFKLSxsrgJKq2zzYVPduFXkbD4VbCOHv7xhElKTZcCzsUXxLBaFRW\naq9F4eEhRFnnGXkjs6pKiIwWI7mkTCak8jBFSpmLF8UrBNWmDdClizhjGZHLuypBixPgu7aTVq+e\n+/EOtETgtk6QrUwyiXdSWZ4G+e/Hw+7jALg2b1hJgUH/c0FxoBt2jkwWWd2D/PtiNuT2Vnh8vh75\ny2qh1ectgH9SUV1l3NlG4Z8ZcJ7d8FnGbZ781gPuheJ+H/QyGmFhYQCA8PBwUUU0Fpw62UKdZKDR\nIBLW0CdMqL+dRAKEhxs/YtnCAvjoI/1ScNTHypVAt27ijFUfRUXCEpUYtGkDfPJJo16iKsvTIG5y\nLKpntETP53TM5nsfXUbbgXurDdJejENJlnE3mbeOSEZZU8daPaX0YfRef7jH5Rs1gK40Rw2rzano\n8HMrg3MyDZjrjHJHG+x61XgzurNry2BfqcCIr3Tz7qoPO1cp8rvpvxxXH1qNhi75Sh6i9FX10rSv\nLWzyDHQFVKmEtBu2ttrbVlcDK1YYN2jutdfEu/kCQEUFMGaMcTUXFwtVBbt2FWc8qRR46y1xxjIS\nW/rdQGUTB4xfZdgf+NOLPVHWygXb+htvkzlyVRlco/Mw6qDhWaE9/C2geNYfV1+6AZ43zn1k57RM\nFDZzxmNTG2aM76f1p37AhjSj7W1cXZgB+fCmsLAWZ/fgmUP+ooxzG62qQkJC8P333yMhIeGBY/Hx\n8fj2228xcOBAUUWZi7ZP2MJNITfM2+DAAd1zNTk5AZ99Buza1fDz1YdGA3zxBfDYY+KN6ewsLE+l\np4s35v0olcK1EZP0dCHQshGy/ZUc2KeWYuJp7WkidGFSWGvYZ5Th3znir73Ly3gkz7kObm5rvWMH\n6mLCGh/IlBrsfitflPHuJi9JBZej6ei7soVoYw6Y64wqOyvs+Z/4elOjquGVWoQnl/uINqadq555\n27Sg1WgcOnQIbm5umDNnDnx8fBAQEIA2bdrAx8cHc+fOhZeXF44cOSKqKHPh3ESGSqkFbp424Mnc\n31/40RW1WliKMQb79wvBhLoWL9KV3bsbntpD1/Hvd1U2lMGDTR+cqANX91bC4s8kBKzvIFq5YUdP\nKVr/1R7S3xKRECau08Kmp1Ihd7bB00vEK6Urs+Tg90NraJYnoSxPXNfovc+lIS/QA+2e0GHmrwdN\n3/dD9apU0d2cj76RidyOXnD3088l2KSQHqjVasrJyaGcnBxSq9X6dBUFPeU2iFWul+jAooKGdeZ5\nomefJSov16/funVER4407Jz1UVIi/IgNzxPt3Uuk0Yg/NhHR/v1ESUnijqlUEgUFEcnl4o5rAGX5\nalpvdY42Tcs0yvhrR6XRX/YXSCkX53O6sLWcdnERlHJeIcp497PCL5ZW9xXvc0+LVtBuLpySz4n/\nmWs0PP1tF0W738kTbcyyfDXt4iIo7lClaGPeRsx7p16LZlKpFF5eXvDy8oJU31TVOpCeno5Bgwah\nQ4cO6NixI37++WfRz6EN3tcW+VEN3AzneSG3k75BdC1aAE3083PXikYj3p7A/XCc4HpbaAQf+8xM\nIa5El1rg+mBhITgoWIqzpCIGm/veQJW3HSb+Jd5SxN1M+bcZNJZSrBtmeMZTlYJH7Ix4KKb5w6+H\ncSLsh+5oBbfTWbguUqzUwWmpyOvm3eDguPqQSDi4v+GH0uWpou3F7H8zF/mejqLPisSmUcVpWFhY\nYMmSJYiNjcWZM2ewfPlyXLt2zaQa7NvbojqhgZvhO3YAGRn6p/Hu2xf4/HMgLa1h562NnBzgyhXx\n9wZus2BBwzLmasPWFhg6VPxxAWG57uuvjTO2nmx/JQf2KaWYeEb/GAddkco4PHG0LVwishD+q541\nVO5j0/gMqC2lmLDGOAYOAJp3s0LJ8OY4NcXwzMQJJ+TwjM3DyPXGy2Aw7FM3cEQ49Lnhy8saNYG2\npqPle4a72RqbRmU0vL29ERQUBECIBWnXrh2yskxbhtW7lx0sshv4pNO7t5AgryG89ZYQuyEWq1cD\n27aJN979FBcD16+LP+6SJcYzdDNmNAovKmPsY9SFb5AVLOcHInfetQYH0Z1dWwbHA+nouyvQqGVE\nAWDSlmawK5bjwAIDkmsCCJt2E0UhzUTbrK8NqYyD3Ut+yPvB8NlG6IJCqGRSDHzTWSR1xkNno7Fl\nyxaUlQlBIp9//jnGjh2LixcvGk1YSkoKoqOj0atXL6OdozbaDLGFa0VVw74EH34oxGk0BD8/IYJc\nDFfWykqhcNLzzxs+Vl107Qo4Ooo7OwIEd97Whrty1oqNDdCqlVnjNXJvqBA3LgbVz7dEtwmmCZId\n8bk7Sju5Y3f3OL3dRIvS1EidFQe82QYBA4yfL83aXgK3T9ug/OvEBhdtOvp9MZxyyjFxm/HLE4/6\n3gOW1SqcWGLYTK7glzQ4vNjc6EZZDHQ2Gp9//jkcHR0RERGBo0ePYtasWXj11VeNIqqiogITJkzA\n0qVLTR597tNe8FrIjmvAU9nbbzc8oZ+nJ7Bvnzhp01NTgTVrDB9HGxqNEGsiFtevAz/+KO6M626s\nrIQEiGZKXqio4HGgZwwqurhj4mrjLfPUxvTIVgCAv3vpnqVYrSTsCL6OsgBXjP7RwLxlevDEh64o\n87DH5qf1fyCpruKR9/EN2L7bWnRX09qQWXKQzfBD6hcN3zc69WcpbOVKjPzW8GA+U6Cz0bi98b13\n717Mnj0bo0aNgtIIT2wqlQrjx4/H1KlTMWbMmAeOL1q0qObnhBHqJEgkHIrsbXHjiJ4374QEISbC\nkOy1Z84Ida0N5fp14LvvDB9HG8OHi5vTyc8P+OAD8carjcWLDavR0UBUCh7r2l+DxkaGGadE3uTX\nAQtrCZ6+0B5214uxdrj2GxzPE/7qkQipXI3nIo0086uHoXvbwOVUlt41LDaPS4fcwQpPfmFYpLo+\nPLXUE/YVCoT/1rB6G9cXpEE1pplowXwAcOLEiXvulaKiq5vViBEjaPbs2dSiRQsqKioiuVxOnTt3\nFs2Ni4iI53maNm0avfnmm7Ue10OuQawIuEYbnsnQr5NcTnTtmmEnVqmIcnKIChro8kskuMO+9pr+\nbr8NoaKCaMUK8cabPp0oLEy88WpDpSLKE89NUhcUlRpa0fQqrXK/TJXFpndVv5vUCwraYHmWVvVK\nJFU1X2t6A5IOAAAgAElEQVQbpVxDK9pep7W25yk/RWlihXfY/W4ebZZFUnGmSqf25zeU0U4ugm5E\nmN6teuOUTFrtEk0aTe3XtC5OrSihbdLTRv9eiHnv1GtPY/jw4Th06BBcXFxQXFyM77//XlQDdurU\nKaxbtw7Hjx9H165d0bVrV4SaIjnefVgF2KEyTs/N8B9+AM6eNezEMhnw00/AyZMNHyM0FJg+HTDF\nsp6dnZCi48ABw8ciAr75xnhuwrdRKoFevYSgShOQl6TC+uZXwakIzyZ1hK2z8ZdM6qN5NysMvBgE\nLqEc6zwuIXLNnWR2PE84vbIUm9yiwRVW46kbQWYNMnvqOw+UtXTGtse01wrJS1IhcUYcNK+01jvZ\noxiMXeEN60olQhfq7obO84T495KhnuJn9u+FPnC3rJBWFAoFtm/fjpSUFKhv/cFxHIcFCxYYVeDd\ncBxnkjxXoZ8WIuvnDLxQqEdm1MJC4cbnbuC6JJHgGjp0qBBboC/79gFubkLxIVNw4YLg7WTo5vW5\nc8CiRcJ7NzYlJUKOMGPtndzi6PfFKJofj7Iu7pge0VLU5QdDUSsJW2dkwXJrGjQch0p7a9hVKMAB\noOf8MGG1d6PYlK0q0WCL3xWoW9hj5oXWkMoe1FReoMH21legae2AWVGmX0q7zaEvClH8WSKeyuuh\nkxHY+34+yn9KxrjiHrCyNe53Q8x7p85KR48ejd27d8PCwgL29vawt7eHnaGV4BopLQfZwqlUz5nG\nk0+K8/TKccKNM6cBWTSTkoSU4qYyGADQqZOQel1lYE2Erl2FyoCm4LffjJbvi+cJ59aVY2WTGBR/\neB0OH7fBrKjWjcpgAMIG7rMbm2KMIhhtt3eC7/vN0WZTR4yv7oVJf/k0CoMBALbOUoy81BEWN8ux\npmUcitLu/RtLPqvATr9LULtZ4/kzrcykUmDox24o97LHxidStLYtzVGjenEifL5tY3SDITY6zzQ6\nduyIGGOn8daCqWYaGjXhsEU4gjP7wLmJjn706elCVLcYkfKlpcA//wBz5+rXLzcXiIoCRo40XIM+\nREQIhsqQ9OsjRwLvvQeYIvmlWg1cvSrqUlj2NSWOzc8FQnNgqdagekRTjF3TxCQePI8CVSUabOiT\nCI/rBSjs6Q2bltaovFQBr/h8FA/1xdT9jcNdNfuaEmc6RsHpu3YY/LZLrW14nrC6zXVAyuHFhLYm\n0WWWmUafPn1w5coVUU7a2JHKOBTY2OL6YR1nG1euALNmiWMwAMEDq7BQP9dQhUIoWjRkiDga9CEn\nB1i4sOH9VSpg48b6Kx2KiUolFJMSwfX2/PpyrGx1DRfbn4X8cgWafNka4+S9MHWXLzMYImLrLMWL\ncYHw3xkEiY0ElZcqYNnCBl0v9cT0UL9GYTAAwKedJRy/aYeyd+NwdW/tHpgbJ2TCJqsCk0+3MbE6\ncdB5ptGuXTskJibC398fVlZC7hmO40xqSEw10wCAlX5xcBnmivF/6lDfQKMBCgoALy/xBMTGAps2\nCelFdEGtBqKjhXrYpqagQAhK9PDQP4UKAERGAp9+apqKgLdJTBRmRi1aNKh7WZ4GW0IS4RpfiIph\nzTBsqQ+82jTizKQMk7L9pRxIVt28Z8ahVhLWPZkKu7AcdDncBQEhxg+WvI2Y906d1xMOiOEh8xAh\na2WL0qs6zjQWLxY2sN9/XzwBvr5A//7CzViiw4TwiScAMyR4BCBs/g8YAPz+O9C+vf79/fyAvXvF\n11Ufhw4JRr4BRqMoTY09Ha8ArtYYcLNn405jzTAL4//0xtE2Vih57xpWf2UH3sMadsmlgLUFgs93\nhW+QcZI+mgKdZxqNAVPONHb9Lw8FG3MxK7uT9sbV1cKPo2FF4B/g0CFh2UZbdHdqqpDoz929YU/6\nYpCfL7j5NiS4cfRooRyr2DU06qOqSnBtfvJJvbpp1IS/va6Ab2KDmdFtavXmYTBuU16gQdjiIpSn\nKtFsoD36zHY0y1KaSfc0+vbtC0BIIOjg4HDPj6PYN8lGhF9/W9gV6jjTGD5cSE8hNv37C7ELqVoi\neBcuFGqNm8tgAIIjwPDh+vcrKQGWLjWtwQCEGdzGjXrnCts4PgNSlQYzztfu/slg3I2DuxQjv/bA\nMxuaot/LTo1m78UQ2EyjDuRlPMKdwjGgvD+s7euxrUTCU6ulZcPiKrRx+LCQrbauUqUbNgCDBgHe\n3uY1GjwP3EpoCWc9MnWeOCGklDfH0tqJE0KVRT8/nZpnXKlGdNB5BB7rbtL1aAbDUMziPfWoYeMo\nQbGFNeKPaimXWVQEBAQYx2AAwl7FokXA998/+FSs0QhFiwDzGgxA2Hf5+mtgzx79+llbC7Mpc3D1\nql7xMAdnZSC3sxczGIxHGp2Nhlwux+LFizF27FiMGzcOS5YsgUJhQC3th4AKN1ukRWhZonJxMc7S\n1N04OAj7JYmJd57my8uFJZ05cwAf02ZMrZNvvgHattVvyWfZMqE2hzkYNw7Iztapae4NFTwvZOPx\nFcZPt81gNGZ0NhrTp09HXFwc5s2bh7lz5yI2NhbTpk0zpjazw/nZoihaS7bbnTuFGA1jYm8PvPyy\nsCEeEQFMmSLkudq/X9gAb0x88onuRiAxUSiK1LSpcTXVRXW1zgb/yAe5yG3hZpTSoQzGw4TOLrex\nsbGIi4ur+X3w4MFo3xD3yocIx052KDmspZTj6NGmi8D+6ivh3+7dhfob5l6Suh+OE1KBxMUB/fpp\nb5+cDKSkmH4T/DYtWwp5s4qLhRljPagP56HZ27rtfTAY/2V0nml069YNkZGRNb+fOXMG3bt3N4qo\nxkLTPrawztOyPPXuu8CKFaYRdBsvr8ZnMG6TlQUcO6a9HZFQg2TGDONrqo+KCkBe/77VzUgFXCqq\nEFJHWggG41FC55lGVFQU+vbtC19fX3Ach7S0NAQGBqJTp04mjww3FYFDbFEqr4JGTXW7V377beO9\ngZuDoCBhnyAhQXAQqAuFQnDTNZYDga4EBwvR902a1Nnk1Ff5qG7jXr8XHYPxiKCz0TBHXQtz49pc\nhiqJDDfPKNCmXx0eM/36CZHQxq4D8TCRn6897fj+/cJGtLkNLpHWuuzqiEI0fb2ZiQQxGI0bnY1G\niwbm6HnYKXWyxc1jVXUbjZMnhRgNxh0mTQK+/FLYe6nLKFhbCzW7zU2nTkL512HDaj1cXqCBV0k5\ner+iR+wJg/Efhs23taBpZof8C3Xsa1RWCssa5n5abmxYWQkzjbpqyKemCkkKu+hR5MpY2NgIRr8O\nN+GzK0uR72Cne4p8BuM/DjMaWrDrYAvF9Trcbi0theAwZjTuheMEj6hly2o/bmtrujTo2rCwEFya\n7/IMvJu03SXgu7ANcAbjNnoZjUuXLmHZsmX45ZdfcPnyZWNpalQ07WsHy8w6jEZYmLAuz3gQf//a\nKwgSAa+9BnTrZnpNddGkSZ2JFqUxJWj+lJOJBTEYjRedjcbSpUsxdepU5OfnIzc3F1OnTsXP5krF\nbULajbSDe2VV7YXte/cWgvsYD+LjI9T3qO07Mm+euLVHDKVpU+DgwQderizSwLO8Aj2fZ0aDwbiN\nzgu1K1euxNmzZ2vqgn/wwQcIDg7GvHnzjCauMeDhbwGFRIqk0woEDLjvafSnn4R/5883vbCHgfHj\nhUJHcvmdJ/n33hM8zRrTkp6bmxDodx/n15Yh394ejp6sAh+DcRu9lqckdxUDkuhSGMiErI3Zgi6r\nQtD0x6YoVZSKOnaJqz0SD9ayRPX66+IWXvqv0aQJ8Nlnd5IY5uUJwZAjRphX1/34+QlVEu/buE/Z\nXQp1ezbLYDDuRueZxsyZM9GrVy+MGzcORISdO3fihRdeMKY2nTldUoI5+Q54pefHeKNFW/wvJRsv\n+AB9ncT5g6cWdsg/XwnA/d4Ds2cD06c3vptgY+KHH4C0NCFLr0YjFIp68UWzSDldWorDxcV4y8cV\nGl4DF5tbG9wcJ3yG98Vr0KUSNJnHEhQyGHejVz2NCxcuICIiAhzHoX///uhq4oC22nLC5yqV6Hz+\nPFa3bYuRbm4AgISqKrSwssKXYZ/hrd5vwdnaMB/7Lc9noyy8BC8mtbv3QEmJkLuoMS21NEby8oRE\niyNHCh5nZrheM+NiEFZWgaleXghSXMb0g/PRrNOHuDRwEqxkVkIqGF/fmkJSigoexxxO4bGUYFbO\nlfHQY5Ya4VOnTsXAgQMxdOhQtGvXTnsHE1CqKEV2STKie/RAk7sCxQJuZX49rHLDxdD52DPmV4PO\n4/OYDRTba0mh3acPcORIvSko/qukKxSwknBwk8kglWhZ8/f0NKuX2bHkYzgQ+SNip26Gm5UdAH8k\n+PbFlIMf41CSM54KfEoIRLyreNTFTeUosrFhBoPBuA+dNyZeeOEFZGVlYd68efD398f48ePx0+2N\nYDMx5/RKfH3uj3sMxt2MDRyFo7LOOJV2yqDztBpoC5fK+wL8eB4ID38kDQYALM3IQNC6CbD50gbu\ne37G98nxJquqqCtEhDdizmDSv7Oweci7twyGgI+9B46N+x19Wg7Hy/HxqLayApYvrzmeuKMUigC2\nn8Fg3I9ey1NqtRpRUVE4duwYfv/9d9jY2CA+Pt6Y+u7h7ilWTkUOWv67ANsffxdP+rSpXS/Po/P5\nM/ihVQBGuLvX2kYXeJ5wQBqBHgnB8Gpz68mzoADo2xcw4fs3N0lyOZamp2Jpm0BwHAelRgkiwoab\np/BruRPa2tpibdu24BrJcp2GCJ/EX0QPLhfjAmvfd+KJMCE2FrKKPGxWysANGAAAWOV1BZ7TffDU\n91pyaDEYDwFiLk/pbDSGDBmCyspK9O7dG/369UP//v3h6ekpighdufuNp5Sk4GTKScwIqj+1dlZ1\nNbwsLSE18Ea21v4CWi5ujX4v33r6VCiEIj4ibLZXajRYlpGGSxVVsJNK8UdAawCATNJ4UldkVVej\nfeRJ+JacwNUxXz1wXK7RILSoCK34bHTy7GR2w1GuVsNOKoVEBx351XI0O7ELR1atQf+f/4ba1Quh\n1qfQ7epjaNKB5RVjPPyYpUZ4586dYWFhgZiYGFy5cgUxMTGQa6lDYCw0RPgsR4EJnaZqbdvEygpy\ntQp/xO416KIpPW2Rc/6uJaozZwyu2EdEKJGX4I0Dr2PxxfV4yt0dkz09EZ4aDr/VT2JO9AGDxheT\nj2KOAVm7cGDwa7Uet5FKMcbdHbP2zsWrp1ebWN2DPB8bjSVpN3Vq62Flg7NBnfCV51nEKTJw6d8K\nlFtYMoPBYNSCzkZjyZIlCA8Px44dO+Du7o6ZM2fC2dk8mT/3FxYitrISdlLdgq7Cy8rw4bVInEg5\n0eBzyvxtUBZ3l5Hs1g34++8GjwcAi1JS0H3nu5CSBjeenIvnvLww1NUVg/wH4ev+72HHxV+wNXar\nQecQizF2KoT2n4ZmjnWnCOc4Dj+OWoV/0q/jdPppE6q7l6iyMuzJz4FNYbjOfYK8OuBD/7lYGXUT\n8VtKUNmS7WcwGLWh8/LUsmXLEB4ejgsXLsDf3x/9+/dHv379MGTIEGNrrOH2FKvZobV4qXkgFrTt\npXPfFRdWYHfCbux5dk+Dzr3zjTwUbM/DixkdhRd++QUoKgIWLGjQeACQplBArSxBS0fvWo8XVBWg\nAlb4J68QH/v5mWXJJ7q8HGtycvBzm9r3jWojLDUM/s7+aOrYTKflIbF569IhbI3bjNRn/tTu2XUX\nypQUbFcoUPm4Gq5Pe2Dcr40o1QnjkUOhVuBY8jHkVuTj8XaT0czKqsH3ALO43FZXV+Ptt99Gt27d\nYGHGamv5lfkojf0Sr/Q/r1e/4e0m4VClcOEacuGbBdug6o+7ZhrPPCNkR20Av6Yno5ODM/o7uwDW\ntRsMAHC3dYeVWo0dBQWw4Qjv+Pk36HyGIFVkYapX3RprY4DfAHyflobq4lR8bIY6LEPtNHii53i9\nDAYAWHIcJr/3PvbkvI3SJ0sAMKPxX+Puv/+G3guMDRFhc3YqZkSuR3D5YfTyG4Qfr17FlR49cCoj\nCnNP/YblfWahj695MkXrvDyVl5eHXr163WMw3jdDCo0d13djpG9XeNo46tXPydIORyRtkV1XjQct\ntOxrA5dqOXj+lrX+5BOgAdUMz5aW4q2EOEQm7dOpvYNMhq3t2mF+QjT2JhvmOqwv0SV5ePzvAbCv\nztS77zOenliSkY79mTFGUFY3X6amopPvIIxo04Ao/SZNkDj8UyjsNJiNy8ivLBBf4H8QpUaJEkUJ\neKq/AqK50PAa/BOzHd13vIUuv3dBVnU1el+8iOHRZ+C2fjbeDH0TCYUJ5pYJQDAYE2Jj8VVmPpb0\nfAbHZhzHd4MW4mrPnuA4Di7ObZDl8wwGX4jE12dXmEWjzkbj8OHDD7y2f/9+UcXown7Lx/Bsv+/0\n7ucok2GyhwdWZdcSpKcDrs1lUHMS5MarhBc++QQYNUrvcaZejkCzvB14M2iSzn1a29lhg68F5uya\nInperbooUqnQN/oSBgQ+g/Ye7fXu72ttjeEWBXjl9CqT3kyaWlrCtaEzYQsLyL/bBY2jJdzsfDDs\n+O/iitOBanU1EosScTnnMnIrck1+fl0pVKmgIULwymBYb/kIzZZ1REpJCjbn5SGhqgqXcy43irid\nXKUSCrUCW2M3w9lnCI7POA5XmQyLW7XCtCb+eKnbS7CzsMOXZ//ETTM59gCCsfjwxJf47ORn+Mzf\nH9E9euC15q0e8Ppsb++EtH5D8GaHEZB59jeb2Hr59ddfqWPHjmRjY0MdO3as+fHz86MpU6Zo6y4q\nAEiuVpNSo2lQ/+uVlTTlyPcUeiO0Qf3X2pyn06tLhV/69ydKStJ7jA+Of04JBQkNOv/rx76kD+LO\nNKivvrx54wb1PL6BMkozGjyGWqOmPqv60IoLK0RUVjfnMs7RxC0TDRpjbdOztHVqKl0tK6KF18+J\npKxuNLyGkstyaE9+PkWVldGXYV+Sy/qXqen62fTb+d9of0EBrc7KotCUSIrNizW6nvqoVFbSa2HL\nqd/ZE+QYFkZXy8spryKP9hfkU4VaTUREc+LjyTsigmz2raIeK/vQ3vi9ZtEqVyloQcJVcgsPp0vl\n5Vrb78rPp29TU4mIKK8iz9jy7kGpVtKTO18nx31/UnZ5tl595Wo1/ZuVrLWfDrd6ndE6UklJCSUn\nJ9PkyZMpJSWFkpOTKTk5mQoKCkQTcZsDBw5QYGAgtW7dmr755psHxQIkVysNOsefUX/SmE1jGtR3\nRdOr9O+8XCKeJ0pJ0avv2dJSOlRY2KDz3qZAqaQ/MzMNGkNXPrl5k3Krqw0e51xmNE28cIyqG2jo\ndSWpqopcDm2kJad/avAYGg1P+7jDlPXMFzWvVanVVK5SiSHxHiqVlfTDqR/IY80Esjx2kAZHR9Oe\n/HwiIspSKKhAKXzP9xYU0ISYGLI+foRcV4ygx9c+TjcKb4iuRxvhKeHUdHFT6rznC/osPprK6rkm\nap6nsKIi2h63nV7Y/x6dLy01oVKijNIM8t8yj3yO7qAblZV69a1SVZPrpv/RovAfiOd5Iym8A8/z\nVKlS0k+RP1GxokLv/tcrK2lQxL/U5uc2lFWWVWc7kxoNU6FWq6lVq1aUnJxMSqWSunTpQnFxcfe0\nAUCzz24z6DyH87PIctMHVFRVpHfflT0S6e9hKUQVFURt2+rV92B+Fu0VydBWqZRUrpSLMlZtqDTi\n3iRXZ2VR1a0nUWMxI+YSOW58iyqV+t0k7iYhvIp2SsJJU3jnu/F5cjI9cWQ5pRTr95BQH1kKBb0Z\nd5EmbplIh1LPUY5CobVPhVpNxdVVtPriXzTpanSNUTEF50tLaUT0OQpLCdO777GiIvru1hN8akmq\n2NIe4EZFKfkvbUmfnvyKqtT6f4+VGg3NiLlIVqGb6PXjDz64ignP8/ROYiK9Fh9v8Fifn/iC2q16\nos6/3f+k0Th9+jQNGzas5vevv/6avv7663vaAKArRQ8ul2g01aRQZFF5+WVSq6tqXs/M/J0SE9+j\n69dfIoVCeEIvU6ko/NJkio4eRNHRg6mqKrmmfVraD5Sa+h1lZ68llaqk5vXbTxwbJmfQirbXiaqq\niLLqtur3k19ZSE0XNzVoqeduehz9mwYeNc6ST2RJCfnsWUInkk+IOq5SraT08lxRx7yNQqOh1mfO\nUHqV9mWI+tg2O5tWN40matNGmE0SUbVaTT+dXkLNl7SguPx44nmeeF6t91OoXCWn907/SVnlOaTQ\naGhFZqZeY/A8TxqNgpSqStqfl0o8z9P57Biatu9tyimJp+rqXKquzrmrvYaqqpKpqiqZ5PL0e8ZR\nqcpIra4ijaZuw8PzPP14aRullWaRmucpuarqgeM8rya1Wk4qVfldr2tILk+lqqokqqy8swyrVCup\n355X6OXdYygz/9A97cvLr1BFRRxVVt64Z3ylsoBUqhJSq3V/EBh++TIdz9Nu4Hmep+rqfFIoMkku\nT73rdTWVlp6hP65vom8ur7jn9eLiMCopOU1lZVH36K+qSiK5PJ2qq3PvGb++z1ehUlC70OXUPjK8\n3gcA4XOvJpWqjJTKOysVGo2KysouUklJJJWUnKI0uZxcwk7QscJcysvbTvn5u6iw8GBNezGNRqPJ\nU5GZmQlf3zu1C5o1a4azZ88+0E6TOhUXkxUIDFwDO7u2AIDo6L5QKNJhaemBDh22w9Y2AADA89WQ\nyVxgbe0PicQagOCN1KnFPMhVFbCUSGBpeSe3kFTqgKqqeFRUXIaLyxOQyYQAr3Pn2kKjKYfXc+5I\nj1oMxJQB332HnGWjwHFWkMmc4ewcAqlUOIdKVQyOswDHcShUy9D2TATGBYyFj70H1OpSaDRVsLT0\nBMcJLqElJRFQq0ug0VTAw2MsJBIhAWNKyudQqfKh0VSgdeufIZMJLr4/Oq3FxdIcHD3zBwZ0PwwL\nCyHIMj7+JRBpIJXaw9//C8hkDgCAvLyt4DgZpFIHODsPgEQiRDqr1RWQSm3BcXf8IbKzw2Cbsxt9\nR8x94NorFBnQaMqh0ZTBwaFnTb+MjJ+hUhVBoylDy5bfQiKxuPW5DIBKVQCer8av9DmOF+UjfeQb\nOHeuIziOg1Rqjy5djtdctxs35kEisYVM5gRf33dqxiktjYRUag+ZzBlWVs0ecJO0kkhwrWdPyO4r\nDEakqbnGRDxKSk7U6PTxeeHWd0SJuLhnoVYXwa53IZQlB4Cfw6DRyBEe4QhAg25SewwOXoURV64g\nqo83rp5xAcBDIrHGgAHC5qlGo8CpU24AOEilNujbN7/m9eMRblDwPHrBBtcrQzDI3gszvVxx6pQr\niHhIJJZ3tZcjIsKx5vXb4/N8NSIinMBxEjhIbMB5FCETDthpMxDjo7rAwcIKNhZO6N07teZ9XboU\nAoDAcRYIDk689boCp0/7ANCA4yzQv39ZzXlPnXIDx8kAzhYvl7yJBOsO8HVMRZOY7iBSIYuzQJ8+\nWbfGkSM83AEcJ4NM5lijn+erER3d79b3zR49e14BAEigxgduZ5CiUGJP9Cy8/ERaTfu4uGdv6ZGh\nZ8+rt16vwtmzASBSgeMs0a9fwS2dlTh1ygMcZwGZzAm9e6ehrLoCP1zeipH0DRaChyTZAvCIq2l/\n+rQ3eF4FicQK/fuX1ox/7lxbSCSWkMmc8Nhj12r03LgxDz0llpBKHaDmX8DRojx0tpAj++aHNdet\na9ewmutw+fLj4HklJBILBAcn3zpvOSIinMFxlrCwcK25bmp1BaKiuiKjPBfvSJ0wqms83CwsoFaX\n4/z5TiBSQiKxRnDwzZpxhM/FChYW7ujdO6Xmc7x+fSYkEivIZC7o0iUU2zt2xrTYC9hi/xccpIBE\nYgVX16EP/B0bis7BfTzPY/369UhOTsaCBQuQlpaGnJwcPPbYY6II2b59O0JDQ7FiheBGtm7dOpw9\nexbLli27I5bj8N5708FxMlhaemHw4KEICQnR29/6Ynk5nr8Wh0Pt/ODtoD0GgedVUKnycO1YMhLG\nESZldQR4HjdLf4BcngS1uhTt22+AhYVQz+PcuXZQKNIAELa4HcThtGhEhkxF/KUuUKvLIJHYoGfP\nK7C0FHJ3xcSMA88rIZXaISDgjxojkJEh1NeWSu3g6TkFUqlQMrW0NBKfxYTCRcph/mPza4xAfv4O\nqNXFUKvL0aTJKzU34/j4l6FU5kKjKUPHjrtqjMnp082gVGZDIrFBnz6ZSFVZYvHx9zDBYTusJBoQ\nKREcnAqZzLHmfRHxkMmc0KXLsRojlpT0wa0vryOaNp1bY/TKys5DKrWDRGKFMs4LTcOP4qcmVnjB\nvzV4vgoaTQUcHXvXfHaZmb9BrS6BWl2Kli2/AsdJQES4dGkAVKpiaDSlCA5OAcdJQUQ4e7YVSGKD\nQkU5enW/AA87j5r3pVaXgEiJAQMUt8bhcfny45DJXGBh4YqAgD9rAp7y87fDwsIVx3pnwv/LMei2\n/WXQc1NATw4Dx8nAcRzUPI93b97Etvx8nAgKggNfDg9b9xrDSUTQaCoBEAACz9mgTENws7DAe1f2\nQyaR4qM2PWBv7V7TXq0uudWfq7nGRAQidc3rdxv02khVKPBi7AUMc7LBO627af0u1wURgeflIFLj\n45hj2FaswsHHhqGlrQOUyqxbD0EWsLBwafA5AOByRQWOFOTg7RatDdBZBZ5XgUiNy8WFGHz+KJys\nHBAbHAQLqTU4zgI2Ni1q2ms0Fbc+RwtI9MznliyX44XLJ5Bydg4OTg1FgFuAHlo1t3Qqaz5fNa/G\n99f2IPfmOiwc8AFcnHreastDoUiFRGIJjrO852FWHyJLS5GccRgbdv2F7tXda/62Pv30U/G82XSd\nkrz88sv06quvUmBgIBERFRYWUvfu3UWb8kRGRt6zPPXVV189sBmuh9x60fA8OR8/QJP2f6RXv8pi\nNR3ECVKvXku0cKHW9uUqFfW5cIFKjLCRKhY8ryGVqozkajW1jIyksOJiqq7OJYUim5TKIlE3A9+4\ndIjAOdkAACAASURBVIimRW4VZSye56mq6iYdSd1PgRvHU+5dS19yeRqpVGV6aU+LVtBuLpzUKp6o\npISojj2YyJISKquuIO/FzSlg27u0+PRi4nme1DxPscXZ9NLRr6nXil4UuPFFeun6dYPfp67wPE9y\ntZpmxF6lV/bN03sp9FhKBH2SlEgqjYY0WpZWxIDneZoWG0OzQudTTnmO9g510PLwOhoSvq3BHpW6\nsuriKnL+Yyhl1LPZrAtKjYYW3rxZ421mDMoUZdRi0xx65dCCmtfEuncSEekcp3H27Fn8+uuvsLER\nnnZdXV2hUqnEsVwAevTogRs3biAlJQVKpRKbN2/G008/Ldr4dyPhOMzy9sa+3BQo1Aqd+9k6S1Eh\nsUC6+wDg7be1t5dKENG1K5xkxlkFVPI8hl++jCJVwwIWAYDjJJDJHPBbVhba2dqiv7MzLC09YWXl\nDQsLF1EjZn/q8gTWBk8QZSyO42Bj448D14/iSWdfeNrfybhsbe0LmcxBv9nn36XI83KCVMYBx48D\n06bV2i7YyQkOlnaIfPkqevkNhkqjwpXKSlicPImBMYmI5Pzw5eAvET1+GX4P0P2p1FA4joOE4zDM\nxRkuVnZov6IvXjz6YDbi+9mccAgh/4zAzJ1ToVGVQkkECccZPVKa4zhM9fKEhwzo8HsQfru4Rue+\nRdUVCCspAQDEDnoGR/qNh4VE51tZg5je5Xm067oQr6YUoFKj0bv/9aJUjDu+HDKOwyJ/f53z5jUE\nBysH/C/4DRTJi/W6v+mMrtblscceI7VaTUFBQURElJeXV/N/sdi/fz8FBARQq1at6KuvvnrguB5y\ntcLzPM3ZN0dv98W/7C9Q/BNfE22r34vrj7REavH3JCqvNmxzVhtfR2+nmTtfMHickSdW0pr444YL\n0oJcraZZ165RZQM8W+7nt4wM+vLqIVEcDFZ0iqe1o9KEXxQKwdlBD0zhnqkPu7LTyDP8BLU/e5a2\n5eXR3vi99FLoB/S/o5/SocRDtL+ggAZHR5PtiaP09vktVK023L26oSy9EUVuJ4/QSi1edqnFqfT+\n4ffJZ1kQTY25avJrXq3R0Iy4OHojIYFOppykKqVu35E18cdItv8f6nVyC2mMPCO6n7OlpVSsVIp6\n79R5T2PdunXYsmULLly4gBkzZmDbtm344osvMGmS7pHNhiJm0i0AuCmXo0ytRpCDg859VjaPRdMQ\nDZ5cEQjUUTEQAMbsfR/2MgusG/6FGFLrpLy6HG1/74pvR6zE1DYhDRrjWv41DPhrAGJfi4WnnfFr\npMw9txkojMQvTza88mOZWo3WZ88iLCgIbe3stHfQwnqb82j1eyCCZzgCGg3g5QVkZADW1gaPbS54\nIpwtK4OE42BZmYRPE69CranGuy0CoHLshAqNBsNcXWFjxKdeXYkoKcHXaWkY4+6OU+fmI6GaR0cn\nb7zT80VkSDxwqKgIy5KvYKz6Ar4IfhEtnFuYRScRQcHzeHXPLBwpKsDS3i9iXNvR9c7MOh/fiCdc\nPbC4y+MmVCrwflIS9hcWIKZXsOmLMAHAtWvXcPToUQBCUSZT1woX22jsKShAnkqFWT4+OvdZ1SMR\n3dI3oGvEs0AdmV/TK4sxceOTODj1IJysjZ9i+8NLe/BHEZAdMhJWek7To8vLMebMv3jDvgD/6/0/\nIym8l/zKfLT7tSNCpx1DD+8ODRrj6+QkXKlSYGOHhvW/m9wbKlwIOIMn5H1hYX3r+ikUAMfV+2DA\nEB8iQrGiGC/FnEfT6pt4o8MwbCyTQsHzGO3mhu4O+i07GgslzyPk3HF4p6/CpnH/ILW6Go5Uhci0\nU8gsz0AabwNHnyH4yM/PrIkRiQirsrMxu2lT8xgNcyO20QCAyPRIpJam4pmOz+jUfv24DEhiMvBs\nfC/hpnIfp0tLMfP6dcTW4gJqLHiex9jYWPRwcMAnemaVJSIkVJSipa0dLKSmy178VPh65PAWOD+w\nYTPVeQffgbWVK74LmW+wln3zC5D7ZyZeKOhy58XZs4GQEOC55wwen/Hf5nplJYZeuYLs6mrYKbMx\nufoEHvMfisBmQ9DPTDWH7scsqdEVCgW2b9+OlJQUqNXqGiELDKgn0RiIr9bgw4u7MbnDZJ2eBv7f\n3pnHRVW9f/wzw44MCAiooA6hiLIH4m6o4dc0zB1308zMr6Ytfkurn1hpmZlbqWUuZbmb4gZRKYmm\nIIssLriBgKyyzQw7zPn9cWMCmWHuDHcW4Lxfr3nB3OXc514u97nnnOf5PJ2FfHQ5ewNA81oedVIp\n3rx3D6FCodYcBgDw+Xx806cPLpeVQUqk4CsJ02zgdGEhXrK1RV+B9m/snwZNR7/YWMSKRAiwVE2x\n+HzuffycdAC33kzhxJa8yFIY+j5zDXbvBiQSTtqntG/cOnVC5uDBqJVKwefxYMCbqWuTNArrJ9sr\nr7yCM2fOwMjICBYWFrCwsEAnDsaSdY2HvReKuk7ClUx2suN2fQ2QYfi83F5GTOFDiAquYrpdF67N\nVEoPU1MEmtXh+R+G4YFYuaT3sfxczE2JQYZYN0qq1kZG2N6nD26Vl6u0Xz0hWJuRgeVDPkQ3Afth\nxZYwvlOG5yY9M4wYHQ3Mm8dJ+5SOgRGf30yVtj3Cuqfx5MkT/Pbbb5q0RSf4CQToZWGPQmNHVtv3\n6JwNSZWo2fJ6aT0+iliMpb3HqVz8hyscLR1hKwzBmN+3IDX4Q5gbmcvd7na5BPNvJcG/6BT6WKpR\nd4IjptvbI+JBBEKjvkdo4FpW+xjweIgbHAQgiBMbSnPq0KWiHP5znuntvPAC0K8fIJUCWuw1Uij6\nDuv/hiFDhiA5OVmTtugEHo+Hn9x9EGDN7q3Vfpgj6mGOitKmsdoj4/+GxLCL1iaTFRE5ehkmdqrC\nE3Eu7sh5i68nBLXih/DO/R7nJ2xhPZSlKZ7v9jy+KDHHvntRSrfdmpWJI/nc9oxi94uQbyWAmeUz\n14HHA8aMATg+HkV32NjYgPdPDkp7/tjY2Gj0OiqdCPf09AQA1NfX4/79+3B2dobJPxElPB5Pq45E\nExPhjamsrYSZkVnLGx06hIi5NhBGjoDb6H/f5B9WVqKnsRGMDPRDzutWeTkCb97EYAszvOZgi3F2\n3bEp8zGkPEN8JBTqVanLA2mROHzja/w2R3ElxPCip5iUFIsN1mV4x5e7MeN9Ax+Cb8bHq1FySumK\nREBdHaDhf0KKdtD080NfkHeeXJ67UqeRkZHRoiG9evXixBA2aPKP/r+78TiQuA+5IdtbHl569AgH\nfYrgFNobI9+xxvWyUlgZGqGfHs7viOrq8Oq1XxB+7zRqn5zF5pd2Ypn/61obd40/JkHS1/kQ9DPH\npO+6wtBY8XHrpfX4v4zHmGxnB79n8mYIIXC5eAQW+ecQM+0H5Y5dBQ52ikevjS4YsUxOMMBnnzH5\nGq+/ztnxKLqDOg1uzl3p2IRQKIRQKMTOnTtlvzde1l5Y9ZwnnqtMwa93fm15wwMHYG5WhuK71Sio\nqcbouGj8dO8P7RipIpaGhvh1+HxULPwVVR9VYcWAxVpzGGdXFSJ7RhJ4RnxUnsjFAa+WazAb8A3g\nLxAgKOkmJsVGgBCCgpoanCosBAHBFGkiLk/+llOHUZheC9uKCgS8qiB663//A0aN4ux4FEp7gPWA\ndmRkZLNluqgRrinsjI3x8bDVOPU4vuUNp06FWNgDkvRqDL96Bp1FCVjr+R/tGKkmPB4Phiqqe7aG\npLBykM334PiLFxZEO2PiQ29YPixB5GdFLe43yc4OJ50FiHl0Fr229sLOuO9wUyIBn8fHpqAv0dmU\n29Dg2O9LkWdrCVMLBf8GGRnA229zekwKpa2j1Gns2rULnp6eSEtLg6enp+wjFArh5eWlDRu1hrPj\nCPxpFYySloQYP/0Ull2qUZNTCd+KWMQHvQlTw7YrNcE19XUEN+emoTxECP+ZzDCTpb0BTJY/h9wv\nHyvdf6SjD56EfIM/5/2J+f1exjpnOXMNHJF7oRSGAS1Ifbu6Ahs3MtnhFAoH5OXlYcaMGejduzf8\n/f0xfvx43L9/H2PHjoW1tTWCg4N1baJSlM5plJWVoaSkBB988AE2btwoGxcTCASwtbXVipENaGNM\n8o20NJjy+dgmTyKkvh64cQNfnu8CqwMSvJHlo1Fb2iLHF+Si8ngOZpc+zyjG/kNtlRRnLGLw3FFP\n+E6x0KGF/3LINBYu37th4LwWkgtDQoBPPgH69tWeYRSNoOs5DUIIhgwZggULFmDx4sUAgOTkZIhE\nItTW1qK8vBzfffcdzp4926rj6HxOw8rKCkKhEEeOHEGvXr1k8xnadhja4jNnZ6CmBFOPTUW99BkJ\nZJEIxatXoryHCGZl6suRt1eqJFLwDmag99beTRwGABiZ8lHqY4eb2wt1ZF1TspOrYVlTA78ZSsQq\nt24FjLQnr0Jpv1y6dAnGxsYyhwEAXl5eGDZsGEaOHAkLC8UvU2VlZRA2kggqLy9Hz549Ua+GTHtr\noVlLz2BnbIzN/Z5HUVUpQs6tRHVdNQDmLeHthJMYF5ABH6EIVhLuaom0F04vzoXIuhOGLJIv0tj3\ndTsYxyrPVtcGN74rRb6DVYsRXQCAP/8EwsO1YxRFZ/B46n/YkpqaCj8/P7Xss7Kygo+PD6KiogAA\n586dw9ixY2GgA4Vi6jTkYMg3xIfjfka8iRcqaisQLxZj3M0b2F9pga2GczBh1AswJ3WoFEl1bare\nUCmSwuhYJvp9IVS4zcD5AlhXVSH/vu4dblFEMcwDWeRfTJ0KeHsr347SpiFE/Q9bWpsXFRISgqNH\njwIAjhw5gpCQkFa1py4dXrBQES926YpHYxaBx+Mhq7AQo2274oSZJTp5DwUMeSgzMEbWzWq4juAu\nBLQtE/ZmHsptOmHKa4rnB4xM+cizsUT8gTKMW699fa4GpFIC24wS9N8jVL5xdTWwaRMwbJjG7aK0\nb9zd3XHixAmF65U5leDgYKxZswYlJSVISEjAKB2Fg3d4wcKWaPgjTrSzw3s9e6JTVBRw5QoAoNzc\nBHnJ1Tq0Tn+oryMgJ7Lh8mFPpdvyfayQG1mmBasUc/PXctTy+eg7ioXDt7ICVq8GiloOF6ZQlDFq\n1ChUV1djz549smXJycm48s8zRdlEtYWFBQYMGIC33noLwcHBOlN06PCChSrh5ycrvFTb2QRFaZp3\nGsWZdfjt/XzUieoxeI09eg/Vv/Dei5tKIOXzMGK58oJTwmArZH70SAtWKebW/mJUu6kgDXL2LDNM\n1U6DPyja49SpU1i5ciU2btwIU1NTODs7Y8uWLRg+fDjS0tIgkUjQo0cP7Nu3D0FBQVi7di38/f1l\nobghISGYPn26bG5DF7AuwrR48WIsW7ZMp7kZug6Zw/LlwJtvAv37Y6//Axh3Ncbcc8rfrtUlKawc\nD6Yko6S7JWBlBPtbBTD6yA0vfaK7oR157HVIgWCsLab/2F3ptuKn9bhqdxVD8ofC0l43asD7bW7C\nfokTxm9geR1zc4G0NKYoE6XNovPnh5bQechtA9HR0fDz84Orq6sswa+9JfcpJTgYcHMDAJg4maDm\nieZ6GoXptbg/JRlY5IxFme5YlOIKu71eqP0sDYkn9ac4UF5aDboWlGLsJgdW2wu6GKCgUyckHBZr\n2DL5iArq4VAixpClKmSXFxYCV9nVW6FQ2jush6fC/wk77Cjeuhm1tcCOHUAQU8dB4GyCqjjNjc2H\njX8EuNli0e6usmWDF1ji2F/PIXVeGrxeeb5ZLoQu+Gv9U4h72KjUa6hxsUTW7yJghfYrBl7bXYoC\nSwtYO6kgq+LlBdy9Czx9CnTRr14ehaJtWPc0evbsiejoaPz4448QCoXg8/koKCjQpG36hUgErFkj\nC8y2dTOBcalmehrX9opgm1aEieebS2hM3cc4kQur9SPfofx8Ieyn2am0j/VgAaqTddPTeBJeBuKj\nhrN6/Bgo0+0EPoWiD7B2GkuXLsW1a9dw6NAhAMxM/tKlSzVmmN6Rnc1MiP5Ddy8TdKrSTFb47dUZ\nqJ4hRJdezTOR+XwebFf2Qtm3jyGV6rbHl3unBg7FIoxcrdoEcd8JAljl6sZp8G+Xoed45RP2zZg8\nGbhxg3uDKJQ2BmunERMTg507d8LMjAlTtLGxQW1Lwn7tDQMDYMEC2VdHb2NY1tegtorbBL+EExLY\nFEkw4VvFcwRjP7UFjxD8/lkxp8dWlb+3FSO3mzUEXVSb0O43xhzmdbXIvaNdKZaK0no4iMTwe7a0\nK1vEunF0FIo+wdppGBsbN9E5KSwsBL8j1U5OSABSUmRfTcz5kPCNkJPKreNMeD8L4iBHmHdW/CDm\n83kwnOaIrN25nB5bVUoiiiF4UfWqdgaGPBR0FiD5uHYfwvGHxHhqbo7O3dWQiXdxAYyNgb//5t4w\nCqUNwfqpv3z5ckyaNAkFBQVYs2YNhg4ditWrV2vSNv2ia1dg5MgmiySmJshJ4W5eozC9Ft0ePcV/\ndigPXR2zwR7dcku0/rbeQF0NgX1mMQL+q14pVOIqQG6Udp1G+pky1PRtxeR7z5609CulVciTRr9x\n4wYGDx4MDw8PeHt749ixY7o2s0VYv3LNmTMHfn5+uHjxIgghCAsLQ79+/TRpm34REcGE21r/W3+h\nxtIYT+9w5zT+eL8A5T1s4NBHuaqqtZMhcp/rgotr8jH7VA/ObGDLjV/EkBgbw3mgesmGXYYJUPhz\nPsdWtUxtogh2c9iFBstlxAhGKv3AAaAFRVIKRR6EEEyaNAkLFizAkSNHADAZ4aWlpfj555/h4uKC\n3Nxc+Pn5YezYsbC0VHMYVcOw7mlIpVLExcWhqKgIy5YtQ6dOnRAbG6tJ2/SHmhpg0CDmTbMRxM4E\noofcOY36c7kQLu3GenvnNxwgjdRNBFvawWJUeqj/1t1/siVsn4q0NpkvlRLYPBXDY2or/hENDICl\nS6lUOkUtFEmjjxgxAi4uLgCAbt26wd7eHoWFTUsItElp9IboqcOHDwPoYNFTYjEQHd1ssbGjKaoe\nc1PVLflMOcxqajHyvRYqyT3DsGWdYVVZiUfXtF9ZjtwshWMwe1uf5bnBJuAR4PEN7eh3ZcZXg08I\nhANNWteQry8jJ9ORgkA6AKFRoeCt44G3jofQqFDWyxsvUwYbafTY2FjU1tbKnEgD+iSNDsISHx+f\nJj8JIcTLy4vt7pyggrnccv8+IZcvN1sc9k4+2dMthZND7B+ZTn7wva/yfnt63yE/T8rixAa2VJXX\nk/O4TAozalrVzg92SeTMqgKOrGqZcx8UkB/skrhpLD+fkBRu/u4U7aGz58c/bN++nbz99tsK1+fk\n5JC+ffuSmJgYuesPHTpElixZQgghZOLEieSPP/6Qu5288+Ty3Gn0FBtyc5mM4GdwHGgO8+JKTg5h\ndK0Qrq+rliQHAN1ndEHtRe1Ww0s4LEGJqancPBJVMHC3RGG0dibD8y+Lwe+npEofW0xNGR2ySm7+\n9pSOgbu7O+Lj4+WuE4lEePnll7FhwwYEBATI3SY4OBgRERFtRxq9Q0dPVVTI5EMa03uEKWyqK1Ff\n17px+VvhFTCvqcWQ11Ufbw981xr2ZRLkpWkviurBr6Wo7NN6CZCugQLw0kQcWMSCNDEcRnDkNCwt\ngUuXgI8+ApKTuWmT0u5RJI3+119/YdKkSZg3bx4mT56scH99kUZn7TTmzJmDjRs3YvXq1ejevTvC\nwsIwffp0TdqmP9y/L1dCwqqrISr5hshKbN24fNyWQhS5d1FLS8q8swFy7Tvj+rclrbJBFWriy2D3\nohpZ1c/gPV0A+xKxxifDpVICu2IxPKdw5DQamDiRCcXetEm1Em6UDsupU6fwxx9/oHfv3vDw8MCa\nNWsQHR2N6OhoHDhwAL6+vvD19UXyPy8ja9euxdlGShQhISE4dOiQzqr2AdDxIJ+K6MTc+npCtm8n\nRCqVu3q/ZQK5tKW4VYc4aHajVW38MjWL7Ol9p1U2sKWuVkrO8KJJVlIVJ+0dN/ib3PmjnJO2FJF2\nqYKc5F/VTOP5+YTs2EHIlSuErFlDyOPHhFy9SkhtrcJ7hsIB1dWEnDxJSHY2IRMnEiKRELJnD/P/\nqoA29rhTG3nnyeW5q9TT2LNnD+7KGdvnglWrVqFfv37w9vbG5MmTUaYv4nCVlUBOjsIK8nUOZihI\nVH9sO+1iJSyqqjFMFanuZ3h+iQ1sHxVrJXw1OawcFYZGcPJqZRTSP5Q6CHA3TLPzGnfCxCix57iX\n0YC9PbBsGdC/P1OoKTub0ag6dAh44w3g4kXg5ElASuvJc8bly0xE45kzQLdujJBoaSlTXTElhcmp\nomgM1k5j4cKFyMnJwfLly+Hs7IwpU6Zg69atnBkyZswY3Lp1C0lJSXB1dcXnn3/OWdut4v594IUX\nFK42EppBkqa+04j5qhBP3brA0Fj98Um30eao5fNx89dytdtgy93jZRALWz801YCRuwBFf2vWaTy9\nIoahh4YTpaytmXDcIUOAFSuAefMYKX17eyaLPDQU2LcPqKvTrB3qkprKSKRs3Qps3Ah8+y3w44/6\np7clFgNhYUxwyoEDAJ8PDBgAODoC77/P1HQXi4EHD3RtabuFdUb4qFGjMGLECMTFxeHixYvYvXs3\nUlNTsXLlSk4MCWo00Txw4ECcPHmSk3ZbTXU1UK74YdzZ3QyFx1qRYHe5EM7/11wCXVVEbjZI3VeM\n56dqNlO5/FoZOgepn5/xLN1HCvBk42PO2pMH/4EY3d7TXIVFhZiYAB4ezO8BAUyS6H/+wzyYPT21\nb488SkqAc+cAJyemRz1/PmN3aSnj4P77X2D6dGDsWMBQDc0uLrl2Dfj8c6aHoYiAAMDfn3nRO36c\nmXOicArrnsbo0aMxbNgwHD16FH379kVcXBzS0tI0YtS+ffswbtw4jbStMnfvAs8/r3C1Y4AZzNQM\nu31wtQqdK6owbFnrI5G6T7RB/XXNqt5KpQQ22aXwnMVd8SSvqQLYlUlaHYGmiPo6AodSMbyna2h4\nii2dOjG9kaNHAXNzZihL15PnaWlAVRXw8CGjqzZ7NmOjuTnQvTujgLB3LzB8OPM/oMtex4ULTK/i\nH/mNFuHzmSGssLCWHQxFLVi/Onh5eSEuLg6pqamwtLSEtbU1Bg8eLJNKZ0NQUBDy8vKaLd+wYYOs\ncPr69ethbGyMWbNmyW0jNDRU9ntgYCACNV23ubaWuQkV0DfIHE+rKlFdIYWJuWp5K9c3FaKqt63K\n+8lj6H874+pndyAqqNdY7e0Hl6vAA9AnUD29KXk49DFChaER7v5eCfeXzDlrt4E7kRUoNzRipeel\nFbp0YR7MH34I/PorMxeiCw03QoD165l8k0b/U80wMgKsrJgQ48hIRun3n/9VrVFf/6+DNWd5j/B4\nwMCBzNBgB6y4GBUVJcse5xxVZ85FIhHZvn076dmzJzE2NuZsRp4QQvbv30+GDBlCKisr5a5Xw9zW\nUVZGyKefKt3skHEMSTghVrn5A4J4ErHuqTqWyWW/VQKn7T3L8UW5ZE+PVM7b3eOUSk6+mcd5u4QQ\ncnJJLtnjxL3NnPDLL0xmeZZ2M/pJSgohwcGqR3fduEFIUhIhmZmasUsRL71ESEKCevuePk3I4sWE\nEBo9xRWsX3F37NiB6dOnw8fHB2FhYVi4cKGsbjgXREREYNOmTQgLC4OpKXdvsq2irg6wU56lXe7Q\nCY9+l6jU9OO4athIKvDCO9zND/D8rZF9RnP5GqWXS9FpEPd1vY09BCi5rpmhj+JrYph46XhoShGz\nZjFv7vPmaW+oKj6eeVvfulVhRKBC/P2ZYba5c7Vn7++/MwEEPj7q7T9hAtOT+uknTs1Sl/z8fMya\nNQsuLi7w9/fHkCFDcPr0aV2bpRKsncaKFSvw7rvv4u7du/jjjz+wdu1a/Pbbb5wZsnz5ckgkEgQF\nBcHX11c/xBCvXwd69VK6mXF/C5TGqeY0rn5RiHxnW5hacCfF0meGNUxvac5pCNLL0Hc6d5FTDTiO\nEsDgoWachtEjMZxG66nTAABXV+bBuGIF8OiRZo9VXw/cvMnM0z33nHptuLgAf/4JvPsuIGeomVMq\nK4H9+xlHpW72M4/HDLFlZXFrmxoQQjBx4kQEBgbi4cOHiIuLw5EjR5Cdna1r01SDbZeksVBhAx4e\nHpx1ediggrnccO0aIdevK93st0+fkn3WiSo1vd8ygZxfU6iuZXKpqawn53CZZKdUc9ouIYRkJVWR\nM7xoUlfLfcJawaMach6XSW01t23XVNaTC/iLFGfVctquRvjtN0Ly8jQ3VFVbS0hAACG5udy0d/Ik\nk9hYzf29Rggh5MEDQubP5y5BsqBA58NTf/zxB3nhhReUbvfBBx+Qb7/9VvZ97dq15KuvvmJ9HHnn\nyeW5K50I37VrF3bu3ImHDx/Cs1GYoFgsxtChQzXmzPSCsDDgnXeUbtZ/ggWq/k8CqZSAz1f+RpQe\nUwVbcTlGvs9tFTgjUz7yunZG7K4STGqhxrg6JPxYhkI7K7WkTpRh52wEsZExbkdUwGtCJ87aTTlX\ngTJjE1g76ThUlA1jxgA//wxkZjLJalwiEjET2b/+yl0I6uTJwNtvM0NWs2dz02YDFRVM72LxYvV7\nGM+ibJi5pWAAjva7desWnm8hErOBkJAQrFy5Ujbacvz4cURGRqpnnwZQ+t80a9YsvPTSS/jggw+w\nceNGkH/GMgUCAWxtbTVuoE5xc2PE6ZTg5GWCOPDw+EY1q0p2Vz4pQLWrHcwsuVcJNh9ug6LfSwBw\n6zQK/iyDsR/3Q1MNiLsJcP+cmFOn8fC8GJLuejw09Sxz5jBZzRMmACdOMPMdraW+HsjPBxITgVde\naX17jdm4kQnXPX4cmDaNu3bPn2dyMr7+mrs2laGu01CBZwUGly1bhitXrsDY2LhJQTsfHx8UFBQg\nNzcXBQUFsLa2hqOjo8btY4tSp2FlZQUrKytZecIOQ2oq8OQJk+jEgiI7SyQfEbFyGrxLBXD5alej\n3wAAHrVJREFUzEXpdurgtcAad4MzWfd62GJ6rwzOS/tw1t6zmHhaoCRGDIC7ZKyyWDHMfPWzZKZC\nbGwY9dykJKBvX1YvLS2ydi0zD6GJh6KxMdMTqK5mEhe5cHLHjgHOzsCUKa1vS89wd3dvkrT8zTff\noKioCP7+/s22nTZtGk6cOCGrKa5PqFTu9eDBg/jkk08AAJmZme273KutLRPnzRKTwZ1R+JvySeiU\nc+XoVF2D4Rwk9Mmj33+YvJm7v3NX66E4sw42lZXwm6W5t/YeLwpg9IjbyXCTDDF6BrWhngbAPIQD\nAoDTp5kXF3WjlAhhEvPeegvQ5EPHzY3Jcg8IaH01w+pqwMyMie5qh7V6Ro0ahaqqKuzevVu2rFyB\n2kRISAgOHz6MEydOYBqXvTgOULnc66FDhwB0gHKvhw+r9ObUf441BA9KlW4X92UBin3sW6U11RJ8\nPg8lztZI2stdFNWNA2XI7yzgNNLrWbynCmAvkaC2ihthv0qRFHYV5fCZpllZFY2xfj3zEJ4zR/V9\npVJGHuTRI6anrEICrlrY2THCjL/+CkhUiyKUQQgQGMgkOrq7c2qePnH69Gn89ddfeO655zBw4EC8\n+uqr+PLLL5Gbm4vx48fLtuvfvz8kEgmcnJzg4MDtUHNrYT1DGBMTg8TERPj6+gIAbGxsUNue6yQP\nG8YoaLLEe2InZNfVIT2mSuEQVV0NgeDvPPT60YMrK+ViO8YaRacKAXAzDvokvAw8L83NZwCAtZMh\nyoxNkHq+Ar5TWv+gTz4tQZGpGQRddFBDmSuGD2eGlr76iuktODmx2+/sWUZPqlGxH41jbQ3cvs30\nzk1NVdOpqq1l5FUuXGDaacd07doVhw8flrvu/PnzTb4n62mBL1ruVR61tcybXvfurHcxMOShwLEz\n4n9Q3Nv4LbQIFWYmGDBbs0MmAW9ao2teKWdv7Qa3StHzZc0MpzVG0l2AB+e5GaJ6FC5GZY82NjT1\nLHw+4yhsbJhcg7Cwlrevr2ckPgYMYBR2tQmPB6xbx8iSf/YZ+/3q65leUVJS6+dvKFqBlntVxPLl\ngIFqb6mWo21QGv5U4fr8757AYq7moyAcPYxRZmKCuF/UHCpohPhpPezFEgyYr/l/aDMfAcpucOM0\nym+IYDGgnTyEFi5kwlCjo4E7dxgNqIb6HHV1TEjtxo1M1NG6dUwPWVeqCq++Cixdyrx0VbOoaLlr\nF/D990z1QxX/3yi6gXUfcs6cOfDz88PFixdBCEFYWBj66UJoTRucOwdkZAAvvqjSbiPXdkHsjw+Y\nieOeTS/tjV/EsC4tx9gvlMuScEFVf2vcO1yMwa+17sEZu1+EAoGFxkQQG9NjtAAZv7dCZr4RnbLE\n6L2e5XBOW8DZmRmmunyZKT28aRMTsWRgwAwFBQcDDg5MAIcuaXBWlpZMQSqxWL4ESEUF82L2xRdM\nTgZFcxRzq37N2mlUVlbiwoULuHLlCng8Hmpra+Hs7Kw/OlFcMmgQoz6qInbORsjtYYPwFbmYfaqH\nbLlUSpC67CHMZwo1kpshD8cJ1sjbkglA2Kp2MsNKAC/ND00BgPdUC1QsL1dLMbgxxZl16FxTBe9X\n2uHDaMQI5ichjMyGmRl3CXBcYWrKOISICObl6/FjJnzY2JhxJl9/DcycyeSN2Nq2y0gpveLDDzlt\njvVfa968ebh9+zbeeustLFu2DLdu3cLcuXM5NUZv+OADZqxVDTw+7QHTs9koy/u3QtuF1U9hWlGD\nyT9oryDM4Des4FAmhqhAvfNogJ9cip4TtOM0rLoaosTEFClnW1eBMPGICPmWAhiZtuOHEY/HhKbq\nm8NozNixwJIlTI9ILAZ272bmLsaPZ+YLJ0ygDkPTbN0KfPwxp02y7mncunULt2/fln0fNWoU+qvx\nNt4mWLUKEArV2nXQfEv88ElnHB92H6/edsPNUxLUbboHp2/ctfoQs+pqiHwrAa5/X4oxH6k3ZCEq\nYOYzAhZqNnKqMeWOAjy6IIZ/iPqT2Nl/iFHfp41PgrcnGvIMBgzQrR0djcpKptfH8fAf66fY888/\nj2vXrsm+X79+HX5+fpwaoxfcv89059gWe5HDtKt9wC+pwVmza8idmQTeyj4YvlQ7b+tN8LNG1mn1\n8zVi9pYh31Kg1bBV8+cFEMW0bjK8LkWELsPbySQ4pd1gYaHFnKGiIib8eeFCpogWhyjtaTSIFNbV\n1WHo0KHo0aMHeDweMjMz0bdvX06N0Qt69mQmGVuBVVdDvFrohftRVXBwM0Ln7roRzOsTYo2MFffU\n3j/rbCl43tp1dq6TrXD/TI7a+0ulBLYFIrhP1ZzkCYWiDs9qT2mU6Gjmw4W0yzMofZqdPXtW4Tqt\nXgRt8fHHTD1kV9dWNcPn89B3lIYzcZUQME+A0jeq8CS1Bo4eqt88himl6LHOWQOWKcZ7Uifkz6pG\nXloNuvZV3eaMmGqAAM8NZqcZRqHoC4MHD8bevXtlw/6BgYH4+uuvWSnjNsPdnfMeRgNKh6eEQqHC\nTy8WBYraHGvWMBN47QCZVPp3qg9RFabXooukHAGvaneYx8iUj3xbSyT8JFJr/5TjIhTZW3Iq1khp\n/4Smp4MXFQVeVBRC09Nlyxr/3tJ6LggJCcGxY8cAALm5ucjLy1PPYQBAH831tHmEaKtuY+vh8XjQ\nqLmVlYwA28OHqskg6DGHpmWjIkmCRffcVNov7O0CPD2Uh9fyvTRkmWIOjM5Avbger8WqrgT8g899\nGHc3wbwLPTVgGaUto/HnhxIEAgHEYsXzdTk5ORgzZgxSU1Oxbds2PH36FJ9++qnKx5F3nlyeO413\na4yJCRAX124cBsBIpVs/KoFUqtoNU3i2COYjdZMo1mu8FQzvlKm1r+m9MrhM1F60F4XCFd27d4et\nrS1SUlJw7NgxhISE6NokubB2GpWVldi8eTMmTZqEyZMnY8uWLaiqqtKkbdpn+3Ymrrkd0X+sOQiA\nxBPscx/q6wi6PCqG31JuKwuyxX+eJRwkEpQXq5Zjog0JdwpFk4SEhGDjxo0QiUTw8NCssKm60OS+\nxrz5JvelNnUMn89DmY8dkncUst7nxi9iVBkZwnWEbibyBV0MUNCpE24cVC30NnZ/GfKtNSvhTqGo\nS0VFBXr06CH7bNmyBWfPnsXatWtl20ydOhVHjx7F9OnTdWhpy7Tt5L64OCA2lhFI4wJfXyA8vN1p\n4fR/0x6Pl96BVCpkNUF869tC8Py1o5GliFo3Kzw+WwqsYB/ymxNRBr6GJdwpFHWpV6AyERwcLPvd\n3t5e70tOtN3kvosXGd2a7t2Z4i9ZWa1rr7qacUA9298E6sAFAhjWS5EcpnyISiolsEoogO879lqw\nTDGOL1tDGq+8qFVjDFNK0EtLkicUSkeFtdOIi4vD0KFD0atXLwiFQgwZMgRxcXHw9PSEl5f2I2xw\n4QJT92LiRCb7saSVleqiohhZ53aYe8Ln8yDys0f85/lKt732gwi1BgbwnqTb3taQpZ3hUCpGaU6d\n8o0B5N+vhW15BQYvpj0NCkWTsA65zcjIaHG9UE2tJlWQhY2dOgU4OjJ1iRvYsIEJl508Wb3Gc3IA\ne/t2FTnVmDu/V+DefxIxpnRwi0q7P3jdg6GtMV69JNSecQrYZ5sEhzccMX5DF6Xbnlqej+ITBXgt\n11MLllHaIroOudUWmg65Zf2E1IZTYI2xcfP0+ClTmOGqujr1HvyLFjGOR572fzugX5A5rnfuhN8+\nKsTE7fJrDhdn1sEhtQCeMf5atk4+RkNskBtWDLBwGkUXitEpUDfRXhRKR0KlMJObN29ix44d+Oab\nb5CUlKQpm1qmoIDRVHn24d63L7BiBfDbb6q3KRIxFcTaqcNowHZBd4j2ZSvM2bjwVi7ye9pAOEA/\naqR4LbJB57QipTkm9XUEXTKK4fcGdRoUiqZh7TS2bduGOXPmoLCwEPn5+ZgzZw62b9+uSdvkw+Mx\nRZLksWcPkz4vVbE2dnIyU56ynTPuczsY1EsR/mHzkrSVIilMz2XD/WP9qXbnGWyOOgM+Yva3HHr7\n9/dlqDAygmugbrW+KJSOAGun8cMPPyAmJgaffPIJPv30U1y/fh179uzRpG3yOXoU6KwgQsbcnOlt\nqKoHY2LS7pL65GFozEOX1c9B/PUjVEmaOtbj07NQ1sWi1eVhuYTP56FqiANu7Wh5Aj/t2wLUjpA/\n5Eah6At8Ph/vvfee7PtXX32FdevW6dAi9VBpeIrfqMoWX1cVtwICWi6QFBYGJCaq1ubWrcDT5m/f\n7ZGgj2wgse2EnwPuy4Z9oneVoXNkNoYf661j65oT8IE9bFMKUVcjf4iqSiKF/Z1CDP5ItyHCFIoy\njI2NcerUKRQVFQFQrBKuKJ9DX2D95F+wYAEGDhyI0NBQrF27FoMGDcLChQs1aZt81q9vOZeCz2dq\nE1dUsGvvwQPg3XfbZX6GPPh8HiZe6wvjTAl+7JKEHzzvoeS/KTD9tJ/OMsBbov9/zCExNcGfXxTL\nXX9xYzFKLMz00nYKpTFGRkZYvHgxtmzZ0mzdq6++iiVLlmDQoEF4//33ZctXr16NnTt3yr6HhoZi\n8+bNWrFXEazCjAghmDp1Kl544QVcuXIFPB4PBw4cgK+vr6bta85//9tyXWFDQ+CTT5h6xO+8o7y9\nR4+YwvfqShC3Qbr0MsL0PF+cf68AFVk1cPvWT68fuqYh3fFkezbwf80FFPN2PoFlSHcdWEVpT0Tx\notTeN5AEst526dKl8PLywv/+979m63JycnDt2rUmPZCQkBCsXLkSS/9RvTh+/DgiIyPVtpULWMem\njhs3Dqmpqbov8XrzJjBmTMvbWFkxtXGVQQgjg/7aa9zY1oYwteBjyu6uujaDFeO/tkf4Txm4+n0Z\nhjZK3oveVQarsgqM30KHpiitQ5UHf2sQCASYN28etm/fDjOzf1/UeDwepk2b1mzIysfHBwUFBcjN\nzUVBQQGsra3h6OioFVsVwWp4isfjwc/PD7GxsZq2RznjxinfplMnwNOTqcLXEhIJkJ0NGBlxYxtF\nI5h3NgAWOSNjxT1UipgJ/IrSemS+cw+8152pQCGlTbFy5Urs3bsX5eVNZX3Mzc3lbj9t2jScOHEC\nx44dw4wZM7RhYouw7mlcv34dP//8M3r16oVO/wj68Xg8JCcna8w4uZSxrLPQrx8TZSWVKh7O+u47\npvB6O5QOaW9M2umAfReKcKh3KoSreiBjUxaInTlmfkujpihtC2tra0yfPh179+7FayxGOUJCQrBo\n0SIUFRXh8uXLWrCwZVi/okVGRuLhw4e4dOkSzp07h3PnzrVYP1wdNm/eDD6fj+Ji+ZOeAJgkPjZ0\n6cLoSX32meJtHB2ZLHKK3sPn8zD3bj/w3QTI/jQdfDcB852WdaW0ERoPPb377rt4+kzEZsP6nJwc\njB8/Xra8f//+kEgkcHJygoOD7l+SlGpPNZ6pb9AvaXzy77CZbGZBVlYWXn/9daSlpSE+Ph42Ns2z\ne3k8Hkh5OZOPwQaRiFGvlUgAZ+em60JDAX9/4OWXW288hULRe6j2lJbKvYrFYkgkEsTHx2PXrl3I\nyclBdnY2du/ejYSEBE6MABjn8+WXXyrf0EyFKB9LS+D8eUY6vTFPnzKKto0FDykUCoWiFKVzGqGh\noQCA4cOHIyEhAQIBU0pz3bp1GMdmUpoFYWFhcHJyYiexrur8w/z5zGT34sXMHEZNDfDWW0zE1OjR\n6hlMoVAoHRTWE+EFBQUwahRlZGRkhIKCAtYHCgoKQl5eXrPl69evx+eff94k9rilblSDEwOAwMBA\nBAYGtnxgHg/o1o1RwT1+HDhzBjh4EDAwYG07hUKhtCWioqIQFRWlkbZZ19NYv349jh49ismTJ4MQ\ngtOnTyMkJARrWllTOzU1FaNHj5aFm2VnZ8PR0RGxsbGwt28af9/qcTlCaKQUhdJBoXMa3Jw7a6cB\nAPHx8YiOjgaPx8OIESM0khHu7Ozc8kR4B/ijUygU7ukozw+9KcIEAH5+fhrPCFck4kWhUCgU3aNS\nT0PXdJQ3BQqFwj26fn4YGBjAy8sL9fX16N27N3766SdYWFhwfhydh9xSKBQKpfWYm5sjMTERycnJ\nsLS0xHfffadrk9SCtdOQSqU4ePAgPvnkEwBAZmamfmhRUSgUShtj8ODBePjwIQCmjPagQYPg7e2N\nyZMno7S0tMm2ZWVlEDaqIVReXo6ePXvqrO4Ga6exdOlSXLt2DYcOHQIAWFhYyOR6KRQKpS2Tnh6K\nqCgeoqJ4SE8PZb288TK21NfXIzIyEh4eHgCAefPmYdOmTUhKSoKnp2ezan5WVlbw8fGRhdCeO3cO\nY8eOhYGO0gZYz2n4+voiMTFR9hMAvL29kZSUpFEDG6PrMUkKhdJ20fXzw9DQEJ6ennjy5AmEQiGu\nX78OsVgMLy8vPH78GADw6NEjTJs2DfHx8U32PXz4MC5fvoxdu3Zh0qRJWLZsGUYrSE7WmzkNY2Pj\nJt2hwsJC3ZV8pVAolDaGmZkZEhMT8fjxY5iamiIsLKxZtKiiB3twcDAiIiJQUlKChIQEjBo1Shsm\ny4X1U3/58uWYNGkSCgoKsGbNGgwdOhSrV6/WpG0UCoXS7jAzM8P27dvx4YcfQiAQwNraGleuXAEA\nHDx4UK7KhYWFBQYMGIC33noLwcHBOk1NUCnk9s6dO/jzzz8BAKNHj0a/fv00Zpg8dN29pFAobRdd\nPz8sLS0hEolk3ydMmIDZs2fDzc0NS5YsQUVFBVxcXLB//35YWVlh7dq18Pf3R3BwMADg5MmTmD59\nOqKiojB8+HCFx9GrjHBdo+s/OoVCabt0lOeH3mSEb968ucmBeTwerKys4OfnBx8fH06MoVAoFIp+\nw7qnMWvWLMTFxSE4OBiEEJw/fx6enp54/Pgxpk6divfff1/TtnaYNwUKhcI9HeX5oTfDU8OHD0d4\neLgs7V0ikWDcuHGIiIiAn58f7ty5w4lBLdFR/ugUCoV7OsrzQ29CbgsLC2FsbCz7bmRkhPz8fJib\nm8PU1JQTYygUCoWi37Ce05g9ezYGDhyIiRMnghCCs2fPYtasWSgvL0f//v01aSOFQqG0Gmtr6w6h\nom1tba3R9lWKnrpx4wauXr0KHo+HoUOHwt/fX5O2NaOjdC/ZEBUVpbxqYQeBXot/odfiX+i1+Bed\nqdy6uLhg8ODB8PHxQUVFBS5fvsyJERTV0VQpx7YIvRb/Qq/Fv9BroRlYD0/t2bMH27dvR3Z2Nnx8\nfHD9+nUMHjwYFy9e1KR9FAqFQtEjWPc0tm3bhtjYWPTq1QuXLl1CYmIirKysNGkbhUKhUPQNwhI/\nPz9CCCHe3t6ksrKSEEJIv3792O7OCd7e3gQA/dAP/dAP/ajw8fb25uw5zHp4qkePHigpKcHEiRMR\nFBQEa2vrJoVBtMHNmze1ejwKhUKhNEUt7amoqCiIRCKMHTu2Se4GhUKhUNo3rOc0GsuEBAYGYsKE\nCfj44481YhSFQqFQ9BPWTiMyMrLZsgsXLnBqDIVCoVD0G6VOY9euXfD09ERaWho8PT1lH6FQCC8v\nL23YCACIiIiAm5sb+vTpg40bN2rtuLqi4fr6+voiICAAAFBcXIygoCC4urpizJgxTQrQf/755+jT\npw/c3NzkOvi2xMKFC+Hg4ABPT0/ZMnXOPT4+Hp6enujTpw9WrFih1XPgCnnXIjQ0FE5OTvD19YWv\nry/Cw8Nl69rztcjKysLIkSPh7u4ODw8PbN++HUDHvDcUXQut3BvKZspLS0tJeno6CQkJIRkZGSQ9\nPZ2kp6eTp0+fcjYbr4y6ujri4uJC0tPTSU1NDfH29ia3b9/W2vF1gVAoJEVFRU2WrVq1imzcuJEQ\nQsgXX3xB3n//fUIIIbdu3SLe3t6kpqaGpKenExcXF1JfX691m7ni8uXLJCEhgXh4eMiWqXLuUqmU\nEELIgAEDSExMDCGEkJdeeomEh4dr+Uxaj7xrERoaSjZv3txs2/Z+LXJzc0liYiIhhBCxWExcXV3J\n7du3O+S9oehaaOPeUNrTsLKyglAoxJEjR9CrVy8IhUIIhULY2tqq4R/VIzY2Fr1794ZQKISRkRFm\nzJiBsLAwrR1fV5BnYhTOnDmD+fPnAwDmz5+P06dPAwDCwsIwc+ZMGBkZQSgUonfv3oiNjdW6vVwx\nfPjwZvo5qpx7TEwMcnNzIRaLZb20efPmyfZpS8i7FkDzewNo/9eia9eusto9FhYW6NevH548edIh\n7w1F1wLQ/L2h1GlYWFhAIBDI/VhaWqp8surw5MkT9OjRQ/bdyclJdoHaKzweDy+++CL8/f2xZ88e\nAEB+fj4cHBwAAA4ODsjPzwcA5OTkwMnJSbZve7w+qp77s8sdHR3b1TXZsWMHvL298dprr8mGYzrS\ntcjIyEBiYiIGDhzY4e+NhmsxaNAgAJq/N5Q6DYlEArFYLPfTuN6tJukIypTPcvXqVSQmJiI8PBzf\nfvstoqOjm6zn8XgtXpf2fM2UnXt7580330R6ejpu3ryJbt264d1339W1SVpFIpFgypQp2LZtGwQC\nQZN1He3ekEgkmDp1KrZt2wYLCwut3BsqCRYmJSVhx44d+Oabb5CUlMS5MYpwdHREVlaW7HtWVlYT\n79ge6datGwDAzs4OkyZNQmxsLBwcHJCXlwcAyM3Nhb29PYDm1yc7OxuOjo7aN1qDqHLuTk5OcHR0\nRHZ2dpPl7eWa2Nvbyx6OixYtkg1FdoRrUVtbiylTpmDu3LmYOHEigI57bzRcizlz5siuhTbuDZW0\np2bPno3CwkLk5+djzpw5shl7TePv74/79+8jIyMDNTU1OHr0KCZMmKCVY+uCiooKiMViAEB5eTki\nIyPh6emJCRMm4McffwQA/Pjjj7IbZcKECThy5AhqamqQnp6O+/fvy8Yo2wuqnnvXrl1haWmJmJgY\nEEJw8OBB2T5tndzcXNnvp06dkkVWtfdrQQjBa6+9hv79+2PlypWy5R3x3lB0LbRyb7Cdrffw8CAS\niUT2XSKRNIno0DQXLlwgrq6uxMXFhWzYsEFrx9UFjx49It7e3sTb25u4u7vLzreoqIiMHj2a9OnT\nhwQFBZGSkhLZPuvXrycuLi6kb9++JCIiQlemc8KMGTNIt27diJGREXFyciL79u1T69zj4uKIh4cH\ncXFxIcuXL9fFqbSaZ6/F3r17ydy5c4mnpyfx8vIir7zyCsnLy5Nt356vRXR0NOHxeMTb25v4+PgQ\nHx8fEh4e3iHvDXnX4sKFC1q5N1jLiHh6eiI2NhZmZmYAgMrKSgQEBCAlJUVVJ0mhUCiUNgprwcIF\nCxZg4MCBmDx5MgghOH36NBYuXKhJ2ygUCoWiZyjtaSxduhSzZs3CsGHDEB8fjytXroDH42H48OHw\n9fXVlp0UCoVC0QOU9jRcXV2xatUq5OTkICQkBDNnzqTOgkKhUDoorOc0MjIycOTIERw9ehQVFRWY\nNWsWZs6cCVdXV03bSKFQKBQ9Qa16GomJiViwYAFSUlJQX1+vCbsoFAqFooewztOoq6vDmTNnMGvW\nLIwdOxZubm749ddfNWkbhUKhUPQMpT2NyMhIHDlyBOfPn0dAQABmzpyJCRMmwMLCQls2UigUCkVP\nUOo0Ro0ahZkzZ2LKlCmwsbHRll0UCoVC0UPUmtOgUNoyRUVFePHFFwEAeXl5MDAwgJ2dHXg8HmJi\nYhAYGIirV69q5NhLlizBvHnzMGTIEI20T6FoGuo0KB2adevWQSAQ4J133tHK8Xx9fZGQkNChlFgp\n7QuVVG4plPbIs+9NFhYWePz4Mdzc3LBgwQL07dsXs2fPRmRkJIYOHQpXV1fcuHFDtv3PP/+MgQMH\nwtfXF0uWLIFUKpV7nDt37sDV1VWuwygvL8f48ePh4+MDT09PHDt2jNuTpFA4gjoNCuUZGh7qDx8+\nxHvvvYe7d+8iLS0NR48exdWrV/HVV19hw4YNABhHcOzYMfz9999ITEwEn8/HL7/8Irfd8PBwvPTS\nS3LXRUREwNHRETdv3kRKSgrGjh2rmZOjUFoJdRoUigKcnZ3h7u4OHo8Hd3d32TyIh4cHMjIyAAB/\n/vkn4uPj4e/vD19fX1y8eBHp6ely24uMjFToDLy8vPD777/jgw8+wJUrV7RWFZNCURXWgoUUSkfD\nxMRE9jufz4exsbHs97q6Otm6+fPny3oeiqioqEBpaSm6du0qd32fPn2QmJiI8+fP46OPPsLo0aPx\n8ccfc3AWFAq30J4GhdIKRo0ahRMnTqCwsBAAUFxcjMzMzGbbXbp0CaNGjVLYTm5uLkxNTTF79my8\n9957SEhI0JjNFEproD0NSofn2Ynphu+Kljf+vX///vjss88wZswYSKVSGBkZYefOnejZs2eTfcPD\nwzF9+nSFNqSkpGDVqlWyHs2uXbtadU4UiqagIbcUihbw8/NDbGwsDAwMdG0KhdIqqNOgUCgUCmvo\nnAaFQqFQWEOdBoVCoVBYQ50GhUKhUFhDnQaFQqFQWEOdBoVCoVBYQ50GhUKhUFhDnQaFQqFQWPP/\nWLEPN06HTUUAAAAASUVORK5CYII=\n", "text": [ "" ] } ], "prompt_number": 20 }, { "cell_type": "markdown", "metadata": {}, "source": [ "The title, axis labels, and legend entries were generated automatically, but they can be customized using other [plot](http://kdavies4.github.io/ModelicaRes/modelicares.simres.html#modelicares.simres.SimRes.plot) arguments or functions from [matplotlib.pyplot](http://matplotlib.org/api/pyplot_api.html#module-matplotlib.pyplot). The abscissa can be any variable, not just time. Here, we use current:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "ax, __ = sim.plot(ynames1='L.v', ylabel1=\"Voltage\", \n", " xname='L.i', xlabel=\"Current\",\n", " title=\"Chua circuit\\n\"\n", " \"Current through and voltage across the inductor\")\n", "\n", "# Mark the start and stop points.\n", "def mark(time, text):\n", " i = sim['L.i'].values(time)\n", " v = sim['L.v'].values(time)\n", " plt.plot(i, v, 'bo')\n", " ax.annotate(text, xy=(i, v), xytext=(0, -4), ha='center', va='top', \n", " textcoords='offset points')\n", "mark(0, \"Start\")\n", "mark(2500, \"Stop\")" ], "language": "python", "metadata": {}, "outputs": [ { "ename": "ValueError", "evalue": "x and y must have same first dimension", "output_type": "pyerr", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m ax, __ = sim.plot(ynames1='L.v', ylabel1=\"Voltage\", \n\u001b[1;32m 2\u001b[0m \u001b[0mxname\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'L.i'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mxlabel\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m\"Current\"\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mtitle\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m\"Chua circuit\\n\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4\u001b[0m \"Current through and voltage across the inductor\")\n\u001b[1;32m 5\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m/usr/local/lib/python2.7/dist-packages/ModelicaRes-0.12.2_97_g5fd3eaa_dirty-py2.7.egg/modelicares/simres.pyc\u001b[0m in \u001b[0;36mplot\u001b[0;34m(self, ynames1, ylabel1, f1, legends1, leg1_kwargs, ax1, ynames2, ylabel2, f2, legends2, leg2_kwargs, ax2, xname, xlabel, title, label, incl_prefix, suffix, use_paren, **kwargs)\u001b[0m\n\u001b[1;32m 1427\u001b[0m \u001b[0mutil\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mplot\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0my2\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my2times\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0max2\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlabel\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mlegends2\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1428\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1429\u001b[0;31m \u001b[0mutil\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mplot\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0my1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my1times\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0max1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlabel\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mlegends1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1430\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0mynames2\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1431\u001b[0m \u001b[0mutil\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mplot\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0my2\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my2times\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0max2\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlabel\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mlegends2\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m/usr/local/lib/python2.7/dist-packages/ModelicaRes-0.12.2_97_g5fd3eaa_dirty-py2.7.egg/modelicares/util.pyc\u001b[0m in \u001b[0;36mplot\u001b[0;34m(y, x, ax, label, color, marker, dashes, **kwargs)\u001b[0m\n\u001b[1;32m 899\u001b[0m \u001b[0mcolor\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mnext\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcolor\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmarker\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mnext\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmarker\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 900\u001b[0m dashes=next(dashes), **kwargs)\n\u001b[0;32m--> 901\u001b[0;31m for i, (xi, yi) in enumerate(zip(x, y))]\n\u001b[0m\u001b[1;32m 902\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 903\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mplots\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m/usr/lib/pymodules/python2.7/matplotlib/axes.pyc\u001b[0m in \u001b[0;36mplot\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m 4135\u001b[0m \u001b[0mlines\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4136\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 4137\u001b[0;31m \u001b[0;32mfor\u001b[0m \u001b[0mline\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_get_lines\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4138\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd_line\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mline\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4139\u001b[0m \u001b[0mlines\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mline\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m/usr/lib/pymodules/python2.7/matplotlib/axes.pyc\u001b[0m in \u001b[0;36m_grab_next_args\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m 315\u001b[0m \u001b[0;32mreturn\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 316\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mremaining\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m<=\u001b[0m \u001b[0;36m3\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 317\u001b[0;31m \u001b[0;32mfor\u001b[0m \u001b[0mseg\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_plot_args\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mremaining\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 318\u001b[0m \u001b[0;32myield\u001b[0m \u001b[0mseg\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 319\u001b[0m \u001b[0;32mreturn\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m/usr/lib/pymodules/python2.7/matplotlib/axes.pyc\u001b[0m in \u001b[0;36m_plot_args\u001b[0;34m(self, tup, kwargs)\u001b[0m\n\u001b[1;32m 293\u001b[0m \u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0marange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0my\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshape\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdtype\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mfloat\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 294\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 295\u001b[0;31m \u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_xy_from_xy\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 296\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 297\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcommand\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m'plot'\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m/usr/lib/pymodules/python2.7/matplotlib/axes.pyc\u001b[0m in \u001b[0;36m_xy_from_xy\u001b[0;34m(self, x, y)\u001b[0m\n\u001b[1;32m 235\u001b[0m \u001b[0my\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0matleast_1d\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0my\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 236\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshape\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0my\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshape\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 237\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"x and y must have same first dimension\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 238\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mndim\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0;36m2\u001b[0m \u001b[0;32mor\u001b[0m \u001b[0my\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mndim\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 239\u001b[0m \u001b[0;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"x and y can be no greater than 2-D\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mValueError\u001b[0m: x and y must have same first dimension" ] }, { "metadata": {}, "output_type": "display_data", "png": "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\nQMQdAAz0f3qBzy0+bjVjAAAAAElFTkSuQmCC\n", "text": [ "" ] } ], "prompt_number": 21 }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can add traces that are a function of other variables in the plot using the *f1* and *f2* [plot](http://kdavies4.github.io/ModelicaRes/modelicares.simres.html#modelicares.simres.SimRes.plot) arguments. Here, we will plot the absolute value of the voltage:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "ax, __ = sim.plot('L.v', ylabel1=\"Voltage\", \n", " f1={\"abs(L.v)\": lambda x: np.abs(x[0])},\n", " title=\"Chua circuit\\nVoltage across the inductor\")\n", "\n", "# Show the max, mean, and rectified mean.\n", "from modelicares import add_hlines\n", "Lv = sim['L.v']\n", "add_hlines(ax, [Lv.max(), Lv.mean(), Lv.mean_rectified()], \n", " [\"max\", \"mean\", \"rectified mean\"], color='k', linestyle=\":\")" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can create a [pandas data frame](http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.html?highlight=dataframe#pandas.DataFrame) of selected data:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "sim.to_pandas(voltages)" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The frame has methods to export the results to various formats (e.g., \n", "[to_clipboard](http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.to_clipboard.html#pandas.DataFrame.to_clipboard), \n", "[to_csv](http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.to_csv.html#pandas.DataFrame.to_csv), \n", "[to_excel](http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.to_excel.html#pandas.DataFrame.to_excel),\n", "[to_hdf](http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.to_hdf.html#pandas.DataFrame.to_hdf),\n", "[to_html](http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.to_html.html#pandas.DataFrame.to_html), and\n", "[to_latex](http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.to_latex.html#pandas.DataFrame.to_latex))." ] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "Linearization results" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We'll load a linearization result of [Modelica.Blocks.Continuous.PID](http://reference.wolfram.com/system-modeler/libraries/Modelica/Modelica_Blocks_Continuous_PID.html):" ] }, { "cell_type": "code", "collapsed": false, "input": [ "from modelicares import LinRes\n", "lin = LinRes('PID.mat')" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can explore it and create diagrams using the methods in [LinRes](http://kdavies4.github.io/ModelicaRes/modelicares.linres.html#modelicares.linres.LinRes). An instance of [LinRes](http://kdavies4.github.io/ModelicaRes/modelicares.linres.html#modelicares.linres.LinRes) has a sys attribute, which is an instance of the [StateSpace](http://python-control.sourceforge.net/manual/class_strings.html#module-statesp) class from the [control](https://pypi.python.org/pypi/control) package. The state names are available in sys.state_names:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "lin.sys.state_names" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The input and output names are also available:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "lin.sys.input_names" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "lin.sys.output_names" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The system matrixes are available in sys.A, sys.B, sys.C, and sys.D, e.g.," ] }, { "cell_type": "code", "collapsed": false, "input": [ "lin.sys.A" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can create a [Bode plot](http://en.wikipedia.org/wiki/Bode_plot) using [bode](http://kdavies4.github.io/ModelicaRes/modelicares.linres.html#modelicares.linres.LinRes.bode)():" ] }, { "cell_type": "code", "collapsed": false, "input": [ "lin.bode();" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[Nyquist plots](http://en.wikipedia.org/wiki/Nyquist_plot) are available via [nyquist](http://kdavies4.github.io/ModelicaRes/modelicares.linres.html#modelicares.linres.LinRes.nyquist)():" ] }, { "cell_type": "code", "collapsed": false, "input": [ "lin.nyquist(freqs=(0.1, 1000));" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "Groups of results" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can also use [ModelicaRes](http://kdavies4.github.io/ModelicaRes) to analyze and plot data from multiple simulation and linearization results at once. First, we'll import some additional classes:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "from modelicares import SimResList, LinResList" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[SimResList](http://kdavies4.github.io/ModelicaRes/modelicares.simres.html#modelicares.simres.SimResList) or [LinResList](http://kdavies4.github.io/ModelicaRes/modelicares.linres.html#modelicares.linres.LinResList) are Python lists with additional methods that operate on the contained simulation and linearization results as a group. Each entry is an instance of [SimRes](http://kdavies4.github.io/ModelicaRes/modelicares.simres.html#modelicares.simres.SimRes) or [LinRes](http://kdavies4.github.io/ModelicaRes/modelicares.linres.html#modelicares.linres.LinRes) (respectively)." ] }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": [ "Simulations" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We'll load simulations from several folders:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "sims = SimResList('ChuaCircuit/*.mat', 'ChuaCircuit/*/*.mat')\n", "print(sims)" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can check which variables have different initial values among the simulations:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "sims.get_unique_IVs()" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In this case it's only the inductance. The order of the simulations is somewhat arbitrary, so let's sort the list by inductance:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "sims.sort(key=lambda sim: sim['L.L'].value)\n", "unique_IVs = sims.get_unique_IVs()\n", "unique_IVs" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "print(sims)" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can query the list for an attribute of a variable across all of the simulations:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "sims['L.v'].FV" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There is a built-in method to plot variables across all of the simulations. First, we'll label each simulation:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "label = lambda L: 'w/ L.L = {L} {U}'.format(L=L.value, U=L.unit)\n", "for sim in sims: \n", " sim.label = label(sim['L.L'])" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Then we'll create the plot:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "sims.plot('L.v', ylabel1='Voltage', title=\"Chua circuit\\nwith varying inductance\");" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": [ "Linearizations" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Similarly, we can load two linearizations:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "lins = LinResList('PID/*.mat', 'PID/*/*.mat')\n", "print(lins)" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We'd like to label the plots with the differential time constants. Since this information isn't recorded in the files, we'll load it from the associated *dsin.txt* files and attach a *label* attribute to each linearization:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "from os.path import join\n", "from modelicares import read_params\n", "for lin in lins:\n", " lin.label = \"Td = %g s\" % read_params('Td', join(lin.dirname, 'dsin.txt'))\n", "lins.label" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "These aren't in order, so we'll sort the list of linearizations:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "lins.sort(key=lambda lin: lin.label)\n", "lins.label" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Finally, we'll create a [Bode plot](http://en.wikipedia.org/wiki/Bode_plot) of all three linearizations using those labels:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "lins.bode(title=\"Bode plot of PID\\n\"\n", " \"with varying differential time constant\");" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Further information" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For advanced topics in ModelicaRes, see the the next IPython notebook as a [file](https://github.com/kdavies4/ModelicaRes/blob/master/examples/advanced.ipynb) or a [static page](http://nbviewer.ipython.org/github/kdavies4/ModelicaRes/blob/master/examples/advanced.ipynb). For full documentation of ModelicaRes, see the [main webpage](http://kdavies4.github.io/ModelicaRes)." ] } ], "metadata": {} } ] }