From 56d737adc398e0dee709ea156ebc533cb289805d Mon Sep 17 00:00:00 2001 From: chriswmackey Date: Sat, 2 Dec 2023 04:35:38 +0000 Subject: [PATCH] deploy: update docs --- .nojekyll | 0 README.md | 1 + docs/.buildinfo | 4 + docs/.doctrees/cli/compare.doctree | Bin 0 -> 19563 bytes docs/.doctrees/cli/create.doctree | Bin 0 -> 86453 bytes docs/.doctrees/cli/edit.doctree | Bin 0 -> 133884 bytes docs/.doctrees/cli/index.doctree | Bin 0 -> 4111 bytes docs/.doctrees/cli/lib.doctree | Bin 0 -> 10753 bytes docs/.doctrees/cli/main.doctree | Bin 0 -> 6789 bytes docs/.doctrees/cli/setconfig.doctree | Bin 0 -> 6147 bytes docs/.doctrees/cli/validate.doctree | Bin 0 -> 21690 bytes docs/.doctrees/environment.pickle | Bin 0 -> 1257734 bytes docs/.doctrees/honeybee.altnumber.doctree | Bin 0 -> 14933 bytes docs/.doctrees/honeybee.aperture.doctree | Bin 0 -> 217429 bytes .../honeybee.boundarycondition.doctree | Bin 0 -> 70869 bytes docs/.doctrees/honeybee.checkdup.doctree | Bin 0 -> 27623 bytes docs/.doctrees/honeybee.cli.compare.doctree | Bin 0 -> 3106 bytes docs/.doctrees/honeybee.cli.create.doctree | Bin 0 -> 3103 bytes docs/.doctrees/honeybee.cli.doctree | Bin 0 -> 11872 bytes docs/.doctrees/honeybee.cli.edit.doctree | Bin 0 -> 3079 bytes docs/.doctrees/honeybee.cli.lib.doctree | Bin 0 -> 2795 bytes docs/.doctrees/honeybee.cli.setconfig.doctree | Bin 0 -> 3160 bytes docs/.doctrees/honeybee.cli.validate.doctree | Bin 0 -> 3117 bytes docs/.doctrees/honeybee.colorobj.doctree | Bin 0 -> 62168 bytes docs/.doctrees/honeybee.config.doctree | Bin 0 -> 34904 bytes docs/.doctrees/honeybee.dictutil.doctree | Bin 0 -> 8717 bytes docs/.doctrees/honeybee.doctree | Bin 0 -> 4741 bytes docs/.doctrees/honeybee.door.doctree | Bin 0 -> 166216 bytes docs/.doctrees/honeybee.extensionutil.doctree | Bin 0 -> 41425 bytes docs/.doctrees/honeybee.face.doctree | Bin 0 -> 316279 bytes docs/.doctrees/honeybee.facetype.doctree | Bin 0 -> 27221 bytes docs/.doctrees/honeybee.logutil.doctree | Bin 0 -> 8909 bytes docs/.doctrees/honeybee.model.doctree | Bin 0 -> 481588 bytes docs/.doctrees/honeybee.orientation.doctree | Bin 0 -> 27527 bytes docs/.doctrees/honeybee.properties.doctree | Bin 0 -> 253867 bytes docs/.doctrees/honeybee.room.doctree | Bin 0 -> 420128 bytes docs/.doctrees/honeybee.search.doctree | Bin 0 -> 22046 bytes docs/.doctrees/honeybee.shade.doctree | Bin 0 -> 111829 bytes docs/.doctrees/honeybee.shademesh.doctree | Bin 0 -> 80200 bytes docs/.doctrees/honeybee.typing.doctree | Bin 0 -> 76687 bytes docs/.doctrees/honeybee.units.doctree | Bin 0 -> 12627 bytes .../honeybee.writer.aperture.doctree | Bin 0 -> 3960 bytes docs/.doctrees/honeybee.writer.doctree | Bin 0 -> 4945 bytes docs/.doctrees/honeybee.writer.door.doctree | Bin 0 -> 3884 bytes docs/.doctrees/honeybee.writer.face.doctree | Bin 0 -> 3884 bytes docs/.doctrees/honeybee.writer.model.doctree | Bin 0 -> 3903 bytes docs/.doctrees/honeybee.writer.room.doctree | Bin 0 -> 3884 bytes docs/.doctrees/honeybee.writer.shade.doctree | Bin 0 -> 3903 bytes .../honeybee.writer.shademesh.doctree | Bin 0 -> 3979 bytes docs/.doctrees/index.doctree | Bin 0 -> 12281 bytes docs/.doctrees/modules.doctree | Bin 0 -> 2714 bytes docs/.nojekyll | 0 docs/README.md | 1 + docs/_modules/honeybee/altnumber.html | 1157 ++ docs/_modules/honeybee/aperture.html | 1933 +++ docs/_modules/honeybee/boundarycondition.html | 1468 +++ docs/_modules/honeybee/checkdup.html | 1283 ++ docs/_modules/honeybee/colorobj.html | 1460 +++ docs/_modules/honeybee/config.html | 1457 +++ docs/_modules/honeybee/dictutil.html | 1164 ++ docs/_modules/honeybee/door.html | 1745 +++ docs/_modules/honeybee/extensionutil.html | 1318 ++ docs/_modules/honeybee/face.html | 2947 +++++ docs/_modules/honeybee/facetype.html | 1263 ++ docs/_modules/honeybee/logutil.html | 1189 ++ docs/_modules/honeybee/model.html | 4364 +++++++ docs/_modules/honeybee/orientation.html | 1242 ++ docs/_modules/honeybee/properties.html | 1874 +++ docs/_modules/honeybee/room.html | 3718 ++++++ docs/_modules/honeybee/search.html | 1211 ++ docs/_modules/honeybee/shade.html | 1590 +++ docs/_modules/honeybee/shademesh.html | 1454 +++ docs/_modules/honeybee/typing.html | 1523 +++ docs/_modules/honeybee/units.html | 1198 ++ docs/_modules/index.html | 1131 ++ docs/_sources/cli/compare.rst.txt | 6 + docs/_sources/cli/create.rst.txt | 6 + docs/_sources/cli/edit.rst.txt | 6 + docs/_sources/cli/index.rst.txt | 21 + docs/_sources/cli/lib.rst.txt | 6 + docs/_sources/cli/main.rst.txt | 7 + docs/_sources/cli/setconfig.rst.txt | 6 + docs/_sources/cli/validate.rst.txt | 6 + docs/_sources/honeybee.altnumber.rst.txt | 7 + docs/_sources/honeybee.aperture.rst.txt | 7 + .../honeybee.boundarycondition.rst.txt | 7 + docs/_sources/honeybee.checkdup.rst.txt | 7 + docs/_sources/honeybee.cli.compare.rst.txt | 7 + docs/_sources/honeybee.cli.create.rst.txt | 7 + docs/_sources/honeybee.cli.edit.rst.txt | 7 + docs/_sources/honeybee.cli.lib.rst.txt | 7 + docs/_sources/honeybee.cli.rst.txt | 23 + docs/_sources/honeybee.cli.setconfig.rst.txt | 7 + docs/_sources/honeybee.cli.validate.rst.txt | 7 + docs/_sources/honeybee.colorobj.rst.txt | 7 + docs/_sources/honeybee.config.rst.txt | 7 + docs/_sources/honeybee.dictutil.rst.txt | 7 + docs/_sources/honeybee.door.rst.txt | 7 + docs/_sources/honeybee.extensionutil.rst.txt | 7 + docs/_sources/honeybee.face.rst.txt | 7 + docs/_sources/honeybee.facetype.rst.txt | 7 + docs/_sources/honeybee.logutil.rst.txt | 7 + docs/_sources/honeybee.model.rst.txt | 7 + docs/_sources/honeybee.orientation.rst.txt | 7 + docs/_sources/honeybee.properties.rst.txt | 7 + docs/_sources/honeybee.room.rst.txt | 7 + docs/_sources/honeybee.rst.txt | 47 + docs/_sources/honeybee.search.rst.txt | 7 + docs/_sources/honeybee.shade.rst.txt | 7 + docs/_sources/honeybee.shademesh.rst.txt | 7 + docs/_sources/honeybee.typing.rst.txt | 7 + docs/_sources/honeybee.units.rst.txt | 7 + .../_sources/honeybee.writer.aperture.rst.txt | 7 + docs/_sources/honeybee.writer.door.rst.txt | 7 + docs/_sources/honeybee.writer.face.rst.txt | 7 + docs/_sources/honeybee.writer.model.rst.txt | 7 + docs/_sources/honeybee.writer.room.rst.txt | 7 + docs/_sources/honeybee.writer.rst.txt | 24 + docs/_sources/honeybee.writer.shade.rst.txt | 7 + .../honeybee.writer.shademesh.rst.txt | 7 + docs/_sources/index.rst.txt | 62 + docs/_sources/modules.rst.txt | 7 + .../_sphinx_javascript_frameworks_compat.js | 134 + docs/_static/basic.css | 899 ++ .../css/bootstrap-responsive.css | 1109 ++ .../css/bootstrap-responsive.min.css | 9 + .../_static/bootstrap-2.3.2/css/bootstrap.css | 6167 +++++++++ .../bootstrap-2.3.2/css/bootstrap.min.css | 9 + .../img/glyphicons-halflings-white.png | Bin 0 -> 8777 bytes .../img/glyphicons-halflings.png | Bin 0 -> 12799 bytes docs/_static/bootstrap-2.3.2/js/bootstrap.js | 2287 ++++ .../bootstrap-2.3.2/js/bootstrap.min.js | 6 + .../bootstrap-3.4.1/css/bootstrap-theme.css | 587 + .../css/bootstrap-theme.css.map | 1 + .../css/bootstrap-theme.min.css | 6 + .../css/bootstrap-theme.min.css.map | 1 + .../_static/bootstrap-3.4.1/css/bootstrap.css | 6834 ++++++++++ .../bootstrap-3.4.1/css/bootstrap.css.map | 1 + .../bootstrap-3.4.1/css/bootstrap.min.css | 6 + .../bootstrap-3.4.1/css/bootstrap.min.css.map | 1 + .../fonts/glyphicons-halflings-regular.eot | Bin 0 -> 20127 bytes .../fonts/glyphicons-halflings-regular.svg | 288 + .../fonts/glyphicons-halflings-regular.ttf | Bin 0 -> 45404 bytes .../fonts/glyphicons-halflings-regular.woff | Bin 0 -> 23424 bytes .../fonts/glyphicons-halflings-regular.woff2 | Bin 0 -> 18028 bytes docs/_static/bootstrap-3.4.1/js/bootstrap.js | 2580 ++++ .../bootstrap-3.4.1/js/bootstrap.min.js | 6 + docs/_static/bootstrap-3.4.1/js/npm.js | 13 + docs/_static/bootstrap-sphinx.css | 223 + docs/_static/bootstrap-sphinx.js | 175 + .../bootswatch-2.3.2/amelia/bootstrap.min.css | 9 + .../cerulean/bootstrap.min.css | 9 + .../bootswatch-2.3.2/cosmo/bootstrap.min.css | 9 + .../bootswatch-2.3.2/cyborg/bootstrap.min.css | 9 + .../bootswatch-2.3.2/flatly/bootstrap.min.css | 9 + .../img/glyphicons-halflings-white.png | Bin 0 -> 8777 bytes .../img/glyphicons-halflings.png | Bin 0 -> 12799 bytes .../journal/bootstrap.min.css | 9 + .../readable/bootstrap.min.css | 9 + .../simplex/bootstrap.min.css | 9 + .../bootswatch-2.3.2/slate/bootstrap.min.css | 9 + .../spacelab/bootstrap.min.css | 9 + .../bootswatch-2.3.2/spruce/bootstrap.min.css | 9 + .../superhero/bootstrap.min.css | 9 + .../bootswatch-2.3.2/united/bootstrap.min.css | 9 + .../cerulean/bootstrap.min.css | 11 + .../bootswatch-3.4.1/cosmo/bootstrap.min.css | 11 + .../bootswatch-3.4.1/cyborg/bootstrap.min.css | 11 + .../bootswatch-3.4.1/darkly/bootstrap.min.css | 11 + .../bootswatch-3.4.1/flatly/bootstrap.min.css | 11 + .../fonts/glyphicons-halflings-regular.eot | Bin 0 -> 20127 bytes .../fonts/glyphicons-halflings-regular.svg | 288 + .../fonts/glyphicons-halflings-regular.ttf | Bin 0 -> 45404 bytes .../fonts/glyphicons-halflings-regular.woff | Bin 0 -> 23424 bytes .../fonts/glyphicons-halflings-regular.woff2 | Bin 0 -> 18028 bytes .../journal/bootstrap.min.css | 11 + .../bootswatch-3.4.1/lumen/bootstrap.min.css | 11 + .../bootswatch-3.4.1/paper/bootstrap.min.css | 11 + .../readable/bootstrap.min.css | 11 + .../sandstone/bootstrap.min.css | 11 + .../simplex/bootstrap.min.css | 11 + .../bootswatch-3.4.1/slate/bootstrap.min.css | 11 + .../spacelab/bootstrap.min.css | 11 + .../superhero/bootstrap.min.css | 11 + .../bootswatch-3.4.1/united/bootstrap.min.css | 11 + .../bootswatch-3.4.1/yeti/bootstrap.min.css | 11 + docs/_static/custom.css | 48 + docs/_static/doctools.js | 156 + docs/_static/documentation_options.js | 14 + docs/_static/file.png | Bin 0 -> 286 bytes docs/_static/jquery-3.6.0.js | 10881 ++++++++++++++++ docs/_static/jquery.js | 2 + docs/_static/js/jquery-1.12.4.min.js | 5 + docs/_static/js/jquery-fix.js | 2 + docs/_static/language_data.js | 199 + docs/_static/minus.png | Bin 0 -> 90 bytes docs/_static/plus.png | Bin 0 -> 90 bytes docs/_static/pygments.css | 84 + docs/_static/searchtools.js | 566 + docs/_static/sphinx_highlight.js | 144 + docs/_static/underscore-1.13.1.js | 2042 +++ docs/_static/underscore.js | 6 + docs/cli/compare.html | 1254 ++ docs/cli/create.html | 1624 +++ docs/cli/edit.html | 1850 +++ docs/cli/index.html | 1172 ++ docs/cli/lib.html | 1210 ++ docs/cli/main.html | 1206 ++ docs/cli/setconfig.html | 1196 ++ docs/cli/validate.html | 1270 ++ docs/genindex.html | 4873 +++++++ docs/honeybee.altnumber.html | 1265 ++ docs/honeybee.aperture.html | 2188 ++++ docs/honeybee.boundarycondition.html | 1529 +++ docs/honeybee.checkdup.html | 1273 ++ docs/honeybee.cli.compare.html | 1176 ++ docs/honeybee.cli.create.html | 1176 ++ docs/honeybee.cli.edit.html | 1176 ++ docs/honeybee.cli.html | 1240 ++ docs/honeybee.cli.lib.html | 1175 ++ docs/honeybee.cli.setconfig.html | 1176 ++ docs/honeybee.cli.validate.html | 1176 ++ docs/honeybee.colorobj.html | 1499 +++ docs/honeybee.config.html | 1360 ++ docs/honeybee.dictutil.html | 1221 ++ docs/honeybee.door.html | 2030 +++ docs/honeybee.extensionutil.html | 1349 ++ docs/honeybee.face.html | 2676 ++++ docs/honeybee.facetype.html | 1333 ++ docs/honeybee.html | 2101 +++ docs/honeybee.logutil.html | 1213 ++ docs/honeybee.model.html | 3329 +++++ docs/honeybee.orientation.html | 1321 ++ docs/honeybee.properties.html | 2572 ++++ docs/honeybee.room.html | 3114 +++++ docs/honeybee.search.html | 1275 ++ docs/honeybee.shade.html | 1750 +++ docs/honeybee.shademesh.html | 1595 +++ docs/honeybee.typing.html | 1468 +++ docs/honeybee.units.html | 1238 ++ docs/honeybee.writer.aperture.html | 1181 ++ docs/honeybee.writer.door.html | 1181 ++ docs/honeybee.writer.face.html | 1181 ++ docs/honeybee.writer.html | 1199 ++ docs/honeybee.writer.model.html | 1181 ++ docs/honeybee.writer.room.html | 1181 ++ docs/honeybee.writer.shade.html | 1181 ++ docs/honeybee.writer.shademesh.html | 1181 ++ docs/index.html | 1210 ++ docs/modules.html | 1295 ++ docs/objects.inv | Bin 0 -> 7417 bytes docs/py-modindex.html | 1310 ++ docs/search.html | 1137 ++ docs/searchindex.js | 1 + 254 files changed, 151300 insertions(+) create mode 100644 .nojekyll create mode 100644 README.md create mode 100644 docs/.buildinfo create mode 100644 docs/.doctrees/cli/compare.doctree create mode 100644 docs/.doctrees/cli/create.doctree create mode 100644 docs/.doctrees/cli/edit.doctree create mode 100644 docs/.doctrees/cli/index.doctree create mode 100644 docs/.doctrees/cli/lib.doctree create mode 100644 docs/.doctrees/cli/main.doctree create mode 100644 docs/.doctrees/cli/setconfig.doctree create mode 100644 docs/.doctrees/cli/validate.doctree create mode 100644 docs/.doctrees/environment.pickle create mode 100644 docs/.doctrees/honeybee.altnumber.doctree create mode 100644 docs/.doctrees/honeybee.aperture.doctree create mode 100644 docs/.doctrees/honeybee.boundarycondition.doctree create mode 100644 docs/.doctrees/honeybee.checkdup.doctree create mode 100644 docs/.doctrees/honeybee.cli.compare.doctree create mode 100644 docs/.doctrees/honeybee.cli.create.doctree create mode 100644 docs/.doctrees/honeybee.cli.doctree create mode 100644 docs/.doctrees/honeybee.cli.edit.doctree create mode 100644 docs/.doctrees/honeybee.cli.lib.doctree create mode 100644 docs/.doctrees/honeybee.cli.setconfig.doctree create mode 100644 docs/.doctrees/honeybee.cli.validate.doctree create mode 100644 docs/.doctrees/honeybee.colorobj.doctree create mode 100644 docs/.doctrees/honeybee.config.doctree create mode 100644 docs/.doctrees/honeybee.dictutil.doctree create mode 100644 docs/.doctrees/honeybee.doctree create mode 100644 docs/.doctrees/honeybee.door.doctree create mode 100644 docs/.doctrees/honeybee.extensionutil.doctree create mode 100644 docs/.doctrees/honeybee.face.doctree create mode 100644 docs/.doctrees/honeybee.facetype.doctree create mode 100644 docs/.doctrees/honeybee.logutil.doctree create mode 100644 docs/.doctrees/honeybee.model.doctree create mode 100644 docs/.doctrees/honeybee.orientation.doctree create mode 100644 docs/.doctrees/honeybee.properties.doctree create mode 100644 docs/.doctrees/honeybee.room.doctree create mode 100644 docs/.doctrees/honeybee.search.doctree create mode 100644 docs/.doctrees/honeybee.shade.doctree create mode 100644 docs/.doctrees/honeybee.shademesh.doctree create mode 100644 docs/.doctrees/honeybee.typing.doctree create mode 100644 docs/.doctrees/honeybee.units.doctree create mode 100644 docs/.doctrees/honeybee.writer.aperture.doctree create mode 100644 docs/.doctrees/honeybee.writer.doctree create mode 100644 docs/.doctrees/honeybee.writer.door.doctree create mode 100644 docs/.doctrees/honeybee.writer.face.doctree create mode 100644 docs/.doctrees/honeybee.writer.model.doctree create mode 100644 docs/.doctrees/honeybee.writer.room.doctree create mode 100644 docs/.doctrees/honeybee.writer.shade.doctree create mode 100644 docs/.doctrees/honeybee.writer.shademesh.doctree create mode 100644 docs/.doctrees/index.doctree create mode 100644 docs/.doctrees/modules.doctree create mode 100644 docs/.nojekyll create mode 100644 docs/README.md create mode 100644 docs/_modules/honeybee/altnumber.html create mode 100644 docs/_modules/honeybee/aperture.html create mode 100644 docs/_modules/honeybee/boundarycondition.html create mode 100644 docs/_modules/honeybee/checkdup.html create mode 100644 docs/_modules/honeybee/colorobj.html create mode 100644 docs/_modules/honeybee/config.html create mode 100644 docs/_modules/honeybee/dictutil.html create mode 100644 docs/_modules/honeybee/door.html create mode 100644 docs/_modules/honeybee/extensionutil.html create mode 100644 docs/_modules/honeybee/face.html create mode 100644 docs/_modules/honeybee/facetype.html create mode 100644 docs/_modules/honeybee/logutil.html create mode 100644 docs/_modules/honeybee/model.html create mode 100644 docs/_modules/honeybee/orientation.html create mode 100644 docs/_modules/honeybee/properties.html create mode 100644 docs/_modules/honeybee/room.html create mode 100644 docs/_modules/honeybee/search.html create mode 100644 docs/_modules/honeybee/shade.html create mode 100644 docs/_modules/honeybee/shademesh.html create mode 100644 docs/_modules/honeybee/typing.html create mode 100644 docs/_modules/honeybee/units.html create mode 100644 docs/_modules/index.html create mode 100644 docs/_sources/cli/compare.rst.txt create mode 100644 docs/_sources/cli/create.rst.txt create mode 100644 docs/_sources/cli/edit.rst.txt create mode 100644 docs/_sources/cli/index.rst.txt create mode 100644 docs/_sources/cli/lib.rst.txt create mode 100644 docs/_sources/cli/main.rst.txt create mode 100644 docs/_sources/cli/setconfig.rst.txt create mode 100644 docs/_sources/cli/validate.rst.txt create mode 100644 docs/_sources/honeybee.altnumber.rst.txt create mode 100644 docs/_sources/honeybee.aperture.rst.txt create mode 100644 docs/_sources/honeybee.boundarycondition.rst.txt create mode 100644 docs/_sources/honeybee.checkdup.rst.txt create mode 100644 docs/_sources/honeybee.cli.compare.rst.txt create mode 100644 docs/_sources/honeybee.cli.create.rst.txt create mode 100644 docs/_sources/honeybee.cli.edit.rst.txt create mode 100644 docs/_sources/honeybee.cli.lib.rst.txt create mode 100644 docs/_sources/honeybee.cli.rst.txt create mode 100644 docs/_sources/honeybee.cli.setconfig.rst.txt create mode 100644 docs/_sources/honeybee.cli.validate.rst.txt create mode 100644 docs/_sources/honeybee.colorobj.rst.txt create mode 100644 docs/_sources/honeybee.config.rst.txt create mode 100644 docs/_sources/honeybee.dictutil.rst.txt create mode 100644 docs/_sources/honeybee.door.rst.txt create mode 100644 docs/_sources/honeybee.extensionutil.rst.txt create mode 100644 docs/_sources/honeybee.face.rst.txt create mode 100644 docs/_sources/honeybee.facetype.rst.txt create mode 100644 docs/_sources/honeybee.logutil.rst.txt create mode 100644 docs/_sources/honeybee.model.rst.txt create mode 100644 docs/_sources/honeybee.orientation.rst.txt create mode 100644 docs/_sources/honeybee.properties.rst.txt create mode 100644 docs/_sources/honeybee.room.rst.txt create mode 100644 docs/_sources/honeybee.rst.txt create mode 100644 docs/_sources/honeybee.search.rst.txt create mode 100644 docs/_sources/honeybee.shade.rst.txt create mode 100644 docs/_sources/honeybee.shademesh.rst.txt create mode 100644 docs/_sources/honeybee.typing.rst.txt create mode 100644 docs/_sources/honeybee.units.rst.txt create mode 100644 docs/_sources/honeybee.writer.aperture.rst.txt create mode 100644 docs/_sources/honeybee.writer.door.rst.txt create mode 100644 docs/_sources/honeybee.writer.face.rst.txt create mode 100644 docs/_sources/honeybee.writer.model.rst.txt create mode 100644 docs/_sources/honeybee.writer.room.rst.txt create mode 100644 docs/_sources/honeybee.writer.rst.txt create mode 100644 docs/_sources/honeybee.writer.shade.rst.txt create mode 100644 docs/_sources/honeybee.writer.shademesh.rst.txt create mode 100644 docs/_sources/index.rst.txt create mode 100644 docs/_sources/modules.rst.txt create mode 100644 docs/_static/_sphinx_javascript_frameworks_compat.js create mode 100644 docs/_static/basic.css create mode 100644 docs/_static/bootstrap-2.3.2/css/bootstrap-responsive.css create mode 100644 docs/_static/bootstrap-2.3.2/css/bootstrap-responsive.min.css create mode 100644 docs/_static/bootstrap-2.3.2/css/bootstrap.css create mode 100644 docs/_static/bootstrap-2.3.2/css/bootstrap.min.css create mode 100644 docs/_static/bootstrap-2.3.2/img/glyphicons-halflings-white.png create mode 100644 docs/_static/bootstrap-2.3.2/img/glyphicons-halflings.png create mode 100644 docs/_static/bootstrap-2.3.2/js/bootstrap.js create mode 100644 docs/_static/bootstrap-2.3.2/js/bootstrap.min.js create mode 100644 docs/_static/bootstrap-3.4.1/css/bootstrap-theme.css create mode 100644 docs/_static/bootstrap-3.4.1/css/bootstrap-theme.css.map create mode 100644 docs/_static/bootstrap-3.4.1/css/bootstrap-theme.min.css create mode 100644 docs/_static/bootstrap-3.4.1/css/bootstrap-theme.min.css.map create mode 100644 docs/_static/bootstrap-3.4.1/css/bootstrap.css create mode 100644 docs/_static/bootstrap-3.4.1/css/bootstrap.css.map create mode 100644 docs/_static/bootstrap-3.4.1/css/bootstrap.min.css create mode 100644 docs/_static/bootstrap-3.4.1/css/bootstrap.min.css.map create mode 100644 docs/_static/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.eot create mode 100644 docs/_static/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.svg create mode 100644 docs/_static/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.ttf create mode 100644 docs/_static/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.woff create mode 100644 docs/_static/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.woff2 create mode 100644 docs/_static/bootstrap-3.4.1/js/bootstrap.js create mode 100644 docs/_static/bootstrap-3.4.1/js/bootstrap.min.js create mode 100644 docs/_static/bootstrap-3.4.1/js/npm.js create mode 100644 docs/_static/bootstrap-sphinx.css create mode 100644 docs/_static/bootstrap-sphinx.js create mode 100644 docs/_static/bootswatch-2.3.2/amelia/bootstrap.min.css create mode 100644 docs/_static/bootswatch-2.3.2/cerulean/bootstrap.min.css create mode 100644 docs/_static/bootswatch-2.3.2/cosmo/bootstrap.min.css create mode 100644 docs/_static/bootswatch-2.3.2/cyborg/bootstrap.min.css create mode 100644 docs/_static/bootswatch-2.3.2/flatly/bootstrap.min.css create mode 100644 docs/_static/bootswatch-2.3.2/img/glyphicons-halflings-white.png create mode 100644 docs/_static/bootswatch-2.3.2/img/glyphicons-halflings.png create mode 100644 docs/_static/bootswatch-2.3.2/journal/bootstrap.min.css create mode 100644 docs/_static/bootswatch-2.3.2/readable/bootstrap.min.css create mode 100644 docs/_static/bootswatch-2.3.2/simplex/bootstrap.min.css create mode 100644 docs/_static/bootswatch-2.3.2/slate/bootstrap.min.css create mode 100644 docs/_static/bootswatch-2.3.2/spacelab/bootstrap.min.css create mode 100644 docs/_static/bootswatch-2.3.2/spruce/bootstrap.min.css create mode 100644 docs/_static/bootswatch-2.3.2/superhero/bootstrap.min.css create mode 100644 docs/_static/bootswatch-2.3.2/united/bootstrap.min.css create mode 100644 docs/_static/bootswatch-3.4.1/cerulean/bootstrap.min.css create mode 100644 docs/_static/bootswatch-3.4.1/cosmo/bootstrap.min.css create mode 100644 docs/_static/bootswatch-3.4.1/cyborg/bootstrap.min.css create mode 100644 docs/_static/bootswatch-3.4.1/darkly/bootstrap.min.css create mode 100644 docs/_static/bootswatch-3.4.1/flatly/bootstrap.min.css create mode 100644 docs/_static/bootswatch-3.4.1/fonts/glyphicons-halflings-regular.eot create mode 100644 docs/_static/bootswatch-3.4.1/fonts/glyphicons-halflings-regular.svg create mode 100644 docs/_static/bootswatch-3.4.1/fonts/glyphicons-halflings-regular.ttf create mode 100644 docs/_static/bootswatch-3.4.1/fonts/glyphicons-halflings-regular.woff create mode 100644 docs/_static/bootswatch-3.4.1/fonts/glyphicons-halflings-regular.woff2 create mode 100644 docs/_static/bootswatch-3.4.1/journal/bootstrap.min.css create mode 100644 docs/_static/bootswatch-3.4.1/lumen/bootstrap.min.css create mode 100644 docs/_static/bootswatch-3.4.1/paper/bootstrap.min.css create mode 100644 docs/_static/bootswatch-3.4.1/readable/bootstrap.min.css create mode 100644 docs/_static/bootswatch-3.4.1/sandstone/bootstrap.min.css create mode 100644 docs/_static/bootswatch-3.4.1/simplex/bootstrap.min.css create mode 100644 docs/_static/bootswatch-3.4.1/slate/bootstrap.min.css create mode 100644 docs/_static/bootswatch-3.4.1/spacelab/bootstrap.min.css create mode 100644 docs/_static/bootswatch-3.4.1/superhero/bootstrap.min.css create mode 100644 docs/_static/bootswatch-3.4.1/united/bootstrap.min.css create mode 100644 docs/_static/bootswatch-3.4.1/yeti/bootstrap.min.css create mode 100644 docs/_static/custom.css create mode 100644 docs/_static/doctools.js create mode 100644 docs/_static/documentation_options.js create mode 100644 docs/_static/file.png create mode 100644 docs/_static/jquery-3.6.0.js create mode 100644 docs/_static/jquery.js create mode 100644 docs/_static/js/jquery-1.12.4.min.js create mode 100644 docs/_static/js/jquery-fix.js create mode 100644 docs/_static/language_data.js create mode 100644 docs/_static/minus.png create mode 100644 docs/_static/plus.png create mode 100644 docs/_static/pygments.css create mode 100644 docs/_static/searchtools.js create mode 100644 docs/_static/sphinx_highlight.js create mode 100644 docs/_static/underscore-1.13.1.js create mode 100644 docs/_static/underscore.js create mode 100644 docs/cli/compare.html create mode 100644 docs/cli/create.html create mode 100644 docs/cli/edit.html create mode 100644 docs/cli/index.html create mode 100644 docs/cli/lib.html create mode 100644 docs/cli/main.html create mode 100644 docs/cli/setconfig.html create mode 100644 docs/cli/validate.html create mode 100644 docs/genindex.html create mode 100644 docs/honeybee.altnumber.html create mode 100644 docs/honeybee.aperture.html create mode 100644 docs/honeybee.boundarycondition.html create mode 100644 docs/honeybee.checkdup.html create mode 100644 docs/honeybee.cli.compare.html create mode 100644 docs/honeybee.cli.create.html create mode 100644 docs/honeybee.cli.edit.html create mode 100644 docs/honeybee.cli.html create mode 100644 docs/honeybee.cli.lib.html create mode 100644 docs/honeybee.cli.setconfig.html create mode 100644 docs/honeybee.cli.validate.html create mode 100644 docs/honeybee.colorobj.html create mode 100644 docs/honeybee.config.html create mode 100644 docs/honeybee.dictutil.html create mode 100644 docs/honeybee.door.html create mode 100644 docs/honeybee.extensionutil.html create mode 100644 docs/honeybee.face.html create mode 100644 docs/honeybee.facetype.html create mode 100644 docs/honeybee.html create mode 100644 docs/honeybee.logutil.html create mode 100644 docs/honeybee.model.html create mode 100644 docs/honeybee.orientation.html create mode 100644 docs/honeybee.properties.html create mode 100644 docs/honeybee.room.html create mode 100644 docs/honeybee.search.html create mode 100644 docs/honeybee.shade.html create mode 100644 docs/honeybee.shademesh.html create mode 100644 docs/honeybee.typing.html create mode 100644 docs/honeybee.units.html create mode 100644 docs/honeybee.writer.aperture.html create mode 100644 docs/honeybee.writer.door.html create mode 100644 docs/honeybee.writer.face.html create mode 100644 docs/honeybee.writer.html create mode 100644 docs/honeybee.writer.model.html create mode 100644 docs/honeybee.writer.room.html create mode 100644 docs/honeybee.writer.shade.html create mode 100644 docs/honeybee.writer.shademesh.html create mode 100644 docs/index.html create mode 100644 docs/modules.html create mode 100644 docs/objects.inv create mode 100644 docs/py-modindex.html create mode 100644 docs/search.html create mode 100644 docs/searchindex.js diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/README.md b/README.md new file mode 100644 index 00000000..ebfb3665 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# documentation diff --git a/docs/.buildinfo b/docs/.buildinfo new file mode 100644 index 00000000..e7a0a40d --- /dev/null +++ b/docs/.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: 3951c8d651649f76fb7c570403bfbf09 +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/docs/.doctrees/cli/compare.doctree b/docs/.doctrees/cli/compare.doctree new file mode 100644 index 0000000000000000000000000000000000000000..0876d28249e5c90fb2f8627480d487c6f4d4d813 GIT binary patch literal 19563 zcmd^HeT-elRbQ{YyWaKg+M5s)w6S~RsLe+B?K+f?;uI&gW2dR(bsIYnS|!)_y*qF3 zoxShfm;2$}MG6g+RIwQT>IJD%tD>liK>Pu%1Vu=E{86AGMW6yjr2<6%0R$mxK?n&6 z@jEkj=HB~0_Pu9sS_drc^W3>JXU;iu=FB-~&YhPI{NnYeCgeYHIPQ3UdwbP!-FE1* zI1>lmu#vV{JIOwoJ@hl#i`j~pjhwAGOrr+N!~|M2JU?(F*3O>G#3D6M{2*S<`_IIz zk@#WTboZvbX>aDaY{i=uQ;DAhtn^CEG{RQLiC9KW(Bi-~woOA9FJ8_h765a%n5L#c z&07+)wn5a}FQ#++*2RIqZ?kMYtvh1QNs`E~rwQmHI`;c+OgPUp0w<19iSkt2X{pjd zH|-P;b*Hfzu_m=i#Z2OC(5uWl>@9oq-hJMF@0d8Z=7lY`7NzYri`KTnXcHA}wo_-U z)(9ik^#pX|wMO8t*QhZLs^Rvpn5;)sT6RXBCD&x?Xn(?Ii-LUY|a zPR#J$1rB)kgU1ix@7?%&5PuJWI`8`>RWT|2BhN$s66@<~0e0aBs z5VPB@;B?$^Xqg@CL@Z{}4HT!qZB*S92Lq?Qkvbbx7kexSu=+fI!wc}2*iN)TQclx( z#XIIFI znC1G-Cd0CBu-K}zWQ(yj>iyV~xLJ@m{Do*4nMv3ya0Q(^KzwU-I!W%nw?}+5GZpKb z5Wj*0U%UoVF{x>g5aBr|w)`Nl!gjD@fkI{_VW$?b8w_=7ErAgZ7#9^>O6CUeh*+t( zWIfpg$8r#s=fniuYIqPI23`VQ5S*Mt`?lpLmPCOX#9p{%r5(#B_7ko&SBB;9Sp17Q zeg$*xQ$Jj8fP84=nl=v)uNNQN-G(0P8%E^FWSQWuA^KwVvQtE6#ViLp4q@b*{?I*E?Z6^r>D0AqF>Y^wq4y>ZBQ0b01mvVxmAdoUCKuG2qMI#qN z;%qX^1ZyytG!khaS}AH}*-9hHhINK5uzdp)hUtbJpi$g^6zK0cBPD7R_v5f_X7K+3 zrGGwBLqQ zB-y12^!x&L*^^KY6HxP?*BhP2<2QAMxKMXurUd7-buopy?>LD^65|w>lM?c#AJ7&6 zS+>%cG&K|qM2`Sy8ukcU!Gk{mC0`zc2i})19YB{q98A1d(7uQT)<@vGs|#$t0nlF` z51WJN^0fk+-3{H}Ak;Bm1&U9|Epxp2+46j7W<51Z)#wS@Gk674-U8BZj>nYIr)a5A zX3`IHjausS#^A&!_D#?l_@D96qPhC-G3Scy>bcN_ej%+7Z$umThs>fpH^6i&IRNL* zUcF#nzVi5mr|gSQK6Syma_s{bo-S4B3EvA)hObZ`%ltTayPKon+1_=}x#`ul8{oNx z-Cs6XX2o=r)+4`Bc6w&6bjUq7Cck+$Nbnz!lgm%hf6~<*!H49lN+MwV8?87YrbuCK zmxfpRap07S8K~C?77*O-l@)QIe~&gj{KTP=mOrVMS;E##0|v?W-fr0Wr@R`c79 zAaz*{h6BUyoQa1UEmys+4FJ{C$D3YHvK4*_REe@9Kf?HK#xD~yN)Uc*z_0@;*k~hw zU$)F*W`GJNP!MnWaYpGEd%1l^O76< zBL<){+9h-5CE66+qUcS5c^@%c5r=3uohfHy|lOrEqfU#M7R z#ES;+eyePSZ{t1R!B1b}2V-DYFsQi(0~D(m{QM9MHVK1Z5C#L;U*SPNhTk%2W#;ma z5%v^2JSuvb`|1$V_Jp}d`mP$_)BB>z_+KA_-JQnxVwYW!8c94bT(3g=o*Le&OY1NS zQX*c91(}ICT9zstl2z7#IEXj~El#;x@H)83e}R5Jj~^!H>?Ca1aKn>0dkEoTdXh`o zncJTQ#^ay=aQX6pZ;F=e4@FF@}M0LJ$F>nyY3RU=K%VV$#qpsjhr^B2` zM^(s}&jVWsOv}Jb9&eF`X#NVJm^5(75zrBZRqM&bf~yM0pqU0VVwGnW##V8gG92`# zIAWW8X9_YoR-D#jgyQnBLL-eRo~}kUmf!y^qRg7(-=H~O=3mdJT8AljcNq}rGeYvU zLP+3fMNcu~vZjOZpw`qgkLS;Z0=aYk`#9+H zZz-Dpjs8=FkiTkhsE6)O2}g18`t@s3%C28mNEkuqQ>Z_oEB(8P`*UIYKvf@L^N;QvgIQbFu0 zFZ>^=-7?prqJ^x`oqY~q_+P3{S_x^9>qe1OVgijit&G_&bvW&YEyr(X{4|IZGf5w?^{kFqg7raA9q{KF(QC3F6faj{oMwL-pt)@97| zYdt(&;Xhfb6Au*jwuA+P-62?{@6~mTJ zHoMJfy)eH!gBz*jZxEN3`Rh5ew7IaWjZv|B{-|K{KlQMgzu8l@!oOXr8`bFi+i~#I zM(5v9Cu4N-Njz#P7;I?1Nu6M5@j*O`QhrRApnNWM968PUF~@|1!M2 zwl9hDZsV;Ri!S@}uX7THV5IF!J?&ax3Qe(#eW{n^E!mg+QDDfe{rGu|O7~OgtSOyC z=_Wrfe;=pcy*C zwwZWutya(i`;e23D1r8|4d=^^wN|WF8f_*0&oe~bz_m7_Re0I}F}r&?s@KP(7%>t$ z1n}-w;WGxS{^r3*hD#p|x~xL3**sa}T~=Xz2nHirg?%u%1DLxrgtR?j?sQ4eu~+EF zssw*x2qt$LlMCIxB6Z6sRv^#Bdxon#sT4-D{vHFjyB}u7xXvv~Oc1;U;zA9b9u|9b9%DT>c^V@O49G8NfQXg8h z6(Eq>M0!?2AyjI7QXb^z1F0~xN{OQw2=))OMUsybAa7156R%p=fZGYJ)on`lJt6ZH zi@Lbsv6h2c)5|2iX z2h)E_CO|375saputxmF|fugf+sAgviDJyZ>AS@B39)PGsF+Ne{vIFvC8J8~2pvp9s zd2oJPG6ICfDMNZ(ieulLL-H^fV_EeO$zj0J@Z9i5_RU9>iI&>CpqWs~H{h5W0ZC?P zqJ!bjlCSfQl+SOz^y!L(e)FZzNEt2HD=C$4zEg6F;Y*TAL*K!&3S^bE5}q)KXBYyy2oIwC98!-B~gP|p)8P&6tOD!1$W-D`mCvGX?s@b1pv zdkt2%;r#W%pyK>3R3=07xvRFy^2dhYHIlc|2d}bAC>Hz31x3@ls;ii-55a6CkFFQ9 zLglPT(HFJhj!a3yaVkpLBg3NE$ALUQho7OY%sn}oeO;N-7e0~7tc0te6S);u(%gqR z9BAhS7Jt8Qo>Wrfs&#J1$}<7X=Q*&wJ22zP%K=PsU2qPJk`|!v#?VFGFD@7hNnlj{k&jqT>AF{0XTK1L`N`cPA4-H?4_zbbu-B0da4#k6u%+=wC-G_U?U{k8@ zRs3_rPPJF{G&j7L8`o>QGJeFU<*NqB9&cQ|fXhnoGZ=PM-cx>=N{?2?!zjv7ve6lK zp7+_D_+e^r>1p;t>PHli$ybKfQhnZ-N#d^)_+|dbhQM3ZwH zO62b_qEaG%PbH~DWN8#7@@Pqk^a*#DDXk>XsD(UULV3@(3*v`ITgg2gZ*3_b>4np~ zmj9FHPp#$N_C`+RV*amus{3ov5f}4+7$AGRn0o=27xP;fc2xGu1Maa`Gcj`LYW`ME z{oAyfm#5@v{yzF|pu13(aqJG2)qFJXIm~U%Gv_opx3QW}VMMi>AEuIA&9XGYYAzWFergG7aeHOC79-&hS>`&zqdl^)e=~9 z1xJBlsj3U3{c1YpH$J$zVz8<;S8{kKX>Rw4#XKj&Hdl4b>l$@s2fq1W34I)oTS%77 zwIcX@n$oZ->+#2(AVspbNtr#oE@n3vF5hsHFv{?NGXfSTPOF25Luwf0=e9TTIF~=B zQGllfN(QGZKIkomn^K96;;v>GCKPNdy}YzfEYO`M?X+cY(`iG7nnen$cM$n+(N!ri zKrX8qd~zgf>@7d>Y<}V%2+AWLUJr;^n&nCig^$dV+qL9 z6aZbwo5^U6ysu`l!#Xx-$}h}7n|Z2{9~qNui+jB!>BOhk)=(Xs$XV=WW+ zP)qVnZM3u#9OVR9Fm%}n>(t(T>IcD&#i-fn0#7vs`1fe=bcF#)+$OH&@LAH7V_?;; zc}Xk4V6%x+$0BeOFS~S59D_);Y_qxy0k*pD| zEWIVt7FZGO4J@$0Z}~}f`N)IfNW6pdx^3Ish?3zdppZm=K5pS75c`D`>pBL&yXCWb zv~eel6QCMb0Ug5)86XG~uhtu;QVxaQn`sA$(RA05yuc{e12-W(VZ(1XAp=@5+(oJa zA6ay@^IN#L1%o+iHPR(Tn;B%LRc9`i@D5P$7)vn7Jq@(lv~hUo2R2e0@%;u}RrHEj z$}d)eum(+~){wicAV}~rdhciL8+7@RIH=SM)-yyCncgtSA&3b~at3t;YM1Cs5MYVR zo4{@a9O(8KaaW~QeO!ZTKx>+ZXtxNDgA*dQFaZd6bJrUQ~G67qF5=Xm=b^9 zl*oVL9VKHxptGO0IzuQb=+p4mCoY56dgL zu+hz&&+9*lnRz*T8Y>=ONYMoa5HpCV8qnyvO7$UAEv4#E{+TVLdV>UN&Lwr6Yc8@9 I()#NE0+bI9%m4rY literal 0 HcmV?d00001 diff --git a/docs/.doctrees/cli/create.doctree b/docs/.doctrees/cli/create.doctree new file mode 100644 index 0000000000000000000000000000000000000000..73c72ec906b54197101192e3e755725a410b5e1a GIT binary patch literal 86453 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 VQ>U@>UQi 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 E0k26$+5i9m literal 0 HcmV?d00001 diff --git a/docs/.doctrees/environment.pickle b/docs/.doctrees/environment.pickle new file mode 100644 index 0000000000000000000000000000000000000000..a0a3d5d46eb2cc18845e2ada4eabea0312107eec GIT binary patch literal 1257734 zcmeEv3Ah|pm46_6^0MyNt6~I@&zHzfc}_`m2pn$*K15E?0NJfs!*a;5fax za@A@120yL!X9n0U`uV^6e6ZSRb4sn6V8g0(?W zoNCq0J2ha{oZ;-LJEfXiF4ac21Ie&Z_SE~bjd~gE8;u=g20JwDu>s5E4 zZ?I7;)|t6cm{PVNKYnv!$U1H}gOTu9;e?mOUp2?4|{7 z9Bod|l`A7vcc=h|7aVuYacht6-jvOc3^aziFDaLc%ym#wg)+!tR?CU0Rj24=Yd~TG zfJ2F}f*vjOG-ubH;Yu+JC7G$P0@)6p$b`p6v*5;ZqndLvwZ`C}yJxgHGgmGa!7}cs z=FBbCyi;}Z8(gpzJiB$YIjOG-UfEo0&KSP|JoJvZ4cTxUIG*QOrAbaF4t@IYPJH-mM21kujnsV>Y!D)TfPnj zk;~=^PXEOtP!y&9wS6b`9eYy$o)eGnFS-N$6@C;B_Sf9H(_6{rb}%3I`#uTp4rE4Pj=z>W>@gLKKKDVSHair4gQ5- z9+T%0%_+m#QX^X&t%I@C;om@lJ#ieSu&QvycDN|J@c?#u9$>kp!7|fZ^lt33!V!g4 z&F(EFryI)F>4uP#tGe8o-Q~e<|5@t;+84RCoKu8{(J41-{H`;cN@E~Xck7@_0GZFf z1|lAGi`<&#%$k#}<_dmkHRrQ9lyOT!>g-Dm{JX@DW0|}&m~9m68L6k{JhxPEs?43e z!_M#kh-dWHT61CW3vnz{W=|VD5JS~+qq5s&0-MbZ%GGL_(3siWtFc4E(O%@DS*6A> z#OcgnxeAex*DF(N;<<(puuc4{do>Fxa9N`Yx0-scJJiPyO|EALpgfw>E@6N9p&2Yj z_6~qa#4=WsAxS9Q9O`(VXqVN*`AI-^7_Sq2#bOLEQ|C$*b zh5#k5JfzSqPR-Avm zQs^xlD^AVvLxod>Jar* zrdEJL5%^4N`SNhqg-4$|ekJ^R7!+Erm&$b~Q*{QRt|_s~2;#OgdYibai$jQ-ujU^t zoV1xs0>U@cmqk`*hMoi8`i%YC%#+v1Cz4|qjw~D{aOMPcVrBqR7Dy+2{8>93r;^#7 zt(Lf)eUs+Z8kI`bfrm0Y1CfezS`1~z>q1cT@NgL-8qk7@70xpaH)lZYnQ{Xj(~7@Q8o{(zyrYV-Bp5Y5h_`pZjNr= z%ki7x3T)Wiz8*tYx5zbO%R*Lo?YS$QYbzy%w;X(WtSzK)oEq2?+2|ruCf- z&|z58^CQPHS^lIzZM|~?R200p7e>$fRR)i9&FMj;;GyO~FAMe8G@gyKzz?-sb0U;J zOBHx}*bsOtg*r2ku@$m4i2fPK+;UE#T!dO7P=0e3uMomY8mhk@?oNINzLED6Xurs34)+gD$HSr#4DEO6A?9(eN5!OAV4i zNLIW>QAX4F&l_%D92ey)3V=5lM%P3S4Z(#@aLBi}>Vy@pxKvmKX&XF`ep1_{4RcEFuThIs{X;k&O%jK zS}WAWKQ1h66bPcp0uORE8|2{P#3BI=t)xt&l859OYFwU~@MPwqf?vgm%b>dD?SX93 z&w(Mo;4Bw#6cOy1%iJ7~P?2-2rmi@U=COtaxO}0g0Q!P}BeK@!0@f~obPl3*rRvw< ztW9@=eK-9?oFNMI^bHt*5;AcU;+^AO?EU^mm zzR5iA^XZAkDkK(=A3?$cNjR&lI60vrQOUA8G-%Hs*w^j<*e_k)kdeufUj#l=aWax6 zacpthfF_tg>QBM&O8pc+s&21#eHVUpS?5&^zEA z2a#Nm5;x`*JtT&#C!!kE;T-w+42w2!&{r1ZH1&c9p^^7>G*2tk>y_H6{r$Oosn4tB zoua#|+E;Sw{iVuqzklsnYx|wr3H{)U-r?b5Z;sgp7yE_A^Ad*GS|+oDTlw*oRq6*` z)iVkoYepSme)!|OTZ5{6gxCBBUiAug(e~h?5C{apQW@VN!EcX)JW_XjZR_!%8RDx0 zba5A}+vf(yS$l^!yZsYg!HEW|CT|m0&kqi=CY|U%1R$R6EDuk~NL9~P;V8>!#5GHT zYoOBvVzS=|VjWh?&b@TgrtZz_E;^_C^m8s+cfqE!)@|6Z^_*?n&KwnYUL=1iddi@e zDmx6pY}2~U=Uuw)Jow$FO=lI|zH)Ua_)VAJBT*V+HC%IAB@dZ0IFgAInv0heUM_N@ z8R9xW$n$h*t~dlet)MF&Qh@_MvqGF1^#_#uF*Fc{{9+18%dpVxhP~3FlGRNbP-KsqCAzK>U!OV`)1i#4IIXzbjl) zxKyAo78gb8k}y@_H<;(!$EyKR4F;`r_7vd{qOT5gAIPlz)sL>%avbgNLvEbR{N9o~aw zsZ5&u$IIj$s?JX6kf>)0PL?Ou!B6K!FA)t}Xs7rE7oyhPVdy+!4TshKi93 zr?RCSq$w;|^B*mhck<830%;!j%0r>)&aXR2URMQSL!can$~3UxytAs0@GPHST)3*R zUHobm>qwI#^0m2~9Uac@fXYv(l68f^zsgW!`IjuHfl`Z(sMvx|LqAO^TwU;unh#GH z?}*bpJadC{kzPV!)Z*ZbUixA0p0v9;E$A8WUAQQKC_yKnQ_s3Z=yYrZ#xD)d=Bj0A zn1`JSVWG2I)C2Ol0_zZMPCfFB-dC?W>S{lJ&El7ooZV3FkYzO|K@TiM6CVE-@N+EJ z3M<*LrN}Jf(0&6pR{8Q@&)5U~-Ov?KuZJzuIk}9R&ph)i>bGXi?ci`L{+Nd1ONSw@Ket2_v{L#J^O4zT*5$hu*tv+CI`u?(d-jkV_M zjViQ3XNlh840Llt8yWfq>V+yi7#ZF_29*>yX?D)<-U14lU2CDt`QfEG-T{(OAlH_e)#`AmJJ67+-l+!ulT;aTB5 z=8aO`?(p{Hd|gMnlB+h`gudHCh-LDUVYdYJe04ZebV@@It!1%9O05RwrR`gOnfS{n1+s+eC=w4FrCzri~;|vN|bfUIfYNPRIhHLr2gnC7N9R3EqRu zJ9YhEbonQE_AuI(Q``TJ&&cPJg;CGFpMdKh$o9Yg9oL;aG@lkQ#c+Y zt`47ixPF)o*NJdj@CrM`^(z=Mq#bhnLPm-p3zj1`Fc1O_o(gn6$jHrYV+brq$q)e{rVEtC z!F7J0HFPjmtB{+EP+hp*582Ct%OH}&6}w=_L=0zzJy2c1koQZ+lD-weQGP1;!W($d zn0nBcSa5u(SRMei)}RuqK=tnD2rXxGFs5CKoL>~24@NY^Be-!5|9Qdno5Hi17kM)j zDyAaKZbU1VA9h#<753Wur2>dk6ANY`|=d#udf}s<6iGsmZC#rRx%qbX^5iyJ+ zG3JD~35Rn<$;^+O;GONl{~TAnaR%DN!!jk77x30H&wE*d6J(<+L-5)Ts2!n>0tG{0 z_B&_%dUb`oiuHL6yET?A`nU40S?JHZ@OuIR8BVM~14uYwc5p?0m&=aAh>-Y)I6WtF zy0&Ww+J95wJpY%tU{-JeZ?3?TEdGj<3xboZ_6GT~sU3m$!*k+(8ECn(a_?zQ=^e^K zzYRQa$M&57E%V+D?4QRT1E0MEVBpM4STk0PUR4)zw(<5!Aa>b&>iH1(63zM6<26IOnMQMnnd~= zR6PCwoOEZd0V&#W(6kDN+2jpaBPWwBLDBd_;==SsW1u-pbZ_xFE0FJQJfOKCc0@FH z;E8BXfi4yHTx~8K+MMloar-j|AWU5BPpAr}pB1JRrnB+%<}^@_7{Go5JnajDJg^Ub z3VqsjHhkTjDh9gYU$evWwF2}GL=Uh54QNo!k6!^J<1o!^VR%qx*gzv$bStaQh(qFtB+NjP=#9p(>b36x={Cn;U*-zl51rqs>L(A-@d#5|jl7 zGmb<9nKetnJpQv~+MkJHjZBW4!G4hQEtHJ>F8(H`3!Oob42IK<`j}~uVFX1Yc`*+B zIe|HM0L!y=X!(Ygz`dwjN*hWAK^>I#rZPp29+i-+l0NdmOKSP^E=fLR3 ziOT)ioJjaVt68;r9u5~4!~e^{iYda1(T%4xnhX8*J4>Qu$=}wTA3F{sJrFTq29a+X z^m8_+LHV#DRx#ILHp|ypPZC6NK7;c>=w4_-o&=r5&^3}3(}yOpRvY-0Cj?>|CXB{I zIp5Y?l!L2wz^nu4P=lH;&*rs2P`tI-Re`B5Z0v?N@gW-dqbYE>)+dUB^~U!@E0FLx6|gG;9VMiJL~c7-f7{t z_1pG%7lhw7?40c#8-9D)cjtPihTpcWKi%6LetYF_M!Yk^Z{FX1+B-M=wqyQ0?_&Aw zSND3Chu>cJ*o)qY;kR4wJ;=K-{C3-C@9VFyQrv-?rTI2JhtX+hw2njJG!YcKO<`dM}gT{^@t#@!_{C=D*9kNPa6#@Q#t+ zzW8}>TlnqDH8t-z`Rz5=duPgT-}!;JF8ub2zC*oJk|4i(1?We zJp-`KxcFA5I_?XN(!C>K1c@+4dCnVD1 zHY|p+OIAcpV#!(biP_78E4wVlpXYL%(DK$_`>7p2X<)FI$LIvmn1^`2$Wv}%H;d@( zx8wbk?bG{do`;weSs}1QofqqZXqmH2pC2_iC<)N3J41zKEnDk<2 zc$EV!H-3Xl#*k_eCWM#r40bQi;Fz0Z#6+81T)>h#st#f_V&xY*6SUmvC1?^Y%Q=~` z?J|*=d_z(1Q~Cb?{3KxkpfRh%<|i>h?9(iSHDs8?V$nC&-z1(J*2KX`acJxwY;Af6 zQyWVnzx)644%V9{$*r{!F>dL1EGC6jYAj&JLTT*!Fowla#Fiv}pHhMN#=3=hEO+;% zrgLg&DH0);M7t8eGj~xvkp?xZQYy}mQM(jB@C^g2V zT}Bz}o#78b_$&@s2|$}8%lZZSSsWOl>#x;|>O&|S!TY-8Lz1!5jW*}wdF>cI@W$pJ z>z-uKL9Fo~8U5j9wNFEVnq}_g-K5N_gsNdL?>%J~wac6nsg2+BKhA~NboRwl6m(re z45?;E_PsdNdZM|npU^M}d;7QmVJgH(c(Vkh$NMwFUl@Y$cqTIXfWNOD6o$}!K^68< zDUQ^3I7R51hkvlehFs=?`b)r|kT} z(XMJSL8fImg^jJ6u8gM3d-=F4yE2xE_?UUWe|j$;k2PHt_-ij8r)5{gy2yR3Fpb^I z2XIYbL2AC25A2%2!e?MFAMs_E9il0dSn9qP<|O!2En%mGTcCiv+u?(a={9G{tg&pI~OLciAKce+hJav5{xKj)~2MxoMQ|lIOjG zoeqySr}#5;y({2&V<6j{5m{Nq?ljTmi>27iGq%);P5y;t2YhE6_}4TToReSJvLKj* z!mepFr`EHuT!?Kk@p2B$r)qeY!@tFTecX~lk9QRu0kbpk2X@I5Gu2|o1_wO{F7ayc z0d{(W@Rv;oDZpR&xhMV<#h;S+Q{jIaUKRcZRU!Z7e-Bn4Z+9%mLAwjJRId{$hu=vw0(JY?s9sbU`Vegs_?PU`u+t@3o zYjb;fdZ9Hp=|W-cNgZ0trUA9FHX=cPp1amo^JT))b2_w?O_ph6X}HG}Uo8Mhg4R&u zRl?3~9oos}+qAKBWlXPORj#$R&9%bjY=<_pxj$`eJ}72$P~~e)PQFxFT<*|fHnF&k z#SuaJiyE}nnlBTUUe}?eY|?WZOCzgX_=+E`ou-R~m9Ov6N;Yq&jg_*Xf|)p4JI$8~ zOW)d|rEJnp8%t$%#9H`TEA^KM3;&@*3)!5HHWtdKIyM(XYigToh0UMp&}KIOq>at8 z$XJhv)>Qo^!on|fXd#>S-^M~IJ!T>FJn5}8UnVU5W`~xtB?)aTm35FmeO_Cf#;b&# zKkCp9+)+@uSIwbQ3`mi@CuFm0@rk2LGL)Y_@PL|C|_Lkrm`O&bek#VAH^v^JV95>~G6 z&`P#osEw8KDdD}gS|bhD2piXSXd_$3)W$~H`w;dlYwb+9PT0DxLtEJ*t2VYuhl&vf zt)Zrigq2%5w2}>Hw6Ripln--gjWk>%Y~0?VjciDzjg7LF5kndJCcg11Vdstx?PLQw zZR|WGY=H-Lls4?KUQ*iB}4HZ|Trpw(yW@uQAw3sb|ZDVnFYph7F(Ar-vEdP3kma_%BZ7e_Hf4{b z=B>5(uIY!yhYb$b{OBdhPXveWcgTS)Gj78{ZuJoxBa?@PCBN#-l16hzu?#y6ve*5{ zVQM~REQWR2s4QQ7@3GNQzVhBpS5q4(Ato^{}a(XOJ=d0j7mJ9Q_PaexS`CJ>1 z<#T*`hsSazzUtj$nF(L9*eAea)ifX7M}p& zu~@+8IC$*Y;w#!crcl0`-Qx;@H*2s#=U|%!F_&QG0KB-(5&NcxGZ0!v@A;&I>1=0p zzO$L(vYzmzbg*BBKeJ&TUw#YQva`*Z_)=g-nTucEg8dY~x%+{D8_Uh!59SS}Ebc3022XU`ylB_Z#b=y|s~2E|$v&<@s-9O4#yT-ddi$(h{X)zeYAg zDcP^sLddB1ufjQF?SfgwUT7Cq;60vf*|XLS&ytPDy5V5O4RLD}SNx7_isFi2+d}Mf zS9A?K@cNk`1&9Xf;DJ~KZ^5J0Iap7uR6G$gMsdV^vL%Wm=Ga2)b4Sc(?-7CB?~3rk zWz$1(GTC~pD-Kay(PEC`j1$PVD9$*}7Gj?}V;b!F4ln90@6pDlSCH+-x?!2(hR_hj z0hg1lP#kcnEkvsWERtH8or?^>0zz7GuWfvlR*3AbBP(v{#0tpH`D%pm%g)u64c@I` zZvIZPH1ry0oZ98)ZztbNQSw_k#5m^W;aa<+*%Y};G!6&rW!Qjs5$X<QwKU35erF_3nHbg1k@7hAhsP`S= zqOs1-=fKpsY9kNX`2f5e3tkMVbHxGE$0jRO;zKi%pEGgywpyb&<8QVlIR)ai=pcH* z7Gj?}V{WnBV4GR@4vc^(8}OnYoi`5OXWob;hTI#9If^?DCEKDr8wcA$>~nX_kMM{0 zndI1;0CWyHkIVoYsSa(4R2qX6muw(gqqt<9EyO-|$+R*&A8gBets^|L-B?E~X>mko zhEn`PWE+&?&)Y)m^WvY+-f&g#h0k)Mnsa*D3Sr$7aR-?J))B2wgvKDnCAX8UQCxD1 zEyO-|$(&lbxXbCy<~^8=UCNDU{qa$<`B;CnR^YAHD9-pW*%ZYYAGC$o=gyeB8{VH$ z-pwm;c>k~nW4YUK}+3%2FgMXdiJlfe4q z@Rq7WZUOg`rV@3jDcY?bX>reI`9G~_FnGbZGA1X z@bG)$$bEmf(5Av$(BM^Q{LP-5#Y^G%zAHD6!Yip@;k_f3ANRA5kFbxAvX76$hXcDRW%s~q zci0QZ4gmaYg+HI0o0Hfpa^clhQwnY#-pB+0n&sn%2d0U)={fL@F$h^=Qmc65ZF2_f zt0c?9_tIT(LwE-nZ|saV&w@Ag3_JbRMycdf`{4!KJHl7@KzB{mY54~4+^Y4nBINH> z>tioGYqGbBvA2#2&E5&{w9!`IE?KV$^>kFPi3isLLRukWvjv0clw%K>4YnK?#LBT( zn4pyAYV!S+(p+T=Aw$a{wh%JF37>Wp;9j(SQl%B*N$tprA9rE}gjv3E+xUf9brU%6 z<6)dFlKrYzH{;YU&bs7#DM}vX5cIfU9cSfIplIVIhz+kNGeVYLb9xvX)cATU`L0Si z-jrO9W8V;*BHq2Ejj$gg^TC#4bVjatMYR%MKR~{@Qkd_zg^=O(J;EQR6w9_+o4Cup zMqA{MlTF4Jc_cYtH&@F0G4h?2@_y77qP4s&Y5`f1h)2i*LRxX7EfHyj2#6h7k?X_? zsLuE5915Y@Jg0o5`jrg}>1jLdMARZ6Rcg6cXqtM)q`Wg?P+6vSNBCRzRfYdnAuvq?Q{i z#{%`^VW7T~%ttSN#;aYRek1u_ikjcRA;vLK&kF-}u#KfQnfoM}8nPIh^JNSPEl}db z$H=!=O7nL1~J0L~54&O|lV6nLcg{A!F}j!YyOn zD(Pao$n@?i7aQVQGKiERFy27INkkz1g$SfeF z6(6!CBCQZXv?D8;omc_YAm5;W{Hj5@8-#ANfA6WVIy`OG*tA<1zjoE($>e(}sy=~3 z7^_2b(6;W3o4Ktq;Fn=MZZu#$nH4kci`oP1-YXfH`FTJNpU z1FhS!gs@?Q9K+@W<73$2=n~tXe3T74hfC}G#NK6aP&f8`0~qeT7CvG_%#+4ph}rur zlu7fY7Q@RylEp`tz0U#6#;HO=Ra;NWa3?(3QMh}V5QC`}wtkvsz|#b25WL!>UeSd)uGdTN#MM!H!@U%!Ej z?3bC0(M=9voE8kU$W&VHSu{e1XdGk+H1mRr%K|pbgPh(_!lyA z>XMirmjvGqF*;loO!a!!mYP(<@5m5XH5}1i4V;)?+H$JyujwWsrSK~t}o*IZLKmp8e?u6~W>QFExx3%^*U4135BSQ)O+$uMA}Xm2&$ z4y5*0ape6W3z_e;4=ZRxU2`e9EEKnHB|~7{Dp%h|@{d+xYBjTkZV=MHo5;vYY`K6# z7@z7f&phS@<&~Us+-S>8KHk@pA+S0)EaCC)GiDpt((OUYV1$gEx(vDk85r}72W&}6 z1>8@Dz$&0SNdfu{<374ENcZ1MMmD(LB0Z29hNx>SAX+mF3kYe2=v=XYkXEd-P1u+f z&|k)1*gk&!W%AvaNpIKko)5dr{!EsO{;6O*+jW=yiF_|#nsSG=KXM3T4r8pj#y%gN zwypxZ3^uCz&as2$cAStdBSRoP(~KshK8e1NjbG%lF|?R&2QpMG;K)X2nx{&Pc^(^*T+UnPkn3|EEMK=iP;4{d`N?mj+hcG_ZW3Gf1p%UPA zLK(K_Qn{Mp1EGdCO3jv|R78agfmOuOk<3IR3qZMY4eXLH2Q&iRQN4jZ9b^L*h zoVq#|#ne%OcL2J34Asd?=5^erIGhZDRYi2HMVn~|YN{FzrJICQ!@*?a)YTwkMJ`*- zyQORqhGN;yk}$o%po&XuS;|=PGBN~K6^XGzrKqZ7GuZDi^GE=p1 zAl)LQ7GC_nr-kLA7J`@LWW+0b42n2`TzJ0RWq>%241ra|QAvtu;iu}NpKcdY7e|wk z_oEoW-Y}a~WenJolZwcYA+U-_j1eI-RSQ?qEkbJH3Nmu)T38y!2wr0B4Qp=BF?C?Q z!Iq%ZLz4`F)kAcWu+mi#W2b83Ho8?vP25aIPF)j+hMFkA%EW76Js9*?MAj%8s*iuM zWh%w-&twR!IF3uIKJ+wImHZ>!JfuoKK}JqpC34)%t!0Lsa>m)&aAB7bSUYGC$ggZk zN`d^G41pC$;<%Z@P}RoI=$0Y1@nbS_>e`U=E{e`zJu~QhEHVUE5sC9IS_!JkID>8& zQW>X`kyBU35n+}QDLClqfw$b}oXmhz-|aZ2uu-w4D@8I)hQNyCq@+|Mfvc()k8UGU zFGFPH)b%na)XOluOVbcN-eJp23gc~L2&^!o^U0M43L~W|;4O4xkO~+jBd4x_#W4kl z*?U1t_09_R4_&OBvoO2k!}-G7@s2} zr!EYcZU%4JHH3#h*>aO&_#+ttD~7~$Ga#la;SY3!kV^P1898+&%nw5Z%(yAS1Pg-@ z4qw=DyW>zY1Xc*qm1jyl;qy{;a4_8-qz+b)kyF>fvQ{0$Ym3%O;$^lBWn9=yhQP`p zx*>*14#s+7Bi$^dD$XY(r>=^_BC6oEYp%@Ru9vN5+Vp$B+Lo)-$E(N?SbZFyltfe= zJyA7&?4cWoR7!)4oVrpDX;n&e#Ym8IwnmW;+47Vs`2ZOLtCC|7Dv6O)74m+%aY%){ zhm4%MLb_WO5}zJz$UDAkOH@kaJ7fr~M2ZT@gmuCO{6CNLPkzq6LNx9)g3A%jg1^fcBW5G#)^J2 z1Xd4;lP^MMsuqr>TZGiY8ZvU~T9_y6kaFETQ!iu7ObX#DG6Yr#s}d^>PD@q66?Aiu zD!7b{oVp4kwFED&`YT~tIcl?PU_(w$q-mQB-auFGgS+ppj(90!bi!-scS(Fp;vBn}pQDf02<> z*MjVagqNzg^+sO5`Q@QYI&MfDOoqTJA#wIpNK4Vd3c5i^9V{gyr>=upVS6%Lb+X!M zu-TTCj0PLY5LgW)PO#;a6#t)3HwNkdbI8c4`(O4aWUq0D8}))#0WaQLUAhSo<6Jpq@S4XrmxXqTCl)=qp2&@bev&WE@qJ!7c4MOVRHDu(} zbs+l}3)xzx0g8vCL`}hT5$6q19#9h zWQ;$v#19CoV%TiNag7^npeo_m+B|~7fkhpI{3pqs-|3xQxHwUSKMP%gEH6UlOLJPr#jzvQk!bV$aG9;W& zhQP`oapt1rr6}PXxGW<-swZ{~;r%t_%5cf_l}>mWCQd*j^)_8Fp%gwfcDpN3ZC( z`LKozft5yoVvx`iIGCbP*KNg=(Zu% zaUB^sb#=&Ihei#=khzmga05S8+71!gRt2@+mN*Yf47f%p7>J~e@fy{ zh5zv(UYG)J2jH&=STL8ReijfDrUnpmIYhP-EB-jAV=Ml^AuO$E40xAL1U`R(a#?f3 zXk>HSt3>G?0Bm(9dc3KIGhUbJL-tB85pK?a7tX*N;P~YALXV>U9`e0>h$*2uR&xkr$@X|-S+v8m^=|TbnNK;d zT5go|O`wZxnabF8AsGVcm}aD(Oi@dpPfGFKd31A-k!ypkOD!IjWRK1h7ey5g`eWc79Cb&-keb# z8Ci)pPjLw2lRoB>SQr*q*acwF#G->c&Ryq|A+VZA%u!T|swn2rO+$*Ji;SGQDCUPH zmfX*Awk?xglJEIwy)#uw(O)J-b#kR3L^4$#sopcIQnHTyTRT} zw+<(1C$;h4WC*M_B5(dp2pmz0iY$IlHx4O_-;j}0m&M{RZp3f7zXv9e>(pX714=Ii1WaQMPv0N_=W1VubEkzkOE+Ru<<#8fi9{NhGmKs_!^G9KlGK(_u04WD*XhxEd1h>?)@kk0_)zyK9E*|Y9Gjl>4qWw{6R9Z5^Mf} zLyTWf>4KoV+I5uv*p{1A#1F_2SVbguo+}JhNqmoP8B!AeK}Jqp5-VZ_R<0LdRZDrm zb8>YT)EG0u=l@ZyY!5l22 z3>8rY`W{JWR213S*D^`L+yY&^U(-ft3cTIjizi1adarLZm=mN=7ya z#GkxgGgN zMZ1B+!f*qJN63!S>yz6cQqrkpabdjB~Vm@$y0RGkiq0hGO`j(p5PGUH{f%4LecsAVj4s; zXH~~3a~Bx`E0RcFgb_)w1E}u~*-bZ{ZXr@DQ^?4vYh@0+lgQcGaCc>k5J3#GINg?) zj2)+tA+WOOmVI)eEMlb8XmKLl7^DK$l93Gxu*e%^>LDsB3kaEdJZKyC{M6%u@l8Dz z%G9Iic2}~w9oeDytQK!on0CC1>?FMw8OL^M#~$*%d_l;xqro98(hi%|m3(`s8QU5I zV(YDVAAK`=LhPFMHZnhCSvF@LR+CmJLHsS``zqx+nq02lTW1)y(86yr*PPvzbR#@Tb+-<;ESHKSaP5q0cDF1p-+6a|OT5p*M{|9D0p2UzUu~31PPKn`xw-=m zh<)UGbLFbj@-1J^)xtx4xuV-wt<^`p&jHlNsY1yg2QrNT%Wd-ngiusRarf`J6=Rtz z@+W%EMSLf{ZjeA7O10&&R?Z4K|3xkl?6bY_FcDsQ1D`RMsP*(O$p$D7`G49%$f{7d z#KNnxLKY$10zz6*wI$+L$j4e$$QC_dTyHC)jtyd)wm0CIuv$L+FzN%Smm6c+u3A2n zd@n^=2irnOpRTZl@O^qJFg4}{V;)16$9>9cC9O-(3|+c~Oi=GqMzozvH<9n9xby;B z2_*0Yf}tmG8WhRoD% zjw0P6q>EiLvR_;>2oG|Iv208xYhi)ZLbhJ7W{h)z-)YNDO5yEf2&@z$Z{^ZRK@w9Q z_qWnbLTcg7WaQMfutcMUjAM9j#n){4Nj-dp41v`{Wbg7MJ#cc0CjOOf7E%*mAS0)) ziAY_+9wT?4Q8&E!`G0N6NkRM%83HSa$R_3nLHNuRHT*Z-CZrmEPex8%4J+djLX=si zTy=-sQnsjFl6J&uYS!(ul(IOC41twJWL{;WEF?umAKi50kos6jMowKHE42D(l-!+- z`1F86j~MgXX3J5k<6<%dRvpo4a%zGp!(qlJsA%INx@kylTu4SvT^nSF2<9p{&m$PidvBxevRK}8z} z&`m>X<8S|`wNZ42pkso~InP4Ka18ICIG$X3z5`^;IF<}CHrh}LD%$9yn}*cJQDo%Q z<3^+(6Xr)|DrL7+*T##iEjOu&SCS#Hnn>=)l*AM*yn=2LQVW-pk@qVtxTORw{GBZ~ zsfE{*A;w4xAu&Y@x6(~QYT+g_vOxKK{v{b%i7@}kA&k%Vm}@~~9=yclK%;Jhl!IT= zaZ6W9HF9OnKaw(oI5YVG$WQbuEYlC5)i%u_Y%3(I7)$1!3&-Y-OgXp-Q(2sfIEcIdwIN5!9A4 zlf#R;dgJ}JETt^oLx#Z0!Z?Czq^RiQopj@n`gl7TIdy%A{?FFJOBg}@mMurAj(;OV zVAWyl|1=O(wDC2%X-I8+g^ZlKHWu*_R9& zUcNBpHfgIlgmEy=IQ}yBW2;loEf@2qDL@z5GL_-#LNWx>G0mmXwW(~gu)ctb5~R+f z8-WZ`8vhAMoV$*!#>R6_wmWHxH?jyUEBAmE1XT!T}T5e`1Etc*~_*kxM;W%4e(jT9R76 zY0Fru<#93uRxQUGqe!ThR*s5T9-~`_6w9Mzgg`+LJOs%e8d~no})STUC zDizX0hQKPsT;Z5WDk@n`HxH?jRb=GURdR?DLu#-G`fxTeid=5XQ)=W=G6Ys5vEh4t z6ltNTC}b<$IHW?hkdaeY$YE_1VvHm=*>aUCxseQkRY~N%dM&AI7)jzP;WQPcTu(O; zsg!HU$f+x3NuZR7=_AK7x0s(6YFfmOxP#s-Y9iWogb8Bfv;Ln`A5GV*?>j9RYh zR_ZmgGP;iHI4_+}h8Qzt#ONu?m_j!Usf>wa+Upc{f*Y)ZLeH4l{$ED%dyoRzw`^6PYKka6p)WMn07ec2X5Mhu~^jv~efI>YyV#qg- z{pEB+kWRgnjI2cZtsG+frhF{n-p}Uq8Mnj=FHK`Sv;4L8vZLaO0LGIHu_SgKWn>1FHxWJ^%W;ZtM?tQ;bnY?$RxQ}yt1 zxE5PF)Yn!uSv?HB*3? z-%CxZeTGsHbI1@_K|~fZ#REi~nyQE{x=BbyOeZ6!u84V|A}UpQnerY(=I~NmW>N{K zlOeE5I9Ssb=wq3Kprk6`6uK!$1)NAmPF(>aCgfn+Cwmz|Chu0E*9hkJ8I(}8Whj;4 zk|D54(8dInnyQFFx=Bby>dZD~qDe1Qys6+~oQOePFM z5DGt48;{WKLTck-GIHwL5D_Bp)*w8LK$T$}X83PgZc-4xCqrNbp^XqxQmP7mLpKJg zf@jFcsjFZvj}ZArrRe6ebyKHPcVEYih?QgrtOQo-Dv6Mh>i^|*OOXCwLPp+C{6APN z4=06yi)@L>5O5(Gq9gx@j8y-hN4Es&{|#j1)cwDZKmWY6U`k2dg_qJ8@`7t@$w>|D zCPQE~5FKp}haY0BR2|gm)*yATlZ>3Y4pwp<6ySY!*RXev6xqIv4*Vmb75NXgETtgc zM~1)(BC?6AOceF>RAs!IZWdA*_mGiOSB4mmaBCTOM^VPv*>K@4@}LYul=ydBf>IRU zBtu|Dp&gG{*3swS=eJ5mGU}RLU zzd$zv>GkKy$fA)M(L5vdR$E%q z`8Savu+Cqhd-{Dos_$>4+ky1`^TX3DF>%)y0W)tB|@_OGZvz7ozXE>O@*#20gg8 z0a5Wh@bsfwS@u3X8&89x3H`}t30(cV{0xN*!+JM06 zsGi?THv{SUJIKhXd)|)#yr`0!6<@F=Ck5~b83HQ+eFTWIQg!e!-5R709wH;Bt^+X( zp(;vj&xoNG_`NMLse#{+A+Q?I&O!(oss4Y4ZVA%=zaS&0?tifYDlDz!P_XjYj@t~& z$q-l>XjeeB5>wT%gl-U04GYQ0sjH!j=L5AIj58V{!G*S@WF$C`41txvGF>{r*{FWs zK(_+v_jP3C)cr1IB=V9le$q-ogYiA@zNvSH>NjC{bO`HkiLJEjJ%)t{_ORc^;v!$!LQX~T`So-okUqbbjGVg9MT2@GJe;*k+bB;63C z@1Gzer|x^v>pM_xuoqU1fC5T+m#sI^#{I6f9jANK$q-l-X!k785L5Ipg>Dj34-?7A zsp~sx+&$C>{UGDJuIj}TJ)zmRSU(*N_w$f^5ZtSXJqrPsX#?mSy+G6ZZOLtrJK z9qEm8QdF>xZVgfeXOfXqSAoa?*gE`TwpP>D0d-qeQUE*25Lf|dGk}ne;`)$>)D783OBn?ep)GQT)DzZU)lto5;wi`(4c7tT`x|X(N!MRbhQPXB zJBv^9QM`XG-4dktN65&jdtdbJRjOquu)6E$+jS4v@{;bqpA3O@zqW5LLP+udeRNZh z{=b)uoVx!-)aS3V()<1?TTasVPm&?9zSl;5pN!)7C+KD%{r+t-a_WAc%3JjHvNqG7 zeqzU&-V`zf*5`|L4SFD=_=j$Dy0AZBqX^qM?R1-vinx-DoVp@J7FZvtI0-X6_uBH3Lb!trffa%_3ycs_{C_*$6r}%e zAtR^me-RNH6=(!N{V-S$w~EuI2M^m4ltOrj41pDbHX`VlDT;WIZWB@wpCluvt_aa9 z(5QhR^4Yq6k;gN(w4@GxL59HUK-()I`6%9hnr;cw`#&Kgr|x|*)*I{>sSN^4PU^Ug zu#gOab-s42H>9KZejeQrr0-{wkqy3gyunEmCR{h#;}ziV_EFChe~RKyN&KnsKR(0@ zQzlIC95~{MSEyS+Oqd!#^w_?FRa()-Av&^RdM8#i2E2_EfzMx{T-Mw$%F6N;P&$Pk z? zH3*)Z|+nMkS~Ag`tyhYV}4A|oqdZ4ZYSKXEM1 z!yAW?!uXgiJt>TjkRhRL{^u8a`Z!b;!(q2G)v|dji-`4BG zu=UE42yLVFt6`({ePk!;g~>R!YqY+bd@o-Rve9}EhcGr;jm;99u7Kg$`fde}_Yq7w z7YbL~!}hPXG-bH>0vQ77mF5DOS}=9=aTb0t%MH^Wq2C`F6dq1?;5ha=%wg2~E-7z= z0afGs)_zYe2)`_)FMmUZ!1^-MTN?T@B&0_AXXu6?o%#zhvJ&Z^<`Bl`*P2if>c11l&XRybYqYzSV%@rT?Gpj6`1-QFSI2m z1HpM@2&@buYb5nDsHr;GK(_{|gLP!&)O8^00`}mr&NxFP*lo*8N}x`Lz)C<{7X*Y< z@9(4=g7kigjGVgn=Y~;$dEXQP-e*fpy8qo|2(0@fqvr7lz!|CjzlUxK(*JjpkyH2o zlF)UA@J(BOQU;HcA+R!t%(9HjAWBSC!(()VkZO38jGVd}mTJ{tiVAnC`sf(w`5LjL4YYc^&s)#4)CLtB^1Q|JXMI0K77g7W zOpaA+mB?cdl2lc)mTnwUCC8AFQ&-86s!F1XMcDPF)XT&WtFvN-^z)XbfZqVTxrfQ-&4X#cZWw)<@lz zs?^6$G6Ys1{R#Teaa1)@qT7bl$PO}c>Kch=o3*g~lCsTr+me*(xQ7gZRYyX$*}_iM z#octPkh-{wjGVeIqSU4-w%nu?o+m?KrJ&6=qoh<7JV!SMse)(8$f>J9%+1UdM5Vlo75B|~)N z|B#XD|1ES&kpAC9Mo!)TVuc1TtzaK0LkzglmYmeU^<)UF2DB?QVysjhTuZkGse=(R za_Tx*$y=7NBa(Yfxm1U73-}kj*N#o2Fr|nO*s_#@xStGx6~vLcMx~yfs*L;SW+9bv zFBv&?Wr%hIdm)%p&Nw?8E;J=U8HOnFlr2FiiYLhsSW#%(4GJ?=4^Pl7Lh9k$WaQNK zAXak}%MGY6_>_WNxnY#U^fNn79H)>WuyW9@=4d6Rs$nACAfy^5kdaeYgXocr6dJU> zVEzp39yQ?9cRP-$@;K3!s*DqB$q-m!XnQ0RII0>shHe{DBfVtg)HO1b=N7}zO>L+& za<-hL7_KHmV8yUhmq{=(s@J#EjX-++N-}clUY{R&JtN*cVsQRmTWZqzcaR~l&OgND ze4mr5f!pb}AT@9c898+gh;`p=e5wF*Dh&d7*p`Q>x(?WC*Mpw5v8u1XXoBO*agwj-QZ`Q&-1q zUO&Kst|ClrFo&OsT2}ItmIvDKs)#ppVm?4}=HwUSN)5yrFD?#)oR2`O3x2+p?+VYcHD3KwsTF~|; zv=UR}!VbDYNHrA5$f>I#$QZa9a^<31a&K`41pDhwy!CHqpFcF(QVUe z>1xPCakSO{(KLG6Yr~+UYG(QmP!Dr5mG_ zgQ|kxk&#nZ!3sao$+ANaOQ9VC_ZU)lxfBnDbc|SkkMU~uZy_Q^TzN}>w zIED;?6@WfJh_X_3&`Y-lse>cQ$f-vFv1pR>kA8l(lgY^YiSN%| zpIN_U)0VBvt$UY`?X6OLOP1?e@8b2>HA-k zkyH1*Slkqh1!b~TC#$XXSFP_j=RbrDffax@=Z|wzRB#a88l(!Ak&#nZf#?AUON_sC zLMwwUw%lYK*hGfF%0N4by@iybgA3^9Aa!sq898+wh_+u)WHqe>uC=8lB``vUz)C=y z|4TlK_jl1PL3+PNMo!)P(|P`HtOD+{Wh5PcFBt;scl&f0T zPu$RP(l>z&fpxt$>ksKDzW*!PLrtXb|4c?s-S=YLcL4Ug$!Du0pny`|WgBE^Rd5X1 zg+4zS0D8#~SQThr?4cp1=;27ZNk~1sgp8cJ9z-iJmo33&H}KvqrVFhUw%byZQn-=~ zft7-`6&UBFsNm&vYmh3qgp8cJ3dHs{F!Bf6^lROJyDcZ_{#(cpSodpZ1NvkXzrT)d z2GZ|0kdagOyLc^au-9-YJFM>me9)Ge^!_Kw5LoYPNB?7#6b*cgZVXZbA0Z>Bt^qOj z!(ZN`ee|EUr6isI6EXzW`P#7`!A0@<59wAQz5abNa_U|et-rxWv6yl7HU7MFI&K2Y zCPQHTu5JAVY!uJWq}ze?{4_Fh>Yf*^KiCO%*r``Xw2%CmwyfkMe;OGA>w0bLFQlXR z{$#o#NZ+48Mo!)LVl%Tsww9?t4_T?M_5Kc9UefyoG6dH9+LzEr2r2$|=%yh3KR`xK z-T$Js$BIj?oV#iChSBRrd%RannlPcz<2mrhyUUiEl)#;22&@FOt-UxWMFnr9TZ2@= z8_3A1t3X5nczaH%?hd+!7T=d_c}WR;o(zGNfHn$52r2&mEZr2O|Nn)IoVx!-6o_pl zp{)p>wWTH{@H;XDRsz~65a*<*;Ma6(kSh2U898+oOygsI!`VGr-yd>r$JzfuWC*P9 zm+01eFeZw}m(guNdVDb%d4KV^tMBaJWJ^ds?H7wipU~F-wk;>=|8I~Xu>RLR|2`ST?_Z~zf%N-V z$;heuUCidII8_%q`3w!b3Fmd3;r*3dGFaDZXY)xuiueCaw*=|^Kar7B_r7S~SE^+w zu)6E$Cv*08?*1dm5LowX+xHPdivM3iHwEec!^z00`(JELUTKta1t-tmd1mhEztWbS zjQ=kuLts^)-Pu8*rD)+2xzvNWXuGjGVgPMK+i`;`0+* zTGI7DBtu|bugwM}AI1CMr(1&b{&&g9se6Aa@8_+TwNL!)^E++?%p^l#-M(1Y%?m^n ze@~;Efb{odGIHwv7HfIxBNhEzzSC?O$p`&pG6dG++O<5KisJJV=tdxYejFJ&b)SnC zA1kPYH5~<8Uefap83OBhZHq5LNb&yw-4vw%Gi2n{{V(?SZB(GapD8+n_3(W&+Ms`@ zEkP-SHfp0v2&@jY zIiKXCc>iDMmLR?V&t&A(y)Wi?hRtH#6tCaevXajKH5mfyeC-_1kdET}U(pRg`u^u+ zWP|S=ZxANdv3Yg{_`7}7^TeN`_)`*pD*TTR@xm0CiN~koJ$y3D(k&n+Obs9&;t<(R zthlFhEAH;ZipGF<-bCQ@7burCu{n!ZiPAd&*y>L7cvB5$ye`v;3_v!Q7Rn`OWWaIy z24P!7mW^}|m-CHcJhS$`J2@!jQ!k)4r}R$*KELdH6*tz57}+1lGGPDQT;BLvCuv#B1m_ zA>Di(8QCu|StVSpKcF7G8nV7;qryXd&7b1Ze5aU;;Oy>$PRwg-HM$-3JlOeFaZyBJI zzSp-}w$lwk`u$2Wvcc~bRe-ETL|CzaK-VH;pWzO{`@WdpGK1Cfa7HYvG-SAMw=HBT z#kZ0nuu{}zxH@iXGVZgM%^uH$7_Ecj@N#l>?ge{8O?U%wcjP*%P&efUi%#mVa#5}uj=Yz4;U2j zkW)2;jKA8ll_BHLWC)~lnvvSe*GZowq{fLq(G5Yyi9eE&l{oPSTL>8^gseJ>6W{8@ z3WyVZ;~OUyg>eGrb2$1a@y9SqoW6$Pid}MtZm-?hGlZ0slt2DM-IwPexV({#0FfBLO3M@j-fYWED&S3I2&@7UVgTo)N?zqh3( zHSilU1Xcr)q3qUFK#)>J@C@A;qzHaNMowJ>kzAl!E)N?duyS+9?SbWF2&@DWasft3 z6~Gd@DM$eSTy9kO1eTN?<457Ni79WaQK(uvq2-ytp#MPOV_j!TW6KNgceK41v`_ zWar7&d_WRY#c&VZAfy=XCL^aVhNU_&7+Z`M;!!ek>Vk;06!=4AN)rBNOHE4Q1u_Iy3JEO*K}r?D^K@g7B6yCBoVo}O@uLFU znz~VSYMFr%cmZYbCMrW+anzQM8xB2W2&^J{wUY(den!EuKQb%RPSx1}rN#-(HktV)hIs3ei7DweHu1Ce6c zLPkzqEPkUCb~(@O$iQj}gD!5eWhQlTBN+m#3qzwbg0Or{q+#btjY5Z}lTvno=iEks+`;IXX!vtprtZJV`eUDUK(|$f=8?Cnk>jmiY;LoS572D zjIm%^sj7lmOE(cIm}AJusS75SvE;+YPIN2Emar+r4B9f5iph~7u!>2{SQ5CZlDV30 zBT_Qk$;hcoMl3(*6Nz7IF|sapM5K9>Ep4fry<`ZiZcfKlO|t7fN>~-o9dtvH;<=rS zoVs|9)@L-q+f$+?X=pz`VoO>|=V3AgRywC5rPCNtk~md357Es;3gomq!fi84_+suEd9w+$(gd1U0&CE~9l6FE$!m@Q>Zt47YV zB`1T&1~LRz6^2!0QCg}H*3r#D3gJvLa_T}jJQ^!_+i_R9*cj$7E-Jb;w_GxXi@GgY zDU6+D2&^!UO9~fynyOGrbn}ox*+E85T`0?1g;LAZ%0)MCs7&5%%TTK09x?=09g#h1 zhS`$%Sc{IS!{??-;%>T4NJ-p9MowK4{^S7>ZEH?(Fyofs_2xAvS2w>};Bi}?QW%es zA+W+QOdc>WRORs~-7=&+zC=b&T^@%;BSz4`t!2va;-F%-QZY;91zWCCBF~c{uo5{o zsb`SivX^Re5ZoTZWX!CNgsB@(5DW z@^B?vb!+8Prs`D6RnzQ}8*Ld%VO&p!zzV~ZlD2YFC2=j?CZr@r$jGTnBFH()CCD;Z z>y?EHn6{Xymtpk-OHK{#l?QCON^#szhQNx$lyjI_sxrBcZXHr4_mYuQmx;d^BF765 z_FXM!8YQ=G(#BJ^1f@2fBtu}eVOR{&N=+5S6Lgc1g7`KWIdwt!{h@ic2A!cJnY^1b z)gsfkb)0)nAwyurVCWBx(o%&mk!}uB2ouQ2sS9C+XpQh4XHbhFPPFAHgTq=f1Xd4g z^lcFhJ5?6P(5*tsqL+-Ex-9&;?cr<>Ll%*8#bAgG8g{BIZl_y?l*KJ%uuq`tw zhKI-ySTPtPL&!;$z=L#KkP`SL8F{~wz@S?+?Y;JlEi);BUyvcjLIRAFDuJizwjd?& z6Ebq@5?CP8M*hSU20ZACGGqu#F6p@Wu#gOa6+z_Pr^AtP(FiM52J`6FAZ0L{jGVd* z{5AD{fmL>x)2&^7V z%}AAkc|0VP!chtN$y3g93za_Rzzb}7|H zN;yN`xYd@Kj00Q95Lg8ybty4UssuLCZ9z)l0y1*y5?B&xL$Kn?us#@5#(2FgKPiN3 z$q-l}tWIb^NM@=WM(7qH<*o)cuUCB~`(QR0cQb^#ym zU_(&(a7u^|$|B$WkLPPbbpNevQ*i2R8803(jM zb?C0fk!%PmBT8aKZkkVs#e9{BggAtaTsa}KbBXeLq|RCwOC$0ztWbAjORS|3D=ub3 zP?-@pmndkXPm#@h-G~&~$VRT5BH3nexA=;Zi*~G)K#x1w5L9{uHiM(~`P7)^>qVqS z!bYx~8rebNZqXH{8Lx>o6S(n8HUyO$frG+v1ATJ5jIS7x94}!bS5A&Itd6R2%KB8& z5&M3-bAhbmbFroZK|alfpb}(FVRscV(kIDZ^OYl#S&*r9tRr?DaS3=x!BJ`qmlt3xEh ziEQMD84=XUZvi4~i!}}+!u4#3JwpU#mQRFh`05aea3veLaw24_aJM?@8?ojA7rw@ZpmHJbGG*H^pA28&D?}v2 zm)OXalOb;|)KRgNSEla!xS{jNMQjKvBSOuEZ=Fwz|6)6jx}4@e*vOUBVsSPK(dmn~ zlm!yWHEcI#Wk&qQ{S8jRbo9fDJ*VM_@S}W}Z)s@AB0m664!!{Y!!7Z^XZWAH6qes2OGI^I%GRG#F5qorxCs~)-IsI%h(W98U%K1WET1Ee+gd` zqWfROMy}lb*(ii4tiogHJ{@Zr5a6%b5L5yLMj^CKJ_SC(*M&%dkFt>~r$Baoh$^n| z5p=(aH4GT=&uj=P0|MuVnA2_>x(9JG8-nWo zz%X=bknj8x`HB#oe;gaRa_46+^z3&V;$$(gqqm>b+Tt}R={sI)cMa;nSnRitJ=VP$?2vPmLSslcUF1 zj7W}IHge_U$OfdWvMX9J`{q~^ff#?rhM*E7Fd*d{=ab?Me5Ht_cpV$La#CckKf3A*jp zFSm)4T&72wiTG$Px_#)J^S{`|LZw1r?lZL}E89a35LPHt{)4Xv(eeMzMy}lP+0r;w zRJHBfuD{}@En6?U0_VW!@ElmdhM;mFu+7&q%%j8Ee3giFIE#&3IUTY^v+2Rc{Z1?C z*4yI=8WA2JYaKKWx3VFqYzPcTyLNeG*v{98NQOtVkt-)dHXN<@c%w9UcC1}MgJ-ZI zs5A(SMuJ5i0q*7NLL|Ub*vOR=AbTZ7{tCi&eFhH&?~64JIPe}e1eF7UEq9ht9u3~b zSBFT0cd(Hwr$Lq+sy-wd1AY)|6ZrqTYzV6V1Ib}(jpz7p^YtJ){+n#%${nB8|77=U zrza2l=q7d4|BLS!x^r*{8-nWpK>fFj@@Q}%UmYS19?3?ooCev_H~-+`AR#u#8VLbm zBO8KBh`?B5z&wu{=kXOIQezz(xpHb`=S1nU6Z=&s!*OCd)|!iJ#IA~4d3nC4Mp z2VW^7C2DNs$|6iSpO6mI6^e!G@p`C9q1e$VQJOALVODB*}-_$d!}CZDdlCgp$#Jjx`Xt z@hdh2l^bP^44CFo;un0Sh?Mv#8@X~yWL?tqoD^)n;^Zd`-6c7Z4MAl=pi3G!_2oFe z9z@3<%|@==@%an3S{?ZYl~4@0Ce|>B0avmisNN5~qZLf@>i%VXWr!4b6dSp63S>Jq zCkNt4^Tq@^Ah9#nD)4`g4MFvPV2yNckLUbZz9vNH&#;jzcYap?8xu*p-i!e)?fTLd&*}fp z*MjKue`O;-Y@FU`qfTE@8#?bln+-9n(}gXb)6e2-L3H}*Y~;$Fo{a!>y0g>uwt4J4 z%7I&B4TOrnoee?dKwty_G0mgIqxnh^DY2D}TsbAO1A%q9g=eRq5o;XK;a)Zbl@5Uu z-5j$#Dm;a+5RnQ`Vk1B7s1P0%dQYrzK!ta)A@&p%0>eY^;44I=!duzMl~W;Gzo@HE zLGR$ZvDN_>zRiZ9av`vO(Y4Eq3*Y2xL?pxCvym$&L*7IT`ei-EL!LNv)_5Qrg35(Z z6JeX>QQ?t%g@{ym1RJ?>DrCb(v)zt--%}$nV6ZXPFbE0fu_3552n-t;CV3QC$5)0( zfz@o}$|;ad8KozxV^c;+tWDtk9c&1y_XAT#f%D;Od_9PcznzU-x#P1{j4BnV%_P0) zK<$4?tZCr?7qKCz{tv8Tw2boV|2$tEA`PC)My{L&*&EXfGQv;98U+OSC>w%GfWWy5 znK_>8Kg?Hz==u+^kt=t7ezt4B(+xHKzlyaAeE$nJ1l9L}8N*&?kLUcK@--nk|3_@( z%AJ2;I!n;+pksw6)`!mgk7Gkn{eA*INgzz|Tz)iP38Kr7U?W%Va(#|k(f-9NW9@<( ze;FHs>iNLNHQ15q5#UjLU5Es@h>cu10kWQdzcX8FB|DRrI!_O+|Gik_fCaN`2r3H# zJ%7h6j|wwSbVmB1TfZ2|_ojtxO&K%m=~TH`tX)qFjOj(-Ik zxpK#6jliInbZZm!KE8A9OR;u=^S{7`pgKR$2!KT%0Y1yug-C$EVIx;gfULu}v(p*` z_AUQMtWn_oe`iBby&vfCW#)LU|5v^uMA!cd8#&$l94CNOpDJu7MjiUqm_QN z(~nv8kwN@n|NPXJTdtRhdIZEGeelao3Zg!Y78{1wV*M~$40bec+E*0Ge~NNB$2z6w z_O$f&5!PZCMw$l%t~3t~U8o7j`IDwQ?PP98l8njDb6dO}snKaKo#{*rTJ~W8%|~co zU9p4PslqFTGhPhm>%(Xe<@p52C={9#U%C9r>KTTEG zC#VBTdbP=JXQtL3%+%5{51bW06>B<#uL(8;(NpurE?a{*W4M8Sf40t7j2Ogz^`+yZMWn#htt&Q{>jW_U>Bf9-{Y-F#|c(sDqdtJ=a5PsAr zCTg?YWU>+JS$r+lPKXCzVM9Z8@Y0(oQN=Grn55%5M*?C zf~;UePzhoTWEK-d8tC)lY`$VdUYx~7uACPqBfJm|Oe+}=#g50v8VOCzt!xM?HCDsm zRWUU(8+~?c=j%pf$D`TEm9t|R%8p*ruZg#ZO(c``K`TU)XUAF#G%GXC2ftOhp^IT$hZ005gGDLHge?*S%NU6H!k`y zfh2WtGITHI5Hz9?3?ooEcb_Dl?EqFiYJWYa~RDjcf=i zH^^CPW~0xJ^Z2?E*|Cm|Tsb?AN8-kGr`Jc9mruvq2gFF&5L9B2d$!8Ftl(kTdE>Sa9g1Pt`s zqfhe{Bf9&q*~nhx`GkT9*7-foi<6vUgXxR_GkzayBQWE4YzQhd@Lq7xM4ubK;j2dE z#y_)>E9b_kPQh7o7y)`Ln;g2Ia|RoNN)NmjTx6xskkk0u5gBqa8@Y0Z9P5-_!7R;9 zvDQJ{*v5vS62mxFF_<@u;WISX^OYj<;Tkq_<$O57;Y0E4%u{0x1WG)a4MC-ZvDQ3H ziQvr49A7UYD|WJxD`&;&9xLpLia=BH&R9!<9&ckqQ0Z|lI^JGlsNb5rnXe#`Cx6C9 zuAC>wyTw;D8}qGL`+yzaU_(&Zv4X^oz)Z~7_-YY3@f9|5<(yc8aw0qnv;Wl4`RBfD z2r4b`arTgfezaJ`*Nn)F|N5WDjN_bgE1G>-&n~!(_z*1Cupy|dIENA}0y8h8e65I# zSiwfFJXW~bXYs7d6JreoPTawUpmKtgeFkS-9?#c{$ckIp$d$9=XeUktXIownYa0;a zd29$OAxJ$`e5U2ue5HtNcm^9ez=nuv5}0X82iYSas+?)LQf$91nQ8eNN^YtN8@nZ`4VKLKU7ed)g%R}rU$x0Qx{2&{G>ScVUC19YRuRg$6 zjOgy4v5~#V^J4|E7iU_WVk@0#Ic0k2uFMiP1eF>1OiR#2pBu;XRU>la7&da{+&I-K zILb`RwXtSG;JAtnL8S*i(^6!m&ydUc+7TJDg^gS}LymRIu3)BRSFCkFj6NHJN(?-Y zMU3UJ0Gc9k5H4rHAMm7YM5_n%1x6fzA>-l;SS@9Y+a^}HUyOx_)JU4LZ2DS_?i)!aRwW? za%LRolv~kE%VT5BgJ5wB8-mITe5M7n&S%6;e65I#*v3Y#oDpvJSv=G7%vb|~6HjA9 zP&q-$K7%tYPvz@HWW|%&$d$9=Xs0FxXIkDHYa0;a-E0UdAxJ$`e5U1{e5HtNcpDoz zz=nuv5}0X82iYSaDx7Ia5ArXWYWZbs@d6=#&W4~8(s+-Du@X_em&h&&NS43CH9aN0U{~&?u|`8oxP%Qs<;o@KnjyN)K6@_Y>q=zLCN^^A>^aRX zNy>ywC)Q3NOp6UcB@BL^U7?viM;d(fh#Z+@BUjFm7O-YvMIA@>_&?Sp`E0~>Gxci&VoGTtNw4D?f#1Ne#&-Mt?h*$YAYD2Tl`_i_v{ z2r4u1u1(NHpBv}$RU>j^EgQLVZk*~A9A#vED%MP(#{?UKN)LRiLy?s}L+X6(hzxlG z8@Y0Z9P5-_!MOTDtaU()7qcO##K0GlAjbK8cp+aYA|Ia5My{L>Cpbk`JgWZ5SOb9) zA7?{QDS;24;`aHh_$$6%L{@x=ja)e^PWMWUwAJC)v6ccoe#wTQ(gWY>P-3Xhlb`by zB=Y1ZY~;#$a=cr7MRPAF%?#Z`Ie`s9Wd}Z#ikjzh;#j^~L{1#VMy{L_OVC0K&%9h6 zYa#@VE7%ZJTHwpZLKgbWxRkFMkr|h;kt=7$aZb4v&ASX@%>!0+*$`A#;KQkybv`3H ze65I#Xt9wiXM~%57SFo;uUG?t6MxEvpmKtgeFi68Udz{u$ck67kt=7#(N0YY&bj=b zSlfUQf6IoT5`xr2#iv|8&sU1bhR?8(18j(xFM%nSbdWs)qQWVcqi>$BPb4=ay=iCO z#hq?Busw8|`$#s#aHPac%lr;=E|1_VMI_~aD^flj=3GuiN}_DyWgWX*vZ93`w3-b; z^*26#T4bf4v8>{2M|Au-Y-BGQEmshGZ}w#=R(7RRFtu1ifg`uGA*dW#k8XD;w$o?H zl4)*vOUhV>!+b(p1gSouPXvN3bENMA^h3ifygWn8Wy55*c$a8@Y1E zoQyK2Xwv3Uu|`5bxrhxxaay?K!qYc1v33GMnrsLv zLGX>ag=YF3nc}NQwJ>09FZR%XCqh6j}x$p6`b7p*H{CA8vnwE zpi+b0&&6kWe$Cg6$ctaHkpsMln4W#%;V`q4jf<7^7qtA|~@O2}y<4J7f%Gr_j ziH(x8rZxgE*L_c{oj{Oxu_34gDd-c2%=9_(4!(Lsj=YtPTscRMb6QySGV=g6z8h;E zP~+Qd2r4!3b&Z&HJ|n)#*NVu9zh@&?&WID;GAo|7IpnUPlgb0x5L8m&dv^l{`n-4~ zUoj#t9>GSgoEK;K#b(c61fs^qSW_WtoX3Ws66Cz_Y>m;NbQ9ZBpDFA38WNeZnvGmJ zQ_`^#v;2x?X_8n2fgd~A5LABPE2F)dpzQNmQRC}HWX0`l*Vo{jlctcAdeU$7yltf1wg!I_w!@)aZU;zw-c%6V~&TbY8hFei40 z?wTCOhM-b{)?dYEV2Bp@4$cj^HG1$?(eqV70+JB1wpL6emu~+Bz^oe~A zz%Pt64+vao9vZq(6Oi-AOn2JJ+>Rs}>xwhlmd+SLBPPbj3NfxF@vO<7ao;q7r2C=`eH&you3S#dR=FDQ;F-=v<`^hbWR;lKv z-90PTOlZTN&W0d*W&UXBDob{ZDJwir{Rv+_F*My%?7)$|H|uh^G`(yR?l0H{k(DL* z^3T~2R9~Kq_);6>=cRAwD?)VYTiD21DM5^VlY-cL-dAVXjme3&Mth>u>DDF(-FBlt z=q7;yuz!lR5t#6gYzQh7jGex^R-?xGtoR4MQbbmKosC>ME7WN+X2JF3mfHX$4(<(| zm>$4}pfbW(h=DRf8RoNLKfXdlHtfSjuAB|(YzU7Hy#O7~k2Mei#JOw;Djk+#O@$Ht z6dig#AJ+0UBJyF3jr=g;Lub%ejYd&;n20qH_)up<49y42GM^7m;A=$W!)QRixs`3H7N!w`$@N#jQ1PusX*BH(^xZsAg^UZ zPzhqJ#BvGZ+2?cPReZgO+;}+~xpHnCWkir(r`4DU@ZoP`O#?oBo()0e!)f7WMA_tX z;4^$(h#dG78@X~0oMCccu%k9vA5VIynk_1W2QjQGE?rUEDajSWHNgt33fixHTO zK1Y7b*Nw=LhuFxKbL3={BRlKih_QSybQk1IHUyO&#)_LTJCt=kFP8GPBJ$!CHge^> zFmsE+Y_Bnq)FwK++Gz|4v?Vvknh9~^Mm7YM83nn8XP?iF8~Az=xp6HUxpHo(cQlQS zw~~6hmb7;!tT^0}%(t!-Lod>>N6S+>Z@GrNAjzqo6JF z{l5=i6QckB_&?A8rzroY{mdP6wW)#38+(JU{3XyXoXal1jO7py*0Ld}WH5I6Kz9N+ z&u7LMUo9dtR*6I^YL5KGET!0bvSnGfhPhdk(8G+`Ewpl(CZsV&% zWWreyXF_aTmALr}S4ys-w-#u7Vyt{l$SkI0on*~pc1C7sLi%TNZ8BA#3tYbwN$ zOV|)po}hDC1vdH|xsb0Lkt3Vf$dz;C7(1R6M2}9aalnce8-mJ;)3KICvqDhM-cyI9tMKPyz<}?07j} zF(Nx&%0{l79qGP|DN%T{k{o5D5ucB>5P0z!HUyOy=)Mf!G@lWl;;Tet#QkjK${CU6 zp_&nmt{9mRv7_ECr^mm=nhW&!EgOPL4?GVow$tazLwx;+TzQayhu+B&?Q&CwdclI8zFGq zz=ojG0zEMRGtOtlwS1+BthkDeTsbSUUaO3_$wW;Ye$%+SBX)eXbo&w*{=O&HR3OLQ zYzQhj@Lp@!MxP_Q__`4}(q|)A&XIIaAe|d;k2Mjv@fJ1&l^f`uK*Tnm6K~?{MC8O9 z*~pc1B8?kHxutnVmX$V=(Dt8yh&2_s@pU!?l^bZ>D6rAz$XEHg5jpZ@Hge@0N#lmz z@>AN8-EVH_Jaiv61eF_T+(2yeIq^rf=jMr=_yZfca!#aY(uh}pOeLLKa@U|Cmb!~A z=7B6@E!&-$feb%<$OqcB{NA^oHj6?FK1QjmjaY{ zLadEIiQCu^R7#+|63jTC6_4dBMP$V-Y~;#WaflippAj3u0xWobtWCgz=ddBDEI0w1 z9+AfQUVkQE38L4Z#zwB(>*kIRE`@2&(hZ9ifIzJ_p{**M-P| zce9Zz=Ri6$))hO%>+PvQt1iYP6206a)T#JMterrJAF?5+gg|G;LI(Qm_#R&|B0Ijr zMy{M4i&eW&{3@uU?jE`qaX1@-N`{lLrXjP(_x+)KJ&3+Ph>cvi@6+|!Sy>e~5SPSS z2l3!SHUyOd==yBiET0LR`05auuz`(SITJ>*D4<$Zao|j&oz%NEacDrlA&(Cz+3?wl zH5kazU_(&JVY~?pmQi$*5=(u)O!74(@@1TjTsdFTo#I(35|7J%Rjir7l9#g~s4PKu ziU;iTx$#oIUPNx($40K48|nCiU3P_?kI%%~2*mgl8-hvD`&S%B_e5Hu2_!t|x za#o~kD6)dHPmm4tNq-w_B+%j^HUyOx=o$*tI-eI0^0gxJ;sG{t<-ADO?`9=e7$%lJ zY3N?aDQpNTAJFx?mQ_9vmhiP9^5A$ja^*b8S`BgTVXvlk)J%3d{n@UV4hn>a8)9vQ z@Ng{~f=UOx)j*8%S#cF#DIzN_XCqh6ifrr(3a%x)sd8P7Jbfg0>9;4`JR>(r1A8+Jq zM&!rq*~pdi6LtpYN9l?_29!xEef(j4FOU*@Yp^!yju$d!9O%PQ6D zyNd@l_j&TrS>+$uiJw`8@aoUmGG1e$Pg(oCoR21KqU5c83lh85^DhE7=fK z4xlFwXp4ORkMK1i`hOW4xpM!f?^)2LRU8U#i?t8hg2%EUs5C&|v)~%$v*8xLLPR#) z#73^14Tq|Hpy(C!&xth(DDX@+1eF3OV(Eag#`pWv_*xMC{!}({<$h1kDO4p@90A@R zYa6)#y=(}o`_Xd>O{07kyqm8Kkp=H$BUjFXbPsT^F(VEtoD`cpvjay$D`0*YYawvq zdu#|Q7tlSxzG*%qzQb3E$cS&Tkt=6Jy5pjE=Uhu}PLu+tJZ0#9 z#S%6Il>+EEG}z;L|9HM8MDHKNMy}lZ*?Zx$_avKXBT9s8V=aVOa1|SZN(6LmOa6Lm z%QTM@m-Ce(a$*Y`xpGdVJ2J(g_~Haylm)wDZ2}hb*$`9~pmWoiF`nP=;;TXQdz+11 zx!;devk>_UX4>_c1oi%#Vl4yjzmW|=^*%ZlZJFe8;PrfEh#Ytg8@X~09Gr4MoFj)P zgI|p`37r3BHU!oA=seVfvc>cI7x`Kcz5Y2ia^+r6XQPwdsMNZmO*1Jg^t^a?F zwGSxp2Q~zi0_gk$VwlH=-}6->^5J)E4lZ-PHej_<`93*`6?8-hv>^z`yFD?O%s zi?1J%Dc@itSI(4lmy9k$YZ@oal0*Mw=%n)?HUyO==o*(I3q6MH&)1E}kbT+6l{3W2 zHByFz`lXvaSSd)MP<7@~j z1<=u{)E3X{PvmPs^!goa0qpbiG%b6^(tnk9z;ASi7L&U(SZ0dLM1= z4TC)YZ{e##^#8?d8xz9yjmbt}1xi2GF7W?dY>1)!Zy4nHzs*;L=>I#}$d&s) zJ^R%?x)F^6Z;Z7LSn&E3;${0S+Gmmc*PIkfUgZkdY4Lf-LbI8Ew9=1u`Z23MsB}O# zNPG5qq<9V6IO?lJUdcwToD}JC@mZmzhq0lI_;Rdiz=$uhA*e(^56!S`@>uXWzBa_r z@M$)39Uk9Scf5S$8xOlwLMm;|A zw4wU|%h(XZd0bfHdHf8%4n&Wi#zwB(<7xUoGidc2Vmo{w{ktXBE~x4^u_36AN7H}9 zAkY8X_^J^7e?1$ya{s5>lI(MM(aQg{SlfUDPh~?;Ie>0Ua*XnL@MOL^L>|nskt^px z8V6>(9eEl?XlvTLW9_c<;j$ zKKB2eSkr(4-(o{hDS&4DwoM)jzQNaq$bzr2kt=6GI`vb~;XCN*L#KfIvmvPNN2h)= zV?4j_%U6Tw_eE^v%Ke^B^veSu@X`Mbu_i&SU(bf1x*eV9Pi^tMzJ{*_(d(mZ4(J7~T)9%~P{{E2J`s>_eVy7$5m&);|ORUrEN@oePE{he+-AM}!LZKB@CcN^Uo zYZkcu1#Aea+tID(V2|hh=kYZmdjHvMBnMi0@r_p4MBB1+O}uL zcz*vNUk#$)-^WI--0x}IE|)yw8T|vXCV|_3#)hD}9c|lFTRgA-n6CxV>px&42fUsz z=DRY8KkT0$qjFDI=H3wyi}Xn>cPohcFj_oecr9)lMvK9Y=H>f}BKc2IF6UUM=iHvo z7Vaag#V(9A4+vao9vZq(6Oi-AO?TSK+>Rs}>xq{kj!!S0=}Zh-_GbO&D($B8p26)R z;gvyJIe&1yJwDy(s>1=MM?A`}W6R1Q_SckHtssKMInoT3XGC$%EXG~aRONg^y**dE zGnw1f=}z=&jdrcq7q9)93Y@)pYpm%Iwzjh&h@P518}ieXGh?`Ie!}`_zD~p-wv~J~TsbR_oJzzQz5RZ-)=ql;WFkO@_rzKTWOx@Ff=UKsw|qth$0(lz@8By#&SP};RQq4)E?$jpv0e=Hu z6{26)vyroMf>66gK?G~@9`76+l@g#nA>R1dO(q+=1Fe1|)-G2UZa^>{M;zWK9Kp4QPhmO&u6 ziVZO&1++~*1up07LZrYJHge?@I5v#}s<_0->;1-f5_;L&u2}1U27NXJl?KL}o6H=+ zvdgE!U3`6rRA{r2E2qMVDHR&Mn%Ev*OYRypcGg>B>uaDJ@upY{fevqELs02pPBIz2 zNzXQ)60hg$M5M%P*vOSr;?R^5Go78Gcf)@*)+k`Xm)Q_h78na-%%C96@g4s~z8XZw ze~yh@x#JH{9WO?cTB6?=hyZ_#wF`Xz2Q~!N_r`iS)AyN0zWaaA*M#W)-?5P^cmLAd z{j#dm#yeuqgIL~CD@hPmK6~h{!U!9J%7-z$tI$nw6Mcd#QJJ`sTyZ_)c`3s+a9cvP}{ysJY)%AffL1m2R_80KgAiDi| zY~;$_p5^@YyBjlu{xn+Y?~k<#JpVB^1l99_v@f^EbN)y8nh>4;K{j&b&d);rj&V5} z*ume$`(UhD;Qa^K5LE96LcTW0bN|oysu11(V>WW-?$0KI3SPv#d<Hv%ae~2{DvO(VW3-L?Se3H z6B~j`fxyf^SmY648($Y90j_5wS5AO~(!t-*n-88AYZ18qscZx~n$%!wcL-3L$R zYe97S92@yztDczpt}A9 ze47V${`vFxN)TQCY&LS`E`YokZ@m3jta(6ykFX)A1Xvy-fMb{!0Y1oA ziAaa{v5_mML)HlN=VsORufT$j2VxBaBK(XEK_x<<5im^hDDY#xGDHgefQ?)^1+wkn zgISR{iI_0i*W3TlzTolmLw5*{VM9>4V4g2)YzN0|^GIpffcHvZ zx#8upc0pL!!iJzyA<#Pji#!5c%-4lTfX!^=$_bFI1ju&+qoLrgShK+YZ8ike|ACbN z+91#Uck)#sx__FD9B_Zc!N72~aC(qw1Oyy-xqs~GSD;0DB<@gJ{4Dlh-t2_q)qD4Z z;}h)@j%Sh{{`Q2c_s?H)@liHk@Jb;KEj#7-!)#d@H{tCGA5aj%6LN#+qwe`rj?+1- z8$=1C@#?#=wnDu6HXDNInt6BKn&iot>Z~byym0kRz9z(Q_4md8+>0k3r)L;S`}GmQ zflbHwppSYzQhN+=K0$AfavZ z>F`{>PDDC9i;etnqJusuG(d-s###q-_%It{579x}=F{N=e4U7N_)9i&<#ad&nhdcH zkaYazFJi3(TKtp^L8Zm&;&#Kc(Wl3c__`74@qIRO<@88rLsa8Ya1`coFC4nBaWor( z$_RG@oYQXLM`9kqSBFS~!`R4`li+BG5yi)1UKVQ`M21JPA*ei9Rva0E$75c^*N8}k z3)sk&Qz6|FtKva=U|b+|n2j|Jm@vbJpfcgC5+(#rLTvICA`)SWja)eqj9!I4IWWM5 z*Tq@~TzEAbg35)GUWK;J&l6t3*NI4n1vYZ!bVzqdskl&dGU69vEdwfimJLCrf_sp@ zlPCmENc{zdkF^bm@ULtLDiKODh2Uw4|H9XZNQGaskt?Ud zdPo|@%NgtKsX1+rpRjw#bC5V>$ zjmxQgjfqq`iH%%2m5iiQpH+#izIk-4X%JMlvLUEUDVg%phGnG5TuIuMUv{|BH=WIR%X7L7!=d1%z+Lng%rZdo~1>1|`jdHq46# zf5%seNQM8yMy{L+#&C7Pfqjp>Z|IEj5o`!55lRN9LI?N#H``hBL>l}j8@X~C7z<cMgReZIGlsJctTsbAu<@+j6P@PS5Ib=jdP=!mDGA10KAB z4MF8WNrqsU<~0Zle5HtVcrhEfayq1k1F8lga7@r=V~qkD{0$p|N(1+B5T`xBjtlxE zUm2qNKh8$3-2Fy0Fb-6~qQSq$8V5A^7d8Zy1|`wJFwKhwzve4Nq{A=S$d%KUF;@v&>}rsVkj;Cau_WJJDMB! z?r|Z<>El8~tJG*uEuHC13|jWPSDTN~XNA0qO%}XnNGr?E3VAtORz^%XE99jLB6wEF zUOZdkgz;8VZ>trWjfq+^TkDDCi|whvs{X%dGd8i2D`&)+td&5G78`;}jaB8;00Vt)H28`UxiQH` zuACc2R*}`J!dB$9u@(X^Ud4u>@}elKu#EFL@p8UWL{7Yvja)e=j!ff4S@ZGvSj&J5 zpJ78#xnPW}Tg`_y%ICnR_{tDDa6cQlat<7oasc9JprQD;Skr(6zhy&ENnlL3TOR0bHwmRbx5^(ao^YeMw?5;k(>-amG- zu{+6!8N}K9?Wz8BAPn3XYaN7v8`uz368ODK#4tY+T+3I8$c3xe$dz;9h{;x`-WP9M zt#!rr@gzWldtwa(8r;o>pwhrNazBd&woN_*cJXx~GN8{!uABkK+ND)Xc8|9LGE>@iko>wH%Hk?lL`{?9+Kkt=6K zmO0FJdX0W#XDD-6%XVaD7(|FMHUyOmq0Aw-$!EYyzAnVLFv3QzoB@j)?b6Kg39)8@ z|8HYMQ2p=sB29~Y??0BW3DNtvu#q1g-p^}FAYpudtXbgw=ddA$^L}oT@BL@;H6eQc zX>8=my?;!jy|dmDOIYN)4{Axb+vx^4@S#}afCKMmLr^(j?Dx)cMBgr-3Ge0WLuA6c z*~pbM;iy)l*RSnr^rwr5l713v8t~wUYzQh3{1Ii>DxU@4<7-1?!FSlmm9yaBcBeZt zTMrH-9`*8}`vixxA*kLz(VKYAt?|8nC|?Vr*AHSNSMK!_`rSc$JU?<$v<8JU3YWwh z2oc~yHUyOe{%S_tHlGoj_&O08v4M?TIU|nl4`y2lp*d*9+6H83upy{qFwTq1(gM#c zp9hnCb%;C|XCqh6gCo=IP*2MTlEYWUS_Uk5IU9n?0)MT6W0cQ#+n5Tc!&)_ zWq?0QWLo5V|3SVcMDIVqMy}lZ2kh$BXJ?ZxdKBE!R}9@LIE4*Cb^8fkryw^aD^xiD zZ3$lqqQ{SCBL_Slv6l_D!=>A&A|PN>-hHu~FtWF2uiv}d;f~eY;RfwSzlZLIo6x)A zYHTmzB$P&$?S{LZEh}RL?1p=sf_OOWhC5}v(-wPOdyP(8zMi1p>DI)HA7+xi_$`nu z+#72@G!;)_LlE6HZ)|Q*ycsL7&u=)M#Mg@$Ms~B2y)ZIR5PNT1-0`#ZZZ8qT%e{WR zJ)RVgEW9h$J|M+A*br1w7>7xwq(Ck6>F`#*MnpRNZ#Hs(4iQZPv?^&BihzJtc3F3IyYe90Je-r#Otf8j*=dXRStS28A(?rA zE!1mZex@KI8kmuY-L+~H?ZGz>cBDJjdse17Z(e97V!v(k&{uMkPGX_XA97|7w8#nt z%Jm?&T(4aBR}jH+ZNBQ@z((UqVYu9|Je}@TZl)it^rM}A%&L$1{Y7+2+Wm#5BFzEf zzuiXCTexFkWb6D14u8k$BD3!gy2-+`7PihG<6fQUbh`Kzd5*HW0(n+iBgTXilNSC^ zx6_%yAL>olCsMo1MuurSM?$6XMVOm8+*aGs$W(zAj$hw0c*k zd#CuJoy_e>lF{)_H*vmAbjEx7r?IRsyFKB@PYSf_4oJCwmau2Aqu!+RA=3+@cFMt_ zqV~Q@i#?f2s2Fhg4eH2>r6T9*i-L6mfp;}6ks7;1sL|l~Gt+=Hn!7FYir>)R&ep+; z43CS2fVMRCN`zy98)@8+fB-Fi9NYS2E&91pEqZLTbDHB@9T3qDLOeEN}Ch|H&Js`aT%LQtQ+R{QkVYzuLpN=wUp`b)Mf&!<0+g#e%aBo-p`>CJo9 zrzgAhRHcuoQ{S$gdg80NNf7Q-X=<5Mk7LX7oO*OD1UU7GScuH2>-MTsz2GYof7GWR z(muVMZ6WScX=#~Hx3Fb-KD{^=0(`nT79#WM#e3DKUPV>?GSsP`(N68KO~jolO)Yb3 zi!IA@Y9kf`oH`i`kvVnCUUlkHH~Q+%HtN`~YsbEtZ6@wmX>OTgU%{5;Id&ly0v!9| zScuHAn~EH}M~^R5UFqewCarNX{IIm&S$cIg>hQxqc~x(z7-ksEh|YCg4uPC*4Yf6Y zsQvqCwzar_rPXEr{cE-?&%d9Dg#iD4R6*?VA&oK|zYCSmU%<)!ZRQRCh7yT-> zRIljIQ4o7+fM2o87~tPJe~>V4b)!9z>=vWtb#Ju1`52*I-5d^o#9kW?zc6ArTv;*( zgWxMuc3c(fC)pOK5UHPr8t5!(G2*L8o|M^f>OlQ-YQau+A<(Oc7UeY)J+@S@ip(mA zU=o;oSVA%g=tCc6FQcde~_`t4Uf8} zE%y8+y`}Z`#L|9!hnz{XG862ERHMI88gZtdsH8hu2!^pe8^x4OR!a}f0ou?neoa+jZ2sbihCU0)MpM6E8gTwQ)=^N^Qb$G96R2w6 zA4ZG8j=}ul{mytztR$%A>jmUmj_rb|*X`T9Onw~Dyh45)(!4tT@lol=`SN4G=C<_P zdFi)H(~nE!$3e}<$&V|Vx5$svnw!&W*T|23n``CAKFtf#kFDv)Md`Bo)f$7AKk z$;}P&V{!9Z`SFP6t@7hh&FkdH0nH2L#}k@Y$&ba&$Hak_dd#&st(czelsx>lnnj`mM~nruuNKOG_N>UWbwofst6 zkjVQ+RDp}NG0iv2g&S{`f8H+tyi@*pm;Cb=^3Qw4pQI^EUfz4}VdAH!%RgU`fBshf z`Lg`;75V4y|&&ofamw&z}{v@hIscFL4}XO{1IxIja<>&O?C_#tqE0PvZP)l9+OnPPZb$_lVu0rWFf*gS(@-o7At&{ zF2aIuay1rwlgqN;n_Qm--y{*`H(9;! zQ;dXfl9KY9tn>E`<`0ugw*)g)jqWYHXkq@ye5IE4>%kM9nYu_V>;1YU@BBXF>f;bG zCDpI>=4N(uS_{qF1m^tyH>clTx{$pbL@qYmI)7-dv7;qk@Umq`XJ;bTjOE`iOCTlH=_(zkW~05QhUuFr@^R8GHj{_sZcro_DGx$_6r#-~NC63g|( z^1S)O#7kv5?aSbo!H)R@Iy;)lxL68x&%*RM*DV@|9{#jE=CPObl^q9UU-k6^#~bO` zuDmQC5l>{lsJM7o{!LWrN%_lQe&6xgS$TJ}FN(PN1W^{vf%uQzj86#*5*^h|DW4@s`x8{ z&AsYFyfH~GXUy!JJ~vliXFXCw*<{|aFfuZ~-)z0nU6{W(@2QFvb>i@XZZfLok9%SX z+02aW-U!bnOFL@4-{z&GquJ`dQL#i(Y*Cn4m|r_SGm&1_tGpa2@0sb5t$m@&>xI_y zdcmIaP(c2~Lh}vcF%#h;t_4%#WP?N-;Ne}!#Y@*yj@HEjNKqcE>E)3=VcNnhjrv0K zElz1{=4zjoMyiU3wuy-*Slnoj_LJTHh51$G1!3GiL@6{En(uN-VLemtrdW~cqcFWO zxiEibxy_Rcrl}V&73~cAvxEMq%qkX|?{}=`G569fH(yb^VcX?bTwlBLn(MDvm_M&v z`FeM1)P2r0hgTQ3ZNK`8n=BPJ&{XgqR5~Q8BOrrY8d}yu*>)2VT}LOoote?zTzfna zT!aIcVG1};kJ>IYO5M3JAZFBZ;wK#^8UdLE=elG5e2NKWj=Y3fcAiJ(H&WH`9yJMd z1yhfkAGh_g+BI8m-hR_9mus%_i zMDT&fOj>V<(W2g6Xnxl*=du_ekv=u*J4EU~o*Lw##ud_3S5RkSRGjH7_TkVA$$D(~ zLYiD?{=_My%ZDta)FKZys!|UaRbpUO2_t<;8!J+5Qd>Y5n!j?2BuaOYXp-Y<-_qS{ zXi2*FJFP^#CP3`nYW~Zf&|g$tvi^475f@Oc+~eOI3u4@P>ou2ezq+<|VSYU|0?FJX zf6A;|M%RT*rt7cRdQ~c(8~~+w{g^2~-uiV>)~~bZIE3{=e2n$B{Hr4Z(v{b5+jdiJ z`?gy8pR2F9=Blf=FU)V@FagIf{c^6W*-X-%DjBDkS(qOQYheP6&RA~n5?}M)P_otO zPbb}U;AEkB@N4byi5T@oRG_MF2ZcEG%}(Xvj{08rro2F)OA_c*rq$a78nrtlmP@?E zq$|erR4P@HaIXk6z=m)#ZZFZZ?+&rRPq~kG$}-Lpk#o~6v6F5uX`)$TW!)$55hFy} zO*g{MyRUNVKg|dv@jl%#<zG;t`AX;3y33i(s8Dy?s|t#-cWc6<}NWbu0e za%b15n(`ILtvFhHm7okxH)Da>r?e{NC@|z?8NqdOXQBBRNAZnJp5&Q9&xhh_BU%y) z;5Ee4wvMq9CCNQFf!K~dOlAG{X2taPoGVaic? zJ&#*in}ANny44{cm$9k?Q{LrQ+_?Q}V)Ya9(%a1#;&qpcODi997^TEnAuzjNNles| zL6|UvYMV?n`eN2W9?aMuRb&szpG>Qx( zw(yL$JN-;24-x!MMijNpw%?2|9`PZR==2FwDnxPhh**Tt6>BsnM1Inp5C`qy3wp$g6>R(&Ll~W~ z0t2Lp*v$cPV%d#6M6CH7$77H=aKN$-bwRl~g^)M2mLXB))>vr1z_Gz$og+F_ATk5$ zh@QNQ7NwP_fn;ymbr5C~m=1vDC<{(`z+wlC3ANQh{Gu{K7{hdldg_{;Vvb)6zeDxOIAI2SFJY`1pI121sXuiWS#%X1##>fWbG(s$Ds&~b5 zCKoc!Wr2Z9v^qE|7h$9cy*p5O?9}_SPPs%y8MD>LmM@~}6*c=&-no9;EsqiFQ7_we z%T_Uoy@_1?)Pe%@S(9;2pVFwiJ#q52*cA~dWijc8_1WE$$UsKzX+NhoNESMp!7ViZ z&T(t386uP7m|^!Y!m*;b?DA~tANG(DBA?8X%WOUrt zNh3D*7cdn~8)F$K6374RluvZb$WuobFuHW|Oc0$J4V6y*(4L@=OduD%&R!N4T_wyE z(glrmpGYD(0mB|Tg7w~kvJ6xzJCQuVDWAydWu}sp6fTQtMakrto^et3iA}6sxq~!d zmB@I`2&Insqt2L-Gt{2n6%deTH-|d~##2+|H05gAnG93SEPpx1Q4==RQA%^CNL#Q? zb=I?^;x4nAIw@CKdFJh}9tJwmQQ4_gWq3y06P_2!LF7iAd^p6kfmckjeLB_A+UZW_ z0z<5VR>=i&Mxx7rbX$b2V72|0-)b7pqp@grmN|CA1fnG@WOv@$xG+3DL;x+XPIlOI zauGtY!chAv$7YtV%@B$0RDUePW~Y>#hM9_LvM$&#`(Q=fb^M#=4DQKI$omTr22^NmfUhG7XrJePA`s#DhzFiHwTHg4vvepIl+l= z2Thg_JT`P0iI{$^Q$|i-!jT^+YeOdwFuHhTm{zZr;uQ}(W)_bVwrOUGGgF$6-XrA$ zN_l`z<3!VJbeEh63HKx%l=SwY%cH(yq4`*+JmTCd4nz@)CB%NwdUwvpbS6R^V?rG4 z4Z7-0Z|J!os+n#tKQQWedwrsy<8@_N}RZ$m3DUd#7)>0=zcu&a%@VEk_ z_346i1O<|hn8L5MM=8)}0>Vf0cUX>2Cyl9TF*P~o_;v`(#A_$RleVaq;xrA*GT4rX zJENdjM|+J{OI!7nJ!jRln4b$yMdMb9M@)a+IE24o5@fWOh(o*56VsYc-*fiuxuS=ciT6-ek#%TwrWWRx7WzZpVj8%P3_dCz&CW%8b8ctS zl*j)9an8=sLS~A<)03~6nO}lvnP0^96T1b(VYwk-v)1D~tJLFGhNa{r>gZx&LVBhd zL{&M~mdX?p0+aPYORVH?%nZ`^og3TlHBn)#t)NPD+C_jzvT}(>97c1R+0k(JTj;L9p)+l!G`$@#9W0 zKztw}jHah3x+qLNMB9voL0bc-J%+e#-xe^{s%6bjJ66MzQVLkw?p}NIwyk(VXk!>{ zt$M`t7jy#kGm2L`J1z0PvCvq0pc9BfIHd-iK=f`>;eE*|JV+QAm}VJb2?Gj+79|`o zt`3(yB0Uv<^U^%-FU%jF{-n>UOO>4-SqxYt|SXlsSw*>gnGn5zlDj#&VC)A$`x>htGr@7&z) z3PB_1EFCF(a;Z2AaJn-ggq%}$>sXF!Nn0GOn@>NS?ZTCc^-mIv)zuE zwd~IctCp2oWzHR`@>{mGbA4l`(J%AL5(GMX)Y4j)TcC(?aoQ7ShJiJfC1JGK2cCd4 z3It%~z9LxeIkZvYrxk!hStsi43Q)1Kx&t**zb<}Z{sgaHN$(E2iB$;8wq(Dee#@>2 zMi_3(ejLl6wD5FM+ir88feK`}&AmxuSrRsg!aER zn3Pp-N1Bm-c;#rpS`tO?FJEI`GtO3_7O6gK1u0S-*^+*KqgR_sI<@4kK|>_I;_P6m z;G#I{fm$-hTFGR;HrXIYn4&f?$Fd}B$o8PrcFfh(Y0gxmirPRI(~`KwxGJiq7_J*n zYCDqtt|TFwsk>x|D+}N)Jyy(!fdQ(uMpESwR^nL5YvnI#Q(IOqbp2ai5Lpa3OU{@a z*^nz2Vi?b|Gv_gA1~|%%qb{5j|cLmTuu%k~e3P?evN2S3PtW7HtDtve##_ zRgO(Ix2TP<04-UoyK)_7ZH(T$LR%CJ4Le4*QdWRt3+XGDRr?L zu{x8rdydM4!qQ6R?4Gmi*`Q@GO)6?(Tue*iN_CnK)gohX#|tLbu|TRfwNCxSw4^9I zHSsJf){D{pnqD+XwWf#%7N8{yAHZ;n19JSLIFAirthw|uv3>XYZ8zO)jvjgV^}ZN4 z+cD@TVwj+aXd2BjV(s?F-FQVRhAgG1{|9iE7&!*m=!*k<3WXR0GDWR!j%7($A>Q^? zr=k~SCKAU&98DzR``^n|IBiXwiBWTERGuRF}=RS<(!MKLAs@xpN5NK-|x(aAxpRclO8 z4Jq<}24z_?COSwWTk6hH1r+%|$Fd}>nXdP0@^yG^F+Ln_SeF_lRaD0T&6c9x0@#>r z(0yJc1<))h>#cN+YEFUGV-}z#Ypv*L%0YSgPIRiIqCSZMXURE7Y&NFipBnbxn1FF` z#pFzZ>88UAaT{$5ca?bO;7q+mg)XYuDUyYLuALQAr4;pVY(z`iDqg)PvL!{b&{qrg zq;IaGno-n*YcNa3nylJ3#I!2W*+umZ&@3sd(vApKLQy%TNEZ4?ze7bnrJw@z_0~xh zxi|DXv$a;TGifoSUr`qAVp?`=61kWdTTm0E6E!i>J-wdXZs6eTLg*YaTis@saJLtrhrs|P(HR=%^BDy^s%X)sI17}ubpRyfB> zB_!%?>@aP3hBqIdXHq&nTbMuHoj>&N$<|vas;|0Ay&DXhM)V#O9R;YK-qo=b$ts-l z@>z7NM-_S$x;!u-AG#NxWV}$1p3?+6Bjr$igJQJ+%g%GLIq47vm7Z~u&{D|J>6{9qQZ)T$%NtN0-2@+t7I=Ruaw3JOujy;V2mhVO0jgfz^KY> z^I@RBK)fNql6;|6k=e3glC(g!CBl;aDC<&G;p?4?MTPH)v9uVyIo;ez4OTGB;TxSn zS@;`>u_{+XhpM8wo862@s*7|GDT!3MNGDJg#mHQ+7Gc?Xh5A{&NUzq}(R3#Rg9WzK z(V(bKSsIw4EKSa%Ma;YebfFhzZn3bV@K z>fmi=hdIAV=ips44Z7gTXHY)LLOH-r3QLJEFCVI5>rxQSYCw$k%Oz@cNvhx*j(DjgUK|{LXi{} zHEbAkDm-a!w$_0AOI6j1HL?B*S*ofpnLW(S=@K`+VoS7BVmw(5_p0e>#GD*QSOH02 z{^M8yo>hRC7TlPP>ja837bWC_AM+oJ?x$-~KczdO zj`4;D##@br`J>&z0QswOPQAI-eEwwY`7!ab3^_KrFnJp|;X(>dP8f>R0xP)u zl7h-6v6f#Zf4x#1CWPg8YWh*2iHdTP9$w9V9Mg|l^Ir)@`|u%5Q84P` z-={>W1psz_aRJDY3qPmi>T9F*^MOo((CGO083Hx1W#L9cvUuIpT?2FS%*Qk38kHhr zF|f~+o5EUBSILuU=tT-6puR?93d%xXJ1O=&$uTU3h(fOco+am8^?N>xOZHbG7cEFj z+QzAFeRjGb*B^)%e2DdZ=J=dnE@V%6u(s4zG9_w-Y-GjOD7jdkY-b@qJXlNW8ZkRs zo9&3z`DAH@u|&f;QX1_&DkX=rq@>aOCb3aBGMdXrEksH*SMqcZF%-?^UD458i7+~W zArB}aI&52(5Tm&(DO7`ONm0?<6%~pLTGX)7+!Yv#=8nLjqq!?LR9juSNHkxk-bh^% za9w%OJGNt&l4k%~d||{uS6-ogdn^XBqz)YeU1^0iFggbEq@XcSEGX{Ggj)_*La4o$ z_l+s2lod&HgOz$`-3c?BSBG0H%pd1<4blr{+I_~A>O2*prauFeb}>ZCeY}x!%VRgj zvWG01if)>`CKhR1Ymw4l^C!#(8YYwMdrTlp!iCw%8#Oq2qm~{AV>OtjhNe6i1b5^G zVJ+#K^=uvMbm&|5hO#WIE^Cd7DgbW_$kBTM%hJ^DU9f-7KlIE?JrpJ22S?YDH^VzT> z1S|Ekso^P?iw*r)D<$s~3LTZ#tugt-n7rF^&T@1#NZ$*CKrp_fFXFug?@$115>G!2 z$k5>Fiynrh^XlS*1vCnXfIg4D=!vjLVU&zcx(+1W08?g0NQMPs*`c=ZTbJ$qVp>-) z1hP7PQ5j;RSW-q{Yk!#uutd{FPmdX}P}lfd_{-2S-F*~G$_h0Ej~xV{6@;>ZfqQ*1 zn=42U60nfZOOd_Z`DI2xP;!NMP?o$E`8EX^7s`ZSmYC05$Y<-Boif;y{a6s#$Umy5 z#{-zod^d)yAuMgzs-H#Z7O!)4Hqz??b!XF!pqj_9be&NSV@VJ*Mx`6)L6jaAfpG+V zQDj9Jk|k}mm>VkCD6g@ArdXWtKr9(z-Kn#A8-az+h`u-`pRDfAw=3_+APg_c^fStZKm%?IgfbqNqygc9D zi=rBH16Ui7KWibL;cN{C(+xDN-Sf5rFY~toqhOe4u&uw#^XG$Wx!a>vj8mY#dzQCp7G(}rXOK;@tL*HjOhGIUwGk|v z&+<0Kl66Hk!Je)6t(K{YH9z`cOT&>YblaO=Q7y5015aD1XL*}kQAEr~$fnk%)}~ez z=~#q-&L&o|bu74v6~)9dE*HbHdM&cMw9Hd5fU9*FLtrd9Be1Qs3?B0tJZ+(_MRt#t z!DHGZFqWLN^}f+Ebd1INVGDD4KJrioiABBq*%UEpUS|yj`zss835ZEsPHd$k*WSuT z`?@(ed{O>N9Wi5)VW@3bp>@CdE-6W5l`vgoUD5lTU0AD(Hc5iHcgTbr89}$;g<$9w zTUXQ=whL(sl`Fm6JBAdBL0UpD5To~EtGZT|RmQMcML#b~UyR)#n3mX0a`rn?YN&uQ zNK5DiDqcoP4cUrfrec%kg;w?OXG)}d7W|nK^|M(SPPtOth|QG9JFS@#`NNpJ+p-*= zDbe>rXCLakzKGA1tdJw~c@?#~qWVEVh5T7xR3rcS^OmkFO=NpgK|c-9kn!n@7PLJx zvRq=zx?QF*Ru1{ImbPc-zm{qW5!%*Ns$*;EP4ARx3$3pWZKl4K)+Mu08U@N3Mt=20 zPfgp3l36GXQ!c|w8ZA4@W}y%v(DT$6l_8c8+mg^Mlm-A3AcxQw6*@8twIOG}JkfPm zW1>G@OJ5#W=52_7h76Ih%7flrET^=xyL$3A_0F?0S!ii_D3+9sxm_ToHq~uROe7O! z(qOLGx6DVgq+WnXm4|+dgHc-c0gxIRyau^~zNqsAL$1cNByX`Kn~tpM2g(eGV{!uu z;INh+WwV+Z8SKWqTQaM;KAn36o7Ep|IY)=dqiH3ZaeGoNbS(p(9h$Tah40^NO2t3A! zd}L5QZy^U}yAfC{SI|@C7G_|!8!&^j-TIcmxfcbq-TKk+Y`4B;$k}d<17wBSZhdhN z%yw%m5QK53c(!}YIMdueq#Y4~Wo|Bpb^hE`T&12*9`1&~j#d3Re9$(Cis{}%vtR~h{B)Yp(n(AX2S_sQ3Wpw2L zVgk$^=!^LjzlB${azH-`B?BY2`eF`?m3TheuiNmlGyr3JHtDS~Ed6O~6ST5m3GM;H z+JsG+J`-}gm^g(~OgrlasmwgAeigu3mafQel)b?+L0GF}K5rqHueLzS4^~^~i@CSW zPNm&XBCNL1Xy7U=6UdAy=#v$!wm@WHqXd}@WDGsGlXaYetZwfq4aeF)K6KWd zSQ3ymBM2<48PONVIBQ1qQ&6~A?T=YAf~*0%PGoKWt&T%W+UREPbUc$3ej`(o>h?pn#a?BbMW! z*w{c&$#R^PkO;|EKmU$zbpXDTmDiX6clT^7)yOnOf0zO9eQu6&zWjy zs*L_vXz>UAk!3@uf*7x;%Z5-uj8}|hLntOT3?5iEv{L@Av!t@J#CT)@SUehmMMY)6 zn8xt5g&JIvgcb#+aX5u`77(F`u<%D;_D0PV1*nI&Fh?l_f z5GNF-K?ytP0IJ7`bLB~^@_KrVYno5VaYAGfVqUvM)Ih2=29y>{(tL~+-~2N!Tb-$N z?WT9eWq!qsZs$l*;=)v-mRKR0W={!4p&+u~#7oKYhjZ=5EbX$>Z;W$s)JnsJ`D|q! ztRG2#H#Ix$2DvB^qma5+=yQx-7p;C7Qx90|89~`&+zpio>ZoxUXU-~f!J9P>Y&;6c zkQE!3)gq&O=)=-^)I_&u7L4Zs9%`m>*@CwR{ng?q*_|!d950i60iC7wIr*;yjbWV4 z)!6T4D{WCHw|FnZqYy2>WywK8@ZJ> zX0Ii-Pwg)(c}!mH7I z!UjMs`Po9znT805Abwngi}E6XB`%0;AJCG!Dz!UZDqAiJ&vQ)-3;n|MimD+yJFUTt zdNpOMAvd2941<#-eZz1}OZr-nE@m^tNhf%^ZR^=16-U@Dm z3}6x-XiN+XeZA^c${jS2X9kN;n*pob3?0;-P$vVnWSyg%xpE13!l(f(-1Vxjxo2!Z zpe$Ld^5-%1+U;0`*FY1=lCeo$ z(VMGSM&b1k0kkBpS2y&gJ7R-fXE(I~@u4&e%94_9mFV@!Ou&awQUQH?;5)5_y}9-{ zRr`WkC}Awk&r4;BpVe96WXHp*R*zy*Mha$0xNK5uvat(XA5SS=8jg-$?Xd6Sj63QhwW9{i^xmY=k z@0hTpo{gQ4Xy^$|GfbZumxYkYmXKp%o|`S_7Go=#5Mdf>GQeIUTY%arU}0I())>-M zI#6C-cpl^8SW?y+SE-|Lcw*=QS#q>B`5@Y`*5o*rlzeAJI$kE)qP*S`+=O>KbF0*_ zo(X8lJWfie^c?AiKvHDa)4vm3tEQJ|i^%L9`@` z{Y9##5Q`LV=S>V0U1gZ%mK35Z3=~~;wTDDk7#4cI7e={D%>qz{SMcm4D3GK;=~E$4maOIJhLLiQ!~C>WGt{0C z3-KJi1*IGm&#E+lg}Y4c>L|yACBdem{w|a3{2Mt`nofUkIx^Mp(${lEv)$ZYX4VdKgBc#A z)zcQ>TJ=+H`?l+^xM|DQ%dD+yA#A*F;R0D=R;z-?v(kF07$3F)*I3mgacdFVFT* z*A7&BJR`xj%B_GrxV#8(Z2`e5*HLSyS2;M|GqXS}{4?$IrUNAb8xV~fye(sA+FQnq zTg_G=faPo(Ti5B%PS@M!m`u6xICFg@s|3dMbz<1Y`=&NZKmxInlt}Pv%W5q>?b?(V z72Xy*Fpd@G`@qbd)d5Ebtguil2`jQD*FGIPfR5K9K(LUPsV;qaso>E`J#68vGJCD% zuy~7XVp!j zf$RY>P{h6q$V83b$8bQaTsEewm-L#qMtgRUE-5LM34{BlOcc)&d9IA!nQ=AIE+=X- zxKtd>%9!FjEKAh7)EqTtMivAOgDJ>Cvc!nSM|z5348%iIh6$4jNSZ4xu4QC0xMsxr z`6VvZjEg4I)^5pWmu~EK!kf@bj3DW0lJV=w6?~=V4?I21^Sc!1n`P zDEGb~yE6)*KsF2z6+RF;miQ8J!eMgPpdr@AWffQt3>4yl0?_Fyd|=EHWR?8}Z<4zZ z2}DCEDSW^`lu%4gsyStA5Va5kgu>)x;REQj^`+^gh!`f!UPT_G!1*)}Wz#qy%PRAY z$h1hIJx~D9JQO~F9V@n3&wRuf4&7^tVDbJq%i{C>>6JnlFc^jl3m-rZ`r0H*-+hZ} zAqYsN@+=c!*(%oc_skTkSY&o}&T5;)O4my4}6H_~G?bbSp$Him6cS$wvi zg!^Ke>3k0Ka)V?`3j@l?75@m~h zGe3^n&x0_u9@sad`71e&+E^eMjidI>#d&K<9JQf9E*eMeo3VVgJdWBJAP|kC_RUdo z)P?|gXdJa~M)K3LIBElcGzx#1anuo27Dw&d{d_cCpv(xQFr1i)79$NVh!siCFN>r% z$P-8m4fNU(lpD_7cr3j}yx*fWCq@hMv5<5GuBeOQ;DQe?#=4Qt-Qu-4A$e9=Tu91V z9dJ+u9m8<$E{M15i}F?n285zD#<|;%xMI0)Vdm-pfH<`MbnZrD?s>(TqXPi~(K_nf zjm5ldWI%MEL%k0N1Vp0kwR3kM>YZDdJvta55smB4-ALTqP?A472q2H-MJ)1(hA)&s zy27&BEmKGmNBtb~Cb6B^2t3F+S`a~m6tpjHV_3DlG>5dGEh#5crE{JJ`eQ_HFM4~yQeX}3Y%KGB=^B@e3FZRu7JR|3jHWmm*b4dH< zp>jwY3gn`(#=aSgr{y`MjR6ADJi)#>5KW8w;x+`xL!*s-GZIV7a!4Bhq*3^TMbd)4 zxFgC4q?DTB#nE*)PuC}s8^ro~MleMsAwX6{-CUMSA^=d5Xrw`&z+>x0<>Q7mNKk|x=T!pzL0s=OpbB@Rp zXbirLIv$Duf(je49t844aWoe1h8F7&>`ku4ZUha`ITBO@e~k3P(lJs52t=cO7UYRQ zgx*+~?;;rCy-cuK}p_=pnzO5!s2YfID;!}HVuryaR%pp zV~jOvUT-b+%FbgpmU?x?2!uFdc}6Wa1b3;Q&E;LE$dnz6%koYUk&n_ThWuen-faco zpip1*)U*$cRWhvCw3L|zG@D8h>3q9}@si%(V*@QI@MTwkl=bA`pl<^MgW9_Q5WoZqkSB+&)`%qQvF zeXGv5PF0;cb?Vfqs`|b%P(|Ig%`Wxu_FWH`DK25#ZKGl&Tv}DCK&YS(;(_oH?l35? zg3JKYWG;GvP@va8Ztq}wLpB|oHHRr`9=CU3<&a8FZ2Q*~aboAEp=B_R~JGyJXD z_pJr?Iw3<8$l>n0mBG>)wc)PvhO=6H*+R-$!u56nRFtyEUVxSkf7^TAGNgfsl*k^ouPTn`3G`li7hO%E1Nixt!3M@{~eN^XBrr`Zd563Ge0VrTN$DoS($TR|y}XGj7F7ZjWnC7tOjaGwnkfJZY-|hCn+R;A z&JPCTl_B(8O*JN&^gOttz&$EQapCoZg}S3x>QF!y1z)QQj>CPaXK%TtTcbER-lmOer{HwT->uF32(#W&CleQ# zvPCeVqVrs48QSCeBD>4$a4eUsqtdaR_A$az?MJYQnhMv-o#RaSQPs_ zZ%1E>$sOiR{oel3mBqbRllPFve+^W@|F-g>F?H#MR6=c3d8S5*P@qpG4}iV_#|8GZ zMkX#WcP59vUjJ>xw>Oo0I7LYp=(6TSEa*dwb9G?D2zCd$@-bHgb z`@3Nads>bO3of_!?w?&+h4at7Qq1Mm(?u4gDCJUp!QMvg>$QcZFOaXW&Zo+?Xl@-m zAEu8~l!n%-yo#`4H~6hpMX4zTyqhZk-TE|^l2M9M_T;)4&0f8J&n?n(>}&v8lz&am zTBD?k-$oMI*t!{|DCHtvk#7X-jZr2nu%;&;o8CsLP#35d^Yzf)}CcRb^>JnA1 zCftZq4^^lO)OK}oyAif$DOWLy5-y9WVePOHytkAr01E8ql-DM@O)Rg;=VWtb;&aL? z6LUs=VWNvuxh`?~#Ol(xkL|vV=XS4;gu1BZwsN7qQ4@NWREbcaPe&uHyzb9!0*_~* zE>N*z#Dp^2>%$Xte8Zvd^?CtNU|&3$D0%uMP!?zxkukouQKNeLlL-r~R&g1h+lEiE zaZlBY_@?shaT{^v*|wRu;Ot^^^_le{fv|+D$ZN`Lwv)wNS z06-X;xZT57xUSBFDcbTXJTC{c3iiXWyGDCtso0GQ6JJ~`tPZFsZss^HAE6t_JIlS% zxX1gpO;r-BHkMMMPpv;ww0>-3-TD-{c6vRA07|GIkD-FYXCI-gUa%kMMKeD+OFe%R z;Y32_;!

~Uje;tAAm7Grf)5mu6y(<^EhSA@NzDtGF0|~)sN|Z^lA2d36=ACq zis7R-#Z07ajKaaxP=a`vRHhI$k)Vo}-(j}kYD>y)AEmgIuo|GE9Q)>+;!k>3CIOXf zciG(6-xP%a$~2{t-Tf)NW9M)7Y}_Cf1riU8kfM^- z@#Qglp9@Z%mxNqQS^TJE$Mx*K3!_McOTQ02N8{G(uJ2rb_?E-BDeFZ;>c=#ERh|Hf zs&6}b*R3}M;3E?ti%F@DuS;M7Y??hjqUSiyvHJJW*a$KBwZmPIAYjB(A zCgbLG-Xf?0_FL9-D@-TXz{cI>w``&>TJ}DsH|EE)L>N{43{hq zh9|m98&}pJS%JE!=_STdRl}f<7^n-xt+>s(4?Cssfz*KdeUbqRT>o8y8em`cYn&D3 z9r`th5_zODRG04C<(B$M+f`h?CGJXRsfWPy=twMEV!XCOAz2gYZNDW1p+MfXx`M_> z$@AkJytA>esdcTgMIET3Eccdu)dqTW_;TXAI;NA2y)omy=1ug0+uq{k#X>pWZ(dy} z(_@UM*T39&DyTs?O*<>5j?mY1|3vMgnP{+Zu1q-eZLn;KxMx z&(G`34a=!4TboPEutlw|!R!V*qAozxX(4Gy+4*v^(fvjxa8d3yTEuNw!Mv8Om}`}W zB&-7caxW;-VN&WMVXsa$cOe=hh$gRt?2EWX*d^kQyuzEjkY*XkfJJM~*hnRZLuspu z^P6Xw|NWLl2*^s&EwcCXt$@u;|BFmi|^(J zOL#?twf)6teJz?tva>kNGnKbEtuJS?naV6yXR7=Co}8;DYaY)w2H|!5RW>qbRI#<2qMLW+|_rfKe23wG^_vdg2&X z`4cywgaDhes!&Cd*O(%u0m$fecCmB)Rv_ zg-yf-?DqaLUvt7wg>`zv;b6ECxR~p)gDpf+M0=?}8h1|i#|smVHKQb|00lg6IIMKX z8xCRFzleO(UIP&pa950ntIM;v6qHx-n8YX3K4RHKa37{9>hkgG3QpUdLCeVUHI-6D zC<>SfU7L0HMm=kEe}%pPZ-+!t-5a5sZmj|o@Rx?v$y(pYyCyDRFFHBIyArhV(=^^? zCndIXqzX{I#a)HTXam#2gS|E|%|7IN_3Qwb`wT~T1D6~`2=t^^ym)Vl4~9EjG6;-D zv3dBLb^}t;1Us?sGwNZ$;~dyB?j31t;#8QdphICUMrxjyhUQuPj&DOGrZuQf4*S@8 za}4U3zy@`9@d}O7GNG3tGhPY7%dEI2@AUe!t2-Oj91-`R#p2X` z5pl0Zd`?}R^FsObdXxtVsfryVSt9Z^jJ&vwKUP=QH!qG(KX`h2@imam2T!k`8_J^Z z7PcPPw7UK%yz#uCb3B&95%5ec-<}s}j{@w};`RLV2L5?7|9mn3d_Mm?%s;Q>pV#rv z7xB-#_~-5X^9B5KKmXjpKX>!bL;Q0O|GbfZ-pW5;#y_v(pD*E`ck<5z{PTtU^Ctdz z2mfsIPkM&?6hDxBito-m#Zk?t7Ad;+6mK1#;x+IoR%@pgY4o1r(RXT*#>%NhlJHZD zB$uZaNtRA6k_4Puq+UC?4Yv4kisL>f^v~&2zx{m$^MCoDx^p?Se4Q=7(@KCt*!VP(tMXoH+Q5K>}>iD9z8K(X?MBDyx{3E7Nv=&+3s+zzl;m2=K6He1#Gwi?Lvzt zE*x9KZ~&C7>GeDHgJcwIV1%<2=pch^1&*%OMO!J3YgKh;3^@ zaJY4dIM_K{3pSjC9jWOnkYw zcC6RSI$HFe!pduzW4-aoUaw?vmxWc6hv`lZ=FrV_m8F-}zU@Um9l&O2siCg1FiovZ z*WE6_b6B+Y3oVA4N=;Q_6iNZ{A`79+oH~ef!HjN~>nxHyk7e7X_MC&pyuo71<;t~~ zbORl= z2#xhAE=kfrcUqvv`UIf+*9zhMN(<7YO>#JqC!Y6MEVUjmf*!(#bdA2+0yNE$#T7>y zXV&60H8DMtk*_o@T4&w@HI4p?AKQ(fRRsd$d_(OtCaAvCpZI;o;T?)N~NDwBhOG|DSIlqMrI-W!UG zcL&RJ*v+UIpdVthts4e>Sw(-cu-9?3+zOC)wz3YDZ50tyWZph$yTME zVG#LK49z#6F+jz>e2WLrB);(giEi1qdKgVcPs9BGHV>PyxYT&vkO*G5VoXwc#lWlH1$_cu@q?U_0S|*+~H=} zhpEjj!8vTcj23py6@c&a0GpZ`+eY#DOM&x#52uMS?}UnOw-0!LO`;?*RvPAm9!!%) zb(gz8Pq;JXu-R;+@2VSkL9}d#EDf7WMGzI9w4J z2MRaf9}!9+XX1XThwvrsPYA1&w5C=|{DfN?`1T6T*`HgqCb`XMp0xd?#S%lLp_)eC z{+fWQ@+J%L1}H6Yg>?L#2Pv0wPY7v*_>DpBEB%bp-BtIPlr4$qMm_9=N?py5cDwQj^+GNLp1G$$pxLDi&8ge|5w986Myy@>Gm!!{@U+*e3l$S7yP1 zz#<Y$~5y9b9(LZ_gR z#cRvlk1x=d`o~gciXBSwkp%T6m+HCC5s$OY9K|Jj_ws0CpnE(Z(H@OJ z9qct8r(Nu#!N1x=RQe!xu5?#B`-4Xvgb2Q3wQROo4^I|(4u=#HSJrag!)R=-c?9`{ zbGJq1`W{eYA2LwYjmS;E7;mYEhu!8#TS8V5 zSXnmO(8Ft#d-(7=D+2_g7j3qB<~TU}U~%sEaO(8HZ4{EI^}s8Mx>$eJ=>a13^}yE< z#$MhjSCiV;#66cner_}!pT7NrE%2jioC<6sFfJh>F6`Ccle806xoDak129VQI+ z#bx7yA^xMss4TuKD098}F0RGy;1wD20dp)q^OY*knBVVViZi1Q6G8TKh!eweQWo+D zJxDFXRJ+thdDViM18z8qqfwiE%;FDuc(v6|{Z`=7ae$)QKjL9(o#OL2f-Qcc>vH*H z9-^%DDh-*rED;T#KjEQj%~J3gLXY7t#A{a+@Es=^ZpEMUki?f!;V&YsbZ76Sr`8SH zPdya0(d@9lGNwEFE4=-zho+|rua=&ue8>Y57lvQS2xQv+!ycF{1;|;sI__r+lVaBw zKMES986-9%1)%B;+$4aE@p~3S%$$0RtVJ2*4<`p11Xp*6qA57} zV+$fvSjkBNQnK=A7De_3OO$YNSHZ(ySZa@l`e0mcj!#(>@f!#a>_OlM@Vcc0{jH^! z(Nd+a4ZdYo{=q_dtfU|c?doUxPg{C904J~&skzMZu7uk;_4P5 z1AN{Bh|MglH%G!U(&q0p2dQ6j7K=d6A`bi}s=~8Q>BN;HiWhFj@4( zR!i(nS((_AjBOS}&Ra{}izrLx{Bld^DMK&1lIeF^davo+s7eO7(gJt`swyz0sH)SnKQWXgRWrPpYcFi9r9 z$s_idu7*c4^-DZz&m2fQJF-1iwB11u#~ZC>I3)9Mt4HezZJNRLUKb-A@esTQtb{)@ z@f{wq*ML=jB~#z!QG3>y4R>VvmrqJBJ3~docRYG;#MW#4V;+Rp05th8bw}lV(etQf zZ$xyJie==QFHB4*F^o)juSe*~S{b{@w96i?H)}UcY_ISzyz~IE0Z0WE zh5v-5mEmn^%YuK>5{u3(iS^80Fz{0rL)P^57$qY=J2^-(XBM1%$byKGS#nZ6Ioz_f(4)hGMSXtRV!8E+Sn~FIf%0n>MK&ue zM}pEhKJ3ro$aaDDaf>F}xe<*H+aq3I_I$X#K4J0X_;3xLZZKTg?ZJN1!g@_t?|x+F ze&3>qmqM5e?#HAWMjZ~hDO&B1ERZ)w0uT*x59CiQh^MAJXDHX^&n>+;L#wr^b%rw3 zUs|ZV(bYCktH;7laEE+jOSs94Zf1>pHw^dJ7OuXXM;Xqx^WRyZ`gUGj8DY88nH!wU zN6(p?|6xJAc24U=?dfIu&scg-BO6aI6aUj>#KzOh#Q$uGy@|;6^fJJv?=mx?czUH@ zn?1dZw8bKMJyGlFWsq|$h&Mf{I|XL-{RE8hXp7;As=`3WhC9|O_YyGNV=SC_U!;Y! z^O@-`v~=P%D(NboIwpUjCHE|Zs`Hs?pJHjfDJd#a?4=L;58xujG^-RN^=TGMJRnky ziX)rZc!njFC9xs(8sS+M!4rq*>-8(}9E;&MMzb@VYjm;2@ZK8kEi`>$? zEK)fB{})0laA?JNygT zxXu#04H!zlf6W_yH&_hWEs(kwy9Lbo&6dy;Y;U)K=?_?Xuj$;~0tPr_0X(f$*)3qw zms(P<)y-}J6CWjFvs>Ub8toPwDSGTqm)4szoSglStRY7fFw`Wa$Kfm{W~tcT%sLBc4N*}O;Y&De(dzDMbaO=Z7?8*j-Y_L{!B zU&7P_kJ?+m)bE!t&d|g0x^T9;+&R|6f)D0Xx!zm#AUu^?kI<9Va?6Hk-|W$Ps;a@> zd5eePm0xbzaQScbXgxJ&wrrUEZ63MT-*(G}>EG_rdlte9j;7(kU3#St=N54Dt6s;y z^Gs2yy9Uh5yF3)H8MVb24aIkRv|cm%!{$96x$HiP%*yT)v;1C<&YNXuyQgTf_j#0F z$Jvb{F8Tc)y=)W-#|;}r4D2~?gc+?V#O101}N7p4Ueh4&b zf1qqL%H7`EA6`cjT35uBDL+i56A>-ZKwTl9%26aULWyf+1YU| zXQ%z>s4>BW!^Y)|$94E?2CD3f%GuPV!EwDUdj}18@W+@?bD`*ArQ$8`Vb z74^6r&dnQ}NxbR$^Tp4W1<3(k&e}f6*XYNYhY3DMB@{zi?qK526LC3`W#-q^ z-VPumY<`9(S`9%rfR z3n%Kb=1({ia;{5J`jaiW4905J%N;we`%^7_ecfr(yeR$Ymb$*~L|xYXnP)=I_D)fH z%aV)HR;_#3qNj_p3XF>^hAcJfF)E#SiAAaJh0<{2Uf62sCDfqcBKf6h>(s7Z7;Kvb zlaopX*l5&0zKoMGbagZDe1?OIL1KGzw62w`^YoTKfS~!1(^)|0r&~LQ}azxTH#KLpmU}^OP-{^<8 z$Pi{$@^r)^iW%i2!rOw=5!pe;jNM^je8m;2R=cmxV0T$CIjd@U%8OWUXPp6GZUJS_ zzX`C|TW6?_g=(s(+FdWtfiu`K3s%$kd|OL@gqOCkGcy>L>aS;EYTB#*!LCA37c8JZ z8RDoVtz_w>BfqUxpxkRwd~r{XPaQ+R?XzqVWDidFTL>1Zp9)`Lf&6JJtH`1zV@vMy z!Dd~MGWu^JKU*vbK6OMuEqAK>6)cbc#p3zeH1cL^_tR&HV7(tdcZLXd-S%HCg0InIEo7}y zvC@Ch0{I$U1C@gFQ48TaB!)c-*NAJp6604aMooRlozh@){JI4amt`R?MYs-&#&23$ ze{wPLHcbB8mR$CpbdqbpPVXT zLQMQOme>~;5Ig4O-&=Cu5MuJGaruvy+Lv=sk19sg|FpFJx_T@p-a5-zjfE%gI(TAr zt{lGq%Od&;Um@1bL;u@i`4U%PSv7sucN_n_zji%YSPj0kJ<5XlWBc|)`;Q(ers;Eu z)C7e2^F32{jvl_{hTHZYx?ZBgSl-TefqbFoLl;=6F2MlB)6oS(k0qRHke4sHc?=c+ zkM{ulNi;2X^_CV_=1Crg-=wx{zsw`{8Q{zC$>vdUYRtfwdl3YTV`#`^r{Zr^SqMyNBW1D^4@M%%k?lXWZ2*3cuSUmxvoZFeJo_ z+wH47N`I#Gr`oOu;0u70VrQi9F+sx%f)Ji?}s3TG*?}8)g0F zmDO<`hzxep0~7y`24kOG_=0W^>}4M)13lmYiF(mMfel`u8JGt>7#W!wrk0ggc^GmR zzEvofZ9&g`9jH|INE=B0{QU2&Lwd1pthNUk;Cqe7TOSTO7RtqT0#Ad+4kHcVZvtW~U z3AG-sQ7xM8?G|oQX;~PIO00JhR&~`UHm0iSJ_MfL>JQp?5lAs;U4BXgf55)m*3A`* z3RcZveUC+R#iD{%KTzLm0mZ7VZLGE#r0=shGX2!!cmwqP7D^(VnxGm6=LamNI0_pu z?ZEt?MRLbcr3Z{FmB-P~STJ!1*Ry2@ zKM+4gAR7_Ger3p7dddjs)P7HSfS zFaz;#38y*`WpSp|%t4AhuNjH|Kq$pXbX&Uu;Sa@6+nQbLnP62gT(7dU1{*dR+F?m# z%!$uhc-Ka*!q*SZ&sjuQJgSIhbbj6fxt2v0$Qz!UzXv^1E(KgsGgx*koo%69-RMJA z2h({L%^l-aG&`Cuut*a%mp7aqXR#*gLo=S9KtR>;KREYVR9DtKM$HJ_ zXTe-wmj~tz)0-^b)t;H)<28)cmsnueec=Mz0ejHGx%NgqTy@mmY7t$P?jhQtd&Htm z+%Mkvy~E;7EHq{i-$h{6LF`(mT-lld{BlAm25>z`0^twdj;&t3bSSWzfqTrt)k}wh zs~@yIi|Fd~N`qOa&4LATt&l2^H(2krSgsq{Vl@oZWee&~ItJ7Z(pOlh`XQyd!FSw@ zEt)&qR~fT|^Q1+Zs1Lk>`GCcmNHENxe2{>ugYvOi_YPs#CI{{jHiZOq8)CkH96XDK*&g9VYmtCEufq-5ny7DXcUN|bURi7WDEOD+3l ziW*0Y=vg|oYgbg|Ef&V>n6Qf}LC^)pTP=pf5eO^Zfjq9t+bq3Im{ofEyHk4{kMZ7a z@kEVP@oG=eG1NOPlx%VvD1D-j$=_wkWo|R%`8HbTa$AObw}lghQx8`hz+<5ISfKhA zsy%+kQ17)+vRABlTI%6qupUmjEy0~sh|l{bL>R<4(GdcI^ClGY@P3Qn31EsE)E+FR z|A3{JI1s6WIoHO-AGE|WHwp1PT~XBJ89Jl@%V7o^46J*&vd76*&MjeH zYxHO93oNK-I>d8bjf;ZEStw6VN+@0zl!o*ZERLsfB2I%v{$vZ}DR}qH8u!^#Er44i z*sw9caDFftuM9CP3(0@F#c@SYaNKj=%+oV1mN;va6bP1oQk%hA7EF%+YOpa5C>K?_ z$Wpp(%dP}ZnlG^co_%5*2+a3ZOYALkGO@?NHj5!~@KX1}=fH(uZV5f}lnK3pcUpRH zs;@sP$6Q=#QM?Jq9Qu$~T#Ej@+QNAjU(GQ&=I8|$!c!$1T&cuR*IFn~&sMxROuE;S zdR!EzR%+U0pM~;Nc6l39(W*BQLe&%GiFq=5OHKF^kKEHh-RKsmHNFmdNZwE{FKgx& zz15@jBt9+3^f4|*IN~9AgKbVfUBIMwc%D@oOw2GBjXaaqDhjH%maJ))*N5L53 z-kb3o4b*S&P&}(8qByqcDGx&Kg%z_w z9iHPFtWQiRN9UOEn>|9W=})XKjr;JW$qlPa|E(UqH;pwI(r@%IJRVkZa9J@8{(Fz! zYk1a9v*BXkQux2kgYX89(`nz~(R$;ZOp|={pIh&{JW{##Tl!nhgfZRscy!*xZ%$J& z`8zyvueRk`DyIEDkJhU#DaW#rf50QXFmGIqdfnk{z9MuVZC$+w6l&{Ad=w!s4qvTx z?(MCe91Q11*iynJ16Um8JD(Ziyh{a^Ppss zk5F_Kad$i(c9wgiaW8u<8R7jN!sDa`^e)y6HNa1n4IpRMSPnyoO5%|Teu_#ccJE{$ zDH^kX$HYHN#HIg1RgahpCARHuI@5p1(u*q4rF)w@jPPNLAj?mSP`e$&U>~tyK0C>> z)Q)OK_+^VAz9G$yarQI$uT4sB+~iFDaZ4_XCS5v{SMRrHh)-AuHHcJ?*81oe=93mi z)P?3md)Juq_bsL9DNR{%YBBL2Sz-wbD2aWiR53LE#G;9XQlJ$93e3r$TUuWbvQMBW z`Y$cHSXR2|!X3aR|FtFc8?drkW#YfH#J)O6&qx(q{|}-zmxjp1su_3Qf?^In<6`(s zR9}N)fPW%@>KfMY4m89=YEDRlA<)FZAgB8O2)mjPS(C5v*;`2v6}4d>Mugoa>Fd zn4I#g%@9xXApGGEh+y3p1L+wafY?lW94W(|%YN1wkcw%~q|fn4eeo+_X<+J$C#No7 z6=LcskJ@iC^R5sBT*H$1b$P}g`+evg<%0|UI!1MroBYl^(cqnBVbZdLt8 zz~yBBUJoL*0H~-g$}VBrX~;3*jZ|7;2Uj|_JVT%}&dFlCtA&J@NNs0?$vg%JmwSFc(tli^-w;VSc8rE=QZWQ4md zf^0~83{|X72Kg!rBEBFOq_7tmqiZpm`^ngi3^Qk8Dl33Wixl=FLmamd%}r9VBN=4T zg6u0-trb4hwRoK_0+8Y+sDuQTSF>{=Cu||jW43CvGRg{}7^AhKGb`LW#w%luT&!l9 z)J7phs}R<4??jPs2iPP5Xth9@KaI}fQ@4jluOq5dBas$#=dL|WOA4Dl@w0YdCa zhB)m(G&hYk%^2zb^^hutQKdd&qA|jM@DQ4Lu_hKHeY=O$tgDTE#6aKa0X0it)lOoZ z@Ah!SONweJ7w6SvB)tO^%19FCL*Di*N7IrT?$334D-|y(Lwp|>TJe%fdwM{_?wp78 z10Is7DG#ai+A=@?$wQHic7uYOw~oPo>sRiFJur!osROI2;E#G}4NVnUb1M1c9+C`$ zf-k>j|Jg$j#ZVyBROi2V5MpN+5KbL_+9NmJJ>S0{v66ut>!s!6?*2IsMHVNK z32a(+$K>Y6b+X5EybuHYR}a9lQ2^jYgxUPC1Ec(+haxK5WrI<`R0Zmz4+V-)ELXqc zLDe+Q%3#zV_wOqk=hr;|)5VA?^V{|}Cnk4G|80+4tc2L8{bfFPz}HW8dc&bCgt=#a z*8?$vj@OpPos<3Xf+u5t;6aEJCh|d^kd?znsU)cEwPPp`}FS#j;;E}9rWi_B_bl=*|Rw!>3O^gtJ_MzA?cx5wde zX~aAyUjoB?&f`{0)Bpzm&!`9S9gXR(>&nc?FrW8eWMV%#?4#sV@JosRE$=A!7hw%~ z+bIGl5nVw<=axjWWf+Ml2r3aAB!UYzARwDP5o{-d3rhmouZ|_0(66K(A&MuJ6ox0- z=uSoKB!Z`w1f~dHh9`<^iQ*Y0h3pVSrt-o)QSBwFXBSkfin)ZZ>r?~>HJDD^W% z>e4$i?d_EMq3_Vhe$XG`jhlzL;4dY+`-N~td?QZJCymr?4WBJ}}Dy^2!5yGVVH zq`rhwKU$>zn55oGslQRAzVG|+RjAPcN`2FJ>UREBN#!@kzrRS`|NWVk-#4cB!9_M+ zC8>81GCgH1sjrn(zUP+SAC}Yy-kp*8%2v9NR#Lx3Qu)3*x(`)S|KJBREyr!pDPTz* zy(g#UKnqFzT1jQsFGV3p>W&}Ew7g&;AFZUmS5jGF)8a%@pN&Bh+c|4!Nxf83v;LFR z8A;8GPExl^YSwC!x=T{C3X{~UBsHrmNxeo=vu={q7fNc@Lz4O;NzM8ur>-t+J+NtY zeajHHWRlW(&9{;AiC>P!bM)o<1z1BLAFPb|8A znCc9!3d1}$clsMnFCHbS`%XaP_cwu^_02Q>_m2npao9i2)E7!2hyqbXyrU?hn~T=p zKQ0$hPy3je864g0FVBn-xS3JjU7#jRu?Jx@q8vv_%6+?yen z`V2n~haO?(uBV>*sQ~(u)Kiu@lf`3>GyS~6ahc;>zo2q`*^#>rUEkS%=*ZFAZomHM z{==-9rR8O+b) zW(han=9y9c{?`>f8iNDqAoi;`0F#Q)SvJqG*m2RHP^3>nC-b%3T^dF+d}VhA&>110 zkOs1lW++xL=lMMawq>R}bQ3Usx^w;RF%&XePmUt!4C31Gca`)Jusi6NE-*H&R91vFHvB{ zz|;x#15@X!8<;a?5i&4!Lc_q++4R7?LgAW$sT1|UyhahZ15;ao}|#6lQZENx1`B*9<*pyuepAAD3HxF1NZy$^SmK*S4k%d`5uL5`dugLem|y& z++SP4^PejdO#U<-xdtIM$y*A5@^W{wB-$rJ2X+U#lR_ z4o|Bk&b~fWR7@hSDD2iDjPN;#^l%O?on&z{+BXKYcTp|T1arL=I2#k5PJDEhshs>e zMZ0;X?|y$C+2`!zNuVVa>o4Zyv_h+C8lA;!nm32~%hbd5UmC1pXKOTbY%SVqMFYGg z6#KJo1L(x43z*mMDv7cMXARxmn+(=r_;Y=YEfoA9nG& zOKv)?W?&2i)su7lkV4)vvvSf+05p^09EF?i2*{5sTrD8_dn+J16`;!ln5KO;;<=$d zs6e;O%*(jc38*I#!9?#4*^V@%dQ^T$LDq<#&f^Bve8P+;cOZ6v9 zqEf1LqL%7ER76&)b*eAbf2!!URO|0Osn+Sy_~n{^O5tH@Lg0a{&`bt@IQ+eWD29Vh z@P>m1r@McgG^mP9N@&3qx^7NW_h->O?K8PcDf{S=EVKX6|DniHrJjMFkrqF_MsbX6B=U?HJzigc%AdD3Zl|EZ{(!)e8ga8sef!{ zWfj+mWsC2{wC?;50pg#jE1(%^10N%0ZZtDLSfb?{hJ?w7DdAXm_TE*tk~#IQ3T4a8 z{X7^=0!9p!PXpznW|juWbBW)pFrgKZly@l@I;5|kmqM|5PJr^EkOl&IK2`7gLo?(+ z16qgA_hAy)7U%pw81myy@XMty;Ub~X0-WRI<>>ovkY=I}8s$vqb4@FS}tTLCn zD=e2L6WJ2QUJ~c{Nrk_8hWC=p_i8W6q(u?t?|)8V*#eP6T=|^k$T> zFunfR(aJ)9`Tq9OU=}y{VXLuo6hU~SAOp7!2YAnrVk7nwKNohEx(}>%#xX+=DT_Vy z>-xFj>dd9n>u2w0bPC{EJO~<2Upz#=9mbE>qHT`7_VoIBkdnX$wn5iOX2M?!(~Ad? zZMs6c{+NRttI?`Qzf+-~lP(;%2Vd4fUT}nOC1~A>YmrZT{C<@}ESOxJW7zd4-MTi$ z0Bse#z4r9#`uW}E!LqbEH+5`p2>k7!uGSh~6R-SZVH$r?5wVt`c~=md4+ z>iVO`gSi29C~YYt0e^A-@|N&DVT%qQG;QPK=I}v^1%Ht$zz2#I+H^XX&j=guwBUNd6MzK8nwvHJ!mml2pc zM--!wZT*SZuRPvg?k;s0zOy>)qa)WJJ?@=Y>2UNL{<;9CmvAE{F6qQZIsSe^=e~aL z9@`7pTE=pZnay#};9nj9Q3kpKEnTEoA8pm!aD4 z>y29DLF>Nmus>KGwLpi>TMYh|#Pqj8fByOB&n|UGqgH3{()bWZVNVYjbL;N&Tlm-M zjFtxDQK!?|)0*CTK7WU41mE{@^LwW=O?NoNyp(?hU?JCwV@Ye7hT5~5f7pZFwA><; zcBjLUOd)RB}Wx*>Wy32v1@UbZ~@kA*q&BGCJ(73{m-_L3*!<&9SXDpe;nzDkX8OWoyr#kWnfwY@h{D ze`cZ<4sP_+a9nmMRbxapD}AK7q1tC5I5fDWf1*F07Ga2W$dZO8#P#$eTmlQvTWfjH zS|S3Hv~Ft_HZTG|l&oPUTy!P#=C=KeAU8pVEuuHymL zJ%+K`W-+HBMHQ>B>++xz+H6lNHTTx@iN(wqMq1evThFIiVEswbEs&Tn{ID#+Xgq!3 z+ym!f!o5)CppHGg_~TGf2hKn67$iPXCFVndoc_22k4L(OPlF%=Jn_Jjkl_gmpo8mx zJDr&PlmlO8l1X}F^3x7{c?G_M1BEnxVuoiN_zGk=U*JzKzHT%4eiVOyZfvIb<+Bew z7nvVhv`|cX-hs<7F;i1jlWEFZ7a;m`RaO>Cv0|O~gk+9OeD3tizV`K-HeJ+$Zid+J zZmo{zXRbaUeSPy_xwm$#*K6&K3qTfj7LQJ6ewCJl(474fD}&(}O6k5nnfB+$zaf(g z=bz7+m%4Ln$5xNiJPm@=?eFf2JzQ8@18PTPk+SPv^&STqaFqFbJT9i(zy=b-idFI(7E@(dppF6r!3*9 zQ;0Z^8DzdnnNnNBZlzYoqwq0na*|+9#fBwXI#Hwqnr%bMXj|)Wh!nzaN5b{|5vAZc zuo^oo3r37dPOE;JbHZ0ylO`Ug%Swwn-P;;Ll$Ls}@XkRNpcWKpw?)kz)zjYL@llwH zNw3IZ#oeu=up3&Tty=TwiEazgL9bX9VQlT+*KQret@5p7z19m`JGO6c%`U(}FbhQn zwYWUTs)}IgAI&CYjgSh*#au1gI)M=Z;L%ENwhz-mh=Z~tswAkpTYFnkif7VyT#a4( zB(v>@-L31QXN$^?y%uNkY12bn1&Yev7nZZTb5}|-j$)E0I!Q-K9|vTyb8JN9nIiRgY!BOQ8zz zt_7|t807=ROOSs?L|s;mF2lVVB6_rRb#LiSClh9u7jQFX)uE`V&1J0u$ADn5p$&-TT#F z>82w6)dTQ}Kp#sD$VP<1Ahjl6rlZ~Jt9+c4zjFT_gOf?Q#BE_4U+N z#+5VfFb`PSPG5D!w$_fTw{L6hyz)x?wtaiZnU2*TLB>~RKBv-Pg4r9$ckH|xq}u_K z>9M8S{KoB2wINpJIqA3-K?oPkv@=LXDTK20YA>?|$ z@Px@Hl@L}JUA=~tij>v>2?4><FS);Lww>6l@d@k@|c9p3zX)FSR=_w)!Ku)w~DR=88CUZmKv=%+6gSi3b<87YK16~;n44+f1N zm*13+{#^t?9>z{4N$y6YykJww2f8(&sqd!lY4zt@Q~Db+$tYh7{?#7FD1MfRXcDfp z71^nKilz`9TmTU7mKNNl{B04X`jSL15MFNy)u_*0u$6WFWL(AU6EU@|b#%DetFkug zl~P6w54(M|?j7VYxPi_OPa9?^*VJ{^Tzu{;AABw?(AgaVy8~-2TBAdUBqggrpV>zZz_dnuHj*rrS14= z0C&m}WE2OK7YjUC!6fPky*}i*9 z@oAE-chYKP3tKR+W8-`N=%U@a; z(p;|x;V!y!A*rG?HXqu;n-EgV()>S<)hR@W%t{<$4|RhIJb?p& zIUhB^^!?jfYuj26RMyf~*EBB8d&k>(cFGQv3M6ruSIT)RE1E#{@FTKJry{ZYu{wme zqFAzLKFaA^+dfGvL&pSf*EC<`FdhA6)0f`2l_!<^NU^4tS93xffHW6~z%(y^D(ak@ z#%`O~t_h~6s1;O$c0tHh6E{N=jk3rg?d;!98lqS;=`DdyA{Hw>4t|@^Mu8Yk%sJV- zHb-1`u^U~PznCRR?$yGHbBJ3`<)vOlew#O1B9*L^JsP9f!<%N@wq>jn4B^pMvQl@! zIE`qz4z4{);8WtN(pE<61i9K4@Y)X4N_~0lsbUC_Q7Ju1@bu4EL)naOVbdATxnSpv z(jcV1xBM3c1>nk0sY=^jb%t(JQXW>6wssgboHt5JoTp^(PmT0u>FuKFg1e5|b~0C8 zG1haX_24e#Tk#UvRo_%4S|!zpvRO2RHd2IW9I8|hMVYqa)O-}{DmHmbF$f}%6RkZg zt0~=L$^K}o@>Ac6865kyuD626pr)f}X%$@xq$p`<2J@*m*A6a*IJon-wLKA?k=$ig z@l`#O4g4VM3}57%IEy}H&0DA}4S=Jx&zGDZ-PUabSPjUDiea)Ow?{(Z`tepET%qzc z6KMarV5Jr@jYOXG6$EorBi$MOF6@ut#)<`I*(D~}Bt`c8rEW%0v6zXAwv?Wf9$h`{ zx_s0e#o!2C(vEbw?3#QzJz`Le>V!&IsOd-<`j{GMe_2L9+9L@zG_2|hYVZ1)EQ%?p zX|iczF3tY6tW~$@qLGlo4vKwo?R=!bFBrUS}SliZ(8EYrtIu0Et|K!Z_Q6uVQHrk18hQlzPr;VuLa&M@tavrj2R%zkH z>FUxPxh}B~oD057dYTQpfdIrl&kdkHzIN*pLSHU#9mbx{k@4zWf8dX$LjF^)v{mI| z6Cyk%HeqL@mT@*X>RYC=`P({38zTG2gfBWXafZghhBDQga=_t5`-pl4vwyj+{w+MU zb1zmrC*hA|V=%WUh6pz$+HSOZjJB$=MN5O8{uOMnqZlzCGz@ul0sXk#x+0sz?Vw(1 z%=O5%jvyS`>xB0>fVDJp*ma|k*`4J@DoUQ2$ABi~jHR24o>84TO+XrL`JRGSmoLUZUJxW<&E1t&y4*Zixij2w(65=_{2q-Pfi>+y zyMi^Xl1r@&stJ@J?={wxm^U69ip_aUgKsRsnYK=DvCCOgbhlOQcI3q#Cjys(UdbJZ zll#(jm>oF$ufAab6D~L8K#36--_Cnj$xoCN3pX6C3~{hwn+b|KNX-&Q=-pdF>L`mtHiDQ;W>)_QjQGrZZskKt= zGOtV_lfKAmvT>rrG0mNED23LM+|CS8NOtC#U^SO`IuS;n7^KsQL++b4vLb?}4OcIB zbo_H|D;zmlAS zXoWag;g}MvR+t;RThmjANbqPonSUWA#Cyx}lNC|;G9ym$mz0ZtA@xLmq)*1-KT<3g zwf7gOoP=QlB^%cN`11jZ+FL3{D0)1PO>sB{(hm0-!ucm}$k=XEwcC{&wrlQ+uv!88 z(>r&z5w~>J^Xcb~9sI|REBUXT+xf4ZSA@T=;lFn6!e3GsGQ9iSFn1j%<=l!&Csgd`>=E( zqni6_HJnwT2wybY;3REt=0;0+628kyIz=-pHsc`%BG5AvD;hjLk)q=;cy*xm^wcXK z?5J?Hz-^p*gsQrUpqm4TO&~g}XaHs_t}_q>u3qn&4lGo%c4VB!r~s1>dP40og?d{n zNj5x7MY7yG*@009p&gNao1~3!ZvqDaZw-5k=}*&lsSoi9`LAOPf%h>yMohZA%~fF5 zA%O3=jWn%llcIPSg6u-<`k^)Bl@C$r@#&*Zve-)HcZ9bkA;~E@+SU;xNHiQl&{0aa zRooCEyskAjfPaXbM)1M)=hu{z7>bAxG7qvW>&u9p9q@gM-66CVd(vRfQ!oH~oY-|i z3TuQ#N_BvS0oiSh_2LF&k`^zpx1ckQ_3#V%Bxz7GR^%Cd#!gqNc4Qlz!W9d%3EQXr zu9$>Jp-;)FjktO2-~@*U9^XhUHNBPi2C>Q%*L2|&6AtFA_OZQ#!HVN)Np1okXn(MG z46OtwUw_O&5W#^(N@jIPUPaaZR&SQ=3sX7tnfT`8tPxgDv>BcFrkbbLmC9-@6Sr*D z_$y1>mP=^}sZE;%cE^iWebXhP(nzuJGF@+>k+SANqqfydWbfWEBv5O}1Ref?hcxdA z!?4HHPUeb4J43UlGc0ObxM6VG@jYsf!ts?#<Tm{qbV@EI&d8)v z;^G2bk^4EUXQ+}^TA3SK&&8!@5Ort?3_-HSux`QaeIkv7!seqxL$q*nb272Rf6-wC zNdE+58Ji~sL_3Avkl=3ThQn!1<{AZ*{DoeU0352TY`v-Wl5Ll86#&Os@+EB45Lwv- z=2|#Q!!OEc=Xk~aN^4pyR9h6{9?xge@k@*n0~VOfDt&9N;BII_#88w~%A!U(3XJe+ zV8jGbcqw;ZICh*iU`e0mZVda2P@s6`sD+&s+wQ#MK{UA-#Z8dyLcc~cmZokfVjR9I zna$$>Cz%qb^c_N(PW1AEI-E<3P_Q58c|Vi(anQiwB$REm5iV0WoWvd7iZHDFC!`;S zC)P~s`ZulIsDl62^xADSW^P2q zf?msie(~$IR25gR<;1M*8}(YwMWd!h$`N{+6=#uI?> zgm*|?>>*RQY6`llFLO)EHrsi7@^8xG!@e2cGLMBg-7;S;pre-Mg^e~H$s%^w$?zf3 zT@CY9`#U;a(sDT%wlTW+;zc^7)+k{#}}L?;C>}* z0xl(XX2oT`tkST^;I<3PHI=75>|v2I>M7r)Mw8!hi3WLZ@`w{z+S9sQw(dp?b76r8 zR<`HN8?Q8pj+Wnil?`ZVdt(1`XmIRxm<1=2vF6O_xg>kM!$Y2GT}C&#OlRTQiZ4*4 ztX;_`GwL0u^$@pKisO-kEl9;i(zvohXRiSTGN2C8t;}Z%b8|uQ9LM=S(ni!{;xZ-` zmUH1QBytwmLkPUypDyZ@t}S3bW&Z~oLa8s{z|DLqCoGki^RzD8)7p`n5gk@m8;hCF z0{n@U>QXb&*S4ML+m7ExRIX}Y%2~P{CcF%YRdT#8#lLF!YMyV9Bpfbufy2S{*>^B z2zjR2y@Owhx}+B1&$>ks2RLoRdCSs92y=BkTxgz$;R?@Fe5e_=n^-)uuZ@p8=Z&W{ z%{5Nyx{b)^&F)%qIMX%h#}TYWqk=tqA$AM)MQm;Ip(bx$>6l@y>^RW*dm`g5gtLio zBU*_NI?028uaUM72qp0m4-a5I>Bc>m5{$ai^Am+a%DfN3_n+8+TK=MR{g*;cZJq+j za^L6hFoYHiuxWz537n{ogw{7sJB&#(aMbB21%vP0hh0y;z)r#};0DJoJ?$WHlt{OQ zVET~BjG-9yK>|a!rNLEC5zN|8*$RPm;Y`;m#c3i6CUIf#B&so2gXRk`z;~W)YmqZ} z`__P#P-x$leWwO4H3cb^Ii}rFrNz6F$8jAgu22h}mXWd{t1*Eju@&Va7BnOuTdw65 zX6(^WqbbDj@Ua@htJv981YZ5jjF7`Um}Dq}UG_<~$xl33AurpIJZ|NfA#Sm|pU&OT zN-4Bk2%JgvP0nWQJ>xP?!dk+jwuFkaOTMm+luz20NW2LDsb6r@#~0}i)Cuf3L1fml zF5?h{E?VZ_%Ffe~1uUO<(}{ljf?KAcZ)%J(vs$8CP@$$1dFeBiiZ;8_A^=uj^Vdl%knb8c7K=C~IQ~scn9#{X<=EL2T+5 zTOl#4ILEwn)^L-pv=CUDtz?=SB)n8LvvS0c7K}ZdR!VG~O}H@X*DQ$gdbwPV)R^3n z0cmxoMQRLgLmJKP_`PdvBPfrpu}(ZlQc6`Y!c(4#TxkP5O^IgnA=ufud#Q;l(_%8F zn@wxPNQSW;E*mTW^Lo2J0_9)8>`txXn7CMG<243c8jm?XWy?n<_$r&wCFRWdC7YY1 zL;w3i4!0>4=$CA6x@Y)HHg~YO3w!xXMmLAJ!Sjx_T(}rrhkc!SpjF=O!=Uq{!X9Cp zoP+PS#U(SZeQ^+ei4Km^>4r4BYQ;srBTx?$0GXN#gOjZh0_2uTeV?Z^wa1WLHdwt; z+%2sK>2v@c_>JL@+IxeztYRXhV$<3@udGy%S!6ZjVNVm6KqmsQ-uGQEd2&@;(sz$g zSlbu);({(CrIT^|;+D8cCRr;ylFNcG2Fp83;zikK6U^^4?CFYsl2H1m3~+eiYt}i* zbnkJlvNclmyL)$rkqs@Ph!;ogr&qYb%~5pu?R@VfR0h-I z0u4Itl}B<|vqqf&iyHxt1z!XzFZa-2xcE0*uSi6UnH_`W3!<-f@$~9fDyGl2fQ~Zbr9jH+n}K9r}VwX5~`#VwvFEg`YDX zcF~d9>9&*QIi3I_~|Zsk==G)54*wQ<;uZ)3L1D zOzOBqGa9ach5C(`SY?*&or>>X2dJp-n7KdhfQVoN9RMnf~@B&UYEVG+1>nW^3< z60)YNL&CNIw1p9#cqS;B7op*6Lcli=p+Gwwy3295;i;_9d6@|Y3}i{V0yVcuO@1Y2 zMTt!`lS*9Y{O<1bIOB^0!!NrlZjO*t#)B%&LPy0b z@%Unv2x`&40ubcqHRKkin{5}4hMLt0*An9 z6RfdsIfp-pc>^s%unXwld` zfsXnoF3k$fPK&-1tJq_u!5x*S?0YfiN_$c-O`x=k5*Roz%lqdn2f3wFztc*RYOa=n zeCR*E8A3_%DLlfvleJK60@~B0|J04pXJ9CV&MCX4(!-o3NlIf*B{CD>ZY(*&9$PAS z7zno@bSY+@wuR%>O=|Ol&p1|xHIeetKaum6v0TWIz|x(FG`;f`2vc&Snv$%_0qJ}) zx;sy|De>N7xC``kAD%Ym{@?~|612+z?5y2a_bMyd!ie1JD zW?1$5q&a1V0UbkdnukHS4ocryoOb!yyp9?VauHV!@nEQ&Yp3N%H=I0IgMmbL47+J5 zDOI#?9#2V9IeM0lJn|)Ya7N`U;Q_eZ&~tqZq9Ghytz+?ajl@nm)s0m#*4WgjBRZ!U zuSX05PURgFQ+OFcPsBA{Ef6`UKUH9hbVAdK=G4Gsw()`P9L~()I$?+6F^eaWpPy7SvX|r<|wR(_&hByLB=Nsx#^N*<)+P} zALR4`>oVCCYSd?rIc_I&jrfp^d7F3ql%q}H;i{#N5iQ7q=Bm$@OVQc_Cw04>9q=)+ zomM=9lI}K+z=_7(kE(0ZK_2ssRQn!ouKtqD&h>0W22GW$(}gBkkuh`wVRG{3ED5s&U8CS0sjoD6eE=PF(H;5CDL6Xgz0!F^BwiR0v5FWV$@cH->*(@r+*jx&T!M0?RjBgCh z4=NP|)ZEB#DneTmK{+5AZTt4^JGSp|F5ly>?$FIPdvKTE^31KwZ|kPGSsI@Xr84NB z>I=3>5qQu2h~WE~!93rJgaBK59UAvNBL=j$1XYuLr-p4x@2ns%{QoAA%3Ep2XU1`7 z5lQ(94c1cqFAtWZ;*@n%?p^6eLZg4>E(m>-8vO3jyq&EtygZbz{Z86d?(cBcsBBTvFe!|=Tr+B)nal!d4l;@{ z9h23FDFDKduAozP-Wg0&|4PQGGDp)%f`_{(r4BbU)c$!^k61~*ISx^=@21s<^S91oWi z*V?7pqj@pBYzk`$m)!8BbQbSeZ?=nDKgmdhwXnLf6z-M^R+o_zy4nv@E7T(woM+kS z+sgD4DP?d)N+4pAMNgoGW-Oa2No%9Fr8);a!A3>k3_FyoE7ANaD&=}#Y^fWTh%K>r zMNwKTh8L_7%W1|)E!TPE=J%Z&%oz&?WPV*I^!KsdiHrG!utyctqCV4h1 zzCh-0I5c6|t%bLliC49#gbE1$sdTZ`zL5DwzLF6;BZZ{`?1$FqBPYh?|^ElWC$)`SZi zwB4VZ&pwx}t(j|a<1LgsuV!R1QY8xKIM7E4i79X6(;aY#Rmt_#5gRx(lbDUk8YVfw zEPrg+ht(Dr|8%K1%dN6bhJHFD_W8``9r;57M=!^zJ$N`NqRl9yfHkb6R4j+Obdv zGsHknvwMoKJYA%VG_gfUKG|6;kLhA;xsiC9EE@!ePG_G%pe*~hXye_jTjJeys%mJ1 z`Ti1xUf$bVqi1j6#7O6V5;Yh%jA9M70ynX0`__#Zvc3DeCswd`c=r@dE63NcBw>Rt zMS-TTsWeRQ2DW=297KFgD~3nGCM&OY>$){qa2#UD+e)N?nDJ;f8o*Qs9L%JXxDtz+ zDS1OMcRRld1;f47JFzmxNj0>X+oVB69a##u3KBYdLy{LOs?#hCwTz;%gI?tZj^|0q zgN(zYxE4LeBw^bTo_bzq*GcEgF24&gIkHL$?2vCCehD&QhGgi|9uzH8qK`V69b@a< zzPHy~Va}w_L#Qq;Qc+?U({?u;qK}#^<%S|(WsL3~ARL~}C@u-Y9gZwo4jHG;9pq*Vh)x-%3n<}P1l z8@nmn!1QJAszf0I5UNVrqwHO3U1|h%c~B<8k=Kv^N8*7HK83%z~%jo*3G zS)1tJgQut0pOAXC-N9WBwY&+ zJt93|ug3IG9r#k>Nmrl@W@iIKCZeHg7)oVxkf0qZp`|c-`iM zw@{)8bqJ4+$%i%{{7OnzZNPENh?tEzUcUL@ampdm6oWovdVll55v4yabIdV&F?DtG z!B23FkU41+RX>Qg$SOW380;z8B`=d%=w1R2Y-NaJ|*YWJB~5a4{kpAi9DF`yI4|*fdhvCeG2uLk zzh0$DNhRI2Wz#057xc*Eq~`I70r-=TzZ84=DP6b^Qr>N3t8kY)+4%KJvH83d#Xjr>9@`D_3sX1pEHF z`0^6o4vnE-yy;Dj4tcp|TWcSJ=Xg2L#~a>w%4-N8EW2FVm^aCZ9KXjS-Q6*iN(ZZm z<3Je04DE&2Y{UIPkqVP_j3JMN-PQ2`q1p5l+!)yB2cK&vv6s1<4(__R;Gqi8Iwn<+ zymldg4NrX`hL~AqQ@zs}Ee*z_P6ta1eV!`Wpw)EgnTKLUm=*v<*Tr}PTk>di838Z2st@lA zAvAZsrg(a%3PGnaXb0<1#81(czkx8FNykcx-PAMD$p|LlTid_yMwh`ugCncUwT$6; z&bf^^!=@Fz1zTl}NFO$DcLGF3X(V?9b!@q;Px9l)Ox1&~7w)l}vcHZchNR>{S>qiY z9N~Qhr&A7Nh6wu}?L#*lh5t3=^cp(KVq7k&!0Qc`keQ=A?vwOSTLmB^KW1_Uf80SR zcMr4x(ixT%$qgqeDX9(EP&%LH=lQ)98>59UdSLQU4+IJ13S|^gX)u+SkyYdi2h-YgyBPhL zA`~@6hv_-V_lwya2;14r4+(r;2;hZJ>~E5&}Wi!w&IcZVG)xX}>^n?@B4`5W$EL1-g%wknk@iIhhQo2m{U z8H%l&u(|fi2PN1^7b#9tJrE#adEZEXKgAn$*g+zQ;Qb9?MJ9=wD8y8Q774YeWiEj& z1+S2C-s)26B{rI_)G~p4ou50QfXtgaTXl^Kn%u$BM1fpR>n4G{-~rlX!*9^@XH*I5y+>w!QB+go?`|ETRq`MxQhXkdi)KpH`aB%b ziCgHf(m75gD-@b~=-&tziNT>j@4SpKC-mq0vmwxALUiq%t`^8+MYAPH^gP-MRs~Iy=je|>_2gQ(L$N-X-SJetQ7TQ z+3A>YaMN+~a<>-#w<+ft=k(zF)V87>i$z*mm&-ZTL`4g@W3&$Ic?wFczG9`t1Qd&} zNjKG(OxA4*xVlH61|LkvN8hEK4%L7iq^l2IK(^Aw}wOJDm8!-1Y&6g zA^X8O(&cx0;PJ)cA1908hs~_>c(kzO8V+%VIEh1KF=FMm0bR9^$p>HM3PpKh4ml+; zWN>qbQUeqWLPTarL=fjjmviF3v>}9bwBg$Tr!y^zRcc1VYA%L4fij~3@k(~6fkB

iTeuS)Fd_ERyc_AOJkw)C!G-~GA52zu_N-l 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

m~}Zc!{orE*5+)J*%9o=k?vgh&l@jRk_s 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.}3g#-UhOfhsI;jGf7LLG=zD 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

K^ie(01Rc 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 literal 0 HcmV?d00001 diff --git a/docs/.doctrees/honeybee.aperture.doctree b/docs/.doctrees/honeybee.aperture.doctree new file mode 100644 index 0000000000000000000000000000000000000000..f876c0595a37b192e17d7e223d192b036d00eb1c GIT binary patch literal 217429 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 literal 0 HcmV?d00001 diff --git a/docs/.doctrees/honeybee.checkdup.doctree b/docs/.doctrees/honeybee.checkdup.doctree new file mode 100644 index 0000000000000000000000000000000000000000..b00e1f81648fee429f8c47e405f3568ab1b51d89 GIT binary patch literal 27623 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 literal 0 HcmV?d00001 diff --git a/docs/.doctrees/honeybee.cli.doctree b/docs/.doctrees/honeybee.cli.doctree new file mode 100644 index 0000000000000000000000000000000000000000..625a952a86ac6ab146dbfdc630d3b41c42cf0a35 GIT binary patch literal 11872 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 a1)a;gR$(AL(oIy@@a(x0q=X~wH2(|O;Oxl& literal 0 HcmV?d00001 diff --git a/docs/.doctrees/honeybee.cli.edit.doctree b/docs/.doctrees/honeybee.cli.edit.doctree new file mode 100644 index 0000000000000000000000000000000000000000..25e46e753c5e202cdd119c9015fff8fd17eec40b GIT binary patch literal 3079 zcmcguTW=dh6i$=aj&pI6mR6uPB^4@7MQ!uILscpes)UdtEP(=V)oQ#u_KdQ-v&^M& zkSf7LrB<4^4nK(h#RK2j^{yR55xih&CC`~N=km>W&YWL1fBR!+t^E0YQwW*Q1}sT( zm2eaMR-$5;@!W>D;o-00WjOI&%`S{`I_ANzK_eD2O*GHL^Wb}=Ze?l)^Yb0UV=GnO z92YIo7M!|64iB zs()LFD;A3}i_bNmkdE^m%cisy#J;#KcEugBA&&evL!mN0)Gp7t9$qMY4ndV}KUSKr ztPrkgL=7GTZII60({(o%YrZA(gwK``tiTl?B7AWVh<$|bKE4O|9#SemL(4LO6Tew7 zse}KZg81{}I-15AV6OK1f87%8kqyj=PegwyNA}-xtj!K_-9x(WL2>zn5=W5v^jJ;) zCMIzgmjxO>s}O$}P{6;M+g4)PYWQcM$s{ z-<@(0oLQv<770T+S(X)8>{MjiUx8Z&wnY@=_9ANGqbcnBj4LU|!uLzpHtnw2e~! zf~Vnh-ERw)Hp`YjS|Im;mFTFqikNrl(GC-cJD zi083NpcQ=A*-8I#-$?wwb9FP~S}Pq1P&VbL(Kdw|+u-+=vsbOON-M!1t?aCr5I_4~ zWpoih>xZ+i`;X!L>c+}Re?SQspd^4#iiCpSOIbd3Y{~(5g7rH3zrUe5`dAVryZ|}i zh8oStw_}x0kR#xbNmQUq%2^O?-($|IXd&|J5{%kQTvkL4>ws!0kRY7SSxN@?O9`OO z4c+}hR2c3O70oi@(*d6q%J69UWJ!_OMlYn16+ic*L>e|uDUo@Uow^#tBfpDe4EWE= zM+}sit3?x;mR;2M3SLCWiKC9*xdnOu{->V-j-H;xE9ObEF#mCF9)-q;Zs%MNB)5~&2TFD*Y?i`V*RnAx zAh9BxZuukdDT|uYY7&S{K^OeS-zwvhx#5~}2W<(Z1U%ls0MIN^cZbv}P!9PN)s@Oj z+VJhc1AkyHbIWFtkW-Q319>-7MZDiN8AFx*Y8j;}W^-tdVu2PP^yPa)y{Ufj3}}ie)|l2kNeHo%)1v;}t!b5qVR^s#2sW;5>jc*_bD& z-%ErbIJa*y-nhy~qsAe%g0q%rmiI?bpSESXv0WqvinnjyR3Zn|-9THam z#hLid_$~?TWdWdH25~kr;vUTg-(f0wibu3v1+eJf^YN^CuEbMTKS}kogQ>&dxeBl8 z4f!2|&HwV~FTbYF?=3U8%zQ7F;6FhJG%5-8ms+oacv({E0eBEK8>_S_hEnyt6=9>@ zy<)Ljdo2%LzhWQngtqiB-CVUb-&yn9=zg(s)Z2pJiB+0{6vzS3U+39e{uUSaDtwPt ufPn{11>>gycPocY6TBkcX~ZSnc4Qu>E+M*4iD}yj_33#_quIfY2Y&)BD!aM> literal 0 HcmV?d00001 diff --git a/docs/.doctrees/honeybee.cli.lib.doctree b/docs/.doctrees/honeybee.cli.lib.doctree new file mode 100644 index 0000000000000000000000000000000000000000..cc8196b454d5e325696ea0b22b82c67b43402bf8 GIT binary patch literal 2795 zcmb7G%WfMt6m@J%viy+kq-g^rP7@Sq95j-;=psn72oRuM7}cUkyDJE4h7t*L$SEJO zya>=P0we%;VgI9_)KBT*jAmpj=%NM$n3tFLdG0;)$M#?U>~2(l;n0>`sKtopxzaha zG3?|z^955bevD84jBn#<=o@-rwKo}yVFMZ&7cw_Y#ouBWBy}gG9WCGYEX$nGs(sEo zyvuvP#Z%r79VeV*SFXYrTq|}tWo(p5F_L2XpwPL8PI`hD+ppOoh4SBu?_w1t+}sM? zk|Hh_`ElrzHW9uRy36<{VOt8t;>1sB*rm=HG4&34r#!brZc|RZOj2th#Qz;di~7Hv z+?T7vlxF9K&617}JxAy1D)K{qm+$j?e2briAIDr5Y;3$z%#1IzIftN5c9?0y)=mi5 zwxXsQBV&=x{j*I!jjiTE+g|=Oy}c0znKuatq;30tBdOaTb}VyFs5uaS z+(LL}v~o=4F?4^W(xYz84DiEA=+7A%Nu4$khnxa7jus^jd$k(^+vhm$E|1TXIeX@9lLUQb|W05`BAgk)gR!;)mWNMmVX@@_3*l2sCN zAsiM*f*@y#u3ThFd5G_!!Dz9NXqYdFy<&pu6-4tr( zVmQ>^UANMyti*7#cC%)Ji!i8-t^(-%^7@D2GdRC~vGy_?r35Uh#8DrKgkm_5RLwn| zGn6~Wc@tYM+%gRFnvYXMlQP>nf)Isix zlC-EpRV#r2;EbX&89b~cD6O)o_bX9pna?#@6bVm9Y*A{<$kmq>L^4O-2rFuQ9+F&G zI+ZDrWt6>U8u-(&k7O+HPpef8$Sl>!Ovq|ogh9zlf}9xUD68__Pm(Ex>jdm@hdWo= z=i@QNc2r(EY>kmN^KlHflV-A%G>Kycs_RhA9mt1|zWom67?@eMW^kw~4IO3?8GwdpG&@qAp)EvGNQ0_c&=38vPYtoum zA%?YCd+4T-0wqJKlXlFcZ(wwzT2Y{DGc*O1R*)8x5cOsSgKN zaa-kmkO`na6%MtiC26}fdUb)XN@_in9WX7XTDGH5seZO5Y_EcP3()uWr&?1LqY zOSE)*-PZDEBkW@LW!k6B7QV4o+P?dEAqFBe++a`4m9zfqJ@N&o-= literal 0 HcmV?d00001 diff --git a/docs/.doctrees/honeybee.cli.setconfig.doctree b/docs/.doctrees/honeybee.cli.setconfig.doctree new file mode 100644 index 0000000000000000000000000000000000000000..2e180a701a5192cd192c4c8c2694e1153cbfee28 GIT binary patch literal 3160 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 literal 0 HcmV?d00001 diff --git a/docs/.doctrees/honeybee.colorobj.doctree b/docs/.doctrees/honeybee.colorobj.doctree new file mode 100644 index 0000000000000000000000000000000000000000..3f482c5b050d7c0eeb3b93bd0ccbafe0865e262e GIT binary patch literal 62168 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 literal 0 HcmV?d00001 diff --git a/docs/.doctrees/honeybee.config.doctree b/docs/.doctrees/honeybee.config.doctree new file mode 100644 index 0000000000000000000000000000000000000000..3c5cc8f700b90e449a3b9face1a2711bfa2f2afb GIT binary patch literal 34904 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 literal 0 HcmV?d00001 diff --git a/docs/.doctrees/honeybee.dictutil.doctree b/docs/.doctrees/honeybee.dictutil.doctree new file mode 100644 index 0000000000000000000000000000000000000000..65e8e440d93279f012a70e521e369323aa344027 GIT binary patch literal 8717 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 NpqI7J&KcQw_+Kt7GUfmP literal 0 HcmV?d00001 diff --git a/docs/.doctrees/honeybee.door.doctree b/docs/.doctrees/honeybee.door.doctree new file mode 100644 index 0000000000000000000000000000000000000000..5a132f6329818dd5bc20ba7a181f578b142fcef5 GIT binary patch literal 166216 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 z z&sgx~=)4HNZoKQ2uE8AuFs1;dQu>;&6tHYp^ZY!JO0&;%sM4sEgjii-%s#>W225i9 zxbKN-@e-Oft1U@ur{mw4m=b?qhEvPJ+9#6%(t6AbHO~9Y9 z@bbIA7%z!n`)ORNih%nTV)*@AyCMgyeU(zF-K}-XQ^=1(G13FSO6j$^(EcD$i7EMN zR7$om(O1jD^q0#WiHa9{%N|sLe-p#Ws)MwB{RN|#rKZKF!h8iQ>YgF5wl-vHo|Jd< z{X5;~Tk&UGK6qdGH~6i;Fry+_9ir6AjS`(PeDdZe*`0HvN(JiWQhx`X`H--6$0Ex2w%=y+SO^TBww2GoZCPUqvniQel{FG@gB}p5=m?vYq~=#cOU%2=@J%lYQx{ z#lF`L0SB53htWEi$sR{KGu=N}W_pp_ZJS&~0#9-fL?I6D(f!qQo%vJ%y_6WGtc=Xa zJJ{|}QqoFoy2I~h_k6~0wZ=@7R9GZe>$K?LD?dbt>>}-UdDfrs#)R`~3(gplp*oi7 z^!8r}OZ`HThe=8A_%KgoVzYIql&nS2SBuS_DcNk#AxRCpw+w&*6WdryXX4`+*4+dO zNknIpGQ9KU8K#Ett&z^2(YN+YRy2L1vHDszOVlny{Z`~+T)M+zDK`?n#&z8%P^FYD zhOsfdVq0j&(G(VQj!#E6W7%Y+Ig6;ha;pX%3Cn?!2AJYxS5%wJK{lxn(i>!}V8mJ; z+#=J~NHCLu5e3T-4RW!Jn`ebPR&H-|xnreWNV7x%ckJC54|m5d(i3yXvZvv@W6$Dl zxk|Iy%IJzcH6{;Lq>(<{u#<*q&IC(s!r3j1h5dq27wq9N&~x`|%ojCbm;`w%$Ym}{ zVF}`Py}nV^?aeQV>(xMJ^mfLFg4^}u3S&9kt{+CFtX_sMI6Fx8GVngaUWQb+>wmaA zE8t_`U?j^r)9w0xj+UixyZ+ia&;;kuFF1Ue+^(xfT(dBlY`l*!*&J@yqut#UAQ%Ur zAi;*}cAapJHGyVlpioeTl6`&IbBoCd^%aYqwFW$lXNW2Z%?YcHzCrWm?YWN~9*Vh5w zK3%SV4LWg`>)+r>x?E$lCFyQGHXeS%)he+F-2Sy#FH&8tmtCw~txUP;)6F`t_LPzs zyoWe?B=~zLW5>Bz_l!yiP~Ry)g&^1N)n{$z_t#`}uX18wuR8?S>T&=@)Av)HzMsfT z-{9j^gS%BV#+SgY`n5ceO1J7)sM4sEbXeo}x>d)jD|<$KXj;VR&vT*uL2hdL2`VKU zMCq%!_k`PM+50Nh#998JLKNB5Vy}ji zz38jOUdzCHsX1~P00Snrv6Rllx8!AFXOq&E`n?P~h471!o}SS!_C>CKq{eJ2*QwBO z)o(>Ewtm0KVktM53RmjusZz?e!q|ik)I-S~JcDdfA!N|5)c57VEpw&5Cj%o2mLVGC zVi`Bj3RkM!(&lodO1qC{i2|00+i!m6r|k1ylQti$CW^( zr{$p1i=7=LQ;GKxrcws4+AH1N6`&IbBoCd^%aT`3%lzPA0(!_^wZkI|WwJv}gBEe9 z{SqrxpANN;VYJ+#_E|hhhgx`PmAJAK^H*X4O?9JP%-v`*%D9Z=N#d9s z^|Zb%E@DPhV!g(19}$NY+c?bS(Xy#y6Cdkr3#o{*wWidF;LF4ZBf%HxPo7kpORqEl z%FhWXf%4DA95PGYY?-Iw#D2?srLe-3tMBJQiS*=rhboQA*#(VYAfBARRVtD?_@fTU zwUK1sI38E__}xl$63(Z?K^4TL!&6w|@$BF>#!#UHa*P2{7~aQrxmKZ*6~u{x3poSI zWz{Ym+`XpUD4>Ib7cQ6UAonNz}Zr9H3))vfZ;%>wq9V)RVDikYTmQzF>ezrt) zcy`4e?ueWm5)vr#UXh!Lp^ZhR!Uj}Io(lBUnhNzq^Y@@|qvy+nPPftvhTgB_de8(H z3tA&jXUo$WCI`lr4liwdPHNIui!qmhty;~;WpW0|#!@;HUz3-K zolQ!^`7bj_Y+(f@wJ4(%^gb@!Q*}9ID0dsq@3L6R&85O{-lIw>T3jK+IgS#_Q%DN~ zI)jwnq~_o3=J@nhAx-begIi`ee^mxX6f8qD$i*^lo)w03xr4}MIF~y;%@PF+=byoN zxZ(V>^u!G3>}mLh^K-dfnKG_Ss*Ec*q?%?!KO@nG9%-r%bNaQ$emm0cnA-V>Q%ROu zm(j9*Oaca^kv;LdnmbGv`!*f4sZ10+i!m6r|k1Oz*yPTnSVv=b%#C*+DXucpqUZWiY)z)7@PG zI&nbq&?&tvnclVd4}L~MZpfy0Gyh(6AxOM3LPHs`!hZu$_i2TH1E|HV@NdVHw8AH@ zz0x3mf>S}*ut*l9Y3ODWufX;<3B{Q%j|kh-VJP+d$}CLrhJ_x6P?4pM-FQ$IIg`ff zwOc4d-Bfc|rzR76U}t;90Gm|mNAOCV?{(`97#QQ6$sW$2WzCzO(^M2xLd2vXJ+X6{BRNS4=!4A@G8 zm73n3=vq_pA2}62m6wXaC#eQM&Z0581Wu4|^;sh*sPF9aAjdQSuv14kNX+L!n;UIhRfqD|HF#9eI9jdb4)%D z+$2rPF4B3JJ`N^ORdO`4MA6E}WpPO@cOt`8twVy=$djqFpf1zIX;zO3}XzZG50!fxL15>5c|1Tn7s1NN{%^+%osYOENH`U>Tx8E|zigtZ-jQ z-9MN6LT-jNOB8Tld;sI&?u!r76LVj%r{TLV&KJh}?$qQA0_NJ2O>7M7<@xyxE{qAa z0i>!ErX?Y+xjx(&PfTljK(34t2R7s;*I7o*C+5=lS5VVjv%&(#?b7(7s@uD5Xz}y-;oa0KM()Bs0G~?_b znM%BmFqJa6H9GF@3ebrIl7~*|Wy!6fmw@0qB!h z>Du@UP>j1a?!}XIZ8+Cq>E1XwZA`}T1Bqi`{&Pa)ryf7p#{CiERtUs+Q-6qxYafvaN~|jTOQ6`=U}Z+tXKz?VmDad}y8>c28h9dwl5(_uIiT+{4H+f0o57 znb_}4C;QP?i~aUm<|CGQ8%ya-JjSr@CXjG1ajEHSQd;K!Im6TtW>(U2GMZW6%f2I15SIB0RZ3CH3R&jWv4V%iiCN~^)9@|x=h!=OrlzMID;UdQlV=U}VU3@T z-Bfe%)D~vY7oCVZk+B&TjtVgf?h{M+s?-!_j(;r&l%2g$ZW-bdJWm};B9-`&|dEPiEkThlwT-JPFrwmOsT zxpJ#>YZrOQ+lzN%R}>tIve0Zf7|Alww9S8(qea{154Y|u-MU#MZu+3S;JX*O4^+ks zSylC+VKz|?IK?$l5=_1;P$?_f);c>#CL8Y~Og6`*C#Sl*DL^m|KtX~HH9gZ-=U5YH zc76_;UFqx~nP$9?FwIggJ-N}{Spmv%FbYy`V9u15b6g2jYUH5O9nKDtsl@vTQz?Tp z<;Cvq3ebrIl7~*|WyzVM7x3USB*%yBOgTPTM@r7qq+yJ>QQird`*fqc3$)^Hln>xZ zx=|7|C+R>5oplN8UWV&LVib6OmsliIT_;x>t`qIzDC2;^baNx+ektSf*jlHG=vm=c zVLwIU96~Qnhjbg2a%(|3Q3l$kQXYd(5tokypKvm}x$<+v=ja|(6#?!?1-Mw0_34o3 z<+}_;69zHNL%0xSxqzc-{S{8@FXg3m@I|V@PmyTMFTp92@8^M3IAHH5Q7mjJuq3^7UHzIB zb-S)!ZEd`iqqj`y!|JLvOtz`kdeKmlA&x5xv|Ln z*nmpO^Mk&cQx5ZE@1-c2E=931m(KU6GfE7M@BM+gY#YjFJG6^YZm@XGjfn@jIp;bj z`_fm7eXlL$!7G`Vza&O*oZsU z#!@;H-@PFu7s9tjI(tUn+I?IV8I(KrA1sz~bE$C0{ykMn*-j$HPIDoG}4C~_G-h#XtX$H>FZmOP}L^EuCfHEjbx(4RHNg?|L=Ix6+f=H~ z4w7lc`v}u4)m^vK-B|(3aWD!}ZeZ@ZyPV@npwbI-Q0Z094w9+F`v_AhgS+m{?(PcE zi35^{PU&UIU8fg;U>yNHWOv=#__Z|IRj1*Lxaw8{-acJ*UqBPwRrhr~NmpIWsw>@e z$Hv2NxacGnf!o!D&@2huwsRMqyj+FS*vydM4gR?KCNkMjRxsg@n{KvR{&WW^nCVZg z*^m}UUZb-xukTqIbhAqJ2)<1t8wu_c1C$DCSo^Tdx9rr@o>4Ra>bDdvjJ?nU*OSY0 z&hJ#46*xWVPMb!3!E5;xOypf!$Bn?kI!x|TMT+kHu5zn_^m;At+Gca+V!u`gh1w-% zM^+{M3eKeMYOtac9*)Pf;c+duVQ;1)ly?tZ%{41NRrdT=i#n6J-)b;DLm`5J89Drr zQI3j$Eov>DPj04Oo1aG~Qw!c>8-8nc;hK84J&rEAZBd$x(k03`*Y(`2IQ0w)SwDiD1gl77?825kddVDmDYJTx7UZAHwhlA4mnJfxQR4AnE1 zO=Tnb*DxG0UM>O&OZGZcN_NE1SIflsZU_=@&gsQko`_aculJB00+tb*BFRdYbZj2S zDC}GrrDJm~E9!P^zQQsw(A-OOZlqp&LyH1q7tFPCgZ>{ob7)GX%({4&rUk4tYeZ7) zDdu2CjVmm+cOy^Cq)Qp{;Hq5d-FL^`o)u|JU#*$++~t8bHT2#x0SH`fV=JA@FJ{mU>Tx8E|zigtnfU^osHaVxGO!2M`cKJhh~Wao~Q3&Jlym2eR^V^C-yXa z&(j%|S{or-3zOvdOmjM&7~^y@>nHk~hJNR47>X0NV|y_v4=O>u!a2UNYDK>2@r#1Z zIvZHFKgTrX>L$;&xTd6~2NlY50L5rABe+69k zX+m9((Q*^&S$L8r)G%{M>uD^r5eDhz3yC%$^EZM8V$U`hE6OF8`5kOb>NU#DGvi&t z=Pzw&&bdTiQb(uBDNJ)`t=%oxYqtsOn8*~a3}S<6OwEJfd}4!<;F0tvYy2|VNQ3{S z(Sv_b`4OUWcPc!COfCfe0wIAV-VAKoYr|M?zxf52+quzm(KlNPj$H*>ZbzS70$)u} zOail~3=&wtPBLdg&Lb{!5+_k_wcqHpK%+$xOi${qS664GiQsi{B3RzLkt~0Mp=9}- zoPue0V)7#TSB(Idm8FQ^!-!dRg&5hp#%PV7!8YC~Zevon=43Uu)b&-}-qIo{QRu$> z`TIbx!2dExUk!b*iw44^uU1-uNxbY&&h-unQ)-dRygx?6QsxTo1@spwZKc}@|-BvYAcaLM#y1+=r8 zluUArkW6yq`6bgE&?lEnZ=@$Cnb=bn$;4srM>1`sQvfdIaJpV@OLx+S#a^6zQcWbv zC%#6zRJNlSC#sglD&TH3Oy1hr;bipYde>c+BuV-*^fxrI3aqohP-=3aq*JdZ% z^N>DUJXO$Jf8m8tYnY0-ws)XW&oZZdR8U{CPPL=@-Pe-}BAyh_G5PcvtCqz%cZ3f0 z(?n^5OQ|cHRm??8Dq%I0{h;cgR~?F!pCM@-M!&p}Qftd=6lo+Tj5lG7d`kfw7g6Mv z*m|(Rzf&_z<{9ei3gQb6fsVB?Uh3=x#>=%m{v!K+0Eh1r1dUyC#taSn zw96Z{PK~r?+!EK|z5;5S+yUwmXtn%gEUlO;*od(JoHOZ99vyj!r#C)^V~JT4tD=q z*R+iUw2nO*HMX)&r1QPas%1@p zc%6^Ba!mlKI*`tHuj-&zUkaU1k}azD9US5{Ddw%WO6o94|8WI;e*I4mJop$jW9xs9 zD#}+3^0BH`8cVt*J}Rv`Mn0|WnXkg5{kn6s32Nk5P${b#`2|+ifcyYWEwY_xxUCOs zd-_Ef=ARXT`N#dhyhhD@K?n`?3i>1&i~k5iTiOtwqt3QHd7|AQ26fCqSi7?YKG7XL;ha+S< zB3e)mGwxG((2sTwI$@IhK@JjLnj}V-xTg=B@ z-16z7?6R@Dluh%*RDOB7$}}S%$vaq}S`8bi@)WXoV25&!H&btxJ8iWK9bAKIW(JGI z$0NbZoa}6xrMTKZx(9R;fO(ey6H;Agr23$~ubgH25@GK!B2$PsP7^fe=KMwlp|<2K zEA#UNDnmbB%~4!#wFz5E2@&Q9=B4OCxFB&nfuBT}@;keHpYAIMWfTc1q+JR`{T9hp z&}|7RQxM);+ey80vjPRLqq_9z$z~LFAL_%z7f1^Pyz{ zF;!j>nPk3FBxgGR=W?M@SVR5^m6EL?^fk0KTidH&zmzypBV6KsA?xh1C$IL>67!D? zmzHX5Sz<)2>L*!IH!nU$iYRVPo2i#O9lrsACPmme6h6&_rz(k6Y;5Dn!Z}x^oVU(WOI*8LE0-;AJnyBNvG}uY;0~c z)Z_CiCFs4hrE0-}{Zi%!$RKS@2G9Z*2)9cot4pU1b=-gScB+#* zabUXH+WJKH=j=X^5y7uC)jc-dDa*{r)3C6_0TdX-776Weo{u@-? zUU$fb?WCdFCgqdU5y|nRZO13ZRw2|g%uBp$8|Oi01&QtO%P@{VrtlPJLr*Z6eF&AZ z+B`q+>>$}-#`_2x%#M)UXJG)kSlp-ZNWbL5v$t00J=}B+Nv|9RqYTwNvm3t*pTM6QO8IOJDWr* zQ2keeDN^lhSMcz`Mt5!sX$7RMW)tmzy>rgnr1D4@lAVVc%48G`k-b)1+6LLAV)fuy z;0ps=OMh|&h3r8w33!hb@P>?T8#j4dz3sI8jC<$P^JB~H4kX{B==r*4m)@WKNcwSu z-|k3pm$Q~e-Fl9?)AFJ&IF)K}lae0C@J&kR=K)ljl+L3{qf)RyjK`Ri47=x)xuEbp zdc9m(nCi|>&iYMgDXj%hN@X<(SREKQMUoYj!(

yHIA%}!%F2L!b&_mu_@RW7YiINxyuHlR9EB+Ml_PMV(VqESkj>nVS zSH#F8xuxJK>mu+Qy9tR!;P%f17o_ecuHw6isU}1yVuZ=-rqkD{gGr<=2_>sG4O97o zrU0sp&31K{u>5sI8in=g1#ha`A&-9vXO(KRnWrKQ<4fa<6g`RT`CYDt@n$-~D|F zEv0NL!{?8PoMCgYhFBRjVo~$Tu2a`lqaK7@+O78nsXAH zlnb`?GcLtreYS&1Xv3DgK*^2Ajcly$jfe1WJ&_f4JC|Rm)DB9kD@t~ncPSaDUd!yl~UxpVT*d) z^({mt)n>GWwkH`xc^!#jQ3N6|xtQFC4z59kjNahd1PgvK4_4Vhsn0R8y0I^qg|MHC zS=`(zOgB=i$Yr{binC^h0;Ze)!+5yq=C}03OgHRl_@ zbp|SBHDjI5${J>@m5lXmz|FTvgv!f=LA|sHs2BAE>H%_k3LHg`7#>}wo=e z-T2`pYm~o8pkZ=`A zHT!j#e4lm>JAr&3&q2PgI6FutAMYbfzPP9u8HFjmwg!U2BmK4;kOBneAQmL>(XskQ zWCk8;6_Zqryblld|D1zOAnUJlkoCX`mwu8=R^CULtSgzSB}XQHg~xN8ySoC!>2*N&=jU&mwM_)}8qTIwb$)wrFqN$m;CP--a zpH9My*m&GS&q2Z`aSK^I4Uu_)Vi#$O%Gt_tC}?S4y2PKMdr>G1hX?pKn!;KhOJ!++ z6Vq7!R5)a2>b6A`_h1E`n@&2@SBuWqMCsh;c-1I+gKrzWVvix6SL%c1l}|InT`a56 zRDqwL7XZ7onn>^%n)GzNXvLpx`3M9mT_YtYml|zyh#-860V-XmH0!BxmJDUw8{0hYZQ8(V%UU9vPq|)_!ypfAg_YfGm#x&w zv&{zOQsJ)Iwvqx{T*qi^Q?^)|?AMB`*%I|BYu;uO1s`*Y0{R*j1v}0I>9<9X4(%m$ zI-wQ0_9C&5*)kH?T$wKZK0HwI*ZYj+t03W*bgw4uF(}N!+-x9g6QVCz?ypk2+Uz2R z8Dfqa#nskILXe)o7w!&hTIeCX(iWf64%A~joD5Wf71-1X^#qTkEh~qr@lt z8U&^r^V=L^xjaWy{9`S~bfZXEQ?@yIoxWPUe*3mPiXzR^dl(S#u8o~^-o0?JynCl| zZxZibEg6^IdPZ7H;x?u+neLnk@A4U>lfb0_;9N?bs?2+rH?FHzNS8rwGkSuB7s*^n z$U{YvOM(#D(56T?if3H~opco?I$xU>pJig*Tb!&*UoF;s+8)J_=G;9C2N>7JO*-RN z^D?fpNqLy#hzwech|ed7R>t`J-@-cwhu5I)vwpqBNN(N~hdEwHl~Vj~#$gWlm}H7i znv4y9m*soK;?m*U66g!{st_)ly=uZgEMSnK~ zit`!Lk(=v$hIFiJ`W85!aUaIR&u9D>J+bo{>}mMtGtL+4Je|*=oZIC2nG^^A(voaU zxQ}Ys&Gm6=<3o0+gWdL+e6fcPZ_Jf<^TQ+ZYMqqB93u|2%LUR|M$J=Z7ce5^kszwe#@&aj|_J}Z0Kc_u*JBO0M?wuSYd7iU_WRmbcGLvM{ z-Aw_KZ~zLDWT{Sjywy4E1oFKx2l?LT>>!zZypJ&X`a13Lk8VH;5SW8lkif$|?Qx%T zunA=S_Z(#XiL--bvhqH{WX*8euBT*^qX^+#K9VAnT z_mP`I=eWBoKp_rDK?)7}vUDm(TL^*@ zEvG|1mBUYzxC|tTDH1iLkpnspz|7I-0i9oiV*G&4zUSxzI!-f7WieaIyl{VP)Seh!MBa+ZjT|ISDrUmUip1L zxbtp{i8Ar!JDq$hxbvUZyv-yE zzUdSN^ffFB_MSN@e&$38p}j~fjzow*n=8}B-`58!{(7I?LkD+4hj5nP$(;iq5tbI2 z1kh?!O5Wzu*RTNUy+9>N>*v$?( z_JYP9XYfO`v6ZG)B*kWeOlz-^OM->rV`p^&dWGcP1^y%*5+A zIeDGFTD-o8kIZPE-ot=^cWvyX^X`tp^6vAMvpRHkN2bxja*jmw?AQ(pvTIsmGHT&e z0CF|p&L*66R!1`R$sT1RV`ZjA0yp2oZHhRdNk=ymPVOk!l!I2kQB-7M$ah*?mWgqn z>ttN|YBBC@>g3MS<429RwCg-v}cc-z0=~bOicSWC)3hb zi)jlV^BM?-G~4c3IKa3zZqga|EqNK&*`z#fHlAVMD~=nH_ch~jqhndofgLydp~XmU z-W12pzE71>oW&2f<7N-$K@>Y~_UjB>CFoBG%|(AV1B&BjGU_1LaWfeZqUl@UxY_CF z%HwA1>4_aTV^70BZgw&qo=-bhc1+BJtOhG)R#EwMPQPJ_FQlM-x0i z?YVf88KgNM%Sf~X6_iG%Xo(&m?R>%%BDhjR&Q7?B@?a=myGTD*7FpwXR1juSS~0~x z!ClnzNbn*7fRu~jDQ1PgK$MRz-E0DMFVN_TW_wOw_eB9gk35zKij4z?j}vqAwt8_hWK?rrnW0so=Ew;nr?V5};8{GtPYNN;$OY7#`vD|B zRsR!uVrmY18orvdfhNKvzW_T;+c_aY+Y#0KPF%nEnUWA`F;3vDoU?McoJ)k6cYWO*nq;;s2 zRY^KFV_8y?G%bQ-2rh;XJxPOo@UlO(q<5Ijhl^ZEc?_DCN=k^+q^@#=UC~fkB(NC5 zegtWRq%w1y|CDMuN-5 zz@+R9&#^dFXgN$L0Dh^a$k4T^25kArCNK12=yPI|S)6#GNk_DidmL@`y0c2U&;2crH zS>w}C2}^1w$~@B9K{91{A7RR5$b<1%cXtIS!~rQtp#f%Dc#3mm36y$L4ocOX9VAnV z_YtO4YLWtkGm#NnD72I=T=_?oLnNh?QVWCc6N`-m-*s|YbRRRi zv`Qc#{4W6^5ER|*5Bdho-{e7u-0uI1Dve71#~K~u6v=;negnVm5ZSgPXHyjmup+TL z{0wOp*FMUny;-CW9^|(3BTy-MUr%4neFpp=>Ch{l%up8mVE2(Mr{qERLmABBJ&!#+ z5e0t`E9ySz{*Q&OtWz|5=-*lQ7>mko%nHW2fMFI4vC_Nmj=MeU@(lWFG0ul0Y){GM zaq&Uig@DTvyPB~d`eVVwvuTt*@y=&7ce6*1iT4I!S2u2JGH*d4=dt30!uQ9N=lxcv zi;(3;vo(jSIhOPenZTL`Zq$jHHRGIF^wpYKua*b7mMQl1yjkv$VpiDrO`jFhgPj#G zRhPgp=Rw?+DLAd?m2vZWXol2gyc#9?Z{s?~Wp%mCqQ$Y9Cc#UblYqWjli)eAm&+_Q zrZlTB4|u@PHm=ec`bC3f=)09wAaq=X-u89X%++$^#P6F?KcPfNE}fD0gbnD@nGah0 zmx-m{>tt#AYO(b5)X|kai!064%LO8^wT-WIwtjbBwstltPX?^X(5eWTqJ3pXH{dT= z(ewzx)z|t^ZW<~)Q2kakWB#IFTFm9K+|&7Yv=2Z2R*F{H41DzMBLWLCH5+c>SGm0#TAugi~krV*_1+i4o~+} zP${d2a^BfNvOk6Qk<*{@ba!V3{3#raWPxjXke|fSqR+z|88c}kBs?TsND|L}9VXkK zItQBI2D_WXm&vjGSI!QS$;SK0Nw#;oJ1amo4n{$;9Xb~ls}Yi|Q3WKmj5lFI{gZQO z355D|4nlq1*+DX)cpqUxWrzUyzPq~uq~d@SB-H>T0QTMDRPjDjwpK;$7?dRYnx(E3_%Bgupz2Ly~d73amo009kV zBtYOIfZb<+zyip{0|cIlCmA4+tS-xdffJphF#-rAYJu=egyc;PAUOBpW&$}PeZ4jv4t#@$FWY)X3 z*_>-r-z~osCTtl_ETi=a?{UptJ{Vx!gXy1K0dac-8V`)%C1eD`CGvp7;FP)Y0>;;Y zvDBL{w|T}OY&?1Mr7*#PN;R0+3!!(rP*cP+_EdvR9;cX}fIIiE~5a*WSKdRZn>`$M{#efg;NT-jXQgWmdeGR)`c03pLA~7p_c}Uq^myU-N_4m@G zWu)lav-5f+u;)zjhC)W}eVENbr&A>m0Yo2QMV*m*JNDaepMAnsHGbYwq&uW=7}ASS zgk?dLxhJ3!cXs(u?vjO~S|8?{5cnY(2jxtpO=Q*~u_BbA95!Yl6%8?JD}GSLnln(h zysBTHR~ja%QjpsCuT9z<(&2YnHR0MYmLjHTcAB$L9(~fwZb2QnaMW4uX43n8=%G*? z1!U#vR0m3CNV18Zc9!d1O4b3y zpnSVto2_=B^uqlz3vlqB^)5AD*4IQytw0SV`+%*D){o|lF(`(~DsEQ-Ql@;+i{%61 zV?gF;+TCC!!h$QXTBiYISz>Ifs#sj?*GjOkW#y;V8sO$rv8?=v@o7>VBz?7(m7l~d zD|=b=;mx9o(RS=5|L>!O8VPJkkiJ;{fJqj&5X!Mw9tOFi{28=P%BWF@S8V8Y`hQX@ zlt10mYk^o)xSTHi|LuJVoE%4WwCBPSwkdOf8%nw2m2Lb^;LPGL|!{!Ka4vYgN5FmjB z5@PcG->Z7n)ivEcJ<~fQLGaJ&?dk5SdiCnn|GiiBs!DW?K(n5SFSC8Jy;N(#@!)Y0 zN6Cg+o9%}q8AtQu!Inw*5};3MKvGvwI-MB|Q;boxBXo;5J&kYxHDCj}9CbztiyR?a zb1;GN-ibBEqqT+E$a{3WGgAMW?b5-0M*yEpy^jcLAj&SEdW-Uv3oFXM<;+W30<9M*g=@V; z8+jOjYt|uoi2nxxoq|tPu2LUR2Tj6VBd_a`#2)!l$mSbmkfGv>j z*B*5g)B*k@-8A7pfgdu55p>O;YW>yq+%!FFv4$g`nM8hns>st@N8}&SB7eki(l8-7 z;z&bha5>n!GgSKR45?ZA--2X;jz7v^gzE5S8sX0v-uf2)biu-#-|C24x&-U+=HI47 zJtic=3Bq98?j{C6^h}$KcVjGw25+WlLn05RFPoM6qdE1iQEg=QCrYoH=QZpyrcxG=m~xwpOZp-9g67G>IbZ=C_eqRyzL;*4Y{&+GW#2 zh<{+x2Gc_iA=XTDBZil7^;IRqKv4T>7`$sg#d>L#GRlsVuSjD@LTuCVNR+npz>Zlx zHsiMx@)PpcA0xVk9P)FVEmp}9J|R_I5kB9AK;(?@c^WFJB7C;tP9l7a@Jc|>Dw|d- zen&646_j?AkXLO0sB&cWkdojf(&08aq@RilVLYd`h#sw1s|gw zEG{l*lzj;VZr22YPoK7|SfB$e+uo*uy%D;$bL~flAB;B7?}r%@v2X_^!pSJ~=je?av76MCz2=RQ3i9FE$D^Dnmahw*T4J-);7RS8L03)rw>Z!fg z1`;I?NYPtcjxf`4P0ZGweOJ&l(86Q~fpRHLH6z%Fsd3FydxostB4NmA#O%qCt8C%v zFgKNC*}_u*CX~$qjF@+zWW9wa-Ki}+>2CN&%tmb?$Ts5}3KQMt3XSI=N^Zk^u(tc< zWHg5yCe4{Po(n%ODY|fr}r~b?Ir4JZqOWNN5IVfIZKZc5{uF1Zxs@3y~<<2BNpNh#k2$kV|O@ zSxMWNPjJnnYRT~q#0DZ^$Y=wdk|9@Z14$ncMH@DdndY6QKlx8Q#Vm5%Y)!F zZFog%00qYL8kIMh4^QaMTiIRRFN|tn%j-V0soiO#BA#w}z1XBZ9IV>`S+2a-aA2|K zO65uS%uiI-;uHesL;@M-A;Tr4-2X+Y#E{2s#0rTvWAY$QNM6?<&LNPS&!qC-iY$}` z^&Z@b1=TGmVnZbgA;qgs0b7KHVC)Ntn@PvUSi=D4?&6-!LHDM2s|i3%4_XIjLy2Vi z)=0Jg5RowM|AD4N05dAs4tB%OUE|+PDIf_*{ClPvsmTOqrPdZNTn#W0ES{Z1iz|n1 z-m?ktPhW}_`74yEaQ0Jl$2iM(8E{t9PG~YIJwl;LVs{9ZA#k8s^;+|oA+0<&z+NFN zo>(b?C0nH?4)er{t|@Q8y+Y#iO2l3z=V?&5$%eviB2A>iRtkXV21u+zOd?4EW%36` zv=}hIu0pG}$i^i>^7~)<}RKj6qb6 z^;+}y)6Pf7t65}4MzUom8te~%P~T^^B%_mjOWH0JJO4kZ35KlgWN~tW046R@4$17& zdVdeHb85Y-(OgRFJrj4L^^$wNXg^t;9A6u2EJ0WchJTs3oTLROEH!w&r3MAl5c+`w zKs&Rw>Qo8woC3q595D%^;-xJ%(8v8f zZ{p3W_4xHlbX+o4#2n&|MAjs)$}BbKuykl21w^;TViqpxH0WMdh?(@s$%0w1$?=tA z>G74Z6H}I2?4>AQ)fYqc;LIzK2$G(#)i}Mi{XBg4CXO{blDTNQ#E${3z#Esx$(meN z`n{CfELn?_aiHUasK2;Qg#)_&Bg&3wWXM$yD+x@9#gt02xI3cW!tOi3u+m3Cq;hvY zMtAJ)@LdLXM|%r{x;jtOzChXA=OHK+TDFL#>qQ!<>FMoECXX=1WtYR@*=##Jad}S| zNKEi~##8Dk7DMVcrvI_$^C;TMhLEV(rh7hLG--poM>EP6$Fc4c_Ts#o;W$6vH5}-} z`S~^yWp#cQJtM7olARw_MxV~l@#%#P;QS~ulJQ3z8ghQV!EA}jpN)m`Ejd4-^E836gjMcrUkufbKn;nK9RYf4 zYw@2t0^%+%luN@vIYc+8Ms@!JD8qIP9sJ~=%1fHECSM3N0O!Val2*QWmcK}D= zZ6H!P0uRz1I|6(+d`I8{F_39&r`O!_lTs{yN}p)z2m424@hU2M%_&Pn6_1^jRn5ER zlaI4GBfdiPp;3>FR3Agz*{~87<#gxZ!zS&hS(RrFIi%YE3{_yrhUJM7BaE9m(UJ^F z>#`&t0;xGI$*&^|Wl4SqcVbCKg+oloSYad3BU@3}1}o)*#K9z6(Hgydk~S47_Ksy& zhQ*yZGl7MipFvdO@RPlRDffQJO2Ze0{HitFxFQdvaHiuT2U%WfP z*u3)!9B)J!0*>)5C?J_CDFT*K51`Gty1imUl`XK`Vu7U+KdiWFTGTq(#P_KYZ{Y|4Rru6DpjJ_)GDLm4 zV?gD*EP#3r5zLS<=&1B18Uh-fHfgquh#IpfL`I*Y86`vND-R!}x+M0()U)hP7fl=k zs;9PE-wPDQWb#KJ-W?$LF>g9v}z)=V(TDDjZpgUCIZL(cWOH0 zcmi-0PT7r4akjm!)sLY}1+M>>?igJ8E(^FS+Vfbe7iuU_ z`mdL(Ur07nRR+mmdhg)_Qz5Mvh@N7Ds4%2!1Yl)^V*;AaQzMrQmVc+^Dqbkl!SYKc zZEz&8Fb_zERq?+`wQ`NmNANHwNS@T)gc=;5K;{CDPGbou#<#zKp^yxa`GRhfUSPP@ z0z++QQVd(4xR^5+BZ~g=Z48l1=})5Sj)Tb0>()ZmkJgDZ+MmKHK&0@me~4UzG8IIg zO?M2De3u0x743N-Qq0E8p%5vHZA>1?KslntHWnqla51vZ!K90^D`lyK`9{#O`-PE8 z2FS}&MKT>ApKQ{OYO#$~J%+GB7u$rC``f7!oS9!<6z<6e=1>rR(#oA+1s3qOX%Fr8 ze6YGW(~`Cago^U};ER*I?-+$jyh;{+-A| zjR$zR6J+id6anW%AryQT76PQUAjd3&rkgB$4j0>Sm@$nbCk&zXnaW7I-ypKa{TWSN zyfqMqzndwAGEsd~wM-_ea02)%{OKQmUxqRj{=S^<7=QUL3;rtF^Wg7AO%GctO!aX} z?|IS#CaDKZYMa2xBpHEchhnOxlF|!;*T&aj!bolR!k!bm*d}Nk^Tr4%!|`uuA&ZyL zbU6N1lQuXUe01#76^22o^5I@v?i*|2j+16}V0{~9)bE?h_7S`GUL;C0pCm|&0=nLv z@mmV$3OVn;i|87%I$0erlF5rVL;AY($!kGxPJQwyvQYZuaomYMi4k>CD5uBMZ!KIA zE`qnOCx&L2hQm4&h8bSJ2^}l(S+Z_IhLx#oJ`s&hdGZbxYE>KpW}j_gMw}NgMipE!ut(ln|$mGT&;I2fTfCBL4EmY zq=2D*4fvSs45mZ<876Ju4O?Yu_A#be_V&p!oZt#iSi#E2&_{|5ADxq^}jXYi*$j>OXH!L zGnz1OHbx5lHxlLJ{{PVx$gKWG33H(Dbs>X?zQyHx`r(B{D8G{ut&xrc;EUPf(*O1% zcRXVv^;ouG2MYk7z}dAC=5w%naie+3wMt0f;ov|;EL@ahCOIX{DAs&9s55rGVNc}$ zWM90{!Nq@yM9IO$^ww6h2rj-RW*f}Dt7l|-VX}kJxs)cuC=I+k11UbnHBUDJ^@$*V z!k?x${{;#UsQm>S=&TNDQaY>y3mlrBENpPMIkl8%g1Y>k(-`Tb>-PN)lb*DSl-@e+ zyS6v^Ve4i17@T%X>D@N}!c?bMu#dKRo`U40U25sDL-b8*E?Qo!Ki0@@wyhmgF*W8K zL}jMNZ(1uBgkBgdKMmv9hCTb5DD%^+tK0KTBuehD^ww$5T`~RjmYg*<^$3QMJ0!-f zM{kKajro$!!idDAW+~@D{BZ_3)a!Xkskok@x==yZ3b@Y^2 zIH8VvTH{Z|oPEMQ?$zlDeSyvsmGU_=C2d7EEB=HhKS9ax-B9f4sdwtP<^85QXe z^;vw+t-Clg9*@lvf{`m1gHQgqh;9tLYVt)JMIp-3cC-iI5rRe_{hvb458WwUbZu0_ zq_Rnz(jO6lYec?*Pd^z>=~;d8LL0fKBT=%EOK&3z{D^f*T}ng9a>w?>DLs{Io-Q!j zj6I1zJ={*|cBe7YN!RUrHIts?l+s(LeKYu(2CRY%9|I8FQhK+|Gnnf13ii=9N2XIc z>o7mPy1G4UsqIN`o%S4t+ZYPKFmi{)xb^5QG1Y!0CN)cON{`Qwt9D9Bsbq9Yf5@Mv zH@9|5MVE>hkWRIBO2zaEb=&|>>F=TH$|-$6-LX^3cf)r|*K3dN&|I&1)Uy)jQHzJ> za!jS_eK?hs2{L%ZFnJzzg&|nnPwR>4EbMyz6_{!F(5MuoyPlskX@km0W>cAou8X-c z!VIpkJ(X%tMuv`%{WM|B^&d^``tUEmj6_-e%fIDsE&np&orSbU9w#|%PYgosfA&pn za(}m-woowqM~SW>Pf_YK>ZErh$Mb}AbdaVLJG)$_z> zJi#7XB2Y0~E(y1waz3FOG&W-2o~zuU{l)N5y(!E~;%xA#T4QSe!DtUM@BX>xQTaVrn z^9trmItwEblbWS?1JB8jtME;4!pS7*podjo=!eR%_-*h2Igz#I4sh*aLdXX%c; z0lpi)H!x|8Ync}6u~SOy;wmv#@=sKq7qupYsEAeE9cp=kTMO|Nx?h<7#16wZz;C+~ zM}<1wVfdO!8@zNV4nvR4U%Hq+Dqmvp_B5s?oOb;qa4V}X@n8Jy0{IeW4npl}BGfJKCkxB67uumd9;a$# znF+c{TlVRvQ)aXFjcLEInHp^HuOp$s9;NBBb3WDvuE)O(ce2kz^F&7s5`g-vH1(q} z`}g$2DKYz>O^Mb>Pe6xTkg1}fnEkE3>Zc9J1`;Kk{q)w>J$cN2H?L$g60^U?v_n zlbWTN{nHt8)n-4zMMkrKSB6}**)J&Bm)S2`FGQ~a%>FNfNM-gvMt5xX^WE^x{&QPX zrCQI0RHw&G0C2(_ga7K-DpmY+iK5A6yqDyf%1>x#H$`pGeD=obC&6A{ zg+y5`;4%Kzve%DQp~u{!x+)gU>ZQ17G9eJ9`GP@cUZ?2DbR^$psRbmTN}KKX3 zu|k@?CRI(U;=EfSK#iGuzo}3 zEZ7vUAKuj$C$yFPAQC0}HuTn(Gg#A4-&PpBYDSRrWdjj&DNBY$@s!@eHI3R737*oM z`O|by>D9V($1kvx6)lnGw-)nEHybkrUdl6uy$rbJCkr=D7f9)BEL7WORgV&ia0{K= zc)C=VJ+XOXf&SkRyFgDga_XX=FE}ln&L1r_4>Ny~Tq}C(2+d1V7X6HjMWOH=5#&IK zT~75D;!iW@(;G=UZ%T+$vlQp;O&N04&Kn_TM&~WakgImyL}B#hyos(3fqVexZTtpt z-p-;scHa1I_|Dq}+_z(@*zAlda(W%TL#-J4$60Ir`RBN?A<*H1N1?{CTV3ww%x4H50mO>M-(e7;to&Wefj z3FUhICh`{7D~bf-fvE#q?4*_>CiJ2flbYW>9kCm3Wk)Q1Ix68j0u^nhz|Qz*3zwlm zKmVOnn{of`x>BO%q5$X^qr6_}h`>5f{?@QLh8}wM;eNOz9^D5i(HfEXpAe7kOMP)d z8|R-#qGXSb-r73&$nof0%97DeJi3Rurm3As=Dt47pZ>4#=#IHD+QRAl(L!?+5+w@_ zy>*1FSk-jgjdaHz9p4S#qr0%>wTq>)kHPTzRL^xeaT`TMGRWc6sm*#L zxlJ@M{?z1C=rdx7 zkfyhuM2Y{UL5P2~A}Eua_Zz7NB)fU449CseJh^#`ROuN05v|R;(hD2F%~NC~!=LTu zsdno9ExCDNm+@zb=poPWsr@LTsE|0*7t+=>(|0>)&F6jkk01->Za#`TaW@@o5`R-| zg%P3KayW%^;O8C0#4G`jJ8$*cYTl1PrJ&&+j~azioe=?l%LNpvrg;c;3tgY8Q}ODa zaXS|}TO-&0SE*)*@YEF)jU2`2IOlWpPz*A^Y}z3_X>iZ;79Dle&PJQ&TT7bxGhVyW zDC3Y;95)EI(;?f{={d});5iu1b1g>U74~@zBxueRs;#l9#wKhoT`x5;KUYB z)xDU@Jy>ni%p7*j#3W3i)u3q@{AhakX2z?Ry|OCa!*{9#p7y@v+R19G2#t@`ZC+W_ ze;ccE_5N+!Atvf0O+^(W7PYyecUPx+0F%gdd^@JAgK5A{3k8L=u;du>NwN~EHn!KB zZZs*q+Qt#2>rAossL?DF$qiu>^1u?jsb&>KS4$#tx*DTd+k>S2|{Av1d-|vK&h8T|B05CvWb*3{@DB~0f#=5;;`=IBk zb?QpN6JWLv!qS_?uG^iaHzq2b4n0QHMy0Bvd$2J#5O1ncZ&jgqq0mJ_CJWbk)1^+W zeR+Z0kBwukPPJVk^8?CT3l^iI>N2rHWcgxRhO8&1Ww=8<*JPAnP-=-B=reA~XYynJX!e2uffx{0_q8>`ZayXuWRNDXqQ)G#h;5U$=Bm;Xe zTF_Zxb0{l?y$0&PwOZpK+1~rTxt8?zq98@9fStI_0X6N;ERL8{X1-S<%%BGZ7_^r^ zWpc6J-x;P6fMJ`)n^s}AR3$uNyU8oSlAH2c&^Oa?SZW6-p&@f}Y|K!h%(^@jT+2tf z^-(%&dwWlit+^N~#zW3rj41gJl0;x;vma@qIax7|PDbK4>%_1*zHJ#jVhDZDdKSFg zG{)f+3B|^%#AFLzb|g?GZF^)86N<=(l!$zAP!Ty5BJzhwoHkAi>qe}W_w%O_t0j1m zX`jQ@g+o+45{OxSn289559vM_PPKR)Ox?kZ)*5dx#mtZh-(I#5Ltkk(dDiXsG zsgko0L;Fn`sFH9{{xmg9*=1f?0qLLW$wL_fl%dM>M0)a225>_yKfvVS2|Hx+@I<=f z$wR&y{^a5L?M9Idj$YgOof)&5PbbYWVR$V$wv$3aX>YSy-shFKZZFkZ6p&t@s&y~` zT7kkEMVCHxxXz>vriVOrXe#5z ze_lEmzqExE9;Ue}nvZ@TPRlKq_o6Vv2T_J@Gfe4YMsX_=VdNmwq}-{ZFe}}N|Uq(a^dHP!| z92EtSIPo1))iv?G7F6b(`2H5MP!r$(fjgP_Hab{G)DSkNZcuaIx-E$8R_adX$PC-1%Y1ouLOipG-W- zIyWOT9w$(uH6r*>+6yw{@#kV)(0s?$4b1pqat(7Fm>!^+zHnaMJJj|tu#G7?G6yjb zUd2$Bngo3J$ z;5_H1H;o~5%spb2EGF>FbWq`R71P-hY;;Z*Cd`n!N*Oz79-2y8XN3=pgt9R@*;k9` zA@d86D0$X}-r9|fq4huh@n*1L*^hfg(B0kENmfAOAg|}vPQ@)5(>aenjg0B2(ZO(7 zWzXptCX{}_9u{@LoAgoURu@BGoUYc;r+9=JbMBaNnxP(oSx8Bbo3TcxO>_3)==Ee_ zJI0W`L!}uSWWHm)SNEFx=GNb-rr34Tf;^_&G21>?I)L8DQ&Z@h5i;0Moh)2Ehc3&L zS$r-K&FRz7w@loR2~CrQ-3^-8Cl@mMB`GmF>+I?O$`D?3KC?$6Fs zBca@>_c%Q;z3p_T-py^7G!I5^qn&!s@o2~)w%cR(zFxK5WB0znX*>JXk=1^t9ri36 zE_XzH9nQ$(Ba1759anyO!_LpJJf@4Tp7YB9JHZch|5ScWtkMs4K9BNfCC}C%4k$HS zSD2noTAV|B7=h65DFTUNbohYb<^dIcgxw3E!`1YeHXHU_bUV%>HfDru1`iZN1~5Qi z1Rz?DC(;oCr=xzF-b~{Ftb%r9Y`^Eta>*g+6(JKmw>BIPsnzTbdw#TZF8p!ueWk3GH_1ntT(q8DMsr8o^CU#wZ@l&3%v2gw6 zTQ0tAW8rG`XB$1-u(7cI`XGQulAC|n;l)Tj``RHe*NlUP3 zcHS-9Uqnev@tNv(Qfeuc)cUOsenR9S+T_%Fb~jB%TA2i?g6Uxg^}j_KaMuZw`d`4q zeB+ye3q@+Ib2C~{#yTzN(W9OI7Q808oPrJz!a(j{>q^G%A5nP{#VfDHmfz>%Uv&F# zU#k|$z{=KDdK1Co*}3^(g@NgL&(6$0eJRw*HqfWE%hhzp+J*0iuU*dDefurf_0}wL z+rx6o99l(f2&r>%G|H0jG5OZ&S5!pr0IO^f?MIW`X3`FQCsbr*dr41F6ybCYQFMi7qcM#IL)99E>m7uX(hp$QP4)T!Y#)ix6Bgr77HED^Y8n12 zyiUSqRZ=ArHoq#hm;`Lr1*{JG=WuJ5UBf$z~6&-CGaN%0seLqZAlY6 zS>R7H0Q^a|1Hs=zAVk66AJHAdAKwih{w|>Inbo{LJJKL(`Mi}r2NbG<^&)vWfOxF? z60jI~78Trwb=!)k)DJj*%A^haAxFzZD&;`rp8XJX*xJ?R)fyU8EaWYlH*bKoy`8XA zea6T;V+->0+3&$a6CePthXSEZUf-!uPyfX^%(Vmi^U~~bie=4Kw|Bg;ZqbNts(7$>P@y-7-W#FpkPvT)tFQpsLm69$% z*hEQ3&|6gXT6`d?T8M+H{!3lafjt$;0IFKD9Y|Gg0ewnUUrcwbs`+mCs(M|i)~>c` zdN6JnOwT>eVH9jUMomlFL>(RM8?vekDL8v4#zl%^W2>3oiAq@>1S>hrHvFC~fpGlk zDR*3PZX5HVmlxJcrPp7%v2cYMW@*i0?C0`=`Kqw~$}8c*ayF}j<&wx5YPkvRY4@dU z=(*cTl?gqmC|CMyr`WcoZ!iUnvW0eFh}at6Tpno*SYF|SC?Hi0wQ+heeRMOdsb8UN zTv)mq4|BqjBUuWQ?m@nSNnyPNkY0?p0!Ts@0O>lSFwu7imkw>aUT<+C9F*xnvs;C% zpS|#Dn+p@2*$uqIz$W@p#)^KuYdKiH06Ceq@_&xVANOCbYY}fH+agIUpmkl>QVO&T z65nT7;0S&ESdnlHnFt@L^cYm zjK=Sw6bg<1#Z)gfnT*^EH-N^%BUkXVpz*Ss1&x=}9iuVdWkF*_eI7L4DD6;e(yUr9 zI9?lP80(f)IV9up%&^U4hmKx=to8_x)?eGWLpPPrL0k84DqrBFa^y4~k*O$GFq07Z zY*Rom^44+;=2bBb159=w8wg-feukmHe^3tV?q5mSxS)JG9_9q)Scy}pd@FJnRCenq zu)G`J2rLVU0KIXdHUlg_i}1B1$0~`@yqT@#Exi2$#ndrWD=g4}Ee+A4D1G{b0s{K#ab?c&cK#s6^-a#l-web{n6#yjGoeoW$IM6Zkp(XmxaFECe=`WDTjv8-RM z1x%zfn`Ql4CzT_d@iw9QljKP%6q5xFihyo*^q3QOh_M@G&H2(!JFW(|H**PfcY( z`cQFLJO32Q#s$r9q4qgJ(~=~Gmm5%!;H9dMK;;E^BTy;i0Gj?)H$nWIRX9X^hKwAz z;|#`1P5Hv`)W3unfs?K14*)trvSI-7J4B}f#7UjF*IrCI{7-5KK$LpB@|gt?Z$POE z5O1VA21LHg0*H$GJb-w9>2B<3i4E#{n3-{V%IKuYusG~h*@l2#$fy?Qo6koBj#G{> zW&_9lPO41cNJY8AmjsSQQ^3%-!!ZnJh_cMfW#)}CF3oS#qZuXdHKg`$T87p1f0nXw zQSx>?%!!gwsZu~Wk8A}fO|1kgUyGN5l|mFy>v=?9l38i*k9dgzOWkR;n=jL88?nw; z?MJJI1}?dDvw_ip(wgS*f1PL?_ur^V%?_}4PznXGZ!q-?mo^9YTwgta4RmkcR5}E^ z7#m3JY&6>y99dl0Dz}&p+*-J<)M{@mAaDuyw_^P=KDqd*^y4d%AW}pT39d9Xshs6G@6hF1p1t= zXfNyk8ET;98t%6kq6T>L;U-ulexTawlxo$xdBIqV_H{99B(POXxk_6r8~Dzhk7+0W zG}H(+IF(R0(&O0`CWQvtHwjMa#T$ zdSk(BPfdnlfD41o2wVz$3+B2GDwE{VMhcyWb{IL6{F=O z8V$g|SIe0QX*PiWBPW$3qxZ%}1X5A1P$mKVyG;Q@j|g??j1yHRva(E_*T0; z(orMfPLFyfleb%Hb!KNVbb~Mzh23fPI^+0)Wop{e{}-y%xc?1ZH|Zjdutx!z=SAO6 zDHM)>-7qFKnc%qa5jZZ~b-PR!9ACUkaQtYxV;twZEI6*H&x7OV>BFmfjGdejW3a1~ z$;j;u*+`f2dqMWGY-h;VqrvJmXiM9R%!bwHJEs}+PsYQXupE&ng~vOQtKhNJNr3ofyb~Z6k^ok# ziMk{pwnzUjSA!+BQh9D~XJ1hU{R_7=s`WO;xCxpm#!qoptm|nz;xA7YrfK{=L@|ye z(}ZV7*;6TnLfKnQtu3EndS~r8`gJE&CcQ;PxdNG_w_alk2u9pej`ljPt5KlCq7O}{XHE7#LwWz2EUdNvUdqPR zWC0%L)MPP|ru5k-khkcwX#GU1{TaRxttR9Fr5+$kvuL#));LkAfGyw&+C`P=V|2OG z(}~lV_eIS6Tw$t$BZH@CpX(-Of1BzM#+I25SkOF8L;9bgI*t3E(pAf@_kMv=D82WW zhA)=h+j1kHTuozT`b=(_%Eq3yrJ4lqha20QnhuaMtk2)8`uy#n^&xE()+duT60v|b z5@B&We->@@J&>%l(ZACjYa_nPqK#B*UFJI#o7}bDEPXlg6Qd(kfRWQ_(8AMxsu(;gzTpAqX(DoM=l@Cl->P zqkJS2dC$y?kGjwDso}H#Od??1zd_R>V(JK7%*fI*N};g-I#Y?%WHPcObp}=nCtR`3 zf|W&-s<83}bjMi9cUiDfQJ)7Z&!6tpYQ<`~m(d;`g)a#+510am9$;!1?xN;0^9D@;+%&&Uk7ne2oguY< zg)0GN7wG~bl zH%9UG>E+rMw>=+Te;Q+z=FP@5lK+09eB6JZu7F6oBeOBE+oTipfw?5JGLh8m6{-O3Q|wX&TBR? z7C3`r-%I;&Vg>@M_94iYLaUkxvBmpRYYwkVbv~49x{3+;`aT@daR32V<$`Kxb@V(k zn`xB2T5GZZ9|c2cO&lad=WRq-1=eAQZ|oMaaja2CfGrKVh1`?Ve&DOMJ579LxcTEq zdf1|$Q7!tZL0fc5q(w8iPtuWL5=i%UQ8|lA@KunkOoFe`9h(Gvm&GJdJu8n%uujHk zd)WkWp}LYb*(exxsBTC>FRMTWREFP=#w=L0TcN#xWj3>5g_FvG*m$#migE=o$t-xn z^pl~7>V_P5?SkduD`gmj4@}2q%i!!(cBC)R3v24Hp=?~s;QQc2PRqcNEM*#8jKah; z2;gFb#2?==?T+MG)RrvCv6@yJwC_@2QXq7kMsbKVarm; zTzQxV@~ADA^F=#I$7SOxz{l~q>3Q*~l&hZe3zY&jE9Qa4g+reuugpgUz6F1DclRn<^!!S`1Q-RS+?Ov#scas(PV{Poa~;mEicn&Z$v`ho$V0r_WS8 zyb;9_G|-T@t1pU*s&>&90m1w|C;b=r9ec3P7y!?agJ~cC{X{MtUQKm&)z+jG zO11s2sj?&PQH?0$jKU#uDs(2U^k;$LPa>^?;lH3ehGD+T0>g^>JTQDA^?+7qZ*dy- zNUN7;5f_OZ$siewhaHLRkkJc|Rcxq}Xf%-gk6O+|NV7rmzc{HJ8I6ZzD#{hgBuM_U zDPZW4$PU{X46V7FmCk$RayU;--)C%I{A>kR!qX^s(*2IG;{GDa#>M8p0b_DvbDXp( zcwUVX1)iN63PPWTPXwWbKw#b9>Gq2CKrDpTql%djdYf!fN=s0#rCCn{(|NNo?d2DU z$>aXn^rtU3-i zg9Dh%Vd`X*9=0)N)6ff|l|f^t7!5w(;s|CoeBR@viXu?LktkG@D~L(>e3L0)=q9tx za~GV)?3W6e?MJ4YGc3;-n)^4I!}|I)%EpD|?Rc0Imb)ZOVe(6mvtY7aHv#1P@Lm8} zNCTkVNK_`7%=VBFhZ6%}X^mg0K*v(J0bHGW^{$R5gF_+54I1ak!ZeZp^F;Buf4?R? zUU}N`NVTRN{coTY3W;A~YHjJ9kEzL(GKPAp(^ZZ)n<-T>Z-P~fEkqxq-fB2V4}W29 z1iLAfFrBm!pUhV2F9MOrF!NHS)$Dv0Ip$8Lr!kX4!$&;(1asBfH;Knni2tgVr#BXw zrSgW!!nRhS)tSOhCluK{CP#PB1Prf|$GlF{CvFUq##6%ZLQ_V(;yp(6r)Qw^F zPefh9Hh+U^^Vbd9<}_dxwt1!jE9n>z9O*7D=w;Eq?*_?A`@VERB38%&k;weQkNY=r__LLkldZ}S$yE=(Rqly3A5z=g$_%lwbOq!UAa)r`H zKKm4hkDCI9?kPEJca`x<=e_onqEAiVXO;X_Lwx@#Ijp$t>4@R$@DIMyC%&TK&6Ob$!kM|CF8i5P%g~H2u{(wIn4fa0S5x#8L zdxewAk-hj)Dk{nqwj}J`YzhcQ(=N`8!O_wLm@43V(`y-Bf5wp4Ke~oh^KYSSTy(tv z4|AexC`AfWJ!C1E%C!+BoyH46QXvLNx{2t@fTY)|Spj#6C3uHjQ)gt2rCE}=w{a+3 zj3{o8!PJGx%(Ro=ph}GUGrBI>y`GJfLZPc~7~x2GJh}?sfUd$#SKzat>&sB8Lf4nm z9iuDXWkFX(eLi%>jC_xQr&x5Y)(<1PQsEiVl|CH}y8eci9}&K6==xSCl_Puc=t@Po z!j^=tziJ8?KDu(dbfK$m0!CNdn_kQ4`awfp|L7W4&Hn&pM^vLQ$zw{dqZA5V zKW7+`noMS5g>OJt;ifC_S~Bcj%7MmG82ktD-&+x}I03L9JRZfQ{QrM5Ro| z*kSKhA?5diS+(*Cktl__Pe-nTx>6?r-Yf7X1$C{@Aj9dyTV%XeAe zR#Be^ZZ~34d>`YvamPSLb4Z5YVIM5$($Ncs)uDWDs?or4N6VTBYBo5&$4TYLX*?WL zQLbPn!SP+DfT14)>GIu$DqiBd{$b0`%%cZ3fs@;q%V8uI6&qf!$nrn6~nNmq;G>->oT^Uf{@c z3|!Ap3I*5iFx5^?CU7lW0$dC4++L9du0M`a6m_KTr!I z(~fk;fa@1E|B-mLPMk5YPL+--Q66LDSXQlR@HWGptWRWrfe zd+=ItR|o?XT}w1(FmL%ha>iZLi}e9#GypMKP_cORsal8PmgvKpSKo*2De#qAY>80| zdd!~-94~OLrWO5HP_@SWm+9JNN9k)Q1=#reaL2J8i0@q*1dx2{q4Vd&EqA~+qUr%PTj(ZL{jR0mwXj(nF zt5mL*>Qmmv!gY18xo?ga%40tvm}g-EGnl+!`I)x!|COpT?tfd?NP2=J(^0JDIlOmM z3I);MH0(%CCJ-&$14Ii?-JX#JqLOdjRv~cqRnm3FB^1ka8fz)8V}u6lq;Y~(7nbK z5FCaUb3!amh;1CiTXerLfWTmWrKv^#U>z%FD02G1mlGXVQG74$|uAl%r6H-k&x(u8*0rpsbWZKSu9+5xpKUdcx zJD8tADHNFBW?0~Kj;Ib0Fc*#i%!Q9`U&#XIccD~eZ#U_V!JO~1fVrZ6LBRZg*KAia ztd36ubIIfIgLz0ve_$S_8x5ETTINJxvw``%lgg3Tcrd4;Tmel2^H-VzMh4~~=NUJx z5DtT7;U{YRr2B;d1P1d5O)dHd^N<7n+bA0s%(d3vAGb zoY_Es8KqE|{!zmTYYEJk!kxTY4ICL_RU2zzaLzEc^YUn&W}yXtMJ=B+-*{M_i7=Q0 zUTtoyje`ad$xR0j(5H0Vj5*5EoIB$oSO&X&(H!h7yq$wsYeW7|wSKVFEYlJj>;g7M zdC=$-^IVT+X*XyNDI1+y*&KjO8_!^$&O>yf8s&s6#F;Yw(ob>~Lkanul8}c7l@MCy z8A?c|WuDTtp!KE0xuBXw>;E%IR$BiXbjMns@3LrpCEt0p{(0Hfcg9ULtCYzae%KSu zQhqPJuBHX$>(OZQCC^p3D^Qh9o3C_IIRF>0&8a9?@RGFoB2&Q7Cz^%dt`1)+FO=q% zpQbCbzCOp$*}uLH>*%kgY+QZ)Lv*v8`Z^*}N=sjgqC`teokTZ374Jkh3rWD6A8D}a zHPO7C9W5uGM{yD7A*=P87n1HFuWEyte@hpl_`pi3##Z5$;#K{mm z?1^ZLgkC7DrV6bDqXFVsM<}xa@gXObBg*kWOhvgum;}T%Q^3$CqAixYSiHh|r{LIn zV){2D@~aKO{UdT%SwEm`TtuG6!<>lhN|yrV-$cd&%2v$;mwyYd1($^|;8>MtO!Ap5 z=V7xN05hk^guC{dAubA#r(Id1`y2P4(6ojB4kB*ce^Aqy9cwF;LSgM&Oa&dejzY8y zZwWtuwZbJ=%(GzapP*EQwI887##+A1g0+hJJXlNWut&7dsWGz??M5QHs*X@8Zg|Q3 zJ@XTlCFm!NX=Qm3EaT|`%3?HN_a)u1A{E)d?lC8oBNXvqM@6|(kOX$0Hw6TxAy45D zuU(W|tQ!D>{&Z{l664zU4Q>77T39dtKPVd)*FJ-XIdRQMkOH)0?+5{n>LN&X9G(l3 z2`NB{hjry*Elhj#hXd9N2b)!jiF5Y&h<#_6=%0$BQPj!wryt{QRH6XdPSCVPHgSLE zvs*NtLtAlqI5LvQUrJLL_HGq!Q+$}JA!w6egZW}Yh6vNu?6lsN%M7(FWR@X=&r=LO zr(Xv9YbnLqJ7{PlmIF(lO$WbRE^!U=Gc5UHRr2OROQxes!jk<*RvmSefyNyiebsJE zVk5H&y5CUPbS3R-ruT-M9Fq^Q$r*qNMR=2Gz)5;DGLb&+B5)Qxd>aT*dUy}r zu^#5T40>3ryh&+BrSd9IBK@}(M`)dkf0hvuEThA;DR$;geDK`hoc7#o&vThii_^kL zm#Bw>sbMP>F1?q7vqC9*{&qC#zDc5FVQw~cf47q=le(v(Tw$|Y+TJg$ZVDJx%Q$oX z$B>u_D5xLN-u!@}uz#f=*3SP0%Endt6+FzT^estJYX8m1Q~VfJA5r|jjW?qBg&ZKu zexfYNg|QVsZ*werb3(7Fts&_QlHK4T%>1njhbiNr zXoRa_i&C%Nq6N-4^Q~Fk+i4>P6~B0cO=bwJ0!-3WaXO1PUFy`@1ssaj@xqXX5tSD5 z?E{K$4-LvUvJyhRWzt6?WMICCo(mCK^wFn5veHMNp*z+`e3wBV=~mC<7fujZ6sHX)6h#xsUT20#b|WZHypvtrmMc|q;g;&-ZiD7TtQ6IRbMj& z3_Z-)=DF*lj@d8KAaGUfN2Z&zExP=93f$wdF@5v@u)h8>%Er}RUj{#NYOgK{Q#$M{ z6el{&uA6AGHFz(YOh^MJJ+2!l)`hj;eTy25yN3HQ&>3_0y!$bnwFA{whjvvi(Uujh z!d{#_i7sz+*8nL^d-&^!iR1ox^vANq9660qS6`ueDRs40Cr%`86t~AFLJ(}Cj}wEN2GVooVVceVC8BxUe?XHSuWxPf6<=g0 zrBL7=n0i~v>JNC0qVYT$d%ZceQn6J+5L&ZCCqn8I0}M8rui=egr{;qtBw?Pk#$q_K zX{LcdK1%Eznk=X_ktPQximWS$Y)q}gxuw==6)q~=JnPkOZFkDmhT-pzE&XBJ{)TGX zUmLV-$zKZFHj}?3T>y$(I);mdSrqs0fn=q)-%od}xcM%N;#QKGM{%#G^TCVdQoGd4 zU5blYFo~0u^sr+VEE0ODW;Ls9B^ZrD{*)t>*%a~@oK%?h=KX$bCL<%X5@zd_l!D)-}fm{aAt(xnvbQFn%l)~cDP z*F|_O>Qx8>6#bd5YOI@N5BTjMKgk;Kn7d}=pu9JFI`EL5l%Fhu}3j{GT8NcSx~3B>Lu%_Cw= zvD5U(SfTwB&1paEm#S=KGjM!;5o`5l-g@&+b?i^8jZxR>TBAgV|I~4zQ2mYEZX0B* z`zNnrp){PXq+#`-(m)D3l!i`A&~h0S+a6t7v($?y<`|$hGDC-*>fy}0?Z*fv(Qr1+ID}YJL`dU*! zFv1pcT;}DG#(^2Xo_qJLV1BGm#Z+@-Ynshe4Y#ZlcSQk0g@97WgIA0uKz@ z0;C7S7RaOrMQEW1MU-6_%AyC~0+N*;d@J3t9^|_$dQiy^^k5c>D=$z6VXF)IWVGDEmD_==%+!e3wROCm5r#;;w-X-*;jVI!qo6s(%+z}~F4 zi~9M_;5d0wtJb~woxyV0x-=o)nh#DaH?Rn?T5CaEur|J zx%uFv=|-cCKI>U8cPt84wqPgMJ2S;Y6lyn*C#zrvS7$L@J2Qi%Eo3>ao_IBnpA>1q zYLS~3VMi!YC!kn9esCP11j{8c^MHk$^E(y?W0g|P{9F>8=pCwpS2&%s(~^&t1WU@^ z-p)Scw+d@D>);i>XnLg?JXyhOKdDmluMAdI>$9D9(W_52Xl>_wu%gqR-gMcfRu%VW zMPC-ZW)lZ2RsdNwuL(XAsZ;Iw;CSF$G?yiu%Y3lLdE;c^KMr{fR;heL8kRhJ_x4Sf zq5S9zCvk8B)u9DORluSegmFGtSu54|br2;8j+gO!u~(lDPKNga9aAi0ZEPK9o=#DK z*Un%m4m+JjHNlZ;xd^zPuF@%E!KzZH-6)2Sg2hz`)yi^bX0~Vq4~*pp@NB#${87sA zczy!z)?3v4;iK7>*C{uOhh|8mPN3zlEw5;&WGR`##8S0YRU&$Pv0QDH_SUE(n#yI; zAu1b#<4~Cvx&XUk$aJOttTpELY|)&fO0*nDPxh8jG|6^wdZpc-ZC!rR zMR?qrRN;S_IiPr~fiN%rK4 zlf>=Ecz4xnPjeaQwHH;|Gc^>pqFvgHPEc-F=65U))b0wF@K52u{g9rS3!e{DZcT9e&>TMw;fKyUPFc#8=T$ualS@#`Pt)ZBQqdRDWzjNR zmeJ*2y1bk&w=KuzPP%-aE`LLpH?6?scj)rGF5S zcwCmzrE&r;Gj#d+lW_S(x}0|^E*t3b{L^rmqRXz+ak-5yzkMby57Om7&cfw~boraJ zarpz<$qDyf-E*@PTqRWTq^6L}0yqPZ-;O=d7 zdEJG$ypb-eHsNwIUB0^+mmkpOsZYV>3c4J1DK1Os@U2eY-m*>-E z?G9Yl(d7#_;qoY5c0CK1+vxI1x_pW*SMS8-2D-e9F7Knu={MtYHeFsym;34RExLS< zF1O!;OOY<0rOOxTvh`GA|W z+fC2t@;7w(GF`Sm8y7nL-KXjv+#(nas{cCaQ1S@Uj!r-)WstOfF=mx-2Psjw2 z?-UB!Ptlgc2c5X92473R1#RKG)JU5RjV2&20eX6%YXtaE17zNNuSEf092E3c-Pbl&GkpwdV)=c#(+xZz6Nek!!; zk>h*1xjkV|+EX9yR_tj$5jl}-r7rOwuzk>SM^lvoqRH$!7AV7I-b>C?bJ*@V@6Tn)H)GnPBY!< zG(wuyRNXbh5QR9N@XVGx+TG~1larcRUk|J%)#>o5$XugKU3kOxigR(>LSgLl_11)uDgFnr)F>C6OPxg&ZRggnQLDU z^6eYIv77M!X8b>h|A%NQ;6~tx2~_y5w&?_2{)3XmKWZpy^k87KytdqX$(~$|x@O0| z)m~1`(Hw1#s@o$<+$-(P<1}#)>8%-lvw$Z1ItUA@Fb&z7Yk}FeQ}gG0?uFtQ4?=Uo z6{$3f*|J1E&VcSyQZ}oiQ?oDMXqrD}AFxk?^V`*QLB)z(6H2N3w$Ji?GQ{Md)4X!Z z2~PVRuVDt8Mn!0u;ds4sKGfw06sxpwR#J_-h0>6-f|~5YTCS(Kq?X_|ELdErh7Qy< z>I9j!IG5_ba!By9g1#0+3)A!b$jq&5e%l96+!SGf9ybn($s9a+*f^m^sD^Eb=D4A& z7za23Z77qs3Mzdeb1nC{m=6H39ay0ioVB{t)$z->?P z{k=-0m{xQt%f(;p&&3Mg0~J~ZBgBY&jtCI)6z5i&!S*NZr-)IXN*HBxT2_MeX+e6P z?ma10R0Lb4)G zcs>Y_r?F{7X0T>OUH(H=iM9#sYh1*}gNjb0YhU1#I08m?`Mw@;3Kjf9LbpVKlp=q~ zq%8qk8@SNrGsFwO#;`|sGeY8%@wQtuhFYrjB;VcaxUS$J=$ffUe!U7*j>4|}l6~Qc zE;d~%iYt)R>i|(9ZP55Ai7BP9b>EB9mWD#rihZ|&S$^cSiH-QUaUA=EP_W~V{%j8y zR;siK&>rxphL@?hVFC?Y7lD>n(kcU>nQdEM11McR2WF?l$txp`jBRSlbs{S;-Bc&` zKL~4P5$sWfCS*Zjmh5k)$;l!XwrxQZ-_hPA@Y!6Jz?qRBvHCUi^LH?7`lFaqB>Q<7 zb)-`*)A73Y8+;09WPCyEWaoSjO008j*Qq;E_q?dEVFn%!ry+@0S?rgH9w`@6)U<9d zl}Jfw?bl!-ZHe_DHt<)<;GMXK-JZV*_zju;b-XMRrN5h0*=YKKVLE|PlLiBfIHO{& zn=8gyCx|+xYtYJbXiE+c88s`~uq@Ab!1r5;A#~{-X`p5Mwr|^JFR=ys5%%qnHq@KU z)v+u#`vd&ggZ}%3QCc}#e9BbHH~>lkBMMohX!>s{Mlf zVwOLDRF4q}R1yW)Gr6p0RFH0{cYQ{>#3Ck2hFNC&Y4?NS52|Unzwc zV3JTTUrsf(59ki_pjnZd(4^G(ya^HSC#*>mnu3`jwiLETr^56~olkkbbY;);+4zt= z)lFDiJ)LWnGc_JBa;(Hqc|9uf z58z0#U(f^a;L3waFY_g&BuKhT%LFJYPqGMlK@(iG8HXE~6O^C5s?e}t(D+x(YYj`e-+r-{w(WNY0&F#oCHp`-l{p&i*f*gbqvG|XeNl`AGw=ik6vs~xBGd2+krlf!{6EDih$u?VyxW4H2|JaOpZ#^k z{!zmu-%t(NPf(vyXZl4)*lKRvyxRW9FtHJKAF*`w@CbVZ?M8`^u$>T+6z48FB2lsl z9PwddB5aC8jKu|M6Ti#Ai4=t57F&u&pz9>)itU0VXt7rZEt<4BB|(VZ3mO$zNIfmF zkHj6SjWH|WG#-B+OnKZ*`&Q+a7e^EXd?vAk-kU-zqDIOAPWv2MCW?i2Ng!cwwkN%% zCx&klF^Jb@QlNz=LI|HOm0Y<2{L8xSn;Jr3XRzWF9`RAb1<54X1)5LZisvXCaaWK# z!bLux6%)k@zKGs#AKF4l@anQV{r7>rqdWZ%bG9hUS(MkB$(`xX3%V-W_RLIvN7^?>g)RJSlNyA@%8XXDW|#$ARm z!0%F@1Hu5mmm4>`)+_dKVSvw|mvO=XUqHLj!vI2@A`C#H94`z&{4RqlQjjfrd?B;Y z0Rzy*UjubL!GLRZFd)D-78<74FzRwMO9BJsl{99si!{O#dnq1Bsa;n5Y5e}aVaT|l zf&mX7q@<7p3<@4TNY(2XHc--2Of3r=EEe^rO@lFl2j41{XnFA9Uv%5IaPT0R1p6+{ zC+{D81BD~*C2}9Z;|4{-q7cITF5p;Zcg_bA`pH>sM2b|b$=72kjNwP9rZCP`hk1}2 z98NGW8RkqRmlJVubJSrl3rWo_>5?F+l<76cfM zgYTo8?Wc3Ca#&s*V4$J$Dw2l%bb#RwJ-}8xNzlvuyoo$8%EQ5l_=A>?qw!=~#Fh&3$shDNE? zxIu!XZ z7FI|m&;FRY>A_4%uk;Fci4*M3|b2U2?-fJfrMw#Vnoyy zfdm=}cHXz~!{}H966ipIvSKzs`8TOBUS@A5qInRunRhZ zuz@Wi2^#d2Ye--RNvuok=2GdVk@(G@@3;Yica}d(KvcLz_N)!aJ(HWOp zYToxBr%Y zPZ5YUm-6=u9`+JqD0qfolodCf>SSv?{BA64jR!+LLhu{8R@pt)F81(gsJu3$0XyyC z|B@bnQ(lD;5-lh=)Gyl(PC~Gf;(Cvns-NfR^OC^lHKoNia+#T$%#wYMy2+!$Qz#r0 z71EmYGJ63XDMUy)^Dm-U0e~U^0PrcIrO<91=*+98007ltUgX0#^RIvc2?4Ltk$?bk zG&BSZcIK6J3{sWN+=tZu&ip@WI$zUtilZ_*FM~7xF1%r0r5CQM&A@L}JwIrf@U)Ez z@=eIscYB{OEPjQtsH1WH{WC?KRU~oMvv@7t4-OjvZW-aldSuMF>yD#`jV3)#8lNA# z{iw=JahV+0??EbMzCf7+`@gy^KYQgNsEBpyA%Vo;y1KZU^oWWtY71I8)pL{O3@Jma zgduE}x)ErVeZF#eBw@#|^Q%N4`X$fw3!ZbC9%Z_SZ89YVB|4GW2vRSE7S&(mxza38 z4wmwSZ})m~im;oh$r8H(KV?p0yrZ$}W%VUdof-Jip3q!oJxGqQThcXVk{WXQi#%PF zoy*-cQeWqn-G~I_(nM|uhO{SiRAL&_{$u&+jqbGk-=#}qggW^Z3xl4JG0?5{c%*7k7QpCBT#U(A)w;th% z27Og((BF)zLF_Bk;=22HW~DjJXPS=XHmbQC7+A6*RDcYO;(BVcPATQ0v-q=oNEJtH`*;o~BQj8pi2{p7HmOKa)#{C$6R;3iXyp zo2r)cs10M<(xdm^KP5mev3W6@T*xSu){-o+Svm1(QI*Z%N6A&{baF4@kz27HryvP( zK4o~FRt;FA@+L{R`;nsrZ35x+{zC4v*lv*L&G{%&mYMEM+ciDfd0cuvgKzA(A|Xk!51%YR(Yig)0VzLIM=0Zo;G_#ET4y*`Gzu5tO-ce@JE; zcR(l5@th(PqYS#v+s%?rXoqFGU9yoOmXjwUCgb~It zgT|p)ui0XXr5S%h!9c>&oXLHPL^JG;s5JO4A;^9jOjpxg+KZ1IfK=a>W0@TFqJ5iJ zgLQt1<#lW@P8}CId)aX6HfVI(Rw@E2;09sAu{%eCDzoOFwFW_z7`h0nXs`n4DFCau zi%Uc+c!8G)R~hFx#;Z)3UK+w~SQh{b<=d@;1kY z+_0BeUf%|TS7TK0D(#X@k-{&rT|@M`LslijKYu?Z=Pt8mD3@sqXkD(pW~ zWqe9T4797F&$Uj8^?rc}7}`LI{gmgZQQA*oJ5iD)CowwtRU$FDh+2^KheW}a_E`(B zX%hQ1U1DDxg=|C`me}XfqAdJOhIA|qn%+p#C|8HqrQlSoLEStqZ6wkRsL)WtYNUD0 zHdFTpn;lPnY#@`gNG2NiTTDmZAN(2}iTi`%Xt?`s$$%C6MDp>0WeP=+Oqb&nxR!eN zIH{u(wyRGWm?|4Txi>S&__|Z-o_!cDJo5VY-);0~3+%(xb~~T1cLMsrK~;awU{;mL z&l>RE@LnRkGmLLJ?4u7Lh>tVChoMxUCBpNr zb=Gpb_wV2{wuw-Fd^*ARS?3(^3W@7GVNyELu;9?6zj;b&Oi7>7uVuDSG93jFFiooa zB%gP@b|ju z5WOJ7f9^`I3pT$S(cF32Z$iVw`yae_`A+1h$X>`b=6h)lAsA(YMK0#l<#TXa*E;5! z1&&h^^Bwqv2fvEE!k|%YSd;)8!_c=PR{116*d{WDgCkC(iahU4=N#_&@_Dlp`PHO| z??8%j+-vK!+EuN1V5}%`pmTv|y42xsGMhSW#1qfmM6Nj#@4Tn~uyH7C|GjyZ7(r z2cS}|s$N}s0`a#I&hte<7j_$pBKRIOm$=k`D(}HJT=XfH-abMLtO#!n3(R#|Nb>!Y zdk^xx;U?l6=c=}|X1n+g{oUnKM2pXgJ7CrL7TA-xvy$8qtGYfy7Lv6G>NetqbqHRr zH;7UUh1%<#HnO|Y7h}X{U}79N5AE^mj@N_^C}7x6P!V=&xq42El-Ko5xffE>H4(@#krvtZq}n8WPaT9z^%J zy~lT2-dXxU4Bsu`1?w5ANe&Pe3m&Qv+53ee?E{fewFoE+cH>SWeMg4x&y-R?RTQJQ zraqxm?DVx6RG*?kdCXp?z3Mgm3HdY?(^f;3#D&$+z5(BP5!dmA$O!~OC*w~EBmvtv z_@zGxb3)wSNt;#ph)jsxtNSEv{_h9KY-u8Pk!})^$`9F=NTn$Wwc}7pvGkRE((G!)79*|=6 z6cwX;UE-EphtH)Kkr2Wh^4tr+poJ?-2kJZ-Yd+I)7;=&%nW;}H!E`J8v^YQKj xKqWjp0epiphFC^&K#j+l;yt=pX#O6@tGk^Bt-Lit&zS~o88Nz&CDW;`{6A$+VLJc- literal 0 HcmV?d00001 diff --git a/docs/.doctrees/honeybee.logutil.doctree b/docs/.doctrees/honeybee.logutil.doctree new file mode 100644 index 0000000000000000000000000000000000000000..b441404450779b2e14710a19034c808b08a9b51a GIT binary patch literal 8909 zcmcgy%Wot{8Mk-+8n4%0Z^$Odap(ZSW7ru3;t(yH1J4zh3}o5xl9E5+{T}ARgkt^9~Yl=YYf^2lxk&xFhlVs`@!&PwZvGN?vz=^>x+v z_*K>S@XK@G{o^}l)IYhFMBEJyyO!ewp~I3)E;*r{j#wbF*R$jzh6w4E!;3DKj-s&fiJ$8wRua<3s?B8HY6Y8VZe_1 zjCK8RND~>O&`H5VpWutRJM54|Ii2xdrliC&kI03{f?Oiw>#}8*itvkaA(y`==X^I{ zSugEda@i6hcKfM--lXS6*GWjHMccQM1VlW~2i8bGEjejaz4R@6FJ=ScN#&xjhBTD% zHNL@D_!Imh-;}p@csOD^aT)|H-Z=>4JrK0A9XpKK*c-%6N>X8sZk#}yCwDKTeLf@S z-N0doHS=l9@^?Ub{uJ!>F8n-=pDp}slO`}m>?--&axSvmIFpZS1Ao{kgelg7jrCAx zVuUaBL}sP@eY{gC*yB&ajJ&H+Qn>ky!Ym|iFoc`s_K*n^z8|u}jY91ttKpTlyaaVS5w;4gCoj|T3iIlnH6YYF9Qikr$fC`^gijI{ z@3V}c@FlErC&#*XKCBmN?c|%j8y(#s`~$4P&As7$W!%GQ6HES9$jtnm8y=Bo2vff zbX8CB?i(=m?@Aa=@#DXyO#O!m;E)$->OYrLFXlHxp-B1O)Zjl;micRAnKy9{R(}xp zY)rYgCVaF$!CYu}!bn3;@7nCl%oJ5m+=|{+d~`;CdGDUSz=zBAHs92?g~*>JYy+xAh=+|L>Zw%`G*fQWqT6~HTM@5cDeYTK z7?z;}WJ82TpBZVw9Agm12D5CQhs$MPc=iuU+~&IUHB7YOedk;z`!;cJ zc&{nTDUi@PR_f3Xoudg!F?^{HNK%&63?M5_S~Oz1f{i9V_XHLzZ=WxdvPP$4d`2Z) z2EBHTJDeHAFm#M4wvfBq%y1KeS_0^~f}Tv%4P0TG#vl$yh8rZV!xZ|K^X;wSr_w1O za>SNzBA5?@VNIYsid2#3i6N!;n{!$7SK6At#4lL!nw&TO`SR;VGw$+ew0^;W@A-$X zd@O-mhyC;b_jY z?_yt8gwg?OSH3}7sUplt>2E#fARFX3`n$5hX*i5{xIBq1kU!-4up=Kw`c zFfLPDUWkrRSRJH+?wX9HEKWGG+#vH(7*sAItr15N%e;MhRW-@l`(hC4{=l(Z$seiw zf0P}|wIIw>k0d9-0Q@J7N7Q0VFy)4(FrO)kdEg3e z77Zw@n17IWqjPFgEi@4t6F{k#) + +
+
+
+ +
+
+ +

Source code for honeybee.altnumber

+"""Objects used as alternatives to various numerical properties."""
+
+
+class _AltNumber(object):
+    __slots__ = ()
+
+    def __init__(self):
+        pass
+
+    @property
+    def name(self):
+        return self.__class__.__name__
+
+    def to_dict(self):
+        """Get the object as a dictionary."""
+        return {'type': self.name}
+
+    def ToString(self):
+        return self.__repr__()
+
+    def __eq__(self, other):
+        return self.__class__ == other.__class__
+
+    def __ne__(self, other):
+        return not self.__eq__(other)
+
+    def __repr__(self):
+        return self.name
+
+
+
[docs]class NoLimit(_AltNumber): + """Object representing no limit to a certain numerical value.""" + __slots__ = () + pass
+ + +
[docs]class Autocalculate(_AltNumber): + """Object representing when a certain numerical value is automatically calculated. + + Typically, this means that the value is determined from other variables. + """ + __slots__ = () + pass
+ + +no_limit = NoLimit() +autocalculate = Autocalculate() +
+ +
+ +
+
+
+
+

+ Back to top + +

+

+ © Copyright 2023, Ladybug Tools.
+ Created using Sphinx 5.3.0.
+

+
+
+ + \ No newline at end of file diff --git a/docs/_modules/honeybee/aperture.html b/docs/_modules/honeybee/aperture.html new file mode 100644 index 00000000..7c5d6a5a --- /dev/null +++ b/docs/_modules/honeybee/aperture.html @@ -0,0 +1,1933 @@ + + + + + + + honeybee.aperture — honeybee documentation + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+ +

Source code for honeybee.aperture

+# coding: utf-8
+"""Honeybee Aperture."""
+from __future__ import division
+import math
+
+from ladybug_geometry.geometry2d.pointvector import Vector2D
+from ladybug_geometry.geometry3d.pointvector import Point3D
+from ladybug_geometry.geometry3d.face import Face3D
+from ladybug.color import Color
+
+from ._basewithshade import _BaseWithShade
+from .typing import clean_string
+from .properties import ApertureProperties
+from .boundarycondition import boundary_conditions, Outdoors, Surface
+from .shade import Shade
+import honeybee.writer.aperture as writer
+
+
+
[docs]class Aperture(_BaseWithShade): + """A single planar Aperture in a Face. + + Args: + identifier: Text string for a unique Aperture ID. Must be < 100 characters and + not contain any spaces or special characters. + geometry: A ladybug-geometry Face3D. + boundary_condition: Boundary condition object (Outdoors, Surface). + Default: Outdoors. + is_operable: Boolean to note whether the Aperture can be opened for + ventilation. (Default: False). + + Properties: + * identifier + * display_name + * boundary_condition + * is_operable + * indoor_shades + * outdoor_shades + * parent + * top_level_parent + * has_parent + * geometry + * vertices + * upper_left_vertices + * triangulated_mesh3d + * normal + * center + * area + * perimeter + * min + * max + * altitude + * azimuth + * type_color + * bc_color + * user_data + """ + __slots__ = ('_geometry', '_parent', '_boundary_condition', '_is_operable') + TYPE_COLOR = Color(64, 180, 255, 100) + BC_COLORS = { + 'Outdoors': Color(128, 204, 255, 100), + 'Surface': Color(0, 190, 0, 100) + } + + def __init__(self, identifier, geometry, boundary_condition=None, is_operable=False): + """A single planar aperture in a face.""" + _BaseWithShade.__init__(self, identifier) # process the identifier + + # process the geometry + assert isinstance(geometry, Face3D), \ + 'Expected ladybug_geometry Face3D. Got {}'.format(type(geometry)) + self._geometry = geometry + self._parent = None # _parent will be set when the Aperture is added to a Face + + # process the boundary condition and type + self.boundary_condition = boundary_condition or boundary_conditions.outdoors + self.is_operable = is_operable + + # initialize properties for extensions + self._properties = ApertureProperties(self) + +
[docs] @classmethod + def from_dict(cls, data): + """Initialize an Aperture from a dictionary. + + Args: + data: A dictionary representation of an Aperture object. + """ + try: + # check the type of dictionary + assert data['type'] == 'Aperture', 'Expected Aperture dictionary. ' \ + 'Got {}.'.format(data['type']) + + # serialize the aperture + is_operable = data['is_operable'] if 'is_operable' in data else False + if data['boundary_condition']['type'] == 'Outdoors': + boundary_condition = Outdoors.from_dict(data['boundary_condition']) + elif data['boundary_condition']['type'] == 'Surface': + boundary_condition = Surface.from_dict(data['boundary_condition'], True) + else: + raise ValueError( + 'Boundary condition "{}" is not supported for Apertures.'.format( + data['boundary_condition']['type'])) + aperture = cls(data['identifier'], Face3D.from_dict(data['geometry']), + boundary_condition, is_operable) + if 'display_name' in data and data['display_name'] is not None: + aperture.display_name = data['display_name'] + if 'user_data' in data and data['user_data'] is not None: + aperture.user_data = data['user_data'] + aperture._recover_shades_from_dict(data) + + # assign extension properties + if data['properties']['type'] == 'ApertureProperties': + aperture.properties._load_extension_attr_from_dict(data['properties']) + return aperture + except Exception as e: + cls._from_dict_error_message(data, e)
+ +
[docs] @classmethod + def from_vertices(cls, identifier, vertices, boundary_condition=None, + is_operable=False): + """Create an Aperture from vertices with each vertex as an iterable of 3 floats. + + Args: + identifier: Text string for a unique Aperture ID. Must be < 100 characters + and not contain any spaces or special characters. + vertices: A flattened list of 3 or more vertices as (x, y, z). + boundary_condition: Boundary condition object (eg. Outdoors, Surface). + Default: Outdoors. + is_operable: Boolean to note whether the Aperture can be opened for + natural ventilation. Default: False + """ + geometry = Face3D(tuple(Point3D(*v) for v in vertices)) + return cls(identifier, geometry, boundary_condition, is_operable)
+ + @property + def boundary_condition(self): + """Get or set the boundary condition of this aperture.""" + return self._boundary_condition + + @boundary_condition.setter + def boundary_condition(self, value): + if not isinstance(value, Outdoors): + if isinstance(value, Surface): + assert len(value.boundary_condition_objects) == 3, 'Surface boundary ' \ + 'condition for Aperture must have 3 boundary_condition_objects.' + else: + raise ValueError('Aperture only supports Outdoor or Surface boundary ' + 'condition. Got {}'.format(type(value))) + self._boundary_condition = value + + @property + def is_operable(self): + """Get or set a boolean for whether the Aperture can be opened for ventilation. + """ + return self._is_operable + + @is_operable.setter + def is_operable(self, value): + try: + self._is_operable = bool(value) + except TypeError: + raise TypeError( + 'Expected boolean for Aperture.is_operable. Got {}.'.format(value)) + + @property + def parent(self): + """Get the parent Face if assigned. None if not assigned.""" + return self._parent + + @property + def top_level_parent(self): + """Get the top-level parent object if assigned. + + This will be a Room if there is a parent Face that has a parent Room and + will be a Face if the parent Face is orphaned. Will be None if no parent + is assigned. + """ + if self.has_parent: + if self._parent.has_parent: + return self._parent._parent + return self._parent + return None + + @property + def has_parent(self): + """Get a boolean noting whether this Aperture has a parent Face.""" + return self._parent is not None + + @property + def geometry(self): + """Get a ladybug_geometry Face3D object representing the aperture.""" + return self._geometry + + @property + def vertices(self): + """Get a list of vertices for the aperture (in counter-clockwise order).""" + return self._geometry.vertices + + @property + def upper_left_vertices(self): + """Get a list of vertices starting from the upper-left corner. + + This property should be used when exporting to EnergyPlus / OpenStudio. + """ + return self._geometry.upper_left_counter_clockwise_vertices + + @property + def triangulated_mesh3d(self): + """Get a ladybug_geometry Mesh3D of the aperture geometry composed of triangles. + + In EnergyPlus / OpenStudio workflows, this property is used to subdivide + the aperture when it has more than 4 vertices. This is necessary since + EnergyPlus cannot accept sub-faces with more than 4 vertices. + """ + return self._geometry.triangulated_mesh3d + + @property + def normal(self): + """Get a ladybug_geometry Vector3D for the direction the aperture is pointing. + """ + return self._geometry.normal + + @property + def center(self): + """Get a ladybug_geometry Point3D for the center of the aperture. + + Note that this is the center of the bounding rectangle around this geometry + and not the area centroid. + """ + return self._geometry.center + + @property + def area(self): + """Get the area of the aperture.""" + return self._geometry.area + + @property + def perimeter(self): + """Get the perimeter of the aperture.""" + return self._geometry.perimeter + + @property + def min(self): + """Get a Point3D for the minimum of the bounding box around the object.""" + return self._min_with_shades(self._geometry) + + @property + def max(self): + """Get a Point3D for the maximum of the bounding box around the object.""" + return self._max_with_shades(self._geometry) + + @property + def altitude(self): + """Get the altitude of the geometry between +90 (up) and -90 (down).""" + return math.degrees(self._geometry.altitude) + + @property + def azimuth(self): + """Get the azimuth of the geometry, between 0 and 360. + + Given Y-axis as North, 0 = North, 90 = East, 180 = South, 270 = West + This will be zero if the Face3D is perfectly horizontal. + """ + return math.degrees(self._geometry.azimuth) + + @property + def type_color(self): + """Get a Color to be used in visualizations by type.""" + return self.TYPE_COLOR + + @property + def bc_color(self): + """Get a Color to be used in visualizations by boundary condition.""" + return self.BC_COLORS[self.boundary_condition.name] + +
[docs] def horizontal_orientation(self, north_vector=Vector2D(0, 1)): + """Get a number between 0 and 360 for the orientation of the aperture in degrees. + + 0 = North, 90 = East, 180 = South, 270 = West + + Args: + north_vector: A ladybug_geometry Vector2D for the north direction. + Default is the Y-axis (0, 1). + """ + return math.degrees( + north_vector.angle_clockwise(Vector2D(self.normal.x, self.normal.y)))
+ +
[docs] def cardinal_direction(self, north_vector=Vector2D(0, 1)): + """Get text description for the cardinal direction that the aperture is pointing. + + Will be one of the following: ('North', 'NorthEast', 'East', 'SouthEast', + 'South', 'SouthWest', 'West', 'NorthWest'). + + Args: + north_vector: A ladybug_geometry Vector2D for the north direction. + Default is the Y-axis (0, 1). + """ + orient = self.horizontal_orientation(north_vector) + orient_text = ('North', 'NorthEast', 'East', 'SouthEast', 'South', + 'SouthWest', 'West', 'NorthWest') + angles = (22.5, 67.5, 112.5, 157.5, 202.5, 247.5, 292.5, 337.5) + for i, ang in enumerate(angles): + if orient < ang: + return orient_text[i] + return orient_text[0]
+ +
[docs] def add_prefix(self, prefix): + """Change the identifier of this object and child objects by inserting a prefix. + + This is particularly useful in workflows where you duplicate and edit + a starting object and then want to combine it with the original object + into one Model (like making a model of repeated rooms) since all objects + within a Model must have unique identifiers. + + Args: + prefix: Text that will be inserted at the start of this object's + (and child objects') identifier and display_name. It is recommended + that this prefix be short to avoid maxing out the 100 allowable + characters for honeybee identifiers. + """ + self._identifier = clean_string('{}_{}'.format(prefix, self.identifier)) + self.display_name = '{}_{}'.format(prefix, self.display_name) + self.properties.add_prefix(prefix) + self._add_prefix_shades(prefix) + if isinstance(self._boundary_condition, Surface): + new_bc_objs = (clean_string('{}_{}'.format(prefix, adj_name)) for adj_name + in self._boundary_condition._boundary_condition_objects) + self._boundary_condition = Surface(new_bc_objs, True)
+ +
[docs] def set_adjacency(self, other_aperture): + """Set this aperture to be adjacent to another. + + Note that this method does not verify whether the other_aperture geometry is + co-planar or compatible with this one so it is recommended that a test + be performed before using this method in order to verify these criteria. + The Face3D.is_centered_adjacent() or the Face3D.is_geometrically_equivalent() + methods are both suitable for this purpose. + + Args: + other_aperture: Another Aperture object to be set adjacent to this one. + """ + assert isinstance(other_aperture, Aperture), \ + 'Expected Aperture. Got {}.'.format(type(other_aperture)) + assert other_aperture.is_operable is self.is_operable, \ + 'Adjacent apertures must have matching is_operable properties.' + self._boundary_condition = boundary_conditions.surface(other_aperture, True) + other_aperture._boundary_condition = boundary_conditions.surface(self, True)
+ +
[docs] def overhang(self, depth, angle=0, indoor=False, tolerance=0.01, base_name=None): + """Add a single overhang for this Aperture. + + Args: + depth: A number for the overhang depth. + angle: A number for the for an angle to rotate the overhang in degrees. + Positive numbers indicate a downward rotation while negative numbers + indicate an upward rotation. Default is 0 for no rotation. + indoor: Boolean for whether the overhang should be generated facing the + opposite direction of the aperture normal (typically meaning + indoor geometry). Default: False. + tolerance: An optional value to return None if the overhang has a length less + than the tolerance. Default: 0.01, suitable for objects in meters. + base_name: Optional base name for the shade objects. If None, the default + is InOverhang or OutOverhang depending on whether indoor is True. + + Returns: + A list of the new Shade objects that have been generated. + """ + if base_name is None: + base_name = 'InOverhang' if indoor else 'OutOverhang' + return self.louvers_by_count(1, depth, angle=angle, indoor=indoor, + tolerance=tolerance, base_name=base_name)
+ +
[docs] def right_fin(self, depth, angle=0, indoor=False, tolerance=0.01, base_name=None): + """Add a single vertical fin on the right side of this Aperture. + + Args: + depth: A number for the fin depth. + angle: A number for the for an angle to rotate the fin in degrees. + Default is 0 for no rotation. + indoor: Boolean for whether the fin should be generated facing the + opposite direction of the aperture normal (typically meaning + indoor geometry). Default: False. + tolerance: An optional value to return None if the fin has a length less + than the tolerance. Default: 0.01, suitable for objects in meters. + base_name: Optional base name for the shade objects. If None, the default + is InRightFin or OutRightFin depending on whether indoor is True. + + Returns: + A list of the new Shade objects that have been generated. + """ + if base_name is None: + base_name = 'InRightFin' if indoor else 'OutRightFin' + return self.louvers_by_count( + 1, depth, angle=angle, contour_vector=Vector2D(1, 0), + indoor=indoor, tolerance=tolerance, base_name=base_name)
+ +
[docs] def left_fin(self, depth, angle=0, indoor=False, tolerance=0.01, base_name=None): + """Add a single vertical fin on the left side of this Aperture. + + Args: + depth: A number for the fin depth. + angle: A number for the for an angle to rotate the fin in degrees. + Default is 0 for no rotation. + indoor: Boolean for whether the fin should be generated facing the + opposite direction of the aperture normal (typically meaning + indoor geometry). Default: False. + tolerance: An optional value to return None if the fin has a length less + than the tolerance. Default: 0.01, suitable for objects in meters. + base_name: Optional base name for the shade objects. If None, the default + is InLeftFin or OutLeftFin depending on whether indoor is True. + + Returns: + A list of the new Shade objects that have been generated. + """ + if base_name is None: + base_name = 'InLeftFin' if indoor else 'OutLeftFin' + return self.louvers_by_count( + 1, depth, angle=angle, contour_vector=Vector2D(1, 0), + flip_start_side=True, indoor=indoor, tolerance=tolerance, + base_name=base_name)
+ +
[docs] def extruded_border(self, depth, indoor=False, base_name=None): + """Add a series of Shade objects to this Aperture that form an extruded border. + + Args: + depth: A number for the extrusion depth. + indoor: Boolean for whether the extrusion should be generated facing the + opposite direction of the aperture normal and added to the Aperture's + indoor_shades instead of outdoor_shades. Default: False. + base_name: Optional base name for the shade objects. If None, the default + is InBorder or OutBorder depending on whether indoor is True. + + Returns: + A list of the new Shade objects that have been generated. + """ + extru_vec = self.normal if indoor is False else self.normal.reverse() + extru_vec = extru_vec * depth + extrusion = [] + shd_count = 0 + if base_name is None: + shd_name_base = '{}_InBorder{}' if indoor else '{}_OutBorder{}' + else: + shd_name_base = '{}_' + str(base_name) + '{}' + for seg in self.geometry.boundary_segments: + shade_geo = Face3D.from_extrusion(seg, extru_vec) + extrusion.append( + Shade(shd_name_base.format(self.identifier, shd_count), shade_geo)) + shd_count += 1 + if self.geometry.has_holes: + for hole in self.geometry.hole_segments: + for seg in hole: + shade_geo = Face3D.from_extrusion(seg, extru_vec) + extrusion.append( + Shade(shd_name_base.format(self.identifier, shd_count), + shade_geo)) + shd_count += 1 + if indoor: + self.add_indoor_shades(extrusion) + else: + self.add_outdoor_shades(extrusion) + return extrusion
+ +
[docs] def louvers_by_count(self, louver_count, depth, offset=0, angle=0, + contour_vector=Vector2D(0, 1), flip_start_side=False, + indoor=False, tolerance=0.01, base_name=None): + """Add a series of louvered Shade objects covering this Aperture. + + Args: + louver_count: A positive integer for the number of louvers to generate. + depth: A number for the depth to extrude the louvers. + offset: A number for the distance to louvers from this aperture. + Default is 0 for no offset. + angle: A number for the for an angle to rotate the louvers in degrees. + Positive numbers indicate a downward rotation while negative numbers + indicate an upward rotation. Default is 0 for no rotation. + contour_vector: A Vector2D for the direction along which contours + are generated. This 2D vector will be interpreted into a 3D vector + within the plane of this Aperture. (0, 1) will usually generate + horizontal contours in 3D space, (1, 0) will generate vertical + contours, and (1, 1) will generate diagonal contours. Default: (0, 1). + flip_start_side: Boolean to note whether the side the louvers start from + should be flipped. Default is False to have louvers on top or right. + Setting to True will start contours on the bottom or left. + indoor: Boolean for whether louvers should be generated facing the + opposite direction of the aperture normal (typically meaning + indoor geometry). Default: False. + tolerance: An optional value to remove any louvers with a length less + than the tolerance. Default: 0.01, suitable for objects in meters. + base_name: Optional base name for the shade objects. If None, the default + is InShd or OutShd depending on whether indoor is True. + + Returns: + A list of the new Shade objects that have been generated. + """ + assert louver_count > 0, 'louver_count must be greater than 0.' + angle = math.radians(angle) + louvers = [] + ap_geo = self.geometry if indoor is False else self.geometry.flip() + shade_faces = ap_geo.contour_fins_by_number( + louver_count, depth, offset, angle, + contour_vector, flip_start_side, tolerance) + if base_name is None: + shd_name_base = '{}_InShd{}' if indoor else '{}_OutShd{}' + else: + shd_name_base = '{}_' + str(base_name) + '{}' + for i, shade_geo in enumerate(shade_faces): + louvers.append(Shade(shd_name_base.format(self.identifier, i), shade_geo)) + if indoor: + self.add_indoor_shades(louvers) + else: + self.add_outdoor_shades(louvers) + return louvers
+ +
[docs] def louvers_by_distance_between( + self, distance, depth, offset=0, angle=0, contour_vector=Vector2D(0, 1), + flip_start_side=False, indoor=False, tolerance=0.01, max_count=None, + base_name=None): + """Add a series of louvered Shade objects covering this Aperture. + + Args: + distance: A number for the approximate distance between each louver. + depth: A number for the depth to extrude the louvers. + offset: A number for the distance to louvers from this aperture. + Default is 0 for no offset. + angle: A number for the for an angle to rotate the louvers in degrees. + Positive numbers indicate a downward rotation while negative numbers + indicate an upward rotation. Default is 0 for no rotation. + contour_vector: A Vector2D for the direction along which contours + are generated. This 2D vector will be interpreted into a 3D vector + within the plane of this Aperture. (0, 1) will usually generate + horizontal contours in 3D space, (1, 0) will generate vertical + contours, and (1, 1) will generate diagonal contours. Default: (0, 1). + flip_start_side: Boolean to note whether the side the louvers start from + should be flipped. Default is False to have contours on top or right. + Setting to True will start contours on the bottom or left. + indoor: Boolean for whether louvers should be generated facing the + opposite direction of the aperture normal (typically meaning + indoor geometry). Default: 0.01, suitable for objects in meters. + tolerance: An optional value to remove any louvers with a length less + than the tolerance. Default is 0, which will include all louvers + no matter how small. + max_count: Optional integer to set the maximum number of louvers that + will be generated. If None, louvers will cover the entire aperture. + base_name: Optional base name for the shade objects. If None, the default + is InShd or OutShd depending on whether indoor is True. + + Returns: + A list of the new Shade objects that have been generated. + """ + # set defaults + angle = math.radians(angle) + ap_geo = self.geometry if indoor is False else self.geometry.flip() + if base_name is None: + shd_name_base = '{}_InShd{}' if indoor else '{}_OutShd{}' + else: + shd_name_base = '{}_' + str(base_name) + '{}' + + # generate shade geometries + shade_faces = ap_geo.contour_fins_by_distance_between( + distance, depth, offset, angle, + contour_vector, flip_start_side, tolerance) + if max_count: + try: + shade_faces = shade_faces[:max_count] + except IndexError: # fewer shades were generated than the max count + pass + + # create the shade objects + louvers = [] + for i, shade_geo in enumerate(shade_faces): + louvers.append(Shade(shd_name_base.format(self.identifier, i), shade_geo)) + if indoor: + self.add_indoor_shades(louvers) + else: + self.add_outdoor_shades(louvers) + return louvers
+ +
[docs] def move(self, moving_vec): + """Move this Aperture along a vector. + + Args: + moving_vec: A ladybug_geometry Vector3D with the direction and distance + to move the face. + """ + self._geometry = self.geometry.move(moving_vec) + self.move_shades(moving_vec) + self.properties.move(moving_vec) + self._reset_parent_geometry()
+ +
[docs] def rotate(self, axis, angle, origin): + """Rotate this Aperture by a certain angle around an axis and origin. + + Args: + axis: A ladybug_geometry Vector3D axis representing the axis of rotation. + angle: An angle for rotation in degrees. + origin: A ladybug_geometry Point3D for the origin around which the + object will be rotated. + """ + self._geometry = self.geometry.rotate(axis, math.radians(angle), origin) + self.rotate_shades(axis, angle, origin) + self.properties.rotate(axis, angle, origin) + self._reset_parent_geometry()
+ +
[docs] def rotate_xy(self, angle, origin): + """Rotate this Aperture counterclockwise in the world XY plane by an angle. + + Args: + angle: An angle in degrees. + origin: A ladybug_geometry Point3D for the origin around which the + object will be rotated. + """ + self._geometry = self.geometry.rotate_xy(math.radians(angle), origin) + self.rotate_xy_shades(angle, origin) + self.properties.rotate_xy(angle, origin) + self._reset_parent_geometry()
+ +
[docs] def reflect(self, plane): + """Reflect this Aperture across a plane. + + Args: + plane: A ladybug_geometry Plane across which the object will + be reflected. + """ + self._geometry = self.geometry.reflect(plane.n, plane.o) + self.reflect_shades(plane) + self.properties.reflect(plane) + self._reset_parent_geometry()
+ +
[docs] def scale(self, factor, origin=None): + """Scale this Aperture by a factor from an origin point. + + Args: + factor: A number representing how much the object should be scaled. + origin: A ladybug_geometry Point3D representing the origin from which + to scale. If None, it will be scaled from the World origin (0, 0, 0). + """ + self._geometry = self.geometry.scale(factor, origin) + self.scale_shades(factor, origin) + self.properties.scale(factor, origin) + self._reset_parent_geometry()
+ +
[docs] def remove_colinear_vertices(self, tolerance=0.01): + """Remove all colinear and duplicate vertices from this object's geometry. + + Note that this does not affect any assigned Shades. + + Args: + tolerance: The minimum distance between a vertex and the boundary segments + at which point the vertex is considered colinear. Default: 0.01, + suitable for objects in meters. + """ + try: + self._geometry = self.geometry.remove_colinear_vertices(tolerance) + except AssertionError as e: # usually a sliver face of some kind + raise ValueError( + 'Aperture "{}" is invalid with dimensions less than the ' + 'tolerance.\n{}'.format(self.full_id, e))
+ +
[docs] def is_geo_equivalent(self, aperture, tolerance=0.01): + """Get a boolean for whether this object is geometrically equivalent to another. + + The total number of vertices and the ordering of these vertices can be + different but the geometries must share the same center point and be + next to one another to within the tolerance. + + Args: + aperture: Another Aperture for which geometric equivalency will be tested. + tolerance: The minimum difference between the coordinate values of two + vertices at which they can be considered geometrically equivalent. + + Returns: + True if geometrically equivalent. False if not geometrically equivalent. + """ + meta_1 = (self.display_name, self.is_operable, self.boundary_condition) + meta_2 = (aperture.display_name, aperture.is_operable, + aperture.boundary_condition) + if meta_1 != meta_2: + return False + if abs(self.area - aperture.area) > tolerance * self.area: + return False + if not self.geometry.is_centered_adjacent(aperture.geometry, tolerance): + return False + if not self._are_shades_equivalent(aperture, tolerance): + return False + return True
+ +
[docs] def check_planar(self, tolerance=0.01, raise_exception=True, detailed=False): + """Check whether all of the Aperture's vertices lie within the same plane. + + Args: + tolerance: The minimum distance between a given vertex and a the + object's plane at which the vertex is said to lie in the plane. + Default: 0.01, suitable for objects in meters. + raise_exception: Boolean to note whether an ValueError should be + raised if a vertex does not lie within the object's plane. + detailed: Boolean for whether the returned object is a detailed list of + dicts with error info or a string with a message. (Default: False). + + Returns: + A string with the message or a list with a dictionary if detailed is True. + """ + try: + self.geometry.check_planar(tolerance, raise_exception=True) + except ValueError as e: + msg = 'Aperture "{}" is not planar.\n{}'.format(self.full_id, e) + full_msg = self._validation_message( + msg, raise_exception, detailed, '000101', + error_type='Non-Planar Geometry') + if detailed: # add the out-of-plane points to helper_geometry + help_pts = [ + p.to_dict() for p in self.geometry.non_planar_vertices(tolerance) + ] + full_msg[0]['helper_geometry'] = help_pts + return full_msg + return [] if detailed else ''
+ +
[docs] def check_self_intersecting(self, tolerance=0.01, raise_exception=True, + detailed=False): + """Check whether the edges of the Aperture intersect one another (like a bowtie). + + Note that objects that have duplicate vertices will not be considered + self-intersecting and are valid in honeybee. + + Args: + tolerance: The minimum difference between the coordinate values of two + vertices at which they can be considered equivalent. Default: 0.01, + suitable for objects in meters. + raise_exception: If True, a ValueError will be raised if the object + intersects with itself. Default: True. + detailed: Boolean for whether the returned object is a detailed list of + dicts with error info or a string with a message. (Default: False). + + Returns: + A string with the message or a list with a dictionary if detailed is True. + """ + if self.geometry.is_self_intersecting: + msg = 'Aperture "{}" has self-intersecting edges.'.format(self.full_id) + try: # see if it is self-intersecting because of a duplicate vertex + new_geo = self.geometry.remove_duplicate_vertices(tolerance) + if not new_geo.is_self_intersecting: + return [] if detailed else '' # valid with removed dup vertex + except AssertionError: + return [] if detailed else '' # degenerate geometry + full_msg = self._validation_message( + msg, raise_exception, detailed, '000102', + error_type='Self-Intersecting Geometry') + if detailed: # add the self-intersection points to helper_geometry + help_pts = [p.to_dict() for p in self.geometry.self_intersection_points] + full_msg[0]['helper_geometry'] = help_pts + return full_msg + return [] if detailed else ''
+ +
[docs] def display_dict(self): + """Get a list of DisplayFace3D dictionaries for visualizing the object.""" + base = [self._display_face(self.geometry, self.type_color)] + for shd in self.shades: + base.extend(shd.display_dict()) + return base
+ + @property + def to(self): + """Aperture writer object. + + Use this method to access Writer class to write the aperture in other formats. + + Usage: + + .. code-block:: python + + aperture.to.idf(aperture) -> idf string. + aperture.to.radiance(aperture) -> Radiance string. + """ + return writer + +
[docs] def to_dict(self, abridged=False, included_prop=None, include_plane=True): + """Return Aperture as a dictionary. + + Args: + abridged: Boolean to note whether the extension properties of the + object (ie. materials, constructions) should be included in detail + (False) or just referenced by identifier (True). (Default: False). + included_prop: List of properties to filter keys that must be included in + output dictionary. For example ['energy'] will include 'energy' key if + available in properties to_dict. By default all the keys will be + included. To exclude all the keys from extensions use an empty list. + include_plane: Boolean to note wether the plane of the Face3D should be + included in the output. This can preserve the orientation of the + X/Y axes of the plane but is not required and can be removed to + keep the dictionary smaller. (Default: True). + """ + base = {'type': 'Aperture'} + base['identifier'] = self.identifier + base['display_name'] = self.display_name + base['properties'] = self.properties.to_dict(abridged, included_prop) + enforce_upper_left = True if 'energy' in base['properties'] else False + base['geometry'] = self._geometry.to_dict(include_plane, enforce_upper_left) + base['is_operable'] = self.is_operable + if isinstance(self.boundary_condition, Outdoors) and \ + 'energy' in base['properties']: + base['boundary_condition'] = self.boundary_condition.to_dict(full=True) + else: + base['boundary_condition'] = self.boundary_condition.to_dict() + self._add_shades_to_dict(base, abridged, included_prop, include_plane) + if self.user_data is not None: + base['user_data'] = self.user_data + return base
+ + def _reset_parent_geometry(self): + """Reset parent punched_geometry in the case that the object is transformed.""" + if self.has_parent: + self._parent._punched_geometry = None + + def __copy__(self): + new_ap = Aperture(self.identifier, self.geometry, self.boundary_condition, + self.is_operable) + new_ap._display_name = self._display_name + new_ap._user_data = None if self.user_data is None else self.user_data.copy() + self._duplicate_child_shades(new_ap) + new_ap._properties._duplicate_extension_attr(self._properties) + return new_ap + + def __repr__(self): + return 'Aperture: %s' % self.display_name
+
+ +
+ +
+
+
+
+

+ Back to top + +

+

+ © Copyright 2023, Ladybug Tools.
+ Created using Sphinx 5.3.0.
+

+
+
+ + \ No newline at end of file diff --git a/docs/_modules/honeybee/boundarycondition.html b/docs/_modules/honeybee/boundarycondition.html new file mode 100644 index 00000000..74c145f6 --- /dev/null +++ b/docs/_modules/honeybee/boundarycondition.html @@ -0,0 +1,1468 @@ + + + + + + + honeybee.boundarycondition — honeybee documentation + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+ +

Source code for honeybee.boundarycondition

+"""Boundary Condition for Face, Aperture, Door."""
+import re
+
+from .typing import float_in_range, tuple_with_length
+from .altnumber import autocalculate
+
+
+class _BoundaryCondition(object):
+    """Base boundary condition class."""
+
+    __slots__ = ()
+
+    def __init__(self):
+        """Initialize Boundary condition."""
+
+    @property
+    def name(self):
+        """Get the name of the boundary condition (ie. 'Outdoors', 'Ground')."""
+        return self.__class__.__name__
+
+    @property
+    def view_factor(self):
+        """Get the view factor to the ground."""
+        return 'autocalculate'
+
+    @property
+    def sun_exposure_idf(self):
+        """Get a text string for sun exposure, which is write-able into an IDF."""
+        return 'NoSun'
+
+    @property
+    def wind_exposure_idf(self):
+        """ Get a text string for wind exposure, which is write-able into an IDF."""
+        return 'NoWind'
+
+    def to_dict(self):
+        """Get the boundary condition as a dictionary."""
+        return {'type': self.name}
+
+    def ToString(self):
+        """Overwrite .NET ToString."""
+        return self.__repr__()
+
+    def __repr__(self):
+        return self.name
+
+
+
[docs]class Outdoors(_BoundaryCondition): + """Outdoor boundary condition. + + Args: + sun_exposure: A boolean noting whether the boundary is exposed to sun. + Default: True. + wind_exposure: A boolean noting whether the boundary is exposed to wind. + Default: True. + view_factor: A number between 0 and 1 for the view factor to the ground. + This input can also be an Autocalculate object to signify that the view + factor automatically calculated. Default: autocalculate. + """ + + __slots__ = ('_sun_exposure', '_wind_exposure', '_view_factor') + + def __init__(self, sun_exposure=True, wind_exposure=True, + view_factor=autocalculate): + """Initialize Outdoors boundary condition.""" + assert isinstance(sun_exposure, bool), \ + 'Input sun_exposure must be a Boolean. Got {}.'.format(type(sun_exposure)) + self._sun_exposure = sun_exposure + assert isinstance(wind_exposure, bool), \ + 'Input wind_exposure must be a Boolean. Got {}.'.format(type(wind_exposure)) + self._wind_exposure = wind_exposure + if view_factor == autocalculate: + self._view_factor = autocalculate + else: + self._view_factor = float_in_range( + view_factor, 0.0, 1.0, 'view factor to ground') + +
[docs] @classmethod + def from_dict(cls, data): + """Initialize Outdoors BoundaryCondition from a dictionary. + + Args: + data: A dictionary representation of the boundary condition. + """ + assert data['type'] == 'Outdoors', 'Expected dictionary for Outdoors boundary ' \ + 'condition. Got {}.'.format(data['type']) + sun_exposure = True if 'sun_exposure' not in data else data['sun_exposure'] + wind_exposure = True if 'wind_exposure' not in data else data['wind_exposure'] + view_factor = autocalculate if 'view_factor' not in data or \ + data['view_factor'] == autocalculate.to_dict() else data['view_factor'] + return cls(sun_exposure, wind_exposure, view_factor)
+ + @property + def sun_exposure(self): + """Get a boolean noting whether the boundary is exposed to sun.""" + return self._sun_exposure + + @property + def wind_exposure(self): + """Get a boolean noting whether the boundary is exposed to wind.""" + return self._wind_exposure + + @property + def view_factor(self): + """Get the view factor to the ground as a number or 'autocalculate'.""" + return self._view_factor + + @property + def sun_exposure_idf(self): + """Get a text string for sun exposure, which is write-able into an IDF.""" + return 'NoSun' if not self.sun_exposure else 'SunExposed' + + @property + def wind_exposure_idf(self): + """Get a text string for wind exposure, which is write-able into an IDF.""" + return 'NoWind' if not self.wind_exposure else 'WindExposed' + +
[docs] def to_dict(self, full=False): + """Get the boundary condition as a dictionary. + + Args: + full: Set to True to get the full dictionary which includes energy + simulation specific keys such as sun_exposure, wind_exposure and + view_factor. (Default: False). + """ + bc_dict = {'type': self.name} + if full: + bc_dict['sun_exposure'] = self.sun_exposure + bc_dict['wind_exposure'] = self.wind_exposure + bc_dict['view_factor'] = autocalculate.to_dict() if \ + self.view_factor == autocalculate else self.view_factor + return bc_dict
+ + def __key(self): + """A tuple based on the object properties, useful for hashing.""" + return (self.sun_exposure, self.wind_exposure, self.view_factor) + + def __hash__(self): + return hash(self.__key()) + + def __eq__(self, other): + return isinstance(other, Outdoors) and self.__key() == other.__key()
+ + +
[docs]class Surface(_BoundaryCondition): + """Boundary condition when an object is adjacent to another object.""" + + __slots__ = ('_boundary_condition_objects',) + + def __init__(self, boundary_condition_objects, sub_face=False): + """Initialize Surface boundary condition. + + Args: + boundary_condition_objects: A list of up to 3 object identifiers that are + adjacent to this one. The first object is always immediately + adjacent and is of the same object type (Face, Aperture, Door). When + this boundary condition is applied to a Face, the second object in the + tuple will be the parent Room of the adjacent object. When the boundary + condition is applied to a sub-face (Door or Aperture), the second object + will be the parent Face of the adjacent sub-face and the third object + will be the parent Room of the adjacent sub-face. + sub_face: Boolean to note whether this boundary condition is applied to a + sub-face (an Aperture or a Door) instead of a Face. (Default: False). + """ + if sub_face: + self._boundary_condition_objects = tuple_with_length( + boundary_condition_objects, 3, str, + 'boundary_condition_objects for Apertures or Doors') + else: + self._boundary_condition_objects = tuple_with_length( + boundary_condition_objects, 2, str, + 'boundary_condition_objects for Faces') + +
[docs] @classmethod + def from_dict(cls, data, sub_face=False): + """Initialize Surface BoundaryCondition from a dictionary. + + Args: + data: A dictionary representation of the boundary condition. + sub_face: Boolean to note whether this boundary condition is applied to a + sub-face (an Aperture or a Door) instead of a Face. Default: False. + """ + assert data['type'] == 'Surface', 'Expected dictionary for Surface boundary ' \ + 'condition. Got {}.'.format(data['type']) + return cls(data['boundary_condition_objects'], sub_face)
+ +
[docs] @classmethod + def from_other_object(cls, other_object, sub_face=False): + """Initialize Surface boundary condition from an adjacent other object. + + Args: + other_object: Another object (Face, Aperture, Door) of the same type + that this boundary condition is assigned. This other_object will be + set as the adjacent object in this boundary condition. + sub_face: Boolean to note whether this boundary condition is applied to a + sub-face (an Aperture or a Door) instead of a Face. Default: False. + """ + error_msg = 'Surface boundary conditions can only be assigned to objects' \ + ' with parent Rooms.' + bc_objects = [other_object.identifier] + if other_object.has_parent: + bc_objects.append(other_object.parent.identifier) + if sub_face: + if other_object.parent.has_parent: + bc_objects.append(other_object.parent.parent.identifier) + else: + raise AttributeError(error_msg) + else: + raise AttributeError(error_msg) + return cls(bc_objects, sub_face)
+ + @property + def boundary_condition_objects(self): + """Get a tuple of up to 3 object identifiers that are adjacent to this one. + + The first object is always the one that is immediately adjacent and is of + the same object type (Face, Aperture, Door). + When this boundary condition is applied to a Face, the second object in the + tuple will be the parent Room of the adjacent object. + When the boundary condition is applied to a sub-face (Door or Aperture), + the second object will be the parent Face of the sub-face and the third + object will be the parent Room of the adjacent sub-face. + """ + return self._boundary_condition_objects + + @property + def boundary_condition_object(self): + """Get the identifier of the object adjacent to this one.""" + return self._boundary_condition_objects[0] + +
[docs] def to_dict(self): + """Get the boundary condition as a dictionary. + + Args: + full: Set to True to get the full dictionary which includes energy + simulation specific keys such as sun_exposure, wind_exposure and + view_factor. Default: False. + """ + return {'type': self.name, + 'boundary_condition_objects': self.boundary_condition_objects}
+ + def __key(self): + """A tuple based on the object properties, useful for hashing.""" + return self.boundary_condition_objects + + def __hash__(self): + return hash(self.__key()) + + def __eq__(self, other): + return isinstance(other, Surface) and self.__key() == other.__key()
+ + +
[docs]class Ground(_BoundaryCondition): + """Ground boundary condition. + + Args: + data: A dictionary representation of the boundary condition. + """ + __slots__ = () + +
[docs] @classmethod + def from_dict(cls, data): + """Initialize Ground BoundaryCondition from a dictionary.""" + assert data['type'] == 'Ground', 'Expected dictionary for Ground boundary ' \ + 'condition. Got {}.'.format(data['type']) + return cls()
+ + def __eq__(self, other): + return isinstance(other, Ground)
+ + +class _BoundaryConditions(object): + """Boundary conditions.""" + + def __init__(self): + self._outdoors = Outdoors() + self._ground = Ground() + self._bc_name_dict = None + + @property + def outdoors(self): + """Default outdoor boundary condition.""" + return self._outdoors + + @property + def ground(self): + """Default ground boundary condition.""" + return self._ground + + def surface(self, other_object, sub_face=False): + """Get a Surface boundary condition. + + Args: + other_object: The other object that is adjacent to the one that will + bear this Surface boundary condition. + sub_face: Boolean to note whether the boundary condition is for a + sub-face (Aperture or Door) instead of a Face. (Default: False). + """ + return Surface.from_other_object(other_object, sub_face) + + def by_name(self, bc_name): + """Get a boundary condition object instance by its name. + + This method will correct for capitalization as well as the presence of + spaces and underscores. Note that this method only works for boundary + conditions with all of their inputs defaulted. + + Args: + bc_name: A boundary condition name. + """ + if self._bc_name_dict is None: + self._build_bc_name_dict() + try: + return self._bc_name_dict[re.sub(r'[\s_]', '', bc_name.lower())] + except KeyError: + raise ValueError( + '"{}" is not a valid boundary condition name.\nChoose from the ' + 'following: {}'.format(bc_name, list(self._bc_name_dict.keys()))) + + def _build_bc_name_dict(self): + """Build a dictionary that can be used to lookup boundary conditions by name.""" + attr = [atr for atr in dir(self) if not atr.startswith('_')] + clean_attr = [re.sub(r'[\s_]', '', atr.lower()) for atr in attr] + self._bc_name_dict = {} + for atr_name, atr in zip(clean_attr, attr): + try: + full_attr = getattr(self, '_' + atr) + self._bc_name_dict[atr_name] = full_attr + except AttributeError: + pass # callable method that has no static default object + + def __contains__(self, value): + return isinstance(value, _BoundaryCondition) + + +boundary_conditions = _BoundaryConditions() + + +
[docs]def get_bc_from_position(positions, ground_depth=0): + """Return a boundary condition based on the relationship to a ground plane. + + Positions that are entirely at or below the ground_depth will get a Ground + boundary condition. If there are any positions above the ground_depth, an + Outdoors boundary condition will be returned. + + args: + positions: A list of ladybug_geometry Point3D objects representing the + vertices of an object. + ground_depth: The Z value above which positions are considered Outdoors + instead of Ground. + + Returns: + Face type instance. + """ + for position in positions: + if position.z > ground_depth: + return boundary_conditions.outdoors + return boundary_conditions.ground
+
+ +
+ +
+
+
+
+

+ Back to top + +

+

+ © Copyright 2023, Ladybug Tools.
+ Created using Sphinx 5.3.0.
+

+
+
+ + \ No newline at end of file diff --git a/docs/_modules/honeybee/checkdup.html b/docs/_modules/honeybee/checkdup.html new file mode 100644 index 00000000..686fce43 --- /dev/null +++ b/docs/_modules/honeybee/checkdup.html @@ -0,0 +1,1283 @@ + + + + + + + honeybee.checkdup — honeybee documentation + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+ +

Source code for honeybee.checkdup

+# coding=utf-8
+"""Utilities to check whether there are any duplicate values in a list of ids."""
+
+import collections
+
+
+
[docs]def check_duplicate_identifiers( + objects_to_check, raise_exception=True, obj_name='', detailed=False, + code='000000', extension='Core', error_type='Duplicate Object Identifier'): + """Check whether there are duplicated identifiers across a list of objects. + + Args: + objects_to_check: A list of honeybee objects across which duplicate + identifiers will be checked. + raise_exception: Boolean to note whether an exception should be raised if + duplicated identifiers are found. (Default: True). + obj_name: An optional name for the object to be included in the error + message. Fro example, 'Room', 'Face', 'Aperture'. + detailed: Boolean for whether the returned object is a detailed list of + dicts with error info or a string with a message. (Default: False). + code: Text for the error code. (Default: 0000). + extension: Text for the name of the Honeybee extension for which duplicate + identifiers are being evaluated. (Default: Core). + error_type: Text for the type of error. This should be directly linked + to the error code and should simply be a human-readable version of + the error code. (Default: Unknown Error). + + Returns: + A message string indicating the duplicated identifiers (if detailed is False) + or a list of dictionaries with information about the duplicated identifiers + (if detailed is True). This string (or list) will be empty if no duplicates + were found. + """ + detailed = False if raise_exception else detailed + obj_id_iter = (obj.identifier for obj in objects_to_check) + dup = [t for t, c in collections.Counter(obj_id_iter).items() if c > 1] + if len(dup) != 0: + if detailed: + # find the object display names + dis_names = [] + for obj_id in dup: + dis_name = None + for obj in objects_to_check: + if obj.identifier == obj_id: + dis_name = obj.display_name + dis_names.append(dis_name) + err_list = [] + for dup_id, dis_name in zip(dup, dis_names): + msg = 'There is a duplicated {} identifier: {}'.format(obj_name, dup_id) + dup_dict = { + 'type': 'ValidationError', + 'code': code, + 'error_type': error_type, + 'extension_type': extension, + 'element_type': obj_name, + 'element_id': [dup_id], + 'message': msg + } + if dis_name is not None: + dup_dict['element_name'] = [dis_name] + err_list.append(dup_dict) + return err_list + msg = 'The following duplicated {} identifiers were found:\n{}'.format( + obj_name, '\n'.join(dup)) + if raise_exception: + raise ValueError(msg) + return msg + return [] if detailed else ''
+ + +
[docs]def check_duplicate_identifiers_parent( + objects_to_check, raise_exception=True, obj_name='', detailed=False, + code='000000', extension='Core', error_type='Duplicate Object Identifier'): + """Check whether there are duplicated identifiers across a list of objects. + + The error message will include the identifiers of top-level parents in order + to make it easier to find the duplicated objects in the model. + + Args: + objects_to_check: A list of honeybee objects across which duplicate + identifiers will be checked. These objects must have the ability to + have parents for this method to run correctly. + raise_exception: Boolean to note whether an exception should be raised if + duplicated identifiers are found. (Default: True). + obj_name: An optional name for the object to be included in the error + message. For example, 'Room', 'Face', 'Aperture'. + detailed: Boolean for whether the returned object is a detailed list of + dicts with error info or a string with a message. (Default: False). + code: Text for the error code. (Default: 0000). + extension: Text for the name of the Honeybee extension for which duplicate + identifiers are being evaluated. (Default: Core). + error_type: Text for the type of error. This should be directly linked + to the error code and should simply be a human-readable version of + the error code. (Default: Unknown Error). + + Returns: + A message string indicating the duplicated identifiers (if detailed is False) + or a list of dictionaries with information about the duplicated identifiers + (if detailed is True). This string (or list) will be empty if no duplicates + were found. + """ + detailed = False if raise_exception else detailed + obj_id_iter = (obj.identifier for obj in objects_to_check) + dup = [t for t, c in collections.Counter(obj_id_iter).items() if c > 1] + if len(dup) != 0: + # find the relevant top-level parents + top_par, dis_names = [], [] + for obj_id in dup: + rel_parents, dis_name = [], None + for obj in objects_to_check: + if obj.identifier == obj_id: + dis_name = obj.display_name + if obj.has_parent: + try: + par_obj = obj.top_level_parent + except AttributeError: + par_obj = obj.parent + rel_parents.append(par_obj) + top_par.append(rel_parents) + dis_names.append(dis_name) + # if a detailed dictionary is requested, then create it + if detailed: + err_list = [] + for dup_id, dis_name, rel_par in zip(dup, dis_names, top_par): + dup_dict = { + 'type': 'ValidationError', + 'code': code, + 'error_type': error_type, + 'extension_type': extension, + 'element_type': obj_name, + 'element_id': [dup_id] + } + if dis_name is not None: + dup_dict['element_name'] = [dis_name] + msg = 'There is a duplicated {} identifier: {}'.format(obj_name, dup_id) + if len(rel_par) != 0: + dup_dict['top_parents'] = [] + msg += '\n Relevant Top-Level Parents:\n' + for par_o in rel_par: + par_dict = { + 'parent_type': par_o.__class__.__name__, + 'id': par_o.identifier, + 'name': par_o.display_name + } + dup_dict['top_parents'].append(par_dict) + msg += ' {} "{}"\n'.format( + par_o.__class__.__name__, par_o.full_id) + dup_dict['message'] = msg + err_list.append(dup_dict) + return err_list + # if just an error message is requested, then build it from the information + msg = 'The following duplicated {} identifiers were found:\n'.format(obj_name) + for obj_id, rel_par in zip(dup, top_par): + obj_msg = obj_id + '\n' + if len(rel_par) != 0: + obj_msg += ' Relevant Top-Level Parents:\n' + for par_o in rel_par: + obj_msg += ' {} "{}"\n'.format( + par_o.__class__.__name__, par_o.full_id) + msg += obj_msg + msg = msg.strip() + if raise_exception: + raise ValueError(msg) + return msg + return [] if detailed else ''
+ + +
[docs]def is_equivalent(object_1, object_2): + """Check if two objects are equal with an initial check for the same instance. + """ + if object_1 is object_2: # first see if they're the same instance + return True + return object_1 == object_2 # two objects that should have == operators
+
+ +
+ +
+
+
+
+

+ Back to top + +

+

+ © Copyright 2023, Ladybug Tools.
+ Created using Sphinx 5.3.0.
+

+
+
+ + \ No newline at end of file diff --git a/docs/_modules/honeybee/colorobj.html b/docs/_modules/honeybee/colorobj.html new file mode 100644 index 00000000..356d2544 --- /dev/null +++ b/docs/_modules/honeybee/colorobj.html @@ -0,0 +1,1460 @@ + + + + + + + honeybee.colorobj — honeybee documentation + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+ +

Source code for honeybee.colorobj

+# coding=utf-8
+"""Module for coloring geometry with attributes."""
+from __future__ import division
+
+from .shade import Shade
+from .door import Door
+from .aperture import Aperture
+from .face import Face
+from .room import Room
+from .facetype import Floor
+from .search import get_attr_nested
+
+from ladybug.graphic import GraphicContainer
+from ladybug.legend import LegendParameters, LegendParametersCategorized
+from ladybug_geometry.geometry3d.pointvector import Point3D
+
+
+class _ColorObject(object):
+    """Base class for visualization objects.
+
+    Properties:
+        * legend_parameters
+        * attr_name
+        * attr_name_end
+        * attributes
+        * attributes_unique
+        * attributes_original
+        * min_point
+        * max_point
+        * graphic_container
+    """
+    __slots__ = ('_attr_name', '_legend_parameters', '_attr_name_end',
+                 '_attributes', '_attributes_unique', '_attributes_original',
+                 '_min_point', '_max_point')
+
+    def __init__(self, legend_parameters=None):
+        """Initialize ColorObject."""
+        # assign the legend parameters of this object
+        self.legend_parameters = legend_parameters
+
+        self._attr_name = None
+        self._attr_name_end = None
+        self._attributes = None
+        self._attributes_unique = None
+        self._attributes_original = None
+        self._min_point = None
+        self._max_point = None
+
+    @property
+    def legend_parameters(self):
+        """Get or set the legend parameters."""
+        return self._legend_parameters
+
+    @legend_parameters.setter
+    def legend_parameters(self, value):
+        if value is not None:
+            assert isinstance(value, LegendParameters) and not \
+                isinstance(value, LegendParametersCategorized), \
+                'Expected LegendParameters. Got {}.'.format(type(value))
+            self._legend_parameters = value
+        else:
+            self._legend_parameters = LegendParameters()
+
+    @property
+    def attr_name(self):
+        """Get a text string of an attribute that the input objects should have."""
+        return self._attr_name
+
+    @property
+    def attr_name_end(self):
+        """Get text for the last attribute in the attr_name.
+
+        Useful when attr_name is nested.
+        """
+        return self._attr_name_end
+
+    @property
+    def attributes(self):
+        """Get a tuple of text for the attributes assigned to the objects.
+
+        If the input attr_name is a valid attribute for the object but None is
+        assigned, the output will be 'None'. If the input attr_name is not valid
+        for the input object, 'N/A' will be returned.
+        """
+        return self._attributes
+
+    @property
+    def attributes_unique(self):
+        """Get a tuple of text for the unique attributes assigned to the objects."""
+        return self._attributes_unique
+
+    @property
+    def attributes_original(self):
+        """Get a tuple of objects for the attributes assigned to the objects.
+
+        These will follow the original object typing of the attribute and won't
+        be strings like the attributes.
+        """
+        return self._attributes_original
+
+    @property
+    def min_point(self):
+        """Get a Point3D for the minimum of the box around the objects."""
+        return self._min_point
+
+    @property
+    def max_point(self):
+        """Get a Point3D for the maximum of the box around the objects."""
+        return self._max_point
+
+    @property
+    def graphic_container(self):
+        """Get a ladybug GraphicContainer that relates to this object.
+
+        The GraphicContainer possesses almost all things needed to visualize the
+        ColorRooms object including the legend, value_colors, etc.
+        """
+        # produce a range of values from the collected attributes
+        attr_dict = {i: val for i, val in enumerate(self._attributes_unique)}
+        attr_dict_rev = {val: i for i, val in attr_dict.items()}
+        values = tuple(attr_dict_rev[r_attr] for r_attr in self._attributes)
+
+        # produce legend parameters with an ordinal dict for the attributes
+        l_par = self.legend_parameters.duplicate()
+        l_par.segment_count = len(self._attributes_unique)
+        l_par.ordinal_dictionary = attr_dict
+        if l_par.is_title_default:
+            l_par.title = self.attr_name_end.replace('_', ' ').title()
+
+        return GraphicContainer(values, self.min_point, self.max_point, l_par)
+
+    def _process_attribute_name(self, attr_name):
+        """Process the attribute name and assign it to this object."""
+        self._attr_name = str(attr_name)
+        at_split = self._attr_name.split('.')
+        if len(at_split) == 1:
+            self._attr_name_end = at_split[-1]
+        elif at_split[-1] == 'display_name':
+            self._attr_name_end = at_split[-2]
+        elif at_split[-1] == '__name__' and at_split[-2] == '__class__':
+            self._attr_name_end = at_split[-3]
+        else:
+            self._attr_name_end = at_split[-1]
+
+    def _process_attributes(self, hb_objs):
+        """Process the attributes of honeybee objects."""
+        nd = self.legend_parameters.decimal_count
+        attributes = [get_attr_nested(obj, self._attr_name, nd) for obj in hb_objs]
+        attributes_unique = set(attributes)
+        float_attr = [atr for atr in attributes_unique if isinstance(atr, float)]
+        str_attr = [atr for atr in attributes_unique if isinstance(atr, str)]
+        float_attr.sort()
+        str_attr.sort()
+        self._attributes = tuple(str(val) for val in attributes)
+        self._attributes_unique = tuple(str_attr) + tuple(str(val) for val in float_attr)
+        self._attributes_original = \
+            tuple(get_attr_nested(obj, self._attr_name, cast_to_str=False)
+                  for obj in hb_objs)
+
+    def _calculate_min_max(self, hb_objs):
+        """Calculate maximum and minimum Point3D for a set of rooms."""
+        st_rm_min, st_rm_max = hb_objs[0].geometry.min, hb_objs[0].geometry.max
+        min_pt = [st_rm_min.x, st_rm_min.y, st_rm_min.z]
+        max_pt = [st_rm_max.x, st_rm_max.y, st_rm_max.z]
+
+        for room in hb_objs[1:]:
+            rm_min, rm_max = room.geometry.min, room.geometry.max
+            if rm_min.x < min_pt[0]:
+                min_pt[0] = rm_min.x
+            if rm_min.y < min_pt[1]:
+                min_pt[1] = rm_min.y
+            if rm_min.z < min_pt[2]:
+                min_pt[2] = rm_min.z
+            if rm_max.x > max_pt[0]:
+                max_pt[0] = rm_max.x
+            if rm_max.y > max_pt[1]:
+                max_pt[1] = rm_max.y
+            if rm_max.z > max_pt[2]:
+                max_pt[2] = rm_max.z
+
+        self._min_point = Point3D(min_pt[0], min_pt[1], min_pt[2])
+        self._max_point = Point3D(max_pt[0], max_pt[1], max_pt[2])
+
+    def ToString(self):
+        """Overwrite .NET ToString."""
+        return self.__repr__()
+
+
+
[docs]class ColorRoom(_ColorObject): + """Object for visualizing room-level attributes. + + Args: + rooms: An array of honeybee Rooms, which will be colored with the attribute. + attr_name: A text string of an attribute that the input rooms should have. + This can have '.' that separate the nested attributes from one another. + For example, 'properties.energy.program_type'. + legend_parameters: An optional LegendParameter object to change the display + of the ColorRoom (Default: None). + + Properties: + * rooms + * attr_name + * legend_parameters + * attr_name_end + * attributes + * attributes_unique + * attributes_original + * floor_faces + * graphic_container + * min_point + * max_point + """ + __slots__ = ('_rooms',) + + def __init__(self, rooms, attr_name, legend_parameters=None): + """Initialize ColorRoom.""" + try: # check the input rooms + rooms = tuple(rooms) + except TypeError: + raise TypeError('Input rooms must be an array. Got {}.'.format(type(rooms))) + assert len(rooms) > 0, 'ColorRooms must have at least one room.' + for room in rooms: + assert isinstance(room, Room), 'Expected honeybee Room for ' \ + 'ColorRoom rooms. Got {}.'.format(type(room)) + self._rooms = rooms + self._calculate_min_max(rooms) + + # assign the legend parameters of this object + self.legend_parameters = legend_parameters + + # get the attributes of the input rooms + self._process_attribute_name(attr_name) + self._process_attributes(rooms) + + @property + def rooms(self): + """Get a tuple of honeybee Rooms assigned to this object.""" + return self._rooms + + @property + def floor_faces(self): + """Get a nested array with each sub-array having all floor Face3Ds of each room. + + This is useful for producing visualizations since coloring floors or rooms + instead of the entire room solid allows more of the model to be viewed at once. + """ + flr_faces = [] + for room in self.rooms: + flr_faces.append( + [face.geometry for face in room.faces if isinstance(face.type, Floor)]) + return flr_faces + + def __repr__(self): + """Color Room representation.""" + return 'Color Room:\n{} Rooms\n{}'.format(len(self.rooms), self.attr_name_end)
+ + +
[docs]class ColorFace(_ColorObject): + """Object for visualizing face and sub-face level attributes. + + Args: + faces: An array of honeybee Faces, Apertures, Doors, and/or shades which + will be colored with their attributes. + attr_name: A text string of an attribute that the input faces should have. + This can have '.' that separate the nested attributes from one another. + For example, 'properties.energy.construction'. + legend_parameters: An optional LegendParameter object to change the display + of the ColorFace (Default: None). + + Properties: + * faces + * attr_name + * legend_parameters + * flat_faces + * flat_geometry + * attr_name_end + * attributes + * attributes_unique + * attributes_original + * floor_faces + * graphic_container + * min_point + * max_point + """ + __slots__ = ('_faces', '_flat_faces', '_flat_geometry') + + def __init__(self, faces, attr_name, legend_parameters=None): + """Initialize ColorFace.""" + try: # check the input faces + faces = tuple(faces) + except TypeError: + raise TypeError('Input faces must be an array. Got {}.'.format(type(faces))) + assert len(faces) > 0, 'ColorFaces must have at least one face.' + flat_f = [] + for face in faces: + if isinstance(face, Face): + flat_f.append(face) + flat_f.extend(face.shades) + for ap in face.apertures: + flat_f.append(ap) + flat_f.extend(ap.shades) + for dr in face.doors: + flat_f.append(dr) + flat_f.extend(dr.shades) + elif isinstance(face, (Aperture, Door)): + flat_f.append(face) + flat_f.extend(face.shades) + elif isinstance(face, Shade): + flat_f.append(face) + else: + raise ValueError('Expected honeybee Face, Aperture, Door or Shade ' + 'for ColorFaces. Got {}.'.format(type(face))) + self._faces = faces + self._flat_faces = tuple(flat_f) + self._flat_geometry = tuple(face.geometry if not isinstance(face, Face) + else face.punched_geometry for face in flat_f) + self._calculate_min_max(faces) + + # assign the legend parameters of this object + self.legend_parameters = legend_parameters + + # get the attributes of the input faces + self._process_attribute_name(attr_name) + self._process_attributes(flat_f) + + @property + def faces(self): + """Get the honeybee Faces, Apertures, Doors and Shades assigned to this object. + """ + return self._faces + + @property + def flat_faces(self): + """Get non-nested honeybee Faces, Apertures, Doors and Shades on this object. + + The objects here align with the attributes and graphic_container colors. + """ + return self._flat_faces + + @property + def flat_geometry(self): + """Get non-nested array of faces on this object. + + The geometries here align with the attributes and graphic_container colors. + """ + return self._flat_geometry + + def __repr__(self): + """Color Room representation.""" + return 'Color Faces:\n{} Faces\n{}'.format(len(self.faces), self.attr_name_end)
+
+ +
+ +
+
+
+
+

+ Back to top + +

+

+ © Copyright 2023, Ladybug Tools.
+ Created using Sphinx 5.3.0.
+

+
+
+ + \ No newline at end of file diff --git a/docs/_modules/honeybee/config.html b/docs/_modules/honeybee/config.html new file mode 100644 index 00000000..b25027cb --- /dev/null +++ b/docs/_modules/honeybee/config.html @@ -0,0 +1,1457 @@ + + + + + + + honeybee.config — honeybee documentation + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+ +

Source code for honeybee.config

+"""Honeybee configurations.
+
+Import this into every module where access configurations are needed.
+
+Usage:
+
+.. code-block:: python
+
+    from honeybee.config import folders
+    print(folders.python_exe_path)
+    print(folders.default_simulation_folder)
+    folders.default_simulation_folder = "C:/my_sim_folder"
+"""
+import ladybug.config as lb_config
+
+import os
+import platform
+import sys
+import subprocess
+import json
+import tempfile
+
+
+
[docs]class Folders(object): + """Honeybee folders. + + Args: + config_file: The path to the config.json file from which folders are loaded. + If None, the config.json module included in this package will be used. + Default: None. + mute: If False, the paths to the various folders will be printed as they + are found. If True, no printing will occur upon initialization of this + class. Default: True. + + Properties: + * default_simulation_folder + * honeybee_core_version + * honeybee_core_version_str + * honeybee_schema_version + * honeybee_schema_version_str + * python_package_path + * python_scripts_path + * python_exe_path + * python_version + * python_version_str + * default_standards_folder + * config_file + * mute + """ + + def __init__(self, config_file=None, mute=True): + # set the mute value + self.mute = bool(mute) + + # load paths from the config JSON file + self.config_file = config_file + + # set python version to only be retrieved if requested + self._python_version = None + self._python_version_str = None + + # search for the version of honeybee-core and honeybee-schema + self._honeybee_core_version = self._find_honeybee_core_version() + self._honeybee_schema_version = self._find_honeybee_schema_version() + + @property + def default_simulation_folder(self): + """Get or set the path to the default simulation folder.""" + return self._default_simulation_folder + + @default_simulation_folder.setter + def default_simulation_folder(self, path): + if not path: # check the default location for simulations + path = self._find_default_simulation_folder() + + self._default_simulation_folder = path + + if not self.mute and self._default_simulation_folder: + print('Path to the default simulation folder is set to: ' + '{}'.format(self._default_simulation_folder)) + + @property + def honeybee_core_version(self): + """Get a tuple for the installed version of honeybee-core (eg. (1, 47, 26)). + + This will be None if the version could not be sensed (it was not installed + via pip). + """ + return self._honeybee_core_version + + @property + def honeybee_core_version_str(self): + """Get a string for the installed version of honeybee-core (eg. "1.47.26"). + + This will be None if the version could not be sensed. + """ + if self._honeybee_core_version is not None: + return '.'.join([str(item) for item in self._honeybee_core_version]) + return None + + @property + def honeybee_schema_version(self): + """Get a tuple for the installed version of honeybee-schema (eg. (1, 35, 0)). + + This will be None if the version could not be sensed (it was not installed + via pip) or if no honeybee-schema installation was found next to the + honeybee-core installation. + """ + return self._honeybee_schema_version + + @property + def honeybee_schema_version_str(self): + """Get a string for the installed version of honeybee-schema (eg. "1.35.0"). + + This will be None if the version could not be sensed. + """ + if self._honeybee_schema_version is not None: + return '.'.join([str(item) for item in self._honeybee_schema_version]) + return None + + @property + def python_package_path(self): + """Get the path to where this Python package is installed.""" + # check the ladybug_tools folder for a Python installation + py_pack = None + lb_install = lb_config.folders.ladybug_tools_folder + if os.path.isdir(lb_install): + if os.name == 'nt': + py_pack = os.path.join(lb_install, 'python', 'Lib', 'site-packages') + elif platform.system() == 'Darwin': # on mac, python version is in path + py_pack = os.path.join( + lb_install, 'python', 'lib', 'python3.7', 'site-packages') + if py_pack is not None and os.path.isdir(py_pack): + return py_pack + return os.path.split(os.path.dirname(__file__))[0] # we're on some other cPython + + @property + def python_scripts_path(self): + """Get the path to where Python CLI executable files are installed. + + This can be used to call command line interface (CLI) executable files + directly (instead of using their usual entry points). + """ + # check the ladybug_tools folder for a Python installation + lb_install = lb_config.folders.ladybug_tools_folder + if os.path.isdir(lb_install): + py_scripts = os.path.join(lb_install, 'python', 'Scripts') \ + if os.name == 'nt' else \ + os.path.join(lb_install, 'python', 'bin') + if os.path.isdir(py_scripts): + return py_scripts + sys_dir = os.path.dirname(sys.executable) # assume we are on some other cPython + return os.path.join(sys_dir, 'Scripts') if os.name == 'nt' else sys_dir + + @property + def python_exe_path(self): + """Get the path to the Python executable to be used for Ladybug Tools CLI calls. + + If a version of Python is found within the ladybug_tools installation folder, + this will be the path to that version of Python. Otherwise, it will be + assumed that this is package is installed in cPython outside of the ladybug_tools + folder and the sys.executable will be returned. + """ + # check the ladybug_tools folder for a Python installation + lb_install = lb_config.folders.ladybug_tools_folder + if os.path.isdir(lb_install): + py_exe_file = os.path.join(lb_install, 'python', 'python.exe') \ + if os.name == 'nt' else \ + os.path.join(lb_install, 'python', 'bin', 'python3') + if os.path.isfile(py_exe_file): + return py_exe_file + return sys.executable # assume we are on some other cPython + + @property + def python_version(self): + """Get a tuple for the version of python (eg. (3, 8, 2)). + + This will be None if the version could not be sensed or if no Python + installation was found. + """ + if self._python_version_str is None and self.python_exe_path: + self._python_version_from_cli() + return self._python_version + + @property + def python_version_str(self): + """Get text for the full version of python (eg."3.8.2"). + + This will be None if the version could not be sensed or if no Python + installation was found. + """ + if self._python_version_str is None and self.python_exe_path: + self._python_version_from_cli() + return self._python_version_str + + @property + def default_standards_folder(self): + """Get or set the path to the default standards library used by extensions. + """ + return self._default_standards_folder + + @default_standards_folder.setter + def default_standards_folder(self, path): + if not path: # check the default locations of the template library + path = self._find_default_standards_folder() + + # set the default_standards_folder + self._default_standards_folder = path + if path and not self.mute: + print('Path to the default_standards_folder is set to: ' + '{}'.format(self._default_standards_folder)) + + @property + def config_file(self): + """Get or set the path to the config.json file from which folders are loaded. + + Setting this to None will result in using the config.json module included + in this package. + """ + return self._config_file + + @config_file.setter + def config_file(self, cfg): + if cfg is None: + cfg = os.path.join(os.path.dirname(__file__), 'config.json') + self._load_from_file(cfg) + self._config_file = cfg + + def _load_from_file(self, file_path): + """Set all of the the properties of this object from a config JSON file. + + Args: + file_path: Path to a JSON file containing the file paths. A sample of this + JSON is the config.json file within this package. + """ + # check the default file path + assert os.path.isfile(file_path), \ + ValueError('No file found at {}'.format(file_path)) + + # set the default paths to be all blank + default_path = { + "default_simulation_folder": r'', + "default_standards_folder": r'' + } + + with open(file_path, 'r') as cfg: + try: + paths = json.load(cfg) + except Exception as e: + print('Failed to load paths from {}.\nThey will be set to defaults ' + 'instead\n{}'.format(file_path, e)) + else: + for key, p in paths.items(): + if not key.startswith('__') and p.strip(): + default_path[key] = p.strip() + + # set paths for the default_simulation_folder + self.default_simulation_folder = default_path["default_simulation_folder"] + self.default_standards_folder = default_path["default_standards_folder"] + + def _python_version_from_cli(self): + """Set this object's Python version by making a call to a Python command.""" + cmds = [self.python_exe_path, '--version'] + use_shell = True if os.name == 'nt' else False + process = subprocess.Popen(cmds, stdout=subprocess.PIPE, shell=use_shell) + stdout = process.communicate() + base_str = str(stdout[0]).replace("b'", '').replace(r"\r\n'", '') + self._python_version_str = base_str.split(' ')[-1] + try: + self._python_version = \ + tuple(int(i) for i in self._python_version_str.split('.')) + except Exception: + pass # failed to parse the version into values + + @staticmethod + def _find_default_simulation_folder(): + """Find the the default simulation folder in its usual location. + + An attempt will be made to create the directory if it does not already exist. + """ + home_folder = os.getenv('HOME') or os.path.expanduser('~') + if not os.access(home_folder, os.W_OK): + home_folder = tempfile.gettempdir() + sim_folder = os.path.join(home_folder, 'simulation') + if not os.path.isdir(sim_folder): + try: + os.makedirs(sim_folder) + except OSError as e: + if e.errno != 17: # avoid race conditions between multiple tasks + raise OSError('Failed to create default simulation ' + 'folder: %s\n%s' % (sim_folder, e)) + return sim_folder + + @staticmethod + def _find_default_standards_folder(): + """Find the user standards library in its default location. + + The %AppData%/ladybug_tools/standards folder will be checked first, which + can contain libraries that are not overwritten with the update of the + honeybee_energy package. If this is not found, the ladybug_tools/resources/ + standards/honeybee_standards folder will be checked next. If no such folder + is found, this None will be returned. + """ + # first check if there's a user-defined folder in AppData + app_folder = os.getenv('APPDATA') + if app_folder is not None: + lib_folder = os.path.join(app_folder, 'ladybug_tools', 'standards') + if os.path.isdir(lib_folder): + return lib_folder + + # then check the ladybug_tools installation folder were permanent lib is + lb_install = lb_config.folders.ladybug_tools_folder + if os.path.isdir(lb_install): + lib_folder = os.path.join( + lb_install, 'resources', 'standards', 'honeybee_standards') + if os.path.isdir(lib_folder): + return lib_folder + + # default to None if nothing was found + return None + + def _find_honeybee_core_version(self): + """Get a tuple of 3 integers for the version of honeybee_core if installed.""" + return self._find_package_version('honeybee_core') + + def _find_honeybee_schema_version(self): + """Get a tuple of 3 integers for the version of honeybee_schema if installed.""" + return self._find_package_version('honeybee_schema') + + def _find_package_version(self, package_name): + """Get a tuple of 3 integers for the version of a package.""" + hb_info_folder = None + for item in os.listdir(self.python_package_path): + if item.startswith(package_name + '-') and item.endswith('.dist-info'): + if os.path.isdir(os.path.join(self.python_package_path, item)): + hb_info_folder = item + break + if hb_info_folder is not None: + hb_info_folder = hb_info_folder.replace('.dist-info', '') + ver = ''.join(s for s in hb_info_folder if (s.isdigit() or s == '.')) + if ver: # version was found in the file path name + return tuple(int(d) for d in ver.split('.')) + return None
+ + +"""Object possesing all key folders within the configuration.""" +folders = Folders() +
+ +
+ +
+
+
+
+

+ Back to top + +

+

+ © Copyright 2023, Ladybug Tools.
+ Created using Sphinx 5.3.0.
+

+
+
+ + \ No newline at end of file diff --git a/docs/_modules/honeybee/dictutil.html b/docs/_modules/honeybee/dictutil.html new file mode 100644 index 00000000..50792e7b --- /dev/null +++ b/docs/_modules/honeybee/dictutil.html @@ -0,0 +1,1164 @@ + + + + + + + honeybee.dictutil — honeybee documentation + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+ +

Source code for honeybee.dictutil

+# coding=utf-8
+"""Utilities to convert any dictionary to Python objects.
+
+Note that importing this module will import almost all modules within the
+library in order to be able to re-serialize almost any dictionary produced
+from the library.
+"""
+from honeybee.model import Model
+from honeybee.room import Room
+from honeybee.face import Face
+from honeybee.aperture import Aperture
+from honeybee.door import Door
+from honeybee.shade import Shade
+import honeybee.boundarycondition as hbc
+
+
+
[docs]def dict_to_object(honeybee_dict, raise_exception=True): + """Re-serialize a dictionary of almost any object within honeybee. + + This includes any Model, Room, Face, Aperture, Door, Shade, or boundary + condition object. + + Args: + honeybee_dict: A dictionary of any Honeybee object. Note + that this should be a non-abridged dictionary to be valid. + raise_exception: Boolean to note whether an exception should be raised + if the object is not identified as a part of honeybee. + Default: True. + + Returns: + A Python object derived from the input honeybee_dict. + """ + try: # get the type key from the dictionary + obj_type = honeybee_dict['type'] + except KeyError: + raise ValueError('Honeybee dictionary lacks required "type" key.') + + if obj_type == 'Model': + return Model.from_dict(honeybee_dict) + elif obj_type == 'Room': + return Room.from_dict(honeybee_dict) + elif obj_type == 'Face': + return Face.from_dict(honeybee_dict) + elif obj_type == 'Aperture': + return Aperture.from_dict(honeybee_dict) + elif obj_type == 'Door': + return Door.from_dict(honeybee_dict) + elif obj_type == 'Shade': + return Shade.from_dict(honeybee_dict) + elif hasattr(hbc, obj_type): + bc_class = getattr(hbc, obj_type) + return bc_class.from_dict(honeybee_dict) + elif raise_exception: + raise ValueError('{} is not a recognized honeybee object'.format(obj_type))
+
+ +
+ +
+
+
+
+

+ Back to top + +

+

+ © Copyright 2023, Ladybug Tools.
+ Created using Sphinx 5.3.0.
+

+
+
+ + \ No newline at end of file diff --git a/docs/_modules/honeybee/door.html b/docs/_modules/honeybee/door.html new file mode 100644 index 00000000..229d30c9 --- /dev/null +++ b/docs/_modules/honeybee/door.html @@ -0,0 +1,1745 @@ + + + + + + + honeybee.door — honeybee documentation + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+ +

Source code for honeybee.door

+# coding: utf-8
+"""Honeybee Door."""
+from __future__ import division
+import math
+
+from ladybug_geometry.geometry2d.pointvector import Vector2D
+from ladybug_geometry.geometry3d.pointvector import Point3D
+from ladybug_geometry.geometry3d.face import Face3D
+from ladybug.color import Color
+
+from ._basewithshade import _BaseWithShade
+from .typing import clean_string
+from .properties import DoorProperties
+from .boundarycondition import boundary_conditions, Outdoors, Surface
+from .shade import Shade
+import honeybee.writer.door as writer
+
+
+
[docs]class Door(_BaseWithShade): + """A single planar Door in a Face. + + Args: + identifier: Text string for a unique Door ID. Must be < 100 characters and + not contain any spaces or special characters. + geometry: A ladybug-geometry Face3D. + boundary_condition: Boundary condition object (Outdoors, Surface, etc.). + Default: Outdoors. + is_glass: Boolean to note whether this object is a glass door as opposed + to an opaque door. Default: False. + + Properties: + * identifier + * display_name + * boundary_condition + * is_glass + * indoor_shades + * outdoor_shades + * parent + * top_level_parent + * has_parent + * geometry + * vertices + * upper_left_vertices + * triangulated_mesh3d + * normal + * center + * area + * perimeter + * min + * max + * altitude + * azimuth + * type_color + * bc_color + * user_data + """ + __slots__ = ('_geometry', '_parent', '_boundary_condition', '_is_glass') + TYPE_COLORS = { + False: Color(160, 150, 100), + True: Color(128, 204, 255, 100) + } + BC_COLORS = { + 'Outdoors': Color(128, 204, 255), + 'Surface': Color(0, 190, 0) + } + + def __init__(self, identifier, geometry, boundary_condition=None, is_glass=False): + """A single planar Door in a Face.""" + _BaseWithShade.__init__(self, identifier) # process the identifier + + # process the geometry + assert isinstance(geometry, Face3D), \ + 'Expected ladybug_geometry Face3D. Got {}'.format(type(geometry)) + self._geometry = geometry + self._parent = None # _parent will be set when the Face is added to a Face + + # process the boundary condition and type + self.boundary_condition = boundary_condition or boundary_conditions.outdoors + self.is_glass = is_glass + + # initialize properties for extensions + self._properties = DoorProperties(self) + +
[docs] @classmethod + def from_dict(cls, data): + """Initialize an Door from a dictionary. + + Args: + data: A dictionary representation of an Door object. + """ + try: + # check the type of dictionary + assert data['type'] == 'Door', 'Expected Door dictionary. ' \ + 'Got {}.'.format(data['type']) + + # serialize the door + is_glass = data['is_glass'] if 'is_glass' in data else False + if data['boundary_condition']['type'] == 'Outdoors': + boundary_condition = Outdoors.from_dict(data['boundary_condition']) + elif data['boundary_condition']['type'] == 'Surface': + boundary_condition = Surface.from_dict(data['boundary_condition'], True) + else: + raise ValueError( + 'Boundary condition "{}" is not supported for Door.'.format( + data['boundary_condition']['type'])) + door = cls(data['identifier'], Face3D.from_dict(data['geometry']), + boundary_condition, is_glass) + if 'display_name' in data and data['display_name'] is not None: + door.display_name = data['display_name'] + if 'user_data' in data and data['user_data'] is not None: + door.user_data = data['user_data'] + door._recover_shades_from_dict(data) + + # assign extension properties + if data['properties']['type'] == 'DoorProperties': + door.properties._load_extension_attr_from_dict(data['properties']) + return door + except Exception as e: + cls._from_dict_error_message(data, e)
+ +
[docs] @classmethod + def from_vertices(cls, identifier, vertices, boundary_condition=None, + is_glass=False): + """Create a Door from vertices with each vertex as an iterable of 3 floats. + + Args: + identifier: Text string for a unique Door ID. Must be < 100 characters and + not contain any spaces or special characters. + vertices: A flattened list of 3 or more vertices as (x, y, z). + boundary_condition: Boundary condition object (eg. Outdoors, Surface). + Default: Outdoors. + is_glass: Boolean to note whether this object is a glass door as opposed + to an opaque door. Default: False. + """ + geometry = Face3D(tuple(Point3D(*v) for v in vertices)) + return cls(identifier, geometry, boundary_condition, is_glass)
+ + @property + def boundary_condition(self): + """Get or set the boundary condition of this door.""" + return self._boundary_condition + + @boundary_condition.setter + def boundary_condition(self, value): + if not isinstance(value, Outdoors): + if isinstance(value, Surface): + assert len(value.boundary_condition_objects) == 3, 'Surface boundary ' \ + 'condition for Door must have 3 boundary_condition_objects.' + else: + raise ValueError('Door only supports Outdoor or Surface boundary ' + 'condition. Got {}'.format(type(value))) + self._boundary_condition = value + + @property + def is_glass(self): + """Get or set a boolean to note whether this object is a glass door.""" + return self._is_glass + + @is_glass.setter + def is_glass(self, value): + try: + self._is_glass = bool(value) + except TypeError: + raise TypeError( + 'Expected boolean for Door.is_glass. Got {}.'.format(value)) + + @property + def parent(self): + """Get the parent Face if assigned. None if not assigned.""" + return self._parent + + @property + def top_level_parent(self): + """Get the top-level parent object if assigned. + + This will be a Room if there is a parent Face that has a parent Room and + will be a Face if the parent Face is orphaned. Will be None if no parent + is assigned. + """ + if self.has_parent: + if self._parent.has_parent: + return self._parent._parent + return self._parent + return None + + @property + def has_parent(self): + """Get a boolean noting whether this Door has a parent Face.""" + return self._parent is not None + + @property + def geometry(self): + """Get a ladybug_geometry Face3D object representing the door.""" + return self._geometry + + @property + def vertices(self): + """Get a list of vertices for the door (in counter-clockwise order).""" + return self._geometry.vertices + + @property + def upper_left_vertices(self): + """Get a list of vertices starting from the upper-left corner. + + This property should be used when exporting to EnergyPlus / OpenStudio. + """ + return self._geometry.upper_left_counter_clockwise_vertices + + @property + def triangulated_mesh3d(self): + """Get a ladybug_geometry Mesh3D of the door geometry composed of triangles. + + In EnergyPlus / OpenStudio workflows, this property is used to subdivide + the door when it has more than 4 vertices. This is necessary since + EnergyPlus cannot accept sub-faces with more than 4 vertices. + """ + return self._geometry.triangulated_mesh3d + + @property + def normal(self): + """Get a ladybug_geometry Vector3D for the direction the door is pointing. + """ + return self._geometry.normal + + @property + def center(self): + """Get a ladybug_geometry Point3D for the center of the door. + + Note that this is the center of the bounding rectangle around this geometry + and not the area centroid. + """ + return self._geometry.center + + @property + def area(self): + """Get the area of the door.""" + return self._geometry.area + + @property + def perimeter(self): + """Get the perimeter of the door.""" + return self._geometry.perimeter + + @property + def min(self): + """Get a Point3D for the minimum of the bounding box around the object.""" + return self._min_with_shades(self._geometry) + + @property + def max(self): + """Get a Point3D for the maximum of the bounding box around the object.""" + return self._max_with_shades(self._geometry) + + @property + def altitude(self): + """Get the altitude of the geometry between +90 (up) and -90 (down).""" + return math.degrees(self._geometry.altitude) + + @property + def azimuth(self): + """Get the azimuth of the geometry, between 0 and 360. + + Given Y-axis as North, 0 = North, 90 = East, 180 = South, 270 = West + This will be zero if the Face3D is perfectly horizontal. + """ + return math.degrees(self._geometry.azimuth) + + @property + def type_color(self): + """Get a Color to be used in visualizations by type.""" + return self.TYPE_COLORS[self.is_glass] + + @property + def bc_color(self): + """Get a Color to be used in visualizations by boundary condition.""" + return self.BC_COLORS[self.boundary_condition.name] + +
[docs] def horizontal_orientation(self, north_vector=Vector2D(0, 1)): + """Get a number between 0 and 360 for the orientation of the door in degrees. + + 0 = North, 90 = East, 180 = South, 270 = West + + Args: + north_vector: A ladybug_geometry Vector2D for the north direction. + Default is the Y-axis (0, 1). + """ + return math.degrees( + north_vector.angle_clockwise(Vector2D(self.normal.x, self.normal.y)))
+ +
[docs] def cardinal_direction(self, north_vector=Vector2D(0, 1)): + """Get text description for the cardinal direction that the door is pointing. + + Will be one of the following: ('North', 'NorthEast', 'East', 'SouthEast', + 'South', 'SouthWest', 'West', 'NorthWest'). + + Args: + north_vector: A ladybug_geometry Vector2D for the north direction. + Default is the Y-axis (0, 1). + """ + orient = self.horizontal_orientation(north_vector) + orient_text = ('North', 'NorthEast', 'East', 'SouthEast', 'South', + 'SouthWest', 'West', 'NorthWest') + angles = (22.5, 67.5, 112.5, 157.5, 202.5, 247.5, 292.5, 337.5) + for i, ang in enumerate(angles): + if orient < ang: + return orient_text[i] + return orient_text[0]
+ +
[docs] def add_prefix(self, prefix): + """Change the identifier of this object and child objects by inserting a prefix. + + This is particularly useful in workflows where you duplicate and edit + a starting object and then want to combine it with the original object + into one Model (like making a model of repeated rooms) since all objects + within a Model must have unique identifiers. + + Args: + prefix: Text that will be inserted at the start of this object's + (and child objects') identifier and display_name. It is recommended + that this prefix be short to avoid maxing out the 100 allowable + characters for honeybee identifiers. + """ + self._identifier = clean_string('{}_{}'.format(prefix, self.identifier)) + self.display_name = '{}_{}'.format(prefix, self.display_name) + self.properties.add_prefix(prefix) + self._add_prefix_shades(prefix) + if isinstance(self._boundary_condition, Surface): + new_bc_objs = (clean_string('{}_{}'.format(prefix, adj_name)) for adj_name + in self._boundary_condition._boundary_condition_objects) + self._boundary_condition = Surface(new_bc_objs, True)
+ +
[docs] def set_adjacency(self, other_door): + """Set this door to be adjacent to another (and vice versa). + + Note that this method does not verify whether the other_door geometry is + co-planar or compatible with this one so it is recommended that a test + be performed before using this method in order to verify these criteria. + The Face3D.is_centered_adjacent() or the Face3D.is_geometrically_equivalent() + methods are both suitable for this purpose. + + Args: + other_door: Another Door object to be set adjacent to this one. + """ + assert isinstance(other_door, Door), \ + 'Expected Door. Got {}.'.format(type(other_door)) + assert other_door.is_glass is self.is_glass, \ + 'Adjacent doors must have matching is_glass properties.' + self._boundary_condition = boundary_conditions.surface(other_door, True) + other_door._boundary_condition = boundary_conditions.surface(self, True)
+ +
[docs] def overhang(self, depth, angle=0, indoor=False, tolerance=0.01, base_name=None): + """Add a single overhang for this Door. Can represent entryway awnings. + + Args: + depth: A number for the overhang depth. + angle: A number for the for an angle to rotate the overhang in degrees. + Positive numbers indicate a downward rotation while negative numbers + indicate an upward rotation. Default is 0 for no rotation. + indoor: Boolean for whether the overhang should be generated facing the + opposite direction of the aperture normal (typically meaning + indoor geometry). Default: False. + tolerance: An optional value to return None if the overhang has a length less + than the tolerance. Default: 0.01, suitable for objects in meters. + base_name: Optional base name for the shade objects. If None, the default + is InOverhang or OutOverhang depending on whether indoor is True. + + Returns: + A list of the new Shade objects that have been generated. + """ + # get a name for the shade + if base_name is None: + base_name = 'InOverhang' if indoor else 'OutOverhang' + shd_name_base = '{}_' + str(base_name) + '{}' + + # create the shade geometry + angle = math.radians(angle) + dr_geo = self.geometry if indoor is False else self.geometry.flip() + shade_faces = dr_geo.contour_fins_by_number( + 1, depth, 0, angle, Vector2D(0, 1), False, tolerance) + + # create the Shade objects + overhang = [] + for i, shade_geo in enumerate(shade_faces): + overhang.append(Shade(shd_name_base.format(self.identifier, i), shade_geo)) + if indoor: + self.add_indoor_shades(overhang) + else: + self.add_outdoor_shades(overhang) + return overhang
+ +
[docs] def move(self, moving_vec): + """Move this Door along a vector. + + Args: + moving_vec: A ladybug_geometry Vector3D with the direction and distance + to move the face. + """ + self._geometry = self.geometry.move(moving_vec) + self.move_shades(moving_vec) + self.properties.move(moving_vec) + self._reset_parent_geometry()
+ +
[docs] def rotate(self, axis, angle, origin): + """Rotate this Door by a certain angle around an axis and origin. + + Args: + axis: A ladybug_geometry Vector3D axis representing the axis of rotation. + angle: An angle for rotation in degrees. + origin: A ladybug_geometry Point3D for the origin around which the + object will be rotated. + """ + self._geometry = self.geometry.rotate(axis, math.radians(angle), origin) + self.rotate_shades(axis, angle, origin) + self.properties.rotate(axis, angle, origin) + self._reset_parent_geometry()
+ +
[docs] def rotate_xy(self, angle, origin): + """Rotate this Door counterclockwise in the world XY plane by a certain angle. + + Args: + angle: An angle in degrees. + origin: A ladybug_geometry Point3D for the origin around which the + object will be rotated. + """ + self._geometry = self.geometry.rotate_xy(math.radians(angle), origin) + self.rotate_xy_shades(angle, origin) + self.properties.rotate_xy(angle, origin) + self._reset_parent_geometry()
+ +
[docs] def reflect(self, plane): + """Reflect this Door across a plane. + + Args: + plane: A ladybug_geometry Plane across which the object will + be reflected. + """ + self._geometry = self.geometry.reflect(plane.n, plane.o) + self.reflect_shades(plane) + self.properties.reflect(plane) + self._reset_parent_geometry()
+ +
[docs] def scale(self, factor, origin=None): + """Scale this Door by a factor from an origin point. + + Args: + factor: A number representing how much the object should be scaled. + origin: A ladybug_geometry Point3D representing the origin from which + to scale. If None, it will be scaled from the World origin (0, 0, 0). + """ + self._geometry = self.geometry.scale(factor, origin) + self.scale_shades(factor, origin) + self.properties.scale(factor, origin) + self._reset_parent_geometry()
+ +
[docs] def remove_colinear_vertices(self, tolerance=0.01): + """Remove all colinear and duplicate vertices from this object's geometry. + + Note that this does not affect any assigned Shades. + + Args: + tolerance: The minimum distance between a vertex and the boundary segments + at which point the vertex is considered colinear. Default: 0.01, + suitable for objects in meters. + """ + try: + self._geometry = self.geometry.remove_colinear_vertices(tolerance) + except AssertionError as e: # usually a sliver face of some kind + raise ValueError( + 'Door "{}" is invalid with dimensions less than the ' + 'tolerance.\n{}'.format(self.full_id, e))
+ +
[docs] def is_geo_equivalent(self, door, tolerance=0.01): + """Get a boolean for whether this object is geometrically equivalent to another. + + The total number of vertices and the ordering of these vertices can be + different but the geometries must share the same center point and be + next to one another to within the tolerance. + + Args: + door: Another Door for which geometric equivalency will be tested. + tolerance: The minimum difference between the coordinate values of two + vertices at which they can be considered geometrically equivalent. + + Returns: + True if geometrically equivalent. False if not geometrically equivalent. + """ + meta_1 = (self.display_name, self.is_glass, self.boundary_condition) + meta_2 = (door.display_name, door.is_glass, door.boundary_condition) + if meta_1 != meta_2: + return False + if abs(self.area - door.area) > tolerance * self.area: + return False + if not self.geometry.is_centered_adjacent(door.geometry, tolerance): + return False + if not self._are_shades_equivalent(door, tolerance): + return False + return True
+ +
[docs] def check_planar(self, tolerance=0.01, raise_exception=True, detailed=False): + """Check whether all of the Door's vertices lie within the same plane. + + Args: + tolerance: The minimum distance between a given vertex and a the + object's plane at which the vertex is said to lie in the plane. + Default: 0.01, suitable for objects in meters. + raise_exception: Boolean to note whether an ValueError should be + raised if a vertex does not lie within the object's plane. + detailed: Boolean for whether the returned object is a detailed list of + dicts with error info or a string with a message. (Default: False). + + Returns: + A string with the message or a list with a dictionary if detailed is True. + """ + try: + self.geometry.check_planar(tolerance, raise_exception=True) + except ValueError as e: + msg = 'Door "{}" is not planar.\n{}'.format(self.full_id, e) + full_msg = self._validation_message( + msg, raise_exception, detailed, '000101', + error_type='Non-Planar Geometry') + if detailed: # add the out-of-plane points to helper_geometry + help_pts = [ + p.to_dict() for p in self.geometry.non_planar_vertices(tolerance) + ] + full_msg[0]['helper_geometry'] = help_pts + return full_msg + return [] if detailed else ''
+ +
[docs] def check_self_intersecting(self, tolerance=0.01, raise_exception=True, + detailed=False): + """Check whether the edges of the Door intersect one another (like a bowtie). + + Note that objects that have duplicate vertices will not be considered + self-intersecting and are valid in honeybee. + + Args: + tolerance: The minimum difference between the coordinate values of two + vertices at which they can be considered equivalent. Default: 0.01, + suitable for objects in meters. + raise_exception: If True, a ValueError will be raised if the object + intersects with itself. Default: True. + detailed: Boolean for whether the returned object is a detailed list of + dicts with error info or a string with a message. (Default: False). + + Returns: + A string with the message or a list with a dictionary if detailed is True. + """ + if self.geometry.is_self_intersecting: + msg = 'Door "{}" has self-intersecting edges.'.format(self.full_id) + try: # see if it is self-intersecting because of a duplicate vertex + new_geo = self.geometry.remove_duplicate_vertices(tolerance) + if not new_geo.is_self_intersecting: + return [] if detailed else '' # valid with removed dup vertex + except AssertionError: + return [] if detailed else '' # degenerate geometry + full_msg = self._validation_message( + msg, raise_exception, detailed, '000102', + error_type='Self-Intersecting Geometry') + if detailed: # add the self-intersection points to helper_geometry + help_pts = [p.to_dict() for p in self.geometry.self_intersection_points] + full_msg[0]['helper_geometry'] = help_pts + return full_msg + return [] if detailed else ''
+ +
[docs] def display_dict(self): + """Get a list of DisplayFace3D dictionaries for visualizing the object.""" + base = [self._display_face(self.geometry, self.type_color)] + for shd in self.shades: + base.extend(shd.display_dict()) + return base
+ + @property + def to(self): + """Door writer object. + + Use this method to access Writer class to write the door in different formats. + + Usage: + + .. code-block:: python + + door.to.idf(door) -> idf string. + door.to.radiance(door) -> Radiance string. + """ + return writer + +
[docs] def to_dict(self, abridged=False, included_prop=None, include_plane=True): + """Return Door as a dictionary. + + Args: + abridged: Boolean to note whether the extension properties of the + object (ie. materials, constructions) should be included in detail + (False) or just referenced by identifier (True). (Default: False). + included_prop: List of properties to filter keys that must be included in + output dictionary. For example ['energy'] will include 'energy' key if + available in properties to_dict. By default all the keys will be + included. To exclude all the keys from extensions use an empty list. + include_plane: Boolean to note wether the plane of the Face3D should be + included in the output. This can preserve the orientation of the + X/Y axes of the plane but is not required and can be removed to + keep the dictionary smaller. (Default: True). + """ + base = {'type': 'Door'} + base['identifier'] = self.identifier + base['display_name'] = self.display_name + base['properties'] = self.properties.to_dict(abridged, included_prop) + enforce_upper_left = True if 'energy' in base['properties'] else False + base['geometry'] = self._geometry.to_dict(include_plane, enforce_upper_left) + base['is_glass'] = self.is_glass + if isinstance(self.boundary_condition, Outdoors) and \ + 'energy' in base['properties']: + base['boundary_condition'] = self.boundary_condition.to_dict(full=True) + else: + base['boundary_condition'] = self.boundary_condition.to_dict() + self._add_shades_to_dict(base, abridged, included_prop, include_plane) + if self.user_data is not None: + base['user_data'] = self.user_data + return base
+ + def _reset_parent_geometry(self): + """Reset parent punched_geometry in the case that the object is transformed.""" + if self.has_parent: + self._parent._punched_geometry = None + + def __copy__(self): + new_door = Door(self.identifier, self.geometry, self.boundary_condition, + self.is_glass) + new_door._display_name = self._display_name + new_door._user_data = None if self.user_data is None else self.user_data.copy() + self._duplicate_child_shades(new_door) + new_door._properties._duplicate_extension_attr(self._properties) + return new_door + + def __repr__(self): + return 'Door: %s' % self.display_name
+
+ +
+ +
+
+
+
+

+ Back to top + +

+

+ © Copyright 2023, Ladybug Tools.
+ Created using Sphinx 5.3.0.
+

+
+
+ + \ No newline at end of file diff --git a/docs/_modules/honeybee/extensionutil.html b/docs/_modules/honeybee/extensionutil.html new file mode 100644 index 00000000..40291828 --- /dev/null +++ b/docs/_modules/honeybee/extensionutil.html @@ -0,0 +1,1318 @@ + + + + + + + honeybee.extensionutil — honeybee documentation + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+ +

Source code for honeybee.extensionutil

+# coding: utf-8
+"""A series of utility functions that are useful across several honeybee extensions."""
+
+
+
[docs]def model_extension_dicts(data, extension_key, room_ext_dicts, face_ext_dicts, + shade_ext_dicts, aperture_ext_dicts, door_ext_dicts): + """Get all Model property dictionaries of an extension organized by geometry type. + + Note that the order in which dictionaries appear in the output lists is the + same order as the geometry objects appear when requested from the model. + For example, the shade_ext_dicts align with the model.shades. + + Args: + data: A dictionary representation of an entire honeybee-core Model. + extension_key: Text for the key of the extension (eg. "energy", "radiance"). + + Returns: + A tuple with five elements + + - room_ext_dicts: A list of Room extension property dictionaries that + align with the serialized model.rooms. + + - face_ext_dicts: A list of Face extension property dictionaries that + align with the serialized model.faces. + + - shade_ext_dicts: A list of Shade extension property dictionaries that + align with the serialized model.shades plus the model.shade_meshes. + + - aperture_ext_dicts: A list of Aperture extension property dictionaries that + align with the serialized model.apertures. + + - door_ext_dicts: A list of Door extension property dictionaries that + align with the serialized model.doors. + """ + assert data['type'] == 'Model', \ + 'Expected Model dictionary. Got {}.'.format(data['type']) + + # loop through the model dictionary using the same logic that the + # model does when you request rooms, faces, shades, apertures and doors. + if 'rooms' in data and data['rooms'] is not None: + room_extension_dicts(data['rooms'], extension_key, room_ext_dicts, + face_ext_dicts, shade_ext_dicts, aperture_ext_dicts, + door_ext_dicts) + if 'orphaned_faces' in data and data['orphaned_faces'] is not None: + face_extension_dicts(data['orphaned_faces'], extension_key, face_ext_dicts, + shade_ext_dicts, aperture_ext_dicts, door_ext_dicts) + if 'orphaned_apertures' in data and data['orphaned_apertures'] is not None: + aperture_extension_dicts(data['orphaned_apertures'], extension_key, + aperture_ext_dicts, shade_ext_dicts) + if 'orphaned_doors' in data and data['orphaned_doors'] is not None: + door_extension_dicts(data['orphaned_doors'], extension_key, door_ext_dicts, + shade_ext_dicts) + if 'orphaned_shades' in data and data['orphaned_shades'] is not None: + shade_extension_dicts(data['orphaned_shades'], extension_key, shade_ext_dicts) + if 'shade_meshes' in data and data['shade_meshes'] is not None: + shade_extension_dicts(data['shade_meshes'], extension_key, shade_ext_dicts) + + return room_ext_dicts, face_ext_dicts, shade_ext_dicts, \ + aperture_ext_dicts, door_ext_dicts
+ + +
[docs]def room_extension_dicts(room_list, extension_key, room_ext_dicts, face_ext_dicts, + shade_ext_dicts, aperture_ext_dicts, door_ext_dicts): + """Get all Room property dictionaries of an extension organized by geometry type. + + Args: + room_list: A list of Room dictionaries. + extension_key: Text for the key of the extension (eg. "energy", "radiance"). + + Returns: + A tuple with five elements + + - room_ext_dicts: A list with the Room extension property dictionaries. + + - face_ext_dicts: A list with Face extension property dictionaries. + + - shade_ext_dicts: A list with Shade extension property dictionaries. + + - aperture_ext_dicts: A list with Aperture extension property dictionaries. + + - door_ext_dicts: A list with Door extension property dictionaries. + """ + for room_dict in room_list: + try: + room_ext_dicts.append(room_dict['properties'][extension_key]) + except KeyError: + room_ext_dicts.append(None) + if 'outdoor_shades' in room_dict and room_dict['outdoor_shades'] is not None: + shade_extension_dicts(room_dict['outdoor_shades'], extension_key, + shade_ext_dicts) + if 'indoor_shades' in room_dict and room_dict['indoor_shades'] is not None: + shade_extension_dicts(room_dict['indoor_shades'], extension_key, + shade_ext_dicts) + face_extension_dicts(room_dict['faces'], extension_key, face_ext_dicts, + shade_ext_dicts, aperture_ext_dicts, door_ext_dicts) + return room_ext_dicts, face_ext_dicts, shade_ext_dicts, \ + aperture_ext_dicts, door_ext_dicts
+ + +
[docs]def face_extension_dicts(face_list, extension_key, face_ext_dicts, + shade_ext_dicts, aperture_ext_dicts, door_ext_dicts): + """Get all Face property dictionaries of an extension organized by geometry type. + + Args: + face_list: A list of Room dictionaries. + extension_key: Text for the key of the extension (eg. "energy", "radiance"). + + Returns: + A tuple with four elements + + - face_ext_dicts: A list with Face extension property dictionaries. + + - shade_ext_dicts: A list with Shade extension property dictionaries. + + - aperture_ext_dicts: A list with Aperture extension property dictionaries. + + - door_ext_dicts: A list with Door extension property dictionaries. + """ + for face_dict in face_list: + try: + face_ext_dicts.append(face_dict['properties'][extension_key]) + except KeyError: + face_ext_dicts.append(None) + if 'outdoor_shades' in face_dict and face_dict['outdoor_shades'] is not None: + shade_extension_dicts(face_dict['outdoor_shades'], extension_key, + shade_ext_dicts) + if 'indoor_shades' in face_dict and face_dict['indoor_shades'] is not None: + shade_extension_dicts(face_dict['indoor_shades'], extension_key, + shade_ext_dicts) + if 'apertures' in face_dict and face_dict['apertures'] is not None: + aperture_extension_dicts(face_dict['apertures'], extension_key, + aperture_ext_dicts, shade_ext_dicts) + if 'doors' in face_dict and face_dict['doors'] is not None: + door_extension_dicts(face_dict['doors'], extension_key, + door_ext_dicts, shade_ext_dicts) + return face_ext_dicts, shade_ext_dicts, aperture_ext_dicts, door_ext_dicts
+ + +
[docs]def shade_extension_dicts(shade_list, extension_key, shade_ext_dicts): + """Get all Shade property dictionaries of an extension organized by geometry type. + + Args: + shade_list: A list of Shade dictionaries. + extension_key: Text for the key of the extension (eg. "energy", "radiance"). + + Returns: + shade_ext_dicts -- A list with Shade extension property dictionaries. + """ + for shd_dict in shade_list: + try: + shade_ext_dicts.append(shd_dict['properties'][extension_key]) + except KeyError: + shade_ext_dicts.append(None) + return shade_ext_dicts
+ + +
[docs]def aperture_extension_dicts(aperture_list, extension_key, aperture_ext_dicts, + shade_ext_dicts): + """Get all Aperture property dictionaries of an extension organized by geometry type. + + Args: + aperture_list: A list of Aperture dictionaries. + extension_key: Text for the key of the extension (eg. "energy", "radiance"). + + Returns: + A tuple with two elements + + - aperture_ext_dicts: A list with Aperture extension property dictionaries. + + - shade_ext_dicts: A list with Shade extension property dictionaries. + """ + for ap_dict in aperture_list: + try: + aperture_ext_dicts.append(ap_dict['properties'][extension_key]) + except KeyError: + aperture_ext_dicts.append(None) + if 'outdoor_shades' in ap_dict and ap_dict['outdoor_shades'] is not None: + shade_extension_dicts(ap_dict['outdoor_shades'], extension_key, shade_ext_dicts) + if 'indoor_shades' in ap_dict and ap_dict['indoor_shades'] is not None: + shade_extension_dicts(ap_dict['indoor_shades'], extension_key, shade_ext_dicts) + return aperture_ext_dicts, shade_ext_dicts
+ + +
[docs]def door_extension_dicts(door_list, extension_key, door_ext_dicts, + shade_ext_dicts): + """Get all Door property dictionaries of an extension organized by geometry type. + + Args: + door_list: A list of Door dictionaries. + extension_key: Text for the key of the extension (eg. "energy", "radiance"). + + Returns: + A tuple with two elements + + - door_ext_dicts: A list with Door extension property dictionaries. + + - shade_ext_dicts: A list with Shade extension property dictionaries. + """ + for dr_dict in door_list: + try: + door_ext_dicts.append(dr_dict['properties'][extension_key]) + except KeyError: + door_ext_dicts.append(None) + if 'outdoor_shades' in dr_dict and dr_dict['outdoor_shades'] is not None: + shade_extension_dicts(dr_dict['outdoor_shades'], extension_key, shade_ext_dicts) + if 'indoor_shades' in dr_dict and dr_dict['indoor_shades'] is not None: + shade_extension_dicts(dr_dict['indoor_shades'], extension_key, shade_ext_dicts) + return door_ext_dicts, shade_ext_dicts
+
+ +
+ +
+
+
+
+

+ Back to top + +

+

+ © Copyright 2023, Ladybug Tools.
+ Created using Sphinx 5.3.0.
+

+
+
+ + \ No newline at end of file diff --git a/docs/_modules/honeybee/face.html b/docs/_modules/honeybee/face.html new file mode 100644 index 00000000..11f44457 --- /dev/null +++ b/docs/_modules/honeybee/face.html @@ -0,0 +1,2947 @@ + + + + + + + honeybee.face — honeybee documentation + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+ +

Source code for honeybee.face

+# coding: utf-8
+"""Honeybee Face."""
+from __future__ import division
+import math
+
+from ladybug_geometry.geometry2d import Vector2D, Point2D, Polygon2D, Mesh2D
+from ladybug_geometry.geometry3d import Vector3D, Point3D, Plane, Face3D
+from ladybug.color import Color
+
+from ._basewithshade import _BaseWithShade
+from .typing import clean_string, invalid_dict_error
+from .properties import FaceProperties
+from .facetype import face_types, get_type_from_normal, AirBoundary, Floor, RoofCeiling
+from .boundarycondition import boundary_conditions, get_bc_from_position, \
+    _BoundaryCondition, Outdoors, Surface, Ground
+from .shade import Shade
+from .aperture import Aperture
+from .door import Door
+import honeybee.boundarycondition as hbc
+import honeybee.writer.face as writer
+
+
+
[docs]class Face(_BaseWithShade): + """A single planar face. + + Args: + identifier: Text string for a unique Face ID. Must be < 100 characters and + not contain any spaces or special characters. + geometry: A ladybug-geometry Face3D. + type: Face type. Default varies depending on the direction that + the Face geometry is points. + RoofCeiling = pointing upward within 30 degrees + Wall = oriented vertically within +/- 60 degrees + Floor = pointing downward within 30 degrees + boundary_condition: Face boundary condition (Outdoors, Ground, etc.) + Default is Outdoors unless all vertices of the geometry lie + below the below the XY plane, in which case it will be set to Ground. + + Properties: + * identifier + * display_name + * type + * boundary_condition + * apertures + * doors + * sub_faces + * indoor_shades + * outdoor_shades + * parent + * has_parent + * has_sub_faces + * can_be_ground + * geometry + * punched_geometry + * vertices + * punched_vertices + * upper_left_vertices + * normal + * center + * area + * perimeter + * min + * max + * aperture_area + * aperture_ratio + * altitude + * azimuth + * type_color + * bc_color + * user_data + """ + TYPES = face_types + __slots__ = ('_geometry', '_parent', '_punched_geometry', + '_apertures', '_doors', '_type', '_boundary_condition') + TYPE_COLORS = { + 'Wall': Color(230, 180, 60), + 'RoofCeiling': Color(128, 20, 20), + 'Floor': Color(128, 128, 128), + 'AirBoundary': Color(255, 255, 200, 100), + 'InteriorWall': Color(230, 215, 150), + 'InteriorRoofCeiling': Color(255, 128, 128), + 'InteriorFloor': Color(255, 128, 128), + 'InteriorAirBoundary': Color(255, 255, 200, 100) + } + BC_COLORS = { + 'Outdoors': Color(64, 180, 255), + 'Surface': Color(0, 128, 0), + 'Ground': Color(165, 82, 0), + 'Adiabatic': Color(255, 128, 128), + 'Other': Color(255, 255, 200) + } + + def __init__(self, identifier, geometry, type=None, boundary_condition=None): + """A single planar face.""" + _BaseWithShade.__init__(self, identifier) # process the identifier + + # process the geometry + assert isinstance(geometry, Face3D), \ + 'Expected ladybug_geometry Face3D. Got {}'.format(geometry) + self._geometry = geometry + self._parent = None # _parent will be set when the Face is added to a Room + # initialize with no apertures/doors (they can be assigned later) + self._punched_geometry = None + self._apertures = [] + self._doors = [] + + # initialize properties for extensions + self._properties = FaceProperties(self) + + # set face type based on normal if not provided + if type is not None: + assert type in self.TYPES, '{} is not a valid face type.'.format(type) + self._type = type or get_type_from_normal(geometry.normal) + + # set boundary condition by the relation to a zero ground plane if not provided + self.boundary_condition = boundary_condition or \ + get_bc_from_position(geometry.boundary) + +
[docs] @classmethod + def from_dict(cls, data): + """Initialize an Face from a dictionary. + + Args: + data: A dictionary representation of an Face object. + """ + try: + # check the type of dictionary + assert data['type'] == 'Face', 'Expected Face dictionary. ' \ + 'Got {}.'.format(data['type']) + + # first serialize it with an outdoor boundary condition + face_type = face_types.by_name(data['face_type']) + face = cls(data['identifier'], Face3D.from_dict(data['geometry']), + face_type, boundary_conditions.outdoors) + if 'display_name' in data and data['display_name'] is not None: + face.display_name = data['display_name'] + if 'user_data' in data and data['user_data'] is not None: + face.user_data = data['user_data'] + + # add sub-faces and shades + if 'apertures' in data and data['apertures'] is not None: + aps = [] + for ap in data['apertures']: + try: + aps.append(Aperture.from_dict(ap)) + except Exception as e: + invalid_dict_error(ap, e) + face.add_apertures(aps) + if 'doors' in data and data['doors'] is not None: + drs = [] + for dr in data['doors']: + try: + drs.append(Door.from_dict(dr)) + except Exception as e: + invalid_dict_error(dr, e) + face.add_doors(drs) + face._recover_shades_from_dict(data) + + # get the boundary condition and assign it + try: + bc_class = getattr(hbc, data['boundary_condition']['type']) + face.boundary_condition = bc_class.from_dict(data['boundary_condition']) + except AttributeError: # extension boundary condition; default to Outdoors + pass + + # assign extension properties + if data['properties']['type'] == 'FaceProperties': + face.properties._load_extension_attr_from_dict(data['properties']) + return face + except Exception as e: + cls._from_dict_error_message(data, e)
+ +
[docs] @classmethod + def from_vertices(cls, identifier, vertices, type=None, boundary_condition=None): + """Create a Face from vertices with each vertex as an iterable of 3 floats. + + Note that this method is not recommended for a face with one or more holes + since the distinction between hole vertices and boundary vertices cannot + be derived from a single list of vertices. + + Args: + identifier: Text string for a unique Face ID. Must be < 100 characters and + not contain any spaces or special characters. + vertices: A flattened list of 3 or more vertices as (x, y, z). + type: Face type object (eg. Wall, Floor). + boundary_condition: Boundary condition object (eg. Outdoors, Ground) + """ + geometry = Face3D(tuple(Point3D(*v) for v in vertices)) + return cls(identifier, geometry, type, boundary_condition)
+ + @property + def type(self): + """Get or set an object for Type of Face (ie. Wall, Floor, Roof). + + Note that setting this property will reset extension attributes on this + Face to their default values. + """ + return self._type + + @type.setter + def type(self, value): + assert value in self.TYPES, '{} is not a valid face type.'.format(value) + if isinstance(value, AirBoundary): + assert self._apertures == [] or self._doors == [], \ + '{} cannot be assigned to a Face with Apertures or Doors.'.format(value) + self.properties.reset_to_default() # reset constructions/modifiers + self._type = value + + @property + def boundary_condition(self): + """Get or set the boundary condition of the Face. (ie. Outdoors, Ground, etc.). + """ + return self._boundary_condition + + @boundary_condition.setter + def boundary_condition(self, value): + assert isinstance(value, _BoundaryCondition), \ + 'Expected BoundaryCondition. Got {}'.format(type(value)) + if self._apertures != [] or self._doors != []: + assert isinstance(value, (Outdoors, Surface)), \ + '{} cannot be assigned to a Face with apertures or doors.'.format(value) + self._boundary_condition = value + + @property + def apertures(self): + """Get a tuple of apertures in this Face.""" + return tuple(self._apertures) + + @property + def doors(self): + """Get a tuple of doors in this Face.""" + return tuple(self._doors) + + @property + def sub_faces(self): + """Get a tuple of apertures and doors in this Face.""" + return tuple(self._apertures + self._doors) + + @property + def parent(self): + """Get the parent Room if assigned. None if not assigned.""" + return self._parent + + @property + def has_parent(self): + """Get a boolean noting whether this Face has a parent Room.""" + return self._parent is not None + + @property + def has_sub_faces(self): + """Get a boolean noting whether this Face has Apertures or Doors.""" + return not (self._apertures == [] and self._doors == []) + + @property + def can_be_ground(self): + """Get a boolean for whether this Face can support a Ground boundary condition. + """ + return self._apertures == [] and self._doors == [] \ + and not isinstance(self._type, AirBoundary) + + @property + def geometry(self): + """Get a ladybug_geometry Face3D object representing the Face. + + Note that this Face3D only represents the parent face and does not have any + holes cut in it for apertures or doors. + """ + return self._geometry + + @property + def punched_geometry(self): + """Get a Face3D object with holes cut in it for apertures and doors. + """ + if self._punched_geometry is None: + _sub_faces = tuple(sub_f.geometry for sub_f in self._apertures + self._doors) + if len(_sub_faces) != 0: + self._punched_geometry = Face3D.from_punched_geometry( + self._geometry, _sub_faces) + else: + self._punched_geometry = self._geometry + return self._punched_geometry + + @property + def vertices(self): + """Get a list of vertices for the face (in counter-clockwise order). + + Note that these vertices only represent the outer boundary of the face + and do not account for holes cut in the face by apertures or doors. + """ + return self._geometry.vertices + + @property + def punched_vertices(self): + """Get a list of vertices with holes cut in it for apertures and doors. + + Note that some vertices will be repeated since the vertices effectively + trace out a single boundary around the whole shape, winding inward to cut + out the holes. This property should be used when exporting to Radiance. + """ + return self.punched_geometry.vertices + + @property + def upper_left_vertices(self): + """Get a list of vertices starting from the upper-left corner. + + This property obeys the same rules as the vertices property but always starts + from the upper-left-most vertex. This property should be used when exporting to + EnergyPlus / OpenStudio. + """ + return self._geometry.upper_left_counter_clockwise_vertices + + @property + def normal(self): + """Get a Vector3D for the direction in which the face is pointing. + """ + return self._geometry.normal + + @property + def center(self): + """Get a ladybug_geometry Point3D for the center of the face. + + Note that this is the center of the bounding rectangle around this geometry + and not the area centroid. + """ + return self._geometry.center + + @property + def area(self): + """Get the area of the face.""" + return self._geometry.area + + @property + def perimeter(self): + """Get the perimeter of the face. This includes the length of holes in the face. + """ + return self._geometry.perimeter + + @property + def min(self): + """Get a Point3D for the minimum of the bounding box around the object.""" + all_geo = self._outdoor_shades + self._indoor_shades + all_geo.extend(self._apertures) + all_geo.extend(self._doors) + all_geo.append(self.geometry) + return self._calculate_min(all_geo) + + @property + def max(self): + """Get a Point3D for the maximum of the bounding box around the object.""" + all_geo = self._outdoor_shades + self._indoor_shades + all_geo.extend(self._apertures) + all_geo.extend(self._doors) + all_geo.append(self.geometry) + return self._calculate_max(all_geo) + + @property + def aperture_area(self): + """Get the combined area of the face's apertures.""" + return sum([ap.area for ap in self._apertures]) + + @property + def aperture_ratio(self): + """Get a number between 0 and 1 for the area ratio of the apertures to the face. + """ + return self.aperture_area / self.area + + @property + def altitude(self): + """Get the altitude of the geometry between +90 (up) and -90 (down).""" + return math.degrees(self._geometry.altitude) + + @property + def azimuth(self): + """Get the azimuth of the geometry, between 0 and 360. + + Given Y-axis as North, 0 = North, 90 = East, 180 = South, 270 = West + This will be zero if the Face3D is perfectly horizontal. + """ + return math.degrees(self._geometry.azimuth) + + @property + def type_color(self): + """Get a Color to be used in visualizations by type.""" + ts = self.type.name if isinstance(self.boundary_condition, (Outdoors, Ground)) \ + else 'Interior{}'.format(self.type.name) + return self.TYPE_COLORS[ts] + + @property + def bc_color(self): + """Get a Color to be used in visualizations by boundary condition.""" + try: + return self.BC_COLORS[self.boundary_condition.name] + except KeyError: # extension boundary condition + return self.BC_COLORS['Other'] + +
[docs] def horizontal_orientation(self, north_vector=Vector2D(0, 1)): + """Get a number between 0 and 360 for the orientation of the face in degrees. + + 0 = North, 90 = East, 180 = South, 270 = West + + Args: + north_vector: A ladybug_geometry Vector2D for the north direction. + Default is the Y-axis (0, 1). + """ + return math.degrees( + north_vector.angle_clockwise(Vector2D(self.normal.x, self.normal.y)))
+ +
[docs] def cardinal_direction(self, north_vector=Vector2D(0, 1)): + """Get text description for the cardinal direction that the face is pointing. + + Will be one of the following: ('North', 'NorthEast', 'East', 'SouthEast', + 'South', 'SouthWest', 'West', 'NorthWest'). + + Args: + north_vector: A ladybug_geometry Vector2D for the north direction. + Default is the Y-axis (0, 1). + """ + orient = self.horizontal_orientation(north_vector) + orient_text = ('North', 'NorthEast', 'East', 'SouthEast', 'South', + 'SouthWest', 'West', 'NorthWest') + angles = (22.5, 67.5, 112.5, 157.5, 202.5, 247.5, 292.5, 337.5) + for i, ang in enumerate(angles): + if orient < ang: + return orient_text[i] + return orient_text[0]
+ +
[docs] def add_prefix(self, prefix): + """Change the identifier of this object and child objects by inserting a prefix. + + This is particularly useful in workflows where you duplicate and edit + a starting object and then want to combine it with the original object + into one Model (like making a model of repeated rooms) since all objects + within a Model must have unique identifiers. + + Args: + prefix: Text that will be inserted at the start of this object's + (and child objects') identifier and display_name. It is recommended + that this prefix be short to avoid maxing out the 100 allowable + characters for honeybee identifiers. + """ + self._identifier = clean_string('{}_{}'.format(prefix, self.identifier)) + self.display_name = '{}_{}'.format(prefix, self.display_name) + self.properties.add_prefix(prefix) + for ap in self._apertures: + ap.add_prefix(prefix) + for dr in self._doors: + dr.add_prefix(prefix) + self._add_prefix_shades(prefix) + if isinstance(self._boundary_condition, Surface): + new_bc_objs = (clean_string('{}_{}'.format(prefix, adj_name)) for adj_name + in self._boundary_condition._boundary_condition_objects) + self._boundary_condition = Surface(new_bc_objs, False)
+ +
[docs] def remove_sub_faces(self): + """Remove all apertures and doors from the face.""" + self.remove_apertures() + self.remove_doors()
+ +
[docs] def remove_apertures(self): + """Remove all apertures from the face.""" + for aperture in self._apertures: + aperture._parent = None + self._apertures = [] + self._punched_geometry = None # reset so that it can be re-computed
+ +
[docs] def remove_doors(self): + """Remove all doors from the face.""" + for door in self._apertures: + door._parent = None + self._doors = [] + self._punched_geometry = None # reset so that it can be re-computed
+ +
[docs] def add_aperture(self, aperture): + """Add an Aperture to this face. + + This method does not check the co-planarity between this Face and the + Aperture or whether the Aperture has all vertices within the boundary of + this Face. To check this, the Face3D.is_sub_face() method can be used + with the Aperture and Face geometry before using this method or the + are_sub_faces_valid() method can be used afterwards. + + Args: + aperture: An Aperture to add to this face. + """ + assert isinstance(aperture, Aperture), \ + 'Expected Aperture. Got {}.'.format(type(aperture)) + self._acceptable_sub_face_check(Aperture) + aperture._parent = self + if self.normal.angle(aperture.normal) > math.pi / 2: # reversed normal + aperture._geometry = aperture._geometry.flip() + self._apertures.append(aperture) + self._punched_geometry = None # reset so that it can be re-computed
+ +
[docs] def add_door(self, door): + """Add a Door to this face. + + This method does not check the co-planarity between this Face and the + Door or whether the Door has all vertices within the boundary of + this Face. To check this, the Face3D.is_sub_face() method can be used + with the Door and Face geometry before using this method or the + are_sub_faces_valid() method can be used afterwards. + + Args: + door: A Door to add to this face. + """ + assert isinstance(door, Door), \ + 'Expected Door. Got {}.'.format(type(door)) + self._acceptable_sub_face_check(Door) + door._parent = self + if self.normal.angle(door.normal) > math.pi / 2: # reversed normal + door._geometry = door._geometry.flip() + self._doors.append(door) + self._punched_geometry = None # reset so that it can be re-computed
+ +
[docs] def add_apertures(self, apertures): + """Add a list of Apertures to this face.""" + for aperture in apertures: + self.add_aperture(aperture)
+ +
[docs] def add_doors(self, doors): + """Add a list of Doors to this face.""" + for door in doors: + self.add_door(door)
+ +
[docs] def replace_apertures(self, apertures): + """Replace all sub-faces assigned to this Face with a new list of Apertures.""" + self.remove_sub_faces() + self.add_apertures(apertures)
+ +
[docs] def set_adjacency(self, other_face, tolerance=0.01): + """Set this face adjacent to another and set the other face adjacent to this one. + + Note that this method does not verify whether the other_face geometry is + co-planar or compatible with this one so it is recommended that either the + Face3D.is_centered_adjacent() or the Face3D.is_geometrically_equivalent() + method be used with this face geometry and the other_face geometry + before using this method in order to verify these criteria. + + However, this method will use the proximity of apertures and doors within + the input tolerance to determine which of the sub faces in the other_face + are adjacent to the ones in this face. An exception will be thrown if not + all sub-faces can be matched. + + Args: + other_face: Another Face object to be set adjacent to this one. + tolerance: The minimum distance between the center of two aperture + geometries at which they are considered adjacent. Default: 0.01, + suitable for objects in meters. + + Returns: + A dictionary of adjacency information with the following keys + + - adjacent_apertures - A list of tuples with each tuple containing 2 + objects for Apertures paired in the process of solving adjacency. + + - adjacent_doors - A list of tuples with each tuple containing 2 + objects for Doors paired in the process of solving adjacency. + """ + # check the inputs and the ability of the faces to be adjacent + assert isinstance(other_face, Face), \ + 'Expected honeybee Face. Got {}.'.format(type(other_face)) + + # set the boundary conditions of the faces + self._boundary_condition = boundary_conditions.surface(other_face) + other_face._boundary_condition = boundary_conditions.surface(self) + + adj_info = {'adjacent_apertures': [], 'adjacent_doors': []} + + # set the apertures to be adjacent to one another + assert len(self._apertures) == len(other_face._apertures), \ + 'Number of apertures does not match between {} and {}.'.format( + self.display_name, other_face.display_name) + if len(self._apertures) > 0: + found_adjacencies = 0 + for aper_1 in self._apertures: + for aper_2 in other_face._apertures: + if aper_1.center.distance_to_point(aper_2.center) <= tolerance: + aper_1.set_adjacency(aper_2) + adj_info['adjacent_apertures'].append((aper_1, aper_2)) + found_adjacencies += 1 + break + assert len(self._apertures) == found_adjacencies, \ + 'Not all apertures of {} were found to be adjacent to apertures in {}.' \ + '\nTry increasing the tolerance.'.format( + self.display_name, other_face.display_name) + + # set the doors to be adjacent to one another + assert len(self._doors) == len(other_face._doors), \ + 'Number of doors does not match between {} and {}.'.format( + self.display_name, other_face.display_name) + if len(self._doors) > 0: + found_adjacencies = 0 + for door_1 in self._doors: + for door_2 in other_face._doors: + if door_1.center.distance_to_point(door_2.center) <= tolerance: + door_1.set_adjacency(door_2) + adj_info['adjacent_doors'].append((door_1, door_2)) + found_adjacencies += 1 + break + assert len(self._doors) == found_adjacencies, \ + 'Not all doors of {} were found to be adjacent to doors in {}.' \ + '\nTry increasing the tolerance.'.format( + self.display_name, other_face.display_name) + + return adj_info
+ +
[docs] def rectangularize_apertures( + self, subdivision_distance=None, max_separation=None, + merge_all=False, tolerance=0.01, angle_tolerance=1.0): + """Convert all Apertures on this Face to be rectangular. + + This is useful when exporting to simulation engines that only accept + rectangular window geometry. This method will always result ing Rooms where + all Apertures are rectangular. However, if the subdivision_distance is not + set, some Apertures may extend past the parent Face or may collide with + one another. + + Args: + subdivision_distance: A number for the resolution at which the + non-rectangular Apertures will be subdivided into smaller + rectangular units. Specifying a number here ensures that the + resulting rectangular Apertures do not extend past the parent + Face or collide with one another. If None, all non-rectangular + Apertures will be rectangularized by taking the bounding rectangle + around the Aperture. (Default: None). + max_separation: A number for the maximum distance between non-rectangular + Apertures at which point the Apertures will be merged into a single + rectangular geometry. This is often helpful when there are several + triangular Apertures that together make a rectangle when they are + merged across their frames. In such cases, this max_separation + should be set to a value that is slightly larger than the window frame. + If None, no merging of Apertures will happen before they are + converted to rectangles. (Default: None). + merge_all: Boolean to note whether all apertures should be merged before + they are rectangularized. If False, only non-rectangular apertures + will be merged before rectangularization. Note that this argument + has no effect when the max_separation is None. (Default: False). + tolerance: The maximum difference between point values for them to be + considered equivalent. (Default: 0.01, suitable for objects in meters). + angle_tolerance: The max angle in degrees that the corners of the + rectangle can differ from a right angle before it is not + considered a rectangle. (Default: 1). + + Returns: + True if the Apertures were changed. False if they were unchanged. + """ + # sort the rectangular and non-rectangular apertures + apertures = self._apertures + if len(apertures) == 0: + return False + tol, ang_tol = tolerance, math.radians(angle_tolerance) + rect_aps, non_rect_aps, non_rect_geos = [], [], [] + for aperture in apertures: + try: + clean_geo = aperture.geometry.remove_colinear_vertices(tol) + except AssertionError: # degenerate Aperture to be ignored + continue + if max_separation is None or not merge_all: + if clean_geo.polygon2d.is_rectangle(ang_tol): + rect_aps.append(aperture) + else: + non_rect_aps.append(aperture) + non_rect_geos.append(clean_geo) + else: + non_rect_aps.append(aperture) + non_rect_geos.append(clean_geo) + if not non_rect_geos: # nothing to be rectangularized + return False + + # reset boundary conditions to outdoors so new apertures can be added + if not isinstance(self.boundary_condition, Outdoors): + self.boundary_condition = boundary_conditions.outdoors + for ap in rect_aps: + ap.boundary_condition = boundary_conditions.outdoors + edits_occurred = False + + # try to merge the non-rectangular apertures if a max_separation is specified + ref_plane = self._reference_plane(ang_tol) + if max_separation is not None: + if merge_all or (not merge_all and len(non_rect_geos) > 1): + edits_occurred = True + if max_separation <= tol: # just join the Apertures at the tolerance + non_rect_geos = Face3D.join_coplanar_faces(non_rect_geos, tol) + else: # join the Apertures using the max_separation + # get polygons for the faces that all lie within the same plane + face_polys = [] + for fg in non_rect_geos: + verts2d = tuple(ref_plane.xyz_to_xy(_v) for _v in fg.boundary) + face_polys.append(Polygon2D(verts2d)) + if fg.has_holes: + for hole in fg.holes: + verts2d = tuple(ref_plane.xyz_to_xy(_v) for _v in hole) + face_polys.append(Polygon2D(verts2d)) + # get the joined boundaries around the Polygon2D + joined_bounds = Polygon2D.gap_crossing_boundary( + face_polys, max_separation, tolerance) + # convert the boundary polygons back to Face3D + if len(joined_bounds) == 1: # can be represented with a single Face3D + verts3d = tuple(ref_plane.xy_to_xyz(_v) for _v in joined_bounds[0]) + non_rect_geos = [Face3D(verts3d, plane=ref_plane)] + else: # need to separate holes from distinct Face3Ds + bound_faces = [] + for poly in joined_bounds: + verts3d = tuple(ref_plane.xy_to_xyz(_v) for _v in poly) + bound_faces.append(Face3D(verts3d, plane=ref_plane)) + non_rect_geos = Face3D.merge_faces_to_holes(bound_faces, tolerance) + clean_aps = [] + for ap_geo in non_rect_geos: + try: + clean_aps.append(ap_geo.remove_colinear_vertices(tol)) + except AssertionError: # degenerate Aperture to be ignored + continue + non_rect_geos = clean_aps + + # convert the remaining Aperture geometries to rectangles + if subdivision_distance is None: # just take the bounding rectangle + edits_occurred = True + # get the bounding rectangle around all of the geometries + ap_geos = [] + for ap_geo in non_rect_geos: + if ap_geo.polygon2d.is_rectangle(ang_tol): + ap_geos.append(ap_geo) # catch rectangles found in merging + continue + geo_2d = Polygon2D([ref_plane.xyz_to_xy(v) for v in ap_geo.vertices]) + g_min, g_max = geo_2d.min, geo_2d.max + base, hgt = g_max.x - g_min.x, g_max.y - g_min.y + bound_poly = Polygon2D.from_rectangle(g_min, Vector2D(0, 1), base, hgt) + geo_3d = Face3D([ref_plane.xy_to_xyz(v) for v in bound_poly.vertices]) + ap_geos.append(geo_3d) + non_rect_geos = ap_geos + + # create Aperture objects from all of the merged geometries + if not edits_occurred: + new_aps = non_rect_aps + else: + new_aps = [] + for i, ap_face in enumerate(non_rect_geos): + exist_ap = None + for old_ap in non_rect_aps: + if old_ap.center.is_equivalent(ap_face.center, tolerance): + exist_ap = old_ap + break + if exist_ap is None: # could not be matched; just make a new aperture + new_ap = Aperture('{}_RectGlz{}'.format(self.identifier, i), ap_face) + else: + new_ap = Aperture(exist_ap.identifier, ap_face, + is_operable=exist_ap.is_operable) + new_ap.display_name = '{}_{}'.format(exist_ap.display_name, i) + new_aps.append(new_ap) + + # we can just add the apertures if there's no subdivision going on + if subdivision_distance is None: + # remove any Apertures that are overlapping + all_aps = rect_aps + new_aps + all_aps = self._remove_overlapping_sub_faces(all_aps, tolerance) + self.remove_apertures() + self.add_apertures(all_aps) + return True + + # if distance is provided, subdivide the apertures into strips + new_ap_objs = [] + for ap_obj in new_aps: + ap_geo = ap_obj.geometry + if ap_geo.polygon2d.is_rectangle(ang_tol): + new_ap_objs.append(ap_obj) # catch rectangles found in merging + continue + # create a mesh grid over the Aperture in the reference plane + geo_2d = Polygon2D([ref_plane.xyz_to_xy(v) for v in ap_geo.vertices]) + try: + grid = Mesh2D.from_polygon_grid( + geo_2d, subdivision_distance, subdivision_distance, False) + except AssertionError: # Aperture smaller than resolution; ignore + continue + + # group face by y value. All the rows will be merged together + vertices = grid.vertices + groups = {} + last_y = vertices[grid.faces[0][0]].y + for i, face in enumerate(grid.faces): + min_2d = vertices[face[0]] + for xy in groups: + if abs(min_2d.x - xy[0]) < tolerance and abs(min_2d.y - last_y) < tolerance: + groups[(xy[0], start_y)].append(face) + break + else: + start_y = min_2d.y + groups[(min_2d.x, start_y)] = [face] + last_y = vertices[face[3]].y + + # get the max and min of each group + sorted_groups = [] + for group in groups.values(): + # find min_2d and max_2d for each group + min_2d = vertices[group[0][0]] + max_2d = vertices[group[-1][2]] + sorted_groups.append({'min': min_2d, 'max': max_2d}) + + def _get_last_row(groups, start=0): + """An internal function to return the index for the last row that can be + merged with the start row that is passed to this function. + + This function compares the min and max x and y values for each row to see + if they can be merged into a rectangle. + """ + for count, group in enumerate(groups[start:]): + next_group = groups[count + start + 1] + if abs(group['min'].y - next_group['min'].y) <= tolerance \ + and abs(group['max'].y - next_group['max'].y) <= tolerance \ + and abs(next_group['min'].x - group['max'].x) <= tolerance: + continue + else: + return start + count + + return start + count + 1 + + # merge the rows if they have the same number of grid cells + sorted_groups.sort(key=lambda x: x['min'].x) + merged_groups = [] + start_row = 0 + last_row = -1 + while last_row < len(sorted_groups): + try: + last_row = _get_last_row(sorted_groups, start=start_row) + except IndexError: + merged_groups.append( + { + 'min': sorted_groups[start_row]['min'], + 'max': sorted_groups[len(sorted_groups) - 1]['max'] + } + ) + break + else: + merged_groups.append( + { + 'min': sorted_groups[start_row]['min'], + 'max': sorted_groups[last_row]['max'] + } + ) + if last_row == start_row: + # the row was not grouped with anything else + start_row += 1 + else: + start_row = last_row + 1 + + # convert the groups into rectangular strips + for i, group in enumerate(merged_groups): + min_2d = group['min'] + max_2d = group['max'] + base, hgt = max_2d.x - min_2d.x, max_2d.y - min_2d.y + bound_poly = Polygon2D.from_rectangle(min_2d, Vector2D(0, 1), base, hgt) + geo_3d = Face3D([ref_plane.xy_to_xyz(v) for v in bound_poly.vertices]) + new_ap = Aperture( + '{}_Glz{}'.format(ap_obj.identifier, i), + geo_3d, is_operable=ap_obj.is_operable) + new_ap.display_name = '{}_{}'.format(ap_obj.display_name, i) + new_ap_objs.append(new_ap) + + # replace the apertures with the new ones + self.remove_apertures() + self.add_apertures(rect_aps + new_ap_objs) + return True
+ + def _reference_plane(self, angle_tolerance): + """Get a Plane for this Face geometry derived from the Face3D plane. + + This will be oriented with the plane Y-Axis either aligned with the + World Z or World Y, which is helpful in rectangularization. + + Args: + angle_tolerance: The max angle in radians that Face normal can differ + from the World Z before the Face is treated as being in the + World XY plane. + """ + parent_llc = self.geometry.lower_left_corner + rel_plane = self.geometry.plane + vertical = Vector3D(0, 0, 1) + vert_ang = rel_plane.n.angle(vertical) + if vert_ang <= angle_tolerance or vert_ang >= math.pi - angle_tolerance: + proj_x = Vector3D(1, 0, 0) + else: + proj_y = vertical.project(rel_plane.n) + proj_x = proj_y.rotate(rel_plane.n, math.pi / -2) + + ref_plane = Plane(rel_plane.n, parent_llc, proj_x) + return ref_plane + +
[docs] def apertures_by_ratio(self, ratio, tolerance=0.01): + """Add apertures to this Face given a ratio of aperture area to face area. + + Note that this method removes any existing apertures and doors on the Face. + This method attempts to generate as few apertures as necessary to meet the ratio. + + Args: + ratio: A number between 0 and 1 (but not perfectly equal to 1) + for the desired ratio between aperture area and face area. + tolerance: The maximum difference between point values for them to be + considered the same. This is used in the event that this face is + concave and an attempt to subdivide the face into a rectangle is + made. It does not affect the ability to produce apertures for + convex Faces. Default: 0.01, suitable for objects in meters. + + Usage: + + .. code-block:: python + + room = Room.from_box(3.0, 6.0, 3.2, 180) + room.faces[1].apertures_by_ratio(0.4) + """ + assert 0 <= ratio < 1, 'Ratio must be between 0 and 1. Got {}'.format(ratio) + self._acceptable_sub_face_check(Aperture) + self.remove_sub_faces() + if ratio == 0: + return + try: + geo = self._geometry.remove_colinear_vertices(tolerance) + except AssertionError: # degenerate face that should not have apertures + return + ap_faces = geo.sub_faces_by_ratio_rectangle(ratio, tolerance) + for i, ap_face in enumerate(ap_faces): + aperture = Aperture('{}_Glz{}'.format(self.identifier, i), ap_face) + self.add_aperture(aperture)
+ +
[docs] def apertures_by_ratio_rectangle(self, ratio, aperture_height, sill_height, + horizontal_separation, vertical_separation=0, + tolerance=0.01): + """Add apertures to this face given a ratio of aperture area to face area. + + Note that this method removes any existing apertures on the Face. + + This function is virtually equivalent to the apertures_by_ratio method but + any rectangular portions of this face will produce customizable rectangular + apertures using the other inputs (aperture_height, sill_height, + horizontal_separation, vertical_separation). + + Args: + ratio: A number between 0 and 0.95 for the ratio between the area of + the apertures and the area of this face. + aperture_height: A number for the target height of the output apertures. + Note that, if the ratio is too large for the height, the ratio will + take precedence and the actual aperture_height will be larger + than this value. + sill_height: A number for the target height above the bottom edge of + the rectangle to start the apertures. Note that, if the + ratio is too large for the height, the ratio will take precedence + and the sill_height will be smaller than this value. + horizontal_separation: A number for the target separation between + individual aperture center lines. If this number is larger than + the parent rectangle base, only one aperture will be produced. + vertical_separation: An optional number to create a single vertical + separation between top and bottom apertures. The default is + 0 for no separation. + tolerance: The maximum difference between point values for them to be + considered a part of a rectangle. Default: 0.01, suitable for + objects in meters. + + Usage: + + .. code-block:: python + + room = Room.from_box(3.0, 6.0, 3.2, 180) + room.faces[1].apertures_by_ratio_rectangle(0.4, 2, 0.9, 3) + """ + assert 0 <= ratio <= 0.95, \ + 'Ratio must be between 0 and 0.95. Got {}'.format(ratio) + self._acceptable_sub_face_check(Aperture) + self.remove_sub_faces() + if ratio == 0: + return + try: + geo = self._geometry.remove_colinear_vertices(tolerance) + except AssertionError: # degenerate face that should not have apertures + return + ap_faces = geo.sub_faces_by_ratio_sub_rectangle( + ratio, aperture_height, sill_height, horizontal_separation, + vertical_separation, tolerance) + for i, ap_face in enumerate(ap_faces): + aperture = Aperture('{}_Glz{}'.format(self.identifier, i), ap_face) + self.add_aperture(aperture)
+ +
[docs] def apertures_by_ratio_gridded(self, ratio, x_dim, y_dim=None, tolerance=0.01): + """Add apertures to this face given a ratio of aperture area to face area. + + Note that this method removes any existing apertures on the Face. + + Apertures will be arranged in a grid derived from this face's plane. + Because the x_dim and y_dim refer to dimensions within the X and Y + coordinate system of this faces's plane, rotating this plane will + result in rotated grid cells. This is particularly useful for generating + skylights based on a glazing ratio. + + If the x_dim and/or y_dim are too large for this face, this method will + return essentially the same result as the apertures_by_ratio method. + + Args: + ratio: A number between 0 and 1 for the ratio between the area of + the apertures and the area of this face. + x_dim: The x dimension of the grid cells as a number. + y_dim: The y dimension of the grid cells as a number. Default is None, + which will assume the same cell dimension for y as is set for x. + tolerance: The maximum difference between point values for them to be + considered a part of a rectangle. Default: 0.01, suitable for + objects in meters. + + Usage: + + .. code-block:: python + + room = Room.from_box(3.0, 6.0, 3.2, 180) + room.faces[-1].apertures_by_ratio_gridded(0.05, 3) + """ + assert 0 <= ratio < 1, 'Ratio must be between 0 and 1. Got {}'.format(ratio) + self._acceptable_sub_face_check(Aperture) + self.remove_sub_faces() + if ratio == 0: + return + try: + geo = self._geometry.remove_colinear_vertices(tolerance) + except AssertionError: # degenerate face that should not have apertures + return + ap_faces = geo.sub_faces_by_ratio_gridded(ratio, x_dim, y_dim) + for i, ap_face in enumerate(ap_faces): + aperture = Aperture('{}_Glz{}'.format(self.identifier, i), ap_face) + self.add_aperture(aperture)
+ +
[docs] def apertures_by_width_height_rectangle(self, aperture_height, aperture_width, + sill_height, horizontal_separation, + tolerance=0.01): + """Add repeating apertures to this face given the aperture width and height. + + Note that this method removes any existing apertures on the Face. + + Note that this method will effectively fill any rectangular portions of + this Face with apertures at the specified width, height and separation. + If no rectangular portion of this Face can be identified, no apertures + will be added. + + Args: + aperture_height: A number for the target height of the apertures. + aperture_width: A number for the target width of the apertures. + sill_height: A number for the target height above the bottom edge of + the rectangle to start the apertures. If the aperture_height + is too large for the sill_height to fit within the rectangle, + the aperture_height will take precedence. + horizontal_separation: A number for the target separation between + individual apertures center lines. If this number is larger than + the parent rectangle base, only one aperture will be produced. + tolerance: The maximum difference between point values for them to be + considered a part of a rectangle. Default: 0.01, suitable for + objects in meters. + + Usage: + + .. code-block:: python + + room = Room.from_box(5.0, 10.0, 3.2, 180) + room.faces[1].apertures_by_width_height_rectangle(1.5, 2, 0.8, 2.5) + """ + assert horizontal_separation > 0, \ + 'horizontal_separation must be above 0. Got {}'.format(horizontal_separation) + if aperture_height <= 0 or aperture_width <= 0: + return + self._acceptable_sub_face_check(Aperture) + self.remove_sub_faces() + try: + geo = self._geometry.remove_colinear_vertices(tolerance) + except AssertionError: # degenerate face that should not have apertures + return + ap_faces = geo.sub_faces_by_dimension_rectangle( + aperture_height, aperture_width, sill_height, horizontal_separation, + tolerance) + for i, ap_face in enumerate(ap_faces): + aperture = Aperture('{}_Glz{}'.format(self.identifier, i), ap_face) + self.add_aperture(aperture)
+ +
[docs] def aperture_by_width_height(self, width, height, sill_height=1, + aperture_identifier=None): + """Add a single rectangular aperture to the center of this Face. + + A rectangular window with the input width and height will always be added + by this method regardless of whether this parent Face contains a recognizable + rectangular portion or not. Furthermore, this method preserves any existing + apertures on the Face. + + While the resulting aperture will always be in the plane of this Face, + this method will not check to ensure that the aperture has all of its + vertices completely within the boundary of this Face or that it does not + intersect with other apertures in the Face. The are_sub_faces_valid() + method can be used afterwards to check this. + + Args: + width: A number for the Aperture width. + height: A number for the Aperture height. + sill_height: A number for the sill height. (Default: 1). + aperture_identifier: Optional string for the aperture identifier. + If None, the default will follow the convention + "[face_identifier]_Glz[count]" where [count] is one more than + the current number of apertures in the face. + + Returns: + The new Aperture object that has been generated. + + Usage: + + .. code-block:: python + + room = Room.from_box(3.0, 6.0, 3.2, 180) + room[1].aperture_by_width_height(2, 2, .7) # aperture in front + room[2].aperture_by_width_height(4, 1.5, .5) # aperture on right + room[2].aperture_by_width_height(4, 0.5, 2.2) # aperture on right + """ + # Perform checks + if width <= 0 or height <= 0: + return + self._acceptable_sub_face_check(Aperture) + # Generate the aperture geometry + origin = self._geometry.lower_left_counter_clockwise_vertices[0] + face_plane = Plane(self._geometry.plane.n, origin) + if face_plane.y.z < 0: + face_plane = face_plane.rotate(face_plane.n, math.pi, face_plane.o) + center2d = face_plane.xyz_to_xy(self._geometry.center) + x_dist = width / 2 + lower_left = Point2D(center2d.x - x_dist, sill_height) + lower_right = Point2D(center2d.x + x_dist, sill_height) + upper_right = Point2D(center2d.x + x_dist, sill_height + height) + upper_left = Point2D(center2d.x - x_dist, sill_height + height) + ap_verts2d = (lower_left, lower_right, upper_right, upper_left) + ap_verts3d = tuple(face_plane.xy_to_xyz(pt) for pt in ap_verts2d) + ap_face = Face3D(ap_verts3d, self._geometry.plane) + if self.normal.angle(ap_face.normal) > math.pi / 2: # reversed normal + ap_face = ap_face.flip() + + # Create the aperture and add it to this Face + identifier = aperture_identifier or \ + '{}_Glz{}'.format(self.identifier, len(self.apertures)) + aperture = Aperture(identifier, ap_face) + self.add_aperture(aperture) + return aperture
+ +
[docs] def overhang(self, depth, angle=0, indoor=False, tolerance=0.01, base_name=None): + """Add an overhang to this Face. + + Args: + depth: A number for the overhang depth. + angle: A number for the for an angle to rotate the overhang in degrees. + Positive numbers indicate a downward rotation while negative numbers + indicate an upward rotation. Default is 0 for no rotation. + indoor: Boolean for whether the overhang should be generated facing the + opposite direction of the aperture normal (typically meaning + indoor geometry). Default: False. + tolerance: An optional value to not add the overhang if it has a length less + than the tolerance. Default: 0.01, suitable for objects in meters. + base_name: Optional base identifier for the shade objects. If None, + the default is InOverhang or OutOverhang depending on whether + indoor is True. + + Returns: + A list of the new Shade objects that have been generated. + """ + if base_name is None: + base_name = 'InOverhang' if indoor else 'OutOverhang' + return self.louvers_by_count(1, depth, angle=angle, indoor=indoor, + tolerance=tolerance, base_name=base_name)
+ +
[docs] def louvers_by_count(self, louver_count, depth, offset=0, angle=0, + contour_vector=Vector2D(0, 1), flip_start_side=False, + indoor=False, tolerance=0.01, base_name=None): + """Add a series of louvered Shade objects over this Face. + + Args: + louver_count: A positive integer for the number of louvers to generate. + depth: A number for the depth to extrude the louvers. + offset: A number for the distance to louvers from this Face. + Default is 0 for no offset. + angle: A number for the for an angle to rotate the louvers in degrees. + Positive numbers indicate a downward rotation while negative numbers + indicate an upward rotation. Default is 0 for no rotation. + contour_vector: A Vector2D for the direction along which contours + are generated. This 2D vector will be interpreted into a 3D vector + within the plane of this Face. (0, 1) will usually generate + horizontal contours in 3D space, (1, 0) will generate vertical + contours, and (1, 1) will generate diagonal contours. Default: (0, 1). + flip_start_side: Boolean to note whether the side the louvers start from + should be flipped. Default is False to have louvers on top or right. + Setting to True will start contours on the bottom or left. + indoor: Boolean for whether louvers should be generated facing the + opposite direction of the Face normal (typically meaning + indoor geometry). Default: False. + tolerance: An optional value to remove any louvers with a length less + than the tolerance. Default: 0.01, suitable for objects in meters. + base_name: Optional base identifier for the shade objects. If None, + the default is InShd or OutShd depending on whether indoor is True. + + Returns: + A list of the new Shade objects that have been generated. + """ + assert louver_count > 0, 'louver_count must be greater than 0.' + angle = math.radians(angle) + louvers = [] + face_geo = self.geometry if indoor is False else self.geometry.flip() + if base_name is None: + shd_name_base = '{}_InShd{}' if indoor else '{}_OutShd{}' + else: + shd_name_base = '{}_' + str(base_name) + '{}' + shade_faces = face_geo.contour_fins_by_number( + louver_count, depth, offset, angle, + contour_vector, flip_start_side, tolerance) + for i, shade_geo in enumerate(shade_faces): + louvers.append(Shade(shd_name_base.format(self.identifier, i), shade_geo)) + if indoor: + self.add_indoor_shades(louvers) + else: + self.add_outdoor_shades(louvers) + return louvers
+ +
[docs] def louvers_by_distance_between( + self, distance, depth, offset=0, angle=0, contour_vector=Vector2D(0, 1), + flip_start_side=False, indoor=False, tolerance=0.01, max_count=None, + base_name=None): + """Add a series of louvered Shade objects over this Face. + + Args: + distance: A number for the approximate distance between each louver. + depth: A number for the depth to extrude the louvers. + offset: A number for the distance to louvers from this Face. + Default is 0 for no offset. + angle: A number for the for an angle to rotate the louvers in degrees. + Positive numbers indicate a downward rotation while negative numbers + indicate an upward rotation. Default is 0 for no rotation. + contour_vector: A Vector2D for the direction along which contours + are generated. This 2D vector will be interpreted into a 3D vector + within the plane of this Face. (0, 1) will usually generate + horizontal contours in 3D space, (1, 0) will generate vertical + contours, and (1, 1) will generate diagonal contours. Default: (0, 1). + flip_start_side: Boolean to note whether the side the louvers start from + should be flipped. Default is False to have contours on top or right. + Setting to True will start contours on the bottom or left. + indoor: Boolean for whether louvers should be generated facing the + opposite direction of the Face normal (typically meaning + indoor geometry). Default: False. + tolerance: An optional value to remove any louvers with a length less + than the tolerance. Default: 0.01, suitable for objects in meters. + max_count: Optional integer to set the maximum number of louvers that + will be generated. If None, louvers will cover the entire face. + base_name: Optional base identifier for the shade objects. If None, the + default is InShd or OutShd depending on whether indoor is True. + + Returns: + A list of the new Shade objects that have been generated. + """ + # set defaults + angle = math.radians(angle) + face_geo = self.geometry if indoor is False else self.geometry.flip() + if base_name is None: + shd_name_base = '{}_InShd{}' if indoor else '{}_OutShd{}' + else: + shd_name_base = '{}_' + str(base_name) + '{}' + + # generate shade geometries + shade_faces = face_geo.contour_fins_by_distance_between( + distance, depth, offset, angle, contour_vector, flip_start_side, tolerance) + if max_count: + try: + shade_faces = shade_faces[:max_count] + except IndexError: # fewer shades were generated than the max count + pass + + # create the shade objects + louvers = [] + for i, shade_geo in enumerate(shade_faces): + louvers.append(Shade(shd_name_base.format(self.identifier, i), shade_geo)) + if indoor: + self.add_indoor_shades(louvers) + else: + self.add_outdoor_shades(louvers) + return louvers
+ +
[docs] def move(self, moving_vec): + """Move this Face along a vector. + + Args: + moving_vec: A ladybug_geometry Vector3D with the direction and distance + to move the face. + """ + self._geometry = self.geometry.move(moving_vec) + for ap in self._apertures: + ap.move(moving_vec) + for dr in self._doors: + dr.move(moving_vec) + self.move_shades(moving_vec) + self.properties.move(moving_vec) + self._punched_geometry = None # reset so that it can be re-computed
+ +
[docs] def rotate(self, axis, angle, origin): + """Rotate this Face by a certain angle around an axis and origin. + + Args: + axis: A ladybug_geometry Vector3D axis representing the axis of rotation. + angle: An angle for rotation in degrees. + origin: A ladybug_geometry Point3D for the origin around which the + object will be rotated. + """ + self._geometry = self.geometry.rotate(axis, math.radians(angle), origin) + for ap in self._apertures: + ap.rotate(axis, angle, origin) + for dr in self._doors: + dr.rotate(axis, angle, origin) + self.rotate_shades(axis, angle, origin) + self.properties.rotate(axis, angle, origin) + self._punched_geometry = None # reset so that it can be re-computed
+ +
[docs] def rotate_xy(self, angle, origin): + """Rotate this Face counterclockwise in the world XY plane by a certain angle. + + Args: + angle: An angle in degrees. + origin: A ladybug_geometry Point3D for the origin around which the + object will be rotated. + """ + self._geometry = self.geometry.rotate_xy(math.radians(angle), origin) + for ap in self._apertures: + ap.rotate_xy(angle, origin) + for dr in self._doors: + dr.rotate_xy(angle, origin) + self.rotate_xy_shades(angle, origin) + self.properties.rotate_xy(angle, origin) + self._punched_geometry = None # reset so that it can be re-computed
+ +
[docs] def reflect(self, plane): + """Reflect this Face across a plane. + + Args: + plane: A ladybug_geometry Plane across which the object will + be reflected. + """ + self._geometry = self.geometry.reflect(plane.n, plane.o) + for ap in self._apertures: + ap.reflect(plane) + for dr in self._doors: + dr.reflect(plane) + self.reflect_shades(plane) + self.properties.reflect(plane) + self._punched_geometry = None # reset so that it can be re-computed
+ +
[docs] def scale(self, factor, origin=None): + """Scale this Face by a factor from an origin point. + + Args: + factor: A number representing how much the object should be scaled. + origin: A ladybug_geometry Point3D representing the origin from which + to scale. If None, it will be scaled from the World origin (0, 0, 0). + """ + self._geometry = self.geometry.scale(factor, origin) + for ap in self._apertures: + ap.scale(factor, origin) + for dr in self._doors: + dr.scale(factor, origin) + self.scale_shades(factor, origin) + self.properties.scale(factor, origin) + self._punched_geometry = None # reset so that it can be re-computed
+ +
[docs] def remove_colinear_vertices(self, tolerance=0.01): + """Remove all colinear and duplicate vertices from this object's geometry. + + Note that this does not affect any assigned Apertures, Doors or Shades. + + Args: + tolerance: The minimum distance between a vertex and the boundary segments + at which point the vertex is considered colinear. Default: 0.01, + suitable for objects in meters. + """ + try: + self._geometry = self.geometry.remove_colinear_vertices(tolerance) + except AssertionError as e: # usually a sliver face of some kind + raise ValueError( + 'Face "{}" is invalid with dimensions less than the ' + 'tolerance.\n{}'.format(self.full_id, e)) + self._punched_geometry = None # reset so that it can be re-computed
+ +
[docs] def remove_degenerate_sub_faces(self, tolerance=0.01): + """Remove colinear vertices from sub-faces and eliminate degenerate ones. + + Args: + tolerance: The minimum distance between a vertex and the boundary segments + at which point the vertex is considered colinear. Default: 0.01, + suitable for objects in meters. + """ + for i, ap in enumerate(self._apertures): + try: + ap.remove_colinear_vertices(tolerance) + except ValueError: + self._apertures.pop(i) + for i, dr in enumerate(self._doors): + try: + dr.remove_colinear_vertices(tolerance) + except ValueError: + self._apertures.pop(i)
+ +
[docs] def is_geo_equivalent(self, face, tolerance=0.01): + """Get a boolean for whether this object is geometrically equivalent to another. + + This will also check all child Apertures and Doors for equivalency but not + assigned shades. + + Args: + face: Another Face for which geometric equivalency will be tested. + tolerance: The minimum difference between the coordinate values of two + vertices at which they can be considered geometrically equivalent. + + Returns: + True if geometrically equivalent. False if not geometrically equivalent. + """ + meta_1 = (self.display_name, self.type, self.boundary_condition) + meta_2 = (face.display_name, face.type, face.boundary_condition) + if meta_1 != meta_2: + return False + if abs(self.area - face.area) > tolerance * self.area: + return False + if not self.geometry.is_centered_adjacent(face.geometry, tolerance): + return False + if len(self._apertures) != len(face._apertures): + return False + if len(self._doors) != len(face._doors): + return False + for ap1, ap2 in zip(self._apertures, face._apertures): + if not ap1.is_geo_equivalent(ap2, tolerance): + return False + for dr1, dr2 in zip(self._doors, face._doors): + if not dr1.is_geo_equivalent(dr2, tolerance): + return False + if not self._are_shades_equivalent(face, tolerance): + return False + return True
+ +
[docs] def check_sub_faces_valid(self, tolerance=0.01, angle_tolerance=1, + raise_exception=True, detailed=False): + """Check that sub-faces are co-planar with this Face within the Face boundary. + + Note this does not check the planarity of the sub-faces themselves, whether + they self-intersect, or whether they have a non-zero area. + + Args: + tolerance: The minimum difference between the coordinate values of two + vertices at which they can be considered equivalent. Default: 0.01, + suitable for objects in meters. + angle_tolerance: The max angle in degrees that the plane normals can + differ from one another in order for them to be considered coplanar. + Default: 1 degree. + raise_exception: Boolean to note whether a ValueError should be raised + if an sub-face is not valid. + detailed: Boolean for whether the returned object is a detailed list of + dicts with error info or a string with a message. (Default: False). + + Returns: + A string with the message or a list with dictionaries if detailed is True. + """ + detailed = False if raise_exception else detailed + ap = self.check_apertures_valid(tolerance, angle_tolerance, False, detailed) + dr = self.check_doors_valid(tolerance, angle_tolerance, False, detailed) + full_msgs = ap + dr if detailed else [m for m in (ap, dr) if m != ''] + if raise_exception and len(full_msgs) != 0: + raise ValueError('\n'.join(full_msgs)) + return full_msgs if detailed else '\n'.join(full_msgs)
+ +
[docs] def check_apertures_valid(self, tolerance=0.01, angle_tolerance=1, + raise_exception=True, detailed=False): + """Check that apertures are co-planar with this Face within the Face boundary. + + Note this does not check the planarity of the apertures themselves, whether + they self-intersect, or whether they have a non-zero area. + + Args: + tolerance: The minimum difference between the coordinate values of two + vertices at which they can be considered equivalent. Default: 0.01, + suitable for objects in meters. + angle_tolerance: The max angle in degrees that the plane normals can + differ from one another in order for them to be considered coplanar. + Default: 1 degree. + raise_exception: Boolean to note whether a ValueError should be raised + if an aperture is not valid. + detailed: Boolean for whether the returned object is a detailed list of + dicts with error info or a string with a message. (Default: False). + + Returns: + A string with the message or a list with dictionaries if detailed is True. + """ + detailed = False if raise_exception else detailed + angle_tolerance = math.radians(angle_tolerance) + msgs = [] + for ap in self._apertures: + if not self.geometry.is_sub_face(ap.geometry, tolerance, angle_tolerance): + msg = 'Aperture "{}" is not coplanar or fully bounded by its parent ' \ + 'Face "{}".'.format(ap.full_id, self.full_id) + msg = self._validation_message_child( + msg, ap, detailed, '000104', error_type='Invalid Sub-Face Geometry') + msgs.append(msg) + full_msg = msgs if detailed else '\n'.join(msgs) + if raise_exception and len(msgs) != 0: + raise ValueError(full_msg) + return full_msg
+ +
[docs] def check_doors_valid(self, tolerance=0.01, angle_tolerance=1, + raise_exception=True, detailed=False): + """Check that doors are co-planar with this Face within the Face boundary. + + Note this does not check the planarity of the doors themselves, whether + they self-intersect, or whether they have a non-zero area. + + Args: + tolerance: The minimum difference between the coordinate values of two + vertices at which they can be considered equivalent. Default: 0.01, + suitable for objects in meters. + angle_tolerance: The max angle in degrees that the plane normals can + differ from one another in order for them to be considered coplanar. + Default: 1 degree. + raise_exception: Boolean to note whether a ValueError should be raised + if an door is not valid. + detailed: Boolean for whether the returned object is a detailed list of + dicts with error info or a string with a message. (Default: False). + + Returns: + A string with the message or a list with dictionaries if detailed is True. + """ + detailed = False if raise_exception else detailed + angle_tolerance = math.radians(angle_tolerance) + msgs = [] + for dr in self._doors: + if not self.geometry.is_sub_face(dr.geometry, tolerance, angle_tolerance): + msg = 'Door "{}" is not coplanar or fully bounded by its parent ' \ + 'Face "{}".'.format(dr.full_id, self.full_id) + msg = self._validation_message_child( + msg, dr, detailed, '000104', error_type='Invalid Sub-Face Geometry') + msgs.append(msg) + full_msg = msgs if detailed else '\n'.join(msgs) + if raise_exception and len(msgs) != 0: + raise ValueError(full_msg) + return full_msg
+ +
[docs] def check_sub_faces_overlapping( + self, tolerance=0.01, raise_exception=True, detailed=False): + """Check that this Face's sub-faces do not overlap with one another. + + Args: + tolerance: The minimum distance that two sub-faces must overlap in order + for them to be considered overlapping and invalid. (Default: 0.01, + suitable for objects in meters). + raise_exception: Boolean to note whether a ValueError should be raised + if a sub-faces overlap with one another. + detailed: Boolean for whether the returned object is a detailed list of + dicts with error info or a string with a message. (Default: False). + + Returns: + A string with the message or a list with dictionaries if detailed is True. + """ + sub_faces = self.sub_faces + if len(sub_faces) == 0: + return [] if detailed else '' + sf_groups = self._group_sub_faces_by_overlap(sub_faces, tolerance) + if not all(len(g) == 1 for g in sf_groups): + base_msg = 'Face "{}" contains Apertures and/or ' \ + 'Doors that overlap with each other.'.format(self.full_id) + if raise_exception: + raise ValueError(base_msg) + if not detailed: # just give a message about the Face if not detailed + return base_msg + all_overlaps = [] + for sf_group in sf_groups: + if len(sf_group) != 1: + det_msg = 'The following sub-faces overlap with one another:' \ + '\n{}'.format('\n'.join([sf.full_id for sf in sf_group])) + msg = '{}\n{}'.format(base_msg, det_msg) + err_obj = self._validation_message_child( + msg, sf_group[0], detailed, '000105', + error_type='Overlapping Sub-Face Geometry') + err_obj['element_type'] = 'SubFace' + for ov_obj in sf_group[1:]: + err_obj['element_id'].append(ov_obj.identifier) + err_obj['element_name'].append(ov_obj.display_name) + err_obj['parents'].append(err_obj['parents'][0]) + all_overlaps.append(err_obj) + return all_overlaps + return [] if detailed else ''
+ +
[docs] def check_upside_down(self, angle_tolerance=1, raise_exception=True, detailed=False): + """Check whether the face is pointing in the correct direction for the face type. + + This method will only report Floors that are pointing upwards or RoofCeilings + that are pointed downwards. These cases are likely modeling errors and are in + danger of having their vertices flipped by EnergyPlus, causing them to + not see the sun. + + Args: + angle_tolerance: The max angle in degrees that the Face normal can + differ from up or down before it is considered a case of a downward + pointing RoofCeiling or upward pointing Floor. Default: 1 degree. + raise_exception: Boolean to note whether an ValueError should be + raised if the Face is an an upward pointing Floor or a downward + pointing RoofCeiling. + detailed: Boolean for whether the returned object is a detailed list of + dicts with error info or a string with a message. (Default: False). + + Returns: + A string with the message or a list with a dictionary if detailed is True. + """ + msg = None + if isinstance(self.type, Floor) and self.altitude > 90 - angle_tolerance: + msg = 'Face "{}" is an upward-pointing Floor, which should be ' \ + 'changed to a RoofCeiling.'.format(self.full_id) + elif isinstance(self.type, RoofCeiling) and self.altitude < angle_tolerance - 90: + msg = 'Face "{}" is an downward-pointing RoofCeiling, which should be ' \ + 'changed to a Floor.'.format(self.full_id) + if msg: + full_msg = self._validation_message( + msg, raise_exception, detailed, '000109', + error_type='Upside Down Face') + return full_msg + return [] if detailed else ''
+ +
[docs] def check_planar(self, tolerance=0.01, raise_exception=True, detailed=False): + """Check whether all of the Face's vertices lie within the same plane. + + Args: + tolerance: The minimum distance between a given vertex and a the + object's plane at which the vertex is said to lie in the plane. + Default: 0.01, suitable for objects in meters. + raise_exception: Boolean to note whether an ValueError should be + raised if a vertex does not lie within the object's plane. + detailed: Boolean for whether the returned object is a detailed list of + dicts with error info or a string with a message. (Default: False). + + Returns: + A string with the message or a list with a dictionary if detailed is True. + """ + try: + self.geometry.check_planar(tolerance, raise_exception=True) + except ValueError as e: + msg = 'Face "{}" is not planar.\n{}'.format(self.full_id, e) + full_msg = self._validation_message( + msg, raise_exception, detailed, '000101', + error_type='Non-Planar Geometry') + if detailed: # add the out-of-plane points to helper_geometry + help_pts = [ + p.to_dict() for p in self.geometry.non_planar_vertices(tolerance) + ] + full_msg[0]['helper_geometry'] = help_pts + return full_msg + return [] if detailed else ''
+ +
[docs] def check_self_intersecting(self, tolerance=0.01, raise_exception=True, + detailed=False): + """Check whether the edges of the Face intersect one another (like a bowtie). + + Note that objects that have duplicate vertices will not be considered + self-intersecting and are valid in honeybee. + + Args: + tolerance: The minimum difference between the coordinate values of two + vertices at which they can be considered equivalent. Default: 0.01, + suitable for objects in meters. + raise_exception: If True, a ValueError will be raised if the object + intersects with itself. Default: True. + detailed: Boolean for whether the returned object is a detailed list of + dicts with error info or a string with a message. (Default: False). + + Returns: + A string with the message or a list with a dictionary if detailed is True. + """ + if self.geometry.is_self_intersecting: + msg = 'Face "{}" has self-intersecting edges.'.format(self.full_id) + try: # see if it is self-intersecting because of a duplicate vertex + new_geo = self.geometry.remove_duplicate_vertices(tolerance) + if not new_geo.is_self_intersecting: + return [] if detailed else '' # valid with removed dup vertex + except AssertionError: + pass # degenerate face; treat it as self-intersecting + full_msg = self._validation_message( + msg, raise_exception, detailed, '000102', + error_type='Self-Intersecting Geometry') + if detailed: # add the self-intersection points to helper_geometry + help_pts = [p.to_dict() for p in self.geometry.self_intersection_points] + full_msg[0]['helper_geometry'] = help_pts + return full_msg + return [] if detailed else ''
+ +
[docs] def display_dict(self): + """Get a list of DisplayFace3D dictionaries for visualizing the object.""" + base = [self._display_face(self.punched_geometry, self.type_color)] + for ap in self._apertures: + base.extend(ap.display_dict()) + for dr in self._doors: + base.extend(dr.display_dict()) + for shd in self.shades: + base.extend(shd.display_dict()) + return base
+ + @property + def to(self): + """Face writer object. + + Use this method to access Writer class to write the face in other formats. + + Usage: + + .. code-block:: python + + face.to.idf(face) -> idf string. + face.to.radiance(face) -> Radiance string. + """ + return writer + +
[docs] def to_dict(self, abridged=False, included_prop=None, include_plane=True): + """Return Face as a dictionary. + + Args: + abridged: Boolean to note whether the extension properties of the + object (ie. materials, constructions) should be included in detail + (False) or just referenced by identifier (True). (Default: False). + included_prop: List of properties to filter keys that must be included in + output dictionary. For example ['energy'] will include 'energy' key if + available in properties to_dict. By default all the keys will be + included. To exclude all the keys from extensions use an empty list. + include_plane: Boolean to note wether the plane of the Face3D should be + included in the output. This can preserve the orientation of the + X/Y axes of the plane but is not required and can be removed to + keep the dictionary smaller. (Default: True). + """ + base = {'type': 'Face'} + base['identifier'] = self.identifier + base['display_name'] = self.display_name + base['properties'] = self.properties.to_dict(abridged, included_prop) + enforce_upper_left = True if 'energy' in base['properties'] else False + base['geometry'] = self._geometry.to_dict(include_plane, enforce_upper_left) + + base['face_type'] = self.type.name + if isinstance(self.boundary_condition, Outdoors) and \ + 'energy' in base['properties']: + base['boundary_condition'] = self.boundary_condition.to_dict(full=True) + else: + base['boundary_condition'] = self.boundary_condition.to_dict() + + if self._apertures != []: + base['apertures'] = [ap.to_dict(abridged, included_prop, include_plane) + for ap in self._apertures] + if self._doors != []: + base['doors'] = [dr.to_dict(abridged, included_prop, include_plane) + for dr in self._doors] + self._add_shades_to_dict(base, abridged, included_prop, include_plane) + if self.user_data is not None: + base['user_data'] = self.user_data + return base
+ + def _acceptable_sub_face_check(self, sub_face_type=Aperture): + """Check whether the Face can accept sub-faces and raise an exception if not.""" + assert isinstance(self.boundary_condition, Outdoors), \ + '{} cannot be added to Face "{}" with a {} boundary condition.'.format( + sub_face_type.__name__, self.full_id, self.boundary_condition) + assert not isinstance(self.type, AirBoundary), \ + '{} cannot be added to AirBoundary Face "{}".'.format( + sub_face_type.__name__, self.full_id) + + @staticmethod + def _remove_overlapping_sub_faces(sub_faces, tolerance): + """Get a list of Apertures and/or Doors with no overlaps. + + Args: + sub_faces: A list of Apertures or Doors to be checked for overlapping. + tolerance: The minimum distance from the edge of a neighboring Face3D + at which a point is considered to overlap with that Face3D. + + Returns: + A list of the input sub_faces with smaller overlapping geometries removed. + """ + # group the sub-faces according to the overlaps with one another + grouped_sfs = Face._group_sub_faces_by_overlap(sub_faces, tolerance) + # build a list of sub-faces without any overlaps + clean_sub_faces = [] + for sf_group in grouped_sfs: + if len(sf_group) == 1: + clean_sub_faces.append(sf_group[0]) + else: # take the subface with the largest area + sf_group.sort(key=lambda x: x.area, reverse=True) + clean_sub_faces.append(sf_group[0]) + return clean_sub_faces + + @staticmethod + def _group_sub_faces_by_overlap(sub_faces, tolerance): + """Group a Apertures and/or Doors depending on whether they overlap one another. + + Args: + sub_faces: A list of Apertures or Doors to be checked for overlapping. + tolerance: The minimum distance from the edge of a neighboring Face3D + at which a point is considered to overlap with that Face3D. + + Returns: + A list of lists where each sub-list represents a group of Apertures and/or + Doors that overlap with one another. + """ + # sort the sub-faces by area + sub_faces = list(sorted(sub_faces, key=lambda x: x.area, reverse=True)) + # create polygons for all of the faces + r_plane = sub_faces[0].geometry.plane + polygons = [Polygon2D([r_plane.xyz_to_xy(pt) for pt in face.vertices]) + for face in sub_faces] + # loop through the polygons and check to see if it overlaps with the others + grouped_polys, grouped_sfs = [[polygons[0]]], [[sub_faces[0]]] + for poly, face in zip(polygons[1:], sub_faces[1:]): + group_found = False + for poly_group, face_group in zip(grouped_polys, grouped_sfs): + for oth_poly in poly_group: + if poly.polygon_relationship(oth_poly, tolerance) >= 0: + poly_group.append(poly) + face_group.append(face) + group_found = True + break + if group_found: + break + if not group_found: # the polygon does not overlap with any of the others + grouped_polys.append([poly]) # make a new group for the polygon + grouped_sfs.append([face]) # make a new group for the face + return grouped_sfs + + def __copy__(self): + new_f = Face(self.identifier, self.geometry, self.type, self.boundary_condition) + new_f._display_name = self._display_name + new_f._user_data = None if self.user_data is None else self.user_data.copy() + new_f._apertures = [ap.duplicate() for ap in self._apertures] + new_f._doors = [dr.duplicate() for dr in self._doors] + for ap in new_f._apertures: + ap._parent = new_f + for dr in new_f._doors: + dr._parent = new_f + self._duplicate_child_shades(new_f) + new_f._punched_geometry = self._punched_geometry + new_f._properties._duplicate_extension_attr(self._properties) + return new_f + + def __repr__(self): + return 'Face: %s' % self.display_name
+
+ +
+ +
+
+
+
+

+ Back to top + +

+

+ © Copyright 2023, Ladybug Tools.
+ Created using Sphinx 5.3.0.
+

+
+
+ + \ No newline at end of file diff --git a/docs/_modules/honeybee/facetype.html b/docs/_modules/honeybee/facetype.html new file mode 100644 index 00000000..c9cc3601 --- /dev/null +++ b/docs/_modules/honeybee/facetype.html @@ -0,0 +1,1263 @@ + + + + + + + honeybee.facetype — honeybee documentation + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+ +

Source code for honeybee.facetype

+"""Face Types."""
+from ladybug_geometry.geometry3d.pointvector import Vector3D
+import re
+import math
+
+
+class _FaceType(object):
+    __slots__ = ()
+
+    def __init__(self):
+        pass
+
+    @property
+    def name(self):
+        return self.__class__.__name__
+
+    def ToString(self):
+        return self.__repr__()
+
+    def __eq__(self, other):
+        return self.__class__ == other.__class__
+
+    def __ne__(self, other):
+        return not self.__eq__(other)
+
+    def __repr__(self):
+        return self.name
+
+
+
[docs]class Wall(_FaceType): + """Type for walls.""" + __slots__ = () + pass
+ + +
[docs]class RoofCeiling(_FaceType): + """Type for roofs and ceilings.""" + __slots__ = () + pass
+ + +
[docs]class Floor(_FaceType): + """Type for floors.""" + __slots__ = () + pass
+ + +
[docs]class AirBoundary(_FaceType): + """Type for air boundaries (aka. virtual partitions) between Rooms.""" + __slots__ = () + pass
+ + +class _FaceTypes(object): + """Face types.""" + + def __init__(self): + self._wall = Wall() + self._roof_ceiling = RoofCeiling() + self._floor = Floor() + self._air_boundary = AirBoundary() + self._type_name_dict = None + + @property + def wall(self): + return self._wall + + @property + def roof_ceiling(self): + return self._roof_ceiling + + @property + def floor(self): + return self._floor + + @property + def air_boundary(self): + return self._air_boundary + + def by_name(self, face_type_name): + """Get a Face Type instance from its name. + + This method will correct for capitalization as well as the presence of + spaces and underscores. + + Args: + face_type_name: A text string for the face type (eg. "Wall"). + """ + if self._type_name_dict is None: + self._build_type_name_dict() + try: + return self._type_name_dict[re.sub(r'[\s_]', '', face_type_name.lower())] + except KeyError: + raise ValueError( + '"{}" is not a valid face type name.\nChoose from the following' + ': {}'.format(face_type_name, list(self._type_name_dict.keys()))) + + def _build_type_name_dict(self): + """Build a dictionary that can be used to lookup face types by name.""" + attr = [atr for atr in dir(self) if not atr.startswith('_')] + clean_attr = [re.sub(r'[\s_]', '', atr.lower()) for atr in attr] + self._type_name_dict = {} + for atr_name, atr in zip(clean_attr, attr): + try: + full_attr = getattr(self, '_' + atr) + self._type_name_dict[atr_name] = full_attr + except AttributeError: + pass # callable method that has no static default object + + def __contains__(self, value): + return isinstance(value, _FaceType) + + def __repr__(self): + attr = [atr for atr in dir(self) if not atr.startswith('_') and atr != 'by_name'] + return 'Face Types:\n{}'.format('\n'.join(attr)) + + +face_types = _FaceTypes() + + +
[docs]def get_type_from_normal(normal_vector, roof_angle=60, floor_angle=130): + """Return face type based on the angle between Z axis and normal vector. + + Angles between 0 and roof_angle will be set to roof_ceiling. + Angles between roof_angle and floor_angle will be set to wall. + Angles larger than floor angle will be set to floor. + + Args: + normal_vector: Normal vector as a ladybug_geometry Vector3D. + roof_angle: A number between 0 and 90 to set the angle from the horizontal + plane below which faces will be considered roofs instead of + walls. 90 indicates that all vertical faces are roofs and 0 + indicates that all horizontal faces are walls. (Default: 60, + recommended by the ASHRAE 90.1 standard). + floor_angle: A number between 90 and 180 to set the angle from the horizontal + plane above which faces will be considered floors instead of + walls. 180 indicates that all vertical faces are floors and 0 + indicates that all horizontal faces are walls. (Default: 130, + recommended by the ASHRAE 90.1 standard). + + Returns: + Face type instance. + """ + z_axis = Vector3D(0, 0, 1) + angle = math.degrees(z_axis.angle(normal_vector)) + if angle < roof_angle: + return face_types.roof_ceiling + elif roof_angle <= angle < floor_angle: + return face_types.wall + else: + return face_types.floor + + return face_types.wall
+
+ +
+ +
+
+
+
+

+ Back to top + +

+

+ © Copyright 2023, Ladybug Tools.
+ Created using Sphinx 5.3.0.
+

+
+
+ + \ No newline at end of file diff --git a/docs/_modules/honeybee/logutil.html b/docs/_modules/honeybee/logutil.html new file mode 100644 index 00000000..d799ce7d --- /dev/null +++ b/docs/_modules/honeybee/logutil.html @@ -0,0 +1,1189 @@ + + + + + + + honeybee.logutil — honeybee documentation + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+ +

Source code for honeybee.logutil

+import logging
+from logging.handlers import TimedRotatingFileHandler
+import os
+import tempfile
+
+
+# This is copied from logging module since python 2 doesn't have it under the same name.
+CRITICAL = 50
+FATAL = CRITICAL
+ERROR = 40
+WARNING = 30
+WARN = WARNING
+INFO = 20
+DEBUG = 10
+NOTSET = 0
+
+_name_to_level = {
+    'CRITICAL': CRITICAL,
+    'FATAL': FATAL,
+    'ERROR': ERROR,
+    'WARN': WARNING,
+    'WARNING': WARNING,
+    'INFO': INFO,
+    'DEBUG': DEBUG,
+    'NOTSET': NOTSET,
+}
+
+
+def _get_log_folder():
+    home_folder = os.getenv('HOME') or os.path.expanduser('~')
+    if not os.access(home_folder, os.W_OK):
+        home_folder = tempfile.gettempdir()
+    log_folder = os.path.join(home_folder, '.honeybee')
+    if not os.path.isdir(log_folder):
+        try:
+            os.mkdir(log_folder)
+        except OSError as e:
+            if e.errno != 17:  # avoid race conditions between multiple tasks
+                raise OSError('Failed to create log folder: %s\n%s' % (log_folder, e))
+    return log_folder
+
+
+def _get_log_level(level):
+    level = _name_to_level.get(level)
+    return level or logging.INFO
+
+
+
[docs]def get_logger(name, filename='honeybee.log', file_log_level='DEBUG', + console_log_level='WARNING'): + """Get a logger to be used for each module. + + Args: + name: Logger name. The good practice is to set it to __init__ from inside each + modules. + filename: Logger filename.Setting filename to None will remove the file handler + (Default: honeybee.log). + file_log_level: Log level for file handler as a string (Default: DEBUG). + console_log_level: Log level for stream handler as a string (Default: WARNING). + """ + logger = logging.getLogger(name) + + # create a file handler to log debug and higher level logs + if filename: + log_file = os.path.join(_get_log_folder(), filename) + file_handler = TimedRotatingFileHandler(log_file, when='midnight') + file_format = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') + file_handler.setFormatter(file_format) + file_handler.setLevel(_get_log_level(file_log_level)) + logger.addHandler(file_handler) + + # create a console handler that only prints out errors and warnings + stream_handler = logging.StreamHandler() + stream_format = logging.Formatter('%(name)s - %(levelname)s - %(message)s') + stream_handler.setFormatter(stream_format) + stream_handler.setLevel(_get_log_level(console_log_level)) + + logger.addHandler(stream_handler) + + return logger
+
+ +
+ +
+
+
+
+

+ Back to top + +

+

+ © Copyright 2023, Ladybug Tools.
+ Created using Sphinx 5.3.0.
+

+
+
+ + \ No newline at end of file diff --git a/docs/_modules/honeybee/model.html b/docs/_modules/honeybee/model.html new file mode 100644 index 00000000..c4f89687 --- /dev/null +++ b/docs/_modules/honeybee/model.html @@ -0,0 +1,4364 @@ + + + + + + + honeybee.model — honeybee documentation + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+ +

Source code for honeybee.model

+# coding: utf-8
+"""Honeybee Model."""
+from __future__ import division
+import os
+import sys
+import re
+import json
+import math
+import uuid
+try:  # check if we are in IronPython
+    import cPickle as pickle
+except ImportError:  # wea are in cPython
+    import pickle
+
+from ladybug_geometry.geometry3d import Plane, Face3D, Mesh3D
+from ladybug_geometry.interop.stl import STL
+
+from ._base import _Base
+from .units import conversion_factor_to_meters, UNITS, UNITS_TOLERANCES
+from .checkdup import check_duplicate_identifiers, check_duplicate_identifiers_parent
+from .properties import ModelProperties
+from .room import Room
+from .face import Face
+from .shade import Shade
+from .aperture import Aperture
+from .door import Door
+from .shademesh import ShadeMesh
+from .typing import float_positive, invalid_dict_error, clean_string, \
+    clean_and_number_string
+from .config import folders
+from .boundarycondition import Outdoors, Surface
+from .facetype import AirBoundary, Wall, Floor, RoofCeiling, face_types
+import honeybee.writer.model as writer
+from honeybee.boundarycondition import boundary_conditions as bcs
+try:
+    ad_bc = bcs.adiabatic
+except AttributeError:  # honeybee_energy is not loaded and adiabatic does not exist
+    ad_bc = None
+
+
+
[docs]class Model(_Base): + """A collection of Rooms, Faces, Shades, Apertures, and Doors representing a model. + + Args: + identifier: Text string for a unique Model ID. Must be < 100 characters and + not contain any spaces or special characters. + rooms: A list of Room objects in the model. + orphaned_faces: A list of the Face objects in the model that lack + a parent Room. Note that orphaned Faces are translated to sun-blocking + shade objects in energy simulation. + orphaned_shades: A list of the Shade objects in the model that lack + a parent. + orphaned_apertures: A list of the Aperture objects in the model that lack + a parent Face. Note that orphaned Apertures are translated to sun-blocking + shade objects in energy simulation. + orphaned_doors: A list of the Door objects in the model that lack + a parent Face. Note that orphaned Doors are translated to sun-blocking + shade objects in energy simulation. + shade_meshes: A list of the ShadeMesh objects in the model. + units: Text for the units system in which the model geometry + exists. Default: 'Meters'. Choose from the following: + + * Meters + * Millimeters + * Feet + * Inches + * Centimeters + + tolerance: The maximum difference between x, y, and z values at which + vertices are considered equivalent. Zero indicates that no tolerance + checks should be performed. None indicates that the tolerance will be + set based on the units above, with the tolerance consistently being + between 1 cm and 1 mm (roughly the tolerance implicit in the OpenStudio + SDK and EnergyPlus). (Default: None). + angle_tolerance: The max angle difference in degrees that vertices are allowed + to differ from one another in order to consider them colinear. Zero indicates + that no angle tolerance checks should be performed. (Default: 1.0). + + Properties: + * identifier + * display_name + * units + * tolerance + * angle_tolerance + * rooms + * faces + * apertures + * doors + * shades + * shade_meshes + * indoor_shades + * outdoor_shades + * orphaned_faces + * orphaned_shades + * orphaned_apertures + * orphaned_doors + * stories + * volume + * floor_area + * exposed_area + * exterior_wall_area + * exterior_roof_area + * exterior_aperture_area + * exterior_wall_aperture_area + * exterior_skylight_aperture_area + * min + * max + * top_level_dict + * user_data + """ + __slots__ = ( + '_rooms', '_orphaned_faces', '_orphaned_apertures', '_orphaned_doors', + '_orphaned_shades', '_shade_meshes', + '_units', '_tolerance', '_angle_tolerance' + ) + + UNITS = UNITS + UNITS_TOLERANCES = UNITS_TOLERANCES + + def __init__(self, identifier, rooms=None, orphaned_faces=None, orphaned_shades=None, + orphaned_apertures=None, orphaned_doors=None, shade_meshes=None, + units='Meters', tolerance=None, angle_tolerance=1.0): + """A collection of Rooms, Faces, Apertures, and Doors for an entire model.""" + _Base.__init__(self, identifier) # process the identifier + + self.units = units + self.tolerance = tolerance + self.angle_tolerance = angle_tolerance + + self._rooms = [] + self._orphaned_faces = [] + self._orphaned_apertures = [] + self._orphaned_doors = [] + self._orphaned_shades = [] + self._shade_meshes = [] + if rooms is not None: + for room in rooms: + self.add_room(room) + if orphaned_faces is not None: + for face in orphaned_faces: + self.add_face(face) + if orphaned_apertures is not None: + for aperture in orphaned_apertures: + self.add_aperture(aperture) + if orphaned_doors is not None: + for door in orphaned_doors: + self.add_door(door) + if orphaned_shades is not None: + for shade in orphaned_shades: + self.add_shade(shade) + if shade_meshes is not None: + for shade_mesh in shade_meshes: + self.add_shade_mesh(shade_mesh) + + self._properties = ModelProperties(self) + +
[docs] @classmethod + def from_dict(cls, data): + """Initialize a Model from a dictionary. + + Args: + data: A dictionary representation of a Model object. + """ + # check the type of dictionary + assert data['type'] == 'Model', 'Expected Model dictionary. ' \ + 'Got {}.'.format(data['type']) + + # import the units and tolerance values + units = 'Meters' if 'units' not in data or data['units'] is None \ + else data['units'] + tol = cls.UNITS_TOLERANCES[units] if 'tolerance' not in data or \ + data['tolerance'] is None else data['tolerance'] + angle_tol = 1.0 if 'angle_tolerance' not in data or \ + data['angle_tolerance'] is None else data['angle_tolerance'] + + # import all of the geometry + rooms = None # import rooms + if 'rooms' in data and data['rooms'] is not None: + rooms = [] + for r in data['rooms']: + try: + rooms.append(Room.from_dict(r, tol, angle_tol)) + except Exception as e: + invalid_dict_error(r, e) + orphaned_faces = None # import orphaned faces + if 'orphaned_faces' in data and data['orphaned_faces'] is not None: + orphaned_faces = [] + for f in data['orphaned_faces']: + try: + orphaned_faces.append(Face.from_dict(f)) + except Exception as e: + invalid_dict_error(f, e) + orphaned_apertures = None # import orphaned apertures + if 'orphaned_apertures' in data and data['orphaned_apertures'] is not None: + orphaned_apertures = [] + for a in data['orphaned_apertures']: + try: + orphaned_apertures.append(Aperture.from_dict(a)) + except Exception as e: + invalid_dict_error(a, e) + orphaned_doors = None # import orphaned doors + if 'orphaned_doors' in data and data['orphaned_doors'] is not None: + orphaned_doors = [] + for d in data['orphaned_doors']: + try: + orphaned_doors.append(Door.from_dict(d)) + except Exception as e: + invalid_dict_error(d, e) + orphaned_shades = None # import orphaned shades + if 'orphaned_shades' in data and data['orphaned_shades'] is not None: + orphaned_shades = [] + for s in data['orphaned_shades']: + try: + orphaned_shades.append(Shade.from_dict(s)) + except Exception as e: + invalid_dict_error(s, e) + shade_meshes = None # import shade meshes + if 'shade_meshes' in data and data['shade_meshes'] is not None: + shade_meshes = [] + for sm in data['shade_meshes']: + try: + shade_meshes.append(ShadeMesh.from_dict(sm)) + except Exception as e: + invalid_dict_error(sm, e) + + # build the model object + model = Model( + data['identifier'], rooms, orphaned_faces, orphaned_shades, + orphaned_apertures, orphaned_doors, shade_meshes, + units, tol, angle_tol) + if 'display_name' in data and data['display_name'] is not None: + model.display_name = data['display_name'] + if 'user_data' in data and data['user_data'] is not None: + model.user_data = data['user_data'] + + # assign extension properties to the model + model.properties.apply_properties_from_dict(data) + return model
+ +
[docs] @classmethod + def from_file(cls, hb_file): + """Initialize a Model from a HBJSON or HBpkl file, auto-sensing the type. + + Args: + hb_file: Path to either a HBJSON or HBpkl file. + """ + # sense the file type from the first character to avoid maxing memory with JSON + # this is needed since queenbee overwrites all file extensions + with open(hb_file) as inf: + first_char = inf.read(1) + is_json = True if first_char == '{' else False + # load the file using either HBJSON pathway or HBpkl + if is_json: + return cls.from_hbjson(hb_file) + return cls.from_hbpkl(hb_file)
+ +
[docs] @classmethod + def from_hbjson(cls, hbjson_file): + """Initialize a Model from a HBJSON file. + + Args: + hbjson_file: Path to HBJSON file. + """ + assert os.path.isfile(hbjson_file), 'Failed to find %s' % hbjson_file + if sys.version_info < (3, 0): + with open(hbjson_file) as inf: + data = json.load(inf) + else: + with open(hbjson_file, encoding='utf-8') as inf: + data = json.load(inf) + return cls.from_dict(data)
+ +
[docs] @classmethod + def from_hbpkl(cls, hbpkl_file): + """Initialize a Model from a HBpkl file. + + Args: + hbpkl_file: Path to HBpkl file. + """ + assert os.path.isfile(hbpkl_file), 'Failed to find %s' % hbpkl_file + with open(hbpkl_file, 'rb') as inf: + data = pickle.load(inf) + return cls.from_dict(data)
+ +
[docs] @classmethod + def from_stl(cls, file_path, geometry_to_faces=False, units='Meters', + tolerance=None, angle_tolerance=1.0): + """Create a Honeybee Model from an STL file. + + Args: + file_path: Path to an STL file as a text string. The STL file can be + in either ASCII or binary format. + geometry_to_faces: A boolean to note whether the geometry in the STL + file should be imported as Faces (with Walls/Floors/RoofCeiling + set according to the normal). If False, all geometry will be + imported as ShadeMeshes instead of Faces. (Default: False). + units: Text for the units system in which the model geometry + exists. Default: 'Meters'. Choose from the following: + + * Meters + * Millimeters + * Feet + * Inches + * Centimeters + + tolerance: The maximum difference between x, y, and z values at which + vertices are considered equivalent. Zero indicates that no tolerance + checks should be performed. None indicates that the tolerance will be + set based on the units above, with the tolerance consistently being + between 1 cm and 1 mm (roughly the tolerance implicit in the OpenStudio + SDK and EnergyPlus). (Default: None). + angle_tolerance: The max angle difference in degrees that vertices + are allowed to differ from one another in order to consider them + colinear. Zero indicates that no angle tolerance checks should be + performed. (Default: 1.0). + """ + stl_obj = STL.from_file(file_path) + all_id = clean_string(stl_obj.name) + all_geo = [] + if geometry_to_faces: + + for verts, normal in zip(stl_obj.face_vertices, stl_obj.face_normals): + all_geo.append(Face3D(verts, plane=Plane(normal, verts[0]))) + hb_objs = [Face(all_id + '_' + str(uuid.uuid4())[:8], go) for go in all_geo] + return Model(all_id, orphaned_faces=hb_objs, units=units, + tolerance=tolerance, angle_tolerance=angle_tolerance) + else: + mesh3d = Mesh3D.from_face_vertices(stl_obj.face_vertices) + hb_objs = [ShadeMesh(all_id, mesh3d)] + return Model(all_id, shade_meshes=hb_objs, units=units, + tolerance=tolerance, angle_tolerance=angle_tolerance)
+ +
[docs] @classmethod + def from_sync(cls, base_model, other_model, sync_instructions): + """Initialize a Model from two models and instructions for syncing them. + + The SyncInstructions dictionary schema is essentially a variant of the + ComparisonReport schema that can be obtained by calling + base_model.comparison_report(other_model). The main difference is + that the XXX_changed properties should be replaced with update_XXX properties + for whether the change from the other_model should be accepted into + the new model or rejected from it. + + Args: + base_model: An base Honeybee Model that forms the base of + the new model to be created. + other_model: An other Honeybee Model that contains changes to + the base model to be merged into the base_model. + sync_instructions: A dictionary of SyncInstructions that states which + changes from the other_model should be accepted or rejected + when building a new Model from the base_model. + """ + # make sure the unit systems of the two models align + if base_model.units != other_model.units: + other_model = other_model.duplicate() + other_model.convert_to_units(base_model.units) + # set up dictionaries of objects and lists of changes + exist_dict = base_model.top_level_dict + other_dict = other_model.top_level_dict + add_dict = { + 'Room': [], 'Face': [], 'Aperture': [], 'Door': [], + 'Shade': [], 'ShadeMesh': [] + } + del_dict = { + 'Room': [], 'Face': [], 'Aperture': [], 'Door': [], + 'Shade': [], 'ShadeMesh': [] + } + # loop through the changed objects and record changes + if 'changed_objects' in sync_instructions: + for change in sync_instructions['changed_objects']: + ex_obj = exist_dict[change['element_id']] + up_obj = other_dict[change['element_id']] + base_obj = up_obj if 'update_geometry' in change \ + and change['update_geometry'] else ex_obj + base_obj.properties._update_by_sync( + change, ex_obj.properties, up_obj.properties) + del_dict[change['element_type']].append(change['element_id']) + add_dict[change['element_type']].append(base_obj) + # loop through deleted objects and record changes + if 'deleted_objects' in sync_instructions: + for change in sync_instructions['deleted_objects']: + del_dict[change['element_type']].append(change['element_id']) + # loop through added objects and record changes + if 'added_objects' in sync_instructions: + for change in sync_instructions['added_objects']: + up_obj = other_dict[change['element_id']] + add_dict[change['element_type']].append(up_obj) + # duplicate the base model and make changes to it + new_model = base_model.duplicate() + new_model.remove_rooms(del_dict['Room']) + new_model.remove_faces(del_dict['Face']) + new_model.remove_apertures(del_dict['Aperture']) + new_model.remove_doors(del_dict['Door']) + new_model.remove_shades(del_dict['Shade']) + new_model.remove_shade_meshes(del_dict['ShadeMesh']) + new_model.add_rooms(add_dict['Room']) + new_model.add_faces(add_dict['Face']) + new_model.add_apertures(add_dict['Aperture']) + new_model.add_doors(add_dict['Door']) + new_model.add_shades(add_dict['Shade']) + new_model.add_shade_meshes(add_dict['ShadeMesh']) + return new_model
+ +
[docs] @classmethod + def from_sync_files( + cls, base_model_file, other_model_file, sync_instructions_file): + """Initialize a Model from two model files and instructions for syncing them. + + Args: + base_model_file: An base Honeybee Model (as HBJSON or HBPkl) + that forms the base of the new model to be created. + other_model_file: An other Honeybee Model (as HBJSON or HBPkl) + that contains changes to the base model to be merged into + the base_model. + sync_instructions: A JSON of SyncInstructions that states which + changes from the other_model should be accepted or rejected + when building a new Model from the base_model. The SyncInstructions + schema is essentially a variant of the ComparisonReport schema + that can be obtained by calling base_model.comparison_report( + other_model). The main difference is that the XXX_changed + properties should be replaced with update_XXX properties for + whether the change from the other_model should be accepted into + the new model or rejected from it. + """ + base_model = cls.from_file(base_model_file) + other_model = cls.from_file(other_model_file) + assert os.path.isfile(sync_instructions_file), \ + 'Failed to find %s' % sync_instructions_file + if sys.version_info < (3, 0): + with open(sync_instructions_file) as inf: + sync_instructions = json.load(inf) + else: + with open(sync_instructions_file, encoding='utf-8') as inf: + sync_instructions = json.load(inf) + return cls.from_sync(base_model, other_model, sync_instructions)
+ +
[docs] @classmethod + def from_objects(cls, identifier, objects, units='Meters', + tolerance=None, angle_tolerance=1.0): + """Initialize a Model from a list of any type of honeybee-core geometry objects. + + Args: + identifier: Text string for a unique Model ID. Must be < 100 characters and + not contain any spaces or special characters. + objects: A list of honeybee Rooms, Faces, Shades, ShadeMEshes, + Apertures and Doors. + units: Text for the units system in which the model geometry + exists. Default: 'Meters'. Choose from the following: + + * Meters + * Millimeters + * Feet + * Inches + * Centimeters + + tolerance: The maximum difference between x, y, and z values at which + vertices are considered equivalent. Zero indicates that no tolerance + checks should be performed. None indicates that the tolerance will be + set based on the units above, with the tolerance consistently being + between 1 cm and 1 mm (roughly the tolerance implicit in the OpenStudio + SDK and EnergyPlus). (Default: None). + angle_tolerance: The max angle difference in degrees that vertices + are allowed to differ from one another in order to consider them + colinear. Zero indicates that no angle tolerance checks should be + performed. (Default: 1.0). + """ + rooms = [] + faces = [] + shades = [] + shade_meshes = [] + apertures = [] + doors = [] + for obj in objects: + if isinstance(obj, Room): + rooms.append(obj) + elif isinstance(obj, Face): + faces.append(obj) + elif isinstance(obj, Shade): + shades.append(obj) + elif isinstance(obj, ShadeMesh): + shade_meshes.append(obj) + elif isinstance(obj, Aperture): + apertures.append(obj) + elif isinstance(obj, Door): + doors.append(obj) + else: + raise TypeError('Expected Room, Face, Shade, Aperture or Door ' + 'for Model. Got {}'.format(type(obj))) + + return cls(identifier, rooms, faces, shades, apertures, doors, shade_meshes, + units, tolerance, angle_tolerance)
+ +
[docs] @classmethod + def from_shoe_box( + cls, width, depth, height, orientation_angle=0, window_ratio=0, + adiabatic=True, units='Meters', tolerance=None, angle_tolerance=1.0): + """Create a model with a single shoe box Room. + + Args: + width: Number for the width of the box (in the X direction). + depth: Number for the depth of the box (in the Y direction). + height: Number for the height of the box (in the Z direction). + orientation_angle: A number between 0 and 360 for the clockwise + orientation of the box in degrees. (0=North, 90=East, 180=South, + 270=West). (Default: 0). + window_ratio: A number between 0 and 1 (but not equal to 1) for the ratio + between aperture area and area of the face pointing towards the + orientation-angle. Using 0 will generate no windows. (Default: 0). + adiabatic: Boolean to note whether the faces that are not in the direction + of the orientation-angle are adiabatic or outdoors. (Default: True) + units: Text for the units system in which the model geometry + exists. (Default: 'Meters'). + tolerance: The maximum difference between x, y, and z values at which + vertices are considered equivalent. Zero indicates that no tolerance + checks should be performed. None indicates that the tolerance will be + set based on the units above, with the tolerance consistently being + between 1 cm and 1 mm (roughly the tolerance implicit in the OpenStudio + SDK and EnergyPlus). (Default: None). + angle_tolerance: The max angle difference in degrees that vertices + are allowed to differ from one another in order to consider them + colinear. Zero indicates that no angle tolerance checks should be + performed. (Default: 1.0). + """ + # create the box room and assign all of the attributes + unique_id = str(uuid.uuid4())[:8] # unique identifier for the shoe box + tolerance = tolerance if tolerance is not None else UNITS_TOLERANCES[units] + room_id = 'Shoe_Box_Room_{}'.format(unique_id) + room = Room.from_box(room_id, width, depth, height, orientation_angle) + room.display_name = 'Shoe_Box_Room' + front_face = room[1] + front_face.apertures_by_ratio(window_ratio, tolerance) + if adiabatic and ad_bc: + room[0].boundary_condition = ad_bc # make the floor adiabatic + for face in room[2:]: # make all other face adiabatic + face.boundary_condition = ad_bc + # create the model object + model_id = 'Shoe_Box_Model_{}'.format(unique_id) + return cls(model_id, [room], units=units, tolerance=tolerance, + angle_tolerance=angle_tolerance)
+ +
[docs] @classmethod + def from_rectangle_plan( + cls, width, length, floor_to_floor_height, perimeter_offset=0, story_count=1, + orientation_angle=0, outdoor_roof=True, ground_floor=True, + units='Meters', tolerance=None, angle_tolerance=1.0): + """Create a model with a rectangular floor plan. + + Note that the resulting Rooms in the model won't have any windows or solved + adjacencies. These can be added by using the Model.solve_adjacency method + and the various Face.apertures_by_XXX methods. + + Args: + width: Number for the width of the plan (in the X direction). + length: Number for the length of the plan (in the Y direction). + floor_to_floor_height: Number for the height of each floor of the model + (in the Z direction). + perimeter_offset: An optional positive number that will be used to offset + the perimeter to create core/perimeter Rooms. If this value is 0, + no offset will occur and each floor will have one Room. (Default: 0). + story_count: An integer for the number of stories to generate. (Default: 1). + orientation_angle: A number between 0 and 360 for the counterclockwise + orientation that the width of the box faces. (0=North, 90=East, + 180=South, 270=West). (Default: 0). + outdoor_roof: Boolean to note whether the roof faces of the top floor + should be outdoor or adiabatic. (Default: True). + ground_floor: Boolean to note whether the floor faces of the bottom + floor should be ground or adiabatic. (Default: True). + units: Text for the units system in which the model geometry + exists. (Default: 'Meters'). + tolerance: The maximum difference between x, y, and z values at which + vertices are considered equivalent. Zero indicates that no tolerance + checks should be performed. None indicates that the tolerance will be + set based on the units above, with the tolerance consistently being + between 1 cm and 1 mm (roughly the tolerance implicit in the OpenStudio + SDK and EnergyPlus). (Default: None). + angle_tolerance: The max angle difference in degrees that vertices + are allowed to differ from one another in order to consider them + colinear. Zero indicates that no angle tolerance checks should be + performed. (Default: 1.0). + """ + # create the honeybee rooms + tolerance = tolerance if tolerance is not None else UNITS_TOLERANCES[units] + unique_id = str(uuid.uuid4())[:8] # unique identifier for the model + rooms = Room.rooms_from_rectangle_plan( + width, length, floor_to_floor_height, perimeter_offset, story_count, + orientation_angle, outdoor_roof, ground_floor, unique_id, tolerance) + # create the model object + model_id = 'Rectangle_Plan_Model_{}'.format(unique_id) + return cls(model_id, rooms, units=units, tolerance=tolerance, + angle_tolerance=angle_tolerance)
+ +
[docs] @classmethod + def from_l_shaped_plan( + cls, width_1, length_1, width_2, length_2, floor_to_floor_height, + perimeter_offset=0, story_count=1, orientation_angle=0, + outdoor_roof=True, ground_floor=True, + units='Meters', tolerance=None, angle_tolerance=1.0): + """Create a model with an L-shaped floor plan. + + Note that the resulting Rooms in the model won't have any windows or solved + adjacencies. These can be added by using the Model.solve_adjacency method + and the various Face.apertures_by_XXX methods. + + Args: + width_1: Number for the width of the lower part of the L segment. + length_1: Number for the length of the lower part of the L segment, not + counting the overlap between the upper and lower segments. + width_2: Number for the width of the upper (left) part of the L segment. + length_2: Number for the length of the upper (left) part of the L segment, + not counting the overlap between the upper and lower segments. + floor_to_floor_height: Number for the height of each floor of the model + (in the Z direction). + perimeter_offset: An optional positive number that will be used to offset + the perimeter to create core/perimeter Rooms. If this value is 0, + no offset will occur and each floor will have one Room. (Default: 0). + story_count: An integer for the number of stories to generate. (Default: 1). + orientation_angle: A number between 0 and 360 for the counterclockwise + orientation that the width of the box faces. (0=North, 90=East, + 180=South, 270=West). (Default: 0). + outdoor_roof: Boolean to note whether the roof faces of the top floor + should be outdoor or adiabatic. (Default: True). + ground_floor: Boolean to note whether the floor faces of the bottom + floor should be ground or adiabatic. (Default: True). + units: Text for the units system in which the model geometry + exists. (Default: 'Meters'). + tolerance: The maximum difference between x, y, and z values at which + vertices are considered equivalent. Zero indicates that no tolerance + checks should be performed. None indicates that the tolerance will be + set based on the units above, with the tolerance consistently being + between 1 cm and 1 mm (roughly the tolerance implicit in the OpenStudio + SDK and EnergyPlus). (Default: None). + angle_tolerance: The max angle difference in degrees that vertices + are allowed to differ from one another in order to consider them + colinear. Zero indicates that no angle tolerance checks should be + performed. (Default: 1.0). + """ + # create the honeybee rooms + tolerance = tolerance if tolerance is not None else UNITS_TOLERANCES[units] + unique_id = str(uuid.uuid4())[:8] # unique identifier for the model + rooms = Room.rooms_from_l_shaped_plan( + width_1, length_1, width_2, length_2, floor_to_floor_height, + perimeter_offset, story_count, + orientation_angle, outdoor_roof, ground_floor, unique_id, tolerance) + # create the model object + model_id = 'L_Shaped_Plan_Model_{}'.format(unique_id) + return cls(model_id, rooms, units=units, tolerance=tolerance, + angle_tolerance=angle_tolerance)
+ + @property + def units(self): + """Get or set Text for the units system in which the model geometry exists.""" + return self._units + + @units.setter + def units(self, value): + value = value.title() + assert value in UNITS, '{} is not supported as a units system. ' \ + 'Choose from the following: {}'.format(value, UNITS) + self._units = value + + @property + def tolerance(self): + """Get or set a number for the max meaningful difference between x, y, z values. + + This value should be in the Model's units. Zero indicates cases + where no tolerance checks should be performed. + """ + return self._tolerance + + @tolerance.setter + def tolerance(self, value): + self._tolerance = float_positive(value, 'model tolerance') if value is not None \ + else UNITS_TOLERANCES[self.units] + + @property + def angle_tolerance(self): + """Get or set a number for the max meaningful angle difference in degrees. + + Face3D normal vectors differing by this amount are not considered parallel + and Face3D segments that differ from 180 by this amount are not considered + colinear. Zero indicates cases where no angle_tolerance checks should be + performed. + """ + return self._angle_tolerance + + @angle_tolerance.setter + def angle_tolerance(self, value): + self._angle_tolerance = float_positive(value, 'model angle_tolerance') + + @property + def rooms(self): + """Get a tuple of all Room objects in the model.""" + return tuple(self._rooms) + + @property + def faces(self): + """Get a list of all Face objects in the model.""" + child_faces = [face for room in self._rooms for face in room._faces] + return child_faces + self._orphaned_faces + + @property + def apertures(self): + """Get a list of all Aperture objects in the model.""" + child_apertures = [] + for room in self._rooms: + for face in room._faces: + child_apertures.extend(face._apertures) + for face in self._orphaned_faces: + child_apertures.extend(face._apertures) + return child_apertures + self._orphaned_apertures + + @property + def doors(self): + """Get a list of all Door objects in the model.""" + child_doors = [] + for room in self._rooms: + for face in room._faces: + child_doors.extend(face._doors) + for face in self._orphaned_faces: + child_doors.extend(face._doors) + return child_doors + self._orphaned_doors + + @property + def shades(self): + """Get a list of all Shade objects in the model.""" + child_shades = [] + for room in self._rooms: + child_shades.extend(room.shades) + for face in room.faces: + child_shades.extend(face.shades) + for ap in face._apertures: + child_shades.extend(ap.shades) + for dr in face._doors: + child_shades.extend(dr.shades) + for face in self._orphaned_faces: + child_shades.extend(face.shades) + for ap in face._apertures: + child_shades.extend(ap.shades) + for dr in face._doors: + child_shades.extend(dr.shades) + for ap in self._orphaned_apertures: + child_shades.extend(ap.shades) + for dr in self._orphaned_doors: + child_shades.extend(dr.shades) + return child_shades + self._orphaned_shades + + @property + def indoor_shades(self): + """Get a list of all indoor Shade objects in the model.""" + child_shades = [] + for room in self._rooms: + child_shades.extend(room._indoor_shades) + for face in room.faces: + child_shades.extend(face._indoor_shades) + for ap in face._apertures: + child_shades.extend(ap._indoor_shades) + for dr in face._doors: + child_shades.extend(dr._indoor_shades) + for face in self._orphaned_faces: + child_shades.extend(face._indoor_shades) + for ap in face._apertures: + child_shades.extend(ap._indoor_shades) + for dr in face._doors: + child_shades.extend(dr._indoor_shades) + for ap in self._orphaned_apertures: + child_shades.extend(ap._indoor_shades) + for dr in self._orphaned_doors: + child_shades.extend(dr._indoor_shades) + return child_shades + + @property + def outdoor_shades(self): + """Get a list of all outdoor Shade objects in the model. + + This includes all of the orphaned_shades. + """ + child_shades = [] + for room in self._rooms: + child_shades.extend(room._outdoor_shades) + for face in room.faces: + child_shades.extend(face._outdoor_shades) + for ap in face._apertures: + child_shades.extend(ap._outdoor_shades) + for dr in face._doors: + child_shades.extend(dr._outdoor_shades) + for face in self._orphaned_faces: + child_shades.extend(face._outdoor_shades) + for ap in face._apertures: + child_shades.extend(ap._outdoor_shades) + for dr in face._doors: + child_shades.extend(dr._outdoor_shades) + for ap in self._orphaned_apertures: + child_shades.extend(ap._outdoor_shades) + for dr in self._orphaned_doors: + child_shades.extend(dr._outdoor_shades) + return child_shades + self._orphaned_shades + + @property + def orphaned_faces(self): + """Get a tuple of all Face objects without parent Rooms in the model.""" + return tuple(self._orphaned_faces) + + @property + def orphaned_apertures(self): + """Get a tuple of all Aperture objects without parent Faces in the model.""" + return tuple(self._orphaned_apertures) + + @property + def orphaned_doors(self): + """Get a tuple of all Door objects without parent Faces in the model.""" + return tuple(self._orphaned_doors) + + @property + def orphaned_shades(self): + """Get a tuple of all Shade objects without parent Rooms in the model.""" + return tuple(self._orphaned_shades) + + @property + def shade_meshes(self): + """Get a tuple of all ShadeMesh objects in the model.""" + return tuple(self._shade_meshes) + + @property + def stories(self): + """Get a list of text for each unique story identifier in the Model. + + Note that this will be an empty list if the model has to rooms. + """ + _stories = set() + for room in self._rooms: + if room.story is not None: + _stories.add(room.story) + return list(_stories) + + @property + def volume(self): + """Get the combined volume of all rooms in the Model. + + Note that this property accounts for the room multipliers. Also note that, + if this model's rooms are not closed solids, the value of this property + will not be accurate. + """ + return sum([room.volume * room.multiplier for room in self._rooms]) + + @property + def floor_area(self): + """Get the combined area of all room floor faces in the Model. + + Note that this property accounts for the room multipliers. + """ + return sum([room.floor_area * room.multiplier for room in self._rooms + if not room.exclude_floor_area]) + + @property + def exposed_area(self): + """Get the combined area of all room faces with outdoor boundary conditions. + + Useful for estimating infiltration, often expressed as a flow per unit exposed + envelope area. Note that this property accounts for the room multipliers. + """ + return sum([room.exposed_area * room.multiplier for room in self._rooms]) + + @property + def exterior_wall_area(self): + """Get the combined area of all exterior walls on the model's rooms. + + This is NOT the area of the wall's punched_geometry and it includes BOTH + the area of opaque and transparent parts of the walls. Note that this + property accounts for the room multipliers. + """ + return sum([room.exterior_wall_area * room.multiplier for room in self._rooms]) + + @property + def exterior_roof_area(self): + """Get the combined area of all exterior roofs on the model's rooms. + + This is NOT the area of the roof's punched_geometry and it includes BOTH + the area of opaque and transparent parts of the roofs. Note that this + property accounts for the room multipliers. + """ + return sum([room.exterior_roof_area * room.multiplier for room in self._rooms]) + + @property + def exterior_aperture_area(self): + """Get the combined area of all exterior apertures on the model's rooms. + + Note that this property accounts for the room multipliers. + """ + return sum([room.exterior_aperture_area * room.multiplier + for room in self._rooms]) + + @property + def exterior_wall_aperture_area(self): + """Get the combined area of all apertures on exterior walls of the model's rooms. + + Note that this property accounts for the room multipliers. + """ + return sum([room.exterior_wall_aperture_area * room.multiplier + for room in self._rooms]) + + @property + def exterior_skylight_aperture_area(self): + """Get the combined area of all apertures on exterior roofs of the model's rooms. + + Note that this property accounts for the room multipliers. + """ + return sum([room.exterior_skylight_aperture_area * room.multiplier + for room in self._rooms]) + + @property + def min(self): + """Get a Point3D for the min bounding box vertex in the XY plane.""" + return self._calculate_min(self._all_objects()) + + @property + def max(self): + """Get a Point3D for the max bounding box vertex in the XY plane.""" + return self._calculate_max(self._all_objects()) + + @property + def top_level_dict(self): + """Get dictionary of top-level model objects with identifiers as the keys. + + This is useful for matching these objects to others using identifiers. + """ + base = {r.identifier: r for r in self._rooms} + for f in self._orphaned_faces: + base[f.identifier] = f + for a in self._orphaned_apertures: + base[a.identifier] = a + for d in self._orphaned_doors: + base[d.identifier] = d + for s in self._orphaned_shades: + base[s.identifier] = s + for sm in self._shade_meshes: + base[sm.identifier] = sm + return base + +
[docs] def add_model(self, other_model): + """Add another Model object to this model.""" + assert isinstance(other_model, Model), \ + 'Expected Model. Got {}.'.format(type(other_model)) + if self.units != other_model.units: + other_model.convert_to_units(self.units) + for room in other_model._rooms: + self._rooms.append(room) + for face in other_model._orphaned_faces: + self._orphaned_faces.append(face) + for shade in other_model._orphaned_shades: + self._orphaned_shades.append(shade) + for shade_mesh in other_model._shade_meshes: + self._shade_meshes.append(shade_mesh) + for aperture in other_model._orphaned_apertures: + self._orphaned_apertures.append(aperture) + for door in other_model._orphaned_doors: + self._orphaned_doors.append(door)
+ +
[docs] def add_room(self, obj): + """Add a Room object to the model.""" + assert isinstance(obj, Room), 'Expected Room. Got {}.'.format(type(obj)) + self._rooms.append(obj)
+ +
[docs] def add_face(self, obj): + """Add an orphaned Face object without a parent to the model.""" + assert isinstance(obj, Face), 'Expected Face. Got {}.'.format(type(obj)) + assert not obj.has_parent, 'Face "{}"" has a parent Room. Add the Room to '\ + 'the model instead of the Face.'.format(obj.display_name) + self._orphaned_faces.append(obj)
+ +
[docs] def add_aperture(self, obj): + """Add an orphaned Aperture object to the model.""" + assert isinstance(obj, Aperture), 'Expected Aperture. Got {}.'.format(type(obj)) + assert not obj.has_parent, 'Aperture "{}"" has a parent Face. Add the Face to '\ + 'the model instead of the Aperture.'.format(obj.display_name) + self._orphaned_apertures.append(obj)
+ +
[docs] def add_door(self, obj): + """Add an orphaned Door object to the model.""" + assert isinstance(obj, Door), 'Expected Door. Got {}.'.format(type(obj)) + assert not obj.has_parent, 'Door "{}"" has a parent Face. Add the Face to '\ + 'the model instead of the Door.'.format(obj.display_name) + self._orphaned_doors.append(obj)
+ +
[docs] def add_shade(self, obj): + """Add an orphaned Shade object to the model, typically representing context.""" + assert isinstance(obj, Shade), 'Expected Shade. Got {}.'.format(type(obj)) + assert not obj.has_parent, 'Shade "{}"" has a parent object. Add the object to '\ + 'the model instead of the Shade.'.format(obj.display_name) + self._orphaned_shades.append(obj)
+ +
[docs] def add_shade_mesh(self, obj): + """Add a ShadeMesh object to the model.""" + assert isinstance(obj, ShadeMesh), 'Expected ShadeMesh. Got {}.'.format(type(obj)) + self._shade_meshes.append(obj)
+ +
[docs] def remove_rooms(self, room_ids=None): + """Remove Rooms from the model. + + Args: + room_ids: An optional list of Room identifiers to only remove certain rooms + from the model. If None, all Rooms will be removed. (Default: None). + """ + self._rooms = self._remove_by_ids(self.rooms, room_ids)
+ +
[docs] def remove_faces(self, face_ids=None): + """Remove orphaned Faces from the model. + + Args: + face_ids: An optional list of Face identifiers to only remove certain faces + from the model. If None, all Faces will be removed. (Default: None). + """ + self._orphaned_faces = self._remove_by_ids(self._orphaned_faces, face_ids)
+ +
[docs] def remove_apertures(self, aperture_ids=None): + """Remove orphaned Apertures from the model. + + Args: + aperture_ids: An optional list of Aperture identifiers to only remove + certain apertures from the model. If None, all Apertures will + be removed. (Default: None). + """ + self._orphaned_apertures = self._remove_by_ids( + self._orphaned_apertures, aperture_ids)
+ +
[docs] def remove_doors(self, door_ids=None): + """Remove orphaned Doors from the model. + + Args: + door_ids: An optional list of Door identifiers to only remove certain doors + from the model. If None, all Doors will be removed. (Default: None). + """ + self._orphaned_doors = self._remove_by_ids(self._orphaned_doors, door_ids)
+ +
[docs] def remove_shades(self, shade_ids=None): + """Remove orphaned Shades from the model. + + Args: + shade_ids: An optional list of Shade identifiers to only remove + certain shades from the model. If None, all Shades will be + removed. (Default: None). + """ + self._orphaned_shades = self._remove_by_ids(self._orphaned_shades, shade_ids)
+ +
[docs] def remove_shade_meshes(self, shade_mesh_ids=None): + """Remove ShadeMeshes from the model. + + Args: + shade_mesh_ids: An optional list of ShadeMesh identifiers to only remove + certain shades from the model. If None, all Shades will be + removed. (Default: None). + """ + self._shade_meshes = self._remove_by_ids(self._shade_meshes, shade_mesh_ids)
+ +
[docs] def remove_assigned_apertures(self): + """Remove all Apertures assigned to the model's Faces. + + This includes nested apertures like those assigned to Faces with parent Rooms. + """ + for room in self._rooms: + for face in room.faces: + face.remove_apertures() + for face in self._orphaned_faces: + face.remove_apertures()
+ +
[docs] def remove_assigned_doors(self): + """Remove all Doors assigned to the model's Faces. + + This includes nested doors like those assigned to Faces with parent Rooms. + """ + for room in self._rooms: + for face in room.faces: + face.remove_doors() + for face in self._orphaned_faces: + face.remove_doors()
+ +
[docs] def remove_assigned_shades(self): + """Remove all Shades assigned to the model's Rooms, Faces, Apertures and Doors. + + This includes nested shades like those assigned to Apertures with parent + Faces that have parent Rooms. + """ + for room in self._rooms: + room.remove_shades() + for face in room.faces: + face.remove_shades() + for ap in face.apertures: + ap.remove_shades() + for dr in face.doors: + dr.remove_shades() + for face in self._orphaned_faces: + face.remove_shades() + for ap in face.apertures: + ap.remove_shades() + for dr in face.doors: + dr.remove_shades() + for aperture in self._orphaned_apertures: + aperture.remove_shades() + for door in self._orphaned_doors: + door.remove_shades()
+ +
[docs] def remove_all_apertures(self): + """Remove all Apertures from the model. + + This includes assigned apertures as well as orphaned apertures. + """ + self.remove_apertures() + self.remove_assigned_apertures()
+ +
[docs] def remove_all_doors(self): + """Remove all Doors from the model. + + This includes assigned doors as well as orphaned doors. + """ + self.remove_doors() + self.remove_assigned_doors()
+ +
[docs] def remove_all_shades(self): + """Remove all Shades from the model. + + This includes assigned shades as well as orphaned shades. + """ + self.remove_shades() + self.remove_assigned_shades()
+ +
[docs] def add_rooms(self, objs): + """Add a list of Room objects to the model.""" + for obj in objs: + self.add_room(obj)
+ +
[docs] def add_faces(self, objs): + """Add a list of orphaned Face objects to the model.""" + for obj in objs: + self.add_face(obj)
+ +
[docs] def add_apertures(self, objs): + """Add a list of orphaned Aperture objects to the model.""" + for obj in objs: + self.add_aperture(obj)
+ +
[docs] def add_doors(self, objs): + """Add a list of orphaned Door objects to the model.""" + for obj in objs: + self.add_door(obj)
+ +
[docs] def add_shades(self, objs): + """Add a list of orphaned Shade objects to the model.""" + for obj in objs: + self.add_shade(obj)
+ +
[docs] def add_shade_meshes(self, objs): + """Add a list of ShadeMesh objects to the model.""" + for obj in objs: + self.add_shade_mesh(obj)
+ +
[docs] def rooms_by_identifier(self, identifiers): + """Get a list of Room objects in the model given the Room identifiers.""" + rooms, missing_ids = [], [] + model_rooms = self._rooms + for obj_id in identifiers: + for room in model_rooms: + if room.identifier == obj_id: + rooms.append(room) + break + else: + missing_ids.append(obj_id) + if len(missing_ids) != 0: + all_objs = ' '.join(['"' + rid + '"' for rid in missing_ids]) + raise ValueError( + 'The following Rooms were not found in the model: {}'.format(all_objs) + ) + return rooms
+ +
[docs] def faces_by_identifier(self, identifiers): + """Get a list of Face objects in the model given the Face identifiers.""" + faces, missing_ids = [], [] + model_faces = self.faces + for obj_id in identifiers: + for face in model_faces: + if face.identifier == obj_id: + faces.append(face) + break + else: + missing_ids.append(obj_id) + if len(missing_ids) != 0: + all_objs = ' '.join(['"' + rid + '"' for rid in missing_ids]) + raise ValueError( + 'The following Faces were not found in the model: {}'.format(all_objs) + ) + return faces
+ +
[docs] def apertures_by_identifier(self, identifiers): + """Get a list of Aperture objects in the model given the Aperture identifiers.""" + apertures, missing_ids = [], [] + model_apertures = self.apertures + for obj_id in identifiers: + for aperture in model_apertures: + if aperture.identifier == obj_id: + apertures.append(aperture) + break + else: + missing_ids.append(obj_id) + if len(missing_ids) != 0: + all_objs = ' '.join(['"' + rid + '"' for rid in missing_ids]) + raise ValueError( + 'The following Apertures were not found in the model:\n' + '{}'.format(all_objs) + ) + return apertures
+ +
[docs] def doors_by_identifier(self, identifiers): + """Get a list of Door objects in the model given the Door identifiers.""" + doors, missing_ids = [], [] + model_doors = self.doors + for obj_id in identifiers: + for door in model_doors: + if door.identifier == obj_id: + doors.append(door) + break + else: + missing_ids.append(obj_id) + if len(missing_ids) != 0: + all_objs = ' '.join(['"' + rid + '"' for rid in missing_ids]) + raise ValueError( + 'The following Doors were not found in the model: {}'.format(all_objs) + ) + return doors
+ +
[docs] def shades_by_identifier(self, identifiers): + """Get a list of Shade objects in the model given the Shade identifiers.""" + shades, missing_ids = [], [] + model_shades = self.shades + for obj_id in identifiers: + for face in model_shades: + if face.identifier == obj_id: + shades.append(face) + break + else: + missing_ids.append(obj_id) + if len(missing_ids) != 0: + all_objs = ' '.join(['"' + rid + '"' for rid in missing_ids]) + raise ValueError( + 'The following Shades were not found in the model: {}'.format(all_objs) + ) + return shades
+ +
[docs] def shade_meshes_by_identifier(self, identifiers): + """Get a list of ShadeMesh objects in the model given the ShadeMesh identifiers. + """ + shades, missing_ids = [], [] + model_shades = self._shade_meshes + for obj_id in identifiers: + for sm in model_shades: + if sm.identifier == obj_id: + shades.append(sm) + break + else: + missing_ids.append(obj_id) + if len(missing_ids) != 0: + a_os = ' '.join(['"' + rid + '"' for rid in missing_ids]) + raise ValueError( + 'The following ShadeMeshes were not found in the model: {}'.format(a_os) + ) + return shades
+ +
[docs] def add_prefix(self, prefix): + """Change the identifier of this object and child objects by inserting a prefix. + + This is particularly useful in workflows where you duplicate and edit + a starting object and then want to combine it with the original object + since all objects within a Model must have unique identifiers. + + Args: + prefix: Text that will be inserted at the start of this object's + (and child objects') identifier and display_name. It is recommended + that this prefix be short to avoid maxing out the 100 allowable + characters for honeybee identifiers. + """ + for room in self._rooms: + room.add_prefix(prefix) + for face in self._orphaned_faces: + face.add_prefix(prefix) + for aperture in self._orphaned_apertures: + aperture.add_prefix(prefix) + for door in self._orphaned_doors: + door.add_prefix(prefix) + for shade in self._orphaned_shades: + shade.add_prefix(prefix) + for shade_mesh in self._shade_meshes: + shade_mesh.add_prefix(prefix)
+ +
[docs] def reset_room_ids(self): + """Reset the identifiers of the Model Rooms to be derived from display_names. + + In the event that duplicate Room identifiers are found in the Model, an + integer will be automatically appended to the new Room ID to make it + unique. This is similar to the routines that automatically assign unique + names to OpenStudio SDK objects. + """ + room_dict = {} + for room in self.rooms: + room.identifier = clean_and_number_string( + room.display_name, room_dict, 'Room identifier')
+ +
[docs] def solve_adjacency( + self, merge_coplanar=False, intersect=False, overwrite=False, + air_boundary=False, adiabatic=False, + tolerance=None, angle_tolerance=None): + """Solve adjacency between Rooms of the Model. + + Args: + merge_coplanar: Boolean to note whether coplanar Faces of the Rooms + should be merged before proceeding with the rest of the adjacency + solving. This is particularly helpful when used with the intersect + option since it will ensure the Room geometry is relatively + clean before the intersection and adjacency solving + occurs. (Default: False). + intersect: Boolean to note whether the Faces of the Rooms should be + intersected with one another before the adjacencies are + solved. (Default: False). + overwrite: Boolean to note whether existing Surface boundary + conditions should be overwritten. (Default: False). + air_boundary: Boolean to note whether the wall adjacencies should be + of the air boundary face type. (Default: False). + adiabatic: Boolean to note whether the adjacencies should be + surface or adiabatic. Note that this requires honeybee-energy + to be installed in order to have any meaning. (Default: False). + tolerance: The maximum difference between point values for them to be + considered equivalent. If None, the Model tolerance will be + used. (Default: None). + angle_tolerance: The max angle difference in degrees where Face normals + are no longer considered coplanar. If None, the Model + angle_tolerance will be used. (Default: None). + """ + tol = tolerance if tolerance else self.tolerance + ang_tol = angle_tolerance if angle_tolerance else self.angle_tolerance + + # merge coplanar faces if requested + if merge_coplanar: + for room in self.rooms: + room.merge_coplanar_faces(tol, ang_tol) + + # intersect adjacencies if requested + if intersect: + Room.intersect_adjacency(self.rooms, tol, ang_tol) + + # solve adjacency + if not overwrite: # only assign new adjacencies + adj_info = Room.solve_adjacency(self.rooms, tol) + else: # overwrite existing Surface BC + adj_faces = Room.find_adjacency(self.rooms, tol) + for face_pair in adj_faces: + face_pair[0].set_adjacency(face_pair[1]) + adj_info = {'adjacent_faces': adj_faces} + + # try to assign the air boundary face type + if air_boundary: + for face_pair in adj_info['adjacent_faces']: + if isinstance(face_pair[0].type, Wall): + face_pair[0].type = face_types.air_boundary + face_pair[1].type = face_types.air_boundary + + # try to assign the adiabatic boundary condition + if adiabatic and ad_bc: + for face_pair in adj_info['adjacent_faces']: + face_pair[0].boundary_condition = ad_bc + face_pair[1].boundary_condition = ad_bc
+ +
[docs] def move(self, moving_vec): + """Move this Model along a vector. + + Args: + moving_vec: A ladybug_geometry Vector3D with the direction and distance + to move the Model. + """ + for room in self._rooms: + room.move(moving_vec) + for face in self._orphaned_faces: + face.move(moving_vec) + for aperture in self._orphaned_apertures: + aperture.move(moving_vec) + for door in self._orphaned_doors: + door.move(moving_vec) + for shade in self._orphaned_shades: + shade.move(moving_vec) + for shade_mesh in self._shade_meshes: + shade_mesh.move(moving_vec) + self.properties.move(moving_vec)
+ +
[docs] def rotate(self, axis, angle, origin): + """Rotate this Model by a certain angle around an axis and origin. + + Args: + axis: A ladybug_geometry Vector3D axis representing the axis of rotation. + angle: An angle for rotation in degrees. + origin: A ladybug_geometry Point3D for the origin around which the + object will be rotated. + """ + for room in self._rooms: + room.rotate(axis, angle, origin) + for face in self._orphaned_faces: + face.rotate(axis, angle, origin) + for aperture in self._orphaned_apertures: + aperture.rotate(axis, angle, origin) + for door in self._orphaned_doors: + door.rotate(axis, angle, origin) + for shade in self._orphaned_shades: + shade.rotate(axis, angle, origin) + for shade_mesh in self._shade_meshes: + shade_mesh.rotate(axis, angle, origin) + self.properties.rotate(axis, angle, origin)
+ +
[docs] def rotate_xy(self, angle, origin): + """Rotate this Model counterclockwise in the world XY plane by a certain angle. + + Args: + angle: An angle in degrees. + origin: A ladybug_geometry Point3D for the origin around which the + object will be rotated. + """ + for room in self._rooms: + room.rotate_xy(angle, origin) + for face in self._orphaned_faces: + face.rotate_xy(angle, origin) + for aperture in self._orphaned_apertures: + aperture.rotate_xy(angle, origin) + for door in self._orphaned_doors: + door.rotate_xy(angle, origin) + for shade in self._orphaned_shades: + shade.rotate_xy(angle, origin) + for shade_mesh in self._shade_meshes: + shade_mesh.rotate_xy(angle, origin) + self.properties.rotate_xy(angle, origin)
+ +
[docs] def reflect(self, plane): + """Reflect this Model across a plane with the input normal vector and origin. + + Args: + plane: A ladybug_geometry Plane across which the object will + be reflected. + """ + for room in self._rooms: + room.reflect(plane) + for face in self._orphaned_faces: + face.reflect(plane) + for aperture in self._orphaned_apertures: + aperture.reflect(plane) + for door in self._orphaned_doors: + door.reflect(plane) + for shade in self._orphaned_shades: + shade.reflect(plane) + for shade_mesh in self._shade_meshes: + shade_mesh.reflect(plane) + self.properties.reflect(plane)
+ +
[docs] def scale(self, factor, origin=None): + """Scale this Model by a factor from an origin point. + + Note that using this method does NOT scale the model tolerance and, if + it is desired that this tolerance be scaled with the model geometry, + it must be scaled separately. + + Args: + factor: A number representing how much the object should be scaled. + origin: A ladybug_geometry Point3D representing the origin from which + to scale. If None, it will be scaled from the World origin (0, 0, 0). + """ + for room in self._rooms: + room.scale(factor, origin) + for face in self._orphaned_faces: + face.scale(factor, origin) + for aperture in self._orphaned_apertures: + aperture.scale(factor, origin) + for door in self._orphaned_doors: + door.scale(factor, origin) + for shade in self._orphaned_shades: + shade.scale(factor, origin) + for shade_mesh in self._shade_meshes: + shade_mesh.scale(factor, origin) + self.properties.scale(factor, origin)
+ +
[docs] def generate_exterior_face_grid( + self, dimension, offset=0.1, face_type='Wall', punched_geometry=False): + """Get a gridded Mesh3D offset from the exterior Faces of this Model. + + This will be None if the Model has no exterior Faces. + + Args: + dimension: The dimension of the grid cells as a number. + offset: A number for how far to offset the grid from the base face. + Positive numbers indicate an offset towards the exterior. (Default + is 0.1, which will offset the grid to be 0.1 unit from the faces). + face_type: Text to specify the type of face that will be used to + generate grids. Note that only Faces with Outdoors boundary + conditions will be used, meaning that most Floors will typically + be excluded unless they represent the underside of a cantilever. + Choose from the following. (Default: Wall). + + * Wall + * Roof + * Floor + * All + + punched_geometry: Boolean to note whether the punched_geometry of the faces + should be used (True) with the areas of sub-faces removed from the grid + or the full geometry should be used (False). (Default:False). + """ + # select the correct face type based on the input + face_t = face_type.title() + if face_t == 'Wall': + ft = Wall + elif face_t in ('Roof', 'Roofceiling'): + ft = RoofCeiling + elif face_t == 'All': + ft = (Wall, RoofCeiling, Floor) + elif face_t == 'Floor': + ft = Floor + else: + raise ValueError('Unrecognized face_type "{}".'.format(face_type)) + face_attr = 'punched_geometry' if punched_geometry else 'geometry' + # loop through the faces and generate grids + face_grids = [] + for face in self.faces: + if isinstance(face.type, ft) and \ + isinstance(face.boundary_condition, Outdoors): + try: + f_geo = getattr(face, face_attr) + face_grids.append( + f_geo.mesh_grid(dimension, None, offset, False)) + except AssertionError: # grid tolerance not fine enough + pass + # join the grids together if there are several ones + if len(face_grids) == 1: + return face_grids[0] + elif len(face_grids) > 1: + return Mesh3D.join_meshes(face_grids) + return None
+ +
[docs] def generate_exterior_aperture_grid( + self, dimension, offset=0.1, aperture_type='All'): + """Get a gridded Mesh3D offset from the exterior Apertures of this Model. + + Will be None if the Model has no exterior Apertures. + + Args: + dimension: The dimension of the grid cells as a number. + offset: A number for how far to offset the grid from the base aperture. + Positive numbers indicate an offset towards the exterior while + negative numbers indicate an offset towards the interior, essentially + modeling the value of sun on the building interior. (Default + is 0.1, which will offset the grid to be 0.1 unit from the aperture). + aperture_type: Text to specify the type of Aperture that will be used to + generate grids. Window indicates Apertures in Walls. Choose from + the following. (Default: All). + + * Window + * Skylight + * All + """ + # select the correct face type based on the input + ap_t = aperture_type.title() + if ap_t == 'Window': + ft = Wall + elif ap_t == 'Skylight': + ft = RoofCeiling + elif ap_t == 'All': + ft = (Wall, RoofCeiling, Floor) + else: + raise ValueError('Unrecognized aperture_type "{}".'.format(aperture_type)) + # loop through the faces and generate grids + ap_grids = [] + for face in self.faces: + if isinstance(face.type, ft) and \ + isinstance(face.boundary_condition, Outdoors): + for ap in face.apertures: + try: + ap_grids.append( + ap.geometry.mesh_grid(dimension, None, offset, False)) + except AssertionError: # grid tolerance not fine enough + pass + # join the grids together if there are several ones + if len(ap_grids) == 1: + return ap_grids[0] + elif len(ap_grids) > 1: + return Mesh3D.join_meshes(ap_grids) + return None
+ +
[docs] def simplify_apertures(self, resolve_adjacency=True, tolerance=None): + """Convert all Apertures in this Model to be a simple window ratio. + + This is useful for studies where faster simulation times are desired and + the window ratio is the critical factor driving the results (as opposed + to the detailed geometry of the window). Apertures assigned to concave + Faces will not be simplified given that the Face.apertures_by_ratio method + likely won't improve the cleanliness of the apertures for such cases. + + Args: + resolve_adjacency: Boolean to note whether Room adjacencies should be + re-solved after the Apertures have been simplified. Setting this + to True should ensure that and interior Apertures that are + simplified retain their Surface boundary conditions. If False, + all interior Apertures that have been simplified will have an + Outdoors boundary condition. (Default: True). + tolerance: The maximum difference between point values for them to be + considered equivalent. If None, the Model tolerance will be + used. (Default: None). + """ + tol = tolerance if tolerance else self.tolerance + for room in self._rooms: + room.simplify_apertures(tol) + if resolve_adjacency: + self.solve_adjacency()
+ +
[docs] def rectangularize_apertures( + self, subdivision_distance=None, max_separation=None, merge_all=False, + resolve_adjacency=True, tolerance=None, angle_tolerance=None): + """Convert all Apertures on this Room to be rectangular. + + This is useful when exporting to simulation engines that only accept + rectangular window geometry. This method will always result ing Rooms where + all Apertures are rectangular. However, if the subdivision_distance is not + set, some Apertures may extend past the parent Face or may collide with + one another. + + Args: + subdivision_distance: A number for the resolution at which the + non-rectangular Apertures will be subdivided into smaller + rectangular units. Specifying a number here ensures that the + resulting rectangular Apertures do not extend past the parent + Face or collide with one another. If None, all non-rectangular + Apertures will be rectangularized by taking the bounding rectangle + around the Aperture. (Default: None). + max_separation: A number for the maximum distance between non-rectangular + Apertures at which point the Apertures will be merged into a single + rectangular geometry. This is often helpful when there are several + triangular Apertures that together make a rectangle when they are + merged across their frames. In such cases, this max_separation + should be set to a value that is slightly larger than the window frame. + If None, no merging of Apertures will happen before they are + converted to rectangles. (Default: None). + merge_all: Boolean to note whether all apertures should be merged before + they are rectangularized. If False, only non-rectangular apertures + will be merged before rectangularization. Note that this argument + has no effect when the max_separation is None. (Default: False). + resolve_adjacency: Boolean to note whether Room adjacencies should be + re-solved after the Apertures have been rectangularized. Setting this + to True should ensure that and interior Apertures that are + rectangularized retain their Surface boundary conditions. If False, + all interior Apertures that have been rectangularized will have an + Outdoors boundary condition. (Default: True). + tolerance: The maximum difference between point values for them to be + considered equivalent. If None, the Model tolerance will be + used. (Default: None). + angle_tolerance: The max angle in degrees that the corners of the + rectangle can differ from a right angle before it is not + considered a rectangle. If None, the Model angle_tolerance will be + used. (Default: None). + """ + tol = tolerance if tolerance else self.tolerance + a_tol = angle_tolerance if angle_tolerance else self.angle_tolerance + for room in self._rooms: + room.rectangularize_apertures( + subdivision_distance, max_separation, merge_all, tol, a_tol) + if resolve_adjacency: + self.solve_adjacency()
+ +
[docs] def wall_apertures_by_ratio(self, ratio, tolerance=None): + """Add apertures to all exterior walls given a ratio of aperture to face area. + + Note this method only affects the Models rooms (no orphaned faces) and it + removes any existing apertures and doors on the room's exterior walls. + This method attempts to generate as few apertures as necessary to meet the ratio. + + Args: + ratio: A number between 0 and 1 (but not perfectly equal to 1) + for the desired ratio between aperture area and face area. + tolerance: The maximum difference between point values for them to be + considered a part of a rectangle. This is used in the event that + this face is concave and an attempt to subdivide the face into a + rectangle is made. It does not affect the ability to produce apertures + for convex Faces. If None, the Model tolerance will be + used. (Default: None). + """ + tol = tolerance if tolerance else self.tolerance + for room in self._rooms: + room.wall_apertures_by_ratio(ratio, tol)
+ +
[docs] def skylight_apertures_by_ratio(self, ratio, tolerance=None): + """Add apertures to all exterior roofs given a ratio of aperture to face area. + + Note this method only affects the Models rooms (no orphaned faces) and + removes any existing apertures and overhead doors on the Room's roofs. + This method attempts to generate as few apertures as necessary to meet the ratio. + + Args: + ratio: A number between 0 and 1 (but not perfectly equal to 1) + for the desired ratio between aperture area and face area. + tolerance: The maximum difference between point values for them to be + considered a part of a rectangle. This is used in the event that + this face is concave and an attempt to subdivide the face into a + rectangle is made. It does not affect the ability to produce apertures + for convex Faces. If None, the Model tolerance will be + used. (Default: None). + """ + tol = tolerance if tolerance else self.tolerance + for room in self._rooms: + room.skylight_apertures_by_ratio(ratio, tol)
+ +
[docs] def assign_stories_by_floor_height(self, min_difference=2.0, overwrite=False): + """Assign story properties to the rooms of this Model using their floor heights. + + Stories will be named with a standard convention ('Floor1', 'Floor2', etc.). + + Args: + min_difference: An float value to denote the minimum difference + in floor heights that is considered meaningful. This can be used + to ensure rooms like those representing stair landings are grouped + with floors. Default: 2.0, which means that any difference in + floor heights less than 2.0 will be considered a part of the + same story. This assumption is suitable for models in meters. + overwrite: If True, all story properties of this model's rooms will + be overwritten by this method. If False, this method will only + assign stories to Rooms that do not already have a story identifier + already assigned to them. (Default: False). + + Returns: + A list of the unique story names that were assigned to the input rooms. + """ + if overwrite: + for room in self._rooms: + room.story = None + return Room.stories_by_floor_height(self._rooms, min_difference)
+ +
[docs] def convert_to_units(self, units='Meters'): + """Convert all of the geometry in this model to certain units. + + This involves scaling the geometry, scaling the Model tolerance, and + changing the Model's units property. + + Args: + units: Text for the units to which the Model geometry should be + converted. Default: Meters. Choose from the following: + + * Meters + * Millimeters + * Feet + * Inches + * Centimeters + """ + if self.units != units: + scale_fac1 = conversion_factor_to_meters(self.units) + scale_fac2 = conversion_factor_to_meters(units) + scale_fac = scale_fac1 / scale_fac2 + self.scale(scale_fac) + self.tolerance = self.tolerance * scale_fac + self.units = units
+ +
[docs] def remove_degenerate_geometry(self, tolerance=None): + """Remove any degenerate geometry from the model. + + Degenerate geometry refers to any objects that evaluate to less than 3 vertices + when duplicate and colinear vertices are removed at the tolerance. + + Args: + tolerance: The minimum distance between a vertex and the boundary segments + at which point the vertex is considered distinct. If None, the + Model's tolerance will be used. (Default: None). + """ + tolerance = self.tolerance if tolerance is None else tolerance + adj_dict = {} # dictionary to track adjacent geometries + for room in self.rooms: + try: + r_adj = room.clean_envelope(adj_dict, tolerance=tolerance) + adj_dict.update(r_adj) + except AssertionError as e: # room removed; likely wrong units + error = 'Failed to remove degenerate geometry for Room {}.\n{}'.format( + room.full_id, e) + raise ValueError(error) + self._remove_degenerate_faces(self._orphaned_faces, tolerance) + self._remove_degenerate_faces(self._orphaned_apertures, tolerance) + self._remove_degenerate_faces(self._orphaned_doors, tolerance) + self._remove_degenerate_faces(self._orphaned_shades, tolerance) + for sm in self._shade_meshes: + sm.triangulate_and_remove_degenerate_faces(tolerance)
+ +
[docs] def triangulate_non_planar_quads(self, tolerance=None): + """Triangulate any non-planar orphaned geometry in the model. + + This method will only planarize the orphaned Faces, Apertures, Doors and + Shades that are quadrilaterals, which usually has a minimal impact on results. + It does not impact the Rooms at all. + + Args: + tolerance: The minimum distance from the geometry plane at which the + geometry is not considered planar. If None, the Model's tolerance + will be used. (Default: None). + """ + tolerance = self.tolerance if tolerance is None else tolerance + self._orphaned_apertures = \ + self._triangulate_quad_faces(self._orphaned_apertures, tolerance) + self._orphaned_doors = \ + self._triangulate_quad_faces(self._orphaned_doors, tolerance) + self._orphaned_shades = \ + self._triangulate_quad_faces(self._orphaned_shades, tolerance)
+ +
[docs] def comparison_report(self, other_model, ignore_deleted=False, ignore_added=False): + """Get a dictionary outlining the differences between this model and another. + + The resulting dictionary will only report top-level objects that are different + between this model and the other. If an object has not changed at all, + then it will not show up in the report. + + Changes to geometry are reported separately from changes in metadata + (aka. properties) for each of the top level objects. + + If the Model units or tolerance are different between the two models, + then the units and tolerance of this model will take precedence and + the other_model will be converted to these units and tolerance for + geometry comparison. + + Args: + other_model: A new Model to which this current model will be compared. + ignore_deleted: A boolean to note whether objects that appear in this + current model but not in the other model should be reported. It is + useful to set this to True when the other model represents only a + subset of the current model. (Default: False). + ignore_added: A boolean to note whether objects that appear in the other + model but not in the current model should be reported. (Default: False). + + Returns: + A dictionary of differences between this model and the other model in + the format below. + """ + # make sure the unit systems of the two models align + tol = self.tolerance + if self.units != other_model.units: + other_model = other_model.duplicate() + other_model.convert_to_units(self.units) + # set up lists and dictionaries of objects for comparison + compare_dict = {'type': 'ComparisonReport'} + self_dict = self.top_level_dict + other_dict = other_model.top_level_dict + # loop through the new objects and detect changes between them + changed, added_objs = [], [] + for obj_id, new_obj in other_dict.items(): + try: + exist_obj = self_dict[obj_id] + change_dict = exist_obj._changed_dict(new_obj, tol) + if change_dict is not None: + changed.append(change_dict) + except KeyError: + added_objs.append(new_obj) + compare_dict['changed_objects'] = changed + # include the added objects in the comparison dictionary + if not ignore_added: + added = [] + for new_obj in added_objs: + added.append(new_obj._base_report_dict('AddedObject')) + compare_dict['added_objects'] = added + # include the deleted objects in the comparison dictionary + if not ignore_deleted: + deleted = [] + for obj_id, exist_obj in self_dict.items(): + try: + new_obj = other_dict[obj_id] + except KeyError: + deleted.append(exist_obj._base_report_dict('DeletedObject')) + compare_dict['deleted_objects'] = deleted + return compare_dict
+ +
[docs] def check_all(self, raise_exception=True, detailed=False): + """Check all of the aspects of the Model for possible errors. + + This includes basic properties like adjacency checks and all geometry checks. + Furthermore, all extension attributes will be checked assuming the extension + Model properties have a check_all function. Note that an exception will + always be raised if the model has a tolerance of zero as this means that + no geometry checks can be performed. + + Args: + raise_exception: Boolean to note whether a ValueError should be raised + if any Model errors are found. If False, this method will simply + return a text string with all errors that were found. (Default: True). + detailed: Boolean for whether the returned object is a detailed list of + dicts with error info or a string with a message. (Default: False). + + Returns: + A text string with all errors that were found or a list if detailed is True. + This string (or list) will be empty if no errors were found. + """ + # set up defaults to ensure the method runs correctly + detailed = False if raise_exception else detailed + msgs = [] + # check that a tolerance has been specified in the model + assert self.tolerance != 0, \ + 'Model must have a non-zero tolerance in order to perform geometry checks.' + assert self.angle_tolerance != 0, \ + 'Model must have a non-zero angle_tolerance to perform geometry checks.' + tol = self.tolerance + ang_tol = self.angle_tolerance + + # perform checks for duplicate identifiers, which might mess with other checks + msgs.append(self.check_duplicate_room_identifiers(False, detailed)) + msgs.append(self.check_duplicate_face_identifiers(False, detailed)) + msgs.append(self.check_duplicate_sub_face_identifiers(False, detailed)) + msgs.append(self.check_duplicate_shade_identifiers(False, detailed)) + msgs.append(self.check_duplicate_shade_mesh_identifiers(False, detailed)) + + # perform several checks for the Honeybee schema geometry rules + msgs.append(self.check_planar(tol, False, detailed)) + msgs.append(self.check_self_intersecting(tol, False, detailed)) + # perform checks for degenerate rooms with a test that removes colinear vertices + for room in self.rooms: + try: + new_room = room.duplicate() # duplicate to avoid editing the original + new_room.remove_colinear_vertices_envelope(tol) + except ValueError as e: + deg_msg = str(e) + if detailed: + deg_msg = [{ + 'type': 'ValidationError', + 'code': '000107', + 'error_type': 'Degenerate Room Volume', + 'extension_type': 'Core', + 'element_type': 'Room', + 'element_id': [room.identifier], + 'element_name': [room.display_name], + 'message': deg_msg + }] + msgs.append(deg_msg) + msgs.append(self.check_degenerate_rooms(tol, False, detailed)) + # perform geometry checks related to parent-child relationships + msgs.append(self.check_sub_faces_valid(tol, ang_tol, False, detailed)) + msgs.append(self.check_sub_faces_overlapping(tol, False, detailed)) + msgs.append(self.check_upside_down_faces(ang_tol, False, detailed)) + msgs.append(self.check_rooms_solid(tol, ang_tol, False, detailed)) + + # perform checks related to adjacency relationships + msgs.append(self.check_room_volume_collisions(tol, False, detailed)) + msgs.append(self.check_missing_adjacencies(False, detailed)) + msgs.append(self.check_matching_adjacent_areas(tol, False, detailed)) + msgs.append(self.check_all_air_boundaries_adjacent(False, detailed)) + + # check the extension attributes + ext_msgs = self._properties._check_extension_attr(detailed) + if detailed: + ext_msgs = [m for m in ext_msgs if isinstance(m, list)] + msgs.extend(ext_msgs) + + # output a final report of errors or raise an exception + full_msgs = [msg for msg in msgs if msg] + if detailed: + return [m for msg in full_msgs for m in msg] + full_msg = '\n'.join(full_msgs) + if raise_exception and len(full_msgs) != 0: + raise ValueError(full_msg) + return full_msg
+ +
[docs] def check_duplicate_room_identifiers(self, raise_exception=True, detailed=False): + """Check that there are no duplicate Room identifiers in the model. + + Args: + raise_exception: Boolean to note whether a ValueError should be raised + if duplicate identifiers are found. (Default: True). + detailed: Boolean for whether the returned object is a detailed list of + dicts with error info or a string with a message. (Default: False). + + Returns: + A string with the message or a list with a dictionary if detailed is True. + """ + return check_duplicate_identifiers( + self._rooms, raise_exception, 'Room', detailed, '000004', 'Core', + 'Duplicate Room Identifier')
+ +
[docs] def check_duplicate_face_identifiers(self, raise_exception=True, detailed=False): + """Check that there are no duplicate Face identifiers in the model. + + Args: + raise_exception: Boolean to note whether a ValueError should be raised + if duplicate identifiers are found. (Default: True). + detailed: Boolean for whether the returned object is a detailed list of + dicts with error info or a string with a message. (Default: False). + + Returns: + A string with the message or a list with a dictionary if detailed is True. + """ + return check_duplicate_identifiers_parent( + self.faces, raise_exception, 'Face', detailed, '000003', 'Core', + 'Duplicate Face Identifier')
+ +
[docs] def check_duplicate_sub_face_identifiers(self, raise_exception=True, detailed=False): + """Check that there are no duplicate sub-face identifiers in the model. + + Note that both Apertures and Doors are checked for duplicates since the two + are counted together by EnergyPlus. + + Args: + raise_exception: Boolean to note whether a ValueError should be raised + if duplicate identifiers are found. (Default: True). + detailed: Boolean for whether the returned object is a detailed list of + dicts with error info or a string with a message. (Default: False). + + Returns: + A string with the message or a list with a dictionary if detailed is True. + """ + sub_faces = self.apertures + self.doors + return check_duplicate_identifiers_parent( + sub_faces, raise_exception, 'SubFace', detailed, '000002', 'Core', + 'Duplicate Sub-Face Identifier')
+ +
[docs] def check_duplicate_shade_identifiers(self, raise_exception=True, detailed=False): + """Check that there are no duplicate Shade identifiers in the model. + + Args: + raise_exception: Boolean to note whether a ValueError should be raised + if duplicate identifiers are found. (Default: True). + detailed: Boolean for whether the returned object is a detailed list of + dicts with error info or a string with a message. (Default: False). + + Returns: + A string with the message or a list with a dictionary if detailed is True. + """ + return check_duplicate_identifiers_parent( + self.shades, raise_exception, 'Shade', detailed, '000001', 'Core', + 'Duplicate Shade Identifier')
+ +
[docs] def check_duplicate_shade_mesh_identifiers( + self, raise_exception=True, detailed=False): + """Check that there are no duplicate ShadeMesh identifiers in the model. + + Args: + raise_exception: Boolean to note whether a ValueError should be raised + if duplicate identifiers are found. (Default: True). + detailed: Boolean for whether the returned object is a detailed list of + dicts with error info or a string with a message. (Default: False). + + Returns: + A string with the message or a list with a dictionary if detailed is True. + """ + return check_duplicate_identifiers( + self._shade_meshes, raise_exception, 'ShadeMesh', detailed, '000001', 'Core', + 'Duplicate ShadeMesh Identifier')
+ +
[docs] def check_planar(self, tolerance=None, raise_exception=True, detailed=False): + """Check that all of the Model's geometry components are planar. + + This includes all of the Model's Faces, Apertures, Doors and Shades. + + Args: + tolerance: The minimum distance between a given vertex and a the + object's plane at which the vertex is said to lie in the plane. + If None, the Model tolerance will be used. (Default: None). + raise_exception: Boolean to note whether an ValueError should be + raised if a vertex does not lie within the object's plane. + detailed: Boolean for whether the returned object is a detailed list of + dicts with error info or a string with a message. (Default: False). + + Returns: + A string with the message or a list with a dictionary if detailed is True. + """ + tolerance = self.tolerance if tolerance is None else tolerance + detailed = False if raise_exception else detailed + msgs = [] + for face in self.faces: + msgs.append(face.check_planar(tolerance, False, detailed)) + for shd in self.shades: + msgs.append(shd.check_planar(tolerance, False, detailed)) + for ap in self.apertures: + msgs.append(ap.check_planar(tolerance, False, detailed)) + for dr in self.doors: + msgs.append(dr.check_planar(tolerance, False, detailed)) + full_msgs = [msg for msg in msgs if msg] + if detailed: + return [m for msg in full_msgs for m in msg] + full_msg = '\n'.join(full_msgs) + if raise_exception and len(full_msgs) != 0: + raise ValueError(full_msg) + return full_msg
+ +
[docs] def check_self_intersecting(self, tolerance=None, raise_exception=True, + detailed=False): + """Check that no edges of the Model's geometry components self-intersect. + + This includes all of the Model's Faces, Apertures, Doors and Shades. + + Args: + tolerance: The minimum difference between the coordinate values of two + vertices at which they can be considered equivalent. If None, the + Model tolerance will be used. (Default: None). + raise_exception: If True, a ValueError will be raised if an object + intersects with itself (like a bowtie). (Default: True). + detailed: Boolean for whether the returned object is a detailed list of + dicts with error info or a string with a message. (Default: False). + + Returns: + A string with the message or a list with a dictionary if detailed is True. + """ + tolerance = self.tolerance if tolerance is None else tolerance + detailed = False if raise_exception else detailed + msgs = [] + for room in self.rooms: + msgs.append(room.check_self_intersecting(tolerance, False, detailed)) + for face in self.orphaned_faces: + msgs.append(face.check_self_intersecting(tolerance, False, detailed)) + for shd in self.orphaned_shades: + msgs.append(shd.check_self_intersecting(tolerance, False, detailed)) + for ap in self.orphaned_apertures: + msgs.append(ap.check_self_intersecting(tolerance, False, detailed)) + for dr in self.orphaned_doors: + msgs.append(dr.check_self_intersecting(tolerance, False, detailed)) + full_msgs = [msg for msg in msgs if msg] + if detailed: + return [m for msg in full_msgs for m in msg] + full_msg = '\n'.join(full_msgs) + if raise_exception and len(full_msgs) != 0: + raise ValueError(full_msg) + return full_msg
+ +
[docs] def check_degenerate_rooms( + self, tolerance=None, raise_exception=True, detailed=False): + """Check whether there are degenerate Rooms (with zero volume) within the Model. + + Args: + tolerance: The maximum difference between x, y, and z values + at which face vertices are considered equivalent. If None, the + Model tolerance will be used. (Default: None). + raise_exception: Boolean to note whether a ValueError should be raised + if degenerate Rooms are found. (Default: True). + detailed: Boolean for whether the returned object is a detailed list of + dicts with error info or a string with a message. (Default: False). + + Returns: + A string with the message or a list with a dictionary if detailed is True. + """ + tolerance = self.tolerance if tolerance is None else tolerance + detailed = False if raise_exception else detailed + msgs = [] + for room in self._rooms: + msg = room.check_degenerate(tolerance, False, detailed) + if detailed: + msgs.extend(msg) + elif msg != '': + msgs.append(msg) + if detailed: + return msgs + full_msg = '\n'.join(msgs) + if raise_exception and len(msgs) != 0: + raise ValueError(full_msg) + return full_msg
+ +
[docs] def check_sub_faces_valid(self, tolerance=None, angle_tolerance=None, + raise_exception=True, detailed=False): + """Check that model's sub-faces are co-planar with faces and in their boundary. + + Note this does not check the planarity of the sub-faces themselves, whether + they self-intersect, or whether they have a non-zero area. + + Args: + tolerance: The minimum difference between the coordinate values of two + vertices at which they can be considered equivalent. If None, the + Model tolerance will be used. (Default: None). + angle_tolerance: The max angle in degrees that the plane normals can + differ from one another in order for them to be considered coplanar. + If None, the Model angle_tolerance will be used. (Default: None). + raise_exception: Boolean to note whether a ValueError should be raised + if an sub-face is not valid. (Default: True). + detailed: Boolean for whether the returned object is a detailed list of + dicts with error info or a string with a message. (Default: False). + + Returns: + A string with the message or a list with a dictionary if detailed is True. + """ + tolerance = self.tolerance if tolerance is None else tolerance + angle_tolerance = self.angle_tolerance \ + if angle_tolerance is None else angle_tolerance + detailed = False if raise_exception else detailed + msgs = [] + for rm in self._rooms: + msg = rm.check_sub_faces_valid(tolerance, angle_tolerance, False, detailed) + if detailed: + msgs.extend(msg) + elif msg != '': + msgs.append(msg) + for f in self._orphaned_faces: + msg = f.check_sub_faces_valid(tolerance, angle_tolerance, False, detailed) + if detailed: + msgs.extend(msg) + elif msg != '': + msgs.append(msg) + if detailed: + return msgs + full_msg = '\n'.join(msgs) + if raise_exception and len(msgs) != 0: + raise ValueError(full_msg) + return full_msg
+ +
[docs] def check_sub_faces_overlapping( + self, tolerance=None, raise_exception=True, detailed=False): + """Check that model's sub-faces do not overlap with one another. + + Args: + tolerance: The minimum distance that two sub-faces must overlap in order + for them to be considered overlapping and invalid. If None, the + Model tolerance will be used. (Default: None). + raise_exception: Boolean to note whether a ValueError should be raised + if a sub-faces overlap with one another. + detailed: Boolean for whether the returned object is a detailed list of + dicts with error info or a string with a message. (Default: False). + + Returns: + A string with the message or a list with a dictionary if detailed is True. + """ + tolerance = self.tolerance if tolerance is None else tolerance + detailed = False if raise_exception else detailed + msgs = [] + for rm in self._rooms: + msg = rm.check_sub_faces_overlapping(tolerance, False, detailed) + if detailed: + msgs.extend(msg) + elif msg != '': + msgs.append(msg) + for f in self._orphaned_faces: + msg = f.check_sub_faces_overlapping(tolerance, False, detailed) + if detailed: + msgs.extend(msg) + elif msg != '': + msgs.append(msg) + if detailed: + return msgs + full_msg = '\n'.join(msgs) + if raise_exception and len(msgs) != 0: + raise ValueError(full_msg) + return full_msg
+ +
[docs] def check_upside_down_faces( + self, angle_tolerance=None, raise_exception=True, detailed=False): + """Check that the Model's Faces have the correct direction for the face type. + + This method will only report Floors that are pointing upwards or RoofCeilings + that are pointed downwards. These cases are likely modeling errors and are in + danger of having their vertices flipped by EnergyPlus, causing them to + not see the sun. + + Args: + angle_tolerance: The max angle in degrees that the Face normal can + differ from up or down before it is considered a case of a downward + pointing RoofCeiling or upward pointing Floor. If None, it + will be the model angle tolerance. (Default: None). + raise_exception: Boolean to note whether an ValueError should be + raised if the Face is an an upward pointing Floor or a downward + pointing RoofCeiling. + detailed: Boolean for whether the returned object is a detailed list of + dicts with error info or a string with a message. (Default: False). + + Returns: + A string with the message or a list with a dictionary if detailed is True. + """ + a_tol = self.angle_tolerance if angle_tolerance is None else angle_tolerance + detailed = False if raise_exception else detailed + msgs = [] + for rm in self._rooms: + msg = rm.check_upside_down_faces(a_tol, False, detailed) + if detailed: + msgs.extend(msg) + elif msg != '': + msgs.append(msg) + if detailed: + return msgs + full_msg = '\n'.join(msgs) + if raise_exception and len(msgs) != 0: + raise ValueError(full_msg) + return full_msg
+ +
[docs] def check_rooms_solid(self, tolerance=None, angle_tolerance=None, + raise_exception=True, detailed=False): + """Check whether the Model's rooms are closed solid to within tolerances. + + Args: + tolerance: tolerance: The maximum difference between x, y, and z values + at which face vertices are considered equivalent. If None, the Model + tolerance will be used. (Default: None). + angle_tolerance: The max angle difference in degrees that vertices are + allowed to differ from one another in order to consider them colinear. + Default: 1 degree. If None, the Model angle_tolerance will be + used. (Default: None). + raise_exception: Boolean to note whether a ValueError should be raised + if the room geometry does not form a closed solid. (Default: True). + detailed: Boolean for whether the returned object is a detailed list of + dicts with error info or a string with a message. (Default: False). + + Returns: + A string with the message or a list with a dictionary if detailed is True. + """ + tolerance = self.tolerance if tolerance is None else tolerance + angle_tolerance = self.angle_tolerance \ + if angle_tolerance is None else angle_tolerance + detailed = False if raise_exception else detailed + msgs = [] + for room in self._rooms: + msg = room.check_solid(tolerance, angle_tolerance, False, detailed) + if detailed: + msgs.extend(msg) + elif msg != '': + msgs.append(msg) + if detailed: + return msgs + full_msg = '\n'.join(msgs) + if raise_exception and len(msgs) != 0: + raise ValueError(full_msg) + return full_msg
+ +
[docs] def check_room_volume_collisions( + self, tolerance=None, raise_exception=True, detailed=False): + """Check whether the Model's rooms collide with one another beyond the tolerance. + + Args: + tolerance: tolerance: The maximum difference between x, y, and z values + at which face vertices are considered equivalent. If None, the Model + tolerance will be used. (Default: None). + raise_exception: Boolean to note whether a ValueError should be raised + if the room geometry does not form a closed solid. (Default: True). + detailed: Boolean for whether the returned object is a detailed list of + dicts with error info or a string with a message. (Default: False). + + Returns: + A string with the message or a list with a dictionary if detailed is True. + """ + # set default values + tolerance = self.tolerance if tolerance is None else tolerance + detailed = False if raise_exception else detailed + # group the rooms by their floor heights to enable collision checking + if len(self.rooms) == 0: + return [] if detailed else '' + room_groups, _ = Room.group_by_floor_height(self.rooms, tolerance) + # loop trough the groups and detect collisions + msgs = [] + for rg in room_groups: + msg = Room.check_room_volume_collisions(rg, tolerance, detailed) + if detailed: + msgs.extend(msg) + elif msg != '': + msgs.append(msg) + if detailed: + return msgs + full_msg = '\n'.join(msgs) + if raise_exception and len(msgs) != 0: + raise ValueError(full_msg) + return full_msg
+ +
[docs] def check_missing_adjacencies(self, raise_exception=True, detailed=False): + """Check that all Faces Apertures, and Doors have adjacent objects in the model. + + Args: + raise_exception: Boolean to note whether a ValueError should be raised + if invalid adjacencies are found. (Default: True). + detailed: Boolean for whether the returned object is a detailed list of + dicts with error info or a string with a message. (Default: False). + + Returns: + A string with the message or a list with a dictionary if detailed is True. + """ + detailed = False if raise_exception else detailed + # loop through all objects and get their adjacent object + room_ids = [] + face_bc_ids, face_set = [], set() + ap_bc_ids, ap_set = [], set() + door_bc_ids, dr_set = [], set() + sr = [] + for room in self._rooms: + for face in room._faces: + if isinstance(face.boundary_condition, Surface): + sr.append(self._self_adj_check( + 'Face', face, face_bc_ids, room_ids, face_set, detailed)) + for ap in face.apertures: + assert isinstance(ap.boundary_condition, Surface), \ + 'Aperture "{}" must have Surface boundary condition ' \ + 'if the parent Face has a Surface BC.'.format(ap.full_id) + sr.append(self._self_adj_check( + 'Aperture', ap, ap_bc_ids, room_ids, ap_set, detailed)) + for dr in face.doors: + assert isinstance(dr.boundary_condition, Surface), \ + 'Door "{}" must have Surface boundary condition ' \ + 'if the parent Face has a Surface BC.'.format(dr.full_id) + sr.append(self._self_adj_check( + 'Door', dr, door_bc_ids, room_ids, dr_set, detailed)) + # check to see if the adjacent objects are in the model + mr = self._missing_adj_check(self.rooms_by_identifier, room_ids) + mf = self._missing_adj_check(self.faces_by_identifier, face_bc_ids) + ma = self._missing_adj_check(self.apertures_by_identifier, ap_bc_ids) + md = self._missing_adj_check(self.doors_by_identifier, door_bc_ids) + # if not, go back and find the original object with the missing BC object + msgs = [] + if len(mr) != 0 or len(mf) != 0 or len(ma) != 0 or len(md) != 0: + for room in self._rooms: + for face in room._faces: + if isinstance(face.boundary_condition, Surface): + bc_obj, bc_room = self._adj_objects(face) + if bc_obj in mf: + self._missing_adj_msg( + msgs, face, bc_obj, 'Face', 'Face', detailed) + if bc_room in mr: + self._missing_adj_msg( + msgs, face, bc_room, 'Face', 'Room', detailed) + for ap in face.apertures: + bc_obj, bc_room = self._adj_objects(ap) + if bc_obj in ma: + self._missing_adj_msg( + msgs, ap, bc_obj, 'Aperture', 'Aperture', detailed) + if bc_room in mr: + self._missing_adj_msg( + msgs, ap, bc_room, 'Aperture', 'Room', detailed) + for dr in face.doors: + bc_obj, bc_room = self._adj_objects(dr) + if bc_obj in md: + self._missing_adj_msg( + msgs, dr, bc_obj, 'Door', 'Door', detailed) + if bc_room in mr: + self._missing_adj_msg( + msgs, dr, bc_room, 'Door', 'Room', detailed) + # return the final error messages + all_msgs = [m for m in sr + msgs if m] + if detailed: + return [m for msg in all_msgs for m in msg] + msg = '\n'.join(all_msgs) + if msg != '' and raise_exception: + raise ValueError(msg) + return msg
+ +
[docs] def check_matching_adjacent_areas(self, tolerance=None, raise_exception=True, + detailed=False): + """Check that all adjacent Faces have areas that match within the tolerance. + + This is required for energy simulation in order to get matching heat flow + across adjacent Faces. Otherwise, conservation of energy is violated. + Note that, if there are missing adjacencies in the model, the message from + this method will simply note this fact without reporting on mis-matched areas. + + Args: + tolerance: tolerance: The maximum difference between x, y, and z values + at which face vertices are considered equivalent. If None, the Model + tolerance will be used. (Default: None). + raise_exception: Boolean to note whether a ValueError should be raised + if invalid adjacencies are found. (Default: True). + detailed: Boolean for whether the returned object is a detailed list of + dicts with error info or a string with a message. (Default: False). + + Returns: + A string with the message or a list with a dictionary if detailed is True. + """ + tolerance = self.tolerance if tolerance is None else tolerance + detailed = False if raise_exception else detailed + + # first gather all interior faces in the model and their adjacent object + base_faces, adj_ids = [], [] + for room in self._rooms: + for face in room._faces: + if isinstance(face.boundary_condition, Surface): + base_faces.append(face) + adj_ids.append(face.boundary_condition.boundary_condition_object) + + # get the adjacent faces + try: + adj_faces = self.faces_by_identifier(adj_ids) + except ValueError as e: # the model has missing adjacencies + if detailed: # the user will get a more detailed error in honeybee-core + return [] + else: + msg = 'Matching adjacent areas could not be verified because ' \ + 'of missing adjacencies in the model. \n{}'.format(e) + if raise_exception: + raise ValueError(msg) + return msg + + # loop through the adjacent face pairs and report if areas are not matched + full_msgs, reported_items = [], set() + for base_f, adj_f in zip(base_faces, adj_faces): + if (base_f.identifier, adj_f.identifier) in reported_items: + continue + tol_area = math.sqrt(base_f.area) * tolerance + if abs(base_f.area - adj_f.area) > tol_area: + f_msg = 'Face "{}" with area {} is adjacent to Face "{}" with area {}.' \ + ' This difference is greater than the tolerance of {}.'.format( + base_f.full_id, base_f.area, adj_f.full_id, adj_f.area, tolerance + ) + f_msg = self._validation_message_child( + f_msg, base_f, detailed, '000205', + error_type='Mismatched Area Adjacency') + if detailed: + f_msg['element_id'].append(adj_f.identifier) + f_msg['element_name'].append(adj_f.display_name) + parents = [] + rel_obj = adj_f + while getattr(rel_obj, '_parent', None) is not None: + rel_obj = getattr(rel_obj, '_parent') + par_dict = { + 'parent_type': rel_obj.__class__.__name__, + 'id': rel_obj.identifier, + 'name': rel_obj.display_name + } + parents.append(par_dict) + f_msg['parents'].append(parents) + full_msgs.append(f_msg) + reported_items.add((adj_f.identifier, base_f.identifier)) + else: # check to ensure the shapes are the same when vertices are removed + base_f_geo = base_f.geometry.remove_colinear_vertices(tolerance) + adj_f_geo = adj_f.geometry.remove_colinear_vertices(tolerance) + if len(base_f_geo) != len(adj_f_geo): + f_msg = 'Face "{}" is a shape with {} distinct vertices and is ' \ + 'adjacent to Face "{}", which has {} distinct vertices' \ + ' within the model tolerance of {}.'.format( + base_f.full_id, len(base_f_geo), + adj_f.full_id, len(adj_f_geo), tolerance + ) + f_msg = self._validation_message_child( + f_msg, base_f, detailed, '000205', + error_type='Mismatched Area Adjacency') + if detailed: + f_msg['element_id'].append(adj_f.identifier) + f_msg['element_name'].append(adj_f.display_name) + parents = [] + rel_obj = adj_f + while getattr(rel_obj, '_parent', None) is not None: + rel_obj = getattr(rel_obj, '_parent') + par_dict = { + 'parent_type': rel_obj.__class__.__name__, + 'id': rel_obj.identifier, + 'name': rel_obj.display_name + } + parents.append(par_dict) + f_msg['parents'].append(parents) + full_msgs.append(f_msg) + reported_items.add((adj_f.identifier, base_f.identifier)) + + # ensure that adjacent sub-faces have matching areas + if base_f.has_sub_faces: + base_subs, adj_subs, sub_ids = [], [], [] + for sf in base_f.sub_faces: + if isinstance(sf.boundary_condition, Surface): + base_subs.append(sf) + sub_ids.append(sf.boundary_condition.boundary_condition_object) + missing_sfs = False + for obj_id in sub_ids: + for adj_sf in adj_f.sub_faces: + if adj_sf.identifier == obj_id: + adj_subs.append(adj_sf) + break + else: # missing sub-face adjacencies will get reported elsewhere + missing_sfs = True + if not missing_sfs: + for base_sf, adj_sf in zip(base_subs, adj_subs): + tol_area = math.sqrt(base_sf.area) * tolerance + if abs(base_sf.area - adj_sf.area) > tol_area: + f_msg = 'SubFace "{}" with area {} is adjacent to ' \ + 'SubFace "{}" with area {}. This difference is greater ' \ + 'than the tolerance of {}.'.format( + base_sf.full_id, base_sf.area, + adj_sf.full_id, adj_sf.area, tolerance + ) + f_msg = self._validation_message_child( + f_msg, base_sf, detailed, '000205', + error_type='Mismatched Area Adjacency') + if detailed: + f_msg['element_id'].append(adj_sf.identifier) + f_msg['element_name'].append(adj_sf.display_name) + parents = [] + rel_obj = adj_sf + while getattr(rel_obj, '_parent', None) is not None: + rel_obj = getattr(rel_obj, '_parent') + par_dict = { + 'parent_type': rel_obj.__class__.__name__, + 'id': rel_obj.identifier, + 'name': rel_obj.display_name + } + parents.append(par_dict) + f_msg['parents'].append(parents) + full_msgs.append(f_msg) + reported_items.add((adj_f.identifier, base_f.identifier)) + + # return all of the validation error messages that were gathered + full_msg = full_msgs if detailed else '\n'.join(full_msgs) + if raise_exception and len(full_msgs) != 0: + raise ValueError(full_msg) + return full_msg
+ +
[docs] def check_all_air_boundaries_adjacent(self, raise_exception=True, detailed=False): + """Check that all Faces with the AirBoundary type are adjacent to other Faces. + + This is a requirement for energy simulation. + + Args: + raise_exception: Boolean to note whether a ValueError should be raised + if an AirBoundary without an adjacency is found. (Default: True). + detailed: Boolean for whether the returned object is a detailed list of + dicts with error info or a string with a message. (Default: False). + + Returns: + A string with the message or a list with a dictionary if detailed is True. + """ + detailed = False if raise_exception else detailed + msgs = [] + for face in self.faces: + if isinstance(face.type, AirBoundary) and not \ + isinstance(face.boundary_condition, Surface): + msg = 'Face "{}" is an AirBoundary but is not adjacent ' \ + 'to another Face.'.format(face.full_id) + msg = self._validation_message_child( + msg, face, detailed, '000206', error_type='Non-Adjacent AirBoundary') + msgs.append(msg) + if detailed: + return msgs + full_msg = '\n'.join(msgs) + if raise_exception and len(msgs) != 0: + raise ValueError(full_msg) + return full_msg
+ +
[docs] def triangulated_apertures(self): + """Get triangulated versions of the model Apertures that have more than 4 sides. + + This is necessary for energy simulation since EnergyPlus cannot accept + sub-faces with more than 4 sides. Note that this method does not alter the + Apertures within the Model object but just returns a list of modified + Apertures that all have 3 or 4 sides. + + Returns: + A tuple with two elements + + - triangulated_apertures: A list of lists where each list is a set of + triangle Apertures meant to replace an Aperture with more than + 4 sides in the model. + + - parents_to_edit: An list of lists that parallels the triangulated + apertures in that each item represents an Aperture that has been + triangulated in the model. However, each of these lists holds between + 1 and 3 values for the identifiers of the original aperture and parents + of the aperture. This information is intended to help edit parent + faces that have had their child faces triangulated. The 3 values + are as follows: + + * 0 = The identifier of the original Aperture that was triangulated. + * 1 = The identifier of the parent Face of the original Aperture + (if it exists). + * 2 = The identifier of the parent Room of the parent Face of the + original Aperture (if it exists). + """ + triangulated_apertures = [] + parents_to_edit = [] + all_apertures = self.apertures + adj_check = [] # confirms when interior apertures are triangulated by adjacency + for ap in all_apertures: + if len(ap.geometry) <= 4: + pass + elif ap.identifier not in adj_check: + # generate the new triangulated apertures + ap_mesh3d = ap.triangulated_mesh3d + new_verts = [[ap_mesh3d[v] for v in face] for face in ap_mesh3d.faces] + new_ap_geo = [Face3D(verts, ap.geometry.plane) for verts in new_verts] + new_ap_geo = self._remove_sliver_geometries(new_ap_geo) + new_aps, parent_edit_info = self._replace_aperture(ap, new_ap_geo) + triangulated_apertures.append(new_aps) + if parent_edit_info is not None: + parents_to_edit.append(parent_edit_info) + # coordinate new apertures with any adjacent apertures + if isinstance(ap.boundary_condition, Surface): + bc_obj_identifier = ap.boundary_condition.boundary_condition_object + for other_ap in all_apertures: + if other_ap.identifier == bc_obj_identifier: + adj_ap = other_ap + break + new_adj_ap_geo = [face.flip() for face in new_ap_geo] + new_adj_aps, edit_in = self._replace_aperture(adj_ap, new_adj_ap_geo) + for new_ap, new_adj_ap in zip(new_aps, new_adj_aps): + new_ap.set_adjacency(new_adj_ap) + triangulated_apertures.append(new_adj_aps) + if edit_in is not None: + parents_to_edit.append(edit_in) + adj_check.append(adj_ap.identifier) + return triangulated_apertures, parents_to_edit
+ +
[docs] def triangulated_doors(self): + """Get triangulated versions of the model Doors that have more than 4 sides. + + This is necessary for energy simulation since EnergyPlus cannot accept + sub-faces with more than 4 sides. Note that this method does not alter the + Doors within the Model object but just returns a list of Doors that + all have 3 or 4 sides. + + Returns: + A tuple with two elements + + - triangulated_doors: A list of lists where each list is a set of triangle + Doors meant to replace a Door with more than 4 sides in the model. + + - parents_to_edit: An list of lists that parallels the triangulated_doors + in that each item represents a Door that has been triangulated + in the model. However, each of these lists holds between 1 and 3 values + for the identifiers of the original door and parents of the door. + This information is intended to help edit parent faces that have had + their child faces triangulated. The 3 values are as follows: + + * 0 = The identifier of the original Door that was triangulated. + * 1 = The identifier of the parent Face of the original Door + (if it exists). + * 2 = The identifier of the parent Room of the parent Face of the + original Door (if it exists). + """ + triangulated_doors = [] + parents_to_edit = [] + all_doors = self.doors + adj_check = [] # confirms when interior doors are triangulated by adjacency + for dr in all_doors: + if len(dr.geometry) <= 4: + pass + elif dr.identifier not in adj_check: + # generate the new triangulated doors + dr_mesh3d = dr.triangulated_mesh3d + new_verts = [[dr_mesh3d[v] for v in face] for face in dr_mesh3d.faces] + new_dr_geo = [Face3D(verts, dr.geometry.plane) for verts in new_verts] + new_dr_geo = self._remove_sliver_geometries(new_dr_geo) + new_drs, parent_edit_info = self._replace_door(dr, new_dr_geo) + triangulated_doors.append(new_drs) + if parent_edit_info is not None: + parents_to_edit.append(parent_edit_info) + # coordinate new doors with any adjacent doors + if isinstance(dr.boundary_condition, Surface): + bc_obj_identifier = dr.boundary_condition.boundary_condition_object + for other_dr in all_doors: + if other_dr.identifier == bc_obj_identifier: + adj_dr = other_dr + break + new_adj_dr_geo = [face.flip() for face in new_dr_geo] + new_adj_drs, edit_in = self._replace_door(adj_dr, new_adj_dr_geo) + for new_dr, new_adj_dr in zip(new_drs, new_adj_drs): + new_dr.set_adjacency(new_adj_dr) + triangulated_doors.append(new_adj_drs) + if edit_in is not None: + parents_to_edit.append(edit_in) + adj_check.append(adj_dr.identifier) + return triangulated_doors, parents_to_edit
+ + def _remove_sliver_geometries(self, face3ds): + """Remove sliver geometries from a list of Face3Ds.""" + clean_face3ds = [] + for face in face3ds: + try: + if face.area >= self.tolerance: + clean_face3ds.append(face.remove_colinear_vertices(self.tolerance)) + except ValueError: + pass # degenerate triangle; remove it + return clean_face3ds + + def _remove_degenerate_faces(self, hb_objs, tolerance): + """Remove degenerate Faces, Apertures, Doors, or Shades from a list.""" + i_to_remove = [] + for i, face in enumerate(hb_objs): + try: + face.remove_colinear_vertices(tolerance) + except ValueError: # degenerate face found! + i_to_remove.append(i) + for i in reversed(i_to_remove): + hb_objs.pop(i) + + def _triangulate_quad_faces(self, hb_objs, tolerance): + """Triangulate quad geometries.""" + clean_objects = [] + for i, geo_obj in enumerate(hb_objs): + geo = geo_obj.geometry + if len(geo.vertices) == 4 and not geo.check_planar(tolerance, False): + verts = geo.vertices + obj_1 = geo_obj.duplicate() + obj_1.identifier = '{}..0'.format(geo_obj.identifier) + obj_1._geometry = Face3D((verts[0], verts[1], verts[2])) + clean_objects.append(obj_1) + obj_2 = geo_obj.duplicate() + obj_2.identifier = '{}..1'.format(geo_obj.identifier) + obj_2._geometry = Face3D((verts[2], verts[3], verts[0])) + clean_objects.append(obj_2) + else: + clean_objects.append(geo_obj) + return clean_objects + + def _replace_aperture(self, original_ap, new_ap_geo): + """Get new Apertures generated from new_ap_geo and the properties of original_ap. + + Note that this method does not re-link the new apertures to new adjacent + apertures in the model. This must be done with the returned apertures. + + Args: + original_ap: The original Aperture object from which properties + are borrowed. + new_ap_geo: A list of ladybug_geometry Face3D objects that will be used + to generate the new Aperture objects. + + Returns: + A tuple with two elements + + - new_aps: A list of the new Aperture objects. + + - parent_edit_info: An array of up to 3 values meant to help edit + parents that have had their child faces triangulated. The 3 values + are as follows: + + * 0 = The identifier of the original Aperture that was triangulated. + * 1 = The identifier of the parent Face of the original Aperture + (if it exists). + * 2 = The identifier of the parent Room of the parent Face of the + original Aperture (if it exists). + """ + # make the new Apertures and add them to the model + new_aps = [] + for i, ap_face in enumerate(new_ap_geo): + new_ap = Aperture('{}..{}'.format(original_ap.identifier, i), + ap_face, None, original_ap.is_operable) + new_ap._properties = original_ap._properties # transfer extension properties + if original_ap.has_parent: + new_ap._parent = original_ap.parent + new_aps.append(new_ap) + + # transfer over any child shades to the first triangulated object + if len(original_ap._indoor_shades) != 0: + new_shds = [shd.duplicate() for shd in original_ap._indoor_shades] + new_aps[0].add_indoor_shades(new_shds) + if len(original_ap._outdoor_shades) != 0: + new_shds = [shd.duplicate() for shd in original_ap._outdoor_shades] + new_aps[0].add_outdoor_shades(new_shds) + + # create the parent edit info + parent_edit_info = [original_ap.identifier] + if original_ap.has_parent: + parent_edit_info.append(original_ap.parent.identifier) + if original_ap.parent.has_parent: + parent_edit_info.append(original_ap.parent.parent.identifier) + return new_aps, parent_edit_info + + def _replace_door(self, original_dr, new_dr_geo): + """Get new Doors generated from new_dr_geo and the properties of original_dr. + + Note that this method does not re-link the new doors to new adjacent + doors in the model. This must be done with the returned doors. + + Args: + original_dr: The original Door object from which properties + are borrowed. + new_dr_geo: A list of ladybug_geometry Face3D objects that will be used + to generate the new Door objects. + + Returns: + A tuple with four elements + + - new_drs: A list of the new Door objects. + + - parent_edit_info: An array of up to 3 values meant to help edit + parents that have had their child faces triangulated. The 3 values + are as follows: + + * 0 = The identifier of the original Door that was triangulated. + * 1 = The identifier of the parent Face of the original Door + (if it exists). + * 2 = The identifier of the parent Room of the parent Face of the + original Door (if it exists). + """ + # make the new doors and add them to the model + new_drs = [] + for i, dr_face in enumerate(new_dr_geo): + new_dr = Door('{}..{}'.format(original_dr.identifier, i), dr_face) + new_dr._properties = original_dr._properties # transfer extension properties + if original_dr.has_parent: + new_dr._parent = original_dr.parent + new_drs.append(new_dr) + + # transfer over any child shades to the first triangulated object + if len(original_dr._indoor_shades) != 0: + new_shds = [shd.duplicate() for shd in original_dr._indoor_shades] + new_drs[0].add_indoor_shades(new_shds) + if len(original_dr._outdoor_shades) != 0: + new_shds = [shd.duplicate() for shd in original_dr._outdoor_shades] + new_drs[0].add_outdoor_shades(new_shds) + + # create the parent edit info + parent_edit_info = [original_dr.identifier] + if original_dr.has_parent: + parent_edit_info.append(original_dr.parent.identifier) + if original_dr.parent.has_parent: + parent_edit_info.append(original_dr.parent.parent.identifier) + return new_drs, parent_edit_info + + @property + def to(self): + """Model writer object. + + Use this method to access Writer class to write the model in other formats. + + Usage: + + .. code-block:: python + + model.to.idf(model) -> idf string. + model.to.radiance(model) -> Radiance string. + """ + return writer + +
[docs] def to_dict(self, included_prop=None, triangulate_sub_faces=False, + include_plane=True): + """Return Model as a dictionary. + + Args: + included_prop: List of properties to filter keys that must be included in + output dictionary. For example ['energy'] will include 'energy' key if + available in properties to_dict. By default all the keys will be + included. To exclude all the keys from extensions use an empty list. + triangulate_sub_faces: Boolean to note whether sub-faces (including + Apertures and Doors) should be triangulated if they have more than + 4 sides (True) or whether they should be left as they are (False). + This triangulation is necessary when exporting directly to EnergyPlus + since it cannot accept sub-faces with more than 4 vertices. Note that + setting this to True will only triangulate sub-faces with parent Faces + that also have parent Rooms since orphaned Apertures and Faces are + not relevant for energy simulation. (Default: False). + include_plane: Boolean to note wether the planes of the Face3Ds should be + included in the output. This can preserve the orientation of the + X/Y axes of the planes but is not required and can be removed to + keep the dictionary smaller. (Default: True). + """ + # write all of the geometry objects and their properties + base = {'type': 'Model'} + base['identifier'] = self.identifier + base['display_name'] = self.display_name + base['units'] = self.units + base['properties'] = self.properties.to_dict(included_prop) + if self._rooms != []: + base['rooms'] = [r.to_dict(True, included_prop, include_plane) + for r in self._rooms] + if self._orphaned_faces != []: + base['orphaned_faces'] = [f.to_dict(True, included_prop, include_plane) + for f in self._orphaned_faces] + if self._orphaned_apertures != []: + base['orphaned_apertures'] = [ap.to_dict(True, included_prop, include_plane) + for ap in self._orphaned_apertures] + if self._orphaned_doors != []: + base['orphaned_doors'] = [dr.to_dict(True, included_prop, include_plane) + for dr in self._orphaned_doors] + if self._orphaned_shades != []: + base['orphaned_shades'] = [shd.to_dict(True, included_prop, include_plane) + for shd in self._orphaned_shades] + if self._shade_meshes != []: + base['shade_meshes'] = [sm.to_dict(True, included_prop) + for sm in self._shade_meshes] + if self.tolerance != 0: + base['tolerance'] = self.tolerance + if self.angle_tolerance != 0: + base['angle_tolerance'] = self.angle_tolerance + + # triangulate sub-faces if this was requested + if triangulate_sub_faces: + apertures, parents_to_edit = self.triangulated_apertures() + for tri_aps, edit_infos in zip(apertures, parents_to_edit): + if len(edit_infos) == 3: + for room in base['rooms']: + if room['identifier'] == edit_infos[2]: + break + for face in room['faces']: + if face['identifier'] == edit_infos[1]: + break + for i, ap in enumerate(face['apertures']): + if ap['identifier'] == edit_infos[0]: + break + del face['apertures'][i] + face['apertures'].extend( + [a.to_dict(True, included_prop) for a in tri_aps]) + doors, parents_to_edit = self.triangulated_doors() + for tri_drs, edit_infos in zip(doors, parents_to_edit): + if len(edit_infos) == 3: + for room in base['rooms']: + if room['identifier'] == edit_infos[2]: + break + for face in room['faces']: + if face['identifier'] == edit_infos[1]: + break + for i, ap in enumerate(face['doors']): + if ap['identifier'] == edit_infos[0]: + break + del face['doors'][i] + face['doors'].extend( + [dr.to_dict(True, included_prop) for dr in tri_drs]) + + # write in the optional keys if they are not None + if self.user_data is not None: + base['user_data'] = self.user_data + if folders.honeybee_schema_version is not None: + base['version'] = folders.honeybee_schema_version_str + + return base
+ +
[docs] def to_hbjson(self, name=None, folder=None, indent=None, + included_prop=None, triangulate_sub_faces=False): + """Write Honeybee model to HBJSON. + + Args: + name: A text string for the name of the HBJSON file. If None, the model + identifier wil be used. (Default: None). + folder: A text string for the directory where the HBJSON will be written. + If unspecified, the default simulation folder will be used. This + is usually at "C:\\Users\\USERNAME\\simulation." + indent: A positive integer to set the indentation used in the resulting + HBJSON file. (Default: None). + included_prop: List of properties to filter keys that must be included in + output dictionary. For example ['energy'] will include 'energy' key if + available in properties to_dict. By default all the keys will be + included. To exclude all the keys from extensions use an empty list. + triangulate_sub_faces: Boolean to note whether sub-faces (including + Apertures and Doors) should be triangulated if they have more than + 4 sides (True) or whether they should be left as they are (False). + This triangulation is necessary when exporting directly to EnergyPlus + since it cannot accept sub-faces with more than 4 vertices. Note that + setting this to True will only triangulate sub-faces with parent Faces + that also have parent Rooms since orphaned Apertures and Faces are + not relevant for energy simulation. (Default: False). + """ + # create dictionary from the Honeybee Model + hb_dict = self.to_dict(included_prop=included_prop, + triangulate_sub_faces=triangulate_sub_faces) + + # set up a name and folder for the HBJSON + if name is None: + name = self.identifier + file_name = name if name.lower().endswith('.hbjson') or \ + name.lower().endswith('.json') else '{}.hbjson'.format(name) + folder = folder if folder is not None else folders.default_simulation_folder + hb_file = os.path.join(folder, file_name) + # write HBJSON + with open(hb_file, 'w') as fp: + json.dump(hb_dict, fp, indent=indent) + return hb_file
+ +
[docs] def to_hbpkl(self, name=None, folder=None, included_prop=None, + triangulate_sub_faces=False): + """Write Honeybee model to compressed pickle file (HBpkl). + + Args: + name: A text string for the name of the pickle file. If None, the model + identifier wil be used. (Default: None). + folder: A text string for the directory where the pickle file will be + written. If unspecified, the default simulation folder will be used. + This is usually at "C:\\Users\\USERNAME\\simulation." + included_prop: List of properties to filter keys that must be included in + output dictionary. For example ['energy'] will include 'energy' key if + available in properties to_dict. By default all the keys will be + included. To exclude all the keys from extensions use an empty list. + triangulate_sub_faces: Boolean to note whether sub-faces (including + Apertures and Doors) should be triangulated if they have more than + 4 sides (True) or whether they should be left as they are (False). + This triangulation is necessary when exporting directly to EnergyPlus + since it cannot accept sub-faces with more than 4 vertices. Note that + setting this to True will only triangulate sub-faces with parent Faces + that also have parent Rooms since orphaned Apertures and Faces are + not relevant for energy simulation. (Default: False). + """ + # create dictionary from the Honeybee Model + hb_dict = self.to_dict(included_prop=included_prop, + triangulate_sub_faces=triangulate_sub_faces) + + # set up a name and folder for the HBpkl + if name is None: + name = self.identifier + file_name = name if name.lower().endswith('.hbpkl') or \ + name.lower().endswith('.pkl') else '{}.hbpkl'.format(name) + folder = folder if folder is not None else folders.default_simulation_folder + hb_file = os.path.join(folder, file_name) + # write the Model dictionary into a file + with open(hb_file, 'wb') as fp: + pickle.dump(hb_dict, fp) + return hb_file
+ +
[docs] def to_stl(self, name=None, folder=None): + """Write Honeybee model to an ASCII STL file. + + Note that all geometry is triangulated when it is converted to STL. + + Args: + name: A text string for the name of the STL file. If None, the model + identifier wil be used. (Default: None). + folder: A text string for the directory where the STL will be written. + If unspecified, the default simulation folder will be used. This + is usually at "C:\\Users\\USERNAME\\simulation." + """ + # set up a name and folder for the STL + if name is None: + name = self.identifier + file_name = name if name.lower().endswith('.stl') else '{}.stl'.format(name) + folder = folder if folder is not None else folders.default_simulation_folder + + # collect all of the Face3Ds across the model as triangles and normals + all_geo = [] + for face in self.faces: + all_geo.append(face.punched_geometry) + for ap in self.apertures: + all_geo.append(ap.geometry) + for dr in self.doors: + all_geo.append(dr.geometry) + for shd in self.doors: + all_geo.append(shd.geometry) + + # convert the Face3Ds into a format for export to STL + _face_vertices, _face_normals = [], [] + for face_3d in all_geo: + # add the geometry of a Face3D to the lists for STL export + if len(face_3d) == 3: + _face_vertices.append(face_3d.vertices) + _face_normals.append(face_3d.normal) + else: + tri_mesh = face_3d.triangulated_mesh3d + for m_fac in tri_mesh.face_vertices: + _face_vertices.append(m_fac) + _face_normals.append(face_3d.normal) + + # convert any shade meshes into STL vertices + for sm in self._shade_meshes: + for fvs, fns in zip(sm.geometry.face_vertices, sm.geometry.face_normals): + _face_vertices.append(fvs) + _face_normals.append(fns) + + # write the geometry into an STL file + stl_obj = STL(_face_vertices, _face_normals, self.identifier) + return stl_obj.to_file(folder, file_name)
+ + def _all_objects(self): + """Get a single list of all the Honeybee objects in a Model.""" + return self._rooms + self._orphaned_faces + self._orphaned_shades + \ + self._orphaned_apertures + self._orphaned_doors + self._shade_meshes + +
[docs] @staticmethod + def conversion_factor_to_meters(units): + """Get the conversion factor to meters based on input units. + + Args: + units: Text for the units. Choose from the following: + + * Meters + * Millimeters + * Feet + * Inches + * Centimeters + + Returns: + A number for the conversion factor, which should be multiplied by + all distance units taken from Rhino geometry in order to convert + them to meters. + """ + return conversion_factor_to_meters(units)
+ + def _self_adj_check(self, obj_type, hb_obj, bc_ids, room_ids, bc_set, detailed): + """Check that an adjacent object is referencing itself or its own room. + + A check will also be performed to ensure the adjacent object doesn't already + have an adjacent pair in the model. + """ + bc_objs = hb_obj.boundary_condition.boundary_condition_objects + bc_obj, bc_room = bc_objs[0], bc_objs[-1] + bc_ids.append(bc_obj) + room_ids.append(bc_room) + msgs = [] + # first ensure that the object is not referencing itself + if hb_obj.identifier == bc_obj: + msg = '{} "{}" cannot reference itself in its Surface boundary ' \ + 'condition.'.format(obj_type, hb_obj.full_id) + msg = self._validation_message_child( + msg, hb_obj, detailed, '000201', + error_type='Self-Referential Adjacency') + msgs.append(msg) + # then ensure that the object is not referencing its own room + if hb_obj.has_parent and hb_obj.parent.has_parent: + if hb_obj.parent.parent.identifier == bc_room: + msg = '{} "{}" and its adjacent object "{}" cannot be a part of the ' \ + 'same Room "{}".'.format(obj_type, hb_obj.full_id, bc_obj, bc_room) + msg = self._validation_message_child( + msg, hb_obj, detailed, '000202', + error_type='Intra-Room Adjacency') + msgs.append(msg) + # lastly make sure the adjacent object doesn't already have an adjacency + if bc_obj in bc_set: + msg = '{} "{}" is adjacent to object "{}", which has another adjacent ' \ + 'object in the Model.'.format(obj_type, hb_obj.full_id, bc_obj) + msg = self._validation_message_child( + msg, hb_obj, detailed, '000203', + error_type='Object with Multiple Adjacencies') + msgs.append(msg) + else: + bc_set.add(bc_obj) + return msgs if detailed else ''.join(msgs) + + def _missing_adj_msg(self, messages, hb_obj, bc_obj, + obj_type='Face', bc_obj_type='Face', detailed=False): + msg = '{} "{}" has an adjacent {} that is missing from the model: ' \ + '{}'.format(obj_type, hb_obj.full_id, bc_obj_type, bc_obj) + msg = self._validation_message_child( + msg, hb_obj, detailed, '000204', error_type='Missing Adjacency') + if detailed: + messages.append([msg]) + else: + messages.append(msg) + + @staticmethod + def _missing_adj_check(id_checking_function, bc_ids): + """Check whether adjacencies are missing from a model.""" + try: + id_checking_function(bc_ids) + return [] + except ValueError as e: + id_pattern = re.compile('\"([^"]*)\"') + return [obj_id for obj_id in id_pattern.findall(str(e))] + + @staticmethod + def _adj_objects(hb_obj): + """Check that an adjacent object is referencing itself.""" + bc_objs = hb_obj.boundary_condition.boundary_condition_objects + return bc_objs[0], bc_objs[-1] + + @staticmethod + def _remove_by_ids(objs, obj_ids): + """Remove items from a list using a list of object IDs.""" + if obj_ids == []: + return objs + new_objs = [] + if obj_ids is not None: + obj_id_set = set(obj_ids) + for obj in objs: + if obj.identifier not in obj_id_set: + new_objs.append(obj) + return new_objs + + def __add__(self, other): + new_model = self.duplicate() + new_model.add_model(other) + return new_model + + def __iadd__(self, other): + self.add_model(other) + return self + + def __copy__(self): + new_model = Model( + self.identifier, + [room.duplicate() for room in self._rooms], + [face.duplicate() for face in self._orphaned_faces], + [shade.duplicate() for shade in self._orphaned_shades], + [aperture.duplicate() for aperture in self._orphaned_apertures], + [door.duplicate() for door in self._orphaned_doors], + [shade_mesh.duplicate() for shade_mesh in self._shade_meshes], + self.units, self.tolerance, self.angle_tolerance) + new_model._display_name = self._display_name + new_model._user_data = None if self.user_data is None else self.user_data.copy() + new_model._properties._duplicate_extension_attr(self._properties) + return new_model + + def __repr__(self): + return 'Model: %s' % self.display_name
+
+ +
+ +
+
+
+
+

+ Back to top + +

+

+ © Copyright 2023, Ladybug Tools.
+ Created using Sphinx 5.3.0.
+

+
+
+ + \ No newline at end of file diff --git a/docs/_modules/honeybee/orientation.html b/docs/_modules/honeybee/orientation.html new file mode 100644 index 00000000..0dd92b32 --- /dev/null +++ b/docs/_modules/honeybee/orientation.html @@ -0,0 +1,1242 @@ + + + + + + + honeybee.orientation — honeybee documentation + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+ +

Source code for honeybee.orientation

+"""Collection of utilities for assigning different properties based on orientation.
+
+The functions here are meant to be adaptable to splitting up the compass based on
+however many bins the user desires, though the most common arrangement is likely
+to be a list of 4 values for North, East South, and West.
+
+Usage:
+
+.. code-block:: python
+
+    # list of constructions + materials to apply to faces of different orientations
+    ep_constructions = [constr_north, constr_east, constr_south, constr_west]
+    rad_materials = [mat_north, mat_east, mat_south, mat_west]
+
+    # check that the inputs align with one another
+    all_inputs = [ep_constructions, rad_materials]
+    all_inputs, num_orient = check_matching_inputs(all_inputs)
+
+    # assign properties based on orientation
+    angles = angles_from_num_orient(num_orient)
+    for face in hb_faces:
+        orient_i = face_orient_index(face, angles)
+        if orient_i is not None:
+            constr, mat = inputs_by_index(orient_i, all_inputs)
+            face.properties.energy.construction = constr
+            face.properties.radiance.modifier = mat
+"""
+from ladybug_geometry.geometry2d.pointvector import Vector2D
+
+
+
[docs]def angles_from_num_orient(num_subdivisions=4): + """Get a list of angles based on the number of compass subdivisions. + + Args: + num_subdivisions: An integer for the number of times that the compass + should be subdivided. Default: 4, which will yield angles for North, + East South, and West. + + Returns: + A list of angles in degrees with a length of the num_subdivisions, which + denote the boundaries of each orientation category. + """ + step = 360.0 / num_subdivisions + start = step / 2.0 + angles = [] + while start < 360: + angles.append(start) + start += step + return angles
+ + +
[docs]def face_orient_index(face, angles, north_vector=Vector2D(0, 1)): + """Get the index to be used for a given face/aperture orientation from an angle list. + + Args: + face: A honeybee Face or Aperture object. + angles: A list of angles that denote the boundaries of each orientation + category. + north_vector: An optional ladybug_geometry Vector2D for the north direction. + Default is the Y-axis (0, 1). + + Returns: + An integer for the index used to assign properties to the object of the + input orientation. Will be None if the input Face or Aperture is perfectly + horizontal. + """ + try: + return orient_index(face.horizontal_orientation(north_vector), angles) + except ZeroDivisionError: # input face is perfectly horizontal + return None
+ + +
[docs]def orient_index(orientation, angles): + """Get the index to be used for a given face/aperture orientation from an angle list. + + Args: + orientation: The horizontal cardinal orientation of the Face or Aperture + in degrees. + angles: A list of angles that denote the boundaries of each orientation + category. + + Returns: + An integer for the index used to assign properties to the object of the + input orientation. + """ + for i, ang in enumerate(angles): + if orientation < ang: + return i + return 0
+ + +
[docs]def inputs_by_index(orientation_index, all_inputs): + """Get all of the inputs of a certain index from a list of all_inputs. + + This is useful for getting the set of all inputs that should be assigned to + a given Face or Aperture using its orientation_index. + """ + return [inp[orientation_index] for inp in all_inputs]
+ + +
[docs]def check_matching_inputs(all_inputs, num_orient=None): + """Check that all orientation-specific inputs are coordinated. + + This means that each input is either a array of values to be applied to each + orientation, which is has the same length as other orientation-specific arrays, + or it is a single value to be used for all orientations. + + Args: + all_inputs: An array of arrays where each sub-array corresponds to an + orientation-specific input. + num_orient: An optional integer for the number of orientation categories + to be used. If None, the length of the longest input list in the + all_inputs will be used. + + Returns: + A tuple with two elements + + - all_inputs -- The input all_inputs with all sub-arrays having the same length. + + - num_orient -- An integer for the number of orientations used in the check. + """ + num_orient = max([len(inp) for inp in all_inputs]) if num_orient is None \ + else num_orient + for i, param_list in enumerate(all_inputs): + if len(param_list) == 1: + all_inputs[i] = param_list * num_orient + else: + assert len(param_list) == num_orient, \ + 'The number of items in one of the inputs lists does not match the ' \ + 'others.\nPlease ensure that either the lists match or you put in '\ + 'a single value for all orientations.' + return all_inputs, num_orient
+
+ +
+ +
+
+
+
+

+ Back to top + +

+

+ © Copyright 2023, Ladybug Tools.
+ Created using Sphinx 5.3.0.
+

+
+
+ + \ No newline at end of file diff --git a/docs/_modules/honeybee/properties.html b/docs/_modules/honeybee/properties.html new file mode 100644 index 00000000..690f2817 --- /dev/null +++ b/docs/_modules/honeybee/properties.html @@ -0,0 +1,1874 @@ + + + + + + + honeybee.properties — honeybee documentation + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+ +

Source code for honeybee.properties

+# coding: utf-8
+"""Extension properties for Model, Room, Face, Shade, Aperture, Door.
+
+These objects hold all attributes assigned by extensions like honeybee-radiance
+and honeybee-energy.  Note that these Property objects are not intended to exist
+on their own but should have a host object.
+"""
+
+
+class _Properties(object):
+    """Base class for all Properties classes.
+
+    Args:
+        host: A honeybee-core geometry object that hosts these properties
+            (ie. Model, Room, Face, Shade, Aperture, Door).
+    """
+    _exclude = set(
+        ('host', 'move', 'rotate', 'rotate_xy', 'reflect', 'scale', 'is_equivalent',
+         'add_prefix', 'reset_to_default', 'to_dict', 'apply_properties_from_dict',
+         'ToString'))
+
+    def __init__(self, host):
+        """Initialize properties."""
+        self._host = host
+
+    @property
+    def host(self):
+        """Get the object hosting these properties."""
+        return self._host
+
+    @property
+    def _extension_attributes(self):
+        return (atr for atr in dir(self) if not atr.startswith('_')
+                and atr not in self._exclude)
+
+    def move(self, moving_vec):
+        """Apply a move transform to extension attributes.
+
+        This is useful in cases where extension attributes possess geometric data
+        that should be moved alongside the host object. For example, dynamic
+        geometry within the honeybee-radiance state of an aperture should be
+        moved if the host aperture is moved.
+
+        Args:
+            moving_vec: A ladybug_geometry Vector3D with the direction and distance
+                to move the face.
+        """
+        for atr in self._extension_attributes:
+            var = getattr(self, atr)
+            if not hasattr(var, 'move'):
+                continue
+            try:
+                var.move(moving_vec)
+            except Exception as e:
+                import traceback
+                traceback.print_exc()
+                raise Exception('Failed to move {}: {}'.format(var, e))
+
+    def rotate(self, axis, angle, origin):
+        """Apply a rotation transform to extension attributes.
+
+        This is useful in cases where extension attributes possess geometric data
+        that should be rotated alongside the host object. For example, dynamic
+        geometry within the honeybee-radiance state of an aperture should be
+        rotated if the host aperture is rotated.
+
+        Args:
+            axis: A ladybug_geometry Vector3D axis representing the axis of rotation.
+            angle: An angle for rotation in degrees.
+            origin: A ladybug_geometry Point3D for the origin around which the
+                object will be rotated.
+        """
+        for atr in self._extension_attributes:
+            var = getattr(self, atr)
+            if not hasattr(var, 'rotate'):
+                continue
+            try:
+                var.rotate(axis, angle, origin)
+            except Exception as e:
+                import traceback
+                traceback.print_exc()
+                raise Exception('Failed to rotate {}: {}'.format(var, e))
+
+    def rotate_xy(self, angle, origin):
+        """Apply a rotation in the XY plane to extension attributes.
+
+        This is useful in cases where extension attributes possess geometric data
+        that should be rotated alongside the host object. For example, dynamic
+        geometry within the honeybee-radiance state of an aperture should be
+        rotated if the host aperture is rotated.
+
+        Args:
+            angle: An angle in degrees.
+            origin: A ladybug_geometry Point3D for the origin around which the
+                object will be rotated.
+        """
+        for atr in self._extension_attributes:
+            var = getattr(self, atr)
+            if not hasattr(var, 'rotate_xy'):
+                continue
+            try:
+                var.rotate_xy(angle, origin)
+            except Exception as e:
+                import traceback
+                traceback.print_exc()
+                raise Exception('Failed to rotate {}: {}'.format(var, e))
+
+    def reflect(self, plane):
+        """Apply a reflection transform to extension attributes.
+
+        This is useful in cases where extension attributes possess geometric data
+        that should be reflected alongside the host object. For example, dynamic
+        geometry within the honeybee-radiance state of an aperture should be
+        reflected if the host aperture is reflected.
+
+        Args:
+            plane: A ladybug_geometry Plane across which the object will
+                be reflected.
+        """
+        for atr in self._extension_attributes:
+            var = getattr(self, atr)
+            if not hasattr(var, 'reflect'):
+                continue
+            try:
+                var.reflect(plane)
+            except Exception as e:
+                import traceback
+                traceback.print_exc()
+                raise Exception('Failed to reflect {}: {}'.format(var, e))
+
+    def scale(self, factor, origin=None):
+        """Apply a scale transform to extension attributes.
+
+        This is useful in cases where extension attributes possess geometric data
+        that should be scaled alongside the host object. For example, dynamic
+        geometry within the honeybee-radiance state of an aperture should be
+        scaled if the host aperture is scaled.
+
+        Args:
+            factor: A number representing how much the object should be scaled.
+            origin: A ladybug_geometry Point3D representing the origin from which
+                to scale. If None, it will be scaled from the World origin (0, 0, 0).
+        """
+        for atr in self._extension_attributes:
+            var = getattr(self, atr)
+            if not hasattr(var, 'scale'):
+                continue
+            try:
+                var.scale(factor, origin)
+            except Exception as e:
+                import traceback
+                traceback.print_exc()
+                raise Exception('Failed to scale {}: {}'.format(var, e))
+
+    def is_equivalent(self, other_properties):
+        """Get a dictionary noting the equivalency of these properties to other ones.
+
+        The keys of this dictionary will note the name of each extension (eg.
+        energy, radiance) and the values will be a boolean for whether the
+        extension properties are equivalent or not.
+
+        Args:
+            other_properties: Properties of another object for which equivalency
+                will be tested.
+        """
+        eq_dict = {}
+        for atr in self._extension_attributes:
+            var = getattr(self, atr)
+            if not hasattr(var, 'is_equivalent'):
+                continue
+            other_var = getattr(other_properties, atr)
+            try:
+                eq_dict[atr] = var.is_equivalent(other_var)
+            except Exception as e:
+                import traceback
+                traceback.print_exc()
+                raise Exception('Failed test is_equivalent for {}: {}'.format(var, e))
+        return eq_dict
+
+    def _update_by_sync(self, change, existing_prop, updated_prop):
+        """Update properties using change instructions and existing/updated objects."""
+        for atr in self._extension_attributes:
+            up_atr = 'update_{}'.format(atr)
+            if up_atr in change:
+                var = getattr(updated_prop, atr) if change[up_atr] \
+                    else getattr(existing_prop, atr)
+                if not hasattr(var, 'duplicate'):
+                    continue
+                try:
+                    setattr(self, '_' + atr, var.duplicate(self.host))
+                except Exception as e:
+                    import traceback
+                    traceback.print_exc()
+                    raise Exception('Failed to duplicate {}: {}'.format(var, e))
+
+    def _duplicate_extension_attr(self, original_properties):
+        """Duplicate the attributes added by extensions.
+
+        This method should be called within the duplicate or __copy__ methods of
+        each honeybee-core geometry object after the core object has been duplicated.
+        This method only needs to be called on the new (duplicated) core object and
+        the extension properties of the original core object should be passed to
+        this method as the original_properties.
+
+        Args:
+            original_properties: The properties object of the original core
+                object from which the duplicate was derived.
+        """
+        for atr in self._extension_attributes:
+            var = getattr(original_properties, atr)
+            if not hasattr(var, 'duplicate'):
+                continue
+            try:
+                setattr(self, '_' + atr, var.duplicate(self.host))
+            except Exception as e:
+                import traceback
+                traceback.print_exc()
+                raise Exception('Failed to duplicate {}: {}'.format(var, e))
+
+    def _add_prefix_extension_attr(self, prefix):
+        """Change the name extension attributes unique to this object by adding a prefix.
+
+        This is particularly useful in workflows where you duplicate and edit
+        a starting object and then want to combine it with the original object
+        into one Model (like making a model of repeated rooms).
+
+        Notably, this method only adds the prefix to extension attributes that must
+        be unique to the object and does not add the prefix to attributes that are
+        shared across several objects.
+
+        Args:
+            prefix: Text that will be inserted at the start of the extension attributes'
+                name. It is recommended that this name be short to avoid maxing
+                out the 100 allowable characters for honeybee names.
+        """
+        for atr in self._extension_attributes:
+            var = getattr(self, atr)
+            if not hasattr(var, 'add_prefix'):
+                continue
+            try:
+                var.add_prefix(prefix)
+            except Exception as e:
+                import traceback
+                traceback.print_exc()
+                raise Exception('Failed to add prefix to {}: {}'.format(var, e))
+
+    def _reset_extension_attr_to_default(self):
+        """Reset all extension attributes for the object to be default.
+
+        This is useful in cases where properties that are hard-assigned to a specific
+        object might be illegal in combination with other properties and so they
+        should be reset upon the setting of the other properties. For example,
+        setting a Face type to AirBoundary typically makes certain types of energy
+        and radiance properties illegal. So calling this function whenever setting
+        Face type to AirBoundary will reset the extension attributes to the legal
+        default values.
+        """
+        for atr in self._extension_attributes:
+            var = getattr(self, atr)
+            if not hasattr(var, 'reset_to_default'):
+                continue
+            try:
+                var.reset_to_default()
+            except Exception as e:
+                import traceback
+                traceback.print_exc()
+                raise Exception('Failed to reset_to_default for {}: {}'.format(var, e))
+
+    def _add_extension_attr_to_dict(self, base, abridged, include):
+        """Add attributes for extensions to the base dictionary.
+
+        This method should be called within the to_dict method of each honeybee-core
+        geometry object.
+
+        Args:
+            base: The dictionary of the core object without any extension attributes.
+                This method will add extension attributes to this dictionary. For
+                example, energy properties will appear under base['properties']['energy'].
+            abridged: Boolean to note whether the attributes of the extensions should
+                be abridged (True) or full (False). For example, if a Room's energy
+                properties are abridged, the program_type attribute under the energy
+                properties dictionary will just be the identifier of the program_type. If
+                it is full (not abridged), the program_type will be a complete
+                dictionary following the ProgramType schema. Abridged dictionaries
+                should be used within the Model.to_dict but full dictionaries should
+                be used within the to_dict methods of individual objects.
+            include: List of properties to filter keys that must be included in
+                output dictionary. For example ['energy'] will include 'energy' key if
+                available in properties to_dict. By default all the keys will be
+                included. To exclude all the keys from extensions use an empty list.
+        """
+        attr = include if include is not None else self._extension_attributes
+        for atr in attr:
+            var = getattr(self, atr)
+            if not hasattr(var, 'to_dict'):
+                continue
+            try:
+                base.update(var.to_dict(abridged))
+            except Exception as e:
+                import traceback
+                traceback.print_exc()
+                raise Exception('Failed to convert {} to a dict: {}'.format(var, e))
+        return base
+
+    def _load_extension_attr_from_dict(self, property_dict):
+        """Get attributes for extensions from a dictionary of the properties.
+
+        This method should be called within the from_dict method of each honeybee-core
+        geometry object. Specifically, this method should be called on the core
+        object after it has been created from a dictionary but lacks any of the
+        extension attributes in the dictionary.
+
+        Args:
+            property_dict: A dictionary of properties for the object (ie.
+                FaceProperties, RoomProperties). These will be used to load
+                attributes from the dictionary and assign them to the object on
+                which this method is called.
+        """
+        for atr in self._extension_attributes:
+            var = getattr(self, atr)
+            if not hasattr(var, 'from_dict'):
+                continue
+            try:
+                setattr(self, '_' + atr, var.__class__.from_dict(
+                    property_dict[atr], self.host))
+            except KeyError:
+                pass  # the property_dict possesses no properties for that extension
+
+    def ToString(self):
+        """Overwrite .NET ToString method."""
+        return self.__repr__()
+
+    def __repr__(self):
+        """Properties representation."""
+        return 'BaseProperties'
+
+
+
[docs]class ModelProperties(_Properties): + """Honeybee Model Properties. + + This class will be extended by extensions. + + Usage: + + .. code-block:: python + + model = Model('New Elementary School', list_of_rooms) + model.properties -> ModelProperties + model.properties.radiance -> ModelRadianceProperties + model.properties.energy -> ModelEnergyProperties + """ + +
[docs] def to_dict(self, include=None): + """Convert properties to dictionary. + + Args: + include: A list of keys to be included in dictionary. + If None all the available keys will be included. + """ + base = {'type': 'ModelProperties'} + attr = include if include is not None else self._extension_attributes + for atr in attr: + var = getattr(self, atr) + if not hasattr(var, 'to_dict'): + continue + try: + base.update(var.to_dict()) # no abridged dictionary for model + except Exception as e: + import traceback + traceback.print_exc() + raise Exception('Failed to convert {} to a dict: {}'.format(var, e)) + return base
+ +
[docs] def apply_properties_from_dict(self, data): + """Apply extension properties from a Model dictionary to the host Model. + + Args: + data: A dictionary representation of an entire honeybee-core Model. + """ + for atr in self._extension_attributes: + if atr not in data['properties'] or data['properties'][atr] is None: + continue + var = getattr(self, atr) + if var and not hasattr(var, 'apply_properties_from_dict'): + continue + try: + var.apply_properties_from_dict(data) + except Exception as e: + import traceback + traceback.print_exc() + raise Exception( + 'Failed to apply {} properties to the Model: {}'.format(atr, e))
+ + def _check_extension_attr(self, detailed=False): + """Check the attributes of extensions. + + This method should be called within the check_all method of the Model object + to ensure that the check_all functions of any extension model properties + are also called. + + Args: + detailed: Boolean for whether the returned object is a detailed list of + dicts with error info or a string with a message. (Default: False). + """ + msgs = [] + for atr in self._extension_attributes: + check_msg = None + var = getattr(self, atr) + if not hasattr(var, 'check_all'): + continue + try: + try: + check_msg = var.check_all(raise_exception=False, detailed=detailed) + except TypeError: # no option available for detailed error message + check_msg = var.check_all(raise_exception=False) + if detailed and check_msg is not None: + msgs.append(check_msg) + elif check_msg != '': + f_msg = 'Attributes for {} are invalid.\n{}'.format(atr, check_msg) + msgs.append(f_msg) + except Exception as e: + import traceback + traceback.print_exc() + raise Exception('Failed to check_all for {}: {}'.format(var, e)) + return msgs + + def __repr__(self): + """Properties representation.""" + return 'ModelProperties: {}'.format(self.host.display_name)
+ + +
[docs]class RoomProperties(_Properties): + """Honeybee Room Properties. + + This class will be extended by extensions. + + Usage: + + .. code-block:: python + + room = Room('Bedroom', geometry) + room.properties -> RoomProperties + room.properties.radiance -> RoomRadianceProperties + room.properties.energy -> RoomEnergyProperties + """ + +
[docs] def to_dict(self, abridged=False, include=None): + """Convert properties to dictionary. + + Args: + abridged: Boolean to note whether the full dictionary describing the + object should be returned (False) or just an abridged version (True). + Default: False. + include: A list of keys to be included in dictionary. + If None all the available keys will be included. + """ + base = {'type': 'RoomProperties'} if not abridged else \ + {'type': 'RoomPropertiesAbridged'} + + base = self._add_extension_attr_to_dict(base, abridged, include) + return base
+ +
[docs] def add_prefix(self, prefix): + """Change the identifier extension attributes unique to this object by adding a prefix. + + Notably, this method only adds the prefix to extension attributes that must + be unique to the Room (eg. single-room HVAC systems) and does not add the + prefix to attributes that are shared across several Rooms (eg. ConstructionSets). + + Args: + prefix: Text that will be inserted at the start of extension attribute identifiers. + """ + self._add_prefix_extension_attr(prefix)
+ +
[docs] def reset_to_default(self): + """Reset the extension properties assigned at the level of this Room to default. + + This typically means erasing any ConstructionSets or ModifierSets assigned + to this Room among other properties. + """ + self._reset_extension_attr_to_default()
+ + def __repr__(self): + """Properties representation.""" + return 'RoomProperties: {}'.format(self.host.display_name)
+ + +
[docs]class FaceProperties(_Properties): + """Honeybee Face Properties. + + This class will be extended by extensions. + + Usage: + + .. code-block:: python + + face = Face('South Bedroom Wall', geometry) + face.properties -> FaceProperties + face.properties.radiance -> FaceRadianceProperties + face.properties.energy -> FaceEnergyProperties + """ + +
[docs] def to_dict(self, abridged=False, include=None): + """Convert properties to dictionary. + + Args: + abridged: Boolean to note whether the full dictionary describing the + object should be returned (False) or just an abridged version (True). + Default: False. + include: A list of keys to be included in dictionary besides Face type + and boundary_condition. If None all the available keys will be included. + """ + base = {'type': 'FaceProperties'} if not abridged else \ + {'type': 'FacePropertiesAbridged'} + base = self._add_extension_attr_to_dict(base, abridged, include) + return base
+ +
[docs] def add_prefix(self, prefix): + """Change the identifier extension attributes unique to this object by adding a prefix. + + Notably, this method only adds the prefix to extension attributes that must + be unique to the Face and does not add the prefix to attributes that are + shared across several Faces. + + Args: + prefix: Text that will be inserted at the start of extension attribute identifiers. + """ + self._add_prefix_extension_attr(prefix)
+ +
[docs] def reset_to_default(self): + """Reset the extension properties assigned at the level of this Face to default. + + This typically means erasing any Constructions or Modifiers assigned to this + Face (having them instead assigned by ConstructionSets and ModifierSets). + """ + self._reset_extension_attr_to_default()
+ + def __repr__(self): + """Properties representation.""" + return 'FaceProperties: {}'.format(self.host.display_name)
+ + +
[docs]class ApertureProperties(_Properties): + """Honeybee Aperture Properties. + + This class will be extended by extensions. + + Usage: + + .. code-block:: python + + aperture = Aperture('Window to My Soul', geometry) + aperture.properties -> ApertureProperties + aperture.properties.radiance -> ApertureRadianceProperties + aperture.properties.energy -> ApertureEnergyProperties + """ + +
[docs] def to_dict(self, abridged=False, include=None): + """Convert properties to dictionary. + + Args: + abridged: Boolean to note whether the full dictionary describing the + object should be returned (False) or just an abridged version (True). + Default: False. + include: A list of keys to be included in dictionary. + If None all the available keys will be included. + """ + base = {'type': 'ApertureProperties'} if not abridged else \ + {'type': 'AperturePropertiesAbridged'} + + base = self._add_extension_attr_to_dict(base, abridged, include) + return base
+ +
[docs] def add_prefix(self, prefix): + """Change the identifier extension attributes unique to this object by adding a prefix. + + Notably, this method only adds the prefix to extension attributes that must + be unique to the Aperture and does not add the prefix to attributes that are + shared across several Apertures. + + Args: + prefix: Text that will be inserted at the start of extension attribute identifiers. + """ + self._add_prefix_extension_attr(prefix)
+ +
[docs] def reset_to_default(self): + """Reset the extension properties assigned to this Aperture to default. + + This typically means erasing any Constructions or Modifiers assigned to this + Aperture (having them instead assigned by ConstructionSets and ModifierSets). + """ + self._reset_extension_attr_to_default()
+ + def __repr__(self): + """Properties representation.""" + return 'ApertureProperties: {}'.format(self.host.display_name)
+ + +
[docs]class DoorProperties(_Properties): + """Honeybee Door Properties. + + This class will be extended by extensions. + + Usage: + + .. code-block:: python + + door = Door('Front Door', geometry) + door.properties -> DoorProperties + door.properties.radiance -> DoorRadianceProperties + door.properties.energy -> DoorEnergyProperties + """ + +
[docs] def to_dict(self, abridged=False, include=None): + """Convert properties to dictionary. + + Args: + abridged: Boolean to note whether the full dictionary describing the + object should be returned (False) or just an abridged version (True). + Default: False. + include: A list of keys to be included in dictionary. + If None all the available keys will be included. + """ + base = {'type': 'DoorProperties'} if not abridged else \ + {'type': 'DoorPropertiesAbridged'} + + base = self._add_extension_attr_to_dict(base, abridged, include) + return base
+ +
[docs] def add_prefix(self, prefix): + """Change the identifier extension attributes unique to this object by adding a prefix. + + Notably, this method only adds the prefix to extension attributes that must + be unique to the Door and does not add the prefix to attributes that are + shared across several Doors. + + Args: + prefix: Text that will be inserted at the start of extension attribute identifiers. + """ + self._add_prefix_extension_attr(prefix)
+ +
[docs] def reset_to_default(self): + """Reset the extension properties assigned to this Door to default. + + This typically means erasing any Constructions or Modifiers assigned to this + Door (having them instead assigned by ConstructionSets and ModifierSets). + """ + self._reset_extension_attr_to_default()
+ + def __repr__(self): + """Properties representation.""" + return 'DoorProperties: {}'.format(self.host.display_name)
+ + +
[docs]class ShadeProperties(_Properties): + """Honeybee Shade Properties. + + This class will be extended by extensions. + + Usage: + + .. code-block:: python + + shade = Shade('Deep Overhang', geometry) + shade.properties -> ShadeProperties + shade.properties.radiance -> ShadeRadianceProperties + shade.properties.energy -> ShadeEnergyProperties + """ + +
[docs] def to_dict(self, abridged=False, include=None): + """Convert properties to dictionary. + + Args: + abridged: Boolean to note whether the full dictionary describing the + object should be returned (False) or just an abridged version (True). + Default: False. + include: A list of keys to be included in dictionary. + If None all the available keys will be included. + """ + base = {'type': 'ShadeProperties'} if not abridged else \ + {'type': 'ShadePropertiesAbridged'} + + base = self._add_extension_attr_to_dict(base, abridged, include) + return base
+ +
[docs] def add_prefix(self, prefix): + """Change the identifier extension attributes unique to this object by adding a prefix. + + Notably, this method only adds the prefix to extension attributes that must + be unique to the Shade and does not add the prefix to attributes that are + shared across several Shades. + + Args: + prefix: Text that will be inserted at the start of extension attribute identifiers. + """ + self._add_prefix_extension_attr(prefix)
+ +
[docs] def reset_to_default(self): + """Reset the extension properties assigned at the level of this Shade to default. + + This typically means erasing any Constructions or Modifiers assigned to this + Shade (having them instead assigned by ConstructionSets and ModifierSets). + """ + self._reset_extension_attr_to_default()
+ + def __repr__(self): + """Properties representation.""" + return 'ShadeProperties: {}'.format(self.host.display_name)
+ + +
[docs]class ShadeMeshProperties(_Properties): + """Honeybee ShadeMesh Properties. + + This class will be extended by extensions. + + Usage: + + .. code-block:: python + + shade = ShadeMesh('Hilly Terrain', geometry) + shade.properties -> ShadeMeshProperties + shade.properties.radiance -> ShadeMeshRadianceProperties + shade.properties.energy -> ShadeMeshEnergyProperties + """ + +
[docs] def to_dict(self, abridged=False, include=None): + """Convert properties to dictionary. + + Args: + abridged: Boolean to note whether the full dictionary describing the + object should be returned (False) or just an abridged version (True). + Default: False. + include: A list of keys to be included in dictionary. + If None all the available keys will be included. + """ + base = {'type': 'ShadeMeshProperties'} if not abridged else \ + {'type': 'ShadeMeshPropertiesAbridged'} + + base = self._add_extension_attr_to_dict(base, abridged, include) + return base
+ +
[docs] def add_prefix(self, prefix): + """Change the identifier extension attributes unique to this object by adding a prefix. + + Notably, this method only adds the prefix to extension attributes that must + be unique to the ShadeMesh and does not add the prefix to attributes that are + shared across several ShadeMeshes (eg. modifier). + + Args: + prefix: Text that will be inserted at the start of extension attribute identifiers. + """ + self._add_prefix_extension_attr(prefix)
+ +
[docs] def reset_to_default(self): + """Reset the extension properties assigned to this ShadeMesh to default. + + This typically means erasing any Constructions or Modifiers assigned to this + ShadeMesh. + """ + self._reset_extension_attr_to_default()
+ + def __repr__(self): + """Properties representation.""" + return 'ShadeMeshProperties: {}'.format(self.host.display_name)
+
+ +
+ +
+
+
+
+

+ Back to top + +

+

+ © Copyright 2023, Ladybug Tools.
+ Created using Sphinx 5.3.0.
+

+
+
+ + \ No newline at end of file diff --git a/docs/_modules/honeybee/room.html b/docs/_modules/honeybee/room.html new file mode 100644 index 00000000..1ebd21e2 --- /dev/null +++ b/docs/_modules/honeybee/room.html @@ -0,0 +1,3718 @@ + + + + + + + honeybee.room — honeybee documentation + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+ +

Source code for honeybee.room

+# coding: utf-8
+"""Honeybee Room."""
+from __future__ import division
+import math
+import uuid
+
+from ladybug_geometry.geometry2d import Point2D, Vector2D, Polygon2D
+from ladybug_geometry.geometry3d import Point3D, Vector3D, Ray3D, Plane, Face3D, \
+    Mesh3D, Polyface3D
+from ladybug_geometry_polyskel.polysplit import perimeter_core_subpolygons
+
+import honeybee.writer.room as writer
+from ._basewithshade import _BaseWithShade
+from .typing import float_in_range, int_in_range, clean_string, \
+    invalid_dict_error
+from .properties import RoomProperties
+from .face import Face
+from .facetype import AirBoundary, Wall, Floor, RoofCeiling, get_type_from_normal
+from .boundarycondition import get_bc_from_position, Outdoors, Ground, Surface, \
+    boundary_conditions
+from .orientation import angles_from_num_orient, orient_index
+try:
+    ad_bc = boundary_conditions.adiabatic
+except AttributeError:  # honeybee_energy is not loaded and adiabatic does not exist
+    ad_bc = None
+
+
+
[docs]class Room(_BaseWithShade): + """A volume enclosed by faces, representing a single room or space. + + Note that, if zero is input for tolerance and angle_tolerance, no checks + will be performed to determine whether the room is a closed volume + and no attempt will be made to flip faces in the event that they are not + facing outward from the room volume. As such, an input tolerance of 0 + is intended for workflows where the solidity of the room volume has been + evaluated elsewhere. + + Args: + identifier: Text string for a unique Room ID. Must be < 100 characters and + not contain any spaces or special characters. + faces: A list or tuple of honeybee Face objects that together form the + closed volume of a room. + tolerance: The maximum difference between x, y, and z values + at which vertices of adjacent faces are considered equivalent. This is + used in determining whether the faces form a closed volume. Default + is 0, which makes no attempt to evaluate whether the Room volume + is closed. + angle_tolerance: The max angle difference in degrees that vertices are + allowed to differ from one another in order to consider them colinear. + Default is 0, which makes no attempt to evaluate whether the Room + volume is closed. + + Properties: + * identifier + * display_name + * faces + * multiplier + * story + * exclude_floor_area + * indoor_furniture + * indoor_shades + * outdoor_shades + * walls + * floors + * roof_ceilings + * air_boundaries + * doors + * apertures + * exterior_apertures + * geometry + * center + * min + * max + * volume + * floor_area + * exposed_area + * exterior_wall_area + * exterior_aperture_area + * exterior_wall_aperture_area + * exterior_skylight_aperture_area + * average_floor_height + * user_data + """ + __slots__ = ('_geometry', '_faces', '_multiplier', '_story', '_exclude_floor_area') + + def __init__(self, identifier, faces, tolerance=0, angle_tolerance=0): + """Initialize Room.""" + _BaseWithShade.__init__(self, identifier) # process the identifier + + # process the zone volume geometry + if not isinstance(faces, tuple): + faces = tuple(faces) + for face in faces: + assert isinstance(face, Face), \ + 'Expected honeybee Face. Got {}'.format(type(face)) + face._parent = self + + if tolerance == 0: + self._faces = faces + self._geometry = None # calculated later from faces or added by classmethods + else: + # try to get a closed volume between the faces + room_polyface = Polyface3D.from_faces( + tuple(face.geometry for face in faces), tolerance) + if not room_polyface.is_solid and angle_tolerance != 0: + ang_tol = math.radians(angle_tolerance) + room_polyface = room_polyface.merge_overlapping_edges(tolerance, ang_tol) + # replace honeybee face geometry with versions that are facing outwards + if room_polyface.is_solid: + for i, correct_face3d in enumerate(room_polyface.faces): + face = faces[i] + norm_init = face._geometry.normal + face._geometry = correct_face3d + if face.has_sub_faces: # flip sub-faces to align with parent Face + if norm_init.angle(face._geometry.normal) > (math.pi / 2): + for ap in face._apertures: + ap._geometry = ap._geometry.flip() + for dr in face._doors: + dr._geometry = dr._geometry.flip() + self._faces = faces + self._geometry = room_polyface + + self._multiplier = 1 # default value that can be overridden later + self._story = None # default value that can be overridden later + self._exclude_floor_area = False # default value that can be overridden later + self._properties = RoomProperties(self) # properties for extensions + +
[docs] @classmethod + def from_dict(cls, data, tolerance=0, angle_tolerance=0): + """Initialize an Room from a dictionary. + + Args: + data: A dictionary representation of a Room object. + tolerance: The maximum difference between x, y, and z values + at which vertices of adjacent faces are considered equivalent. This is + used in determining whether the faces form a closed volume. Default + is 0, which makes no attempt to evaluate whether the Room volume + is closed. + angle_tolerance: The max angle difference in degrees that vertices are + allowed to differ from one another in order to consider them colinear. + Default is 0, which makes no attempt to evaluate whether the Room + volume is closed. + """ + try: + # check the type of dictionary + assert data['type'] == 'Room', 'Expected Room dictionary. ' \ + 'Got {}.'.format(data['type']) + + # create the room object and assign properties + faces = [] + for f_dict in data['faces']: + try: + faces.append(Face.from_dict(f_dict)) + except Exception as e: + invalid_dict_error(f_dict, e) + room = cls(data['identifier'], faces, tolerance, angle_tolerance) + if 'display_name' in data and data['display_name'] is not None: + room.display_name = data['display_name'] + if 'user_data' in data and data['user_data'] is not None: + room.user_data = data['user_data'] + if 'multiplier' in data and data['multiplier'] is not None: + room.multiplier = data['multiplier'] + if 'story' in data and data['story'] is not None: + room.story = data['story'] + if 'exclude_floor_area' in data and data['exclude_floor_area'] is not None: + room.exclude_floor_area = data['exclude_floor_area'] + room._recover_shades_from_dict(data) + + if data['properties']['type'] == 'RoomProperties': + room.properties._load_extension_attr_from_dict(data['properties']) + return room + except Exception as e: + cls._from_dict_error_message(data, e)
+ +
[docs] @classmethod + def from_polyface3d(cls, identifier, polyface, roof_angle=60, floor_angle=130, + ground_depth=0): + """Initialize a Room from a ladybug_geometry Polyface3D object. + + Args: + identifier: Text string for a unique Room ID. Must be < 100 characters and + not contain any spaces or special characters. + polyface: A ladybug_geometry Polyface3D object representing the closed + volume of a room. The Polyface3D.is_solid property can be used to + determine whether the polyface is a closed solid before input here. + roof_angle: A number between 0 and 90 to set the angle from the horizontal + plane below which faces will be considered roofs instead of + walls. 90 indicates that all vertical faces are roofs and 0 + indicates that all horizontal faces are walls. (Default: 60, + recommended by the ASHRAE 90.1 standard). + floor_angle: A number between 90 and 180 to set the angle from the horizontal + plane above which faces will be considered floors instead of + walls. 180 indicates that all vertical faces are floors and 0 + indicates that all horizontal faces are walls. (Default: 130, + recommended by the ASHRAE 90.1 standard). + ground_depth: The Z value above which faces are considered Outdoors + instead of Ground. Faces will have a Ground boundary condition if + all of their vertices lie at or below this value. Default: 0. + """ + assert isinstance(polyface, Polyface3D), \ + 'Expected ladybug_geometry Polyface3D. Got {}'.format(type(polyface)) + faces = [] + for i, face in enumerate(polyface.faces): + faces.append(Face('{}..Face{}'.format(identifier, i), face, + get_type_from_normal(face.normal, roof_angle, floor_angle), + get_bc_from_position(face.boundary, ground_depth))) + room = cls(identifier, faces) + room._geometry = polyface + return room
+ +
[docs] @classmethod + def from_box(cls, identifier, width=3.0, depth=6.0, height=3.2, + orientation_angle=0, origin=Point3D(0, 0, 0)): + """Initialize a Room from parameters describing a box. + + The resulting faces of the room will always be ordered as follows: + (Bottom, Front, Right, Back, Left, Top) where the front is facing the + cardinal direction of the orientation_angle. + + Args: + identifier: Text string for a unique Room ID. Must be < 100 characters and + not contain any spaces or special characters. + width: Number for the width of the box (in the X direction). Default: 3.0. + depth: Number for the depth of the box (in the Y direction). Default: 6.0. + height: Number for the height of the box (in the Z direction). Default: 3.2. + orientation_angle: A number between 0 and 360 for the clockwise + orientation of the box in degrees. + (0 = North, 90 = East, 180 = South, 270 = West) + origin: A ladybug_geometry Point3D for the origin of the room. + """ + # create a box Polyface3D + x_axis = Vector3D(1, 0, 0) + if orientation_angle != 0: + angle = -1 * math.radians( + float_in_range(orientation_angle, 0, 360, 'orientation_angle')) + x_axis = x_axis.rotate_xy(angle) + base_plane = Plane(Vector3D(0, 0, 1), origin, x_axis) + polyface = Polyface3D.from_box(width, depth, height, base_plane) + + # create the honeybee Faces + directions = ('Bottom', 'Front', 'Right', 'Back', 'Left', 'Top') + faces = [] + for face, dir in zip(polyface.faces, directions): + faces.append(Face('{}_{}'.format(identifier, dir), face, + get_type_from_normal(face.normal), + get_bc_from_position(face.boundary))) + room = cls(identifier, faces) + room._geometry = polyface + return room
+ + @property + def faces(self): + """Get a tuple of all honeybee Faces making up this room volume.""" + return self._faces + + @property + def multiplier(self): + """Get or set an integer noting how many times this Room is repeated. + + Multipliers are used to speed up the calculation when similar Rooms are + repeated more than once. Essentially, a given simulation with the + Room is run once and then the result is multiplied by the multiplier. + This means that the "repetition" isn't in a particular direction (it's + essentially in the exact same location) and this comes with some + inaccuracy. However, this error might not be too large if the Rooms + are similar enough and it can often be worth it since it can greatly + speed up the calculation. + """ + return self._multiplier + + @multiplier.setter + def multiplier(self, value): + self._multiplier = int_in_range(value, 1, input_name='room multiplier') + + @property + def story(self): + """Get or set text for the story identifier to which this Room belongs. + + Rooms sharing the same story identifier are considered part of the same + story in a Model. Note that the story identifier has no character + restrictions much like display_name. + """ + return self._story + + @story.setter + def story(self, value): + if value is not None: + try: + self._story = str(value) + except UnicodeEncodeError: # Python 2 machine lacking the character set + self._story = value # keep it as unicode + else: + self._story = value + + @property + def exclude_floor_area(self): + """Get or set a boolean for whether the floor area contributes to the Model. + + Note that this will not affect the floor_area property of this Room but + it will ensure the Room's floor area is excluded from any calculations + when the Room is part of a Model. + """ + return self._exclude_floor_area + + @exclude_floor_area.setter + def exclude_floor_area(self, value): + self._exclude_floor_area = bool(value) + + @property + def indoor_furniture(self): + """Array of all indoor furniture Shade objects assigned to this Room. + + Note that this property is identical to the indoor_shades property but + it is provided here under an alternate name to make it clear that indoor + furniture objects should be added here to the Room. + """ + return tuple(self._indoor_shades) + + @property + def walls(self): + """Get a tuple of all of the Wall Faces of the Room.""" + return tuple(face for face in self._faces if isinstance(face.type, Wall)) + + @property + def floors(self): + """Get a tuple of all of the Floor Faces of the Room.""" + return tuple(face for face in self._faces if isinstance(face.type, Floor)) + + @property + def roof_ceilings(self): + """Get a tuple of all of the RoofCeiling Faces of the Room.""" + return tuple(face for face in self._faces if isinstance(face.type, RoofCeiling)) + + @property + def air_boundaries(self): + """Get a tuple of all of the AirBoundary Faces of the Room.""" + return tuple(face for face in self._faces if isinstance(face.type, AirBoundary)) + + @property + def doors(self): + """Get a tuple of all Doors of the Room.""" + drs = [] + for face in self._faces: + if len(face._doors) > 0: + drs.extend(face._doors) + return tuple(drs) + + @property + def apertures(self): + """Get a tuple of all Apertures of the Room.""" + aps = [] + for face in self._faces: + if len(face._apertures) > 0: + aps.extend(face._apertures) + return tuple(aps) + + @property + def exterior_apertures(self): + """Get a tuple of all exterior Apertures of the Room.""" + aps = [] + for face in self._faces: + if isinstance(face.boundary_condition, Outdoors) and \ + len(face._apertures) > 0: + aps.extend(face._apertures) + return tuple(aps) + + @property + def geometry(self): + """Get a ladybug_geometry Polyface3D object representing the room.""" + if self._geometry is None: + self._geometry = Polyface3D.from_faces( + tuple(face.geometry for face in self._faces), 0) # use 0 tolerance + return self._geometry + + @property + def center(self): + """Get a ladybug_geometry Point3D for the center of the room. + + Note that this is the center of the bounding box around the room Polyface + geometry and not the volume centroid. Also note that shades assigned to + this room are not included in this center calculation. + """ + return self.geometry.center + + @property + def min(self): + """Get a Point3D for the minimum of the bounding box around the object. + + This includes any shades assigned to this object or its children. + """ + all_geo = self._outdoor_shades + self._indoor_shades + all_geo.extend(self._faces) + return self._calculate_min(all_geo) + + @property + def max(self): + """Get a Point3D for the maximum of the bounding box around the object. + + This includes any shades assigned to this object or its children. + """ + all_geo = self._outdoor_shades + self._indoor_shades + all_geo.extend(self._faces) + return self._calculate_max(all_geo) + + @property + def volume(self): + """Get the volume of the room. + + Note that, if this room faces do not form a closed solid the value of this + property will not be accurate. + """ + return self.geometry.volume + + @property + def floor_area(self): + """Get the combined area of all room floor faces.""" + return sum([face.area for face in self._faces if isinstance(face.type, Floor)]) + + @property + def exposed_area(self): + """Get the combined area of all room faces with outdoor boundary conditions. + + Useful for estimating infiltration, often expressed as a flow per + unit exposed envelope area. + """ + return sum([face.area for face in self._faces if + isinstance(face.boundary_condition, Outdoors)]) + + @property + def exterior_wall_area(self): + """Get the combined area of all exterior walls on the room. + + This is NOT the area of the wall's punched_geometry and it includes BOTH + the area of opaque and transparent parts of the walls. + """ + wall_areas = 0 + for f in self._faces: + if isinstance(f.boundary_condition, Outdoors) and isinstance(f.type, Wall): + wall_areas += f.area + return wall_areas + + @property + def exterior_roof_area(self): + """Get the combined area of all exterior roofs on the room. + + This is NOT the area of the roof's punched_geometry and it includes BOTH + the area of opaque and transparent parts of the roofs. + """ + wall_areas = 0 + for f in self._faces: + if isinstance(f.boundary_condition, Outdoors) and \ + isinstance(f.type, RoofCeiling): + wall_areas += f.area + return wall_areas + + @property + def exterior_aperture_area(self): + """Get the combined area of all exterior apertures on the room.""" + ap_areas = 0 + for face in self._faces: + if isinstance(face.boundary_condition, Outdoors) and \ + len(face._apertures) > 0: + ap_areas += sum(ap.area for ap in face._apertures) + return ap_areas + + @property + def exterior_wall_aperture_area(self): + """Get the combined area of all apertures on exterior walls of the room.""" + ap_areas = 0 + for face in self._faces: + if isinstance(face.boundary_condition, Outdoors) and \ + isinstance(face.type, Wall) and len(face._apertures) > 0: + ap_areas += sum(ap.area for ap in face._apertures) + return ap_areas + + @property + def exterior_skylight_aperture_area(self): + """Get the combined area of all apertures on exterior roofs of the room.""" + ap_areas = 0 + for face in self._faces: + if isinstance(face.boundary_condition, Outdoors) and \ + isinstance(face.type, RoofCeiling) and len(face._apertures) > 0: + ap_areas += sum(ap.area for ap in face._apertures) + return ap_areas + + @property + def average_floor_height(self): + """Get the height of the room floor averaged over all floor faces in the room. + + The resulting value is weighted by the area of each of the floor faces. + Will be the minimum Z value of the Room volume if the room possesses no floors. + """ + heights = 0 + areas = 0 + for face in self._faces: + if isinstance(face.type, Floor): + heights += face.center.z * face.area + areas += face.area + return heights / areas if areas != 0 else self.geometry.min.z + + @property + def has_parent(self): + """Always False as Rooms cannot have parents.""" + return False + +
[docs] def average_orientation(self, north_vector=Vector2D(0, 1)): + """Get a number between 0 and 360 for the average orientation of exposed walls. + + 0 = North, 90 = East, 180 = South, 270 = West. Will be None if the zone has + no exterior walls. Resulting value is weighted by the area of each of the + wall faces. + + Args: + north_vector: A ladybug_geometry Vector2D for the north direction. + Default is the Y-axis (0, 1). + """ + orientations = 0 + areas = 0 + for face in self._faces: + if isinstance(face.type, Wall) and \ + isinstance(face.boundary_condition, Outdoors): + orientations += face.horizontal_orientation(north_vector) * face.area + areas += face.area + return orientations / areas if areas != 0 else None
+ +
[docs] def add_prefix(self, prefix): + """Change the identifier of this object and child objects by inserting a prefix. + + This is particularly useful in workflows where you duplicate and edit + a starting object and then want to combine it with the original object + into one Model (like making a model of repeated rooms) since all objects + within a Model must have unique identifiers. + + Args: + prefix: Text that will be inserted at the start of this object's + (and child objects') identifier and display_name. It is recommended + that this prefix be short to avoid maxing out the 100 allowable + characters for honeybee identifiers. + """ + self._identifier = clean_string('{}_{}'.format(prefix, self.identifier)) + self.display_name = '{}_{}'.format(prefix, self.display_name) + self.properties.add_prefix(prefix) + for face in self._faces: + face.add_prefix(prefix) + self._add_prefix_shades(prefix)
+ +
[docs] def horizontal_boundary(self, match_walls=False, tolerance=0.01): + """Get a Face3D representing the horizontal boundary around the Room. + + This will be generated from all downward-facing Faces of the Room (essentially + the Floor faces but can also include overhanging slanted walls). So, for + a valid closed-volume Honeybee Room, the result should always represent + the Room in the XY plane. + + The Z height of the resulting Face3D will be at the minimum floor height. + + Args: + match_walls: Boolean to note whether vertices should be inserted into + the final Face3D that will help match the segments of the result + back to the walls that are adjacent to the floors. If False, the + result may lack some colinear vertices that relate the Face3D + to the Walls, though setting this to True does not guarantee that + all walls will relate to a segment in the result. (Default: False). + tolerance: The minimum difference between x, y, and z coordinate values + at which points are considered distinct. (Default: 0.01, + suitable for objects in Meters). + """ + # get the starting horizontal boundary + horiz_bound = self._base_horiz_boundary(tolerance) + if match_walls: # insert the wall vertices + return self._match_walls_to_horizontal_faces([horiz_bound], tolerance)[0] + return horiz_bound
+ +
[docs] def horizontal_floor_boundaries(self, match_walls=False, tolerance=0.01): + """Get a list of horizontal Face3D for the boundaries around the Room's Floors. + + Unlike the horizontal_boundary method, which uses all downward-pointing + geometries, this method will derive horizontal boundaries using only the + Floors. This is useful when the resulting geometry is used to specify the + floor area in the result. + + The Z height of the resulting Face3D will be at the minimum floor height. + + Args: + match_walls: Boolean to note whether vertices should be inserted into + the final Face3Ds that will help match the segments of the result + back to the walls that are adjacent to the floors. If False, the + result may lack some colinear vertices that relate the Face3Ds + to the Walls, though setting this to True does not guarantee that + all walls will relate to a segment in the result. (Default: False). + tolerance: The minimum difference between x, y, and z coordinate values + at which points are considered distinct. (Default: 0.01, + suitable for objects in Meters). + """ + # gather all of the floor geometries + flr_geo = [face.geometry for face in self.floors] + + # ensure that all geometries are horizontal with as few faces as possible + if len(flr_geo) == 0: # degenerate face + return [] + elif len(flr_geo) == 1: + if flr_geo[0].is_horizontal(tolerance): + horiz_bound = flr_geo + else: + floor_height = self.geometry.min.z + bound = [Point3D(p.x, p.y, floor_height) for p in flr_geo[0].boundary] + holes = None + if flr_geo[0].has_holes: + holes = [[Point3D(p.x, p.y, floor_height) for p in hole] + for hole in flr_geo[0].holes] + horiz_bound = [Face3D(bound, holes=holes)] + else: # multiple geometries to be joined together + floor_height = self.geometry.min.z + horiz_geo = [] + for fg in flr_geo: + if fg.is_horizontal(tolerance) and \ + abs(floor_height - fg.min.z) <= tolerance: + horiz_geo.append(fg) + else: # project the face geometry into the XY plane + bound = [Point3D(p.x, p.y, floor_height) for p in fg.boundary] + holes = None + if fg.has_holes: + holes = [[Point3D(p.x, p.y, floor_height) for p in hole] + for hole in fg.holes] + horiz_geo.append(Face3D(bound, holes=holes)) + # join the coplanar horizontal faces together + horiz_bound = Face3D.join_coplanar_faces(horiz_geo, tolerance) + + if match_walls: # insert the wall vertices + return self._match_walls_to_horizontal_faces(horiz_bound, tolerance) + return horiz_bound
+ +
[docs] def remove_indoor_furniture(self): + """Remove all indoor furniture assigned to this Room. + + Note that this method is identical to the remove_indoor_shade method but + it is provided here under an alternate name to make it clear that indoor + furniture objects should be added here to the Room. + """ + self.remove_indoor_shades()
+ +
[docs] def add_indoor_furniture(self, shade): + """Add a Shade object representing furniture to the Room. + + Note that this method is identical to the add_indoor_shade method but + it is provided here under an alternate name to make it clear that indoor + furniture objects should be added here to the Room. + + Args: + shade: A Shade object to add to the indoors of this Room, representing + furniture, desks, partitions, etc. + """ + self.add_indoor_shade(shade)
+ +
[docs] def generate_grid(self, x_dim, y_dim=None, offset=1.0): + """Get a gridded Mesh3D objects offset from the floors of this room. + + Note that the x_dim and y_dim refer to dimensions within the XY coordinate + system of the floor faces's planes. So rotating the planes of the floor faces + will result in rotated grid cells. + + Will be None if the Room has no floor faces. + + Args: + x_dim: The x dimension of the grid cells as a number. + y_dim: The y dimension of the grid cells as a number. Default is None, + which will assume the same cell dimension for y as is set for x. + offset: A number for how far to offset the grid from the base face. + Default is 1.0, which will offset the grid to be 1 unit above + the floor. + + Usage: + + .. code-block:: python + + room = Room.from_box(3.0, 6.0, 3.2, 180) + floor_mesh = room.generate_grid(0.5, 0.5, 1) + test_points = floor_mesh.face_centroids + """ + floor_grids = [] + for face in self._faces: + if isinstance(face.type, Floor): + try: + floor_grids.append( + face.geometry.mesh_grid(x_dim, y_dim, offset, True)) + except AssertionError: # grid tolerance not fine enough + pass + if len(floor_grids) == 1: + return floor_grids[0] + elif len(floor_grids) > 1: + return Mesh3D.join_meshes(floor_grids) + return None
+ +
[docs] def generate_exterior_face_grid( + self, dimension, offset=0.1, face_type='Wall', punched_geometry=False): + """Get a gridded Mesh3D offset from the exterior Faces of this Room. + + This will be None if the Room has no exterior Faces. + + Args: + dimension: The dimension of the grid cells as a number. + offset: A number for how far to offset the grid from the base face. + Positive numbers indicate an offset towards the exterior. (Default + is 0.1, which will offset the grid to be 0.1 unit from the faces). + face_type: Text to specify the type of face that will be used to + generate grids. Note that only Faces with Outdoors boundary + conditions will be used, meaning that most Floors will typically + be excluded unless they represent the underside of a cantilever. + Choose from the following. (Default: Wall). + + * Wall + * Roof + * Floor + * All + + punched_geometry: Boolean to note whether the punched_geometry of the faces + should be used (True) with the areas of sub-faces removed from the grid + or the full geometry should be used (False). (Default:False). + + Usage: + + .. code-block:: python + + room = Room.from_box(3.0, 6.0, 3.2, 180) + face_mesh = room.generate_exterior_face_grid(0.5) + test_points = face_mesh.face_centroids + """ + # select the correct face type based on the input + face_t = face_type.title() + if face_t == 'Wall': + ft = Wall + elif face_t in ('Roof', 'Roofceiling'): + ft = RoofCeiling + elif face_t == 'All': + ft = (Wall, RoofCeiling, Floor) + elif face_t == 'Floor': + ft = Floor + else: + raise ValueError('Unrecognized face_type "{}".'.format(face_type)) + face_attr = 'punched_geometry' if punched_geometry else 'geometry' + # loop through the faces and generate grids + face_grids = [] + for face in self._faces: + if isinstance(face.type, ft) and \ + isinstance(face.boundary_condition, Outdoors): + try: + f_geo = getattr(face, face_attr) + face_grids.append( + f_geo.mesh_grid(dimension, None, offset, False)) + except AssertionError: # grid tolerance not fine enough + pass + # join the grids together if there are several ones + if len(face_grids) == 1: + return face_grids[0] + elif len(face_grids) > 1: + return Mesh3D.join_meshes(face_grids) + return None
+ +
[docs] def generate_exterior_aperture_grid( + self, dimension, offset=0.1, aperture_type='All'): + """Get a gridded Mesh3D offset from the exterior Apertures of this room. + + Will be None if the Room has no exterior Apertures. + + Args: + dimension: The dimension of the grid cells as a number. + offset: A number for how far to offset the grid from the base aperture. + Positive numbers indicate an offset towards the exterior while + negative numbers indicate an offset towards the interior, essentially + modeling the value of sun on the building interior. (Default + is 0.1, which will offset the grid to be 0.1 unit from the apertures). + aperture_type: Text to specify the type of Aperture that will be used to + generate grids. Window indicates Apertures in Walls. Choose from + the following. (Default: All). + + * Window + * Skylight + * All + + Usage: + + .. code-block:: python + + room = Room.from_box(3.0, 6.0, 3.2, 180) + room[3].apertures_by_ratio(0.4) + aperture_mesh = room.generate_exterior_aperture_grid(0.5) + test_points = aperture_mesh.face_centroids + """ + # select the correct face type based on the input + ap_t = aperture_type.title() + if ap_t == 'Window': + ft = Wall + elif ap_t == 'Skylight': + ft = RoofCeiling + elif ap_t == 'All': + ft = (Wall, RoofCeiling, Floor) + else: + raise ValueError('Unrecognized aperture_type "{}".'.format(aperture_type)) + # loop through the faces and generate grids + ap_grids = [] + for face in self._faces: + if isinstance(face.type, ft) and \ + isinstance(face.boundary_condition, Outdoors): + for ap in face.apertures: + try: + ap_grids.append( + ap.geometry.mesh_grid(dimension, None, offset, False)) + except AssertionError: # grid tolerance not fine enough + pass + # join the grids together if there are several ones + if len(ap_grids) == 1: + return ap_grids[0] + elif len(ap_grids) > 1: + return Mesh3D.join_meshes(ap_grids) + return None
+ +
[docs] def wall_apertures_by_ratio(self, ratio, tolerance=0.01): + """Add apertures to all exterior walls given a ratio of aperture to face area. + + Note this method removes any existing apertures and doors on the Room's walls. + This method attempts to generate as few apertures as necessary to meet the ratio. + + Args: + ratio: A number between 0 and 1 (but not perfectly equal to 1) + for the desired ratio between aperture area and face area. + tolerance: The maximum difference between point values for them to be + considered equivalent. (Default: 0.01, suitable for objects in meters). + + Usage: + + .. code-block:: python + + room = Room.from_box(3.0, 6.0, 3.2, 180) + room.wall_apertures_by_ratio(0.4) + """ + for face in self._faces: + if isinstance(face.boundary_condition, Outdoors) and \ + isinstance(face.type, Wall): + face.apertures_by_ratio(ratio, tolerance)
+ +
[docs] def skylight_apertures_by_ratio(self, ratio, tolerance=0.01): + """Add apertures to all exterior roofs given a ratio of aperture to face area. + + Note this method removes any existing apertures and overhead doors on the + Room's roofs. This method attempts to generate as few apertures as + necessary to meet the ratio. + + Args: + ratio: A number between 0 and 1 (but not perfectly equal to 1) + for the desired ratio between aperture area and face area. + tolerance: The maximum difference between point values for them to be + considered equivalent. (Default: 0.01, suitable for objects in meters). + + Usage: + + .. code-block:: python + + room = Room.from_box(3.0, 6.0, 3.2, 180) + room.skylight_apertures_by_ratio(0.05) + """ + for face in self._faces: + if isinstance(face.boundary_condition, Outdoors) and \ + isinstance(face.type, RoofCeiling): + face.apertures_by_ratio(ratio, tolerance)
+ +
[docs] def simplify_apertures(self, tolerance=0.01): + """Convert all Apertures on this Room to be a simple window ratio. + + This is useful for studies where faster simulation times are desired and + the window ratio is the critical factor driving the results (as opposed + to the detailed geometry of the window). Apertures assigned to concave + Faces will not be simplified given that the apertures_by_ratio method + likely won't improve the cleanliness of the apertures for such cases. + + Args: + tolerance: The maximum difference between point values for them to be + considered equivalent. (Default: 0.01, suitable for objects in meters). + """ + for face in self.faces: + f_ap = face._apertures + if len(f_ap) != 0 and face.geometry.is_convex: + # reset boundary conditions to outdoors so new apertures can be added + if not isinstance(face.boundary_condition, Outdoors): + face.boundary_condition = boundary_conditions.outdoors + face.apertures_by_ratio(face.aperture_ratio, tolerance)
+ +
[docs] def rectangularize_apertures( + self, subdivision_distance=None, max_separation=None, merge_all=False, + tolerance=0.01, angle_tolerance=1.0): + """Convert all Apertures on this Room to be rectangular. + + This is useful when exporting to simulation engines that only accept + rectangular window geometry. This method will always result ing Rooms where + all Apertures are rectangular. However, if the subdivision_distance is not + set, some Apertures may extend past the parent Face or may collide with + one another. + + Args: + subdivision_distance: A number for the resolution at which the + non-rectangular Apertures will be subdivided into smaller + rectangular units. Specifying a number here ensures that the + resulting rectangular Apertures do not extend past the parent + Face or collide with one another. If None, all non-rectangular + Apertures will be rectangularized by taking the bounding rectangle + around the Aperture. (Default: None). + max_separation: A number for the maximum distance between non-rectangular + Apertures at which point the Apertures will be merged into a single + rectangular geometry. This is often helpful when there are several + triangular Apertures that together make a rectangle when they are + merged across their frames. In such cases, this max_separation + should be set to a value that is slightly larger than the window frame. + If None, no merging of Apertures will happen before they are + converted to rectangles. (Default: None). + merge_all: Boolean to note whether all apertures should be merged before + they are rectangularized. If False, only non-rectangular apertures + will be merged before rectangularization. Note that this argument + has no effect when the max_separation is None. (Default: False). + tolerance: The maximum difference between point values for them to be + considered equivalent. (Default: 0.01, suitable for objects in meters). + angle_tolerance: The max angle in degrees that the corners of the + rectangle can differ from a right angle before it is not + considered a rectangle. (Default: 1). + """ + for face in self._faces: + face.rectangularize_apertures( + subdivision_distance, max_separation, merge_all, + tolerance, angle_tolerance + )
+ +
[docs] def ground_by_custom_surface(self, ground_geometry, tolerance=0.01, + angle_tolerance=1.0): + """Set ground boundary conditions using an array of Face3D for the ground. + + Room faces that are coplanar with the ground surface or lie completely below it + will get a Ground boundary condition while those above will get an Outdoors + boundary condition. Existing Faces with an indoor boundary condition will + be unaffected. + + Args: + ground_geometry: An array of ladybug_geometry Face3D that together + represent the ground surface. + tolerance: The minimum difference between the coordinate values of two + vertices at which they can be considered equivalent. (Default: 0.01, + suitable for objects in meters). + angle_tolerance: The max angle in degrees that the plane normals can + differ from one another in order for them to be considered + coplanar. (Default: 1). + """ + select_faces = self.faces_by_guide_surface( + ground_geometry, Vector3D(0, 0, -1), tolerance, angle_tolerance) + for face in select_faces: + if face.can_be_ground and \ + isinstance(face.boundary_condition, (Outdoors, Ground)): + face.boundary_condition = boundary_conditions.ground
+ +
[docs] def faces_by_guide_surface(self, surface_geometry, directional_vector=None, + tolerance=0.01, angle_tolerance=1.0): + """Get the Faces of the Room that are touching and coplanar with a given surface. + + This is useful in workflows were one would like to set the properties + of a group of Faces using a guide surface, like setting a series of faces + along a given stretch of a parti wall to be adiabatic. + + Args: + surface_geometry: An array of ladybug_geometry Face3D that together + represent the guide surface. + directional_vector: An optional Vector3D to select the room Faces that + lie on a certain side of the surface_geometry. For example, using + (0, 0, -1) will include all Faces that lie below the surface_geometry + in the resulting selection. + tolerance: The minimum difference between the coordinate values of two + vertices at which they can be considered equivalent. (Default: 0.01, + suitable for objects in meters). + angle_tolerance: The max angle in degrees that the plane normals can + differ from one another in order for them to be considered + coplanar. (Default: 1). + """ + selected_faces, ang_tol = [], math.radians(angle_tolerance) + if directional_vector is None: # only check for co-planarity + for face in self.faces: + for srf_geo in surface_geometry: + pl1, pl2 = face.geometry.plane, srf_geo.plane + if pl1.is_coplanar_tolerance(pl2, tolerance, ang_tol): + pt_on_face = face.geometry._point_on_face(tolerance * 2) + if srf_geo.is_point_on_face(pt_on_face, tolerance): + selected_faces.append(face) + break + else: # first check to see if the Face is on the correct side of the surface + rev_vector = directional_vector.reverse() + for face in self.faces: + ray = Ray3D(face.center, rev_vector) + for srf_geo in surface_geometry: + if srf_geo.intersect_line_ray(ray): + selected_faces.append(face) + break + pl1, pl2 = face.geometry.plane, srf_geo.plane + if pl1.is_coplanar_tolerance(pl2, tolerance, ang_tol): + pt_on_face = face.geometry._point_on_face(tolerance * 2) + if srf_geo.is_point_on_face(pt_on_face, tolerance): + selected_faces.append(face) + break + return selected_faces
+ +
[docs] def move(self, moving_vec): + """Move this Room along a vector. + + Args: + moving_vec: A ladybug_geometry Vector3D with the direction and distance + to move the room. + """ + for face in self._faces: + face.move(moving_vec) + self.move_shades(moving_vec) + self.properties.move(moving_vec) + if self._geometry is not None: + self._geometry = self.geometry.move(moving_vec)
+ +
[docs] def rotate(self, axis, angle, origin): + """Rotate this Room by a certain angle around an axis and origin. + + Args: + axis: A ladybug_geometry Vector3D axis representing the axis of rotation. + angle: An angle for rotation in degrees. + origin: A ladybug_geometry Point3D for the origin around which the + object will be rotated. + """ + for face in self._faces: + face.rotate(axis, angle, origin) + self.rotate_shades(axis, angle, origin) + self.properties.rotate(axis, angle, origin) + if self._geometry is not None: + self._geometry = self.geometry.rotate(axis, math.radians(angle), origin)
+ +
[docs] def rotate_xy(self, angle, origin): + """Rotate this Room counterclockwise in the world XY plane by a certain angle. + + Args: + angle: An angle in degrees. + origin: A ladybug_geometry Point3D for the origin around which the + object will be rotated. + """ + for face in self._faces: + face.rotate_xy(angle, origin) + self.rotate_xy_shades(angle, origin) + self.properties.rotate_xy(angle, origin) + if self._geometry is not None: + self._geometry = self.geometry.rotate_xy(math.radians(angle), origin)
+ +
[docs] def reflect(self, plane): + """Reflect this Room across a plane. + + Args: + plane: A ladybug_geometry Plane across which the object will + be reflected. + """ + for face in self._faces: + face.reflect(plane) + self.reflect_shades(plane) + self.properties.reflect(plane) + if self._geometry is not None: + self._geometry = self.geometry.reflect(plane.n, plane.o)
+ +
[docs] def scale(self, factor, origin=None): + """Scale this Room by a factor from an origin point. + + Args: + factor: A number representing how much the object should be scaled. + origin: A ladybug_geometry Point3D representing the origin from which + to scale. If None, it will be scaled from the World origin (0, 0, 0). + """ + for face in self._faces: + face.scale(factor, origin) + self.scale_shades(factor, origin) + self.properties.scale(factor, origin) + if self._geometry is not None: + self._geometry = self.geometry.scale(factor, origin)
+ +
[docs] def remove_colinear_vertices_envelope(self, tolerance=0.01, delete_degenerate=False): + """Remove colinear and duplicate vertices from this object's Faces and Sub-faces. + + If degenerate geometry is found in the process of removing colinear vertices, + an exception will be raised. Note that this does not affect the assigned Shades. + + Args: + tolerance: The minimum distance between a vertex and the boundary segments + at which point the vertex is considered colinear. Default: 0.01, + suitable for objects in meters. + delete_degenerate: Boolean to note whether degenerate Faces, Apertures and + Doors (objects that evaluate to less than 3 vertices at the tolerance) + should be deleted from the Room instead of raising a ValueError. + (Default: False). + """ + if delete_degenerate: + new_faces, i_to_remove = list(self._faces), [] + for i, face in enumerate(new_faces): + try: + face.remove_colinear_vertices(tolerance) + face.remove_degenerate_sub_faces(tolerance) + except ValueError: # degenerate face found! + i_to_remove.append(i) + for i in reversed(i_to_remove): + new_faces.pop(i) + self._faces = tuple(new_faces) + else: + try: + for face in self._faces: + face.remove_colinear_vertices(tolerance) + for ap in face._apertures: + ap.remove_colinear_vertices(tolerance) + for dr in face._doors: + dr.remove_colinear_vertices(tolerance) + except ValueError as e: + raise ValueError( + 'Room "{}" contains invalid geometry.\n {}'.format( + self.full_id, str(e).replace('\n', '\n '))) + if self._geometry is not None: + self._geometry = Polyface3D.from_faces( + tuple(face.geometry for face in self._faces), tolerance)
+ +
[docs] def clean_envelope(self, adjacency_dict, tolerance=0.01): + """Remove colinear and duplicate vertices from this object's Faces and Sub-faces. + + This method also automatically removes degenerate Faces and coordinates + adjacent Faces with the adjacency_dict to ensure matching numbers of + vertices, which is a requirement for engines like EnergyPlus. + + Args: + adjacency_dict: A dictionary containing the identifiers of Room Faces as + keys and Honeybee Face objects as values. This is used to indicate the + target number of vertices that each Face should have after colinear + vertices are removed. This can be used to ensure adjacent Faces + have matching numbers of vertices, which is a requirement for + certain interfaces like EnergyPlus. + tolerance: The minimum distance between a vertex and the boundary segments + at which point the vertex is considered colinear. Default: 0.01, + suitable for objects in meters. + + Returns: + A dictionary containing the identifiers of adjacent Faces as keys and + Honeybee Face objects as values. This can be used as an input in future + Rooms on which this method is run to ensure adjacent Faces have matching + numbers of vertices, which is a requirement for certain interfaces + like EnergyPlus. + """ + adj_dict = {} + new_faces, i_to_remove = list(self._faces), [] + for i, face in enumerate(new_faces): + try: # first make sure that the geometry is not degenerate + new_geo = face.geometry.remove_colinear_vertices(tolerance) + except AssertionError: # degenerate face found! + i_to_remove.append(i) + continue + # see if the geometry matches its adjacent geometry + if isinstance(face.boundary_condition, Surface): + try: + adj_face = adjacency_dict[face.identifier] + if len(new_geo) != len(adj_face.geometry): + new_geo = adj_face.geometry.flip() + except KeyError: # the adjacent object has not been found yet + pass + adj_dict[face.boundary_condition.boundary_condition_object] = face + # update geometry and remove degenerate Apertures and Doors + face._geometry = new_geo + face._punched_geometry = None # reset so that it can be re-computed + face.remove_degenerate_sub_faces(tolerance) + # remove any degenerate Faces from the Room + for i in reversed(i_to_remove): + new_faces.pop(i) + self._faces = tuple(new_faces) + if self._geometry is not None: + self._geometry = Polyface3D.from_faces( + tuple(face.geometry for face in self._faces), tolerance) + return adj_dict
+ +
[docs] def is_geo_equivalent(self, room, tolerance=0.01): + """Get a boolean for whether this object is geometrically equivalent to another. + + This will also check all child Faces, Apertures, Doors and Shades + for equivalency. + + Args: + room: Another Room for which geometric equivalency will be tested. + tolerance: The minimum difference between the coordinate values of two + vertices at which they can be considered geometrically equivalent. + + Returns: + True if geometrically equivalent. False if not geometrically equivalent. + """ + met_1 = (self.display_name, self.multiplier, self.story, self.exclude_floor_area) + met_2 = (room.display_name, room.multiplier, room.story, room.exclude_floor_area) + if met_1 != met_2: + return False + if len(self._faces) != len(room._faces): + return False + for f1, f2 in zip(self._faces, room._faces): + if not f1.is_geo_equivalent(f2, tolerance): + return False + if not self._are_shades_equivalent(room, tolerance): + return False + return True
+ +
[docs] def check_solid(self, tolerance=0.01, angle_tolerance=1, raise_exception=True, + detailed=False): + """Check whether the Room is a closed solid to within the input tolerances. + + Args: + tolerance: tolerance: The maximum difference between x, y, and z values + at which face vertices are considered equivalent. Default: 0.01, + suitable for objects in meters. + angle_tolerance: The max angle difference in degrees that vertices are + allowed to differ from one another in order to consider them colinear. + Default: 1 degree. + raise_exception: Boolean to note whether a ValueError should be raised + if the room geometry does not form a closed solid. + detailed: Boolean for whether the returned object is a detailed list of + dicts with error info or a string with a message. (Default: False). + + Returns: + A string with the message or a list with a dictionary if detailed is True. + """ + if self._geometry is not None and self.geometry.is_solid: + return [] if detailed else '' + face_geometries = tuple(face.geometry for face in self._faces) + self._geometry = Polyface3D.from_faces(face_geometries, tolerance) + if self.geometry.is_solid: + return [] if detailed else '' + ang_tol = math.radians(angle_tolerance) + self._geometry = self.geometry.merge_overlapping_edges(tolerance, ang_tol) + if self.geometry.is_solid: + return [] if detailed else '' + msg = 'Room "{}" is not closed to within {} tolerance and {} angle ' \ + 'tolerance.\n {} naked edges found\n {} non-manifold edges found'.format( + self.full_id, tolerance, angle_tolerance, + len(self._geometry.naked_edges), len(self._geometry.non_manifold_edges)) + full_msg = self._validation_message( + msg, raise_exception, detailed, '000106', + error_type='Non-Solid Room Geometry') + if detailed: # add the naked and non-manifold edges to helper_geometry + help_edges = [ln.to_dict() for ln in self.geometry.naked_edges] + help_edges.extend([ln.to_dict() for ln in self.geometry.non_manifold_edges]) + full_msg[0]['helper_geometry'] = help_edges + return full_msg
+ +
[docs] def check_sub_faces_valid(self, tolerance=0.01, angle_tolerance=1, + raise_exception=True, detailed=False): + """Check that room's sub-faces are co-planar with faces and in the face boundary. + + Note this does not check the planarity of the sub-faces themselves, whether + they self-intersect, or whether they have a non-zero area. + + Args: + tolerance: The minimum difference between the coordinate values of two + vertices at which they can be considered equivalent. Default: 0.01, + suitable for objects in meters. + angle_tolerance: The max angle in degrees that the plane normals can + differ from one another in order for them to be considered coplanar. + Default: 1 degree. + raise_exception: Boolean to note whether a ValueError should be raised + if an sub-face is not valid. (Default: True). + detailed: Boolean for whether the returned object is a detailed list of + dicts with error info or a string with a message. (Default: False). + + Returns: + A string with the message or a list with a dictionary if detailed is True. + """ + detailed = False if raise_exception else detailed + msgs = [] + for f in self._faces: + msg = f.check_sub_faces_valid(tolerance, angle_tolerance, False, detailed) + if detailed: + msgs.extend(msg) + elif msg != '': + msgs.append(msg) + if len(msgs) == 0: + return [] if detailed else '' + elif detailed: + return msgs + full_msg = 'Room "{}" contains invalid sub-faces (Apertures and Doors).' \ + '\n {}'.format(self.full_id, '\n '.join(msgs)) + if raise_exception and len(msgs) != 0: + raise ValueError(full_msg) + return full_msg
+ +
[docs] def check_sub_faces_overlapping( + self, tolerance=0.01, raise_exception=True, detailed=False): + """Check that this Room's sub-faces do not overlap with one another. + + Args: + tolerance: The minimum distance that two sub-faces must overlap in order + for them to be considered overlapping and invalid. (Default: 0.01, + suitable for objects in meters). + raise_exception: Boolean to note whether a ValueError should be raised + if a sub-faces overlap with one another. (Default: True). + detailed: Boolean for whether the returned object is a detailed list of + dicts with error info or a string with a message. (Default: False). + + Returns: + A string with the message or a list with a dictionary if detailed is True. + """ + detailed = False if raise_exception else detailed + msgs = [] + for f in self._faces: + msg = f.check_sub_faces_overlapping(tolerance, False, detailed) + if detailed: + msgs.extend(msg) + elif msg != '': + msgs.append(msg) + if len(msgs) == 0: + return [] if detailed else '' + elif detailed: + return msgs + full_msg = 'Room "{}" contains overlapping sub-faces.' \ + '\n {}'.format(self.full_id, '\n '.join(msgs)) + if raise_exception and len(msgs) != 0: + raise ValueError(full_msg) + return full_msg
+ +
[docs] def check_upside_down_faces( + self, angle_tolerance=1, raise_exception=True, detailed=False): + """Check whether the Room's Faces have the correct direction for the face type. + + This method will only report Floors that are pointing upwards or RoofCeilings + that are pointed downwards. These cases are likely modeling errors and are in + danger of having their vertices flipped by EnergyPlus, causing them to + not see the sun. + + Args: + angle_tolerance: The max angle in degrees that the Face normal can + differ from up or down before it is considered a case of a downward + pointing RoofCeiling or upward pointing Floor. Default: 1 degree. + raise_exception: Boolean to note whether an ValueError should be + raised if the Face is an an upward pointing Floor or a downward + pointing RoofCeiling. + detailed: Boolean for whether the returned object is a detailed list of + dicts with error info or a string with a message. (Default: False). + + Returns: + A string with the message or a list with a dictionary if detailed is True. + """ + detailed = False if raise_exception else detailed + msgs = [] + for f in self._faces: + msg = f.check_upside_down(angle_tolerance, False, detailed) + if detailed: + msgs.extend(msg) + elif msg != '': + msgs.append(msg) + if len(msgs) == 0: + return [] if detailed else '' + elif detailed: + return msgs + full_msg = 'Room "{}" contains upside down Faces.' \ + '\n {}'.format(self.full_id, '\n '.join(msgs)) + if raise_exception and len(msgs) != 0: + raise ValueError(full_msg) + return full_msg
+ +
[docs] def check_planar(self, tolerance=0.01, raise_exception=True, detailed=False): + """Check that all of the Room's geometry components are planar. + + This includes all of the Room's Faces, Apertures, Doors and Shades. + + Args: + tolerance: The minimum distance between a given vertex and a the + object's plane at which the vertex is said to lie in the plane. + Default: 0.01, suitable for objects in meters. + raise_exception: Boolean to note whether an ValueError should be + raised if a vertex does not lie within the object's plane. + detailed: Boolean for whether the returned object is a detailed list of + dicts with error info or a string with a message. (Default: False). + + Returns: + A string with the message or a list with a dictionary if detailed is True. + """ + detailed = False if raise_exception else detailed + msgs = [self._check_planar_shades(tolerance, detailed)] + for face in self._faces: + msgs.append(face.check_planar(tolerance, False, detailed)) + msgs.append(face._check_planar_shades(tolerance, detailed)) + for ap in face._apertures: + msgs.append(ap.check_planar(tolerance, False, detailed)) + msgs.append(ap._check_planar_shades(tolerance, detailed)) + for dr in face._doors: + msgs.append(dr.check_planar(tolerance, False, detailed)) + msgs.append(dr._check_planar_shades(tolerance, detailed)) + full_msgs = [msg for msg in msgs if msg] + if len(full_msgs) == 0: + return [] if detailed else '' + elif detailed: + return [m for megs in full_msgs for m in megs] + full_msg = 'Room "{}" contains non-planar geometry.' \ + '\n {}'.format(self.full_id, '\n '.join(full_msgs)) + if raise_exception and len(full_msgs) != 0: + raise ValueError(full_msg) + return full_msg
+ +
[docs] def check_self_intersecting(self, tolerance=0.01, raise_exception=True, + detailed=False): + """Check that no edges of the Room's geometry components self-intersect. + + This includes all of the Room's Faces, Apertures, Doors and Shades. + + Args: + tolerance: The minimum difference between the coordinate values of two + vertices at which they can be considered equivalent. Default: 0.01, + suitable for objects in meters. + raise_exception: If True, a ValueError will be raised if an object + intersects with itself (like a bow tie). (Default: True). + detailed: Boolean for whether the returned object is a detailed list of + dicts with error info or a string with a message. (Default: False). + + Returns: + A string with the message or a list with a dictionary if detailed is True. + """ + detailed = False if raise_exception else detailed + msgs = [self._check_self_intersecting_shades(tolerance, detailed)] + for face in self._faces: + msgs.append(face.check_self_intersecting(tolerance, False, detailed)) + msgs.append(face._check_self_intersecting_shades(tolerance, detailed)) + for ap in face._apertures: + msgs.append(ap.check_self_intersecting(tolerance, False, detailed)) + msgs.append(ap._check_self_intersecting_shades(tolerance, detailed)) + for dr in face._doors: + msgs.append(dr.check_self_intersecting(tolerance, False, detailed)) + msgs.append(dr._check_self_intersecting_shades(tolerance, detailed)) + full_msgs = [msg for msg in msgs if msg] + if len(full_msgs) == 0: + return [] if detailed else '' + elif detailed: + return [m for megs in full_msgs for m in megs] + full_msg = 'Room "{}" contains self-intersecting geometry.' \ + '\n {}'.format(self.full_id, '\n '.join(full_msgs)) + if raise_exception and len(full_msgs) != 0: + raise ValueError(full_msg) + return full_msg
+ +
[docs] def check_degenerate(self, tolerance=0.01, raise_exception=True, detailed=False): + """Check whether the Room is degenerate with zero volume. + + Args: + tolerance: tolerance: The maximum difference between x, y, and z values + at which face vertices are considered equivalent. (Default: 0.01, + suitable for objects in meters). + raise_exception: Boolean to note whether a ValueError should be raised + if the room geometry is degenerate. (Default: True). + detailed: Boolean for whether the returned object is a detailed list of + dicts with error info or a string with a message. (Default: False). + + Returns: + A string with the message or a list with a dictionary if detailed is True. + """ + if len(self._faces) >= 4 and self.volume > tolerance: + return [] if detailed else '' + msg = 'Room "{}" is degenerate with zero volume. It should be deleted'.format( + self.full_id) + return self._validation_message( + msg, raise_exception, detailed, '000107', + error_type='Degenerate Room Volume')
+ +
[docs] def merge_coplanar_faces( + self, tolerance=0.01, angle_tolerance=1, orthogonal_only=False): + """Merge coplanar Faces of this Room. + + This is often useful before running Room.intersect_adjacency between + multiple Rooms as it will ensure the result is clean with any previous + intersections erased. + + This method attempts to preserve as many properties as possible for the + split Faces but, when Faces are merged, the properties of one of the + merged faces will determine the face type and boundary condition. Also, all + Face extension attributes will be removed (reset to default) and, if merged + Faces originally had Surface boundary conditions, they will be reset + to Outdoors. + + Args: + tolerance: The minimum difference between the coordinate values of two + faces at which they can be considered adjacent. Default: 0.01, + suitable for objects in meters. + angle_tolerance: The max angle in degrees that the plane normals can + differ from one another in order for them to be considered + coplanar. (Default: 1 degree). + orthogonal_only: A boolean to note whether only vertical and horizontal + coplanar faces should be merged, leaving faces with any other tilt + intact. Useful for cases where alignment of walls with the + Room.horizontal_boundary is desired without disrupting the roof + geometry. (Default: False). + + Returns: + A list containing only the new Faces that were created as part of the + merging process. These new Faces will have as many properties of the + original Face assigned to them as possible but they will not have a + Surface boundary condition if the original Face had one. Having + the new Faces here can be used in operations like setting new Surface + boundary conditions or re-assigning extension attributes. + """ + # group the Faces of the Room by their co-planarity + tol, a_tol = tolerance, math.radians(angle_tolerance) + coplanar_dict = {self._faces[0].geometry.plane: [self._faces[0]]} + if not orthogonal_only: + for face in self._faces[1:]: + for pln, f_list in coplanar_dict.items(): + if face.geometry.plane.is_coplanar_tolerance(pln, tol, a_tol): + f_list.append(face) + break + else: # the first face with this type of plane + coplanar_dict[face.geometry.plane] = [face] + else: + up_vec = Vector3D(0, 0, 1) + min_ang, max_ang = (math.pi / 2) - a_tol, (math.pi / 2) + a_tol + max_h_ang = math.pi + a_tol + for face in self._faces[1:]: + v_ang = up_vec.angle(face.normal) + if v_ang < a_tol or min_ang < v_ang < max_ang or v_ang > max_h_ang: + for pln, f_list in coplanar_dict.items(): + if face.geometry.plane.is_coplanar_tolerance(pln, tol, a_tol): + f_list.append(face) + break + else: # the first face with this type of plane + coplanar_dict[face.geometry.plane] = [face] + else: + coplanar_dict[face.geometry.plane] = [face] + + # merge any of the coplanar Faces together + all_faces, new_faces = [], [] + for face_list in coplanar_dict.values(): + if len(face_list) == 1: # no faces to merge + all_faces.append(face_list[0]) + else: # there are faces to merge + f_geos = [f.geometry for f in face_list] + joined_geos = Face3D.join_coplanar_faces(f_geos, tolerance) + if len(joined_geos) < len(f_geos): # faces were merged + prop_f = face_list[0] + apertures, doors, in_shades, out_shades = [], [], [], [] + for f in face_list: + apertures.extend(f._apertures) + doors.extend(f._doors) + in_shades.extend(f._indoor_shades) + out_shades.extend(f._outdoor_shades) + for i, new_geo in enumerate(joined_geos): + fid = prop_f.identifier if i == 0 else \ + '{}_{}'.format(prop_f.identifier, i) + fbc = prop_f.boundary_condition if not \ + isinstance(prop_f.boundary_condition, Surface) \ + else boundary_conditions.outdoors + nf = Face(fid, new_geo, prop_f.type, fbc) + for ap in apertures: + if nf.geometry.is_sub_face(ap.geometry, tol, a_tol): + nf.add_aperture(ap) + for dr in doors: + if nf.geometry.is_sub_face(dr.geometry, tol, a_tol): + nf.add_door(dr) + if i == 0: # add all assigned shades to this face + nf.add_indoor_shades(in_shades) + nf.add_outdoor_shades(out_shades) + nf._parent = self + all_faces.append(nf) + new_faces.append(nf) + else: # faces don't overlap and were not merged + all_faces.extend(face_list) + if len(new_faces) == 0: + return new_faces # nothing has been merged + + # make a new polyface from the updated faces + room_polyface = Polyface3D.from_faces( + tuple(face.geometry for face in all_faces), tolerance) + if not room_polyface.is_solid: + room_polyface = room_polyface.merge_overlapping_edges(tolerance, a_tol) + # replace honeybee face geometry with versions that are facing outwards + if room_polyface.is_solid: + for i, correct_face3d in enumerate(room_polyface.faces): + face = all_faces[i] + norm_init = face._geometry.normal + face._geometry = correct_face3d + if face.has_sub_faces: # flip sub-faces to align with parent Face + if norm_init.angle(face._geometry.normal) > (math.pi / 2): + for ap in face._apertures: + ap._geometry = ap._geometry.flip() + for dr in face._doors: + dr._geometry = dr._geometry.flip() + # reset the faces and geometry of the room with the new faces + self._faces = tuple(all_faces) + self._geometry = room_polyface + return new_faces
+ +
[docs] def coplanar_split(self, geometry, tolerance=0.01, angle_tolerance=1): + """Split the Faces of this Room with coplanar geometry (Polyface3D or Face3D). + + This method attempts to preserve as many properties as possible for the + split Faces, including all extension attributes and sub-faces (as long + as they don't fall in the path of the intersection). + + Args: + geometry: A list of coplanar geometry (either Polyface3D or Face3D) + that will be used to split the Faces of this Room. Typically, these + are Polyface3D of other Room geometries to be intersected with this + one but they can also be Face3D if only one intersection is desired. + tolerance: The minimum difference between the coordinate values of two + faces at which they can be considered adjacent. Default: 0.01, + suitable for objects in meters. + angle_tolerance: The max angle in degrees that the plane normals can + differ from one another in order for them to be considered + coplanar. (Default: 1 degree). + + Returns: + A list containing only the new Faces that were created as part of the + splitting process. These new Faces will have as many properties of the + original Face assigned to them as possible but they will not have a + Surface boundary condition if the original Face had one. Having just + the new Faces here can be used in operations like setting new Surface + boundary conditions. + """ + # make a dictionary of all face geometry to be intersected + geo_dict = {f.identifier: [f.geometry] for f in self.faces} + + # loop through the polyface geometries and intersect this room's geometry + ang_tol = math.radians(angle_tolerance) + for s_geo in geometry: + if isinstance(s_geo, Polyface3D) and not \ + Polyface3D.overlapping_bounding_boxes( + self.geometry, s_geo, tolerance): + continue # no overlap in bounding box; intersection impossible + s_geos = s_geo.faces if isinstance(s_geo, Polyface3D) else [s_geo] + for face_1 in self.faces: + for face_2 in s_geos: + if not face_1.geometry.plane.is_coplanar_tolerance( + face_2.plane, tolerance, ang_tol): + continue # not coplanar; intersection impossible + if face_1.geometry.is_centered_adjacent(face_2, tolerance): + tol_area = math.sqrt(face_1.geometry.area) * tolerance + if abs(face_1.geometry.area - face_2.area) < tol_area: + continue # already intersected; no need to re-do + new_geo = [] + for f_geo in geo_dict[face_1.identifier]: + f_split, _ = Face3D.coplanar_split( + f_geo, face_2, tolerance, ang_tol) + new_geo.extend(f_split) + geo_dict[face_1.identifier] = new_geo + + # use the intersected geometry to remake this room's faces + all_faces, new_faces = [], [] + for face in self.faces: + int_faces = geo_dict[face.identifier] + if len(int_faces) == 1: # just use the old Face object + all_faces.append(face) + else: # make new Face objects + new_bc = face.boundary_condition \ + if not isinstance(face.boundary_condition, Surface) \ + else boundary_conditions.outdoors + new_aps = [ap.duplicate() for ap in face.apertures] + new_drs = [dr.duplicate() for dr in face.doors] + for x, nf_geo in enumerate(int_faces): + new_id = '{}_{}'.format(face.identifier, x) + new_face = Face(new_id, nf_geo, face.type, new_bc) + new_face._display_name = face._display_name + new_face._user_data = None if face.user_data is None \ + else face.user_data.copy() + for ap in new_aps: + if nf_geo.is_sub_face(ap.geometry, tolerance, ang_tol): + new_face.add_aperture(ap) + for dr in new_drs: + if nf_geo.is_sub_face(dr.geometry, tolerance, ang_tol): + new_face.add_door(dr) + if x == 0: + face._duplicate_child_shades(new_face) + new_face._parent = face._parent + new_face._properties._duplicate_extension_attr(face._properties) + new_faces.append(new_face) + all_faces.append(new_face) + if len(new_faces) == 0: + return new_faces # nothing has been intersected + + # make a new polyface from the updated faces + room_polyface = Polyface3D.from_faces( + tuple(face.geometry for face in all_faces), tolerance) + if not room_polyface.is_solid: + room_polyface = room_polyface.merge_overlapping_edges(tolerance, ang_tol) + # replace honeybee face geometry with versions that are facing outwards + if room_polyface.is_solid: + for i, correct_face3d in enumerate(room_polyface.faces): + face = all_faces[i] + norm_init = face._geometry.normal + face._geometry = correct_face3d + if face.has_sub_faces: # flip sub-faces to align with parent Face + if norm_init.angle(face._geometry.normal) > (math.pi / 2): + for ap in face._apertures: + ap._geometry = ap._geometry.flip() + for dr in face._doors: + dr._geometry = dr._geometry.flip() + # reset the faces and geometry of the room with the new faces + self._faces = tuple(all_faces) + self._geometry = room_polyface + return new_faces
+ +
[docs] @staticmethod + def intersect_adjacency(rooms, tolerance=0.01, angle_tolerance=1): + """Intersect the Faces of an array of Rooms to ensure matching adjacencies. + + Note that this method may remove Apertures and Doors if they align with + an intersection so it is typically recommended that this method be used + before sub-faces are assigned (if possible). Sub-faces that do not fall + along an intersection will be preserved. + + Also note that this method does not actually set the walls that are next to one + another to be adjacent. The solve_adjacency method must be used for this after + running this method. + + Args: + rooms: A list of Rooms for which adjacent Faces will be intersected. + tolerance: The minimum difference between the coordinate values of two + faces at which they can be considered adjacent. Default: 0.01, + suitable for objects in meters. + angle_tolerance: The max angle in degrees that the plane normals can + differ from one another in order for them to be considered + coplanar. (Default: 1 degree). + + Returns: + An array of Rooms that have been intersected with one another. + """ + # get all of the room polyfaces + room_geos = [r.geometry for r in rooms] + # intersect all adjacencies between rooms + for i, room in enumerate(rooms): + other_rooms = room_geos[:i] + room_geos[i + 1:] + room.coplanar_split(other_rooms, tolerance, angle_tolerance)
+ +
[docs] @staticmethod + def solve_adjacency(rooms, tolerance=0.01): + """Solve for adjacencies between a list of rooms. + + Note that this method will mutate the input rooms by setting Surface + boundary conditions for any adjacent objects. However, it does NOT overwrite + existing Surface boundary conditions and only adds new ones if faces are + found to be adjacent with equivalent areas. + + Args: + rooms: A list of rooms for which adjacencies will be solved. + tolerance: The minimum difference between the coordinate values of two + faces at which they can be considered centered adjacent. Default: 0.01, + suitable for objects in meters. + + Returns: + A dictionary of information about the objects that had their adjacency set. + The dictionary has the following keys. + + - adjacent_faces - A list of tuples with each tuple containing 2 objects + for Faces paired in the process of solving adjacency. This data can + be used to assign custom properties to the new adjacent Faces (like + making all adjacencies an AirBoundary face type or assigning custom + materials/constructions). + + - adjacent_apertures - A list of tuples with each tuple containing 2 + objects for Apertures paired in the process of solving adjacency. + + - adjacent_doors - A list of tuples with each tuple containing 2 objects + for Doors paired in the process of solving adjacency. + """ + # lists of adjacencies to track + adj_info = {'adjacent_faces': [], 'adjacent_apertures': [], + 'adjacent_doors': []} + + # solve all adjacencies between rooms + for i, room_1 in enumerate(rooms): + try: + for room_2 in rooms[i + 1:]: + if not Polyface3D.overlapping_bounding_boxes( + room_1.geometry, room_2.geometry, tolerance): + continue # no overlap in bounding box; adjacency impossible + for face_1 in room_1._faces: + for face_2 in room_2._faces: + if not isinstance(face_2.boundary_condition, Surface): + if face_1.geometry.is_centered_adjacent( + face_2.geometry, tolerance): + face_info = face_1.set_adjacency(face_2) + adj_info['adjacent_faces'].append((face_1, face_2)) + adj_info['adjacent_apertures'].extend( + face_info['adjacent_apertures']) + adj_info['adjacent_doors'].extend( + face_info['adjacent_doors']) + break + except IndexError: + pass # we have reached the end of the list of rooms + return adj_info
+ +
[docs] @staticmethod + def find_adjacency(rooms, tolerance=0.01): + """Get a list with all adjacent pairs of Faces between input rooms. + + Note that this method does not change any boundary conditions of the input + rooms or mutate them in any way. It's purely a geometric analysis of the + faces between rooms. + + Args: + rooms: A list of rooms for which adjacencies will be solved. + tolerance: The minimum difference between the coordinate values of two + faces at which they can be considered centered adjacent. Default: 0.01, + suitable for objects in meters. + + Returns: + A list of tuples with each tuple containing 2 objects for Faces that + are adjacent to one another. + """ + adj_faces = [] # lists of adjacencies to track + for i, room_1 in enumerate(rooms): + try: + for room_2 in rooms[i + 1:]: + if not Polyface3D.overlapping_bounding_boxes( + room_1.geometry, room_2.geometry, tolerance): + continue # no overlap in bounding box; adjacency impossible + for face_1 in room_1._faces: + for face_2 in room_2._faces: + if face_1.geometry.is_centered_adjacent( + face_2.geometry, tolerance): + adj_faces.append((face_1, face_2)) + break + except IndexError: + pass # we have reached the end of the list of zones + return adj_faces
+ +
[docs] @staticmethod + def group_by_adjacency(rooms): + """Group Rooms together that are connected by adjacencies. + + This is useful for separating rooms in the case where a Model contains + multiple buildings or sections that are separated by adiabatic or + outdoor boundary conditions. + + Args: + rooms: A list of rooms to be grouped by their adjacency. + + Returns: + A list of list with each sub-list containing rooms that share adjacencies. + """ + return Room._adjacency_grouping(rooms, Room._find_adjacent_rooms)
+ +
[docs] @staticmethod + def group_by_air_boundary_adjacency(rooms): + """Group Rooms together that share air boundaries. + + This is useful for understanding the radiant enclosures that will exist + when a model is exported to EnergyPlus. + + Args: + rooms: A list of rooms to be grouped by their air boundary adjacency. + + Returns: + A list of list with each sub-list containing rooms that share adjacent + air boundaries. If a Room has no air boundaries it will the the only + item within its sub-list. + """ + return Room._adjacency_grouping(rooms, Room._find_adjacent_air_boundary_rooms)
+ +
[docs] @staticmethod + def group_by_orientation(rooms, group_count=None, north_vector=Vector2D(0, 1)): + """Group Rooms with the same average outdoor wall orientation. + + Args: + rooms: A list of honeybee rooms to be grouped by orientation. + group_count: An optional positive integer to set the number of orientation + groups to use. For example, setting this to 4 will result in rooms + being grouped by four orientations (North, East, South, West). If None, + the maximum number of unique groups will be used. + north_vector: A ladybug_geometry Vector2D for the north direction. + Default is the Y-axis (0, 1). + + Returns: + A tuple with three items. + + - grouped_rooms - A list of lists of honeybee rooms with each sub-list + representing a different orientation. + + - core_rooms - A list of honeybee rooms with no identifiable orientation. + + - orientations - A list of numbers between 0 and 360 with one orientation + for each branch of the output grouped_rooms. This will be a list of + angle ranges if a value is input for group_count. + """ + # loop through each of the rooms and get the orientation + orient_dict = {} + core_rooms = [] + for room in rooms: + ori = room.average_orientation(north_vector) + if ori is None: + core_rooms.append(room) + else: + try: + orient_dict[ori].append(room) + except KeyError: + orient_dict[ori] = [] + orient_dict[ori].append(room) + + # sort the rooms by orientation values + room_mtx = sorted(orient_dict.items(), key=lambda d: float(d[0])) + orientations = [r_tup[0] for r_tup in room_mtx] + grouped_rooms = [r_tup[1] for r_tup in room_mtx] + + # group orientations if there is an input group_count + if group_count is not None: + angs = angles_from_num_orient(group_count) + p_rooms = [[] for i in range(group_count)] + for ori, rm in zip(orientations, grouped_rooms): + or_ind = orient_index(ori, angs) + p_rooms[or_ind].extend(rm) + orientations = ['{} - {}'.format(int(angs[i - 1]), int(angs[i])) + for i in range(group_count)] + grouped_rooms = p_rooms + return grouped_rooms, core_rooms, orientations
+ +
[docs] @staticmethod + def group_by_floor_height(rooms, min_difference=0.01): + """Group Rooms according to their average floor height. + + Args: + rooms: A list of honeybee rooms to be grouped by floor height. + min_difference: An float value to denote the minimum difference + in floor heights that is considered meaningful. This can be used + to ensure rooms like those representing stair landings are grouped + with those below them. Default: 0.01, which means that virtually + any minor difference in floor heights will result in a new group. + This assumption is suitable for models in meters. + + Returns: + A tuple with two items. + + - grouped_rooms - A list of lists of honeybee rooms with each sub-list + representing a different floor height. + + - floor_heights - A list of floor heights with one floor height for each + sub-list of the output grouped_rooms. + """ + # loop through each of the rooms and get the floor height + flrhgt_dict = {} + for room in rooms: + flrhgt = room.average_floor_height + try: # assume there is already a story with the room's floor height + flrhgt_dict[flrhgt].append(room) + except KeyError: # this is the first room with this floor height + flrhgt_dict[flrhgt] = [] + flrhgt_dict[flrhgt].append(room) + + # sort the rooms by floor heights + room_mtx = sorted(flrhgt_dict.items(), key=lambda d: float(d[0])) + flr_hgts = [r_tup[0] for r_tup in room_mtx] + rooms = [r_tup[1] for r_tup in room_mtx] + + # group floor heights if they differ by less than the min_difference + floor_heights = [flr_hgts[0]] + grouped_rooms = [rooms[0]] + for flrh, rm in zip(flr_hgts[1:], rooms[1:]): + if flrh - floor_heights[-1] < min_difference: + grouped_rooms[-1].extend(rm) + else: + grouped_rooms.append(rm) + floor_heights.append(flrh) + return grouped_rooms, floor_heights
+ +
[docs] @staticmethod + def stories_by_floor_height(rooms, min_difference=2.0): + """Assign story properties to a set of Rooms using their floor heights. + + Stories will be named with a standard convention ('Floor1', 'Floor2', etc.). + Note that this method will only assign stories to Rooms that do not have + a story identifier already assigned to them. + + Args: + rooms: A list of rooms for which story properties will be automatically + assigned. + min_difference: An float value to denote the minimum difference + in floor heights that is considered meaningful. This can be used + to ensure rooms like those representing stair landings are grouped + with those below them. Default: 2.0, which means that any difference + in floor heights less than 2.0 will be considered a part of the + same story. This assumption is suitable for models in meters. + + Returns: + A list of the unique story names that were assigned to the input rooms. + """ + # group the rooms by floor height + new_rooms, _ = Room.group_by_floor_height(rooms, min_difference) + + # assign the story property to each of the groups + story_names = [] + for i, room_list in enumerate(new_rooms): + story_name = 'Floor{}'.format(i + 1) + story_names.append(story_name) + for room in room_list: + if room.story is not None: + continue # preserve any existing user-assigned story values + room.story = story_name + return story_names
+ +
[docs] @staticmethod + def check_room_volume_collisions(rooms, tolerance=0.01, detailed=False): + """Check whether the volumes of Rooms collide with one another beyond tolerance. + + At the moment, this method only checks for the case where coplanar Floor + Faces of different Rooms overlap with one another, which clearly indicates + that there is definitely a collision between the Room volumes. In the + future, this method may be amended to sense more complex cases of + colliding Room volumes. For now, it is designed to only detect the most + common cases. + + Args: + rooms: A list of rooms that will be checked for volumetric collisions. + For this method to run most efficiently, these input Rooms should + be at the same horizontal floor level. The Room.group_by_floor_height() + method can be used to group the Rooms of a model according to their + height before running this method. + tolerance: The minimum difference between the coordinate values of two + vertices at which they can be considered equivalent. (Default: 0.01, + suitable for objects in meters. + detailed: Boolean for whether the returned object is a detailed list of + dicts with error info or a string with a message. (Default: False). + + Returns: + A string with the message or a list with a dictionary if detailed is True. + """ + # create Polygon2Ds from the floors of the rooms + polys = [ + [(Polygon2D(Point2D(p.x, p.y) for p in flr.vertices), flr.geometry[0].z) + for flr in room.floors if flr.geometry.is_horizontal(tolerance)] + for room in rooms + ] + + # find the number of overlaps across the Rooms + msgs = [] + for i, (room_1, polys_1) in enumerate(zip(rooms, polys)): + overlap_rooms = [] + if len(polys_1) == 0: + continue + try: + for room_2, polys_2 in zip(rooms[i + 1:], polys[i + 1:]): + collision_found = False + for ply_1, z1 in polys_1: + if collision_found: + break + for ply_2, z2 in polys_2: + if collision_found: + break + if abs(z1 - z2) < tolerance: + if Polygon2D.overlapping_bounding_rect( + ply_1, ply_2, tolerance): + if ply_1.polygon_relationship(ply_2, tolerance) >= 0: + overlap_rooms.append(room_2) + collision_found = True + break + except IndexError: + pass # we have reached the end of the list + + # of colliding rooms were found, create error messages + if len(overlap_rooms) != 0: + for room_2 in overlap_rooms: + msg = 'Room "{}" has a volume that collides with the volume ' \ + 'of Room "{}" more than the tolerance ({}).'.format( + room_1.display_name, room_2.display_name, tolerance) + msg = Room._validation_message_child( + msg, room_1, detailed, '000108', + error_type='Colliding Room Volumes') + if detailed: + msg['element_id'].append(room_2.identifier) + msg['element_name'].append(room_2.display_name) + msg['parents'].append(msg['parents'][0]) + msgs.append(msg) + # report any errors + if detailed: + return msgs + full_msg = '\n '.join(msgs) + return full_msg
+ +
[docs] @staticmethod + def grouped_horizontal_boundary( + rooms, min_separation=0, tolerance=0.01, floors_only=True): + """Get a list of Face3D for the horizontal boundary around several Rooms. + + This method will attempt to produce a boundary that follows along the + outer parts of the Floors of the Rooms so it is not suitable for groups + of Rooms that overlap one another in plan. This method may return an empty + list if the min_separation is so large that a continuous boundary could not + be determined. + + Args: + rooms: A list of Honeybee Rooms for which the horizontal boundary will + be computed. + min_separation: A number for the minimum distance between Rooms that + is considered a meaningful separation. Gaps between Rooms that + are less than this distance will be ignored and the boundary + will continue across the gap. When the input rooms represent + volumes of interior Faces, this input can be thought of as the + maximum interior wall thickness, which should be ignored in + the calculation of the overall boundary of the Rooms. When Rooms + are touching one another (with Room volumes representing center lines + of walls), this value can be set to zero or anything less than + or equal to the tolerance. Doing so will yield a cleaner result for + the boundary, which will be faster. Note that care should be taken + not to set this value higher than the length of any meaningful + exterior wall segments. Otherwise, the exterior segments + will be ignored in the result. This can be particularly dangerous + around curved exterior walls that have been planarized through + subdivision into small segments. (Default: 0). + tolerance: The maximum difference between coordinate values of two + vertices at which they can be considered equivalent. (Default: 0.01, + suitable for objects in meters). + floors_only: A boolean to note whether the grouped boundary should only + surround the Floor geometries of the Rooms (True) or if they should + surround the entirety of the Room volumes in plan (False). + """ + # get the horizontal boundary geometry of each room + floor_geos = [] + if floors_only: + for room in rooms: + floor_geos.extend(room.horizontal_floor_boundaries(tolerance=tolerance)) + else: + for room in rooms: + floor_geos.append(room.horizontal_boundary(tolerance=tolerance)) + + # remove colinear vertices and degenerate faces + clean_floor_geos = [] + for geo in floor_geos: + try: + clean_floor_geos.append(geo.remove_colinear_vertices(tolerance)) + except AssertionError: # degenerate geometry to ignore + pass + if len(clean_floor_geos) == 0: + return [] # no Room boundary to be found + + # convert the floor Face3Ds into counterclockwise Polygon2Ds + floor_polys, z_vals = [], [] + for flr_geo in clean_floor_geos: + z_vals.append(flr_geo.min.z) + b_poly = Polygon2D([Point2D(pt.x, pt.y) for pt in flr_geo.boundary]) + floor_polys.append(b_poly) + if flr_geo.has_holes: + for hole in flr_geo.holes: + h_poly = Polygon2D([Point2D(pt.x, pt.y) for pt in hole]) + floor_polys.append(h_poly) + z_min = min(z_vals) + + # if the min_separation is small, use the more reliable intersection method + if min_separation <= tolerance: + closed_polys = Polygon2D.joined_intersected_boundary(floor_polys, tolerance) + else: # otherwise, use the more intense and less reliable gap crossing method + closed_polys = Polygon2D.gap_crossing_boundary( + floor_polys, min_separation, tolerance) + + # remove colinear vertices from the resulting polygons + clean_polys = [] + for poly in closed_polys: + try: + clean_polys.append(poly.remove_colinear_vertices(tolerance)) + except AssertionError: + pass # degenerate polygon to ignore + + # figure out if polygons represent holes in the others and make Face3D + if len(clean_polys) == 0: + return [] + elif len(clean_polys) == 1: # can be represented with a single Face3D + pts3d = [Point3D(pt.x, pt.y, z_min) for pt in clean_polys[0]] + return [Face3D(pts3d)] + else: # need to separate holes from distinct Face3Ds + bound_faces = [] + for poly in clean_polys: + pts3d = tuple(Point3D(pt.x, pt.y, z_min) for pt in poly) + bound_faces.append(Face3D(pts3d)) + return Face3D.merge_faces_to_holes(bound_faces, tolerance)
+ +
[docs] @staticmethod + def rooms_from_rectangle_plan( + width, length, floor_to_floor_height, perimeter_offset=0, story_count=1, + orientation_angle=0, outdoor_roof=True, ground_floor=True, + unique_id=None, tolerance=0.01): + """Create a Rooms that represent a rectangular floor plan. + + Note that the resulting Rooms won't have any windows or solved adjacencies. + These can be added by using the Room.solve_adjacency method and the + various Face.apertures_by_XXX methods. + + Args: + width: Number for the width of the plan (in the X direction). + length: Number for the length of the plan (in the Y direction). + floor_to_floor_height: Number for the height of each floor of the model + (in the Z direction). + perimeter_offset: An optional positive number that will be used to offset + the perimeter to create core/perimeter Rooms. If this value is 0, + no offset will occur and each floor will have one Room. (Default: 0). + story_count: An integer for the number of stories to generate. (Default: 1). + orientation_angle: A number between 0 and 360 for the counterclockwise + orientation that the width of the box faces. (0=North, 90=East, + 180=South, 270=West). (Default: 0). + outdoor_roof: Boolean to note whether the roof faces of the top floor + should be outdoor or adiabatic. (Default: True). + ground_floor: Boolean to note whether the floor faces of the bottom + floor should be ground or adiabatic. (Default: True). + unique_id: Text for a unique identifier to be incorporated into all + of the Room identifiers. If None, a default one will be generated. + tolerance: The maximum difference between x, y, and z values at which + vertices are considered equivalent. (Default: 0.01, suitable + for objects in meters). + """ + footprint = [Face3D.from_rectangle(width, length)] + if perimeter_offset != 0: # use the straight skeleton methods + assert perimeter_offset > 0, 'perimeter_offset cannot be less than than 0.' + try: + footprint = [] + base = Polygon2D.from_rectangle(Point2D(), Vector2D(0, 1), width, length) + sub_polys_perim, sub_polys_core = perimeter_core_subpolygons( + polygon=base, distance=perimeter_offset, tol=tolerance) + for s_poly in sub_polys_perim + sub_polys_core: + sub_face = Face3D([Point3D(pt.x, pt.y, 0) for pt in s_poly]) + footprint.append(sub_face) + except RuntimeError: + pass + # create the honeybee rooms + if unique_id is None: + unique_id = str(uuid.uuid4())[:8] # unique identifier for the rooms + rm_ids = ['Room'] if len(footprint) == 1 else ['Front', 'Right', 'Back', 'Left'] + if len(footprint) == 5: + rm_ids.append('Core') + return Room.rooms_from_footprint( + footprint, floor_to_floor_height, rm_ids, unique_id, orientation_angle, + story_count, outdoor_roof, ground_floor)
+ +
[docs] @staticmethod + def rooms_from_l_shaped_plan( + width_1, length_1, width_2, length_2, floor_to_floor_height, + perimeter_offset=0, story_count=1, orientation_angle=0, + outdoor_roof=True, ground_floor=True, unique_id=None, tolerance=0.01): + """Create a Rooms that represent an L-shaped floor plan. + + Note that the resulting Rooms in the model won't have any windows or solved + adjacencies. These can be added by using the Room.solve_adjacency method + and the various Face.apertures_by_XXX methods. + + Args: + width_1: Number for the width of the lower part of the L segment. + length_1: Number for the length of the lower part of the L segment, not + counting the overlap between the upper and lower segments. + width_2: Number for the width of the upper (left) part of the L segment. + length_2: Number for the length of the upper (left) part of the L segment, + not counting the overlap between the upper and lower segments. + floor_to_floor_height: Number for the height of each floor of the model + (in the Z direction). + perimeter_offset: An optional positive number that will be used to offset + the perimeter to create core/perimeter Rooms. If this value is 0, + no offset will occur and each floor will have one Room. (Default: 0). + story_count: An integer for the number of stories to generate. (Default: 1). + orientation_angle: A number between 0 and 360 for the counterclockwise + orientation that the width of the box faces. (0=North, 90=East, + 180=South, 270=West). (Default: 0). + outdoor_roof: Boolean to note whether the roof faces of the top floor + should be outdoor or adiabatic. (Default: True). + ground_floor: Boolean to note whether the floor faces of the bottom + floor should be ground or adiabatic. (Default: True). + unique_id: Text for a unique identifier to be incorporated into all + of the Room identifiers. If None, a default one will be generated. + tolerance: The maximum difference between x, y, and z values at which + vertices are considered equivalent. (Default: 0.01, suitable + for objects in meters). + """ + # create the geometry of the rooms for the first floor + max_x, max_y = width_2 + length_1, width_1 + length_2 + pts = [(0, 0), (max_x, 0), (max_x, width_1), (width_2, width_1), + (width_2, max_y), (0, max_y)] + footprint = Face3D(tuple(Point3D(*pt) for pt in pts)) + if perimeter_offset != 0: # use the straight skeleton methods + assert perimeter_offset > 0, 'perimeter_offset cannot be less than than 0.' + try: + footprint = [] + base = Polygon2D(tuple(Point2D(*pt) for pt in pts)) + sub_polys_perim, sub_polys_core = perimeter_core_subpolygons( + polygon=base, distance=perimeter_offset, tol=tolerance) + for s_poly in sub_polys_perim + sub_polys_core: + sub_face = Face3D([Point3D(pt.x, pt.y, 0) for pt in s_poly]) + footprint.append(sub_face) + except RuntimeError: + pass + # create the honeybee rooms + unique_id = '' if unique_id is None else '_{}'.format(unique_id) + rm_ids = ['Room'] if len(footprint) == 1 else \ + ['LongEdge1', 'End1', 'ShortEdge1', 'ShortEdge2', 'End2', 'LongEdge2'] + if len(footprint) == 7: + rm_ids.append('Core') + return Room.rooms_from_footprint( + footprint, floor_to_floor_height, rm_ids, unique_id, orientation_angle, + story_count, outdoor_roof, ground_floor)
+ +
[docs] @staticmethod + def rooms_from_footprint( + footprints, floor_to_floor_height, room_ids=None, unique_id=None, + orientation_angle=0, story_count=1, outdoor_roof=True, ground_floor=True): + """Create several Honeybee Rooms from footprint Face3Ds. + + Args: + footprints: A list of Face3Ds representing the floors of Rooms. + floor_to_floor_height: Number for the height of each floor of the model + (in the Z direction). + room_ids: A list of strings for the identifiers of the Rooms to be generated. + If None, default unique IDs will be generated. (Default: None) + unique_id: Text for a unique identifier to be incorporated into all + Room identifiers. (Default: None). + orientation_angle: A number between 0 and 360 for the counterclockwise + orientation that the width of the box faces. (0=North, 90=East, + 180=South, 270=West). (Default: 0). + story_count: An integer for the number of stories to generate. (Default: 1). + outdoor_roof: Boolean to note whether the roof faces of the top floor + should be outdoor or adiabatic. (Default: True). + ground_floor: Boolean to note whether the floor faces of the bottom + floor should be ground or adiabatic. (Default: True). + """ + # set default identifiers if not provided + if room_ids is None: + room_ids = ['Room_{}'.format(str(uuid.uuid4())[:8]) for _ in footprints] + # extrude the footprint into solids + first_floor = [Polyface3D.from_offset_face(geo, floor_to_floor_height) + for geo in footprints] + # rotate the geometries if an orientation angle is specified + if orientation_angle != 0: + angle, origin = math.radians(orientation_angle), Point3D() + first_floor = [geo.rotate_xy(angle, origin) for geo in first_floor] + # create the initial rooms for the first floor + rooms = [] + unique_id = '' if unique_id is None else '_{}'.format(unique_id) + for polyface, rmid in zip(first_floor, room_ids): + rooms.append(Room.from_polyface3d('{}{}'.format(rmid, unique_id), polyface)) + # if there are multiple stories, duplicate the first floor rooms + if story_count != 1: + all_rooms = [] + for i in range(story_count): + for room in rooms: + new_room = room.duplicate() + new_room.add_prefix('Floor{}'.format(i + 1)) + m_vec = Vector3D(0, 0, floor_to_floor_height * i) + new_room.move(m_vec) + all_rooms.append(new_room) + rooms = all_rooms + # assign readable names for the display_name (without the UUID) + for room in rooms: + room.display_name = room.identifier[:-9] + # assign adiabatic boundary conditions if requested + if not outdoor_roof and ad_bc: + for room in rooms[-len(first_floor):]: + room[-1].boundary_condition = ad_bc # make the roof adiabatic + if not ground_floor and ad_bc: + for room in rooms[:len(first_floor)]: + room[0].boundary_condition = ad_bc # make the floor adiabatic + return rooms
+ +
[docs] def display_dict(self): + """Get a list of DisplayFace3D dictionaries for visualizing the object.""" + base = [] + for f in self._faces: + base.extend(f.display_dict()) + for shd in self.shades: + base.extend(shd.display_dict()) + return base
+ + @property + def to(self): + """Room writer object. + + Use this method to access Writer class to write the room in other formats. + + Usage: + + .. code-block:: python + + room.to.idf(room) -> idf string. + room.to.radiance(room) -> Radiance string. + """ + return writer + +
[docs] def to_dict(self, abridged=False, included_prop=None, include_plane=True): + """Return Room as a dictionary. + + Args: + abridged: Boolean to note whether the extension properties of the + object (ie. construction sets) should be included in detail + (False) or just referenced by identifier (True). Default: False. + included_prop: List of properties to filter keys that must be included in + output dictionary. For example ['energy'] will include 'energy' key if + available in properties to_dict. By default all the keys will be + included. To exclude all the keys from extensions use an empty list. + include_plane: Boolean to note wether the planes of the Face3Ds should be + included in the output. This can preserve the orientation of the + X/Y axes of the planes but is not required and can be removed to + keep the dictionary smaller. (Default: True). + """ + base = {'type': 'Room'} + base['identifier'] = self.identifier + base['display_name'] = self.display_name + base['properties'] = self.properties.to_dict(abridged, included_prop) + base['faces'] = [f.to_dict(abridged, included_prop, include_plane) + for f in self._faces] + self._add_shades_to_dict(base, abridged, included_prop, include_plane) + if self.multiplier != 1: + base['multiplier'] = self.multiplier + if self.story is not None: + base['story'] = self.story + if self.exclude_floor_area: + base['exclude_floor_area'] = self.exclude_floor_area + if self.user_data is not None: + base['user_data'] = self.user_data + return base
+ + def _base_horiz_boundary(self, tolerance=0.01): + """Get a starting horizontal boundary for the Room. + + This is the raw result obtained by merging all downward-facing Faces of the Room. + + Args: + tolerance: The minimum difference between x, y, and z coordinate values + at which points are considered distinct. (Default: 0.01, + suitable for objects in Meters). + """ + z_axis = Vector3D(0, 0, 1) + flr_geo = [] + for face in self.faces: + if math.degrees(z_axis.angle(face.normal)) >= 91: + flr_geo.append(face.geometry) + if len(flr_geo) == 1: + if flr_geo[0].is_horizontal(tolerance): + return flr_geo[0] + else: + floor_height = self.geometry.min.z + bound = [Point3D(p.x, p.y, floor_height) for p in flr_geo[0].boundary] + holes = None + if flr_geo[0].has_holes: + holes = [[Point3D(p.x, p.y, floor_height) for p in hole] + for hole in flr_geo[0].holes] + return Face3D(bound, holes=holes) + else: # multiple geometries to be joined together + floor_height = self.geometry.min.z + horiz_geo = [] + for fg in flr_geo: + if fg.is_horizontal(tolerance) and \ + abs(floor_height - fg.min.z) <= tolerance: + horiz_geo.append(fg) + else: # project the face geometry into the XY plane + bound = [Point3D(p.x, p.y, floor_height) for p in fg.boundary] + holes = None + if fg.has_holes: + holes = [[Point3D(p.x, p.y, floor_height) for p in hole] + for hole in fg.holes] + horiz_geo.append(Face3D(bound, holes=holes)) + # sense if there are overlapping geometries to be boolean unioned + overlap_groups = Face3D.group_by_coplanar_overlap(horiz_geo, tolerance) + if all(len(g) == 1 for g in overlap_groups): # no overlaps; just join + return Face3D.join_coplanar_faces(horiz_geo, tolerance)[0] + # we must do a boolean union + clean_geo = [] + for og in overlap_groups: + if len(og) == 1: + clean_geo.extend(og) + else: + it_count, max_iter = 0, len(og) * 2 + while len(og) > 1: + a_tol = math.radians(1) + union = Face3D.coplanar_union(og[0], og[1], tolerance, a_tol) + if union is None: + og.append(og.pop(1)) + else: + og.pop(0) + og[0] = union + it_count += 1 + if it_count > max_iter: + break + if len(og) == 1: + clean_geo.extend(og) + else: + sort_geo = sorted(clean_geo, key=lambda x: x.area, reverse=True) + clean_geo.append(sort_geo[0]) + if len(clean_geo) == 1: + return clean_geo[0] + return Face3D.join_coplanar_faces(clean_geo, tolerance)[0] + + def _match_walls_to_horizontal_faces(self, faces, tolerance): + """Insert vertices to horizontal faces so they align with the Room's Walls. + + Args: + faces: A list of Face3D into which the vertices of the walls will + be inserted. + tolerance: The minimum difference between x, y, and z coordinate values + at which points are considered distinct. (Default: 0.01, + suitable for objects in Meters). + """ + # get 2D vertices for all of the walls + wall_st_pts = [ + f.geometry.lower_left_counter_clockwise_vertices[0] for f in self.walls] + wall_st_pts_2d = [Point2D(v[0], v[1]) for v in wall_st_pts] + # insert the wall points into each of the faces + wall_faces = [] + for horiz_bound in faces: + # get 2D polygons for the horizontal boundary + z_val = horiz_bound[0].z + polys = [Polygon2D([Point2D(v.x, v.y) for v in horiz_bound.boundary])] + if horiz_bound.holes is not None: + for hole in horiz_bound.holes: + polys.append(Polygon2D([Point2D(v.x, v.y) for v in hole])) + # insert the wall vertices into the polygon + wall_polys = [] + for st_poly in polys: + st_poly = st_poly.remove_colinear_vertices(tolerance) + polygon_update = [] + for pt in wall_st_pts_2d: + for v in st_poly.vertices: # check if pt is already included + if pt.is_equivalent(v, tolerance): + break + else: + values = [seg.distance_to_point(pt) for seg in st_poly.segments] + if min(values) < tolerance: + index_min = min(range(len(values)), key=values.__getitem__) + polygon_update.append((index_min, pt)) + if polygon_update: + end_poly = Polygon2D._insert_updates_in_order(st_poly, polygon_update) + wall_polys.append(end_poly) + else: + wall_polys.append(st_poly) + # rebuild the Face3D from the polygons + pts_3d = [[Point3D(p.x, p.y, z_val) for p in poly] for poly in wall_polys] + wall_faces.append(Face3D(pts_3d[0], holes=pts_3d[1:])) + return wall_faces + + @staticmethod + def _adjacency_grouping(rooms, adj_finding_function): + """Group Rooms together according to an adjacency finding function. + + Args: + rooms: A list of rooms to be grouped by their adjacency. + adj_finding_function: A function that denotes which rooms are adjacent + to another. + + Returns: + A list of list with each sub-list containing rooms that share adjacencies. + """ + # create a room lookup table and duplicate the list of rooms + room_lookup = {rm.identifier: rm for rm in rooms} + all_rooms = list(rooms) + adj_network = [] + + # loop through the rooms and find air boundary adjacencies + for room in all_rooms: + adj_ids = adj_finding_function(room) + if len(adj_ids) == 0: # a room that is its own solar enclosure + adj_network.append([room]) + else: # there are other adjacent rooms to find + local_network = [room] + local_ids, first_id = set(adj_ids), room.identifier + while len(adj_ids) != 0: + # add the current rooms to the local network + adj_objs = [room_lookup[rm_id] for rm_id in adj_ids] + local_network.extend(adj_objs) + adj_ids = [] # reset the list of new adjacencies + # find any rooms that are adjacent to the adjacent rooms + for obj in adj_objs: + all_new_ids = adj_finding_function(obj) + new_ids = [rid for rid in all_new_ids + if rid not in local_ids and rid != first_id] + for rm_id in new_ids: + local_ids.add(rm_id) + adj_ids.extend(new_ids) + # after the local network is understood, clean up duplicated rooms + adj_network.append(local_network) + i_to_remove = [i for i, room_obj in enumerate(all_rooms) + if room_obj.identifier in local_ids] + for i in reversed(i_to_remove): + all_rooms.pop(i) + return adj_network + + @staticmethod + def _find_adjacent_rooms(room): + """Find the identifiers of all rooms with adjacency to a room.""" + adj_rooms = [] + for face in room._faces: + if isinstance(face.boundary_condition, Surface): + adj_rooms.append(face.boundary_condition.boundary_condition_objects[-1]) + return adj_rooms + + @staticmethod + def _find_adjacent_air_boundary_rooms(room): + """Find the identifiers of all rooms with air boundary adjacency to a room.""" + adj_rooms = [] + for face in room._faces: + if isinstance(face.type, AirBoundary) and \ + isinstance(face.boundary_condition, Surface): + adj_rooms.append(face.boundary_condition.boundary_condition_objects[-1]) + return adj_rooms + + def __copy__(self): + new_r = Room(self.identifier, tuple(face.duplicate() for face in self._faces)) + new_r._display_name = self._display_name + new_r._user_data = None if self.user_data is None else self.user_data.copy() + new_r._multiplier = self.multiplier + new_r._story = self.story + new_r._exclude_floor_area = self.exclude_floor_area + self._duplicate_child_shades(new_r) + new_r._geometry = self._geometry + new_r._properties._duplicate_extension_attr(self._properties) + return new_r + + def __len__(self): + return len(self._faces) + + def __getitem__(self, key): + return self._faces[key] + + def __iter__(self): + return iter(self._faces) + + def __repr__(self): + return 'Room: %s' % self.display_name
+
+ +
+ +
+
+
+
+

+ Back to top + +

+

+ © Copyright 2023, Ladybug Tools.
+ Created using Sphinx 5.3.0.
+

+
+
+ + \ No newline at end of file diff --git a/docs/_modules/honeybee/search.html b/docs/_modules/honeybee/search.html new file mode 100644 index 00000000..1d0b29a9 --- /dev/null +++ b/docs/_modules/honeybee/search.html @@ -0,0 +1,1211 @@ + + + + + + + honeybee.search — honeybee documentation + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+ +

Source code for honeybee.search

+"""Collection of methods for searching for keywords and filtering lists by keywords.
+This module also included methods to get nested attributes of objects.
+
+This is useful for cases like the following:
+
+* Searching through the honeybee-radiance modifier library.
+* Searching through the honeybee-energy material, construction, schedule,
+  constructionset, or programtype libraries.
+* Searching through EnergyPlus IDD or RDD to find possible output variables
+  to request form the simulation.
+"""
+
+
+
[docs]def filter_array_by_keywords(array, keywords, parse_phrases=True): + """Filter an array of strings to get only those containing the given keywords. + + This method is case insensitive, allowing the searching of keywords across + different cases of letters. + + Args: + array: An array of strings which will be filtered to get only those containing + the given keywords. + keywords: An array of strings representing keywords. + parse_phrases: If True, this method will automatically parse any strings of + multiple keywords (separated by spaces) into separate keywords for + searching. This results in a greater likelihood that someone finds what + they are searching for in large arrays but it may not be appropriate for + all cases. You may want to set it to False when you are searching for a + specific phrase that includes spaces. Default: True. + """ + # split any keywords separated by spaces + if parse_phrases: + keywords = [kw for words in keywords for kw in words.upper().split()] + else: + keywords = [kw.upper() for kw in keywords] + + # filter the input array + return [item for item in array if any_keywords_in_string(item.upper(), keywords)]
+ + +
[docs]def any_keywords_in_string(name, keywords): + """Check whether any keywords in an array exist within a given string. + + Args: + name: A string which will be tested for whether it possesses any of the keywords. + keywords: An array of strings representing keywords, which will be searched for + in the name. + """ + return all(kw in name for kw in keywords)
+ + +
[docs]def get_attr_nested(obj_instance, attr_name, decimal_count=None, cast_to_str=True): + """Get the attribute of an object while allowing the request of nested attributes. + + Args: + obj_instance: An instance of a Python object. Typically, this is a honeybee + object like a Model, Room, Face, Aperture, Door, or Shade. + attr_name: A string of an attribute that the input obj_instance should have. + This can have '.' that separate the nested attributes from one another. + For example, 'properties.energy.construction'. + decimal_count: An optional integer to be used to round the property to a + number of decimal places if it is a float. (Default: None). + cast_to_str: Boolean to note whether attributes with a type other than + float should be cast to strings. If False, the attribute will be + returned with the original object type. (Default: True). + + Returns: + A string or number for tha attribute assigned ot the obj_instance. If the + input attr_name is a valid attribute for the object but None is assigned, + the output will be 'None'. If the input attr_name is not valid for + the input object, 'N/A' will be returned. + """ + if '.' in attr_name: # nested attribute + attributes = attr_name.split('.') # get all the sub-attributes + current_obj = obj_instance + try: + for attribute in attributes: + if current_obj is None: + raise AttributeError + elif isinstance(current_obj, dict): + current_obj = current_obj.get(attribute, None) + else: + current_obj = getattr(current_obj, attribute) + if isinstance(current_obj, float) and decimal_count: + return round(current_obj, decimal_count) + else: + return str(current_obj) if cast_to_str else current_obj + except AttributeError as e: + if 'NoneType' in str(e): # it's a valid attribute but it's not assigned + return 'None' + else: # it's not a valid attribute + return 'N/A' + else: # honeybee-core attribute + try: + current_obj = getattr(obj_instance, attr_name) + if isinstance(current_obj, float) and decimal_count: + return round(current_obj, decimal_count) + else: + return str(current_obj) if cast_to_str else current_obj + except AttributeError: + return 'N/A'
+
+ +
+ +
+
+
+
+

+ Back to top + +

+

+ © Copyright 2023, Ladybug Tools.
+ Created using Sphinx 5.3.0.
+

+
+
+ + \ No newline at end of file diff --git a/docs/_modules/honeybee/shade.html b/docs/_modules/honeybee/shade.html new file mode 100644 index 00000000..47d3bcdc --- /dev/null +++ b/docs/_modules/honeybee/shade.html @@ -0,0 +1,1590 @@ + + + + + + + honeybee.shade — honeybee documentation + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+ +

Source code for honeybee.shade

+# coding: utf-8
+"""Honeybee Shade."""
+from __future__ import division
+import math
+
+from ladybug_geometry.geometry3d.pointvector import Point3D
+from ladybug_geometry.geometry3d.face import Face3D
+from ladybug.color import Color
+
+from ._base import _Base
+from .typing import clean_string
+from .properties import ShadeProperties
+import honeybee.writer.shade as writer
+
+
+
[docs]class Shade(_Base): + """A single planar shade. + + Args: + identifier: Text string for a unique Shade ID. Must be < 100 characters and + not contain any spaces or special characters. + geometry: A ladybug-geometry Face3D. + is_detached: Boolean to note whether this object is detached from other + geometry. Cases where this should be True include shade representing + surrounding buildings or context. (Default: False). + + Properties: + * identifier + * display_name + * is_detached + * parent + * top_level_parent + * has_parent + * is_indoor + * geometry + * vertices + * upper_left_vertices + * normal + * center + * area + * perimeter + * min + * max + * altitude + * azimuth + * type_color + * bc_color + * user_data + """ + __slots__ = ('_geometry', '_parent', '_is_indoor', '_is_detached') + TYPE_COLORS = { + (False, False): Color(120, 75, 190), + (False, True): Color(80, 50, 128), + (True, False): Color(159, 99, 255), + (True, True): Color(159, 99, 255) + } + BC_COLOR = Color(120, 75, 190) + + def __init__(self, identifier, geometry, is_detached=False): + """A single planar shade.""" + _Base.__init__(self, identifier) # process the identifier + + # process the geometry and basic properties + assert isinstance(geometry, Face3D), \ + 'Expected ladybug_geometry Face3D. Got {}'.format(type(geometry)) + self._geometry = geometry + self._parent = None # _parent will be set when the Shade is added to an object + self._is_indoor = False # this will be set by the _parent + self.is_detached = is_detached + + # initialize properties for extensions + self._properties = ShadeProperties(self) + +
[docs] @classmethod + def from_dict(cls, data): + """Initialize an Shade from a dictionary. + + Args: + data: A dictionary representation of an Shade object. + """ + try: + # check the type of dictionary + assert data['type'] == 'Shade', 'Expected Shade dictionary. ' \ + 'Got {}.'.format(data['type']) + + is_detached = data['is_detached'] if 'is_detached' in data else False + shade = cls( + data['identifier'], Face3D.from_dict(data['geometry']), is_detached) + if 'display_name' in data and data['display_name'] is not None: + shade.display_name = data['display_name'] + if 'user_data' in data and data['user_data'] is not None: + shade.user_data = data['user_data'] + + if data['properties']['type'] == 'ShadeProperties': + shade.properties._load_extension_attr_from_dict(data['properties']) + return shade + except Exception as e: + cls._from_dict_error_message(data, e)
+ +
[docs] @classmethod + def from_vertices(cls, identifier, vertices, is_detached=False): + """Create a Shade from vertices with each vertex as an iterable of 3 floats. + + Note that this method is not recommended for a shade with one or more holes + since the distinction between hole vertices and boundary vertices cannot + be derived from a single list of vertices. + + Args: + identifier: Text string for a unique Shade ID. Must be < 100 characters and + not contain any spaces or special characters. + vertices: A flattened list of 3 or more vertices as (x, y, z). + is_detached: Boolean to note whether this object is detached from other + geometry. Cases where this should be True include shade representing + surrounding buildings or context. (Default: False). + """ + geometry = Face3D(tuple(Point3D(*v) for v in vertices)) + return cls(identifier, geometry, is_detached)
+ + @property + def is_detached(self): + """Get or set a boolean for whether this object is detached from other geometry. + + This will automatically be set to False if the shade is assigned to + parent objects. + """ + return self._is_detached + + @is_detached.setter + def is_detached(self, value): + try: + self._is_detached = bool(value) + if self._is_detached: + assert not self.has_parent, 'Shade cannot be detached when it has ' \ + 'a parent Room, Face, Aperture or Door.' + except TypeError: + raise TypeError( + 'Expected boolean for Shade.is_detached. Got {}.'.format(value)) + + @property + def parent(self): + """Get the parent object if assigned. None if not assigned. + + The parent object can be either a Room, Face, Aperture or Door. + """ + return self._parent + + @property + def top_level_parent(self): + """Get the top-level parent object if assigned. + + This will be the highest-level parent in the hierarchy of the parent-child + chain. Will be None if no parent is assigned. + """ + if self.has_parent: + if self._parent.has_parent: + if self._parent._parent.has_parent: + return self._parent._parent._parent + return self._parent._parent + return self._parent + return None + + @property + def has_parent(self): + """Get a boolean noting whether this Shade has a parent object.""" + return self._parent is not None + + @property + def is_indoor(self): + """Get a boolean for whether this Shade is on the indoors of its parent object. + + Note that, if there is no parent assigned to this Shade, this property will + be False. + """ + return self._is_indoor + + @property + def geometry(self): + """Get a ladybug_geometry Face3D object representing the Shade.""" + return self._geometry + + @property + def vertices(self): + """Get a list of vertices for the shade (in counter-clockwise order).""" + return self._geometry.vertices + + @property + def upper_left_vertices(self): + """Get a list of vertices starting from the upper-left corner. + + This property should be used when exporting to EnergyPlus / OpenStudio. + """ + return self._geometry.upper_left_counter_clockwise_vertices + + @property + def normal(self): + """Get a ladybug_geometry Vector3D for the direction the shade is pointing. + """ + return self._geometry.normal + + @property + def center(self): + """Get a ladybug_geometry Point3D for the center of the shade. + + Note that this is the center of the bounding rectangle around this geometry + and not the area centroid. + """ + return self._geometry.center + + @property + def area(self): + """Get the area of the shade.""" + return self._geometry.area + + @property + def perimeter(self): + """Get the perimeter of the shade.""" + return self._geometry.perimeter + + @property + def min(self): + """Get a Point3D for the minimum of the bounding box around the object.""" + return self._geometry.min + + @property + def max(self): + """Get a Point3D for the maximum of the bounding box around the object.""" + return self._geometry.max + + @property + def altitude(self): + """Get the altitude of the geometry between +90 (up) and -90 (down).""" + return math.degrees(self._geometry.altitude) + + @property + def azimuth(self): + """Get the azimuth of the geometry, between 0 and 360. + + Given Y-axis as North, 0 = North, 90 = East, 180 = South, 270 = West + This will be zero if the Face3D is perfectly horizontal. + """ + return math.degrees(self._geometry.azimuth) + + @property + def type_color(self): + """Get a Color to be used in visualizations by type.""" + return self.TYPE_COLORS[(self.is_indoor, self.is_detached)] + + @property + def bc_color(self): + """Get a Color to be used in visualizations by boundary condition.""" + return self.BC_COLOR + +
[docs] def add_prefix(self, prefix): + """Change the identifier of this object by inserting a prefix. + + This is particularly useful in workflows where you duplicate and edit + a starting object and then want to combine it with the original object + into one Model (like making a model of repeated rooms) since all objects + within a Model must have unique identifiers. + + Args: + prefix: Text that will be inserted at the start of this object's identifier + and display_name. It is recommended that this prefix be short to + avoid maxing out the 100 allowable characters for honeybee identifiers. + """ + self._identifier = clean_string('{}_{}'.format(prefix, self.identifier)) + self.display_name = '{}_{}'.format(prefix, self.display_name) + self.properties.add_prefix(prefix)
+ +
[docs] def move(self, moving_vec): + """Move this Shade along a vector. + + Args: + moving_vec: A ladybug_geometry Vector3D with the direction and distance + to move the face. + """ + self._geometry = self.geometry.move(moving_vec) + self.properties.move(moving_vec)
+ +
[docs] def rotate(self, axis, angle, origin): + """Rotate this Shade by a certain angle around an axis and origin. + + Args: + axis: A ladybug_geometry Vector3D axis representing the axis of rotation. + angle: An angle for rotation in degrees. + origin: A ladybug_geometry Point3D for the origin around which the + object will be rotated. + """ + self._geometry = self.geometry.rotate(axis, math.radians(angle), origin) + self.properties.rotate(axis, angle, origin)
+ +
[docs] def rotate_xy(self, angle, origin): + """Rotate this Shade counterclockwise in the world XY plane by a certain angle. + + Args: + angle: An angle in degrees. + origin: A ladybug_geometry Point3D for the origin around which the + object will be rotated. + """ + self._geometry = self.geometry.rotate_xy(math.radians(angle), origin) + self.properties.rotate_xy(angle, origin)
+ +
[docs] def reflect(self, plane): + """Reflect this Shade across a plane. + + Args: + plane: A ladybug_geometry Plane across which the object will + be reflected. + """ + self._geometry = self.geometry.reflect(plane.n, plane.o) + self.properties.reflect(plane)
+ +
[docs] def scale(self, factor, origin=None): + """Scale this Shade by a factor from an origin point. + + Args: + factor: A number representing how much the object should be scaled. + origin: A ladybug_geometry Point3D representing the origin from which + to scale. If None, it will be scaled from the World origin (0, 0, 0). + """ + self._geometry = self.geometry.scale(factor, origin) + self.properties.scale(factor, origin)
+ +
[docs] def remove_colinear_vertices(self, tolerance=0.01): + """Remove all colinear and duplicate vertices from this object's geometry. + + Args: + tolerance: The minimum distance between a vertex and the boundary segments + at which point the vertex is considered colinear. Default: 0.01, + suitable for objects in meters. + """ + try: + self._geometry = self.geometry.remove_colinear_vertices(tolerance) + except AssertionError as e: # usually a sliver face of some kind + raise ValueError( + 'Shade "{}" is invalid with dimensions less than the ' + 'tolerance.\n{}'.format(self.full_id, e))
+ +
[docs] def is_geo_equivalent(self, shade, tolerance=0.01): + """Get a boolean for whether this object is geometrically equivalent to another. + + The total number of vertices and the ordering of these vertices can be + different but the geometries must share the same center point and be + next to one another to within the tolerance. + + Args: + shade: Another Shade for which geometric equivalency will be tested. + tolerance: The minimum difference between the coordinate values of two + vertices at which they can be considered geometrically equivalent. + + Returns: + True if geometrically equivalent. False if not geometrically equivalent. + """ + meta_1 = (self.display_name, self.is_detached) + meta_2 = (shade.display_name, shade.is_detached) + if meta_1 != meta_2: + return False + if abs(self.area - shade.area) > tolerance * self.area: + return False + return self.geometry.is_centered_adjacent(shade.geometry, tolerance)
+ +
[docs] def check_planar(self, tolerance=0.01, raise_exception=True, detailed=False): + """Check whether all of the Shade's vertices lie within the same plane. + + Args: + tolerance: The minimum distance between a given vertex and a the + object's plane at which the vertex is said to lie in the plane. + Default: 0.01, suitable for objects in meters. + raise_exception: Boolean to note whether an ValueError should be + raised if a vertex does not lie within the object's plane. + detailed: Boolean for whether the returned object is a detailed list of + dicts with error info or a string with a message. (Default: False). + + Returns: + A string with the message or a list with a dictionary if detailed is True. + """ + try: + self.geometry.check_planar(tolerance, raise_exception=True) + except ValueError as e: + msg = 'Shade "{}" is not planar.\n{}'.format(self.full_id, e) + full_msg = self._validation_message( + msg, raise_exception, detailed, '000101', + error_type='Non-Planar Geometry') + if detailed: # add the out-of-plane points to helper_geometry + help_pts = [ + p.to_dict() for p in self.geometry.non_planar_vertices(tolerance) + ] + full_msg[0]['helper_geometry'] = help_pts + return full_msg + return [] if detailed else ''
+ +
[docs] def check_self_intersecting(self, tolerance=0.01, raise_exception=True, + detailed=False): + """Check whether the edges of the Shade intersect one another (like a bowtie). + + Args: + tolerance: The minimum difference between the coordinate values of two + vertices at which they can be considered equivalent. Default: 0.01, + suitable for objects in meters. + raise_exception: If True, a ValueError will be raised if the object + intersects with itself. Default: True. + detailed: Boolean for whether the returned object is a detailed list of + dicts with error info or a string with a message. (Default: False). + + Returns: + A string with the message or a list with a dictionary if detailed is True. + """ + if self.geometry.is_self_intersecting: + msg = 'Shade "{}" has self-intersecting edges.'.format(self.full_id) + try: # see if it is self-intersecting because of a duplicate vertex + new_geo = self.geometry.remove_duplicate_vertices(tolerance) + if not new_geo.is_self_intersecting: + return [] if detailed else '' # valid with removed dup vertex + except AssertionError: + return [] if detailed else '' # degenerate geometry + full_msg = self._validation_message( + msg, raise_exception, detailed, '000102', + error_type='Self-Intersecting Geometry') + if detailed: # add the self-intersection points to helper_geometry + help_pts = [p.to_dict() for p in self.geometry.self_intersection_points] + full_msg[0]['helper_geometry'] = help_pts + return full_msg + return [] if detailed else ''
+ +
[docs] def display_dict(self): + """Get a list of DisplayFace3D dictionaries for visualizing the object.""" + return [self._display_face(self.geometry, self.type_color)]
+ + @property + def to(self): + """Shade writer object. + + Use this method to access Writer class to write the shade in different formats. + + Usage: + + .. code-block:: python + + shade.to.idf(shade) -> idf string. + shade.to.radiance(shade) -> Radiance string. + """ + return writer + +
[docs] def to_dict(self, abridged=False, included_prop=None, include_plane=True): + """Return Shade as a dictionary. + + Args: + abridged: Boolean to note whether the extension properties of the + object (ie. modifiers, transmittance schedule) should be included in + detail (False) or just referenced by identifier (True). Default: False. + included_prop: List of properties to filter keys that must be included in + output dictionary. For example ['energy'] will include 'energy' key if + available in properties to_dict. By default all the keys will be + included. To exclude all the keys from extensions use an empty list. + include_plane: Boolean to note wether the plane of the Face3D should be + included in the output. This can preserve the orientation of the + X/Y axes of the plane but is not required and can be removed to + keep the dictionary smaller. (Default: True). + """ + base = {'type': 'Shade'} + base['identifier'] = self.identifier + base['display_name'] = self.display_name + base['properties'] = self.properties.to_dict(abridged, included_prop) + enforce_upper_left = True if 'energy' in base['properties'] else False + base['geometry'] = self._geometry.to_dict(include_plane, enforce_upper_left) + if self.is_detached: + base['is_detached'] = self.is_detached + if self.user_data is not None: + base['user_data'] = self.user_data + return base
+ + def __copy__(self): + new_shade = Shade(self.identifier, self.geometry, self.is_detached) + new_shade._display_name = self._display_name + new_shade._user_data = None if self.user_data is None else self.user_data.copy() + new_shade._properties._duplicate_extension_attr(self._properties) + return new_shade + + def __repr__(self): + return 'Shade: %s' % self.display_name
+
+ +
+ +
+
+
+
+

+ Back to top + +

+

+ © Copyright 2023, Ladybug Tools.
+ Created using Sphinx 5.3.0.
+

+
+
+ + \ No newline at end of file diff --git a/docs/_modules/honeybee/shademesh.html b/docs/_modules/honeybee/shademesh.html new file mode 100644 index 00000000..6618ccf2 --- /dev/null +++ b/docs/_modules/honeybee/shademesh.html @@ -0,0 +1,1454 @@ + + + + + + + honeybee.shademesh — honeybee documentation + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+ +

Source code for honeybee.shademesh

+# coding: utf-8
+"""Honeybee ShadeMesh."""
+from __future__ import division
+import math
+
+from ladybug_geometry.geometry3d import Mesh3D, Face3D
+from ladybug.color import Color
+
+from ._base import _Base
+from .typing import clean_string
+from .properties import ShadeMeshProperties
+import honeybee.writer.shademesh as writer
+
+
+
[docs]class ShadeMesh(_Base): + """A single planar shade. + + Args: + identifier: Text string for a unique Shade ID. Must be < 100 characters and + not contain any spaces or special characters. + geometry: A ladybug-geometry Mesh3D. + is_detached: Boolean to note whether this object is detached from other + geometry. Cases where this should be True include shade representing + surrounding buildings or context. (Default: True). + + Properties: + * identifier + * display_name + * is_detached + * geometry + * vertices + * faces + * center + * area + * min + * max + * type_color + * bc_color + * user_data + """ + __slots__ = ('_geometry', '_is_detached') + TYPE_COLORS = { + False: Color(120, 75, 190), + True: Color(80, 50, 128) + } + BC_COLOR = Color(120, 75, 190) + + def __init__(self, identifier, geometry, is_detached=True): + """A single planar shade.""" + _Base.__init__(self, identifier) # process the identifier + + # process the geometry and basic properties + assert isinstance(geometry, Mesh3D), \ + 'Expected ladybug_geometry Mesh3D. Got {}'.format(type(geometry)) + self._geometry = geometry + self.is_detached = is_detached + + # initialize properties for extensions + self._properties = ShadeMeshProperties(self) + +
[docs] @classmethod + def from_dict(cls, data): + """Initialize an ShadeMesh from a dictionary. + + Args: + data: A dictionary representation of an ShadeMesh object. + """ + try: + # check the type of dictionary + assert data['type'] == 'ShadeMesh', 'Expected ShadeMesh dictionary. ' \ + 'Got {}.'.format(data['type']) + + is_detached = data['is_detached'] if 'is_detached' in data else True + shade = cls( + data['identifier'], Mesh3D.from_dict(data['geometry']), is_detached) + if 'display_name' in data and data['display_name'] is not None: + shade.display_name = data['display_name'] + if 'user_data' in data and data['user_data'] is not None: + shade.user_data = data['user_data'] + + if data['properties']['type'] == 'ShadeMeshProperties': + shade.properties._load_extension_attr_from_dict(data['properties']) + return shade + except Exception as e: + cls._from_dict_error_message(data, e)
+ + @property + def is_detached(self): + """Get or set a boolean for whether this object is detached from other geometry. + """ + return self._is_detached + + @is_detached.setter + def is_detached(self, value): + try: + self._is_detached = bool(value) + except TypeError: + raise TypeError( + 'Expected boolean for ShadeMesh.is_detached. Got {}.'.format(value)) + + @property + def geometry(self): + """Get a ladybug_geometry Mesh3D object representing the Shade.""" + return self._geometry + + @property + def vertices(self): + """Get a tuple of ladybug_geometry Point3D for the vertices of the mesh.""" + return self._geometry.vertices + + @property + def faces(self): + """Get a tuple of tuples for the faces of the mesh.""" + return self._geometry.faces + + @property + def center(self): + """Get a ladybug_geometry Point3D for the center of the shade. + + Note that this is the center of the bounding box around this geometry + and not the area or volume centroid. + """ + return self._geometry.center + + @property + def area(self): + """Get the surface area of the shade mesh.""" + return self._geometry.area + + @property + def min(self): + """Get a Point3D for the minimum of the bounding box around the object.""" + return self._geometry.min + + @property + def max(self): + """Get a Point3D for the maximum of the bounding box around the object.""" + return self._geometry.max + + @property + def type_color(self): + """Get a Color to be used in visualizations by type.""" + return self.TYPE_COLORS[self.is_detached] + + @property + def bc_color(self): + """Get a Color to be used in visualizations by boundary condition.""" + return self.BC_COLOR + +
[docs] def add_prefix(self, prefix): + """Change the identifier of this object by inserting a prefix. + + This is particularly useful in workflows where you duplicate and edit + a starting object and then want to combine it with the original object + into one Model (like making a model of repeated rooms) since all objects + within a Model must have unique identifiers. + + Args: + prefix: Text that will be inserted at the start of this object's identifier + and display_name. It is recommended that this prefix be short to + avoid maxing out the 100 allowable characters for honeybee identifiers. + """ + self._identifier = clean_string('{}_{}'.format(prefix, self.identifier)) + self.display_name = '{}_{}'.format(prefix, self.display_name) + self.properties.add_prefix(prefix)
+ +
[docs] def move(self, moving_vec): + """Move this Shade along a vector. + + Args: + moving_vec: A ladybug_geometry Vector3D with the direction and distance + to move the face. + """ + self._geometry = self.geometry.move(moving_vec) + self.properties.move(moving_vec)
+ +
[docs] def rotate(self, axis, angle, origin): + """Rotate this Shade by a certain angle around an axis and origin. + + Args: + axis: A ladybug_geometry Vector3D axis representing the axis of rotation. + angle: An angle for rotation in degrees. + origin: A ladybug_geometry Point3D for the origin around which the + object will be rotated. + """ + self._geometry = self.geometry.rotate(axis, math.radians(angle), origin) + self.properties.rotate(axis, angle, origin)
+ +
[docs] def rotate_xy(self, angle, origin): + """Rotate this Shade counterclockwise in the world XY plane by a certain angle. + + Args: + angle: An angle in degrees. + origin: A ladybug_geometry Point3D for the origin around which the + object will be rotated. + """ + self._geometry = self.geometry.rotate_xy(math.radians(angle), origin) + self.properties.rotate_xy(angle, origin)
+ +
[docs] def reflect(self, plane): + """Reflect this Shade across a plane. + + Args: + plane: A ladybug_geometry Plane across which the object will + be reflected. + """ + self._geometry = self.geometry.reflect(plane.n, plane.o) + self.properties.reflect(plane)
+ +
[docs] def scale(self, factor, origin=None): + """Scale this Shade by a factor from an origin point. + + Args: + factor: A number representing how much the object should be scaled. + origin: A ladybug_geometry Point3D representing the origin from which + to scale. If None, it will be scaled from the World origin (0, 0, 0). + """ + self._geometry = self.geometry.scale(factor, origin) + self.properties.scale(factor, origin)
+ +
[docs] def triangulate_and_remove_degenerate_faces(self, tolerance=0.01): + """Triangulate non-planar faces in the mesh and remove all degenerate faces. + + This is helpful for certain geometry interfaces that require perfectly + planar geometry without duplicate or colinear vertices. + + Args: + tolerance: The minimum distance between a vertex and the boundary segments + at which point the vertex is considered colinear. Default: 0.01, + suitable for objects in meters. + """ + new_faces, verts = [], self.geometry.vertices + for shd in self.faces: + shd_verts = [verts[v] for v in shd] + shf = Face3D(shd_verts) + if not shf.check_planar(tolerance, raise_exception=False): + shades = ((shd[0], shd[1], shd[2]), (shd[2], shd[3], shd[0])) + for shade in shades: + shd_verts = [verts[v] for v in shade] + shade_face = Face3D(shd_verts) + try: + shade_face.remove_colinear_vertices(tolerance) + except AssertionError: + continue # degenerate face to remove + new_faces.append(shade) + else: + try: + new_face = shf.remove_colinear_vertices(tolerance) + except AssertionError: + continue # degenerate face to remove + if len(new_face.vertices) == len(shd): + new_faces.append(shd) + else: # quad face with duplicate or colinear verts + new_sh = tuple(shd[shd_verts.index(v)] for v in new_face.vertices) + new_faces.append(new_sh) + self._geometry = Mesh3D(verts, new_faces)
+ +
[docs] def is_geo_equivalent(self, shade_mesh, tolerance=0.01): + """Get a boolean for whether this object is geometrically equivalent to another. + + The total number of vertices and the ordering of these vertices can be + different but the geometries must share the same center point and be + next to one another to within the tolerance. + + Args: + shade_mesh: Another ShadeMesh for which geometric equivalency will be tested. + tolerance: The minimum difference between the coordinate values of two + vertices at which they can be considered geometrically equivalent. + + Returns: + True if geometrically equivalent. False if not geometrically equivalent. + """ + meta_1 = (self.display_name, self.is_detached) + meta_2 = (shade_mesh.display_name, shade_mesh.is_detached) + if meta_1 != meta_2: + return False + if len(self.geometry.vertices) != len(shade_mesh.geometry.vertices): + return False + if len(self.geometry.faces) != len(shade_mesh.geometry.faces): + return False + return all(pt.is_equivalent(o_pt, tolerance) for pt, o_pt in + zip(self.geometry.vertices, shade_mesh.geometry.vertices))
+ +
[docs] def display_dict(self): + """Get a list of DisplayMesh3D dictionaries for visualizing the object.""" + return [self._display_mesh(self.geometry, self.type_color)]
+ + @property + def to(self): + """ShadeMesh writer object. + + Use this method to access Writer class to write the shade in different formats. + + Usage: + + .. code-block:: python + + shade_mesh.to.idf(shade) -> idf string. + shade_mesh.to.radiance(shade) -> Radiance string. + """ + return writer + +
[docs] def to_dict(self, abridged=False, included_prop=None): + """Return Shade as a dictionary. + + Args: + abridged: Boolean to note whether the extension properties of the + object (ie. modifiers, transmittance schedule) should be included in + detail (False) or just referenced by identifier (True). Default: False. + included_prop: List of properties to filter keys that must be included in + output dictionary. For example ['energy'] will include 'energy' key if + available in properties to_dict. By default all the keys will be + included. To exclude all the keys from extensions use an empty list. + """ + base = {'type': 'ShadeMesh'} + base['identifier'] = self.identifier + base['display_name'] = self.display_name + base['properties'] = self.properties.to_dict(abridged, included_prop) + base['geometry'] = self._geometry.to_dict() + if not self.is_detached: + base['is_detached'] = self.is_detached + if self.user_data is not None: + base['user_data'] = self.user_data + return base
+ + @staticmethod + def _display_mesh(mesh3d, color): + """Create a DisplayMesh3D dictionary from a Mesh3D and color.""" + return { + 'type': 'DisplayMesh3D', + 'geometry': mesh3d.to_dict(), + 'color': color.to_dict(), + 'display_mode': 'SurfaceWithEdges' + } + + def __copy__(self): + new_shade = ShadeMesh(self.identifier, self.geometry, self.is_detached) + new_shade._display_name = self._display_name + new_shade._user_data = None if self.user_data is None else self.user_data.copy() + new_shade._properties._duplicate_extension_attr(self._properties) + return new_shade + + def __repr__(self): + return 'ShadeMesh: %s' % self.display_name
+
+ +
+ +
+
+
+
+

+ Back to top + +

+

+ © Copyright 2023, Ladybug Tools.
+ Created using Sphinx 5.3.0.
+

+
+
+ + \ No newline at end of file diff --git a/docs/_modules/honeybee/typing.html b/docs/_modules/honeybee/typing.html new file mode 100644 index 00000000..377488a8 --- /dev/null +++ b/docs/_modules/honeybee/typing.html @@ -0,0 +1,1523 @@ + + + + + + + honeybee.typing — honeybee documentation + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+ +

Source code for honeybee.typing

+"""Collection of methods for type input checking."""
+import re
+import os
+import math
+import uuid
+
+try:
+    INFPOS = math.inf
+    INFNEG = -1 * math.inf
+except AttributeError:
+    # python 2
+    INFPOS = float('inf')
+    INFNEG = float('-inf')
+
+
+
[docs]def valid_string(value, input_name=''): + """Check that a string is valid for both Radiance and EnergyPlus. + + This is used for honeybee geometry object names. + """ + try: + illegal_match = re.search(r'[^.A-Za-z0-9_-]', value) + except TypeError: + raise TypeError('Input {} must be a text string. Got {}: {}.'.format( + input_name, type(value), value)) + assert illegal_match is None, 'Illegal character "{}" found in {}'.format( + illegal_match.group(0), input_name) + assert len(value) > 0, 'Input {} "{}" contains no characters.'.format( + input_name, value) + assert len(value) <= 100, 'Input {} "{}" must be less than 100 characters.'.format( + input_name, value) + return value
+ + +
[docs]def valid_rad_string(value, input_name=''): + """Check that a string is valid for Radiance. + + This is used for radiance modifier names, etc. + """ + try: + illegal_match = re.search(r'[^.A-Za-z0-9_-]', value) + except TypeError: + raise TypeError('Input {} must be a text string. Got {}: {}.'.format( + input_name, type(value), value)) + assert illegal_match is None, 'Illegal character "{}" found in {}'.format( + illegal_match.group(0), input_name) + assert len(value) > 0, 'Input {} "{}" contains no characters.'.format( + input_name, value) + return value
+ + +
[docs]def valid_ep_string(value, input_name=''): + """Check that a string is valid for EnergyPlus. + + This is used for energy material names, schedule names, etc. + """ + try: + non_ascii = tuple(i for i in value if ord(i) >= 128) + except TypeError: + raise TypeError('Input {} must be a text string. Got {}: {}.'.format( + input_name, type(value), value)) + assert non_ascii == (), 'Illegal characters {} found in {}'.format( + non_ascii, input_name) + illegal_match = re.search(r'[,;!\n\t]', value) + assert illegal_match is None, 'Illegal character "{}" found in {}'.format( + illegal_match.group(0), input_name) + assert len(value) > 0, 'Input {} "{}" contains no characters.'.format( + input_name, value) + assert len(value) <= 100, 'Input {} "{}" must be less than 100 characters.'.format( + input_name, value) + return value
+ + +def _number_check(value, input_name): + """Check if value is a number.""" + try: + number = float(value) + except (ValueError, TypeError): + raise TypeError('Input {} must be a number. Got {}: {}.'.format( + input_name, type(value), value)) + return number + + +
[docs]def float_in_range(value, mi=INFNEG, ma=INFPOS, input_name=''): + """Check a float value to be between minimum and maximum.""" + number = _number_check(value, input_name) + assert mi <= number <= ma, 'Input number {} must be between {} and {}. ' \ + 'Got {}'.format(input_name, mi, ma, value) + return number
+ + +
[docs]def float_in_range_excl(value, mi=INFNEG, ma=INFPOS, input_name=''): + """Check a float value to be greater than minimum and less than maximum.""" + number = _number_check(value, input_name) + assert mi < number < ma, 'Input number {} must be greater than {} ' \ + 'and less than {}. Got {}'.format(input_name, mi, ma, value) + return number
+ + +
[docs]def float_in_range_excl_incl(value, mi=INFNEG, ma=INFPOS, input_name=''): + """Check a float value to be greater than minimum and less than/equal to maximum.""" + number = _number_check(value, input_name) + assert mi < number <= ma, 'Input number {} must be greater than {} and less than ' \ + 'or equal to {}. Got {}'.format(input_name, mi, ma, value) + return number
+ + +
[docs]def float_in_range_incl_excl(value, mi=INFNEG, ma=INFPOS, input_name=''): + """Check a float value to be greater than/equal to minimum and less than maximum.""" + number = _number_check(value, input_name) + assert mi <= number < ma, 'Input number {} must be greater than or equal to {} ' \ + 'and less than {}. Got {}'.format(input_name, mi, ma, value) + return number
+ + +
[docs]def int_in_range(value, mi=INFNEG, ma=INFPOS, input_name=''): + """Check an integer value to be between minimum and maximum.""" + try: + number = int(value) + except ValueError: + # try to convert to float and then digit if possible + try: + number = int(float(value)) + except (ValueError, TypeError): + raise TypeError('Input {} must be an integer. Got {}: {}.'.format( + input_name, type(value), value)) + except (ValueError, TypeError): + raise TypeError('Input {} must be an integer. Got {}: {}.'.format( + input_name, type(value), value)) + assert mi <= number <= ma, 'Input integer {} must be between {} and {}. ' \ + 'Got {}.'.format(input_name, mi, ma, value) + return number
+ + +
[docs]def float_positive(value, input_name=''): + """Check a float value to be positive.""" + return float_in_range(value, 0, INFPOS, input_name)
+ + +
[docs]def int_positive(value, input_name=''): + """Check if an integer value is positive.""" + return int_in_range(value, 0, INFPOS, input_name)
+ + +
[docs]def tuple_with_length(value, length=3, item_type=float, input_name=''): + """Try to create a tuple with a certain value.""" + try: + value = tuple(item_type(v) for v in value) + except (ValueError, TypeError): + raise TypeError('Input {} must be a {}.'.format( + input_name, item_type)) + assert len(value) == length, 'Input {} length must be {} not {}'.format( + input_name, length, len(value)) + return value
+ + +
[docs]def list_with_length(value, length=3, item_type=float, input_name=''): + """Try to create a list with a certain value.""" + try: + value = [item_type(v) for v in value] + except (ValueError, TypeError): + raise TypeError('Input {} must be a {}.'.format( + input_name, item_type)) + assert len(value) == length, 'Input {} length must be {} not {}'.format( + input_name, length, len(value)) + return value
+ + +
[docs]def clean_string(value, input_name=''): + """Clean a string so that it is valid for both Radiance and EnergyPlus. + + This will strip out spaces and special characters and raise an error if the + string is empty after stripping or has more than 100 characters. + """ + try: + val = re.sub(r'[^.A-Za-z0-9_-]', '', value) + except TypeError: + raise TypeError('Input {} must be a text string. Got {}: {}.'.format( + input_name, type(value), value)) + assert len(val) > 0, 'Input {} "{}" contains no valid characters.'.format( + input_name, value) + assert len(val) <= 100, 'Input {} "{}" must be less than 100 characters.'.format( + input_name, value) + return val
+ + +
[docs]def clean_rad_string(value, input_name=''): + """Clean a string for Radiance that can be used for rad material names. + + This includes stripping out illegal characters and white spaces as well as + raising an error if no legal characters are found. + """ + try: + val = re.sub(r'[^.A-Za-z0-9_-]', '', value) + except TypeError: + raise TypeError('Input {} must be a text string. Got {}: {}.'.format( + input_name, type(value), value)) + assert len(val) > 0, 'Input {} "{}" contains no valid characters.'.format( + input_name, value) + return val
+ + +
[docs]def clean_ep_string(value, input_name=''): + """Clean a string for EnergyPlus that can be used for energy material names. + + This includes stripping out all illegal characters, removing trailing spaces, + and rasing an error if the name is not longer than 100 characters or no legal + characters found. + """ + try: + val = ''.join(i for i in value if ord(i) < 128) # strip out non-ascii + val = re.sub(r'[,;!\n\t]', '', val) # strip out E+ special characters + except TypeError: + raise TypeError('Input {} must be a text string. Got {}: {}.'.format( + input_name, type(value), value)) + val = val.strip() + assert len(val) > 0, 'Input {} "{}" contains no valid characters.'.format( + input_name, value) + assert len(val) <= 100, 'Input {} "{}" must be less than 100 characters.'.format( + input_name, value) + return val
+ + +
[docs]def clean_and_id_string(value, input_name=''): + """Clean a string and add 8 unique characters to it to make it unique. + + Strings longer than 50 characters will be truncated before adding the ID. + The resulting string will be valid for both Radiance and EnergyPlus. + """ + try: + val = re.sub(r'[^.A-Za-z0-9_-]', '', value) + except TypeError: + raise TypeError('Input {} must be a text string. Got {}: {}.'.format( + input_name, type(value), value)) + if len(val) > 50: + val = val[:50] + return val + '_' + str(uuid.uuid4())[:8]
+ + +
[docs]def clean_and_id_rad_string(value, input_name=''): + """Clean a string and add 8 unique characters to it to make it unique for Radiance. + + This includes stripping out illegal characters and white spaces. + """ + try: + val = re.sub(r'[^.A-Za-z0-9_-]', '', value) + except TypeError: + raise TypeError('Input {} must be a text string. Got {}: {}.'.format( + input_name, type(value), value)) + return val + '_' + str(uuid.uuid4())[:8]
+ + +
[docs]def clean_and_id_ep_string(value, input_name=''): + """Clean a string and add 8 unique characters to it to make it unique for EnergyPlus. + + This includes stripping out all illegal characters and removing trailing white spaces. + Strings longer than 50 characters will be truncated before adding the ID. + """ + try: + val = ''.join(i for i in value if ord(i) < 128) # strip out non-ascii + val = re.sub(r'[,;!\n\t]', '', val) # strip out E+ special characters + except TypeError: + raise TypeError('Input {} must be a text string. Got {}: {}.'.format( + input_name, type(value), value)) + val = val.strip() + if len(val) > 50: + val = val[:50] + return val + '_' + str(uuid.uuid4())[:8]
+ + +
[docs]def clean_and_number_string(value, existing_dict, input_name=''): + """Clean a string and add an integer to it if it is found in the existing_dict. + + The resulting string will be valid for both Radiance and EnergyPlus. + + Args: + value: The text string to be cleaned and possibly given a unique integer. + existing_dict: A dictionary where the keys are text strings of existing items + and the values are the number of times that the item has appeared in + the model already. + """ + try: + val = re.sub(r'[^.A-Za-z0-9_-]', '_', value) + except TypeError: + raise TypeError('Input {} must be a text string. Got {}: {}.'.format( + input_name, type(value), value)) + if len(val) > 95: + val = val[:95] + if val in existing_dict: + existing_dict[val] += 1 + return val + '_' + str(existing_dict[val]) + else: + existing_dict[val] = 1 + return val
+ + +
[docs]def clean_and_number_rad_string(value, existing_dict, input_name=''): + """Clean a string for Radiance and add an integer if found in the existing_dict. + + This includes stripping out illegal characters and white spaces. + + Args: + value: The text string to be cleaned and possibly given a unique integer. + existing_dict: A dictionary where the keys are text strings of existing items + and the values are the number of times that the item has appeared in + the model already. + """ + try: + val = re.sub(r'[^.A-Za-z0-9_-]', '_', value) + except TypeError: + raise TypeError('Input {} must be a text string. Got {}: {}.'.format( + input_name, type(value), value)) + if val in existing_dict: + existing_dict[val] += 1 + return val + '_' + str(existing_dict[val]) + else: + existing_dict[val] = 1 + return val
+ + +
[docs]def clean_and_number_ep_string(value, existing_dict, input_name=''): + """Clean a string for EnergyPlus and add an integer if found in the existing_dict. + + This includes stripping out all illegal characters and removing trailing white spaces. + Strings longer than 95 characters will be truncated before adding the integer. + + Args: + value: The text string to be cleaned and possibly given a unique integer. + existing_dict: A dictionary where the keys are text strings of existing items + and the values are the number of times that the item has appeared in + the model already. + """ + try: + val = ''.join(i for i in value if ord(i) < 128) # strip out non-ascii + val = re.sub(r'[,;!\n\t]', '', val) # strip out E+ special characters + except TypeError: + raise TypeError('Input {} must be a text string. Got {}: {}.'.format( + input_name, type(value), value)) + val = val.strip() + if len(val) > 95: + val = val[:95] + if val in existing_dict: + existing_dict[val] += 1 + return val + ' ' + str(existing_dict[val]) + else: + existing_dict[val] = 1 + return val
+ + +
[docs]def truncate_and_id_string(value, truncate_len=32, uuid_len=0, input_name=''): + """Truncate a string to a length with an option to add unique characters at the end. + + Note that all outputs will always be the truncate_len or less and the uuid_len + just specifies the number of characters to replace at the end with unique ones. + + The result will be valid for EnergyPlus, Radiance, and likely many more engines + with different types of character restrictions. + """ + try: + val = re.sub(r'[^.A-Za-z0-9_-]', '', value) + except TypeError: + raise TypeError('Input {} must be a text string. Got {}: {}.'.format( + input_name, type(value), value)) + final_len = truncate_len - uuid_len + if len(val) > final_len: + val = val[:final_len] + if uuid_len > 0: + return val + str(uuid.uuid4())[:uuid_len] + return val
+ + +
[docs]def fixed_string_length(value, target_len=32): + """Truncate a string or add trailing spaces to hit a target character length. + + This is useful when trying to construct human-readable tables of text. + """ + if len(value) > target_len: + return value[:target_len] + elif len(value) < target_len: + return value + ' ' * (target_len - len(value)) + else: + return value
+ +
[docs]def invalid_dict_error(invalid_dict, error): + """Raise a ValueError for an invalid dictionary that failed to serialize. + + This error message will include the identifier (and display_name) if they are + present within the invalid_dict, making it easier for ens users to find the + invalid object within large objects like Models. + + Args: + invalid_dict: A dictionary of an invalid honeybee object that failed + to serialize. + error: + """ + obj_type = invalid_dict['type'].replace('Abridged', '') \ + if 'type' in invalid_dict else 'Honeybee Object' + obj_id = invalid_dict['identifier'] if 'identifier' in invalid_dict else '' + full_id = '{}[{}]'.format(invalid_dict['display_name'], obj_id) \ + if 'display_name' in invalid_dict else obj_id + raise ValueError('{} "{}" is invalid:\n{}'.format(obj_type, full_id, error))
+ + +wrapper = '"' if os.name == 'nt' else '\'' +"""String wrapper.""" + + +
[docs]def normpath(value): + """Normalize path eliminating double slashes, etc and put it in quotes if needed.""" + value = os.path.normpath(value) + if ' ' in value: + value = '{0}{1}{0}'.format(wrapper, value) + return value
+
+ +
+ +
+
+
+
+

+ Back to top + +

+

+ © Copyright 2023, Ladybug Tools.
+ Created using Sphinx 5.3.0.
+

+
+
+ + \ No newline at end of file diff --git a/docs/_modules/honeybee/units.html b/docs/_modules/honeybee/units.html new file mode 100644 index 00000000..75e16924 --- /dev/null +++ b/docs/_modules/honeybee/units.html @@ -0,0 +1,1198 @@ + + + + + + + honeybee.units — honeybee documentation + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+ +

Source code for honeybee.units

+"""Utility functions for converting and parsing units of length."""
+
+# global properties to set all supported units
+UNITS = ('Meters', 'Millimeters', 'Feet', 'Inches', 'Centimeters')
+UNITS_ABBREVIATIONS = ('m', 'mm', 'ft', 'in', 'cm')
+UNITS_TOLERANCES = {
+    'Meters': 0.01,
+    'Millimeters': 1.0,
+    'Feet': 0.01,
+    'Inches': 0.1,
+    'Centimeters': 1.0
+}
+
+
+
[docs]def conversion_factor_to_meters(units): + """Get the conversion factor to meters based on input units. + + Args: + units: Text for the units. Choose from the following: + + * Meters + * Millimeters + * Feet + * Inches + * Centimeters + + Returns: + A number for the conversion factor, which should be multiplied by + all distance units taken from Rhino geometry in order to convert + them to meters. + """ + if units == 'Meters': + return 1.0 + elif units == 'Millimeters': + return 0.001 + elif units == 'Feet': + return 0.3048 + elif units == 'Inches': + return 0.0254 + elif units == 'Centimeters': + return 0.01 + else: + raise ValueError( + 'You are kidding me! What units are you using? {}?\n' + 'Please use one of the following: {}'.format(units, ' '.join(UNITS)) + )
+ + +
[docs]def parse_distance_string(distance_string, destination_units='Meters'): + """Parse a string of a distance value into a destination units system. + + Args: + distance_string: Text for a distance value to be parsed into the + destination units. This can have the units at the end of + it (eg. "3ft"). If no units are included, the number will be + assumed to be in the destination units system. + destination_units: The destination units system to which the distance + string will be computed. (Default: Meters). + + Returns: + A number for the distance in the destination_units. + """ + # separate the distance string into a number and a unit abbreviation + distance_string = distance_string.strip().replace(',', '.') + try: # check if the distance string is just a number + return float(distance_string) + except ValueError: # it must have some units attached to it + for i, ua in enumerate(UNITS_ABBREVIATIONS): + try: # see if replacing the units yields a float + distance = float(distance_string.replace(ua, '', 1)) + u_sys = UNITS[i] + break + except ValueError: # not the right type of units + pass + else: # we could not match the units system + raise ValueError( + 'Text string "{}" could not be decoded into a distance and a unit.\n' + 'Make sure your units are one of the following: {}'.format( + distance_string, ' '.join(UNITS_ABBREVIATIONS)) + ) + + # process the number into the destination units system + if u_sys == destination_units: + return distance + con_factor = 1 / conversion_factor_to_meters(destination_units) + if u_sys != 'Meters': + con_factor = con_factor * conversion_factor_to_meters(u_sys) + return distance * con_factor
+
+ +
+ +
+
+
+
+

+ Back to top + +

+

+ © Copyright 2023, Ladybug Tools.
+ Created using Sphinx 5.3.0.
+

+
+
+ + \ No newline at end of file diff --git a/docs/_modules/index.html b/docs/_modules/index.html new file mode 100644 index 00000000..4806d457 --- /dev/null +++ b/docs/_modules/index.html @@ -0,0 +1,1131 @@ + + + + + + + Overview: module code — honeybee documentation + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+

+ Back to top + +

+

+ © Copyright 2023, Ladybug Tools.
+ Created using Sphinx 5.3.0.
+

+
+
+ + \ No newline at end of file diff --git a/docs/_sources/cli/compare.rst.txt b/docs/_sources/cli/compare.rst.txt new file mode 100644 index 00000000..dc2967d3 --- /dev/null +++ b/docs/_sources/cli/compare.rst.txt @@ -0,0 +1,6 @@ +compare +======= + +.. click:: honeybee.cli.compare:compare + :prog: honeybee compare + :show-nested: diff --git a/docs/_sources/cli/create.rst.txt b/docs/_sources/cli/create.rst.txt new file mode 100644 index 00000000..1a6e1885 --- /dev/null +++ b/docs/_sources/cli/create.rst.txt @@ -0,0 +1,6 @@ +create +====== + +.. click:: honeybee.cli.create:create + :prog: honeybee create + :show-nested: diff --git a/docs/_sources/cli/edit.rst.txt b/docs/_sources/cli/edit.rst.txt new file mode 100644 index 00000000..96b50ad5 --- /dev/null +++ b/docs/_sources/cli/edit.rst.txt @@ -0,0 +1,6 @@ +edit +==== + +.. click:: honeybee.cli.edit:edit + :prog: honeybee edit + :show-nested: diff --git a/docs/_sources/cli/index.rst.txt b/docs/_sources/cli/index.rst.txt new file mode 100644 index 00000000..0948faf8 --- /dev/null +++ b/docs/_sources/cli/index.rst.txt @@ -0,0 +1,21 @@ +CLI Docs +======== + +Installation +------------ + +To check if the Honeybee command line interface is installed correctly try ``honeybee viz`` and you +should get a ``viiiiiiiiiiiiizzzzzzzzz!`` back in response! + +Commands +-------- +.. toctree:: + :maxdepth: 1 + + main + validate + compare + setconfig + edit + lib + create diff --git a/docs/_sources/cli/lib.rst.txt b/docs/_sources/cli/lib.rst.txt new file mode 100644 index 00000000..3e7028fc --- /dev/null +++ b/docs/_sources/cli/lib.rst.txt @@ -0,0 +1,6 @@ +lib +=== + +.. click:: honeybee.cli.lib:lib + :prog: honeybee lib + :show-nested: diff --git a/docs/_sources/cli/main.rst.txt b/docs/_sources/cli/main.rst.txt new file mode 100644 index 00000000..d9c70d8d --- /dev/null +++ b/docs/_sources/cli/main.rst.txt @@ -0,0 +1,7 @@ +main +==== + +.. click:: honeybee.cli.__init__:main + :prog: honeybee + :show-nested: + :commands: config ,viz diff --git a/docs/_sources/cli/setconfig.rst.txt b/docs/_sources/cli/setconfig.rst.txt new file mode 100644 index 00000000..b98d5236 --- /dev/null +++ b/docs/_sources/cli/setconfig.rst.txt @@ -0,0 +1,6 @@ +setconfig +========= + +.. click:: honeybee.cli.setconfig:set_config + :prog: honeybee set-config + :show-nested: diff --git a/docs/_sources/cli/validate.rst.txt b/docs/_sources/cli/validate.rst.txt new file mode 100644 index 00000000..05a5e701 --- /dev/null +++ b/docs/_sources/cli/validate.rst.txt @@ -0,0 +1,6 @@ +validate +======== + +.. click:: honeybee.cli.validate:validate + :prog: honeybee validate + :show-nested: diff --git a/docs/_sources/honeybee.altnumber.rst.txt b/docs/_sources/honeybee.altnumber.rst.txt new file mode 100644 index 00000000..6eb0819b --- /dev/null +++ b/docs/_sources/honeybee.altnumber.rst.txt @@ -0,0 +1,7 @@ +honeybee.altnumber module +========================= + +.. automodule:: honeybee.altnumber + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/honeybee.aperture.rst.txt b/docs/_sources/honeybee.aperture.rst.txt new file mode 100644 index 00000000..72d88f3d --- /dev/null +++ b/docs/_sources/honeybee.aperture.rst.txt @@ -0,0 +1,7 @@ +honeybee.aperture module +======================== + +.. automodule:: honeybee.aperture + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/honeybee.boundarycondition.rst.txt b/docs/_sources/honeybee.boundarycondition.rst.txt new file mode 100644 index 00000000..c2801234 --- /dev/null +++ b/docs/_sources/honeybee.boundarycondition.rst.txt @@ -0,0 +1,7 @@ +honeybee.boundarycondition module +================================= + +.. automodule:: honeybee.boundarycondition + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/honeybee.checkdup.rst.txt b/docs/_sources/honeybee.checkdup.rst.txt new file mode 100644 index 00000000..a2dcbb75 --- /dev/null +++ b/docs/_sources/honeybee.checkdup.rst.txt @@ -0,0 +1,7 @@ +honeybee.checkdup module +======================== + +.. automodule:: honeybee.checkdup + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/honeybee.cli.compare.rst.txt b/docs/_sources/honeybee.cli.compare.rst.txt new file mode 100644 index 00000000..98f89305 --- /dev/null +++ b/docs/_sources/honeybee.cli.compare.rst.txt @@ -0,0 +1,7 @@ +honeybee.cli.compare module +=========================== + +.. automodule:: honeybee.cli.compare + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/honeybee.cli.create.rst.txt b/docs/_sources/honeybee.cli.create.rst.txt new file mode 100644 index 00000000..1a6e3df7 --- /dev/null +++ b/docs/_sources/honeybee.cli.create.rst.txt @@ -0,0 +1,7 @@ +honeybee.cli.create module +========================== + +.. automodule:: honeybee.cli.create + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/honeybee.cli.edit.rst.txt b/docs/_sources/honeybee.cli.edit.rst.txt new file mode 100644 index 00000000..697b1c68 --- /dev/null +++ b/docs/_sources/honeybee.cli.edit.rst.txt @@ -0,0 +1,7 @@ +honeybee.cli.edit module +======================== + +.. automodule:: honeybee.cli.edit + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/honeybee.cli.lib.rst.txt b/docs/_sources/honeybee.cli.lib.rst.txt new file mode 100644 index 00000000..c96be7f2 --- /dev/null +++ b/docs/_sources/honeybee.cli.lib.rst.txt @@ -0,0 +1,7 @@ +honeybee.cli.lib module +======================= + +.. automodule:: honeybee.cli.lib + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/honeybee.cli.rst.txt b/docs/_sources/honeybee.cli.rst.txt new file mode 100644 index 00000000..e0dc2233 --- /dev/null +++ b/docs/_sources/honeybee.cli.rst.txt @@ -0,0 +1,23 @@ +honeybee.cli package +==================== + +Submodules +---------- + +.. toctree:: + :maxdepth: 4 + + honeybee.cli.compare + honeybee.cli.create + honeybee.cli.edit + honeybee.cli.lib + honeybee.cli.setconfig + honeybee.cli.validate + +Module contents +--------------- + +.. automodule:: honeybee.cli + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/honeybee.cli.setconfig.rst.txt b/docs/_sources/honeybee.cli.setconfig.rst.txt new file mode 100644 index 00000000..bcecb98c --- /dev/null +++ b/docs/_sources/honeybee.cli.setconfig.rst.txt @@ -0,0 +1,7 @@ +honeybee.cli.setconfig module +============================= + +.. automodule:: honeybee.cli.setconfig + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/honeybee.cli.validate.rst.txt b/docs/_sources/honeybee.cli.validate.rst.txt new file mode 100644 index 00000000..4d366837 --- /dev/null +++ b/docs/_sources/honeybee.cli.validate.rst.txt @@ -0,0 +1,7 @@ +honeybee.cli.validate module +============================ + +.. automodule:: honeybee.cli.validate + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/honeybee.colorobj.rst.txt b/docs/_sources/honeybee.colorobj.rst.txt new file mode 100644 index 00000000..e7bc72e1 --- /dev/null +++ b/docs/_sources/honeybee.colorobj.rst.txt @@ -0,0 +1,7 @@ +honeybee.colorobj module +======================== + +.. automodule:: honeybee.colorobj + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/honeybee.config.rst.txt b/docs/_sources/honeybee.config.rst.txt new file mode 100644 index 00000000..3655f4fe --- /dev/null +++ b/docs/_sources/honeybee.config.rst.txt @@ -0,0 +1,7 @@ +honeybee.config module +====================== + +.. automodule:: honeybee.config + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/honeybee.dictutil.rst.txt b/docs/_sources/honeybee.dictutil.rst.txt new file mode 100644 index 00000000..378e8f70 --- /dev/null +++ b/docs/_sources/honeybee.dictutil.rst.txt @@ -0,0 +1,7 @@ +honeybee.dictutil module +======================== + +.. automodule:: honeybee.dictutil + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/honeybee.door.rst.txt b/docs/_sources/honeybee.door.rst.txt new file mode 100644 index 00000000..a40420b7 --- /dev/null +++ b/docs/_sources/honeybee.door.rst.txt @@ -0,0 +1,7 @@ +honeybee.door module +==================== + +.. automodule:: honeybee.door + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/honeybee.extensionutil.rst.txt b/docs/_sources/honeybee.extensionutil.rst.txt new file mode 100644 index 00000000..5e667967 --- /dev/null +++ b/docs/_sources/honeybee.extensionutil.rst.txt @@ -0,0 +1,7 @@ +honeybee.extensionutil module +============================= + +.. automodule:: honeybee.extensionutil + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/honeybee.face.rst.txt b/docs/_sources/honeybee.face.rst.txt new file mode 100644 index 00000000..60b575c1 --- /dev/null +++ b/docs/_sources/honeybee.face.rst.txt @@ -0,0 +1,7 @@ +honeybee.face module +==================== + +.. automodule:: honeybee.face + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/honeybee.facetype.rst.txt b/docs/_sources/honeybee.facetype.rst.txt new file mode 100644 index 00000000..8ba4400a --- /dev/null +++ b/docs/_sources/honeybee.facetype.rst.txt @@ -0,0 +1,7 @@ +honeybee.facetype module +======================== + +.. automodule:: honeybee.facetype + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/honeybee.logutil.rst.txt b/docs/_sources/honeybee.logutil.rst.txt new file mode 100644 index 00000000..da74223a --- /dev/null +++ b/docs/_sources/honeybee.logutil.rst.txt @@ -0,0 +1,7 @@ +honeybee.logutil module +======================= + +.. automodule:: honeybee.logutil + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/honeybee.model.rst.txt b/docs/_sources/honeybee.model.rst.txt new file mode 100644 index 00000000..181a4721 --- /dev/null +++ b/docs/_sources/honeybee.model.rst.txt @@ -0,0 +1,7 @@ +honeybee.model module +===================== + +.. automodule:: honeybee.model + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/honeybee.orientation.rst.txt b/docs/_sources/honeybee.orientation.rst.txt new file mode 100644 index 00000000..c56148c0 --- /dev/null +++ b/docs/_sources/honeybee.orientation.rst.txt @@ -0,0 +1,7 @@ +honeybee.orientation module +=========================== + +.. automodule:: honeybee.orientation + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/honeybee.properties.rst.txt b/docs/_sources/honeybee.properties.rst.txt new file mode 100644 index 00000000..b5124d91 --- /dev/null +++ b/docs/_sources/honeybee.properties.rst.txt @@ -0,0 +1,7 @@ +honeybee.properties module +========================== + +.. automodule:: honeybee.properties + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/honeybee.room.rst.txt b/docs/_sources/honeybee.room.rst.txt new file mode 100644 index 00000000..3ba67b21 --- /dev/null +++ b/docs/_sources/honeybee.room.rst.txt @@ -0,0 +1,7 @@ +honeybee.room module +==================== + +.. automodule:: honeybee.room + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/honeybee.rst.txt b/docs/_sources/honeybee.rst.txt new file mode 100644 index 00000000..cb5ff286 --- /dev/null +++ b/docs/_sources/honeybee.rst.txt @@ -0,0 +1,47 @@ +honeybee package +================ + +Subpackages +----------- + +.. toctree:: + :maxdepth: 4 + + honeybee.cli + honeybee.writer + +Submodules +---------- + +.. toctree:: + :maxdepth: 4 + + honeybee.altnumber + honeybee.aperture + honeybee.boundarycondition + honeybee.checkdup + honeybee.colorobj + honeybee.config + honeybee.dictutil + honeybee.door + honeybee.extensionutil + honeybee.face + honeybee.facetype + honeybee.logutil + honeybee.model + honeybee.orientation + honeybee.properties + honeybee.room + honeybee.search + honeybee.shade + honeybee.shademesh + honeybee.typing + honeybee.units + +Module contents +--------------- + +.. automodule:: honeybee + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/honeybee.search.rst.txt b/docs/_sources/honeybee.search.rst.txt new file mode 100644 index 00000000..d293d647 --- /dev/null +++ b/docs/_sources/honeybee.search.rst.txt @@ -0,0 +1,7 @@ +honeybee.search module +====================== + +.. automodule:: honeybee.search + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/honeybee.shade.rst.txt b/docs/_sources/honeybee.shade.rst.txt new file mode 100644 index 00000000..b973ba61 --- /dev/null +++ b/docs/_sources/honeybee.shade.rst.txt @@ -0,0 +1,7 @@ +honeybee.shade module +===================== + +.. automodule:: honeybee.shade + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/honeybee.shademesh.rst.txt b/docs/_sources/honeybee.shademesh.rst.txt new file mode 100644 index 00000000..4405624b --- /dev/null +++ b/docs/_sources/honeybee.shademesh.rst.txt @@ -0,0 +1,7 @@ +honeybee.shademesh module +========================= + +.. automodule:: honeybee.shademesh + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/honeybee.typing.rst.txt b/docs/_sources/honeybee.typing.rst.txt new file mode 100644 index 00000000..fdcfafd1 --- /dev/null +++ b/docs/_sources/honeybee.typing.rst.txt @@ -0,0 +1,7 @@ +honeybee.typing module +====================== + +.. automodule:: honeybee.typing + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/honeybee.units.rst.txt b/docs/_sources/honeybee.units.rst.txt new file mode 100644 index 00000000..b01c11f4 --- /dev/null +++ b/docs/_sources/honeybee.units.rst.txt @@ -0,0 +1,7 @@ +honeybee.units module +===================== + +.. automodule:: honeybee.units + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/honeybee.writer.aperture.rst.txt b/docs/_sources/honeybee.writer.aperture.rst.txt new file mode 100644 index 00000000..75ccaa31 --- /dev/null +++ b/docs/_sources/honeybee.writer.aperture.rst.txt @@ -0,0 +1,7 @@ +honeybee.writer.aperture module +=============================== + +.. automodule:: honeybee.writer.aperture + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/honeybee.writer.door.rst.txt b/docs/_sources/honeybee.writer.door.rst.txt new file mode 100644 index 00000000..c859008f --- /dev/null +++ b/docs/_sources/honeybee.writer.door.rst.txt @@ -0,0 +1,7 @@ +honeybee.writer.door module +=========================== + +.. automodule:: honeybee.writer.door + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/honeybee.writer.face.rst.txt b/docs/_sources/honeybee.writer.face.rst.txt new file mode 100644 index 00000000..8f2a572f --- /dev/null +++ b/docs/_sources/honeybee.writer.face.rst.txt @@ -0,0 +1,7 @@ +honeybee.writer.face module +=========================== + +.. automodule:: honeybee.writer.face + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/honeybee.writer.model.rst.txt b/docs/_sources/honeybee.writer.model.rst.txt new file mode 100644 index 00000000..d39a00ff --- /dev/null +++ b/docs/_sources/honeybee.writer.model.rst.txt @@ -0,0 +1,7 @@ +honeybee.writer.model module +============================ + +.. automodule:: honeybee.writer.model + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/honeybee.writer.room.rst.txt b/docs/_sources/honeybee.writer.room.rst.txt new file mode 100644 index 00000000..d46e1c9d --- /dev/null +++ b/docs/_sources/honeybee.writer.room.rst.txt @@ -0,0 +1,7 @@ +honeybee.writer.room module +=========================== + +.. automodule:: honeybee.writer.room + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/honeybee.writer.rst.txt b/docs/_sources/honeybee.writer.rst.txt new file mode 100644 index 00000000..6bb09d43 --- /dev/null +++ b/docs/_sources/honeybee.writer.rst.txt @@ -0,0 +1,24 @@ +honeybee.writer package +======================= + +Submodules +---------- + +.. toctree:: + :maxdepth: 4 + + honeybee.writer.aperture + honeybee.writer.door + honeybee.writer.face + honeybee.writer.model + honeybee.writer.room + honeybee.writer.shade + honeybee.writer.shademesh + +Module contents +--------------- + +.. automodule:: honeybee.writer + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/honeybee.writer.shade.rst.txt b/docs/_sources/honeybee.writer.shade.rst.txt new file mode 100644 index 00000000..7c54f0e3 --- /dev/null +++ b/docs/_sources/honeybee.writer.shade.rst.txt @@ -0,0 +1,7 @@ +honeybee.writer.shade module +============================ + +.. automodule:: honeybee.writer.shade + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/honeybee.writer.shademesh.rst.txt b/docs/_sources/honeybee.writer.shademesh.rst.txt new file mode 100644 index 00000000..a146bd89 --- /dev/null +++ b/docs/_sources/honeybee.writer.shademesh.rst.txt @@ -0,0 +1,7 @@ +honeybee.writer.shademesh module +================================ + +.. automodule:: honeybee.writer.shademesh + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/index.rst.txt b/docs/_sources/index.rst.txt new file mode 100644 index 00000000..9d73970e --- /dev/null +++ b/docs/_sources/index.rst.txt @@ -0,0 +1,62 @@ + +Welcome to Honeybee's documentation! +========================================= + +.. image:: http://www.ladybug.tools/assets/img/honeybee.png + +Honeybee is a collection of Python libraries to create representations of buildings +following `honeybee-schema `_. + +This package is the core library that provides honeybee's common functionalities. +To extend these functionalities you should install available Honeybee extensions or write +your own. + +Installation +============ + +To install the core library try ``pip install -U honeybee-core``. + +To check if the Honeybee command line interface is installed correctly try ``honeybee viz`` and you +should get a ``viiiiiiiiiiiiizzzzzzzzz!`` back in response! + + +Documentation +============= + +This document includes `Honeybee API documentation <#honeybee>`_ and +`Honeybee Command Line Interface <#cli-docs>`_ documentation for ``honeybee core`` and does +not include the documentation for honeybee extensions. For each extension refer to +extension's documentation page. + +Here are a number of Honeybee popular extensions: + +- `honeybee-energy `_ +- `honeybee-radiance `_ + + +CLI Docs +============= + +For command line interface documentation and API documentation see the pages below. + + +.. toctree:: + :maxdepth: 2 + + cli/index + + +honeybee +============= + +.. toctree:: + :maxdepth: 4 + + modules + +Indices and tables +------------------ + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/docs/_sources/modules.rst.txt b/docs/_sources/modules.rst.txt new file mode 100644 index 00000000..b1e490b0 --- /dev/null +++ b/docs/_sources/modules.rst.txt @@ -0,0 +1,7 @@ +honeybee +======== + +.. toctree:: + :maxdepth: 4 + + honeybee diff --git a/docs/_static/_sphinx_javascript_frameworks_compat.js b/docs/_static/_sphinx_javascript_frameworks_compat.js new file mode 100644 index 00000000..8549469d --- /dev/null +++ b/docs/_static/_sphinx_javascript_frameworks_compat.js @@ -0,0 +1,134 @@ +/* + * _sphinx_javascript_frameworks_compat.js + * ~~~~~~~~~~ + * + * Compatability shim for jQuery and underscores.js. + * + * WILL BE REMOVED IN Sphinx 6.0 + * xref RemovedInSphinx60Warning + * + */ + +/** + * select a different prefix for underscore + */ +$u = _.noConflict(); + + +/** + * small helper function to urldecode strings + * + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL + */ +jQuery.urldecode = function(x) { + if (!x) { + return 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; +}; + +/** + * 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, addItems) { + if (node.nodeType === 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && + !jQuery(node.parentNode).hasClass(className) && + !jQuery(node.parentNode).hasClass("nohighlight")) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + 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); + if (isInSVG) { + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + var bbox = node.parentElement.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute('class', className); + addItems.push({ + "parent": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} diff --git a/docs/_static/basic.css b/docs/_static/basic.css new file mode 100644 index 00000000..eeb0519a --- /dev/null +++ b/docs/_static/basic.css @@ -0,0 +1,899 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- 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%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +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 form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- 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 p.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%; + margin-left: auto; + margin-right: auto; +} + +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 ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +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; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 360px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} +a.brackets:before, +span.brackets > a:before{ + content: "["; +} + +a.brackets:after, +span.brackets > a:after { + content: "]"; +} + + +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, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ +div.topic { + border: 1px solid #ccc; + padding: 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; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +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; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + + +/* -- other body styles ----------------------------------------------------- */ + +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; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} +dl.footnote > dt, +dl.citation > dt { + float: left; + margin-right: 0.5em; +} + +dl.footnote > dd, +dl.citation > dd { + margin-bottom: 0em; +} + +dl.footnote > dd:after, +dl.citation > dd:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} +dl.field-list > dt:after { + content: ":"; +} + + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.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; +} + +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + 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; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- 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/docs/_static/bootstrap-2.3.2/css/bootstrap-responsive.css b/docs/_static/bootstrap-2.3.2/css/bootstrap-responsive.css new file mode 100644 index 00000000..09e88ce3 --- /dev/null +++ b/docs/_static/bootstrap-2.3.2/css/bootstrap-responsive.css @@ -0,0 +1,1109 @@ +/*! + * Bootstrap Responsive v2.3.2 + * + * Copyright 2012 Twitter, Inc + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Designed and built with all the love in the world @twitter by @mdo and @fat. + */ + +.clearfix { + *zoom: 1; +} + +.clearfix:before, +.clearfix:after { + display: table; + line-height: 0; + content: ""; +} + +.clearfix:after { + clear: both; +} + +.hide-text { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} + +.input-block-level { + display: block; + width: 100%; + min-height: 30px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +@-ms-viewport { + width: device-width; +} + +.hidden { + display: none; + visibility: hidden; +} + +.visible-phone { + display: none !important; +} + +.visible-tablet { + display: none !important; +} + +.hidden-desktop { + display: none !important; +} + +.visible-desktop { + display: inherit !important; +} + +@media (min-width: 768px) and (max-width: 979px) { + .hidden-desktop { + display: inherit !important; + } + .visible-desktop { + display: none !important ; + } + .visible-tablet { + display: inherit !important; + } + .hidden-tablet { + display: none !important; + } +} + +@media (max-width: 767px) { + .hidden-desktop { + display: inherit !important; + } + .visible-desktop { + display: none !important; + } + .visible-phone { + display: inherit !important; + } + .hidden-phone { + display: none !important; + } +} + +.visible-print { + display: none !important; +} + +@media print { + .visible-print { + display: inherit !important; + } + .hidden-print { + display: none !important; + } +} + +@media (min-width: 1200px) { + .row { + margin-left: -30px; + *zoom: 1; + } + .row:before, + .row:after { + display: table; + line-height: 0; + content: ""; + } + .row:after { + clear: both; + } + [class*="span"] { + float: left; + min-height: 1px; + margin-left: 30px; + } + .container, + .navbar-static-top .container, + .navbar-fixed-top .container, + .navbar-fixed-bottom .container { + width: 1170px; + } + .span12 { + width: 1170px; + } + .span11 { + width: 1070px; + } + .span10 { + width: 970px; + } + .span9 { + width: 870px; + } + .span8 { + width: 770px; + } + .span7 { + width: 670px; + } + .span6 { + width: 570px; + } + .span5 { + width: 470px; + } + .span4 { + width: 370px; + } + .span3 { + width: 270px; + } + .span2 { + width: 170px; + } + .span1 { + width: 70px; + } + .offset12 { + margin-left: 1230px; + } + .offset11 { + margin-left: 1130px; + } + .offset10 { + margin-left: 1030px; + } + .offset9 { + margin-left: 930px; + } + .offset8 { + margin-left: 830px; + } + .offset7 { + margin-left: 730px; + } + .offset6 { + margin-left: 630px; + } + .offset5 { + margin-left: 530px; + } + .offset4 { + margin-left: 430px; + } + .offset3 { + margin-left: 330px; + } + .offset2 { + margin-left: 230px; + } + .offset1 { + margin-left: 130px; + } + .row-fluid { + width: 100%; + *zoom: 1; + } + .row-fluid:before, + .row-fluid:after { + display: table; + line-height: 0; + content: ""; + } + .row-fluid:after { + clear: both; + } + .row-fluid [class*="span"] { + display: block; + float: left; + width: 100%; + min-height: 30px; + margin-left: 2.564102564102564%; + *margin-left: 2.5109110747408616%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + .row-fluid [class*="span"]:first-child { + margin-left: 0; + } + .row-fluid .controls-row [class*="span"] + [class*="span"] { + margin-left: 2.564102564102564%; + } + .row-fluid .span12 { + width: 100%; + *width: 99.94680851063829%; + } + .row-fluid .span11 { + width: 91.45299145299145%; + *width: 91.39979996362975%; + } + .row-fluid .span10 { + width: 82.90598290598291%; + *width: 82.8527914166212%; + } + .row-fluid .span9 { + width: 74.35897435897436%; + *width: 74.30578286961266%; + } + .row-fluid .span8 { + width: 65.81196581196582%; + *width: 65.75877432260411%; + } + .row-fluid .span7 { + width: 57.26495726495726%; + *width: 57.21176577559556%; + } + .row-fluid .span6 { + width: 48.717948717948715%; + *width: 48.664757228587014%; + } + .row-fluid .span5 { + width: 40.17094017094017%; + *width: 40.11774868157847%; + } + .row-fluid .span4 { + width: 31.623931623931625%; + *width: 31.570740134569924%; + } + .row-fluid .span3 { + width: 23.076923076923077%; + *width: 23.023731587561375%; + } + .row-fluid .span2 { + width: 14.52991452991453%; + *width: 14.476723040552828%; + } + .row-fluid .span1 { + width: 5.982905982905983%; + *width: 5.929714493544281%; + } + .row-fluid .offset12 { + margin-left: 105.12820512820512%; + *margin-left: 105.02182214948171%; + } + .row-fluid .offset12:first-child { + margin-left: 102.56410256410257%; + *margin-left: 102.45771958537915%; + } + .row-fluid .offset11 { + margin-left: 96.58119658119658%; + *margin-left: 96.47481360247316%; + } + .row-fluid .offset11:first-child { + margin-left: 94.01709401709402%; + *margin-left: 93.91071103837061%; + } + .row-fluid .offset10 { + margin-left: 88.03418803418803%; + *margin-left: 87.92780505546462%; + } + .row-fluid .offset10:first-child { + margin-left: 85.47008547008548%; + *margin-left: 85.36370249136206%; + } + .row-fluid .offset9 { + margin-left: 79.48717948717949%; + *margin-left: 79.38079650845607%; + } + .row-fluid .offset9:first-child { + margin-left: 76.92307692307693%; + *margin-left: 76.81669394435352%; + } + .row-fluid .offset8 { + margin-left: 70.94017094017094%; + *margin-left: 70.83378796144753%; + } + .row-fluid .offset8:first-child { + margin-left: 68.37606837606839%; + *margin-left: 68.26968539734497%; + } + .row-fluid .offset7 { + margin-left: 62.393162393162385%; + *margin-left: 62.28677941443899%; + } + .row-fluid .offset7:first-child { + margin-left: 59.82905982905982%; + *margin-left: 59.72267685033642%; + } + .row-fluid .offset6 { + margin-left: 53.84615384615384%; + *margin-left: 53.739770867430444%; + } + .row-fluid .offset6:first-child { + margin-left: 51.28205128205128%; + *margin-left: 51.175668303327875%; + } + .row-fluid .offset5 { + margin-left: 45.299145299145295%; + *margin-left: 45.1927623204219%; + } + .row-fluid .offset5:first-child { + margin-left: 42.73504273504273%; + *margin-left: 42.62865975631933%; + } + .row-fluid .offset4 { + margin-left: 36.75213675213675%; + *margin-left: 36.645753773413354%; + } + .row-fluid .offset4:first-child { + margin-left: 34.18803418803419%; + *margin-left: 34.081651209310785%; + } + .row-fluid .offset3 { + margin-left: 28.205128205128204%; + *margin-left: 28.0987452264048%; + } + .row-fluid .offset3:first-child { + margin-left: 25.641025641025642%; + *margin-left: 25.53464266230224%; + } + .row-fluid .offset2 { + margin-left: 19.65811965811966%; + *margin-left: 19.551736679396257%; + } + .row-fluid .offset2:first-child { + margin-left: 17.094017094017094%; + *margin-left: 16.98763411529369%; + } + .row-fluid .offset1 { + margin-left: 11.11111111111111%; + *margin-left: 11.004728132387708%; + } + .row-fluid .offset1:first-child { + margin-left: 8.547008547008547%; + *margin-left: 8.440625568285142%; + } + input, + textarea, + .uneditable-input { + margin-left: 0; + } + .controls-row [class*="span"] + [class*="span"] { + margin-left: 30px; + } + input.span12, + textarea.span12, + .uneditable-input.span12 { + width: 1156px; + } + input.span11, + textarea.span11, + .uneditable-input.span11 { + width: 1056px; + } + input.span10, + textarea.span10, + .uneditable-input.span10 { + width: 956px; + } + input.span9, + textarea.span9, + .uneditable-input.span9 { + width: 856px; + } + input.span8, + textarea.span8, + .uneditable-input.span8 { + width: 756px; + } + input.span7, + textarea.span7, + .uneditable-input.span7 { + width: 656px; + } + input.span6, + textarea.span6, + .uneditable-input.span6 { + width: 556px; + } + input.span5, + textarea.span5, + .uneditable-input.span5 { + width: 456px; + } + input.span4, + textarea.span4, + .uneditable-input.span4 { + width: 356px; + } + input.span3, + textarea.span3, + .uneditable-input.span3 { + width: 256px; + } + input.span2, + textarea.span2, + .uneditable-input.span2 { + width: 156px; + } + input.span1, + textarea.span1, + .uneditable-input.span1 { + width: 56px; + } + .thumbnails { + margin-left: -30px; + } + .thumbnails > li { + margin-left: 30px; + } + .row-fluid .thumbnails { + margin-left: 0; + } +} + +@media (min-width: 768px) and (max-width: 979px) { + .row { + margin-left: -20px; + *zoom: 1; + } + .row:before, + .row:after { + display: table; + line-height: 0; + content: ""; + } + .row:after { + clear: both; + } + [class*="span"] { + float: left; + min-height: 1px; + margin-left: 20px; + } + .container, + .navbar-static-top .container, + .navbar-fixed-top .container, + .navbar-fixed-bottom .container { + width: 724px; + } + .span12 { + width: 724px; + } + .span11 { + width: 662px; + } + .span10 { + width: 600px; + } + .span9 { + width: 538px; + } + .span8 { + width: 476px; + } + .span7 { + width: 414px; + } + .span6 { + width: 352px; + } + .span5 { + width: 290px; + } + .span4 { + width: 228px; + } + .span3 { + width: 166px; + } + .span2 { + width: 104px; + } + .span1 { + width: 42px; + } + .offset12 { + margin-left: 764px; + } + .offset11 { + margin-left: 702px; + } + .offset10 { + margin-left: 640px; + } + .offset9 { + margin-left: 578px; + } + .offset8 { + margin-left: 516px; + } + .offset7 { + margin-left: 454px; + } + .offset6 { + margin-left: 392px; + } + .offset5 { + margin-left: 330px; + } + .offset4 { + margin-left: 268px; + } + .offset3 { + margin-left: 206px; + } + .offset2 { + margin-left: 144px; + } + .offset1 { + margin-left: 82px; + } + .row-fluid { + width: 100%; + *zoom: 1; + } + .row-fluid:before, + .row-fluid:after { + display: table; + line-height: 0; + content: ""; + } + .row-fluid:after { + clear: both; + } + .row-fluid [class*="span"] { + display: block; + float: left; + width: 100%; + min-height: 30px; + margin-left: 2.7624309392265194%; + *margin-left: 2.709239449864817%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + .row-fluid [class*="span"]:first-child { + margin-left: 0; + } + .row-fluid .controls-row [class*="span"] + [class*="span"] { + margin-left: 2.7624309392265194%; + } + .row-fluid .span12 { + width: 100%; + *width: 99.94680851063829%; + } + .row-fluid .span11 { + width: 91.43646408839778%; + *width: 91.38327259903608%; + } + .row-fluid .span10 { + width: 82.87292817679558%; + *width: 82.81973668743387%; + } + .row-fluid .span9 { + width: 74.30939226519337%; + *width: 74.25620077583166%; + } + .row-fluid .span8 { + width: 65.74585635359117%; + *width: 65.69266486422946%; + } + .row-fluid .span7 { + width: 57.18232044198895%; + *width: 57.12912895262725%; + } + .row-fluid .span6 { + width: 48.61878453038674%; + *width: 48.56559304102504%; + } + .row-fluid .span5 { + width: 40.05524861878453%; + *width: 40.00205712942283%; + } + .row-fluid .span4 { + width: 31.491712707182323%; + *width: 31.43852121782062%; + } + .row-fluid .span3 { + width: 22.92817679558011%; + *width: 22.87498530621841%; + } + .row-fluid .span2 { + width: 14.3646408839779%; + *width: 14.311449394616199%; + } + .row-fluid .span1 { + width: 5.801104972375691%; + *width: 5.747913483013988%; + } + .row-fluid .offset12 { + margin-left: 105.52486187845304%; + *margin-left: 105.41847889972962%; + } + .row-fluid .offset12:first-child { + margin-left: 102.76243093922652%; + *margin-left: 102.6560479605031%; + } + .row-fluid .offset11 { + margin-left: 96.96132596685082%; + *margin-left: 96.8549429881274%; + } + .row-fluid .offset11:first-child { + margin-left: 94.1988950276243%; + *margin-left: 94.09251204890089%; + } + .row-fluid .offset10 { + margin-left: 88.39779005524862%; + *margin-left: 88.2914070765252%; + } + .row-fluid .offset10:first-child { + margin-left: 85.6353591160221%; + *margin-left: 85.52897613729868%; + } + .row-fluid .offset9 { + margin-left: 79.8342541436464%; + *margin-left: 79.72787116492299%; + } + .row-fluid .offset9:first-child { + margin-left: 77.07182320441989%; + *margin-left: 76.96544022569647%; + } + .row-fluid .offset8 { + margin-left: 71.2707182320442%; + *margin-left: 71.16433525332079%; + } + .row-fluid .offset8:first-child { + margin-left: 68.50828729281768%; + *margin-left: 68.40190431409427%; + } + .row-fluid .offset7 { + margin-left: 62.70718232044199%; + *margin-left: 62.600799341718584%; + } + .row-fluid .offset7:first-child { + margin-left: 59.94475138121547%; + *margin-left: 59.838368402492065%; + } + .row-fluid .offset6 { + margin-left: 54.14364640883978%; + *margin-left: 54.037263430116376%; + } + .row-fluid .offset6:first-child { + margin-left: 51.38121546961326%; + *margin-left: 51.27483249088986%; + } + .row-fluid .offset5 { + margin-left: 45.58011049723757%; + *margin-left: 45.47372751851417%; + } + .row-fluid .offset5:first-child { + margin-left: 42.81767955801105%; + *margin-left: 42.71129657928765%; + } + .row-fluid .offset4 { + margin-left: 37.01657458563536%; + *margin-left: 36.91019160691196%; + } + .row-fluid .offset4:first-child { + margin-left: 34.25414364640884%; + *margin-left: 34.14776066768544%; + } + .row-fluid .offset3 { + margin-left: 28.45303867403315%; + *margin-left: 28.346655695309746%; + } + .row-fluid .offset3:first-child { + margin-left: 25.69060773480663%; + *margin-left: 25.584224756083227%; + } + .row-fluid .offset2 { + margin-left: 19.88950276243094%; + *margin-left: 19.783119783707537%; + } + .row-fluid .offset2:first-child { + margin-left: 17.12707182320442%; + *margin-left: 17.02068884448102%; + } + .row-fluid .offset1 { + margin-left: 11.32596685082873%; + *margin-left: 11.219583872105325%; + } + .row-fluid .offset1:first-child { + margin-left: 8.56353591160221%; + *margin-left: 8.457152932878806%; + } + input, + textarea, + .uneditable-input { + margin-left: 0; + } + .controls-row [class*="span"] + [class*="span"] { + margin-left: 20px; + } + input.span12, + textarea.span12, + .uneditable-input.span12 { + width: 710px; + } + input.span11, + textarea.span11, + .uneditable-input.span11 { + width: 648px; + } + input.span10, + textarea.span10, + .uneditable-input.span10 { + width: 586px; + } + input.span9, + textarea.span9, + .uneditable-input.span9 { + width: 524px; + } + input.span8, + textarea.span8, + .uneditable-input.span8 { + width: 462px; + } + input.span7, + textarea.span7, + .uneditable-input.span7 { + width: 400px; + } + input.span6, + textarea.span6, + .uneditable-input.span6 { + width: 338px; + } + input.span5, + textarea.span5, + .uneditable-input.span5 { + width: 276px; + } + input.span4, + textarea.span4, + .uneditable-input.span4 { + width: 214px; + } + input.span3, + textarea.span3, + .uneditable-input.span3 { + width: 152px; + } + input.span2, + textarea.span2, + .uneditable-input.span2 { + width: 90px; + } + input.span1, + textarea.span1, + .uneditable-input.span1 { + width: 28px; + } +} + +@media (max-width: 767px) { + body { + padding-right: 20px; + padding-left: 20px; + } + .navbar-fixed-top, + .navbar-fixed-bottom, + .navbar-static-top { + margin-right: -20px; + margin-left: -20px; + } + .container-fluid { + padding: 0; + } + .dl-horizontal dt { + float: none; + width: auto; + clear: none; + text-align: left; + } + .dl-horizontal dd { + margin-left: 0; + } + .container { + width: auto; + } + .row-fluid { + width: 100%; + } + .row, + .thumbnails { + margin-left: 0; + } + .thumbnails > li { + float: none; + margin-left: 0; + } + [class*="span"], + .uneditable-input[class*="span"], + .row-fluid [class*="span"] { + display: block; + float: none; + width: 100%; + margin-left: 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + .span12, + .row-fluid .span12 { + width: 100%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + .row-fluid [class*="offset"]:first-child { + margin-left: 0; + } + .input-large, + .input-xlarge, + .input-xxlarge, + input[class*="span"], + select[class*="span"], + textarea[class*="span"], + .uneditable-input { + display: block; + width: 100%; + min-height: 30px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + .input-prepend input, + .input-append input, + .input-prepend input[class*="span"], + .input-append input[class*="span"] { + display: inline-block; + width: auto; + } + .controls-row [class*="span"] + [class*="span"] { + margin-left: 0; + } + .modal { + position: fixed; + top: 20px; + right: 20px; + left: 20px; + width: auto; + margin: 0; + } + .modal.fade { + top: -100px; + } + .modal.fade.in { + top: 20px; + } +} + +@media (max-width: 480px) { + .nav-collapse { + -webkit-transform: translate3d(0, 0, 0); + } + .page-header h1 small { + display: block; + line-height: 20px; + } + input[type="checkbox"], + input[type="radio"] { + border: 1px solid #ccc; + } + .form-horizontal .control-label { + float: none; + width: auto; + padding-top: 0; + text-align: left; + } + .form-horizontal .controls { + margin-left: 0; + } + .form-horizontal .control-list { + padding-top: 0; + } + .form-horizontal .form-actions { + padding-right: 10px; + padding-left: 10px; + } + .media .pull-left, + .media .pull-right { + display: block; + float: none; + margin-bottom: 10px; + } + .media-object { + margin-right: 0; + margin-left: 0; + } + .modal { + top: 10px; + right: 10px; + left: 10px; + } + .modal-header .close { + padding: 10px; + margin: -10px; + } + .carousel-caption { + position: static; + } +} + +@media (max-width: 979px) { + body { + padding-top: 0; + } + .navbar-fixed-top, + .navbar-fixed-bottom { + position: static; + } + .navbar-fixed-top { + margin-bottom: 20px; + } + .navbar-fixed-bottom { + margin-top: 20px; + } + .navbar-fixed-top .navbar-inner, + .navbar-fixed-bottom .navbar-inner { + padding: 5px; + } + .navbar .container { + width: auto; + padding: 0; + } + .navbar .brand { + padding-right: 10px; + padding-left: 10px; + margin: 0 0 0 -5px; + } + .nav-collapse { + clear: both; + } + .nav-collapse .nav { + float: none; + margin: 0 0 10px; + } + .nav-collapse .nav > li { + float: none; + } + .nav-collapse .nav > li > a { + margin-bottom: 2px; + } + .nav-collapse .nav > .divider-vertical { + display: none; + } + .nav-collapse .nav .nav-header { + color: #777777; + text-shadow: none; + } + .nav-collapse .nav > li > a, + .nav-collapse .dropdown-menu a { + padding: 9px 15px; + font-weight: bold; + color: #777777; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + } + .nav-collapse .btn { + padding: 4px 10px 4px; + font-weight: normal; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + } + .nav-collapse .dropdown-menu li + li a { + margin-bottom: 2px; + } + .nav-collapse .nav > li > a:hover, + .nav-collapse .nav > li > a:focus, + .nav-collapse .dropdown-menu a:hover, + .nav-collapse .dropdown-menu a:focus { + background-color: #f2f2f2; + } + .navbar-inverse .nav-collapse .nav > li > a, + .navbar-inverse .nav-collapse .dropdown-menu a { + color: #999999; + } + .navbar-inverse .nav-collapse .nav > li > a:hover, + .navbar-inverse .nav-collapse .nav > li > a:focus, + .navbar-inverse .nav-collapse .dropdown-menu a:hover, + .navbar-inverse .nav-collapse .dropdown-menu a:focus { + background-color: #111111; + } + .nav-collapse.in .btn-group { + padding: 0; + margin-top: 5px; + } + .nav-collapse .dropdown-menu { + position: static; + top: auto; + left: auto; + display: none; + float: none; + max-width: none; + padding: 0; + margin: 0 15px; + background-color: transparent; + border: none; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; + } + .nav-collapse .open > .dropdown-menu { + display: block; + } + .nav-collapse .dropdown-menu:before, + .nav-collapse .dropdown-menu:after { + display: none; + } + .nav-collapse .dropdown-menu .divider { + display: none; + } + .nav-collapse .nav > li > .dropdown-menu:before, + .nav-collapse .nav > li > .dropdown-menu:after { + display: none; + } + .nav-collapse .navbar-form, + .nav-collapse .navbar-search { + float: none; + padding: 10px 15px; + margin: 10px 0; + border-top: 1px solid #f2f2f2; + border-bottom: 1px solid #f2f2f2; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); + -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); + } + .navbar-inverse .nav-collapse .navbar-form, + .navbar-inverse .nav-collapse .navbar-search { + border-top-color: #111111; + border-bottom-color: #111111; + } + .navbar .nav-collapse .nav.pull-right { + float: none; + margin-left: 0; + } + .nav-collapse, + .nav-collapse.collapse { + height: 0; + overflow: hidden; + } + .navbar .btn-navbar { + display: block; + } + .navbar-static .navbar-inner { + padding-right: 10px; + padding-left: 10px; + } +} + +@media (min-width: 980px) { + .nav-collapse.collapse { + height: auto !important; + overflow: visible !important; + } +} diff --git a/docs/_static/bootstrap-2.3.2/css/bootstrap-responsive.min.css b/docs/_static/bootstrap-2.3.2/css/bootstrap-responsive.min.css new file mode 100644 index 00000000..f4ede63f --- /dev/null +++ b/docs/_static/bootstrap-2.3.2/css/bootstrap-responsive.min.css @@ -0,0 +1,9 @@ +/*! + * Bootstrap Responsive v2.3.2 + * + * Copyright 2012 Twitter, Inc + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Designed and built with all the love in the world @twitter by @mdo and @fat. + */.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;line-height:0;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}@-ms-viewport{width:device-width}.hidden{display:none;visibility:hidden}.visible-phone{display:none!important}.visible-tablet{display:none!important}.hidden-desktop{display:none!important}.visible-desktop{display:inherit!important}@media(min-width:768px) and (max-width:979px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-tablet{display:inherit!important}.hidden-tablet{display:none!important}}@media(max-width:767px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-phone{display:inherit!important}.hidden-phone{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:inherit!important}.hidden-print{display:none!important}}@media(min-width:1200px){.row{margin-left:-30px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:30px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:1170px}.span12{width:1170px}.span11{width:1070px}.span10{width:970px}.span9{width:870px}.span8{width:770px}.span7{width:670px}.span6{width:570px}.span5{width:470px}.span4{width:370px}.span3{width:270px}.span2{width:170px}.span1{width:70px}.offset12{margin-left:1230px}.offset11{margin-left:1130px}.offset10{margin-left:1030px}.offset9{margin-left:930px}.offset8{margin-left:830px}.offset7{margin-left:730px}.offset6{margin-left:630px}.offset5{margin-left:530px}.offset4{margin-left:430px}.offset3{margin-left:330px}.offset2{margin-left:230px}.offset1{margin-left:130px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.564102564102564%;*margin-left:2.5109110747408616%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.564102564102564%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.45299145299145%;*width:91.39979996362975%}.row-fluid .span10{width:82.90598290598291%;*width:82.8527914166212%}.row-fluid .span9{width:74.35897435897436%;*width:74.30578286961266%}.row-fluid .span8{width:65.81196581196582%;*width:65.75877432260411%}.row-fluid .span7{width:57.26495726495726%;*width:57.21176577559556%}.row-fluid .span6{width:48.717948717948715%;*width:48.664757228587014%}.row-fluid .span5{width:40.17094017094017%;*width:40.11774868157847%}.row-fluid .span4{width:31.623931623931625%;*width:31.570740134569924%}.row-fluid .span3{width:23.076923076923077%;*width:23.023731587561375%}.row-fluid .span2{width:14.52991452991453%;*width:14.476723040552828%}.row-fluid .span1{width:5.982905982905983%;*width:5.929714493544281%}.row-fluid .offset12{margin-left:105.12820512820512%;*margin-left:105.02182214948171%}.row-fluid .offset12:first-child{margin-left:102.56410256410257%;*margin-left:102.45771958537915%}.row-fluid .offset11{margin-left:96.58119658119658%;*margin-left:96.47481360247316%}.row-fluid .offset11:first-child{margin-left:94.01709401709402%;*margin-left:93.91071103837061%}.row-fluid .offset10{margin-left:88.03418803418803%;*margin-left:87.92780505546462%}.row-fluid .offset10:first-child{margin-left:85.47008547008548%;*margin-left:85.36370249136206%}.row-fluid .offset9{margin-left:79.48717948717949%;*margin-left:79.38079650845607%}.row-fluid .offset9:first-child{margin-left:76.92307692307693%;*margin-left:76.81669394435352%}.row-fluid .offset8{margin-left:70.94017094017094%;*margin-left:70.83378796144753%}.row-fluid .offset8:first-child{margin-left:68.37606837606839%;*margin-left:68.26968539734497%}.row-fluid .offset7{margin-left:62.393162393162385%;*margin-left:62.28677941443899%}.row-fluid .offset7:first-child{margin-left:59.82905982905982%;*margin-left:59.72267685033642%}.row-fluid .offset6{margin-left:53.84615384615384%;*margin-left:53.739770867430444%}.row-fluid .offset6:first-child{margin-left:51.28205128205128%;*margin-left:51.175668303327875%}.row-fluid .offset5{margin-left:45.299145299145295%;*margin-left:45.1927623204219%}.row-fluid .offset5:first-child{margin-left:42.73504273504273%;*margin-left:42.62865975631933%}.row-fluid .offset4{margin-left:36.75213675213675%;*margin-left:36.645753773413354%}.row-fluid .offset4:first-child{margin-left:34.18803418803419%;*margin-left:34.081651209310785%}.row-fluid .offset3{margin-left:28.205128205128204%;*margin-left:28.0987452264048%}.row-fluid .offset3:first-child{margin-left:25.641025641025642%;*margin-left:25.53464266230224%}.row-fluid .offset2{margin-left:19.65811965811966%;*margin-left:19.551736679396257%}.row-fluid .offset2:first-child{margin-left:17.094017094017094%;*margin-left:16.98763411529369%}.row-fluid .offset1{margin-left:11.11111111111111%;*margin-left:11.004728132387708%}.row-fluid .offset1:first-child{margin-left:8.547008547008547%;*margin-left:8.440625568285142%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:30px}input.span12,textarea.span12,.uneditable-input.span12{width:1156px}input.span11,textarea.span11,.uneditable-input.span11{width:1056px}input.span10,textarea.span10,.uneditable-input.span10{width:956px}input.span9,textarea.span9,.uneditable-input.span9{width:856px}input.span8,textarea.span8,.uneditable-input.span8{width:756px}input.span7,textarea.span7,.uneditable-input.span7{width:656px}input.span6,textarea.span6,.uneditable-input.span6{width:556px}input.span5,textarea.span5,.uneditable-input.span5{width:456px}input.span4,textarea.span4,.uneditable-input.span4{width:356px}input.span3,textarea.span3,.uneditable-input.span3{width:256px}input.span2,textarea.span2,.uneditable-input.span2{width:156px}input.span1,textarea.span1,.uneditable-input.span1{width:56px}.thumbnails{margin-left:-30px}.thumbnails>li{margin-left:30px}.row-fluid .thumbnails{margin-left:0}}@media(min-width:768px) and (max-width:979px){.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:724px}.span12{width:724px}.span11{width:662px}.span10{width:600px}.span9{width:538px}.span8{width:476px}.span7{width:414px}.span6{width:352px}.span5{width:290px}.span4{width:228px}.span3{width:166px}.span2{width:104px}.span1{width:42px}.offset12{margin-left:764px}.offset11{margin-left:702px}.offset10{margin-left:640px}.offset9{margin-left:578px}.offset8{margin-left:516px}.offset7{margin-left:454px}.offset6{margin-left:392px}.offset5{margin-left:330px}.offset4{margin-left:268px}.offset3{margin-left:206px}.offset2{margin-left:144px}.offset1{margin-left:82px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.7624309392265194%;*margin-left:2.709239449864817%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.7624309392265194%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.43646408839778%;*width:91.38327259903608%}.row-fluid .span10{width:82.87292817679558%;*width:82.81973668743387%}.row-fluid .span9{width:74.30939226519337%;*width:74.25620077583166%}.row-fluid .span8{width:65.74585635359117%;*width:65.69266486422946%}.row-fluid .span7{width:57.18232044198895%;*width:57.12912895262725%}.row-fluid .span6{width:48.61878453038674%;*width:48.56559304102504%}.row-fluid .span5{width:40.05524861878453%;*width:40.00205712942283%}.row-fluid .span4{width:31.491712707182323%;*width:31.43852121782062%}.row-fluid .span3{width:22.92817679558011%;*width:22.87498530621841%}.row-fluid .span2{width:14.3646408839779%;*width:14.311449394616199%}.row-fluid .span1{width:5.801104972375691%;*width:5.747913483013988%}.row-fluid .offset12{margin-left:105.52486187845304%;*margin-left:105.41847889972962%}.row-fluid .offset12:first-child{margin-left:102.76243093922652%;*margin-left:102.6560479605031%}.row-fluid .offset11{margin-left:96.96132596685082%;*margin-left:96.8549429881274%}.row-fluid .offset11:first-child{margin-left:94.1988950276243%;*margin-left:94.09251204890089%}.row-fluid .offset10{margin-left:88.39779005524862%;*margin-left:88.2914070765252%}.row-fluid .offset10:first-child{margin-left:85.6353591160221%;*margin-left:85.52897613729868%}.row-fluid .offset9{margin-left:79.8342541436464%;*margin-left:79.72787116492299%}.row-fluid .offset9:first-child{margin-left:77.07182320441989%;*margin-left:76.96544022569647%}.row-fluid .offset8{margin-left:71.2707182320442%;*margin-left:71.16433525332079%}.row-fluid .offset8:first-child{margin-left:68.50828729281768%;*margin-left:68.40190431409427%}.row-fluid .offset7{margin-left:62.70718232044199%;*margin-left:62.600799341718584%}.row-fluid .offset7:first-child{margin-left:59.94475138121547%;*margin-left:59.838368402492065%}.row-fluid .offset6{margin-left:54.14364640883978%;*margin-left:54.037263430116376%}.row-fluid .offset6:first-child{margin-left:51.38121546961326%;*margin-left:51.27483249088986%}.row-fluid .offset5{margin-left:45.58011049723757%;*margin-left:45.47372751851417%}.row-fluid .offset5:first-child{margin-left:42.81767955801105%;*margin-left:42.71129657928765%}.row-fluid .offset4{margin-left:37.01657458563536%;*margin-left:36.91019160691196%}.row-fluid .offset4:first-child{margin-left:34.25414364640884%;*margin-left:34.14776066768544%}.row-fluid .offset3{margin-left:28.45303867403315%;*margin-left:28.346655695309746%}.row-fluid .offset3:first-child{margin-left:25.69060773480663%;*margin-left:25.584224756083227%}.row-fluid .offset2{margin-left:19.88950276243094%;*margin-left:19.783119783707537%}.row-fluid .offset2:first-child{margin-left:17.12707182320442%;*margin-left:17.02068884448102%}.row-fluid .offset1{margin-left:11.32596685082873%;*margin-left:11.219583872105325%}.row-fluid .offset1:first-child{margin-left:8.56353591160221%;*margin-left:8.457152932878806%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:710px}input.span11,textarea.span11,.uneditable-input.span11{width:648px}input.span10,textarea.span10,.uneditable-input.span10{width:586px}input.span9,textarea.span9,.uneditable-input.span9{width:524px}input.span8,textarea.span8,.uneditable-input.span8{width:462px}input.span7,textarea.span7,.uneditable-input.span7{width:400px}input.span6,textarea.span6,.uneditable-input.span6{width:338px}input.span5,textarea.span5,.uneditable-input.span5{width:276px}input.span4,textarea.span4,.uneditable-input.span4{width:214px}input.span3,textarea.span3,.uneditable-input.span3{width:152px}input.span2,textarea.span2,.uneditable-input.span2{width:90px}input.span1,textarea.span1,.uneditable-input.span1{width:28px}}@media(max-width:767px){body{padding-right:20px;padding-left:20px}.navbar-fixed-top,.navbar-fixed-bottom,.navbar-static-top{margin-right:-20px;margin-left:-20px}.container-fluid{padding:0}.dl-horizontal dt{float:none;width:auto;clear:none;text-align:left}.dl-horizontal dd{margin-left:0}.container{width:auto}.row-fluid{width:100%}.row,.thumbnails{margin-left:0}.thumbnails>li{float:none;margin-left:0}[class*="span"],.uneditable-input[class*="span"],.row-fluid [class*="span"]{display:block;float:none;width:100%;margin-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.span12,.row-fluid .span12{width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="offset"]:first-child{margin-left:0}.input-large,.input-xlarge,.input-xxlarge,input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.input-prepend input,.input-append input,.input-prepend input[class*="span"],.input-append input[class*="span"]{display:inline-block;width:auto}.controls-row [class*="span"]+[class*="span"]{margin-left:0}.modal{position:fixed;top:20px;right:20px;left:20px;width:auto;margin:0}.modal.fade{top:-100px}.modal.fade.in{top:20px}}@media(max-width:480px){.nav-collapse{-webkit-transform:translate3d(0,0,0)}.page-header h1 small{display:block;line-height:20px}input[type="checkbox"],input[type="radio"]{border:1px solid #ccc}.form-horizontal .control-label{float:none;width:auto;padding-top:0;text-align:left}.form-horizontal .controls{margin-left:0}.form-horizontal .control-list{padding-top:0}.form-horizontal .form-actions{padding-right:10px;padding-left:10px}.media .pull-left,.media .pull-right{display:block;float:none;margin-bottom:10px}.media-object{margin-right:0;margin-left:0}.modal{top:10px;right:10px;left:10px}.modal-header .close{padding:10px;margin:-10px}.carousel-caption{position:static}}@media(max-width:979px){body{padding-top:0}.navbar-fixed-top,.navbar-fixed-bottom{position:static}.navbar-fixed-top{margin-bottom:20px}.navbar-fixed-bottom{margin-top:20px}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding:5px}.navbar .container{width:auto;padding:0}.navbar .brand{padding-right:10px;padding-left:10px;margin:0 0 0 -5px}.nav-collapse{clear:both}.nav-collapse .nav{float:none;margin:0 0 10px}.nav-collapse .nav>li{float:none}.nav-collapse .nav>li>a{margin-bottom:2px}.nav-collapse .nav>.divider-vertical{display:none}.nav-collapse .nav .nav-header{color:#777;text-shadow:none}.nav-collapse .nav>li>a,.nav-collapse .dropdown-menu a{padding:9px 15px;font-weight:bold;color:#777;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.nav-collapse .btn{padding:4px 10px 4px;font-weight:normal;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.nav-collapse .dropdown-menu li+li a{margin-bottom:2px}.nav-collapse .nav>li>a:hover,.nav-collapse .nav>li>a:focus,.nav-collapse .dropdown-menu a:hover,.nav-collapse .dropdown-menu a:focus{background-color:#f2f2f2}.navbar-inverse .nav-collapse .nav>li>a,.navbar-inverse .nav-collapse .dropdown-menu a{color:#999}.navbar-inverse .nav-collapse .nav>li>a:hover,.navbar-inverse .nav-collapse .nav>li>a:focus,.navbar-inverse .nav-collapse .dropdown-menu a:hover,.navbar-inverse .nav-collapse .dropdown-menu a:focus{background-color:#111}.nav-collapse.in .btn-group{padding:0;margin-top:5px}.nav-collapse .dropdown-menu{position:static;top:auto;left:auto;display:none;float:none;max-width:none;padding:0;margin:0 15px;background-color:transparent;border:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.nav-collapse .open>.dropdown-menu{display:block}.nav-collapse .dropdown-menu:before,.nav-collapse .dropdown-menu:after{display:none}.nav-collapse .dropdown-menu .divider{display:none}.nav-collapse .nav>li>.dropdown-menu:before,.nav-collapse .nav>li>.dropdown-menu:after{display:none}.nav-collapse .navbar-form,.nav-collapse .navbar-search{float:none;padding:10px 15px;margin:10px 0;border-top:1px solid #f2f2f2;border-bottom:1px solid #f2f2f2;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1)}.navbar-inverse .nav-collapse .navbar-form,.navbar-inverse .nav-collapse .navbar-search{border-top-color:#111;border-bottom-color:#111}.navbar .nav-collapse .nav.pull-right{float:none;margin-left:0}.nav-collapse,.nav-collapse.collapse{height:0;overflow:hidden}.navbar .btn-navbar{display:block}.navbar-static .navbar-inner{padding-right:10px;padding-left:10px}}@media(min-width:980px){.nav-collapse.collapse{height:auto!important;overflow:visible!important}} diff --git a/docs/_static/bootstrap-2.3.2/css/bootstrap.css b/docs/_static/bootstrap-2.3.2/css/bootstrap.css new file mode 100644 index 00000000..b725064a --- /dev/null +++ b/docs/_static/bootstrap-2.3.2/css/bootstrap.css @@ -0,0 +1,6167 @@ +/*! + * Bootstrap v2.3.2 + * + * Copyright 2012 Twitter, Inc + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Designed and built with all the love in the world @twitter by @mdo and @fat. + */ + +.clearfix { + *zoom: 1; +} + +.clearfix:before, +.clearfix:after { + display: table; + line-height: 0; + content: ""; +} + +.clearfix:after { + clear: both; +} + +.hide-text { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} + +.input-block-level { + display: block; + width: 100%; + min-height: 30px; + -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; +} + +html { + font-size: 100%; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; +} + +a:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} + +a:hover, +a:active { + outline: 0; +} + +sub, +sup { + position: relative; + font-size: 75%; + line-height: 0; + vertical-align: baseline; +} + +sup { + top: -0.5em; +} + +sub { + bottom: -0.25em; +} + +img { + width: auto\9; + height: auto; + max-width: 100%; + vertical-align: middle; + border: 0; + -ms-interpolation-mode: bicubic; +} + +#map_canvas img, +.google-maps img { + max-width: none; +} + +button, +input, +select, +textarea { + margin: 0; + font-size: 100%; + vertical-align: middle; +} + +button, +input { + *overflow: visible; + line-height: normal; +} + +button::-moz-focus-inner, +input::-moz-focus-inner { + padding: 0; + border: 0; +} + +button, +html input[type="button"], +input[type="reset"], +input[type="submit"] { + cursor: pointer; + -webkit-appearance: button; +} + +label, +select, +button, +input[type="button"], +input[type="reset"], +input[type="submit"], +input[type="radio"], +input[type="checkbox"] { + cursor: pointer; +} + +input[type="search"] { + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + -webkit-appearance: textfield; +} + +input[type="search"]::-webkit-search-decoration, +input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; +} + +textarea { + overflow: auto; + vertical-align: top; +} + +@media print { + * { + color: #000 !important; + text-shadow: none !important; + background: transparent !important; + box-shadow: none !important; + } + a, + a:visited { + text-decoration: underline; + } + a[href]:after { + content: " (" attr(href) ")"; + } + abbr[title]:after { + content: " (" attr(title) ")"; + } + .ir a:after, + a[href^="javascript:"]:after, + a[href^="#"]:after { + content: ""; + } + pre, + blockquote { + border: 1px solid #999; + 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, + h3 { + orphans: 3; + widows: 3; + } + h2, + h3 { + page-break-after: avoid; + } +} + +body { + margin: 0; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + line-height: 20px; + color: #333333; + background-color: #ffffff; +} + +a { + color: #0088cc; + text-decoration: none; +} + +a:hover, +a:focus { + color: #005580; + text-decoration: underline; +} + +.img-rounded { + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} + +.img-polaroid { + padding: 4px; + background-color: #fff; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); +} + +.img-circle { + -webkit-border-radius: 500px; + -moz-border-radius: 500px; + border-radius: 500px; +} + +.row { + margin-left: -20px; + *zoom: 1; +} + +.row:before, +.row:after { + display: table; + line-height: 0; + content: ""; +} + +.row:after { + clear: both; +} + +[class*="span"] { + float: left; + min-height: 1px; + margin-left: 20px; +} + +.container, +.navbar-static-top .container, +.navbar-fixed-top .container, +.navbar-fixed-bottom .container { + width: 940px; +} + +.span12 { + width: 940px; +} + +.span11 { + width: 860px; +} + +.span10 { + width: 780px; +} + +.span9 { + width: 700px; +} + +.span8 { + width: 620px; +} + +.span7 { + width: 540px; +} + +.span6 { + width: 460px; +} + +.span5 { + width: 380px; +} + +.span4 { + width: 300px; +} + +.span3 { + width: 220px; +} + +.span2 { + width: 140px; +} + +.span1 { + width: 60px; +} + +.offset12 { + margin-left: 980px; +} + +.offset11 { + margin-left: 900px; +} + +.offset10 { + margin-left: 820px; +} + +.offset9 { + margin-left: 740px; +} + +.offset8 { + margin-left: 660px; +} + +.offset7 { + margin-left: 580px; +} + +.offset6 { + margin-left: 500px; +} + +.offset5 { + margin-left: 420px; +} + +.offset4 { + margin-left: 340px; +} + +.offset3 { + margin-left: 260px; +} + +.offset2 { + margin-left: 180px; +} + +.offset1 { + margin-left: 100px; +} + +.row-fluid { + width: 100%; + *zoom: 1; +} + +.row-fluid:before, +.row-fluid:after { + display: table; + line-height: 0; + content: ""; +} + +.row-fluid:after { + clear: both; +} + +.row-fluid [class*="span"] { + display: block; + float: left; + width: 100%; + min-height: 30px; + margin-left: 2.127659574468085%; + *margin-left: 2.074468085106383%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.row-fluid [class*="span"]:first-child { + margin-left: 0; +} + +.row-fluid .controls-row [class*="span"] + [class*="span"] { + margin-left: 2.127659574468085%; +} + +.row-fluid .span12 { + width: 100%; + *width: 99.94680851063829%; +} + +.row-fluid .span11 { + width: 91.48936170212765%; + *width: 91.43617021276594%; +} + +.row-fluid .span10 { + width: 82.97872340425532%; + *width: 82.92553191489361%; +} + +.row-fluid .span9 { + width: 74.46808510638297%; + *width: 74.41489361702126%; +} + +.row-fluid .span8 { + width: 65.95744680851064%; + *width: 65.90425531914893%; +} + +.row-fluid .span7 { + width: 57.44680851063829%; + *width: 57.39361702127659%; +} + +.row-fluid .span6 { + width: 48.93617021276595%; + *width: 48.88297872340425%; +} + +.row-fluid .span5 { + width: 40.42553191489362%; + *width: 40.37234042553192%; +} + +.row-fluid .span4 { + width: 31.914893617021278%; + *width: 31.861702127659576%; +} + +.row-fluid .span3 { + width: 23.404255319148934%; + *width: 23.351063829787233%; +} + +.row-fluid .span2 { + width: 14.893617021276595%; + *width: 14.840425531914894%; +} + +.row-fluid .span1 { + width: 6.382978723404255%; + *width: 6.329787234042553%; +} + +.row-fluid .offset12 { + margin-left: 104.25531914893617%; + *margin-left: 104.14893617021275%; +} + +.row-fluid .offset12:first-child { + margin-left: 102.12765957446808%; + *margin-left: 102.02127659574467%; +} + +.row-fluid .offset11 { + margin-left: 95.74468085106382%; + *margin-left: 95.6382978723404%; +} + +.row-fluid .offset11:first-child { + margin-left: 93.61702127659574%; + *margin-left: 93.51063829787232%; +} + +.row-fluid .offset10 { + margin-left: 87.23404255319149%; + *margin-left: 87.12765957446807%; +} + +.row-fluid .offset10:first-child { + margin-left: 85.1063829787234%; + *margin-left: 84.99999999999999%; +} + +.row-fluid .offset9 { + margin-left: 78.72340425531914%; + *margin-left: 78.61702127659572%; +} + +.row-fluid .offset9:first-child { + margin-left: 76.59574468085106%; + *margin-left: 76.48936170212764%; +} + +.row-fluid .offset8 { + margin-left: 70.2127659574468%; + *margin-left: 70.10638297872339%; +} + +.row-fluid .offset8:first-child { + margin-left: 68.08510638297872%; + *margin-left: 67.9787234042553%; +} + +.row-fluid .offset7 { + margin-left: 61.70212765957446%; + *margin-left: 61.59574468085106%; +} + +.row-fluid .offset7:first-child { + margin-left: 59.574468085106375%; + *margin-left: 59.46808510638297%; +} + +.row-fluid .offset6 { + margin-left: 53.191489361702125%; + *margin-left: 53.085106382978715%; +} + +.row-fluid .offset6:first-child { + margin-left: 51.063829787234035%; + *margin-left: 50.95744680851063%; +} + +.row-fluid .offset5 { + margin-left: 44.68085106382979%; + *margin-left: 44.57446808510638%; +} + +.row-fluid .offset5:first-child { + margin-left: 42.5531914893617%; + *margin-left: 42.4468085106383%; +} + +.row-fluid .offset4 { + margin-left: 36.170212765957444%; + *margin-left: 36.06382978723405%; +} + +.row-fluid .offset4:first-child { + margin-left: 34.04255319148936%; + *margin-left: 33.93617021276596%; +} + +.row-fluid .offset3 { + margin-left: 27.659574468085104%; + *margin-left: 27.5531914893617%; +} + +.row-fluid .offset3:first-child { + margin-left: 25.53191489361702%; + *margin-left: 25.425531914893618%; +} + +.row-fluid .offset2 { + margin-left: 19.148936170212764%; + *margin-left: 19.04255319148936%; +} + +.row-fluid .offset2:first-child { + margin-left: 17.02127659574468%; + *margin-left: 16.914893617021278%; +} + +.row-fluid .offset1 { + margin-left: 10.638297872340425%; + *margin-left: 10.53191489361702%; +} + +.row-fluid .offset1:first-child { + margin-left: 8.51063829787234%; + *margin-left: 8.404255319148938%; +} + +[class*="span"].hide, +.row-fluid [class*="span"].hide { + display: none; +} + +[class*="span"].pull-right, +.row-fluid [class*="span"].pull-right { + float: right; +} + +.container { + margin-right: auto; + margin-left: auto; + *zoom: 1; +} + +.container:before, +.container:after { + display: table; + line-height: 0; + content: ""; +} + +.container:after { + clear: both; +} + +.container-fluid { + padding-right: 20px; + padding-left: 20px; + *zoom: 1; +} + +.container-fluid:before, +.container-fluid:after { + display: table; + line-height: 0; + content: ""; +} + +.container-fluid:after { + clear: both; +} + +p { + margin: 0 0 10px; +} + +.lead { + margin-bottom: 20px; + font-size: 21px; + font-weight: 200; + line-height: 30px; +} + +small { + font-size: 85%; +} + +strong { + font-weight: bold; +} + +em { + font-style: italic; +} + +cite { + font-style: normal; +} + +.muted { + color: #999999; +} + +a.muted:hover, +a.muted:focus { + color: #808080; +} + +.text-warning { + color: #c09853; +} + +a.text-warning:hover, +a.text-warning:focus { + color: #a47e3c; +} + +.text-error { + color: #b94a48; +} + +a.text-error:hover, +a.text-error:focus { + color: #953b39; +} + +.text-info { + color: #3a87ad; +} + +a.text-info:hover, +a.text-info:focus { + color: #2d6987; +} + +.text-success { + color: #468847; +} + +a.text-success:hover, +a.text-success:focus { + color: #356635; +} + +.text-left { + text-align: left; +} + +.text-right { + text-align: right; +} + +.text-center { + text-align: center; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + margin: 10px 0; + font-family: inherit; + font-weight: bold; + line-height: 20px; + color: inherit; + text-rendering: optimizelegibility; +} + +h1 small, +h2 small, +h3 small, +h4 small, +h5 small, +h6 small { + font-weight: normal; + line-height: 1; + color: #999999; +} + +h1, +h2, +h3 { + line-height: 40px; +} + +h1 { + font-size: 38.5px; +} + +h2 { + font-size: 31.5px; +} + +h3 { + font-size: 24.5px; +} + +h4 { + font-size: 17.5px; +} + +h5 { + font-size: 14px; +} + +h6 { + font-size: 11.9px; +} + +h1 small { + font-size: 24.5px; +} + +h2 small { + font-size: 17.5px; +} + +h3 small { + font-size: 14px; +} + +h4 small { + font-size: 14px; +} + +.page-header { + padding-bottom: 9px; + margin: 20px 0 30px; + border-bottom: 1px solid #eeeeee; +} + +ul, +ol { + padding: 0; + margin: 0 0 10px 25px; +} + +ul ul, +ul ol, +ol ol, +ol ul { + margin-bottom: 0; +} + +li { + line-height: 20px; +} + +ul.unstyled, +ol.unstyled { + margin-left: 0; + list-style: none; +} + +ul.inline, +ol.inline { + margin-left: 0; + list-style: none; +} + +ul.inline > li, +ol.inline > li { + display: inline-block; + *display: inline; + padding-right: 5px; + padding-left: 5px; + *zoom: 1; +} + +dl { + margin-bottom: 20px; +} + +dt, +dd { + line-height: 20px; +} + +dt { + font-weight: bold; +} + +dd { + margin-left: 10px; +} + +.dl-horizontal { + *zoom: 1; +} + +.dl-horizontal:before, +.dl-horizontal:after { + display: table; + line-height: 0; + content: ""; +} + +.dl-horizontal:after { + clear: both; +} + +.dl-horizontal dt { + float: left; + width: 160px; + overflow: hidden; + clear: left; + text-align: right; + text-overflow: ellipsis; + white-space: nowrap; +} + +.dl-horizontal dd { + margin-left: 180px; +} + +hr { + margin: 20px 0; + border: 0; + border-top: 1px solid #eeeeee; + border-bottom: 1px solid #ffffff; +} + +abbr[title], +abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #999999; +} + +abbr.initialism { + font-size: 90%; + text-transform: uppercase; +} + +blockquote { + padding: 0 0 0 15px; + margin: 0 0 20px; + border-left: 5px solid #eeeeee; +} + +blockquote p { + margin-bottom: 0; + font-size: 17.5px; + font-weight: 300; + line-height: 1.25; +} + +blockquote small { + display: block; + line-height: 20px; + color: #999999; +} + +blockquote small:before { + content: '\2014 \00A0'; +} + +blockquote.pull-right { + float: right; + padding-right: 15px; + padding-left: 0; + border-right: 5px solid #eeeeee; + border-left: 0; +} + +blockquote.pull-right p, +blockquote.pull-right small { + text-align: right; +} + +blockquote.pull-right small:before { + content: ''; +} + +blockquote.pull-right small:after { + content: '\00A0 \2014'; +} + +q:before, +q:after, +blockquote:before, +blockquote:after { + content: ""; +} + +address { + display: block; + margin-bottom: 20px; + font-style: normal; + line-height: 20px; +} + +code, +pre { + padding: 0 3px 2px; + font-family: Monaco, Menlo, Consolas, "Courier New", monospace; + font-size: 12px; + color: #333333; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + +code { + padding: 2px 4px; + color: #d14; + white-space: nowrap; + background-color: #f7f7f9; + border: 1px solid #e1e1e8; +} + +pre { + display: block; + padding: 9.5px; + margin: 0 0 10px; + font-size: 13px; + line-height: 20px; + word-break: break-all; + word-wrap: break-word; + white-space: pre; + white-space: pre-wrap; + background-color: #f5f5f5; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.15); + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +pre.prettyprint { + margin-bottom: 20px; +} + +pre code { + padding: 0; + color: inherit; + white-space: pre; + white-space: pre-wrap; + background-color: transparent; + border: 0; +} + +.pre-scrollable { + max-height: 340px; + overflow-y: scroll; +} + +form { + margin: 0 0 20px; +} + +fieldset { + padding: 0; + margin: 0; + border: 0; +} + +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: 20px; + font-size: 21px; + line-height: 40px; + color: #333333; + border: 0; + border-bottom: 1px solid #e5e5e5; +} + +legend small { + font-size: 15px; + color: #999999; +} + +label, +input, +button, +select, +textarea { + font-size: 14px; + font-weight: normal; + line-height: 20px; +} + +input, +button, +select, +textarea { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; +} + +label { + display: block; + margin-bottom: 5px; +} + +select, +textarea, +input[type="text"], +input[type="password"], +input[type="datetime"], +input[type="datetime-local"], +input[type="date"], +input[type="month"], +input[type="time"], +input[type="week"], +input[type="number"], +input[type="email"], +input[type="url"], +input[type="search"], +input[type="tel"], +input[type="color"], +.uneditable-input { + display: inline-block; + height: 20px; + padding: 4px 6px; + margin-bottom: 10px; + font-size: 14px; + line-height: 20px; + color: #555555; + vertical-align: middle; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +input, +textarea, +.uneditable-input { + width: 206px; +} + +textarea { + height: auto; +} + +textarea, +input[type="text"], +input[type="password"], +input[type="datetime"], +input[type="datetime-local"], +input[type="date"], +input[type="month"], +input[type="time"], +input[type="week"], +input[type="number"], +input[type="email"], +input[type="url"], +input[type="search"], +input[type="tel"], +input[type="color"], +.uneditable-input { + background-color: #ffffff; + border: 1px solid #cccccc; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -webkit-transition: border linear 0.2s, box-shadow linear 0.2s; + -moz-transition: border linear 0.2s, box-shadow linear 0.2s; + -o-transition: border linear 0.2s, box-shadow linear 0.2s; + transition: border linear 0.2s, box-shadow linear 0.2s; +} + +textarea:focus, +input[type="text"]:focus, +input[type="password"]:focus, +input[type="datetime"]:focus, +input[type="datetime-local"]:focus, +input[type="date"]:focus, +input[type="month"]:focus, +input[type="time"]:focus, +input[type="week"]:focus, +input[type="number"]:focus, +input[type="email"]:focus, +input[type="url"]:focus, +input[type="search"]:focus, +input[type="tel"]:focus, +input[type="color"]:focus, +.uneditable-input:focus { + border-color: rgba(82, 168, 236, 0.8); + outline: 0; + outline: thin dotted \9; + /* IE6-9 */ + + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); +} + +input[type="radio"], +input[type="checkbox"] { + margin: 4px 0 0; + margin-top: 1px \9; + *margin-top: 0; + line-height: normal; +} + +input[type="file"], +input[type="image"], +input[type="submit"], +input[type="reset"], +input[type="button"], +input[type="radio"], +input[type="checkbox"] { + width: auto; +} + +select, +input[type="file"] { + height: 30px; + /* In IE7, the height of the select element cannot be changed by height, only font-size */ + + *margin-top: 4px; + /* For IE7, add top margin to align select with labels */ + + line-height: 30px; +} + +select { + width: 220px; + background-color: #ffffff; + border: 1px solid #cccccc; +} + +select[multiple], +select[size] { + height: auto; +} + +select:focus, +input[type="file"]:focus, +input[type="radio"]:focus, +input[type="checkbox"]:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} + +.uneditable-input, +.uneditable-textarea { + color: #999999; + cursor: not-allowed; + background-color: #fcfcfc; + border-color: #cccccc; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); + -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); +} + +.uneditable-input { + overflow: hidden; + white-space: nowrap; +} + +.uneditable-textarea { + width: auto; + height: auto; +} + +input:-moz-placeholder, +textarea:-moz-placeholder { + color: #999999; +} + +input:-ms-input-placeholder, +textarea:-ms-input-placeholder { + color: #999999; +} + +input::-webkit-input-placeholder, +textarea::-webkit-input-placeholder { + color: #999999; +} + +.radio, +.checkbox { + min-height: 20px; + padding-left: 20px; +} + +.radio input[type="radio"], +.checkbox input[type="checkbox"] { + float: left; + margin-left: -20px; +} + +.controls > .radio:first-child, +.controls > .checkbox:first-child { + padding-top: 5px; +} + +.radio.inline, +.checkbox.inline { + display: inline-block; + padding-top: 5px; + margin-bottom: 0; + vertical-align: middle; +} + +.radio.inline + .radio.inline, +.checkbox.inline + .checkbox.inline { + margin-left: 10px; +} + +.input-mini { + width: 60px; +} + +.input-small { + width: 90px; +} + +.input-medium { + width: 150px; +} + +.input-large { + width: 210px; +} + +.input-xlarge { + width: 270px; +} + +.input-xxlarge { + width: 530px; +} + +input[class*="span"], +select[class*="span"], +textarea[class*="span"], +.uneditable-input[class*="span"], +.row-fluid input[class*="span"], +.row-fluid select[class*="span"], +.row-fluid textarea[class*="span"], +.row-fluid .uneditable-input[class*="span"] { + float: none; + margin-left: 0; +} + +.input-append input[class*="span"], +.input-append .uneditable-input[class*="span"], +.input-prepend input[class*="span"], +.input-prepend .uneditable-input[class*="span"], +.row-fluid input[class*="span"], +.row-fluid select[class*="span"], +.row-fluid textarea[class*="span"], +.row-fluid .uneditable-input[class*="span"], +.row-fluid .input-prepend [class*="span"], +.row-fluid .input-append [class*="span"] { + display: inline-block; +} + +input, +textarea, +.uneditable-input { + margin-left: 0; +} + +.controls-row [class*="span"] + [class*="span"] { + margin-left: 20px; +} + +input.span12, +textarea.span12, +.uneditable-input.span12 { + width: 926px; +} + +input.span11, +textarea.span11, +.uneditable-input.span11 { + width: 846px; +} + +input.span10, +textarea.span10, +.uneditable-input.span10 { + width: 766px; +} + +input.span9, +textarea.span9, +.uneditable-input.span9 { + width: 686px; +} + +input.span8, +textarea.span8, +.uneditable-input.span8 { + width: 606px; +} + +input.span7, +textarea.span7, +.uneditable-input.span7 { + width: 526px; +} + +input.span6, +textarea.span6, +.uneditable-input.span6 { + width: 446px; +} + +input.span5, +textarea.span5, +.uneditable-input.span5 { + width: 366px; +} + +input.span4, +textarea.span4, +.uneditable-input.span4 { + width: 286px; +} + +input.span3, +textarea.span3, +.uneditable-input.span3 { + width: 206px; +} + +input.span2, +textarea.span2, +.uneditable-input.span2 { + width: 126px; +} + +input.span1, +textarea.span1, +.uneditable-input.span1 { + width: 46px; +} + +.controls-row { + *zoom: 1; +} + +.controls-row:before, +.controls-row:after { + display: table; + line-height: 0; + content: ""; +} + +.controls-row:after { + clear: both; +} + +.controls-row [class*="span"], +.row-fluid .controls-row [class*="span"] { + float: left; +} + +.controls-row .checkbox[class*="span"], +.controls-row .radio[class*="span"] { + padding-top: 5px; +} + +input[disabled], +select[disabled], +textarea[disabled], +input[readonly], +select[readonly], +textarea[readonly] { + cursor: not-allowed; + background-color: #eeeeee; +} + +input[type="radio"][disabled], +input[type="checkbox"][disabled], +input[type="radio"][readonly], +input[type="checkbox"][readonly] { + background-color: transparent; +} + +.control-group.warning .control-label, +.control-group.warning .help-block, +.control-group.warning .help-inline { + color: #c09853; +} + +.control-group.warning .checkbox, +.control-group.warning .radio, +.control-group.warning input, +.control-group.warning select, +.control-group.warning textarea { + color: #c09853; +} + +.control-group.warning input, +.control-group.warning select, +.control-group.warning textarea { + border-color: #c09853; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} + +.control-group.warning input:focus, +.control-group.warning select:focus, +.control-group.warning textarea:focus { + border-color: #a47e3c; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; +} + +.control-group.warning .input-prepend .add-on, +.control-group.warning .input-append .add-on { + color: #c09853; + background-color: #fcf8e3; + border-color: #c09853; +} + +.control-group.error .control-label, +.control-group.error .help-block, +.control-group.error .help-inline { + color: #b94a48; +} + +.control-group.error .checkbox, +.control-group.error .radio, +.control-group.error input, +.control-group.error select, +.control-group.error textarea { + color: #b94a48; +} + +.control-group.error input, +.control-group.error select, +.control-group.error textarea { + border-color: #b94a48; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} + +.control-group.error input:focus, +.control-group.error select:focus, +.control-group.error textarea:focus { + border-color: #953b39; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; +} + +.control-group.error .input-prepend .add-on, +.control-group.error .input-append .add-on { + color: #b94a48; + background-color: #f2dede; + border-color: #b94a48; +} + +.control-group.success .control-label, +.control-group.success .help-block, +.control-group.success .help-inline { + color: #468847; +} + +.control-group.success .checkbox, +.control-group.success .radio, +.control-group.success input, +.control-group.success select, +.control-group.success textarea { + color: #468847; +} + +.control-group.success input, +.control-group.success select, +.control-group.success textarea { + border-color: #468847; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} + +.control-group.success input:focus, +.control-group.success select:focus, +.control-group.success textarea:focus { + border-color: #356635; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; +} + +.control-group.success .input-prepend .add-on, +.control-group.success .input-append .add-on { + color: #468847; + background-color: #dff0d8; + border-color: #468847; +} + +.control-group.info .control-label, +.control-group.info .help-block, +.control-group.info .help-inline { + color: #3a87ad; +} + +.control-group.info .checkbox, +.control-group.info .radio, +.control-group.info input, +.control-group.info select, +.control-group.info textarea { + color: #3a87ad; +} + +.control-group.info input, +.control-group.info select, +.control-group.info textarea { + border-color: #3a87ad; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} + +.control-group.info input:focus, +.control-group.info select:focus, +.control-group.info textarea:focus { + border-color: #2d6987; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3; + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3; +} + +.control-group.info .input-prepend .add-on, +.control-group.info .input-append .add-on { + color: #3a87ad; + background-color: #d9edf7; + border-color: #3a87ad; +} + +input:focus:invalid, +textarea:focus:invalid, +select:focus:invalid { + color: #b94a48; + border-color: #ee5f5b; +} + +input:focus:invalid:focus, +textarea:focus:invalid:focus, +select:focus:invalid:focus { + border-color: #e9322d; + -webkit-box-shadow: 0 0 6px #f8b9b7; + -moz-box-shadow: 0 0 6px #f8b9b7; + box-shadow: 0 0 6px #f8b9b7; +} + +.form-actions { + padding: 19px 20px 20px; + margin-top: 20px; + margin-bottom: 20px; + background-color: #f5f5f5; + border-top: 1px solid #e5e5e5; + *zoom: 1; +} + +.form-actions:before, +.form-actions:after { + display: table; + line-height: 0; + content: ""; +} + +.form-actions:after { + clear: both; +} + +.help-block, +.help-inline { + color: #595959; +} + +.help-block { + display: block; + margin-bottom: 10px; +} + +.help-inline { + display: inline-block; + *display: inline; + padding-left: 5px; + vertical-align: middle; + *zoom: 1; +} + +.input-append, +.input-prepend { + display: inline-block; + margin-bottom: 10px; + font-size: 0; + white-space: nowrap; + vertical-align: middle; +} + +.input-append input, +.input-prepend input, +.input-append select, +.input-prepend select, +.input-append .uneditable-input, +.input-prepend .uneditable-input, +.input-append .dropdown-menu, +.input-prepend .dropdown-menu, +.input-append .popover, +.input-prepend .popover { + font-size: 14px; +} + +.input-append input, +.input-prepend input, +.input-append select, +.input-prepend select, +.input-append .uneditable-input, +.input-prepend .uneditable-input { + position: relative; + margin-bottom: 0; + *margin-left: 0; + vertical-align: top; + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} + +.input-append input:focus, +.input-prepend input:focus, +.input-append select:focus, +.input-prepend select:focus, +.input-append .uneditable-input:focus, +.input-prepend .uneditable-input:focus { + z-index: 2; +} + +.input-append .add-on, +.input-prepend .add-on { + display: inline-block; + width: auto; + height: 20px; + min-width: 16px; + padding: 4px 5px; + font-size: 14px; + font-weight: normal; + line-height: 20px; + text-align: center; + text-shadow: 0 1px 0 #ffffff; + background-color: #eeeeee; + border: 1px solid #ccc; +} + +.input-append .add-on, +.input-prepend .add-on, +.input-append .btn, +.input-prepend .btn, +.input-append .btn-group > .dropdown-toggle, +.input-prepend .btn-group > .dropdown-toggle { + vertical-align: top; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.input-append .active, +.input-prepend .active { + background-color: #a9dba9; + border-color: #46a546; +} + +.input-prepend .add-on, +.input-prepend .btn { + margin-right: -1px; +} + +.input-prepend .add-on:first-child, +.input-prepend .btn:first-child { + -webkit-border-radius: 4px 0 0 4px; + -moz-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; +} + +.input-append input, +.input-append select, +.input-append .uneditable-input { + -webkit-border-radius: 4px 0 0 4px; + -moz-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; +} + +.input-append input + .btn-group .btn:last-child, +.input-append select + .btn-group .btn:last-child, +.input-append .uneditable-input + .btn-group .btn:last-child { + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} + +.input-append .add-on, +.input-append .btn, +.input-append .btn-group { + margin-left: -1px; +} + +.input-append .add-on:last-child, +.input-append .btn:last-child, +.input-append .btn-group:last-child > .dropdown-toggle { + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} + +.input-prepend.input-append input, +.input-prepend.input-append select, +.input-prepend.input-append .uneditable-input { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.input-prepend.input-append input + .btn-group .btn, +.input-prepend.input-append select + .btn-group .btn, +.input-prepend.input-append .uneditable-input + .btn-group .btn { + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} + +.input-prepend.input-append .add-on:first-child, +.input-prepend.input-append .btn:first-child { + margin-right: -1px; + -webkit-border-radius: 4px 0 0 4px; + -moz-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; +} + +.input-prepend.input-append .add-on:last-child, +.input-prepend.input-append .btn:last-child { + margin-left: -1px; + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} + +.input-prepend.input-append .btn-group:first-child { + margin-left: 0; +} + +input.search-query { + padding-right: 14px; + padding-right: 4px \9; + padding-left: 14px; + padding-left: 4px \9; + /* IE7-8 doesn't have border-radius, so don't indent the padding */ + + margin-bottom: 0; + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + border-radius: 15px; +} + +/* Allow for input prepend/append in search forms */ + +.form-search .input-append .search-query, +.form-search .input-prepend .search-query { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.form-search .input-append .search-query { + -webkit-border-radius: 14px 0 0 14px; + -moz-border-radius: 14px 0 0 14px; + border-radius: 14px 0 0 14px; +} + +.form-search .input-append .btn { + -webkit-border-radius: 0 14px 14px 0; + -moz-border-radius: 0 14px 14px 0; + border-radius: 0 14px 14px 0; +} + +.form-search .input-prepend .search-query { + -webkit-border-radius: 0 14px 14px 0; + -moz-border-radius: 0 14px 14px 0; + border-radius: 0 14px 14px 0; +} + +.form-search .input-prepend .btn { + -webkit-border-radius: 14px 0 0 14px; + -moz-border-radius: 14px 0 0 14px; + border-radius: 14px 0 0 14px; +} + +.form-search input, +.form-inline input, +.form-horizontal input, +.form-search textarea, +.form-inline textarea, +.form-horizontal textarea, +.form-search select, +.form-inline select, +.form-horizontal select, +.form-search .help-inline, +.form-inline .help-inline, +.form-horizontal .help-inline, +.form-search .uneditable-input, +.form-inline .uneditable-input, +.form-horizontal .uneditable-input, +.form-search .input-prepend, +.form-inline .input-prepend, +.form-horizontal .input-prepend, +.form-search .input-append, +.form-inline .input-append, +.form-horizontal .input-append { + display: inline-block; + *display: inline; + margin-bottom: 0; + vertical-align: middle; + *zoom: 1; +} + +.form-search .hide, +.form-inline .hide, +.form-horizontal .hide { + display: none; +} + +.form-search label, +.form-inline label, +.form-search .btn-group, +.form-inline .btn-group { + display: inline-block; +} + +.form-search .input-append, +.form-inline .input-append, +.form-search .input-prepend, +.form-inline .input-prepend { + margin-bottom: 0; +} + +.form-search .radio, +.form-search .checkbox, +.form-inline .radio, +.form-inline .checkbox { + padding-left: 0; + margin-bottom: 0; + vertical-align: middle; +} + +.form-search .radio input[type="radio"], +.form-search .checkbox input[type="checkbox"], +.form-inline .radio input[type="radio"], +.form-inline .checkbox input[type="checkbox"] { + float: left; + margin-right: 3px; + margin-left: 0; +} + +.control-group { + margin-bottom: 10px; +} + +legend + .control-group { + margin-top: 20px; + -webkit-margin-top-collapse: separate; +} + +.form-horizontal .control-group { + margin-bottom: 20px; + *zoom: 1; +} + +.form-horizontal .control-group:before, +.form-horizontal .control-group:after { + display: table; + line-height: 0; + content: ""; +} + +.form-horizontal .control-group:after { + clear: both; +} + +.form-horizontal .control-label { + float: left; + width: 160px; + padding-top: 5px; + text-align: right; +} + +.form-horizontal .controls { + *display: inline-block; + *padding-left: 20px; + margin-left: 180px; + *margin-left: 0; +} + +.form-horizontal .controls:first-child { + *padding-left: 180px; +} + +.form-horizontal .help-block { + margin-bottom: 0; +} + +.form-horizontal input + .help-block, +.form-horizontal select + .help-block, +.form-horizontal textarea + .help-block, +.form-horizontal .uneditable-input + .help-block, +.form-horizontal .input-prepend + .help-block, +.form-horizontal .input-append + .help-block { + margin-top: 10px; +} + +.form-horizontal .form-actions { + padding-left: 180px; +} + +table { + max-width: 100%; + background-color: transparent; + border-collapse: collapse; + border-spacing: 0; +} + +.table { + width: 100%; + margin-bottom: 20px; +} + +.table th, +.table td { + padding: 8px; + line-height: 20px; + text-align: left; + vertical-align: top; + border-top: 1px solid #dddddd; +} + +.table th { + font-weight: bold; +} + +.table thead th { + vertical-align: bottom; +} + +.table caption + thead tr:first-child th, +.table caption + thead tr:first-child td, +.table colgroup + thead tr:first-child th, +.table colgroup + thead tr:first-child td, +.table thead:first-child tr:first-child th, +.table thead:first-child tr:first-child td { + border-top: 0; +} + +.table tbody + tbody { + border-top: 2px solid #dddddd; +} + +.table .table { + background-color: #ffffff; +} + +.table-condensed th, +.table-condensed td { + padding: 4px 5px; +} + +.table-bordered { + border: 1px solid #dddddd; + border-collapse: separate; + *border-collapse: collapse; + border-left: 0; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.table-bordered th, +.table-bordered td { + border-left: 1px solid #dddddd; +} + +.table-bordered caption + thead tr:first-child th, +.table-bordered caption + tbody tr:first-child th, +.table-bordered caption + tbody tr:first-child td, +.table-bordered colgroup + thead tr:first-child th, +.table-bordered colgroup + tbody tr:first-child th, +.table-bordered colgroup + tbody tr:first-child td, +.table-bordered thead:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child td { + border-top: 0; +} + +.table-bordered thead:first-child tr:first-child > th:first-child, +.table-bordered tbody:first-child tr:first-child > td:first-child, +.table-bordered tbody:first-child tr:first-child > th:first-child { + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; +} + +.table-bordered thead:first-child tr:first-child > th:last-child, +.table-bordered tbody:first-child tr:first-child > td:last-child, +.table-bordered tbody:first-child tr:first-child > th:last-child { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; +} + +.table-bordered thead:last-child tr:last-child > th:first-child, +.table-bordered tbody:last-child tr:last-child > td:first-child, +.table-bordered tbody:last-child tr:last-child > th:first-child, +.table-bordered tfoot:last-child tr:last-child > td:first-child, +.table-bordered tfoot:last-child tr:last-child > th:first-child { + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; +} + +.table-bordered thead:last-child tr:last-child > th:last-child, +.table-bordered tbody:last-child tr:last-child > td:last-child, +.table-bordered tbody:last-child tr:last-child > th:last-child, +.table-bordered tfoot:last-child tr:last-child > td:last-child, +.table-bordered tfoot:last-child tr:last-child > th:last-child { + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -moz-border-radius-bottomright: 4px; +} + +.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { + -webkit-border-bottom-left-radius: 0; + border-bottom-left-radius: 0; + -moz-border-radius-bottomleft: 0; +} + +.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { + -webkit-border-bottom-right-radius: 0; + border-bottom-right-radius: 0; + -moz-border-radius-bottomright: 0; +} + +.table-bordered caption + thead tr:first-child th:first-child, +.table-bordered caption + tbody tr:first-child td:first-child, +.table-bordered colgroup + thead tr:first-child th:first-child, +.table-bordered colgroup + tbody tr:first-child td:first-child { + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; +} + +.table-bordered caption + thead tr:first-child th:last-child, +.table-bordered caption + tbody tr:first-child td:last-child, +.table-bordered colgroup + thead tr:first-child th:last-child, +.table-bordered colgroup + tbody tr:first-child td:last-child { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; +} + +.table-striped tbody > tr:nth-child(odd) > td, +.table-striped tbody > tr:nth-child(odd) > th { + background-color: #f9f9f9; +} + +.table-hover tbody tr:hover > td, +.table-hover tbody tr:hover > th { + background-color: #f5f5f5; +} + +table td[class*="span"], +table th[class*="span"], +.row-fluid table td[class*="span"], +.row-fluid table th[class*="span"] { + display: table-cell; + float: none; + margin-left: 0; +} + +.table td.span1, +.table th.span1 { + float: none; + width: 44px; + margin-left: 0; +} + +.table td.span2, +.table th.span2 { + float: none; + width: 124px; + margin-left: 0; +} + +.table td.span3, +.table th.span3 { + float: none; + width: 204px; + margin-left: 0; +} + +.table td.span4, +.table th.span4 { + float: none; + width: 284px; + margin-left: 0; +} + +.table td.span5, +.table th.span5 { + float: none; + width: 364px; + margin-left: 0; +} + +.table td.span6, +.table th.span6 { + float: none; + width: 444px; + margin-left: 0; +} + +.table td.span7, +.table th.span7 { + float: none; + width: 524px; + margin-left: 0; +} + +.table td.span8, +.table th.span8 { + float: none; + width: 604px; + margin-left: 0; +} + +.table td.span9, +.table th.span9 { + float: none; + width: 684px; + margin-left: 0; +} + +.table td.span10, +.table th.span10 { + float: none; + width: 764px; + margin-left: 0; +} + +.table td.span11, +.table th.span11 { + float: none; + width: 844px; + margin-left: 0; +} + +.table td.span12, +.table th.span12 { + float: none; + width: 924px; + margin-left: 0; +} + +.table tbody tr.success > td { + background-color: #dff0d8; +} + +.table tbody tr.error > td { + background-color: #f2dede; +} + +.table tbody tr.warning > td { + background-color: #fcf8e3; +} + +.table tbody tr.info > td { + background-color: #d9edf7; +} + +.table-hover tbody tr.success:hover > td { + background-color: #d0e9c6; +} + +.table-hover tbody tr.error:hover > td { + background-color: #ebcccc; +} + +.table-hover tbody tr.warning:hover > td { + background-color: #faf2cc; +} + +.table-hover tbody tr.info:hover > td { + background-color: #c4e3f3; +} + +[class^="icon-"], +[class*=" icon-"] { + display: inline-block; + width: 14px; + height: 14px; + margin-top: 1px; + *margin-right: .3em; + line-height: 14px; + vertical-align: text-top; + background-image: url("../img/glyphicons-halflings.png"); + background-position: 14px 14px; + background-repeat: no-repeat; +} + +/* White icons with optional class, or on hover/focus/active states of certain elements */ + +.icon-white, +.nav-pills > .active > a > [class^="icon-"], +.nav-pills > .active > a > [class*=" icon-"], +.nav-list > .active > a > [class^="icon-"], +.nav-list > .active > a > [class*=" icon-"], +.navbar-inverse .nav > .active > a > [class^="icon-"], +.navbar-inverse .nav > .active > a > [class*=" icon-"], +.dropdown-menu > li > a:hover > [class^="icon-"], +.dropdown-menu > li > a:focus > [class^="icon-"], +.dropdown-menu > li > a:hover > [class*=" icon-"], +.dropdown-menu > li > a:focus > [class*=" icon-"], +.dropdown-menu > .active > a > [class^="icon-"], +.dropdown-menu > .active > a > [class*=" icon-"], +.dropdown-submenu:hover > a > [class^="icon-"], +.dropdown-submenu:focus > a > [class^="icon-"], +.dropdown-submenu:hover > a > [class*=" icon-"], +.dropdown-submenu:focus > a > [class*=" icon-"] { + background-image: url("../img/glyphicons-halflings-white.png"); +} + +.icon-glass { + background-position: 0 0; +} + +.icon-music { + background-position: -24px 0; +} + +.icon-search { + background-position: -48px 0; +} + +.icon-envelope { + background-position: -72px 0; +} + +.icon-heart { + background-position: -96px 0; +} + +.icon-star { + background-position: -120px 0; +} + +.icon-star-empty { + background-position: -144px 0; +} + +.icon-user { + background-position: -168px 0; +} + +.icon-film { + background-position: -192px 0; +} + +.icon-th-large { + background-position: -216px 0; +} + +.icon-th { + background-position: -240px 0; +} + +.icon-th-list { + background-position: -264px 0; +} + +.icon-ok { + background-position: -288px 0; +} + +.icon-remove { + background-position: -312px 0; +} + +.icon-zoom-in { + background-position: -336px 0; +} + +.icon-zoom-out { + background-position: -360px 0; +} + +.icon-off { + background-position: -384px 0; +} + +.icon-signal { + background-position: -408px 0; +} + +.icon-cog { + background-position: -432px 0; +} + +.icon-trash { + background-position: -456px 0; +} + +.icon-home { + background-position: 0 -24px; +} + +.icon-file { + background-position: -24px -24px; +} + +.icon-time { + background-position: -48px -24px; +} + +.icon-road { + background-position: -72px -24px; +} + +.icon-download-alt { + background-position: -96px -24px; +} + +.icon-download { + background-position: -120px -24px; +} + +.icon-upload { + background-position: -144px -24px; +} + +.icon-inbox { + background-position: -168px -24px; +} + +.icon-play-circle { + background-position: -192px -24px; +} + +.icon-repeat { + background-position: -216px -24px; +} + +.icon-refresh { + background-position: -240px -24px; +} + +.icon-list-alt { + background-position: -264px -24px; +} + +.icon-lock { + background-position: -287px -24px; +} + +.icon-flag { + background-position: -312px -24px; +} + +.icon-headphones { + background-position: -336px -24px; +} + +.icon-volume-off { + background-position: -360px -24px; +} + +.icon-volume-down { + background-position: -384px -24px; +} + +.icon-volume-up { + background-position: -408px -24px; +} + +.icon-qrcode { + background-position: -432px -24px; +} + +.icon-barcode { + background-position: -456px -24px; +} + +.icon-tag { + background-position: 0 -48px; +} + +.icon-tags { + background-position: -25px -48px; +} + +.icon-book { + background-position: -48px -48px; +} + +.icon-bookmark { + background-position: -72px -48px; +} + +.icon-print { + background-position: -96px -48px; +} + +.icon-camera { + background-position: -120px -48px; +} + +.icon-font { + background-position: -144px -48px; +} + +.icon-bold { + background-position: -167px -48px; +} + +.icon-italic { + background-position: -192px -48px; +} + +.icon-text-height { + background-position: -216px -48px; +} + +.icon-text-width { + background-position: -240px -48px; +} + +.icon-align-left { + background-position: -264px -48px; +} + +.icon-align-center { + background-position: -288px -48px; +} + +.icon-align-right { + background-position: -312px -48px; +} + +.icon-align-justify { + background-position: -336px -48px; +} + +.icon-list { + background-position: -360px -48px; +} + +.icon-indent-left { + background-position: -384px -48px; +} + +.icon-indent-right { + background-position: -408px -48px; +} + +.icon-facetime-video { + background-position: -432px -48px; +} + +.icon-picture { + background-position: -456px -48px; +} + +.icon-pencil { + background-position: 0 -72px; +} + +.icon-map-marker { + background-position: -24px -72px; +} + +.icon-adjust { + background-position: -48px -72px; +} + +.icon-tint { + background-position: -72px -72px; +} + +.icon-edit { + background-position: -96px -72px; +} + +.icon-share { + background-position: -120px -72px; +} + +.icon-check { + background-position: -144px -72px; +} + +.icon-move { + background-position: -168px -72px; +} + +.icon-step-backward { + background-position: -192px -72px; +} + +.icon-fast-backward { + background-position: -216px -72px; +} + +.icon-backward { + background-position: -240px -72px; +} + +.icon-play { + background-position: -264px -72px; +} + +.icon-pause { + background-position: -288px -72px; +} + +.icon-stop { + background-position: -312px -72px; +} + +.icon-forward { + background-position: -336px -72px; +} + +.icon-fast-forward { + background-position: -360px -72px; +} + +.icon-step-forward { + background-position: -384px -72px; +} + +.icon-eject { + background-position: -408px -72px; +} + +.icon-chevron-left { + background-position: -432px -72px; +} + +.icon-chevron-right { + background-position: -456px -72px; +} + +.icon-plus-sign { + background-position: 0 -96px; +} + +.icon-minus-sign { + background-position: -24px -96px; +} + +.icon-remove-sign { + background-position: -48px -96px; +} + +.icon-ok-sign { + background-position: -72px -96px; +} + +.icon-question-sign { + background-position: -96px -96px; +} + +.icon-info-sign { + background-position: -120px -96px; +} + +.icon-screenshot { + background-position: -144px -96px; +} + +.icon-remove-circle { + background-position: -168px -96px; +} + +.icon-ok-circle { + background-position: -192px -96px; +} + +.icon-ban-circle { + background-position: -216px -96px; +} + +.icon-arrow-left { + background-position: -240px -96px; +} + +.icon-arrow-right { + background-position: -264px -96px; +} + +.icon-arrow-up { + background-position: -289px -96px; +} + +.icon-arrow-down { + background-position: -312px -96px; +} + +.icon-share-alt { + background-position: -336px -96px; +} + +.icon-resize-full { + background-position: -360px -96px; +} + +.icon-resize-small { + background-position: -384px -96px; +} + +.icon-plus { + background-position: -408px -96px; +} + +.icon-minus { + background-position: -433px -96px; +} + +.icon-asterisk { + background-position: -456px -96px; +} + +.icon-exclamation-sign { + background-position: 0 -120px; +} + +.icon-gift { + background-position: -24px -120px; +} + +.icon-leaf { + background-position: -48px -120px; +} + +.icon-fire { + background-position: -72px -120px; +} + +.icon-eye-open { + background-position: -96px -120px; +} + +.icon-eye-close { + background-position: -120px -120px; +} + +.icon-warning-sign { + background-position: -144px -120px; +} + +.icon-plane { + background-position: -168px -120px; +} + +.icon-calendar { + background-position: -192px -120px; +} + +.icon-random { + width: 16px; + background-position: -216px -120px; +} + +.icon-comment { + background-position: -240px -120px; +} + +.icon-magnet { + background-position: -264px -120px; +} + +.icon-chevron-up { + background-position: -288px -120px; +} + +.icon-chevron-down { + background-position: -313px -119px; +} + +.icon-retweet { + background-position: -336px -120px; +} + +.icon-shopping-cart { + background-position: -360px -120px; +} + +.icon-folder-close { + width: 16px; + background-position: -384px -120px; +} + +.icon-folder-open { + width: 16px; + background-position: -408px -120px; +} + +.icon-resize-vertical { + background-position: -432px -119px; +} + +.icon-resize-horizontal { + background-position: -456px -118px; +} + +.icon-hdd { + background-position: 0 -144px; +} + +.icon-bullhorn { + background-position: -24px -144px; +} + +.icon-bell { + background-position: -48px -144px; +} + +.icon-certificate { + background-position: -72px -144px; +} + +.icon-thumbs-up { + background-position: -96px -144px; +} + +.icon-thumbs-down { + background-position: -120px -144px; +} + +.icon-hand-right { + background-position: -144px -144px; +} + +.icon-hand-left { + background-position: -168px -144px; +} + +.icon-hand-up { + background-position: -192px -144px; +} + +.icon-hand-down { + background-position: -216px -144px; +} + +.icon-circle-arrow-right { + background-position: -240px -144px; +} + +.icon-circle-arrow-left { + background-position: -264px -144px; +} + +.icon-circle-arrow-up { + background-position: -288px -144px; +} + +.icon-circle-arrow-down { + background-position: -312px -144px; +} + +.icon-globe { + background-position: -336px -144px; +} + +.icon-wrench { + background-position: -360px -144px; +} + +.icon-tasks { + background-position: -384px -144px; +} + +.icon-filter { + background-position: -408px -144px; +} + +.icon-briefcase { + background-position: -432px -144px; +} + +.icon-fullscreen { + background-position: -456px -144px; +} + +.dropup, +.dropdown { + position: relative; +} + +.dropdown-toggle { + *margin-bottom: -3px; +} + +.dropdown-toggle:active, +.open .dropdown-toggle { + outline: 0; +} + +.caret { + display: inline-block; + width: 0; + height: 0; + vertical-align: top; + border-top: 4px solid #000000; + border-right: 4px solid transparent; + border-left: 4px solid transparent; + content: ""; +} + +.dropdown .caret { + margin-top: 8px; + margin-left: 2px; +} + +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 160px; + padding: 5px 0; + margin: 2px 0 0; + list-style: none; + background-color: #ffffff; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + *border-right-width: 2px; + *border-bottom-width: 2px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -webkit-background-clip: padding-box; + -moz-background-clip: padding; + background-clip: padding-box; +} + +.dropdown-menu.pull-right { + right: 0; + left: auto; +} + +.dropdown-menu .divider { + *width: 100%; + height: 1px; + margin: 9px 1px; + *margin: -5px 0 5px; + overflow: hidden; + background-color: #e5e5e5; + border-bottom: 1px solid #ffffff; +} + +.dropdown-menu > li > a { + display: block; + padding: 3px 20px; + clear: both; + font-weight: normal; + line-height: 20px; + color: #333333; + white-space: nowrap; +} + +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus, +.dropdown-submenu:hover > a, +.dropdown-submenu:focus > a { + color: #ffffff; + text-decoration: none; + background-color: #0081c2; + background-image: -moz-linear-gradient(top, #0088cc, #0077b3); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3)); + background-image: -webkit-linear-gradient(top, #0088cc, #0077b3); + background-image: -o-linear-gradient(top, #0088cc, #0077b3); + background-image: linear-gradient(to bottom, #0088cc, #0077b3); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0); +} + +.dropdown-menu > .active > a, +.dropdown-menu > .active > a:hover, +.dropdown-menu > .active > a:focus { + color: #ffffff; + text-decoration: none; + background-color: #0081c2; + background-image: -moz-linear-gradient(top, #0088cc, #0077b3); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3)); + background-image: -webkit-linear-gradient(top, #0088cc, #0077b3); + background-image: -o-linear-gradient(top, #0088cc, #0077b3); + background-image: linear-gradient(to bottom, #0088cc, #0077b3); + background-repeat: repeat-x; + outline: 0; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0); +} + +.dropdown-menu > .disabled > a, +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + color: #999999; +} + +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + text-decoration: none; + cursor: default; + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.open { + *z-index: 1000; +} + +.open > .dropdown-menu { + display: block; +} + +.dropdown-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 990; +} + +.pull-right > .dropdown-menu { + right: 0; + left: auto; +} + +.dropup .caret, +.navbar-fixed-bottom .dropdown .caret { + border-top: 0; + border-bottom: 4px solid #000000; + content: ""; +} + +.dropup .dropdown-menu, +.navbar-fixed-bottom .dropdown .dropdown-menu { + top: auto; + bottom: 100%; + margin-bottom: 1px; +} + +.dropdown-submenu { + position: relative; +} + +.dropdown-submenu > .dropdown-menu { + top: 0; + left: 100%; + margin-top: -6px; + margin-left: -1px; + -webkit-border-radius: 0 6px 6px 6px; + -moz-border-radius: 0 6px 6px 6px; + border-radius: 0 6px 6px 6px; +} + +.dropdown-submenu:hover > .dropdown-menu { + display: block; +} + +.dropup .dropdown-submenu > .dropdown-menu { + top: auto; + bottom: 0; + margin-top: 0; + margin-bottom: -2px; + -webkit-border-radius: 5px 5px 5px 0; + -moz-border-radius: 5px 5px 5px 0; + border-radius: 5px 5px 5px 0; +} + +.dropdown-submenu > a:after { + display: block; + float: right; + width: 0; + height: 0; + margin-top: 5px; + margin-right: -10px; + border-color: transparent; + border-left-color: #cccccc; + border-style: solid; + border-width: 5px 0 5px 5px; + content: " "; +} + +.dropdown-submenu:hover > a:after { + border-left-color: #ffffff; +} + +.dropdown-submenu.pull-left { + float: none; +} + +.dropdown-submenu.pull-left > .dropdown-menu { + left: -100%; + margin-left: 10px; + -webkit-border-radius: 6px 0 6px 6px; + -moz-border-radius: 6px 0 6px 6px; + border-radius: 6px 0 6px 6px; +} + +.dropdown .dropdown-menu .nav-header { + padding-right: 20px; + padding-left: 20px; +} + +.typeahead { + z-index: 1051; + margin-top: 2px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.well { + min-height: 20px; + padding: 19px; + margin-bottom: 20px; + background-color: #f5f5f5; + border: 1px solid #e3e3e3; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); +} + +.well blockquote { + border-color: #ddd; + border-color: rgba(0, 0, 0, 0.15); +} + +.well-large { + padding: 24px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} + +.well-small { + padding: 9px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + +.fade { + opacity: 0; + -webkit-transition: opacity 0.15s linear; + -moz-transition: opacity 0.15s linear; + -o-transition: opacity 0.15s linear; + transition: opacity 0.15s linear; +} + +.fade.in { + opacity: 1; +} + +.collapse { + position: relative; + height: 0; + overflow: hidden; + -webkit-transition: height 0.35s ease; + -moz-transition: height 0.35s ease; + -o-transition: height 0.35s ease; + transition: height 0.35s ease; +} + +.collapse.in { + height: auto; +} + +.close { + float: right; + font-size: 20px; + font-weight: bold; + line-height: 20px; + color: #000000; + text-shadow: 0 1px 0 #ffffff; + opacity: 0.2; + filter: alpha(opacity=20); +} + +.close:hover, +.close:focus { + color: #000000; + text-decoration: none; + cursor: pointer; + opacity: 0.4; + filter: alpha(opacity=40); +} + +button.close { + padding: 0; + cursor: pointer; + background: transparent; + border: 0; + -webkit-appearance: none; +} + +.btn { + display: inline-block; + *display: inline; + padding: 4px 12px; + margin-bottom: 0; + *margin-left: .3em; + font-size: 14px; + line-height: 20px; + color: #333333; + text-align: center; + text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); + vertical-align: middle; + cursor: pointer; + background-color: #f5f5f5; + *background-color: #e6e6e6; + background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6)); + background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6); + background-image: -o-linear-gradient(top, #ffffff, #e6e6e6); + background-image: linear-gradient(to bottom, #ffffff, #e6e6e6); + background-repeat: repeat-x; + border: 1px solid #cccccc; + *border: 0; + border-color: #e6e6e6 #e6e6e6 #bfbfbf; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + border-bottom-color: #b3b3b3; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); + *zoom: 1; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); +} + +.btn:hover, +.btn:focus, +.btn:active, +.btn.active, +.btn.disabled, +.btn[disabled] { + color: #333333; + background-color: #e6e6e6; + *background-color: #d9d9d9; +} + +.btn:active, +.btn.active { + background-color: #cccccc \9; +} + +.btn:first-child { + *margin-left: 0; +} + +.btn:hover, +.btn:focus { + color: #333333; + text-decoration: none; + background-position: 0 -15px; + -webkit-transition: background-position 0.1s linear; + -moz-transition: background-position 0.1s linear; + -o-transition: background-position 0.1s linear; + transition: background-position 0.1s linear; +} + +.btn:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} + +.btn.active, +.btn:active { + background-image: none; + outline: 0; + -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); +} + +.btn.disabled, +.btn[disabled] { + cursor: default; + background-image: none; + opacity: 0.65; + filter: alpha(opacity=65); + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} + +.btn-large { + padding: 11px 19px; + font-size: 17.5px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} + +.btn-large [class^="icon-"], +.btn-large [class*=" icon-"] { + margin-top: 4px; +} + +.btn-small { + padding: 2px 10px; + font-size: 11.9px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + +.btn-small [class^="icon-"], +.btn-small [class*=" icon-"] { + margin-top: 0; +} + +.btn-mini [class^="icon-"], +.btn-mini [class*=" icon-"] { + margin-top: -1px; +} + +.btn-mini { + padding: 0 6px; + font-size: 10.5px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + +.btn-block { + display: block; + width: 100%; + padding-right: 0; + padding-left: 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.btn-block + .btn-block { + margin-top: 5px; +} + +input[type="submit"].btn-block, +input[type="reset"].btn-block, +input[type="button"].btn-block { + width: 100%; +} + +.btn-primary.active, +.btn-warning.active, +.btn-danger.active, +.btn-success.active, +.btn-info.active, +.btn-inverse.active { + color: rgba(255, 255, 255, 0.75); +} + +.btn-primary { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #006dcc; + *background-color: #0044cc; + background-image: -moz-linear-gradient(top, #0088cc, #0044cc); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc)); + background-image: -webkit-linear-gradient(top, #0088cc, #0044cc); + background-image: -o-linear-gradient(top, #0088cc, #0044cc); + background-image: linear-gradient(to bottom, #0088cc, #0044cc); + background-repeat: repeat-x; + border-color: #0044cc #0044cc #002a80; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.btn-primary:hover, +.btn-primary:focus, +.btn-primary:active, +.btn-primary.active, +.btn-primary.disabled, +.btn-primary[disabled] { + color: #ffffff; + background-color: #0044cc; + *background-color: #003bb3; +} + +.btn-primary:active, +.btn-primary.active { + background-color: #003399 \9; +} + +.btn-warning { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #faa732; + *background-color: #f89406; + background-image: -moz-linear-gradient(top, #fbb450, #f89406); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406)); + background-image: -webkit-linear-gradient(top, #fbb450, #f89406); + background-image: -o-linear-gradient(top, #fbb450, #f89406); + background-image: linear-gradient(to bottom, #fbb450, #f89406); + background-repeat: repeat-x; + border-color: #f89406 #f89406 #ad6704; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.btn-warning:hover, +.btn-warning:focus, +.btn-warning:active, +.btn-warning.active, +.btn-warning.disabled, +.btn-warning[disabled] { + color: #ffffff; + background-color: #f89406; + *background-color: #df8505; +} + +.btn-warning:active, +.btn-warning.active { + background-color: #c67605 \9; +} + +.btn-danger { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #da4f49; + *background-color: #bd362f; + background-image: -moz-linear-gradient(top, #ee5f5b, #bd362f); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f)); + background-image: -webkit-linear-gradient(top, #ee5f5b, #bd362f); + background-image: -o-linear-gradient(top, #ee5f5b, #bd362f); + background-image: linear-gradient(to bottom, #ee5f5b, #bd362f); + background-repeat: repeat-x; + border-color: #bd362f #bd362f #802420; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffbd362f', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.btn-danger:hover, +.btn-danger:focus, +.btn-danger:active, +.btn-danger.active, +.btn-danger.disabled, +.btn-danger[disabled] { + color: #ffffff; + background-color: #bd362f; + *background-color: #a9302a; +} + +.btn-danger:active, +.btn-danger.active { + background-color: #942a25 \9; +} + +.btn-success { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #5bb75b; + *background-color: #51a351; + background-image: -moz-linear-gradient(top, #62c462, #51a351); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#51a351)); + background-image: -webkit-linear-gradient(top, #62c462, #51a351); + background-image: -o-linear-gradient(top, #62c462, #51a351); + background-image: linear-gradient(to bottom, #62c462, #51a351); + background-repeat: repeat-x; + border-color: #51a351 #51a351 #387038; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff51a351', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.btn-success:hover, +.btn-success:focus, +.btn-success:active, +.btn-success.active, +.btn-success.disabled, +.btn-success[disabled] { + color: #ffffff; + background-color: #51a351; + *background-color: #499249; +} + +.btn-success:active, +.btn-success.active { + background-color: #408140 \9; +} + +.btn-info { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #49afcd; + *background-color: #2f96b4; + background-image: -moz-linear-gradient(top, #5bc0de, #2f96b4); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#2f96b4)); + background-image: -webkit-linear-gradient(top, #5bc0de, #2f96b4); + background-image: -o-linear-gradient(top, #5bc0de, #2f96b4); + background-image: linear-gradient(to bottom, #5bc0de, #2f96b4); + background-repeat: repeat-x; + border-color: #2f96b4 #2f96b4 #1f6377; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2f96b4', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.btn-info:hover, +.btn-info:focus, +.btn-info:active, +.btn-info.active, +.btn-info.disabled, +.btn-info[disabled] { + color: #ffffff; + background-color: #2f96b4; + *background-color: #2a85a0; +} + +.btn-info:active, +.btn-info.active { + background-color: #24748c \9; +} + +.btn-inverse { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #363636; + *background-color: #222222; + background-image: -moz-linear-gradient(top, #444444, #222222); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#444444), to(#222222)); + background-image: -webkit-linear-gradient(top, #444444, #222222); + background-image: -o-linear-gradient(top, #444444, #222222); + background-image: linear-gradient(to bottom, #444444, #222222); + background-repeat: repeat-x; + border-color: #222222 #222222 #000000; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444', endColorstr='#ff222222', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.btn-inverse:hover, +.btn-inverse:focus, +.btn-inverse:active, +.btn-inverse.active, +.btn-inverse.disabled, +.btn-inverse[disabled] { + color: #ffffff; + background-color: #222222; + *background-color: #151515; +} + +.btn-inverse:active, +.btn-inverse.active { + background-color: #080808 \9; +} + +button.btn, +input[type="submit"].btn { + *padding-top: 3px; + *padding-bottom: 3px; +} + +button.btn::-moz-focus-inner, +input[type="submit"].btn::-moz-focus-inner { + padding: 0; + border: 0; +} + +button.btn.btn-large, +input[type="submit"].btn.btn-large { + *padding-top: 7px; + *padding-bottom: 7px; +} + +button.btn.btn-small, +input[type="submit"].btn.btn-small { + *padding-top: 3px; + *padding-bottom: 3px; +} + +button.btn.btn-mini, +input[type="submit"].btn.btn-mini { + *padding-top: 1px; + *padding-bottom: 1px; +} + +.btn-link, +.btn-link:active, +.btn-link[disabled] { + background-color: transparent; + background-image: none; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} + +.btn-link { + color: #0088cc; + cursor: pointer; + border-color: transparent; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.btn-link:hover, +.btn-link:focus { + color: #005580; + text-decoration: underline; + background-color: transparent; +} + +.btn-link[disabled]:hover, +.btn-link[disabled]:focus { + color: #333333; + text-decoration: none; +} + +.btn-group { + position: relative; + display: inline-block; + *display: inline; + *margin-left: .3em; + font-size: 0; + white-space: nowrap; + vertical-align: middle; + *zoom: 1; +} + +.btn-group:first-child { + *margin-left: 0; +} + +.btn-group + .btn-group { + margin-left: 5px; +} + +.btn-toolbar { + margin-top: 10px; + margin-bottom: 10px; + font-size: 0; +} + +.btn-toolbar > .btn + .btn, +.btn-toolbar > .btn-group + .btn, +.btn-toolbar > .btn + .btn-group { + margin-left: 5px; +} + +.btn-group > .btn { + position: relative; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.btn-group > .btn + .btn { + margin-left: -1px; +} + +.btn-group > .btn, +.btn-group > .dropdown-menu, +.btn-group > .popover { + font-size: 14px; +} + +.btn-group > .btn-mini { + font-size: 10.5px; +} + +.btn-group > .btn-small { + font-size: 11.9px; +} + +.btn-group > .btn-large { + font-size: 17.5px; +} + +.btn-group > .btn:first-child { + margin-left: 0; + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; + -moz-border-radius-topleft: 4px; +} + +.btn-group > .btn:last-child, +.btn-group > .dropdown-toggle { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -moz-border-radius-topright: 4px; + -moz-border-radius-bottomright: 4px; +} + +.btn-group > .btn.large:first-child { + margin-left: 0; + -webkit-border-bottom-left-radius: 6px; + border-bottom-left-radius: 6px; + -webkit-border-top-left-radius: 6px; + border-top-left-radius: 6px; + -moz-border-radius-bottomleft: 6px; + -moz-border-radius-topleft: 6px; +} + +.btn-group > .btn.large:last-child, +.btn-group > .large.dropdown-toggle { + -webkit-border-top-right-radius: 6px; + border-top-right-radius: 6px; + -webkit-border-bottom-right-radius: 6px; + border-bottom-right-radius: 6px; + -moz-border-radius-topright: 6px; + -moz-border-radius-bottomright: 6px; +} + +.btn-group > .btn:hover, +.btn-group > .btn:focus, +.btn-group > .btn:active, +.btn-group > .btn.active { + z-index: 2; +} + +.btn-group .dropdown-toggle:active, +.btn-group.open .dropdown-toggle { + outline: 0; +} + +.btn-group > .btn + .dropdown-toggle { + *padding-top: 5px; + padding-right: 8px; + *padding-bottom: 5px; + padding-left: 8px; + -webkit-box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); +} + +.btn-group > .btn-mini + .dropdown-toggle { + *padding-top: 2px; + padding-right: 5px; + *padding-bottom: 2px; + padding-left: 5px; +} + +.btn-group > .btn-small + .dropdown-toggle { + *padding-top: 5px; + *padding-bottom: 4px; +} + +.btn-group > .btn-large + .dropdown-toggle { + *padding-top: 7px; + padding-right: 12px; + *padding-bottom: 7px; + padding-left: 12px; +} + +.btn-group.open .dropdown-toggle { + background-image: none; + -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); +} + +.btn-group.open .btn.dropdown-toggle { + background-color: #e6e6e6; +} + +.btn-group.open .btn-primary.dropdown-toggle { + background-color: #0044cc; +} + +.btn-group.open .btn-warning.dropdown-toggle { + background-color: #f89406; +} + +.btn-group.open .btn-danger.dropdown-toggle { + background-color: #bd362f; +} + +.btn-group.open .btn-success.dropdown-toggle { + background-color: #51a351; +} + +.btn-group.open .btn-info.dropdown-toggle { + background-color: #2f96b4; +} + +.btn-group.open .btn-inverse.dropdown-toggle { + background-color: #222222; +} + +.btn .caret { + margin-top: 8px; + margin-left: 0; +} + +.btn-large .caret { + margin-top: 6px; +} + +.btn-large .caret { + border-top-width: 5px; + border-right-width: 5px; + border-left-width: 5px; +} + +.btn-mini .caret, +.btn-small .caret { + margin-top: 8px; +} + +.dropup .btn-large .caret { + border-bottom-width: 5px; +} + +.btn-primary .caret, +.btn-warning .caret, +.btn-danger .caret, +.btn-info .caret, +.btn-success .caret, +.btn-inverse .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; +} + +.btn-group-vertical { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + + *zoom: 1; +} + +.btn-group-vertical > .btn { + display: block; + float: none; + max-width: 100%; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.btn-group-vertical > .btn + .btn { + margin-top: -1px; + margin-left: 0; +} + +.btn-group-vertical > .btn:first-child { + -webkit-border-radius: 4px 4px 0 0; + -moz-border-radius: 4px 4px 0 0; + border-radius: 4px 4px 0 0; +} + +.btn-group-vertical > .btn:last-child { + -webkit-border-radius: 0 0 4px 4px; + -moz-border-radius: 0 0 4px 4px; + border-radius: 0 0 4px 4px; +} + +.btn-group-vertical > .btn-large:first-child { + -webkit-border-radius: 6px 6px 0 0; + -moz-border-radius: 6px 6px 0 0; + border-radius: 6px 6px 0 0; +} + +.btn-group-vertical > .btn-large:last-child { + -webkit-border-radius: 0 0 6px 6px; + -moz-border-radius: 0 0 6px 6px; + border-radius: 0 0 6px 6px; +} + +.alert { + padding: 8px 35px 8px 14px; + margin-bottom: 20px; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + background-color: #fcf8e3; + border: 1px solid #fbeed5; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.alert, +.alert h4 { + color: #c09853; +} + +.alert h4 { + margin: 0; +} + +.alert .close { + position: relative; + top: -2px; + right: -21px; + line-height: 20px; +} + +.alert-success { + color: #468847; + background-color: #dff0d8; + border-color: #d6e9c6; +} + +.alert-success h4 { + color: #468847; +} + +.alert-danger, +.alert-error { + color: #b94a48; + background-color: #f2dede; + border-color: #eed3d7; +} + +.alert-danger h4, +.alert-error h4 { + color: #b94a48; +} + +.alert-info { + color: #3a87ad; + background-color: #d9edf7; + border-color: #bce8f1; +} + +.alert-info h4 { + color: #3a87ad; +} + +.alert-block { + padding-top: 14px; + padding-bottom: 14px; +} + +.alert-block > p, +.alert-block > ul { + margin-bottom: 0; +} + +.alert-block p + p { + margin-top: 5px; +} + +.nav { + margin-bottom: 20px; + margin-left: 0; + list-style: none; +} + +.nav > li > a { + display: block; +} + +.nav > li > a:hover, +.nav > li > a:focus { + text-decoration: none; + background-color: #eeeeee; +} + +.nav > li > a > img { + max-width: none; +} + +.nav > .pull-right { + float: right; +} + +.nav-header { + display: block; + padding: 3px 15px; + font-size: 11px; + font-weight: bold; + line-height: 20px; + color: #999999; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + text-transform: uppercase; +} + +.nav li + .nav-header { + margin-top: 9px; +} + +.nav-list { + padding-right: 15px; + padding-left: 15px; + margin-bottom: 0; +} + +.nav-list > li > a, +.nav-list .nav-header { + margin-right: -15px; + margin-left: -15px; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); +} + +.nav-list > li > a { + padding: 3px 15px; +} + +.nav-list > .active > a, +.nav-list > .active > a:hover, +.nav-list > .active > a:focus { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2); + background-color: #0088cc; +} + +.nav-list [class^="icon-"], +.nav-list [class*=" icon-"] { + margin-right: 2px; +} + +.nav-list .divider { + *width: 100%; + height: 1px; + margin: 9px 1px; + *margin: -5px 0 5px; + overflow: hidden; + background-color: #e5e5e5; + border-bottom: 1px solid #ffffff; +} + +.nav-tabs, +.nav-pills { + *zoom: 1; +} + +.nav-tabs:before, +.nav-pills:before, +.nav-tabs:after, +.nav-pills:after { + display: table; + line-height: 0; + content: ""; +} + +.nav-tabs:after, +.nav-pills:after { + clear: both; +} + +.nav-tabs > li, +.nav-pills > li { + float: left; +} + +.nav-tabs > li > a, +.nav-pills > li > a { + padding-right: 12px; + padding-left: 12px; + margin-right: 2px; + line-height: 14px; +} + +.nav-tabs { + border-bottom: 1px solid #ddd; +} + +.nav-tabs > li { + margin-bottom: -1px; +} + +.nav-tabs > li > a { + padding-top: 8px; + padding-bottom: 8px; + line-height: 20px; + border: 1px solid transparent; + -webkit-border-radius: 4px 4px 0 0; + -moz-border-radius: 4px 4px 0 0; + border-radius: 4px 4px 0 0; +} + +.nav-tabs > li > a:hover, +.nav-tabs > li > a:focus { + border-color: #eeeeee #eeeeee #dddddd; +} + +.nav-tabs > .active > a, +.nav-tabs > .active > a:hover, +.nav-tabs > .active > a:focus { + color: #555555; + cursor: default; + background-color: #ffffff; + border: 1px solid #ddd; + border-bottom-color: transparent; +} + +.nav-pills > li > a { + padding-top: 8px; + padding-bottom: 8px; + margin-top: 2px; + margin-bottom: 2px; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; +} + +.nav-pills > .active > a, +.nav-pills > .active > a:hover, +.nav-pills > .active > a:focus { + color: #ffffff; + background-color: #0088cc; +} + +.nav-stacked > li { + float: none; +} + +.nav-stacked > li > a { + margin-right: 0; +} + +.nav-tabs.nav-stacked { + border-bottom: 0; +} + +.nav-tabs.nav-stacked > li > a { + border: 1px solid #ddd; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.nav-tabs.nav-stacked > li:first-child > a { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topright: 4px; + -moz-border-radius-topleft: 4px; +} + +.nav-tabs.nav-stacked > li:last-child > a { + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -moz-border-radius-bottomright: 4px; + -moz-border-radius-bottomleft: 4px; +} + +.nav-tabs.nav-stacked > li > a:hover, +.nav-tabs.nav-stacked > li > a:focus { + z-index: 2; + border-color: #ddd; +} + +.nav-pills.nav-stacked > li > a { + margin-bottom: 3px; +} + +.nav-pills.nav-stacked > li:last-child > a { + margin-bottom: 1px; +} + +.nav-tabs .dropdown-menu { + -webkit-border-radius: 0 0 6px 6px; + -moz-border-radius: 0 0 6px 6px; + border-radius: 0 0 6px 6px; +} + +.nav-pills .dropdown-menu { + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} + +.nav .dropdown-toggle .caret { + margin-top: 6px; + border-top-color: #0088cc; + border-bottom-color: #0088cc; +} + +.nav .dropdown-toggle:hover .caret, +.nav .dropdown-toggle:focus .caret { + border-top-color: #005580; + border-bottom-color: #005580; +} + +/* move down carets for tabs */ + +.nav-tabs .dropdown-toggle .caret { + margin-top: 8px; +} + +.nav .active .dropdown-toggle .caret { + border-top-color: #fff; + border-bottom-color: #fff; +} + +.nav-tabs .active .dropdown-toggle .caret { + border-top-color: #555555; + border-bottom-color: #555555; +} + +.nav > .dropdown.active > a:hover, +.nav > .dropdown.active > a:focus { + cursor: pointer; +} + +.nav-tabs .open .dropdown-toggle, +.nav-pills .open .dropdown-toggle, +.nav > li.dropdown.open.active > a:hover, +.nav > li.dropdown.open.active > a:focus { + color: #ffffff; + background-color: #999999; + border-color: #999999; +} + +.nav li.dropdown.open .caret, +.nav li.dropdown.open.active .caret, +.nav li.dropdown.open a:hover .caret, +.nav li.dropdown.open a:focus .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; + opacity: 1; + filter: alpha(opacity=100); +} + +.tabs-stacked .open > a:hover, +.tabs-stacked .open > a:focus { + border-color: #999999; +} + +.tabbable { + *zoom: 1; +} + +.tabbable:before, +.tabbable:after { + display: table; + line-height: 0; + content: ""; +} + +.tabbable:after { + clear: both; +} + +.tab-content { + overflow: auto; +} + +.tabs-below > .nav-tabs, +.tabs-right > .nav-tabs, +.tabs-left > .nav-tabs { + border-bottom: 0; +} + +.tab-content > .tab-pane, +.pill-content > .pill-pane { + display: none; +} + +.tab-content > .active, +.pill-content > .active { + display: block; +} + +.tabs-below > .nav-tabs { + border-top: 1px solid #ddd; +} + +.tabs-below > .nav-tabs > li { + margin-top: -1px; + margin-bottom: 0; +} + +.tabs-below > .nav-tabs > li > a { + -webkit-border-radius: 0 0 4px 4px; + -moz-border-radius: 0 0 4px 4px; + border-radius: 0 0 4px 4px; +} + +.tabs-below > .nav-tabs > li > a:hover, +.tabs-below > .nav-tabs > li > a:focus { + border-top-color: #ddd; + border-bottom-color: transparent; +} + +.tabs-below > .nav-tabs > .active > a, +.tabs-below > .nav-tabs > .active > a:hover, +.tabs-below > .nav-tabs > .active > a:focus { + border-color: transparent #ddd #ddd #ddd; +} + +.tabs-left > .nav-tabs > li, +.tabs-right > .nav-tabs > li { + float: none; +} + +.tabs-left > .nav-tabs > li > a, +.tabs-right > .nav-tabs > li > a { + min-width: 74px; + margin-right: 0; + margin-bottom: 3px; +} + +.tabs-left > .nav-tabs { + float: left; + margin-right: 19px; + border-right: 1px solid #ddd; +} + +.tabs-left > .nav-tabs > li > a { + margin-right: -1px; + -webkit-border-radius: 4px 0 0 4px; + -moz-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; +} + +.tabs-left > .nav-tabs > li > a:hover, +.tabs-left > .nav-tabs > li > a:focus { + border-color: #eeeeee #dddddd #eeeeee #eeeeee; +} + +.tabs-left > .nav-tabs .active > a, +.tabs-left > .nav-tabs .active > a:hover, +.tabs-left > .nav-tabs .active > a:focus { + border-color: #ddd transparent #ddd #ddd; + *border-right-color: #ffffff; +} + +.tabs-right > .nav-tabs { + float: right; + margin-left: 19px; + border-left: 1px solid #ddd; +} + +.tabs-right > .nav-tabs > li > a { + margin-left: -1px; + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} + +.tabs-right > .nav-tabs > li > a:hover, +.tabs-right > .nav-tabs > li > a:focus { + border-color: #eeeeee #eeeeee #eeeeee #dddddd; +} + +.tabs-right > .nav-tabs .active > a, +.tabs-right > .nav-tabs .active > a:hover, +.tabs-right > .nav-tabs .active > a:focus { + border-color: #ddd #ddd #ddd transparent; + *border-left-color: #ffffff; +} + +.nav > .disabled > a { + color: #999999; +} + +.nav > .disabled > a:hover, +.nav > .disabled > a:focus { + text-decoration: none; + cursor: default; + background-color: transparent; +} + +.navbar { + *position: relative; + *z-index: 2; + margin-bottom: 20px; + overflow: visible; +} + +.navbar-inner { + min-height: 40px; + padding-right: 20px; + padding-left: 20px; + background-color: #fafafa; + background-image: -moz-linear-gradient(top, #ffffff, #f2f2f2); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#f2f2f2)); + background-image: -webkit-linear-gradient(top, #ffffff, #f2f2f2); + background-image: -o-linear-gradient(top, #ffffff, #f2f2f2); + background-image: linear-gradient(to bottom, #ffffff, #f2f2f2); + background-repeat: repeat-x; + border: 1px solid #d4d4d4; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff2f2f2', GradientType=0); + *zoom: 1; + -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); + -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); + box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); +} + +.navbar-inner:before, +.navbar-inner:after { + display: table; + line-height: 0; + content: ""; +} + +.navbar-inner:after { + clear: both; +} + +.navbar .container { + width: auto; +} + +.nav-collapse.collapse { + height: auto; + overflow: visible; +} + +.navbar .brand { + display: block; + float: left; + padding: 10px 20px 10px; + margin-left: -20px; + font-size: 20px; + font-weight: 200; + color: #777777; + text-shadow: 0 1px 0 #ffffff; +} + +.navbar .brand:hover, +.navbar .brand:focus { + text-decoration: none; +} + +.navbar-text { + margin-bottom: 0; + line-height: 40px; + color: #777777; +} + +.navbar-link { + color: #777777; +} + +.navbar-link:hover, +.navbar-link:focus { + color: #333333; +} + +.navbar .divider-vertical { + height: 40px; + margin: 0 9px; + border-right: 1px solid #ffffff; + border-left: 1px solid #f2f2f2; +} + +.navbar .btn, +.navbar .btn-group { + margin-top: 5px; +} + +.navbar .btn-group .btn, +.navbar .input-prepend .btn, +.navbar .input-append .btn, +.navbar .input-prepend .btn-group, +.navbar .input-append .btn-group { + margin-top: 0; +} + +.navbar-form { + margin-bottom: 0; + *zoom: 1; +} + +.navbar-form:before, +.navbar-form:after { + display: table; + line-height: 0; + content: ""; +} + +.navbar-form:after { + clear: both; +} + +.navbar-form input, +.navbar-form select, +.navbar-form .radio, +.navbar-form .checkbox { + margin-top: 5px; +} + +.navbar-form input, +.navbar-form select, +.navbar-form .btn { + display: inline-block; + margin-bottom: 0; +} + +.navbar-form input[type="image"], +.navbar-form input[type="checkbox"], +.navbar-form input[type="radio"] { + margin-top: 3px; +} + +.navbar-form .input-append, +.navbar-form .input-prepend { + margin-top: 5px; + white-space: nowrap; +} + +.navbar-form .input-append input, +.navbar-form .input-prepend input { + margin-top: 0; +} + +.navbar-search { + position: relative; + float: left; + margin-top: 5px; + margin-bottom: 0; +} + +.navbar-search .search-query { + padding: 4px 14px; + margin-bottom: 0; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 13px; + font-weight: normal; + line-height: 1; + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + border-radius: 15px; +} + +.navbar-static-top { + position: static; + margin-bottom: 0; +} + +.navbar-static-top .navbar-inner { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.navbar-fixed-top, +.navbar-fixed-bottom { + position: fixed; + right: 0; + left: 0; + z-index: 1030; + margin-bottom: 0; +} + +.navbar-fixed-top .navbar-inner, +.navbar-static-top .navbar-inner { + border-width: 0 0 1px; +} + +.navbar-fixed-bottom .navbar-inner { + border-width: 1px 0 0; +} + +.navbar-fixed-top .navbar-inner, +.navbar-fixed-bottom .navbar-inner { + padding-right: 0; + padding-left: 0; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.navbar-static-top .container, +.navbar-fixed-top .container, +.navbar-fixed-bottom .container { + width: 940px; +} + +.navbar-fixed-top { + top: 0; +} + +.navbar-fixed-top .navbar-inner, +.navbar-static-top .navbar-inner { + -webkit-box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1); + box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1); +} + +.navbar-fixed-bottom { + bottom: 0; +} + +.navbar-fixed-bottom .navbar-inner { + -webkit-box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.1); + box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.1); +} + +.navbar .nav { + position: relative; + left: 0; + display: block; + float: left; + margin: 0 10px 0 0; +} + +.navbar .nav.pull-right { + float: right; + margin-right: 0; +} + +.navbar .nav > li { + float: left; +} + +.navbar .nav > li > a { + float: none; + padding: 10px 15px 10px; + color: #777777; + text-decoration: none; + text-shadow: 0 1px 0 #ffffff; +} + +.navbar .nav .dropdown-toggle .caret { + margin-top: 8px; +} + +.navbar .nav > li > a:focus, +.navbar .nav > li > a:hover { + color: #333333; + text-decoration: none; + background-color: transparent; +} + +.navbar .nav > .active > a, +.navbar .nav > .active > a:hover, +.navbar .nav > .active > a:focus { + color: #555555; + text-decoration: none; + background-color: #e5e5e5; + -webkit-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); + -moz-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); + box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); +} + +.navbar .btn-navbar { + display: none; + float: right; + padding: 7px 10px; + margin-right: 5px; + margin-left: 5px; + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #ededed; + *background-color: #e5e5e5; + background-image: -moz-linear-gradient(top, #f2f2f2, #e5e5e5); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f2f2f2), to(#e5e5e5)); + background-image: -webkit-linear-gradient(top, #f2f2f2, #e5e5e5); + background-image: -o-linear-gradient(top, #f2f2f2, #e5e5e5); + background-image: linear-gradient(to bottom, #f2f2f2, #e5e5e5); + background-repeat: repeat-x; + border-color: #e5e5e5 #e5e5e5 #bfbfbf; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2', endColorstr='#ffe5e5e5', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075); + -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075); +} + +.navbar .btn-navbar:hover, +.navbar .btn-navbar:focus, +.navbar .btn-navbar:active, +.navbar .btn-navbar.active, +.navbar .btn-navbar.disabled, +.navbar .btn-navbar[disabled] { + color: #ffffff; + background-color: #e5e5e5; + *background-color: #d9d9d9; +} + +.navbar .btn-navbar:active, +.navbar .btn-navbar.active { + background-color: #cccccc \9; +} + +.navbar .btn-navbar .icon-bar { + display: block; + width: 18px; + height: 2px; + background-color: #f5f5f5; + -webkit-border-radius: 1px; + -moz-border-radius: 1px; + border-radius: 1px; + -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); + -moz-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); + box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); +} + +.btn-navbar .icon-bar + .icon-bar { + margin-top: 3px; +} + +.navbar .nav > li > .dropdown-menu:before { + position: absolute; + top: -7px; + left: 9px; + display: inline-block; + border-right: 7px solid transparent; + border-bottom: 7px solid #ccc; + border-left: 7px solid transparent; + border-bottom-color: rgba(0, 0, 0, 0.2); + content: ''; +} + +.navbar .nav > li > .dropdown-menu:after { + position: absolute; + top: -6px; + left: 10px; + display: inline-block; + border-right: 6px solid transparent; + border-bottom: 6px solid #ffffff; + border-left: 6px solid transparent; + content: ''; +} + +.navbar-fixed-bottom .nav > li > .dropdown-menu:before { + top: auto; + bottom: -7px; + border-top: 7px solid #ccc; + border-bottom: 0; + border-top-color: rgba(0, 0, 0, 0.2); +} + +.navbar-fixed-bottom .nav > li > .dropdown-menu:after { + top: auto; + bottom: -6px; + border-top: 6px solid #ffffff; + border-bottom: 0; +} + +.navbar .nav li.dropdown > a:hover .caret, +.navbar .nav li.dropdown > a:focus .caret { + border-top-color: #333333; + border-bottom-color: #333333; +} + +.navbar .nav li.dropdown.open > .dropdown-toggle, +.navbar .nav li.dropdown.active > .dropdown-toggle, +.navbar .nav li.dropdown.open.active > .dropdown-toggle { + color: #555555; + background-color: #e5e5e5; +} + +.navbar .nav li.dropdown > .dropdown-toggle .caret { + border-top-color: #777777; + border-bottom-color: #777777; +} + +.navbar .nav li.dropdown.open > .dropdown-toggle .caret, +.navbar .nav li.dropdown.active > .dropdown-toggle .caret, +.navbar .nav li.dropdown.open.active > .dropdown-toggle .caret { + border-top-color: #555555; + border-bottom-color: #555555; +} + +.navbar .pull-right > li > .dropdown-menu, +.navbar .nav > li > .dropdown-menu.pull-right { + right: 0; + left: auto; +} + +.navbar .pull-right > li > .dropdown-menu:before, +.navbar .nav > li > .dropdown-menu.pull-right:before { + right: 12px; + left: auto; +} + +.navbar .pull-right > li > .dropdown-menu:after, +.navbar .nav > li > .dropdown-menu.pull-right:after { + right: 13px; + left: auto; +} + +.navbar .pull-right > li > .dropdown-menu .dropdown-menu, +.navbar .nav > li > .dropdown-menu.pull-right .dropdown-menu { + right: 100%; + left: auto; + margin-right: -1px; + margin-left: 0; + -webkit-border-radius: 6px 0 6px 6px; + -moz-border-radius: 6px 0 6px 6px; + border-radius: 6px 0 6px 6px; +} + +.navbar-inverse .navbar-inner { + background-color: #1b1b1b; + background-image: -moz-linear-gradient(top, #222222, #111111); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#222222), to(#111111)); + background-image: -webkit-linear-gradient(top, #222222, #111111); + background-image: -o-linear-gradient(top, #222222, #111111); + background-image: linear-gradient(to bottom, #222222, #111111); + background-repeat: repeat-x; + border-color: #252525; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff111111', GradientType=0); +} + +.navbar-inverse .brand, +.navbar-inverse .nav > li > a { + color: #999999; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} + +.navbar-inverse .brand:hover, +.navbar-inverse .nav > li > a:hover, +.navbar-inverse .brand:focus, +.navbar-inverse .nav > li > a:focus { + color: #ffffff; +} + +.navbar-inverse .brand { + color: #999999; +} + +.navbar-inverse .navbar-text { + color: #999999; +} + +.navbar-inverse .nav > li > a:focus, +.navbar-inverse .nav > li > a:hover { + color: #ffffff; + background-color: transparent; +} + +.navbar-inverse .nav .active > a, +.navbar-inverse .nav .active > a:hover, +.navbar-inverse .nav .active > a:focus { + color: #ffffff; + background-color: #111111; +} + +.navbar-inverse .navbar-link { + color: #999999; +} + +.navbar-inverse .navbar-link:hover, +.navbar-inverse .navbar-link:focus { + color: #ffffff; +} + +.navbar-inverse .divider-vertical { + border-right-color: #222222; + border-left-color: #111111; +} + +.navbar-inverse .nav li.dropdown.open > .dropdown-toggle, +.navbar-inverse .nav li.dropdown.active > .dropdown-toggle, +.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle { + color: #ffffff; + background-color: #111111; +} + +.navbar-inverse .nav li.dropdown > a:hover .caret, +.navbar-inverse .nav li.dropdown > a:focus .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; +} + +.navbar-inverse .nav li.dropdown > .dropdown-toggle .caret { + border-top-color: #999999; + border-bottom-color: #999999; +} + +.navbar-inverse .nav li.dropdown.open > .dropdown-toggle .caret, +.navbar-inverse .nav li.dropdown.active > .dropdown-toggle .caret, +.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; +} + +.navbar-inverse .navbar-search .search-query { + color: #ffffff; + background-color: #515151; + border-color: #111111; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15); + -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15); + -webkit-transition: none; + -moz-transition: none; + -o-transition: none; + transition: none; +} + +.navbar-inverse .navbar-search .search-query:-moz-placeholder { + color: #cccccc; +} + +.navbar-inverse .navbar-search .search-query:-ms-input-placeholder { + color: #cccccc; +} + +.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder { + color: #cccccc; +} + +.navbar-inverse .navbar-search .search-query:focus, +.navbar-inverse .navbar-search .search-query.focused { + padding: 5px 15px; + color: #333333; + text-shadow: 0 1px 0 #ffffff; + background-color: #ffffff; + border: 0; + outline: 0; + -webkit-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); + -moz-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); + box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); +} + +.navbar-inverse .btn-navbar { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #0e0e0e; + *background-color: #040404; + background-image: -moz-linear-gradient(top, #151515, #040404); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#151515), to(#040404)); + background-image: -webkit-linear-gradient(top, #151515, #040404); + background-image: -o-linear-gradient(top, #151515, #040404); + background-image: linear-gradient(to bottom, #151515, #040404); + background-repeat: repeat-x; + border-color: #040404 #040404 #000000; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff151515', endColorstr='#ff040404', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.navbar-inverse .btn-navbar:hover, +.navbar-inverse .btn-navbar:focus, +.navbar-inverse .btn-navbar:active, +.navbar-inverse .btn-navbar.active, +.navbar-inverse .btn-navbar.disabled, +.navbar-inverse .btn-navbar[disabled] { + color: #ffffff; + background-color: #040404; + *background-color: #000000; +} + +.navbar-inverse .btn-navbar:active, +.navbar-inverse .btn-navbar.active { + background-color: #000000 \9; +} + +.breadcrumb { + padding: 8px 15px; + margin: 0 0 20px; + list-style: none; + background-color: #f5f5f5; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.breadcrumb > li { + display: inline-block; + *display: inline; + text-shadow: 0 1px 0 #ffffff; + *zoom: 1; +} + +.breadcrumb > li > .divider { + padding: 0 5px; + color: #ccc; +} + +.breadcrumb > .active { + color: #999999; +} + +.pagination { + margin: 20px 0; +} + +.pagination ul { + display: inline-block; + *display: inline; + margin-bottom: 0; + margin-left: 0; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + *zoom: 1; + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); +} + +.pagination ul > li { + display: inline; +} + +.pagination ul > li > a, +.pagination ul > li > span { + float: left; + padding: 4px 12px; + line-height: 20px; + text-decoration: none; + background-color: #ffffff; + border: 1px solid #dddddd; + border-left-width: 0; +} + +.pagination ul > li > a:hover, +.pagination ul > li > a:focus, +.pagination ul > .active > a, +.pagination ul > .active > span { + background-color: #f5f5f5; +} + +.pagination ul > .active > a, +.pagination ul > .active > span { + color: #999999; + cursor: default; +} + +.pagination ul > .disabled > span, +.pagination ul > .disabled > a, +.pagination ul > .disabled > a:hover, +.pagination ul > .disabled > a:focus { + color: #999999; + cursor: default; + background-color: transparent; +} + +.pagination ul > li:first-child > a, +.pagination ul > li:first-child > span { + border-left-width: 1px; + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; + -moz-border-radius-topleft: 4px; +} + +.pagination ul > li:last-child > a, +.pagination ul > li:last-child > span { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -moz-border-radius-topright: 4px; + -moz-border-radius-bottomright: 4px; +} + +.pagination-centered { + text-align: center; +} + +.pagination-right { + text-align: right; +} + +.pagination-large ul > li > a, +.pagination-large ul > li > span { + padding: 11px 19px; + font-size: 17.5px; +} + +.pagination-large ul > li:first-child > a, +.pagination-large ul > li:first-child > span { + -webkit-border-bottom-left-radius: 6px; + border-bottom-left-radius: 6px; + -webkit-border-top-left-radius: 6px; + border-top-left-radius: 6px; + -moz-border-radius-bottomleft: 6px; + -moz-border-radius-topleft: 6px; +} + +.pagination-large ul > li:last-child > a, +.pagination-large ul > li:last-child > span { + -webkit-border-top-right-radius: 6px; + border-top-right-radius: 6px; + -webkit-border-bottom-right-radius: 6px; + border-bottom-right-radius: 6px; + -moz-border-radius-topright: 6px; + -moz-border-radius-bottomright: 6px; +} + +.pagination-mini ul > li:first-child > a, +.pagination-small ul > li:first-child > a, +.pagination-mini ul > li:first-child > span, +.pagination-small ul > li:first-child > span { + -webkit-border-bottom-left-radius: 3px; + border-bottom-left-radius: 3px; + -webkit-border-top-left-radius: 3px; + border-top-left-radius: 3px; + -moz-border-radius-bottomleft: 3px; + -moz-border-radius-topleft: 3px; +} + +.pagination-mini ul > li:last-child > a, +.pagination-small ul > li:last-child > a, +.pagination-mini ul > li:last-child > span, +.pagination-small ul > li:last-child > span { + -webkit-border-top-right-radius: 3px; + border-top-right-radius: 3px; + -webkit-border-bottom-right-radius: 3px; + border-bottom-right-radius: 3px; + -moz-border-radius-topright: 3px; + -moz-border-radius-bottomright: 3px; +} + +.pagination-small ul > li > a, +.pagination-small ul > li > span { + padding: 2px 10px; + font-size: 11.9px; +} + +.pagination-mini ul > li > a, +.pagination-mini ul > li > span { + padding: 0 6px; + font-size: 10.5px; +} + +.pager { + margin: 20px 0; + text-align: center; + list-style: none; + *zoom: 1; +} + +.pager:before, +.pager:after { + display: table; + line-height: 0; + content: ""; +} + +.pager:after { + clear: both; +} + +.pager li { + display: inline; +} + +.pager li > a, +.pager li > span { + display: inline-block; + padding: 5px 14px; + background-color: #fff; + border: 1px solid #ddd; + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + border-radius: 15px; +} + +.pager li > a:hover, +.pager li > a:focus { + text-decoration: none; + background-color: #f5f5f5; +} + +.pager .next > a, +.pager .next > span { + float: right; +} + +.pager .previous > a, +.pager .previous > span { + float: left; +} + +.pager .disabled > a, +.pager .disabled > a:hover, +.pager .disabled > a:focus, +.pager .disabled > span { + color: #999999; + cursor: default; + background-color: #fff; +} + +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + background-color: #000000; +} + +.modal-backdrop.fade { + opacity: 0; +} + +.modal-backdrop, +.modal-backdrop.fade.in { + opacity: 0.8; + filter: alpha(opacity=80); +} + +.modal { + position: fixed; + top: 10%; + left: 50%; + z-index: 1050; + width: 560px; + margin-left: -280px; + background-color: #ffffff; + border: 1px solid #999; + border: 1px solid rgba(0, 0, 0, 0.3); + *border: 1px solid #999; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + outline: none; + -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + -moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + -webkit-background-clip: padding-box; + -moz-background-clip: padding-box; + background-clip: padding-box; +} + +.modal.fade { + top: -25%; + -webkit-transition: opacity 0.3s linear, top 0.3s ease-out; + -moz-transition: opacity 0.3s linear, top 0.3s ease-out; + -o-transition: opacity 0.3s linear, top 0.3s ease-out; + transition: opacity 0.3s linear, top 0.3s ease-out; +} + +.modal.fade.in { + top: 10%; +} + +.modal-header { + padding: 9px 15px; + border-bottom: 1px solid #eee; +} + +.modal-header .close { + margin-top: 2px; +} + +.modal-header h3 { + margin: 0; + line-height: 30px; +} + +.modal-body { + position: relative; + max-height: 400px; + padding: 15px; + overflow-y: auto; +} + +.modal-form { + margin-bottom: 0; +} + +.modal-footer { + padding: 14px 15px 15px; + margin-bottom: 0; + text-align: right; + background-color: #f5f5f5; + border-top: 1px solid #ddd; + -webkit-border-radius: 0 0 6px 6px; + -moz-border-radius: 0 0 6px 6px; + border-radius: 0 0 6px 6px; + *zoom: 1; + -webkit-box-shadow: inset 0 1px 0 #ffffff; + -moz-box-shadow: inset 0 1px 0 #ffffff; + box-shadow: inset 0 1px 0 #ffffff; +} + +.modal-footer:before, +.modal-footer:after { + display: table; + line-height: 0; + content: ""; +} + +.modal-footer:after { + clear: both; +} + +.modal-footer .btn + .btn { + margin-bottom: 0; + margin-left: 5px; +} + +.modal-footer .btn-group .btn + .btn { + margin-left: -1px; +} + +.modal-footer .btn-block + .btn-block { + margin-left: 0; +} + +.tooltip { + position: absolute; + z-index: 1030; + display: block; + font-size: 11px; + line-height: 1.4; + opacity: 0; + filter: alpha(opacity=0); + visibility: visible; +} + +.tooltip.in { + opacity: 0.8; + filter: alpha(opacity=80); +} + +.tooltip.top { + padding: 5px 0; + margin-top: -3px; +} + +.tooltip.right { + padding: 0 5px; + margin-left: 3px; +} + +.tooltip.bottom { + padding: 5px 0; + margin-top: 3px; +} + +.tooltip.left { + padding: 0 5px; + margin-left: -3px; +} + +.tooltip-inner { + max-width: 200px; + padding: 8px; + color: #ffffff; + text-align: center; + text-decoration: none; + background-color: #000000; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.tooltip-arrow { + position: absolute; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} + +.tooltip.top .tooltip-arrow { + bottom: 0; + left: 50%; + margin-left: -5px; + border-top-color: #000000; + border-width: 5px 5px 0; +} + +.tooltip.right .tooltip-arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-right-color: #000000; + border-width: 5px 5px 5px 0; +} + +.tooltip.left .tooltip-arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-left-color: #000000; + border-width: 5px 0 5px 5px; +} + +.tooltip.bottom .tooltip-arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-bottom-color: #000000; + border-width: 0 5px 5px; +} + +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1010; + display: none; + max-width: 276px; + padding: 1px; + text-align: left; + white-space: normal; + background-color: #ffffff; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -webkit-background-clip: padding-box; + -moz-background-clip: padding; + background-clip: padding-box; +} + +.popover.top { + margin-top: -10px; +} + +.popover.right { + margin-left: 10px; +} + +.popover.bottom { + margin-top: 10px; +} + +.popover.left { + margin-left: -10px; +} + +.popover-title { + padding: 8px 14px; + margin: 0; + font-size: 14px; + font-weight: normal; + line-height: 18px; + background-color: #f7f7f7; + border-bottom: 1px solid #ebebeb; + -webkit-border-radius: 5px 5px 0 0; + -moz-border-radius: 5px 5px 0 0; + border-radius: 5px 5px 0 0; +} + +.popover-title:empty { + display: none; +} + +.popover-content { + padding: 9px 14px; +} + +.popover .arrow, +.popover .arrow:after { + position: absolute; + display: block; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} + +.popover .arrow { + border-width: 11px; +} + +.popover .arrow:after { + border-width: 10px; + content: ""; +} + +.popover.top .arrow { + bottom: -11px; + left: 50%; + margin-left: -11px; + border-top-color: #999; + border-top-color: rgba(0, 0, 0, 0.25); + border-bottom-width: 0; +} + +.popover.top .arrow:after { + bottom: 1px; + margin-left: -10px; + border-top-color: #ffffff; + border-bottom-width: 0; +} + +.popover.right .arrow { + top: 50%; + left: -11px; + margin-top: -11px; + border-right-color: #999; + border-right-color: rgba(0, 0, 0, 0.25); + border-left-width: 0; +} + +.popover.right .arrow:after { + bottom: -10px; + left: 1px; + border-right-color: #ffffff; + border-left-width: 0; +} + +.popover.bottom .arrow { + top: -11px; + left: 50%; + margin-left: -11px; + border-bottom-color: #999; + border-bottom-color: rgba(0, 0, 0, 0.25); + border-top-width: 0; +} + +.popover.bottom .arrow:after { + top: 1px; + margin-left: -10px; + border-bottom-color: #ffffff; + border-top-width: 0; +} + +.popover.left .arrow { + top: 50%; + right: -11px; + margin-top: -11px; + border-left-color: #999; + border-left-color: rgba(0, 0, 0, 0.25); + border-right-width: 0; +} + +.popover.left .arrow:after { + right: 1px; + bottom: -10px; + border-left-color: #ffffff; + border-right-width: 0; +} + +.thumbnails { + margin-left: -20px; + list-style: none; + *zoom: 1; +} + +.thumbnails:before, +.thumbnails:after { + display: table; + line-height: 0; + content: ""; +} + +.thumbnails:after { + clear: both; +} + +.row-fluid .thumbnails { + margin-left: 0; +} + +.thumbnails > li { + float: left; + margin-bottom: 20px; + margin-left: 20px; +} + +.thumbnail { + display: block; + padding: 4px; + line-height: 20px; + border: 1px solid #ddd; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055); + -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055); + -webkit-transition: all 0.2s ease-in-out; + -moz-transition: all 0.2s ease-in-out; + -o-transition: all 0.2s ease-in-out; + transition: all 0.2s ease-in-out; +} + +a.thumbnail:hover, +a.thumbnail:focus { + border-color: #0088cc; + -webkit-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); + -moz-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); + box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); +} + +.thumbnail > img { + display: block; + max-width: 100%; + margin-right: auto; + margin-left: auto; +} + +.thumbnail .caption { + padding: 9px; + color: #555555; +} + +.media, +.media-body { + overflow: hidden; + *overflow: visible; + zoom: 1; +} + +.media, +.media .media { + margin-top: 15px; +} + +.media:first-child { + margin-top: 0; +} + +.media-object { + display: block; +} + +.media-heading { + margin: 0 0 5px; +} + +.media > .pull-left { + margin-right: 10px; +} + +.media > .pull-right { + margin-left: 10px; +} + +.media-list { + margin-left: 0; + list-style: none; +} + +.label, +.badge { + display: inline-block; + padding: 2px 4px; + font-size: 11.844px; + font-weight: bold; + line-height: 14px; + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + white-space: nowrap; + vertical-align: baseline; + background-color: #999999; +} + +.label { + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + +.badge { + padding-right: 9px; + padding-left: 9px; + -webkit-border-radius: 9px; + -moz-border-radius: 9px; + border-radius: 9px; +} + +.label:empty, +.badge:empty { + display: none; +} + +a.label:hover, +a.label:focus, +a.badge:hover, +a.badge:focus { + color: #ffffff; + text-decoration: none; + cursor: pointer; +} + +.label-important, +.badge-important { + background-color: #b94a48; +} + +.label-important[href], +.badge-important[href] { + background-color: #953b39; +} + +.label-warning, +.badge-warning { + background-color: #f89406; +} + +.label-warning[href], +.badge-warning[href] { + background-color: #c67605; +} + +.label-success, +.badge-success { + background-color: #468847; +} + +.label-success[href], +.badge-success[href] { + background-color: #356635; +} + +.label-info, +.badge-info { + background-color: #3a87ad; +} + +.label-info[href], +.badge-info[href] { + background-color: #2d6987; +} + +.label-inverse, +.badge-inverse { + background-color: #333333; +} + +.label-inverse[href], +.badge-inverse[href] { + background-color: #1a1a1a; +} + +.btn .label, +.btn .badge { + position: relative; + top: -1px; +} + +.btn-mini .label, +.btn-mini .badge { + top: 0; +} + +@-webkit-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} + +@-moz-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} + +@-ms-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} + +@-o-keyframes progress-bar-stripes { + from { + background-position: 0 0; + } + to { + background-position: 40px 0; + } +} + +@keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} + +.progress { + height: 20px; + margin-bottom: 20px; + overflow: hidden; + background-color: #f7f7f7; + background-image: -moz-linear-gradient(top, #f5f5f5, #f9f9f9); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f9f9f9)); + background-image: -webkit-linear-gradient(top, #f5f5f5, #f9f9f9); + background-image: -o-linear-gradient(top, #f5f5f5, #f9f9f9); + background-image: linear-gradient(to bottom, #f5f5f5, #f9f9f9); + background-repeat: repeat-x; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#fff9f9f9', GradientType=0); + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); +} + +.progress .bar { + float: left; + width: 0; + height: 100%; + font-size: 12px; + color: #ffffff; + text-align: center; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #0e90d2; + background-image: -moz-linear-gradient(top, #149bdf, #0480be); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#149bdf), to(#0480be)); + background-image: -webkit-linear-gradient(top, #149bdf, #0480be); + background-image: -o-linear-gradient(top, #149bdf, #0480be); + background-image: linear-gradient(to bottom, #149bdf, #0480be); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf', endColorstr='#ff0480be', GradientType=0); + -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + -moz-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + -webkit-transition: width 0.6s ease; + -moz-transition: width 0.6s ease; + -o-transition: width 0.6s ease; + transition: width 0.6s ease; +} + +.progress .bar + .bar { + -webkit-box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15); + -moz-box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15); + box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15); +} + +.progress-striped .bar { + background-color: #149bdf; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + -webkit-background-size: 40px 40px; + -moz-background-size: 40px 40px; + -o-background-size: 40px 40px; + background-size: 40px 40px; +} + +.progress.active .bar { + -webkit-animation: progress-bar-stripes 2s linear infinite; + -moz-animation: progress-bar-stripes 2s linear infinite; + -ms-animation: progress-bar-stripes 2s linear infinite; + -o-animation: progress-bar-stripes 2s linear infinite; + animation: progress-bar-stripes 2s linear infinite; +} + +.progress-danger .bar, +.progress .bar-danger { + background-color: #dd514c; + background-image: -moz-linear-gradient(top, #ee5f5b, #c43c35); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#c43c35)); + background-image: -webkit-linear-gradient(top, #ee5f5b, #c43c35); + background-image: -o-linear-gradient(top, #ee5f5b, #c43c35); + background-image: linear-gradient(to bottom, #ee5f5b, #c43c35); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffc43c35', GradientType=0); +} + +.progress-danger.progress-striped .bar, +.progress-striped .bar-danger { + background-color: #ee5f5b; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} + +.progress-success .bar, +.progress .bar-success { + background-color: #5eb95e; + background-image: -moz-linear-gradient(top, #62c462, #57a957); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#57a957)); + background-image: -webkit-linear-gradient(top, #62c462, #57a957); + background-image: -o-linear-gradient(top, #62c462, #57a957); + background-image: linear-gradient(to bottom, #62c462, #57a957); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff57a957', GradientType=0); +} + +.progress-success.progress-striped .bar, +.progress-striped .bar-success { + background-color: #62c462; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} + +.progress-info .bar, +.progress .bar-info { + background-color: #4bb1cf; + background-image: -moz-linear-gradient(top, #5bc0de, #339bb9); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#339bb9)); + background-image: -webkit-linear-gradient(top, #5bc0de, #339bb9); + background-image: -o-linear-gradient(top, #5bc0de, #339bb9); + background-image: linear-gradient(to bottom, #5bc0de, #339bb9); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff339bb9', GradientType=0); +} + +.progress-info.progress-striped .bar, +.progress-striped .bar-info { + background-color: #5bc0de; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} + +.progress-warning .bar, +.progress .bar-warning { + background-color: #faa732; + background-image: -moz-linear-gradient(top, #fbb450, #f89406); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406)); + background-image: -webkit-linear-gradient(top, #fbb450, #f89406); + background-image: -o-linear-gradient(top, #fbb450, #f89406); + background-image: linear-gradient(to bottom, #fbb450, #f89406); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0); +} + +.progress-warning.progress-striped .bar, +.progress-striped .bar-warning { + background-color: #fbb450; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} + +.accordion { + margin-bottom: 20px; +} + +.accordion-group { + margin-bottom: 2px; + border: 1px solid #e5e5e5; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.accordion-heading { + border-bottom: 0; +} + +.accordion-heading .accordion-toggle { + display: block; + padding: 8px 15px; +} + +.accordion-toggle { + cursor: pointer; +} + +.accordion-inner { + padding: 9px 15px; + border-top: 1px solid #e5e5e5; +} + +.carousel { + position: relative; + margin-bottom: 20px; + line-height: 1; +} + +.carousel-inner { + position: relative; + width: 100%; + overflow: hidden; +} + +.carousel-inner > .item { + position: relative; + display: none; + -webkit-transition: 0.6s ease-in-out left; + -moz-transition: 0.6s ease-in-out left; + -o-transition: 0.6s ease-in-out left; + transition: 0.6s ease-in-out left; +} + +.carousel-inner > .item > img, +.carousel-inner > .item > a > img { + display: block; + line-height: 1; +} + +.carousel-inner > .active, +.carousel-inner > .next, +.carousel-inner > .prev { + display: block; +} + +.carousel-inner > .active { + left: 0; +} + +.carousel-inner > .next, +.carousel-inner > .prev { + position: absolute; + top: 0; + width: 100%; +} + +.carousel-inner > .next { + left: 100%; +} + +.carousel-inner > .prev { + left: -100%; +} + +.carousel-inner > .next.left, +.carousel-inner > .prev.right { + left: 0; +} + +.carousel-inner > .active.left { + left: -100%; +} + +.carousel-inner > .active.right { + left: 100%; +} + +.carousel-control { + position: absolute; + top: 40%; + left: 15px; + width: 40px; + height: 40px; + margin-top: -20px; + font-size: 60px; + font-weight: 100; + line-height: 30px; + color: #ffffff; + text-align: center; + background: #222222; + border: 3px solid #ffffff; + -webkit-border-radius: 23px; + -moz-border-radius: 23px; + border-radius: 23px; + opacity: 0.5; + filter: alpha(opacity=50); +} + +.carousel-control.right { + right: 15px; + left: auto; +} + +.carousel-control:hover, +.carousel-control:focus { + color: #ffffff; + text-decoration: none; + opacity: 0.9; + filter: alpha(opacity=90); +} + +.carousel-indicators { + position: absolute; + top: 15px; + right: 15px; + z-index: 5; + margin: 0; + list-style: none; +} + +.carousel-indicators li { + display: block; + float: left; + width: 10px; + height: 10px; + margin-left: 5px; + text-indent: -999px; + background-color: #ccc; + background-color: rgba(255, 255, 255, 0.25); + border-radius: 5px; +} + +.carousel-indicators .active { + background-color: #fff; +} + +.carousel-caption { + position: absolute; + right: 0; + bottom: 0; + left: 0; + padding: 15px; + background: #333333; + background: rgba(0, 0, 0, 0.75); +} + +.carousel-caption h4, +.carousel-caption p { + line-height: 20px; + color: #ffffff; +} + +.carousel-caption h4 { + margin: 0 0 5px; +} + +.carousel-caption p { + margin-bottom: 0; +} + +.hero-unit { + padding: 60px; + margin-bottom: 30px; + font-size: 18px; + font-weight: 200; + line-height: 30px; + color: inherit; + background-color: #eeeeee; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} + +.hero-unit h1 { + margin-bottom: 0; + font-size: 60px; + line-height: 1; + letter-spacing: -1px; + color: inherit; +} + +.hero-unit li { + line-height: 30px; +} + +.pull-right { + float: right; +} + +.pull-left { + float: left; +} + +.hide { + display: none; +} + +.show { + display: block; +} + +.invisible { + visibility: hidden; +} + +.affix { + position: fixed; +} diff --git a/docs/_static/bootstrap-2.3.2/css/bootstrap.min.css b/docs/_static/bootstrap-2.3.2/css/bootstrap.min.css new file mode 100644 index 00000000..b6428e69 --- /dev/null +++ b/docs/_static/bootstrap-2.3.2/css/bootstrap.min.css @@ -0,0 +1,9 @@ +/*! + * Bootstrap v2.3.2 + * + * Copyright 2012 Twitter, Inc + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Designed and built with all the love in the world @twitter by @mdo and @fat. + */.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;line-height:0;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-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}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}a:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}a:hover,a:active{outline:0}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{width:auto\9;height:auto;max-width:100%;vertical-align:middle;border:0;-ms-interpolation-mode:bicubic}#map_canvas img,.google-maps img{max-width:none}button,input,select,textarea{margin:0;font-size:100%;vertical-align:middle}button,input{*overflow:visible;line-height:normal}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}button,html input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button}label,select,button,input[type="button"],input[type="reset"],input[type="submit"],input[type="radio"],input[type="checkbox"]{cursor:pointer}input[type="search"]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none}textarea{overflow:auto;vertical-align:top}@media print{*{color:#000!important;text-shadow:none!important;background:transparent!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}}body{margin:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:20px;color:#333;background-color:#fff}a{color:#08c;text-decoration:none}a:hover,a:focus{color:#005580;text-decoration:underline}.img-rounded{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.img-polaroid{padding:4px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.1);box-shadow:0 1px 3px rgba(0,0,0,0.1)}.img-circle{-webkit-border-radius:500px;-moz-border-radius:500px;border-radius:500px}.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.span12{width:940px}.span11{width:860px}.span10{width:780px}.span9{width:700px}.span8{width:620px}.span7{width:540px}.span6{width:460px}.span5{width:380px}.span4{width:300px}.span3{width:220px}.span2{width:140px}.span1{width:60px}.offset12{margin-left:980px}.offset11{margin-left:900px}.offset10{margin-left:820px}.offset9{margin-left:740px}.offset8{margin-left:660px}.offset7{margin-left:580px}.offset6{margin-left:500px}.offset5{margin-left:420px}.offset4{margin-left:340px}.offset3{margin-left:260px}.offset2{margin-left:180px}.offset1{margin-left:100px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.127659574468085%;*margin-left:2.074468085106383%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.127659574468085%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.48936170212765%;*width:91.43617021276594%}.row-fluid .span10{width:82.97872340425532%;*width:82.92553191489361%}.row-fluid .span9{width:74.46808510638297%;*width:74.41489361702126%}.row-fluid .span8{width:65.95744680851064%;*width:65.90425531914893%}.row-fluid .span7{width:57.44680851063829%;*width:57.39361702127659%}.row-fluid .span6{width:48.93617021276595%;*width:48.88297872340425%}.row-fluid .span5{width:40.42553191489362%;*width:40.37234042553192%}.row-fluid .span4{width:31.914893617021278%;*width:31.861702127659576%}.row-fluid .span3{width:23.404255319148934%;*width:23.351063829787233%}.row-fluid .span2{width:14.893617021276595%;*width:14.840425531914894%}.row-fluid .span1{width:6.382978723404255%;*width:6.329787234042553%}.row-fluid .offset12{margin-left:104.25531914893617%;*margin-left:104.14893617021275%}.row-fluid .offset12:first-child{margin-left:102.12765957446808%;*margin-left:102.02127659574467%}.row-fluid .offset11{margin-left:95.74468085106382%;*margin-left:95.6382978723404%}.row-fluid .offset11:first-child{margin-left:93.61702127659574%;*margin-left:93.51063829787232%}.row-fluid .offset10{margin-left:87.23404255319149%;*margin-left:87.12765957446807%}.row-fluid .offset10:first-child{margin-left:85.1063829787234%;*margin-left:84.99999999999999%}.row-fluid .offset9{margin-left:78.72340425531914%;*margin-left:78.61702127659572%}.row-fluid .offset9:first-child{margin-left:76.59574468085106%;*margin-left:76.48936170212764%}.row-fluid .offset8{margin-left:70.2127659574468%;*margin-left:70.10638297872339%}.row-fluid .offset8:first-child{margin-left:68.08510638297872%;*margin-left:67.9787234042553%}.row-fluid .offset7{margin-left:61.70212765957446%;*margin-left:61.59574468085106%}.row-fluid .offset7:first-child{margin-left:59.574468085106375%;*margin-left:59.46808510638297%}.row-fluid .offset6{margin-left:53.191489361702125%;*margin-left:53.085106382978715%}.row-fluid .offset6:first-child{margin-left:51.063829787234035%;*margin-left:50.95744680851063%}.row-fluid .offset5{margin-left:44.68085106382979%;*margin-left:44.57446808510638%}.row-fluid .offset5:first-child{margin-left:42.5531914893617%;*margin-left:42.4468085106383%}.row-fluid .offset4{margin-left:36.170212765957444%;*margin-left:36.06382978723405%}.row-fluid .offset4:first-child{margin-left:34.04255319148936%;*margin-left:33.93617021276596%}.row-fluid .offset3{margin-left:27.659574468085104%;*margin-left:27.5531914893617%}.row-fluid .offset3:first-child{margin-left:25.53191489361702%;*margin-left:25.425531914893618%}.row-fluid .offset2{margin-left:19.148936170212764%;*margin-left:19.04255319148936%}.row-fluid .offset2:first-child{margin-left:17.02127659574468%;*margin-left:16.914893617021278%}.row-fluid .offset1{margin-left:10.638297872340425%;*margin-left:10.53191489361702%}.row-fluid .offset1:first-child{margin-left:8.51063829787234%;*margin-left:8.404255319148938%}[class*="span"].hide,.row-fluid [class*="span"].hide{display:none}[class*="span"].pull-right,.row-fluid [class*="span"].pull-right{float:right}.container{margin-right:auto;margin-left:auto;*zoom:1}.container:before,.container:after{display:table;line-height:0;content:""}.container:after{clear:both}.container-fluid{padding-right:20px;padding-left:20px;*zoom:1}.container-fluid:before,.container-fluid:after{display:table;line-height:0;content:""}.container-fluid:after{clear:both}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:21px;font-weight:200;line-height:30px}small{font-size:85%}strong{font-weight:bold}em{font-style:italic}cite{font-style:normal}.muted{color:#999}a.muted:hover,a.muted:focus{color:#808080}.text-warning{color:#c09853}a.text-warning:hover,a.text-warning:focus{color:#a47e3c}.text-error{color:#b94a48}a.text-error:hover,a.text-error:focus{color:#953b39}.text-info{color:#3a87ad}a.text-info:hover,a.text-info:focus{color:#2d6987}.text-success{color:#468847}a.text-success:hover,a.text-success:focus{color:#356635}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}h1,h2,h3,h4,h5,h6{margin:10px 0;font-family:inherit;font-weight:bold;line-height:20px;color:inherit;text-rendering:optimizelegibility}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-weight:normal;line-height:1;color:#999}h1,h2,h3{line-height:40px}h1{font-size:38.5px}h2{font-size:31.5px}h3{font-size:24.5px}h4{font-size:17.5px}h5{font-size:14px}h6{font-size:11.9px}h1 small{font-size:24.5px}h2 small{font-size:17.5px}h3 small{font-size:14px}h4 small{font-size:14px}.page-header{padding-bottom:9px;margin:20px 0 30px;border-bottom:1px solid #eee}ul,ol{padding:0;margin:0 0 10px 25px}ul ul,ul ol,ol ol,ol ul{margin-bottom:0}li{line-height:20px}ul.unstyled,ol.unstyled{margin-left:0;list-style:none}ul.inline,ol.inline{margin-left:0;list-style:none}ul.inline>li,ol.inline>li{display:inline-block;*display:inline;padding-right:5px;padding-left:5px;*zoom:1}dl{margin-bottom:20px}dt,dd{line-height:20px}dt{font-weight:bold}dd{margin-left:10px}.dl-horizontal{*zoom:1}.dl-horizontal:before,.dl-horizontal:after{display:table;line-height:0;content:""}.dl-horizontal:after{clear:both}.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}hr{margin:20px 0;border:0;border-top:1px solid #eee;border-bottom:1px solid #fff}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999}abbr.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:0 0 0 15px;margin:0 0 20px;border-left:5px solid #eee}blockquote p{margin-bottom:0;font-size:17.5px;font-weight:300;line-height:1.25}blockquote small{display:block;line-height:20px;color:#999}blockquote small:before{content:'\2014 \00A0'}blockquote.pull-right{float:right;padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0}blockquote.pull-right p,blockquote.pull-right small{text-align:right}blockquote.pull-right small:before{content:''}blockquote.pull-right small:after{content:'\00A0 \2014'}q:before,q:after,blockquote:before,blockquote:after{content:""}address{display:block;margin-bottom:20px;font-style:normal;line-height:20px}code,pre{padding:0 3px 2px;font-family:Monaco,Menlo,Consolas,"Courier New",monospace;font-size:12px;color:#333;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}code{padding:2px 4px;color:#d14;white-space:nowrap;background-color:#f7f7f9;border:1px solid #e1e1e8}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:20px;word-break:break-all;word-wrap:break-word;white-space:pre;white-space:pre-wrap;background-color:#f5f5f5;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}pre.prettyprint{margin-bottom:20px}pre code{padding:0;color:inherit;white-space:pre;white-space:pre-wrap;background-color:transparent;border:0}.pre-scrollable{max-height:340px;overflow-y:scroll}form{margin:0 0 20px}fieldset{padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:40px;color:#333;border:0;border-bottom:1px solid #e5e5e5}legend small{font-size:15px;color:#999}label,input,button,select,textarea{font-size:14px;font-weight:normal;line-height:20px}input,button,select,textarea{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif}label{display:block;margin-bottom:5px}select,textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{display:inline-block;height:20px;padding:4px 6px;margin-bottom:10px;font-size:14px;line-height:20px;color:#555;vertical-align:middle;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}input,textarea,.uneditable-input{width:206px}textarea{height:auto}textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{background-color:#fff;border:1px solid #ccc;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border linear .2s,box-shadow linear .2s;-moz-transition:border linear .2s,box-shadow linear .2s;-o-transition:border linear .2s,box-shadow linear .2s;transition:border linear .2s,box-shadow linear .2s}textarea:focus,input[type="text"]:focus,input[type="password"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus,.uneditable-input:focus{border-color:rgba(82,168,236,0.8);outline:0;outline:thin dotted \9;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;*margin-top:0;line-height:normal}input[type="file"],input[type="image"],input[type="submit"],input[type="reset"],input[type="button"],input[type="radio"],input[type="checkbox"]{width:auto}select,input[type="file"]{height:30px;*margin-top:4px;line-height:30px}select{width:220px;background-color:#fff;border:1px solid #ccc}select[multiple],select[size]{height:auto}select:focus,input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.uneditable-input,.uneditable-textarea{color:#999;cursor:not-allowed;background-color:#fcfcfc;border-color:#ccc;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);box-shadow:inset 0 1px 2px rgba(0,0,0,0.025)}.uneditable-input{overflow:hidden;white-space:nowrap}.uneditable-textarea{width:auto;height:auto}input:-moz-placeholder,textarea:-moz-placeholder{color:#999}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#999}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#999}.radio,.checkbox{min-height:20px;padding-left:20px}.radio input[type="radio"],.checkbox input[type="checkbox"]{float:left;margin-left:-20px}.controls>.radio:first-child,.controls>.checkbox:first-child{padding-top:5px}.radio.inline,.checkbox.inline{display:inline-block;padding-top:5px;margin-bottom:0;vertical-align:middle}.radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline{margin-left:10px}.input-mini{width:60px}.input-small{width:90px}.input-medium{width:150px}.input-large{width:210px}.input-xlarge{width:270px}.input-xxlarge{width:530px}input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"]{float:none;margin-left:0}.input-append input[class*="span"],.input-append .uneditable-input[class*="span"],.input-prepend input[class*="span"],.input-prepend .uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"],.row-fluid .input-prepend [class*="span"],.row-fluid .input-append [class*="span"]{display:inline-block}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:926px}input.span11,textarea.span11,.uneditable-input.span11{width:846px}input.span10,textarea.span10,.uneditable-input.span10{width:766px}input.span9,textarea.span9,.uneditable-input.span9{width:686px}input.span8,textarea.span8,.uneditable-input.span8{width:606px}input.span7,textarea.span7,.uneditable-input.span7{width:526px}input.span6,textarea.span6,.uneditable-input.span6{width:446px}input.span5,textarea.span5,.uneditable-input.span5{width:366px}input.span4,textarea.span4,.uneditable-input.span4{width:286px}input.span3,textarea.span3,.uneditable-input.span3{width:206px}input.span2,textarea.span2,.uneditable-input.span2{width:126px}input.span1,textarea.span1,.uneditable-input.span1{width:46px}.controls-row{*zoom:1}.controls-row:before,.controls-row:after{display:table;line-height:0;content:""}.controls-row:after{clear:both}.controls-row [class*="span"],.row-fluid .controls-row [class*="span"]{float:left}.controls-row .checkbox[class*="span"],.controls-row .radio[class*="span"]{padding-top:5px}input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#eee}input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"][readonly],input[type="checkbox"][readonly]{background-color:transparent}.control-group.warning .control-label,.control-group.warning .help-block,.control-group.warning .help-inline{color:#c09853}.control-group.warning .checkbox,.control-group.warning .radio,.control-group.warning input,.control-group.warning select,.control-group.warning textarea{color:#c09853}.control-group.warning input,.control-group.warning select,.control-group.warning textarea{border-color:#c09853;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.warning input:focus,.control-group.warning select:focus,.control-group.warning textarea:focus{border-color:#a47e3c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e}.control-group.warning .input-prepend .add-on,.control-group.warning .input-append .add-on{color:#c09853;background-color:#fcf8e3;border-color:#c09853}.control-group.error .control-label,.control-group.error .help-block,.control-group.error .help-inline{color:#b94a48}.control-group.error .checkbox,.control-group.error .radio,.control-group.error input,.control-group.error select,.control-group.error textarea{color:#b94a48}.control-group.error input,.control-group.error select,.control-group.error textarea{border-color:#b94a48;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.error input:focus,.control-group.error select:focus,.control-group.error textarea:focus{border-color:#953b39;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392}.control-group.error .input-prepend .add-on,.control-group.error .input-append .add-on{color:#b94a48;background-color:#f2dede;border-color:#b94a48}.control-group.success .control-label,.control-group.success .help-block,.control-group.success .help-inline{color:#468847}.control-group.success .checkbox,.control-group.success .radio,.control-group.success input,.control-group.success select,.control-group.success textarea{color:#468847}.control-group.success input,.control-group.success select,.control-group.success textarea{border-color:#468847;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.success input:focus,.control-group.success select:focus,.control-group.success textarea:focus{border-color:#356635;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b}.control-group.success .input-prepend .add-on,.control-group.success .input-append .add-on{color:#468847;background-color:#dff0d8;border-color:#468847}.control-group.info .control-label,.control-group.info .help-block,.control-group.info .help-inline{color:#3a87ad}.control-group.info .checkbox,.control-group.info .radio,.control-group.info input,.control-group.info select,.control-group.info textarea{color:#3a87ad}.control-group.info input,.control-group.info select,.control-group.info textarea{border-color:#3a87ad;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.info input:focus,.control-group.info select:focus,.control-group.info textarea:focus{border-color:#2d6987;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3}.control-group.info .input-prepend .add-on,.control-group.info .input-append .add-on{color:#3a87ad;background-color:#d9edf7;border-color:#3a87ad}input:focus:invalid,textarea:focus:invalid,select:focus:invalid{color:#b94a48;border-color:#ee5f5b}input:focus:invalid:focus,textarea:focus:invalid:focus,select:focus:invalid:focus{border-color:#e9322d;-webkit-box-shadow:0 0 6px #f8b9b7;-moz-box-shadow:0 0 6px #f8b9b7;box-shadow:0 0 6px #f8b9b7}.form-actions{padding:19px 20px 20px;margin-top:20px;margin-bottom:20px;background-color:#f5f5f5;border-top:1px solid #e5e5e5;*zoom:1}.form-actions:before,.form-actions:after{display:table;line-height:0;content:""}.form-actions:after{clear:both}.help-block,.help-inline{color:#595959}.help-block{display:block;margin-bottom:10px}.help-inline{display:inline-block;*display:inline;padding-left:5px;vertical-align:middle;*zoom:1}.input-append,.input-prepend{display:inline-block;margin-bottom:10px;font-size:0;white-space:nowrap;vertical-align:middle}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input,.input-append .dropdown-menu,.input-prepend .dropdown-menu,.input-append .popover,.input-prepend .popover{font-size:14px}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input{position:relative;margin-bottom:0;*margin-left:0;vertical-align:top;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-append input:focus,.input-prepend input:focus,.input-append select:focus,.input-prepend select:focus,.input-append .uneditable-input:focus,.input-prepend .uneditable-input:focus{z-index:2}.input-append .add-on,.input-prepend .add-on{display:inline-block;width:auto;height:20px;min-width:16px;padding:4px 5px;font-size:14px;font-weight:normal;line-height:20px;text-align:center;text-shadow:0 1px 0 #fff;background-color:#eee;border:1px solid #ccc}.input-append .add-on,.input-prepend .add-on,.input-append .btn,.input-prepend .btn,.input-append .btn-group>.dropdown-toggle,.input-prepend .btn-group>.dropdown-toggle{vertical-align:top;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-append .active,.input-prepend .active{background-color:#a9dba9;border-color:#46a546}.input-prepend .add-on,.input-prepend .btn{margin-right:-1px}.input-prepend .add-on:first-child,.input-prepend .btn:first-child{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-append input,.input-append select,.input-append .uneditable-input{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-append input+.btn-group .btn:last-child,.input-append select+.btn-group .btn:last-child,.input-append .uneditable-input+.btn-group .btn:last-child{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-append .add-on,.input-append .btn,.input-append .btn-group{margin-left:-1px}.input-append .add-on:last-child,.input-append .btn:last-child,.input-append .btn-group:last-child>.dropdown-toggle{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append input,.input-prepend.input-append select,.input-prepend.input-append .uneditable-input{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-prepend.input-append input+.btn-group .btn,.input-prepend.input-append select+.btn-group .btn,.input-prepend.input-append .uneditable-input+.btn-group .btn{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append .add-on:first-child,.input-prepend.input-append .btn:first-child{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-prepend.input-append .add-on:last-child,.input-prepend.input-append .btn:last-child{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append .btn-group:first-child{margin-left:0}input.search-query{padding-right:14px;padding-right:4px \9;padding-left:14px;padding-left:4px \9;margin-bottom:0;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.form-search .input-append .search-query,.form-search .input-prepend .search-query{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.form-search .input-append .search-query{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}.form-search .input-append .btn{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .search-query{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .btn{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}.form-search input,.form-inline input,.form-horizontal input,.form-search textarea,.form-inline textarea,.form-horizontal textarea,.form-search select,.form-inline select,.form-horizontal select,.form-search .help-inline,.form-inline .help-inline,.form-horizontal .help-inline,.form-search .uneditable-input,.form-inline .uneditable-input,.form-horizontal .uneditable-input,.form-search .input-prepend,.form-inline .input-prepend,.form-horizontal .input-prepend,.form-search .input-append,.form-inline .input-append,.form-horizontal .input-append{display:inline-block;*display:inline;margin-bottom:0;vertical-align:middle;*zoom:1}.form-search .hide,.form-inline .hide,.form-horizontal .hide{display:none}.form-search label,.form-inline label,.form-search .btn-group,.form-inline .btn-group{display:inline-block}.form-search .input-append,.form-inline .input-append,.form-search .input-prepend,.form-inline .input-prepend{margin-bottom:0}.form-search .radio,.form-search .checkbox,.form-inline .radio,.form-inline .checkbox{padding-left:0;margin-bottom:0;vertical-align:middle}.form-search .radio input[type="radio"],.form-search .checkbox input[type="checkbox"],.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:left;margin-right:3px;margin-left:0}.control-group{margin-bottom:10px}legend+.control-group{margin-top:20px;-webkit-margin-top-collapse:separate}.form-horizontal .control-group{margin-bottom:20px;*zoom:1}.form-horizontal .control-group:before,.form-horizontal .control-group:after{display:table;line-height:0;content:""}.form-horizontal .control-group:after{clear:both}.form-horizontal .control-label{float:left;width:160px;padding-top:5px;text-align:right}.form-horizontal .controls{*display:inline-block;*padding-left:20px;margin-left:180px;*margin-left:0}.form-horizontal .controls:first-child{*padding-left:180px}.form-horizontal .help-block{margin-bottom:0}.form-horizontal input+.help-block,.form-horizontal select+.help-block,.form-horizontal textarea+.help-block,.form-horizontal .uneditable-input+.help-block,.form-horizontal .input-prepend+.help-block,.form-horizontal .input-append+.help-block{margin-top:10px}.form-horizontal .form-actions{padding-left:180px}table{max-width:100%;background-color:transparent;border-collapse:collapse;border-spacing:0}.table{width:100%;margin-bottom:20px}.table th,.table td{padding:8px;line-height:20px;text-align:left;vertical-align:top;border-top:1px solid #ddd}.table th{font-weight:bold}.table thead th{vertical-align:bottom}.table caption+thead tr:first-child th,.table caption+thead tr:first-child td,.table colgroup+thead tr:first-child th,.table colgroup+thead tr:first-child td,.table thead:first-child tr:first-child th,.table thead:first-child tr:first-child td{border-top:0}.table tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed th,.table-condensed td{padding:4px 5px}.table-bordered{border:1px solid #ddd;border-collapse:separate;*border-collapse:collapse;border-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.table-bordered th,.table-bordered td{border-left:1px solid #ddd}.table-bordered caption+thead tr:first-child th,.table-bordered caption+tbody tr:first-child th,.table-bordered caption+tbody tr:first-child td,.table-bordered colgroup+thead tr:first-child th,.table-bordered colgroup+tbody tr:first-child th,.table-bordered colgroup+tbody tr:first-child td,.table-bordered thead:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child td{border-top:0}.table-bordered thead:first-child tr:first-child>th:first-child,.table-bordered tbody:first-child tr:first-child>td:first-child,.table-bordered tbody:first-child tr:first-child>th:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}.table-bordered thead:first-child tr:first-child>th:last-child,.table-bordered tbody:first-child tr:first-child>td:last-child,.table-bordered tbody:first-child tr:first-child>th:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}.table-bordered thead:last-child tr:last-child>th:first-child,.table-bordered tbody:last-child tr:last-child>td:first-child,.table-bordered tbody:last-child tr:last-child>th:first-child,.table-bordered tfoot:last-child tr:last-child>td:first-child,.table-bordered tfoot:last-child tr:last-child>th:first-child{-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px}.table-bordered thead:last-child tr:last-child>th:last-child,.table-bordered tbody:last-child tr:last-child>td:last-child,.table-bordered tbody:last-child tr:last-child>th:last-child,.table-bordered tfoot:last-child tr:last-child>td:last-child,.table-bordered tfoot:last-child tr:last-child>th:last-child{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px}.table-bordered tfoot+tbody:last-child tr:last-child td:first-child{-webkit-border-bottom-left-radius:0;border-bottom-left-radius:0;-moz-border-radius-bottomleft:0}.table-bordered tfoot+tbody:last-child tr:last-child td:last-child{-webkit-border-bottom-right-radius:0;border-bottom-right-radius:0;-moz-border-radius-bottomright:0}.table-bordered caption+thead tr:first-child th:first-child,.table-bordered caption+tbody tr:first-child td:first-child,.table-bordered colgroup+thead tr:first-child th:first-child,.table-bordered colgroup+tbody tr:first-child td:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}.table-bordered caption+thead tr:first-child th:last-child,.table-bordered caption+tbody tr:first-child td:last-child,.table-bordered colgroup+thead tr:first-child th:last-child,.table-bordered colgroup+tbody tr:first-child td:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}.table-striped tbody>tr:nth-child(odd)>td,.table-striped tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}.table-hover tbody tr:hover>td,.table-hover tbody tr:hover>th{background-color:#f5f5f5}table td[class*="span"],table th[class*="span"],.row-fluid table td[class*="span"],.row-fluid table th[class*="span"]{display:table-cell;float:none;margin-left:0}.table td.span1,.table th.span1{float:none;width:44px;margin-left:0}.table td.span2,.table th.span2{float:none;width:124px;margin-left:0}.table td.span3,.table th.span3{float:none;width:204px;margin-left:0}.table td.span4,.table th.span4{float:none;width:284px;margin-left:0}.table td.span5,.table th.span5{float:none;width:364px;margin-left:0}.table td.span6,.table th.span6{float:none;width:444px;margin-left:0}.table td.span7,.table th.span7{float:none;width:524px;margin-left:0}.table td.span8,.table th.span8{float:none;width:604px;margin-left:0}.table td.span9,.table th.span9{float:none;width:684px;margin-left:0}.table td.span10,.table th.span10{float:none;width:764px;margin-left:0}.table td.span11,.table th.span11{float:none;width:844px;margin-left:0}.table td.span12,.table th.span12{float:none;width:924px;margin-left:0}.table tbody tr.success>td{background-color:#dff0d8}.table tbody tr.error>td{background-color:#f2dede}.table tbody tr.warning>td{background-color:#fcf8e3}.table tbody tr.info>td{background-color:#d9edf7}.table-hover tbody tr.success:hover>td{background-color:#d0e9c6}.table-hover tbody tr.error:hover>td{background-color:#ebcccc}.table-hover tbody tr.warning:hover>td{background-color:#faf2cc}.table-hover tbody tr.info:hover>td{background-color:#c4e3f3}[class^="icon-"],[class*=" icon-"]{display:inline-block;width:14px;height:14px;margin-top:1px;*margin-right:.3em;line-height:14px;vertical-align:text-top;background-image:url("../img/glyphicons-halflings.png");background-position:14px 14px;background-repeat:no-repeat}.icon-white,.nav-pills>.active>a>[class^="icon-"],.nav-pills>.active>a>[class*=" icon-"],.nav-list>.active>a>[class^="icon-"],.nav-list>.active>a>[class*=" icon-"],.navbar-inverse .nav>.active>a>[class^="icon-"],.navbar-inverse .nav>.active>a>[class*=" icon-"],.dropdown-menu>li>a:hover>[class^="icon-"],.dropdown-menu>li>a:focus>[class^="icon-"],.dropdown-menu>li>a:hover>[class*=" icon-"],.dropdown-menu>li>a:focus>[class*=" icon-"],.dropdown-menu>.active>a>[class^="icon-"],.dropdown-menu>.active>a>[class*=" icon-"],.dropdown-submenu:hover>a>[class^="icon-"],.dropdown-submenu:focus>a>[class^="icon-"],.dropdown-submenu:hover>a>[class*=" icon-"],.dropdown-submenu:focus>a>[class*=" icon-"]{background-image:url("../img/glyphicons-halflings-white.png")}.icon-glass{background-position:0 0}.icon-music{background-position:-24px 0}.icon-search{background-position:-48px 0}.icon-envelope{background-position:-72px 0}.icon-heart{background-position:-96px 0}.icon-star{background-position:-120px 0}.icon-star-empty{background-position:-144px 0}.icon-user{background-position:-168px 0}.icon-film{background-position:-192px 0}.icon-th-large{background-position:-216px 0}.icon-th{background-position:-240px 0}.icon-th-list{background-position:-264px 0}.icon-ok{background-position:-288px 0}.icon-remove{background-position:-312px 0}.icon-zoom-in{background-position:-336px 0}.icon-zoom-out{background-position:-360px 0}.icon-off{background-position:-384px 0}.icon-signal{background-position:-408px 0}.icon-cog{background-position:-432px 0}.icon-trash{background-position:-456px 0}.icon-home{background-position:0 -24px}.icon-file{background-position:-24px -24px}.icon-time{background-position:-48px -24px}.icon-road{background-position:-72px -24px}.icon-download-alt{background-position:-96px -24px}.icon-download{background-position:-120px -24px}.icon-upload{background-position:-144px -24px}.icon-inbox{background-position:-168px -24px}.icon-play-circle{background-position:-192px -24px}.icon-repeat{background-position:-216px -24px}.icon-refresh{background-position:-240px -24px}.icon-list-alt{background-position:-264px -24px}.icon-lock{background-position:-287px -24px}.icon-flag{background-position:-312px -24px}.icon-headphones{background-position:-336px -24px}.icon-volume-off{background-position:-360px -24px}.icon-volume-down{background-position:-384px -24px}.icon-volume-up{background-position:-408px -24px}.icon-qrcode{background-position:-432px -24px}.icon-barcode{background-position:-456px -24px}.icon-tag{background-position:0 -48px}.icon-tags{background-position:-25px -48px}.icon-book{background-position:-48px -48px}.icon-bookmark{background-position:-72px -48px}.icon-print{background-position:-96px -48px}.icon-camera{background-position:-120px -48px}.icon-font{background-position:-144px -48px}.icon-bold{background-position:-167px -48px}.icon-italic{background-position:-192px -48px}.icon-text-height{background-position:-216px -48px}.icon-text-width{background-position:-240px -48px}.icon-align-left{background-position:-264px -48px}.icon-align-center{background-position:-288px -48px}.icon-align-right{background-position:-312px -48px}.icon-align-justify{background-position:-336px -48px}.icon-list{background-position:-360px -48px}.icon-indent-left{background-position:-384px -48px}.icon-indent-right{background-position:-408px -48px}.icon-facetime-video{background-position:-432px -48px}.icon-picture{background-position:-456px -48px}.icon-pencil{background-position:0 -72px}.icon-map-marker{background-position:-24px -72px}.icon-adjust{background-position:-48px -72px}.icon-tint{background-position:-72px -72px}.icon-edit{background-position:-96px -72px}.icon-share{background-position:-120px -72px}.icon-check{background-position:-144px -72px}.icon-move{background-position:-168px -72px}.icon-step-backward{background-position:-192px -72px}.icon-fast-backward{background-position:-216px -72px}.icon-backward{background-position:-240px -72px}.icon-play{background-position:-264px -72px}.icon-pause{background-position:-288px -72px}.icon-stop{background-position:-312px -72px}.icon-forward{background-position:-336px -72px}.icon-fast-forward{background-position:-360px -72px}.icon-step-forward{background-position:-384px -72px}.icon-eject{background-position:-408px -72px}.icon-chevron-left{background-position:-432px -72px}.icon-chevron-right{background-position:-456px -72px}.icon-plus-sign{background-position:0 -96px}.icon-minus-sign{background-position:-24px -96px}.icon-remove-sign{background-position:-48px -96px}.icon-ok-sign{background-position:-72px -96px}.icon-question-sign{background-position:-96px -96px}.icon-info-sign{background-position:-120px -96px}.icon-screenshot{background-position:-144px -96px}.icon-remove-circle{background-position:-168px -96px}.icon-ok-circle{background-position:-192px -96px}.icon-ban-circle{background-position:-216px -96px}.icon-arrow-left{background-position:-240px -96px}.icon-arrow-right{background-position:-264px -96px}.icon-arrow-up{background-position:-289px -96px}.icon-arrow-down{background-position:-312px -96px}.icon-share-alt{background-position:-336px -96px}.icon-resize-full{background-position:-360px -96px}.icon-resize-small{background-position:-384px -96px}.icon-plus{background-position:-408px -96px}.icon-minus{background-position:-433px -96px}.icon-asterisk{background-position:-456px -96px}.icon-exclamation-sign{background-position:0 -120px}.icon-gift{background-position:-24px -120px}.icon-leaf{background-position:-48px -120px}.icon-fire{background-position:-72px -120px}.icon-eye-open{background-position:-96px -120px}.icon-eye-close{background-position:-120px -120px}.icon-warning-sign{background-position:-144px -120px}.icon-plane{background-position:-168px -120px}.icon-calendar{background-position:-192px -120px}.icon-random{width:16px;background-position:-216px -120px}.icon-comment{background-position:-240px -120px}.icon-magnet{background-position:-264px -120px}.icon-chevron-up{background-position:-288px -120px}.icon-chevron-down{background-position:-313px -119px}.icon-retweet{background-position:-336px -120px}.icon-shopping-cart{background-position:-360px -120px}.icon-folder-close{width:16px;background-position:-384px -120px}.icon-folder-open{width:16px;background-position:-408px -120px}.icon-resize-vertical{background-position:-432px -119px}.icon-resize-horizontal{background-position:-456px -118px}.icon-hdd{background-position:0 -144px}.icon-bullhorn{background-position:-24px -144px}.icon-bell{background-position:-48px -144px}.icon-certificate{background-position:-72px -144px}.icon-thumbs-up{background-position:-96px -144px}.icon-thumbs-down{background-position:-120px -144px}.icon-hand-right{background-position:-144px -144px}.icon-hand-left{background-position:-168px -144px}.icon-hand-up{background-position:-192px -144px}.icon-hand-down{background-position:-216px -144px}.icon-circle-arrow-right{background-position:-240px -144px}.icon-circle-arrow-left{background-position:-264px -144px}.icon-circle-arrow-up{background-position:-288px -144px}.icon-circle-arrow-down{background-position:-312px -144px}.icon-globe{background-position:-336px -144px}.icon-wrench{background-position:-360px -144px}.icon-tasks{background-position:-384px -144px}.icon-filter{background-position:-408px -144px}.icon-briefcase{background-position:-432px -144px}.icon-fullscreen{background-position:-456px -144px}.dropup,.dropdown{position:relative}.dropdown-toggle{*margin-bottom:-3px}.dropdown-toggle:active,.open .dropdown-toggle{outline:0}.caret{display:inline-block;width:0;height:0;vertical-align:top;border-top:4px solid #000;border-right:4px solid transparent;border-left:4px solid transparent;content:""}.dropdown .caret{margin-top:8px;margin-left:2px}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);*border-right-width:2px;*border-bottom-width:2px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:20px;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus,.dropdown-submenu:hover>a,.dropdown-submenu:focus>a{color:#fff;text-decoration:none;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0)}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;outline:0;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0)}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#999}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;cursor:default;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open{*z-index:1000}.open>.dropdown-menu{display:block}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid #000;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}.dropdown-submenu{position:relative}.dropdown-submenu>.dropdown-menu{top:0;left:100%;margin-top:-6px;margin-left:-1px;-webkit-border-radius:0 6px 6px 6px;-moz-border-radius:0 6px 6px 6px;border-radius:0 6px 6px 6px}.dropdown-submenu:hover>.dropdown-menu{display:block}.dropup .dropdown-submenu>.dropdown-menu{top:auto;bottom:0;margin-top:0;margin-bottom:-2px;-webkit-border-radius:5px 5px 5px 0;-moz-border-radius:5px 5px 5px 0;border-radius:5px 5px 5px 0}.dropdown-submenu>a:after{display:block;float:right;width:0;height:0;margin-top:5px;margin-right:-10px;border-color:transparent;border-left-color:#ccc;border-style:solid;border-width:5px 0 5px 5px;content:" "}.dropdown-submenu:hover>a:after{border-left-color:#fff}.dropdown-submenu.pull-left{float:none}.dropdown-submenu.pull-left>.dropdown-menu{left:-100%;margin-left:10px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}.dropdown .dropdown-menu .nav-header{padding-right:20px;padding-left:20px}.typeahead{z-index:1051;margin-top:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.well-large{padding:24px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.well-small{padding:9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.fade{opacity:0;-webkit-transition:opacity .15s linear;-moz-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;-moz-transition:height .35s ease;-o-transition:height .35s ease;transition:height .35s ease}.collapse.in{height:auto}.close{float:right;font-size:20px;font-weight:bold;line-height:20px;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;opacity:.4;filter:alpha(opacity=40)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.btn{display:inline-block;*display:inline;padding:4px 12px;margin-bottom:0;*margin-left:.3em;font-size:14px;line-height:20px;color:#333;text-align:center;text-shadow:0 1px 1px rgba(255,255,255,0.75);vertical-align:middle;cursor:pointer;background-color:#f5f5f5;*background-color:#e6e6e6;background-image:-moz-linear-gradient(top,#fff,#e6e6e6);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#e6e6e6));background-image:-webkit-linear-gradient(top,#fff,#e6e6e6);background-image:-o-linear-gradient(top,#fff,#e6e6e6);background-image:linear-gradient(to bottom,#fff,#e6e6e6);background-repeat:repeat-x;border:1px solid #ccc;*border:0;border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);border-bottom-color:#b3b3b3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffe6e6e6',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);*zoom:1;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.btn:hover,.btn:focus,.btn:active,.btn.active,.btn.disabled,.btn[disabled]{color:#333;background-color:#e6e6e6;*background-color:#d9d9d9}.btn:active,.btn.active{background-color:#ccc \9}.btn:first-child{*margin-left:0}.btn:hover,.btn:focus{color:#333;text-decoration:none;background-position:0 -15px;-webkit-transition:background-position .1s linear;-moz-transition:background-position .1s linear;-o-transition:background-position .1s linear;transition:background-position .1s linear}.btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn.disabled,.btn[disabled]{cursor:default;background-image:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-large{padding:11px 19px;font-size:17.5px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.btn-large [class^="icon-"],.btn-large [class*=" icon-"]{margin-top:4px}.btn-small{padding:2px 10px;font-size:11.9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.btn-small [class^="icon-"],.btn-small [class*=" icon-"]{margin-top:0}.btn-mini [class^="icon-"],.btn-mini [class*=" icon-"]{margin-top:-1px}.btn-mini{padding:0 6px;font-size:10.5px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.btn-block{display:block;width:100%;padding-right:0;padding-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.btn-primary.active,.btn-warning.active,.btn-danger.active,.btn-success.active,.btn-info.active,.btn-inverse.active{color:rgba(255,255,255,0.75)}.btn-primary{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#006dcc;*background-color:#04c;background-image:-moz-linear-gradient(top,#08c,#04c);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#04c));background-image:-webkit-linear-gradient(top,#08c,#04c);background-image:-o-linear-gradient(top,#08c,#04c);background-image:linear-gradient(to bottom,#08c,#04c);background-repeat:repeat-x;border-color:#04c #04c #002a80;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0044cc',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{color:#fff;background-color:#04c;*background-color:#003bb3}.btn-primary:active,.btn-primary.active{background-color:#039 \9}.btn-warning{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#faa732;*background-color:#f89406;background-image:-moz-linear-gradient(top,#fbb450,#f89406);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406));background-image:-webkit-linear-gradient(top,#fbb450,#f89406);background-image:-o-linear-gradient(top,#fbb450,#f89406);background-image:linear-gradient(to bottom,#fbb450,#f89406);background-repeat:repeat-x;border-color:#f89406 #f89406 #ad6704;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450',endColorstr='#fff89406',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled]{color:#fff;background-color:#f89406;*background-color:#df8505}.btn-warning:active,.btn-warning.active{background-color:#c67605 \9}.btn-danger{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#da4f49;*background-color:#bd362f;background-image:-moz-linear-gradient(top,#ee5f5b,#bd362f);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#bd362f));background-image:-webkit-linear-gradient(top,#ee5f5b,#bd362f);background-image:-o-linear-gradient(top,#ee5f5b,#bd362f);background-image:linear-gradient(to bottom,#ee5f5b,#bd362f);background-repeat:repeat-x;border-color:#bd362f #bd362f #802420;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b',endColorstr='#ffbd362f',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled]{color:#fff;background-color:#bd362f;*background-color:#a9302a}.btn-danger:active,.btn-danger.active{background-color:#942a25 \9}.btn-success{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#5bb75b;*background-color:#51a351;background-image:-moz-linear-gradient(top,#62c462,#51a351);background-image:-webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#51a351));background-image:-webkit-linear-gradient(top,#62c462,#51a351);background-image:-o-linear-gradient(top,#62c462,#51a351);background-image:linear-gradient(to bottom,#62c462,#51a351);background-repeat:repeat-x;border-color:#51a351 #51a351 #387038;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462',endColorstr='#ff51a351',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled]{color:#fff;background-color:#51a351;*background-color:#499249}.btn-success:active,.btn-success.active{background-color:#408140 \9}.btn-info{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#49afcd;*background-color:#2f96b4;background-image:-moz-linear-gradient(top,#5bc0de,#2f96b4);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#2f96b4));background-image:-webkit-linear-gradient(top,#5bc0de,#2f96b4);background-image:-o-linear-gradient(top,#5bc0de,#2f96b4);background-image:linear-gradient(to bottom,#5bc0de,#2f96b4);background-repeat:repeat-x;border-color:#2f96b4 #2f96b4 #1f6377;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff2f96b4',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled]{color:#fff;background-color:#2f96b4;*background-color:#2a85a0}.btn-info:active,.btn-info.active{background-color:#24748c \9}.btn-inverse{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#363636;*background-color:#222;background-image:-moz-linear-gradient(top,#444,#222);background-image:-webkit-gradient(linear,0 0,0 100%,from(#444),to(#222));background-image:-webkit-linear-gradient(top,#444,#222);background-image:-o-linear-gradient(top,#444,#222);background-image:linear-gradient(to bottom,#444,#222);background-repeat:repeat-x;border-color:#222 #222 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444',endColorstr='#ff222222',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-inverse:hover,.btn-inverse:focus,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled]{color:#fff;background-color:#222;*background-color:#151515}.btn-inverse:active,.btn-inverse.active{background-color:#080808 \9}button.btn,input[type="submit"].btn{*padding-top:3px;*padding-bottom:3px}button.btn::-moz-focus-inner,input[type="submit"].btn::-moz-focus-inner{padding:0;border:0}button.btn.btn-large,input[type="submit"].btn.btn-large{*padding-top:7px;*padding-bottom:7px}button.btn.btn-small,input[type="submit"].btn.btn-small{*padding-top:3px;*padding-bottom:3px}button.btn.btn-mini,input[type="submit"].btn.btn-mini{*padding-top:1px;*padding-bottom:1px}.btn-link,.btn-link:active,.btn-link[disabled]{background-color:transparent;background-image:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-link{color:#08c;cursor:pointer;border-color:transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-link:hover,.btn-link:focus{color:#005580;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,.btn-link[disabled]:focus{color:#333;text-decoration:none}.btn-group{position:relative;display:inline-block;*display:inline;*margin-left:.3em;font-size:0;white-space:nowrap;vertical-align:middle;*zoom:1}.btn-group:first-child{*margin-left:0}.btn-group+.btn-group{margin-left:5px}.btn-toolbar{margin-top:10px;margin-bottom:10px;font-size:0}.btn-toolbar>.btn+.btn,.btn-toolbar>.btn-group+.btn,.btn-toolbar>.btn+.btn-group{margin-left:5px}.btn-group>.btn{position:relative;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group>.btn+.btn{margin-left:-1px}.btn-group>.btn,.btn-group>.dropdown-menu,.btn-group>.popover{font-size:14px}.btn-group>.btn-mini{font-size:10.5px}.btn-group>.btn-small{font-size:11.9px}.btn-group>.btn-large{font-size:17.5px}.btn-group>.btn:first-child{margin-left:0;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-bottomleft:4px;-moz-border-radius-topleft:4px}.btn-group>.btn:last-child,.btn-group>.dropdown-toggle{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-bottomright:4px}.btn-group>.btn.large:first-child{margin-left:0;-webkit-border-bottom-left-radius:6px;border-bottom-left-radius:6px;-webkit-border-top-left-radius:6px;border-top-left-radius:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topleft:6px}.btn-group>.btn.large:last-child,.btn-group>.large.dropdown-toggle{-webkit-border-top-right-radius:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;border-bottom-right-radius:6px;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px}.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active{z-index:2}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{*padding-top:5px;padding-right:8px;*padding-bottom:5px;padding-left:8px;-webkit-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.btn-group>.btn-mini+.dropdown-toggle{*padding-top:2px;padding-right:5px;*padding-bottom:2px;padding-left:5px}.btn-group>.btn-small+.dropdown-toggle{*padding-top:5px;*padding-bottom:4px}.btn-group>.btn-large+.dropdown-toggle{*padding-top:7px;padding-right:12px;*padding-bottom:7px;padding-left:12px}.btn-group.open .dropdown-toggle{background-image:none;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn-group.open .btn.dropdown-toggle{background-color:#e6e6e6}.btn-group.open .btn-primary.dropdown-toggle{background-color:#04c}.btn-group.open .btn-warning.dropdown-toggle{background-color:#f89406}.btn-group.open .btn-danger.dropdown-toggle{background-color:#bd362f}.btn-group.open .btn-success.dropdown-toggle{background-color:#51a351}.btn-group.open .btn-info.dropdown-toggle{background-color:#2f96b4}.btn-group.open .btn-inverse.dropdown-toggle{background-color:#222}.btn .caret{margin-top:8px;margin-left:0}.btn-large .caret{margin-top:6px}.btn-large .caret{border-top-width:5px;border-right-width:5px;border-left-width:5px}.btn-mini .caret,.btn-small .caret{margin-top:8px}.dropup .btn-large .caret{border-bottom-width:5px}.btn-primary .caret,.btn-warning .caret,.btn-danger .caret,.btn-info .caret,.btn-success .caret,.btn-inverse .caret{border-top-color:#fff;border-bottom-color:#fff}.btn-group-vertical{display:inline-block;*display:inline;*zoom:1}.btn-group-vertical>.btn{display:block;float:none;max-width:100%;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group-vertical>.btn+.btn{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:first-child{-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.btn-group-vertical>.btn:last-child{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.btn-group-vertical>.btn-large:first-child{-webkit-border-radius:6px 6px 0 0;-moz-border-radius:6px 6px 0 0;border-radius:6px 6px 0 0}.btn-group-vertical>.btn-large:last-child{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.alert{padding:8px 35px 8px 14px;margin-bottom:20px;text-shadow:0 1px 0 rgba(255,255,255,0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.alert,.alert h4{color:#c09853}.alert h4{margin:0}.alert .close{position:relative;top:-2px;right:-21px;line-height:20px}.alert-success{color:#468847;background-color:#dff0d8;border-color:#d6e9c6}.alert-success h4{color:#468847}.alert-danger,.alert-error{color:#b94a48;background-color:#f2dede;border-color:#eed3d7}.alert-danger h4,.alert-error h4{color:#b94a48}.alert-info{color:#3a87ad;background-color:#d9edf7;border-color:#bce8f1}.alert-info h4{color:#3a87ad}.alert-block{padding-top:14px;padding-bottom:14px}.alert-block>p,.alert-block>ul{margin-bottom:0}.alert-block p+p{margin-top:5px}.nav{margin-bottom:20px;margin-left:0;list-style:none}.nav>li>a{display:block}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li>a>img{max-width:none}.nav>.pull-right{float:right}.nav-header{display:block;padding:3px 15px;font-size:11px;font-weight:bold;line-height:20px;color:#999;text-shadow:0 1px 0 rgba(255,255,255,0.5);text-transform:uppercase}.nav li+.nav-header{margin-top:9px}.nav-list{padding-right:15px;padding-left:15px;margin-bottom:0}.nav-list>li>a,.nav-list .nav-header{margin-right:-15px;margin-left:-15px;text-shadow:0 1px 0 rgba(255,255,255,0.5)}.nav-list>li>a{padding:3px 15px}.nav-list>.active>a,.nav-list>.active>a:hover,.nav-list>.active>a:focus{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.2);background-color:#08c}.nav-list [class^="icon-"],.nav-list [class*=" icon-"]{margin-right:2px}.nav-list .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.nav-tabs,.nav-pills{*zoom:1}.nav-tabs:before,.nav-pills:before,.nav-tabs:after,.nav-pills:after{display:table;line-height:0;content:""}.nav-tabs:after,.nav-pills:after{clear:both}.nav-tabs>li,.nav-pills>li{float:left}.nav-tabs>li>a,.nav-pills>li>a{padding-right:12px;padding-left:12px;margin-right:2px;line-height:14px}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{margin-bottom:-1px}.nav-tabs>li>a{padding-top:8px;padding-bottom:8px;line-height:20px;border:1px solid transparent;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover,.nav-tabs>li>a:focus{border-color:#eee #eee #ddd}.nav-tabs>.active>a,.nav-tabs>.active>a:hover,.nav-tabs>.active>a:focus{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-pills>li>a{padding-top:8px;padding-bottom:8px;margin-top:2px;margin-bottom:2px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.nav-pills>.active>a,.nav-pills>.active>a:hover,.nav-pills>.active>a:focus{color:#fff;background-color:#08c}.nav-stacked>li{float:none}.nav-stacked>li>a{margin-right:0}.nav-tabs.nav-stacked{border-bottom:0}.nav-tabs.nav-stacked>li>a{border:1px solid #ddd;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.nav-tabs.nav-stacked>li:first-child>a{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-topleft:4px}.nav-tabs.nav-stacked>li:last-child>a{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomright:4px;-moz-border-radius-bottomleft:4px}.nav-tabs.nav-stacked>li>a:hover,.nav-tabs.nav-stacked>li>a:focus{z-index:2;border-color:#ddd}.nav-pills.nav-stacked>li>a{margin-bottom:3px}.nav-pills.nav-stacked>li:last-child>a{margin-bottom:1px}.nav-tabs .dropdown-menu{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.nav-pills .dropdown-menu{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.nav .dropdown-toggle .caret{margin-top:6px;border-top-color:#08c;border-bottom-color:#08c}.nav .dropdown-toggle:hover .caret,.nav .dropdown-toggle:focus .caret{border-top-color:#005580;border-bottom-color:#005580}.nav-tabs .dropdown-toggle .caret{margin-top:8px}.nav .active .dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.nav-tabs .active .dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}.nav>.dropdown.active>a:hover,.nav>.dropdown.active>a:focus{cursor:pointer}.nav-tabs .open .dropdown-toggle,.nav-pills .open .dropdown-toggle,.nav>li.dropdown.open.active>a:hover,.nav>li.dropdown.open.active>a:focus{color:#fff;background-color:#999;border-color:#999}.nav li.dropdown.open .caret,.nav li.dropdown.open.active .caret,.nav li.dropdown.open a:hover .caret,.nav li.dropdown.open a:focus .caret{border-top-color:#fff;border-bottom-color:#fff;opacity:1;filter:alpha(opacity=100)}.tabs-stacked .open>a:hover,.tabs-stacked .open>a:focus{border-color:#999}.tabbable{*zoom:1}.tabbable:before,.tabbable:after{display:table;line-height:0;content:""}.tabbable:after{clear:both}.tab-content{overflow:auto}.tabs-below>.nav-tabs,.tabs-right>.nav-tabs,.tabs-left>.nav-tabs{border-bottom:0}.tab-content>.tab-pane,.pill-content>.pill-pane{display:none}.tab-content>.active,.pill-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:hover,.tabs-below>.nav-tabs>li>a:focus{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:hover,.tabs-below>.nav-tabs>.active>a:focus{border-color:transparent #ddd #ddd #ddd}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{min-width:74px;margin-right:0;margin-bottom:3px}.tabs-left>.nav-tabs{float:left;margin-right:19px;border-right:1px solid #ddd}.tabs-left>.nav-tabs>li>a{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:hover,.tabs-left>.nav-tabs>li>a:focus{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs .active>a,.tabs-left>.nav-tabs .active>a:hover,.tabs-left>.nav-tabs .active>a:focus{border-color:#ddd transparent #ddd #ddd;*border-right-color:#fff}.tabs-right>.nav-tabs{float:right;margin-left:19px;border-left:1px solid #ddd}.tabs-right>.nav-tabs>li>a{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:hover,.tabs-right>.nav-tabs>li>a:focus{border-color:#eee #eee #eee #ddd}.tabs-right>.nav-tabs .active>a,.tabs-right>.nav-tabs .active>a:hover,.tabs-right>.nav-tabs .active>a:focus{border-color:#ddd #ddd #ddd transparent;*border-left-color:#fff}.nav>.disabled>a{color:#999}.nav>.disabled>a:hover,.nav>.disabled>a:focus{text-decoration:none;cursor:default;background-color:transparent}.navbar{*position:relative;*z-index:2;margin-bottom:20px;overflow:visible}.navbar-inner{min-height:40px;padding-right:20px;padding-left:20px;background-color:#fafafa;background-image:-moz-linear-gradient(top,#fff,#f2f2f2);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#f2f2f2));background-image:-webkit-linear-gradient(top,#fff,#f2f2f2);background-image:-o-linear-gradient(top,#fff,#f2f2f2);background-image:linear-gradient(to bottom,#fff,#f2f2f2);background-repeat:repeat-x;border:1px solid #d4d4d4;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#fff2f2f2',GradientType=0);*zoom:1;-webkit-box-shadow:0 1px 4px rgba(0,0,0,0.065);-moz-box-shadow:0 1px 4px rgba(0,0,0,0.065);box-shadow:0 1px 4px rgba(0,0,0,0.065)}.navbar-inner:before,.navbar-inner:after{display:table;line-height:0;content:""}.navbar-inner:after{clear:both}.navbar .container{width:auto}.nav-collapse.collapse{height:auto;overflow:visible}.navbar .brand{display:block;float:left;padding:10px 20px 10px;margin-left:-20px;font-size:20px;font-weight:200;color:#777;text-shadow:0 1px 0 #fff}.navbar .brand:hover,.navbar .brand:focus{text-decoration:none}.navbar-text{margin-bottom:0;line-height:40px;color:#777}.navbar-link{color:#777}.navbar-link:hover,.navbar-link:focus{color:#333}.navbar .divider-vertical{height:40px;margin:0 9px;border-right:1px solid #fff;border-left:1px solid #f2f2f2}.navbar .btn,.navbar .btn-group{margin-top:5px}.navbar .btn-group .btn,.navbar .input-prepend .btn,.navbar .input-append .btn,.navbar .input-prepend .btn-group,.navbar .input-append .btn-group{margin-top:0}.navbar-form{margin-bottom:0;*zoom:1}.navbar-form:before,.navbar-form:after{display:table;line-height:0;content:""}.navbar-form:after{clear:both}.navbar-form input,.navbar-form select,.navbar-form .radio,.navbar-form .checkbox{margin-top:5px}.navbar-form input,.navbar-form select,.navbar-form .btn{display:inline-block;margin-bottom:0}.navbar-form input[type="image"],.navbar-form input[type="checkbox"],.navbar-form input[type="radio"]{margin-top:3px}.navbar-form .input-append,.navbar-form .input-prepend{margin-top:5px;white-space:nowrap}.navbar-form .input-append input,.navbar-form .input-prepend input{margin-top:0}.navbar-search{position:relative;float:left;margin-top:5px;margin-bottom:0}.navbar-search .search-query{padding:4px 14px;margin-bottom:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:1;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.navbar-static-top{position:static;margin-bottom:0}.navbar-static-top .navbar-inner{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030;margin-bottom:0}.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{border-width:0 0 1px}.navbar-fixed-bottom .navbar-inner{border-width:1px 0 0}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding-right:0;padding-left:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.navbar-fixed-top{top:0}.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{-webkit-box-shadow:0 1px 10px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 10px rgba(0,0,0,0.1);box-shadow:0 1px 10px rgba(0,0,0,0.1)}.navbar-fixed-bottom{bottom:0}.navbar-fixed-bottom .navbar-inner{-webkit-box-shadow:0 -1px 10px rgba(0,0,0,0.1);-moz-box-shadow:0 -1px 10px rgba(0,0,0,0.1);box-shadow:0 -1px 10px rgba(0,0,0,0.1)}.navbar .nav{position:relative;left:0;display:block;float:left;margin:0 10px 0 0}.navbar .nav.pull-right{float:right;margin-right:0}.navbar .nav>li{float:left}.navbar .nav>li>a{float:none;padding:10px 15px 10px;color:#777;text-decoration:none;text-shadow:0 1px 0 #fff}.navbar .nav .dropdown-toggle .caret{margin-top:8px}.navbar .nav>li>a:focus,.navbar .nav>li>a:hover{color:#333;text-decoration:none;background-color:transparent}.navbar .nav>.active>a,.navbar .nav>.active>a:hover,.navbar .nav>.active>a:focus{color:#555;text-decoration:none;background-color:#e5e5e5;-webkit-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);-moz-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);box-shadow:inset 0 3px 8px rgba(0,0,0,0.125)}.navbar .btn-navbar{display:none;float:right;padding:7px 10px;margin-right:5px;margin-left:5px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#ededed;*background-color:#e5e5e5;background-image:-moz-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f2f2f2),to(#e5e5e5));background-image:-webkit-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:-o-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:linear-gradient(to bottom,#f2f2f2,#e5e5e5);background-repeat:repeat-x;border-color:#e5e5e5 #e5e5e5 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2',endColorstr='#ffe5e5e5',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075)}.navbar .btn-navbar:hover,.navbar .btn-navbar:focus,.navbar .btn-navbar:active,.navbar .btn-navbar.active,.navbar .btn-navbar.disabled,.navbar .btn-navbar[disabled]{color:#fff;background-color:#e5e5e5;*background-color:#d9d9d9}.navbar .btn-navbar:active,.navbar .btn-navbar.active{background-color:#ccc \9}.navbar .btn-navbar .icon-bar{display:block;width:18px;height:2px;background-color:#f5f5f5;-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.25);-moz-box-shadow:0 1px 0 rgba(0,0,0,0.25);box-shadow:0 1px 0 rgba(0,0,0,0.25)}.btn-navbar .icon-bar+.icon-bar{margin-top:3px}.navbar .nav>li>.dropdown-menu:before{position:absolute;top:-7px;left:9px;display:inline-block;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-left:7px solid transparent;border-bottom-color:rgba(0,0,0,0.2);content:''}.navbar .nav>li>.dropdown-menu:after{position:absolute;top:-6px;left:10px;display:inline-block;border-right:6px solid transparent;border-bottom:6px solid #fff;border-left:6px solid transparent;content:''}.navbar-fixed-bottom .nav>li>.dropdown-menu:before{top:auto;bottom:-7px;border-top:7px solid #ccc;border-bottom:0;border-top-color:rgba(0,0,0,0.2)}.navbar-fixed-bottom .nav>li>.dropdown-menu:after{top:auto;bottom:-6px;border-top:6px solid #fff;border-bottom:0}.navbar .nav li.dropdown>a:hover .caret,.navbar .nav li.dropdown>a:focus .caret{border-top-color:#333;border-bottom-color:#333}.navbar .nav li.dropdown.open>.dropdown-toggle,.navbar .nav li.dropdown.active>.dropdown-toggle,.navbar .nav li.dropdown.open.active>.dropdown-toggle{color:#555;background-color:#e5e5e5}.navbar .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#777;border-bottom-color:#777}.navbar .nav li.dropdown.open>.dropdown-toggle .caret,.navbar .nav li.dropdown.active>.dropdown-toggle .caret,.navbar .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}.navbar .pull-right>li>.dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right{right:0;left:auto}.navbar .pull-right>li>.dropdown-menu:before,.navbar .nav>li>.dropdown-menu.pull-right:before{right:12px;left:auto}.navbar .pull-right>li>.dropdown-menu:after,.navbar .nav>li>.dropdown-menu.pull-right:after{right:13px;left:auto}.navbar .pull-right>li>.dropdown-menu .dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right .dropdown-menu{right:100%;left:auto;margin-right:-1px;margin-left:0;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}.navbar-inverse .navbar-inner{background-color:#1b1b1b;background-image:-moz-linear-gradient(top,#222,#111);background-image:-webkit-gradient(linear,0 0,0 100%,from(#222),to(#111));background-image:-webkit-linear-gradient(top,#222,#111);background-image:-o-linear-gradient(top,#222,#111);background-image:linear-gradient(to bottom,#222,#111);background-repeat:repeat-x;border-color:#252525;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222',endColorstr='#ff111111',GradientType=0)}.navbar-inverse .brand,.navbar-inverse .nav>li>a{color:#999;text-shadow:0 -1px 0 rgba(0,0,0,0.25)}.navbar-inverse .brand:hover,.navbar-inverse .nav>li>a:hover,.navbar-inverse .brand:focus,.navbar-inverse .nav>li>a:focus{color:#fff}.navbar-inverse .brand{color:#999}.navbar-inverse .navbar-text{color:#999}.navbar-inverse .nav>li>a:focus,.navbar-inverse .nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .nav .active>a,.navbar-inverse .nav .active>a:hover,.navbar-inverse .nav .active>a:focus{color:#fff;background-color:#111}.navbar-inverse .navbar-link{color:#999}.navbar-inverse .navbar-link:hover,.navbar-inverse .navbar-link:focus{color:#fff}.navbar-inverse .divider-vertical{border-right-color:#222;border-left-color:#111}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle{color:#fff;background-color:#111}.navbar-inverse .nav li.dropdown>a:hover .caret,.navbar-inverse .nav li.dropdown>a:focus .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#999;border-bottom-color:#999}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .navbar-search .search-query{color:#fff;background-color:#515151;border-color:#111;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-webkit-transition:none;-moz-transition:none;-o-transition:none;transition:none}.navbar-inverse .navbar-search .search-query:-moz-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query:-ms-input-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query:focus,.navbar-inverse .navbar-search .search-query.focused{padding:5px 15px;color:#333;text-shadow:0 1px 0 #fff;background-color:#fff;border:0;outline:0;-webkit-box-shadow:0 0 3px rgba(0,0,0,0.15);-moz-box-shadow:0 0 3px rgba(0,0,0,0.15);box-shadow:0 0 3px rgba(0,0,0,0.15)}.navbar-inverse .btn-navbar{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e0e0e;*background-color:#040404;background-image:-moz-linear-gradient(top,#151515,#040404);background-image:-webkit-gradient(linear,0 0,0 100%,from(#151515),to(#040404));background-image:-webkit-linear-gradient(top,#151515,#040404);background-image:-o-linear-gradient(top,#151515,#040404);background-image:linear-gradient(to bottom,#151515,#040404);background-repeat:repeat-x;border-color:#040404 #040404 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff151515',endColorstr='#ff040404',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.navbar-inverse .btn-navbar:hover,.navbar-inverse .btn-navbar:focus,.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active,.navbar-inverse .btn-navbar.disabled,.navbar-inverse .btn-navbar[disabled]{color:#fff;background-color:#040404;*background-color:#000}.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active{background-color:#000 \9}.breadcrumb{padding:8px 15px;margin:0 0 20px;list-style:none;background-color:#f5f5f5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.breadcrumb>li{display:inline-block;*display:inline;text-shadow:0 1px 0 #fff;*zoom:1}.breadcrumb>li>.divider{padding:0 5px;color:#ccc}.breadcrumb>.active{color:#999}.pagination{margin:20px 0}.pagination ul{display:inline-block;*display:inline;margin-bottom:0;margin-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;*zoom:1;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:0 1px 2px rgba(0,0,0,0.05);box-shadow:0 1px 2px rgba(0,0,0,0.05)}.pagination ul>li{display:inline}.pagination ul>li>a,.pagination ul>li>span{float:left;padding:4px 12px;line-height:20px;text-decoration:none;background-color:#fff;border:1px solid #ddd;border-left-width:0}.pagination ul>li>a:hover,.pagination ul>li>a:focus,.pagination ul>.active>a,.pagination ul>.active>span{background-color:#f5f5f5}.pagination ul>.active>a,.pagination ul>.active>span{color:#999;cursor:default}.pagination ul>.disabled>span,.pagination ul>.disabled>a,.pagination ul>.disabled>a:hover,.pagination ul>.disabled>a:focus{color:#999;cursor:default;background-color:transparent}.pagination ul>li:first-child>a,.pagination ul>li:first-child>span{border-left-width:1px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-bottomleft:4px;-moz-border-radius-topleft:4px}.pagination ul>li:last-child>a,.pagination ul>li:last-child>span{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-bottomright:4px}.pagination-centered{text-align:center}.pagination-right{text-align:right}.pagination-large ul>li>a,.pagination-large ul>li>span{padding:11px 19px;font-size:17.5px}.pagination-large ul>li:first-child>a,.pagination-large ul>li:first-child>span{-webkit-border-bottom-left-radius:6px;border-bottom-left-radius:6px;-webkit-border-top-left-radius:6px;border-top-left-radius:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topleft:6px}.pagination-large ul>li:last-child>a,.pagination-large ul>li:last-child>span{-webkit-border-top-right-radius:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;border-bottom-right-radius:6px;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px}.pagination-mini ul>li:first-child>a,.pagination-small ul>li:first-child>a,.pagination-mini ul>li:first-child>span,.pagination-small ul>li:first-child>span{-webkit-border-bottom-left-radius:3px;border-bottom-left-radius:3px;-webkit-border-top-left-radius:3px;border-top-left-radius:3px;-moz-border-radius-bottomleft:3px;-moz-border-radius-topleft:3px}.pagination-mini ul>li:last-child>a,.pagination-small ul>li:last-child>a,.pagination-mini ul>li:last-child>span,.pagination-small ul>li:last-child>span{-webkit-border-top-right-radius:3px;border-top-right-radius:3px;-webkit-border-bottom-right-radius:3px;border-bottom-right-radius:3px;-moz-border-radius-topright:3px;-moz-border-radius-bottomright:3px}.pagination-small ul>li>a,.pagination-small ul>li>span{padding:2px 10px;font-size:11.9px}.pagination-mini ul>li>a,.pagination-mini ul>li>span{padding:0 6px;font-size:10.5px}.pager{margin:20px 0;text-align:center;list-style:none;*zoom:1}.pager:before,.pager:after{display:table;line-height:0;content:""}.pager:after{clear:both}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#f5f5f5}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#999;cursor:default;background-color:#fff}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop,.modal-backdrop.fade.in{opacity:.8;filter:alpha(opacity=80)}.modal{position:fixed;top:10%;left:50%;z-index:1050;width:560px;margin-left:-280px;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,0.3);*border:1px solid #999;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;outline:0;-webkit-box-shadow:0 3px 7px rgba(0,0,0,0.3);-moz-box-shadow:0 3px 7px rgba(0,0,0,0.3);box-shadow:0 3px 7px rgba(0,0,0,0.3);-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box}.modal.fade{top:-25%;-webkit-transition:opacity .3s linear,top .3s ease-out;-moz-transition:opacity .3s linear,top .3s ease-out;-o-transition:opacity .3s linear,top .3s ease-out;transition:opacity .3s linear,top .3s ease-out}.modal.fade.in{top:10%}.modal-header{padding:9px 15px;border-bottom:1px solid #eee}.modal-header .close{margin-top:2px}.modal-header h3{margin:0;line-height:30px}.modal-body{position:relative;max-height:400px;padding:15px;overflow-y:auto}.modal-form{margin-bottom:0}.modal-footer{padding:14px 15px 15px;margin-bottom:0;text-align:right;background-color:#f5f5f5;border-top:1px solid #ddd;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;*zoom:1;-webkit-box-shadow:inset 0 1px 0 #fff;-moz-box-shadow:inset 0 1px 0 #fff;box-shadow:inset 0 1px 0 #fff}.modal-footer:before,.modal-footer:after{display:table;line-height:0;content:""}.modal-footer:after{clear:both}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.tooltip{position:absolute;z-index:1030;display:block;font-size:11px;line-height:1.4;opacity:0;filter:alpha(opacity=0);visibility:visible}.tooltip.in{opacity:.8;filter:alpha(opacity=80)}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-color:#000;border-width:5px 5px 0}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-right-color:#000;border-width:5px 5px 5px 0}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-left-color:#000;border-width:5px 0 5px 5px}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-bottom-color:#000;border-width:0 5px 5px}.popover{position:absolute;top:0;left:0;z-index:1010;display:none;max-width:276px;padding:1px;text-align:left;white-space:normal;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;font-weight:normal;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0}.popover-title:empty{display:none}.popover-content{padding:9px 14px}.popover .arrow,.popover .arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover .arrow{border-width:11px}.popover .arrow:after{border-width:10px;content:""}.popover.top .arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,0.25);border-bottom-width:0}.popover.top .arrow:after{bottom:1px;margin-left:-10px;border-top-color:#fff;border-bottom-width:0}.popover.right .arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,0.25);border-left-width:0}.popover.right .arrow:after{bottom:-10px;left:1px;border-right-color:#fff;border-left-width:0}.popover.bottom .arrow{top:-11px;left:50%;margin-left:-11px;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,0.25);border-top-width:0}.popover.bottom .arrow:after{top:1px;margin-left:-10px;border-bottom-color:#fff;border-top-width:0}.popover.left .arrow{top:50%;right:-11px;margin-top:-11px;border-left-color:#999;border-left-color:rgba(0,0,0,0.25);border-right-width:0}.popover.left .arrow:after{right:1px;bottom:-10px;border-left-color:#fff;border-right-width:0}.thumbnails{margin-left:-20px;list-style:none;*zoom:1}.thumbnails:before,.thumbnails:after{display:table;line-height:0;content:""}.thumbnails:after{clear:both}.row-fluid .thumbnails{margin-left:0}.thumbnails>li{float:left;margin-bottom:20px;margin-left:20px}.thumbnail{display:block;padding:4px;line-height:20px;border:1px solid #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.055);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.055);box-shadow:0 1px 3px rgba(0,0,0,0.055);-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}a.thumbnail:hover,a.thumbnail:focus{border-color:#08c;-webkit-box-shadow:0 1px 4px rgba(0,105,214,0.25);-moz-box-shadow:0 1px 4px rgba(0,105,214,0.25);box-shadow:0 1px 4px rgba(0,105,214,0.25)}.thumbnail>img{display:block;max-width:100%;margin-right:auto;margin-left:auto}.thumbnail .caption{padding:9px;color:#555}.media,.media-body{overflow:hidden;*overflow:visible;zoom:1}.media,.media .media{margin-top:15px}.media:first-child{margin-top:0}.media-object{display:block}.media-heading{margin:0 0 5px}.media>.pull-left{margin-right:10px}.media>.pull-right{margin-left:10px}.media-list{margin-left:0;list-style:none}.label,.badge{display:inline-block;padding:2px 4px;font-size:11.844px;font-weight:bold;line-height:14px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);white-space:nowrap;vertical-align:baseline;background-color:#999}.label{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.badge{padding-right:9px;padding-left:9px;-webkit-border-radius:9px;-moz-border-radius:9px;border-radius:9px}.label:empty,.badge:empty{display:none}a.label:hover,a.label:focus,a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}.label-important,.badge-important{background-color:#b94a48}.label-important[href],.badge-important[href]{background-color:#953b39}.label-warning,.badge-warning{background-color:#f89406}.label-warning[href],.badge-warning[href]{background-color:#c67605}.label-success,.badge-success{background-color:#468847}.label-success[href],.badge-success[href]{background-color:#356635}.label-info,.badge-info{background-color:#3a87ad}.label-info[href],.badge-info[href]{background-color:#2d6987}.label-inverse,.badge-inverse{background-color:#333}.label-inverse[href],.badge-inverse[href]{background-color:#1a1a1a}.btn .label,.btn .badge{position:relative;top:-1px}.btn-mini .label,.btn-mini .badge{top:0}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-moz-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-ms-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:0 0}to{background-position:40px 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f7f7f7;background-image:-moz-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f5f5f5),to(#f9f9f9));background-image:-webkit-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-o-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:linear-gradient(to bottom,#f5f5f5,#f9f9f9);background-repeat:repeat-x;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5',endColorstr='#fff9f9f9',GradientType=0);-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1)}.progress .bar{float:left;width:0;height:100%;font-size:12px;color:#fff;text-align:center;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e90d2;background-image:-moz-linear-gradient(top,#149bdf,#0480be);background-image:-webkit-gradient(linear,0 0,0 100%,from(#149bdf),to(#0480be));background-image:-webkit-linear-gradient(top,#149bdf,#0480be);background-image:-o-linear-gradient(top,#149bdf,#0480be);background-image:linear-gradient(to bottom,#149bdf,#0480be);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf',endColorstr='#ff0480be',GradientType=0);-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:width .6s ease;-moz-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress .bar+.bar{-webkit-box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15)}.progress-striped .bar{background-color:#149bdf;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;-moz-background-size:40px 40px;-o-background-size:40px 40px;background-size:40px 40px}.progress.active .bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-moz-animation:progress-bar-stripes 2s linear infinite;-ms-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-danger .bar,.progress .bar-danger{background-color:#dd514c;background-image:-moz-linear-gradient(top,#ee5f5b,#c43c35);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#c43c35));background-image:-webkit-linear-gradient(top,#ee5f5b,#c43c35);background-image:-o-linear-gradient(top,#ee5f5b,#c43c35);background-image:linear-gradient(to bottom,#ee5f5b,#c43c35);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b',endColorstr='#ffc43c35',GradientType=0)}.progress-danger.progress-striped .bar,.progress-striped .bar-danger{background-color:#ee5f5b;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-success .bar,.progress .bar-success{background-color:#5eb95e;background-image:-moz-linear-gradient(top,#62c462,#57a957);background-image:-webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#57a957));background-image:-webkit-linear-gradient(top,#62c462,#57a957);background-image:-o-linear-gradient(top,#62c462,#57a957);background-image:linear-gradient(to bottom,#62c462,#57a957);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462',endColorstr='#ff57a957',GradientType=0)}.progress-success.progress-striped .bar,.progress-striped .bar-success{background-color:#62c462;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-info .bar,.progress .bar-info{background-color:#4bb1cf;background-image:-moz-linear-gradient(top,#5bc0de,#339bb9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#339bb9));background-image:-webkit-linear-gradient(top,#5bc0de,#339bb9);background-image:-o-linear-gradient(top,#5bc0de,#339bb9);background-image:linear-gradient(to bottom,#5bc0de,#339bb9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff339bb9',GradientType=0)}.progress-info.progress-striped .bar,.progress-striped .bar-info{background-color:#5bc0de;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-warning .bar,.progress .bar-warning{background-color:#faa732;background-image:-moz-linear-gradient(top,#fbb450,#f89406);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406));background-image:-webkit-linear-gradient(top,#fbb450,#f89406);background-image:-o-linear-gradient(top,#fbb450,#f89406);background-image:linear-gradient(to bottom,#fbb450,#f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450',endColorstr='#fff89406',GradientType=0)}.progress-warning.progress-striped .bar,.progress-striped .bar-warning{background-color:#fbb450;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.accordion{margin-bottom:20px}.accordion-group{margin-bottom:2px;border:1px solid #e5e5e5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.accordion-heading{border-bottom:0}.accordion-heading .accordion-toggle{display:block;padding:8px 15px}.accordion-toggle{cursor:pointer}.accordion-inner{padding:9px 15px;border-top:1px solid #e5e5e5}.carousel{position:relative;margin-bottom:20px;line-height:1}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-moz-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;line-height:1}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:40%;left:15px;width:40px;height:40px;margin-top:-20px;font-size:60px;font-weight:100;line-height:30px;color:#fff;text-align:center;background:#222;border:3px solid #fff;-webkit-border-radius:23px;-moz-border-radius:23px;border-radius:23px;opacity:.5;filter:alpha(opacity=50)}.carousel-control.right{right:15px;left:auto}.carousel-control:hover,.carousel-control:focus{color:#fff;text-decoration:none;opacity:.9;filter:alpha(opacity=90)}.carousel-indicators{position:absolute;top:15px;right:15px;z-index:5;margin:0;list-style:none}.carousel-indicators li{display:block;float:left;width:10px;height:10px;margin-left:5px;text-indent:-999px;background-color:#ccc;background-color:rgba(255,255,255,0.25);border-radius:5px}.carousel-indicators .active{background-color:#fff}.carousel-caption{position:absolute;right:0;bottom:0;left:0;padding:15px;background:#333;background:rgba(0,0,0,0.75)}.carousel-caption h4,.carousel-caption p{line-height:20px;color:#fff}.carousel-caption h4{margin:0 0 5px}.carousel-caption p{margin-bottom:0}.hero-unit{padding:60px;margin-bottom:30px;font-size:18px;font-weight:200;line-height:30px;color:inherit;background-color:#eee;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.hero-unit h1{margin-bottom:0;font-size:60px;line-height:1;letter-spacing:-1px;color:inherit}.hero-unit li{line-height:30px}.pull-right{float:right}.pull-left{float:left}.hide{display:none}.show{display:block}.invisible{visibility:hidden}.affix{position:fixed} diff --git a/docs/_static/bootstrap-2.3.2/img/glyphicons-halflings-white.png b/docs/_static/bootstrap-2.3.2/img/glyphicons-halflings-white.png new file mode 100644 index 0000000000000000000000000000000000000000..3bf6484a29d8da269f9bc874b25493a45fae3bae GIT binary patch literal 8777 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 B7G?kd literal 0 HcmV?d00001 diff --git a/docs/_static/bootstrap-2.3.2/img/glyphicons-halflings.png b/docs/_static/bootstrap-2.3.2/img/glyphicons-halflings.png new file mode 100644 index 0000000000000000000000000000000000000000..a9969993201f9cee63cf9f49217646347297b643 GIT binary patch literal 12799 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 literal 0 HcmV?d00001 diff --git a/docs/_static/bootstrap-2.3.2/js/bootstrap.js b/docs/_static/bootstrap-2.3.2/js/bootstrap.js new file mode 100644 index 00000000..638bb187 --- /dev/null +++ b/docs/_static/bootstrap-2.3.2/js/bootstrap.js @@ -0,0 +1,2287 @@ +/* =================================================== + * bootstrap-transition.js v2.3.2 + * http://twitter.github.com/bootstrap/javascript.html#transitions + * =================================================== + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* CSS TRANSITION SUPPORT (http://www.modernizr.com/) + * ======================================================= */ + + $(function () { + + $.support.transition = (function () { + + var transitionEnd = (function () { + + var el = document.createElement('bootstrap') + , transEndEventNames = { + 'WebkitTransition' : 'webkitTransitionEnd' + , 'MozTransition' : 'transitionend' + , 'OTransition' : 'oTransitionEnd otransitionend' + , 'transition' : 'transitionend' + } + , name + + for (name in transEndEventNames){ + if (el.style[name] !== undefined) { + return transEndEventNames[name] + } + } + + }()) + + return transitionEnd && { + end: transitionEnd + } + + })() + + }) + +}(window.$jqTheme || window.jQuery); +/* ========================================================== + * bootstrap-alert.js v2.3.2 + * http://twitter.github.com/bootstrap/javascript.html#alerts + * ========================================================== + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* ALERT CLASS DEFINITION + * ====================== */ + + var dismiss = '[data-dismiss="alert"]' + , Alert = function (el) { + $(el).on('click', dismiss, this.close) + } + + Alert.prototype.close = function (e) { + var $this = $(this) + , selector = $this.attr('data-target') + , $parent + + if (!selector) { + selector = $this.attr('href') + selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 + } + + $parent = $(selector) + + e && e.preventDefault() + + $parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent()) + + $parent.trigger(e = $.Event('close')) + + if (e.isDefaultPrevented()) return + + $parent.removeClass('in') + + function removeElement() { + $parent + .trigger('closed') + .remove() + } + + $.support.transition && $parent.hasClass('fade') ? + $parent.on($.support.transition.end, removeElement) : + removeElement() + } + + + /* ALERT PLUGIN DEFINITION + * ======================= */ + + var old = $.fn.alert + + $.fn.alert = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('alert') + if (!data) $this.data('alert', (data = new Alert(this))) + if (typeof option == 'string') data[option].call($this) + }) + } + + $.fn.alert.Constructor = Alert + + + /* ALERT NO CONFLICT + * ================= */ + + $.fn.alert.noConflict = function () { + $.fn.alert = old + return this + } + + + /* ALERT DATA-API + * ============== */ + + $(document).on('click.alert.data-api', dismiss, Alert.prototype.close) + +}(window.$jqTheme || window.jQuery); +/* ============================================================ + * bootstrap-button.js v2.3.2 + * http://twitter.github.com/bootstrap/javascript.html#buttons + * ============================================================ + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================ */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* BUTTON PUBLIC CLASS DEFINITION + * ============================== */ + + var Button = function (element, options) { + this.$element = $(element) + this.options = $.extend({}, $.fn.button.defaults, options) + } + + Button.prototype.setState = function (state) { + var d = 'disabled' + , $el = this.$element + , data = $el.data() + , val = $el.is('input') ? 'val' : 'html' + + state = state + 'Text' + data.resetText || $el.data('resetText', $el[val]()) + + $el[val](data[state] || this.options[state]) + + // push to event loop to allow forms to submit + setTimeout(function () { + state == 'loadingText' ? + $el.addClass(d).attr(d, d) : + $el.removeClass(d).removeAttr(d) + }, 0) + } + + Button.prototype.toggle = function () { + var $parent = this.$element.closest('[data-toggle="buttons-radio"]') + + $parent && $parent + .find('.active') + .removeClass('active') + + this.$element.toggleClass('active') + } + + + /* BUTTON PLUGIN DEFINITION + * ======================== */ + + var old = $.fn.button + + $.fn.button = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('button') + , options = typeof option == 'object' && option + if (!data) $this.data('button', (data = new Button(this, options))) + if (option == 'toggle') data.toggle() + else if (option) data.setState(option) + }) + } + + $.fn.button.defaults = { + loadingText: 'loading...' + } + + $.fn.button.Constructor = Button + + + /* BUTTON NO CONFLICT + * ================== */ + + $.fn.button.noConflict = function () { + $.fn.button = old + return this + } + + + /* BUTTON DATA-API + * =============== */ + + $(document).on('click.button.data-api', '[data-toggle^=button]', function (e) { + var $btn = $(e.target) + if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn') + $btn.button('toggle') + }) + +}(window.$jqTheme || window.jQuery); +/* ========================================================== + * bootstrap-carousel.js v2.3.2 + * http://twitter.github.com/bootstrap/javascript.html#carousel + * ========================================================== + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* CAROUSEL CLASS DEFINITION + * ========================= */ + + var Carousel = function (element, options) { + this.$element = $(element) + this.$indicators = this.$element.find('.carousel-indicators') + this.options = options + this.options.pause == 'hover' && this.$element + .on('mouseenter', $.proxy(this.pause, this)) + .on('mouseleave', $.proxy(this.cycle, this)) + } + + Carousel.prototype = { + + cycle: function (e) { + if (!e) this.paused = false + if (this.interval) clearInterval(this.interval); + this.options.interval + && !this.paused + && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) + return this + } + + , getActiveIndex: function () { + this.$active = this.$element.find('.item.active') + this.$items = this.$active.parent().children() + return this.$items.index(this.$active) + } + + , to: function (pos) { + var activeIndex = this.getActiveIndex() + , that = this + + if (pos > (this.$items.length - 1) || pos < 0) return + + if (this.sliding) { + return this.$element.one('slid', function () { + that.to(pos) + }) + } + + if (activeIndex == pos) { + return this.pause().cycle() + } + + return this.slide(pos > activeIndex ? 'next' : 'prev', $(this.$items[pos])) + } + + , pause: function (e) { + if (!e) this.paused = true + if (this.$element.find('.next, .prev').length && $.support.transition.end) { + this.$element.trigger($.support.transition.end) + this.cycle(true) + } + clearInterval(this.interval) + this.interval = null + return this + } + + , next: function () { + if (this.sliding) return + return this.slide('next') + } + + , prev: function () { + if (this.sliding) return + return this.slide('prev') + } + + , slide: function (type, next) { + var $active = this.$element.find('.item.active') + , $next = next || $active[type]() + , isCycling = this.interval + , direction = type == 'next' ? 'left' : 'right' + , fallback = type == 'next' ? 'first' : 'last' + , that = this + , e + + this.sliding = true + + isCycling && this.pause() + + $next = $next.length ? $next : this.$element.find('.item')[fallback]() + + e = $.Event('slide', { + relatedTarget: $next[0] + , direction: direction + }) + + if ($next.hasClass('active')) return + + if (this.$indicators.length) { + this.$indicators.find('.active').removeClass('active') + this.$element.one('slid', function () { + var $nextIndicator = $(that.$indicators.children()[that.getActiveIndex()]) + $nextIndicator && $nextIndicator.addClass('active') + }) + } + + if ($.support.transition && this.$element.hasClass('slide')) { + this.$element.trigger(e) + if (e.isDefaultPrevented()) return + $next.addClass(type) + $next[0].offsetWidth // force reflow + $active.addClass(direction) + $next.addClass(direction) + this.$element.one($.support.transition.end, function () { + $next.removeClass([type, direction].join(' ')).addClass('active') + $active.removeClass(['active', direction].join(' ')) + that.sliding = false + setTimeout(function () { that.$element.trigger('slid') }, 0) + }) + } else { + this.$element.trigger(e) + if (e.isDefaultPrevented()) return + $active.removeClass('active') + $next.addClass('active') + this.sliding = false + this.$element.trigger('slid') + } + + isCycling && this.cycle() + + return this + } + + } + + + /* CAROUSEL PLUGIN DEFINITION + * ========================== */ + + var old = $.fn.carousel + + $.fn.carousel = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('carousel') + , options = $.extend({}, $.fn.carousel.defaults, typeof option == 'object' && option) + , action = typeof option == 'string' ? option : options.slide + if (!data) $this.data('carousel', (data = new Carousel(this, options))) + if (typeof option == 'number') data.to(option) + else if (action) data[action]() + else if (options.interval) data.pause().cycle() + }) + } + + $.fn.carousel.defaults = { + interval: 5000 + , pause: 'hover' + } + + $.fn.carousel.Constructor = Carousel + + + /* CAROUSEL NO CONFLICT + * ==================== */ + + $.fn.carousel.noConflict = function () { + $.fn.carousel = old + return this + } + + /* CAROUSEL DATA-API + * ================= */ + + $(document).on('click.carousel.data-api', '[data-slide], [data-slide-to]', function (e) { + var $this = $(this), href + , $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7 + , options = $.extend({}, $target.data(), $this.data()) + , slideIndex + + $target.carousel(options) + + if (slideIndex = $this.attr('data-slide-to')) { + $target.data('carousel').pause().to(slideIndex).cycle() + } + + e.preventDefault() + }) + +}(window.$jqTheme || window.jQuery); +/* ============================================================= + * bootstrap-collapse.js v2.3.2 + * http://twitter.github.com/bootstrap/javascript.html#collapse + * ============================================================= + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================ */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* COLLAPSE PUBLIC CLASS DEFINITION + * ================================ */ + + var Collapse = function (element, options) { + this.$element = $(element) + this.options = $.extend({}, $.fn.collapse.defaults, options) + + if (this.options.parent) { + this.$parent = $(this.options.parent) + } + + this.options.toggle && this.toggle() + } + + Collapse.prototype = { + + constructor: Collapse + + , dimension: function () { + var hasWidth = this.$element.hasClass('width') + return hasWidth ? 'width' : 'height' + } + + , show: function () { + var dimension + , scroll + , actives + , hasData + + if (this.transitioning || this.$element.hasClass('in')) return + + dimension = this.dimension() + scroll = $.camelCase(['scroll', dimension].join('-')) + actives = this.$parent && this.$parent.find('> .accordion-group > .in') + + if (actives && actives.length) { + hasData = actives.data('collapse') + if (hasData && hasData.transitioning) return + actives.collapse('hide') + hasData || actives.data('collapse', null) + } + + this.$element[dimension](0) + this.transition('addClass', $.Event('show'), 'shown') + $.support.transition && this.$element[dimension](this.$element[0][scroll]) + } + + , hide: function () { + var dimension + if (this.transitioning || !this.$element.hasClass('in')) return + dimension = this.dimension() + this.reset(this.$element[dimension]()) + this.transition('removeClass', $.Event('hide'), 'hidden') + this.$element[dimension](0) + } + + , reset: function (size) { + var dimension = this.dimension() + + this.$element + .removeClass('collapse') + [dimension](size || 'auto') + [0].offsetWidth + + this.$element[size !== null ? 'addClass' : 'removeClass']('collapse') + + return this + } + + , transition: function (method, startEvent, completeEvent) { + var that = this + , complete = function () { + if (startEvent.type == 'show') that.reset() + that.transitioning = 0 + that.$element.trigger(completeEvent) + } + + this.$element.trigger(startEvent) + + if (startEvent.isDefaultPrevented()) return + + this.transitioning = 1 + + this.$element[method]('in') + + $.support.transition && this.$element.hasClass('collapse') ? + this.$element.one($.support.transition.end, complete) : + complete() + } + + , toggle: function () { + this[this.$element.hasClass('in') ? 'hide' : 'show']() + } + + } + + + /* COLLAPSE PLUGIN DEFINITION + * ========================== */ + + var old = $.fn.collapse + + $.fn.collapse = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('collapse') + , options = $.extend({}, $.fn.collapse.defaults, $this.data(), typeof option == 'object' && option) + if (!data) $this.data('collapse', (data = new Collapse(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + $.fn.collapse.defaults = { + toggle: true + } + + $.fn.collapse.Constructor = Collapse + + + /* COLLAPSE NO CONFLICT + * ==================== */ + + $.fn.collapse.noConflict = function () { + $.fn.collapse = old + return this + } + + + /* COLLAPSE DATA-API + * ================= */ + + $(document).on('click.collapse.data-api', '[data-toggle=collapse]', function (e) { + var $this = $(this), href + , target = $this.attr('data-target') + || e.preventDefault() + || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7 + , option = $(target).data('collapse') ? 'toggle' : $this.data() + $this[$(target).hasClass('in') ? 'addClass' : 'removeClass']('collapsed') + $(target).collapse(option) + }) + +}(window.$jqTheme || window.jQuery); +/* ============================================================ + * bootstrap-dropdown.js v2.3.2 + * http://twitter.github.com/bootstrap/javascript.html#dropdowns + * ============================================================ + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================ */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* DROPDOWN CLASS DEFINITION + * ========================= */ + + var toggle = '[data-toggle=dropdown]' + , Dropdown = function (element) { + var $el = $(element).on('click.dropdown.data-api', this.toggle) + $('html').on('click.dropdown.data-api', function () { + $el.parent().removeClass('open') + }) + } + + Dropdown.prototype = { + + constructor: Dropdown + + , toggle: function (e) { + var $this = $(this) + , $parent + , isActive + + if ($this.is('.disabled, :disabled')) return + + $parent = getParent($this) + + isActive = $parent.hasClass('open') + + clearMenus() + + if (!isActive) { + if ('ontouchstart' in document.documentElement) { + // if mobile we we use a backdrop because click events don't delegate + $('

&a3_zr0BE;>nxa%@8P-|e;DjC3LOJS8Tm?IxVmxf+04T?~YuNJ$GeGUP+DuVI7*>9daK( z!0((-iK|>u^=>mSc;82%tg3$_M76Elw3{|Z#lVL9^nQaY)l%TzOCy}V)FW4o@BAD% z26{r<4FN7CwRqoT1QmEFZPOwP!Ni z7ru#BB06={!oDxp^M*XY>JRj>h6_T^pr%JLUtVOvJ~hSVl0IG-f$j>f6BnCBn7W*& zfV2)F0X2bB7Uo9ZfO_ZhYJ*B;1x3begYt!{eAHnF`yvtbvv&`B-upWKOJs}4bfXcI z8t5hbDKxj$IPR&NsD>=$wZ*C*qEpqX32{>u1nX%YI_C*4uk1eE`~SvTC|sFuam$k0 z_OrP8)Sm+&71-r>QhB)!Wo3%Xwu=oxwuE^!g$|s8Pusjs(R^s`1G%Gq=$E@gvA%7L zSaP=-Gq#FV)kjww^W*M_1zlE;j?a~k%*bUNhjy6Kk(J3yc8Kzn3SV#~E`BVhzYZVX z%WmUrKw%T73?PvJ%zDA{RBVthm1Kp#OKxEMsiX2i`df@;hYs%ijH7rW?RWnRAxy=m literal 0 HcmV?d00001 diff --git a/docs/.doctrees/honeybee.model.doctree b/docs/.doctrees/honeybee.model.doctree new file mode 100644 index 0000000000000000000000000000000000000000..50e000f014cf6ded6f8865e5beeba930febc7e8e GIT binary patch literal 481588 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%0DhN8&7PZ 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 z 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 literal 0 HcmV?d00001 diff --git a/docs/.doctrees/honeybee.orientation.doctree b/docs/.doctrees/honeybee.orientation.doctree new file mode 100644 index 0000000000000000000000000000000000000000..fd1a054809e8d43a11c5a790cf6d4a221414f540 GIT binary patch literal 27527 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 WoT`{P#z|@S<_Yo$big&y(EkUiNdv;c9 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 lC(UBJ%9Of(w(|IXdtt@mENs_Lo% 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 literal 0 HcmV?d00001 diff --git a/docs/.doctrees/honeybee.shademesh.doctree b/docs/.doctrees/honeybee.shademesh.doctree new file mode 100644 index 0000000000000000000000000000000000000000..dc030419a156129113425a29299e7faf2c3a2bd7 GIT binary patch literal 80200 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 bNABiEtJ>_=2ssugSE)u*o}3+oEYAKvjFJxH literal 0 HcmV?d00001 diff --git a/docs/.doctrees/honeybee.typing.doctree b/docs/.doctrees/honeybee.typing.doctree new file mode 100644 index 0000000000000000000000000000000000000000..2b8915089c042e22aba7a3bf45d80ada2a466747 GIT binary patch literal 76687 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 literal 0 HcmV?d00001 diff --git a/docs/.doctrees/honeybee.units.doctree b/docs/.doctrees/honeybee.units.doctree new file mode 100644 index 0000000000000000000000000000000000000000..37856b187e77e8632cedd073e9e55daced273b05 GIT binary patch literal 12627 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 Q1C9gtErk^?Da^6)e{p{2=l}o! literal 0 HcmV?d00001 diff --git a/docs/.doctrees/honeybee.writer.aperture.doctree b/docs/.doctrees/honeybee.writer.aperture.doctree new file mode 100644 index 0000000000000000000000000000000000000000..63f42e2b9e43011059cfc194eb50d1fc76ff68e3 GIT binary patch literal 3960 zcmc&%O^+Kz8cs4}&v-uUnS?}0VZdm`W+Gyn!yZsJT0ls9i7?U%7Ir1nDR-A$rRnZ! zs;V=dLnQWqG!b>9IB?@H@R#@%d*pe$y4xPJSs)iivNZM9Tkq%de)Lz{-(`bq)t?)f zLdbkMW=WE(gd6X66BU;k&#nK~-~W$)=1*NuvvZ?L9dqxlfg=_&O*GH_7vA-W-OALA z>-Rf`$5yJmeJ(npD|Wu{r=sUNR@#)WUAZ@e%K62N^YOWsmg_MqxVEL{!%QV5cb6svb3ZL-%?X+9^O((PEbperv1;;uLluZb;j;y#`TmGOx# z^PKC+xzcAK1m{Pw(tP6tb4^RyjLujac=h_@8|6$~a~+u{e7P3Z5OMJayby09et*L6 zE&T4`cb_~$P_(T4ICa|vliIsF;C~%9Ms4au>_bjQFXRy2sr9TBZ;R2I4ZpKr;2EU7<7pF%4}5KUGeXAVgDZ_pObC?T>4jwyyIWwx^ZQ& z0fLpr%B}2W+`4{$CB@;eX&C=aHME6iRSzv^s|Tmz(P|WoLN$z7UD%^~cJQY0tynjk zS~F%?(;KOJ_n>hrI4mB7F8kt4wzEV$ptsjuKQ1**ov58L2Ms068nwJ1-F+v9eA z&b7*^+`a4mlcgn^a|^q{)b$n|Q-fKhJq`)OjIt~%aM%xOBFH|&aj!m>I>qVGsyL$A zM7L1ap~ipV-OagDHb)m)yL^1z9n$d5%Pd-=v1A^UKDFB-id9BCfq}@ofx=T>QKEBc zMbu14XsjR9BXjBwG%u94QA)keKfdAi1WVgv#~t&fM64{crD>Q@X9=H`3#jX#Go2$= z;Lx09p!BR}F(;?|rR&SQC~br?Rn+jj>y>ssdUs?b{(tT2WyG~sIua~TQjUq&B~xST z-9VN0s+3M8#k-S@n+*}-N7oNRR|a%G{p9bXccJ|1#l}l_L=G54NgzHc9P;ikW%;6H z3yyFnIN!jE@2#Jk(XNs@>&vOGg{Euy&#`sl59{(^Ay^*r7XPn4DTKR4o0XpG=? zhRsxRJFj%0WGBLADU|gro1p>{EBxbKcLF?RQCnK=0EtXN34ZSGRCdYSV8_L<25c!x z32?lR9lJfE?vANdpd9iAsw@i3OIT7>N(XhE!In@cOJQU?XkxVE~3E@Eqt-vCQYdK+_d&QlBv8 zY=ci`1m0A!P>Qr#pLt*=oACtodjS&!=N3wC$KX1Pc*bNJVIR@FTCgwOasBxKu%`3S z)1JG7AfXa(@Oq2qPibX$yP>zBm;p^J!4kz{Bg^!HqgP?kJ%*8hn#Csy!ky59{tVsk z3NXU;L&WgE_(ohB*CT?xC=lppUVJk(;!WDLFEOSbVSnfb16KXJ z{sLM}yGN{y*HUGyt~QOr>pURIIOT5L@ov6^Xq@YxU^n75SJN+R~W1y(z1{x#srJ3u9GMr}J(< zR%r@|zy}P&oeyjJw@BmH{vT)z_+UVb!55wZl7qswC0-%#x8w?Z`!bKyG9mCU2zPr4 Ob?v&r(I!#O#y8k+BMxZQ?=^u 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 literal 0 HcmV?d00001 diff --git a/docs/.doctrees/honeybee.writer.face.doctree b/docs/.doctrees/honeybee.writer.face.doctree new file mode 100644 index 0000000000000000000000000000000000000000..a44f6d55e35cd77112f338882c7ae6fa90f948be GIT binary patch literal 3884 zcmcgvTW=f36}Byr5_O?0J2nc~N@x_WWz;0|kcYrA(gp$YB9sM+q)7_|>*4M!XQ17k z?aZu2Js5Bv49Lj5WeOxeBY!EsB9Hyf4tGg0m&Sew0Ro&eXU_FI7rxm1@4bU7^~W8U zQpjRHVo6e{gd6X+6BSoEFRcH@Km5u+_s6cM*_lz5j=6VNz!3|XC7KuhOYi!`Ze?ah zi}zcG$5yJMeJ(npE4IG$$D-#tR@#iOT)8_!75se4`RGhb%k?N_F(2eAslZ3i@M`l@ zJ|}a2o%yA&t%bUqu3IwLXT3Ody{L6aY`E^ikBQsNWWoKUnliV;tkrT_S@=)>Zpg%t zZ(DK3i~$k9I|a+bukEBNmxn2fPc=`8r*d1C&FIRD193;}iMwJ$9J!ORP&ps#swlV~ zpDBF`LU4K*E6vwVFxRxC)u@cLfk$tjT&t$yitETC;q#SHhA4}7;DNY@xcw2|`}jV< z_aS+MfM{9!aO^fqCbf5WL!dtxGzP8eL%hTF@MmvDcVa!O#Gl1*#o5{GIon7chwP6j z`=j#wF$DqE7PEm$f8IFpHgX4W^pI*c)2tLLv2c5z5R5(#kP0}uy+&N((!W}y?O)1o$_Ad*{ji!Y9~_G(%a%S2$RDP_>~PWldDFy}Y^x2b856AO zaa5f<(6kX86^}x<{N>EG^FTbJw^v<1t~5=KsGSpg4JFJAw{5t!C_#+M!*=$iS`}2z z-gW=UvIv#ZK$ls$Jh|%jY48?R9?j7_at}(MT4))?DyMmFAo5P2@Ql}#=uBD>HB$~6 z7Y`O=Z{qeeFO{}YM!n3RTyr~uW$m%!4*6UnR+ibyG)$--+wSsz~7@!XcBWL~oLFFS@SJDyyO;$z78`)P7RsWz?b$ zQLPCQfYSxbNZ>(DL1+s@xnGh>!>dF^^PKQ>ozF{Uc(nSmhDdCqXVS=k&x0tDhD|ea zWMSo2Qw`#g+k-O(_-FNw2goegqEu$}ZsGbRFPHt6Y}q5qltDEC+xp;nlh0QZ4>sdBM1teDZlWlhdJmpbaTJ6AyOi2lTkr&@b6!|BkA$3w3}1kEGgE~7J(Dw3*?%e&wSmB!^*J1) zOvP*w+M`%t*@=<(P;5wLtqQMCs}eTSHXa6EXacW*9u>fJ0X2)i7YKJkOZIbgzf07xh=UAi zX?y5WNnwWveT#_UxAPp~g^g8|F_z4-UCoN`ZC zGnJaLgI(NUV)+Z2AwOc{{~ed$)h)Dg`>Xh^{ojuzs(=EBm;?%SnT9U}dX*CR5PrZl zpQ@}aiJJATHDb%%yCkvKXssXJxFjFbLR%V7x7KAXZmzf;^uSnE)Zx6_ja8Nb8t?%_ zaO>j*{Trn3rT+&S0{#G?wcy{G0fK|VwiR9?@3!O`bi1;MvnnCb&j@cj33cm5W1|hC HnvVVlFu~jo literal 0 HcmV?d00001 diff --git a/docs/.doctrees/honeybee.writer.model.doctree b/docs/.doctrees/honeybee.writer.model.doctree new file mode 100644 index 0000000000000000000000000000000000000000..dc10330591ba18f8010b7c06df742d2d0961e7dd GIT binary patch literal 3903 zcmcgvNsk*v6izZ@&v+J3CLs}0GGK%t6A{}SIG_-*2#HI;NQhlRopN{CRhsUurm8yQ zIYfd3(nQpa;sF1Gzr?TL$oIP3?F9lP2Q0PK_3G8z>U&FnxB2rM2N$ZJJ1~Wi`E0lf?=FBN7BWpV&;2*vb&1`|)C}h5w+xT1 zRC#k;v_xBMedCWs$F;1qDPP)hH-*ai*_iXesg{=OK?XC@9{x)((m5R4{FKkgo`2!~ z!B_S|;Z@fz7%a429J)@_xFj}Qd+y1|ZKg8kepHT`+hNvfIW8?CKpt<%#E^GeamtJV z5$~;>W#Mf*DT~Eo%;FQxC&W{_Ez72~<;8)xA@;;gu_2D!heM$dcKApd{=wX1su!6v#IJ--M zfWi5+rzTIZPrQH&1VlQxZ#LDe5KHlJ`yW+k`XWFp!0Gxrbpf0A;lq33&PJ7B_QY6{ z%kPLI@iuPbV(mICc{k*YXt`fU%JQC7y@WsHsVcZOcXvKBAPH&a0H`?!faENT#hw9y_cCsUN_r0}kprs+#C^L8 z#Id;U#IxD>`**)QrIo%3vYR}c&Zmuw$EAF{e3t;pK~;VtWGhE;Ksl>R9ImTX1+s<+ z3czGxGxF+&__yj&OHGX=YTCwLO$qJ8Z5wVaG7-J=uxW-9t#V3h@7kZU zv_#2mpms2Fohe5nU{-05MZ(Z_EXxWkc7vJ-vQMzwnJ-J7VzqBo98tTWU8rkOIY0C6 z%0wxfquMNO-oNPfsT1dA7R^vYG7n0Zs%a6$Dx(H(Ao50_@RV1S=u}z})lCl?=LhCp zaOCzhFO;@XN;S>jzvOlVOPgiO9rBq(tSqyoshN;l2_KhJsOz3Gog-G@(41wUbgX7E zC#U?m>&m<+ZG_ZRRNK7kly=g8vu`BcZ?0}eTx+Ex!SW>K=wod%HMZUzsM4-VX;o6t z>ehDFM2O#9HwaxA(E9At5BhIH`Rc~nNq3nXFo=>sd{Q{%-G0jQY00J>;ZCr=gn7wb z)g1jki4tA_98g2ec;wo#$|vv<;gCsGpgzf&7j4&NrB%^_Jkc(i=7f=FzmhtkM^&x0tDhK*BlWNzhF zoekoS+k-O(_-ED72guCXqKQnaNyBvuUMy-Z*|JBJF@tIXwtHS!TbR4UA;<=OA1x~% zC_No|ca1nn5^+YBXNayvG`B(Tzw-JU2uD{>;x+L^S%`nN7LP<@1h*56nUdQ{r2{ED z6gEqttYg_28IV}v?{B*!;3 zr2^@YPmx`z%%t@nUB2Zmo3q@qStR6Cq<8?{%~TQY_e{o+W#5)aY6F2+t94jLsfyV= zv`4YP*c0R8L$cv2D^)msQWmh0#`DnhLJ@cj^r%?o6JVgO3RkF3m~ytJ_lD zb}*S6v@Cy4J>(C30Q|25@$x)cy8UGYR}t8cCGvnmh^Pb#)tQ`zaxAC!u;hFKskKl;gpl DX-VbU literal 0 HcmV?d00001 diff --git a/docs/.doctrees/honeybee.writer.room.doctree b/docs/.doctrees/honeybee.writer.room.doctree new file mode 100644 index 0000000000000000000000000000000000000000..f5253dc4b9a17966de33a5147c57d14fe20ed315 GIT binary patch literal 3884 zcmcgvTW=dh6mFZ?iF0w9mR3k@z!fS@MQ!uI11c34A@LGnB*a}p+wtz$Gs^DHGBeva z50%P8rBuutg9JZ=zr?TLk?-ty*N(Zi4_LC~IdkS*zjN`E^`CC-U8p{8&lE!DvjIzz zTqWFix0$H8%y@47kN)oW{;@xF9nDURDs{}gy8w<@$TZPB_uqQgC3Y)QGnl{MFg&(W z<;`=^5^b^Ztv?hU*Rs;4eCf*F5Gv=VW6lRBT3W6LTB)p;siXuSJ;ST@&-jeY`Df;* zzOokTuDW)?V4wA3-*uwKA+hG#b3aCIJ(W54qjJpL7PD5%acSW{`MV|)L%waqDKiE{ z{BGqe3%@p#vRE9(EI!tJLOiA0uxv_KUhIh*Vn^H*YvRBi4TZ}1P?vem_3%XLV-SMV z{a9(fa)P<0AuUH`pbb2F<>*p578hJg<_VuIg)&50yb2G*EyV3Ld~f4>2j9Eo4FaNN z<-?&{FPPNc-3)<#r&k-atPk-H*Zse|744DrtQ2pE{*trP=X17}JPg?%QuYVM>3s?U ztj(uAHTi4f#4E@hz|ldf*;KPaEXBg@d`d9-GC(Te==utAftL?q{|6yiqe?9M+bEK| z?}-EPF7j}(b{lrQA4)~E+|MIrdC#g|!XNQe6sr> zD6YHdi&^;FlV6_CM&Cr(@fTD1oI&wO$S2Er1U&YtjuW9oIXVJ5Sl!i-s#X=n8Xc(m z$--n*(+%;>vao*!#aE;oK)CLD|CW}8lK;T_Czrl%khXg+zqK3NOG#g7s@%z5#GQ+G z7g8J!s|NA^R4Z$ER`tVjym)XZ9xPgVKOn!af!Y4N|MR+uE!dVDR6QnG-Q%b_x1eb) zI4bUiZu$3_YvzHtM{h5>Zd_`b98ohTc4|tP7jDyVYf*w2mHW-?n`o6&IeXXsf~6&z zYy-2sk?Tx3IzO{YdmIvmIb&H?;IJLkM38-qJ+D4tKx{}3*ACpiyHW;cULA# z*&JPF>GJ5J+oi#qmsvDJ^T<3XU23646swHpxq-+Vfx=T>QKA!RMO05YXq-QokG+xG z(Y#RFMk)0&e{{)h36?g;mfPnuiC9@?OH(tUt`a^jr%=~DVLC^wz@a(IK)W*D39!|90O<{JweqGU8e*9SN2vDaYh$lc}-wZcml=yp&cY#k+%* zn-vk_SJw?f7Y4LG|Lmjw+faV~V&$c~Ob!@CNgzHc9P(~AW%;yZQ;u*aIA6kg$1|SXhCw9BoMWmlvxoqs6$jMf&}1n z&QcP%S5Xk!+)(Zpq{8qrQPC_TJYD9qLKz+{zpNk<+vt%rGT?JBN~B@qlpL8`xlvbx zxaW4@i~;^xwc`OYbGB$A(`vVH-GUd3eoMCO5M|7unt<(I7SwepYZ1*&(EGRFd<)^|>PfsJo+u0Puh-&HXpG=?jIB~~JE?S_WQW3L zDU@|A8>0deEBw)>I{==ts41;xU__>%1V3}vE4yTFxF+8LTZ&Qw9B*SkZjPwCeQFgb zhkT0aN@XUk|M>D9ciEigmdzp|ry|7{;9XA@;eN+t3|01BiJ~?Tc(po*W0b0x%|m+- z3oJV^5+8~UsjO7t^>JCiM%u>1zza>_8PKC*nNNU$x+`3vK4Hr73ZKjfys2WL6lpy^ z_P|Uw<_YTe6ebAHEtFh~!F3$*jL9^@&Y^j=B%itc`RWg_rjyXqp1GYMp%QQKdX49g zXzg~Jp|_xz0ZlBk62)R8%k-3^S7Bk@hmnAq#or5rJE0}}F}mM5YFNZUhO|j@Xj4gH zhX;Lwh~c;RL7W-aA%Zal}e z++bq)Gnyg4W8?oHm*C|sv~;`6_^tfkjU}pp0*IId3U!&9F9dp-68I2)z%?7Iv?+;- z^`#YJ!`(S2u~TcU9$h&nAJalx8c)|&WzBCcxGnU+Se4Y_yxWddngSZ|0Yh-(!#Vv& zr0=Q!6b%7?0MJ_S@5}(fL1EJh&ylwqas|3=na63F5a_3bx2=S_^}Mms22qX&e*ip1 B-*^B3 literal 0 HcmV?d00001 diff --git a/docs/.doctrees/honeybee.writer.shade.doctree b/docs/.doctrees/honeybee.writer.shade.doctree new file mode 100644 index 0000000000000000000000000000000000000000..3f60f13e509edd9968b33e480f3e8503102293ba GIT binary patch literal 3903 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 + + + + + + honeybee.altnumber — honeybee documentation + + + + + + + + + + + + + + + + + + + + + + +