diff --git a/README.rst b/README.rst index 861e003e..9336ca1c 100644 --- a/README.rst +++ b/README.rst @@ -26,7 +26,7 @@ Documentation The complete documentation is available here, both in pdf & html: - ./documentation/UsersGuide/UsersGuide.html + ./documentation/_build/html/index.html ./documentation/UsersGuide/UsersGuide.pdf The documentation of the latest *stable* version is also diff --git a/bootstrap/cmake_modules/CMakeLists.txt b/bootstrap/cmake_modules/CMakeLists.txt index cb316971..f0c6c9d1 100644 --- a/bootstrap/cmake_modules/CMakeLists.txt +++ b/bootstrap/cmake_modules/CMakeLists.txt @@ -7,6 +7,7 @@ FindLibexecinfo.cmake FindLibbfd.cmake FindQwt.cmake + FindSphinx.cmake GetGitRevisionDescription.cmake GetGitRevisionDescription.cmake.in ) diff --git a/bootstrap/cmake_modules/FindSphinx.cmake b/bootstrap/cmake_modules/FindSphinx.cmake new file mode 100644 index 00000000..7d4f192a --- /dev/null +++ b/bootstrap/cmake_modules/FindSphinx.cmake @@ -0,0 +1,12 @@ + +# CMake snippet courtesy of Eric Scott BARR's blog. + + find_program( SPHINX_EXECUTABLE NAMES sphinx-build + HINTS $ENV{SPHINX_DIR} + PATH_SUFFIXES bin + DOC "Sphinx documentation generator" + ) + + include( FindPackageHandleStandardArgs ) +find_package_handle_standard_args( Sphinx DEFAULT_MSG SPHINX_EXECUTABLE ) + mark_as_advanced( SPHINX_EXECUTABLE ) diff --git a/documentation/CMakeLists.txt b/documentation/CMakeLists.txt index 338c83ec..a3ced41c 100644 --- a/documentation/CMakeLists.txt +++ b/documentation/CMakeLists.txt @@ -5,16 +5,14 @@ cmake_minimum_required(VERSION 2.4.0) - OPTION(BUILD_DOC "Build the documentation (html+latex)" OFF) + option(BUILD_DOC "Build the documentation (html+pdf)" OFF) list(INSERT CMAKE_MODULE_PATH 0 "${DESTDIR}$ENV{CORIOLIS_TOP}/share/cmake/Modules/") find_package(Bootstrap REQUIRED) + find_package(Sphinx REQUIRED) setup_project_paths(CORIOLIS) - list(INSERT CMAKE_MODULE_PATH 0 "${CRLCORE_SOURCE_DIR}/cmake_modules/") - print_cmake_module_path() set_cmake_policies() - check_distribution() #if(BUILD_DOC) # include(UseLATEX) @@ -22,13 +20,77 @@ add_subdirectory(examples) if(BUILD_DOC) - add_subdirectory(etc) - add_subdirectory(UsersGuide) - add_subdirectory(PythonCpp) + set ( htmlInstallDir share/doc/coriolis2/en/html/main ) + set ( pdfInstallDir share/doc/coriolis2/en/pdf/main ) + + set ( pythonCppRst PythonCpp/pdfHeader.rst + PythonCpp/Introduction.rst + PythonCpp/Configuration.rst + PythonCpp/DBoStandalone.rst + PythonCpp/DBoHierarchy.rst + PythonCpp/NonDBo.rst + PythonCpp/DbU.rst + PythonCpp/Name.rst ) + + set ( usersGuideRst UsersGuide/pdfHeader.rst + UsersGuide/LicenseCredits.rst + UsersGuide/Releases.rst + UsersGuide/Installation.rst + UsersGuide/Configuration.rst + UsersGuide/ViewerTools.rst + UsersGuide/ScriptsPlugins.rst ) + + set ( rdsRst RDS/pdfHeader.rst + RDS/RDSpage.rst ) + + add_custom_target ( doc_HTML ALL + cd ${DOCUMENTATION_SOURCE_DIR} + && rm -rf _build + && sphinx-build -b html -d _build/doctrees . _build/html ) + add_dependencies ( doc_HTML ../etc/definitions.rst + ../_static/SoC.css + ../_static/www-SoC.css + ../_static/SoC-ReST.css + ../_static/pygments.css + CrlCore/CrlCore.rst + DpGen/DpGen.rst + Hurricane/Hurricane.rst + Patterns/Patterns.rst + Stratus/Stratus.rst + Unicorn/Unicorn.rst + Viewer/Viewer.rst + ${usersGuideRst} UsersGuide/index.rst + ${pythonCppRst} PythonCpp/index.rst + ${rdsRst} RDS/index.rst + ) + + add_custom_target ( pdf_UsersGuide ALL + cd ${DOCUMENTATION_SOURCE_DIR}/UsersGuide + && ../etc/doPdf.sh ${usersGuideRst} UsersGuide.rst ) + add_dependencies ( pdf_UsersGuide ../etc/definitions.rst + ../etc/SoC-ReST.tex + ${usersGuideRst} ) + + add_custom_target ( pdf_PythonCpp ALL + cd ${DOCUMENTATION_SOURCE_DIR}/PythonCpp + && ../etc/doPdf.sh ${pythonCppRst} PythonCpp.rst + ) + add_dependencies ( pdf_PythonCpp ../etc/definitions.rst + ../etc/SoC-ReST.tex + ${pythonCppRst} ) + + add_custom_target ( pdf_RDS ALL + cd ${DOCUMENTATION_SOURCE_DIR}/RDS + && ../etc/doPdf.sh ${rdsRst} RDS.rst + ) + add_dependencies ( pdf_RDS ../etc/definitions.rst + ../etc/SoC-ReST.tex + ${pythonCppRst} ) + + install ( DIRECTORY _build/html/ DESTINATION ${htmlInstallDir} ) + install ( FILES RDS/RDS.pdf + PythonCpp/PythonCpp.pdf + UsersGuide/UsersGuide.pdf DESTINATION ${pdfInstallDir} ) + endif(BUILD_DOC) - set ( htmlInstallDir share/doc/coriolis2/ ) - set ( latexInstallDir share/doc/coriolis2/ ) - - install ( FILES general-index.html DESTINATION ${htmlInstallDir} RENAME index.html ) - diff --git a/documentation/Contents.rst b/documentation/Contents.rst new file mode 100644 index 00000000..febd0e88 --- /dev/null +++ b/documentation/Contents.rst @@ -0,0 +1,20 @@ +.. Coriolis documentation master file, created by + sphinx-quickstart on Mon Jul 10 15:08:36 2017. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Comprenhensive Table of Contents +================================ + +.. toctree:: + + UsersGuide/index.rst + Stratus/Stratus.rst + DpGen/DpGen.rst + Patterns/Patterns.rst + Hurricane/Hurricane.rst + Viewer/Viewer.rst + CrlCore/CrlCore.rst + Unicorn/Unicorn.rst + PythonCpp/index.rst + RDS/index.rst diff --git a/documentation/CrlCore/CrlCore.rst b/documentation/CrlCore/CrlCore.rst new file mode 100644 index 00000000..d462e48e --- /dev/null +++ b/documentation/CrlCore/CrlCore.rst @@ -0,0 +1,11 @@ +.. -*- Mode: rst -*- + +.. include:: ../etc/definitions.rst + + +==================== +CRL Core Reference +==================== + +The CRL Core C++ API reference is generated by Doxygen_ and is +available here: `CRL Core `_ diff --git a/documentation/DpGen/DpGen.rst b/documentation/DpGen/DpGen.rst new file mode 100644 index 00000000..0d8324d1 --- /dev/null +++ b/documentation/DpGen/DpGen.rst @@ -0,0 +1,11 @@ +.. -*- Mode: rst -*- + +.. include:: ../etc/definitions.rst + + +================= +DpGen Reference +================= + +The DpGen extension of the Stratus Language reference is generated by LaTeX2HTML_ and is +available here: `DpGen `_ diff --git a/documentation/Hurricane/Hurricane.rst b/documentation/Hurricane/Hurricane.rst new file mode 100644 index 00000000..4b1ec994 --- /dev/null +++ b/documentation/Hurricane/Hurricane.rst @@ -0,0 +1,11 @@ +.. -*- Mode: rst -*- + +.. include:: ../etc/definitions.rst + + +===================== +Hurricane Reference +===================== + +The Hurricane C++ API reference is generated by Doxygen_ and is +available here: `Hurricane `_ diff --git a/documentation/Makefile b/documentation/Makefile new file mode 100644 index 00000000..97677091 --- /dev/null +++ b/documentation/Makefile @@ -0,0 +1,153 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = _build + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext + +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " texinfo to make Texinfo files" + @echo " info to make Texinfo files and run them through makeinfo" + @echo " gettext to make PO message catalogs" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +clean: + -rm -rf $(BUILDDIR)/* + +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Coriolis.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Coriolis.qhc" + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/Coriolis" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Coriolis" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +texinfo: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo + @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." + @echo "Run \`make' in that directory to run these through makeinfo" \ + "(use \`make info' here to do that automatically)." + +info: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo "Running Texinfo files through makeinfo..." + make -C $(BUILDDIR)/texinfo info + @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." + +gettext: + $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale + @echo + @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." diff --git a/documentation/Patterns/Patterns.rst b/documentation/Patterns/Patterns.rst new file mode 100644 index 00000000..66c4791c --- /dev/null +++ b/documentation/Patterns/Patterns.rst @@ -0,0 +1,11 @@ +.. -*- Mode: rst -*- + +.. include:: ../etc/definitions.rst + + +==================== +Patterns Reference +==================== + +The Patterns extension of the Stratus Language reference is generated by LaTeX2HTML_ and is +available here: `Patterns `_ diff --git a/documentation/PythonCpp/CMakeLists.txt b/documentation/PythonCpp/CMakeLists.txt deleted file mode 100644 index 49281f72..00000000 --- a/documentation/PythonCpp/CMakeLists.txt +++ /dev/null @@ -1,39 +0,0 @@ -# -*- mode: CMAKE; explicit-buffer-name: "CMakeLists.txt" -*- - - set ( htmlInstallDir share/doc/coriolis2/en/html/PythonCpp ) - set ( latexInstallDir share/doc/coriolis2/en/latex/PythonCpp ) - - add_custom_target ( doc_HTML ALL - cd ${DOCUMENTATION_SOURCE_DIR}/PythonCpp - && rst2html --link-stylesheet --stylesheet=../etc/SoC.css,../etc/SoC-ReST.css,../etc/Pygments.css PythonCpp.rst PythonCpp.html ) - add_dependencies ( doc_HTML ../etc/definitions.rst - ../etc/SoC.css - ../etc/SoC-ReST.css - ../etc/Pygments.css - PythonCpp.rst ) - - add_custom_target ( doc_LaTeX ALL - cd ${DOCUMENTATION_SOURCE_DIR}/PythonCpp - && export TEXINPUTS=../etc/images//:./images//: - && rst2latex --use-latex-toc --stylesheet=../etc/SoC-ReST.tex PythonCpp.rst PythonCpp-raw.tex - && sed 's, \\& \\\\multicolumn{2}{l|}{, \\& \\\\multicolumn{2}{p{0.6\\\\DUtablewidth}|}{,' PythonCpp-raw.tex > PythonCpp.tex - && pdflatex PythonCpp - && pdflatex PythonCpp - ) - add_dependencies ( doc_LaTeX ../etc/definitions.rst - ../etc/SoC-ReST.tex - PythonCpp.rst ) - - install ( DIRECTORY images/ - DESTINATION ${htmlInstallDir}/images - FILES_MATCHING PATTERN "*.png" ) - install ( FILES PythonCpp.html DESTINATION ${htmlInstallDir} ) - - install ( DIRECTORY images/ - DESTINATION ${latexInstallDir}/images - FILES_MATCHING PATTERN "*.pdf" - PATTERN "*.eps" - PATTERN "*.bb" ) - - install ( FILES PythonCpp.tex - PythonCpp.pdf DESTINATION ${latexInstallDir} ) diff --git a/documentation/PythonCpp/Configuration.rst b/documentation/PythonCpp/Configuration.rst new file mode 100644 index 00000000..2e9d11e9 --- /dev/null +++ b/documentation/PythonCpp/Configuration.rst @@ -0,0 +1,42 @@ +.. -*- Mode: rst -*- + +.. include:: ../etc/definitions.rst + + +2. Basic File Structure and CMake configuration +================================================= + +As a first example we will consider the ``Hurrican::Library`` +class. To export a class into Python, we must create three files: + +#. ``PyLibrary.h``, defines the ``PyLibrary`` C-Struct and the functions + needed outside the module istself (mostly for ``PyHurricane.cpp``). + +#. ``PyLibrary.cpp``, contains the complete wrapping of the class and + the Python type definition (``PyTypeLibrary``). + +#. ``PyHurricane.cpp``, the definition of the Python module into which + the classes are registered. The module act as a ``namespace`` in + Python so it is good practice to give it the same name as it's + associated C++ namespace. + +|newpage| + +To build a Python module in |cmake|, use the following macro: + + .. code-block:: cmake + + set( pyCpps PyLibrary.cpp + PyHurricane.cpp ) + set( pyIncludes hurricane/isobar/PyLibrary.h + + add_python_module( "${pyCpps}" + "${pyIncludes}" + "isobar;1.0;1" # Name & version of the supporting + # shared library. + Hurricane # Name of the Python module will give: + # Hurricane.so + "${depLibs}" # List of dependency libraries. + include/coriolis2/hurricane/isobar + # Where to install the include files. + ) diff --git a/documentation/PythonCpp/DBoHierarchy.rst b/documentation/PythonCpp/DBoHierarchy.rst new file mode 100644 index 00000000..4c72bf3b --- /dev/null +++ b/documentation/PythonCpp/DBoHierarchy.rst @@ -0,0 +1,439 @@ +.. -*- Mode: rst -*- + +.. include:: ../etc/definitions.rst + + +|newpage| + + +4. Case 2 - Hierarchy of DBo Derived Classes +============================================== + +Now we want to export the following C++ class hierarchy into Python: :: + + PyEntity <-- PyComponent <-+- PyContact + +- PySegment <-+- PyHorizontal + +- PyVertical + + +4.1 Base Class Header +~~~~~~~~~~~~~~~~~~~~~~~ + +**Remark:** this is only a partial description of the tree for the sake of +clarity. + +One important fact to remember is that ``PyEntity`` and ``PyComponent`` +being related to C++ abstract classes, no objects of those types will be +created, only ``PyContact``, ``PyHorizontal`` or ``PyVertical`` will. + +The consequence is that there is no ``PyEntity_Link()`` like in :ref:`3.1` +but instead two functions: + +#. ``PyEntity_NEW()`` which create the relevant ``PyEntity`` *derived* + object from the ``Entity`` one. For example, if the ``Entity*`` given + as argument is in fact a ``Horizontal*``, then the function will + return a ``PyHorizontal*``. + +#. ``EntityCast()`` do the reverse of ``PyEntity_NEW()`` that is, from + a ``PyEntity``, return the C++ *derived* object. Again, if the + ``PyEntity*`` is a ``PyHorizontal*``, the function will cast it as + a ``Horizontal*`` *then* return it as an ``Entity*``. + +.. code-block:: python + + #ifndef ISOBAR_PY_ENTITY_H + #define ISOBAR_PY_ENTITY_H + + #include "hurricane/isobar/PyHurricane.h" + #include "hurricane/Entity.h" + + namespace Isobar { + extern "C" { + + typedef struct { + PyObject_HEAD + Hurricane::Entity* _object; + } PyEntity; + + extern PyObject* PyEntity_NEW ( Hurricane::Entity* entity ); + extern void PyEntity_LinkPyType (); + extern PyTypeObject PyTypeEntity; + extern PyMethodDef PyEntity_Methods[]; + + + #define IsPyEntity(v) ( (v)->ob_type == &PyTypeEntity ) + #define PYENTITY(v) ( (PyEntity*)(v) ) + #define PYENTITY_O(v) ( PYENTITY(v)->_object ) + + } // extern "C". + + Hurricane::Entity* EntityCast ( PyObject* derivedObject ); + + } // Isobar namespace. + + #endif // ISOBAR_PY_ENTITY_H + +|newpage| + + +4.2 Base Class File +~~~~~~~~~~~~~~~~~~~~~ + +Changes from :ref:`3.2 Class Associated File` are: + +#. No call to ``DBoLinkCreateMethod()`` because there must be no ``PyEntity_Link()``, + but the definitions of ``PyEntity_NEW()`` and ``EntityCast``. + +#. For defining the ``PyTypeEntity`` Python type, we call a different + macro: ``PyTypeRootObjectDefinitions``, dedicated to base classes. + + +.. code-block:: c++ + + #include "hurricane/isobar/PyCell.h" + #include "hurricane/isobar/PyHorizontal.h" + #include "hurricane/isobar/PyVertical.h" + #include "hurricane/isobar/PyContact.h" + + namespace Isobar { + using namespace Hurricane; + + extern "C" { + + #if defined(__PYTHON_MODULE__) + + #define METHOD_HEAD(function) GENERIC_METHOD_HEAD(Entity,entity,function) + + DBoDestroyAttribute(PyEntity_destroy ,PyEntity) + + static PyObject* PyEntity_getCell ( PyEntity *self ) + { + Cell* cell = NULL; + HTRY + METHOD_HEAD( "Entity.getCell()" ) + cell = entity->getCell(); + HCATCH + return PyCell_Link( cell ); + } + + PyMethodDef PyEntity_Methods[] = + { { "getCell", (PyCFunction)PyEntity_getCell, METH_NOARGS + , "Returns the entity cell." } + , { "destroy", (PyCFunction)PyEntity_destroy, METH_NOARGS + , "Destroy associated hurricane object, the python object remains." } + , {NULL, NULL, 0, NULL} /* sentinel */ + }; + + + DBoDeleteMethod(Entity) + PyTypeObjectLinkPyType(Entity) + + #else // End of Python Module Code Part. + + PyObject* PyEntity_NEW ( Entity* entity ) + { + if (not entity) { + PyErr_SetString ( HurricaneError, "Invalid Entity (bad occurrence)" ); + return NULL; + } + + Horizontal* horizontal = dynamic_cast(entity); + if (horizontal) return PyHorizontal_Link( horizontal ); + + Vertical* vertical = dynamic_cast(entity); + if (vertical) return PyVertical_Link( vertical ); + + Contact* contact = dynamic_cast(entity); + if (contact) return PyContact_Link( contact ); + + Py_RETURN_NONE; + } + + PyTypeRootObjectDefinitions(Entity) + + #endif // Shared Library Code Part (1). + + } // extern "C". + + + #if !defined(__PYTHON_MODULE__) + + Hurricane::Entity* EntityCast ( PyObject* derivedObject ) { + if (IsPyHorizontal(derivedObject)) return PYHORIZONTAL_O(derivedObject); + if (IsPyVertical (derivedObject)) return PYVERTICAL_O(derivedObject); + if (IsPyContact (derivedObject)) return PYCONTACT_O(derivedObject); + return NULL; + } + + #endif // Shared Library Code Part (2). + + } // Isobar namespace. + +|newpage| + + +4.3 Intermediate Class Header +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Changes from :ref:`3.1 Class Associated Header File` are: + +#. As for ``PyEntity``, and because this is still an abstract class, + there is no ``PyComponent_Link()`` function. + +#. The definition of the ``PyComponent`` |struct| is differs. There is + no ``PyObject_HEAD`` (it is a Python *derived* class). The only + field is of the base class type ``PyEntity`` and for use with + Coriolis macros, **it must** be named ``_baseObject`` (note that + this is *not* a pointer but a whole object). + +.. code-block:: c++ + + #ifndef ISOBAR_PY_COMPONENT_H + #define ISOBAR_PY_COMPONENT_H + + #include "hurricane/isobar/PyEntity.h" + #include "hurricane/Component.h" + + namespace Isobar { + extern "C" { + + typedef struct { + PyEntity _baseObject; + } PyComponent; + + extern PyTypeObject PyTypeComponent; + extern PyMethodDef PyComponent_Methods[]; + extern void PyComponent_LinkPyType (); + + #define IsPyComponent(v) ((v)->ob_type == &PyTypeComponent) + #define PYCOMPONENT(v) ((PyComponent*)(v)) + #define PYCOMPONENT_O(v) (static_cast(PYCOMPONENT(v)->_baseObject._object)) + + } // extern "C". + } // Isobar namespace. + + #endif + + +4.4 Intermediate Class File +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Changes from :ref:`3.2 Class Associated File` are: + +1. Redefinition of the default macros ``ACCESS_OBJECT`` and ``ACCESS_CLASS``. + + * The pointer to the C++ encapsulated object (attribute ``_object``) is hold + by the base class ``PyEntity``. The ``ACCESS_OBJECT`` macro which is tasked + to give access to that attribute is then ``_baseObject._object`` as + ``PyComponent`` is a direct derived class of ``PyEntity``. + + * ``ACCESS_CLASS`` is similar to ``ACCESS_OBJECT`` for accessing the base + class, that is a pointer to ``PyEntity``. + +|newpage| + +2. For defining the ``PyTypeComponent`` Python type, we call a yet different + macro: ``PyTypeInheritedObjectDefinitions()``, dedicated to derived classes. + For this this macro we need to give as argument the derived class and the + base class. + +.. code-block:: c++ + + #include "hurricane/isobar/PyComponent.h" + #include "hurricane/isobar/PyNet.h" + + namespace Isobar { + using namespace Hurricane; + + extern "C" { + + #undef ACCESS_OBJECT + #undef ACCESS_CLASS + #define ACCESS_OBJECT _baseObject._object + #define ACCESS_CLASS(_pyObject) &(_pyObject->_baseObject) + #define METHOD_HEAD(function) GENERIC_METHOD_HEAD(Component,component,function) + + #if defined(__PYTHON_MODULE__) + + DirectGetLongAttribute(PyComponent_getX,getX,PyComponent,Component) + DirectGetLongAttribute(PyComponent_getY,getY,PyComponent,Component) + DBoDestroyAttribute(PyComponent_destroy,PyComponent) + + static PyObject* PyComponent_getNet ( PyComponent *self ) + { + Net* net = NULL; + HTRY + METHOD_HEAD( "Component.getNet()" ) + net = component->getNet( ); + HCATCH + return PyNet_Link( net ); + } + + PyMethodDef PyComponent_Methods[] = + { { "getX" , (PyCFunction)PyComponent_getX , METH_NOARGS + , "Return the Component X value." } + , { "getY" , (PyCFunction)PyComponent_getY , METH_NOARGS + , "Return the Component Y value." } + , { "getNet" , (PyCFunction)PyComponent_getNet , METH_NOARGS + , "Returns the net owning the component." } + , { "destroy", (PyCFunction)PyComponent_destroy, METH_NOARGS + , "destroy associated hurricane object, the python object remains." } + , {NULL, NULL, 0, NULL} /* sentinel */ + }; + + DBoDeleteMethod(Component) + PyTypeObjectLinkPyType(Component) + + #else // Python Module Code Part. + + PyTypeInheritedObjectDefinitions(Component, Entity) + + #endif // Shared Library Code Part. + + } // extern "C". + } // Isobar namespace. + + +4.5 Terminal Class Header +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The contents of this file is almost identical to `4.3 Intermediate Class Header`_, +save for the presence of a ``PyContact_Link()`` function. She is present +at this level because the class is a concrete one and can be instanciated. + +.. code-block:: c++ + + #ifndef ISOBAR_PY_CONTACT_H + #define ISOBAR_PY_CONTACT_H + + #include "hurricane/isobar/PyComponent.h" + #include "hurricane/Contact.h" + + namespace Isobar { + extern "C" { + + typedef struct { + PyComponent _baseObject; + } PyContact; + + extern PyTypeObject PyTypeContact; + extern PyMethodDef PyContact_Methods[]; + extern PyObject* PyContact_Link ( Hurricane::Contact* object ); + extern void PyContact_LinkPyType (); + + #define IsPyContact(v) ( (v)->ob_type == &PyTypeContact ) + #define PYCONTACT(v) ( (PyContact*)(v) ) + #define PYCONTACT_O(v) ( PYCONTACT(v)->_baseObject._baseObject._object ) + + } // extern "C". + } // Isobar namespace. + + #endif // ISOBAR_PY_CONTACT_H + + +4.6 Terminal Class File +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Changes from `4.4 Intermediate Class File`_ are: + +#. As previously, we have to redefine the macros ``ACCESS_OBJECT`` and ``ACCESS_CLASS``. + But, as we are one level deeper into the hierarchy, one more level of + indirection using ``_baseObject`` must be used. + + * ``ACCESS_OBJECT`` becomes ``_baseObject._baseObject._object``. + + * ``ACCESS_CLASS`` becomes ``&(_pyObject->_baseObject._baseObject)``. + +#. For defining the ``PyTypeContact`` Python type, we call again + ``PyTypeInheritedObjectDefinitions()``. It is the same whether the class is + terminal or not. + +#. And, this time, as the Python class is concrete, we call the macro + ``DBoLinkCreateMethod()`` to create the ``PyContact_Link()`` function. + + +.. code-block:: c++ + + #include "hurricane/isobar/PyContact.h" + + namespace Isobar { + using namespace Hurricane; + + extern "C" { + + #undef ACCESS_OBJECT + #undef ACCESS_CLASS + #define ACCESS_OBJECT _baseObject._baseObject._object + #define ACCESS_CLASS(_pyObject) &(_pyObject->_baseObject._baseObject) + #define METHOD_HEAD(function) GENERIC_METHOD_HEAD(Contact,contact,function) + + #if defined(__PYTHON_MODULE__) + + DirectGetLongAttribute(PyContact_getWidth , getWidth , PyContact,Contact) + DirectGetLongAttribute(PyContact_getHeight, getHeight, PyContact,Contact) + DBoDestroyAttribute(PyContact_destroy, PyContact) + + static PyObject* PyContact_create ( PyObject*, PyObject *args ) + { + Contact* contact = NULL; + HTRY + // Usual signature then arguments parsing. + HCATCH + return PyContact_Link(contact); + } + + PyMethodDef PyContact_Methods[] = + { { "create" , (PyCFunction)PyContact_create , METH_VARARGS|METH_STATIC + , "Create a new Contact." } + , { "destroy" , (PyCFunction)PyContact_destroy , METH_NOARGS + , "Destroy associated hurricane object, the python object remains." } + , { "getWidth" , (PyCFunction)PyContact_getWidth , METH_NOARGS + , "Return the contact width." } + , { "getHeight", (PyCFunction)PyContact_getHeight, METH_NOARGS + , "Return the contact height." } + , {NULL, NULL, 0, NULL} /* sentinel */ + }; + + DBoDeleteMethod(Contact) + PyTypeObjectLinkPyType(Contact) + + #else // Python Module Code Part. + + DBoLinkCreateMethod(Contact) + PyTypeInheritedObjectDefinitions(Contact, Component) + + #endif // Shared Library Code Part. + + } // extern "C". + } // Isobar namespace. + + +4.8 Python Module +~~~~~~~~~~~~~~~~~~~ + +.. code-block:: c++ + + DL_EXPORT(void) initHurricane () + { + PyEntity_LinkPyType(); // step 1. + PyComponent_LinkPyType(); + PyContact_LinkPyType(); + + PYTYPE_READY( Entity ) // step 2. + PYTYPE_READY_SUB( Component, Entity ) + PYTYPE_READY_SUB( Contact , Component ) + + __cs.addType( "ent" , &PyTypeEntity , "" , false ); // step 3. + __cs.addType( "comp" , &PyTypeComponent, "", false, "ent" ); + __cs.addType( "contact", &PyTypeContact , "" , false, "comp" ); + + PyObject* module = Py_InitModule( "Hurricane", PyHurricane_Methods ); + if (module == NULL) { + cerr << "[ERROR]\n" + << " Failed to initialize Hurricane module." << endl; + return; + } + + Py_INCREF( &PyTypeContact ); // step 4. + PyModule_AddObject( module, "Contact", (PyObject*)&PyTypeContact ); // step 4. + } diff --git a/documentation/PythonCpp/DBoStandalone.rst b/documentation/PythonCpp/DBoStandalone.rst new file mode 100644 index 00000000..36cdb46e --- /dev/null +++ b/documentation/PythonCpp/DBoStandalone.rst @@ -0,0 +1,395 @@ +.. -*- Mode: rst -*- + +.. include:: ../etc/definitions.rst + + +3. Case 1 - DBo Derived, Standalone +====================================== + +As example, we take ``Library``. This a ``DBo`` derived class, but we +choose not to export the parent classes. From Python, it will appear +as a base class. + +.. _3.1: + +.. _3.1 Class Associated Header File: + +3.1 Class Associated Header File +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Here is the typical content of a header file (for ``PyLibrary``): + +.. code-block:: c++ + + #ifndef PY_LIBRARY_H + #define PY_LIBRARY_H + + #include "hurricane/isobar/PyHurricane.h" + #include "hurricane/Library.h" + + namespace Isobar { + using namespace Hurricane; + + extern "C" { + + typedef struct { + PyObject_HEAD + Library* _object; + } PyLibrary; + + extern PyTypeObject PyTypeLibrary; + extern PyMethodDef PyLibrary_Methods[]; + extern PyObject* PyLibrary_Link ( Hurricane::Library* lib ); + extern void PyLibrary_LinkPyType (); + + + #define IsPyLibrary(v) ( (v)->ob_type == &PyTypeLibrary ) + #define PYLIBRARY(v) ( (PyLibrary*)(v) ) + #define PYLIBRARY_O(v) ( PYLIBRARY(v)->_object ) + + } // extern "C". + } // Isobar namespace. + + #endif // PY_LIBRARY_H + + +The code is organized as follow: + +1. It must have, *as the first include* ``PyHurricane.h``, which provides + the complete bunch of macros needed to build the module. Then the include + of the C++ class we want to wrap (``Library.h``). + +2. As Python is written in C, all the wrapper code has to be but inside + an ``extern "C"`` namespace. + +3. Definition of the wrapped |struct|, ``PyLibrary``. It is standard Python here. + + .. note:: + For our set of macros to work, the name of the pointer to the + C++ class must always be **_object**, and the various functions and + macros defined here must take the name of the class (either in + lowercase, camel case or capitals). + +4. Declaration of the Python type ``PyTypeLibrary`` (standard). + +5. Declaration of the Python type table of methods ``PyLibrary_Methods`` (standard). + +.. _3.6: + +6. Declaration of ``PyLibrary_Link()``, helper to convert a C++ ``Lybrary`` into + a ``PyLibrary`` (put in the support shared library). + +7. Declaration of ``PyLibrary_LinkPyType()``, this function setup the class-level + function of the new Python type (here, ``PyTypeLibrary``). + +8. And, lastly, three macros to: + + * ``IsPylibrary()``, know if a Python object is a ``PyLibrary`` + * ``PYLIBRARY()``, force cast (C style) of a ``PyObject`` into a ``PyLibrary``. + * ``PYLIBRARY_O()``, extract the C++ object (``Library*``) from the Python + object (``PyLibrary``). + + +.. _3.2 Class Associated File: + +3.2 Class Associated File +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +3.2.1 Head of the file +------------------------ + +.. code-block:: c++ + + #include "hurricane/isobar/PyLibrary.h" + #include "hurricane/isobar/PyDataBase.h" + #include "hurricane/isobar/PyCell.h" + + namespace Isobar { + using namespace Hurricane; + + extern "C" { + + #define METHOD_HEAD(function) GENERIC_METHOD_HEAD(Library,lib,function) + +As for the header, all the code must be put inside a ``extern "C"`` namespace. + +A convenience macro ``METHOD_HEAD()`` must be defined, by refining +``GENERIC_METHOD_HEAD()``. This macro will be used in the method wrappers +below to cast the ``_object`` field of the Python object into the +appropriate C++ class, this is done using a C-style cast. +The parameters of that macro are: + +#. The C++ encapsulated class (``Library``). +#. The name of the *variable* that will be used to store a pointer + to the C++ working object. +#. The name of the C++ method which is to be wrapped. + + +3.2.2 The Python Module Part +------------------------------ + +First, we have to build all the wrappers to the C++ methods of +the class. For common predicates, accessors, and mutators macros +are supplied. + +Wrapping of the ``Library::getCell()`` method: + +.. code-block:: c++ + + static PyObject* PyLibrary_getCell ( PyLibrary* self, PyObject* args ) + { + Cell* cell = NULL; + + HTRY + METHOD_HEAD( "Library.getCell()" ) + char* name = NULL; + if (PyArg_ParseTuple(args,"s:Library.getCell", &name)) { + cell = lib->getCell( Name(name) ); + } else { + PyErr_SetString( ConstructorError + , "invalid number of parameters for Library::getCell." ); + return NULL; + } + HCATCH + + return PyCell_Link(cell); + } + +Key points about this method wrapper: + +#. The ``HTRY`` / ``HCATCH`` macros provides an insulation from the C++ + exceptions. If one is emitted, it will be catched and transformed in + a Python one. This way, the Python program will be cleanly interrupted + and the usual stack trace displayed. + +#. The returned value of this method is of type ``Cell*``, we have to + transform it into a Python one. This is done with ``PyCell_Link()``. + This macro is supplied by the ``PyCell.h`` header and this is why + it must be included. + +|newpage| + + +Wrapping of the ``Library::create()`` method: + +.. code-block:: c++ + + static PyObject* PyLibrary_create( PyObject*, PyObject* args ) + { + PyObject* arg0; + PyObject* arg1; + Library* library = NULL; + + HTRY + __cs.init( "Library.create" ); // Step (1). + if (not PyArg_ParseTuple( args, "O&O&:Library.create" + , Converter, &arg0 + , Converter, &arg1 )) { // Step (2). + PyErr_SetString( ConstructorError + , "invalid number of parameters for Library constructor." ); + return NULL; + } + if (__cs.getObjectIds() == ":db:string") { // Step (3.a) + DataBase* db = PYDATABASE_O(arg0); + library = Library::create( db, Name(PyString_AsString(arg1)) ); + } else if (__cs.getObjectIds() == ":library:string") { // Step (3.b) + Library* masterLibrary = PYLIBRARY_O(arg0); + library = Library::create( masterLibrary, Name(PyString_AsString(arg1)) ); + } else { + PyErr_SetString( ConstructorError + , "invalid number of parameters for Library constructor." ); + return NULL; + } + HCATCH + + return PyLibrary_Link( library ); + } + +Key point about this constructor: + +#. We want the Python interface to mimic as closely as possible the + C++ API. As such, Python object will be created using a static + ``.create()`` method. So we do not use the usual Python allocation + mechanism. + +#. As it is a *static* method, there is no first argument. + +#. Python do not allow function overload like C++. To emulate that + behavior we use the ``__cs`` object (which is a global variable). + + #. Init/reset the ``__cs`` object: see *step (1)*. + + #. Call ``PyArg_ParseTuple()``, read every mandatory or optional + argument as a Python object (``"O&"``) and use ``Converter`` + on each one. ``Converter`` will determine the real type of + the Python object given as argument by looking at the + encapsulated C++ class. It then update the ``__cs`` object. + Done in *step (2)* + + #. After the call to ``PyArg_ParseTuple()``, the function + ``__cs.getObjectIds()`` will return the *signature* of + the various arguments. In our case, the valid signatures + will be ``":db:string"`` (*step (3.a)*a) and ``":library:string"`` + (*step (3.b)*). + + #. Call the C++ method after extracting the C++ objects from + the Python arguments. Note the use of the ``PYLIBRARY_O()`` + and ``PYDATABSE_O()`` macros to perform the conversion. + +#. Return the result, encapsulated through a call to ``PyLibrary_Link()``. + +|newpage| + + +Wrapping of the ``Library::destroy()`` method: + +.. code-block:: c++ + + DBoDestroyAttribute(PyLibrary_destroy, PyLibrary) + +For C++ classes **that are derived** from ``DBo``, the destroy method +wrapper must be defined using the macro ``DBoDestroyAttribute()``. +This macro implements the bi-directional communication mechanism +using ``Hurricane::Property``. It **must not** be used for +non ``DBo`` derived classes. + + +Defining the method table of the PyLibrary type: + +.. code-block:: c++ + + PyMethodDef PyLibrary_Methods[] = + { { "create" , (PyCFunction)PyLibrary_create , METH_VARARGS|METH_STATIC + , "Creates a new library." } + , { "getCell" , (PyCFunction)PyLibrary_getCell, METH_VARARGS + , "Get the cell of name " } + , { "destroy" , (PyCFunction)PyLibrary_destroy, METH_NOARGS + , "Destroy associated hurricane object The python object remains." } + , {NULL, NULL, 0, NULL} /* sentinel */ + }; + + +This is standard Python/C API. The name of the ``PyMethodDef`` table must be +named from the class: ``PyLibrary_Methods``. + + +3.2.3 Python Type Linking +--------------------------- + +Defining the ``PyTypeLibrary`` class methods and the type linking function. + +Those are the functions for the Python object itself to work, not the +wrapped method from the C++ class. + +.. note:: + At this point we **do not** define the ``PyTypeLibrary`` itself. + Only it's functions and a function to set them up *once* the + type will be defined. + +.. code-block:: c++ + + DBoDeleteMethod(Library) + PyTypeObjectLinkPyType(Library) + + +The macro ``DBoDeleteMethod()`` define the function to delete a +``PyLibrary`` *Python* object. Again, do not mistake it for the deletion +of the C++ class (implemented by ``DBoDestroyAttribute()``). +Here again, ``DBoDeleteMethod()`` is specially tailored for +``DBo`` derived classes. + +.. _PyLibrary_LinkPyType(): + +To define ``PyLibrary_LinkPyType()``, use the ``PyTypeObjectLinkPyType()`` +macro. This macro is specific for ``DBo`` derived classes that are seen as +base classes under Python (i.e. we don't bother exposing the base +class under Python). ``PyLibrary_LinkPyType()`` setup the class functions +in the ``PyTypeLibrary`` type object, it **must** be called in the +Python module this class is part of (in this case: ``PyHurricane.cpp``). +This particular flavor of the macro *will define* and setup the +following class functions: + +* ``PyTypeLibrary.tp_compare`` (defined by the macro). +* ``PyTypeLibrary.tp_repr`` (defined by the macro). +* ``PyTypeLibrary.tp_str`` (defined by the macro). +* ``PyTypeLibrary.tp_hash`` (defined by the macro). +* ``PyTypeLibrary.tp_methods`` sets to the previously defined ``PyLibrary_Methods`` table. +* ``PyTypeLibrary.tp_dealloc`` is set to a function that *must* be named ``PyLibrary_DeAlloc``, + this is what ``DBoDeleteMethod`` does. It is *not* done by ``PyTypeObjectLinkPyType``. + +Defining the ``PyTypeLibrary`` type: + + +3.2.4 The Shared Library Part +------------------------------- + +This part will be put in a separate supporting shared library, allowing +other Python module to link against it (and make use of its symbols). + +.. code-block:: c++ + + DBoLinkCreateMethod(Library) + PyTypeObjectDefinitions(Library) + + +To define ``PyTypeLibrary``, use the ``PyTypeObjectDefinitions()`` macro. +This macro is specific for classes that, as exposed by Python, +are neither *derived* classes nor *base* classes for others. +That is, they are standalone from the inheritance point of view. + +The ``DBoLinkCreateMethod()`` macro will define the ``PyLibrary_Link()`` +function which is responsible for encapsulating a C++ ``Library`` object +into a Python ``PyLibrary`` one. + + +3.3 Python Module (C++ namespace) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +We use the Python module to replicate the C++ *namespace*. Thus, for the +``Hurricane`` namespace we create a Python ``Hurricane`` module which is +defined in the ``PyHurricane.cpp`` file, then we add into that module +dictionary all the Python types encapsulating the C++ classes of that +namespace. + +.. code-block:: c++ + + DL_EXPORT(void) initHurricane () + { + PyLibrary_LinkPyType(); // step 1. + + PYTYPE_READY( Library ) // step 2. + + __cs.addType( "library", &PyTypeLibrary, "", false ); // step 3. + + PyObject* module = Py_InitModule( "Hurricane", PyHurricane_Methods ); + if (module == NULL) { + cerr << "[ERROR]\n" + << " Failed to initialize Hurricane module." << endl; + return; + } + + Py_INCREF( &PyTypeLibrary ); // step 4. + PyModule_AddObject( module, "Library", (PyObject*)&PyTypeLibrary ); // step 4. + } + +The ``initHurricane()`` initialisation function shown above has +been scrubbed of everything not relevant to the ``PyLibrary`` class. +The integration of the ``PyLibrary`` class into the module needs +four steps: + +#. A call to `PyLibrary_LinkPyType()`_ to hook the Python type functions + in the Python type object. + +#. A call to the ``PYTYPE_READY()`` macro (standard Python). + +#. Registering the type into the ``__cs`` object, with ``addType()``. + The arguments are self explanatory, save for the last which is a + boolean to tell if this is a *derived* class or not. + +#. Adding the type object (``PyTypeLibrary``) into the dictionnary of + the module itself. This allow to mimic closely the C++ syntax: + + .. code-block:: python + + import Hurricane + lib = Hurricane.Library.create( db, 'root' ) diff --git a/documentation/PythonCpp/DbU.rst b/documentation/PythonCpp/DbU.rst new file mode 100644 index 00000000..930e76d1 --- /dev/null +++ b/documentation/PythonCpp/DbU.rst @@ -0,0 +1,67 @@ +.. -*- Mode: rst -*- + +.. include:: ../etc/definitions.rst + + +6. Encapsulating DbU +====================== + +While ``Hurricane::DbU`` is a class, the ``Hurricane::DbU::Unit`` is only +a ``typedef`` over ``uint64_t``. The ``DbU`` class only provides a set of +static methods to manipulate and convert to and from other units. +At Python level, ``DbU::Unit`` will be stored in plain ``long long``. + +When a ``DbU::Unit`` argument is expected in a Python functions, just use +the ``DbU::Unit PyAny_AsLong( PyObject* )`` function to convert it. + +For example, if we explicit the expension of: + +.. code-block:: c++ + + DirectSetLongAttribute(PyPoint_SetX,setX,PyPoint,Point) + +|newpage| + +We would get: + +.. code-block:: c++ + + static PyObject* PyPoint_setX ( PyPoint *self, PyObject* args ) + { + Point* cobject = static_cast( self->_object ); + if (cobject == NULL) { + PyErr_SetString( ProxyError + , "Attempt to call Point.setX() on an unbound Hurricane object" ); + return NULL; + } + + HTRY + PyObject* arg0 = NULL; + if (not PyArg_ParseTuple( args, "O:Point.setX()", &arg0 )) + return ( NULL ); + cobject->setX( Isobar::PyAny_AsLong(arg0) ); + HCATCH + Py_RETURN_NONE; + } + + +For the other way around, use ``PyObject* PyDbU_FromLong( DbU::Unit )``. + +.. code-block:: c++ + + DirectGetLongAttribute(PyPoint_GetX,getX,PyPoint,Point) + +We would get: + +.. code-block:: c++ + + static PyObject* PyPoint_GetX ( PyPoint *self, PyObject* args ) + { + Point* cobject = static_cast( self->_object ); + if (cobject == NULL) { + PyErr_SetString( ProxyError + , "Attempt to call Point.getX() on an unbound Hurricane object" ); + return NULL; + } + return Isobar::PyDbU_FromLong(cobject->getX()); + } diff --git a/documentation/PythonCpp/Introduction.rst b/documentation/PythonCpp/Introduction.rst new file mode 100644 index 00000000..5a3300e4 --- /dev/null +++ b/documentation/PythonCpp/Introduction.rst @@ -0,0 +1,185 @@ +.. -*- Mode: rst -*- + +.. include:: ../etc/definitions.rst + + +1. Introduction +================= + +* This document is written for people already familiar with the + `Python/C API Reference Manual`_. + +* The macros provided by the Hurricane Python/C API are written using + the standard Python C/API. That is, you may not use them and write + directly your functions with the original API or any mix between. + You only have to respect some naming convention. + +* Coriolis is build against Python 2.7. + + +1.1 First, A Disclaimer +~~~~~~~~~~~~~~~~~~~~~~~~~ + +The Hurricane Python/C++ API has been written about ten years ago, at a time +my mastering of template programming was less than complete. This is why this +interface is build with old fashioned C macro instead of C++ template. + +It is my hope that at some point in the future I will have time to completly +rewrite it, borrowing the interface from ``boost::python``. + + +1.2 About Technical Choices +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Some would say, why not use *off the shelf* wrappers like ``swig`` +or ``boost::python``, here are some clues. + +#. **Partial exposure of the C++ class tree.** We expose at Python level + C++ base classes, only if they provides common methods that we want + to see. Otherwise, we just show them as base classes under Python. + For instance ``Library`` is derived from ``DBo``, but we won't see + it under Python. + +#. **Bi-directional communication.** When a Python object is deleted, the + wrapper obviously has a pointer toward the underlying C++ object and + is able to delete it. But, the reverse case can occurs, meaning that + you have a C++ object wrapped in Python and the database delete the + underlying object. The wrapped Python object *must* be informed that + it no longer refer a valid C++ one. Moreover, as we do not control + when Python objects gets deleteds (that is, when their reference count + reaches zero), we can have valid Python object with a dangling + C++ pointer. So our Python objects can be warned by the C++ objects + that they are no longer valid and any other operation than the + deletion should result in a severe non-blocking error. + + To be precise, this apply to persistent object in the C++ database, + like ``Cell``, ``Net``, ``Instance`` or ``Component``. Short lived + objects like ``Box`` or ``Point`` retains the classic Python behavior. + + Another aspect is that, for all derived ``DBo`` objects, one and only + one Python object is associated. For one given ``Instance`` object we + will always return the *same* ``PyInstance`` object, thanks to the + bi-directional link. Obviously, the *reference count* of the + ``PyInstance`` is managed accordingly. This mechanism is implemented + by the ``PyInstance_Link()`` function. + +#. **Linking accross modules.** As far as I understand, the wrappers + are for monolithic libraries. That is, you wrap the entire library + in one go. But Hurricane has a modular design, the core database + then various tools. We do not, and cannot, have one gigantic wrapper + that would encompass all the libraries in one go. We do one Python + module for one C++ library. + + This brings another issue, at Python level this time. The Python + modules for the libraries have to share some functions. Python + provides a mechanism to pass C function pointers accross modules, + but I did found it cumbersome. Instead, all our modules are split + in two: + + * The first part contains the classic Python module code. + * The second part is to be put in a separate dynamic library that + will hold the shared functions. The Python module is dynamically linked + against that library like any other. And any other Python module + requiring the functions will link against the associated shared + library. + + Each module file will be compiled *twice*, once to build the Python + module (``__PYTHON_MODULE`` is defined) and once to build the supporting + shared library (``__PYTHON_MODULE__`` **not** defined). This tricky + double compilation is taken care of though the ``add_python_module`` + ``cmake`` macro. + + For the core Hurricane library we will have: + + * ``Hurricane.so`` the Python module (use with: ``import Hurricane``). + * ``libisobar.so.1.0`` the supporting shared library. + + The ``PyLibrary.cpp`` file will have the following structure: + + .. code-block:: c++ + + #include "hurricane/isobar/PyLibrary.h" + + namespace Isobar { + + extern "C" { + + #if defined(__PYTHON_MODULE__) + + // +=================================================================+ + // | "PyLibrary" Python Module Code Part | + // +=================================================================+ + // + // The classic part of a Python module. Goes into Hurricane.so. + + + #else // End of Python Module Code Part. + + // x=================================================================x + // | "PyLibrary" Shared Library Code Part | + // x=================================================================x + // + // Functions here will be part of the associated shared library and + // made available to all other Python modules. Goes into libisobar.so.1.0 + + + # endif // Shared Library Code Part. + + } // extern "C". + + } // Isobar namespace. + + + This way, we do not rely upon a pointer transmission through Python + modules, but directly uses linker capabilities. + + +1.3 Botched Design +~~~~~~~~~~~~~~~~~~~~ + +The mechanism to compute the signature of a call to a Python function, +the ``__cs`` object, is much too complex and, in fact, not needed. +At some point I may root it out, but it is used in so many places... + +What I should have used the ``"O!"`` capablity of ``PyArg_ParseTuple()``, +like in the code below: + +|newpage| + +.. code-block:: c++ + + static PyObject* PyContact_create ( PyObject*, PyObject *args ) + { + Contact* contact = NULL; + HTRY + PyNet* pyNet = NULL; + PyLayer* pyLayer = NULL; + PyComponent* pyComponent = NULL; + DbU::Unit x = 0; + DbU::Unit y = 0; + DbU::Unit width = 0; + DbU::Unit height = 0; + + if (PyArg_ParseTuple( args, "O!O!ll|ll:Contact.create" + , &PyTypeNet , &pyNet + , &PyTypeLayer, &pyLayer + , &x, &y, &width, &height)) { + contact = Contact::create( PYNET_O(pyNet), PYLAYER_O(pyLayer) + , x, y, width, height ); + } else { + PyErr_Clear(); + if (PyArg_ParseTuple( args, "O!O!ll|ll:Contact.create" + , &PyTypeComponent, &pyComponent + , &PyTypeLayer , &pyLayer + , &x, &y, &width, &height)) { + contact = Contact::create( PYCOMPONENT_O(pyComponent), PYLAYER_O(pyLayer) + , x, y, width, height ); + } else { + PyErr_SetString( ConstructorError + , "invalid number of parameters for Contact constructor." ); + return NULL; + } + } + HCATCH + return PyContact_Link( contact ); + } diff --git a/documentation/PythonCpp/Name.rst b/documentation/PythonCpp/Name.rst new file mode 100644 index 00000000..bb4470e8 --- /dev/null +++ b/documentation/PythonCpp/Name.rst @@ -0,0 +1,9 @@ +.. -*- Mode: rst -*- + +.. include:: ../etc/definitions.rst + + +7. No C++ Hurricane::Name encapsulation +========================================== + +To be written. diff --git a/documentation/PythonCpp/NonDBo.rst b/documentation/PythonCpp/NonDBo.rst new file mode 100644 index 00000000..db9f570a --- /dev/null +++ b/documentation/PythonCpp/NonDBo.rst @@ -0,0 +1,171 @@ +.. -*- Mode: rst -*- + +.. include:: ../etc/definitions.rst + + +5. Case 3 - Non-DBo Standalone Classe +======================================= + +Let's have a look at the encapsulation of ``Hurricane::Point``. + +Non-BDo derived classes do not support the bi-directionnal communication. +So each Python object is associated with one C++ object. The C++ object +is created and deleted along with the Python one. This behavior implies +that the C++ object is *copy constructible* (which should be the case). + + +5.1 Class Header +~~~~~~~~~~~~~~~~~~ + +Changes from :ref:`3.1 Class Associated Header File`: + +* There is no ``PyPoint_Link()`` function, as it's related to the + bi-directional communication mechanism. + +.. note:: + **About the _object attribute** of the PyPoint. As the C++ object life span + (``Point``) is linked to the Python (``PyPoint``) one, we may have used a + value instead of a pointer. It is best to keep a pointer as the macros + written for ``DBo`` derived classes will remain usables. + + +.. code-block:: c++ + + #ifndef ISOBAR_PY_POINT_H + #define ISOBAR_PY_POINT_H + + #include "hurricane/isobar/PyHurricane.h" + #include "hurricane/Point.h" + + namespace Isobar { + extern "C" { + + typedef struct { + PyObject_HEAD + Hurricane::Point* _object; + } PyPoint; + + extern PyTypeObject PyTypePoint; + extern PyMethodDef PyPoint_Methods[]; + extern void PyPoint_LinkPyType(); + + #define IsPyPoint(v) ( (v)->ob_type == &PyTypePoint ) + #define PYPOINT(v) ( (PyPoint*)(v) ) + #define PYPOINT_O(v) ( PYPOINT(v)->_object ) + + } // extern "C". + } // Isobar namespace. + + #endif // ISOBAR_PY_POINT_H + +|newpage| + + +5.2 Class File +~~~~~~~~~~~~~~~~ + +Changes from :ref:`3.2 Class Associated File`: + +* As there is no ``PyPoint_Link()`` function, there is no call to any + flavor of the ``DBoLinkcreatemethod()`` macro (obvious as it's *not* + a ``DBo``). + +* To use the standard Python constructor, we have to define ``PyPoint_NEW()`` + and ``PyPoint_Init()`` functions, I'm not absolutely certain that the later + needs to be defined (that part is still not clear to me from the Python doc). + +* As it's not a ``DBo`` there is no ``destroy()`` method, so no call to + ``DirectDestroyMethod()`` + +* Lastly, as this object has a ``PyPoint_NEW()`` (field ``tp_new``) and + a ``PyPoint_Init()`` (field ``tp_init``) we have to use the macro + ``PyTypeObjectLinkPyTypeNewInit()`` to define ``PyPoint_LinkPyType()``. + + +.. code-block:: c++ + + #include "hurricane/isobar/PyPoint.h" + + namespace Isobar { + using namespace Hurricane; + + extern "C" { + + #define METHOD_HEAD(function) GENERIC_METHOD_HEAD(Point,point,function) + + #if defined(__PYTHON_MODULE__) + + static PyObject* PyPoint_NEW ( PyObject* module, PyObject *args ) + { + Point* point = NULL; + HTRY + PyObject* arg0 = NULL; + PyObject* arg1 = NULL; + + __cs.init( "Point.Point" ); + if (not PyArg_ParseTuple( args,"|O&O&:Point.Point" + , Converter,&arg0 + , Converter,&arg1 )) { + PyErr_SetString ( ConstructorError + , "invalid number of parameters for Point constructor." ); + return NULL; + } + + if (__cs.getObjectIds() == "") + { point = new Point()); } + else if (__cs.getObjectIds() == ":point") + { point = new Point( *PYPOINT_O(arg0) ); } + else if (__cs.getObjectIds() == ":int:int") + { point = new Point( PyAny_AsLong(arg0), PyAny_AsLong(arg1) ); } + else { + PyErr_SetString ( ConstructorError + , "invalid number of parameters for Point constructor." ); + return NULL; + } + + PyPoint* pyPoint = PyObject_NEW( PyPoint, &PyTypePoint ); + if (pyPoint == NULL) { delete point; return NULL; } + pyPoint->_object = point; + HCATCH + + return (PyObject*)pyPoint; + } + + static int PyPoint_Init ( PyPoint* self, PyObject* args, PyObject* kwargs ) + { return 0; } + + DirectGetLongAttribute(PyPoint_getX,getX,PyPoint,Point) + DirectGetLongAttribute(PyPoint_getY,getY,PyPoint,Point) + DirectSetLongAttribute(PyPoint_SetX,setX,PyPoint,Point) + DirectSetLongAttribute(PyPoint_SetY,setY,PyPoint,Point) + + PyMethodDef PyPoint_Methods[] = + { { "getX" , (PyCFunction)PyPoint_getX , METH_NOARGS + , "Return the Point X value." } + , { "getY" , (PyCFunction)PyPoint_getY , METH_NOARGS + , "Return the Point Y value." } + , { "setX" , (PyCFunction)PyPoint_SetX , METH_VARARGS + , "Modify the Point X value." } + , { "setY" , (PyCFunction)PyPoint_SetY , METH_VARARGS + , "Modify the Point Y value." } + , {NULL, NULL, 0, NULL} /* sentinel */ + }; + + DirectDeleteMethod(PyPoint_DeAlloc,PyPoint) + PyTypeObjectLinkPyTypeNewInit(Point) + + #else // Python Module Code Part. + + PyTypeObjectDefinitions(Point) + + #endif // Shared Library Code Part. + + } // extern "C". + } // Isobar namespace. + + +5.2 Class File +~~~~~~~~~~~~~~~~ + +To put it bluntly, there is no difference in the Python module for +a standalone ``DBo`` class and a non-``DBo`` class. diff --git a/documentation/PythonCpp/PythonCpp.pdf b/documentation/PythonCpp/PythonCpp.pdf index a23b9254..c5b7b45e 100644 Binary files a/documentation/PythonCpp/PythonCpp.pdf and b/documentation/PythonCpp/PythonCpp.pdf differ diff --git a/documentation/PythonCpp/PythonCpp.rst b/documentation/PythonCpp/PythonCpp.rst deleted file mode 100644 index 6225a1f9..00000000 --- a/documentation/PythonCpp/PythonCpp.rst +++ /dev/null @@ -1,1296 +0,0 @@ -.. -*- Mode: rst -*- - -.. include:: ../etc/definitions.rst - - -|medskip| - - -=================================== -Hurricane Python/C++ API Tutorial -=================================== - -.. contents:: - -|newpage| - - -1. Introduction -================= - -* This document is written for people already familiar with the - `Python/C API Reference Manual`_. - -* The macros provided by the Hurricane Python/C API are written using - the standard Python C/API. That is, you may not use them and write - directly your functions with the original API or any mix between. - You only have to respect some naming convention. - -* Coriolis is build against Python 2.7. - - -1.1 First, A Disclaimer -~~~~~~~~~~~~~~~~~~~~~~~~~ - -The Hurricane Python/C++ API has been written about ten years ago, at a time -my mastering of template programming was less than complete. This is why this -interface is build with old fashioned C macro instead of C++ template. - -It is my hope that at some point in the future I will have time to completly -rewrite it, borrowing the interface from ``boost::python``. - - -1.2 About Technical Choices -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Some would say, why not use *off the shelf* wrappers like ``swig`` -or ``boost::python``, here are some clues. - -#. **Partial exposure of the C++ class tree.** We expose at Python level - C++ base classes, only if they provides common methods that we want - to see. Otherwise, we just show them as base classes under Python. - For instance ``Library`` is derived from ``DBo``, but we won't see - it under Python. - -#. **Bi-directional communication.** When a Python object is deleted, the - wrapper obviously has a pointer toward the underlying C++ object and - is able to delete it. But, the reverse case can occurs, meaning that - you have a C++ object wrapped in Python and the database delete the - underlying object. The wrapped Python object *must* be informed that - it no longer refer a valid C++ one. Moreover, as we do not control - when Python objects gets deleteds (that is, when their reference count - reaches zero), we can have valid Python object with a dangling - C++ pointer. So our Python objects can be warned by the C++ objects - that they are no longer valid and any other operation than the - deletion should result in a severe non-blocking error. - - To be precise, this apply to persistent object in the C++ database, - like ``Cell``, ``Net``, ``Instance`` or ``Component``. Short lived - objects like ``Box`` or ``Point`` retains the classic Python behavior. - - Another aspect is that, for all derived ``DBo`` objects, one and only - one Python object is associated. For one given ``Instance`` object we - will always return the *same* ``PyInstance`` object, thanks to the - bi-directional link. Obviously, the *reference count* of the - ``PyInstance`` is managed accordingly. This mechanism is implemented - by the ``PyInstance_Link()`` function. - -#. **Linking accross modules.** As far as I understand, the wrappers - are for monolithic libraries. That is, you wrap the entire library - in one go. But Hurricane has a modular design, the core database - then various tools. We do not, and cannot, have one gigantic wrapper - that would encompass all the libraries in one go. We do one Python - module for one C++ library. - - This brings another issue, at Python level this time. The Python - modules for the libraries have to share some functions. Python - provides a mechanism to pass C function pointers accross modules, - but I did found it cumbersome. Instead, all our modules are split - in two: - - * The first part contains the classic Python module code. - * The second part is to be put in a separate dynamic library that - will hold the shared functions. The Python module is dynamically linked - against that library like any other. And any other Python module - requiring the functions will link against the associated shared - library. - - Each module file will be compiled *twice*, once to build the Python - module (``__PYTHON_MODULE`` is defined) and once to build the supporting - shared library (``__PYTHON_MODULE__`` **not** defined). This tricky - double compilation is taken care of though the ``add_python_module`` - ``cmake`` macro. - - For the core Hurricane library we will have: - - * ``Hurricane.so`` the Python module (use with: ``import Hurricane``). - * ``libisobar.so.1.0`` the supporting shared library. - - The ``PyLibrary.cpp`` file will have the following structure: - - .. code:: c++ - - #include "hurricane/isobar/PyLibrary.h" - - namespace Isobar { - - extern "C" { - - #if defined(__PYTHON_MODULE__) - - // +=================================================================+ - // | "PyLibrary" Python Module Code Part | - // +=================================================================+ - // - // The classic part of a Python module. Goes into Hurricane.so. - - - #else // End of Python Module Code Part. - - // x=================================================================x - // | "PyLibrary" Shared Library Code Part | - // x=================================================================x - // - // Functions here will be part of the associated shared library and - // made available to all other Python modules. Goes into libisobar.so.1.0 - - - # endif // Shared Library Code Part. - - } // extern "C". - - } // Isobar namespace. - - - This way, we do not rely upon a pointer transmission through Python - modules, but directly uses linker capabilities. - - -1.3 Botched Design -~~~~~~~~~~~~~~~~~~~~ - -The mechanism to compute the signature of a call to a Python function, -the ``__cs`` object, is much too complex and, in fact, not needed. -At some point I may root it out, but it is used in so many places... - -What I should have used the ``"O!"`` capablity of ``PyArg_ParseTuple()``, -like in the code below: - -|newpage| - -.. code:: c++ - - static PyObject* PyContact_create ( PyObject*, PyObject *args ) - { - Contact* contact = NULL; - HTRY - PyNet* pyNet = NULL; - PyLayer* pyLayer = NULL; - PyComponent* pyComponent = NULL; - DbU::Unit x = 0; - DbU::Unit y = 0; - DbU::Unit width = 0; - DbU::Unit height = 0; - - if (PyArg_ParseTuple( args, "O!O!ll|ll:Contact.create" - , &PyTypeNet , &pyNet - , &PyTypeLayer, &pyLayer - , &x, &y, &width, &height)) { - contact = Contact::create( PYNET_O(pyNet), PYLAYER_O(pyLayer) - , x, y, width, height ); - } else { - PyErr_Clear(); - if (PyArg_ParseTuple( args, "O!O!ll|ll:Contact.create" - , &PyTypeComponent, &pyComponent - , &PyTypeLayer , &pyLayer - , &x, &y, &width, &height)) { - contact = Contact::create( PYCOMPONENT_O(pyComponent), PYLAYER_O(pyLayer) - , x, y, width, height ); - } else { - PyErr_SetString( ConstructorError - , "invalid number of parameters for Contact constructor." ); - return NULL; - } - } - HCATCH - return PyContact_Link( contact ); - } - - -2. Basic File Structure and CMake configuration -================================================= - -As a first example we will consider the ``Hurrican::Library`` -class. To export a class into Python, we must create three files: - -#. ``PyLibrary.h``, defines the ``PyLibrary`` C-Struct and the functions - needed outside the module istself (mostly for ``PyHurricane.cpp``). - -#. ``PyLibrary.cpp``, contains the complete wrapping of the class and - the Python type definition (``PyTypeLibrary``). - -#. ``PyHurricane.cpp``, the definition of the Python module into which - the classes are registered. The module act as a ``namespace`` in - Python so it is good practice to give it the same name as it's - associated C++ namespace. - -|newpage| - -To build a Python module in |cmake|, use the following macro: - - .. code:: cmake - - set( pyCpps PyLibrary.cpp - PyHurricane.cpp ) - set( pyIncludes hurricane/isobar/PyLibrary.h - - add_python_module( "${pyCpps}" - "${pyIncludes}" - "isobar;1.0;1" # Name & version of the supporting - # shared library. - Hurricane # Name of the Python module will give: - # Hurricane.so - "${depLibs}" # List of dependency libraries. - include/coriolis2/hurricane/isobar - # Where to install the include files. - ) - - -3. Case 1 - DBo Derived, Standalone -====================================== - -As example, we take ``Library``. This a ``DBo`` derived class, but we -choose not to export the parent classes. From Python, it will appear -as a base class. - - -3.1 Class Associated Header File -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Here is the typical content of a header file (for ``PyLibrary``): - -.. code:: c++ - - #ifndef PY_LIBRARY_H - #define PY_LIBRARY_H - - #include "hurricane/isobar/PyHurricane.h" - #include "hurricane/Library.h" - - namespace Isobar { - using namespace Hurricane; - - extern "C" { - - typedef struct { - PyObject_HEAD - Library* _object; - } PyLibrary; - - extern PyTypeObject PyTypeLibrary; - extern PyMethodDef PyLibrary_Methods[]; - extern PyObject* PyLibrary_Link ( Hurricane::Library* lib ); - extern void PyLibrary_LinkPyType (); - - - #define IsPyLibrary(v) ( (v)->ob_type == &PyTypeLibrary ) - #define PYLIBRARY(v) ( (PyLibrary*)(v) ) - #define PYLIBRARY_O(v) ( PYLIBRARY(v)->_object ) - - } // extern "C". - } // Isobar namespace. - - #endif // PY_LIBRARY_H - - -The code is organized as follow: - -1. It must have, *as the first include* ``PyHurricane.h``, which provides - the complete bunch of macros needed to build the module. Then the include - of the C++ class we want to wrap (``Library.h``). - -2. As Python is written in C, all the wrapper code has to be but inside - an ``extern "C"`` namespace. - -3. Definition of the wrapped |struct|, ``PyLibrary``. It is standard Python here. - - .. note:: - For our set of macros to work, the name of the pointer to the - C++ class must always be **_object**, and the various functions and - macros defined here must take the name of the class (either in - lowercase, camel case or capitals). - -4. Declaration of the Python type ``PyTypeLibrary`` (standard). - -5. Declaration of the Python type table of methods ``PyLibrary_Methods`` (standard). - -.. _3.6: - -6. Declaration of ``PyLibrary_Link()``, helper to convert a C++ ``Lybrary`` into - a ``PyLibrary`` (put in the support shared library). - -7. Declaration of ``PyLibrary_LinkPyType()``, this function setup the class-level - function of the new Python type (here, ``PyTypeLibrary``). - -8. And, lastly, three macros to: - - * ``IsPylibrary()``, know if a Python object is a ``PyLibrary`` - * ``PYLIBRARY()``, force cast (C style) of a ``PyObject`` into a ``PyLibrary``. - * ``PYLIBRARY_O()``, extract the C++ object (``Library*``) from the Python - object (``PyLibrary``). - - -3.2 Class Associated File -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -3.2.1 Head of the file ------------------------- - -.. code:: c++ - - #include "hurricane/isobar/PyLibrary.h" - #include "hurricane/isobar/PyDataBase.h" - #include "hurricane/isobar/PyCell.h" - - namespace Isobar { - using namespace Hurricane; - - extern "C" { - - #define METHOD_HEAD(function) GENERIC_METHOD_HEAD(Library,lib,function) - -As for the header, all the code must be put inside a ``extern "C"`` namespace. - -A convenience macro ``METHOD_HEAD()`` must be defined, by refining -``GENERIC_METHOD_HEAD()``. This macro will be used in the method wrappers -below to cast the ``_object`` field of the Python object into the -appropriate C++ class, this is done using a C-style cast. -The parameters of that macro are: - -#. The C++ encapsulated class (``Library``). -#. The name of the *variable* that will be used to store a pointer - to the C++ working object. -#. The name of the C++ method which is to be wrapped. - - -3.2.2 The Python Module Part ------------------------------- - -First, we have to build all the wrappers to the C++ methods of -the class. For common predicates, accessors, and mutators macros -are supplied. - -Wrapping of the ``Library::getCell()`` method: - -.. code:: c++ - - static PyObject* PyLibrary_getCell ( PyLibrary* self, PyObject* args ) - { - Cell* cell = NULL; - - HTRY - METHOD_HEAD( "Library.getCell()" ) - char* name = NULL; - if (PyArg_ParseTuple(args,"s:Library.getCell", &name)) { - cell = lib->getCell( Name(name) ); - } else { - PyErr_SetString( ConstructorError - , "invalid number of parameters for Library::getCell." ); - return NULL; - } - HCATCH - - return PyCell_Link(cell); - } - -Key points about this method wrapper: - -#. The ``HTRY`` / ``HCATCH`` macros provides an insulation from the C++ - exceptions. If one is emitted, it will be catched and transformed in - a Python one. This way, the Python program will be cleanly interrupted - and the usual stack trace displayed. - -#. The returned value of this method is of type ``Cell*``, we have to - transform it into a Python one. This is done with ``PyCell_Link()``. - This macro is supplied by the ``PyCell.h`` header and this is why - it must be included. - -|newpage| - - -Wrapping of the ``Library::create()`` method: - -.. code:: c++ - - static PyObject* PyLibrary_create( PyObject*, PyObject* args ) - { - PyObject* arg0; - PyObject* arg1; - Library* library = NULL; - - HTRY - __cs.init( "Library.create" ); // Step (1). - if (not PyArg_ParseTuple( args, "O&O&:Library.create" - , Converter, &arg0 - , Converter, &arg1 )) { // Step (2). - PyErr_SetString( ConstructorError - , "invalid number of parameters for Library constructor." ); - return NULL; - } - if (__cs.getObjectIds() == ":db:string") { // Step (3.a) - DataBase* db = PYDATABASE_O(arg0); - library = Library::create( db, Name(PyString_AsString(arg1)) ); - } else if (__cs.getObjectIds() == ":library:string") { // Step (3.b) - Library* masterLibrary = PYLIBRARY_O(arg0); - library = Library::create( masterLibrary, Name(PyString_AsString(arg1)) ); - } else { - PyErr_SetString( ConstructorError - , "invalid number of parameters for Library constructor." ); - return NULL; - } - HCATCH - - return PyLibrary_Link( library ); - } - -Key point about this constructor: - -#. We want the Python interface to mimic as closely as possible the - C++ API. As such, Python object will be created using a static - ``.create()`` method. So we do not use the usual Python allocation - mechanism. - -#. As it is a *static* method, there is no first argument. - -#. Python do not allow function overload like C++. To emulate that - behavior we use the ``__cs`` object (which is a global variable). - - #. Init/reset the ``__cs`` object: see *step (1)*. - - #. Call ``PyArg_ParseTuple()``, read every mandatory or optional - argument as a Python object (``"O&"``) and use ``Converter`` - on each one. ``Converter`` will determine the real type of - the Python object given as argument by looking at the - encapsulated C++ class. It then update the ``__cs`` object. - Done in *step (2)* - - #. After the call to ``PyArg_ParseTuple()``, the function - ``__cs.getObjectIds()`` will return the *signature* of - the various arguments. In our case, the valid signatures - will be ``":db:string"`` (*step (3.a)*a) and ``":library:string"`` - (*step (3.b)*). - - #. Call the C++ method after extracting the C++ objects from - the Python arguments. Note the use of the ``PYLIBRARY_O()`` - and ``PYDATABSE_O()`` macros to perform the conversion. - -#. Return the result, encapsulated through a call to ``PyLibrary_Link()``. - -|newpage| - - -Wrapping of the ``Library::destroy()`` method: - -.. code:: c++ - - DBoDestroyAttribute(PyLibrary_destroy, PyLibrary) - -For C++ classes **that are derived** from ``DBo``, the destroy method -wrapper must be defined using the macro ``DBoDestroyAttribute()``. -This macro implements the bi-directional communication mechanism -using ``Hurricane::Property``. It **must not** be used for -non ``DBo`` derived classes. - - -Defining the method table of the PyLibrary type: - -.. code:: c++ - - PyMethodDef PyLibrary_Methods[] = - { { "create" , (PyCFunction)PyLibrary_create , METH_VARARGS|METH_STATIC - , "Creates a new library." } - , { "getCell" , (PyCFunction)PyLibrary_getCell, METH_VARARGS - , "Get the cell of name " } - , { "destroy" , (PyCFunction)PyLibrary_destroy, METH_NOARGS - , "Destroy associated hurricane object The python object remains." } - , {NULL, NULL, 0, NULL} /* sentinel */ - }; - - -This is standard Python/C API. The name of the ``PyMethodDef`` table must be -named from the class: ``PyLibrary_Methods``. - - -3.2.3 Python Type Linking ---------------------------- - -Defining the ``PyTypeLibrary`` class methods and the type linking function. - -Those are the functions for the Python object itself to work, not the -wrapped method from the C++ class. - -.. note:: - At this point we **do not** define the ``PyTypeLibrary`` itself. - Only it's functions and a function to set them up *once* the - type will be defined. - -.. code:: c++ - - DBoDeleteMethod(Library) - PyTypeObjectLinkPyType(Library) - - -The macro ``DBoDeleteMethod()`` define the function to delete a -``PyLibrary`` *Python* object. Again, do not mistake it for the deletion -of the C++ class (implemented by ``DBoDestroyAttribute()``). -Here again, ``DBoDeleteMethod()`` is specially tailored for -``DBo`` derived classes. - -.. _PyLibrary_LinkPyType(): - -To define ``PyLibrary_LinkPyType()``, use the ``PyTypeObjectLinkPyType()`` -macro. This macro is specific for ``DBo`` derived classes that are seen as -base classes under Python (i.e. we don't bother exposing the base -class under Python). ``PyLibrary_LinkPyType()`` setup the class functions -in the ``PyTypeLibrary`` type object, it **must** be called in the -Python module this class is part of (in this case: ``PyHurricane.cpp``). -This particular flavor of the macro *will define* and setup the -following class functions: - -* ``PyTypeLibrary.tp_compare`` (defined by the macro). -* ``PyTypeLibrary.tp_repr`` (defined by the macro). -* ``PyTypeLibrary.tp_str`` (defined by the macro). -* ``PyTypeLibrary.tp_hash`` (defined by the macro). -* ``PyTypeLibrary.tp_methods`` sets to the previously defined ``PyLibrary_Methods`` table. -* ``PyTypeLibrary.tp_dealloc`` is set to a function that *must* be named ``PyLibrary_DeAlloc``, - this is what ``DBoDeleteMethod`` does. It is *not* done by ``PyTypeObjectLinkPyType``. - -Defining the ``PyTypeLibrary`` type: - - -3.2.4 The Shared Library Part -------------------------------- - -This part will be put in a separate supporting shared library, allowing -other Python module to link against it (and make use of its symbols). - -.. code:: c++ - - DBoLinkCreateMethod(Library) - PyTypeObjectDefinitions(Library) - - -To define ``PyTypeLibrary``, use the ``PyTypeObjectDefinitions()`` macro. -This macro is specific for classes that, as exposed by Python, -are neither *derived* classes nor *base* classes for others. -That is, they are standalone from the inheritance point of view. - -The ``DBoLinkCreateMethod()`` macro will define the ``PyLibrary_Link()`` -function which is responsible for encapsulating a C++ ``Library`` object -into a Python ``PyLibrary`` one. - - -3.3 Python Module (C++ namespace) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -We use the Python module to replicate the C++ *namespace*. Thus, for the -``Hurricane`` namespace we create a Python ``Hurricane`` module which is -defined in the ``PyHurricane.cpp`` file, then we add into that module -dictionary all the Python types encapsulating the C++ classes of that -namespace. - -.. code:: c++ - - DL_EXPORT(void) initHurricane () - { - PyLibrary_LinkPyType(); // step 1. - - PYTYPE_READY( Library ) // step 2. - - __cs.addType( "library", &PyTypeLibrary, "", false ); // step 3. - - PyObject* module = Py_InitModule( "Hurricane", PyHurricane_Methods ); - if (module == NULL) { - cerr << "[ERROR]\n" - << " Failed to initialize Hurricane module." << endl; - return; - } - - Py_INCREF( &PyTypeLibrary ); // step 4. - PyModule_AddObject( module, "Library", (PyObject*)&PyTypeLibrary ); // step 4. - } - -The ``initHurricane()`` initialisation function shown above has -been scrubbed of everything not relevant to the ``PyLibrary`` class. -The integration of the ``PyLibrary`` class into the module needs -four steps: - -#. A call to `PyLibrary_LinkPyType()`_ to hook the Python type functions - in the Python type object. - -#. A call to the ``PYTYPE_READY()`` macro (standard Python). - -#. Registering the type into the ``__cs`` object, with ``addType()``. - The arguments are self explanatory, save for the last which is a - boolean to tell if this is a *derived* class or not. - -#. Adding the type object (``PyTypeLibrary``) into the dictionnary of - the module itself. This allow to mimic closely the C++ syntax: - - .. code:: python - - import Hurricane - lib = Hurricane.Library.create( db, 'root' ) - -|newpage| - - -4. Case 2 - Hierarchy of DBo Derived Classes -============================================== - -Now we want to export the following C++ class hierarchy into Python: :: - - PyEntity <-- PyComponent <-+- PyContact - +- PySegment <-+- PyHorizontal - +- PyVertical - - -4.1 Base Class Header -~~~~~~~~~~~~~~~~~~~~~~~ - -**Remark:** this is only a partial description of tree for the sake of -clarity. - -One important fact to remember is that ``PyEntity`` and ``PyComponent`` -being related to C++ abstract classes, no objects of those types will be -created, only ``PyContact``, ``PyHorizontal`` or ``PyVertical`` will. - -The consequence is that there is no ``PyEntity_Link()`` like in `3.6`_ -but instead two functions: - -#. ``PyEntity_NEW()`` which create the relevant ``PyEntity`` *derived* - object from the ``Entity`` one. For example, if the ``Entity*`` given - as argument is in fact a ``Horizontal*``, then the function will - return a ``PyHorizontal*``. - -#. ``EntityCast()`` do the reverse of ``PyEntity_NEW()`` that is, from - a ``PyEntity``, return the C++ *derived* object. Again, if the - ``PyEntity*`` is a ``PyHorizontal*``, the function will cast it as - a ``Horizontal*`` *then* return it as an ``Entity*``. - -.. code:: python - - #ifndef ISOBAR_PY_ENTITY_H - #define ISOBAR_PY_ENTITY_H - - #include "hurricane/isobar/PyHurricane.h" - #include "hurricane/Entity.h" - - namespace Isobar { - extern "C" { - - typedef struct { - PyObject_HEAD - Hurricane::Entity* _object; - } PyEntity; - - extern PyObject* PyEntity_NEW ( Hurricane::Entity* entity ); - extern void PyEntity_LinkPyType (); - extern PyTypeObject PyTypeEntity; - extern PyMethodDef PyEntity_Methods[]; - - - #define IsPyEntity(v) ( (v)->ob_type == &PyTypeEntity ) - #define PYENTITY(v) ( (PyEntity*)(v) ) - #define PYENTITY_O(v) ( PYENTITY(v)->_object ) - - } // extern "C". - - Hurricane::Entity* EntityCast ( PyObject* derivedObject ); - - } // Isobar namespace. - - #endif // ISOBAR_PY_ENTITY_H - -|newpage| - - -4.2 Base Class File -~~~~~~~~~~~~~~~~~~~~~ - -Changes from `3.2 Class Associated File`_ are: - -#. No call to ``DBoLinkCreateMethod()`` because there must be no ``PyEntity_Link()``, - but the definitions of ``PyEntity_NEW()`` and ``EntityCast``. - -#. For defining the ``PyTypeEntity`` Python type, we call a different - macro: ``PyTypeRootObjectDefinitions``, dedicated to base classes. - - -.. code:: c++ - - #include "hurricane/isobar/PyCell.h" - #include "hurricane/isobar/PyHorizontal.h" - #include "hurricane/isobar/PyVertical.h" - #include "hurricane/isobar/PyContact.h" - - namespace Isobar { - using namespace Hurricane; - - extern "C" { - - #if defined(__PYTHON_MODULE__) - - #define METHOD_HEAD(function) GENERIC_METHOD_HEAD(Entity,entity,function) - - DBoDestroyAttribute(PyEntity_destroy ,PyEntity) - - static PyObject* PyEntity_getCell ( PyEntity *self ) - { - Cell* cell = NULL; - HTRY - METHOD_HEAD( "Entity.getCell()" ) - cell = entity->getCell(); - HCATCH - return PyCell_Link( cell ); - } - - PyMethodDef PyEntity_Methods[] = - { { "getCell", (PyCFunction)PyEntity_getCell, METH_NOARGS - , "Returns the entity cell." } - , { "destroy", (PyCFunction)PyEntity_destroy, METH_NOARGS - , "Destroy associated hurricane object, the python object remains." } - , {NULL, NULL, 0, NULL} /* sentinel */ - }; - - - DBoDeleteMethod(Entity) - PyTypeObjectLinkPyType(Entity) - - #else // End of Python Module Code Part. - - PyObject* PyEntity_NEW ( Entity* entity ) - { - if (not entity) { - PyErr_SetString ( HurricaneError, "Invalid Entity (bad occurrence)" ); - return NULL; - } - - Horizontal* horizontal = dynamic_cast(entity); - if (horizontal) return PyHorizontal_Link( horizontal ); - - Vertical* vertical = dynamic_cast(entity); - if (vertical) return PyVertical_Link( vertical ); - - Contact* contact = dynamic_cast(entity); - if (contact) return PyContact_Link( contact ); - - Py_RETURN_NONE; - } - - PyTypeRootObjectDefinitions(Entity) - - #endif // Shared Library Code Part (1). - - } // extern "C". - - - #if !defined(__PYTHON_MODULE__) - - Hurricane::Entity* EntityCast ( PyObject* derivedObject ) { - if (IsPyHorizontal(derivedObject)) return PYHORIZONTAL_O(derivedObject); - if (IsPyVertical (derivedObject)) return PYVERTICAL_O(derivedObject); - if (IsPyContact (derivedObject)) return PYCONTACT_O(derivedObject); - return NULL; - } - - #endif // Shared Library Code Part (2). - - } // Isobar namespace. - -|newpage| - - -4.3 Intermediate Class Header -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Changes from `3.1 Class Associated Header File`_ are: - -#. As for ``PyEntity``, and because this is still an abstract class, - there is no ``PyComponent_Link()`` function. - -#. The definition of the ``PyComponent`` |struct| is differs. There is - no ``PyObject_HEAD`` (it is a Python *derived* class). The only - field is of the base class type ``PyEntity`` and for use with - Coriolis macros, **it must** be named ``_baseObject`` (note that - this is *not* a pointer but a whole object). - -.. code:: c++ - - #ifndef ISOBAR_PY_COMPONENT_H - #define ISOBAR_PY_COMPONENT_H - - #include "hurricane/isobar/PyEntity.h" - #include "hurricane/Component.h" - - namespace Isobar { - extern "C" { - - typedef struct { - PyEntity _baseObject; - } PyComponent; - - extern PyTypeObject PyTypeComponent; - extern PyMethodDef PyComponent_Methods[]; - extern void PyComponent_LinkPyType (); - - #define IsPyComponent(v) ((v)->ob_type == &PyTypeComponent) - #define PYCOMPONENT(v) ((PyComponent*)(v)) - #define PYCOMPONENT_O(v) (static_cast(PYCOMPONENT(v)->_baseObject._object)) - - } // extern "C". - } // Isobar namespace. - - #endif - - -4.4 Intermediate Class File -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Changes from `3.2 Class Associated File`_ are: - -1. Redefinition of the default macros ``ACCESS_OBJECT`` and ``ACCESS_CLASS``. - - * The pointer to the C++ encapsulated object (attribute ``_object``) is hold - by the base class ``PyEntity``. The ``ACCESS_OBJECT`` macro which is tasked - to give access to that attribute is then ``_baseObject._object`` as - ``PyComponent`` is a direct derived class of ``PyEntity``. - - * ``ACCESS_CLASS`` is similar to ``ACCESS_OBJECT`` for accessing the base - class, that is a pointer to ``PyEntity``. - -|newpage| - -2. For defining the ``PyTypeComponent`` Python type, we call a yet different - macro: ``PyTypeInheritedObjectDefinitions()``, dedicated to derived classes. - For this this macro we need to give as argument the derived class and the - base class. - -.. code:: c++ - - #include "hurricane/isobar/PyComponent.h" - #include "hurricane/isobar/PyNet.h" - - namespace Isobar { - using namespace Hurricane; - - extern "C" { - - #undef ACCESS_OBJECT - #undef ACCESS_CLASS - #define ACCESS_OBJECT _baseObject._object - #define ACCESS_CLASS(_pyObject) &(_pyObject->_baseObject) - #define METHOD_HEAD(function) GENERIC_METHOD_HEAD(Component,component,function) - - #if defined(__PYTHON_MODULE__) - - DirectGetLongAttribute(PyComponent_getX,getX,PyComponent,Component) - DirectGetLongAttribute(PyComponent_getY,getY,PyComponent,Component) - DBoDestroyAttribute(PyComponent_destroy,PyComponent) - - static PyObject* PyComponent_getNet ( PyComponent *self ) - { - Net* net = NULL; - HTRY - METHOD_HEAD( "Component.getNet()" ) - net = component->getNet( ); - HCATCH - return PyNet_Link( net ); - } - - PyMethodDef PyComponent_Methods[] = - { { "getX" , (PyCFunction)PyComponent_getX , METH_NOARGS - , "Return the Component X value." } - , { "getY" , (PyCFunction)PyComponent_getY , METH_NOARGS - , "Return the Component Y value." } - , { "getNet" , (PyCFunction)PyComponent_getNet , METH_NOARGS - , "Returns the net owning the component." } - , { "destroy", (PyCFunction)PyComponent_destroy, METH_NOARGS - , "destroy associated hurricane object, the python object remains." } - , {NULL, NULL, 0, NULL} /* sentinel */ - }; - - DBoDeleteMethod(Component) - PyTypeObjectLinkPyType(Component) - - #else // Python Module Code Part. - - PyTypeInheritedObjectDefinitions(Component, Entity) - - #endif // Shared Library Code Part. - - } // extern "C". - } // Isobar namespace. - - -4.5 Terminal Class Header -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The contents of this file is almost identical to `4.3 Intermediate Class Header`_, -save for the presence of a ``PyContact_Link()`` function. She is present -at this level because the class is a concrete one and can be instanciated. - -.. code:: c++ - - #ifndef ISOBAR_PY_CONTACT_H - #define ISOBAR_PY_CONTACT_H - - #include "hurricane/isobar/PyComponent.h" - #include "hurricane/Contact.h" - - namespace Isobar { - extern "C" { - - typedef struct { - PyComponent _baseObject; - } PyContact; - - extern PyTypeObject PyTypeContact; - extern PyMethodDef PyContact_Methods[]; - extern PyObject* PyContact_Link ( Hurricane::Contact* object ); - extern void PyContact_LinkPyType (); - - #define IsPyContact(v) ( (v)->ob_type == &PyTypeContact ) - #define PYCONTACT(v) ( (PyContact*)(v) ) - #define PYCONTACT_O(v) ( PYCONTACT(v)->_baseObject._baseObject._object ) - - } // extern "C". - } // Isobar namespace. - - #endif // ISOBAR_PY_CONTACT_H - - -4.6 Terminal Class File -~~~~~~~~~~~~~~~~~~~~~~~~~ - -Changes from `4.4 Intermediate Class File`_ are: - -#. As previously, we have to redefine the macros ``ACCESS_OBJECT`` and ``ACCESS_CLASS``. - But, as we are one level deeper into the hierarchy, one more level of - indirection using ``_baseObject`` must be used. - - * ``ACCESS_OBJECT`` becomes ``_baseObject._baseObject._object``. - - * ``ACCESS_CLASS`` becomes ``&(_pyObject->_baseObject._baseObject)``. - -#. For defining the ``PyTypeContact`` Python type, we call again - ``PyTypeInheritedObjectDefinitions()``. It is the same whether the class is - terminal or not. - -#. And, this time, as the Python class is concrete, we call the macro - ``DBoLinkCreateMethod()`` to create the ``PyContact_Link()`` function. - - -.. code:: c++ - - #include "hurricane/isobar/PyContact.h" - - namespace Isobar { - using namespace Hurricane; - - extern "C" { - - #undef ACCESS_OBJECT - #undef ACCESS_CLASS - #define ACCESS_OBJECT _baseObject._baseObject._object - #define ACCESS_CLASS(_pyObject) &(_pyObject->_baseObject._baseObject) - #define METHOD_HEAD(function) GENERIC_METHOD_HEAD(Contact,contact,function) - - #if defined(__PYTHON_MODULE__) - - DirectGetLongAttribute(PyContact_getWidth , getWidth , PyContact,Contact) - DirectGetLongAttribute(PyContact_getHeight, getHeight, PyContact,Contact) - DBoDestroyAttribute(PyContact_destroy, PyContact) - - static PyObject* PyContact_create ( PyObject*, PyObject *args ) - { - Contact* contact = NULL; - HTRY - // Usual signature then arguments parsing. - HCATCH - return PyContact_Link(contact); - } - - PyMethodDef PyContact_Methods[] = - { { "create" , (PyCFunction)PyContact_create , METH_VARARGS|METH_STATIC - , "Create a new Contact." } - , { "destroy" , (PyCFunction)PyContact_destroy , METH_NOARGS - , "Destroy associated hurricane object, the python object remains." } - , { "getWidth" , (PyCFunction)PyContact_getWidth , METH_NOARGS - , "Return the contact width." } - , { "getHeight", (PyCFunction)PyContact_getHeight, METH_NOARGS - , "Return the contact height." } - , {NULL, NULL, 0, NULL} /* sentinel */ - }; - - DBoDeleteMethod(Contact) - PyTypeObjectLinkPyType(Contact) - - #else // Python Module Code Part. - - DBoLinkCreateMethod(Contact) - PyTypeInheritedObjectDefinitions(Contact, Component) - - #endif // Shared Library Code Part. - - } // extern "C". - } // Isobar namespace. - - -4.8 Python Module -~~~~~~~~~~~~~~~~~~~ - -.. code:: c++ - - DL_EXPORT(void) initHurricane () - { - PyEntity_LinkPyType(); // step 1. - PyComponent_LinkPyType(); - PyContact_LinkPyType(); - - PYTYPE_READY( Entity ) // step 2. - PYTYPE_READY_SUB( Component, Entity ) - PYTYPE_READY_SUB( Contact , Component ) - - __cs.addType( "ent" , &PyTypeEntity , "" , false ); // step 3. - __cs.addType( "comp" , &PyTypeComponent, "", false, "ent" ); - __cs.addType( "contact", &PyTypeContact , "" , false, "comp" ); - - PyObject* module = Py_InitModule( "Hurricane", PyHurricane_Methods ); - if (module == NULL) { - cerr << "[ERROR]\n" - << " Failed to initialize Hurricane module." << endl; - return; - } - - Py_INCREF( &PyTypeContact ); // step 4. - PyModule_AddObject( module, "Contact", (PyObject*)&PyTypeContact ); // step 4. - } - - -5. Case 3 - Non-DBo Standalone Classe -======================================= - -Let's have a look at the encapsulation of ``Hurricane::Point``. - -Non-BDo derived classes do not support the bi-directionnal communication. -So each Python object is associated with one C++ object. The C++ object -is created and deleted along with the Python one. This behavior implies -that the C++ object is *copy constructible* (which should be the case). - - -5.1 Class Header -~~~~~~~~~~~~~~~~~~ - -Changes from `3.1 Class Associated Header File`_: - -* There is no ``PyPoint_Link()`` function, as it's related to the - bi-directional communication mechanism. - -.. note:: - **About the _object attribute** of the PyPoint. As the C++ object life span - (``Point``) is linked to the Python (``PyPoint``) one, we may have used a - value instead of a pointer. It is best to keep a pointer as the macros - written for ``DBo`` derived classes will remain usables. - - -.. code:: c++ - - #ifndef ISOBAR_PY_POINT_H - #define ISOBAR_PY_POINT_H - - #include "hurricane/isobar/PyHurricane.h" - #include "hurricane/Point.h" - - namespace Isobar { - extern "C" { - - typedef struct { - PyObject_HEAD - Hurricane::Point* _object; - } PyPoint; - - extern PyTypeObject PyTypePoint; - extern PyMethodDef PyPoint_Methods[]; - extern void PyPoint_LinkPyType(); - - #define IsPyPoint(v) ( (v)->ob_type == &PyTypePoint ) - #define PYPOINT(v) ( (PyPoint*)(v) ) - #define PYPOINT_O(v) ( PYPOINT(v)->_object ) - - } // extern "C". - } // Isobar namespace. - - #endif // ISOBAR_PY_POINT_H - -|newpage| - - -5.2 Class File -~~~~~~~~~~~~~~~~ - -Changes from `3.2 Class Associated File`_: - -* As there is no ``PyPoint_Link()`` function, there is no call to any - flavor of the ``DBoLinkcreatemethod()`` macro (obvious as it's *not* - a ``DBo``). - -* To use the standard Python constructor, we have to define ``PyPoint_NEW()`` - and ``PyPoint_Init()`` functions, I'm not absolutely certain that the later - needs to be defined (that part is still not clear to me from the Python doc). - -* As it's not a ``DBo`` there is no ``destroy()`` method, so no call to - ``DirectDestroyMethod()`` - -* Lastly, as this object has a ``PyPoint_NEW()`` (field ``tp_new``) and - a ``PyPoint_Init()`` (field ``tp_init``) we have to use the macro - ``PyTypeObjectLinkPyTypeNewInit()`` to define ``PyPoint_LinkPyType()``. - - -.. code:: c++ - - #include "hurricane/isobar/PyPoint.h" - - namespace Isobar { - using namespace Hurricane; - - extern "C" { - - #define METHOD_HEAD(function) GENERIC_METHOD_HEAD(Point,point,function) - - #if defined(__PYTHON_MODULE__) - - static PyObject* PyPoint_NEW ( PyObject* module, PyObject *args ) - { - Point* point = NULL; - HTRY - PyObject* arg0 = NULL; - PyObject* arg1 = NULL; - - __cs.init( "Point.Point" ); - if (not PyArg_ParseTuple( args,"|O&O&:Point.Point" - , Converter,&arg0 - , Converter,&arg1 )) { - PyErr_SetString ( ConstructorError - , "invalid number of parameters for Point constructor." ); - return NULL; - } - - if (__cs.getObjectIds() == "") - { point = new Point()); } - else if (__cs.getObjectIds() == ":point") - { point = new Point( *PYPOINT_O(arg0) ); } - else if (__cs.getObjectIds() == ":int:int") - { point = new Point( PyAny_AsLong(arg0), PyAny_AsLong(arg1) ); } - else { - PyErr_SetString ( ConstructorError - , "invalid number of parameters for Point constructor." ); - return NULL; - } - - PyPoint* pyPoint = PyObject_NEW( PyPoint, &PyTypePoint ); - if (pyPoint == NULL) { delete point; return NULL; } - pyPoint->_object = point; - HCATCH - - return (PyObject*)pyPoint; - } - - static int PyPoint_Init ( PyPoint* self, PyObject* args, PyObject* kwargs ) - { return 0; } - - DirectGetLongAttribute(PyPoint_getX,getX,PyPoint,Point) - DirectGetLongAttribute(PyPoint_getY,getY,PyPoint,Point) - DirectSetLongAttribute(PyPoint_SetX,setX,PyPoint,Point) - DirectSetLongAttribute(PyPoint_SetY,setY,PyPoint,Point) - - PyMethodDef PyPoint_Methods[] = - { { "getX" , (PyCFunction)PyPoint_getX , METH_NOARGS - , "Return the Point X value." } - , { "getY" , (PyCFunction)PyPoint_getY , METH_NOARGS - , "Return the Point Y value." } - , { "setX" , (PyCFunction)PyPoint_SetX , METH_VARARGS - , "Modify the Point X value." } - , { "setY" , (PyCFunction)PyPoint_SetY , METH_VARARGS - , "Modify the Point Y value." } - , {NULL, NULL, 0, NULL} /* sentinel */ - }; - - DirectDeleteMethod(PyPoint_DeAlloc,PyPoint) - PyTypeObjectLinkPyTypeNewInit(Point) - - #else // Python Module Code Part. - - PyTypeObjectDefinitions(Point) - - #endif // Shared Library Code Part. - - } // extern "C". - } // Isobar namespace. - - -5.2 Class File -~~~~~~~~~~~~~~~~ - -To put it bluntly, there is no difference in the Python module for -a standalone ``DBo`` class and a non-``DBo`` class. - - -6. Encapsulating DbU -====================== - -While ``Hurricane::DbU`` is a class, the ``Hurricane::DbU::Unit`` is only -a ``typedef`` over ``uint64_t``. The ``DbU`` class only provides a set of -static methods to manipulate and convert to and from other units. -At Python level, ``DbU::Unit`` will be stored in plain ``long long``. - -When a ``DbU::Unit`` argument is expected in a Python functions, just use -the ``DbU::Unit PyAny_AsLong( PyObject* )`` function to convert it. - -For example, if we explicit the expension of: - -.. code:: c++ - - DirectSetLongAttribute(PyPoint_SetX,setX,PyPoint,Point) - -|newpage| - -We would get: - -.. code:: c++ - - static PyObject* PyPoint_setX ( PyPoint *self, PyObject* args ) - { - Point* cobject = static_cast( self->_object ); - if (cobject == NULL) { - PyErr_SetString( ProxyError - , "Attempt to call Point.setX() on an unbound Hurricane object" ); - return NULL; - } - - HTRY - PyObject* arg0 = NULL; - if (not PyArg_ParseTuple( args, "O:Point.setX()", &arg0 )) - return ( NULL ); - cobject->setX( Isobar::PyAny_AsLong(arg0) ); - HCATCH - Py_RETURN_NONE; - } - - -For the other way around, use ``PyObject* PyDbU_FromLong( DbU::Unit )``. - -.. code:: c++ - - DirectGetLongAttribute(PyPoint_GetX,getX,PyPoint,Point) - -We would get: - -.. code:: c++ - - static PyObject* PyPoint_GetX ( PyPoint *self, PyObject* args ) - { - Point* cobject = static_cast( self->_object ); - if (cobject == NULL) { - PyErr_SetString( ProxyError - , "Attempt to call Point.getX() on an unbound Hurricane object" ); - return NULL; - } - return Isobar::PyDbU_FromLong(cobject->getX()); - } - - -7. No C++ Hurricane::Name encapsulation -========================================== - -To be written. diff --git a/documentation/PythonCpp/index.rst b/documentation/PythonCpp/index.rst new file mode 100644 index 00000000..cb5575c2 --- /dev/null +++ b/documentation/PythonCpp/index.rst @@ -0,0 +1,23 @@ +.. -*- mode: rst; explicit-buffer-name: "index.rst" -*- + +.. include:: ../etc/definitions.rst + + +=================================== +Hurricane Python/C++ API Tutorial +=================================== + +Printable version of this document `PythonCpp.pdf <../../../pdf/main/PythonCpp.pdf>`_. + + +.. toctree:: + :maxdepth: 2 + + Introduction.rst + Configuration.rst + DBoStandalone.rst + DBoHierarchy.rst + NonDBo.rst + DbU.rst + Name.rst + diff --git a/documentation/PythonCpp/pdfHeader.rst b/documentation/PythonCpp/pdfHeader.rst new file mode 100644 index 00000000..29cdbf2b --- /dev/null +++ b/documentation/PythonCpp/pdfHeader.rst @@ -0,0 +1,15 @@ +.. -*- Mode: rst -*- + +.. include:: ../etc/definitions.rst + + +=================================== +Hurricane Python/C++ API Tutorial +=================================== + +|pagestylefancy| + + +.. contents:: + +|newpage| diff --git a/documentation/RDS/HTML_defs.rst b/documentation/RDS/HTML_defs.rst deleted file mode 100644 index 43c7dd0a..00000000 --- a/documentation/RDS/HTML_defs.rst +++ /dev/null @@ -1,22 +0,0 @@ -.. -*- Mode: rst -*- - -.. role:: raw-html(raw) - :format: html - -.. URLs that changes between the various backends. - -.. For HTML backend - -.. Stand-alone images. -.. |RDS_VW| replace:: :raw-html:`
RDS Variable Width Rule
` -.. |RDS_LCW| replace:: :raw-html:`
RDS Left Constant Width Rule
` -.. |SegmentOrientation| replace:: :raw-html:`
Symbolic Segment Orientations
` -.. |BIGVIA_1| replace:: :raw-html:`
BIGVIA holes
` -.. |BIGVIA_2| replace:: :raw-html:`
BIGVIA holes overlap
` - -.. Direct LaTeX commands encapsulation. -.. |dotfill| replace:: :raw-html:`  ` -.. |noindent| replace:: :raw-html:`

` -.. |medskip| replace:: :raw-html:`
` -.. |newpage| replace:: :raw-html:`
` - diff --git a/documentation/RDS/LaTeX_defs.rst b/documentation/RDS/LaTeX_defs.rst deleted file mode 100644 index 37d0bbf3..00000000 --- a/documentation/RDS/LaTeX_defs.rst +++ /dev/null @@ -1,25 +0,0 @@ - -.. -*- Mode: rst -*- - -.. role:: raw-latex(raw) - :format: latex - -.. URLs that changes between the various backends. - -.. |DONE| replace:: :raw-latex:`\marginpar{\fbox{\small\ding{56}}}` - -.. For LaTeX/PDF backend. - -.. Stand-alone images. -.. |RDS_VW| replace:: :raw-latex:`\begin{center}\fbox{\includegraphics[width=.7\textwidth]{./images/RDS_VW.eps}}\end{center}` -.. |RDS_LCW| replace:: :raw-latex:`\begin{center}\fbox{\includegraphics[width=.4\textwidth]{./images/RDS_LCW.eps}}\end{center}` -.. |SegmentOrientation| replace:: :raw-latex:`\begin{center}\fbox{\includegraphics[width=.5\textwidth]{./images/SegmentOrientation.eps}}\end{center}` -.. |BIGVIA_1| replace:: :raw-latex:`\begin{center}\fbox{\includegraphics[width=.5\textwidth]{./images/bigvia-1.eps}}\end{center}` -.. |BIGVIA_2| replace:: :raw-latex:`\begin{center}\fbox{\includegraphics[width=.5\textwidth]{./images/bigvia-2.eps}}\end{center}` - -.. Direct LaTeX commands encapsulation. -.. |dotfill| replace:: :raw-latex:`\dotfill` -.. |noindent| replace:: :raw-latex:`\noindent` -.. |medskip| replace:: :raw-latex:`\medskip` -.. |newpage| replace:: :raw-latex:`\newpage` - diff --git a/documentation/RDS/RDS.html b/documentation/RDS/RDS.html deleted file mode 100644 index f93f2d4d..00000000 --- a/documentation/RDS/RDS.html +++ /dev/null @@ -1,1286 +0,0 @@ - - - - - - - - - - - - -
- - --- - - - - - - - - - -
Date:26, september 2014
Authors:Jean-Paul Chaput
Contact:<alliance-users@soc.lip6.fr>
Version:0.2
- - - - - - - - - - -


-

Disclaimer: This document is still far from complete.

-


-
-

Symbolic to Real Conversion In Alliance

- -


-


-
-

Symbolic Layout

-
-

Symbolic Components

-

A symbolic layout is, in practice, made of only of three objects:

- ----- - - - - - - - - - - - - - - - - - - - - -
ObjectmbkExplanation
SegmentsphsegOriented segments with a width and an orientation.
VIAs & contactsphviaBoils down to just a point.
Big VIAs & Big ContactsphviaPoint with a width and a height -That is a rectangle of width by height centered -on the VIA coordinates.
-

Each of thoses objects is associated to a symbolic layer which will -control how the object is translated in many real rectangles.

- ------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
mbkLayer NameUsable ByUsage
phsegNWELLSegmentN Well
PWELLSegmentP Well
NDIFSegmentN Diffusion
PDIFSegmentP Diffusion
NTIESegmentN Tie
PTIESegmentP Tie
NTRANSSegmentN transistor, in Alliance, a transistor -is represented as a segment (it's grid).
PTRANSSegmentP transistor
POLYSegmentPolysilicium
ALUxSegmentMetal level x
CALUxSegmentMetal level x, that can be used by the -upper hierarchical level as a connector. -From the layout point of view it is the -same as ALUx.
TALUxSegmentBlockage for metal level x. Will -diseappear in the real layout as it is an -information for the P&R tools only.
phviaCONT_BODY_NVIA, BIGVIAContact to N Well
CONT_BODY_PVIA, BIGVIAContact to P Well
CONT_DIF_NVIA, BIGVIAContact to N Diffusion
CONT_DIF_PVIA, BIGVIAContact to P Diffusion
CONT_POLYVIA, BIGVIAContact to polysilicium
CONT_VIAVIA, BIGVIAContact between metal1 and metal2
CONT_VIAxVIA, BIGVIAContact between metal x and metal x+1. -The index is the the one of the bottom -metal of the VIA.
C_X_NVIAN transistor corner, to build transistor -bend. Not used anymore in recent technos
C_X_PVIAP transistor corner, to build transistor -bend. Not used anymore in recent technos
-
-

Note

-

Not all association of object and symbolic layers are meaningful. -For instance you cannot associate a contact to a NTRANS layer.

-
-
-

Note

-

The symbolic layer associated with blockages is prefixed by a T, -for transparency, which may seems silly. It is for historical reasons, -it started as a true transparency, but at some point we had to invert -the meaning (blockage) with the rise of over-the-cell routing, but the -name stuck...

-
-
-
-

Symbolic Segments

-

In Alliance, segments are oriented (up, down, left, right). This disambiguate -the left or right side when using the LCW and RCW rules in the rds file. -It allows to generate, if needed, asymetric object in the real layout file.

-

Symbolic Segment Orientations

-
-
-
-

The RDS File

-

The RDS file control how a symbolic layout is transformed into it's real -conterpart.

-
-

Note

-

Unit used inside the RDS file: all units are expressed in micrometers.

-
-

Alliance tools relying on the RDS file, and what layers are active for them:

- ----- - - - - - - - - - - - - - - - - - - - - - - - - -
ToolNameRDS Flags
Layout editorgraalALL
Design Rule CheckerdrucALL, DRC
Electrical extractorcougarALL, EXT
The symbolic to real layout translators2rALL
-
-

Physical Grid & Lambda Value

-

RDS file:

-
-DEFINE  PHYSICAL_GRID  0.005
-DEFINE  LAMBDA         0.09
-
-

Tells that the physical grid (founder grid) step is 0.005µm and the lambda has -a value of 0.09µm. That is, one lambda is 18 grid steps.

-

We can distinguish two kind of rds files:

-
    -
  • The 1µm kind, odd segment widths and coordinates are allowed, but the LAMBDA -value must represent an even number of foundry grid step.
  • -
  • The 2µm kind, segments widths and coordinates must all be even. And in that case -the LAMBDA value can be any multiple of the foundry grid.
  • -
-
-
-

The MBK_TO_RDS_SEGMENT table

-

The MBK_TO_RDS_SEGMENT table control the way segments are translated into -real rectangles. Be aware that we are translating segments and not rectangles. -Segments are defined by their axis (source & target points) and their width. -The geometrical transformations are described according to that model. -Obviously, they are either horizontal or vertical.

-

The translation method of a symbolic segment is as follow:

-
    -
  1. The segment is translated into one or more physical rectangles. -The generated rectangles depends on the tool which is actually -using rds and the flag for the considered real layer. -For instance, real layers flagged with DRC will be generated -for s2r (for the cif or gds) and druc, but will not -be shown under graal.

    -
  2. -
  3. Translation into one real layer. First the source & target coordinates and width -of the symbolic segment are multiplied by the LAMBDA value to obtain a real -segment. Then one of the VW, LCW or RCW transformation is applied to -that segment to get the final real rectangle.

    -
      -
    • VW for Variable Width, expand the real layer staying centered from the -original one. In those rules, the third number is not used, it is only here -to make the life easier for the parser...

      -

      RDS Variable Width Rule

      -
    • -
    • LCW or RCW for Left/Right Constant Width, create an off-center rectangle -of fixed width relatively to the real segment. Note that the SP number -is the distance between the edge of the real segment and the edge of the -generated real rectangle (not from the axis). It is often zero.

      -

      RDS Left Constant Width Rule

      -
    • -
    -
  4. -
-


-

Examples:

-
-TABLE MBK_TO_RDS_SEGMENT
-
-    # (Case 1)
-    ALU1       RDS_ALU1   VW  0.18  0.09  0.0  ALL
-
-    # (Case 2)
-    NDIF       RDS_NDIF   VW  0.18  0.0   0.0  ALL \
-               RDS_ACTIV  VW  0.18  0.0   0.0  DRC \
-               RDS_NIMP   VW  0.36  0.36  0.0  DRC
-
-    # (Case 3)
-    NTRANS     RDS_POLY   VW  0.27  0.00  0.0  ALL \
-               RDS_GATE   VW  0.27  0.00  0.0  DRC \
-               RDS_NDIF  LCW  0.0   0.27  0.0  EXT \
-               RDS_NDIF  RCW  0.0   0.27  0.0  EXT \
-               RDS_NDIF   VW  0.0   0.72  0.0  DRC \
-               RDS_ACTIV  VW  0.0   0.72  0.0  ALL \
-               RDS_NIMP   VW  0.18  1.26  0.0  DRC
-
-END
-
-

Case 1 the ALU1 is translated in exacltly one real rectangle of -RDS_ALU1, both ends are extended by 0.18µm and it's width is increased -by 0.09µm.

-

Case 2 the NDIF will be translated into only one segment -under graal, for symbolic visualization. And into three real rectangles -for s2r and druc.

-

Case 3 the NTRANS, associated to a transistor is a little bit -more complex, the generated shapes are different for the extractor cougar -in one hand, and for both druc & s2r in the other hand.

-
    -
  • For the extractor (EXT & ALL flags) there will be four rectangles -generateds:

    -
      -
    1. The gate (RDS_GATE)
    2. -
    3. The left diffusion of the transistor (source or drain) (RDS_NDIF).
    4. -
    5. The right diffusion of the transistor (drain or source) (RDS_NDIF).
    6. -
    7. The active area (RDS_ACTIV).
    8. -
    -

    As the extractor must kept separate the source and the drain of the transistor, -they are generated as two offset rectangles, using the LCW and RCW directives.

    -
  • -
  • For s2r and druc (DRC and ALL), five rectangles are generateds:

    -
      -
    1. The poly (RDS_POLY).
    2. -
    3. The gate (RDS_GATE).
    4. -
    5. The diffusion, as one rectangle that covers both the LCW and the RCW (RDS_NDIF).
    6. -
    7. The active area (RDS_ACTIV).
    8. -
    9. The N implantation (RDS_NIMP).
    10. -
    -

    In the layout send to the foundry, the source & drain are draw as one rectangle -across the gate area (the transistor being defined by the intersection of both -rectangles).

    -
  • -
-


-
-
-

The MBK_TO_RDS_VIA table

-

This table is to translate default VIAs into real via. In the symbolic layout -the default VIA is simply a point and a set of layers. All layers are converted -in squares shapes centered on the VIA coordinate. The one dimension given is the -size of the side of that square.

-

Note that although we are refering to VIAs, which for the purists are between two -metal layers, this table also describe contacts.

-

Example:

-
-TABLE MBK_TO_RDS_VIA
-
-    CONT_DIF_P RDS_PDIF  0.54 ALL \
-               RDS_CONT  0.18 ALL \
-               RDS_ALU1  0.36 ALL \
-               RDS_ACTIV 0.54 DRC \
-               RDS_PIMP  0.90 DRC
-
-    CONT_POLY  RDS_POLY  0.54 ALL \
-               RDS_CONT  0.18 ALL \
-               RDS_ALU1  0.36 ALL
-
-    CONT_VIA   RDS_ALU1  0.45 ALL \
-               RDS_VIA1  0.27 ALL \
-               RDS_ALU2  0.45 ALL
-
-END
-
-
-

Note

-

In CONT_DIF_P you may see that only three layers will be shown under -graal, but five will be generated in the gds layout.

-
-
-
-

The MBK_TO_RDS_BIGVIA_HOLE table

-

In s2r, when generating BIGVIAs, the matrix of holes they contains is -not draw relative to the position of the BIGVIA itself, but on a grid which -is common througout all the design real layout. This is to allow overlap -between two BIGVIA without risking the holes matrix to be not exactly overlapping. -As a consequence, when visualizing the gds file, the holes may not be centerend -inside one individual BIGVIA.

-

The MBK_TO_RDS_BIGVIA_HOLE table define the global hole matrix for the whole -design. The first number is the individual hole side and the second the grid step -(edge to edge). The figure below show the hole generation.

-

BIGVIA holes

-

Example of BIGVIA overlap:

-

BIGVIA holes overlap

-

Example:

-
-TABLE MBK_TO_RDS_BIGVIA_HOLE
-
-    CONT_VIA   RDS_VIA1 0.27 0.27 ALL
-    CONT_VIA2  RDS_VIA2 0.27 0.27 ALL
-    CONT_VIA3  RDS_VIA3 0.27 0.27 ALL
-    CONT_VIA4  RDS_VIA4 0.27 0.27 ALL
-    CONT_VIA5  RDS_VIA5 0.36 0.36 ALL
-
-END
-
-
-

Note

-

BIGVIA demotion. If the size of the bigvia is too small, there is -a possibility that no hole from the global matrix will be under it. -To avoid that case, if the either side of the BIGVIA is less than -1.5 * step, the BIGVIA is demoted to a simple VIA.

-
-


-
-
-

The MBK_TO_RDS_BIGVIA_METAL table

-

This table describe how the metal part of a BIGVIA is expanded (for the hole -part, see the previous table MBK_TO_RDS_BIGVIA_HOLE). The rule give for each -metal:

-
    -
  1. The delta-with (have to ask Franck).
  2. -
  3. The overhang, the length the real rectangle is expanded on each side from -the symbolic rectange.
  4. -
-

Example:

-
-TABLE MBK_TO_RDS_BIGVIA_METAL
-
-    CONT_VIA  RDS_ALU1 0.0 0.09  ALL \
-              RDS_ALU2 0.0 0.09  ALL
-
-    CONT_VIA2 RDS_ALU2 0.0 0.09  ALL \
-              RDS_ALU3 0.0 0.09  ALL
-
-    CONT_VIA3 RDS_ALU3 0.0 0.09  ALL \
-              RDS_ALU4 0.0 0.09  ALL
-
-    CONT_VIA4 RDS_ALU4 0.0 0.09  ALL \
-              RDS_ALU5 0.0 0.09  ALL
-
-    CONT_VIA5 RDS_ALU5 0.0 0.09  ALL \
-              RDS_ALU6 0.0 0.18  ALL
-
-END
-
-


-
-
-

The MBK_WIRESETTING table

-

From a strict standpoint this table shouldn't be here but put in a separate -configuration file, because it contains informations only used by the symbolic -layout tools (ocp, nero, ring).

-

This table defines the cell gauge the routing pitch and minimal (symbolic) -wire width and minimal spacing for the routers. They are patly redundant.

-

Example:

-
-TABLE MBK_WIRESETTING
-
-    X_GRID             10
-    Y_GRID             10
-    Y_SLICE           100
-    WIDTH_VDD          12
-    WIDTH_VSS          12
-    TRACK_WIDTH_ALU8    0
-    TRACK_WIDTH_ALU7    4
-    TRACK_WIDTH_ALU6    4
-    TRACK_WIDTH_ALU5    4
-    TRACK_WIDTH_ALU4    3
-    TRACK_WIDTH_ALU3    3
-    TRACK_WIDTH_ALU2    3
-    TRACK_WIDTH_ALU1    3
-    TRACK_SPACING_ALU8  0
-    TRACK_SPACING_ALU7  4
-    TRACK_SPACING_ALU6  4
-    TRACK_SPACING_ALU5  4
-    TRACK_SPACING_ALU4  4
-    TRACK_SPACING_ALU3  4
-    TRACK_SPACING_ALU2  4
-    TRACK_SPACING_ALU1  3
-
-END
-
-
-
-
-
- - diff --git a/documentation/RDS/RDS_HTML.rst b/documentation/RDS/RDS_HTML.rst deleted file mode 100644 index c16f2565..00000000 --- a/documentation/RDS/RDS_HTML.rst +++ /dev/null @@ -1,5 +0,0 @@ - -.. -*- Mode: rst -*- - -.. include:: HTML_defs.rst -.. include:: RDS.rst diff --git a/documentation/RDS/RDS_LaTeX.rst b/documentation/RDS/RDS_LaTeX.rst deleted file mode 100644 index 87ae6c88..00000000 --- a/documentation/RDS/RDS_LaTeX.rst +++ /dev/null @@ -1,4 +0,0 @@ -.. -*- Mode: rst -*- - -.. include:: LaTeX_defs.rst -.. include:: RDS.rst diff --git a/documentation/RDS/RDS.rst b/documentation/RDS/RDSpage.rst similarity index 93% rename from documentation/RDS/RDS.rst rename to documentation/RDS/RDSpage.rst index ab352843..be3aa644 100644 --- a/documentation/RDS/RDS.rst +++ b/documentation/RDS/RDSpage.rst @@ -1,18 +1,7 @@ .. -*- Mode: rst -*- -.. role:: ul -.. role:: cb -.. role:: sc -.. role:: fboxtt +.. include:: ../etc/definitions.rst -.. Acronyms & names. -.. |GNU| replace:: :sc:`gnu` -.. |LGPL| replace:: :sc:`lgpl` -.. |GPL| replace:: :sc:`gpl` -.. |UPMC| replace:: :sc:`upmc` -.. |Alliance| replace:: :sc:`Alliance` -.. |MBK| replace:: :sc:`mbk` -.. |RDS| replace:: :sc:`rds` .. Tools .. |ocp| replace:: ``ocp`` @@ -48,7 +37,6 @@ .. |PTIE| replace:: ``PTIE`` .. |NDIF| replace:: ``NDIF`` .. |PDIF| replace:: ``PDIF`` -.. |NWELL| replace:: ``NWELL`` .. |PWELL| replace:: ``PWELL`` .. |NTRANS| replace:: ``NTRANS`` .. |PTRANS| replace:: ``PTRANS`` @@ -68,26 +56,33 @@ .. |RDS_POLY| replace:: ``RDS_POLY`` .. |RDS_ALU1| replace:: ``RDS_ALU1`` +.. Stand-alone images. +.. |RDS_VW| image:: ./images/RDS_VW.png + :alt: RDS Variable Width Rule + :align: middle + :width: 60% -:Date: 26, september 2014 -:Authors: Jean-Paul Chaput -:Contact: -:Version: 0.2 +.. |RDS_LCW| image:: ./images/RDS_LCW.png + :alt: RDS Left Constant Width Rule + :align: middle + :width: 40% -|medskip| +.. |SegmentOrientation| image:: ./images/SegmentOrientation.png + :alt: Symbolic Segment Orientations + :align: middle + :width: 50% -**Disclaimer:** This document is still far from complete. +.. |BIGVIA_1| image:: ./images/bigvia-1.png + :alt: BIGVIA holes + :align: middle + :width: 40% -|medskip| - -========================================= -Symbolic to Real Conversion In Alliance -========================================= +.. |BIGVIA_2| image:: ./images/bigvia-2.png + :alt: BIGVIA holes overlap + :align: middle + :width: 40% -.. contents:: - -|medskip| |newpage| @@ -189,7 +184,7 @@ In |Alliance|, segments are oriented (up, down, left, right). This disambiguate the left or right side when using the ``LCW`` and ``RCW`` rules in the |RDS| file. It allows to generate, if needed, asymetric object in the real layout file. -|SegmentOrientation| +|bcenter| |SegmentOrientation| |ecenter| |newpage| @@ -261,14 +256,14 @@ The translation method of a symbolic segment is as follow: original one. In those rules, the third number is not used, it is only here to make the life easier for the parser... - |RDS_VW| + |bcenter| |RDS_VW| |ecenter| * |LCW| or |RCW| for Left/Right Constant Width, create an off-center rectangle of fixed width relatively to the real segment. Note that the ``SP`` number is the distance *between the edge* of the real segment and the edge of the generated real rectangle (*not* from the axis). It is often zero. - |RDS_LCW| + |bcenter| |RDS_LCW| |ecenter| |newpage| @@ -383,11 +378,11 @@ The |MBK_TO_RDS_BIGVIA_HOLE| table define the global hole matrix for the whole design. The first number is the individual hole side and the second the grid step (edge to edge). The figure below show the hole generation. -|BIGVIA_1| +|bcenter| |BIGVIA_1| |ecenter| Example of BIGVIA overlap: -|BIGVIA_2| +|bcenter| |BIGVIA_2| |ecenter| Example: :: @@ -407,8 +402,6 @@ Example: :: ``1.5 * step``, the BIGVIA is demoted to a simple VIA. -|newpage| - The |MBK_TO_RDS_BIGVIA_METAL| table ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -438,12 +431,9 @@ Example: :: CONT_VIA5 RDS_ALU5 0.0 0.09 ALL \ RDS_ALU6 0.0 0.18 ALL - END -|newpage| - The |MBK_WIRESETTING| table ~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/documentation/RDS/SoC.css b/documentation/RDS/SoC.css deleted file mode 100644 index 3744b6b4..00000000 --- a/documentation/RDS/SoC.css +++ /dev/null @@ -1,750 +0,0 @@ - -html, body, th, td, tr, p, li, h1, h2, h3, h4, h5, h6 { - font-size: 96%; - font-family: "Open Sans", verdana, sans-serif; -} - -p, li { - text-align: justify; -} - -.sc { - font-variant: small-caps; - font-size: 120%; -} - -h1, h2, h3, h4, h5, h6 { - font-family: "Open Sans", verdana, sans-serif; -} - -h1 { text-align: center; - border-top: 2px solid #09550b; - border-bottom: 2px solid #09550b; - padding-top: 7pt; - padding-bottom: 7pt; - } -h2, h3, h4, h5, h6 { text-align: left; } -h1, h2, h3 { font-family: "Open Sans"; - } -h1 { font-weight: normal; font-size: 170%; padding-top: 7pt; margin-top: 25pt; } -h2 { font-weight: normal; font-size: 140%; padding-top: 7pt; margin-top: 25pt; } -h3 { font-weight: bold; font-size: 118%; padding-top: 7pt; margin-top: 25pt; } -h4 { font-weight: bold; font-size: 100%; } -h5 { font-style: italic; font-size: 100%; } -h6 { font-variant: small-caps; font-size: 100%; } - -body { - color: black; - background: white; - /* - background: #09550B; - background-color: white; - */ - background-position: top left; - background-attachment: fixed; - background-repeat: no-repeat; - margin: 0 0 0 0; - padding: 20pt; - width: 550pt; - margin-right: auto; - margin-left: auto; - margin-top: 20pt; - margin-bottom: 20pt; - -moz-box-shadow: 4px 4px 5px 3px #ccc; - -webkit-box-shadow: 4px 4px 5px 3px #ccc; - box-shadow: 4px 4px 5px 3px #ccc; -} - -hr { - color: #09550b; - border: 1px dotted #09550b; - border-style: none none dotted; - padding-top: 10pt; - padding-bottom: 10pt; -} - -div#contents { - margin: 30pt; - padding: 2pt 10pt; - background-color: #fff676; - -moz-box-shadow: 4px 4px 5px 2px #ccc; - -webkit-box-shadow: 4px 4px 5px 2px #ccc; - box-shadow: 4px 4px 5px 2px #ccc; - -/* Shadow explanation: - * The shadow is a rectangle the same size as the box. It is then shifted - * blurred according to the following parameters. - * - * 1. The horizontal offset of the shadow, positive means the shadow will be - * on the right of the box, a negative offset will put the shadow on the - * left of the box. - * 2. The vertical offset of the shadow, a negative one means the box-shadow - * will be above the box, a positive one means the shadow will be below - * the box. - * 3. The blur radius (optional), if set to 0 the shadow will be sharp, - * the higher the number, the more blurred it will be. - * 4. The spread radius (optional), positive values increase the size of the - * shadow, negative values decrease the size. Default is 0 (the shadow is - * same size as blur). - * 5. Color - */ -} - - -div#centered { - margin-left: auto; - margin-right: auto; - text-align: center; -} - -pre, tt, code { - font-family: "courrier", "andale mono", monospace; - font-size: 100%; - white-space: pre; -} - -tt { - color: #09550b; -} - -pre.wiki, div.code, pre.literal-block { - font-size: 90%; - padding: 5pt; - margin-left: 4%; - margin-right: 4%; - border: dashed; - border-width: thin; - border-color: #FC8676; - background-color: #FCFCE1; -} - -a:link, a:active { - font-weight: normal; - text-decoration: none; - color: #09550b; - border-bottom: 1px dotted #09550b; -} - -a:hover, a:focus, a:visited { - font-weight: normal; - font-style: italic; - text-decoration: none; - /* - color: #A40010; - border-bottom: 1px dotted #A40010; - */ - color: #09550b; - border-bottom: 1px dotted #09550b; -} - -h1 a:link { - border-bottom: 0px; -} - -p.credit { - margin-left: 10%; - margin-right: 10%; - font-size: 110%; -} - -p.credit span.left { - float: left; - white-space: nowrap; -} - -p.credit span.right { - float: right; - white-space: nowrap; -} - -img.addborder { - border: 1px solid black; -} - -div#header { - margin: 0px; - padding: 0pt; - background-color: white; - display: inline-block; - width: 100%; -} - -div#header_logo { - margin: 0px; - padding: 10px 0px 10px 12pt; - background-color: white; - width: 40%; - float: left; -} - -div#header_menus { - background-color: white; - width: 55%; - float: right; - padding-top: 60pt; - padding-right: 10pt; - text-align: right; - font-size: 80%; -} - -div#header_menus ul { - padding-top: 45pt; - list-style: none; - text-align: right; - font-size: 80%; -} - -div#header_menus li { - padding: 0pt; - margin: 0pt; - display: inline; - white-space: nowrap; -} - -/* -div#header_menus a { - border-left: 1px solid #d7d7d7; - padding: 0 .75em; -} - -div#header_menus a.first { - border-left: none; -} -*/ - -div#header a:link, div#header a:active, div#header a:visited { - margin: 0pt; - padding: 0pt 5pt; - font-weight: normal; - color: black; - text-decoration: none; - border-bottom: 1px solid black; - border-left: 0px; - border-right: 0px; -} - -div#header a:hover, div#header a:focus { - margin: 0pt; - padding: 0pt 5pt; - font-weight: normal; - color: black; - text-decoration: none; - border-bottom: 4px solid #09550b; - border-left: 0px; - border-right: 0px; -} - -div#header a.current:link, div#header a.current:active, div#header a.current:visited { - margin: 0pt; - padding: 0pt 5pt; - font-weight: bold; - font-style: normal; - font-size: 120%; - color: white; - text-decoration: none; - border-bottom: 4px solid #09550b; - border-left: 0px; - border-right: 0px; - background-color: #09550b; -} - -div#header a.current:hover, div#header a.current:focus { - margin: 0pt; - padding: 0pt 5pt; - font-weight: bold; - font-style: normal; - font-size: 120%; - color: white; - text-decoration: none; - border-bottom: 4px solid #09550b; - border-left: 0px; - border-right: 0px; - background-color: #09550b; -} - -div#header_ancestors { - padding: 4px 0px 4px 12pt; - background-color: #09550B; - color: white; -} - -div#header_ancestors ul, div#header_ancestors * li { - display: inline; - list-style-type: none; - padding: 0px 0px 0px 0pt; -} - -div#header_ancestors a:link, div#header_ancestors a:active, div#header_ancestors a:visited { - font-weight: bold; - color: white; - text-decoration: none; - border-bottom: 0px; -} - -div#header_ancestors a:hover, div#header_ancestors a:focus { - font-weight: bold; - color: white; - text-decoration: underline; -} - -div#footer { - margin: 0px; - padding: 0px; - border-top: 1px dotted #09550b; - background-color: white; - display: inline-block; - width: 100%; - text-align: right; -} - -div#searchform { - width: 80%; - background-color: #ccffcd; - padding: 15pt 10pt 15pt 10pt; - margin-top: 50pt; - margin-bottom: 50pt; - margin-left: auto; - margin-right: auto; - text-align: center; -} - -div#searchform input#id_q { - background-color: white; - border: 1px solid #09550b; - padding: 2pt; - width: 80%; - font-size: 110%; - font-weight: bold; -} - -span.queryref { - font-weight: bold; -} - -div#searchform ul { - list-style: none; -} - -div#searchform li { - display: inline; -} - -hr#search_vs_results { - color: #09550b; - border: 2px dotted #09550b; - border-style: none none dotted; - margin-top: 0pt; - margin-bottom: 20pt; -} - -div#search_results { - width: 85%; - margin: auto; -} - -div#sidebar hr#separator { - color: white; - border: 0px; - margin-top: 0pt; - margin-bottom: 20pt; -} - -img.footer-logo { - height: 24px; - padding: 0px 2px; -} - -hr#site_vs_page { - color: white; - border: 3px dotted white; - border-style: none none dotted; - margin-top: 20pt; - margin-bottom: 20pt; -} - -div#sidebar { - /* - background: #09550B; - background: #ccffcd; - */ - background: white; -} - -div#sidebar div#sitemenu, div#sidebar div#pagemenu { - /* - background: white; - */ - background: #09550b; - width: 85%; - margin: auto; - padding: 5pt 10pt; -} - -div#sidebar * li { - text-align: left; -} - -div#sidebar * ul { - list-style-type: square; - padding-left: 12pt; -} - -div#sitemenu ul { - list-style-type: none; - padding-left: 0pt; -} - -div#sitemenu ul ul { - list-style-type: none; - padding-left: 0pt; -} - -div#sitemenu ul ul ul { - list-style-type: square; - padding-left: 12pt; -} - -div#sitemenu ul li ul li { - padding-top: 3pt; - padding-bottom: 5pt; - border-top: 1px dotted white; -} - -div#sitemenu ul li ul li ul li { - border-top: none; - padding-top: 1pt; - padding-bottom: 1pt; -} - -div#sitemenu ul li a:link, -div#sitemenu ul li a:active, -div#sitemenu ul lu a:visited -{ - font-size: 140%; - font-weight: bold; - border-bottom: none; -} - -div#sitemenu ul li a:focus, -div#sitemenu ul lu a:hover -{ - font-size: 140%; - font-weight: bold; - font-style: italic; - border-bottom: none; -} - -div#sitemenu ul ul li a:link, -div#sitemenu ul ul li a:active, -div#sitemenu ul ul lu a:visited, -div#sitemenu ul ul li a:focus, -div#sitemenu ul ul lu a:hover -{ - font-size: 90%; - font-weight: normal; - border-bottom: none; -/*border-bottom: 1px dotted white;*/ -} - -div#pagemenu ul { - list-style-type: none; - padding-left: 0pt; -} - -div#pagemenu ul ul { - list-style-type: none; - padding-left: 0pt; -} - -div#pagemenu ul ul ul { - padding-left: 12pt; -} - -div#pagemenu ul li ul li { - padding-top: 3pt; - padding-bottom: 5pt; - border-top: 1px dotted white; -} - -div#pagemenu ul li ul li ul li { - border-top: none; - padding-top: 1pt; - padding-bottom: 1pt; -} - -div#pagemenu ul li a:link, -div#pagemenu ul li a:active, -div#pagemenu ul lu a:visited -{ - font-size: 120%; - font-weight: bold; - border-bottom: none; -} - -div#pagemenu ul li a:focus, -div#pagemenu ul lu a:hover -{ - font-size: 120%; - font-weight: bold; - font-style: italic; - border-bottom: none; -} - -div#pagemenu ul ul li a:link, -div#pagemenu ul ul li a:active, -div#pagemenu ul ul lu a:visited, -div#pagemenu ul ul li a:focus, -div#pagemenu ul ul lu a:hover -{ - font-size: 90%; - font-weight: normal; - border-bottom: none; - /* - border-bottom: 1px dotted white; - */ -} - - -div#sidebar ul.ancestor * li { - padding-top: 0pt; -} - -div#sidebar ul { - padding-bottom: 8pt; -} - -div#sidebar a:link, div#sidebar a:active, div#sidebar a:visited { - /* - font-weight: normal; - */ - color: white; - text-align: left; - text-decoration: none; - border-bottom: 1px dotted white; -} - -div#sidebar a:hover, div#sidebar a:focus { - /* - font-weight: normal; - */ - color: white; - text-align: left; - text-decoration: none; - border-bottom: 1px dotted white; -} - -div#main { - border-left: 1px solid #09550b; -} - -div#main ul#summary { - list-style-type: square; - padding-left: 12pt; - font-size: 14pt; -} - -div#main ul#summary * ul { - padding-left: 12pt; - padding-bottom: 14pt; - font-size: 95%; -} - -div.code * { - background-color: #FCFCE1; -} - -div.note { - margin: 8px 2% 0px 2%; - border: 1px none #fff01c; - border-left-width: 4px; - border-left-style: solid; - padding: 1px 10pt 1px 55px; - background: #fff676 url('./images/clipboard.png') no-repeat 0% 50%;; - font-size: 90% -} - -div.error { - margin: 8px 2% 0px 2%; - border: 1px none #dd0000; - border-left-width: 4px; - border-left-style: solid; - padding: 1px 10pt 1px 55px; - background: #ffddcc url('./images/i-core.png') no-repeat 0% 50%;; - font-size: 90% -} - -p.admonition-title { - font-weight: bold; -} - -div.topic { - margin: 5pt; - padding: 2pt 10pt; - background-color: fff676; -} - -div.topic p.first { - font-weight: bold; -} - -table.wiki th, table th { - color: black; - background: #FFFFCC; -} - -table.docutils { - margin-left: 10%; - margin-right: 10%; -} - -table.wiki, table.wiki th, table.wiki td { border: 1px solid black; } -table.wiki th * p { text-align: center; } -table.wiki * p { margin: 0pt; } -table.wiki * blockquote { margin: 0pt; } -table { border-collapse: collapse; } -table th, table td { border: 1px solid black; - padding: 2px 10px 2px 10px; } - -table.docinfo { - margin-top: 10pt; - margin-left: auto; - margin-right: 0pt; - border: 10px solid #303030; - border-collapse: collapse; - background: #303030; - font-size: 90%; - font-family: sans-serif; -} - -table.docinfo tr { - border-bottom: 1px dotted white; -} - -th.docinfo-name, -table.docinfo td, -table.docinfo td a:link, -table.docinfo td a:active, -table.docinfo td a:visited, -table.docinfo td a:focus, -table.docinfo td a:hover -{ - border: 0px solid white; - background: #303030; - color: white; - text-align: left; - font-weight: bold; -} - -th.docinfo-name { - font-weight: normal; -} - -table.docinfo td { - font-weight: bold; -} - -span.ul { - text-decoration: underline; -} - -* span.smallcaps { - /*font-variant: "small-caps";*/ - text-transform: "uppercase"; - font-size: "smaller"; -} - - -span.cb { - font-family: "andale mono", monospace; - font-weight: bold; - white-space: pre; -} - -span.fboxtt { - border: 1px solid black; - padding: 0px 4px; - font-family: "andale mono", monospace; - font-weight: bold; - white-space: pre; -} - -#notice.system-message, .notice.system-message { - color: black; - background: #DDFFDD; - padding-top: 5pt; - padding-bottom: 5pt; - border: 1px none #55BB55; - border-top-width: 4px; - border-top-style: solid; -} - -#content.error .message, div.system-message { - color: #550000; - background: #ffddcc; - border: 2px none #dd0000; - border-top-width: 4px; - border-top-style: solid; - padding: .5em; - margin: 1em 0; -} - -#main { - float: right; - width: 70%; - padding: 0pt; - margin: 0pt; - min-height: 700px; - background: white; -} - -div#main h1 { - border-bottom: 2px solid #09550b; -} - -div#main div.section h1 { - border-bottom: none; -} - -#cmscontent { - padding: 0pt 4% 10pt 4%; - margin: 0pt; -} - -div#htmlerrorcontents { - padding: 10pt 4% 10pt 4%; - margin: 0pt; -} - -div#htmlerrorcontents span.cs { - font-size: 80%; - font-family: "andale mono", monospace; - white-space: pre; -} - -div#htmlerrorcontents hr.lang_separator { - border: 1px dotted black; - border-style: none none dotted; - margin-top: 20pt; - margin-bottom: 10pt; -} - -#embedcontent { - border: 0pt; - padding: 0pt; - margin: 0pt; -} - -#sidebar { - float: left; - width: 29.9%; - padding: 0 0 0 0; - margin: 0 0 0 0; - color: white; - background: #09550B; - /* - min-height: 300px; - background: #f2f2f2; - border-right: 1px solid #ccc; - padding: 0 0 0 10px; - */ -} diff --git a/documentation/RDS/images/RDS_LCW-eps-converted-to.pdf b/documentation/RDS/images/RDS_LCW-eps-converted-to.pdf deleted file mode 100644 index c78679f5..00000000 Binary files a/documentation/RDS/images/RDS_LCW-eps-converted-to.pdf and /dev/null differ diff --git a/documentation/RDS/images/RDS_LCW.eps b/documentation/RDS/images/RDS_LCW.eps deleted file mode 100644 index 78b0a9e1..00000000 --- a/documentation/RDS/images/RDS_LCW.eps +++ /dev/null @@ -1,238 +0,0 @@ -%!PS-Adobe-2.0 EPSF-2.0 -%%Title: RDS_LCW.fig -%%Creator: fig2dev Version 3.2 Patchlevel 5 -%%CreationDate: Mon Sep 15 18:23:48 2014 -%%For: jpc@lepka (Jean-Paul Chaput) -%%BoundingBox: 0 0 233 348 -%Magnification: 0.8000 -%%EndComments -/$F2psDict 200 dict def -$F2psDict begin -$F2psDict /mtrx matrix put -/col-1 {0 setgray} bind def -/col0 {0.000 0.000 0.000 srgb} bind def -/col1 {0.000 0.000 1.000 srgb} bind def -/col2 {0.000 1.000 0.000 srgb} bind def -/col3 {0.000 1.000 1.000 srgb} bind def -/col4 {1.000 0.000 0.000 srgb} bind def -/col5 {1.000 0.000 1.000 srgb} bind def -/col6 {1.000 1.000 0.000 srgb} bind def -/col7 {1.000 1.000 1.000 srgb} bind def -/col8 {0.000 0.000 0.560 srgb} bind def -/col9 {0.000 0.000 0.690 srgb} bind def -/col10 {0.000 0.000 0.820 srgb} bind def -/col11 {0.530 0.810 1.000 srgb} bind def -/col12 {0.000 0.560 0.000 srgb} bind def -/col13 {0.000 0.690 0.000 srgb} bind def -/col14 {0.000 0.820 0.000 srgb} bind def -/col15 {0.000 0.560 0.560 srgb} bind def -/col16 {0.000 0.690 0.690 srgb} bind def -/col17 {0.000 0.820 0.820 srgb} bind def -/col18 {0.560 0.000 0.000 srgb} bind def -/col19 {0.690 0.000 0.000 srgb} bind def -/col20 {0.820 0.000 0.000 srgb} bind def -/col21 {0.560 0.000 0.560 srgb} bind def -/col22 {0.690 0.000 0.690 srgb} bind def -/col23 {0.820 0.000 0.820 srgb} bind def -/col24 {0.500 0.190 0.000 srgb} bind def -/col25 {0.630 0.250 0.000 srgb} bind def -/col26 {0.750 0.380 0.000 srgb} bind def -/col27 {1.000 0.500 0.500 srgb} bind def -/col28 {1.000 0.630 0.630 srgb} bind def -/col29 {1.000 0.750 0.750 srgb} bind def -/col30 {1.000 0.880 0.880 srgb} bind def -/col31 {1.000 0.840 0.000 srgb} bind def - -end -save -newpath 0 348 moveto 0 0 lineto 233 0 lineto 233 348 lineto closepath clip newpath --114.1 389.4 translate -1 -1 scale - -/cp {closepath} bind def -/ef {eofill} bind def -/gr {grestore} bind def -/gs {gsave} bind def -/sa {save} bind def -/rs {restore} bind def -/l {lineto} bind def -/m {moveto} bind def -/rm {rmoveto} bind def -/n {newpath} bind def -/s {stroke} bind def -/sh {show} bind def -/slc {setlinecap} bind def -/slj {setlinejoin} bind def -/slw {setlinewidth} bind def -/srgb {setrgbcolor} bind def -/rot {rotate} bind def -/sc {scale} bind def -/sd {setdash} bind def -/ff {findfont} bind def -/sf {setfont} bind def -/scf {scalefont} bind def -/sw {stringwidth} bind def -/tr {translate} bind def -/tnt {dup dup currentrgbcolor - 4 -2 roll dup 1 exch sub 3 -1 roll mul add - 4 -2 roll dup 1 exch sub 3 -1 roll mul add - 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} - bind def -/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul - 4 -2 roll mul srgb} bind def -/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def -/$F2psEnd {$F2psEnteredState restore end} def - -$F2psBegin -10 setmiterlimit -0 slj 0 slc - 0.04800 0.04800 sc -% -% Fig objects follow -% -% -% here starts figure with depth 60 -% Polyline -0 slj -0 slc -15.000 slw -n 3900 5700 m 3900 2700 l 4800 2700 l 4800 5700 l - cp gs col18 0.50 tnt ef gr gs col18 s gr -% here ends figure; -% -% here starts figure with depth 55 -% Polyline -0 slj -0 slc -15.000 slw -n 5100 6600 m 5100 1800 l 6300 1800 l 6300 6600 l - cp gs col7 1.00 shd ef gr gs col0 s gr -% here ends figure; -% -% here starts figure with depth 50 -% Polyline -0 slj -0 slc -45.000 slw -n 5625 1725 m - 5775 1875 l gs col0 s gr -% Polyline -n 5625 1875 m - 5775 1725 l gs col0 s gr -% Polyline -n 5625 6525 m - 5775 6675 l gs col0 s gr -% Polyline -n 5625 6675 m - 5775 6525 l gs col0 s gr -% Polyline -15.000 slw -n 2400 900 m 5775 900 l 5775 1275 l 2400 1275 l - cp gs col0 s gr -/Courier-Bold ff 300.00 scf sf -2550 1200 m -gs 1 -1 sc (LCW) col18 sh gr -/Courier-Bold ff 300.00 scf sf -3450 1200 m -gs 1 -1 sc (dL) col18 sh gr -/Courier-Bold ff 300.00 scf sf -5250 1200 m -gs 1 -1 sc (SP) col18 sh gr -/Courier-Bold ff 300.00 scf sf -4350 1200 m -gs 1 -1 sc (W) col18 sh gr -% Polyline - [90 45 15 45] 0 sd -n 5700 1800 m - 5700 6600 l gs col0 s gr [] 0 sd -% Polyline -7.500 slw -n 3225 2700 m - 3825 2700 l gs col0 s gr -% Polyline -n 5025 1800 m - 3225 1800 l gs col0 s gr -% Polyline -n 3825 5700 m - 3225 5700 l gs col0 s gr -% Polyline -n 5025 6600 m - 3225 6600 l gs col0 s gr -% Polyline -n 3900 5775 m - 3900 7575 l gs col0 s gr -% Polyline -n 4800 5775 m - 4800 7575 l gs col0 s gr -% Polyline -n 5100 6675 m 5100 6900 l 5400 7200 l - 5400 7575 l gs col0 s gr -% Polyline -gs clippath -3270 2564 m 3270 2715 l 3330 2715 l 3330 2564 l 3330 2564 l 3300 2684 l 3270 2564 l cp -3330 1936 m 3330 1785 l 3270 1785 l 3270 1936 l 3270 1936 l 3300 1816 l 3330 1936 l cp -eoclip -n 3300 1800 m - 3300 2700 l gs col0 s gr gr - -% arrowhead -n 3330 1936 m 3300 1816 l 3270 1936 l 3330 1936 l cp gs 0.00 setgray ef gr col0 s -% arrowhead -n 3270 2564 m 3300 2684 l 3330 2564 l 3270 2564 l cp gs 0.00 setgray ef gr col0 s -% Polyline -gs clippath -3270 6464 m 3270 6615 l 3330 6615 l 3330 6464 l 3330 6464 l 3300 6584 l 3270 6464 l cp -3330 5836 m 3330 5685 l 3270 5685 l 3270 5836 l 3270 5836 l 3300 5716 l 3330 5836 l cp -eoclip -n 3300 5700 m - 3300 6600 l gs col0 s gr gr - -% arrowhead -n 3330 5836 m 3300 5716 l 3270 5836 l 3330 5836 l cp gs 0.00 setgray ef gr col0 s -% arrowhead -n 3270 6464 m 3300 6584 l 3330 6464 l 3270 6464 l cp gs 0.00 setgray ef gr col0 s -% Polyline -gs clippath -4664 7530 m 4815 7530 l 4815 7470 l 4664 7470 l 4664 7470 l 4784 7500 l 4664 7530 l cp -4036 7470 m 3885 7470 l 3885 7530 l 4036 7530 l 4036 7530 l 3916 7500 l 4036 7470 l cp -eoclip -n 3900 7500 m - 4800 7500 l gs col0 s gr gr - -% arrowhead -n 4036 7470 m 3916 7500 l 4036 7530 l 4036 7470 l cp gs 0.00 setgray ef gr col0 s -% arrowhead -n 4664 7530 m 4784 7500 l 4664 7470 l 4664 7530 l cp gs 0.00 setgray ef gr col0 s -% Polyline -gs clippath -5264 7530 m 5415 7530 l 5415 7470 l 5264 7470 l 5264 7470 l 5384 7500 l 5264 7530 l cp -4936 7470 m 4785 7470 l 4785 7530 l 4936 7530 l 4936 7530 l 4816 7500 l 4936 7470 l cp -eoclip -n 4800 7500 m - 5400 7500 l gs col0 s gr gr - -% arrowhead -n 4936 7470 m 4816 7500 l 4936 7530 l 4936 7470 l cp gs 0.00 setgray ef gr col0 s -% arrowhead -n 5264 7530 m 5384 7500 l 5264 7470 l 5264 7530 l cp gs 0.00 setgray ef gr col0 s -% Polyline -n 2400 900 m 7200 900 l 7200 8100 l 2400 8100 l - cp gs col0 s gr -/Courier-Bold ff 200.00 scf sf -5100 7425 m -gs 1 -1 sc (SP) dup sw pop 2 div neg 0 rm col0 sh gr -/Courier-Bold ff 200.00 scf sf -4350 7425 m -gs 1 -1 sc (W) dup sw pop 2 div neg 0 rm col0 sh gr -/Courier-Bold ff 200.00 scf sf -3225 2250 m -gs 1 -1 sc 90.0 rot (dL) dup sw pop 2 div neg 0 rm col0 sh gr -/Courier-Bold ff 200.00 scf sf -3225 6150 m -gs 1 -1 sc 90.0 rot (dL) dup sw pop 2 div neg 0 rm col0 sh gr -% here ends figure; -$F2psEnd -rs -showpage -%%Trailer -%EOF diff --git a/documentation/RDS/images/RDS_VW-eps-converted-to.pdf b/documentation/RDS/images/RDS_VW-eps-converted-to.pdf deleted file mode 100644 index 7051bba6..00000000 Binary files a/documentation/RDS/images/RDS_VW-eps-converted-to.pdf and /dev/null differ diff --git a/documentation/RDS/images/RDS_VW.eps b/documentation/RDS/images/RDS_VW.eps deleted file mode 100644 index 6761037f..00000000 --- a/documentation/RDS/images/RDS_VW.eps +++ /dev/null @@ -1,243 +0,0 @@ -%!PS-Adobe-2.0 EPSF-2.0 -%%Title: RDS_VW.fig -%%Creator: fig2dev Version 3.2 Patchlevel 5 -%%CreationDate: Mon Sep 15 18:24:04 2014 -%%For: jpc@lepka (Jean-Paul Chaput) -%%BoundingBox: 0 0 489 255 -%Magnification: 1.0000 -%%EndComments -/$F2psDict 200 dict def -$F2psDict begin -$F2psDict /mtrx matrix put -/col-1 {0 setgray} bind def -/col0 {0.000 0.000 0.000 srgb} bind def -/col1 {0.000 0.000 1.000 srgb} bind def -/col2 {0.000 1.000 0.000 srgb} bind def -/col3 {0.000 1.000 1.000 srgb} bind def -/col4 {1.000 0.000 0.000 srgb} bind def -/col5 {1.000 0.000 1.000 srgb} bind def -/col6 {1.000 1.000 0.000 srgb} bind def -/col7 {1.000 1.000 1.000 srgb} bind def -/col8 {0.000 0.000 0.560 srgb} bind def -/col9 {0.000 0.000 0.690 srgb} bind def -/col10 {0.000 0.000 0.820 srgb} bind def -/col11 {0.530 0.810 1.000 srgb} bind def -/col12 {0.000 0.560 0.000 srgb} bind def -/col13 {0.000 0.690 0.000 srgb} bind def -/col14 {0.000 0.820 0.000 srgb} bind def -/col15 {0.000 0.560 0.560 srgb} bind def -/col16 {0.000 0.690 0.690 srgb} bind def -/col17 {0.000 0.820 0.820 srgb} bind def -/col18 {0.560 0.000 0.000 srgb} bind def -/col19 {0.690 0.000 0.000 srgb} bind def -/col20 {0.820 0.000 0.000 srgb} bind def -/col21 {0.560 0.000 0.560 srgb} bind def -/col22 {0.690 0.000 0.690 srgb} bind def -/col23 {0.820 0.000 0.820 srgb} bind def -/col24 {0.500 0.190 0.000 srgb} bind def -/col25 {0.630 0.250 0.000 srgb} bind def -/col26 {0.750 0.380 0.000 srgb} bind def -/col27 {1.000 0.500 0.500 srgb} bind def -/col28 {1.000 0.630 0.630 srgb} bind def -/col29 {1.000 0.750 0.750 srgb} bind def -/col30 {1.000 0.880 0.880 srgb} bind def -/col31 {1.000 0.840 0.000 srgb} bind def - -end -save -newpath 0 255 moveto 0 0 lineto 489 0 lineto 489 255 lineto closepath clip newpath --106.7 306.7 translate -1 -1 scale - -/cp {closepath} bind def -/ef {eofill} bind def -/gr {grestore} bind def -/gs {gsave} bind def -/sa {save} bind def -/rs {restore} bind def -/l {lineto} bind def -/m {moveto} bind def -/rm {rmoveto} bind def -/n {newpath} bind def -/s {stroke} bind def -/sh {show} bind def -/slc {setlinecap} bind def -/slj {setlinejoin} bind def -/slw {setlinewidth} bind def -/srgb {setrgbcolor} bind def -/rot {rotate} bind def -/sc {scale} bind def -/sd {setdash} bind def -/ff {findfont} bind def -/sf {setfont} bind def -/scf {scalefont} bind def -/sw {stringwidth} bind def -/tr {translate} bind def -/tnt {dup dup currentrgbcolor - 4 -2 roll dup 1 exch sub 3 -1 roll mul add - 4 -2 roll dup 1 exch sub 3 -1 roll mul add - 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} - bind def -/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul - 4 -2 roll mul srgb} bind def -/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def -/$F2psEnd {$F2psEnteredState restore end} def - -$F2psBegin -10 setmiterlimit -0 slj 0 slc - 0.06000 0.06000 sc -% -% Fig objects follow -% -% -% here starts figure with depth 60 -% Polyline -0 slj -0 slc -15.000 slw -n 2400 1800 m 8400 1800 l 8400 3600 l 2400 3600 l - cp gs col18 0.50 tnt ef gr gs col18 s gr -% here ends figure; -% -% here starts figure with depth 55 -% Polyline -0 slj -0 slc -15.000 slw -n 3000 2100 m 7800 2100 l 7800 3300 l 3000 3300 l - cp gs col7 1.00 shd ef gr gs col0 s gr -% here ends figure; -% -% here starts figure with depth 50 -% Polyline -0 slj -0 slc -15.000 slw -n 1800 900 m 5175 900 l 5175 1275 l 1800 1275 l - cp gs col0 s gr -/Courier-Bold ff 300.00 scf sf -1950 1200 m -gs 1 -1 sc (VW) col18 sh gr -/Courier-Bold ff 300.00 scf sf -2850 1200 m -gs 1 -1 sc (dL) col18 sh gr -/Courier-Bold ff 300.00 scf sf -3750 1200 m -gs 1 -1 sc (dW) col18 sh gr -/Courier-Bold ff 300.00 scf sf -4650 1200 m -gs 1 -1 sc (dX) col0 sh gr -% Polyline -7.500 slw -n 7875 2100 m - 9375 2100 l gs col0 s gr -% Polyline -n 8475 1800 m 8700 1800 l 9000 1500 l - 9375 1500 l gs col0 s gr -% Polyline -n 7875 3300 m - 9375 3300 l gs col0 s gr -% Polyline -n 8475 3600 m 8700 3600 l 9000 3900 l - 9375 3900 l gs col0 s gr -% Polyline -n 7800 3375 m - 7800 4575 l gs col0 s gr -% Polyline -n 8400 3675 m - 8400 4575 l gs col0 s gr -% Polyline -n 2400 3675 m - 2400 4575 l gs col0 s gr -% Polyline -n 3000 3375 m - 3000 4575 l gs col0 s gr -% Polyline -gs clippath -9270 1964 m 9270 2115 l 9330 2115 l 9330 1964 l 9330 1964 l 9300 2084 l 9270 1964 l cp -9330 1636 m 9330 1485 l 9270 1485 l 9270 1636 l 9270 1636 l 9300 1516 l 9330 1636 l cp -eoclip -n 9300 1500 m - 9300 2100 l gs col0 s gr gr - -% arrowhead -n 9330 1636 m 9300 1516 l 9270 1636 l 9330 1636 l cp gs 0.00 setgray ef gr col0 s -% arrowhead -n 9270 1964 m 9300 2084 l 9330 1964 l 9270 1964 l cp gs 0.00 setgray ef gr col0 s -% Polyline -gs clippath -9270 3764 m 9270 3915 l 9330 3915 l 9330 3764 l 9330 3764 l 9300 3884 l 9270 3764 l cp -9330 3436 m 9330 3285 l 9270 3285 l 9270 3436 l 9270 3436 l 9300 3316 l 9330 3436 l cp -eoclip -n 9300 3300 m - 9300 3900 l gs col0 s gr gr - -% arrowhead -n 9330 3436 m 9300 3316 l 9270 3436 l 9330 3436 l cp gs 0.00 setgray ef gr col0 s -% arrowhead -n 9270 3764 m 9300 3884 l 9330 3764 l 9270 3764 l cp gs 0.00 setgray ef gr col0 s -% Polyline -gs clippath -8264 4530 m 8415 4530 l 8415 4470 l 8264 4470 l 8264 4470 l 8384 4500 l 8264 4530 l cp -7936 4470 m 7785 4470 l 7785 4530 l 7936 4530 l 7936 4530 l 7816 4500 l 7936 4470 l cp -eoclip -n 7800 4500 m - 8400 4500 l gs col0 s gr gr - -% arrowhead -n 7936 4470 m 7816 4500 l 7936 4530 l 7936 4470 l cp gs 0.00 setgray ef gr col0 s -% arrowhead -n 8264 4530 m 8384 4500 l 8264 4470 l 8264 4530 l cp gs 0.00 setgray ef gr col0 s -% Polyline -gs clippath -2864 4530 m 3015 4530 l 3015 4470 l 2864 4470 l 2864 4470 l 2984 4500 l 2864 4530 l cp -2536 4470 m 2385 4470 l 2385 4530 l 2536 4530 l 2536 4530 l 2416 4500 l 2536 4470 l cp -eoclip -n 2400 4500 m - 3000 4500 l gs col0 s gr gr - -% arrowhead -n 2536 4470 m 2416 4500 l 2536 4530 l 2536 4470 l cp gs 0.00 setgray ef gr col0 s -% arrowhead -n 2864 4530 m 2984 4500 l 2864 4470 l 2864 4530 l cp gs 0.00 setgray ef gr col0 s -% Polyline -45.000 slw -n 2925 2625 m - 3075 2775 l gs col0 s gr -% Polyline -n 2925 2775 m - 3075 2625 l gs col0 s gr -% Polyline -n 7725 2625 m - 7875 2775 l gs col0 s gr -% Polyline -n 7725 2775 m - 7875 2625 l gs col0 s gr -% Polyline -15.000 slw - [90 45 15 45] 0 sd -n 3000 2700 m - 7800 2700 l gs col0 s gr [] 0 sd -% Polyline -7.500 slw -n 1800 900 m 9900 900 l 9900 5100 l 1800 5100 l - cp gs col0 s gr -/Courier-Bold ff 200.00 scf sf -2700 4425 m -gs 1 -1 sc (dL) dup sw pop 2 div neg 0 rm col0 sh gr -/Courier-Bold ff 200.00 scf sf -8100 4425 m -gs 1 -1 sc (dL) dup sw pop 2 div neg 0 rm col0 sh gr -/Courier-Bold ff 200.00 scf sf -9225 3600 m -gs 1 -1 sc 90.0 rot (dW/2) dup sw pop 2 div neg 0 rm col0 sh gr -/Courier-Bold ff 200.00 scf sf -9225 1800 m -gs 1 -1 sc 90.0 rot (dW/2) dup sw pop 2 div neg 0 rm col0 sh gr -% here ends figure; -$F2psEnd -rs -showpage -%%Trailer -%EOF diff --git a/documentation/RDS/images/SegmentOrientation.eps b/documentation/RDS/images/SegmentOrientation.eps deleted file mode 100644 index 17802f3b..00000000 --- a/documentation/RDS/images/SegmentOrientation.eps +++ /dev/null @@ -1,283 +0,0 @@ -%!PS-Adobe-2.0 EPSF-2.0 -%%Title: SegmentOrientation.fig -%%Creator: fig2dev Version 3.2 Patchlevel 5 -%%CreationDate: Fri Sep 26 17:55:45 2014 -%%For: jpc@lepka (Jean-Paul Chaput) -%%BoundingBox: 0 0 507 471 -%Magnification: 1.0000 -%%EndComments -/$F2psDict 200 dict def -$F2psDict begin -$F2psDict /mtrx matrix put -/col-1 {0 setgray} bind def -/col0 {0.000 0.000 0.000 srgb} bind def -/col1 {0.000 0.000 1.000 srgb} bind def -/col2 {0.000 1.000 0.000 srgb} bind def -/col3 {0.000 1.000 1.000 srgb} bind def -/col4 {1.000 0.000 0.000 srgb} bind def -/col5 {1.000 0.000 1.000 srgb} bind def -/col6 {1.000 1.000 0.000 srgb} bind def -/col7 {1.000 1.000 1.000 srgb} bind def -/col8 {0.000 0.000 0.560 srgb} bind def -/col9 {0.000 0.000 0.690 srgb} bind def -/col10 {0.000 0.000 0.820 srgb} bind def -/col11 {0.530 0.810 1.000 srgb} bind def -/col12 {0.000 0.560 0.000 srgb} bind def -/col13 {0.000 0.690 0.000 srgb} bind def -/col14 {0.000 0.820 0.000 srgb} bind def -/col15 {0.000 0.560 0.560 srgb} bind def -/col16 {0.000 0.690 0.690 srgb} bind def -/col17 {0.000 0.820 0.820 srgb} bind def -/col18 {0.560 0.000 0.000 srgb} bind def -/col19 {0.690 0.000 0.000 srgb} bind def -/col20 {0.820 0.000 0.000 srgb} bind def -/col21 {0.560 0.000 0.560 srgb} bind def -/col22 {0.690 0.000 0.690 srgb} bind def -/col23 {0.820 0.000 0.820 srgb} bind def -/col24 {0.500 0.190 0.000 srgb} bind def -/col25 {0.630 0.250 0.000 srgb} bind def -/col26 {0.750 0.380 0.000 srgb} bind def -/col27 {1.000 0.500 0.500 srgb} bind def -/col28 {1.000 0.630 0.630 srgb} bind def -/col29 {1.000 0.750 0.750 srgb} bind def -/col30 {1.000 0.880 0.880 srgb} bind def -/col31 {1.000 0.840 0.000 srgb} bind def - -end -save -newpath 0 471 moveto 0 0 lineto 507 0 lineto 507 471 lineto closepath clip newpath --88.7 595.3 translate -1 -1 scale - -/cp {closepath} bind def -/ef {eofill} bind def -/gr {grestore} bind def -/gs {gsave} bind def -/sa {save} bind def -/rs {restore} bind def -/l {lineto} bind def -/m {moveto} bind def -/rm {rmoveto} bind def -/n {newpath} bind def -/s {stroke} bind def -/sh {show} bind def -/slc {setlinecap} bind def -/slj {setlinejoin} bind def -/slw {setlinewidth} bind def -/srgb {setrgbcolor} bind def -/rot {rotate} bind def -/sc {scale} bind def -/sd {setdash} bind def -/ff {findfont} bind def -/sf {setfont} bind def -/scf {scalefont} bind def -/sw {stringwidth} bind def -/tr {translate} bind def -/tnt {dup dup currentrgbcolor - 4 -2 roll dup 1 exch sub 3 -1 roll mul add - 4 -2 roll dup 1 exch sub 3 -1 roll mul add - 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} - bind def -/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul - 4 -2 roll mul srgb} bind def - /DrawEllipse { - /endangle exch def - /startangle exch def - /yrad exch def - /xrad exch def - /y exch def - /x exch def - /savematrix mtrx currentmatrix def - x y tr xrad yrad sc 0 0 1 startangle endangle arc - closepath - savematrix setmatrix - } def - -/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def -/$F2psEnd {$F2psEnteredState restore end} def - -$F2psBegin -10 setmiterlimit -0 slj 0 slc - 0.06000 0.06000 sc -% -% Fig objects follow -% -% -% here starts figure with depth 60 -% Ellipse -15.000 slw -n 2775 4200 450 450 0 360 DrawEllipse gs col18 0.50 tnt ef gr gs col18 s gr - -% Polyline -0 slj -0 slc -45.000 slw -n 3300 2700 m 3900 2700 l 3900 5700 l 3300 5700 l - cp gs col0 s gr -% Polyline -7.500 slw - [60 30 15 30] 0 sd -n 3600 2700 m - 3600 5700 l gs col0 s gr [] 0 sd -% Polyline -45.000 slw -n 3450 5550 m - 3750 5850 l gs col0 s gr -% Polyline -n 3450 5850 m - 3750 5550 l gs col0 s gr -% Polyline -n 3600 2700 m - 3450 3000 l gs col0 s gr -% Polyline -n 3600 2700 m - 3750 3000 l gs col0 s gr -% Ellipse -15.000 slw -n 4425 4200 450 450 0 360 DrawEllipse gs col12 0.50 tnt ef gr gs col12 s gr - -% Polyline -45.000 slw -n 7500 5700 m 8100 5700 l 8100 2700 l 7500 2700 l - cp gs col0 s gr -% Polyline -7.500 slw - [60 30 15 30] 0 sd -n 7800 5700 m - 7800 2700 l gs col0 s gr [] 0 sd -% Polyline -45.000 slw -n 7650 2850 m - 7950 2550 l gs col0 s gr -% Polyline -n 7650 2550 m - 7950 2850 l gs col0 s gr -% Polyline -n 7800 5700 m - 7650 5400 l gs col0 s gr -% Polyline -n 7800 5700 m - 7950 5400 l gs col0 s gr -% Ellipse -15.000 slw -n 6975 4200 450 450 0 360 DrawEllipse gs col12 0.50 tnt ef gr gs col12 s gr - -% Ellipse -n 8625 4200 450 450 0 360 DrawEllipse gs col18 0.50 tnt ef gr gs col18 s gr - -% Polyline -45.000 slw -n 6300 8400 m 6300 7800 l 9300 7800 l 9300 8400 l - cp gs col0 s gr -% Polyline -7.500 slw - [60 30 15 30] 0 sd -n 6300 8100 m - 9300 8100 l gs col0 s gr [] 0 sd -% Polyline -45.000 slw -n 9150 8250 m - 9450 7950 l gs col0 s gr -% Polyline -n 9450 8250 m - 9150 7950 l gs col0 s gr -% Polyline -n 6300 8100 m - 6600 8250 l gs col0 s gr -% Polyline -n 6300 8100 m - 6600 7950 l gs col0 s gr -% Ellipse -15.000 slw -n 7800 8925 450 450 0 360 DrawEllipse gs col18 0.50 tnt ef gr gs col18 s gr - -% Ellipse -n 7800 7275 450 450 0 360 DrawEllipse gs col12 0.50 tnt ef gr gs col12 s gr - -% Polyline -45.000 slw -n 5100 7800 m 5100 8400 l 2100 8400 l 2100 7800 l - cp gs col0 s gr -% Polyline -7.500 slw - [60 30 15 30] 0 sd -n 5100 8100 m - 2100 8100 l gs col0 s gr [] 0 sd -% Polyline -45.000 slw -n 2250 7950 m - 1950 8250 l gs col0 s gr -% Polyline -n 1950 7950 m - 2250 8250 l gs col0 s gr -% Polyline -n 5100 8100 m - 4800 7950 l gs col0 s gr -% Polyline -n 5100 8100 m - 4800 8250 l gs col0 s gr -% Ellipse -15.000 slw -n 3525 7275 450 450 0 360 DrawEllipse gs col18 0.50 tnt ef gr gs col18 s gr - -% Ellipse -n 3525 8925 450 450 0 360 DrawEllipse gs col12 0.50 tnt ef gr gs col12 s gr - -% here ends figure; -% -% here starts figure with depth 50 -/Courier-Bold ff 200.00 scf sf -2775 4275 m -gs 1 -1 sc (left) dup sw pop 2 div neg 0 rm col18 sh gr -/Courier-Bold ff 200.00 scf sf -4425 4275 m -gs 1 -1 sc (right) dup sw pop 2 div neg 0 rm col12 sh gr -/Courier-Bold ff 200.00 scf sf -6975 4275 m -gs 1 -1 sc (right) dup sw pop 2 div neg 0 rm col12 sh gr -/Courier-Bold ff 200.00 scf sf -8625 4275 m -gs 1 -1 sc (left) dup sw pop 2 div neg 0 rm col18 sh gr -/Courier-Bold ff 200.00 scf sf -7800 9000 m -gs 1 -1 sc (left) dup sw pop 2 div neg 0 rm col18 sh gr -/Courier-Bold ff 200.00 scf sf -7800 7350 m -gs 1 -1 sc (right) dup sw pop 2 div neg 0 rm col12 sh gr -/Courier-Bold ff 200.00 scf sf -3525 7350 m -gs 1 -1 sc (left) dup sw pop 2 div neg 0 rm col18 sh gr -/Courier-Bold ff 200.00 scf sf -3525 9000 m -gs 1 -1 sc (right) dup sw pop 2 div neg 0 rm col12 sh gr -% Polyline -0 slj -0 slc -15.000 slw -n 5700 2100 m - 5700 9900 l gs col0 s gr -% Polyline -n 1500 6300 m - 9900 6300 l gs col0 s gr -% Polyline -n 1500 2100 m 9900 2100 l 9900 9900 l 1500 9900 l - cp gs col0 s gr -/Courier-Bold ff 266.67 scf sf -1650 2400 m -gs 1 -1 sc (Up) col0 sh gr -/Courier-Bold ff 266.67 scf sf -1650 6600 m -gs 1 -1 sc (Right) col0 sh gr -/Courier-Bold ff 266.67 scf sf -5850 6600 m -gs 1 -1 sc (Left) col0 sh gr -/Courier-Bold ff 266.67 scf sf -5850 2400 m -gs 1 -1 sc (Down) col0 sh gr -% here ends figure; -$F2psEnd -rs -showpage -%%Trailer -%EOF diff --git a/documentation/RDS/images/bigvia-1.eps b/documentation/RDS/images/bigvia-1.eps deleted file mode 100644 index 0e990719..00000000 --- a/documentation/RDS/images/bigvia-1.eps +++ /dev/null @@ -1,259 +0,0 @@ -%!PS-Adobe-2.0 EPSF-2.0 -%%Title: bigvia-1.fig -%%Creator: fig2dev Version 3.2 Patchlevel 5 -%%CreationDate: Fri Sep 26 22:43:59 2014 -%%For: jpc@lepka (Jean-Paul Chaput) -%%BoundingBox: 0 0 275 269 -%Magnification: 0.7000 -%%EndComments -/$F2psDict 200 dict def -$F2psDict begin -$F2psDict /mtrx matrix put -/col-1 {0 setgray} bind def -/col0 {0.000 0.000 0.000 srgb} bind def -/col1 {0.000 0.000 1.000 srgb} bind def -/col2 {0.000 1.000 0.000 srgb} bind def -/col3 {0.000 1.000 1.000 srgb} bind def -/col4 {1.000 0.000 0.000 srgb} bind def -/col5 {1.000 0.000 1.000 srgb} bind def -/col6 {1.000 1.000 0.000 srgb} bind def -/col7 {1.000 1.000 1.000 srgb} bind def -/col8 {0.000 0.000 0.560 srgb} bind def -/col9 {0.000 0.000 0.690 srgb} bind def -/col10 {0.000 0.000 0.820 srgb} bind def -/col11 {0.530 0.810 1.000 srgb} bind def -/col12 {0.000 0.560 0.000 srgb} bind def -/col13 {0.000 0.690 0.000 srgb} bind def -/col14 {0.000 0.820 0.000 srgb} bind def -/col15 {0.000 0.560 0.560 srgb} bind def -/col16 {0.000 0.690 0.690 srgb} bind def -/col17 {0.000 0.820 0.820 srgb} bind def -/col18 {0.560 0.000 0.000 srgb} bind def -/col19 {0.690 0.000 0.000 srgb} bind def -/col20 {0.820 0.000 0.000 srgb} bind def -/col21 {0.560 0.000 0.560 srgb} bind def -/col22 {0.690 0.000 0.690 srgb} bind def -/col23 {0.820 0.000 0.820 srgb} bind def -/col24 {0.500 0.190 0.000 srgb} bind def -/col25 {0.630 0.250 0.000 srgb} bind def -/col26 {0.750 0.380 0.000 srgb} bind def -/col27 {1.000 0.500 0.500 srgb} bind def -/col28 {1.000 0.630 0.630 srgb} bind def -/col29 {1.000 0.750 0.750 srgb} bind def -/col30 {1.000 0.880 0.880 srgb} bind def -/col31 {1.000 0.840 0.000 srgb} bind def - -end -save -newpath 0 269 moveto 0 0 lineto 275 0 lineto 275 269 lineto closepath clip newpath --3.2 331.3 translate -1 -1 scale - -/cp {closepath} bind def -/ef {eofill} bind def -/gr {grestore} bind def -/gs {gsave} bind def -/sa {save} bind def -/rs {restore} bind def -/l {lineto} bind def -/m {moveto} bind def -/rm {rmoveto} bind def -/n {newpath} bind def -/s {stroke} bind def -/sh {show} bind def -/slc {setlinecap} bind def -/slj {setlinejoin} bind def -/slw {setlinewidth} bind def -/srgb {setrgbcolor} bind def -/rot {rotate} bind def -/sc {scale} bind def -/sd {setdash} bind def -/ff {findfont} bind def -/sf {setfont} bind def -/scf {scalefont} bind def -/sw {stringwidth} bind def -/tr {translate} bind def -/tnt {dup dup currentrgbcolor - 4 -2 roll dup 1 exch sub 3 -1 roll mul add - 4 -2 roll dup 1 exch sub 3 -1 roll mul add - 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} - bind def -/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul - 4 -2 roll mul srgb} bind def -/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def -/$F2psEnd {$F2psEnteredState restore end} def - -$F2psBegin -10 setmiterlimit -0 slj 0 slc - 0.04200 0.04200 sc -% -% Fig objects follow -% -% -% here starts figure with depth 60 -% Polyline -0 slj -0 slc -0.000 slw -n 900 6300 m 1500 6300 l 1500 6900 l 900 6900 l - cp gs col7 0.80 shd ef gr -% Polyline -n 2400 6300 m 3000 6300 l 3000 6900 l 2400 6900 l - cp gs col7 0.80 shd ef gr -% Polyline -n 3900 6300 m 4500 6300 l 4500 6900 l 3900 6900 l - cp gs col7 0.80 shd ef gr -% Polyline -n 5400 6300 m 6000 6300 l 6000 6900 l 5400 6900 l - cp gs col7 0.80 shd ef gr -% Polyline -n 900 4800 m 1500 4800 l 1500 5400 l 900 5400 l - cp gs col7 0.80 shd ef gr -% Polyline -n 900 3300 m 1500 3300 l 1500 3900 l 900 3900 l - cp gs col7 0.80 shd ef gr -% Polyline -n 900 1800 m 1500 1800 l 1500 2400 l 900 2400 l - cp gs col7 0.80 shd ef gr -% Polyline -n 2400 4800 m 3000 4800 l 3000 5400 l 2400 5400 l - cp gs col7 0.00 shd ef gr -% Polyline -n 2400 3300 m 3000 3300 l 3000 3900 l 2400 3900 l - cp gs col7 0.00 shd ef gr -% Polyline -n 3900 3300 m 4500 3300 l 4500 3900 l 3900 3900 l - cp gs col7 0.00 shd ef gr -% Polyline -n 3900 4800 m 4500 4800 l 4500 5400 l 3900 5400 l - cp gs col7 0.00 shd ef gr -% Polyline -n 2400 1800 m 3000 1800 l 3000 2400 l 2400 2400 l - cp gs col7 0.80 shd ef gr -% Polyline -n 3900 1800 m 4500 1800 l 4500 2400 l 3900 2400 l - cp gs col7 0.80 shd ef gr -% Polyline -n 5400 1800 m 6000 1800 l 6000 2400 l 5400 2400 l - cp gs col7 0.80 shd ef gr -% Polyline -n 5400 3300 m 6000 3300 l 6000 3900 l 5400 3900 l - cp gs col7 0.80 shd ef gr -% Polyline -n 5400 4800 m 6000 4800 l 6000 5400 l 5400 5400 l - cp gs col7 0.80 shd ef gr -% Polyline -7.500 slw -n 5400 6900 m - 5400 7875 l gs col7 0.00 shd ef gr gs col0 s gr -% Polyline -n 6000 6900 m 6000 7200 l 6300 7500 l - 6300 7875 l gs col0 s gr -% Polyline -n 1500 5775 m - 1500 7875 l gs col0 s gr -% Polyline -n 1425 5700 m - 225 5700 l gs col0 s gr -% Polyline -n 1425 2700 m - 225 2700 l gs col0 s gr -% Polyline -gs clippath -270 5564 m 270 5715 l 330 5715 l 330 5564 l 330 5564 l 300 5684 l 270 5564 l cp -330 2836 m 330 2685 l 270 2685 l 270 2836 l 270 2836 l 300 2716 l 330 2836 l cp -eoclip -n 300 2700 m - 300 5700 l gs col0 s gr gr - -% arrowhead -n 330 2836 m 300 2716 l 270 2836 l 330 2836 l cp gs 0.00 setgray ef gr col0 s -% arrowhead -n 270 5564 m 300 5684 l 330 5564 l 270 5564 l cp gs 0.00 setgray ef gr col0 s -% Polyline -gs clippath -4364 7830 m 4515 7830 l 4515 7770 l 4364 7770 l 4364 7770 l 4484 7800 l 4364 7830 l cp -1636 7770 m 1485 7770 l 1485 7830 l 1636 7830 l 1636 7830 l 1516 7800 l 1636 7770 l cp -eoclip -n 1500 7800 m - 4500 7800 l gs col0 s gr gr - -% arrowhead -n 1636 7770 m 1516 7800 l 1636 7830 l 1636 7770 l cp gs 0.00 setgray ef gr col0 s -% arrowhead -n 4364 7830 m 4484 7800 l 4364 7770 l 4364 7830 l cp gs 0.00 setgray ef gr col0 s -% Polyline -gs clippath -5264 7830 m 5415 7830 l 5415 7770 l 5264 7770 l 5264 7770 l 5384 7800 l 5264 7830 l cp -4636 7770 m 4485 7770 l 4485 7830 l 4636 7830 l 4636 7830 l 4516 7800 l 4636 7770 l cp -eoclip -n 4500 7800 m - 5400 7800 l gs col0 s gr gr - -% arrowhead -n 4636 7770 m 4516 7800 l 4636 7830 l 4636 7770 l cp gs 0.00 setgray ef gr col0 s -% arrowhead -n 5264 7830 m 5384 7800 l 5264 7770 l 5264 7830 l cp gs 0.00 setgray ef gr col0 s -% Polyline -gs clippath -6164 7830 m 6315 7830 l 6315 7770 l 6164 7770 l 6164 7770 l 6284 7800 l 6164 7830 l cp -5536 7770 m 5385 7770 l 5385 7830 l 5536 7830 l 5536 7830 l 5416 7800 l 5536 7770 l cp -eoclip -n 5400 7800 m - 6300 7800 l gs col0 s gr gr - -% arrowhead -n 5536 7770 m 5416 7800 l 5536 7830 l 5536 7770 l cp gs 0.00 setgray ef gr col0 s -% arrowhead -n 6164 7830 m 6284 7800 l 6164 7770 l 6164 7830 l cp gs 0.00 setgray ef gr col0 s -% Polyline -n 4500 5775 m - 4500 7875 l gs col0 s gr -/Courier-Bold ff 200.00 scf sf -3000 7725 m -gs 1 -1 sc (width) dup sw pop 2 div neg 0 rm col0 sh gr -/Courier-Bold ff 200.00 scf sf -4950 7725 m -gs 1 -1 sc (step) dup sw pop 2 div neg 0 rm col0 sh gr -/Courier-Bold ff 200.00 scf sf -5850 7725 m -gs 1 -1 sc (side) dup sw pop 2 div neg 0 rm col0 sh gr -/Courier-Bold ff 200.00 scf sf -225 4200 m -gs 1 -1 sc 90.0 rot (height) dup sw pop 2 div neg 0 rm col0 sh gr -% here ends figure; -% -% here starts figure with depth 50 -% Polyline -0 slj -0 slc -7.500 slw -gs clippath -6343 6960 m 6615 6960 l 6615 6840 l 6343 6840 l 6343 6840 l 6583 6900 l 6343 6960 l cp -eoclip -n 600 6900 m - 6600 6900 l gs col0 s gr gr - -% arrowhead -n 6343 6960 m 6583 6900 l 6343 6840 l col0 s -% Polyline -gs clippath -960 1757 m 960 1485 l 840 1485 l 840 1757 l 840 1757 l 900 1517 l 960 1757 l cp -eoclip -n 900 7200 m - 900 1500 l gs col0 s gr gr - -% arrowhead -n 960 1757 m 900 1517 l 840 1757 l col0 s -% Polyline -45.000 slw - [150 75 15 75] 0 sd -n 1500 2700 m 4500 2700 l 4500 5700 l 1500 5700 l - cp gs col0 s gr [] 0 sd -% here ends figure; -$F2psEnd -rs -showpage -%%Trailer -%EOF diff --git a/documentation/RDS/images/bigvia-2.eps b/documentation/RDS/images/bigvia-2.eps deleted file mode 100644 index 9073b7be..00000000 --- a/documentation/RDS/images/bigvia-2.eps +++ /dev/null @@ -1,184 +0,0 @@ -%!PS-Adobe-2.0 EPSF-2.0 -%%Title: bigvia-2.fig -%%Creator: fig2dev Version 3.2 Patchlevel 5 -%%CreationDate: Fri Sep 26 22:28:01 2014 -%%For: jpc@lepka (Jean-Paul Chaput) -%%BoundingBox: 0 0 254 254 -%Magnification: 0.7000 -%%EndComments -/$F2psDict 200 dict def -$F2psDict begin -$F2psDict /mtrx matrix put -/col-1 {0 setgray} bind def -/col0 {0.000 0.000 0.000 srgb} bind def -/col1 {0.000 0.000 1.000 srgb} bind def -/col2 {0.000 1.000 0.000 srgb} bind def -/col3 {0.000 1.000 1.000 srgb} bind def -/col4 {1.000 0.000 0.000 srgb} bind def -/col5 {1.000 0.000 1.000 srgb} bind def -/col6 {1.000 1.000 0.000 srgb} bind def -/col7 {1.000 1.000 1.000 srgb} bind def -/col8 {0.000 0.000 0.560 srgb} bind def -/col9 {0.000 0.000 0.690 srgb} bind def -/col10 {0.000 0.000 0.820 srgb} bind def -/col11 {0.530 0.810 1.000 srgb} bind def -/col12 {0.000 0.560 0.000 srgb} bind def -/col13 {0.000 0.690 0.000 srgb} bind def -/col14 {0.000 0.820 0.000 srgb} bind def -/col15 {0.000 0.560 0.560 srgb} bind def -/col16 {0.000 0.690 0.690 srgb} bind def -/col17 {0.000 0.820 0.820 srgb} bind def -/col18 {0.560 0.000 0.000 srgb} bind def -/col19 {0.690 0.000 0.000 srgb} bind def -/col20 {0.820 0.000 0.000 srgb} bind def -/col21 {0.560 0.000 0.560 srgb} bind def -/col22 {0.690 0.000 0.690 srgb} bind def -/col23 {0.820 0.000 0.820 srgb} bind def -/col24 {0.500 0.190 0.000 srgb} bind def -/col25 {0.630 0.250 0.000 srgb} bind def -/col26 {0.750 0.380 0.000 srgb} bind def -/col27 {1.000 0.500 0.500 srgb} bind def -/col28 {1.000 0.630 0.630 srgb} bind def -/col29 {1.000 0.750 0.750 srgb} bind def -/col30 {1.000 0.880 0.880 srgb} bind def -/col31 {1.000 0.840 0.000 srgb} bind def - -end -save -newpath 0 254 moveto 0 0 lineto 254 0 lineto 254 254 lineto closepath clip newpath --24.7 302.9 translate -1 -1 scale - -/cp {closepath} bind def -/ef {eofill} bind def -/gr {grestore} bind def -/gs {gsave} bind def -/sa {save} bind def -/rs {restore} bind def -/l {lineto} bind def -/m {moveto} bind def -/rm {rmoveto} bind def -/n {newpath} bind def -/s {stroke} bind def -/sh {show} bind def -/slc {setlinecap} bind def -/slj {setlinejoin} bind def -/slw {setlinewidth} bind def -/srgb {setrgbcolor} bind def -/rot {rotate} bind def -/sc {scale} bind def -/sd {setdash} bind def -/ff {findfont} bind def -/sf {setfont} bind def -/scf {scalefont} bind def -/sw {stringwidth} bind def -/tr {translate} bind def -/tnt {dup dup currentrgbcolor - 4 -2 roll dup 1 exch sub 3 -1 roll mul add - 4 -2 roll dup 1 exch sub 3 -1 roll mul add - 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} - bind def -/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul - 4 -2 roll mul srgb} bind def -/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def -/$F2psEnd {$F2psEnteredState restore end} def - -$F2psBegin -10 setmiterlimit -0 slj 0 slc - 0.04200 0.04200 sc -% -% Fig objects follow -% -% -% here starts figure with depth 60 -% Polyline -0 slj -0 slc -0.000 slw -n 900 6300 m 1500 6300 l 1500 6900 l 900 6900 l - cp gs col7 0.80 shd ef gr -% Polyline -n 2400 6300 m 3000 6300 l 3000 6900 l 2400 6900 l - cp gs col7 0.80 shd ef gr -% Polyline -n 3900 6300 m 4500 6300 l 4500 6900 l 3900 6900 l - cp gs col7 0.80 shd ef gr -% Polyline -n 5400 6300 m 6000 6300 l 6000 6900 l 5400 6900 l - cp gs col7 0.80 shd ef gr -% Polyline -n 900 4800 m 1500 4800 l 1500 5400 l 900 5400 l - cp gs col7 0.80 shd ef gr -% Polyline -n 900 3300 m 1500 3300 l 1500 3900 l 900 3900 l - cp gs col7 0.80 shd ef gr -% Polyline -n 900 1800 m 1500 1800 l 1500 2400 l 900 2400 l - cp gs col7 0.80 shd ef gr -% Polyline -n 2400 4800 m 3000 4800 l 3000 5400 l 2400 5400 l - cp gs col7 0.00 shd ef gr -% Polyline -n 2400 3300 m 3000 3300 l 3000 3900 l 2400 3900 l - cp gs col7 0.00 shd ef gr -% Polyline -n 3900 3300 m 4500 3300 l 4500 3900 l 3900 3900 l - cp gs col7 0.00 shd ef gr -% Polyline -n 3900 4800 m 4500 4800 l 4500 5400 l 3900 5400 l - cp gs col7 0.00 shd ef gr -% Polyline -n 2400 1800 m 3000 1800 l 3000 2400 l 2400 2400 l - cp gs col7 0.80 shd ef gr -% Polyline -n 5400 4800 m 6000 4800 l 6000 5400 l 5400 5400 l - cp gs col7 0.80 shd ef gr -% Polyline -n 3900 1800 m 4500 1800 l 4500 2400 l 3900 2400 l - cp gs col7 0.00 shd ef gr -% Polyline -n 5400 1800 m 6000 1800 l 6000 2400 l 5400 2400 l - cp gs col7 0.00 shd ef gr -% Polyline -n 5400 3300 m 6000 3300 l 6000 3900 l 5400 3900 l - cp gs col7 0.00 shd ef gr -% here ends figure; -% -% here starts figure with depth 50 -% Polyline -0 slj -0 slc -7.500 slw -gs clippath -6343 6960 m 6615 6960 l 6615 6840 l 6343 6840 l 6343 6840 l 6583 6900 l 6343 6960 l cp -eoclip -n 600 6900 m - 6600 6900 l gs col0 s gr gr - -% arrowhead -n 6343 6960 m 6583 6900 l 6343 6840 l col0 s -% Polyline -gs clippath -960 1457 m 960 1185 l 840 1185 l 840 1457 l 840 1457 l 900 1217 l 960 1457 l cp -eoclip -n 900 7200 m - 900 1200 l gs col0 s gr gr - -% arrowhead -n 960 1457 m 900 1217 l 840 1457 l col0 s -% Polyline -45.000 slw - [150 75 15 75] 0 sd -n 1500 2700 m 4500 2700 l 4500 5700 l 1500 5700 l - cp gs col0 s gr [] 0 sd -% Polyline - [150 75 15 75] 0 sd -n 3600 1500 m 6300 1500 l 6300 4200 l 3600 4200 l - cp gs col0 s gr [] 0 sd -% here ends figure; -$F2psEnd -rs -showpage -%%Trailer -%EOF diff --git a/documentation/RDS/images/clipboard-eps-converted-to.pdf b/documentation/RDS/images/clipboard-eps-converted-to.pdf deleted file mode 100644 index 12640803..00000000 Binary files a/documentation/RDS/images/clipboard-eps-converted-to.pdf and /dev/null differ diff --git a/documentation/RDS/index.rst b/documentation/RDS/index.rst new file mode 100644 index 00000000..757d647e --- /dev/null +++ b/documentation/RDS/index.rst @@ -0,0 +1,26 @@ +.. -*- mode: rst; explicit-buffer-name: "index.rst" -*- + +.. include:: ../etc/definitions.rst + + +:Date: 26, september 2014 +:Authors: Jean-Paul Chaput +:Contact: +:Version: 0.2 + + +**Disclaimer:** This document is still far from complete. + + +========================================= +Symbolic to Real Conversion in Alliance +========================================= + +Printable version of this document `RDS.pdf <../../../pdf/main/RDS.pdf>`_. + + +.. toctree:: + :maxdepth: 2 + + RDSpage.rst + diff --git a/documentation/RDS/pdfHeader.rst b/documentation/RDS/pdfHeader.rst new file mode 100644 index 00000000..4cce0e35 --- /dev/null +++ b/documentation/RDS/pdfHeader.rst @@ -0,0 +1,27 @@ +.. -*- mode: rst; explicit-buffer-name: "pdfHeader.rst" -*- + +.. include:: ../etc/definitions.rst + + +:Date: 26, september 2014 +:Authors: Jean-Paul Chaput +:Contact: +:Version: 0.2 + +|medskip| + +**Disclaimer:** This document is still far from complete. + +|medskip| + + +========================================= +Symbolic To Real Conversion in Alliance +========================================= + +|pagestylefancy| + + +.. contents:: + +|newpage| diff --git a/documentation/RDS/socstyle.tex b/documentation/RDS/socstyle.tex deleted file mode 100644 index af9f073e..00000000 --- a/documentation/RDS/socstyle.tex +++ /dev/null @@ -1,86 +0,0 @@ - - \usepackage[default,osfigures,scale=0.95]{opensans} - \usepackage{xspace} - \usepackage{fancyhdr} - \usepackage{graphicx} - \usepackage{enumitem} - \usepackage[sf,bf]{titlesec} - \usepackage{titletoc} - \usepackage[paper=a4paper,headheight=30pt,tmargin=1.5in,bmargin=1in]{geometry} -%\usepackage{layouts} - - \renewlist{itemize}{itemize}{9} - \setlist[itemize]{label=\textbullet} - -% The LaTeX Companion -- p. 204. -% Miniature display of the page layout. -%\newcommand{\showpage}{% -% \setlayoutscale{0.65}\setlabelfont{\tiny}% -% \printheadingsfalse\printparametersfalse% -% \currentpage\pagedesign% -%} - - \titlecontents{section}[0pc] - {\sffamily\bfseries} % above code. - {\contentslabel{1pc}} % numbered entry format. - {} % numberless entry format. - {\titlerule*[8pt]{.}\textsc{\textbf{{\contentspage}}}} % page format. - \titlecontents{subsection}[0pc] - {\sffamily} % above code. - {\contentslabel{2pc}} % numbered entry format. - {} % numberless entry format. - {\titlerule*[8pt]{.}\textsc{\textbf{{\contentspage}}}} % page format. - \titlecontents{subsubsection}[1pc] - {\sffamily} % above code. - {\contentslabel{2pc}} % numbered entry format. - {} % numberless entry format. - {\titlerule*[8pt]{.}\textsc{\textbf{{\contentspage}}}} % page format. - - \newcommand{\key}[1]{\raisebox{-0.5\baselineskip}{\rule{0pt}{1.5\baselineskip}}\fbox{\textsf{#1}}} - - \newcommand{\DUroleul}[1]{\underline{#1}\xspace} - \newcommand{\DUrolesc}[1]{\textsc{#1}\xspace} - \newcommand{\DUrolecb}[1]{\textbf{\texttt{#1}}\xspace} - \newcommand{\DUrolefboxtt}[1]{\fbox{\texttt{#1}}\xspace} - - \newcommand{\DUtitlenote}[1]{\noindent\textbf{#1}\smallskip} - - \newcommand{\DUadmonitionnote}[1]{% - \begin{center} - \sffamily - \begin{array}[t]{m{1cm}!{\vrule width 1pt}m{.90\textwidth}} - \raisebox{0.0cm}{\includegraphics[scale=0.5]{./images/clipboard.eps}} & - \begin{minipage}[t]{.85\textwidth} #1 - \end{minipage} \\ - \end{array} - \end{center} - } - - \newcommand{\DUtitleerror}[1]{\noindent\textbf{\color{red}#1}\smallskip} - - \newcommand{\DUadmonitionerror}[1]{% - \begin{center} - \sffamily - \begin{array}[t]{m{1cm}!{\vrule width 1pt}m{.90\textwidth}} - \raisebox{0.0cm}{\includegraphics[scale=0.5]{./images/i-core.eps}} & - \begin{minipage}[t]{.85\textwidth} #1 - \end{minipage} \\ - \end{array} - \end{center} - } - - \newcommand{\UPMC} {\textsc{upmc}\xspace} - \newcommand{\LIP} {\textsc{lip6}\xspace} - \newcommand{\SoC} {\textsc{S}o\textsc{C}\xspace} - - \renewcommand{\headrulewidth}{0.2mm} - \renewcommand{\footrulewidth}{0.2mm} - \renewcommand{\sectionmark}[1]{\markboth{\thesection\ #1}{\thesection\ #1}} - \renewcommand{\subsectionmark}[1]{} - \lhead[]{\textsc{SoC} Documentation} - \rhead[]{September 2014} - \lfoot[]{\UPMC/\LIP/\SoC} - \rfoot[]{\thepage} - \cfoot[]{} - - \pagestyle{fancy} diff --git a/documentation/Stratus/Stratus.rst b/documentation/Stratus/Stratus.rst new file mode 100644 index 00000000..f61b2dac --- /dev/null +++ b/documentation/Stratus/Stratus.rst @@ -0,0 +1,11 @@ +.. -*- Mode: rst -*- + +.. include:: ../etc/definitions.rst + + +=================== +Stratus Reference +=================== + +The Stratus Language reference is generated by LaTeX2HTML_ and is +available here: `Stratus `_ diff --git a/documentation/Unicorn/Unicorn.rst b/documentation/Unicorn/Unicorn.rst new file mode 100644 index 00000000..c972e5f0 --- /dev/null +++ b/documentation/Unicorn/Unicorn.rst @@ -0,0 +1,11 @@ +.. -*- Mode: rst -*- + +.. include:: ../etc/definitions.rst + + +=================== +Unicorn Reference +=================== + +The Unicorn C++ API reference is generated by Doxygen_ and is +available here: `Unicorn `_ diff --git a/documentation/UsersGuide/CMakeLists.txt b/documentation/UsersGuide/CMakeLists.txt deleted file mode 100644 index 870a0f14..00000000 --- a/documentation/UsersGuide/CMakeLists.txt +++ /dev/null @@ -1,36 +0,0 @@ -# -*- mode: CMAKE; explicit-buffer-name: "CMakeLists.txt" -*- - - set ( htmlInstallDir share/doc/coriolis2/en/html/users-guide ) - set ( latexInstallDir share/doc/coriolis2/en/latex/users-guide ) - - add_custom_target ( doc_HTML ALL - cd ${DOCUMENTATION_SOURCE_DIR}/UsersGuide - && rst2html --link-stylesheet --stylesheet=./SoC.css,./Pygments.css UsersGuide_HTML.rst UsersGuide.html ) - add_dependencies ( doc_HTML SoC.css Pygments.css UsersGuide_HTML.rst UsersGuide.rst ) - - add_custom_target ( doc_LaTeX ALL - cd ${DOCUMENTATION_SOURCE_DIR}/UsersGuide - && rst2latex --use-latex-toc --stylesheet=./socstyle.tex UsersGuide_LaTeX.rst UsersGuide-raw.tex - && sed 's, \\& \\\\multicolumn{2}{l|}{, \\& \\\\multicolumn{2}{p{0.6\\\\DUtablewidth}|}{,' UsersGuide-raw.tex > UsersGuide.tex - && latex UsersGuide - && latex UsersGuide - && latex UsersGuide - && dvipdfm UsersGuide - ) - add_dependencies ( doc_LaTeX socstyle.tex UsersGuide_LaTeX.rst UsersGuide.rst ) - - install ( DIRECTORY images/ - DESTINATION ${htmlInstallDir}/images - FILES_MATCHING PATTERN "*.png" ) - install ( FILES SoC.css - Pygments.css - UsersGuide.html DESTINATION ${htmlInstallDir} ) - - install ( DIRECTORY images/ - DESTINATION ${latexInstallDir}/images - FILES_MATCHING PATTERN "*.pdf" - PATTERN "*.eps" - PATTERN "*.bb" ) - - install ( FILES socstyle.tex - UsersGuide.tex DESTINATION ${latexInstallDir} ) diff --git a/documentation/UsersGuide/Configuration.rst b/documentation/UsersGuide/Configuration.rst new file mode 100644 index 00000000..e2da0de5 --- /dev/null +++ b/documentation/UsersGuide/Configuration.rst @@ -0,0 +1,342 @@ +.. -*- Mode: rst -*- + +.. include:: ../etc/definitions.rst + +.. URLs that changes between the various backends. +.. _Coriolis Tools Documentation: file:///usr/share/doc/coriolis2/index.html + + + +.. |CoriolisSoftSchema| image:: ./images/Coriolis-Soft-Schema.png + :alt: Coriolis Software Schematic + :align: middle + :width: 60% + +|newpage| + + +Coriolis Configuration & Initialisation +======================================= + + +General Software Architecture +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +|Coriolis| has been build with respect of the classical paradigm that the +computational instensive parts have been written in C++, and almost +everything else in |Python|. To build the |Python| interface we used +two methods: + +* For self-contained modules :cb:`boost::python` (mainly in :cb:`vlsisapd`). +* For all modules based on |Hurricane|, we created our own wrappers due + to very specific requirements such as shared functions between modules + or C++/|Python| secure bi-directional object deletion. + +.. note:: **Python Documentation:** + Most of the documentation is related to the C++ API and implemetation of + the tools. However, the |Python| bindings have been created so they + mimic *as closely as possible* the C++ interface, so the documentation + applies to both languages with only minor syntactic changes. + +|bcenter| |CoriolisSoftSchema| |ecenter| + +All configuration & initialization files are Python scripts, despite their +|dot_conf| extention. From a syntactic point of view, there is no difference +between the system-wide configuration files and the user's configuration, +they may use the same Python helpers. +|medskip| + +Configuration is done in two stages: + +#. Selecting the symbolic technology. +#. Loading the complete configuration for the given technology. + +|newpage| + + +First Stage: Symbolic Technology Selection +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +|noindent| +The initialization process is done by executing, in order, the following +file(s): + ++-------+----------------------------------+----------------------------------------------+ +| Order | Meaning | File | ++=======+==================================+==============================================+ +| **1** | The system setting | :cb:`/etc/coriolis2/techno.conf` | ++-------+----------------------------------+----------------------------------------------+ +| **2** | The user's global setting | :cb:`${HOME}/.coriolis2/techno.py` | ++-------+----------------------------------+----------------------------------------------+ +| **3** | The user's local setting | :cb:`/.coriolis2/techno.py` | ++-------+----------------------------------+----------------------------------------------+ + +Thoses files must provides only two variables, the name of the symbolic technology +and the one of the real technology. For example: :: + + # -*- Mode:Python -*- + + symbolicTechno = 'cmos' + realTechno = 'hcmos9' + + +Second Stage: Technology Configuration Loading +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +|noindent| +The :cb:`TECHNO` variable is set by the first stage and it's the name of the +symbolic technology. A directory of that name, with all the configuration files, +must exists in the configuration directory. In addition to the technology-specific +directories, a :cb:`common/` directory is there to provides a trunk for all the +identical datas across the various technologies. The initialization process is done +by executing, in order, the following file(s): + ++-------+----------------------------------+----------------------------------------------+ +| Order | Meaning | File | ++=======+==================================+==============================================+ +| **1** | The system initialization | :cb:`/etc/coriolis2//.conf` | ++-------+----------------------------------+----------------------------------------------+ +| **2** | The user's global initialization | :cb:`${HOME}/.coriolis2/settings.py` | ++-------+----------------------------------+----------------------------------------------+ +| **3** | The user's local initialization | :cb:`/.coriolis2/settings.py` | ++-------+----------------------------------+----------------------------------------------+ + +.. note:: *The loading policy is not hard-coded.* It is implemented + at Python level in :cb:`/etc/coriolis2/coriolisInit.py`, and thus may be easily be + amended to whatever site policy. + + The truly mandatory requirement is the existence of :cb:`coriolisInit.py` + which *must* contain a :cb:`coriolisConfigure()` function with no argument. + + +Configuration Helpers +~~~~~~~~~~~~~~~~~~~~~ + +To ease the writing of configuration files, a set of small helpers +is available. They allow to setup the configuration parameters through +simple assembly of tuples. The helpers are installed under the directory: :: + + /etc/coriolis2/ + +Where :cb:`/` is the root of the installation. + +|newpage| + + +.. _Alliance Helper: + +|Alliance| Helper +----------------- + +The configuration file must provide a :cb:`allianceConfig` tuple of +the form: :: + + cellsTop = '/usr/share/alliance/cells/' + + allianceConfig = \ + ( ( 'SYMBOLIC_TECHNOLOGY', helpers.sysConfDir+'/technology.symbolic.xml' ) + , ( 'REAL_TECHNOLOGY' , helpers.sysConfDir+'/technology.cmos130.s2r.xml') + , ( 'DISPLAY' , helpers.sysConfDir+'/display.xml' ) + , ( 'CATALOG' , 'CATAL') + , ( 'WORKING_LIBRARY' , '.') + , ( 'SYSTEM_LIBRARY' , ( (cellsTop+'sxlib' , Environment.Append) + , (cellsTop+'dp_sxlib', Environment.Append) + , (cellsTop+'ramlib' , Environment.Append) + , (cellsTop+'romlib' , Environment.Append) + , (cellsTop+'rflib' , Environment.Append) + , (cellsTop+'rf2lib' , Environment.Append) + , (cellsTop+'pxlib' , Environment.Append) ) ) + , ( 'SCALE_X' , 100) + , ( 'IN_LO' , 'vst') + , ( 'IN_PH' , 'ap') + , ( 'OUT_LO' , 'vst') + , ( 'OUT_PH' , 'ap') + , ( 'POWER' , 'vdd') + , ( 'GROUND' , 'vss') + , ( 'CLOCK' , '^ck.*') + , ( 'BLOCKAGE' , '^blockageNet*') + ) + + +|noindent| The example above shows the system configuration file, with all the +available settings. Some important remarks about thoses settings: + +* In it's configuration file, the user do not need to redefine all the settings, + just the one he wants to change. In most of the cases, the ``SYSTEM_LIBRARY``, + the ``WORKING_LIBRARY`` and the special net names (at this point there is not + much alternatives for the others settings). + +* ``SYSTEM_LIBRARY`` setting: Setting up the library search path. + Each library entry in the tuple will be added to the search path according + to the second parameter: + + * :cb:`Environment::Append`: append to the search path. + + * :cb:`Environment::Prepend`: insert in head of the search path. + + * :cb:`Environment::Replace`: look for a library of the same name and replace + it, whithout changing the search path order. If no library of that name + already exists, it is appended. + + A library is identified by it's name, this name is the last component of the + path name. For instance: ``/soc/alliance/sxlib`` will be named ``sxlib``. + Implementing the |Alliance| specification, when looking for a |Cell| ``name``, + the system will browse sequentially trought the library list and returns + the first |Cell| whose name match. + +* For ``POWER``, ``GROUND``, ``CLOCK`` and ``BLOCKAGE`` net names, a regular + expression (|GNU| regexp) is expected. + +* The ``helpers.sysConfDir`` variable is supplied by the helpers, it is the + directory in which the system-wide configuration files are locateds. + For a standard installation it would be: ``/soc/coriolis2``. + +.. * Trick and naming convention about ``SYMBOLIC_TECHNOLOGY``, ``REAL_TECHNOLOGY`` +.. and ``DISPLAY``. In the previous releases, thoses files where to read by +.. XML parsers, and still do if you triggers the XML compatibility mode. +.. But now, they have Python conterparts. In the configuration files, you +.. still have to name them as XML files, the Python file name will be +.. deduced from this one with thoses two translation rules: +.. +.. #. In the filename, all dots, except for the last (the file extention), +.. are replaced by underscores. +.. +.. #. The ``.xml`` extention is substituted by a ``.conf``. +.. +.. For the symbolic technology, it would give: :: +.. +.. /soc/coriolis2/technology.symbolic.xml +.. --> /soc/coriolis2/technology_symbolic.conf + +A typical user's configuration file would be: :: + + import os + + homeDir = os.getenv('HOME') + + allianceConfig = \ + ( ('WORKING_LIBRARY' , homeDir+'/worklib') + , ('SYSTEM_LIBRARY' , ( (homeDir+'/mylib', Environment.Append) ) ) + , ('POWER' , 'vdd.*') + , ('GROUND' , 'vss.*') + ) + + +Tools Configuration Helpers +--------------------------- + +All the tools uses the same helper to load their configuration (a.k.a. +*Configuration Helper*). Currently the following configuration system-wide +configuration files are defined: + +* :cb:`misc.conf`: commons settings or not belonging specifically to a tool. +* :cb:`etesian.conf`: for the |Etesian| tool. +* :cb:`kite.conf`: for the |Kite| tool. +* :cb:`stratus1.conf`: for the |stratus1| tool. + +Here is the contents of :cb:`etesian.conf`: :: + + # Etesian parameters. + parametersTable = \ + ( ('etesian.aspectRatio' , TypePercentage, 100 , { 'min':10, 'max':1000 } ) + , ('etesian.spaceMargin' , TypePercentage, 5 ) + , ('etesian.uniformDensity' , TypeBool , False ) + , ('etesian.routingDriven' , TypeBool , False ) + , ("etesian.effort" , TypeEnumerate , 2 + , { 'values':( ("Fast" , 1) + , ("Standard", 2) + , ("High" , 3) + , ("Extreme" , 4) ) } + ) + , ("etesian.graphics" , TypeEnumerate , 2 + , { 'values':( ("Show every step" , 1) + , ("Show lower bound" , 2) + , ("Show result only" , 3) ) } + ) + ) + + layoutTable = \ + ( (TypeTab , 'Etesian', 'etesian') + + , (TypeTitle , 'Placement area') + , (TypeOption, "etesian.aspectRatio" , "Aspect Ratio, X/Y (%)", 0 ) + , (TypeOption, "etesian.spaceMargin" , "Space Margin" , 1 ) + , (TypeRule ,) + , (TypeTitle , 'Etesian - Placer') + , (TypeOption, "etesian.uniformDensity", "Uniform density" , 0 ) + , (TypeOption, "etesian.routingDriven" , "Routing driven" , 0 ) + , (TypeOption, "etesian.effort" , "Placement effort" , 1 ) + , (TypeOption, "etesian.graphics" , "Placement view" , 1 ) + , (TypeRule ,) + ) + +|newpage| + + +Taxonomy of the file: + +* It must contains, at least, the two tables: + + * ``parametersTable``, defines & initialise the configuration variables. + + * ``layoutTables``, defines how the various parameters will be displayed + in the configuration window (:ref:`The Settings Tab`). + +* The ``parametersTable``, is a tuple (list) of tuples. Each entry in the list + describe a configuration parameter. In it's simplest form, it's a quadruplet + :cb:`(TypeOption, 'paramId', ParameterType, DefaultValue)` with: + + #. ``TypeOption``, tells that this tuple describe a parameter. + + #. ``paramId``, the identifier of the parameter. Identifiers are defined + by the tools. The list of parameters is detailed in each tool section. + + #. ``ParameterType``, the kind of parameter. Could be: + + * ``TypeBool``, boolean. + * ``TypeInt``, signed integer. + * ``TypeEnumerate``, enumerated type, needs extra entry. + * ``TypePercentage``, percentage, expressed between 0 and 100. + * ``TypeDouble``, float. + * ``TypeString``, character string. + + #. ``DefaultValue``, the default value for that parameter. + + +Hacking the Configuration Files +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Asides from the symbols that gets used by the configuration helpers like +:cb:`allianceConfig` or :cb:`parametersTable`, you can put pretty much anything +in :cb:`/.coriolis2/settings.py` (that is, written in |Python|). + +For example: :: + + # -*- Mode:Python -*- + + defaultStyle = 'Alliance.Classic [black]' + + # Regular Coriolis configuration. + parametersTable = \ + ( ('misc.catchCore' , TypeBool , False ) + , ('misc.info' , TypeBool , False ) + , ('misc.paranoid' , TypeBool , False ) + , ('misc.bug' , TypeBool , False ) + , ('misc.logMode' , TypeBool , True ) + , ('misc.verboseLevel1' , TypeBool , False ) + , ('misc.verboseLevel2' , TypeBool , True ) + , ('misc.minTraceLevel' , TypeInt , 0 ) + , ('misc.maxTraceLevel' , TypeInt , 0 ) + ) + + # Some ordinary Python script... + import os + + print ' o Cleaning up ClockTree previous run.' + for fileName in os.listdir('.'): + if fileName.endswith('.ap') or (fileName.find('_clocked.') >= 0): + print ' - <%s>' % fileName + os.unlink(fileName) + + +See :ref:`Python Interface to Coriolis` for more details those capabilities. diff --git a/documentation/UsersGuide/HTML_defs.rst b/documentation/UsersGuide/HTML_defs.rst deleted file mode 100644 index 2d04ed45..00000000 --- a/documentation/UsersGuide/HTML_defs.rst +++ /dev/null @@ -1,49 +0,0 @@ - -.. -*- Mode: rst -*- - -.. role:: raw-html(raw) - :format: html - -.. URLs that changes between the various backends. -.. _Coriolis Tools Documentation: file:///usr/share/doc/coriolis2/index.html -.. _Stratus Documentation: file:///usr/share/doc/coriolis2/en/html/stratus/index.html -.. _Here: file:///usr/share/doc/coriolis2/en/latex/users-guide/UsersGuide.pdf - -.. For HTML backend -.. |rightarrow| replace:: :raw-html:`

` -.. |menu_P&R| replace:: :raw-html:`

` -.. |menu_StepByStep| replace:: :raw-html:`

` -.. |menu_KiteSaveGlobalRouting| image:: ./images/PR-SBS-SaveGlobal.png -.. |menu_KiteLoadGlobalRouting| image:: ./images/PR-SBS-LoadGlobal.png -.. |menu_KiteGlobalRoute| image:: ./images/PR-GlobalRoute.png -.. |menu_KiteDetailedRoute| image:: ./images/PR-DetailedRoute.png -.. |menu_KiteDetailedPreRoute| image:: ./images/PR-DetailedPreRoute.png -.. |menu_KiteFinalizeRoute| image:: ./images/PR-FinalizeRoute.png - -.. Stand-alone images. -.. |ViewerSnapshot_1| replace:: :raw-html:`
Viewer Basic Snapshot
` -.. |ControllerSnapshot_1| replace:: :raw-html:`
Controller Basic Snapshot
` -.. |ControllerLook_1| replace:: :raw-html:`
Controller Basic Snapshot
` -.. |ControllerFilter_1| replace:: :raw-html:`
Controller Basic Snapshot
` -.. |ControllerLayersGos_1| replace:: :raw-html:`
Controller Basic Snapshot
` -.. |ControllerNetlist_1| replace:: :raw-html:`
Controller Basic Snapshot
` -.. |ViewerNetlist_1| replace:: :raw-html:`
Controller Basic Snapshot
` -.. |ControllerSelection_1| replace:: :raw-html:`
Controller Basic Snapshot
` -.. |ControllerInspector_1| replace:: :raw-html:`
Controller Basic Snapshot
` -.. |ControllerInspector_2| replace:: :raw-html:`
Controller Basic Snapshot
` -.. |ControllerInspector_3| replace:: :raw-html:`
Controller Basic Snapshot
` -.. |ControllerSettings_1| replace:: :raw-html:`
Controller Basic Snapshot
` -.. |CoriolisSoftSchema| replace:: :raw-html:`
Coriolis Software Schematic
` -.. |ChipStructure-1| replace:: :raw-html:`
Chip Top Structure
` -.. |Etesian-1| replace:: :raw-html:`
Etesian Abutment Box
` - -.. |BigMouse| image:: ./images/ComputerMouse.png - :scale: 25% - -.. Direct LaTeX commands encapsulation. -.. |dotfill| replace:: :raw-html:`  ` -.. |noindent| replace:: :raw-html:`

` -.. |medskip| replace:: :raw-html:`
` -.. |newpage| replace:: :raw-html:`
` -.. |br| replace:: :raw-html:`
` - diff --git a/documentation/UsersGuide/Installation.rst b/documentation/UsersGuide/Installation.rst new file mode 100644 index 00000000..224ee5f4 --- /dev/null +++ b/documentation/UsersGuide/Installation.rst @@ -0,0 +1,230 @@ +.. -*- Mode: rst -*- + +.. include:: ../etc/definitions.rst + +|newpage| + + +Installation +============ + +.. note:: + As the sources are being released, the binary packaging is dropped. + You still may find older version here: http://asim.lip6.fr/pub/coriolis/2.0 . + +In a nutshell, building source consist in pulling the |git| repository then +running the |ccb| installer. + +Main building prerequisites: + +* cmake +* C++11-capable compiler +* RapidJSON_ +* python2.7 +* boost +* libxml2 +* bzip2 +* yacc & lex +* Qt 4 or Qt 5 + +Building documentation prerequisites: + +* doxygen +* latex +* latex2html +* python-docutils (for reStructuredText) + +Optional libraries: + +* LEF/DEF (from `SI2 `_) + +For other distributions, refer to their own packaging system. + +|newpage| + + +Fixed Directory Tree +~~~~~~~~~~~~~~~~~~~~ + +In order to simplificate the work of the |ccb| installer, the source, build +and installation tree is fixed. To successfully compile |Coriolis| you must +follow it exactly. The tree is relative to the home directory of the user +building it (noted :fboxtt:`~/` or :fboxtt:`$HOME/`). Only the source +directory needs to be manually created by the user, all others will be +automatically created either by |ccb| or the build system. + ++--------------------------------------------------------------------------------------------------------------+ +| **Sources** | ++------------------------------+-------------------------------------------------------------------------------+ +| | Sources root | | ~/coriolis-2.x/src | +| | **under git** | | ~/coriolis-2.x/src/coriolis | ++------------------------------+-------------------------------------------------------------------------------+ +| **Architecture Dependant Build** | ++------------------------------+-------------------------------------------------------------------------------+ +| | Linux, SL 7, 64b | | ~/coriolis-2.x/Linux.el7_64/Release.Shared/build/ | +| | Linux, SL 6, 32b | | ~/coriolis-2.x/Linux.slsoc6x/Release.Shared/build/ | +| | Linux, SL 6, 64b | | ~/coriolis-2.x/Linux.slsoc6x_64/Release.Shared/build/ | +| | Linux, Fedora, 64b | | ~/coriolis-2.x/Linux.fc_64/Release.Shared/build/ | +| | Linux, Fedora, 32b | | ~/coriolis-2.x/Linux.fc/Release.Shared/build/ | +| | FreeBSD 8, 32b | | ~/coriolis-2.x/FreeBSD.8x.i386/Release.Shared/build/ | +| | FreeBSD 8, 64b | | ~/coriolis-2.x/FreeBSD.8x.amd64/Release.Shared/build/ | +| | Windows 7, 32b | | ~/coriolis-2.x/Cygwin.W7/Release.Shared/build/ | +| | Windows 7, 64b | | ~/coriolis-2.x/Cygwin.W7_64/Release.Shared/build/ | +| | Windows 8.x, 32b | | ~/coriolis-2.x/Cygwin.W8/Release.Shared/build/ | +| | Windows 8.x, 64b | | ~/coriolis-2.x/Cygwin.W8_64/Release.Shared/build/ | ++------------------------------+-------------------------------------------------------------------------------+ +| **Architecture Dependant Install** | ++------------------------------+-------------------------------------------------------------------------------+ +| Linux, SL 6, 32b | ~/coriolis-2.x/Linux.slsoc6x/Release.Shared/install/ | ++------------------------------+-------------------------------------------------------------------------------+ +| **FHS Compliant Structure under Install** | ++------------------------------+-------------------------------------------------------------------------------+ +| | Binaries | | .../install/bin | +| | Libraries (Python) | | .../install/lib | +| | Include by tool | | .../install/include/coriolis2// | +| | Configuration files | | .../install/etc/coriolis2/ | +| | Doc, by tool | | .../install/share/doc/coriolis2/en/html/ | ++------------------------------+-------------------------------------------------------------------------------+ + +.. note:: *Alternate build types:* the ``Release.Shared`` means an optimized build + with shared libraries. But there are also available ``Static`` instead of ``Shared`` + and ``Debug`` instead of ``Release`` and any combination of them. + + ``Static`` do not work because I don't know yet to mix statically linked binaries + and Python modules (which must be dynamic). + +|newpage| + + +Building Coriolis +~~~~~~~~~~~~~~~~~ + +First step is to install the prerequisites. Currently, only RapidJSON_. +As RapidJSON is evolving fast, if you encounter compatibility problems, +the exact version we compiled against is given below. :: + + dummy@lepka:~$ mkdir -p ~/coriolis-2.x/src/support + dummy@lepka:~$ cd ~/coriolis-2.x/src/support + dummy@lepka:~$ git clone http://github.com/miloyip/rapidjson + dummy@lepka:~$ git checkout ec322005072076ef53984462fb4a1075c27c7dfd + +The second step is to create the source directory and pull the |git| repository: :: + + dummy@lepka:~$ mkdir -p ~/coriolis-2.x/src + dummy@lepka:~$ cd ~/coriolis-2.x/src + dummy@lepka:~$ git clone https://www-soc.lip6.fr/git/coriolis.git + +Third and final step, build & install: :: + + dummy@lepka:src$ ./bootstrap/ccb.py --project=support \ + --project=coriolis \ + --make="-j4 install" + dummy@lepka:src$ ./bootstrap/ccb.py --project=support \ + --project=coriolis \ + --doc --make="-j1 install" + +We need to separate to perform a separate installation of the documentation because it +do not support to be generated with a parallel build. So we compile & install in a first +stage in ``-j4`` (or whatever) then we generate the documentation in ``-j1`` + +Under |RHEL6| or clones, you must build using the |devtoolset2|: :: + + dummy@lepka:src$ ./bootstrap/ccb.py --project=coriolis \ + --devtoolset-2 --make="-j4 install" + +If you want to uses Qt 5 instead of Qt 4, you may add the ``--qt5`` argument. + +The complete list of |ccb| functionalities can be accessed with the ``--help`` argument. +It also may be run in graphical mode (``--gui``). + + +Building the Devel Branch +------------------------- + +In the |Coriolis| |git| repository, two branches are present: + +* The :cb:`master` branch, which contains the latest stable version. This is the + one used by default if you follow the above instructions. + +* The :cb:`devel` branch, which obviously contains the latest commits from the + development team. To use it instead of the :cb:`master` one, do the following + command just after the first step: :: + + dummy@lepka:~$ git checkout devel + dummy@lepka:src$ ./bootstrap/ccb.py --project=coriolis \ + --make="-j4 install" --debug + + Be aware that it may requires newer versions of the dependencies and may introduce + incompatibilites with the stable version. + + In the (unlikely) event of a crash of |cgt|, as it is a |Python| script, the right + command to run |gdb| on it is: :: + + dummy@lepka:work$ gdb python core.XXXX + +|newpage| + + +Additionnal Requirement under |MacOS| +------------------------------------- + +|Coriolis| make uses of the :cb:`boost::python` module, but the |macports| |boost| +seems unable to work with the |Python| bundled with |MacOS|. So you have to install +both of them from |macports|: :: + + dummy@macos:~$ port install boost +python27 + dummy@macos:~$ port select python python27 + dummy@macos:-$ export DYLD_FRAMEWORK_PATH=/opt/local/Library/Frameworks + +The last two lines tell |MacOS| to use the |Python| from |macports| and *not* from +the system. + +Then proceed with the generic install instructions. + + +Packaging Coriolis +~~~~~~~~~~~~~~~~~~ + +Packager should not uses |ccb|, instead ``bootstrap/Makefile.package`` is provided +to emulate a top-level ``autotool`` makefile. Just copy it in the root of the +|Coriolis| git repository (``~/corriolis-2.x/src/coriolis/``) and build. + +Sligthly outaded packaging configuration files can also be found under ``bootstrap/``: + +* ``bootstrap/coriolis2.spec.in`` for |rpm| based distributions. +* ``bootstrap/debian`` for |Debian| based distributions. + + +Hooking up into |Alliance| +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +|Coriolis| relies on |Alliance| for the cell libraries. So after installing or +packaging, you must configure it so that it can found those libraries. + +This is done by editing the one variable :cb:`cellsTop` in the |Alliance| helper +(see :ref:`Alliance Helper`). This variable must point to the directory of the +cells libraries. In a typical installation, this is generally +:cb:`/usr/share/alliance/cells`. + + +Setting up the Environment (coriolisEnv.py) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To simplify the tedious task of configuring your environment, a helper is provided +in the ``bootstrap`` source directory (also installed in the directory +``.../install/etc/coriolis2/``) : :: + + ~/coriolis-2.x/src/coriolis/bootstrap/coriolisEnv.py + +Use it like this: :: + + dummy@lepka:~> eval `~/coriolis-2.x/src/coriolis/bootstrap/coriolisEnv.py` + +.. note:: **Do not call that script in your environement initialisation.** + When used under |RHEL6| or clones, it needs to be run in the |devtoolset2| + environement. The script then launch a new shell, which may cause an + infinite loop if it's called again in, say :cb:`~/.bashrc`. + + Instead you may want to create an alias: :: + + alias c2r='eval "`~/coriolis-2.x/src/coriolis/bootstrap/coriolisEnv.py`"' diff --git a/documentation/UsersGuide/LaTeX_defs.rst b/documentation/UsersGuide/LaTeX_defs.rst deleted file mode 100644 index 8d48f8e1..00000000 --- a/documentation/UsersGuide/LaTeX_defs.rst +++ /dev/null @@ -1,50 +0,0 @@ - -.. -*- Mode: rst -*- - -.. role:: raw-latex(raw) - :format: latex - -.. URLs that changes between the various backends. -.. _Coriolis Tools Documentation: https://www-soc.lip6.fr/sesi-docs/coriolis2-docs/coriolis2/ -.. _Stratus Documentation: https://www-soc.lip6.fr/sesi-docs/coriolis2-docs/coriolis2/en/html/stratus/index.html - -.. |DONE| replace:: :raw-latex:`\marginpar{\fbox{\small\ding{56}}}` - -.. For LaTeX/PDF backend. -.. |rightarrow| replace:: :raw-latex:`$\rightarrow$` -.. |menu_P&R| replace:: :raw-latex:`\fbox{\textsf{\textbf{{P\&R}}}}` -.. |menu_StepByStep| replace:: :raw-latex:`\fbox{\textsf{\textbf{{\underline{S}tep by Step}}}}` -.. |menu_KiteSaveGlobalRouting| replace:: :raw-latex:`\fbox{\textsf{\textbf{{\underline{S}ave Global Routing}}}}` -.. |menu_KiteLoadGlobalRouting| replace:: :raw-latex:`\fbox{\textsf{\textbf{{\underline{L}oad Global Routing}}}}` -.. |menu_KiteGlobalRoute| replace:: :raw-latex:`\fbox{\textsf{\textbf{{\underline{G}lobal Route}}}}` -.. |menu_KiteDetailedRoute| replace:: :raw-latex:`\fbox{\textsf{\textbf{{\underline{D}etailed Route}}}}` -.. |menu_KiteDetailedPreRoute| replace:: :raw-latex:`\fbox{\textsf{\textbf{{\underline{D}etailed Pre-Route}}}}` -.. |menu_KiteFinalizeRoute| replace:: :raw-latex:`\fbox{\textsf{\textbf{{\underline{F}inalize Route}}}}` - -.. Stand-alone images. -.. |ViewerSnapshot_1| replace:: :raw-latex:`\begin{center}\fbox{\includegraphics[width=.7\textwidth]{./images/Viewer-1.eps}}\end{center}` -.. |ControllerSnapshot_1| replace:: :raw-latex:`\begin{center}\includegraphics[width=.7\textwidth]{./images/Controller-1.eps}\end{center}` -.. |ControllerLook_1| replace:: :raw-latex:`\begin{center}\includegraphics[width=.7\textwidth]{./images/Controller-Look-1.eps}\end{center}` -.. |ControllerFilter_1| replace:: :raw-latex:`\begin{center}\includegraphics[width=.7\textwidth]{./images/Controller-Filter-1.eps}\end{center}` -.. |ControllerLayersGos_1| replace:: :raw-latex:`\begin{center}\includegraphics[width=.7\textwidth]{./images/Controller-LayersGos-1.eps}\end{center}` -.. |ControllerNetlist_1| replace:: :raw-latex:`\begin{center}\includegraphics[width=.7\textwidth]{./images/Controller-Netlist-1.eps}\end{center}` -.. |ViewerNetlist_1| replace:: :raw-latex:`\begin{center}\includegraphics[width=.7\textwidth]{./images/Viewer-Netlist-1.eps}\end{center}` -.. |ControllerSelection_1| replace:: :raw-latex:`\begin{center}\includegraphics[width=.7\textwidth]{./images/Controller-Selection-1.eps}\end{center}` -.. |ControllerInspector_1| replace:: :raw-latex:`\begin{center}\includegraphics[width=.7\textwidth]{./images/Controller-Inspector-1.eps}\end{center}` -.. |ControllerInspector_2| replace:: :raw-latex:`\begin{center}\includegraphics[width=.7\textwidth]{./images/Controller-Inspector-2.eps}\end{center}` -.. |ControllerInspector_3| replace:: :raw-latex:`\begin{center}\includegraphics[width=.7\textwidth]{./images/Controller-Inspector-3.eps}\end{center}` -.. |ControllerSettings_1| replace:: :raw-latex:`\begin{center}\includegraphics[width=.7\textwidth]{./images/Controller-Settings-1.eps}\end{center}` -.. |CoriolisSoftSchema| replace:: :raw-latex:`\begin{center}\includegraphics[width=.7\textwidth]{./images/Coriolis-Soft-Schema.eps}\end{center}` -.. |ChipStructure-1| replace:: :raw-latex:`\begin{center}\includegraphics[width=.95\textwidth]{./images/chip-structure-1.eps}\end{center}` -.. |Etesian-1| replace:: :raw-latex:`\begin{center}\includegraphics[width=.95\textwidth]{./images/etesian-1.eps}\end{center}` - -.. |BigMouse| image:: ./images/ComputerMouse.eps - :scale: 25% - -.. Direct LaTeX commands encapsulation. -.. |dotfill| replace:: :raw-latex:`\dotfill` -.. |noindent| replace:: :raw-latex:`\noindent` -.. |medskip| replace:: :raw-latex:`\medskip` -.. |newpage| replace:: :raw-latex:`\newpage` -.. |br| replace:: :raw-latex:`\\` - diff --git a/documentation/UsersGuide/LicenseCredits.rst b/documentation/UsersGuide/LicenseCredits.rst new file mode 100644 index 00000000..3cf0eefe --- /dev/null +++ b/documentation/UsersGuide/LicenseCredits.rst @@ -0,0 +1,55 @@ +.. -*- Mode: rst -*- + +.. include:: ../etc/definitions.rst + + +Credits & License +================= + +.. raw:: html + +

Hurricane + Rémy Escassut & + Christian Masson

+
+

Etesian + Gabriel Gouvine

+
+

Stratus + Sophie Belloeil

+
+

Knik + Damien Dupuis

+
+

Kite, + Unicorn + Jean-Paul Chaput

+
+ + +.. raw:: latex + + \begin{center}\begin{minipage}[t]{.8\textwidth} + \noindent\DUrole{sc}{Hurricane} \dotfill Rémy \DUrole{sc}{Escassut} \& + Christian \DUrole{sc}{Masson} \\ + \noindent\DUrole{sc}{Etesian} \dotfill Gabriel \DUrole{sc}{Gouvine} \\ + \noindent\DUrole{sc}{Stratus} \dotfill Sophie \DUrole{sc}{Belloeil} \\ + \noindent\DUrole{sc}{Knik} \dotfill Damien \DUrole{sc}{Dupuis} \\ + \noindent\DUrole{sc}{Kite}, + \DUrole{sc}{Unicorn} \dotfill Jean-Paul \DUrole{sc}{Chaput} \\ + \end{minipage}\end{center} + + +|medskip| + +The |Hurricane| data-base is copyright© |Bull| 2000-2016 and is +released under the terms of the |LGPL| license. All other tools are +copyright© |UPMC| 2008-2016 and released under the |GPL| +license. + +Others important contributors to |Coriolis| are Christophe |Alexandre|, +Hugo |Clement|, Marek |Sroka| and Wu |Yifei|. + +The |Knik| router makes use of the |Flute| software, which is +copyright© Chris C. N. |Chu| from the Iowa State University +(http://home.eng.iastate.edu/~cnchu/). diff --git a/documentation/UsersGuide/Pygments.css b/documentation/UsersGuide/Pygments.css deleted file mode 100644 index de3dc8fe..00000000 --- a/documentation/UsersGuide/Pygments.css +++ /dev/null @@ -1,41 +0,0 @@ -div.codeblock { font-size: 90%; - margin: 10pt; - padding: 5pt; - border: dashed; - border-width: thin; - background-color: #ffffcc; - border-color: #fc8676; - } -.codeblock * .hll { background-color: #ffffcc } -.codeblock * .c { color: #008000 } /* Comment */ -.codeblock * .err { border: 1px solid #FF0000 } /* Error */ -.codeblock * .k { color: #0000ff } /* Keyword */ -.codeblock * .cm { color: #008000 } /* Comment.Multiline */ -.codeblock * .cp { color: #0000ff } /* Comment.Preproc */ -.codeblock * .c1 { color: #008000 } /* Comment.Single */ -.codeblock * .cs { color: #008000 } /* Comment.Special */ -.codeblock * .ge { font-style: italic } /* Generic.Emph */ -.codeblock * .gh { font-weight: bold } /* Generic.Heading */ -.codeblock * .gp { font-weight: bold } /* Generic.Prompt */ -.codeblock * .gs { font-weight: bold } /* Generic.Strong */ -.codeblock * .gu { font-weight: bold } /* Generic.Subheading */ -.codeblock * .kc { color: #0000ff } /* Keyword.Constant */ -.codeblock * .kd { color: #0000ff } /* Keyword.Declaration */ -.codeblock * .kn { color: #0000ff } /* Keyword.Namespace */ -.codeblock * .kp { color: #0000ff } /* Keyword.Pseudo */ -.codeblock * .kr { color: #0000ff } /* Keyword.Reserved */ -.codeblock * .kt { color: #2b91af } /* Keyword.Type */ -.codeblock * .s { color: #a31515 } /* Literal.String */ -.codeblock * .nc { color: #2b91af } /* Name.Class */ -.codeblock * .ow { color: #0000ff } /* Operator.Word */ -.codeblock * .sb { color: #a31515 } /* Literal.String.Backtick */ -.codeblock * .sc { color: #a31515 } /* Literal.String.Char */ -.codeblock * .sd { color: #a31515 } /* Literal.String.Doc */ -.codeblock * .s2 { color: #a31515 } /* Literal.String.Double */ -.codeblock * .se { color: #a31515 } /* Literal.String.Escape */ -.codeblock * .sh { color: #a31515 } /* Literal.String.Heredoc */ -.codeblock * .si { color: #a31515 } /* Literal.String.Interpol */ -.codeblock * .sx { color: #a31515 } /* Literal.String.Other */ -.codeblock * .sr { color: #a31515 } /* Literal.String.Regex */ -.codeblock * .s1 { color: #a31515 } /* Literal.String.Single */ -.codeblock * .ss { color: #a31515 } /* Literal.String.Symbol */ diff --git a/documentation/UsersGuide/Releases.rst b/documentation/UsersGuide/Releases.rst new file mode 100644 index 00000000..c86243a1 --- /dev/null +++ b/documentation/UsersGuide/Releases.rst @@ -0,0 +1,102 @@ +.. -*- Mode: rst -*- + +.. include:: ../etc/definitions.rst + + +Release Notes +============= + +Release 1.0.1475 +~~~~~~~~~~~~~~~~ + +This is the first preliminary release of the |Coriolis2| framework. + +This release mainly ships the global router |Knik| and the detailed router +|Kite|. Together they aim to replace the |Alliance| |Nero| router. +Unlike |Nero|, |Kite| is based on an innovating routing modeling and ad-hoc +algorithm. Although it is released under |GPL| license, the source code +will be avalaible later. +|medskip| + + +|noindent| Contents of this release: + +1. A graphical user interface (viewer only). +2. The |Knik| global router. +3. The |Kite| detailed router. + +|noindent| Supported input/output formats: + +* |Alliance| |vst| (netlist) & |ap| (physical) formats. +* Even if there are some references to the |Cadence| |LEFDEF| format, its + support is not included because it depends on a library only available + to |Si2| affiliated members. + + +Release 1.0.1963 +~~~~~~~~~~~~~~~~ + +Release 1963 is alpha. All the tools from |Coriolis1| have been ported into +this release. + +|noindent| Contents of this release: + +#. The |Stratus| netlist capture language (|GenLib| replacement). +#. The |Mauka| placer (still contains bugs). +#. A graphical user interface (viewer only). +#. The |Knik| global router. +#. The |Kite| detailed router. +#. Partially implemented python support for configuration files + (alternative to |XML|). +#. A documentation (imcomplete/obsoleted in |Hurricane|'s case). + + +Release 1.0.2049 +~~~~~~~~~~~~~~~~ + +Release `2049` is Alpha. + +|noindent| Changes of this release: + +#. The |Hurricane| documentation is now accurate. Documentation + for the Cell viewer and |CRLcore| has been added. +#. More extensive Python support for all the components of + |Coriolis|. +#. Configuration is now completly migrated under Python. + |XML| loaders can still be useds for compatibilty. +#. The |cgt| main has been rewritten in Python. + + +Release v2.0.1 +~~~~~~~~~~~~~~ + +#. Migrated the repository from |svn| to |git|, and release complete sources. + As a consequence, we drop the distribution packaging support and give + public read-only access to the repository. +#. Deep rewrite of the |Katabatic| database and |Kite| detailed router, + achieve a speedup factor greater than 20... + + +Release v2.1 +~~~~~~~~~~~~ + +#. Replace the old simulated annealing placer |Mauka| by the analytical placer + |Etesian| and its legalization and detailed placement tools. +#. Added a Blif format parser to process circuits generated by the Yosys and ABC + logic synthetizers. +#. The multiples user defined configuration files are now grouped under + a common hidden (dot) directory ``.coriolis2`` and the file extension + is back from ``.conf`` to ``.py``. + +.. #. Under |RHEL7| / |SL7|, there is a known bug in the graphical visualizer. +.. When shifting to the left, the right-half part of the screen gets +.. badly redrawn. Uses |CTRL_L| to refresh. It will be corrected as soon +.. as possible. + + +**Release v2.2** +~~~~~~~~~~~~~~~~ + +#. Added JSON import/export of the whole Hurricane DataBase. Two save mode + are supported: *Cell* mode (standalone) or *Blob* mode, which dump the + whole design down and including the standard cells. diff --git a/documentation/UsersGuide/ScriptsPlugins.rst b/documentation/UsersGuide/ScriptsPlugins.rst new file mode 100644 index 00000000..2e9e3d0c --- /dev/null +++ b/documentation/UsersGuide/ScriptsPlugins.rst @@ -0,0 +1,332 @@ +.. -*- Mode: rst -*- + +.. include:: ../etc/definitions.rst + +.. URLs that changes between the various backends. +.. _Stratus Documentation: file:///usr/share/doc/coriolis2/en/html/stratus/index.html + +.. |ChipStructure-1| image:: ./images/chip-structure-1.png + :alt: Chip Top Structure + :align: middle + :width: 90% + + +.. _Python Interface to Coriolis: + +Python Interface for |Hurricane| / |Coriolis| +============================================= + +The (almost) complete interface of |Hurricane| is exported as a |Python| module +and some part of the other components of |Coriolis| (each one in a separate +module). The interface has been made to mirror as closely as possible the +C++ one, so the C++ doxygen documentation could be used to write code with +either languages. + +`Summary of the C++ Documentation `_ + +A script could be run directly in text mode from the command line or through +the graphical interface (see :ref:`Python Scripts in Cgt`). + +Asides for this requirement, the python script can contain anything valid +in |Python|, so don't hesitate to use any package or extention. + +Small example of Python/Stratus script: :: + + from Hurricane import * + from Stratus import * + + def doSomething (): + # ... + return + + def ScriptMain ( **kw ): + editor = None + if kw.has_key('editor') and kw['editor']: + editor = kw['editor'] + stratus.setEditor( editor ) + + doSomething() + return + + if __name__ == "__main__" : + kw = {} + success = ScriptMain( **kw ) + shellSuccess = 0 + if not success: shellSuccess = 1 + + sys.exit( shellSuccess ) + ScriptMain () + +This typical script can be executed in two ways: + +#. Run directly as a |Python| script, thanks to the :: + + if __name__ == "__main__" : + + part (this is standart |Python|). It is a simple adapter that will + calls :cb:`ScriptMain()`. +#. Through |cgt|, either in text or graphical mode. In that case, the + :cb:`ScriptMain()` is directly called trough a sub-interpreter. + The arguments of the script are passed through the ``**kw`` dictionnary. + + +----------------------+-----------------------------------------------+ + | \*\*kw Dictionnary | + +----------------------+-----------------------------------------------+ + | Parameter Key/Name | Contents type | + +======================+===============================================+ + | ``'cell'`` | A Hurricane cell on which to work. Depending | + | | on the context, it may be ``None``. | + | | For example, when run from |cgt|, it the cell | + | | currently loaded in the viewer, if any. | + +----------------------+-----------------------------------------------+ + | ``'editor'`` | The viewer from which the script is run, when | + | | lauched through |cgt|. | + +----------------------+-----------------------------------------------+ + + +Plugins +~~~~~~~ + +Plugins are |Python| scripts specially crafted to integrate with |cgt|. +Their entry point is a :cb:`ScriptMain()` method as described in +`Python Interface to Coriolis`_. They can be called by user scripts +through this method. + + + +Chip Placement +-------------- + +Automatically perform the placement of a complete chip. This plugin, as well +as the other P&R tools expect a specific top-level hierarchy for the design. +The top-level hierarchy must contains the instances of all the I/O pads and +**exactly one** instance of the chip's core model. + +|bcenter| |ChipStructure-1| |ecenter| + +The designer must provide a configuration file that define the rules for the +placement of the top-level hierarchy (that is, the pads and the core). +This file must be named after the chip's name, by appending ``_chip.py`` +(obviously, it is a |Python| file). For instance if the chip netlist file +is called ``amd2901_crl.vst``, then the configuration file must be named +``amd2901_crl_chip.vst``. + +Example of chip placement configuration file (for ``AM2901``): :: + + chip = \ + { 'pads.south' : [ 'p_a3' , 'p_a2' , 'p_a1' , 'p_r0' + , 'p_vddick0', 'p_vssick0', 'p_a0' , 'p_i6' + , 'p_i8' , 'p_i7' , 'p_r3' ] + , 'pads.east' : [ 'p_zero' , 'p_i0' , 'p_i1' , 'p_i2' + , 'p_vddeck0', 'p_vsseck0', 'p_q3' , 'p_b0' + , 'p_b1' , 'p_b2' , 'p_b3' ] + , 'pads.north' : [ 'p_noe' , 'p_y3' , 'p_y2' , 'p_y1' + , 'p_y0' , 'p_vddeck1', 'p_vsseck1', 'p_np' + , 'p_ovr' , 'p_cout' , 'p_ng' ] + , 'pads.west' : [ 'p_cin' , 'p_i4' , 'p_i5' , 'p_i3' + , 'p_ck' , 'p_d0' , 'p_d1' , 'p_d2' + , 'p_d3' , 'p_q0' , 'p_f3' ] + , 'core.size' : ( 1500, 1500 ) + , 'chip.size' : ( 3000, 3000 ) + , 'chip.clockTree' : True + } + +The file must contain *one dictionnary* named ``chip``. + ++----------------------+-------------------------------------------------------+ +| Chip Dictionnary | ++----------------------+-------------------------------------------------------+ +| Parameter Key/Name | Value/Contents type | ++======================+=======================================================+ +| ``'pad.south'`` | Ordered list (left to right) of pad instances names | +| | to put on the south side of the chip | ++----------------------+-------------------------------------------------------+ +| ``'pad.east'`` | Ordered list (down to up) of pad instances names | +| | to put on the east side of the chip | ++----------------------+-------------------------------------------------------+ +| ``'pad.north'`` | Ordered list (left to right) of pad instances names | +| | to put on the north side of the chip | ++----------------------+-------------------------------------------------------+ +| ``'pad.west'`` | Ordered list (down to up) of pad instances names | +| | to put on the west side of the chip | ++----------------------+-------------------------------------------------------+ +| ``'core.size'`` | The size of the core (to be used by the placer) | ++----------------------+-------------------------------------------------------+ +| ``'chip.size'`` | The size of the whole chip. The sides must be great | +| | enough to accomodate all the pads | ++----------------------+-------------------------------------------------------+ +| ``'chip.clockTree'`` | Whether to generate a clock tree or not. This calls | +| | the ClockTree plugin | ++----------------------+-------------------------------------------------------+ + +Configuration parameters, defaults are defined in ``etc/coriolis2//plugins.conf``. + ++-----------------------------------+------------------+----------------------------+ +| Parameter Identifier | Type | Default | ++===================================+==================+============================+ +| **Chip Plugin Parameters** | ++-----------------------------------+------------------+----------------------------+ +|``chip.block.rails.count`` | TypeInt | :cb:`5` | +| +------------------+----------------------------+ +| | The minimum number of rails around the core | +| | block. Must be odd and suppérior to 5. | +| | One rail for the clock and at least two pairs | +| | of power/grounds | ++-----------------------------------+------------------+----------------------------+ +|``chip.block.rails.hWidth`` | TypeInt | :cb:`12` | +| +------------------+----------------------------+ +| | The horizontal with of the rails | ++-----------------------------------+------------------+----------------------------+ +|``chip.block.rails.vWidth`` | TypeInt | :cb:`12` | +| +------------------+----------------------------+ +| | The vertical with of the rails | ++-----------------------------------+------------------+----------------------------+ +|``chip.block.rails.hSpacing`` | TypeInt | :cb:`6` | +| +------------------+----------------------------+ +| | The spacing, *edge to edge* of two adjacent | +| | horizontal rails | ++-----------------------------------+------------------+----------------------------+ +|``chip.block.rails.vSpacing`` | TypeInt | :cb:`6` | +| +------------------+----------------------------+ +| | The spacing, *edge to edge* of two adjacent | +| | vertical rails | ++-----------------------------------+------------------+----------------------------+ +|``chip.pad.pck`` | TypeString | :cb:`pck_px` | +| +------------------+----------------------------+ +| | The model name of the pad connected to the | +| | chip external clock | ++-----------------------------------+------------------+----------------------------+ +|``chip.pad.pvddeck`` | TypeString | :cb:`pvddeck_px` | +| +------------------+----------------------------+ +| | The model name of the pad connected to the | +| | ``vdde`` (external power) and suppling it to | +| | the core | ++-----------------------------------+------------------+----------------------------+ +|``chip.pad.pvsseck`` | TypeString | :cb:`pvsseck_px` | +| +------------------+----------------------------+ +| | The model name of the pad connected to the | +| | ``vsse`` (external ground) and suppling it to | +| | the core | ++-----------------------------------+------------------+----------------------------+ +|``chip.pad.pvddick`` | TypeString | :cb:`pvddick_px` | +| +------------------+----------------------------+ +| | The model name of the pad connected to the | +| | ``vddi`` (internal power) and suppling it to | +| | the core | ++-----------------------------------+------------------+----------------------------+ +|``chip.pad.pvssick`` | TypeString | :cb:`pvssick_px` | +| +------------------+----------------------------+ +| | The model name of the pad connected to the | +| | ``vssi`` (internal ground) and suppling it to | +| | the core | ++-----------------------------------+------------------+----------------------------+ + +.. note:: + If no clock tree is generated, then the clock rail is *not* created. + So even if the requested number of rails ``chip.block.rails.count`` is, say 5, + only four rails (2* ``power``, 2* ``ground``) will be generateds. + + +Clock Tree +---------- + +Insert a clock tree into a block. The clock tree uses the H strategy. +The clock net is splitted into sub-nets, one for each branch of the +tree. + +* On **chips** design, the sub-nets are createds in the model of the + core block (then trans-hierarchically flattened to be shown at + chip level). +* On **blocks**, the sub nets are created directly in the top block. +* The sub-nets are named according to a simple geometrical scheme. + A common prefix ``ck_htree``, then one postfix by level telling + on which quarter of plane the sub-clock is located: + + #. ``_bl``: bottom left plane quarter. + #. ``_br``: bottom right plane quarter. + #. ``_tl``: top left plane quarter. + #. ``_tr``: top right plane quarter. + + We can have ``ck_htree_bl``, ``ck_htree_bl_bl``, ``ch_htree_bl_tl`` and so on. + +The clock tree plugin works in four steps: + +#. Build the clock tree: creates the top-block abutment box, compute the + levels of H tree neededs and place the clock buffers. +#. Once the clock buffers are placed, calls the placer (|etesian|) to place + the ordinary standart cells, whithout disturbing clock H-tree buffers. +#. At this point we know the exact positions of all the DFFs, so we can + connect them to the nearest H-tree leaf clock signal. +#. Leaf clock signals that are not connecteds to any DFFs are removed. + +Netlist reorganisation: + +* Obviously the top block or chip core model netlist is modificated to + contains all the clock sub-nets. The interface is *not* changed. +* If the top block contains instances of other models *and* those models + contains DFFs that get re-connecteds to the clock sub-nets (from the + top level). Change both the model netlist and interface to propagate + the relevant clock sub-nets to the instanciated model. The new model + with the added clock signal is renamed with a ``_clocked`` suffix. + For example, the sub-block model ``ram.vst`` will become ``ram_clocked.vst``. + +.. note:: + If you are to re-run the clock tree plugin on a netlist, be careful + to erase any previously generated ``_clocked`` file (both netlist and + layout: ``rm *.clocked.{ap,vst}``). And restart |cgt| to clear it's + memory cache. + +Configuration parameters, defaults are defined in ``etc/coriolis2//plugins.conf``. + ++-----------------------------------+------------------+----------------------------+ +| Parameter Identifier | Type | Default | ++===================================+==================+============================+ +| **ClockTree Plugin Parameters** | ++-----------------------------------+------------------+----------------------------+ +|``clockTree.minimumSide`` | TypeInt | :cb:`300` | +| +------------------+----------------------------+ +| | The minimum size below which the clock tree | +| | will stop to perform quadri-partitions | ++-----------------------------------+------------------+----------------------------+ +|``clockTree.buffer`` | TypeString | :cb:`buf_x2` | +| +------------------+----------------------------+ +| | The buffer model to use to drive sub-nets | ++-----------------------------------+------------------+----------------------------+ +|``clockTree.placerEngine`` | TypeString | :cb:`Etesian` | +| +------------------+----------------------------+ +| | The placer to use. Other value is ``Mauka`` | +| | the simulated annealing placer which will go | +| | into retirement very soon | ++-----------------------------------+------------------+----------------------------+ + + +Recursive-Save (RSave) +---------------------- + +Perform a recursive top down save of all the models from the top cell +loaded in |cgt|. Force a write of any non-terminal model. This plugin is used +by the clock tree plugin after the netlist clock sub-nets creation. + + +A Simple Example: AM2901 +~~~~~~~~~~~~~~~~~~~~~~~~ + +To illustrate the capabilities of |Coriolis| tools and |Python| scripting, a small +example, derived from the |Alliance| :cb:`AM2901` is supplied. + +This example contains only the synthetized netlists and the :cb:`doChip.py` script +which perform the whole P&R of the design. + +You can generate the chip using one of the following method: + +#. **Command line mode:** directly run the script: :: + + dummy@lepka:AM2901$ ./doChip -V --cell=amd2901 + +#. **Graphic mode:** launch |cgt|, load chip netlist ``amd2901`` (the top cell) + then run the |Python| script :cb:`doChip.py`. + +.. note:: + Between two consecutive run, be sure to erase the netlist/layout generateds: :: + + dummy@lepka:AM2901$ rm *_clocked*.vst *.ap diff --git a/documentation/UsersGuide/SoC.css b/documentation/UsersGuide/SoC.css deleted file mode 100644 index 4bca9453..00000000 --- a/documentation/UsersGuide/SoC.css +++ /dev/null @@ -1,796 +0,0 @@ - -html, body, th, td, tr, p, li, h1, h2, h3, h4, h5, h6 { - font-size: 96%; - font-family: "Open Sans", verdana, sans-serif; -} - -body { - color: black; - background: white; - /* - background: #09550B; - background-color: white; - */ - background-position: top left; - background-attachment: fixed; - background-repeat: no-repeat; - margin: 0 0 0 0; - padding: 20pt; - width: 550pt; - margin-right: 10%; - margin-left: 30%; - -moz-box-shadow: 4px 4px 5px 3px #ccc; - -webkit-box-shadow: 4px 4px 5px 3px #ccc; - box-shadow: 4px 4px 5px 3px #ccc; -} - -body.gsummary { - margin-right: 10%; - margin-left: 10%; -} - -h1, h2, h3, h4, h5, h6 { font-family: "Open Sans", verdana, sans-serif; } -h1 { text-align: center; - border-top: 2px solid #09550b; - border-bottom: 2px solid #09550b; - padding-top: 7pt; - padding-bottom: 7pt; - } -h2, h3, h4, h5, h6 { text-align: left; } -h1, h2, h3 { font-family: "Open Sans"; - } -h1 { font-weight: normal; font-size: 170%; padding-top: 7pt; margin-top: 25pt; } -h2 { font-weight: normal; font-size: 140%; padding-top: 7pt; margin-top: 25pt; } -h3 { font-weight: bold; font-size: 118%; padding-top: 7pt; margin-top: 25pt; } -h4 { font-weight: bold; font-size: 100%; } -h5 { font-style: italic; font-size: 100%; } -h6 { font-variant: small-caps; font-size: 100%; } - -body.gsummary h1 { text-align: center; font-size: 220%; } - -h1 a:link { border-bottom: 0px; } - - -hr { - color: #09550b; - border: 1px dotted #09550b; - border-style: none none dotted; - padding-top: 10pt; - padding-bottom: 10pt; -} - -div#contents { - margin: 30pt; - padding: 2pt 10pt; - background-color: #fff676; -} - -div#centered { - margin-left: auto; - margin-right: auto; - text-align: center; -} - -p, li { - text-align: justify; -} - -.sc { - font-variant: small-caps; - font-size: 110%; -} - -pre, tt, code { - font-family: "courrier", "andale mono", monospace; - font-size: 100%; - white-space: pre; -} - -tt { - color: #09550b; -} - -pre.wiki, div.code, pre.literal-block { - font-size: 90%; - padding: 5pt; - margin-left: 4%; - margin-right: 4%; - border: dashed; - border-width: thin; - border-color: #FC8676; - background-color: #FCFCE1; -} - -a:link, a:active { - font-weight: normal; - text-decoration: none; - color: #09550b; - border-bottom: 1px dotted #09550b; -} - -a:hover, a:focus, a:visited { - font-weight: normal; - font-style: italic; - text-decoration: none; - /* - color: #A40010; - border-bottom: 1px dotted #A40010; - */ - color: #09550b; - border-bottom: 1px dotted #09550b; -} - -body.gsummary a:link, a:active { - font-size: 140%; - font-weight: bold; - text-decoration: none; - color: #09550b; - border-bottom: none; - /* - border-bottom: 1px dotted #09550b; - */ -} - -body.gsummary a:hover, a:focus, a:visited { - font-size: 120%; - font-weight: bold; - font-style: italic; - text-decoration: none; - /* - color: #A40010; - border-bottom: 1px dotted #A40010; - */ - color: #09550b; - /* - border-bottom: 1px dotted #09550b; - */ -} - -p.credit { - margin-left: 10%; - margin-right: 10%; - font-size: 110%; -} - -p.credit span.left { - float: left; - white-space: nowrap; -} - -p.credit span.right { - float: right; - white-space: nowrap; -} - -img.addborder { - border: 1px solid black; -} - -div#header { - margin: 0px; - padding: 0pt; - background-color: white; - display: inline-block; - width: 100%; -} - -div#header_logo { - margin: 0px; - padding: 10px 0px 10px 12pt; - background-color: white; - width: 40%; - float: left; -} - -div#header_menus { - background-color: white; - width: 55%; - float: right; - padding-top: 60pt; - padding-right: 10pt; - text-align: right; - font-size: 80%; -} - -div#header_menus ul { - padding-top: 45pt; - list-style: none; - text-align: right; - font-size: 80%; -} - -div#header_menus li { - padding: 0pt; - margin: 0pt; - display: inline; - white-space: nowrap; -} - -/* -div#header_menus a { - border-left: 1px solid #d7d7d7; - padding: 0 .75em; -} - -div#header_menus a.first { - border-left: none; -} -*/ - -div#header a:link, div#header a:active, div#header a:visited { - margin: 0pt; - padding: 0pt 5pt; - font-weight: normal; - color: black; - text-decoration: none; - border-bottom: 1px solid black; - border-left: 0px; - border-right: 0px; -} - -div#header a:hover, div#header a:focus { - margin: 0pt; - padding: 0pt 5pt; - font-weight: normal; - color: black; - text-decoration: none; - border-bottom: 4px solid #09550b; - border-left: 0px; - border-right: 0px; -} - -div#header a.current:link, div#header a.current:active, div#header a.current:visited { - margin: 0pt; - padding: 0pt 5pt; - font-weight: bold; - font-style: normal; - font-size: 120%; - color: white; - text-decoration: none; - border-bottom: 4px solid #09550b; - border-left: 0px; - border-right: 0px; - background-color: #09550b; -} - -div#header a.current:hover, div#header a.current:focus { - margin: 0pt; - padding: 0pt 5pt; - font-weight: bold; - font-style: normal; - font-size: 120%; - color: white; - text-decoration: none; - border-bottom: 4px solid #09550b; - border-left: 0px; - border-right: 0px; - background-color: #09550b; -} - -div#header_ancestors { - padding: 4px 0px 4px 12pt; - background-color: #09550B; - color: white; -} - -div#header_ancestors ul, div#header_ancestors * li { - display: inline; - list-style-type: none; - padding: 0px 0px 0px 0pt; -} - -div#header_ancestors a:link, div#header_ancestors a:active, div#header_ancestors a:visited { - font-weight: bold; - color: white; - text-decoration: none; - border-bottom: 0px; -} - -div#header_ancestors a:hover, div#header_ancestors a:focus { - font-weight: bold; - color: white; - text-decoration: underline; -} - -div#footer { - margin: 0px; - padding: 0px; - border-top: 1px dotted #09550b; - background-color: white; - display: inline-block; - width: 100%; - text-align: right; -} - -div#searchform { - width: 80%; - background-color: #ccffcd; - padding: 15pt 10pt 15pt 10pt; - margin-top: 50pt; - margin-bottom: 50pt; - margin-left: auto; - margin-right: auto; - text-align: center; -} - -div#searchform input#id_q { - background-color: white; - border: 1px solid #09550b; - padding: 2pt; - width: 80%; - font-size: 110%; - font-weight: bold; -} - -span.queryref { - font-weight: bold; -} - -div#searchform ul { - list-style: none; -} - -div#searchform li { - display: inline; -} - -hr#search_vs_results { - color: #09550b; - border: 2px dotted #09550b; - border-style: none none dotted; - margin-top: 0pt; - margin-bottom: 20pt; -} - -div#search_results { - width: 85%; - margin: auto; -} - -div#sidebar hr#separator { - color: white; - border: 0px; - margin-top: 0pt; - margin-bottom: 20pt; -} - -img.footer-logo { - height: 24px; - padding: 0px 2px; -} - -hr#site_vs_page { - color: white; - border: 3px dotted white; - border-style: none none dotted; - margin-top: 20pt; - margin-bottom: 20pt; -} - -div#sidebar { - /* - background: #09550B; - background: #ccffcd; - */ - background: white; -} - -div#sidebar div#sitemenu, div#sidebar div#pagemenu { - /* - background: white; - */ - background: #09550b; - width: 85%; - margin: auto; - padding: 5pt 10pt; -} - -div#sidebar * li { - text-align: left; -} - -div#sidebar * ul { - list-style-type: square; - padding-left: 12pt; -} - -div#sitemenu ul { - list-style-type: none; - padding-left: 0pt; -} - -div#sitemenu ul ul { - list-style-type: none; - padding-left: 0pt; -} - -div#sitemenu ul ul ul { - list-style-type: square; - padding-left: 12pt; -} - -div#sitemenu ul li ul li { - padding-top: 3pt; - padding-bottom: 5pt; - border-top: 1px dotted white; -} - -div#sitemenu ul li ul li ul li { - border-top: none; - padding-top: 1pt; - padding-bottom: 1pt; -} - -div#sitemenu ul li a:link, -div#sitemenu ul li a:active, -div#sitemenu ul lu a:visited -{ - font-size: 140%; - font-weight: bold; - border-bottom: none; -} - -div#sitemenu ul li a:focus, -div#sitemenu ul lu a:hover -{ - font-size: 140%; - font-weight: bold; - font-style: italic; - border-bottom: none; -} - -div#sitemenu ul ul li a:link, -div#sitemenu ul ul li a:active, -div#sitemenu ul ul lu a:visited, -div#sitemenu ul ul li a:focus, -div#sitemenu ul ul lu a:hover -{ - font-size: 90%; - font-weight: normal; - border-bottom: none; -/*border-bottom: 1px dotted white;*/ -} - -div#pagemenu ul { - list-style-type: none; - padding-left: 0pt; -} - -div#pagemenu ul ul { - list-style-type: none; - padding-left: 0pt; -} - -div#pagemenu ul ul ul { - padding-left: 12pt; -} - -div#pagemenu ul li ul li { - padding-top: 3pt; - padding-bottom: 5pt; - border-top: 1px dotted white; -} - -div#pagemenu ul li ul li ul li { - border-top: none; - padding-top: 1pt; - padding-bottom: 1pt; -} - -div#pagemenu ul li a:link, -div#pagemenu ul li a:active, -div#pagemenu ul lu a:visited -{ - font-size: 120%; - font-weight: bold; - border-bottom: none; -} - -div#pagemenu ul li a:focus, -div#pagemenu ul lu a:hover -{ - font-size: 120%; - font-weight: bold; - font-style: italic; - border-bottom: none; -} - -div#pagemenu ul ul li a:link, -div#pagemenu ul ul li a:active, -div#pagemenu ul ul lu a:visited, -div#pagemenu ul ul li a:focus, -div#pagemenu ul ul lu a:hover -{ - font-size: 90%; - font-weight: normal; - border-bottom: none; - /* - border-bottom: 1px dotted white; - */ -} - - -div#sidebar ul.ancestor * li { - padding-top: 0pt; -} - -div#sidebar ul { - padding-bottom: 8pt; -} - -div#sidebar a:link, div#sidebar a:active, div#sidebar a:visited { - /* - font-weight: normal; - */ - color: white; - text-align: left; - text-decoration: none; - border-bottom: 1px dotted white; -} - -div#sidebar a:hover, div#sidebar a:focus { - /* - font-weight: normal; - */ - color: white; - text-align: left; - text-decoration: none; - border-bottom: 1px dotted white; -} - -div#main { - border-left: 1px solid #09550b; -} - -div#main ul#summary { - list-style-type: square; - padding-left: 12pt; - font-size: 14pt; -} - -div#main ul#summary * ul { - padding-left: 12pt; - padding-bottom: 14pt; - font-size: 95%; -} - -div.code * { - background-color: #FCFCE1; -} - -div.note { - margin: 8px 2% 0px 2%; - border: 1px none #fff01c; - border-left-width: 4px; - border-left-style: solid; - padding: 1px 10pt 1px 55px; - background: #fff676 url('./images/clipboard.png') no-repeat 0% 50%;; - font-size: 90% -} - -div.error { - margin: 8px 2% 0px 2%; - border: 1px none #dd0000; - border-left-width: 4px; - border-left-style: solid; - padding: 1px 10pt 1px 55px; - background: #ffddcc url('./images/i-core.png') no-repeat 0% 50%;; - font-size: 90% -} - -p.admonition-title { - font-weight: bold; -} - -div.topic { - margin: 5pt; - padding: 2pt 10pt; - background-color: fff676; -} - -div.topic p.first { - font-weight: bold; -} - -body.gsummary table { - border-collapse: collapse; - border-color: transparent; - width: 60%; - margin-left: auto; - margin-right: auto; -} - -/* -body.gsummary table th { -} -*/ - -body.gsummary table td { - border: none; -} - -/* -body.gsummary table tr td ul { - margin: 0pt; - border-left: 1px solid black; -} -*/ - -/* -body.gsummary table tr td ul li { - border-bottom: 2px dotted black; -} -*/ - -body.gsummary li { - padding: 0%; - list-style-type: none; -} - -body.gsummary ul { - padding: 0px 0px 10px 0px; - margin: 0%; - border-bottom: 1px dotted black; -} - -table.wiki th, table th { - color: black; - background: #FFFFCC; -} - -table.docutils { - margin-left: 5%; - margin-right: 5%; -} - -table.wiki, table.wiki th, table.wiki td { border: 1px solid black; } -table.wiki th * p { text-align: center; } -table.wiki * p { margin: 0pt; } -table.wiki * blockquote { margin: 0pt; } -table { border-collapse: collapse; } -table th, table td { border: 1px solid black; - padding: 2px 10px 2px 10px; } - -table.docinfo { - margin-top: 10pt; - margin-left: auto; - margin-right: 0pt; - border: 10px solid #303030; - border-collapse: collapse; - background: #303030; - font-size: 90%; - font-family: sans-serif; -} - -table.docinfo tr { - border-bottom: 1px dotted white; -} - -th.docinfo-name, -table.docinfo td, -table.docinfo td a:link, -table.docinfo td a:active, -table.docinfo td a:visited, -table.docinfo td a:focus, -table.docinfo td a:hover -{ - border: 0px solid white; - background: #303030; - color: white; - text-align: left; - font-weight: bold; -} - -th.docinfo-name { - font-weight: normal; -} - -table.docinfo td { - font-weight: bold; -} - -span.ul { - text-decoration: underline; -} - -* span.smallcaps { - /*font-variant: "small-caps";*/ - text-transform: "uppercase"; - font-size: "smaller"; -} - - -span.cb { - font-family: "andale mono", monospace; - font-weight: bold; - white-space: pre; -} - -span.fboxtt { - border: 1px solid black; - padding: 0px 4px; - font-family: "andale mono", monospace; - font-weight: bold; - white-space: pre; -} - -#notice.system-message, .notice.system-message { - color: black; - background: #DDFFDD; - padding-top: 5pt; - padding-bottom: 5pt; - border: 1px none #55BB55; - border-top-width: 4px; - border-top-style: solid; -} - -#content.error .message, div.system-message { - color: #550000; - background: #ffddcc; - border: 2px none #dd0000; - border-top-width: 4px; - border-top-style: solid; - padding: .5em; - margin: 1em 0; -} - -#main { - float: right; - width: 70%; - padding: 0pt; - margin: 0pt; - min-height: 700px; - background: white; -} - -div#main h1 { - border-bottom: 2px solid #09550b; -} - -div#main div.section h1 { - border-bottom: none; -} - -#cmscontent { - padding: 0pt 4% 10pt 4%; - margin: 0pt; -} - -div#htmlerrorcontents { - padding: 10pt 4% 10pt 4%; - margin: 0pt; -} - -div#htmlerrorcontents span.cs { - font-size: 80%; - font-family: "andale mono", monospace; - white-space: pre; -} - -div#htmlerrorcontents hr.lang_separator { - border: 1px dotted black; - border-style: none none dotted; - margin-top: 20pt; - margin-bottom: 10pt; -} - -#embedcontent { - border: 0pt; - padding: 0pt; - margin: 0pt; -} - -#sidebar { - float: left; - width: 29.9%; - padding: 0 0 0 0; - margin: 0 0 0 0; - color: white; - background: #09550B; - /* - min-height: 300px; - background: #f2f2f2; - border-right: 1px solid #ccc; - padding: 0 0 0 10px; - */ -} diff --git a/documentation/UsersGuide/UsersGuide.html b/documentation/UsersGuide/UsersGuide.html deleted file mode 100644 index b22602be..00000000 --- a/documentation/UsersGuide/UsersGuide.html +++ /dev/null @@ -1,2096 +0,0 @@ - - - - - - - - - - - -
- - - - - - - - - - - - - - -


-
-

Coriolis User's Guide

-


-
- The pdf version of this document is available here:
- Coriolis User's Guide -
-


-
-

Credits & License

-

Hurricane -Rémy Escassut & - Christian Masson

-
-

Etesian -Gabriel Gouvine

-
-

Stratus -Sophie Belloeil

-
-

Knik -Damien Dupuis

-
-

Kite, - Unicorn -Jean-Paul Chaput

-


-

The Hurricane data-base is copyright© Bull 2000-2016 and is -released under the terms of the lgpl license. All other tools are -copyright© upmc 2008-2016 and released under the gpl -license.

-

Others important contributors to Coriolis are Christophe Alexandre, -Hugo Clement, Marek Sroka and Wu Yifei.

-

The Knik router makes use of the Flute software, which is -copyright© Chris C. N. Chu from the Iowa State University -(http://home.eng.iastate.edu/~cnchu/).

-


-
-
-

Release Notes

-
-

Release 1.0.1475

-

This is the first preliminary release of the Coriolis 2 framework.

-

This release mainly ships the global router Knik and the detailed router -Kite. Together they aim to replace the Alliance Nero router. -Unlike Nero, Kite is based on an innovating routing modeling and ad-hoc -algorithm. Although it is released under gpl license, the source code -will be avalaible later. -

-

Contents of this release:

-
    -
  1. A graphical user interface (viewer only).
  2. -
  3. The Knik global router.
  4. -
  5. The Kite detailed router.
  6. -
-

Supported input/output formats:

-
    -
  • Alliance vst (netlist) & ap (physical) formats.
  • -
  • Even if there are some references to the Cadence lefdef format, its -support is not included because it depends on a library only available -to Si2 affiliated members.
  • -
-
-
-

Release 1.0.1963

-

Release 1963 is alpha. All the tools from Coriolis 1 have been ported into -this release.

-

Contents of this release:

-
    -
  1. The Stratus netlist capture language (GenLib replacement).
  2. -
  3. The Mauka placer (still contains bugs).
  4. -
  5. A graphical user interface (viewer only).
  6. -
  7. The Knik global router.
  8. -
  9. The Kite detailed router.
  10. -
  11. Partially implemented python support for configuration files -(alternative to xml).
  12. -
  13. A documentation (imcomplete/obsoleted in Hurricane's case).
  14. -
-
-
-

Release 1.0.2049

-

Release 2049 is Alpha.

-

Changes of this release:

-
    -
  1. The Hurricane documentation is now accurate. Documentation -for the Cell viewer and CRLcore has been added.
  2. -
  3. More extensive Python support for all the components of -Coriolis.
  4. -
  5. Configuration is now completly migrated under Python. -xml loaders can still be useds for compatibilty.
  6. -
  7. The cgt main has been rewritten in Python.
  8. -
-
-
-

Release v2.0.1

-
    -
  1. Migrated the repository from svn to git, and release complete sources. -As a consequence, we drop the distribution packaging support and give -public read-only access to the repository.
  2. -
  3. Deep rewrite of the Katabatic database and Kite detailed router, -achieve a speedup factor greater than 20...
  4. -
-
-
-

Release v2.1

-
    -
  1. Replace the old simulated annealing placer Mauka by the analytical placer -Etesian and its legalization and detailed placement tools.
  2. -
  3. Added a Blif format parser to process circuits generated by the Yosys and ABC -logic synthetizers.
  4. -
  5. The multiples user defined configuration files are now grouped under -a common hidden (dot) directory .coriolis2 and the file extension -is back from .conf to .py.
  6. -
- - - - -
-
-

Release v2.2

-
    -
  1. Added JSON import/export of the whole Hurricane DataBase. Two save mode -are supported: Cell mode (standalone) or Blob mode, which dump the -whole design down and including the standard cells.
  2. -
-


-
-
-
-

Installation

-
-

Note

-

As the sources are being released, the binary packaging is dropped. -You still may find older version here: http://asim.lip6.fr/pub/coriolis/2.0 .

-
-

In a nutshell, building source consist in pulling the git repository then -running the ccb installer.

-

Main building prerequisites:

-
    -
  • cmake
  • -
  • C++11-capable compiler
  • -
  • RapidJSON
  • -
  • python2.7
  • -
  • boost
  • -
  • libxml2
  • -
  • bzip2
  • -
  • yacc & lex
  • -
  • Qt 4 or Qt 5
  • -
-

Building documentation prerequisites:

-
    -
  • doxygen
  • -
  • latex
  • -
  • latex2html
  • -
  • python-docutils (for reStructuredText)
  • -
-

Optional libraries:

-
    -
  • LEF/DEF (from SI2)
  • -
-

For other distributions, refer to their own packaging system.

-


-
-

Fixed Directory Tree

-

In order to simplificate the work of the ccb installer, the source, build -and installation tree is fixed. To successfully compile Coriolis you must -follow it exactly. The tree is relative to the home directory of the user -building it (noted ~/ or $HOME/). Only the source -directory needs to be manually created by the user, all others will be -automatically created either by ccb or the build system.

- ---- - - - - - - - - - - - - - - - - - - - - - - -
Sources
-
Sources root
-
under git
-
-
-
~/coriolis-2.x/src
-
~/coriolis-2.x/src/coriolis
-
-
Architecture Dependant Build
-
Linux, SL 7, 64 bits
-
Linux, SL 6, 32 bits
-
Linux, SL 6, 64 bits
-
Linux, Fedora, 64 bits
-
Linux, Fedora, 32 bits
-
FreeBSD 8, 32 bits
-
FreeBSD 8, 64 bits
-
Windows 7, 32 bits
-
Windows 7, 64 bits
-
Windows 8.x, 32 bits
-
Windows 8.x, 64 bits
-
-
-
~/coriolis-2.x/Linux.el7_64/Release.Shared/build/<tool>
-
~/coriolis-2.x/Linux.slsoc6x/Release.Shared/build/<tool>
-
~/coriolis-2.x/Linux.slsoc6x_64/Release.Shared/build/<tool>
-
~/coriolis-2.x/Linux.fc_64/Release.Shared/build/<tool>
-
~/coriolis-2.x/Linux.fc/Release.Shared/build/<tool>
-
~/coriolis-2.x/FreeBSD.8x.i386/Release.Shared/build/<tool>
-
~/coriolis-2.x/FreeBSD.8x.amd64/Release.Shared/build/<tool>
-
~/coriolis-2.x/Cygwin.W7/Release.Shared/build/<tool>
-
~/coriolis-2.x/Cygwin.W7_64/Release.Shared/build/<tool>
-
~/coriolis-2.x/Cygwin.W8/Release.Shared/build/<tool>
-
~/coriolis-2.x/Cygwin.W8_64/Release.Shared/build/<tool>
-
-
Architecture Dependant Install
Linux, SL 6, 32 bits~/coriolis-2.x/Linux.slsoc6x/Release.Shared/install/
FHS Compliant Structure under Install
-
Binaries
-
Libraries (Python)
-
Include by tool
-
Configuration files
-
Doc, by tool
-
-
-
.../install/bin
-
.../install/lib
-
.../install/include/coriolis2/<project>/<tool>
-
.../install/etc/coriolis2/
-
.../install/share/doc/coriolis2/en/html/<tool>
-
-
-
-

Note

-

Alternate build types: the Release.Shared means an optimized build -with shared libraries. But there are also available Static instead of Shared -and Debug instead of Release and any combination of them.

-

Static do not work because I don't know yet to mix statically linked binaries -and Python modules (which must be dynamic).

-
-


-
-
-

Building Coriolis

-

First step is to install the prerequisites. Currently, only RapidJSON. -As RapidJSON is evolving fast, if you encounter compatibility problems, -the exact version we compiled against is given below.

-
-dummy@lepka:~$ mkdir -p ~/coriolis-2.x/src/support
-dummy@lepka:~$ cd ~/coriolis-2.x/src/support
-dummy@lepka:~$ git clone http://github.com/miloyip/rapidjson
-dummy@lepka:~$ git checkout ec322005072076ef53984462fb4a1075c27c7dfd
-
-

The second step is to create the source directory and pull the git repository:

-
-dummy@lepka:~$ mkdir -p ~/coriolis-2.x/src
-dummy@lepka:~$ cd ~/coriolis-2.x/src
-dummy@lepka:~$ git clone https://www-soc.lip6.fr/git/coriolis.git
-
-

Third and final step, build & install:

-
-dummy@lepka:src$ ./bootstrap/ccb.py --project=support  \
-                                    --project=coriolis \
-                                    --make="-j4 install"
-dummy@lepka:src$ ./bootstrap/ccb.py --project=support  \
-                                    --project=coriolis \
-                                    --doc --make="-j1 install"
-
-

We need to separate to perform a separate installation of the documentation because it -do not support to be generated with a parallel build. So we compile & install in a first -stage in -j4 (or whatever) then we generate the documentation in -j1

-

Under rhel6 or clones, you must build using the devtoolset2:

-
-dummy@lepka:src$ ./bootstrap/ccb.py --project=coriolis \
-                                    --devtoolset-2 --make="-j4 install"
-
-

If you want to uses Qt 5 instead of Qt 4, you may add the --qt5 argument.

-

The complete list of ccb functionalities can be accessed with the --help argument. -It also may be run in graphical mode (--gui).

-
-

Building the Devel Branch

-

In the Coriolis git repository, two branches are present:

-
    -
  • The master branch, which contains the latest stable version. This is the -one used by default if you follow the above instructions.

    -
  • -
  • The devel branch, which obviously contains the latest commits from the -development team. To use it instead of the master one, do the following -command just after the first step:

    -
    -dummy@lepka:~$ git checkout devel
    -dummy@lepka:src$ ./bootstrap/ccb.py --project=coriolis \
    -                                    --make="-j4 install" --debug
    -
    -

    Be aware that it may requires newer versions of the dependencies and may introduce -incompatibilites with the stable version.

    -

    In the (unlikely) event of a crash of cgt, as it is a Python script, the right -command to run gdb on it is:

    -
    -dummy@lepka:work$ gdb python core.XXXX
    -
    -
  • -
-


-
-
-

Additionnal Requirement under MacOS

-

Coriolis make uses of the boost::python module, but the MacPorts boost -seems unable to work with the Python bundled with MacOS. So you have to install -both of them from MacPorts:

-
-dummy@macos:~$ port install boost +python27
-dummy@macos:~$ port select python python27
-dummy@macos:-$ export DYLD_FRAMEWORK_PATH=/opt/local/Library/Frameworks
-
-

The last two lines tell MacOS to use the Python from MacPorts and not from -the system.

-

Then proceed with the generic install instructions.

-
-
-
-

Packaging Coriolis

-

Packager should not uses ccb, instead bootstrap/Makefile.package is provided -to emulate a top-level autotool makefile. Just copy it in the root of the -Coriolis git repository (~/corriolis-2.x/src/coriolis/) and build.

-

Sligthly outaded packaging configuration files can also be found under bootstrap/:

-
    -
  • bootstrap/coriolis2.spec.in for rpm based distributions.
  • -
  • bootstrap/debian for Debian based distributions.
  • -
-
-
-

Hooking up into Alliance

-

Coriolis relies on Alliance for the cell libraries. So after installing or -packaging, you must configure it so that it can found those libraries.

-

This is done by editing the one variable cellsTop in the Alliance helper -(see Alliance Helper). This variable must point to the directory of the -cells libraries. In a typical installation, this is generally -/usr/share/alliance/cells.

-
-
-

Setting up the Environment (coriolisEnv.py)

-

To simplify the tedious task of configuring your environment, a helper is provided -in the bootstrap source directory (also installed in the directory -.../install/etc/coriolis2/) :

-
-~/coriolis-2.x/src/coriolis/bootstrap/coriolisEnv.py
-
-

Use it like this:

-
-dummy@lepka:~> eval `~/coriolis-2.x/src/coriolis/bootstrap/coriolisEnv.py`
-
-
-

Note

-

Do not call that script in your environement initialisation. -When used under rhel6 or clones, it needs to be run in the devtoolset2 -environement. The script then launch a new shell, which may cause an -infinite loop if it's called again in, say ~/.bashrc.

-

Instead you may want to create an alias:

-
-alias c2r='eval "`~/coriolis-2.x/src/coriolis/bootstrap/coriolisEnv.py`"'
-
-
-


-
-
-
-

Documentation

-

The general index of the documentation for the various parts of Coriolis -are avalaibles here Coriolis Tools Documentation.

-
-

Note

-

Python Documentation: -Most of the documentation is related to the C++ API and implemetation of -the tools. However, the Python bindings have been created so they -mimic as closely as possible the C++ interface, so the documentation -applies to both languages with only minor syntactic changes.

-
-
-

General Software Architecture

-

Coriolis has been build with respect of the classical paradigm that the -computational instensive parts have been written in C++, and almost -everything else in Python. To build the Python interface we used -two methods:

-
    -
  • For self-contained modules boost::python (mainly in vlsisapd).
  • -
  • For all modules based on Hurricane, we created our own wrappers due -to very specific requirements such as shared functions between modules -or C++/Python secure bi-directional object deletion.
  • -
-

Coriolis Software Schematic

-
-
-
-

Coriolis Configuration & Initialisation

-

All configuration & initialization files are Python scripts, despite their -.conf extention. From a syntactic point of view, there is no difference -between the system-wide configuration files and the user's configuration, -they may use the same Python helpers. -

-

Configuration is done in two stages:

-
    -
  1. Selecting the symbolic technology.
  2. -
  3. Loading the complete configuration for the given technology.
  4. -
-
-

First Stage: Symbolic Technology Selection

-

-The initialization process is done by executing, in order, the following -file(s):

- ----- - - - - - - - - - - - - - - - - - - - - -
OrderMeaningFile
1The system setting/etc/coriolis2/techno.conf
2The user's global setting${HOME}/.coriolis2/techno.py
3The user's local setting<CWD>/.coriolis2/techno.py
-

Thoses files must provides only two variables, the name of the symbolic technology -and the one of the real technology. For example:

-
-# -*- Mode:Python -*-
-
-symbolicTechno = 'cmos'
-realTechno     = 'hcmos9'
-
-
-
-

Second Stage: Technology Configuration Loading

-

-The TECHNO variable is set by the first stage and it's the name of the -symbolic technology. A directory of that name, with all the configuration files, -must exists in the configuration directory. In addition to the technology-specific -directories, a common/ directory is there to provides a trunk for all the -identical datas across the various technologies. The initialization process is done -by executing, in order, the following file(s):

- ----- - - - - - - - - - - - - - - - - - - - - -
OrderMeaningFile
1The system initialization/etc/coriolis2/<TECHNO>/<TOOL>.conf
2The user's global initialization${HOME}/.coriolis2/settings.py
3The user's local initialization<CWD>/.coriolis2/settings.py
-
-

Note

-

The loading policy is not hard-coded. It is implemented -at Python level in /etc/coriolis2/coriolisInit.py, and thus may be easily be -amended to whatever site policy.

-

The truly mandatory requirement is the existence of coriolisInit.py -which must contain a coriolisConfigure() function with no argument.

-
-
-
-

Configuration Helpers

-

To ease the writing of configuration files, a set of small helpers -is available. They allow to setup the configuration parameters through -simple assembly of tuples. The helpers are installed under the directory:

-
-<install>/etc/coriolis2/
-
-

Where <install>/ is the root of the installation.

-


-
-

Alliance Helper

-

The configuration file must provide a allianceConfig tuple of -the form:

-
-cellsTop = '/usr/share/alliance/cells/'
-
-allianceConfig = \
-    ( ( 'SYMBOLIC_TECHNOLOGY', helpers.sysConfDir+'/technology.symbolic.xml'   )
-    , ( 'REAL_TECHNOLOGY'    , helpers.sysConfDir+'/technology.cmos130.s2r.xml')
-    , ( 'DISPLAY'            , helpers.sysConfDir+'/display.xml'               )
-    , ( 'CATALOG'            , 'CATAL')
-    , ( 'WORKING_LIBRARY'    , '.')
-    , ( 'SYSTEM_LIBRARY'     , ( (cellsTop+'sxlib'   , Environment.Append)
-                               , (cellsTop+'dp_sxlib', Environment.Append)
-                               , (cellsTop+'ramlib'  , Environment.Append)
-                               , (cellsTop+'romlib'  , Environment.Append)
-                               , (cellsTop+'rflib'   , Environment.Append)
-                               , (cellsTop+'rf2lib'  , Environment.Append)
-                               , (cellsTop+'pxlib'   , Environment.Append) ) )
-    , ( 'SCALE_X'            , 100)
-    , ( 'IN_LO'              , 'vst')
-    , ( 'IN_PH'              , 'ap')
-    , ( 'OUT_LO'             , 'vst')
-    , ( 'OUT_PH'             , 'ap')
-    , ( 'POWER'              , 'vdd')
-    , ( 'GROUND'             , 'vss')
-    , ( 'CLOCK'              , '^ck.*')
-    , ( 'BLOCKAGE'           , '^blockageNet*')
-    )
-
-

The example above shows the system configuration file, with all the -available settings. Some important remarks about thoses settings:

-
    -
  • In it's configuration file, the user do not need to redefine all the settings, -just the one he wants to change. In most of the cases, the SYSTEM_LIBRARY, -the WORKING_LIBRARY and the special net names (at this point there is not -much alternatives for the others settings).

    -
  • -
  • SYSTEM_LIBRARY setting: Setting up the library search path. -Each library entry in the tuple will be added to the search path according -to the second parameter:

    -
      -
    • Environment::Append: append to the search path.
    • -
    • Environment::Prepend: insert in head of the search path.
    • -
    • Environment::Replace: look for a library of the same name and replace -it, whithout changing the search path order. If no library of that name -already exists, it is appended.
    • -
    -

    A library is identified by it's name, this name is the last component of the -path name. For instance: /soc/alliance/sxlib will be named sxlib. -Implementing the Alliance specification, when looking for a Cell name, -the system will browse sequentially trought the library list and returns -the first Cell whose name match.

    -
  • -
  • For POWER, GROUND, CLOCK and BLOCKAGE net names, a regular -expression (gnu regexp) is expected.

    -
  • -
  • The helpers.sysConfDir variable is supplied by the helpers, it is the -directory in which the system-wide configuration files are locateds. -For a standard installation it would be: /soc/coriolis2.

    -
  • -
- - - - - - - - - - - - - - - - -

A typical user's configuration file would be:

-
-import os
-
-homeDir = os.getenv('HOME')
-
-allianceConfig = \
-    ( ('WORKING_LIBRARY'    , homeDir+'/worklib')
-    , ('SYSTEM_LIBRARY'     , ( (homeDir+'/mylib', Environment.Append) ) )
-    , ('POWER'              , 'vdd.*')
-    , ('GROUND'             , 'vss.*')
-    )
-
-
-
-

Tools Configuration Helpers

-

All the tools uses the same helper to load their configuration (a.k.a. -Configuration Helper). Currently the following configuration system-wide -configuration files are defined:

-
    -
  • misc.conf: commons settings or not belonging specifically to a tool.
  • -
  • etesian.conf: for the Etesian tool.
  • -
  • kite.conf: for the Kite tool.
  • -
  • stratus1.conf: for the Stratus1 tool.
  • -
-

Here is the contents of etesian.conf:

-
-# Etesian parameters.
-parametersTable = \
-    ( ('etesian.aspectRatio'    , TypePercentage, 100    , { 'min':10, 'max':1000 } )
-    , ('etesian.spaceMargin'    , TypePercentage, 5      )
-    , ('etesian.uniformDensity' , TypeBool      , False  )
-    , ('etesian.routingDriven'  , TypeBool      , False  )
-    , ("etesian.effort"         , TypeEnumerate , 2
-      , { 'values':( ("Fast"    , 1)
-                   , ("Standard", 2)
-                   , ("High"    , 3)
-                   , ("Extreme" , 4) ) }
-      )
-    , ("etesian.graphics"       , TypeEnumerate , 2
-      , { 'values':( ("Show every step"  , 1)
-                   , ("Show lower bound" , 2)
-                   , ("Show result only" , 3) ) }
-      )
-    )
-
-layoutTable = \
-    ( (TypeTab   , 'Etesian', 'etesian')
-
-    , (TypeTitle , 'Placement area')
-    , (TypeOption, "etesian.aspectRatio"   , "Aspect Ratio, X/Y (%)", 0 )
-    , (TypeOption, "etesian.spaceMargin"   , "Space Margin"         , 1 )
-    , (TypeRule  ,)
-    , (TypeTitle , 'Etesian - Placer')
-    , (TypeOption, "etesian.uniformDensity", "Uniform density"      , 0 )
-    , (TypeOption, "etesian.routingDriven" , "Routing driven"       , 0 )
-    , (TypeOption, "etesian.effort"        , "Placement effort"     , 1 )
-    , (TypeOption, "etesian.graphics"      , "Placement view"       , 1 )
-    , (TypeRule  ,)
-    )
-
-

Taxonomy of the file:

-
    -
  • It must contains, at least, the two tables:
      -
    • parametersTable, defines & initialise the configuration variables.
    • -
    • layoutTables, defines how the various parameters will be displayed -in the configuration window (The Settings Tab).
    • -
    -
  • -
  • The parametersTable, is a tuple (list) of tuples. Each entry in the list -describe a configuration parameter. In it's simplest form, it's a quadruplet -(TypeOption, 'paramId', ParameterType, DefaultValue) with:
      -
    1. TypeOption, tells that this tuple describe a parameter.
    2. -
    3. paramId, the identifier of the parameter. Identifiers are defined -by the tools. The list of parameters is detailed in each tool section.
    4. -
    5. ParameterType, the kind of parameter. Could be:
        -
      • TypeBool, boolean.
      • -
      • TypeInt, signed integer.
      • -
      • TypeEnumerate, enumerated type, needs extra entry.
      • -
      • TypePercentage, percentage, expressed between 0 and 100.
      • -
      • TypeDouble, float.
      • -
      • TypeString, character string.
      • -
      -
    6. -
    7. DefaultValue, the default value for that parameter.
    8. -
    -
  • -
-
-
-
-

Hacking the Configuration Files

-

Asides from the symbols that gets used by the configuration helpers like -allianceConfig or parametersTable, you can put pretty much anything -in <CWD>/.coriolis2/settings.py (that is, written in Python).

-

For example:

-
-# -*- Mode:Python -*-
-
-defaultStyle = 'Alliance.Classic [black]'
-
-# Regular Coriolis configuration.
-parametersTable = \
-    ( ('misc.catchCore'           , TypeBool      , False  )
-    , ('misc.info'                , TypeBool      , False  )
-    , ('misc.paranoid'            , TypeBool      , False  )
-    , ('misc.bug'                 , TypeBool      , False  )
-    , ('misc.logMode'             , TypeBool      , True   )
-    , ('misc.verboseLevel1'       , TypeBool      , False  )
-    , ('misc.verboseLevel2'       , TypeBool      , True   )
-    , ('misc.minTraceLevel'       , TypeInt       , 0      )
-    , ('misc.maxTraceLevel'       , TypeInt       , 0      )
-    )
-
-# Some ordinary Python script...
-import os
-
-print '       o  Cleaning up ClockTree previous run.'
-for fileName in os.listdir('.'):
-  if fileName.endswith('.ap') or (fileName.find('_clocked.') >= 0):
-    print '          - <%s>' % fileName
-    os.unlink(fileName)
-
-

See Python Interface to Coriolis for more details those capabilities.

-
-
-
-

CGT - The Graphical Interface

-

The Coriolis graphical interface is split up into two windows.

-
    -
  • The Viewer, with the following features:
      -
    • Basic load/save capabilities.
    • -
    • Display the current working cell. Could be empty if the design -is not yet placed.
    • -
    • Execute Stratus Scripts.
    • -
    • Menu to run the tools (placement, routage).
    • -
    -
  • -
-

Features are detailed in Viewer & Tools.

-

Viewer Basic Snapshot

-
    -
  • The Controller, which allows:
      -
    • Tweak what is displayer by the Viewer. Through the Look, -Filter and Layers&Gos tabs.
    • -
    • Browse the netlist with eponym tab.
    • -
    • Show the list of selected objects (if any) with selection
    • -
    • Walk through the Database, the Cell or the Selection with Inspector. -This is an advanced feature, reserved for experimented users.
    • -
    • The tab Settings which give access to all the settings. -They are closely related to Configuration & Initialisation.
    • -
    -
  • -
-

Controller Basic Snapshot

-
-
-

Viewer & Tools

-
-

Stratus Netlist Capture

-

Stratus is the replacement for GenLib procedural netlist capture language. -It is designed as a set of Python classes, and comes with it's own documentation -(Stratus Documentation)

-
-
-

The Hurricane Data-Base

-

The Alliance flow is based on the mbk data-base, which has one data-structure -for each view. That is, Lofig for the logical view and Phfig for the physical -view. The place and route tools were responsible for maintaining (or not) the -coherency between views. Reflecting this weak coupling between views, each one -was stored in a separate file with a specific format. The logical view is stored -in a vst file in vhdl format and the physical in an ap file in an ad-hoc format.

-

The Coriolis flow is based on the Hurricane data-base, which has a unified -structure for logical and physical view. That data structure is the Cell object. -The Cell can have any state between pure netlist and completly placed and -routed design. Although the memory representation of the views has deeply -changed we still use the Alliance files format, but they now really represent -views of the same object. The point is that one must be very careful about -view coherency when going to and from Coriolis.

-

As for the second release, Coriolis can be used only for three purposes :

-
    -
  • Placing a design, in which case the netlist view must be present.
  • -
  • Routing a design, in that case the netlist -view and the layout view must be present and layout view must contain -a placement. Both views must have the same name. When saving the routed design, -it is advised to change the design name otherwise the original unrouted placement -in the layout view will be overwritten.
  • -
  • Viewing a design, the netlist view must be present, if a layout -view is present it still must have the same name but it can be in any -state.
  • -
-
-
-

Synthetizing and loading a design

-

Coriolis supports several file formats. It can load all file format -from the Alliance toolchain (.ap for layout, behavioural and structural vhdl .vbe and .vst), -BLIF netlist format as well as benchmark formats from the ISPD contests.

-

It can be compiled with LEF/DEF support, although it requires acceptance of the SI2 license -and may not be compiled in your version of the software.

-
-

Synthesis under Yosys

-

You can create a BLIF file from the Yosys synthetizer, which can be imported under Coriolis. -Most libraries are specified as a .lib liberty file and a .lef LEF file. -Yosys opens most .lib files with minor modifications, but LEF support in Coriolis relies on SI2. -If Coriolis hasn't been compiled against it, the library is given in Alliance .ap format. -Some free libraries already provide both .ap and .lib files.

-

Once you have installed a common library under Yosys and Coriolis, just synthetize your design -with Yosys and import it (as Blif without the extension) under Coriolis to perform place&route.

-
-
-

Synthesis under Alliance

-

Alliance is an older toolchain but has been extensively used for years. Coriolis can import -and write Alliance designs and libraries directly.

-
-
-
-

Etesian -- Placer

-

The Etesian placer is a state of the art (as of 2015) analytical placer. It is -within 5% of other placers' solutions, but is normally a bit worse than ePlace. -This Coriolis tool is actually an encapsulation of Coloquinte which is the placer.

-
-

Note

-

Instance Uniquification Unsupported: a same logical instance cannot have -two different placements. So, either you manually make a clone of it or you -supply a placement for it. We need to implement uniquification in the -Hurricane database.

-
-

-Hierarchical Placement

-

The placement area is defined by the top cell abutment box.

-

When placing a complete hierarchy, the abutment boxes of the cells (models) other than -the top cell are sets identical to the one of the top cell and their instances are -all placed at position (0,0,ID). That is, all the abutments boxes, whatever the -hierarchical level, defines the same area (they are exactly superposed).

-

We choose this scheme because the placer will see all the instances as virtually -flattened, so they can be placed anywhere inside the top-cell abutment box.

-

Etesian Abutment Box

-

-Computing the Placement Area

-

The placement area is computed using the etesian.aspectRatio and etesian.spaceMargin -parameters only if the top-cell has an empty abutment box. If the top-cell abutment -box has to be set, then it is propagated to all the instances models recursively.

-

-Reseting the Placement

-

Once a placement has been done, the placer cannot reset it (will be implemented -later). To perform a new placement, you must restart cgt. In addition, if you -have saved the placement on disk, you must erase any .ap file, which are -automatically reloaded along with the netlist (.vst).

-

-Limitations

-

Etesian supports standard cells and fixed macros. As for the Coriolis 2.1 version, -it doesn't support movable macros, and you must place every macro beforehand. -Timing and routability analysis are not included either, and the returned placement -may be unroutable.

-


-
-

Etesian Configuration Parameters

- ----- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Parameter IdentifierTypeDefault
Etesian Parameters
etesian.aspectRatioTypePercentage100
Define the height on width H/W aspect -ratio, can be comprised between 10 and 1000
etesian.spaceMarginTypePercentage5
The extra white space added to the total area -of the standard cells
etesian.uniformDensityTypeBoolFalse
Whether the cells will be spread envenly -across the area or allowed to form denser -clusters
etesian.effortTypeInt2
Sets the balance between the speed of the -placer and the solution quality
etesian.routingDrivenTypeBoolFalse
Whether the tool will try routing iterations -and whitespace allocation to improve -routability; to be implemented
etesian.graphicsTypeInt2

How often the display will be refreshed -More refreshing slows the placer.

-
    -
  • 1 shows both upper and lower bounds
  • -
  • 2 only shows lower bound results
  • -
  • 3 only shows the final results
  • -
-
-
-
-
-

Knik -- Global Router

-

The quality of Knik global routing solutions are equivalent to those of FGR 1.0. -For an in-depth description of Knik algorithms, you may download the thesis of -D. Dupuis avalaible from here~: Knik Thesis.

-

The global router is (not yet) deterministic. To circumvent this limitation, -a global routing solution can be saved to disk and reloaded for later uses.

-

A global routing is saved into a file with the same name as the design and a -kgr extention. It is in Box Router output format.

-

Menus:

-
    -
  • menu_KiteSaveGlobalRouting.
  • -
  • menu_KiteLoadGlobalRouting.
  • -
-
-
-

Kite -- Detailed Router

-

Kite no longer suffers from the limitations of Nero. It can route big designs -as its runtime and memory footprint is almost linear (with respect to the number -of gates). It has successfully routed design of more than 150K gates. -

-

However, this first release comes with the temporary the following -restrictions:

-
    -
  • Works only with SxLib standard cell gauge.
  • -
  • Works always with 4 routing metal layers (M2 through M5).
  • -
  • Do not allow (take into account) pre-routed wires on signals -other than power or ground.
  • -
-
-

Note

-

Slow Layer Assignment. Most of the time, the layer assignment stage is -fast (less than a dozen seconds), but in some instances it can take more -than a dozen minutes. This is a known bug and will be corrected in later -releases.

-
-

After each run, Kite displays a set of completion ratios which must all -be equal to 100% if the detailed routing has been successfull. -In the event of a failure, on a saturated design, you may decrease the -edge saturation ratio (argument --edge) to balance more evenly the design -saturation. That is, the maximum saturation decrease at the price of a wider -saturated area and increased wirelength. This is the saturation of the -global router Knik, and you may increase/decrease by steps of 5%, -which represent one track. The maximum capacity of the SxLib gauge is -10 tracks in two layers, that makes 20 tracks by Knik edge.

-

Routing a design is done in four ordered steps:

-
    -
  1. Detailed pre-route

    menu_KiteDetailedPreRoute.
  2. -
  3. Global routing

    menu_KiteGlobalRoute.
  4. -
  5. Detailed routing

    menu_KiteDetailedRoute.
  6. -
  7. Finalize routing

    menu_KiteFinalizeRoute.
  8. -
-

It is possible to supply to the router a complete wiring for some nets that the user's -wants to be routed according to a specific topology. The supplied topology must respect -the building rules of the Katabatic database (contacts must be, terminals, turns, h-tee -& v-tee only). During the first step Detailed Pre-Route the router will solve -overlaps between the segments, without making any dogleg. If no pre-routed topologies -are present, this step may be ommited. Any net routed at this step is then fixed and -become unmovable for the later stages.

-

After the detailed routing step the Kite data-structure is still active -(the Hurricane wiring is decorated). The finalize step performs the removal of -the Kite data-structure, and it is not advisable to save the design before -that step.

-

You may visualize the density (saturation) of either Knik (on edges) or -Kite (on GCells) until the routing is finalized. Special layers appears -to that effect in the The Layers&Go Tab.

-
-

Kite Configuration Parameters

-

As Knik is only called through Kite, it's parameters also have -the kite. prefix.

-

The Katabatic parameters control the layer assignment step.

-

All the defaults value given below are from the default Alliance technology -(cmos and SxLib cell gauge/routing gauge).

- ----- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Parameter IdentifierTypeDefault
Katabatic Parameters
katabatic.topRoutingLayerTypeStringMETAL5
Define the highest metal layer that will be -used for routing (inclusive).
katabatic.globalLengthThresholdTypeInt1450
This parameter is used by a layer assignment -method which is no longer used (did not give -good results)
katabatic.saturateRatioTypePercentage80
If M(x) density is above this ratio, -move up feedthru global segments up from -depth x to x+2
katabatic.saturateRpTypeInt8
If a GCell contains more terminals -(RoutingPad) than that number, force a -move up of the connecting segments to those -in excess
Knik Parameters
kite.hTracksReservedLocalTypeInt3
To take account the tracks needed inside a -GCell to build the local routing, decrease -the capacity of the edges of the global -router. Horizontal and vertical locally -reserved capacity can be distinguished for -more accuracy.
kite.vTracksReservedLocalTypeInt3
cf. kite.hTracksReservedLocal
Kite Parameters
kite.eventsLimitTypeInt4000002
The maximum number of segment displacements, -this is a last ditch safety against infinite -loop. It's perhaps a little too low for big -designs
kite.ripupCostTypeInt3
Differential introduced between two ripup -cost to avoid a loop between two ripped up -segments
kite.strapRipupLimitTypeInt16
Maximum number of ripup for strap segments
kite.localRipupLimitTypeInt9
Maximum number of ripup for local segments
kite.globalRipupLimitTypeInt5
Maximum number of ripup for global segments, -when this limit is reached, triggers topologic -modification
kite.longGlobalRipupLimitTypeInt5
Maximum number of ripup for long global -segments, when this limit is reached, triggers -topological modification
-
-
-
-

Executing Python Scripts in Cgt

-

Python/Stratus scripts can be executed either in text or graphical mode.

-
-

Note

-

How Cgt Locates Python Scripts: -cgt uses the Python import mechanism to load Python scripts. -So you must give the name of your script whitout .py extention and -it must be reachable through the PYTHONPATH. You may uses the -dotted module notation.

-
-

A Python/Stratus script must contains a function called ScriptMain() -with one optional argument, the graphical editor into which it may be -running (will be set to None in text mode). The Python interface to -the editor (type: CellViewer) is limited to basic capabilities -only.

-

Any script given on the command line will be run immediatly after the -initializations and before any other argument is processed.

-

For more explanation on Python scripts see Python Interface to Coriolis.

-
-
-

Printing & Snapshots

-

Printing or saving into a pdf is fairly simple, just uses the File -> Print -menu or the CTRL+P shortcut to open the dialog box.

-

The print functionality uses exactly the same rendering mechanism as for the -screen, beeing almost WYSIWYG. Thus, to obtain the best results it is advisable -to select the Coriolis.Printer look (in the Controller), which uses a -white background and much suited for high resolutions 32x32 pixels patterns

-

There is also two mode of printing selectable through the Controller -Settings -> Misc -> Printer/Snapshot Mode:

- ----- - - - - - - - - - - - - - - -
ModeDPI (approx.)Intended Usage
Cell Mode150For single Cell printing or very small designs. -Patterns will be bigger and more readable.
Design Mode300For designs (mostly commposed of wires and cells -outlines).
-
-

Note

-

The pdf file size -Be aware that the generated pdf files are indeed only pixmaps. -So they can grew very large if you select paper format above A2 -or similar.

-
-

-Saving into an image is subject to the same remarks as for pdf.

-
-
-

Memento of Shortcuts in Graphic Mode

-

The main application binary is cgt.

- ----- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CategoryKeysAction
Moves
-
Up, -Down
-
Left, -Right
-
-
Shift the view in the according direction
FitfFit to the Cell abutment box
RefreshCTRL+LTriggers a complete display redraw
Gotogapperture is the minimum side of the area -displayed around the point to go to. It's an -alternative way of setting the zoom level
Zoomz, -mRespectively zoom by a 2 factor and unzoom -by a 2 factor
-
BigMouse
-
Area Zoom
-
-
You can perform a zoom to an area. -Define the zoom area by holding down the left -mouse button while moving the mouse.
Selection
-
BigMouse
-
Area Selection
-
-
You can select displayed objects under an area. -Define the selection area by holding down the -right mouse button while moving the mouse.
-
BigMouse
-
Toggle Selection
-
-
You can toggle the selection of one object under -the mouse position by pressing CTRL and -pressing down the right mouse button. A popup -list of what's under the position shows up into -which you can toggle the selection state of one -item.
SToggle the selection visibility
ControllerCTRL+I

Show/hide the controller window.

-

It's the Swiss Army Knife of the viewer. -From it, you can fine-control the display and -inspect almost everything in your design.

-
Rulersk, -ESCOne stroke on k enters the ruler mode, in -which you can draw one ruler. You can exit the -ruler mode by pressing ESC. Once in ruler -mode, the first click on the left mouse button -sets the ruler's starting point and the second -click the ruler's end point. The second click -exits automatically the ruler mode.
KClears all the drawn rulers
PrintCTRL+PCurrently rather crude. It's a direct copy of -what's displayed in pixels. So the resulting -picture will be a little blurred due to -anti-aliasing mechanism.
Open/CloseCTRL+OOpens a new design. The design name must be -given without path or extention.
CTRL+WClose the current viewer window, but do not quit -the application.
CTRL+QCTRL+Q quit the application -(closing all windows).
HierarchyCTRL+DownGo one hierarchy level down. That is, if there -is an instance under the cursor position, load -it's model Cell in place of the current one.
CTRL+UpGo one hierarchy level up. if we have entered -the current model through CTRL+Down -reload the previous model (the one -in which this model is instanciated).
-
-
-

Cgt Command Line Options

-

Appart from the obvious --text options, all can be used for text and graphical mode.

- ---- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ArgumentsMeaning
-t|--textInstruct cgt to run in text mode.
-L|--log-modeDisable the uses of ansi escape sequence on -the tty. Useful when the output is -redirected to a file.
-c <cell>|--cell=<cell>The name of the design to load, without -leading path or extention.
-g|--load-globalReload a global routing solution from disk. -The file containing the solution must be named -<cell>.kgr.
--save-globalSave the global routing solution, into a file -named <design>.kgr.
-e <ratio>|--edge=<ratio>Change the edge capacity for the global -router, between 0 and 1 (Knik).
-G|--global-routeRun the global router (Knik).
-R|--detailed-routeRun the detailed router (Kite).
-s|--save-design=<routed>The design into which the routed layout will -be saved. It is strongly recommanded to choose -a different name from the source (unrouted) -design.
--events-limit=<count>The maximal number of events after which the -router will stops. This is mainly a failsafe -against looping. The limit is sets to 4 -millions of iteration which should suffice to -any design of 100K. gates. For bigger -designs you may wants to increase this limit.
--stratus-script=<module>Run the Python/Stratus script module. -See Python Scripts in Cgt.
-

Some Examples :

-
    -
  • Run both global and detailed router, then save the routed design :

    -
    -> cgt -v -t -G -R --cell=design --save-design=design_kite
    -
    -
  • -
  • Load a previous global solution, run the detailed router, then save the -routed design :

    -
    -> cgt -v -t --load-global -R --cell=design --save-design=design_kite
    -
    -
  • -
  • Run the global router, then save the global routing solution :

    -
    -> cgt -v -t -G --save-global --cell=design
    -
    -
  • -
-
-
-

Miscellaneous Settings

- ----- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Parameter IdentifierTypeDefault
Verbosity/Log Parameters
misc.infoTypeBoolFalse
Enable display of info level message -(cinfo stream)
misc.bugTypeBoolFalse
Enable display of bug level message -(cbug stream), messages can be a little -scarry
misc.logModeTypeBoolFalse
If enabled, assume that the output device -is not a tty and suppress any escaped -sequences
misc.verboseLevel1TypeBoolTrue
First level of verbosity, disable level 2
misc.verboseLevel2TypeBoolFalse
Second level of verbosity
Development/Debug Parameters
misc.minTraceLevelTypeInt0
misc.maxTraceLevelTypeInt0
Display trace information between those two -levels (cdebug stream)
misc.catchCoreTypeBoolFalse
By default, cgt do not dump core. -To generate one set this flag to True
-


-
-
-
-

The Controller

-

The Controller window is composed of seven tabs:

-
    -
  1. The Look Tab to select the display style.
  2. -
  3. The Filter Tab the hierarchical levels to be displayed, the look of -rubbers and the dimension units.
  4. -
  5. The Layers&Go Tab to selectively hide/display layers.
  6. -
  7. The Netlist Tab to browse through the netlist. Works in association -with the Selection tab.
  8. -
  9. The Selection Tab allow to view all the currently selected elements.
  10. -
  11. The Inspector Tab browse through either the DataBase, the Cell or -the current selection.
  12. -
  13. The Settings Tab access all the tool's configuration settings.
  14. -
-
-

The Look Tab

-

You can select how the layout will be displayed. There is a special one -Printer.Coriolis specifically designed for Printing & Snapshots. -You should select it prior to calling the print or snapshot dialog boxes.

-

Controller Basic Snapshot

-
-
-

The Filter Tab

-

The filter tab let you select what hierarchical levels of your design will be -displayed. Hierarchy level are numbered top-down: the level 0 correspond to -the top-level cell, the level one to the instances of the top-level Cell and -so on.

-

There are also check boxes to enable/disable the processing of Terminal Cell, -Master Cells and Compnents. The processing of Terminal Cell (hierarchy leaf -cells) is disabled by default when you load a hierarchical design and enabled -when you load a single Cell.

-

You can choose what kind of form to give to the rubbers and the type of -unit used to display coordinates.

-
-

Note

-

What are Rubbers: Hurricane uses Rubbers to materialize -physical gaps in net topology. That is, if some wires are missing to -connect two or more parts of net, a rubber will be drawn between them -to signal the gap.

-

For example, after the detailed routing no rubbers should remains. -They have been made very visibles as big violet lines...

-
-

Controller Basic Snapshot

-
-
-

The Layers&Go Tab

-

Control the individual display of all layers and Gos.

-
    -
  • Layers correspond to a true physical layer. From a Hurricane point of -view they are all the BasicLayers (could be matched to GDSII).
  • -
  • Gos stands from Graphical Objects, they are drawings that have no -physical existence but are added by the various tools to display extra -information. One good exemple is the density map of the detailed router, -to easily locate congested areas.
  • -
-

For each layer/Go there are two check boxes:

-
    -
  • The normal one triggers the display.
  • -
  • The red-outlined allows objects of that layer to be selectable or not.
  • -
-

Controller Basic Snapshot

-
-
-

The Netlist Tab

-

The Netlist tab shows the list of nets... By default the tab is not -synched with the displayed Cell. To see the nets you must check the -Sync Netlist checkbox. You can narrow the set of displayed nets by -using the filter pattern (supports regular expressions).

-

An very useful feature is to enable the Sync Selection, which will -automatically select all the components of the selected net(s). You can -select multiple nets. In the figure the net auxsc35 is selected and -is highlited in the Viewer.

-

Controller Basic Snapshot
-
Controller Basic Snapshot

-
-
-

The Selection Tab

-

The Selection tab list all the components currently selecteds. They -can be filtered thanks to the filter pattern.

-

Used in conjunction with the Netlist Sync Selection you will all see -all the components part of net.

-

In this list, you can toggle individually the selection of component by -pressing the t key. When unselected in this way a component is not -removed from the the selection list but instead displayed in red italic. -To see where a component is you may make it blink by repeatedly press -the t key...

-

Controller Basic Snapshot

-
-
-

The Inspector Tab

-

This tab is very useful, but mostly for Coriolis developpers. It allows -to browse through the live DataBase. The Inspector provide three entry points:

-
    -
  • DataBase: Starts from the whole Hurricane DataBase.
  • -
  • Cell: Inspect the currently loaded Cell.
  • -
  • Selection: Inspect the object currently highlited in the Selection tab.
  • -
-

Once an entry point has been activated, you may recursively expore all -it's fields using the right/left arrows.

-
-

Note

-

Do not put your fingers in the socket: when inspecting -anything, do not modify the DataBase. If any object under inspection -is deleted, you will crash the application...

-
-
-

Note

-

Implementation Detail: the inspector support is done with -Slot, Record and getString().

-
-

Controller Basic Snapshot
-
Controller Basic Snapshot
-
Controller Basic Snapshot

-
-
-

The Settings Tab

-

Here comes the description of the Settings tab.

-

Controller Basic Snapshot

-
-
-
-

Python Interface for Hurricane / Coriolis

-

The (almost) complete interface of Hurricane is exported as a Python module -and some part of the other components of Coriolis (each one in a separate -module). The interface has been made to mirror as closely as possible the -C++ one, so the C++ doxygen documentation could be used to write code with -either languages.

-

Summary of the C++ Documentation

-

A script could be run directly in text mode from the command line or through -the graphical interface (see Python Scripts in Cgt).

-

Asides for this requirement, the python script can contain anything valid -in Python, so don't hesitate to use any package or extention.

-

Small example of Python/Stratus script:

-
-from Hurricane import *
-from Stratus   import *
-
-def doSomething ():
-    # ...
-    return
-
-def ScriptMain ( **kw ):
-  editor = None
-  if kw.has_key('editor') and kw['editor']:
-    editor = kw['editor']
-    stratus.setEditor( editor )
-
-  doSomething()
-  return
-
-if __name__ == "__main__" :
-  kw           = {}
-  success      = ScriptMain( **kw )
-  shellSuccess = 0
-  if not success: shellSuccess = 1
-
-  sys.exit( shellSuccess )
-      ScriptMain ()
-
-

This typical script can be executed in two ways:

-
    -
  1. Run directly as a Python script, thanks to the

    -
    -if __name__ == "__main__" :
    -
    -

    part (this is standart Python). It is a simple adapter that will -calls ScriptMain().

    -
  2. -
  3. Through cgt, either in text or graphical mode. In that case, the -ScriptMain() is directly called trough a sub-interpreter. -The arguments of the script are passed through the **kw dictionnary.

    - ---- - - - - - - - - - - - - - - - -
    **kw Dictionnary
    Parameter Key/NameContents type
    'cell'A Hurricane cell on which to work. Depending -on the context, it may be None. -For example, when run from cgt, it the cell -currently loaded in the viewer, if any.
    'editor'The viewer from which the script is run, when -lauched through cgt.
    -
  4. -
-
-
-

Plugins

-

Plugins are Python scripts specially crafted to integrate with cgt. -Their entry point is a ScriptMain() method as described in -Python Interface to Coriolis. They can be called by user scripts -through this method.

-
-

Chip Placement

-

Automatically perform the placement of a complete chip. This plugin, as well -as the other P&R tools expect a specific top-level hierarchy for the design. -The top-level hierarchy must contains the instances of all the I/O pads and -exactly one instance of the chip's core model.

-

Chip Top Structure

-

The designer must provide a configuration file that define the rules for the -placement of the top-level hierarchy (that is, the pads and the core). -This file must be named after the chip's name, by appending _chip.py -(obviously, it is a Python file). For instance if the chip netlist file -is called amd2901_crl.vst, then the configuration file must be named -amd2901_crl_chip.vst.

-

Example of chip placement configuration file (for AM2901):

-
-chip = \
-  { 'pads.south'     : [ 'p_a3'     , 'p_a2'     , 'p_a1'     , 'p_r0'
-                       , 'p_vddick0', 'p_vssick0', 'p_a0'     , 'p_i6'
-                       , 'p_i8'     , 'p_i7'     , 'p_r3'     ]
-  , 'pads.east'      : [ 'p_zero'   , 'p_i0'     , 'p_i1'     , 'p_i2'
-                       , 'p_vddeck0', 'p_vsseck0', 'p_q3'     , 'p_b0'
-                       , 'p_b1'     , 'p_b2'     , 'p_b3'     ]
-  , 'pads.north'     : [ 'p_noe'    , 'p_y3'     , 'p_y2'     , 'p_y1'
-                       , 'p_y0'     , 'p_vddeck1', 'p_vsseck1', 'p_np'
-                       , 'p_ovr'    , 'p_cout'   , 'p_ng'     ]
-  , 'pads.west'      : [ 'p_cin'    , 'p_i4'     , 'p_i5'     , 'p_i3'
-                       , 'p_ck'     , 'p_d0'     , 'p_d1'     , 'p_d2'
-                       , 'p_d3'     , 'p_q0'     , 'p_f3'     ]
-  , 'core.size'      : ( 1500, 1500 )
-  , 'chip.size'      : ( 3000, 3000 )
-  , 'chip.clockTree' : True
-  }
-
-

The file must contain one dictionnary named chip.

- ---- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Chip Dictionnary
Parameter Key/NameValue/Contents type
'pad.south'Ordered list (left to right) of pad instances names -to put on the south side of the chip
'pad.east'Ordered list (down to up) of pad instances names -to put on the east side of the chip
'pad.north'Ordered list (left to right) of pad instances names -to put on the north side of the chip
'pad.west'Ordered list (down to up) of pad instances names -to put on the west side of the chip
'core.size'The size of the core (to be used by the placer)
'chip.size'The size of the whole chip. The sides must be great -enough to accomodate all the pads
'chip.clockTree'Whether to generate a clock tree or not. This calls -the ClockTree plugin
-

Configuration parameters, defaults are defined in etc/coriolis2/<STECHNO>/plugins.conf.

- ----- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Parameter IdentifierTypeDefault
Chip Plugin Parameters
chip.block.rails.countTypeInt5
The minimum number of rails around the core -block. Must be odd and suppérior to 5. -One rail for the clock and at least two pairs -of power/grounds
chip.block.rails.hWidthTypeInt12
The horizontal with of the rails
chip.block.rails.vWidthTypeInt12
The vertical with of the rails
chip.block.rails.hSpacingTypeInt6
The spacing, edge to edge of two adjacent -horizontal rails
chip.block.rails.vSpacingTypeInt6
The spacing, edge to edge of two adjacent -vertical rails
chip.pad.pckTypeStringpck_px
The model name of the pad connected to the -chip external clock
chip.pad.pvddeckTypeStringpvddeck_px
The model name of the pad connected to the -vdde (external power) and suppling it to -the core
chip.pad.pvsseckTypeStringpvsseck_px
The model name of the pad connected to the -vsse (external ground) and suppling it to -the core
chip.pad.pvddickTypeStringpvddick_px
The model name of the pad connected to the -vddi (internal power) and suppling it to -the core
chip.pad.pvssickTypeStringpvssick_px
The model name of the pad connected to the -vssi (internal ground) and suppling it to -the core
-
-

Note

-

If no clock tree is generated, then the clock rail is not created. -So even if the requested number of rails chip.block.rails.count is, say 5, -only four rails (2* power, 2* ground) will be generateds.

-
-
-
-

Clock Tree

-

Insert a clock tree into a block. The clock tree uses the H strategy. -The clock net is splitted into sub-nets, one for each branch of the -tree.

-
    -
  • On chips design, the sub-nets are createds in the model of the -core block (then trans-hierarchically flattened to be shown at -chip level).

    -
  • -
  • On blocks, the sub nets are created directly in the top block.

    -
  • -
  • The sub-nets are named according to a simple geometrical scheme. -A common prefix ck_htree, then one postfix by level telling -on which quarter of plane the sub-clock is located:

    -
      -
    1. _bl: bottom left plane quarter.
    2. -
    3. _br: bottom right plane quarter.
    4. -
    5. _tl: top left plane quarter.
    6. -
    7. _tr: top right plane quarter.
    8. -
    -

    We can have ck_htree_bl, ck_htree_bl_bl, ch_htree_bl_tl and so on.

    -
  • -
-

The clock tree plugin works in four steps:

-
    -
  1. Build the clock tree: creates the top-block abutment box, compute the -levels of H tree neededs and place the clock buffers.
  2. -
  3. Once the clock buffers are placed, calls the placer (Etesian) to place -the ordinary standart cells, whithout disturbing clock H-tree buffers.
  4. -
  5. At this point we know the exact positions of all the DFFs, so we can -connect them to the nearest H-tree leaf clock signal.
  6. -
  7. Leaf clock signals that are not connecteds to any DFFs are removed.
  8. -
-

Netlist reorganisation:

-
    -
  • Obviously the top block or chip core model netlist is modificated to -contains all the clock sub-nets. The interface is not changed.
  • -
  • If the top block contains instances of other models and those models -contains DFFs that get re-connecteds to the clock sub-nets (from the -top level). Change both the model netlist and interface to propagate -the relevant clock sub-nets to the instanciated model. The new model -with the added clock signal is renamed with a _clocked suffix. -For example, the sub-block model ram.vst will become ram_clocked.vst.
  • -
-
-

Note

-

If you are to re-run the clock tree plugin on a netlist, be careful -to erase any previously generated _clocked file (both netlist and -layout: rm *.clocked.{ap,vst}). And restart cgt to clear it's -memory cache.

-
-

Configuration parameters, defaults are defined in etc/coriolis2/<STECHNO>/plugins.conf.

- ----- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Parameter IdentifierTypeDefault
ClockTree Plugin Parameters
clockTree.minimumSideTypeInt300
The minimum size below which the clock tree -will stop to perform quadri-partitions
clockTree.bufferTypeStringbuf_x2
The buffer model to use to drive sub-nets
clockTree.placerEngineTypeStringEtesian
The placer to use. Other value is Mauka -the simulated annealing placer which will go -into retirement very soon
-
-
-

Recursive-Save (RSave)

-

Perform a recursive top down save of all the models from the top cell -loaded in cgt. Force a write of any non-terminal model. This plugin is used -by the clock tree plugin after the netlist clock sub-nets creation.

-
-
-
-

A Simple Example: AM2901

-

To illustrate the capabilities of Coriolis tools and Python scripting, a small -example, derived from the Alliance AM2901 is supplied.

-

This example contains only the synthetized netlists and the doChip.py script -which perform the whole P&R of the design.

-

You can generate the chip using one of the following method:

-
    -
  1. Command line mode: directly run the script:

    -
    -dummy@lepka:AM2901$ ./doChip -V --cell=amd2901
    -
    -
  2. -
  3. Graphic mode: launch cgt, load chip netlist amd2901 (the top cell) -then run the Python script doChip.py.

    -
  4. -
-
-

Note

-

Between two consecutive run, be sure to erase the netlist/layout generateds:

-
-dummy@lepka:AM2901$ rm *_clocked*.vst *.ap
-
-
-
-
-
- - diff --git a/documentation/UsersGuide/UsersGuide.pdf b/documentation/UsersGuide/UsersGuide.pdf deleted file mode 100644 index 181cb75f..00000000 --- a/documentation/UsersGuide/UsersGuide.pdf +++ /dev/null @@ -1,2494 +0,0 @@ -%PDF-1.5 -% -60 0 obj -<> -stream -xMwaF}?1ubuа&r]4tsCqa=99v'$oWYպ\Wj^xmX-y5_We{n]-W~oweoպE"YUʬ4̚?˓vU-W뫿Uբ톟՟ժTwysx]>rփ_YU5-B\ D.Ov\/]M:W| >?2>gj[j뱯|z=R6OU{F|Sl;peU7׋j|Qy|9f |SVVլ|v3ooNϛ[¥oߤ_jomy)ZjoҲXVke][j -V+ZMQ7j9Fz6eo~oԺ9D.Ze7jEӥ lozQu] 7jsP*n4p6QAioEsPz Sv\y7Tfd~Gķ wx]T͓|% TY(~7^yތӷ_fL&( ? ϛMpZKZٕ 7v֭%7Zr49fF-E$/evkIflMnIM7i; -6 |ۭ%ɛQp6`=&mFߤ(XOn-IrWFm7ߨ&X֒(X `1FmFo{ 7j j&ndlg2+GA=kƷv7MO3:w/ͪ[fxB&d`y&Lə g2Hd$g}H$g}Hayև!y)lևY>$g}X!9CrևYVg}H!9CrևY>$g}H<YCr>>Uci`/1&Dy>!:B.an)z*>$gX"93Erf)R3S,L"93Erf3SgK`3S$gHL"93ə)3S$g8L:3Erfə)3S,L"93Erf)VgHLq)3S.2%/ɜ4S̔}&:g:Oə$gH$I"y&L3I$gH$I"9LI"9DR&Lə$3I$gH$2Mo𪴯V<᧾>voc?}?rrzT}[ywo߭Jo^УM7xO.W˨N~s7/ntuZJNN%T)I}S%'2&U Urjy*9qJN^V'SXI4Vr"ky*+9JNh%OiNj%^cW9[ԻYn=|o?nsr܀t?CWuuPV9J΁Urs`<V9J΁Urs`:V9J΁Urs`<V9J΁Urjus`u?J΁;+24{5 uσ_ntУܝiyϔ;4%Ms&5a4LrN$4LrN$49ޟIiLY $g-HZ`yւY g-X 9kArւY g-HZ 9kA$g-8ޯY Z'ojOÚl^7~wz]wU~<{o|uqw{=%wRIN,O#$9 6IN$'B!!ɉDHr"8:IN$'B!!ɉDHr"$y"du"$9rDЀOPNY|o޽X}or5Jco:5:;=87TCsWi:&OI.O'˓'K`u/|xCPY]6`~]pvZ]mwwydkΚD4#7UGR9JΑTrs$~=@Ǜۗj3f?too|kѾwR!IN,OC$9! 6!IN$'D"" HrB8!:!IN$'D"" HrB$yBduB$9!rRm>ƔYy-fs/2o>>~8 .SI<9˳_w c=L}b,91<1[KN%'ƒcɉ剱}%'ƒ2&ƒcɉXrblyb,91KN'V'ƒcɉXrblyb,91KN%ON%'Ǝ1_c1.o>]֓>l 䜠[M 9@r6R ,&M 9@r6l˳ 7lK` $gH&M 9l $g8&:@r6l ,&M 9@r6VgH&p .M0&XO_&ww[%pKN%'ܒ'Rnn [r-9ܒ |,~ -+p|aOPo'/ށǏM]"*NS{iä^iB4w;MN4wOxi4q:mw;Mٝ&JuuDi4I:Ew;Mϝ&N'Nr;MɿB~]ǧʪ<[~~קO: 4k.Vw<<<iC^f7N We^ͺ%xv[t^s~=xsxSպx஀wui]Kz:_ -(ߊ9]WͿoF Ҍ:o1j ->o6[?F.eWY۷ ªhm(9U*JN%SEɩTqhu(9U*JN%SEɩTQTTQrx_Eɩ>r;]*֥=꟪x ]./mSm֛}λH'IݟKΉ99<'RsoyN%_rN%_rN-ωđ#y)l&Lə83q$gX#9Gr&LǙ8VgHđ#9Gr&83q$gHđ<Lə8Gr&>6q8j۽͇|2]s~S|)햧viiԴ]r.9mKN-O.9m 6mKN%vvi]r8m:mKN%vvi]r.ynu.9mwokUE'?\?>ϛ^{^!9K, Y4$Ґay, Y4$giXx4$giH^!9KCr, YgiHҐ!9KqY4$giHҐay, Y4$Ұ:KCrҐq-Y6gUQv{Yユ?m~0l3XL Sr)9`Z`:Sr)y)l)9`JN0%''L qiu)9`JN0%''L SSrxL >̂ͬZwo^U>&zǻ<_ܴ?mV25Y`<}!)ZbZbJN1%SL))}1%2SL)Sriy)9ŔbJN1VSL)Sriy)9ŔbJN1%O1N1%Ŕb^cϊj;a\ϗ]Z4~ǫ?q}On~|ew 7#=ú[GY޳^Tl_ey+Wތ< 8OV1 -endstream -endobj -65 0 obj -<> -stream -xY[o6~߯PUޔDVk+uE%nRm}74eJ&yT|.HC -E %5tqu[brN - -Q]0*լڴpL.Y7:P0 ׋Cөkr{ #´Sb -71 Vg *,+(#@ZUFN5KrUXzfl/*+c,9 -aCpnH$Xñ% ׸L"[l("'@ -)J$(Q|7ztD1+tx  @˜!F̍՛M\MҴu x&ˍ@ǍzpJyjC͌Rs7zlp>Yͥ $84& dNdD)RI? ;_"PwbvP؍6!!z9mϋos`HD8+`mw?βC#`s4!k tmU8&;F_eTmBRb%KzD.m ke*;G9"0Hdaxx%P"K%RzH򻦞Ý*$z X8A|]іI@5f6 SPev@ U7U;}j6=zmWK۷xh/>@%k9q}}3j*fz9hȌ8b]&fe[4 ™5 ?DKf1 ӝTRDDNRX3 =Ox&Á_ǽ_&gw fJ,CuK?ܳP3%Q6hx,F$y#jHdFT)6==F:F'L1cS@'v.na깁[F shOVs4gkxRxpmdRٻ@ v{D˴0wP宩7OwƳql T0xuǖ4k$սd>7/`G[TR;Ϻp4uX+G}!Sga)Pd!.8q\Fգ_ -7Ճء[*.߮NGi}5Y6 }PD/s:P&H=ڠl9vi`!9RU=B#ȥsnb){{ٻ؇ڃڄ?'mMhþp|[-.kD.2xF%:zswoЇOw޽/>]|[^F Y=Ia + -'x$ԪC몤m]᡹9YrOvT}G&<_}$ -endstream -endobj -70 0 obj -<> -stream -xZ[۸~t] 3M"i[ckW<@P7GRfv=fdU/|I v$ U8V^`ǽgF.c.G~adD~4ʯt1 q"fB9*qN& -O/Bt\\PyR*AE tn%]%7|z"E؟"!Zw$+V2?k·}stHalkFXe&KDZ*w)W;֣jz^(#—nIv)0lE%箆ݝ>aK(VG2`)oTulզT0ߨ,;}ovOb#"TI=b0ٕ#r6C[CB Hư89{#+Kf2,4m! ‚  M~KVUg5/"֬Օ-K.!wS3T%qߟw{;`a(m璨 xֈ0jxHt6j"whb>x_>6m )2EYUޠ:vgǾ$Ok~,(125:GSu^i rA潝َ: 0tLљ89=o~ҘN~q<{v -@q^FĐ Y %D2%2%w<%7vnR -MAX(PXZ(_p@CQL4jQ Zc;G^:a' |Et! ^Lar"(ٯɒ4H# ]eLPt6Y Œl'b*O+K*-A[FGˢ Ա)ZfeGknSvF=HayQD*"KuQ=B1\$[`HV.1R`6X/7z?m\&(Х` jξilcm}qrYۀ "vVMIQWԉNX&m凚Wy?_+Bh5EC}XקKjZT:k~55uuNqM- ݑ e:ݨW Ǿo >|p+SΨJbrš*׍Yq^o9e^v2\z+EWʌM(&h=<ERa]}F-`Uv6a2G<0,o9USۛ 5*T{ڤUR:lU9c^w)}'0hok% -ɰO9FX!#j_uhm'eꍈJJ'/@PQm0as8&=Mq[0)"jgHI@zl9 4gFB4A킪v@%yO3af9xADbHPgI9lzű6%z;T2#|e'#SwP% En ~/Q[d7f$;tŔtf%}7S6XGKɗ4_"Dgٰ,d=.[GcXGӃ.j;4;v[;gi $@zNaMA^>`: W6u@> -stream -xXmo6_$- 3+H>hEՒ>uPa~7:H=wt%Q8$Y"z! - -2 o#)5G)?~rvC՚ELfTukqX".-Tݓ'OjV!4ѿ~ͣ~+kr:3&D6RZ{ ʧCtr>\A|R,)`Z:C4=]|rh^[DBezwX$ Xõ9L٩Np5B'Ȩ9;qn"IPc>%a?=\K*bVRFWM4޾+m/a֢r99`e[J9orLFOQ~8ԛѥH:Q"vuӏ`u09 HwSЍ.'*mj;(؛XKSb@l4xp,#%zY$Dɣh{&eg vijsX T[kǭ@gA1,f+8:#jͨy2:@:WLPWs9 l%q< l 6rDnόOWrucQ<8lj{Zj7КwRVcg!N0C%ľsM{jn>)5V3sV,C .~10)#OEˁ6"F(젯cc9jj[))zּz:%p/s]ĝV'D+.Ec --x>";U:OL5>2q7h)]q=PA_}1d+{%rT?K 'ң2$8eSo`{1Xi'Ic SAmmTxd+c@-AàX1)..Q;dAߵc_ù R+`o yS@3P$jzHфLOTmF'5E>xɖԣ5M1C|[ntZ%7qA 8n~3;WR:oV>3H>ik&$RH*5?lř,M/b--V0It9Ƣ7z 9Qs N֐8ϷCHƔ_(T &.z.l .||P(aK>w1>WQnkRQəJ4񧪨6ǒGnAm[qFz-q V ]랟Ax)̽n)$3y4{qUF>lh|z{S?+4 Xᱻ$5QIw F̓e6 AYb[N^p7ʫq+Zbhfe_uR:>lޝ»̈́BsRM1d< ~^paN8^kIL6 7B@6]wjٹ'7NLy-VJ9,Cy:a>~!z%l -endstream -endobj -80 0 obj -<> -stream - -endstream -endobj -82 0 obj -<> -stream - 84H84H8HH84H8HH8HH$(Мx,hxH(hH(xH(hH(xH(hH(xH(hH(xH(hH(xH(hH(xH(84HX;8HH((xH(xH8hX(xH8xX(xH8xX(xH8xX(xH8xX(xH8xX(xH8hxH()hH8hX(hH(hX(hH8hX(xH8hX(hH8hX(xH8hX(xH88HHHXh5$($(hX(xH8hX(xX8hX(xH8hX8xX8hX(xH8xX8xX8hX(xX8&hH(xH(hH(xH(hH(xH(8HH84H84H84H8HH84H84H&ма$(((84H84H8HH84H84HXxX(xH8xX(xH8xX(xH8xX(hxH8hX(hH8hX(xH8(Hh/аааHXh$(XxX8xX8xX8xH8xX8xX8XxhH(xH(hH(84HFHHX$(8$xH8xX(Hh hH8hX(xH88HHHXhHhhXXhHXhHhhXXhHXhHhhXXhHXhHhhXXhHXhHhhXXhHXh(48(xH$(xX8xX8848H$($( -hH(xH(hX(T((x84H8xX( 848$(xx xH8hX(xH8hXh848($(x>xxxxxxxxH$(xX8X8 HHhx$($(bhX(xH(hH(xhx8$(hHHHH4H 8$X8xX(HHh$(H xH8hX(xH8x(X8$8x H$(xX8HXhHXXHxX(xH8hX(!Xx(HH88xx84HHhHXX$( xH8hX(xH8𰬰($((HHHhHXX$(xhX(xH8xX(РxH4(HHhHXX$(Hx -xH8hX(xX8HXhXH4(x($(Hx!xX(xH8xX(H4(xH4(848Hx -xX8hX(xH8H4(xH4(X8($(HxxX(xH8xX(>HHhHXXHHhHXXHHhHXXHHhHXXHHhHXXHHhHXXHHhHXXHHhHXXHHhHXXHHhHXXH4(xH4(X8xX8848Hx -xX8xX8xX8H4(x H4(H$(xh8XH($(Hx xX(xH8xX((()HXXHHhHXXHHhHXXHHhH4(xH4(H4X8X8848Hx -xX8xX8xH8H4(xH4( H$(h8XH($(Hx xX(H8xX82HHhHXXHHhHXXHHhHXXHHhHXXHHhHXXHHhHXXHHhHXXHHhH4(xH4(H4X8X8848Hx -xX8xX8xX8H4(xH4(H4(xh8XH($(HxxX(X8xX(((HHhHXXHHhH4(x H4( H4X8X8848Hx -xX8xX8xX8H4(xH4(H$(h8XH($(HxxX(H8xX8)HHhHXXHHhHXXHHhHXXHHhHXXHHhHXXHHhH4(x H4(HHhHXXHHh H4XHxX8848Hx xX8xX8X8H4(xH4( H$(hX(X48($(HxxX8X8xX(((HXXHHhHHhH4(x H4(ма($H$(8$848Hx X8xX8X8H4(xH4(xhhxHXX($8$($(HxxX8X8xX8HHhHXXHHhHXXHHhHXXHHhH4(xH4(HHhHXXHHX8HX84H(48($8XHHX8H8H4HH$(H4(848HxX8xh8X8h48xH4(xxXhhHHX8HXHh -xx8$hH8xXH($(Hx X8X8xX8&((𠬰48xh48 H4(84H8488$8H 84H$848HXHXhxhH4XHh8848Hx X8xX8XH 𰌐xH88$hXhhX8H8HHX hxx H4(hHhH($(Hx2xX8X8X8HHhHXXHHhHXXHHhxH(ЬxH($($8($($(((($(8$884884X8HXHHhH4(XHh8848Hx"XHxh8X8xxh ($($(hxxXXhHXhhx H4(hHhH($(Hx X8X8X8((84xxH4XHh8848HxXHxh8XH H4(hHhH($(Hx X8X8X8CHHhHXXHHhHXXHHhHXXHHhHXXHHhHXXHHhHXXHHhHXXHHhHXXHHhHXXHHhHXXHHhH4(XHh8848Hx -XHh8XHH4(hHhH($(Hx X8XHh8H4XHh8848HxXHh8XH$H4(hHhH($(Hxnh8XHX8H$(H4H$(H4H$(H4H$(H4H$(H4H$(H4H$(H4X$(H4(H$(H4X$(H4(H$(H4X$(H4(X$(H4X$(H4(X$(H4X$(H4(hHhH848HxnXHh8XHh8XHh8hHh8XHh8hHh8XHhHhHh8XHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhHhH($(HxqЌxМhXHh8XHh8XHh8XHh8XHh8XHh8XHh8XHh8XHh8XHh8XHh8XHh8hHh8XHhHhHh8XHhHhHh8hHhH(848HxxH8(4(848HxhH_848($(848($(848($(848($(848($(848($(848($(848($(848($(848($(848($(848($(848($(848($(848($(848848Hhxhx -endstream -endobj -84 0 obj -<>/ProcSet 83 0 R>>>> -stream -q -48 0 0 48 0 0 cm -/Im0 Do -Q - -endstream -endobj -88 0 obj -<> -stream -xڝWQs6~Per:$!} "͵CN\cq&+$@$tt^zg2I->f!TeT.HlvͣՅכd.Kr"pKa.|Ofz@c8 BW:[ܷb8B[8}a*^B|PIXZ]:RH2^*ǼUOt:bk6_Z|)A(X HM//OV{wOz^=}y|{+ӷ -a6}x1 iX%KfdVdvq$z9:IM^&Ϫ#t*4oM%Pe"B5"+)`x+,;PeF[8v/\- %h#\U -nPZXR)t傺N|U'x\bjfi% f`=G_ ||hq%~mU=:曨֩i|_$@ءzFE}Vx&Gt؃X)4/KWf2D9&aoOX5 2kpX]3p6R2csay#e*bstX Ͱz8sښIS?tE施 TaB E+2z&z#kjT+;RZVU(TT&_>}:J25}o|T ,ʐ :`\ܵSf2Y׊Ϫuj.b̻y?1/ -FPxo1Y1s:s8Zg>KA3g?0fc\[odtOnsh`Si#Vp!x8FP ;O -endstream -endobj -91 0 obj -<> -stream -x[mo_"f߸K~*(xHH6-˥/kore0drٙgfghXd%i.+"hP4(A×bΫ6k8 y}qۀKX",\4\7WgIĸ%{O6%bF< y&S"RyUܢ,M—-_fgĥH%#a&0^$X$J`AxXA4lk벰 x@(#i.6GV,lW޼^+><0IA8`&Ǐ?hA#[jڬ,{BpI?`So(fZ:bE fLo1""lک*i!svA& )* ) b7ն,wgQ273@<q*Lu(b`p)u*9QimZswUeƹ1w-Z0 3ʚ/\M' u#.ʝ53F=C2f14=4G -n!2 Q!"!2I]ۄ ES / \%݈8b$oBz|m;!'煮EzB@!Fə&*"̵ 1 -mf@Sf -1Kgxۆx o*"扫V$ j`Iʝŕ FX -EMtpߏeΪmC -. 5k ޙ{#P!M|@iMzKٶq0/y -p\e+ͮslۋ6c*6_ $"^!`jqMeDoAxJtTEd*1ӎkC bˮۏzCPOOa¨)E: )=e)2eIh3aId〠C4#7E] Lp}&9hC\hȳ1;"ISKⳟE9' Ǔx,5$c~@,{y WE ! 1iy~WˬjM(yʔ5:!|LYElcQ{֝o4> s.[ PKE,1-2D96m+>SXA&LۚU4{l\]<8fX.'$":9r$)Q?8%sKЇַ uF5jpӌpqwY?>{Iˈ`Na_Utx$ r>-rzy.*˼añ "C)$xɤX^YLj2OM%޼'\u]UIٽהMr"DzgOi )hH곪7b̛R\|kwyFs/aO=~ZNЇAL[s$[c)w.*0e_Mr2TΞͼ,Lz{{STڒjĜ_{ST+12q9ņ7gֿ2|%&x^ NU]̚N"HRXj}&*)3Oc|7t)1jVN1G+Х Ӧt -c;KMjOpwvCku7x;L=d=3ǜď&lc5B._˧B̄zr΋WHlc~f(̫ˡvKc/NsNҞ>Sa}SR!cFp7G\2kE_U)c'uBr\LkicٵMJ Y)FXg(K;}E*wL┢5E] +\I%go LۀOcs> Oi>=\<{0`>~Ց̃>e1?4@cZ}h8=TK| ifRLP=?oEO$$ɏaX[aHi!B Ԫ]'Ыb'R+QIi0;˟ YJ`ˈ3 IӌOs -Xn^_,\y7eo*]"3Jb]̊fv&aw6~ߟ!3 <#IVk}OhW,8ѵ}]=,,$,q댩SJ/->~nGlٗʾϊ2#k:_?ϏCU!+Kr -SC~k> -stream -xڵY[s۸~`C3;SJlniRx=ulIȑ"u}pK$q988|o5lO  4ư4jdPа|R\|8+2ɳc AgEcS58HnհKf3+Gǥ Oz}J {ᜄ^Uv;*;. =Ȼ*IIv$OB)ګ r1ɬ(a͢Bfɖ2ge4Ɨz<;f")ҦޱũmU3űc则gТLΙM7c89RiMO|@!b~w*)a=UmX1O?Eg܃Xbhť Z"%Fy`!9ϦO$M lB4>+y@YXE?Ƴ󸑚H8 ?Vy|լaBr-(-B 9BOİ?W͗lahYm-϶Mkn{a;<q#Ge>HV2ÅXt`M|g]0[e9`tisrQEw)G؏:? 6VBzmDN$!].quyʢ 0Rm{*_ 8i@`Ae"2^w;H|~M6ߕvy9s٢0\Qаf" -R|eYW_>;8jz#O>^Golc?vE]Di_bY,``2E@-g& ?"u89 'jS%p|iq`RqLrgtJ\AvYucyRi"^BT%ű*/]쎺Y!;MiKlNj)|s)5{ٹbw3huu8msTqiʸOVF+ 򵛍aY=7Pt$\$ nMGjC݆j{A;O y (ִUuLyG8Sk,ݭ׫uu>km_E[_Ջ?}`hmC4rzy.=4xX4A֖?rp(CKEǑynr3'~"P∧2ў&DbJ4KR}APXλZ^njM&U6h9&EHu(. -Ъ{mA}զq1|k%*J86hRIkkrۓacf+Oq #!% D@iIOqRsCP0#BZH=1'Qe$O>9edVI,:uka-|sZ \7׎Co8\cWEz!ԮӸ %1 3s0B|*0Z9A9>CO;g:@F| A ho;xA ^x#+&r t?,i  -gxm"[hW}{6JpbxnZD@l] > -stream -xZ[s6~_2w#HLw(TD*zUD\II=n;;^ccq[]{7`/Eazfހ{O<ڬ-d@ԧhM$_7'8GS15$ j% ?CQ̼zMk/xR99PM ~*+4IrQjimjAhy S#5 $c!<5[h\f0ÓAL| [‰p'`BT -9Qaj؉\y~C=v@ )'vxC/ƿ7Ǘ4)E4d(sa$O\,'C%SHŝ}RzKm3<6-)_h ,T̴/Ԩh8v!ҚM^p8Q-w -TcGdmo"ۅK P`,Z9IRϑXuQ/$ny3<__|Yc(1 N*\H, ]N#DlPZY z -qg3b"|3-n'0bQ9kaXEQw/ZBQYaOe

JQ7DKej]m7WA " ]NcdKP%EQ `Hqj#-vZ^H0m6wg.?rgMӇB,zthjI&J;lYG*ﲲQT^hE%q nc8U/( &ݙX ߬W+PhO >#A͵3GJӬd\@(pFP5 oo&ţD>;8R(z2GUvQ0Eamݯ!$iw^H{&Ġq/[aڗBdK!M,)`cԕ2kY -#*u_u:Xe!ІQ_XIޢ]['A5?cԕ"FΦ*jFeq*S6NdȔYqi^bΥ/7%ȃ Bv0Ni;i|4J EZ?Hdzbgb\T[mLKGZ2KP5]-2Ŭ1Q^,. CA ʦŷB‘h, W30< p@^¨13UiBy/:o^lܧ+R-r n#U‚=gR.Dz|wĠ˓Nc)ge1wL+Q7YB;K{ gN pv.G1 - y|\kTGO!&u#SpܱGas#Ѻ12T]k-4L -p}0qLQdLS0ߦ/vh(|V_܊zex.* -Bfu+7_a'u@|'p 7tuK,?{PcXJwn$Ũ0yEhn'j{IdB r8f4/fei0+?Km g#Kc&Ƞ2S=:/uTV8XDDVҧ#N@7#1Q.E%0(ʼ VTy>n T E%izä{ vq$̤ŭҀ^7%b C^.!h-T3.8\,Izyv!׏2$Mmp7(e].Dn]k$NeEwrl7+<[u,v+WԤμe V{sٞѽڀL~0r4M"\D2G }_0W`ꁅuG/Dvip$ 00P%Ԩ9Ⱥ:`w CpYlN`j<_?j -endstream -endobj -109 0 obj -<>/Length 64>> -stream -x33T0A(Uȥkdkb`- R!2 -\ - -9\\\ܔ -endstream -endobj -113 0 obj -<>>> -stream -xYnF }W15`yA[6uܮmd ߗfFsHlQ$ϙCά2 pqiۧF%tk;|~I*pO$s79;ӵ(5JBA?Ƈ@oaZYZI=sHyWnFK!H3,RWx!-+ c&c]9"ՠ%Vl![iH\q=Yɢ!7BLϢnUBIz(k<(dǫ/ ;wCipFт[>%dk1]`̺FI[ԛ" zʔ-d 죧_J eY(e?c?mdoc %mx`DulǼZbT" =^U8Ift bUA"aaOf=%¡-~vE6"6żhZa m4m>g< ==ȖB"p-wB|X{#)if}޳;#MْH )e<_'55|@>znjAJ:h'hs13V IyxCBXЌh/NRVc(ub lHDLÓ"LBrM!B~Ș I>A Zِ '9HHo$s%ѐ)y-wȒDDWzft\#S0ƅTI4>mLƀUbkV@Y'Q[V rd/!U>Q@.&U餩B)$(? ٰZِG'ٯ#ᬅ z~%W'鼃uP«I ZMx>R`#Ve<6~c+ h{˅ c&ƍ&9$ ٲr65MMBZ/a :<(gh!r7[ b)ldžr iZ,ٴF 4fγLxW~!PYF5$_|(rRMty䅝3Z$Sn.bjCZ44.L*TC;EխtV.鋇swaiHMW-ƛXD϶mj ҒhamJ6`p`K,Uqi̝/.yX Uvyj݄O%Yz%#1hWgz ?+4y8=#uͫL6+ֽ5g DrtXk˜$veQh WRXWc6)^A׳VtJriW ƔY9wǭ=L@M("܏?_^p <_C#:'&5ZCTq(4nhQ2s8Ͻn<=y|b\G;.kfB*&/bQ(|Bwǚ)!鹔d*})+'+sj(@xº=ȭ5V{f:p5-ywJ1 *ۯw - oJ Uh_vwcwWKߞ٥o% -endstream -endobj -114 0 obj -<> -stream -xڝX[D~Wx 8{ټ99v&v:ۻ ]${N]J3ӳj]U˩swK OI'߽M6CzǒH-ᇄdmb?ӿuXC1]Zs[k&Ö8o]W,O˃}z'-%\irQ1);_I 3FDM$BO8UCD2KEr (#2CZ ߱nOnH%|3Ź.=wa7X)MSʿ:s<}טg44\,vCp&Hޏ؜V,xpNs.z&'$Ld&JSdF2VwLykt͈1Nm+I.(}4 -> ^?wZK`R5rjںClIu_ypyǀb.) h TjO*w00խcڡjiz_ፄZM+(@dp˙֚G"}m;d.=BpcQV~(yjХS*bDpw憧}OnX=c]1"92pw;MW̓Aۮ1W)oau"(+Vn%}^AhħSSW>Zѳ07pphb_E AXPrnyU l .2Q(b8ʧzrF>wsWӄ ⼊a3=)5Bfv)/e!25)`݇Q˜tskz@˩?| W|eSV=9 zt+C1VXOOa]CZ dTD3F"zBO=9nI"S4Gж  cnw[,#y2(ƌB!5|sf 0I$71RPC?/0h Wnۏ*ģ`TLk. :pMy3;FBC,! BQߋV6F <ӻ߿~sdtX8F|78菟߿|?Vi[65)4j&[5Iܬi!GMammqbCgE(a2=tg}O쎟/#, - S->,*90Ȳ֍^N}{;`. o7h6%l2B9l~ETx K0aͥvI'bSi2)IOJ[7cwiKDMTաtFby F9*d2!kUy rSO:d/^1mqix[5#7\fԷ $X9s}uB=q7[&ZUL fJ_{rĄSz =  QW~:[zzap8>T PFQ#ڒ Vb/`]g\ -[z=z'4F8612|H[Dǔ$'M@C^׈Pڮ+7AVѹ>-1yݾ\Z,y 卽%K2IdtB> -stream -xZmo_"*Nk h=JtD*nZ!8wf߸)K,r83;PѯdUtuw "* STFݏifE슮j)KƯvx& WjBU<;ӷNDϒ'qKv>>.׈~s)%fLNݗ+fe=)/ѻn 2*㡯zG׏WGWo?ҚMyȚ+#0L◐ir S+mvHA>:/&TxO*xOzVCM|d%l}-(U$2ç:c#/W7ș -Նi=K99r TOeUP"S@*)wtJM1S*Fu`%̐D5E-Y%1 \• vJ =(hѰxQuCPUݮ؋| _Qn[~#*M jTu^]9'fr -" -9܈QgP3ugfkGZPtɃ̺a4em )U۵fVܯ?K?p{DlX$)˳0\2Ǫ$pb><u  Yb,&ƺ*gmиƙHi;),K]X@Œd3;<m,[M'x<3pc;Fˮ ϋh-kXGR7(! ~o4Bpjg)BsISsA0Ԙs et{8?Sm"L:ds!aqd'KݒqL{7 ER -iuK45c\c~˦3gY3/?ݕݦ -#$3L):1|[H>.cauagU̵$$\- -N:Mhzkjt6bdT˕=f=&)V(S(AVpǔoֶASV}mY.g-TCK3(2勡=FU{W^U}qTs|GXECk]ʂM"tj /h;R]{PE`%Y8dJ陙hu5m[.u,*0 ׮0NFKZB0x @ 7r)ho~B^oEl+2JbcH0^gfi{k00 lE.vb#$̆H I,pQt2hb4RG1'ҁ[gpa aJ H'rF"]6 a -endstream -endobj -120 0 obj -<> -stream -xڭZms۸_jw fhTD*n3$-^/X/"%i#]۳ nX _ 4n89F1ʏ\n48+2ɳpC_հ=!DQ89G'gNҶٕ|,p:. z_=?{ñm~m,$?(\mcDx O4AM JLawRS mcE_ &溚x,%R™Ƹ܁9u'vcMŚ v.2Ki_O<~^TI3[%\͏eM&qyX$ld^nVǻO qM[.4+rFT ٕez`y /yݬmy<ah,fYO'O-؉<9-c$xMFWWhW L"o9aq9;d,Oˣqeۯ[arɗz+جn؟pc-&jnM9gl9V<ɉ3z3NbF:u!e路wWROf -Hw8!}Qg' -H"_Nir+xĎ,xV'~rٟ>hi?6/,z|\=*)H: o^&f=# VY>(Pқ7yDZbwC~Mi~ ~yA4ǣ{ʆE~n"^1}E&ݾ8ǯpoL>u8 Iw9"yC@c!y|hoןVꋤ -xCEUHQ2\6@qͻh&D9UT^t[(5 ^ƃ;6b<',Lk^$T)$&(ITqYB+elbg^^Mf|QFRx-^ -B`iqA$;8OmDp#hEf4&q#1&4Ic-Wt@l -bku@pktyѹ,l沀CJ9i$KxBCzD&}qqĞ kYUH]ixvqr>Ko$ &Fy,ӈA|g H@*WV*BFAXW[{pJ>N?_p*K>Iu6t\4C6W,8RR]D3 WH Ӥyd`L~CB̖) Ei/2"~bB9+p;2Bp3G_l?k+Y: H2\6 _r߁@2_9P {<*y=#v_8+20xio WtCsꧣsLNF[q.MmȊO}ץݐc5^ss{7h_N$pn3ׯg <^PiZ դAdڧJkR@ fUM4&{vUU9F[-V Di>FI/"j -=)>E>HWYu%s"^P8דұ,v1x.OQ*پhǸo '*0 w-lfrn' 5ZH}|w4QĄEy^._3WkG ֏BB@mTm9b/|eHqI6i`S䯹=@pOpy)}U_P@S瀚8S2}GS:ʁ9v=A -Ufm8X'M)ί. K~X4B>T8 -԰O -PC^-|AA 9=;-[ԿV!VO e_ebK`ɴU8Zm7 ,ZW1_P'9Ӧw jGdP>E7K4# DU|-x jK}JN!r@TDS~+L55nv8Ag"[Ur~wQglա6$J ,*CSwwVg'drٰuzR tͪ.e?ܢ!(AP`VFo7B8{UtrwPQsLsٯEAg0MR7apȽUxHn*[L fqwXhcʡXl:LC&vz[]Hzѻ'<=Q`ת m?A%uclA"Fpijdڱ0w&@B4Ur$ڋ|Ntq0l:7n+<:P`؆˭Y^DחdUnhu :zgsQHU,];<`Zf͛-/$|.sJ 5D3 4G`Z{<~7h":HasHJ;ENY^9 ߥ|⹈+6_A -endstream -endobj -124 0 obj -<> -stream -xڽXmo6_9+l"z-N -`QJr`E(ˉ CH;T)H)6VlW-@98A_dkUT[3?F 8G}n{bqʩq3upbD0bScC3(ʹlЏFehSDMvߵ70tċ2麽e4芊O~ W-]9.ʣa^wq̢e%OLRk-k|tp<tLFsa2:?W,p&ߠMn&wQQQd\0-pYjX)*++͹n+5}57ߺ.ҰLؿ?2*n…"HY[kٮx}pW`` PMS؊DwLC^5%7HUWuR5ᐎu{/ z5&B1].6˙w.:6$)yVL552Mi2'04~H?# - -&t@-GMQn&2 bYQN ۻ3H‰މ?H$^#œc^3,s%H^Fæ㻇`2$yU4NB*8@&3*ưcR^L`ќM*tm\\ 9'^Eˡ7G,wt+"h0QG)bz%Ce4rQ6]I[!f(#PPMÀ5@HHlʎ("4m0 /Bgm -(VwmY$ mY+yf6 _QM*74؎fi(< uvE٨9z4Uma%&k"hםk41"XIhcYTItlE8)UXC:PW.'h[0s[Ge*LKEqWs} Yi*0*9xZEQ:b5G?\Iҋp~M*M?Vok U8. [5 gնN/tq%Y?u9fEr9lZDӑ\ GR BP.yCD'+v -hU<=O2.U%E)!xbq&-U!<uN TJ^Dh\dŨI&az) q@g}M kb=OEԑiOc?+R|/ϒ~xϴO=DhՑ/6Pcur+J4\$'kdW)'XwmeBwNiiW$t_} *粫sHzb4 -8 -v" : )#[.`㏃Qb-n3*inƄvBpEx=/2f7xA~U`I y{)\ϼu+:w&;-G^r17ӚV陛:Nm9H[i% 3uM6!r˛ E$Q[r[)aI@C:uɊqToDFʺ>)O - '#h{<ԷFy út0PŸ\ -ŕS/8ӿa -endstream -endobj -129 0 obj -<> -stream -xڽZyoF?TN83]:4ehGzWW$"$ZVRdU[Gx]esGȶ[M1GH/@>V2LKe:F jA'%XkhT<սєNMCA;B 8Ѣ0%r5m/hJj$4\1tuq@26aYg,o5\ᨂ,P7 oBe+PIʠLGӻӃA* L@g$+j5vp*/$xF5hg|4I3 $u):fUGٍa7|orkHsBw?( -.'UeG΀-O֮fCIv'?јot,1m|3=Hs 3lˠ5²Y6M7tK@`Hrܮ/Ʌ -?}?I|b7L_-rk=ȣ6 l,N:,"/GԽ£50wBVoB/>D9و6T2EmZ$i<1X4E\D*貛MձߩSqY7saeРfa7qOFgmBQ;(*O96j@c ;RsF)phe͸6gsv+j 4?_Yє p|0\R Yj%e:wYG;KofƖx褩Yz{akMt [x@{MnawCClAK~\?~@|lK>lR|:@v36W1gA& 1)7.q{ETPU?7ECCsA!՛ ~Abpa ب _]61^X<5٩sL miF7uP؂.B./~E'Bʿ9sO/6[ǿ}Y%o:'a,߯ Hw" q`Dˡ]Wg(蹸zĨl?d%Z&W +hHV[ ۓsl}DZ]"yvƖ~߿ߗoL3/6~cۚMTd^MJd/S0lJx#*KECKPvw5j7/{x7;*߶#@`[!B}WifPu/śTIg^~8Cs|oĻlNi_&ɷJ6E' iw^rAvgʖ%PM.[̄ERFx0cd-:9wM%Ekjƀ*[:(e4\R?3Y Sp, -;WZzV37C gA8 -c~05dʃ@9G9^?qM6@TŃw"͠MK ͐V> (c1"Sޗ/=6FoQ[ǎm{o F́J~_1 -endstream -endobj -136 0 obj -<>/Length 13338>> -stream -x DڇgnkPQ9TaW]wE/uuWE`YOXnA\\@Pn{ftTJ:?aO:g*D D["뒒@4tqE"eZH[$kV2[w+~p?_:61vE8q+W @[#Dԫ^sƍOaF?ZuEwnٺ-߶T۶Ám*gԓTa~Kbsr^ǎyճ\~YYTE"uNnڬi -{k{tem'U^;l>=:U|Շ*Voݧ{V5wީ5/-أmoߞB]]K dukc۴A?\r7|kc:uڴi{C[AEWvn ;7śY -ufvVё_{`qm_1NSmߴqn٫チ B@eǜѠ ORo7WhW]{s\Ε_nc\կ7}MHU߬iMNuO,X䴕]1oKJ-XhE%LG$ˮ:vןm۱y/^_Sl󩧞Cv??l?{֮o/֭_qa@pCKȓ]uvŧ5Ĕeo]U3:DGN7h3O**0c2f>4d?q=bw>筟>:7m*+8u6*8VƒSf'DtГk "W?`#ʆhqIT{Grjϫrt=G/ڝAn) v uK'.LNX#:ge/##?+p^so9y7:Rf}w*Xճ~™Z\os{J*U:Za.?Z53&wսlAx1Rcjo‰|n[I͕oWU9?^m8yp}W6-qj1=!fv可:k 7ykJ󁣟`c'|{~%D>G+\hʟs *-Gϣ_Ъù LW?b]UZ['|ˡOOk4f^[r{:~'8aI:x]CUizkwKsozۋT9 -wUkf?SsD LЪVO콣ߤ!~;h&^}[Ek?j};oɍ)kק2W,ыDe&12yKN wscW/ϫۂo'=3kS/zcGvvn}~WQƸã%f{j?}{ŏx@Vͳt֧zVsǰ@]4yUzOT-o;偹x밂GyKNzkBzx빯-qKǻھ}d> Z+rg\Ww>bAN^۷£~xw sOy풙G?55 ~'?/U5Ok1Y  qз^}=PrdU -'*tÜWZ;4K0N[WiԬa'߼/zù{ogOF[NnӱC l^|_+ -_s ါog>˦V뿻KJMJ}C~( @~nkYӧ^<[o/ -Ȯ\;yys|,kĕ~I$wuE;_9cUh>?H5Wvl]Z+5_~';WRn|6*jРzd{zhWxv <     F~wztj媸6_Z7-) F"ʂĀĀĀĀ Y]Nw=bR/0Ea ۝n*8=-h+@[8 pV m#8L.| ho E gg "!uDlhk)DWU׻;Vh_H2ڊկX$ެ"j"ɎJ\"fڲ-kR*IbN߿eFh VJ1:K\ - YNmJ)x|Pa>Q-zEh+j%ehVJJ[ UF+8]?XN"?CX Ѷ$J)>i+bbYXߢfĢ^%~K@0R -|_+5\z mɷ_9yFo+@[4jP8HKfDG/h9h+@[40jA[BsY W9o?m@-2Y|=rl:s =߸Ecm@r) |iYfr~"EB*ӷy&Q+z+ugr -6^[ۏA"!-wl}Q|Wbz+z/PL-B@[4Ȥ-~B:Cs-X,7e2[ cz~㔬mh5,`cC^7qxGՐ$j.$mڢ,&Z]S:C7W!o+l@[4Ȁ-ޟƟ2A㿻!jbUx-h|2n-YjKͮԖu-B@[4$5/w0VxdG1g1zmhJkh;_H3\:=1ޖy[aڢnD^/nɼ-*yM.LDV؀h`[;_MJ\׋?e1d- o+@[4j25X_¼-fXm 둷6-eyi L8¼-Y0佰y[aڢN[y[H\_fk7;Y_m@r)\DqsIFLFeNq|KZ-hVVz[y[OBVhh]d-n3&͟K6o˚!oKy[aڢ<|i= Gj|x{eu5#o+@[4XnDdL-ߓ-3s g -3 lITI+3< X}iK:ZxaszmhڲJe$ԕH}|= E Di4j EB3e3mޖC;Y y[aڢAe&bX {[K')ve-|p'"o+@[4$Zu//*9+7}&Ѭ -Y별 o+@[4V]YmSW|ˤeHTms1mh DyXT)g>m_z.m hm4kmrRp y[aڢP[f&^X^C1,7eX_¼-YGVh`Ԗe\kE5zy[֕빐6-h^ܡ9V4oKq.m2@ۅ\12mmm3~,z-8~hy[ -i6"U*f¼dmC2oDgr7S{b.cޖ(@[!e[X*m)/m6oM^Aj |ޖ-gmmíd -d]N~ImY bVaxaq%o.y[L;0۲E e m#9mɗջK̠{2ZTE$.*Ry[Fae+ E/崘imF[ksA[aڢ=Wb 0n(3bQaڢX^[[)*|nшY=6-z]`4AhQİmCK\x&1l@[ I,PA =mA[+-zJ~(ߞ1H$Ey[ -=ms;Eh!-z -8!-z -8!-z -v, Ey[mڢѼA"!-zq +=G4"EbQ\51RcTbҝmuaQb`M<@ -hmoi ڢy[:m1Q?T[N1hѦX$Omÿ-~fBILzmڢy[kѯI>!V]6LaDx_ޖ2oȲ-~>  ڢy[NVD7ϥHc]A[/oKf*2 mmQĿ-㼕Y2 _.P$ Hmÿ-üыht;*-ze -oMzt,] Y1H ڢy[&:hv&2(_ޖh]ci/z-,\lB@[/o.FRƻ^iKf - ڢy[gŋ$$J0H ڢy[BmT屶>!-z1of̸mļ$-hۊҩzcG1 i>؟AE7(mڢG4l/LO m h2j+qP^GLϗuڢG*=^~}(ެ4}=6-z,oKՖ{i,/Ab-GҷG DǼm#y[L3sI00kI|@&"4@[Hޖf+;HѽK՗UW]@[!ڢG@@Le!]F[$ -h2֯ϲm%6,?C[ڢG ܫz_#lʴ "ぶ-C7ee:eVm h2Ԙ2[?z~#aڢG 5fe6fVm?:-z oK_#\ͥYe]r:z,=۲jO-z oK~h+t@[ȼ-G}@?X6-zdXޖnC[aڢt1H =$ helZ/hCpMx葑y[$j}@h+@[ȼ-is!o 0h"emheq -=22o˼%fU h+$@[ȼ-fm## Eےgzm##[mmQy[a>-z oK~h+t@[ȼ-R,z Emꡭmy[$ hҁgEm) &@[@ޖZ-z o+$ -hjV؀聼-Fm h~# -=25olhFhe=%B[ڢGFmŤn]=kER8 -;=25o8 w$ h"ҵ -=22oK]E{[cD؀葑y[2_ -=22oKfI:-zddޖLzqLb؀聼-ׄhRB E r -w[ڢGmY\aVh+l@[@ޖn#Emimhe!]= /=22oKzh+@[ȼ-zi =22oKݿ5`E25oKx߈Ab؀葑y[y4zmm##$ۏ--ddޖdE-!+QYBIeMW_>+5T[FULo$mhN򶄘K-妖s,*z>BI =m -U %5c}wk[4j^?%.CN 3#&l@[p%$jz4'U^_v(%o\njڇ2kF\m hsLI?W,*ӓXnW_EM2.ܛLmk-B@[o|]Le޵}5"EhK;se¥r-m#mJ[n{om#b-N`mڢGڵܖ.m#ڒ2;n,="Etis[2J(m!$J ڢHe:9m ڢHe1$\c-f34m@[JmYD[ -Eim^pX$Om#mYWEhˢ_@[m4 =֖u&r!-z-f|PAem# y[!=RL -ϵ@[A[E[;[1m@mWm9%er: h=|mg1cF70=Ye[mmQom)Yth.w@[ [ʹ-]mڢG -'R-O,&Eh)Xv2 ̞Ei+,\/h=R6HjD]0Om#s[Bs:t+-B@[H-ao˿No,zEh)cg1ߴt @[葑 .h=2O[2(-?my[~mڢG8k#-B@[HYL~&X`E!-z o-B@[uJ>>21~Ytk-B@[HognmڢG@BE hK_km"Ek!o hiזs[Ng"E4jt(SmwDX{EhҖqr[-B@[H=$:].9!-z^[Ӗ'"Ekbɓ y[!=R-;}ɞ-2@[HѾ..6-B@[u[֕mmQ$ڲBa᷶5זӵ]mWm1󆆚T.w Ehrb2@[mEE hK?嵶mڢGڵŐ -Ek׹-]^mڢ"EmEhh=!-z o-B@[@ޖ@[聼-?m#mYWEmEhh=!-zgnmڢG@mV[fNh @[_^r{sEhiCH+=Ү-_綜vyEh2ÉXh=!-z o-B@[@ޖ@[av,k|4[cc9"k]?H(n.ױEVǑ2絥 -B@[4Q[ML[1=o7Ӗ/E ,sL̴%ؿקiI>2-z^`%Ii뭵/YUʱmڢtG>=z|vY{̦u<=$/0{4)-u[Xh:Zh=/0RK¨%=2azom1h=l6xJTc*[S\pJzn#@ h.enbϢmY,ˢO' -3=iK@-f~OL`sW>E -3=\k˶ƨ$ :32ϒ t2y[LUm#mY {Ry%ޥY -6-z$-J~t&\1>z~#6-z$-b\-a"ol5)ymm 2mYiKe}L$yy[ڢLޖ;seiKQhS]C[aڢdޖ s,4O0sq{шuB-zm95Lւxk{֓\u^mڢGFmR.k-B@[ȼ-%4m0y-B@[ȼ-co+ոLW0m##󶄽-Kmhem]"o+@[ȼ-]oK*0m##l@ o @[5o)wy[N-mÿ-)ڢy[둷RE'(BE׻J="E׻=΁mÿ-n -=қ%1 06-z7o˺el_k-B@[HoEm%n+@[--B-z$oaEry[2L;!-z'oF['18@[h\py`AڢvAc9QϛPbtzEghR-(ROټ-w8˘Ȭޫ C[hOImמpJ{ -Xm_Iwͥ[h%D57Opm3Q[ l2`IJ -\C[h - cS;}ߨsT$JpHm@R[f b"~hm^T3 sQqHm@F[ DKJRg*q',mڢ,:es[[Jh9A[h`-]t+%m1P@iwzh ,e>lWm K!A.ճJIʐm@r=wEޖ2^9 EWt+mh:oHp>eEhFmY\ZO0Yԛ9њ`֣Ehgq<A.-B@[4. o(N !-\m I^+"E--!zh i:oˈ'Y "Eym)sL49%4-r=Eh 8"!-h#Xmڢh9"!-Xk+|C[h` \P-B@[4j=7+EhBmπzmڢQ[3s[dhӖmޖQ/gۢE妶EY=z[h^H~Qo]mڢKXG"E~1C[htn+`=Eh|G"EympD-B@[4G"EmrD-B@[4-G"Ekmπzh ,k>ꑷEh^Fy%m@\P-B@[4h宂      FKwK@h @ h @ h @ h b1Z\\A3S"RDlmY5 -׾4O{Itp#]; +oq,x5ێr7 \eOx|ηksܫXœr8L:)CN/3niYvo7t趴53s"m&,~K=ܟi-2,}31&tuO:icW=1?q G=J}LlE^$Sm|@떝z=~>4kHΦ+Fx{#Lj:~ͧeo1O/yiLܧ[^qm c#ZW꧶:LXSBc@ -)Czmo'i؋K-ᙱo7lXZY{ 6떯.zjW7\zʹU5knː ]f-~걯;twNZ}}ʓl0 1RF\[7udN)1g-\K. )xׇw\9֣?F ~|%14\E{Տl?~jfi!jUn0fɤ<6UZ<O~vZ3/U>}Gl_8+8{ZsƅθU4=j;f][W#~EJhu3J&í};3$uxB[x?Ye_ޟ0v֎v^}͈9A[ Ĥ5|f|i77f3(5Sn}]Mֱv qq?|l8O7oR[}Ǟ'=|Fe_'y'Dxğݳt`;*HŠ-:>fOviK*6ڝgT;>Fo:uO|}€n=?6ɮ?,]c\pm귻}on9tI|F'sǗxjW6pI W-j:ˠV:Kkn^0B|{NYcϩI蜅)yb1`R_^PƽvwP篜1\ď5Ι2=[ޞx5F4 ΃hŠw;mj Q0: S"tÔ< X;A[@a,m0%”< @8aJ9A[r@[bi+YYW -endstream -endobj -138 0 obj -<>>> -stream -x+T03T0A(˥d^U`l`hgf76535t ͍ -\z - -endstream -endobj -139 0 obj -<> -stream -xڕXKs6Wp4f,xG$ OS;NzE3Eŷoʾf8gdR(?;qV"&XfʰD̶q?[Gel /״[m~72*$%r[ur]힍*i b_HNÇ;imBf#ZdE'O2#.̌R]V{f/98;jaUc]&.R ȄtS罪tJ +`5Ȃ! K*n7[d s| ,Uђ࿫,1"=7$\^pֽOMmZ+.v<8Ŝ&9E˶`ތpA4SY1 -F=锌9 1#RVROq|85W a -Q}] N]٫R'uWC jCF$G-0J!|R]|i-%x./܅Ǔy -C;͸ `nTXl(g:MƓAuOf9A ׇ:_3]?yww1!o)F'5<ApNU7z>.fKJ>*(@Y5跪BBLр^D|.M3*e( Ii 9[YAEWڰ}IX<Ѝo$*Z4/UO0[iAAٔ1NtյeP29~ RHKh hbi$̓+3哝'5y@KRBqI -eUB^ydD(C ?Ekc|ꓩdn,HXQnѸύuTo}_+F-C. Ƨ nHT8iԽ U~֧}U-F九1HӣEouhUzc]HK?P>YzOD^{xB _.pnl¤ -hla -\z9".^;aBܤ8j vs]9-mA8% cw6ǖjЦT[Nɑ4tXʱ>׶Kte'Dy+RHxҢg؂=}Tj7JZUuMAXN"Z୪ ӟ_h[ m+s.x K9;L6Wih-IK} 3-1@aɁ;vұO[bKy ;KzrLN P ~`UW -endstream -endobj -145 0 obj -<>/Length 52128>> -stream -x \Lϴ{-ZB]k i/ZdIZ$[*IlK{uPEQڦf2[ui1s:>ődw{5tz,/-^}C;~ç_E^D_惗:ǡY_tX s38``"cx0Ջ&y^~IocB8ͧ#]S{; +ɊIE‘IdӆTA?Tˡys~V\ۺzcxY4E{pm΍Ͽ,$FOUshiq!嚗$mʼ` hӟ -Ge Ƨ?! 53I Q VOSY ӯo|UܴÈa4f͜x}-((lݹS޳rS~i}ɲ+g6N~ΨO.SK`MgW xEmgñXC@0x<BmHHdū.%W֒ɤ3q CX;9i[M $jF$3VJ֔@ԢX#b9 -L&\3NVSbvK{w*ݚPS O'&pҦ;4994J|Z ӯ[j3={{Qq9(&Bwl]ޖ%Tɗ}wC/uZ@AJ'-EQW?/>QƼ̜@PݣyAQ?s!"B|ABCP8Mמ4EsIQRkyO*`]C9`v`BCLhj0,~,0"`2`̀eIMM={vOw޼yz:=L>zs|ڡ\OίYv؃Z{Vhmqmts"H<ޘgǀ6g찧3žFw!0'syx asڱC  +>+I~5/u²j`A`N f@+ͨYTD:ر}9 >ק(o:36hrw! ߄ RAN~M%ZDJ8xM(|kwաR?Џ觎R@]+˧/rڹ3 t!]9E\{ --3vtHGvXi{`蹍87L+pǔɲ؞R ,J'K S>lЪz*T,' ѺoS4vH(hTUSUw2HэLRV' ּ/R_JLU]VGn,(I9Mr_&1q'( jIb" J/8Y' ssU b{_W%M-JWS].1%Lv^SήHC vC*|y\@;~GLCoA8JpRQ뇲ikf6g.sB"t- ׼CPs… AJ'퐄@îp69$J:B7K(S ߿Ջ*2O9~DX+gvPxjGB -+װ;gY$fs{Rh@|>\'5Tc~5>N7A^ ?n9T|2!ssuM -n|z4HA=?^r!2$Dvrc.Q| }eaF;d䪧?ʢŦj.2MU˾TTPofؿg;hxlX|l%*|A$iw'L`C.G&OV)cQ>M]8tsX[!اxݚT-/׏NҜ3꠾tPsϞoڒ*?iQSB|8@s;$׽߹%ER=;2O]|RFuFVh dnk6g~W=8Bg"i<1xAsaqe# '"3x@ bIS# TpU͎/5qf:CC!G_9|njȇ.tekQ ]I%D(\n/rlmԿڷjkWiwYC5i(r54Gj@r%#ko`s" -ErB5'mK-&dMM u ֈJ{~ FG4pNS;E]lC}jЫE Q2_p\[Rmۯ6!(1G'~&\">CC8æu6X.TU>ڽֿ_p□l6hءio;A]aXʨANI)M'AVW䙝QEbo#X?}~mX0w=I)q8CR[1ן!닊%Sqa3'ay j Ӆ-6g&Ν5mڬ9 &iow0bR~VyFX`Gڭ1;9SM6k뚣s"c.3%z~pNQ%O-j6W]e|=kbæP~H~vѴ$&?qƢz: -5 Ԝ X:6ʘEm"D؜oEtھIέ+)OYRmr2JJZTf=ic?8=5urFK7 -ZЪYƨH}w\ 5W,<N\aceKvBkw̜ ,VJ=ݍ %gzD:%=R곰·Cm!^2Pʞy 1Cbf)6Եqq^z=2;*j0RАNn!:aQDUBfr'Cf!quMgk"ONibm֥xjs]0Truq}y>^;S0#ӚR'aՄEFGZ#Ok%]v7|yLyM=w0E;D(]d/Nxp¡s~~e&cn'b}%Q\A_z;$We)SoV=k&|%pM%l+u"l'#vm=@v$'V`e<\_fG)dĭ0w}aC5BoҸ9 "v:;DA)z)YlhriZ_5%nVQl`C6\v;q69sxjm! B6jDkgmy>r:j֤TuSN"0_"9>CC:Yjj&|U\k;KY7:K%l 0בf?Kv(_/6f0SՑA+Q\Q Ҵq=i U B!B,sQ_ͭG<6$?n@oon5qjܽX]_tGh&1PD"7~]k6?"(\[<|F3)Ci? Qzx*Em*I2? :e6ekY ԛޜwxjpz]4mX'ntҷG#\cL'U,"uyT`E|6Vߦȹil Jg鞔 }ev_N^#tSc[ΈBZvacQ.X[ \9id?|gD,}`@`eVi2R43wx]. Շ(]PO捭Cik^F?x(px:v(_,hgjG؞A݂6X_/WS-։3JpN]|P†bK 9]C2Ӌ4hs7t`Khk=gv7ІE> !!ܽ{}uuႅ 1١(rLSSS;;`v`` !@vH&ݻv>`v!<;`v`ϐ4hPII  -.^Ƭr<ALM-/_n7,n:E 4G"BPQ` LnoJJ -:Att/`w3fLV1@@_UԙJ3kjJ vHW; *K_Ma~|;HcӍ<[~v(qL5v]g~)/]mvpZwVMM -Z BKCk6}آ 5Hruצ rp+݁;JK^oZ|}1bFk,}/>FcR<p5sJr‘DDd菅R-.B [Y1a F.H wZRUXu56S*KAW[.B*ADJJ&Ͱlgo [(m\Zb02ICtj+-`F'hBRe%~T3fFH 5]DZJ+R "KHW`F.F\"""[vx)-ͯA 52#D llTWD`@[\r%B [Y و(z_PXaݿioVv>o uEPFWtFH#Ca޽X }D~ >013;ҘHvȅzivY*%KM]< -B Q]l;Kٶ+7ف%R^+%TΖ# XfĈ%7P7U}Gʹ'={_k (/]mvpy'efl5HӨjZB(Lɺ9 !(xgX]RRyp E8)+-?{jH{5x|k$d^R}?fW"Z -W<| MW -*ZGt! {'K&پFE]a옩_f?ɟh̞QYYSRRnQWP;hi7/;x-r }41Iϴ0V]c%Y+C1{Ƥ+kjKK7_6j<)ٓ7PMؐq8~*u翑YKWX_HXu|W+RuaQB=>HSIAeQm3 .9Ye[ ẫj+"CuC4_{fc~rCDL,3bY51U7OXkvHR~g4@ ApF(ɦԝ1\vWT #mϋcprKeDlesL$V<:'2æXJ#n)N>FefB +GWN9!l9_C,i b5C$!Ad"[MV=f?} `܏Jv˷:qZ0㗳C]}=+(]Yϸ@d-6i{ ^jֹM'g1WyPݪk)D>[2LJ"e/{7EI+I ) %䒄 pzwGw qgݞe -1vȧPnUg3Fh~uckL$ll$ :GHSlRZX&.*V<+0klkJ=Fבֿ*`g-/xXԝ-bڿcV:^dmF53Х'&dmZjuD~2j 9tqkisrv 7ώh)^Xo>k_N$X)a{WvȸO–Kfw^FPbU+>&!~>L -VHUژf̱W'kwٔC_"Ɖ$/V1i9qH3[M/t@!~JY2Di˴ .liLr ͏~k^yn\rtYڢ3V#$6rKkx -9 a O6> Dw\ǁ)0^{y¾ew]ԉcx2SQRIvX<]bB9]X_ssl+IUy>zr'bΑ??YK%HHJwm!>wgkvmHI?nrqbHXf~$skQJ퐹ZIW;SBGʛVvMoXiC.ᄛ~=gYb篫v;u׾Zc(?bR75rYΓǟK|ayİ3yӝJ9S~ wMS9Xix>yۭso" n~?Q1d+zXp5 -2$)L%f-&A,C,RGe*$;j/ݖ4>0/@->̒KEu<$DZKI %QD4Յ |Š,ϛód>fuT n~P}.(8<yKB_}FF)Xhnjˀ+NgOE-RZ i>`cvb0UuoYc8xd?t2㍳iz -"ߟ:-p×,Rf8ɩAIT4)gͱ%$57>'zᄾ2죿Ў)`n=ӭ|]r0qbee6_:g,WѤ7ȌX3_U:%INa *d&\[\pEXwTvNSV T0 -@bcJm__ȍ55hL)Ss)f)%3lRf@;]"׋ynSaZlci}a?#j v:p)*?ǡq)_msQ$+5Kշ5x㷻/3U+,>!@5mv-qZtڭj)/^Nz:Ũ˫Ѣx&{fw2U"bŒ6| Op-Ed)/B֭[쌂MF*139o1m;>;l'amݠVϚo7u$u=bi8,u>[ޕ5>?lSjV- / -ka- (Rď4A455_KMݶ -#,*(P$)_7$2QhfoJXpῨR->s`OA> QDkj-557mvaqK0 uEhi<0vz-"8̾&(]3/8osh(}aRQh]{ -2!h'F$^ڿLvIf+jq(jq "Z7w9[W -;8~+?'S;Oh=%*fDK[;88x>Mѩiic *%4'n.Ij`K\w%WbqN/ -t޻O 7)I.$

C۠v_y~,?hu;.-h$;+^2N%ur_;c)zs<2 Oz*54Ah;dۭC> RIJK66&1hLƄ~D s1G M6ƙ'nO~ޟ2}RUDdD}1ts_-ϡS;GJMY[[Un`=}=qd$-'vHʌ[Iđߗvj2WX$V‘޷4tlkt6\,#[5ӏ]7Edv~hX%UP -ĆiS+䈑7/ZT{\ɣ *81_a4ڜ'7}'HO;dۭC> R5YNFA?bBy9}mdcfujTۡ>Qk]=}Vex O+  cmvH5Hc,[^-=>ni"ON!UYwJ -O -WS;3gNcw̞C{8ڗ.'EY;Tdrx=rpQq-u~jqvṉ0spyԠpOdrl({j̇pOKqK0ں -; -_|=o%uwٙ&%I59T w>[|盍]LI,dm}g)%JFa̹&9Xs\]l9] -pڡ.EBL(2sY/NK0qǴw\,^DYBqV+|/]y8[ߝ+YәޠDQi -Ci&Oߜ6~6mX+`"Vl#\Ub>kDžiao uQmPG:Q!iTmWzU}V/g! /^-m*CdA]vؽ3*A3@gL&fJL:7y>9ovHAms;І%u"u*r<uzmk%DPة8zՂ/i`j됿41&4|t/OXl=Z+{Vi_ - <-<hZfMۺ٭[찝`=u*Ϛo7u#4|Sw#= F:#`,>?lSjV- /(g_4Oh߼ G:\j*UG,xAQ5AuA[[~E߬;w_zTxɼe8<#DF)(4x鮽dRZ3 vg)`Ah*Ђ[odoTM!i)& /5/+3i;ݮP``,jq "Z7w9[W -hLΕ SR(˺hikק):5-;\ q [;\T*gړvUzWR|.bw_Ƹ%|m'uF k40Lp\C {h*J,I)!Nכ[Novo5C 'MΞn'G cҗv5Ƅɏ6ؤc,(`Ŵc8?KBvN3 <8@[;եY8Z 2^}\*|2Fϼ?˴4>F|NP-4¼.ANw6UnX+Qbcm\}Gq!r<¿ssN|/r|tE!̲/!j%&^lJ#=ʡ8RuVȶ] -CWY%vfL+~Oq#wx$u̖9+MBz[?Q/mxjtGU3_"g<vnK0ںٍpuG6Κ95qí~Ç m;.찛v됏4ms - ,6,9UpnA3+Z hROEs;@CE+Z;@`CS`_;@ C z#`@@h84F84`6S@3v(b7% n7a72E0J#E'ǡ T'! /^-m*CdA],8uD0:C2D*a2e -CD7o@ĝ大SЅǘʂ#GڰNQRyדOEewM ԔW -^PN%^3xj д(o)dOķuݳ[n]߬e9 -m#졭UAE9U:i A)bCxk 7/삾jjjQzE;jq}W;s?\f?J钷7$2Qhfol%))1?xR2xP̶^C\CHd>Mg*U;ٖFGڰ#B[Uk3N4X%uNKu@[H2Xg(_QFe˧VD t '2J DKwgV_S;OhKKvpp<}}SW]IA󕾦Xӏ9bVH%S<$)sIYUJi,N0\sjaC}XnellMbєo9[Ӌ adl1$∘B`=uU/bK3!N-WdRۭC S$9Xm6196O 8P%J,cL'|m'uF w5;}| OP+5emmW::hƑ;xuEbl%}KӋfA'6$GMCZE8&,Kʌ[IđߗM cއ%d9G|9<"1.$պ^B-XGʴK0ں -EXЀ4c3:^ [HttkxGL0_(5 -Ѭ5}'8&U3S;ԛG}PIOߴisXA1ŴH$>{bNVj}>0 9e h)ڇYxGC쎈#졭0`)_җi{F;t;^ [Hr+v:c6ǡv%Tciuly\~At "F`ڡ,QՌi"g<8:$m:"v!am]RE-!iJT$pgٚ͜8Edj? -Cî֜;"v;.sXv됏4vY*3w;# * [-Wh!<` mЋ,.v(t[GhBӋV.v(RfPp -hp -h荀  ;@   - NءR4[ &4Жmh `V,8vD6P@_95E /^-m*CdA],8sD0:C2D T ɸ}o޸)9M65{t %a FmQXxԔW -^P` /'=b|8'G\mfP`S;\EyK,m&{$ݺu,:"G`=uImщEBnf[;iоyaUSS3//u.ڹw/9T\9X _xyANqV1(ܛZ(4@o %aVlEյy$濥$gz(%/ݵzP^Νq2<{ FY`rD, K0 uUFLV{K8*ěF7bE"ӵo8Sz*bӧKΖAKCP[f IF{2nH3%KfYiIOЍ"̘ ~^>*^Op>U-7ڤ*Vj:rsutPtV;!1p-M/8XGZGmdb'6$GMCZE8&r2qNʋ[Iđߗvr&Zgj~wW(ʝ0" 9:Enﳦԛ6B-XǎXK0ںU~aC}]Iʫuc]9Qd&c#Ve2".̂QKf4:#Ͱ,oMFv -aՕLڡ\=Z%i&Ts 6sb" ⛷X^m~2!9r2+_luV;4|v +=1['+ -5d$sh[nŝɝ~h76 ;XK0ںUX0˖azֿ1dT0 4CH3%Z߫3 # Elª+OpΜ989=;p=,bZ6utG;49`gR`{$t]@ʖD"άH*Jq29N6Zn2\TSME[Jt:GCctDv%amݩxjvhrTCQqf}KCFU$Ú盍]ڻ;Ÿ:#Ͱ,Z߅K.Ә1HUn6n:BT鳐\+BXuջuѷR,dipr/~&|/]y8[ߝ+^lJ#=!ᛷ?4y_fgH<_4(.h{]sr&N,v/8VV:nBFM15¼.A3WgmdRoa?fXK0 u*ڹj( -6U;:$pd87".OWl,NfTE;;$Uglە^Y -\P[GdBӋV.v(RfPp -hp -h荀 ء_v(p -ءv)0+ҋTS;\x1 )"o\uj;>gL&L=2<79IumX vEU4|ttks\Gв@ש\dNX\~+r'|hBĆX2BsBV Vqr piQRm&{$ݺu 10v UI(vh^U={kt _:#C3xk 7/삾jjjQz|+xǙC5~M-Lq0۪#s ٭-Qh_scߖ jnG&ɑ3BOdBk=NV5{ n! -%f _D("Ȍٰu%%D>&$zHrc!JBH /cSNE.UƢN]R{P8lU/'3{щ=.iךpaG~"[!gϮt|35J Wkϊ5+e{ӮΑO +3,fF4tM_m3^SwW%4Row\eFfxjAeh ZiQ05-=;\dl1$ZMV!akKWlY{6hݗy +D,Oax[Wm_FQ$I9^5a.!?3j ypOI mm$ YL-ްСdج34E ~6Ұ7\Чi.???vaBÕ; v޺uR'^L ݳ`n2NS;5GMY[[UnhGFtk]IʫucrxD}yk&#k7I,|ҭp."nr1_a4Rrwˆ$Qn!n]RBd@3ց鋲#;Dՙ #C'4 6_%ȴ{C,оJ5/ejL96_U~9qH3[Sϛ_nIj"6*>E[A?]?r=Cu բеnz!9uHdf]?QMW9xjzshIOߴiΝcAlIOOc,[^߰uk6_!}CZ~`zC5bwMBѱq1: n!n]REkCF qBpY\t˸N ͑Qas3)톊\jv#^[/t#ag\Gg,k|El!l+ٷ=ؽvOۼ0:HKHBm(7>zr'bΑA@9sZoޝ3{& -wlI:8)ځ'Ԙ۟7Gۭgg $|S3X,vaTQŐQWWzO -7!IYHPF O.VbeU M(}Br6:gY\Go %^n2[fޮ+?8xd?t2so" nٯҲUgijyI=^ݖ4>0/@$_3]]wYoj䲜'$fΑV.L +LCcuu 8Z?2H^}0%D^\>b[v~Z9gmJy]9VmBa3Xq`]Q/NfĦ',&Hlf?L.{y+g)R|P΢x g>; J) - z:/&L 3]"#h?5mvkm 3bg4Psq7Fn<)D3t0lڐO5OԁGo*wt~(Q~yXq* -OPwnH|[]v!% -n/VRv'h8\ÀOp̙Su>u> sB+*Y~NMhOS;\EyK,i?w-.Ӂ"l#졍3Eir䈜ak:_zŚ@= -opy!]Ԍ+N=kS_.Q]udβUTz钘FQ/eT.,,vg)`Ahc -MMͼUFLV{K8[_ϕ<]'Dguc cy+Յ]S6(~nxՋi6n8C>ῨR->qo#IOЍ"̘ ~^Slo5$?_v?D& - 8C&4dz(%/ݵzwl|Op>U-uc cjZZ"&~fg} *hm\mClᒤ$I9QeWlm:Q.8!`=BK[;88x~Ǫ@zJ_S],ǜ&$&r^Lr:XQ=N[ n|otXz_vU3BbOޏI!IJK6*bypOsQ; ZymAG'F )J # |׿ax[Wm_!_S;GJMR1BZ6E\(hu|wqM$OBM~*Y΂)6,(MA EtBQ8@%HP" ӳųP<M!H -C|bܝM2><|b7ug^ejl6b؋#u~'8bFЭm@jjOIE@R ,0g^莱JRϹ@dLKؽMe\d؊C +y 2*V;`5rm&t'':#Noz")IZYeU$H#~D!O8֡(?+h9H[Dpaa1 /8N!3nmùֆ -fk Ӭbh:4?")NUvJMb~#w81fl!k=*UD،PH6CdOCJc4Fһ)+xCq5`;/ \:Lgo% --W;fGu(1BNwB1#6X+WiA_--s43~tHh' s"%TP{,kDkkyjM|1B[I #@܍CMMZ ډ$V\a(wʽn%eo=.LZ]N74M5Mr?;[RaZߵ!`(P@C(fĆEasO~UxuDLA) -'v *yƅ#;g%/ -k8!ojMdMdy( BL*"4HA%Q4R]Sm]f* ̨K(/[_aO2w5t*X:fSssXl8,\C͵atxr8$| ?.EGbFЭmL5uGUJX-N?wC.&\õk N)&RQ`ׯ#aA:j6tB1#6&U*nDXvѐ""yH3YʇpA6( pCVC&МB)huqȇpA < !]@ o!`h0qC:Kv;:(!?q(#KG#!_/qt*7aڑ܏C$1|^zu%YGDQL-<Ŝc5 Kz&]Jh~=q%+omJWgȷJmn;E='Vyš۔<9 -VV]2OQUH8y(eGr%< oWyzp;qϩOg+K].%.DZ(wk':ԭss['_wV,TFn'wݢn _-fU20vBA19 o\"3ud7Y;IO<,rV&'Fh{+"SECO?fjMEqXO]kmh 7dQ:zBKaX{̯*Q/,rg8:ݗZ~%$!?RSW')XGWk8V<{;<+qڕktV͕ 02NNg^莱JBd9N"8z;$ )j$ER~նZ K[ڌ| -#!9Xu׶+D~$KWfţ K QdMnG?KsB6VWRDs-(~&u_/Nz1t7Is)"j806JA19 or ŷ `V ]ėrm,#t'':#Noz")6ce\VEtD77&7f$*}( թg7m8֡(]\\\H -=p;΍RlvV&vf714Xw{@~E W/ ;lyLÅqj#]ٴ͎؉CGr -Z5S_ ?y=[O }V NüLNm -?l<[*-c=Sd(?n^>[X~lLA;P zI/ѬI(q~p^yh iA`~XCZ9q<|)MoZj؄7ZZZrEk֠{]:u-B'ޝ߃+8ӣ岷efFҏYwvj)+SO\vq{^,cZ }mtBIw" -v&q>P޿ LO]."xe)ҵ>Xڠ0BfQMkul~pP/L7^r6}8߼'cq TPUMI&?4v_i65G;$!crVz8I:t% EHz'I遻EΏ$bS$[4uI´Dѐ~p 8t03٫f|ZE~)Gt+K.>i^^,~oS25|ozdznai u"V ÞxSxm>G+ -rw3~Jcq/&&2<W/Z$!:]46FCyc̣]!Uxieޔ+L[Bwʽn%eo=.LZ]Fr".NmӻgHP\'>2ujjUM.**xH - "gÌ=8\f _)SF[S[)(AF _yrWaUr}YooĻ8!$A}нAAxA`7qy5117m ,N?w%!o.܋CpC(b! < CBnq9c9Aիu!`"048C@]f|6k6 xPHA"X7 -Y3f!kf%545 ek! @3q6u -_"<}4uyK30nKtH(# 8;U ~7n"k:S0u߁uJKK0q8b-kƌ[8%PjabO:W*ۈïb'zZRpR0fq}Zᆍ ''UUUo/+4uz[ZIuIír/Z3֟Ov'j\lu:2T&`MӤYDMcv D(ŌذdIDf -^Ul_vLK Ɋw}xt|k{Y;G(븢/pu[2gZEDeh&'!Jh.\hD[wI[q؁sS|9{Ϥ>*J[=X!R%>aºRVp@iL^eZ||z]]ˇ1FM --ea1$F凪4Y[0K-O`3vے٬#(Fwcg!8`FЭmL U$< kv"ϫoCq2JSE__Tn'to"(( zr]kC8CoChKy\"3u39IO<,rV&'Fh{+"SECO?fjLʱ}FZF~ `ҧp^9jzdDwqxơ.IdjjOI -աN.).&hÜupb5XlD˓v`LR R5MFmsF޸m5:JQp,PIԪOJ&E8f:e:>U U5sܘܘ%DT\'t7N={ ![<ȏA!mLNA[c3t_'>^R6򝲑 BoǥT'=Q -y5jhPn.p...$kkkZpᆍX }R<`d85mci~΃$tяܨ,fWiebmg -1!,PIԪ̴OG圅<Ŭ-Sw> 5>(qӐCPt. !Gf=*靄۱ǡᕑ~mV u휍dp-VAiK~r~o8x4w:A\zu#K ћZ= C) q(Pő*4}(= -cK$HZ$fSV"^ CYc'tk*0?Ԛ$9b-NGVdj:c/i<1>5V`,یa'yK3Җޖ1)['w>IR~zn#:|{dm./iW}Vh~hw_.cw"p| i'N9ݥ_ơ&YBSL`U\a(wʽn%eo=$0ġ";kH^`~k鰄 p -3 C P j؉C(fĆEqx6miwe"*kWP\,u!Uxieޔ+LӐzqϫTP _-fSssXl:C̎9'?z&&26]f] ȨBJ.k@Eyk5GULvHVQ9Lz>H - "g|Yia#!tk*[߬fkM k׬"ehkpk"Vy0"n{ftCAkhX38hJB6(fƨ -{߬fkM |q8.#kbFЭ '4nxV2 @aY -p|8d~6,mx@!`C8@!c `m&@3Ck `"048C@]f|67: ?qȇЬmھUHa7 hYi8xqj,VFUqH3H0/@38cz:/Nv"aC*Ç"8F*xqH}gPh|8$ s$ab(VR\2ߜϿD_F}u^޿zA PqHeX3RPAKt;';0Lhv?R=2G[5,G{vZĎxs3%aƍ)Yԙ쩓{VZZ:NډqHe#[6A -PnB;2(?s+:puCa)QiĎ']S:>T==T8_nn_؅WUU2="]4M5MLT$:fP_c Ɋw}xB,&<oIܤgmPXb ^,')vK}GH_X\,`('8 8|A1#6mTv?YµtU<)2^t|5{[=@#u\Q? nk<~לpu[2gZEDe}bWMQ򿒋1C|3%]\'$(.*sX!IW}/VR]pߠ݌x9/CڄW(/Z^Wr6ZƲ(Mi~}Q9AvEKC˲9 <`s?=>`lqˤjR'n)Ï$Qƽ(ts Jy<}sz2t<בb G>G4ұJC}tvC*!ڠtk*0?ٗ^:5ȊlSBYg8b4 u!J8:-:K[.{[Ƥlpv7!q{;K-r~D'#}"ؚ|./iW}Vh~hB7+{;KYA`<2܍CMMU%(u5x׆CBCvYS+Qq^HV\DXxO]]{J -fB֦I:TO\K~S'v *yƅC3G4;bFlXXTgӖv3 u!Uxieޔ+LӐ\AϚv)ϐ$C\'>2|!oifGllYl@Jxv;k -H,:s(Fr/$(n ѐzj4vW!r[FIm[σ 0Sx=ek5GU2x<<;v8!3nm@[߬f={Ecb3aGj]/IGSF9˨Y<" ;bFЭ tLۃ0{\@s5 <s!~A6_pu4}|;R&DkhRC8C8|X. |XX۷ 0486&" `! .4Ͱ;J}e5{Q۫WN\.) rB1QX(U46^$x^@Su*‡mfQ<^1siP&nc$8qqF Dl$Ḋ랕g|8^]8Bݒ8ƌ[XU(5Ÿ !+%'cWaߋS2nfXa2nn˜ѪՔee1 -iҬib&1T+NNV#o=b1x}Kr&?lSb.|3%]\'$(.*h"db)!qŌذѫRDf -^Ul_vL нemvPqE9$/0dm?}*u+ -ǜhpu[2gZEDe}bWMQ򿒋1C87 -L{}!'^ꒆ[-Ʃ'~OՀ QĮWE>.:S![<:y8>sq?me 2݊%HlukV/ [)M~IWNH!XlgF}bÕႊf/NɵYJp5uuk]\\\H -t pšq},f ksjMsY$gދJnf%Ag)P A1Zh#]P7 9դΥ +\88pWht̕Wö\Mb6eeQ}R'SkL^&ep{2He܋B8z#ȝ9?߾GL^P]|hcht0pCA1#6&U0a~d/Suk)٦*ڳfq؋ioy1;E8ZEܴfow)[ZgieoSژjiCYN)Rϫ>+LKQWF4x!K ћZ= CɝlR$&o1SI<8<  ܍CMM*0U\. <efLkLD]z #[q{JaN=u9veDN3E**hK Y&Տo. JECi,=^PA3.|Fdz7sP̈ k*lnc 3 -/-l՛~i)(#G+xO ^`!oifGllYl@Jx.;k -H,:s(%hCi4ں>6Pth-N?w0&Мqȇp < !]@ o!`h0q`mvLD@! .@3C>X]i kak/@9 _qȇP@A"%B YH@3JÇ !~BO~UqHm(-_l4zzzLoS%ɓ._";!q83Up V@3 WpʹD0Hk '7o4Wfk9{?.^bK:6"kbF6"0U@aիJ'./K쨊7<#Xs!3bXBUUz$UPjj,Z *MˎДi{AXS? 0) 2qHӭC̎9˕*&ҟ/cj\lu3sX!IW}/VR]pߠxSoBtw* -A(1c -:7p0NFiHʱ +Z_%"nfۂ$F凪;ے٬#(&y`MEqXO]kmhꆟi*;`26i<1Bk[8oa?klw8 A6fU,PS_;*HU`67uš*:{vTSy z!?sJsv-O/nfxKGoo.F(]f#;os|."!@Fsܘܘ%o62ЙšIUV&)r@޸m5:J,NNtRqG^R68e#цr,vc]礩 *,f'jhPM~с`8849ŬWt-]lVVh" 8^P -x=">>s])TrP7 9D-ˡvlq-X3nmùֆ -jd'rB2#9&]gXi&_7(;o]HJ=NyK3tqX螏fF9X!ݙK*GH6Cd,9kH+?,boڴ2pا?v8'.k/q5hсEaWW^.q5ٔGmK,OO2#Fh{2{mw#Iq/ -/~^+?Hġxk]Iw + --`<=H6U!Ԟu6#0šxSEΏ$bS&1|ǖ}dmP VuZl9#}~ώjb##Xc%ñyK3Җޖ1)['w>iCYNJ>& #uI´DukD0Y0Yʨe$e*{q VFnjj/d8N&pqHhq.0 <`P_ce"*k؊VpRqv~+#Bwq/RIUAl_z_4IꤻyCk=eV11h&F-g<ό*UoaP -o. JECi (e6ΚB1#6m,`óiK~OF 0Tad {^g\j9VI [sO~MdMdy( 5Ci$Y9Sp҆hHu=Ou}lyTQW?]N-IK)r߉M^aˤ_ơZvM.**ócB1#T pujG@ZT0voL, ,\õk5SJnMzv<" ;bFЭ tLۃ0{\@s0js!~A6(pu4}|; ZG@s!G6,8Czvq8CRھMf`D!`o|vqȇ8vqȇb/JÇ Ca_.!PzzzLoS%ɓ._7vC؈sy -g D%7 \͛7?s/D %%_W+3!jB Q!H*0]۫WN\-zJϥAqBdYL>`< U&Ӆf;{}:TKrH_+:e^J\'>gKRn8ģ3oLAs\Í7R.>GC$랕g|[yn"W7 -aL۰8*df"ʆl݋6vgf,`$÷xZӫ0w(Z?bql87Me̲>X52)TJ.`p77lOh<d7-+4Ѯ)+*DRk8:YPd-ɑZ MK dڋt|͔PtqmBzk\luG~"kW/x6/;@ lƔ/> -/9]yqϧb;a 9ښn0,u%aP8d -UUTAq(zДi A2E( Dp'cYLEZS珓1ger{8WphM©nJgYy9C|c -d|4 [ [eYڈ##EؤuoTbm3no.uMӺgkGw"ըPu|rE!6lrB0qȬjjuuGV2S {7`=u段y z$9b&}9llÉaM -Ry(eGr%沈r[ZnfX4?AL}YqxLbV go}D(q%*.p...CՋsI gP7 9D5XsiqH+g|cf쩝[I95z#9/Xǡ]l/۝X0gQ-y, W9VFC-c!D̛?Eyơր_ņ 8Wö\Mb6eeQ}R'SkL^&ep{2V "1*rgEΏ$bS&&--s43~ӎ^N3jp2fCV:}P zVuZl9#};GVdj:c/i<1>5V"mCnj&N7Wǩ$? \uM沃ѡgˏcwgvC'W?g S2}!SB 06p,`óiKae5+̨K(/[_ad {^gkp!BY`֟EÈh=n<8/O4pZ-=o/%/ܩdD r/:#!=:'^{[ry(M?5u M[3 Ak5G1YAVQ9aᑇ~JACRp5׮YC@O)u>~}߄C6PJACR9KN?w%!T8 XтsPʂ#8C8qx|X!2qM@F!qvLD@!.@3C>X]f|.ZZQ.PX۷I gs42yg>JÇ !)ި ~=mlm@<Cj1M'O X|x0!Cb4@<Gh0!:qH$S$L$O{Id8w9{Ȑ^,q=zA'BH@0TR}(ŌFamTF@w]o^}P:q˜Į !? -ϲ8''C^ QnxDQu :<*|vz. =ݢ Um0A?ͣї=PO+ʼncqqFFla+--F8.=~xSr~o.\h^T?.~pk(ŌذѫRqDf -^Ul_vL_/@ʗQE( D6CWfC2!qŌ[ۘTADd_dcS)zӝ⪏x8qS5`Lq[`NOA rmfxIqC!޺ۅfHxnuiP& M0t6i8k::8 I_Qp8{qhr\Y0誽6l4EpF]2) ̗۱!ˣCfpFbmPI3>qosrz|j|P"!hfz.1EYZkC -/kt(qp56ܕ+Z; sDI̦L=jXdyjM|1B[I+ԤnsO~S*^:_9[%VbLݰ%/.`,eMHjp2C2WIso#Ln/cytpCA1#6&U0a~d/ӯAGVdj:c/i<1>5VlClX%!`t(Pӎs>8WtftXP|L֑= \CMMZ hǫ6\Z'xµ*45*XF:jn%2{rʈНg܋TRGU6ۗ6MbݡJ_gǏئcrMP -o. JECiX2~amcQsM[1j_WQQ^M]4 ɮXzA5ϸrƫNh"o]& `rfz2|& -d_#8BXVr n7$bCŇmơZQ.**ócB1#T p<f<Wp5QLmMnM*_";~A6 -^q4}|;bFЭ 74CVC8!2!ZG@s!G6ghp|X.`_! .@3Ck `"3 t C!}yЂ(3̀8`V08 Cp5ަNK'3],D pJ!NG0&l!R>%܆kq8LAñ:I׿1{[=c!8ܰ?}.ՔeeFXu¹;/Z3֟Ov'ú/L#9iBO[]qu]1}bߒW5MfMR&$0za`p×tmxB^Q**k[MѻUįWpE˺,PS_KUtYy9{q-xAB\jT~HfKݍw18)"¯/*bʎCsг~ {6!sMӨ -6w/l|^3y*ySdjŔ;-+eaJIw)6!}dme%'y$ozв=)⒌Wag#*Fb.Me.Fu]䃕1`Wߢi';?icq!ᘜ[e1Ĥ@WqK+*5uuutuašIUV&)&hupb5Xl,S*$_"~Cn 8m7[?]>lㄾ1t7Is)"ܠ-vShH-nY־m^;ⰳ*h's-({jYƲ>mfgr)Vj-/ Dn hۗ_`a8lJVwhqL_\>?e,ȑ|è3&#pn[6vq8$\}7/-R?z6d1agL?UMPb._%'tS -#oe;j`}g>orxT $( -XY. 0 -$kh#"YBFD!5puM@`HeJ -,]5(3=s0 xl*zߗߙsEMVV2En-sOExTυ J2?tcOnj?w9&K7U4՟=l³0s>-D9 יW7磒Y~8_+63L#/ŦսQ]d^%o'2~&y7g5/dQo?zW%TKgf5>N&m9{W]7+虀寍.1A;vz U'Kӆ%f'KI<PI y{:5b2n旷m{)u^”a>3Toʯ l^'K~oRιCfŝ7qhf,Zڥ"5鄧٪" ~*+C4,|ҋ'K/T2We~jnkmP^Js$-&O>qȧ7˷nLKw!olSd.oղ;vp/n_O+>\>}s=>~)'ZX~kpcei\c|?ߛf lyaXW[IDG73wyךeum -wL5}l_Ȩ %~-ۜ.iܟ_4$E>v%|lnꌬOuOK|?}v-LYP4I 5[ZemrgKi~5o :4a flCDf|WZ3wo_`kKEjA9 O5UWUD`HWTͳн{&wwO`ٓтޛtqH`qW:>0oo?'sp=8trtl;٫˭i< -uJg&1"yCyq[>];s}Z^^;~^_qH`q/xtS6$: e2kqH`qHPI@[iR @v /Cx 6 #ġh sq(@k!*AW 0!PB,0fk{zġiơrGꗈC0#qc΀0 HZe!EOvyxxt43-R.qI*878$B8Ĝ8 ^C(m4EaǢ [[^ݟwb'䷏]WP#\WUK]mi;9UY3#92PVMHN 6wwwspK;w+**ki\Ϯ ; ~vߘݡ͙HӿAġ#-J wJ́j棝]MM 끨pM~XzlbA][? DO[aSe:'.;ٚ?]t{&ԜiVl;:x׏_ Izu&S߫`zfgە1WMnJNƬ4lkbVЬF6na1K0Ըk8>w_ߘ_rZ -B -!I1"/m3زվ rbqrrt&o(~'0wr4`Eu8d S"t:'/y^yIIkBvM4' -ݡ.͙/ -.=qB}?Y'8rkWzoq໌m[rCƴvjn4(2Vg]Oǧ;dXA B -!I1"/m(v|uޞM=Jdݖ3> 9U[ECC3s3 ѷ* 6_dǢʏKf]򭥭1 ~nIt8t27NZP}G.Rܽu::x/*u"'}I65eC;$)FՍ}*BCC\]]nNQ289]#3A鏎{Ƥ?lݡ͙ٹ;:aVH[e䙳ἢ̢z2[/Cq8*ġ#~?EVV2E%NNI5U4_a4Rfl9lO,Mg%fy5wAc_¥4ݡ.͙ޞٱNqw9&K7U4՟=l³Z:΢"ߛsn2$:P+s؞=7C8 CbEisvVQĝI/gWVx)ѭ LH.H"'h}b~)ϤGɚ-F{m'EҪoТ_M[CpݡN4OZOq9 R:ތߵII:=|_O>Ri7DdV[L|jɩ՟e8.gŻ{X#6M5P 6g'gյ귖_+*jԜQtW ,r{C -!I1"/mNk﹋iu -q7C3M_n >bb?k:Qw PIyi#|;Ĝ݇8 =ZtY -ġa'Жhġ!A[q(@98^0g@!(m-GC‰/ PBۋiQ q(@+K@Pq+`΀@ H}V{H\ڰˆЌWTw*`΀0 H;*Iɮ0”6.vE%.CPC͜{;Ĝ8 ^C(m4 ;\ؒ]޲}O;iӒe؂wwsF= I *ġ#-J wJçdggWSSz *.>c OX%zJ݂gf0l(Ӂ6>q\EwwSsFm[{ѹ!isWӿd{Wlq25ɍcZɘgum_-,fwTOG#r,K Yk5+8}]F-!cZ;MŽ -჌Y3AC|<"0kVfʴ-g$!}Ñ: q(@|w$ňIqbb{{f(7"*v[ښ΄$xdJ7pUP|w:6ggfN*oU3$mtɎEiA[ӗd-͞[K[3&?$eӄt27NZP}G.Rܽu::la>3<4T!5ҜypQp퉯[. ˞,yZ9cySES&<;,j*I;*.Ke8=9#gZxOyiwwHR(mT#3iTeʊ/9uCba¸iXdO^ϦLJxjצX/_c n521!gPR[-F'8)poZ$b/çFl b)4"2-l&z2}=WLIa7e4iwwHRKZ{[KOnݡNhL7"!''=ġ#pfϮQG|;ԩ9Ɛ-&Fc֭k -q(H|w$ň|ECb΀C -Y -:B, PhKv P-w8 lœ@B/P@[3 6 #ġh sq(@עR^wP q(@B,fi P:!1'HqFt! q(@P,ɮ0”6.vE%.CPkb΀^@ -!SHc6Vpűcʅ-- -ZZ;1fO'Vl./՟7z꘠>C3]uE @C;$)Fݝ]CGyj UvignxEEE}-mvU4_:ybx+/ES{;O SC3]ahC -!I1ҢpT<\Rή@T\|&Ե31pK\͢:"?r ƌ2hkK97WC3Wl;:x׏_ޗ1" ġ#6-[)7/'''OHKJ-mws''Hƙ*ZTw,d.Y|ꭝO4ǡ͙/ -.=q=@8wwHRK9G,?_]-grq YiLOgNĪ=5BF7Wo Y[cܬ{nPLiCE7sv.xq(@|w$ňoQ2Yhh(3289]{Kg8ǃӻ+d{pMĠLo;um)c 6u \hTV^Ұ)Rk7FX\쐑ђ>'Tx5 󉟙1\:yhZ䫖h 9|ǡ.͙ޞٱ5Z"ġ#-J0Ո"L~>KinݐXX/gbf0.FbvAYe>E듥cLx&%W1Wܿld ya_ԧG}8 C"g?Uv?G;;vQq=XP|-SpGq:"?r ƌ2hkڒ6v q(@|w$F3بkOyx899yD ]\Rm ̝ ghflkQ1َswȸܯZ'g>7{ B8 C#C s;XlZlo &qy~%nLOgNĪ}Wucޫݷ"m{y`wwH`q>T& eruu}M:EdpVNt8 .py"h'yiW`PwwH`q^2@VV2E]HNNI5U4_a4Rfl9t6'~fvp7_mD+FZk.0lC;$ 0-YyjDQjq[7=^Jstzy?3q1 Ұ*I/Z,CE㙔(YhM^ ϬϨK֮ofa@ -!IǡYߎGc<oC;$ 08trt|8Dh =#KBwwH`qH!oCң5KtP8PZ 0!C0C Pp@[Cj-FyO= Pq,pe)*ġuC~~bUC҈C"'* ]>-NˢR -!oC;d$#iZA֊cƢ5[;1FsSC:C --0ġyc OX%zJ.(.SGG.?X[{aؘQm|}m1a4kٟܺ.`wwH`q8DK$%%ơ Ҁqkƶ㐍N!uR\ݹk8 C#C s;XlZlo &q@DS%nLOgNHuuL&/L%^ד`wwH`qƾHdPJ&r2katq~}<;Qqx>s?=wq6ݩ 8 C#CsLsxRaScMn!#ۣ%}Nl6 󉟙1ܸᏸ PIL8tvVQĝ}o`WVx)ѭ LH.H"'h}b~6gR£d͖V6zYU!C -!Iǡ ۑϛn!$4ww͞TU!oC;$ 08$7ġњ:q(@ @[CBh q(@}y-` !!qq(@8Y --ġq퍷:jȺ! PB,08Ä8 u2#wӏCJ:q(@ݡVHOvU&=<<|[ )EBkw!I=FҴ[=V..ZXP8l?dOOy^>h~^#M4:PI<tQeWXTT8촯!9.wwH`Z wJ55jjj؝2DŇ{XzlbA][? DO[Ee^kk/7 3tO\ೈCq(@|w$F3بk8QAx899yD ]\Rm ̝ ghflkQ1)ΰ!r֮7x!A -!Iǡ9G,?_]-grq Yiqt&'3'Sbe:zCŽ&W>_Η? z!$Ս}ˑ*BCC\]]5wad=ᬜq-]@Nt|4774)C -!Iǡ\eƻJe=, ̝(khvhť(-sOE`#lO,LopKa9X~rmڮEcwwH`Zġ0Ո"+~KinݐXX/gbf0.FbvAYe>E듥cqh<%k)YNOqo7Ǜu7: ġy:;9PIZQywwH`qp_qfRG7ġy|ECPhR8 l-ġ!8C0LC q8BPC -q@!(!8zq TC!BPC -q@!(!8:/d~18/u -endstream -endobj -147 0 obj -<>>> -stream -x+T03T0A(˥d^U`bjhgb7161Գ44CC3cb |@ \' -endstream -endobj -149 0 obj -<> -stream -xYo~_ -Z+ԣb3AӇ] tqhpHXdMQ9329aIXyU2ӷOXRfRɤ!a:eYϿO6}msEwP:%LV=+νzx"ϸx/?m$+Ng,&H!҄%]=UR) 4hSrJ=<}'+Б~B ;@$U[lQ="E2i XBdLx,AE&^ޯO9/O=p㗣hIĻ؟*0`2_BP"98"x(W"Wi jmi}ƆN= ekRz03N:Oa3ayi90E3xљ RDHŚΘa `- E΀sٸ=KWn@I$aFkEXz@9vkrdn;׹G6yU(->R e`BtB}vfo\\]zՐoZ;\܃ROd"U'{Kٸ,UPŝ ^.!1 -$ɽ釿CLp4M&90վk@乥J"~w`NRX_,q-( W}<*.{;T>{CVdq@"Zjctu,Mzj-u M;r⡱nw~fJk(u2Mu@9&"–Lj;_ˍcE(بHSS/1zy j5UP$~h`>8lBrngjLz%sFV>Se`1]%x>~92ai҂kDtWXj^>\_ȭEJcP8F耟XM޼Rc?G6UŞ;)~MN#tzur2;ۍU#bc?D<6lG:O׻ْpî{{|0RуeT+Uo(>WQ;0+Yi%Wdj/'13'U'xF;P#,4Z|CmMq -@y{îé]ŢakMt>Q=  OygŶuL}{qD~ gzkR|y7V}Z#WafTa,uɋQQA6,cºbZss#&[{"f'{-Dd@cۅS\Ԥ_ -;#XA'sj1XyBCwjx~4l<!ɍΌ&ȴG_" ~8:F[9U -ڪټYYe#T_3uSq!Essevg|8^Nf(U}_(QV,k '@2*/|\IDD [A) [ .P&1w &^ ]+<_w\ KMǑЉI0wAU^P>rt\o< PhrW{Ax>WɌhgǴv{`uc`w,BwیE"%y9JxsunmOZxcJ(cY"݋^xM'?Ӕ#EHa"6@tZrL_8drGR-`-MƳ]EW@KkH@D}8-b cz. %PʨR Y$\^+Pabz b^O' -endstream -endobj -153 0 obj -<> -stream -xڽZ[s~ϯ`)\f[vKCOCdKR9 T%岑;9=Q -?"e2)o}~QhYFvk62+cm9R&OT KMueӫϏzZRTnWJMWoF%ɣ?B$EZ,|Q}a:KJCK;Pnq4ʏ"m m.ޢОNqո/UIJ>˅$ -X\2ӡ0KUT3db,Y]DxރĚĊV^` '${h/Ye7*ϒM?>EWǻω,nKw~Lg$Ŷt]oq;o4&2KV>/=ڿmy0Bܑes'l/lN_]g ҏkۿe@^9ce,h;xܺo?q!I9xw'7I_5aEF&[{vkyVO2BHL9t#IMmo&E(Յm7pA|ڹ <ѳ)ɧF=/(9pWo $ }P_fR\K?[,dXۮ bMUX1^<~ڹٕP#o!!dF:F{H(4mrTN]k*v`rrzsw{+ED.qNkw Ȟzgy#day cMxڌ=9ClHPg7)Jw \tZJ&ُࠔ'aYBPwMpvљ <)DoDa[+ܻ0?t1)/@)?1A7ퟚq";)dؠdVLAxY{1'}hOh4T[`IjX/522+?4MM[q(of}X:H@/F^}z0]"+f92Y? - -&T@Q>9)(!Ff-pO&8'L| ڪ K;}/A*87BS(!B,&z9^).(_:A%l=t]{5 ٭NIj(RPY/ݩز)(iIP]^LRQX -jC&\u8f?[|Nl žB[(o<,u5`HnJhEƍ|ۻ(kR!)]`oiW`DDK|NuY`dR"^ѻ# 7C? }~(SOW!be o9 ѯAHTM_F'F=B%Ko5t,;fzfS!V3X-aa %skHք0@\Cv -j/`Ńۦk-F!+^X;E 򬜣,'`&+31i;RL30ڤcpu%b[=BkCS<. &W  azVQ -뚡VUCPGe/!>>> -stream -xYIo7 ϯ[ Oվ\!) -v⍃8 ҟ_ZfÛ4?Q"9_gY޸Ix=>`gݼLBk$Y*V)ӧrLrf,A{8}D2|Y&9Շ)-f瘆Lj.^?0#́f]N^0َaB -1+<]c -u^$??]M3ҁB+GHxB¯0R@!FËȥ.Zс5]|,q2mz6LZ$gR#mђd-0 8yΰq44H|6 -DQrK Zge`k[~x1wRµ V&\{] [B8 TR=0WCw@^>=Ĩ;20eG-{뮂K9ݎչE`UvZ -|-$<f3 hVnXZ8mˎlqz[Z{),6M -bCŚw:c!n+)i嚲#1I$1OG"#PZrUTQ}U 9k8# fiXnzZdu3%ސze)6r=Hb]MS$t[<(M+iZc״֧;l@NٻU{R8,0$acH8Q,9 -р%+{:1 {9V aAQvH6VԆ}Eko]]H,!ޱ_8ҘuA5wvj%3BdCNsoN>X^M$|T9x6P {FXF98WcMAjF+pi\`Ǒ|壘:\ݱ>Q,*dpTҩVnX)iq}q"=+#z=x E}T>ƞC1{YQ(vmؠz9 ΦV qBwRk#BA -ӧՒܑ*lbĠEe! šӰuRX0_5~2 Us٣SlrNOx`  ։qPPKIli -endstream -endobj -165 0 obj -<> -stream -xڍWYo6~P,-"Gʊhp@89a,|3ÍF4JFEJ$ˣۇhkKDHٿ"ˣ")쟿?6նl Kg_#.9t6zNxw..,'#K< <66TQ?gC$8'y6~{We)haB9..DT|޿t_NR:۝Igm lޡw 82FRoa.@$\,*֣X8M_C qCgAW.ו {{?~&ǧǻˊq4%B)D`KOۻS]N}ӵf1I㶩nҽY cBӝ*q{\ N0l,l[Lc &1~j<#rV-5Q3~L1$]`x bĮEe{wgK3'ܯioђe[L8\Y}ym "hK(D "3`U_Ep(k, [amL'˂Ry 9}RABrSzt-=P{K= X,1A_w ^q&8_p!C;롷x$m~0Y_. s -̊S]%tA7h.r`x p]0*p!APK\ .T\oiǍ nk0AId62z -αYUr\B$JhZ8 l[CA0\Z]80U oJxTclUJ%iWeDvV@t]n膎Vx-xz*bM_jڽݗ])+  Bc\Z*)7!0s?M* WSwS a'$`†khSjqޙXoNQ|ҞQv* cյV&L8(YPj+}|]ČϦ5Vn\r8KָH]PX3 `%gReUZLdI;Џ=qJH ޷{$B:,Z60b}3ծ-{hfC}wOUpJ&.pw_ͼJ ?[Mxj1 3NԝVVu -SCf̼k+_/HpA,5b/ -endstream -endobj -172 0 obj -<> -stream -xڵks{8 5.a#DB" ЊjgY" |ݮaaa_eDz G ]ONI((Y*uBTpy9nyy2PS|4Lls g:XxL0 -Ds}ۏO޿|xIN2:4Y՝f7g\XNvpoa)Ov)'!:9"y MK"<$ryX"(ݭrtlB.yqmi\֦BX c?d>_䊐B&ik.i0,HcX׻h yey5LѠ.Il)6C$,Ec*,cBYsIH!K5DPD>A噴`P_FyncxHhqj2x8BSqĂ;[AY+gh#-D"HL0@ǖ+܊7ۢ5w}֗2l/n[߭mV%ܠ 4޴T'_e9' $l6 }%ma?>O;r4O\f* ~iG)csOڳ}u&IU;mL9w7!(ODۄu}?AH(I1v}yS%]]цʫ7yUloMӡx9vD@-eV5>{ceqUvtQuylVN6'j2Nf6 u -~z9әȹ6b'<)qsSi4hz5lV1U;ȎD1$qđ=-n_dT3?c 'vNV2u)'v}M(NHP("oD$\^feVz@ FOK̅ؗ\ƮB%ߤ2=]6uyXYYJhmˢ߬BkĠ?/O"03>Aϓÿ+018mL8iҝ6yWw4 b͆a1aܩoܨKW焇u}?HH/MF Up -(K-mQߨii7ls2]VHڌJ:/oL\q1@O J\[KȀqo&dxbΈwF\h{ij9S -?z>49ɹV0:{Bu$!#.8PndU?2G%y*'&ܽkrFqPq%TeܑO\[LҶx)ȑ@ޏۗ6UWT6[̳.d#ݣ:|`mLuܜ$`JՀ% zC8,6Aw8'遏gQvY["j |6,割S'QށԷ`aJ$5DzO&O_Fmz4Ճ3 :8; 9l| ԋJ-/:v0/t!Gu< u@FQiZГ#}N(Z؀6&̑x7~9-Tf^ZVRٯ4p љ٠MVBm?uz}6Sp~&,$y<>j]K͊ ux$}ǰ<]~g(~ -d*PM#A= 93笼E5 K;OHᆢDUzf#M )>C/.Dj/Fef?bNh4t_\H-UߡO7^9颋3f>q g+cgA:(q+l>X2 "[Z-=ǻ*Xb!/bP!!YqF;:[,v}yBFAF:T/x $C$`Q`xm? MnRAmI@E+;6,&o:c -T܅NuҤM pÒE lP]~>jU+HY/ԧU宲Pq]զO_峔wo-~y b$BA1yʞmZZR'VOwK")k~${c }$:emg*IY3U^?x(G%^W-A P@P@-ҬO1 -B=eı||.. aK熑ۮ}4,OB(˟Ŝ*ϓGDtۍs``$i2% 8ȡ$Ӻf,TV*pr:r |\P"S=/xH -$'ߑ5 ^ £V/χ 5/8 -1/RN]b3B ]+|P_',n` TeO81'lR!/VRwAQm7CƟCZ!]Oɞz<:iFLjP~0@j"D 1EKe0xYQIcc-i(ڨI};)rCk]3$9\7amEwW5ϛMQ]w6 m~!CCio5K\c#ssG3|@5BkLY\>8b{J}j|'%nBrW7-Eg\ }<2l"Du]YJn^C{M0V@rs5tieyknKy']86 -E\ƨkb1?2i|·fgc&;$P5C (j懣^('5y.7=iT{=*;ܞ<1PS>S0"rMPB3&#1 *ԪI %1^Ęlzla?6Yy:$LozF/y8C`;fw+oF\PſdȬgRV2xrr 1B_QcvfHC~]Ȟ2?c -endstream -endobj -176 0 obj -<> -stream -xڵ<]FrIe|xĒX." P8تN9RtO Ā*_ʵ"hL7ۊR2t珫a[r5e /V,Ql5W|ڡꮽpUE?[ %)O7XoͣHR GrK2հ*Q:[ÍX"Ǖ")rwaկ'E@_$F4Hʤ#|9?f7<]w=-_C<!2\H %'C<l|S>V';p:BB۸2``c2$$IG0zB|FWHLu tQ6MHr(_#";v۝#l4UCMz"kl}o˦nNx)@e>3M3+f`u-_HDm1Xwe)[feRiP}Ē Д6mTs%nQ[ -}\mllw۝h -[rLxn]%4UW,YK_""몄 tnj_eq ' ~3Dcc 1?`s eCoñh6@y2k7ù@ ҂ Ηe"804&<[G0by4qTL KӺAfneO-Own $cܪyO&%gHn|XZlh0IH ~6,">p ٚ% !8H.-nY\ | )zoȐrO>b+3CpzcVAS-c>rjhǹ %I+t4JT!wDx(DSRrG#Kc4[C31jJRMUbG 4Ui'[lL3éC7+A-to"Uh' YHTdvM, Yvr,!Pȫ 4JCE?u?TG\-u:+ Ҹ|F} lKH,&@][t}r`y`Xn3K;ܘ5cR*vRHAs?͉C1y_ e]%.ʉf(C\RZlat\ݶ9FvGFFP0|)࿉m=Eax8 -w6YzGZbugRHnsEU?O2P, Y*d,"{f5ʧ'NllD.zrX&y@ Ftp2V ` 1!VS4HBs]!a*orϋ9+Zed@‡"'X.LM.,/Τ"~ e^Z r@f3U(#s }9ɞ>LJ_HI_\\$4lxpEhQ*†EqK404f@!'ɣ^y0!i -DXD`#'Sؘ+grm?Fj_Sfnfff9 A FOmp/5TnXyLWo' Kwg&=7 +L^ez\ش.`_>{@fA)gwwlTQۜ>wx1)fSl= -⡒,d@FW}׼HUOMu6|x[ \-_l 'u= Gkm邭.vݾ ~ċ0~Gێ~TEMA})Ssmq{0*muuw80Xal5̶~Zvծw>qP@qŞg*fvS$] ̏c}XƙhcUdyN1׳HAKҥ8칸[9ᴷeh]b3eFڸHזmyby;G~Htv@f[Dkc`x뗝[?!wJ -v\Mڵ7}7h(8!pB8] y_/$65B_~~N>/<{_Et;͍Wo>1^1bBg~oql8|u 001#~}@x:j1(l;TV{'T4ɻ#ygT`PB}eN -KXS>!w 5c\^vۜ{H,,j' P XND(xyDqW)uꮿ~ͻO~YvZ?7+͛bƁ'+δ ?~a0g1#Lt&so,Co';toQt\S(cOTQګSk9ݓ="'Z$ud vWZT -Nv~?6]7qМƣwΡt7v7@0HwBlf P y;%qtۯ=W;3'?r_-_$2070i< (s}CBGY䣵$LMDߪ:OWd1 -6BN>y?[5( -endstream -endobj -179 0 obj -<> -stream -xڽ[[w~PϦI#MIT$jmĻxK}gpN8hӌb켛}}AfE3>5#"l.̺}VMʮigsk_یe"fttrFZW__p%Kb4[PK_*n,N31ՌOHهg,.rSf"-6K˲")s(9PIR UR.XfGY yLN1ITn}JcՠLSx=Z7Bxcrw)o5j <&u$9NͮΒٷYŌQ_u7ǼM|(r MSOr=)ZE^vI:_/PF/]ϕĭo17ovsKT:-þN? -_TyctN瀶(NcIOApC95$!-`qA[ܴjo XMØ |X̃]{/$ F7 ƒOsN⚳XO !i̞ -4sTk,QVlŦf[c-4r}PēI4jcvyH QΜRSCM*#9:,e9 -hA hUe"hm/Գ[ժ3:M]V]*zCk;a"4>OϠ"&KO{$e5r|%QMw$f=R ϥuHq҈`qջ??_rm}퀦a4cX_âm8Gׄ4!yx!~\˚z~-/GLn 'u7GiGeUm* -,栾قU/P{ -E=!z)X{v):؞D&9Uo<6ŅtF<RJ)SU宬5 +諁m{\/5,cLS^) r)gۨ7 Oۅ*]c#8P_% 6SܸV +ql+E.wѦ.}@娕O"9Y4z"5< ϥEgoHe_~к<7a8/E0fqh=@k B@9V7֒[OA? [h-u_BE.A߹q3l V8`@-{"\j|"=iFEՑZտW3 Qg""I32d4yyFԅЩ݄|Y\Q3&`N@I5<q(cOZ#|oscY&O2?ˢ1XenvJ=?[ P7,ВO~U0BGݗ#6?*cO@;xA0S7SN\[JeK jnx.TE¸qo>_>TAw3vtTMFq$c.sf9Mc۪_7ܨ +$!ʑYeKܙR5^^~$)k/X7{ջOo$u,% jv Qޕ,J&铹!~ASEEx^cq7ةugvP1iSD?Bx0x=a -$2癏PK>'D}wj(zjv -,PƹuQS]޾~0ǫ89Px s^6]yެv4Ib~8zn 7yAru ˢ}'sM",¸_Y޾=u^2]&ɦ<)N<̯?(^g? -endstream -endobj -186 0 obj -<>/Length 10116>> -stream -x}xl)lzH!E& p( A!R xA@+ҮWG.t˥4R&3;9%Yn ,3ga`$ -D%)J R@ *HAT"Q D -D%)J R@ *HAT~^$Q=~" =}Q[ ˧Lp@ G?7 1ATj a~T Mgl6N^~|^rqė_~y!X!!!)))K,Q*% e8j7A^oP <(SlD_p<& ? 4X~}vb1Lp5}ZI~p2PvT+4lrWf_{、$HɓoT*1:+tc"ov_ǬE FX ^6cƌCyfժU`Aqr.X(ܜT"}*TñoX1b]Whu3KRiՃ×V!f+)v;RyyӸxb18 6qLL RlA18r@D"n FlhO=#GL0R ‰Q(Q.Ϧp5'<=j(a-Z j4*>2B9 _6oirÆ_|X֩aÆ.O*ORTTuXOV\`#?={F?sMfDxFXNVލY椧1 QQ+V6|-eD<|f6F[ޒ64X# ?A8JjC"##@yy90c[P*yf3`[4nᰙ+VL -uR)%$ -I>7F@ʊo^f&&& -z*.xRRR֮]s }J*)1 >|֭J DT=<8gҴ7|3:::"22mѢE8!yUfYPa0|/:4;+ -O -&@bbҥK;w~<66V&mh -ť6oh~,yER.\[TTviXR޽~B$=[@Fij(vF8Y~+ ťԺCt}ʕZj lN'sOtlfCZn.|E<_;,!B6!!K2ǏnONN޷o+ѷۭgpHGsq,5j(++K׃F|ΨT%jd֬YJ -vˆܜ6m3gNϞ=#"2tX9 _'$ԁ_SOm߾bA0DXl21!p,{06kp:`|ny*B"_8wOMSnwQb;Y(o%/0!+v浬Y,6͐cs#C ?.&ޟL]NBÜ9EK~8uRy صֿ9g Yl0Kc(yݺ`agN>fO^fn7leц̞='4T~/-@7*ORI=󯿤j - Մ%%$\zx Xv;RD<@p9LY$;*,d#F=sol6ovoFxE_cK!J9գ,ȇC{ #_uV+VZKX0ͅba Vߛkh޽z;Xfغu1rޑs*T{7ʈx⨑csRW.(}?쳓'Oܺ=Z&,Zpڞz#*޻l^._lӡ4itYLf8zhtt^~gUe 0Ra7,Sun:ص0xF =Rhx'蘗WԡCE̚5gju ){.y*(J0BC-ʉEB*&%ױXE6]vaa!{[CГ -y' :#q8RP|s0`DpN>JʬǏH?̡C:thi:Z|RL "XKX%u_h);v - D$qx@Č׭[-XVWJu)d5((Jw yYߒK;w;wjb5klƌ;:<=z'~,((jӦͷD tD*#L&]D;+`0'6-))iԩ͚5߿OBb"C>_=zt[PHxVBwT*5y`K`xhw1 clNR(..}WvEM,|K6#F<7gΜziĞu t<CN8/**Z`kzZvRR0>pn*,Ui7oތ^3zҥK۷LLLsEb/(Hs]55{`p" B+tEO - -oc1;ĉ\Լeb'PÆ S'L>bF"ޜT&fܰ )d=0zBÑ to7;v̸+Wq NZX?eʔ%K5n,ѸIüA2~#ݼT 1 Е2+|e捛AE-=zΜ9Cz8,oB v ?H4foٲ9**V8}4N\L&FY#ӽ̙\/qvoo)1/gºC;*''gՓ'O`/J، ǀspJ b+`Wf 6E`DJ }M2cTaDKJMXY}SRoMivӰaC)fDHoӧO[/n`9'6YVmW_}/"2?IO?иq}F0j$SQ`ڶ]O+Y=a_7m—5,yv0T0=%tٳg׬YW_xxF1jɓ&NӓL Z;dK, -K.TDNXxc寭DQQQfKYVVVddꄋhb:GP)j>}+?"arhu))y7[l #{]e˖c<b~Az^)-%+qx'|23#wyzRH:mN?xă%tuYRqM;ԪU779eF3|u('S1]`8ڷ_:BB9 /0pp~dȜbL't{wݶ#@bL gffifR -D* -Yqq`@>;CCVM~gG8]8ʂQQZו$>X -Fx8d}\;c6Yԩ+**nݞX`Vǎ!|FjzJEE&.IÙ)Sn۶-6!l6#<]%(ްK)O>sݢioSQq -\r/]lܸ^vv>ѣG1& Wz!#"tB0 \sL'H{FӇ ֨ R -x<$T1o pWZ,ν E'Ă2GEbT#eN8 -! Qa,fk2$p Lqb8 'uB<O?iG[8Խ"aQޘʜ6m~㍴PȖV gNGta͘(\z5QdA(͘1жo -6YH0! -T`_p{C2)yX2{ 3BOREoUI -aw zz硱^lٲ f ^\H7̲Weg -h0 .NOՉ~nwJ -4wVKV}DȷGIHH"FpI0p!&T )..NOO񶴌bǣڵ_;ACEF0%쳳gϦP"Sr?欷C4* rjcUj=aBL*v9ax !~Ku:!kTSm 11hɿov~|r(hzru7ݺuy7b!dXKkCg=ϝ=c(.3gΒ%K0A@TxUp&jxSji&**^ӠA7n$&/YScb"?|Ax3/D`}8jx݃ -`]N64T]ԲesX1z.Gyі ٌYi=%tI*%|wz2 ͕Re_-Fx<֦GHH(0_ߚMu[ *L՗yAB7h'Eҥ+iJKKcǾkԨDZ]չZ5"^+hڿ/}С*:&&ojB>CrnD?_*M4eΝ;0UO*|T01j!T-+hU4/FbmjqJeb I8{k?}yvHJJۻ.]:V=8DXI$2|lERFѺuB^f͚}El" c0V]DUFΞ={$!!ҥKo׮EAz}!:yؿGAWsiPa\d@ݻo>rrrefLcj *Dl/~{Y3&5J[oճg_쫚5 -}`PX?1}_@=z$>>a`w+Y -N'IײZjt!!rե$W81T @RVVf̘=hݺ ,^l+?-BJQnnO?,55u787RVt[Lu-qBqlXݺLh+Wm6RM*;7YzŔ!xf0Xx -Ŵ{>}{*ZTx߀qD 0#;ʤe˖͙3r7Ik *^G-DzL,|5mu!/2.>{qjj4E'pfSLjB@|}\*z(H:,-%;+8>>~߾} o}bN Rؐ`hpf捙3g~w*<Nfdzxw@+22ZLB?b%KײeKPhYPc1Jvo=7ot>;l„ M6-:BAwUZ,*,8]N .}dS+C}ǎ3[G}(m@U^=T@`#0l..1@|A9P~T$!8ͳ; x+w-rT̄񅂡9;&O!JJJȀP vi߱C۶m -%,J \^\F)}BU{"ZRnn.r(F Q{P -J<3\BiҞ|Tb=Q(*tiD㚠 *^"U}YDK)*⊯@D%)J%?@ D%)J R@ *HAT"Q D -D%)J R@ *HAT"pB= -endstream -endobj -188 0 obj -<>>> -stream -x+T03T0A(˥d^U`hl -3 B%+DS -endstream -endobj -189 0 obj -<> -stream -xڥ[m۶_Ԟ7/FIE*"usOiz'g.#)\.b`,?ljȂG\+<у|<ܬDT{lgᾺ+la-iC]5|_5ֆr:.áVE_?2O HY!N#6T9]_%M;N# vӚZm@iZ~sǘo٤PaL_t[4ML_ lI ݹ٠Ac?-2ƅ7]q0-22Ͷ<6),h@m-Ͻ^6u,`M[QFREEb0jM:hkzJl3(m!Ҙ#h4.K{g'(˺q8S3|avظ|[ɽO4.x߂OlwϱIw[w\Eb:DoF)KNQw-{8[rt^QN?_7dK/-Ћڽ! ثPضQEyRb+t۱8CY R#1 J,R["7LB0,q% xNH -R,q4bF] Tgv2 ڑ&ʜߓ&2{@Ae<˖6TrBx8/d[1\n >󵢦0W(|Qb 70r086,py(ޚGa3Ke(OZE=iW.ql;m$aL$A]H= QU5egb oa5COns}\W80N$Gcl?[z(1 w4Cœp% c -ܚQB jH%8"ޞv3e$Z|h/"< ݈PB1.E0*ƃr ^.ҍ`&kbfRi(]+&L)2at&-*=ӮՓZA0 2=“.Tiwǫݱ.m_׍@/s5$7}RSXElڮ= 鹵;MpCנ9n^Tl }$=09 iqyK7`cdwb68TMu8ozl Yb3 MjE#x;ig2 Gxf`KS`%0? hù4 ICw1{{ltftc?epF2 ';ьHvl1{k^x-J 03w-?sp5\$l0ȥw0Nb|;5]uOuV -endstream -endobj -192 0 obj -<> -stream -xڽ[o_ChEGVb9ג74}~<;,E"ki4"|[TRej~\}x`*X_1Neƿym9=5XmZ/+^W$[V7;ÃM<+e{-rc' w3~]eT\e\V_ay9pdmHo{|幣}/q7S,4V=QF\7TLGP3a@fRvY&TYrs> `&WULJ6XcZ5b -ɗڐfm 0}|"#e#bP:5"!r2"!he0;sb" rYF2/օ}>eQ >CK❅<\0 '+Ā5)Kq gDv쀹=ptU0]UMBnVLHxewqsɁ[ǂeqi$%xy/0KE?EZy/KeK5df.;p:l}ܭV|s122 ԒE^:A`1b\:H]F.a]cDÀ91dtzJ3YB;6O=3Wp&)ؽ\f'WY0ogtuz+=ozAH3̄vm%0+eY HD3 -2nr{!b0j2S~eσq.!1F}oǗ$(g@[Nj"X{ J*$(*ǔ2}7o|#J (v !Ԙy -0|!)LQ?eKO$GN":Upbjnρ1Ryv6LBߤ עuQh!pޕ㘒hs;酮 /|jM)r-a?B?Or[}-3~i] [MI^p0Djx`9;Mjz8>vYtҁ52]Dl튫y&(E/N!b|儶F -8lQ -"SʩKE .3|ˎ<KKML^c3Y -( -ꚪ>s(l;3TDf,8\a(ߴ :'mwg\A7r^BNI#>K[y-hhpa1(<܊RcsnŸa{6/HlF -F4V31s(sN&!6䒹DH KU=[+~;aMP кl5v;[ik'!^t-MJUr(NвQ`ΧW;3\Us,dJ \ibSfIۖ0i\nV,p `4IUA#}-9= |ɲ(6ٷҚ%$Di=!6ҶoF*N`!{qhjg\5}~MmBE{횃*Jh+K"hlMyBN -,M|j\GFFXZ!Yftu>S=z$]20Bȓ[s0{KHTo&-H߷\i'8pp&"-!`LEJaL]LxBӎ7=ع'B*)=fǁ:Õ 7A𸜎zd9aΠvJX!{ K#oM*x~ -ũ6pnoAb4RYq_("0f7~'R0JAddd׼g -w x":sb}oߪgߎ~a~%G=Ytcm=>efWwpyڣ.E2ETH^nt3([DqdRCr?tC,؀p?X.A+Iw'n&tY'Lĵ`I -uGlTEkNw%+mJp6Ů~j4Xopo)s;H?;66o>lDwUxzf$㸚et`7g 3J-7&!w\.n.z^rs:K)L$QVcv.>!kH==jf3ń#~6۱{!lطo^M~Tƶ4=3 -qW<zS'p}0wi|Up8GC8N=Iw -pL>¢'Q.!5xqo;> Ճ[ڀ}ՍaE,-*쪰=gh0se_ɭGLt̊T5dZ8E*sF(a ;aZ^[C0|[h,f:=9;xr󉱛mj9⏹41=??:xڸ$ѡxpT~ǂ-9~gW{ML;NnAрgC_#{jBWlAsAز>z?9Զ2Rzi;m;pJ".،V EZ -bt )ͰVxj̹ #Eݸwџ?oP &(I9C$vMwVV~]4YXKyft&~dEغZ,ry -endstream -endobj -197 0 obj -<> -stream -xڽ[m_IC <ҩˑs±/ѻ;.;IIE.G;3ϳ;;˛< щf -7OnN -"t?N&4tҽfVuWv릾1YLy&\i f-륈]0^'4U7yBғ{O&sRqNEYm ['33hn/ )3%[N8L1I -: E2CU1]\,)4DTì*uu"v=R&.,:W+_=o+J竌իWMS.LӦ.7*c8tu -r̵!B0DАOfs􁻥}wu f<˧rɘ3IhD@CO7u# pF+׵T"1Wy]nW:H8[8g\̫]b^Dǐ [Adr2Y#-Sk5i3yqҙJ T1`@>]]c}$Rm t6AhG#fUX=MۮWqDi -K|qBSK XAX+pE)-373Eڸ)̇bҊ,#0 3İ7eɠ/{5/ow@=^; P$F(ޜ~:&Y:9eIANiٗA(ȵ@"'"4Zx,˾zA<h{ J:~,4xe@ל^wTvXY$D)eȏbB #j4 16ɚKM -d \;Gi!&OEvݘ#ǮGljs*FPMxz~@AS^4Vw=y!p7oue,'boC~XuQ%j+b„,?]$ aHGF5H\ -6fvS9w%88^ŞpwKu7|X38ښR\Z[Kw i󓑱%`e^$Lo}O߯yx|ۇ>0M?)c,uqaإUMҲnv}t<{;rV뷳w?~EGԙ'g:u,"?88h*#|T음 -~Ŝí[<(! _k~WB\[Jt)܃.Ǝ-$r%jvV>z'i#:&.9.bV` t}~ -ך< .4fh8:Nj4@_52G Nm>nW#gА* 6\*-$Y`F3AR`Ʃ0uӮ{Lj3:S;ꈠ>zՈPtp JG@z"xt -'wX3Yo~|mPzhJG) yR6Qҋx &,> dbyF#% S`uj<Fb灑x3H7t8C)SyYᅧS -Sm|{^ݏ6#,^måEň3E~*chtۇq^{)Ԋ*Ol%4 ;9l"c6d0v #>j.JI/<DqA gDfz5 Ӳmw@`Yv5fvamϊ= qe483&$?vfqq!n]Uu [-2/o}UϚw2Nl.6Q]\}Oaᑎ2:h;T5h~lF-eщ_ LRC}Am, mo$x1+!vi%ƣrBk{ J)@ЇkJ*OG 3㵄!D5J9W:mb9/}9-x5oII[q,b?lIF\ž#\8^zw~ Ύ3푿 o= Uھ ik4/Me?/ǣ= ˼j%8}ά?,λE~'7sýO: -endstream -endobj -200 0 obj -<> -stream -xڽWo6~_AyoK7l+ź?G(Kr(x}#("GfH++GtЋ%E % QAƒ"^nݪJ&M_O+WofՋLr0PmTSyHpMh^{,g-+~=_ɪNnz˺s+^c:mn $ۭE/.I]dd<3|`x a=Q.yqrq3qw8Q~m| 'b 9)q< -Rj|]DAspTQ±~]f%UB[Xjo6a.Ls H֥uo zMupaR)y5 !.E"CFOSrpǑ0TyM;߀A:Y mf1ayn&41Hgp`~uχä[/ye;ѓ;^O*>znfyw0MZ̔=♈ QxI?&OxrBH4yE4Lh-F")I+4`E:X.\oUT"~x@ֆV)Pj;#0[D.|qW]gz1u~rݻi!x?zwHj(ϲNV(uE>B6$7"ZpNj=۷]V{yyՐM0vwV5m[>t)|+'m5 -endstream -endobj -214 0 obj -<>/Length 46926>> -stream -xw\?I 앰)֟{ jUk[FD6jAŁ -EAdVAnk]-:@DEA!2>OFH> Sk}s|00 C 6`?#rhb:__(t iĢ@C\ȔGi+`>@G9GD=G^eNߤs!˄:jXL/|RPMg)PO=GQe p9 D  /1mF*^\?1#`10'O&ua#_rZu;x3}"(Ⱦ3aad^Kj+., Lh̵(Ԓ?U/ンq^uM_u51cF]qS@_&vN tj*m5l*Vҟ0BɼС)c 9m'#)-,wEy`ǯ!ƇW ŊЙ-iokJÇ=-^' D #8X8{M^ /JMevCG$"-sr)PVKKm9079%ME|S[zZ ۛbA6 K$*Qe2fHbi_uK_Ԕ[װ՚\]m_<~(ԗ9%CV3:yLNWd^`( 9:@˗.͜9_֭[}ݿR5> 9TTTW;L46YSsrrOٶ>87}/ 9?~|ζ/f'g9r8EN:w_[LRvٶ>87}/ $@`obn~fuxyiG(wΜ]CM`k[@]H?UA0T-5x՜UtU۾ң0_?L;h`-(CHJ{6 $c/(#C.DU'$'vCbN䐞yML KM宲>4-al_ X3\_#TA -9Ұ ;ঌ6=}RX+N]IYCTw2#CC\L=dzpeוN(ܶ4HH-7`WOH)(||?leGm:_MվPuJƨ.N†%>>֋4%!}w9/ӷmTqՕ5,FկI~Ze#LVP>\:.#~%w̮vJ1?SINc8Pe W$T Q+ 8DMߪˡkp?]mxCڛL̘nKqJOɚ3UǸ*H*Eyw9kAj4EMN0~ Z$7`ը*ICx4; TW).W0=F %b iU,yÁ~#}CVY?'c4"RWW$yr['{]F+uӾa縆S)YsᕦѪ4Y\PuQM\:JNVwΖva뛘՛a5U>Gw,҂ʒ}n6~u[[Z4%Vo۳CB&i*x!0_۬iY\[Z_]|cf4e1 -HN2ڵc\X++7cpS!QCbB-`fLC~ "%Rlc,c$І.9DkGtdjUׅ]@qD!a,ҚCM'j8EW}LxiFlCPQJ[Imo(X w1!c._ [Q<F-sE.%ܦHC*q6z4~#}Cឧ]Szo@n &.aKąrn e9E] H.{Å&c2=8̝κxb߷8vyO;&cQy$̎(0.9<g~MzcEʁJw|J6 {=щa Rnۇ_wxQcQ1X.٘!¾I9騋Vڛ6.FFASԃ40>Ky"^x_2h_—CWohuKZ˜ޢ4=:MZK23jXCvv|Kr'FY Qڒ*X\~ 9][$(sr"b?kDD毗ۚ9W}SI6 }ugx |}s9ư8{7kB)տ -i 5ڸ~#Y*{v^Nk#Yt=Y-7no;qu p^wېwٔtdr98]|FAKu9>&.()!m>oV913"l7V!!sղĶ͘:e r8Ny$ڒ73ׁ/$m!{o/}=ȯ#w\;>_DR~)?#rbňs HX`#6e+\˗"SY P!YG8{! =Q (?C4K/;4C񣞺Gx1Q #[~D@iC&3eeQ"g+<2¸\gx |}Ir(yiޙA z#Zw7:b!"%hJC2Qc0NŇzn -cE1)ibߚ109h͖?>sO #}TFi$;D [VѦw -t$!*0C^naH3 -q0K9m}b04<}NAdQ8E%UDMᆪAZf?U>g?gh399'G/EB&O.Tm_#ӗ̀O Cl[bm|b?U>g?gh3YR/|?, 3 _!@r!C @@9rW9r80a8,[:,Ͼtsc9\wFrXpjr8Lv6?#0QNMdܷ֞g !a8KK^if6$~gfYtD1Xp㫇Zߥ0;B] v|]m+˽V6>O56yieb(dd pi 2E?$\[]!P5(>ᰝFqh]- E WEl)رtŘ+ˡH9PQ9TWԱ(eBGKr6 =Ǧ]pz^qfԙ:uEξU5'k$qAD콐oPtMОw(ڀP%$켵K-~& Wgl dvp' 5-/Ԓfβ "vUPc-o#C̕ - kG/A[/mWnN~5ۜ{Ko65P&lh-I)g&4-uhV<;}p'7LW25;k7i3yتTIuΟ>KGo:Wڇ.P=7aɇVUc`rn-:Ωv;Л40Y-4&9k9grЌ-~5#΄[(c4\;}Fgok[aCI?cGpBʙֹXMu=RjT#9Lkeν<:֖բRbiՍA7f9@H̲K>}U\b:5sQcfȢʡU3D?';ʕl6ܘt>sgwV$N+ CSsf-mY')&ȗbv-պbSl#[bU0v`=e飵%Fe=wq34?9bv}-@ؚ͊&J Qc$bŸRW\MTpҭ?aRxr8Ԓ} -6׶>q2;ֻTOep&?عol+r>d&rLr7h qΨֶںf<}A_e3\=,x"σ N$lhwLP$}][i7x~EМݶ[i^}׊6g0Y1ط>C߻ٻ--8x6_?ʲz؆-۾Ve֞׊ؼͫdhC{g$E+!>q~èid(R(Dzt OFc%Lȣ=iU4Ȩi5[r?)x -VEEV=q5-Xu - <>яwfAYE,"*W||"9۪<~/'%4qbjH!RӜ9s0|)0 sׯO2H[ދ!,^3˳o?i }5ܘB, _5VVԵ5)J^J IJgZ+o=@9eRjK9OnUBNyԌ:$2z>Į{xI§L+i%iT =$&ןk}il1IO⨹;תg -ڜ{ǫ7'8HZbEDpzm%qv1oXiag#-T'?Ky>b_żJ&`l"&F -zzdI럱t,v^j5un-_3 =`rpxZx?7.kp %UR>0hՉq?8Mi{ںmFV!z, 킵#S ~7?t:ylsuܻK <>;=jetr8w\N,^zu̘1JJJR`sH-C&9]gU EW_\􎁧SH/Y͵u- -UC0_08L554d3YKc)EBg*-G(MwH4`kaHj|sx^sjs5m$5l2tԎ6h 2Z,݄G;JC'DNJےX 'TNFR5ECN4u܆|k5J"杇+nykbTVXX;zƒ淩N_ɖZ;)lsfb56p@m?)M1A?xF &o뜓G9T2XY2GkRa gR0W斟r^tKzICEu`0U罼vVñ+~疴gB5jf$,as1 NalVٚg*t<9`G_rLrI=<^L`L19DAZaq{ؼeBo:)ß6 4h3)a'|0HZըUhcW2hyg"GR2}Ej$I,}5y2^j޸9z>QXJlS\N6$6?[u52qseļ=N^X])Ҳ{Gyl~FVhYKuۻ*EJgLHM,;z!ԈŅ/L{i,<;8e<-|@ z~SvD -}|Ӄ QcjHCEFĄKy\QRJژcn鱓"L.!-~Jl/ -n|z=RLФL <K-~%.u^~\Ixg^(?qd2㬯k2kSLfr$*6$|nآHYN>bbM~}Xφpj|?LJQǴ3UA)-5vDϖa~!P\Jz8{fD';NaW7܏2ˡxz=A7r]$Þ.gȀrFO$` SN{C5g.~qO"w&+[%gZ]qa -Ti܂׾BU0vlnqr -m(~>ւuoފ>ĞP(e9.}G ujanCìYT9DX\8u9|R4⤵ r88MQ9Y-.r8&q}CuɭO7م͌DoD|19ieu,QDKnUX{uK%ˡ>!54/;'sO v'o'tbrhTvZvl)v9 U&n(YLf"CG-UWqH=_%CiǦ mŭI -bDmdnO ܜϬnC.LHn:e9r(!œy{YzZu̍ÚzCW\MTpҭ?aR$aIA[r(өboxjmmFU6ۙ{)dJU|wf7 fۘW6OU*fFAlHc㭩B+[랲{YqSu[c_i{!Ԏbiotb5K\,2틥.1=ӊe7e\9$9͌KXɏ"hT_c>1a~WQW bYKig3r/do=6[%~x{|)aWeDX)j*Wq/,[}sjs,9D_ =*&79*Na \KfݻI!s"YXe)o8uR+AWߵb͙øuah2ܾ[i^f :z C:aw!9T8o-GYG1N -^ā1x w^(!ۿxt[,-juopI[i7x~EМݶ[iP#v&@XdҜPwE/ 8cvA'&D S _HiC+7A04auKB 1d#z5Gvŗ] -|v2USYmDfA{8: -W;w8 eLpF}x/Î=n;V!+ݘO64PԼ5p?8_SxCKr.g5qmH6,i;W =4`pw,R[I}vnA;)aEҪFԜߒUoOZH *i -O''6D|8I|[[N H vm/'5$pKM,-NP@_'àyQZF~efWRrC9r!C @@9rT&hnn.##Q@:N̙#Ha^~}ʔ)D"7p9BXafy' Y?;ʊ6&EлW+Bݽd$O{2֣:aSfUA%PN3S5c @u~{7u+vV^JRF_&*l{ԓ#HL p]46XJc6~݀{ǫ8HZb(x!/RJlb0FZOIl+(\b/U20Keu'$k%yڣw>chY>~l?,K awQ?o}5xpxZx?7.kp I U'~Y.7MOHӣ^:B/ ֎L6N v6{#6~wDܹsl6[8]Lz1c())I-*! cw=:W7J \}q;jlL!bokU -~2yp0LPz5YKcE^j_]QǖP&~s~;j$v0$5ιWe+ɓBN^7!3 cj#;W 0Cx7:Z,(ٷjۙ&aI ҃LA!46lmFErdmR3GlD ޵0oWтph+Mp^Kzp\oʼ'.dKP^Vxڶ@ (6O-qJ\n( ' 6FqKbC681{2§*u/ӷmq9DAa_޷)MyozXT_^}8健.f$\ork^)^G'"VJDI~N?R"k)PĶy #EiS3)kd ,C}6!U uok5\јtrezhϵyUr(9snaXׯ_6lGK<{r o8[!ڦ܄!MeM~bIP~hǟU#~otL;.nYjqV㈯:Wڇ.P=7a~tVSyeIp p -o, ߐoE噗 |cg7A=ao1ZͷҲyNJ[G+5֎^!2;d<`ɘy̚oТ6=m"*Lw96:-,5;<;a7S%Q:>h9Ň7x=X<7>Ǥȡ&!^+Fp22. nOa-?P,Wb# c+`{yg횭cWs-iD.ki1#!^Ҝq>6WӐڈmf{fz@͓Qz4*$ ޴t_CT%f['{]F+ޥ:oM9<@-;ye*O5L}̲c!v/#̓ß6 4h6FM Dx$?y`-.Q>`{L!%sWJRWaZ+sѩ6iۏ尭$h9%jCb#^wX##7g$;vv8yaQwŦH"yY=S3cfY.mbiKŞ-޴mܫs=\\kk5gh'GpB%18x =?)D;"y>Ǩ1qKdɡ"jb¥f.()%mJVw-=!QI1#y;OW֐e]a]OOIICឧ]Sz2lÿK\(f<ﱑϼP*dY_dYӧL͸!HTQmHݰE}Įwzq -. &-~\*~P!A3S ڸamٶul&'&=G'GӎT>D 86-սypL̈]Ruw\^îvAoe~GC^!=#zo,kI R.gȀrFO$` SN{C5g.~qO"w&+[%gZM]qa -Ti܂׾BU0vlnqr -m(~>ւuoފ>ĞP(e9.}G ujan~ϔq~Q[{~gFEΰD9DwT,Anz/"jnQuMMw'H 5VZeKn}.lf|I=ZY<ǺÞ"!q3VCbm:M5f{':4憋/'r(t~~?5k2ss>]z3!9 䰇jˡ{KKB&OMaf镳jխ27kQ]qi6QKBmHvn>I(&mʉ׻OK-0n!O_W ogkZ=*UuܙH4eocnHjz_v,?U-!q9ן -|vCo7{"fsOFUl͏Y|u|(R;rq*~q )d@$džrZj̏?2HBol+r>dD.b* wf%,䇐Q~ @b燱ol~0Ox?~ӫUYrxl -㌫ۍ1,틥3nG/I09=[il^;C Ҵoܐߩc -v -ZCb)bM%6s -ڙ/:kDX/tmTXjv`ȟg4~^yC9ܘvt -V7؇s8rC[OVjoors4~!_MiY"'X,˸?F-99t iӎ/քنCcҜWz'Pj[eR`CUDD $gfw}MuGۈ7? ֺb^Õ ЫZ1a:^0b4Q|n_`l4/V$SG:.$j8ރ-B(5fP]׋80:bEg/,K{]mB.4'2\h}G\q[coz2|Us<?lQzl%noVw֛6kF3Wr88\q„;"|ᰡy{j Ir8 wh?z&.TviRZ(߽!&l#PȮKa>A! -x#HL=hsorGGWUUzaANҨ~رMxJw9o;Xt3՚j׵k -"rh~UNVL&ֹMXVɆ[%ߒ=vG -$Tu:9Y^nuVf-rؒ{x][K`+pw,R[I}sQmaEb~9:%&5 (8yA-Hb!/VgqaʃNˡ" q 2L'Z[[{BhQT%}K3D -?hAn*STw\UYۆWyBԄ|(! rYUȒQP -0351ePj{p%[BxUXT -92*iiG`VceE#NEKz^cTɚV F ofo Vh*0>)9œfZE3 :Ц('zA$!h{hBmT=0֪I\>鏴!pOp /wXGҐPekXLG>ɨ/7WF'[Rehbiw -v? _2͋6+3<2C!C @@9r!'C2DsssZ/tr4g A - \.SL!)p3˳o?i }5ܘB)_5VVԵ5)Jl7hFߊj̾A攙cHygj.N3S5c n B=b=Bo$ -VN3Mf={] -ݛKE$>]꫿ҫa;(ks66|"9h!Heȿ_KEl+y*O ;i?$#^avp/G싽W,QcMX aO{,Jgl5m=݇*OeJxoWL~NOemN$;>ւPďNT"ܴ=y\m]EvՇ6#fp^+vڑ)}?~ :KW?wPh~n52`tr8w\N,^zu̘1JJJR`sH-C&<]gU W_\􎁧S[kZ8D_0e08L554d5YKcE^j_]QǖP Ws~;j$v0$5ιWe+ɓBN^g'3Z[LQ$/K2%AI!£oPtMОw(ڀГymt3:ÏeE1&V9(&8m=8.7 e^%j(si/ <m[ Kw8w -G.7ZKS@JW[wt8B}E!JoM}lK uS_uڃV;]j*wE1ES ؝&f@+.0ehdرu<5S9mJq޿[W;\V#41m%%V/FKIQh{ϒL2ԗiR}騱RŮ#U -HnnZ"暛S sܝNL ^xb}<|~@{Y͜9sP̰Xׯ6L[[[rp%Z=ᅷC`]fLpKmSU\}n搋۲&?X$(Uq֪Q7h:yi,8͂lqWmӫtCB0?:+x|$ ԅD -ŌS,5 1Wj*+,jӕ Ee,E1R'9oSr-0fwS̸kңm V@m?)M1A?xF f!M)j9'ύ1)rep5Ny֤ 2. nOa-?P,Wb# ,`{yg횭cWs-iD.ki1#!^N{jhyg"GR2}Ej$I,}5y2^j޸9z>QbbM~}Xφpj|?LJQǴ3U)-5vDdgd{"j ULdcgF4R D/O?nΛ֣-GPDM-Voc} -eDHZ,E-y99w{b;y8hJǏ,L^;/lpܖks^e¼0n&b;M$V^!~ 5f{':4憋/'r(tUw\So {Y2d)u:q[p Sd2Tdlu:h-:B 28jysN'xz -*% ^'6ȡy"$m7=]K~p|?.[7N n1R=1E cp7vmzD+f )E 1.3uy$mw~};s;砽k,L|S.*X9NVΗ[%ٍ"窋FUd<y1QD -ф,YOdza " E $K5<2Xq[V!YvܻR ]ge^ŏ(6icX92! 4P1N[_/EL~Zg+dz^>7'bi[ioIX\UtsGθ'姃WX6 XH&lAV uD[cRCqUSʴ̜eZPhSr9}}ڼP =,U^^\-466kso \_*.*vsd^ǥ 5wWceiuS/J,."Jm PYXP {"%!\UA 1I@t#qz:o F|W|HIH!Ex+ Coϋ2Z36h(ѽzD }JsG5+͊Zs{Q9{JBYnLN<ܿnus=T'Z{2/Y+3ޜTXG]}o/$nK{]) 7OAص'![GWa+ĺ5NȚ-5T_$؊% ҈z+ -k 9@Mrw\rHż'(*Ϋg+M¾4]OWJZ-\F3qݯ_-߻ڼo+ r1M04 SkvQw{N5&7\=O #gف tM ǐp":78,P_R | B|-RRjZ8 nT  "+f&Rbށ7RX`8G Oa=s3éc>d:)&,aAP׹c}9йc4LCWF2FeFߨ`w571q5q#UR} uH5zh^ -{f@_ ?g~z+&]3:-Z)1s8Zp&BzMD#m\Eaق'1W> ^>f&%n3ե3a*Nr_IY.0JSt= -^&Vݪ3 -&  o_>{-Caa" nN%!@r!C @@9r+!טhjzrȵdmm#(a\zuʔ)X,VJ8lމw86Lo7b,< &75u(ki*ɠn|\Uњ2k`cg΁ 򘙓upg$/4!V[e34"/N)ĆVNMLg[n( FK ݽd$/uXᧅs|xeb5A߼Jr(B4-@are*blU/hi'MW s@~m(~.3?ls`1!qF_ Y',5m?~P}QLK9d1W Z0/ ]ԻeF -zώ9~LM#SLT{oD؝UE1q9ںv1-^7?:Z""5Ob} +u[,df߾x>oܵũ)_Oϟ}bi˗/7NIIi:/W9.x`'f[qrhiILL4().6V 8 f S[!l:BE+;ԞwwKNSSYf)Tˮ_XùΎ q-7X-4n47h95MUYBVs@_m/+X6 ӳFoz ֋=q+!PB!dQZreʩ +eT*E4 lOv ~QXKA-*( fS[ZCyݍƠ褦AÐYXIKhuD<g_3eQGBr(j;kFN]CA.!0G._O6xAI~|P/aK+,IUAC rsk~$Ş`VfAo45?LGHvb3SG2 ^!Z+CFCoB$n0¯ E&?g Y`W KQF ->}] rҥKa*ջVzyi?r,-ohuzyύf^Lfug38]̐0ٽ?%1/ޱQK_]=~Qn1h>ِnH=yÆHi[.Vl*9|JGM8O#ܓz+UA($+n8BLIh@A }Kz:ky nݯRjkd①ЋLC}n'"&bFԴtmiZ$Dp/;;yY=oף늓Ht@_g)CIX[[3LkKKKA'O ի+)—^a|hȳDK u$Cşkbګo>O6Q=5#2ǺlWHNC˥XNUnoc\kvz<[Gf]dEMg=GVCĜ9@]HE8/uWA:Ԑ,"t^Zc;P[J*7N*C|K)mVMvk,-!|̱Y*ǹ(gJ -;Z&?tRFPZrh9Dt"39~Ό)Sfv,~`Io j@<!Q*׵8 -tL}xs\[*Sr28~lgAI6?}HП''햏 yϺFvG&,ѨfNz("C'i.EYTм5׫w`Εq)-Imm<ݎ/ˡC,+1n~ACϹȻ$;ބsӭlQ ={^~}!wr_b]2$J NgK 0Z}dE>h?h߮eRҘU6>д{T017=RE:cYφL"q"TޅA`_Xl)4&rn]Q=iA7굟{\|tY8oC|O@9+~e+].Ub}r]> [2o]8+'g:M% T#"Û"SBFd>X-3aBY1^r$Y\:bwyXq˧z`IϷ'JZ/lU{bU VnFBqo'Ss=*s.V+Gjá+ٳ9"/}I "Wuu/ʜ%NP+FD9\"uVPa(Yn/r?GE!9lZ -PR3T/. -\6Ƈo.AR+b9zbRT$9nږ)VR݋c\ggI%-va;,vZwA{"YܙJͧ\vUs q/Z Jh+ EUx)c¡HO %K_#89Hi9"BgAk,9m[IqrLutyd=cȉ{z;Ҵtɞ}x?2{ bp@r/@8m},Q3iɟm2ГIOxXdJMkgcol%}L-Hk‘[itw -z8Gj$q` (YV-,Րk+W&|55'Y*Z(HEoz:#.Bv4~w;vp OR6S=< qJŽEf/"d|رĹVqi9 `*Ƈ,n uD[cRCqUSʴ̜eZPhSr9}}ڼP =,U^^>sL! -͛7_tZx:䗊J#2Yq);r=%ojmMqaXYZݩԋ*i x^`7t;(+6m([K*vU1Zyȁ0+J3R~ZnY8JBWbcZ+.{gTP3nrУ)T lA L{ @4m|q Y+Rs2 -`+0 -!K"6vHi$LE+ZP[[ -*bzIin"uK+> bs+)EV(|r373=1u/jj@f@a8tnpiH -0Hƨ {ĩčtS6$VMK]-H9"VR}AdMk=0կň$CM!6RptbRPܢ<#E -Aj"A*KDd(hi Ut>l6[:`0C<_$xӷy;yq.=%Tq|JJv,UQBp-4VQPF87)`Ox6ٛn ips:$@rC @@9r!C @_YD V דC%kkkA իSLb_a`>wYmkAkN5^Ei~J*uE10܈V&=Y@.(4 ~| wl@96}3IP9gz!T(XbSq+T |8VYLo$M &' y+D>qH!<kk,ҽL&[}%9h!HCb -g*˯79g L܁̳'ieY>)Z#&,h ?Ke䇙\Bc?Č;4r@TPWEj+XGuVM5IaYFښ>7aey4E=t,q8RӖy,4;>vO*(nfS鑆ꃀX XuӶpQG/.u[,d~ Ey!Xӟ_ETz;-NO9 '`X4˗Ǎ$rȦ47h95MUYzf9N4Li!d5vAf=}CFo,3 CM)";ԍ |Pa&ƪ4x !tyK U'I|,EWho{޶cМꨕkP,SNeX)zӼcXr2_vEp6욡ZK Mԧ9nV:(?l+ifYgP-5E[6-Y؝޸ʞMn;-{`>-I7Qp -ik7^o*N{|=/\{#=S6YɕΙ{?&#" -)S&т1>B!(AXXIK{3iɻ@Қyd3SG'4;d4&$ Qv2>/Db[?/ ,j!wi(\] rҥKABr@N'j;8o]a3 j/Ndh -coO\\= -7PiVkO:~`QzP_ ;pY' FI^0 [i}n4 rV8i^{b̺. &W|VDp+*dA4ʬ/Xަκ{^K=[_t%No%+_ K̂0x=+(1 -@UNA;')EʛdJ_XI{U轎2cպg%SD+}sy-LjZv{GsS}Kz:ky nݯ59-w Jyo&x4 TQ[p/;;Gr?{ޮGEn8BLIh@CÕ({הF9D2F,S醋[~7ll'b|FxS\hFm U50-֬v0Ӓw$5oL<zi/Ս]Dh6;U_K;cJ'jlZ) 0ȖS]<O&q ɼz?EΤ^_틶R|[SCkH[IOUgH؝c4{Q{JcMJs6.U#uw3rn:<9@t&|˼ܧ^ZKn_Y]RcIB6m|ۢϓweO}͠Ckg;#e'cX915Q|9*-tԡai N ]M^Jct*=uclTRY^9NQEMKKš͸ lX(axu WڱUVlzѤ9w7p^V%<\] 7ou8RwH|uTGEkFrcVגrG ҵ i9Q4[{;IClŚߊ3ܛHԖAS[adEڊUٱs0Ɵ˽&*Q_>[ -y-u<Pyr -|QCA; hdޗyz][zh2npl4`M u$5cr6 ȋ^K?͗Cm*a%qsT1b&w*l ;9 =^cJ*Zϑ*P gp…z -f^}gnald>nΊ3pe\Ҋ6Ds77ZccrM̙ iU~oڎǂʡ'1AӣC,A-3YV̋HGYYv}@dK= "())ņ& 雧ȾF6:Rȓe}rx"3jSg+3_8;|1yt!PTl" -*O0EՃGr113v~ 8a#gZ>Z3Prmo89n8xݛ/?8ZG2G?[Z͗@ǤٹrU^i.EYTLq*<r ( nKyj41rh 3,ou6eZ)Wb_CoNֺvWN΋Y[4RStJ]fw鬾Se; ¨MT_&S4>u=PjTߪ碜*(JĚc $nR[>Aח!}uq/yQý*>ĽY6;˰|\]tӭlQ bʡīE̷.E]oh`cr?J!Zm&ѥ~P@lOvU$ä33/!>M |"=#~$Ѿ]y v^/|HX|Q~Q']N;94+rn;<"Դ7=Ri/_W?z7o:҄SUS3%ᨻ-%Y)w.ޯܽaz+]Y㭫g,P,e*Y𾅚h w5O[Aѣd!ĆrXkj2'j ÉI&H9O7 q1^X8]W.Vu i|o$+"'ߵ |H%4 .f\)׽(5~:(_b()Hw }ö@Cɿ;C;q葺"/1&::֗ g,xً:zۖq H4YSp*eWYflG{+i[5Z{WkRi -CGϱ'MMڠ<&wc׶GtM0wfrW']j,5E~ l_/S]r)Yy>r%-va;,vZ_#;v'{N{Es,.WC!Kia)52FX'ׯ)0mMڪP!9%KW\:HפRcsU!ͭ9rlA)?^"ߍqb}Yr]w.%P`]2-3gv;1TXԓYY?h`X˼|n,KOo %KE Y'K7G=l!+8)?b@@)<~ؿBOF8)4 .fi鉶:ֻ¥ AC9̜Y侾fm^teJfrb#*"W ^8Yڸj="VkW|H\`?ˌ^ȔњnGC<ށM!E;!ѬEPEV.3) YuMc}Pul%jilV/Ex\gMi7Nlu:K{ѭAncQZWDB}kk]׏5(,2ni}ϒwOqiWj;Xvad c_ER񠀢8]E{9~DZ;fT`ia|/b Utay[q_ o9J$b޿[շfz=ܲq^1CuuW+%C奇Ӗlgف tM ǒ)U~*lr L½ ln%355!irURQ&0DbH)iȊΜ{AKM-l -ivCJMk(ClCkmlGk 3MmmlB+koJ"tr5K|ot(#S6^KGpG{#G (йÌ4Lc_[ }@ژ8U§RrCZiħ1F2Fe $Z9i'NMD旈W6"l f|ԳQBp-4VQPF87 &3f>{-Caa"?D @@9r!C @_YD V דC%kkkA իSLb8㿶.Ơ?PqQn +g?x^Y?zdugzS'i|U&+j*/tsԾ|˿,Xt}`Jr(B4-@areC+b&'?/IC3`)"xB! -S6v9?f3$C\^=Gtke#K$ PX-m<{"cYڅtfWI)wm)\"P#Yg'/.u[,d%{?b|>9]wtG:0xΟ?b Ҥ/_7n!̤ZںXHQ ;S^SqލvyotUG\sbr*JN\ Mun۪[:`ISjilcij*Ȧ47h9eY~Uz4D7V"S[ȱڀCI&6ur*4*!0+1<'p?0ZqHkx:w:Ay";d4NE&?zӒ4 zS $5cT Qr/w#uFP[^#KhnAEp9wzz&&W;gOR,хA=>;.41Eׂ Q \hx$ |.Xܥp9wUK.YXX#a}n4 R8i^{v-%G9YxtX9"g-eGv ;pY' FI^0 `þwz:y-YPni~ew+ -f x59vY'&J՝ K̂0x=+(WKfy'j;y*dGcWR6<$xYW9g-)<{ﺥ4gd/ז}89\L5ҖlOM6v7\=T+;\lw<]a_'pH|䱐~*2lF[E#ak4Z ;oN;ZsdKЩ.}n"s',kJ*ѷԨc_ۛf%]qOyx(("P_W~HH=Z|ȦտQ?Aq~!>o1ݿfs-ady9~7홢@{^<0>pH+Q7{en$ovWx)>AO6QfV~kJ(Enޏ)K1_^Ҩe(uhZKKѱ/7߈ùo7ynaxomŪعjVO^yqq ܍F86#*\ob-r~$q:"5Q#p1fJXII[W{s$f -|iC{$Pl =dxMH˱]urdkƗySk[bS-I68Jp}1&-H ʡAyK8vu6msHdEV}oFAS[adE"Ydeޗyz][zh2ql4W|j"Zn1V3 mԧՌm@ -/o '1AS… … &&&:::bGewjwЙ]M D6!l3SbyL@}O闹:5hz`<|&k*'à -DgԊէ(f LЋKwNw?3bTc9^C*!3+tV9+q>ȡTC ׂc=m6?:U?n~zIcH5E|93L1 -;Z0է2t?O徫r] -tLk+W吾8Ji߹Ȼ$;7<6=`7'^i.EYT -\"N&씺"/c#_KPVw9 L{<5^gs % g/!O,6S~L\ -U9E93TPB, c h;' F~*DŽR-~]#1kP?͘z-pŖ+NJ?˲5YTF)vrHi дcz;\{d té;-Y]oVܻwGCG<\kj2Z^0fX-3aw}ri}+0z,{9rt-a/o?sq,;g+dѣNES3*gGx,Z8@{=> -rJ=1$9uKpteJ@Lpۭk}uHȴm)}5Pî+:Xw 7~C$KE-qSWI wLh&|RG~_1~L*E{p?C;LYlmN΢թ cp7vmzDɡ)jJ3ѥmh,Ͻ5)۴}F?#k,5E~ l_/S]r)Yy>rL3y'eq: -49(?y$mw~};cx)c¡hN!gW2̓Tw mjk+/וKsFq:Xޖ=ΑGܤzXd"MkgceҞԾSʴ̜eZPhS%KW\:Hפd]B5k+CW0Τ,CɇK -nnTIΓ>mmu8/w?K9:P8fNBIǿ tH! nryru9W,{|5A!>lP8%AC] 2g+dS~E{QśΈw\DĠOل|!c… ;DG׿LY,Vyy9"rXOOooE~ld 5wա)btv: -_S|;cӯuaMPtrڀZ*$o1ac J|9w- f{?T$NW"Ot g0Ck RjZ{!NkJ н؎VRjlJ c{'JfJ)jj*cϡ?z'7HUaWLY1 P@*} ;aEM-%mL*8 5 B̐iZp]"CAKۑ}cSط0'InJye(/йeҰm~ظ0tӃHP ==Hƨ ӐT]p]W6"l f'@KPVX\>UWx~_h,Ba`'fɏ=Io/Bne)"~B=&W=\vgҬ++OxeLh㚗]0Nq_h -`ӈ/i!0PF/z$蝌3"|Nxqsr 9r!C @@9r5&Zhee%%~$_OQ|%0 s8WN2~9?A"] -A+0܈V&s`fs`0h!zC?4/B#%E;~:8XmNҔ$5MWU;^&'}aq:5CiN/= 6>$-D v/_6=" -ΠgYĜ]Oތ;4r''dB0X95mo3c 6Q!n,hۈ˵P_n}_STKysBʩ+l^? tù({*R2eqZ~{C[6bIOWF}UBv][,rJsҿGyDץ>7wK]每09wG:0HΟ?b Ҥ/_7n!̤ZںXlH{OljkBZUreʩ +eT;q'4i6ֺonU<'mOq %,{0H帖eUjii0V"S[;lWΙ)R-[(˷Q|Tjx -dć@Gi*R{La&˩k|Ӭ&`F}WHcxN1~"`tO6y$s$cTJ88aHV `k?V|LK,MfO%0܏I3SG ZasP܍CAQzz ޔڍ h0N/P_nF$>ɕΙ%Ktq } c0TAG1NvH h{tJZrs?yFaH1H|'" Z] -s\Et钅@{=v=ܼF uәgRrJwc-rOi0RvdaיWu`0 V9{x.גu;]vwɫmy{WC~nWz"iT݉+,׳rdǯqrhMvq9Vxe&E=msPC27(}s6ޒ{3K_[JsfHvrmipWxS&D6L -ijc_ PXχg\\ 4A.W&it6'Ʀz`.ćDyE6߻e[.հ VEo\s$w@zt]qXHDm -]6-LjZv{Gsݰ5RӆӝuL9%Tt7~xwǹo5y[jӱݯ_Mp3Œxy8<<zi/ū NYBTosxm>PCd(LYm ]"3h i{CV}E['pHb@턁 ݯDϽ槸ЌjRj`ZYmJ7\Z$垰i2H^$;\Љ |־jq ɼzϵ T1UE'(K3+tr?5%Dw"7}GŔr/iT}fuVtv{dHi{:P{4utJ&/s%Is2= -ZuVOnͺN16*U)A,<1ys+}VJokjHcmiK ɡx;s7ڪq02nk - I/'Ҩpۍ.y&(@{ha7[[*;vW^D\CG0)*w8!۾oIꨈtMH.`̪٦V7Gu@Җ5_{&u47%[B&YAk!yrqDٚe@^%XzTKBa?9 ',R4s_x{qI %rġqxʊxo,a[.\87YUf㛭EacЅ8V9YQgwH&k7ǑC9!MhF}m3BJQ"J%|e^זڷL+&%M{C쀚Ȼx6 E7ZGU6Ӕ0erpBqpႉ尻fAfٝtfWSMp/ی?`S%y_qei E7b)mn1G'ɚJ)>9<fb)YBz]q? ~ fr(FӽTCfXWx=s c#qsV,|C/RW76co{l~$auXh"܂=g {C}RרЭriI% VnnZa|2rE TZZr|(Ґ`E|93L1 -;Z0է2t?O徫r] -tLk+W吾8Ji]}swIw -^#*DL2xR[~햧%-/^ŇxC})uE^ƨG ʡ"r ( nKyj(53lK7Ab_$CNg*YFmr0 1I#H޳gńC6Q vd`2I=CyT#(^8Fs*V8PA ]4RStJ]fC:+F 1mfc?ߒÏ_~|"=#~$Ѿ]y v'SP}BSY'wYrw9L:sh!A7Xv9?NYM8G\Psd#?Ǵzܷ66$ -ә.E]oh`㾕QoS+_:n1iaau#WrhZvs*TK#6+"p olg|Oa|%`]or,ᐮy8p$k54Ê{n_>`w~與kSBFX-3aw}ri}+0z,{9rt-a/o?q,;g+dѣNES)gGx,Z8@{=> -;;; $!Sբvu\Z) -(R[Gݢ(8pKQOquzOj=[ukN@ $G0l{Z>lox%||⺯_+XKM,tT[I,s||gO0Q#㚮eOJrwg/6tPZf':0fYF/mr~¡MZ8Z~iwsV$kk9,,,lÐmev^4'$^=)R+ƻYcsUGV~_9wұک`꠸+zΎ lΛkzr.#w.[hPpraȠmn/u|ͬuN[p <\Oiqv𰓪H_|/>kpm5aclo12#S_0?<мتqjX'e][7lu!/8ٴT{s(+[,<] JߍyB}aEkԊʻkŽ5ɡYާj?tpyuDC_aC+8h'kV}Yix@I^l:0ӽb>+c~/IqS4[ri}fU^=4(!EOEcn,B.Q'^0d|XA69|اW.^Q-<ʍUpu]V&Ώ ]R۝_tvԎSۃG/0،XyןGȶnSnDP9y=؋}FsUQV||*Kg::E2rߥ]5O/."EvFMYt{cޝ״f93{zElƮ.ު#o{wMPSvy ,MC'%rLU7lg}9$6ݷ"Ok7W|g|Kbh|t"Ǝ]X_n͕i۪ϡiN5_ucיQCi*;¾$xĉ{ j7`ml҃8z^*+G  -rkt^z/z9 luol]lF*܊br껥:(@szoXWR!<z|.cuU^ڴO2nAfT}Gk풝oޱ!ط!sg@Sbʯy/>r< v-~"Wscs:! ''?63__Æ[KטsɷV94|V\[X}^ZJo-Rӗm-|=t{_H}~FJzߏ].qvT8>ґ4eS|uߌAS>kVmfj}TK_a:,׫f44wٻ[>7-%!U 2x̀Y6 ƪU?II%PZ2]L<6e7ZgmU?QV!Vo:'5%[^˩M5X%/sOHzL|JU>ҟawJ/8az2FUyX2@>];2u&zʴ_k8aT1Vo)}oߙ]>Mwo.ijPRz v Բׯ1=?}1HPo!C#G7 2 XK!w@ 9@!BrC !=Ρ*ضm[6<~w94>Rǎ̷ }nZT=y^ -6 -$~$mW*(E٩)7nޮ_?&cCX<@iW2v~]gݍCIuj,c<;jw%~.׊{͚=IMF/~'ܦ2o?^[dnWo}y]rQ)|ZFFgPz(<7_qrةS'?t:ݤ}Q˖-]]]+ޜB^H.}yO޶KLT䤥8\R`ӨFaЛ2䧧jMWy.;>ݹZMTL}^z ޭiͳuW.e~sgk<߷Ov?H:y¶IEv޵ou/;2c+yI$SӹS,ϽYt4A]B .у7ԍ\Zj -]q6mw%Kx޺ƹiS #-KlcЗ7ASηs(}7CqvZjݾܧJrXa n,C -?GLho~EV\w^wFe,~/zoLSUQgq3]\Ԑ}(W>"_]|ֽaΝ-4~4XĽ{6iǧ953wwIxFv:K~tuکˁg?pƻC] -pl_^GQS>>}@37+;bAQ;^ОZkTgm_׭רA)>>3(l=8wLjs۬I*~:łQos*Go|8]nFB{auX׶Ĵq-.Ȑ&׷ֵzɾyCuRkn'n0i_'Z`ηshmc=iI-|jnܰ2᫘Ccl`^p6_{yץy5x~SgmnBVGe:z׃7=s"M_psN;A:5|uX/Xsʡk절w-:_]^Z,zLqq}7nW0uܓ>^eq[6t<sڱ:Ͼʓ,rrLҢCj%'˷-Ấ.ֿ ZIx?lnOX"&mӏ˟f~S10vrOkg;o^ޙ66 UMR!Ý?} Kfu͹|Dfn]xAd5Wl7ۖ#\"+yzE^Fw{}ʖj6[kh9lqvT 7-{YL !*W2>kFs"jWޜ?l<1sfhʍT׷Ŋ -#<>lu=r}όęmJlg?RmDتVr]ʻ#_M~e=TED$ozJrX.]t|AFԩS)5=w@PcIWNt&o"^q@=1*O +=k۹߷򋪇Z tThS$}q#̶>՜fw'Xu}=x 4ߌ>汻׶- UI*~:>9=xAM|.g<JrhJJBu_c<.Е׶5ͿiNGU1C7?\֭?x=)Ccxg"oKXowrrU]ةk7}͝UsVCiO\c,a3÷rhJ<%4dwUGz~o9kTf돈L-Wz>mVcl@S(c OgĶ(CS.=ޭ۟(zu,jߢ\A;mugix+mٽ]Jf=Ts'\OȦNll>E^Xq-ewVC#V2.~|:R7w8X0$e} /[䰲#q~Yȝ29u{ aqׯngcä!qmD6w2P}ںo=zUk J;Yڜ/kǑkTޒkʌfNWÈ'G;o|8jw|'\Xhv9?ylAR^79Y7=>'ұ_R$Mپh@.cM߫}b͞=50JS;|(M^. zР=YObZ&Zsm4zN]?ũ vVmt+7慊3ZзEB,~,Evg糋lݲe_QV||*KgEҥ'W̡tN1hhH̒qMSW;7(lk56ah[MRfg)a#]*4\e|tMy?a:b_O)~(d $Nܚ㯺vձ̨p#VeڝJׇّĦPdY]|-КNi޼9MIW÷t(Ms~ɏ͌b-r(UOȡKeM$Cl_R̛+QwЦZG//_DVwk䊷W{@tvCq"[7oo]>)&|=jM]Mb|z=#MC Lgej5'4 2L'$zo5%ڬO[] ڼQlW˧XKXRz|&Jj)r9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!R.{077sx}%e} -endstream -endobj -216 0 obj -<>>> -stream -x+T03T0A(˥d^U`bjhgb7161Գ44CC3cb |@ \' -endstream -endobj -217 0 obj -<> -stream -xڭXmo6_!,&57GVbZt`٧@ݑ'A%{OH8ĚEۇdW")6:q&2Y$K2I_tmպ]XʬHUw(c*~!tS8$˼tO ˌMyT|HgU -^uzuMSIhsIYN4ɟBӚ CwuP5Ӻ]Wp]k_o6r?p%LdKT.̀X_'$В왧/uX/l N̪uÖj )I7U$kb\~"|oeMC8_l -Ê9uiZzzlp&KbFI4^W&YbP-!?VCٴl7I_ͬF!{<=p#1թC2DL0Ty33 ͉5؞7G;ciC+Q ZE&1*Uׄk??V3CJ]\ZOwpM\ZR2ЈlTR/S*:T}d@mrFex h!T@|s~y?yigejz -BG {}{Cd d H̷ؓ^?z=flR䙤%;R=蒩>WI<~š/JW~_URi^Aq*VeΙP3.Ҍs|{uOu]CQSD.AcpŐ9e!tn=9I+a/>= t:@:P[8tQЁcwpAFb)RHYaPҰv~^Ы}wϺv4/ @32}|l=5\2qà}t8U_ߴ_N!^a #Ֆ~۹K  0\[9ݡ!Gøn_cjoGy7N0` -8̢bh/D4di. !" ʅ6ۖ4zXd@DjL8Ye/ǵx91ܴ&D mLO NN];K+3:܉2 -ܑ20#* Ipk\, -!Mu]p5>+p<H!gnK@,x>/Length 28112>> -stream -x\K!0CX -N@;ZuQjd),8P[lZպ[V'! $g0B" >ϧ{y/0 :[O841mz~w '9>w!轔ti&Gj*9b8̬x2; ?zC;)hc>)crԴ txXj=mӑ֗ \wj*4qxpW7ВC8e^%QVz5ڬʹGFAMFva>5~Ub' jsͼ_A%w -5szFFV.z5jԈW4?!lqSII,^9J_ a;S!޽z\IE?8e~'O[_kY a=/fX8?u᤾*9ytgN>J/]%N4?{ qz'QLJb7CKHxjhc%w>֎uަ(|ށz8%<2Lhyb8dÆ$/?Ht\DMOꭠQJFj*Sstk< ܴP@^q2Jݯ(r;Mo1nUi KBѐ2aĭ&|(&5+&|Ie$ˈVjc=޽ȓ85wYu2yS"Hm=C) 6i?`f Qg͡8yIԞ%NN 1v{Pji}ڈĚQ9uvc[~hd- Z$~č" {?h[WkwOP\oA!A:ػ+؟:. D;}[z8$> v7(<(Ndwn[ dްxߌx#ǁ~F?>ZdhT`]-:2i摪 gjy 1ed޹soi\kw񤅺H_.;r'تz0rMΫ0K'^i't)Kr8\H%H,+OoKBݏJ+,q؈b-i8dj4ߚ(w8lؚ5Y&84@ǧ+nC68lk\l8X#s-cNF >.]^ڴ/U%sCЦ9Yă)w}mן,(:Yv2)/,{!&mWDuS>=*ҊqAkKJGUDA"ubanIsE_3>>+P bM( -U s|)Giv _2Iv_<%잯8[j4'jy(8nsYۥ&U}e|xۮ84ײ|Y*` q<[ꐊÉjbroA+0 >UUj7r'?_eƬ/fo%// ]܇XFtC$84'KЯoX5lG&oY>F[jd920fBO+.>Ѐ2ei_GʵC6#/R$ -2%{ .O%QsP-(3ƬEU#TeN:[iК -IQVLq| }hfAN>.C-9bagվh:_evI6!8Rp+~%dwrQ!Ho՟^hI` uI I/\^F[KIg#LFӈ=\+hm -Lre, 6́ b,8-酢a5[^fZơ4u2~Kb[ Cw"Bd4D0c1-J3RUz(8L'7-GZԂ({Kfk%W8o׿zޫ&k3FmM4(#RTmLlOKx2׼uvkl,(-~QРjWFc`:M1nWo~-K"y*:.s2.m5MB{`m(N+cbJTm&GQm)Xrt)FJUM{}qGA;';޵ A>/i:KʌS./:j0=HѓklH#֍ڲ9^H_qŀMv<V\ّq9q27Q=HѓklZ0uQ:qݻQPVZACiwi +{'!!ȧٖOf !{'!!ȧٖOf q_w˫=Hѓk^l˧X3b=Hѓk^l˧X3b=Hѓk^l˧X3bqŋ] ҍq- f޼84_qsq@q q q q 8( x'.s#4pAʄX.a/qJ**Z@CFwNwf~g! -iT=L=O#. avoKUa>%\权!V.M>ilef|H^fyh_Z\V%b#xyUA#βtΕvnО#k :ձ} 4F_k,eԓT 43Bskէ`psły6=Q#'\u<_͙fDB*q:0q%ng1V Cl=Qy&K+WnQ%SSRHC^iQqukҗOUGxUSٜVVp맀w垖Cه[$v|q,7cmdB/G*Yڋq>˜~f*9rp -‚P VoOuat}":RQ-ޗxADl!{F(ܻ뭇_< 2:١n^}jNa*̷9~3yјuKB -5[r,#6YOY' Nn\5ApTV"XM.犹͚}$y~Ǐ觅{2=!2uuX/y6ed!S6=4䅛EqxЬ4jÇkE{_BF~M me(ͳmaVr)#z$u\V]z]S<{6Rq(4>ߐߞJ 2Kl+RNoZ~sYE5;C~ -8GGQQwCz믪 -&1nFTb<KE._`t: Z>D/{}2[iP&$ZuV\)Ij5 )3jT*Ƈlw6OHM\j(/sve)BPj;zVyhM9;|)`+z/#GQW$|IšUieʷS|ǫuw̠g,ī*pZn.3UQ338D~j 7f0'|s]W5IF շЍzK8 @ @ @ ]=E~̻34Aq@ƏCIww q85jTK8jCE P"C>S #ya/[~icu wo=4i\2ˊJUԹX V#n !96;'+lU>mkwhG).#:Dh< }w/l tc-DuaD -#EHfJ[%Ƈ ZC[Y\Rңz9q8hРgϞ5iax1ƭ.-a)uㄡ(O@XtZ%[Gz"&=9JLMWGPC9%x-n}ڗ?H3Yy2DSHw[i>F1T,ku[X $J+ -3B2"<7]ը(/ejGC~4&' qN}ryUn¿p$Ùv OQў;>_ONJR|>psD@}B9]3$qqhcz]jz|$nJƊz'VX[Sv%7[0FV约&j*]YZ wA*NjzQrbf"~wq!~5q)ƩVarN:@$Y("J:f$ϭ\\D"pϻv{8OjtM -P(.\V?Xs?tC8yԝ)& -Oگ~5ϔӵ&s_'`S0nZ`2jF;f,)kri6h⟥Euڊ%-:=_Jd9qɌúh+g;PF ~â}2(᛼ 8ު@Z%pRCFjSulCA>`U/?UCʱje{1X$ؙZtyʿ\lb$LhHǔ(A&1نGN Wۼ"nZD蔊K}IAnQco#wLnibw\d4O.}Qhzk֡<8d!͋|"NVaE~vQ2zP82dpkb~qh:#k&*>ds`jL\mHafې#z,59^!Cb[w~j㖵T֎b:e4_Xqvqڜk=Z͆8 @>8kP;TAl.5VKU|MZd O^qļd8D -b9Eh^/Z[TO0Dd=_zO;v -=U6eh>> ]FĖdg_K'KnO'Kg$7l {7hظPf«Z*vGJ *i +;伓Q}ic.-Hdh@^L_~ytt=wln^^Gw7]L_櫮*+(x7X$ _KNoXQ(aP2d䪿QC`( >8l'CҤj)dcӋxjzeٿ8U%U =J+nnM<Qf9S֦j)ZN6sޢ -"nWxp>= Zy"6Y˵z~U)Mҡ2|۵rO`di(|K@ZV,Dw@qgorDY@лA|FCi- !o!q%S״]8 C8C8 -hZ8@|I) -o -o!HCo@Ku2pРAϞ=kӌ$c9ƭ.-a)u(O@XtZ%*w%:EJSMzre% ->SÇrJ*ZTu"9վ GUc!:$FےHdDlFV"Ge% CR*8lȎC& )4~ro4-:(dNLqBєD4h)osT#my~Yd8s)<ڳ2c##XQnQO(kz:.0M}LCY T-C9W3Ci8XwXjkkα䆔Y뚚wsW=$M׊ -X9B/(Ư0kB]~edaTՋ{$o6SW'qe"φ8I\]RTQ tKdLeZ|$1 ED5C̀$[<ߣn28T1PXˏF$hhrl(D/.^*d0V~;-v3]l/%15Ap41%a3{my|r+EN8ԗO -ҍuGL4T}Ԙ,2-a ! GÃ$hY@=krBX22-kө/S/8,$~cks~ H@jaN43!C.'> K*Ǟ\g\#cC8+P;TAl6(&7qs)~IC+#!6,H]A509s$N$U95Mux.GmcǾ8o\fi*atTHMcFȷhoyw}xA& +-ɂ?-,8/xhԲԨZx8^-aF*LUgYѴo[-E x4@PAK;Yޗ8V2ڂ ɯHdUuAgGoJ'z٢qa ՐPV]Cih`*9|ZeEѡI'n ' FdZ:]pxC׵V*B!?-!?0-kN˜]Й>8l'CҤj)ܟǦ(ʭ 8U%U =J+pnM<Qf9S֦j)^ʢ .m(0SV1D.hI 9A";iNٚ}W"eOWG0hUشW8vd^ǿ%w?RկeD6N9O_+^|F0(;-xBgdD|wPK@ZV,Dw@qgorDY@лA|FCi- !o!q%S״8 C8Cq] Њ?n*)p%#`2D8Y -@q q q q ]hlKy&c .ګP?7#փ'p-NP^KQ!8">~ v] 80?֐0Q(D~oՙ9N70uj|Vݸ83g0,H?LG]t8١8X(f qV N$RtUKyjTm%P¸JLMqKKD -E8U4L EB SճTAIg#qܷoV& eKu/|iXUےH.TItqK~v_+l="_a 7T/i2㰕窫pD{(E -]G;P6-ĠTG 5W gni$M׊ -X9B4PPN Xxq\%#5F^~9:zWO.aYՇ-9c_Kz}|v5o0c=}SygeGדG%Ԧ2s]S5{<$Jg7ka9ڼH['SǫIꤛ&/q[k|(gϚzbjfvY3g+šv蛛a[^'3oI p$ۻܷ?~`6IFi+uxVy|نV +.xL|1}q}iD$1E[1i. Τ}Gsǒ8N%R\ŬBcbgKKrOuʹ-,X"fii81}p ի,>}zySWdi#~ZGt o;[L"W51#њ;ݺt68 a˗24q܄%+~4 ?,X~dDCڇlLM@$jC%q3ZLm^[ԃO4[֚.iӦ5^6m4a4׮_8,upMw {]p+#!֟,t}axq(NFTCOO.A9xܞR+1eE_bzqh˸˕/Qa}&.v.Wuv5iqs5$BmcǾEi%-aP#uSt>o0㌌尤>;T`4\uUN"pP4'iP0|jH(z@GPvGJ *i B[7Z16.(t?^+k/ˍWpGb<]РqjM0㦽 ]Ѵo[=̣]Mn^nq(bބ,)- ܳnRTq1,ۻ窋p)6j8[ݸy_eZR/TW4(5&U3^m%VutՈM/.ҤJj5e -Z.+ir޿i{uQN40 -<Ą)"n߆/i];Kq q q q q q eq8o<ɢ[b8M<=@;CQD[d@}RuX.L5QWx~í)~CQ(->ĝCda]gSbl U-U$>K"G>\p89sdž!N(Qs꟭š}r?*7d~X;(amRPi<-:v61Kc&kԱ;.;Ug6yHXpceǍds`jL\m̓Qn9S6?YBll8J]ӦMk<Q]p.EYB NUIqACxA:ZSZ\!iR?VhYGW)m2;M/.5k[k*h6Ev+tQN4QRѕ#E%m |g)w @ @ @ @ @ @,͛'5Yt_ ' "r^»Q{BBz-IK_G@80莿0>~oՙ9N70uYqsqB>Eyx¢*]U9%<5j;c\FYI%؇øե%L"Nllb*&em")%?/~`0*XT Nvyi6_'2hle93fY #lH 'W⵨Mwj9t%v c@@tUΞb_\A2b˗hG*fch -M;-5S{Z]+Gڂ#r隞a_ /dȫ2u=G_A -%1!%_Qm^ۓ՚w13鎋䔢 -MnG]זM%¯0kB]~e`:^Zr览IH^zN{O uMMTlz7gpY'!ffG5s(/_ZZm?lg5u"x:1q M}h*;@9nTQZ+=z&[|c|Y˓Vb8Ssꮳ)IʔYn_]);'l|0*T9 5oR|"xR~ky dKL5QWx~í)~&U?Kh Cyn˒"&#խ6>C]3' yc6d? g̜!JH\gkqhr܏J"* fh* -wH96QE*o;٥DOR?;j%15X3f -BXˏF$T2MSrZC5-Pt\5V=iOV3EtX =vecS589&q6(ǔ(~!u!r\[Ԝqz3Eq8c ϫWY8}W^mF8r99Z@v 5\E4kbG£5Ywݻulq@–/UeLi|ڼ([,m%-wmBBXOvԯ*ێÆ&37؆,81?-fH9I)Zi |(MW]6u0kׯ@ -NT:;U.dGO~rt0pG 8C8C8C8C8C8C8C8C8C8C8!E18<kc΍J)ڞt!#;;U@*zSl6n6S˞]_9ee ~ -mOKMi13rםLXj(<#&G b/ՉRMc)PCkʊ+::Da6,ϫXd"(-.g㕵t4mQu<f~g%:`,,9u }֞JZbȺ,~\-ʓ/KԟyҘX*{"|SOOAD]솱~t{MrFUM-fs6Zm{NYzM0cw[xσ,e鍃I]b١Vu^Y}zgL6,պ[!J8YYxR4^pRTB2[u>Lg0ۜ{0TV bH}vﵣ~ E+ @oqC`=;b,PyTx29j,TJ3yq<`ݯa(tE,-p[\ #z$5>._?t: Z>+=voںDY Z SBh{:ʤUu4d^ޕҫ8rduHB 8 @ @ / =qĉrrrZ׀t3}8/}8! x<˗ǍЮ/FBz-IK_H:N[$,4ܤZp]=S}e2 d] l^#ơh/O?h{vS:3/0!oH `f 0LP̜mkwh2|x 3B8x 7-M[. ^ئ:ZHEaˆFXN`qpΜ9\tѹK.5JMMsK~v_+l="_a 7TIPo,K0cT⵨/ݖD%%#x'aiDphGƸJLM3;|nÏC]0c5x>SWxq\%#5F^~9:ti(ue!{O uMMTn¿p$Ùv~W6">jz]9J tM0/U:q%m*ѣv6q%gW1Y_w/Pzo5eXrYR%xRoInL{ )t s3L ܴK:c~[_n "vt^;Em?t-1zrsً O r#nys$ѯ^^^ Ϝ9#O]6?޶d%Pw͒M ೴ֆ; 7 /2԰<5'֐gUvFEnh<ּ3 -i{vAa; ˦K.Ư===_8x`Ɛz8{a C~EͼE1WҵKqVӣ6T'Х9"sN7Vk|S_!]^蓧Ntpgq.>+e]~û>+v")P<-P7wWd.ALkkgԲn˖? +I;Ê %9;+;Kl:w\ڿ>|“A;FnnSs'бMW907[>tibyoS!+⮦? 􏙱'ͅ;9Tqͩ"9k۞["A sX/i<}ÔNu-R=Z7V?ɺt<38;ge쌌OC NUeS:k%~vN<4o; _i$U/ob"'D+Pr6Cl̖up -1I -QѤŞh֪UڛZ"o^¹ӯϊ.=!i-gG*.Shذaٷ`xⷷhʻH YO6?OuXnZigT+#z%[8ws9qN >knzy%T$ԩuG)h1p4敉sȡ./=%FܤAd_ 4 )Vu\k[܄xu׆+k3b?kՇMPT./ox67LxFP7751If˄rHuuu&Ds3n蟉~o/~=moT=B_AW]i:=jK[jydRzy^}=;5:׷E|;xbOC+%s]=n^zdk*mzMZg߫p_I)SǤ꬛u!?*?}[ZT ;-\8Q{+Ük}{VMjnFo֧iۻW_k(jUm}w;0~X_k9l9|?]|"~j}b[r\~ရK/|\&L ^rʐC+~^|cN?--E}[\^57zt^_=6DogF -rslܵ켌+7mQS?YqբN~E =Z 5ۼLCO]0{紖_aך6>㪎ᯅ)Dlm2x)Ci9H{|:8!L~Ʒ#zyBtqTRD%s7|uFgb^۫g)/[։&Ezd}!?ֹEXŴ\F#wԲؖst7˪Ҥ_;yZ[bWXTKi~Z6oRՆڸ=fDr+od$Ƨթ[۪K17 3'I;n`^ o~[ǦțY7M:Y(ߗ.fBѭ_?39>)Ɇ7%mVu.)">;5ZPs_ޢY_ 9 P%/رY0M faL=t7[ڵI>%:N~W:t,Vk3U\ݜJM)?~{Ry>մ ֯c*-GhڊWȽ<0UqJ~sKꂁu2u'NiݶV齩egUo\?Ux{?Q3UCUR94.SSS:_h4/ g,$ٵIq%wm:vW*MF$u}>g˼ [^]k:}]<:u{i]F>.2q+hRN3b66NSf>L59O̚;]c^| lط}g&u|G>xTWdz2cO=ZdUuj AK?2}RҏݮR\]}֤sح[7js_|EvJ?qy; &)IjZ4"?.1CMUrNml2\:;!U{f$hn_YњLԩӓRuu]z&~7[ۭ>z89Q=oNkfA/1 oaU:ygɐÁ>E#}mC -~ N}zBKT.93V9wM68wϚ¯nni7Gd%'Z٘] "}=ڤݾf;Gaa:SHik5FU}{ċ-] A!Cmh_S^'wIkiN -CǬUP{~ԦMgϞ?K/?unnn}{֯KfG.h_p_o\cNMc'-i%&ҍVoLoy4Pr3՗F^.-s/]-l$NߝX֯,\:Q;]yL>:7e3cmJI~E&4 Fm͝ݺs7uq&d̚gn=m/[~Ѥyug -/_:uHH/ծYi*zyH-_?nŮ-Drxgf9wz7W-WaaenڲI>9<Ȟ1#z]6좺[wfiM Wrv^7r3,$?\m5 -M}g%NgI+9&_!?z7[u ܴDeSؼv 0fVyE&\ ;:jzv) -/YYNsv.{+?΍ I[wp%$}wHbx:=Re:S -Zi-)]S?t -u9.AiDt-Q^'&' TYRNYņN¬zsإKמ/bcc_lLȉ.u^t/Zi7;w._>\SX7?fƞ~]>tibyoVE(kQ'^czK+m _vi6_55āk_۲>G9|*y੹L&+^ uyggz!w np\q?MXUò,s ?zo^T8qδvq3۲ӕ5 -[ttXt`kfF6p[8ͣ~{'aK2O\,Ni(Y1);s3'7"QMzI%oD1hw/UՙJ/9 !բCWʎUGePOsgǪNkj8Ssxg!zsX 蚴sZ3t_{AK݋ܸ'3e]"T$Ͱ{Eڒrdv wbXs6Iae,g> -N\ taY+WIڏ|f^H/.|Q vA-p<3kЪgCB^qĹr١.#f9E|ozoX+'KǼ-Waс-~Tq}uw9 yVD,C5V:ѣڰ V>*-hw/UՙRakХG*Uz]aXd泲ƍ/ߥp -F3UfNY'Y+E5PV=zSN9rãaÆe|{NI%]fojxɈ&:aE;[u>ñ3w*vwR̹=dUurXZ3tY -#_C,2H^CSʻ~wqΡީŹbCxaJQo9vX_i2S2tnu wqgYWZzb|[;d%^\Ŷ̽./-!>MT7ZƷ~`Gm0;9>IPۭFRsM;>og{ʾ4 7j~sGFy`0kڜqRT)*2cW}a֑z]{ɪZķXæS%w2b*I~Ydh4ƣCJU։2iҢwm:uWC~ב:W>>> -stream -x+T03T0A(˥d^U`bjhgb7161Գ44CC3cb |@ \' -endstream -endobj -226 0 obj -<> -stream -xXM6 WMgb!Q<Җl3EǢMOL'+:;"%$M>'4&%PTKw4QD"q%T$9Mܟr[jrrj{B[t{wbt3x42R̓u |ק2Ή*I|x2gd-rZ VtYxv7m#Ξ8rZOo/M}p{ơѥtFCLTSm !L]}h1^H.\DC -R>ϻOYR3ξ$yA_A`qZDi1%9dA*y Tdoldxبq0d3z2' PIǀF-<p8_ ` g:}1$4xyJǭp0|r-q,4|K~|}Lѳэ5Iý3[lOL/0Q/ N=+$kT*ecES{=zEz3+R:Znm]jI] v$l&cz!>Xx ѥhs3MZ[`n[]GZ=Ƒkgn8\ \Fve '~SScE&S4ix*?{q!\ʴ qJ"4(^QId]:v|UfޜN+ l,k}/R6tfKń=6qcZw( -0.I" J$- -(Q,H~)"B$gx"ҫa:Ldbc?LBIUjr[&l!=--4'4!h|-N@yFGk1+39r֞#, -+YG=_|g!̜*O7@%@l<+(iza105 $"ʡaZ|6) d:Wns; Qze_` -"Me9Uthm!>}_#;|f`,K}om5}5l̋k|CNθ{Y9< -BxDDȮ\HڍBch56YcV>гv5|9]~ [~C}ҎT/y(8d PEAm;fA(%Rl62黇*ưiBn백8vɭgnMiFֺ?Ц6xc;J 80Ah=YYB~pҷ#GdTǬXxA'04e`^̝ -endstream -endobj -232 0 obj -<>/Length 51544>> -stream -x\/a-Ѫ WjTp['C "C\ -"KEպATj+d_, Әw}y}D"!`hߣqkeona0-:@! H>g -XY^~z~?}~ ZZ3߀8 e]EH^7+Wo]XU1 ^NvfzC@8d [[,D$aD'Ϙ6|(\_NjV~ RCϊڦAl/ ˽qyeǫeC Vr_-'9,̫<Ϟ=/~TUQ0a|ZzF{CZs3q &9!H`4u/yYEȐɺKNi͡_UO8TN6Ls̙ fi\Pjp3~yWXQ0@w@'Ͽ3g{ xE ufٟe!pqhbNEcHZ5.%&E,גH3E;9SMY-sbi V絼*50iD1/صDdg)C@8r891RNs#)]ݩhnIk|mךfzl]Q6%! J[^W鯆MMk^ͧ)NQ&:3̳Ǐ3πj5V /_2 ҿoq8.wBHD+s=~*?{ {^PϜ=z({yNWHL5tWUY^ -!pRC8C@ !D77vIzOKvzW?vzQ11C2} 2-͞=K ܻwo޼y] -^%=|%egP^^K\_"|͏8E߽T}<)z]=l""ex aK { umB!`n 1- ""e7AU|*IWdjBO_E5X# yl""exLq0WfԬiرRx9꿿 >|.Eڍk;jJ7 Eh0ᒭ"d':rCIJ5ݷBK4CGS_oT.Fk|? (CwS)WWJi @Yzvn0à&0)5j\'3vTˬ3 -"O -9:U$8(1FOm? vp\@p&)5u%N")An$|ײzq55E y/jrR/e$U5%)fr45?9GKl#ˈ_z&qG,5~]1Zj"J]ocX9#!HStH>,W{ Kʫp?YKIt2 :P=WՇ"JVGGRmQbﴁ`햟:y2NacwJT -mI9(3PbqʫɈ?.i# ׃Ŵ,l ) <"-kSSSbrJȋ2dacᩭa_WiwY$vsG®Ҩ!|`i̗P[])cA?   = ?m9Tb2ܔCswM.GiNAٽh Aja3p< ϳA*"qȰIOEËM Re9}'I)L7;-6ةܑ^"6|KQN4@L -.RSM^CHmg|0jx{ΞY~|)+/׏FҜn-x~ЖS޾%5W},&!TSaEy$~KM"Ķ8x36gը |M:LVGO·]52}NXZgqbh1V Mjb.gqH"4Rd'!^qK>]NZN8c3qhFWv˼vK6fB&QHtM]`$6|~Ey({z1 R&"FTv𰁒DKqGb{U;_<|l}-RȹmH[" sŮE453w$"gsïGNȳj {LS=jb,qHcnaңV+]{c Ql`-h}!4ʯ9b;\UiK浉W=oÚPI{ۯQ{9cZV".[JUl2eطĚ۶_mISIrhO>OL`EL}@p%lI\z{-CYLLC.yv?n<6SXANIi-gӒݑ&'82)7_zY*?W7dOz4 !ؘ?I EŒ1*ﰉ-liaՏVӟ?$˴_#8ؙ:{j3Κ6m֜_Jtk[9i˞z~yEæTGگ5?5S]k]5D.&^fX9uÏ)OsjQ~JJ\eKb̄9I -B#5k1UnoʖԞ0~V* /1uR]坕LճؐX|g)?[Şc98dZېeMfWJU6)N馱<[BZ%)C1.l9ný'-t8! !G{sd8svw.i.9gx٬)>[f;ۜ#|~\oᘽ#8D+bb6?F,$1fcqhֿyMעqXjWgw8ُ?#5{ݓ1ݍ6poC쳽R6ocQ0Hc ݋Vu=j2! ;l!1(q7-q[6pi!KT -ZڍCsqhX,]tI=¸O NJgS0Uw h,eH,u: eO^@ 뛮9یb?'[Y]%~$:8\>Qz;"lb]q m(J"?7zk,~+?P!4?lOx8$~t9^xW>pb Q\ѕ#aY@_<[*mbS~hᗐ?HI iҍ^g(oE}O2K||KW3\q؍Áb%%VǟbW7l 暚!f<%V IXcs_ӟ܍Nd?rk, -VRb˒,ӖG oQ0oou 튜qb) wM 2PA*m75KncnZ)jcq=Uʨ9EH\;w]tqt -q:IV:{ 5%oƋqbۭ42/]=L<~xI\sv?0AxCOn\p^^;NK -{vOۿ= [ -CxvAX)zrC/}2aB48w+P.kHab=8킰׵S͆ -Xf@ⰷ š^FO!4bqRrrrSN킰׵S͆ -Xf@ⰷ š^FO!4bqR.kz]=l""exLK޸~K8">/nþ6 !@! @q! pbbb*0@!@q! @q! @q!3$%% TRRz,z -CU[U"7ۛ `Ѓ@\Yx|&1ξ)))4X t -Y 2f̘'?< G_U5m R ->@/0,qq! W^u|S'^!4~̃R8C@ 8C@XKpT@0g7_6i<%՛7+۶'!%up X]F.B/^as!n` {6_9g2@ڷ UFҐv! % &_˞143 /j5YuZ+ẫ5+tG\wfc~nZrCDM-3rY5Փ7OXk qH|XgqH=zCA5Bd]uR)_J<~{>/,7TGćXx"щ6}Rq/G@nz-w.>*'mn޶SQ8NX9㭿0.eBMeq>$[C½w洞^ShN6S؛!27r?+F/VŭhZM"_" t[ʨYV{vYHz\L0TmƗF^:lsEG@C':ʃ2ӾW}B7LI1k߰.Ab˥$b8*]~$ VT)/,lV}s,]jb:jbkuYP'={w%jyVMy=%M -Z}N)q4_n`TG lCaN^K_zcʮ$Tm2Y<{Wf7jnL*eL"b"~:<'^L9qW+f8Sju."[,?ٴ|Km]>*uS%?[Εzūs2ZG~8O֬ 5}K\]!mURiݵql+a䈥o;$qC@ӥĥn+_韹Ƀi hsȫhnMS8SQ*#Mu*Y!<[/*>I^} Rpa,Զ,i^+g\kz[_TZiYIqY3zxyG×Vߺ8$U?r\N7l=j__NXi -"r -d8? rlg#攔5_n(Ҽ0A!o2뇿HkEʠ+'nZbkU2?cկB[qbh8gL= }URiqogM -HBvQz}|jݘ 4X4sB` -%9xhĽX!<[.G{¾i6CzX95$`%Q0qoND_)i{%K=\+91I(uaEKωcDEҝr}ZO;c"ϩV*o> [Z,aW.};oC;ύ+/J|F'~ӋAث~8CtM'L^]u#80Pjb=s/Ȑ\h$6wP +v.0 \.6%ir53 _'wR/MMjm9]^s~v׆D܈~[.'.!֗ F*'y\;rVL 9+:l.0k /zA(/`K_O8AP뚚7G܏Uڳ1*Oz4sMTf77e*dsw^Wx-W]k巙xSN[i2ʍKӡ淥Lv{L? KzbU)b^WcXA%)ѷDt4D -}‹[d>uiyխ4\U7t|:f5ݧ`F[v=f |P4!6VX1b^j[f߼G/cլq+=߸~x=6ܫEj"7\m~r`P7J[.zs@o)w-LIn8l%<[Rhq963ץ8 ]6_vys&9χF B}櫉NIsUb/8fbV;[*7'JTyH`&}UKb-qWWLuJzu`ٺ}..%ŚNG ~mqryy$/.zpZ؄Xp8_ voha5]Ac+lfИI5&-=:/rz:<<4S Lܝ } C@>յ?U;_ RsSSW -@8BŜk fPk84B.^^;cM`Oʈ,S'fwqN͛l@P*jf.8\x1dCBH 2Ѩcى׮SK~@W4$."a*`7nv"bB.H*~nW߿v:% #R9|Vז%:D3ꂵu]mz5tˠHS5F\fO'} 㷃R邧ON1hQr{awբ" `Dq`D,b _[:1CL)329sn1L8lN3bz@m?q_HzMG2 שNA7bc6ZdGY\Pw?8IoUؙCԊpỵbv8%<' a'2KॻٌBRLkOF$ ^:LN=(; -GLVk8K(^CBSHt6.Mgx5m[*!y NXFOt F8x)m=DŌh脄30*:-=!gq_**j"HSq"$/f6p̮ʕiN-_O)#5şE*qh˃9L-␝ ٲ66̈}k*}vh%3|]gvz;31 n71褷r(xFC: elm3LcQOzBl@e?\A1  čaIӶ'?vUUDdD֓}5rX#ib%C}*X@k IϸI#nU0ĆîC-bg+cH.$~=.1PXҭ0/"ߊv3bں -rؐ= yjm9ӆSK+y4rrYEW:(AItpk b~xBEK\t1p>I~Av%iА~8n2 ժ3XH+fm.?8wGmq#^-UUnk-=jYB6wR5؟އx_6v㐏4@ÄO41)aCU+mҾ'=)`V -/5 I <9s]Fθ{w94ܽw8{jthR䙵EΦQEr܍M7hWO?7˳sc=~=WTyY$L 0!E.kKSc>FXmpz>~3bں -8 -_ݙ}=o-}wٙ!åŹT u>;KH3(7,<z'쒍m:֝dHЋ9>ӄ8L9s$t4l?SsNû;+xzzdC3AZo&_}N:Kq)\c -&NQeqo]>EHSD^3~9k%\9ļ͏O YLz+d9\s]܏_mۿ;dnj8)'Z pwTY){.A6oTElg:Q8#͠kCʨSTϪ [nk}krMKԈ=s:!wfJ/@+GV]I>#sBc;Wz_?oxzZFz^ZOI3g[C L94g͜"eۭ֔I~Ç`|݇qȎom -~q(`8B3b)p4?D !ۿ;d lZ'И% z'P88E\Pk84@'CNġ_fPk84BHk]qP K;r ;A3p! ->w! 4/^4:/ C~:C Haώ0:A!DK0 ' -/Bn!;fľuKLxp1f JR`ziF 8ۭC>  ZX]^9[F {yӝfEA^K@83gN[dݻsfϡv@{a}QGow,΍=Y2g- 0.E-:ftPY!3bںOЋt[틳;wӳ筥ndq\ѡF73MKpuȿA=!| ;Ko6Xx:n1VЮaqӍ%;gs@8#Ej z52sW?4֝y_J3~9k%JC?|+̓p%Zb~ۦ*8cFX[wTQk޹߻+.* 5ZB45ŽwwI |`!1MKpuȟi‹-Ȍ>r$XmWFU|V>gĝYj>PU?:Ȝx؎f^Og[OPo^]痭dzۭ݇Cv̈}k*vg!iځq8kO)SnM >wn!;fľuK=[|hTvcF[;UpnA3OBCv|Y -\P'Z|=ġqp -< 6S@3qtX)@8:  @ -!p -h 6S@3q(Pb7G6!MȢYlJ#!om{[OqrT@3p8\x1d$ y0C C:(ىÞaT'puމCH"ayC@7o@]S1tl!;fkU ~w=\D~I>^ZR,X_5®s('aW[|a < PܗYHA|۞{v-^ġ!;:dnjطV.TqT!,ZvP4R@6/@Zoy OvÇv1Yۯ5|ȏ]yp!ZjEH()LKIN3k,@ybcK-g}sRͲEӵqo8sXOEpkcFX[7U(g͝2WkiuMKzC['eWxFhU>4Sc+\q=0xv]l۲'4S:/.::!!! NKOHKdv%WLs:g{Lc^Kf>Dܗ -Th#F 0.fkbyN?6pQqYx0ixn_;dnjطwEp}mF7ҩKZX:/08ɩu`iyJ'`V&XFϷ9fSn~ewbҾլ %Kgj bZ|%"2)>$զuA1#0d_) k3>܂^KA?KZX:/08Iazi`&~g)-.X5NeDТ5Ǐ8&Y38ԟOPشisx 6ddd-Bi$>F2{cNV¶!aqhвfK ۨksj}(Cv̈}k* ayځ>/$3aC$pu_apNX3Եmqh9C&`PQMT?>q8gΜ6͸{w94ܽw.ow,b4ѡIg$:SXYX O-V\$]XG b" qȥk]Ut-\1x# *꺤%ۭC  [C_*ucsTYz>σ%[\bzNNlyvfHp)bmq7UͲFoPO!c}&H ˼pyW^#>U96V+NGW0qڧwij0bMv]u*CWY_bErVR,qp!;fāuS`Ŧ'8\GmKQӕ%JOK3 N2PU]QVeNE.S$?]{SmQcCq7Kji"g>@Ok-Ut nfzAEBOp̙(RmMݚDGA<|q}}3bںZbۭC> !0fk* ['Z!4f)'И% ^;`m|=ġ;8 BX)8:  @p -hD 84BX)8BZ O;K(TPMO{*@8Qi8$ф"[ylm ->4A3p8\x1d$ y0C C:(y=* Oj4$ H}o޸!9]g]2=W.Y~"Q+`:Y8fj]P`.'?b|'K\mfQp8\`}ɚmq_ m=u_ǡ!;p-UGjkb quzope@hiiSƷǤkx;_qZ); -%oV;s?Z0J -4~r3EѥY/qMD4CYUG,xAQ ^mmHG^IoiN!a'2Kॻٌy#!";;ܫڐ\vZ;fāuWGLVk8*$Z~ M"ڸ7w)}R*ƿЯV:HJr@AۭC> sRwgXiP$'F^LTv=0+q8"KѤ2o̮ʕiNLydoaNN iMqQdf+QviyJREm I Mʼnf|oC"'JɋaP1褷r(x-9H $&%ܾvȎom= -saUA!fM,m69nĴT=Cq_Uqj#z-I OۭC> sRP"mE”RĚ"I63+d5+5O+<]]TT]YzƝoueRle X( ÄSb,,ĆiSkHS1?XQ 7bÇaN\l7OKWc6wŁ2"f*YSfO!kcF[[KrϲLq>I~t`Zl,zU$ۇ[kIN -7Z|暥!&{qJ!̺m8ԟO=ddlڴ UܹsiM9##㋵4Lhbiva[EUcJd?FL&mqh֞2{cNV¶dV84><>./UY܊?7'.~ۼ+p!;fľ*.$8pEY!^ѫC%c!Z|e>kl蝄c~,¬+Cq8gΜ6͸{w94ܽwnow,΍ hm:AO:>=C/ncsTYz> uKIg$:[- 0.E-X^-6XUXzyM掔c{!cF[[O"A/&j:sg)s3-՘nthrtY_Ո^)f々 v[|Ewگ2w銴 S"FH>1+YWoPO!c}&H ˼M>VbΕ -/J#3!?4֝y_frH=c^4ʪ )hP\c -&NLq{+ Yu#>][6A1jG$bAoaR]'Cv̈k!UԈ=sPZlqbu KIbH.IDUt\LWj*NWE<8$dnەQ2tUVH3f]q|+nDet7{ϓȬf]Sikpj5ck-U_G nfJiΚ9Eʔ)[փ!cF[[TqCpuG+,B}3b"Pv4?D !D,ġk]'Z8ByPk84@'C @ -!)B!@ -!! -ŋ&S%aȃ"o\>\ÞaT;qH"?i捛=l|}rP]n!;օ8*?]N~:x u{RLGc)S~?I€1  QW߿TRoL:.9L,6B-xc*&yx|}48Q ّ9{vUe nGV*\{VIBe,kvszJ5gXa7&6k8O^ϰkݼmǖyEG"`|OX[G'$$d;UA!fM,m?dT]QEMZi*N4\ݜexv{u'V^}y1 rXByLzo,v4"Jɋ Slq-U Dz $Ha>RXSYd iCZ- \ ⃭R\u^׳?4Q-J ]9w ~rӌ!.8Yc}Zɟ .ih %8ԟO},̝M67w\ eddtqV oX{:Y [ybM Q85>th?\-n4,zl_;SXq-U41g4t^k44Me>WN>YZnz~x}Υf6B+^>ey'aUq4q!W7q_j!cHl)G=M )7ia%GR{'wR/MM$(4̙vqsh7{qxfKIg$:CSc>FXmpzo6Za:\X[Mu`:؉Cv8*^k*/Af#u`Kako6Xx:nMCFֽm/ZShJ3YhfJÛ?%bts,nə{4j;W{e|"neɉ2s7L)ۋC#͹k.V ;v Xm߶-qU F Ll~|r_b$bMv]u*CWYTr+Yu#Ixx%x9L:@|F۵C VLF_Wo0MIWx9~Q ^vb2a{%IAn.mʖ)#xLJs?F[ٟ7oc_ʏ_J0I<3N׸æ @ԍ ON J~Q\i'ac7Qyjvikf~uz`!Ho/VV~'`4\Aq8kOܡOED{C<|}qR߻UdO1ymv,BqN@px"@c B=O8B 8P8C  @qp -hD ,84BX)T`8|2 h MPtA/%A3p!tqH.+ qh:Uohx/fL!\qD}~!YQi@|B[ɁJ並@ i.ZSh ^Ryf.w[hj6v̨ F"nW߿v]!Y=vf} -)?!V=9zݨ ބq`D,5?=+֭[\k`q\;cz"w뎍?RCi߱;큫] Wf E#H0eYE'>A7bc6ZdGYd|[.s$咷ǹ7uD;@ eY'`/ݵf36q8"ccJ=15{A Um[.%oC"'JɋaE(bgw4<[.K :dnjط6fUh脄30\h]/qٕ4_2Aɏm3Lc)\,F/WU9~rp}~c 53˹}o5*$B(dK/Y$L 0)E),2P!Cv_uajDܗ -Th'aۭoNLzo,v4!ơ*V2\FHϸӮk7N!U޷Xul7OcNZaf;2,%v3bT*/OGW];︦'a%ஊPGUdD0d˞, -*Dv"(hmUցb =f$ !1OsCs9::TAk<,~wcҬ.q?A ^SiѶqEnzj}WNfSoӭbpVC*g[3j]~0|4m§;9Iŕ HbG]ģNhzv2u|."ARwfLnI<WPG[2PwWr:㇌X,c= &8B[p"B*J[[* N5 qH5p{w4+g?CL{>f8W%2VCK;#[=2.Au< 3؇uӐC/MZ8Da yơV@_6RG?5^|ywK 1= hC!9;ft(1BN|k -KZXPŀޖ9I?_,zct@#gDk.~"q$/tOpzw5s\i:]^uYZFdkN9A"]\TIf3Ĉ͝,qp755j2Ak'R'\Wqe4)d|_ab8|u=qܴIt~=bL_ƃ.Ijׄ~WSi8:cF,X; Ox -#tVMg?`TQ$W'\d?{FLK:1[Ηpz75*2&*`G >d Y -Кqȇ-< qȇqȇSھOfa`X!e@" ,@d]8 efN@* 0~x.!pjnذm!|y b!t" Gq8p]!^#hsyU$m"a!e!Òqכ3)ricg$JPLᇟMBlxxdAĖ*\CBϙ#ܔIq'F#qe߻j3Q6C -nD^~FMbX[8\v-"k!og`_o9~vWk Gr1t)K:24.TJ.PqO{fVe8 -q8lqdq8DCdPCKRS'h@ۃ0T]NldQ1*78tPσ''BB+zJI.%XaOlqrk!fsRwWK&&o̵v,TNi7Vמ؃NJTF7sE]5K6<|XCN 0qȖ%2S7gp B}5"gilYbĖڷ*28l#̤ IF|HTP@t暻քؾpCc)4yŜPa)"¿`4IG˂oWP$V2J5uuutuFBrůSk7\BgL) ,䑤]X4+aNG-ᷣo -)ium}sDwn -l5*jt`mrX$ٓTNoAS^᧤Š$_K$D6i?2 +W[s mZ7Y]j$J`jWQ^ۓcjf_:EDtN8dI}c0 =|; nU@})g[3j]~0|)ei§;9Iŕ HbG]ģNh8l,S*%s̘ܘP[e}CtT8֡  ....$kkkC~|~R\vV&vj4XÜwz@~Cc?{8 fI8l1.jF&Nġ#9/П<6=[M`=& 6Pý:Om t(<[Jԃb( f?D3Tuڟ7/*T?tɌ|N 0qȖ0?FcCz'\qiGtdGe2aF~nr(Zec h!_bf(~q_KVi ; s寊R,4y(ݙ - _:=/z[hf$|WuYc;F4qFJ $9?cg޾GM|lMNԹ% -4:$%TXs,=Y.1HǬWh.0#w6Z_d6CZYndXK2YPơ&Y}BFRL U\۟ "v 1b2]ְ?z"<:2PHgua<ۦ"-vI.O4\C~>]WM-NZ2H~)Gt+ Q?iZ'[vL +n"?FnKXn\]H6)>o?o!Պنcp8dIZF|@T=NPA3.bIM7C1%!A uT 究M3iwzfTe-{S~׿0m)d|_a҂!q^#HNImzIrćO4 \C͕}AiЕ, -P Wj'~( 'Xzz0/Cta*19r8:`p?w H -@mcwFSFaGj\Eʔ֔q5}k.w^&7'ʜտ{WNcp ~pQDAAjY -8:`N`Kk!< C!@w8 (0q`mVE@! *@3C>XU4S\iW"fC>ZHg -BfXB*W* e?(? T#|CJfWpÆ LoS !,F*x8$!^S@31C"RyH"/aHYȰKxw9{; lR1XbP /_t]lY\ao}ߜw"U!a"Ex3lRw:X7fc+"?t({!8=vnj[[ U>8< gv"ϫo}CQr|ϋ4 ރ9Ӻj(.5w ␃c{1$($DfM`r_xX,M9KRV@E6mp~!)՘tc޵E} dҧp^9jzdDLQqK+HMMIe:I::T]#!D9WEzcJ 5]؎sͶOî-Sw< 3؇uӐCQt: !GyK3tqX螏,靄[pơQё{ɠu휍fpIiK~b~o8pKZtFc+4{Q:KPm1#YEh8Q3;Hq̺ C8fRsG5Z_d6CZy5lSb)g8(|#8#%8V␷4C,mmy\i|}$9?cg޾GM|lMFvygkV2\dkcҧ?( W-&=0t~ d I3A&\Wqe4)d|&!¾pyV)VgDc?dĖ {m -S#'Tg Ǝ*T®!q^#H߂rσ?"jP[QIQ^M]4 8:A5ϸr,n665J)Ņt?NfX<ˆV6Q4C#d(Fr( $(nBJ!." - -2WPC8fT`TwZcf)C8fE@ӭCvCКa Y -p|GG6l8C~Vq8Cة `m'@3C0k - `,0 48C@Uf|6MB6 ?qȇЬe `m+$ͰTH44|HB:䷈C -?!ت?hp57l6u _I^q<1 Á8kq8+UI݊/! `Lm{$aC"JKqכ3)΢/6W>(=?hdmph6BUa 0/X[C~9:-0a9һ{t„+-O'Wk׮S0mđ̠b=?>10 -wpZD_o̗9UUժ*Ȳ _1 qܴIb1&*B GCU%&oj1xmcr:)ALg R`z}#QAQ\]kZ0gPw|[CFo5Me't2S7og달fX1c)jRӘXm|C ]cXÜcȽ8܂X=0/lܻLŬllt8gwmfar۲GYBSONjp5+*cd.]lqSvkuOr=S?IgQxTgJy fh`=}77|h㌔rx4?|kcKqT/h{it`IJ -攳Y{>MC~ nq%$z-!NyK3ޖǵ)w1EhkRw1I3ňmoߣ&H>&sKUg%Zɨs^tzr0rg D> wPSTIQ'\Wqe8$O؋oU?QjbH܅ҵvD"n`P$WkK~x!g(C/p>yu -jqPWU}';-l x "mSindGuaTyVM%6HŔ%ChSi4:ں>6ӭC8f|6 -N! ;Z!chR0,8C>d hOC>w`C>}48 6"  *@3C>t|Xhqȇk -M3Φ!O^ (`+}P43EYRVC,F9T# Cw< ?jnذm!|y bÁ8kxq8+Uqs-#*^h!MBѷ"IPߪPHDIqP"zs&Rc=e/5gQWn!m06;_$x^ ":NV*ƇmfQ>~.Ue, e{*C4{^Y̱lW0lA-Jo"4Ysv jJRSSRYNRUHQBw\VEB|K~@f=^Q`ibU@3H،CC8fR -?)NYӝʏ$a?R5_MUKNz?Ls]XE";-a{>f85;%\TQё{ɠu휍5~5dc8\C--~KZtPqq̺ f$b~TNٽ=q]N$2EEcPU¯+QRW1I3ňmoߣ&o+c(ydG>F4qFJrڙ 8:cF-U0a~T/Sݵkс%)٦*ĚSfqP4 $Ujp%"nӭC qmlʦ] __,uw ǔ1Թ% -dչz/tA:fBsA^RrMq*wOơ&Y}BFRL U\*-Ou}lyHQW?N% -snj5H!bYPv8\7 ] -y}8:cF t s0vgL,=4x+hQLmMn QQW]i8=vnj[P/V3 3@wk!n1#UpNfтCkx1f)!@!chG 6x@!`C8@!!`Xh0q`mVE@! *@3C>XUiof, 9 _qȇPDA^!i,BJDVCbalm@[s<0mđ̠bMk"g\'=WDL{n7mqtPoCѐcz ɛZ{:^ۘNzmDbY_›|oϼ/IB߶ފ)?h?[ XT\0qσx[{Y"u\Ca( 4L  - Jε;Lj@ϗbs N 6rUPjj4s:+MώԔi} ~`r7R&8e -28ƃ= [\ЌjUU,l X-" l2>Y]Է|~[\ Zsa{&]>zKZIuAvMѹ?q"PA1$ ZV^BPǡ(9DSE[ɫvE 6ۢ!9`> =sJkv-O.;f権ǯՅ{1k<-Odn-Ex3l,Rw1ؔ_x߹28l#̤ IOLʱ}.6LǬSh.0o91^ez`ƙwn,njJvS arEf*e?ΌɍY ~SKYOY+H_meX!q)鵛W.]lԠ%>ɉN*H@;&ߝhI_q.CW&A -ɡat6TADdOtcS) WSj C -xx *<%>pu!ͨ?TSW'W3 yUH.q?ALb1r nE֌Z) _*M~Z9qΌLq[/'j⧊`I6SFaf.e::TK!6YC#z8jR]59jd̓@2-;7+2qSJxf'!꓾}%}98܂X=0 -!3omlZh?L5uI6'EOo>Z|;Ci"B*J[[a{>f85;%\R9zFwDGzd]&ѱrA"wƬLK^.D|n=9?q1_?{,\C--/{~xWuY>BCIf3ĈP{_{▻2IeOCOKRMU58o,sd>S=j2bdqӭC8fRsG52}4 G>F4qFJ\`)9KZX qmlʦ]O/B[ww߹H_.:p-JF]Bc+4{;Kl> ˤ4 =8&'p755j2AkP'\Wqe8$O؋oU?QjbH܅ҵvD"n1:l :/ AcOc1.d<ڂPόJeoP -Ah)% JE +<z,Ou}lyHQW?N% -0Sa7 =ɛmI&p55Wj/}] -y}8:cF t s0vgL, y+hQ[CTzxLC8fڀ*xN~i}n|]Edf0`R>ӭC8f|6 -N! ;Z!chR0,8C>d hOC>w`C>}48 6"  |8C@ -C>! -C>V#~,)`U>d@@Gjnذm!|y`|CCqװptWpbOw/B@HH [TrZ8\~={)AUJK27go/5Sfi3ma3suHC868 HTaϮ /_tZ:24.TJ.cp7׬E-h؋GYYVv+G{~+&lc"Pq4XŻ^j򦽡6&GShn29,ts鄦)a^!AɹvW.Sr~r[E .Ylv~L _|homp'Y[1b[g! =ʚC_ N q8*TUUSš%RSy7{'ėD- -=P:!PA8@On[=O$O"c_W_q|OeYQ}/BxʮZ>[`(cvelOx7/0e]WZַ?N-ؾuJN_nbqbj4h=H~-+/guHh(Pa)"¿``amQƐ#lEؤĈ-oT&fm7Ʈo*u>~ }Qrܷ>AӺObF6ܵ&,/`Nc7{~'Gog]~yW:`鯎 3\ONVyVV;/7UnnkzcEQKxơ.Ќ9S)CO,a}͎eU$6wfLn7z^dzEAbq.CW10'c<j{2;*☹;"2K;kf|1eV)HϜ=)Ntn 0qد -55'jꤢttu`EՋS)* NNtRqGQ0c% ufOɵCi{%L[vnP ݾP&M -]g )-6V9jb>mabDE!ifg8[,5եk,%&KDZ)?NڀцqCt4m@xZa]59jḍ +-tqku=qi3˞>OciVEt">shǼ=v'a*....᪂EՋsI g0#?}X7 9T8iqHi 3 o=sER's ^HNA&{Юjٖ3gNb-F*{byr9f yu+JIšFA1Pf͞ Z<WPKK_ЗM|WuY>BCIf3ĈP{_{▻2ɠϢ"1*ו(rgEϘ$bĶQ>4aCޖ9I?_쬁Q';1`>n 0q8PKVi -8̏jNo>zXmB9lŞOxct@#gD:D'&@h5SI<{xEýmLNyWM+M̛Ѳg#y0g9]E|S '2 ͷvN/9uGRL:QA?]k@wm~ ->FYJeUC߇=oT=@I@M<wPSp}DډIU\*-рr-_#[jb72>hvN]Ĵ$9gWzH?qtvsNcT1>k4W-_gLÃp55WjħoКЕcyx![p ~*qr -o=) qڵ1c|c,GsNCR5KN8ɀ*;Z!chR@!chG @!`C`|;u|8 C=0 48C@g)Uf|6 j]47z\ld |XCR?z< GCq4\ 60M]BD/>D>p`(f4@<Gh0&6qAD?S$ ,~YR\2ޜɿXOY䫇YBx{ĵQ.d@!m0իJGY9q4#|r8%[FDUu - FnKdqdwCӪ'~y(0½i%p?}k׮md-IYҡodH-67;){Y3!,YfUh ;]jjnAtka3_,y/DzBНԥf:_}!̓؇qf-o/kKVUUQD@]iՍMU61Qm8r]/5yPxOk)\MH b:kIVHkʅ5-CKFM-+JJ:)԰L޶ފ)?h?[ 4L  - Jε;Zj`*y/w\`m#WL\>DHM^_F xF(e_%ԛ/8<{( 3ꡏZmǹd$Xۺ؇q"Pڪ䭀権ǯե*!lCQr|ϋ4 ރ9Wm;E Crll@8d&#iˑdiE rui]ÕslI9 rE滫BEX,M9KRV@eb;dV&pz6TA~Ǜ:̎Zyy^4@|HTP@t暻ք?垽g޹ov5 JC a[׳]˖-[~y -=k3?}f ;$ԟTVC5B/7;>U /=wfLn7z^dzX8ԏ3\jɒE z 4\9c-/Cܶ2Nq,H@w1e*kW [p -j`w'Z%S3L: >ɉN*H@;&#U[%r(~Hk3eK(C ޏo]~gr2PsK$1$BhqЃCqC(@\]\\H -:YC#z8jO]59jd̓@25Lq|̰o8܂X=0:l8=vnj[[~h?K0#?}X7 9T8iq,rgʴ2HħVs r:yH3 |(gxѯCq/]Z5`̥˗q?127P}R'+f[k7Q:eV-w;e/A1EEcPU¯+) X(AiiNFq(Xj3&|{Ԅme^6n1#Ɩ*0?ɗk@COKRMU5i|h㌔(@-w7&.n,L* ''*CLoTN kFI:!qIVk>m5zWCb6Yaz&]x ][q{ʫnG$3ŻksdDC2E*2xKY ޡJ_Aeʱt7C)Fr( $(nBJ3aC8fĂ -8yu -jqP HAMnH#㐇40?gAaGpF`92z²KvLЬt*)/".>wsp55Wjͪߥ] -y}8:cF xx+hQLmMn QQW]"fN1#T p:fXt68 p:fтCkx1f)!@!chG 0v8C>w`/`!`Xh0qFC:K! QVq4`,!pjnذm!|y bp4GwU$m;"a!e!ÒQ;>8qET࣡,5ކc nhFȩ%1Dh~RbN=eV6$4]69(udB@=?aE/|~rlMϴ5%iBbH8{x`5M:&y_аYI=)Nzy{ߞ2;{%r:pNQ?+8΃L_'j]"=f+SKqnxr`hz^g[bn?'u :24.TJ.aM:ǛXo^usAt 0'!5^%+hvy ܈rtB,BT8:DE("0Q;(9jVGh8y[{Y"u\C,,/Hئ$i&V3#IH@ WkZzM1UoWp EۺQS_KUtYy9kqyߜw"U!a"gml.ak*u7s.cCQr|ϋ4 ރ9+Ov'.k2ǡۄ<9Z!׆#P妠 ϫo4_&?HttW'RM==RvGUU٧via6H8>t:Ŧ!7෬M̡D6M,ے"/x _r6T]NldQߤtqHh,s1 ]J, i}sl1ߏO_=[p<a8dI=uYn#n8V0yEꋬf5$o#Y2 !N42 -8ͻm8lr\4xmqϛOV:ud1vlK߳UuPb.^%%WwQ 9܁yCcVMLqز+uo/ECԃb#( f+=c+@NCvdDQPwS?3xqkzi8xf'!>N[~ƩRӬeH09#ހq/]Z5`̥˗L"5Ҳ66X?ggs,4=&_+f[k7;Y9k3wa^i!7f6co}??vP㰻6D?BZ, Q*$PX+$f=;KO:K)S"(B -/\B)BN -7?ee~4:ٗ޽4q&z^VPtPu(+*XZtxGDtk+)fDD"=^V"Em!dd&A.cL5ik,_:{ 9׳U~fpᯂbW:|/_lΪ/F.yu{gO}Wp'Kӆ$֛O<1a /+li-/bꂎsfZhLlټ黳'5Z2wmcanL s) -Yf9Z|cݥ46 Z}a;S~x*@;\+>c͡؟_G<HMLS͡Um"pDd+Y^7Is/w'hHzA&CF4So \jd&9"a1f, :$#Lm,Ej䖷,/xܩڡS~Cux 53k{K^7&r3tN.3jᚚ[SjFrf9SˡɈ|j>߀_ڹm7ǝ:J\`k{B߮Y/6fpyݽwstEҶN94+!!dd6݇msGť@TTtԦ}"=N_vܢ1jv:uXo+CF0,pj~o`M{1 FC^n̴|?W82pK7N^ KߨV6W\t\gݝmnUYM-&x~Ɗ$ENms&&ʃX[:Uu!71uφO^P|Zꎰimnц<]?glÝٛ aiAfO UwՍc=6#xM֜Q-꩛o֫d}(ۿv.9ӆ)y ::67uw~!!dD>I4#^j-@2Ŋns~ٙުm)vj0?_ȼshbcF6;'s`{pm6{;Z9'ml/Ќ <1Cw}GKh܏pKЄФƌO,d_$mK} f99$ȧ)5Xe%r(4;41MV꾣g_(BoRHLFSkC&}3`C -њ`"3B)dF;ZG1OrH!l -~!C0 r=˜sB00f!‰/0 rH!Lm`,B-|Xމ34R1f!(XaD;54s'3@Bɮ0|}}Z.K\2G`jZ[wg ٻC0 !!dS˪W.l-oY_S[˵C&9~{⏞5{h ,LWFQ\pMͭG0rHCýT v+,,|ܩ>lwg.x"L _4ǷoԩXٸ.\K*m'xR!vs) -Yf9r=QvAC7D5Ԙ^J"lp'ِ0SdXZle[#'ً:"U]UvN_V|fnf|gU+͓ie14ejhҐC - CɈ|j⡻־%ខ-8[&C3{?ݳߒU~.1;'=BBd2"ڦ?8_{_rgטcȡЄ~whRcMa1g,}GZ>Plwm T:$FڐC cLrH!3ZLY - Bf3@ !+  BX3!S cr=˜sR'X3!00fC -.+{kSLm?cRȌrFLcRH>F4SovfE%.#G0 Mb̀Y@)$tI&GXVͯ.l-oY_S[˵C&9Bĕ[e&6w -BLWFP9SˡɈ|j֓>߀_ڹm7ǝ:V^>}nXK bXSˡٌ_4C - CȈm@ݏ櫋Kuu5끨Ok[Xَ[5fRB~b+uX^Ԋ55Wꇌa) >an GdnlVGԘnrٖ]^qR}5C - CɈ|jM[MI$TEoLLV7]t8qђ3d^TИ9;e3EޤL{Q@)$tI&#MywBUUs(o7")Vt;5HΔ86g0ʪakXo˞9:&6fds2˃ȖY'FP99$ȧ6o/o#D6 P( pfvvY<yzzIQZ9ճ'JZeeNJs&䁣7-]-#˷)}N虘Oɫ4 aFnߡ7O~Hzo yBД̭ËC fp8rvwtѣRHLFFLmڇ(Ϥ15* ^Js|FYAXE4v K.&2uùhavV2yv-941fE7O~c;f9bƣ rH!sH0OmSUt!:$6X{"|;D&tMj4~),lYmzŠRHLFSKC&t1f!25KDњA)dF;Z0-R[CB! c9`jcà9B7@)_B) 9w!b[_5 9 9+@)$h -#> \jdA@h!!I!,sj䖷,/x\;{jbS?ߦD*Z1j G§8` ;^9SˡLJ{K;WXX9켏D0f.mzac=;BB$`Fp@ݏ櫋Kuu5끨Ok[Xَ[5fRB| ayQ+\2jumcURC0[ <#t.uMbX'L'\KfdʽT)49DcF Nn!!Iȡ˴T![74* ^Js|FYAXE4v K.rn8P;9n֐"3houXt; <#ϡmG2q?Wm 4BB$`9%k7nYXe%rBC)$tIFC׆АC -њ&9h`"C -a_c!BBC CrrH!,0rH!X!hF ŐC -Q* BɮJɡ^ (vYTHRHrȲj5sbrKԿc RHn;km BB$`FpCE櫋Kuu5SOk[Xَ[5fRB>u ߼ayQ+\2ju# rH!sH0NR8QAX899yDΙ(cnnlW1\; Cl_nu.vA)$tIFCQqb UUbWW͡%XXQmE$egJ,tV>9T7RZ U]t[{^L0Y ^^99$ y"""Bs(///N-Ba833a<*-+3tT3I&mV^i1r-nYMsB|%4 aFnߡ-C-U+6&9]< Z 99$ 9>LwDߺQVQnR7 -T}l\Jl.ʥQ^p<]r)Cuùha1smZQ=k׽1Ƣ@RH<S>>> -stream -x+T03T0A(˥d^U`bjhgb7161Գ44CC3cb |@ \' -endstream -endobj -235 0 obj -<> -stream -x}Vێ0}W>TuZ`}SWUUUwȒ"/93cODP -?EJ8t%(\rd!0Q |a[SkㄊIO@%֦؀PW. n) 71"no̕ ܰl>8G@۟k`~0q~y꾇0 -مer_G}`tK[Vs9J wHU]Vnn*EӜ]o`2ew-P{<YaHMՄIP"^u`;AN|oP ֵfK:c.',CxJnT`N'šxF*U99J둉넩%]zEaoq:+\Y[ܬu'ҕA= .\ lrB -,J0 5YLV!m&}LK 5&] 2(&Ɍ‡ׂ8% *?={ -endstream -endobj -241 0 obj -<>/Length 36813>> -stream -x RO=-Yc$"#?m~.!j#_?vH"it"Ɋs6rCexo{U/۵+O>sqa۳mDq!1\Sn?;kٳfN[cP ^!8<Q8ViH"jZNUGRju:~-9^9yBklǡ*M>a{yq9FT7~_"]C`OWjXjk|_>r9)eydt!J5%S4a^U 2٪y/ ;~TEĶZ5k >uSuIfV~ ::ӖNy:+ѳHΝė%C:iĊC&~-EXR'>/S$P߿y~}^GMQ.IT|ΖH:v`ނ|\4rUqa~ڃ۩UCg)@!CP4:B&wuI+}Xԫв'-prq!q!JJJ]]\2{.t ]]J%%%]] -`&L"K]XWܹӵ5 еq,c!Y] q ة;:% -еڎCJ'rp͙Rx R;\0!kw,3to!Gz0J^( ۮy?$E)R:~||ҽy4Qx:Z9#Du#!^uwa.`{ k{J1rS7C`< -sv=[V^6s*5C}ֺoġ*oMa38!R[-))ꕗEUdF{v^LmvjiЋo{4y8tجơiC[]gsPr56wxxb~4i&[wvD'r0iNߒ2yycHó8liNOԇ _S̖~~V\ɕ]#23CxߵZ*msnkUIRYռ5B^k[ZLn.{dW^7]ZX7n:Y3?W lAv=G7u85Ս'I,.m&‹dfxpz[:iHĠ̫0&!syN_;:/ƵSUfI0'\ӏH|fƑб8S+i$>55޺\Yn_"ZYv[G<%w Wҍ/L BM-\p0VsѲkzN^՗@YTC#r - KmiH=i>q*D{G*9>mB3ezJזIǛulyEP?>\ 2UR}9pTf/+?Zؚ./ME/qPܟ9DvjKg͗a~F8Hc!FoMLWT,@8U >xѻR23xl [V!+YiuĄqZߎcMBkΞҌq8'u/:4{7aXW?d%g$d-7PWM5ɞ c[SU#V*(ۈ)Djy[w\O<0?( &W>~rB;HY:|^[[G=7h#֯:zxؗ -9xS+70RMko6ʸ|N#nꪇDy,;h-˵K#K7D88ڕGbG/modYӝeqlט|g ^)3ҨIci8v)[!T5dH/oPVyXm`6/ՓM+f><_PKEv׆d˽loyeYInݾz&.I-a廕E($2tJ!xibUq>>2\s68Th2q-|{ۮ8E~6&̭}^KjҨTQg^ӃYSFb~mTrC/NߒhQwź$8O9Hk| ~,fcsU;;[[ӍH|X3J%\GorR;8u!:G2.ҌPӝy=G7}Oc*{k̑$pPXźR^#fϦyxh h!3.d謹rG1Ӄ\;eMT<D-$~o+󚬠nVҹ#ϓ`ОP+K<µ! Z4yL WIUJʍ>$E?-U_+UV+ɼM7b'ҭq> W63J.Zr%jEҁRJ.|\R>܇&p~>Sv=G7#^sF.n 紽呏=e8޿\sWۦ/~J#P4Z:8){cn{[^w}@'PMuGwka-6KHW9TwyC=G㸇竷w',Fm^̐x] g紨'gUqMw |$ {<ko[F,/0`úb-l3jy4"28k35Dc)]XH=0FҬC 8zl)9KW[ue3~\EMZU#ti8 ˦+p, -9=]`PbK ۋk(ܥ_KⷅER2v)s8߮C|* 2?.SR/OԲb2OiV+Ъs½/jM&9Vyh?хz~ :cnI,_fɼϣ$(!գm7A3ow~Hc~_BZayK?rjtI%o+riiBt|Ѿc,ߵQ:"]I爁,9 i9~zs2p!^z 3+ypt[va>^GW^z؆ qs -@~{ȡRF88~vGݦZ.@:8>ucNp7AΘ;Y<*[$pV~  F?2 ](y۱Rj,S]M3=-:@/S=[hg,s땰3o~oqgܹ [pUij: +̺j?eó"S<Ƽsl=^QH?u` OݷV4>|Pߤf*mal ?ee;z%l[߮@4qg\B;;xT!N<\vյHxK1d C9yz^nً!sV&Z8~AhrKvoҟ%Ue1p}ި}m^g١4S=ޝt谔χ8̜5PD.\ֆUf'&6.f_1^3W6,sobK߇L寈8uOoeqewGBUwN84w`GԚv-=jN9 WJ^AY2NsXȷڕR[w.O:Q8d%,[-[sVKg +!#n<@eIp.Jp), qg_zp_|y._+K|bCE/zxKP9rqHޡXP{U=hz1jj\FJo{uobNsj:+|ћr*H&Y9 *_TN56h$GY㎉G}Nq muvK]izDigw doW5ܢ}4a=C.|OcjTeF;UF{jE{(wLw :KjĢngI0mi:XZ8gBfR]J(PtQ)A>Q%ܿP--!Y ,q8 t4:T?|t,z:kh{4 !q@@!q@@~n2C$[SwN>7CA ]&pt2C[:+M $_"ڝ6YBCxcWK6]$>tYU!Ly] g }uW~91CH%.+xd/{/m%&4>UƏSJ2]՗+qpܹ_B}w[>u]uq"{|Œ]73|^p^ Mi$' ѥŁР~ -?]N^*ZcikqȓL3]` "]*~bCmqX]^"ZSZgYM 3^yrc)3[ѺRDk8-QtRB`$"|AJ$q Hʏ[lh2w'ֺBc_b 1"GjFqbGs´EjHt KF!/]ICdV(r+9q(3h]-4>W.8숬7ϐ|=:w//lzճtZ7!Oon9{+W'K.96] _NJӰ_gϙ8YX"e4tUY)&lHW/@'h;˓L>_9dǩjlkQ~ӫcV,o|d OV)hUrGbjymz=}9qq+5PE/P֥׊8\Ty;}&0}^.^qϠً& \e)4ڎCJvNBqӌ*KH),Tޚ ^ϫdǎι Jgz_ew}F +X"b5X)`bUuYXX85w_df|-{{J%S~t5{}j?C63qh2/heBl6\{=$>DꮯMObTT -}AoMN[9ޓW(ݓBvuO_}(& v(!R/)Og,DK+IBM)dP=4Kiq0 ]6kl!^/[wSb4oE{AT[8_3gBo}iEt^ 1stl6.UGf:9^"UtB64Ru=K*:33g"%t~]^vm?-d͕tB6Qwu8V%qXwόCtsu-]4}:X¯/ea]Ki]NSRBK8WB:-KcիW;5W܄܎:f>8ZxzGLR+Lѳ86-$\OG"jUo) 60(aXJ'a*WM¨XY–%)~;iO蚩qkbx0F!Jc>Iߓp#5Nl/2NXJ/YZ}tR2N E+.O_SwqX}X(w;L?&Dy;|\ < kh,Za3EZxm+7UFWitR^!:6svXԗYz:-~qK0vs|j6)7ݢŵU.R|+A&̮4&1jK$|O~*ZP+#ݍ&C)b8$deu:Lx왅jQF;?ҕF +7Z8o"Av)ߔphXUr_][VqYs `1-J۫uiaTLݍ-hAp;C it8$P lZ.vtkmPct5o!@CC"wrc;!!膽aQ &˘DZݗ̔cF'&iB pɫ~1s$M~m+sC0\|z <@+Iݕ%}j ? :mX !4nWdn1ɫmWS]U?^3,1+ҩC+*͏3w%׍u#5C&qհc>MH%D˽}^1zBvQ_4 Xݕ%< -HqZQ橽Mxw~kO~qXCY2ڡAShd.;yJ,,1Y GO40o .3@Р遚CjϷ57DK T6[ -)zhe=RJ+w?(jnx✵A~F7yfm_Wc8$KL->CRU%4RCɗ4e ?,И cjTl?_]i৪J0$COmcЙ_>mksChђ-#ܧ@t7$ v:>·hqߜxc݄tp>@] C!ġr!twC!@CjU+57!NU6d|Fc_5ǦCE}}'8'nUijZF0Vs~cӏ^ш8򚩲qkb~:jGt¥-;mᱥVjGYE5<⃦8i "8P%2ΰg?N!P|hM8s_^teFvd1հc>K-D˹~V%a85A'G6k(4=?AGЊ;D|,&uE+.O_Vr[,?%w~2MTxt PNki5?wηXa3EZxm+7UFWiPuAz8~ !Ro _&.^}Of"冿[tVTʅUq7sb7j|gb s6H -@c) -Z]ܮA]jO:R&~[Lv<1Uu%!kF%WK^15=*|.+*͏3w%׍u#5C&qհc>MH%D˽}^1zBvQc P?[W6k㏒gX)@+< oɹu/kr}~(WF;4h a\޼ȸwD!|K,,1Y GO40o .3@Р遚㰮ln)۔F\l!RϷ57DK T6[ -)zhe=RJޥ/yx+,}QɢύA~F7yfm_Wc8$KL->CRU%4RCI]WJ^ߍ7~n1.\躮4ϗDWR= ~,).! 9h!t`--~O[kdZF i=M7C𺝎-Z7'X7/ 9܆t8hq6q( #snqq8!UNM@oۯGͿu2{FE8/v9p?LH5FB[ %+@*c. rmkH.~qH+ymԣASu\6 کl,*ޠhQ9uu#KeO>G5 3F+_&qő[=y[%(7Ii8,ޣ.u.Y.qBs -.Լ3fQø),qd\\o!ZUw6=y_0*~ctmhCrNeMq$JbښykFjXM,!Gۚdn$ub'۫#[{{.VEB|8QkcT<_d;n_ٕDO5CKyު4EU8N&qh_˒L\@-v=̌A&a% !tς>vqXz%^ek -dM~U ,Ey)3x8*`&MTz_ -`a}XqhpaFjM(Ycjvm:.Ѹ8We!sâ5n.`W=i).ͨxsS&[zqB$,O83Yn*5Iso?1 ̻`ը;n^ғwoy-LdZO3%4E+}jew{t(`Ql쓻,N =|U5U<$w$ڳ+++ږ17_Ts;bT塇9EiU+dqu&4R}fteoYq.e!gυ:2G Ű_:sWĤy.CՊ3[@{ o>QWa΁lq8@&DߏWCCwQV^5)U 7v%S=lܪ7N7H:gܙ'<_Yi@Kȅ !O*M{OV? J/iIv-&sO^AC"HOfK hlC -=(B;gpD+.5x wy{xcU *0ÝvnTi.&Њ'[T s;>-skL -V鉧vç h7|Kn!9|H^ =n["$B#F0K<8/nÎwSOԞgc|3pϙ`j6ߕ㐒{Fg >вS[ 68L&')0釲eoI)nT]y3˜qhnJP֡|_˟lZnt<NP:c/YMj_8>7:NZoZEλpUy^`1l\]la1g )e깦"}3\yc]r^vXxoE>$0Re!6zkW"8tQӽŒ"6n-o:*zӮQwXa -|*-Qn_j5+8'rFE%U\)auqH-h1YFmR/=&wʿp{2Kc3wz&^/1!d"4E+{a0zcѡE]jrx% T|)@MX*0E˃L-b,7MɍEJ+3l?IF/B瀦Okzկ5O9<W~ b/ze^O חA - ۏ^ryݥ?Uo q8 M -h!Pha}1簙k춨*CgkRQL󷭫ܴ -ZF]"/NI0eiE - 'wFGvL, J/i%zUT#>h˦A;sE3]>紮n$Q72|Cc^ۧfah$8 3x;o&[9{A%=8\]a}#Ү zMFA^?Žq82.EL-窻YiqwN4!9z8N%Jq!ad<YJJbY'v{2o;-bгd.Zo]A3$Ъ&S8h7 uհ_d;n_ٕDO5CKyު4EU|YJ,tњ_֮g8Ȥ;,Ѹ$toү9p0Y`51];PZ/ή. 4vqXz%^ek -dM~U ,Ey)3x8*`&MTz_ -`a}XqhpaFu=x}֘]K4.2psoη(5ZӯhJ(+ޮ. -4~qlx9>5n.`W=i).ͨxsS&[zqB$,O83Yn*5Iso?1 ̻`ը;n^zkX"?jH?_PK_eqȹ]xs%^P}r2ᑳg -D{vse~UےGbxVj}Tq2bv|YPݣY殦R֖Re]6ꣴr̟K6l0K׆zk<tV xסW1T8Gt^›OT~v(@@8@ lD"zc;!qhHDҕЍQuv4Oq6vUHY86+RB6ʬ=3^ ,Vo+b2U=-d<F1Ѓ,4s KRQ~p-qIߜw=v] -s[1iG6z@&bo] Z86PιnKW#Hp Z1&>/ц\5C#M{e3(Ina'e84~LD/\@ ;MYo<ǻS{=gȇ>~WG?wqE&Zü0=$q'߳ 6CcÚD_ħYA$ѧanSvPW?(StwBaqhnJP֡|_˟lZnt<NP:c/YMj_/?6?\[4mT @4E?mU:p`w b.+;,7»b@RnsME./faƺ8,BhP}+aI`ơgCl\׮/Eq袦{D'ro, -#Jq|nRGd@ R/SV_Sl1r+pO\RX>K54r-.J}N 4CjEU2jVO|q14VwJȀ#\JtB+{Y;fY?5+M8,Ps/1Lx K e[lRy)Ҟ_\-@ogʈmei4 On@,w= VZa haӍ %H77 -~}F 2,{d ·TgU9bL~q+3.^ǮxFX>`w^gw)OƋe= Cġr!twC!6۝">Zɹx=\U!h{|iT 8lP&$#C׮9|IG[U6#X -!䁷SjxMq4hqxbyF"Ս$F/}h=+v؂6]~CLaC qJ';oͳ4[@(?רPqByD0i}nE 6[Aqd\\o!ZUw6=y_0*~ctmhCrNeMqtE2R)J4VyWzD3gKq!;ռ?U=2'E@i[4Iή.4~qX}tҺeWn=^0-y^ -HU8AD>j#Sa)͛5F -7|GS)ka8xfH|R&<qXh<}]r\^aX?&*P/sP -Soݸyb\aqn#700H!ji-GL&P?jI˸B]],h0vs|j6)7ݢŗ)\v?~zfS\Q"79LㄈIyȈ}TMxDJ.~[hɴRg*J VtP-`~QF_U]jO:R&|*#6q%/WY< -_tq8 lD"xߏWCCaTg9n?uU6Y$\-2jws*j92@Cv|z <u >/2BTz~~tCZiݮobW9nP;4RRCf&B.JΙ3~Lᱝ.1Pf41JAォvt"QY92-(X`)OcREe{ roxhCs.2 q{$9mZn1f`,ɹjㅋ/Xh:&Q I.!S[ 68LEc)Ka8Iu -L|n_D}J≥qqoYCnn| PE/vqXasRvk*rѷx1#̕7!geՎF[S;oѫn߽ϋ!;#GdX1p_!0zӮQwÃ,`=)N+/lG'.S|kn[{xhȥ^mTEs> C|ԥ]T,͑+(kաêW5So\37'8eW~H Q6x$)SӮ7~Ei8he"fCo,:(CBM/[23/%Po KH{~sy)#Eiv^ {ݶTqI_`j6CRp3/j6yOx~^fWȢ;~Xe~bj)=UOW -c80!q@@&~d͕#C PѺk^q}Osj( #rvUJE1߶F0kA[ŋ]NG(y?aUޕ+C?3VR5Z]?ZB) -rygtԎhDŽ͒ uuCZoeiNeeQFrE9Iԍ _X-{WGmLNwV gi$t\B8~㣲2xFo."nM;$ᩥ,qd\\o!ZUw6=y_0*~ctmhCrNeMqtE2R)J4VyWzD3gKq5G tqO}V!=e<n'0'8oAih*`15٧=mN'/Wv&E R>MtQ}1IF+=2f͟2yڼYcyʓLMrmTvqpݻ\lpEЪwq(TF`-lϬi]U@JvWRg2# 篯C +l D0֍/?62}3COl5^.8%LX]y%f GpTYiYeEF/m>ǧ`3r-:]|e'm:ťo.rycdYO=ND9xhO:G5y/$h~ITZq/)L)5qƈt;e{#6/2!Q$ $s/m;JP}r2ᑳg -D{vse~UےGbxVj}Ծw-oWrKolINJ5GomWԛ^I ={ptUͻ|$H^e4q|%M˞V#M詨mePaj/: q8@:1$"{}X,sD\_+j#%}? ->e_{E>A{~ov1vG6Q}Jo?뤌fmVs⊥.=U'vxhb_e" pO÷;~ =yAˁv0 -6ěeF|/Ƙ> 2]{vYQR|iL&>{ޙmw*{f0 i5S͛W:,OȶJ'&_V@31@fy5nyR$Vݏq~)? -u9,YcKdі;IFdw% *?]}%v`ヘc19g_;;zXrp1Nunx9#]*[Zn_8S$zZtYuOʩVOo%oRVޱ[o$!M1ޣ$zݶnDy+.9|ۇ}^r_!K!]74V^2.WǺexd$ڈl5)V~Z|sBl d Lr (9 hC*G9k/x(iwJ\M2d[_S8g11'B=cB&lM:kh;Ku.nJ] "bYd0 ?򎔀i稖ao'=~^}(Uw-'2.q CM o~w9$k/ -B+ Jk9,vUS@FIl+HY>7uWzA[HaNE}7S;%&Q`\f9lc0z%|#. gZzlUqSpٱ'w -z -cËJK%ʧ/_^o|+e ݂qc]*-ӲJ˪zUj,sTyj|kGwwaIJQ3K]ĪrNZ{4q\n| 6{qQ#m7,=|EX/~V}wd3L2&7[8wNjSb3tOnW9LtQe0bs[m~]UQRY ֺ{]7ͤ<+&ii <6x -;Ut-AI!YS/N=G;qnn[l52>22oޡF+B# - Y2+:)P:kl]"71C՚2̞``[ 3NNy|3(ߚ6㻳ycF&_GX5gv dK|,v2ӋWbEBo%NgCtrXof u]*XQ/^~!#hbHF& -|>8vS\CH·:ƧOGLxE{c,waUݸ> _/(49_;X^讽jOLVnTim|ncXr8-Ajs˂{'%lScL&Or4}gtٺG)trtBp4a3[D O2 CgõD=Tũ4~y c Ԥ0|^+yShU|F AHCʹ&ybɎa3J}t7I۫y)ڣIڮ!.T2J#4FE"ȝ,6rħ%?'7/Z0E xh#΀C -8u>q ,r>}\ti%!pa!r9@x&D". \oo/r;9@?@Wi5]s k;O|X#gz`-F_ad3/OBpW^m!gGN:Vd𾫂I=yAKJo;3-AyYb8Ux/mw*{f0 i5S͛W:,OȶJ'&_V@31@fy5nyR$Vݏq~)> j`⾌imW7CX5g}w0wDEijb=Q,9f:7<ՑN{-Kc-7e/_}j`L}g=R-,Ѻ'E73 -Ģ >HR3R:3'%"7p>箍NI;{M{[Id7Cq]o+\"Sua]x9P:0EgxOzr;8^hbSzC+s~j8俿4B-&fP>2<Î"O=mm<3=k }9lpq!Zoh#_mxx#'{\ҟýޯvߪ,nX`rX讽jOLVnTim|ncXr8-Ajs˂{'%lScL&Or4}gtٺG)trtBp4a3.o2e89oaar#p!ShU|F AHCʹ&ybɎa3J}t7I۫y)ڣIڮ!.T2J#4FE"ȝ,6rħ%-gOMUmpp!!CCx&D". \oo/r;9@?@Wi5]s &_jijr\N/>K=U'vxhb_e"pok/ =;rԱe']OJ2N]{mO^=Anr'!B&=a6%ΗuK R?NEclB!fybyJ qV -haUs=cyL"F>OĪ17O;E4ՇvVe*\N\!i_B;0wƱ2:^ὣ'% T熇: urexi %oRV=SFm)IjmVKo,uD)JmItDZR{9dzo FʋݝQ&EJ`X` l~Tf>ųԊOoN7=t8ATWnr%m^R8glΩ!#ָY~?WL~,I30#y.{b8oa>.2`hI8]x.B#[ſRWkx*jH4=2q*Y/.L!#%`Zy9eb[yO:_-qWJf]̼Kd6+[~[}'ؿhzv\k%N7+p!CCx&,C̑B{Cn>ok raaǿCAa3Hbޚ E/{,Hbn^^/>S%ђ EHeV-J!a;$ - ̿_LyŒqoۂ{z 8y-࿊(!Bhn%"=a۫)o!MyٰDQC2Hg\ѣm=Y=Sz/G$- b_.9i&Y Sd(>$++,Ww%hXڔ!W/-EjXM&^gET_S ϡFrivwQ#l;Y*҉oǾ"%+Tں/k ?tÜ;t~|A/g=H*6E#&4 LJ$וty#rlBhg‹Ӷ]1}ڥ{V0¹tm5ENٕ : 9Dfٱ(Pycڙ-Ѵ!Cg~Ie?9j5i^k-!޺m=^d\p޷V 5Tt :ۨ<rdx#պ!sx"U!|aJ>pGrPoo/r;9@D7;ϛ8Y%5UBDBoW0sEݢ㗇sVM]7{؝a [L :ÿi֓!Qe܎j˰]g㻞i~ph˖#Tá"& XOm,myqȃ.^ὣ'% T熇: urexi Oz~U7rOepbŸ<2^-SUK -尻*;+6N/ (g'z v=o1LrEX_O1uꚪ3hΟBlkÜ=I nxKi})Z)4%UVܗNE( %»\ -_@o 尣S2EF[( pZEBDv_trH乖qAZbFO|@/[ԥ?{3XZoS<5фZ̨nٮtj>C`N]Yi#B{9dzo FʋݝQ&EJ`X` l~Tf>ųԊOoN7=t8ATWnr%m^RD-}QCJ -<<[=ahkbAӢxMMim獉,TpB)~u.nJ] "bYd0 ?򎔀i稖ao'=~^}(Uw-'2.q ܦ}RN[=T(5+vΖ‹qцcGKdY-_тV&!CCx&""~smmm!|C9ۺJci5MXmpZ~n?xf4yE?]}_^U5b.h]ÿ.ǎf=:,dwcw^9^@||u1"|?RI ܄rinAs8ӱ^iheU*5yay*<5yen`У;Up$.Mb^ -9SEx-=^ME7Z=)ǑVe&akɇVsbf0!Ʃ -:#K$yôL%Qf/V:]>7,Je'O:c -WvWfGf)ac:h|6y—H;>bLhK/3[N5Qzh'7Ͷq4ۗB8-w]]WJ]y)4*>YS\ W$!IQVܿL^O1dGd>ؤռ{Qm$mM*U{%~KTa+c]Wմ%nپ]ude` /0ޭa*#H4(d.\rC9 !or?ۋ9@ÿ,9&EVIyU{%fguRF~|69C1ޅ]+Fu=lviZWAB2rrcYOD]q;-!EFwẍłqRxV%e9a;ƅ'_n{9DmϾS# 0ۄalHYjdҡfyBFU:4qqX\dr7ȫwϓ"~8NQM w{ڲp#;MmD nJvW|̦cמ?4/.^ -/ŒcqsQHW9LL24rSg&$wֳ/բ;{RN]zxy1p|$5#uS(_,A'M"k\M|~l`$Id]yze[*F[pawUvWl$_ϡ8G7ƕIKrS:.B^]SuSwtmӢ3' O~)-/ V+6D~7ϕuK#6hųԊOoN7=t8ATWnr%m^RD-}QCJ -<<[<9C_\=7ƱcoOٶD]*8K\ U?Gfx{UvhzR1e,NU^\BSyGJ@csTİuSZk>̪yiȸn>m'fVe v]+m(l aFu -E+k<o !!r@@tWeZ6ZiYUJM^enJ4OM^oX9?N#;.=l"I)jxF{KXWBT):^}&owSd}ODͪ-XhXkOGmw\Ö%$̓;bf0!Ʃ -:#K$yôL%Qf/V:]>7,Je'7tq hSh$u[]tDUx \ APmx/ 9@Cr@8S^>w!r~cALes9vC^GPfI:tCx'v]n=N-IU®=' ?=ww[ک'ɬ=GcNSO}~Q0_faLG '{9DmϾS# 0ۄalHYjdҡfyBFU:4qqX\dr7ȫwϓ"~8NQM wĦ;ׇWwP"pÙB?tԷ/[t A}Q; /ŒcqsQHW9LL24rSg&$wֳ/բ;{RN]zxy1p|$5ۛ#Sh}9~`c}[PBH}\{㻧`\w魖bn 8X -Ux/U^ӳo|=v7W&",MEú -yuMՙs4O -uҵaN$ųԊOoN7=t8ATWnr%m^R8`ZӃ^Bp5Ɣ\W*M8މz?e]wYR.s9$tW]*ZUQEIŔ8EWzqa -1~L)Q- -pO{ROjP2ZOd歧]"8xh x!M-{E ]VC0 :"=MɲZ>ƣq^>r 39kkkCs y~dBMƑMϢݶQg,-xzE_NɤS{eua@gK D69V^TZul,q Ux/[a.;O.o?wx?UiVZVիRfSW[V=SKHR^$Vh?UtrI%6^fħ+|1c]_?p-77.@X/~V}wdQxp^ #8U9AAgd鞄5r8$laJU熥3Tw,dhR&$uFnIyVL0[ \`Bor9ڦ 99Nmm ׷c vWfGfWY J WXUG7}! jz*8* - zx/k -dF.ۦx8=n.2$.9f0g,|R65tXl/JwF;|ĘrJ^(gJ.T QhF#Kh/vݴ'y9ן?0Uv0?fS5m21LNPU\ ݕB55e }EeU5#MvNQꣻM^NvLv qѤYW7*DG\񭗻/?;^kͿ-Y|Z>fSuD9wrT,!!r@@ھZF멹hQ2p3paGe6PӵhąF688\s-|7/64gdvonj5_]Ì6>Z4%j7^>r 39{\[[r;9@?X# vRm2l#[Ʈ ߾/mLL.a@g?G=u?k8e_ObR7Mx/[a.;O.o?wx?UiVZVիRfSW[V=SKHR^$Vh?UtrI%6^fħ+|1cqpl|?YPO>z8p^ #8U9AAgd鞄5r8$laJU熥3Tw,dhR&$uFnIyVL0[ \`Bor9ڦ֬/~rw޺9~~t#g,*ʬȬg-Ǭq -jx=N -_FHMg)ac:h|6y—H;>bLhK/3[Nf4Y%nZL%P[*r7eue 8K\ ݕB55e }EeU5#MvNQꣻM^NvLv qѤYW7*DG\Hx!Mz?JàUƇ;F;liP:92C !9 LD| PyҔ߻?!#C9`=lMT˔F]k}> N=o$ Įˍq4 \ e3!ZzܦZ0hDW%0ޭ>UIYNq qE?n{9DmϾS# 0ۄalHYjdҡfyBFU:4qqX\dr7ȫwϓ"~8NQM wĦ;ׇWw ж)-z:мxaxMx1(3\SvH'Dz׽abᥱ2>T50m&}yhݓrӌ# h?$flbF7ȡyfE1kLLt<2^-S- 尻*;+6ցrzv፯n`ף$W%TsX^!:s)TN6iޓ,6om5vo0Y'<;\Rc/Mn"Kv+w(PD2<Ïs>|}o_b[@g[ǬM;CG[jnR%^E/#:^4 P_%խWn[/o6DWbg}uߙe .orn[N=4ABt.٫A[cH6+Y޲7y2jێգ^^'9ejE`wY^px8k|TI΋c7پ|Xߖ"BULyK\Zm理"|(3 -[Po[adp |n`pq_nIٿ&4rhiJLqf<$Vֹ-HW"u}vz8t4*#>>v6[ok?%-eԝ%9ώۖP[Qtv*!7&z$ߺQ$7DI{6X8G޹6ozԸ8H*hCqjC<˵)H) #r0k9o+pb\Tr7oEUﬠ-PGnЊJwYN`:%JkKJ-|KJl}pAX;s(ј(f2or0,"%+-Ҽ2hVo_tUr$SE>xr0+LUy7?f; 9\ܕ~A_AC. .+ 9 -!BB_{Coo_Gw)9@!9 Cr@x+2j -ʼ -endstream -endobj -243 0 obj -<>>> -stream -x+T03T0A(˥d^U`bjhgb7161Գ44CC3cb |@ \' -endstream -endobj -247 0 obj -<>/Length 23997>> -stream -xy\UB6 , +8BaFd_D!l>.BX("ٓ%l~SI[}9~MJS}=/β?惖cN$zk+wzՠ߯IAK]䥧gUtgɒ%;rSh򺥌 ӭ -e P+wzw#?e,x;quKuLQ'|KKyni y^ -O׳tv}4Ko^mQ٢矹7n\k7uz[luRZol4y˗nҗn1y?]nkߺVƎVSw>C.;5~j_:y1O?s<`o`ϯFm4EmڳlٲW"=dlo_y}kڂ=dLo5W\8{̚FG퓤ֿ}}/Ǜ~uim;q|敍kW,~~;g/d-5NmMygG>੏|?g%@:+g.Xr㬙3k t*[9}9r0nivM&5xࡇyjZwt/,u7׎wra]w9w>Or3{Ɨ3fI/z뭶ru'~ws*~Q`^n[uo1ۼ坻o6~>^Kuཪ޾塞^YS?ߡMsL}ԗn1w}7C/nC]T]qv-j=Vb;n[_nK/Ǟo1fKgCuKu=kmgniw~[n'U#k{ɄQ햗l{㮆}  [lgZcfg-[ovazO]XDձI+9;n)ad5v/_2[m)@bŊ!v%;z_+bW`=wE0{ - %tKy-[Cn O^;jTOZo|C+6eos?{F]7;_vco-תx<1vS.zW94|4~dz~ݽG?[x7^ W{79Cg -4C5/8'귌מi|g^x幑z&ՙ_iBYg{{<?뼦W=x~=,\1j'nӟywgolM'}}3'/cmvKםʜ%zG7&S/}g%`ϯ:ߗ :ZwԨ$h(jaOgӗ/;yO{єz{b M=S_u艓LyaSOl<&}W~-3>GNj9a1.]^~e=*-5څe藼|pxvݩrއ?' /g>tK4%w>o=:cw8s_}W~GpneMxˏ:#'?ಗl~ZgW>G7e{ti~ѓ y緬̕_x!/{wiܢ?|wGp=ላ`:+/C?NCVv\ <糁VO.Z[/l^]'νϿ|Ecw<?9jݎw~7(@n/x)=RkD^|fO\~RStm;\/wN|^wբZrʬo>[/+9'ӡU0w?) ?wFw[~/euGw_+T\5߸</f-ܹ-n߼=k~uxHkdzG/%WջxOsoi{NW4?f껿s.;}?x#-8}gYQ6wf|ʣ_X>ziNw޻[/S^?v˾wx/{Ś߉].8섟_ϸ꣫މkNo;j_>9댧>p茇}P9{]ߛ):_OY՟ew{qU&ؗN|݊ɛx{Qs>޵~Ӛw>jӃIO7ٗ7<_&.SgO<ܷK^S*vŽU]vƏ?06LL -e=c>瞴kߗIvu?^}g߻Ce\}W?qUGɦ^Gxly/7ijaƺ1OnO>J==k7yʺ} `? @%uK䖚R*얲.-hX|'%'v fKiuKͷH\q2[rba`MnI芓ܒ %)2`R'%'v fKiHvKuW̖X--baSA[$nAnIq X|'%'v fKis/ysf{^-%-l/fKN,̖M^;qMՇ!%;Wů8Ԝ̛L'9q9>s/+C{^門|`%'v fKtK@l>[{LnyLnR}N-[|`%'v fK̖2T} ܒR1%% %-lɉ݂ROl 6Uj%䖜Z-yK@tKa%'v fKis_ y,Q@z07?ubOϽB5%bN͍)r0:qκlDn)h٦[ -i)!D9̀m7gAGnP+Aw}+?!b'S/D6Rh Аi2 +yKtvJ5gMͷ7:#>|{Ej8(biDx>}Q\qReBn)Nss -R\~5O[pu6d/Ssɲo6k tZڦf%lI\ 3B[*@lS--; 3[ʫtny-h>v$~l%'ѲM!$j79[r\[rCډm -9q)\!~N\W![ZMlS-ْD#sKjq٢/C-9I!D6Rh%U8ˎtQsM/C-9I!D6Rh&%)HqIu+Tn{ BnIbi'Z)B=9r'mو&CR\~5>7a*-9]=DMOrKNeBn)4rKILn_!Ԃܒh٦[ -RD5[jL%rK--9m --E$Q3q- $Z)B#D䖆3䖜D6zncUkRD5-y]Q%rK- -nu!nCډmRm3%K~RqnR5-cV,E_!Ԣ`n-5o^u|c>r7ZH!D6znAgUR$5-gKףK?Z-ջ6(gʘ-a0빥TgKŏ#$QRْK?Z- 9[ʆ陘-@n)X$j6[5[{ R⹥fKY[ϔ1[`B#DL%rK-䖆;fB#DZCnEҗ.:~1[`B#D䖆|@|Ǚp-44e̖07h--۔RcԗGn)R-9I=4gJo^sKɆ{E9ٔ<#{LsLΖ2>o)h٦߉r]lR,5>%6#dRm۟Ih90 A>>oIlSvKΖ-E!Q՟ԬUS"ĵ J{Z U Mh=jϭZሖmJnR-E$QsRlg"d_R[9$Z)'nNFnB"9qo#r&ԢvR--rK[HfrK-- Ԃ[r-rK[HfrK-D6[ -RD5- yT-yK̖0$j3}-- ;-e|:ωcTrKI`#d_ҐXn) ~N\h"i83-yK-۔NrK1ޒ-e"sܒsKޞ{^yKNex'.+JJuT8rKN5>|^񷇈-9mJ'%fKU Df'䖌0;}[r-۔n[%rKQHlvrq cv $Z)B#Df'䖌0;}[r-rK[HfrKF>-9m --E$Q%#NcD6Rh"ܒfyKNe"[wP\~5x]Q%X:BfsK9/95RD5+N\k콄cvKR2$veb=#(*"YqrPe˽cvKR*Y-ȟ*An)"'kκ%ܟꂹ%Uh[ʡ;[-E"QHѫ%Uh#$jV[ -Iq%'ѲM!$jV[ -Iq%'ѲM!$jV[ -)ܒh٦[ -RD5+N-8}ܒh٦[ -RD5+N-8}ܒh٦[ -RD5+N-8}ܒh٦[ -RD5+N-CMnIlS-Fn)"'BR>zEnIlS-Fn)"'BR>zEnIlSRU"$jV[ -Iq%'ѲMij[RD5+N-CMnIlS-yBn)"'BR>zEnIlSfKuf- $QRHG-9mJs-@n)"'BR>zEnIlSWj-yDn)"'Bh&$Z)nR "Yqr@n)$W䖜D6[Z3[3{Fn%''BR>zEnIlkZrK%Wo%O[?%''BR>zEnIlkV Fn/rKIԬ89 RGk5%'Ѳ[" $jV[ -Iq%'ѲuH͟#-En)"'BR>zEnIlkZ%rK~[Hf^[r-ۚFT$jV[ -)ܒh4J䖼#D͊rK!)N"$Z5RW>o/rKIԬ89 +rKNe[U?ܒW"Yqr@n)$W䖜D˶ْ7rK--9IԬ89 RGk5%'ѲobeDn#rKIԬ89 +rKNe[?%-E$QRHG-9mMPlܒ'"Yqr@n)$W䖜D6hЛqn䖜$jV[ -)ܒh -[RD5+N-8}ܒh z3䖜$jV[ -Iq%'Ѳ jjG<"D͊rK!)N"$ZM;ܒ_"Yqr@n)jrKNe۴fT-[RD5+N-8}ܒhfΖ^[jAnIf^[r-۬U%rK^[Hf^[r-۲A)oWoZ[rYqr@n)jrKNe-En)"'BR>zEnIlz#ԂܒD͊rK!)N"$Zq"D͊rK!)N"$Zq"D͊rK!EwP[r-8>o/rKIԬ89 +rKNeGn/rKI\Arq޹ɫjrKNeGn/rK) %'Ѳ#kܒhƑ[RD5GnIl-En)"Ś#$Zq"b[r-8rK~[Hf-9m%-EX3|䖜D6ܒ_"R@>rKNeGn/rK) %'Ѳ#kܒhƑ[RD5GnIl-En)"Ś#$Zq"b[r-8rK~[Hf-9m%-EX3|䖜D6ܒ_"R@>rKNeGn/rK) %'Ѳ#kܒhƑ[RD5GnIl-En)"Ś#$Zq"b~BM*=Dl-En)"Ś8ԺǎDѲ#kల[r|7O6ܒ_"RO~oYu{O[,8rK~[HfN=6ܒ_"R["$Zq"b7y&fKeGn/rK) ܒhƑ[RD5p "Zqkމk=ݒVni|PR-Ů"5ę%:[ْb%ѲrK[rRC#)tKe'-?'̖kωs-8nI(%'Ś84ύ mdTd0[rRCNnIlĺ%rK 䖜kdR1ݒ`ƉuKI%'Ś80[r-8nRFnŚ8[r-8n9`X3fK.e'-[j X3rK.e'-?'̖klEl$%rKk@nEl$2$ْb-mXDnܒb-mXTd0[rR%Ѳ-e -P%Ѳʜ fKN5p`"ZqbrKN5p "ZqbRslIf̖\D6N["[*@f\D6N[*sN2-9) ْhƉuK-9) ܒhƉuKI%'Ś80[r-8nRFnŚ8[r-8n9`X3fK.e'-[j X3rK.e'-?'̖klEl$%rKk@nEl$2$ْb-mXDnܒb-mXTd0[rR%Ѳ-e -P%Ѳʜ fKN5p`"ZqbrKN5p "ZqbRslIf̖\D6N["[*@f\D6N[*sN2-9) ْhƉuK-9) ܒhƉuKI%'Ś80[r-8nRFnŚ8[r-8n9`X3fK.e'-[j X3rK.e'-?'̖klEl$%rKk@nEl$2$ْb-mXDnܒb-mXTd0[rR%Ѳ-e -P%Ѳʜ fKN5p`"ZqbrKN5p "ZqbRslIf̖\D6N["[*@f\D6N[*sN2-9) ْhƉuK-9) ܒhƉuKI%'Ś80[r-8nRFnŚ8[r-8n9`X3fK.e[:cW= ϫ|p۝*[2ඏIgfK#8CSlp$%dT??!-5kn CEˆ/sKX2>HvKu̖-#{hْ Kn -ܘUyKH*Z6| yKX2>uKͷ0[befK.,$%rK%tNt-a -1[befK.,ĺ%rK )=TlBnɅ%X| %fK*Z6|a’A["[BDPѲ %R%fK*Z6|a’A["@n CEˆ/\X2>uKͷ0[befK.,$%rK%tNt-a -1[befK.,ĺ%rK )=TlBnɅ%X| %fK*Z6|a’A["[BDPѲ %R%fK*Z6|a’A["@n CEˆ/\X2>uKͷ0[befK.,$%rK%tNt-a -1[befK.,ĺ%rK )=TlBnɅ%X| %fK*Z6|a’A["[BDPѲ %R%fK*Z6|a’A["@n CEˆ/\X2>uKͷ0[befK.,$%rK%tNt-a -1[befK.,ĺ%rK )=TlBnɅ%X| %fK*Z6|a’A["[BDPѲ %R%fK*Z6|a’A["@n CEˆ/\X2>uKͷ0[befK.,$%rK%tNt-a -1[befK.,ĺ%rK )=TlBnɅ%X| %fK*Z6|a’A["[BDPѲ %R%fK*Z6|a’A["@n CEˆ/\X2>uKͷ0[befK.,$%rK%tNt-a -1[befK.,ĺ%rK )=TlBnɅ%X| %fK*Z6|a’A["[BDPѲ %R%fK*Z6|a’A["@n CEˆ/\X2>uKͷ0[befK.,tKM8v1y.ZrE 6nˍ[BDPѲ6mzfϞỒΐ[ralI%tJt-۾ZTǙn9b0D4m3fX;&Ԃ:%m_1iZ~ -rK.,fK& kz''u׾9O?gE==EYGi{[FGCMv)ҍ/La(-ٙ$vKޚGG{h4FE=?6 -^qfQ=~^{E/2%ܒ_@n).e[ -ܒ%ْ_@n).e[ -ܒ%H/yK@n).e[ -ܒ%Ho Y@n).e[ -ܒ%H/8?!$k#-%R\&%KF?U/rK usKEN3-9 %y'R-elܒ*rK."%-%R\-"b([R-elܒ*rK."%-%R\-"b([R-elrKA[rd-En)_6-_2"rKq/RP\/EtK~[JMn)(rK."%-%R\&%KFݒ_@n).e[ -ܒ%n/rK -EnQD[~䖂"b([R-elrKA[rd-En)_6-_2"rKq/RP\/EtK~[JMn)(rK."%-%R\&%KFݒ_@n).e[ -ܒ%n/rK -EnQD[~䖂"b([R-elrKA[rd-En)_6-_2"rKq/RP\/EtK~[JMn)(rK."%-%R\&%KFݒ_@n).e[ -ܒ%n/rK -EnQD[~䖂"b([R-elrKA[rd-En)_6-_2"rKq/RP\/EtK~[JMn)(rK."%-%R\&%KFݒ_@n).e[ -ܒ%n/rK -EnQD[~䖂"b([R-elrKA[rd-En)_6-_2"rKq/RP\/EtK~[JMn)(rK."%-%R\&%KFݒ_@n).e[ -ܒ%n/rK -EnQD[~䖂"b([R-elrKA[rd-En)_6-_2"rKq/RP\/EtK~[JMn)(rK."%-%R\&%KFݒ_@n).e[ -ܒ%n/rK -EnQD[~䖂"b([R-elrKA[rd-En)_6-_2"rKq/RP\/EtK~[JMn)(rK."%-%R\&%KFݒ_@n).e[ -ܒ%n/rK -EnQD[~䖂"b([R-elrKA[rd-En)_6-_2"rKq/RP\/EtK~[JMn)(rK."%-%R\&%KFݒ_@n).e[ -ܒ%n/rK -EnQD[~䖂"b(-s'/\0wu7.~FM-%;sKnZ̧] i'Tv-+%1-bxɒq-uKϯ[";sKnxCl'TR[u_|[jo9Κ%73%b h:4G-IR3-e䖂)[wKsL+-!n~l)#$;sK M=Szp<ϖtp"Rző[ -ksK- M=S -F0["X̖-#T'nR \/EfK䖤usnidrKA[rd[J!ωptz#+[?-_2- 4}["wt?IvK!b(Z-fK)h`tp-TJtsnido)j-UsK|R䖂"b(-Տ-eđ[[ -ܒ%blqq䖂!4-On)(rK."R8%u䖊$-[ -ܒ%blܒn-w-e䖂!b(2-?-nIn #ӵ%$-[ -l{%|H %[R-elѶR rKA[~٢m䖐n/rK ErK--!ݒ_@n).eo [rd-En)_h!"%'KFݒ_@n).eo [rd-En)_h!"%'KFݒ_@n).eo [rd-En)_h!"%'KFݒ_@n).eo [rd-En)_h!"%'KFݒ_@n).eo [rd-En)_h!"%'KFݒ_@n).eo [rd-En)_h!"%'KFݒ_@n).eo [rd-En)_h!"%'KFݒ_@n).eo [rd-En)_h!"%'KFݒ_@n).eo [rd-En)= _ -[*Zċ%-%N%ۨĒiglrKA-5-a׻e),EtK~[J@Oj=OY;>`1ROJSOqm0{F:{mԼHDžsK#]MǖI8ʡ[RC6*d/RPި- zܾefK]n/rK pvK֎kKf֬kԓqȟ*՗3B:얊OdRע[Rr8Mn+e[ -l)h*KFݒ_wŹR;ܒc MOvoc<O`ċ%-!N܈QfKĒigApMP/EtK~ωCDhċ%[.ѲXX2>-BtɈ ’n KFl tK@]2ed|[-%-Dh@,,薀n!dDba@t %#Z6 K%[.ѲXX2>-BtɈ ’n KFl tK@]2ed|[-%-Dh@,,薀n!dDba@t %#Z6 K%[.ѲXX2>-BtɈ ’n KFl tK@]2ed|[-%-Dh@,,薀n!dDba@t %#Z6 K%[.ѲXX2>-BtɈ ’n KFl tK@]2ed|[-%-Dh@,,薀n!dDba@t %#Z6 K%[.ѲXX2>-BtɈ ’n KFl tK@]2ed|[-%-Dh@,,薀n!dDba@t %#Z6 K%[.ѲXX2>-BtɈ ’n KFl tK@]2ed|[-%-Dh@,,薀n!dDba@t %#Z6 K%[.ѲXX2>-BtɈ ’n KFl tK@]2ed|[-%-Dh@,,tK+[ܪn'v6-[Cn @%+btݼx2v7Z~U_8?uw[og~kz~ [:F;m;s4}o8]msv/{{ɗW?߳/˖=>u>x'_zfNn5;y?WHѣG/[ -o>uԹ޽m=9;gﵲW_xW鮧{(?o~U-Y_}M>}ۂ[?ޜn{>vE{nnTO?o/>[w]r;6Y’!w5x!W}[:z% *]wuOFH[_w|sW׿𮯝]O8i'C?ϻ.ɿ,7u3/[W6=6U9{W;7xͩ}_7ʋG%g^|~g=>r#74 *wG?%嫗ӄqrޱ'^{.k]}y7_ܥO?wKGlG~qW<לĞ9gϾ?5DԿ9λ={|֩GO.FO|/f٠nҢU Ju˾t=I;{ɇ_>_=6hoطkf{e{-g~}>=:n˵r~_o0nr3_ӯ7?_}O ^{ƫ_:9sW77'~f_Y{-7oG_sm^q_1'[-xc}N˞ÿp߸ᨬŇ׾mb\tEuu/nz}7=l^OZtҽ[~j7aL{W}ޓG O/|}6p_:}ƣ87=x_~W7P/,_5_%{L-?F| tL?y)=Gӎةl7H~@[%R *e2W-nl2%е[%R9[%R{i2R;u*etKjy33 -endstream -endobj -249 0 obj -<>>> -stream -x+T03T0A(˥d^U`jangn7573t B%+oW -endstream -endobj -250 0 obj -<> -stream -xڍTM0+,-D"S;>iv&+T@ОL T97C#NPZJlXZ0ܒ€b}Sӹ.//m@XL939ErqP Ƒ7J+\l yZj jH!쯖~ XfXFkVZhQמ<4QmYUXBNQ;"[23]e0GY{j0>/Length 67970>> -stream -x E$ISE7Xc(4Bnӑ?a5г$5B_]z|FD!*-e{ b{)wڨuio|(ZV"QcNWQA\3S_}Ϋb[sou 4.Y2,韒&Mwa{[ 118J,3eK"/z}߯fU~Q%"T敱FW2|%oߋh^IYwV*ۗX ?h!!Y뛧 ̝9|$T3wBCfcyP$|N$7jH$Ϩ)T0",+U&:>;@:M:P$"#Z#!7 -:: !@@޽{ ,(Ǐ/]#~yRR_G쩮:(vO!Va~o3[si N*9a3ˀE}Kn>ҟ=1 _зs!-,-#ƋjM䤯gMzRa_e8B&#v a_<EuP9ly]# Kvیr =](~5R~0/GL&+S+op߮c5}n&J*|VXԾ=@<{L҆L%F[{:$dʷ>4O\YB\qjJ빥DV̯"ԖWQEddͧFMFh*Dˋ)"2M I+G&SPh$msJBF@paoX'#% )Ge2$EBa!;0Fw}Z tS<(H FUolDiZWyw&Azq3E+U0RRb ++▒bd]!Kj>mGI>xĪj*8먕IZa:I(Z -`s̤f[ _ K:ѿ -ʻjd8%:djmX>Z6P IiI`ڼ3trX'taƴjyL~%ժ>N˥1:$yAȻ;8<+n}D,YUafG6}_"ϷATm2.?OH+oP>P;Cr6UY,B -QWV\#-͐,ִVZXVZ,9Gy͹# QJK2(f 6Ŕ!*ޠuGeI)QPFI<_cǕ =|xriepq.بxvsB$Z(;=dz9}*Z]5jq2Z ^l!CBNKJJRty rH}.ݒK<2=6[g\Ypb5ŸGMiնsq#ff5M8]zяP+_TZOҦGJe4* 3W#u~Zm ';YtxzgSqg/֥Zo]x&b@ѦFq!w=yz6U.pn Q~lgAkދ%[çFjȔERo1}}i'koʫ:i„sVnX;@s7AԜF#"Gآ4WL!OO^Yo5w\wH݇]Za3pnƓz Qjsps(v,#[`9_%>g;[Jʇ_c9&=2ƙ 7Ś] ZD_Š̓1]&ể]d"FO 7oDNNUU.ɖ`h5W^ȕRh.KCkW݉1!:\\'Rsmqd5YDs_u}R;3_e13n.ѡ l>>s0r3Ci:5c״tH9d\Y7LU~݀RuađoGUyDq/x]b}U`ht] ܿOi CCptYoϋ[}/sZL~Kiم4˵h2"*|o?/࿟4IuI8F-ꐩ7LL7 -q6 A1O"<-Fo /BV&Xʺby/2|o#r^|6bTxaGg~/vd1:7vI);ՏZ%E[h9~N/Э&qTyL -IچCUy3kJنNتoyĂm>ECMF"HE f[cF /FY]{/Oa7.C̕Pdmt8Ce޹z9C+l2#59?4Ymoë0HZS(n4PpK` -JIPRD`9r+MWyyW=⪪ 8<z![TS#֬V7%2 -_z5J!~HX/~k?P#*M[ ۹{vwҾtREq쒇MR.s0l6jgQϙn ;y3h"<m $2Q .DV@p&oqar+@0;W=vLI:}or#69p3oǓɨŅپtzkNG)!Qr6Şm!\|`OgoG;RVߧLn;5\' .A[u;=g{81lNWyh6C PZ9o!Z꡹iBMӸkZ[+ƈqΌh Xb)* )#xC!+.#ƴ^brR^GSDV 7|4cH|ĜF쒍fDۀ#0G&!Z<`=NnBY| -Eٿ;w\J?F8[N9kÜ9t8_!Saɡf|7_)st[iȸrlÙJ--$Hvvr|YQUil;ugmo-PYRRKexjJ.)Eʰ]w%~ 3_oMƺxZ_T###,jТrRBrӖS%eT~I6(]S死_?XsjLqan-x6@[3;tȆN>M.#P;`I@=_!{Q<=]B@>_qX9:}0d\qvfn)Gv_fI@"?7t Ř^t/[sA0_e@"?7PHHhƌ}HП=1 _з!9a3ˀE}Kn>ҟ=1o޾u#v:U~@!t! @t! @t! @t! @t!#%%C&O'A -矾INN`@:C{:Uיwd>vUX6S$AERܺyGڒX CbTu=!ח֣exQD#Ϝ-WϾ;]'CtH_2]RdW\/Z?T*mAh\wn`GXyaRiap wmX+uV!sEՉ~b'QD}γkLɕJ@T,R 4PzH QT*˙6[FBLϟ"CQBNir'}.SQM3Q˗/oCE4ݻT|r{c|9n$}qv1BH -B7R//HJ q!ڲ$?;n3blTq2:|QAӅ(4J iEwnq -@7WJ)-疒f>&dʷ>4O WVC+va['T[V\E ): -""I\i;g-:<4<|MKJdSR['9S; 䀣uH*N5)оeYW;~GFKeaKdivE?ul9>CjC{mwQqZ9Y"mzhsiǞկwl=ow|"5H$Rrmn.'XBiew$A*RyΗj%%J)V6ľu֖7dUUD^iJ{)D뢽G")cjH"WQj\3am{ܞӅMTCdW'!tr,A}_"ϷAT-la;|z+cj&h7I#; - -Y!x/!!,g؝?δ,#jSuHysHh͏*U 2BNmEJRK59oꇆ˨SX|P[G.[Ѫ@jSdӡ2ooGկL4Uޮ׻;0[aM-$X{lUBP䢫)Մn^­3 ,>(@*llng̡ɼWL^9XM*nnd5M!]-NL?nҬ])ԇ;_e}ur%CB:B$#1T g雾?{l$ǤX'ѻH@9yA6UG:y%K8f>l,ç\:Њ1U\w~ D -'7^ '=D2/-:% 0$FK#+&mdE]Y$wK.M~:GH -?|c:tzǹBүxY{cp^[8!]աqFB:%/gùB7ME\o'j/SBt/mzp鐶PجԔ>r;oG_ٔhf,F 6OEl}zgSqg[ԥZo]x&b@*Bh{J=l:0fQ3GMs%;嘳e>u~b7"[=}=w,xtFcomh99]Вd~sRѦJwh ljRmM6 -v̜ÈG.^΁߇}HÇ_, 5O;|VN3>ƝvIL2ҿd[o4 &l7I]DlR:`yb~'gc VHPZ Q3&}3j8/*DԜ"EȪȵw>;@s7сM)ǖUed?[zŨh{jsc?xҒEu2;[.2|Zj>V'W߰<1tm}DyD{Rڲfwޯ!?h41~@u’?9, -F!=wwQ .l3jӉat=~V% ܈[iƯM٧d6ICyB*R:c2"|s΄ώ CCWJ&V3֖WCxE)?;C4MfF8a[u0C3 -IdmI;XnQUGOX먵]_8-1첤:;*6moë0HZS(n4])rwՉϻ?|WUMaZX߶xDF]K`A/`0g h3jy_>5S h{p_?ֺ,vSfU~h<n<&6SS4F*Hk 1}^¦?밆KdqBZ'{;IP/)m;CmvOFbd^Z!baSDapzz'oqm~3a2(Ԉkv.7d"(qG -OzA~v85~t_!G^g*W -g˥:=q+ ۱uUN]e5⒰ǧ  ޥGNHHnyוV~wӋIBSg;h ITݶr']S=(D6^ + z !@g֤v M} У:!\pwo3b= 4^}['? B !t~Caa?Auu5w:'[ަtt= @B14=5ﶯ0|[DqI tJ// ۺ^6.ۍkh]=;ZwLk'g%Ov{vkD~ڠs'uI7#拱qGzBoDEs๥UvQ_!6 2j;K.%';Z-aGH3U@kWCyC#7Nya6K/<떮!x{atPJ>>zLU]DqW}[r σyǿ.hQ]ees>J-)q礀zbR3]u?&.Q06gޒ7mh%@I/ꧨTp yf੘Q!a #?~j=|F69ןWy-U3&>0)QE# LCqk]u!>T^Rő&DZsI>v?1?-81f[m1+Un65.˲~H2S⮹'͎&3xf/(ek:oFPE 4i^(#SI|f>l>[Ӟ{HE׭7K<4KŢC֚9.MW&q0!dj7tȚ#ozmμ9-+0"Cg^)6Fsꊸq ry}y ]=qkU~Eǖ{K%zMBvܮqӯ7{dtC8e&sJvRôte^Jz|qԖN"ˠŖYԜj#51S[5;2F_ۧʃu͞Z G^L ۋE;V,>٠ڎVk9u*u,;hS )c.n!R] u߰B(62d/z˻)fנz9Aܦ f|rG.Y9wK&ԥ\m6=%g}yzl'7R契/pw=w~VQNGa:$S:4h-wF*fܶ"e3O-K̬Co}ÖT5a)7pJ,g}u6:k àCl*1Y5{/YM>*X9NčNEjeJTDocvVP3#vV9c;[ a:lc5h(jq#;Xzsx͓*_,ך~}J)uqQKD~hls/~/ [s)[XE´]}̚>F -Tyٴ͟&2M)2mOXۥҊ@]]~= Xt&{/YDj7ί-71RxU7o?Nk:eN+ -MLVG K]SAX3-w']Guܰmuh{YW(vÄG}[.Y%\nOi)v#룞t -;q{o8vKYKic"l28,sUdgi=ҋawTFɢ\8|fއfNizN -F伪:]WqWg]U!= ->P6tѩBEmu=Smu#FUFK~~3G#jX/+*\f\:B[;̒Szo4ϕwo 6;ꡉJuC0WjcxE`sw>Go?5Nk l]jc-JƜ-uH.wӧ![ϒz=PcX?fB#R"[h)Y۴+ƛmVSys^N73,pbgm;Srd [muږrӾI*b3VmTW_;o8=@UIDg{9w~*%PPUFc86@:~C$?b>T*@@}q; MN%BTum;_/6£+r#/|UEQ]~pd5ܮxKsz[JՏ{戸]FPtMzDj#,YpY"HP7}+$*;UXyJMs~ÏZ2_6|3#ty\];in3dq%``ؽRNCѭ'HE% RvⱀW!K7ٌܮ1"~ȷtR - #Gڱ]סU˧WF#p_'c>\cܤCr_k/Jz둀qk.Ɩ)b;=ewдCs?<}ǚc=u}u9N OwotPJ??yƙO{< .JopO:s۟ "ʋ9;,QpgYt|Ȭ=^w?WG9eᓉo #{L˷`.Ū -JMjzvѱ)]gPet]xfzg֤l+wr%OOWņ/p:2_M;mE%VwLss;X>=g#+s%fjZ6rTSzuض]fmMS~zmM:l}z Bq'nam)}w {LSGyvT=ll.6Pӂ ڎrW86uv?k7[>m`!Ayukw.Xr2s.}h틊@ l9ڧiև>wvPϙ{&ZyX9v8"LQ%9!Jq=7, Ҳ1z|R#Y~Rm=NSVFY16I,S.S0h V?V8fI-מ&\yfW0tBIDڢlpKxi1WƑK-ni5>cxG3w~b._gwҽk^0|X㡟nqgCtqM;ݺc)N[xlZio;m;eF9C;i;K8"~yr;^vڵt'pf@_}ؙ.DA(wkZĠúv^ح]hƁ 6|+h+ -+5yLrӯڦ0UԴ550}WKY%r׿Qu`Ghz()B(b%m-=c҅x?ک[d;"σĔQn2UNQK%|< 3XpO|h:tδ 3n7ʂ]җ_x,0m~D^٦mfԑ#3*صs:Լ0sHDimxz:! ۹xڎ2[O0؅ m1;h;B'OxeKQFQ[~-k7];^I[Җo:ĥj?]kcl8*ir'ǾO JpRʵ4VX6-|\\ݯdqRsPV|{՛W}QqÁC#_#Lͩ .bK9*EGf^>nܕQ>8Qw\G/N~y+=|4"H笆M?39R^8i;e8uneMKkߛ1Tܷ]Xmz:a'!r'J<Ν{O3]]o~"!WB|ןd 0ixr_}C6(>aqoN.,tCmT# -KWyixl32xBwCulO-BݴP -TJIiel[O q.F+"Bn}̙ o -Ȕ%F="νln-{'J徭_3h7ae󟆝}dAH*hٯ|ոw~'_,e2/dg4E][gHSK Qщ3n8e|_p Yc[tC׏ʊ:S;dԴ$: -W9gKLƦ/{Wfqbqnc򛜍gO]UPgxÃ6||eΥhYluׯ"֓7G l@_ :' +=F"H?N{qrrAEΎ+l, ?/ Mʭ"L -r\˩c-|x0%6.kR Eֳ1`@ST&虔g\~#Nyf=sdjV#&qxcƬ>lH -ޭJ.GtB6IȹZ֎:Y>ȤAK;%&4dBы>G0p噈b/*o 25~ZW|x3̦ay֫m:^{6z}K {|r!cv"mFG=/O|% -~^)Q;:z Oi~E^'~X*XUǮR:cMT//%ZAo>BAcw5D+c>ذVtX :z4znx٢B1>W%W0&xvQXCi?-TY5UTAӡd7P \cQc]R*/3>SM%\h*4*MQ ;- gO}@ -S /bNJI"Gm-N07A4__c.!nӾԜ~czYͱƉXöFfArO@Z+hxCK]6?Kt1j[0#|?a0rstVlĔB@>4PIˋӨm&E_SD%9(GJ<vLObRjCƵ)DZ=݊gĭ4%ҫS!DLF+K,r"HXQ>ՐA z%_97*]dx(n$(F=QrCa6^쐌J vh:9:X%ݬ+RlG[Y"׊;bhGI[ j3dCJ,Nxfixxpd6DrX-Ƚ[2E3Z=|b7 -KM tȦ~ -n᠇ă%;CHñlbFG`CW1wV7ւ/\(+-½={2ϫ%vM/;$.w*.E~Ȗ)=ʳJE]A × )zE:iت{UČtdnDikJ#I\Gm7ܬ}Ve,0T\Z!bFY.}Ecŭ̿혨_ N@(9{$*N`5QEbvU>¶Cw ymYrAb{#soI>턛wT-m#^1JLpl5*bRѲ5ZpXarX!|-}WKV/lle["S:+ܪGf A6OZ!0S.:/T1CӡQ2Õr9qζF.=xB>3~-0{P3k)TzWJE> -ĝ}9|<21* -䥄mYK˭;\_IB ߊxg,f-%Tvy2Šig.o6yNiO)%bv0ه@~!?!{"G|㟆Ná1g|`S"uI{l{??2 KwK(yQ;Q@nD@.IinTT lESP]vُ ߽W(&ڣMpy&a+̅:GIHkȹ U_p&$d]KDF7~^Aj::rC~9>e - -:RC4O[ "xxWPG%rl9=!ͻirVrM*9^E- 8YsZPT%%BS/Y'El)Lr^M7Pt*-ʫ0f=j۟x9aN>Q*otI!$7v'v;%3{VZ'krD!ˣߎЮuaIΚ-IVkLfV(^Ymz-f;gHWW&[.o52%9F.*61g-GiJm=~q𪁢W|ԙp}LS3GJ" S,OT -Ct4X:D>sPv|}}A|٧Dםuexl^hl-˳Sֲf(X\亖qEl@qG̈McA:…cueEWo>"<$)-)yP ̙K bQpXv 9!dn2m4O -{O5T8=.cK}9xpfVOJ3]M - -ynljTc/ h~낋8yJ†pfr5ƵKl!ͳ >(Kd d浘O 4=KM器(yZB}76$pp0-75Ra2dkx}:+nvS:o%Ma jY"th4u, T48G(<^`@puhٺ/H`Aȟ!hC:DGpQ1p'%4(Nbᪿ5>tXb eec>t}-Ki_pt8&cKs9dhƂC2u8Y`t\7aQ[mѹ^~@xX᠍HjTyL/=IӚ&j衑֥ۨ8P_ȪÉif3amqZ1K\9b1*iHKz>\Ӡ],-YhiTdb5"uul;uQZ~Q *ަw݆( mgRkv?[BNw+yo$XQɱ&ZOE<2_r9*Vz(%Ӗa&$1L 61/?+Q{o\FE%2u/#۟Myy18uߺwY9萝" -wL 5]! BLl;'Dk+ m~8\i;dyaًo<^d$qZ&$wƱM3ļk H[=(;"Eظ-!SqۇaTb -CFԏѮ=N!R>)El՚An?aF^#{c摋>t!@bz -;o!`3\W\F=gh~4gQSC%)͎І^uOAHW͆~X[E!$!ݓ'x |eT3l,NǀD y~L,ug#>@eKJ'i -SMzG{$(x35F99h%eد}Ym ǴJ4^COri).L"9~=BQ߀5Vi1#N# OpχRLQGJ֫ڪ=KO9\6džvӓ-NJ﹒q єգ(El(@F﹢t\^!zwgu~uU&>R[ï1C^J3S9Zu ~N;ܼoIUV8A@pЅW>~Wغ5\=2|;AAĠQCBdT\4rO"{}RV!2MyhymFNЦM΃>/:M|W^`Y59f:MH_/((EyyԈ /fYsvhu(T@֓.8"̼lҶIvmwvAxFs/'nk<#&ms֕5RwO:F'*!LA8^oO5>䋅.CG^`F9ȚCLѱ闎\K'K$L޿@pΙY]61r\s(\aú 9u_24o м=dB+q3y'wC_DW;[-'[w%;o줴_K6Z$Q ̉'~uMdq@IGީ`-a*dj$迊۝OQyF_PUر?{!`i~t%//jy'ڃe.as_Ʈ*C} -r]8g"fkyx(GOCۯ"Gԍ"!w|YgFRocAE{M:L%738;oT2f- ]`Arv}Ì|;HmLq⎽+-wwErLc`[Nu'czCڢL5P5rq}eԲ(vᖵGаV0<_NiK-!jRںW?֠4䯾5#zبx-8[s4VH^ `ɴ&zfB"}e"t+UQ[Ei^{y5w -K*:￧@OU G,,9)?M{1O9VgqQŰ˧K5Qh,fԱҕk)1aȾ;gNܠT>`q< -N4370.늵X -qu\Uz& 'JŁZ|BյZ壳UzLUyٽOfV'^85Tz?+ñ|YnGgށrYx2GztkyqtDlv9I!d,WpCJ4džZ9EBMzv|zyuJDZ< xh(5 7W(Y(4{JrS -w:%xAbg?u|Ҫ ̸@%~ZTjN˱"G$IXe*y+ Gus:c~OCm2'̖r{Q'| 'k!ur%r*f&f#^:Í4(;;`&>(IsVXU٢Uͯ jB0骿W5POv(?CweZǜFtsr Wb"s:t(E> 5nա9y [/}.#"y ΰ&,㆏bXHF.3sGYJ4ZCɨPr:ó\{1y~B^(vPSW߫'fw_htXLOv=/)+HD30_|]֙*-{~'*{)zcy4:{^/UQ暩U1ɸ9g'c`k[8eX^v!/i͛"3_LZfRZ%4;6odU3J$]kΫvq,&QȷkQ": ZlsJb#j>ծN~T޹z0EOBbG`߄aEBMltȎ1!}{.o{uXtQlѧJrԥa~n;'\B.:+mܺZmF„4|{Eh;0ߍ.L˿/=՛c%!?il>6CN?@<ٸ+FZ衁[Hetz]-"Gԛn$)}﹊p*&|ݮ{*bx#4NW no7b->QS$)zI GQfbDߧ>èy:y<8v8-V/f{iJ̿OMkC-r;EN srLV!jJJ/7E,7qi3pŞw6O= sΚ}#jGQh#Aaݤpvd`Qy~X^l f`떓?94;Y-#;&"'~M{\ńh)`qɊS1})a]{-?GLGƏwzxһ#0!?`dӓ5u5X:DՕ])Q\𐤴A!+0!`E !S'c-s'!~32c PUq|6/e2<:{Ɩ}76Ww]IU2XSa\;thV©<NDL6Qi/o^-*kS- mmbRbSmy&*J^tߍ #L]<_h\e&Y$%5YuyպwF{0b(`ÝРZ:墯@%bQv\fA16CGݷu׮j|Wd{e*c^21Ú?HhcFnV'䬚[Y>Nָ+#=MXzvԒv^:ZGjTyL/=I]PCF.hʼ st`:f+|5l~ul!b靛7nܺ_ sLIWK:,IݯJ])kU¼kZdTJj#FϳnEi\Nn%$JIfCvY[tS66DylHn;#}Ӗa&$1L 61/?+Q{o\FE%2uv[{&qRҺ?o]ջt gxm.3 {a:D|tm7΍.Ifkjm -v ȷVwM)!c{͌w0 o#?d^Ű.~+0!`Iin뎰;ُC=!ajCHaD{zr5f>̅N>q oDA&%ckS$樫@[\N=7e -Vp&^8lt+?0ٯGh7**)4ER{C\8 -+H)x(UmMNUL2I+ f*/}ΆT4Bc]1y!tX⠐ L۶{R-/)HA)/3rm|QFи})񱢳ssLxϕ;\\LǬE)bC2z6K - {(ZR^"fLC,,!7ChymFNЦMO?5w~մB q{KSw GMOvVx6a_H`% -f\OK( sM~3WiUNZf ԋj1:D!ӄ?0tX*o]P#.L/th|ʗx-z#Q']p:QCWsk>!S/v[ҍpi/>UgҶ0g]Y#~c,DɎϐ|Vwܬ^g%?w5Vg%?z_CWp2&:ޞ*c/!X/rŪ xQ|>f~5=tK2/{ڟu%n0#!(σLD3 QA9O:|b=Eѥ5 XF 1;Q{Z03a-a*dj$~WDGԛK,pZ{Qxscن]M{$ 1K?9>(i7<[ dvLphz;/ kۛ ih7wVմ3z0xˠ=q&C~Qw{ǍBn6%Wb>,C$nR2ȕ!=q5;toY@ VCCw;8nyTݘWo0!!nَ5R['D\coh.J&-]wQ5A7Xb&SX萶(@{ boez_>$ -AC9]&u8DBV.䫦 =ar/)XXV[QV99+1&un<ͣus➽yʆ s(Β ?1B J I33iQ9%/ǖ8&!~`Mq -9[;1u8D/;07g1 I5CZM:X2Qt\8/aCT™oL5b̖܎`- wB-NVW5'j](:Jx&uJ PдFvS.g<#^XcXitޖU(pFS?:ƣ6 "r{b$Ptxnn1Òq)fK4ᖷ![ixo]gq̎;NMieGib-]UU>Mal!֤y˞hhnԡ8{䗈;VZ衁[H崋K]S;*^48QJ lR oj!m&7X3Ez>j$eY/(L90jN"Άo8N@r)ˆno2SstD.J`e.~/>@X7)x5ȄGϒжtWȲQIpWfZ4_ύ>u,)@z)p׈3GQ}[DbpΖuދaُa (4c?k[`E8;7_WN>e ({!g7u'.x,s7bl,Ê~lXS \KYԎVP~;{!^:MP7:EK}d#PǬ{L8(H\OBN r]K C5MDZeIBXY Čܝ| t:uMCS"j.n˩nw&{>¦ )W0:!( -KC: 'Dp洲So!JXKv_NS弚nj͡, TX[ǕWa$|{-?rlo݉*WyH !;)q%x)~3"=Yr<- zYgo$-"]n`š jéBcxIk -VCopˊbL1z8)(C] -7\#GJky[m( k9u E}rVbBEVdŊ].KͽC+dmF*pӬuUug}0X{%ֈPgOE^LW uI<.AмY娰-;bJт,$ɛ+dFt8^yZռjq-;'uUEN}G$h-6|.!Ee 癆vվt'!LHYL - &$tXl\o&|-@/=EkŗRgu8:rs[3+pަȓ%o:Hyvkx*rMǝ /xup4ǎ•kJ%*13͆h%mڻ<"!f.z1Z? ]wj.233xgE}FnoNSYj #7u{(=~E5OG2W -h{NRƊϹOTP2y-/DA|e:1cyyofԙ!9XUWp^_u W&Xkn&YFËN~=/j:Z'~]V{$e -sQ6:,5 -.xE)#f &D߱sPX** -\:ԮɡA^m"16UzMKUU}9!59Lz-Jj%[=awDQbG}UIbsIѵ?EAMauKQeaڡR[udjU#_-u&yTc^~? gV48h=q*AYA겘:D>sPv|}}AK;m -:[g;-!6+e^Qu-*ـZHcr/I7DVL4?+5,<[3#6YuBՕ])Q\𐤴A!E|C=X02u2ANL6xe޸|w NR_teLWa/{{K=cK޾+aRю4i[Ty .Q+ ÙgN/ⲕp7F'.=60MT˛b>5(/O,6Ֆgj9 Aؐ>´@HːyM3q문ENLB뼕L7%UXgKL4u, T48G(<^`@puhٺ/H`AE "׼::V!D<=$;)Aٵt:S W)C1(;.G㇦hi_"4Hć1[!C3ůw{䒶G k\/ڲ5oZ:ēǒvmd&G⁻l9f 6>-xzrO׺6GZ_#^n*nX]pZރ.Nbv8:O=lQm) aQR?F;Hy`Tk;eŌ½F^#y*9\ptbP >NmWlzkRyK?y9ˈݺ˶-}0=4|6a d%'U!2g}id`b#ˈ+xnZWSEpP)`4ꮙϐJYV6 V[4c bձoG0Uu?o ;?ڳ=bv!6ƈC#=B -_؟\TtgQ' V *?*0& ~.':6H N+ tWRo!~ x {t~!'; DT_o67sae :!O0>>t!@h}ΆT4Bc]]d㬜*)Mi)SQX[E!$!ݓ'x |eT3l,Nǀu/DIiIW6PABC3  |HTI, -L F,zZn6?So zsPR'>g?^iLI9=Q<}1'"zy崙 +u26ʡ7R -)Jc(vf䧐?KtߞL}v^u{o; .46)(][J..&DSOcVNixqw4%*$1RSYrL9#? -~TeT - -](&|=/ Kt8^w}ŎI[΅#SηÝ:4h$@G'*U"#3Zc{GS]R:mpqy';_< -u/3̈́xEiBrPDA?T.˻^z-TBl_?> N' j*>b.nҶ0g]Y#~cu1bB1T[303(I'OHvG^`q5{/o4d*f^.ґkzzzd^9?Ka"FCQf.z1ZeF\44Jc=W/@ưDA>oJUx9~KK'(.~?9Pw|ZNG50WIi\|5l#NMY1 Fhs]X-p]syIqߞW>{5/U(*IX+@4?rA2fuC7|:},k2vUa~Sv|ˠ=q&C~Mӛ >_!BskWL`=\hSXAf(~R #o08CB>~aF{kN&@oql]ĕMZkjc9nLy~L5P5rqg݇D!(8v8g Oz/iSr5iɧpEl%!jRںW?֠4DxubU#N:o+ -[c{s:\\Ù:=B+(*.$_DV^VVt#x C=V1tT ? _e^[7?p)R'h}ff%SqʙrX˞kA^wΕ]Yra{U NKq8_ ÙJ/?Փe{X|}b78_@S]K.:M<*~bg!^$2?xkBQÏLm.]ws($~Q''kitYyf\C?-*5r#$@L>/pT6opƂ&bfu8Qt\8/aCT™OB?C/94=w ](1Tofಪh{^ dV N6 r0A?y!vfC;Ma:c GqKT2HKtX [_9WX!O;t <܎Yv*kQoMYk|vVH\rF<0jgR̽F\̣p*&|ݮ{*bx#4NW no7b->QS$)zI GQfbDߧ@!lt+H[:l覛()3>5G7M~B3Bqf" -޼hˁ䘬&C/Ԕ:7eb_oqPI-RpJKfi 7͊?:ZWU~ / :^,mHL|dCй,$ɛ+dFsҚ -!(0bJ%֡yQa!>Z"ed}ζ I:EF%a<ЮWQV!̈́.؟DiB2PDA?V+.*ٸL[&^z֊/*φ=qq<2j+k!tA^H71&2fWHM'}KtM2pU(;^ J#*i+טyxUm?J% [|J;Tbf J?V=w%y>e#D C\1\b~pH]egfwQ-m^JDBDEɋqQ PP;ZD@.)AQQP k4RͲ~, 5.e=3sΙggN!* vi{W~9oWZ,m]nՇbɆ&IYB?w\6$| :pyRɤb6v ȼMFׁE9MGl8+M}Xkn -$y|хqP5z{pKsX:*N @_/RWDLkqkdsBd; z={UWM5 -vjqiR[^j:UFio[z]YH-Fkgj(AI6 o.Ņ|f3- S-WEgq+Mr"~e`v f ` TmfQ?EAl(tS^n cTs7“viGѾdrCTրX:Dm:E[,.XG8dpgǩ=v:$Ԅ=96:!o8 - =ty֧Z^I= //~ZDu7*(`` Nr%A(ÛfcђLD,N{*<Vni,N ÙpSzTLdeBOK|:R_ 栵 'j]IBbu>ΗBYK^cI{;tPrV6#q]WMmP5s<.r/J=WZX[?6k|jHeDrZ=v:b670cp-ZC+S_FKY7Q d[-4xK.ojWni*cN2.͚ *zEl!y -dF팗tP -1͢[+j%3~%3]%W 6Ǟ#ԋVzVF>{9H+SRAM0^l$š|fbeV6M.݉xΠ\ZU[d=T2`ZJ5MԹ+bƑq[ͥD)>՜gnڐBU޼\pu]tu‡dU><~9)(yt0]XU](1xj`FuNռ} Lk ('=JTmX8q^pS~g(հ3<⿤8= -2 0pocAֱKi3E󨔴0=HOtX [k6M<6㕺aaagXN8 !m'ccPB]ڇ(]b}V0J|||zw\)ʍG\/a#{n`Ƒ ?MKj =SX!:Wdַ>q7I¸IUĈ@oicȲqmMNd ,k"YŵOQUOhF*, o>% *lySʗI*MF[5¸i( J}ۈpL/28oNL/NgGu"(_Y ݂>@dZ] XREt[gtK3ڃ|_/8._9t$]b%etU{Ro!~ g%<=:3o_MC(soĿtsyk#=HC~ARR⼵ 1C,w:/f ȹ=#tK˵cSU[r.)a0~}2j)4Y^sqV)]Ӑt }SmQPʮA$9 aS'eTӺSo /?@k`MR*\801V^%?*C/e% fglϓ4ȩƿ+N'[#ayO`> S.vǵJz#%#-{Tt"BeV lUt5`RZg#cƙh՗q|ڭ|g X?RX`+l㚶O;!`B=52N"G_׷M3pr`y[lPPe3ojjZ^z;+}5;;9+[AұA?g[Ixpޝ֡fp>O OڬMy(9dxiګGF}vxjmCޝp=Rr79|nݽcÊ֜H2smq;-&)7 mDxJ%Kd{ VT}h)Y2.s{#^J7!n_1E?ܤݸ{[? }U؊mΪ !bqPBtX_.ɹF/aYv~uiyE ݜ)femAc̵!>Es8&m[՗6Qz')pcN_]|isR^f"F販Ů^0>uvG_MCD+Fb B>p$1 DC{{d O`֡~VUkx5eV=~ ZaF[T "}].Lu_ҮOݧh3FcyfxԴ`^M>66KOs^8h/W[V3 -3scU? -r7/^{b!2X.acgg^ypNl5ުA 2]^\H$gA?uz(fHjz'K7isӕ_Ks?sׁg Ujv 3=~~E̞q{  R0WHˇukN"Sر?8M TmL5vêȺk2kHNov= ->;Pe"Q5N7^bVurGǹHwLYX`lQ=Q%gWOU~iG\Qwn-Kc4V) V?'#grL1FvwQ~Kk:aA+(,.CYLV^VVtO9!`> _ыYX* -~;Vc|t1{tEaWNh85Q6Q`Dwj,PkfG\NEuZ,w_p^52wAz^"N){~ u8[v1R]+N>2U~;TſL:Veq\fW5-Oa 'fø>E2tM's:l1qg wH9C~f[!$e¼PnReFh?2b .hgzY*a1Y;FѡkPs5 1ߥCD/tV,}?xꌿ>(D8?ZÌ3@OH*]-$&q\BNSq[ipt8! yV#ۤNK4ZG\Y _9кC&"TB+ilj=0 ;[L|('I_"b,-Jm.ip㲇巳sk}Z:+y*ġ#Fik?% (:8ekס}^0 WָeNxF:$lW)0dՓS8ݎo0:c+LT-XZQSo)ib{7z.]1>ɶ\lf ъ9QUue{[Ba"zXDGCvNRq9ZN;=\bi/DŢ.-bʯߪ$uOT/b nUn?fÁbSY{D|Bz@g^UV$e -S3ȑWtRe5?~)Nef0!ȍXLTEFj=,*BM \īgޕbA<Ʊ\edM"S7Iu1nƣʂ4%Pu5JP=AҷMD"jV\3P" u6vazv~ۇD!X M[[{Yk/e*IiəԜ7f;GmLֿŚc9Z_Zpi'aIiIC?<1,`9tXffQKX5G$$e =+úbt1:+X6dֶy(땲!8=|Ju -V!̍S1ztIN; {rltBp'zp #K;y?ghilk{x'XT2s9j5Aݨ^48ҿUD7Z7I3(YGȂGP;Iu:ɆpbXr@?̌N+e<| oe;Oyq^bnV5Zi*cN2.͚KjcFvN#'嬚SY>NԺ*#B8|/M:0Fn%۠kR4=y\^z^d6~"=)06zl* Kd`ˈ$g^[WojWnŻX -@!bɝEEW:IKfw%3]%W 6Ө@)s0P2*Rqb_yFK7bT3+z֛_,sW4M.݉x q߷basғڞ mDjC -iLBT{ns0zGwh$$*ڨխUAӌel:b"10uo˵}khodž _HN}.K!#N Ϩsoz-4w+ ;MXS|ìАGG]B:*roe}msRP~3ca&Fdg_<*%--.Cs@e r+T!SQe-A[lv> V2;&sr}[ϣm7ÊFi6 ?M;Nt0%:3>;;|խo1|oqyC}pot|:W2};tpïLX"@~a|N ۟c !@uHI{`t!%@e3cO 8 w. BdߣZJ)MiࣣK˵$[GHx9 9^_PT`XzIUjZVv "Y:E-5z[xaz<{iw\I=Z>:GX+xEO8{/:*xvRdY̪aQJ)ZNk]Rr)$˱,љњq[&hxz:o oA>>UzB'}1Ɖ|?u}ɷ{k9(dS)Ӷ.gd' =J͖w9@A)“9mlIFи}iтsLٿxJ}5;;9+[AұA?g[~xIC&)7 m?0|nݽcÊ֜H2%S+*>pꔬ~_{/v WR3oj? -Q($|1PI#\b -T>l -A\v[eȇ1q?V}3d߻0tX_.ɹF+ﴦNJ wȭ29M}S8E~jy>UgҶ[}ikq&hS$ 7k6DD&Y$+xboDp7;-2ptWYepc<-Wg~YʞKlAS/]K%K,Sa&}00쎾3NwVrvp?@4;mp$1 TDC{{d O`֡[+<{a+]p-d+ã:lU10\Ҥxzb%rpll6R|גDi&)ɆCsROFc -DŽ a-mASez0?h=ퟁAX]*uH챺_wXLhč3Ӈ/~x(ޖKX`j"U*Iހﭽ_@~x5''7I9rItdQNVBcgg^ypH[φ˺43}xixpyU^gaPM=~&}nQgn;OnOmatbTIdZ3kcjv 3=~~E;YP<5_`B\>,-kkN:8oOaL7a◖'LZN: S61M;Pl&fSw4"j :-П!Z;IQ;*xZf/ _[y3/sFţvwp޹=:4NJGάΙnwg쏃ņ%ZLkyîB͔Ct$,:YY?`P~W@Ԡ{zwI ."tʎȗ1u螥©"wP|]kA컅A;tbڙc9X|#og;9yo6ʊn]߁ l^RQٿ0phu°+yIJ4OUp../>۰TrzްlW\׵JYY&!ٚðhƾa׫FW.j|̆v"h<:wcR7UHuV:L]4*\G=pvfұ*5w~G0OQL} rgfYuJX4sC"|31jb%ZDx -c O:|#a- g>wlu\zn_[h ݻ}3jCơ:~[*+pƠۮ.!8*Y8!ћcl؈q`tXf D$gW8.!~pcq3_GdY;:1u8H';{Уn?l%Et&v{^&jY22YG8a}ؤwl}7{ʪXCubi!GDa(O˞sn<{,.":=6xFUWz]K:B6YY6tFǕ%t8L/d:ZpE\|W (ϼQsB.8%x"ӜLu$_CQՇ#틥9sOlTKj~&l~|ƵjH\bhCdfYq^vNޝ&ZMG$S -24;MV=;){YF UN$C#ZY. --Jf-M{uHc`~7UGcЌ,WM޷oÖ|?/b5Β7ɕ]aBW+sXX~~7&-R8u:޵Uvpڿ"ˇbb?X2Fg1լӂ w7"[8yR ?}9 X9qbPvKy;Nd٪yUt3߻BD÷UiyWco&Û;O?@$Upn+DV1z-JRKv0I<Orl3a}T̓=6ɞ.'tEuifװÌzWS^Is s{X:Hx)%6<:FC:y5tw>e É#9ՇK|S,j;lQ/2~b x+F/?Skۙ-b. -$} 9#QƋ8Gˢ:D<\HƾlG }]0D[`:yxW7߮&\eB'{)։s7>\t_,i$TZog땵uS|>jEmnخ4^CGoYځN\u6ԇ:~?i dU&(`euXn?_.:%-CHʵʧY؏|c!WoQr]Nՙnj05CHs%ϮC~AK X~P(C,w:@{uB{"$ /dWN^=(jw|vhWD^9PE7|"_*{ҩ@5ٍXj o#,otI%(;j-T[ʎS$l8zc>k^gFֻ&z#%N}VȘU|/`?_E|j>9KF3Q:gK9T=9aJVZ;a XJ٩ ZW.oZzv) r&(ѡ -Y7ft"_*Mܴ~/_odg]][MKܷQAn"xC@5W_|@s4/0Ij ѼqjI$0zg 5D6jE_Zp.Q{{E㠛_Y1aku^R)rj{S)(W - -n6m6Ns*s!9O܇tF4>h w9F^5'~ʻś+9j9+?>sSY9v)\ǓTaƱW~O }4s -ܳ/D" +f'[? -wz>2==pO_E]Zޕ_P )#9]Ϗ#C/7OG?N<܅Vq'-?*t`CXY2+oSqGtMXdI%*::wno'k5Z.dRۦnJXZ/7GQ5zGKJb5 &')#uT꧿FtXn GZ˯\)zI+"&~B5 ڸ52g9![=ªp`&Gz;4V r-^5d*ᢦf7Э_M=,$K535kzoDbI=3R [񩖫ۢIĸu -&9 Wn;MxTYfpV\3P" u6vazv0CdJvBx^|_`۳Z"$ޔz1nC'^ -S+gn0(ՎhuƯ[zP!ѝM}6#W%C1޶% ݀ICrįC,doo,U~jŬg2BCg:<{h>xR҂E%O;KJKJ`^r*C2}[6u4s !ݚֲfp쥝e̓+*R] )tezSL7b/{CݣߎΧ0]hZ׼3"cEKq(X .5gN'䴃p'F' !Qa}07@Kc[Ë>ɽǢQF L>{C$&CYVN vF)qF.͖"VL9?'%hz9I5hp>CҝҜyq;EfF*MÍRjl~g!>|4F_VzOR,EL1oh) -1x')8 V'1p_C203:=jEѣbx&/$i|kQ(Y jP:uU0G& q8_: -e- x32ۃt'%AYXw]5JȷAC%hzɽ+^mhbm~cSYب^j'Oˌ]F.'i^Y5ӡ޽:5Jk+:<_ ;o0y C Fd\5 &m1:\%^ tی".EPMɶVGχ[ -}Kx4Ũ!^fa BaiP,9΢:=ZP -1͢[+jr[%3]%W 6Ǟ#ԋVzVF>{9H+SRAM0^l$š|fbeV6M.݉xΠ\ZU[d=T2`ZJ5LԹ+bƑq[ͥD)>՜gnڐBU޼\fC q!nGKxoִʙyTJZZ\A1mbxmB+u!v(ϰpCNle8:rOEMQn 9af!;H$Ĺ8Se,;G#~2@Ʒ{Bt0%:3>;;|խo1|oqyC}[޺~e-ێ4=0tX20Ek΅YfjN:'W!wt~3f&4Qވoyw`f^t:b6 /!@:\{`t!13 G@HHS? !`3L;\;o9嫬QE1;, K(#RJS퓍J隆Xn;jZVv "Y:E-5:RN -4fͽ5VwbQuW62ޙgEY̪aQJi:4m:;niiq ŷy yw…JN:v +Zs·#U̵H <$AS+*>jcJN#GUmګNq ѼR q=-&݃a0,d.:\ -ܶ'Kd{ckjvUBo1㠐3d?{LA߿]sW8ϧ_:1Ú#@E29+rS͎&md7u?j'84kC|:qćMڶa/mq8N^S*1lae{7bЙ瘥칽dEMeS/]K%K,Sa&}00쎾3NwVrvp?@}כI*cEICF)֟̋= C?V\H}` kʬ{A -! $Œ7hAER!]1]jY&2{a+]p-d+Ϋ"1~k9F<37]˺43}xixpA^f׭J=SW`Q,s|[i:$=3݄_Z0i9,Lt\c7@3|& -hYEbwU[H?}~SqTXa׫F7H7Yd8)bOwo`gN6FkEGf3Owgs߷#ۙIǪ,슻8\z?#l§(V&swc8tN-&n]Z)8uh6l+ LVpMJGZYlz>3,X:P%,O< Ka#0w)DΙ -td"|31jbK$^|8:4Z/Rjh 3rpaC2w?%"9btq ;M1oNf6Z8'0Yzo>~;i.hGir}f-;73:xB#L>lR 4cݲy\_SJŽfl~3$}%~(U έ hB0橈,4xTnV:Qd^yQd3_Y9萰5B^R$vxCqq[ao byuoD<16Zd݋Aٽ.$&סCAUDs+ͦ5gs:RqM7Q<(|Nڸu8MHͽ_WM7褸4<[xpsbшG˻c|GE-0 o=%kEw.nW\)Cn M(MQRMԺ~#3tW8߬,[̶zUٮÛ;OJcak10xI/$!'//?'0!`Yjn}dnmS31psQĺځ{LI<4qZt(m_VmxnF@pl2n=#E8i0K)Ş #yuXE0353MpBF+~:!<:( -C: %=i ڋWN^=x3_!cp hTz;J 0^g&j(=j .`II6÷\PM>ᵅ2vYS:M6'.nW+;>L0rSU}|>$Ֆ=qf`[TRHGVly0kig6kZԹȓMXg9P !9KF3#|,mYZ)?!`B=9aJVZ;a XrAC -ӅYK{g[πh /grʈ -Q1unFxMș2+~mF*pӌ#SyEoiEME֓ I$h 8$yqh^c 7ng_^bR%֡k W4D8<"TKڪ39v<ݲB>ћ /'2ZISWgf<5b* :ĎL4['wB!fIv*@e - -ս‚Mﺤ&it. c΅4i$sRRŒc - 7d-cA*.pi&D+>DT=ge9^n 9D`AVNz1~h:p}e{z+8Nwehҝ h^}(&ֹIuЏG2WhMxt9Ic>#hΧY'_T2⻘52CnSL`ęjM_az>m@U"&[E i6ӕ&Zd^02Z1'J~%2NxMCGRDV$e -SȑWtRcM66nqNcVϣg2*\:ضѾ^Nm<.6Uju˫W Y>͐8 Y tWSϼ+ !L% &"إpόTcƱA>t)'8=|u%~;#=6/X|]t'mqBS1ztIN; {rltBp'zp #K;y:̭O4={,*9^^nTP{T/A35\n4hexu:#ZzO%Bb- X}3)pu83RnGnKVrIB%^U\ ::V|xg Jև}z_!@܃K,5Kw2hu 4U DQGLҾLhiW2P+AD=2I(TQ(ki띑ߠCY -5Xf$2u9I{-xWDo=ՑCSmZq2J\:w@M⶗d###iRQiOvTT*RZ쑇(+)=Y-r{ꞷsv:S^0 \Xbia, C,7$xźfX0p@BHj7raJ`"Wd߻z…K7G\N[n4K׃B\_rt729bt/S7YywN.tښ!k›rT2/sXpxfU{vYA6! -zWU'ztrܕ6Tb$RQ&L|L.Dp0K۶8J֣n&q_!I-4ˆ5S<9˱1GC8> -C^KPGH7̴>,wv0Keϰ1Q{fV"0Rp37dȝ:?|4tN1k';WRKi92ߨf -W]>' -#GݹOfYI~A㑐44]^(Trۏ3[2oCICn w 7^J%/jkjdFG(z\iot5N79syxoPZ=㞼hܽ3M -9~RZ?F s+.e-Djn:=|!:o\yq[-*X'Li^1fޜ 0GZi`9AZ:#6o?VV۰tyݓ6vѽ]L/z}>NvI=yݦ1K> &q;]\Kp dfWv{&e50 ff!չO4UɖjƷʘ8p -^ 7 [?b =5& k&^4tL7Pۗu*Mu.%Ր/dc 7Z2F{ү!/zU`R~5uWAW;,l<8CC -2*b#tۻ닲i -'C搕ӧ6`555!w!rUɭ_E/>Cr5 -F&3kr7ES%em٬&JᢤY~Z ~gCgsW!sTJ}ey.>&0xת6>yn^r= 8 +wSyf~>9"SE/a%͕wM/k+6ke6D/<AlzJ]{Y#*m/6Գ۶6oc#zv'(vS{9>x6WbQu3?ų 581^1{t\%r%>ֲ C*Lg]4az*.A5(iFSd!S576EL jz̰_GbXƟa{Qa|[qs+kw9Tq@K?K@4m~QyϜ1[nD56-Y:%O97}w~HXBt#9~NٴD/}N"y|<æK_\ -qs,S/*p9~\rՃe/_&6K6{JUڿj2D۬ rV`tmH}2iEƙk̴gKkSV_d^h+CNj9I]Eq^X6zS"ߝNdC!7zQZôm_g%r֌R %8kIō%œkbgĻNfx6r:,}SA-kjXZ:fb?Cctpȫ*σBF~SedCM~7l/L' $4vz-7I~diy8,2u[AN|􌋥繴jb(jY}>~PwT))Ϊ/EXpoel<1o9yF+h`I.j8OdA ]nfi=}`{ZK?r&|1m+SZ؄?&IMpƕU$<]?rm9o]޳#c8r`ooԯ!k -(]< - ߆ZZ֡+4o V!>9@>C:: ~6*@ ! n~r .>~=Rwl Vy%mאjgfĜUV*2=ם$lRgpcUP{Nk rp:Olڨ`g|4lSLDHup`֚ a]4"SF4dzj~,uh@WbaB?G46f=I%XzlCUڧ%MdmXt.ݰxvQ *| &e5F~Jce;-` j=(w_)6o*se|C2ne̲sc~Q0p&iW{WlXKu\!QqLFk[SadnYHlA4zh#s-Y{&q:|#{[/< -'>omަnjV⣾)2WrԺc[?=Օ:Lk͡k.*RdGchoTlR4-[>_M[Ht?)i3}{n;ߴ:~n4n fl3Co(U9w%M%>3SH%94{sX;K>04xpnbo.f'jiT|E+9/k9]<3+vh ,۱v6oSˡS'B%,tAs'5]J%^o:ԡȳobEoۮbH̍]mڪr8FոۣqzwKQ_8y_$eI F3#ᛞslPRˡ扩aƄ69yb嬠bJ-^dvʳ帰TٲX5o L|Ou9?f6_i&>msrxj<ǥf7(lOy \0w<'FiT{ޣrGGM|HOWx-+gi{cΡhۡ;W=ؚ#"U)~=dowa۴E.j,mGx$6iJ.˸ƹQ!3A/?]haku0gm{9)crS%u_')/E>a bv.1漲\%efOW;].c`ŐIz^޻sS/$96ךk'h>~@ٶZ'"t*P˓U x -C^KPGH7̴>,wv0Keϰ1Q{fV"0Rp37dȝ:>ɯOhyN75{[ڌrfߴ=ֹ"Mo7x<Rӟ@0J>u0ճ 7L瓞1Cیel]^zJy.OjdF4dǵ35xPѣqam:NV:.|qTۆ$6?Ÿ<{tۏezO?{ýwKț67\^nf7ہZc%7學3)iL53 O˵ߡ&f#-3ȭZҋ{SEhWڿnVw?i-b(]mVId^ e:^_v)g=v_߲nF~tUsB_ IvC:j][h_uwk coCkHnX2!/{Jixa,r_G|sÖ,S޺AYo&=x>H! -2*b#+h/*nhgBC>CVVo🪩ACC%/2($O02B(oL%vx쥎ي3sYhjTXf 0Av҄U -G9Ԙ]LLܼp:Qjlɳw H**+/e9~:9g WH 3ӷ>w1,dM|EyZIeHLNbisVv99M8åz 6y(uv s[*3r0'%Ad>ᖑWQUU65+BFȾ{{[e|O1."O3};af{6#mRW/i|}\Z5K1ݬ>f!iӛ]gT?(j{K\gՍ",2vfqq -6 7<4^d$skw5thd.73KִvОA-MNk;  r r@ r@ r@ r@ r@ r@ r@ r@ r@ r@ r@ r@ r@ r@ r@ r@ r@ r@ r@ r@ r@ r@ r@ r@ r@ r@ r@ r@ r@ r@ r@ r@ r@ r@ r@ r@ r@ r@ r@ r@ r@ r@~߬Qo[R+BC@@@_ZZZoo,~N0BS )))a/Czr' 尙B Gw^6aRlվ 9]},U5q2Ҿccx{j-?8猬,߳ݩ_0!@{9&n0b4Sj dCap tA%W{S;k}T -+y[1O͔DO&'JmɛFf>nRʇҲjFfڷto*ydw~Lֳ^̌d -Js4e&pms`:pJ CwELu)ŝVFo}˫r6~`c^rw7m1 3|\o_ذo2{>o:YbK#1I - ]{3&=q4'}W9]}/  1h~s[`|dyPh A.JhpGnY^riC$#.tɺ"]0t[ -v{.%Jڬ;2?XCvG):(<|$Kuʧm[֢(=b ¨5FOD8ay}q&I!@_rj!L-F,s]R+lT.Pv"I|z)u<6"hg-R_u,h7}=8!+14fj]^>6&d>om9[֢H[ꑀ7=w~bi&mP`#5St7i9<4S -^eho avs}!=Y#-}bx8`&rЧj9j97(h1uuR)>Z}uM2mPRaDzׯCG- iL?mu(Wsy䠂&Rc^Z R}FvH &rW9$7Z|lk27k( _V!@c9wEeM$^.KPEKU8>Ѣs0k75rлV'L۔߳YUı!oǢT>{T0199])}rл>9]a.Ohaoo!Tj7Vtt=苐C9 C9 C9 C9 CC{{cz͇fIیy -endstream -endobj -258 0 obj -<>>> -stream -x+T03T0A(˥d^U`bjhgb7161Գ44CC3cb |@ \' -endstream -endobj -259 0 obj -<> -stream -xڥXmF_A{ǾGlcV44JtR~fwvraf噗%(?ii,}CtQNOD5ayh"i4+~խ۪Edf:JH×>]HKRQI] ׈H~J Ϣϑ䙿[T9Q"$ɕۄqF`#kLæj~xHX$;,^k*\۲C4'\6USQf[;1v׵DZGYU}_wfEYa{砳1Qqj[NOX cB1X,sg=ܤ7(OCW%n8 -&[۹4k=Xkmzͼ4t5AAjyn*JkPHkKY8ٝtC+됄< 12L*d:n*| o I=^-PZʶx3aG|l 2ǸѮ*0"5 HNFF{dJ::ђhe3QŧTRPa1*l9bc8c;@D7'/J4*3U13x'\9`3I1@܌Bqj.DEM1Mi`@\HcFJJVLSgevվpQU%D^7WPt-Π\=t%&WwP!wS#n_ԬWPVbF@{3_?kF#l -1̨-.hnp.g>l@8'qyU5X ./Z A|_Ҙ~QKyX>nƑ  T -pZX)K>7Nx=3TM3U#˼!Aܡ {T5tEi<6z]cvNή5oіSPt?~bf<륞)K|p AKH'( NF3 u:kqfk't邜T DPGp#)FD_~sJAQ -endstream -endobj -265 0 obj -<>/Length 27018>> -stream -xu\TY ;l];nWEAADAJEQ~UBDcwaJQXx;w<7{g.B 686]nj0J580A`h/ -Xɝr3g,_jijPMNI?`8-L75&Z^4wH2׳#?} Z`tCu7˻"QH -D,\d Pws##n@V}sڳ靺?yŋdZ__f{!6ci2✬(jJV͆k={QS[񧐠ܹ߸`tRPgA"Oa:XSR^"QI1Bzaֵwo9P"gɼ )&_b?ܹCO3c>Pl8z -i7j1rS%dxJo[c:f?Bѩ#Oǡ^68N2UgӚhM 5 -񔞃S.digRˎBu-oz h2؈Kā< NswstOS~,sYKĖf\nFQ``tr)V"0i)I| !HNS0j_T;sk7j͎_} 7J -MHloë X0H!V@!:E A^fj*6ս{r 횗K&I -1!5_y5/TW!Ƅ">s6D.X4MFL5|}qPs\Y - !q@Cd -H w%re[Ň!q|K`113C;@0A@0A\~}]7l0U0ύwF<<<]ŏXxpFq8ÇwOH^\۠Pd4n :#5$6(kHׁ8 #A;$F1|l8UqoTbrS?3R ~;sb,["{|-?,?P٠ CWSVgdҤj [TѣG~_~Կ6J~nK{j,GDTUA~]7.j&Y5Wua>Yl` q8қ!Zt ACkǝ.& Dgg驸מJ-@AMKpz}P?w'b/ 8Zs^?$ BfIl"5=KqL%HP?W2Rpי>ߦydm`O7at}-Z}@oQ7oʩ(\c p+u?Ե0^! DFF(ח*)B76 -lafꬌBlİ |! -l^1.4)toFJbc bud^QlmU#X;(]W/Xt A~0ɸZ[GTnqH{!{c *ȴvPo'FKx)ĦJ,0#·wMۛ=ڑGZOiڡ -!$,qkk+^xZABfV3"D#uSj1ZwXi&7B7$q3 !ݢQؗ&QL{qQ0tiq#c(F{"Oi#&+Y?5L`!|@q(J_k*s ,y>f(\[f0Czgk[q1N?_ͩȶ/9ļm4/f伷CZ+ի.>M5ÂaUbeݼfsZ{Nş_6n#>(]W21ۺ \H>o?8|R0Ҝl33sl1Íb83Y\Ma ΨS14<1Bx-L}=k?" 8'55Z:neml76:U{*( ǻ(a>rջ nZItK:?te/msi#IvO1upT[9.Eg/qe ( z4>&m6b q9Dg"/]D.[*=a9ab"6vvyDIaݕNz,):53r1UF`e ‡eH 5?՛Ψځơ |/'2<ߘ'뤅.TIAv!3` NxcjqĊw絜ӿ=&x$35$$3(ʹ?yt-ZI !j YL"+8;^+Sq8ЍuoYYw! -gen/ll/M&SW9~q58${IpEW$4sL 84N~_¼+,Yf A]鱫QJ}CDT_#6G%}٧7=~AgxH-Q##nUsk9Fjg.eҁo{K=sϡau;&nGte|wGN?8lRS:>DqwKNYְtQ8xC)O`D@?ce{jCK3843~kfiڙ6r㋫e -(L\ٳG5␌p9>f2[\x&eQw;OdH=,sĶV-]zhReMDW sB' YK}r]VH&|,"풺M,>5cRwbZU:$uOS-5chåSd"hCd5>}KzwoĠ075~c=f*'W t ;# N&l}a+: -F{ڀ083z-m)&ES[#ᝫg^Jq|qt!vWrgY\/b6#GⰳFf[ү۸/vdВRw[kO澬Y-o"ǡWj>i -S -Yqa#℧^38}mطbʱuɛloCf$I0 RKܾ|c.E;}V'C 0v}lם~#v؝ -^;K^ٽQ4] yHܱh1bj0Z}!2b6; -CU;'0(3z<:ᷭjWxp.em!rNuLv:D:s#wr ~6m *OP -Qbſ&6JӵMr}iu6Xq8uo5mܜ7FONkkͶ>9Ms?8Ruz w]1Xjz"ЫU~~r/8dyew]R0X~R[q;I,_:8lyj%-e0rd{38DjRMӢ6 Q' ~{">u}ktIlHKկbU̙ yb)16Di[$i3٬ -} N(%h"*c9`ѰyۢZL_~Ӑ_`&ɊӆU=.2( e*Ojk]WW ܫ 5םa̗5bEu \/L`k+.qO{:_z1)Jf7b$.5$I!p9ݪen]f8ty~ǥ4?(]VF{8_?}kG\Irqc(Ћs!A -:7ڸ8:Cp%Ub/\<}Ƒ~b4-y -2=Iq,z-+څ&Hq*)z7=H7XdeM()ӓAU -;k _zXnhՈv\1xچ>BbmBLWt9vgD6d-R%-Օ.F+ 6gCƙAiys # -Eci-|wwRqO_  /Ғ$kӴBqR2uvvDsb4m fWS17 FE0Xڥ4?!)<"bWWv$؊6QѮKZ+ l]..nhB s1AҮe(^?W|t[XW88n6MX7Χer!A~WiHؚ: -XÉ1{*/*47 j*j(F9-bQM+L5vA{/}/.7{qþM9hV)>Cx.7ƶ#^WşxELb'U_=d={VE+3 ! 0IϹΟ=w~[m/Aw?ZvܹK+mںm놅{}ڡ%'`y.wG$Xee%;#ǣ9\[MZMC g( uw._p˶kC9!!v&P8!C0ZA1s9w;yz ['Iо_Ak:yS%1\Yς:{磨Lu;UY)yOM&:X[MȆ;*>K{!O`c -9m)j"B! 0+KL0J.dTqm8(39OP8q6SҴ1x W|Ⱦ<)!_es -؝y)Uj4K)OIǥ4 w\pKKK^e!^`LIV -{!TĄ%G)Ɗ&4H_ akh_/Q ! ?6T hqáqF+C0&@C0ZA1p@ - CV`L8*`8cP8!q8%`T8 Cq !8>4yg\rpp Yi`KC@@Cq !8@@Cq !8CCT08?!L ͅ80A!!X^eBPc" -Pkd F~ =] b( /RkuY+*&(c!i+ify9܃M&J 5԰im -PS}􈿄=~dTDAl/Z+>`5u+U=(qlt940wyɣKuQ8e5yD!Hjl>*;6'W[QKN$ -hhaibSUED{];tsv`%b,5ԗ'cbnqHW!rĥ_RP+0MDПm1͡Z_Xo?G ])|^ץ%,륧HWyܹ+f;. 6uZxbEܨ[]df>~73Jy؄sNk.j -q"PfRv0-gIu/]G18\\~D{$k)o;a+xq{qܓy[x?B޸UQaiL?`lqɳSp{t{1liWU%! 9.߯]yⶍ9:Oq8&YU~fad]GoS6S56Xs>YQ{}Zt 8$ֹQM,?w83pasqNj<9廀KPϾGq^S6s_!a300WO)DT2ޯKDws=M^m",?v~ƲfvuDKC爇:)-H>>$dʜO5O@!(w5UbMN%):NHQ"7>4LCM TMJ<;9E^j>yS>;幖Es^j39]~Cj?}L.JZ!FI&u#=SYn̽4@Ɩ>vܹK+mںm놅㻜[X@W9[?i'K-5?v -[/s3X!h3sɳ -B].\mZyjPNHg"z_3;qq)M eKr6 -"joYE-HHxK?XZyS%1\Yv} [Ob]%Cig"3lI,b$h߯ ߵWvEN|9XʠB}JSSrKAaۖSx5{f!?/ZDX]I՗+FQnU -ۙ$O q[14Vb/\>&.&>~T 1ľߢq 1)vsFPA7c ) G".~ưm[~K\MWk(k/E.ulC`D+툪w0A*O3T6G|h{Zv؁A7>)-ώ:^`xZC5}p+Pؙ@*e\::v~> Y^CnJ?yuP~9ªˑ}FF{67\@%yGȥW8,Ss;o>/RIʊ^pҍ[ N{_y*&Z<^45pCc/>؀Nq.c2i+UҴ`]63g-'v;BdɄ -suHWBx&MTXXk_`ګ{7d KSYw sNEb SM'2wʻ=xG}{GNC(6I1&CicSI3al[?A埃,*>LF!4mq3!u!m^>,3ls|"lƞ:$Xy vP̺+sb")N䞿_r*`w`8̋VIߞ̞߈hm#*k6+j]D>ۺ2ZֹL -J .><7Z:Qz8c88m\]͔ęE[wI{N>N IVu,£ex"vc$┛O( $ðc2`[>S'K{ --O 7hn[zP( $3?mӼM~5u!17`ܝu,[ԉ7W@Hcvqx9> #)o^~&eicsv7xf)fh~N!bH]{ qRK[l"] ]JC7H(eqց``Ivbalٜ>c>IjZsNElˎfGocBPEm|Otk74Uyw!ega=m2vN#8XJ]+jCv5u  sgxL>x iFy͜M'.y׼Guxbspř][^1}ۇ[oԸ~bNjS vx6رǐ/Zxl`D'%D Sоh%%7OѓX)N[`(40KsR) .[+ިEO[4_ -URgynSI.caғM0DIikAS笩q1Bi{h唣O(htqV 3ZiʊP.yݥAYp*maFX^M\C;VsG`VTlp0;2k\#?e`vVa·75#\~+̭ގdzlkI~r1ny7|f܇-&SFfh}\;1po/3jz]]-pG:,  SV +jCN\a; nc!q@<<}[SS!n!''| -q`8Fm mD^c':iY݁T7 -ҞkRt<{]@kGգsbSv1!/ 3V }ZKUO[Y~١[ŜGGd1 DIGO|WNM_rHN9#y>Ub+hܘ~9f1wCʦLIcOPl9HL#7HXjh8zcKiIp@HA[V h}q`wl:o8_$[.R> U;=j)ogUK;54|$q$`il23*滩,{jIkSUũE[oOV>i-/U=DH1ĩgRC5QMvhK`0j7xSBl]چq)pԜӾARK;(ەN83ڳͰd~Zhkٙ?x?L6{ -Wo0\@7 J>mgҷn.l: -6vOZǯڢy$Ki[٥O9F0ԜM(tbKՖj0qT -SsnD.G3k=%D-!:b\6ԱHRj)hJmY'r!Mike,DugduIt]lsXtl͌IAD(Uԝ%SeXȸ&-}=¬G͝k8UB/{$ Ź0H&+Ne`S73;A[P|c݋LJ#ŶzhKSط^CwIW,%rGE,䬾}:ߛo^O/}ʳ&3tŷhFqXql/U't,||V*7v=aAߚoץa,C˦#ٌqS߰:kwym`PsvȘ'Ο=w r_;v0Guv=Fxp3b<^A:Uٖ1BCaXgҮh{z <'yTtNzŽU?$GTX^|O9D8hX^՘9 u U蘽sIz4#״j8jB=zP[nJKb탴um2ò3PuBhvQ:cQiscДbhJ#G%󇳜ҽYh7}2ߵi՚ԃg=ߴZ*JG -on;v韦f)ZFC{_՝HԯXe-C^{gLI*<*GgǦ?ԮްI1+:;}NeGv%M+V'Bil}:r!mSCpjO5kIè槖I)!ze߳|f~j1#fE: g !cJǿ_&7"#<FZSZ -wAiz_q b(LiAi~qgWضuqvgKb9RmZ<.ӾAi;7r{r.OMRO 9"'ˠ}nG,?ihpgfi{{c$D/9SgEJMQ}QC,;i{s#'TQF֘t/ -޽NJSՉHaN{Ђe.{a^9L7Rvx*̈́$T#6<0P̞ǞtE(M)FI\_+(7iuodjKk]ףǧ(-.uu ZZ״ӂ.j/?6;:CMq'igƱw$ưyuYzыX -4 68|qϪ^IhLi%Y\ M0&Ny[=\"u ʛ:AL^ma|"h`@d<]z:2::7?Cޑ$e1x|ҏ:)Zò>m>7Rq'RuVIד8Z#34AVrNf:v Qtʛ{RwEa FzIm5ߣJ[m5aᮩ9ӌczmoZ -jR_NzJKvzc,NKKiliZJN`DjGxvEbwqh+=y<<ׂtziP{EL^PMlӸ=̻. \8yɲײtKұ1?pShN౵!NZKjyI?,&ᓅ$VIyMXٕ|R'S{G=x -qMQ 9Kϙ"X4(jIU 8q>V_-+'+< Gky)6jK]qju -Zl yh3ܬHfɕk%`zNRmijG饫>bΌd/ccCSsuI;Đ4=:M} .Qj \L@-ua:ڭ l 2"]hQ{_X Aګ3k yjYުloD -.I^~mx YԣDvs>kNMVu- ' -ZdauLNKfn8NokD ㇼ.&f/l(W^#8ru=˲zXQeL!ߩ(>KIN+ -7[2kPm?}]RGR*c2 C`!9B(FP u!04G%6+bݺF91ݤW|QitO[hfN)Kw3mHuO)ܲ[^ZA3!1rLMY%Q*]즲"}4s{'uc&%X\o\tc꫘X>v̾5yd^)S18}7]qcX5%&-k@FpدlCGKOϾYk$>y0y,rTLzNm6ٲ?#LJm|4R+G͹7 36LtT-3,EP1z>%L[f[hϢgD@-iεҎcS78i8"v(儮TGIz0{ ,b=;BizhIkx,qX\m%jHQkWΪ|mW tS9N;8_(LX5cnn;iסMLw4qm.5d>E^8)eAY-Ȧ~Q?D_+鶇_l{Mi}_=huT[Ib`n 웼- 4MꜨ6: ^@ꔚ;nQ2MO~U7}5ޠ<[\o 2K{ťVľvՋX~8$7>1=WJ៶|nCI/Pٿ5&eF(6/[>qnr‡2#,1n1S\kPk%r)ˣ+LW^ }?`FaHR}s^lVU ZmYI-'lwo)F}]}VSo9LWcqA4~(P>s!}K#?F=rc|Ԃ7̓~,ReS#U]0`>G#&>إ|wK[KzG'SpMdtSxiMpՉXv[rܻHcb,zfqDm_ MiO~͈Yq&(Ok+'\q "긪"%+LigӃvB 7+l]>Mi|`4=%tcU\BzԺ6ֹ!G~I=:>nif$ >nS1t-s> ->ʠe$4rhp6_둃0AfɃYϜ_º5r{N~ߎWC]c敵UZ+1]avYwNey@OɊؓNK|vk_8wCJ u.T׳eS/tG\?G?惝;۾-<m#!j -_=l;34oMa )*v Dr-fɾݩT]| Ln'`{l%|vӔNh}X}걝NMĈuODzWF"4cFi!/ijU,/؅ok܆Q %{œP;50$~k^>SBbJ9rE@a^;m 8UHjҭR҆]ٽw(7A7S1+}Ubp]BSłj=T{sҪP -`_)}@T}V_\~,Fg=[W'sdPR%C6Inf>D)_2q@&,2?D3{'{uq1߻^Ma9 S#Η6J7{?vrmdKVVR|t;)kGWG|c -v[x#W1kGH՗nFS+XQ- *"OcoNՍ'/ⴑ]S6:YԮ3Z21Xo 6ˠC:_ -qBHb]_HN}n.-I6{uӉKAiNo%gQh`~iMwmo/DVbCO֓o׮5).$;(d!s#Y~ &,i=Ȍ7&Y91kW7:KRcG$߈ژ$֘qtx[?]/쯭g˖_[܈)7.ZK"ԏyf/_>k& {Z\<+T_S]cc=ECn}yP3hQD(VJb*ܭb˥, W7|"<Ⱦn -0ȃ֊Z^II^]"LI̬?&t>W+9~l"doNmR,-/Swgp|'3tq e'4O-M5vBrId> 5Ǝ-}{uEҿTĻN9U|'M+I?*2Oh:5?ZDu4m'k<(Ā;{q Dױq\wui% 0  38ErpgaD8xU*gŏ[ C@8s.~VCc!q8$N9Og&G ?pMM&Jdz=@/]c8Y8n;ukh_<6{PGR4H"YB)_WW0>f~ns֧zN$܇ Wb^v׎GĦn[ mG+H|E;7t rKUO[O՟A(?xy@ xVVe0,;KEATڡ?y+!( ]]<>__08;3Y93 ;.W_l3tfW#{6ia+:&?}̒C?>f73.q]|OZ66&=|FI:Yq4oN2vtzMgErKG;l33˻w;{lʜ'7 9S[X8)9O6Ŗcg]|,n q'.f%Ma{@S"wfd̽@W~6~ZIxGXlȌɏn.%aV Շ,VkaHGM~[]']>V\UklT<[4$.pAzeW/_dEv I[5\:vSR_J3b0\u -ש|_T]+7K<Ί}<OsVT9@=`ğs)K/͟]s z%}mQ-99|5BˬlC`4_H%#Es)wpې{);"6)۾瞛l/Vennֱʞ%K>y/3Kw)}6zo+}=}0S#F -=۷lCQW6쭧m9u#j+2}4*šzf-(OM{\m\cϸ%6J -'82uyh^z^Mdͥ_^yZ׀\[(n^7hm*) Zkأ6)FcJFVx:u784 2e czDO&&+e5/4-Bc4]lwy OZ~SsZԳoJX{&e־jl߰hkOҜٳ =猐?|:ԛ#Fأa]9~U,IxQþcWIOz0eis^˨5 -~PО1oոP|t݊7_IO[a\5}Q]j38S_j#[/Msx@YwCEq2,>7㹦js ;DV:rss)S gL=t٨W|~lq;jVo9$|Kacf6]Y}?EǓw&3\-p>uΌśn=y{-E7X v雦he8ol^\_bm/~(~nj0)YaO7.9q^UO_rEK%}nUND[LwkocGqȺPu-eu'Pu-=My7k5Rܾ*;VcUs G,Z+攢óGoܢq xJmV<LB:Ww}_:Jo%{Ǐ9p)=i^U)íէ=ESe5&oܧgLzH8i4lxLskm=sϔ/YI[txPoK[tSX$u/{6a>'fԸZy)^㳽2}궉9kow3G~}VFذVշ_u4r.n1) 8], utABFsOUJ qh=?tLXV_KʡvCn!ɩCm/T幇vn޲ }g=,΄hboGCe>k'?TB;-$wǷ3R~<1o7(f}ԤyaF'na)pKui~~XF]^^ۜUFdN|Zegb4m50sAW\+b)\ո "gs7*96>57:h,a>u1m`s?|E7gu6 7zh(<6D}4n1я̱ט2Bw\qim=Q; -ھ2lkFLhe[yyIngfnI_KuTB`;PKjWf,~fGS=W=j)#oמH־w~#^뼶e̶5dؤhk9~0tԨvk Ia!=jen)21:E{yksaP5_ֹ93YIZϱ~{[/~3߰fKǵ+lTOy`'ȿ\ѱz*r> uj߶ҢT~kyYPʌ^M4(~y뤱iH9{6/)k½Fly?7/qkc}bDl^Rhl§-0IwmV-Y[X~w]n↠[87=\eq+Brw{ܾ˾ze_klͱh'/99mCtƗrv3{z}eco͘ߦ3 70{nw3QK3w)Ec6/vn= 5X#9EU|"c촣&m -gտ<,m|{';$٥cv -&t5w߫(;yN*3#6o-vq{-mҲ眕Ϙ5EizS4cxO`t\sʺsiZ[z<]uiPxb͘~q0ki;{:-W.`}1e=XGW|o14۵ho4bu:;Y\UE*-/j3dEkOy&=8svF*13m/@瀉[_ٖklf@[jpnɷn}[48 W>li#Z'hlTqݴՍ]&zo|iUq}7Ox,:鹩łM[1%Wwt=:Fm1)/붲WBQqoCJr9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!s0PzRlFx? 9@rC !/;;W ]v}RgϞ -W8@9ErPPʂ{nb}}ꋇlՆ@j`9,>6{/*MU}g퉂oGD-wh) /䮍fL;K_@jx9zEW[ -N[9쫻>15OQU)60ЭCP(u$fj2GR|5ШE;?R75~ Ս}^-QOYNi~Nܳ@j9/W&/o7-6s}|/Z[׾TvW6_P>qo߶~ ]ںu%Īmaa/[Chn948:nY5k޲ҫceêT\WZdaif'u]Ϙu~z+)q΍ݜ4yّK#ĺsX߯OyvFu@IU|g`e_/_ݯWT/,Y=?ݚ0*?{dDDKƒ+}0Nn[9uݔYʊ@Xb94.~xJhV#PX(ʵ -f֖,BӥJuBYwҼɟ<}/C_ +=UxVxF~57<߾ǓMWt;?) 9Er69l9U9=T?GJG^BtWr9@!BrC !V{e7尾Wz\ -endstream -endobj -267 0 obj -<>>> -stream -x+T03T0A(˥d^U`bjhgb7161Գ44CC3cb |@ \' -endstream -endobj -271 0 obj -<>/Length 50990>> -stream -xu\1[@DbwOE11.iAQJJiA;PQ@`@(H/jrfI$}/L@y:N6A3e7q 6_O1I$zuwC Nwd˾qI!$IH4e'q Zʿ}Umkeս_M'5e<1C``pÇ+V]l8D0/"*D"~|}^ Ւ -`YnMZ򊊶\\gK޸y!WA<Dr52K3^"DK6?Khϡꜷ5o_|9~cƢiME.gNXcsiNƷF6AB %5_0؈mΓ|L qF8LvC9XFQ~NDgUJLtD"ig'gې1x@3P+V¥%0 6zNk8 4{Ǟ,=;K[=_Rkqi//km !9%!:J%p3jdQz5_|C.m,yx^M]ȴ'jpy=G lWn_)XMN VZv-! i -gP0ShFKN5RyYX\/у}B'|t -sa[,I?mނ) lueWO?V`!*p;K8 Cq H"[Z&r[ -CCbpWGCK qqHq_qHq_rƍUV w-~ݻwׯ_?ܵ`GwMjkkGGw-~… -`DV={6-u+0F -yAFSse4$@ - #nq8FMCረɋ?6(}!@@(0`?}GW<=ybn~F컥+q׏E.EUx/lC[^Xc5O#.?%BTG1(*kBq*Qߙ1fWxߚ@`s|.0 $Qz3D+CЯ.!8=u/Uv&ggľZ**lh+f ͩ5Ov/B-!uL@+kWk_zXަ$Rظ=P61W-ǏLe?zoU}&V2mehR;Va?i?6}aЭM֣9_7Q_"!Ju+uTc`s?ZXD,Aq%@HPz // MGHF:v1DחfeFj_?p:`!+HY%mQ8TQZCߩ67JVx7_DlybaB>KR1d/XJ#"RK.@16x1ۏݛ-+iqDh߽[wo`+Њ@>U`x?ͣ㤩 e!ԔԒy8v5w ]Å"tu'(D2[O#Bm넅;gz. ߡAw(kkv[4R͋ۢ݁zTqQ7\n\8U#6!Py8E&+'WݭbSYäV`te,%4;,FWAG_-woe8 ˠljY˻l8Q]Yi"wS1O9~傭EB)ma>$3\ㄙUqOq8y%#_kSYὭ[RKuiY 3#@BgsCЯ!1;Ylxڂ\ƭ.XPTv!NfiT= P;Duh[~6E\ɔ,&1/5 <6ђ~$gFø v߽W2VQ<21]H%oVq3ȟn UǸ/ek~ѩo*?#N95-t &Cθ`2.{6VERG]jTԭG^"z/1ęH :}xma)\Ӗ [|֥2k\;o;˹T5eitl?e5SY?!gy~' TsbIeA؛7ǧ. X7=|&0P@p Xe JzcdGDkTIBz2cJNiϵD/`EElӞ͊"6emy}uT8Z W5a !P.z>ŗ=&鬑>,xS8THm~n\bf^?Mˍ1z:[RrβMJԏ:,ť|w^Cҭ2HeA4DSo[,qXA_ݑD. 4R "g>_S  NYb28/ >TWr%9ʲv8J3%զ00rwýcBW$OkCRC -!)X鍺\rl^*,FZ:Cvry>1ǖo:s0)vq58$UW U:Dn\F^Qi*[I쌬>'d0_p,cpu/Pf`rR%IՏ4a^IrX!*2*gW<`!АKiuDDSn.*zJaWUyxOH}ZÛ_d53 %5ToɅq~G}}ޫCv\"wk&vBLV,>9v57* j'-WGm>KI+qtzg7/wlVd!T2Cǻ1 -d"Wrv4*GPtu|ƙ0ʘ o v{\N 8Ocġ>mȥ>ywN[Ea*rU:l2km3GOJWⰣ+7J[v_!3ުI $ҾxĀw"N9Vlr3a(ҨAKWrKA`T38~c37\>LMہġ@  _ -#aE{Gkֽ279>Zo[LT #z;alxkkGt(v~9Y(۰.x<#T9շbNp_ˉwH%tnyuͻ;<^ 4UQ%Ij7e~>XLn-1:]))xwfptn-au2+CkwrBrd㤀,wW:K_EynAV?Rd+%t[qHdڈp)4茲?UzopTֿ֗q}z3rt'(J"5hu7r >Z=k O2:IAƖS1HKέxeP|V$_=:d%/-ekESON]H rv@q(DKb\)^&*NEkJ=2L]p}97 CV4J7:ꑕ1ܗTGeb{*9tc[lGf`\% ѽ6?3YzBV|qf3?V Lsn.ӎnSVQqŤŮ~1ؼNŅhjg!]A>ۊRqB&){g[i~#Q:j-J.ŝUU#!8m@Kho_CǐmA86E貵iL){VZ?n>VPSsNjH 8dO2QA1퐿>PbLؒ"RS]X׀M[KtD(aħ{b"ZA(9Ӌ-m7\}ևXyDɭ\r˩OMq4y/L_[*JTŮ7 d-NE8e% mVplꞅ~As\V%%Jhtu?h[*w+4#4/X7:a0K!ZsO9Vf*3#帉{Ih]f#,Va:+/?[ݕm?fiBCYqU ŵ%ŵhf*;M{eyzJﮟ;KQ:_K+Z`~߳:VnʰN};8_!4TX_TTB}Yqu =wW-/.'v;4(^CU֓XxަOזԣZE1srtsM@n~}rU2+F]RKMIq]EF>d? 5_(uW(]M  ~mh*@I =sZ?9~g߇\A8$Ծ/2kzojQ#mo,#DP%iws~xg!?ph*@}S@7a4^-bFr~{J|-On GFH^\A8^!?pDT`xu5js GDH^\AMq²hѢQ5$mP רiHρ8^#yGrpxqx Ħ͛(Q_@q`8 Cq !8@@C0FdffwFiӦ wz`L ܹsW qáqF+C0&@C0ZA1p@ - CV`L8$ԕ0B|,^GW>%| _)+r7pd8!G҈B¬I{\NhLgBRN= WѦh{3 9xKGC0ZA1a@qHjH*N*jjF a=Z7K?Ve,|miq#//X^\ωA>CE#:9yԺ@Ǚk!$"BM?17sp8!Cݭmr5RS-Prn\z/IKf~ھ_>Xl)RÇ`Jӿ;c6\n{B4\n q{(xp F求lqkG܈5 qF+C0&PCBcΥ^yRʷdӖm[7a$8 +>^}]3LT!Q={'q8*y̥݇ -< BZyr}xϳ'^;rVsgOl*+Ep34vn5$.BdG {/+MvCBcΥ^yRʷdӖm[7a8}rO}7 Z:'Ljyޘ&nD ý! b8!(IYbn4(EMv}o%:aQTyn:ʘQi?17X5fY.ڹ~:;#֟VWj;U"X"|U+S/^fmRgU8lr.ë? -czB{z#H59Kvuq2LO*ZˉBj*$E*RY6l_k\M_~hye[:q^kt91y?%gzI9踆m뻑)Snq؎Py9Pj!F qq/srr:qH]Ϲw,bSRS/?)Yq-tmm`qWS\io=-nQӦ bF2ƹ'M2& eOPKI38$Tf=r'&Jp!Pӑwn'0㭑mҔ[&8-e}tX֙/r+Ms{˗<lEj.Ms|4sS=*57 Xɺ,e?ﻁ Qqxo༰EΏ;K oɆS!4U)wɐjRht~rԇ̆WZ!Nw𱣳J w:ʋF*zYHa?i魛Mb{j?D왅 )_?`~ +^U ;EĝD*y:0=o0*A/`q+ _d5$[lVcfld%JL [RDZj2 CWҊ7.j}L|"sHe9y[V5$ֽз^A!q8'湳D `!)(U(ibeůSGh*|A-Pq@J账z ?'ԗU`8$4V5xӽ#8<eت`X@vBy:OtpC8@8_6GA!8@ mH!@"{}bcGߙettt3!;;jCc!q@CB,A@X5ܕBu෍8{V9bAԭ,|sF@U[m=b ! {Wq1: ˩{eQZ9suŬ?[9P!(p9^;wMu'ŃF˯)n4JgWLh9Cu -l1ϵ>` qHOsءW7o@WygLT 6ogeqeoL7s}&!ݩ-+#.jF{jJ<&-pM ⬼!e:0넩DB 3 ̷#d9ec)vK!6duw -H?mAk9lhr6\vk5MDrqN}2mi ޹ݻvrs]v:IHL<v%eyL~Rqzht@|{[?xNNΟo479&,8-#X0rv>tKE[i qhKvZ/lm}w ;  MYvR'_J@JesI(,2coߚh'HJbz.G_ -65SOnur>یW Y'Ο',zq%|m>U 9Ylt'RiA;HwT4]v:@.:GR{<\#w_ -T.WoGv(7g,lqj=sga+PO56h|AV~'m4o?-Jh4GR]G ŵ#t=8z+Mefϐ}z2QnI(vՁZg`^<*QLs.BL𔺨]\>c:$O *4wtTYܴw-Q2[sf-AW=Ik1T=Nf; uyceWL;v)a7spq͇Ӵ7n4MuKu_Z@CF{Rhq|Rwy K H:2)Ezfa9_~mt@*B(9~5鼨ڂ7"7Okbfcʂ¨LLv*YH?yE"E$_VhK3)՘_wn)p!a'?r=oɡmk4M-3J|KJ[X:HeTByYa=-@?Zj%Svx(ƘH6=p2h=[>X,^ʡ6ڮe]u^g@ys"U B,Ԃ~u=m>4"0SR*k$5}Nv;u]q9ER:0}š_jt`{kаnj1G޽dl6^?9ikσ8 _zZa'O>cf`t8 Wffۄ.Nә0@!q -BF\21m :C8qBb6AO&Լ>4# Z4-+ ə v =D|"w:^Ifd(uocޑsι}Rdu0XrYfu}~vߵ;ՐTDtb| -úi^>kn.F NFì'# uB%1~h 7q7YlC=է'bsU#I(,t:n=CFRbf(bAQjcks1sCm]4M]qjSަS*غ%<2-{Nm{crM1Gt<uŮʡ]|OMz1 ?!:dۈn%ˡ7TN8p#T=9uB^@K%ox~anZQ9+zY<(嘴.C)*h 9/4R?ې%+C׼tG[o#Yc^mKU|D>J9&p s -[ɉ t-Y{[=~2 q|M1|DZ/d%oThf͛ƁOu>}I Z2s\v2Rs'`]1.`6Cns{(_#f3V_Pi1Mj˓N)2>w*jCyVqw x yG $|gw>ىSXXLgӥY7%fKkO'׸+$9ܡU7t-7JKVr$Bp"[ GɋhNvZ$Qq&y.企 lヤ1I=Ɩ#,>=g3mHcLNh:*di R9Dl3}Srq+8]Cl,xy¹۱cYKJ>r|pзyCC} -0P"_m;5lyfު ԿߢquTT -[2gIv*<09;r1{J:CѭP~SoUr[/c&bM%IyK%kAg/JWeڽqm{^MIܐ&1bmUdyy%7١D\\Pq}WUlm7&= -Ov>X KulʣAh)xR-b1ޢܽ):ImE_WS{p0CeoGl{z,ӂd{ FUD ʦ`$wpSPdg\i녖qX˜gNuF5t; 7n'odtPtG}f?J-1^C@B)kl}+ֳd>RȂy*X?)IQC#vOf@SyĦle7]\#d(y7oqr~g%Bh,(! -2UCCOŚOnu/ȸ>ାR -$Nfg:GAj)DKˬτ6j}ytle߹9ѦL="wRo%_R2+ۃG|$5}V8mկi/pS:w}~ґK E JE1]ӜiuXZFFz' %%}m@~䖣Ix+IW9'sq;g3NnK8032[}4&dyvFj∆;fanZr &z_ΉB*9e}z&S- U>p߲sZ3|u*sYS]kC}Q> Y-Fj'}OlTQ>y9HhJHa (0bB$u~¾ܬ[*l0aQrSDlsz!'Wq)#5[E~?QhW1\qH)G5^dENZgF/oM9 7R H$ܤo#H:CCbK3ECp#8ӴIv`ect2+[60ڌ>xlg8Tsr29#c3vCB×\z!zq}>` BU]Ì&GUc+ 0&[qHT/t;got=i ֌4̓:|T)Gͯn㜸LD›Lض fؐM/,w|wt3ƎbD7/[_ٖ9BMcWXZ_oYs*l6?d*kn:9u3K^d5r -(ʪa*Lc>Ak)EHbS;r]Bߜ$ⷡ-Ԉ-/=wV~(Qr;1wwtڄm?$%Pu)p_͟^.ABv3ȗu> tڲ-Ho\( -Ɣ+MY~M;;P7pfI'\do3dp7]tGvQbC7x,<B~Y3.tcӏͧAҨDjԫiK7HmٰHw]S~{S}hʴS_ཛྷhusxCk8kq`Pr@ikjH4Zi]7t(Xံ v/Qg֕S3+KA?xLKSPpoڇ+LҼwT8Tl"sʅKnݺf&=|,c¿=S7(\vBq9ϺJ,NmKk>vA [^D)>_iQs$X}<=TD3E>a. 񽕂M,_=\C |勄Ǘ~ S}rS;1;9ZAsX<첁MLZkMliC)gJb!ߺvJI=@owJA<>R<Ȋ[zv%yHzoΏԶAˏk=W%6?r̙k=>1`ġaцso{LjN6eҼjlAbu -G>T1Z87LRT0FDj.Ou|ϴ3Vo޼q4ʼnl%բa[cz.9dIgR.^*qHM})%4SBw_EKg٨ ]P-;f 9AZSu=7w>J?Uaєa<+LuŽ"u'Vn}!>~>T=en).eOl, hOc7Pn'5%c?(sțfN;/jS^g̋dvqOU aEϼanx@j۶˦rnƐ~ӈ˜Fs7x=0mqg ɶ[i:G]s+kYYU}Aj('v; n#H-5_4kYi(-ŶkۣO *؄؄w;ZM>eO']a_eQz8[Ԙq:MhiDc6NW{ݧzN~jcvQzpY0\ Tu;G "zK?G,킕ߚGvMzkf9.jp:ƞ[!=1Xp0HKE{-vh8 Hf#=zض$H~? R-^x \6캭ՇH0|Ѓ::4-fe0Z0< C@8dbb_q`8 R -[D5I ?(g;]^F+WWp K*Z/-cl;s`4q `+湍W{WL5yyi<6O=76n bKS[ -~"r ˨55EvsPL,e󠜖c ]|m*a\(ᰍm\C((y,͹A4nQ"~0Fvjٯ&*K@k'er ﹺ^eUXXBgSWPatI&o*μ.8c/3vDlYM?QIZ:傜7ݗ6&~ CjN;[`Zz:BJ:A>]p)XsBW?QH֎ `aQM}wm;e&)a^zZ^~A|+$-1Aq4'5K~PAl/#n!?C -~W< ULh.lZHݤ9@C*uN! '2NuΨbo`)']+磌\3sMni H5$9PkHUۘ&>3󭒔$eFg}gV6CM7( ߤ|pvZhj:=>#(b+/쒊3X{ H50%j}\H.tx'jJl,ʸGnTal>^Te 46û!hؽ|/Tou%'qe_٫/tBNK.X-Eͻgs##8Yoscjؼ'L=.gֳ\FRq%:vkAיG8:q39Y6`%bM~it)%&N|M3>lc!KJBM!##m!B׭uDfM=zg `q5!q C$"o#H:CqX]u]{,sΦd1m#%@`?y{Z{= TcsY},}q577Nob?:ָ#3Ə&{%13:=6;fOi-wT-l}&hFp߿ϊup~axh ˤXx+z4> >J(0 ~} Qgu9[>PrAS+ɷw')V~FY_/0Q˽A؛r}#!ٺFȁk!>>mF9_4̛Z(g~_D˩EsZI9Ϥ~ͯn㜸LDF]W<vIyQej 7iYŲFV+v'|q\xncS)cRMV;r^~lwY z^kn-aw>?BnUŊ%/ ˚g9y;e>9/\C`0-,_!R~Ŭ5b&#HPuIC {y0n77xWwU܈ɜkϷ2FeⰍq[ml|R9X4M˷¬{KBQk vR]a"q3o0sqc0[2l1sŗ<-`m"S~Lttz~N)H<]TX  줻kƪ ?W[~`&`rK9Z58Xv.Aʏ/O(tԖ (/o} PKfqXqD֟ge55nGltVv_YqKWQT 쒎'b?{*s(ꁞ-p /uGQ\e)gsݲK:_iQs$X}0vvU3i_Q{f4[5x~Xǖwoʯijԋt1)yKdXF0sqhLI/wP1%dwSJc}ˌ} JnZ -eN 33vyqspμ9|m0j|ɝ.VEq8Yu);c"VlU ۙċ/qlF%p쯇[Dci vL򰼼ܡMdN45L<|0orK5 '᠞xir{~ ܲ1e6\c^x\ .Hu3gif~2=!Hَ%1>6Yko/Jk>+)?oM6g N>>2`lK&1Q [c%^VAO$^>&(i4c[,LRM|ѪsD7.?drf&TY%)È؎w7-g?Mu晸M89tDJƤ6u?9S{Uŗ;/p7c8vĴ$ WH`zDؿtV,83PN6Ww*()c uGp?Z5C8G-8mBWAiKRiHﰬ2oġ0t!: y'iQ#+!CO3J5 `+d_<5ѐ'J6Kj4ԃžr6V @Ìkgѐ{L\>&\[*-Gp('9Wx%_k!ZFZvi5GK9N_xoJBoI+q͎IKdSa "~ pJ}8$~cl cƋHl~bđe6(T׏pEYaiߖad߻b.qNw?RsoC`|$F!+@w,8" T[=Iwq?>\~^wq !@a211;8~v !,8$afkd3 pWD {^;4AtbSv[?|gE/4i],ןp|^I+8>r#TX_挿 }1BQ~z^B%GMw͗Y'@yksNևӺĠa 2Ѹ(d?qX06>9rM7 D] :sCC,Ÿ,K7yKHs[*Nu=Ί8>X _pYfh!)zGЕ,Y,3(S^a393_8%Ȃ8fN,^? ZŪ!m )G22yďZםJˆ:Ymh-d.`8I "@w'3~?}NRmn6Z4x@=^޿bV5QˡtㆮYuA[DY@]+ #-8pQ;mkrCwYy>$NUسq07|+i7=ym6\᫼,޻y|QG2M9:m{q'qҰ35K%xħ!ڝԣz $^ -)G[V\Rl|Ay%=UdtP=٣3̴KL#h P]S"hޫ&fOT!Vtk\:{\2.Xŝ=.t0y>iRzFeqT3ZǃzKWKY*<:L˓ -$9_>XՃ-&| -iYuTϜ9#+ -r#=yoš/JVwv(O qZ*ơqˁ9ؗV'o|)K/+ypuQ1Yz@f=tvIy8hL jIa׈]u4'.f HܗR~"$Z4p@IJ ~;+wEWmkaꞜ9Sg FnҾI6(+њL}ZC]ѹn[ZG9Ɲ%oIq, u;GLIە hLġ-3.'QE8]o.n 8~Mq8Ox/-^Hj=Lqf_-Y|ё }*/&uTIn1t)Gғ7kH3NqC*e1z|.!C+Mh&T㢔~ 97U?+#pnd~h5LKCͷk;|\!(InCANh}cGZ/rRC^XG>;{Gl[y}W)f&ê&bTl\Zߊѵ|oz}.*'to}f$55ae{-8GljZ_& [oJ'|t?B NtRqуGw߆,i q'aRQLq@CXqH}^}W\aAVP3=z1=mb,[JQ[ȖŗkGTwva9X2|wOp͆?X8Z[|ǍS 9;^𿰌̪dNćַɳ-o4eܺ{E~oK:ˬ .:ۑ]/+@1BHwL JY1)B|Kk׵ 1>\TO҂tOqD^3SξZںyWq0i sR H}| y4:_ОnM5rG畆)\utlQvjQ>7yu2,}pcV$)*ї_i(u.9mymfx go¾'t#-DiHشE-G)&GH#վh& 'v 3!,8$<5v,$owJXZow+V>>a1/uUdnI7 L>bx´C œ2A ->Ŗl!*hInMK>f"j+M.ruT -7؉PFP.C]յď:uJF -Ge3HEŗ.?j77EqH狾;WWH#@ڻxuT6 ~)K,;K}q6?dsơ_9=אክ^Leo暽,]sl7b3lQ#"b|)c~+a񾀿c/a9dsPuAϪ缾QeL?BMq -\TUfx_r0.d>~{ډ}f.)_ -V9Stg)} *t_ |saj$4gv "coJKpe\ uW \ % 8V8BoU7* -uM5F~cG[:q7f#M5|(\Hb(y.(5j,LtIFKݶvh6A;oe4BLhf=6)􊔗krBMZe7b.Akf_(5=(7dIЎ^6s_ M5>yTNiyXpb+8\VlU ۙċ/qhZ/@&*-+<,//wh/=w=Y1:MR\ľ-u$5 'R -N|yx"tH?-RnS4 $:rbec˺a0\f<7dI; c`&jt[#D?,>E<,,yˮ:3[?z # ޱ1:ekk:;GcpBg߸ZqŨ^%EmeWŎc]9g#Bn@ʬnw`QݎG訋m'/C;b -73 -Zk&jxQAiP¡4kN_ǡլ*uxm%!vLJrBGFY'/3?H{W\Ƭm56QW;@}og\/D~^V^q_:,FSz<ۇxmOF-6q"1AIbQӽ[Ddsph*!Z7]7#vmK} =Kۙ9RM|ѪsRf>m2@9K3,aDlǻo?QM?7Od -JlsjNՌKpYY90FX%Zj1vP,8wqjszؠ3 }ڱLJN\t*!shV)Q9=τ/| |Lsġ % uO7FyZ8(&u?j$mldVR.iBWAiKRi.$̈́%;Lk:FxY Yt<&Ed/#Ot4? 7 bi U0HX;C4jr D{aFεT=E&.<0_ƦM\|D9Uv  !xaD 28ydSa "~ pChޡnc":燋[86Nmr}:R<ȶ}PO᜛>sk4sJߘ`ղ2Cf:VlR}6z;VKp"18cPW|!q !@a211;8~v !,8x] =VL=i!VPTǤJe]׃Xq~;پ5 y~9Y<u Ǎ}F]Cb}l~O,J6?߉7k!TL.~҄{1>Iz']vT2ë+]qk8R›|=ew=\s3uDP*'jyFgj%^-;Q%YWLQS{.[w|q<55V|j&yp?df/RCyhuqYx*F7ώBhCk ⪺|q1ګNuS!c5:cؕ:E23(z#C$-޺d;|qKO  $h]"#M-m(\KrfɴK:ľk{|4Y=kYTwh^Ito0j/Wh?dk{,4vg|!c "J-'27r+h* T<_sP^I^JɆO<Ք򿃷 Tr[&`½ ڒvb~*l}iӤpɑ,}oL-3H0-Olմ$(cl߉n1Ӓͤ#Uϓ9"UԞw2c(2ґbjFxPMpoc`Q6݁I9!sp2@CwM5L cVQAII5XϛHc۱~{K\z"#7Kz -Ԑm뎞ؿѭ7Cf!ygl ~*Ѯ8ӳP_=x3:Mt!@To+i!d}'glECvqHm5qYV~*cVP;xx`ױ6ܲ{b_b$٨$:tG܌%ylpص[M\G,3o6 })eND_5侔SPD 'Rxp}CNNzR]?BP)6㈁s1DpDj?~l=K-^97jŽfs95=ϺJC2aoj72w/, -麡5ɣZ3l܀RBGI/ʊ9@M')\s!A4O11iWI v;Yjp0y{z_KaS$-SNKtpd|mLfB{7M FIZpҝ)"ȫ&@u1%븎u2*N 9ѧ9c#OпC&%hЅ6os)kX}Jn&HNyhoԳQx(mvl<| O3-aCk.afp?t E:":(5*LRmDp =G8'zDGeC4qpY7&t C熙L|yx"tH?-Rncq稥D c`J[قϳ A9}\z~: h#<$:nMc& ޱ1@uZ!bqi*{䩁wo\bT`6zp?e_ %b߿yku~qh@{5fh[I]+#S]#b?T_/+/`# -)[p -D)4-[l끱XK7{ؾ=NttD%blnnF6ږ\#zY z>xjӌmST_@܈hqF!43yRH.)NFvui/I9< 'Hɘ/Ц.w'gj{5`Gю3]S#7N9~ Bg -JJAePCۧ,[r њ_!{KB6Fwo4ѐ'J6Kj4ԃžr6V @Ìkgѐ{L\>&\[*-Gp('9Wx%_k!ZFZvi5GK9N_xoJBoI+q͎碔l* DO11XoMd왽qxճZ38 Źtι(0, C;OãԬQ -v0D :HUVlR}6~@::z@CqeLLL C!( %9#O1m|M}̵r Bz% J=ӗ3xMz˽ZS9o'7v^.yN/}yC1q#:zE_QлXFz+Koq:;wBnQ^ e<0Oj!1%6M-g'7Ԇ8GO||DlsCz^00p͑jy_ -V,_{IGXFg_6~2-G{5| Cn!\3@m)zwpIL2[c`fs`.;uJ>N/2NO(z܁c^/+x,,ޫ _犹8Xw+W| pϯ^ gLsQhR/7h~-5+i$;lV=+ưZ?*LؚXqCG&Ymh-dQ_\UqrO5.F{=ީ}J6}=dZ'M/bsKlۺ';(wt+(H,d=l mAO:ڕvgzvJ6oF)qSW. -{e;7LŚϥi MFs+?Y1+II6y8-T& Vy#vޙFq7 Dp侔2'r_J)n(C)c?֤*SKq|s<s< t-6"ߍ ľ+p˺9ىw*ˮ?Yu@IU ~8j/8"khx|A:r m_=7n|06>9r7B]l$#KeB:.;zS>L}5Z{xVZ?qF^hkBޅU`υ8򰢸V߶T4FO #g)׺h3 gيOX|s^?Al⭇&R&5sg&䝴:w -d?z);)gx(C9[tݘYZscVf>YK xnc!W+d -cky:2u'<\\C7'`e)  |373ow+!3ڻ*9ɇa#uC.ژQxP -~"8SVs5ڹ -[M3oMKg{t;үlCyG>3w?>|?e_%yRVpæIZM#dgOGn> rGls$g юJȎ -!t:ȴRtv ;_ľJO3TOyb?DX8cتnmp>&jFD2 {VϫHIK\SL0U$3):zYLJ>$uɡəm? MNLKu0ҵqthgGhVvh]{i75-&]ki vP -8"W:J|@oSy 5'wq !@aRQd2Cg@rɆWfje ,o+1akLO)Ysb\c= -!f>Ữ~Z/76Wy_P-hmATf,7N-t64PCg{-C10èF:"!Nד:(e ~oCdr$;ZߗC㧅?5~dbcyǡ +0vkl̥ iwGGȍWSϋ_i|jc;t aCii/LPMmJ?1弭6ɚ@9B26BEDHWJ k \(Y11(g - };$F_6[sQ ?I N=EyLe8ji]I 8ElK1t8 >tpd|mLfB{7M FvnW:dsANFکR3G58g{l yȤ"a{ÍmZч0x}:RzVpVzhFwmp6.qH7p(>}!qwiW{V\ G[6:khn9ju0Yy=&o]­wr.0sW.(ek&V=pnaJw0.d>x!i讙NT@nrzh?FUfgQAHpc+ f Te Fq=y+B#lzC]W?Hb~v*3R%ud[` Kݢ}%[ҍiO4#0=vB侵LPBE`4ap%[y;zl -ZcRl@䭏لH -}\-Huľ+)v"Q PWurŭ*NeEena+}%:[kmA`Mjӳx_)M9mչSC).7{BJ+%z=dٽ/֚eg^To^LeoW?c/a9dsPuAϪ缾QeL?BMq -\TUfx_r0.d>~{ډ}f.)_Z9St -ݷ0L`7FOs-m)2v}`ZxYVo -Rwx0[cUS!VuZTi7֡^|LA|iwc<ߴ[ʇ2U([S yTNiyXpb+ L]UZV~ &yX^^&^z_zG'xct!S}[a'>RpzCCir3)'ё+-k3\kS#NpAY?sH|i QKB߆1 w aEi]0uzgbn:ȭu"S][xk{&(i4c[,7t}{|LcϽckuu3bѶYJ8г-ė9:7*(T׏pEYakiy칵zXT9oL@V2d!{3Hs6sTwj .X@?&>\~^w*}ܲ"70~X !82C&&|q!8HSig9#O1m|M}̵r Bz%߽grѭ1."wā -nk: LyҸL؛X:y%Sw ?|dyԜ~)RW(.nEJ}wPA3VѲi?_YzAq<) VFy%<bD -Ԗqj]b0kxRxsKms_C=NE/!!5ES)M2"uSt\gJj^9 -}z?Ckt柚w"U8K85H=]fnHz{F#]>;ukCh-ǖɪ;õ<#VӒpP0*]vЖK'Ǟk w[M=QE[љqHEsa:=,qWf 0B(,lژ[ t`Eɏ=:SK:L4?Rzfѧ6:[?߼1Ouӈ9|-#J4cdN(y让fia̪:*(|Zՠ59LwˊK*9(tb(e ->J {2$ROn:rætX:=._=g*!5vL1nnX&7gMVdžnս溗I1+^EIi᜹RTfw9h0$4p3mI3S%Ҥj蜶jzzye+JhwͶ+]/[YuK@XڪŦ19 r^]JϤ |D>vimB%},%m)vԷܲߠ~u޶1mZgzoR<%i$zS\C\!r4[~73UP͍!Ayŕ"mI:;U|6=ݕ( l.Vc^g{8meTNND9Omޏ#mf;rm 揍MPZ︪-IN[#@"^=tzXZMoکd.Aj8+#e.7u=1.Gq`onPHqip0f,3]KBD>-?yMf=c|)qUs% ՜joy/.gn8k$4逺Kt3TۥΝG3M_i㆕3wݷzMNs2<[ӺɇVO=߇M{^Κ9xAlsz??4]lt4~ȉ_):aU+]S4Q׋J39(MVؒDX3Ktwڇ-uV4Mr"7ce#ڢiӞ\yn=}|55zjKؤf\ - -]zw2.CUjh̉X%@j~3ְeYB tR՚ܕc7e&,%,аxe6{pN.)sR6 3R~&O<'|bpHn)tKf+r64HEPa3?b/vDە3$zJ~x?FwCFRa:se+L[M-xkdbwT;&hl Re`vMnyJMc-,ԪSN+L'IΞov9^- u#cQh:zJg$me"7r6swй!G`m};cY{WGY҂MM2א;e-rFOƆit 7gW4WtЛH=s2=sV9-l4qO_sݑ"brJ^׊=Q?ɾg׶3IҕdZd?DGyiܩ'9g4ڈ}zlR98kW;r'E|Pc^OahŬEL -5cd>"3 Ayd?Ц D MͺVBvI -{uE7=#2Q?6"g ux3>uw;&aVE[hsiUy3p*uD[/H\4aE 8?Out=>68b^zy|W?NGmԿ5rMJ*x-_uEzE)dij -T#!rtC< m -9:9?Rys|$tPƪF6=70ϝrS\?^k;MWM.7RMYlN/Y%?ηlMQy,;B]WR{?­|.(o%׭Z3q*;md5s8_]qK ``d7r<Vj:Od]x _[ȊP:ٷg-#Ya<릊U"Ű]bW[Z]XNv5ϳuȱidH|}ȷ Tq5i9=|K 1,D{@/U|ZuܷM?1u>,R RIw@O/2m`c䆉E,qe}۩ocn}~؁_0eƍWNfq|LoF2/V:x꣠sfB\rJEζalRsM]^n.QZO]]bͻ/\ẎNQP앉 ,M.6gjVJG^3^,٘޴?M)lglwO@?!"!b!<2t◪3h7:d]'+?t Pk^,5g:szj;Xh96剉(n#_xݭe#32/}UC-Ugo>b\æZO}uNê[nLmSszr\x)5~w'99u+P=GZ^Y|xx_-Tr2ř[KtO vcv8MY2܎ֳʹJ JGc=IbźuR˧ 66;f<6iXxFّQj% {,rnf{?,ѵ.uvJ9`lp@%%b)\s]͸/M~Zi/gQ-ahϸw[78hA9*w0(]+NqlKmm?fJgӇ;rқ~eſ@6]: -*x[Kb6g&.R0ɶbՈ3 zveh*Q=25o+Tݽxa⓬W}sk;u~ -Ҭh}?<((8Stm\۾)>bZϽD6LTǓO{f+;f)imB`F$iߢ@{IP~~iXhoߒZ~([v힯fMr[9^ap G9gadCFs-x\+ukrGh:`Qggiziu'a2kkO()dgb!W'il~ضuI7Ae=) "&Dbw39fF rõ)k_{X+:ẽp9Sih2؇#m5$WjjHx) R8"2 -A_̍|36a1R7}/?t=-p$0WxNYeLNb>ɡ q+A7*H̜S6]htwX5k?P:l'Kxߩg6ֲr230 _alϻ]EZ=r,j̄$_ZfrルO(mؾh;o6MAzB<1he\1 z"lג@/]t^K=%8l c)?Dt-"E7yO8f_&9dww|1Aj7>!GkSGiq)}'9jn!-mY(*5_xe~&AԟQK]p;J+s dCն9ηW뵄3Ws8a[l<-o|5!$Anc& ML6pRΎC6uSthI 8c[,Z+fLZ{γ-s{-y=[|^.q18Xj;,cLk'U+]Q趈aLg(%,wyԲuk]ՓqVUɼ+m5_uѹM5PN_Ka–o8 6wU] -Ɨ~+n)t{aeͫg`a;ϥnD^엩WފXjmpn*ÞzuFkM_s3oŃb;|Zm69gWi v<;4SUF L85B+'^반\W4x#2rkHzGcl|(c-Nw%3䪽j*v]KTS?nZzB@Z@GPQσam=FGg 2S]VWW?hY2mꨏ~h\d6~K(ᷟEWAORnXˇoؗWwK鹜`sӋ/ШF`$sm Lap8?r3^k.ƴi`^g>& þkYӿ'nzrh7h=pp}$%1LKg(,>ziM7!t@SwiKn#6{m ӆt0HI23Iz46HpLQjcd6ro:jįH}YS:uo:e;NӼzU[r^SE ۡ0A4 t~];L5\Q%(!i=Wltܷ֔wK bKe+ƆE/k+.3(R'=aF[bU7C%ēO};'xqOyjbCZJ/f z+-Kϒj8 u0G%p1S m/;e-rFO(ȭT+:x)?Q[+HtVim67h-qWL"]/^w. -x;4d;ݍ7Kepɧ< Ӗ+6yue!-$+i~L5 _s!CpLjqAU\7MhIwZ'OPؘ.0,(0i?QsBwLjȪ/x)FCcN_ix9ms=SU&r|nlD#]l\, LKuW3n)_Ssm"3ݢ\$$Ox9! xJ~LIE-*Pd~<'qʶmX?/I ?oD9(-O*f>UHV/,2kr)?]4>n sk: r 搁o'6 -rߜG}XVoJ3E_i|!׬ݱ8vW_Ô5 -^t#Tp ʽj -̴5fQ9__> iFt .z&r[DͳwS4Ubx}V^RvKlG|I=rIBm^i6=2z9mw}z?=qkF9GYTK˷J{)Q;/q\I'VJ%7N~q2k6afLپ 3m&$W6K!RX)ARXC^u2[u_P=,ѵpͰdɵ'Cݳnok634{l0[K~u!?NrYD68HQ#O:B+ug ?.zaw;w|~5߰x*`q/ -s\wVճ|}ɷfGnH:!TcO~IDoх?˿HH̉X}ѶirOF%-y^V֛;v9LdA&ᏅxRw8Ix(QHyuBgnV(m+z*)=Wx KVgnk$UlPz웬2iΊecW^4o'c8d^n}1FYr52fKwOf=T\4tf:7$g*2}-6ȦH:tESg7eq\WᏥI;9.$d_Alxٺ `DVqߨ o.vU/e˪KNfidsM6n٨hyQCaW _8{I9oCY[tGUh8;FmMmSszr\xmJrZ*F ^ V9֌%:%SǑ 2Ӷ[EI~3v -ۮb3K2akF0>o!)a?\s]͸خ'WϞؗ^+-hQmMɺ}@9i2]N:hα!' -3>+H.UTwc6n Q^Υ`9\"F5aVclVs%=PJ?ʩd9_wnGwv - :;B҂dlpI0]Wa|H_2axy4msx&JN[ /{} IRCG9l&Ppc vX| -ڄ !=TV;}WK;X&,Y0NVג):ƻY9zjz5{=۵9$^Kg6`{_Yj;i%c46wo՞IDj6}3w\g֮a -ёjb 3b>nl' v5Njl9-OoyvP\q<|*^uՏ.2v?JG8|P3AŽM8u7J>^"1OK9喖KߘZdqOQ%10mqz}rH=b{b';B6oΈS>QN"4(~6FJ)C139 E \73A=Ru:5#?{EuPtGI!ٚE9q:_)<jˤVfi~ְtW3Ab7a+o;^uyi{G[ /RZzNԾFuWuzuFkM ZQ;<]':ݺrǫSЦn{1::SF/wqZb M Lʣ"~;s;SB=]%m)vَ-leA8f{ImchcMrh^7H V*h]=EGD߽x~'ݵǵvG~eޟrq~křΚ$d tv'գKI.7ȋnҤi8e2qBg+&C\jv E&HnT;̦0LlPuū$Q %F(x8i39Tm -S*oJ(ͷo 0X+B&,]Gf5g;wi-w>H喣dbpX-c3 iD+J&fn{pN.)s\7Tھ>#i(V`(L ~)'{=$}X,4m}jB=s2=sV9-l4qO_sݑ"BGӸSO^s~dKfuO,<{OLb ھ9pcvh꽖fk}߽# r)ᒜoP$[W=mSm -bQS>ڸEfE/3;Q2,s]owrr0p1́89@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@~_rQ([+G !!!~}@L<[VG53g$@^~g!vᱫڹ#"_>sv[~!厫މN!8&LlssD\ʱrIKXdo9=ocCr1<2h˛nFC79\Lb? 122YPԳL&1U ̂"\C>2S$UHç-l|=۠~/]=2v>dhl 2ɜ!E9|W%L=ÌpxKL9Rt{#ydSe]91JYV9z*}J`YKdzgr!;&[% vW=eIp.|v_Jf T[Jc#4GQoDŽgi94y#PQ0mRgʇRo f8mhtN)gƮ_feɉe{J~>vk#Ƕ5Dq{qJZIlQbl)MW푺iWa<ż 4Ln:Lekqxl_lDSRzrF6y,át5HI |jnr>us0>:nJRVU-H݋bn^mݖ1Lo!E9>99jaeXRT쑖wܰUH\‹е-̷V$'dzYrs|tWd^˟FGNПSZ3Rl"֦I 2>д(]jh{!Zn=g.\8u0"׏Ck6nky'G ?w4:,5OZIMעLO0OH#=ݚ"5^"3m!ϫS:ʉ2ٛ>9,_\]Q/,>`i>xqZ+X߽Тg {b!E_99k^r[O7ȯo]+1}C뿔C:|_!]@/. rH9އr? -2×BI!r!!!!'`9އ -endstream -endobj -273 0 obj -<>>> -stream -x+T03T0A(˥d^U`bjhgb7161Գ44CC3cb |@ \' -endstream -endobj -274 0 obj -<> -stream -x}AO0 -KJԋncl$6mpqB;I44 U@-l|tpa&AREO?_iԍ~!f)ThvlrެL*JzEw?r 8f ϰYq"4ǝiaa# w?bZda. -%MdGٺdUrhXEmi}U&\5:L BƌJ)SkM p\2D#<:?Xpi -endstream -endobj -280 0 obj -<>/Length 32929>> -stream -xw\NӖpQq -"QTE 8p{8P"@G7X;RVrI.y\rWSy@GC -iׯo߾d -2hj KA.B+pMrLOK¡z$7ҷo_P#/8Tt5ˠj#.33Ɓ1wo18wm=/|6[nB?²Ɇ~/i #E4x`8] iU㇑6)y}GLUpX/dղzJ[m[=CphHW*˰ʢx=/)8Jع;iO.T'=`I$#?exp$^Cs %g|~ͬeK޷-|&-;AYJ ?3>cvmmx ԩSn^vهaÆR$xaÊH,ײNE2VQIFuhBo/tbv[JF -b^-m;}5.*wĈΜ>Nb>3m-ˢg_JJ -.==#F ' V̪)2|T%8O %'#?5wԷT*yE8B)j#Րڒ-c Kr[g7^]q.kvlRٗKKKqȑF/ޠzx^:+fJ{},O4g([rBVtz~Ar,T=&z%&&RSSQ/QFe4u! <.2tcC9Sx{.2X vÖZ>Q&&w$4DPڛ,xuJ,EXv}^8Ed헛a5&$$޽{GT>4>_zPO.$=֣2(6y̑-a9J{ mV,S^+{ϥ{qqq4j3f /P}-.99 Q;7ˠj|5.))FuuuP#/166HWA W^j0aAK\||<]'N52_xAScC#'MB ե\-.B-{W:>~ϟjn]P#4ARغ߿?}?=zhΜ9]]x0YW -:LIrRQQ1mڴ.,/1cqqq̟ZNrƏEl5vayU./@͛߮k ?5ұ5j`;(3yK4͕@\W7eô`[&0b&_F8uԎͶ#ɓ'h8(&03ps%&5Κ5JA#P|pZVWUcee)S0ECw6ájDFuuuÂ̟-Oy\BF -rҒ?8u_+3\kbghLT~N~ -(7NXQYVs֯W[W8ҏ{G岡2CwZÅM %oc2zNPhɗ2mHi܋e ޼yӬksQv?n"[h ǼL8H}134jdV#'(HP@ -_6 #OmFUڣƚwKtH}Fcǎe$L^wQ\i²#gyl @@t) -zOdQ#|5{LZ>x܏+TeAOl:թZ~yy馫Cө^[TP. $yµ_䚢!ZF0h^jCyA~UDN^~+{ff|LY<" ̤H5}voDs{ۿlJ% yo,UlF-X&mQt8 -23h eC/6e[N!cMA"HTJCj>YYI~]6ktBL5ZH䓕lܯt)RH%191<"ԲC$ -7]שu4"iT -e&{?XUU]ܕ\eӶ0Z>L#qp@E\o@U!Qݰ)qZCd 6|*Y?\(S:r:-3@.߁}eL%D{ۛuw*RMx=}{(6mNjDFẸfo =8MЃ"B֖"Z[d lW&P* Bq~9^VQ6)ʋT< ' -y %گ!U^x?dfSp|v"c$ۿTȸsj4ڴǂOL, Ssv_0KB8hҬg'sEwo/AXp3jŬ+6{AvJyݔ'mK6 0853jcHx;J -R%duv^^'ܲ@[=T9&M>s\oQ9u-;_>M~޳FHl~&5<87;J $E–l>Х'VY:cnar6amڻ8x0Ɵ1"c|\BRQ<oMN3]$˓KU?NǴ M^&2ufwگwߏ -ɵ7?4w$cU΍gCS㻽N-PMw4$o[@0tΚ}4yc醪q„ Y{!}e,ϯpx3s\I(o^?wvCӊBeמtpәqv +Zjy%\h1jhMu<1k;Z]GNj/^3ŏI))o^59lȴMKfv"޻ 7ɧƥGG%V'n1?1,dyEd0͂ԒF+/l Q~@#Pnj/s__#qeQ])vo:*jovg:#[!&muy/mۖw6CϬ򐫲^x> l}%JHiφ+Ş&/95M!Y%?K۹UƯ4%I`mW+W=[ws'j̲ڴԈ0U#O+6&ڞw߱Ȥ]6#hw)Tv&Zoc*k\ǏC0nx&5Fުrv]=ո$OBvVCjrzx# 3񣯕[/sf:YM, JY%xnRf"'J"vC]jl%ZWZJ]%Y@_tg箘Σ5RI_} ]voN i4~Rfa/r - ˗/Q5yaǟrlD $e%xGBkK7RbLN2[vbӓk/R7\uRqVզMB}ʞYԠʙHoPxuo4//CUQ ~K) )O }XkPߒR@ueۥƪ8K=agʟ;~ -><ʿ1|94-!V%hX.[KֱUp 9kyM :HoOʻd&Ci - `C镦WF -b>T¸&5vGblx$zD*Ʀ&3瑚,T^mH*{Vg J%>߳q=GJTڲ~qꤝǵ}oY"-20zg]/PGs'!u.[C&L!U|O;IsnJBE(۽kz wGដ -{ Aއ,k`.V@x +|Njt#\Ԉ~R+?,L rׯCB,H5VPcFukġ%)oX}T͠Q|sP#*Tzx"Cw`^ԋ-GlyS7{DF7Ѫj֏oҲ% Jyd_%jaQ#.q!* -|OCӍjDyEyMl8D{XJmF^EʽeqşlدG̊r~8S=vh e}po'u%C*G.c>UqD83z8jDU ׅ6\hB4ʟ ̔Hd^G\0;뷠Fbmៅweu_ݷ۾Gq Nן<=^ d|eڮFq RQ(2޷m055ED_Sy7s?0VK9%|~E΁&3a?eGRRRuuqsP+KJj2r=`kR4pSWT# ++\[RTAOFQ5^BNF/XV\Nc)Etllѣ9E܋;"w!I-':sl۾A=D -e әK5{R4_UJQTK~*o[FU:EqڢĶ\UW ((̽/XWDPfk,^p8ukԕTQiEWXadI{vSfy`fƯvղ1R( E!i9!<'Rez~9i|xOLFJט㉎j⠛P\NiQ5;v.5;9vF4jdV#&A"uťD0ORcUAA'{~w+K^@@;T;s!wKtO.Sn?\FT#3 2Eͧ0/șsnHJJ -1ct@^OJ6s`3"0ׯ1$9D]gU>y|=ϙJp Ǝ/=1!G! -\1@{-Yul$)WLqɵԘ5JfIp7oޠj5j2ӎP6rm:A}d}\.uZy[P#fi>}tU52331}l?V6njt-ܼͩe/CFt~>}8j?V6njt-ܼjl"Ë(DBym???KhFFqJ͕@\W7e5Aw!4Pc'CWcZZ ;M\.uZy9222HfBUU5v2t5`V#s++sJ͕0x֭. {-DU333jA{Gͻ홐_<4p,? DWcpp0g *-?Ze…j>}zW Zͅ4#EĘVSSCګF+=Jgah)B{G͛F'2| dS\]qqq-d{G2=5< yMj6Π*Gbz=!455\!N>3S jFV찺\շ7PPcD -;Zy&pּXa Ajx6# 5'/0Hɉ{}=ʼnPVnα؞[;lU ˌ5ƅ;D"!m[sRUt5jEq="lYEtV=7otS*C[ѷ'\hԡm}mgCWWFDǩF8F5< C̑"}I=C'3h1Pj4^;lp1eaËfjy̺'. ԨƐfAqYydxTF+#.k$W]t}ߍe.t5|юʬFM=@éFT'&M`Go̗7w欱*yjNv4.s:̰ a p]CW28 5&r =H8vO5<2ZqFjCI:6޼ ~-6Ddj|9È;n0 53dD6:|Z_8ƍ[?wo<aH*}+`O6*onXE0ilPwo,Rh1ϬLijP%FrvfypiH]k=1"%1o|U9_$ǡ1&&:\9P#=71{9dD)S6P%N=;%^$IQ>)N35_2BԹcXfCvp] g|6I!3STtn8XAW;ac}د7_@wn8?H4t5>}Ef5Euua0Ǚj)ƩS"6sFhw %0<14,^LIwt5>yFfUUP#=Sl̠{ڴi(jd=WAwjxlD+ZjWlPcBW#zqdnPeFk5< 92E3Pc'CWÇj"FP#%'7#Ee̙#́#c7@0AU3ie@jN@jxP#wjxP#15oM)(6=7ڛɔȎ5aE:;WZEFxRqړ22B-poOvX@jxU#_ \vJ0.6Cn9Ck "$'P[WBlq!-O?/GP9fGn8ՍA-1zP#̍ŐTTU1OBAIq> ْغӀ^0F҈YZښ3߶J F"G:,^:}*8Hs+߅F -=5C; jDJi.5~XB1}fD?~P~:>TgL=<{׮~^J3@jxU#A瘹tLT~;ڍ{okhahदK)hdN뮿+F|Lȕ-'Ŕ33 Y+W=ans393L/5{UA[-mdӧ&]mş$$d/*h|'/֚;Jn\vQJA}4Ԃ^0FQ[eOs+Y)j `~\3Ej=pZ+2/2@ca׼j]dnP:mdu5sҲ&=y 6"5̓neт%GpSćtݹ[|tAOP#CFpNT,}#/{wjt_j3N cbmIq#LUzzx)ClW.Jj8]裵f+;YƁbcbF>9nw.KQØD@PWAj#4xeCtΊ4tk=ZX4'3yvw_qه.jxP#tnU>ë -_VՀbǑG.'VP%lNΩO͢JP}-[}*-}l]i}g@ؘ[5 k>{&O YD/Ş{j:ZHQlχ&dUsEUP#߆SǗT5Vghmf8"{S4?$;d -u@j5a@ u@jN@jxP#wjxP#щ. ?2F5r'F5< ;5aɕߊd)TiD T駁SeZKb@jx?FrEYǃg(zJ -rb]ǫ- ONOhn:MAc[Kb@jxU#sP9|O,CĬg*Gj "UK оA䚢!yE!ϕ -߯_ư f"謕ET %FD˚Bx}Ӕ=Z P#sHO~x3:O=Y,L?t^G=.ͨZ^goĻ)O(ڒ)5oSIAj{f,<2x{CVL #xqËg~)[ -B.ۜ@Lyǧ:FШR-Att.Ԝ5V.\]Qw;"YTeOLt5JTj -P#0 8lmWH;2YתvoDI1n}awmQi I~ N4.+U{9Y"\F+/qZ@"a71&&5 q[S߃o P#0Fsͪ- f~ BG6y,U)BkEq:}axs@ !$FVĮ ;4_Wg [71ڥx Tiʷ̒Fk|!UgE0ކ\SjsOn.0jG veܸqqI\eޛ7?qT3_WlbFPcdSӍhRYgB/=>$m-~SXƏȱ_|T搑56ljdxvea}K ۚǘ7_ 6=5x8q 4성_zx8]F5ve P#PT#cZ]]iPRj Q=A)_v,wq5'l3u-Ɩo4 lupl rڕMaMⱞj:S#T=F$߯Q8ѓMc@*}2eb܂}x_N.-f/,H· 9?9zpXpz3:lAwA@G[jTZK4_(ZZr]Iըx(a ?2O՗Ԥw?/*ngK=۶*cx'{7sw_ks혲`ll^dhY`Gf{*H NBtߣ*UKP)k\cF諷PaW -8":$:.̫RTh QQ#TQW#@>:# -e4dqbyHM J5,jd+!}HF+_ڣ2B!(T)`ZN5\w>2+,;]Gs.[O"q̩C;jou:yxFL)U^QHʪ%ou5/K9Wk)ev^Yc-۱Ub525x6'5ٲhM:^RcM}7Aþ̀s]Sr,waP w'جRvmU\f8\{Nw?L Eo$$w)GL_όJZU65\.\Հ;fvX<~ Ua$҆9vG~~+/Rt, ɀRw^˫Z5g\o{qmSc,\Kj|l;aϡ؇ &ƙVF8mbn]}P3s0:?ZbڥFjCIѷ']_1v -3!㨫[ 04?}p''oUن\%[r$MPt@81Lӧ]PﮚҶkWLTp9g]r:Hhs0eun'nu0$X#[n>AX튊 t kk/t2e{ hVDz SSȏ}K̥^x^ho!ݶZǏUJ~T 0ʩJm[+I7{RSL6̄e$mڳ?v+O -X;{!G=Vtciai>I^ERQ٭[$p=m~̾b^)ݮOw<,^O]곎.-yɩ箏Zum+*~\bCW6(5#fTi|*%5V5m:R|7x(3Fr.Yx{6jgNKeur K5>+oj/X-Ժ2*nC-{j><Zv_>3GiTղ}rm%UH9!ļeW#' /;Ԥ4[yÖpX[lͬw|G!gr<$Q틷݆GBb]jAwCg%WO x֙Sg>Q)9oq=G#͑xjNZyE|Aں'sxxF#fɰE+~Zhq{|lWa&{>Z7"kB6Z;2 /u8[^GpI?ߩ7ڢF\TlԈՠ.ŅUN%yTř1|\%>}%E&  7 :wH࡭s#o"b>-M|pZ]E5׶Fb2>0E{rk2:~j#Ud,H*_Z -a_R#k7[f M +J֐Ӝ~0gqX\sPe4^9ćP?K1T6zΈY!'TO( 5i>T"֫-z fz >nc*§i>ip7tF)y)6I6@Ls\v7Wߵo46]70aȁ yQ w sܯ|慥ʍjU9X^*?ĿF:Fz-?M6ۊӗH=Q'.SUM Mf-.onarM:O0T_+ٱoP>'>/9]֩. -5WW`$2oNukTGtu8x㢮|01ٝϯ8GM?LoG|?eKn^)hgc[ BgU8wO͠ݢ:tom#kzۜBda W'>hľ2m> vO>xVhM{k(Zr7{B7*h-*w&PӢysIR39w|v-rx3׺_ѳi6^uznj~ I|\ͪԊ =<5RMMݷrzݐiҸJou6^(屇7ۅ-W埆Woeퟎ: {{ B_6IxuIDzP_WFTyz@_+W-{P15Tܗ&<ܽCD4@jlR]_P%4̑q'56G]fxɾSֻ*T P#jZ𧩨5OZ !𧩮5O@X5r󋑩kwћ\_fU )W[kWޫ/q}uR{i`j2JT7a˘j{ Z|}DG#rK':pyx"R+J9b(U7~Vִ֨SpuAwK:;ȅ7 -7DD}[].lg.}r,ʃC|&߮uvخgXxE>Ì<-Fi^2Y8U By^|S/9x *6-`_Z⫯D>+v7Qat71ĸc=׆] [Xr>Zy0k^w}F2[ M^3s -ՐK_s<߷r-Iya?V}KR)/bP䑟E)IF3e٧7>䣩$' =pseYqAG9EόBy{J6l[6$Ismu -lS!a@@ҟ~8gYx/~ -&(OOf}eN1Rx]I}ř ̹ʳFFNh 4wo<|\={--1t|uy3!r ڙneɲTT륻[YMɾ6(}s> ow|"c qACuCW,˽ \J2mɚM ̚s@Zi$O] vZEB, HbGNқI#-b͕9beԬKR˞+~8w=+E·y4ol[+tm/~uQ?v7ս-\xF_7iM#JZn>k{6x0(U0֜wr[ze3;2kaYFymM}eزJXCysSq-Yd(%Aǖwdݒ~{؅Oq÷ze[7GSD7AJZ>#hZj+~ŵyu'?,Wߖ`k%=شؾp-[l?_/D͊zbDԳ,ɮ*:-yB64r4 O1~G׌7e 1քYubն-([ŀmx{5I{XƉ(H\y]uG֬mn@IzXtڻ6Z3 ~5EtjzU<綹s_nLNϷrc]ߘ#O.V31yUam&E灐ꧮ8 oޱ?jYh5Z랿bxcCKm%~qu!&I{,MSx!E1C!q}&'Sq_-:UOE?ə" }zJjRuUA:g50_EP@j9<0Hn|;&۪C-bY0ޥWdHk(e$mӐ`U olL9 9kYsN޵v_b7ak,k'_3a_B{VyL9~r,uialG7_z=fIٽis+mj4Ioc'ۮe-E6Lfao -qɑ֖,K}g.jIw/%W^gήt|v޻0&IwMdpxk(T% {^C/^ZiÑB{>߂\OQ&F8=1.Env`㱯|Y{ٰ%9-N(B+ԒNfۃGڑs +kO~_,[϶Ūsk+i7?=a%o~-?8]Z?YJѽ,9KH>ݼW)Ӄ\L{{c]]+Ր"hY~Bzf5Dm==i2|[)ݗ܆a{-N0Mâ4Rѓ>_%6Ye})j"b2{ mK)GgՉw}﬽ꎲS)-yB]eUMXn™,92G>@WQ{ӎł|2jk5{ -j;JD۶rtK]89GOvng#5UΜk3 } &/cng!8u)x6}yw$rhy !<>h(4zԎl})4TaPc547TPҋ"b,""%ݨ&AEKQeBT.$ y'gfgf ?wfvfc՟Xn՚[j5MW9U=ʼڏ+ԨYM+͎Y8yOӞ(j׬mEݴ8^Hca~^~7%9~h-zf@y;^V}'>fه/^ޫ&C? i,w3rjm\fR^i/Ln?5~pNT4J3n̐zC5_3ʐFEAND©nL&#@F:_wU<~{)Ō# "6ɍ 0nr#-ؤG繄ȑ'N[_UR` gD+ 8ʿ쫁 N޽iնo"k̋lYEUg^p\VyJܛ+'쯳r5pN sn$\Z=4rL{.6 .|8+VfO&}õ%OUm*m味>K]1zߕOhX{.]j|JNK='ٌաwk?ũ}kE2StHSb;yz}9jU:G_y+\ᴴgoi쿪rHY[֏}}ܬVmI}Pasc#W}5´nҧ,[]|FNY] -R~_wVDx9Luc+c3جu+QO/^m %e7sv;`pjQǚyX TJ6m^ wM𐀢>9>wzdۀ ^E@;6eu<%7iI}B6;ɟ#M;*inNVaa'RR;;CTRif\t΅~G-oٲuicݳ/C/u i}8^We6Wju4 ?5sˆAmG\1(+%d9UssmM׏_%fдMC(㆘,tʵC(%EZV:Q'aْv˃:|?:5_}5 M򟺨Y`(=u6_)[0Ow}2'ԼI?ւԓF'r/$e^WSwwlqV,e/}LDJ%}ׅM_ZZknkv+FgE/1cƨq)E}0,|]W1cKn)NCҸ씇rb$6Ls9%_>:kCµ?[僄E{_VK B mNm޿hY41w2 nu2+hEh3x;&\ۯ1|`*ܮXNc^҆)F2Өߨ1s.ΜAؓueAL vU'9ZGg{_kc458g=?WE?'xٵ?||YnӟY 6kZM!W ꊲ,4⚽×R>guu'OIS\ -!da*reg2{yB^b\ uE ξ=yQcdYgzgH䔗^ah,;\i݇1iTȻz4Izgi8'7, %.5jmz[ϳk (\fz$i*[W<}&)&譌{~Zf 47[YQh8zn];6' Tl'R VZ:8>[cժ6yi+m |㥪U8XhKܹS)gw1WsKϼSuQN1k JZݧz']Df\WM,3ANfkL΍:78$ EZ/dT(|z+O*Iu$uuuАkSGnYܳWɤYy -jՔd;ZgBE!vy #724Tgo(u@ {zpB] -ی9_Шs]͠n?e*++l"|v$[S(ͼy->̭hV[޼ʐFEAN?YCff&i4U8 w0ҔB>|҈ :ю JO?~h-5r;d.\R3{};|Sk5K'^1[hmNI_)W]}kF61[) - -Lc1|Qq#6!V z*"K=b>>jʎОwїf<6G|7h˴mVϾ8Ѣhgk&zj-4.E{]@V(/eBQm|saKz;O[9c[Szʠ6N>}n- ʤ1ʜF{((Ny>jJ2o/:LYԢbٵoZf/J˫VK) IOA̽hFoS76{۳&{l]a_u(mbgk.fE ^nV*K4}3>YkO}7mż5{wky[]~Invf(_ӶewkK -s7 bPEvmZilvsҶy'B8p++G`|4ei5kTj㩁K-.׵ZC?9zG4Ri4;[{]im1^r=y!]&!bdsXis+MV톔IcaV¥+,$Xmǽ[&^[/olZ_K`oG Qh\nCo9qW୐ٷ;SM>z%ÙKc};FTpwc(dOۘ윲qYw-IDZ{o8Tƒ ^Vn2-i*H9iUwyҼw?Yϻ5qzMf]m"i,jyg4iTpoe-9nc>hPO bL~`&~yOOX^+/)r> MMѣoW q")OU?9^RNQWTȻ6H\ŧ81G.T[݆7%^{޽/9|աvI _FÍyo -vS-߉lkDC|X〵&=fܻݨau]#A^X^:U -nl`~}SeWBg9G?ިiw9nVfbOOXkŮի ͍o}Jruœm{=7^*p\W5'~8EYW:^%Bƍ /UXFMneJRR5f߉mKɯw\3O uRX|aZ֭dq3\nawn4^.qHjާ߻o76/=O13]O9icetVݩiv=x;}dԑK|ǵP(/6L gl\IoS6^+gjM7|la&!-Δ) -%}ׅM*E1ii, _aX}M>=/i頹?qQ'=+s0o,7髅.[&-vԠ]P4炂?; j{g:Zv[hFԧƍ=Q2?ZO$ "zvc)%;TK/'|\Rr8粮Iԑ==y^_]40kjWq?Ut-#=.kU'nS;P*%F/ -5qC8yZsѵήY?wxɤPqim\|ͻrb**Qd(hԱ$GAްep.J[-X4z^% "ŤxʄM?@i,N|E.˳qrnjnϦI3n&jWOˤmsw*QU_y:vO}GX%vd,[jir?뚮WTP%8gWfJ Gω6C'y/kRFӏ'85k}[ן(lwv>)x/} -E|J}= -J 7.ySA 5=r]0!u%Kh-a`6ʗFz3M>:|i9NΝO- 8VqoHKϡ/Ѧhpiv/++73 -?ɼ/iV/{^5o[Bes3X#9.ΐj}g;Jk :3Ѿn 1[VZ:tJMir%qj?bnBv6>m|rzjl$Ϩi1l;MWXel9#o7Yi ް-{^g|zE}V~Ōs3N>U[sueb~z~~׭yv贫{WK98igƔ;Yq_Cƌ+i*[56nc'#, ڼK7{w3-*ܼ*i?Nj}k\4Y0EqbveV%RTRV_;~hW6t),}ʎ]F,ZeSi?(փlvǸhE/N+*T2W&d]3m Di,> =; @NXkލ}|58IȞ67f;g뚾ώ5-3LlǸ^l2qGue.?K/ZvNm6n<>/:gT.&񳇛|9iGjuM:h3ι9YոdyB G.P_A#ċ~:g~vv!i|[ -nd~sעvj)*JFJ5u;aX7nu,Ҷ&K;k;{݁ оN,4E4xǮ*hخm~⒳_JA8ݪ/C}uŜ-$hMx!3cT}\x*[~nGjtmlPĜs%ɰdM߆옅g~4퉢vͺo\MqT4o!H#4 H#4 H#4 H#4 H#4 H#4 H#4 H#4 H#4 H#4 H#4 H#4 H#4 H#4 H#4 H#4 H#4 H#4 H#4 H#4 H#Mo>"?@Fi@@Fi@@Fi@@Fi@@Fi@@Fi@@Fi@@Fi@@Fi@@Fi@@Fi@@Fi@@Fi@@Fi@@Fi@@Fi@@Fi@@Fi@@Fi@@Fi@@Fi@@Fi@@Fi@@Fi@@Fi@@Fi@@Fi@@Fi@@Fi@@Fi@@Fi@@Fi@@Fi@@Fi@@Fi@@Fi@@400׽{I#zi\ʨPCO/;TFk@0j@FpF\^Fi@@Fi@@Fi@@Fi@@Fi@@Fi@@Fi@@Fi@@Fi@@Fi@@Fi@@Fi@@FAN?y:[M#Pd2{D"gH#4 H#4 oRLLLyo@uM*JcΝRiyorF+4V8WNcT⊓OrG=(>zM]"P*p6}zWZ=uݕ /ڵV'grnXKo iU8anQVML(J%JkIRPTR(( -=RѩX TZN=*nmP-E*u4+AJN*ː==|-EkkT*)I}DVʯsoY{V-5nZc?㋸z5Yij3[/s_,l֡FLJ~n +v:I95,[jj?N‡דX^/߳|q/ȍ!wPtKsS2/-}wmWnbqZz 7U= ƢUY5BVLXo-[[5\]r|G T* sSw0Ba]&ԗd*G,m8DkqZJ=~5ezm.znYV5J=lgv%PU4Tu3lPh;UӖNeO~4w@CSw{hY)[B?~iGfQOګbLai]7FuNF,;~^[cZƇoY'nօYFA!1"bvIQqAxt(bzZWp|:m!]5^Zoi\߫yW7c' r/M6vu(O/.8ҳ:i -2QQ@A:JvOaԚُժ+g4s߷BaF("|Fnq"ν|- -Y_Ǐ5F*$iUӨyn)]Vy?|Fqш}هKWh^i@M|DQKMW8{eFtņ -7FX[b-+\#_FǦBFFF Sh1of>Rn-WV煒hm ϾRֳoO.~OGOH#w-3&F|4?P>t.IS[75{sH#7"9w\I{|ANcF|4z%iޣi{H#7*pBIuN /kn)Jcyo@፤ɓK.uh~.Vd?H^nI$gN\|X'wVIϞ9#rJQF;u"wVIϟ;'-5vؑ4Y%ipի%ilߡiJxKض];xgK8TZmڐF;$1WHn޼YV*IXI||XK==xgkĒ46oт4Y%i'IJJ*IcfH#U7%w)baanEi, Vb޽{%ilبQyovR2E?(MV/+W,O߅ {+J@yy{?2<(CIIÇ%+Œ -~\_릓F \]-^R[U)Ƣ)e2YHIrr-,W"6''e{+J@yy?2W)2i,O M -endstream -endobj -282 0 obj -<>>> -stream -x+T03T0A(˥d^U`bjbgb 716M,]= 036Pp -BkH -endstream -endobj -286 0 obj -<>/Length 26788>> -stream -x\hZlAE O=Ed D! E\"* -m-~>wBH<ɓ'IPEM3} ۬.:(?j,C CqQ۴z٨=_=KX/qvZ?$4^u03@@Iu2İCOsH| E5cR2xf5[׶6/cAݕ]Ӭ&zMp( %m6woHeS^vgZ׆eӔ8Ol{.c:?y -!^Jzfi#;wBKU ŋ,;;ׯ~522vc?_f,ӄۆS:qbpNS<8q\fF>FK ŏ73ş_B+l>Q"`1YS{:H]VMۧYPo%) FcS`zDC_̝Ž,%oKDq^q:&`>K[[ -bo>yB&v=ڗ'+v}C}s"98S4̼g ݾXG4KuAtO{[-knTsD>o?XpLk]wǖUmĄnY8Zi< -gphEOiV#k"H6gB˼~jy [{Tu9izcgXsU)Qy-IǾUsq*qB:R%Oq~D -]RoCw@ϴ, Wjy/!hQKqH{i%,uU7{t2pLŒ) -̵T#p~S0/ dHBEɇ˾5򭮠-e,իsWڈ=1.=Hub=JPYW -Γok/=GVβ*i) @yOd{]axj!fdu*s@R0&V2m'ўkH>&6oQ3qX.|uKv#UDzE(FKjCE;j>ٟM.&ˮxqTnӯ>iX]w)c x_qZ8Di6P;I(7?n"^8rf[Ԋ`T"kܳäaΎhQVcR`u Mil>@-XV{ڦ틵к8zyOVaS_ws G's,_6+$\mNH=8=>" [uIcU%XջE/67FE% В; -o_MgU߿R"q4]rkf5_K%ۨ2acԍw+'or#6oCa-T}:}}3] - Y|CȊЅkea"C -XdۅFTE~^doU9o~]Oy Y#1ҪWf ۠3N2P&0stXy{qduop4X9Rӯ~p1yޚ[SUa9bɦ^Vw2J-ԟ^/VY[% FqBZA:k>'."i 2@Ja!{p!~M߼m)}<9gar}?{GdK=7 <3Z;w:ncs"n םn{$ *vc}QVh],:/q6R[_Z{23;vM7#Q{fq+WB{ru_sgӳe ܱcZE}Rޅ.L[| Ãvz"_nZO [h%Р+Va4Ue 0x?&::!סG[3?6taid YѕIw=4}Ӷ.9ܷcX -TĚ^H?k~0ޔp&/sHܭ4hMᛌOO |piڜ.=lDDFVqhiřH\k0>oE}N׭9V~:f$Q&ѕRqCТ!ZrzQeZw ;RNON`b|GVsQ9%] D_yiHpŜLU)ޱ,DD%lQ2Ss]Q)!faUZhlڛ1?\F?ޤoY},K\<-kŖaIW [ghFz|g"#og޽ṫA;R}>R1r1lyբˎďWA+V"1ɍmq|d68a{q(PHvjAȲ#ZzkCv{ZjB2w/b=hx#5MBzW'jӉX8r89Tn"3}OZ!c>4o}qXך]MOzÎq(4qa͚V8CVY89K#[] hwE/aUdO̓&<<4QvW3 '(S,"j)U-:Mx!Aeub42ݵyGp.>O޽P^2OךNM&0sҖ[]Yo~m+fUe*[UqXiYI ȸv=HKoQiǤqâJܞԛ j>'/7ݝ;>aJ8riRO)ҜgnDa mZaai.VRLTk?I}[XRyʨlM*}Àw-i9񷐊j+3qTń-*S;x*"+D?3l7L`}Sԑ«nK7ßh ˍHtSK{v%}¤P>-WEEG9YsPFE}xڟw'TOn_m/W<>p_\+|Wg{tӊAs.U+L`sb@3^뒩Z:/ﲯƳ[i+Ĭpg1CG\=/U 6o־߭<#/)nnI-}`c d tqefq8DXy'W,اQgoUOj>kk-wt䷅B%x-וXFEΐ:Xh|`iwŎG:j<<'o{#5&/,\0!Vd-:ErH?b -Y54Io25 opO24wg駸5Ioe**Lvv9 -VY+MN {*K[X-"`"dE8҈V[i?1ek޿_dc ͯZ_[#Z,eъ:̬{G -Z櫼'ZWaWREKYͽE4,zA^EV 0Q?;X%5DUM ʾlFAnԩV^sثo{)ZJ@)Z OVqUU?R_$9^AS?@hM|o2VH-rVL_њҼrJ'bs&;yKJ2߳_oX6LMIZxj"'SqC"SV飔ąvjcx$LofHrZGpg>Th4S}!hᏩyY{ -G~/ۿ\V+*}([gP?2zޠC8 --I^}I[tA Aq(h[\V0+@ -P"*ж$y%naViq8i$ƗA{q(h[\V0+@ -P"*ж$y%naV8Tm=skhO]u9kVmQ7LA!@!@!@a|VO|jå` C{{e[]klEk*))ɢ2xථ4hq(ߤⵝ~,VmCD8 q4?%, \ 7_u="󽕆8l(I␖Ԃ dY3 _uݜ8`S{+ᄼ5n>Ee{UoQR[!|£x;fԷEh1Y9tESof6q4?''Q<19_/(NK8JhM5 j_2+ -iZ\ҞyYzV8OOC^?Sl\~YG8GS'b]RWu#+e}j}N1sB$5?hqۡ>' 4k Eٹ clu7[ -s[t5s'MR{! 6!@84JʭF7HΌuyq|h`eCmU%׳3P5B3n!)މ~<>b嵂bdNhy5$rjOc~n(T6%N:?psQ,)ooz`YQʵ(,?.M&ʈ84KNxj[Ñ. 5'e4q%1Fb\#} 7:4.$kn~+ϯ35.yF5/ ZV n~}!~M߼m)Yt ,8g/],"P8L>4^ꑽI3-]S4ܓvmvvU}LvۗA4`3lB@/s<{ݓ9cȨ_Yfq+WBjЮ8 5f&,Yqrwj`w.p -Uwo?#g㏍Cȃ#lwjMO}`.,*?l#DT"q8USٵ F-ueC(YOzxDoJޥ#$ђ[(LIvOGE8֞v83YǙw/?aЎT ҏPX#F-aNbN?zԄI.BڕZO]*2g+cu8M`9Wl!->emsin]ejKq73N0*фkhŠ-GsZaL%k\]i12?S劫C˗pce`Sxޛ,pgNC_v_}Z3s -YJx^^f7xb'}N.Wm" c16Cۅ !6ªqkg3J-Ў8RQ8藹aEp:]^YZҌO'wGZʼnH_=fqn5qz"q&dϸC k[{N];<Kvy:~e:/W/|7aX*ݚ'..gzL}R2OךNM&0sҖ[]Yo6 E~?M3c>{AaMQv-OS_dϱ/IVњJQU(-wjLV[\& -IXdN8y {H\ޭJ>>?6f{zWd(6=;ԩi,I:sS|PƇSC~VTFzU!vkm~sx1[.clJhN7Z-EkAgiTH!^3Qz]wN\lk5iIKwmz,G1ta+"f#H^Fl3+cZlr ɹ&I)^Y1oӇn|*~hٝٯ-^8f{CoYkU̬i9 !szjCoNߊ>ϪZ6QOE.\)PFg ݏkpPhYZ}z Y_LplTK58DnrhHMp%Ŗv7]Ф ?,1 $躞B?r&~"9<*4Mӄ~w-12˜RFMe* k>/%6`=tc?Щ*K^?wUrs7bCyk<8"M;7ġ+!x)b1'&;/? )yˏLYi!9+7p}ZVe,uP &'BVd q8PvZrShR^z;\fpyF -2ߞzE V;}/,e 9t~vnZz|vNiǿ>; ('UZ\|[Bqjم[(LUye`ka+on;$)[E//,RPT|yȡWЂV[PWԠ5=[*F/̪[>4/3Ogxu;KgU~wZ,YSgh%KPBx(ۿ8y8L=з&"4[xX.y_J="*{}!cOİU}HlA~-Q_.A -GYT/_nwhCuAqMp¦.г߿yVΧhQVr, Ej}^,ڡ?T9Ehwy7Yq -{Mv{S_roGI[ 3ڲKJ >Y{9+UX>7.VgO -p[z^F,P"7Swġe[l"E,z顉+o/N`x&~pC^;'qޏbuFyAԑVCc#-L޲t98ətEURPEfX -)_QPֈӦNE1ֵ}SKۯ;%ՎR4@Yt6^s=D,P*9G,K0sҭm.o~Nf֔mcU_Xz)ŏ_Բj>' =w{fn8DKoQXږu2QV.?i>FRH/=ǥIjfWh᎘x'wġa YxsNX`=['Othg#"4ژXrp,=5&'yn-I q[4%z -6KeYY?]jO25h]9|ma~5,8PYYXN2q(r?8dޞ=t -6J!uZ}ba8fIrj}&pK#mRDhkCG;,;O>oG[uġ ",65j"zW&Yr;1{YR΅RS{~;U# %Iuv2,]C.>hrM{б^xi W^wKSђ6ǜk㰶p4W҆>$*pX ^g9DQ;AA;P0sX&I1|S|(ఞicwuy2؟YQEi٨udd5FA1д+, +w pZ"*r9` -XLEO5ĉ]\8a"߭W5-[*}tC3ȸ;~8Шzn4dw܈ 4 6ի4Up »̒½>qС 7c"ck!7||i'ċC^fhҡVȈڮM;1#I % m_gݻ^x]=95.jdא?~kr}4>ڄ Wz}Ep:]^YZ'K黵Խ=?ř5hvǬ.J55=Mo[ړxWdgh*2B\.QwҺ=\.R%k{l!E,,]`豍v]΃WjD1;vo*$COH}xqش!ءDnU;=`Uא4՛:V45` 9k^Ʈ*RQ%2]bρ5xI0^~`UUյa3 -s ʝ'hMY^nA5 YW+ucW!j/ 4QH>Q/ޡ# A+`h4n\o=Pe͛Р# A+.S:*}@ߑ|!q q q q q?ۺ - Ĝ~., bں"_£G @R@ C vh+CQ'ϟZ2΍׽ƍP:kYf L}7|)rlv ѻv,~pU#(2q& vsRK3ƫ6rYW.ƒIi3~ono3~鹳:@C6n4,]*JQ%5E)"{mLoAhYދtޗRc -p13"c=-"vbD}ޤxnM}cX[$m4&1mqҔhnp5 ;uBIFFM+/-|TF2e -ǺCߩ"K J8ٴcy?~"mH?4Y%1FIW7C/Zʫ6%ZfoJWV u#8`!9/̓M̉??ß:;nsˮk4VIX/ -'jӉ.vlwr5 1,x#跕\Aq8Oݻ7ΟۑJ!D^q{fjOr$sР4C]vjNc媞l\gBLt;q(Ղq(%He'EZjGK9Y`LbQ1sm?4Os5^"nt_:*e6]rT2wTȞjHѵV1ciW>X8UWAR=ET\g -XLE_qĉ=6Fq44hޙfqew7qJBM47b®2c-ՂB;g厛偮* J֕5',,59}WqQ1'` _s]}ᶯ3bzpU}>3!^{JEG9` ->$DcWJ»ͷ̹OP#T]soq?L&|m+ qlzҒV>IspxNVԝ'=sZih&D!5Ck"J#*skHjr"ĹWmSaRldL -RÃ,z!A -|UTj9DRibρ5xR0Z^~74hClFan[S>֔ͅT;n KZY@V>hNqEI":tGk<0:=`O3bNMAJ(VYCg.qpN?c~ƍ~!ʽܸy$Ҡ̲|*D!+5z^܉ġB9_eSw, C,m$ a8q& @`qUqvp8qo^8 C8C8C8C8_ VO#(Q4UIfݹ׸?[,B lfޔ? _5Y&_) -V[ORԑ/y#W<1r89T-xK}+`Q0vN!ql,0D(F"r9hh@qKU 3_풸H -5,5Ud(+b+kjxX8A,_#L!ebKFSmsc\z -hѰF>}:zCyp;<44݁8/MRP⋯6v|Neѳ?)]MNټUKGkm;s&q!EV7^ߋ2h YVOTю;=gv}/Ҵ&KQ9ʋiN졼O>/_~< vתqUhϠ =c$e'yknM6V'Rz%[:ܷ3]Wz{=$g$~vRm>c<`Y%0fYW醥ǡ@}?'Y/;泐 >ֈӦNExg_70 :e -//^ hw 9M'~[KgؘEڤDT’,sy~O.MeLeYyP)p%Zϫ}͉zg6-9rܗ8$޴McX#Nbϳ ,X8UWAaLvUfTa[vy}ֆ.RaKY'NX+W&Nw hh@;qKU}JtsI~OQ6pJ!L~M*?{NM.KTR*zbZĎCsΉ9W8CC<ׯAC_E+T-<r"˷wUH`8h|pՍ׮߀;F477n(r<>yr/)"7nބ;3K!q@!@!@!@!@!@VtTB%998NZ*2gQn:zE{JAY,Ħ_OX?O 4!祍&45Y%ș1@@6*Gw +{,ܺ|e qz,CԫhY>Nq w[) ׊RTIMQ -4Ǫe4(L>m{b{iJ(3g/0D9_}sgϵ~1sJn,f ΥjF8.\p`έ DpaNѯjt.#!SSF+E5ȪB˜E++%kW.tT/YYExZue׋t{NT-Qamӧs+I?^wwva#U"|65x -/d%7\LFԩ`c{k}VC씮ë}q]O})+tw.M,jU+beyq|h`eCmjy¦.г߿yn'iu'@,mu{yfiN졸CAXIŋ$ F?d]/5ىoK^siD9G,K ll84M)n?4<ƄtWÁo,⭒B*"y(#ziUp -Uwo?#sbCaeyXm'3CCമq(lPX#N4{L b]֞$b._, M@6Iw\'j(u,7͒Ca *31{n4doTȞjHѵV1cU*~, WKV4<{QK虱fqew7qJuq8q[wbp ǕvaS-L{'KA?Һzl=h_E:di ޹ ([r(k?CRǏw^/߆*j0_ZzwEz{gi+.ؿjr6â_sr8а\ᥕ -:w'&$V[|6OL }8d, ɾv|V0#fh ,6gSt9R/ti^(D -D2YJʬmVDX-tWny&3an9ZGYҖ[{"‹@k* -+YDUM" fƣX(|_Ī-b)jrφ8LӬh\2gvZa^Q5 [WʷȄ*nJ[9yZ}'[:y`4Ǜ~w5fj]][␃GAn0ݦkj~n! _% E-,]x!JeM>83ˏTL Ldr|e9ē37:G(dN ʙ(NZ.U?|7FD'WtspLr5^1lױ66bQ Oo<϶荖ݵo9$/uy&}a/^kRe,yF'ux0 bW |qJijjY$0oݽ#A56j#& =ZE <y6=K+v5`T1ZD6UXQG\{r^zY_OPq2#[\fj OG#'d>߱域?/8wvg)%wdj2uJA ѨךVa,T&JZD$uMP/]spm+cU*ì'}4Nqx?ڎNXXkǓcP]n;Z7gց4DžKWQ72!yqXVxb1g9/F1Dѥ8^Tpۀq]C_l[DESiO3|/aօ>zCQ*$k2EI]KL2QS4M8jYya1>{~*g߅] zt4i$^ -S%uYUrs7bCyk<8q[D}EU~!BV$2܄c>z.ڴ$sG2dgG۾"=qUywo>i&'I]R_Ú1KIgް[ $aN1jDyۊÎ݈B.f\ȘS![8WXL_eޜ7^XQ;]3Tz!!s/* Gm0ݣlCF |7y÷tM{ d8 :58lXydv>Oڊvƾg)18yh8ōlҐsSNJW71i؊4xZzӆVCP_V80DB;3ŊCf1_9|zMWZ0E\Mv=:zKTI'҄ڑ%_n<ɠ% wԃ;X,M]}ē ErjhԩAt쓽d<)k6-$gEF?bO1jT(D՟dv>OKqejAgch_yUy[:B&e*APsװ˪u,FvK7J>8{OSTE -{4_O^{q?jfO.f38EZ#lvZ -DTR"ŷ,'oڙ]3)7~c0;9DMiF[nu}B\\9D1;#)F 9ACCktr0;"2av EQ1e! ޛTJZS7MkllW eNٛ6**ZTś~Vji=TܭY]_+NoaַQr/_.zIM MfGWjC giq~nջItifWD[ 73en/?o=xM- -/}Xjgf)k>d6^1w}Pײ7N~^1tvޛ;-s}=CGo~Cv>.KhuMl? dӣA#)k;.8=yasN_M΂y)Ontcegy/ Y?ו3ݥL^>p`$?l[姹~imQg G, ?in E6m¹{]Lhomƽ乼X/;0lUQm/['TC -u٨縻ZJ9*Y*NABgnR`_.r֪u37bRm,t}}/ a^b^3&5s7+3V7.Nhʔ#o=jtԻ<Ӵ;!wO 7{>}76íO.{ wOUo[;xq;364ߎ~c*<3?/diiѻLuLz;`\|y|vT.:lFXuG/mrڧ>yטwht:{lp{1;oo~?zy -Yr9T}b -ig|gۣ/'x;IzFoިY3;a?2m۶-sYsXyiQ~-;jk{bg-2Qq_0aG-[kL&f#oۋyg'ʲ7I#wn+Y93{z[+V'nub="τmh0v"m׎ 6=b6WG훾'okvȡꑱ޴yE7sWN;t9-cw Z\f9[ǽ[r죓_}؝}7(zJאݯoZ pVͫϭW8}]- N_Txy۴+,E?>Ngů0syfjt*A~B)np={6bڼ/f2Lҳ*<fsDXav}Ml9dpT ^{yK?׭M?9*{瞘JԖލPr,iM -Oʖ_*呴 5ح=l9?rnF*mpsS0$rpvq<+sʡ#0f !dSCu,U_=4ГK?ls}ڷo^_}w +'PKã{gN .SFar]BdF-}ھȒǂY۷phi+%T]U51ͭ:e_rڴ+JoVȪ=[ZXg- yЪt_ާgU@V]jM}cwnVY6FY=kB+=i ͸VTshzz级^p4ֿ<}ړqj9!nPy*[]x:L[?N|rC@?h! 9tCa"r4LA:49C 9@rC !9@!BrC !9@!BrC !9@!BrC !9@!BrC !9@!BrTa] uZ0cDI -endstream -endobj -288 0 obj -<>>> -stream -x+T03T0A(˥d^U`bjhgb7161Գ44CC3cb |@ \' -endstream -endobj -289 0 obj -<> -stream -xeRN0+!]-)I4wN NT8nxQdNƓ8 zl=``#(V 9 =UW}wu_`}p&_mҧNΔPs=kPqP&_:O };?JbTyh,Lv',hT:I.BnNj&ۙ%vPT](jw|hoq_;#2LTfr\EB )԰<+,X;Wc>L1wd,b>%#hLphn ԍJř&͗KK#(Č24|':.2@-(1FTgPh&nN[,4<z -endstream -endobj -294 0 obj -<> -stream -xڥks۸{sN/t[ă@KF:sx'$/2MXM#}c| xtq\uppăDk&`Ỹ/rY:r?qroL4)DQi8#բ҂H/_l:87Gs&Mdؽ-8kg41Tz'cRIN>.tb!u>&9zp! E<-Dw5C5` _xe, EP -p=o,sUjG'`'c4IR3P"KM0+=>]2b#kX= _J,[NiP ;ֵA0`")7.l,R֨"њr "y58' qI]f\J:ʠXDFU G_?Rf6X,;s#$,jI(ħ,Q*2yYSvùCa8=N|% ]qtSr3-mkS74eϓuaDI9(/x-7q^ DIs}lz9S -&2!d"[R0& ,qM U$PKC bIXMŪ(#\o4F6 -1YJ, -FGd zS8x8>΋6fms<#2cլdsk -ҳMߞAD3U?_%%Q4ua)sDmt 1 -x*qT@ -}0ģTv: -Υ`B(? jT klI&%XPa_%c9SZ >Tm GL6:P6H5%a>R\iDA ;62˫Μo;w@ V 85խ zvHl>']& -K6do*!MER8269S")gc -nG1ˋ+U6tLC ;fJ7 >>.lo),M?K3ہ"Lc+;%͍Ijxٹ;H v[%V ))M;GhGjLO1K 6V+Π`w21m6^l.6+#DZ*~Zz! d܄f eUxڳ|h+dξ`]xUQ^L[ܕDưo L ~'t{Ht[ 1ANx!ߚߛKTO`!L4{ǁ̵SxC0TD1l&/)x5ġ㢙lp=fJv؃;mb>]ehh Ъ#MSN7ؓ='C >NXDg~u ޫ2u}!w_@75el$#2XH!ÓrF,/Ubo SIJ "(HKâEvJÁy\nne8#H2$8톴m8E5dfZVl_L1q?:U)ٯ I+vU8Ps"F8qSkυ9I*BGm/DñqgYK%;}41lB5B5r?.nlXn\}n\mI8 -;9;>j߱ډOmK_cj -{s"SAkUowԁ/ ~Ebg(sy4ʽﱉ/ Ԝ ӷ4 -endstream -endobj -306 0 obj -<>>> -stream -xYKoEϯvq!CK9Y ٵ?z+vuMW5_wUuO>bqxҏ7?r|lnRQyA?ݳy}}}]}P}!RȾ^خ^o _ַ~I/["oH|ƞL#by3xH 5_%W`fFk9jc<:jc {j  YN/ށw>FHQm<9gW}~b}mvbU^UZJ_J$b5[BP^8݋ LilVo&#cff9`h|dd4|d|&+!GjITRiȆ' ; kOtԅfSN(k%U2tTj%QؖA *"1ɇ$cc79lHC_u@?6 -hm>WYRڞZ)SSbB_^ЯԈe!2ip<==c1)) ^r[FH)hDVGKM8{P1X317)du2:{l3z~WSxoP!g5>WXJq J+M(5dr -@s9rWs/P&&NrB#/ZǑ Tf\,i Kd$,Doe֥N52Ulkl`UOpwJ𯵗"FZc%w`-xH/Wl; kf++\p&&X5# tg` რ U ,1H4MQ\I7tx #ݔ-ͼI1ꏭഁ, {Z-qw̨+ij9<oc Q&orxHL^:cH1U+gm(dt -Zs)-q 鏝ո_J?θ׆SKO`1 xx01Giv)%zfuՐu 'BcA6,S^`e! ӅIf,Æŷo;Υ%$@x1:BdFЁU(zyų>?~JZU6nK7 -"âq9 rjGNY~XYd -+aqԍ V![VH޳9j4c@'y5 8I2*e;W'S?q\/`/wÛs%d/~~}jMym~v -pO-j]g7R,T)*}~H`x{# 0p⣫=9I.pyqUF jɈvh#Q`- \|Bi~[AiB㵊BR0v }q|1f -endstream -endobj -307 0 obj -<> -stream -xڽYmoF~4Zr%Y>4eN"UcEHj*$M7$"(!P/3ϼv>:O8*fQ,?8s2N|;/;©V?ߕbUReq<ؕ㟫9RLXn:['Ce)9!??@Sga -ϵ|!/%zޙ;?"NX82eL8@p& 5S ,hoVW,TtE.<+٥u[Պ疼;iXAk*i++xeL*Krm8p@ tP<ժP ˆVEYTsrr= w-Ȃ?|ol i5C,! L JZƉB.Gv{, E?ʎW<p.PNhv1!9hª>1Ogq>lQ0Qʊ?E:ΌG$fq^[4€ۇIązg'P5 ۺf[c B+E ȫxI#a/fFi -5F=BSr{\onܫ } -BJ *gu弨} oI&C!ʗ ’ž1 f$H#4 *8j]<_Rbi2R 0% 4)f.Vp*N(tJ7ZҞg"1e*|^@z̛\¹ߓy3=-늃&Y6ޭQTG#/d!G - ?@=J$4.>7є2?3 =&Z>n -aa$c|:بU5z|/įhenk'k#BV~os!' ;}a@Ÿkh<FzD]eB݌S#6-]mzDH cad'*Jh4+0||$ίnc-A˼\!J؋GanУw|^Ѝaњ]I;:VIgO>UzPTFiTdt2U ;΢z==V4QTC:F‚T}9R% ФVkl)PSPu EDتu3߳Colֶ+T&髯H#&DLL.?r=iz-~>OPC.8v ᅩJ%Ƕ>^ݳ~=2M V?մ%Qَ}ngW#SmGHZV?VwV #gWF vl}لv2J^ 8GL-̽~ JE -QE!V~#f9 ]a;GGoT{mD6͝C,zm|i۽Cn0O>ӗ6{]w^5jo,|+ov7VMhsR!8L>/!JX]k P\uKɟ+P}/XfWcC2wH3@pn= $n+.m֟$]~l>ڿꩾ.6|UR 65?? -endstream -endobj -310 0 obj -<> -stream -x[ܶ5ڣ%%E|t4E/!~g'EуRmqD}Gr(EH_Bix,]L(h~XeL3._~Qeլm]=>dhZp/Jĝb0<m sVd!;Kƭz -)6:Xbɷ@fP> XuSfScW=Βjw,#_Po*vFp1 ѷi*Yֺvhy(/4T]ܫ?5d>ݔ=DmgdW>sWMGo/=^6:4j]l9n WGW}3(P a)58vCŨ :O(Ba^5 #TMfa7p~j&aGalj5R!9^sC -mPCN6 re"F -XMi5קa 簦I  ? 7oOb.ZQ'=4&*!hK>uƖ_o' `Y#5˓6Z X0+8gI ,#!K -˛onZ !gBwQ_fP!EXbn+ڭބNalɆ`EWT50 Y8Dg`ϒēu|'ΝVLvuƥF]{RD8{n[W5TV™]eY5.HV]/`8$}f9Oߎ6t%~.Y:G?()7Լ`'EX E \siXJ!xgeow̚bYmiU76D DN X# r(vVqp;QH nP C-td%v͑D>"1aBH}0?[wצ^`l6$$7a+ >4zAb~{m޾ϞД닪˓w>xݼ}Io&Xgn&Mk -}*ZuND7q8SIacƆaN|1-;\lʪ:&FE[G:@alڻ n~ϻͱ-ZSxpC-|axuSGOmS&F 9 r92b˗!;ĝLN!pS4슈C8yrٿpc߽ |AZ:`ng?>Kq+NZNn(l[ --LȮ2N?g }CeP.|I\;HSK mU|yK().Z:/c׍!d!nE+\gv5]±lɪ2'jy8^]}drNsdxӛmE @,W(`^=hʩy[b'Mܮln2.}n7tĠmd+8mL.fFBmtdzy}/bU~ɷ0 Z864ML8nEtl*]&=ºmYdh -.ӬDvgE~D]z#[ oUϻIA\W3-D68ZوLsT6L˦)ۏC衅`ِ&N&2_m.Z Sٸl

-4sLt 8~!oٮ77n=TqLęE띜Gû7wo~($G71 8&*μ?W -ĄQZk}z݋ q* jNڍrsR-FK^}A#R7_eb25)dL{GjDNlh,y -Ōz )pV -=9J`1&NhWMAvT ]̏2on8ML2\$JX;gPxlȢxVxf`']䓤t\֔Wp*S|ZL lt.3wST ,Yםkyң vBΈ!?;N7@y,K -" @(%aٶŔ]Nf(8'/M=CѾg X\74(0|IR*or_eߘ{#*"i%~ :C8 %~ˋS -v}Cc|OR7 -f~Lh$68ә+}pO9k[LTee<ïIN'Ԫ*%t't}'DUP&|N,I_ ÙB+f4𛤸H2W[OZ>fwi/:"t'tzfsJE'#JRrkDl"' `'HyhgDĐɔg|[zFEFD:&TXAA\ -9LUaTqC"j6]USOP03&֐ɤg3<(3pkuRjsY_}>Z_eT,t/~7Zs$37r~"TE)]p.",w WevsC5/|$( -endstream -endobj -313 0 obj -<> -stream -xڭZmo6~bsi ЕER$p겖6zZ7m&M Ej%;NR%h4g^ů H?"3E׋~q"NMX,bZ,}ѮUӗ}6'KHOsLX"ݲܟ"ZmOԳTI,}# 'Uuk-p"V"U*.rwj-#VX"iZP@Xi [L*LIę[L@2ʋkg "bԵLL=1e`b,iwXw1Ic5d[&UwwwXզ< s4 -ɁTt9.EEdGLl,BަHbjD#bAn+h]jG -^JrMiU_e$$_,୅QVx;޽d@%`"I@4*-f Z+5Qw9=% -'>@SkTzSfemny*tI22`$buX!0R*y,66X[~Y ʍ۾btLS#X -'63TEMhkW'WDPwz^5 'TI4MÏm#VYDԻK$a[j~*4L\ d ·=!ym/\J Q(Pul -`6M#Cko^9w~y?oCuGTIuԪ@2ӱUߴ>\|8q_Nߟƹȩ&x73~iK`) [f- X)x&@i(: HǡJ!ۑCd9;-ctpnj˨?ʅ!^[Z/3pRpѡ:"do"Zz4[ɨzZ_YhUwjw8A} g*%ӑX v8 -D)$:Yu葐 Fħʹƻj[_v3V ɮ>o8D\ڕ3YэuWZz$~5Mi܅~@ c4 2Lú`[WTZÎWn`/PI|,0i P nۢHO.7@EՎs>O6'5=lAfvitAvǫH؝5z`nexXN>)OlAaЏ|lp7+f׼bO\R@ϲ/.wjۣႊն_"ݪI.r\2=F]{6= -]7/^dlʰZ 9l~&r➂Z6g+RjTBnI];d}bJ'!!LJCAW*R!jt::& =|:@P;kp`aa%hp7"^ŸoxvϿGBK2׍$jp!{g@0DW!sI6>z33 TTCb9eP2o'3=\_H5PffZ=4,ߛOٜ? -PP+50J_#(@QtPp?F#~1̙OBNğ -K;S}3{ۚ^|ʱ&(D- -<+WU(fk&^+}s^Fi ~0Rv3ٮ*7bW^>dBa=iu,V>sJpGę+HOk~]_Ox.k vVND_MIvZf63+_:Υ -WW6#"q"Ha_pczڜI iu龬~EJAg K 1l413TP.Qfȣz=zߖy wTؠĠ=N8dξ -㬬HH͂O/1Ɠ_nNS#tHK-PnFf;_os;Bva GpCR6f ]S3S3hMڜHE G)9/g+$*alBң,p%pPsIsޢpCl7id2V>Xtd`Nj>톇_[9sD8@*Dbن]l|J7sv 0 BFNX0DP?n(J~?;c 1j7yуաbJ'Эs87oWLJ?u5ԮƎ$+Ȁ3"_R (c4b3b-bsmuW 4T.KXö,N{e~YC+1נ$y:|#s 2S/dZ73 !Oܼ|;yVۦWNf$oA3 t| /|3YB۱@badɦ "`B2/1dg|`~:/3 -endstream -endobj -316 0 obj -<> -stream -xڥY{S?B:+UV"K^K^BB{r{ܷO4$BQFQg(!`?<$ipN)  OyLBu^Y[LGl(&"H7϶,-VəX -J0dWrQ1:oFq]1"`H!HCVH* -3| ʐ4Jaa'6>#%"Mp:yo6>$N60GAU4_[Sv<ؐADBih  ӄ0_D3~JF* )QM>.(;vwA#"m~v 'Y]Cz.e4AaBhhܘ`!襩~ud#^BnjB-p%(TWy/ KStcWh~l T$ __{(ppi= uB9#b -t3MTΰ>P?HHշ*m^yeӅc 7P~B~h^s#.]; )'We ]o4ҿub j:ďkn;u*qwAgg^ Q#Ą,OV>3kR-\:gft4r/et#m)3(b$/a aW`G#P!yXI ڝXN} -endstream -endobj -9 0 obj -<> -stream -x\[o[7~ϯcPrx/MNX ȃ,ږ!M}.֑9iDr8o.$Q*k[-z -+U-![%F%#eIJ*݃J!qI0B#cYUV9bQ *w (tlHkëshZ;ʃ-tM0>Id)3b` V'A0&ˡ 9K_CD)V, Et17 - #H"EQ`5d@,Z4,'|s(RSc(lTLd3)x%>Jͩ$)7QLbIfUѽEF\@ -kZd߸)qQ~eH ezeu=[ڒB~ -Xhg#c-0J{T61 I[IRN@# '.fr)6.G#\k=hq. e\bU9-bS_Q-HK(sovU B{KKTJr(=hjXD@IIЗ2=(sH |Bhs`B5FIhۀOd c9# F[@s~j;fpf6ghT4Ȫ!Sc-_*3Ȍ Xk?A$E vuVhKKX_Yn̑3T{$g\A\Q|eV!@W~exq1]tݳ줟1ml.ߦӧQ?^ESd9mhXۧOݓ H- !RBn@ecҀ_j}}Y|'Wyi@+ iY5)+xCR4$ӥ[kVB (I|!T N1|!)LuۀhWC~ ~B5!Wǐ ` i cE-"p4 h i٤s@)tchW?evtV@@Ղ|h0lD^} k'$]}1@e퐱DbF3s-<.jlegcŴ0e놌eu&| :  -Y]l辐X|ikyStB .if[JJ IIڶQ< #x/+@}"C3U6!u _!b,,5l/03p6tataɂ8܌4sbŠ0r3Cr 3ksvM:1`f:[YnbjV,'~${C2Y@zYB iAKഘz"zגM:1bn-X`I!~kWp$D4d @ DABdYҩI!C/&ֹdTjRΆiXl.g:& 0["rZdł rQ ]HXKKY/#<6dl2 Ht&Y  -\a giFxgh։y֜I!'Z#Ea "+o5chȂ+V0p$H2kHE`E#JT@`Zx8+1@FP!`Hۯ)^,aXG ²T\6J+>Wuxӽz~>Z~<[~|GW|gtN/h->7^ukΉXPy# `pY3Nzxݨ^,VLgGɹ>\F:dz6w76FoMId*lqrMWz2fF-&[ -I|y& g*3|޿ٻ-p];L+le?{UeI _ewRvіoq}5A2 -V pƽM(O,M+AwPṄ%Bn{Zw-V&kKlU*DRR=uk˭k,^E[׶Jﯢr|:^#輟O;k`V=&ik-{9G/U?*Hez>,^~}Oe7ehSH?dE1kѐ:ar>oJfgɢ^LϦ>2T @;Cb\r1!eKm[e>oKU^-y<:}?Vs{h+ *=K&+o!؆+ռͻ8̻Wa1^ܗo1բ0/^ӏl:fS0۴[%<ꆈVc=+~RnG=wV}ǣf%Vr~dg[o͚5NW{~&xDt<4o-y'v[+O<41,6||Sjt组7lJ! ohĄwZl]]bJU"pBboYRhȾ&r(= -2ፈĸ)<΍7Wbґ7UR!MFQBjٿ"N^^C䥞(\Bn׿ܗ$]@3w6[qц6|z~0,efn|vfGH'NjXNNUtktI`l ݗ]/Ʌ,8s'&ro,vLǃnUyſҞp3TSު:mE{ --T]$ެJ[6~_w6=^>ʹl'Blt -endstream -endobj -482 0 obj -<> -stream -xڭXwXUW?= Eȕ4%hh!"R Ez/b[LLC ذ Ѩ+'%ƨ: sy} >络kG===y9 9ҳ1'vFۦ4T -hJ=q q(fE&0g9';MvIOM/J_jIBQURnފԴ"+${+ΓmD+ԬdYy E9NwV:!#ay8&33 e1cX0Jf4cɌe1fc1#3811dƅ¸2Six0tf&3af3s_ƏgL 3 b& c™&dh&Y,fjo5̜A3NRoA9 -?h#ҿ%KĆ짜>WUp'~ޛ$L|``Q&WG5lzyDrSYYmsK) - l\ P??J1RT=LxC%{GtQʶɅMGkj}A.33dI Qdʘةѡ-' O"gxo|*Sy&tr4m=VzHEmMuᶣߞ^QS] sxsdi0&OK{jzjܿ p9 N=}uƟpzq/u-^N_JnWYϻ8 -97 < <bK?Oٕ+}Byхq"X`(=UԣVt6*~AVW e L x?49pA.4hN蔏gKvr0(x/ -=H~Fy7ZCftڏ.'Zcpb NA+'4x ` -mxܨ1P3Qr#5i-,܌gL ?IM>hǢ>kHWXmR;]cD'7Xޢ3 ?Alc!hRbeSWsau?`N̖%0Q['aorpgzҊeU뎐ʊʝGH9n]KH2))^p}V6s]$ݚ,x4I\Vjߏ$vZ7ydK$~GzyѾc$M6﯄uȳ`,Wqyу Yt1Xc[3J8mƇɬIrm6Cwov)**}*:=ŭ:*cJ8a9AGu<p$ux$x@&{hٛ&LAa A#\N5: ~ ~(PUQ5i kv'.3_ʕ="0*#~QB;[;iTIJ 8`8IV &+z}bZtPsR,}H7J[XU6w(+@0ucCBp Mk׿ ,Ls<*8%FgNGe#|a5Q?ԅ9OgoqbY+\Qn:rf0_Pq%Ney*Vu>T%!Aܮa -,h2 y7ԁAlhs6t*k0F -J,4z} F0} QmM8 .LD774i2(;/A*1Rohr94\5=9~ ŧ(sQYāXz"OlGK+PN}wXA2'[98x}B,V@7HP@A`L|ߴSR$eSop=^_5bbE Jg5;E Vᤋuʪ^^v J8z؍'DJA ΃QІ(В,c4J,vUu e˴[YygdgؑH+;'8,A[%I97 uϫ`E$Q -RMk25Ӳ*zzSl:pu-p\mzXT}If$(ݢjw\2i3" ta,#67opqu+Xg&~3bg:=I?V׭ƿw즦GW7Y^)lZyɆ {orouK&0BU]]SptO4SQr=:;d/fM?TEꔒ <ԋYQěY!4~v\kу -(Z|{/tu>jΥ'XϏg)0@FR"Oٞ[ly*rTn/++ۻ4U.[=䒢 W,_!$K&5YJ:3xZ_S&đTYVm(a.exNr~NUttx0F-z@ SYvH|DNpu%KGQ߲j;3˩Y9/c^Ƣ،0p`+!!Có"S;މwzH4nyZx4XPe]͋76P((YU\aSP~+V;Aw Xy-T$kbiE@iWbKr' 3Q@f7vwB#)X|rJO ~Gr{"}+-D߇m~m$!lBB<#ҖGws}Nm:x(9WJn?uvLU~q0 )Wu6KU'\s%-96&2pA SS]#?\] ]5=,P5Q? eE37ѥp:ULu1 =k vitMgcEIM)!k:oPf`ʠMɴ0>/p&m=, I-Y&PGɻPgUb GVBb\ֆH6J4kY On,r=B19#I&Pazn]G)sJ΂="IZ/g<-}Et)̾Ԭ&Lgrm//~ςE}EV c嵤o<%'ן =OM^__d]*"[2eH޽,@)G7S@GXuSɊc;uGj<\ٝ^)8},}Gu랯@NΒ[l^vƼ[09_HPP|pJuFUGGN 厫w! |`6KBaԴ V ƺOp` B:At4=?ݏ 4!R<6F_^>$K{^*;] r Bɑpi{i~9P{ DH'"q4=4 @oo9TuP$c_(.ۧ_~?f;yPz7 -endstream -endobj -484 0 obj -<> -stream -xcd`aa`ddvv/H N+q1thww<~/ùH#y -L?200<AE)$9ŤBJ2ݜ !2634pL,ɬJMQHI,ITH/,L(QHT0204: -9 -EE%yz W+!cnvN6&FeO&FN&CeXy`[*k ˳2~[o18󱭻'k/1i-~6vۘ1PKnܺiݷVLْ%tkswHYjbZb_ ˞FE^}s+ܲs݇Om.)a}z`7\/c=_w_?%EZB)*U,jZ޽{єy͝{Cs+L).ijN3dD~[|'^*Gt(.jCqДukw/4tq1B7 `B -endstream -endobj -334 0 obj -<> -stream -x[[oF~_1OE_EiӢIy`d:&DP*@9C b)eU8&dJ+&1=Sxx|c(+GÌżN0A syi"'zYG8c0  ,#n -H<$*) *e5@\^A! jp $4 /*+Kc⏲ 05t$*@#Q-$ `UExGT l+0`JpLrEq 1Vb@Z-i -ƀ\,do?*.&(rWȚKU=!ozN* HXDȢ<M2EZ d|5VI:@L92x{R'@@$9 4 5U "߃!N> tDHm&Qt%B1MiHj t`0' -=ap4 ~xOCI#M@21YR3Inj'>yH/3"$ `}!DE,BYhf5BXSMˬUu0FXgbYCI8cWkSd~8ؑUdp3@ń'!P \0$9Ϟû/m*üx* {*G= 86Fi ?Ti;tR ->l P   $W[Ov 24TD兆`H T4$ސ<&PP%Ȑ X (KkQ,4R1JR];:GHqXkJt*%Q4JG< d'ceP&Y*Aˆ* ,\G1\Z$ -C+uK ӬW eIFG- F8 -N1KԒy˛@_4nw}&Lś_uN%g/HaXPͷ fwdcH~\-Evop8A~ۂfA2 qx.9&3)rA($_PC:ALԦ&rhԂ*z[i#Dd@ U>t4*XB -&+/I%J&+WX>Ey]QV&ª4+"]pMއmr/l j` -(Yd6AV -sIxM)az]wS f} -ݧa"ap {m'9`OftݛɁsRR/q~kjG_F7Z"Ka~y9G{XX)kyn~Q4x3wJ-!1_x y'?Ϋ#?O|֨Ea_0Jn4T{ӻ?ˑ0}8#9/rFrOqT{(uxja0hZ{_xd4eiQI!a<7-]gşLp]jCWM.MWo)]?oggb篪--Rb[ߠ؋fUovKN`M~lu]j&,זPQ`L@e]Õ\\b$n5!L9 󘳢v0lw/^ؙ 3jc}Þ5zյOj[mGFFCi6Emu3e5mKQ2VWAG>"ض=k6]˞MY P{uefo>4vp~;[eepvyŀ<ӑ?mv]^W]n0!z;e:oTכz[e{ztk:vhD!a=kWd)%/"ZI-WqeWa޿WV^muDRJ Ʊj77=}ymEI4'8%0]@^Q3GHM -pcN?4Q5vτ)=_6MTYF,#Ŕg""bT._' ->Vw -VjT4kHee]v엺)ӕ"|n!fϪz]5Zj2\6m9jڗ6C0_0fwͻs*] G=$j4{Z!jY\ϛw}n¯ۇn~3^:UgEBVwRf/\!6W;$jcmlŻnvOr+vwwh-_>yLGLX/P!Vb -?d'x^%'ū>}Bve*5ܗ \?[fSrG.sT)d, ~ -G.TiS Oz=*R_f7e;T<%rߺ-ts7r5ӏ~T .԰ a*[lnWOݫ lR8=qzC[tݑ(>`,nF) -[մUV=Oe~aO_7Jzqq2z=hF=w=>K'TK"#ci–9Kkg,q2Lve -մ`ԚYqMDټ'wN-[;yg'JΒXާL[,meeeiOP6bXYwҾ%K{,祍I6%]];ί>Իz뺿wH^} ?9E9nYz] yI1vעz;fǂmrTrDEN[,C y,Q3(K!5E:<.W0 u0-F dDu \/ M6”TT -hHIsB.t\>pP⢏(s -ڡnAS$?-RK -0~Cn^veqjC)auR};0w@/?Q4K5HfrYt=9Z竜n|M*ISMe@˅\j5̽+ -g#=g6=s -v aOGF+aez9{w'S)}jn3 N+$4ˋÃGO\d(~ aRN 49BM!E# 窾CܱNLi(g[PrpxJy:~T1ycS+gCL)ݩNv6l.>fw"u2q2qfz.-?*%X~\I3 )ytP Vӝ*!:LqeUiڑaujSS2fU8iUqzȪRb.H)gj`OK*TO}fR'_s@E Oo=\MS}~&8k!C_lkg/쏦cwַ>>:Q/_mۛU=ܾ~;C&"HnU]}L9%b7\~׋z4hZDh{ׇnlj|8D=֌&jݾ$qn>РJz+3ab|?Wv8rF9q0L"-HvZzE% n oFoXt!RKMt47щNz `R^qz^:J5#Bu|9 ΧG<d&AIHnbS!ژ^ތ -?E -endstream -endobj -486 0 obj -<> -stream -xڥSSTw{A x#"2"%(VV؅HKm&ړ8ıQR"2\V^B""ƤQ8gaz|3s7w~)d䦦denI+3 -ǝw)]) 7f]" @h>P9N|%'a_iX+qlb;竴Fpܠ -XQ+JZgtit'qϝ= V+)^R ו*tUZЧP 3'xOxhXVB| Z7 2Bg+l}VRk`ޥ@G~>O@RMdSר*(XQ4 z[̈q_.1qrYaޔ9Ew9[A"?Q/Pڏ2Qp7`R'I <|1I`>P_> -stream -xڝWiTǶn2h '  33ȠD@fd0QԤQc0 " 2(F&N1^wWyY֩}z׮W:B3$FƯ7+!ve>Ql ^W_YɌT:҇4T!w湱|>Hћ8Fúx/rw?':2:%+BSB-3#R,mXN0~9YOHo/;i){i){y sƊNP8<g@ƈ1f1f3fF2ь cˌaq=13q`'̧3bf3sʸ1'x3>/c&Y,b`f10`:t4uwL ^q֑ `s}3΂>V%Lno0`@6 7cxQ*=`L?KC,T): P֋*}{SUJ\mἑch3&8qi?a6Ka5){.޹rɫw]Zgٖ &:v4d4WhaUy?a<0pid{0/PVgўb@Љd-FE'(`{&Qc[=G 1*:oV6xIx@xt0p~-^۵֬EQ:۴8#>胵HBZH3+/+/ϫ%9.4ty^#˲B?]]9`ѨaoM}]Ai"yeeGKJ[ &U[}F7j\UxiT9Vki4sXϿʸW+yջV ֌tv9xI ~[7LɋVB;cu-'Z -o'ĥkoñeN8OյuO$fyD$':!OЂ -[) /*ey 4'ەhZ-Z21Д>hqtJI ~ prɳOd$^Tu6 47J]&4=9  < -عA;8's4x3e`x݂af ҖJةwR4m"uJav#QF{~QW"2l]s72vuƀ!Gv'ޝxzV%Z2P UtEOnnSa;$=}ў{(_|hbWڛ.&^@w/m&iڌWRFª,04Dȥ3 -3m TsJ6&d/d -ud^rZj'S9r/@֫u8;6rƚXpa.X"zPsbNۿD@/kJ(!Ao -mArq"7k`&6 }L(à+<_1:X1z0v:O\D ,2{u҈+g#c?]hVsiF{0e_?<'NjlٕZn%N3dtU3rmcZC&ƒ'5tQE~&`tawmp xzĜF9*}$:wFsLO8^Ss KKNHΑ9…b\KŬC5 W:Μ8s("ק$$2ԊS+? }ruUYp4(moI< X2)2iQ|ʩ^ϟTn{RZ |<FIEo]g()e-R3Q)j%+wKV*3@ņׂ}9lgBg&&#ƐƔXA3ro>z3F/_ 0?y_wy35ޗ^rFo%d<(6眔K˙ԧEzSN3c-pI `prT$=W K*qz:߻o=ѕ)5&(L62m8k7)mSBy\SrqpD)*厗/{?}G֞ō r1O\!-HSnђXA=a-m7wiM~|\]&ר ]k+a˟.oF6cpx4$VWL"KH=tw8Bԅ B]~WE hj$Mx\q~OÞϕ ^Vǩ #hQKrksjמ<SRC4^iRYh;HO~KEA -{8{"j8K$a=:hEp84}ԌhMЃ[ Z9MCx9$$%iCCS$h(pto@nn[ -W@c(B~''(8Tpzr({zSU-88ՙEgmC9sU8MέݖͲ;"!ȭ:5|dnO]L^6,H#9x - IJ|L팇``#)Vsto7uS %?cz47. -'-HS[`  Gu/h˙-1a)epMə-4&pwIˆxJņyy}:" +/N uiF`rf;gIbTbTh䒜lTRu ߲am 2QGv>6rnO67)xQVv1͠}2~bkYQkE`3x%%uyC`[sҬ5=#o;)Xz+nNV4ME[ƨ %_)C؁RJ&ré'K:'dkkƭ -Bs^,{T@7[YJOiw];}U%V΁7}gsa[Uz`mjZ?[p؈Icbe0u>Mβ+z #Q(HMi7[IyN/}z2si6Hӑڊ&ʺ_Om4\TqODkvY’%{zҰ>RfUQ{@)׋OՇ5Y(O! _37#Jn6o>u$e[m,Qd 4.XkN9WVVQ1rqϲ jΝ*~f@m8u.BzB\ahF8#pZ@tbKZ\46DU?G'MJ8-e\CV 1gHu ƾ#OT\E3ki P461'daZ}cՃj{1 n/ki:%B.U6m:|SŦeJ7naR/4Vd~l s40J{AܢGr>A -%S醨5`5!V;?8`H'Y|aJ,Mӣ|^fǘE/ $I7+w oXאHޑ?o8w%ax~wyˍkf4cZ_iPȲU=Ž-eڼ@]yBzi|p@T:?7x -endstream -endobj -491 0 obj -<> -stream -xcd`aa`dd w -/H N+uIIq1thww<2ye!Cy", A~yMDJ B Ǿ.'s/^\d> -stream -x=S{PS?SJUpM!(*K!" 1FIxE"c[RWZl/m@"0*b$h ꅫqjG%lp98?{~.M MӒZ?l2)zIH#BrΥoz8y: ޠ(:u|x!5QTJLӬxt΂ЕDm8V[./ujvP{%|Crz s'! RJ22c9?mpFkJjv"1/冋ΪGI{XH( @z7+7>'E##r tA`b -rQ=hu:/`j?A{9K,擕"Q胁xu6% iGx n ]ࢱMeV$A$dļlsT*^ܥKcWliOhO.i4e~zdbflVlIp_?<5EjRn`BL97.< CE?msd mK~U7*޲Qƭx|}̾r7k`G2alVXVIeVt,1K.AgyP|WAnAؼ֌ւSpL擭{9y{Ɵ CE{BE+Ζ-N -endstream -endobj -495 0 obj -<> -stream -xڝyTٶv!tu)LhW먈:f8 -`1`l+I$Lq09;:88^{ \yj.[ZZPy{eaAdYSi#]C|9/ R/~NV 梍ENy~Jћ]ɳCHgM41(3JaVlvo#3cbL Ќ?~;FӶq k_CB#ji"Vi~isݗts tqиyj#>9Zp?{H&E쫍І8k4~>Z__1D 'k 0?_MDF+'!аDv)p0mhptwrn1bW7\K5!oOM^68\!jCb_B*4Lk!2\`>Dn+YŤFWhh`vڈp@&y5T4$VB4s4Rz}HQfʾvgkHP)Hu,)+3JEuP])kQ՝APTOs7x՗GPv@ʞD Rèj$5MRj55B9PTjDM)j5EͦP5rQBʃZD-PKerjI}C-"!@Yt8dnf`l̂mjhy9 |ǦOBg}U0@|0}r5FzCz(9S*'`&{AWK*SKbt%Um"HˍÑ6 d$ϐR,OcR:[+F~p"MO5Q.zDڼqXnZ.d@DW]I֟dHkN"7փB5 \y[ZB U`76e;v#rҵ͉uP3+5{ؗu8:$1 1$eLIjEyZ]є`K"X*.EᘽCjUח1앨:9{ Et6( ?81ҷ%;:C&JɍQYȜRs{*i?8Vzr9܌ \\N/~̙SxNG}`?{šw6m9Mڝ+]lf͎q ZF{!/j.3*D!+vI26HIR_6lZ1t- wۄ q`-NoY -g]:3@c٫ЂA(Iu ws3Ͼ,\?q܉f]wǼW+YPE-EţT4;5eVLA( ((+/8'-59zoa -ۦ!`6TӠ)_a/ԷPA1̅6'1_}ջuts؂T[AY+d=شc߾nC='EE9ȶ*@YũE` lQAnAoUQH; QJTw%G/ ݻJIQnnrJTw*={]``l.|qynh,tҼ|ERvBn2b4p^;;SLV&RFWɶh? 5fS@!$T& !N?]$y$ŻyOytmձ;޺d;^өfZ~83\ݾvx q`wGܴ0 :UqB'aM%A$%cXȭh[7@qCQď0Gб͕X~\4- ziz;Jt~#}UgOwᒼ %%LP<.fy^K:"'Ƒt@q,, b!+}ҶX)Fnu1V~x35zwKK'm4SGXk+*plr[nH9oˌ̷bt:ѝWGhⷀv'0XfS)cԩU@}z H=8_&u&דMڥp`+d=2${K`/*HDG0t9HGw{Y{h<#bG~::F?mɸzDDĚz%MCsbG֑sd -чs-y - J8h-1;x<'ЛJI-Ӹ=+_4yI~(aZ -8z@tq8e+Y@W8O?Wa@Zkl4#Յ@7;@Aj<]1&=3+3ɭf p5NUfoKa)JnWmT(snv( d( FQ(.'(9.> Fcr`C_}99k@z 7Mۤf -- T޾1wHl#*$A/J< V*v1R²lkd6?߃`#+ ]ıC`bL&uLXob/]=/ .pe>Vj."09)UGIBQV)bJKUUQV Nx43z)!(} ׄ"3OOBcڀv-I)Z)Cb(:pY,}oA2ˑmey -r s@@'lkSoPaXĽ2{@-}P?0:9+#Hf|THA⽈sb2I^XtD]Ǹ)TD^<˰{-fwBgKA2(&Py -BGBKL]־9=:4@W25VaG`R'`Ɓy?o&hk -{qhyq#<nUtd ը!R -ֳs/w JΚM;t:O-E鲞o\M+Ej^\N-^vkBr&3`ɳaЅ7r8roLgM`o7[IEL`ª`9kaĦXkiF -q)2kZl4 ~j_ߐus;@6ZG6+S{5QK#ݼ -1 -.g[ -6"D"L+D8OS!PLJ  xoQ@5uDN+s&H5fZRs:ifH@`?@?p72xb߁c'b'~?JvpI}ͽDH>_}txsnՅ;'2d8ĖAgЙM: -ra[&q~b. ޫWoud` >eؔҴ*~>7HxʍM MF &EH'VFKвc;a}#T -Qw9n. c?u,Vm=nm[H-* E0fy_DYO2vZ{ֻB\xr>7op+ȏ }TYrd}W} -.̏+I/k7Ho/ĴXcMZ3O"̍,W%Qih&_?eܴLX$7a7X﷬8qdR65 -m\8-hb=0sާʐDυ&Xoðb֧Tc=&~Yh@ W`+̢A/V+*>-t3x7SgH"LvEsH6;tf(Iҧm8}Z:nނ<] *Gdp (ߊJίjZF %597"y OBބjY<> -stream -xڝZ XSg־rsk-kKmնZZglǎK֥/B$! KHd!$!awQQk]ju:mvi\ g};{9yϧ"$p8F,??bIʎ42ȒcG/'|Op|O$| 07&d;+ 2b?7??q7\N)5΍Szf Nj!sTW1xE|͏ȿFW/s6G7=f -~}xӞ'&H -gEωE2nYۭ?]n2PgF})b9ʛ] ^O)Cm[ @mJ\*X &] ՙ^Pbph *W[v堁J vJ9*l"P_ny.\v9)ꍊe 4S] Ry*[D; m͙r0ђ__TX]f(6[<ȵRHv;^X -rpK8iUq6,QpotT vf dxWnZꚅഔgPZ -N9N*EYx74&MK !jvh.3!maLLX̐CZu﹊1x[ңr%~w.h֮.ikPMƧJhVN5Z fPAO)TMpTvPZ/ҋt` 14|+<3f5LI|0ƒ-/l?yΞ-÷\^ڲx-46Fiԃ=p@qQMaO䥂` YZ`3 -BITtث UJC_fʁH}K$l"K_lOsO4K -%*X 3b%ɩ JOkB]Vdu8TROF!H&Mߺ#Saxߦk\ޠD1h쵫 Be)H$/5~'N(dZB=1rSśNQƱg`$bFM9s`^QNMjiRb~ _|>kpEԣ#:f)3>F)մ_= Jx|Sdvm>{iw3E|po#~wF.^;&J-e0KS F{0 aLJ.*/uYÊˬeP5ʉgB3.&\cu8bS%4*eP^,-@ a PJnin³!+'OWh +0YL`='xzgwXYт]$zTe/_K4gY/$4F%IAFm`켁qOdqXX'iĚ1HLK.(o/ܛ=#b|}I{P)<xQ"瑙fi (Q ~fl/!f& -0dgK$dح{ybiyC:ޚ -#j s| n/n4y_o'eP?&׹ۅC8`7$lގ͟ naoL/=h/dgp|w3Ib3>EWOx_8F0;ߒ(2~G#L<0e8$HaQ!9Wˏ-/4=M.=i)~{,תJGF׽{;/32cOs]!h -]NF}*g)_ ;vitCzEBݶ8u:wV^Bڦn_}?*6.ǕUK`y?}캒@ѱ=e%U{UP9zJ&v1mɍb׋U\y GZjC=.1=, ]w *7/ S -Le;Uelk\[=!zKy" -?ƚ'b0un0fg#b&|h3\nV7#'E2j^.uy3˙ayԗlf<9v1(|3:-8ˎ2UڝsV/ SB\o Gooƥ<6a΄< =&< *; qXc 5yg -g#Ey._9w>zBVh@Y y37c2euΣj9 [4$s0u=p3ZNz;Nfˆh,/;"qĸ}Z/:lfFGQnGK'~Ih6]9=GX?fŽI$T6nK> QɵqipfS,ow__Dx,׵sbCXi@ 2k9wc6D>f\K>Eoq4Gi*i*="-ʄTHS-=Ov4 -h]57:reB!NutV1"Mv;5-B$}yM'VB -ddԀ`(; }Aqh&T-%=BjYNp>2JlQւDM!2[4 Ýiv,"F/&hŌNrE^xaُ>|[!KOE;]da9h ߀hͦhH yh oGm-[H/>톦8H^{#r̈+hjmB_mn' l{ߵԜI$?>.pU<P-B69MI?uY!D;\ll'lCaM$Ђďa^Z'!9D7͵nS"tj}2:6vi\,`f ܉5CSe -gПaaѝzh[C;|c\])NUsĘd/<D,Hd>5 9#=R3YI"pe="'3ng4` S.,Y YYNbdzJ΋ي`_Y '5{䆵 -]$P+dDžh7Nڡ=]*&پ?MyPwNC(pa58iJ3-!{d@H'-}íM&ߝ7 -{ސd)0t ^w&y!=6K>Xw K4Yu+۰=l:зz2*"""ám4^ߠ1 'X2Ԑbk!4+dΫo}0i3A-d׀΂AL;XweTKK| `^1!=\Hh?3{g؝A%ի!roQm5 4ȪջPTOMCRj1{WGhŊf6fcjAJ -)R(f>oyv %VjY<8Vַ6Rhi B%#/O|6KmMmnmW;igj?]YqĴ<魖 $A`;[>3@oʐ+u\ߦ#ܑձ[ILȤ fA5JښvؠPM`Wu}6vGhǷăF{<R0"||ƈ~g9ȇ|?? -endstream -endobj -499 0 obj -<> -stream -xڭx T׶v1Tu!8[@Vp@Aq DDdI桙ACy^y@PFAdTfD0q$j x=} -w%]o{E|go{V)uz:'E$ IwL ܧFK4_ Ѹ/aCi~*KTit5Sߡ:T&+vp \uEfB[{.4]hf+J3"CRCHS Ì-4O. M"W'$%JLRHEhRcU>$3/dSC(-j5JMSzLj52ReBͧLZL-R˨)sʂVSʎ(Gʉr\(Wʍr<(OʋZKyS>:j=(*ZJPTlTUTT ƩQ W+U_~sf+sy'B+{NcecTF;c;5c & M4zI'c)VSp ܰvmu6$Iԯ# }(ɍh8M$/c%38 AB7 `cf6yF&B,? Txc5=Z![01:8:8<-X.$҃{G,)έs-P*W2 @;xD#Jm$"Od[NaFL%ur7 HzƼX2ە"zD=YGpY1؅m\d|ͧ 3N9AБТ®}95NbM4! l0Y =zt!a-V9aǵ]}]}EgH_3;E1VF.:w=q~~Yhzb:e1N~1H E\uӦ EFBXjjdi?:tj4ϔ2A|112F#?`2J䥙AǃI݀lr2yHr%7^ Dvue\h|9:2ѵ+˵?fw -sCre1{l(ş7h?4~}ErT6%ê!C6JcΊAr[ZnYö||"#aa?d,DA:Mx\3{ 7cfل=N.cJ)aP֤T͉KyD`l:qF?WNc :F!g3s%؅`#$^ -#GO p&[2;-QiQss w$2<50 z'0!4W|%x9`Bp!0}gO,8]pf-cugl@F,^ -Cmz.fW#{,RRF3ь"ȞUVIgz&1<7O cp1p,^U:u."H\uWeGC>"ۜsҰx# -c]M-,Lcf7$>W4p((H^eb׀/Þ$S9A4rc.Tu?&F{/M Y0C0!.'Xh ;/;/D̡zLxLa[rкqKMƅRicQ SΦr.+/+ym w>.n־9.:r=cGu _beDvvSűv.\|` -&`1/v|u׭~uHH=ߪJ$͛1GlL\,Q<X-wvo$1CF=.~u~ p* -/{nbhWνkw1h> s@ڵ?˓>]V xH-S,@FsGm-,vC$oI֖>ub:##1$w2C{.؎Q hOH)}nB,(i/Eʹsg.jb00of#'2y;#sk*hd i#n|b3RssGI OXձN+@Gh>QdLʼAh,eÌ[89:9l6{/K?~e=Ӏ4"GzD/]_wݦt>8(7OWKv'QN?~&BAWMdn!+0Q$$#"C+1ٴzƌцVk}<}ܒa ˎIJP_~i}{PM}e,Q薐w -p;11o^VtՖyux(eь%e O2b.u[i2RHKbm۶CQd!q{́˝,7 o$ĭ..$K"ǠA 3 -lmAl'+MGh1;-h{B`)85\JϾy[ʠP@ʐMvg@Z gC:\0˝;;.ŌfS4+{ˆeKOHZjG^ԣ aÿj Ϯ^v&)f)vQ[W[W|4 mS /<4;?*i^wId\//o8M~0$Ї/|zaq\]@#gXy$B7mX<|3Dkw7:xx)Ĕc< B-Ϳ0#3nrKJC[XA7EULH5kk y]S%k{08۬l(W_$Wk[.s#yAw勵k=<o}jFBv:BJnbl4Dpqpq̢HKnsNc-ۋN7xeG''n_:9__"t~{6dn;M(5q'n~AF@%[ܣ]<\Y'{u:qhі×^>zZ` (yQwW\Ύ3i3ԃ=ws)2##hT&7]P9아bRHܱ)u,+"9Tµv~K[kKHZ >% xZ{sCQTl PO\X޿--؊R!*qjqVcb2F nkR>Ɓ4mdT~&).?{s~-~RsK\}|۠*3se璏DHi te|ɉW^ R;]ebvߓ] z3=+3ӒEA4w!`?nCg[MKM99ɇS>Q@E {Z0H .ut/)I ]BD]2ϑ>B iv5bxsws~X˄g2`ֿE)^?j&F9IN|, w6ܝ[E,XőڻmvAv~~.2;$$1iMpMɏjl6t.縂՟J>t6sY4_3AfXH䣈Q7!KޮA(i^F[0s3c[}'X#zPzh7" `cʡhgFEmR_4Pnj -endstream -endobj -501 0 obj -<> -stream -xcd`aa`ddw r/H N+,ILIq1thww<&)yS# YrL?0200<A)$/ 122r'e9dgdV($$*$Teg(h$k* CTĒ<=@.VZh$_˰*úMTϻ@R_DeX-'ҫAq> -stream -x=kLSgi{N (tRE 6. aZZJ{-P^ɞ-318q[K]7A̽}ˇ>IDIooٵ`dQf[52I:x%/O-E\E 5BN*$P&A 'C IF2$̺=Á6YY*x pH熱>D$`_q2gR\>^LTbC -xm| 1YX=0URCn1׎ oϱٱgnWm4oh{> -stream -xcd`aa`ddspv 44 l2 ?d1g!"Ћ?,AD~j@1W[mjbQQ~yQfzFs~A%`hii`d``ZXX('gT*hdX뗗%i(gd(((%*@s JKR|SR.dT L,9?:~|xk߫DC ܚ}8wO?wc={Rk_gO߼{StLhﮗc~m*+vϕ+^~!oir\,y8'ppo̽y6~(S -endstream -endobj -509 0 obj -<> -stream -x]Pn0+/'!qH[PKemCf;I֑~Y-z0*^@pR-fnXܹ3B:jO5HAr\ q Gy;5THN<ާhMpz6}18#yX]G|(Dg@iBVeY U I{+w0nYUa~츌tP 1RUi0_qm+?y{ -endstream -endobj -512 0 obj -<> -stream -x]Pn0 +|**!-+$}~@H T( $P=Ē3cgҺܩ6A/A -endstream -endobj -488 0 obj -<> -stream -x͘YSHW{gTJ !$pʃ0֮-9dLRaO=;ƙN8^b-Lk,e[=BXf8gBsjHl U`1ay$%ܒ( F3ˤIc%sE@ =șeJ*ǬbJ )c*GEj;樷heiD0mgW8zND1٧th8N;R>CHopU-kTNŢ=sj%$#sf3ڐ9:vXζU25>t%[;yl%^Qli5m%v|O5׹&O\UOj?јz9Srߺ%H).=&gUO~S˧=Ej}5U/|fT31TX1 %ҽ&X -N3,sԝQK7pȮx -ojA18c։R4*`MƊƢ0iT9DZU"!ԍbK?|u+|v|n>ӼD\fʊ~<ۙyye7fЭ.,S[F' q)MY Y%>5o9>H&X^9S 5+׳0y/FaLj@:V(AT1)& %0ͨrPҲ -89(r(0ZPN\Cro:6=l2-av``|C|c8S8 34DM{8`. - C# -c(aSO -5˲I6["{݌+F io: _i:-F\¦APhFWUKV UEGyϠ 3E E|Ibc}2-ԈNG<\]PT]T2opb9I~/ -endstream -endobj -524 0 obj -<<1fc3b00cdb8184dd4523869777b7f018>]/Size -525/W[1 3 2]/Filter/FlateDecode/Length 1265>> -stream -x5wLVW{D'b8jV8‰[VEqT[ܸJU+iĤ+#6mlM'O~g<1TUxzn\835F/_CRDЇ~ `C50c&a-bاǣ}nDLd6FS 10b3 -[c&bL\yu;2.{b/uuFW0d]I^OLA*^b:9duѺAi -db1?i҅d-uW1ckލ|=uw!fj]}э=6a fAՙ::6{)-bJj2d嬨lSw-s?9T̳gSJ<p_9#D*)riv?(\GL}X8'DOɓDgS"9Gy8_|Fϊot&\^p1\E r\!J'OCrWj\9ߒY@XUN} ZVNOUiUv7J`r6IZX"'iEyz;Ui?pGn9;$4{oUhRmU]X*'tn }Bh.F}u;D%iPBtAqϵ'?e5?,9~TV#loxLy:zQnwkpOiY!7cmyH [Qx1u&N 9'җ=b"&G?all-`CØQ 39:ha{l.Ħ -mgh}1;avXh{VM=v6B\?v%ۉlF)lC0p h(p,|p"^0`ڛ7Lq;|.hj{?/{,B{;sn57`Nq/xcxOi.^ƫXPw{֏ _Fe#ƌDM'n~q3ʵ[;!q}u ^i[A0FcK 44qNiRxLtLd 16?cj -endstream -endobj -startxref -623471 -%%EOF diff --git a/documentation/UsersGuide/UsersGuide.rst b/documentation/UsersGuide/UsersGuide.rst deleted file mode 100644 index 3b058989..00000000 --- a/documentation/UsersGuide/UsersGuide.rst +++ /dev/null @@ -1,2007 +0,0 @@ - -.. -*- Mode: rst -*- - -.. role:: ul -.. role:: cb -.. role:: sc -.. role:: fboxtt - -.. Acronyms & names. -.. |GNU| replace:: :sc:`gnu` -.. |LGPL| replace:: :sc:`lgpl` -.. |GPL| replace:: :sc:`gpl` -.. |UPMC| replace:: :sc:`upmc` -.. |Bull| replace:: :sc:`Bull` -.. |Cadence| replace:: :sc:`Cadence` -.. |Si2| replace:: :sc:`Si2` -.. |LEFDEF| replace:: :sc:`lefdef` -.. |Flute| replace:: :sc:`Flute` -.. |MacOS| replace:: :sc:`MacOS` -.. |RHEL6| replace:: :sc:`rhel6` -.. |RHEL7| replace:: :sc:`rhel7` -.. |SL6| replace:: :sc:`Scientific Linux 6` -.. |SL7| replace:: :sc:`Scientific Linux 7` -.. |Scientific Linux| replace:: :sc:`Scientific Linux` -.. |RedHat| replace:: :sc:`RedHat` -.. |Fedora| replace:: :sc:`Fedora` -.. |FC13| replace:: :sc:`fc13` -.. |Debian| replace:: :sc:`Debian` -.. |Ubuntu| replace:: :sc:`Ubuntu` - -.. |Alexandre| replace:: :sc:`Alexandre` -.. |Belloeil| replace:: :sc:`Belloeil` -.. |Chaput| replace:: :sc:`Chaput` -.. |Chu| replace:: :sc:`Chu` -.. |Clement| replace:: :sc:`Clement` -.. |Dupuis| replace:: :sc:`Dupuis` -.. |Escassut| replace:: :sc:`Escassut` -.. |Gouvine| replace:: :sc:`Gouvine` -.. |Masson| replace:: :sc:`Masson` -.. |Sroka| replace:: :sc:`Sroka` -.. |Yifei| replace:: :sc:`Yifei` - -.. |ANSI| replace:: :sc:`ansi` -.. |MIPS| replace:: :sc:`mips` -.. |Am2901| replace:: :sc:`Am2901` -.. |Hurricane| replace:: :sc:`Hurricane` -.. |HurricaneAMS| replace:: :sc:`HurricaneAMS` -.. |Alliance| replace:: :sc:`Alliance` -.. |Yosys| replace:: :sc:`Yosys` -.. |GenLib| replace:: :sc:`GenLib` -.. |Nero| replace:: :sc:`Nero` -.. |Druc| replace:: :cb:`Druc` -.. |Coloquinte| replace:: :sc:`Coloquinte` -.. |Coriolis| replace:: :sc:`Coriolis` -.. |Coriolis1| replace:: :sc:`Coriolis 1` -.. |Coriolis2| replace:: :sc:`Coriolis 2` -.. |VLSISAPD| replace:: :sc:`vlsisapd` -.. |CRLcore| replace:: :sc:`CRLcore` -.. |Cyclop| replace:: :sc:`Cyclop` -.. |Nimbus| replace:: :sc:`Nimbus` -.. |hMetis| replace:: :sc:`hMetis` -.. |Mauka| replace:: :sc:`Mauka` -.. |Etesian| replace:: :sc:`Etesian` -.. |Knik| replace:: :sc:`Knik` -.. |Katabatic| replace:: :sc:`Katabatic` -.. |Kite| replace:: :sc:`Kite` -.. |Stratus| replace:: :sc:`Stratus` -.. |Stratus1| replace:: :sc:`Stratus1` -.. |Stratus2| replace:: :sc:`Stratus2` -.. |Unicorn| replace:: :sc:`Unicorn` -.. |ccb| replace:: :cb:`ccb` -.. |cgt| replace:: :cb:`cgt` -.. |Chams| replace:: :sc:`Chams` -.. |OpenChams| replace:: :sc:`OpenChams` -.. |Pharos| replace:: :cb:`Pharos` -.. |API| replace:: :sc:`api` -.. |STL| replace:: :sc:`stl` -.. |XML| replace:: :sc:`xml` -.. |pdf| replace:: :sc:`pdf` -.. |UTF-8| replace:: :sc:`utf-8` -.. |Python| replace:: :sc:`Python` -.. |Linux| replace:: :sc:`Linux` -.. |MacPorts| replace:: :sc:`MacPorts` -.. |devtoolset2| replace:: :cb:`devtoolset2` -.. |boost| replace:: :cb:`boost` -.. |Qt| replace:: :sc:`qt` -.. |tty| replace:: :cb:`tty` -.. |svn| replace:: :cb:`svn` -.. |git| replace:: :cb:`git` -.. |rpm| replace:: :cb:`rpm` -.. |gdb| replace:: :cb:`gdb` - -.. |KeyUp| replace:: :fboxtt:`Up` -.. |KeyDown| replace:: :fboxtt:`Down` -.. |KeyLeft| replace:: :fboxtt:`Left` -.. |KeyRight| replace:: :fboxtt:`Right` -.. |KeyF| replace:: :fboxtt:`f` -.. |KeyL| replace:: :fboxtt:`l` -.. |KeyG| replace:: :fboxtt:`g` -.. |KeyZ| replace:: :fboxtt:`z` -.. |KeyM| replace:: :fboxtt:`m` -.. |KeyI| replace:: :fboxtt:`i` -.. |KeyK| replace:: :fboxtt:`k` -.. |KeyP| replace:: :fboxtt:`p` -.. |KeyO| replace:: :fboxtt:`o` -.. |KeyW| replace:: :fboxtt:`w` -.. |KeyQ| replace:: :fboxtt:`q` -.. |KeyCapK| replace:: :fboxtt:`K` -.. |KeyCapS| replace:: :fboxtt:`S` -.. |Plus| replace:: :fboxtt:`+` -.. |KeyESC| replace:: :fboxtt:`ESC` -.. |CTRL| replace:: :fboxtt:`CTRL` -.. |CTRL_L| replace:: :fboxtt:`CTRL+L` -.. |CTRL_I| replace:: :fboxtt:`CTRL+I` -.. |CTRL_P| replace:: :fboxtt:`CTRL+P` -.. |CTRL_O| replace:: :fboxtt:`CTRL+O` -.. |CTRL_W| replace:: :fboxtt:`CTRL+W` -.. |CTRL_Q| replace:: :fboxtt:`CTRL+Q` -.. |CTRL_Down| replace:: :fboxtt:`CTRL+Down` -.. |CTRL_Up| replace:: :fboxtt:`CTRL+Up` -.. |CTRL_Left| replace:: :fboxtt:`CTRL+Left` -.. |CTRL_Right| replace:: :fboxtt:`CTRL+Right` - -.. URLs -.. _FGR: http://vlsicad.eecs.umich.edu/BK/FGR/ -.. _Box Router: http://www.cerc.utexas.edu/~thyeros/boxrouter/boxrouter.htm -.. _hMETIS: http://glaros.dtc.umn.edu/gkhome/views/metis -.. _Knik Thesis: http://www-soc.lip6.fr/en/users/damiendupuis/PhD/ -.. _RapidJSON: http://miloyip.github.io/rapidjson/ - -.. _coriolis2-1.0.2049-1.slsoc6.i686.rpm: http://asim.lip6.fr/pub/coriolis/2.0/coriolis2-1.0.2049-1.slsoc6.i686.rpm -.. _coriolis2-1.0.2049-1.slsoc6.x86_64.rpm: http://asim.lip6.fr/pub/coriolis/2.0/coriolis2-1.0.2049-1.slsoc6.x86_64.rpm -.. _coriolis2-1.0.2049-1.fc16.i686.rpm: http://asim.lip6.fr/pub/coriolis/2.0/coriolis2-1.0.2049-1.fc16.i686.rpm -.. _coriolis2-1.0.2049-1.fc16.x86_64.rpm: http://asim.lip6.fr/pub/coriolis/2.0/coriolis2-1.0.2049-1.fc16.x86_64.rpm -.. _coriolis2_1.0-2049-1_.i386.rpm (10.04): http://asim.lip6.fr/pub/coriolis/2.0/Ubuntu/10.04/coriolis2_1.0-2049-1_i386.rpm -.. _coriolis2_1.0-2049-1_.amd64.rpm (10.04): http://asim.lip6.fr/pub/coriolis/2.0/Ubuntu/10.04/coriolis2_1.0-2049-1_i386.rpm -.. _coriolis2_1.0-2049-1_.i386.rpm (12.04): http://asim.lip6.fr/pub/coriolis/2.0/Ubuntu/12.04/coriolis2_1.0-2049-1_i386.rpm -.. _coriolis2_1.0-2049-1_.amd64.rpm (12.04): http://asim.lip6.fr/pub/coriolis/2.0/Ubuntu/12.04/coriolis2_1.0-2049-1_i386.rpm - -.. Standard CAO/VLSI Concepts. -.. |netlist| replace:: *netlist* -.. |netlists| replace:: *netlists* -.. |layout| replace:: *layout* -.. |layouts| replace:: *layouts* -.. |CMOS| replace:: :sc:`cmos` -.. |VHDL| replace:: :sc:`vhdl` -.. |NWELL| replace:: :sc:`nwell` -.. |POWER| replace:: :sc:`power` -.. |GROUND| replace:: :sc:`ground` - -.. MBK Concepts -.. |MBK| replace:: :sc:`mbk` -.. |LOFIG| replace:: :cb:`Lofig` -.. |PHFIG| replace:: :cb:`Phfig` -.. |SxLib| replace:: :sc:`SxLib` - -.. Hurricane Concepts. -.. |hypernet| replace:: *hypernet* -.. |hypernets| replace:: *hypernets* -.. |Cell| replace:: *Cell* -.. |Rings| replace:: *Rings* -.. |QuadTrees| replace:: *QuadTrees* -.. |Collections| replace:: *Collections* -.. |ap| replace:: :cb:`ap` -.. |vst| replace:: :cb:`vst` -.. |kgr| replace:: :cb:`kgr` -.. |dot_conf| replace:: :cb:`.conf` - - -|medskip| - -===================== -Coriolis User's Guide -===================== - -|medskip| - -.. raw:: html - -

- The pdf version of this document is available here:
- Coriolis User's Guide -
- -.. contents:: - -|newpage| - - -Credits & License -================= - -.. raw:: html - -

Hurricane - Rémy Escassut & - Christian Masson

-
-

Etesian - Gabriel Gouvine

-
-

Stratus - Sophie Belloeil

-
-

Knik - Damien Dupuis

-
-

Kite, - Unicorn - Jean-Paul Chaput

-
- - -.. raw:: latex - - \begin{center}\begin{minipage}[t]{.8\textwidth} - \noindent\DUrole{sc}{Hurricane} \dotfill Rémy \DUrole{sc}{Escassut} \& - Christian \DUrole{sc}{Masson} \\ - \noindent\DUrole{sc}{Etesian} \dotfill Gabriel \DUrole{sc}{Gouvine} \\ - \noindent\DUrole{sc}{Stratus} \dotfill Sophie \DUrole{sc}{Belloeil} \\ - \noindent\DUrole{sc}{Knik} \dotfill Damien \DUrole{sc}{Dupuis} \\ - \noindent\DUrole{sc}{Kite}, - \DUrole{sc}{Unicorn} \dotfill Jean-Paul \DUrole{sc}{Chaput} \\ - \end{minipage}\end{center} - - -|medskip| - -The |Hurricane| data-base is copyright© |Bull| 2000-2016 and is -released under the terms of the |LGPL| license. All other tools are -copyright© |UPMC| 2008-2016 and released under the |GPL| -license. - -Others important contributors to |Coriolis| are Christophe |Alexandre|, -Hugo |Clement|, Marek |Sroka| and Wu |Yifei|. - -The |Knik| router makes use of the |Flute| software, which is -copyright© Chris C. N. |Chu| from the Iowa State University -(http://home.eng.iastate.edu/~cnchu/). - -|newpage| - - -Release Notes -============= - -Release 1.0.1475 -~~~~~~~~~~~~~~~~ - -This is the first preliminary release of the |Coriolis2| framework. - -This release mainly ships the global router |Knik| and the detailed router -|Kite|. Together they aim to replace the |Alliance| |Nero| router. -Unlike |Nero|, |Kite| is based on an innovating routing modeling and ad-hoc -algorithm. Although it is released under |GPL| license, the source code -will be avalaible later. -|medskip| - - -|noindent| Contents of this release: - -1. A graphical user interface (viewer only). -2. The |Knik| global router. -3. The |Kite| detailed router. - -|noindent| Supported input/output formats: - -* |Alliance| |vst| (netlist) & |ap| (physical) formats. -* Even if there are some references to the |Cadence| |LEFDEF| format, its - support is not included because it depends on a library only available - to |Si2| affiliated members. - - -Release 1.0.1963 -~~~~~~~~~~~~~~~~ - -Release 1963 is alpha. All the tools from |Coriolis1| have been ported into -this release. - -|noindent| Contents of this release: - -#. The |Stratus| netlist capture language (|GenLib| replacement). -#. The |Mauka| placer (still contains bugs). -#. A graphical user interface (viewer only). -#. The |Knik| global router. -#. The |Kite| detailed router. -#. Partially implemented python support for configuration files - (alternative to |XML|). -#. A documentation (imcomplete/obsoleted in |Hurricane|'s case). - - -Release 1.0.2049 -~~~~~~~~~~~~~~~~ - -Release `2049` is Alpha. - -|noindent| Changes of this release: - -#. The |Hurricane| documentation is now accurate. Documentation - for the Cell viewer and |CRLcore| has been added. -#. More extensive Python support for all the components of - |Coriolis|. -#. Configuration is now completly migrated under Python. - |XML| loaders can still be useds for compatibilty. -#. The |cgt| main has been rewritten in Python. - - -Release v2.0.1 -~~~~~~~~~~~~~~ - -#. Migrated the repository from |svn| to |git|, and release complete sources. - As a consequence, we drop the distribution packaging support and give - public read-only access to the repository. -#. Deep rewrite of the |Katabatic| database and |Kite| detailed router, - achieve a speedup factor greater than 20... - - -Release v2.1 -~~~~~~~~~~~~ - -#. Replace the old simulated annealing placer |Mauka| by the analytical placer - |Etesian| and its legalization and detailed placement tools. -#. Added a Blif format parser to process circuits generated by the Yosys and ABC - logic synthetizers. -#. The multiples user defined configuration files are now grouped under - a common hidden (dot) directory ``.coriolis2`` and the file extension - is back from ``.conf`` to ``.py``. - -.. #. Under |RHEL7| / |SL7|, there is a known bug in the graphical visualizer. -.. When shifting to the left, the right-half part of the screen gets -.. badly redrawn. Uses |CTRL_L| to refresh. It will be corrected as soon -.. as possible. - - -**Release v2.2** -~~~~~~~~~~~~~~~~ - -#. Added JSON import/export of the whole Hurricane DataBase. Two save mode - are supported: *Cell* mode (standalone) or *Blob* mode, which dump the - whole design down and including the standard cells. - - -|newpage| - - -Installation -============ - -.. note:: - As the sources are being released, the binary packaging is dropped. - You still may find older version here: http://asim.lip6.fr/pub/coriolis/2.0 . - -In a nutshell, building source consist in pulling the |git| repository then -running the |ccb| installer. - -Main building prerequisites: - -* cmake -* C++11-capable compiler -* RapidJSON_ -* python2.7 -* boost -* libxml2 -* bzip2 -* yacc & lex -* Qt 4 or Qt 5 - -Building documentation prerequisites: - -* doxygen -* latex -* latex2html -* python-docutils (for reStructuredText) - -Optional libraries: - -* LEF/DEF (from `SI2 `_) - -For other distributions, refer to their own packaging system. - -|newpage| - - -Fixed Directory Tree -~~~~~~~~~~~~~~~~~~~~ - -In order to simplificate the work of the |ccb| installer, the source, build -and installation tree is fixed. To successfully compile |Coriolis| you must -follow it exactly. The tree is relative to the home directory of the user -building it (noted :fboxtt:`~/` or :fboxtt:`$HOME/`). Only the source -directory needs to be manually created by the user, all others will be -automatically created either by |ccb| or the build system. - -+--------------------------+-----------------------------------------------------------------------------+ -| **Sources** | -+--------------------------+-----------------------------------------------------------------------------+ -| | Sources root | | ~/coriolis-2.x/src | -| | **under git** | | ~/coriolis-2.x/src/coriolis | -+--------------------------+-----------------------------------------------------------------------------+ -| **Architecture Dependant Build** | -+--------------------------+-----------------------------------------------------------------------------+ -| | Linux, SL 7, 64 bits | | ~/coriolis-2.x/Linux.el7_64/Release.Shared/build/ | -| | Linux, SL 6, 32 bits | | ~/coriolis-2.x/Linux.slsoc6x/Release.Shared/build/ | -| | Linux, SL 6, 64 bits | | ~/coriolis-2.x/Linux.slsoc6x_64/Release.Shared/build/ | -| | Linux, Fedora, 64 bits | | ~/coriolis-2.x/Linux.fc_64/Release.Shared/build/ | -| | Linux, Fedora, 32 bits | | ~/coriolis-2.x/Linux.fc/Release.Shared/build/ | -| | FreeBSD 8, 32 bits | | ~/coriolis-2.x/FreeBSD.8x.i386/Release.Shared/build/ | -| | FreeBSD 8, 64 bits | | ~/coriolis-2.x/FreeBSD.8x.amd64/Release.Shared/build/ | -| | Windows 7, 32 bits | | ~/coriolis-2.x/Cygwin.W7/Release.Shared/build/ | -| | Windows 7, 64 bits | | ~/coriolis-2.x/Cygwin.W7_64/Release.Shared/build/ | -| | Windows 8.x, 32 bits | | ~/coriolis-2.x/Cygwin.W8/Release.Shared/build/ | -| | Windows 8.x, 64 bits | | ~/coriolis-2.x/Cygwin.W8_64/Release.Shared/build/ | -+--------------------------+-----------------------------------------------------------------------------+ -| **Architecture Dependant Install** | -+--------------------------+-----------------------------------------------------------------------------+ -| Linux, SL 6, 32 bits | ~/coriolis-2.x/Linux.slsoc6x/Release.Shared/install/ | -+--------------------------+-----------------------------------------------------------------------------+ -| **FHS Compliant Structure under Install** | -+--------------------------+-----------------------------------------------------------------------------+ -| | Binaries | | .../install/bin | -| | Libraries (Python) | | .../install/lib | -| | Include by tool | | .../install/include/coriolis2// | -| | Configuration files | | .../install/etc/coriolis2/ | -| | Doc, by tool | | .../install/share/doc/coriolis2/en/html/ | -+--------------------------+-----------------------------------------------------------------------------+ - -.. note:: *Alternate build types:* the ``Release.Shared`` means an optimized build - with shared libraries. But there are also available ``Static`` instead of ``Shared`` - and ``Debug`` instead of ``Release`` and any combination of them. - - ``Static`` do not work because I don't know yet to mix statically linked binaries - and Python modules (which must be dynamic). - -|newpage| - - -Building Coriolis -~~~~~~~~~~~~~~~~~ - -First step is to install the prerequisites. Currently, only RapidJSON_. -As RapidJSON is evolving fast, if you encounter compatibility problems, -the exact version we compiled against is given below. :: - - dummy@lepka:~$ mkdir -p ~/coriolis-2.x/src/support - dummy@lepka:~$ cd ~/coriolis-2.x/src/support - dummy@lepka:~$ git clone http://github.com/miloyip/rapidjson - dummy@lepka:~$ git checkout ec322005072076ef53984462fb4a1075c27c7dfd - -The second step is to create the source directory and pull the |git| repository: :: - - dummy@lepka:~$ mkdir -p ~/coriolis-2.x/src - dummy@lepka:~$ cd ~/coriolis-2.x/src - dummy@lepka:~$ git clone https://www-soc.lip6.fr/git/coriolis.git - -Third and final step, build & install: :: - - dummy@lepka:src$ ./bootstrap/ccb.py --project=support \ - --project=coriolis \ - --make="-j4 install" - dummy@lepka:src$ ./bootstrap/ccb.py --project=support \ - --project=coriolis \ - --doc --make="-j1 install" - -We need to separate to perform a separate installation of the documentation because it -do not support to be generated with a parallel build. So we compile & install in a first -stage in ``-j4`` (or whatever) then we generate the documentation in ``-j1`` - -Under |RHEL6| or clones, you must build using the |devtoolset2|: :: - - dummy@lepka:src$ ./bootstrap/ccb.py --project=coriolis \ - --devtoolset-2 --make="-j4 install" - -If you want to uses Qt 5 instead of Qt 4, you may add the ``--qt5`` argument. - -The complete list of |ccb| functionalities can be accessed with the ``--help`` argument. -It also may be run in graphical mode (``--gui``). - - -Building the Devel Branch -------------------------- - -In the |Coriolis| |git| repository, two branches are present: - -* The :cb:`master` branch, which contains the latest stable version. This is the - one used by default if you follow the above instructions. - -* The :cb:`devel` branch, which obviously contains the latest commits from the - development team. To use it instead of the :cb:`master` one, do the following - command just after the first step: :: - - dummy@lepka:~$ git checkout devel - dummy@lepka:src$ ./bootstrap/ccb.py --project=coriolis \ - --make="-j4 install" --debug - - Be aware that it may requires newer versions of the dependencies and may introduce - incompatibilites with the stable version. - - In the (unlikely) event of a crash of |cgt|, as it is a |Python| script, the right - command to run |gdb| on it is: :: - - dummy@lepka:work$ gdb python core.XXXX - -|newpage| - - -Additionnal Requirement under |MacOS| -------------------------------------- - -|Coriolis| make uses of the :cb:`boost::python` module, but the |macports| |boost| -seems unable to work with the |Python| bundled with |MacOS|. So you have to install -both of them from |macports|: :: - - dummy@macos:~$ port install boost +python27 - dummy@macos:~$ port select python python27 - dummy@macos:-$ export DYLD_FRAMEWORK_PATH=/opt/local/Library/Frameworks - -The last two lines tell |MacOS| to use the |Python| from |macports| and *not* from -the system. - -Then proceed with the generic install instructions. - - -Packaging Coriolis -~~~~~~~~~~~~~~~~~~ - -Packager should not uses |ccb|, instead ``bootstrap/Makefile.package`` is provided -to emulate a top-level ``autotool`` makefile. Just copy it in the root of the -|Coriolis| git repository (``~/corriolis-2.x/src/coriolis/``) and build. - -Sligthly outaded packaging configuration files can also be found under ``bootstrap/``: - -* ``bootstrap/coriolis2.spec.in`` for |rpm| based distributions. -* ``bootstrap/debian`` for |Debian| based distributions. - - -Hooking up into |Alliance| -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -|Coriolis| relies on |Alliance| for the cell libraries. So after installing or -packaging, you must configure it so that it can found those libraries. - -This is done by editing the one variable :cb:`cellsTop` in the |Alliance| helper -(see `Alliance Helper`_). This variable must point to the directory of the -cells libraries. In a typical installation, this is generally -:cb:`/usr/share/alliance/cells`. - - -Setting up the Environment (coriolisEnv.py) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -To simplify the tedious task of configuring your environment, a helper is provided -in the ``bootstrap`` source directory (also installed in the directory -``.../install/etc/coriolis2/``) : :: - - ~/coriolis-2.x/src/coriolis/bootstrap/coriolisEnv.py - -Use it like this: :: - - dummy@lepka:~> eval `~/coriolis-2.x/src/coriolis/bootstrap/coriolisEnv.py` - -.. note:: **Do not call that script in your environement initialisation.** - When used under |RHEL6| or clones, it needs to be run in the |devtoolset2| - environement. The script then launch a new shell, which may cause an - infinite loop if it's called again in, say :cb:`~/.bashrc`. - - Instead you may want to create an alias: :: - - alias c2r='eval "`~/coriolis-2.x/src/coriolis/bootstrap/coriolisEnv.py`"' - - -|newpage| - - -Documentation -============= - -The general index of the documentation for the various parts of Coriolis -are avalaibles here `Coriolis Tools Documentation`_. - -.. note:: **Python Documentation:** - Most of the documentation is related to the C++ API and implemetation of - the tools. However, the |Python| bindings have been created so they - mimic *as closely as possible* the C++ interface, so the documentation - applies to both languages with only minor syntactic changes. - -General Software Architecture -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -|Coriolis| has been build with respect of the classical paradigm that the -computational instensive parts have been written in C++, and almost -everything else in |Python|. To build the |Python| interface we used -two methods: - -* For self-contained modules :cb:`boost::python` (mainly in :cb:`vlsisapd`). -* For all modules based on |Hurricane|, we created our own wrappers due - to very specific requirements such as shared functions between modules - or C++/|Python| secure bi-directional object deletion. - -|CoriolisSoftSchema| - - -Coriolis Configuration & Initialisation -======================================= - -All configuration & initialization files are Python scripts, despite their -|dot_conf| extention. From a syntactic point of view, there is no difference -between the system-wide configuration files and the user's configuration, -they may use the same Python helpers. -|medskip| - -Configuration is done in two stages: - -#. Selecting the symbolic technology. -#. Loading the complete configuration for the given technology. - - -First Stage: Symbolic Technology Selection -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -|noindent| -The initialization process is done by executing, in order, the following -file(s): - -+-------+----------------------------------+----------------------------------------------+ -| Order | Meaning | File | -+=======+==================================+==============================================+ -| **1** | The system setting | :cb:`/etc/coriolis2/techno.conf` | -+-------+----------------------------------+----------------------------------------------+ -| **2** | The user's global setting | :cb:`${HOME}/.coriolis2/techno.py` | -+-------+----------------------------------+----------------------------------------------+ -| **3** | The user's local setting | :cb:`/.coriolis2/techno.py` | -+-------+----------------------------------+----------------------------------------------+ - -Thoses files must provides only two variables, the name of the symbolic technology -and the one of the real technology. For example: :: - - # -*- Mode:Python -*- - - symbolicTechno = 'cmos' - realTechno = 'hcmos9' - - -Second Stage: Technology Configuration Loading -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -|noindent| -The :cb:`TECHNO` variable is set by the first stage and it's the name of the -symbolic technology. A directory of that name, with all the configuration files, -must exists in the configuration directory. In addition to the technology-specific -directories, a :cb:`common/` directory is there to provides a trunk for all the -identical datas across the various technologies. The initialization process is done -by executing, in order, the following file(s): - -+-------+----------------------------------+----------------------------------------------+ -| Order | Meaning | File | -+=======+==================================+==============================================+ -| **1** | The system initialization | :cb:`/etc/coriolis2//.conf` | -+-------+----------------------------------+----------------------------------------------+ -| **2** | The user's global initialization | :cb:`${HOME}/.coriolis2/settings.py` | -+-------+----------------------------------+----------------------------------------------+ -| **3** | The user's local initialization | :cb:`/.coriolis2/settings.py` | -+-------+----------------------------------+----------------------------------------------+ - -.. note:: *The loading policy is not hard-coded.* It is implemented - at Python level in :cb:`/etc/coriolis2/coriolisInit.py`, and thus may be easily be - amended to whatever site policy. - - The truly mandatory requirement is the existence of :cb:`coriolisInit.py` - which *must* contain a :cb:`coriolisConfigure()` function with no argument. - - -Configuration Helpers -~~~~~~~~~~~~~~~~~~~~~ - -To ease the writing of configuration files, a set of small helpers -is available. They allow to setup the configuration parameters through -simple assembly of tuples. The helpers are installed under the directory: :: - - /etc/coriolis2/ - -Where :cb:`/` is the root of the installation. - -|newpage| - - -.. _Alliance Helper: - -|Alliance| Helper ------------------ - -The configuration file must provide a :cb:`allianceConfig` tuple of -the form: :: - - cellsTop = '/usr/share/alliance/cells/' - - allianceConfig = \ - ( ( 'SYMBOLIC_TECHNOLOGY', helpers.sysConfDir+'/technology.symbolic.xml' ) - , ( 'REAL_TECHNOLOGY' , helpers.sysConfDir+'/technology.cmos130.s2r.xml') - , ( 'DISPLAY' , helpers.sysConfDir+'/display.xml' ) - , ( 'CATALOG' , 'CATAL') - , ( 'WORKING_LIBRARY' , '.') - , ( 'SYSTEM_LIBRARY' , ( (cellsTop+'sxlib' , Environment.Append) - , (cellsTop+'dp_sxlib', Environment.Append) - , (cellsTop+'ramlib' , Environment.Append) - , (cellsTop+'romlib' , Environment.Append) - , (cellsTop+'rflib' , Environment.Append) - , (cellsTop+'rf2lib' , Environment.Append) - , (cellsTop+'pxlib' , Environment.Append) ) ) - , ( 'SCALE_X' , 100) - , ( 'IN_LO' , 'vst') - , ( 'IN_PH' , 'ap') - , ( 'OUT_LO' , 'vst') - , ( 'OUT_PH' , 'ap') - , ( 'POWER' , 'vdd') - , ( 'GROUND' , 'vss') - , ( 'CLOCK' , '^ck.*') - , ( 'BLOCKAGE' , '^blockageNet*') - ) - - -|noindent| The example above shows the system configuration file, with all the -available settings. Some important remarks about thoses settings: - -* In it's configuration file, the user do not need to redefine all the settings, - just the one he wants to change. In most of the cases, the ``SYSTEM_LIBRARY``, - the ``WORKING_LIBRARY`` and the special net names (at this point there is not - much alternatives for the others settings). - -* ``SYSTEM_LIBRARY`` setting: Setting up the library search path. - Each library entry in the tuple will be added to the search path according - to the second parameter: - - * :cb:`Environment::Append`: append to the search path. - - * :cb:`Environment::Prepend`: insert in head of the search path. - - * :cb:`Environment::Replace`: look for a library of the same name and replace - it, whithout changing the search path order. If no library of that name - already exists, it is appended. - - A library is identified by it's name, this name is the last component of the - path name. For instance: ``/soc/alliance/sxlib`` will be named ``sxlib``. - Implementing the |Alliance| specification, when looking for a |Cell| ``name``, - the system will browse sequentially trought the library list and returns - the first |Cell| whose name match. - -* For ``POWER``, ``GROUND``, ``CLOCK`` and ``BLOCKAGE`` net names, a regular - expression (|GNU| regexp) is expected. - -* The ``helpers.sysConfDir`` variable is supplied by the helpers, it is the - directory in which the system-wide configuration files are locateds. - For a standard installation it would be: ``/soc/coriolis2``. - -.. * Trick and naming convention about ``SYMBOLIC_TECHNOLOGY``, ``REAL_TECHNOLOGY`` -.. and ``DISPLAY``. In the previous releases, thoses files where to read by -.. XML parsers, and still do if you triggers the XML compatibility mode. -.. But now, they have Python conterparts. In the configuration files, you -.. still have to name them as XML files, the Python file name will be -.. deduced from this one with thoses two translation rules: -.. -.. #. In the filename, all dots, except for the last (the file extention), -.. are replaced by underscores. -.. -.. #. The ``.xml`` extention is substituted by a ``.conf``. -.. -.. For the symbolic technology, it would give: :: -.. -.. /soc/coriolis2/technology.symbolic.xml -.. --> /soc/coriolis2/technology_symbolic.conf - -A typical user's configuration file would be: :: - - import os - - homeDir = os.getenv('HOME') - - allianceConfig = \ - ( ('WORKING_LIBRARY' , homeDir+'/worklib') - , ('SYSTEM_LIBRARY' , ( (homeDir+'/mylib', Environment.Append) ) ) - , ('POWER' , 'vdd.*') - , ('GROUND' , 'vss.*') - ) - - -Tools Configuration Helpers ---------------------------- - -All the tools uses the same helper to load their configuration (a.k.a. -*Configuration Helper*). Currently the following configuration system-wide -configuration files are defined: - -* :cb:`misc.conf`: commons settings or not belonging specifically to a tool. -* :cb:`etesian.conf`: for the |Etesian| tool. -* :cb:`kite.conf`: for the |Kite| tool. -* :cb:`stratus1.conf`: for the |stratus1| tool. - -Here is the contents of :cb:`etesian.conf`: :: - - # Etesian parameters. - parametersTable = \ - ( ('etesian.aspectRatio' , TypePercentage, 100 , { 'min':10, 'max':1000 } ) - , ('etesian.spaceMargin' , TypePercentage, 5 ) - , ('etesian.uniformDensity' , TypeBool , False ) - , ('etesian.routingDriven' , TypeBool , False ) - , ("etesian.effort" , TypeEnumerate , 2 - , { 'values':( ("Fast" , 1) - , ("Standard", 2) - , ("High" , 3) - , ("Extreme" , 4) ) } - ) - , ("etesian.graphics" , TypeEnumerate , 2 - , { 'values':( ("Show every step" , 1) - , ("Show lower bound" , 2) - , ("Show result only" , 3) ) } - ) - ) - - layoutTable = \ - ( (TypeTab , 'Etesian', 'etesian') - - , (TypeTitle , 'Placement area') - , (TypeOption, "etesian.aspectRatio" , "Aspect Ratio, X/Y (%)", 0 ) - , (TypeOption, "etesian.spaceMargin" , "Space Margin" , 1 ) - , (TypeRule ,) - , (TypeTitle , 'Etesian - Placer') - , (TypeOption, "etesian.uniformDensity", "Uniform density" , 0 ) - , (TypeOption, "etesian.routingDriven" , "Routing driven" , 0 ) - , (TypeOption, "etesian.effort" , "Placement effort" , 1 ) - , (TypeOption, "etesian.graphics" , "Placement view" , 1 ) - , (TypeRule ,) - ) - -Taxonomy of the file: - -* It must contains, at least, the two tables: - - * ``parametersTable``, defines & initialise the configuration variables. - - * ``layoutTables``, defines how the various parameters will be displayed - in the configuration window (`The Settings Tab`_). - -* The ``parametersTable``, is a tuple (list) of tuples. Each entry in the list - describe a configuration parameter. In it's simplest form, it's a quadruplet - :cb:`(TypeOption, 'paramId', ParameterType, DefaultValue)` with: - - #. ``TypeOption``, tells that this tuple describe a parameter. - - #. ``paramId``, the identifier of the parameter. Identifiers are defined - by the tools. The list of parameters is detailed in each tool section. - - #. ``ParameterType``, the kind of parameter. Could be: - - * ``TypeBool``, boolean. - * ``TypeInt``, signed integer. - * ``TypeEnumerate``, enumerated type, needs extra entry. - * ``TypePercentage``, percentage, expressed between 0 and 100. - * ``TypeDouble``, float. - * ``TypeString``, character string. - - #. ``DefaultValue``, the default value for that parameter. - - -Hacking the Configuration Files -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Asides from the symbols that gets used by the configuration helpers like -:cb:`allianceConfig` or :cb:`parametersTable`, you can put pretty much anything -in :cb:`/.coriolis2/settings.py` (that is, written in |Python|). - -For example: :: - - # -*- Mode:Python -*- - - defaultStyle = 'Alliance.Classic [black]' - - # Regular Coriolis configuration. - parametersTable = \ - ( ('misc.catchCore' , TypeBool , False ) - , ('misc.info' , TypeBool , False ) - , ('misc.paranoid' , TypeBool , False ) - , ('misc.bug' , TypeBool , False ) - , ('misc.logMode' , TypeBool , True ) - , ('misc.verboseLevel1' , TypeBool , False ) - , ('misc.verboseLevel2' , TypeBool , True ) - , ('misc.minTraceLevel' , TypeInt , 0 ) - , ('misc.maxTraceLevel' , TypeInt , 0 ) - ) - - # Some ordinary Python script... - import os - - print ' o Cleaning up ClockTree previous run.' - for fileName in os.listdir('.'): - if fileName.endswith('.ap') or (fileName.find('_clocked.') >= 0): - print ' - <%s>' % fileName - os.unlink(fileName) - - -See `Python Interface to Coriolis`_ for more details those capabilities. - - -CGT - The Graphical Interface -============================= - -The |Coriolis| graphical interface is split up into two windows. - -* The **Viewer**, with the following features: - - * Basic load/save capabilities. - * Display the current working cell. Could be empty if the design - is not yet placed. - * Execute Stratus Scripts. - * Menu to run the tools (placement, routage). - -Features are detailed in `Viewer & Tools`_. - -|ViewerSnapShot_1| - -* The **Controller**, which allows: - - * Tweak what is displayer by the *Viewer*. Through the *Look*, - *Filter* and *Layers&Gos* tabs. - * Browse the |netlist| with eponym tab. - * Show the list of selected objects (if any) with *selection* - * Walk through the Database, the Cell or the Selection with *Inspector*. - This is an advanced feature, reserved for experimented users. - * The tab *Settings* which give access to all the settings. - They are closely related to Configuration & Initialisation. - -|ControllerSnapShot_1| - - -.. _Viewer & Tools: - -Viewer & Tools -============== - -|Stratus| Netlist Capture -~~~~~~~~~~~~~~~~~~~~~~~~~ - -|Stratus| is the replacement for |GenLib| procedural netlist capture language. -It is designed as a set of |Python| classes, and comes with it's own documentation -(`Stratus Documentation`_) - - -The |Hurricane| Data-Base -~~~~~~~~~~~~~~~~~~~~~~~~~ - -The |Alliance| flow is based on the |MBK| data-base, which has one data-structure -for each view. That is, |LOFIG| for the *logical* view and |PHFIG| for the *physical* -view. The place and route tools were responsible for maintaining (or not) the -coherency between views. Reflecting this weak coupling between views, each one -was stored in a separate file with a specific format. The *logical* view is stored -in a |vst| file in |VHDL| format and the *physical* in an |ap| file in an ad-hoc format. - -The |Coriolis| flow is based on the |Hurricane| data-base, which has a unified -structure for *logical* and *physical* view. That data structure is the |Cell| object. -The |Cell| can have any state between pure netlist and completly placed and -routed design. Although the memory representation of the views has deeply -changed we still use the |Alliance| files format, but they now really represent -views of the same object. The point is that one must be very careful about -view coherency when going to and from |Coriolis|. - -As for the second release, |Coriolis| can be used only for three purposes : - -* **Placing a design**, in which case the |netlist| view must be present. -* **Routing a design**, in that case the |netlist| - view and the |layout| view must be present and |layout| view must contain - a placement. Both views must have the same name. When saving the routed design, - it is advised to change the design name otherwise the original unrouted placement - in the |layout| view will be overwritten. -* **Viewing a design**, the |netlist| view must be present, if a |layout| - view is present it still must have the same name but it can be in any - state. - - -Synthetizing and loading a design -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -|Coriolis| supports several file formats. It can load all file format -from the |Alliance| toolchain (.ap for layout, behavioural and structural vhdl .vbe and .vst), -BLIF netlist format as well as benchmark formats from the ISPD contests. - -It can be compiled with LEF/DEF support, although it requires acceptance of the SI2 license -and may not be compiled in your version of the software. - -Synthesis under Yosys ---------------------- - -You can create a BLIF file from the |Yosys| synthetizer, which can be imported under Coriolis. -Most libraries are specified as a .lib liberty file and a .lef LEF file. -|Yosys| opens most .lib files with minor modifications, but LEF support in Coriolis relies on SI2. -If Coriolis hasn't been compiled against it, the library is given in |Alliance| .ap format. -`Some free libraries `_ already provide both .ap and .lib files. - -Once you have installed a common library under |Yosys| and Coriolis, just synthetize your design -with |Yosys| and import it (as Blif without the extension) under Coriolis to perform place&route. - -Synthesis under Alliance ------------------------- - -|Alliance| is an older toolchain but has been extensively used for years. Coriolis can import -and write Alliance designs and libraries directly. - -Etesian -- Placer -~~~~~~~~~~~~~~~~~ - -The |Etesian| placer is a state of the art (as of 2015) analytical placer. It is -within ``5%`` of other placers' solutions, but is normally a bit worse than ePlace. -This |Coriolis| tool is actually an encapsulation of |Coloquinte| which *is* the placer. - -.. note:: *Instance Uniquification Unsupported:* a same logical instance cannot have - two different placements. So, either you manually make a clone of it or you - supply a placement for it. We need to implement uniquification in the - |Hurricane| database. - - -|noindent| -**Hierarchical Placement** - -The placement area is defined by the top cell abutment box. - -When placing a complete hierarchy, the abutment boxes of the cells (models) other than -the top cell are sets identical to the one of the top cell and their instances are -all placed at position ``(0,0,ID)``. That is, all the abutments boxes, whatever the -hierarchical level, defines the same area (they are exactly superposed). - -We choose this scheme because the placer will see all the instances as virtually -flattened, so they can be placed anywhere inside the top-cell abutment box. - -|Etesian-1| - - -|noindent| -**Computing the Placement Area** - -The placement area is computed using the ``etesian.aspectRatio`` and ``etesian.spaceMargin`` -parameters only if the top-cell has an empty abutment box. If the top-cell abutment -box has to be set, then it is propagated to all the instances models recursively. - - -|noindent| -**Reseting the Placement** - -Once a placement has been done, the placer cannot reset it (will be implemented -later). To perform a new placement, you must restart |cgt|. In addition, if you -have saved the placement on disk, you must erase any :cb:`.ap` file, which are -automatically reloaded along with the netlist (:cb:`.vst`). - -|noindent| -**Limitations** - -Etesian supports standard cells and fixed macros. As for the Coriolis 2.1 version, -it doesn't support movable macros, and you must place every macro beforehand. -Timing and routability analysis are not included either, and the returned placement -may be unroutable. - -|newpage| - - -Etesian Configuration Parameters --------------------------------- - -+-----------------------------------+------------------+----------------------------+ -| Parameter Identifier | Type | Default | -+===================================+==================+============================+ -| **Etesian Parameters** | -+-----------------------------------+------------------+----------------------------+ -|``etesian.aspectRatio`` | TypePercentage | :cb:`100` | -| +------------------+----------------------------+ -| | Define the height on width ``H/W`` aspect | -| | ratio, can be comprised between 10 and 1000 | -+-----------------------------------+------------------+----------------------------+ -|``etesian.spaceMargin`` | TypePercentage | :cb:`5` | -| +------------------+----------------------------+ -| | The extra white space added to the total area | -| | of the standard cells | -+-----------------------------------+------------------+----------------------------+ -|``etesian.uniformDensity`` | TypeBool | :cb:`False` | -| +------------------+----------------------------+ -| | Whether the cells will be spread envenly | -| | across the area or allowed to form denser | -| | clusters | -+-----------------------------------+------------------+----------------------------+ -|``etesian.effort`` | TypeInt | :cb:`2` | -| +------------------+----------------------------+ -| | Sets the balance between the speed of the | -| | placer and the solution quality | -+-----------------------------------+------------------+----------------------------+ -|``etesian.routingDriven`` | TypeBool | :cb:`False` | -| +------------------+----------------------------+ -| | Whether the tool will try routing iterations | -| | and whitespace allocation to improve | -| | routability; to be implemented | -+-----------------------------------+------------------+----------------------------+ -|``etesian.graphics`` | TypeInt | :cb:`2` | -| +------------------+----------------------------+ -| | How often the display will be refreshed | -| | More refreshing slows the placer. | -| | | -| | * ``1`` shows both upper and lower bounds | -| | * ``2`` only shows lower bound results | -| | * ``3`` only shows the final results | -+-----------------------------------+-----------------------------------------------+ - - -Knik -- Global Router -~~~~~~~~~~~~~~~~~~~~~ - -The quality of |Knik| global routing solutions are equivalent to those of FGR_ 1.0. -For an in-depth description of |Knik| algorithms, you may download the thesis of -D. |Dupuis| avalaible from here~: `Knik Thesis`_. - -The global router is (not yet) deterministic. To circumvent this limitation, -a global routing *solution* can be saved to disk and reloaded for later uses. - -A global routing is saved into a file with the same name as the design and a -|kgr| extention. It is in `Box Router`_ output format. - -|noindent| Menus: - -* |menu_P&R| |rightarrow| |menu_StepByStep| |rightarrow| |menu_KiteSaveGlobalRouting|. -* |menu_P&R| |rightarrow| |menu_StepByStep| |rightarrow| |menu_KiteLoadGlobalRouting|. - - -Kite -- Detailed Router -~~~~~~~~~~~~~~~~~~~~~~~ - -|Kite| no longer suffers from the limitations of |Nero|. It can route big designs -as its runtime and memory footprint is almost linear (with respect to the number -of gates). It has successfully routed design of more than `150K` gates. -|medskip| - -|noindent| However, this first release comes with the temporary the following -restrictions: - -* Works only with |SxLib| standard cell gauge. -* Works always with 4 routing metal layers (`M2` through `M5`). -* Do not allow (take into account) pre-routed wires on signals - other than |POWER| or |GROUND|. - -.. note:: - **Slow Layer Assignment.** Most of the time, the layer assignment stage is - fast (less than a dozen seconds), but in some instances it can take more - than a dozen *minutes*. This is a known bug and will be corrected in later - releases. - -After each run, |Kite| displays a set of *completion ratios* which must all -be equal to `100%` if the detailed routing has been successfull. -In the event of a failure, on a saturated design, you may decrease the -`edge saturation ratio` (argument `--edge`) to balance more evenly the design -saturation. That is, the maximum saturation decrease at the price of a wider -saturated area and increased wirelength. This is the saturation of the -*global* router |Knik|, and you may increase/decrease by steps of ``5%``, -which represent one track. The maximum capacity of the |SxLib| gauge is -10 tracks in two layers, that makes 20 tracks by |Knik| edge. - -Routing a design is done in four ordered steps: - -#. Detailed pre-route |menu_P&R| |rightarrow| |menu_StepByStep| |rightarrow| |menu_KiteDetailedPreRoute|. -#. Global routing |menu_P&R| |rightarrow| |menu_StepByStep| |rightarrow| |menu_KiteGlobalRoute|. -#. Detailed routing |menu_P&R| |rightarrow| |menu_StepByStep| |rightarrow| |menu_KiteDetailedRoute|. -#. Finalize routing |menu_P&R| |rightarrow| |menu_StepByStep| |rightarrow| |menu_KiteFinalizeRoute|. - -It is possible to supply to the router a complete wiring for some nets that the user's -wants to be routed according to a specific topology. The supplied topology must respect -the building rules of the |Katabatic| database (contacts must be, terminals, turns, h-tee -& v-tee only). During the first step :fboxtt:`Detailed Pre-Route` the router will solve -overlaps between the segments, without making any dogleg. If no pre-routed topologies -are present, this step may be ommited. Any net routed at this step is then fixed and -become unmovable for the later stages. - -After the detailed routing step the |Kite| data-structure is still active -(the Hurricane wiring is decorated). The finalize step performs the removal of -the |Kite| data-structure, and it is not advisable to save the design before -that step. - -You may visualize the density (saturation) of either |Knik| (on edges) or -|Kite| (on GCells) until the routing is finalized. Special layers appears -to that effect in the `The Layers&Go Tab`_. - - -Kite Configuration Parameters ------------------------------ - -As |Knik| is only called through |Kite|, it's parameters also have -the :cb:`kite.` prefix. - -The |Katabatic| parameters control the layer assignment step. - -All the defaults value given below are from the default |Alliance| technology -(:cb:`cmos` and :cb:`SxLib` cell gauge/routing gauge). - -+-----------------------------------+------------------+----------------------------+ -| Parameter Identifier | Type | Default | -+===================================+==================+============================+ -| **Katabatic Parameters** | -+-----------------------------------+------------------+----------------------------+ -|``katabatic.topRoutingLayer`` | TypeString | :cb:`METAL5` | -| +------------------+----------------------------+ -| | Define the highest metal layer that will be | -| | used for routing (inclusive). | -+-----------------------------------+------------------+----------------------------+ -|``katabatic.globalLengthThreshold``| TypeInt | :cb:`1450` | -| +------------------+----------------------------+ -| | This parameter is used by a layer assignment | -| | method which is no longer used (did not give | -| | good results) | -+-----------------------------------+------------------+----------------------------+ -| ``katabatic.saturateRatio`` | TypePercentage | :cb:`80` | -| +------------------+----------------------------+ -| | If ``M(x)`` density is above this ratio, | -| | move up feedthru global segments up from | -| | depth ``x`` to ``x+2`` | -+-----------------------------------+------------------+----------------------------+ -| ``katabatic.saturateRp`` | TypeInt | :cb:`8` | -| +------------------+----------------------------+ -| | If a GCell contains more terminals | -| | (:cb:`RoutingPad`) than that number, force a | -| | move up of the connecting segments to those | -| | in excess | -+-----------------------------------+------------------+----------------------------+ -| **Knik Parameters** | -+-----------------------------------+------------------+----------------------------+ -| ``kite.hTracksReservedLocal`` | TypeInt | :cb:`3` | -| +------------------+----------------------------+ -| | To take account the tracks needed *inside* a | -| | GCell to build the *local* routing, decrease | -| | the capacity of the edges of the global | -| | router. Horizontal and vertical locally | -| | reserved capacity can be distinguished for | -| | more accuracy. | -+-----------------------------------+------------------+----------------------------+ -| ``kite.vTracksReservedLocal`` | TypeInt | :cb:`3` | -| +------------------+----------------------------+ -| | cf. ``kite.hTracksReservedLocal`` | -+-----------------------------------+------------------+----------------------------+ -| **Kite Parameters** | -+-----------------------------------+------------------+----------------------------+ -| ``kite.eventsLimit`` | TypeInt | :cb:`4000002` | -| +------------------+----------------------------+ -| | The maximum number of segment displacements, | -| | this is a last ditch safety against infinite | -| | loop. It's perhaps a little too low for big | -| | designs | -+-----------------------------------+------------------+----------------------------+ -| ``kite.ripupCost`` | TypeInt | :cb:`3` | -| +------------------+----------------------------+ -| | Differential introduced between two ripup | -| | cost to avoid a loop between two ripped up | -| | segments | -+-----------------------------------+------------------+----------------------------+ -| ``kite.strapRipupLimit`` | TypeInt | :cb:`16` | -| +------------------+----------------------------+ -| | Maximum number of ripup for *strap* segments | -+-----------------------------------+------------------+----------------------------+ -| ``kite.localRipupLimit`` | TypeInt | :cb:`9` | -| +------------------+----------------------------+ -| | Maximum number of ripup for *local* segments | -+-----------------------------------+------------------+----------------------------+ -| ``kite.globalRipupLimit`` | TypeInt | :cb:`5` | -| +------------------+----------------------------+ -| | Maximum number of ripup for *global* segments,| -| | when this limit is reached, triggers topologic| -| | modification | -+-----------------------------------+------------------+----------------------------+ -| ``kite.longGlobalRipupLimit`` | TypeInt | :cb:`5` | -| +------------------+----------------------------+ -| | Maximum number of ripup for *long global* | -| | segments, when this limit is reached, triggers| -| | topological modification | -+-----------------------------------+------------------+----------------------------+ - - - -.. _Python Scripts in Cgt: - -Executing Python Scripts in Cgt -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Python/Stratus scripts can be executed either in text or graphical mode. - -.. note:: **How Cgt Locates Python Scripts:** - |cgt| uses the Python ``import`` mechanism to load Python scripts. - So you must give the name of your script whitout ``.py`` extention and - it must be reachable through the ``PYTHONPATH``. You may uses the - dotted module notation. - -A Python/Stratus script must contains a function called ``ScriptMain()`` -with one optional argument, the graphical editor into which it may be -running (will be set to ``None`` in text mode). The Python interface to -the editor (type: :cb:`CellViewer`) is limited to basic capabilities -only. - -Any script given on the command line will be run immediatly *after* the -initializations and *before* any other argument is processed. - -For more explanation on Python scripts see `Python Interface to Coriolis`_. - - -Printing & Snapshots -~~~~~~~~~~~~~~~~~~~~ - -Printing or saving into a |pdf| is fairly simple, just uses the **File -> Print** -menu or the |CTRL_P| shortcut to open the dialog box. - -The print functionality uses exactly the same rendering mechanism as for the -screen, beeing almost *WYSIWYG*. Thus, to obtain the best results it is advisable -to select the ``Coriolis.Printer`` look (in the *Controller*), which uses a -white background and much suited for high resolutions ``32x32`` pixels patterns - -There is also two mode of printing selectable through the *Controller* -**Settings -> Misc -> Printer/Snapshot Mode**: - -=============== ================= ===================================================== -Mode DPI (approx.) Intended Usage ---------------- ----------------- ----------------------------------------------------- -**Cell Mode** 150 For single ``Cell`` printing or very small designs. - Patterns will be bigger and more readable. -**Design Mode** 300 For designs (mostly commposed of wires and cells - outlines). -=============== ================= ===================================================== - -.. note:: *The pdf file size* - Be aware that the generated |pdf| files are indeed only pixmaps. - So they can grew very large if you select paper format above ``A2`` - or similar. - - -|noindent| -Saving into an image is subject to the same remarks as for |pdf|. - - -Memento of Shortcuts in Graphic Mode -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The main application binary is |cgt|. - -+---------------+-------------------+-----------------------------------------------------------+ -| Category | Keys | Action | -+===============+===================+===========================================================+ -| **Moves** | | |KeyUp|, | Shift the view in the according direction | -| | |KeyDown| | | -| | | |KeyLeft|, | | -| | |KeyRight| | | -+---------------+-------------------+-----------------------------------------------------------+ -| **Fit** | |KeyF| | Fit to the Cell abutment box | -+---------------+-------------------+-----------------------------------------------------------+ -| **Refresh** | |CTRL_L| | Triggers a complete display redraw | -+---------------+-------------------+-----------------------------------------------------------+ -| **Goto** | |KeyG| | *apperture* is the minimum side of the area | -| | | displayed around the point to go to. It's an | -| | | alternative way of setting the zoom level | -+---------------+-------------------+-----------------------------------------------------------+ -| **Zoom** | |KeyZ|, | Respectively zoom by a 2 factor and *unzoom* | -| | |KeyM| | by a 2 factor | -| +-------------------+-----------------------------------------------------------+ -| | | |BigMouse| | You can perform a zoom to an area. | -| | | Area Zoom | Define the zoom area by *holding down the left | -| | | mouse button* while moving the mouse. | -+---------------+-------------------+-----------------------------------------------------------+ -| **Selection** | | |BigMouse| | You can select displayed objects under an area. | -| | | Area Selection | Define the selection area by *holding down the | -| | | right mouse button* while moving the mouse. | -| +-------------------+-----------------------------------------------------------+ -| | | |BigMouse| | You can toggle the selection of one object under | -| | | Toggle Selection| the mouse position by pressing |CTRL| and | -| | | pressing down *the right mouse button*. A popup | -| | | list of what's under the position shows up into | -| | | which you can toggle the selection state of one | -| | | item. | -| +-------------------+-----------------------------------------------------------+ -| | |KeyCapS| | Toggle the selection visibility | -+---------------+-------------------+-----------------------------------------------------------+ -| **Controller**| |CTRL_I| | Show/hide the controller window. | -| | | | -| | | It's the Swiss Army Knife of the viewer. | -| | | From it, you can fine-control the display and | -| | | inspect almost everything in your design. | -+---------------+-------------------+-----------------------------------------------------------+ -| **Rulers** | |KeyK|, | One stroke on |KeyK| enters the ruler mode, in | -| | |KeyESC| | which you can draw one ruler. You can exit the | -| | | ruler mode by pressing |KeyESC|. Once in ruler | -| | | mode, the first click on the *left mouse button* | -| | | sets the ruler's starting point and the second | -| | | click the ruler's end point. The second click | -| | | exits automatically the ruler mode. | -| +-------------------+-----------------------------------------------------------+ -| | |KeyCapK| | Clears all the drawn rulers | -+---------------+-------------------+-----------------------------------------------------------+ -| **Print** | |CTRL_P| | Currently rather crude. It's a direct copy of | -| | | what's displayed in pixels. So the resulting | -| | | picture will be a little blurred due to | -| | | anti-aliasing mechanism. | -+---------------+-------------------+-----------------------------------------------------------+ -| **Open/Close**| |CTRL_O| | Opens a new design. The design name must be | -| | | given without path or extention. | -| +-------------------+-----------------------------------------------------------+ -| | |CTRL_W| | Close the current viewer window, but do not quit | -| | | the application. | -| +-------------------+-----------------------------------------------------------+ -| | |CTRL_Q| | `CTRL+Q` quit the application | -| | | (closing all windows). | -+---------------+-------------------+-----------------------------------------------------------+ -| **Hierarchy** | |CTRL_Down| | Go one hierarchy level down. That is, if there | -| | | is an *instance* under the cursor position, load | -| | | it's *model* Cell in place of the current one. | -| +-------------------+-----------------------------------------------------------+ -| | |CTRL_Up| | Go one hierarchy level up. if we have entered | -| | | the current model through |CTRL_Down| | -| | | reload the previous model (the one | -| | | in which this model is instanciated). | -+---------------+-------------------+-----------------------------------------------------------+ - - -Cgt Command Line Options -~~~~~~~~~~~~~~~~~~~~~~~~ - -Appart from the obvious ``--text`` options, all can be used for text and graphical mode. - -+-----------------------------+------------------------------------------------+ -| Arguments | Meaning | -+=============================+================================================+ -| `-t|--text` | Instruct |cgt| to run in text mode. | -+-----------------------------+------------------------------------------------+ -| `-L|--log-mode` | Disable the uses of |ANSI| escape sequence on | -| | the |tty|. Useful when the output is | -| | redirected to a file. | -+-----------------------------+------------------------------------------------+ -| `-c |--cell=` | The name of the design to load, without | -| | leading path or extention. | -+-----------------------------+------------------------------------------------+ -| `-g|--load-global` | Reload a global routing solution from disk. | -| | The file containing the solution must be named | -| | `.kgr`. | -+-----------------------------+------------------------------------------------+ -| `--save-global` | Save the global routing solution, into a file | -| | named `.kgr`. | -+-----------------------------+------------------------------------------------+ -| `-e |--edge=` | Change the edge capacity for the global | -| | router, between 0 and 1 (|Knik|). | -+-----------------------------+------------------------------------------------+ -| `-G|--global-route` | Run the global router (|Knik|). | -+-----------------------------+------------------------------------------------+ -| `-R|--detailed-route` | Run the detailed router (|Kite|). | -+-----------------------------+------------------------------------------------+ -| `-s|--save-design=` | The design into which the routed layout will | -| | be saved. It is strongly recommanded to choose | -| | a different name from the source (unrouted) | -| | design. | -+-----------------------------+------------------------------------------------+ -| `--events-limit=` | The maximal number of events after which the | -| | router will stops. This is mainly a failsafe | -| | against looping. The limit is sets to 4 | -| | millions of iteration which should suffice to | -| | any design of `100K`. gates. For bigger | -| | designs you may wants to increase this limit. | -+-----------------------------+------------------------------------------------+ -| `--stratus-script=` | Run the Python/Stratus script ``module``. | -| | See `Python Scripts in Cgt`_. | -+-----------------------------+------------------------------------------------+ - - -Some Examples : - -* Run both global and detailed router, then save the routed design : :: - - > cgt -v -t -G -R --cell=design --save-design=design_kite - -* Load a previous global solution, run the detailed router, then save the - routed design : :: - - > cgt -v -t --load-global -R --cell=design --save-design=design_kite - -* Run the global router, then save the global routing solution : :: - - > cgt -v -t -G --save-global --cell=design - - -Miscellaneous Settings -~~~~~~~~~~~~~~~~~~~~~~ - -+---------------------------------------+------------------+----------------------------+ -| Parameter Identifier | Type | Default | -+=======================================+==================+============================+ -| **Verbosity/Log Parameters** | -+---------------------------------------+------------------+----------------------------+ -| ``misc.info`` | TypeBool | :cb:`False` | -| +------------------+----------------------------+ -| | Enable display of *info* level message | -| | (:cb:`cinfo` stream) | -+---------------------------------------+------------------+----------------------------+ -| ``misc.bug`` | TypeBool | :cb:`False` | -| +------------------+----------------------------+ -| | Enable display of *bug* level message | -| | (:cb:`cbug` stream), messages can be a little | -| | scarry | -+---------------------------------------+------------------+----------------------------+ -| ``misc.logMode`` | TypeBool | :cb:`False` | -| +------------------+----------------------------+ -| | If enabled, assume that the output device | -| | is not a ``tty`` and suppress any escaped | -| | sequences | -+---------------------------------------+------------------+----------------------------+ -| ``misc.verboseLevel1`` | TypeBool | :cb:`True` | -| +------------------+----------------------------+ -| | First level of verbosity, disable level 2 | -+---------------------------------------+------------------+----------------------------+ -| ``misc.verboseLevel2`` | TypeBool | :cb:`False` | -| +------------------+----------------------------+ -| | Second level of verbosity | -+---------------------------------------+------------------+----------------------------+ -| **Development/Debug Parameters** | -+---------------------------------------+------------------+----------------------------+ -| ``misc.minTraceLevel`` | TypeInt | :cb:`0` | -+---------------------------------------+------------------+----------------------------+ -| ``misc.maxTraceLevel`` | TypeInt | :cb:`0` | -| +------------------+----------------------------+ -| | Display trace information *between* those two | -| | levels (:cb:`cdebug` stream) | -+---------------------------------------+------------------+----------------------------+ -| ``misc.catchCore`` | TypeBool | :cb:`False` | -| +------------------+----------------------------+ -| | By default, |cgt| do not dump core. | -| | To generate one set this flag to :cb:`True` | -+---------------------------------------+------------------+----------------------------+ - -|newpage| - - -.. _The Controller: - -The Controller -============== - -The *Controller* window is composed of seven tabs: - -#. `The Look Tab`_ to select the display style. -#. `The Filter Tab`_ the hierarchical levels to be displayed, the look of - rubbers and the dimension units. -#. `The Layers&Go Tab`_ to selectively hide/display layers. -#. `The Netlist Tab`_ to browse through the |netlist|. Works in association - with the *Selection* tab. -#. `The Selection Tab`_ allow to view all the currently selected elements. -#. `The Inspector Tab`_ browse through either the DataBase, the Cell or - the current selection. -#. `The Settings Tab`_ access all the tool's configuration settings. - - -.. _The Look Tab: - -The Look Tab -~~~~~~~~~~~~ - -You can select how the layout will be displayed. There is a special one -``Printer.Coriolis`` specifically designed for `Printing & Snapshots`_. -You should select it prior to calling the print or snapshot dialog boxes. - -|ControllerLook_1| - - -.. _The Filter Tab: - -The Filter Tab -~~~~~~~~~~~~~~ - -The filter tab let you select what hierarchical levels of your design will be -displayed. Hierarchy level are numbered top-down: the level 0 correspond to -the top-level cell, the level one to the instances of the top-level Cell and -so on. - -There are also check boxes to enable/disable the processing of Terminal Cell, -Master Cells and Compnents. The processing of Terminal Cell (hierarchy leaf -cells) is disabled by default when you load a hierarchical design and enabled -when you load a single Cell. - -You can choose what kind of form to give to the rubbers and the type of -unit used to display coordinates. - -.. note:: *What are Rubbers:* |Hurricane| uses *Rubbers* to materialize - physical gaps in net topology. That is, if some wires are missing to - connect two or more parts of net, a *rubber* will be drawn between them - to signal the gap. - - For example, after the detailed routing no *rubbers* should remains. - They have been made *very* visibles as big violet lines... - -|ControllerFilter_1| - - -.. _The Layers&Go Tab: - -The Layers&Go Tab -~~~~~~~~~~~~~~~~~ - -Control the individual display of all *layers* and *Gos*. - -* *Layers* correspond to a true physical layer. From a |Hurricane| point of - view they are all the *BasicLayers* (could be matched to GDSII). -* *Gos* stands from *Graphical Objects*, they are drawings that have no - physical existence but are added by the various tools to display extra - information. One good exemple is the density map of the detailed router, - to easily locate congested areas. - -For each layer/Go there are two check boxes: - -* The normal one triggers the display. -* The red-outlined allows objects of that layer to be selectable or not. - -|ControllerLayersGos_1| - - -.. _The Netlist Tab: - -The Netlist Tab -~~~~~~~~~~~~~~~ - -The *Netlist* tab shows the list of nets... By default the tab is not -*synched* with the displayed Cell. To see the nets you must check the -**Sync Netlist** checkbox. You can narrow the set of displayed nets by -using the filter pattern (supports regular expressions). - -An very useful feature is to enable the **Sync Selection**, which will -automatically select all the components of the selected net(s). You can -select multiple nets. In the figure the net ``auxsc35`` is selected and -is highlited in the *Viewer*. - -|ControllerNetlist_1| -|ViewerNetlist_1| - - -.. _The Selection Tab: - -The Selection Tab -~~~~~~~~~~~~~~~~~ - -The *Selection* tab list all the components currently selecteds. They -can be filtered thanks to the filter pattern. - -Used in conjunction with the *Netlist* **Sync Selection** you will all see -all the components part of *net*. - -In this list, you can toggle individually the selection of component by -pressing the ``t`` key. When unselected in this way a component is not -removed from the the selection list but instead displayed in red italic. -To see where a component is you may make it blink by repeatedly press -the ``t`` key... - -|ControllerSelection_1| - - -.. _The Inspector Tab: - -The Inspector Tab -~~~~~~~~~~~~~~~~~ - -This tab is very useful, but mostly for |Coriolis| developpers. It allows -to browse through the live DataBase. The *Inspector* provide three entry points: - -* **DataBase**: Starts from the whole |Hurricane| DataBase. -* **Cell**: Inspect the currently loaded Cell. -* **Selection**: Inspect the object currently highlited in the *Selection* tab. - -Once an entry point has been activated, you may recursively expore all -it's fields using the right/left arrows. - -.. note:: *Do not put your fingers in the socket:* when inspecting - anything, do not modify the DataBase. If any object under inspection - is deleted, you will crash the application... - -.. note:: *Implementation Detail:* the inspector support is done with - ``Slot``, ``Record`` and ``getString()``. - -|ControllerInspector_1| -|ControllerInspector_2| -|ControllerInspector_3| - - -.. _The Settings Tab: - -The Settings Tab -~~~~~~~~~~~~~~~~ - -Here comes the description of the *Settings* tab. - -|ControllerSettings_1| - - -.. _Python Interface to Coriolis: - -Python Interface for |Hurricane| / |Coriolis| -============================================= - -The (almost) complete interface of |Hurricane| is exported as a |Python| module -and some part of the other components of |Coriolis| (each one in a separate -module). The interface has been made to mirror as closely as possible the -C++ one, so the C++ doxygen documentation could be used to write code with -either languages. - -`Summary of the C++ Documentation `_ - -A script could be run directly in text mode from the command line or through -the graphical interface (see `Python Scripts in Cgt`_). - -Asides for this requirement, the python script can contain anything valid -in |Python|, so don't hesitate to use any package or extention. - -Small example of Python/Stratus script: :: - - from Hurricane import * - from Stratus import * - - def doSomething (): - # ... - return - - def ScriptMain ( **kw ): - editor = None - if kw.has_key('editor') and kw['editor']: - editor = kw['editor'] - stratus.setEditor( editor ) - - doSomething() - return - - if __name__ == "__main__" : - kw = {} - success = ScriptMain( **kw ) - shellSuccess = 0 - if not success: shellSuccess = 1 - - sys.exit( shellSuccess ) - ScriptMain () - -This typical script can be executed in two ways: - -#. Run directly as a |Python| script, thanks to the :: - - if __name__ == "__main__" : - - part (this is standart |Python|). It is a simple adapter that will - calls :cb:`ScriptMain()`. -#. Through |cgt|, either in text or graphical mode. In that case, the - :cb:`ScriptMain()` is directly called trough a sub-interpreter. - The arguments of the script are passed through the ``**kw`` dictionnary. - - +----------------------+-----------------------------------------------+ - | \*\*kw Dictionnary | - +----------------------+-----------------------------------------------+ - | Parameter Key/Name | Contents type | - +======================+===============================================+ - | ``'cell'`` | A Hurricane cell on which to work. Depending | - | | on the context, it may be ``None``. | - | | For example, when run from |cgt|, it the cell | - | | currently loaded in the viewer, if any. | - +----------------------+-----------------------------------------------+ - | ``'editor'`` | The viewer from which the script is run, when | - | | lauched through |cgt|. | - +----------------------+-----------------------------------------------+ - - -Plugins -======= - -Plugins are |Python| scripts specially crafted to integrate with |cgt|. -Their entry point is a :cb:`ScriptMain()` method as described in -`Python Interface to Coriolis`_. They can be called by user scripts -through this method. - - - -Chip Placement -~~~~~~~~~~~~~~ - -Automatically perform the placement of a complete chip. This plugin, as well -as the other P&R tools expect a specific top-level hierarchy for the design. -The top-level hierarchy must contains the instances of all the I/O pads and -**exactly one** instance of the chip's core model. - -|ChipStructure-1| - -The designer must provide a configuration file that define the rules for the -placement of the top-level hierarchy (that is, the pads and the core). -This file must be named after the chip's name, by appending ``_chip.py`` -(obviously, it is a |Python| file). For instance if the chip netlist file -is called ``amd2901_crl.vst``, then the configuration file must be named -``amd2901_crl_chip.vst``. - -Example of chip placement configuration file (for ``AM2901``): :: - - chip = \ - { 'pads.south' : [ 'p_a3' , 'p_a2' , 'p_a1' , 'p_r0' - , 'p_vddick0', 'p_vssick0', 'p_a0' , 'p_i6' - , 'p_i8' , 'p_i7' , 'p_r3' ] - , 'pads.east' : [ 'p_zero' , 'p_i0' , 'p_i1' , 'p_i2' - , 'p_vddeck0', 'p_vsseck0', 'p_q3' , 'p_b0' - , 'p_b1' , 'p_b2' , 'p_b3' ] - , 'pads.north' : [ 'p_noe' , 'p_y3' , 'p_y2' , 'p_y1' - , 'p_y0' , 'p_vddeck1', 'p_vsseck1', 'p_np' - , 'p_ovr' , 'p_cout' , 'p_ng' ] - , 'pads.west' : [ 'p_cin' , 'p_i4' , 'p_i5' , 'p_i3' - , 'p_ck' , 'p_d0' , 'p_d1' , 'p_d2' - , 'p_d3' , 'p_q0' , 'p_f3' ] - , 'core.size' : ( 1500, 1500 ) - , 'chip.size' : ( 3000, 3000 ) - , 'chip.clockTree' : True - } - -The file must contain *one dictionnary* named ``chip``. - -+----------------------+-------------------------------------------------------+ -| Chip Dictionnary | -+----------------------+-------------------------------------------------------+ -| Parameter Key/Name | Value/Contents type | -+======================+=======================================================+ -| ``'pad.south'`` | Ordered list (left to right) of pad instances names | -| | to put on the south side of the chip | -+----------------------+-------------------------------------------------------+ -| ``'pad.east'`` | Ordered list (down to up) of pad instances names | -| | to put on the east side of the chip | -+----------------------+-------------------------------------------------------+ -| ``'pad.north'`` | Ordered list (left to right) of pad instances names | -| | to put on the north side of the chip | -+----------------------+-------------------------------------------------------+ -| ``'pad.west'`` | Ordered list (down to up) of pad instances names | -| | to put on the west side of the chip | -+----------------------+-------------------------------------------------------+ -| ``'core.size'`` | The size of the core (to be used by the placer) | -+----------------------+-------------------------------------------------------+ -| ``'chip.size'`` | The size of the whole chip. The sides must be great | -| | enough to accomodate all the pads | -+----------------------+-------------------------------------------------------+ -| ``'chip.clockTree'`` | Whether to generate a clock tree or not. This calls | -| | the ClockTree plugin | -+----------------------+-------------------------------------------------------+ - -Configuration parameters, defaults are defined in ``etc/coriolis2//plugins.conf``. - -+-----------------------------------+------------------+----------------------------+ -| Parameter Identifier | Type | Default | -+===================================+==================+============================+ -| **Chip Plugin Parameters** | -+-----------------------------------+------------------+----------------------------+ -|``chip.block.rails.count`` | TypeInt | :cb:`5` | -| +------------------+----------------------------+ -| | The minimum number of rails around the core | -| | block. Must be odd and suppérior to 5. | -| | One rail for the clock and at least two pairs | -| | of power/grounds | -+-----------------------------------+------------------+----------------------------+ -|``chip.block.rails.hWidth`` | TypeInt | :cb:`12` | -| +------------------+----------------------------+ -| | The horizontal with of the rails | -+-----------------------------------+------------------+----------------------------+ -|``chip.block.rails.vWidth`` | TypeInt | :cb:`12` | -| +------------------+----------------------------+ -| | The vertical with of the rails | -+-----------------------------------+------------------+----------------------------+ -|``chip.block.rails.hSpacing`` | TypeInt | :cb:`6` | -| +------------------+----------------------------+ -| | The spacing, *edge to edge* of two adjacent | -| | horizontal rails | -+-----------------------------------+------------------+----------------------------+ -|``chip.block.rails.vSpacing`` | TypeInt | :cb:`6` | -| +------------------+----------------------------+ -| | The spacing, *edge to edge* of two adjacent | -| | vertical rails | -+-----------------------------------+------------------+----------------------------+ -|``chip.pad.pck`` | TypeString | :cb:`pck_px` | -| +------------------+----------------------------+ -| | The model name of the pad connected to the | -| | chip external clock | -+-----------------------------------+------------------+----------------------------+ -|``chip.pad.pvddeck`` | TypeString | :cb:`pvddeck_px` | -| +------------------+----------------------------+ -| | The model name of the pad connected to the | -| | ``vdde`` (external power) and suppling it to | -| | the core | -+-----------------------------------+------------------+----------------------------+ -|``chip.pad.pvsseck`` | TypeString | :cb:`pvsseck_px` | -| +------------------+----------------------------+ -| | The model name of the pad connected to the | -| | ``vsse`` (external ground) and suppling it to | -| | the core | -+-----------------------------------+------------------+----------------------------+ -|``chip.pad.pvddick`` | TypeString | :cb:`pvddick_px` | -| +------------------+----------------------------+ -| | The model name of the pad connected to the | -| | ``vddi`` (internal power) and suppling it to | -| | the core | -+-----------------------------------+------------------+----------------------------+ -|``chip.pad.pvssick`` | TypeString | :cb:`pvssick_px` | -| +------------------+----------------------------+ -| | The model name of the pad connected to the | -| | ``vssi`` (internal ground) and suppling it to | -| | the core | -+-----------------------------------+------------------+----------------------------+ - -.. note:: - If no clock tree is generated, then the clock rail is *not* created. - So even if the requested number of rails ``chip.block.rails.count`` is, say 5, - only four rails (2* ``power``, 2* ``ground``) will be generateds. - - -Clock Tree -~~~~~~~~~~ - -Insert a clock tree into a block. The clock tree uses the H strategy. -The clock net is splitted into sub-nets, one for each branch of the -tree. - -* On **chips** design, the sub-nets are createds in the model of the - core block (then trans-hierarchically flattened to be shown at - chip level). -* On **blocks**, the sub nets are created directly in the top block. -* The sub-nets are named according to a simple geometrical scheme. - A common prefix ``ck_htree``, then one postfix by level telling - on which quarter of plane the sub-clock is located: - - #. ``_bl``: bottom left plane quarter. - #. ``_br``: bottom right plane quarter. - #. ``_tl``: top left plane quarter. - #. ``_tr``: top right plane quarter. - - We can have ``ck_htree_bl``, ``ck_htree_bl_bl``, ``ch_htree_bl_tl`` and so on. - -The clock tree plugin works in four steps: - -#. Build the clock tree: creates the top-block abutment box, compute the - levels of H tree neededs and place the clock buffers. -#. Once the clock buffers are placed, calls the placer (|etesian|) to place - the ordinary standart cells, whithout disturbing clock H-tree buffers. -#. At this point we know the exact positions of all the DFFs, so we can - connect them to the nearest H-tree leaf clock signal. -#. Leaf clock signals that are not connecteds to any DFFs are removed. - -Netlist reorganisation: - -* Obviously the top block or chip core model netlist is modificated to - contains all the clock sub-nets. The interface is *not* changed. -* If the top block contains instances of other models *and* those models - contains DFFs that get re-connecteds to the clock sub-nets (from the - top level). Change both the model netlist and interface to propagate - the relevant clock sub-nets to the instanciated model. The new model - with the added clock signal is renamed with a ``_clocked`` suffix. - For example, the sub-block model ``ram.vst`` will become ``ram_clocked.vst``. - -.. note:: - If you are to re-run the clock tree plugin on a netlist, be careful - to erase any previously generated ``_clocked`` file (both netlist and - layout: ``rm *.clocked.{ap,vst}``). And restart |cgt| to clear it's - memory cache. - -Configuration parameters, defaults are defined in ``etc/coriolis2//plugins.conf``. - -+-----------------------------------+------------------+----------------------------+ -| Parameter Identifier | Type | Default | -+===================================+==================+============================+ -| **ClockTree Plugin Parameters** | -+-----------------------------------+------------------+----------------------------+ -|``clockTree.minimumSide`` | TypeInt | :cb:`300` | -| +------------------+----------------------------+ -| | The minimum size below which the clock tree | -| | will stop to perform quadri-partitions | -+-----------------------------------+------------------+----------------------------+ -|``clockTree.buffer`` | TypeString | :cb:`buf_x2` | -| +------------------+----------------------------+ -| | The buffer model to use to drive sub-nets | -+-----------------------------------+------------------+----------------------------+ -|``clockTree.placerEngine`` | TypeString | :cb:`Etesian` | -| +------------------+----------------------------+ -| | The placer to use. Other value is ``Mauka`` | -| | the simulated annealing placer which will go | -| | into retirement very soon | -+-----------------------------------+------------------+----------------------------+ - - -Recursive-Save (RSave) -~~~~~~~~~~~~~~~~~~~~~~ - -Perform a recursive top down save of all the models from the top cell -loaded in |cgt|. Force a write of any non-terminal model. This plugin is used -by the clock tree plugin after the netlist clock sub-nets creation. - - -A Simple Example: AM2901 -======================== - -To illustrate the capabilities of |Coriolis| tools and |Python| scripting, a small -example, derived from the |Alliance| :cb:`AM2901` is supplied. - -This example contains only the synthetized netlists and the :cb:`doChip.py` script -which perform the whole P&R of the design. - -You can generate the chip using one of the following method: - -#. **Command line mode:** directly run the script: :: - - dummy@lepka:AM2901$ ./doChip -V --cell=amd2901 - -#. **Graphic mode:** launch |cgt|, load chip netlist ``amd2901`` (the top cell) - then run the |Python| script :cb:`doChip.py`. - -.. note:: - Between two consecutive run, be sure to erase the netlist/layout generateds: :: - - dummy@lepka:AM2901$ rm *_clocked*.vst *.ap diff --git a/documentation/UsersGuide/UsersGuide_HTML.rst b/documentation/UsersGuide/UsersGuide_HTML.rst deleted file mode 100644 index 1bb507b5..00000000 --- a/documentation/UsersGuide/UsersGuide_HTML.rst +++ /dev/null @@ -1,5 +0,0 @@ - -.. -*- Mode: rst -*- - -.. include:: HTML_defs.rst -.. include:: UsersGuide.rst diff --git a/documentation/UsersGuide/UsersGuide_LaTeX.rst b/documentation/UsersGuide/UsersGuide_LaTeX.rst deleted file mode 100644 index 0c6ed943..00000000 --- a/documentation/UsersGuide/UsersGuide_LaTeX.rst +++ /dev/null @@ -1,5 +0,0 @@ - -.. -*- Mode: rst -*- - -.. include:: LaTeX_defs.rst -.. include:: UsersGuide.rst diff --git a/documentation/UsersGuide/ViewerTools.rst b/documentation/UsersGuide/ViewerTools.rst new file mode 100644 index 00000000..8313e1df --- /dev/null +++ b/documentation/UsersGuide/ViewerTools.rst @@ -0,0 +1,868 @@ +.. -*- Mode: rst -*- + +.. include:: ../etc/definitions.rst + +.. URLs that changes between the various backends. +.. _Stratus Documentation: file:///usr/share/doc/coriolis2/en/html/stratus/index.html + + +.. |BigMouse| image:: ./images/ComputerMouse.png + :scale: 25% + +.. |ViewerSnapshot_1| image:: ./images/Viewer-1.png + :alt: Viewer Basic Snapshot + :align: middle + :width: 80% + +.. |ControllerSnapshot_1| image:: ./images/Controller-1.png + :alt: Controller Basic Snapshot + :align: middle + :width: 80% + +.. |ControllerLook_1| image:: ./images/Controller-Look-1.png + :alt: Controller Look, Snapshot 1 + :align: middle + :width: 80% + +.. |ControllerFilter_1| image:: ./images/Controller-Filter-1.png + :alt: Controller Basic Snapshot + :align: middle + :width: 80% + +.. |ControllerLayersGos_1| image:: ./images/Controller-LayersGos-1.png + :alt: Controller Basic Snapshot + :align: middle + :width: 80% + +.. |ControllerNetlist_1| image:: ./images/Controller-Netlist-1.png + :alt: Controller Basic Snapshot + :align: middle + :width: 80% + +.. |ViewerNetlist_1| image:: ./images/Viewer-Netlist-1.png + :alt: Controller Basic Snapshot + :align: middle + :width: 80% + +.. |ControllerSelection_1| image:: ./images/Controller-Selection-1.png + :alt: Controller Basic Snapshot + :align: middle + :width: 80% + +.. |ControllerInspector_1| image:: ./images/Controller-Inspector-1.png + :alt: Controller Basic Snapshot + :align: middle + :width: 80% + +.. |ControllerInspector_2| image:: ./images/Controller-Inspector-2.png + :alt: Controller Basic Snapshot + :align: middle + :width: 80% + +.. |ControllerInspector_3| image:: ./images/Controller-Inspector-3.png + :alt: Controller Basic Snapshot + :align: middle + :width: 80% + +.. |ControllerSettings_1| image:: ./images/Controller-Settings-1.png + :alt: Controller Basic Snapshot + :align: middle + :width: 80% + +.. |Etesian-1| image:: ./images/etesian-1.png + :alt: Etesian Abutment Box + :align: middle + :width: 80% + + +CGT - The Graphical Interface +============================= + +The |Coriolis| graphical interface is split up into two windows. + +* The **Viewer**, with the following features: + + * Basic load/save capabilities. + * Display the current working cell. Could be empty if the design + is not yet placed. + * Execute Stratus Scripts. + * Menu to run the tools (placement, routage). + +Features are detailed in `Viewer & Tools`_. + +|ViewerSnapShot_1| + +* The **Controller**, which allows: + + * Tweak what is displayer by the *Viewer*. Through the *Look*, + *Filter* and *Layers&Gos* tabs. + * Browse the |netlist| with eponym tab. + * Show the list of selected objects (if any) with *selection* + * Walk through the Database, the Cell or the Selection with *Inspector*. + This is an advanced feature, reserved for experimented users. + * The tab *Settings* which give access to all the settings. + They are closely related to Configuration & Initialisation. + +|bcenter| |ControllerSnapShot_1| |ecenter| + + +.. _Viewer & Tools: + +Viewer & Tools +~~~~~~~~~~~~~~ + +|Stratus| Netlist Capture +------------------------- + +|Stratus| is the replacement for |GenLib| procedural netlist capture language. +It is designed as a set of |Python| classes, and comes with it's own documentation +(`Stratus Documentation`_) + + +The |Hurricane| Data-Base +------------------------- + +The |Alliance| flow is based on the |MBK| data-base, which has one data-structure +for each view. That is, |LOFIG| for the *logical* view and |PHFIG| for the *physical* +view. The place and route tools were responsible for maintaining (or not) the +coherency between views. Reflecting this weak coupling between views, each one +was stored in a separate file with a specific format. The *logical* view is stored +in a |vst| file in |VHDL| format and the *physical* in an |ap| file in an ad-hoc format. + +The |Coriolis| flow is based on the |Hurricane| data-base, which has a unified +structure for *logical* and *physical* view. That data structure is the |Cell| object. +The |Cell| can have any state between pure netlist and completly placed and +routed design. Although the memory representation of the views has deeply +changed we still use the |Alliance| files format, but they now really represent +views of the same object. The point is that one must be very careful about +view coherency when going to and from |Coriolis|. + +As for the second release, |Coriolis| can be used only for three purposes : + +* **Placing a design**, in which case the |netlist| view must be present. +* **Routing a design**, in that case the |netlist| + view and the |layout| view must be present and |layout| view must contain + a placement. Both views must have the same name. When saving the routed design, + it is advised to change the design name otherwise the original unrouted placement + in the |layout| view will be overwritten. +* **Viewing a design**, the |netlist| view must be present, if a |layout| + view is present it still must have the same name but it can be in any + state. + + +Synthetizing and loading a design +--------------------------------- + +|Coriolis| supports several file formats. It can load all file format +from the |Alliance| toolchain (.ap for layout, behavioural and structural vhdl .vbe and .vst), +BLIF netlist format as well as benchmark formats from the ISPD contests. + +It can be compiled with LEF/DEF support, although it requires acceptance of the SI2 license +and may not be compiled in your version of the software. + +Synthesis under Yosys +..................... + +You can create a BLIF file from the |Yosys| synthetizer, which can be imported under Coriolis. +Most libraries are specified as a .lib liberty file and a .lef LEF file. +|Yosys| opens most .lib files with minor modifications, but LEF support in Coriolis relies on SI2. +If Coriolis hasn't been compiled against it, the library is given in |Alliance| .ap format. +`Some free libraries `_ already provide both .ap and .lib files. + +Once you have installed a common library under |Yosys| and Coriolis, just synthetize your design +with |Yosys| and import it (as Blif without the extension) under Coriolis to perform place&route. + +Synthesis under Alliance +........................ + +|Alliance| is an older toolchain but has been extensively used for years. Coriolis can import +and write Alliance designs and libraries directly. + +Etesian -- Placer +----------------- + +The |Etesian| placer is a state of the art (as of 2015) analytical placer. It is +within ``5%`` of other placers' solutions, but is normally a bit worse than ePlace. +This |Coriolis| tool is actually an encapsulation of |Coloquinte| which *is* the placer. + +.. note:: *Instance Uniquification Unsupported:* a same logical instance cannot have + two different placements. So, either you manually make a clone of it or you + supply a placement for it. We need to implement uniquification in the + |Hurricane| database. + + +|noindent| +**Hierarchical Placement** + +The placement area is defined by the top cell abutment box. + +When placing a complete hierarchy, the abutment boxes of the cells (models) other than +the top cell are sets identical to the one of the top cell and their instances are +all placed at position ``(0,0,ID)``. That is, all the abutments boxes, whatever the +hierarchical level, defines the same area (they are exactly superposed). + +We choose this scheme because the placer will see all the instances as virtually +flattened, so they can be placed anywhere inside the top-cell abutment box. + +|bcenter| |Etesian-1| |ecenter| + + +|noindent| +**Computing the Placement Area** + +The placement area is computed using the ``etesian.aspectRatio`` and ``etesian.spaceMargin`` +parameters only if the top-cell has an empty abutment box. If the top-cell abutment +box has to be set, then it is propagated to all the instances models recursively. + + +|noindent| +**Reseting the Placement** + +Once a placement has been done, the placer cannot reset it (will be implemented +later). To perform a new placement, you must restart |cgt|. In addition, if you +have saved the placement on disk, you must erase any :cb:`.ap` file, which are +automatically reloaded along with the netlist (:cb:`.vst`). + +|noindent| +**Limitations** + +Etesian supports standard cells and fixed macros. As for the Coriolis 2.1 version, +it doesn't support movable macros, and you must place every macro beforehand. +Timing and routability analysis are not included either, and the returned placement +may be unroutable. + + +Etesian Configuration Parameters +................................ + ++-----------------------------------+------------------+----------------------------+ +| Parameter Identifier | Type | Default | ++===================================+==================+============================+ +| **Etesian Parameters** | ++-----------------------------------+------------------+----------------------------+ +|``etesian.aspectRatio`` | TypePercentage | :cb:`100` | +| +------------------+----------------------------+ +| | Define the height on width ``H/W`` aspect | +| | ratio, can be comprised between 10 and 1000 | ++-----------------------------------+------------------+----------------------------+ +|``etesian.spaceMargin`` | TypePercentage | :cb:`5` | +| +------------------+----------------------------+ +| | The extra white space added to the total area | +| | of the standard cells | ++-----------------------------------+------------------+----------------------------+ +|``etesian.uniformDensity`` | TypeBool | :cb:`False` | +| +------------------+----------------------------+ +| | Whether the cells will be spread envenly | +| | across the area or allowed to form denser | +| | clusters | ++-----------------------------------+------------------+----------------------------+ +|``etesian.effort`` | TypeInt | :cb:`2` | +| +------------------+----------------------------+ +| | Sets the balance between the speed of the | +| | placer and the solution quality | ++-----------------------------------+------------------+----------------------------+ +|``etesian.routingDriven`` | TypeBool | :cb:`False` | +| +------------------+----------------------------+ +| | Whether the tool will try routing iterations | +| | and whitespace allocation to improve | +| | routability; to be implemented | ++-----------------------------------+------------------+----------------------------+ +|``etesian.graphics`` | TypeInt | :cb:`2` | +| +------------------+----------------------------+ +| | How often the display will be refreshed | +| | More refreshing slows the placer. | +| | | +| | * ``1`` shows both upper and lower bounds | +| | * ``2`` only shows lower bound results | +| | * ``3`` only shows the final results | ++-----------------------------------+-----------------------------------------------+ + +|newpage| + + +Knik -- Global Router +--------------------- + +The quality of |Knik| global routing solutions are equivalent to those of FGR_ 1.0. +For an in-depth description of |Knik| algorithms, you may download the thesis of +D. |Dupuis| avalaible from here~: `Knik Thesis`_. + +The global router is (not yet) deterministic. To circumvent this limitation, +a global routing *solution* can be saved to disk and reloaded for later uses. + +A global routing is saved into a file with the same name as the design and a +|kgr| extention. It is in `Box Router`_ output format. + +|noindent| Menus: + +* :math:`\textbf{P\&R} \rightarrow \textbf{Step by Step} \rightarrow \textbf{Save Global Routing}` +* :math:`\textbf{P\&R} \rightarrow \textbf{Step by Step} \rightarrow \textbf{Load Global Routing}` + + +Kite -- Detailed Router +----------------------- + +|Kite| no longer suffers from the limitations of |Nero|. It can route big designs +as its runtime and memory footprint is almost linear (with respect to the number +of gates). It has successfully routed design of more than `150K` gates. +|medskip| + +|noindent| However, this first release comes with the temporary the following +restrictions: + +* Works only with |SxLib| standard cell gauge. +* Works always with 4 routing metal layers (`M2` through `M5`). +* Do not allow (take into account) pre-routed wires on signals + other than |POWER| or |GROUND|. + +.. note:: + **Slow Layer Assignment.** Most of the time, the layer assignment stage is + fast (less than a dozen seconds), but in some instances it can take more + than a dozen *minutes*. This is a known bug and will be corrected in later + releases. + +After each run, |Kite| displays a set of *completion ratios* which must all +be equal to `100%` if the detailed routing has been successfull. +In the event of a failure, on a saturated design, you may decrease the +`edge saturation ratio` (argument `--edge`) to balance more evenly the design +saturation. That is, the maximum saturation decrease at the price of a wider +saturated area and increased wirelength. This is the saturation of the +*global* router |Knik|, and you may increase/decrease by steps of ``5%``, +which represent one track. The maximum capacity of the |SxLib| gauge is +10 tracks in two layers, that makes 20 tracks by |Knik| edge. + +Routing a design is done in four ordered steps: + +#. Detailed pre-route :math:`\textbf{P\&R} \rightarrow \textbf{Step by Step} \rightarrow \textbf{Detailed PreRoute}` +#. Global routing :math:`\textbf{P\&R} \rightarrow \textbf{Step by Step} \rightarrow \textbf{Global Route}` +#. Detailed routing :math:`\textbf{P\&R} \rightarrow \textbf{Step by Step} \rightarrow \textbf{Detailed Route}` +#. Finalize routing :math:`\textbf{P\&R} \rightarrow \textbf{Step by Step} \rightarrow \textbf{Finalize Route}` + +It is possible to supply to the router a complete wiring for some nets that the user's +wants to be routed according to a specific topology. The supplied topology must respect +the building rules of the |Katabatic| database (contacts must be, terminals, turns, h-tee +& v-tee only). During the first step :fboxtt:`Detailed Pre-Route` the router will solve +overlaps between the segments, without making any dogleg. If no pre-routed topologies +are present, this step may be ommited. Any net routed at this step is then fixed and +become unmovable for the later stages. + +After the detailed routing step the |Kite| data-structure is still active +(the Hurricane wiring is decorated). The finalize step performs the removal of +the |Kite| data-structure, and it is not advisable to save the design before +that step. + +You may visualize the density (saturation) of either |Knik| (on edges) or +|Kite| (on GCells) until the routing is finalized. Special layers appears +to that effect in the `The Layers&Go Tab`_. + + +Kite Configuration Parameters +............................. + +As |Knik| is only called through |Kite|, it's parameters also have +the :cb:`kite.` prefix. + +The |Katabatic| parameters control the layer assignment step. + +All the defaults value given below are from the default |Alliance| technology +(:cb:`cmos` and :cb:`SxLib` cell gauge/routing gauge). + ++-----------------------------------+------------------+----------------------------+ +| Parameter Identifier | Type | Default | ++===================================+==================+============================+ +| **Katabatic Parameters** | ++-----------------------------------+------------------+----------------------------+ +|``katabatic.topRoutingLayer`` | TypeString | :cb:`METAL5` | +| +------------------+----------------------------+ +| | Define the highest metal layer that will be | +| | used for routing (inclusive). | ++-----------------------------------+------------------+----------------------------+ +|``katabatic.globalLengthThreshold``| TypeInt | :cb:`1450` | +| +------------------+----------------------------+ +| | This parameter is used by a layer assignment | +| | method which is no longer used (did not give | +| | good results) | ++-----------------------------------+------------------+----------------------------+ +| ``katabatic.saturateRatio`` | TypePercentage | :cb:`80` | +| +------------------+----------------------------+ +| | If ``M(x)`` density is above this ratio, | +| | move up feedthru global segments up from | +| | depth ``x`` to ``x+2`` | ++-----------------------------------+------------------+----------------------------+ +| ``katabatic.saturateRp`` | TypeInt | :cb:`8` | +| +------------------+----------------------------+ +| | If a GCell contains more terminals | +| | (:cb:`RoutingPad`) than that number, force a | +| | move up of the connecting segments to those | +| | in excess | ++-----------------------------------+------------------+----------------------------+ +| **Knik Parameters** | ++-----------------------------------+------------------+----------------------------+ +| ``kite.hTracksReservedLocal`` | TypeInt | :cb:`3` | +| +------------------+----------------------------+ +| | To take account the tracks needed *inside* a | +| | GCell to build the *local* routing, decrease | +| | the capacity of the edges of the global | +| | router. Horizontal and vertical locally | +| | reserved capacity can be distinguished for | +| | more accuracy. | ++-----------------------------------+------------------+----------------------------+ +| ``kite.vTracksReservedLocal`` | TypeInt | :cb:`3` | +| +------------------+----------------------------+ +| | cf. ``kite.hTracksReservedLocal`` | ++-----------------------------------+------------------+----------------------------+ +| **Kite Parameters** | ++-----------------------------------+------------------+----------------------------+ +| ``kite.eventsLimit`` | TypeInt | :cb:`4000002` | +| +------------------+----------------------------+ +| | The maximum number of segment displacements, | +| | this is a last ditch safety against infinite | +| | loop. It's perhaps a little too low for big | +| | designs | ++-----------------------------------+------------------+----------------------------+ +| ``kite.ripupCost`` | TypeInt | :cb:`3` | +| +------------------+----------------------------+ +| | Differential introduced between two ripup | +| | cost to avoid a loop between two ripped up | +| | segments | ++-----------------------------------+------------------+----------------------------+ +| ``kite.strapRipupLimit`` | TypeInt | :cb:`16` | +| +------------------+----------------------------+ +| | Maximum number of ripup for *strap* segments | ++-----------------------------------+------------------+----------------------------+ +| ``kite.localRipupLimit`` | TypeInt | :cb:`9` | +| +------------------+----------------------------+ +| | Maximum number of ripup for *local* segments | ++-----------------------------------+------------------+----------------------------+ +| ``kite.globalRipupLimit`` | TypeInt | :cb:`5` | +| +------------------+----------------------------+ +| | Maximum number of ripup for *global* segments,| +| | when this limit is reached, triggers topologic| +| | modification | ++-----------------------------------+------------------+----------------------------+ +| ``kite.longGlobalRipupLimit`` | TypeInt | :cb:`5` | +| +------------------+----------------------------+ +| | Maximum number of ripup for *long global* | +| | segments, when this limit is reached, triggers| +| | topological modification | ++-----------------------------------+------------------+----------------------------+ + + + +.. _Python Scripts in Cgt: + +Executing Python Scripts in Cgt +------------------------------- + +Python/Stratus scripts can be executed either in text or graphical mode. + +.. note:: **How Cgt Locates Python Scripts:** + |cgt| uses the Python ``import`` mechanism to load Python scripts. + So you must give the name of your script whitout ``.py`` extention and + it must be reachable through the ``PYTHONPATH``. You may uses the + dotted module notation. + +A Python/Stratus script must contains a function called ``ScriptMain()`` +with one optional argument, the graphical editor into which it may be +running (will be set to ``None`` in text mode). The Python interface to +the editor (type: :cb:`CellViewer`) is limited to basic capabilities +only. + +Any script given on the command line will be run immediatly *after* the +initializations and *before* any other argument is processed. + +For more explanation on Python scripts see :ref:`Python Interface to Coriolis`. + + +Printing & Snapshots +-------------------- + +Printing or saving into a |pdf| is fairly simple, just uses the **File -> Print** +menu or the |CTRL_P| shortcut to open the dialog box. + +The print functionality uses exactly the same rendering mechanism as for the +screen, beeing almost *WYSIWYG*. Thus, to obtain the best results it is advisable +to select the ``Coriolis.Printer`` look (in the *Controller*), which uses a +white background and much suited for high resolutions ``32x32`` pixels patterns + +There is also two mode of printing selectable through the *Controller* +**Settings -> Misc -> Printer/Snapshot Mode**: + +=============== ================= ===================================================== +Mode DPI (approx.) Intended Usage +--------------- ----------------- ----------------------------------------------------- +**Cell Mode** 150 For single ``Cell`` printing or very small designs. + Patterns will be bigger and more readable. +**Design Mode** 300 For designs (mostly commposed of wires and cells + outlines). +=============== ================= ===================================================== + +.. note:: *The pdf file size* + Be aware that the generated |pdf| files are indeed only pixmaps. + So they can grew very large if you select paper format above ``A2`` + or similar. + + +|noindent| +Saving into an image is subject to the same remarks as for |pdf|. + + +Memento of Shortcuts in Graphic Mode +------------------------------------ + +The main application binary is |cgt|. + ++---------------+-------------------+-----------------------------------------------------------+ +| Category | Keys | Action | ++===============+===================+===========================================================+ +| **Moves** | | |KeyUp|, | Shift the view in the according direction | +| | |KeyDown| | | +| | | |KeyLeft|, | | +| | |KeyRight| | | ++---------------+-------------------+-----------------------------------------------------------+ +| **Fit** | |KeyF| | Fit to the Cell abutment box | ++---------------+-------------------+-----------------------------------------------------------+ +| **Refresh** | |CTRL_L| | Triggers a complete display redraw | ++---------------+-------------------+-----------------------------------------------------------+ +| **Goto** | |KeyG| | *apperture* is the minimum side of the area | +| | | displayed around the point to go to. It's an | +| | | alternative way of setting the zoom level | ++---------------+-------------------+-----------------------------------------------------------+ +| **Zoom** | |KeyZ|, | Respectively zoom by a 2 factor and *unzoom* | +| | |KeyM| | by a 2 factor | +| +-------------------+-----------------------------------------------------------+ +| | | |BigMouse| | You can perform a zoom to an area. | +| | | Area Zoom | Define the zoom area by *holding down the left | +| | | mouse button* while moving the mouse. | ++---------------+-------------------+-----------------------------------------------------------+ +| **Selection** | | |BigMouse| | You can select displayed objects under an area. | +| | | Area Selection | Define the selection area by *holding down the | +| | | right mouse button* while moving the mouse. | +| +-------------------+-----------------------------------------------------------+ +| | | |BigMouse| | You can toggle the selection of one object under | +| | | Toggle Selection| the mouse position by pressing |CTRL| and | +| | | pressing down *the right mouse button*. A popup | +| | | list of what's under the position shows up into | +| | | which you can toggle the selection state of one | +| | | item. | +| +-------------------+-----------------------------------------------------------+ +| | |KeyCapS| | Toggle the selection visibility | ++---------------+-------------------+-----------------------------------------------------------+ +| **Controller**| |CTRL_I| | Show/hide the controller window. | +| | | | +| | | It's the Swiss Army Knife of the viewer. | +| | | From it, you can fine-control the display and | +| | | inspect almost everything in your design. | ++---------------+-------------------+-----------------------------------------------------------+ +| **Rulers** | |KeyK|, | One stroke on |KeyK| enters the ruler mode, in | +| | |KeyESC| | which you can draw one ruler. You can exit the | +| | | ruler mode by pressing |KeyESC|. Once in ruler | +| | | mode, the first click on the *left mouse button* | +| | | sets the ruler's starting point and the second | +| | | click the ruler's end point. The second click | +| | | exits automatically the ruler mode. | +| +-------------------+-----------------------------------------------------------+ +| | |KeyCapK| | Clears all the drawn rulers | ++---------------+-------------------+-----------------------------------------------------------+ +| **Print** | |CTRL_P| | Currently rather crude. It's a direct copy of | +| | | what's displayed in pixels. So the resulting | +| | | picture will be a little blurred due to | +| | | anti-aliasing mechanism. | ++---------------+-------------------+-----------------------------------------------------------+ +| **Open/Close**| |CTRL_O| | Opens a new design. The design name must be | +| | | given without path or extention. | +| +-------------------+-----------------------------------------------------------+ +| | |CTRL_W| | Close the current viewer window, but do not quit | +| | | the application. | +| +-------------------+-----------------------------------------------------------+ +| | |CTRL_Q| | `CTRL+Q` quit the application | +| | | (closing all windows). | ++---------------+-------------------+-----------------------------------------------------------+ +| **Hierarchy** | |CTRL_Down| | Go one hierarchy level down. That is, if there | +| | | is an *instance* under the cursor position, load | +| | | it's *model* Cell in place of the current one. | +| +-------------------+-----------------------------------------------------------+ +| | |CTRL_Up| | Go one hierarchy level up. if we have entered | +| | | the current model through |CTRL_Down| | +| | | reload the previous model (the one | +| | | in which this model is instanciated). | ++---------------+-------------------+-----------------------------------------------------------+ + + +Cgt Command Line Options +------------------------ + +Appart from the obvious ``--text`` options, all can be used for text and graphical mode. + ++-----------------------------+------------------------------------------------+ +| Arguments | Meaning | ++=============================+================================================+ +| `-t|--text` | Instruct |cgt| to run in text mode. | ++-----------------------------+------------------------------------------------+ +| `-L|--log-mode` | Disable the uses of |ANSI| escape sequence on | +| | the |tty|. Useful when the output is | +| | redirected to a file. | ++-----------------------------+------------------------------------------------+ +| `-c |--cell=` | The name of the design to load, without | +| | leading path or extention. | ++-----------------------------+------------------------------------------------+ +| `-g|--load-global` | Reload a global routing solution from disk. | +| | The file containing the solution must be named | +| | `.kgr`. | ++-----------------------------+------------------------------------------------+ +| `--save-global` | Save the global routing solution, into a file | +| | named `.kgr`. | ++-----------------------------+------------------------------------------------+ +| `-e |--edge=` | Change the edge capacity for the global | +| | router, between 0 and 1 (|Knik|). | ++-----------------------------+------------------------------------------------+ +| `-G|--global-route` | Run the global router (|Knik|). | ++-----------------------------+------------------------------------------------+ +| `-R|--detailed-route` | Run the detailed router (|Kite|). | ++-----------------------------+------------------------------------------------+ +| `-s|--save-design=` | The design into which the routed layout will | +| | be saved. It is strongly recommanded to choose | +| | a different name from the source (unrouted) | +| | design. | ++-----------------------------+------------------------------------------------+ +| `--events-limit=` | The maximal number of events after which the | +| | router will stops. This is mainly a failsafe | +| | against looping. The limit is sets to 4 | +| | millions of iteration which should suffice to | +| | any design of `100K`. gates. For bigger | +| | designs you may wants to increase this limit. | ++-----------------------------+------------------------------------------------+ +| `--stratus-script=` | Run the Python/Stratus script ``module``. | +| | See `Python Scripts in Cgt`_. | ++-----------------------------+------------------------------------------------+ + +|newpage| + + +Some Examples : + +* Run both global and detailed router, then save the routed design : :: + + > cgt -v -t -G -R --cell=design --save-design=design_kite + +* Load a previous global solution, run the detailed router, then save the + routed design : :: + + > cgt -v -t --load-global -R --cell=design --save-design=design_kite + +* Run the global router, then save the global routing solution : :: + + > cgt -v -t -G --save-global --cell=design + + +Miscellaneous Settings +---------------------- + ++---------------------------------------+------------------+----------------------------+ +| Parameter Identifier | Type | Default | ++=======================================+==================+============================+ +| **Verbosity/Log Parameters** | ++---------------------------------------+------------------+----------------------------+ +| ``misc.info`` | TypeBool | :cb:`False` | +| +------------------+----------------------------+ +| | Enable display of *info* level message | +| | (:cb:`cinfo` stream) | ++---------------------------------------+------------------+----------------------------+ +| ``misc.bug`` | TypeBool | :cb:`False` | +| +------------------+----------------------------+ +| | Enable display of *bug* level message | +| | (:cb:`cbug` stream), messages can be a little | +| | scarry | ++---------------------------------------+------------------+----------------------------+ +| ``misc.logMode`` | TypeBool | :cb:`False` | +| +------------------+----------------------------+ +| | If enabled, assume that the output device | +| | is not a ``tty`` and suppress any escaped | +| | sequences | ++---------------------------------------+------------------+----------------------------+ +| ``misc.verboseLevel1`` | TypeBool | :cb:`True` | +| +------------------+----------------------------+ +| | First level of verbosity, disable level 2 | ++---------------------------------------+------------------+----------------------------+ +| ``misc.verboseLevel2`` | TypeBool | :cb:`False` | +| +------------------+----------------------------+ +| | Second level of verbosity | ++---------------------------------------+------------------+----------------------------+ +| **Development/Debug Parameters** | ++---------------------------------------+------------------+----------------------------+ +| ``misc.minTraceLevel`` | TypeInt | :cb:`0` | ++---------------------------------------+------------------+----------------------------+ +| ``misc.maxTraceLevel`` | TypeInt | :cb:`0` | +| +------------------+----------------------------+ +| | Display trace information *between* those two | +| | levels (:cb:`cdebug` stream) | ++---------------------------------------+------------------+----------------------------+ +| ``misc.catchCore`` | TypeBool | :cb:`False` | +| +------------------+----------------------------+ +| | By default, |cgt| do not dump core. | +| | To generate one set this flag to :cb:`True` | ++---------------------------------------+------------------+----------------------------+ + +|newpage| + + +.. _The Controller: + +The Controller +~~~~~~~~~~~~~~ + +The *Controller* window is composed of seven tabs: + +#. `The Look Tab`_ to select the display style. +#. `The Filter Tab`_ the hierarchical levels to be displayed, the look of + rubbers and the dimension units. +#. `The Layers&Go Tab`_ to selectively hide/display layers. +#. `The Netlist Tab`_ to browse through the |netlist|. Works in association + with the *Selection* tab. +#. `The Selection Tab`_ allow to view all the currently selected elements. +#. `The Inspector Tab`_ browse through either the DataBase, the Cell or + the current selection. +#. `The Settings Tab`_ access all the tool's configuration settings. + + +.. _The Look Tab: + +The Look Tab +------------ + +You can select how the layout will be displayed. There is a special one +``Printer.Coriolis`` specifically designed for `Printing & Snapshots`_. +You should select it prior to calling the print or snapshot dialog boxes. + +|bcenter| |ControllerLook_1| |ecenter| + +|newpage| + + +.. _The Filter Tab: + +The Filter Tab +-------------- + +The filter tab let you select what hierarchical levels of your design will be +displayed. Hierarchy level are numbered top-down: the level 0 correspond to +the top-level cell, the level one to the instances of the top-level Cell and +so on. + +There are also check boxes to enable/disable the processing of Terminal Cell, +Master Cells and Compnents. The processing of Terminal Cell (hierarchy leaf +cells) is disabled by default when you load a hierarchical design and enabled +when you load a single Cell. + +You can choose what kind of form to give to the rubbers and the type of +unit used to display coordinates. + +.. note:: *What are Rubbers:* |Hurricane| uses *Rubbers* to materialize + physical gaps in net topology. That is, if some wires are missing to + connect two or more parts of net, a *rubber* will be drawn between them + to signal the gap. + + For example, after the detailed routing no *rubbers* should remains. + They have been made *very* visibles as big violet lines... + +|bcenter| |ControllerFilter_1| |ecenter| + +|newpage| + + +.. _The Layers&Go Tab: + +The Layers&Go Tab +----------------- + +Control the individual display of all *layers* and *Gos*. + +* *Layers* correspond to a true physical layer. From a |Hurricane| point of + view they are all the *BasicLayers* (could be matched to GDSII). +* *Gos* stands from *Graphical Objects*, they are drawings that have no + physical existence but are added by the various tools to display extra + information. One good exemple is the density map of the detailed router, + to easily locate congested areas. + +For each layer/Go there are two check boxes: + +* The normal one triggers the display. +* The red-outlined allows objects of that layer to be selectable or not. + +|bcenter| |ControllerLayersGos_1| |ecenter| + + +.. _The Netlist Tab: + +The Netlist Tab +--------------- + +The *Netlist* tab shows the list of nets... By default the tab is not +*synched* with the displayed Cell. To see the nets you must check the +**Sync Netlist** checkbox. You can narrow the set of displayed nets by +using the filter pattern (supports regular expressions). + +An very useful feature is to enable the **Sync Selection**, which will +automatically select all the components of the selected net(s). You can +select multiple nets. In the figure the net ``auxsc35`` is selected and +is highlited in the *Viewer*. + +|bcenter| |ControllerNetlist_1| |ecenter| +|bcenter| |ViewerNetlist_1| |ecenter| + + +.. _The Selection Tab: + +The Selection Tab +----------------- + +The *Selection* tab list all the components currently selecteds. They +can be filtered thanks to the filter pattern. + +Used in conjunction with the *Netlist* **Sync Selection** you will all see +all the components part of *net*. + +In this list, you can toggle individually the selection of component by +pressing the ``t`` key. When unselected in this way a component is not +removed from the the selection list but instead displayed in red italic. +To see where a component is you may make it blink by repeatedly press +the ``t`` key... + +|bcenter| |ControllerSelection_1| |ecenter| + + +.. _The Inspector Tab: + +The Inspector Tab +----------------- + +This tab is very useful, but mostly for |Coriolis| developpers. It allows +to browse through the live DataBase. The *Inspector* provide three entry points: + +* **DataBase**: Starts from the whole |Hurricane| DataBase. +* **Cell**: Inspect the currently loaded Cell. +* **Selection**: Inspect the object currently highlited in the *Selection* tab. + +Once an entry point has been activated, you may recursively expore all +it's fields using the right/left arrows. + +.. note:: *Do not put your fingers in the socket:* when inspecting + anything, do not modify the DataBase. If any object under inspection + is deleted, you will crash the application... + +.. note:: *Implementation Detail:* the inspector support is done with + ``Slot``, ``Record`` and ``getString()``. + +|bcenter| |ControllerInspector_1| |ecenter| +|bcenter| |ControllerInspector_2| |ecenter| +|bcenter| |ControllerInspector_3| |ecenter| + + +.. _The Settings Tab: + +The Settings Tab +---------------- + +Here comes the description of the *Settings* tab. + +|bcenter| |ControllerSettings_1| |ecenter| diff --git a/documentation/UsersGuide/WWW_defs.rst b/documentation/UsersGuide/WWW_defs.rst deleted file mode 100644 index 5062f371..00000000 --- a/documentation/UsersGuide/WWW_defs.rst +++ /dev/null @@ -1,70 +0,0 @@ - -.. -*- Mode: rst -*- -.. This header contains the definitions needed for the UsersGuide.rst -.. document to be displayed correctly on the soc-extras website. -.. The only difference with HTML_defs.rst is that the images are -.. stored at a different URL on the website. Namely: -.. https://soc-extras.lip6.fr/media/filer/2012/12/07/ - -.. URLs that changes between the various backends. -.. _Coriolis Tools Documentation: https://www-soc.lip6.fr/sesi-docs/coriolis2-docs/coriolis2/ -.. _Stratus Documentation: https://www-soc.lip6.fr/sesi-docs/coriolis2-docs/coriolis2/en/html/stratus/index.html -.. _Here: https://www-soc.lip6.fr/sesi-docs/coriolis2-docs/coriolis2/en/latex/users-guide/UsersGuide.pdf - -.. role:: raw-html(raw) - :format: html - -.. For HTML backend -.. |Key_ESC| image:: https://soc-extras.lip6.fr/media/filer/2012/12/07/key_esc.png -.. |Key_CTRL| image:: https://soc-extras.lip6.fr/media/filer/2012/12/07/key_ctrl.png -.. |Key_Up| image:: https://soc-extras.lip6.fr/media/filer/2012/12/07/key_up.png -.. |Key_Down| image:: https://soc-extras.lip6.fr/media/filer/2012/12/07/key_down.png -.. |Key_Left| image:: https://soc-extras.lip6.fr/media/filer/2012/12/07/key_left.png -.. |Key_Right| image:: https://soc-extras.lip6.fr/media/filer/2012/12/07/key_right.png -.. |Key_f| image:: https://soc-extras.lip6.fr/media/filer/2012/12/07/key_f.png -.. |Key_G| image:: https://soc-extras.lip6.fr/media/filer/2012/12/07/key_gcap.png -.. |Key_i| image:: https://soc-extras.lip6.fr/media/filer/2012/12/07/key_icap.png -.. |Key_l| image:: https://soc-extras.lip6.fr/media/filer/2012/12/07/key_lcap.png -.. |Key_m| image:: https://soc-extras.lip6.fr/media/filer/2012/12/07/key_m.png -.. |Key_k| image:: https://soc-extras.lip6.fr/media/filer/2012/12/07/key_k.png -.. |Key_K| image:: https://soc-extras.lip6.fr/media/filer/2012/12/07/key_kcap.png -.. |Key_o| image:: https://soc-extras.lip6.fr/media/filer/2012/12/07/key_ocap.png -.. |Key_p| image:: https://soc-extras.lip6.fr/media/filer/2012/12/07/key_pcap.png -.. |Key_q| image:: https://soc-extras.lip6.fr/media/filer/2012/12/07/key_qcap.png -.. |Key_w| image:: https://soc-extras.lip6.fr/media/filer/2012/12/07/key_wcap.png -.. |Key_S| image:: https://soc-extras.lip6.fr/media/filer/2012/12/07/key_scap.png -.. |Key_z| image:: https://soc-extras.lip6.fr/media/filer/2012/12/07/key_z.png -.. |Plus| replace:: :raw-html:`+` -.. |rightarrow| replace:: :raw-html:`

` -.. |menu_P&R| replace:: :raw-html:`

` -.. |menu_StepByStep| replace:: :raw-html:`

` -.. |menu_KiteSaveGlobalRouting| image:: https://soc-extras.lip6.fr/media/filer/2012/12/07/pr-sbs-saveglobal.png -.. |menu_KiteLoadGlobalRouting| image:: https://soc-extras.lip6.fr/media/filer/2012/12/07/pr-sbs-loadglobal.png -.. |menu_KiteGlobalRoute| image:: https://soc-extras.lip6.fr/media/filer/2012/12/07/pr-globalroute.png -.. |menu_KiteDetailedRoute| image:: https://soc-extras.lip6.fr/media/filer/2012/12/07/pr-detailedroute.png -.. |menu_KiteDetailedPreRoute| image:: https://soc-extras.lip6.fr/media/filer/2012/12/07/pr-detailedpreroute.png -.. |menu_KiteFinalizeRoute| image:: https://soc-extras.lip6.fr/media/filer/2012/12/07/pr-finalizeroute.png - -.. Stand-alone images. -.. |ViewerSnapshot_1| replace:: :raw-html:`
Viewer Basic Snapshot
` -.. |ControllerSnapshot_1| replace:: :raw-html:`
Controller Basic Snapshot
` -.. |ControllerLook_1| replace:: :raw-html:`
Controller Basic Snapshot
` -.. |ControllerFilter_1| replace:: :raw-html:`
Controller Basic Snapshot
` -.. |ControllerLayersGos_1| replace:: :raw-html:`
Controller Basic Snapshot
` -.. |ControllerNetlist_1| replace:: :raw-html:`
Controller Basic Snapshot
` -.. |ViewerNetlist_1| replace:: :raw-html:`
Controller Basic Snapshot
` -.. |ControllerSelection_1| replace:: :raw-html:`
Controller Basic Snapshot
` -.. |ControllerInspector_1| replace:: :raw-html:`
Controller Basic Snapshot
` -.. |ControllerInspector_2| replace:: :raw-html:`
Controller Basic Snapshot
` -.. |ControllerInspector_3| replace:: :raw-html:`
Controller Basic Snapshot
` -.. |ControllerSettings_1| replace:: :raw-html:`
Controller Basic Snapshot
` -.. |CoriolisSoftSchema| replace:: :raw-html:`
Coriolis Software Schematic
` - -.. |BigMouse| image:: https://soc-extras.lip6.fr/media/filer/2012/12/07/computermouse.png - :scale: 25% - -.. Direct LaTeX commands encapsulation. -.. |dotfill| replace:: :raw-html:`  ` -.. |noindent| replace:: :raw-html:`

` -.. |medskip| replace:: :raw-html:`
` -.. |newpage| replace:: :raw-html:`
` diff --git a/documentation/UsersGuide/images/Controller-1-eps-converted-to.pdf b/documentation/UsersGuide/images/Controller-1-eps-converted-to.pdf new file mode 100644 index 00000000..f30a0f38 Binary files /dev/null and b/documentation/UsersGuide/images/Controller-1-eps-converted-to.pdf differ diff --git a/documentation/UsersGuide/images/Controller-Filter-1-eps-converted-to.pdf b/documentation/UsersGuide/images/Controller-Filter-1-eps-converted-to.pdf new file mode 100644 index 00000000..3298d8fa Binary files /dev/null and b/documentation/UsersGuide/images/Controller-Filter-1-eps-converted-to.pdf differ diff --git a/documentation/UsersGuide/images/Controller-Inspector-1-eps-converted-to.pdf b/documentation/UsersGuide/images/Controller-Inspector-1-eps-converted-to.pdf new file mode 100644 index 00000000..817a0120 Binary files /dev/null and b/documentation/UsersGuide/images/Controller-Inspector-1-eps-converted-to.pdf differ diff --git a/documentation/UsersGuide/images/Controller-Inspector-2-eps-converted-to.pdf b/documentation/UsersGuide/images/Controller-Inspector-2-eps-converted-to.pdf new file mode 100644 index 00000000..12982531 Binary files /dev/null and b/documentation/UsersGuide/images/Controller-Inspector-2-eps-converted-to.pdf differ diff --git a/documentation/UsersGuide/images/Controller-Inspector-3-eps-converted-to.pdf b/documentation/UsersGuide/images/Controller-Inspector-3-eps-converted-to.pdf new file mode 100644 index 00000000..9fa8ec11 Binary files /dev/null and b/documentation/UsersGuide/images/Controller-Inspector-3-eps-converted-to.pdf differ diff --git a/documentation/UsersGuide/images/Controller-LayersGos-1-eps-converted-to.pdf b/documentation/UsersGuide/images/Controller-LayersGos-1-eps-converted-to.pdf new file mode 100644 index 00000000..e58dfa22 Binary files /dev/null and b/documentation/UsersGuide/images/Controller-LayersGos-1-eps-converted-to.pdf differ diff --git a/documentation/UsersGuide/images/Controller-Look-1-eps-converted-to.pdf b/documentation/UsersGuide/images/Controller-Look-1-eps-converted-to.pdf new file mode 100644 index 00000000..1cbaae91 Binary files /dev/null and b/documentation/UsersGuide/images/Controller-Look-1-eps-converted-to.pdf differ diff --git a/documentation/UsersGuide/images/Controller-Netlist-1-eps-converted-to.pdf b/documentation/UsersGuide/images/Controller-Netlist-1-eps-converted-to.pdf new file mode 100644 index 00000000..442f8b76 Binary files /dev/null and b/documentation/UsersGuide/images/Controller-Netlist-1-eps-converted-to.pdf differ diff --git a/documentation/UsersGuide/images/Controller-Selection-1-eps-converted-to.pdf b/documentation/UsersGuide/images/Controller-Selection-1-eps-converted-to.pdf new file mode 100644 index 00000000..535fbae2 Binary files /dev/null and b/documentation/UsersGuide/images/Controller-Selection-1-eps-converted-to.pdf differ diff --git a/documentation/UsersGuide/images/Controller-Settings-1-eps-converted-to.pdf b/documentation/UsersGuide/images/Controller-Settings-1-eps-converted-to.pdf new file mode 100644 index 00000000..96fd825a Binary files /dev/null and b/documentation/UsersGuide/images/Controller-Settings-1-eps-converted-to.pdf differ diff --git a/documentation/UsersGuide/images/Coriolis-Soft-Schema-eps-converted-to.pdf b/documentation/UsersGuide/images/Coriolis-Soft-Schema-eps-converted-to.pdf new file mode 100644 index 00000000..7cfb3bcb Binary files /dev/null and b/documentation/UsersGuide/images/Coriolis-Soft-Schema-eps-converted-to.pdf differ diff --git a/documentation/UsersGuide/images/Viewer-1-eps-converted-to.pdf b/documentation/UsersGuide/images/Viewer-1-eps-converted-to.pdf new file mode 100644 index 00000000..357780b2 Binary files /dev/null and b/documentation/UsersGuide/images/Viewer-1-eps-converted-to.pdf differ diff --git a/documentation/UsersGuide/images/Viewer-Netlist-1-eps-converted-to.pdf b/documentation/UsersGuide/images/Viewer-Netlist-1-eps-converted-to.pdf new file mode 100644 index 00000000..39e492d2 Binary files /dev/null and b/documentation/UsersGuide/images/Viewer-Netlist-1-eps-converted-to.pdf differ diff --git a/documentation/UsersGuide/images/chip-structure-1-eps-converted-to.pdf b/documentation/UsersGuide/images/chip-structure-1-eps-converted-to.pdf new file mode 100644 index 00000000..c937a9b4 Binary files /dev/null and b/documentation/UsersGuide/images/chip-structure-1-eps-converted-to.pdf differ diff --git a/documentation/UsersGuide/images/etesian-1-eps-converted-to.pdf b/documentation/UsersGuide/images/etesian-1-eps-converted-to.pdf new file mode 100644 index 00000000..c083696b Binary files /dev/null and b/documentation/UsersGuide/images/etesian-1-eps-converted-to.pdf differ diff --git a/documentation/UsersGuide/index.rst b/documentation/UsersGuide/index.rst new file mode 100644 index 00000000..7121510a --- /dev/null +++ b/documentation/UsersGuide/index.rst @@ -0,0 +1,21 @@ +.. -*- mode: rst; explicit-buffer-name: "index.rst" -*- + +.. include:: ../etc/definitions.rst + + +======================= +Coriolis User's Guide +======================= + +Printable version of this document `UsersGuide.pdf <../../../pdf/main/UsersGuide.pdf>`_. + + +.. toctree:: + :maxdepth: 2 + + LicenseCredits.rst + Releases.rst + Installation.rst + Configuration.rst + ViewerTools.rst + ScriptsPlugins.rst diff --git a/documentation/UsersGuide/pdfHeader.rst b/documentation/UsersGuide/pdfHeader.rst new file mode 100644 index 00000000..3a9c832f --- /dev/null +++ b/documentation/UsersGuide/pdfHeader.rst @@ -0,0 +1,15 @@ +.. -*- Mode: rst -*- + +.. include:: ../etc/definitions.rst + + +======================= +Coriolis User's Guide +======================= + +|pagestylefancy| + + +.. contents:: + +|newpage| diff --git a/documentation/UsersGuide/socstyle.tex b/documentation/UsersGuide/socstyle.tex deleted file mode 100644 index 5cf8f487..00000000 --- a/documentation/UsersGuide/socstyle.tex +++ /dev/null @@ -1,89 +0,0 @@ - - \usepackage[default,osfigures,scale=0.95]{opensans} - \usepackage{xspace} - \usepackage{fancyhdr} -%\usepackage[dvipdfm]{graphicx} - \usepackage{graphicx} - \usepackage{enumitem} - \usepackage[sf,bf]{titlesec} - \usepackage{titletoc} - \usepackage[colorlinks=true,linkcolor=blue,urlcolor=blue,dvipdfm]{hyperref} - \usepackage[paper=a4paper,headheight=30pt,tmargin=1.5in,bmargin=1in]{geometry} -%\usepackage{layouts} - - \urlstyle{tt} % normal text font (alternatives: same, tt, rm, sf) - \renewlist{itemize}{itemize}{9} - \setlist[itemize]{label=\textbullet} - -% The LaTeX Companion -- p. 204. -% Miniature display of the page layout. -%\newcommand{\showpage}{% -% \setlayoutscale{0.65}\setlabelfont{\tiny}% -% \printheadingsfalse\printparametersfalse% -% \currentpage\pagedesign% -%} - - \titlecontents{section}[0pc] - {\sffamily\bfseries} % above code. - {\contentslabel{1pc}} % numbered entry format. - {} % numberless entry format. - {\titlerule*[8pt]{.}\textsc{\textbf{{\contentspage}}}} % page format. - \titlecontents{subsection}[0pc] - {\sffamily} % above code. - {\contentslabel{2pc}} % numbered entry format. - {} % numberless entry format. - {\titlerule*[8pt]{.}\textsc{\textbf{{\contentspage}}}} % page format. - \titlecontents{subsubsection}[1pc] - {\sffamily} % above code. - {\contentslabel{2pc}} % numbered entry format. - {} % numberless entry format. - {\titlerule*[8pt]{.}\textsc{\textbf{{\contentspage}}}} % page format. - - \newcommand{\key}[1]{\raisebox{-0.5\baselineskip}{\rule{0pt}{1.5\baselineskip}}\fbox{\textsf{#1}}} - - \newcommand{\DUroleul}[1]{\underline{#1}\xspace} - \newcommand{\DUrolesc}[1]{\textsc{#1}\xspace} - \newcommand{\DUrolecb}[1]{\textbf{\texttt{#1}}\xspace} - \newcommand{\DUrolefboxtt}[1]{\fbox{\texttt{#1}}\xspace} - - \newcommand{\DUtitlenote}[1]{\noindent\textbf{#1}\smallskip} - - \newcommand{\DUadmonitionnote}[1]{% - \begin{center} - \sffamily - \begin{array}[t]{m{1cm}!{\vrule width 1pt}m{.90\textwidth}} - \raisebox{0.0cm}{\includegraphics[scale=0.5,natwidth=48,natheight=48]{./images/clipboard.pdf}} & - \begin{minipage}[t]{.85\textwidth} #1 - \end{minipage} \\ - \end{array} - \end{center} - } - - \newcommand{\DUtitleerror}[1]{\noindent\textbf{\color{red}#1}\smallskip} - - \newcommand{\DUadmonitionerror}[1]{% - \begin{center} - \sffamily - \begin{array}[t]{m{1cm}!{\vrule width 1pt}m{.90\textwidth}} - \raisebox{0.0cm}{\includegraphics[scale=0.5,natwidth=48,natheight=48]{./images/i-core.pdf}} & - \begin{minipage}[t]{.85\textwidth} #1 - \end{minipage} \\ - \end{array} - \end{center} - } - - \newcommand{\UPMC} {\textsc{upmc}\xspace} - \newcommand{\LIP} {\textsc{lip6}\xspace} - \newcommand{\SoC} {\textsc{S}o\textsc{C}\xspace} - - \renewcommand{\headrulewidth}{0.2mm} - \renewcommand{\footrulewidth}{0.2mm} - \renewcommand{\sectionmark}[1]{\markboth{\thesection\ #1}{\thesection\ #1}} - \renewcommand{\subsectionmark}[1]{} - \lhead[]{Documentation \SoC} - \rhead[]{March 2015} - \lfoot[]{\UPMC/\LIP/\SoC} - \rfoot[]{\thepage} - \cfoot[]{} - - \pagestyle{fancy} diff --git a/documentation/Viewer/Viewer.rst b/documentation/Viewer/Viewer.rst new file mode 100644 index 00000000..c103b413 --- /dev/null +++ b/documentation/Viewer/Viewer.rst @@ -0,0 +1,11 @@ +.. -*- Mode: rst -*- + +.. include:: ../etc/definitions.rst + + +================== +Viewer Reference +================== + +The Viewer C++ API reference is generated by Doxygen_ and is +available here: `Viewer `_ diff --git a/documentation/_build/doctrees/Contents.doctree b/documentation/_build/doctrees/Contents.doctree new file mode 100644 index 00000000..b4e850b7 Binary files /dev/null and b/documentation/_build/doctrees/Contents.doctree differ diff --git a/documentation/_build/doctrees/CrlCore/CrlCore.doctree b/documentation/_build/doctrees/CrlCore/CrlCore.doctree new file mode 100644 index 00000000..c59fd7ab Binary files /dev/null and b/documentation/_build/doctrees/CrlCore/CrlCore.doctree differ diff --git a/documentation/_build/doctrees/DpGen/DpGen.doctree b/documentation/_build/doctrees/DpGen/DpGen.doctree new file mode 100644 index 00000000..3fe89591 Binary files /dev/null and b/documentation/_build/doctrees/DpGen/DpGen.doctree differ diff --git a/documentation/_build/doctrees/Hurricane/Hurricane.doctree b/documentation/_build/doctrees/Hurricane/Hurricane.doctree new file mode 100644 index 00000000..6424b3dc Binary files /dev/null and b/documentation/_build/doctrees/Hurricane/Hurricane.doctree differ diff --git a/documentation/_build/doctrees/Patterns/Patterns.doctree b/documentation/_build/doctrees/Patterns/Patterns.doctree new file mode 100644 index 00000000..3cf843ff Binary files /dev/null and b/documentation/_build/doctrees/Patterns/Patterns.doctree differ diff --git a/documentation/_build/doctrees/PythonCpp/Configuration.doctree b/documentation/_build/doctrees/PythonCpp/Configuration.doctree new file mode 100644 index 00000000..c94cda98 Binary files /dev/null and b/documentation/_build/doctrees/PythonCpp/Configuration.doctree differ diff --git a/documentation/_build/doctrees/PythonCpp/DBoHierarchy.doctree b/documentation/_build/doctrees/PythonCpp/DBoHierarchy.doctree new file mode 100644 index 00000000..bb51d68a Binary files /dev/null and b/documentation/_build/doctrees/PythonCpp/DBoHierarchy.doctree differ diff --git a/documentation/_build/doctrees/PythonCpp/DBoStandalone.doctree b/documentation/_build/doctrees/PythonCpp/DBoStandalone.doctree new file mode 100644 index 00000000..93375329 Binary files /dev/null and b/documentation/_build/doctrees/PythonCpp/DBoStandalone.doctree differ diff --git a/documentation/_build/doctrees/PythonCpp/DbU.doctree b/documentation/_build/doctrees/PythonCpp/DbU.doctree new file mode 100644 index 00000000..4af94566 Binary files /dev/null and b/documentation/_build/doctrees/PythonCpp/DbU.doctree differ diff --git a/documentation/_build/doctrees/PythonCpp/Introduction.doctree b/documentation/_build/doctrees/PythonCpp/Introduction.doctree new file mode 100644 index 00000000..9d40ab70 Binary files /dev/null and b/documentation/_build/doctrees/PythonCpp/Introduction.doctree differ diff --git a/documentation/_build/doctrees/PythonCpp/Name.doctree b/documentation/_build/doctrees/PythonCpp/Name.doctree new file mode 100644 index 00000000..cedf191e Binary files /dev/null and b/documentation/_build/doctrees/PythonCpp/Name.doctree differ diff --git a/documentation/_build/doctrees/PythonCpp/NonDBo.doctree b/documentation/_build/doctrees/PythonCpp/NonDBo.doctree new file mode 100644 index 00000000..37ea30bc Binary files /dev/null and b/documentation/_build/doctrees/PythonCpp/NonDBo.doctree differ diff --git a/documentation/_build/doctrees/PythonCpp/index.doctree b/documentation/_build/doctrees/PythonCpp/index.doctree new file mode 100644 index 00000000..f73b40b0 Binary files /dev/null and b/documentation/_build/doctrees/PythonCpp/index.doctree differ diff --git a/documentation/_build/doctrees/RDS/RDSpage.doctree b/documentation/_build/doctrees/RDS/RDSpage.doctree new file mode 100644 index 00000000..0c7b4e48 Binary files /dev/null and b/documentation/_build/doctrees/RDS/RDSpage.doctree differ diff --git a/documentation/_build/doctrees/RDS/index.doctree b/documentation/_build/doctrees/RDS/index.doctree new file mode 100644 index 00000000..b83309ed Binary files /dev/null and b/documentation/_build/doctrees/RDS/index.doctree differ diff --git a/documentation/_build/doctrees/Stratus/Stratus.doctree b/documentation/_build/doctrees/Stratus/Stratus.doctree new file mode 100644 index 00000000..a7088527 Binary files /dev/null and b/documentation/_build/doctrees/Stratus/Stratus.doctree differ diff --git a/documentation/_build/doctrees/Unicorn/Unicorn.doctree b/documentation/_build/doctrees/Unicorn/Unicorn.doctree new file mode 100644 index 00000000..91237311 Binary files /dev/null and b/documentation/_build/doctrees/Unicorn/Unicorn.doctree differ diff --git a/documentation/_build/doctrees/UsersGuide/Configuration.doctree b/documentation/_build/doctrees/UsersGuide/Configuration.doctree new file mode 100644 index 00000000..37ca9b5f Binary files /dev/null and b/documentation/_build/doctrees/UsersGuide/Configuration.doctree differ diff --git a/documentation/_build/doctrees/UsersGuide/Installation.doctree b/documentation/_build/doctrees/UsersGuide/Installation.doctree new file mode 100644 index 00000000..cba3753c Binary files /dev/null and b/documentation/_build/doctrees/UsersGuide/Installation.doctree differ diff --git a/documentation/_build/doctrees/UsersGuide/LicenseCredits.doctree b/documentation/_build/doctrees/UsersGuide/LicenseCredits.doctree new file mode 100644 index 00000000..f4097c02 Binary files /dev/null and b/documentation/_build/doctrees/UsersGuide/LicenseCredits.doctree differ diff --git a/documentation/_build/doctrees/UsersGuide/Releases.doctree b/documentation/_build/doctrees/UsersGuide/Releases.doctree new file mode 100644 index 00000000..51764cc6 Binary files /dev/null and b/documentation/_build/doctrees/UsersGuide/Releases.doctree differ diff --git a/documentation/_build/doctrees/UsersGuide/ScriptsPlugins.doctree b/documentation/_build/doctrees/UsersGuide/ScriptsPlugins.doctree new file mode 100644 index 00000000..676605dc Binary files /dev/null and b/documentation/_build/doctrees/UsersGuide/ScriptsPlugins.doctree differ diff --git a/documentation/_build/doctrees/UsersGuide/ViewerTools.doctree b/documentation/_build/doctrees/UsersGuide/ViewerTools.doctree new file mode 100644 index 00000000..85bb1659 Binary files /dev/null and b/documentation/_build/doctrees/UsersGuide/ViewerTools.doctree differ diff --git a/documentation/_build/doctrees/UsersGuide/index.doctree b/documentation/_build/doctrees/UsersGuide/index.doctree new file mode 100644 index 00000000..df558295 Binary files /dev/null and b/documentation/_build/doctrees/UsersGuide/index.doctree differ diff --git a/documentation/_build/doctrees/Viewer/Viewer.doctree b/documentation/_build/doctrees/Viewer/Viewer.doctree new file mode 100644 index 00000000..3da5916d Binary files /dev/null and b/documentation/_build/doctrees/Viewer/Viewer.doctree differ diff --git a/documentation/_build/doctrees/environment.pickle b/documentation/_build/doctrees/environment.pickle new file mode 100644 index 00000000..3e71d905 Binary files /dev/null and b/documentation/_build/doctrees/environment.pickle differ diff --git a/documentation/_build/doctrees/etc/definitions.doctree b/documentation/_build/doctrees/etc/definitions.doctree new file mode 100644 index 00000000..899fce4f Binary files /dev/null and b/documentation/_build/doctrees/etc/definitions.doctree differ diff --git a/documentation/_build/doctrees/index.doctree b/documentation/_build/doctrees/index.doctree new file mode 100644 index 00000000..8f884b1e Binary files /dev/null and b/documentation/_build/doctrees/index.doctree differ diff --git a/documentation/_build/html/.buildinfo b/documentation/_build/html/.buildinfo new file mode 100644 index 00000000..3ba06f68 --- /dev/null +++ b/documentation/_build/html/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. +config: 1563ffe9c48542af75d7298c4e351220 +tags: fbb0d17656682115ca4d033fb2f83ba1 diff --git a/documentation/_build/html/Contents.html b/documentation/_build/html/Contents.html new file mode 100644 index 00000000..9fbbead3 --- /dev/null +++ b/documentation/_build/html/Contents.html @@ -0,0 +1,473 @@ + + + + + + + + + + + + Comprenhensive Table of Contents — Coriolis 2 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+
+
+
    +
  • Docs »
  • + +
  • Comprenhensive Table of Contents
  • +
  • + + + +
  • +
+
+
+
+ +
+

Comprenhensive Table of Contents

+
+ +
+
+ + +
+
+ + +
+ +
+ + + + + +
+ Generated by Sphinx + using a RTD theme on Jul 15, 2017. +
+ + + + + +
Coriolis 2 Documentation + © Copyright 2000-2017, UPMC. +
+
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/documentation/_build/html/CrlCore/CrlCore.html b/documentation/_build/html/CrlCore/CrlCore.html new file mode 100644 index 00000000..4b5509f1 --- /dev/null +++ b/documentation/_build/html/CrlCore/CrlCore.html @@ -0,0 +1,334 @@ + + + + + + + + + + + + CRL Core Reference — Coriolis 2 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+
+
+
    +
  • Docs »
  • + +
  • CRL Core Reference
  • +
  • + + + +
  • +
+
+
+
+ +
+

CRL Core Reference

+

The CRL Core C++ API reference is generated by Doxygen and is +available here: CRL Core

+
+ + +
+
+ + + + +
+ +
+ + + + + +
+ Generated by Sphinx + using a RTD theme on Jul 15, 2017. +
+ + + + + +
Coriolis 2 Documentation + © Copyright 2000-2017, UPMC. +
+
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/documentation/_build/html/DpGen/DpGen.html b/documentation/_build/html/DpGen/DpGen.html new file mode 100644 index 00000000..c4f9e8bf --- /dev/null +++ b/documentation/_build/html/DpGen/DpGen.html @@ -0,0 +1,334 @@ + + + + + + + + + + + + DpGen Reference — Coriolis 2 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+
+
+
    +
  • Docs »
  • + +
  • DpGen Reference
  • +
  • + + + +
  • +
+
+
+
+ +
+

DpGen Reference

+

The DpGen extension of the Stratus Language reference is generated by LaTeX2HTML and is +available here: DpGen

+
+ + +
+
+ + + + +
+ +
+ + + + + +
+ Generated by Sphinx + using a RTD theme on Jul 15, 2017. +
+ + + + + +
Coriolis 2 Documentation + © Copyright 2000-2017, UPMC. +
+
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/documentation/_build/html/Hurricane/Hurricane.html b/documentation/_build/html/Hurricane/Hurricane.html new file mode 100644 index 00000000..08a418ab --- /dev/null +++ b/documentation/_build/html/Hurricane/Hurricane.html @@ -0,0 +1,334 @@ + + + + + + + + + + + + Hurricane Reference — Coriolis 2 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+
+
+
    +
  • Docs »
  • + +
  • Hurricane Reference
  • +
  • + + + +
  • +
+
+
+
+ +
+

Hurricane Reference

+

The Hurricane C++ API reference is generated by Doxygen and is +available here: Hurricane

+
+ + +
+
+ + + + +
+ +
+ + + + + +
+ Generated by Sphinx + using a RTD theme on Jul 15, 2017. +
+ + + + + +
Coriolis 2 Documentation + © Copyright 2000-2017, UPMC. +
+
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/documentation/_build/html/Patterns/Patterns.html b/documentation/_build/html/Patterns/Patterns.html new file mode 100644 index 00000000..c50c5ab5 --- /dev/null +++ b/documentation/_build/html/Patterns/Patterns.html @@ -0,0 +1,334 @@ + + + + + + + + + + + + Patterns Reference — Coriolis 2 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+
+
+
    +
  • Docs »
  • + +
  • Patterns Reference
  • +
  • + + + +
  • +
+
+
+
+ +
+

Patterns Reference

+

The Patterns extension of the Stratus Language reference is generated by LaTeX2HTML and is +available here: Patterns

+
+ + +
+
+ + + + +
+ +
+ + + + + +
+ Generated by Sphinx + using a RTD theme on Jul 15, 2017. +
+ + + + + +
Coriolis 2 Documentation + © Copyright 2000-2017, UPMC. +
+
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/documentation/_build/html/PythonCpp/Configuration.html b/documentation/_build/html/PythonCpp/Configuration.html new file mode 100644 index 00000000..cd4adf59 --- /dev/null +++ b/documentation/_build/html/PythonCpp/Configuration.html @@ -0,0 +1,367 @@ + + + + + + + + + + + + 2. Basic File Structure and CMake configuration — Coriolis 2 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+
+
+ +
+
+
+ +
+

2. Basic File Structure and CMake configuration

+

As a first example we will consider the Hurrican::Library +class. To export a class into Python, we must create three files:

+
    +
  1. PyLibrary.h, defines the PyLibrary C-Struct and the functions +needed outside the module istself (mostly for PyHurricane.cpp).
  2. +
  3. PyLibrary.cpp, contains the complete wrapping of the class and +the Python type definition (PyTypeLibrary).
  4. +
  5. PyHurricane.cpp, the definition of the Python module into which +the classes are registered. The module act as a namespace in +Python so it is good practice to give it the same name as it’s +associated C++ namespace.
  6. +
+

+

To build a Python module in cmake, use the following macro:

+
+
              set( pyCpps      PyLibrary.cpp
+                               PyHurricane.cpp )
+              set( pyIncludes  hurricane/isobar/PyLibrary.h
+
+add_python_module( "${pyCpps}"
+                   "${pyIncludes}"
+                   "isobar;1.0;1"     # Name & version of the supporting
+                                      # shared library.
+                   Hurricane          # Name of the Python module will give:
+                                      #   Hurricane.so
+                   "${depLibs}"       # List of dependency libraries.
+                   include/coriolis2/hurricane/isobar
+                                      # Where to install the include files.
+                 )
+
+
+
+
+ + +
+
+ + + + +
+ +
+ + + + + +
+ Generated by Sphinx + using a RTD theme on Jul 15, 2017. +
+ + + + + +
Coriolis 2 Documentation + © Copyright 2000-2017, UPMC. +
+
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/documentation/_build/html/PythonCpp/DBoHierarchy.html b/documentation/_build/html/PythonCpp/DBoHierarchy.html new file mode 100644 index 00000000..4b794806 --- /dev/null +++ b/documentation/_build/html/PythonCpp/DBoHierarchy.html @@ -0,0 +1,738 @@ + + + + + + + + + + + + 4. Case 2 - Hierarchy of DBo Derived Classes — Coriolis 2 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+
+
+ +
+
+
+ +

+
+

4. Case 2 - Hierarchy of DBo Derived Classes

+

Now we want to export the following C++ class hierarchy into Python:

+
PyEntity <-- PyComponent <-+- PyContact
+                           +- PySegment <-+- PyHorizontal
+                                          +- PyVertical
+
+
+

4.1 Base Class Header

+

Remark: this is only a partial description of the tree for the sake of +clarity.

+

One important fact to remember is that PyEntity and PyComponent +being related to C++ abstract classes, no objects of those types will be +created, only PyContact, PyHorizontal or PyVertical will.

+

The consequence is that there is no PyEntity_Link() like in 3.1 Class Associated Header File +but instead two functions:

+
    +
  1. PyEntity_NEW() which create the relevant PyEntity derived +object from the Entity one. For example, if the Entity* given +as argument is in fact a Horizontal*, then the function will +return a PyHorizontal*.
  2. +
  3. EntityCast() do the reverse of PyEntity_NEW() that is, from +a PyEntity, return the C++ derived object. Again, if the +PyEntity* is a PyHorizontal*, the function will cast it as +a Horizontal* then return it as an Entity*.
  4. +
+
#ifndef ISOBAR_PY_ENTITY_H
+#define ISOBAR_PY_ENTITY_H
+
+#include "hurricane/isobar/PyHurricane.h"
+#include "hurricane/Entity.h"
+
+namespace  Isobar {
+  extern "C" {
+
+    typedef struct {
+        PyObject_HEAD
+        Hurricane::Entity* _object;
+    } PyEntity;
+
+    extern  PyObject*     PyEntity_NEW        ( Hurricane::Entity* entity );
+    extern  void          PyEntity_LinkPyType ();
+    extern  PyTypeObject  PyTypeEntity;
+    extern  PyMethodDef   PyEntity_Methods[];
+
+
+#define IsPyEntity(v)    ( (v)->ob_type == &PyTypeEntity )
+#define PYENTITY(v)      ( (PyEntity*)(v) )
+#define PYENTITY_O(v)    ( PYENTITY(v)->_object )
+
+  }  // extern "C".
+
+  Hurricane::Entity*  EntityCast ( PyObject* derivedObject );
+
+}  // Isobar namespace.
+
+#endif  // ISOBAR_PY_ENTITY_H
+
+
+

+
+
+

4.2 Base Class File

+

Changes from 3.2 Class Associated File are:

+
    +
  1. No call to DBoLinkCreateMethod() because there must be no PyEntity_Link(), +but the definitions of PyEntity_NEW() and EntityCast.
  2. +
  3. For defining the PyTypeEntity Python type, we call a different +macro: PyTypeRootObjectDefinitions, dedicated to base classes.
  4. +
+
#include "hurricane/isobar/PyCell.h"
+#include "hurricane/isobar/PyHorizontal.h"
+#include "hurricane/isobar/PyVertical.h"
+#include "hurricane/isobar/PyContact.h"
+
+namespace Isobar {
+  using namespace Hurricane;
+
+  extern "C" {
+
+#if defined(__PYTHON_MODULE__)
+
+#define  METHOD_HEAD(function)   GENERIC_METHOD_HEAD(Entity,entity,function)
+
+    DBoDestroyAttribute(PyEntity_destroy ,PyEntity)
+
+    static PyObject* PyEntity_getCell ( PyEntity *self )
+    {
+      Cell* cell = NULL;
+      HTRY
+        METHOD_HEAD( "Entity.getCell()" )
+        cell = entity->getCell();
+      HCATCH
+      return PyCell_Link( cell );
+    }
+
+    PyMethodDef PyEntity_Methods[] =
+      { { "getCell", (PyCFunction)PyEntity_getCell, METH_NOARGS
+                   , "Returns the entity cell." }
+      , { "destroy", (PyCFunction)PyEntity_destroy, METH_NOARGS
+                   , "Destroy associated hurricane object, the python object remains." }
+      , {NULL, NULL, 0, NULL}  /* sentinel */
+      };
+
+
+    DBoDeleteMethod(Entity)
+    PyTypeObjectLinkPyType(Entity)
+
+#else  // End of Python Module Code Part.
+
+    PyObject* PyEntity_NEW ( Entity* entity )
+    {
+      if (not entity) {
+        PyErr_SetString ( HurricaneError, "Invalid Entity (bad occurrence)" );
+        return NULL;
+      }
+
+      Horizontal* horizontal = dynamic_cast<Horizontal*>(entity);
+      if (horizontal) return PyHorizontal_Link( horizontal );
+
+      Vertical* vertical = dynamic_cast<Vertical*>(entity);
+      if (vertical) return PyVertical_Link( vertical );
+
+      Contact* contact = dynamic_cast<Contact*>(entity);
+      if (contact) return PyContact_Link( contact );
+
+      Py_RETURN_NONE;
+    }
+
+    PyTypeRootObjectDefinitions(Entity)
+
+#endif  // Shared Library Code Part (1).
+
+}  // extern "C".
+
+
+#if !defined(__PYTHON_MODULE__)
+
+Hurricane::Entity* EntityCast ( PyObject* derivedObject ) {
+  if (IsPyHorizontal(derivedObject)) return PYHORIZONTAL_O(derivedObject);
+  if (IsPyVertical  (derivedObject)) return PYVERTICAL_O(derivedObject);
+  if (IsPyContact   (derivedObject)) return PYCONTACT_O(derivedObject);
+  return NULL;
+}
+
+#endif  // Shared Library Code Part (2).
+
+}  // Isobar namespace.
+
+
+

+
+
+

4.3 Intermediate Class Header

+

Changes from 3.1 Class Associated Header File are:

+
    +
  1. As for PyEntity, and because this is still an abstract class, +there is no PyComponent_Link() function.
  2. +
  3. The definition of the PyComponent struct is differs. There is +no PyObject_HEAD (it is a Python derived class). The only +field is of the base class type PyEntity and for use with +Coriolis macros, it must be named _baseObject (note that +this is not a pointer but a whole object).
  4. +
+
#ifndef ISOBAR_PY_COMPONENT_H
+#define ISOBAR_PY_COMPONENT_H
+
+#include "hurricane/isobar/PyEntity.h"
+#include "hurricane/Component.h"
+
+namespace  Isobar {
+  extern "C" {
+
+    typedef struct {
+        PyEntity  _baseObject;
+    } PyComponent;
+
+    extern  PyTypeObject  PyTypeComponent;
+    extern  PyMethodDef   PyComponent_Methods[];
+    extern  void          PyComponent_LinkPyType ();
+
+#define IsPyComponent(v) ((v)->ob_type == &PyTypeComponent)
+#define PYCOMPONENT(v)   ((PyComponent*)(v))
+#define PYCOMPONENT_O(v) (static_cast<Component*>(PYCOMPONENT(v)->_baseObject._object))
+
+  }  // extern "C".
+}  // Isobar namespace.
+
+#endif
+
+
+
+
+

4.4 Intermediate Class File

+

Changes from 3.2 Class Associated File are:

+
    +
  1. Redefinition of the default macros ACCESS_OBJECT and ACCESS_CLASS.
      +
    • The pointer to the C++ encapsulated object (attribute _object) is hold +by the base class PyEntity. The ACCESS_OBJECT macro which is tasked +to give access to that attribute is then _baseObject._object as +PyComponent is a direct derived class of PyEntity.
    • +
    • ACCESS_CLASS is similar to ACCESS_OBJECT for accessing the base +class, that is a pointer to PyEntity.
    • +
    +
  2. +
+

+
    +
  1. For defining the PyTypeComponent Python type, we call a yet different +macro: PyTypeInheritedObjectDefinitions(), dedicated to derived classes. +For this this macro we need to give as argument the derived class and the +base class.
  2. +
+
#include "hurricane/isobar/PyComponent.h"
+#include "hurricane/isobar/PyNet.h"
+
+namespace  Isobar {
+  using namespace Hurricane;
+
+  extern "C" {
+
+#undef   ACCESS_OBJECT
+#undef   ACCESS_CLASS
+#define  ACCESS_OBJECT           _baseObject._object
+#define  ACCESS_CLASS(_pyObject)  &(_pyObject->_baseObject)
+#define  METHOD_HEAD(function)   GENERIC_METHOD_HEAD(Component,component,function)
+
+#if defined(__PYTHON_MODULE__)
+
+    DirectGetLongAttribute(PyComponent_getX,getX,PyComponent,Component)
+    DirectGetLongAttribute(PyComponent_getY,getY,PyComponent,Component)
+    DBoDestroyAttribute(PyComponent_destroy,PyComponent)
+
+    static PyObject* PyComponent_getNet ( PyComponent *self )
+    {
+      Net* net = NULL;
+      HTRY
+        METHOD_HEAD( "Component.getNet()" )
+        net = component->getNet( );
+      HCATCH
+      return PyNet_Link( net );
+    }
+
+    PyMethodDef PyComponent_Methods[] =
+      { { "getX"   , (PyCFunction)PyComponent_getX   , METH_NOARGS
+                   , "Return the Component X value." }
+      , { "getY"   , (PyCFunction)PyComponent_getY   , METH_NOARGS
+                   , "Return the Component Y value." }
+      , { "getNet" , (PyCFunction)PyComponent_getNet , METH_NOARGS
+                   , "Returns the net owning the component." }
+      , { "destroy", (PyCFunction)PyComponent_destroy, METH_NOARGS
+                   , "destroy associated hurricane object, the python object remains." }
+      , {NULL, NULL, 0, NULL}    /* sentinel */
+      };
+
+    DBoDeleteMethod(Component)
+    PyTypeObjectLinkPyType(Component)
+
+#else  // Python Module Code Part.
+
+    PyTypeInheritedObjectDefinitions(Component, Entity)
+
+#endif  // Shared Library Code Part.
+
+  }  // extern "C".
+}  // Isobar namespace.
+
+
+
+
+

4.5 Terminal Class Header

+

The contents of this file is almost identical to 4.3 Intermediate Class Header, +save for the presence of a PyContact_Link() function. She is present +at this level because the class is a concrete one and can be instanciated.

+
#ifndef ISOBAR_PY_CONTACT_H
+#define ISOBAR_PY_CONTACT_H
+
+#include "hurricane/isobar/PyComponent.h"
+#include "hurricane/Contact.h"
+
+namespace  Isobar {
+  extern "C" {
+
+    typedef struct {
+      PyComponent _baseObject;
+    } PyContact;
+
+    extern PyTypeObject  PyTypeContact;
+    extern PyMethodDef   PyContact_Methods[];
+    extern PyObject*     PyContact_Link       ( Hurricane::Contact* object );
+    extern void          PyContact_LinkPyType ();
+
+#define IsPyContact(v)    ( (v)->ob_type == &PyTypeContact )
+#define PYCONTACT(v)      ( (PyContact*)(v) )
+#define PYCONTACT_O(v)    ( PYCONTACT(v)->_baseObject._baseObject._object )
+
+  }  // extern "C".
+}  // Isobar namespace.
+
+#endif  // ISOBAR_PY_CONTACT_H
+
+
+
+
+

4.6 Terminal Class File

+

Changes from 4.4 Intermediate Class File are:

+
    +
  1. As previously, we have to redefine the macros ACCESS_OBJECT and ACCESS_CLASS. +But, as we are one level deeper into the hierarchy, one more level of +indirection using _baseObject must be used.
      +
    • ACCESS_OBJECT becomes _baseObject._baseObject._object.
    • +
    • ACCESS_CLASS becomes &(_pyObject->_baseObject._baseObject).
    • +
    +
  2. +
  3. For defining the PyTypeContact Python type, we call again +PyTypeInheritedObjectDefinitions(). It is the same whether the class is +terminal or not.
  4. +
  5. And, this time, as the Python class is concrete, we call the macro +DBoLinkCreateMethod() to create the PyContact_Link() function.
  6. +
+
#include "hurricane/isobar/PyContact.h"
+
+namespace  Isobar {
+  using namespace Hurricane;
+
+  extern "C" {
+
+#undef  ACCESS_OBJECT
+#undef  ACCESS_CLASS
+#define ACCESS_OBJECT           _baseObject._baseObject._object
+#define ACCESS_CLASS(_pyObject) &(_pyObject->_baseObject._baseObject)
+#define METHOD_HEAD(function)   GENERIC_METHOD_HEAD(Contact,contact,function)
+
+#if defined(__PYTHON_MODULE__)
+
+    DirectGetLongAttribute(PyContact_getWidth , getWidth , PyContact,Contact)
+    DirectGetLongAttribute(PyContact_getHeight, getHeight, PyContact,Contact)
+    DBoDestroyAttribute(PyContact_destroy, PyContact)
+
+    static PyObject* PyContact_create ( PyObject*, PyObject *args )
+    {
+      Contact* contact = NULL;
+      HTRY
+        // Usual signature then arguments parsing.
+      HCATCH
+      return PyContact_Link(contact);
+    }
+
+    PyMethodDef PyContact_Methods[] =
+      { { "create"   , (PyCFunction)PyContact_create   , METH_VARARGS|METH_STATIC
+                     , "Create a new Contact." }
+      , { "destroy"  , (PyCFunction)PyContact_destroy  , METH_NOARGS
+                     , "Destroy associated hurricane object, the python object remains." }
+      , { "getWidth" , (PyCFunction)PyContact_getWidth , METH_NOARGS
+                     , "Return the contact width." }
+      , { "getHeight", (PyCFunction)PyContact_getHeight, METH_NOARGS
+                     , "Return the contact height." }
+      , {NULL, NULL, 0, NULL}  /* sentinel */
+      };
+
+    DBoDeleteMethod(Contact)
+    PyTypeObjectLinkPyType(Contact)
+
+#else  // Python Module Code Part.
+
+    DBoLinkCreateMethod(Contact)
+    PyTypeInheritedObjectDefinitions(Contact, Component)
+
+#endif  // Shared Library Code Part.
+
+  }  // extern "C".
+}  // Isobar namespace.
+
+
+
+
+

4.8 Python Module

+
DL_EXPORT(void) initHurricane ()
+{
+  PyEntity_LinkPyType();  // step 1.
+  PyComponent_LinkPyType();
+  PyContact_LinkPyType();
+
+  PYTYPE_READY( Entity )  // step 2.
+  PYTYPE_READY_SUB( Component, Entity )
+  PYTYPE_READY_SUB( Contact  , Component )
+
+  __cs.addType( "ent"    , &PyTypeEntity   , "<Entity>"   , false ); // step 3.
+  __cs.addType( "comp"   , &PyTypeComponent, "<Component>", false, "ent"  );
+  __cs.addType( "contact", &PyTypeContact  , "<Contact>"  , false, "comp" );
+
+  PyObject* module = Py_InitModule( "Hurricane", PyHurricane_Methods );
+  if (module == NULL) {
+    cerr << "[ERROR]\n"
+         << "  Failed to initialize Hurricane module." << endl;
+    return;
+  }
+
+  Py_INCREF( &PyTypeContact );                                        // step 4.
+  PyModule_AddObject( module, "Contact", (PyObject*)&PyTypeContact ); // step 4.
+}
+
+
+
+
+ + +
+
+ + + + +
+ +
+ + + + + +
+ Generated by Sphinx + using a RTD theme on Jul 15, 2017. +
+ + + + + +
Coriolis 2 Documentation + © Copyright 2000-2017, UPMC. +
+
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/documentation/_build/html/PythonCpp/DBoStandalone.html b/documentation/_build/html/PythonCpp/DBoStandalone.html new file mode 100644 index 00000000..b0bc58cb --- /dev/null +++ b/documentation/_build/html/PythonCpp/DBoStandalone.html @@ -0,0 +1,669 @@ + + + + + + + + + + + + 3. Case 1 - DBo Derived, Standalone — Coriolis 2 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+
+
+ +
+
+
+ +
+

3. Case 1 - DBo Derived, Standalone

+

As example, we take Library. This a DBo derived class, but we +choose not to export the parent classes. From Python, it will appear +as a base class.

+
+

3.1 Class Associated Header File

+

Here is the typical content of a header file (for PyLibrary):

+
#ifndef  PY_LIBRARY_H
+#define  PY_LIBRARY_H
+
+#include "hurricane/isobar/PyHurricane.h"
+#include "hurricane/Library.h"
+
+namespace  Isobar {
+  using namespace Hurricane;
+
+  extern "C" {
+
+    typedef struct {
+        PyObject_HEAD
+        Library* _object;
+    } PyLibrary;
+
+    extern  PyTypeObject  PyTypeLibrary;
+    extern  PyMethodDef   PyLibrary_Methods[];
+    extern  PyObject*     PyLibrary_Link       ( Hurricane::Library* lib );
+    extern  void          PyLibrary_LinkPyType ();
+
+
+#define IsPyLibrary(v) ( (v)->ob_type == &PyTypeLibrary )
+#define PYLIBRARY(v)   ( (PyLibrary*)(v) )
+#define PYLIBRARY_O(v) ( PYLIBRARY(v)->_object )
+
+  }  // extern "C".
+}  // Isobar namespace.
+
+#endif  // PY_LIBRARY_H
+
+
+

The code is organized as follow:

+
    +
  1. It must have, as the first include PyHurricane.h, which provides +the complete bunch of macros needed to build the module. Then the include +of the C++ class we want to wrap (Library.h).

    +
  2. +
  3. As Python is written in C, all the wrapper code has to be but inside +an extern "C" namespace.

    +
  4. +
  5. Definition of the wrapped struct, PyLibrary. It is standard Python here.

    +
    +

    Note

    +

    For our set of macros to work, the name of the pointer to the +C++ class must always be _object, and the various functions and +macros defined here must take the name of the class (either in +lowercase, camel case or capitals).

    +
    +
  6. +
  7. Declaration of the Python type PyTypeLibrary (standard).

    +
  8. +
  9. Declaration of the Python type table of methods PyLibrary_Methods (standard).

    +
  10. +
+
    +
  1. Declaration of PyLibrary_Link(), helper to convert a C++ Lybrary into +a PyLibrary (put in the support shared library).
  2. +
  3. Declaration of PyLibrary_LinkPyType(), this function setup the class-level +function of the new Python type (here, PyTypeLibrary).
  4. +
  5. And, lastly, three macros to:
      +
    • IsPylibrary(), know if a Python object is a PyLibrary
    • +
    • PYLIBRARY(), force cast (C style) of a PyObject into a PyLibrary.
    • +
    • PYLIBRARY_O(), extract the C++ object (Library*) from the Python +object (PyLibrary).
    • +
    +
  6. +
+
+
+

3.2 Class Associated File

+
+

3.2.1 Head of the file

+
#include "hurricane/isobar/PyLibrary.h"
+#include "hurricane/isobar/PyDataBase.h"
+#include "hurricane/isobar/PyCell.h"
+
+namespace Isobar {
+  using namespace Hurricane;
+
+  extern "C" {
+
+#define  METHOD_HEAD(function)   GENERIC_METHOD_HEAD(Library,lib,function)
+
+
+

As for the header, all the code must be put inside a extern "C" namespace.

+

A convenience macro METHOD_HEAD() must be defined, by refining +GENERIC_METHOD_HEAD(). This macro will be used in the method wrappers +below to cast the _object field of the Python object into the +appropriate C++ class, this is done using a C-style cast. +The parameters of that macro are:

+
    +
  1. The C++ encapsulated class (Library).
  2. +
  3. The name of the variable that will be used to store a pointer +to the C++ working object.
  4. +
  5. The name of the C++ method which is to be wrapped.
  6. +
+
+
+

3.2.2 The Python Module Part

+

First, we have to build all the wrappers to the C++ methods of +the class. For common predicates, accessors, and mutators macros +are supplied.

+

Wrapping of the Library::getCell() method:

+
static PyObject* PyLibrary_getCell ( PyLibrary* self, PyObject* args )
+{
+  Cell* cell = NULL;
+
+  HTRY
+    METHOD_HEAD( "Library.getCell()" )
+    char* name = NULL;
+    if (PyArg_ParseTuple(args,"s:Library.getCell", &name)) {
+      cell = lib->getCell( Name(name) );
+    } else {
+      PyErr_SetString( ConstructorError
+                     , "invalid number of parameters for Library::getCell." );
+      return NULL;
+    }
+  HCATCH
+
+  return PyCell_Link(cell);
+}
+
+
+

Key points about this method wrapper:

+
    +
  1. The HTRY / HCATCH macros provides an insulation from the C++ +exceptions. If one is emitted, it will be catched and transformed in +a Python one. This way, the Python program will be cleanly interrupted +and the usual stack trace displayed.
  2. +
  3. The returned value of this method is of type Cell*, we have to +transform it into a Python one. This is done with PyCell_Link(). +This macro is supplied by the PyCell.h header and this is why +it must be included.
  4. +
+

+

Wrapping of the Library::create() method:

+
static PyObject* PyLibrary_create( PyObject*, PyObject* args )
+{
+  PyObject* arg0;
+  PyObject* arg1;
+  Library* library = NULL;
+
+  HTRY
+    __cs.init( "Library.create" );                          // Step (1).
+    if (not PyArg_ParseTuple( args, "O&O&:Library.create"
+                            , Converter, &arg0
+                            , Converter, &arg1 )) {         // Step (2).
+      PyErr_SetString( ConstructorError
+                     , "invalid number of parameters for Library constructor." );
+      return NULL;
+    }
+    if (__cs.getObjectIds() == ":db:string") {              // Step (3.a)
+      DataBase* db = PYDATABASE_O(arg0);
+      library = Library::create( db, Name(PyString_AsString(arg1)) );
+    } else if (__cs.getObjectIds() == ":library:string") {  // Step (3.b)
+      Library* masterLibrary = PYLIBRARY_O(arg0);
+      library = Library::create( masterLibrary, Name(PyString_AsString(arg1)) );
+    } else {
+      PyErr_SetString( ConstructorError
+                     , "invalid number of parameters for Library constructor." );
+      return NULL;
+    }
+  HCATCH
+
+  return PyLibrary_Link( library );
+}
+
+
+

Key point about this constructor:

+
    +
  1. We want the Python interface to mimic as closely as possible the +C++ API. As such, Python object will be created using a static +.create() method. So we do not use the usual Python allocation +mechanism.
  2. +
  3. As it is a static method, there is no first argument.
  4. +
  5. Python do not allow function overload like C++. To emulate that +behavior we use the __cs object (which is a global variable).
      +
    1. Init/reset the __cs object: see step (1).
    2. +
    3. Call PyArg_ParseTuple(), read every mandatory or optional +argument as a Python object ("O&") and use Converter +on each one. Converter will determine the real type of +the Python object given as argument by looking at the +encapsulated C++ class. It then update the __cs object. +Done in step (2)
    4. +
    5. After the call to PyArg_ParseTuple(), the function +__cs.getObjectIds() will return the signature of +the various arguments. In our case, the valid signatures +will be ":db:string" (step (3.a)*a) and ``”:library:string”`` +(*step (3.b)).
    6. +
    7. Call the C++ method after extracting the C++ objects from +the Python arguments. Note the use of the PYLIBRARY_O() +and PYDATABSE_O() macros to perform the conversion.
    8. +
    +
  6. +
  7. Return the result, encapsulated through a call to PyLibrary_Link().
  8. +
+

+

Wrapping of the Library::destroy() method:

+
DBoDestroyAttribute(PyLibrary_destroy, PyLibrary)
+
+
+

For C++ classes that are derived from DBo, the destroy method +wrapper must be defined using the macro DBoDestroyAttribute(). +This macro implements the bi-directional communication mechanism +using Hurricane::Property. It must not be used for +non DBo derived classes.

+

Defining the method table of the PyLibrary type:

+
PyMethodDef PyLibrary_Methods[] =
+  { { "create"    , (PyCFunction)PyLibrary_create , METH_VARARGS|METH_STATIC
+                  , "Creates a new library." }
+  , { "getCell"   , (PyCFunction)PyLibrary_getCell, METH_VARARGS
+                  , "Get the cell of name <name>" }
+  , { "destroy"   , (PyCFunction)PyLibrary_destroy, METH_NOARGS
+                  , "Destroy associated hurricane object The python object remains." }
+  , {NULL, NULL, 0, NULL}           /* sentinel */
+  };
+
+
+

This is standard Python/C API. The name of the PyMethodDef table must be +named from the class: PyLibrary_Methods.

+
+
+

3.2.3 Python Type Linking

+

Defining the PyTypeLibrary class methods and the type linking function.

+

Those are the functions for the Python object itself to work, not the +wrapped method from the C++ class.

+
+

Note

+

At this point we do not define the PyTypeLibrary itself. +Only it’s functions and a function to set them up once the +type will be defined.

+
+
DBoDeleteMethod(Library)
+PyTypeObjectLinkPyType(Library)
+
+
+

The macro DBoDeleteMethod() define the function to delete a +PyLibrary Python object. Again, do not mistake it for the deletion +of the C++ class (implemented by DBoDestroyAttribute()). +Here again, DBoDeleteMethod() is specially tailored for +DBo derived classes.

+

To define PyLibrary_LinkPyType(), use the PyTypeObjectLinkPyType() +macro. This macro is specific for DBo derived classes that are seen as +base classes under Python (i.e. we don’t bother exposing the base +class under Python). PyLibrary_LinkPyType() setup the class functions +in the PyTypeLibrary type object, it must be called in the +Python module this class is part of (in this case: PyHurricane.cpp). +This particular flavor of the macro will define and setup the +following class functions:

+
    +
  • PyTypeLibrary.tp_compare (defined by the macro).
  • +
  • PyTypeLibrary.tp_repr (defined by the macro).
  • +
  • PyTypeLibrary.tp_str (defined by the macro).
  • +
  • PyTypeLibrary.tp_hash (defined by the macro).
  • +
  • PyTypeLibrary.tp_methods sets to the previously defined PyLibrary_Methods table.
  • +
  • PyTypeLibrary.tp_dealloc is set to a function that must be named PyLibrary_DeAlloc, +this is what DBoDeleteMethod does. It is not done by PyTypeObjectLinkPyType.
  • +
+

Defining the PyTypeLibrary type:

+
+
+

3.2.4 The Shared Library Part

+

This part will be put in a separate supporting shared library, allowing +other Python module to link against it (and make use of its symbols).

+
DBoLinkCreateMethod(Library)
+PyTypeObjectDefinitions(Library)
+
+
+

To define PyTypeLibrary, use the PyTypeObjectDefinitions() macro. +This macro is specific for classes that, as exposed by Python, +are neither derived classes nor base classes for others. +That is, they are standalone from the inheritance point of view.

+

The DBoLinkCreateMethod() macro will define the PyLibrary_Link() +function which is responsible for encapsulating a C++ Library object +into a Python PyLibrary one.

+
+
+
+

3.3 Python Module (C++ namespace)

+

We use the Python module to replicate the C++ namespace. Thus, for the +Hurricane namespace we create a Python Hurricane module which is +defined in the PyHurricane.cpp file, then we add into that module +dictionary all the Python types encapsulating the C++ classes of that +namespace.

+
DL_EXPORT(void) initHurricane ()
+{
+  PyLibrary_LinkPyType();  // step 1.
+
+  PYTYPE_READY( Library )  // step 2.
+
+  __cs.addType( "library", &PyTypeLibrary, "<Library>", false ); // step 3.
+
+  PyObject* module = Py_InitModule( "Hurricane", PyHurricane_Methods );
+  if (module == NULL) {
+    cerr << "[ERROR]\n"
+         << "  Failed to initialize Hurricane module." << endl;
+    return;
+  }
+
+  Py_INCREF( &PyTypeLibrary );                                        // step 4.
+  PyModule_AddObject( module, "Library", (PyObject*)&PyTypeLibrary ); // step 4.
+}
+
+
+

The initHurricane() initialisation function shown above has +been scrubbed of everything not relevant to the PyLibrary class. +The integration of the PyLibrary class into the module needs +four steps:

+
    +
  1. A call to PyLibrary_LinkPyType() to hook the Python type functions +in the Python type object.

    +
  2. +
  3. A call to the PYTYPE_READY() macro (standard Python).

    +
  4. +
  5. Registering the type into the __cs object, with addType(). +The arguments are self explanatory, save for the last which is a +boolean to tell if this is a derived class or not.

    +
  6. +
  7. Adding the type object (PyTypeLibrary) into the dictionnary of +the module itself. This allow to mimic closely the C++ syntax:

    +
    import Hurricane
    +lib = Hurricane.Library.create( db, 'root' )
    +
    +
    +
  8. +
+
+
+ + +
+
+ + + + +
+ +
+ + + + + +
+ Generated by Sphinx + using a RTD theme on Jul 15, 2017. +
+ + + + + +
Coriolis 2 Documentation + © Copyright 2000-2017, UPMC. +
+
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/documentation/_build/html/PythonCpp/DbU.html b/documentation/_build/html/PythonCpp/DbU.html new file mode 100644 index 00000000..e1d1b95c --- /dev/null +++ b/documentation/_build/html/PythonCpp/DbU.html @@ -0,0 +1,383 @@ + + + + + + + + + + + + 6. Encapsulating DbU — Coriolis 2 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+
+
+ +
+
+
+ +
+

6. Encapsulating DbU

+

While Hurricane::DbU is a class, the Hurricane::DbU::Unit is only +a typedef over uint64_t. The DbU class only provides a set of +static methods to manipulate and convert to and from other units. +At Python level, DbU::Unit will be stored in plain long long.

+

When a DbU::Unit argument is expected in a Python functions, just use +the DbU::Unit  PyAny_AsLong( PyObject* ) function to convert it.

+

For example, if we explicit the expension of:

+
DirectSetLongAttribute(PyPoint_SetX,setX,PyPoint,Point)
+
+
+

+

We would get:

+
static PyObject* PyPoint_setX ( PyPoint *self, PyObject* args )
+{
+  Point* cobject = static_cast<Point*>( self->_object );
+  if (cobject == NULL) {
+    PyErr_SetString( ProxyError
+                   , "Attempt to call Point.setX() on an unbound Hurricane object" );
+    return NULL;
+  }
+
+  HTRY
+    PyObject* arg0 = NULL;
+    if (not PyArg_ParseTuple( args, "O:Point.setX()", &arg0 ))
+      return ( NULL );
+    cobject->setX( Isobar::PyAny_AsLong(arg0) );
+  HCATCH
+  Py_RETURN_NONE;
+}
+
+
+

For the other way around, use PyObject* PyDbU_FromLong( DbU::Unit ).

+
DirectGetLongAttribute(PyPoint_GetX,getX,PyPoint,Point)
+
+
+

We would get:

+
static PyObject* PyPoint_GetX ( PyPoint *self, PyObject* args )
+{
+  Point* cobject = static_cast<Point*>( self->_object );
+  if (cobject == NULL) {
+    PyErr_SetString( ProxyError
+                   , "Attempt to call Point.getX() on an unbound Hurricane object" );
+    return NULL;
+  }
+  return Isobar::PyDbU_FromLong(cobject->getX());
+}
+
+
+
+ + +
+
+ + + + +
+ +
+ + + + + +
+ Generated by Sphinx + using a RTD theme on Jul 15, 2017. +
+ + + + + +
Coriolis 2 Documentation + © Copyright 2000-2017, UPMC. +
+
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/documentation/_build/html/PythonCpp/Introduction.html b/documentation/_build/html/PythonCpp/Introduction.html new file mode 100644 index 00000000..b63d2391 --- /dev/null +++ b/documentation/_build/html/PythonCpp/Introduction.html @@ -0,0 +1,497 @@ + + + + + + + + + + + + 1. Introduction — Coriolis 2 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+
+
+ +
+
+
+ +
+

1. Introduction

+
    +
  • This document is written for people already familiar with the +Python/C API Reference Manual.
  • +
  • The macros provided by the Hurricane Python/C API are written using +the standard Python C/API. That is, you may not use them and write +directly your functions with the original API or any mix between. +You only have to respect some naming convention.
  • +
  • Coriolis is build against Python 2.7.
  • +
+
+

1.1 First, A Disclaimer

+

The Hurricane Python/C++ API has been written about ten years ago, at a time +my mastering of template programming was less than complete. This is why this +interface is build with old fashioned C macro instead of C++ template.

+

It is my hope that at some point in the future I will have time to completly +rewrite it, borrowing the interface from boost::python.

+
+
+

1.2 About Technical Choices

+

Some would say, why not use off the shelf wrappers like swig +or boost::python, here are some clues.

+
    +
  1. Partial exposure of the C++ class tree. We expose at Python level +C++ base classes, only if they provides common methods that we want +to see. Otherwise, we just show them as base classes under Python. +For instance Library is derived from DBo, but we won’t see +it under Python.

    +
  2. +
  3. Bi-directional communication. When a Python object is deleted, the +wrapper obviously has a pointer toward the underlying C++ object and +is able to delete it. But, the reverse case can occurs, meaning that +you have a C++ object wrapped in Python and the database delete the +underlying object. The wrapped Python object must be informed that +it no longer refer a valid C++ one. Moreover, as we do not control +when Python objects gets deleteds (that is, when their reference count +reaches zero), we can have valid Python object with a dangling +C++ pointer. So our Python objects can be warned by the C++ objects +that they are no longer valid and any other operation than the +deletion should result in a severe non-blocking error.

    +

    To be precise, this apply to persistent object in the C++ database, +like Cell, Net, Instance or Component. Short lived +objects like Box or Point retains the classic Python behavior.

    +

    Another aspect is that, for all derived DBo objects, one and only +one Python object is associated. For one given Instance object we +will always return the same PyInstance object, thanks to the +bi-directional link. Obviously, the reference count of the +PyInstance is managed accordingly. This mechanism is implemented +by the PyInstance_Link() function.

    +
  4. +
  5. Linking accross modules. As far as I understand, the wrappers +are for monolithic libraries. That is, you wrap the entire library +in one go. But Hurricane has a modular design, the core database +then various tools. We do not, and cannot, have one gigantic wrapper +that would encompass all the libraries in one go. We do one Python +module for one C++ library.

    +

    This brings another issue, at Python level this time. The Python +modules for the libraries have to share some functions. Python +provides a mechanism to pass C function pointers accross modules, +but I did found it cumbersome. Instead, all our modules are split +in two:

    +
      +
    • The first part contains the classic Python module code.
    • +
    • The second part is to be put in a separate dynamic library that +will hold the shared functions. The Python module is dynamically linked +against that library like any other. And any other Python module +requiring the functions will link against the associated shared +library.
    • +
    +

    Each module file will be compiled twice, once to build the Python +module (__PYTHON_MODULE is defined) and once to build the supporting +shared library (__PYTHON_MODULE__ not defined). This tricky +double compilation is taken care of though the add_python_module +cmake macro.

    +

    For the core Hurricane library we will have:

    +
      +
    • Hurricane.so the Python module (use with: import Hurricane).
    • +
    • libisobar.so.1.0 the supporting shared library.
    • +
    +

    The PyLibrary.cpp file will have the following structure:

    +
    #include "hurricane/isobar/PyLibrary.h"
    +
    +namespace  Isobar {
    +
    +  extern "C" {
    +
    +#if defined(__PYTHON_MODULE__)
    +
    +  // +=================================================================+
    +  // |               "PyLibrary" Python Module Code Part               |
    +  // +=================================================================+
    +  //
    +  // The classic part of a Python module. Goes into Hurricane.so.
    +
    +
    +#else  // End of Python Module Code Part.
    +
    +  // x=================================================================x
    +  // |              "PyLibrary" Shared Library Code Part               |
    +  // x=================================================================x
    +  //
    +  // Functions here will be part of the associated shared library and
    +  // made available to all other Python modules. Goes into libisobar.so.1.0
    +
    +
    +# endif  // Shared Library Code Part.
    +
    +  }  // extern "C".
    +
    +}  // Isobar namespace.
    +
    +
    +

    This way, we do not rely upon a pointer transmission through Python +modules, but directly uses linker capabilities.

    +
  6. +
+
+
+

1.3 Botched Design

+

The mechanism to compute the signature of a call to a Python function, +the __cs object, is much too complex and, in fact, not needed. +At some point I may root it out, but it is used in so many places...

+

What I should have used the "O!" capablity of PyArg_ParseTuple(), +like in the code below:

+

+
static PyObject* PyContact_create ( PyObject*, PyObject *args )
+{
+  Contact* contact = NULL;
+  HTRY
+    PyNet*       pyNet       = NULL;
+    PyLayer*     pyLayer     = NULL;
+    PyComponent* pyComponent = NULL;
+    DbU::Unit    x           = 0;
+    DbU::Unit    y           = 0;
+    DbU::Unit    width       = 0;
+    DbU::Unit    height      = 0;
+
+    if (PyArg_ParseTuple( args, "O!O!ll|ll:Contact.create"
+                        , &PyTypeNet  , &pyNet
+                        , &PyTypeLayer, &pyLayer
+                        , &x, &y, &width, &height)) {
+      contact = Contact::create( PYNET_O(pyNet), PYLAYER_O(pyLayer)
+                               , x, y, width, height );
+    } else {
+      PyErr_Clear();
+      if (PyArg_ParseTuple( args, "O!O!ll|ll:Contact.create"
+                          , &PyTypeComponent, &pyComponent
+                          , &PyTypeLayer    , &pyLayer
+                          , &x, &y, &width, &height)) {
+        contact = Contact::create( PYCOMPONENT_O(pyComponent), PYLAYER_O(pyLayer)
+                                 , x, y, width, height );
+      } else {
+        PyErr_SetString( ConstructorError
+                       , "invalid number of parameters for Contact constructor." );
+        return NULL;
+      }
+    }
+  HCATCH
+  return PyContact_Link( contact );
+}
+
+
+
+
+ + +
+
+ + + + +
+ +
+ + + + + +
+ Generated by Sphinx + using a RTD theme on Jul 15, 2017. +
+ + + + + +
Coriolis 2 Documentation + © Copyright 2000-2017, UPMC. +
+
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/documentation/_build/html/PythonCpp/Name.html b/documentation/_build/html/PythonCpp/Name.html new file mode 100644 index 00000000..84b19d21 --- /dev/null +++ b/documentation/_build/html/PythonCpp/Name.html @@ -0,0 +1,336 @@ + + + + + + + + + + + + 7. No C++ Hurricane::Name encapsulation — Coriolis 2 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+
+
+ +
+
+
+ +
+

7. No C++ Hurricane::Name encapsulation

+

To be written.

+
+ + +
+
+ + + + +
+ +
+ + + + + +
+ Generated by Sphinx + using a RTD theme on Jul 15, 2017. +
+ + + + + +
Coriolis 2 Documentation + © Copyright 2000-2017, UPMC. +
+
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/documentation/_build/html/PythonCpp/NonDBo.html b/documentation/_build/html/PythonCpp/NonDBo.html new file mode 100644 index 00000000..857508c6 --- /dev/null +++ b/documentation/_build/html/PythonCpp/NonDBo.html @@ -0,0 +1,486 @@ + + + + + + + + + + + + 5. Case 3 - Non-DBo Standalone Classe — Coriolis 2 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+
+
+ +
+
+
+ +
+

5. Case 3 - Non-DBo Standalone Classe

+

Let’s have a look at the encapsulation of Hurricane::Point.

+

Non-BDo derived classes do not support the bi-directionnal communication. +So each Python object is associated with one C++ object. The C++ object +is created and deleted along with the Python one. This behavior implies +that the C++ object is copy constructible (which should be the case).

+
+

5.1 Class Header

+

Changes from 3.1 Class Associated Header File:

+
    +
  • There is no PyPoint_Link() function, as it’s related to the +bi-directional communication mechanism.
  • +
+
+

Note

+

About the _object attribute of the PyPoint. As the C++ object life span +(Point) is linked to the Python (PyPoint) one, we may have used a +value instead of a pointer. It is best to keep a pointer as the macros +written for DBo derived classes will remain usables.

+
+
#ifndef ISOBAR_PY_POINT_H
+#define ISOBAR_PY_POINT_H
+
+#include "hurricane/isobar/PyHurricane.h"
+#include "hurricane/Point.h"
+
+namespace  Isobar {
+  extern "C" {
+
+    typedef struct {
+        PyObject_HEAD
+        Hurricane::Point* _object;
+    } PyPoint;
+
+    extern  PyTypeObject  PyTypePoint;
+    extern  PyMethodDef   PyPoint_Methods[];
+    extern  void          PyPoint_LinkPyType();
+
+#define IsPyPoint(v)    ( (v)->ob_type == &PyTypePoint )
+#define PYPOINT(v)      ( (PyPoint*)(v) )
+#define PYPOINT_O(v)    ( PYPOINT(v)->_object )
+
+  }  // extern "C".
+}  // Isobar namespace.
+
+#endif  // ISOBAR_PY_POINT_H
+
+
+

+
+
+

5.2 Class File

+

Changes from 3.2 Class Associated File:

+
    +
  • As there is no PyPoint_Link() function, there is no call to any +flavor of the DBoLinkcreatemethod() macro (obvious as it’s not +a DBo).
  • +
  • To use the standard Python constructor, we have to define PyPoint_NEW() +and PyPoint_Init() functions, I’m not absolutely certain that the later +needs to be defined (that part is still not clear to me from the Python doc).
  • +
  • As it’s not a DBo there is no destroy() method, so no call to +DirectDestroyMethod()
  • +
  • Lastly, as this object has a PyPoint_NEW() (field tp_new) and +a PyPoint_Init() (field tp_init) we have to use the macro +PyTypeObjectLinkPyTypeNewInit() to define PyPoint_LinkPyType().
  • +
+
#include "hurricane/isobar/PyPoint.h"
+
+namespace Isobar {
+  using namespace Hurricane;
+
+  extern "C" {
+
+#define METHOD_HEAD(function)   GENERIC_METHOD_HEAD(Point,point,function)
+
+#if defined(__PYTHON_MODULE__)
+
+    static PyObject* PyPoint_NEW ( PyObject* module, PyObject *args )
+    {
+      Point* point = NULL;
+      HTRY
+        PyObject* arg0 = NULL;
+        PyObject* arg1 = NULL;
+
+        __cs.init( "Point.Point" );
+        if (not PyArg_ParseTuple( args,"|O&O&:Point.Point"
+                                , Converter,&arg0
+                                , Converter,&arg1 )) {
+          PyErr_SetString ( ConstructorError
+                          , "invalid number of parameters for Point constructor." );
+          return NULL;
+        }
+
+        if      (__cs.getObjectIds() == "")
+                { point = new Point()); }
+        else if (__cs.getObjectIds() == ":point")
+                { point = new Point( *PYPOINT_O(arg0) ); }
+        else if (__cs.getObjectIds() == ":int:int")
+                { point = new Point( PyAny_AsLong(arg0), PyAny_AsLong(arg1) ); }
+        else {
+          PyErr_SetString ( ConstructorError
+                          , "invalid number of parameters for Point constructor." );
+          return NULL;
+        }
+
+        PyPoint* pyPoint = PyObject_NEW( PyPoint, &PyTypePoint );
+        if (pyPoint == NULL) { delete point; return NULL; }
+        pyPoint->_object = point;
+      HCATCH
+
+      return (PyObject*)pyPoint;
+    }
+
+    static int  PyPoint_Init ( PyPoint* self, PyObject* args, PyObject* kwargs )
+    { return 0; }
+
+    DirectGetLongAttribute(PyPoint_getX,getX,PyPoint,Point)
+    DirectGetLongAttribute(PyPoint_getY,getY,PyPoint,Point)
+    DirectSetLongAttribute(PyPoint_SetX,setX,PyPoint,Point)
+    DirectSetLongAttribute(PyPoint_SetY,setY,PyPoint,Point)
+
+    PyMethodDef PyPoint_Methods[] =
+      { { "getX"   , (PyCFunction)PyPoint_getX     , METH_NOARGS
+                   , "Return the Point X value." }
+      , { "getY"   , (PyCFunction)PyPoint_getY     , METH_NOARGS
+                   , "Return the Point Y value." }
+      , { "setX"   , (PyCFunction)PyPoint_SetX     , METH_VARARGS
+                   , "Modify the Point X value." }
+      , { "setY"   , (PyCFunction)PyPoint_SetY     , METH_VARARGS
+                   , "Modify the Point Y value." }
+      , {NULL, NULL, 0, NULL}  /* sentinel */
+      };
+
+    DirectDeleteMethod(PyPoint_DeAlloc,PyPoint)
+    PyTypeObjectLinkPyTypeNewInit(Point)
+
+#else  // Python Module Code Part.
+
+    PyTypeObjectDefinitions(Point)
+
+#endif  // Shared Library Code Part.
+
+  }  // extern "C".
+}  // Isobar namespace.
+
+
+
+
+

5.2 Class File

+

To put it bluntly, there is no difference in the Python module for +a standalone DBo class and a non-DBo class.

+
+
+ + +
+
+ + + + +
+ +
+ + + + + +
+ Generated by Sphinx + using a RTD theme on Jul 15, 2017. +
+ + + + + +
Coriolis 2 Documentation + © Copyright 2000-2017, UPMC. +
+
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/documentation/_build/html/PythonCpp/index.html b/documentation/_build/html/PythonCpp/index.html new file mode 100644 index 00000000..f475e012 --- /dev/null +++ b/documentation/_build/html/PythonCpp/index.html @@ -0,0 +1,368 @@ + + + + + + + + + + + + Hurricane Python/C++ API Tutorial — Coriolis 2 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/documentation/_build/html/RDS/RDSpage.html b/documentation/_build/html/RDS/RDSpage.html new file mode 100644 index 00000000..5cba7b2e --- /dev/null +++ b/documentation/_build/html/RDS/RDSpage.html @@ -0,0 +1,784 @@ + + + + + + + + + + + + Symbolic Layout — Coriolis 2 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+
+
+ +
+
+
+ +

+
+

Symbolic Layout

+
+

Symbolic Components

+

A symbolic layout is, in practice, made of only of three objects:

+ +++++ + + + + + + + + + + + + + + + + + + + + +
ObjectmbkExplanation
SegmentsphsegOriented segments with a width and an orientation.
VIAs & contactsphviaBoils down to just a point.
Big VIAs & Big ContactsphviaPoint with a width and a height +That is a rectangle of width by height centered +on the VIA coordinates.
+

Each of thoses objects is associated to a symbolic layer which will +control how the object is translated in many real rectangles.

+ ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
mbkLayer NameUsable ByUsage
phsegnwellSegmentN Well
PWELLSegmentP Well
NDIFSegmentN Diffusion
PDIFSegmentP Diffusion
NTIESegmentN Tie
PTIESegmentP Tie
NTRANSSegmentN transistor, in Alliance, a transistor +is represented as a segment (it’s grid).
PTRANSSegmentP transistor
POLYSegmentPolysilicium
ALUxSegmentMetal level x
CALUxSegmentMetal level x, that can be used by the +upper hierarchical level as a connector. +From the layout point of view it is the +same as ALUx.
TALUxSegmentBlockage for metal level x. Will +diseappear in the real layout as it is an +information for the P&R tools only.
phviaCONT_BODY_NVIA, BIGVIAContact to N Well
CONT_BODY_PVIA, BIGVIAContact to P Well
CONT_DIF_NVIA, BIGVIAContact to N Diffusion
CONT_DIF_PVIA, BIGVIAContact to P Diffusion
CONT_POLYVIA, BIGVIAContact to polysilicium
CONT_VIAVIA, BIGVIAContact between metal1 and metal2
CONT_VIAxVIA, BIGVIAContact between metal x and metal x+1. +The index is the the one of the bottom +metal of the VIA.
C_X_NVIAN transistor corner, to build transistor +bend. Not used anymore in recent technos
C_X_PVIAP transistor corner, to build transistor +bend. Not used anymore in recent technos
+
+

Note

+

Not all association of object and symbolic layers are meaningful. +For instance you cannot associate a contact to a NTRANS layer.

+
+
+

Note

+

The symbolic layer associated with blockages is prefixed by a T, +for transparency, which may seems silly. It is for historical reasons, +it started as a true transparency, but at some point we had to invert +the meaning (blockage) with the rise of over-the-cell routing, but the +name stuck...

+
+
+
+

Symbolic Segments

+

In Alliance, segments are oriented (up, down, left, right). This disambiguate +the left or right side when using the LCW and RCW rules in the rds file. +It allows to generate, if needed, asymetric object in the real layout file.

+

Symbolic Segment Orientations

+

+
+
+
+

The RDS File

+

The RDS file control how a symbolic layout is transformed into it’s real +conterpart.

+
+

Note

+

Unit used inside the RDS file: all units are expressed in micrometers.

+
+

Alliance tools relying on the RDS file, and what layers are active for them:

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + +
ToolNameRDS Flags
Layout editorgraalALL
Design Rule CheckerdrucALL, DRC
Electrical extractorcougarALL, EXT
The symbolic to real layout translators2rALL
+
+

Physical Grid & Lambda Value

+

RDS file:

+
DEFINE  PHYSICAL_GRID  0.005
+DEFINE  LAMBDA         0.09
+
+

Tells that the physical grid (founder grid) step is 0.005µm and the lambda has +a value of 0.09µm. That is, one lambda is 18 grid steps.

+

We can distinguish two kind of rds files:

+
    +
  • The 1µm kind, odd segment widths and coordinates are allowed, but the LAMBDA +value must represent an even number of foundry grid step.
  • +
  • The 2µm kind, segments widths and coordinates must all be even. And in that case +the LAMBDA value can be any multiple of the foundry grid.
  • +
+
+
+

The MBK_TO_RDS_SEGMENT table

+

The MBK_TO_RDS_SEGMENT table control the way segments are translated into +real rectangles. Be aware that we are translating segments and not rectangles. +Segments are defined by their axis (source & target points) and their width. +The geometrical transformations are described according to that model. +Obviously, they are either horizontal or vertical.

+

The translation method of a symbolic segment is as follow:

+
    +
  1. The segment is translated into one or more physical rectangles. +The generated rectangles depends on the tool which is actually +using rds and the flag for the considered real layer. +For instance, real layers flagged with DRC will be generated +for s2r (for the cif or gds) and druc, but will not +be shown under graal.

    +
  2. +
  3. Translation into one real layer. First the source & target coordinates and width +of the symbolic segment are multiplied by the LAMBDA value to obtain a real +segment. Then one of the VW, LCW or RCW transformation is applied to +that segment to get the final real rectangle.

    +
      +
    • VW for Variable Width, expand the real layer staying centered from the +original one. In those rules, the third number is not used, it is only here +to make the life easier for the parser...

      +

      RDS Variable Width Rule

      +
    • +
    • LCW or RCW for Left/Right Constant Width, create an off-center rectangle +of fixed width relatively to the real segment. Note that the SP number +is the distance between the edge of the real segment and the edge of the +generated real rectangle (not from the axis). It is often zero.

      +

      RDS Left Constant Width Rule

      +
    • +
    +
  4. +
+

+

Examples:

+
TABLE MBK_TO_RDS_SEGMENT
+
+    # (Case 1)
+    ALU1       RDS_ALU1   VW  0.18  0.09  0.0  ALL
+
+    # (Case 2)
+    NDIF       RDS_NDIF   VW  0.18  0.0   0.0  ALL \
+               RDS_ACTIV  VW  0.18  0.0   0.0  DRC \
+               RDS_NIMP   VW  0.36  0.36  0.0  DRC
+
+    # (Case 3)
+    NTRANS     RDS_POLY   VW  0.27  0.00  0.0  ALL \
+               RDS_GATE   VW  0.27  0.00  0.0  DRC \
+               RDS_NDIF  LCW  0.0   0.27  0.0  EXT \
+               RDS_NDIF  RCW  0.0   0.27  0.0  EXT \
+               RDS_NDIF   VW  0.0   0.72  0.0  DRC \
+               RDS_ACTIV  VW  0.0   0.72  0.0  ALL \
+               RDS_NIMP   VW  0.18  1.26  0.0  DRC
+
+END
+
+

Case 1 the ALU1 is translated in exacltly one real rectangle of +RDS_ALU1, both ends are extended by 0.18µm and it’s width is increased +by 0.09µm.

+

Case 2 the NDIF will be translated into only one segment +under graal, for symbolic visualization. And into three real rectangles +for s2r and druc.

+

Case 3 the NTRANS, associated to a transistor is a little bit +more complex, the generated shapes are different for the extractor cougar +in one hand, and for both druc & s2r in the other hand.

+
    +
  • For the extractor (EXT & ALL flags) there will be four rectangles +generateds:

    +
      +
    1. The gate (RDS_GATE)
    2. +
    3. The left diffusion of the transistor (source or drain) (RDS_NDIF).
    4. +
    5. The right diffusion of the transistor (drain or source) (RDS_NDIF).
    6. +
    7. The active area (RDS_ACTIV).
    8. +
    +

    As the extractor must kept separate the source and the drain of the transistor, +they are generated as two offset rectangles, using the LCW and RCW directives.

    +
  • +
  • For s2r and druc (DRC and ALL), five rectangles are generateds:

    +
      +
    1. The poly (RDS_POLY).
    2. +
    3. The gate (RDS_GATE).
    4. +
    5. The diffusion, as one rectangle that covers both the LCW and the RCW (RDS_NDIF).
    6. +
    7. The active area (RDS_ACTIV).
    8. +
    9. The N implantation (RDS_NIMP).
    10. +
    +

    In the layout send to the foundry, the source & drain are draw as one rectangle +across the gate area (the transistor being defined by the intersection of both +rectangles).

    +
  • +
+

+
+
+

The MBK_TO_RDS_VIA table

+

This table is to translate default VIAs into real via. In the symbolic layout +the default VIA is simply a point and a set of layers. All layers are converted +in squares shapes centered on the VIA coordinate. The one dimension given is the +size of the side of that square.

+

Note that although we are refering to VIAs, which for the purists are between two +metal layers, this table also describe contacts.

+

Example:

+
TABLE MBK_TO_RDS_VIA
+
+    CONT_DIF_P RDS_PDIF  0.54 ALL \
+               RDS_CONT  0.18 ALL \
+               RDS_ALU1  0.36 ALL \
+               RDS_ACTIV 0.54 DRC \
+               RDS_PIMP  0.90 DRC
+
+    CONT_POLY  RDS_POLY  0.54 ALL \
+               RDS_CONT  0.18 ALL \
+               RDS_ALU1  0.36 ALL
+
+    CONT_VIA   RDS_ALU1  0.45 ALL \
+               RDS_VIA1  0.27 ALL \
+               RDS_ALU2  0.45 ALL
+
+END
+
+
+

Note

+

In CONT_DIF_P you may see that only three layers will be shown under +graal, but five will be generated in the gds layout.

+
+
+
+

The MBK_TO_RDS_BIGVIA_HOLE table

+

In s2r, when generating BIGVIAs, the matrix of holes they contains is +not draw relative to the position of the BIGVIA itself, but on a grid which +is common througout all the design real layout. This is to allow overlap +between two BIGVIA without risking the holes matrix to be not exactly overlapping. +As a consequence, when visualizing the gds file, the holes may not be centerend +inside one individual BIGVIA.

+

The MBK_TO_RDS_BIGVIA_HOLE table define the global hole matrix for the whole +design. The first number is the individual hole side and the second the grid step +(edge to edge). The figure below show the hole generation.

+

BIGVIA holes

+

Example of BIGVIA overlap:

+

BIGVIA holes overlap

+

Example:

+
TABLE MBK_TO_RDS_BIGVIA_HOLE
+
+    CONT_VIA   RDS_VIA1 0.27 0.27 ALL
+    CONT_VIA2  RDS_VIA2 0.27 0.27 ALL
+    CONT_VIA3  RDS_VIA3 0.27 0.27 ALL
+    CONT_VIA4  RDS_VIA4 0.27 0.27 ALL
+    CONT_VIA5  RDS_VIA5 0.36 0.36 ALL
+
+END
+
+
+

Note

+

BIGVIA demotion. If the size of the bigvia is too small, there is +a possibility that no hole from the global matrix will be under it. +To avoid that case, if the either side of the BIGVIA is less than +1.5 * step, the BIGVIA is demoted to a simple VIA.

+
+
+
+

The MBK_TO_RDS_BIGVIA_METAL table

+

This table describe how the metal part of a BIGVIA is expanded (for the hole +part, see the previous table MBK_TO_RDS_BIGVIA_HOLE). The rule give for each +metal:

+
    +
  1. The delta-with (have to ask Franck).
  2. +
  3. The overhang, the length the real rectangle is expanded on each side from +the symbolic rectange.
  4. +
+

Example:

+
TABLE MBK_TO_RDS_BIGVIA_METAL
+
+    CONT_VIA  RDS_ALU1 0.0 0.09  ALL \
+              RDS_ALU2 0.0 0.09  ALL
+
+    CONT_VIA2 RDS_ALU2 0.0 0.09  ALL \
+              RDS_ALU3 0.0 0.09  ALL
+
+    CONT_VIA3 RDS_ALU3 0.0 0.09  ALL \
+              RDS_ALU4 0.0 0.09  ALL
+
+    CONT_VIA4 RDS_ALU4 0.0 0.09  ALL \
+              RDS_ALU5 0.0 0.09  ALL
+
+    CONT_VIA5 RDS_ALU5 0.0 0.09  ALL \
+              RDS_ALU6 0.0 0.18  ALL
+END
+
+
+
+

The MBK_WIRESETTING table

+

From a strict standpoint this table shouldn’t be here but put in a separate +configuration file, because it contains informations only used by the symbolic +layout tools (ocp, nero, ring).

+

This table defines the cell gauge the routing pitch and minimal (symbolic) +wire width and minimal spacing for the routers. They are patly redundant.

+

Example:

+
TABLE MBK_WIRESETTING
+
+    X_GRID             10
+    Y_GRID             10
+    Y_SLICE           100
+    WIDTH_VDD          12
+    WIDTH_VSS          12
+    TRACK_WIDTH_ALU8    0
+    TRACK_WIDTH_ALU7    4
+    TRACK_WIDTH_ALU6    4
+    TRACK_WIDTH_ALU5    4
+    TRACK_WIDTH_ALU4    3
+    TRACK_WIDTH_ALU3    3
+    TRACK_WIDTH_ALU2    3
+    TRACK_WIDTH_ALU1    3
+    TRACK_SPACING_ALU8  0
+    TRACK_SPACING_ALU7  4
+    TRACK_SPACING_ALU6  4
+    TRACK_SPACING_ALU5  4
+    TRACK_SPACING_ALU4  4
+    TRACK_SPACING_ALU3  4
+    TRACK_SPACING_ALU2  4
+    TRACK_SPACING_ALU1  3
+
+END
+
+
+
+ + +
+
+ + + + +
+ +
+ + + + + +
+ Generated by Sphinx + using a RTD theme on Jul 15, 2017. +
+ + + + + +
Coriolis 2 Documentation + © Copyright 2000-2017, UPMC. +
+
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/documentation/_build/html/RDS/index.html b/documentation/_build/html/RDS/index.html new file mode 100644 index 00000000..bcaceb10 --- /dev/null +++ b/documentation/_build/html/RDS/index.html @@ -0,0 +1,352 @@ + + + + + + + + + + + + Symbolic to Real Conversion in Alliance — Coriolis 2 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+
+
+
    +
  • Docs »
  • + +
  • Symbolic to Real Conversion in Alliance
  • +
  • + + + +
  • +
+
+
+
+ +

Disclaimer: This document is still far from complete.

+ + + +
+
+ + + + +
+ +
+ + + + + +
+ Generated by Sphinx + using a RTD theme on Jul 15, 2017. +
+ + + + + +
Coriolis 2 Documentation + © Copyright 2000-2017, UPMC. +
+
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/documentation/_build/html/Stratus/Stratus.html b/documentation/_build/html/Stratus/Stratus.html new file mode 100644 index 00000000..6a731f36 --- /dev/null +++ b/documentation/_build/html/Stratus/Stratus.html @@ -0,0 +1,334 @@ + + + + + + + + + + + + Stratus Reference — Coriolis 2 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+
+
+
    +
  • Docs »
  • + +
  • Stratus Reference
  • +
  • + + + +
  • +
+
+
+
+ +
+

Stratus Reference

+

The Stratus Language reference is generated by LaTeX2HTML and is +available here: Stratus

+
+ + +
+
+ + + + +
+ +
+ + + + + +
+ Generated by Sphinx + using a RTD theme on Jul 15, 2017. +
+ + + + + +
Coriolis 2 Documentation + © Copyright 2000-2017, UPMC. +
+
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/documentation/_build/html/Unicorn/Unicorn.html b/documentation/_build/html/Unicorn/Unicorn.html new file mode 100644 index 00000000..52571658 --- /dev/null +++ b/documentation/_build/html/Unicorn/Unicorn.html @@ -0,0 +1,334 @@ + + + + + + + + + + + + Unicorn Reference — Coriolis 2 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+
+
+
    +
  • Docs »
  • + +
  • Unicorn Reference
  • +
  • + + + +
  • +
+
+
+
+ +
+

Unicorn Reference

+

The Unicorn C++ API reference is generated by Doxygen and is +available here: Unicorn

+
+ + +
+
+ + + + +
+ +
+ + + + + +
+ Generated by Sphinx + using a RTD theme on Jul 15, 2017. +
+ + + + + +
Coriolis 2 Documentation + © Copyright 2000-2017, UPMC. +
+
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/documentation/_build/html/UsersGuide/Configuration.html b/documentation/_build/html/UsersGuide/Configuration.html new file mode 100644 index 00000000..c81cc030 --- /dev/null +++ b/documentation/_build/html/UsersGuide/Configuration.html @@ -0,0 +1,653 @@ + + + + + + + + + + + + Coriolis Configuration & Initialisation — Coriolis 2 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+
+
+ +
+
+
+ +

+
+

Coriolis Configuration & Initialisation

+
+

General Software Architecture

+

Coriolis has been build with respect of the classical paradigm that the +computational instensive parts have been written in C++, and almost +everything else in Python. To build the Python interface we used +two methods:

+
    +
  • For self-contained modules boost::python (mainly in vlsisapd).
  • +
  • For all modules based on Hurricane, we created our own wrappers due +to very specific requirements such as shared functions between modules +or C++/Python secure bi-directional object deletion.
  • +
+
+

Note

+

Python Documentation: +Most of the documentation is related to the C++ API and implemetation of +the tools. However, the Python bindings have been created so they +mimic as closely as possible the C++ interface, so the documentation +applies to both languages with only minor syntactic changes.

+
+

Coriolis Software Schematic

+

All configuration & initialization files are Python scripts, despite their +.conf extention. From a syntactic point of view, there is no difference +between the system-wide configuration files and the user’s configuration, +they may use the same Python helpers. +

+

Configuration is done in two stages:

+
    +
  1. Selecting the symbolic technology.
  2. +
  3. Loading the complete configuration for the given technology.
  4. +
+

+
+
+

First Stage: Symbolic Technology Selection

+

+The initialization process is done by executing, in order, the following +file(s):

+ +++++ + + + + + + + + + + + + + + + + + + + + +
OrderMeaningFile
1The system setting/etc/coriolis2/techno.conf
2The user’s global setting${HOME}/.coriolis2/techno.py
3The user’s local setting<CWD>/.coriolis2/techno.py
+

Thoses files must provides only two variables, the name of the symbolic technology +and the one of the real technology. For example:

+
# -*- Mode:Python -*-
+
+symbolicTechno = 'cmos'
+realTechno     = 'hcmos9'
+
+
+
+
+

Second Stage: Technology Configuration Loading

+

+The TECHNO variable is set by the first stage and it’s the name of the +symbolic technology. A directory of that name, with all the configuration files, +must exists in the configuration directory. In addition to the technology-specific +directories, a common/ directory is there to provides a trunk for all the +identical datas across the various technologies. The initialization process is done +by executing, in order, the following file(s):

+ +++++ + + + + + + + + + + + + + + + + + + + + +
OrderMeaningFile
1The system initialization/etc/coriolis2/<TECHNO>/<TOOL>.conf
2The user’s global initialization${HOME}/.coriolis2/settings.py
3The user’s local initialization<CWD>/.coriolis2/settings.py
+
+

Note

+

The loading policy is not hard-coded. It is implemented +at Python level in /etc/coriolis2/coriolisInit.py, and thus may be easily be +amended to whatever site policy.

+

The truly mandatory requirement is the existence of coriolisInit.py +which must contain a coriolisConfigure() function with no argument.

+
+
+
+

Configuration Helpers

+

To ease the writing of configuration files, a set of small helpers +is available. They allow to setup the configuration parameters through +simple assembly of tuples. The helpers are installed under the directory:

+
<install>/etc/coriolis2/
+
+

Where <install>/ is the root of the installation.

+

+
+

Alliance Helper

+

The configuration file must provide a allianceConfig tuple of +the form:

+
cellsTop = '/usr/share/alliance/cells/'
+
+allianceConfig = \
+    ( ( 'SYMBOLIC_TECHNOLOGY', helpers.sysConfDir+'/technology.symbolic.xml'   )
+    , ( 'REAL_TECHNOLOGY'    , helpers.sysConfDir+'/technology.cmos130.s2r.xml')
+    , ( 'DISPLAY'            , helpers.sysConfDir+'/display.xml'               )
+    , ( 'CATALOG'            , 'CATAL')
+    , ( 'WORKING_LIBRARY'    , '.')
+    , ( 'SYSTEM_LIBRARY'     , ( (cellsTop+'sxlib'   , Environment.Append)
+                               , (cellsTop+'dp_sxlib', Environment.Append)
+                               , (cellsTop+'ramlib'  , Environment.Append)
+                               , (cellsTop+'romlib'  , Environment.Append)
+                               , (cellsTop+'rflib'   , Environment.Append)
+                               , (cellsTop+'rf2lib'  , Environment.Append)
+                               , (cellsTop+'pxlib'   , Environment.Append) ) )
+    , ( 'SCALE_X'            , 100)
+    , ( 'IN_LO'              , 'vst')
+    , ( 'IN_PH'              , 'ap')
+    , ( 'OUT_LO'             , 'vst')
+    , ( 'OUT_PH'             , 'ap')
+    , ( 'POWER'              , 'vdd')
+    , ( 'GROUND'             , 'vss')
+    , ( 'CLOCK'              , '^ck.*')
+    , ( 'BLOCKAGE'           , '^blockageNet*')
+    )
+
+
+

The example above shows the system configuration file, with all the +available settings. Some important remarks about thoses settings:

+
    +
  • In it’s configuration file, the user do not need to redefine all the settings, +just the one he wants to change. In most of the cases, the SYSTEM_LIBRARY, +the WORKING_LIBRARY and the special net names (at this point there is not +much alternatives for the others settings).

    +
  • +
  • SYSTEM_LIBRARY setting: Setting up the library search path. +Each library entry in the tuple will be added to the search path according +to the second parameter:

    +
      +
    • Environment::Append: append to the search path.
    • +
    • Environment::Prepend: insert in head of the search path.
    • +
    • Environment::Replace: look for a library of the same name and replace +it, whithout changing the search path order. If no library of that name +already exists, it is appended.
    • +
    +

    A library is identified by it’s name, this name is the last component of the +path name. For instance: /soc/alliance/sxlib will be named sxlib. +Implementing the Alliance specification, when looking for a Cell name, +the system will browse sequentially trought the library list and returns +the first Cell whose name match.

    +
  • +
  • For POWER, GROUND, CLOCK and BLOCKAGE net names, a regular +expression (gnu regexp) is expected.

    +
  • +
  • The helpers.sysConfDir variable is supplied by the helpers, it is the +directory in which the system-wide configuration files are locateds. +For a standard installation it would be: /soc/coriolis2.

    +
  • +
+

A typical user’s configuration file would be:

+
import os
+
+homeDir = os.getenv('HOME')
+
+allianceConfig = \
+    ( ('WORKING_LIBRARY'    , homeDir+'/worklib')
+    , ('SYSTEM_LIBRARY'     , ( (homeDir+'/mylib', Environment.Append) ) )
+    , ('POWER'              , 'vdd.*')
+    , ('GROUND'             , 'vss.*')
+    )
+
+
+
+
+

Tools Configuration Helpers

+

All the tools uses the same helper to load their configuration (a.k.a. +Configuration Helper). Currently the following configuration system-wide +configuration files are defined:

+
    +
  • misc.conf: commons settings or not belonging specifically to a tool.
  • +
  • etesian.conf: for the Etesian tool.
  • +
  • kite.conf: for the Kite tool.
  • +
  • stratus1.conf: for the Stratus1 tool.
  • +
+

Here is the contents of etesian.conf:

+
# Etesian parameters.
+parametersTable = \
+    ( ('etesian.aspectRatio'    , TypePercentage, 100    , { 'min':10, 'max':1000 } )
+    , ('etesian.spaceMargin'    , TypePercentage, 5      )
+    , ('etesian.uniformDensity' , TypeBool      , False  )
+    , ('etesian.routingDriven'  , TypeBool      , False  )
+    , ("etesian.effort"         , TypeEnumerate , 2
+      , { 'values':( ("Fast"    , 1)
+                   , ("Standard", 2)
+                   , ("High"    , 3)
+                   , ("Extreme" , 4) ) }
+      )
+    , ("etesian.graphics"       , TypeEnumerate , 2
+      , { 'values':( ("Show every step"  , 1)
+                   , ("Show lower bound" , 2)
+                   , ("Show result only" , 3) ) }
+      )
+    )
+
+layoutTable = \
+    ( (TypeTab   , 'Etesian', 'etesian')
+
+    , (TypeTitle , 'Placement area')
+    , (TypeOption, "etesian.aspectRatio"   , "Aspect Ratio, X/Y (%)", 0 )
+    , (TypeOption, "etesian.spaceMargin"   , "Space Margin"         , 1 )
+    , (TypeRule  ,)
+    , (TypeTitle , 'Etesian - Placer')
+    , (TypeOption, "etesian.uniformDensity", "Uniform density"      , 0 )
+    , (TypeOption, "etesian.routingDriven" , "Routing driven"       , 0 )
+    , (TypeOption, "etesian.effort"        , "Placement effort"     , 1 )
+    , (TypeOption, "etesian.graphics"      , "Placement view"       , 1 )
+    , (TypeRule  ,)
+    )
+
+
+

+

Taxonomy of the file:

+
    +
  • It must contains, at least, the two tables:
      +
    • parametersTable, defines & initialise the configuration variables.
    • +
    • layoutTables, defines how the various parameters will be displayed +in the configuration window (The Settings Tab).
    • +
    +
  • +
  • The parametersTable, is a tuple (list) of tuples. Each entry in the list +describe a configuration parameter. In it’s simplest form, it’s a quadruplet +(TypeOption, ‘paramId’, ParameterType, DefaultValue) with:
      +
    1. TypeOption, tells that this tuple describe a parameter.
    2. +
    3. paramId, the identifier of the parameter. Identifiers are defined +by the tools. The list of parameters is detailed in each tool section.
    4. +
    5. ParameterType, the kind of parameter. Could be:
        +
      • TypeBool, boolean.
      • +
      • TypeInt, signed integer.
      • +
      • TypeEnumerate, enumerated type, needs extra entry.
      • +
      • TypePercentage, percentage, expressed between 0 and 100.
      • +
      • TypeDouble, float.
      • +
      • TypeString, character string.
      • +
      +
    6. +
    7. DefaultValue, the default value for that parameter.
    8. +
    +
  • +
+
+
+
+

Hacking the Configuration Files

+

Asides from the symbols that gets used by the configuration helpers like +allianceConfig or parametersTable, you can put pretty much anything +in <CWD>/.coriolis2/settings.py (that is, written in Python).

+

For example:

+
# -*- Mode:Python -*-
+
+defaultStyle = 'Alliance.Classic [black]'
+
+# Regular Coriolis configuration.
+parametersTable = \
+    ( ('misc.catchCore'           , TypeBool      , False  )
+    , ('misc.info'                , TypeBool      , False  )
+    , ('misc.paranoid'            , TypeBool      , False  )
+    , ('misc.bug'                 , TypeBool      , False  )
+    , ('misc.logMode'             , TypeBool      , True   )
+    , ('misc.verboseLevel1'       , TypeBool      , False  )
+    , ('misc.verboseLevel2'       , TypeBool      , True   )
+    , ('misc.minTraceLevel'       , TypeInt       , 0      )
+    , ('misc.maxTraceLevel'       , TypeInt       , 0      )
+    )
+
+# Some ordinary Python script...
+import os
+
+print '       o  Cleaning up ClockTree previous run.'
+for fileName in os.listdir('.'):
+  if fileName.endswith('.ap') or (fileName.find('_clocked.') >= 0):
+    print '          - <%s>' % fileName
+    os.unlink(fileName)
+
+
+

See Python Interface for Hurricane / Coriolis for more details those capabilities.

+
+
+ + +
+
+ + + + +
+ +
+ + + + + +
+ Generated by Sphinx + using a RTD theme on Jul 15, 2017. +
+ + + + + +
Coriolis 2 Documentation + © Copyright 2000-2017, UPMC. +
+
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/documentation/_build/html/UsersGuide/Installation.html b/documentation/_build/html/UsersGuide/Installation.html new file mode 100644 index 00000000..faedd981 --- /dev/null +++ b/documentation/_build/html/UsersGuide/Installation.html @@ -0,0 +1,574 @@ + + + + + + + + + + + + Installation — Coriolis 2 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+
+
+ +
+
+
+ +

+
+

Installation

+
+

Note

+

As the sources are being released, the binary packaging is dropped. +You still may find older version here: http://asim.lip6.fr/pub/coriolis/2.0 .

+
+

In a nutshell, building source consist in pulling the git repository then +running the ccb installer.

+

Main building prerequisites:

+
    +
  • cmake
  • +
  • C++11-capable compiler
  • +
  • RapidJSON
  • +
  • python2.7
  • +
  • boost
  • +
  • libxml2
  • +
  • bzip2
  • +
  • yacc & lex
  • +
  • Qt 4 or Qt 5
  • +
+

Building documentation prerequisites:

+
    +
  • doxygen
  • +
  • latex
  • +
  • latex2html
  • +
  • python-docutils (for reStructuredText)
  • +
+

Optional libraries:

+
    +
  • LEF/DEF (from SI2)
  • +
+

For other distributions, refer to their own packaging system.

+

+
+

Fixed Directory Tree

+

In order to simplificate the work of the ccb installer, the source, build +and installation tree is fixed. To successfully compile Coriolis you must +follow it exactly. The tree is relative to the home directory of the user +building it (noted ~/ or $HOME/). Only the source +directory needs to be manually created by the user, all others will be +automatically created either by ccb or the build system.

+ ++++ + + + + + + + + + + + + + + + + + + + + + + +
Sources
+
Sources root
+
under git
+
+
+
~/coriolis-2.x/src
+
~/coriolis-2.x/src/coriolis
+
+
Architecture Dependant Build
+
Linux, SL 7, 64b
+
Linux, SL 6, 32b
+
Linux, SL 6, 64b
+
Linux, Fedora, 64b
+
Linux, Fedora, 32b
+
FreeBSD 8, 32b
+
FreeBSD 8, 64b
+
Windows 7, 32b
+
Windows 7, 64b
+
Windows 8.x, 32b
+
Windows 8.x, 64b
+
+
+
~/coriolis-2.x/Linux.el7_64/Release.Shared/build/<tool>
+
~/coriolis-2.x/Linux.slsoc6x/Release.Shared/build/<tool>
+
~/coriolis-2.x/Linux.slsoc6x_64/Release.Shared/build/<tool>
+
~/coriolis-2.x/Linux.fc_64/Release.Shared/build/<tool>
+
~/coriolis-2.x/Linux.fc/Release.Shared/build/<tool>
+
~/coriolis-2.x/FreeBSD.8x.i386/Release.Shared/build/<tool>
+
~/coriolis-2.x/FreeBSD.8x.amd64/Release.Shared/build/<tool>
+
~/coriolis-2.x/Cygwin.W7/Release.Shared/build/<tool>
+
~/coriolis-2.x/Cygwin.W7_64/Release.Shared/build/<tool>
+
~/coriolis-2.x/Cygwin.W8/Release.Shared/build/<tool>
+
~/coriolis-2.x/Cygwin.W8_64/Release.Shared/build/<tool>
+
+
Architecture Dependant Install
Linux, SL 6, 32b~/coriolis-2.x/Linux.slsoc6x/Release.Shared/install/
FHS Compliant Structure under Install
+
Binaries
+
Libraries (Python)
+
Include by tool
+
Configuration files
+
Doc, by tool
+
+
+
.../install/bin
+
.../install/lib
+
.../install/include/coriolis2/<project>/<tool>
+
.../install/etc/coriolis2/
+
.../install/share/doc/coriolis2/en/html/<tool>
+
+
+
+

Note

+

Alternate build types: the Release.Shared means an optimized build +with shared libraries. But there are also available Static instead of Shared +and Debug instead of Release and any combination of them.

+

Static do not work because I don’t know yet to mix statically linked binaries +and Python modules (which must be dynamic).

+
+

+
+
+

Building Coriolis

+

First step is to install the prerequisites. Currently, only RapidJSON. +As RapidJSON is evolving fast, if you encounter compatibility problems, +the exact version we compiled against is given below.

+
dummy@lepka:~$ mkdir -p ~/coriolis-2.x/src/support
+dummy@lepka:~$ cd ~/coriolis-2.x/src/support
+dummy@lepka:~$ git clone http://github.com/miloyip/rapidjson
+dummy@lepka:~$ git checkout ec322005072076ef53984462fb4a1075c27c7dfd
+
+

The second step is to create the source directory and pull the git repository:

+
dummy@lepka:~$ mkdir -p ~/coriolis-2.x/src
+dummy@lepka:~$ cd ~/coriolis-2.x/src
+dummy@lepka:~$ git clone https://www-soc.lip6.fr/git/coriolis.git
+
+

Third and final step, build & install:

+
dummy@lepka:src$ ./bootstrap/ccb.py --project=support  \
+                                    --project=coriolis \
+                                    --make="-j4 install"
+dummy@lepka:src$ ./bootstrap/ccb.py --project=support  \
+                                    --project=coriolis \
+                                    --doc --make="-j1 install"
+
+

We need to separate to perform a separate installation of the documentation because it +do not support to be generated with a parallel build. So we compile & install in a first +stage in -j4 (or whatever) then we generate the documentation in -j1

+

Under rhel6 or clones, you must build using the devtoolset2:

+
dummy@lepka:src$ ./bootstrap/ccb.py --project=coriolis \
+                                    --devtoolset-2 --make="-j4 install"
+
+

If you want to uses Qt 5 instead of Qt 4, you may add the --qt5 argument.

+

The complete list of ccb functionalities can be accessed with the --help argument. +It also may be run in graphical mode (--gui).

+
+

Building the Devel Branch

+

In the Coriolis git repository, two branches are present:

+
    +
  • The master branch, which contains the latest stable version. This is the +one used by default if you follow the above instructions.

    +
  • +
  • The devel branch, which obviously contains the latest commits from the +development team. To use it instead of the master one, do the following +command just after the first step:

    +
    dummy@lepka:~$ git checkout devel
    +dummy@lepka:src$ ./bootstrap/ccb.py --project=coriolis \
    +                                    --make="-j4 install" --debug
    +
    +

    Be aware that it may requires newer versions of the dependencies and may introduce +incompatibilites with the stable version.

    +

    In the (unlikely) event of a crash of cgt, as it is a Python script, the right +command to run gdb on it is:

    +
    dummy@lepka:work$ gdb python core.XXXX
    +
    +
  • +
+

+
+
+

Additionnal Requirement under MacOS

+

Coriolis make uses of the boost::python module, but the MacPorts boost +seems unable to work with the Python bundled with MacOS. So you have to install +both of them from MacPorts:

+
dummy@macos:~$ port install boost +python27
+dummy@macos:~$ port select python python27
+dummy@macos:-$ export DYLD_FRAMEWORK_PATH=/opt/local/Library/Frameworks
+
+

The last two lines tell MacOS to use the Python from MacPorts and not from +the system.

+

Then proceed with the generic install instructions.

+
+
+
+

Packaging Coriolis

+

Packager should not uses ccb, instead bootstrap/Makefile.package is provided +to emulate a top-level autotool makefile. Just copy it in the root of the +Coriolis git repository (~/corriolis-2.x/src/coriolis/) and build.

+

Sligthly outaded packaging configuration files can also be found under bootstrap/:

+
    +
  • bootstrap/coriolis2.spec.in for rpm based distributions.
  • +
  • bootstrap/debian for Debian based distributions.
  • +
+
+
+

Hooking up into Alliance

+

Coriolis relies on Alliance for the cell libraries. So after installing or +packaging, you must configure it so that it can found those libraries.

+

This is done by editing the one variable cellsTop in the Alliance helper +(see Alliance Helper). This variable must point to the directory of the +cells libraries. In a typical installation, this is generally +/usr/share/alliance/cells.

+
+
+

Setting up the Environment (coriolisEnv.py)

+

To simplify the tedious task of configuring your environment, a helper is provided +in the bootstrap source directory (also installed in the directory +.../install/etc/coriolis2/) :

+
~/coriolis-2.x/src/coriolis/bootstrap/coriolisEnv.py
+
+

Use it like this:

+
dummy@lepka:~> eval `~/coriolis-2.x/src/coriolis/bootstrap/coriolisEnv.py`
+
+
+

Note

+

Do not call that script in your environement initialisation. +When used under rhel6 or clones, it needs to be run in the devtoolset2 +environement. The script then launch a new shell, which may cause an +infinite loop if it’s called again in, say ~/.bashrc.

+

Instead you may want to create an alias:

+
alias c2r='eval "`~/coriolis-2.x/src/coriolis/bootstrap/coriolisEnv.py`"'
+
+
+
+
+ + +
+
+ + + + +
+ +
+ + + + + +
+ Generated by Sphinx + using a RTD theme on Jul 15, 2017. +
+ + + + + +
Coriolis 2 Documentation + © Copyright 2000-2017, UPMC. +
+
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/documentation/_build/html/UsersGuide/LicenseCredits.html b/documentation/_build/html/UsersGuide/LicenseCredits.html new file mode 100644 index 00000000..f7ce4e9a --- /dev/null +++ b/documentation/_build/html/UsersGuide/LicenseCredits.html @@ -0,0 +1,361 @@ + + + + + + + + + + + + Credits & License — Coriolis 2 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+
+
+ +
+
+
+ +
+

Credits & License

+

Hurricane +Rémy Escassut & + Christian Masson

+
+

Etesian +Gabriel Gouvine

+
+

Stratus +Sophie Belloeil

+
+

Knik +Damien Dupuis

+
+

Kite, + Unicorn +Jean-Paul Chaput

+


+

The Hurricane data-base is copyright© Bull 2000-2016 and is +released under the terms of the lgpl license. All other tools are +copyright© upmc 2008-2016 and released under the gpl +license.

+

Others important contributors to Coriolis are Christophe Alexandre, +Hugo Clement, Marek Sroka and Wu Yifei.

+

The Knik router makes use of the Flute software, which is +copyright© Chris C. N. Chu from the Iowa State University +(http://home.eng.iastate.edu/~cnchu/).

+
+ + +
+
+ + + + +
+ +
+ + + + + +
+ Generated by Sphinx + using a RTD theme on Jul 15, 2017. +
+ + + + + +
Coriolis 2 Documentation + © Copyright 2000-2017, UPMC. +
+
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/documentation/_build/html/UsersGuide/Releases.html b/documentation/_build/html/UsersGuide/Releases.html new file mode 100644 index 00000000..4a9b956a --- /dev/null +++ b/documentation/_build/html/UsersGuide/Releases.html @@ -0,0 +1,418 @@ + + + + + + + + + + + + Release Notes — Coriolis 2 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+
+
+ +
+
+
+ +
+

Release Notes

+
+

Release 1.0.1475

+

This is the first preliminary release of the Coriolis 2 framework.

+

This release mainly ships the global router Knik and the detailed router +Kite. Together they aim to replace the Alliance Nero router. +Unlike Nero, Kite is based on an innovating routing modeling and ad-hoc +algorithm. Although it is released under gpl license, the source code +will be avalaible later. +

+

Contents of this release:

+
    +
  1. A graphical user interface (viewer only).
  2. +
  3. The Knik global router.
  4. +
  5. The Kite detailed router.
  6. +
+

Supported input/output formats:

+
    +
  • Alliance vst (netlist) & ap (physical) formats.
  • +
  • Even if there are some references to the Cadence lefdef format, its +support is not included because it depends on a library only available +to Si2 affiliated members.
  • +
+
+
+

Release 1.0.1963

+

Release 1963 is alpha. All the tools from Coriolis 1 have been ported into +this release.

+

Contents of this release:

+
    +
  1. The Stratus netlist capture language (GenLib replacement).
  2. +
  3. The Mauka placer (still contains bugs).
  4. +
  5. A graphical user interface (viewer only).
  6. +
  7. The Knik global router.
  8. +
  9. The Kite detailed router.
  10. +
  11. Partially implemented python support for configuration files +(alternative to xml).
  12. +
  13. A documentation (imcomplete/obsoleted in Hurricane‘s case).
  14. +
+
+
+

Release 1.0.2049

+

Release 2049 is Alpha.

+

Changes of this release:

+
    +
  1. The Hurricane documentation is now accurate. Documentation +for the Cell viewer and CRLcore has been added.
  2. +
  3. More extensive Python support for all the components of +Coriolis.
  4. +
  5. Configuration is now completly migrated under Python. +xml loaders can still be useds for compatibilty.
  6. +
  7. The cgt main has been rewritten in Python.
  8. +
+
+
+

Release v2.0.1

+
    +
  1. Migrated the repository from svn to git, and release complete sources. +As a consequence, we drop the distribution packaging support and give +public read-only access to the repository.
  2. +
  3. Deep rewrite of the Katabatic database and Kite detailed router, +achieve a speedup factor greater than 20...
  4. +
+
+
+

Release v2.1

+
    +
  1. Replace the old simulated annealing placer Mauka by the analytical placer +Etesian and its legalization and detailed placement tools.
  2. +
  3. Added a Blif format parser to process circuits generated by the Yosys and ABC +logic synthetizers.
  4. +
  5. The multiples user defined configuration files are now grouped under +a common hidden (dot) directory .coriolis2 and the file extension +is back from .conf to .py.
  6. +
+
+
+

Release v2.2

+
    +
  1. Added JSON import/export of the whole Hurricane DataBase. Two save mode +are supported: Cell mode (standalone) or Blob mode, which dump the +whole design down and including the standard cells.
  2. +
+
+
+ + +
+
+ + + + +
+ +
+ + + + + +
+ Generated by Sphinx + using a RTD theme on Jul 15, 2017. +
+ + + + + +
Coriolis 2 Documentation + © Copyright 2000-2017, UPMC. +
+
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/documentation/_build/html/UsersGuide/ScriptsPlugins.html b/documentation/_build/html/UsersGuide/ScriptsPlugins.html new file mode 100644 index 00000000..990c8ec8 --- /dev/null +++ b/documentation/_build/html/UsersGuide/ScriptsPlugins.html @@ -0,0 +1,712 @@ + + + + + + + + + + + + Python Interface for Hurricane / Coriolis — Coriolis 2 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+
+
+ +
+
+
+ +
+

Python Interface for Hurricane / Coriolis

+

The (almost) complete interface of Hurricane is exported as a Python module +and some part of the other components of Coriolis (each one in a separate +module). The interface has been made to mirror as closely as possible the +C++ one, so the C++ doxygen documentation could be used to write code with +either languages.

+

Summary of the C++ Documentation

+

A script could be run directly in text mode from the command line or through +the graphical interface (see Executing Python Scripts in Cgt).

+

Asides for this requirement, the python script can contain anything valid +in Python, so don’t hesitate to use any package or extention.

+

Small example of Python/Stratus script:

+
from Hurricane import *
+from Stratus   import *
+
+def doSomething ():
+    # ...
+    return
+
+def ScriptMain ( **kw ):
+  editor = None
+  if kw.has_key('editor') and kw['editor']:
+    editor = kw['editor']
+    stratus.setEditor( editor )
+
+  doSomething()
+  return
+
+if __name__ == "__main__" :
+  kw           = {}
+  success      = ScriptMain( **kw )
+  shellSuccess = 0
+  if not success: shellSuccess = 1
+
+  sys.exit( shellSuccess )
+      ScriptMain ()
+
+

This typical script can be executed in two ways:

+
    +
  1. Run directly as a Python script, thanks to the

    +
    if __name__ == "__main__" :
    +
    +

    part (this is standart Python). It is a simple adapter that will +calls ScriptMain().

    +
  2. +
  3. Through cgt, either in text or graphical mode. In that case, the +ScriptMain() is directly called trough a sub-interpreter. +The arguments of the script are passed through the **kw dictionnary.

    + ++++ + + + + + + + + + + + + + + + +
    **kw Dictionnary
    Parameter Key/NameContents type
    'cell'A Hurricane cell on which to work. Depending +on the context, it may be None. +For example, when run from cgt, it the cell +currently loaded in the viewer, if any.
    'editor'The viewer from which the script is run, when +lauched through cgt.
    +
  4. +
+
+

Plugins

+

Plugins are Python scripts specially crafted to integrate with cgt. +Their entry point is a ScriptMain() method as described in +Python Interface to Coriolis. They can be called by user scripts +through this method.

+
+

Chip Placement

+

Automatically perform the placement of a complete chip. This plugin, as well +as the other P&R tools expect a specific top-level hierarchy for the design. +The top-level hierarchy must contains the instances of all the I/O pads and +exactly one instance of the chip’s core model.

+

Chip Top Structure

+

The designer must provide a configuration file that define the rules for the +placement of the top-level hierarchy (that is, the pads and the core). +This file must be named after the chip’s name, by appending _chip.py +(obviously, it is a Python file). For instance if the chip netlist file +is called amd2901_crl.vst, then the configuration file must be named +amd2901_crl_chip.vst.

+

Example of chip placement configuration file (for AM2901):

+
chip = \
+  { 'pads.south'     : [ 'p_a3'     , 'p_a2'     , 'p_a1'     , 'p_r0'
+                       , 'p_vddick0', 'p_vssick0', 'p_a0'     , 'p_i6'
+                       , 'p_i8'     , 'p_i7'     , 'p_r3'     ]
+  , 'pads.east'      : [ 'p_zero'   , 'p_i0'     , 'p_i1'     , 'p_i2'
+                       , 'p_vddeck0', 'p_vsseck0', 'p_q3'     , 'p_b0'
+                       , 'p_b1'     , 'p_b2'     , 'p_b3'     ]
+  , 'pads.north'     : [ 'p_noe'    , 'p_y3'     , 'p_y2'     , 'p_y1'
+                       , 'p_y0'     , 'p_vddeck1', 'p_vsseck1', 'p_np'
+                       , 'p_ovr'    , 'p_cout'   , 'p_ng'     ]
+  , 'pads.west'      : [ 'p_cin'    , 'p_i4'     , 'p_i5'     , 'p_i3'
+                       , 'p_ck'     , 'p_d0'     , 'p_d1'     , 'p_d2'
+                       , 'p_d3'     , 'p_q0'     , 'p_f3'     ]
+  , 'core.size'      : ( 1500, 1500 )
+  , 'chip.size'      : ( 3000, 3000 )
+  , 'chip.clockTree' : True
+  }
+
+
+

The file must contain one dictionnary named chip.

+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Chip Dictionnary
Parameter Key/NameValue/Contents type
'pad.south'Ordered list (left to right) of pad instances names +to put on the south side of the chip
'pad.east'Ordered list (down to up) of pad instances names +to put on the east side of the chip
'pad.north'Ordered list (left to right) of pad instances names +to put on the north side of the chip
'pad.west'Ordered list (down to up) of pad instances names +to put on the west side of the chip
'core.size'The size of the core (to be used by the placer)
'chip.size'The size of the whole chip. The sides must be great +enough to accomodate all the pads
'chip.clockTree'Whether to generate a clock tree or not. This calls +the ClockTree plugin
+

Configuration parameters, defaults are defined in etc/coriolis2/<STECHNO>/plugins.conf.

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameter IdentifierTypeDefault
Chip Plugin Parameters
chip.block.rails.countTypeInt5
The minimum number of rails around the core +block. Must be odd and suppérior to 5. +One rail for the clock and at least two pairs +of power/grounds
chip.block.rails.hWidthTypeInt12
The horizontal with of the rails
chip.block.rails.vWidthTypeInt12
The vertical with of the rails
chip.block.rails.hSpacingTypeInt6
The spacing, edge to edge of two adjacent +horizontal rails
chip.block.rails.vSpacingTypeInt6
The spacing, edge to edge of two adjacent +vertical rails
chip.pad.pckTypeStringpck_px
The model name of the pad connected to the +chip external clock
chip.pad.pvddeckTypeStringpvddeck_px
The model name of the pad connected to the +vdde (external power) and suppling it to +the core
chip.pad.pvsseckTypeStringpvsseck_px
The model name of the pad connected to the +vsse (external ground) and suppling it to +the core
chip.pad.pvddickTypeStringpvddick_px
The model name of the pad connected to the +vddi (internal power) and suppling it to +the core
chip.pad.pvssickTypeStringpvssick_px
The model name of the pad connected to the +vssi (internal ground) and suppling it to +the core
+
+

Note

+

If no clock tree is generated, then the clock rail is not created. +So even if the requested number of rails chip.block.rails.count is, say 5, +only four rails (2* power, 2* ground) will be generateds.

+
+
+
+

Clock Tree

+

Insert a clock tree into a block. The clock tree uses the H strategy. +The clock net is splitted into sub-nets, one for each branch of the +tree.

+
    +
  • On chips design, the sub-nets are createds in the model of the +core block (then trans-hierarchically flattened to be shown at +chip level).

    +
  • +
  • On blocks, the sub nets are created directly in the top block.

    +
  • +
  • The sub-nets are named according to a simple geometrical scheme. +A common prefix ck_htree, then one postfix by level telling +on which quarter of plane the sub-clock is located:

    +
      +
    1. _bl: bottom left plane quarter.
    2. +
    3. _br: bottom right plane quarter.
    4. +
    5. _tl: top left plane quarter.
    6. +
    7. _tr: top right plane quarter.
    8. +
    +

    We can have ck_htree_bl, ck_htree_bl_bl, ch_htree_bl_tl and so on.

    +
  • +
+

The clock tree plugin works in four steps:

+
    +
  1. Build the clock tree: creates the top-block abutment box, compute the +levels of H tree neededs and place the clock buffers.
  2. +
  3. Once the clock buffers are placed, calls the placer (Etesian) to place +the ordinary standart cells, whithout disturbing clock H-tree buffers.
  4. +
  5. At this point we know the exact positions of all the DFFs, so we can +connect them to the nearest H-tree leaf clock signal.
  6. +
  7. Leaf clock signals that are not connecteds to any DFFs are removed.
  8. +
+

Netlist reorganisation:

+
    +
  • Obviously the top block or chip core model netlist is modificated to +contains all the clock sub-nets. The interface is not changed.
  • +
  • If the top block contains instances of other models and those models +contains DFFs that get re-connecteds to the clock sub-nets (from the +top level). Change both the model netlist and interface to propagate +the relevant clock sub-nets to the instanciated model. The new model +with the added clock signal is renamed with a _clocked suffix. +For example, the sub-block model ram.vst will become ram_clocked.vst.
  • +
+
+

Note

+

If you are to re-run the clock tree plugin on a netlist, be careful +to erase any previously generated _clocked file (both netlist and +layout: rm *.clocked.{ap,vst}). And restart cgt to clear it’s +memory cache.

+
+

Configuration parameters, defaults are defined in etc/coriolis2/<STECHNO>/plugins.conf.

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameter IdentifierTypeDefault
ClockTree Plugin Parameters
clockTree.minimumSideTypeInt300
The minimum size below which the clock tree +will stop to perform quadri-partitions
clockTree.bufferTypeStringbuf_x2
The buffer model to use to drive sub-nets
clockTree.placerEngineTypeStringEtesian
The placer to use. Other value is Mauka +the simulated annealing placer which will go +into retirement very soon
+
+
+

Recursive-Save (RSave)

+

Perform a recursive top down save of all the models from the top cell +loaded in cgt. Force a write of any non-terminal model. This plugin is used +by the clock tree plugin after the netlist clock sub-nets creation.

+
+
+
+

A Simple Example: AM2901

+

To illustrate the capabilities of Coriolis tools and Python scripting, a small +example, derived from the Alliance AM2901 is supplied.

+

This example contains only the synthetized netlists and the doChip.py script +which perform the whole P&R of the design.

+

You can generate the chip using one of the following method:

+
    +
  1. Command line mode: directly run the script:

    +
    dummy@lepka:AM2901$ ./doChip -V --cell=amd2901
    +
    +
  2. +
  3. Graphic mode: launch cgt, load chip netlist amd2901 (the top cell) +then run the Python script doChip.py.

    +
  4. +
+
+

Note

+

Between two consecutive run, be sure to erase the netlist/layout generateds:

+
dummy@lepka:AM2901$ rm *_clocked*.vst *.ap
+
+
+
+
+ + +
+
+ + + + +
+ +
+ + + + + +
+ Generated by Sphinx + using a RTD theme on Jul 15, 2017. +
+ + + + + +
Coriolis 2 Documentation + © Copyright 2000-2017, UPMC. +
+
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/documentation/_build/html/UsersGuide/ViewerTools.html b/documentation/_build/html/UsersGuide/ViewerTools.html new file mode 100644 index 00000000..0972c80d --- /dev/null +++ b/documentation/_build/html/UsersGuide/ViewerTools.html @@ -0,0 +1,1205 @@ + + + + + + + + + + + + CGT - The Graphical Interface — Coriolis 2 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+
+
+ +
+
+
+ +
+

CGT - The Graphical Interface

+

The Coriolis graphical interface is split up into two windows.

+
    +
  • The Viewer, with the following features:
      +
    • Basic load/save capabilities.
    • +
    • Display the current working cell. Could be empty if the design +is not yet placed.
    • +
    • Execute Stratus Scripts.
    • +
    • Menu to run the tools (placement, routage).
    • +
    +
  • +
+

Features are detailed in Viewer & Tools.

+

Viewer Basic Snapshot

+
    +
  • The Controller, which allows:
      +
    • Tweak what is displayer by the Viewer. Through the Look, +Filter and Layers&Gos tabs.
    • +
    • Browse the netlist with eponym tab.
    • +
    • Show the list of selected objects (if any) with selection
    • +
    • Walk through the Database, the Cell or the Selection with Inspector. +This is an advanced feature, reserved for experimented users.
    • +
    • The tab Settings which give access to all the settings. +They are closely related to Configuration & Initialisation.
    • +
    +
  • +
+

Controller Basic Snapshot

+
+

Viewer & Tools

+
+

Stratus Netlist Capture

+

Stratus is the replacement for GenLib procedural netlist capture language. +It is designed as a set of Python classes, and comes with it’s own documentation +(Stratus Documentation)

+
+
+

The Hurricane Data-Base

+

The Alliance flow is based on the mbk data-base, which has one data-structure +for each view. That is, Lofig for the logical view and Phfig for the physical +view. The place and route tools were responsible for maintaining (or not) the +coherency between views. Reflecting this weak coupling between views, each one +was stored in a separate file with a specific format. The logical view is stored +in a vst file in vhdl format and the physical in an ap file in an ad-hoc format.

+

The Coriolis flow is based on the Hurricane data-base, which has a unified +structure for logical and physical view. That data structure is the Cell object. +The Cell can have any state between pure netlist and completly placed and +routed design. Although the memory representation of the views has deeply +changed we still use the Alliance files format, but they now really represent +views of the same object. The point is that one must be very careful about +view coherency when going to and from Coriolis.

+

As for the second release, Coriolis can be used only for three purposes :

+
    +
  • Placing a design, in which case the netlist view must be present.
  • +
  • Routing a design, in that case the netlist +view and the layout view must be present and layout view must contain +a placement. Both views must have the same name. When saving the routed design, +it is advised to change the design name otherwise the original unrouted placement +in the layout view will be overwritten.
  • +
  • Viewing a design, the netlist view must be present, if a layout +view is present it still must have the same name but it can be in any +state.
  • +
+
+
+

Synthetizing and loading a design

+

Coriolis supports several file formats. It can load all file format +from the Alliance toolchain (.ap for layout, behavioural and structural vhdl .vbe and .vst), +BLIF netlist format as well as benchmark formats from the ISPD contests.

+

It can be compiled with LEF/DEF support, although it requires acceptance of the SI2 license +and may not be compiled in your version of the software.

+
+

Synthesis under Yosys

+

You can create a BLIF file from the Yosys synthetizer, which can be imported under Coriolis. +Most libraries are specified as a .lib liberty file and a .lef LEF file. +Yosys opens most .lib files with minor modifications, but LEF support in Coriolis relies on SI2. +If Coriolis hasn’t been compiled against it, the library is given in Alliance .ap format. +Some free libraries already provide both .ap and .lib files.

+

Once you have installed a common library under Yosys and Coriolis, just synthetize your design +with Yosys and import it (as Blif without the extension) under Coriolis to perform place&route.

+
+
+

Synthesis under Alliance

+

Alliance is an older toolchain but has been extensively used for years. Coriolis can import +and write Alliance designs and libraries directly.

+
+
+
+

Etesian – Placer

+

The Etesian placer is a state of the art (as of 2015) analytical placer. It is +within 5% of other placers’ solutions, but is normally a bit worse than ePlace. +This Coriolis tool is actually an encapsulation of Coloquinte which is the placer.

+
+

Note

+

Instance Uniquification Unsupported: a same logical instance cannot have +two different placements. So, either you manually make a clone of it or you +supply a placement for it. We need to implement uniquification in the +Hurricane database.

+
+

+Hierarchical Placement

+

The placement area is defined by the top cell abutment box.

+

When placing a complete hierarchy, the abutment boxes of the cells (models) other than +the top cell are sets identical to the one of the top cell and their instances are +all placed at position (0,0,ID). That is, all the abutments boxes, whatever the +hierarchical level, defines the same area (they are exactly superposed).

+

We choose this scheme because the placer will see all the instances as virtually +flattened, so they can be placed anywhere inside the top-cell abutment box.

+

Etesian Abutment Box

+

+Computing the Placement Area

+

The placement area is computed using the etesian.aspectRatio and etesian.spaceMargin +parameters only if the top-cell has an empty abutment box. If the top-cell abutment +box has to be set, then it is propagated to all the instances models recursively.

+

+Reseting the Placement

+

Once a placement has been done, the placer cannot reset it (will be implemented +later). To perform a new placement, you must restart cgt. In addition, if you +have saved the placement on disk, you must erase any .ap file, which are +automatically reloaded along with the netlist (.vst).

+

+Limitations

+

Etesian supports standard cells and fixed macros. As for the Coriolis 2.1 version, +it doesn’t support movable macros, and you must place every macro beforehand. +Timing and routability analysis are not included either, and the returned placement +may be unroutable.

+
+

Etesian Configuration Parameters

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameter IdentifierTypeDefault
Etesian Parameters
etesian.aspectRatioTypePercentage100
Define the height on width H/W aspect +ratio, can be comprised between 10 and 1000
etesian.spaceMarginTypePercentage5
The extra white space added to the total area +of the standard cells
etesian.uniformDensityTypeBoolFalse
Whether the cells will be spread envenly +across the area or allowed to form denser +clusters
etesian.effortTypeInt2
Sets the balance between the speed of the +placer and the solution quality
etesian.routingDrivenTypeBoolFalse
Whether the tool will try routing iterations +and whitespace allocation to improve +routability; to be implemented
etesian.graphicsTypeInt2

How often the display will be refreshed +More refreshing slows the placer.

+
    +
  • 1 shows both upper and lower bounds
  • +
  • 2 only shows lower bound results
  • +
  • 3 only shows the final results
  • +
+
+

+
+
+
+

Knik – Global Router

+

The quality of Knik global routing solutions are equivalent to those of FGR 1.0. +For an in-depth description of Knik algorithms, you may download the thesis of +D. Dupuis avalaible from here~: Knik Thesis.

+

The global router is (not yet) deterministic. To circumvent this limitation, +a global routing solution can be saved to disk and reloaded for later uses.

+

A global routing is saved into a file with the same name as the design and a +kgr extention. It is in Box Router output format.

+

Menus:

+
    +
  • \textbf{P\&R} \rightarrow \textbf{Step by Step} \rightarrow \textbf{Save Global Routing}
  • +
  • \textbf{P\&R} \rightarrow \textbf{Step by Step} \rightarrow \textbf{Load Global Routing}
  • +
+
+
+

Kite – Detailed Router

+

Kite no longer suffers from the limitations of Nero. It can route big designs +as its runtime and memory footprint is almost linear (with respect to the number +of gates). It has successfully routed design of more than 150K gates. +

+

However, this first release comes with the temporary the following +restrictions:

+
    +
  • Works only with SxLib standard cell gauge.
  • +
  • Works always with 4 routing metal layers (M2 through M5).
  • +
  • Do not allow (take into account) pre-routed wires on signals +other than power or ground.
  • +
+
+

Note

+

Slow Layer Assignment. Most of the time, the layer assignment stage is +fast (less than a dozen seconds), but in some instances it can take more +than a dozen minutes. This is a known bug and will be corrected in later +releases.

+
+

After each run, Kite displays a set of completion ratios which must all +be equal to 100% if the detailed routing has been successfull. +In the event of a failure, on a saturated design, you may decrease the +edge saturation ratio (argument –edge) to balance more evenly the design +saturation. That is, the maximum saturation decrease at the price of a wider +saturated area and increased wirelength. This is the saturation of the +global router Knik, and you may increase/decrease by steps of 5%, +which represent one track. The maximum capacity of the SxLib gauge is +10 tracks in two layers, that makes 20 tracks by Knik edge.

+

Routing a design is done in four ordered steps:

+
    +
  1. Detailed pre-route \textbf{P\&R} \rightarrow \textbf{Step by Step} \rightarrow \textbf{Detailed PreRoute}
  2. +
  3. Global routing \textbf{P\&R} \rightarrow \textbf{Step by Step} \rightarrow \textbf{Global Route}
  4. +
  5. Detailed routing \textbf{P\&R} \rightarrow \textbf{Step by Step} \rightarrow \textbf{Detailed Route}
  6. +
  7. Finalize routing \textbf{P\&R} \rightarrow \textbf{Step by Step} \rightarrow \textbf{Finalize Route}
  8. +
+

It is possible to supply to the router a complete wiring for some nets that the user’s +wants to be routed according to a specific topology. The supplied topology must respect +the building rules of the Katabatic database (contacts must be, terminals, turns, h-tee +& v-tee only). During the first step Detailed Pre-Route the router will solve +overlaps between the segments, without making any dogleg. If no pre-routed topologies +are present, this step may be ommited. Any net routed at this step is then fixed and +become unmovable for the later stages.

+

After the detailed routing step the Kite data-structure is still active +(the Hurricane wiring is decorated). The finalize step performs the removal of +the Kite data-structure, and it is not advisable to save the design before +that step.

+

You may visualize the density (saturation) of either Knik (on edges) or +Kite (on GCells) until the routing is finalized. Special layers appears +to that effect in the The Layers&Go Tab.

+
+

Kite Configuration Parameters

+

As Knik is only called through Kite, it’s parameters also have +the kite. prefix.

+

The Katabatic parameters control the layer assignment step.

+

All the defaults value given below are from the default Alliance technology +(cmos and SxLib cell gauge/routing gauge).

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameter IdentifierTypeDefault
Katabatic Parameters
katabatic.topRoutingLayerTypeStringMETAL5
Define the highest metal layer that will be +used for routing (inclusive).
katabatic.globalLengthThresholdTypeInt1450
This parameter is used by a layer assignment +method which is no longer used (did not give +good results)
katabatic.saturateRatioTypePercentage80
If M(x) density is above this ratio, +move up feedthru global segments up from +depth x to x+2
katabatic.saturateRpTypeInt8
If a GCell contains more terminals +(RoutingPad) than that number, force a +move up of the connecting segments to those +in excess
Knik Parameters
kite.hTracksReservedLocalTypeInt3
To take account the tracks needed inside a +GCell to build the local routing, decrease +the capacity of the edges of the global +router. Horizontal and vertical locally +reserved capacity can be distinguished for +more accuracy.
kite.vTracksReservedLocalTypeInt3
cf. kite.hTracksReservedLocal
Kite Parameters
kite.eventsLimitTypeInt4000002
The maximum number of segment displacements, +this is a last ditch safety against infinite +loop. It’s perhaps a little too low for big +designs
kite.ripupCostTypeInt3
Differential introduced between two ripup +cost to avoid a loop between two ripped up +segments
kite.strapRipupLimitTypeInt16
Maximum number of ripup for strap segments
kite.localRipupLimitTypeInt9
Maximum number of ripup for local segments
kite.globalRipupLimitTypeInt5
Maximum number of ripup for global segments, +when this limit is reached, triggers topologic +modification
kite.longGlobalRipupLimitTypeInt5
Maximum number of ripup for long global +segments, when this limit is reached, triggers +topological modification
+
+
+
+

Executing Python Scripts in Cgt

+

Python/Stratus scripts can be executed either in text or graphical mode.

+
+

Note

+

How Cgt Locates Python Scripts: +cgt uses the Python import mechanism to load Python scripts. +So you must give the name of your script whitout .py extention and +it must be reachable through the PYTHONPATH. You may uses the +dotted module notation.

+
+

A Python/Stratus script must contains a function called ScriptMain() +with one optional argument, the graphical editor into which it may be +running (will be set to None in text mode). The Python interface to +the editor (type: CellViewer) is limited to basic capabilities +only.

+

Any script given on the command line will be run immediatly after the +initializations and before any other argument is processed.

+

For more explanation on Python scripts see Python Interface for Hurricane / Coriolis.

+
+
+

Printing & Snapshots

+

Printing or saving into a pdf is fairly simple, just uses the File -> Print +menu or the CTRL+P shortcut to open the dialog box.

+

The print functionality uses exactly the same rendering mechanism as for the +screen, beeing almost WYSIWYG. Thus, to obtain the best results it is advisable +to select the Coriolis.Printer look (in the Controller), which uses a +white background and much suited for high resolutions 32x32 pixels patterns

+

There is also two mode of printing selectable through the Controller +Settings -> Misc -> Printer/Snapshot Mode:

+ +++++ + + + + + + + + + + + + + + +
ModeDPI (approx.)Intended Usage
Cell Mode150For single Cell printing or very small designs. +Patterns will be bigger and more readable.
Design Mode300For designs (mostly commposed of wires and cells +outlines).
+
+

Note

+

The pdf file size +Be aware that the generated pdf files are indeed only pixmaps. +So they can grew very large if you select paper format above A2 +or similar.

+
+

+Saving into an image is subject to the same remarks as for pdf.

+
+
+

Memento of Shortcuts in Graphic Mode

+

The main application binary is cgt.

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CategoryKeysAction
Moves
+
Up, +Down
+
Left, +Right
+
+
Shift the view in the according direction
FitfFit to the Cell abutment box
RefreshCTRL+LTriggers a complete display redraw
Gotogapperture is the minimum side of the area +displayed around the point to go to. It’s an +alternative way of setting the zoom level
Zoomz, +mRespectively zoom by a 2 factor and unzoom +by a 2 factor
+
BigMouse
+
Area Zoom
+
+
You can perform a zoom to an area. +Define the zoom area by holding down the left +mouse button while moving the mouse.
Selection
+
BigMouse
+
Area Selection
+
+
You can select displayed objects under an area. +Define the selection area by holding down the +right mouse button while moving the mouse.
+
BigMouse
+
Toggle Selection
+
+
You can toggle the selection of one object under +the mouse position by pressing CTRL and +pressing down the right mouse button. A popup +list of what’s under the position shows up into +which you can toggle the selection state of one +item.
SToggle the selection visibility
ControllerCTRL+I

Show/hide the controller window.

+

It’s the Swiss Army Knife of the viewer. +From it, you can fine-control the display and +inspect almost everything in your design.

+
Rulersk, +ESCOne stroke on k enters the ruler mode, in +which you can draw one ruler. You can exit the +ruler mode by pressing ESC. Once in ruler +mode, the first click on the left mouse button +sets the ruler’s starting point and the second +click the ruler’s end point. The second click +exits automatically the ruler mode.
KClears all the drawn rulers
PrintCTRL+PCurrently rather crude. It’s a direct copy of +what’s displayed in pixels. So the resulting +picture will be a little blurred due to +anti-aliasing mechanism.
Open/CloseCTRL+OOpens a new design. The design name must be +given without path or extention.
CTRL+WClose the current viewer window, but do not quit +the application.
CTRL+QCTRL+Q quit the application +(closing all windows).
HierarchyCTRL+DownGo one hierarchy level down. That is, if there +is an instance under the cursor position, load +it’s model Cell in place of the current one.
CTRL+UpGo one hierarchy level up. if we have entered +the current model through CTRL+Down +reload the previous model (the one +in which this model is instanciated).
+
+
+

Cgt Command Line Options

+

Appart from the obvious --text options, all can be used for text and graphical mode.

+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ArgumentsMeaning
-t|–textInstruct cgt to run in text mode.
-L|–log-modeDisable the uses of ansi escape sequence on +the tty. Useful when the output is +redirected to a file.
-c <cell>|–cell=<cell>The name of the design to load, without +leading path or extention.
-g|–load-globalReload a global routing solution from disk. +The file containing the solution must be named +<cell>.kgr.
–save-globalSave the global routing solution, into a file +named <design>.kgr.
-e <ratio>|–edge=<ratio>Change the edge capacity for the global +router, between 0 and 1 (Knik).
-G|–global-routeRun the global router (Knik).
-R|–detailed-routeRun the detailed router (Kite).
-s|–save-design=<routed>The design into which the routed layout will +be saved. It is strongly recommanded to choose +a different name from the source (unrouted) +design.
–events-limit=<count>The maximal number of events after which the +router will stops. This is mainly a failsafe +against looping. The limit is sets to 4 +millions of iteration which should suffice to +any design of 100K. gates. For bigger +designs you may wants to increase this limit.
–stratus-script=<module>Run the Python/Stratus script module. +See Python Scripts in Cgt.
+

+

Some Examples :

+
    +
  • Run both global and detailed router, then save the routed design :

    +
    > cgt -v -t -G -R --cell=design --save-design=design_kite
    +
    +
  • +
  • Load a previous global solution, run the detailed router, then save the +routed design :

    +
    > cgt -v -t --load-global -R --cell=design --save-design=design_kite
    +
    +
  • +
  • Run the global router, then save the global routing solution :

    +
    > cgt -v -t -G --save-global --cell=design
    +
    +
  • +
+
+
+

Miscellaneous Settings

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameter IdentifierTypeDefault
Verbosity/Log Parameters
misc.infoTypeBoolFalse
Enable display of info level message +(cinfo stream)
misc.bugTypeBoolFalse
Enable display of bug level message +(cbug stream), messages can be a little +scarry
misc.logModeTypeBoolFalse
If enabled, assume that the output device +is not a tty and suppress any escaped +sequences
misc.verboseLevel1TypeBoolTrue
First level of verbosity, disable level 2
misc.verboseLevel2TypeBoolFalse
Second level of verbosity
Development/Debug Parameters
misc.minTraceLevelTypeInt0
misc.maxTraceLevelTypeInt0
Display trace information between those two +levels (cdebug stream)
misc.catchCoreTypeBoolFalse
By default, cgt do not dump core. +To generate one set this flag to True
+

+
+
+
+

The Controller

+

The Controller window is composed of seven tabs:

+
    +
  1. The Look Tab to select the display style.
  2. +
  3. The Filter Tab the hierarchical levels to be displayed, the look of +rubbers and the dimension units.
  4. +
  5. The Layers&Go Tab to selectively hide/display layers.
  6. +
  7. The Netlist Tab to browse through the netlist. Works in association +with the Selection tab.
  8. +
  9. The Selection Tab allow to view all the currently selected elements.
  10. +
  11. The Inspector Tab browse through either the DataBase, the Cell or +the current selection.
  12. +
  13. The Settings Tab access all the tool’s configuration settings.
  14. +
+
+

The Look Tab

+

You can select how the layout will be displayed. There is a special one +Printer.Coriolis specifically designed for Printing & Snapshots. +You should select it prior to calling the print or snapshot dialog boxes.

+

Controller Look, Snapshot 1

+

+
+
+

The Filter Tab

+

The filter tab let you select what hierarchical levels of your design will be +displayed. Hierarchy level are numbered top-down: the level 0 correspond to +the top-level cell, the level one to the instances of the top-level Cell and +so on.

+

There are also check boxes to enable/disable the processing of Terminal Cell, +Master Cells and Compnents. The processing of Terminal Cell (hierarchy leaf +cells) is disabled by default when you load a hierarchical design and enabled +when you load a single Cell.

+

You can choose what kind of form to give to the rubbers and the type of +unit used to display coordinates.

+
+

Note

+

What are Rubbers: Hurricane uses Rubbers to materialize +physical gaps in net topology. That is, if some wires are missing to +connect two or more parts of net, a rubber will be drawn between them +to signal the gap.

+

For example, after the detailed routing no rubbers should remains. +They have been made very visibles as big violet lines...

+
+

Controller Basic Snapshot

+

+
+
+

The Layers&Go Tab

+

Control the individual display of all layers and Gos.

+
    +
  • Layers correspond to a true physical layer. From a Hurricane point of +view they are all the BasicLayers (could be matched to GDSII).
  • +
  • Gos stands from Graphical Objects, they are drawings that have no +physical existence but are added by the various tools to display extra +information. One good exemple is the density map of the detailed router, +to easily locate congested areas.
  • +
+

For each layer/Go there are two check boxes:

+
    +
  • The normal one triggers the display.
  • +
  • The red-outlined allows objects of that layer to be selectable or not.
  • +
+

Controller Basic Snapshot

+
+
+

The Netlist Tab

+

The Netlist tab shows the list of nets... By default the tab is not +synched with the displayed Cell. To see the nets you must check the +Sync Netlist checkbox. You can narrow the set of displayed nets by +using the filter pattern (supports regular expressions).

+

An very useful feature is to enable the Sync Selection, which will +automatically select all the components of the selected net(s). You can +select multiple nets. In the figure the net auxsc35 is selected and +is highlited in the Viewer.

+

Controller Basic Snapshot + Controller Basic Snapshot

+
+
+

The Selection Tab

+

The Selection tab list all the components currently selecteds. They +can be filtered thanks to the filter pattern.

+

Used in conjunction with the Netlist Sync Selection you will all see +all the components part of net.

+

In this list, you can toggle individually the selection of component by +pressing the t key. When unselected in this way a component is not +removed from the the selection list but instead displayed in red italic. +To see where a component is you may make it blink by repeatedly press +the t key...

+

Controller Basic Snapshot

+
+
+

The Inspector Tab

+

This tab is very useful, but mostly for Coriolis developpers. It allows +to browse through the live DataBase. The Inspector provide three entry points:

+
    +
  • DataBase: Starts from the whole Hurricane DataBase.
  • +
  • Cell: Inspect the currently loaded Cell.
  • +
  • Selection: Inspect the object currently highlited in the Selection tab.
  • +
+

Once an entry point has been activated, you may recursively expore all +it’s fields using the right/left arrows.

+
+

Note

+

Do not put your fingers in the socket: when inspecting +anything, do not modify the DataBase. If any object under inspection +is deleted, you will crash the application...

+
+
+

Note

+

Implementation Detail: the inspector support is done with +Slot, Record and getString().

+
+

Controller Basic Snapshot + Controller Basic Snapshot + Controller Basic Snapshot

+
+
+

The Settings Tab

+

Here comes the description of the Settings tab.

+

Controller Basic Snapshot

+
+
+
+ + +
+
+ + + + +
+ +
+ + + + + +
+ Generated by Sphinx + using a RTD theme on Jul 15, 2017. +
+ + + + + +
Coriolis 2 Documentation + © Copyright 2000-2017, UPMC. +
+
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/documentation/_build/html/UsersGuide/index.html b/documentation/_build/html/UsersGuide/index.html new file mode 100644 index 00000000..ca9f52ab --- /dev/null +++ b/documentation/_build/html/UsersGuide/index.html @@ -0,0 +1,373 @@ + + + + + + + + + + + + Coriolis User’s Guide — Coriolis 2 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/documentation/_build/html/Viewer/Viewer.html b/documentation/_build/html/Viewer/Viewer.html new file mode 100644 index 00000000..cce3f0ea --- /dev/null +++ b/documentation/_build/html/Viewer/Viewer.html @@ -0,0 +1,334 @@ + + + + + + + + + + + + Viewer Reference — Coriolis 2 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + +
+
+
+
    +
  • Docs »
  • + +
  • Viewer Reference
  • +
  • + + + +
  • +
+
+
+
+ +
+

Viewer Reference

+

The Viewer C++ API reference is generated by Doxygen and is +available here: Viewer

+
+ + +
+
+ + + + +
+ +
+ + + + + +
+ Generated by Sphinx + using a RTD theme on Jul 15, 2017. +
+ + + + + +
Coriolis 2 Documentation + © Copyright 2000-2017, UPMC. +
+
+ +
+ +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/documentation/_build/html/_images/ComputerMouse.png b/documentation/_build/html/_images/ComputerMouse.png new file mode 100644 index 00000000..81b89ddf Binary files /dev/null and b/documentation/_build/html/_images/ComputerMouse.png differ diff --git a/documentation/_build/html/_images/Controller-1.png b/documentation/_build/html/_images/Controller-1.png new file mode 100644 index 00000000..964ddbf8 Binary files /dev/null and b/documentation/_build/html/_images/Controller-1.png differ diff --git a/documentation/_build/html/_images/Controller-Filter-1.png b/documentation/_build/html/_images/Controller-Filter-1.png new file mode 100644 index 00000000..71b669ba Binary files /dev/null and b/documentation/_build/html/_images/Controller-Filter-1.png differ diff --git a/documentation/_build/html/_images/Controller-Inspector-1.png b/documentation/_build/html/_images/Controller-Inspector-1.png new file mode 100644 index 00000000..618a1cde Binary files /dev/null and b/documentation/_build/html/_images/Controller-Inspector-1.png differ diff --git a/documentation/_build/html/_images/Controller-Inspector-2.png b/documentation/_build/html/_images/Controller-Inspector-2.png new file mode 100644 index 00000000..ac509d41 Binary files /dev/null and b/documentation/_build/html/_images/Controller-Inspector-2.png differ diff --git a/documentation/_build/html/_images/Controller-Inspector-3.png b/documentation/_build/html/_images/Controller-Inspector-3.png new file mode 100644 index 00000000..0cb730b0 Binary files /dev/null and b/documentation/_build/html/_images/Controller-Inspector-3.png differ diff --git a/documentation/_build/html/_images/Controller-LayersGos-1.png b/documentation/_build/html/_images/Controller-LayersGos-1.png new file mode 100644 index 00000000..fdcaa53d Binary files /dev/null and b/documentation/_build/html/_images/Controller-LayersGos-1.png differ diff --git a/documentation/_build/html/_images/Controller-Look-1.png b/documentation/_build/html/_images/Controller-Look-1.png new file mode 100644 index 00000000..1d095170 Binary files /dev/null and b/documentation/_build/html/_images/Controller-Look-1.png differ diff --git a/documentation/_build/html/_images/Controller-Netlist-1.png b/documentation/_build/html/_images/Controller-Netlist-1.png new file mode 100644 index 00000000..b541b147 Binary files /dev/null and b/documentation/_build/html/_images/Controller-Netlist-1.png differ diff --git a/documentation/_build/html/_images/Controller-Selection-1.png b/documentation/_build/html/_images/Controller-Selection-1.png new file mode 100644 index 00000000..326ab8d7 Binary files /dev/null and b/documentation/_build/html/_images/Controller-Selection-1.png differ diff --git a/documentation/_build/html/_images/Controller-Settings-1.png b/documentation/_build/html/_images/Controller-Settings-1.png new file mode 100644 index 00000000..ef260368 Binary files /dev/null and b/documentation/_build/html/_images/Controller-Settings-1.png differ diff --git a/documentation/_build/html/_images/Coriolis-Soft-Schema.png b/documentation/_build/html/_images/Coriolis-Soft-Schema.png new file mode 100644 index 00000000..93c9135c Binary files /dev/null and b/documentation/_build/html/_images/Coriolis-Soft-Schema.png differ diff --git a/documentation/_build/html/_images/RDS_LCW.png b/documentation/_build/html/_images/RDS_LCW.png new file mode 100644 index 00000000..b6f22d24 Binary files /dev/null and b/documentation/_build/html/_images/RDS_LCW.png differ diff --git a/documentation/_build/html/_images/RDS_VW.png b/documentation/_build/html/_images/RDS_VW.png new file mode 100644 index 00000000..2bd2c1be Binary files /dev/null and b/documentation/_build/html/_images/RDS_VW.png differ diff --git a/documentation/_build/html/_images/SegmentOrientation.png b/documentation/_build/html/_images/SegmentOrientation.png new file mode 100644 index 00000000..4de3a6e4 Binary files /dev/null and b/documentation/_build/html/_images/SegmentOrientation.png differ diff --git a/documentation/_build/html/_images/Viewer-1.png b/documentation/_build/html/_images/Viewer-1.png new file mode 100644 index 00000000..01195845 Binary files /dev/null and b/documentation/_build/html/_images/Viewer-1.png differ diff --git a/documentation/_build/html/_images/Viewer-Netlist-1.png b/documentation/_build/html/_images/Viewer-Netlist-1.png new file mode 100644 index 00000000..6f357c0d Binary files /dev/null and b/documentation/_build/html/_images/Viewer-Netlist-1.png differ diff --git a/documentation/_build/html/_images/bigvia-1.png b/documentation/_build/html/_images/bigvia-1.png new file mode 100644 index 00000000..33a567d7 Binary files /dev/null and b/documentation/_build/html/_images/bigvia-1.png differ diff --git a/documentation/_build/html/_images/bigvia-2.png b/documentation/_build/html/_images/bigvia-2.png new file mode 100644 index 00000000..71f6b7e0 Binary files /dev/null and b/documentation/_build/html/_images/bigvia-2.png differ diff --git a/documentation/_build/html/_images/chip-structure-1.png b/documentation/_build/html/_images/chip-structure-1.png new file mode 100644 index 00000000..8af23393 Binary files /dev/null and b/documentation/_build/html/_images/chip-structure-1.png differ diff --git a/documentation/_build/html/_images/etesian-1.png b/documentation/_build/html/_images/etesian-1.png new file mode 100644 index 00000000..80552016 Binary files /dev/null and b/documentation/_build/html/_images/etesian-1.png differ diff --git a/documentation/_build/html/_images/math/0183b70ce5b7bb56d8ad838429a01d2858d99612.png b/documentation/_build/html/_images/math/0183b70ce5b7bb56d8ad838429a01d2858d99612.png new file mode 100644 index 00000000..ea9f234e Binary files /dev/null and b/documentation/_build/html/_images/math/0183b70ce5b7bb56d8ad838429a01d2858d99612.png differ diff --git a/documentation/_build/html/_images/math/642cf89034341e49c1fbc546ca776e1205ae49c0.png b/documentation/_build/html/_images/math/642cf89034341e49c1fbc546ca776e1205ae49c0.png new file mode 100644 index 00000000..c93ee4ca Binary files /dev/null and b/documentation/_build/html/_images/math/642cf89034341e49c1fbc546ca776e1205ae49c0.png differ diff --git a/documentation/_build/html/_images/math/6a2cfe8749bfed89e3c82527f74daaff6378d70e.png b/documentation/_build/html/_images/math/6a2cfe8749bfed89e3c82527f74daaff6378d70e.png new file mode 100644 index 00000000..1b39c2bb Binary files /dev/null and b/documentation/_build/html/_images/math/6a2cfe8749bfed89e3c82527f74daaff6378d70e.png differ diff --git a/documentation/_build/html/_images/math/7242aab75de488b349c95eca46e25a03ea80c207.png b/documentation/_build/html/_images/math/7242aab75de488b349c95eca46e25a03ea80c207.png new file mode 100644 index 00000000..82088e1c Binary files /dev/null and b/documentation/_build/html/_images/math/7242aab75de488b349c95eca46e25a03ea80c207.png differ diff --git a/documentation/_build/html/_images/math/d3499f8834024d33c997cd9730e31d3a02ebab18.png b/documentation/_build/html/_images/math/d3499f8834024d33c997cd9730e31d3a02ebab18.png new file mode 100644 index 00000000..adb6d5bf Binary files /dev/null and b/documentation/_build/html/_images/math/d3499f8834024d33c997cd9730e31d3a02ebab18.png differ diff --git a/documentation/_build/html/_images/math/e171f7265a6f90fdc6622dfa4a4fd08927ae5fea.png b/documentation/_build/html/_images/math/e171f7265a6f90fdc6622dfa4a4fd08927ae5fea.png new file mode 100644 index 00000000..23b1d137 Binary files /dev/null and b/documentation/_build/html/_images/math/e171f7265a6f90fdc6622dfa4a4fd08927ae5fea.png differ diff --git a/documentation/_build/html/_sources/Contents.txt b/documentation/_build/html/_sources/Contents.txt new file mode 100644 index 00000000..febd0e88 --- /dev/null +++ b/documentation/_build/html/_sources/Contents.txt @@ -0,0 +1,20 @@ +.. Coriolis documentation master file, created by + sphinx-quickstart on Mon Jul 10 15:08:36 2017. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Comprenhensive Table of Contents +================================ + +.. toctree:: + + UsersGuide/index.rst + Stratus/Stratus.rst + DpGen/DpGen.rst + Patterns/Patterns.rst + Hurricane/Hurricane.rst + Viewer/Viewer.rst + CrlCore/CrlCore.rst + Unicorn/Unicorn.rst + PythonCpp/index.rst + RDS/index.rst diff --git a/documentation/_build/html/_sources/CrlCore/CrlCore.txt b/documentation/_build/html/_sources/CrlCore/CrlCore.txt new file mode 100644 index 00000000..d462e48e --- /dev/null +++ b/documentation/_build/html/_sources/CrlCore/CrlCore.txt @@ -0,0 +1,11 @@ +.. -*- Mode: rst -*- + +.. include:: ../etc/definitions.rst + + +==================== +CRL Core Reference +==================== + +The CRL Core C++ API reference is generated by Doxygen_ and is +available here: `CRL Core `_ diff --git a/documentation/_build/html/_sources/DpGen/DpGen.txt b/documentation/_build/html/_sources/DpGen/DpGen.txt new file mode 100644 index 00000000..0d8324d1 --- /dev/null +++ b/documentation/_build/html/_sources/DpGen/DpGen.txt @@ -0,0 +1,11 @@ +.. -*- Mode: rst -*- + +.. include:: ../etc/definitions.rst + + +================= +DpGen Reference +================= + +The DpGen extension of the Stratus Language reference is generated by LaTeX2HTML_ and is +available here: `DpGen `_ diff --git a/documentation/_build/html/_sources/Hurricane/Hurricane.txt b/documentation/_build/html/_sources/Hurricane/Hurricane.txt new file mode 100644 index 00000000..4b1ec994 --- /dev/null +++ b/documentation/_build/html/_sources/Hurricane/Hurricane.txt @@ -0,0 +1,11 @@ +.. -*- Mode: rst -*- + +.. include:: ../etc/definitions.rst + + +===================== +Hurricane Reference +===================== + +The Hurricane C++ API reference is generated by Doxygen_ and is +available here: `Hurricane `_ diff --git a/documentation/_build/html/_sources/Patterns/Patterns.txt b/documentation/_build/html/_sources/Patterns/Patterns.txt new file mode 100644 index 00000000..66c4791c --- /dev/null +++ b/documentation/_build/html/_sources/Patterns/Patterns.txt @@ -0,0 +1,11 @@ +.. -*- Mode: rst -*- + +.. include:: ../etc/definitions.rst + + +==================== +Patterns Reference +==================== + +The Patterns extension of the Stratus Language reference is generated by LaTeX2HTML_ and is +available here: `Patterns `_ diff --git a/documentation/_build/html/_sources/PythonCpp/Configuration.txt b/documentation/_build/html/_sources/PythonCpp/Configuration.txt new file mode 100644 index 00000000..2e9d11e9 --- /dev/null +++ b/documentation/_build/html/_sources/PythonCpp/Configuration.txt @@ -0,0 +1,42 @@ +.. -*- Mode: rst -*- + +.. include:: ../etc/definitions.rst + + +2. Basic File Structure and CMake configuration +================================================= + +As a first example we will consider the ``Hurrican::Library`` +class. To export a class into Python, we must create three files: + +#. ``PyLibrary.h``, defines the ``PyLibrary`` C-Struct and the functions + needed outside the module istself (mostly for ``PyHurricane.cpp``). + +#. ``PyLibrary.cpp``, contains the complete wrapping of the class and + the Python type definition (``PyTypeLibrary``). + +#. ``PyHurricane.cpp``, the definition of the Python module into which + the classes are registered. The module act as a ``namespace`` in + Python so it is good practice to give it the same name as it's + associated C++ namespace. + +|newpage| + +To build a Python module in |cmake|, use the following macro: + + .. code-block:: cmake + + set( pyCpps PyLibrary.cpp + PyHurricane.cpp ) + set( pyIncludes hurricane/isobar/PyLibrary.h + + add_python_module( "${pyCpps}" + "${pyIncludes}" + "isobar;1.0;1" # Name & version of the supporting + # shared library. + Hurricane # Name of the Python module will give: + # Hurricane.so + "${depLibs}" # List of dependency libraries. + include/coriolis2/hurricane/isobar + # Where to install the include files. + ) diff --git a/documentation/_build/html/_sources/PythonCpp/DBoHierarchy.txt b/documentation/_build/html/_sources/PythonCpp/DBoHierarchy.txt new file mode 100644 index 00000000..4c72bf3b --- /dev/null +++ b/documentation/_build/html/_sources/PythonCpp/DBoHierarchy.txt @@ -0,0 +1,439 @@ +.. -*- Mode: rst -*- + +.. include:: ../etc/definitions.rst + + +|newpage| + + +4. Case 2 - Hierarchy of DBo Derived Classes +============================================== + +Now we want to export the following C++ class hierarchy into Python: :: + + PyEntity <-- PyComponent <-+- PyContact + +- PySegment <-+- PyHorizontal + +- PyVertical + + +4.1 Base Class Header +~~~~~~~~~~~~~~~~~~~~~~~ + +**Remark:** this is only a partial description of the tree for the sake of +clarity. + +One important fact to remember is that ``PyEntity`` and ``PyComponent`` +being related to C++ abstract classes, no objects of those types will be +created, only ``PyContact``, ``PyHorizontal`` or ``PyVertical`` will. + +The consequence is that there is no ``PyEntity_Link()`` like in :ref:`3.1` +but instead two functions: + +#. ``PyEntity_NEW()`` which create the relevant ``PyEntity`` *derived* + object from the ``Entity`` one. For example, if the ``Entity*`` given + as argument is in fact a ``Horizontal*``, then the function will + return a ``PyHorizontal*``. + +#. ``EntityCast()`` do the reverse of ``PyEntity_NEW()`` that is, from + a ``PyEntity``, return the C++ *derived* object. Again, if the + ``PyEntity*`` is a ``PyHorizontal*``, the function will cast it as + a ``Horizontal*`` *then* return it as an ``Entity*``. + +.. code-block:: python + + #ifndef ISOBAR_PY_ENTITY_H + #define ISOBAR_PY_ENTITY_H + + #include "hurricane/isobar/PyHurricane.h" + #include "hurricane/Entity.h" + + namespace Isobar { + extern "C" { + + typedef struct { + PyObject_HEAD + Hurricane::Entity* _object; + } PyEntity; + + extern PyObject* PyEntity_NEW ( Hurricane::Entity* entity ); + extern void PyEntity_LinkPyType (); + extern PyTypeObject PyTypeEntity; + extern PyMethodDef PyEntity_Methods[]; + + + #define IsPyEntity(v) ( (v)->ob_type == &PyTypeEntity ) + #define PYENTITY(v) ( (PyEntity*)(v) ) + #define PYENTITY_O(v) ( PYENTITY(v)->_object ) + + } // extern "C". + + Hurricane::Entity* EntityCast ( PyObject* derivedObject ); + + } // Isobar namespace. + + #endif // ISOBAR_PY_ENTITY_H + +|newpage| + + +4.2 Base Class File +~~~~~~~~~~~~~~~~~~~~~ + +Changes from :ref:`3.2 Class Associated File` are: + +#. No call to ``DBoLinkCreateMethod()`` because there must be no ``PyEntity_Link()``, + but the definitions of ``PyEntity_NEW()`` and ``EntityCast``. + +#. For defining the ``PyTypeEntity`` Python type, we call a different + macro: ``PyTypeRootObjectDefinitions``, dedicated to base classes. + + +.. code-block:: c++ + + #include "hurricane/isobar/PyCell.h" + #include "hurricane/isobar/PyHorizontal.h" + #include "hurricane/isobar/PyVertical.h" + #include "hurricane/isobar/PyContact.h" + + namespace Isobar { + using namespace Hurricane; + + extern "C" { + + #if defined(__PYTHON_MODULE__) + + #define METHOD_HEAD(function) GENERIC_METHOD_HEAD(Entity,entity,function) + + DBoDestroyAttribute(PyEntity_destroy ,PyEntity) + + static PyObject* PyEntity_getCell ( PyEntity *self ) + { + Cell* cell = NULL; + HTRY + METHOD_HEAD( "Entity.getCell()" ) + cell = entity->getCell(); + HCATCH + return PyCell_Link( cell ); + } + + PyMethodDef PyEntity_Methods[] = + { { "getCell", (PyCFunction)PyEntity_getCell, METH_NOARGS + , "Returns the entity cell." } + , { "destroy", (PyCFunction)PyEntity_destroy, METH_NOARGS + , "Destroy associated hurricane object, the python object remains." } + , {NULL, NULL, 0, NULL} /* sentinel */ + }; + + + DBoDeleteMethod(Entity) + PyTypeObjectLinkPyType(Entity) + + #else // End of Python Module Code Part. + + PyObject* PyEntity_NEW ( Entity* entity ) + { + if (not entity) { + PyErr_SetString ( HurricaneError, "Invalid Entity (bad occurrence)" ); + return NULL; + } + + Horizontal* horizontal = dynamic_cast(entity); + if (horizontal) return PyHorizontal_Link( horizontal ); + + Vertical* vertical = dynamic_cast(entity); + if (vertical) return PyVertical_Link( vertical ); + + Contact* contact = dynamic_cast(entity); + if (contact) return PyContact_Link( contact ); + + Py_RETURN_NONE; + } + + PyTypeRootObjectDefinitions(Entity) + + #endif // Shared Library Code Part (1). + + } // extern "C". + + + #if !defined(__PYTHON_MODULE__) + + Hurricane::Entity* EntityCast ( PyObject* derivedObject ) { + if (IsPyHorizontal(derivedObject)) return PYHORIZONTAL_O(derivedObject); + if (IsPyVertical (derivedObject)) return PYVERTICAL_O(derivedObject); + if (IsPyContact (derivedObject)) return PYCONTACT_O(derivedObject); + return NULL; + } + + #endif // Shared Library Code Part (2). + + } // Isobar namespace. + +|newpage| + + +4.3 Intermediate Class Header +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Changes from :ref:`3.1 Class Associated Header File` are: + +#. As for ``PyEntity``, and because this is still an abstract class, + there is no ``PyComponent_Link()`` function. + +#. The definition of the ``PyComponent`` |struct| is differs. There is + no ``PyObject_HEAD`` (it is a Python *derived* class). The only + field is of the base class type ``PyEntity`` and for use with + Coriolis macros, **it must** be named ``_baseObject`` (note that + this is *not* a pointer but a whole object). + +.. code-block:: c++ + + #ifndef ISOBAR_PY_COMPONENT_H + #define ISOBAR_PY_COMPONENT_H + + #include "hurricane/isobar/PyEntity.h" + #include "hurricane/Component.h" + + namespace Isobar { + extern "C" { + + typedef struct { + PyEntity _baseObject; + } PyComponent; + + extern PyTypeObject PyTypeComponent; + extern PyMethodDef PyComponent_Methods[]; + extern void PyComponent_LinkPyType (); + + #define IsPyComponent(v) ((v)->ob_type == &PyTypeComponent) + #define PYCOMPONENT(v) ((PyComponent*)(v)) + #define PYCOMPONENT_O(v) (static_cast(PYCOMPONENT(v)->_baseObject._object)) + + } // extern "C". + } // Isobar namespace. + + #endif + + +4.4 Intermediate Class File +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Changes from :ref:`3.2 Class Associated File` are: + +1. Redefinition of the default macros ``ACCESS_OBJECT`` and ``ACCESS_CLASS``. + + * The pointer to the C++ encapsulated object (attribute ``_object``) is hold + by the base class ``PyEntity``. The ``ACCESS_OBJECT`` macro which is tasked + to give access to that attribute is then ``_baseObject._object`` as + ``PyComponent`` is a direct derived class of ``PyEntity``. + + * ``ACCESS_CLASS`` is similar to ``ACCESS_OBJECT`` for accessing the base + class, that is a pointer to ``PyEntity``. + +|newpage| + +2. For defining the ``PyTypeComponent`` Python type, we call a yet different + macro: ``PyTypeInheritedObjectDefinitions()``, dedicated to derived classes. + For this this macro we need to give as argument the derived class and the + base class. + +.. code-block:: c++ + + #include "hurricane/isobar/PyComponent.h" + #include "hurricane/isobar/PyNet.h" + + namespace Isobar { + using namespace Hurricane; + + extern "C" { + + #undef ACCESS_OBJECT + #undef ACCESS_CLASS + #define ACCESS_OBJECT _baseObject._object + #define ACCESS_CLASS(_pyObject) &(_pyObject->_baseObject) + #define METHOD_HEAD(function) GENERIC_METHOD_HEAD(Component,component,function) + + #if defined(__PYTHON_MODULE__) + + DirectGetLongAttribute(PyComponent_getX,getX,PyComponent,Component) + DirectGetLongAttribute(PyComponent_getY,getY,PyComponent,Component) + DBoDestroyAttribute(PyComponent_destroy,PyComponent) + + static PyObject* PyComponent_getNet ( PyComponent *self ) + { + Net* net = NULL; + HTRY + METHOD_HEAD( "Component.getNet()" ) + net = component->getNet( ); + HCATCH + return PyNet_Link( net ); + } + + PyMethodDef PyComponent_Methods[] = + { { "getX" , (PyCFunction)PyComponent_getX , METH_NOARGS + , "Return the Component X value." } + , { "getY" , (PyCFunction)PyComponent_getY , METH_NOARGS + , "Return the Component Y value." } + , { "getNet" , (PyCFunction)PyComponent_getNet , METH_NOARGS + , "Returns the net owning the component." } + , { "destroy", (PyCFunction)PyComponent_destroy, METH_NOARGS + , "destroy associated hurricane object, the python object remains." } + , {NULL, NULL, 0, NULL} /* sentinel */ + }; + + DBoDeleteMethod(Component) + PyTypeObjectLinkPyType(Component) + + #else // Python Module Code Part. + + PyTypeInheritedObjectDefinitions(Component, Entity) + + #endif // Shared Library Code Part. + + } // extern "C". + } // Isobar namespace. + + +4.5 Terminal Class Header +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The contents of this file is almost identical to `4.3 Intermediate Class Header`_, +save for the presence of a ``PyContact_Link()`` function. She is present +at this level because the class is a concrete one and can be instanciated. + +.. code-block:: c++ + + #ifndef ISOBAR_PY_CONTACT_H + #define ISOBAR_PY_CONTACT_H + + #include "hurricane/isobar/PyComponent.h" + #include "hurricane/Contact.h" + + namespace Isobar { + extern "C" { + + typedef struct { + PyComponent _baseObject; + } PyContact; + + extern PyTypeObject PyTypeContact; + extern PyMethodDef PyContact_Methods[]; + extern PyObject* PyContact_Link ( Hurricane::Contact* object ); + extern void PyContact_LinkPyType (); + + #define IsPyContact(v) ( (v)->ob_type == &PyTypeContact ) + #define PYCONTACT(v) ( (PyContact*)(v) ) + #define PYCONTACT_O(v) ( PYCONTACT(v)->_baseObject._baseObject._object ) + + } // extern "C". + } // Isobar namespace. + + #endif // ISOBAR_PY_CONTACT_H + + +4.6 Terminal Class File +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Changes from `4.4 Intermediate Class File`_ are: + +#. As previously, we have to redefine the macros ``ACCESS_OBJECT`` and ``ACCESS_CLASS``. + But, as we are one level deeper into the hierarchy, one more level of + indirection using ``_baseObject`` must be used. + + * ``ACCESS_OBJECT`` becomes ``_baseObject._baseObject._object``. + + * ``ACCESS_CLASS`` becomes ``&(_pyObject->_baseObject._baseObject)``. + +#. For defining the ``PyTypeContact`` Python type, we call again + ``PyTypeInheritedObjectDefinitions()``. It is the same whether the class is + terminal or not. + +#. And, this time, as the Python class is concrete, we call the macro + ``DBoLinkCreateMethod()`` to create the ``PyContact_Link()`` function. + + +.. code-block:: c++ + + #include "hurricane/isobar/PyContact.h" + + namespace Isobar { + using namespace Hurricane; + + extern "C" { + + #undef ACCESS_OBJECT + #undef ACCESS_CLASS + #define ACCESS_OBJECT _baseObject._baseObject._object + #define ACCESS_CLASS(_pyObject) &(_pyObject->_baseObject._baseObject) + #define METHOD_HEAD(function) GENERIC_METHOD_HEAD(Contact,contact,function) + + #if defined(__PYTHON_MODULE__) + + DirectGetLongAttribute(PyContact_getWidth , getWidth , PyContact,Contact) + DirectGetLongAttribute(PyContact_getHeight, getHeight, PyContact,Contact) + DBoDestroyAttribute(PyContact_destroy, PyContact) + + static PyObject* PyContact_create ( PyObject*, PyObject *args ) + { + Contact* contact = NULL; + HTRY + // Usual signature then arguments parsing. + HCATCH + return PyContact_Link(contact); + } + + PyMethodDef PyContact_Methods[] = + { { "create" , (PyCFunction)PyContact_create , METH_VARARGS|METH_STATIC + , "Create a new Contact." } + , { "destroy" , (PyCFunction)PyContact_destroy , METH_NOARGS + , "Destroy associated hurricane object, the python object remains." } + , { "getWidth" , (PyCFunction)PyContact_getWidth , METH_NOARGS + , "Return the contact width." } + , { "getHeight", (PyCFunction)PyContact_getHeight, METH_NOARGS + , "Return the contact height." } + , {NULL, NULL, 0, NULL} /* sentinel */ + }; + + DBoDeleteMethod(Contact) + PyTypeObjectLinkPyType(Contact) + + #else // Python Module Code Part. + + DBoLinkCreateMethod(Contact) + PyTypeInheritedObjectDefinitions(Contact, Component) + + #endif // Shared Library Code Part. + + } // extern "C". + } // Isobar namespace. + + +4.8 Python Module +~~~~~~~~~~~~~~~~~~~ + +.. code-block:: c++ + + DL_EXPORT(void) initHurricane () + { + PyEntity_LinkPyType(); // step 1. + PyComponent_LinkPyType(); + PyContact_LinkPyType(); + + PYTYPE_READY( Entity ) // step 2. + PYTYPE_READY_SUB( Component, Entity ) + PYTYPE_READY_SUB( Contact , Component ) + + __cs.addType( "ent" , &PyTypeEntity , "" , false ); // step 3. + __cs.addType( "comp" , &PyTypeComponent, "", false, "ent" ); + __cs.addType( "contact", &PyTypeContact , "" , false, "comp" ); + + PyObject* module = Py_InitModule( "Hurricane", PyHurricane_Methods ); + if (module == NULL) { + cerr << "[ERROR]\n" + << " Failed to initialize Hurricane module." << endl; + return; + } + + Py_INCREF( &PyTypeContact ); // step 4. + PyModule_AddObject( module, "Contact", (PyObject*)&PyTypeContact ); // step 4. + } diff --git a/documentation/_build/html/_sources/PythonCpp/DBoStandalone.txt b/documentation/_build/html/_sources/PythonCpp/DBoStandalone.txt new file mode 100644 index 00000000..36cdb46e --- /dev/null +++ b/documentation/_build/html/_sources/PythonCpp/DBoStandalone.txt @@ -0,0 +1,395 @@ +.. -*- Mode: rst -*- + +.. include:: ../etc/definitions.rst + + +3. Case 1 - DBo Derived, Standalone +====================================== + +As example, we take ``Library``. This a ``DBo`` derived class, but we +choose not to export the parent classes. From Python, it will appear +as a base class. + +.. _3.1: + +.. _3.1 Class Associated Header File: + +3.1 Class Associated Header File +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Here is the typical content of a header file (for ``PyLibrary``): + +.. code-block:: c++ + + #ifndef PY_LIBRARY_H + #define PY_LIBRARY_H + + #include "hurricane/isobar/PyHurricane.h" + #include "hurricane/Library.h" + + namespace Isobar { + using namespace Hurricane; + + extern "C" { + + typedef struct { + PyObject_HEAD + Library* _object; + } PyLibrary; + + extern PyTypeObject PyTypeLibrary; + extern PyMethodDef PyLibrary_Methods[]; + extern PyObject* PyLibrary_Link ( Hurricane::Library* lib ); + extern void PyLibrary_LinkPyType (); + + + #define IsPyLibrary(v) ( (v)->ob_type == &PyTypeLibrary ) + #define PYLIBRARY(v) ( (PyLibrary*)(v) ) + #define PYLIBRARY_O(v) ( PYLIBRARY(v)->_object ) + + } // extern "C". + } // Isobar namespace. + + #endif // PY_LIBRARY_H + + +The code is organized as follow: + +1. It must have, *as the first include* ``PyHurricane.h``, which provides + the complete bunch of macros needed to build the module. Then the include + of the C++ class we want to wrap (``Library.h``). + +2. As Python is written in C, all the wrapper code has to be but inside + an ``extern "C"`` namespace. + +3. Definition of the wrapped |struct|, ``PyLibrary``. It is standard Python here. + + .. note:: + For our set of macros to work, the name of the pointer to the + C++ class must always be **_object**, and the various functions and + macros defined here must take the name of the class (either in + lowercase, camel case or capitals). + +4. Declaration of the Python type ``PyTypeLibrary`` (standard). + +5. Declaration of the Python type table of methods ``PyLibrary_Methods`` (standard). + +.. _3.6: + +6. Declaration of ``PyLibrary_Link()``, helper to convert a C++ ``Lybrary`` into + a ``PyLibrary`` (put in the support shared library). + +7. Declaration of ``PyLibrary_LinkPyType()``, this function setup the class-level + function of the new Python type (here, ``PyTypeLibrary``). + +8. And, lastly, three macros to: + + * ``IsPylibrary()``, know if a Python object is a ``PyLibrary`` + * ``PYLIBRARY()``, force cast (C style) of a ``PyObject`` into a ``PyLibrary``. + * ``PYLIBRARY_O()``, extract the C++ object (``Library*``) from the Python + object (``PyLibrary``). + + +.. _3.2 Class Associated File: + +3.2 Class Associated File +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +3.2.1 Head of the file +------------------------ + +.. code-block:: c++ + + #include "hurricane/isobar/PyLibrary.h" + #include "hurricane/isobar/PyDataBase.h" + #include "hurricane/isobar/PyCell.h" + + namespace Isobar { + using namespace Hurricane; + + extern "C" { + + #define METHOD_HEAD(function) GENERIC_METHOD_HEAD(Library,lib,function) + +As for the header, all the code must be put inside a ``extern "C"`` namespace. + +A convenience macro ``METHOD_HEAD()`` must be defined, by refining +``GENERIC_METHOD_HEAD()``. This macro will be used in the method wrappers +below to cast the ``_object`` field of the Python object into the +appropriate C++ class, this is done using a C-style cast. +The parameters of that macro are: + +#. The C++ encapsulated class (``Library``). +#. The name of the *variable* that will be used to store a pointer + to the C++ working object. +#. The name of the C++ method which is to be wrapped. + + +3.2.2 The Python Module Part +------------------------------ + +First, we have to build all the wrappers to the C++ methods of +the class. For common predicates, accessors, and mutators macros +are supplied. + +Wrapping of the ``Library::getCell()`` method: + +.. code-block:: c++ + + static PyObject* PyLibrary_getCell ( PyLibrary* self, PyObject* args ) + { + Cell* cell = NULL; + + HTRY + METHOD_HEAD( "Library.getCell()" ) + char* name = NULL; + if (PyArg_ParseTuple(args,"s:Library.getCell", &name)) { + cell = lib->getCell( Name(name) ); + } else { + PyErr_SetString( ConstructorError + , "invalid number of parameters for Library::getCell." ); + return NULL; + } + HCATCH + + return PyCell_Link(cell); + } + +Key points about this method wrapper: + +#. The ``HTRY`` / ``HCATCH`` macros provides an insulation from the C++ + exceptions. If one is emitted, it will be catched and transformed in + a Python one. This way, the Python program will be cleanly interrupted + and the usual stack trace displayed. + +#. The returned value of this method is of type ``Cell*``, we have to + transform it into a Python one. This is done with ``PyCell_Link()``. + This macro is supplied by the ``PyCell.h`` header and this is why + it must be included. + +|newpage| + + +Wrapping of the ``Library::create()`` method: + +.. code-block:: c++ + + static PyObject* PyLibrary_create( PyObject*, PyObject* args ) + { + PyObject* arg0; + PyObject* arg1; + Library* library = NULL; + + HTRY + __cs.init( "Library.create" ); // Step (1). + if (not PyArg_ParseTuple( args, "O&O&:Library.create" + , Converter, &arg0 + , Converter, &arg1 )) { // Step (2). + PyErr_SetString( ConstructorError + , "invalid number of parameters for Library constructor." ); + return NULL; + } + if (__cs.getObjectIds() == ":db:string") { // Step (3.a) + DataBase* db = PYDATABASE_O(arg0); + library = Library::create( db, Name(PyString_AsString(arg1)) ); + } else if (__cs.getObjectIds() == ":library:string") { // Step (3.b) + Library* masterLibrary = PYLIBRARY_O(arg0); + library = Library::create( masterLibrary, Name(PyString_AsString(arg1)) ); + } else { + PyErr_SetString( ConstructorError + , "invalid number of parameters for Library constructor." ); + return NULL; + } + HCATCH + + return PyLibrary_Link( library ); + } + +Key point about this constructor: + +#. We want the Python interface to mimic as closely as possible the + C++ API. As such, Python object will be created using a static + ``.create()`` method. So we do not use the usual Python allocation + mechanism. + +#. As it is a *static* method, there is no first argument. + +#. Python do not allow function overload like C++. To emulate that + behavior we use the ``__cs`` object (which is a global variable). + + #. Init/reset the ``__cs`` object: see *step (1)*. + + #. Call ``PyArg_ParseTuple()``, read every mandatory or optional + argument as a Python object (``"O&"``) and use ``Converter`` + on each one. ``Converter`` will determine the real type of + the Python object given as argument by looking at the + encapsulated C++ class. It then update the ``__cs`` object. + Done in *step (2)* + + #. After the call to ``PyArg_ParseTuple()``, the function + ``__cs.getObjectIds()`` will return the *signature* of + the various arguments. In our case, the valid signatures + will be ``":db:string"`` (*step (3.a)*a) and ``":library:string"`` + (*step (3.b)*). + + #. Call the C++ method after extracting the C++ objects from + the Python arguments. Note the use of the ``PYLIBRARY_O()`` + and ``PYDATABSE_O()`` macros to perform the conversion. + +#. Return the result, encapsulated through a call to ``PyLibrary_Link()``. + +|newpage| + + +Wrapping of the ``Library::destroy()`` method: + +.. code-block:: c++ + + DBoDestroyAttribute(PyLibrary_destroy, PyLibrary) + +For C++ classes **that are derived** from ``DBo``, the destroy method +wrapper must be defined using the macro ``DBoDestroyAttribute()``. +This macro implements the bi-directional communication mechanism +using ``Hurricane::Property``. It **must not** be used for +non ``DBo`` derived classes. + + +Defining the method table of the PyLibrary type: + +.. code-block:: c++ + + PyMethodDef PyLibrary_Methods[] = + { { "create" , (PyCFunction)PyLibrary_create , METH_VARARGS|METH_STATIC + , "Creates a new library." } + , { "getCell" , (PyCFunction)PyLibrary_getCell, METH_VARARGS + , "Get the cell of name " } + , { "destroy" , (PyCFunction)PyLibrary_destroy, METH_NOARGS + , "Destroy associated hurricane object The python object remains." } + , {NULL, NULL, 0, NULL} /* sentinel */ + }; + + +This is standard Python/C API. The name of the ``PyMethodDef`` table must be +named from the class: ``PyLibrary_Methods``. + + +3.2.3 Python Type Linking +--------------------------- + +Defining the ``PyTypeLibrary`` class methods and the type linking function. + +Those are the functions for the Python object itself to work, not the +wrapped method from the C++ class. + +.. note:: + At this point we **do not** define the ``PyTypeLibrary`` itself. + Only it's functions and a function to set them up *once* the + type will be defined. + +.. code-block:: c++ + + DBoDeleteMethod(Library) + PyTypeObjectLinkPyType(Library) + + +The macro ``DBoDeleteMethod()`` define the function to delete a +``PyLibrary`` *Python* object. Again, do not mistake it for the deletion +of the C++ class (implemented by ``DBoDestroyAttribute()``). +Here again, ``DBoDeleteMethod()`` is specially tailored for +``DBo`` derived classes. + +.. _PyLibrary_LinkPyType(): + +To define ``PyLibrary_LinkPyType()``, use the ``PyTypeObjectLinkPyType()`` +macro. This macro is specific for ``DBo`` derived classes that are seen as +base classes under Python (i.e. we don't bother exposing the base +class under Python). ``PyLibrary_LinkPyType()`` setup the class functions +in the ``PyTypeLibrary`` type object, it **must** be called in the +Python module this class is part of (in this case: ``PyHurricane.cpp``). +This particular flavor of the macro *will define* and setup the +following class functions: + +* ``PyTypeLibrary.tp_compare`` (defined by the macro). +* ``PyTypeLibrary.tp_repr`` (defined by the macro). +* ``PyTypeLibrary.tp_str`` (defined by the macro). +* ``PyTypeLibrary.tp_hash`` (defined by the macro). +* ``PyTypeLibrary.tp_methods`` sets to the previously defined ``PyLibrary_Methods`` table. +* ``PyTypeLibrary.tp_dealloc`` is set to a function that *must* be named ``PyLibrary_DeAlloc``, + this is what ``DBoDeleteMethod`` does. It is *not* done by ``PyTypeObjectLinkPyType``. + +Defining the ``PyTypeLibrary`` type: + + +3.2.4 The Shared Library Part +------------------------------- + +This part will be put in a separate supporting shared library, allowing +other Python module to link against it (and make use of its symbols). + +.. code-block:: c++ + + DBoLinkCreateMethod(Library) + PyTypeObjectDefinitions(Library) + + +To define ``PyTypeLibrary``, use the ``PyTypeObjectDefinitions()`` macro. +This macro is specific for classes that, as exposed by Python, +are neither *derived* classes nor *base* classes for others. +That is, they are standalone from the inheritance point of view. + +The ``DBoLinkCreateMethod()`` macro will define the ``PyLibrary_Link()`` +function which is responsible for encapsulating a C++ ``Library`` object +into a Python ``PyLibrary`` one. + + +3.3 Python Module (C++ namespace) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +We use the Python module to replicate the C++ *namespace*. Thus, for the +``Hurricane`` namespace we create a Python ``Hurricane`` module which is +defined in the ``PyHurricane.cpp`` file, then we add into that module +dictionary all the Python types encapsulating the C++ classes of that +namespace. + +.. code-block:: c++ + + DL_EXPORT(void) initHurricane () + { + PyLibrary_LinkPyType(); // step 1. + + PYTYPE_READY( Library ) // step 2. + + __cs.addType( "library", &PyTypeLibrary, "", false ); // step 3. + + PyObject* module = Py_InitModule( "Hurricane", PyHurricane_Methods ); + if (module == NULL) { + cerr << "[ERROR]\n" + << " Failed to initialize Hurricane module." << endl; + return; + } + + Py_INCREF( &PyTypeLibrary ); // step 4. + PyModule_AddObject( module, "Library", (PyObject*)&PyTypeLibrary ); // step 4. + } + +The ``initHurricane()`` initialisation function shown above has +been scrubbed of everything not relevant to the ``PyLibrary`` class. +The integration of the ``PyLibrary`` class into the module needs +four steps: + +#. A call to `PyLibrary_LinkPyType()`_ to hook the Python type functions + in the Python type object. + +#. A call to the ``PYTYPE_READY()`` macro (standard Python). + +#. Registering the type into the ``__cs`` object, with ``addType()``. + The arguments are self explanatory, save for the last which is a + boolean to tell if this is a *derived* class or not. + +#. Adding the type object (``PyTypeLibrary``) into the dictionnary of + the module itself. This allow to mimic closely the C++ syntax: + + .. code-block:: python + + import Hurricane + lib = Hurricane.Library.create( db, 'root' ) diff --git a/documentation/_build/html/_sources/PythonCpp/DbU.txt b/documentation/_build/html/_sources/PythonCpp/DbU.txt new file mode 100644 index 00000000..930e76d1 --- /dev/null +++ b/documentation/_build/html/_sources/PythonCpp/DbU.txt @@ -0,0 +1,67 @@ +.. -*- Mode: rst -*- + +.. include:: ../etc/definitions.rst + + +6. Encapsulating DbU +====================== + +While ``Hurricane::DbU`` is a class, the ``Hurricane::DbU::Unit`` is only +a ``typedef`` over ``uint64_t``. The ``DbU`` class only provides a set of +static methods to manipulate and convert to and from other units. +At Python level, ``DbU::Unit`` will be stored in plain ``long long``. + +When a ``DbU::Unit`` argument is expected in a Python functions, just use +the ``DbU::Unit PyAny_AsLong( PyObject* )`` function to convert it. + +For example, if we explicit the expension of: + +.. code-block:: c++ + + DirectSetLongAttribute(PyPoint_SetX,setX,PyPoint,Point) + +|newpage| + +We would get: + +.. code-block:: c++ + + static PyObject* PyPoint_setX ( PyPoint *self, PyObject* args ) + { + Point* cobject = static_cast( self->_object ); + if (cobject == NULL) { + PyErr_SetString( ProxyError + , "Attempt to call Point.setX() on an unbound Hurricane object" ); + return NULL; + } + + HTRY + PyObject* arg0 = NULL; + if (not PyArg_ParseTuple( args, "O:Point.setX()", &arg0 )) + return ( NULL ); + cobject->setX( Isobar::PyAny_AsLong(arg0) ); + HCATCH + Py_RETURN_NONE; + } + + +For the other way around, use ``PyObject* PyDbU_FromLong( DbU::Unit )``. + +.. code-block:: c++ + + DirectGetLongAttribute(PyPoint_GetX,getX,PyPoint,Point) + +We would get: + +.. code-block:: c++ + + static PyObject* PyPoint_GetX ( PyPoint *self, PyObject* args ) + { + Point* cobject = static_cast( self->_object ); + if (cobject == NULL) { + PyErr_SetString( ProxyError + , "Attempt to call Point.getX() on an unbound Hurricane object" ); + return NULL; + } + return Isobar::PyDbU_FromLong(cobject->getX()); + } diff --git a/documentation/_build/html/_sources/PythonCpp/Introduction.txt b/documentation/_build/html/_sources/PythonCpp/Introduction.txt new file mode 100644 index 00000000..5a3300e4 --- /dev/null +++ b/documentation/_build/html/_sources/PythonCpp/Introduction.txt @@ -0,0 +1,185 @@ +.. -*- Mode: rst -*- + +.. include:: ../etc/definitions.rst + + +1. Introduction +================= + +* This document is written for people already familiar with the + `Python/C API Reference Manual`_. + +* The macros provided by the Hurricane Python/C API are written using + the standard Python C/API. That is, you may not use them and write + directly your functions with the original API or any mix between. + You only have to respect some naming convention. + +* Coriolis is build against Python 2.7. + + +1.1 First, A Disclaimer +~~~~~~~~~~~~~~~~~~~~~~~~~ + +The Hurricane Python/C++ API has been written about ten years ago, at a time +my mastering of template programming was less than complete. This is why this +interface is build with old fashioned C macro instead of C++ template. + +It is my hope that at some point in the future I will have time to completly +rewrite it, borrowing the interface from ``boost::python``. + + +1.2 About Technical Choices +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Some would say, why not use *off the shelf* wrappers like ``swig`` +or ``boost::python``, here are some clues. + +#. **Partial exposure of the C++ class tree.** We expose at Python level + C++ base classes, only if they provides common methods that we want + to see. Otherwise, we just show them as base classes under Python. + For instance ``Library`` is derived from ``DBo``, but we won't see + it under Python. + +#. **Bi-directional communication.** When a Python object is deleted, the + wrapper obviously has a pointer toward the underlying C++ object and + is able to delete it. But, the reverse case can occurs, meaning that + you have a C++ object wrapped in Python and the database delete the + underlying object. The wrapped Python object *must* be informed that + it no longer refer a valid C++ one. Moreover, as we do not control + when Python objects gets deleteds (that is, when their reference count + reaches zero), we can have valid Python object with a dangling + C++ pointer. So our Python objects can be warned by the C++ objects + that they are no longer valid and any other operation than the + deletion should result in a severe non-blocking error. + + To be precise, this apply to persistent object in the C++ database, + like ``Cell``, ``Net``, ``Instance`` or ``Component``. Short lived + objects like ``Box`` or ``Point`` retains the classic Python behavior. + + Another aspect is that, for all derived ``DBo`` objects, one and only + one Python object is associated. For one given ``Instance`` object we + will always return the *same* ``PyInstance`` object, thanks to the + bi-directional link. Obviously, the *reference count* of the + ``PyInstance`` is managed accordingly. This mechanism is implemented + by the ``PyInstance_Link()`` function. + +#. **Linking accross modules.** As far as I understand, the wrappers + are for monolithic libraries. That is, you wrap the entire library + in one go. But Hurricane has a modular design, the core database + then various tools. We do not, and cannot, have one gigantic wrapper + that would encompass all the libraries in one go. We do one Python + module for one C++ library. + + This brings another issue, at Python level this time. The Python + modules for the libraries have to share some functions. Python + provides a mechanism to pass C function pointers accross modules, + but I did found it cumbersome. Instead, all our modules are split + in two: + + * The first part contains the classic Python module code. + * The second part is to be put in a separate dynamic library that + will hold the shared functions. The Python module is dynamically linked + against that library like any other. And any other Python module + requiring the functions will link against the associated shared + library. + + Each module file will be compiled *twice*, once to build the Python + module (``__PYTHON_MODULE`` is defined) and once to build the supporting + shared library (``__PYTHON_MODULE__`` **not** defined). This tricky + double compilation is taken care of though the ``add_python_module`` + ``cmake`` macro. + + For the core Hurricane library we will have: + + * ``Hurricane.so`` the Python module (use with: ``import Hurricane``). + * ``libisobar.so.1.0`` the supporting shared library. + + The ``PyLibrary.cpp`` file will have the following structure: + + .. code-block:: c++ + + #include "hurricane/isobar/PyLibrary.h" + + namespace Isobar { + + extern "C" { + + #if defined(__PYTHON_MODULE__) + + // +=================================================================+ + // | "PyLibrary" Python Module Code Part | + // +=================================================================+ + // + // The classic part of a Python module. Goes into Hurricane.so. + + + #else // End of Python Module Code Part. + + // x=================================================================x + // | "PyLibrary" Shared Library Code Part | + // x=================================================================x + // + // Functions here will be part of the associated shared library and + // made available to all other Python modules. Goes into libisobar.so.1.0 + + + # endif // Shared Library Code Part. + + } // extern "C". + + } // Isobar namespace. + + + This way, we do not rely upon a pointer transmission through Python + modules, but directly uses linker capabilities. + + +1.3 Botched Design +~~~~~~~~~~~~~~~~~~~~ + +The mechanism to compute the signature of a call to a Python function, +the ``__cs`` object, is much too complex and, in fact, not needed. +At some point I may root it out, but it is used in so many places... + +What I should have used the ``"O!"`` capablity of ``PyArg_ParseTuple()``, +like in the code below: + +|newpage| + +.. code-block:: c++ + + static PyObject* PyContact_create ( PyObject*, PyObject *args ) + { + Contact* contact = NULL; + HTRY + PyNet* pyNet = NULL; + PyLayer* pyLayer = NULL; + PyComponent* pyComponent = NULL; + DbU::Unit x = 0; + DbU::Unit y = 0; + DbU::Unit width = 0; + DbU::Unit height = 0; + + if (PyArg_ParseTuple( args, "O!O!ll|ll:Contact.create" + , &PyTypeNet , &pyNet + , &PyTypeLayer, &pyLayer + , &x, &y, &width, &height)) { + contact = Contact::create( PYNET_O(pyNet), PYLAYER_O(pyLayer) + , x, y, width, height ); + } else { + PyErr_Clear(); + if (PyArg_ParseTuple( args, "O!O!ll|ll:Contact.create" + , &PyTypeComponent, &pyComponent + , &PyTypeLayer , &pyLayer + , &x, &y, &width, &height)) { + contact = Contact::create( PYCOMPONENT_O(pyComponent), PYLAYER_O(pyLayer) + , x, y, width, height ); + } else { + PyErr_SetString( ConstructorError + , "invalid number of parameters for Contact constructor." ); + return NULL; + } + } + HCATCH + return PyContact_Link( contact ); + } diff --git a/documentation/_build/html/_sources/PythonCpp/Name.txt b/documentation/_build/html/_sources/PythonCpp/Name.txt new file mode 100644 index 00000000..bb4470e8 --- /dev/null +++ b/documentation/_build/html/_sources/PythonCpp/Name.txt @@ -0,0 +1,9 @@ +.. -*- Mode: rst -*- + +.. include:: ../etc/definitions.rst + + +7. No C++ Hurricane::Name encapsulation +========================================== + +To be written. diff --git a/documentation/_build/html/_sources/PythonCpp/NonDBo.txt b/documentation/_build/html/_sources/PythonCpp/NonDBo.txt new file mode 100644 index 00000000..db9f570a --- /dev/null +++ b/documentation/_build/html/_sources/PythonCpp/NonDBo.txt @@ -0,0 +1,171 @@ +.. -*- Mode: rst -*- + +.. include:: ../etc/definitions.rst + + +5. Case 3 - Non-DBo Standalone Classe +======================================= + +Let's have a look at the encapsulation of ``Hurricane::Point``. + +Non-BDo derived classes do not support the bi-directionnal communication. +So each Python object is associated with one C++ object. The C++ object +is created and deleted along with the Python one. This behavior implies +that the C++ object is *copy constructible* (which should be the case). + + +5.1 Class Header +~~~~~~~~~~~~~~~~~~ + +Changes from :ref:`3.1 Class Associated Header File`: + +* There is no ``PyPoint_Link()`` function, as it's related to the + bi-directional communication mechanism. + +.. note:: + **About the _object attribute** of the PyPoint. As the C++ object life span + (``Point``) is linked to the Python (``PyPoint``) one, we may have used a + value instead of a pointer. It is best to keep a pointer as the macros + written for ``DBo`` derived classes will remain usables. + + +.. code-block:: c++ + + #ifndef ISOBAR_PY_POINT_H + #define ISOBAR_PY_POINT_H + + #include "hurricane/isobar/PyHurricane.h" + #include "hurricane/Point.h" + + namespace Isobar { + extern "C" { + + typedef struct { + PyObject_HEAD + Hurricane::Point* _object; + } PyPoint; + + extern PyTypeObject PyTypePoint; + extern PyMethodDef PyPoint_Methods[]; + extern void PyPoint_LinkPyType(); + + #define IsPyPoint(v) ( (v)->ob_type == &PyTypePoint ) + #define PYPOINT(v) ( (PyPoint*)(v) ) + #define PYPOINT_O(v) ( PYPOINT(v)->_object ) + + } // extern "C". + } // Isobar namespace. + + #endif // ISOBAR_PY_POINT_H + +|newpage| + + +5.2 Class File +~~~~~~~~~~~~~~~~ + +Changes from :ref:`3.2 Class Associated File`: + +* As there is no ``PyPoint_Link()`` function, there is no call to any + flavor of the ``DBoLinkcreatemethod()`` macro (obvious as it's *not* + a ``DBo``). + +* To use the standard Python constructor, we have to define ``PyPoint_NEW()`` + and ``PyPoint_Init()`` functions, I'm not absolutely certain that the later + needs to be defined (that part is still not clear to me from the Python doc). + +* As it's not a ``DBo`` there is no ``destroy()`` method, so no call to + ``DirectDestroyMethod()`` + +* Lastly, as this object has a ``PyPoint_NEW()`` (field ``tp_new``) and + a ``PyPoint_Init()`` (field ``tp_init``) we have to use the macro + ``PyTypeObjectLinkPyTypeNewInit()`` to define ``PyPoint_LinkPyType()``. + + +.. code-block:: c++ + + #include "hurricane/isobar/PyPoint.h" + + namespace Isobar { + using namespace Hurricane; + + extern "C" { + + #define METHOD_HEAD(function) GENERIC_METHOD_HEAD(Point,point,function) + + #if defined(__PYTHON_MODULE__) + + static PyObject* PyPoint_NEW ( PyObject* module, PyObject *args ) + { + Point* point = NULL; + HTRY + PyObject* arg0 = NULL; + PyObject* arg1 = NULL; + + __cs.init( "Point.Point" ); + if (not PyArg_ParseTuple( args,"|O&O&:Point.Point" + , Converter,&arg0 + , Converter,&arg1 )) { + PyErr_SetString ( ConstructorError + , "invalid number of parameters for Point constructor." ); + return NULL; + } + + if (__cs.getObjectIds() == "") + { point = new Point()); } + else if (__cs.getObjectIds() == ":point") + { point = new Point( *PYPOINT_O(arg0) ); } + else if (__cs.getObjectIds() == ":int:int") + { point = new Point( PyAny_AsLong(arg0), PyAny_AsLong(arg1) ); } + else { + PyErr_SetString ( ConstructorError + , "invalid number of parameters for Point constructor." ); + return NULL; + } + + PyPoint* pyPoint = PyObject_NEW( PyPoint, &PyTypePoint ); + if (pyPoint == NULL) { delete point; return NULL; } + pyPoint->_object = point; + HCATCH + + return (PyObject*)pyPoint; + } + + static int PyPoint_Init ( PyPoint* self, PyObject* args, PyObject* kwargs ) + { return 0; } + + DirectGetLongAttribute(PyPoint_getX,getX,PyPoint,Point) + DirectGetLongAttribute(PyPoint_getY,getY,PyPoint,Point) + DirectSetLongAttribute(PyPoint_SetX,setX,PyPoint,Point) + DirectSetLongAttribute(PyPoint_SetY,setY,PyPoint,Point) + + PyMethodDef PyPoint_Methods[] = + { { "getX" , (PyCFunction)PyPoint_getX , METH_NOARGS + , "Return the Point X value." } + , { "getY" , (PyCFunction)PyPoint_getY , METH_NOARGS + , "Return the Point Y value." } + , { "setX" , (PyCFunction)PyPoint_SetX , METH_VARARGS + , "Modify the Point X value." } + , { "setY" , (PyCFunction)PyPoint_SetY , METH_VARARGS + , "Modify the Point Y value." } + , {NULL, NULL, 0, NULL} /* sentinel */ + }; + + DirectDeleteMethod(PyPoint_DeAlloc,PyPoint) + PyTypeObjectLinkPyTypeNewInit(Point) + + #else // Python Module Code Part. + + PyTypeObjectDefinitions(Point) + + #endif // Shared Library Code Part. + + } // extern "C". + } // Isobar namespace. + + +5.2 Class File +~~~~~~~~~~~~~~~~ + +To put it bluntly, there is no difference in the Python module for +a standalone ``DBo`` class and a non-``DBo`` class. diff --git a/documentation/_build/html/_sources/PythonCpp/index.txt b/documentation/_build/html/_sources/PythonCpp/index.txt new file mode 100644 index 00000000..cb5575c2 --- /dev/null +++ b/documentation/_build/html/_sources/PythonCpp/index.txt @@ -0,0 +1,23 @@ +.. -*- mode: rst; explicit-buffer-name: "index.rst" -*- + +.. include:: ../etc/definitions.rst + + +=================================== +Hurricane Python/C++ API Tutorial +=================================== + +Printable version of this document `PythonCpp.pdf <../../../pdf/main/PythonCpp.pdf>`_. + + +.. toctree:: + :maxdepth: 2 + + Introduction.rst + Configuration.rst + DBoStandalone.rst + DBoHierarchy.rst + NonDBo.rst + DbU.rst + Name.rst + diff --git a/documentation/_build/html/_sources/RDS/RDSpage.txt b/documentation/_build/html/_sources/RDS/RDSpage.txt new file mode 100644 index 00000000..be3aa644 --- /dev/null +++ b/documentation/_build/html/_sources/RDS/RDSpage.txt @@ -0,0 +1,474 @@ +.. -*- Mode: rst -*- + +.. include:: ../etc/definitions.rst + + +.. Tools +.. |ocp| replace:: ``ocp`` +.. |nero| replace:: ``nero`` +.. |ring| replace:: ``ring`` +.. |s2r| replace:: ``s2r`` +.. |druc| replace:: ``druc`` +.. |graal| replace:: ``graal`` +.. |cougar| replace:: ``cougar`` +.. |cif| replace:: ``cif`` +.. |gds| replace:: ``gds`` +.. |phseg| replace:: ``phseg`` +.. |phvia| replace:: ``phvia`` + +.. RDS file syntax. +.. |MBK_TO_RDS_SEGMENT| replace:: ``MBK_TO_RDS_SEGMENT`` +.. |MBK_TO_RDS_VIA| replace:: ``MBK_TO_RDS_VIA`` +.. |MBK_TO_RDS_BIGVIA_HOLE| replace:: ``MBK_TO_RDS_BIGVIA_HOLE`` +.. |MBK_TO_RDS_BIGVIA_METAL| replace:: ``MBK_TO_RDS_BIGVIA_METAL`` +.. |MBK_WIRESETTING| replace:: ``MBK_WIRESETTING`` +.. |ALL| replace:: ``ALL`` +.. |DRC| replace:: ``DRC`` +.. |EXT| replace:: ``EXT`` +.. |VW| replace:: ``VW`` +.. |LCW| replace:: ``LCW`` +.. |RCW| replace:: ``RCW`` +.. |ALUx| replace:: ``ALUx`` +.. |CALUx| replace:: ``CALUx`` +.. |TALUx| replace:: ``TALUx`` +.. |ALU1| replace:: ``ALU1`` +.. |POLY| replace:: ``POLY`` +.. |NTIE| replace:: ``NTIE`` +.. |PTIE| replace:: ``PTIE`` +.. |NDIF| replace:: ``NDIF`` +.. |PDIF| replace:: ``PDIF`` +.. |PWELL| replace:: ``PWELL`` +.. |NTRANS| replace:: ``NTRANS`` +.. |PTRANS| replace:: ``PTRANS`` +.. |CONT_DIF_N| replace:: ``CONT_DIF_N`` +.. |CONT_DIF_P| replace:: ``CONT_DIF_P`` +.. |CONT_BODY_N| replace:: ``CONT_BODY_N`` +.. |CONT_BODY_P| replace:: ``CONT_BODY_P`` +.. |CONT_POLY| replace:: ``CONT_POLY`` +.. |CONT_VIA| replace:: ``CONT_VIA`` +.. |CONT_VIAx| replace:: ``CONT_VIAx`` +.. |C_X_N| replace:: ``C_X_N`` +.. |C_X_P| replace:: ``C_X_P`` +.. |RDS_NDIF| replace:: ``RDS_NDIF`` +.. |RDS_NIMP| replace:: ``RDS_NIMP`` +.. |RDS_ACTIV| replace:: ``RDS_ACTIV`` +.. |RDS_GATE| replace:: ``RDS_GATE`` +.. |RDS_POLY| replace:: ``RDS_POLY`` +.. |RDS_ALU1| replace:: ``RDS_ALU1`` + +.. Stand-alone images. +.. |RDS_VW| image:: ./images/RDS_VW.png + :alt: RDS Variable Width Rule + :align: middle + :width: 60% + +.. |RDS_LCW| image:: ./images/RDS_LCW.png + :alt: RDS Left Constant Width Rule + :align: middle + :width: 40% + +.. |SegmentOrientation| image:: ./images/SegmentOrientation.png + :alt: Symbolic Segment Orientations + :align: middle + :width: 50% + +.. |BIGVIA_1| image:: ./images/bigvia-1.png + :alt: BIGVIA holes + :align: middle + :width: 40% + +.. |BIGVIA_2| image:: ./images/bigvia-2.png + :alt: BIGVIA holes overlap + :align: middle + :width: 40% + + + +|newpage| + + +Symbolic Layout +=============== + +Symbolic Components +~~~~~~~~~~~~~~~~~~~ + +A symbolic layout is, in practice, made of only of three objects: + +=========================== ============ =================================================== +Object |MBK| Explanation +=========================== ============ =================================================== +Segments |phseg| Oriented segments with a width and an orientation. +VIAs & contacts |phvia| Boils down to just a point. +Big VIAs & Big Contacts |phvia| Point with a width and a height + That is a rectangle of width by height centered + on the VIA coordinates. +=========================== ============ =================================================== + +Each of thoses objects is associated to a *symbolic layer* which will +control how the object is translated in many *real rectangles*. + ++---------+---------------+-------------+--------------------------------------------+ +| |MBK| | Layer Name | Usable By | Usage | ++=========+===============+=============+============================================+ +| |phseg| | |NWELL| | Segment | N Well | +| +---------------+-------------+--------------------------------------------+ +| | |PWELL| | Segment | P Well | +| +---------------+-------------+--------------------------------------------+ +| | |NDIF| | Segment | N Diffusion | +| +---------------+-------------+--------------------------------------------+ +| | |PDIF| | Segment | P Diffusion | +| +---------------+-------------+--------------------------------------------+ +| | |NTIE| | Segment | N Tie | +| +---------------+-------------+--------------------------------------------+ +| | |PTIE| | Segment | P Tie | +| +---------------+-------------+--------------------------------------------+ +| | |NTRANS| | Segment | N transistor, in |Alliance|, a transistor | +| | | | is represented as a segment (it's grid). | +| +---------------+-------------+--------------------------------------------+ +| | |PTRANS| | Segment | P transistor | +| +---------------+-------------+--------------------------------------------+ +| | |POLY| | Segment | Polysilicium | +| +---------------+-------------+--------------------------------------------+ +| | |ALUx| | Segment | Metal level *x* | +| +---------------+-------------+--------------------------------------------+ +| | |CALUx| | Segment | Metal level *x*, that can be used by the | +| | | | upper hierarchical level as a connector. | +| | | | From the layout point of view it is the | +| | | | same as |ALUx|. | +| +---------------+-------------+--------------------------------------------+ +| | |TALUx| | Segment | Blockage for metal level *x*. Will | +| | | | diseappear in the real layout as it is an | +| | | | information for the P&R tools only. | ++---------+---------------+-------------+--------------------------------------------+ +| |phvia| | |CONT_BODY_N| | VIA, BIGVIA | Contact to N Well | +| +---------------+-------------+--------------------------------------------+ +| | |CONT_BODY_P| | VIA, BIGVIA | Contact to P Well | +| +---------------+-------------+--------------------------------------------+ +| | |CONT_DIF_N| | VIA, BIGVIA | Contact to N Diffusion | +| +---------------+-------------+--------------------------------------------+ +| | |CONT_DIF_P| | VIA, BIGVIA | Contact to P Diffusion | +| +---------------+-------------+--------------------------------------------+ +| | |CONT_POLY| | VIA, BIGVIA | Contact to polysilicium | +| +---------------+-------------+--------------------------------------------+ +| | |CONT_VIA| | VIA, BIGVIA | Contact between metal1 and metal2 | +| +---------------+-------------+--------------------------------------------+ +| | |CONT_VIAx| | VIA, BIGVIA | Contact between metal *x* and metal *x+1*. | +| | | | The index is the the one of the bottom | +| | | | metal of the VIA. | +| +---------------+-------------+--------------------------------------------+ +| | |C_X_N| | VIA | N transistor corner, to build transistor | +| | | | bend. Not used anymore in recent technos | +| +---------------+-------------+--------------------------------------------+ +| | |C_X_P| | VIA | P transistor corner, to build transistor | +| | | | bend. Not used anymore in recent technos | ++---------+---------------+-------------+--------------------------------------------+ + +.. note:: + Not all association of object and symbolic layers are meaningful. + For instance you cannot associate a contact to a ``NTRANS`` layer. + +.. note:: + The symbolic layer associated with blockages is prefixed by a ``T``, + for *transparency*, which may seems silly. It is for historical reasons, + it started as a true transparency, but at some point we had to invert + the meaning (blockage) with the rise of over-the-cell routing, but the + name stuck... + + + +Symbolic Segments +~~~~~~~~~~~~~~~~~ + +In |Alliance|, segments are oriented (up, down, left, right). This disambiguate +the left or right side when using the ``LCW`` and ``RCW`` rules in the |RDS| file. +It allows to generate, if needed, asymetric object in the real layout file. + +|bcenter| |SegmentOrientation| |ecenter| + +|newpage| + + +The RDS File +============ + + +The RDS file control how a symbolic layout is transformed into it's real +conterpart. + +.. note:: **Unit used inside the RDS file:** all units are expressed in micrometers. + +Alliance tools relying on the RDS file, and what layers are active for them: + +======================================= ============= =============================== +Tool Name RDS Flags +======================================= ============= =============================== +Layout editor |graal| |ALL| +Design Rule Checker |druc| |ALL|, |DRC| +Electrical extractor |cougar| |ALL|, |EXT| +The symbolic to real layout translator |s2r| |ALL| +======================================= ============= =============================== + + +Physical Grid & Lambda Value +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +RDS file: :: + + DEFINE PHYSICAL_GRID 0.005 + DEFINE LAMBDA 0.09 + +Tells that the physical grid (founder grid) step is 0.005µm and the lambda has +a value of 0.09µm. That is, one lambda is 18 grid steps. + +We can distinguish two kind of |RDS| files: + +* The *1µm* kind, odd segment widths and coordinates are allowed, but the ``LAMBDA`` + value **must** represent an *even* number of foundry grid step. +* The *2µm* kind, segments widths and coordinates must all be even. And in that case + the ``LAMBDA`` value can be any multiple of the foundry grid. + + +The |MBK_TO_RDS_SEGMENT| table +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The |MBK_TO_RDS_SEGMENT| table control the way segments are translated into +real rectangles. Be aware that we are translating *segments* and not *rectangles*. +Segments are defined by their axis (source & target points) and their width. +The geometrical transformations are described according to that model. +Obviously, they are either horizontal or vertical. + +The translation method of a symbolic segment is as follow: + +1. The segment is translated into one or more physical rectangles. + The generated rectangles depends on the tool which is actually + using |RDS| and the flag for the considered real layer. + For instance, real layers flagged with |DRC| will be generated + for |s2r| (for the |cif| or |gds|) and |druc|, but will not + be shown under |graal|. + +2. Translation into one real layer. *First* the source & target coordinates and width + of the symbolic segment are multiplied by the ``LAMBDA`` value to obtain a real + segment. *Then* one of the |VW|, |LCW| or |RCW| transformation is applied to + that segment to get the final real rectangle. + + * |VW| for Variable Width, expand the real layer staying centered from the + original one. In those rules, the third number is not used, it is only here + to make the life easier for the parser... + + |bcenter| |RDS_VW| |ecenter| + + * |LCW| or |RCW| for Left/Right Constant Width, create an off-center rectangle + of fixed width relatively to the real segment. Note that the ``SP`` number + is the distance *between the edge* of the real segment and the edge of the + generated real rectangle (*not* from the axis). It is often zero. + + |bcenter| |RDS_LCW| |ecenter| + + +|newpage| + +Examples: :: + + TABLE MBK_TO_RDS_SEGMENT + + # (Case 1) + ALU1 RDS_ALU1 VW 0.18 0.09 0.0 ALL + + # (Case 2) + NDIF RDS_NDIF VW 0.18 0.0 0.0 ALL \ + RDS_ACTIV VW 0.18 0.0 0.0 DRC \ + RDS_NIMP VW 0.36 0.36 0.0 DRC + + # (Case 3) + NTRANS RDS_POLY VW 0.27 0.00 0.0 ALL \ + RDS_GATE VW 0.27 0.00 0.0 DRC \ + RDS_NDIF LCW 0.0 0.27 0.0 EXT \ + RDS_NDIF RCW 0.0 0.27 0.0 EXT \ + RDS_NDIF VW 0.0 0.72 0.0 DRC \ + RDS_ACTIV VW 0.0 0.72 0.0 ALL \ + RDS_NIMP VW 0.18 1.26 0.0 DRC + + END + +:fboxtt:`Case 1` the |ALU1| is translated in exacltly one real rectangle of +|RDS_ALU1|, both ends are extended by 0.18µm and it's width is increased +by 0.09µm. + +:fboxtt:`Case 2` the |NDIF| will be translated into only one segment +under |graal|, for symbolic visualization. And into three real rectangles +for |s2r| and |druc|. + +:fboxtt:`Case 3` the |NTRANS|, associated to a transistor is a little bit +more complex, the generated shapes are different for the extractor |cougar| +in one hand, and for both |druc| & |s2r| in the other hand. + +* For the extractor (|EXT| & |ALL| flags) there will be four rectangles + generateds: + + 1. The gate (|RDS_GATE|) + 2. The left diffusion of the transistor (source or drain) (|RDS_NDIF|). + 3. The right diffusion of the transistor (drain or source) (|RDS_NDIF|). + 4. The active area (|RDS_ACTIV|). + + As the extractor must kept separate the source and the drain of the transistor, + they are generated as two offset rectangles, using the |LCW| and |RCW| directives. + +* For |s2r| and |druc| (|DRC| and |ALL|), five rectangles are generateds: + + 1. The poly (|RDS_POLY|). + 2. The gate (|RDS_GATE|). + 3. The diffusion, as one rectangle that covers both the |LCW| and the |RCW| (|RDS_NDIF|). + 4. The active area (|RDS_ACTIV|). + 5. The N implantation (|RDS_NIMP|). + + In the layout send to the foundry, the source & drain are draw as one rectangle + across the gate area (the transistor being defined by the intersection of both + rectangles). + + +|newpage| + +The |MBK_TO_RDS_VIA| table +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This table is to translate *default* VIAs into real via. In the symbolic layout +the default VIA is simply a point and a set of layers. All layers are converted +in squares shapes centered on the VIA coordinate. The one dimension given is the +size of the side of that square. + +Note that although we are refering to VIAs, which for the purists are between two +metal layers, this table also describe *contacts*. + +Example: :: + + TABLE MBK_TO_RDS_VIA + + CONT_DIF_P RDS_PDIF 0.54 ALL \ + RDS_CONT 0.18 ALL \ + RDS_ALU1 0.36 ALL \ + RDS_ACTIV 0.54 DRC \ + RDS_PIMP 0.90 DRC + + CONT_POLY RDS_POLY 0.54 ALL \ + RDS_CONT 0.18 ALL \ + RDS_ALU1 0.36 ALL + + CONT_VIA RDS_ALU1 0.45 ALL \ + RDS_VIA1 0.27 ALL \ + RDS_ALU2 0.45 ALL + + END + +.. note:: **In CONT_DIF_P** you may see that only three layers will be shown under + |graal|, but five will be generated in the |gds| layout. + + +The |MBK_TO_RDS_BIGVIA_HOLE| table +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In |s2r|, when generating BIGVIAs, the matrix of holes they contains is +not draw relative to the position of the BIGVIA itself, but on a grid which +is common througout all the design real layout. This is to allow overlap +between two BIGVIA without risking the holes matrix to be not exactly overlapping. +As a consequence, when visualizing the |gds| file, the holes may not be centerend +inside one individual BIGVIA. + +The |MBK_TO_RDS_BIGVIA_HOLE| table define the global hole matrix for the whole +design. The first number is the individual hole side and the second the grid step +(edge to edge). The figure below show the hole generation. + +|bcenter| |BIGVIA_1| |ecenter| + +Example of BIGVIA overlap: + +|bcenter| |BIGVIA_2| |ecenter| + +Example: :: + + TABLE MBK_TO_RDS_BIGVIA_HOLE + + CONT_VIA RDS_VIA1 0.27 0.27 ALL + CONT_VIA2 RDS_VIA2 0.27 0.27 ALL + CONT_VIA3 RDS_VIA3 0.27 0.27 ALL + CONT_VIA4 RDS_VIA4 0.27 0.27 ALL + CONT_VIA5 RDS_VIA5 0.36 0.36 ALL + + END + +.. note:: **BIGVIA demotion.** If the size of the bigvia is too small, there is + a possibility that no hole from the global matrix will be under it. + To avoid that case, if the either side of the BIGVIA is less than + ``1.5 * step``, the BIGVIA is demoted to a simple VIA. + + +The |MBK_TO_RDS_BIGVIA_METAL| table +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This table describe how the metal part of a BIGVIA is expanded (for the hole +part, see the previous table |MBK_TO_RDS_BIGVIA_HOLE|). The rule give for each +metal: + +1. The *delta-with* (have to ask Franck). +2. The *overhang*, the length the real rectangle is expanded on each side from + the symbolic rectange. + +Example: :: + + TABLE MBK_TO_RDS_BIGVIA_METAL + + CONT_VIA RDS_ALU1 0.0 0.09 ALL \ + RDS_ALU2 0.0 0.09 ALL + + CONT_VIA2 RDS_ALU2 0.0 0.09 ALL \ + RDS_ALU3 0.0 0.09 ALL + + CONT_VIA3 RDS_ALU3 0.0 0.09 ALL \ + RDS_ALU4 0.0 0.09 ALL + + CONT_VIA4 RDS_ALU4 0.0 0.09 ALL \ + RDS_ALU5 0.0 0.09 ALL + + CONT_VIA5 RDS_ALU5 0.0 0.09 ALL \ + RDS_ALU6 0.0 0.18 ALL + END + + +The |MBK_WIRESETTING| table +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +From a strict standpoint this table shouldn't be here but put in a separate +configuration file, because it contains informations only used by the symbolic +layout tools (|ocp|, |nero|, |ring|). + +This table defines the cell gauge the routing pitch and minimal (symbolic) +wire width and minimal spacing for the routers. They are patly redundant. + +Example: :: + + TABLE MBK_WIRESETTING + + X_GRID 10 + Y_GRID 10 + Y_SLICE 100 + WIDTH_VDD 12 + WIDTH_VSS 12 + TRACK_WIDTH_ALU8 0 + TRACK_WIDTH_ALU7 4 + TRACK_WIDTH_ALU6 4 + TRACK_WIDTH_ALU5 4 + TRACK_WIDTH_ALU4 3 + TRACK_WIDTH_ALU3 3 + TRACK_WIDTH_ALU2 3 + TRACK_WIDTH_ALU1 3 + TRACK_SPACING_ALU8 0 + TRACK_SPACING_ALU7 4 + TRACK_SPACING_ALU6 4 + TRACK_SPACING_ALU5 4 + TRACK_SPACING_ALU4 4 + TRACK_SPACING_ALU3 4 + TRACK_SPACING_ALU2 4 + TRACK_SPACING_ALU1 3 + + END + diff --git a/documentation/_build/html/_sources/RDS/index.txt b/documentation/_build/html/_sources/RDS/index.txt new file mode 100644 index 00000000..757d647e --- /dev/null +++ b/documentation/_build/html/_sources/RDS/index.txt @@ -0,0 +1,26 @@ +.. -*- mode: rst; explicit-buffer-name: "index.rst" -*- + +.. include:: ../etc/definitions.rst + + +:Date: 26, september 2014 +:Authors: Jean-Paul Chaput +:Contact: +:Version: 0.2 + + +**Disclaimer:** This document is still far from complete. + + +========================================= +Symbolic to Real Conversion in Alliance +========================================= + +Printable version of this document `RDS.pdf <../../../pdf/main/RDS.pdf>`_. + + +.. toctree:: + :maxdepth: 2 + + RDSpage.rst + diff --git a/documentation/_build/html/_sources/Stratus/Stratus.txt b/documentation/_build/html/_sources/Stratus/Stratus.txt new file mode 100644 index 00000000..f61b2dac --- /dev/null +++ b/documentation/_build/html/_sources/Stratus/Stratus.txt @@ -0,0 +1,11 @@ +.. -*- Mode: rst -*- + +.. include:: ../etc/definitions.rst + + +=================== +Stratus Reference +=================== + +The Stratus Language reference is generated by LaTeX2HTML_ and is +available here: `Stratus `_ diff --git a/documentation/_build/html/_sources/Unicorn/Unicorn.txt b/documentation/_build/html/_sources/Unicorn/Unicorn.txt new file mode 100644 index 00000000..c972e5f0 --- /dev/null +++ b/documentation/_build/html/_sources/Unicorn/Unicorn.txt @@ -0,0 +1,11 @@ +.. -*- Mode: rst -*- + +.. include:: ../etc/definitions.rst + + +=================== +Unicorn Reference +=================== + +The Unicorn C++ API reference is generated by Doxygen_ and is +available here: `Unicorn `_ diff --git a/documentation/_build/html/_sources/UsersGuide/Configuration.txt b/documentation/_build/html/_sources/UsersGuide/Configuration.txt new file mode 100644 index 00000000..e2da0de5 --- /dev/null +++ b/documentation/_build/html/_sources/UsersGuide/Configuration.txt @@ -0,0 +1,342 @@ +.. -*- Mode: rst -*- + +.. include:: ../etc/definitions.rst + +.. URLs that changes between the various backends. +.. _Coriolis Tools Documentation: file:///usr/share/doc/coriolis2/index.html + + + +.. |CoriolisSoftSchema| image:: ./images/Coriolis-Soft-Schema.png + :alt: Coriolis Software Schematic + :align: middle + :width: 60% + +|newpage| + + +Coriolis Configuration & Initialisation +======================================= + + +General Software Architecture +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +|Coriolis| has been build with respect of the classical paradigm that the +computational instensive parts have been written in C++, and almost +everything else in |Python|. To build the |Python| interface we used +two methods: + +* For self-contained modules :cb:`boost::python` (mainly in :cb:`vlsisapd`). +* For all modules based on |Hurricane|, we created our own wrappers due + to very specific requirements such as shared functions between modules + or C++/|Python| secure bi-directional object deletion. + +.. note:: **Python Documentation:** + Most of the documentation is related to the C++ API and implemetation of + the tools. However, the |Python| bindings have been created so they + mimic *as closely as possible* the C++ interface, so the documentation + applies to both languages with only minor syntactic changes. + +|bcenter| |CoriolisSoftSchema| |ecenter| + +All configuration & initialization files are Python scripts, despite their +|dot_conf| extention. From a syntactic point of view, there is no difference +between the system-wide configuration files and the user's configuration, +they may use the same Python helpers. +|medskip| + +Configuration is done in two stages: + +#. Selecting the symbolic technology. +#. Loading the complete configuration for the given technology. + +|newpage| + + +First Stage: Symbolic Technology Selection +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +|noindent| +The initialization process is done by executing, in order, the following +file(s): + ++-------+----------------------------------+----------------------------------------------+ +| Order | Meaning | File | ++=======+==================================+==============================================+ +| **1** | The system setting | :cb:`/etc/coriolis2/techno.conf` | ++-------+----------------------------------+----------------------------------------------+ +| **2** | The user's global setting | :cb:`${HOME}/.coriolis2/techno.py` | ++-------+----------------------------------+----------------------------------------------+ +| **3** | The user's local setting | :cb:`/.coriolis2/techno.py` | ++-------+----------------------------------+----------------------------------------------+ + +Thoses files must provides only two variables, the name of the symbolic technology +and the one of the real technology. For example: :: + + # -*- Mode:Python -*- + + symbolicTechno = 'cmos' + realTechno = 'hcmos9' + + +Second Stage: Technology Configuration Loading +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +|noindent| +The :cb:`TECHNO` variable is set by the first stage and it's the name of the +symbolic technology. A directory of that name, with all the configuration files, +must exists in the configuration directory. In addition to the technology-specific +directories, a :cb:`common/` directory is there to provides a trunk for all the +identical datas across the various technologies. The initialization process is done +by executing, in order, the following file(s): + ++-------+----------------------------------+----------------------------------------------+ +| Order | Meaning | File | ++=======+==================================+==============================================+ +| **1** | The system initialization | :cb:`/etc/coriolis2//.conf` | ++-------+----------------------------------+----------------------------------------------+ +| **2** | The user's global initialization | :cb:`${HOME}/.coriolis2/settings.py` | ++-------+----------------------------------+----------------------------------------------+ +| **3** | The user's local initialization | :cb:`/.coriolis2/settings.py` | ++-------+----------------------------------+----------------------------------------------+ + +.. note:: *The loading policy is not hard-coded.* It is implemented + at Python level in :cb:`/etc/coriolis2/coriolisInit.py`, and thus may be easily be + amended to whatever site policy. + + The truly mandatory requirement is the existence of :cb:`coriolisInit.py` + which *must* contain a :cb:`coriolisConfigure()` function with no argument. + + +Configuration Helpers +~~~~~~~~~~~~~~~~~~~~~ + +To ease the writing of configuration files, a set of small helpers +is available. They allow to setup the configuration parameters through +simple assembly of tuples. The helpers are installed under the directory: :: + + /etc/coriolis2/ + +Where :cb:`/` is the root of the installation. + +|newpage| + + +.. _Alliance Helper: + +|Alliance| Helper +----------------- + +The configuration file must provide a :cb:`allianceConfig` tuple of +the form: :: + + cellsTop = '/usr/share/alliance/cells/' + + allianceConfig = \ + ( ( 'SYMBOLIC_TECHNOLOGY', helpers.sysConfDir+'/technology.symbolic.xml' ) + , ( 'REAL_TECHNOLOGY' , helpers.sysConfDir+'/technology.cmos130.s2r.xml') + , ( 'DISPLAY' , helpers.sysConfDir+'/display.xml' ) + , ( 'CATALOG' , 'CATAL') + , ( 'WORKING_LIBRARY' , '.') + , ( 'SYSTEM_LIBRARY' , ( (cellsTop+'sxlib' , Environment.Append) + , (cellsTop+'dp_sxlib', Environment.Append) + , (cellsTop+'ramlib' , Environment.Append) + , (cellsTop+'romlib' , Environment.Append) + , (cellsTop+'rflib' , Environment.Append) + , (cellsTop+'rf2lib' , Environment.Append) + , (cellsTop+'pxlib' , Environment.Append) ) ) + , ( 'SCALE_X' , 100) + , ( 'IN_LO' , 'vst') + , ( 'IN_PH' , 'ap') + , ( 'OUT_LO' , 'vst') + , ( 'OUT_PH' , 'ap') + , ( 'POWER' , 'vdd') + , ( 'GROUND' , 'vss') + , ( 'CLOCK' , '^ck.*') + , ( 'BLOCKAGE' , '^blockageNet*') + ) + + +|noindent| The example above shows the system configuration file, with all the +available settings. Some important remarks about thoses settings: + +* In it's configuration file, the user do not need to redefine all the settings, + just the one he wants to change. In most of the cases, the ``SYSTEM_LIBRARY``, + the ``WORKING_LIBRARY`` and the special net names (at this point there is not + much alternatives for the others settings). + +* ``SYSTEM_LIBRARY`` setting: Setting up the library search path. + Each library entry in the tuple will be added to the search path according + to the second parameter: + + * :cb:`Environment::Append`: append to the search path. + + * :cb:`Environment::Prepend`: insert in head of the search path. + + * :cb:`Environment::Replace`: look for a library of the same name and replace + it, whithout changing the search path order. If no library of that name + already exists, it is appended. + + A library is identified by it's name, this name is the last component of the + path name. For instance: ``/soc/alliance/sxlib`` will be named ``sxlib``. + Implementing the |Alliance| specification, when looking for a |Cell| ``name``, + the system will browse sequentially trought the library list and returns + the first |Cell| whose name match. + +* For ``POWER``, ``GROUND``, ``CLOCK`` and ``BLOCKAGE`` net names, a regular + expression (|GNU| regexp) is expected. + +* The ``helpers.sysConfDir`` variable is supplied by the helpers, it is the + directory in which the system-wide configuration files are locateds. + For a standard installation it would be: ``/soc/coriolis2``. + +.. * Trick and naming convention about ``SYMBOLIC_TECHNOLOGY``, ``REAL_TECHNOLOGY`` +.. and ``DISPLAY``. In the previous releases, thoses files where to read by +.. XML parsers, and still do if you triggers the XML compatibility mode. +.. But now, they have Python conterparts. In the configuration files, you +.. still have to name them as XML files, the Python file name will be +.. deduced from this one with thoses two translation rules: +.. +.. #. In the filename, all dots, except for the last (the file extention), +.. are replaced by underscores. +.. +.. #. The ``.xml`` extention is substituted by a ``.conf``. +.. +.. For the symbolic technology, it would give: :: +.. +.. /soc/coriolis2/technology.symbolic.xml +.. --> /soc/coriolis2/technology_symbolic.conf + +A typical user's configuration file would be: :: + + import os + + homeDir = os.getenv('HOME') + + allianceConfig = \ + ( ('WORKING_LIBRARY' , homeDir+'/worklib') + , ('SYSTEM_LIBRARY' , ( (homeDir+'/mylib', Environment.Append) ) ) + , ('POWER' , 'vdd.*') + , ('GROUND' , 'vss.*') + ) + + +Tools Configuration Helpers +--------------------------- + +All the tools uses the same helper to load their configuration (a.k.a. +*Configuration Helper*). Currently the following configuration system-wide +configuration files are defined: + +* :cb:`misc.conf`: commons settings or not belonging specifically to a tool. +* :cb:`etesian.conf`: for the |Etesian| tool. +* :cb:`kite.conf`: for the |Kite| tool. +* :cb:`stratus1.conf`: for the |stratus1| tool. + +Here is the contents of :cb:`etesian.conf`: :: + + # Etesian parameters. + parametersTable = \ + ( ('etesian.aspectRatio' , TypePercentage, 100 , { 'min':10, 'max':1000 } ) + , ('etesian.spaceMargin' , TypePercentage, 5 ) + , ('etesian.uniformDensity' , TypeBool , False ) + , ('etesian.routingDriven' , TypeBool , False ) + , ("etesian.effort" , TypeEnumerate , 2 + , { 'values':( ("Fast" , 1) + , ("Standard", 2) + , ("High" , 3) + , ("Extreme" , 4) ) } + ) + , ("etesian.graphics" , TypeEnumerate , 2 + , { 'values':( ("Show every step" , 1) + , ("Show lower bound" , 2) + , ("Show result only" , 3) ) } + ) + ) + + layoutTable = \ + ( (TypeTab , 'Etesian', 'etesian') + + , (TypeTitle , 'Placement area') + , (TypeOption, "etesian.aspectRatio" , "Aspect Ratio, X/Y (%)", 0 ) + , (TypeOption, "etesian.spaceMargin" , "Space Margin" , 1 ) + , (TypeRule ,) + , (TypeTitle , 'Etesian - Placer') + , (TypeOption, "etesian.uniformDensity", "Uniform density" , 0 ) + , (TypeOption, "etesian.routingDriven" , "Routing driven" , 0 ) + , (TypeOption, "etesian.effort" , "Placement effort" , 1 ) + , (TypeOption, "etesian.graphics" , "Placement view" , 1 ) + , (TypeRule ,) + ) + +|newpage| + + +Taxonomy of the file: + +* It must contains, at least, the two tables: + + * ``parametersTable``, defines & initialise the configuration variables. + + * ``layoutTables``, defines how the various parameters will be displayed + in the configuration window (:ref:`The Settings Tab`). + +* The ``parametersTable``, is a tuple (list) of tuples. Each entry in the list + describe a configuration parameter. In it's simplest form, it's a quadruplet + :cb:`(TypeOption, 'paramId', ParameterType, DefaultValue)` with: + + #. ``TypeOption``, tells that this tuple describe a parameter. + + #. ``paramId``, the identifier of the parameter. Identifiers are defined + by the tools. The list of parameters is detailed in each tool section. + + #. ``ParameterType``, the kind of parameter. Could be: + + * ``TypeBool``, boolean. + * ``TypeInt``, signed integer. + * ``TypeEnumerate``, enumerated type, needs extra entry. + * ``TypePercentage``, percentage, expressed between 0 and 100. + * ``TypeDouble``, float. + * ``TypeString``, character string. + + #. ``DefaultValue``, the default value for that parameter. + + +Hacking the Configuration Files +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Asides from the symbols that gets used by the configuration helpers like +:cb:`allianceConfig` or :cb:`parametersTable`, you can put pretty much anything +in :cb:`/.coriolis2/settings.py` (that is, written in |Python|). + +For example: :: + + # -*- Mode:Python -*- + + defaultStyle = 'Alliance.Classic [black]' + + # Regular Coriolis configuration. + parametersTable = \ + ( ('misc.catchCore' , TypeBool , False ) + , ('misc.info' , TypeBool , False ) + , ('misc.paranoid' , TypeBool , False ) + , ('misc.bug' , TypeBool , False ) + , ('misc.logMode' , TypeBool , True ) + , ('misc.verboseLevel1' , TypeBool , False ) + , ('misc.verboseLevel2' , TypeBool , True ) + , ('misc.minTraceLevel' , TypeInt , 0 ) + , ('misc.maxTraceLevel' , TypeInt , 0 ) + ) + + # Some ordinary Python script... + import os + + print ' o Cleaning up ClockTree previous run.' + for fileName in os.listdir('.'): + if fileName.endswith('.ap') or (fileName.find('_clocked.') >= 0): + print ' - <%s>' % fileName + os.unlink(fileName) + + +See :ref:`Python Interface to Coriolis` for more details those capabilities. diff --git a/documentation/_build/html/_sources/UsersGuide/Installation.txt b/documentation/_build/html/_sources/UsersGuide/Installation.txt new file mode 100644 index 00000000..224ee5f4 --- /dev/null +++ b/documentation/_build/html/_sources/UsersGuide/Installation.txt @@ -0,0 +1,230 @@ +.. -*- Mode: rst -*- + +.. include:: ../etc/definitions.rst + +|newpage| + + +Installation +============ + +.. note:: + As the sources are being released, the binary packaging is dropped. + You still may find older version here: http://asim.lip6.fr/pub/coriolis/2.0 . + +In a nutshell, building source consist in pulling the |git| repository then +running the |ccb| installer. + +Main building prerequisites: + +* cmake +* C++11-capable compiler +* RapidJSON_ +* python2.7 +* boost +* libxml2 +* bzip2 +* yacc & lex +* Qt 4 or Qt 5 + +Building documentation prerequisites: + +* doxygen +* latex +* latex2html +* python-docutils (for reStructuredText) + +Optional libraries: + +* LEF/DEF (from `SI2 `_) + +For other distributions, refer to their own packaging system. + +|newpage| + + +Fixed Directory Tree +~~~~~~~~~~~~~~~~~~~~ + +In order to simplificate the work of the |ccb| installer, the source, build +and installation tree is fixed. To successfully compile |Coriolis| you must +follow it exactly. The tree is relative to the home directory of the user +building it (noted :fboxtt:`~/` or :fboxtt:`$HOME/`). Only the source +directory needs to be manually created by the user, all others will be +automatically created either by |ccb| or the build system. + ++--------------------------------------------------------------------------------------------------------------+ +| **Sources** | ++------------------------------+-------------------------------------------------------------------------------+ +| | Sources root | | ~/coriolis-2.x/src | +| | **under git** | | ~/coriolis-2.x/src/coriolis | ++------------------------------+-------------------------------------------------------------------------------+ +| **Architecture Dependant Build** | ++------------------------------+-------------------------------------------------------------------------------+ +| | Linux, SL 7, 64b | | ~/coriolis-2.x/Linux.el7_64/Release.Shared/build/ | +| | Linux, SL 6, 32b | | ~/coriolis-2.x/Linux.slsoc6x/Release.Shared/build/ | +| | Linux, SL 6, 64b | | ~/coriolis-2.x/Linux.slsoc6x_64/Release.Shared/build/ | +| | Linux, Fedora, 64b | | ~/coriolis-2.x/Linux.fc_64/Release.Shared/build/ | +| | Linux, Fedora, 32b | | ~/coriolis-2.x/Linux.fc/Release.Shared/build/ | +| | FreeBSD 8, 32b | | ~/coriolis-2.x/FreeBSD.8x.i386/Release.Shared/build/ | +| | FreeBSD 8, 64b | | ~/coriolis-2.x/FreeBSD.8x.amd64/Release.Shared/build/ | +| | Windows 7, 32b | | ~/coriolis-2.x/Cygwin.W7/Release.Shared/build/ | +| | Windows 7, 64b | | ~/coriolis-2.x/Cygwin.W7_64/Release.Shared/build/ | +| | Windows 8.x, 32b | | ~/coriolis-2.x/Cygwin.W8/Release.Shared/build/ | +| | Windows 8.x, 64b | | ~/coriolis-2.x/Cygwin.W8_64/Release.Shared/build/ | ++------------------------------+-------------------------------------------------------------------------------+ +| **Architecture Dependant Install** | ++------------------------------+-------------------------------------------------------------------------------+ +| Linux, SL 6, 32b | ~/coriolis-2.x/Linux.slsoc6x/Release.Shared/install/ | ++------------------------------+-------------------------------------------------------------------------------+ +| **FHS Compliant Structure under Install** | ++------------------------------+-------------------------------------------------------------------------------+ +| | Binaries | | .../install/bin | +| | Libraries (Python) | | .../install/lib | +| | Include by tool | | .../install/include/coriolis2// | +| | Configuration files | | .../install/etc/coriolis2/ | +| | Doc, by tool | | .../install/share/doc/coriolis2/en/html/ | ++------------------------------+-------------------------------------------------------------------------------+ + +.. note:: *Alternate build types:* the ``Release.Shared`` means an optimized build + with shared libraries. But there are also available ``Static`` instead of ``Shared`` + and ``Debug`` instead of ``Release`` and any combination of them. + + ``Static`` do not work because I don't know yet to mix statically linked binaries + and Python modules (which must be dynamic). + +|newpage| + + +Building Coriolis +~~~~~~~~~~~~~~~~~ + +First step is to install the prerequisites. Currently, only RapidJSON_. +As RapidJSON is evolving fast, if you encounter compatibility problems, +the exact version we compiled against is given below. :: + + dummy@lepka:~$ mkdir -p ~/coriolis-2.x/src/support + dummy@lepka:~$ cd ~/coriolis-2.x/src/support + dummy@lepka:~$ git clone http://github.com/miloyip/rapidjson + dummy@lepka:~$ git checkout ec322005072076ef53984462fb4a1075c27c7dfd + +The second step is to create the source directory and pull the |git| repository: :: + + dummy@lepka:~$ mkdir -p ~/coriolis-2.x/src + dummy@lepka:~$ cd ~/coriolis-2.x/src + dummy@lepka:~$ git clone https://www-soc.lip6.fr/git/coriolis.git + +Third and final step, build & install: :: + + dummy@lepka:src$ ./bootstrap/ccb.py --project=support \ + --project=coriolis \ + --make="-j4 install" + dummy@lepka:src$ ./bootstrap/ccb.py --project=support \ + --project=coriolis \ + --doc --make="-j1 install" + +We need to separate to perform a separate installation of the documentation because it +do not support to be generated with a parallel build. So we compile & install in a first +stage in ``-j4`` (or whatever) then we generate the documentation in ``-j1`` + +Under |RHEL6| or clones, you must build using the |devtoolset2|: :: + + dummy@lepka:src$ ./bootstrap/ccb.py --project=coriolis \ + --devtoolset-2 --make="-j4 install" + +If you want to uses Qt 5 instead of Qt 4, you may add the ``--qt5`` argument. + +The complete list of |ccb| functionalities can be accessed with the ``--help`` argument. +It also may be run in graphical mode (``--gui``). + + +Building the Devel Branch +------------------------- + +In the |Coriolis| |git| repository, two branches are present: + +* The :cb:`master` branch, which contains the latest stable version. This is the + one used by default if you follow the above instructions. + +* The :cb:`devel` branch, which obviously contains the latest commits from the + development team. To use it instead of the :cb:`master` one, do the following + command just after the first step: :: + + dummy@lepka:~$ git checkout devel + dummy@lepka:src$ ./bootstrap/ccb.py --project=coriolis \ + --make="-j4 install" --debug + + Be aware that it may requires newer versions of the dependencies and may introduce + incompatibilites with the stable version. + + In the (unlikely) event of a crash of |cgt|, as it is a |Python| script, the right + command to run |gdb| on it is: :: + + dummy@lepka:work$ gdb python core.XXXX + +|newpage| + + +Additionnal Requirement under |MacOS| +------------------------------------- + +|Coriolis| make uses of the :cb:`boost::python` module, but the |macports| |boost| +seems unable to work with the |Python| bundled with |MacOS|. So you have to install +both of them from |macports|: :: + + dummy@macos:~$ port install boost +python27 + dummy@macos:~$ port select python python27 + dummy@macos:-$ export DYLD_FRAMEWORK_PATH=/opt/local/Library/Frameworks + +The last two lines tell |MacOS| to use the |Python| from |macports| and *not* from +the system. + +Then proceed with the generic install instructions. + + +Packaging Coriolis +~~~~~~~~~~~~~~~~~~ + +Packager should not uses |ccb|, instead ``bootstrap/Makefile.package`` is provided +to emulate a top-level ``autotool`` makefile. Just copy it in the root of the +|Coriolis| git repository (``~/corriolis-2.x/src/coriolis/``) and build. + +Sligthly outaded packaging configuration files can also be found under ``bootstrap/``: + +* ``bootstrap/coriolis2.spec.in`` for |rpm| based distributions. +* ``bootstrap/debian`` for |Debian| based distributions. + + +Hooking up into |Alliance| +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +|Coriolis| relies on |Alliance| for the cell libraries. So after installing or +packaging, you must configure it so that it can found those libraries. + +This is done by editing the one variable :cb:`cellsTop` in the |Alliance| helper +(see :ref:`Alliance Helper`). This variable must point to the directory of the +cells libraries. In a typical installation, this is generally +:cb:`/usr/share/alliance/cells`. + + +Setting up the Environment (coriolisEnv.py) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To simplify the tedious task of configuring your environment, a helper is provided +in the ``bootstrap`` source directory (also installed in the directory +``.../install/etc/coriolis2/``) : :: + + ~/coriolis-2.x/src/coriolis/bootstrap/coriolisEnv.py + +Use it like this: :: + + dummy@lepka:~> eval `~/coriolis-2.x/src/coriolis/bootstrap/coriolisEnv.py` + +.. note:: **Do not call that script in your environement initialisation.** + When used under |RHEL6| or clones, it needs to be run in the |devtoolset2| + environement. The script then launch a new shell, which may cause an + infinite loop if it's called again in, say :cb:`~/.bashrc`. + + Instead you may want to create an alias: :: + + alias c2r='eval "`~/coriolis-2.x/src/coriolis/bootstrap/coriolisEnv.py`"' diff --git a/documentation/_build/html/_sources/UsersGuide/LicenseCredits.txt b/documentation/_build/html/_sources/UsersGuide/LicenseCredits.txt new file mode 100644 index 00000000..3cf0eefe --- /dev/null +++ b/documentation/_build/html/_sources/UsersGuide/LicenseCredits.txt @@ -0,0 +1,55 @@ +.. -*- Mode: rst -*- + +.. include:: ../etc/definitions.rst + + +Credits & License +================= + +.. raw:: html + +

Hurricane + Rémy Escassut & + Christian Masson

+
+

Etesian + Gabriel Gouvine

+
+

Stratus + Sophie Belloeil

+
+

Knik + Damien Dupuis

+
+

Kite, + Unicorn + Jean-Paul Chaput

+
+ + +.. raw:: latex + + \begin{center}\begin{minipage}[t]{.8\textwidth} + \noindent\DUrole{sc}{Hurricane} \dotfill Rémy \DUrole{sc}{Escassut} \& + Christian \DUrole{sc}{Masson} \\ + \noindent\DUrole{sc}{Etesian} \dotfill Gabriel \DUrole{sc}{Gouvine} \\ + \noindent\DUrole{sc}{Stratus} \dotfill Sophie \DUrole{sc}{Belloeil} \\ + \noindent\DUrole{sc}{Knik} \dotfill Damien \DUrole{sc}{Dupuis} \\ + \noindent\DUrole{sc}{Kite}, + \DUrole{sc}{Unicorn} \dotfill Jean-Paul \DUrole{sc}{Chaput} \\ + \end{minipage}\end{center} + + +|medskip| + +The |Hurricane| data-base is copyright© |Bull| 2000-2016 and is +released under the terms of the |LGPL| license. All other tools are +copyright© |UPMC| 2008-2016 and released under the |GPL| +license. + +Others important contributors to |Coriolis| are Christophe |Alexandre|, +Hugo |Clement|, Marek |Sroka| and Wu |Yifei|. + +The |Knik| router makes use of the |Flute| software, which is +copyright© Chris C. N. |Chu| from the Iowa State University +(http://home.eng.iastate.edu/~cnchu/). diff --git a/documentation/_build/html/_sources/UsersGuide/Releases.txt b/documentation/_build/html/_sources/UsersGuide/Releases.txt new file mode 100644 index 00000000..c86243a1 --- /dev/null +++ b/documentation/_build/html/_sources/UsersGuide/Releases.txt @@ -0,0 +1,102 @@ +.. -*- Mode: rst -*- + +.. include:: ../etc/definitions.rst + + +Release Notes +============= + +Release 1.0.1475 +~~~~~~~~~~~~~~~~ + +This is the first preliminary release of the |Coriolis2| framework. + +This release mainly ships the global router |Knik| and the detailed router +|Kite|. Together they aim to replace the |Alliance| |Nero| router. +Unlike |Nero|, |Kite| is based on an innovating routing modeling and ad-hoc +algorithm. Although it is released under |GPL| license, the source code +will be avalaible later. +|medskip| + + +|noindent| Contents of this release: + +1. A graphical user interface (viewer only). +2. The |Knik| global router. +3. The |Kite| detailed router. + +|noindent| Supported input/output formats: + +* |Alliance| |vst| (netlist) & |ap| (physical) formats. +* Even if there are some references to the |Cadence| |LEFDEF| format, its + support is not included because it depends on a library only available + to |Si2| affiliated members. + + +Release 1.0.1963 +~~~~~~~~~~~~~~~~ + +Release 1963 is alpha. All the tools from |Coriolis1| have been ported into +this release. + +|noindent| Contents of this release: + +#. The |Stratus| netlist capture language (|GenLib| replacement). +#. The |Mauka| placer (still contains bugs). +#. A graphical user interface (viewer only). +#. The |Knik| global router. +#. The |Kite| detailed router. +#. Partially implemented python support for configuration files + (alternative to |XML|). +#. A documentation (imcomplete/obsoleted in |Hurricane|'s case). + + +Release 1.0.2049 +~~~~~~~~~~~~~~~~ + +Release `2049` is Alpha. + +|noindent| Changes of this release: + +#. The |Hurricane| documentation is now accurate. Documentation + for the Cell viewer and |CRLcore| has been added. +#. More extensive Python support for all the components of + |Coriolis|. +#. Configuration is now completly migrated under Python. + |XML| loaders can still be useds for compatibilty. +#. The |cgt| main has been rewritten in Python. + + +Release v2.0.1 +~~~~~~~~~~~~~~ + +#. Migrated the repository from |svn| to |git|, and release complete sources. + As a consequence, we drop the distribution packaging support and give + public read-only access to the repository. +#. Deep rewrite of the |Katabatic| database and |Kite| detailed router, + achieve a speedup factor greater than 20... + + +Release v2.1 +~~~~~~~~~~~~ + +#. Replace the old simulated annealing placer |Mauka| by the analytical placer + |Etesian| and its legalization and detailed placement tools. +#. Added a Blif format parser to process circuits generated by the Yosys and ABC + logic synthetizers. +#. The multiples user defined configuration files are now grouped under + a common hidden (dot) directory ``.coriolis2`` and the file extension + is back from ``.conf`` to ``.py``. + +.. #. Under |RHEL7| / |SL7|, there is a known bug in the graphical visualizer. +.. When shifting to the left, the right-half part of the screen gets +.. badly redrawn. Uses |CTRL_L| to refresh. It will be corrected as soon +.. as possible. + + +**Release v2.2** +~~~~~~~~~~~~~~~~ + +#. Added JSON import/export of the whole Hurricane DataBase. Two save mode + are supported: *Cell* mode (standalone) or *Blob* mode, which dump the + whole design down and including the standard cells. diff --git a/documentation/_build/html/_sources/UsersGuide/ScriptsPlugins.txt b/documentation/_build/html/_sources/UsersGuide/ScriptsPlugins.txt new file mode 100644 index 00000000..2e9e3d0c --- /dev/null +++ b/documentation/_build/html/_sources/UsersGuide/ScriptsPlugins.txt @@ -0,0 +1,332 @@ +.. -*- Mode: rst -*- + +.. include:: ../etc/definitions.rst + +.. URLs that changes between the various backends. +.. _Stratus Documentation: file:///usr/share/doc/coriolis2/en/html/stratus/index.html + +.. |ChipStructure-1| image:: ./images/chip-structure-1.png + :alt: Chip Top Structure + :align: middle + :width: 90% + + +.. _Python Interface to Coriolis: + +Python Interface for |Hurricane| / |Coriolis| +============================================= + +The (almost) complete interface of |Hurricane| is exported as a |Python| module +and some part of the other components of |Coriolis| (each one in a separate +module). The interface has been made to mirror as closely as possible the +C++ one, so the C++ doxygen documentation could be used to write code with +either languages. + +`Summary of the C++ Documentation `_ + +A script could be run directly in text mode from the command line or through +the graphical interface (see :ref:`Python Scripts in Cgt`). + +Asides for this requirement, the python script can contain anything valid +in |Python|, so don't hesitate to use any package or extention. + +Small example of Python/Stratus script: :: + + from Hurricane import * + from Stratus import * + + def doSomething (): + # ... + return + + def ScriptMain ( **kw ): + editor = None + if kw.has_key('editor') and kw['editor']: + editor = kw['editor'] + stratus.setEditor( editor ) + + doSomething() + return + + if __name__ == "__main__" : + kw = {} + success = ScriptMain( **kw ) + shellSuccess = 0 + if not success: shellSuccess = 1 + + sys.exit( shellSuccess ) + ScriptMain () + +This typical script can be executed in two ways: + +#. Run directly as a |Python| script, thanks to the :: + + if __name__ == "__main__" : + + part (this is standart |Python|). It is a simple adapter that will + calls :cb:`ScriptMain()`. +#. Through |cgt|, either in text or graphical mode. In that case, the + :cb:`ScriptMain()` is directly called trough a sub-interpreter. + The arguments of the script are passed through the ``**kw`` dictionnary. + + +----------------------+-----------------------------------------------+ + | \*\*kw Dictionnary | + +----------------------+-----------------------------------------------+ + | Parameter Key/Name | Contents type | + +======================+===============================================+ + | ``'cell'`` | A Hurricane cell on which to work. Depending | + | | on the context, it may be ``None``. | + | | For example, when run from |cgt|, it the cell | + | | currently loaded in the viewer, if any. | + +----------------------+-----------------------------------------------+ + | ``'editor'`` | The viewer from which the script is run, when | + | | lauched through |cgt|. | + +----------------------+-----------------------------------------------+ + + +Plugins +~~~~~~~ + +Plugins are |Python| scripts specially crafted to integrate with |cgt|. +Their entry point is a :cb:`ScriptMain()` method as described in +`Python Interface to Coriolis`_. They can be called by user scripts +through this method. + + + +Chip Placement +-------------- + +Automatically perform the placement of a complete chip. This plugin, as well +as the other P&R tools expect a specific top-level hierarchy for the design. +The top-level hierarchy must contains the instances of all the I/O pads and +**exactly one** instance of the chip's core model. + +|bcenter| |ChipStructure-1| |ecenter| + +The designer must provide a configuration file that define the rules for the +placement of the top-level hierarchy (that is, the pads and the core). +This file must be named after the chip's name, by appending ``_chip.py`` +(obviously, it is a |Python| file). For instance if the chip netlist file +is called ``amd2901_crl.vst``, then the configuration file must be named +``amd2901_crl_chip.vst``. + +Example of chip placement configuration file (for ``AM2901``): :: + + chip = \ + { 'pads.south' : [ 'p_a3' , 'p_a2' , 'p_a1' , 'p_r0' + , 'p_vddick0', 'p_vssick0', 'p_a0' , 'p_i6' + , 'p_i8' , 'p_i7' , 'p_r3' ] + , 'pads.east' : [ 'p_zero' , 'p_i0' , 'p_i1' , 'p_i2' + , 'p_vddeck0', 'p_vsseck0', 'p_q3' , 'p_b0' + , 'p_b1' , 'p_b2' , 'p_b3' ] + , 'pads.north' : [ 'p_noe' , 'p_y3' , 'p_y2' , 'p_y1' + , 'p_y0' , 'p_vddeck1', 'p_vsseck1', 'p_np' + , 'p_ovr' , 'p_cout' , 'p_ng' ] + , 'pads.west' : [ 'p_cin' , 'p_i4' , 'p_i5' , 'p_i3' + , 'p_ck' , 'p_d0' , 'p_d1' , 'p_d2' + , 'p_d3' , 'p_q0' , 'p_f3' ] + , 'core.size' : ( 1500, 1500 ) + , 'chip.size' : ( 3000, 3000 ) + , 'chip.clockTree' : True + } + +The file must contain *one dictionnary* named ``chip``. + ++----------------------+-------------------------------------------------------+ +| Chip Dictionnary | ++----------------------+-------------------------------------------------------+ +| Parameter Key/Name | Value/Contents type | ++======================+=======================================================+ +| ``'pad.south'`` | Ordered list (left to right) of pad instances names | +| | to put on the south side of the chip | ++----------------------+-------------------------------------------------------+ +| ``'pad.east'`` | Ordered list (down to up) of pad instances names | +| | to put on the east side of the chip | ++----------------------+-------------------------------------------------------+ +| ``'pad.north'`` | Ordered list (left to right) of pad instances names | +| | to put on the north side of the chip | ++----------------------+-------------------------------------------------------+ +| ``'pad.west'`` | Ordered list (down to up) of pad instances names | +| | to put on the west side of the chip | ++----------------------+-------------------------------------------------------+ +| ``'core.size'`` | The size of the core (to be used by the placer) | ++----------------------+-------------------------------------------------------+ +| ``'chip.size'`` | The size of the whole chip. The sides must be great | +| | enough to accomodate all the pads | ++----------------------+-------------------------------------------------------+ +| ``'chip.clockTree'`` | Whether to generate a clock tree or not. This calls | +| | the ClockTree plugin | ++----------------------+-------------------------------------------------------+ + +Configuration parameters, defaults are defined in ``etc/coriolis2//plugins.conf``. + ++-----------------------------------+------------------+----------------------------+ +| Parameter Identifier | Type | Default | ++===================================+==================+============================+ +| **Chip Plugin Parameters** | ++-----------------------------------+------------------+----------------------------+ +|``chip.block.rails.count`` | TypeInt | :cb:`5` | +| +------------------+----------------------------+ +| | The minimum number of rails around the core | +| | block. Must be odd and suppérior to 5. | +| | One rail for the clock and at least two pairs | +| | of power/grounds | ++-----------------------------------+------------------+----------------------------+ +|``chip.block.rails.hWidth`` | TypeInt | :cb:`12` | +| +------------------+----------------------------+ +| | The horizontal with of the rails | ++-----------------------------------+------------------+----------------------------+ +|``chip.block.rails.vWidth`` | TypeInt | :cb:`12` | +| +------------------+----------------------------+ +| | The vertical with of the rails | ++-----------------------------------+------------------+----------------------------+ +|``chip.block.rails.hSpacing`` | TypeInt | :cb:`6` | +| +------------------+----------------------------+ +| | The spacing, *edge to edge* of two adjacent | +| | horizontal rails | ++-----------------------------------+------------------+----------------------------+ +|``chip.block.rails.vSpacing`` | TypeInt | :cb:`6` | +| +------------------+----------------------------+ +| | The spacing, *edge to edge* of two adjacent | +| | vertical rails | ++-----------------------------------+------------------+----------------------------+ +|``chip.pad.pck`` | TypeString | :cb:`pck_px` | +| +------------------+----------------------------+ +| | The model name of the pad connected to the | +| | chip external clock | ++-----------------------------------+------------------+----------------------------+ +|``chip.pad.pvddeck`` | TypeString | :cb:`pvddeck_px` | +| +------------------+----------------------------+ +| | The model name of the pad connected to the | +| | ``vdde`` (external power) and suppling it to | +| | the core | ++-----------------------------------+------------------+----------------------------+ +|``chip.pad.pvsseck`` | TypeString | :cb:`pvsseck_px` | +| +------------------+----------------------------+ +| | The model name of the pad connected to the | +| | ``vsse`` (external ground) and suppling it to | +| | the core | ++-----------------------------------+------------------+----------------------------+ +|``chip.pad.pvddick`` | TypeString | :cb:`pvddick_px` | +| +------------------+----------------------------+ +| | The model name of the pad connected to the | +| | ``vddi`` (internal power) and suppling it to | +| | the core | ++-----------------------------------+------------------+----------------------------+ +|``chip.pad.pvssick`` | TypeString | :cb:`pvssick_px` | +| +------------------+----------------------------+ +| | The model name of the pad connected to the | +| | ``vssi`` (internal ground) and suppling it to | +| | the core | ++-----------------------------------+------------------+----------------------------+ + +.. note:: + If no clock tree is generated, then the clock rail is *not* created. + So even if the requested number of rails ``chip.block.rails.count`` is, say 5, + only four rails (2* ``power``, 2* ``ground``) will be generateds. + + +Clock Tree +---------- + +Insert a clock tree into a block. The clock tree uses the H strategy. +The clock net is splitted into sub-nets, one for each branch of the +tree. + +* On **chips** design, the sub-nets are createds in the model of the + core block (then trans-hierarchically flattened to be shown at + chip level). +* On **blocks**, the sub nets are created directly in the top block. +* The sub-nets are named according to a simple geometrical scheme. + A common prefix ``ck_htree``, then one postfix by level telling + on which quarter of plane the sub-clock is located: + + #. ``_bl``: bottom left plane quarter. + #. ``_br``: bottom right plane quarter. + #. ``_tl``: top left plane quarter. + #. ``_tr``: top right plane quarter. + + We can have ``ck_htree_bl``, ``ck_htree_bl_bl``, ``ch_htree_bl_tl`` and so on. + +The clock tree plugin works in four steps: + +#. Build the clock tree: creates the top-block abutment box, compute the + levels of H tree neededs and place the clock buffers. +#. Once the clock buffers are placed, calls the placer (|etesian|) to place + the ordinary standart cells, whithout disturbing clock H-tree buffers. +#. At this point we know the exact positions of all the DFFs, so we can + connect them to the nearest H-tree leaf clock signal. +#. Leaf clock signals that are not connecteds to any DFFs are removed. + +Netlist reorganisation: + +* Obviously the top block or chip core model netlist is modificated to + contains all the clock sub-nets. The interface is *not* changed. +* If the top block contains instances of other models *and* those models + contains DFFs that get re-connecteds to the clock sub-nets (from the + top level). Change both the model netlist and interface to propagate + the relevant clock sub-nets to the instanciated model. The new model + with the added clock signal is renamed with a ``_clocked`` suffix. + For example, the sub-block model ``ram.vst`` will become ``ram_clocked.vst``. + +.. note:: + If you are to re-run the clock tree plugin on a netlist, be careful + to erase any previously generated ``_clocked`` file (both netlist and + layout: ``rm *.clocked.{ap,vst}``). And restart |cgt| to clear it's + memory cache. + +Configuration parameters, defaults are defined in ``etc/coriolis2//plugins.conf``. + ++-----------------------------------+------------------+----------------------------+ +| Parameter Identifier | Type | Default | ++===================================+==================+============================+ +| **ClockTree Plugin Parameters** | ++-----------------------------------+------------------+----------------------------+ +|``clockTree.minimumSide`` | TypeInt | :cb:`300` | +| +------------------+----------------------------+ +| | The minimum size below which the clock tree | +| | will stop to perform quadri-partitions | ++-----------------------------------+------------------+----------------------------+ +|``clockTree.buffer`` | TypeString | :cb:`buf_x2` | +| +------------------+----------------------------+ +| | The buffer model to use to drive sub-nets | ++-----------------------------------+------------------+----------------------------+ +|``clockTree.placerEngine`` | TypeString | :cb:`Etesian` | +| +------------------+----------------------------+ +| | The placer to use. Other value is ``Mauka`` | +| | the simulated annealing placer which will go | +| | into retirement very soon | ++-----------------------------------+------------------+----------------------------+ + + +Recursive-Save (RSave) +---------------------- + +Perform a recursive top down save of all the models from the top cell +loaded in |cgt|. Force a write of any non-terminal model. This plugin is used +by the clock tree plugin after the netlist clock sub-nets creation. + + +A Simple Example: AM2901 +~~~~~~~~~~~~~~~~~~~~~~~~ + +To illustrate the capabilities of |Coriolis| tools and |Python| scripting, a small +example, derived from the |Alliance| :cb:`AM2901` is supplied. + +This example contains only the synthetized netlists and the :cb:`doChip.py` script +which perform the whole P&R of the design. + +You can generate the chip using one of the following method: + +#. **Command line mode:** directly run the script: :: + + dummy@lepka:AM2901$ ./doChip -V --cell=amd2901 + +#. **Graphic mode:** launch |cgt|, load chip netlist ``amd2901`` (the top cell) + then run the |Python| script :cb:`doChip.py`. + +.. note:: + Between two consecutive run, be sure to erase the netlist/layout generateds: :: + + dummy@lepka:AM2901$ rm *_clocked*.vst *.ap diff --git a/documentation/_build/html/_sources/UsersGuide/ViewerTools.txt b/documentation/_build/html/_sources/UsersGuide/ViewerTools.txt new file mode 100644 index 00000000..8313e1df --- /dev/null +++ b/documentation/_build/html/_sources/UsersGuide/ViewerTools.txt @@ -0,0 +1,868 @@ +.. -*- Mode: rst -*- + +.. include:: ../etc/definitions.rst + +.. URLs that changes between the various backends. +.. _Stratus Documentation: file:///usr/share/doc/coriolis2/en/html/stratus/index.html + + +.. |BigMouse| image:: ./images/ComputerMouse.png + :scale: 25% + +.. |ViewerSnapshot_1| image:: ./images/Viewer-1.png + :alt: Viewer Basic Snapshot + :align: middle + :width: 80% + +.. |ControllerSnapshot_1| image:: ./images/Controller-1.png + :alt: Controller Basic Snapshot + :align: middle + :width: 80% + +.. |ControllerLook_1| image:: ./images/Controller-Look-1.png + :alt: Controller Look, Snapshot 1 + :align: middle + :width: 80% + +.. |ControllerFilter_1| image:: ./images/Controller-Filter-1.png + :alt: Controller Basic Snapshot + :align: middle + :width: 80% + +.. |ControllerLayersGos_1| image:: ./images/Controller-LayersGos-1.png + :alt: Controller Basic Snapshot + :align: middle + :width: 80% + +.. |ControllerNetlist_1| image:: ./images/Controller-Netlist-1.png + :alt: Controller Basic Snapshot + :align: middle + :width: 80% + +.. |ViewerNetlist_1| image:: ./images/Viewer-Netlist-1.png + :alt: Controller Basic Snapshot + :align: middle + :width: 80% + +.. |ControllerSelection_1| image:: ./images/Controller-Selection-1.png + :alt: Controller Basic Snapshot + :align: middle + :width: 80% + +.. |ControllerInspector_1| image:: ./images/Controller-Inspector-1.png + :alt: Controller Basic Snapshot + :align: middle + :width: 80% + +.. |ControllerInspector_2| image:: ./images/Controller-Inspector-2.png + :alt: Controller Basic Snapshot + :align: middle + :width: 80% + +.. |ControllerInspector_3| image:: ./images/Controller-Inspector-3.png + :alt: Controller Basic Snapshot + :align: middle + :width: 80% + +.. |ControllerSettings_1| image:: ./images/Controller-Settings-1.png + :alt: Controller Basic Snapshot + :align: middle + :width: 80% + +.. |Etesian-1| image:: ./images/etesian-1.png + :alt: Etesian Abutment Box + :align: middle + :width: 80% + + +CGT - The Graphical Interface +============================= + +The |Coriolis| graphical interface is split up into two windows. + +* The **Viewer**, with the following features: + + * Basic load/save capabilities. + * Display the current working cell. Could be empty if the design + is not yet placed. + * Execute Stratus Scripts. + * Menu to run the tools (placement, routage). + +Features are detailed in `Viewer & Tools`_. + +|ViewerSnapShot_1| + +* The **Controller**, which allows: + + * Tweak what is displayer by the *Viewer*. Through the *Look*, + *Filter* and *Layers&Gos* tabs. + * Browse the |netlist| with eponym tab. + * Show the list of selected objects (if any) with *selection* + * Walk through the Database, the Cell or the Selection with *Inspector*. + This is an advanced feature, reserved for experimented users. + * The tab *Settings* which give access to all the settings. + They are closely related to Configuration & Initialisation. + +|bcenter| |ControllerSnapShot_1| |ecenter| + + +.. _Viewer & Tools: + +Viewer & Tools +~~~~~~~~~~~~~~ + +|Stratus| Netlist Capture +------------------------- + +|Stratus| is the replacement for |GenLib| procedural netlist capture language. +It is designed as a set of |Python| classes, and comes with it's own documentation +(`Stratus Documentation`_) + + +The |Hurricane| Data-Base +------------------------- + +The |Alliance| flow is based on the |MBK| data-base, which has one data-structure +for each view. That is, |LOFIG| for the *logical* view and |PHFIG| for the *physical* +view. The place and route tools were responsible for maintaining (or not) the +coherency between views. Reflecting this weak coupling between views, each one +was stored in a separate file with a specific format. The *logical* view is stored +in a |vst| file in |VHDL| format and the *physical* in an |ap| file in an ad-hoc format. + +The |Coriolis| flow is based on the |Hurricane| data-base, which has a unified +structure for *logical* and *physical* view. That data structure is the |Cell| object. +The |Cell| can have any state between pure netlist and completly placed and +routed design. Although the memory representation of the views has deeply +changed we still use the |Alliance| files format, but they now really represent +views of the same object. The point is that one must be very careful about +view coherency when going to and from |Coriolis|. + +As for the second release, |Coriolis| can be used only for three purposes : + +* **Placing a design**, in which case the |netlist| view must be present. +* **Routing a design**, in that case the |netlist| + view and the |layout| view must be present and |layout| view must contain + a placement. Both views must have the same name. When saving the routed design, + it is advised to change the design name otherwise the original unrouted placement + in the |layout| view will be overwritten. +* **Viewing a design**, the |netlist| view must be present, if a |layout| + view is present it still must have the same name but it can be in any + state. + + +Synthetizing and loading a design +--------------------------------- + +|Coriolis| supports several file formats. It can load all file format +from the |Alliance| toolchain (.ap for layout, behavioural and structural vhdl .vbe and .vst), +BLIF netlist format as well as benchmark formats from the ISPD contests. + +It can be compiled with LEF/DEF support, although it requires acceptance of the SI2 license +and may not be compiled in your version of the software. + +Synthesis under Yosys +..................... + +You can create a BLIF file from the |Yosys| synthetizer, which can be imported under Coriolis. +Most libraries are specified as a .lib liberty file and a .lef LEF file. +|Yosys| opens most .lib files with minor modifications, but LEF support in Coriolis relies on SI2. +If Coriolis hasn't been compiled against it, the library is given in |Alliance| .ap format. +`Some free libraries `_ already provide both .ap and .lib files. + +Once you have installed a common library under |Yosys| and Coriolis, just synthetize your design +with |Yosys| and import it (as Blif without the extension) under Coriolis to perform place&route. + +Synthesis under Alliance +........................ + +|Alliance| is an older toolchain but has been extensively used for years. Coriolis can import +and write Alliance designs and libraries directly. + +Etesian -- Placer +----------------- + +The |Etesian| placer is a state of the art (as of 2015) analytical placer. It is +within ``5%`` of other placers' solutions, but is normally a bit worse than ePlace. +This |Coriolis| tool is actually an encapsulation of |Coloquinte| which *is* the placer. + +.. note:: *Instance Uniquification Unsupported:* a same logical instance cannot have + two different placements. So, either you manually make a clone of it or you + supply a placement for it. We need to implement uniquification in the + |Hurricane| database. + + +|noindent| +**Hierarchical Placement** + +The placement area is defined by the top cell abutment box. + +When placing a complete hierarchy, the abutment boxes of the cells (models) other than +the top cell are sets identical to the one of the top cell and their instances are +all placed at position ``(0,0,ID)``. That is, all the abutments boxes, whatever the +hierarchical level, defines the same area (they are exactly superposed). + +We choose this scheme because the placer will see all the instances as virtually +flattened, so they can be placed anywhere inside the top-cell abutment box. + +|bcenter| |Etesian-1| |ecenter| + + +|noindent| +**Computing the Placement Area** + +The placement area is computed using the ``etesian.aspectRatio`` and ``etesian.spaceMargin`` +parameters only if the top-cell has an empty abutment box. If the top-cell abutment +box has to be set, then it is propagated to all the instances models recursively. + + +|noindent| +**Reseting the Placement** + +Once a placement has been done, the placer cannot reset it (will be implemented +later). To perform a new placement, you must restart |cgt|. In addition, if you +have saved the placement on disk, you must erase any :cb:`.ap` file, which are +automatically reloaded along with the netlist (:cb:`.vst`). + +|noindent| +**Limitations** + +Etesian supports standard cells and fixed macros. As for the Coriolis 2.1 version, +it doesn't support movable macros, and you must place every macro beforehand. +Timing and routability analysis are not included either, and the returned placement +may be unroutable. + + +Etesian Configuration Parameters +................................ + ++-----------------------------------+------------------+----------------------------+ +| Parameter Identifier | Type | Default | ++===================================+==================+============================+ +| **Etesian Parameters** | ++-----------------------------------+------------------+----------------------------+ +|``etesian.aspectRatio`` | TypePercentage | :cb:`100` | +| +------------------+----------------------------+ +| | Define the height on width ``H/W`` aspect | +| | ratio, can be comprised between 10 and 1000 | ++-----------------------------------+------------------+----------------------------+ +|``etesian.spaceMargin`` | TypePercentage | :cb:`5` | +| +------------------+----------------------------+ +| | The extra white space added to the total area | +| | of the standard cells | ++-----------------------------------+------------------+----------------------------+ +|``etesian.uniformDensity`` | TypeBool | :cb:`False` | +| +------------------+----------------------------+ +| | Whether the cells will be spread envenly | +| | across the area or allowed to form denser | +| | clusters | ++-----------------------------------+------------------+----------------------------+ +|``etesian.effort`` | TypeInt | :cb:`2` | +| +------------------+----------------------------+ +| | Sets the balance between the speed of the | +| | placer and the solution quality | ++-----------------------------------+------------------+----------------------------+ +|``etesian.routingDriven`` | TypeBool | :cb:`False` | +| +------------------+----------------------------+ +| | Whether the tool will try routing iterations | +| | and whitespace allocation to improve | +| | routability; to be implemented | ++-----------------------------------+------------------+----------------------------+ +|``etesian.graphics`` | TypeInt | :cb:`2` | +| +------------------+----------------------------+ +| | How often the display will be refreshed | +| | More refreshing slows the placer. | +| | | +| | * ``1`` shows both upper and lower bounds | +| | * ``2`` only shows lower bound results | +| | * ``3`` only shows the final results | ++-----------------------------------+-----------------------------------------------+ + +|newpage| + + +Knik -- Global Router +--------------------- + +The quality of |Knik| global routing solutions are equivalent to those of FGR_ 1.0. +For an in-depth description of |Knik| algorithms, you may download the thesis of +D. |Dupuis| avalaible from here~: `Knik Thesis`_. + +The global router is (not yet) deterministic. To circumvent this limitation, +a global routing *solution* can be saved to disk and reloaded for later uses. + +A global routing is saved into a file with the same name as the design and a +|kgr| extention. It is in `Box Router`_ output format. + +|noindent| Menus: + +* :math:`\textbf{P\&R} \rightarrow \textbf{Step by Step} \rightarrow \textbf{Save Global Routing}` +* :math:`\textbf{P\&R} \rightarrow \textbf{Step by Step} \rightarrow \textbf{Load Global Routing}` + + +Kite -- Detailed Router +----------------------- + +|Kite| no longer suffers from the limitations of |Nero|. It can route big designs +as its runtime and memory footprint is almost linear (with respect to the number +of gates). It has successfully routed design of more than `150K` gates. +|medskip| + +|noindent| However, this first release comes with the temporary the following +restrictions: + +* Works only with |SxLib| standard cell gauge. +* Works always with 4 routing metal layers (`M2` through `M5`). +* Do not allow (take into account) pre-routed wires on signals + other than |POWER| or |GROUND|. + +.. note:: + **Slow Layer Assignment.** Most of the time, the layer assignment stage is + fast (less than a dozen seconds), but in some instances it can take more + than a dozen *minutes*. This is a known bug and will be corrected in later + releases. + +After each run, |Kite| displays a set of *completion ratios* which must all +be equal to `100%` if the detailed routing has been successfull. +In the event of a failure, on a saturated design, you may decrease the +`edge saturation ratio` (argument `--edge`) to balance more evenly the design +saturation. That is, the maximum saturation decrease at the price of a wider +saturated area and increased wirelength. This is the saturation of the +*global* router |Knik|, and you may increase/decrease by steps of ``5%``, +which represent one track. The maximum capacity of the |SxLib| gauge is +10 tracks in two layers, that makes 20 tracks by |Knik| edge. + +Routing a design is done in four ordered steps: + +#. Detailed pre-route :math:`\textbf{P\&R} \rightarrow \textbf{Step by Step} \rightarrow \textbf{Detailed PreRoute}` +#. Global routing :math:`\textbf{P\&R} \rightarrow \textbf{Step by Step} \rightarrow \textbf{Global Route}` +#. Detailed routing :math:`\textbf{P\&R} \rightarrow \textbf{Step by Step} \rightarrow \textbf{Detailed Route}` +#. Finalize routing :math:`\textbf{P\&R} \rightarrow \textbf{Step by Step} \rightarrow \textbf{Finalize Route}` + +It is possible to supply to the router a complete wiring for some nets that the user's +wants to be routed according to a specific topology. The supplied topology must respect +the building rules of the |Katabatic| database (contacts must be, terminals, turns, h-tee +& v-tee only). During the first step :fboxtt:`Detailed Pre-Route` the router will solve +overlaps between the segments, without making any dogleg. If no pre-routed topologies +are present, this step may be ommited. Any net routed at this step is then fixed and +become unmovable for the later stages. + +After the detailed routing step the |Kite| data-structure is still active +(the Hurricane wiring is decorated). The finalize step performs the removal of +the |Kite| data-structure, and it is not advisable to save the design before +that step. + +You may visualize the density (saturation) of either |Knik| (on edges) or +|Kite| (on GCells) until the routing is finalized. Special layers appears +to that effect in the `The Layers&Go Tab`_. + + +Kite Configuration Parameters +............................. + +As |Knik| is only called through |Kite|, it's parameters also have +the :cb:`kite.` prefix. + +The |Katabatic| parameters control the layer assignment step. + +All the defaults value given below are from the default |Alliance| technology +(:cb:`cmos` and :cb:`SxLib` cell gauge/routing gauge). + ++-----------------------------------+------------------+----------------------------+ +| Parameter Identifier | Type | Default | ++===================================+==================+============================+ +| **Katabatic Parameters** | ++-----------------------------------+------------------+----------------------------+ +|``katabatic.topRoutingLayer`` | TypeString | :cb:`METAL5` | +| +------------------+----------------------------+ +| | Define the highest metal layer that will be | +| | used for routing (inclusive). | ++-----------------------------------+------------------+----------------------------+ +|``katabatic.globalLengthThreshold``| TypeInt | :cb:`1450` | +| +------------------+----------------------------+ +| | This parameter is used by a layer assignment | +| | method which is no longer used (did not give | +| | good results) | ++-----------------------------------+------------------+----------------------------+ +| ``katabatic.saturateRatio`` | TypePercentage | :cb:`80` | +| +------------------+----------------------------+ +| | If ``M(x)`` density is above this ratio, | +| | move up feedthru global segments up from | +| | depth ``x`` to ``x+2`` | ++-----------------------------------+------------------+----------------------------+ +| ``katabatic.saturateRp`` | TypeInt | :cb:`8` | +| +------------------+----------------------------+ +| | If a GCell contains more terminals | +| | (:cb:`RoutingPad`) than that number, force a | +| | move up of the connecting segments to those | +| | in excess | ++-----------------------------------+------------------+----------------------------+ +| **Knik Parameters** | ++-----------------------------------+------------------+----------------------------+ +| ``kite.hTracksReservedLocal`` | TypeInt | :cb:`3` | +| +------------------+----------------------------+ +| | To take account the tracks needed *inside* a | +| | GCell to build the *local* routing, decrease | +| | the capacity of the edges of the global | +| | router. Horizontal and vertical locally | +| | reserved capacity can be distinguished for | +| | more accuracy. | ++-----------------------------------+------------------+----------------------------+ +| ``kite.vTracksReservedLocal`` | TypeInt | :cb:`3` | +| +------------------+----------------------------+ +| | cf. ``kite.hTracksReservedLocal`` | ++-----------------------------------+------------------+----------------------------+ +| **Kite Parameters** | ++-----------------------------------+------------------+----------------------------+ +| ``kite.eventsLimit`` | TypeInt | :cb:`4000002` | +| +------------------+----------------------------+ +| | The maximum number of segment displacements, | +| | this is a last ditch safety against infinite | +| | loop. It's perhaps a little too low for big | +| | designs | ++-----------------------------------+------------------+----------------------------+ +| ``kite.ripupCost`` | TypeInt | :cb:`3` | +| +------------------+----------------------------+ +| | Differential introduced between two ripup | +| | cost to avoid a loop between two ripped up | +| | segments | ++-----------------------------------+------------------+----------------------------+ +| ``kite.strapRipupLimit`` | TypeInt | :cb:`16` | +| +------------------+----------------------------+ +| | Maximum number of ripup for *strap* segments | ++-----------------------------------+------------------+----------------------------+ +| ``kite.localRipupLimit`` | TypeInt | :cb:`9` | +| +------------------+----------------------------+ +| | Maximum number of ripup for *local* segments | ++-----------------------------------+------------------+----------------------------+ +| ``kite.globalRipupLimit`` | TypeInt | :cb:`5` | +| +------------------+----------------------------+ +| | Maximum number of ripup for *global* segments,| +| | when this limit is reached, triggers topologic| +| | modification | ++-----------------------------------+------------------+----------------------------+ +| ``kite.longGlobalRipupLimit`` | TypeInt | :cb:`5` | +| +------------------+----------------------------+ +| | Maximum number of ripup for *long global* | +| | segments, when this limit is reached, triggers| +| | topological modification | ++-----------------------------------+------------------+----------------------------+ + + + +.. _Python Scripts in Cgt: + +Executing Python Scripts in Cgt +------------------------------- + +Python/Stratus scripts can be executed either in text or graphical mode. + +.. note:: **How Cgt Locates Python Scripts:** + |cgt| uses the Python ``import`` mechanism to load Python scripts. + So you must give the name of your script whitout ``.py`` extention and + it must be reachable through the ``PYTHONPATH``. You may uses the + dotted module notation. + +A Python/Stratus script must contains a function called ``ScriptMain()`` +with one optional argument, the graphical editor into which it may be +running (will be set to ``None`` in text mode). The Python interface to +the editor (type: :cb:`CellViewer`) is limited to basic capabilities +only. + +Any script given on the command line will be run immediatly *after* the +initializations and *before* any other argument is processed. + +For more explanation on Python scripts see :ref:`Python Interface to Coriolis`. + + +Printing & Snapshots +-------------------- + +Printing or saving into a |pdf| is fairly simple, just uses the **File -> Print** +menu or the |CTRL_P| shortcut to open the dialog box. + +The print functionality uses exactly the same rendering mechanism as for the +screen, beeing almost *WYSIWYG*. Thus, to obtain the best results it is advisable +to select the ``Coriolis.Printer`` look (in the *Controller*), which uses a +white background and much suited for high resolutions ``32x32`` pixels patterns + +There is also two mode of printing selectable through the *Controller* +**Settings -> Misc -> Printer/Snapshot Mode**: + +=============== ================= ===================================================== +Mode DPI (approx.) Intended Usage +--------------- ----------------- ----------------------------------------------------- +**Cell Mode** 150 For single ``Cell`` printing or very small designs. + Patterns will be bigger and more readable. +**Design Mode** 300 For designs (mostly commposed of wires and cells + outlines). +=============== ================= ===================================================== + +.. note:: *The pdf file size* + Be aware that the generated |pdf| files are indeed only pixmaps. + So they can grew very large if you select paper format above ``A2`` + or similar. + + +|noindent| +Saving into an image is subject to the same remarks as for |pdf|. + + +Memento of Shortcuts in Graphic Mode +------------------------------------ + +The main application binary is |cgt|. + ++---------------+-------------------+-----------------------------------------------------------+ +| Category | Keys | Action | ++===============+===================+===========================================================+ +| **Moves** | | |KeyUp|, | Shift the view in the according direction | +| | |KeyDown| | | +| | | |KeyLeft|, | | +| | |KeyRight| | | ++---------------+-------------------+-----------------------------------------------------------+ +| **Fit** | |KeyF| | Fit to the Cell abutment box | ++---------------+-------------------+-----------------------------------------------------------+ +| **Refresh** | |CTRL_L| | Triggers a complete display redraw | ++---------------+-------------------+-----------------------------------------------------------+ +| **Goto** | |KeyG| | *apperture* is the minimum side of the area | +| | | displayed around the point to go to. It's an | +| | | alternative way of setting the zoom level | ++---------------+-------------------+-----------------------------------------------------------+ +| **Zoom** | |KeyZ|, | Respectively zoom by a 2 factor and *unzoom* | +| | |KeyM| | by a 2 factor | +| +-------------------+-----------------------------------------------------------+ +| | | |BigMouse| | You can perform a zoom to an area. | +| | | Area Zoom | Define the zoom area by *holding down the left | +| | | mouse button* while moving the mouse. | ++---------------+-------------------+-----------------------------------------------------------+ +| **Selection** | | |BigMouse| | You can select displayed objects under an area. | +| | | Area Selection | Define the selection area by *holding down the | +| | | right mouse button* while moving the mouse. | +| +-------------------+-----------------------------------------------------------+ +| | | |BigMouse| | You can toggle the selection of one object under | +| | | Toggle Selection| the mouse position by pressing |CTRL| and | +| | | pressing down *the right mouse button*. A popup | +| | | list of what's under the position shows up into | +| | | which you can toggle the selection state of one | +| | | item. | +| +-------------------+-----------------------------------------------------------+ +| | |KeyCapS| | Toggle the selection visibility | ++---------------+-------------------+-----------------------------------------------------------+ +| **Controller**| |CTRL_I| | Show/hide the controller window. | +| | | | +| | | It's the Swiss Army Knife of the viewer. | +| | | From it, you can fine-control the display and | +| | | inspect almost everything in your design. | ++---------------+-------------------+-----------------------------------------------------------+ +| **Rulers** | |KeyK|, | One stroke on |KeyK| enters the ruler mode, in | +| | |KeyESC| | which you can draw one ruler. You can exit the | +| | | ruler mode by pressing |KeyESC|. Once in ruler | +| | | mode, the first click on the *left mouse button* | +| | | sets the ruler's starting point and the second | +| | | click the ruler's end point. The second click | +| | | exits automatically the ruler mode. | +| +-------------------+-----------------------------------------------------------+ +| | |KeyCapK| | Clears all the drawn rulers | ++---------------+-------------------+-----------------------------------------------------------+ +| **Print** | |CTRL_P| | Currently rather crude. It's a direct copy of | +| | | what's displayed in pixels. So the resulting | +| | | picture will be a little blurred due to | +| | | anti-aliasing mechanism. | ++---------------+-------------------+-----------------------------------------------------------+ +| **Open/Close**| |CTRL_O| | Opens a new design. The design name must be | +| | | given without path or extention. | +| +-------------------+-----------------------------------------------------------+ +| | |CTRL_W| | Close the current viewer window, but do not quit | +| | | the application. | +| +-------------------+-----------------------------------------------------------+ +| | |CTRL_Q| | `CTRL+Q` quit the application | +| | | (closing all windows). | ++---------------+-------------------+-----------------------------------------------------------+ +| **Hierarchy** | |CTRL_Down| | Go one hierarchy level down. That is, if there | +| | | is an *instance* under the cursor position, load | +| | | it's *model* Cell in place of the current one. | +| +-------------------+-----------------------------------------------------------+ +| | |CTRL_Up| | Go one hierarchy level up. if we have entered | +| | | the current model through |CTRL_Down| | +| | | reload the previous model (the one | +| | | in which this model is instanciated). | ++---------------+-------------------+-----------------------------------------------------------+ + + +Cgt Command Line Options +------------------------ + +Appart from the obvious ``--text`` options, all can be used for text and graphical mode. + ++-----------------------------+------------------------------------------------+ +| Arguments | Meaning | ++=============================+================================================+ +| `-t|--text` | Instruct |cgt| to run in text mode. | ++-----------------------------+------------------------------------------------+ +| `-L|--log-mode` | Disable the uses of |ANSI| escape sequence on | +| | the |tty|. Useful when the output is | +| | redirected to a file. | ++-----------------------------+------------------------------------------------+ +| `-c |--cell=` | The name of the design to load, without | +| | leading path or extention. | ++-----------------------------+------------------------------------------------+ +| `-g|--load-global` | Reload a global routing solution from disk. | +| | The file containing the solution must be named | +| | `.kgr`. | ++-----------------------------+------------------------------------------------+ +| `--save-global` | Save the global routing solution, into a file | +| | named `.kgr`. | ++-----------------------------+------------------------------------------------+ +| `-e |--edge=` | Change the edge capacity for the global | +| | router, between 0 and 1 (|Knik|). | ++-----------------------------+------------------------------------------------+ +| `-G|--global-route` | Run the global router (|Knik|). | ++-----------------------------+------------------------------------------------+ +| `-R|--detailed-route` | Run the detailed router (|Kite|). | ++-----------------------------+------------------------------------------------+ +| `-s|--save-design=` | The design into which the routed layout will | +| | be saved. It is strongly recommanded to choose | +| | a different name from the source (unrouted) | +| | design. | ++-----------------------------+------------------------------------------------+ +| `--events-limit=` | The maximal number of events after which the | +| | router will stops. This is mainly a failsafe | +| | against looping. The limit is sets to 4 | +| | millions of iteration which should suffice to | +| | any design of `100K`. gates. For bigger | +| | designs you may wants to increase this limit. | ++-----------------------------+------------------------------------------------+ +| `--stratus-script=` | Run the Python/Stratus script ``module``. | +| | See `Python Scripts in Cgt`_. | ++-----------------------------+------------------------------------------------+ + +|newpage| + + +Some Examples : + +* Run both global and detailed router, then save the routed design : :: + + > cgt -v -t -G -R --cell=design --save-design=design_kite + +* Load a previous global solution, run the detailed router, then save the + routed design : :: + + > cgt -v -t --load-global -R --cell=design --save-design=design_kite + +* Run the global router, then save the global routing solution : :: + + > cgt -v -t -G --save-global --cell=design + + +Miscellaneous Settings +---------------------- + ++---------------------------------------+------------------+----------------------------+ +| Parameter Identifier | Type | Default | ++=======================================+==================+============================+ +| **Verbosity/Log Parameters** | ++---------------------------------------+------------------+----------------------------+ +| ``misc.info`` | TypeBool | :cb:`False` | +| +------------------+----------------------------+ +| | Enable display of *info* level message | +| | (:cb:`cinfo` stream) | ++---------------------------------------+------------------+----------------------------+ +| ``misc.bug`` | TypeBool | :cb:`False` | +| +------------------+----------------------------+ +| | Enable display of *bug* level message | +| | (:cb:`cbug` stream), messages can be a little | +| | scarry | ++---------------------------------------+------------------+----------------------------+ +| ``misc.logMode`` | TypeBool | :cb:`False` | +| +------------------+----------------------------+ +| | If enabled, assume that the output device | +| | is not a ``tty`` and suppress any escaped | +| | sequences | ++---------------------------------------+------------------+----------------------------+ +| ``misc.verboseLevel1`` | TypeBool | :cb:`True` | +| +------------------+----------------------------+ +| | First level of verbosity, disable level 2 | ++---------------------------------------+------------------+----------------------------+ +| ``misc.verboseLevel2`` | TypeBool | :cb:`False` | +| +------------------+----------------------------+ +| | Second level of verbosity | ++---------------------------------------+------------------+----------------------------+ +| **Development/Debug Parameters** | ++---------------------------------------+------------------+----------------------------+ +| ``misc.minTraceLevel`` | TypeInt | :cb:`0` | ++---------------------------------------+------------------+----------------------------+ +| ``misc.maxTraceLevel`` | TypeInt | :cb:`0` | +| +------------------+----------------------------+ +| | Display trace information *between* those two | +| | levels (:cb:`cdebug` stream) | ++---------------------------------------+------------------+----------------------------+ +| ``misc.catchCore`` | TypeBool | :cb:`False` | +| +------------------+----------------------------+ +| | By default, |cgt| do not dump core. | +| | To generate one set this flag to :cb:`True` | ++---------------------------------------+------------------+----------------------------+ + +|newpage| + + +.. _The Controller: + +The Controller +~~~~~~~~~~~~~~ + +The *Controller* window is composed of seven tabs: + +#. `The Look Tab`_ to select the display style. +#. `The Filter Tab`_ the hierarchical levels to be displayed, the look of + rubbers and the dimension units. +#. `The Layers&Go Tab`_ to selectively hide/display layers. +#. `The Netlist Tab`_ to browse through the |netlist|. Works in association + with the *Selection* tab. +#. `The Selection Tab`_ allow to view all the currently selected elements. +#. `The Inspector Tab`_ browse through either the DataBase, the Cell or + the current selection. +#. `The Settings Tab`_ access all the tool's configuration settings. + + +.. _The Look Tab: + +The Look Tab +------------ + +You can select how the layout will be displayed. There is a special one +``Printer.Coriolis`` specifically designed for `Printing & Snapshots`_. +You should select it prior to calling the print or snapshot dialog boxes. + +|bcenter| |ControllerLook_1| |ecenter| + +|newpage| + + +.. _The Filter Tab: + +The Filter Tab +-------------- + +The filter tab let you select what hierarchical levels of your design will be +displayed. Hierarchy level are numbered top-down: the level 0 correspond to +the top-level cell, the level one to the instances of the top-level Cell and +so on. + +There are also check boxes to enable/disable the processing of Terminal Cell, +Master Cells and Compnents. The processing of Terminal Cell (hierarchy leaf +cells) is disabled by default when you load a hierarchical design and enabled +when you load a single Cell. + +You can choose what kind of form to give to the rubbers and the type of +unit used to display coordinates. + +.. note:: *What are Rubbers:* |Hurricane| uses *Rubbers* to materialize + physical gaps in net topology. That is, if some wires are missing to + connect two or more parts of net, a *rubber* will be drawn between them + to signal the gap. + + For example, after the detailed routing no *rubbers* should remains. + They have been made *very* visibles as big violet lines... + +|bcenter| |ControllerFilter_1| |ecenter| + +|newpage| + + +.. _The Layers&Go Tab: + +The Layers&Go Tab +----------------- + +Control the individual display of all *layers* and *Gos*. + +* *Layers* correspond to a true physical layer. From a |Hurricane| point of + view they are all the *BasicLayers* (could be matched to GDSII). +* *Gos* stands from *Graphical Objects*, they are drawings that have no + physical existence but are added by the various tools to display extra + information. One good exemple is the density map of the detailed router, + to easily locate congested areas. + +For each layer/Go there are two check boxes: + +* The normal one triggers the display. +* The red-outlined allows objects of that layer to be selectable or not. + +|bcenter| |ControllerLayersGos_1| |ecenter| + + +.. _The Netlist Tab: + +The Netlist Tab +--------------- + +The *Netlist* tab shows the list of nets... By default the tab is not +*synched* with the displayed Cell. To see the nets you must check the +**Sync Netlist** checkbox. You can narrow the set of displayed nets by +using the filter pattern (supports regular expressions). + +An very useful feature is to enable the **Sync Selection**, which will +automatically select all the components of the selected net(s). You can +select multiple nets. In the figure the net ``auxsc35`` is selected and +is highlited in the *Viewer*. + +|bcenter| |ControllerNetlist_1| |ecenter| +|bcenter| |ViewerNetlist_1| |ecenter| + + +.. _The Selection Tab: + +The Selection Tab +----------------- + +The *Selection* tab list all the components currently selecteds. They +can be filtered thanks to the filter pattern. + +Used in conjunction with the *Netlist* **Sync Selection** you will all see +all the components part of *net*. + +In this list, you can toggle individually the selection of component by +pressing the ``t`` key. When unselected in this way a component is not +removed from the the selection list but instead displayed in red italic. +To see where a component is you may make it blink by repeatedly press +the ``t`` key... + +|bcenter| |ControllerSelection_1| |ecenter| + + +.. _The Inspector Tab: + +The Inspector Tab +----------------- + +This tab is very useful, but mostly for |Coriolis| developpers. It allows +to browse through the live DataBase. The *Inspector* provide three entry points: + +* **DataBase**: Starts from the whole |Hurricane| DataBase. +* **Cell**: Inspect the currently loaded Cell. +* **Selection**: Inspect the object currently highlited in the *Selection* tab. + +Once an entry point has been activated, you may recursively expore all +it's fields using the right/left arrows. + +.. note:: *Do not put your fingers in the socket:* when inspecting + anything, do not modify the DataBase. If any object under inspection + is deleted, you will crash the application... + +.. note:: *Implementation Detail:* the inspector support is done with + ``Slot``, ``Record`` and ``getString()``. + +|bcenter| |ControllerInspector_1| |ecenter| +|bcenter| |ControllerInspector_2| |ecenter| +|bcenter| |ControllerInspector_3| |ecenter| + + +.. _The Settings Tab: + +The Settings Tab +---------------- + +Here comes the description of the *Settings* tab. + +|bcenter| |ControllerSettings_1| |ecenter| diff --git a/documentation/_build/html/_sources/UsersGuide/index.txt b/documentation/_build/html/_sources/UsersGuide/index.txt new file mode 100644 index 00000000..7121510a --- /dev/null +++ b/documentation/_build/html/_sources/UsersGuide/index.txt @@ -0,0 +1,21 @@ +.. -*- mode: rst; explicit-buffer-name: "index.rst" -*- + +.. include:: ../etc/definitions.rst + + +======================= +Coriolis User's Guide +======================= + +Printable version of this document `UsersGuide.pdf <../../../pdf/main/UsersGuide.pdf>`_. + + +.. toctree:: + :maxdepth: 2 + + LicenseCredits.rst + Releases.rst + Installation.rst + Configuration.rst + ViewerTools.rst + ScriptsPlugins.rst diff --git a/documentation/_build/html/_sources/Viewer/Viewer.txt b/documentation/_build/html/_sources/Viewer/Viewer.txt new file mode 100644 index 00000000..c103b413 --- /dev/null +++ b/documentation/_build/html/_sources/Viewer/Viewer.txt @@ -0,0 +1,11 @@ +.. -*- Mode: rst -*- + +.. include:: ../etc/definitions.rst + + +================== +Viewer Reference +================== + +The Viewer C++ API reference is generated by Doxygen_ and is +available here: `Viewer `_ diff --git a/documentation/_build/html/_sources/etc/definitions.txt b/documentation/_build/html/_sources/etc/definitions.txt new file mode 100644 index 00000000..ab364f9b --- /dev/null +++ b/documentation/_build/html/_sources/etc/definitions.txt @@ -0,0 +1,182 @@ +.. -*- Mode: rst; explicit-buffer-name: "definition.rst" -*- + + +.. role:: raw-html(raw) + :format: html + +.. role:: raw-latex(raw) + :format: latex + +.. role:: ul +.. role:: cb +.. role:: sc +.. role:: fboxtt + +.. HTML/LaTeX backends mixed macros. +.. |br| replace:: :raw-latex:`\linebreak` :raw-html:`
` +.. |medskip| replace:: :raw-latex:`\medskip` :raw-html:`
` +.. |newpage| replace:: :raw-latex:`\newpage` +.. |linebreak| replace:: :raw-latex:`\smallskip` +.. |noindent| replace:: :raw-latex:`\noindent` :raw-html:`

` +.. |dotfill| replace:: :raw-html:`  ` +.. |bcenter| replace:: :raw-latex:`\begin{center}` +.. |ecenter| replace:: :raw-latex:`\end{center}` +.. |pagestylefancy| replace:: :raw-latex:`\thispagestyle{fancy}` + + +.. Acronyms & names. +.. |GNU| replace:: :sc:`gnu` +.. |LGPL| replace:: :sc:`lgpl` +.. |GPL| replace:: :sc:`gpl` +.. |UPMC| replace:: :sc:`upmc` +.. |Bull| replace:: :sc:`Bull` +.. |Cadence| replace:: :sc:`Cadence` +.. |Si2| replace:: :sc:`Si2` +.. |LEFDEF| replace:: :sc:`lefdef` +.. |Flute| replace:: :sc:`Flute` +.. |MacOS| replace:: :sc:`MacOS` +.. |RHEL6| replace:: :sc:`rhel6` +.. |RHEL7| replace:: :sc:`rhel7` +.. |SL6| replace:: :sc:`Scientific Linux 6` +.. |SL7| replace:: :sc:`Scientific Linux 7` +.. |Scientific Linux| replace:: :sc:`Scientific Linux` +.. |RedHat| replace:: :sc:`RedHat` +.. |Fedora| replace:: :sc:`Fedora` +.. |FC13| replace:: :sc:`fc13` +.. |Debian| replace:: :sc:`Debian` +.. |Ubuntu| replace:: :sc:`Ubuntu` + +.. |Alexandre| replace:: :sc:`Alexandre` +.. |Belloeil| replace:: :sc:`Belloeil` +.. |Chaput| replace:: :sc:`Chaput` +.. |Chu| replace:: :sc:`Chu` +.. |Clement| replace:: :sc:`Clement` +.. |Dupuis| replace:: :sc:`Dupuis` +.. |Escassut| replace:: :sc:`Escassut` +.. |Gouvine| replace:: :sc:`Gouvine` +.. |Masson| replace:: :sc:`Masson` +.. |Sroka| replace:: :sc:`Sroka` +.. |Yifei| replace:: :sc:`Yifei` + +.. |ANSI| replace:: :sc:`ansi` +.. |MIPS| replace:: :sc:`mips` +.. |Am2901| replace:: :sc:`Am2901` +.. |Hurricane| replace:: :sc:`Hurricane` +.. |HurricaneAMS| replace:: :sc:`HurricaneAMS` +.. |Alliance| replace:: :sc:`Alliance` +.. |Yosys| replace:: :sc:`Yosys` +.. |GenLib| replace:: :sc:`GenLib` +.. |Nero| replace:: :sc:`Nero` +.. |Druc| replace:: :cb:`Druc` +.. |Coloquinte| replace:: :sc:`Coloquinte` +.. |Coriolis| replace:: :sc:`Coriolis` +.. |Coriolis1| replace:: :sc:`Coriolis 1` +.. |Coriolis2| replace:: :sc:`Coriolis 2` +.. |VLSISAPD| replace:: :sc:`vlsisapd` +.. |CRLcore| replace:: :sc:`CRLcore` +.. |Cyclop| replace:: :sc:`Cyclop` +.. |Nimbus| replace:: :sc:`Nimbus` +.. |hMetis| replace:: :sc:`hMetis` +.. |Mauka| replace:: :sc:`Mauka` +.. |Etesian| replace:: :sc:`Etesian` +.. |Knik| replace:: :sc:`Knik` +.. |Katabatic| replace:: :sc:`Katabatic` +.. |Kite| replace:: :sc:`Kite` +.. |Stratus| replace:: :sc:`Stratus` +.. |Stratus1| replace:: :sc:`Stratus1` +.. |Stratus2| replace:: :sc:`Stratus2` +.. |Unicorn| replace:: :sc:`Unicorn` +.. |ccb| replace:: :cb:`ccb` +.. |cgt| replace:: :cb:`cgt` +.. |Chams| replace:: :sc:`Chams` +.. |OpenChams| replace:: :sc:`OpenChams` +.. |Pharos| replace:: :cb:`Pharos` +.. |API| replace:: :sc:`api` +.. |STL| replace:: :sc:`stl` +.. |XML| replace:: :sc:`xml` +.. |pdf| replace:: :sc:`pdf` +.. |UTF-8| replace:: :sc:`utf-8` +.. |Python| replace:: :sc:`Python` +.. |Linux| replace:: :sc:`Linux` +.. |MacPorts| replace:: :sc:`MacPorts` +.. |devtoolset2| replace:: :cb:`devtoolset2` +.. |boost| replace:: :cb:`boost` +.. |Qt| replace:: :sc:`qt` +.. |tty| replace:: :cb:`tty` +.. |svn| replace:: :cb:`svn` +.. |git| replace:: :cb:`git` +.. |rpm| replace:: :cb:`rpm` +.. |gdb| replace:: :cb:`gdb` +.. |cmake| replace:: :cb:`cmake` +.. |struct| replace:: :cb:`struct` + +.. |KeyUp| replace:: :fboxtt:`Up` +.. |KeyDown| replace:: :fboxtt:`Down` +.. |KeyLeft| replace:: :fboxtt:`Left` +.. |KeyRight| replace:: :fboxtt:`Right` +.. |KeyF| replace:: :fboxtt:`f` +.. |KeyL| replace:: :fboxtt:`l` +.. |KeyG| replace:: :fboxtt:`g` +.. |KeyZ| replace:: :fboxtt:`z` +.. |KeyM| replace:: :fboxtt:`m` +.. |KeyI| replace:: :fboxtt:`i` +.. |KeyK| replace:: :fboxtt:`k` +.. |KeyP| replace:: :fboxtt:`p` +.. |KeyO| replace:: :fboxtt:`o` +.. |KeyW| replace:: :fboxtt:`w` +.. |KeyQ| replace:: :fboxtt:`q` +.. |KeyCapK| replace:: :fboxtt:`K` +.. |KeyCapS| replace:: :fboxtt:`S` +.. |Plus| replace:: :fboxtt:`+` +.. |KeyESC| replace:: :fboxtt:`ESC` +.. |CTRL| replace:: :fboxtt:`CTRL` +.. |CTRL_L| replace:: :fboxtt:`CTRL+L` +.. |CTRL_I| replace:: :fboxtt:`CTRL+I` +.. |CTRL_P| replace:: :fboxtt:`CTRL+P` +.. |CTRL_O| replace:: :fboxtt:`CTRL+O` +.. |CTRL_W| replace:: :fboxtt:`CTRL+W` +.. |CTRL_Q| replace:: :fboxtt:`CTRL+Q` +.. |CTRL_Down| replace:: :fboxtt:`CTRL+Down` +.. |CTRL_Up| replace:: :fboxtt:`CTRL+Up` +.. |CTRL_Left| replace:: :fboxtt:`CTRL+Left` +.. |CTRL_Right| replace:: :fboxtt:`CTRL+Right` + +.. URLs +.. _Doxygen: http://www.stack.nl/~dimitri/doxygen/ +.. _LaTeX2HTML: http://www.latex2html.org/ +.. _FGR: http://vlsicad.eecs.umich.edu/BK/FGR/ +.. _Box Router: http://www.cerc.utexas.edu/~thyeros/boxrouter/boxrouter.htm +.. _hMETIS: http://glaros.dtc.umn.edu/gkhome/views/metis +.. _Knik Thesis: http://www-soc.lip6.fr/en/users/damiendupuis/PhD/ +.. _RapidJSON: http://miloyip.github.io/rapidjson/ +.. _Python/C API Reference Manual: https://docs.python.org/2/c-api/index.html + +.. Standard CAO/VLSI Concepts. +.. |netlist| replace:: *netlist* +.. |netlists| replace:: *netlists* +.. |layout| replace:: *layout* +.. |layouts| replace:: *layouts* +.. |CMOS| replace:: :sc:`cmos` +.. |VHDL| replace:: :sc:`vhdl` +.. |NWELL| replace:: :sc:`nwell` +.. |POWER| replace:: :sc:`power` +.. |GROUND| replace:: :sc:`ground` + +.. MBK Concepts +.. |MBK| replace:: :sc:`mbk` +.. |LOFIG| replace:: :cb:`Lofig` +.. |PHFIG| replace:: :cb:`Phfig` +.. |SxLib| replace:: :sc:`SxLib` +.. |RDS| replace:: :sc:`rds` + +.. Hurricane Concepts. +.. |hypernet| replace:: *hypernet* +.. |hypernets| replace:: *hypernets* +.. |Cell| replace:: *Cell* +.. |Rings| replace:: *Rings* +.. |QuadTrees| replace:: *QuadTrees* +.. |Collections| replace:: *Collections* +.. |ap| replace:: :cb:`ap` +.. |vst| replace:: :cb:`vst` +.. |kgr| replace:: :cb:`kgr` +.. |dot_conf| replace:: :cb:`.conf` diff --git a/documentation/_build/html/_sources/index.txt b/documentation/_build/html/_sources/index.txt new file mode 100644 index 00000000..eb622595 --- /dev/null +++ b/documentation/_build/html/_sources/index.txt @@ -0,0 +1,34 @@ +.. -*- mode: rst; explicit-buffer-name: "index.rst" -*- + +.. Coriolis documentation master file, created by + sphinx-quickstart on Mon Jul 10 15:08:36 2017. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to Coriolis's documentation! +==================================== + +Contents: + +.. toctree:: + + UsersGuide/index.rst + Stratus/Stratus.rst + DpGen/DpGen.rst + Patterns/Patterns.rst + Hurricane/Hurricane.rst + Viewer/Viewer.rst + CrlCore/CrlCore.rst + Unicorn/Unicorn.rst + PythonCpp/index.rst + RDS/index.rst + + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` + diff --git a/documentation/etc/SoC-ReST.css b/documentation/_build/html/_static/SoC-ReST.css similarity index 96% rename from documentation/etc/SoC-ReST.css rename to documentation/_build/html/_static/SoC-ReST.css index eb5b2304..6b45edf2 100644 --- a/documentation/etc/SoC-ReST.css +++ b/documentation/_build/html/_static/SoC-ReST.css @@ -34,8 +34,10 @@ hr { color: #09550b; border: 1px dotted #09550b; border-style: none none dotted; +/* padding-top: 10pt; padding-bottom: 10pt; + */ } h2, h3 { @@ -77,6 +79,17 @@ div.contents p.first { font-weight: bold; } +table.contentstable { + width: 90%; +} + +table.contentstable, +table.contentstable tr, +table.contentstable tr td +{ + border: none; +} + div#centered { margin-left: auto; @@ -172,14 +185,14 @@ img.addborder { border: 1px solid black; } -img.align-center { +img.align-center, img.align-middle { display: block; /* clear: both; */ margin-left: auto; margin-right: auto; - width: 99%; + width: 70%; text-align: center; } @@ -206,7 +219,7 @@ div.note { border-left-style: solid; padding: 1px 10pt 1px 55px; /*background: #fff676 url('/dsk/l1/jpc/pictures/ReST/clipboard.png') no-repeat 0% 50%;;*/ - background: #ffdd66 url('../etc/images/clipboard.png') no-repeat 0% 50%;; + background: #ffdd66 url('../_static/images/clipboard.png') no-repeat 0% 50%;; font-size: 90% } @@ -216,7 +229,7 @@ div.error { border-left-width: 4px; border-left-style: solid; padding: 1px 10pt 1px 55px; - background: #ffddcc url('../etc/images/i-core.png') no-repeat 0% 50%;; + background: #ffddcc url('../_static/images/i-core.png') no-repeat 0% 50%;; font-size: 90% } diff --git a/documentation/_build/html/_static/SoC.css b/documentation/_build/html/_static/SoC.css new file mode 100644 index 00000000..391cd3e0 --- /dev/null +++ b/documentation/_build/html/_static/SoC.css @@ -0,0 +1,5 @@ + +@import url("../_static/css/theme.css"); +@import url("../_static/www-SoC.css"); +@import url("../_static/SoC-ReST.css"); +@import url("../_static/pygments.css"); diff --git a/documentation/_build/html/_static/ajax-loader.gif b/documentation/_build/html/_static/ajax-loader.gif new file mode 100644 index 00000000..61faf8ca Binary files /dev/null and b/documentation/_build/html/_static/ajax-loader.gif differ diff --git a/documentation/_build/html/_static/basic.css b/documentation/_build/html/_static/basic.css new file mode 100644 index 00000000..43e8bafa --- /dev/null +++ b/documentation/_build/html/_static/basic.css @@ -0,0 +1,540 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox input[type="text"] { + width: 170px; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + width: 30px; +} + +img { + border: 0; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li div.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable dl, table.indextable dd { + margin-top: 0; + margin-bottom: 0; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- general body styles --------------------------------------------------- */ + +a.headerlink { + visibility: hidden; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.field-list ul { + padding-left: 1em; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px 7px 0 7px; + background-color: #ffe; + width: 40%; + float: right; +} + +p.sidebar-title { + font-weight: bold; +} + +/* -- topics ---------------------------------------------------------------- */ + +div.topic { + border: 1px solid #ccc; + padding: 7px 7px 0 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +div.admonition dl { + margin-bottom: 0; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + border: 0; + border-collapse: collapse; +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +table.field-list td, table.field-list th { + border: 0 !important; +} + +table.footnote td, table.footnote th { + border: 0 !important; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +dl { + margin-bottom: 15px; +} + +dd p { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +dt:target, .highlighted { + background-color: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.refcount { + color: #060; +} + +.optional { + font-size: 1.3em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +td.linenos pre { + padding: 5px 0px; + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + margin-left: 0.5em; +} + +table.highlighttable td { + padding: 0 0.5em 0 0.5em; +} + +tt.descname { + background-color: transparent; + font-weight: bold; + font-size: 1.2em; +} + +tt.descclassname { + background-color: transparent; +} + +tt.xref, a tt { + background-color: transparent; + font-weight: bold; +} + +h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/documentation/_build/html/_static/comment-bright.png b/documentation/_build/html/_static/comment-bright.png new file mode 100644 index 00000000..551517b8 Binary files /dev/null and b/documentation/_build/html/_static/comment-bright.png differ diff --git a/documentation/_build/html/_static/comment-close.png b/documentation/_build/html/_static/comment-close.png new file mode 100644 index 00000000..09b54be4 Binary files /dev/null and b/documentation/_build/html/_static/comment-close.png differ diff --git a/documentation/_build/html/_static/comment.png b/documentation/_build/html/_static/comment.png new file mode 100644 index 00000000..92feb52b Binary files /dev/null and b/documentation/_build/html/_static/comment.png differ diff --git a/documentation/_build/html/_static/css/badge_only.css b/documentation/_build/html/_static/css/badge_only.css new file mode 100644 index 00000000..7e17fb14 --- /dev/null +++ b/documentation/_build/html/_static/css/badge_only.css @@ -0,0 +1,2 @@ +.fa:before{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-weight:normal;font-style:normal;src:url("../font/fontawesome_webfont.eot");src:url("../font/fontawesome_webfont.eot?#iefix") format("embedded-opentype"),url("../font/fontawesome_webfont.woff") format("woff"),url("../font/fontawesome_webfont.ttf") format("truetype"),url("../font/fontawesome_webfont.svg#FontAwesome") format("svg")}.fa:before{display:inline-block;font-family:FontAwesome;font-style:normal;font-weight:normal;line-height:1;text-decoration:inherit}a .fa{display:inline-block;text-decoration:inherit}li .fa{display:inline-block}li .fa-large:before,li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-0.8em}ul.fas li .fa{width:0.8em}ul.fas li .fa-large:before,ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before{content:""}.icon-book:before{content:""}.fa-caret-down:before{content:""}.icon-caret-down:before{content:""}.fa-caret-up:before{content:""}.icon-caret-up:before{content:""}.fa-caret-left:before{content:""}.icon-caret-left:before{content:""}.fa-caret-right:before{content:""}.icon-caret-right:before{content:""}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;border-top:solid 10px #343131;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;z-index:400}.rst-versions a{color:#2980B9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27AE60;*zoom:1}.rst-versions .rst-current-version:before,.rst-versions .rst-current-version:after{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book{float:left}.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#E74C3C;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#F1C40F;color:#000}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:gray;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:solid 1px #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px}.rst-versions.rst-badge .icon-book{float:none}.rst-versions.rst-badge .fa-book{float:none}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book{float:left}.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge .rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width: 768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}img{width:100%;height:auto}} +/*# sourceMappingURL=badge_only.css.map */ diff --git a/documentation/_build/html/_static/css/theme.css b/documentation/_build/html/_static/css/theme.css new file mode 100644 index 00000000..a53cc26a --- /dev/null +++ b/documentation/_build/html/_static/css/theme.css @@ -0,0 +1,3876 @@ + +/* +*{-webkit-box-sizing:border-box; + -moz-box-sizing:border-box; + box-sizing:border-box} + +article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block} + +audio,canvas,video{display:inline-block; + *display:inline; + *zoom:1} + +audio:not([controls]){display:none} + +[hidden]{display:none} + +*{-webkit-box-sizing:border-box; + -moz-box-sizing:border-box; + box-sizing:border-box} + +html{font-size:80%; + -webkit-text-size-adjust:80%; + -ms-text-size-adjust:80%} +*/ + +body { margin: 0; } + +a:hover, a:active { outline: 0; } + +/* +abbr[title]{border-bottom:1px dotted} + +b,strong{font-weight:bold} + +blockquote{margin:0} + +dfn{font-style:italic} + +ins{background:#ff9; + color:#000; + text-decoration:none} + +mark{background:#ff0; + color:#000; + font-style:italic; + font-weight:bold} + +pre,code,.rst-content tt,.rst-content code,kbd,samp{font-family:monospace,serif; + _font-family:"courier new",monospace; + font-size:1em} + +pre{white-space:pre} + +q{quotes:none} + +q:before,q:after{content:""; + content:none} + +small{font-size:85%} + +sub,sup{font-size:75%; + line-height:0; + position:relative; + vertical-align:baseline} + +sup{top:-0.5em} + +sub{bottom:-0.25em} +*/ + +.wy-menu ul, +.wy-menu ol, +.wy-menu dl +{ + margin: 0; + padding: 0; + list-style: none; + list-style-image: none; +} + +.wy-menu li { list-style: none; } + +/* +dd{margin:0} + +img{border:0; + -ms-interpolation-mode:bicubic; + vertical-align:middle; + max-width:100%} + +svg:not(:root){overflow:hidden} + +figure{margin:0} + +form{margin:0} + +fieldset{border:0; + margin:0; + padding:0} + +label{cursor:pointer} + +legend{border:0; + *margin-left:-7px; + padding:0; + white-space:normal} + +button,input,select,textarea{font-size:100%; + margin:0; + vertical-align:baseline; + *vertical-align:middle} + +button,input{line-height:normal} + +button,input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer; + -webkit-appearance:button; + *overflow:visible} + +button[disabled],input[disabled]{cursor:default} + +input[type="checkbox"],input[type="radio"]{box-sizing:border-box; + padding:0; + *width:13px; + *height:13px} + +input[type="search"]{-webkit-appearance:textfield; + -moz-box-sizing:content-box; + -webkit-box-sizing:content-box; + box-sizing:content-box} + +input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none} + +button::-moz-focus-inner,input::-moz-focus-inner{border:0; + padding:0} + +textarea{overflow:auto; + vertical-align:top; + resize:vertical} + +.chromeframe{margin:0.2em 0; + background:#ccc; + color:#000; + padding:0.2em 0} + +.ir{display:block; + border:0; + text-indent:-999em; + overflow:hidden; + background-color:transparent; + background-repeat:no-repeat; + text-align:left; + direction:ltr; + *line-height:0} + +.ir br{display:none} + +.hidden{display:none !important; + visibility:hidden} + +.visuallyhidden{border:0; + clip:rect(0 0 0 0); + height:1px; + margin:-1px; + overflow:hidden; + padding:0; + position:absolute; + width:1px} + +.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto; + height:auto; + margin:0; + overflow:visible; + position:static; + width:auto} + +.invisible{visibility:hidden} + +.relative{position:relative} + +big,small{font-size:100%} + +@media print{html,body,section{background:none !important} + +*{box-shadow:none !important; + text-shadow:none !important; + filter:none !important; + -ms-filter:none !important} + +a,a:visited{text-decoration:underline} +*/ + +.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""} + +/* +pre,blockquote{page-break-inside:avoid} + +thead{display:table-header-group} + +tr,img{page-break-inside:avoid} + +img{max-width:100% !important} + +@page{margin:0.5cm} + +p,h2,.rst-content p.caption,h3{orphans:3; + widows:3} + +h2,.rst-content p.caption,h3{page-break-after:avoid} + +} +*/ + +.fa:before, +.wy-menu-vertical li span.toctree-expand:before, +.wy-menu-vertical li.on a span.toctree-expand:before, +.wy-menu-vertical li.current>a span.toctree-expand:before, +.rst-content h1 .headerlink:before, +.rst-content h2 .headerlink:before, +.rst-content p.caption .headerlink:before, +.rst-content h3 .headerlink:before, +.rst-content h4 .headerlink:before, +.rst-content h5 .headerlink:before, +.rst-content h6 .headerlink:before, +.rst-content dl dt .headerlink:before, +.rst-content tt.download span:first-child:before, +.rst-content code.download span:first-child:before, +.icon:before, +.wy-dropdown .caret:before, +.wy-inline-validate.wy-inline-validate-success .wy-input-context:before, +.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before, +.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before, +.wy-inline-validate.wy-inline-validate-info .wy-input-context:before, +.wy-alert, +.btn, +input[type="text"], +input[type="password"], +input[type="email"], +input[type="url"], +input[type="date"], +input[type="month"], +input[type="time"], +input[type="datetime"], +input[type="datetime-local"], +input[type="week"], +input[type="number"], +input[type="search"], +input[type="tel"], +input[type="color"], +select, +textarea, +.wy-menu-vertical li.on a, +.wy-menu-vertical li.current>a, +.wy-side-nav-search>a, +.wy-side-nav-search .wy-dropdown>a, +.wy-nav-top a +{ -webkit-font-smoothing:antialiased; } + +/* +.clearfix{*zoom:1} + +.clearfix:before,.clearfix:after{display:table; + content:""} + +.clearfix:after{clear:both} +*/ + +/*! + * Font Awesome 4.2.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */ +@font-face { + font-family: 'FontAwesome'; + src: url("../fonts/fontawesome-webfont.eot?v=4.2.0"); + src: url("../fonts/fontawesome-webfont.eot?#iefix&v=4.2.0") format("embedded-opentype"), + url("../fonts/fontawesome-webfont.woff?v=4.2.0") format("woff"), + url("../fonts/fontawesome-webfont.ttf?v=4.2.0") format("truetype"), + url("../fonts/fontawesome-webfont.svg?v=4.2.0#fontawesomeregular") format("svg"); + font-weight: normal; + font-style: normal; +} + +.fa, +.wy-menu-vertical li span.toctree-expand, +.wy-menu-vertical li.on a span.toctree-expand, +.wy-menu-vertical li.current>a span.toctree-expand, +.rst-content h1 .headerlink, +.rst-content h2 .headerlink, +.rst-content h3 .headerlink, +.rst-content h4 .headerlink, +.rst-content h5 .headerlink, +.rst-content h6 .headerlink, +.rst-content dl dt .headerlink, +.rst-content p.caption .headerlink, +.rst-content tt.download span:first-child, +.rst-content code.download span:first-child, +.icon { + display: inline-block; + font: normal normal normal 14px/1 FontAwesome; + font-size: inherit; + text-rendering: auto; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +/* +.fa-lg{font-size:1.33333em; + line-height:0.75em; + vertical-align:-15%} + +.fa-2x{font-size:2em} + +.fa-3x{font-size:3em} + +.fa-4x{font-size:4em} + +.fa-5x{font-size:5em} + +.fa-fw{width:1.28571em; + text-align:center} + +.fa-ul{padding-left:0; + margin-left:2.14286em; + list-style-type:none} + +.fa-ul>li{position:relative} + +.fa-li{position:absolute; + left:-2.14286em; + width:2.14286em; + top:0.14286em; + text-align:center} + +.fa-li.fa-lg{left:-1.85714em} + +.fa-border{padding:.2em .25em .15em; + border:solid 0.08em #eee; + border-radius:.1em} + +.pull-right{float:right} + +.pull-left{float:left} +*/ + +/* +.rst-content .pull-left.admonition-title, +.rst-content h1 .pull-left.headerlink, +.rst-content h2 .pull-left.headerlink, +.rst-content p.caption .pull-left.headerlink, +.rst-content h3 .pull-left.headerlink, +.rst-content h4 .pull-left.headerlink, +.rst-content h5 .pull-left.headerlink, +.rst-content h6 .pull-left.headerlink, +.rst-content dl dt .pull-left.headerlink, +.rst-content tt.download span.pull-left:first-child, +.rst-content code.download span.pull-left:first-child, +*/ +.fa.pull-left, +.wy-menu-vertical li span.pull-left.toctree-expand, +.wy-menu-vertical li.on a span.pull-left.toctree-expand, +.wy-menu-vertical li.current>a span.pull-left.toctree-expand, +.pull-left.icon +{ margin-right:.3em; } + +/* +.rst-content .pull-right.admonition-title, +.rst-content h1 .pull-right.headerlink, +.rst-content h2 .pull-right.headerlink, +.rst-content p.caption .pull-right.headerlink, +.rst-content h3 .pull-right.headerlink, +.rst-content h4 .pull-right.headerlink, +.rst-content h5 .pull-right.headerlink, +.rst-content h6 .pull-right.headerlink, +.rst-content dl dt .pull-right.headerlink, +.rst-content tt.download span.pull-right:first-child, +.rst-content code.download span.pull-right:first-child, +*/ +.fa.pull-right, +.wy-menu-vertical li span.pull-right.toctree-expand, +.wy-menu-vertical li.on a span.pull-right.toctree-expand, +.wy-menu-vertical li.current>a span.pull-right.toctree-expand, +.pull-right.icon +{ margin-left:.3em; } + +/* +.fa-spin{-webkit-animation:fa-spin 2s infinite linear; + animation:fa-spin 2s infinite linear} + +@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg); + transform:rotate(0deg)} + +100%{-webkit-transform:rotate(359deg); + transform:rotate(359deg)} + +} + +@keyframes fa-spin{0%{-webkit-transform:rotate(0deg); + transform:rotate(0deg)} + +100%{-webkit-transform:rotate(359deg); + transform:rotate(359deg)} + +} + +.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1); + -webkit-transform:rotate(90deg); + -ms-transform:rotate(90deg); + transform:rotate(90deg)} + +.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2); + -webkit-transform:rotate(180deg); + -ms-transform:rotate(180deg); + transform:rotate(180deg)} + +.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3); + -webkit-transform:rotate(270deg); + -ms-transform:rotate(270deg); + transform:rotate(270deg)} + +.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0); + -webkit-transform:scale(-1, 1); + -ms-transform:scale(-1, 1); + transform:scale(-1, 1)} + +.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2); + -webkit-transform:scale(1, -1); + -ms-transform:scale(1, -1); + transform:scale(1, -1)} + +:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none} + +.fa-stack{position:relative; + display:inline-block; + width:2em; + height:2em; + line-height:2em; + vertical-align:middle} + +.fa-stack-1x,.fa-stack-2x{position:absolute; + left:0; + width:100%; + text-align:center} + +.fa-stack-1x{line-height:inherit} + +.fa-stack-2x{font-size:2em} + +.fa-inverse{color:#fff} +*/ + +.fa-glass:before{content:""} + +.fa-music:before{content:""} + +.fa-search:before,.icon-search:before{content:""} + +.fa-envelope-o:before{content:""} + +.fa-heart:before{content:""} + +.fa-star:before{content:""} + +.fa-star-o:before{content:""} + +.fa-user:before{content:""} + +.fa-film:before{content:""} + +.fa-th-large:before{content:""} + +.fa-th:before{content:""} + +.fa-th-list:before{content:""} + +.fa-check:before{content:""} + +.fa-remove:before,.fa-close:before,.fa-times:before{content:""} + +.fa-search-plus:before{content:""} + +.fa-search-minus:before{content:""} + +.fa-power-off:before{content:""} + +.fa-signal:before{content:""} + +.fa-gear:before,.fa-cog:before{content:""} + +.fa-trash-o:before{content:""} + +.fa-home:before,.icon-home:before { content: ""; } + +.fa-file-o:before{content:""} + +.fa-clock-o:before{content:""} + +.fa-road:before{content:""} + +.fa-download:before,.rst-content tt.download span:first-child:before,.rst-content code.download span:first-child:before{content:""} + +.fa-arrow-circle-o-down:before{content:""} + +.fa-arrow-circle-o-up:before{content:""} + +.fa-inbox:before{content:""} + +.fa-play-circle-o:before{content:""} + +.fa-rotate-right:before,.fa-repeat:before{content:""} + +.fa-refresh:before{content:""} + +.fa-list-alt:before{content:""} + +.fa-lock:before{content:""} + +.fa-flag:before{content:""} + +.fa-headphones:before{content:""} + +.fa-volume-off:before{content:""} + +.fa-volume-down:before{content:""} + +.fa-volume-up:before{content:""} + +.fa-qrcode:before{content:""} + +.fa-barcode:before{content:""} + +.fa-tag:before{content:""} + +.fa-tags:before{content:""} + +.fa-book:before,.icon-book:before{content:""} + +.fa-bookmark:before{content:""} + +.fa-print:before{content:""} + +.fa-camera:before{content:""} + +.fa-font:before{content:""} + +.fa-bold:before{content:""} + +.fa-italic:before{content:""} + +.fa-text-height:before{content:""} + +.fa-text-width:before{content:""} + +.fa-align-left:before{content:""} + +.fa-align-center:before{content:""} + +.fa-align-right:before{content:""} + +.fa-align-justify:before{content:""} + +.fa-list:before{content:""} + +.fa-dedent:before,.fa-outdent:before{content:""} + +.fa-indent:before{content:""} + +.fa-video-camera:before{content:""} + +.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:""} + +.fa-pencil:before{content:""} + +.fa-map-marker:before{content:""} + +.fa-adjust:before{content:""} + +.fa-tint:before{content:""} + +.fa-edit:before,.fa-pencil-square-o:before{content:""} + +.fa-share-square-o:before{content:""} + +.fa-check-square-o:before{content:""} + +.fa-arrows:before{content:""} + +.fa-step-backward:before{content:""} + +.fa-fast-backward:before{content:""} + +.fa-backward:before{content:""} + +.fa-play:before{content:""} + +.fa-pause:before{content:""} + +.fa-stop:before{content:""} + +.fa-forward:before{content:""} + +.fa-fast-forward:before{content:""} + +.fa-step-forward:before{content:""} + +.fa-eject:before{content:""} + +.fa-chevron-left:before{content:""} + +.fa-chevron-right:before{content:""} + +.fa-plus-circle:before{content:""} + +.fa-minus-circle:before{content:""} + +.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""} + +.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""} + +.fa-question-circle:before{content:""} + +.fa-info-circle:before{content:""} + +.fa-crosshairs:before{content:""} + +.fa-times-circle-o:before{content:""} + +.fa-check-circle-o:before{content:""} + +.fa-ban:before{content:""} + +.fa-arrow-left:before{content:""} + +.fa-arrow-right:before{content:""} + +.fa-arrow-up:before{content:""} + +.fa-arrow-down:before{content:""} + +.fa-mail-forward:before,.fa-share:before{content:""} + +.fa-expand:before{content:""} + +.fa-compress:before{content:""} + +.fa-plus:before{content:""} + +.fa-minus:before{content:""} + +.fa-asterisk:before{content:""} + +.fa-exclamation-circle:before, +.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before, +.wy-inline-validate.wy-inline-validate-info .wy-input-context:before +{content:""} + +.fa-gift:before{content:""} + +.fa-leaf:before{content:""} + +.fa-fire:before,.icon-fire:before{content:""} + +.fa-eye:before{content:""} + +.fa-eye-slash:before{content:""} + +.fa-warning:before,.fa-exclamation-triangle:before{content:""} + +.fa-plane:before{content:""} + +.fa-calendar:before{content:""} + +.fa-random:before{content:""} + +.fa-comment:before{content:""} + +.fa-magnet:before{content:""} + +.fa-chevron-up:before{content:""} + +.fa-chevron-down:before{content:""} + +.fa-retweet:before{content:""} + +.fa-shopping-cart:before{content:""} + +.fa-folder:before{content:""} + +.fa-folder-open:before{content:""} + +.fa-arrows-v:before{content:""} + +.fa-arrows-h:before{content:""} + +.fa-bar-chart-o:before,.fa-bar-chart:before{content:""} + +.fa-twitter-square:before{content:""} + +.fa-facebook-square:before{content:""} + +.fa-camera-retro:before{content:""} + +.fa-key:before{content:""} + +.fa-gears:before,.fa-cogs:before{content:""} + +.fa-comments:before{content:""} + +.fa-thumbs-o-up:before{content:""} + +.fa-thumbs-o-down:before{content:""} + +.fa-star-half:before{content:""} + +.fa-heart-o:before{content:""} + +.fa-sign-out:before{content:""} + +.fa-linkedin-square:before{content:""} + +.fa-thumb-tack:before{content:""} + +.fa-external-link:before{content:""} + +.fa-sign-in:before{content:""} + +.fa-trophy:before{content:""} + +.fa-github-square:before{content:""} + +.fa-upload:before{content:""} + +.fa-lemon-o:before{content:""} + +.fa-phone:before{content:""} + +.fa-square-o:before{content:""} + +.fa-bookmark-o:before{content:""} + +.fa-phone-square:before{content:""} + +.fa-twitter:before{content:""} + +.fa-facebook:before{content:""} + +.fa-github:before,.icon-github:before{content:""} + +.fa-unlock:before{content:""} + +.fa-credit-card:before{content:""} + +.fa-rss:before{content:""} + +.fa-hdd-o:before{content:""} + +.fa-bullhorn:before{content:""} + +.fa-bell:before{content:""} + +.fa-certificate:before{content:""} + +.fa-hand-o-right:before{content:""} + +.fa-hand-o-left:before{content:""} + +.fa-hand-o-up:before{content:""} + +.fa-hand-o-down:before{content:""} + +.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""} + +.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""} + +.fa-arrow-circle-up:before{content:""} + +.fa-arrow-circle-down:before{content:""} + +.fa-globe:before{content:""} + +.fa-wrench:before{content:""} + +.fa-tasks:before{content:""} + +.fa-filter:before{content:""} + +.fa-briefcase:before{content:""} + +.fa-arrows-alt:before{content:""} + +.fa-group:before,.fa-users:before{content:""} + +.fa-chain:before,.fa-link:before,.icon-link:before{content:""} + +.fa-cloud:before{content:""} + +.fa-flask:before{content:""} + +.fa-cut:before,.fa-scissors:before{content:""} + +.fa-copy:before,.fa-files-o:before{content:""} + +.fa-paperclip:before{content:""} + +.fa-save:before,.fa-floppy-o:before{content:""} + +.fa-square:before{content:""} + +.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:""} + +.fa-list-ul:before{content:""} + +.fa-list-ol:before{content:""} + +.fa-strikethrough:before{content:""} + +.fa-underline:before{content:""} + +.fa-table:before{content:""} + +.fa-magic:before{content:""} + +.fa-truck:before{content:""} + +.fa-pinterest:before{content:""} + +.fa-pinterest-square:before{content:""} + +.fa-google-plus-square:before{content:""} + +.fa-google-plus:before{content:""} + +.fa-money:before{content:""} + +.fa-caret-down:before,.wy-dropdown .caret:before,.icon-caret-down:before{content:""} + +.fa-caret-up:before{content:""} + +.fa-caret-left:before{content:""} + +.fa-caret-right:before{content:""} + +.fa-columns:before{content:""} + +.fa-unsorted:before,.fa-sort:before{content:""} + +.fa-sort-down:before,.fa-sort-desc:before{content:""} + +.fa-sort-up:before,.fa-sort-asc:before{content:""} + +.fa-envelope:before{content:""} + +.fa-linkedin:before{content:""} + +.fa-rotate-left:before,.fa-undo:before{content:""} + +.fa-legal:before,.fa-gavel:before{content:""} + +.fa-dashboard:before,.fa-tachometer:before{content:""} + +.fa-comment-o:before{content:""} + +.fa-comments-o:before{content:""} + +.fa-flash:before,.fa-bolt:before{content:""} + +.fa-sitemap:before{content:""} + +.fa-umbrella:before{content:""} + +.fa-paste:before,.fa-clipboard:before{content:""} + +.fa-lightbulb-o:before{content:""} + +.fa-exchange:before{content:""} + +.fa-cloud-download:before{content:""} + +.fa-cloud-upload:before{content:""} + +.fa-user-md:before{content:""} + +.fa-stethoscope:before{content:""} + +.fa-suitcase:before{content:""} + +.fa-bell-o:before{content:""} + +.fa-coffee:before{content:""} + +.fa-cutlery:before{content:""} + +.fa-file-text-o:before{content:""} + +.fa-building-o:before{content:""} + +.fa-hospital-o:before{content:""} + +.fa-ambulance:before{content:""} + +.fa-medkit:before{content:""} + +.fa-fighter-jet:before{content:""} + +.fa-beer:before{content:""} + +.fa-h-square:before{content:""} + +.fa-plus-square:before{content:""} + +.fa-angle-double-left:before{content:""} + +.fa-angle-double-right:before{content:""} + +.fa-angle-double-up:before{content:""} + +.fa-angle-double-down:before{content:""} + +.fa-angle-left:before{content:""} + +.fa-angle-right:before{content:""} + +.fa-angle-up:before{content:""} + +.fa-angle-down:before{content:""} + +.fa-desktop:before{content:""} + +.fa-laptop:before{content:""} + +.fa-tablet:before{content:""} + +.fa-mobile-phone:before,.fa-mobile:before{content:""} + +.fa-circle-o:before{content:""} + +.fa-quote-left:before{content:""} + +.fa-quote-right:before{content:""} + +.fa-spinner:before{content:""} + +.fa-circle:before{content:""} + +.fa-mail-reply:before,.fa-reply:before{content:""} + +.fa-github-alt:before{content:""} + +.fa-folder-o:before{content:""} + +.fa-folder-open-o:before{content:""} + +.fa-smile-o:before{content:""} + +.fa-frown-o:before{content:""} + +.fa-meh-o:before{content:""} + +.fa-gamepad:before{content:""} + +.fa-keyboard-o:before{content:""} + +.fa-flag-o:before{content:""} + +.fa-flag-checkered:before{content:""} + +.fa-terminal:before{content:""} + +.fa-code:before{content:""} + +.fa-mail-reply-all:before,.fa-reply-all:before{content:""} + +.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""} + +.fa-location-arrow:before{content:""} + +.fa-crop:before{content:""} + +.fa-code-fork:before{content:""} + +.fa-unlink:before,.fa-chain-broken:before{content:""} + +.fa-question:before{content:""} + +.fa-info:before{content:""} + +.fa-exclamation:before{content:""} + +.fa-superscript:before{content:""} + +.fa-subscript:before{content:""} + +.fa-eraser:before{content:""} + +.fa-puzzle-piece:before{content:""} + +.fa-microphone:before{content:""} + +.fa-microphone-slash:before{content:""} + +.fa-shield:before{content:""} + +.fa-calendar-o:before{content:""} + +.fa-fire-extinguisher:before{content:""} + +.fa-rocket:before{content:""} + +.fa-maxcdn:before{content:""} + +.fa-chevron-circle-left:before{content:""} + +.fa-chevron-circle-right:before{content:""} + +.fa-chevron-circle-up:before{content:""} + +.fa-chevron-circle-down:before{content:""} + +.fa-html5:before{content:""} + +.fa-css3:before{content:""} + +.fa-anchor:before{content:""} + +.fa-unlock-alt:before{content:""} + +.fa-bullseye:before{content:""} + +.fa-ellipsis-h:before{content:""} + +.fa-ellipsis-v:before{content:""} + +.fa-rss-square:before{content:""} + +.fa-play-circle:before{content:""} + +.fa-ticket:before{content:""} + +.fa-minus-square:before{content:""} + +.fa-minus-square-o:before, +.wy-menu-vertical li.on a span.toctree-expand:before, +.wy-menu-vertical li.current>a span.toctree-expand:before +{ content:""; } + +.fa-level-up:before{content:""} + +.fa-level-down:before{content:""} + +.fa-check-square:before{content:""} + +.fa-pencil-square:before{content:""} + +.fa-external-link-square:before{content:""} + +.fa-share-square:before{content:""} + +.fa-compass:before{content:""} + +.fa-toggle-down:before,.fa-caret-square-o-down:before{content:""} + +.fa-toggle-up:before,.fa-caret-square-o-up:before{content:""} + +.fa-toggle-right:before,.fa-caret-square-o-right:before{content:""} + +.fa-euro:before,.fa-eur:before{content:""} + +.fa-gbp:before{content:""} + +.fa-dollar:before,.fa-usd:before{content:""} + +.fa-rupee:before,.fa-inr:before{content:""} + +.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:""} + +.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:""} + +.fa-won:before,.fa-krw:before{content:""} + +.fa-bitcoin:before,.fa-btc:before{content:""} + +.fa-file:before{content:""} + +.fa-file-text:before{content:""} + +.fa-sort-alpha-asc:before{content:""} + +.fa-sort-alpha-desc:before{content:""} + +.fa-sort-amount-asc:before{content:""} + +.fa-sort-amount-desc:before{content:""} + +.fa-sort-numeric-asc:before{content:""} + +.fa-sort-numeric-desc:before{content:""} + +.fa-thumbs-up:before{content:""} + +.fa-thumbs-down:before{content:""} + +.fa-youtube-square:before{content:""} + +.fa-youtube:before{content:""} + +.fa-xing:before{content:""} + +.fa-xing-square:before{content:""} + +.fa-youtube-play:before{content:""} + +.fa-dropbox:before{content:""} + +.fa-stack-overflow:before{content:""} + +.fa-instagram:before{content:""} + +.fa-flickr:before{content:""} + +.fa-adn:before{content:""} + +.fa-bitbucket:before,.icon-bitbucket:before{content:""} + +.fa-bitbucket-square:before{content:""} + +.fa-tumblr:before{content:""} + +.fa-tumblr-square:before{content:""} + +.fa-long-arrow-down:before{content:""} + +.fa-long-arrow-up:before{content:""} + +.fa-long-arrow-left:before{content:""} + +.fa-long-arrow-right:before{content:""} + +.fa-apple:before{content:""} + +.fa-windows:before{content:""} + +.fa-android:before{content:""} + +.fa-linux:before{content:""} + +.fa-dribbble:before{content:""} + +.fa-skype:before{content:""} + +.fa-foursquare:before{content:""} + +.fa-trello:before{content:""} + +.fa-female:before{content:""} + +.fa-male:before{content:""} + +.fa-gittip:before{content:""} + +.fa-sun-o:before{content:""} + +.fa-moon-o:before{content:""} + +.fa-archive:before{content:""} + +.fa-bug:before{content:""} + +.fa-vk:before{content:""} + +.fa-weibo:before{content:""} + +.fa-renren:before{content:""} + +.fa-pagelines:before{content:""} + +.fa-stack-exchange:before{content:""} + +.fa-arrow-circle-o-right:before{content:""} + +.fa-arrow-circle-o-left:before{content:""} + +.fa-toggle-left:before,.fa-caret-square-o-left:before{content:""} + +.fa-dot-circle-o:before{content:""} + +.fa-wheelchair:before{content:""} + +.fa-vimeo-square:before{content:""} + +.fa-turkish-lira:before,.fa-try:before{content:""} + +.fa-plus-square-o:before, +.wy-menu-vertical li span.toctree-expand:before +{ content:""; } + +.fa-space-shuttle:before{content:""} + +.fa-slack:before{content:""} + +.fa-envelope-square:before{content:""} + +.fa-wordpress:before{content:""} + +.fa-openid:before{content:""} + +.fa-institution:before,.fa-bank:before,.fa-university:before{content:""} + +.fa-mortar-board:before,.fa-graduation-cap:before{content:""} + +.fa-yahoo:before{content:""} + +.fa-google:before{content:""} + +.fa-reddit:before{content:""} + +.fa-reddit-square:before{content:""} + +.fa-stumbleupon-circle:before{content:""} + +.fa-stumbleupon:before{content:""} + +.fa-delicious:before{content:""} + +.fa-digg:before{content:""} + +.fa-pied-piper:before{content:""} + +.fa-pied-piper-alt:before{content:""} + +.fa-drupal:before{content:""} + +.fa-joomla:before{content:""} + +.fa-language:before{content:""} + +.fa-fax:before{content:""} + +.fa-building:before{content:""} + +.fa-child:before{content:""} + +.fa-paw:before{content:""} + +.fa-spoon:before{content:""} + +.fa-cube:before{content:""} + +.fa-cubes:before{content:""} + +.fa-behance:before{content:""} + +.fa-behance-square:before{content:""} + +.fa-steam:before{content:""} + +.fa-steam-square:before{content:""} + +.fa-recycle:before{content:""} + +.fa-automobile:before,.fa-car:before{content:""} + +.fa-cab:before,.fa-taxi:before{content:""} + +.fa-tree:before{content:""} + +.fa-spotify:before{content:""} + +.fa-deviantart:before{content:""} + +.fa-soundcloud:before{content:""} + +.fa-database:before{content:""} + +.fa-file-pdf-o:before{content:""} + +.fa-file-word-o:before{content:""} + +.fa-file-excel-o:before{content:""} + +.fa-file-powerpoint-o:before{content:""} + +.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:""} + +.fa-file-zip-o:before,.fa-file-archive-o:before{content:""} + +.fa-file-sound-o:before,.fa-file-audio-o:before{content:""} + +.fa-file-movie-o:before,.fa-file-video-o:before{content:""} + +.fa-file-code-o:before{content:""} + +.fa-vine:before{content:""} + +.fa-codepen:before{content:""} + +.fa-jsfiddle:before{content:""} + +.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:""} + +.fa-circle-o-notch:before{content:""} + +.fa-ra:before,.fa-rebel:before{content:""} + +.fa-ge:before,.fa-empire:before{content:""} + +.fa-git-square:before{content:""} + +.fa-git:before{content:""} + +.fa-hacker-news:before{content:""} + +.fa-tencent-weibo:before{content:""} + +.fa-qq:before{content:""} + +.fa-wechat:before,.fa-weixin:before{content:""} + +.fa-send:before,.fa-paper-plane:before{content:""} + +.fa-send-o:before,.fa-paper-plane-o:before{content:""} + +.fa-history:before{content:""} + +.fa-circle-thin:before{content:""} + +.fa-header:before{content:""} + +.fa-paragraph:before{content:""} + +.fa-sliders:before{content:""} + +.fa-share-alt:before{content:""} + +.fa-share-alt-square:before{content:""} + +.fa-bomb:before{content:""} + +.fa-soccer-ball-o:before,.fa-futbol-o:before{content:""} + +.fa-tty:before{content:""} + +.fa-binoculars:before{content:""} + +.fa-plug:before{content:""} + +.fa-slideshare:before{content:""} + +.fa-twitch:before{content:""} + +.fa-yelp:before{content:""} + +.fa-newspaper-o:before{content:""} + +.fa-wifi:before{content:""} + +.fa-calculator:before{content:""} + +.fa-paypal:before{content:""} + +.fa-google-wallet:before{content:""} + +.fa-cc-visa:before{content:""} + +.fa-cc-mastercard:before{content:""} + +.fa-cc-discover:before{content:""} + +.fa-cc-amex:before{content:""} + +.fa-cc-paypal:before{content:""} + +.fa-cc-stripe:before{content:""} + +.fa-bell-slash:before{content:""} + +.fa-bell-slash-o:before{content:""} + +.fa-trash:before{content:""} + +.fa-copyright:before{content:""} + +.fa-at:before{content:""} + +.fa-eyedropper:before{content:""} + +.fa-paint-brush:before{content:""} + +.fa-birthday-cake:before{content:""} + +.fa-area-chart:before{content:""} + +.fa-pie-chart:before{content:""} + +.fa-line-chart:before{content:""} + +.fa-lastfm:before{content:""} + +.fa-lastfm-square:before{content:""} + +.fa-toggle-off:before{content:""} + +.fa-toggle-on:before{content:""} + +.fa-bicycle:before{content:""} + +.fa-bus:before{content:""} + +.fa-ioxhost:before{content:""} + +.fa-angellist:before{content:""} + +.fa-cc:before{content:""} + +.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:""} + +.fa-meanpath:before{content:""} + +/* +.rst-content h1 .headerlink, +.rst-content h2 .headerlink, +.rst-content p.caption .headerlink, +.rst-content h3 .headerlink, +.rst-content h4 .headerlink, +.rst-content h5 .headerlink, +.rst-content h6 .headerlink, +.rst-content dl dt .headerlink, +.rst-content tt.download span:first-child, +.rst-content code.download span:first-child, +*/ +.fa, +.wy-menu-vertical li span.toctree-expand, +.wy-menu-vertical li.on a span.toctree-expand, +.wy-menu-vertical li.current>a span.toctree-expand, +.icon, +.wy-dropdown .caret, +.wy-inline-validate.wy-inline-validate-success .wy-input-context, +.wy-inline-validate.wy-inline-validate-danger .wy-input-context, +.wy-inline-validate.wy-inline-validate-warning .wy-input-context, +.wy-inline-validate.wy-inline-validate-info .wy-input-context +{ font-family: inherit; } + +/* +.rst-content h1 .headerlink:before, +.rst-content h2 .headerlink:before, +.rst-content p.caption .headerlink:before, +.rst-content h3 .headerlink:before, +.rst-content h4 .headerlink:before, +.rst-content h5 .headerlink:before, +.rst-content h6 .headerlink:before, +.rst-content dl dt .headerlink:before, +.rst-content tt.download span:first-child:before, +.rst-content code.download span:first-child:before, +*/ +.fa:before, +.wy-menu-vertical li span.toctree-expand:before, +.wy-menu-vertical li.on a span.toctree-expand:before, +.wy-menu-vertical li.current>a span.toctree-expand:before, +.icon:before, +.wy-dropdown .caret:before, +.wy-inline-validate.wy-inline-validate-success .wy-input-context:before, +.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before, +.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before, +.wy-inline-validate.wy-inline-validate-info .wy-input-context:before +{ + font-family: "FontAwesome"; + display: inline-block; + font-style: normal; + font-weight: normal; + line-height: 1; + text-decoration: inherit +} + +/* +a .rst-content h1 .headerlink, +.rst-content h1 a .headerlink, +a .rst-content h2 .headerlink, +.rst-content h2 a .headerlink, +a .rst-content p.caption .headerlink, +.rst-content p.caption a .headerlink, +a .rst-content h3 .headerlink, +.rst-content h3 a .headerlink, +a .rst-content h4 .headerlink, +.rst-content h4 a .headerlink, +a .rst-content h5 .headerlink, +.rst-content h5 a .headerlink, +a .rst-content h6 .headerlink, +.rst-content h6 a .headerlink, +a .rst-content dl dt .headerlink, +.rst-content dl dt a .headerlink, +a .rst-content tt.download span:first-child, +.rst-content tt.download a span:first-child, +a .rst-content code.download span:first-child, +.rst-content code.download a span:first-child, +*/ +a .fa, +a .wy-menu-vertical li span.toctree-expand, +.wy-menu-vertical li a span.toctree-expand, +.wy-menu-vertical li.on a span.toctree-expand, +.wy-menu-vertical li.current>a span.toctree-expand, +a .icon +{ + display: inline-block; + text-decoration: inherit; +} + +.btn .fa, +.btn .wy-menu-vertical li span.toctree-expand, +.wy-menu-vertical li .btn span.toctree-expand, +.btn .wy-menu-vertical li.on a span.toctree-expand, +.wy-menu-vertical li.on a .btn span.toctree-expand, +.btn .wy-menu-vertical li.current>a span.toctree-expand, +.wy-menu-vertical li.current>a .btn span.toctree-expand, +.btn .rst-content .admonition-title, +.rst-content .btn .admonition-title, +.btn .rst-content h1 .headerlink, +.rst-content h1 .btn .headerlink, +.btn .rst-content h2 .headerlink, +.rst-content h2 .btn .headerlink, +.btn .rst-content p.caption .headerlink, +.rst-content p.caption .btn .headerlink, +.btn .rst-content h3 .headerlink, +.rst-content h3 .btn .headerlink, +.btn .rst-content h4 .headerlink, +.rst-content h4 .btn .headerlink, +.btn .rst-content h5 .headerlink, +.rst-content h5 .btn .headerlink, +.btn .rst-content h6 .headerlink, +.rst-content h6 .btn .headerlink, +.btn .rst-content dl dt .headerlink, +.rst-content dl dt .btn .headerlink, +.btn .rst-content tt.download span:first-child, +.rst-content tt.download .btn span:first-child, +.btn .rst-content code.download span:first-child, +.rst-content code.download .btn span:first-child, +.btn .icon, +.nav .fa, +.nav .wy-menu-vertical li span.toctree-expand, +.wy-menu-vertical li .nav span.toctree-expand, +.nav .wy-menu-vertical li.on a span.toctree-expand, +.wy-menu-vertical li.on a .nav span.toctree-expand, +.nav .wy-menu-vertical li.current>a span.toctree-expand, +.wy-menu-vertical li.current>a .nav span.toctree-expand, +.nav .rst-content .admonition-title, +.rst-content .nav .admonition-title, +.nav .rst-content h1 .headerlink, +.rst-content h1 .nav .headerlink, +.nav .rst-content h2 .headerlink, +.rst-content h2 .nav .headerlink, +.nav .rst-content p.caption .headerlink, +.rst-content p.caption .nav .headerlink, +.nav .rst-content h3 .headerlink, +.rst-content h3 .nav .headerlink, +.nav .rst-content h4 .headerlink, +.rst-content h4 .nav .headerlink, +.nav .rst-content h5 .headerlink, +.rst-content h5 .nav .headerlink, +.nav .rst-content h6 .headerlink, +.rst-content h6 .nav .headerlink, +.nav .rst-content dl dt .headerlink, +.rst-content dl dt .nav .headerlink, +.nav .rst-content tt.download span:first-child, +.rst-content tt.download .nav span:first-child, +.nav .rst-content code.download span:first-child, +.rst-content code.download .nav span:first-child, +.nav .icon +{ display: inline; } + +.btn .fa.fa-large, +.btn .wy-menu-vertical li span.fa-large.toctree-expand, +.wy-menu-vertical li .btn span.fa-large.toctree-expand, +.btn .rst-content .fa-large.admonition-title, +.rst-content .btn .fa-large.admonition-title, +.btn .rst-content h1 .fa-large.headerlink, +.rst-content h1 .btn .fa-large.headerlink, +.btn .rst-content h2 .fa-large.headerlink, +.rst-content h2 .btn .fa-large.headerlink, +.btn .rst-content p.caption .fa-large.headerlink, +.rst-content p.caption .btn .fa-large.headerlink, +.btn .rst-content h3 .fa-large.headerlink, +.rst-content h3 .btn .fa-large.headerlink, +.btn .rst-content h4 .fa-large.headerlink, +.rst-content h4 .btn .fa-large.headerlink, +.btn .rst-content h5 .fa-large.headerlink, +.rst-content h5 .btn .fa-large.headerlink, +.btn .rst-content h6 .fa-large.headerlink, +.rst-content h6 .btn .fa-large.headerlink, +.btn .rst-content dl dt .fa-large.headerlink, +.rst-content dl dt .btn .fa-large.headerlink, +.btn .rst-content tt.download span.fa-large:first-child, +.rst-content tt.download .btn span.fa-large:first-child, +.btn .rst-content code.download span.fa-large:first-child, +.rst-content code.download .btn span.fa-large:first-child, +.btn .fa-large.icon, +.nav .fa.fa-large, +.nav .wy-menu-vertical li span.fa-large.toctree-expand, +.wy-menu-vertical li .nav span.fa-large.toctree-expand, +.nav .rst-content .fa-large.admonition-title, +.rst-content .nav .fa-large.admonition-title, +.nav .rst-content h1 .fa-large.headerlink, +.rst-content h1 .nav .fa-large.headerlink, +.nav .rst-content h2 .fa-large.headerlink, +.rst-content h2 .nav .fa-large.headerlink, +.nav .rst-content p.caption .fa-large.headerlink, +.rst-content p.caption .nav .fa-large.headerlink, +.nav .rst-content h3 .fa-large.headerlink, +.rst-content h3 .nav .fa-large.headerlink, +.nav .rst-content h4 .fa-large.headerlink, +.rst-content h4 .nav .fa-large.headerlink, +.nav .rst-content h5 .fa-large.headerlink, +.rst-content h5 .nav .fa-large.headerlink, +.nav .rst-content h6 .fa-large.headerlink, +.rst-content h6 .nav .fa-large.headerlink, +.nav .rst-content dl dt .fa-large.headerlink, +.rst-content dl dt .nav .fa-large.headerlink, +.nav .rst-content tt.download span.fa-large:first-child, +.rst-content tt.download .nav span.fa-large:first-child, +.nav .rst-content code.download span.fa-large:first-child, +.rst-content code.download .nav span.fa-large:first-child, +.nav .fa-large.icon +{ line-height: 0.9em; } + +.btn .fa.fa-spin, +.btn .wy-menu-vertical li span.fa-spin.toctree-expand, +.wy-menu-vertical li .btn span.fa-spin.toctree-expand, +.btn .rst-content .fa-spin.admonition-title, +.rst-content .btn .fa-spin.admonition-title, +.btn .rst-content h1 .fa-spin.headerlink, +.rst-content h1 .btn .fa-spin.headerlink, +.btn .rst-content h2 .fa-spin.headerlink, +.rst-content h2 .btn .fa-spin.headerlink, +.btn .rst-content p.caption .fa-spin.headerlink, +.rst-content p.caption .btn .fa-spin.headerlink, +.btn .rst-content h3 .fa-spin.headerlink, +.rst-content h3 .btn .fa-spin.headerlink, +.btn .rst-content h4 .fa-spin.headerlink, +.rst-content h4 .btn .fa-spin.headerlink, +.btn .rst-content h5 .fa-spin.headerlink, +.rst-content h5 .btn .fa-spin.headerlink, +.btn .rst-content h6 .fa-spin.headerlink, +.rst-content h6 .btn .fa-spin.headerlink, +.btn .rst-content dl dt .fa-spin.headerlink, +.rst-content dl dt .btn .fa-spin.headerlink, +.btn .rst-content tt.download span.fa-spin:first-child, +.rst-content tt.download .btn span.fa-spin:first-child, +.btn .rst-content code.download span.fa-spin:first-child, +.rst-content code.download .btn span.fa-spin:first-child, +.btn .fa-spin.icon, +.nav .fa.fa-spin, +.nav .wy-menu-vertical li span.fa-spin.toctree-expand, +.wy-menu-vertical li .nav span.fa-spin.toctree-expand, +.nav .rst-content .fa-spin.admonition-title, +.rst-content .nav .fa-spin.admonition-title, +.nav .rst-content h1 .fa-spin.headerlink, +.rst-content h1 .nav .fa-spin.headerlink, +.nav .rst-content h2 .fa-spin.headerlink, +.rst-content h2 .nav .fa-spin.headerlink, +.nav .rst-content p.caption .fa-spin.headerlink, +.rst-content p.caption .nav .fa-spin.headerlink, +.nav .rst-content h3 .fa-spin.headerlink, +.rst-content h3 .nav .fa-spin.headerlink, +.nav .rst-content h4 .fa-spin.headerlink, +.rst-content h4 .nav .fa-spin.headerlink, +.nav .rst-content h5 .fa-spin.headerlink, +.rst-content h5 .nav .fa-spin.headerlink, +.nav .rst-content h6 .fa-spin.headerlink, +.rst-content h6 .nav .fa-spin.headerlink, +.nav .rst-content dl dt .fa-spin.headerlink, +.rst-content dl dt .nav .fa-spin.headerlink, +.nav .rst-content tt.download span.fa-spin:first-child, +.rst-content tt.download .nav span.fa-spin:first-child, +.nav .rst-content code.download span.fa-spin:first-child, +.rst-content code.download .nav span.fa-spin:first-child, +.nav .fa-spin.icon +{ display: inline-block; } + +.btn.fa:before, +.wy-menu-vertical li span.btn.toctree-expand:before, +.rst-content .btn.admonition-title:before, +.rst-content h1 .btn.headerlink:before, +.rst-content h2 .btn.headerlink:before, +.rst-content p.caption .btn.headerlink:before, +.rst-content h3 .btn.headerlink:before, +.rst-content h4 .btn.headerlink:before, +.rst-content h5 .btn.headerlink:before, +.rst-content h6 .btn.headerlink:before, +.rst-content dl dt .btn.headerlink:before, +.rst-content tt.download span.btn:first-child:before, +.rst-content code.download span.btn:first-child:before, +.btn.icon:before +{ + opacity: 0.5; + -webkit-transition: opacity 0.05s ease-in; + -moz-transition: opacity 0.05s ease-in; + transition: opacity 0.05s ease-in; +} + +.btn.fa:hover:before, +.wy-menu-vertical li span.btn.toctree-expand:hover:before, +.rst-content .btn.admonition-title:hover:before, +.rst-content h1 .btn.headerlink:hover:before, +.rst-content h2 .btn.headerlink:hover:before, +.rst-content p.caption .btn.headerlink:hover:before, +.rst-content h3 .btn.headerlink:hover:before, +.rst-content h4 .btn.headerlink:hover:before, +.rst-content h5 .btn.headerlink:hover:before, +.rst-content h6 .btn.headerlink:hover:before, +.rst-content dl dt .btn.headerlink:hover:before, +.rst-content tt.download span.btn:first-child:hover:before, +.rst-content code.download span.btn:first-child:hover:before, +.btn.icon:hover:before +{ opacity: 1; } + +.btn-mini .fa:before, +.btn-mini .wy-menu-vertical li span.toctree-expand:before, +.wy-menu-vertical li .btn-mini span.toctree-expand:before, +.btn-mini .rst-content .admonition-title:before, +.rst-content .btn-mini .admonition-title:before, +.btn-mini .rst-content h1 .headerlink:before, +.rst-content h1 .btn-mini .headerlink:before, +.btn-mini .rst-content h2 .headerlink:before, +.rst-content h2 .btn-mini .headerlink:before, +.btn-mini .rst-content p.caption .headerlink:before, +.rst-content p.caption .btn-mini .headerlink:before, +.btn-mini .rst-content h3 .headerlink:before, +.rst-content h3 .btn-mini .headerlink:before, +.btn-mini .rst-content h4 .headerlink:before, +.rst-content h4 .btn-mini .headerlink:before, +.btn-mini .rst-content h5 .headerlink:before, +.rst-content h5 .btn-mini .headerlink:before, +.btn-mini .rst-content h6 .headerlink:before, +.rst-content h6 .btn-mini .headerlink:before, +.btn-mini .rst-content dl dt .headerlink:before, +.rst-content dl dt .btn-mini .headerlink:before, +.btn-mini .rst-content tt.download span:first-child:before, +.rst-content tt.download .btn-mini span:first-child:before, +.btn-mini .rst-content code.download span:first-child:before, +.rst-content code.download .btn-mini span:first-child:before, +.btn-mini .icon:before +{ + font-size: 14px; + vertical-align: -15%; +} + +/* +.wy-alert{padding:12px; + line-height:24px; + margin-bottom:24px; + background:#e7f2fa} + +.wy-alert-title{color:#fff; + font-weight:bold; + display:block; + color:#fff; + background:#6ab0de; + margin:-12px; + padding:6px 12px; + margin-bottom:12px} + +.wy-alert.wy-alert-danger, +.rst-content .wy-alert-danger.note, +.rst-content .wy-alert-danger.attention, +.rst-content .wy-alert-danger.caution, +.rst-content .wy-alert-danger.hint, +.rst-content .wy-alert-danger.important, +.rst-content .wy-alert-danger.tip, +.rst-content .wy-alert-danger.warning, +.rst-content .wy-alert-danger.seealso, +.rst-content .wy-alert-danger.admonition-todo{background:#fdf3f2} + +.wy-alert.wy-alert-danger .wy-alert-title, +.rst-content .wy-alert-danger.note .wy-alert-title, +.rst-content .wy-alert-danger.attention .wy-alert-title, +.rst-content .wy-alert-danger.caution .wy-alert-title, +.rst-content .danger .wy-alert-title, +.rst-content .error .wy-alert-title, +.rst-content .wy-alert-danger.hint .wy-alert-title, +.rst-content .wy-alert-danger.important .wy-alert-title, +.rst-content .wy-alert-danger.tip .wy-alert-title, +.rst-content .wy-alert-danger.warning .wy-alert-title, +.rst-content .wy-alert-danger.seealso .wy-alert-title, +.rst-content .wy-alert-danger.admonition-todo .wy-alert-title, +.wy-alert.wy-alert-danger .rst-content .admonition-title, +.rst-content .wy-alert.wy-alert-danger .admonition-title, +.rst-content .wy-alert-danger.note .admonition-title, +.rst-content .wy-alert-danger.attention .admonition-title, +.rst-content .wy-alert-danger.caution .admonition-title, +.rst-content .wy-alert-danger.hint .admonition-title, +.rst-content .wy-alert-danger.important .admonition-title, +.rst-content .wy-alert-danger.tip .admonition-title, +.rst-content .wy-alert-danger.warning .admonition-title, +.rst-content .wy-alert-danger.seealso .admonition-title, +.rst-content .wy-alert-danger.admonition-todo .admonition-title{background:#f29f97} + +.wy-alert.wy-alert-warning, +.rst-content .wy-alert-warning.note, +.rst-content .wy-alert-warning.danger, +.rst-content .wy-alert-warning.error, +.rst-content .wy-alert-warning.hint, +.rst-content .wy-alert-warning.important, +.rst-content .wy-alert-warning.tip, +.rst-content .wy-alert-warning.seealso +{background:#ffedcc} + +.wy-alert.wy-alert-warning .wy-alert-title, +.rst-content .wy-alert-warning.note .wy-alert-title, +.rst-content .attention .wy-alert-title, +.rst-content .caution .wy-alert-title, +.rst-content .wy-alert-warning.danger .wy-alert-title, +.rst-content .wy-alert-warning.error .wy-alert-title, +.rst-content .wy-alert-warning.hint .wy-alert-title, +.rst-content .wy-alert-warning.important .wy-alert-title, +.rst-content .wy-alert-warning.tip .wy-alert-title, +.rst-content .warning .wy-alert-title, +.rst-content .wy-alert-warning.seealso .wy-alert-title, +.rst-content .admonition-todo .wy-alert-title, +.wy-alert.wy-alert-warning .rst-content .admonition-title, +.rst-content .wy-alert.wy-alert-warning .admonition-title, +.rst-content .wy-alert-warning.note .admonition-title, +.rst-content .wy-alert-warning.danger .admonition-title, +.rst-content .wy-alert-warning.error .admonition-title, +.rst-content .wy-alert-warning.hint .admonition-title, +.rst-content .wy-alert-warning.important .admonition-title, +.rst-content .wy-alert-warning.tip .admonition-title, +.rst-content .wy-alert-warning.seealso .admonition-title +{background:#f0b37e} + +.wy-alert.wy-alert-info, +.rst-content .wy-alert-info.attention, +.rst-content .wy-alert-info.caution, +.rst-content .wy-alert-info.danger, +.rst-content .wy-alert-info.error, +.rst-content .wy-alert-info.hint, +.rst-content .wy-alert-info.important, +.rst-content .wy-alert-info.tip, +.rst-content .wy-alert-info.warning, +.rst-content .wy-alert-info.admonition-todo{background:#e7f2fa} + +.wy-alert.wy-alert-info .wy-alert-title, +.rst-content .note .wy-alert-title, +.rst-content .wy-alert-info.attention .wy-alert-title, +.rst-content .wy-alert-info.caution .wy-alert-title, +.rst-content .wy-alert-info.danger .wy-alert-title, +.rst-content .wy-alert-info.error .wy-alert-title, +.rst-content .wy-alert-info.hint .wy-alert-title, +.rst-content .wy-alert-info.important .wy-alert-title, +.rst-content .wy-alert-info.tip .wy-alert-title, +.rst-content .wy-alert-info.warning .wy-alert-title, +.rst-content .seealso .wy-alert-title, +.rst-content .wy-alert-info.admonition-todo .wy-alert-title, +.wy-alert.wy-alert-info .rst-content .admonition-title, +.rst-content .wy-alert.wy-alert-info .admonition-title, +.rst-content .wy-alert-info.attention .admonition-title, +.rst-content .wy-alert-info.caution .admonition-title, +.rst-content .wy-alert-info.danger .admonition-title, +.rst-content .wy-alert-info.error .admonition-title, +.rst-content .wy-alert-info.hint .admonition-title, +.rst-content .wy-alert-info.important .admonition-title, +.rst-content .wy-alert-info.tip .admonition-title, +.rst-content .wy-alert-info.warning .admonition-title, +.rst-content .wy-alert-info.admonition-todo .admonition-title{background:#6ab0de} + +.wy-alert.wy-alert-success, +.rst-content .wy-alert-success.note, +.rst-content .wy-alert-success.attention, +.rst-content .wy-alert-success.caution, +.rst-content .wy-alert-success.danger, +.rst-content .wy-alert-success.error, +.rst-content .wy-alert-success.warning, +.rst-content .wy-alert-success.seealso, +.rst-content .wy-alert-success.admonition-todo{background:#dbfaf4} + +.wy-alert.wy-alert-success .wy-alert-title, +.rst-content .wy-alert-success.note .wy-alert-title, +.rst-content .wy-alert-success.attention .wy-alert-title, +.rst-content .wy-alert-success.caution .wy-alert-title, +.rst-content .wy-alert-success.danger .wy-alert-title, +.rst-content .wy-alert-success.error .wy-alert-title, +.rst-content .hint .wy-alert-title, +.rst-content .important .wy-alert-title, +.rst-content .tip .wy-alert-title, +.rst-content .wy-alert-success.warning .wy-alert-title, +.rst-content .wy-alert-success.seealso .wy-alert-title, +.rst-content .wy-alert-success.admonition-todo .wy-alert-title, +.wy-alert.wy-alert-success .rst-content .admonition-title, +.rst-content .wy-alert.wy-alert-success .admonition-title, +.rst-content .wy-alert-success.note .admonition-title, +.rst-content .wy-alert-success.attention .admonition-title, +.rst-content .wy-alert-success.caution .admonition-title, +.rst-content .wy-alert-success.danger .admonition-title, +.rst-content .wy-alert-success.error .admonition-title, +.rst-content .wy-alert-success.warning .admonition-title, +.rst-content .wy-alert-success.seealso .admonition-title, +.rst-content .wy-alert-success.admonition-todo .admonition-title{background:#1abc9c} + +.wy-alert.wy-alert-neutral, +.rst-content .wy-alert-neutral.note, +.rst-content .wy-alert-neutral.attention, +.rst-content .wy-alert-neutral.caution, +.rst-content .wy-alert-neutral.danger, +.rst-content .wy-alert-neutral.error, +.rst-content .wy-alert-neutral.hint, +.rst-content .wy-alert-neutral.important, +.rst-content .wy-alert-neutral.tip, +.rst-content .wy-alert-neutral.warning, +.rst-content .wy-alert-neutral.seealso, +.rst-content .wy-alert-neutral.admonition-todo{background:#f3f6f6} + +.wy-alert.wy-alert-neutral .wy-alert-title, +.rst-content .wy-alert-neutral.note .wy-alert-title, +.rst-content .wy-alert-neutral.attention .wy-alert-title, +.rst-content .wy-alert-neutral.caution .wy-alert-title, +.rst-content .wy-alert-neutral.danger .wy-alert-title, +.rst-content .wy-alert-neutral.error .wy-alert-title, +.rst-content .wy-alert-neutral.hint .wy-alert-title, +.rst-content .wy-alert-neutral.important .wy-alert-title, +.rst-content .wy-alert-neutral.tip .wy-alert-title, +.rst-content .wy-alert-neutral.warning .wy-alert-title, +.rst-content .wy-alert-neutral.seealso .wy-alert-title, +.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title, +.wy-alert.wy-alert-neutral .rst-content .admonition-title, +.rst-content .wy-alert.wy-alert-neutral .admonition-title, +.rst-content .wy-alert-neutral.note .admonition-title, +.rst-content .wy-alert-neutral.attention .admonition-title, +.rst-content .wy-alert-neutral.caution .admonition-title, +.rst-content .wy-alert-neutral.danger .admonition-title, +.rst-content .wy-alert-neutral.error .admonition-title, +.rst-content .wy-alert-neutral.hint .admonition-title, +.rst-content .wy-alert-neutral.important .admonition-title, +.rst-content .wy-alert-neutral.tip .admonition-title, +.rst-content .wy-alert-neutral.warning .admonition-title, +.rst-content .wy-alert-neutral.seealso .admonition-title, +.rst-content .wy-alert-neutral.admonition-todo .admonition-title{color:#404040; + background:#e1e4e5} + +.wy-alert.wy-alert-neutral a, +.rst-content .wy-alert-neutral.note a, +.rst-content .wy-alert-neutral.attention a, +.rst-content .wy-alert-neutral.caution a, +.rst-content .wy-alert-neutral.danger a, +.rst-content .wy-alert-neutral.error a, +.rst-content .wy-alert-neutral.hint a, +.rst-content .wy-alert-neutral.important a, +.rst-content .wy-alert-neutral.tip a, +.rst-content .wy-alert-neutral.warning a, +.rst-content .wy-alert-neutral.seealso a, +.rst-content .wy-alert-neutral.admonition-todo a{color:#2980B9} + +.wy-alert p:last-child{margin-bottom:0} + +.wy-tray-container{position:fixed; + bottom:0px; + left:0; + z-index:600} + +.wy-tray-container li{display:block; + width:300px; + background:transparent; + color:#fff; + text-align:center; + box-shadow:0 5px 5px 0 rgba(0,0,0,0.1); + padding:0 24px; + min-width:20%; + opacity:0; + height:0; + line-height:56px; + overflow:hidden; + -webkit-transition:all 0.3s ease-in; + -moz-transition:all 0.3s ease-in; + transition:all 0.3s ease-in} + +.wy-tray-container li.wy-tray-item-success{background:#27AE60} + +.wy-tray-container li.wy-tray-item-info{background:#2980B9} + +.wy-tray-container li.wy-tray-item-warning{background:#E67E22} + +.wy-tray-container li.wy-tray-item-danger{background:#E74C3C} + +.wy-tray-container li.on{opacity:1; + height:56px} + +@media screen and (max-width: 768px){.wy-tray-container{bottom:auto; + top:0; + width:100%} + +.wy-tray-container li{width:100%} + +} + +button{font-size:100%; + margin:0; + vertical-align:baseline; + *vertical-align:middle; + cursor:pointer; + line-height:normal; + -webkit-appearance:button; + *overflow:visible} + +button::-moz-focus-inner,input::-moz-focus-inner{border:0; + padding:0} + +button[disabled]{cursor:default} +*/ + +a.btn, a.btn:link { + display: inline-block; + text-align: center; + cursor: pointer; + font-size: 110%; + font-weight: bold; + padding: 4pt; + margin-top: 10pt; + border: 2px solid black; + border-bottom: 2px solid black; +} + +a.btn:hover { + color: white; + background: black; +} + +/* +.btn { + display: inline-block; + border-radius: 2px; + line-height: normal; + white-space: nowrap; + text-align: center; + cursor: pointer; + font-size: 100%; + padding: 6px 12px 8px 12px; + color: #fff; + border: 1px solid rgba(0,0,0,0.1); + background-color: #27AE60; + text-decoration: none; + font-weight: normal; + font-family: "Lato","proxima-nova","Helvetica Neue",Arial,sans-serif; + box-shadow: 0px 1px 2px -1px rgba(255,255,255,0.5) inset,0px -2px 0px 0px rgba(0,0,0,0.1) inset; + outline-none: false; + vertical-align: middle; + *display: inline; + zoom: 1; + -webkit-user-drag: none; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + -webkit-transition: all 0.1s linear; + -moz-transition: all 0.1s linear; + transition: all 0.1s linear; +} + +.btn-hover { background: #2e8ece; color: #fff; } +.btn:hover { background: #2cc36b; color: #fff; } +.btn:focus { background: #2cc36b; outline: 0; } + +.btn:active { + box-shadow: 0px -1px 0px 0px rgba(0,0,0,0.05) inset,0px 2px 0px 0px rgba(0,0,0,0.1) inset; + padding: 8px 12px 6px 12px; +} + +.btn:visited { color: #fff; } + +.btn:disabled { + background-image: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + filter: alpha(opacity=40); + opacity: 0.4; + cursor: not-allowed; + box-shadow: none; +} + +.btn-disabled { + background-image: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + filter: alpha(opacity=40); + opacity: 0.4; + cursor: not-allowed; + box-shadow: none; +} + +.btn-disabled:hover, +.btn-disabled:focus, +.btn-disabled:active +{ + background-image: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + filter: alpha(opacity=40); + opacity: 0.4; + cursor: not-allowed; + box-shadow: none; +} + +.btn::-moz-focus-inner { + padding: 0; + border: 0; +} + +.btn-small { font-size: 80%; } +.btn-info { background-color: #2980B9 !important; } +.btn-info:hover { background-color: #2e8ece !important; } +.btn-neutral { background-color: #f3f6f6 !important; color:#404040 !important; } +.btn-neutral:hover { background-color: #e5ebeb !important; color:#404040; } +.btn-neutral:visited { color: #404040 !important; } +.btn-success { background-color: #27AE60 !important; } +.btn-success:hover { background-color: #295 !important; } +.btn-danger { background-color: #E74C3C !important; } +.btn-danger:hover { background-color: #ea6153 !important; } +.btn-warning { background-color: #E67E22 !important; } +.btn-warning:hover { background-color: #e98b39 !important; } +.btn-invert { background-color: #222} +.btn-invert:hover { background-color: #2f2f2f !important; } + +.btn-link { + background-color: transparent !important; + color: #2980B9; + box-shadow: none; + border-color: transparent !important; +} + +.btn-link:hover { + background-color: transparent !important; + color: #409ad5 !important; + box-shadow: none; +} + +.btn-link:active { + background-color: transparent !important; + color: #409ad5 !important; + box-shadow: none; +} + +.btn-link:visited { color:#9B59B6; } + +.wy-btn-group .btn, +.wy-control .btn +{ vertical-align: middle; } + +.wy-btn-group { margin-bottom: 24px; *zoom:1; } + +.wy-btn-group:before, +.wy-btn-group:after +{ display:table; content: ""; } + +.wy-btn-group:after { clear: both; } + +.wy-dropdown{position:relative; + display:inline-block} + +.wy-dropdown-active .wy-dropdown-menu{display:block} + +.wy-dropdown-menu{position:absolute; + left:0; + display:none; + float:left; + top:100%; + min-width:100%; + background:#fcfcfc; + z-index:100; + border:solid 1px #cfd7dd; + box-shadow:0 2px 2px 0 rgba(0,0,0,0.1); + padding:12px} + +.wy-dropdown-menu>dd>a{display:block; + clear:both; + color:#404040; + white-space:nowrap; + font-size:90%; + padding:0 12px; + cursor:pointer} + +.wy-dropdown-menu>dd>a:hover{background:#2980B9; + color:#fff} + +.wy-dropdown-menu>dd.divider{border-top:solid 1px #cfd7dd; + margin:6px 0} + +.wy-dropdown-menu>dd.search{padding-bottom:12px} + +.wy-dropdown-menu>dd.search input[type="search"]{width:100%} + +.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3; + text-transform:uppercase; + font-weight:500; + font-size:80%} + +.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3} + +.wy-dropdown-menu>dd.call-to-action .btn{color:#fff} + +.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%; + top:auto; + left:auto; + right:0} + +.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc; + margin-top:2px} + +.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px} + +.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980B9; + color:#fff} + +.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0; + left:auto; + text-align:right} + +.wy-dropdown-arrow:before{content:" "; + border-bottom:5px solid #f5f5f5; + border-left:5px solid transparent; + border-right:5px solid transparent; + position:absolute; + display:block; + top:-4px; + left:50%; + margin-left:-3px} + +.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px} + +.wy-form-stacked select{display:block} + +.wy-form-aligned input,.wy-form-aligned textarea,.wy-form-aligned select,.wy-form-aligned .wy-help-inline,.wy-form-aligned label{display:inline-block; + *display:inline; + *zoom:1; + vertical-align:middle} + +.wy-form-aligned .wy-control-group>label{display:inline-block; + vertical-align:middle; + width:10em; + margin:6px 12px 0 0; + float:left} + +.wy-form-aligned .wy-control{float:left} + +.wy-form-aligned .wy-control label{display:block} + +.wy-form-aligned .wy-control select{margin-top:6px} + +fieldset{border:0; + margin:0; + padding:0} + +legend{display:block; + width:100%; + border:0; + padding:0; + white-space:normal; + margin-bottom:24px; + font-size:150%; + *margin-left:-7px} + +label{display:block; + margin:0 0 0.3125em 0; + color:#333; + font-size:90%} + +input,select,textarea{font-size:100%; + margin:0; + vertical-align:baseline; + *vertical-align:middle} + +.wy-control-group{margin-bottom:24px; + *zoom:1; + max-width:68em; + margin-left:auto; + margin-right:auto; + *zoom:1} + +.wy-control-group:before,.wy-control-group:after{display:table; + content:""} + +.wy-control-group:after{clear:both} + +.wy-control-group:before,.wy-control-group:after{display:table; + content:""} + +.wy-control-group:after{clear:both} + +.wy-control-group.wy-control-group-required>label:after{content:" *"; + color:#E74C3C} + +.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px} + +.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds select{width:100%} + +.wy-control-group .wy-form-full input[type="text"],.wy-control-group .wy-form-full input[type="password"],.wy-control-group .wy-form-full input[type="email"],.wy-control-group .wy-form-full input[type="url"],.wy-control-group .wy-form-full input[type="date"],.wy-control-group .wy-form-full input[type="month"],.wy-control-group .wy-form-full input[type="time"],.wy-control-group .wy-form-full input[type="datetime"],.wy-control-group .wy-form-full input[type="datetime-local"],.wy-control-group .wy-form-full input[type="week"],.wy-control-group .wy-form-full input[type="number"],.wy-control-group .wy-form-full input[type="search"],.wy-control-group .wy-form-full input[type="tel"],.wy-control-group .wy-form-full input[type="color"],.wy-control-group .wy-form-halves input[type="text"],.wy-control-group .wy-form-halves input[type="password"],.wy-control-group .wy-form-halves input[type="email"],.wy-control-group .wy-form-halves input[type="url"],.wy-control-group .wy-form-halves input[type="date"],.wy-control-group .wy-form-halves input[type="month"],.wy-control-group .wy-form-halves input[type="time"],.wy-control-group .wy-form-halves input[type="datetime"],.wy-control-group .wy-form-halves input[type="datetime-local"],.wy-control-group .wy-form-halves input[type="week"],.wy-control-group .wy-form-halves input[type="number"],.wy-control-group .wy-form-halves input[type="search"],.wy-control-group .wy-form-halves input[type="tel"],.wy-control-group .wy-form-halves input[type="color"],.wy-control-group .wy-form-thirds input[type="text"],.wy-control-group .wy-form-thirds input[type="password"],.wy-control-group .wy-form-thirds input[type="email"],.wy-control-group .wy-form-thirds input[type="url"],.wy-control-group .wy-form-thirds input[type="date"],.wy-control-group .wy-form-thirds input[type="month"],.wy-control-group .wy-form-thirds input[type="time"],.wy-control-group .wy-form-thirds input[type="datetime"],.wy-control-group .wy-form-thirds input[type="datetime-local"],.wy-control-group .wy-form-thirds input[type="week"],.wy-control-group .wy-form-thirds input[type="number"],.wy-control-group .wy-form-thirds input[type="search"],.wy-control-group .wy-form-thirds input[type="tel"],.wy-control-group .wy-form-thirds input[type="color"]{width:100%} + +.wy-control-group .wy-form-full{float:left; + display:block; + margin-right:2.35765%; + width:100%; + margin-right:0} + +.wy-control-group .wy-form-full:last-child{margin-right:0} + +.wy-control-group .wy-form-halves{float:left; + display:block; + margin-right:2.35765%; + width:48.82117%} + +.wy-control-group .wy-form-halves:last-child{margin-right:0} + +.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0} + +.wy-control-group .wy-form-halves:nth-of-type(2n+1){clear:left} + +.wy-control-group .wy-form-thirds{float:left; + display:block; + margin-right:2.35765%; + width:31.76157%} + +.wy-control-group .wy-form-thirds:last-child{margin-right:0} + +.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0} + +.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left} + +.wy-control-group.wy-control-group-no-input .wy-control{margin:6px 0 0 0; + font-size:90%} + +.wy-control-no-input{display:inline-block; + margin:6px 0 0 0; + font-size:90%} + +.wy-control-group.fluid-input input[type="text"],.wy-control-group.fluid-input input[type="password"],.wy-control-group.fluid-input input[type="email"],.wy-control-group.fluid-input input[type="url"],.wy-control-group.fluid-input input[type="date"],.wy-control-group.fluid-input input[type="month"],.wy-control-group.fluid-input input[type="time"],.wy-control-group.fluid-input input[type="datetime"],.wy-control-group.fluid-input input[type="datetime-local"],.wy-control-group.fluid-input input[type="week"],.wy-control-group.fluid-input input[type="number"],.wy-control-group.fluid-input input[type="search"],.wy-control-group.fluid-input input[type="tel"],.wy-control-group.fluid-input input[type="color"]{width:100%} + +.wy-form-message-inline{display:inline-block; + padding-left:0.3em; + color:#666; + vertical-align:middle; + font-size:90%} + +.wy-form-message{display:block; + color:#999; + font-size:70%; + margin-top:0.3125em; + font-style:italic} + +.wy-form-message p{font-size:inherit; + font-style:italic; + margin-bottom:6px} + +.wy-form-message p:last-child{margin-bottom:0} + +input{line-height:normal} + +input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button; + cursor:pointer; + font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif; + *overflow:visible} + +input[type="text"],input[type="password"],input[type="email"],input[type="url"],input[type="date"],input[type="month"],input[type="time"],input[type="datetime"],input[type="datetime-local"],input[type="week"],input[type="number"],input[type="search"],input[type="tel"],input[type="color"]{-webkit-appearance:none; + padding:6px; + display:inline-block; + border:1px solid #ccc; + font-size:80%; + font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif; + box-shadow:inset 0 1px 3px #ddd; + border-radius:0; + -webkit-transition:border 0.3s linear; + -moz-transition:border 0.3s linear; + transition:border 0.3s linear} + +input[type="datetime-local"]{padding:0.34375em 0.625em} + +input[disabled]{cursor:default} + +input[type="checkbox"],input[type="radio"]{-webkit-box-sizing:border-box; + -moz-box-sizing:border-box; + box-sizing:border-box; + padding:0; + margin-right:0.3125em; + *height:13px; + *width:13px} +*/ + +input[type="search"] { + -webkit-box-sizing:border-box; + -moz-box-sizing:border-box; + box-sizing:border-box +} + +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none +} + +input[type="text"]:focus, +input[type="password"]:focus, +input[type="email"]:focus, +input[type="url"]:focus, +input[type="date"]:focus, +input[type="month"]:focus, +input[type="time"]:focus, +input[type="datetime"]:focus, +input[type="datetime-local"]:focus, +input[type="week"]:focus, +input[type="number"]:focus, +input[type="search"]:focus, +input[type="tel"]:focus, +input[type="color"]:focus$ +{ + outline: 0; + outline: thin dotted \9; + border-color: #333 +} + +/* +input.no-focus:focus{border-color:#ccc !important} + +input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333; + outline:1px auto #129FEA} + +input[type="text"][disabled],input[type="password"][disabled],input[type="email"][disabled],input[type="url"][disabled],input[type="date"][disabled],input[type="month"][disabled],input[type="time"][disabled],input[type="datetime"][disabled],input[type="datetime-local"][disabled],input[type="week"][disabled],input[type="number"][disabled],input[type="search"][disabled],input[type="tel"][disabled],input[type="color"][disabled]{cursor:not-allowed; + background-color:#fafafa} + +input:focus:invalid,textarea:focus:invalid,select:focus:invalid{color:#E74C3C; + border:1px solid #E74C3C} + +input:focus:invalid:focus,textarea:focus:invalid:focus,select:focus:invalid:focus{border-color:#E74C3C} + +input[type="file"]:focus:invalid:focus,input[type="radio"]:focus:invalid:focus,input[type="checkbox"]:focus:invalid:focus{outline-color:#E74C3C} + +input.wy-input-large{padding:12px; + font-size:100%} + +textarea{overflow:auto; + vertical-align:top; + width:100%; + font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif} + +select,textarea{padding:0.5em 0.625em; + display:inline-block; + border:1px solid #ccc; + font-size:80%; + box-shadow:inset 0 1px 3px #ddd; + -webkit-transition:border 0.3s linear; + -moz-transition:border 0.3s linear; + transition:border 0.3s linear} + +select{border:1px solid #ccc; + background-color:#fff} + +select[multiple]{height:auto} + +select:focus,textarea:focus{outline:0} + +select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed; + background-color:#fafafa} + +input[type="radio"][disabled],input[type="checkbox"][disabled]{cursor:not-allowed} + +.wy-checkbox,.wy-radio{margin:6px 0; + color:#404040; + display:block} + +.wy-checkbox input,.wy-radio input{vertical-align:baseline} + +.wy-form-message-inline{display:inline-block; + *display:inline; + *zoom:1; + vertical-align:middle} + +.wy-input-prefix,.wy-input-suffix{white-space:nowrap; + padding:6px} + +.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px; + padding:0 8px; + display:inline-block; + font-size:80%; + background-color:#f3f6f6; + border:solid 1px #ccc; + color:#999} + +.wy-input-suffix .wy-input-context{border-left:0} + +.wy-input-prefix .wy-input-context{border-right:0} + +.wy-switch{width:36px; + height:12px; + margin:12px 0; + position:relative; + border-radius:4px; + background:#ccc; + cursor:pointer; + -webkit-transition:all 0.2s ease-in-out; + -moz-transition:all 0.2s ease-in-out; + transition:all 0.2s ease-in-out} + +.wy-switch:before{position:absolute; + content:""; + display:block; + width:18px; + height:18px; + border-radius:4px; + background:#999; + left:-3px; + top:-3px; + -webkit-transition:all 0.2s ease-in-out; + -moz-transition:all 0.2s ease-in-out; + transition:all 0.2s ease-in-out} + +.wy-switch:after{content:"false"; + position:absolute; + left:48px; + display:block; + font-size:12px; + color:#ccc} + +.wy-switch.active{background:#1e8449} + +.wy-switch.active:before{left:24px; + background:#27AE60} + +.wy-switch.active:after{content:"true"} + +.wy-switch.disabled,.wy-switch.active.disabled{cursor:not-allowed} + +.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#E74C3C} + +.wy-control-group.wy-control-group-error input[type="text"],.wy-control-group.wy-control-group-error input[type="password"],.wy-control-group.wy-control-group-error input[type="email"],.wy-control-group.wy-control-group-error input[type="url"],.wy-control-group.wy-control-group-error input[type="date"],.wy-control-group.wy-control-group-error input[type="month"],.wy-control-group.wy-control-group-error input[type="time"],.wy-control-group.wy-control-group-error input[type="datetime"],.wy-control-group.wy-control-group-error input[type="datetime-local"],.wy-control-group.wy-control-group-error input[type="week"],.wy-control-group.wy-control-group-error input[type="number"],.wy-control-group.wy-control-group-error input[type="search"],.wy-control-group.wy-control-group-error input[type="tel"],.wy-control-group.wy-control-group-error input[type="color"]{border:solid 1px #E74C3C} + +.wy-control-group.wy-control-group-error textarea{border:solid 1px #E74C3C} + +.wy-inline-validate{white-space:nowrap} + +.wy-inline-validate .wy-input-context{padding:0.5em 0.625em; + display:inline-block; + font-size:80%} + +.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27AE60} + +.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#E74C3C} + +.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#E67E22} + +.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980B9} + +.rotate-90{-webkit-transform:rotate(90deg); + -moz-transform:rotate(90deg); + -ms-transform:rotate(90deg); + -o-transform:rotate(90deg); + transform:rotate(90deg)} + +.rotate-180{-webkit-transform:rotate(180deg); + -moz-transform:rotate(180deg); + -ms-transform:rotate(180deg); + -o-transform:rotate(180deg); + transform:rotate(180deg)} + +.rotate-270{-webkit-transform:rotate(270deg); + -moz-transform:rotate(270deg); + -ms-transform:rotate(270deg); + -o-transform:rotate(270deg); + transform:rotate(270deg)} + +.mirror{-webkit-transform:scaleX(-1); + -moz-transform:scaleX(-1); + -ms-transform:scaleX(-1); + -o-transform:scaleX(-1); + transform:scaleX(-1)} + +.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg); + -moz-transform:scaleX(-1) rotate(90deg); + -ms-transform:scaleX(-1) rotate(90deg); + -o-transform:scaleX(-1) rotate(90deg); + transform:scaleX(-1) rotate(90deg)} + +.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg); + -moz-transform:scaleX(-1) rotate(180deg); + -ms-transform:scaleX(-1) rotate(180deg); + -o-transform:scaleX(-1) rotate(180deg); + transform:scaleX(-1) rotate(180deg)} + +.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg); + -moz-transform:scaleX(-1) rotate(270deg); + -ms-transform:scaleX(-1) rotate(270deg); + -o-transform:scaleX(-1) rotate(270deg); + transform:scaleX(-1) rotate(270deg)} + +@media only screen and (max-width: 480px){.wy-form button[type="submit"]{margin:0.7em 0 0} + +.wy-form input[type="text"],.wy-form input[type="password"],.wy-form input[type="email"],.wy-form input[type="url"],.wy-form input[type="date"],.wy-form input[type="month"],.wy-form input[type="time"],.wy-form input[type="datetime"],.wy-form input[type="datetime-local"],.wy-form input[type="week"],.wy-form input[type="number"],.wy-form input[type="search"],.wy-form input[type="tel"],.wy-form input[type="color"]{margin-bottom:0.3em; + display:block} + +.wy-form label{margin-bottom:0.3em; + display:block} + +.wy-form input[type="password"],.wy-form input[type="email"],.wy-form input[type="url"],.wy-form input[type="date"],.wy-form input[type="month"],.wy-form input[type="time"],.wy-form input[type="datetime"],.wy-form input[type="datetime-local"],.wy-form input[type="week"],.wy-form input[type="number"],.wy-form input[type="search"],.wy-form input[type="tel"],.wy-form input[type="color"]{margin-bottom:0} + +.wy-form-aligned .wy-control-group label{margin-bottom:0.3em; + text-align:left; + display:block; + width:100%} + +.wy-form-aligned .wy-control{margin:1.5em 0 0 0} + +.wy-form .wy-help-inline,.wy-form-message-inline,.wy-form-message{display:block; + font-size:80%; + padding:6px 0} + +} + +@media screen and (max-width: 768px){.tablet-hide{display:none} + +} + +@media screen and (max-width: 480px){.mobile-hide{display:none} + +} +*/ + +.float-left { float: left; } +.float-right { float: right; } +.full-width { width: 100%; } + +/* +.wy-table{border-collapse:collapse; + border-spacing:0; + empty-cells:show; + margin-bottom:24px} + +.wy-table caption{color:#000; + font:italic 85%/1 arial,sans-serif; + padding:1em 0; + text-align:center} + +.wy-table td,.wy-table th{font-size:90%; + margin:0; + overflow:visible; + padding:8px 16px} + +.wy-table td:first-child,.wy-table th:first-child{border-left-width:0} + +.wy-table thead{color:#000; + text-align:left; + vertical-align:bottom; + white-space:nowrap} + +.wy-table thead th{font-weight:bold; + border-bottom:solid 2px #e1e4e5} + +.wy-table td{background-color:transparent; + vertical-align:middle} + +.wy-table td p{line-height:18px} + +.wy-table td p:last-child{margin-bottom:0} + +.wy-table .wy-table-cell-min{width:1%; + padding-right:0} + +.wy-table .wy-table-cell-min input[type=checkbox],.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox],.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox]{margin:0} + +.wy-table-secondary{color:gray; + font-size:90%} + +.wy-table-tertiary{color:gray; + font-size:80%} + +.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6} + +.wy-table-backed{background-color:#f3f6f6} + +.wy-table-bordered-all{border:1px solid #e1e4e5} + +.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5; + border-left:1px solid #e1e4e5} + +.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0} + +.wy-table-bordered{border:1px solid #e1e4e5} + +.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5} + +.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0} + +.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0} + +.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px 0; + border-bottom:1px solid #e1e4e5} + +.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0} + +.wy-table-responsive{margin-bottom:24px; + max-width:100%; + overflow:auto} + +.wy-table-responsive table{margin-bottom:0 !important} + +.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap} +*/ + +a { + color: #2980B9; + text-decoration: none; + cursor: pointer; +} + +a:hover { color: #3091d1; } +a:visited { color: #9B59B6; } + +html { + height: 100%; + overflow-x: hidden; +} + +body { + font-family: "Lato","proxima-nova","Helvetica Neue",Arial,sans-serif; + font-weight: normal; + color: #404040; + min-height: 100%; + overflow-x: hidden; + background: #edf0f2; +} + +/* +.wy-text-left{text-align:left} + +.wy-text-center{text-align:center} + +.wy-text-right{text-align:right} + +.wy-text-large{font-size:120%} + +.wy-text-normal{font-size:100%} + +.wy-text-small,small{font-size:80%} + +.wy-text-strike{text-decoration:line-through} + +.wy-text-warning{color:#E67E22 !important} + +a.wy-text-warning:hover{color:#eb9950 !important} + +.wy-text-info{color:#2980B9 !important} + +a.wy-text-info:hover{color:#409ad5 !important} + +.wy-text-success{color:#27AE60 !important} + +a.wy-text-success:hover{color:#36d278 !important} + +.wy-text-danger{color:#E74C3C !important} + +a.wy-text-danger:hover{color:#ed7669 !important} + +.wy-text-neutral{color:#404040 !important} + +a.wy-text-neutral:hover{color:#595959 !important} + +h1,h2,.rst-content p.caption,h3,h4,h5,h6,legend{margin-top:0; + font-weight:700; + font-family:"Roboto Slab","ff-tisa-web-pro","Georgia",Arial,sans-serif} + +p{line-height:24px; + margin:0; + font-size:16px; + margin-bottom:24px} + +h1{font-size:175%} + +h2,.rst-content p.caption{font-size:150%} + +h3{font-size:125%} + +h4{font-size:115%} + +h5{font-size:110%} + +h6{font-size:100%} + +hr{display:block; + height:1px; + border:0; + border-top:1px solid #e1e4e5; + margin:24px 0; + padding:0} + +code,.rst-content tt,.rst-content code{white-space:nowrap; + max-width:100%; + background:#fff; + border:solid 1px #e1e4e5; + font-size:75%; + padding:0 5px; + font-family:Consolas,"Andale Mono WT","Andale Mono","Lucida Console","Lucida Sans Typewriter","DejaVu Sans Mono","Bitstream Vera Sans Mono","Liberation Mono","Nimbus Mono L",Monaco,"Courier New",Courier,monospace; + color:#E74C3C; + overflow-x:auto} + +code.code-large,.rst-content tt.code-large{font-size:90%} + +.wy-plain-list-disc,.rst-content .section ul,.rst-content .toctree-wrapper ul,article ul{list-style:disc; + line-height:24px; + margin-bottom:24px} + +.wy-plain-list-disc li,.rst-content .section ul li,.rst-content .toctree-wrapper ul li,article ul li{list-style:disc; + margin-left:24px} + +.wy-plain-list-disc li p:last-child,.rst-content .section ul li p:last-child,.rst-content .toctree-wrapper ul li p:last-child,article ul li p:last-child{margin-bottom:0} + +.wy-plain-list-disc li ul,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li ul,article ul li ul{margin-bottom:0} + +.wy-plain-list-disc li li,.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,article ul li li{list-style:circle} + +.wy-plain-list-disc li li li,.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,article ul li li li{list-style:square} + +.wy-plain-list-disc li ol li,.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,article ul li ol li{list-style:decimal} + +.wy-plain-list-decimal,.rst-content .section ol,.rst-content ol.arabic,article ol{list-style:decimal; + line-height:24px; + margin-bottom:24px} + +.wy-plain-list-decimal li,.rst-content .section ol li,.rst-content ol.arabic li,article ol li{list-style:decimal; + margin-left:24px} + +.wy-plain-list-decimal li p:last-child,.rst-content .section ol li p:last-child,.rst-content ol.arabic li p:last-child,article ol li p:last-child{margin-bottom:0} + +.wy-plain-list-decimal li ul,.rst-content .section ol li ul,.rst-content ol.arabic li ul,article ol li ul{margin-bottom:0} + +.wy-plain-list-decimal li ul li,.rst-content .section ol li ul li,.rst-content ol.arabic li ul li,article ol li ul li{list-style:disc} + +.codeblock-example{border:1px solid #e1e4e5; + border-bottom:none; + padding:24px; + padding-top:48px; + font-weight:500; + background:#fff; + position:relative} + +.codeblock-example:after{content:"Example"; + position:absolute; + top:0px; + left:0px; + background:#9B59B6; + color:#fff; + padding:6px 12px} + +.codeblock-example.prettyprint-example-only{border:1px solid #e1e4e5; + margin-bottom:24px} + +.codeblock,pre.literal-block,.rst-content .literal-block,.rst-content pre.literal-block,div[class^='highlight']{border:1px solid #e1e4e5; + padding:0px; + overflow-x:auto; + background:#fff; + margin:1px 0 24px 0} + +.codeblock div[class^='highlight'],pre.literal-block div[class^='highlight'],.rst-content .literal-block div[class^='highlight'],div[class^='highlight'] div[class^='highlight']{border:none; + background:none; + margin:0} + +div[class^='highlight'] td.code{width:100%} + +.linenodiv pre{border-right:solid 1px #e6e9ea; + margin:0; + padding:12px 12px; + font-family:Consolas,"Andale Mono WT","Andale Mono","Lucida Console","Lucida Sans Typewriter","DejaVu Sans Mono","Bitstream Vera Sans Mono","Liberation Mono","Nimbus Mono L",Monaco,"Courier New",Courier,monospace; + font-size:12px; + line-height:1.5; + color:#d9d9d9} + +div[class^='highlight'] pre{white-space:pre; + margin:0; + padding:12px 12px; + font-family:Consolas,"Andale Mono WT","Andale Mono","Lucida Console","Lucida Sans Typewriter","DejaVu Sans Mono","Bitstream Vera Sans Mono","Liberation Mono","Nimbus Mono L",Monaco,"Courier New",Courier,monospace; + font-size:12px; + line-height:1.5; + display:block; + overflow:auto; + color:#404040} + +@media print{.codeblock,pre.literal-block,.rst-content .literal-block,.rst-content pre.literal-block,div[class^='highlight'],div[class^='highlight'] pre{white-space:pre-wrap} + +} + +.hll{background-color:#ffc; + margin:0 -12px; + padding:0 12px; + display:block} + +.c{color:#998; + font-style:italic} + +.err{color:#a61717; + background-color:#e3d2d2} + +.k{font-weight:bold} + +.o{font-weight:bold} + +.cm{color:#998; + font-style:italic} + +.cp{color:#999; + font-weight:bold} + +.c1{color:#998; + font-style:italic} + +.cs{color:#999; + font-weight:bold; + font-style:italic} + +.gd{color:#000; + background-color:#fdd} + +.gd .x{color:#000; + background-color:#faa} + +.ge{font-style:italic} + +.gr{color:#a00} + +.gh{color:#999} + +.gi{color:#000; + background-color:#dfd} + +.gi .x{color:#000; + background-color:#afa} + +.go{color:#888} + +.gp{color:#555} + +.gs{font-weight:bold} + +.gu{color:purple; + font-weight:bold} + +.gt{color:#a00} + +.kc{font-weight:bold} + +.kd{font-weight:bold} + +.kn{font-weight:bold} + +.kp{font-weight:bold} + +.kr{font-weight:bold} + +.kt{color:#458; + font-weight:bold} + +.m{color:#099} + +.s{color:#d14} + +.n{color:#333} + +.na{color:teal} + +.nb{color:#0086b3} + +.nc{color:#458; + font-weight:bold} + +.no{color:teal} + +.ni{color:purple} + +.ne{color:#900; + font-weight:bold} + +.nf{color:#900; + font-weight:bold} + +.nn{color:#555} + +.nt{color:navy} + +.nv{color:teal} + +.ow{font-weight:bold} + +.w{color:#bbb} + +.mf{color:#099} + +.mh{color:#099} + +.mi{color:#099} + +.mo{color:#099} + +.sb{color:#d14} +*/ + +/*.sc{color:#d14}*/ + +/* +.sd{color:#d14} + +.s2{color:#d14} + +.se{color:#d14} + +.sh{color:#d14} + +.si{color:#d14} + +.sx{color:#d14} + +.sr{color:#009926} + +.s1{color:#d14} + +.ss{color:#990073} + +.bp{color:#999} + +.vc{color:teal} + +.vg{color:teal} + +.vi{color:teal} + +.il{color:#099} + +.gc{color:#999; + background-color:#EAF2F5} +*/ + +ul.wy-breadcrumbs { + padding: 0pt; + margin: 0pt; + font-size: 90%; +} + +.wy-breadcrumbs li { display: inline-block; } +.wy-breadcrumbs li.wy-breadcrumbs-aside { float: right; } + +.wy-breadcrumbs li a { + display: inline-block; + padding: 5px; + border-bottom: none; +} + +.wy-breadcrumbs li a:first-child { padding-left: 0; } + +.wy-breadcrumbs-extra { + margin-bottom: 0; + color: #b3b3b3; + font-size: 80%; + display: inline-block; +} + +@media screen and (max-width: 480px) { + .wy-breadcrumbs-extra { display: none; } + .wy-breadcrumbs li.wy-breadcrumbs-aside { display: none; } +} + +@media print { + .wy-breadcrumbs li.wy-breadcrumbs-aside { display: none; } +} + +/* +.wy-affix{position:fixed; + top:1.618em} +*/ + +.wy-menu a:hover { text-decoration: none; } + +/* +.wy-menu-horiz{*zoom:1} + +.wy-menu-horiz:before,.wy-menu-horiz:after{display:table; + content:""} + +.wy-menu-horiz:after{clear:both} + +.wy-menu-horiz ul,.wy-menu-horiz li{display:inline-block} + +.wy-menu-horiz li:hover{background:rgba(255,255,255,0.1)} + +.wy-menu-horiz li.divide-left{border-left:solid 1px #404040} + +.wy-menu-horiz li.divide-right{border-right:solid 1px #404040} + +.wy-menu-horiz a{height:32px; + display:inline-block; + line-height:32px; + padding:0 16px} +*/ + +.wy-menu-vertical header, +.wy-menu-vertical p.caption +{ + height: 32px; + display: inline-block; + line-height: 32px; + padding: 0 1.618em; + margin-bottom: 0; + display: block; + font-weight: bold; + text-transform: uppercase; + font-size: 80%; + color: #555; + white-space: nowrap; +} + +div.wy-menu-vertical ul { margin-bottom: 0; } +div.wy-menu-vertical li.divide-top { border-top: solid 1px #404040; } +div.wy-menu-vertical li.divide-bottom { border-bottom: solid 1px #404040; } +div.wy-menu-vertical li.current { background: #e3e3e3; } + +div.wy-menu-vertical li.current a { + color: black; + border-right: solid 1px #c9c9c9; + padding: 0.4045em 2.427em; +} + +div.wy-menu-vertical li.current a:hover { background:#d6d6d6; } + +div.wy-menu-vertical li code, +div.wy-menu-vertical li .rst-content tt, +.rst-content div.wy-menu-vertical li tt +{ + border: none; + background: inherit; + color: inherit; + padding-left: 0; + padding-right: 0 +} + +div.wy-menu-vertical li span.toctree-expand { + display: block; + float: left; + margin-left: -1.2em; + font-size: 0.8em; + line-height: 1.6em; + color: #4d4d4d; +} + +div.wy-menu-vertical li.on a, +div.wy-menu-vertical li.current>a +{ +/* + color: #404040; + */ + color: black; + background: #fcfcfc; + padding: 0.4045em 1.618em; + font-weight: bold; + position: relative; + border: none; + border-bottom: solid 1px #c9c9c9; + border-top: solid 1px #c9c9c9; + padding-left: 1.618em -4px; +} + +div.wy-menu-vertical li.on a:hover, +div.wy-menu-vertical li.current>a:hover +{ background: #fcfcfc; } + +div.wy-menu-vertical li.on a:hover span.toctree-expand, +div.wy-menu-vertical li.current>a:hover span.toctree-expand +{ color: gray; } + +div.wy-menu-vertical li.on a span.toctree-expand, +div.wy-menu-vertical li.current>a span.toctree-expand +{ + display: block; + font-size: 0.8em; + line-height: 1.6em; + color: #333; +} + +div.wy-menu-vertical li.toctree-l1.current li.toctree-l2>ul, +div.wy-menu-vertical li.toctree-l2.current li.toctree-l3>ul +{ display:none; } + +div.wy-menu-vertical li.toctree-l1.current li.toctree-l2.current>ul, +div.wy-menu-vertical li.toctree-l2.current li.toctree-l3.current>ul +{ display:block; } + +div.wy-menu-vertical li.toctree-l2.current>a { + background: #c9c9c9; + padding: 0.4045em 2.427em; +} + +div.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a { + display: block; + background: #c9c9c9; + padding: 0.4045em 4.045em +} + +div.wy-menu-vertical li.toctree-l2 a:hover span.toctree-expand { color: gray; } +div.wy-menu-vertical li.toctree-l2 span.toctree-expand { color: #a3a3a3; } + +div.wy-menu-vertical li.toctree-l3 {font-size: 0.9em; } + +div.wy-menu-vertical li.toctree-l3.current>a { + background: #bdbdbd; + padding: 0.4045em 4.045em; +} + +div.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a { + display: block; + background: #bdbdbd; + padding: 0.4045em 5.663em; + border-top: none; + border-bottom: none; +} + +div.wy-menu-vertical li.toctree-l3 a:hover span.toctree-expand { color: gray; } +div.wy-menu-vertical li.toctree-l3 span.toctree-expand { color: #969696; } +div.wy-menu-vertical li.toctree-l4 { font-size: 0.9em; } +div.wy-menu-vertical li.current ul { display: block; } + +div.wy-menu-vertical li ul { + margin-bottom: 0; + display: none; +} + +div.wy-menu-vertical .local-toc li ul { display: block; } + +div.wy-menu-vertical li ul li a { + margin-bottom: 0; + color: #b3b3b3; + font-weight: normal; +} + +div.wy-menu-vertical a { + display: inline-block; + line-height: 18px; + padding: 0.4045em 1.618em; + border-bottom: none; + display: block; + position: relative; + font-size: 90%; + color: #b3b3b3; +} + +div.wy-menu-vertical a:hover { + background-color: #4e4a4a; + cursor: pointer; + border-bottom: none; +} + +div.wy-menu-vertical a:hover span.toctree-expand { color: #b3b3b3; } + +div.wy-menu-vertical a:active { + background-color: #2980B9; + cursor: pointer; + color: #fff; +} + +div.wy-menu-vertical a:active span.toctree-expand { color: #fff; } + +.wy-side-nav-search { + z-index: 200; +/*background-color: #2980B9;*/ + background-color: #7aa2f3; + text-align: center; + padding: 0.809em; + display: block; + color: #fcfcfc; + margin-bottom: 0.809em; +} + +.wy-side-nav-search input[type=text] { + width: 80%; + border-radius: 50px; + padding: 6px 12px; + border-color: #2472a4; + font-size: 90%; +} + +.wy-side-nav-search img { + display: block; + margin: auto auto 0.809em auto; + height: 45px; + width: 45px; + background-color: #2980B9; + padding: 5px; + border-radius: 100%; +} + +div.wy-side-nav-search>a, +div.wy-side-nav-search .wy-dropdown>a +{ + color: #fcfcfc; + font-size: 120%; + font-weight: bold; + display: inline-block; + padding: 4px 6px; + margin-bottom: 0.809em; + border-bottom: none; + outline: 0; +} + +/* +.wy-side-nav-search>a:hover, +.wy-side-nav-search .wy-dropdown>a:hover { + background: rgba(255,255,255,0.1); +} +*/ + +.wy-side-nav-search>a img.logo, +.wy-side-nav-search .wy-dropdown>a img.logo +{ + display: block; + margin: 0 auto; + height: auto; + width: auto; + border-radius: 0; + max-width: 100%; + background: transparent; +} + +.wy-side-nav-search>a.icon img.logo, +.wy-side-nav-search .wy-dropdown>a.icon img.logo +{ + margin-top: 0.85em; +} + +.wy-nav .wy-menu-vertical header { color: #2980B9; } +.wy-nav .wy-menu-vertical a { color: #b3b3b3; } + +.wy-nav .wy-menu-vertical a:hover { + background-color: #2980B9; + color: #fff; +} + +/* +[data-menu-wrap]{-webkit-transition:all 0.2s ease-in; + -moz-transition:all 0.2s ease-in; + transition:all 0.2s ease-in; + position:absolute; + opacity:1; + width:100%; + opacity:0} + +[data-menu-wrap].move-center{left:0; + right:auto; + opacity:1} + +[data-menu-wrap].move-left{right:auto; + left:-100%; + opacity:0} + +[data-menu-wrap].move-right{right:-100%; + left:auto; + opacity:0} +*/ + +.wy-body-for-nav { + background: left repeat-y #dddddd; +/* + background: left repeat-y #fcfcfc; + background-image: url(data:image/png; + base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDoxOERBMTRGRDBFMUUxMUUzODUwMkJCOThDMEVFNURFMCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDoxOERBMTRGRTBFMUUxMUUzODUwMkJCOThDMEVFNURFMCI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjE4REExNEZCMEUxRTExRTM4NTAyQkI5OEMwRUU1REUwIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjE4REExNEZDMEUxRTExRTM4NTAyQkI5OEMwRUU1REUwIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+EwrlwAAAAA5JREFUeNpiMDU0BAgwAAE2AJgB9BnaAAAAAElFTkSuQmCC); + background-size: 300px 1px; + */ +} + +.wy-grid-for-nav { + position: absolute; + width: 80%; + height: 100%; +} + +.wy-nav-side { + position: fixed; + top: 0; + bottom: 0; + left: 0; + padding-bottom: 2em; + width: 300px; + overflow-x: hidden; + overflow-y: auto; + min-height: 100%; + background: #343131; + z-index: 200; +} + +.wy-nav-top{display:none; + background:#2980B9; + color:#fff; + padding:0.4045em 0.809em; + position:relative; + line-height:50px; + text-align:center; + font-size:100%; + *zoom:1} + +/* +.wy-nav-top:before,.wy-nav-top:after{display:table; + content:""} + +.wy-nav-top:after{clear:both} +*/ + +.wy-nav-top a { + color: #fff; + font-weight: bold; +} + +/* +.wy-nav-top img{margin-right:12px; + height:45px; + width:45px; + background-color:#2980B9; + padding:5px; + border-radius:100%} + +.wy-nav-top i{font-size:30px; + float:left; + cursor:pointer} + +.wy-nav-content-wrap { + margin-left: 300px; + background: #fcfcfc; + min-height: 100%; +} +*/ + +.wy-nav-content { + padding: 1.618em 3.236em; + height: 100%; + max-width: 900px; +/*margin: auto;*/ +} + +/* +.wy-body-mask{position:fixed; + width:100%; + height:100%; + background:rgba(0,0,0,0.2); + display:none; + z-index:499} + +.wy-body-mask.on{display:block} + +footer{color:#999} +*/ + +footer { font-size: 90%; } + +/* + +footer p{margin-bottom:12px} + +.rst-footer-buttons{*zoom:1} + +.rst-footer-buttons:before,.rst-footer-buttons:after{display:table; + content:""} + +.rst-footer-buttons:after{clear:both} + +#search-results .search li{margin-bottom:24px; + border-bottom:solid 1px #e1e4e5; + padding-bottom:24px} + +#search-results .search li:first-child{border-top:solid 1px #e1e4e5; + padding-top:24px} + +#search-results .search li a{font-size:120%; + margin-bottom:12px; + display:inline-block} + +#search-results .context{color:gray; + font-size:90%} + +@media screen and (max-width: 768px){.wy-body-for-nav{background:#fcfcfc} + +.wy-nav-top{display:block} + +.wy-nav-side{left:-300px} + +.wy-nav-side.shift{width:85%; + left:0} + +.wy-nav-content-wrap { + margin-left: 0pt; + margin-bottom: 0pt; +} + +.wy-nav-content-wrap .wy-nav-content{padding:1.618em} + +.wy-nav-content-wrap.shift{position:fixed; + min-width:100%; + left:85%; + top:0; + height:100%; + overflow:hidden} + +} + +@media screen and (min-width: 1400px){.wy-nav-content-wrap{background:rgba(0,0,0,0.05)} + +*/ +.wy-nav-content { + margin: 0px 0px 0px 300px; + background: white; +} + +.wy-nav-content-wrap { + font-size: 95%; + margin: 0px; + padding: 0px; +} +/* + +} + +@media print{.rst-versions,footer,.wy-nav-side{display:none} + +.wy-nav-content-wrap{margin-left:0} + +} + +.rst-versions{position:fixed; + bottom:0; + left:0; + width:300px; + color:#fcfcfc; + background:#1f1d1d; + border-top:solid 10px #343131; + font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif; + z-index:400} + +.rst-versions a{color:#2980B9; + text-decoration:none} + +.rst-versions .rst-badge-small{display:none} + +.rst-versions .rst-current-version{padding:12px; + background-color:#272525; + display:block; + text-align:right; + font-size:90%; + cursor:pointer; + color:#27AE60; + *zoom:1} + +.rst-versions .rst-current-version:before,.rst-versions .rst-current-version:after{display:table; + content:""} + +.rst-versions .rst-current-version:after{clear:both} +*/ + +.rst-versions .rst-current-version .fa, +.rst-versions .rst-current-version .wy-menu-vertical li span.toctree-expand, +.wy-menu-vertical li .rst-versions .rst-current-version span.toctree-expand, +.rst-versions .rst-current-version .rst-content .admonition-title, +.rst-content .rst-versions .rst-current-version .admonition-title, +.rst-versions .rst-current-version .rst-content h1 .headerlink, +.rst-content h1 .rst-versions .rst-current-version .headerlink, +.rst-versions .rst-current-version .rst-content h2 .headerlink, +.rst-content h2 .rst-versions .rst-current-version .headerlink, +.rst-versions .rst-current-version .rst-content p.caption .headerlink, +.rst-content p.caption .rst-versions .rst-current-version .headerlink, +.rst-versions .rst-current-version .rst-content h3 .headerlink, +.rst-content h3 .rst-versions .rst-current-version .headerlink, +.rst-versions .rst-current-version .rst-content h4 .headerlink, +.rst-content h4 .rst-versions .rst-current-version .headerlink, +.rst-versions .rst-current-version .rst-content h5 .headerlink, +.rst-content h5 .rst-versions .rst-current-version .headerlink, +.rst-versions .rst-current-version .rst-content h6 .headerlink, +.rst-content h6 .rst-versions .rst-current-version .headerlink, +.rst-versions .rst-current-version .rst-content dl dt .headerlink, +.rst-content dl dt .rst-versions .rst-current-version .headerlink, +.rst-versions .rst-current-version .rst-content tt.download span:first-child, +.rst-content tt.download .rst-versions .rst-current-version span:first-child, +.rst-versions .rst-current-version .rst-content code.download span:first-child, +.rst-content code.download .rst-versions .rst-current-version span:first-child, +.rst-versions .rst-current-version .icon +{ + color: #fcfcfc +} + +/* +.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left} + +.rst-versions .rst-current-version .icon-book{float:left} + +.rst-versions .rst-current-version.rst-out-of-date{background-color:#E74C3C; + color:#fff} + +.rst-versions .rst-current-version.rst-active-old-version{background-color:#F1C40F; + color:#000} + +.rst-versions.shift-up .rst-other-versions{display:block} + +.rst-versions .rst-other-versions{font-size:90%; + padding:12px; + color:gray; + display:none} + +.rst-versions .rst-other-versions hr{display:block; + height:1px; + border:0; + margin:20px 0; + padding:0; + border-top:solid 1px #413d3d} + +.rst-versions .rst-other-versions dd{display:inline-block; + margin:0} + +.rst-versions .rst-other-versions dd a{display:inline-block; + padding:6px; + color:#fcfcfc} + +.rst-versions.rst-badge{width:auto; + bottom:20px; + right:20px; + left:auto; + border:none; + max-width:300px} + +.rst-versions.rst-badge .icon-book{float:none} + +.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none} + +.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right} + +.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left} + +.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left} + +.rst-versions.rst-badge .rst-current-version{width:auto; + height:30px; + line-height:30px; + padding:0 6px; + display:block; + text-align:center} + +@media screen and (max-width: 768px){.rst-versions{width:85%; + display:none} + +.rst-versions.shift{display:block} + +img{width:100%; + height:auto} + +} +*/ + +/* +.rst-content img{max-width:100%; + height:auto !important} + +.rst-content div.figure{margin-bottom:24px} + +.rst-content div.figure.align-center{text-align:center} + +.rst-content .section>img,.rst-content .section>a>img{margin-bottom:24px} + +.rst-content blockquote{margin-left:24px; + line-height:24px; + margin-bottom:24px} + +.rst-content .note .last,.rst-content .attention .last,.rst-content .caution .last,.rst-content .danger .last,.rst-content .error .last,.rst-content .hint .last,.rst-content .important .last,.rst-content .tip .last,.rst-content .warning .last,.rst-content .seealso .last,.rst-content .admonition-todo .last{margin-bottom:0} + +.rst-content .admonition-title:before{margin-right:4px} + +.rst-content .admonition table{border-color:rgba(0,0,0,0.1)} + +.rst-content .admonition table td,.rst-content .admonition table th{background:transparent !important; + border-color:rgba(0,0,0,0.1) !important} + +.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha li{list-style:lower-alpha} + +.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha li{list-style:upper-alpha} + +.rst-content .section ol p,.rst-content .section ul p{margin-bottom:12px} + +.rst-content .line-block{margin-left:24px} + +.rst-content .topic-title{font-weight:bold; + margin-bottom:12px} + +.rst-content .toc-backref{color:#404040} + +.rst-content .align-right{float:right; + margin:0px 0px 24px 24px} + +.rst-content .align-left{float:left; + margin:0px 24px 24px 0px} + +.rst-content .align-center{margin:auto; + display:block} + +.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content p.caption .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink,.rst-content p.caption .headerlink{display:none; + visibility:hidden; + font-size:14px} + +.rst-content h1 .headerlink:after,.rst-content h2 .headerlink:after,.rst-content p.caption .headerlink:after,.rst-content h3 .headerlink:after,.rst-content h4 .headerlink:after,.rst-content h5 .headerlink:after,.rst-content h6 .headerlink:after,.rst-content dl dt .headerlink:after,.rst-content p.caption .headerlink:after{visibility:visible; + content:""; + font-family:FontAwesome; + display:inline-block} + +.rst-content h1:hover .headerlink,.rst-content h2:hover .headerlink,.rst-content p.caption:hover .headerlink,.rst-content h3:hover .headerlink,.rst-content h4:hover .headerlink,.rst-content h5:hover .headerlink,.rst-content h6:hover .headerlink,.rst-content dl dt:hover .headerlink,.rst-content p.caption:hover .headerlink{display:inline-block} + +.rst-content .sidebar{float:right; + width:40%; + display:block; + margin:0 0 24px 24px; + padding:24px; + background:#f3f6f6; + border:solid 1px #e1e4e5} + +.rst-content .sidebar p,.rst-content .sidebar ul,.rst-content .sidebar dl{font-size:90%} + +.rst-content .sidebar .last{margin-bottom:0} + +.rst-content .sidebar .sidebar-title{display:block; + font-family:"Roboto Slab","ff-tisa-web-pro","Georgia",Arial,sans-serif; + font-weight:bold; + background:#e1e4e5; + padding:6px 12px; + margin:-24px; + margin-bottom:24px; + font-size:100%} + +.rst-content .highlighted{background:#F1C40F; + display:inline-block; + font-weight:bold; + padding:0 6px} + +.rst-content .footnote-reference,.rst-content .citation-reference{vertical-align:super; + font-size:90%} + +.rst-content table.docutils.citation,.rst-content table.docutils.footnote{background:none; + border:none; + color:#999} + +.rst-content table.docutils.citation td,.rst-content table.docutils.citation tr,.rst-content table.docutils.footnote td,.rst-content table.docutils.footnote tr{border:none; + background-color:transparent !important; + white-space:normal} + +.rst-content table.docutils.citation td.label,.rst-content table.docutils.footnote td.label{padding-left:0; + padding-right:0; + vertical-align:top} + +.rst-content table.field-list{border:none} + +.rst-content table.field-list td{border:none; + padding-top:5px} + +.rst-content table.field-list td>strong{display:inline-block; + margin-top:3px} + +.rst-content table.field-list .field-name{padding-right:10px; + text-align:left; + white-space:nowrap} + +.rst-content table.field-list .field-body{text-align:left; + padding-left:0} + +.rst-content tt,.rst-content tt,.rst-content code{color:#000} + +.rst-content tt big,.rst-content tt em,.rst-content tt big,.rst-content code big,.rst-content tt em,.rst-content code em{font-size:100% !important; + line-height:normal} + +.rst-content tt .xref,a .rst-content tt,.rst-content tt .xref,.rst-content code .xref,a .rst-content tt,a .rst-content code{font-weight:bold} + +.rst-content a tt,.rst-content a tt,.rst-content a code{color:#2980B9} + +.rst-content dl{margin-bottom:24px} + +.rst-content dl dt{font-weight:bold} + +.rst-content dl p,.rst-content dl table,.rst-content dl ul,.rst-content dl ol{margin-bottom:12px !important} + +.rst-content dl dd{margin:0 0 12px 24px} + +.rst-content dl:not(.docutils){margin-bottom:24px} + +.rst-content dl:not(.docutils) dt{display:inline-block; + margin:6px 0; + font-size:90%; + line-height:normal; + background:#e7f2fa; + color:#2980B9; + border-top:solid 3px #6ab0de; + padding:6px; + position:relative} + +.rst-content dl:not(.docutils) dt:before{color:#6ab0de} + +.rst-content dl:not(.docutils) dt .headerlink{color:#404040; + font-size:100% !important} + +.rst-content dl:not(.docutils) dl dt{margin-bottom:6px; + border:none; + border-left:solid 3px #ccc; + background:#f0f0f0; + color:gray} + +.rst-content dl:not(.docutils) dl dt .headerlink{color:#404040; + font-size:100% !important} + +.rst-content dl:not(.docutils) dt:first-child{margin-top:0} + +.rst-content dl:not(.docutils) tt,.rst-content dl:not(.docutils) tt,.rst-content dl:not(.docutils) code{font-weight:bold} + +.rst-content dl:not(.docutils) tt.descname,.rst-content dl:not(.docutils) tt.descclassname,.rst-content dl:not(.docutils) tt.descname,.rst-content dl:not(.docutils) code.descname,.rst-content dl:not(.docutils) tt.descclassname,.rst-content dl:not(.docutils) code.descclassname{background-color:transparent; + border:none; + padding:0; + font-size:100% !important} + +.rst-content dl:not(.docutils) tt.descname,.rst-content dl:not(.docutils) tt.descname,.rst-content dl:not(.docutils) code.descname{font-weight:bold} + +.rst-content dl:not(.docutils) .optional{display:inline-block; + padding:0 4px; + color:#000; + font-weight:bold} + +.rst-content dl:not(.docutils) .property{display:inline-block; + padding-right:8px} + +.rst-content .viewcode-link,.rst-content .viewcode-back{display:inline-block; + color:#27AE60; + font-size:80%; + padding-left:24px} + +.rst-content .viewcode-back{display:block; + float:right} + +.rst-content p.rubric{margin-bottom:12px; + font-weight:bold} + +.rst-content tt.download,.rst-content code.download{background:inherit; + padding:inherit; + font-family:inherit; + font-size:inherit; + color:inherit; + border:inherit; + white-space:inherit} + +.rst-content tt.download span:first-child:before,.rst-content code.download span:first-child:before{margin-right:4px} + +@media screen and (max-width: 480px){.rst-content .sidebar{width:100%} +*/ + +} + +/* +span[id*='MathJax-Span']{color:#404040} + +.math{text-align:center} + +@font-face{font-family:"Inconsolata"; + font-style:normal; + font-weight:400; + src:local("Inconsolata"),url(../fonts/Inconsolata.ttf) format("truetype")} + +@font-face{font-family:"Inconsolata"; + font-style:normal; + font-weight:700; + src:local("Inconsolata Bold"),local("Inconsolata-Bold"),url(../fonts/Inconsolata-Bold.ttf) format("truetype")} + +@font-face{font-family:"Lato"; + font-style:normal; + font-weight:400; + src:local("Lato Regular"),local("Lato-Regular"),url(../fonts/Lato-Regular.ttf) format("truetype")} + +@font-face{font-family:"Lato"; + font-style:normal; + font-weight:700; + src:local("Lato Bold"),local("Lato-Bold"),url(../fonts/Lato-Bold.ttf) format("truetype")} + +@font-face{font-family:"Roboto Slab"; + font-style:normal; + font-weight:400; + src:local("Roboto Slab Regular"),local("RobotoSlab-Regular"),url(../fonts/RobotoSlab-Regular.ttf) format("truetype")} + +@font-face{font-family:"Roboto Slab"; + font-style:normal; + font-weight:700; + src:local("Roboto Slab Bold"),local("RobotoSlab-Bold"),url(../fonts/RobotoSlab-Bold.ttf) format("truetype")} +*/ + + +/*# sourceMappingURL=theme.css.map */ diff --git a/documentation/_build/html/_static/doctools.js b/documentation/_build/html/_static/doctools.js new file mode 100644 index 00000000..d4619fdf --- /dev/null +++ b/documentation/_build/html/_static/doctools.js @@ -0,0 +1,247 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for all documentation. + * + * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/** + * select a different prefix for underscore + */ +$u = _.noConflict(); + +/** + * make the code below compatible with browsers without + * an installed firebug like debugger +if (!window.console || !console.firebug) { + var names = ["log", "debug", "info", "warn", "error", "assert", "dir", + "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", + "profile", "profileEnd"]; + window.console = {}; + for (var i = 0; i < names.length; ++i) + window.console[names[i]] = function() {}; +} + */ + +/** + * small helper function to urldecode strings + */ +jQuery.urldecode = function(x) { + return decodeURIComponent(x).replace(/\+/g, ' '); +} + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s == 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * small function to check if an array contains + * a given item. + */ +jQuery.contains = function(arr, item) { + for (var i = 0; i < arr.length; i++) { + if (arr[i] == item) + return true; + } + return false; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node) { + if (node.nodeType == 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) { + var span = document.createElement("span"); + span.className = className; + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this); + }); + } + } + return this.each(function() { + highlight(this); + }); +}; + +/** + * Small JavaScript module for the documentation. + */ +var Documentation = { + + init : function() { + this.fixFirefoxAnchorBug(); + this.highlightSearchWords(); + this.initIndexTable(); + }, + + /** + * i18n support + */ + TRANSLATIONS : {}, + PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; }, + LOCALE : 'unknown', + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext : function(string) { + var translated = Documentation.TRANSLATIONS[string]; + if (typeof translated == 'undefined') + return string; + return (typeof translated == 'string') ? translated : translated[0]; + }, + + ngettext : function(singular, plural, n) { + var translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated == 'undefined') + return (n == 1) ? singular : plural; + return translated[Documentation.PLURALEXPR(n)]; + }, + + addTranslations : function(catalog) { + for (var key in catalog.messages) + this.TRANSLATIONS[key] = catalog.messages[key]; + this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); + this.LOCALE = catalog.locale; + }, + + /** + * add context elements like header anchor links + */ + addContextElements : function() { + $('div[id] > :header:first').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this headline')). + appendTo(this); + }); + $('dt[id]').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this definition')). + appendTo(this); + }); + }, + + /** + * workaround a firefox stupidity + */ + fixFirefoxAnchorBug : function() { + if (document.location.hash && $.browser.mozilla) + window.setTimeout(function() { + document.location.href += ''; + }, 10); + }, + + /** + * highlight the search words provided in the url in the text + */ + highlightSearchWords : function() { + var params = $.getQueryParameters(); + var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; + if (terms.length) { + var body = $('div.body'); + window.setTimeout(function() { + $.each(terms, function() { + body.highlightText(this.toLowerCase(), 'highlighted'); + }); + }, 10); + $('') + .appendTo($('#searchbox')); + } + }, + + /** + * init the domain index toggle buttons + */ + initIndexTable : function() { + var togglers = $('img.toggler').click(function() { + var src = $(this).attr('src'); + var idnum = $(this).attr('id').substr(7); + $('tr.cg-' + idnum).toggle(); + if (src.substr(-9) == 'minus.png') + $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); + else + $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); + }).css('display', ''); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { + togglers.click(); + } + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords : function() { + $('#searchbox .highlight-link').fadeOut(300); + $('span.highlighted').removeClass('highlighted'); + }, + + /** + * make the url absolute + */ + makeURL : function(relativeURL) { + return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; + }, + + /** + * get the current relative url + */ + getCurrentURL : function() { + var path = document.location.pathname; + var parts = path.split(/\//); + $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { + if (this == '..') + parts.pop(); + }); + var url = parts.join('/'); + return path.substring(url.lastIndexOf('/') + 1, path.length - 1); + } +}; + +// quick alias for translations +_ = Documentation.gettext; + +$(document).ready(function() { + Documentation.init(); +}); diff --git a/documentation/_build/html/_static/down-pressed.png b/documentation/_build/html/_static/down-pressed.png new file mode 100644 index 00000000..6f7ad782 Binary files /dev/null and b/documentation/_build/html/_static/down-pressed.png differ diff --git a/documentation/_build/html/_static/down.png b/documentation/_build/html/_static/down.png new file mode 100644 index 00000000..3003a887 Binary files /dev/null and b/documentation/_build/html/_static/down.png differ diff --git a/documentation/_build/html/_static/file.png b/documentation/_build/html/_static/file.png new file mode 100644 index 00000000..d18082e3 Binary files /dev/null and b/documentation/_build/html/_static/file.png differ diff --git a/documentation/_build/html/_static/fonts/Inconsolata-Bold.ttf b/documentation/_build/html/_static/fonts/Inconsolata-Bold.ttf new file mode 100644 index 00000000..360a232d Binary files /dev/null and b/documentation/_build/html/_static/fonts/Inconsolata-Bold.ttf differ diff --git a/documentation/_build/html/_static/fonts/Inconsolata.ttf b/documentation/_build/html/_static/fonts/Inconsolata.ttf new file mode 100644 index 00000000..4b8a36d2 Binary files /dev/null and b/documentation/_build/html/_static/fonts/Inconsolata.ttf differ diff --git a/documentation/_build/html/_static/fonts/Lato-Bold.ttf b/documentation/_build/html/_static/fonts/Lato-Bold.ttf new file mode 100644 index 00000000..59c48434 Binary files /dev/null and b/documentation/_build/html/_static/fonts/Lato-Bold.ttf differ diff --git a/documentation/_build/html/_static/fonts/Lato-Regular.ttf b/documentation/_build/html/_static/fonts/Lato-Regular.ttf new file mode 100644 index 00000000..f01f5589 Binary files /dev/null and b/documentation/_build/html/_static/fonts/Lato-Regular.ttf differ diff --git a/documentation/_build/html/_static/fonts/RobotoSlab-Bold.ttf b/documentation/_build/html/_static/fonts/RobotoSlab-Bold.ttf new file mode 100644 index 00000000..e6ed0de5 Binary files /dev/null and b/documentation/_build/html/_static/fonts/RobotoSlab-Bold.ttf differ diff --git a/documentation/_build/html/_static/fonts/RobotoSlab-Regular.ttf b/documentation/_build/html/_static/fonts/RobotoSlab-Regular.ttf new file mode 100644 index 00000000..141d6c08 Binary files /dev/null and b/documentation/_build/html/_static/fonts/RobotoSlab-Regular.ttf differ diff --git a/documentation/_build/html/_static/fonts/fontawesome-webfont.eot b/documentation/_build/html/_static/fonts/fontawesome-webfont.eot new file mode 100644 index 00000000..7c79c6a6 Binary files /dev/null and b/documentation/_build/html/_static/fonts/fontawesome-webfont.eot differ diff --git a/documentation/_build/html/_static/fonts/fontawesome-webfont.svg b/documentation/_build/html/_static/fonts/fontawesome-webfont.svg new file mode 100644 index 00000000..a9f84695 --- /dev/null +++ b/documentation/_build/html/_static/fonts/fontawesome-webfont.svg @@ -0,0 +1,504 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/documentation/_build/html/_static/fonts/fontawesome-webfont.ttf b/documentation/_build/html/_static/fonts/fontawesome-webfont.ttf new file mode 100644 index 00000000..5ec37c4f Binary files /dev/null and b/documentation/_build/html/_static/fonts/fontawesome-webfont.ttf differ diff --git a/documentation/_build/html/_static/fonts/fontawesome-webfont.woff b/documentation/_build/html/_static/fonts/fontawesome-webfont.woff new file mode 100644 index 00000000..9eaecb37 Binary files /dev/null and b/documentation/_build/html/_static/fonts/fontawesome-webfont.woff differ diff --git a/documentation/_build/html/_static/images/clipboard.bb b/documentation/_build/html/_static/images/clipboard.bb new file mode 100644 index 00000000..3bd31e10 --- /dev/null +++ b/documentation/_build/html/_static/images/clipboard.bb @@ -0,0 +1 @@ +%%BoundingBox: 0 0 48 48 diff --git a/documentation/RDS/images/clipboard.eps b/documentation/_build/html/_static/images/clipboard.eps similarity index 100% rename from documentation/RDS/images/clipboard.eps rename to documentation/_build/html/_static/images/clipboard.eps diff --git a/documentation/_build/html/_static/images/clipboard.pdf b/documentation/_build/html/_static/images/clipboard.pdf new file mode 100644 index 00000000..5424a7a2 Binary files /dev/null and b/documentation/_build/html/_static/images/clipboard.pdf differ diff --git a/documentation/RDS/images/clipboard.png b/documentation/_build/html/_static/images/clipboard.png similarity index 100% rename from documentation/RDS/images/clipboard.png rename to documentation/_build/html/_static/images/clipboard.png diff --git a/documentation/_build/html/_static/images/i-core.bb b/documentation/_build/html/_static/images/i-core.bb new file mode 100644 index 00000000..3bd31e10 --- /dev/null +++ b/documentation/_build/html/_static/images/i-core.bb @@ -0,0 +1 @@ +%%BoundingBox: 0 0 48 48 diff --git a/documentation/RDS/images/i-core.eps b/documentation/_build/html/_static/images/i-core.eps similarity index 100% rename from documentation/RDS/images/i-core.eps rename to documentation/_build/html/_static/images/i-core.eps diff --git a/documentation/_build/html/_static/images/i-core.pdf b/documentation/_build/html/_static/images/i-core.pdf new file mode 100644 index 00000000..2bb22c3b Binary files /dev/null and b/documentation/_build/html/_static/images/i-core.pdf differ diff --git a/documentation/RDS/images/i-core.png b/documentation/_build/html/_static/images/i-core.png similarity index 100% rename from documentation/RDS/images/i-core.png rename to documentation/_build/html/_static/images/i-core.png diff --git a/documentation/_build/html/_static/jquery.js b/documentation/_build/html/_static/jquery.js new file mode 100644 index 00000000..7c243080 --- /dev/null +++ b/documentation/_build/html/_static/jquery.js @@ -0,0 +1,154 @@ +/*! + * jQuery JavaScript Library v1.4.2 + * http://jquery.com/ + * + * Copyright 2010, John Resig + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * Copyright 2010, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * + * Date: Sat Feb 13 22:33:48 2010 -0500 + */ +(function(A,w){function ma(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(ma,1);return}c.ready()}}function Qa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,j){var i=a.length;if(typeof b==="object"){for(var o in b)X(a,o,b[o],f,e,d);return a}if(d!==w){f=!j&&f&&c.isFunction(d);for(o=0;o)[^>]*$|^#([\w-]+)$/,Ua=/^.[^:#\[\.,]*$/,Va=/\S/, +Wa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Xa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,R=Array.prototype.slice,ya=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(a==="body"&&!b){this.context=s;this[0]=s.body;this.selector="body";this.length=1;return this}if(typeof a==="string")if((d=Ta.exec(a))&& +(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Xa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=sa([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}return c.merge(this,a)}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return T.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagName(a);return c.merge(this, +a)}else return!b||b.jquery?(b||T).find(a):c(b).find(a);else if(c.isFunction(a))return T.ready(a);if(a.selector!==w){this.selector=a.selector;this.context=a.context}return c.makeArray(a,this)},selector:"",jquery:"1.4.2",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){var f=c();c.isArray(a)?ba.apply(f,a):c.merge(f,a);f.prevObject=this;f.context=this.context;if(b=== +"find")f.selector=this.selector+(this.selector?" ":"")+d;else if(b)f.selector=this.selector+"."+b+"("+d+")";return f},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this, +function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,j,i,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b
a"; +var e=d.getElementsByTagName("*"),j=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!j)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(j.getAttribute("style")),hrefNormalized:j.getAttribute("href")==="/a",opacity:/^0.55$/.test(j.style.opacity),cssFloat:!!j.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select").appendChild(s.createElement("option")).selected, +parentNode:d.removeChild(d.appendChild(s.createElement("div"))).parentNode===null,deleteExpando:true,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(i){}a.insertBefore(b,a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}try{delete b.test}catch(o){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function k(){c.support.noCloneEvent= +false;d.detachEvent("onclick",k)});d.cloneNode(true).fireEvent("onclick")}d=s.createElement("div");d.innerHTML="";a=s.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var k=s.createElement("div");k.style.width=k.style.paddingLeft="1px";s.body.appendChild(k);c.boxModel=c.support.boxModel=k.offsetWidth===2;s.body.removeChild(k).style.display="none"});a=function(k){var n= +s.createElement("div");k="on"+k;var r=k in n;if(!r){n.setAttribute(k,"return;");r=typeof n[k]==="function"}return r};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=j=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ya=0,za={};c.extend({cache:{},expando:G,noData:{embed:true,object:true, +applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var f=a[G],e=c.cache;if(!f&&typeof b==="string"&&d===w)return null;f||(f=++Ya);if(typeof b==="object"){a[G]=f;e[f]=c.extend(true,{},b)}else if(!e[f]){a[G]=f;e[f]={}}a=e[f];if(d!==w)a[b]=d;return typeof b==="string"?a[b]:a}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{if(c.support.deleteExpando)delete a[c.expando]; +else a.removeAttribute&&a.removeAttribute(c.expando);delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this, +a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b=== +w)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var Aa=/[\n\t]/g,ca=/\s+/,Za=/\r/g,$a=/href|src|style/,ab=/(button|input)/i,bb=/(button|input|object|select|textarea)/i, +cb=/^(a|area)$/i,Ba=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(n){var r=c(this);r.addClass(a.call(this,n,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var j=b?d:0;for(d=b?d+1:e.length;j=0;else if(c.nodeName(this,"select")){var u=c.makeArray(r);c("option",this).each(function(){this.selected= +c.inArray(c(this).val(),u)>=0});if(!u.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var j=$a.test(b);if(b in a&&f&&!j){if(e){b==="type"&&ab.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed"); +a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:bb.test(a.nodeName)||cb.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&j?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var O=/\.(.*)$/,db=function(a){return a.replace(/[^\w\s\.\|`]/g, +function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;var e,j;if(d.handler){e=d;d=e.handler}if(!d.guid)d.guid=c.guid++;if(j=c.data(a)){var i=j.events=j.events||{},o=j.handle;if(!o)j.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem,arguments):w};o.elem=a;b=b.split(" ");for(var k,n=0,r;k=b[n++];){j=e?c.extend({},e):{handler:d,data:f};if(k.indexOf(".")>-1){r=k.split("."); +k=r.shift();j.namespace=r.slice(0).sort().join(".")}else{r=[];j.namespace=""}j.type=k;j.guid=d.guid;var u=i[k],z=c.event.special[k]||{};if(!u){u=i[k]=[];if(!z.setup||z.setup.call(a,f,r,o)===false)if(a.addEventListener)a.addEventListener(k,o,false);else a.attachEvent&&a.attachEvent("on"+k,o)}if(z.add){z.add.call(a,j);if(!j.handler.guid)j.handler.guid=d.guid}u.push(j);c.event.global[k]=true}a=null}}},global:{},remove:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){var e,j=0,i,o,k,n,r,u,z=c.data(a), +C=z&&z.events;if(z&&C){if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(e in C)c.event.remove(a,e+b)}else{for(b=b.split(" ");e=b[j++];){n=e;i=e.indexOf(".")<0;o=[];if(!i){o=e.split(".");e=o.shift();k=new RegExp("(^|\\.)"+c.map(o.slice(0).sort(),db).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(r=C[e])if(d){n=c.event.special[e]||{};for(B=f||0;B=0){a.type= +e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(j){}if(!a.isPropagationStopped()&& +f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){f=a.target;var i,o=c.nodeName(f,"a")&&e==="click",k=c.event.special[e]||{};if((!k._default||k._default.call(d,a)===false)&&!o&&!(f&&f.nodeName&&c.noData[f.nodeName.toLowerCase()])){try{if(f[e]){if(i=f["on"+e])f["on"+e]=null;c.event.triggered=true;f[e]()}}catch(n){}if(i)f["on"+e]=i;c.event.triggered=false}}},handle:function(a){var b,d,f,e;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive; +if(!b){d=a.type.split(".");a.type=d.shift();f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)")}e=c.data(this,"events");d=e[a.type];if(e&&d){d=d.slice(0);e=0;for(var j=d.length;e-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},fa=function(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Fa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data", +e);if(!(f===w||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:fa,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return fa.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return fa.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a, +"_change_data",Fa(a))}},setup:function(){if(this.type==="file")return false;for(var a in ea)c.event.add(this,a+".specialChange",ea[a]);return da.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return da.test(this.nodeName)}};ea=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventListener(a, +d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var j in d)this[b](j,f,d[j],e);return this}if(c.isFunction(f)){e=f;f=w}var i=b==="one"?c.proxy(e,function(k){c(this).unbind(k,i);return e.apply(this,arguments)}):e;if(d==="unload"&&b!=="one")this.one(d,f,e);else{j=0;for(var o=this.length;j0){y=t;break}}t=t[g]}m[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, +e=0,j=Object.prototype.toString,i=false,o=true;[0,0].sort(function(){o=false;return 0});var k=function(g,h,l,m){l=l||[];var q=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return l;for(var p=[],v,t,y,S,H=true,M=x(h),I=g;(f.exec(""),v=f.exec(I))!==null;){I=v[3];p.push(v[1]);if(v[2]){S=v[3];break}}if(p.length>1&&r.exec(g))if(p.length===2&&n.relative[p[0]])t=ga(p[0]+p[1],h);else for(t=n.relative[p[0]]?[h]:k(p.shift(),h);p.length;){g=p.shift();if(n.relative[g])g+=p.shift(); +t=ga(g,t)}else{if(!m&&p.length>1&&h.nodeType===9&&!M&&n.match.ID.test(p[0])&&!n.match.ID.test(p[p.length-1])){v=k.find(p.shift(),h,M);h=v.expr?k.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:p.pop(),set:z(m)}:k.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=v.expr?k.filter(v.expr,v.set):v.set;if(p.length>0)y=z(t);else H=false;for(;p.length;){var D=p.pop();v=D;if(n.relative[D])v=p.pop();else D="";if(v==null)v=h;n.relative[D](y,v,M)}}else y=[]}y||(y=t);y||k.error(D|| +g);if(j.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))l.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&l.push(t[g]);else l.push.apply(l,y);else z(y,l);if(S){k(S,q,l,m);k.uniqueSort(l)}return l};k.uniqueSort=function(g){if(B){i=o;g.sort(B);if(i)for(var h=1;h":function(g,h){var l=typeof h==="string";if(l&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,q=g.length;m=0))l||m.push(v);else if(l)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()}, +CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,l,m,q,p){h=g[1].replace(/\\/g,"");if(!p&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,l,m,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,h);else{g=k.filter(g[3],h,l,true^q);l||m.push.apply(m, +g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,l){return!!k(l[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)}, +text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}}, +setFilters:{first:function(g,h){return h===0},last:function(g,h,l,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,l){return hl[3]-0},nth:function(g,h,l){return l[3]-0===h},eq:function(g,h,l){return l[3]-0===h}},filter:{PSEUDO:function(g,h,l,m){var q=h[1],p=n.filters[q];if(p)return p(g,l,h,m);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h= +h[3];l=0;for(m=h.length;l=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var l=h[1];g=n.attrHandle[l]?n.attrHandle[l](g):g[l]!=null?g[l]:g.getAttribute(l);l=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m=== +"="?l===h:m==="*="?l.indexOf(h)>=0:m==="~="?(" "+l+" ").indexOf(h)>=0:!h?l&&g!==false:m==="!="?l!==h:m==="^="?l.indexOf(h)===0:m==="$="?l.substr(l.length-h.length)===h:m==="|="?l===h||l.substr(0,h.length+1)===h+"-":false},POS:function(g,h,l,m){var q=n.setFilters[h[2]];if(q)return q(g,l,h,m)}}},r=n.match.POS;for(var u in n.match){n.match[u]=new RegExp(n.match[u].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[u]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[u].source.replace(/\\(\d+)/g,function(g, +h){return"\\"+(h-0+1)}))}var z=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){z=function(g,h){h=h||[];if(j.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var l=0,m=g.length;l";var l=s.documentElement;l.insertBefore(g,l.firstChild);if(s.getElementById(h)){n.find.ID=function(m,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(m[1]))?q.id===m[1]||typeof q.getAttributeNode!=="undefined"&& +q.getAttributeNode("id").nodeValue===m[1]?[q]:w:[]};n.filter.ID=function(m,q){var p=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&p&&p.nodeValue===q}}l.removeChild(g);l=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,l){l=l.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;l[m];m++)l[m].nodeType===1&&h.push(l[m]);l=h}return l};g.innerHTML=""; +if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=k,h=s.createElement("div");h.innerHTML="

";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){k=function(m,q,p,v){q=q||s;if(!v&&q.nodeType===9&&!x(q))try{return z(q.querySelectorAll(m),p)}catch(t){}return g(m,q,p,v)};for(var l in g)k[l]=g[l];h=null}}(); +(function(){var g=s.createElement("div");g.innerHTML="
";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,l,m){if(typeof l.getElementsByClassName!=="undefined"&&!m)return l.getElementsByClassName(h[1])};g=null}}})();var E=s.compareDocumentPosition?function(g,h){return!!(g.compareDocumentPosition(h)&16)}: +function(g,h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ga=function(g,h){var l=[],m="",q;for(h=h.nodeType?[h]:h;q=n.match.PSEUDO.exec(g);){m+=q[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;q=0;for(var p=h.length;q=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f0)for(var j=d;j0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,j= +{},i;if(f&&a.length){e=0;for(var o=a.length;e-1:c(f).is(e)){d.push({selector:i,elem:f});delete j[i]}}f=f.parentNode}}return d}var k=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,r){for(;r&&r.ownerDocument&&r!==b;){if(k?k.index(r)>-1:c(r).is(a))return r;r=r.parentNode}return null})},index:function(a){if(!a||typeof a=== +"string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(qa(a[0])||qa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode", +d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")? +a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);eb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||gb.test(f))&&fb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||a.nodeType!==1||!c(a).is(d));){a.nodeType=== +1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ja=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ka=/(<([\w:]+)[^>]*?)\/>/g,hb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,La=/<([\w:]+)/,ib=/"},F={option:[1,""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div
","
"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d= +c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this}, +wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})}, +prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b, +this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,f;(f=this[d])!=null;d++)if(!a||c.filter(a,[f]).length){if(!b&&f.nodeType===1){c.cleanData(f.getElementsByTagName("*"));c.cleanData([f])}f.parentNode&&f.parentNode.removeChild(f)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild); +return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ja,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ra(this,b);ra(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Ja, +""):null;else if(typeof a==="string"&&!ta.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(La.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Ka,Ma);try{for(var b=0,d=this.length;b0||e.cacheable||this.length>1?k.cloneNode(true):k)}o.length&&c.each(o,Qa)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);var e=this.length===1&&this[0].parentNode;if(e&&e.nodeType===11&&e.childNodes.length===1&&d.length===1){d[b](this[0]); +return this}else{e=0;for(var j=d.length;e0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),i);f=f.concat(i)}return this.pushStack(f,a,d.selector)}}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;for(var e=[],j=0,i;(i=a[j])!=null;j++){if(typeof i==="number")i+="";if(i){if(typeof i==="string"&&!jb.test(i))i=b.createTextNode(i);else if(typeof i==="string"){i=i.replace(Ka,Ma);var o=(La.exec(i)||["", +""])[1].toLowerCase(),k=F[o]||F._default,n=k[0],r=b.createElement("div");for(r.innerHTML=k[1]+i+k[2];n--;)r=r.lastChild;if(!c.support.tbody){n=ib.test(i);o=o==="table"&&!n?r.firstChild&&r.firstChild.childNodes:k[1]===""&&!n?r.childNodes:[];for(k=o.length-1;k>=0;--k)c.nodeName(o[k],"tbody")&&!o[k].childNodes.length&&o[k].parentNode.removeChild(o[k])}!c.support.leadingWhitespace&&V.test(i)&&r.insertBefore(b.createTextNode(V.exec(i)[0]),r.firstChild);i=r.childNodes}if(i.nodeType)e.push(i);else e= +c.merge(e,i)}}if(d)for(j=0;e[j];j++)if(f&&c.nodeName(e[j],"script")&&(!e[j].type||e[j].type.toLowerCase()==="text/javascript"))f.push(e[j].parentNode?e[j].parentNode.removeChild(e[j]):e[j]);else{e[j].nodeType===1&&e.splice.apply(e,[j+1,0].concat(c.makeArray(e[j].getElementsByTagName("script"))));d.appendChild(e[j])}return e},cleanData:function(a){for(var b,d,f=c.cache,e=c.event.special,j=c.support.deleteExpando,i=0,o;(o=a[i])!=null;i++)if(d=o[c.expando]){b=f[d];if(b.events)for(var k in b.events)e[k]? +c.event.remove(o,k):Ca(o,k,b.handle);if(j)delete o[c.expando];else o.removeAttribute&&o.removeAttribute(c.expando);delete f[d]}}});var kb=/z-?index|font-?weight|opacity|zoom|line-?height/i,Na=/alpha\([^)]*\)/,Oa=/opacity=([^)]*)/,ha=/float/i,ia=/-([a-z])/ig,lb=/([A-Z])/g,mb=/^-?\d+(?:px)?$/i,nb=/^-?\d/,ob={position:"absolute",visibility:"hidden",display:"block"},pb=["Left","Right"],qb=["Top","Bottom"],rb=s.defaultView&&s.defaultView.getComputedStyle,Pa=c.support.cssFloat?"cssFloat":"styleFloat",ja= +function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!kb.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter= +Na.test(a)?a.replace(Na,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Oa.exec(f.filter)[1])/100+"":""}if(ha.test(b))b=Pa;b=b.replace(ia,ja);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,j=b==="width"?pb:qb;function i(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(j,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a, +"border"+this+"Width",true))||0})}a.offsetWidth!==0?i():c.swap(a,ob,i);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Oa.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ha.test(b))b=Pa;if(!d&&e&&e[b])f=e[b];else if(rb){if(ha.test(b))b="float";b=b.replace(lb,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f= +a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ia,ja);f=a.currentStyle[b]||a.currentStyle[d];if(!mb.test(f)&&nb.test(f)){b=e.left;var j=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=j}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b= +a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var sb=J(),tb=//gi,ub=/select|textarea/i,vb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ka=/\?/,wb=/(\?|&)_=.*?(&|$)/,xb=/^(\w+:)?\/\/([^\/?#]+)/,yb=/%20/g,zb=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!== +"string")return zb.call(this,a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);f="POST"}var j=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(i,o){if(o==="success"||o==="notmodified")j.html(e?c("
").append(i.responseText.replace(tb,"")).find(e):i.responseText);d&&j.each(d,[i.responseText,o,i])}});return this}, +serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ub.test(this.nodeName)||vb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), +function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href, +global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:A.XMLHttpRequest&&(A.location.protocol!=="file:"||!A.ActiveXObject)?function(){return new A.XMLHttpRequest}:function(){try{return new A.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&& +e.success.call(k,o,i,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(k,x,i);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),j,i,o,k=a&&a.context||e,n=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(n==="GET")N.test(e.url)||(e.url+=(ka.test(e.url)? +"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||N.test(e.url))){j=e.jsonpCallback||"jsonp"+sb++;if(e.data)e.data=(e.data+"").replace(N,"="+j+"$1");e.url=e.url.replace(N,"="+j+"$1");e.dataType="script";A[j]=A[j]||function(q){o=q;b();d();A[j]=w;try{delete A[j]}catch(p){}z&&z.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache=== +false&&n==="GET"){var r=J(),u=e.url.replace(wb,"$1_="+r+"$2");e.url=u+(u===e.url?(ka.test(e.url)?"&":"?")+"_="+r:"")}if(e.data&&n==="GET")e.url+=(ka.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");r=(r=xb.exec(e.url))&&(r[1]&&r[1]!==location.protocol||r[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&r){var z=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if(!j){var B= +false;C.onload=C.onreadystatechange=function(){if(!B&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){B=true;b();d();C.onload=C.onreadystatechange=null;z&&C.parentNode&&z.removeChild(C)}}}z.insertBefore(C,z.firstChild);return w}var E=false,x=e.xhr();if(x){e.username?x.open(n,e.url,e.async,e.username,e.password):x.open(n,e.url,e.async);try{if(e.data||a&&a.contentType)x.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&x.setRequestHeader("If-Modified-Since", +c.lastModified[e.url]);c.etag[e.url]&&x.setRequestHeader("If-None-Match",c.etag[e.url])}r||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ga){}if(e.beforeSend&&e.beforeSend.call(k,x,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");x.abort();return false}e.global&&f("ajaxSend",[x,e]);var g=x.onreadystatechange=function(q){if(!x||x.readyState===0||q==="abort"){E|| +d();E=true;if(x)x.onreadystatechange=c.noop}else if(!E&&x&&(x.readyState===4||q==="timeout")){E=true;x.onreadystatechange=c.noop;i=q==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";var p;if(i==="success")try{o=c.httpData(x,e.dataType,e)}catch(v){i="parsererror";p=v}if(i==="success"||i==="notmodified")j||b();else c.handleError(e,x,i,p);d();q==="timeout"&&x.abort();if(e.async)x=null}};try{var h=x.abort;x.abort=function(){x&&h.call(x); +g("abort")}}catch(l){}e.async&&e.timeout>0&&setTimeout(function(){x&&!E&&g("timeout")},e.timeout);try{x.send(n==="POST"||n==="PUT"||n==="DELETE"?e.data:null)}catch(m){c.handleError(e,x,null,m);d()}e.async||g();return x}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status=== +1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b=== +"json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(i,o){if(c.isArray(o))c.each(o,function(k,n){b||/\[\]$/.test(i)?f(i,n):d(i+"["+(typeof n==="object"||c.isArray(n)?k:"")+"]",n)});else!b&&o!=null&&typeof o==="object"?c.each(o,function(k,n){d(i+"["+k+"]",n)}):f(i,o)}function f(i,o){o=c.isFunction(o)?o():o;e[e.length]=encodeURIComponent(i)+"="+encodeURIComponent(o)}var e=[];if(b===w)b=c.ajaxSettings.traditional; +if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var j in a)d(j,a[j]);return e.join("&").replace(yb,"+")}});var la={},Ab=/toggle|show|hide/,Bb=/^([+-]=)?([\d+-.]+)(.*)$/,W,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();la[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration=== +"number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]|| +c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(j){return e.step(j)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start; +this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.startTime){this.now= +this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem, +e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b
"; +a.insertBefore(b,a.firstChild);d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==j;a.removeChild(b); +c.offset.initialize=c.noop},bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),j=parseInt(c.curCSS(a,"top",true),10)||0,i=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a, +d,e);d={top:b.top-e.top+j,left:b.left-e.left+i};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top- +f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||s.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],j;if(!e)return null;if(f!==w)return this.each(function(){if(j=wa(this))j.scrollTo(!a?f:c(j).scrollLeft(),a?f:c(j).scrollTop());else this[d]=f});else return(j=wa(e))?"pageXOffset"in j?j[a?"pageYOffset": +"pageXOffset"]:c.support.boxModel&&j.document.documentElement[d]||j.document.body[d]:e[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(j){var i=c(this);i[d](f.call(this,j,i[d]()))});return"scrollTo"in +e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===w?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});A.jQuery=A.$=c})(window); diff --git a/documentation/_build/html/_static/js/modernizr.min.js b/documentation/_build/html/_static/js/modernizr.min.js new file mode 100644 index 00000000..f65d4797 --- /dev/null +++ b/documentation/_build/html/_static/js/modernizr.min.js @@ -0,0 +1,4 @@ +/* Modernizr 2.6.2 (Custom Build) | MIT & BSD + * Build: http://modernizr.com/download/#-fontface-backgroundsize-borderimage-borderradius-boxshadow-flexbox-hsla-multiplebgs-opacity-rgba-textshadow-cssanimations-csscolumns-generatedcontent-cssgradients-cssreflections-csstransforms-csstransforms3d-csstransitions-applicationcache-canvas-canvastext-draganddrop-hashchange-history-audio-video-indexeddb-input-inputtypes-localstorage-postmessage-sessionstorage-websockets-websqldatabase-webworkers-geolocation-inlinesvg-smil-svg-svgclippaths-touch-webgl-shiv-mq-cssclasses-addtest-prefixed-teststyles-testprop-testallprops-hasevent-prefixes-domprefixes-load + */ +;window.Modernizr=function(a,b,c){function D(a){j.cssText=a}function E(a,b){return D(n.join(a+";")+(b||""))}function F(a,b){return typeof a===b}function G(a,b){return!!~(""+a).indexOf(b)}function H(a,b){for(var d in a){var e=a[d];if(!G(e,"-")&&j[e]!==c)return b=="pfx"?e:!0}return!1}function I(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:F(f,"function")?f.bind(d||b):f}return!1}function J(a,b,c){var d=a.charAt(0).toUpperCase()+a.slice(1),e=(a+" "+p.join(d+" ")+d).split(" ");return F(b,"string")||F(b,"undefined")?H(e,b):(e=(a+" "+q.join(d+" ")+d).split(" "),I(e,b,c))}function K(){e.input=function(c){for(var d=0,e=c.length;d',a,""].join(""),l.id=h,(m?l:n).innerHTML+=f,n.appendChild(l),m||(n.style.background="",n.style.overflow="hidden",k=g.style.overflow,g.style.overflow="hidden",g.appendChild(n)),i=c(l,a),m?l.parentNode.removeChild(l):(n.parentNode.removeChild(n),g.style.overflow=k),!!i},z=function(b){var c=a.matchMedia||a.msMatchMedia;if(c)return c(b).matches;var d;return y("@media "+b+" { #"+h+" { position: absolute; } }",function(b){d=(a.getComputedStyle?getComputedStyle(b,null):b.currentStyle)["position"]=="absolute"}),d},A=function(){function d(d,e){e=e||b.createElement(a[d]||"div"),d="on"+d;var f=d in e;return f||(e.setAttribute||(e=b.createElement("div")),e.setAttribute&&e.removeAttribute&&(e.setAttribute(d,""),f=F(e[d],"function"),F(e[d],"undefined")||(e[d]=c),e.removeAttribute(d))),e=null,f}var a={select:"input",change:"input",submit:"form",reset:"form",error:"img",load:"img",abort:"img"};return d}(),B={}.hasOwnProperty,C;!F(B,"undefined")&&!F(B.call,"undefined")?C=function(a,b){return B.call(a,b)}:C=function(a,b){return b in a&&F(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=w.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(w.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(w.call(arguments)))};return e}),s.flexbox=function(){return J("flexWrap")},s.canvas=function(){var a=b.createElement("canvas");return!!a.getContext&&!!a.getContext("2d")},s.canvastext=function(){return!!e.canvas&&!!F(b.createElement("canvas").getContext("2d").fillText,"function")},s.webgl=function(){return!!a.WebGLRenderingContext},s.touch=function(){var c;return"ontouchstart"in a||a.DocumentTouch&&b instanceof DocumentTouch?c=!0:y(["@media (",n.join("touch-enabled),("),h,")","{#modernizr{top:9px;position:absolute}}"].join(""),function(a){c=a.offsetTop===9}),c},s.geolocation=function(){return"geolocation"in navigator},s.postmessage=function(){return!!a.postMessage},s.websqldatabase=function(){return!!a.openDatabase},s.indexedDB=function(){return!!J("indexedDB",a)},s.hashchange=function(){return A("hashchange",a)&&(b.documentMode===c||b.documentMode>7)},s.history=function(){return!!a.history&&!!history.pushState},s.draganddrop=function(){var a=b.createElement("div");return"draggable"in a||"ondragstart"in a&&"ondrop"in a},s.websockets=function(){return"WebSocket"in a||"MozWebSocket"in a},s.rgba=function(){return D("background-color:rgba(150,255,150,.5)"),G(j.backgroundColor,"rgba")},s.hsla=function(){return D("background-color:hsla(120,40%,100%,.5)"),G(j.backgroundColor,"rgba")||G(j.backgroundColor,"hsla")},s.multiplebgs=function(){return D("background:url(https://),url(https://),red url(https://)"),/(url\s*\(.*?){3}/.test(j.background)},s.backgroundsize=function(){return J("backgroundSize")},s.borderimage=function(){return J("borderImage")},s.borderradius=function(){return J("borderRadius")},s.boxshadow=function(){return J("boxShadow")},s.textshadow=function(){return b.createElement("div").style.textShadow===""},s.opacity=function(){return E("opacity:.55"),/^0.55$/.test(j.opacity)},s.cssanimations=function(){return J("animationName")},s.csscolumns=function(){return J("columnCount")},s.cssgradients=function(){var a="background-image:",b="gradient(linear,left top,right bottom,from(#9f9),to(white));",c="linear-gradient(left top,#9f9, white);";return D((a+"-webkit- ".split(" ").join(b+a)+n.join(c+a)).slice(0,-a.length)),G(j.backgroundImage,"gradient")},s.cssreflections=function(){return J("boxReflect")},s.csstransforms=function(){return!!J("transform")},s.csstransforms3d=function(){var a=!!J("perspective");return a&&"webkitPerspective"in g.style&&y("@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}",function(b,c){a=b.offsetLeft===9&&b.offsetHeight===3}),a},s.csstransitions=function(){return J("transition")},s.fontface=function(){var a;return y('@font-face {font-family:"font";src:url("https://")}',function(c,d){var e=b.getElementById("smodernizr"),f=e.sheet||e.styleSheet,g=f?f.cssRules&&f.cssRules[0]?f.cssRules[0].cssText:f.cssText||"":"";a=/src/i.test(g)&&g.indexOf(d.split(" ")[0])===0}),a},s.generatedcontent=function(){var a;return y(["#",h,"{font:0/0 a}#",h,':after{content:"',l,'";visibility:hidden;font:3px/1 a}'].join(""),function(b){a=b.offsetHeight>=3}),a},s.video=function(){var a=b.createElement("video"),c=!1;try{if(c=!!a.canPlayType)c=new Boolean(c),c.ogg=a.canPlayType('video/ogg; codecs="theora"').replace(/^no$/,""),c.h264=a.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(/^no$/,""),c.webm=a.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,"")}catch(d){}return c},s.audio=function(){var a=b.createElement("audio"),c=!1;try{if(c=!!a.canPlayType)c=new Boolean(c),c.ogg=a.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),c.mp3=a.canPlayType("audio/mpeg;").replace(/^no$/,""),c.wav=a.canPlayType('audio/wav; codecs="1"').replace(/^no$/,""),c.m4a=(a.canPlayType("audio/x-m4a;")||a.canPlayType("audio/aac;")).replace(/^no$/,"")}catch(d){}return c},s.localstorage=function(){try{return localStorage.setItem(h,h),localStorage.removeItem(h),!0}catch(a){return!1}},s.sessionstorage=function(){try{return sessionStorage.setItem(h,h),sessionStorage.removeItem(h),!0}catch(a){return!1}},s.webworkers=function(){return!!a.Worker},s.applicationcache=function(){return!!a.applicationCache},s.svg=function(){return!!b.createElementNS&&!!b.createElementNS(r.svg,"svg").createSVGRect},s.inlinesvg=function(){var a=b.createElement("div");return a.innerHTML="",(a.firstChild&&a.firstChild.namespaceURI)==r.svg},s.smil=function(){return!!b.createElementNS&&/SVGAnimate/.test(m.call(b.createElementNS(r.svg,"animate")))},s.svgclippaths=function(){return!!b.createElementNS&&/SVGClipPath/.test(m.call(b.createElementNS(r.svg,"clipPath")))};for(var L in s)C(s,L)&&(x=L.toLowerCase(),e[x]=s[L](),v.push((e[x]?"":"no-")+x));return e.input||K(),e.addTest=function(a,b){if(typeof a=="object")for(var d in a)C(a,d)&&e.addTest(d,a[d]);else{a=a.toLowerCase();if(e[a]!==c)return e;b=typeof b=="function"?b():b,typeof f!="undefined"&&f&&(g.className+=" "+(b?"":"no-")+a),e[a]=b}return e},D(""),i=k=null,function(a,b){function k(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function l(){var a=r.elements;return typeof a=="string"?a.split(" "):a}function m(a){var b=i[a[g]];return b||(b={},h++,a[g]=h,i[h]=b),b}function n(a,c,f){c||(c=b);if(j)return c.createElement(a);f||(f=m(c));var g;return f.cache[a]?g=f.cache[a].cloneNode():e.test(a)?g=(f.cache[a]=f.createElem(a)).cloneNode():g=f.createElem(a),g.canHaveChildren&&!d.test(a)?f.frag.appendChild(g):g}function o(a,c){a||(a=b);if(j)return a.createDocumentFragment();c=c||m(a);var d=c.frag.cloneNode(),e=0,f=l(),g=f.length;for(;e",f="hidden"in a,j=a.childNodes.length==1||function(){b.createElement("a");var a=b.createDocumentFragment();return typeof a.cloneNode=="undefined"||typeof a.createDocumentFragment=="undefined"||typeof a.createElement=="undefined"}()}catch(c){f=!0,j=!0}})();var r={elements:c.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video",shivCSS:c.shivCSS!==!1,supportsUnknownElements:j,shivMethods:c.shivMethods!==!1,type:"default",shivDocument:q,createElement:n,createDocumentFragment:o};a.html5=r,q(b)}(this,b),e._version=d,e._prefixes=n,e._domPrefixes=q,e._cssomPrefixes=p,e.mq=z,e.hasEvent=A,e.testProp=function(a){return H([a])},e.testAllProps=J,e.testStyles=y,e.prefixed=function(a,b,c){return b?J(a,b,c):J(a,"pfx")},g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" js "+v.join(" "):""),e}(this,this.document),function(a,b,c){function d(a){return"[object Function]"==o.call(a)}function e(a){return"string"==typeof a}function f(){}function g(a){return!a||"loaded"==a||"complete"==a||"uninitialized"==a}function h(){var a=p.shift();q=1,a?a.t?m(function(){("c"==a.t?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){"img"!=a&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l=b.createElement(a),o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};1===y[c]&&(r=1,y[c]=[]),"object"==a?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),"img"!=a&&(r||2===y[c]?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i("c"==b?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),1==p.length&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&"[object Opera]"==o.call(a.opera),l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return"[object Array]"==o.call(a)},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;f ul li.current').removeClass('current'); + parent_li.toggleClass('current'); +} + +$(document).ready(function() { + // Shift nav in mobile when clicking the menu. + $(document).on('click', "[data-toggle='wy-nav-top']", function() { + $("[data-toggle='wy-nav-shift']").toggleClass("shift"); + $("[data-toggle='rst-versions']").toggleClass("shift"); + }); + // Nav menu link click operations + $(document).on('click', ".wy-menu-vertical .current ul li a", function() { + var target = $(this); + // Close menu when you click a link. + $("[data-toggle='wy-nav-shift']").removeClass("shift"); + $("[data-toggle='rst-versions']").toggleClass("shift"); + // Handle dynamic display of l3 and l4 nav lists + toggleCurrent(target); + if (typeof(window.SphinxRtdTheme) != 'undefined') { + window.SphinxRtdTheme.StickyNav.hashChange(); + } + }); + $(document).on('click', "[data-toggle='rst-current-version']", function() { + $("[data-toggle='rst-versions']").toggleClass("shift-up"); + }); + // Make tables responsive + $("table.docutils:not(.field-list)").wrap("
"); + + // Add expand links to all parents of nested ul + $('.wy-menu-vertical ul').siblings('a').each(function () { + var link = $(this); + expand = $(''); + expand.on('click', function (ev) { + toggleCurrent(link); + ev.stopPropagation(); + return false; + }); + link.prepend(expand); + }); +}); + +// Sphinx theme state +window.SphinxRtdTheme = (function (jquery) { + var stickyNav = (function () { + var navBar, + win, + winScroll = false, + linkScroll = false, + winPosition = 0, + enable = function () { + init(); + reset(); + win.on('hashchange', reset); + + // Set scrolling + win.on('scroll', function () { + if (!linkScroll) { + winScroll = true; + } + }); + setInterval(function () { + if (winScroll) { + winScroll = false; + var newWinPosition = win.scrollTop(), + navPosition = navBar.scrollTop(), + newNavPosition = navPosition + (newWinPosition - winPosition); + navBar.scrollTop(newNavPosition); + winPosition = newWinPosition; + } + }, 25); + }, + init = function () { + navBar = jquery('nav.wy-nav-side:first'); + win = jquery(window); + }, + reset = function () { + // Get anchor from URL and open up nested nav + var anchor = encodeURI(window.location.hash); + if (anchor) { + try { + var link = $('.wy-menu-vertical') + .find('[href="' + anchor + '"]'); + $('.wy-menu-vertical li.toctree-l1 li.current') + .removeClass('current'); + link.closest('li.toctree-l2').addClass('current'); + link.closest('li.toctree-l3').addClass('current'); + link.closest('li.toctree-l4').addClass('current'); + } + catch (err) { + console.log("Error expanding nav for anchor", err); + } + } + }, + hashChange = function () { + linkScroll = true; + win.one('hashchange', function () { + linkScroll = false; + }); + }; + jquery(init); + return { + enable: enable, + hashChange: hashChange + }; + }()); + return { + StickyNav: stickyNav + }; +}($)); diff --git a/documentation/_build/html/_static/minus.png b/documentation/_build/html/_static/minus.png new file mode 100644 index 00000000..da1c5620 Binary files /dev/null and b/documentation/_build/html/_static/minus.png differ diff --git a/documentation/_build/html/_static/plus.png b/documentation/_build/html/_static/plus.png new file mode 100644 index 00000000..b3cb3742 Binary files /dev/null and b/documentation/_build/html/_static/plus.png differ diff --git a/documentation/_build/html/_static/pygments.css b/documentation/_build/html/_static/pygments.css new file mode 100644 index 00000000..68e7c8c8 --- /dev/null +++ b/documentation/_build/html/_static/pygments.css @@ -0,0 +1,46 @@ +div.codeblock, div[class^="highlight"] { + font-family: "courrier", "andale mono", monospace; + font-size: 90%; + white-space: pre; +/* + margin: 10pt; +*/ + padding: 1px 10pt 1px 10pt; + margin: 0pt; + border: none; + background-color: #fcfce1; + } +.codeblock * .hll, [class^="highlight"] * .hll { background-color: #fcfce1 } +.codeblock * .c , [class^="highlight"] * .c { color: black } /* Comment */ +.codeblock * .err, [class^="highlight"] * .err { border: 1px solid #FF0000 } /* Error */ +.codeblock * .k , [class^="highlight"] * .k { color: black; font-weight: bold } /* Keyword */ +.codeblock * .cm , [class^="highlight"] * .cm { color: black; font-style: italic } /* Comment.Multiline */ +.codeblock * .cp , [class^="highlight"] * .cp { color: black; font-style: italic } /* Comment.Preproc */ +.codeblock * .c1 , [class^="highlight"] * .c1 { color: black; font-style: italic } /* Comment.Single */ +.codeblock * .cs , [class^="highlight"] * .cs { color: black; font-style: italic } /* Comment.Special */ +.codeblock * .ge , [class^="highlight"] * .ge { font-style: italic } /* Generic.Emph */ +.codeblock * .gh , [class^="highlight"] * .gh { font-weight: bold } /* Generic.Heading */ +.codeblock * .gp , [class^="highlight"] * .gp { font-weight: bold } /* Generic.Prompt */ +.codeblock * .gs , [class^="highlight"] * .gs { font-weight: bold } /* Generic.Strong */ +.codeblock * .gu , [class^="highlight"] * .gu { font-weight: bold } /* Generic.Subheading */ +.codeblock * .kc , [class^="highlight"] * .kc { color: black } /* Keyword.Constant */ +.codeblock * .kd , [class^="highlight"] * .kd { color: black } /* Keyword.Declaration */ +.codeblock * .kn , [class^="highlight"] * .kn { color: black } /* Keyword.Namespace */ +.codeblock * .kp , [class^="highlight"] * .kp { color: black } /* Keyword.Pseudo */ +.codeblock * .kr , [class^="highlight"] * .kr { color: black } /* Keyword.Reserved */ +.codeblock * .kt , [class^="highlight"] * .kt { color: black } /* Keyword.Type */ +.codeblock * .s , [class^="highlight"] * .s { color: black } /* Literal.String */ +.codeblock * .n , [class^="highlight"] * .n { font-weight: bold; font-style: italic } /* Name.Class */ +.codeblock * .nc , [class^="highlight"] * .nc { color: black } /* Name.Class */ +.codeblock * .ow , [class^="highlight"] * .ow { color: black } /* Operator.Word */ +.codeblock * .sb , [class^="highlight"] * .sb { color: black } /* Literal.String.Backtick */ +.codeblock * .sc , [class^="highlight"] * .sc { color: black } /* Literal.String.Char */ +.codeblock * .sd , [class^="highlight"] * .sd { color: black } /* Literal.String.Doc */ +.codeblock * .s2 , [class^="highlight"] * .s2 { color: black } /* Literal.String.Double */ +.codeblock * .se , [class^="highlight"] * .se { color: black } /* Literal.String.Escape */ +.codeblock * .sh , [class^="highlight"] * .sh { color: black } /* Literal.String.Heredoc */ +.codeblock * .si , [class^="highlight"] * .si { color: black } /* Literal.String.Interpol */ +.codeblock * .sx , [class^="highlight"] * .sx { color: black } /* Literal.String.Other */ +.codeblock * .sr , [class^="highlight"] * .sr { color: black } /* Literal.String.Regex */ +.codeblock * .s1 , [class^="highlight"] * .s1 { color: black } /* Literal.String.Single */ +.codeblock * .ss , [class^="highlight"] * .ss { color: black } /* Literal.String.Symbol */ diff --git a/documentation/_build/html/_static/searchtools.js b/documentation/_build/html/_static/searchtools.js new file mode 100644 index 00000000..663be4c9 --- /dev/null +++ b/documentation/_build/html/_static/searchtools.js @@ -0,0 +1,560 @@ +/* + * searchtools.js_t + * ~~~~~~~~~~~~~~~~ + * + * Sphinx JavaScript utilties for the full-text search. + * + * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/** + * helper function to return a node containing the + * search summary for a given text. keywords is a list + * of stemmed words, hlwords is the list of normal, unstemmed + * words. the first one is used to find the occurance, the + * latter for highlighting it. + */ + +jQuery.makeSearchSummary = function(text, keywords, hlwords) { + var textLower = text.toLowerCase(); + var start = 0; + $.each(keywords, function() { + var i = textLower.indexOf(this.toLowerCase()); + if (i > -1) + start = i; + }); + start = Math.max(start - 120, 0); + var excerpt = ((start > 0) ? '...' : '') + + $.trim(text.substr(start, 240)) + + ((start + 240 - text.length) ? '...' : ''); + var rv = $('
').text(excerpt); + $.each(hlwords, function() { + rv = rv.highlightText(this, 'highlighted'); + }); + return rv; +} + + +/** + * Porter Stemmer + */ +var Stemmer = function() { + + var step2list = { + ational: 'ate', + tional: 'tion', + enci: 'ence', + anci: 'ance', + izer: 'ize', + bli: 'ble', + alli: 'al', + entli: 'ent', + eli: 'e', + ousli: 'ous', + ization: 'ize', + ation: 'ate', + ator: 'ate', + alism: 'al', + iveness: 'ive', + fulness: 'ful', + ousness: 'ous', + aliti: 'al', + iviti: 'ive', + biliti: 'ble', + logi: 'log' + }; + + var step3list = { + icate: 'ic', + ative: '', + alize: 'al', + iciti: 'ic', + ical: 'ic', + ful: '', + ness: '' + }; + + var c = "[^aeiou]"; // consonant + var v = "[aeiouy]"; // vowel + var C = c + "[^aeiouy]*"; // consonant sequence + var V = v + "[aeiou]*"; // vowel sequence + + var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 + var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 + var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 + var s_v = "^(" + C + ")?" + v; // vowel in stem + + this.stemWord = function (w) { + var stem; + var suffix; + var firstch; + var origword = w; + + if (w.length < 3) + return w; + + var re; + var re2; + var re3; + var re4; + + firstch = w.substr(0,1); + if (firstch == "y") + w = firstch.toUpperCase() + w.substr(1); + + // Step 1a + re = /^(.+?)(ss|i)es$/; + re2 = /^(.+?)([^s])s$/; + + if (re.test(w)) + w = w.replace(re,"$1$2"); + else if (re2.test(w)) + w = w.replace(re2,"$1$2"); + + // Step 1b + re = /^(.+?)eed$/; + re2 = /^(.+?)(ed|ing)$/; + if (re.test(w)) { + var fp = re.exec(w); + re = new RegExp(mgr0); + if (re.test(fp[1])) { + re = /.$/; + w = w.replace(re,""); + } + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = new RegExp(s_v); + if (re2.test(stem)) { + w = stem; + re2 = /(at|bl|iz)$/; + re3 = new RegExp("([^aeiouylsz])\\1$"); + re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re2.test(w)) + w = w + "e"; + else if (re3.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + else if (re4.test(w)) + w = w + "e"; + } + } + + // Step 1c + re = /^(.+?)y$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(s_v); + if (re.test(stem)) + w = stem + "i"; + } + + // Step 2 + re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step2list[suffix]; + } + + // Step 3 + re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step3list[suffix]; + } + + // Step 4 + re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + re2 = /^(.+?)(s|t)(ion)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + if (re.test(stem)) + w = stem; + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = new RegExp(mgr1); + if (re2.test(stem)) + w = stem; + } + + // Step 5 + re = /^(.+?)e$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + re2 = new RegExp(meq1); + re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) + w = stem; + } + re = /ll$/; + re2 = new RegExp(mgr1); + if (re.test(w) && re2.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + + // and turn initial Y back to y + if (firstch == "y") + w = firstch.toLowerCase() + w.substr(1); + return w; + } +} + + +/** + * Search Module + */ +var Search = { + + _index : null, + _queued_query : null, + _pulse_status : -1, + + init : function() { + var params = $.getQueryParameters(); + if (params.q) { + var query = params.q[0]; + $('input[name="q"]')[0].value = query; + this.performSearch(query); + } + }, + + loadIndex : function(url) { + $.ajax({type: "GET", url: url, data: null, success: null, + dataType: "script", cache: true}); + }, + + setIndex : function(index) { + var q; + this._index = index; + if ((q = this._queued_query) !== null) { + this._queued_query = null; + Search.query(q); + } + }, + + hasIndex : function() { + return this._index !== null; + }, + + deferQuery : function(query) { + this._queued_query = query; + }, + + stopPulse : function() { + this._pulse_status = 0; + }, + + startPulse : function() { + if (this._pulse_status >= 0) + return; + function pulse() { + Search._pulse_status = (Search._pulse_status + 1) % 4; + var dotString = ''; + for (var i = 0; i < Search._pulse_status; i++) + dotString += '.'; + Search.dots.text(dotString); + if (Search._pulse_status > -1) + window.setTimeout(pulse, 500); + }; + pulse(); + }, + + /** + * perform a search for something + */ + performSearch : function(query) { + // create the required interface elements + this.out = $('#search-results'); + this.title = $('

' + _('Searching') + '

').appendTo(this.out); + this.dots = $('').appendTo(this.title); + this.status = $('

').appendTo(this.out); + this.output = $('