diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ad6eaef7..2a7c6984 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -32,22 +32,23 @@ jobs: docs: runs-on: ubuntu-latest + defaults: + run: + shell: bash -l {0} needs: - deploy steps: - uses: actions/checkout@v2 - - - uses: actions/setup-python@v2.2.2 + - uses: conda-incubator/setup-miniconda@v2 with: - python-version: 3.8 - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -r requirements.txt - pip install -r requirements-optional.txt + miniconda-version: "latest" + python-version: 3.9 + activate-environment: foo + - run: | + conda install -c conda-forge graph-tool pip install -e . + pip install -r requirements-optional.txt pip install -r requirements-docs.txt - name: Generate changelog @@ -58,8 +59,8 @@ jobs: - name: Commit files run: | - git config --local user.email "feedback@materialsproject.org" - git config --local user.name "materialsproject" + git config --local user.email "mcdermott@lbl.gov" + git config --local user.name "GENESIS-EFRC" mv CHANGELOG.md docs/ git add docs/CHANGELOG.md && git commit -m 'Updated CHANGELOG.md' diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index d3f60c14..8638799f 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -35,7 +35,7 @@ jobs: - name: Lint with mypy run: | pip install mypy - # mypy src/rxn_network + mypy src/rxn_network - name: Lint with flake8 run: | @@ -78,19 +78,23 @@ jobs: docs: runs-on: ubuntu-latest - + defaults: + run: + shell: bash -l {0} steps: - uses: actions/checkout@v2 - - - uses: actions/setup-python@v2.2.2 + - uses: conda-incubator/setup-miniconda@v2 with: - python-version: 3.8 + miniconda-version: "latest" + python-version: 3.9 + activate-environment: foo - name: Install dependencies run: | - python -m pip install --upgrade pip + conda install -c conda-forge graph-tool pip install -e . pip install -r requirements-optional.txt pip install -r requirements-docs.txt - - name: Build + + - name: Build docs run: mkdocs build \ No newline at end of file diff --git a/README.md b/README.md index 3daf54cc..548f603e 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,8 @@ # ![Reaction Network](docs/images/logo.png) +[![Pytest Status](https://github.com/GENESIS-EFRC/reaction-network/workflows/testing/badge.svg)](https://github.com/GENESIS-EFRC/reaction-network/actions?query=workflow%3Atesting) +[![Code Coverage](https://codecov.io/gh/GENESIS-EFRC/reaction-network/branch/main/graph/badge.svg)](https://codecov.io/gh/GENESIS-EFRC/reaction-network) + Reaction network (rxn-network) is a Python package for predicting chemical reaction pathways in solid-state materials synthesis using graph theory. diff --git a/cinder/404.html b/cinder/404.html new file mode 100644 index 00000000..0d58f066 --- /dev/null +++ b/cinder/404.html @@ -0,0 +1,13 @@ +{% extends "base.html" %} + +{% block content %} + +
+
+

404

+

Page not found

+

Home

+
+
+ +{% endblock %} diff --git a/src/__init__.py b/cinder/__init__.py similarity index 100% rename from src/__init__.py rename to cinder/__init__.py diff --git a/cinder/base.html b/cinder/base.html new file mode 100644 index 00000000..f818eacf --- /dev/null +++ b/cinder/base.html @@ -0,0 +1,139 @@ + + + + + + + + {% if config.site_description %}{% endif %} + {% if config.site_author %}{% endif %} + {% if page.canonical_url %}{% endif %} + + + {% block htmltitle %} + {% if page.title %}{{ page.title }} - {% endif %}{{ config.site_name }} + {% endblock %} + + + + + + + + + + + {% if config.theme.highlightjs is defined and config.theme.highlightjs is sameas false %} + + {% else %} + {% if config.theme.colorscheme %} + + {% else %} + + {% endif %} + {% endif %} + + {%- for path in config['extra_css'] %} + + {%- endfor %} + + + + + {% if config.google_analytics %} + + {% endif %} + + {% block extrahead %} {% endblock %} + + + + + {% include "nav.html" %} + +
+ {% block content %} + {% if page.meta.disable_toc %} +
{% include "content.html" %}
+ {% else %} +
{% include "toc.html" %}
+
{% include "content.html" %}
+ {% endif %} + {% endblock %} +
+ + {% if not config.theme.disable_footer %} + + {% endif %} + + {%- block scripts %} + + + + {% if config.theme.highlightjs is defined and config.theme.highlightjs is sameas false %} + + {% else %} + + {% if config.theme.hljs_languages %} + {%- for lang in config.theme.hljs_languages %} + + {%- endfor %} + {% endif %} + + {% endif %} + + + {% if config.shortcuts %} + + {% endif %} + + {%- for path in config['extra_javascript'] %} + + {%- endfor %} + {%- endblock %} + + {% if 'search' in config['plugins'] %}{%- include "search-modal.html" %}{% endif %} + {%- include "keyboard-modal.html" %} + + + +{% if page and page.is_homepage %} + +{% endif %} diff --git a/cinder/content.html b/cinder/content.html new file mode 100644 index 00000000..8b51ac66 --- /dev/null +++ b/cinder/content.html @@ -0,0 +1,9 @@ +{% if page.meta.source %} + +{% endif %} + +{{ page.content }} diff --git a/cinder/css/base.css b/cinder/css/base.css new file mode 100644 index 00000000..2d684824 --- /dev/null +++ b/cinder/css/base.css @@ -0,0 +1,289 @@ +html { + scroll-padding-top: 70px; +} + +body { + padding-top: 70px; +} + +p > img { + max-width: 100%; + height: auto; +} + +ul.nav li.first-level { + font-weight: bold; +} + +ul.nav li.third-level { + padding-left: 12px; +} + +div.col-md-3 { + padding-left: 0; +} + +div.col-md-9 { + padding-bottom: 100px; +} + +div.source-links { + float: right; +} + +/* + * Side navigation + * + * Scrollspy and affixed enhanced navigation to highlight sections and secondary + * sections of docs content. + */ + +/* By default it's not affixed in mobile views, so undo that */ +.bs-sidebar.affix { + position: static; +} + +.bs-sidebar.well { + padding: 0; +} + +/* First level of nav */ +.bs-sidenav { + margin-top: 30px; + margin-bottom: 30px; + padding-top: 10px; + padding-bottom: 10px; + border-radius: 5px; +} + +/* All levels of nav */ +.bs-sidebar .nav > li > a { + display: block; + padding: 5px 20px; + z-index: 1; +} +.bs-sidebar .nav > li > a:hover, +.bs-sidebar .nav > li > a:focus { + text-decoration: none; + border-right: 1px solid; +} +.bs-sidebar .nav > .active > a, +.bs-sidebar .nav > .active:hover > a, +.bs-sidebar .nav > .active:focus > a { + font-weight: bold; + background-color: transparent; + border-right: 1px solid; +} + +/* Nav: second level (shown on .active) */ +.bs-sidebar .nav .nav { + display: none; /* Hide by default, but at >768px, show it */ + margin-bottom: 8px; +} +.bs-sidebar .nav .nav > li > a { + padding-top: 3px; + padding-bottom: 3px; + padding-left: 30px; + font-size: 90%; +} + +/* Show and affix the side nav when space allows it */ +@media (min-width: 992px) { + .bs-sidebar .nav > .active > ul { + display: block; + } + /* Widen the fixed sidebar */ + .bs-sidebar.affix, + .bs-sidebar.affix-bottom { + width: 213px; + } + .bs-sidebar.affix { + position: fixed; /* Undo the static from mobile first approach */ + top: 80px; + max-height: calc(100% - 180px); + overflow-y: auto; + } + .bs-sidebar.affix-bottom { + position: absolute; /* Undo the static from mobile first approach */ + } + .bs-sidebar.affix-bottom .bs-sidenav, + .bs-sidebar.affix .bs-sidenav { + margin-top: 0; + margin-bottom: 0; + } +} +@media (min-width: 1200px) { + /* Widen the fixed sidebar again */ + .bs-sidebar.affix-bottom, + .bs-sidebar.affix { + width: 263px; + } +} + + +/* Added to support >2 level nav in drop down */ + +.dropdown-submenu { + position: relative; +} + +.dropdown-submenu>.dropdown-menu { + top: 0; + left: 100%; + margin-top: 0px; + margin-left: 0px; +} + +.dropdown-submenu:hover>.dropdown-menu { + display: block; +} + +.dropdown-submenu>a:after { + display: block; + content: " "; + float: right; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; + border-width: 5px 0 5px 5px; + border-left-color: #ccc; + margin-top: 5px; + margin-right: -10px; +} + +.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: 00px; +} +/* Start Bootstrap Callouts CSS Source by Chris Pratt (https://codepen.io/chrisdpratt/pen/IAymB) MIT License*/ +.bs-callout { + padding: 20px; + margin: 20px 0; + border: 1px solid #eee; + border-left-width: 5px; + border-radius: 3px; + background-color: #FCFDFF; +} +.bs-callout h4 { + font-style: normal; + font-weight: 400; + margin-top: 0; + margin-bottom: 5px; +} +.bs-callout p:last-child { + margin-bottom: 0; +} +.bs-callout code { + border-radius: 3px; +} +.bs-callout+.bs-callout { + margin-top: -5px; +} +.bs-callout-default { + border-left-color: #FA023C; /*modified from upstream default by Christopher Simpkins*/ +} +.bs-callout-default h4 { + color: #FA023C; /*modified from upstream default by Christopher Simpkins*/ +} +.bs-callout-primary { + border-left-color: #428bca; +} +.bs-callout-primary h4 { + color: #428bca; +} +.bs-callout-success { + border-left-color: #5cb85c; +} +.bs-callout-success h4 { + color: #5cb85c; +} +.bs-callout-danger { + border-left-color: #d9534f; +} +.bs-callout-danger h4 { + color: #d9534f; +} +.bs-callout-warning { + border-left-color: #f0ad4e; +} +.bs-callout-warning h4 { + color: #f0ad4e; +} +.bs-callout-info { + border-left-color: #5bc0de; +} +.bs-callout-info h4 { + color: #5bc0de; +} +/* End Bootstrap Callouts CSS Source by Chris Pratt */ + +/* Headerlinks */ +.headerlink { + display: none; + padding-left: .5em; +} + +h1:hover .headerlink, h2:hover .headerlink, h3:hover .headerlink, h4:hover .headerlink, h5:hover .headerlink, h6:hover .headerlink { + display: inline-block; +} + +/* Admonitions */ +.admonition { + padding: 20px; + margin: 20px 0; + border: 1px solid #eee; + border-left-width: 5px; + border-radius: 3px; + background-color: #FCFDFF; +} + +.admonition p:last-child { + margin-bottom: 0; +} +.admonition code { + border-radius: 3px; +} +.admonition+.admonition { + margin-top: -5px; +} + +.admonition.note { /* csslint allow: adjoining-classes */ + border-left-color: #428bca; +} + +.admonition.warning { /* csslint allow: adjoining-classes */ + border-left-color: #f0ad4e; +} + +.admonition.danger { /* csslint allow: adjoining-classes */ + border-left-color: #d9534f; +} + +.admonition-title { + font-size: 19px; + font-style: normal; + font-weight: 400; + margin-top: 0; + margin-bottom: 5px; +} + +.admonition.note > .admonition-title { + color: #428bca; +} + +.admonition.warning > .admonition-title { + color: #f0ad4e; +} + +.admonition.danger > .admonition-title { + color: #d9534f; +} diff --git a/cinder/css/base.min.css b/cinder/css/base.min.css new file mode 100644 index 00000000..f7e580f2 --- /dev/null +++ b/cinder/css/base.min.css @@ -0,0 +1 @@ +html{scroll-padding-top:70px}body{padding-top:70px}p>img{max-width:100%;height:auto}ul.nav li.first-level{font-weight:bold}ul.nav li.third-level{padding-left:12px}div.col-md-3{padding-left:0}div.col-md-9{padding-bottom:100px}div.source-links{float:right}.bs-sidebar.affix{position:static}.bs-sidebar.well{padding:0}.bs-sidenav{margin-top:30px;margin-bottom:30px;padding-top:10px;padding-bottom:10px;border-radius:5px}.bs-sidebar .nav>li>a{display:block;padding:5px 20px;z-index:1}.bs-sidebar .nav>li>a:hover,.bs-sidebar .nav>li>a:focus{text-decoration:none;border-right:1px solid}.bs-sidebar .nav>.active>a,.bs-sidebar .nav>.active:hover>a,.bs-sidebar .nav>.active:focus>a{font-weight:bold;background-color:transparent;border-right:1px solid}.bs-sidebar .nav .nav{display:none;margin-bottom:8px}.bs-sidebar .nav .nav>li>a{padding-top:3px;padding-bottom:3px;padding-left:30px;font-size:90%}@media(min-width:992px){.bs-sidebar .nav>.active>ul{display:block}.bs-sidebar.affix,.bs-sidebar.affix-bottom{width:213px}.bs-sidebar.affix{position:fixed;top:80px;max-height:calc(100% - 180px);overflow-y:auto}.bs-sidebar.affix-bottom{position:absolute}.bs-sidebar.affix-bottom .bs-sidenav,.bs-sidebar.affix .bs-sidenav{margin-top:0;margin-bottom:0}}@media(min-width:1200px){.bs-sidebar.affix-bottom,.bs-sidebar.affix{width:263px}}.dropdown-submenu{position:relative}.dropdown-submenu>.dropdown-menu{top:0;left:100%;margin-top:0;margin-left:0}.dropdown-submenu:hover>.dropdown-menu{display:block}.dropdown-submenu>a:after{display:block;content:" ";float:right;width:0;height:0;border-color:transparent;border-style:solid;border-width:5px 0 5px 5px;border-left-color:#ccc;margin-top:5px;margin-right:-10px}.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:00px}.bs-callout{padding:20px;margin:20px 0;border:1px solid #eee;border-left-width:5px;border-radius:3px;background-color:#fcfdff}.bs-callout h4{font-style:normal;font-weight:400;margin-top:0;margin-bottom:5px}.bs-callout p:last-child{margin-bottom:0}.bs-callout code{border-radius:3px}.bs-callout+.bs-callout{margin-top:-5px}.bs-callout-default{border-left-color:#fa023c}.bs-callout-default h4{color:#fa023c}.bs-callout-primary{border-left-color:#428bca}.bs-callout-primary h4{color:#428bca}.bs-callout-success{border-left-color:#5cb85c}.bs-callout-success h4{color:#5cb85c}.bs-callout-danger{border-left-color:#d9534f}.bs-callout-danger h4{color:#d9534f}.bs-callout-warning{border-left-color:#f0ad4e}.bs-callout-warning h4{color:#f0ad4e}.bs-callout-info{border-left-color:#5bc0de}.bs-callout-info h4{color:#5bc0de}.headerlink{display:none;padding-left:.5em}h1:hover .headerlink,h2:hover .headerlink,h3:hover .headerlink,h4:hover .headerlink,h5:hover .headerlink,h6:hover .headerlink{display:inline-block}.admonition{padding:20px;margin:20px 0;border:1px solid #eee;border-left-width:5px;border-radius:3px;background-color:#fcfdff}.admonition p:last-child{margin-bottom:0}.admonition code{border-radius:3px}.admonition+.admonition{margin-top:-5px}.admonition.note{border-left-color:#428bca}.admonition.warning{border-left-color:#f0ad4e}.admonition.danger{border-left-color:#d9534f}.admonition-title{font-size:19px;font-style:normal;font-weight:400;margin-top:0;margin-bottom:5px}.admonition.note>.admonition-title{color:#428bca}.admonition.warning>.admonition-title{color:#f0ad4e}.admonition.danger>.admonition-title{color:#d9534f} diff --git a/cinder/css/bootstrap-custom.css b/cinder/css/bootstrap-custom.css new file mode 100644 index 00000000..631252d2 --- /dev/null +++ b/cinder/css/bootstrap-custom.css @@ -0,0 +1,5309 @@ +/*! normalize.css v2.1.3 | MIT License | git.io/normalize */ +article, aside, details, figcaption, figure, footer, header, hgroup, main, nav, section, summary { + display: block; +} +audio, canvas, video { + display: inline-block; +} +audio:not([controls]) { + display: none; + height: 0; +} +[hidden], template { + display: none; +} +html { + font-family: sans-serif; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%} +body { + margin: 0; +} +a { + background: transparent; +} +a:focus { + outline: thin dotted; +} +a:active, a:hover { + outline: 0; +} +h1 { + margin: .67em 0; + font-size: 2em; +} +abbr[title] { + border-bottom: 1px dotted; +} +b, strong { + font-weight: bold; +} +dfn { + font-style: italic; +} +hr { + height: 0; + -moz-box-sizing: content-box; + box-sizing: content-box; +} +mark { + color: #000; + background: #ff0; +} +code, kbd, pre, samp { + font-family: Hack, monospace, serif; + font-size: 1em; +} +pre { + white-space: pre-wrap; +} +q { + quotes: "\201C" "\201D" "\2018" "\2019"} +small { + font-size: 80%} +sub, sup { + position: relative; + font-size: 75%; + line-height: 0; + vertical-align: baseline; +} +sup { + top: -0.5em; +} +sub { + bottom: -0.25em; +} +img { + border: 0; +} +svg:not(:root) { + overflow: hidden; +} +figure { + margin: 0; +} +fieldset { + padding: .35em .625em .75em; + margin: 0 2px; + border: 1px solid #c0c0c0; +} +legend { + padding: 0; + border: 0; +} +button, input, select, textarea { + margin: 0; + font-family: inherit; + font-size: 100%} +button, input { + line-height: normal; +} +button, select { + text-transform: none; +} +button, html input[type="button"], input[type="reset"], input[type="submit"] { + cursor: pointer; + -webkit-appearance: button; +} +button[disabled], html input[disabled] { + cursor: default; +} +input[type="checkbox"], input[type="radio"] { + padding: 0; + box-sizing: border-box; +} +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-cancel-button, input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} +button::-moz-focus-inner, input::-moz-focus-inner { + padding: 0; + border: 0; +} +textarea { + overflow: auto; + vertical-align: top; +} +table { + border-collapse: collapse; + border-spacing: 0; +} +@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) ")"} +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: 2cm .5cm; +} +p, h2, h3 { + orphans: 3; + widows: 3; +} +h2, h3 { + page-break-after: avoid; +} +select { + background: #fff!important; +} +.navbar { + display: none; +} +.table td, .table th { + background-color: #fff!important; +} +.btn>.caret, .dropup>.btn>.caret { + border-top-color: #000!important; +} +.label { + border: 1px solid #000; +} +.table { + border-collapse: collapse!important; +} +.table-bordered th, .table-bordered td { + border: 1px solid #ddd!important; +} +}*, *:before, *:after { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +html { + font-size: 62.5%; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); +} +body { + font-family: Merriweather, Georgia, serif; + font-size: 14px; + line-height: 1.428571429; + color: #222; + background-color: #fff; +} +input, button, select, textarea { + font-family: inherit; + font-size: inherit; + line-height: inherit; +} +a { + color: #008cba; + text-decoration: none; +} +a:hover, a:focus { + color: #00526e; + text-decoration: underline; +} +a:focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +img { + vertical-align: middle; +} +.img-responsive { + display: block; + height: auto; + max-width: 100%} +.img-rounded { + border-radius: 0; +} +.img-thumbnail { + display: inline-block; + height: auto; + max-width: 100%; + padding: 4px; + line-height: 1.428571429; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 0; + -webkit-transition: all .2s ease-in-out; + transition: all .2s ease-in-out; +} +.img-circle { + border-radius: 50%} +hr { + margin-top: 21px; + margin-bottom: 21px; + border: 0; + border-top: 1px solid #ddd; +} +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; +} +h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 { + font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: 300; + line-height: 1.1; + color: inherit; +} +h1 small, h2 small, h3 small, h4 small, h5 small, h6 small, .h1 small, .h2 small, .h3 small, .h4 small, .h5 small, .h6 small, h1 .small, h2 .small, h3 .small, h4 .small, h5 .small, h6 .small, .h1 .small, .h2 .small, .h3 .small, .h4 .small, .h5 .small, .h6 .small { + font-weight: normal; + line-height: 1; + color: #999; +} +h1, h2, h3 { + margin-top: 21px; + margin-bottom: 10.5px; +} +h1 small, h2 small, h3 small, h1 .small, h2 .small, h3 .small { + font-size: 65%} +h4, h5, h6 { + margin-top: 10.5px; + margin-bottom: 10.5px; +} +h4 small, h5 small, h6 small, h4 .small, h5 .small, h6 .small { + font-size: 75%} +h1, .h1 { + font-size: 39px; +} +h2, .h2 { + font-size: 32px; +} +h3, .h3 { + font-size: 26px; +} +h4, .h4 { + font-size: 19px; +} +h5, .h5 { + font-size: 15px; +} +h6, .h6 { + font-size: 13px; +} +p { + margin: 0 0 10.5px; +} +.lead { + margin-bottom: 21px; + font-size: 17px; + font-weight: 200; + line-height: 1.4; +} +@media(min-width:768px) { + .lead { + font-size: 22.5px; +} +}small, .small { + font-size: 85%} +cite { + font-style: normal; +} +.text-muted { + color: #999; +} +.text-primary { + color: #008cba; +} +.text-primary:hover { + color: #006687; +} +.text-warning { + color: #e99002; +} +.text-warning:hover { + color: #b67102; +} +.text-danger { + color: #f04124; +} +.text-danger:hover { + color: #d32a0e; +} +.text-success { + color: #43ac6a; +} +.text-success:hover { + color: #358753; +} +.text-info { + color: #5bc0de; +} +.text-info:hover { + color: #31b0d5; +} +.text-left { + text-align: left; +} +.text-right { + text-align: right; +} +.text-center { + text-align: center; +} +.page-header { + padding-bottom: 9.5px; + margin: 42px 0 21px; + border-bottom: 1px solid #ddd; +} +ul, ol { + margin-top: 0; + margin-bottom: 10.5px; +} +ul ul, ol ul, ul ol, ol ol { + margin-bottom: 0; +} +.list-unstyled { + padding-left: 0; + list-style: none; +} +.list-inline { + padding-left: 0; + list-style: none; +} +.list-inline>li { + display: inline-block; + padding-right: 5px; + padding-left: 5px; +} +.list-inline>li:first-child { + padding-left: 0; +} +dl { + margin-top: 0; + margin-bottom: 21px; +} +dt, dd { + line-height: 1.428571429; +} +dt { + font-weight: bold; +} +dd { + margin-left: 0; +} +@media(min-width:768px) { + .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; +} +.dl-horizontal dd:before, .dl-horizontal dd:after { + display: table; + content: " "} +.dl-horizontal dd:after { + clear: both; +} +.dl-horizontal dd:before, .dl-horizontal dd:after { + display: table; + content: " "} +.dl-horizontal dd:after { + clear: both; +} +.dl-horizontal dd:before, .dl-horizontal dd:after { + display: table; + content: " "} +.dl-horizontal dd:after { + clear: both; +} +.dl-horizontal dd:before, .dl-horizontal dd:after { + display: table; + content: " "} +.dl-horizontal dd:after { + clear: both; +} +.dl-horizontal dd:before, .dl-horizontal dd:after { + display: table; + content: " "} +.dl-horizontal dd:after { + clear: both; +} +}abbr[title], abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #999; +} +.initialism { + font-size: 90%; + text-transform: uppercase; +} +blockquote { + padding: 10.5px 21px; + margin: 0 0 21px; + border-left: 5px solid #ddd; +} +blockquote p { + font-size: 18.75px; + font-weight: 300; + line-height: 1.25; +} +blockquote p:last-child { + margin-bottom: 0; +} +blockquote small, blockquote .small { + display: block; + line-height: 1.428571429; + color: #6f6f6f; +} +blockquote small:before, blockquote .small:before { + content: '\2014 \00A0'} +blockquote.pull-right { + padding-right: 15px; + padding-left: 0; + border-right: 5px solid #ddd; + border-left: 0; +} +blockquote.pull-right p, blockquote.pull-right small, blockquote.pull-right .small { + text-align: right; +} +blockquote.pull-right small:before, blockquote.pull-right .small:before { + content: ''} +blockquote.pull-right small:after, blockquote.pull-right .small:after { + content: '\00A0 \2014'} +blockquote:before, blockquote:after { + content: ""} +address { + margin-bottom: 21px; + font-style: normal; + line-height: 1.428571429; +} +code, kbd, pre, samp { + font-family: Hack, Menlo, Monaco, Consolas, "Courier New", monospace; +} +code { + padding: 2px 4px; + font-size: 90%; + color: #c7254e; + white-space: nowrap; + background-color: #f9f2f4; + border-radius: 0; +} +pre { + display: block; + padding: 10px; + margin: 0 0 10.5px; + font-size: 14px; + line-height: 1.428571429; + color: #333; + word-break: break-all; + word-wrap: break-word; + background-color: #f5f5f5; + border: 1px solid #ccc; + border-radius: 0; +} +pre code { + padding: 0; + font-size: inherit; + color: inherit; + white-space: pre-wrap; + background-color: transparent; + border-radius: 0; +} +.pre-scrollable { + max-height: 340px; + overflow-y: scroll; +} +.container { + padding-right: 15px; + padding-left: 15px; + margin-right: auto; + margin-left: auto; +} +.container:before, .container:after { + display: table; + content: " "} +.container:after { + clear: both; +} +.container:before, .container:after { + display: table; + content: " "} +.container:after { + clear: both; +} +.container:before, .container:after { + display: table; + content: " "} +.container:after { + clear: both; +} +.container:before, .container:after { + display: table; + content: " "} +.container:after { + clear: both; +} +.container:before, .container:after { + display: table; + content: " "} +.container:after { + clear: both; +} +@media(min-width:768px) { + .container { + width: 750px; +} +}@media(min-width:992px) { + .container { + width: 970px; +} +}@media(min-width:1200px) { + .container { + width: 1170px; +} +}.row { + margin-right: -15px; + margin-left: -15px; +} +.row:before, .row:after { + display: table; + content: " "} +.row:after { + clear: both; +} +.row:before, .row:after { + display: table; + content: " "} +.row:after { + clear: both; +} +.row:before, .row:after { + display: table; + content: " "} +.row:after { + clear: both; +} +.row:before, .row:after { + display: table; + content: " "} +.row:after { + clear: both; +} +.row:before, .row:after { + display: table; + content: " "} +.row:after { + clear: both; +} +.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 { + position: relative; + min-height: 1px; + padding-right: 15px; + padding-left: 15px; +} +.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 { + float: left; +} +.col-xs-12 { + width: 100%} +.col-xs-11 { + width: 91.66666666666666%} +.col-xs-10 { + width: 83.33333333333334%} +.col-xs-9 { + width: 75%} +.col-xs-8 { + width: 66.66666666666666%} +.col-xs-7 { + width: 58.333333333333336%} +.col-xs-6 { + width: 50%} +.col-xs-5 { + width: 41.66666666666667%} +.col-xs-4 { + width: 33.33333333333333%} +.col-xs-3 { + width: 25%} +.col-xs-2 { + width: 16.666666666666664%} +.col-xs-1 { + width: 8.333333333333332%} +.col-xs-pull-12 { + right: 100%} +.col-xs-pull-11 { + right: 91.66666666666666%} +.col-xs-pull-10 { + right: 83.33333333333334%} +.col-xs-pull-9 { + right: 75%} +.col-xs-pull-8 { + right: 66.66666666666666%} +.col-xs-pull-7 { + right: 58.333333333333336%} +.col-xs-pull-6 { + right: 50%} +.col-xs-pull-5 { + right: 41.66666666666667%} +.col-xs-pull-4 { + right: 33.33333333333333%} +.col-xs-pull-3 { + right: 25%} +.col-xs-pull-2 { + right: 16.666666666666664%} +.col-xs-pull-1 { + right: 8.333333333333332%} +.col-xs-pull-0 { + right: 0; +} +.col-xs-push-12 { + left: 100%} +.col-xs-push-11 { + left: 91.66666666666666%} +.col-xs-push-10 { + left: 83.33333333333334%} +.col-xs-push-9 { + left: 75%} +.col-xs-push-8 { + left: 66.66666666666666%} +.col-xs-push-7 { + left: 58.333333333333336%} +.col-xs-push-6 { + left: 50%} +.col-xs-push-5 { + left: 41.66666666666667%} +.col-xs-push-4 { + left: 33.33333333333333%} +.col-xs-push-3 { + left: 25%} +.col-xs-push-2 { + left: 16.666666666666664%} +.col-xs-push-1 { + left: 8.333333333333332%} +.col-xs-push-0 { + left: 0; +} +.col-xs-offset-12 { + margin-left: 100%} +.col-xs-offset-11 { + margin-left: 91.66666666666666%} +.col-xs-offset-10 { + margin-left: 83.33333333333334%} +.col-xs-offset-9 { + margin-left: 75%} +.col-xs-offset-8 { + margin-left: 66.66666666666666%} +.col-xs-offset-7 { + margin-left: 58.333333333333336%} +.col-xs-offset-6 { + margin-left: 50%} +.col-xs-offset-5 { + margin-left: 41.66666666666667%} +.col-xs-offset-4 { + margin-left: 33.33333333333333%} +.col-xs-offset-3 { + margin-left: 25%} +.col-xs-offset-2 { + margin-left: 16.666666666666664%} +.col-xs-offset-1 { + margin-left: 8.333333333333332%} +.col-xs-offset-0 { + margin-left: 0; +} +@media(min-width:768px) { + .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 { + float: left; +} +.col-sm-12 { + width: 100%} +.col-sm-11 { + width: 91.66666666666666%} +.col-sm-10 { + width: 83.33333333333334%} +.col-sm-9 { + width: 75%} +.col-sm-8 { + width: 66.66666666666666%} +.col-sm-7 { + width: 58.333333333333336%} +.col-sm-6 { + width: 50%} +.col-sm-5 { + width: 41.66666666666667%} +.col-sm-4 { + width: 33.33333333333333%} +.col-sm-3 { + width: 25%} +.col-sm-2 { + width: 16.666666666666664%} +.col-sm-1 { + width: 8.333333333333332%} +.col-sm-pull-12 { + right: 100%} +.col-sm-pull-11 { + right: 91.66666666666666%} +.col-sm-pull-10 { + right: 83.33333333333334%} +.col-sm-pull-9 { + right: 75%} +.col-sm-pull-8 { + right: 66.66666666666666%} +.col-sm-pull-7 { + right: 58.333333333333336%} +.col-sm-pull-6 { + right: 50%} +.col-sm-pull-5 { + right: 41.66666666666667%} +.col-sm-pull-4 { + right: 33.33333333333333%} +.col-sm-pull-3 { + right: 25%} +.col-sm-pull-2 { + right: 16.666666666666664%} +.col-sm-pull-1 { + right: 8.333333333333332%} +.col-sm-pull-0 { + right: 0; +} +.col-sm-push-12 { + left: 100%} +.col-sm-push-11 { + left: 91.66666666666666%} +.col-sm-push-10 { + left: 83.33333333333334%} +.col-sm-push-9 { + left: 75%} +.col-sm-push-8 { + left: 66.66666666666666%} +.col-sm-push-7 { + left: 58.333333333333336%} +.col-sm-push-6 { + left: 50%} +.col-sm-push-5 { + left: 41.66666666666667%} +.col-sm-push-4 { + left: 33.33333333333333%} +.col-sm-push-3 { + left: 25%} +.col-sm-push-2 { + left: 16.666666666666664%} +.col-sm-push-1 { + left: 8.333333333333332%} +.col-sm-push-0 { + left: 0; +} +.col-sm-offset-12 { + margin-left: 100%} +.col-sm-offset-11 { + margin-left: 91.66666666666666%} +.col-sm-offset-10 { + margin-left: 83.33333333333334%} +.col-sm-offset-9 { + margin-left: 75%} +.col-sm-offset-8 { + margin-left: 66.66666666666666%} +.col-sm-offset-7 { + margin-left: 58.333333333333336%} +.col-sm-offset-6 { + margin-left: 50%} +.col-sm-offset-5 { + margin-left: 41.66666666666667%} +.col-sm-offset-4 { + margin-left: 33.33333333333333%} +.col-sm-offset-3 { + margin-left: 25%} +.col-sm-offset-2 { + margin-left: 16.666666666666664%} +.col-sm-offset-1 { + margin-left: 8.333333333333332%} +.col-sm-offset-0 { + margin-left: 0; +} +}@media(min-width:992px) { + .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 { + float: left; +} +.col-md-12 { + width: 100%} +.col-md-11 { + width: 91.66666666666666%} +.col-md-10 { + width: 83.33333333333334%} +.col-md-9 { + width: 75%} +.col-md-8 { + width: 66.66666666666666%} +.col-md-7 { + width: 58.333333333333336%} +.col-md-6 { + width: 50%} +.col-md-5 { + width: 41.66666666666667%} +.col-md-4 { + width: 33.33333333333333%} +.col-md-3 { + width: 25%} +.col-md-2 { + width: 16.666666666666664%} +.col-md-1 { + width: 8.333333333333332%} +.col-md-pull-12 { + right: 100%} +.col-md-pull-11 { + right: 91.66666666666666%} +.col-md-pull-10 { + right: 83.33333333333334%} +.col-md-pull-9 { + right: 75%} +.col-md-pull-8 { + right: 66.66666666666666%} +.col-md-pull-7 { + right: 58.333333333333336%} +.col-md-pull-6 { + right: 50%} +.col-md-pull-5 { + right: 41.66666666666667%} +.col-md-pull-4 { + right: 33.33333333333333%} +.col-md-pull-3 { + right: 25%} +.col-md-pull-2 { + right: 16.666666666666664%} +.col-md-pull-1 { + right: 8.333333333333332%} +.col-md-pull-0 { + right: 0; +} +.col-md-push-12 { + left: 100%} +.col-md-push-11 { + left: 91.66666666666666%} +.col-md-push-10 { + left: 83.33333333333334%} +.col-md-push-9 { + left: 75%} +.col-md-push-8 { + left: 66.66666666666666%} +.col-md-push-7 { + left: 58.333333333333336%} +.col-md-push-6 { + left: 50%} +.col-md-push-5 { + left: 41.66666666666667%} +.col-md-push-4 { + left: 33.33333333333333%} +.col-md-push-3 { + left: 25%} +.col-md-push-2 { + left: 16.666666666666664%} +.col-md-push-1 { + left: 8.333333333333332%} +.col-md-push-0 { + left: 0; +} +.col-md-offset-12 { + margin-left: 100%} +.col-md-offset-11 { + margin-left: 91.66666666666666%} +.col-md-offset-10 { + margin-left: 83.33333333333334%} +.col-md-offset-9 { + margin-left: 75%} +.col-md-offset-8 { + margin-left: 66.66666666666666%} +.col-md-offset-7 { + margin-left: 58.333333333333336%} +.col-md-offset-6 { + margin-left: 50%} +.col-md-offset-5 { + margin-left: 41.66666666666667%} +.col-md-offset-4 { + margin-left: 33.33333333333333%} +.col-md-offset-3 { + margin-left: 25%} +.col-md-offset-2 { + margin-left: 16.666666666666664%} +.col-md-offset-1 { + margin-left: 8.333333333333332%} +.col-md-offset-0 { + margin-left: 0; +} +}@media(min-width:1200px) { + .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 { + float: left; +} +.col-lg-12 { + width: 100%} +.col-lg-11 { + width: 91.66666666666666%} +.col-lg-10 { + width: 83.33333333333334%} +.col-lg-9 { + width: 75%} +.col-lg-8 { + width: 66.66666666666666%} +.col-lg-7 { + width: 58.333333333333336%} +.col-lg-6 { + width: 50%} +.col-lg-5 { + width: 41.66666666666667%} +.col-lg-4 { + width: 33.33333333333333%} +.col-lg-3 { + width: 25%} +.col-lg-2 { + width: 16.666666666666664%} +.col-lg-1 { + width: 8.333333333333332%} +.col-lg-pull-12 { + right: 100%} +.col-lg-pull-11 { + right: 91.66666666666666%} +.col-lg-pull-10 { + right: 83.33333333333334%} +.col-lg-pull-9 { + right: 75%} +.col-lg-pull-8 { + right: 66.66666666666666%} +.col-lg-pull-7 { + right: 58.333333333333336%} +.col-lg-pull-6 { + right: 50%} +.col-lg-pull-5 { + right: 41.66666666666667%} +.col-lg-pull-4 { + right: 33.33333333333333%} +.col-lg-pull-3 { + right: 25%} +.col-lg-pull-2 { + right: 16.666666666666664%} +.col-lg-pull-1 { + right: 8.333333333333332%} +.col-lg-pull-0 { + right: 0; +} +.col-lg-push-12 { + left: 100%} +.col-lg-push-11 { + left: 91.66666666666666%} +.col-lg-push-10 { + left: 83.33333333333334%} +.col-lg-push-9 { + left: 75%} +.col-lg-push-8 { + left: 66.66666666666666%} +.col-lg-push-7 { + left: 58.333333333333336%} +.col-lg-push-6 { + left: 50%} +.col-lg-push-5 { + left: 41.66666666666667%} +.col-lg-push-4 { + left: 33.33333333333333%} +.col-lg-push-3 { + left: 25%} +.col-lg-push-2 { + left: 16.666666666666664%} +.col-lg-push-1 { + left: 8.333333333333332%} +.col-lg-push-0 { + left: 0; +} +.col-lg-offset-12 { + margin-left: 100%} +.col-lg-offset-11 { + margin-left: 91.66666666666666%} +.col-lg-offset-10 { + margin-left: 83.33333333333334%} +.col-lg-offset-9 { + margin-left: 75%} +.col-lg-offset-8 { + margin-left: 66.66666666666666%} +.col-lg-offset-7 { + margin-left: 58.333333333333336%} +.col-lg-offset-6 { + margin-left: 50%} +.col-lg-offset-5 { + margin-left: 41.66666666666667%} +.col-lg-offset-4 { + margin-left: 33.33333333333333%} +.col-lg-offset-3 { + margin-left: 25%} +.col-lg-offset-2 { + margin-left: 16.666666666666664%} +.col-lg-offset-1 { + margin-left: 8.333333333333332%} +.col-lg-offset-0 { + margin-left: 0; +} +}table { + max-width: 100%; + background-color: transparent; +} +th { + text-align: left; +} +.table { + width: 100%; + margin-bottom: 21px; +} +.table>thead>tr>th, .table>tbody>tr>th, .table>tfoot>tr>th, .table>thead>tr>td, .table>tbody>tr>td, .table>tfoot>tr>td { + padding: 8px; + line-height: 1.428571429; + vertical-align: top; + border-top: 1px solid #ddd; +} +.table>thead>tr>th { + vertical-align: bottom; + border-bottom: 2px solid #ddd; +} +.table>caption+thead>tr:first-child>th, .table>colgroup+thead>tr:first-child>th, .table>thead:first-child>tr:first-child>th, .table>caption+thead>tr:first-child>td, .table>colgroup+thead>tr:first-child>td, .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>thead>tr>th, .table-condensed>tbody>tr>th, .table-condensed>tfoot>tr>th, .table-condensed>thead>tr>td, .table-condensed>tbody>tr>td, .table-condensed>tfoot>tr>td { + padding: 5px; +} +.table-bordered { + border: 1px solid #ddd; +} +.table-bordered>thead>tr>th, .table-bordered>tbody>tr>th, .table-bordered>tfoot>tr>th, .table-bordered>thead>tr>td, .table-bordered>tbody>tr>td, .table-bordered>tfoot>tr>td { + border: 1px solid #ddd; +} +.table-bordered>thead>tr>th, .table-bordered>thead>tr>td { + border-bottom-width: 2px; +} +.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 col[class*="col-"] { + position: static; + display: table-column; + float: none; +} +table td[class*="col-"], table th[class*="col-"] { + display: table-cell; + float: none; +} +.table>thead>tr>.active, .table>tbody>tr>.active, .table>tfoot>tr>.active, .table>thead>.active>td, .table>tbody>.active>td, .table>tfoot>.active>td, .table>thead>.active>th, .table>tbody>.active>th, .table>tfoot>.active>th { + background-color: #f5f5f5; +} +.table-hover>tbody>tr>.active:hover, .table-hover>tbody>.active:hover>td, .table-hover>tbody>.active:hover>th { + background-color: #e8e8e8; +} +.table>thead>tr>.success, .table>tbody>tr>.success, .table>tfoot>tr>.success, .table>thead>.success>td, .table>tbody>.success>td, .table>tfoot>.success>td, .table>thead>.success>th, .table>tbody>.success>th, .table>tfoot>.success>th { + background-color: #dff0d8; +} +.table-hover>tbody>tr>.success:hover, .table-hover>tbody>.success:hover>td, .table-hover>tbody>.success:hover>th { + background-color: #d0e9c6; +} +.table>thead>tr>.danger, .table>tbody>tr>.danger, .table>tfoot>tr>.danger, .table>thead>.danger>td, .table>tbody>.danger>td, .table>tfoot>.danger>td, .table>thead>.danger>th, .table>tbody>.danger>th, .table>tfoot>.danger>th { + background-color: #f2dede; +} +.table-hover>tbody>tr>.danger:hover, .table-hover>tbody>.danger:hover>td, .table-hover>tbody>.danger:hover>th { + background-color: #ebcccc; +} +.table>thead>tr>.warning, .table>tbody>tr>.warning, .table>tfoot>tr>.warning, .table>thead>.warning>td, .table>tbody>.warning>td, .table>tfoot>.warning>td, .table>thead>.warning>th, .table>tbody>.warning>th, .table>tfoot>.warning>th { + background-color: #fcf8e3; +} +.table-hover>tbody>tr>.warning:hover, .table-hover>tbody>.warning:hover>td, .table-hover>tbody>.warning:hover>th { + background-color: #faf2cc; +} +@media(max-width:767px) { + .table-responsive { + width: 100%; + margin-bottom: 15.75px; + overflow-x: scroll; + overflow-y: hidden; + border: 1px solid #ddd; + -ms-overflow-style: -ms-autohiding-scrollbar; + -webkit-overflow-scrolling: touch; +} +.table-responsive>.table { + margin-bottom: 0; +} +.table-responsive>.table>thead>tr>th, .table-responsive>.table>tbody>tr>th, .table-responsive>.table>tfoot>tr>th, .table-responsive>.table>thead>tr>td, .table-responsive>.table>tbody>tr>td, .table-responsive>.table>tfoot>tr>td { + white-space: nowrap; +} +.table-responsive>.table-bordered { + border: 0; +} +.table-responsive>.table-bordered>thead>tr>th:first-child, .table-responsive>.table-bordered>tbody>tr>th:first-child, .table-responsive>.table-bordered>tfoot>tr>th:first-child, .table-responsive>.table-bordered>thead>tr>td:first-child, .table-responsive>.table-bordered>tbody>tr>td:first-child, .table-responsive>.table-bordered>tfoot>tr>td:first-child { + border-left: 0; +} +.table-responsive>.table-bordered>thead>tr>th:last-child, .table-responsive>.table-bordered>tbody>tr>th:last-child, .table-responsive>.table-bordered>tfoot>tr>th:last-child, .table-responsive>.table-bordered>thead>tr>td:last-child, .table-responsive>.table-bordered>tbody>tr>td:last-child, .table-responsive>.table-bordered>tfoot>tr>td:last-child { + border-right: 0; +} +.table-responsive>.table-bordered>tbody>tr:last-child>th, .table-responsive>.table-bordered>tfoot>tr:last-child>th, .table-responsive>.table-bordered>tbody>tr:last-child>td, .table-responsive>.table-bordered>tfoot>tr:last-child>td { + border-bottom: 0; +} +}fieldset { + padding: 0; + margin: 0; + border: 0; +} +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: 21px; + font-size: 22.5px; + line-height: inherit; + color: #333; + border: 0; + border-bottom: 1px solid #e5e5e5; +} +label { + display: inline-block; + margin-bottom: 5px; + font-weight: bold; +} +input[type="search"] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +input[type="radio"], input[type="checkbox"] { + margin: 4px 0 0; + margin-top: 1px \9; + line-height: normal; +} +input[type="file"] { + display: block; +} +select[multiple], select[size] { + height: auto; +} +select optgroup { + font-family: inherit; + font-size: inherit; + font-style: inherit; +} +input[type="file"]:focus, input[type="radio"]:focus, input[type="checkbox"]:focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +input[type="number"]::-webkit-outer-spin-button, input[type="number"]::-webkit-inner-spin-button { + height: auto; +} +output { + display: block; + padding-top: 7px; + font-size: 15px; + line-height: 1.428571429; + color: #6f6f6f; + vertical-align: middle; +} +.form-control { + display: block; + width: 100%; + height: 35px; + padding: 6px 12px; + font-size: 15px; + line-height: 1.428571429; + color: #6f6f6f; + vertical-align: middle; + background-color: #fff; + background-image: none; + border: 1px solid #ccc; + border-radius: 0; + -webkit-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-color ease-in-out .15s, box-shadow ease-in-out .15s; + transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; +} +.form-control:focus { + border-color: #66afe9; + outline: 0; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6); +} +.form-control:-moz-placeholder { + color: #999; +} +.form-control::-moz-placeholder { + color: #999; + opacity: 1; +} +.form-control:-ms-input-placeholder { + color: #999; +} +.form-control::-webkit-input-placeholder { + color: #999; +} +.form-control[disabled], .form-control[readonly], fieldset[disabled] .form-control { + cursor: not-allowed; + background-color: #eee; +} +textarea.form-control { + height: auto; +} +.form-group { + margin-bottom: 15px; +} +.radio, .checkbox { + display: block; + min-height: 21px; + padding-left: 20px; + margin-top: 10px; + margin-bottom: 10px; + vertical-align: middle; +} +.radio label, .checkbox label { + display: inline; + margin-bottom: 0; + font-weight: normal; + cursor: pointer; +} +.radio input[type="radio"], .radio-inline input[type="radio"], .checkbox input[type="checkbox"], .checkbox-inline input[type="checkbox"] { + float: left; + margin-left: -20px; +} +.radio+.radio, .checkbox+.checkbox { + margin-top: -5px; +} +.radio-inline, .checkbox-inline { + display: inline-block; + padding-left: 20px; + margin-bottom: 0; + font-weight: normal; + vertical-align: middle; + cursor: pointer; +} +.radio-inline+.radio-inline, .checkbox-inline+.checkbox-inline { + margin-top: 0; + margin-left: 10px; +} +input[type="radio"][disabled], input[type="checkbox"][disabled], .radio[disabled], .radio-inline[disabled], .checkbox[disabled], .checkbox-inline[disabled], fieldset[disabled] input[type="radio"], fieldset[disabled] input[type="checkbox"], fieldset[disabled] .radio, fieldset[disabled] .radio-inline, fieldset[disabled] .checkbox, fieldset[disabled] .checkbox-inline { + cursor: not-allowed; +} +.input-sm { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 0; +} +select.input-sm { + height: 30px; + line-height: 30px; +} +textarea.input-sm { + height: auto; +} +.input-lg { + height: 48px; + padding: 10px 16px; + font-size: 19px; + line-height: 1.33; + border-radius: 0; +} +select.input-lg { + height: 48px; + line-height: 48px; +} +textarea.input-lg { + height: auto; +} +.has-warning .help-block, .has-warning .control-label, .has-warning .radio, .has-warning .checkbox, .has-warning .radio-inline, .has-warning .checkbox-inline { + color: #e99002; +} +.has-warning .form-control { + border-color: #e99002; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} +.has-warning .form-control:focus { + border-color: #b67102; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #febc53; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #febc53; +} +.has-warning .input-group-addon { + color: #e99002; + background-color: #fcf8e3; + border-color: #e99002; +} +.has-error .help-block, .has-error .control-label, .has-error .radio, .has-error .checkbox, .has-error .radio-inline, .has-error .checkbox-inline { + color: #f04124; +} +.has-error .form-control { + border-color: #f04124; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} +.has-error .form-control:focus { + border-color: #d32a0e; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #f79483; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #f79483; +} +.has-error .input-group-addon { + color: #f04124; + background-color: #f2dede; + border-color: #f04124; +} +.has-success .help-block, .has-success .control-label, .has-success .radio, .has-success .checkbox, .has-success .radio-inline, .has-success .checkbox-inline { + color: #43ac6a; +} +.has-success .form-control { + border-color: #43ac6a; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} +.has-success .form-control:focus { + border-color: #358753; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #85d0a1; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #85d0a1; +} +.has-success .input-group-addon { + color: #43ac6a; + background-color: #dff0d8; + border-color: #43ac6a; +} +.form-control-static { + margin-bottom: 0; +} +.help-block { + display: block; + margin-top: 5px; + margin-bottom: 10px; + color: #626262; +} +@media(min-width:768px) { + .form-inline .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; +} +.form-inline .form-control { + display: inline-block; +} +.form-inline select.form-control { + width: auto; +} +.form-inline .radio, .form-inline .checkbox { + display: inline-block; + padding-left: 0; + margin-top: 0; + margin-bottom: 0; +} +.form-inline .radio input[type="radio"], .form-inline .checkbox input[type="checkbox"] { + float: none; + margin-left: 0; +} +}.form-horizontal .control-label, .form-horizontal .radio, .form-horizontal .checkbox, .form-horizontal .radio-inline, .form-horizontal .checkbox-inline { + padding-top: 7px; + margin-top: 0; + margin-bottom: 0; +} +.form-horizontal .radio, .form-horizontal .checkbox { + min-height: 28px; +} +.form-horizontal .form-group { + margin-right: -15px; + margin-left: -15px; +} +.form-horizontal .form-group:before, .form-horizontal .form-group:after { + display: table; + content: " "} +.form-horizontal .form-group:after { + clear: both; +} +.form-horizontal .form-group:before, .form-horizontal .form-group:after { + display: table; + content: " "} +.form-horizontal .form-group:after { + clear: both; +} +.form-horizontal .form-group:before, .form-horizontal .form-group:after { + display: table; + content: " "} +.form-horizontal .form-group:after { + clear: both; +} +.form-horizontal .form-group:before, .form-horizontal .form-group:after { + display: table; + content: " "} +.form-horizontal .form-group:after { + clear: both; +} +.form-horizontal .form-group:before, .form-horizontal .form-group:after { + display: table; + content: " "} +.form-horizontal .form-group:after { + clear: both; +} +.form-horizontal .form-control-static { + padding-top: 7px; +} +@media(min-width:768px) { + .form-horizontal .control-label { + text-align: right; +} +}.btn { + display: inline-block; + padding: 6px 12px; + margin-bottom: 0; + font-size: 15px; + font-weight: normal; + line-height: 1.428571429; + text-align: center; + white-space: nowrap; + vertical-align: middle; + cursor: pointer; + background-image: none; + border: 1px solid transparent; + border-radius: 0; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + -o-user-select: none; + user-select: none; +} +.btn:focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +.btn:hover, .btn:focus { + color: #333; + text-decoration: none; +} +.btn:active, .btn.active { + background-image: none; + outline: 0; + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); +} +.btn.disabled, .btn[disabled], fieldset[disabled] .btn { + pointer-events: none; + cursor: not-allowed; + opacity: .65; + filter: alpha(opacity=65); + -webkit-box-shadow: none; + box-shadow: none; +} +.btn-default { + color: #333; + background-color: #e7e7e7; + border-color: #dadada; +} +.btn-default:hover, .btn-default:focus, .btn-default:active, .btn-default.active, .open .dropdown-toggle.btn-default { + color: #333; + background-color: #d3d3d3; + border-color: #bbb; +} +.btn-default:active, .btn-default.active, .open .dropdown-toggle.btn-default { + background-image: none; +} +.btn-default.disabled, .btn-default[disabled], fieldset[disabled] .btn-default, .btn-default.disabled:hover, .btn-default[disabled]:hover, fieldset[disabled] .btn-default:hover, .btn-default.disabled:focus, .btn-default[disabled]:focus, fieldset[disabled] .btn-default:focus, .btn-default.disabled:active, .btn-default[disabled]:active, fieldset[disabled] .btn-default:active, .btn-default.disabled.active, .btn-default[disabled].active, fieldset[disabled] .btn-default.active { + background-color: #e7e7e7; + border-color: #dadada; +} +.btn-default .badge { + color: #e7e7e7; + background-color: #fff; +} +.btn-primary { + color: #fff; + background-color: #008cba; + border-color: #0079a1; +} +.btn-primary:hover, .btn-primary:focus, .btn-primary:active, .btn-primary.active, .open .dropdown-toggle.btn-primary { + color: #fff; + background-color: #006d91; + border-color: #004b63; +} +.btn-primary:active, .btn-primary.active, .open .dropdown-toggle.btn-primary { + background-image: none; +} +.btn-primary.disabled, .btn-primary[disabled], fieldset[disabled] .btn-primary, .btn-primary.disabled:hover, .btn-primary[disabled]:hover, fieldset[disabled] .btn-primary:hover, .btn-primary.disabled:focus, .btn-primary[disabled]:focus, fieldset[disabled] .btn-primary:focus, .btn-primary.disabled:active, .btn-primary[disabled]:active, fieldset[disabled] .btn-primary:active, .btn-primary.disabled.active, .btn-primary[disabled].active, fieldset[disabled] .btn-primary.active { + background-color: #008cba; + border-color: #0079a1; +} +.btn-primary .badge { + color: #008cba; + background-color: #fff; +} +.btn-warning { + color: #fff; + background-color: #e99002; + border-color: #d08002; +} +.btn-warning:hover, .btn-warning:focus, .btn-warning:active, .btn-warning.active, .open .dropdown-toggle.btn-warning { + color: #fff; + background-color: #c17702; + border-color: #935b01; +} +.btn-warning:active, .btn-warning.active, .open .dropdown-toggle.btn-warning { + background-image: none; +} +.btn-warning.disabled, .btn-warning[disabled], fieldset[disabled] .btn-warning, .btn-warning.disabled:hover, .btn-warning[disabled]:hover, fieldset[disabled] .btn-warning:hover, .btn-warning.disabled:focus, .btn-warning[disabled]:focus, fieldset[disabled] .btn-warning:focus, .btn-warning.disabled:active, .btn-warning[disabled]:active, fieldset[disabled] .btn-warning:active, .btn-warning.disabled.active, .btn-warning[disabled].active, fieldset[disabled] .btn-warning.active { + background-color: #e99002; + border-color: #d08002; +} +.btn-warning .badge { + color: #e99002; + background-color: #fff; +} +.btn-danger { + color: #fff; + background-color: #f04124; + border-color: #ea2f10; +} +.btn-danger:hover, .btn-danger:focus, .btn-danger:active, .btn-danger.active, .open .dropdown-toggle.btn-danger { + color: #fff; + background-color: #dc2c0f; + border-color: #b1240c; +} +.btn-danger:active, .btn-danger.active, .open .dropdown-toggle.btn-danger { + background-image: none; +} +.btn-danger.disabled, .btn-danger[disabled], fieldset[disabled] .btn-danger, .btn-danger.disabled:hover, .btn-danger[disabled]:hover, fieldset[disabled] .btn-danger:hover, .btn-danger.disabled:focus, .btn-danger[disabled]:focus, fieldset[disabled] .btn-danger:focus, .btn-danger.disabled:active, .btn-danger[disabled]:active, fieldset[disabled] .btn-danger:active, .btn-danger.disabled.active, .btn-danger[disabled].active, fieldset[disabled] .btn-danger.active { + background-color: #f04124; + border-color: #ea2f10; +} +.btn-danger .badge { + color: #f04124; + background-color: #fff; +} +.btn-success { + color: #fff; + background-color: #43ac6a; + border-color: #3c9a5f; +} +.btn-success:hover, .btn-success:focus, .btn-success:active, .btn-success.active, .open .dropdown-toggle.btn-success { + color: #fff; + background-color: #388f58; + border-color: #2b6e44; +} +.btn-success:active, .btn-success.active, .open .dropdown-toggle.btn-success { + background-image: none; +} +.btn-success.disabled, .btn-success[disabled], fieldset[disabled] .btn-success, .btn-success.disabled:hover, .btn-success[disabled]:hover, fieldset[disabled] .btn-success:hover, .btn-success.disabled:focus, .btn-success[disabled]:focus, fieldset[disabled] .btn-success:focus, .btn-success.disabled:active, .btn-success[disabled]:active, fieldset[disabled] .btn-success:active, .btn-success.disabled.active, .btn-success[disabled].active, fieldset[disabled] .btn-success.active { + background-color: #43ac6a; + border-color: #3c9a5f; +} +.btn-success .badge { + color: #43ac6a; + background-color: #fff; +} +.btn-info { + color: #fff; + background-color: #5bc0de; + border-color: #46b8da; +} +.btn-info:hover, .btn-info:focus, .btn-info:active, .btn-info.active, .open .dropdown-toggle.btn-info { + color: #fff; + background-color: #39b3d7; + border-color: #269abc; +} +.btn-info:active, .btn-info.active, .open .dropdown-toggle.btn-info { + background-image: none; +} +.btn-info.disabled, .btn-info[disabled], fieldset[disabled] .btn-info, .btn-info.disabled:hover, .btn-info[disabled]:hover, fieldset[disabled] .btn-info:hover, .btn-info.disabled:focus, .btn-info[disabled]:focus, fieldset[disabled] .btn-info:focus, .btn-info.disabled:active, .btn-info[disabled]:active, fieldset[disabled] .btn-info:active, .btn-info.disabled.active, .btn-info[disabled].active, fieldset[disabled] .btn-info.active { + background-color: #5bc0de; + border-color: #46b8da; +} +.btn-info .badge { + color: #5bc0de; + background-color: #fff; +} +.btn-link { + font-weight: normal; + color: #008cba; + cursor: pointer; + border-radius: 0; +} +.btn-link, .btn-link:active, .btn-link[disabled], fieldset[disabled] .btn-link { + background-color: transparent; + -webkit-box-shadow: none; + box-shadow: none; +} +.btn-link, .btn-link:hover, .btn-link:focus, .btn-link:active { + border-color: transparent; +} +.btn-link:hover, .btn-link:focus { + color: #00526e; + text-decoration: underline; + background-color: transparent; +} +.btn-link[disabled]:hover, fieldset[disabled] .btn-link:hover, .btn-link[disabled]:focus, fieldset[disabled] .btn-link:focus { + color: #999; + text-decoration: none; +} +.btn-lg { + padding: 10px 16px; + font-size: 19px; + line-height: 1.33; + border-radius: 0; +} +.btn-sm { + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 0; +} +.btn-xs { + padding: 1px 5px; + font-size: 12px; + line-height: 1.5; + border-radius: 0; +} +.btn-block { + display: block; + width: 100%; + padding-right: 0; + padding-left: 0; +} +.btn-block+.btn-block { + margin-top: 5px; +} +input[type="submit"].btn-block, input[type="reset"].btn-block, input[type="button"].btn-block { + width: 100%} +.fade { + opacity: 0; + -webkit-transition: opacity .15s linear; + transition: opacity .15s linear; +} +.fade.in { + opacity: 1; +} +.collapse { + display: none; +} +.collapse.in { + display: block; +} +.collapsing { + position: relative; + height: 0; + overflow: hidden; + -webkit-transition: height .35s ease; + transition: height .35s ease; +} +@font-face { + font-family: 'Glyphicons Halflings'; + src: url('../fonts/glyphicons-halflings-regular.eot'); + src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons-halflingsregular') format('svg'); +} +.glyphicon { + position: relative; + top: 1px; + display: inline-block; + font-family: 'Glyphicons Halflings'; + -webkit-font-smoothing: antialiased; + font-style: normal; + font-weight: normal; + line-height: 1; + -moz-osx-font-smoothing: grayscale; +} +.glyphicon:empty { + width: 1em; +} +.glyphicon-asterisk:before { + content: "\2a"} +.glyphicon-plus:before { + content: "\2b"} +.glyphicon-euro:before { + content: "\20ac"} +.glyphicon-minus:before { + content: "\2212"} +.glyphicon-cloud:before { + content: "\2601"} +.glyphicon-envelope:before { + content: "\2709"} +.glyphicon-pencil:before { + content: "\270f"} +.glyphicon-glass:before { + content: "\e001"} +.glyphicon-music:before { + content: "\e002"} +.glyphicon-search:before { + content: "\e003"} +.glyphicon-heart:before { + content: "\e005"} +.glyphicon-star:before { + content: "\e006"} +.glyphicon-star-empty:before { + content: "\e007"} +.glyphicon-user:before { + content: "\e008"} +.glyphicon-film:before { + content: "\e009"} +.glyphicon-th-large:before { + content: "\e010"} +.glyphicon-th:before { + content: "\e011"} +.glyphicon-th-list:before { + content: "\e012"} +.glyphicon-ok:before { + content: "\e013"} +.glyphicon-remove:before { + content: "\e014"} +.glyphicon-zoom-in:before { + content: "\e015"} +.glyphicon-zoom-out:before { + content: "\e016"} +.glyphicon-off:before { + content: "\e017"} +.glyphicon-signal:before { + content: "\e018"} +.glyphicon-cog:before { + content: "\e019"} +.glyphicon-trash:before { + content: "\e020"} +.glyphicon-home:before { + content: "\e021"} +.glyphicon-file:before { + content: "\e022"} +.glyphicon-time:before { + content: "\e023"} +.glyphicon-road:before { + content: "\e024"} +.glyphicon-download-alt:before { + content: "\e025"} +.glyphicon-download:before { + content: "\e026"} +.glyphicon-upload:before { + content: "\e027"} +.glyphicon-inbox:before { + content: "\e028"} +.glyphicon-play-circle:before { + content: "\e029"} +.glyphicon-repeat:before { + content: "\e030"} +.glyphicon-refresh:before { + content: "\e031"} +.glyphicon-list-alt:before { + content: "\e032"} +.glyphicon-lock:before { + content: "\e033"} +.glyphicon-flag:before { + content: "\e034"} +.glyphicon-headphones:before { + content: "\e035"} +.glyphicon-volume-off:before { + content: "\e036"} +.glyphicon-volume-down:before { + content: "\e037"} +.glyphicon-volume-up:before { + content: "\e038"} +.glyphicon-qrcode:before { + content: "\e039"} +.glyphicon-barcode:before { + content: "\e040"} +.glyphicon-tag:before { + content: "\e041"} +.glyphicon-tags:before { + content: "\e042"} +.glyphicon-book:before { + content: "\e043"} +.glyphicon-bookmark:before { + content: "\e044"} +.glyphicon-print:before { + content: "\e045"} +.glyphicon-camera:before { + content: "\e046"} +.glyphicon-font:before { + content: "\e047"} +.glyphicon-bold:before { + content: "\e048"} +.glyphicon-italic:before { + content: "\e049"} +.glyphicon-text-height:before { + content: "\e050"} +.glyphicon-text-width:before { + content: "\e051"} +.glyphicon-align-left:before { + content: "\e052"} +.glyphicon-align-center:before { + content: "\e053"} +.glyphicon-align-right:before { + content: "\e054"} +.glyphicon-align-justify:before { + content: "\e055"} +.glyphicon-list:before { + content: "\e056"} +.glyphicon-indent-left:before { + content: "\e057"} +.glyphicon-indent-right:before { + content: "\e058"} +.glyphicon-facetime-video:before { + content: "\e059"} +.glyphicon-picture:before { + content: "\e060"} +.glyphicon-map-marker:before { + content: "\e062"} +.glyphicon-adjust:before { + content: "\e063"} +.glyphicon-tint:before { + content: "\e064"} +.glyphicon-edit:before { + content: "\e065"} +.glyphicon-share:before { + content: "\e066"} +.glyphicon-check:before { + content: "\e067"} +.glyphicon-move:before { + content: "\e068"} +.glyphicon-step-backward:before { + content: "\e069"} +.glyphicon-fast-backward:before { + content: "\e070"} +.glyphicon-backward:before { + content: "\e071"} +.glyphicon-play:before { + content: "\e072"} +.glyphicon-pause:before { + content: "\e073"} +.glyphicon-stop:before { + content: "\e074"} +.glyphicon-forward:before { + content: "\e075"} +.glyphicon-fast-forward:before { + content: "\e076"} +.glyphicon-step-forward:before { + content: "\e077"} +.glyphicon-eject:before { + content: "\e078"} +.glyphicon-chevron-left:before { + content: "\e079"} +.glyphicon-chevron-right:before { + content: "\e080"} +.glyphicon-plus-sign:before { + content: "\e081"} +.glyphicon-minus-sign:before { + content: "\e082"} +.glyphicon-remove-sign:before { + content: "\e083"} +.glyphicon-ok-sign:before { + content: "\e084"} +.glyphicon-question-sign:before { + content: "\e085"} +.glyphicon-info-sign:before { + content: "\e086"} +.glyphicon-screenshot:before { + content: "\e087"} +.glyphicon-remove-circle:before { + content: "\e088"} +.glyphicon-ok-circle:before { + content: "\e089"} +.glyphicon-ban-circle:before { + content: "\e090"} +.glyphicon-arrow-left:before { + content: "\e091"} +.glyphicon-arrow-right:before { + content: "\e092"} +.glyphicon-arrow-up:before { + content: "\e093"} +.glyphicon-arrow-down:before { + content: "\e094"} +.glyphicon-share-alt:before { + content: "\e095"} +.glyphicon-resize-full:before { + content: "\e096"} +.glyphicon-resize-small:before { + content: "\e097"} +.glyphicon-exclamation-sign:before { + content: "\e101"} +.glyphicon-gift:before { + content: "\e102"} +.glyphicon-leaf:before { + content: "\e103"} +.glyphicon-fire:before { + content: "\e104"} +.glyphicon-eye-open:before { + content: "\e105"} +.glyphicon-eye-close:before { + content: "\e106"} +.glyphicon-warning-sign:before { + content: "\e107"} +.glyphicon-plane:before { + content: "\e108"} +.glyphicon-calendar:before { + content: "\e109"} +.glyphicon-random:before { + content: "\e110"} +.glyphicon-comment:before { + content: "\e111"} +.glyphicon-magnet:before { + content: "\e112"} +.glyphicon-chevron-up:before { + content: "\e113"} +.glyphicon-chevron-down:before { + content: "\e114"} +.glyphicon-retweet:before { + content: "\e115"} +.glyphicon-shopping-cart:before { + content: "\e116"} +.glyphicon-folder-close:before { + content: "\e117"} +.glyphicon-folder-open:before { + content: "\e118"} +.glyphicon-resize-vertical:before { + content: "\e119"} +.glyphicon-resize-horizontal:before { + content: "\e120"} +.glyphicon-hdd:before { + content: "\e121"} +.glyphicon-bullhorn:before { + content: "\e122"} +.glyphicon-bell:before { + content: "\e123"} +.glyphicon-certificate:before { + content: "\e124"} +.glyphicon-thumbs-up:before { + content: "\e125"} +.glyphicon-thumbs-down:before { + content: "\e126"} +.glyphicon-hand-right:before { + content: "\e127"} +.glyphicon-hand-left:before { + content: "\e128"} +.glyphicon-hand-up:before { + content: "\e129"} +.glyphicon-hand-down:before { + content: "\e130"} +.glyphicon-circle-arrow-right:before { + content: "\e131"} +.glyphicon-circle-arrow-left:before { + content: "\e132"} +.glyphicon-circle-arrow-up:before { + content: "\e133"} +.glyphicon-circle-arrow-down:before { + content: "\e134"} +.glyphicon-globe:before { + content: "\e135"} +.glyphicon-wrench:before { + content: "\e136"} +.glyphicon-tasks:before { + content: "\e137"} +.glyphicon-filter:before { + content: "\e138"} +.glyphicon-briefcase:before { + content: "\e139"} +.glyphicon-fullscreen:before { + content: "\e140"} +.glyphicon-dashboard:before { + content: "\e141"} +.glyphicon-paperclip:before { + content: "\e142"} +.glyphicon-heart-empty:before { + content: "\e143"} +.glyphicon-link:before { + content: "\e144"} +.glyphicon-phone:before { + content: "\e145"} +.glyphicon-pushpin:before { + content: "\e146"} +.glyphicon-usd:before { + content: "\e148"} +.glyphicon-gbp:before { + content: "\e149"} +.glyphicon-sort:before { + content: "\e150"} +.glyphicon-sort-by-alphabet:before { + content: "\e151"} +.glyphicon-sort-by-alphabet-alt:before { + content: "\e152"} +.glyphicon-sort-by-order:before { + content: "\e153"} +.glyphicon-sort-by-order-alt:before { + content: "\e154"} +.glyphicon-sort-by-attributes:before { + content: "\e155"} +.glyphicon-sort-by-attributes-alt:before { + content: "\e156"} +.glyphicon-unchecked:before { + content: "\e157"} +.glyphicon-expand:before { + content: "\e158"} +.glyphicon-collapse-down:before { + content: "\e159"} +.glyphicon-collapse-up:before { + content: "\e160"} +.glyphicon-log-in:before { + content: "\e161"} +.glyphicon-flash:before { + content: "\e162"} +.glyphicon-log-out:before { + content: "\e163"} +.glyphicon-new-window:before { + content: "\e164"} +.glyphicon-record:before { + content: "\e165"} +.glyphicon-save:before { + content: "\e166"} +.glyphicon-open:before { + content: "\e167"} +.glyphicon-saved:before { + content: "\e168"} +.glyphicon-import:before { + content: "\e169"} +.glyphicon-export:before { + content: "\e170"} +.glyphicon-send:before { + content: "\e171"} +.glyphicon-floppy-disk:before { + content: "\e172"} +.glyphicon-floppy-saved:before { + content: "\e173"} +.glyphicon-floppy-remove:before { + content: "\e174"} +.glyphicon-floppy-save:before { + content: "\e175"} +.glyphicon-floppy-open:before { + content: "\e176"} +.glyphicon-credit-card:before { + content: "\e177"} +.glyphicon-transfer:before { + content: "\e178"} +.glyphicon-cutlery:before { + content: "\e179"} +.glyphicon-header:before { + content: "\e180"} +.glyphicon-compressed:before { + content: "\e181"} +.glyphicon-earphone:before { + content: "\e182"} +.glyphicon-phone-alt:before { + content: "\e183"} +.glyphicon-tower:before { + content: "\e184"} +.glyphicon-stats:before { + content: "\e185"} +.glyphicon-sd-video:before { + content: "\e186"} +.glyphicon-hd-video:before { + content: "\e187"} +.glyphicon-subtitles:before { + content: "\e188"} +.glyphicon-sound-stereo:before { + content: "\e189"} +.glyphicon-sound-dolby:before { + content: "\e190"} +.glyphicon-sound-5-1:before { + content: "\e191"} +.glyphicon-sound-6-1:before { + content: "\e192"} +.glyphicon-sound-7-1:before { + content: "\e193"} +.glyphicon-copyright-mark:before { + content: "\e194"} +.glyphicon-registration-mark:before { + content: "\e195"} +.glyphicon-cloud-download:before { + content: "\e197"} +.glyphicon-cloud-upload:before { + content: "\e198"} +.glyphicon-tree-conifer:before { + content: "\e199"} +.glyphicon-tree-deciduous:before { + content: "\e200"} +.caret { + display: inline-block; + width: 0; + height: 0; + margin-left: 2px; + vertical-align: middle; + border-top: 4px solid; + border-right: 4px solid transparent; + border-left: 4px solid transparent; +} +.dropdown { + position: relative; +} +.dropdown-toggle:focus { + outline: 0; +} +.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; + font-size: 15px; + list-style: none; + background-color: #fff; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.15); + border-radius: 0; + -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + background-clip: padding-box; +} +.dropdown-menu.pull-right { + right: 0; + left: auto; +} +.dropdown-menu .divider { + height: 1px; + margin: 9.5px 0; + overflow: hidden; + background-color: rgba(0, 0, 0, 0.2); +} +.dropdown-menu>li>a { + display: block; + padding: 3px 20px; + clear: both; + font-weight: normal; + line-height: 1.428571429; + color: #555; + white-space: nowrap; +} +.dropdown-menu>li>a:hover, .dropdown-menu>li>a:focus { + color: #262626; + text-decoration: none; + background-color: #eee; +} +.dropdown-menu>.active>a, .dropdown-menu>.active>a:hover, .dropdown-menu>.active>a:focus { + color: #fff; + text-decoration: none; + background-color: #008cba; + outline: 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: not-allowed; + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} +.open>.dropdown-menu { + display: block; +} +.open>a { + outline: 0; +} +.dropdown-header { + display: block; + padding: 3px 20px; + font-size: 12px; + line-height: 1.428571429; + color: #999; +} +.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; + content: ""} +.dropup .dropdown-menu, .navbar-fixed-bottom .dropdown .dropdown-menu { + top: auto; + bottom: 100%; + margin-bottom: 1px; +} +@media(min-width:768px) { + .navbar-right .dropdown-menu { + right: 0; + left: auto; +} +}.btn-group, .btn-group-vertical { + position: relative; + display: inline-block; + vertical-align: middle; +} +.btn-group>.btn, .btn-group-vertical>.btn { + position: relative; + float: left; +} +.btn-group>.btn:hover, .btn-group-vertical>.btn:hover, .btn-group>.btn:focus, .btn-group-vertical>.btn:focus, .btn-group>.btn:active, .btn-group-vertical>.btn:active, .btn-group>.btn.active, .btn-group-vertical>.btn.active { + z-index: 2; +} +.btn-group>.btn:focus, .btn-group-vertical>.btn:focus { + outline: 0; +} +.btn-group .btn+.btn, .btn-group .btn+.btn-group, .btn-group .btn-group+.btn, .btn-group .btn-group+.btn-group { + margin-left: -1px; +} +.btn-toolbar:before, .btn-toolbar:after { + display: table; + content: " "} +.btn-toolbar:after { + clear: both; +} +.btn-toolbar:before, .btn-toolbar:after { + display: table; + content: " "} +.btn-toolbar:after { + clear: both; +} +.btn-toolbar:before, .btn-toolbar:after { + display: table; + content: " "} +.btn-toolbar:after { + clear: both; +} +.btn-toolbar:before, .btn-toolbar:after { + display: table; + content: " "} +.btn-toolbar:after { + clear: both; +} +.btn-toolbar:before, .btn-toolbar:after { + display: table; + content: " "} +.btn-toolbar:after { + clear: both; +} +.btn-toolbar .btn-group { + float: left; +} +.btn-toolbar>.btn+.btn, .btn-toolbar>.btn-group+.btn, .btn-toolbar>.btn+.btn-group, .btn-toolbar>.btn-group+.btn-group { + margin-left: 5px; +} +.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { + border-radius: 0; +} +.btn-group>.btn:first-child { + margin-left: 0; +} +.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.btn-group>.btn:last-child:not(:first-child), .btn-group>.dropdown-toggle:not(:first-child) { + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} +.btn-group>.btn-group { + float: left; +} +.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn { + border-radius: 0; +} +.btn-group>.btn-group:first-child>.btn:last-child, .btn-group>.btn-group:first-child>.dropdown-toggle { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.btn-group>.btn-group:last-child>.btn:first-child { + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} +.btn-group .dropdown-toggle:active, .btn-group.open .dropdown-toggle { + outline: 0; +} +.btn-group-xs>.btn { + padding: 1px 5px; + font-size: 12px; + line-height: 1.5; + border-radius: 0; +} +.btn-group-sm>.btn { + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 0; +} +.btn-group-lg>.btn { + padding: 10px 16px; + font-size: 19px; + line-height: 1.33; + border-radius: 0; +} +.btn-group>.btn+.dropdown-toggle { + padding-right: 8px; + padding-left: 8px; +} +.btn-group>.btn-lg+.dropdown-toggle { + padding-right: 12px; + padding-left: 12px; +} +.btn-group.open .dropdown-toggle { + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); +} +.btn-group.open .dropdown-toggle.btn-link { + -webkit-box-shadow: none; + box-shadow: none; +} +.btn .caret { + margin-left: 0; +} +.btn-lg .caret { + border-width: 5px 5px 0; + border-bottom-width: 0; +} +.dropup .btn-lg .caret { + border-width: 0 5px 5px; +} +.btn-group-vertical>.btn, .btn-group-vertical>.btn-group, .btn-group-vertical>.btn-group>.btn { + display: block; + float: none; + width: 100%; + max-width: 100%} +.btn-group-vertical>.btn-group:before, .btn-group-vertical>.btn-group:after { + display: table; + content: " "} +.btn-group-vertical>.btn-group:after { + clear: both; +} +.btn-group-vertical>.btn-group:before, .btn-group-vertical>.btn-group:after { + display: table; + content: " "} +.btn-group-vertical>.btn-group:after { + clear: both; +} +.btn-group-vertical>.btn-group:before, .btn-group-vertical>.btn-group:after { + display: table; + content: " "} +.btn-group-vertical>.btn-group:after { + clear: both; +} +.btn-group-vertical>.btn-group:before, .btn-group-vertical>.btn-group:after { + display: table; + content: " "} +.btn-group-vertical>.btn-group:after { + clear: both; +} +.btn-group-vertical>.btn-group:before, .btn-group-vertical>.btn-group:after { + display: table; + content: " "} +.btn-group-vertical>.btn-group:after { + clear: both; +} +.btn-group-vertical>.btn-group>.btn { + float: none; +} +.btn-group-vertical>.btn+.btn, .btn-group-vertical>.btn+.btn-group, .btn-group-vertical>.btn-group+.btn, .btn-group-vertical>.btn-group+.btn-group { + margin-top: -1px; + margin-left: 0; +} +.btn-group-vertical>.btn:not(:first-child):not(:last-child) { + border-radius: 0; +} +.btn-group-vertical>.btn:first-child:not(:last-child) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group-vertical>.btn:last-child:not(:first-child) { + border-top-right-radius: 0; + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} +.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn { + border-radius: 0; +} +.btn-group-vertical>.btn-group:first-child>.btn:last-child, .btn-group-vertical>.btn-group:first-child>.dropdown-toggle { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group-vertical>.btn-group:last-child>.btn:first-child { + border-top-right-radius: 0; + border-top-left-radius: 0; +} +.btn-group-justified { + display: table; + width: 100%; + border-collapse: separate; + table-layout: fixed; +} +.btn-group-justified>.btn, .btn-group-justified>.btn-group { + display: table-cell; + float: none; + width: 1%} +.btn-group-justified>.btn-group .btn { + width: 100%} +[data-toggle="buttons"]>.btn>input[type="radio"], [data-toggle="buttons"]>.btn>input[type="checkbox"] { + display: none; +} +.input-group { + position: relative; + display: table; + border-collapse: separate; +} +.input-group[class*="col-"] { + float: none; + padding-right: 0; + padding-left: 0; +} +.input-group .form-control { + width: 100%; + margin-bottom: 0; +} +.input-group-lg>.form-control, .input-group-lg>.input-group-addon, .input-group-lg>.input-group-btn>.btn { + height: 48px; + padding: 10px 16px; + font-size: 19px; + line-height: 1.33; + border-radius: 0; +} +select.input-group-lg>.form-control, select.input-group-lg>.input-group-addon, select.input-group-lg>.input-group-btn>.btn { + height: 48px; + line-height: 48px; +} +textarea.input-group-lg>.form-control, textarea.input-group-lg>.input-group-addon, textarea.input-group-lg>.input-group-btn>.btn { + height: auto; +} +.input-group-sm>.form-control, .input-group-sm>.input-group-addon, .input-group-sm>.input-group-btn>.btn { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 0; +} +select.input-group-sm>.form-control, select.input-group-sm>.input-group-addon, select.input-group-sm>.input-group-btn>.btn { + height: 30px; + line-height: 30px; +} +textarea.input-group-sm>.form-control, textarea.input-group-sm>.input-group-addon, textarea.input-group-sm>.input-group-btn>.btn { + height: auto; +} +.input-group-addon, .input-group-btn, .input-group .form-control { + display: table-cell; +} +.input-group-addon:not(:first-child):not(:last-child), .input-group-btn:not(:first-child):not(:last-child), .input-group .form-control:not(:first-child):not(:last-child) { + border-radius: 0; +} +.input-group-addon, .input-group-btn { + width: 1%; + white-space: nowrap; + vertical-align: middle; +} +.input-group-addon { + padding: 6px 12px; + font-size: 15px; + font-weight: normal; + line-height: 1; + color: #6f6f6f; + text-align: center; + background-color: #eee; + border: 1px solid #ccc; + border-radius: 0; +} +.input-group-addon.input-sm { + padding: 5px 10px; + font-size: 12px; + border-radius: 0; +} +.input-group-addon.input-lg { + padding: 10px 16px; + font-size: 19px; + border-radius: 0; +} +.input-group-addon input[type="radio"], .input-group-addon input[type="checkbox"] { + margin-top: 0; +} +.input-group .form-control:first-child, .input-group-addon:first-child, .input-group-btn:first-child>.btn, .input-group-btn:first-child>.dropdown-toggle, .input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.input-group-addon:first-child { + border-right: 0; +} +.input-group .form-control:last-child, .input-group-addon:last-child, .input-group-btn:last-child>.btn, .input-group-btn:last-child>.dropdown-toggle, .input-group-btn:first-child>.btn:not(:first-child) { + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} +.input-group-addon:last-child { + border-left: 0; +} +.input-group-btn { + position: relative; + white-space: nowrap; +} +.input-group-btn:first-child>.btn { + margin-right: -1px; +} +.input-group-btn:last-child>.btn { + margin-left: -1px; +} +.input-group-btn>.btn { + position: relative; +} +.input-group-btn>.btn+.btn { + margin-left: -4px; +} +.input-group-btn>.btn:hover, .input-group-btn>.btn:active { + z-index: 2; +} +.nav { + font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + padding-left: 0; + margin-bottom: 0; + list-style: none; +} +.nav:before, .nav:after { + display: table; + content: " "} +.nav:after { + clear: both; +} +.nav:before, .nav:after { + display: table; + content: " "} +.nav:after { + clear: both; +} +.nav:before, .nav:after { + display: table; + content: " "} +.nav:after { + clear: both; +} +.nav:before, .nav:after { + display: table; + content: " "} +.nav:after { + clear: both; +} +.nav:before, .nav:after { + display: table; + content: " "} +.nav:after { + clear: both; +} +.nav>li { + position: relative; + display: block; +} +.nav>li>a { + position: relative; + display: block; + padding: 10px 15px; +} +.nav>li>a:hover, .nav>li>a:focus { + text-decoration: none; + background-color: #eee; +} +.nav>li.disabled>a { + color: #999; +} +.nav>li.disabled>a:hover, .nav>li.disabled>a:focus { + color: #999; + text-decoration: none; + cursor: not-allowed; + background-color: transparent; +} +.nav .open>a, .nav .open>a:hover, .nav .open>a:focus { + background-color: #eee; + border-color: #008cba; +} +.nav .nav-divider { + height: 1px; + margin: 9.5px 0; + overflow: hidden; + background-color: #e5e5e5; +} +.nav>li>a>img { + max-width: none; +} +.nav-tabs { + border-bottom: 1px solid #ddd; +} +.nav-tabs>li { + float: left; + margin-bottom: -1px; +} +.nav-tabs>li>a { + margin-right: 2px; + line-height: 1.428571429; + border: 1px solid transparent; + border-radius: 0; +} +.nav-tabs>li>a:hover { + border-color: #eee #eee #ddd; +} +.nav-tabs>li.active>a, .nav-tabs>li.active>a:hover, .nav-tabs>li.active>a:focus { + color: #6f6f6f; + cursor: default; + background-color: #fff; + border: 1px solid #ddd; + border-bottom-color: transparent; +} +.nav-tabs.nav-justified { + width: 100%; + border-bottom: 0; +} +.nav-tabs.nav-justified>li { + float: none; +} +.nav-tabs.nav-justified>li>a { + margin-bottom: 5px; + text-align: center; +} +.nav-tabs.nav-justified>.dropdown .dropdown-menu { + top: auto; + left: auto; +} +@media(min-width:768px) { + .nav-tabs.nav-justified>li { + display: table-cell; + width: 1%} +.nav-tabs.nav-justified>li>a { + margin-bottom: 0; +} +}.nav-tabs.nav-justified>li>a { + margin-right: 0; + border-radius: 0; +} +.nav-tabs.nav-justified>.active>a, .nav-tabs.nav-justified>.active>a:hover, .nav-tabs.nav-justified>.active>a:focus { + border: 1px solid #ddd; +} +@media(min-width:768px) { + .nav-tabs.nav-justified>li>a { + border-bottom: 1px solid #ddd; + border-radius: 0; +} +.nav-tabs.nav-justified>.active>a, .nav-tabs.nav-justified>.active>a:hover, .nav-tabs.nav-justified>.active>a:focus { + border-bottom-color: #fff; +} +}.nav-pills>li { + float: left; +} +.nav-pills>li>a { + border-radius: 0; +} +.nav-pills>li+li { + margin-left: 2px; +} +.nav-pills>li.active>a, .nav-pills>li.active>a:hover, .nav-pills>li.active>a:focus { + color: #fff; + background-color: #008cba; +} +.nav-stacked>li { + float: none; +} +.nav-stacked>li+li { + margin-top: 2px; + margin-left: 0; +} +.nav-justified { + width: 100%} +.nav-justified>li { + float: none; +} +.nav-justified>li>a { + margin-bottom: 5px; + text-align: center; +} +.nav-justified>.dropdown .dropdown-menu { + top: auto; + left: auto; +} +@media(min-width:768px) { + .nav-justified>li { + display: table-cell; + width: 1%} +.nav-justified>li>a { + margin-bottom: 0; +} +}.nav-tabs-justified { + border-bottom: 0; +} +.nav-tabs-justified>li>a { + margin-right: 0; + border-radius: 0; +} +.nav-tabs-justified>.active>a, .nav-tabs-justified>.active>a:hover, .nav-tabs-justified>.active>a:focus { + border: 1px solid #ddd; +} +@media(min-width:768px) { + .nav-tabs-justified>li>a { + border-bottom: 1px solid #ddd; + border-radius: 0; +} +.nav-tabs-justified>.active>a, .nav-tabs-justified>.active>a:hover, .nav-tabs-justified>.active>a:focus { + border-bottom-color: #fff; +} +}.tab-content>.tab-pane { + display: none; +} +.tab-content>.active { + display: block; +} +.nav-tabs .dropdown-menu { + margin-top: -1px; + border-top-right-radius: 0; + border-top-left-radius: 0; +} +.navbar { + position: relative; + min-height: 45px; + margin-bottom: 21px; + border: 1px solid transparent; +} +.navbar:before, .navbar:after { + display: table; + content: " "} +.navbar:after { + clear: both; +} +.navbar:before, .navbar:after { + display: table; + content: " "} +.navbar:after { + clear: both; +} +.navbar:before, .navbar:after { + display: table; + content: " "} +.navbar:after { + clear: both; +} +.navbar:before, .navbar:after { + display: table; + content: " "} +.navbar:after { + clear: both; +} +.navbar:before, .navbar:after { + display: table; + content: " "} +.navbar:after { + clear: both; +} +@media(min-width:768px) { + .navbar { + border-radius: 0; +} +}.navbar-header:before, .navbar-header:after { + display: table; + content: " "} +.navbar-header:after { + clear: both; +} +.navbar-header:before, .navbar-header:after { + display: table; + content: " "} +.navbar-header:after { + clear: both; +} +.navbar-header:before, .navbar-header:after { + display: table; + content: " "} +.navbar-header:after { + clear: both; +} +.navbar-header:before, .navbar-header:after { + display: table; + content: " "} +.navbar-header:after { + clear: both; +} +.navbar-header:before, .navbar-header:after { + display: table; + content: " "} +.navbar-header:after { + clear: both; +} +@media(min-width:768px) { + .navbar-header { + float: left; +} +}.navbar-collapse { + max-height: 340px; + padding-right: 15px; + padding-left: 15px; + overflow-x: visible; + border-top: 1px solid transparent; + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1); + -webkit-overflow-scrolling: touch; +} +.navbar-collapse:before, .navbar-collapse:after { + display: table; + content: " "} +.navbar-collapse:after { + clear: both; +} +.navbar-collapse:before, .navbar-collapse:after { + display: table; + content: " "} +.navbar-collapse:after { + clear: both; +} +.navbar-collapse:before, .navbar-collapse:after { + display: table; + content: " "} +.navbar-collapse:after { + clear: both; +} +.navbar-collapse:before, .navbar-collapse:after { + display: table; + content: " "} +.navbar-collapse:after { + clear: both; +} +.navbar-collapse:before, .navbar-collapse:after { + display: table; + content: " "} +.navbar-collapse:after { + clear: both; +} +.navbar-collapse.in { + overflow-y: auto; +} +@media(min-width:768px) { + .navbar-collapse { + width: auto; + border-top: 0; + box-shadow: none; +} +.navbar-collapse.collapse { + display: block!important; + height: auto!important; + padding-bottom: 0; + overflow: visible!important; +} +.navbar-collapse.in { + overflow-y: visible; +} +.navbar-fixed-top .navbar-collapse, .navbar-static-top .navbar-collapse, .navbar-fixed-bottom .navbar-collapse { + padding-right: 0; + padding-left: 0; +} +}.container>.navbar-header, .container>.navbar-collapse { + margin-right: -15px; + margin-left: -15px; +} +@media(min-width:768px) { + .container>.navbar-header, .container>.navbar-collapse { + margin-right: 0; + margin-left: 0; +} +}.navbar-static-top { + z-index: 1000; + border-width: 0 0 1px; +} +@media(min-width:768px) { + .navbar-static-top { + border-radius: 0; +} +}.navbar-fixed-top, .navbar-fixed-bottom { + position: fixed; + right: 0; + left: 0; + z-index: 1030; +} +@media(min-width:768px) { + .navbar-fixed-top, .navbar-fixed-bottom { + border-radius: 0; +} +}.navbar-fixed-top { + top: 0; + border-width: 0 0 1px; +} +.navbar-fixed-bottom { + bottom: 0; + margin-bottom: 0; + border-width: 1px 0 0; +} +.navbar-brand { + font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + float: left; + padding: 12px 15px; + font-size: 19px; + line-height: 21px; +} +.navbar-brand:hover, .navbar-brand:focus { + text-decoration: none; +} +@media(min-width:768px) { + .navbar>.container .navbar-brand { + margin-left: -15px; +} +}.navbar-toggle { + position: relative; + float: right; + padding: 9px 10px; + margin-top: 5.5px; + margin-right: 15px; + margin-bottom: 5.5px; + background-color: transparent; + background-image: none; + border: 1px solid transparent; + border-radius: 0; +} +.navbar-toggle .icon-bar { + display: block; + width: 22px; + height: 2px; + border-radius: 1px; +} +.navbar-toggle .icon-bar+.icon-bar { + margin-top: 4px; +} +@media(min-width:768px) { + .navbar-toggle { + display: none; +} +}.navbar-nav { + margin: 6px -15px; +} +.navbar-nav>li>a { + padding-top: 10px; + padding-bottom: 10px; + line-height: 21px; +} +@media(max-width:767px) { + .navbar-nav .open .dropdown-menu { + position: static; + float: none; + width: auto; + margin-top: 0; + background-color: transparent; + border: 0; + box-shadow: none; +} +.navbar-nav .open .dropdown-menu>li>a, .navbar-nav .open .dropdown-menu .dropdown-header { + padding: 5px 15px 5px 25px; +} +.navbar-nav .open .dropdown-menu>li>a { + line-height: 21px; +} +.navbar-nav .open .dropdown-menu>li>a:hover, .navbar-nav .open .dropdown-menu>li>a:focus { + background-image: none; +} +}@media(min-width:768px) { + .navbar-nav { + float: left; + margin: 0; +} +.navbar-nav>li { + float: left; +} +.navbar-nav>li>a { + padding-top: 12px; + padding-bottom: 12px; +} +.navbar-nav.navbar-right:last-child { + margin-right: -15px; +} +}@media(min-width:768px) { + .navbar-left { + float: left!important; +} +.navbar-right { + float: right!important; +} +}.navbar-form { + padding: 10px 15px; + margin-top: 5px; + margin-right: -15px; + margin-bottom: 5px; + margin-left: -15px; + border-top: 1px solid transparent; + border-bottom: 1px solid transparent; + -webkit-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); +} +@media(min-width:768px) { + .navbar-form .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; +} +.navbar-form .form-control { + display: inline-block; +} +.navbar-form select.form-control { + width: auto; +} +.navbar-form .radio, .navbar-form .checkbox { + display: inline-block; + padding-left: 0; + margin-top: 0; + margin-bottom: 0; +} +.navbar-form .radio input[type="radio"], .navbar-form .checkbox input[type="checkbox"] { + float: none; + margin-left: 0; +} +}@media(max-width:767px) { + .navbar-form .form-group { + margin-bottom: 5px; +} +}@media(min-width:768px) { + .navbar-form { + width: auto; + padding-top: 0; + padding-bottom: 0; + margin-right: 0; + margin-left: 0; + border: 0; + -webkit-box-shadow: none; + box-shadow: none; +} +.navbar-form.navbar-right:last-child { + margin-right: -15px; +} +}.navbar-nav>li>.dropdown-menu { + margin-top: 0; + border-top-right-radius: 0; + border-top-left-radius: 0; +} +.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.navbar-nav.pull-right>li>.dropdown-menu, .navbar-nav>li>.dropdown-menu.pull-right { + right: 0; + left: auto; +} +.navbar-btn { + margin-top: 5px; + margin-bottom: 5px; +} +.navbar-btn.btn-sm { + margin-top: 7.5px; + margin-bottom: 7.5px; +} +.navbar-btn.btn-xs { + margin-top: 11.5px; + margin-bottom: 11.5px; +} +.navbar-text { + margin-top: 12px; + margin-bottom: 12px; +} +@media(min-width:768px) { + .navbar-text { + float: left; + margin-right: 15px; + margin-left: 15px; +} +.navbar-text.navbar-right:last-child { + margin-right: 0; +} +}.navbar-default { + background-color: #333; + border-color: #222; +} +.navbar-default .navbar-brand { + color: #fff; +} +.navbar-default .navbar-brand:hover, .navbar-default .navbar-brand:focus { + color: #fff; + background-color: transparent; +} +.navbar-default .navbar-text { + color: #fff; +} +.navbar-default .navbar-nav>li>a { + color: #fff; +} +.navbar-default .navbar-nav>li>a:hover, .navbar-default .navbar-nav>li>a:focus { + color: #fff; + background-color: #272727; +} +.navbar-default .navbar-nav>.active>a, .navbar-default .navbar-nav>.active>a:hover, .navbar-default .navbar-nav>.active>a:focus { + color: #fff; + background-color: #272727; +} +.navbar-default .navbar-nav>.disabled>a, .navbar-default .navbar-nav>.disabled>a:hover, .navbar-default .navbar-nav>.disabled>a:focus { + color: #ccc; + background-color: transparent; +} +.navbar-default .navbar-toggle { + border-color: transparent; +} +.navbar-default .navbar-toggle:hover, .navbar-default .navbar-toggle:focus { + background-color: transparent; +} +.navbar-default .navbar-toggle .icon-bar { + background-color: #fff; +} +.navbar-default .navbar-collapse, .navbar-default .navbar-form { + border-color: #222; +} +.navbar-default .navbar-nav>.open>a, .navbar-default .navbar-nav>.open>a:hover, .navbar-default .navbar-nav>.open>a:focus { + color: #fff; + background-color: #272727; +} +@media(max-width:767px) { + .navbar-default .navbar-nav .open .dropdown-menu>li>a { + color: #fff; +} +.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover, .navbar-default .navbar-nav .open .dropdown-menu>li>a:focus { + color: #fff; + background-color: #272727; +} +.navbar-default .navbar-nav .open .dropdown-menu>.active>a, .navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover, .navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus { + color: #fff; + background-color: #272727; +} +.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a, .navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover, .navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus { + color: #ccc; + background-color: transparent; +} +}.navbar-default .navbar-link { + color: #fff; +} +.navbar-default .navbar-link:hover { + color: #fff; +} +.navbar-inverse { + background-color: #008cba; + border-color: #006687; +} +.navbar-inverse .navbar-brand { + color: #fff; +} +.navbar-inverse .navbar-brand:hover, .navbar-inverse .navbar-brand:focus { + color: #fff; + background-color: transparent; +} +.navbar-inverse .navbar-text { + color: #fff; +} +.navbar-inverse .navbar-nav>li>a { + color: #fff; +} +.navbar-inverse .navbar-nav>li>a:hover, .navbar-inverse .navbar-nav>li>a:focus { + color: #fff; + background-color: #006687; +} +.navbar-inverse .navbar-nav>.active>a, .navbar-inverse .navbar-nav>.active>a:hover, .navbar-inverse .navbar-nav>.active>a:focus { + color: #fff; + background-color: #006687; +} +.navbar-inverse .navbar-nav>.disabled>a, .navbar-inverse .navbar-nav>.disabled>a:hover, .navbar-inverse .navbar-nav>.disabled>a:focus { + color: #444; + background-color: transparent; +} +.navbar-inverse .navbar-toggle { + border-color: transparent; +} +.navbar-inverse .navbar-toggle:hover, .navbar-inverse .navbar-toggle:focus { + background-color: transparent; +} +.navbar-inverse .navbar-toggle .icon-bar { + background-color: #fff; +} +.navbar-inverse .navbar-collapse, .navbar-inverse .navbar-form { + border-color: #007196; +} +.navbar-inverse .navbar-nav>.open>a, .navbar-inverse .navbar-nav>.open>a:hover, .navbar-inverse .navbar-nav>.open>a:focus { + color: #fff; + background-color: #006687; +} +@media(max-width:767px) { + .navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header { + border-color: #006687; +} +.navbar-inverse .navbar-nav .open .dropdown-menu .divider { + background-color: #006687; +} +.navbar-inverse .navbar-nav .open .dropdown-menu>li>a { + color: #fff; +} +.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover, .navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus { + color: #fff; + background-color: #006687; +} +.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a, .navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover, .navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus { + color: #fff; + background-color: #006687; +} +.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a, .navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover, .navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus { + color: #444; + background-color: transparent; +} +}.navbar-inverse .navbar-link { + color: #fff; +} +.navbar-inverse .navbar-link:hover { + color: #fff; +} +.breadcrumb { + padding: 8px 15px; + margin-bottom: 21px; + list-style: none; + background-color: #f5f5f5; + border-radius: 0; +} +.breadcrumb>li { + display: inline-block; +} +.breadcrumb>li+li:before { + padding: 0 5px; + color: #999; + content: "/\00a0"} +.breadcrumb>.active { + color: #333; +} +.pagination { + display: inline-block; + padding-left: 0; + margin: 21px 0; + border-radius: 0; +} +.pagination>li { + display: inline; +} +.pagination>li>a, .pagination>li>span { + position: relative; + float: left; + padding: 6px 12px; + margin-left: -1px; + line-height: 1.428571429; + text-decoration: none; + background-color: transparent; + border: 1px solid transparent; +} +.pagination>li:first-child>a, .pagination>li:first-child>span { + margin-left: 0; + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} +.pagination>li:last-child>a, .pagination>li:last-child>span { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.pagination>li>a:hover, .pagination>li>span:hover, .pagination>li>a:focus, .pagination>li>span:focus { + background-color: #eee; +} +.pagination>.active>a, .pagination>.active>span, .pagination>.active>a:hover, .pagination>.active>span:hover, .pagination>.active>a:focus, .pagination>.active>span:focus { + z-index: 2; + color: #fff; + cursor: default; + background-color: #008cba; + border-color: #008cba; +} +.pagination>.disabled>span, .pagination>.disabled>span:hover, .pagination>.disabled>span:focus, .pagination>.disabled>a, .pagination>.disabled>a:hover, .pagination>.disabled>a:focus { + color: #999; + cursor: not-allowed; + background-color: transparent; + border-color: transparent; +} +.pagination-lg>li>a, .pagination-lg>li>span { + padding: 10px 16px; + font-size: 19px; +} +.pagination-lg>li:first-child>a, .pagination-lg>li:first-child>span { + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} +.pagination-lg>li:last-child>a, .pagination-lg>li:last-child>span { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.pagination-sm>li>a, .pagination-sm>li>span { + padding: 5px 10px; + font-size: 12px; +} +.pagination-sm>li:first-child>a, .pagination-sm>li:first-child>span { + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} +.pagination-sm>li:last-child>a, .pagination-sm>li:last-child>span { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.pager { + padding-left: 0; + margin: 21px 0; + text-align: center; + list-style: none; +} +.pager:before, .pager:after { + display: table; + content: " "} +.pager:after { + clear: both; +} +.pager:before, .pager:after { + display: table; + content: " "} +.pager:after { + clear: both; +} +.pager:before, .pager:after { + display: table; + content: " "} +.pager:after { + clear: both; +} +.pager:before, .pager:after { + display: table; + content: " "} +.pager:after { + clear: both; +} +.pager:before, .pager:after { + display: table; + content: " "} +.pager:after { + clear: both; +} +.pager li { + display: inline; +} +.pager li>a, .pager li>span { + display: inline-block; + padding: 5px 14px; + background-color: transparent; + border: 1px solid transparent; + border-radius: 3px; +} +.pager li>a:hover, .pager li>a:focus { + text-decoration: none; + background-color: #eee; +} +.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: not-allowed; + background-color: transparent; +} +.label { + display: inline; + padding: .2em .6em .3em; + font-size: 75%; + font-weight: bold; + line-height: 1; + color: #fff; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: .25em; +} +.label[href]:hover, .label[href]:focus { + color: #fff; + text-decoration: none; + cursor: pointer; +} +.label:empty { + display: none; +} +.btn .label { + position: relative; + top: -1px; +} +.label-default { + background-color: #999; +} +.label-default[href]:hover, .label-default[href]:focus { + background-color: #808080; +} +.label-primary { + background-color: #008cba; +} +.label-primary[href]:hover, .label-primary[href]:focus { + background-color: #006687; +} +.label-success { + background-color: #43ac6a; +} +.label-success[href]:hover, .label-success[href]:focus { + background-color: #358753; +} +.label-info { + background-color: #5bc0de; +} +.label-info[href]:hover, .label-info[href]:focus { + background-color: #31b0d5; +} +.label-warning { + background-color: #e99002; +} +.label-warning[href]:hover, .label-warning[href]:focus { + background-color: #b67102; +} +.label-danger { + background-color: #f04124; +} +.label-danger[href]:hover, .label-danger[href]:focus { + background-color: #d32a0e; +} +.badge { + display: inline-block; + min-width: 10px; + padding: 3px 7px; + font-size: 12px; + font-weight: bold; + line-height: 1; + color: #777; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + background-color: #e7e7e7; + border-radius: 10px; +} +.badge:empty { + display: none; +} +.btn .badge { + position: relative; + top: -1px; +} +a.badge:hover, a.badge:focus { + color: #fff; + text-decoration: none; + cursor: pointer; +} +a.list-group-item.active>.badge, .nav-pills>.active>a>.badge { + color: #008cba; + background-color: #fff; +} +.nav-pills>li>a>.badge { + margin-left: 3px; +} +.jumbotron { + padding: 30px; + margin-bottom: 30px; + font-size: 23px; + font-weight: 200; + line-height: 2.1428571435; + color: inherit; + background-color: #fafafa; +} +.jumbotron h1, .jumbotron .h1 { + line-height: 1; + color: inherit; +} +.jumbotron p { + line-height: 1.4; +} +.container .jumbotron { + border-radius: 0; +} +.jumbotron .container { + max-width: 100%} +@media screen and (min-width:768px) { + .jumbotron { + padding-top: 48px; + padding-bottom: 48px; +} +.container .jumbotron { + padding-right: 60px; + padding-left: 60px; +} +.jumbotron h1, .jumbotron .h1 { + font-size: 67.5px; +} +}.thumbnail { + display: block; + padding: 4px; + margin-bottom: 21px; + line-height: 1.428571429; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 0; + -webkit-transition: all .2s ease-in-out; + transition: all .2s ease-in-out; +} +.thumbnail>img, .thumbnail a>img { + display: block; + height: auto; + max-width: 100%; + margin-right: auto; + margin-left: auto; +} +a.thumbnail:hover, a.thumbnail:focus, a.thumbnail.active { + border-color: #008cba; +} +.thumbnail .caption { + padding: 9px; + color: #222; +} +.alert { + position: relative; + padding: 0.75rem 1.25rem; + margin-bottom: 1rem; + border: 1px solid transparent; + border-radius: 0.25rem; + } + + .alert-heading { + color: inherit; + } + + .alert-link { + font-weight: 700; + } + + .alert-dismissible { + padding-right: 4rem; + } + + .alert-dismissible .close { + position: absolute; + top: 0; + right: 0; + padding: 0.75rem 1.25rem; + color: inherit; + } + + .alert-primary { + color: #004085; + background-color: #cce5ff; + border-color: #b8daff; + } + + .alert-primary hr { + border-top-color: #9fcdff; + } + + .alert-primary .alert-link { + color: #002752; + } + + .alert-secondary { + color: #383d41; + background-color: #e2e3e5; + border-color: #d6d8db; + } + + .alert-secondary hr { + border-top-color: #c8cbcf; + } + + .alert-secondary .alert-link { + color: #202326; + } + + .alert-success { + color: #155724; + background-color: #d4edda; + border-color: #c3e6cb; + } + + .alert-success hr { + border-top-color: #b1dfbb; + } + + .alert-success .alert-link { + color: #0b2e13; + } + + .alert-info { + color: #0c5460; + background-color: #d1ecf1; + border-color: #bee5eb; + } + + .alert-info hr { + border-top-color: #abdde5; + } + + .alert-info .alert-link { + color: #062c33; + } + + .alert-warning { + color: #856404; + background-color: #fff3cd; + border-color: #ffeeba; + } + + .alert-warning hr { + border-top-color: #ffe8a1; + } + + .alert-warning .alert-link { + color: #533f03; + } + + .alert-danger { + color: #721c24; + background-color: #f8d7da; + border-color: #f5c6cb; + } + + .alert-danger hr { + border-top-color: #f1b0b7; + } + + .alert-danger .alert-link { + color: #491217; + } + + .alert-light { + color: #818182; + background-color: #fefefe; + border-color: #fdfdfe; + } + + .alert-light hr { + border-top-color: #ececf6; + } + + .alert-light .alert-link { + color: #686868; + } + + .alert-dark { + color: #1b1e21; + background-color: #d6d8d9; + border-color: #c6c8ca; + } + + .alert-dark hr { + border-top-color: #b9bbbe; + } + + .alert-dark .alert-link { + color: #040505; + } + + +@-webkit-keyframes progress-bar-stripes { + from { + background-position: 40px 0; +} +to { + background-position: 0 0; +} +}@keyframes progress-bar-stripes { + from { + background-position: 40px 0; +} +to { + background-position: 0 0; +} +}.progress { + height: 21px; + margin-bottom: 21px; + overflow: hidden; + background-color: #f5f5f5; + border-radius: 0; + -webkit-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; + line-height: 21px; + color: #fff; + text-align: center; + background-color: #008cba; + -webkit-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-transition: width .6s ease; + transition: width .6s ease; +} +.progress-striped .progress-bar { + 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: 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-size: 40px 40px; +} +.progress.active .progress-bar { + -webkit-animation: progress-bar-stripes 2s linear infinite; + animation: progress-bar-stripes 2s linear infinite; +} +.progress-bar-success { + background-color: #43ac6a; +} +.progress-striped .progress-bar-success { + 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: 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-bar-info { + background-color: #5bc0de; +} +.progress-striped .progress-bar-info { + 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: 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-bar-warning { + background-color: #e99002; +} +.progress-striped .progress-bar-warning { + 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: 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-bar-danger { + background-color: #f04124; +} +.progress-striped .progress-bar-danger { + 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: 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); +} +.media, .media-body { + overflow: hidden; + 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 { + padding-left: 0; + list-style: none; +} +.list-group { + padding-left: 0; + margin-bottom: 20px; +} +.list-group-item { + position: relative; + display: block; + padding: 10px 15px; + margin-bottom: -1px; + background-color: #fff; + border: 1px solid #ddd; +} +.list-group-item:first-child { + border-top-right-radius: 0; + border-top-left-radius: 0; +} +.list-group-item:last-child { + margin-bottom: 0; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.list-group-item>.badge { + float: right; +} +.list-group-item>.badge+.badge { + margin-right: 5px; +} +a.list-group-item { + color: #555; +} +a.list-group-item .list-group-item-heading { + color: #333; +} +a.list-group-item:hover, a.list-group-item:focus { + text-decoration: none; + background-color: #f5f5f5; +} +a.list-group-item.active, a.list-group-item.active:hover, a.list-group-item.active:focus { + z-index: 2; + color: #fff; + background-color: #008cba; + border-color: #008cba; +} +a.list-group-item.active .list-group-item-heading, a.list-group-item.active:hover .list-group-item-heading, a.list-group-item.active:focus .list-group-item-heading { + color: inherit; +} +a.list-group-item.active .list-group-item-text, a.list-group-item.active:hover .list-group-item-text, a.list-group-item.active:focus .list-group-item-text { + color: #87e1ff; +} +.list-group-item-heading { + margin-top: 0; + margin-bottom: 5px; +} +.list-group-item-text { + margin-bottom: 0; + line-height: 1.3; +} +.panel { + margin-bottom: 21px; + background-color: #fff; + border: 1px solid transparent; + border-radius: 0; + -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); +} +.panel-body { + padding: 15px; +} +.panel-body:before, .panel-body:after { + display: table; + content: " "} +.panel-body:after { + clear: both; +} +.panel-body:before, .panel-body:after { + display: table; + content: " "} +.panel-body:after { + clear: both; +} +.panel-body:before, .panel-body:after { + display: table; + content: " "} +.panel-body:after { + clear: both; +} +.panel-body:before, .panel-body:after { + display: table; + content: " "} +.panel-body:after { + clear: both; +} +.panel-body:before, .panel-body:after { + display: table; + content: " "} +.panel-body:after { + clear: both; +} +.panel>.list-group { + margin-bottom: 0; +} +.panel>.list-group .list-group-item { + border-width: 1px 0; +} +.panel>.list-group .list-group-item:first-child { + border-top-right-radius: 0; + border-top-left-radius: 0; +} +.panel>.list-group .list-group-item:last-child { + border-bottom: 0; +} +.panel-heading+.list-group .list-group-item:first-child { + border-top-width: 0; +} +.panel>.table, .panel>.table-responsive>.table { + margin-bottom: 0; +} +.panel>.panel-body+.table, .panel>.panel-body+.table-responsive { + border-top: 1px solid #ddd; +} +.panel>.table>tbody:first-child th, .panel>.table>tbody:first-child td { + border-top: 0; +} +.panel>.table-bordered, .panel>.table-responsive>.table-bordered { + border: 0; +} +.panel>.table-bordered>thead>tr>th:first-child, .panel>.table-responsive>.table-bordered>thead>tr>th:first-child, .panel>.table-bordered>tbody>tr>th:first-child, .panel>.table-responsive>.table-bordered>tbody>tr>th:first-child, .panel>.table-bordered>tfoot>tr>th:first-child, .panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child, .panel>.table-bordered>thead>tr>td:first-child, .panel>.table-responsive>.table-bordered>thead>tr>td:first-child, .panel>.table-bordered>tbody>tr>td:first-child, .panel>.table-responsive>.table-bordered>tbody>tr>td:first-child, .panel>.table-bordered>tfoot>tr>td:first-child, .panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child { + border-left: 0; +} +.panel>.table-bordered>thead>tr>th:last-child, .panel>.table-responsive>.table-bordered>thead>tr>th:last-child, .panel>.table-bordered>tbody>tr>th:last-child, .panel>.table-responsive>.table-bordered>tbody>tr>th:last-child, .panel>.table-bordered>tfoot>tr>th:last-child, .panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child, .panel>.table-bordered>thead>tr>td:last-child, .panel>.table-responsive>.table-bordered>thead>tr>td:last-child, .panel>.table-bordered>tbody>tr>td:last-child, .panel>.table-responsive>.table-bordered>tbody>tr>td:last-child, .panel>.table-bordered>tfoot>tr>td:last-child, .panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child { + border-right: 0; +} +.panel>.table-bordered>thead>tr:last-child>th, .panel>.table-responsive>.table-bordered>thead>tr:last-child>th, .panel>.table-bordered>tbody>tr:last-child>th, .panel>.table-responsive>.table-bordered>tbody>tr:last-child>th, .panel>.table-bordered>tfoot>tr:last-child>th, .panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th, .panel>.table-bordered>thead>tr:last-child>td, .panel>.table-responsive>.table-bordered>thead>tr:last-child>td, .panel>.table-bordered>tbody>tr:last-child>td, .panel>.table-responsive>.table-bordered>tbody>tr:last-child>td, .panel>.table-bordered>tfoot>tr:last-child>td, .panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td { + border-bottom: 0; +} +.panel>.table-responsive { + margin-bottom: 0; + border: 0; +} +.panel-heading { + padding: 10px 15px; + border-bottom: 1px solid transparent; + border-top-right-radius: -1; + border-top-left-radius: -1; +} +.panel-heading>.dropdown .dropdown-toggle { + color: inherit; +} +.panel-title { + margin-top: 0; + margin-bottom: 0; + font-size: 17px; + color: inherit; +} +.panel-title>a { + color: inherit; +} +.panel-footer { + padding: 10px 15px; + background-color: #f5f5f5; + border-top: 1px solid #ddd; + border-bottom-right-radius: -1; + border-bottom-left-radius: -1; +} +.panel-group .panel { + margin-bottom: 0; + overflow: hidden; + border-radius: 0; +} +.panel-group .panel+.panel { + margin-top: 5px; +} +.panel-group .panel-heading { + border-bottom: 0; +} +.panel-group .panel-heading+.panel-collapse .panel-body { + border-top: 1px solid #ddd; +} +.panel-group .panel-footer { + border-top: 0; +} +.panel-group .panel-footer+.panel-collapse .panel-body { + border-bottom: 1px solid #ddd; +} +.panel-default { + border-color: #ddd; +} +.panel-default>.panel-heading { + color: #333; + background-color: #f5f5f5; + border-color: #ddd; +} +.panel-default>.panel-heading+.panel-collapse .panel-body { + border-top-color: #ddd; +} +.panel-default>.panel-footer+.panel-collapse .panel-body { + border-bottom-color: #ddd; +} +.panel-primary { + border-color: #008cba; +} +.panel-primary>.panel-heading { + color: #fff; + background-color: #008cba; + border-color: #008cba; +} +.panel-primary>.panel-heading+.panel-collapse .panel-body { + border-top-color: #008cba; +} +.panel-primary>.panel-footer+.panel-collapse .panel-body { + border-bottom-color: #008cba; +} +.panel-success { + border-color: #3c9a5f; +} +.panel-success>.panel-heading { + color: #43ac6a; + background-color: #dff0d8; + border-color: #3c9a5f; +} +.panel-success>.panel-heading+.panel-collapse .panel-body { + border-top-color: #3c9a5f; +} +.panel-success>.panel-footer+.panel-collapse .panel-body { + border-bottom-color: #3c9a5f; +} +.panel-warning { + border-color: #d08002; +} +.panel-warning>.panel-heading { + color: #e99002; + background-color: #fcf8e3; + border-color: #d08002; +} +.panel-warning>.panel-heading+.panel-collapse .panel-body { + border-top-color: #d08002; +} +.panel-warning>.panel-footer+.panel-collapse .panel-body { + border-bottom-color: #d08002; +} +.panel-danger { + border-color: #ea2f10; +} +.panel-danger>.panel-heading { + color: #f04124; + background-color: #f2dede; + border-color: #ea2f10; +} +.panel-danger>.panel-heading+.panel-collapse .panel-body { + border-top-color: #ea2f10; +} +.panel-danger>.panel-footer+.panel-collapse .panel-body { + border-bottom-color: #ea2f10; +} +.panel-info { + border-color: #3db5d8; +} +.panel-info>.panel-heading { + color: #5bc0de; + background-color: #d9edf7; + border-color: #3db5d8; +} +.panel-info>.panel-heading+.panel-collapse .panel-body { + border-top-color: #3db5d8; +} +.panel-info>.panel-footer+.panel-collapse .panel-body { + border-bottom-color: #3db5d8; +} +.well { + min-height: 20px; + padding: 19px; + margin-bottom: 20px; + background-color: #fafafa; + border: 1px solid #e8e8e8; + border-radius: 0; + -webkit-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-lg { + padding: 24px; + border-radius: 0; +} +.well-sm { + padding: 9px; + border-radius: 0; +} +.close { + float: right; + font-size: 22.5px; + font-weight: bold; + line-height: 1; + 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: .5; + filter: alpha(opacity=50); +} +button.close { + padding: 0; + cursor: pointer; + background: transparent; + border: 0; + -webkit-appearance: none; +} +.modal-open { + overflow: hidden; +} +.modal { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + display: none; + overflow: auto; + overflow-y: scroll; +} +.modal.fade .modal-dialog { + -webkit-transform: translate(0, -25%); + -ms-transform: translate(0, -25%); + transform: translate(0, -25%); + -webkit-transition: -webkit-transform .3s ease-out; + -moz-transition: -moz-transform .3s ease-out; + -o-transition: -o-transform .3s ease-out; + transition: transform .3s ease-out; +} +.modal.in .modal-dialog { + -webkit-transform: translate(0, 0); + -ms-transform: translate(0, 0); + transform: translate(0, 0); +} +.modal-dialog { + position: relative; + z-index: 1050; + width: auto; + margin: 10px; +} +.modal-content { + position: relative; + background-color: #fff; + border: 1px solid #999; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 0; + outline: 0; + -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); + box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); + background-clip: padding-box; +} +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1030; + background-color: #000; +} +.modal-backdrop.fade { + opacity: 0; + filter: alpha(opacity=0); +} +.modal-backdrop.in { + opacity: .5; + filter: alpha(opacity=50); +} +.modal-header { + min-height: 16.428571429px; + padding: 15px; + border-bottom: 1px solid #e5e5e5; +} +.modal-header .close { + margin-top: -2px; +} +.modal-title { + margin: 0; + line-height: 1.428571429; +} +.modal-body { + position: relative; + padding: 20px; +} +.modal-footer { + padding: 19px 20px 20px; + margin-top: 15px; + text-align: right; + border-top: 1px solid #e5e5e5; +} +.modal-footer:before, .modal-footer:after { + display: table; + content: " "} +.modal-footer:after { + clear: both; +} +.modal-footer:before, .modal-footer:after { + display: table; + content: " "} +.modal-footer:after { + clear: both; +} +.modal-footer:before, .modal-footer:after { + display: table; + content: " "} +.modal-footer:after { + clear: both; +} +.modal-footer:before, .modal-footer:after { + display: table; + content: " "} +.modal-footer:after { + clear: both; +} +.modal-footer:before, .modal-footer:after { + display: table; + 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; +} +@media screen and (min-width:768px) { + .modal-dialog { + width: 600px; + margin: 30px auto; +} +.modal-content { + -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5); + box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5); +} +}.tooltip { + position: absolute; + z-index: 1030; + display: block; + font-size: 12px; + line-height: 1.4; + opacity: 0; + filter: alpha(opacity=0); + visibility: visible; +} +.tooltip.in { + opacity: .9; + filter: alpha(opacity=90); +} +.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: 3px 8px; + color: #fff; + text-align: center; + text-decoration: none; + background-color: #333; + border-radius: 0; +} +.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: #333; + border-width: 5px 5px 0; +} +.tooltip.top-left .tooltip-arrow { + bottom: 0; + left: 5px; + border-top-color: #333; + border-width: 5px 5px 0; +} +.tooltip.top-right .tooltip-arrow { + right: 5px; + bottom: 0; + border-top-color: #333; + border-width: 5px 5px 0; +} +.tooltip.right .tooltip-arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-right-color: #333; + border-width: 5px 5px 5px 0; +} +.tooltip.left .tooltip-arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-left-color: #333; + border-width: 5px 0 5px 5px; +} +.tooltip.bottom .tooltip-arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-bottom-color: #333; + border-width: 0 5px 5px; +} +.tooltip.bottom-left .tooltip-arrow { + top: 0; + left: 5px; + border-bottom-color: #333; + border-width: 0 5px 5px; +} +.tooltip.bottom-right .tooltip-arrow { + top: 0; + right: 5px; + border-bottom-color: #333; + 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: #333; + border: 1px solid #333; + border: 1px solid transparent; + border-radius: 0; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + 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: 15px; + font-weight: normal; + line-height: 18px; + background-color: #333; + border-bottom: 1px solid #262626; + border-radius: 5px 5px 0 0; +} +.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: #333; + border-bottom-width: 0; + content: " "} +.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: #333; + border-left-width: 0; + content: " "} +.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: #333; + border-top-width: 0; + content: " "} +.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: #333; + border-right-width: 0; + content: " "} +.carousel { + position: relative; +} +.carousel-inner { + position: relative; + width: 100%; + overflow: hidden; +} +.carousel-inner>.item { + position: relative; + display: none; + -webkit-transition: .6s ease-in-out left; + transition: .6s ease-in-out left; +} +.carousel-inner>.item>img, .carousel-inner>.item>a>img { + display: block; + height: auto; + max-width: 100%; + 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: 0; + bottom: 0; + left: 0; + width: 15%; + font-size: 20px; + color: #fff; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); + opacity: .5; + filter: alpha(opacity=50); +} +.carousel-control.left { + background-image: -webkit-linear-gradient(left, color-stop(rgba(0, 0, 0, 0.5) 0), color-stop(rgba(0, 0, 0, 0.0001) 100%)); + background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0, rgba(0, 0, 0, 0.0001) 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1); +} +.carousel-control.right { + right: 0; + left: auto; + background-image: -webkit-linear-gradient(left, color-stop(rgba(0, 0, 0, 0.0001) 0), color-stop(rgba(0, 0, 0, 0.5) 100%)); + background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0, rgba(0, 0, 0, 0.5) 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1); +} +.carousel-control:hover, .carousel-control:focus { + color: #fff; + text-decoration: none; + outline: 0; + opacity: .9; + filter: alpha(opacity=90); +} +.carousel-control .icon-prev, .carousel-control .icon-next, .carousel-control .glyphicon-chevron-left, .carousel-control .glyphicon-chevron-right { + position: absolute; + top: 50%; + z-index: 5; + display: inline-block; +} +.carousel-control .icon-prev, .carousel-control .glyphicon-chevron-left { + left: 50%} +.carousel-control .icon-next, .carousel-control .glyphicon-chevron-right { + right: 50%} +.carousel-control .icon-prev, .carousel-control .icon-next { + width: 20px; + height: 20px; + margin-top: -10px; + margin-left: -10px; + font-family: serif; +} +.carousel-control .icon-prev:before { + content: '\2039'} +.carousel-control .icon-next:before { + content: '\203a'} +.carousel-indicators { + position: absolute; + bottom: 10px; + left: 50%; + z-index: 15; + width: 60%; + padding-left: 0; + margin-left: -30%; + text-align: center; + list-style: none; +} +.carousel-indicators li { + display: inline-block; + width: 10px; + height: 10px; + margin: 1px; + text-indent: -999px; + cursor: pointer; + background-color: #000 \9; + background-color: rgba(0, 0, 0, 0); + border: 1px solid #fff; + border-radius: 10px; +} +.carousel-indicators .active { + width: 12px; + height: 12px; + margin: 0; + background-color: #fff; +} +.carousel-caption { + position: absolute; + right: 15%; + bottom: 20px; + left: 15%; + z-index: 10; + padding-top: 20px; + padding-bottom: 20px; + color: #fff; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); +} +.carousel-caption .btn { + text-shadow: none; +} +@media screen and (min-width:768px) { + .carousel-control .glyphicons-chevron-left, .carousel-control .glyphicons-chevron-right, .carousel-control .icon-prev, .carousel-control .icon-next { + width: 30px; + height: 30px; + margin-top: -15px; + margin-left: -15px; + font-size: 30px; +} +.carousel-caption { + right: 20%; + left: 20%; + padding-bottom: 30px; +} +.carousel-indicators { + bottom: 20px; +} +}.clearfix:before, .clearfix:after { + display: table; + content: " "} +.clearfix:after { + clear: both; +} +.clearfix:before, .clearfix:after { + display: table; + content: " "} +.clearfix:after { + clear: both; +} +.center-block { + display: block; + margin-right: auto; + margin-left: auto; +} +.pull-right { + float: right!important; +} +.pull-left { + float: left!important; +} +.hide { + display: none!important; +} +.show { + display: block!important; +} +.invisible { + visibility: hidden; +} +.text-hide { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} +.hidden { + display: none!important; + visibility: hidden!important; +} +.affix { + position: fixed; +} +@-ms-viewport { + width: device-width; +} +.visible-xs, tr.visible-xs, th.visible-xs, td.visible-xs { + display: none!important; +} +@media(max-width:767px) { + .visible-xs { + display: block!important; +} +table.visible-xs { + display: table; +} +tr.visible-xs { + display: table-row!important; +} +th.visible-xs, td.visible-xs { + display: table-cell!important; +} +}@media(min-width:768px) and (max-width:991px) { + .visible-xs.visible-sm { + display: block!important; +} +table.visible-xs.visible-sm { + display: table; +} +tr.visible-xs.visible-sm { + display: table-row!important; +} +th.visible-xs.visible-sm, td.visible-xs.visible-sm { + display: table-cell!important; +} +}@media(min-width:992px) and (max-width:1199px) { + .visible-xs.visible-md { + display: block!important; +} +table.visible-xs.visible-md { + display: table; +} +tr.visible-xs.visible-md { + display: table-row!important; +} +th.visible-xs.visible-md, td.visible-xs.visible-md { + display: table-cell!important; +} +}@media(min-width:1200px) { + .visible-xs.visible-lg { + display: block!important; +} +table.visible-xs.visible-lg { + display: table; +} +tr.visible-xs.visible-lg { + display: table-row!important; +} +th.visible-xs.visible-lg, td.visible-xs.visible-lg { + display: table-cell!important; +} +}.visible-sm, tr.visible-sm, th.visible-sm, td.visible-sm { + display: none!important; +} +@media(max-width:767px) { + .visible-sm.visible-xs { + display: block!important; +} +table.visible-sm.visible-xs { + display: table; +} +tr.visible-sm.visible-xs { + display: table-row!important; +} +th.visible-sm.visible-xs, td.visible-sm.visible-xs { + display: table-cell!important; +} +}@media(min-width:768px) and (max-width:991px) { + .visible-sm { + display: block!important; +} +table.visible-sm { + display: table; +} +tr.visible-sm { + display: table-row!important; +} +th.visible-sm, td.visible-sm { + display: table-cell!important; +} +}@media(min-width:992px) and (max-width:1199px) { + .visible-sm.visible-md { + display: block!important; +} +table.visible-sm.visible-md { + display: table; +} +tr.visible-sm.visible-md { + display: table-row!important; +} +th.visible-sm.visible-md, td.visible-sm.visible-md { + display: table-cell!important; +} +}@media(min-width:1200px) { + .visible-sm.visible-lg { + display: block!important; +} +table.visible-sm.visible-lg { + display: table; +} +tr.visible-sm.visible-lg { + display: table-row!important; +} +th.visible-sm.visible-lg, td.visible-sm.visible-lg { + display: table-cell!important; +} +}.visible-md, tr.visible-md, th.visible-md, td.visible-md { + display: none!important; +} +@media(max-width:767px) { + .visible-md.visible-xs { + display: block!important; +} +table.visible-md.visible-xs { + display: table; +} +tr.visible-md.visible-xs { + display: table-row!important; +} +th.visible-md.visible-xs, td.visible-md.visible-xs { + display: table-cell!important; +} +}@media(min-width:768px) and (max-width:991px) { + .visible-md.visible-sm { + display: block!important; +} +table.visible-md.visible-sm { + display: table; +} +tr.visible-md.visible-sm { + display: table-row!important; +} +th.visible-md.visible-sm, td.visible-md.visible-sm { + display: table-cell!important; +} +}@media(min-width:992px) and (max-width:1199px) { + .visible-md { + display: block!important; +} +table.visible-md { + display: table; +} +tr.visible-md { + display: table-row!important; +} +th.visible-md, td.visible-md { + display: table-cell!important; +} +}@media(min-width:1200px) { + .visible-md.visible-lg { + display: block!important; +} +table.visible-md.visible-lg { + display: table; +} +tr.visible-md.visible-lg { + display: table-row!important; +} +th.visible-md.visible-lg, td.visible-md.visible-lg { + display: table-cell!important; +} +}.visible-lg, tr.visible-lg, th.visible-lg, td.visible-lg { + display: none!important; +} +@media(max-width:767px) { + .visible-lg.visible-xs { + display: block!important; +} +table.visible-lg.visible-xs { + display: table; +} +tr.visible-lg.visible-xs { + display: table-row!important; +} +th.visible-lg.visible-xs, td.visible-lg.visible-xs { + display: table-cell!important; +} +}@media(min-width:768px) and (max-width:991px) { + .visible-lg.visible-sm { + display: block!important; +} +table.visible-lg.visible-sm { + display: table; +} +tr.visible-lg.visible-sm { + display: table-row!important; +} +th.visible-lg.visible-sm, td.visible-lg.visible-sm { + display: table-cell!important; +} +}@media(min-width:992px) and (max-width:1199px) { + .visible-lg.visible-md { + display: block!important; +} +table.visible-lg.visible-md { + display: table; +} +tr.visible-lg.visible-md { + display: table-row!important; +} +th.visible-lg.visible-md, td.visible-lg.visible-md { + display: table-cell!important; +} +}@media(min-width:1200px) { + .visible-lg { + display: block!important; +} +table.visible-lg { + display: table; +} +tr.visible-lg { + display: table-row!important; +} +th.visible-lg, td.visible-lg { + display: table-cell!important; +} +}.hidden-xs { + display: block!important; +} +table.hidden-xs { + display: table; +} +tr.hidden-xs { + display: table-row!important; +} +th.hidden-xs, td.hidden-xs { + display: table-cell!important; +} +@media(max-width:767px) { + .hidden-xs, tr.hidden-xs, th.hidden-xs, td.hidden-xs { + display: none!important; +} +}@media(min-width:768px) and (max-width:991px) { + .hidden-xs.hidden-sm, tr.hidden-xs.hidden-sm, th.hidden-xs.hidden-sm, td.hidden-xs.hidden-sm { + display: none!important; +} +}@media(min-width:992px) and (max-width:1199px) { + .hidden-xs.hidden-md, tr.hidden-xs.hidden-md, th.hidden-xs.hidden-md, td.hidden-xs.hidden-md { + display: none!important; +} +}@media(min-width:1200px) { + .hidden-xs.hidden-lg, tr.hidden-xs.hidden-lg, th.hidden-xs.hidden-lg, td.hidden-xs.hidden-lg { + display: none!important; +} +}.hidden-sm { + display: block!important; +} +table.hidden-sm { + display: table; +} +tr.hidden-sm { + display: table-row!important; +} +th.hidden-sm, td.hidden-sm { + display: table-cell!important; +} +@media(max-width:767px) { + .hidden-sm.hidden-xs, tr.hidden-sm.hidden-xs, th.hidden-sm.hidden-xs, td.hidden-sm.hidden-xs { + display: none!important; +} +}@media(min-width:768px) and (max-width:991px) { + .hidden-sm, tr.hidden-sm, th.hidden-sm, td.hidden-sm { + display: none!important; +} +}@media(min-width:992px) and (max-width:1199px) { + .hidden-sm.hidden-md, tr.hidden-sm.hidden-md, th.hidden-sm.hidden-md, td.hidden-sm.hidden-md { + display: none!important; +} +}@media(min-width:1200px) { + .hidden-sm.hidden-lg, tr.hidden-sm.hidden-lg, th.hidden-sm.hidden-lg, td.hidden-sm.hidden-lg { + display: none!important; +} +}.hidden-md { + display: block!important; +} +table.hidden-md { + display: table; +} +tr.hidden-md { + display: table-row!important; +} +th.hidden-md, td.hidden-md { + display: table-cell!important; +} +@media(max-width:767px) { + .hidden-md.hidden-xs, tr.hidden-md.hidden-xs, th.hidden-md.hidden-xs, td.hidden-md.hidden-xs { + display: none!important; +} +}@media(min-width:768px) and (max-width:991px) { + .hidden-md.hidden-sm, tr.hidden-md.hidden-sm, th.hidden-md.hidden-sm, td.hidden-md.hidden-sm { + display: none!important; +} +}@media(min-width:992px) and (max-width:1199px) { + .hidden-md, tr.hidden-md, th.hidden-md, td.hidden-md { + display: none!important; +} +}@media(min-width:1200px) { + .hidden-md.hidden-lg, tr.hidden-md.hidden-lg, th.hidden-md.hidden-lg, td.hidden-md.hidden-lg { + display: none!important; +} +}.hidden-lg { + display: block!important; +} +table.hidden-lg { + display: table; +} +tr.hidden-lg { + display: table-row!important; +} +th.hidden-lg, td.hidden-lg { + display: table-cell!important; +} +@media(max-width:767px) { + .hidden-lg.hidden-xs, tr.hidden-lg.hidden-xs, th.hidden-lg.hidden-xs, td.hidden-lg.hidden-xs { + display: none!important; +} +}@media(min-width:768px) and (max-width:991px) { + .hidden-lg.hidden-sm, tr.hidden-lg.hidden-sm, th.hidden-lg.hidden-sm, td.hidden-lg.hidden-sm { + display: none!important; +} +}@media(min-width:992px) and (max-width:1199px) { + .hidden-lg.hidden-md, tr.hidden-lg.hidden-md, th.hidden-lg.hidden-md, td.hidden-lg.hidden-md { + display: none!important; +} +}@media(min-width:1200px) { + .hidden-lg, tr.hidden-lg, th.hidden-lg, td.hidden-lg { + display: none!important; +} +}.visible-print, tr.visible-print, th.visible-print, td.visible-print { + display: none!important; +} +@media print { + .visible-print { + display: block!important; +} +table.visible-print { + display: table; +} +tr.visible-print { + display: table-row!important; +} +th.visible-print, td.visible-print { + display: table-cell!important; +} +.hidden-print, tr.hidden-print, th.hidden-print, td.hidden-print { + display: none!important; +} +}.navbar { + font-size: 13px; + font-weight: 300; + border: 0; +} +.navbar .navbar-toggle:hover .icon-bar { + background-color: #b3b3b3; +} +.navbar-collapse { + border-top-color: rgba(0, 0, 0, 0.2); + -webkit-box-shadow: none; + box-shadow: none; +} +.navbar .dropdown-menu { + border: 0; +} +.navbar .dropdown-menu>li>a, .navbar .dropdown-menu>li>a:focus { + font-size: 13px; + font-weight: 300; + background-color: transparent; +} +.navbar .dropdown-header { + color: rgba(255, 255, 255, 0.5); +} +.navbar-default .dropdown-menu { + background-color: #333; +} +.navbar-default .dropdown-menu>li>a, .navbar-default .dropdown-menu>li>a:focus { + color: #fff; +} +.navbar-default .dropdown-menu>li>a:hover, .navbar-default .dropdown-menu>.active>a, .navbar-default .dropdown-menu>.active>a:hover { + background-color: #272727; +} +.navbar-inverse .dropdown-menu { + background-color: #008cba; +} +.navbar-inverse .dropdown-menu>li>a, .navbar-inverse .dropdown-menu>li>a:focus { + color: #fff; +} +.navbar-inverse .dropdown-menu>li>a:hover, .navbar-inverse .dropdown-menu>.active>a, .navbar-inverse .dropdown-menu>.active>a:hover { + background-color: #006687; +} +.btn { + padding: 14px 28px; +} +.btn-lg { + padding: 16px 32px; +} +.btn-sm { + padding: 8px 16px; +} +.btn-xs { + padding: 4px 8px; +} +.btn-group .btn~.dropdown-toggle { + padding-right: 16px; + padding-left: 16px; +} +.btn-group .dropdown-menu { + border-top-width: 0; +} +.btn-group.dropup .dropdown-menu { + margin-bottom: 0; + border-top-width: 1px; + border-bottom-width: 0; +} +.btn-group .dropdown-toggle.btn-default~.dropdown-menu { + background-color: #e7e7e7; + border-color: #dadada; +} +.btn-group .dropdown-toggle.btn-default~.dropdown-menu>li>a { + color: #333; +} +.btn-group .dropdown-toggle.btn-default~.dropdown-menu>li>a:hover { + background-color: #d3d3d3; +} +.btn-group .dropdown-toggle.btn-primary~.dropdown-menu { + background-color: #008cba; + border-color: #0079a1; +} +.btn-group .dropdown-toggle.btn-primary~.dropdown-menu>li>a { + color: #fff; +} +.btn-group .dropdown-toggle.btn-primary~.dropdown-menu>li>a:hover { + background-color: #006d91; +} +.btn-group .dropdown-toggle.btn-success~.dropdown-menu { + background-color: #43ac6a; + border-color: #3c9a5f; +} +.btn-group .dropdown-toggle.btn-success~.dropdown-menu>li>a { + color: #fff; +} +.btn-group .dropdown-toggle.btn-success~.dropdown-menu>li>a:hover { + background-color: #388f58; +} +.btn-group .dropdown-toggle.btn-info~.dropdown-menu { + background-color: #5bc0de; + border-color: #46b8da; +} +.btn-group .dropdown-toggle.btn-info~.dropdown-menu>li>a { + color: #fff; +} +.btn-group .dropdown-toggle.btn-info~.dropdown-menu>li>a:hover { + background-color: #39b3d7; +} +.btn-group .dropdown-toggle.btn-warning~.dropdown-menu { + background-color: #e99002; + border-color: #d08002; +} +.btn-group .dropdown-toggle.btn-warning~.dropdown-menu>li>a { + color: #fff; +} +.btn-group .dropdown-toggle.btn-warning~.dropdown-menu>li>a:hover { + background-color: #c17702; +} +.btn-group .dropdown-toggle.btn-danger~.dropdown-menu { + background-color: #f04124; + border-color: #ea2f10; +} +.btn-group .dropdown-toggle.btn-danger~.dropdown-menu>li>a { + color: #fff; +} +.btn-group .dropdown-toggle.btn-danger~.dropdown-menu>li>a:hover { + background-color: #dc2c0f; +} +.lead { + color: #6f6f6f; +} +cite { + font-style: italic; +} +blockquote { + color: #6f6f6f; + border-left-width: 1px; +} +blockquote.pull-right { + border-right-width: 1px; +} +blockquote small { + font-size: 12px; + font-weight: 300; +} +table { + font-size: 12px; +} +input, .form-control { + padding: 7px; + font-size: 12px; +} +label, .control-label, .help-block, .checkbox, .radio { + font-size: 12px; + font-weight: normal; +} +.form-group .btn, .input-group-addon, .input-group-btn .btn { + padding: 8px 14px; + font-size: 12px; +} +.nav .open>a, .nav .open>a:hover, .nav .open>a:focus { + border-color: transparent; +} +.nav-tabs>li>a { + color: #222; + background-color: #e7e7e7; +} +.nav-tabs .caret { + border-top-color: #222; + border-bottom-color: #222; +} +.nav-pills { + font-weight: 300; +} +.breadcrumb { + font-size: 10px; + font-weight: 300; + text-transform: uppercase; + border: 1px solid #ddd; + border-radius: 3px; +} +.pagination { + font-size: 12px; + font-weight: 300; + color: #999; +} +.pagination>li>a, .pagination>li>span { + margin-left: 4px; + color: #999; +} +.pagination>.active>a, .pagination>.active>span { + color: #fff; +} +.pagination>li>a, .pagination>li:first-child>a, .pagination>li:last-child>a, .pagination>li>span, .pagination>li:first-child>span, .pagination>li:last-child>span { + border-radius: 3px; +} +.pagination-lg>li>a { + padding-right: 22px; + padding-left: 22px; +} +.pagination-sm>li>a { + padding: 0 5px; +} +.pager { + font-size: 12px; + font-weight: 300; + color: #999; +} +.list-group { + font-size: 12px; + font-weight: 300; +} +.label { + padding-right: 1em; + padding-left: 1em; + font-weight: 300; + border-radius: 0; +} +.label-default { + color: #333; + background-color: #e7e7e7; +} +.badge { + font-weight: 300; +} +.progress { + height: 22px; + padding: 2px; + background-color: #f6f6f6; + border: 1px solid #ccc; + -webkit-box-shadow: none; + box-shadow: none; +} +.dropdown-menu { + padding: 0; + margin-top: 0; + font-size: 12px; +} +.dropdown-menu>li>a { + padding: 12px 15px; +} +.dropdown-header { + padding-right: 15px; + padding-left: 15px; + font-size: 9px; + text-transform: uppercase; +} +.popover { + font-size: 12px; + font-weight: 300; + color: #fff; +} +.panel-heading, .panel-footer { + border-top-right-radius: 0; + border-top-left-radius: 0; +} +.clearfix:before, .clearfix:after { + display: table; + content: " "} +.clearfix:after { + clear: both; +} +.clearfix:before, .clearfix:after { + display: table; + content: " "} +.clearfix:after { + clear: both; +} +.center-block { + display: block; + margin-right: auto; + margin-left: auto; +} +.pull-right { + float: right!important; +} +.pull-left { + float: left!important; +} +.hide { + display: none!important; +} +.show { + display: block!important; +} +.invisible { + visibility: hidden; +} +.text-hide { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} +.hidden { + display: none!important; + visibility: hidden!important; +} +.affix { + position: fixed; +} diff --git a/cinder/css/bootstrap-custom.min.css b/cinder/css/bootstrap-custom.min.css new file mode 100644 index 00000000..25d43d46 --- /dev/null +++ b/cinder/css/bootstrap-custom.min.css @@ -0,0 +1 @@ +/*! normalize.css v2.1.3 | MIT License | git.io/normalize */article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,video{display:inline-block}audio:not([controls]){display:none;height:0}[hidden],template{display:none}html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a{background:transparent}a:focus{outline:thin dotted}a:active,a:hover{outline:0}h1{margin:.67em 0;font-size:2em}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}hr{height:0;-moz-box-sizing:content-box;box-sizing:content-box}mark{color:#000;background:#ff0}code,kbd,pre,samp{font-family:Hack,monospace,serif;font-size:1em}pre{white-space:pre-wrap}q{quotes:"\201C" "\201D" "\2018" "\2019"}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:0}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}button,input,select,textarea{margin:0;font-family:inherit;font-size:100%}button,input{line-height:normal}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button}button[disabled],html input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{padding:0;box-sizing:border-box}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-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}textarea{overflow:auto;vertical-align:top}table{border-collapse:collapse;border-spacing:0}@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) ")"}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:2cm .5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}select{background:#fff !important}.navbar{display:none}.table td,.table th{background-color:#fff !important}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000 !important}.label{border:1px solid #000}.table{border-collapse:collapse !important}.table-bordered th,.table-bordered td{border:1px solid #ddd !important}}*,*:before,*:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:62.5%;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:Merriweather,Georgia,serif;font-size:14px;line-height:1.428571429;color:#222;background-color:#fff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#008cba;text-decoration:none}a:hover,a:focus{color:#00526e;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}img{vertical-align:middle}.img-responsive{display:block;height:auto;max-width:100%}.img-rounded{border-radius:0}.img-thumbnail{display:inline-block;height:auto;max-width:100%;padding:4px;line-height:1.428571429;background-color:#fff;border:1px solid #ddd;border-radius:0;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:21px;margin-bottom:21px;border:0;border-top:1px solid #ddd}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300;line-height:1.1;color:inherit}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small,h1 .small,h2 .small,h3 .small,h4 .small,h5 .small,h6 .small,.h1 .small,.h2 .small,.h3 .small,.h4 .small,.h5 .small,.h6 .small{font-weight:normal;line-height:1;color:#999}h1,h2,h3{margin-top:21px;margin-bottom:10.5px}h1 small,h2 small,h3 small,h1 .small,h2 .small,h3 .small{font-size:65%}h4,h5,h6{margin-top:10.5px;margin-bottom:10.5px}h4 small,h5 small,h6 small,h4 .small,h5 .small,h6 .small{font-size:75%}h1,.h1{font-size:39px}h2,.h2{font-size:32px}h3,.h3{font-size:26px}h4,.h4{font-size:19px}h5,.h5{font-size:15px}h6,.h6{font-size:13px}p{margin:0 0 10.5px}.lead{margin-bottom:21px;font-size:17px;font-weight:200;line-height:1.4}@media(min-width:768px){.lead{font-size:22.5px}}small,.small{font-size:85%}cite{font-style:normal}.text-muted{color:#999}.text-primary{color:#008cba}.text-primary:hover{color:#006687}.text-warning{color:#e99002}.text-warning:hover{color:#b67102}.text-danger{color:#f04124}.text-danger:hover{color:#d32a0e}.text-success{color:#43ac6a}.text-success:hover{color:#358753}.text-info{color:#5bc0de}.text-info:hover{color:#31b0d5}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.page-header{padding-bottom:9.5px;margin:42px 0 21px;border-bottom:1px solid #ddd}ul,ol{margin-top:0;margin-bottom:10.5px}ul ul,ol ul,ul ol,ol ol{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}.list-inline>li:first-child{padding-left:0}dl{margin-top:0;margin-bottom:21px}dt,dd{line-height:1.428571429}dt{font-weight:bold}dd{margin-left:0}@media(min-width:768px){.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}.dl-horizontal dd:before,.dl-horizontal dd:after{display:table;content:" "}.dl-horizontal dd:after{clear:both}.dl-horizontal dd:before,.dl-horizontal dd:after{display:table;content:" "}.dl-horizontal dd:after{clear:both}.dl-horizontal dd:before,.dl-horizontal dd:after{display:table;content:" "}.dl-horizontal dd:after{clear:both}.dl-horizontal dd:before,.dl-horizontal dd:after{display:table;content:" "}.dl-horizontal dd:after{clear:both}.dl-horizontal dd:before,.dl-horizontal dd:after{display:table;content:" "}.dl-horizontal dd:after{clear:both}}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10.5px 21px;margin:0 0 21px;border-left:5px solid #ddd}blockquote p{font-size:18.75px;font-weight:300;line-height:1.25}blockquote p:last-child{margin-bottom:0}blockquote small,blockquote .small{display:block;line-height:1.428571429;color:#6f6f6f}blockquote small:before,blockquote .small:before{content:'\2014 \00A0'}blockquote.pull-right{padding-right:15px;padding-left:0;border-right:5px solid #ddd;border-left:0}blockquote.pull-right p,blockquote.pull-right small,blockquote.pull-right .small{text-align:right}blockquote.pull-right small:before,blockquote.pull-right .small:before{content:''}blockquote.pull-right small:after,blockquote.pull-right .small:after{content:'\00A0 \2014'}blockquote:before,blockquote:after{content:""}address{margin-bottom:21px;font-style:normal;line-height:1.428571429}code,kbd,pre,samp{font-family:Hack,Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;white-space:nowrap;background-color:#f9f2f4;border-radius:0}pre{display:block;padding:10px;margin:0 0 10.5px;font-size:14px;line-height:1.428571429;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:0}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.container:before,.container:after{display:table;content:" "}.container:after{clear:both}.container:before,.container:after{display:table;content:" "}.container:after{clear:both}.container:before,.container:after{display:table;content:" "}.container:after{clear:both}.container:before,.container:after{display:table;content:" "}.container:after{clear:both}.container:before,.container:after{display:table;content:" "}.container:after{clear:both}@media(min-width:768px){.container{width:750px}}@media(min-width:992px){.container{width:970px}}@media(min-width:1200px){.container{width:1170px}}.row{margin-right:-15px;margin-left:-15px}.row:before,.row:after{display:table;content:" "}.row:after{clear:both}.row:before,.row:after{display:table;content:" "}.row:after{clear:both}.row:before,.row:after{display:table;content:" "}.row:after{clear:both}.row:before,.row:after{display:table;content:" "}.row:after{clear:both}.row:before,.row:after{display:table;content:" "}.row:after{clear:both}.col-xs-1,.col-sm-1,.col-md-1,.col-lg-1,.col-xs-2,.col-sm-2,.col-md-2,.col-lg-2,.col-xs-3,.col-sm-3,.col-md-3,.col-lg-3,.col-xs-4,.col-sm-4,.col-md-4,.col-lg-4,.col-xs-5,.col-sm-5,.col-md-5,.col-lg-5,.col-xs-6,.col-sm-6,.col-md-6,.col-lg-6,.col-xs-7,.col-sm-7,.col-md-7,.col-lg-7,.col-xs-8,.col-sm-8,.col-md-8,.col-lg-8,.col-xs-9,.col-sm-9,.col-md-9,.col-lg-9,.col-xs-10,.col-sm-10,.col-md-10,.col-lg-10,.col-xs-11,.col-sm-11,.col-md-11,.col-lg-11,.col-xs-12,.col-sm-12,.col-md-12,.col-lg-12{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666666666666%}.col-xs-10{width:83.33333333333334%}.col-xs-9{width:75%}.col-xs-8{width:66.66666666666666%}.col-xs-7{width:58.333333333333336%}.col-xs-6{width:50%}.col-xs-5{width:41.66666666666667%}.col-xs-4{width:33.33333333333333%}.col-xs-3{width:25%}.col-xs-2{width:16.666666666666664%}.col-xs-1{width:8.333333333333332%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666666666666%}.col-xs-pull-10{right:83.33333333333334%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666666666666%}.col-xs-pull-7{right:58.333333333333336%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666666666667%}.col-xs-pull-4{right:33.33333333333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.666666666666664%}.col-xs-pull-1{right:8.333333333333332%}.col-xs-pull-0{right:0}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666666666666%}.col-xs-push-10{left:83.33333333333334%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666666666666%}.col-xs-push-7{left:58.333333333333336%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666666666667%}.col-xs-push-4{left:33.33333333333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.666666666666664%}.col-xs-push-1{left:8.333333333333332%}.col-xs-push-0{left:0}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666666666666%}.col-xs-offset-10{margin-left:83.33333333333334%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666666666666%}.col-xs-offset-7{margin-left:58.333333333333336%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666666666667%}.col-xs-offset-4{margin-left:33.33333333333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.666666666666664%}.col-xs-offset-1{margin-left:8.333333333333332%}.col-xs-offset-0{margin-left:0}@media(min-width:768px){.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666666666666%}.col-sm-10{width:83.33333333333334%}.col-sm-9{width:75%}.col-sm-8{width:66.66666666666666%}.col-sm-7{width:58.333333333333336%}.col-sm-6{width:50%}.col-sm-5{width:41.66666666666667%}.col-sm-4{width:33.33333333333333%}.col-sm-3{width:25%}.col-sm-2{width:16.666666666666664%}.col-sm-1{width:8.333333333333332%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666666666666%}.col-sm-pull-10{right:83.33333333333334%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666666666666%}.col-sm-pull-7{right:58.333333333333336%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666666666667%}.col-sm-pull-4{right:33.33333333333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.666666666666664%}.col-sm-pull-1{right:8.333333333333332%}.col-sm-pull-0{right:0}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666666666666%}.col-sm-push-10{left:83.33333333333334%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666666666666%}.col-sm-push-7{left:58.333333333333336%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666666666667%}.col-sm-push-4{left:33.33333333333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.666666666666664%}.col-sm-push-1{left:8.333333333333332%}.col-sm-push-0{left:0}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666666666666%}.col-sm-offset-10{margin-left:83.33333333333334%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666666666666%}.col-sm-offset-7{margin-left:58.333333333333336%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666666666667%}.col-sm-offset-4{margin-left:33.33333333333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.666666666666664%}.col-sm-offset-1{margin-left:8.333333333333332%}.col-sm-offset-0{margin-left:0}}@media(min-width:992px){.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666666666666%}.col-md-10{width:83.33333333333334%}.col-md-9{width:75%}.col-md-8{width:66.66666666666666%}.col-md-7{width:58.333333333333336%}.col-md-6{width:50%}.col-md-5{width:41.66666666666667%}.col-md-4{width:33.33333333333333%}.col-md-3{width:25%}.col-md-2{width:16.666666666666664%}.col-md-1{width:8.333333333333332%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666666666666%}.col-md-pull-10{right:83.33333333333334%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666666666666%}.col-md-pull-7{right:58.333333333333336%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666666666667%}.col-md-pull-4{right:33.33333333333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.666666666666664%}.col-md-pull-1{right:8.333333333333332%}.col-md-pull-0{right:0}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666666666666%}.col-md-push-10{left:83.33333333333334%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666666666666%}.col-md-push-7{left:58.333333333333336%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666666666667%}.col-md-push-4{left:33.33333333333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.666666666666664%}.col-md-push-1{left:8.333333333333332%}.col-md-push-0{left:0}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666666666666%}.col-md-offset-10{margin-left:83.33333333333334%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666666666666%}.col-md-offset-7{margin-left:58.333333333333336%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666666666667%}.col-md-offset-4{margin-left:33.33333333333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.666666666666664%}.col-md-offset-1{margin-left:8.333333333333332%}.col-md-offset-0{margin-left:0}}@media(min-width:1200px){.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666666666666%}.col-lg-10{width:83.33333333333334%}.col-lg-9{width:75%}.col-lg-8{width:66.66666666666666%}.col-lg-7{width:58.333333333333336%}.col-lg-6{width:50%}.col-lg-5{width:41.66666666666667%}.col-lg-4{width:33.33333333333333%}.col-lg-3{width:25%}.col-lg-2{width:16.666666666666664%}.col-lg-1{width:8.333333333333332%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666666666666%}.col-lg-pull-10{right:83.33333333333334%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666666666666%}.col-lg-pull-7{right:58.333333333333336%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666666666667%}.col-lg-pull-4{right:33.33333333333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.666666666666664%}.col-lg-pull-1{right:8.333333333333332%}.col-lg-pull-0{right:0}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666666666666%}.col-lg-push-10{left:83.33333333333334%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666666666666%}.col-lg-push-7{left:58.333333333333336%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666666666667%}.col-lg-push-4{left:33.33333333333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.666666666666664%}.col-lg-push-1{left:8.333333333333332%}.col-lg-push-0{left:0}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666666666666%}.col-lg-offset-10{margin-left:83.33333333333334%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666666666666%}.col-lg-offset-7{margin-left:58.333333333333336%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666666666667%}.col-lg-offset-4{margin-left:33.33333333333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.666666666666664%}.col-lg-offset-1{margin-left:8.333333333333332%}.col-lg-offset-0{margin-left:0}}table{max-width:100%;background-color:transparent}th{text-align:left}.table{width:100%;margin-bottom:21px}.table>thead>tr>th,.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>td,.table>tbody>tr>td,.table>tfoot>tr>td{padding:8px;line-height:1.428571429;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>th,.table>caption+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>td,.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>thead>tr>th,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>tbody>tr>td,.table-condensed>tfoot>tr>td{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.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 col[class*="col-"]{position:static;display:table-column;float:none}table td[class*="col-"],table th[class*="col-"]{display:table-cell;float:none}.table>thead>tr>.active,.table>tbody>tr>.active,.table>tfoot>tr>.active,.table>thead>.active>td,.table>tbody>.active>td,.table>tfoot>.active>td,.table>thead>.active>th,.table>tbody>.active>th,.table>tfoot>.active>th{background-color:#f5f5f5}.table-hover>tbody>tr>.active:hover,.table-hover>tbody>.active:hover>td,.table-hover>tbody>.active:hover>th{background-color:#e8e8e8}.table>thead>tr>.success,.table>tbody>tr>.success,.table>tfoot>tr>.success,.table>thead>.success>td,.table>tbody>.success>td,.table>tfoot>.success>td,.table>thead>.success>th,.table>tbody>.success>th,.table>tfoot>.success>th{background-color:#dff0d8}.table-hover>tbody>tr>.success:hover,.table-hover>tbody>.success:hover>td,.table-hover>tbody>.success:hover>th{background-color:#d0e9c6}.table>thead>tr>.danger,.table>tbody>tr>.danger,.table>tfoot>tr>.danger,.table>thead>.danger>td,.table>tbody>.danger>td,.table>tfoot>.danger>td,.table>thead>.danger>th,.table>tbody>.danger>th,.table>tfoot>.danger>th{background-color:#f2dede}.table-hover>tbody>tr>.danger:hover,.table-hover>tbody>.danger:hover>td,.table-hover>tbody>.danger:hover>th{background-color:#ebcccc}.table>thead>tr>.warning,.table>tbody>tr>.warning,.table>tfoot>tr>.warning,.table>thead>.warning>td,.table>tbody>.warning>td,.table>tfoot>.warning>td,.table>thead>.warning>th,.table>tbody>.warning>th,.table>tfoot>.warning>th{background-color:#fcf8e3}.table-hover>tbody>tr>.warning:hover,.table-hover>tbody>.warning:hover>td,.table-hover>tbody>.warning:hover>th{background-color:#faf2cc}@media(max-width:767px){.table-responsive{width:100%;margin-bottom:15.75px;overflow-x:scroll;overflow-y:hidden;border:1px solid #ddd;-ms-overflow-style:-ms-autohiding-scrollbar;-webkit-overflow-scrolling:touch}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>thead>tr>th,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>td{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}}fieldset{padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:21px;font-size:22.5px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;margin-bottom:5px;font-weight:bold}input[type="search"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type="file"]{display:block}select[multiple],select[size]{height:auto}select optgroup{font-family:inherit;font-size:inherit;font-style:inherit}input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}input[type="number"]::-webkit-outer-spin-button,input[type="number"]::-webkit-inner-spin-button{height:auto}output{display:block;padding-top:7px;font-size:15px;line-height:1.428571429;color:#6f6f6f;vertical-align:middle}.form-control{display:block;width:100%;height:35px;padding:6px 12px;font-size:15px;line-height:1.428571429;color:#6f6f6f;vertical-align:middle;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:0;-webkit-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-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(102,175,233,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(102,175,233,0.6)}.form-control:-moz-placeholder{color:#999}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{cursor:not-allowed;background-color:#eee}textarea.form-control{height:auto}.form-group{margin-bottom:15px}.radio,.checkbox{display:block;min-height:21px;padding-left:20px;margin-top:10px;margin-bottom:10px;vertical-align:middle}.radio label,.checkbox label{display:inline;margin-bottom:0;font-weight:normal;cursor:pointer}.radio input[type="radio"],.radio-inline input[type="radio"],.checkbox input[type="checkbox"],.checkbox-inline input[type="checkbox"]{float:left;margin-left:-20px}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{display:inline-block;padding-left:20px;margin-bottom:0;font-weight:normal;vertical-align:middle;cursor:pointer}.radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px}input[type="radio"][disabled],input[type="checkbox"][disabled],.radio[disabled],.radio-inline[disabled],.checkbox[disabled],.checkbox-inline[disabled],fieldset[disabled] input[type="radio"],fieldset[disabled] input[type="checkbox"],fieldset[disabled] .radio,fieldset[disabled] .radio-inline,fieldset[disabled] .checkbox,fieldset[disabled] .checkbox-inline{cursor:not-allowed}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:0}select.input-sm{height:30px;line-height:30px}textarea.input-sm{height:auto}.input-lg{height:48px;padding:10px 16px;font-size:19px;line-height:1.33;border-radius:0}select.input-lg{height:48px;line-height:48px}textarea.input-lg{height:auto}.has-warning .help-block,.has-warning .control-label,.has-warning .radio,.has-warning .checkbox,.has-warning .radio-inline,.has-warning .checkbox-inline{color:#e99002}.has-warning .form-control{border-color:#e99002;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-warning .form-control:focus{border-color:#b67102;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #febc53;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #febc53}.has-warning .input-group-addon{color:#e99002;background-color:#fcf8e3;border-color:#e99002}.has-error .help-block,.has-error .control-label,.has-error .radio,.has-error .checkbox,.has-error .radio-inline,.has-error .checkbox-inline{color:#f04124}.has-error .form-control{border-color:#f04124;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-error .form-control:focus{border-color:#d32a0e;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #f79483;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #f79483}.has-error .input-group-addon{color:#f04124;background-color:#f2dede;border-color:#f04124}.has-success .help-block,.has-success .control-label,.has-success .radio,.has-success .checkbox,.has-success .radio-inline,.has-success .checkbox-inline{color:#43ac6a}.has-success .form-control{border-color:#43ac6a;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-success .form-control:focus{border-color:#358753;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #85d0a1;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #85d0a1}.has-success .input-group-addon{color:#43ac6a;background-color:#dff0d8;border-color:#43ac6a}.form-control-static{margin-bottom:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#626262}@media(min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block}.form-inline select.form-control{width:auto}.form-inline .radio,.form-inline .checkbox{display:inline-block;padding-left:0;margin-top:0;margin-bottom:0}.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:none;margin-left:0}}.form-horizontal .control-label,.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .radio,.form-horizontal .checkbox{min-height:28px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}.form-horizontal .form-group:before,.form-horizontal .form-group:after{display:table;content:" "}.form-horizontal .form-group:after{clear:both}.form-horizontal .form-group:before,.form-horizontal .form-group:after{display:table;content:" "}.form-horizontal .form-group:after{clear:both}.form-horizontal .form-group:before,.form-horizontal .form-group:after{display:table;content:" "}.form-horizontal .form-group:after{clear:both}.form-horizontal .form-group:before,.form-horizontal .form-group:after{display:table;content:" "}.form-horizontal .form-group:after{clear:both}.form-horizontal .form-group:before,.form-horizontal .form-group:after{display:table;content:" "}.form-horizontal .form-group:after{clear:both}.form-horizontal .form-control-static{padding-top:7px}@media(min-width:768px){.form-horizontal .control-label{text-align:right}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:15px;font-weight:normal;line-height:1.428571429;text-align:center;white-space:nowrap;vertical-align:middle;cursor:pointer;background-image:none;border:1px solid transparent;border-radius:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none}.btn:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.btn:focus{color:#333;text-decoration:none}.btn:active,.btn.active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{pointer-events:none;cursor:not-allowed;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}.btn-default{color:#333;background-color:#e7e7e7;border-color:#dadada}.btn-default:hover,.btn-default:focus,.btn-default:active,.btn-default.active,.open .dropdown-toggle.btn-default{color:#333;background-color:#d3d3d3;border-color:#bbb}.btn-default:active,.btn-default.active,.open .dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default[disabled],fieldset[disabled] .btn-default,.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled:active,.btn-default[disabled]:active,fieldset[disabled] .btn-default:active,.btn-default.disabled.active,.btn-default[disabled].active,fieldset[disabled] .btn-default.active{background-color:#e7e7e7;border-color:#dadada}.btn-default .badge{color:#e7e7e7;background-color:#fff}.btn-primary{color:#fff;background-color:#008cba;border-color:#0079a1}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.open .dropdown-toggle.btn-primary{color:#fff;background-color:#006d91;border-color:#004b63}.btn-primary:active,.btn-primary.active,.open .dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary[disabled],fieldset[disabled] .btn-primary,.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled:active,.btn-primary[disabled]:active,fieldset[disabled] .btn-primary:active,.btn-primary.disabled.active,.btn-primary[disabled].active,fieldset[disabled] .btn-primary.active{background-color:#008cba;border-color:#0079a1}.btn-primary .badge{color:#008cba;background-color:#fff}.btn-warning{color:#fff;background-color:#e99002;border-color:#d08002}.btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.open .dropdown-toggle.btn-warning{color:#fff;background-color:#c17702;border-color:#935b01}.btn-warning:active,.btn-warning.active,.open .dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-warning,.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled:active,.btn-warning[disabled]:active,fieldset[disabled] .btn-warning:active,.btn-warning.disabled.active,.btn-warning[disabled].active,fieldset[disabled] .btn-warning.active{background-color:#e99002;border-color:#d08002}.btn-warning .badge{color:#e99002;background-color:#fff}.btn-danger{color:#fff;background-color:#f04124;border-color:#ea2f10}.btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.open .dropdown-toggle.btn-danger{color:#fff;background-color:#dc2c0f;border-color:#b1240c}.btn-danger:active,.btn-danger.active,.open .dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger[disabled],fieldset[disabled] .btn-danger,.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled:active,.btn-danger[disabled]:active,fieldset[disabled] .btn-danger:active,.btn-danger.disabled.active,.btn-danger[disabled].active,fieldset[disabled] .btn-danger.active{background-color:#f04124;border-color:#ea2f10}.btn-danger .badge{color:#f04124;background-color:#fff}.btn-success{color:#fff;background-color:#43ac6a;border-color:#3c9a5f}.btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.open .dropdown-toggle.btn-success{color:#fff;background-color:#388f58;border-color:#2b6e44}.btn-success:active,.btn-success.active,.open .dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success[disabled],fieldset[disabled] .btn-success,.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled:active,.btn-success[disabled]:active,fieldset[disabled] .btn-success:active,.btn-success.disabled.active,.btn-success[disabled].active,fieldset[disabled] .btn-success.active{background-color:#43ac6a;border-color:#3c9a5f}.btn-success .badge{color:#43ac6a;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.open .dropdown-toggle.btn-info{color:#fff;background-color:#39b3d7;border-color:#269abc}.btn-info:active,.btn-info.active,.open .dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info[disabled],fieldset[disabled] .btn-info,.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled:active,.btn-info[disabled]:active,fieldset[disabled] .btn-info:active,.btn-info.disabled.active,.btn-info[disabled].active,fieldset[disabled] .btn-info.active{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-link{font-weight:normal;color:#008cba;cursor:pointer;border-radius:0}.btn-link,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent}.btn-link:hover,.btn-link:focus{color:#00526e;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#999;text-decoration:none}.btn-lg{padding:10px 16px;font-size:19px;line-height:1.33;border-radius:0}.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:0}.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:0}.btn-block{display:block;width:100%;padding-right:0;padding-left:0}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;transition:height .35s ease}@font-face{font-family:'Glyphicons Halflings';src:url('../fonts/glyphicons-halflings-regular.eot');src:url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'),url('../fonts/glyphicons-halflings-regular.woff') format('woff'),url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'),url('../fonts/glyphicons-halflings-regular.svg#glyphicons-halflingsregular') format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';-webkit-font-smoothing:antialiased;font-style:normal;font-weight:normal;line-height:1;-moz-osx-font-smoothing:grayscale}.glyphicon:empty{width:1em}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px solid;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown{position:relative}.dropdown-toggle:focus{outline:0}.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;font-size:15px;list-style:none;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,0.175);box-shadow:0 6px 12px rgba(0,0,0,0.175);background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9.5px 0;overflow:hidden;background-color:rgba(0,0,0,0.2)}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:1.428571429;color:#555;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{color:#262626;text-decoration:none;background-color:#eee}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;background-color:#008cba;outline: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:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.428571429;color:#999}.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;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}@media(min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;float:left}.btn-group>.btn:hover,.btn-group-vertical>.btn:hover,.btn-group>.btn:focus,.btn-group-vertical>.btn:focus,.btn-group>.btn:active,.btn-group-vertical>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn.active{z-index:2}.btn-group>.btn:focus,.btn-group-vertical>.btn:focus{outline:0}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar:before,.btn-toolbar:after{display:table;content:" "}.btn-toolbar:after{clear:both}.btn-toolbar:before,.btn-toolbar:after{display:table;content:" "}.btn-toolbar:after{clear:both}.btn-toolbar:before,.btn-toolbar:after{display:table;content:" "}.btn-toolbar:after{clear:both}.btn-toolbar:before,.btn-toolbar:after{display:table;content:" "}.btn-toolbar:after{clear:both}.btn-toolbar:before,.btn-toolbar:after{display:table;content:" "}.btn-toolbar:after{clear:both}.btn-toolbar .btn-group{float:left}.btn-toolbar>.btn+.btn,.btn-toolbar>.btn-group+.btn,.btn-toolbar>.btn+.btn-group,.btn-toolbar>.btn-group+.btn-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child>.btn:last-child,.btn-group>.btn-group:first-child>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child>.btn:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group-xs>.btn{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:0}.btn-group-sm>.btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:0}.btn-group-lg>.btn{padding:10px 16px;font-size:19px;line-height:1.33;border-radius:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after{display:table;content:" "}.btn-group-vertical>.btn-group:after{clear:both}.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after{display:table;content:" "}.btn-group-vertical>.btn-group:after{clear:both}.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after{display:table;content:" "}.btn-group-vertical>.btn-group:after{clear:both}.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after{display:table;content:" "}.btn-group-vertical>.btn-group:after{clear:both}.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after{display:table;content:" "}.btn-group-vertical>.btn-group:after{clear:both}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-right-radius:0;border-bottom-left-radius:0;border-top-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child>.btn:last-child,.btn-group-vertical>.btn-group:first-child>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child>.btn:first-child{border-top-right-radius:0;border-top-left-radius:0}.btn-group-justified{display:table;width:100%;border-collapse:separate;table-layout:fixed}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}[data-toggle="buttons"]>.btn>input[type="radio"],[data-toggle="buttons"]>.btn>input[type="checkbox"]{display:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*="col-"]{float:none;padding-right:0;padding-left:0}.input-group .form-control{width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:48px;padding:10px 16px;font-size:19px;line-height:1.33;border-radius:0}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:48px;line-height:48px}textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:0}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group-addon,.input-group-btn,.input-group .form-control{display:table-cell}.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child),.input-group .form-control:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:15px;font-weight:normal;line-height:1;color:#6f6f6f;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:0}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:0}.input-group-addon.input-lg{padding:10px 16px;font-size:19px;border-radius:0}.input-group-addon input[type="radio"],.input-group-addon input[type="checkbox"]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:last-child>.btn,.input-group-btn:last-child>.dropdown-toggle,.input-group-btn:first-child>.btn:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;white-space:nowrap}.input-group-btn:first-child>.btn{margin-right:-1px}.input-group-btn:last-child>.btn{margin-left:-1px}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-4px}.input-group-btn>.btn:hover,.input-group-btn>.btn:active{z-index:2}.nav{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;padding-left:0;margin-bottom:0;list-style:none}.nav:before,.nav:after{display:table;content:" "}.nav:after{clear:both}.nav:before,.nav:after{display:table;content:" "}.nav:after{clear:both}.nav:before,.nav:after{display:table;content:" "}.nav:after{clear:both}.nav:before,.nav:after{display:table;content:" "}.nav:after{clear:both}.nav:before,.nav:after{display:table;content:" "}.nav:after{clear:both}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#999}.nav>li.disabled>a:hover,.nav>li.disabled>a:focus{color:#999;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{background-color:#eee;border-color:#008cba}.nav .nav-divider{height:1px;margin:9.5px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.428571429;border:1px solid transparent;border-radius:0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{color:#6f6f6f;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media(min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border:1px solid #ddd}@media(min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:0}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:hover,.nav-pills>li.active>a:focus{color:#fff;background-color:#008cba}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media(min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border:1px solid #ddd}@media(min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-right-radius:0;border-top-left-radius:0}.navbar{position:relative;min-height:45px;margin-bottom:21px;border:1px solid transparent}.navbar:before,.navbar:after{display:table;content:" "}.navbar:after{clear:both}.navbar:before,.navbar:after{display:table;content:" "}.navbar:after{clear:both}.navbar:before,.navbar:after{display:table;content:" "}.navbar:after{clear:both}.navbar:before,.navbar:after{display:table;content:" "}.navbar:after{clear:both}.navbar:before,.navbar:after{display:table;content:" "}.navbar:after{clear:both}@media(min-width:768px){.navbar{border-radius:0}}.navbar-header:before,.navbar-header:after{display:table;content:" "}.navbar-header:after{clear:both}.navbar-header:before,.navbar-header:after{display:table;content:" "}.navbar-header:after{clear:both}.navbar-header:before,.navbar-header:after{display:table;content:" "}.navbar-header:after{clear:both}.navbar-header:before,.navbar-header:after{display:table;content:" "}.navbar-header:after{clear:both}.navbar-header:before,.navbar-header:after{display:table;content:" "}.navbar-header:after{clear:both}@media(min-width:768px){.navbar-header{float:left}}.navbar-collapse{max-height:340px;padding-right:15px;padding-left:15px;overflow-x:visible;border-top:1px solid transparent;box-shadow:inset 0 1px 0 rgba(255,255,255,0.1);-webkit-overflow-scrolling:touch}.navbar-collapse:before,.navbar-collapse:after{display:table;content:" "}.navbar-collapse:after{clear:both}.navbar-collapse:before,.navbar-collapse:after{display:table;content:" "}.navbar-collapse:after{clear:both}.navbar-collapse:before,.navbar-collapse:after{display:table;content:" "}.navbar-collapse:after{clear:both}.navbar-collapse:before,.navbar-collapse:after{display:table;content:" "}.navbar-collapse:after{clear:both}.navbar-collapse:before,.navbar-collapse:after{display:table;content:" "}.navbar-collapse:after{clear:both}.navbar-collapse.in{overflow-y:auto}@media(min-width:768px){.navbar-collapse{width:auto;border-top:0;box-shadow:none}.navbar-collapse.collapse{display:block !important;height:auto !important;padding-bottom:0;overflow:visible !important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{padding-right:0;padding-left:0}}.container>.navbar-header,.container>.navbar-collapse{margin-right:-15px;margin-left:-15px}@media(min-width:768px){.container>.navbar-header,.container>.navbar-collapse{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media(min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030}@media(min-width:768px){.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;float:left;padding:12px 15px;font-size:19px;line-height:21px}.navbar-brand:hover,.navbar-brand:focus{text-decoration:none}@media(min-width:768px){.navbar>.container .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:5.5px;margin-right:15px;margin-bottom:5.5px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media(min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:6px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:21px}@media(max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;box-shadow:none}.navbar-nav .open .dropdown-menu>li>a,.navbar-nav .open .dropdown-menu .dropdown-header{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:21px}.navbar-nav .open .dropdown-menu>li>a:hover,.navbar-nav .open .dropdown-menu>li>a:focus{background-image:none}}@media(min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:12px;padding-bottom:12px}.navbar-nav.navbar-right:last-child{margin-right:-15px}}@media(min-width:768px){.navbar-left{float:left !important}.navbar-right{float:right !important}}.navbar-form{padding:10px 15px;margin-top:5px;margin-right:-15px;margin-bottom:5px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-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)}@media(min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block}.navbar-form select.form-control{width:auto}.navbar-form .radio,.navbar-form .checkbox{display:inline-block;padding-left:0;margin-top:0;margin-bottom:0}.navbar-form .radio input[type="radio"],.navbar-form .checkbox input[type="checkbox"]{float:none;margin-left:0}}@media(max-width:767px){.navbar-form .form-group{margin-bottom:5px}}@media(min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-form.navbar-right:last-child{margin-right:-15px}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-right-radius:0;border-top-left-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-nav.pull-right>li>.dropdown-menu,.navbar-nav>li>.dropdown-menu.pull-right{right:0;left:auto}.navbar-btn{margin-top:5px;margin-bottom:5px}.navbar-btn.btn-sm{margin-top:7.5px;margin-bottom:7.5px}.navbar-btn.btn-xs{margin-top:11.5px;margin-bottom:11.5px}.navbar-text{margin-top:12px;margin-bottom:12px}@media(min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}.navbar-text.navbar-right:last-child{margin-right:0}}.navbar-default{background-color:#333;border-color:#222}.navbar-default .navbar-brand{color:#fff}.navbar-default .navbar-brand:hover,.navbar-default .navbar-brand:focus{color:#fff;background-color:transparent}.navbar-default .navbar-text{color:#fff}.navbar-default .navbar-nav>li>a{color:#fff}.navbar-default .navbar-nav>li>a:hover,.navbar-default .navbar-nav>li>a:focus{color:#fff;background-color:#272727}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#fff;background-color:#272727}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:hover,.navbar-default .navbar-nav>.disabled>a:focus{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:transparent}.navbar-default .navbar-toggle:hover,.navbar-default .navbar-toggle:focus{background-color:transparent}.navbar-default .navbar-toggle .icon-bar{background-color:#fff}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#222}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:hover,.navbar-default .navbar-nav>.open>a:focus{color:#fff;background-color:#272727}@media(max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#fff}.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus{color:#fff;background-color:#272727}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus{color:#fff;background-color:#272727}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#fff}.navbar-default .navbar-link:hover{color:#fff}.navbar-inverse{background-color:#008cba;border-color:#006687}.navbar-inverse .navbar-brand{color:#fff}.navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-brand:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#fff}.navbar-inverse .navbar-nav>li>a{color:#fff}.navbar-inverse .navbar-nav>li>a:hover,.navbar-inverse .navbar-nav>li>a:focus{color:#fff;background-color:#006687}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:hover,.navbar-inverse .navbar-nav>.active>a:focus{color:#fff;background-color:#006687}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:hover,.navbar-inverse .navbar-nav>.disabled>a:focus{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:transparent}.navbar-inverse .navbar-toggle:hover,.navbar-inverse .navbar-toggle:focus{background-color:transparent}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#007196}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:hover,.navbar-inverse .navbar-nav>.open>a:focus{color:#fff;background-color:#006687}@media(max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#006687}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#006687}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#fff}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus{color:#fff;background-color:#006687}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus{color:#fff;background-color:#006687}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#fff}.navbar-inverse .navbar-link:hover{color:#fff}.breadcrumb{padding:8px 15px;margin-bottom:21px;list-style:none;background-color:#f5f5f5;border-radius:0}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#999;content:"/\00a0"}.breadcrumb>.active{color:#333}.pagination{display:inline-block;padding-left:0;margin:21px 0;border-radius:0}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.428571429;text-decoration:none;background-color:transparent;border:1px solid transparent}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-bottom-left-radius:0;border-top-left-radius:0}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:0;border-bottom-right-radius:0}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{background-color:#eee}.pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus{z-index:2;color:#fff;cursor:default;background-color:#008cba;border-color:#008cba}.pagination>.disabled>span,.pagination>.disabled>span:hover,.pagination>.disabled>span:focus,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#999;cursor:not-allowed;background-color:transparent;border-color:transparent}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:19px}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-bottom-left-radius:0;border-top-left-radius:0}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:0;border-bottom-right-radius:0}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-bottom-left-radius:0;border-top-left-radius:0}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:0;border-bottom-right-radius:0}.pager{padding-left:0;margin:21px 0;text-align:center;list-style:none}.pager:before,.pager:after{display:table;content:" "}.pager:after{clear:both}.pager:before,.pager:after{display:table;content:" "}.pager:after{clear:both}.pager:before,.pager:after{display:table;content:" "}.pager:after{clear:both}.pager:before,.pager:after{display:table;content:" "}.pager:after{clear:both}.pager:before,.pager:after{display:table;content:" "}.pager:after{clear:both}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:transparent;border:1px solid transparent;border-radius:3px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#eee}.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:not-allowed;background-color:transparent}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:bold;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}.label[href]:hover,.label[href]:focus{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#999}.label-default[href]:hover,.label-default[href]:focus{background-color:gray}.label-primary{background-color:#008cba}.label-primary[href]:hover,.label-primary[href]:focus{background-color:#006687}.label-success{background-color:#43ac6a}.label-success[href]:hover,.label-success[href]:focus{background-color:#358753}.label-info{background-color:#5bc0de}.label-info[href]:hover,.label-info[href]:focus{background-color:#31b0d5}.label-warning{background-color:#e99002}.label-warning[href]:hover,.label-warning[href]:focus{background-color:#b67102}.label-danger{background-color:#f04124}.label-danger[href]:hover,.label-danger[href]:focus{background-color:#d32a0e}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:bold;line-height:1;color:#777;text-align:center;white-space:nowrap;vertical-align:baseline;background-color:#e7e7e7;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}a.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#008cba;background-color:#fff}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding:30px;margin-bottom:30px;font-size:23px;font-weight:200;line-height:2.1428571435;color:inherit;background-color:#fafafa}.jumbotron h1,.jumbotron .h1{line-height:1;color:inherit}.jumbotron p{line-height:1.4}.container .jumbotron{border-radius:0}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron{padding-right:60px;padding-left:60px}.jumbotron h1,.jumbotron .h1{font-size:67.5px}}.thumbnail{display:block;padding:4px;margin-bottom:21px;line-height:1.428571429;background-color:#fff;border:1px solid #ddd;border-radius:0;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.thumbnail>img,.thumbnail a>img{display:block;height:auto;max-width:100%;margin-right:auto;margin-left:auto}a.thumbnail:hover,a.thumbnail:focus,a.thumbnail.active{border-color:#008cba}.thumbnail .caption{padding:9px;color:#222}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:4rem}.alert-dismissible .close{position:absolute;top:0;right:0;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff}.alert-primary hr{border-top-color:#9fcdff}.alert-primary .alert-link{color:#002752}.alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}.alert-secondary hr{border-top-color:#c8cbcf}.alert-secondary .alert-link{color:#202326}.alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.alert-success hr{border-top-color:#b1dfbb}.alert-success .alert-link{color:#0b2e13}.alert-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}.alert-info hr{border-top-color:#abdde5}.alert-info .alert-link{color:#062c33}.alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}.alert-warning hr{border-top-color:#ffe8a1}.alert-warning .alert-link{color:#533f03}.alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.alert-danger hr{border-top-color:#f1b0b7}.alert-danger .alert-link{color:#491217}.alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.alert-light hr{border-top-color:#ececf6}.alert-light .alert-link{color:#686868}.alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.alert-dark hr{border-top-color:#b9bbbe}.alert-dark .alert-link{color:#040505}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:21px;margin-bottom:21px;overflow:hidden;background-color:#f5f5f5;border-radius:0;-webkit-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;line-height:21px;color:#fff;text-align:center;background-color:#008cba;-webkit-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-transition:width .6s ease;transition:width .6s ease}.progress-striped .progress-bar{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: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-size:40px 40px}.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#43ac6a}.progress-striped .progress-bar-success{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: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-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{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: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-bar-warning{background-color:#e99002}.progress-striped .progress-bar-warning{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: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-bar-danger{background-color:#f04124}.progress-striped .progress-bar-danger{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: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)}.media,.media-body{overflow:hidden;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{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-right-radius:0;border-top-left-radius:0}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}a.list-group-item{color:#555}a.list-group-item .list-group-item-heading{color:#333}a.list-group-item:hover,a.list-group-item:focus{text-decoration:none;background-color:#f5f5f5}a.list-group-item.active,a.list-group-item.active:hover,a.list-group-item.active:focus{z-index:2;color:#fff;background-color:#008cba;border-color:#008cba}a.list-group-item.active .list-group-item-heading,a.list-group-item.active:hover .list-group-item-heading,a.list-group-item.active:focus .list-group-item-heading{color:inherit}a.list-group-item.active .list-group-item-text,a.list-group-item.active:hover .list-group-item-text,a.list-group-item.active:focus .list-group-item-text{color:#87e1ff}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:21px;background-color:#fff;border:1px solid transparent;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.05);box-shadow:0 1px 1px rgba(0,0,0,0.05)}.panel-body{padding:15px}.panel-body:before,.panel-body:after{display:table;content:" "}.panel-body:after{clear:both}.panel-body:before,.panel-body:after{display:table;content:" "}.panel-body:after{clear:both}.panel-body:before,.panel-body:after{display:table;content:" "}.panel-body:after{clear:both}.panel-body:before,.panel-body:after{display:table;content:" "}.panel-body:after{clear:both}.panel-body:before,.panel-body:after{display:table;content:" "}.panel-body:after{clear:both}.panel>.list-group{margin-bottom:0}.panel>.list-group .list-group-item{border-width:1px 0}.panel>.list-group .list-group-item:first-child{border-top-right-radius:0;border-top-left-radius:0}.panel>.list-group .list-group-item:last-child{border-bottom:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive{border-top:1px solid #ddd}.panel>.table>tbody:first-child th,.panel>.table>tbody:first-child td{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.panel>.table-bordered>thead>tr:last-child>th,.panel>.table-responsive>.table-bordered>thead>tr:last-child>th,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th,.panel>.table-bordered>thead>tr:last-child>td,.panel>.table-responsive>.table-bordered>thead>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-right-radius:-1;border-top-left-radius:-1}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:17px;color:inherit}.panel-title>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:-1;border-bottom-left-radius:-1}.panel-group .panel{margin-bottom:0;overflow:hidden;border-radius:0}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse .panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse .panel-body{border-top-color:#ddd}.panel-default>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#008cba}.panel-primary>.panel-heading{color:#fff;background-color:#008cba;border-color:#008cba}.panel-primary>.panel-heading+.panel-collapse .panel-body{border-top-color:#008cba}.panel-primary>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#008cba}.panel-success{border-color:#3c9a5f}.panel-success>.panel-heading{color:#43ac6a;background-color:#dff0d8;border-color:#3c9a5f}.panel-success>.panel-heading+.panel-collapse .panel-body{border-top-color:#3c9a5f}.panel-success>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#3c9a5f}.panel-warning{border-color:#d08002}.panel-warning>.panel-heading{color:#e99002;background-color:#fcf8e3;border-color:#d08002}.panel-warning>.panel-heading+.panel-collapse .panel-body{border-top-color:#d08002}.panel-warning>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#d08002}.panel-danger{border-color:#ea2f10}.panel-danger>.panel-heading{color:#f04124;background-color:#f2dede;border-color:#ea2f10}.panel-danger>.panel-heading+.panel-collapse .panel-body{border-top-color:#ea2f10}.panel-danger>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#ea2f10}.panel-info{border-color:#3db5d8}.panel-info>.panel-heading{color:#5bc0de;background-color:#d9edf7;border-color:#3db5d8}.panel-info>.panel-heading+.panel-collapse .panel-body{border-top-color:#3db5d8}.panel-info>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#3db5d8}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#fafafa;border:1px solid #e8e8e8;border-radius:0;-webkit-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-lg{padding:24px;border-radius:0}.well-sm{padding:9px;border-radius:0}.close{float:right;font-size:22.5px;font-weight:bold;line-height:1;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:.5;filter:alpha(opacity=50)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;display:none;overflow:auto;overflow-y:scroll}.modal.fade .modal-dialog{-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);transform:translate(0,-25%);-webkit-transition:-webkit-transform .3s ease-out;-moz-transition:-moz-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);transform:translate(0,0)}.modal-dialog{position:relative;z-index:1050;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,0.2);border-radius:0;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,0.5);box-shadow:0 3px 9px rgba(0,0,0,0.5);background-clip:padding-box}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1030;background-color:#000}.modal-backdrop.fade{opacity:0;filter:alpha(opacity=0)}.modal-backdrop.in{opacity:.5;filter:alpha(opacity=50)}.modal-header{min-height:16.428571429px;padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.428571429}.modal-body{position:relative;padding:20px}.modal-footer{padding:19px 20px 20px;margin-top:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer:before,.modal-footer:after{display:table;content:" "}.modal-footer:after{clear:both}.modal-footer:before,.modal-footer:after{display:table;content:" "}.modal-footer:after{clear:both}.modal-footer:before,.modal-footer:after{display:table;content:" "}.modal-footer:after{clear:both}.modal-footer:before,.modal-footer:after{display:table;content:" "}.modal-footer:after{clear:both}.modal-footer:before,.modal-footer:after{display:table;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}@media screen and (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,0.5);box-shadow:0 5px 15px rgba(0,0,0,0.5)}}.tooltip{position:absolute;z-index:1030;display:block;font-size:12px;line-height:1.4;opacity:0;filter:alpha(opacity=0);visibility:visible}.tooltip.in{opacity:.9;filter:alpha(opacity=90)}.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:3px 8px;color:#fff;text-align:center;text-decoration:none;background-color:#333;border-radius:0}.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:#333;border-width:5px 5px 0}.tooltip.top-left .tooltip-arrow{bottom:0;left:5px;border-top-color:#333;border-width:5px 5px 0}.tooltip.top-right .tooltip-arrow{right:5px;bottom:0;border-top-color:#333;border-width:5px 5px 0}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-right-color:#333;border-width:5px 5px 5px 0}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-left-color:#333;border-width:5px 0 5px 5px}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-bottom-color:#333;border-width:0 5px 5px}.tooltip.bottom-left .tooltip-arrow{top:0;left:5px;border-bottom-color:#333;border-width:0 5px 5px}.tooltip.bottom-right .tooltip-arrow{top:0;right:5px;border-bottom-color:#333;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:#333;border:1px solid #333;border:1px solid transparent;border-radius:0;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);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:15px;font-weight:normal;line-height:18px;background-color:#333;border-bottom:1px solid #262626;border-radius:5px 5px 0 0}.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:#333;border-bottom-width:0;content:" "}.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:#333;border-left-width:0;content:" "}.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:#333;border-top-width:0;content:" "}.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:#333;border-right-width:0;content:" "}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;height:auto;max-width:100%;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:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,0.6);opacity:.5;filter:alpha(opacity=50)}.carousel-control.left{background-image:-webkit-linear-gradient(left,color-stop(rgba(0,0,0,0.5) 0),color-stop(rgba(0,0,0,0.0001) 100%));background-image:linear-gradient(to right,rgba(0,0,0,0.5) 0,rgba(0,0,0,0.0001) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000',endColorstr='#00000000',GradientType=1)}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,color-stop(rgba(0,0,0,0.0001) 0),color-stop(rgba(0,0,0,0.5) 100%));background-image:linear-gradient(to right,rgba(0,0,0,0.0001) 0,rgba(0,0,0,0.5) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000',endColorstr='#80000000',GradientType=1)}.carousel-control:hover,.carousel-control:focus{color:#fff;text-decoration:none;outline:0;opacity:.9;filter:alpha(opacity=90)}.carousel-control .icon-prev,.carousel-control .icon-next,.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right{position:absolute;top:50%;z-index:5;display:inline-block}.carousel-control .icon-prev,.carousel-control .glyphicon-chevron-left{left:50%}.carousel-control .icon-next,.carousel-control .glyphicon-chevron-right{right:50%}.carousel-control .icon-prev,.carousel-control .icon-next{width:20px;height:20px;margin-top:-10px;margin-left:-10px;font-family:serif}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000 \9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,0.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicons-chevron-left,.carousel-control .glyphicons-chevron-right,.carousel-control .icon-prev,.carousel-control .icon-next{width:30px;height:30px;margin-top:-15px;margin-left:-15px;font-size:30px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.clearfix:before,.clearfix:after{display:table;content:" "}.clearfix:after{clear:both}.clearfix:before,.clearfix:after{display:table;content:" "}.clearfix:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right !important}.pull-left{float:left !important}.hide{display:none !important}.show{display:block !important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none !important;visibility:hidden !important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-xs,tr.visible-xs,th.visible-xs,td.visible-xs{display:none !important}@media(max-width:767px){.visible-xs{display:block !important}table.visible-xs{display:table}tr.visible-xs{display:table-row !important}th.visible-xs,td.visible-xs{display:table-cell !important}}@media(min-width:768px) and (max-width:991px){.visible-xs.visible-sm{display:block !important}table.visible-xs.visible-sm{display:table}tr.visible-xs.visible-sm{display:table-row !important}th.visible-xs.visible-sm,td.visible-xs.visible-sm{display:table-cell !important}}@media(min-width:992px) and (max-width:1199px){.visible-xs.visible-md{display:block !important}table.visible-xs.visible-md{display:table}tr.visible-xs.visible-md{display:table-row !important}th.visible-xs.visible-md,td.visible-xs.visible-md{display:table-cell !important}}@media(min-width:1200px){.visible-xs.visible-lg{display:block !important}table.visible-xs.visible-lg{display:table}tr.visible-xs.visible-lg{display:table-row !important}th.visible-xs.visible-lg,td.visible-xs.visible-lg{display:table-cell !important}}.visible-sm,tr.visible-sm,th.visible-sm,td.visible-sm{display:none !important}@media(max-width:767px){.visible-sm.visible-xs{display:block !important}table.visible-sm.visible-xs{display:table}tr.visible-sm.visible-xs{display:table-row !important}th.visible-sm.visible-xs,td.visible-sm.visible-xs{display:table-cell !important}}@media(min-width:768px) and (max-width:991px){.visible-sm{display:block !important}table.visible-sm{display:table}tr.visible-sm{display:table-row !important}th.visible-sm,td.visible-sm{display:table-cell !important}}@media(min-width:992px) and (max-width:1199px){.visible-sm.visible-md{display:block !important}table.visible-sm.visible-md{display:table}tr.visible-sm.visible-md{display:table-row !important}th.visible-sm.visible-md,td.visible-sm.visible-md{display:table-cell !important}}@media(min-width:1200px){.visible-sm.visible-lg{display:block !important}table.visible-sm.visible-lg{display:table}tr.visible-sm.visible-lg{display:table-row !important}th.visible-sm.visible-lg,td.visible-sm.visible-lg{display:table-cell !important}}.visible-md,tr.visible-md,th.visible-md,td.visible-md{display:none !important}@media(max-width:767px){.visible-md.visible-xs{display:block !important}table.visible-md.visible-xs{display:table}tr.visible-md.visible-xs{display:table-row !important}th.visible-md.visible-xs,td.visible-md.visible-xs{display:table-cell !important}}@media(min-width:768px) and (max-width:991px){.visible-md.visible-sm{display:block !important}table.visible-md.visible-sm{display:table}tr.visible-md.visible-sm{display:table-row !important}th.visible-md.visible-sm,td.visible-md.visible-sm{display:table-cell !important}}@media(min-width:992px) and (max-width:1199px){.visible-md{display:block !important}table.visible-md{display:table}tr.visible-md{display:table-row !important}th.visible-md,td.visible-md{display:table-cell !important}}@media(min-width:1200px){.visible-md.visible-lg{display:block !important}table.visible-md.visible-lg{display:table}tr.visible-md.visible-lg{display:table-row !important}th.visible-md.visible-lg,td.visible-md.visible-lg{display:table-cell !important}}.visible-lg,tr.visible-lg,th.visible-lg,td.visible-lg{display:none !important}@media(max-width:767px){.visible-lg.visible-xs{display:block !important}table.visible-lg.visible-xs{display:table}tr.visible-lg.visible-xs{display:table-row !important}th.visible-lg.visible-xs,td.visible-lg.visible-xs{display:table-cell !important}}@media(min-width:768px) and (max-width:991px){.visible-lg.visible-sm{display:block !important}table.visible-lg.visible-sm{display:table}tr.visible-lg.visible-sm{display:table-row !important}th.visible-lg.visible-sm,td.visible-lg.visible-sm{display:table-cell !important}}@media(min-width:992px) and (max-width:1199px){.visible-lg.visible-md{display:block !important}table.visible-lg.visible-md{display:table}tr.visible-lg.visible-md{display:table-row !important}th.visible-lg.visible-md,td.visible-lg.visible-md{display:table-cell !important}}@media(min-width:1200px){.visible-lg{display:block !important}table.visible-lg{display:table}tr.visible-lg{display:table-row !important}th.visible-lg,td.visible-lg{display:table-cell !important}}.hidden-xs{display:block !important}table.hidden-xs{display:table}tr.hidden-xs{display:table-row !important}th.hidden-xs,td.hidden-xs{display:table-cell !important}@media(max-width:767px){.hidden-xs,tr.hidden-xs,th.hidden-xs,td.hidden-xs{display:none !important}}@media(min-width:768px) and (max-width:991px){.hidden-xs.hidden-sm,tr.hidden-xs.hidden-sm,th.hidden-xs.hidden-sm,td.hidden-xs.hidden-sm{display:none !important}}@media(min-width:992px) and (max-width:1199px){.hidden-xs.hidden-md,tr.hidden-xs.hidden-md,th.hidden-xs.hidden-md,td.hidden-xs.hidden-md{display:none !important}}@media(min-width:1200px){.hidden-xs.hidden-lg,tr.hidden-xs.hidden-lg,th.hidden-xs.hidden-lg,td.hidden-xs.hidden-lg{display:none !important}}.hidden-sm{display:block !important}table.hidden-sm{display:table}tr.hidden-sm{display:table-row !important}th.hidden-sm,td.hidden-sm{display:table-cell !important}@media(max-width:767px){.hidden-sm.hidden-xs,tr.hidden-sm.hidden-xs,th.hidden-sm.hidden-xs,td.hidden-sm.hidden-xs{display:none !important}}@media(min-width:768px) and (max-width:991px){.hidden-sm,tr.hidden-sm,th.hidden-sm,td.hidden-sm{display:none !important}}@media(min-width:992px) and (max-width:1199px){.hidden-sm.hidden-md,tr.hidden-sm.hidden-md,th.hidden-sm.hidden-md,td.hidden-sm.hidden-md{display:none !important}}@media(min-width:1200px){.hidden-sm.hidden-lg,tr.hidden-sm.hidden-lg,th.hidden-sm.hidden-lg,td.hidden-sm.hidden-lg{display:none !important}}.hidden-md{display:block !important}table.hidden-md{display:table}tr.hidden-md{display:table-row !important}th.hidden-md,td.hidden-md{display:table-cell !important}@media(max-width:767px){.hidden-md.hidden-xs,tr.hidden-md.hidden-xs,th.hidden-md.hidden-xs,td.hidden-md.hidden-xs{display:none !important}}@media(min-width:768px) and (max-width:991px){.hidden-md.hidden-sm,tr.hidden-md.hidden-sm,th.hidden-md.hidden-sm,td.hidden-md.hidden-sm{display:none !important}}@media(min-width:992px) and (max-width:1199px){.hidden-md,tr.hidden-md,th.hidden-md,td.hidden-md{display:none !important}}@media(min-width:1200px){.hidden-md.hidden-lg,tr.hidden-md.hidden-lg,th.hidden-md.hidden-lg,td.hidden-md.hidden-lg{display:none !important}}.hidden-lg{display:block !important}table.hidden-lg{display:table}tr.hidden-lg{display:table-row !important}th.hidden-lg,td.hidden-lg{display:table-cell !important}@media(max-width:767px){.hidden-lg.hidden-xs,tr.hidden-lg.hidden-xs,th.hidden-lg.hidden-xs,td.hidden-lg.hidden-xs{display:none !important}}@media(min-width:768px) and (max-width:991px){.hidden-lg.hidden-sm,tr.hidden-lg.hidden-sm,th.hidden-lg.hidden-sm,td.hidden-lg.hidden-sm{display:none !important}}@media(min-width:992px) and (max-width:1199px){.hidden-lg.hidden-md,tr.hidden-lg.hidden-md,th.hidden-lg.hidden-md,td.hidden-lg.hidden-md{display:none !important}}@media(min-width:1200px){.hidden-lg,tr.hidden-lg,th.hidden-lg,td.hidden-lg{display:none !important}}.visible-print,tr.visible-print,th.visible-print,td.visible-print{display:none !important}@media print{.visible-print{display:block !important}table.visible-print{display:table}tr.visible-print{display:table-row !important}th.visible-print,td.visible-print{display:table-cell !important}.hidden-print,tr.hidden-print,th.hidden-print,td.hidden-print{display:none !important}}.navbar{font-size:13px;font-weight:300;border:0}.navbar .navbar-toggle:hover .icon-bar{background-color:#b3b3b3}.navbar-collapse{border-top-color:rgba(0,0,0,0.2);-webkit-box-shadow:none;box-shadow:none}.navbar .dropdown-menu{border:0}.navbar .dropdown-menu>li>a,.navbar .dropdown-menu>li>a:focus{font-size:13px;font-weight:300;background-color:transparent}.navbar .dropdown-header{color:rgba(255,255,255,0.5)}.navbar-default .dropdown-menu{background-color:#333}.navbar-default .dropdown-menu>li>a,.navbar-default .dropdown-menu>li>a:focus{color:#fff}.navbar-default .dropdown-menu>li>a:hover,.navbar-default .dropdown-menu>.active>a,.navbar-default .dropdown-menu>.active>a:hover{background-color:#272727}.navbar-inverse .dropdown-menu{background-color:#008cba}.navbar-inverse .dropdown-menu>li>a,.navbar-inverse .dropdown-menu>li>a:focus{color:#fff}.navbar-inverse .dropdown-menu>li>a:hover,.navbar-inverse .dropdown-menu>.active>a,.navbar-inverse .dropdown-menu>.active>a:hover{background-color:#006687}.btn{padding:14px 28px}.btn-lg{padding:16px 32px}.btn-sm{padding:8px 16px}.btn-xs{padding:4px 8px}.btn-group .btn~.dropdown-toggle{padding-right:16px;padding-left:16px}.btn-group .dropdown-menu{border-top-width:0}.btn-group.dropup .dropdown-menu{margin-bottom:0;border-top-width:1px;border-bottom-width:0}.btn-group .dropdown-toggle.btn-default~.dropdown-menu{background-color:#e7e7e7;border-color:#dadada}.btn-group .dropdown-toggle.btn-default~.dropdown-menu>li>a{color:#333}.btn-group .dropdown-toggle.btn-default~.dropdown-menu>li>a:hover{background-color:#d3d3d3}.btn-group .dropdown-toggle.btn-primary~.dropdown-menu{background-color:#008cba;border-color:#0079a1}.btn-group .dropdown-toggle.btn-primary~.dropdown-menu>li>a{color:#fff}.btn-group .dropdown-toggle.btn-primary~.dropdown-menu>li>a:hover{background-color:#006d91}.btn-group .dropdown-toggle.btn-success~.dropdown-menu{background-color:#43ac6a;border-color:#3c9a5f}.btn-group .dropdown-toggle.btn-success~.dropdown-menu>li>a{color:#fff}.btn-group .dropdown-toggle.btn-success~.dropdown-menu>li>a:hover{background-color:#388f58}.btn-group .dropdown-toggle.btn-info~.dropdown-menu{background-color:#5bc0de;border-color:#46b8da}.btn-group .dropdown-toggle.btn-info~.dropdown-menu>li>a{color:#fff}.btn-group .dropdown-toggle.btn-info~.dropdown-menu>li>a:hover{background-color:#39b3d7}.btn-group .dropdown-toggle.btn-warning~.dropdown-menu{background-color:#e99002;border-color:#d08002}.btn-group .dropdown-toggle.btn-warning~.dropdown-menu>li>a{color:#fff}.btn-group .dropdown-toggle.btn-warning~.dropdown-menu>li>a:hover{background-color:#c17702}.btn-group .dropdown-toggle.btn-danger~.dropdown-menu{background-color:#f04124;border-color:#ea2f10}.btn-group .dropdown-toggle.btn-danger~.dropdown-menu>li>a{color:#fff}.btn-group .dropdown-toggle.btn-danger~.dropdown-menu>li>a:hover{background-color:#dc2c0f}.lead{color:#6f6f6f}cite{font-style:italic}blockquote{color:#6f6f6f;border-left-width:1px}blockquote.pull-right{border-right-width:1px}blockquote small{font-size:12px;font-weight:300}table{font-size:12px}input,.form-control{padding:7px;font-size:12px}label,.control-label,.help-block,.checkbox,.radio{font-size:12px;font-weight:normal}.form-group .btn,.input-group-addon,.input-group-btn .btn{padding:8px 14px;font-size:12px}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{border-color:transparent}.nav-tabs>li>a{color:#222;background-color:#e7e7e7}.nav-tabs .caret{border-top-color:#222;border-bottom-color:#222}.nav-pills{font-weight:300}.breadcrumb{font-size:10px;font-weight:300;text-transform:uppercase;border:1px solid #ddd;border-radius:3px}.pagination{font-size:12px;font-weight:300;color:#999}.pagination>li>a,.pagination>li>span{margin-left:4px;color:#999}.pagination>.active>a,.pagination>.active>span{color:#fff}.pagination>li>a,.pagination>li:first-child>a,.pagination>li:last-child>a,.pagination>li>span,.pagination>li:first-child>span,.pagination>li:last-child>span{border-radius:3px}.pagination-lg>li>a{padding-right:22px;padding-left:22px}.pagination-sm>li>a{padding:0 5px}.pager{font-size:12px;font-weight:300;color:#999}.list-group{font-size:12px;font-weight:300}.label{padding-right:1em;padding-left:1em;font-weight:300;border-radius:0}.label-default{color:#333;background-color:#e7e7e7}.badge{font-weight:300}.progress{height:22px;padding:2px;background-color:#f6f6f6;border:1px solid #ccc;-webkit-box-shadow:none;box-shadow:none}.dropdown-menu{padding:0;margin-top:0;font-size:12px}.dropdown-menu>li>a{padding:12px 15px}.dropdown-header{padding-right:15px;padding-left:15px;font-size:9px;text-transform:uppercase}.popover{font-size:12px;font-weight:300;color:#fff}.panel-heading,.panel-footer{border-top-right-radius:0;border-top-left-radius:0}.clearfix:before,.clearfix:after{display:table;content:" "}.clearfix:after{clear:both}.clearfix:before,.clearfix:after{display:table;content:" "}.clearfix:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right !important}.pull-left{float:left !important}.hide{display:none !important}.show{display:block !important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none !important;visibility:hidden !important}.affix{position:fixed} diff --git a/cinder/css/cinder.css b/cinder/css/cinder.css new file mode 100644 index 00000000..48345605 --- /dev/null +++ b/cinder/css/cinder.css @@ -0,0 +1,88 @@ +/* + Cinder Theme for MkDocs | Copyright 2015 Christopher Simpkins | MIT License +*/ + +body { + font-family:"Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 16px; + line-height: 1.7; + background-color: #FFF; + color: #343838; +} +h1, h2, h3, h4, h5, h6 { + font-family:'Inter', 'Helvetica Neue', Helvetica, Arial, sans-serif; + color: #222; +} +h1 small, h2 small, h3 small, h4 small, h5 small, h6 small, .h1 small, .h2 small, .h3 small, .h4 small, .h5 small, .h6 small, h1 .small, h2 .small, h3 .small, h4 .small, h5 .small, h6 .small, .h1 .small, .h2 .small, .h3 .small, .h4 .small, .h5 .small, .h6 .small { + color: #B1B7B9; +} + +h2 { + margin-top: 35px; +} + +h1, h2 { + font-weight: 700; +} +h4 { + font-family: 'Inter', 'Helvetica Neue', Helvetica, Arial, sans-serif; + font-weight: 300; + margin-top: 20px; + font-style: italic; +} +h5 { + font-family: 'Inter', 'Helvetica Neue', Helvetica, Arial, sans-serif; + font-weight: 300; + font-variant: small-caps; +} +pre, code { + background-color: #FCFDFF; +} +pre>code { + font-size: 13px; +} +pre { + margin-top: 25px; + margin-bottom: 25px; +} +.lead { + font-family:"Inter", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: 400; + line-height: 1.4; + letter-spacing: 0.0312em; + color: #B1B7B9; +} +.navbar-default { + background-color: #343838; + border-bottom: 8px #EBF2F2 solid; +} +.bs-sidenav { + background-image: url("../img/grid11.png"); + background-repeat: repeat; + font-family: Inter,"Helvetica Neue",Helvetica,Arial,sans-serif; + font-size: 13px; +} +.well { + background-color: #FCFDFF; +} +.btn-default { + background-color:#FCFDFF; +} +.table-striped > tbody > tr:nth-child(2n+1) > td, .table-striped > tbody > tr:nth-child(2n+1) > th { + background-color: #FCFDFF; +} +#mkdocs-search-query:focus { + outline: none; + -webkit-box-shadow: none; + box-shadow: none; +} +#mkdocs-search-query { + font-family:"Inter", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 20px; + font-weight: 700; + color: #343838; + height: 45px; +} +footer > hr { + width: 35%; +} diff --git a/cinder/css/cinder.min.css b/cinder/css/cinder.min.css new file mode 100644 index 00000000..fb7cc34f --- /dev/null +++ b/cinder/css/cinder.min.css @@ -0,0 +1 @@ +body{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:16px;line-height:1.7;background-color:#FFF;color:#343838}h1,h2,h3,h4,h5,h6{font-family:'Inter','Helvetica Neue',Helvetica,Arial,sans-serif;color:#222}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small,h1 .small,h2 .small,h3 .small,h4 .small,h5 .small,h6 .small,.h1 .small,.h2 .small,.h3 .small,.h4 .small,.h5 .small,.h6 .small{color:#b1b7b9}h2{margin-top:35px}h1,h2{font-weight:700}h4{font-family:'Inter','Helvetica Neue',Helvetica,Arial,sans-serif;font-weight:300;margin-top:20px;font-style:italic}h5{font-family:'Inter','Helvetica Neue',Helvetica,Arial,sans-serif;font-weight:300;font-variant:small-caps}pre,code{background-color:#fcfdff}pre>code{font-size:13px}pre{margin-top:25px;margin-bottom:25px}.lead{font-family:"Inter","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:400;line-height:1.4;letter-spacing:.0312em;color:#b1b7b9}.navbar-default{background-color:#343838;border-bottom:8px #ebf2f2 solid}.bs-sidenav{background-image:url("../img/grid11.png");background-repeat:repeat;font-family:Inter,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px}.well{background-color:#fcfdff}.btn-default{background-color:#fcfdff}.table-striped>tbody>tr:nth-child(2n+1)>td,.table-striped>tbody>tr:nth-child(2n+1)>th{background-color:#fcfdff}#mkdocs-search-query:focus{outline:0;-webkit-box-shadow:none;box-shadow:none}#mkdocs-search-query{font-family:"Inter","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:20px;font-weight:700;color:#343838;height:45px}footer>hr{width:35%} diff --git a/cinder/css/highlight.css b/cinder/css/highlight.css new file mode 100644 index 00000000..a2b9270e --- /dev/null +++ b/cinder/css/highlight.css @@ -0,0 +1,99 @@ +/* + +github.com style (c) Vasily Polovnyov + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + color: #333; + background: #FCFDFF; +} + +.hljs-comment, +.hljs-quote { + color: #998; + font-style: italic; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-subst { + color: #333; + font-weight: bold; +} + +.hljs-number, +.hljs-literal, +.hljs-variable, +.hljs-template-variable, +.hljs-tag .hljs-attr { + color: #008080; +} + +.hljs-string, +.hljs-doctag { + color: #d14; +} + +.hljs-title, +.hljs-section, +.hljs-selector-id { + color: #900; + font-weight: bold; +} + +.hljs-subst { + font-weight: normal; +} + +.hljs-type, +.hljs-class .hljs-title { + color: #458; + font-weight: bold; +} + +.hljs-tag, +.hljs-name, +.hljs-attribute { + color: #000080; + font-weight: normal; +} + +.hljs-regexp, +.hljs-link { + color: #009926; +} + +.hljs-symbol, +.hljs-bullet { + color: #990073; +} + +.hljs-built_in, +.hljs-builtin-name { + color: #0086b3; +} + +.hljs-meta { + color: #999; + font-weight: bold; +} + +.hljs-deletion { + background: #fdd; +} + +.hljs-addition { + background: #dfd; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/cinder/css/highlight.min.css b/cinder/css/highlight.min.css new file mode 100644 index 00000000..1b6ab941 --- /dev/null +++ b/cinder/css/highlight.min.css @@ -0,0 +1 @@ +.hljs{display:block;overflow-x:auto;padding:.5em;color:#333;background:#fcfdff}.hljs-comment,.hljs-quote{color:#998;font-style:italic}.hljs-keyword,.hljs-selector-tag,.hljs-subst{color:#333;font-weight:bold}.hljs-number,.hljs-literal,.hljs-variable,.hljs-template-variable,.hljs-tag .hljs-attr{color:teal}.hljs-string,.hljs-doctag{color:#d14}.hljs-title,.hljs-section,.hljs-selector-id{color:#900;font-weight:bold}.hljs-subst{font-weight:normal}.hljs-type,.hljs-class .hljs-title{color:#458;font-weight:bold}.hljs-tag,.hljs-name,.hljs-attribute{color:navy;font-weight:normal}.hljs-regexp,.hljs-link{color:#009926}.hljs-symbol,.hljs-bullet{color:#990073}.hljs-built_in,.hljs-builtin-name{color:#0086b3}.hljs-meta{color:#999;font-weight:bold}.hljs-deletion{background:#fdd}.hljs-addition{background:#dfd}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:bold} diff --git a/cinder/fonts/fontawesome-webfont.eot b/cinder/fonts/fontawesome-webfont.eot new file mode 100755 index 00000000..7c79c6a6 Binary files /dev/null and b/cinder/fonts/fontawesome-webfont.eot differ diff --git a/cinder/fonts/fontawesome-webfont.svg b/cinder/fonts/fontawesome-webfont.svg new file mode 100755 index 00000000..45fdf338 --- /dev/null +++ b/cinder/fonts/fontawesome-webfont.svg @@ -0,0 +1,414 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/cinder/fonts/fontawesome-webfont.ttf b/cinder/fonts/fontawesome-webfont.ttf new file mode 100755 index 00000000..e89738de Binary files /dev/null and b/cinder/fonts/fontawesome-webfont.ttf differ diff --git a/cinder/fonts/fontawesome-webfont.woff b/cinder/fonts/fontawesome-webfont.woff new file mode 100755 index 00000000..8c1748aa Binary files /dev/null and b/cinder/fonts/fontawesome-webfont.woff differ diff --git a/cinder/img/favicon.ico b/cinder/img/favicon.ico new file mode 100644 index 00000000..e85006a3 Binary files /dev/null and b/cinder/img/favicon.ico differ diff --git a/cinder/img/grid1.png b/cinder/img/grid1.png new file mode 100644 index 00000000..a6c493ab Binary files /dev/null and b/cinder/img/grid1.png differ diff --git a/cinder/img/grid10.png b/cinder/img/grid10.png new file mode 100644 index 00000000..7c41953e Binary files /dev/null and b/cinder/img/grid10.png differ diff --git a/cinder/img/grid11.png b/cinder/img/grid11.png new file mode 100644 index 00000000..ef37b27e Binary files /dev/null and b/cinder/img/grid11.png differ diff --git a/cinder/img/grid12.png b/cinder/img/grid12.png new file mode 100644 index 00000000..3f100c41 Binary files /dev/null and b/cinder/img/grid12.png differ diff --git a/cinder/img/grid13.png b/cinder/img/grid13.png new file mode 100644 index 00000000..1a0d83f3 Binary files /dev/null and b/cinder/img/grid13.png differ diff --git a/cinder/img/grid14.png b/cinder/img/grid14.png new file mode 100644 index 00000000..deabc036 Binary files /dev/null and b/cinder/img/grid14.png differ diff --git a/cinder/img/grid15.png b/cinder/img/grid15.png new file mode 100644 index 00000000..1f0417a5 Binary files /dev/null and b/cinder/img/grid15.png differ diff --git a/cinder/img/grid16.png b/cinder/img/grid16.png new file mode 100644 index 00000000..984454f4 Binary files /dev/null and b/cinder/img/grid16.png differ diff --git a/cinder/img/grid17.png b/cinder/img/grid17.png new file mode 100644 index 00000000..fe48c9dd Binary files /dev/null and b/cinder/img/grid17.png differ diff --git a/cinder/img/grid18.png b/cinder/img/grid18.png new file mode 100644 index 00000000..3c84524b Binary files /dev/null and b/cinder/img/grid18.png differ diff --git a/cinder/img/grid19.png b/cinder/img/grid19.png new file mode 100644 index 00000000..2bfdd500 Binary files /dev/null and b/cinder/img/grid19.png differ diff --git a/cinder/img/grid2.png b/cinder/img/grid2.png new file mode 100644 index 00000000..c9eed3e9 Binary files /dev/null and b/cinder/img/grid2.png differ diff --git a/cinder/img/grid20.png b/cinder/img/grid20.png new file mode 100644 index 00000000..30e3faea Binary files /dev/null and b/cinder/img/grid20.png differ diff --git a/cinder/img/grid3.png b/cinder/img/grid3.png new file mode 100644 index 00000000..4617c9d9 Binary files /dev/null and b/cinder/img/grid3.png differ diff --git a/cinder/img/grid4.png b/cinder/img/grid4.png new file mode 100644 index 00000000..2a1f1801 Binary files /dev/null and b/cinder/img/grid4.png differ diff --git a/cinder/img/grid5.png b/cinder/img/grid5.png new file mode 100644 index 00000000..a1d710e0 Binary files /dev/null and b/cinder/img/grid5.png differ diff --git a/cinder/img/grid6.png b/cinder/img/grid6.png new file mode 100644 index 00000000..71b4148d Binary files /dev/null and b/cinder/img/grid6.png differ diff --git a/cinder/img/grid7.png b/cinder/img/grid7.png new file mode 100644 index 00000000..6044a419 Binary files /dev/null and b/cinder/img/grid7.png differ diff --git a/cinder/img/grid8.png b/cinder/img/grid8.png new file mode 100644 index 00000000..a4b6d44e Binary files /dev/null and b/cinder/img/grid8.png differ diff --git a/cinder/img/grid9.png b/cinder/img/grid9.png new file mode 100644 index 00000000..627dda51 Binary files /dev/null and b/cinder/img/grid9.png differ diff --git a/cinder/js/base.js b/cinder/js/base.js new file mode 100644 index 00000000..1db589ca --- /dev/null +++ b/cinder/js/base.js @@ -0,0 +1,225 @@ +function getSearchTerm() { + var sPageURL = window.location.search.substring(1); + var sURLVariables = sPageURL.split('&'); + for (var i = 0; i < sURLVariables.length; i++) { + var sParameterName = sURLVariables[i].split('='); + if (sParameterName[0] == 'q') { + return sParameterName[1]; + } + } +} + +$(document).ready(function() { + /** + * ------------------------------------------------------------------------ + * Taken from themes/mkdocs/js/base.js + * ------------------------------------------------------------------------ + */ + var search_term = getSearchTerm(), + $search_modal = $('#mkdocs_search_modal'), + $keyboard_modal = $('#mkdocs_keyboard_modal'); + + if (search_term) { + $search_modal.modal(); + } + + // make sure search input gets autofocus everytime modal opens. + $search_modal.on('shown.bs.modal', function() { + $search_modal.find('#mkdocs-search-query').focus(); + }); + + // Close search modal when result is selected + // The links get added later so listen to parent + $('#mkdocs-search-results').click(function(e) { + if ($(e.target).is('a')) { + $search_modal.modal('hide'); + } + }); + + if (typeof shortcuts !== 'undefined') { + // Populate keyboard modal with proper Keys + $keyboard_modal.find('.help.shortcut kbd')[0].innerHTML = keyCodes[shortcuts.help]; + $keyboard_modal.find('.prev.shortcut kbd')[0].innerHTML = keyCodes[shortcuts.previous]; + $keyboard_modal.find('.next.shortcut kbd')[0].innerHTML = keyCodes[shortcuts.next]; + $keyboard_modal.find('.search.shortcut kbd')[0].innerHTML = keyCodes[shortcuts.search]; + + // Keyboard navigation + document.addEventListener("keydown", function(e) { + if ($(e.target).is(':input')) return true; + var key = e.which || e.key || window.event && window.event.key; + var page; + switch (key) { + case shortcuts.next: + page = $('.navbar a[rel="next"]:first').prop('href'); + break; + case shortcuts.previous: + page = $('.navbar a[rel="prev"]:first').prop('href'); + break; + case shortcuts.search: + e.preventDefault(); + $keyboard_modal.modal('hide'); + $search_modal.modal('show'); + $search_modal.find('#mkdocs-search-query').focus(); + break; + case shortcuts.help: + $search_modal.modal('hide'); + $keyboard_modal.modal('show'); + break; + default: + break; + } + if (page) { + $keyboard_modal.modal('hide'); + window.location.href = page; + } + }); + } + + $('table').addClass('table table-striped table-hover'); + + // Improve the scrollspy behaviour when users click on a TOC item. + $(".bs-sidenav a").on("click", function() { + var clicked = this; + setTimeout(function() { + var active = $('.nav li.active a'); + active = active[active.length - 1]; + if (clicked !== active) { + $(active).parent().removeClass("active"); + $(clicked).parent().addClass("active"); + } + }, 50); + }); +}); + + +/** + * ------------------------------------------------------------------------ + * Taken from themes/mkdocs/js/base.js + * ------------------------------------------------------------------------ + */ + +$('body').scrollspy({ + target: '.bs-sidebar', + offset: 100 +}); + +/* Prevent disabled links from causing a page reload */ +$("li.disabled a").click(function() { + event.preventDefault(); +}); + +// See https://www.cambiaresearch.com/articles/15/javascript-char-codes-key-codes +// We only list common keys below. Obscure keys are omited and their use is discouraged. +var keyCodes = { + 8: 'backspace', + 9: 'tab', + 13: 'enter', + 16: 'shift', + 17: 'ctrl', + 18: 'alt', + 19: 'pause/break', + 20: 'caps lock', + 27: 'escape', + 32: 'spacebar', + 33: 'page up', + 34: 'page down', + 35: 'end', + 36: 'home', + 37: '←', + 38: '↑', + 39: '→', + 40: '↓', + 45: 'insert', + 46: 'delete', + 48: '0', + 49: '1', + 50: '2', + 51: '3', + 52: '4', + 53: '5', + 54: '6', + 55: '7', + 56: '8', + 57: '9', + 65: 'a', + 66: 'b', + 67: 'c', + 68: 'd', + 69: 'e', + 70: 'f', + 71: 'g', + 72: 'h', + 73: 'i', + 74: 'j', + 75: 'k', + 76: 'l', + 77: 'm', + 78: 'n', + 79: 'o', + 80: 'p', + 81: 'q', + 82: 'r', + 83: 's', + 84: 't', + 85: 'u', + 86: 'v', + 87: 'w', + 88: 'x', + 89: 'y', + 90: 'z', + 91: 'Left Windows Key / Left ⌘', + 92: 'Right Windows Key', + 93: 'Windows Menu / Right ⌘', + 96: 'numpad 0', + 97: 'numpad 1', + 98: 'numpad 2', + 99: 'numpad 3', + 100: 'numpad 4', + 101: 'numpad 5', + 102: 'numpad 6', + 103: 'numpad 7', + 104: 'numpad 8', + 105: 'numpad 9', + 106: 'multiply', + 107: 'add', + 109: 'subtract', + 110: 'decimal point', + 111: 'divide', + 112: 'f1', + 113: 'f2', + 114: 'f3', + 115: 'f4', + 116: 'f5', + 117: 'f6', + 118: 'f7', + 119: 'f8', + 120: 'f9', + 121: 'f10', + 122: 'f11', + 123: 'f12', + 124: 'f13', + 125: 'f14', + 126: 'f15', + 127: 'f16', + 128: 'f17', + 129: 'f18', + 130: 'f19', + 131: 'f20', + 132: 'f21', + 133: 'f22', + 134: 'f23', + 135: 'f24', + 144: 'num lock', + 145: 'scroll lock', + 186: ';', + 187: '=', + 188: ',', + 189: '‐', + 190: '.', + 191: '?', + 192: '`', + 219: '[', + 220: '\', + 221: ']', + 222: ''', +}; diff --git a/cinder/js/bootstrap-3.0.3.min.js b/cinder/js/bootstrap-3.0.3.min.js new file mode 100644 index 00000000..1a6258ef --- /dev/null +++ b/cinder/js/bootstrap-3.0.3.min.js @@ -0,0 +1,7 @@ +/*! + * Bootstrap v3.0.3 (http://getbootstrap.com) + * Copyright 2013 Twitter, Inc. + * Licensed under http://www.apache.org/licenses/LICENSE-2.0 + */ + +if("undefined"==typeof jQuery)throw new Error("Bootstrap requires jQuery");+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]}}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one(a.support.transition.end,function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b()})}(jQuery),+function(a){"use strict";var b='[data-dismiss="alert"]',c=function(c){a(c).on("click",b,this.close)};c.prototype.close=function(b){function c(){f.trigger("closed.bs.alert").remove()}var d=a(this),e=d.attr("data-target");e||(e=d.attr("href"),e=e&&e.replace(/.*(?=#[^\s]*$)/,""));var f=a(e);b&&b.preventDefault(),f.length||(f=d.hasClass("alert")?d:d.parent()),f.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(f.removeClass("in"),a.support.transition&&f.hasClass("fade")?f.one(a.support.transition.end,c).emulateTransitionEnd(150):c())};var d=a.fn.alert;a.fn.alert=function(b){return this.each(function(){var d=a(this),e=d.data("bs.alert");e||d.data("bs.alert",e=new c(this)),"string"==typeof b&&e[b].call(d)})},a.fn.alert.Constructor=c,a.fn.alert.noConflict=function(){return a.fn.alert=d,this},a(document).on("click.bs.alert.data-api",b,c.prototype.close)}(jQuery),+function(a){"use strict";var b=function(c,d){this.$element=a(c),this.options=a.extend({},b.DEFAULTS,d)};b.DEFAULTS={loadingText:"loading..."},b.prototype.setState=function(a){var b="disabled",c=this.$element,d=c.is("input")?"val":"html",e=c.data();a+="Text",e.resetText||c.data("resetText",c[d]()),c[d](e[a]||this.options[a]),setTimeout(function(){"loadingText"==a?c.addClass(b).attr(b,b):c.removeClass(b).removeAttr(b)},0)},b.prototype.toggle=function(){var a=this.$element.closest('[data-toggle="buttons"]'),b=!0;if(a.length){var c=this.$element.find("input");"radio"===c.prop("type")&&(c.prop("checked")&&this.$element.hasClass("active")?b=!1:a.find(".active").removeClass("active")),b&&c.prop("checked",!this.$element.hasClass("active")).trigger("change")}b&&this.$element.toggleClass("active")};var c=a.fn.button;a.fn.button=function(c){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof c&&c;e||d.data("bs.button",e=new b(this,f)),"toggle"==c?e.toggle():c&&e.setState(c)})},a.fn.button.Constructor=b,a.fn.button.noConflict=function(){return a.fn.button=c,this},a(document).on("click.bs.button.data-api","[data-toggle^=button]",function(b){var c=a(b.target);c.hasClass("btn")||(c=c.closest(".btn")),c.button("toggle"),b.preventDefault()})}(jQuery),+function(a){"use strict";var b=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=this.sliding=this.interval=this.$active=this.$items=null,"hover"==this.options.pause&&this.$element.on("mouseenter",a.proxy(this.pause,this)).on("mouseleave",a.proxy(this.cycle,this))};b.DEFAULTS={interval:5e3,pause:"hover",wrap:!0},b.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},b.prototype.getActiveIndex=function(){return this.$active=this.$element.find(".item.active"),this.$items=this.$active.parent().children(),this.$items.index(this.$active)},b.prototype.to=function(b){var c=this,d=this.getActiveIndex();return b>this.$items.length-1||0>b?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){c.to(b)}):d==b?this.pause().cycle():this.slide(b>d?"next":"prev",a(this.$items[b]))},b.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition.end&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},b.prototype.next=function(){return this.sliding?void 0:this.slide("next")},b.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},b.prototype.slide=function(b,c){var d=this.$element.find(".item.active"),e=c||d[b](),f=this.interval,g="next"==b?"left":"right",h="next"==b?"first":"last",i=this;if(!e.length){if(!this.options.wrap)return;e=this.$element.find(".item")[h]()}this.sliding=!0,f&&this.pause();var j=a.Event("slide.bs.carousel",{relatedTarget:e[0],direction:g});if(!e.hasClass("active")){if(this.$indicators.length&&(this.$indicators.find(".active").removeClass("active"),this.$element.one("slid.bs.carousel",function(){var b=a(i.$indicators.children()[i.getActiveIndex()]);b&&b.addClass("active")})),a.support.transition&&this.$element.hasClass("slide")){if(this.$element.trigger(j),j.isDefaultPrevented())return;e.addClass(b),e[0].offsetWidth,d.addClass(g),e.addClass(g),d.one(a.support.transition.end,function(){e.removeClass([b,g].join(" ")).addClass("active"),d.removeClass(["active",g].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger("slid.bs.carousel")},0)}).emulateTransitionEnd(600)}else{if(this.$element.trigger(j),j.isDefaultPrevented())return;d.removeClass("active"),e.addClass("active"),this.sliding=!1,this.$element.trigger("slid.bs.carousel")}return f&&this.cycle(),this}};var c=a.fn.carousel;a.fn.carousel=function(c){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},b.DEFAULTS,d.data(),"object"==typeof c&&c),g="string"==typeof c?c:f.slide;e||d.data("bs.carousel",e=new b(this,f)),"number"==typeof c?e.to(c):g?e[g]():f.interval&&e.pause().cycle()})},a.fn.carousel.Constructor=b,a.fn.carousel.noConflict=function(){return a.fn.carousel=c,this},a(document).on("click.bs.carousel.data-api","[data-slide], [data-slide-to]",function(b){var c,d=a(this),e=a(d.attr("data-target")||(c=d.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"")),f=a.extend({},e.data(),d.data()),g=d.attr("data-slide-to");g&&(f.interval=!1),e.carousel(f),(g=d.attr("data-slide-to"))&&e.data("bs.carousel").to(g),b.preventDefault()}),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var b=a(this);b.carousel(b.data())})})}(jQuery),+function(a){"use strict";var b=function(c,d){this.$element=a(c),this.options=a.extend({},b.DEFAULTS,d),this.transitioning=null,this.options.parent&&(this.$parent=a(this.options.parent)),this.options.toggle&&this.toggle()};b.DEFAULTS={toggle:!0},b.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},b.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b=a.Event("show.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.$parent&&this.$parent.find("> .panel > .in");if(c&&c.length){var d=c.data("bs.collapse");if(d&&d.transitioning)return;c.collapse("hide"),d||c.data("bs.collapse",null)}var e=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[e](0),this.transitioning=1;var f=function(){this.$element.removeClass("collapsing").addClass("in")[e]("auto"),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return f.call(this);var g=a.camelCase(["scroll",e].join("-"));this.$element.one(a.support.transition.end,a.proxy(f,this)).emulateTransitionEnd(350)[e](this.$element[0][g])}}},b.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse").removeClass("in"),this.transitioning=1;var d=function(){this.transitioning=0,this.$element.trigger("hidden.bs.collapse").removeClass("collapsing").addClass("collapse")};return a.support.transition?(this.$element[c](0).one(a.support.transition.end,a.proxy(d,this)).emulateTransitionEnd(350),void 0):d.call(this)}}},b.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()};var c=a.fn.collapse;a.fn.collapse=function(c){return this.each(function(){var d=a(this),e=d.data("bs.collapse"),f=a.extend({},b.DEFAULTS,d.data(),"object"==typeof c&&c);e||d.data("bs.collapse",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.collapse.Constructor=b,a.fn.collapse.noConflict=function(){return a.fn.collapse=c,this},a(document).on("click.bs.collapse.data-api","[data-toggle=collapse]",function(b){var c,d=a(this),e=d.attr("data-target")||b.preventDefault()||(c=d.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,""),f=a(e),g=f.data("bs.collapse"),h=g?"toggle":d.data(),i=d.attr("data-parent"),j=i&&a(i);g&&g.transitioning||(j&&j.find('[data-toggle=collapse][data-parent="'+i+'"]').not(d).addClass("collapsed"),d[f.hasClass("in")?"addClass":"removeClass"]("collapsed")),f.collapse(h)})}(jQuery),+function(a){"use strict";function b(){a(d).remove(),a(e).each(function(b){var d=c(a(this));d.hasClass("open")&&(d.trigger(b=a.Event("hide.bs.dropdown")),b.isDefaultPrevented()||d.removeClass("open").trigger("hidden.bs.dropdown"))})}function c(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}var d=".dropdown-backdrop",e="[data-toggle=dropdown]",f=function(b){a(b).on("click.bs.dropdown",this.toggle)};f.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=c(e),g=f.hasClass("open");if(b(),!g){if("ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(''}),b.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),b.prototype.constructor=b,b.prototype.getDefaults=function(){return b.DEFAULTS},b.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content")[this.options.html?"html":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},b.prototype.hasContent=function(){return this.getTitle()||this.getContent()},b.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},b.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")},b.prototype.tip=function(){return this.$tip||(this.$tip=a(this.options.template)),this.$tip};var c=a.fn.popover;a.fn.popover=function(c){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof c&&c;e||d.data("bs.popover",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.popover.Constructor=b,a.fn.popover.noConflict=function(){return a.fn.popover=c,this}}(jQuery),+function(a){"use strict";function b(c,d){var e,f=a.proxy(this.process,this);this.$element=a(c).is("body")?a(window):a(c),this.$body=a("body"),this.$scrollElement=this.$element.on("scroll.bs.scroll-spy.data-api",f),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||(e=a(c).attr("href"))&&e.replace(/.*(?=#[^\s]+$)/,"")||"")+" .nav li > a",this.offsets=a([]),this.targets=a([]),this.activeTarget=null,this.refresh(),this.process()}b.DEFAULTS={offset:10},b.prototype.refresh=function(){var b=this.$element[0]==window?"offset":"position";this.offsets=a([]),this.targets=a([]);var c=this;this.$body.find(this.selector).map(function(){var d=a(this),e=d.data("target")||d.attr("href"),f=/^#\w/.test(e)&&a(e);return f&&f.length&&[[f[b]().top+(!a.isWindow(c.$scrollElement.get(0))&&c.$scrollElement.scrollTop()),e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){c.offsets.push(this[0]),c.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.$scrollElement[0].scrollHeight||this.$body[0].scrollHeight,d=c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(b>=d)return g!=(a=f.last()[0])&&this.activate(a);for(a=e.length;a--;)g!=f[a]&&b>=e[a]&&(!e[a+1]||b<=e[a+1])&&this.activate(f[a])},b.prototype.activate=function(b){this.activeTarget=b,a(this.selector).parents(".active").removeClass("active");var c=this.selector+'[data-target="'+b+'"],'+this.selector+'[href="'+b+'"]',d=a(c).parents("li").addClass("active");d.parent(".dropdown-menu").length&&(d=d.closest("li.dropdown").addClass("active")),d.trigger("activate.bs.scrollspy")};var c=a.fn.scrollspy;a.fn.scrollspy=function(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=c,this},a(window).on("load",function(){a('[data-spy="scroll"]').each(function(){var b=a(this);b.scrollspy(b.data())})})}(jQuery),+function(a){"use strict";var b=function(b){this.element=a(b)};b.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.data("target");if(d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),!b.parent("li").hasClass("active")){var e=c.find(".active:last a")[0],f=a.Event("show.bs.tab",{relatedTarget:e});if(b.trigger(f),!f.isDefaultPrevented()){var g=a(d);this.activate(b.parent("li"),c),this.activate(g,g.parent(),function(){b.trigger({type:"shown.bs.tab",relatedTarget:e})})}}},b.prototype.activate=function(b,c,d){function e(){f.removeClass("active").find("> .dropdown-menu > .active").removeClass("active"),b.addClass("active"),g?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu")&&b.closest("li.dropdown").addClass("active"),d&&d()}var f=c.find("> .active"),g=d&&a.support.transition&&f.hasClass("fade");g?f.one(a.support.transition.end,e).emulateTransitionEnd(150):e(),f.removeClass("in")};var c=a.fn.tab;a.fn.tab=function(c){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new b(this)),"string"==typeof c&&e[c]()})},a.fn.tab.Constructor=b,a.fn.tab.noConflict=function(){return a.fn.tab=c,this},a(document).on("click.bs.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"]',function(b){b.preventDefault(),a(this).tab("show")})}(jQuery),+function(a){"use strict";var b=function(c,d){this.options=a.extend({},b.DEFAULTS,d),this.$window=a(window).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(c),this.affixed=this.unpin=null,this.checkPosition()};b.RESET="affix affix-top affix-bottom",b.DEFAULTS={offset:0},b.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},b.prototype.checkPosition=function(){if(this.$element.is(":visible")){var c=a(document).height(),d=this.$window.scrollTop(),e=this.$element.offset(),f=this.options.offset,g=f.top,h=f.bottom;"object"!=typeof f&&(h=g=f),"function"==typeof g&&(g=f.top()),"function"==typeof h&&(h=f.bottom());var i=null!=this.unpin&&d+this.unpin<=e.top?!1:null!=h&&e.top+this.$element.height()>=c-h?"bottom":null!=g&&g>=d?"top":!1;this.affixed!==i&&(this.unpin&&this.$element.css("top",""),this.affixed=i,this.unpin="bottom"==i?e.top-d:null,this.$element.removeClass(b.RESET).addClass("affix"+(i?"-"+i:"")),"bottom"==i&&this.$element.offset({top:document.body.offsetHeight-h-this.$element.height()}))}};var c=a.fn.affix;a.fn.affix=function(c){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof c&&c;e||d.data("bs.affix",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.affix.Constructor=b,a.fn.affix.noConflict=function(){return a.fn.affix=c,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var b=a(this),c=b.data();c.offset=c.offset||{},c.offsetBottom&&(c.offset.bottom=c.offsetBottom),c.offsetTop&&(c.offset.top=c.offsetTop),b.affix(c)})})}(jQuery); \ No newline at end of file diff --git a/cinder/keyboard-modal.html b/cinder/keyboard-modal.html new file mode 100644 index 00000000..a3640b62 --- /dev/null +++ b/cinder/keyboard-modal.html @@ -0,0 +1,40 @@ + diff --git a/cinder/main.html b/cinder/main.html new file mode 100644 index 00000000..5eabbc28 --- /dev/null +++ b/cinder/main.html @@ -0,0 +1,10 @@ +{% extends "base.html" %} + +{# +The entry point for the MkDocs Theme. + +Any theme customisations should override this file to redefine blocks defined in +the various templates. The custom theme should only need to define a main.html +which `{% extends "base.html" %}` and defines various blocks which will replace +the blocks defined in base.html and its included child templates. +#} \ No newline at end of file diff --git a/cinder/mkdocs_theme.yml b/cinder/mkdocs_theme.yml new file mode 100644 index 00000000..08299469 --- /dev/null +++ b/cinder/mkdocs_theme.yml @@ -0,0 +1,13 @@ +cinder_theme: true + +static_templates: + - 404.html + +include_search_page: false +search_index_only: false + +shortcuts: + help: 191 # ? + next: 78 # n + previous: 80 # p + search: 83 # s diff --git a/cinder/nav-sub.html b/cinder/nav-sub.html new file mode 100644 index 00000000..3578b057 --- /dev/null +++ b/cinder/nav-sub.html @@ -0,0 +1,14 @@ +{% if not nav_item.children %} +
  • + {{ nav_item.title }} +
  • +{% else %} + +{% endif %} diff --git a/cinder/nav.html b/cinder/nav.html new file mode 100644 index 00000000..77a7aaea --- /dev/null +++ b/cinder/nav.html @@ -0,0 +1,109 @@ + diff --git a/cinder/search-modal.html b/cinder/search-modal.html new file mode 100644 index 00000000..b1eddb74 --- /dev/null +++ b/cinder/search-modal.html @@ -0,0 +1,27 @@ + diff --git a/cinder/toc.html b/cinder/toc.html new file mode 100644 index 00000000..26519c56 --- /dev/null +++ b/cinder/toc.html @@ -0,0 +1,13 @@ + \ No newline at end of file diff --git a/docs/reference/core/calculator.md b/docs/reference/core/calculator.md new file mode 100644 index 00000000..dffeeb17 --- /dev/null +++ b/docs/reference/core/calculator.md @@ -0,0 +1 @@ +::: rxn_network.core.calculator \ No newline at end of file diff --git a/docs/reference/core/cost_function.md b/docs/reference/core/cost_function.md new file mode 100644 index 00000000..d982db6f --- /dev/null +++ b/docs/reference/core/cost_function.md @@ -0,0 +1 @@ +::: rxn_network.core.cost_function \ No newline at end of file diff --git a/docs/reference/core/enumerator.md b/docs/reference/core/enumerator.md new file mode 100644 index 00000000..98b10ba9 --- /dev/null +++ b/docs/reference/core/enumerator.md @@ -0,0 +1 @@ +::: rxn_network.core.enumerator \ No newline at end of file diff --git a/docs/reference/core/network.md b/docs/reference/core/network.md new file mode 100644 index 00000000..46266805 --- /dev/null +++ b/docs/reference/core/network.md @@ -0,0 +1 @@ +::: rxn_network.core.network \ No newline at end of file diff --git a/docs/reference/core/pathway.md b/docs/reference/core/pathway.md new file mode 100644 index 00000000..fbe107f4 --- /dev/null +++ b/docs/reference/core/pathway.md @@ -0,0 +1 @@ +::: rxn_network.core.pathway \ No newline at end of file diff --git a/docs/reference/core/reaction.md b/docs/reference/core/reaction.md new file mode 100644 index 00000000..fbd1c609 --- /dev/null +++ b/docs/reference/core/reaction.md @@ -0,0 +1 @@ +::: rxn_network.core.reaction \ No newline at end of file diff --git a/docs/reference/core/solver.md b/docs/reference/core/solver.md new file mode 100644 index 00000000..9e5844be --- /dev/null +++ b/docs/reference/core/solver.md @@ -0,0 +1 @@ +::: rxn_network.core.solver \ No newline at end of file diff --git a/docs/reference/costs/calculators.md b/docs/reference/costs/calculators.md new file mode 100644 index 00000000..6d710786 --- /dev/null +++ b/docs/reference/costs/calculators.md @@ -0,0 +1 @@ +::: rxn_network.costs.calculators \ No newline at end of file diff --git a/docs/reference/costs/softplus.md b/docs/reference/costs/softplus.md new file mode 100644 index 00000000..ede82186 --- /dev/null +++ b/docs/reference/costs/softplus.md @@ -0,0 +1 @@ +::: rxn_network.costs.softplus \ No newline at end of file diff --git a/docs/reference/data/data.md b/docs/reference/data/data.md new file mode 100644 index 00000000..941a886f --- /dev/null +++ b/docs/reference/data/data.md @@ -0,0 +1 @@ +::: rxn_network.data \ No newline at end of file diff --git a/docs/reference/entries/entry_set.md b/docs/reference/entries/entry_set.md new file mode 100644 index 00000000..835f19b7 --- /dev/null +++ b/docs/reference/entries/entry_set.md @@ -0,0 +1 @@ +::: rxn_network.entries.entry_set \ No newline at end of file diff --git a/docs/reference/entries/gibbs.md b/docs/reference/entries/gibbs.md new file mode 100644 index 00000000..e74441b3 --- /dev/null +++ b/docs/reference/entries/gibbs.md @@ -0,0 +1 @@ +::: rxn_network.entries.gibbs \ No newline at end of file diff --git a/docs/reference/entries/nist.md b/docs/reference/entries/nist.md new file mode 100644 index 00000000..66056adf --- /dev/null +++ b/docs/reference/entries/nist.md @@ -0,0 +1 @@ +::: rxn_network.entries.nist \ No newline at end of file diff --git a/docs/reference/enumerators/basic.md b/docs/reference/enumerators/basic.md new file mode 100644 index 00000000..e7ea8557 --- /dev/null +++ b/docs/reference/enumerators/basic.md @@ -0,0 +1 @@ +::: rxn_network.enumerators.basic \ No newline at end of file diff --git a/docs/reference/enumerators/minimize.md b/docs/reference/enumerators/minimize.md new file mode 100644 index 00000000..e855de64 --- /dev/null +++ b/docs/reference/enumerators/minimize.md @@ -0,0 +1 @@ +::: rxn_network.enumerators.minimize \ No newline at end of file diff --git a/docs/reference/enumerators/utils.md b/docs/reference/enumerators/utils.md new file mode 100644 index 00000000..7a90b85b --- /dev/null +++ b/docs/reference/enumerators/utils.md @@ -0,0 +1 @@ +::: rxn_network.enumerators.utils \ No newline at end of file diff --git a/docs/reference/firetasks/build_inputs.md b/docs/reference/firetasks/build_inputs.md new file mode 100644 index 00000000..29df5cad --- /dev/null +++ b/docs/reference/firetasks/build_inputs.md @@ -0,0 +1 @@ +::: rxn_network.firetasks.build_inputs \ No newline at end of file diff --git a/docs/reference/firetasks/parse_outputs.md b/docs/reference/firetasks/parse_outputs.md new file mode 100644 index 00000000..12a1c21e --- /dev/null +++ b/docs/reference/firetasks/parse_outputs.md @@ -0,0 +1 @@ +::: rxn_network.firetasks.parse_outputs \ No newline at end of file diff --git a/docs/reference/firetasks/run_calc.md b/docs/reference/firetasks/run_calc.md new file mode 100644 index 00000000..ba2fe8fb --- /dev/null +++ b/docs/reference/firetasks/run_calc.md @@ -0,0 +1 @@ +::: rxn_network.firetasks.run_calc \ No newline at end of file diff --git a/docs/reference/firetasks/utils.md b/docs/reference/firetasks/utils.md new file mode 100644 index 00000000..1f79efb2 --- /dev/null +++ b/docs/reference/firetasks/utils.md @@ -0,0 +1 @@ +::: rxn_network.firetasks.utils \ No newline at end of file diff --git a/docs/reference/fireworks/core.md b/docs/reference/fireworks/core.md new file mode 100644 index 00000000..324cf093 --- /dev/null +++ b/docs/reference/fireworks/core.md @@ -0,0 +1 @@ +::: rxn_network.fireworks.core \ No newline at end of file diff --git a/docs/reference/network/entry.md b/docs/reference/network/entry.md new file mode 100644 index 00000000..e73c6448 --- /dev/null +++ b/docs/reference/network/entry.md @@ -0,0 +1 @@ +::: rxn_network.network.entry \ No newline at end of file diff --git a/docs/reference/network/gt.md b/docs/reference/network/gt.md new file mode 100644 index 00000000..04c040af --- /dev/null +++ b/docs/reference/network/gt.md @@ -0,0 +1 @@ +::: rxn_network.network.gt \ No newline at end of file diff --git a/docs/reference/network/network.md b/docs/reference/network/network.md new file mode 100644 index 00000000..698f644c --- /dev/null +++ b/docs/reference/network/network.md @@ -0,0 +1 @@ +::: rxn_network.network.network \ No newline at end of file diff --git a/docs/reference/network/utils.md b/docs/reference/network/utils.md new file mode 100644 index 00000000..43be63ae --- /dev/null +++ b/docs/reference/network/utils.md @@ -0,0 +1 @@ +::: rxn_network.network.utils \ No newline at end of file diff --git a/docs/reference/network/visualize.md b/docs/reference/network/visualize.md new file mode 100644 index 00000000..3d0c7376 --- /dev/null +++ b/docs/reference/network/visualize.md @@ -0,0 +1 @@ +::: rxn_network.network.visualize \ No newline at end of file diff --git a/docs/reference/pathways/balanced.md b/docs/reference/pathways/balanced.md new file mode 100644 index 00000000..78e5f201 --- /dev/null +++ b/docs/reference/pathways/balanced.md @@ -0,0 +1 @@ +::: rxn_network.pathways.balanced \ No newline at end of file diff --git a/docs/reference/pathways/basic.md b/docs/reference/pathways/basic.md new file mode 100644 index 00000000..c152dfe0 --- /dev/null +++ b/docs/reference/pathways/basic.md @@ -0,0 +1 @@ +::: rxn_network.pathways.basic \ No newline at end of file diff --git a/docs/reference/pathways/solver.md b/docs/reference/pathways/solver.md new file mode 100644 index 00000000..a7102e13 --- /dev/null +++ b/docs/reference/pathways/solver.md @@ -0,0 +1 @@ +::: rxn_network.pathways.solver \ No newline at end of file diff --git a/docs/reference/pathways/utils.md b/docs/reference/pathways/utils.md new file mode 100644 index 00000000..67ba1ca1 --- /dev/null +++ b/docs/reference/pathways/utils.md @@ -0,0 +1 @@ +::: rxn_network.pathways.utils \ No newline at end of file diff --git a/docs/reference/reactions/basic.md b/docs/reference/reactions/basic.md new file mode 100644 index 00000000..346a38ed --- /dev/null +++ b/docs/reference/reactions/basic.md @@ -0,0 +1 @@ +::: rxn_network.reactions.basic \ No newline at end of file diff --git a/docs/reference/reactions/computed.md b/docs/reference/reactions/computed.md new file mode 100644 index 00000000..4648bede --- /dev/null +++ b/docs/reference/reactions/computed.md @@ -0,0 +1 @@ +::: rxn_network.reactions.computed \ No newline at end of file diff --git a/docs/reference/reactions/open.md b/docs/reference/reactions/open.md new file mode 100644 index 00000000..9183a51a --- /dev/null +++ b/docs/reference/reactions/open.md @@ -0,0 +1 @@ +::: rxn_network.reactions.open \ No newline at end of file diff --git a/docs/reference/reactions/reaction_set.md b/docs/reference/reactions/reaction_set.md new file mode 100644 index 00000000..16fd1233 --- /dev/null +++ b/docs/reference/reactions/reaction_set.md @@ -0,0 +1 @@ +::: rxn_network.reactions.reaction_set \ No newline at end of file diff --git a/docs/reference/reactions/utils.md b/docs/reference/reactions/utils.md new file mode 100644 index 00000000..a6562cef --- /dev/null +++ b/docs/reference/reactions/utils.md @@ -0,0 +1 @@ +::: rxn_network.reactions.utils \ No newline at end of file diff --git a/docs/reference/thermo/chempot_diagram.md b/docs/reference/thermo/chempot_diagram.md new file mode 100644 index 00000000..d3a0915a --- /dev/null +++ b/docs/reference/thermo/chempot_diagram.md @@ -0,0 +1 @@ +::: rxn_network.thermo.chempot_diagram \ No newline at end of file diff --git a/docs/reference/thermo/utils.md b/docs/reference/thermo/utils.md new file mode 100644 index 00000000..acb517e9 --- /dev/null +++ b/docs/reference/thermo/utils.md @@ -0,0 +1 @@ +::: rxn_network.thermo.utils \ No newline at end of file diff --git a/docs/reference/utils.md b/docs/reference/utils.md new file mode 100644 index 00000000..f76256ff --- /dev/null +++ b/docs/reference/utils.md @@ -0,0 +1 @@ +::: rxn_network.utils \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index 414036b2..caee01a8 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -3,10 +3,61 @@ site_description: Documentation for rxn_network copyright: Built by The GENESIS EFRC theme: - name: 'material' + name: null + custom_dir: 'cinder' nav: - Home: index.md + - Reference: + Core: + Calculator: reference/core/calculator.md + Cost Function: reference/core/cost_function.md + Enumerator: reference/core/enumerator.md + Network: reference/core/network.md + Pathway: reference/core/pathway.md + Reaction: reference/core/reaction.md + Solver: reference/core/solver.md + Costs: + Calculators: reference/costs/calculators.md + Softplus: reference/costs/softplus.md + Data: reference/data/data.md + Entries: + Entry Set: reference/entries/entry_set.md + Gibbs: reference/entries/gibbs.md + Nist: reference/entries/nist.md + Enumerators: + Basic: reference/enumerators/basic.md + Minimize: reference/enumerators/minimize.md + Utils: reference/enumerators/utils.md + Firetasks: + Build Inputs: reference/firetasks/build_inputs.md + Parse Outputs: reference/firetasks/parse_outputs.md + Run Calc: reference/firetasks/run_calc.md + Utils: reference/firetasks/utils.md + Fireworks: + Core: reference/fireworks/core.md + Network: + Entry: reference/network/entry.md + Graph-tool: reference/network/gt.md + Network: reference/network/network.md + Utils: reference/network/utils.md + Visualize: reference/network/visualize.md + Pathways: + Balanced: reference/pathways/balanced.md + Basic: reference/pathways/basic.md + Solver: reference/pathways/solver.md + Utils: reference/pathways/utils.md + Reactions: + Basic: reference/reactions/basic.md + Computed: reference/reactions/computed.md + Open: reference/reactions/open.md + Reaction Set: reference/reactions/reaction_set.md + Utils: reference/reactions/utils.md + Thermo: + Chempot Diagram: reference/thermo/chempot_diagram.md + Utils: reference/thermo/utils.md + Utils: reference/utils.md + - CHANGELOG: CHANGELOG.md site_url: https://github.com/GENESIS-EFRC/reaction-network repo_url: https://github.com/GENESIS-EFRC/reaction-network/ diff --git a/requirements-docs.txt b/requirements-docs.txt index b1aed02b..9a3e8b8d 100644 --- a/requirements-docs.txt +++ b/requirements-docs.txt @@ -1,5 +1,7 @@ -mkdocs==1.1.2 -mkdocs-material==7.1.8 +mkdocs==1.2.2 +mkdocs-material==7.3.0 +mkdocs-material-extensions==1.0.3 +mkdocs-gitbook==0.0.1 mkdocs-minify-plugin==0.4.0 mkdocstrings==0.15.2 pymdown-extensions==8.1.1 \ No newline at end of file diff --git a/requirements-testing.txt b/requirements-testing.txt index d30923a3..da936130 100644 --- a/requirements-testing.txt +++ b/requirements-testing.txt @@ -1,8 +1,8 @@ pre-commit==2.14.1 pytest==6.2.5 pytest-cov==2.12.1 -pycodestyle==2.6.0 +pycodestyle==2.7.0 pydocstyle==6.1.1 -flake8==3.8.4 +flake8==3.9.2 mypy==0.910 mypy-extensions==0.4.3 diff --git a/requirements.txt b/requirements.txt index 26c37ba4..ea68c5c0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ fireworks==1.9.7 maggma>=0.26.0 numba==0.54.0 -pymatgen==2022.0.12 +pymatgen==2022.0.14 diff --git a/setup.cfg b/setup.cfg index a6d7a635..da6cd525 100644 --- a/setup.cfg +++ b/setup.cfg @@ -21,34 +21,5 @@ profile=black [pydocstyle] ignore = D105,D2,D4 -[mypy-monty.*] -ignore_missing_imports = True -follow_imports = skip - -[mypy-tqdm.*] -ignore_missing_imports = True - -[mypy-pymatgen.*] -ignore_missing_imports = True -follow_imports = skip - -[mypy-scipy.*] -ignore_missing_imports = True - -[mypy-numpy.*] -ignore_missing_imports = True - -[mypy-numba.*] -ignore_missing_imports = True - -[mypy-dask.*] -ignore_missing_imports = True - -[mypy-graph_tool.*] -ignore_missing_imports = True - -[mypy-matplotlib.*] -ignore_missing_imports = True - -[mypy-uncertainties.*] -ignore_missing_imports = True +[mypy] +ignore_missing_imports = True \ No newline at end of file diff --git a/setup.py b/setup.py index bdfab03a..392ce6ed 100644 --- a/setup.py +++ b/setup.py @@ -38,7 +38,6 @@ extra_requires={"demo": ["jupyter>=1.0.0"]}, classifiers=[ "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Development Status :: 4 - Beta", @@ -51,5 +50,5 @@ "Topic :: Software Development :: Libraries :: Python Modules", ], tests_require=["pytest"], - python_requires=">=3.7", + python_requires=">=3.8", ) diff --git a/src/rxn_network/core/__init__.py b/src/rxn_network/core/__init__.py index f2b1aa90..0b8e4f56 100644 --- a/src/rxn_network/core/__init__.py +++ b/src/rxn_network/core/__init__.py @@ -1,4 +1,4 @@ -" Core interfaces for the reaction-network package. " +""" Core interfaces for the reaction-network package. """ from rxn_network.core.calculator import Calculator from rxn_network.core.cost_function import CostFunction from rxn_network.core.enumerator import Enumerator diff --git a/src/rxn_network/core/calculator.py b/src/rxn_network/core/calculator.py index e4ca97c0..29a6de9b 100644 --- a/src/rxn_network/core/calculator.py +++ b/src/rxn_network/core/calculator.py @@ -1,4 +1,6 @@ -" Basic interface for a reaction cost Calculator" +""" +Basic interface for a reaction cost Calculator +""" from abc import ABCMeta, abstractmethod from monty.json import MSONable @@ -7,12 +9,18 @@ class Calculator(MSONable, metaclass=ABCMeta): - "Base definition for a property calculator" + """ + Base definition for a property calculator + """ @abstractmethod def calculate(self, rxn: Reaction) -> float: - "Evaluates the specified property of a reaction" + """ + Evaluates the specified property of a reaction + """ @abstractmethod def decorate(self, rxn: Reaction) -> "Reaction": - "Evaluates the specified prop. of a reaction and stores it in the reaction data" + """ + Evaluates the specified prop. of a reaction and stores it in the reaction data + """ diff --git a/src/rxn_network/core/cost_function.py b/src/rxn_network/core/cost_function.py index 48d613ba..86c80d15 100644 --- a/src/rxn_network/core/cost_function.py +++ b/src/rxn_network/core/cost_function.py @@ -1,4 +1,6 @@ -" Basic interface for a cost function " +""" +Basic interface for a cost function +""" from abc import ABCMeta, abstractmethod from monty.json import MSONable @@ -7,8 +9,12 @@ class CostFunction(MSONable, metaclass=ABCMeta): - "Base definition for a cost function" + """ + Base definition for a cost function + """ @abstractmethod def evaluate(self, rxn: Reaction) -> float: - "Evaluates the total cost function on a reaction" + """ + Evaluates the total cost function on a reaction + """ diff --git a/src/rxn_network/core/enumerator.py b/src/rxn_network/core/enumerator.py index 8f6a12a4..3459bf82 100644 --- a/src/rxn_network/core/enumerator.py +++ b/src/rxn_network/core/enumerator.py @@ -1,15 +1,17 @@ -" Basic interface for a reaction Enumerator " +""" +Basic interface for a reaction Enumerator +""" import logging from abc import ABCMeta, abstractmethod from typing import List from monty.json import MSONable -from rxn_network.core.reaction import Reaction - class Enumerator(MSONable, metaclass=ABCMeta): - "Base definition for a reaction enumeration methodology" + """ + Base definition for the reaction enumeration methodology + """ def __init__(self, precursors, target, calculators): self.logger = logging.getLogger(str(self.__class__.__name__)) @@ -23,9 +25,13 @@ def __init__(self, precursors, target, calculators): self.calculators = calculators @abstractmethod - def enumerate(self, entries) -> List[Reaction]: - "Enumerates the potential reactions from the list of entries" + def enumerate(self, entries): + """ + Enumerates the potential reactions from the list of entries + """ @abstractmethod - def estimate_num_reactions(self, entries) -> int: - "Estimate of the number of reactions from a list of entires" + def estimate_max_num_reactions(self, entries) -> int: + """ + Estimate of the number of reactions from a list of entries + """ diff --git a/src/rxn_network/core/network.py b/src/rxn_network/core/network.py index 5a5a2632..eb073583 100644 --- a/src/rxn_network/core/network.py +++ b/src/rxn_network/core/network.py @@ -1,4 +1,6 @@ -" Basic interface for a reaction Network " +""" +Basic interface for a (reaction) Network +""" import logging from abc import ABCMeta, abstractmethod from typing import List @@ -10,7 +12,9 @@ class Network(MSONable, metaclass=ABCMeta): - "Base definition for a reaction network" + """ + Base definition for a reaction network + """ def __init__(self, entries: List[Entry], enumerators, cost_function): self.logger = logging.getLogger(str(self.__class__.__name__)) @@ -24,16 +28,16 @@ def __init__(self, entries: List[Entry], enumerators, cost_function): @abstractmethod def build(self): - "Construct the network from the supplied enumerators" + """Construct the network from the supplied enumerators""" @abstractmethod - def find_pathways(self) -> List[Pathway]: - "Find reaction pathways" + def find_pathways(self, target, k) -> List[Pathway]: + """Find reaction pathways""" @abstractmethod def set_precursors(self): - "Set the phases used as precursors in the network" + """Set the phases used as precursors in the network""" @abstractmethod def set_target(self): - "Set the phase used as a target in the network" + """Set the phase used as a target in the network""" diff --git a/src/rxn_network/core/pathway.py b/src/rxn_network/core/pathway.py index 2a5ec289..97fddd35 100644 --- a/src/rxn_network/core/pathway.py +++ b/src/rxn_network/core/pathway.py @@ -1,6 +1,7 @@ -" Basic interface for a reaction Pathway " -import logging -from abc import ABCMeta, abstractmethod, abstractproperty +""" +Basic interface for a reaction Pathway +""" +from abc import ABCMeta from typing import List from monty.json import MSONable @@ -9,53 +10,56 @@ class Pathway(MSONable, metaclass=ABCMeta): - "Base definition for a reaction pathway" + """ + Base definition for a reaction pathway + """ @property def reactions(self) -> List[Reaction]: + """List of reactions in this Pathway""" return self._reactions - " List of reactions in this Pathway " @property def entries(self): - "Entry objects in this Pathway" + """Entry objects in this Pathway""" return {entry for rxn in self.reactions for entry in rxn.entries} @property def all_reactants(self): - "Entries serving as a reactant in any sub reaction" + """Entries serving as a reactant in any sub reaction""" return {entry for rxn in self.reactions for entry in rxn.reactants} @property def all_products(self): - "Entries serving as a product in any sub reaction" + """Entries serving as a product in any sub reaction""" return {entry for rxn in self.reactions for entry in rxn.products} @property def compositions(self): + """Compositions in the reaction""" return list(self.all_reactants | self.all_products) @property def reactants(self): - "The reactants of this whole reaction pathway" + """The reactants of this whole reaction pathway""" return self.all_reactants - self.all_products @property def products(self): - "The products of this whole reaction pathway" + """The products of this whole reaction pathway""" return self.all_products - self.all_reactants @property def intermediates(self): - "Intermediates as entries in this reaction pathway" + """Intermediates as entries in this reaction pathway""" return self.all_products & self.all_reactants @property def energy(self): - "Total energy of this reaction pathway" + """Total energy of this reaction pathway""" return sum([rxn.energy for rxn in self.reactions]) @property def energy_per_atom(self): - "Total energy per atom of this reaction pathway" + """Total energy per atom of this reaction pathway""" return sum([rxn.energy_per_atom for rxn in self.reactions]) diff --git a/src/rxn_network/core/reaction.py b/src/rxn_network/core/reaction.py index 27631eaa..b79821d4 100644 --- a/src/rxn_network/core/reaction.py +++ b/src/rxn_network/core/reaction.py @@ -1,5 +1,7 @@ -" Basic interface for a chemical Reaction " -from abc import ABCMeta, abstractproperty +""" +Basic interface for a (chemical) Reaction +""" +from abc import ABCMeta, abstractmethod from typing import List import numpy as np @@ -8,39 +10,43 @@ class Reaction(MSONable, metaclass=ABCMeta): - "Base definition for a Reaction" + """ + Base definition for a Reaction + """ - @abstractproperty + @property + @abstractmethod def reactants(self) -> List[Composition]: - "List of reactants for this reaction" + """List of reactants for this reaction""" - @abstractproperty + @property + @abstractmethod def products(self) -> List[Composition]: - "List of products for this reaction" + """List of products for this reaction""" + + @property + @abstractmethod + def coefficients(self) -> np.ndarray: + """Coefficients of the reaction""" - @abstractproperty - def coefficients(self) -> np.array: - """ - Coefficients of the reaction - """ + @property + @abstractmethod + def energy(self) -> float: + """The energy of this reaction in total eV""" @property def compositions(self) -> List[Composition]: - """ - List of all compositions in the reaction. - """ + """List of all compositions in the reaction""" return self.reactants + self.products @property def elements(self) -> List[Element]: - """ - List of elements in the reaction - """ + """List of elements in the reaction""" return list(set(el for comp in self.compositions for el in comp.elements)) @property def num_atoms(self) -> float: - "Total number of atoms in this reaction" + """Total number of atoms in this reaction""" return ( sum( [ @@ -52,11 +58,7 @@ def num_atoms(self) -> float: / 2 ) - @abstractproperty - def energy(self) -> float: - "The energy of this reaction in total eV" - @property def energy_per_atom(self) -> float: - "The energy per atom of this reaction in eV" + """The energy per atom of this reaction in eV""" return self.energy / self.num_atoms diff --git a/src/rxn_network/core/solver.py b/src/rxn_network/core/solver.py index fa7c2d21..ac20c537 100644 --- a/src/rxn_network/core/solver.py +++ b/src/rxn_network/core/solver.py @@ -1,4 +1,6 @@ -" Basic interface for a pathway Solver " +""" +Basic interface for a reaction pathway Solver +""" import logging from abc import ABCMeta, abstractmethod from typing import List @@ -11,7 +13,9 @@ class Solver(MSONable, metaclass=ABCMeta): - "Base definition for a pathway solver class." + """ + Base definition for a pathway solver class + """ def __init__(self, entries, pathways): self.logger = logging.getLogger(str(self.__class__.__name__)) @@ -34,28 +38,34 @@ def __init__(self, entries, pathways): @abstractmethod def solve(self, net_rxn) -> List[Pathway]: - "Solve paths" + """Solve paths""" @property def entries(self) -> EntrySet: + """Entry set used in solver""" return self._entries @property def pathways(self) -> List[Pathway]: + """Pathways used in solver class""" return self._pathways @property def reactions(self) -> List[Reaction]: + """Reactions used in solver class""" return self._reactions @property def costs(self) -> List[float]: + """ Costs used in solver class""" return self._costs @property def num_rxns(self) -> int: + """Length of reaction list""" return len(self.reactions) @property def num_entries(self) -> int: + """Length of entry list""" return len(self._entries) diff --git a/src/rxn_network/costs/__init__.py b/src/rxn_network/costs/__init__.py index e69de29b..7cc0b1ec 100644 --- a/src/rxn_network/costs/__init__.py +++ b/src/rxn_network/costs/__init__.py @@ -0,0 +1,2 @@ +from rxn_network.costs.calculators import ChempotDistanceCalculator +from rxn_network.costs.softplus import Softplus diff --git a/src/rxn_network/costs/calculators.py b/src/rxn_network/costs/calculators.py index c18d2f47..c7d25a97 100644 --- a/src/rxn_network/costs/calculators.py +++ b/src/rxn_network/costs/calculators.py @@ -1,27 +1,35 @@ -" A calculator class for determining chemical potential distance of reactions " +""" +A calculator class for determining chemical potential distance of reactions +""" from itertools import chain, combinations, product from typing import List, Optional import numpy as np -from pymatgen.analysis.phase_diagram import PhaseDiagram -from pymatgen.entries.computed_entries import ComputedEntry +from pymatgen.analysis.phase_diagram import PDEntry -from rxn_network.core import Calculator -from rxn_network.reactions import ComputedReaction -from rxn_network.thermo.chempot_diagram import ChempotDiagram +from rxn_network.core.calculator import Calculator +from rxn_network.reactions.computed import ComputedReaction +from rxn_network.thermo.chempot_diagram import ChemicalPotentialDiagram class ChempotDistanceCalculator(Calculator): """ Calculator for determining the "chemical potential distance" for a reaction (in eV/atom). + + For more information on this specific implementation of the algorithm, + please cite/reference the paper below: + + Todd, Paul K., McDermott, M.J., et al. “Selectivity in yttrium manganese oxide + synthesis via local chemical potentials in hyperdimensional phase space.” + ArXiv:2104.05986 [Cond-Mat], Apr. 2021. arXiv.org, http://arxiv.org/abs/2104.05986 """ def __init__( self, - cpd: ChempotDiagram, - mu_func: Optional[str] = "sum", - name: Optional[str] = "chempot_distance", + cpd: ChemicalPotentialDiagram, + mu_func: str = "sum", + name: str = "chempot_distance", ): """ Args: @@ -29,17 +37,17 @@ def __init__( mu_func: the name of the function used to process the interfacial chemical potential distances into a single value describing the whole reaction. - name: the data dictionary key by which to store the calculated value. + name: the data dictionary key with which to store the calculated value. """ self.cpd = cpd self.name = name if mu_func == "max": - self._mu_func = np.max + self._mu_func = np.max # type: ignore elif mu_func == "mean": - self._mu_func = np.mean + self._mu_func = np.mean # type: ignore elif mu_func == "sum": - self._mu_func = np.sum + self._mu_func = np.sum # type: ignore def calculate(self, rxn: ComputedReaction) -> float: """ @@ -64,7 +72,7 @@ def calculate(self, rxn: ComputedReaction) -> float: for combo in combos ] - distance = self._mu_func(distances) + distance = float(self._mu_func(distances)) return distance def decorate(self, rxn: ComputedReaction) -> ComputedReaction: @@ -88,33 +96,35 @@ def decorate(self, rxn: ComputedReaction) -> ComputedReaction: @classmethod def from_entries( cls, - entries: List[ComputedEntry], - mu_func: Optional[str] = "max", - cpd_kws: Optional[dict] = {"default_limit": -50}, - name: Optional[str] = "chempot_distance", - ): + entries: List[PDEntry], + mu_func: str = "sum", + name: str = "chempot_distance", + **kwargs + ) -> "ChempotDistanceCalculator": """ - Convenience constructor which first builds the ChempotDiagram + Convenience constructor which first builds the ChemicalPotentialDiagram object from a list of entry objects. Args: - entries: entry objects used to build the ChempotDiagram + entries: entry objects used to build the ChemicalPotentialDiagram mu_func: the name of the function used to process the interfacial chemical potential distances into a single value describing the whole reaction. - cpd_kws: optional kwargs passed to the ChempotDiagram constructor. - Default kwarg is default_limit = -50. name: the data dictionary key by which to store the calculated value, defaults to "chempot_distance" + **kwargs: optional kwargs passed to ChemicalPotentialDiagram; defaults to + "default_min_limit"=-50 Returns: A ChempotDistanceCalculator object """ - pd = PhaseDiagram(entries) - cpd = ChempotDiagram(pd, **cpd_kws) + if not kwargs.get("default_min_limit"): + kwargs["default_min_limit"] = -50 + + cpd = ChemicalPotentialDiagram(entries=entries, **kwargs) return cls(cpd, mu_func, name) @property def mu_func(self): - "Returns the function used to process the interfacial mu distances" + """Returns the function used to process the interfacial mu distances""" return self._mu_func diff --git a/src/rxn_network/costs/softplus.py b/src/rxn_network/costs/softplus.py index f7e9292d..6726f98d 100644 --- a/src/rxn_network/costs/softplus.py +++ b/src/rxn_network/costs/softplus.py @@ -1,10 +1,12 @@ -" Implementation of the softplus cost function" -from typing import List +""" +Implementation of the softplus cost function +""" +from typing import List, Optional import numpy as np from rxn_network.core import CostFunction -from rxn_network.reactions import ComputedReaction +from rxn_network.reactions.computed import ComputedReaction class Softplus(CostFunction): @@ -19,17 +21,22 @@ class Softplus(CostFunction): def __init__( self, temp: float = 300, - params: List[str] = ["energy_per_atom"], - weights: List[float] = [1.0], + params: Optional[List[str]] = None, + weights: Optional[List[float]] = None, ): """ Args: temp: Temperature [K]. - params: List of data dictionary keys for function parameters used in the - softplus function. Defaults to ["energy_per_atom"] + params: List of data dictionary keys for function parameters used as an + argument to the softplus function. Defaults to ["energy_per_atom"] weights: List of corresponding values by which to weight the function parameters. Defaults to [1.0]. """ + if params is None: + params = ["energy_per_atom"] + if weights is None: + weights = [1.0] + self.temp = temp self.params = params self.weights = np.array(weights) @@ -39,7 +46,7 @@ def evaluate(self, rxn: ComputedReaction) -> float: Calculates the ost of reaction based on the initialized parameters and weights. Args: - rxn: A computed reaction. + rxn: A computed reaction to evaluate. Returns: The cost of the reaction. @@ -54,18 +61,18 @@ def evaluate(self, rxn: ComputedReaction) -> float: raise ValueError(f"Reaction is missing parameter {p}!") values.append(value) - values = np.array(values) - total = np.dot(values, self.weights) + values_arr = np.array(values) + total = float(np.dot(values_arr, self.weights)) return self._softplus(total, self.temp) @staticmethod def _softplus(x: float, t: float) -> float: - "The mathematical formula for the softplus function" + """The mathematical formula for the softplus function""" return np.log(1 + (273 / t) * np.exp(x)) def __repr__(self): return ( f"Softplus with parameters: " - f"{' '.join([(f'{k} ({v})') for k, v in zip(self.params, self.weights)])}" + f"{' '.join([f'{k} ({v})' for k, v in zip(self.params, self.weights)])}" ) diff --git a/src/rxn_network/data/README.md b/src/rxn_network/data/README.md index a267a1f1..dea7c01d 100644 --- a/src/rxn_network/data/README.md +++ b/src/rxn_network/data/README.md @@ -1,4 +1,2 @@ This folder contains a copy of the experimental thermochemistry data used in the -reaction-network code. Note that currently much of this data is in pymatgen and used -by the _GibbsComputedStructureEntry_ class; hence this copy is not actually utilized -in the software here. \ No newline at end of file +reaction-network code. \ No newline at end of file diff --git a/src/rxn_network/data/__init__.py b/src/rxn_network/data/__init__.py index 064b0743..a5bfdbe0 100644 --- a/src/rxn_network/data/__init__.py +++ b/src/rxn_network/data/__init__.py @@ -1,6 +1,5 @@ """ -Experimental Gibbs free energy data from NIST-JANAF (compounds, gases) and FactSage ( -elements) +Experimental Gibbs free energy data from NIST-JANAF (compounds, gases) and FactSage (elements) """ from pathlib import Path diff --git a/src/rxn_network/entries/__init__.py b/src/rxn_network/entries/__init__.py index 384f0287..af1056f5 100644 --- a/src/rxn_network/entries/__init__.py +++ b/src/rxn_network/entries/__init__.py @@ -1,8 +1,6 @@ -" Entry and entry set classes used in reaction enumeration / networks " - -from rxn_network.entries.gibbs import ( # pylint: disable=C0413; noqa: E402 - GibbsComputedEntry, -) -from rxn_network.entries.nist import ( # pylint: disable=C0413; noqa: E402 - NISTReferenceEntry, -) +""" +Entry and entry set classes used in reaction enumeration / networks +""" +from rxn_network.entries.gibbs import GibbsComputedEntry +from rxn_network.entries.nist import NISTReferenceEntry +from rxn_network.entries.entry_set import GibbsEntrySet diff --git a/src/rxn_network/entries/entry_set.py b/src/rxn_network/entries/entry_set.py index a8b53c34..a530f649 100644 --- a/src/rxn_network/entries/entry_set.py +++ b/src/rxn_network/entries/entry_set.py @@ -1,7 +1,9 @@ -" An entry set class for acquiring entries with Gibbs formation energies" -from typing import List, Optional, Union +""" +An entry set class for acquiring entries with Gibbs formation energies +""" +from typing import List, Optional, Union, Set, Dict -from monty.json import MontyDecoder, MSONable +from monty.json import MontyDecoder from pymatgen.analysis.phase_diagram import PhaseDiagram from pymatgen.core import Composition from pymatgen.entries.computed_entries import ( @@ -32,7 +34,9 @@ def __init__(self, entries: List[Union[GibbsComputedEntry, NISTReferenceEntry]]) entries: A collection of entry objects that will make up the entry set. """ super().__init__(entries) - self.entries_list = list(entries) + self.entries_list = list( + sorted(entries, key=lambda e: e.composition.reduced_formula) + ) self.build_indices() def filter_by_stability( @@ -54,8 +58,8 @@ def filter_by_stability( """ pd_dict = expand_pd(self.entries) - filtered_entries = set() - all_comps = dict() + filtered_entries: Set[Union[GibbsComputedEntry, NISTReferenceEntry]] = set() + all_comps: Dict[str, Union[GibbsComputedEntry, NISTReferenceEntry]] = dict() for chemsys, pd in pd_dict.items(): for entry in pd.all_entries: @@ -74,7 +78,7 @@ def filter_by_stability( all_comps[formula] = entry filtered_entries.add(entry) - return self.__class__(filtered_entries) + return self.__class__(list(filtered_entries)) def build_indices(self): for idx, e in enumerate(self.entries_list): @@ -194,7 +198,7 @@ def from_entries( experimental reference entry objects at the specified temperature. """ e_set = EntrySet(entries) - new_entries = set() + new_entries: Set[GibbsComputedEntry] = set() if len(e_set.chemsys) <= 9: # Qhull algorithm struggles beyond 9 dimensions pd = PhaseDiagram(e_set) return cls.from_pd(pd, temperature) @@ -204,4 +208,7 @@ def from_entries( gibbs_set = cls.from_pd(pd, temperature) new_entries.update(gibbs_set) - return cls(new_entries) + return cls(list(new_entries)) + + def copy(self) -> "GibbsEntrySet": + return GibbsEntrySet(entries=self.entries) diff --git a/src/rxn_network/entries/gibbs.py b/src/rxn_network/entries/gibbs.py index 2f6b5e89..bd828239 100644 --- a/src/rxn_network/entries/gibbs.py +++ b/src/rxn_network/entries/gibbs.py @@ -1,4 +1,6 @@ -" Specialized entry to estimate Gibbs Free Energy for a solid" +""" +Specialized computed entry to estimate Gibbs free energy of formation +""" import hashlib from itertools import combinations from typing import List, Optional @@ -203,7 +205,7 @@ def _reduced_mass(composition: Composition) -> float: denominator = (num_elems - 1) * reduced_comp.num_atoms all_pairs = combinations(elem_dict.items(), 2) - mass_sum = 0 + mass_sum = 0.0 for pair in all_pairs: m_i = Composition(pair[0][0]).weight diff --git a/src/rxn_network/entries/nist.py b/src/rxn_network/entries/nist.py index 37122653..06a54268 100644 --- a/src/rxn_network/entries/nist.py +++ b/src/rxn_network/entries/nist.py @@ -1,7 +1,9 @@ -" Implements an Entry that looks up NIST pre-tabulated Gibbs free energies " +""" +Implements an Entry that looks up NIST pre-tabulated Gibbs free energies +""" import hashlib +from typing import Dict, Any -from monty.json import MontyDecoder from pymatgen.core.composition import Composition from pymatgen.entries import Entry from scipy.interpolate import interp1d @@ -38,25 +40,20 @@ def __init__(self, composition: Composition, temperature: float): raise ValueError("Formula must be in NIST-JANAF thermochemical tables") if temperature < 300 or temperature > 2000: - raise ValueError("Temperature must be selected from range: [300, 2000] K.") + raise ValueError("Temperature must be selected from range: [300, 2000] K") - energy = self.get_nist_energy(formula, temperature) + energy = self._get_nist_energy(formula, temperature) self.temperature = temperature self._formula = formula self.name = formula self.entry_id = "NISTReferenceEntry" - self.data = {} + self.data = {} # type: Dict[Any, Any] super().__init__(composition.reduced_composition, energy) - @property - def energy(self) -> float: - "The energy of the entry" - return self._energy - @staticmethod - def get_nist_energy(formula: str, temperature: float) -> float: + def _get_nist_energy(formula: str, temperature: float) -> float: """ Convenience method for accessing and interpolating NIST-JANAF data. @@ -74,29 +71,35 @@ def get_nist_energy(formula: str, temperature: float) -> float: return data[str(temperature)] + @property + def energy(self) -> float: + """The energy of the entry, as supplied by the NIST-JANAF tables.""" + return self._energy + @property def correction_uncertainty(self) -> float: - "Uncertainty of NIST-JANAF data is not supplied." + """ Uncertainty of NIST-JANAF data is not supplied.""" return 0 @property def correction_uncertainty_per_atom(self) -> float: - "Uncertainty of NIST-JANAF data is not supplied." + """Uncertainty of NIST-JANAF data is not supplied.""" return 0 @property def is_experimental(self) -> bool: + """ Returns True by default.""" return True def as_dict(self) -> dict: - "Returns an MSONable dict." + """ Returns an MSONable dict.""" data = super().as_dict() data["temperature"] = self.temperature return data @classmethod def from_dict(cls, d) -> "NISTReferenceEntry": - "Returns NISTReferenceEntry constructed from MSONable dict." + """ Returns NISTReferenceEntry constructed from MSONable dict.""" return cls(composition=d["composition"], temperature=d["temperature"]) def __repr__(self): diff --git a/src/rxn_network/enumerators/__init__.py b/src/rxn_network/enumerators/__init__.py index 27fa426d..e767eef3 100644 --- a/src/rxn_network/enumerators/__init__.py +++ b/src/rxn_network/enumerators/__init__.py @@ -1 +1,8 @@ -"Implementations of reaction enumerators" +""" +Implementations of reaction enumerators +""" +from rxn_network.enumerators.basic import BasicEnumerator, BasicOpenEnumerator +from rxn_network.enumerators.minimize import ( + MinimizeGibbsEnumerator, + MinimizeGrandPotentialEnumerator, +) diff --git a/src/rxn_network/enumerators/basic.py b/src/rxn_network/enumerators/basic.py index de6bbd64..80b2bf87 100644 --- a/src/rxn_network/enumerators/basic.py +++ b/src/rxn_network/enumerators/basic.py @@ -1,26 +1,26 @@ -from itertools import chain, combinations, compress, groupby, product +""" +This module implements two types of basic reaction enumerators, with or without the +option of an open entry +""" +from itertools import combinations, product from math import comb from typing import List, Optional -import numpy as np -from pymatgen.analysis.phase_diagram import PhaseDiagram -from pymatgen.core.composition import Composition from pymatgen.entries.computed_entries import ComputedEntry +from pymatgen.analysis.phase_diagram import PhaseDiagram, GrandPotentialPhaseDiagram from tqdm.auto import tqdm -from rxn_network.core import Calculator, Enumerator, Reaction +from rxn_network.core import Enumerator from rxn_network.entries.entry_set import GibbsEntrySet from rxn_network.enumerators.utils import ( apply_calculators, filter_entries_by_chemsys, - get_total_chemsys, + get_elems_set, group_by_chemsys, initialize_calculators, initialize_entry, - initialize_open_entries, ) from rxn_network.reactions import ComputedReaction -from rxn_network.thermo.chempot_diagram import ChempotDiagram from rxn_network.utils import limited_powerset @@ -44,10 +44,10 @@ def __init__( objects during enumeration. Args: - precursors: Optional collection of precursor formulas; only reactions - with these phases as reactants will be enumerated. - target: Optional formula of target; only reactions which make this target - will be enumerated. + precursors: Optional list of precursor formulas; only reactions + which contain at least these phases as reactants will be enumerated. + target: Optional formula of target; only reactions which include + formation of this target will be enumerated. calculators: Optional list of Calculator object names; see calculators module for options (e.g., ["ChempotDistanceCalculator]) n: Maximum reactant/product cardinality; i.e., largest possible number of @@ -62,75 +62,61 @@ def __init__( self.n = n self.remove_unbalanced = remove_unbalanced self.remove_changed = remove_changed - self.stabilize = False + + self._stabilize = False if "ChempotDistanceCalculator" in self.calculators: - self.stabilize = True + self._stabilize = True - def enumerate( - self, - entries: GibbsEntrySet, - ) -> List[ComputedReaction]: + self._build_pd = False + self._build_grand_pd = False + + def enumerate(self, entries: GibbsEntrySet) -> List[ComputedReaction]: """ Calculate all possible reactions given a set of entries. If the enumerator - was initialized with precursors/target, the reactions will be filtered by - these constraints. + was initialized with specified precursors or target, the reactions will be + filtered by these constraints. Every enumerator follows a standard procedure: - Args: - entries: the set of all entries to enumerate from + 1. Initialize entries, i.e. ensure that precursors and target are considered + stable entries within the entry set. If using ChempotDistanceCalculator, + ensure that entries are filtered by stability. - Returns: - List of unique computed reactions. - """ - entries = GibbsEntrySet(entries) + 2. Get a dictionary representing every possible node, i.e. phase combination, + grouped by chemical system. - target = None - if self.target: - target = initialize_entry(self.target, entries, self.stabilize) - entries.add(target) - target_elems = {str(elem) for elem in target.composition.elements} + 3. Filter the combos dictionary for chemical systems which are not relevant ( + i.e. don't contain elements in precursors and/or target. - precursors = None - if self.precursors: - precursors = { - initialize_entry(f, entries, self.stabilize) for f in self.precursors - } - for p in precursors: - if p not in entries: - entries.add(p) - precursor_elems = { - str(elem) for p in precursors for elem in p.composition.elements - } + 4. Iterate through each chemical system, initializing calculators, + and computing all possible reactions for reactant/product pair and/or + thermodynamically predicted reactions for given reactants. - if self.stabilize: - entries = entries.filter_by_stability(e_above_hull=0.0) - self.logger.info( - "Filtering by stable entries due to use of " "ChempotDistanceCalculator" - ) + 5. Add reactions to growing list, repeat Step 4 until combos dict exhausted. - combos = list(limited_powerset(entries, self.n)) - combos_dict = group_by_chemsys(combos) + Args: + entries: the set of all entries to enumerate from + """ + entries, precursors, target = self._get_initialized_entries(entries) + combos_dict = self._get_combos_dict(entries, precursors, target) + open_combos = self._get_open_combos(entries) + + pbar = tqdm(combos_dict.items(), desc=self.__class__.__name__) rxns = [] - pbar = tqdm(combos_dict.items(), desc="BasicEnumerator") - for chemsys, selected_combos in pbar: + for chemsys, combos in pbar: pbar.set_description(f"{chemsys}") - elems = chemsys.split("-") - if ( - (target and not target_elems.issubset(elems)) - or (precursors and not precursor_elems.issuperset(elems)) - or len(elems) >= 10 - ): - continue filtered_entries = filter_entries_by_chemsys(entries, chemsys) calculators = initialize_calculators(self.calculators, filtered_entries) - rxn_iter = combinations(selected_combos, 2) - rxns.extend(self._get_rxns(rxn_iter, precursors, target, calculators)) + rxn_iter = self._get_rxn_iterable(combos, open_combos) + r = self._get_rxns( + rxn_iter, precursors, target, calculators, filtered_entries + ) + rxns.extend(r) return list(set(rxns)) - def estimate_num_reactions(self, entries: List[ComputedEntry]) -> int: + def estimate_max_num_reactions(self, entries: List[ComputedEntry]) -> int: """ Estimate the upper bound of the number of possible reactions. This will correlate with the amount of time it takes to enumerate reactions. @@ -140,60 +126,160 @@ def estimate_num_reactions(self, entries: List[ComputedEntry]) -> int: Returns: The upper bound on the number of possible reactions """ - return sum([comb(len(entries), i) for i in range(self.n)]) ** 2 + return sum([comb(len(entries), i) for i in range(1, self.n + 1)]) ** 2 + + def _get_combos_dict(self, entries, precursor_entries, target_entries): + precursor_elems = ( + get_elems_set(precursor_entries) if precursor_entries else set() + ) + target_elems = ( + {e.name for e in target_entries.composition.elements} + if target_entries + else set() + ) + + combos = [set(c) for c in limited_powerset(entries, self.n)] + + combos_dict = group_by_chemsys(combos) + filtered_combos = self._filter_dict_by_elems( + combos_dict, precursor_elems, target_elems + ) - def _get_rxns(self, rxn_iter, precursors, target, calculators, open=[]): + return filtered_combos + + def _get_open_combos(self, entries): + """ No open entries for BasicEnumerator, returns None""" + return None + + def _get_rxns( + self, rxn_iterable, precursors, target, calculators, filtered_entries=None + ): """ Returns reactions from an iterable representing the combination of 2 sets - of phases + of phases. Works for reactions with open phases. """ + pd = None + if self.build_pd: + pd = PhaseDiagram(filtered_entries) + + grand_pd = None + if self.build_grand_pd: + chempots = getattr(self, "chempots") + grand_pd = GrandPotentialPhaseDiagram(filtered_entries, chempots) + rxns = [] - open = set(open) - for reactants, products in rxn_iter: - r = set(reactants) - p = set(products) - all_phases = r | p | open + for reactants, products in rxn_iterable: + r = set(reactants) if reactants else set() + p = set(products) if products else set() + all_phases = r | p - if r & p: # do not allow repeated phases - continue - if target and target not in all_phases: + if (r & p) or (precursors and not precursors.issubset(all_phases)): continue - forward_rxn = ComputedReaction.balance(r, p) + suggested_rxns = self._react(r, p, calculators, pd, grand_pd) + + for rxn in suggested_rxns: + if ( + rxn.is_identity + or (self.remove_unbalanced and not rxn.balanced) + or (self.remove_changed and rxn.lowest_num_errors != 0) + ): + continue + + if not target or target in rxn.product_entries: + if not precursors or precursors.issubset(rxn.reactant_entries): + rxns.append(rxn) + + return rxns + + def _react(self, reactants, products, calculators, pd=None, grand_pd=None): + forward_rxn = ComputedReaction.balance(reactants, products) + backward_rxn = forward_rxn.reverse() + + forward_rxn = apply_calculators(forward_rxn, calculators) + backward_rxn = apply_calculators(backward_rxn, calculators) + return [forward_rxn, backward_rxn] + + def _get_rxn_iterable(self, combos, open_combos): + return combinations(combos, 2) + + def _get_initialized_entries(self, entries): + precursors, target = None, None + entries_new = entries.copy() - if (self.remove_unbalanced and not (forward_rxn.balanced)) or ( - self.remove_changed and forward_rxn.lowest_num_errors != 0 + if self.precursors: + precursors = { + initialize_entry(f, entries, self.stabilize) for f in self.precursors + } + for p in precursors: + if p not in entries: + old_entry = entries_new.get_min_entry_by_formula( + p.composition.reduced_formula + ) + entries_new.remove(old_entry) + entries_new.add(p) + + if self.target: + target = initialize_entry(self.target, entries, self.stabilize) + if self.stabilize: + entries_new.remove(entries.get_min_entry_by_formula(self.target)) + entries_new.add(target) + + if self.stabilize: + entries_new = entries_new.filter_by_stability(e_above_hull=0.0) + self.logger.info("Filtering by stable entries!") + + return entries_new, precursors, target + + @staticmethod + def _filter_dict_by_elems(combos_dict, precursor_elems, target_elems): + filtered_dict = dict() + for chemsys, combos in combos_dict.items(): + elems = chemsys.split("-") + if ( + (target_elems and not target_elems.issubset(elems)) + or (precursor_elems and not precursor_elems.issubset(elems)) + or len(elems) >= 10 + or len(elems) == 1 ): - forward_rxn = None - backward_rxn = None + continue else: - backward_rxn = forward_rxn.reverse() - - if forward_rxn: - if not target or target in p: - if not precursors or (r - open).issubset(precursors): - forward_rxn = apply_calculators(forward_rxn, calculators) - rxns.append(forward_rxn) - if not target or target in r: - if not precursors or (p - open).issubset(precursors): - backward_rxn = apply_calculators(backward_rxn, calculators) - rxns.append(backward_rxn) + filtered_dict[chemsys] = combos - return rxns + return filtered_dict + + @property + def stabilize(self): + """ Whether or not to use only stable entries in analysis""" + return self._stabilize + + @property + def build_pd(self): + """Whether or not to build a PhaseDiagram object during reaction enumeration ( + useful for some analyses)""" + return self._build_pd + + @property + def build_grand_pd(self): + """Whether or not to build a GrandPotentialPhaseDiagram object during + reaction enumeration (useful for some analyses)""" + return self._build_grand_pd class BasicOpenEnumerator(BasicEnumerator): """ Enumerator for finding all simple reactions within a set of entries, up to a - maximum reactant/product cardinality (n), with any number of open phases. + maximum reactant/product cardinality (n), with any number of open phases. Note: + this does not return OpenComputedReaction objects (this can be calculated using + the ReactionSet class). """ def __init__( self, - open_entries: List[str], + open_phases: List[str], precursors: Optional[List[str]] = None, target: Optional[str] = None, - calculators: Optional[List[Calculator]] = None, + calculators: Optional[List[str]] = None, n: int = 2, remove_unbalanced: bool = True, remove_changed: bool = True, @@ -203,8 +289,9 @@ def __init__( objects during enumeration. Args: - open_entries: List of formulas of open entries (e.g. ["O2"]) - precursors: + open_phases: List of formulas of open entries (e.g. ["O2"]) + precursors: Optional list of formulas of precursor phases; only reactions + which have these phases as reactants will be enumerated. target: Optional formula of target; only reactions which make this target will be enumerated. calculators: Optional list of Calculator object names; see calculators @@ -219,92 +306,46 @@ def __init__( super().__init__( precursors, target, calculators, n, remove_unbalanced, remove_changed ) - self.open_entries = open_entries + self.open_phases = open_phases - def enumerate(self, entries: GibbsEntrySet) -> List[ComputedReaction]: + def estimate_max_num_reactions(self, entries: List[ComputedEntry]) -> int: """ - Calculate all possible reactions given a set of entries. If the enumerator - was initialized with precursors/target, only reactions containing these - phases will be enumerated. + Estimate the upper bound of the number of possible reactions. This will + correlate with the amount of time it takes to enumerate reactions. Args: - entries: the set of all entries to enumerate from + entries: A list of all entries to consider - Returns: - List of unique computed reactions. Note: this does not return - OpenComputedReaction objects (this can be calculated using the - ReactionSet class). + Returns: The upper bound on the number of possible reactions """ - entries = GibbsEntrySet(entries) - - target = None - if self.target: - target = initialize_entry(self.target, entries) - entries.add(target) - target_elems = {str(e) for e in target.composition.elements} - precursors = None + num_open_phases = len(self.open_phases) + num_combos_with_open = sum( + [comb(num_open_phases, i) for i in range(1, num_open_phases + 1)] + ) - precursors = None - if self.precursors: - precursors = {initialize_entry(f, entries) for f in self.precursors} - for p in precursors: - entries.add(p) - precursor_elems = { - str(elem) for p in precursors for elem in p.composition.elements - } + num_total_combos = 0 + for i in range(1, self.n + 1): + num_combos = comb(len(entries), i) + num_total_combos += num_combos_with_open * num_combos - if self.stabilize: - entries = entries.filter_by_stability(e_above_hull=0.0) - self.logger.info( - "Filtering by stable entries due to use of " "ChempotDistanceCalculator" - ) + return num_total_combos ** 2 - combos = [set(c) for c in limited_powerset(entries, self.n)] - open_entries = initialize_open_entries(self.open_entries, entries) - open_entry_elems = { - str(elem) for entry in open_entries for elem in entry.composition.elements + def _get_open_combos(self, entries): + open_entries = { + e for e in entries if e.composition.reduced_formula in self.open_phases } - if precursors: - precursor_elems = precursor_elems | open_entry_elems open_combos = [ set(c) for c in limited_powerset(open_entries, len(open_entries)) ] + return open_combos + + def _get_rxn_iterable(self, combos, open_combos): combos_with_open = [ combo | open_combo for combo in combos for open_combo in open_combos if not combo & open_combo ] - combos_dict = group_by_chemsys(combos) - combos_open_dict = group_by_chemsys(combos_with_open) + rxn_iter = product(combos, combos_with_open) - pbar = tqdm(combos_dict.items(), desc="BasicOpenEnumerator") - rxns = [] - for chemsys, selected_combos in pbar: - pbar.set_description(f"{chemsys}") - elems = chemsys.split("-") - if chemsys not in combos_open_dict: - continue - if target and not target_elems.issubset(elems): - continue - - filtered_entries = filter_entries_by_chemsys(entries, chemsys) - calculators = initialize_calculators(self.calculators, filtered_entries) - - if ( - (target and not target_elems.issubset(elems)) - or (precursors and not precursor_elems.issuperset(elems)) - or len(elems) >= 10 - ): - continue - - selected_open_combos = combos_open_dict[chemsys] - rxn_iter = product(selected_combos, selected_open_combos) - - rxns.extend( - self._get_rxns( - rxn_iter, precursors, target, calculators, open=open_entries - ) - ) - - return list(set(rxns)) + return rxn_iter diff --git a/src/rxn_network/enumerators/minimize.py b/src/rxn_network/enumerators/minimize.py index f7d8d765..aaf55afc 100644 --- a/src/rxn_network/enumerators/minimize.py +++ b/src/rxn_network/enumerators/minimize.py @@ -1,33 +1,21 @@ -from itertools import chain, combinations, compress, groupby, product +from itertools import combinations, product from math import comb from typing import List, Optional -import numpy as np from pymatgen.analysis.interface_reactions import InterfacialReactivity -from pymatgen.analysis.phase_diagram import GrandPotentialPhaseDiagram, PhaseDiagram from pymatgen.core.composition import Element from pymatgen.entries.computed_entries import ComputedEntry from tqdm.auto import tqdm -from rxn_network.core import Enumerator, Reaction -from rxn_network.costs.calculators import Calculator, ChempotDistanceCalculator -from rxn_network.entries.entry_set import GibbsEntrySet +from rxn_network.enumerators.basic import BasicEnumerator from rxn_network.enumerators.utils import ( apply_calculators, - filter_entries_by_chemsys, get_computed_rxn, - get_entry_by_comp, get_open_computed_rxn, - get_total_chemsys, - group_by_chemsys, - initialize_calculators, - initialize_entry, ) -from rxn_network.reactions import ComputedReaction -from rxn_network.thermo.chempot_diagram import ChempotDiagram -class MinimizeGibbsEnumerator(Enumerator): +class MinimizeGibbsEnumerator(BasicEnumerator): """ Enumerator for finding all reactions between two reactants that are predicted by thermodynamics; i.e., they appear when taking the convex hull along a straight @@ -50,84 +38,40 @@ def __init__( module for options (e.g., ["ChempotDistanceCalculator]) """ super().__init__(precursors, target, calculators) + self._build_pd = True - def enumerate(self, entries): + def estimate_max_num_reactions(self, entries: List[ComputedEntry]) -> int: """ - Calculate all possible reactions given a set of entries. If the enumerator - was initialized with a target, only reactions to this target will be considered. + Estimate the upper bound of the number of possible reactions. This will + correlate with the amount of time it takes to enumerate reactions. Args: - entries: the set of all entries to enumerate from + entries: A list of all entries to consider - Returns: - List of unique computed reactions. + Returns: The upper bound on the number of possible reactions """ - entries = GibbsEntrySet(entries) - - target = None - if self.target: - target = initialize_entry(self.target, entries) - entries.add(target) - target_elems = {str(e) for e in target.composition.elements} - - precursors = None - if self.precursors: - precursors = {initialize_entry(f, entries) for f in self.precursors} - for p in precursors: - entries.add(p) - precursor_elems = { - str(elem) for p in precursors for elem in p.composition.elements - } - - if "ChempotDistanceCalculator" in self.calculators: - entries = entries.filter_by_stability(e_above_hull=0.0) - self.logger.info( - "Filtering by stable entries due to use of 'ChempotDistanceCalculator'" - ) - - combos = list(combinations(entries, 2)) - combos_dict = group_by_chemsys(combos) + return comb(len(entries), 2) * 2 - rxns = [] - for chemsys, combos in tqdm(combos_dict.items()): - elems = chemsys.split("-") - if ( - (target and not target_elems.issubset(elems)) - or (precursors and not precursor_elems.issuperset(elems)) - or len(elems) >= 10 - ): - continue - - chemsys_entries = filter_entries_by_chemsys(entries, chemsys) - pd = PhaseDiagram(chemsys_entries) - calculators = initialize_calculators(self.calculators, chemsys_entries) + def _react(self, reactants, products, calculators, pd=None, grand_pd=None): + r = list(reactants) + r0 = r[0] - for e1, e2 in combos: - if precursors and {e1, e2} != precursors: - continue - predicted_rxns = self._react_interface( - e1.composition, e2.composition, pd, calculators=calculators - ) - rxns.extend(predicted_rxns) + if len(r) == 1: + r1 = r[0] + else: + r1 = r[1] - return list(set(rxns)) + return self._react_interface( + r0.composition, r1.composition, pd, grand_pd, calculators=calculators + ) - def estimate_num_reactions(self, entries: List[ComputedEntry]) -> int: - """ - Estimate the upper bound of the number of possible reactions. This will - correlate with the amount of time it takes to enumerate reactions. - - Args: - entries: A list of all entries to consider + def _get_rxn_iterable(self, combos, open_entries): + return product(combos, [None]) - Returns: The upper bound on the number of possible reactions - """ - return comb(len(entries), 2) + def _react_interface(self, r1, r2, pd, grand_pd=None, calculators=None): + """Simple API for InterfacialReactivity module from pymatgen.""" + chempots = None - def _react_interface( - self, r1, r2, pd, grand_pd=None, open_entry=None, calculators=None - ): - "Simple API for InterfacialReactivity module from pymatgen." if grand_pd: interface = InterfacialReactivity( r1, @@ -158,12 +102,6 @@ def _react_interface( else: rxn = get_computed_rxn(rxn, pd.all_entries) - if rxn.is_identity or rxn.lowest_num_errors > 0: - continue - - if self.target and self.target not in rxn.product_entries: - continue - rxn = apply_calculators(rxn, calculators) rxns.append(rxn) @@ -184,74 +122,34 @@ def __init__( mu: float, precursors: Optional[List[str]] = None, target: Optional[str] = None, - calculators: Optional[str] = None, + calculators: Optional[List[str]] = None, ): super().__init__(precursors=precursors, target=target, calculators=calculators) - self.open_elem = Element(open_elem) + self.open_elem = Element(open_elem) # type: ignore self.mu = mu + self.chempots = {self.open_elem: self.mu} + self._build_grand_pd = True - def enumerate(self, entries): - entries = GibbsEntrySet(entries) - - target = None - if self.target: - target = initialize_entry(self.target, entries) - entries.add(target) - target_elems = {str(e) for e in target.composition.elements} - - precursors = None - if self.precursors: - precursors = {initialize_entry(f, entries) for f in self.precursors} - for p in precursors: - entries.add(p) - precursor_elems = { - str(elem) for p in precursors for elem in p.composition.elements - } - - if "ChempotDistanceCalculator" in self.calculators: - entries = entries.filter_by_stability(e_above_hull=0.0) - self.logger.info( - "Filtering by stable entries due to use of 'ChempotDistanceCalculator'" - ) - - open_entry = sorted( - filter(lambda e: e.composition.elements == [self.open_elem], entries), - key=lambda e: e.energy_per_atom, - )[0] - entries_no_open = GibbsEntrySet(entries) - entries_no_open.remove(open_entry) - combos = list(combinations(entries_no_open, 2)) - combos_dict = group_by_chemsys(combos, self.open_elem) - - rxns = [] - for chemsys, combos in tqdm(combos_dict.items()): - elems = chemsys.split("-") - if ( - (target and not target_elems.issubset(elems)) - or (precursors and not precursor_elems.issuperset(elems)) - or len(elems) >= 10 - ): - continue - - chemsys_entries = filter_entries_by_chemsys(entries, chemsys) - pd = PhaseDiagram(chemsys_entries) + def _react(self, reactants, products, calculators, pd=None, grand_pd=None): + r = list(reactants) + r0 = r[0] - calculators = initialize_calculators(self.calculators, chemsys_entries) - - grand_pd = GrandPotentialPhaseDiagram( - chemsys_entries, {self.open_elem: self.mu} - ) - for e1, e2 in combos: - if precursors and {e1, e2} != precursors: - continue - predicted_rxns = self._react_interface( - e1.composition, - e2.composition, - pd, - grand_pd, - open_entry, - calculators, - ) - rxns.extend(predicted_rxns) - - return list(set(rxns)) + if len(r) == 1: + r1 = r[0] + else: + r1 = r[1] + + open_elem = list(grand_pd.chempots.keys())[0] + + for reactant in r: + elems = reactant.composition.elements + if len(elems) == 1 and elems[0] == open_elem: # skip if reactant = open_e + return [] + + return self._react_interface( + r0.composition, + r1.composition, + pd, + grand_pd=grand_pd, + calculators=calculators, + ) diff --git a/src/rxn_network/enumerators/utils.py b/src/rxn_network/enumerators/utils.py index 50e3ab07..219affcf 100644 --- a/src/rxn_network/enumerators/utils.py +++ b/src/rxn_network/enumerators/utils.py @@ -1,66 +1,56 @@ -from itertools import permutations +""" +Helpful utility functions used by the enumerator classes. +""" +from typing import List, Union -import numpy as np -from pymatgen.entries.computed_entries import ComputedEntry +from pymatgen.entries.computed_entries import Entry, ComputedEntry import rxn_network.costs.calculators as calcs +from rxn_network.entries.entry_set import GibbsEntrySet from rxn_network.reactions.computed import ComputedReaction from rxn_network.reactions.open import OpenComputedReaction -from rxn_network.utils import limited_powerset -def initialize_entry(formula, entry_set, stabilize=True): +def initialize_entry(formula: str, entry_set: GibbsEntrySet, stabilize: bool = True): """ + Acquire a (stabilized) entry by user-specified formula. Args: - formula: - entry_set: - - Returns: - + formula: Chemical formula + entry_set: GibbsEntrySet containing 1 or more entries corresponding to + given formula + stabilize: Whether or not to stabilize the entry by decreasing its energy + such that it is 'on the hull' """ entry = entry_set.get_min_entry_by_formula(formula) + if stabilize: entry = entry_set.stabilize_entry(entry) return entry -def initialize_open_entries(open_entries, entry_set): +def initialize_calculators( + calculators: Union[List[calcs.Calculator], List[str]], entries: GibbsEntrySet +): """ + Initialize a list of Calculators given a list of their names (strings) or + uninitialized objects, and a provided list of entries. Args: - open_entries: - entry_set: - - Returns: - - """ - open_entries = [entry_set.get_min_entry_by_formula(e) for e in open_entries] - return open_entries - - -def initialize_calculators(calculators, entries): - """ - - Args: - calculators: - entries: - - Returns: - + calculators: List of names of calculators + entries: List of entries or EntrySet-type object """ calculators = [getattr(calcs, c) if isinstance(c, str) else c for c in calculators] - return [c.from_entries(entries) for c in calculators] + return [c.from_entries(entries) for c in calculators] # type: ignore -def apply_calculators(rxn, calculators): +def apply_calculators(rxn: ComputedReaction, calculators: List[calcs.Calculator]): """ + Decorates a reaction by applying decorate() from a list of calculators. Args: - rxn: - calculators: - - Returns: + rxn: ComputedReaction object + calculators: List of (initialized) calculators """ for calc in calculators: @@ -68,15 +58,13 @@ def apply_calculators(rxn, calculators): return rxn -def get_total_chemsys(entries, open_elem=None): +def get_total_chemsys(entries: List[Entry], open_elem=None): """ + Returns chemical system for set of entries, with optional open element. Args: entries: open_elem: - - Returns: - """ elements = {elem for entry in entries for elem in entry.composition.elements} if open_elem: @@ -84,6 +72,18 @@ def get_total_chemsys(entries, open_elem=None): return "-".join(sorted([str(e) for e in elements])) +def get_elems_set(entries): + """ + + Args: + entries: + + Returns: + + """ + return {str(elem) for e in entries for elem in e.composition.elements} + + def group_by_chemsys(combos, open_elem=None): """ @@ -122,7 +122,7 @@ def stabilize_entries(pd, entries_to_adjust, tol=1e-6): e_above_hull = pd.get_e_above_hull(entry) entry_dict = entry.to_dict() entry_dict["energy"] = entry.uncorrected_energy + ( - e_above_hull * entry.composition.num_atoms + e_above_hull * entry.composition.num_atoms - tol ) new_entry = ComputedEntry.from_dict(entry_dict) new_entries.append(new_entry) @@ -140,6 +140,7 @@ def filter_entries_by_chemsys(entries, chemsys): """ chemsys = set(chemsys.split("-")) + filtered_entries = list( filter( lambda e: chemsys.issuperset(e.composition.chemical_system.split("-")), diff --git a/src/rxn_network/firetasks/build_inputs.py b/src/rxn_network/firetasks/build_inputs.py index 957e8002..f5d6a953 100644 --- a/src/rxn_network/firetasks/build_inputs.py +++ b/src/rxn_network/firetasks/build_inputs.py @@ -1,15 +1,12 @@ -" Firetasks for acquiring ComputedEntry data from MPRester or another materials MongoDB" -import datetime +""" +Firetasks for acquiring ComputedEntry data from MPRester or another materials MongoDB +""" import itertools -import json -import os import warnings -from typing import Union +from typing import Union, Optional, List from fireworks import FiretaskBase, FWAction, explicit_serialize from maggma.stores import MongoStore -from monty.json import MontyDecoder, jsanitize -from monty.serialization import loadfn from pymatgen.core.structure import Structure from pymatgen.entries.computed_entries import ComputedEntry, ComputedStructureEntry from pymatgen.ext.matproj import MPRester @@ -138,14 +135,14 @@ def process_entries(entries, temperature, e_above_hull, include_polymorphs): def get_entries( # noqa: C901 - db: str, + db: MongoStore, chemsys_formula_id_criteria: Union[str, dict], - compatible_only=True, - inc_structure=None, - property_data=None, - use_premade_entries=False, - conventional_unit_cell=False, - sort_by_e_above_hull=False, + compatible_only: bool = True, + inc_structure: bool = None, + property_data: Optional[List[str]] = None, + use_premade_entries: bool = False, + conventional_unit_cell: bool = False, + sort_by_e_above_hull: bool = False, ): """ Get a list of ComputedEntries or ComputedStructureEntries corresponding @@ -153,27 +150,29 @@ def get_entries( # noqa: C901 from pymatgen.ext.matproj. Args: - db: - chemsys_formula_id_criteria (str/dict): A chemical system + db: MongoStore object with database connection + chemsys_formula_id_criteria: A chemical system (e.g., Li-Fe-O), or formula (e.g., Fe2O3) or materials_id (e.g., mp-1234) or full Mongo-style dict criteria. - compatible_only (bool): Whether to return only "compatible" + compatible_only: Whether to return only "compatible" entries. Compatible entries are entries that have been processed using the MaterialsProjectCompatibility class, which performs adjustments to allow mixing of GGA and GGA+U calculations for more accurate phase diagrams and reaction energies. - inc_structure (str): If None, entries returned are + inc_structure: If None, entries returned are ComputedEntries. If inc_structure="initial", ComputedStructureEntries with initial structures are returned. Otherwise, ComputedStructureEntries with final structures are returned. - property_data (list): Specify additional properties to include in + property_data: Specify additional properties to include in entry.data. If None, no data. Should be a subset of supported_properties. - conventional_unit_cell (bool): Whether to get the standard + use_premade_entries: Whether to use entry objects that have already been + constructed. Defaults to False. + conventional_unit_cell: Whether to get the standard conventional unit cell - sort_by_e_above_hull (bool): Whether to sort the list of entries by + sort_by_e_above_hull: Whether to sort the list of entries by e_above_hull (will query e_above_hull as a property_data if True). Returns: List of ComputedEntry or ComputedStructureEntry objects. diff --git a/src/rxn_network/firetasks/parse_outputs.py b/src/rxn_network/firetasks/parse_outputs.py index ad3330c9..fdf8017f 100644 --- a/src/rxn_network/firetasks/parse_outputs.py +++ b/src/rxn_network/firetasks/parse_outputs.py @@ -1,4 +1,6 @@ -" Firetasks for storing enumerated reaction or network data into a MongoDB." +""" +Firetasks for storing enumerated reaction or network data into a MongoDB. +""" import datetime import json import os diff --git a/src/rxn_network/firetasks/run_calc.py b/src/rxn_network/firetasks/run_calc.py index 139714ca..aded39fb 100644 --- a/src/rxn_network/firetasks/run_calc.py +++ b/src/rxn_network/firetasks/run_calc.py @@ -1,4 +1,6 @@ -" Firetasks for running enumeration and network calculations." +""" +Firetasks for running enumeration and network calculations +""" import json from fireworks import FiretaskBase, FWAction, explicit_serialize @@ -48,11 +50,12 @@ def run_task(self, fw_spec): } added_elems = "-".join(sorted(list(added_elems))) - metadata = {} - metadata["chemsys"] = chemsys - metadata["enumerators"] = enumerators - metadata["target"] = target - metadata["added_elems"] = added_elems + metadata = { + "chemsys": chemsys, + "enumerators": enumerators, + "target": target, + "added_elems": added_elems, + } results = [] for enumerator in enumerators: diff --git a/src/rxn_network/firetasks/utils.py b/src/rxn_network/firetasks/utils.py index 2abe21e7..eb01c5f3 100644 --- a/src/rxn_network/firetasks/utils.py +++ b/src/rxn_network/firetasks/utils.py @@ -1,4 +1,6 @@ -"Utility Fireworks functions borrowed from the atomate package." +""" +Utility Fireworks functions borrowed from the atomate package +""" import logging import os import sys diff --git a/src/rxn_network/fireworks/__init__.py b/src/rxn_network/fireworks/__init__.py index 606be6f1..53f7f279 100644 --- a/src/rxn_network/fireworks/__init__.py +++ b/src/rxn_network/fireworks/__init__.py @@ -1 +1 @@ -from rxn_network.fireworks.core import EnumeratorFW +from rxn_network.fireworks.core import EnumeratorFW, NetworkFW diff --git a/src/rxn_network/fireworks/core.py b/src/rxn_network/fireworks/core.py index 18a92717..8457478c 100644 --- a/src/rxn_network/fireworks/core.py +++ b/src/rxn_network/fireworks/core.py @@ -1,8 +1,13 @@ +""" +Implementation of Fireworks for performing reaction enumreation and network +construction +""" from fireworks import Firework from rxn_network.entries.entry_set import GibbsEntrySet from rxn_network.firetasks.build_inputs import EntriesFromDb, EntriesFromMPRester from rxn_network.firetasks.parse_outputs import ReactionsToDb + from rxn_network.firetasks.run_calc import RunEnumerators diff --git a/src/rxn_network/network/__init__.py b/src/rxn_network/network/__init__.py index e69de29b..e1056eac 100644 --- a/src/rxn_network/network/__init__.py +++ b/src/rxn_network/network/__init__.py @@ -0,0 +1,2 @@ +from rxn_network.network.entry import NetworkEntry +from rxn_network.network.network import ReactionNetwork diff --git a/src/rxn_network/network/entry.py b/src/rxn_network/network/entry.py index b2ed84ce..c24b7aaf 100644 --- a/src/rxn_network/network/entry.py +++ b/src/rxn_network/network/entry.py @@ -1,4 +1,7 @@ -" Basic Entry to hold multiple entries for the network book keeping " +""" +Entry objects used in a Network. This holds multiple entries and can be used as data +for a graph node. +""" from enum import Enum, auto from typing import List @@ -7,7 +10,8 @@ class NetworkEntryType(Enum): - "Describes the Network Entry Type" + """Describes the Network Entry Type""" + Precursors = auto() Reactants = auto() Products = auto() @@ -24,7 +28,7 @@ class NetworkEntry(MSONable): def __init__(self, entries: List[Entry], description: NetworkEntryType): """ Args: - entries: list of ComputedEntry-like objects + entries: list of ComputedEntry-like objects description: Node type """ self.entries = set(entries) @@ -52,24 +56,24 @@ def __hash__(self): class DummyEntry(NetworkEntry): - "A Dummy Entry that doesn't hold any info" + """A Dummy Entry that doesn't hold any info""" def __init__(self): # pylint: disable=W0231 - "Dummy node doesn't need any parameters" + """Dummy node doesn't need any parameters""" @property def entries(self): - "No entries in DummyEntry" + """No entries in DummyEntry""" return [] @property def chemsys(self): - "No Chemsys to DummyEntry" + """No Chemsys to DummyEntry""" return "" @property def description(self): - "DummyEntry is always of type Dummy" + """DummyEntry is always of type Dummy""" return NetworkEntryType.Dummy def __repr__(self): diff --git a/src/rxn_network/network/adaptors/gt.py b/src/rxn_network/network/gt.py similarity index 97% rename from src/rxn_network/network/adaptors/gt.py rename to src/rxn_network/network/gt.py index 46f1d96e..919b9789 100644 --- a/src/rxn_network/network/adaptors/gt.py +++ b/src/rxn_network/network/gt.py @@ -1,3 +1,7 @@ +""" +Graph-related functions specific to the graph-tool library. Used in the network module. +""" + from queue import Empty, PriorityQueue from typing import Dict @@ -103,7 +107,7 @@ def path_cost(vertices): a = [path] a_costs = [path_cost(path)] - b = PriorityQueue() # automatically sorts by path cost (priority) + b = PriorityQueue() # type: ignore g.ep["bool"] = g.new_edge_property("bool", val=True) @@ -152,7 +156,6 @@ def path_cost(vertices): return a -@staticmethod def update_vertex_properties(g, v, prop_dict): """ Helper method for updating several vertex properties at once in a graph-tool diff --git a/src/rxn_network/network/network.py b/src/rxn_network/network/network.py index d0614d36..1595d6fd 100644 --- a/src/rxn_network/network/network.py +++ b/src/rxn_network/network/network.py @@ -1,12 +1,14 @@ -"Implementation of reaction network interface" -import logging +""" +Implementation of an actual reaction network interface. +""" + from typing import List, Optional from graph_tool.util import find_edge, find_vertex from rxn_network.core import CostFunction, Enumerator, Network from rxn_network.entries.entry_set import GibbsEntrySet -from rxn_network.network.adaptors.gt import ( +from rxn_network.network.gt import ( initialize_graph, update_vertex_props, yens_ksp, @@ -14,7 +16,6 @@ from rxn_network.network.entry import NetworkEntry, NetworkEntryType from rxn_network.network.utils import get_loopback_edges, get_rxn_nodes_and_edges from rxn_network.pathways.basic import BasicPathway -from rxn_network.reactions.computed import ComputedReaction from rxn_network.reactions.reaction_set import ReactionSet @@ -53,8 +54,8 @@ def __init__( def build(self): """ Construct the reaction network graph object and store under the "graph" - attribute. Does NOT initialize precursors or target; you must call set_precursors() or - set_target() to do so. + attribute. Does NOT initialize precursors or target; you must call set_precursors() + or set_target() to do so. Returns: None @@ -198,7 +199,7 @@ def set_target(self, target): self.target = target def _shortest_paths(self, k=15): - "Finds the k shortest paths using Yen's algorithm and returns BasicPathways" + """Finds the k shortest paths using Yen's algorithm and returns BasicPathways""" g = self._g paths = [] @@ -208,7 +209,7 @@ def _shortest_paths(self, k=15): target_v = find_vertex(g, g.vp["type"], NetworkEntryType.Target.value)[0] for path in yens_ksp(g, k, precursors_v, target_v): - paths.append(BasicPathway.from_graph_path(g, path)) + paths.append(self._path_from_graph(g, path)) for path in paths: print(path, "\n") @@ -224,6 +225,20 @@ def _get_rxns(self) -> ReactionSet: rxns = ReactionSet.from_rxns(rxns, self.entries) return rxns + @staticmethod + def _path_from_graph(g, path): + rxns = [] + costs = [] + + for step, v in enumerate(path): + if g.vp["type"][v] == NetworkEntryType.Products.value: + e = g.edge(path[step - 1], v) + + rxns.append(g.ep["rxn"][e]) + costs.append(g.ep["cost"][e]) + + return BasicPathway(reactions=rxns, costs=costs) + @property def graph(self): return self._g diff --git a/src/rxn_network/network/utils.py b/src/rxn_network/network/utils.py index bda029eb..17b1ac42 100644 --- a/src/rxn_network/network/utils.py +++ b/src/rxn_network/network/utils.py @@ -1,3 +1,7 @@ +""" +Utility functions used in the ReactionNetwork class. +""" + from rxn_network.network.entry import NetworkEntry, NetworkEntryType diff --git a/src/rxn_network/network/visualize.py b/src/rxn_network/network/visualize.py index d0df9731..67422b79 100644 --- a/src/rxn_network/network/visualize.py +++ b/src/rxn_network/network/visualize.py @@ -1,3 +1,7 @@ +""" +Functions for visualizing/plotting reaction networks. +""" + import graph_tool.all as gt import matplotlib.cm import numpy as np @@ -67,6 +71,7 @@ def plot_network_on_graphistry(graph): "Must install optional dependencies: pygraphistry, networkx, " "and pyintergraph!" ) + return nx_graph = pyintergraph.gt2nx(graph) mapping = {} diff --git a/src/rxn_network/pathways/__init__.py b/src/rxn_network/pathways/__init__.py index d0156ec8..63f04e0b 100644 --- a/src/rxn_network/pathways/__init__.py +++ b/src/rxn_network/pathways/__init__.py @@ -1 +1,4 @@ -" Implementations of Reaction Network Pathway " +""" Implementations of Reaction Network Pathway """ +from rxn_network.pathways.balanced import BalancedPathway +from rxn_network.pathways.basic import BasicPathway +from rxn_network.pathways.solver import PathwaySolver diff --git a/src/rxn_network/pathways/balanced.py b/src/rxn_network/pathways/balanced.py index 19558ffc..61f53ebd 100644 --- a/src/rxn_network/pathways/balanced.py +++ b/src/rxn_network/pathways/balanced.py @@ -1,13 +1,12 @@ -" A balanced reaction pathway class" -from functools import cached_property +""" +Implements a class for storing balanced reaction pathways. +""" from typing import List, Optional, Union import numpy as np from rxn_network.core import Pathway, Reaction from rxn_network.pathways.basic import BasicPathway -from rxn_network.pathways.utils import balance_path_arrays -from rxn_network.reactions.basic import BasicReaction from rxn_network.utils import limited_powerset diff --git a/src/rxn_network/pathways/basic.py b/src/rxn_network/pathways/basic.py index 76176e0f..24ad7e6f 100644 --- a/src/rxn_network/pathways/basic.py +++ b/src/rxn_network/pathways/basic.py @@ -1,9 +1,11 @@ -" A basic reaction pathway class" +""" +Implements a class for storing (unbalanced/unconstrained) collection of reactions +forming a reaction pathway. +""" from typing import List, Optional from rxn_network.core import Pathway, Reaction -from rxn_network.network.entry import NetworkEntryType class BasicPathway(Pathway): @@ -15,7 +17,7 @@ class BasicPathway(Pathway): def __init__(self, reactions: List[Reaction], costs: Optional[List[float]] = None): """ Args: - rxns ([ComputedReaction]): list of ComputedReaction objects in pymatgen + reactions ([ComputedReaction]): list of ComputedReaction objects in pymatgen which occur along path. costs ([float]): list of corresponding costs for each reaction. """ @@ -49,20 +51,6 @@ def __eq__(self, other): def __hash__(self): return hash(tuple(self.reactions)) - @classmethod - def from_graph_path(cls, g, path): - rxns = [] - costs = [] - - for step, v in enumerate(path): - if g.vp["type"][v] == NetworkEntryType.Products.value: - e = g.edge(path[step - 1], v) - - rxns.append(g.ep["rxn"][e]) - costs.append(g.ep["cost"][e]) - - return cls(reactions=rxns, costs=costs) - @property def total_cost(self): return sum(self.costs) diff --git a/src/rxn_network/pathways/solver.py b/src/rxn_network/pathways/solver.py index 9022265f..f6e70e30 100644 --- a/src/rxn_network/pathways/solver.py +++ b/src/rxn_network/pathways/solver.py @@ -1,12 +1,17 @@ -from itertools import chain, combinations, compress, groupby, product +""" +Implements a reaction pathway solver class which efficiently solves mass balance +equations using matrix operations. +""" + +from itertools import combinations from typing import List import numpy as np -from pymatgen.entries.entry_tools import EntrySet from scipy.special import comb from tqdm.notebook import tqdm -from rxn_network.core import CostFunction, Pathway, Reaction, Solver +from rxn_network.core import CostFunction, Pathway, Solver +from rxn_network.entries.entry_set import GibbsEntrySet from rxn_network.enumerators.basic import BasicEnumerator, BasicOpenEnumerator from rxn_network.pathways.balanced import BalancedPathway from rxn_network.pathways.utils import balance_path_arrays @@ -20,12 +25,21 @@ class PathwaySolver(Solver): def __init__( self, - entries: EntrySet, + entries: GibbsEntrySet, pathways: List[Pathway], cost_function: CostFunction, open_elem: str = None, chempot: float = None, ): + """ + + Args: + entries: + pathways: + cost_function: + open_elem: + chempot: + """ super().__init__(entries=entries, pathways=pathways) self.cost_function = cost_function @@ -34,14 +48,26 @@ def __init__( def solve( self, - net_rxn: Reaction, + net_rxn: ComputedReaction, max_num_combos: int = 4, find_intermediate_rxns: bool = True, intermediate_rxn_energy_cutoff: float = 0.0, filter_interdependent: bool = True, ): + """ + + Args: + net_rxn: + max_num_combos: + find_intermediate_rxns: + intermediate_rxn_energy_cutoff: + filter_interdependent: - entries = list(self.entries) + Returns: + + """ + + entries = self.entries.entries_list precursors = net_rxn.reactant_entries targets = net_rxn.product_entries @@ -68,6 +94,10 @@ def solve( reactions.append(r) costs.append(c) + net_rxn_vector = self._build_idx_vector(net_rxn) + if net_rxn in reactions: + reactions.remove(net_rxn) + paths = [] for n in range(1, max_num_combos + 1): total = int(comb(len(reactions), n) / self.BATCH_SIZE) + 1 @@ -86,14 +116,12 @@ def solve( ) comp_matrices = np.stack( [ - np.vstack([self.build_idx_vector(reactions[r]) for r in combo]) + np.vstack([self._build_idx_vector(reactions[r]) for r in combo]) for combo in combos if combo ] ) - c_mats, m_mats = balance_path_arrays( - comp_matrices, self.build_idx_vector(net_rxn) - ) + c_mats, m_mats = balance_path_arrays(comp_matrices, net_rxn_vector) all_c_mats.extend(c_mats) all_m_mats.extend(m_mats) @@ -101,18 +129,17 @@ def solve( path_rxns = [] path_costs = [] for rxn_mat in c_mat: - reactant_entries = [ - entries[i] for i in range(len(rxn_mat)) if rxn_mat[i] < 0 - ] - product_entries = [ - entries[i] for i in range(len(rxn_mat)) if rxn_mat[i] > 0 - ] - rxn = ComputedReaction.balance( - reactant_entries, - product_entries, + entries, coeffs = zip( + *[(entries[idx], c) for idx, c in enumerate(rxn_mat)] ) - path_rxns.append(rxn) - path_costs.append(costs[reactions.index(rxn)]) + + rxn = ComputedReaction(entries=entries, coefficients=coeffs) + try: + path_rxns.append(rxn) + path_costs.append(costs[reactions.index(rxn)]) + except Exception as e: + print(e) + continue p = BalancedPathway( path_rxns, m_mat.flatten(), path_costs, balanced=True @@ -132,6 +159,20 @@ def solve( filtered_paths = sorted(list(set(filtered_paths)), key=lambda p: p.average_cost) return filtered_paths + def _build_idx_vector(self, rxn): + """ + + Args: + rxn: + + Returns: + + """ + indices = [e.data.get("idx") for e in rxn.entries] + v = np.zeros(self.num_entries) + v[indices] = rxn.coefficients + return v + def _find_intermediate_rxns(self, precursors, targets, energy_cutoff): rxns = [] intermediates = {e for rxn in self.reactions for e in rxn.entries} @@ -156,7 +197,7 @@ def _find_intermediate_rxns(self, precursors, targets, energy_cutoff): if self.open_elem: boe = BasicOpenEnumerator( - open_entries=[self.open_elem], + open_phases=[self.open_elem], precursors=intermediate_formulas, target=target.composition.reduced_formula, ) @@ -171,9 +212,3 @@ def _find_intermediate_rxns(self, precursors, targets, energy_cutoff): self.logger.info(f"Found {len(rxns)} intermediate reactions!") return rxns - - def build_idx_vector(self, rxn): - indices = [e.data.get("idx") for e in rxn.entries] - v = np.zeros(self.num_entries) - v[indices] = rxn.coefficients - return v diff --git a/src/rxn_network/pathways/utils.py b/src/rxn_network/pathways/utils.py index df322b7b..8318fffa 100644 --- a/src/rxn_network/pathways/utils.py +++ b/src/rxn_network/pathways/utils.py @@ -1,30 +1,27 @@ +""" +Utility functions used in reaction pathway balancing. +""" + import numpy as np from numba import njit, prange @njit(parallel=True) def balance_path_arrays( - comp_matrices, - net_coeffs, - tol=1e-6, + comp_matrices: np.ndarray, + net_coeffs: np.ndarray, + tol: float = 1e-6, ): """ Fast solution for reaction multiplicities via mass balance stochiometric constraints. Parallelized using Numba. Args: - comp_matrices ([np.array]): list of numpy arrays containing stoichiometric - coefficients of all compositions in all reactions, for each trial - combination. - net_coeffs ([np.array]): list of numpy arrays containing stoichiometric - coefficients of net reaction. - tol (float): numerical tolerance for determining if a multiplicity is zero + comp_matrices: Array containing stoichiometric coefficients of all + compositions in all reactions, for each trial combination. + net_coeffs: Array containing stoichiometric coefficients of net reaction. + tol: numerical tolerance for determining if a multiplicity is zero (reaction was removed). - - Returns: - ([bool],[np.array]): Tuple containing bool identifying which trial - BalancedPathway objects were successfully balanced, and a list of all - multiplicities arrays. """ shape = comp_matrices.shape net_coeff_filter = np.argwhere(net_coeffs != 0).flatten() diff --git a/src/rxn_network/reactions/__init__.py b/src/rxn_network/reactions/__init__.py index 24ccf5e3..b9b39e98 100644 --- a/src/rxn_network/reactions/__init__.py +++ b/src/rxn_network/reactions/__init__.py @@ -1,3 +1,5 @@ -" Implementations of various reaction classes for the reaction-network " +""" Implementations of various reaction classes for the reaction-network """ from rxn_network.reactions.basic import BasicReaction from rxn_network.reactions.computed import ComputedReaction +from rxn_network.reactions.open import OpenComputedReaction +from rxn_network.reactions.reaction_set import ReactionSet diff --git a/src/rxn_network/reactions/basic.py b/src/rxn_network/reactions/basic.py index 1119bd60..9d06b56a 100644 --- a/src/rxn_network/reactions/basic.py +++ b/src/rxn_network/reactions/basic.py @@ -1,13 +1,11 @@ -# coding: utf-8 """ This module for defining chemical reaction objects was originally sourced from pymatgen and streamlined for the reaction-network code. """ import re -from functools import cached_property from itertools import chain, combinations -from typing import Dict, List, Optional +from typing import Dict, List, Optional, Union, Tuple import numpy as np from monty.fractions import gcd_float @@ -28,10 +26,10 @@ class BasicReaction(Reaction): def __init__( self, compositions: List[Composition], - coefficients: List[float], + coefficients: Union[List[float], np.ndarray], balanced: Optional[bool] = None, data: Optional[Dict] = None, - lowest_num_errors: Optional[int] = None, + lowest_num_errors: Union[int, float] = 0, ): """ A BasicReaction object is defined by a list of compositions and their @@ -51,13 +49,18 @@ def __init__( >= 1 means that the reaction may be different than intended (some phases may be shuffled or removed entirely). """ - self._compositions = compositions + self._compositions = [Composition(c) for c in compositions] self._coefficients = np.array(coefficients) + self.reactant_coeffs = { - comp: coeff for comp, coeff in zip(compositions, coefficients) if coeff < 0 + comp: coeff + for comp, coeff in zip(self._compositions, self._coefficients) + if coeff < 0 } self.product_coeffs = { - comp: coeff for comp, coeff in zip(compositions, coefficients) if coeff > 0 + comp: coeff + for comp, coeff in zip(self._compositions, self._coefficients) + if coeff > 0 } if balanced is not None: @@ -80,75 +83,36 @@ def __init__( self.data = data self.lowest_num_errors = lowest_num_errors - @property - def reactants(self) -> List[Composition]: - "List of reactants for this reaction" - return list(self.reactant_coeffs.keys()) - - @property - def products(self) -> List[Composition]: - "List of products for this reaction" - return list(self.product_coeffs.keys()) - - @property - def compositions(self) -> List[Composition]: - "List of composition objects for this reaction" - return self._compositions - - @property - def coefficients(self) -> np.array: # pylint: disable = W0236 - "Array of reaction coefficients" - return self._coefficients - - @property - def energy(self) -> float: - "The energy of this reaction" - raise ValueError("No energy for a basic reaction!") - - @property - def energy_per_atom(self) -> float: - "The energy per atom of this reaction" - raise ValueError("No energy (per atom) for a basic reaction!") - - @property - def is_identity(self): - "Returns True if the reaction has identical reactants and products" - if set(self.reactants) != set(self.products): - return False - if self.balanced is False: # if not balanced, can not check coefficients - return True - return all( - [ - np.isclose(self.reactant_coeffs[c] * -1, self.product_coeffs[c]) - for c in self.reactant_coeffs - ] - ) - - @property - def chemical_system(self): - return "-".join(sorted([str(el) for el in self.elements])) - - def copy(self) -> "BasicReaction": - "Returns a copy of the BasicReaction object" - return BasicReaction( - self.compositions, - self.coefficients, - self.balanced, - self.data, - self.lowest_num_errors, - ) - - def reverse(self) -> "Reaction": + @classmethod + def balance( + cls, + reactants: List[Composition], + products: List[Composition], + data: Optional[Dict] = None, + ) -> "BasicReaction": """ - Returns a copy of the original Reaction object where original reactants are - new products, and vice versa. + Reactants and products to be specified as list of + pymatgen.core.Composition. e.g., [comp1, comp2] + + Args: + reactants: List of reactants. + products: List of products. + data: Optional dictionary containing extra data about the reaction. """ - return Reaction( - self.compositions, - -1 * self.coefficients, - self.balanced, - self.data, - self.lowest_num_errors, + compositions = reactants + products + coeffs, lowest_num_errors = cls._balance_coeffs(reactants, products) + + balanced = True + if coeffs is None or lowest_num_errors == np.inf: + balanced = False + coeffs = np.zeros(len(compositions)) + + return cls( + compositions=compositions, + coefficients=coeffs, + balanced=balanced, + data=data, + lowest_num_errors=lowest_num_errors, ) def normalize_to(self, comp: Composition, factor: float = 1) -> "BasicReaction": @@ -223,93 +187,31 @@ def normalized_repr_and_factor(self): """ return self._str_from_comp(self.coefficients, self.compositions, True) - @property - def normalized_repr(self): - """ - A normalized representation of the reaction. All factors are converted - to lowest common factors. - """ - return self.normalized_repr_and_factor()[0] - - @staticmethod - def _reduce(coeffs, compositions): - r_coeffs = np.zeros(len(coeffs)) - r_comps = [] - for i, (amt, comp) in enumerate(zip(coeffs, compositions)): - comp, factor = comp.get_reduced_composition_and_factor() - r_coeffs[i] = amt * factor - r_comps.append(comp) - - factor = 1 / gcd_float(np.abs(r_coeffs)) - r_coeffs *= factor - return r_coeffs, r_comps, factor - - @classmethod - def _str_from_formulas(cls, coeffs, formulas) -> str: - reactant_str = [] - product_str = [] - for amt, formula in zip(coeffs, formulas): - if abs(amt + 1) < cls.TOLERANCE: - reactant_str.append(formula) - elif abs(amt - 1) < cls.TOLERANCE: - product_str.append(formula) - elif amt < -cls.TOLERANCE: - reactant_str.append("{:.4g} {}".format(-amt, formula)) - elif amt > cls.TOLERANCE: - product_str.append("{:.4g} {}".format(amt, formula)) - - return " + ".join(reactant_str) + " -> " + " + ".join(product_str) - - @classmethod - def _str_from_comp(cls, coeffs, compositions, reduce=False): - r_coeffs = np.zeros(len(coeffs)) - r_formulas = [] - for i, (amt, comp) in enumerate(zip(coeffs, compositions)): - formula, factor = comp.get_reduced_formula_and_factor() - r_coeffs[i] = amt * factor - r_formulas.append(formula) - if reduce: - factor = 1 / gcd_float(np.abs(r_coeffs)) - r_coeffs *= factor - else: - factor = 1 - return cls._str_from_formulas(r_coeffs, r_formulas), factor - - def __eq__(self, other): - if self is other: - return True - elif str(self) == str(other): - return True - else: - return (set(self.reactants) == set(other.reactants)) & ( - set(self.products) == set(other.products) - ) - - def __hash__(self): - return hash( - "-".join( - [e.reduced_formula for e in sorted(self.reactants)] - + [e.reduced_formula for e in sorted(self.products)] - ) + def copy(self) -> "BasicReaction": + """Returns a copy of the BasicReaction object""" + return BasicReaction( + compositions=self.compositions, + coefficients=self.coefficients, + balanced=self.balanced, + data=self.data, + lowest_num_errors=self.lowest_num_errors, ) - def __str__(self): - return self._str_from_comp(self.coefficients, self.compositions)[0] - - __repr__ = __str__ - - @staticmethod - def _from_coeff_dicts(reactant_coeffs, product_coeffs): - reactant_comps, r_coefs = zip( - *[(comp, -1 * coeff) for comp, coeff in reactant_coeffs.items()] - ) - product_comps, p_coefs = zip( - *[(comp, coeff) for comp, coeff in product_coeffs.items()] + def reverse(self) -> "BasicReaction": + """ + Returns a copy of the original BasicReaction object where original reactants are + new products, and vice versa. + """ + return BasicReaction( + compositions=self.compositions, + coefficients=-1 * self.coefficients, + balanced=self.balanced, + data=self.data, + lowest_num_errors=self.lowest_num_errors, ) - return BasicReaction(reactant_comps + product_comps, r_coefs + p_coefs) - @staticmethod - def from_string(rxn_string) -> "BasicReaction": + @classmethod + def from_string(cls, rxn_string) -> "BasicReaction": """ Generates a balanced reaction from a string. The reaction must already be balanced. @@ -334,12 +236,89 @@ def get_comp_amt(comp_str): reactant_coeffs = get_comp_amt(rct_str) product_coeffs = get_comp_amt(prod_str) - return BasicReaction._from_coeff_dicts(reactant_coeffs, product_coeffs) + return cls._from_coeff_dicts(reactant_coeffs, product_coeffs) + + @classmethod + def from_formulas( + cls, reactants: List[str], products: List[str] + ) -> "BasicReaction": + """ + + Args: + reactants: + products: + + Returns: + + """ + + reactant_comps = [Composition(r) for r in reactants] + product_comps = [Composition(p) for p in products] + rxn = cls.balance(reactants=reactant_comps, products=product_comps) + + return rxn + + @property + def reactants(self) -> List[Composition]: + """List of reactants for this reaction""" + return list(self.reactant_coeffs.keys()) + + @property + def products(self) -> List[Composition]: + """List of products for this reaction""" + return list(self.product_coeffs.keys()) + + @property + def compositions(self) -> List[Composition]: + """List of composition objects for this reaction""" + return self._compositions + + @property + def coefficients(self) -> np.ndarray: # pylint: disable = W0236 + """Array of reaction coefficients""" + return self._coefficients + + @property + def energy(self) -> float: + """The energy of this reaction""" + raise ValueError("No energy for a basic reaction!") + + @property + def energy_per_atom(self) -> float: + """The energy per atom of this reaction""" + raise ValueError("No energy per atom for a basic reaction!") + + @property + def is_identity(self): + """Returns True if the reaction has identical reactants and products""" + if set(self.reactants) != set(self.products): + return False + if self.balanced is False: # if not balanced, can not check coefficients + return True + return all( + [ + np.isclose(self.reactant_coeffs[c] * -1, self.product_coeffs[c]) + for c in self.reactant_coeffs + ] + ) + + @property + def chemical_system(self): + """Returns the chemical system as string in the form of A-B-C-...""" + return "-".join(sorted([str(el) for el in self.elements])) + + @property + def normalized_repr(self): + """ + A normalized representation of the reaction. All factors are converted + to lowest common factors. + """ + return self.normalized_repr_and_factor()[0] @classmethod def _balance_coeffs( - cls, reactants: List[Composition], products: List[Composition], robust=True - ) -> np.array: + cls, reactants: List[Composition], products: List[Composition] + ) -> Tuple[np.ndarray, Union[int, float]]: """ Balances the reaction and returns the new coefficient matrix """ @@ -360,7 +339,7 @@ def _balance_coeffs( first_product_idx = len(reactants) - # start with simplest product constraints, work towards most complex reactant constraints + # start with simplest product constraints, work to more complex constraints product_constraints = chain.from_iterable( [ combinations(range(first_product_idx, num_comp), n_constr) @@ -373,7 +352,7 @@ def _balance_coeffs( for n_constr in range(num_constraints, 0, -1) ] ) - best_soln = None + best_soln = np.zeros(num_comp) for constraints in chain(product_constraints, reactant_constraints): n_constr = len(constraints) @@ -405,23 +384,68 @@ def _balance_coeffs( return np.squeeze(best_soln), lowest_num_errors + @staticmethod + def _from_coeff_dicts(reactant_coeffs, product_coeffs) -> "BasicReaction": + reactant_comps, r_coefs = zip( + *[(comp, -1 * coeff) for comp, coeff in reactant_coeffs.items()] + ) + product_comps, p_coefs = zip( + *[(comp, coeff) for comp, coeff in product_coeffs.items()] + ) + return BasicReaction(reactant_comps + product_comps, r_coefs + p_coefs) + @classmethod - def balance( - cls, - reactants: List[Composition], - products: List[Composition], - data: Optional[Dict] = None, - ) -> "BasicReaction": - """ - Reactants and products to be specified as list of - pymatgen.core.Composition. e.g., [comp1, comp2] + def _str_from_formulas(cls, coeffs, formulas) -> str: + reactant_str = [] + product_str = [] + tol = cls.TOLERANCE + for amt, formula in zip(coeffs, formulas): + if abs(amt + 1) < tol: + reactant_str.append(formula) + elif abs(amt - 1) < tol: + product_str.append(formula) + elif amt < -tol: + reactant_str.append("{:.4g} {}".format(-amt, formula)) + elif amt > tol: + product_str.append("{:.4g} {}".format(amt, formula)) - Args: - reactants: List of reactants. - products: List of products. - data: Optional dictionary containing extra data about the reaction. - """ - compositions = reactants + products - coeffs, lowest_num_errors = cls._balance_coeffs(reactants, products) + return " + ".join(reactant_str) + " -> " + " + ".join(product_str) + + @classmethod + def _str_from_comp(cls, coeffs, compositions, reduce=False): + r_coeffs = np.zeros(len(coeffs)) + r_formulas = [] + for i, (amt, comp) in enumerate(zip(coeffs, compositions)): + formula, factor = comp.get_reduced_formula_and_factor() + r_coeffs[i] = amt * factor + r_formulas.append(formula) + if reduce: + factor = 1 / gcd_float(np.abs(r_coeffs)) + r_coeffs *= factor + else: + factor = 1 + return cls._str_from_formulas(r_coeffs, r_formulas), factor + + def __eq__(self, other): + if self is other: + return True + elif str(self) == str(other): + return True + else: + return (set(self.reactants) == set(other.reactants)) & ( + set(self.products) == set(other.products) + ) + + def __hash__(self): + return hash( + "-".join( + [e.reduced_formula for e in sorted(self.reactants)] + + [e.reduced_formula for e in sorted(self.products)] + ) + ) + + def __str__(self): + return self._str_from_comp(self.coefficients, self.compositions)[0] - return cls(compositions, coeffs, data=data, lowest_num_errors=lowest_num_errors) + def __repr__(self): + return self.__str__() diff --git a/src/rxn_network/reactions/computed.py b/src/rxn_network/reactions/computed.py index 1b9a7fb2..ad7fa13e 100644 --- a/src/rxn_network/reactions/computed.py +++ b/src/rxn_network/reactions/computed.py @@ -1,10 +1,12 @@ -" A ComputedReaction class to generate from ComputedEntry objects " -from typing import Dict, List, Optional +""" +A reaction class that builds reactions based on ComputedEntry objects and provides +information about reaction thermodynamics. +""" +from typing import Dict, List, Optional, Union import numpy as np -from pymatgen.analysis.phase_diagram import GrandPotPDEntry, PDEntry -from pymatgen.core.composition import Element -from pymatgen.entries import Entry +from pymatgen.core.composition import Composition +from pymatgen.entries.computed_entries import ComputedEntry from uncertainties import ufloat from rxn_network.reactions.basic import BasicReaction @@ -14,20 +16,22 @@ class ComputedReaction(BasicReaction): """ Convenience class to generate a reaction from ComputedEntry objects, with some additional attributes, such as a reaction energy based on computed - energies. Will balance the reaction. + energies. This class also balances the reaction. """ def __init__( self, - entries: List[Entry], - coefficients: List[float], + entries: List[ComputedEntry], + coefficients: Union[np.ndarray, List[float]], data: Optional[Dict] = None, - lowest_num_errors: Optional[int] = None, + lowest_num_errors: Union[int, float] = 0, ): """ Args: - entries([ComputedEntry]): List of ComputedEntry objects. - coefficients([float]): List of reaction coefficients. + entries: List of ComputedEntry objects. + coefficients: List of reaction coefficients. + data: Optional dict of data + lowest_num_errors: number of "errors" encountered during reaction balancing """ self._entries = list(entries) self.reactant_entries = [ @@ -42,14 +46,36 @@ def __init__( compositions, coefficients, data=data, lowest_num_errors=lowest_num_errors ) - @property - def entries(self): + @classmethod + def balance( + cls, + reactant_entries: List[ComputedEntry], + product_entries: List[ComputedEntry], + data: Optional[Dict] = None, + ): # pylint: disable = W0221 """ - Equivalent of all_comp but returns entries, in the same order as the - coefficients. + Balances and returns a new ComputedReaction. + + Reactants and products to be specified as list of + pymatgen.core.structure.Composition. e.g., [comp1, comp2] + Args: + reactant_entries: List of reactant entries + product_entries: List of product entries + data: Optional dict of data """ - return self._entries + reactant_comps = [e.composition.reduced_composition for e in reactant_entries] + product_comps = [e.composition.reduced_composition for e in product_entries] + coefficients, lowest_num_errors = cls._balance_coeffs( + reactant_comps, product_comps + ) + + return cls( + entries=list(reactant_entries) + list(product_entries), + coefficients=coefficients, + data=data, + lowest_num_errors=lowest_num_errors, + ) @property def energy(self) -> float: @@ -57,7 +83,7 @@ def energy(self) -> float: Returns (float): The calculated reaction energy. """ - calc_energies = {} + calc_energies: Dict[Composition, float] = {} for entry in self._entries: (comp, factor) = entry.composition.get_reduced_composition_and_factor() @@ -85,7 +111,7 @@ def energy_per_atom(self) -> float: def energy_uncertainty(self): """ Calculates the uncertainty in the reaction energy based on the uncertainty in the - energies of the products and reactants + energies of the reactants/products """ calc_energies = {} @@ -97,58 +123,49 @@ def energy_uncertainty(self): calc_energies.get(comp, float("inf")), energy_ufloat / factor ) - return sum( + energy_with_uncertainty = sum( [ amt * calc_energies[c] for amt, c in zip(self.coefficients, self.compositions) ] ) + return energy_with_uncertainty.s + + @property + def energy_uncertainty_per_atom(self): + return self.energy_uncertainty / self.num_atoms + + @property + def entries(self): + """ + Returns a copy of the entries + """ + return self._entries + def copy(self) -> "ComputedReaction": """ - Returns a copy of the Reaction object. + Returns a copy of the Reaction object """ return ComputedReaction( self.entries, self.coefficients, self.data, self.lowest_num_errors ) def reverse(self): - return ComputedReaction( - self.entries, -1 * self.coefficients, self.data, self.lowest_num_errors - ) - - @property - def energy_uncertainty_per_atom(self): - return self.energy_uncertainty / self.num_atoms - - @classmethod - def balance( - cls, - reactant_entries: List[Entry], - product_entries: List[Entry], - data: Optional[Dict] = None, - ): # pylint: disable = W0221 """ - Balances and returns a new ComputedReaction. + Returns a reversed reaction (i.e. sides flipped) - Reactants and products to be specified as list of - pymatgen.core.structure.Composition. e.g., [comp1, comp2] - - Args: - reactants ([Composition]): List of reactants. - products ([Composition]): List of products. """ - reactant_comps = [e.composition.reduced_composition for e in reactant_entries] - product_comps = [e.composition.reduced_composition for e in product_entries] - coefficients, lowest_num_errors = cls._balance_coeffs( - reactant_comps, product_comps + return ComputedReaction( + self.entries, -1 * self.coefficients, self.data, self.lowest_num_errors ) - if not coefficients.any(): - coefficients = [] - return cls( - entries=list(reactant_entries) + list(product_entries), - coefficients=coefficients, - data=data, - lowest_num_errors=lowest_num_errors, - ) + def __hash__(self): + return BasicReaction.__hash__(self) + + def __eq__(self, other): + eq = BasicReaction.__eq__(self, other) + if not eq: + return False + else: + return np.isclose(self.energy_per_atom, other.energy_per_atom) diff --git a/src/rxn_network/reactions/open.py b/src/rxn_network/reactions/open.py index afd8d10d..45addf92 100644 --- a/src/rxn_network/reactions/open.py +++ b/src/rxn_network/reactions/open.py @@ -1,9 +1,16 @@ -from typing import Dict, List, Optional +""" +A reaction class that builds reactions based on ComputedEntry objects under the +presence of an open entry (e.g. O2), and provides information about reaction +thermodynamics computed as changes in grand potential. +""" + +from typing import Dict, List, Optional, Union import numpy as np + from pymatgen.analysis.phase_diagram import GrandPotPDEntry -from pymatgen.core.composition import Element -from pymatgen.entries import Entry +from pymatgen.core.composition import Element, Composition +from pymatgen.entries.computed_entries import ComputedEntry from rxn_network.reactions.computed import ComputedReaction @@ -16,42 +23,82 @@ class OpenComputedReaction(ComputedReaction): def __init__( self, - entries: List[Entry], - coefficients: np.array, + entries: List[ComputedEntry], + coefficients: Union[np.ndarray, List[float]], chempots: Dict[Element, float], data: Optional[Dict] = None, lowest_num_errors=None, ): """ + Args: - reactant_entries ([ComputedEntry]): List of reactant_entries. - product_entries ([ComputedEntry]): List of product_entries. + entries: List of ComputedEntry objects. + coefficients: List of reaction coefficients. + chempots: Dict of chemical potentials corresponding to open elements + data: Optional dict of data + lowest_num_errors: number of "errors" encountered during reaction balancing """ - super().__init__(entries, coefficients, data, lowest_num_errors) + super().__init__( + entries=entries, + coefficients=coefficients, + data=data, + lowest_num_errors=lowest_num_errors, + ) self.chempots = chempots self.open_elems = list(chempots.keys()) - self.grand_compositions = [] - self.grand_coefficients = [] - - self.reactant_grand_entries = [] - for e, coeff in zip(self.reactant_entries, self.reactant_coeffs.values()): + grand_entries = [] + for e in entries: comp = e.composition.reduced_composition if len(comp.elements) == 1 and comp.elements[0] in self.open_elems: - continue - self.reactant_grand_entries.append(GrandPotPDEntry(e, chempots)) - self.grand_coefficients.append(coeff) - self.grand_compositions.append(comp) + grand_entries.append(e) + else: + grand_entries.append(GrandPotPDEntry(e, chempots)) - self.product_grand_entries = [] - for e, coeff in zip(self.product_entries, self.product_coeffs.values()): - comp = e.composition.reduced_composition - if len(comp.elements) == 1 and comp.elements[0] in self.open_elems: - continue - self.product_grand_entries.append(GrandPotPDEntry(e, chempots)) - self.grand_coefficients.append(coeff) - self.grand_compositions.append(comp) + self.grand_entries = grand_entries + + @classmethod + def balance( # type: ignore + cls, + reactant_entries: List[ComputedEntry], + product_entries: List[ComputedEntry], + chempots: Dict[Element, float] = None, + data: Optional[Dict] = None, + ): # pylint: disable = W0221 + """ + + Args: + reactant_entries: + product_entries: + chempots: + data: + + Returns: + + """ + + reactant_comps = [e.composition.reduced_composition for e in reactant_entries] + product_comps = [e.composition.reduced_composition for e in product_entries] + coefficients, lowest_num_errors = cls._balance_coeffs( + reactant_comps, product_comps + ) + + entries = list(reactant_entries) + list(product_entries) + + args = { + "entries": entries, + "coefficients": coefficients, + "data": data, + "lowest_num_errors": lowest_num_errors, + } + + if not chempots: + rxn = ComputedReaction(**args) # type: ignore + else: + rxn = cls(chempots=chempots, **args) # type: ignore + + return rxn @property def energy(self) -> float: @@ -59,10 +106,14 @@ def energy(self) -> float: Returns (float): The calculated reaction energy. """ - calc_energies = {} + calc_energies: Dict[Composition, float] = {} + + for entry in self.grand_entries: + attr = "composition" + if type(entry) == GrandPotPDEntry: + attr = "original_comp" - for entry in self.reactant_grand_entries + self.product_grand_entries: - (comp, factor) = entry.original_comp.get_reduced_composition_and_factor() + comp, factor = getattr(entry, attr).get_reduced_composition_and_factor() calc_energies[comp] = min( calc_energies.get(comp, float("inf")), entry.energy / factor ) @@ -70,7 +121,7 @@ def energy(self) -> float: return sum( [ amt * calc_energies[c] - for amt, c in zip(self.grand_coefficients, self.grand_compositions) + for amt, c in zip(self.coefficients, self.compositions) ] ) @@ -84,6 +135,15 @@ def elements(self) -> List[Element]: - set(self.open_elems) ) + @property + def total_chemical_system(self) -> str: + """ + Chemical system string, including open elements + """ + return "-".join( + sorted([str(e) for e in set(self.elements) | set(self.open_elems)]) + ) + def copy(self) -> "OpenComputedReaction": """ Returns a copy of the OpenComputedReaction object. @@ -97,6 +157,11 @@ def copy(self) -> "OpenComputedReaction": ) def reverse(self): + """ + + Returns a copy of reaction with reactants/products swapped + + """ return OpenComputedReaction( self.entries, -1 * self.coefficients, @@ -105,47 +170,6 @@ def reverse(self): self.lowest_num_errors, ) - @classmethod - def balance( - cls, - reactant_entries: List[Entry], - product_entries: List[Entry], - chempots, - data=None, - ): # pylint: disable = W0221 - """ - Balances and returns a new OpenComputedReaction - - Reactants and products to be specified as list of - pymatgen.core.structure.Composition. e.g., [comp1, comp2] - - Args: - reactants ([Composition]): List of reactants. - products ([Composition]): List of products. - """ - reactant_comps = [e.composition.reduced_composition for e in reactant_entries] - product_comps = [e.composition.reduced_composition for e in product_entries] - coefficients, lowest_num_errors = cls._balance_coeffs( - reactant_comps, product_comps - ) - - if not coefficients.any(): - coefficients = [] - - return cls( - entries=list(reactant_entries) + list(product_entries), - coefficients=list(coefficients), - chempots=chempots, - data=data, - lowest_num_errors=lowest_num_errors, - ) - - @property - def total_chemical_system(self): - return "-".join( - sorted([str(e) for e in set(self.elements) | set(self.open_elems)]) - ) - def __repr__(self): cp = f"({','.join([f'mu_{e}={m}' for e, m in self.chempots.items()])})" return f"{super().__repr__()} {cp}" diff --git a/src/rxn_network/reactions/reaction_set.py b/src/rxn_network/reactions/reaction_set.py index 6fa8dcad..ebab5925 100644 --- a/src/rxn_network/reactions/reaction_set.py +++ b/src/rxn_network/reactions/reaction_set.py @@ -1,10 +1,17 @@ +""" +Implements a class for conveniently and efficiently storing sets of ComputedReaction +objects which share entries. +""" + from functools import lru_cache -from typing import Dict, List, Optional +from typing import List, Optional, Union, Set, Iterable import numpy as np from monty.json import MSONable from pymatgen.core import Element +from pymatgen.entries.computed_entries import ComputedEntry +from rxn_network.core.cost_function import CostFunction from rxn_network.reactions.computed import ComputedReaction from rxn_network.reactions.open import OpenComputedReaction @@ -12,84 +19,100 @@ class ReactionSet(MSONable): """ A lightweight class for storing large sets of ComputedReaction objects. + Automatically represents a set of reactions as an array of coefficients with + a second array linking to a corresponding list of shared entries. """ - def __init__(self, entries, all_indices, all_coeffs, all_data=None): + def __init__( + self, + entries: List[ComputedEntry], + indices: Union[np.ndarray, List[List[int]]], + coeffs: Union[np.ndarray, List[List[float]]], + all_data: Optional[List] = None, + ): """ - Args: - entries: - all_indices: - all_coeffs: - all_data: + entries: List of ComputedEntry objects shared by reactions + indices: Array indexing the entry list; gets entries used by each + reaction object + coeffs: Array of all reaction coefficients + all_data: Optional list of data for each reaction """ self.entries = entries - self.all_indices = all_indices - self.all_coeffs = all_coeffs - if not all_data: - all_data = [] - self.all_data = all_data + self.indices = indices + self.coeffs = coeffs + self.all_data = all_data if all_data else [] @lru_cache(1) - def get_rxns(self, open_elem=None, chempot=0): + def get_rxns( + self, + open_elem: Optional[str] = None, + chempot: float = 0.0, + ) -> List[Union[ComputedReaction, OpenComputedReaction]]: """ + Returns list of ComputedReaction objects or OpenComputedReaction objects (when + open element and chempot are specified) for the reaction set. Args: - open_elem: - chempot: - - Returns: - + open_elem: Open element, e.g. "O2" + chempot: Chemical potential (mu) of open element in equation: Phi = G - mu*N """ rxns = [] + chempots = None + if open_elem: chempots = {Element(open_elem): chempot} - for indices, coeffs, data in zip( - self.all_indices, self.all_coeffs, self.all_data - ): + + for indices, coeffs, data in zip(self.indices, self.coeffs, self.all_data): entries = [self.entries[i] for i in indices] if chempots: - rxns.append( - OpenComputedReaction( - entries=entries, - coefficients=coeffs, - data=data, - chempots=chempots, - ) + rxn = OpenComputedReaction( + entries=entries, coefficients=coeffs, data=data, chempots=chempots ) else: - rxns.append( - ComputedReaction(entries=entries, coefficients=coeffs, data=data) - ) + rxn = ComputedReaction(entries=entries, coefficients=coeffs, data=data) + rxns.append(rxn) return rxns - def calculate_costs(self, cf, open_elem=None, chempot=0): + def calculate_costs( + self, + cf: CostFunction, + open_elem: Optional[Union[str, Element]] = None, + chempot: Optional[float] = 0, + ) -> List[float]: """ + Evaluate a cost function on an acquired set of reactions. Args: - cf: - - Returns: - + cf: CostFunction object, e.g. Softplus() + open_elem: Open element, e.g. "O2" + chempot: Chemical potential (mu) of open element in equation: Phi = G - mu*N """ - return [cf.evaluate(rxn) for rxn in self.get_rxns(open_elem, chempot)] + return [ + cf.evaluate(rxn) + for rxn in self.get_rxns(open_elem=open_elem, chempot=chempot) + ] @classmethod - def from_rxns(cls, rxns, entries=None): + def from_rxns( + cls, + rxns: List[Union[ComputedReaction, OpenComputedReaction]], + entries: Optional[Iterable[ComputedEntry]] = None, + ) -> "ReactionSet": """ + Initiate a ReactionSet object from a list of reactions. Including a list of + unique entries saves some computation time. Args: - rxns: - entries: - - Returns: - + rxns: List of ComputedReaction-like objects. + entries: Optional list of ComputedEntry objects """ if not entries: entries = cls._get_unique_entries(rxns) entries = sorted(list(set(entries)), key=lambda r: r.composition) + all_indices, all_coeffs, all_data = [], [], [] for rxn in rxns: all_indices.append([entries.index(e) for e in rxn.entries]) @@ -98,14 +121,14 @@ def from_rxns(cls, rxns, entries=None): return cls( entries=entries, - all_indices=all_indices, - all_coeffs=all_coeffs, + indices=all_indices, + coeffs=all_coeffs, all_data=all_data, ) @staticmethod - def _get_unique_entries(rxns): - "Return only unique entries from reactions" + def _get_unique_entries(rxns: List[ComputedReaction]) -> Set[ComputedEntry]: + """Return only unique entries from reactions""" entries = set() for r in rxns: entries.update(r.entries) diff --git a/src/rxn_network/reactions/utils.py b/src/rxn_network/reactions/utils.py index 61befc5f..a2444882 100644 --- a/src/rxn_network/reactions/utils.py +++ b/src/rxn_network/reactions/utils.py @@ -1,5 +1,9 @@ +""" +Utility functions used in the reaction classes. +""" + import numpy as np -from pymatgen import Element +from pymatgen.core.composition import Element def is_separable_rxn(rxn, target_comp, added_elems): diff --git a/src/rxn_network/thermo/__init__.py b/src/rxn_network/thermo/__init__.py index a59c2ce5..61f8e5b5 100644 --- a/src/rxn_network/thermo/__init__.py +++ b/src/rxn_network/thermo/__init__.py @@ -1 +1 @@ -from rxn_network.thermo.chempot_diagram import ChempotDiagram +from rxn_network.thermo.chempot_diagram import ChemicalPotentialDiagram diff --git a/src/rxn_network/thermo/chempot_diagram.py b/src/rxn_network/thermo/chempot_diagram.py index 25ab8f3a..26d7c7a4 100644 --- a/src/rxn_network/thermo/chempot_diagram.py +++ b/src/rxn_network/thermo/chempot_diagram.py @@ -1,303 +1,43 @@ -" A chemical potential diagram class" +""" +This module implements added features to the ChemicalPotentialDiagram class from +pymatgen. +""" -from functools import cached_property from typing import Dict, List, Optional import numpy as np -import plotly.express as px -import plotly.graph_objects as go -from monty.json import MSONable -from pymatgen.analysis.phase_diagram import PDPlotter, PhaseDiagram +from pymatgen.analysis.chempot_diagram import ChemicalPotentialDiagram as ChempotDiagram +from pymatgen.analysis.phase_diagram import PDEntry from pymatgen.core.composition import Composition, Element -from pymatgen.entries.computed_entries import ComputedEntry -from pymatgen.util.coord import Simplex -from scipy.spatial import ConvexHull, HalfspaceIntersection, KDTree -from scipy.spatial.qhull import QhullError +from scipy.spatial import KDTree -from rxn_network.thermo.chempot_layouts import ( - default_chempot_annotation_layout, - default_chempot_layout_3d, -) -from rxn_network.thermo.utils import get_centroid_2d, simple_pca - - -class ChempotDiagram(MSONable): - """ - The chemical potential diagram is the mathematical dual (intensive analog) to the - traditional compositional phase diagram. To create the diagram, convex - minimization is performed in E vs. μ space by taking the lower convex envelope of - hyperplanes. Accordingly, "points" on the standard phase diagram become - "domains" in chemical potential space. - """ +class ChemicalPotentialDiagram(ChempotDiagram): def __init__( self, - pd: PhaseDiagram, + entries: List[PDEntry], limits: Optional[Dict[Element, float]] = None, - default_limit: Optional[float] = -15.0, + default_min_limit: Optional[float] = -20.0, ): """ Args: - pd: Phase diagram object (pymatgen). - limits: Chemical potential value chosen for bordering elemental - hyperplanes; constrains the space over which the domains are calculated - default_limit (float): Default minimum limit for unspecified elements. - """ - self.pd = pd - self.limits = limits - self.default_limit = default_limit - - self.dim = pd.dim - - @cached_property - def domains(self) -> Dict[str, np.array]: - """ - Mapping of formulas to array of domain boundary points + entries: List of PDEntry-like objects containing a composition and + energy. Must contain elemental references and be suitable for typical + phase diagram construction. Entries must be within a chemical system + of with 2+ elements + limits: Bounds of elemental chemical potentials (min, max), which are + used to construct the border hyperplanes used in the + HalfSpaceIntersection algorithm; these constrain the space over which the + domains are calculated and also determine the size of the plotted + diagram. Any elemental limits not specified are covered in the + default_min_limit argument + default_min_limit (float): Default minimum chemical potential limit for + unspecified elements within the "limits" argument. This results in + default limits of (default_min_limit, 0) """ - lims = np.array([[self.default_limit, 0]] * self.dim) - for idx, elem in enumerate(self.pd.elements): - if self.limits and elem in self.limits: - lims[idx, :] = self.limits[elem] - - data = self.pd.qhull_data - hyperplanes = np.insert( - data, [0], (1 - np.sum(data[:, :-1], axis=1)).reshape(-1, 1), axis=1 + super().__init__( + entries=entries, limits=limits, default_min_limit=default_min_limit ) - hyperplanes[:, -1] = hyperplanes[:, -1] * -1 # flip to all positive energies - entries = self.pd.qhull_entries - - border_hyperplanes = np.array(([[0] * (self.dim + 1)] * (2 * self.dim))) - - for idx, limit in enumerate(lims): - border_hyperplanes[2 * idx, idx] = -1 - border_hyperplanes[2 * idx, -1] = limit[0] - border_hyperplanes[(2 * idx) + 1, idx] = 1 - border_hyperplanes[(2 * idx) + 1, -1] = limit[1] - - hs_hyperplanes = np.vstack([hyperplanes, border_hyperplanes]) - - interior_point = np.average(lims, axis=1).tolist() - hs_int = HalfspaceIntersection(hs_hyperplanes, np.array(interior_point)) - - domains = {entry.composition.reduced_formula: [] for entry in self.entries} - - for intersection, facet in zip(hs_int.intersections, hs_int.dual_facets): - for v in facet: - if v < len(entries): - this_entry = entries[v] - formula = this_entry.composition.reduced_formula - domains[formula].append(intersection) - - return {k: np.array(v) for k, v in domains.items() if v} - - def get_plot( # noqa: C901 - self, - elements: list = None, - formulas: list = [], - formula_mode="mesh", - formula_colors=None, - label_stable=True, - shade_energy=True, - ) -> go.Scatter3d: - """ - - Args: - elements: - formulas: - formula_mode: - formula_colors: - label_stable: - shade_energy: - - Returns: - - """ - - if not formula_colors: - formula_colors = px.colors.qualitative.Dark2 - - if not elements: - elements = self.pd.elements[:3] - else: - elements = [Element(e) for e in elements] - - elem_indices = [self.pd.elements.index(e) for e in elements] - - domain_vertices = {} - annotations = [] - font_dict = {"color": "black", "size": 16.0} - opacity = 0.7 - - extra_domains = {} - domains = self.domains.copy() - comps_reduced = [ - Composition(formula).reduced_composition for formula in formulas - ] - - for formula, points in domains.items(): - entry = self.entry_dict[formula] - points_3d = np.array(points[:, elem_indices]) - contains_target_elems = set(entry.composition.elements).issubset(elements) - - if formulas: - if entry.composition.reduced_composition in comps_reduced: - domains[formula] = None - extra_domains[formula] = points_3d - - if contains_target_elems: - domains[formula] = points_3d - else: - continue - - if not contains_target_elems: - domains[formula] = None - continue - - # Try to get all convex polyhedra (3d), default to polygons (2d) - try: - domain = ConvexHull(points_3d) - ann_loc = np.mean(points_3d.T, axis=1) - except QhullError: - points_2d, v, w = simple_pca(points_3d, k=2) - domain = ConvexHull(points_2d) - centroid_2d = get_centroid_2d(points_2d[domain.vertices]) - ann_loc = centroid_2d @ w.T + np.mean( - points_3d.T, axis=1 - ) # recover orig 3D coords from eigenvectors - - simplices = [Simplex(points_3d[indices]) for indices in domain.simplices] - - formula_disp = formula - if hasattr(entry, "original_entry"): - formula_disp = entry.original_entry.composition.reduced_formula - - clean_formula = PDPlotter._htmlize_formula(formula_disp) - annotation = default_chempot_annotation_layout.copy() - - annotation.update( - { - "x": ann_loc[0], - "y": ann_loc[1], - "z": ann_loc[2], - "font": font_dict, - "text": clean_formula, - "opacity": opacity, - } - ) - annotations.append(annotation) - domains[formula] = simplices - domain_vertices[formula] = points_3d - - x, y, z = [], [], [] - meshes = [] - cmax = 0.0001 - cmin = ( - min([self.pd.get_form_energy_per_atom(e) for e in self.pd.stable_entries]) - - 0.0001 - ) - - for phase, simplexes in domains.items(): - if simplexes: - for s in simplexes: - x.extend(s.coords[:, 0].tolist() + [None]) - y.extend(s.coords[:, 1].tolist() + [None]) - z.extend(s.coords[:, 2].tolist() + [None]) - - layout = default_chempot_layout_3d.copy() - layout["scene"].update( - { - "xaxis": self._get_chempot_axis_layout(elements[0]), - "yaxis": self._get_chempot_axis_layout(elements[1]), - "zaxis": self._get_chempot_axis_layout(elements[2]), - } - ) - layout["scene"]["annotations"] = None - if label_stable: - layout["scene"].update({"annotations": annotations}) - - lines = [ - go.Scatter3d( - x=x, - y=y, - z=z, - mode="lines", - line=dict(color="black", width=4.5), - showlegend=False, - ) - ] - - extra_phases = [] - - for idx, formula in enumerate(formulas): - try: - coords = extra_domains[formula] - except KeyError: - continue - - points_3d = coords[:, :3] - entry = self.entry_dict[formula] - if "mesh" in formula_mode: - extra_phases.append( - go.Mesh3d( - x=points_3d[:, 0], - y=points_3d[:, 1], - z=points_3d[:, 2], - alphahull=0, - showlegend=True, - lighting=dict(fresnel=1.0), - color=formula_colors[idx], - name=f"{entry.composition.reduced_formula} (mesh)", - opacity=0.13, - ) - ) - if "lines" in formula_mode: - points_2d = points_3d[:, 0:2] - domain = ConvexHull(points_2d) - simplexes = [ - Simplex(points_3d[indices]) for indices in domain.simplices - ] - x, y, z = [], [], [] - for s in simplexes: - x.extend(s.coords[:, 0].tolist() + [None]) - y.extend(s.coords[:, 1].tolist() + [None]) - z.extend(s.coords[:, 2].tolist() + [None]) - - extra_phases.append( - go.Scatter3d( - x=x, - y=y, - z=z, - mode="lines", - line={"width": 8, "color": formula_colors[idx]}, - opacity=1.0, - name=f"{formula} (lines)", - ) - ) - - layout["scene_camera"] = dict( - eye=dict(x=0, y=0, z=2.0), projection=dict(type="orthographic") - ) - fig = go.Figure(meshes + lines + extra_phases, layout) - fig.update_layout( - coloraxis={ - "colorscale": "blugrn", - "cmin": cmin, - "cmax": cmax, - "showscale": True, - } - ) - - return fig - - @property - def entries(self) -> List[ComputedEntry]: - "Returns mu diagram entries (i.e., stable entries of phase diagram)" - return self.pd.stable_entries - - @cached_property - def entry_dict(self) -> Dict[str, ComputedEntry]: - """Mapping between reduced formula and ComputedEntry""" - return {e.composition.reduced_formula: e for e in self.entries} def shortest_domain_distance(self, f1: str, f2: str) -> float: """ @@ -322,8 +62,8 @@ def shortest_elemental_domain_distances(self, f1, f2) -> float: """ pts1 = self.domains[f1] pts2 = self.domains[f2] - pts1 = pts1[~np.isclose(pts1, self.default_limit).any(axis=1)] - pts2 = pts2[~np.isclose(pts2, self.default_limit).any(axis=1)] + pts1 = pts1[~np.isclose(pts1, self.default_min_limit).any(axis=1)] + pts2 = pts2[~np.isclose(pts2, self.default_min_limit).any(axis=1)] num_elems = pts1.shape[1] mesh = np.meshgrid(pts1, pts2) @@ -331,26 +71,3 @@ def shortest_elemental_domain_distances(self, f1, f2) -> float: diff = diff.reshape(-1, num_elems) return diff.min(axis=0) - - @property - def chemical_system(self) -> str: - "Returns the chemical system (A-B-C-...) of diagram object" - return "-".join(sorted([e.symbol for e in self.pd.elements])) - - @staticmethod - def _get_chempot_axis_layout(element): - return dict( - title=f"μ{str(element)} - μ" - f"{str(element)}o (eV)", - titlefont={"size": 30}, - gridcolor="#dbdbdb", - gridwidth=5.0, - tickfont={"size": 16}, - ticks="inside", - ticklen=14, - showline=True, - backgroundcolor="rgba(0,0,0,0)", - ) - - def __repr__(self): - return f"ChempotMap for {self.chemical_system} with {len(self.entries)} entries" diff --git a/src/rxn_network/thermo/chempot_layouts.py b/src/rxn_network/thermo/chempot_layouts.py deleted file mode 100644 index 23bae6bb..00000000 --- a/src/rxn_network/thermo/chempot_layouts.py +++ /dev/null @@ -1,26 +0,0 @@ -default_chempot_layout_3d = dict( - width=800, - height=800, - hovermode="closest", - paper_bgcolor="rgba(0,0,0,0)", - plot_bgcolor="rgba(0,0,0,0)", - showlegend=True, - legend=dict( - orientation="v", - x=0.1, - y=0.99, - traceorder="reversed", - xanchor="left", - yanchor="top", - ), - scene_camera=dict(projection=dict(type="orthographic")), - scene=dict(), -) - -default_chempot_annotation_layout = { - "align": "center", - "opacity": 0.7, - "showarrow": False, - "xanchor": "center", - "yanchor": "auto", -} diff --git a/src/rxn_network/thermo/utils.py b/src/rxn_network/thermo/utils.py index bd7d00fb..8653d419 100644 --- a/src/rxn_network/thermo/utils.py +++ b/src/rxn_network/thermo/utils.py @@ -1,6 +1,9 @@ -from typing import Dict, List, Tuple +""" +Utility functions used in the thermodynamic analysis classes. +""" + +from typing import Dict, List -import numpy as np from pymatgen.analysis.phase_diagram import PhaseDiagram from pymatgen.entries import Entry @@ -19,7 +22,7 @@ def expand_pd(entries: List[Entry]) -> Dict[str, PhaseDiagram]: e.g. {"Li-Mn-O": , "C-Y": , ...} """ - pd_dict = dict() + pd_dict: Dict[str, PhaseDiagram] = dict() sorted_entries = sorted( entries, key=lambda x: len(x.composition.elements), reverse=True @@ -44,109 +47,3 @@ def expand_pd(entries: List[Entry]) -> Dict[str, PhaseDiagram]: ) return pd_dict - - -def simple_pca(data: np.array, k: int = 2) -> Tuple[np.array, np.array, np.array]: - """ - A barebones implementation of principal component analysis (PCA) utilized in - the ChemicalPotentialDiagram class. - - Args: - data: array of observations - k: Number of principal components returned - - Returns: - tuple: Projected data, eigenvalues, eigenvectors - """ - data = data - np.mean(data.T, axis=1) # centering the data - cov = np.cov(data.T) # calculating covariance matrix - v, w = np.linalg.eig(cov) # performing eigendecomposition - idx = v.argsort()[::-1] # sorting the components - v = v[idx] - w = w[:, idx] - scores = data.dot(w[:, :k]) - - return scores, v[:k], w[:, :k] - - -def get_centroid_2d(vertices: np.array): - """ - A barebones implementation of the formula for calculating the centroid of a 2D - polygon. - - **NOTE**: vertices must be ordered circumfrentially! - - Args: - vertices: - - Returns: - - """ - n = len(vertices) - cx = 0 - cy = 0 - a = 0 - - for i in range(0, n - 1): - xi = vertices[i, 0] - yi = vertices[i, 1] - xi_p = vertices[i + 1, 0] - yi_p = vertices[i + 1, 1] - common_term = xi * yi_p - xi_p * yi - - cx += (xi + xi_p) * common_term - cy += (yi + yi_p) * common_term - a += common_term - - prefactor = 0.5 / (6 * a) - return np.array([prefactor * cx, prefactor * cy]) - - -def check_chempot_bounds(pd, rxn): - phases = rxn._reactant_entries - other_phases = rxn._product_entries - - entry_mu_ranges = {} - - for e in phases + other_phases: - elems = e.composition.elements - chempot_ranges = {} - all_chempots = {e: [] for e in elems} - for simplex, chempots in pd.get_all_chempots(e.composition).items(): - for elem in elems: - all_chempots[elem].append(chempots[elem]) - for elem in elems: - chempot_ranges[elem] = (min(all_chempots[elem]), max(all_chempots[elem])) - - entry_mu_ranges[e] = chempot_ranges - - elems = { - elem for phase in phases + other_phases for elem in phase.composition.elements - } - - reactant_mu_ranges = [entry_mu_ranges[e] for e in phases] - reactant_mu_span = { - elem: ( - min([r[elem][0] for r in reactant_mu_ranges if elem in r]), - max([r[elem][1] for r in reactant_mu_ranges if elem in r]), - ) - for elem in elems - } - - product_mu_ranges = [entry_mu_ranges[e] for e in other_phases] - product_mu_span = { - elem: ( - min([p[elem][0] for p in product_mu_ranges if elem in p]), - max([p[elem][1] for p in product_mu_ranges if elem in p]), - ) - for elem in elems - } - - out_of_bounds = False - for elem in product_mu_span: - if not out_of_bounds: - if product_mu_span[elem][0] > (reactant_mu_span[elem][1] + 1e-5): - out_of_bounds = True - else: - break - return out_of_bounds diff --git a/src/rxn_network/utils.py b/src/rxn_network/utils.py index 81b83d5c..72d800df 100644 --- a/src/rxn_network/utils.py +++ b/src/rxn_network/utils.py @@ -1,3 +1,5 @@ +""" Utility functions used throughout the reaction-network package.""" + from itertools import chain, combinations, zip_longest from pathlib import Path diff --git a/tests/conftest.py b/tests/conftest.py index 48a262f4..0a3663fe 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,3 +1,11 @@ +import pytest +from pathlib import Path +from monty.serialization import loadfn +from rxn_network.entries.entry_set import GibbsEntrySet + +TEST_FILES_PATH = Path(__file__).parent / "test_files" + + def pytest_itemcollected(item): """Make tests names more readable in the tests output.""" item._nodeid = ( @@ -12,3 +20,32 @@ def pytest_itemcollected(item): doc = item.obj.__doc__.strip() if item.obj.__doc__ else "" if doc: item._nodeid = item._nodeid.split("::")[0] + "::" + doc + + +@pytest.fixture( + params=[ + "Mn-O-Y_entries.json.gz", + ], + scope="session", +) +def mp_entries(request): + mp_entries = loadfn(TEST_FILES_PATH / request.param) + return mp_entries + + +@pytest.fixture(scope="session") +def gibbs_entries(mp_entries): + entries = GibbsEntrySet.from_entries(mp_entries, temperature=1000) + return entries + + +@pytest.fixture(scope="session") +def filtered_entries(gibbs_entries): + filtered_entries = gibbs_entries.filter_by_stability(0.0) + return filtered_entries + + +@pytest.fixture(scope="session") +def computed_rxn(): + """ 2 YOCl + 2 NaMnO2 + 0.5 O2 -> Y2Mn2O7 + 2 NaCl""" + return loadfn(TEST_FILES_PATH / "computed_rxn.json.gz") diff --git a/src/rxn_network/network/adaptors/__init__.py b/tests/costs/__init__.py similarity index 100% rename from src/rxn_network/network/adaptors/__init__.py rename to tests/costs/__init__.py diff --git a/tests/costs/test_calculators.py b/tests/costs/test_calculators.py new file mode 100644 index 00000000..0adff6d2 --- /dev/null +++ b/tests/costs/test_calculators.py @@ -0,0 +1,89 @@ +""" Tests for ChempotDistanceCalculator """ +from pathlib import Path + +import pytest +from monty.serialization import loadfn + +import numpy as np + +from rxn_network.costs.calculators import ChempotDistanceCalculator +from rxn_network.thermo.chempot_diagram import ChemicalPotentialDiagram +from rxn_network.entries.entry_set import GibbsEntrySet +from rxn_network.reactions.computed import ComputedReaction + +TEST_FILES_PATH = Path(__file__).parent.parent / "test_files" + +answers = { + "0.5 Y2O3 + 0.5 Mn2O3 -> YMnO3": { + np.sum: 0.480008216, + np.max: 0.480008216, + np.mean: 0.240004108, + }, + "2 YClO + 2 NaMnO2 + 0.5 O2 -> Y2Mn2O7 + 2 NaCl": { + np.sum: 1.369790046, + np.max: 1.369790045, + np.mean: 0.195684292, + }, +} + + +@pytest.fixture(params=["Cl-Mn-Na-O-Y_entries.json.gz"]) +def entries(request): + entries = loadfn(TEST_FILES_PATH / request.param) + return GibbsEntrySet(entries) + + +@pytest.fixture( + params=[ + [["Y2O3", "Mn2O3"], ["YMnO3"]], + [["YOCl", "NaMnO2", "O2"], ["Y2Mn2O7", "NaCl"]], + ] +) +def rxn(entries, request): + reactants = request.param[0] + products = request.param[1] + reactant_entries = [entries.get_min_entry_by_formula(r) for r in reactants] + product_entries = [entries.get_min_entry_by_formula(p) for p in products] + return ComputedReaction.balance(reactant_entries, product_entries) + + +@pytest.fixture(params=["sum", "max", "mean"]) +def mu_func(request): + return request.param + + +@pytest.fixture +def cpd(entries): + return ChemicalPotentialDiagram(entries) + + +@pytest.fixture +def calculator(cpd, mu_func): + return ChempotDistanceCalculator(cpd=cpd, mu_func=mu_func) + + +def test_calculate(calculator, rxn): + actual_cost = calculator.calculate(rxn) + expected_cost = answers[str(rxn)][calculator.mu_func] + + assert actual_cost == pytest.approx(expected_cost) + + +def test_decorate(calculator, rxn): + rxn_dec = calculator.decorate(rxn) + + actual_cost = rxn_dec.data[calculator.name] + expected_cost = answers[str(rxn)][calculator.mu_func] + + assert type(rxn_dec) == ComputedReaction + assert pytest.approx(expected_cost, actual_cost) + + +def test_from_entries(entries, mu_func, rxn): + calc = ChempotDistanceCalculator.from_entries(entries=entries, mu_func=mu_func) + + actual_cost = calc.calculate(rxn) + expected_cost = answers[str(rxn)][calc.mu_func] + + assert type(calc) == ChempotDistanceCalculator + assert pytest.approx(expected_cost, actual_cost) diff --git a/tests/costs/test_softplus.py b/tests/costs/test_softplus.py new file mode 100644 index 00000000..45527010 --- /dev/null +++ b/tests/costs/test_softplus.py @@ -0,0 +1,32 @@ +""" Tests for Softplus """ +import pytest +from rxn_network.costs.softplus import Softplus + + +@pytest.fixture(scope="module") +def softplus_with_attr(): + return Softplus(temp=800, params=["energy_per_atom"], weights=[1.0]) + + +@pytest.fixture(scope="module") +def softplus_with_attr_and_param(): + return Softplus( + temp=800, params=["energy_per_atom", "test_param"], weights=[0.3, 0.7] + ) + + +def test_evaluate(softplus_with_attr, softplus_with_attr_and_param, computed_rxn): + r = computed_rxn.copy() + r.data = {"test_param": 0.1} + + cost1 = softplus_with_attr.evaluate(r) + cost2 = softplus_with_attr_and_param.evaluate(r) + + assert cost1 == pytest.approx(0.250771199) + assert cost2 == pytest.approx(0.297691790) + + +def test_missing_parameter(softplus_with_attr_and_param, computed_rxn): + with pytest.raises(ValueError) as error: + assert softplus_with_attr_and_param.evaluate(computed_rxn) + assert str(error.value) == "Reaction is missing parameter test_param!" diff --git a/tests/entries/__init__.py b/tests/entries/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/entries/test_entry_set.py b/tests/entries/test_entry_set.py new file mode 100644 index 00000000..9ba90e0d --- /dev/null +++ b/tests/entries/test_entry_set.py @@ -0,0 +1,91 @@ +""" Tests for GibbsEntrySet. """ +import pytest +from pymatgen.analysis.phase_diagram import PhaseDiagram + +from rxn_network.entries.entry_set import GibbsEntrySet + + +@pytest.mark.parametrize( + "e_above_hull, expected_phases", + [ + ( + 0.030, + { + "Mn", + "Mn2O3", + "Mn3O4", + "Mn5O8", + "MnO", + "MnO2", + "O2", + "Y", + "Y2Mn2O7", + "Y2O3", + "YMn12", + "YMn2O5", + "YMnO3", + }, + ), + ( + 0.100, + { + "YMnO3", + "Y", + "Y2O3", + "Mn5O8", + "Mn", + "Y2Mn2O7", + "YMn2O4", + "YMn2O5", + "MnO2", + "Mn21O40", + "Mn3O4", + "Mn7O12", + "MnO", + "O2", + "Mn2O3", + "YMn12", + }, + ), + ], +) +def test_filter_by_stability(e_above_hull, expected_phases, gibbs_entries): + filtered_entries = gibbs_entries.filter_by_stability(e_above_hull) + + actual_phases = {e.composition.reduced_formula for e in filtered_entries} + + assert actual_phases == expected_phases + + +def test_build_indices(gibbs_entries): + entries = gibbs_entries.copy() + entries.build_indices() + + num_entries = len(entries) + + indices = [e.data["idx"] for e in entries.entries_list] + assert indices == list(range(num_entries)) + + +def test_get_min_entry_by_formula(gibbs_entries): + f_id = [("YMnO3", "mp-19385"), ("Mn2O3", "mp-1172875"), ("MnO2", "mp-1279979")] + for f, entry_id in f_id: + assert gibbs_entries.get_min_entry_by_formula(f).entry_id == entry_id + + +def test_stabilize_entry(gibbs_entries): + entries = gibbs_entries.copy() + + formulas = ["YMn3O6", "Mn2O5"] + + for f in formulas: + e = entries.get_min_entry_by_formula(f) + e_stable = entries.stabilize_entry(e) + entries.add(e_stable) + + assert e_stable in PhaseDiagram(entries).stable_entries + + +def test_from_pd(mp_entries): + entries = GibbsEntrySet.from_pd(PhaseDiagram(mp_entries), temperature=1000) + assert entries is not None diff --git a/tests/test_gibbs_entry.py b/tests/entries/test_gibbs.py similarity index 85% rename from tests/test_gibbs_entry.py rename to tests/entries/test_gibbs.py index d1df438c..34e0061d 100644 --- a/tests/test_gibbs_entry.py +++ b/tests/entries/test_gibbs.py @@ -3,11 +3,10 @@ import pytest from monty.serialization import loadfn -from pytest import approx from rxn_network.entries.gibbs import GibbsComputedEntry -TEST_FILES_PATH = Path(__file__).parent / "test_files" +TEST_FILES_PATH = Path(__file__).parent.parent / "test_files" @pytest.fixture @@ -23,7 +22,7 @@ def entry(structure): formation_energy_per_atom=-2.436, temperature=300, parameters=None, - entry_id="Test LiFe4P4O16 structure", + entry_id="LiFe4P4O16 test structure", ) return entry @@ -57,7 +56,7 @@ def test_gf_sisso(entries_temps_dict): } entry_energies = {t: e.energy for t, e in entries_temps_dict.items()} - assert entry_energies == approx(test_energies) + assert entry_energies == pytest.approx(test_energies) def test_interpolation(structure): @@ -65,14 +64,14 @@ def test_interpolation(structure): e = GibbsComputedEntry.from_structure( structure=structure, formation_energy_per_atom=-2.436, temperature=temp ) - assert e.energy == approx(-53.7243542548528) + assert e.energy == pytest.approx(-53.7243542548528) def test_to_from_dict(entry): d = entry.as_dict() e = GibbsComputedEntry.from_dict(d) assert e == entry - assert e.energy == approx(entry.energy) + assert e.energy == pytest.approx(entry.energy) def test_str(entry): @@ -83,6 +82,6 @@ def test_normalize(entries_temps_dict): num_atoms = 25 for e in entries_temps_dict.values(): normed_entry = e.normalize(mode="atom") - assert e.uncorrected_energy == approx( + assert e.uncorrected_energy == pytest.approx( normed_entry.uncorrected_energy * num_atoms ) diff --git a/tests/entries/test_nist.py b/tests/entries/test_nist.py new file mode 100644 index 00000000..e9227549 --- /dev/null +++ b/tests/entries/test_nist.py @@ -0,0 +1,83 @@ +""" Tests for NistReferenceEntry. """ +import pytest + +from pymatgen.core.composition import Composition + +from rxn_network.entries.nist import NISTReferenceEntry + + +@pytest.fixture(scope="session") +def entries(): + comp = Composition("CO2") + temps = [300, 600, 900, 1200, 1500, 1800] + return {t: NISTReferenceEntry(composition=comp, temperature=t) for t in temps} + + +def test_invalid_formula(): + with pytest.raises(ValueError) as error: + assert NISTReferenceEntry(Composition("AX"), temperature=300) + assert str(error.value) == "Formula must be in NIST-JANAF thermochemical tables" + + +def test_invalid_temperature(): + with pytest.raises(ValueError) as error: + assert NISTReferenceEntry(Composition("K2CO3"), temperature=200) + assert str(error.value) == "Temperature must be selected from range: [300, 2000] K" + + with pytest.raises(ValueError) as error: + assert NISTReferenceEntry(Composition("K2CO3"), temperature=2300) + assert str(error.value) == "Temperature must be selected from range: [300, 2000] K" + + +def test_energy(entries): + expected_energies = [ + -4.087606831162386, + -4.095773877778095, + -4.101640055931004, + -4.105267551255239, + -4.107236763002682, + -4.107910440705754, + ] + actual_energies = [entry.energy for entry in entries.values()] + + assert actual_energies == pytest.approx(expected_energies) + + +def test_energy_per_atom(entries): + expected_energies = [ + -1.362535610387462, + -1.365257959259365, + -1.3672133519770011, + -1.3684225170850797, + -1.369078921000894, + -1.3693034802352513, + ] + actual_energies = [entry.energy_per_atom for entry in entries.values()] + + assert actual_energies == pytest.approx(expected_energies) + + +def test_correction_uncertainty(entries): + assert all([e.correction_uncertainty == 0 for e in entries.values()]) + + +def test_correction_uncertainty_per_atom(entries): + assert all([e.correction_uncertainty_per_atom == 0 for e in entries.values()]) + + +def test_is_experimental(entries): + assert all([e.is_experimental for e in entries.values()]) + + +def test_as_dict(entries): + d = entries[300].as_dict() + + assert type(d) == dict + assert d.get("composition") + assert d.get("temperature") + + +def test_from_dict(entries): + e = entries[300] + d = e.as_dict() + assert NISTReferenceEntry.from_dict(d) == e diff --git a/tests/enumerators/__init__.py b/tests/enumerators/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/enumerators/test_basic.py b/tests/enumerators/test_basic.py new file mode 100644 index 00000000..8d842db5 --- /dev/null +++ b/tests/enumerators/test_basic.py @@ -0,0 +1,147 @@ +""" Tests for BasicEnumerator and BasicOpenEnumerator """ +from pathlib import Path +from monty.serialization import loadfn +import pytest + +from rxn_network.enumerators.basic import BasicEnumerator, BasicOpenEnumerator + +TEST_FILES_PATH = Path(__file__).parent.parent / "test_files" +RXNS_FILE = "ymno3_rxns.json.gz" + + +@pytest.fixture +def ymno3_rxns(): + return loadfn(TEST_FILES_PATH / RXNS_FILE) + + +@pytest.fixture +def basic_enumerator_default(): + return BasicEnumerator() + + +@pytest.fixture +def basic_enumerator_with_calculator(): + return BasicEnumerator(calculators=["ChempotDistanceCalculator"]) + + +@pytest.fixture +def basic_enumerator_with_precursors(): + return BasicEnumerator(precursors=["Y2O3", "Mn2O3"]) + + +@pytest.fixture +def basic_enumerator_with_target(): + return BasicEnumerator(target="YMnO3") + + +@pytest.fixture +def basic_enumerator_with_precursors_and_target(): + return BasicEnumerator(precursors=["Y2O3", "Mn2O3"], target="YMnO3") + + +@pytest.fixture +def basic_open_enumerator(): + return BasicOpenEnumerator(["O2"]) + + +@pytest.fixture +def basic_open_enumerator_with_precursors(): + return BasicOpenEnumerator(["O2"], precursors=["Y2O3", "Mn2O3"]) + + +@pytest.fixture +def basic_open_enumerator_with_target(): + return BasicOpenEnumerator(["O2"], target="Y2Mn2O7") + + +@pytest.fixture +def basic_open_enumerator_with_precursors_and_target(): + return BasicOpenEnumerator(["O2"], precursors=["Y2O3", "Mn2O3"], target="Y2Mn2O7") + + +def test_enumerate( + filtered_entries, basic_enumerator_default, basic_enumerator_with_calculator +): + expected_num_rxns = 538 + + for enumerator in [basic_enumerator_default, basic_enumerator_with_calculator]: + rxns = enumerator.enumerate(filtered_entries) + + assert expected_num_rxns == len(rxns) + assert len(rxns) == len(set(rxns)) + assert all([not r.is_identity for r in rxns]) + + if enumerator.calculators: + assert all([r.data["chempot_distance"] is not None for r in rxns]) + + +def test_enumerate_with_precursors( + filtered_entries, + basic_enumerator_with_precursors, + basic_open_enumerator_with_precursors, +): + + for enumerator in [ + basic_enumerator_with_precursors, + basic_open_enumerator_with_precursors, + ]: + + rxns = enumerator.enumerate(filtered_entries) + precursors = enumerator.precursors + + for r in rxns: + reactants = [i.reduced_formula for i in r.reactants] + products = [i.reduced_formula for i in r.products] + + for precursor in precursors: + assert precursor in reactants + assert precursor not in products + + +def test_enumerate_with_target( + filtered_entries, basic_enumerator_with_target, basic_open_enumerator_with_target +): + + for enumerator in [basic_enumerator_with_target, basic_open_enumerator_with_target]: + rxns = enumerator.enumerate(filtered_entries) + target = enumerator.target + + for r in rxns: + reactants = [i.reduced_formula for i in r.reactants] + products = [i.reduced_formula for i in r.products] + assert target not in reactants + assert target in products + + +def test_enumerate_with_precursors_and_target( + filtered_entries, basic_enumerator_with_precursors_and_target +): + rxns = basic_enumerator_with_precursors_and_target.enumerate(filtered_entries) + + assert len(rxns) == 1 + assert str(rxns[0]) == "Mn2O3 + Y2O3 -> 2 YMnO3" + + +def test_open_enumerate_with_precursors_and_target( + filtered_entries, basic_open_enumerator_with_precursors_and_target +): + rxns = basic_open_enumerator_with_precursors_and_target.enumerate(filtered_entries) + + assert len(rxns) == 11 + + for r in rxns: + reactants = [i.reduced_formula for i in r.reactants] + products = [i.reduced_formula for i in r.products] + assert "O2" in reactants or "O2" in products + assert "Y2Mn2O7" in products + + +def test_open_enumerate(filtered_entries, basic_open_enumerator): + expected_num_rxns = 1358 + + rxns = basic_open_enumerator.enumerate(filtered_entries) + print(rxns) + + assert expected_num_rxns == len(rxns) + assert len(rxns) == len(set(rxns)) + assert all([not r.is_identity for r in rxns]) diff --git a/tests/enumerators/test_minimize.py b/tests/enumerators/test_minimize.py new file mode 100644 index 00000000..4bdf58f9 --- /dev/null +++ b/tests/enumerators/test_minimize.py @@ -0,0 +1,166 @@ +""" Tests for MinimizeGibbsEnumerator and MinimizeGrandPotentialEnumerator """ +import pytest +from pymatgen.core.composition import Element +from rxn_network.enumerators.minimize import ( + MinimizeGibbsEnumerator, + MinimizeGrandPotentialEnumerator, +) + + +@pytest.fixture +def gibbs_enumerator_default(): + return MinimizeGibbsEnumerator() + + +@pytest.fixture +def gibbs_enumerator_with_calculator(): + return MinimizeGibbsEnumerator(calculators=["ChempotDistanceCalculator"]) + + +@pytest.fixture +def gibbs_enumerator_with_precursors(): + return MinimizeGibbsEnumerator(precursors=["Y2O3", "Mn2O3"]) + + +@pytest.fixture +def gibbs_enumerator_with_target(): + return MinimizeGibbsEnumerator(target="YMnO3") + + +@pytest.fixture +def gibbs_enumerator_with_precursors_and_target(): + return MinimizeGibbsEnumerator(precursors=["Y2O3", "Mn2O3"], target="YMnO3") + + +@pytest.fixture +def grand_potential_enumerator(): + return MinimizeGrandPotentialEnumerator(open_elem=Element("O"), mu=0.0) + + +@pytest.fixture +def grand_potential_enumerator_with_precursors(): + return MinimizeGrandPotentialEnumerator( + open_elem=Element("O"), mu=0.0, precursors=["Y2O3", "Mn2O3"] + ) + + +@pytest.fixture +def grand_potential_enumerator_with_target(): + return MinimizeGrandPotentialEnumerator( + open_elem=Element("O"), mu=0.0, target="Y2Mn2O7" + ) + + +@pytest.fixture +def grand_potential_enumerator_with_precursors_and_target(): + return MinimizeGrandPotentialEnumerator( + open_elem=Element("O"), mu=0.0, precursors=["Y2O3", "Mn2O3"], target="Y2Mn2O7" + ) + + +def test_enumerate_gibbs( + filtered_entries, gibbs_enumerator_default, gibbs_enumerator_with_calculator +): + expected_num_rxns = 109 + + for enumerator in [gibbs_enumerator_default, gibbs_enumerator_with_calculator]: + rxns = enumerator.enumerate(filtered_entries) + + assert len(rxns) == expected_num_rxns + assert len(rxns) == len(set(rxns)) + assert all([not r.is_identity for r in rxns]) + + if enumerator.calculators: + assert all([r.data["chempot_distance"] is not None for r in rxns]) + + +def test_enumerate_gibbs_with_precursors( + filtered_entries, gibbs_enumerator_with_precursors +): + expected_num_rxns = 2 + + rxns = gibbs_enumerator_with_precursors.enumerate(filtered_entries) + precursors = gibbs_enumerator_with_precursors.precursors + + assert len(rxns) == expected_num_rxns + + for r in rxns: + reactants = [i.reduced_formula for i in r.reactants] + products = [i.reduced_formula for i in r.products] + + for precursor in precursors: + assert precursor in reactants + assert precursor not in products + + +def test_enumerate_gibbs_with_target(filtered_entries, gibbs_enumerator_with_target): + expected_num_rxns = 32 + + rxns = gibbs_enumerator_with_target.enumerate(filtered_entries) + target = gibbs_enumerator_with_target.target + + assert len(rxns) == expected_num_rxns + + for r in rxns: + reactants = [i.reduced_formula for i in r.reactants] + products = [i.reduced_formula for i in r.products] + assert target not in reactants + assert target in products + + +def test_enumerate_gibbs_with_precursors_and_target( + filtered_entries, gibbs_enumerator_with_precursors_and_target +): + rxns = gibbs_enumerator_with_precursors_and_target.enumerate(filtered_entries) + + assert {str(r) for r in rxns} == {"0.5 Mn2O3 + 0.5 Y2O3 -> YMnO3"} + + +def test_enumerate_grand_potential(filtered_entries, grand_potential_enumerator): + expected_num_rxns = 39 + + rxns = grand_potential_enumerator.enumerate(filtered_entries) + + assert len(rxns) == expected_num_rxns + assert len(rxns) == len(set(rxns)) + assert all([not r.is_identity for r in rxns]) + + +def test_enumerate_grand_potential_precursors( + filtered_entries, grand_potential_enumerator_with_precursors +): + expected_rxns = { + "Mn2O3 + 0.5 Y2O3 + 0.25 O2 -> YMn2O5", + "Mn2O3 + Y2O3 + 0.5 O2 -> Y2Mn2O7", + } + + rxns = grand_potential_enumerator_with_precursors.enumerate(filtered_entries) + assert {str(r) for r in rxns} == expected_rxns + + +def test_enumerate_grand_potential_target( + filtered_entries, grand_potential_enumerator_with_target +): + expected_num_rxns = 12 + + rxns = grand_potential_enumerator_with_target.enumerate(filtered_entries) + target = grand_potential_enumerator_with_target.target + + assert len(rxns) == expected_num_rxns + + for r in rxns: + reactants = [i.reduced_formula for i in r.reactants] + products = [i.reduced_formula for i in r.products] + assert target not in reactants + assert target in products + + +def test_enumerate_grand_potential_precursors_target( + filtered_entries, grand_potential_enumerator_with_precursors_and_target +): + rxns = grand_potential_enumerator_with_precursors_and_target.enumerate( + filtered_entries + ) + + assert len(rxns) == 1 + assert str(rxns[0]) == "Mn2O3 + Y2O3 + 0.5 O2 -> Y2Mn2O7" diff --git a/tests/enumerators/test_utils.py b/tests/enumerators/test_utils.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/firetasks/__init__.py b/tests/firetasks/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/firetasks/test_build_inputs.py b/tests/firetasks/test_build_inputs.py new file mode 100644 index 00000000..d7b051fd --- /dev/null +++ b/tests/firetasks/test_build_inputs.py @@ -0,0 +1,2 @@ +""" Tests for EntriesFromDb and EntriesFromMPRester""" +import pytest diff --git a/tests/firetasks/test_parse_outputs.py b/tests/firetasks/test_parse_outputs.py new file mode 100644 index 00000000..fa6d61cc --- /dev/null +++ b/tests/firetasks/test_parse_outputs.py @@ -0,0 +1,2 @@ +""" Tests for ReactionsToDb and NetworkToDb """ +import pytest diff --git a/tests/firetasks/test_run_calc.py b/tests/firetasks/test_run_calc.py new file mode 100644 index 00000000..784376b1 --- /dev/null +++ b/tests/firetasks/test_run_calc.py @@ -0,0 +1,2 @@ +""" Tests for RunEnumerators and RunNetwork""" +import pytest diff --git a/tests/firetasks/test_utils.py b/tests/firetasks/test_utils.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/fireworks/__init__.py b/tests/fireworks/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/fireworks/test_core.py b/tests/fireworks/test_core.py new file mode 100644 index 00000000..6dc11cd3 --- /dev/null +++ b/tests/fireworks/test_core.py @@ -0,0 +1,2 @@ +""" Tests for EnumeratorFW and NetworkFW """ +import pytest diff --git a/tests/network/__init__.py b/tests/network/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/network/test_entry.py b/tests/network/test_entry.py new file mode 100644 index 00000000..6641e207 --- /dev/null +++ b/tests/network/test_entry.py @@ -0,0 +1,2 @@ +""" Tests for NetworkEntry """ +import pytest diff --git a/tests/network/test_network.py b/tests/network/test_network.py new file mode 100644 index 00000000..c29d9110 --- /dev/null +++ b/tests/network/test_network.py @@ -0,0 +1,2 @@ +""" Tests for ReactionNetwork """ +import pytest diff --git a/tests/pathways/__init__.py b/tests/pathways/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/pathways/test_balanced.py b/tests/pathways/test_balanced.py new file mode 100644 index 00000000..6c8a831b --- /dev/null +++ b/tests/pathways/test_balanced.py @@ -0,0 +1,2 @@ +""" Tests for BalancedPathway """ +import pytest diff --git a/tests/pathways/test_basic.py b/tests/pathways/test_basic.py new file mode 100644 index 00000000..59917a54 --- /dev/null +++ b/tests/pathways/test_basic.py @@ -0,0 +1,2 @@ +""" Tests for BasicPathway """ +import pytest diff --git a/tests/pathways/test_solver.py b/tests/pathways/test_solver.py new file mode 100644 index 00000000..59451327 --- /dev/null +++ b/tests/pathways/test_solver.py @@ -0,0 +1,2 @@ +""" Tests for PathwaySolver""" +import pytest diff --git a/tests/pathways/test_utils.py b/tests/pathways/test_utils.py new file mode 100644 index 00000000..0e28dc74 --- /dev/null +++ b/tests/pathways/test_utils.py @@ -0,0 +1,315 @@ +""" Tests for pathways/utils.py """ +from pathlib import Path +import pytest +import numpy as np +from rxn_network.pathways.utils import balance_path_arrays + +TEST_FILES_PATH = Path(__file__).parent.parent / "test_files" +ARRAY_FILE = "comp_matrices.npy" + + +@pytest.fixture(scope="module") +def comp_matrices(): + return np.load(str(TEST_FILES_PATH / ARRAY_FILE)) + + +@pytest.fixture +def net_coeffs(): + return np.array( + [ + 0.5, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + -1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ] + ) + + +@pytest.fixture() +def c_mats(): + arr = np.array( + [ + [ + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + -1.6, + 0.0, + 0.0, + 0.0, + 0.2, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -1.0, + 0.0, + 0.0, + ], + [ + 0.5, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -1.0, + 0.0, + 0.0, + 0.0, + -1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 4.0, + 0.0, + 0.0, + ], + ], + [ + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + -1.6, + 0.0, + 0.0, + 0.0, + 0.2, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.90909091, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.90909091, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.18181818, + 0.0, + 0.0, + 0.0, + 0.0, + ], + [ + 0.1, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -1.0, + 0.0, + 0.0, + 0.0, + -1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.8, + 0.0, + 0.0, + 0.0, + 0.0, + ], + ], + ] + ) + return arr + + +@pytest.fixture +def m_mats(): + arr = np.array( + [[0.55555556, 0.44444444, 0.11111111], [0.55555556, 0.48888889, 0.11111111]] + ) + + return arr + + +def test_balance_path_arrays(comp_matrices, net_coeffs, c_mats, m_mats): + c_mats_actual, m_mats_actual = balance_path_arrays( + comp_matrices, net_coeffs, tol=1e-6 + ) + assert np.allclose(c_mats, c_mats_actual) + assert np.allclose(m_mats, m_mats_actual) diff --git a/tests/reactions/__init__.py b/tests/reactions/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/reactions/test_basic.py b/tests/reactions/test_basic.py new file mode 100644 index 00000000..4fa2d25b --- /dev/null +++ b/tests/reactions/test_basic.py @@ -0,0 +1,237 @@ +""" +Test for BasicReaction. Several tests adapted from +test module for pymatgen.analysis.reaction_calculator +""" +import pytest +from pymatgen.core.composition import Composition, Element + +from rxn_network.reactions.basic import BasicReaction + + +@pytest.fixture +def pre_balanced_rxn(): + """Returns a simple, pre-balanced iron oxidation reaction.""" + reactants = [Composition("Fe"), Composition("O2")] + products = [Composition("Fe2O3")] + coefficients = [-2, -1.5, 1] + + rxn = BasicReaction( + compositions=reactants + products, coefficients=coefficients, balanced=True + ) + return rxn + + +@pytest.fixture +def auto_balanced_rxn(): + """Returns the same iron oxidation reaction, after automatically balancing""" + reactants = ["Fe", "O2"] + products = ["Fe2O3"] + return BasicReaction.from_formulas(reactants, products) + + +@pytest.mark.parametrize( + "reactants, products, expected_rxn, expected_lowest_num_errors", + [ + (["MgO"], ["MgO"], "MgO -> MgO", 0), + (["Fe", "O2"], ["Fe2O3"], "2 Fe + 1.5 O2 -> Fe2O3", 0), + (["FePO4", "LiPO3"], ["LiFeP2O7"], "FePO4 + LiPO3 -> LiFeP2O7", 0), + (["Zn", "HCl"], ["ZnCl2", "H2"], "Zn + 2 HCl -> ZnCl2 + H2", 0), + ( + ["LiCrO2", "La8Ti8O12", "O2"], + ["LiLa3Ti3CrO12"], + "LiCrO2 + 1.5 La2Ti2O3 + 2.75 O2 -> LiLa3Ti3CrO12", + 0, + ), + (["Na", "K2O"], ["Na2O", "K"], "2 Na + K2O -> Na2O + 2 K", 0), + ( + ["NaMnO2", "YClO", "O2"], + ["Y2Mn2O7", "NaCl"], + "2 NaMnO2 + 2 YClO + 0.5 O2 -> Y2Mn2O7 + 2 NaCl", + 0, + ), + ( + ["La2O3", "Co2O3", "Li2ZrO3"], + ["Li2O", "La2Zr2O7", "Li3CoO3"], + "La2O3 + 0.3333 Co2O3 + 2 Li2ZrO3 -> Li2O + La2Zr2O7 + 0.6667 Li3CoO3", + 0, + ), + (["Li", "Cl", "Cl"], ["LiCl"], "Li + 0.25 Cl2 + 0.25 Cl2 -> LiCl", 0), + ( + ["LiMnCl3", "LiCl", "MnCl2"], + ["Li2MnCl4"], + "LiMnCl3 + 3 LiCl + MnCl2 -> 2 Li2MnCl4", + 0, + ), + (["Fe", "O2"], ["Fe", "O2"], "Fe + O2 -> Fe + O2", 0), + ( + ["Fe", "O2", "Na", "Li", "Cl"], + ["FeO2", "NaCl", "Li2Cl2"], + "Fe + O2 + Na + 2 Li + 1.5 Cl2 -> FeO2 + NaCl + 2 LiCl", + 0, + ), + (["FePO4", "O"], ["FePO4"], "FePO4 -> FePO4", 1), + ( + ["La2O3", "Co2O3", "Li2ZrO3"], + ["Li2O", "La2Zr2O7", "Li3CoO3", "Xe"], + "La2O3 + 0.3333 Co2O3 + 2 Li2ZrO3 -> Li2O + La2Zr2O7 + 0.6667 Li3CoO3", + 1, + ), + (["FePO4", "Mn"], ["FePO4", "Xe"], "FePO4 -> FePO4", 2), + ( + ["La2O3", "Co2O3", "Li2ZrO3"], + ["Li2O", "La2Zr2O7", "Li3CoO3", "Xe", "XeNe"], + "La2O3 + 0.3333 Co2O3 + 2 Li2ZrO3 -> Li2O + La2Zr2O7 + 0.6667 Li3CoO3", + 2, + ), + ( + ["LiCoO2"], + ["La2O3", "Co2O3", "Li2O", "LiF", "CoF3"], + "1.667 LiCoO2 + 0.3333 CoF3 -> Co2O3 + 0.3333 Li2O + LiF", + 2, + ), + (["LiCoO2", "Li2O"], ["ZrF4", "Co2O3"], "2 LiCoO2 -> Li2O + Co2O3", 2), + ( + ["Fe", "Na", "Li2O", "Cl"], + ["LiCl", "Na2O", "Xe", "FeCl", "Mn"], + "Fe + Na + 0.5 Li2O + Cl2 -> LiCl + 0.5 Na2O + FeCl", + 2, + ), + (["XeMn", "Li"], ["S", "LiS2", "FeCl"], "Li + 2 S -> LiS2", 3), + ], +) +def test_balance(reactants, products, expected_rxn, expected_lowest_num_errors): + rxn = BasicReaction.from_formulas(reactants, products) + assert str(rxn) == expected_rxn + assert rxn.lowest_num_errors == expected_lowest_num_errors + + +def test_equality(pre_balanced_rxn, auto_balanced_rxn): + assert pre_balanced_rxn == auto_balanced_rxn + + +@pytest.mark.parametrize( + "reactants, products", + [ + (["YMnO3"], ["YMnO3"]), + (["YMnO3", "O2"], ["YMnO3", "O2"]), + (["Li", "Na", "K"], ["Li", "Na", "K"]), + ], +) +def test_is_identity(reactants, products): + rxn = BasicReaction.from_formulas(reactants, products) + + assert rxn.is_identity is True + + +def test_get_el_amount(pre_balanced_rxn): + rxn_normalized_oxygen = pre_balanced_rxn.copy().normalize_to_element(Element("O")) + assert pre_balanced_rxn.get_el_amount(Element("Fe")) == 2 + assert pre_balanced_rxn.get_el_amount(Element("O")) == 3 + assert rxn_normalized_oxygen.get_el_amount(Element("O")) == 1 + + +def test_copy(pre_balanced_rxn): + rxn_copy = pre_balanced_rxn.copy() + assert rxn_copy == pre_balanced_rxn.copy() + + +def test_equals(): + rxn1 = BasicReaction.from_formulas(["Y2O3", "MnO2"], ["Y2Mn2O7"]) + rxn2 = BasicReaction.from_formulas(["MnO2", "Y2O3"], ["Y2Mn2O7"]) + + assert rxn1 == rxn2 + + +def test_reverse(): + rxn = BasicReaction.from_formulas( + ["La2O3", "Co2O3", "Li2ZrO3"], ["Li2O", "La2Zr2O7", "Li3CoO3", "Xe"] + ) + rxn_reverse = rxn.reverse() + + assert ( + rxn_reverse + == "Li2O + La2Zr2O7 + 0.6667 Li3CoO3 -> La2O3 + 0.3333 Co2O3 + 2 Li2ZrO3" + ) + assert rxn_reverse.reverse() == rxn + + +def test_normalize(pre_balanced_rxn): + rxn, factor = pre_balanced_rxn.normalized_repr_and_factor() + rxn_o2_norm = pre_balanced_rxn.normalize_to(Composition("O2")) + rxn_o2_norm_5 = pre_balanced_rxn.normalize_to(Composition("O2"), 5) + + assert rxn == "4 Fe + 3 O2 -> 2 Fe2O3" + assert factor == 2 + assert rxn_o2_norm == "1.333 Fe + O2 -> 0.6667 Fe2O3" + assert rxn_o2_norm_5 == "6.667 Fe + 5 O2 -> 3.333 Fe2O3" + + +def test_from_string(pre_balanced_rxn): + prebalanced_rxn_from_str = BasicReaction.from_string("2 Fe + 1.5 O2 -> Fe2O3") + + rxn = BasicReaction.from_formulas(["Y2O3", "MnO2"], ["Y2Mn2O7"]) + rxn_from_str = BasicReaction.from_string("Y2O3 + 2 MnO2 -> Y2Mn2O7") + + assert pre_balanced_rxn == prebalanced_rxn_from_str + assert rxn == rxn_from_str + + +def test_chemical_system(pre_balanced_rxn): + complex_rxn = BasicReaction.from_formulas( + ["LiCoO2", "Be", "Na"], ["La2O3", "Co2O3", "Li2O", "LiF", "CoF3"] + ) + assert pre_balanced_rxn.chemical_system == "Fe-O" + assert complex_rxn.chemical_system == "Be-Co-F-La-Li-Na-O" + + +def test_balanced(): + rxn_unbalanced = BasicReaction.from_formulas(["MnO2", "Y2O3"], ["YMn2O5"]) + rxn_balanced = BasicReaction.from_formulas(["YClO", "LiMnO2"], ["YMnO3", "LiCl"]) + rxn_balanced_2 = BasicReaction.from_formulas( + ["Li", "Na2O", "FeCl2", "Y2O3"], ["YCl3", "Fe2O3", "NaCl", "Li2O"] + ) + + assert rxn_unbalanced.balanced is False + assert rxn_balanced.balanced is True + assert rxn_balanced_2.balanced is True + + +def test_get_coeff(pre_balanced_rxn): + expected_coeffs = [-2, -1.5, 1] + coeffs = [pre_balanced_rxn.get_coeff(c) for c in pre_balanced_rxn.compositions] + + assert coeffs == expected_coeffs + + +def test_energy(pre_balanced_rxn): + with pytest.raises(ValueError) as error: + assert pre_balanced_rxn.energy + assert str(error.value) == "No energy for a basic reaction!" + + +def test_energy_per_atom(pre_balanced_rxn): + with pytest.raises(ValueError) as error: + assert pre_balanced_rxn.energy_per_atom + assert str(error.value) == "No energy per atom for a basic reaction!" + + +def test_reactants_products(pre_balanced_rxn): + assert pre_balanced_rxn.reactants == [Composition("Fe"), Composition("O2")] + assert pre_balanced_rxn.products == [Composition("Fe2O3")] + + +def test_to_from_dict(pre_balanced_rxn): + d = pre_balanced_rxn.as_dict() + rxn = BasicReaction.from_dict(d) + + assert rxn == pre_balanced_rxn + + +def test_scientific_notation(): + reactants = ["FePO4"] + products = ["FePO3.9999", "O2"] + rxn = BasicReaction.from_formulas(reactants, products) + rxn2 = BasicReaction.from_string("1e3 FePO4 + 20 CO -> 1e1 O2 + 1e3 Fe1P1O4 + 20 C") + + assert str(rxn) == "FePO4 -> Fe1P1O3.9999 + 5e-05 O2" + assert str(rxn2) == "1000 FePO4 + 20 CO -> 10 O2 + 1000 FePO4 + 20 C" diff --git a/tests/reactions/test_computed.py b/tests/reactions/test_computed.py new file mode 100644 index 00000000..b198f728 --- /dev/null +++ b/tests/reactions/test_computed.py @@ -0,0 +1,99 @@ +""" Tests for ComputedReaction. Some tests adapted from pymatgen. """ +import pytest +from pathlib import Path +from monty.serialization import loadfn + +from rxn_network.reactions.computed import ComputedReaction + +TEST_FILES_PATH = Path(__file__).parent.parent / "test_files" +ENTRIES_FILE = "yocl-namno2_rxn_entries.json.gz" + + +@pytest.fixture(scope="session") +def entries(): + return loadfn(TEST_FILES_PATH / ENTRIES_FILE) + + +@pytest.fixture(scope="session") +def reactants(entries): + return [entries["YOCl"], entries["NaMnO2"], entries["O2"]] + + +@pytest.fixture(scope="session") +def products(entries): + return [entries["Y2Mn2O7"], entries["NaCl"]] + + +@pytest.fixture(scope="session") +def pre_balanced_rxn(reactants, products): + """Returns a simple, pre-balanced computed reaction.""" + coefficients = [-2, -2, -0.5, 1, 2] + rxn = ComputedReaction( + entries=reactants + products, + coefficients=coefficients, + ) + return rxn + + +@pytest.fixture(scope="session") +def auto_balanced_rxn(reactants, products): + """Returns the same iron oxidation reaction, after automatically balancing""" + return ComputedReaction.balance( + reactant_entries=reactants, product_entries=products + ) + + +def test_energy(pre_balanced_rxn, auto_balanced_rxn): + expected_energy = -2.701048 + + assert pre_balanced_rxn.energy == pytest.approx(expected_energy) + assert auto_balanced_rxn.energy == pytest.approx(expected_energy) + + +def test_energy_per_atom(pre_balanced_rxn, auto_balanced_rxn): + expected_energy_per_atom = -0.1800700 + + assert pre_balanced_rxn.energy_per_atom == pytest.approx(expected_energy_per_atom) + assert auto_balanced_rxn.energy_per_atom == pytest.approx(expected_energy_per_atom) + + +def test_energy_uncertainty(pre_balanced_rxn, auto_balanced_rxn): + expected_energy_uncertainty = 0.0229486383 + + assert pre_balanced_rxn.energy_uncertainty == pytest.approx( + expected_energy_uncertainty + ) + assert auto_balanced_rxn.energy_uncertainty == pytest.approx( + expected_energy_uncertainty + ) + + +def test_energy_uncertainty_per_atom(pre_balanced_rxn, auto_balanced_rxn): + expected_energy_uncertainty_per_atom = 0.0015299092 + + assert pre_balanced_rxn.energy_uncertainty_per_atom == pytest.approx( + expected_energy_uncertainty_per_atom + ) + assert auto_balanced_rxn.energy_uncertainty_per_atom == pytest.approx( + expected_energy_uncertainty_per_atom + ) + + +def test_copy(pre_balanced_rxn, auto_balanced_rxn): + pre_balanced_rxn_copy = pre_balanced_rxn.copy() + auto_balanced_rxn_copy = auto_balanced_rxn.copy() + + assert ( + pre_balanced_rxn + == auto_balanced_rxn + == pre_balanced_rxn_copy + == auto_balanced_rxn_copy + ) + + +def test_reverse(pre_balanced_rxn): + pre_balanced_rxn_rev = pre_balanced_rxn.reverse() + + assert pre_balanced_rxn.energy == -pre_balanced_rxn_rev.energy + + assert pre_balanced_rxn == pre_balanced_rxn_rev.reverse() diff --git a/tests/reactions/test_open.py b/tests/reactions/test_open.py new file mode 100644 index 00000000..d63c3491 --- /dev/null +++ b/tests/reactions/test_open.py @@ -0,0 +1,106 @@ +""" Tests for OpenComputedReaction. """ +import pytest + +from pymatgen.core.composition import Element +from rxn_network.reactions.open import OpenComputedReaction + + +@pytest.fixture(scope="module", params=["Na", "Mn", "O"]) +def element(request): + return request.param + + +@pytest.fixture(scope="module", params=[0, -2, -4, -6]) +def chempot(request): + return request.param + + +@pytest.fixture(scope="module") +def open_computed_rxn(computed_rxn, element, chempot): + chempots = {Element(element): chempot} + + return OpenComputedReaction( + entries=computed_rxn.entries, + coefficients=computed_rxn.coefficients, + chempots=chempots, + data=computed_rxn.data, + lowest_num_errors=computed_rxn.lowest_num_errors, + ) + + +def test_energy(open_computed_rxn): + open_elem = list(open_computed_rxn.chempots.keys())[0] + chempot = list(open_computed_rxn.chempots.values())[0] + + expected = { + "Na": { + 0: -2.701048424999957, + -2: -2.701048424999957, + -4: -2.701048424999957, + -6: -2.701048424999957, + }, + "Mn": { + 0: -2.701048424999957, + -2: -2.701048424999957, + -4: -2.701048424999957, + -6: -2.701048424999957, + }, + "O": { + 0: -2.701048424999957, + -2: -0.7010484249999713, + -4: 1.2989515750000287, + -6: 3.2989515750000145, + }, + } + + assert open_computed_rxn.energy == pytest.approx(expected[open_elem.name][chempot]) + + +def test_num_atoms(open_computed_rxn): + open_elem = list(open_computed_rxn.chempots.keys())[0] + + expected = {"Na": 13, "Mn": 13, "O": 8} + assert open_computed_rxn.num_atoms == pytest.approx(expected[open_elem.name]) + + +def test_elements(open_computed_rxn): + open_elem = list(open_computed_rxn.chempots.keys())[0] + + expected = { + "Na": {Element(e) for e in ["Mn", "O", "Y", "Cl"]}, + "Mn": {Element(e) for e in ["Na", "O", "Y", "Cl"]}, + "O": {Element(e) for e in ["Na", "Mn", "Y", "Cl"]}, + } + + assert set(open_computed_rxn.elements) == expected[open_elem.name] + + +def test_copy(open_computed_rxn): + assert open_computed_rxn.copy() == open_computed_rxn + + +def test_reverse(open_computed_rxn): + open_computed_rxn_rev = open_computed_rxn.reverse() + + assert open_computed_rxn_rev.energy == -open_computed_rxn.energy + assert open_computed_rxn_rev.reverse() == open_computed_rxn + + +def test_balance(open_computed_rxn): + reactant_entries = open_computed_rxn.reactant_entries + product_entries = open_computed_rxn.product_entries + chempots = open_computed_rxn.chempots + + rxn = OpenComputedReaction.balance(reactant_entries, product_entries, chempots) + + assert open_computed_rxn == rxn + + +def test_total_chemical_system(open_computed_rxn): + open_elem = list(open_computed_rxn.chempots.keys())[0].name + + elems = [e.name for e in open_computed_rxn.elements] + elems.append(open_elem) + + total_chemsys = "-".join(sorted(set(elems))) + assert open_computed_rxn.total_chemical_system == total_chemsys diff --git a/tests/reactions/test_reaction_set.py b/tests/reactions/test_reaction_set.py new file mode 100644 index 00000000..73369f13 --- /dev/null +++ b/tests/reactions/test_reaction_set.py @@ -0,0 +1,35 @@ +""" Tests for ReactionSet.""" +from pathlib import Path +import pytest + +from monty.serialization import loadfn +from pymatgen.core.composition import Element +from rxn_network.reactions.open import OpenComputedReaction +from rxn_network.reactions.reaction_set import ReactionSet +from rxn_network.costs.softplus import Softplus + +TEST_FILES_PATH = Path(__file__).parent.parent / "test_files" +RXNS_FILE = "ymno3_rxns.json.gz" + + +@pytest.fixture(scope="module") +def rxns(): + return loadfn(TEST_FILES_PATH / RXNS_FILE) + + +@pytest.fixture(scope="module") +def rxn_set(rxns): + return ReactionSet.from_rxns(rxns) + + +def test_get_rxns(rxns, rxn_set): + open_rxns = rxn_set.get_rxns(open_elem="O", chempot=0) + assert rxn_set.get_rxns() == rxns + assert open_rxns != rxns + assert all([type(r) == OpenComputedReaction for r in open_rxns]) + assert all([r.chempots == {Element("O"): 0} for r in open_rxns]) + + +def test_calculate_costs(rxns, rxn_set): + cf = Softplus() + assert rxn_set.calculate_costs(cf) == [cf.evaluate(r) for r in rxns] diff --git a/tests/test_basic_reaction.py b/tests/test_basic_reaction.py deleted file mode 100644 index 9b891f00..00000000 --- a/tests/test_basic_reaction.py +++ /dev/null @@ -1,65 +0,0 @@ -""" Test for BasicReaction. Some tests adapted from pymatgen. """ -import pytest -from pymatgen.core.composition import Composition - -from rxn_network.reactions.basic import BasicReaction - - -@pytest.fixture -def prebalanced_rxn(): - """Returns a simple, pre-balanced iron oxidation reaction.""" - reactants = [Composition("Fe"), Composition("O2")] - products = [Composition("Fe2O3")] - coefficients = [-2, -1.5, 1] - - rxn = BasicReaction(reactants + products, coefficients, balanced=True) - return rxn - - -def test_simple_balance(): - reactants = [Composition("Fe"), Composition("O2")] - products = [Composition("Fe2O3")] - rxn = BasicReaction.balance(reactants, products) - - assert str(rxn) == "2 Fe + 1.5 O2 -> Fe2O3" - - -def test_complex_balance(): - pass - - -def test_is_identity(prebalanced_rxn): - rxn1 = BasicReaction.balance([Composition("YMnO3")], [Composition("YMnO3")]) - - rxn2 = BasicReaction.balance( - [Composition("YMnO3"), Composition("O2")], - [Composition("YMnO3"), Composition("O2")], - ) - - assert rxn1.is_identity is True - assert rxn2.is_identity is True - assert prebalanced_rxn.is_identity is False - - -def test_copy(): - pass - - -def test_reverse(): - pass - - -def test_normalize(prebalanced_rxn): - assert prebalanced_rxn.normalized_repr == "4 Fe + 3 O2 -> 2 Fe2O3" - - -def test_reduce(): - pass - - -def test_eq(): - pass - - -def test_from_str(): - pass diff --git a/tests/test_computed_reaction.py b/tests/test_computed_reaction.py deleted file mode 100644 index 14b246f5..00000000 --- a/tests/test_computed_reaction.py +++ /dev/null @@ -1,2 +0,0 @@ -""" Tests for ComputedReaction. Some tests adapted from pymatgen. """ -import pytest diff --git a/tests/test_entry_set.py b/tests/test_entry_set.py deleted file mode 100644 index d901d358..00000000 --- a/tests/test_entry_set.py +++ /dev/null @@ -1,28 +0,0 @@ -""" Tests for GibbsEntrySet. """ -from pathlib import Path - -import pytest -from monty.serialization import loadfn -from pymatgen.analysis.phase_diagram import PhaseDiagram -from pytest import approx - -from rxn_network.entries.entry_set import GibbsEntrySet - -TEST_FILES_PATH = Path(__file__).parent / "test_files" - - -@pytest.fixture -def mp_entries(): - mp_entries = loadfn(TEST_FILES_PATH / "Mn-O_entries.json") - return mp_entries - - -@pytest.fixture -def gibbs_entries(mp_entries): - entries = GibbsEntrySet.from_entries(mp_entries, temperature=1000) - return entries - - -def test_from_pd(mp_entries): - entries = GibbsEntrySet.from_pd(PhaseDiagram(mp_entries), temperature=1000) - assert entries is not None diff --git a/tests/test_files/Cl-Mn-Na-O-Y_entries.json.gz b/tests/test_files/Cl-Mn-Na-O-Y_entries.json.gz new file mode 100644 index 00000000..6e282c3f Binary files /dev/null and b/tests/test_files/Cl-Mn-Na-O-Y_entries.json.gz differ diff --git a/tests/test_files/Fe-Li-O-P_entries.json.gz b/tests/test_files/Fe-Li-O-P_entries.json.gz new file mode 100644 index 00000000..6850a7a6 Binary files /dev/null and b/tests/test_files/Fe-Li-O-P_entries.json.gz differ diff --git a/tests/test_files/Mn-Na-O-Y_entries.json.gz b/tests/test_files/Mn-Na-O-Y_entries.json.gz new file mode 100644 index 00000000..7894f770 Binary files /dev/null and b/tests/test_files/Mn-Na-O-Y_entries.json.gz differ diff --git a/tests/test_files/Mn-O-Y_entries.json.gz b/tests/test_files/Mn-O-Y_entries.json.gz new file mode 100644 index 00000000..52ccd089 Binary files /dev/null and b/tests/test_files/Mn-O-Y_entries.json.gz differ diff --git a/tests/test_files/Mn-O_entries.json b/tests/test_files/Mn-O_entries.json deleted file mode 100644 index 0bf244ed..00000000 --- a/tests/test_files/Mn-O_entries.json +++ /dev/null @@ -1 +0,0 @@ -[{"@module": "pymatgen.entries.computed_entries", "@class": "ComputedStructureEntry", "energy": -31.42682858, "composition": {"Mn": 2.0, "O": 2.0}, "energy_adjustments": [{"@module": "pymatgen.entries.computed_entries", "@class": "ConstantEnergyAdjustment", "@version": "2020.8.3", "value": 0, "name": "MPRelaxSet Potcar Correction", "cls": {"@module": "pymatgen.entries.compatibility", "@class": "MaterialsProjectCompatibility", "@version": "2020.8.3", "compat_type": "Advanced", "correct_peroxide": true, "check_potcar_hash": false}, "description": "Constant energy adjustment (0.000 eV)"}, {"@module": "pymatgen.entries.computed_entries", "@class": "ConstantEnergyAdjustment", "@version": "2020.8.3", "value": 0, "name": "MP Gas Correction", "cls": {"@module": "pymatgen.entries.compatibility", "@class": "MaterialsProjectCompatibility", "@version": "2020.8.3", "compat_type": "Advanced", "correct_peroxide": true, "check_potcar_hash": false}, "description": "Constant energy adjustment (0.000 eV)"}, {"@module": "pymatgen.entries.computed_entries", "@class": "ConstantEnergyAdjustment", "@version": "2020.8.3", "value": -1.40458, "name": "MP Anion Correction", "cls": {"@module": "pymatgen.entries.compatibility", "@class": "MaterialsProjectCompatibility", "@version": "2020.8.3", "compat_type": "Advanced", "correct_peroxide": true, "check_potcar_hash": false}, "description": "Constant energy adjustment (-1.405 eV)"}, {"@module": "pymatgen.entries.computed_entries", "@class": "ConstantEnergyAdjustment", "@version": "2020.8.3", "value": -3.36170030192, "name": "MP Advanced Correction", "cls": {"@module": "pymatgen.entries.compatibility", "@class": "MaterialsProjectCompatibility", "@version": "2020.8.3", "compat_type": "Advanced", "correct_peroxide": true, "check_potcar_hash": false}, "description": "Constant energy adjustment (-3.362 eV)"}], "parameters": {"run_type": "GGA+U", "is_hubbard": true, "pseudo_potential": {"functional": "PBE", "labels": ["Mn_pv", "O"], "pot_type": "paw"}, "hubbards": {"Mn": 3.9, "O": 0.0}, "potcar_symbols": ["PBE Mn_pv", "PBE O"], "oxide_type": "oxide"}, "data": {"oxide_type": "oxide"}, "entry_id": "mp-19006", "correction": -4.76628030192, "structure": {"@module": "pymatgen.core.structure", "@class": "Structure", "charge": null, "lattice": {"matrix": [[2.768974, 5e-05, 1.598707], [0.923025, 2.610708, 1.59873], [-0.878246, -2.578988, 4.71854]], "a": 3.1973553269890105, "b": 3.1974535219122417, "c": 5.448588337565979, "alpha": 89.99985583138601, "beta": 72.93751790695626, "gamma": 59.998925238391344, "volume": 45.386638186518894}, "sites": [{"species": [{"element": "Mn", "occu": 1}], "abc": [0.0, 0.0, 0.0], "xyz": [0.0, 0.0, 0.0], "label": "Mn", "properties": {"magmom": 4.591}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.0, 0.5, 0.5], "xyz": [0.022389500000000007, 0.015859999999999985, 3.158635], "label": "Mn", "properties": {"magmom": -4.591}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.499999, 0.750001, 0.250001], "xyz": [1.8571915258050005, 1.3133090316699998, 3.178040718563], "label": "O", "properties": {"magmom": 0.0}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.500001, 0.249999, 0.749999], "xyz": [0.9565614741950001, -1.28153903167, 4.737936281436999], "label": "O", "properties": {"magmom": 0.0}}]}}, {"@module": "pymatgen.entries.computed_entries", "@class": "ComputedStructureEntry", "energy": -85.73370849, "composition": {"Mn": 4.0, "O": 8.0}, "energy_adjustments": [{"@module": "pymatgen.entries.computed_entries", "@class": "ConstantEnergyAdjustment", "@version": "2020.8.3", "value": 0, "name": "MPRelaxSet Potcar Correction", "cls": {"@module": "pymatgen.entries.compatibility", "@class": "MaterialsProjectCompatibility", "@version": "2020.8.3", "compat_type": "Advanced", "correct_peroxide": true, "check_potcar_hash": false}, "description": "Constant energy adjustment (0.000 eV)"}, {"@module": "pymatgen.entries.computed_entries", "@class": "ConstantEnergyAdjustment", "@version": "2020.8.3", "value": 0, "name": "MP Gas Correction", "cls": {"@module": "pymatgen.entries.compatibility", "@class": "MaterialsProjectCompatibility", "@version": "2020.8.3", "compat_type": "Advanced", "correct_peroxide": true, "check_potcar_hash": false}, "description": "Constant energy adjustment (0.000 eV)"}, {"@module": "pymatgen.entries.computed_entries", "@class": "ConstantEnergyAdjustment", "@version": "2020.8.3", "value": -5.61832, "name": "MP Anion Correction", "cls": {"@module": "pymatgen.entries.compatibility", "@class": "MaterialsProjectCompatibility", "@version": "2020.8.3", "compat_type": "Advanced", "correct_peroxide": true, "check_potcar_hash": false}, "description": "Constant energy adjustment (-5.618 eV)"}, {"@module": "pymatgen.entries.computed_entries", "@class": "ConstantEnergyAdjustment", "@version": "2020.8.3", "value": -6.72340060384, "name": "MP Advanced Correction", "cls": {"@module": "pymatgen.entries.compatibility", "@class": "MaterialsProjectCompatibility", "@version": "2020.8.3", "compat_type": "Advanced", "correct_peroxide": true, "check_potcar_hash": false}, "description": "Constant energy adjustment (-6.723 eV)"}], "parameters": {"run_type": "GGA+U", "is_hubbard": true, "pseudo_potential": {"functional": "PBE", "labels": ["Mn_pv", "O"], "pot_type": "paw"}, "hubbards": {"Mn": 3.9, "O": 0.0}, "potcar_symbols": ["PBE Mn_pv", "PBE O"], "oxide_type": "oxide"}, "data": {"oxide_type": "oxide"}, "entry_id": "mp-19395", "correction": -12.341720603839999, "structure": {"@module": "pymatgen.core.structure", "@class": "Structure", "charge": null, "lattice": {"matrix": [[2.865569, -0.000728, 0.587157], [1.430411, 7.014927, 0.296261], [0.022098, 0.002584, 7.16407]], "a": 2.9251050521979547, "b": 7.1654062707128485, "c": 7.164104547224308, "alpha": 87.57482286635624, "beta": 78.24361041871992, "gamma": 78.25127452159832, "volume": 143.92681011884497}, "sites": [{"species": [{"element": "Mn", "occu": 1}], "abc": [0.65172, 0.183104, 0.516697], "xyz": [2.1408805747299997, 1.2853218862959999, 4.138562010974], "label": "Mn", "properties": {"magmom": 3.201}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.16706, 0.48647, 0.183322], "xyz": [1.178625045866, 3.4129036220580002, 1.5555441776299999], "label": "Mn", "properties": {"magmom": 3.2}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.834099, 0.516327, 0.819773], "xyz": [3.1468434014819997, 3.623507282489, 6.515625776], "label": "Mn", "properties": {"magmom": 3.202}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.34942, 0.819682, 0.486093], "xyz": [2.1845109523960002, 5.751011079766, 3.930408486452], "label": "Mn", "properties": {"magmom": 3.201}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.836051, 0.709259, 0.623567], "xyz": [3.4240732870339996, 4.976402761093, 5.168296615296], "label": "O", "properties": {"magmom": -0.054}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.457531, 0.378522, 0.710109], "xyz": [1.868220671363, 2.6568060369820006, 5.4680544192389995], "label": "O", "properties": {"magmom": -0.055}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.543632, 0.623959, 0.293333], "xyz": [2.4568148963909997, 4.377389044369, 2.6055101968330003], "label": "O", "properties": {"magmom": -0.054}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.164293, 0.29433, 0.380077], "xyz": [0.9002047388929999, 2.065565977574, 2.906562518521], "label": "O", "properties": {"magmom": -0.052}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.156647, 0.049469, 0.64082], "xyz": [0.533804629262, 0.348563263627, 4.697511455388], "label": "O", "properties": {"magmom": -0.177}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.795471, 0.361934, 0.050233], "xyz": [2.798301461707, 2.538491288002, 0.934166023031], "label": "O", "properties": {"magmom": -0.177}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.844601, 0.953264, 0.361624], "xyz": [3.791812921625, 6.687396938616, 3.369027984941], "label": "O", "properties": {"magmom": -0.177}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.205655, 0.640841, 0.953012], "xyz": [1.527044267522, 4.497765699774999, 7.138052647175999], "label": "O", "properties": {"magmom": -0.177}}]}}, {"@module": "pymatgen.entries.computed_entries", "@class": "ComputedStructureEntry", "energy": -107.75750916, "composition": {"Mn": 6.0, "O": 8.0}, "energy_adjustments": [{"@module": "pymatgen.entries.computed_entries", "@class": "ConstantEnergyAdjustment", "@version": "2020.8.3", "value": 0, "name": "MPRelaxSet Potcar Correction", "cls": {"@module": "pymatgen.entries.compatibility", "@class": "MaterialsProjectCompatibility", "@version": "2020.8.3", "compat_type": "Advanced", "correct_peroxide": true, "check_potcar_hash": false}, "description": "Constant energy adjustment (0.000 eV)"}, {"@module": "pymatgen.entries.computed_entries", "@class": "ConstantEnergyAdjustment", "@version": "2020.8.3", "value": 0, "name": "MP Gas Correction", "cls": {"@module": "pymatgen.entries.compatibility", "@class": "MaterialsProjectCompatibility", "@version": "2020.8.3", "compat_type": "Advanced", "correct_peroxide": true, "check_potcar_hash": false}, "description": "Constant energy adjustment (0.000 eV)"}, {"@module": "pymatgen.entries.computed_entries", "@class": "ConstantEnergyAdjustment", "@version": "2020.8.3", "value": -5.61832, "name": "MP Anion Correction", "cls": {"@module": "pymatgen.entries.compatibility", "@class": "MaterialsProjectCompatibility", "@version": "2020.8.3", "compat_type": "Advanced", "correct_peroxide": true, "check_potcar_hash": false}, "description": "Constant energy adjustment (-5.618 eV)"}, {"@module": "pymatgen.entries.computed_entries", "@class": "ConstantEnergyAdjustment", "@version": "2020.8.3", "value": -10.085100905760001, "name": "MP Advanced Correction", "cls": {"@module": "pymatgen.entries.compatibility", "@class": "MaterialsProjectCompatibility", "@version": "2020.8.3", "compat_type": "Advanced", "correct_peroxide": true, "check_potcar_hash": false}, "description": "Constant energy adjustment (-10.085 eV)"}], "parameters": {"run_type": "GGA+U", "is_hubbard": true, "pseudo_potential": {"functional": "PBE", "labels": ["Mn_pv", "O"], "pot_type": "paw"}, "hubbards": {"Mn": 3.9, "O": 0.0}, "potcar_symbols": ["PBE Mn_pv", "PBE O"], "oxide_type": "oxide"}, "data": {"oxide_type": "oxide"}, "entry_id": "mp-18759", "correction": -15.703420905760002, "structure": {"@module": "pymatgen.core.structure", "@class": "Structure", "charge": null, "lattice": {"matrix": [[-1.411225, 5.010316, -2.713619], [-0.005231, -0.015119, 6.348054], [5.212233, 0.001971, -2.707051]], "a": 5.870140585849883, "b": 6.3480741594942005, "c": 5.87328714160401, "alpha": 117.49296084548875, "beta": 89.99975596506606, "gamma": 117.6525217154401, "volume": 165.45414815955115}, "sites": [{"species": [{"element": "Mn", "occu": 1}], "abc": [0.374136, 0.249108, 0.623737], "xyz": [2.721769414173, 1.8720027087510003, -1.1223993919389998], "label": "Mn", "properties": {"magmom": -4.567}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.625867, 0.750903, 0.376265], "xyz": [1.0740137190770005, 3.12518015983, 2.0498396655740008], "label": "Mn", "properties": {"magmom": -4.567}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.499997, 0.999997, 0.999996], "xyz": [4.501372900436, 2.4919950065250003, 2.2841934248990006], "label": "Mn", "properties": {"magmom": -3.927}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [4e-06, 0.499999, 1e-06], "xyz": [-0.002615927436, -0.007539441646, 3.1740070904190008], "label": "Mn", "properties": {"magmom": 3.823}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.999997, 0.999997, 0.999999], "xyz": [3.7957760371350004, 4.997153012438, 0.9273758037460005], "label": "Mn", "properties": {"magmom": 3.806}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [5e-06, 0.500006, 0.500001], "xyz": [2.6034991247220005, -0.0065490371629999995, 1.8205233131779999], "label": "Mn", "properties": {"magmom": 3.825}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.786014, 0.516723, 0.758504], "xyz": [2.8415539942690002, 3.9318611967710004, -0.9060660293279992], "label": "O", "properties": {"magmom": -0.017}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.24077, 0.983639, 0.213991], "xyz": [0.770444893044, 1.19188392154, 5.011550891335], "label": "O", "properties": {"magmom": 0.024}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.759146, 0.016228, 0.230767], "xyz": [0.13140067019300017, 3.8037708407610005, -2.581714827179], "label": "O", "properties": {"magmom": 0.024}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.759229, 0.016358, 0.786008], "xyz": [3.025328321641, 3.805279111530001, -4.084180514827], "label": "O", "properties": {"magmom": 0.024}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.771278, 0.484118, 0.241929], "xyz": [0.17001110064900016, 3.8575039658650003, 0.3253384299109999], "label": "O", "properties": {"magmom": -0.084}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.213985, 0.483274, 0.241496], "xyz": [0.9542244326490001, 1.06530183827, 1.8334336987850004], "label": "O", "properties": {"magmom": -0.017}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.22872, 0.51588, 0.758071], "xyz": [3.6257687322630003, 1.139654043741, 0.6020383012190003], "label": "O", "properties": {"magmom": -0.084}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.240853, 0.983771, 0.769233], "xyz": [3.664377746263, 1.1933921640420002, 3.509095192744], "label": "O", "properties": {"magmom": 0.024}}]}}, {"@module": "pymatgen.entries.computed_entries", "@class": "ComputedStructureEntry", "energy": -265.68948764, "composition": {"Mn": 29.0}, "energy_adjustments": [{"@module": "pymatgen.entries.computed_entries", "@class": "ConstantEnergyAdjustment", "@version": "2020.8.3", "value": 0, "name": "MPRelaxSet Potcar Correction", "cls": {"@module": "pymatgen.entries.compatibility", "@class": "MaterialsProjectCompatibility", "@version": "2020.8.3", "compat_type": "Advanced", "correct_peroxide": true, "check_potcar_hash": false}, "description": "Constant energy adjustment (0.000 eV)"}, {"@module": "pymatgen.entries.computed_entries", "@class": "ConstantEnergyAdjustment", "@version": "2020.8.3", "value": 0, "name": "MP Gas Correction", "cls": {"@module": "pymatgen.entries.compatibility", "@class": "MaterialsProjectCompatibility", "@version": "2020.8.3", "compat_type": "Advanced", "correct_peroxide": true, "check_potcar_hash": false}, "description": "Constant energy adjustment (0.000 eV)"}, {"@module": "pymatgen.entries.computed_entries", "@class": "ConstantEnergyAdjustment", "@version": "2020.8.3", "value": 0, "name": "MP Anion Correction", "cls": {"@module": "pymatgen.entries.compatibility", "@class": "MaterialsProjectCompatibility", "@version": "2020.8.3", "compat_type": "Advanced", "correct_peroxide": true, "check_potcar_hash": false}, "description": "Constant energy adjustment (0.000 eV)"}, {"@module": "pymatgen.entries.computed_entries", "@class": "ConstantEnergyAdjustment", "@version": "2020.8.3", "value": 0, "name": "MP Advanced Correction", "cls": {"@module": "pymatgen.entries.compatibility", "@class": "MaterialsProjectCompatibility", "@version": "2020.8.3", "compat_type": "Advanced", "correct_peroxide": true, "check_potcar_hash": false}, "description": "Constant energy adjustment (0.000 eV)"}], "parameters": {"run_type": "GGA", "is_hubbard": false, "pseudo_potential": {"functional": "PBE", "labels": ["Mn_pv"], "pot_type": "paw"}, "hubbards": {}, "potcar_symbols": ["PBE Mn_pv"], "oxide_type": "None"}, "data": {"oxide_type": "None"}, "entry_id": "mp-35", "correction": 0, "structure": {"@module": "pymatgen.core.structure", "@class": "Structure", "charge": null, "lattice": {"matrix": [[-4.309249, 4.309249, 4.309249], [4.309249, -4.309249, 4.309249], [4.309249, 4.309249, -4.309249]], "a": 7.4638382104653775, "b": 7.4638382104653775, "c": 7.4638382104653775, "alpha": 109.47122063449069, "beta": 109.47122063449069, "gamma": 109.47122063449069, "volume": 320.0845853552375}, "sites": [{"species": [{"element": "Mn", "occu": 1}], "abc": [0.0, 0.0, 0.0], "xyz": [0.0, 0.0, 0.0], "label": "Mn", "properties": {"magmom": 0.767}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.637573, 0.637573, 0.637573], "xyz": [2.747460812677, 2.747460812677, 2.747460812677], "label": "Mn", "properties": {"magmom": 2.176}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.0, 0.0, 0.362427], "xyz": [1.5617881873230002, 1.5617881873230002, -1.5617881873230002], "label": "Mn", "properties": {"magmom": 2.161}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.362427, 0.0, 0.0], "xyz": [-1.5617881873230002, 1.5617881873230002, 1.5617881873230002], "label": "Mn", "properties": {"magmom": 2.177}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.0, 0.362427, 0.0], "xyz": [1.5617881873230002, -1.5617881873230002, 1.5617881873230002], "label": "Mn", "properties": {"magmom": 2.174}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.391672, 0.712408, 0.391672], "xyz": [3.0699434615920005, 0.30568088706399976, 3.0699434615920005], "label": "Mn", "properties": {"magmom": -0.488}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.320736, 0.0, 0.608328], "xyz": [1.239305538408, 4.003568112936001, -1.239305538408], "label": "Mn", "properties": {"magmom": -0.472}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.608328, 0.0, 0.320736], "xyz": [-1.239305538408, 4.003568112936001, 1.239305538408], "label": "Mn", "properties": {"magmom": -0.504}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.320736, 0.608328, 0.0], "xyz": [1.239305538408, -1.239305538408, 4.003568112936001], "label": "Mn", "properties": {"magmom": -0.482}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.679264, 0.679264, 0.287592], "xyz": [1.239305538408, 1.239305538408, 4.614929887064], "label": "Mn", "properties": {"magmom": -0.475}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.287592, 0.679264, 0.679264], "xyz": [4.614929887064, 1.239305538408, 1.2393055384079998], "label": "Mn", "properties": {"magmom": -0.485}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.0, 0.608328, 0.320736], "xyz": [4.003568112936001, -1.239305538408, 1.239305538408], "label": "Mn", "properties": {"magmom": -0.485}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.0, 0.320736, 0.608328], "xyz": [4.003568112936001, 1.239305538408, -1.239305538408], "label": "Mn", "properties": {"magmom": -0.464}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.608328, 0.320736, 0.0], "xyz": [-1.239305538408, 1.239305538408, 4.003568112936001], "label": "Mn", "properties": {"magmom": -0.492}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.391672, 0.391672, 0.712408], "xyz": [3.0699434615920005, 3.0699434615920005, 0.30568088706399976], "label": "Mn", "properties": {"magmom": -0.499}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.712408, 0.391672, 0.391672], "xyz": [0.30568088706399976, 3.0699434615920005, 3.0699434615920005], "label": "Mn", "properties": {"magmom": -0.477}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.679264, 0.287592, 0.679264], "xyz": [1.239305538408, 4.614929887064, 1.2393055384079998], "label": "Mn", "properties": {"magmom": -0.484}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.371604, 0.178119, 0.371604], "xyz": [0.767559122631, 2.435109208161, 0.7675591226309999], "label": "Mn", "properties": {"magmom": 0.123}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.806515, 0.0, 0.628396], "xyz": [-0.7675591226310003, 6.1833887918390005, 0.7675591226310003], "label": "Mn", "properties": {"magmom": 0.135}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.628396, 0.0, 0.806515], "xyz": [0.7675591226310003, 6.1833887918390005, -0.7675591226310003], "label": "Mn", "properties": {"magmom": 0.127}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.806515, 0.628396, 0.0], "xyz": [-0.7675591226310003, 0.7675591226310003, 6.1833887918390005], "label": "Mn", "properties": {"magmom": 0.122}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.193485, 0.193485, 0.821881], "xyz": [3.541689877369, 3.541689877369, -1.874139791839], "label": "Mn", "properties": {"magmom": 0.136}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.821881, 0.193485, 0.193485], "xyz": [-1.8741397918389997, 3.541689877369, 3.541689877369], "label": "Mn", "properties": {"magmom": 0.142}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.0, 0.628396, 0.806515], "xyz": [6.1833887918390005, 0.7675591226310003, -0.7675591226310003], "label": "Mn", "properties": {"magmom": 0.149}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.0, 0.806515, 0.628396], "xyz": [6.1833887918390005, -0.7675591226310003, 0.7675591226310003], "label": "Mn", "properties": {"magmom": 0.147}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.628396, 0.806515, 0.0], "xyz": [0.7675591226310003, -0.7675591226310003, 6.1833887918390005], "label": "Mn", "properties": {"magmom": 0.111}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.371604, 0.371604, 0.178119], "xyz": [0.767559122631, 0.767559122631, 2.435109208161], "label": "Mn", "properties": {"magmom": 0.11}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.178119, 0.371604, 0.371604], "xyz": [2.435109208161, 0.767559122631, 0.7675591226309999], "label": "Mn", "properties": {"magmom": 0.144}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.193485, 0.821881, 0.193485], "xyz": [3.541689877369, -1.8741397918389997, 3.541689877369], "label": "Mn", "properties": {"magmom": 0.132}}]}}, {"@module": "pymatgen.entries.computed_entries", "@class": "ComputedStructureEntry", "energy": -39.58364375, "composition": {"O": 8.0}, "energy_adjustments": [{"@module": "pymatgen.entries.computed_entries", "@class": "ConstantEnergyAdjustment", "@version": "2020.8.3", "value": 0, "name": "MPRelaxSet Potcar Correction", "cls": {"@module": "pymatgen.entries.compatibility", "@class": "MaterialsProjectCompatibility", "@version": "2020.8.3", "compat_type": "Advanced", "correct_peroxide": true, "check_potcar_hash": false}, "description": "Constant energy adjustment (0.000 eV)"}, {"@module": "pymatgen.entries.computed_entries", "@class": "ConstantEnergyAdjustment", "@version": "2020.8.3", "value": 0, "name": "MP Gas Correction", "cls": {"@module": "pymatgen.entries.compatibility", "@class": "MaterialsProjectCompatibility", "@version": "2020.8.3", "compat_type": "Advanced", "correct_peroxide": true, "check_potcar_hash": false}, "description": "Constant energy adjustment (0.000 eV)"}, {"@module": "pymatgen.entries.computed_entries", "@class": "ConstantEnergyAdjustment", "@version": "2020.8.3", "value": 0, "name": "MP Anion Correction", "cls": {"@module": "pymatgen.entries.compatibility", "@class": "MaterialsProjectCompatibility", "@version": "2020.8.3", "compat_type": "Advanced", "correct_peroxide": true, "check_potcar_hash": false}, "description": "Constant energy adjustment (0.000 eV)"}, {"@module": "pymatgen.entries.computed_entries", "@class": "ConstantEnergyAdjustment", "@version": "2020.8.3", "value": 0, "name": "MP Advanced Correction", "cls": {"@module": "pymatgen.entries.compatibility", "@class": "MaterialsProjectCompatibility", "@version": "2020.8.3", "compat_type": "Advanced", "correct_peroxide": true, "check_potcar_hash": false}, "description": "Constant energy adjustment (0.000 eV)"}], "parameters": {"run_type": "GGA", "is_hubbard": false, "pseudo_potential": {"functional": "PBE", "labels": ["O"], "pot_type": "paw"}, "hubbards": {}, "potcar_symbols": ["PBE O"], "oxide_type": "None"}, "data": {"oxide_type": "None"}, "entry_id": "mp-12957", "correction": 0, "structure": {"@module": "pymatgen.core.structure", "@class": "Structure", "charge": null, "lattice": {"matrix": [[3.110107, 4.377428, 0.0], [-3.110107, 4.377428, 0.0], [0.0, 1.908312, 3.953345]], "a": 5.369789702272613, "b": 5.369789702272613, "c": 4.389828171850124, "alpha": 69.2448296788145, "beta": 69.2448296788145, "gamma": 70.78662063844565, "volume": 107.6438082346079}, "sites": [{"species": [{"element": "O", "occu": 1}], "abc": [0.726541, 0.213911, 0.155391], "xyz": [1.59433415141, 4.413295427448, 0.614314232895], "label": "O", "properties": {"magmom": 0.0}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.786089, 0.273459, 0.844609], "xyz": [1.59433415141, 6.249872572552, 3.339030767105], "label": "O", "properties": {"magmom": 0.0}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.273459, 0.786089, 0.844609], "xyz": [-1.59433415141, 6.249872572552, 3.339030767105], "label": "O", "properties": {"magmom": 0.0}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.213911, 0.726541, 0.155391], "xyz": [-1.59433415141, 4.413295427448, 0.614314232895], "label": "O", "properties": {"magmom": 0.0}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.792252, 0.792252, 0.17832], "xyz": [0.0, 7.2763423715519995, 0.7049604804], "label": "O", "properties": {"magmom": -0.0}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.207748, 0.207748, 0.82168], "xyz": [0.0, 3.3868256284480003, 3.2483845196], "label": "O", "properties": {"magmom": -0.0}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.851778, 0.851778, 0.867359], "xyz": [0.0, 9.112385321976, 3.428969365855], "label": "O", "properties": {"magmom": -0.0}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.148222, 0.148222, 0.132641], "xyz": [0.0, 1.550782678024, 0.5243756341450001], "label": "O", "properties": {"magmom": -0.0}}]}}, {"@module": "pymatgen.entries.computed_entries", "@class": "ComputedStructureEntry", "energy": -605.44549615, "composition": {"Mn": 32.0, "O": 48.0}, "energy_adjustments": [{"@module": "pymatgen.entries.computed_entries", "@class": "ConstantEnergyAdjustment", "@version": "2020.8.3", "value": 0, "name": "MPRelaxSet Potcar Correction", "cls": {"@module": "pymatgen.entries.compatibility", "@class": "MaterialsProjectCompatibility", "@version": "2020.8.3", "compat_type": "Advanced", "correct_peroxide": true, "check_potcar_hash": false}, "description": "Constant energy adjustment (0.000 eV)"}, {"@module": "pymatgen.entries.computed_entries", "@class": "ConstantEnergyAdjustment", "@version": "2020.8.3", "value": 0, "name": "MP Gas Correction", "cls": {"@module": "pymatgen.entries.compatibility", "@class": "MaterialsProjectCompatibility", "@version": "2020.8.3", "compat_type": "Advanced", "correct_peroxide": true, "check_potcar_hash": false}, "description": "Constant energy adjustment (0.000 eV)"}, {"@module": "pymatgen.entries.computed_entries", "@class": "ConstantEnergyAdjustment", "@version": "2020.8.3", "value": -33.70992, "name": "MP Anion Correction", "cls": {"@module": "pymatgen.entries.compatibility", "@class": "MaterialsProjectCompatibility", "@version": "2020.8.3", "compat_type": "Advanced", "correct_peroxide": true, "check_potcar_hash": false}, "description": "Constant energy adjustment (-33.710 eV)"}, {"@module": "pymatgen.entries.computed_entries", "@class": "ConstantEnergyAdjustment", "@version": "2020.8.3", "value": -53.78720483072, "name": "MP Advanced Correction", "cls": {"@module": "pymatgen.entries.compatibility", "@class": "MaterialsProjectCompatibility", "@version": "2020.8.3", "compat_type": "Advanced", "correct_peroxide": true, "check_potcar_hash": false}, "description": "Constant energy adjustment (-53.787 eV)"}], "parameters": {"run_type": "GGA+U", "is_hubbard": true, "pseudo_potential": {"functional": "PBE", "labels": ["Mn_pv", "O"], "pot_type": "paw"}, "hubbards": {"Mn": 3.9, "O": 0.0}, "potcar_symbols": ["PBE Mn_pv", "PBE O"], "oxide_type": "oxide"}, "data": {"oxide_type": "oxide"}, "entry_id": "mp-1172875", "correction": -87.49712483072, "structure": {"@module": "pymatgen.core.structure", "@class": "Structure", "charge": null, "lattice": {"matrix": [[9.580269, 0.0, 0.0], [0.0, 9.608742, 0.0], [0.0, 0.0, 9.658434]], "a": 9.580269, "b": 9.608742, "c": 9.658434, "alpha": 90.0, "beta": 90.0, "gamma": 90.0, "volume": 889.1007007723838}, "sites": [{"species": [{"element": "Mn", "occu": 1}], "abc": [0.5, 0.5, 0.0], "xyz": [4.7901345, 4.804371, 0.0], "label": "Mn", "properties": {"magmom": 3.954}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.5, 0.0, 0.5], "xyz": [4.7901345, 0.0, 4.829217], "label": "Mn", "properties": {"magmom": 3.947}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.0, 0.5, 0.5], "xyz": [0.0, 4.804371, 4.829217], "label": "Mn", "properties": {"magmom": 3.95}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.0, 0.0, 0.0], "xyz": [0.0, 0.0, 0.0], "label": "Mn", "properties": {"magmom": 3.95}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.0, 0.0, 0.5], "xyz": [0.0, 0.0, 4.829217], "label": "Mn", "properties": {"magmom": 3.958}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.0, 0.5, 0.0], "xyz": [0.0, 4.804371, 0.0], "label": "Mn", "properties": {"magmom": 3.961}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.5, 0.0, 0.0], "xyz": [4.7901345, 0.0, 0.0], "label": "Mn", "properties": {"magmom": 3.958}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.5, 0.5, 0.5], "xyz": [4.7901345, 4.804371, 4.829217], "label": "Mn", "properties": {"magmom": 3.96}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.509136, 0.758839, 0.285941], "xyz": [4.877659837584, 7.291488170538, 2.761742276394], "label": "Mn", "properties": {"magmom": 3.994}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.490864, 0.258839, 0.214059], "xyz": [4.702609162416, 2.4871171705379997, 2.067474723606], "label": "Mn", "properties": {"magmom": 3.994}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.990864, 0.241161, 0.785941], "xyz": [9.492743662415998, 2.3172538294619995, 7.590959276394], "label": "Mn", "properties": {"magmom": 3.994}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.009136, 0.741161, 0.714059], "xyz": [0.087525337584, 7.121624829461999, 6.896691723606], "label": "Mn", "properties": {"magmom": 3.995}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.490864, 0.241161, 0.714059], "xyz": [4.702609162416, 2.3172538294619995, 6.896691723606], "label": "Mn", "properties": {"magmom": 3.994}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.509136, 0.741161, 0.785941], "xyz": [4.877659837584, 7.121624829461999, 7.590959276394], "label": "Mn", "properties": {"magmom": 3.994}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.009136, 0.758839, 0.214059], "xyz": [0.087525337584, 7.291488170538, 2.067474723606], "label": "Mn", "properties": {"magmom": 3.994}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.990864, 0.258839, 0.285941], "xyz": [9.492743662415998, 2.4871171705379997, 2.761742276394], "label": "Mn", "properties": {"magmom": 3.995}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.256414, 0.787943, 0.999876], "xyz": [2.4565150953659995, 7.571140997705999, 9.657236354184], "label": "Mn", "properties": {"magmom": 3.983}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.743586, 0.287943, 0.500124], "xyz": [7.1237539046339995, 2.766769997706, 4.830414645816], "label": "Mn", "properties": {"magmom": 3.983}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.243586, 0.212057, 0.499876], "xyz": [2.3336194046339997, 2.0376010022939997, 4.828019354184], "label": "Mn", "properties": {"magmom": 3.983}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.756414, 0.712057, 0.000124], "xyz": [7.246649595366, 6.841972002294, 0.001197645816], "label": "Mn", "properties": {"magmom": 3.983}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.743586, 0.212057, 0.000124], "xyz": [7.1237539046339995, 2.0376010022939997, 0.001197645816], "label": "Mn", "properties": {"magmom": 3.983}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.256414, 0.712057, 0.499876], "xyz": [2.4565150953659995, 6.841972002294, 4.828019354184], "label": "Mn", "properties": {"magmom": 3.983}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.756414, 0.787943, 0.500124], "xyz": [7.246649595366, 7.571140997705999, 4.830414645816], "label": "Mn", "properties": {"magmom": 3.983}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.243586, 0.287943, 0.999876], "xyz": [2.3336194046339997, 2.766769997706, 9.657236354184], "label": "Mn", "properties": {"magmom": 3.983}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.215751, 0.511796, 0.246639], "xyz": [2.066952617019, 4.917715720632, 2.382146503326], "label": "Mn", "properties": {"magmom": 3.993}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.784249, 0.011796, 0.253361], "xyz": [7.5133163829809995, 0.11334472063199999, 2.447070496674], "label": "Mn", "properties": {"magmom": 3.993}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.284249, 0.488204, 0.746639], "xyz": [2.7231818829809997, 4.691026279368, 7.211363503326], "label": "Mn", "properties": {"magmom": 3.993}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.715751, 0.988204, 0.753361], "xyz": [6.857087117019, 9.495397279368, 7.276287496674], "label": "Mn", "properties": {"magmom": 3.993}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.784249, 0.488204, 0.753361], "xyz": [7.5133163829809995, 4.691026279368, 7.276287496674], "label": "Mn", "properties": {"magmom": 3.993}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.215751, 0.988204, 0.746639], "xyz": [2.066952617019, 9.495397279368, 7.211363503326], "label": "Mn", "properties": {"magmom": 3.993}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.715751, 0.511796, 0.253361], "xyz": [6.857087117019, 4.917715720632, 2.447070496674], "label": "Mn", "properties": {"magmom": 3.993}}, {"species": [{"element": "Mn", "occu": 1}], "abc": [0.284249, 0.011796, 0.246639], "xyz": [2.7231818829809997, 0.11334472063199999, 2.382146503326], "label": "Mn", "properties": {"magmom": 3.993}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.148653, 0.92325, 0.125336], "xyz": [1.424135727657, 8.871271051499999, 1.210549483824], "label": "O", "properties": {"magmom": -0.066}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.851347, 0.42325, 0.374664], "xyz": [8.156133272342998, 4.0669000515, 3.618667516176], "label": "O", "properties": {"magmom": -0.066}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.351347, 0.07675, 0.625336], "xyz": [3.365998772343, 0.7374709485, 6.039766483824], "label": "O", "properties": {"magmom": -0.066}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.648653, 0.57675, 0.874664], "xyz": [6.214270227657, 5.541841948499999, 8.447884516176], "label": "O", "properties": {"magmom": -0.067}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.851347, 0.07675, 0.874664], "xyz": [8.156133272342998, 0.7374709485, 8.447884516176], "label": "O", "properties": {"magmom": -0.066}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.148653, 0.57675, 0.625336], "xyz": [1.424135727657, 5.541841948499999, 6.039766483824], "label": "O", "properties": {"magmom": -0.066}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.648653, 0.92325, 0.374664], "xyz": [6.214270227657, 8.871271051499999, 3.618667516176], "label": "O", "properties": {"magmom": -0.066}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.351347, 0.42325, 0.125336], "xyz": [3.365998772343, 4.0669000515, 1.210549483824], "label": "O", "properties": {"magmom": -0.067}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.093362, 0.639767, 0.352725], "xyz": [0.8944330743779999, 6.147356043114, 3.40677113265], "label": "O", "properties": {"magmom": -0.046}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.906638, 0.139767, 0.147275], "xyz": [8.685835925622, 1.342985043114, 1.4224458673499998], "label": "O", "properties": {"magmom": -0.046}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.406638, 0.360233, 0.852725], "xyz": [3.8957014256219997, 3.461385956886, 8.23598813265], "label": "O", "properties": {"magmom": -0.046}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.593362, 0.860233, 0.647275], "xyz": [5.684567574377999, 8.265756956886, 6.25166286735], "label": "O", "properties": {"magmom": -0.047}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.906638, 0.360233, 0.647275], "xyz": [8.685835925622, 3.461385956886, 6.25166286735], "label": "O", "properties": {"magmom": -0.046}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.093362, 0.860233, 0.852725], "xyz": [0.8944330743779999, 8.265756956886, 8.23598813265], "label": "O", "properties": {"magmom": -0.046}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.593362, 0.639767, 0.147275], "xyz": [5.684567574377999, 6.147356043114, 1.4224458673499998], "label": "O", "properties": {"magmom": -0.046}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.406638, 0.139767, 0.352725], "xyz": [3.8957014256219997, 1.342985043114, 3.40677113265], "label": "O", "properties": {"magmom": -0.047}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.377278, 0.8579, 0.416654], "xyz": [3.6144247277819996, 8.2433397618, 4.024225159836], "label": "O", "properties": {"magmom": -0.083}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.622722, 0.3579, 0.083346], "xyz": [5.965844272218, 3.4389687617999996, 0.804991840164], "label": "O", "properties": {"magmom": -0.082}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.122722, 0.1421, 0.916654], "xyz": [1.1757097722179999, 1.3654022382, 8.853442159836], "label": "O", "properties": {"magmom": -0.082}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.877278, 0.6421, 0.583346], "xyz": [8.404559227782, 6.1697732381999995, 5.634208840164], "label": "O", "properties": {"magmom": -0.082}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.622722, 0.1421, 0.583346], "xyz": [5.965844272218, 1.3654022382, 5.634208840164], "label": "O", "properties": {"magmom": -0.083}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.377278, 0.6421, 0.916654], "xyz": [3.6144247277819996, 6.1697732381999995, 8.853442159836], "label": "O", "properties": {"magmom": -0.082}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.877278, 0.8579, 0.083346], "xyz": [8.404559227782, 8.2433397618, 0.804991840164], "label": "O", "properties": {"magmom": -0.082}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.122722, 0.3579, 0.416654], "xyz": [1.1757097722179999, 3.4389687617999996, 4.024225159836], "label": "O", "properties": {"magmom": -0.082}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.361212, 0.58585, 0.372296], "xyz": [3.4605081260279995, 5.629281500699999, 3.595796344464], "label": "O", "properties": {"magmom": -0.074}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.638788, 0.08585, 0.127704], "xyz": [6.119760873972, 0.8249105006999999, 1.233420655536], "label": "O", "properties": {"magmom": -0.075}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.138788, 0.41415, 0.872296], "xyz": [1.3296263739719998, 3.9794604993, 8.425013344463999], "label": "O", "properties": {"magmom": -0.074}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.861212, 0.91415, 0.627704], "xyz": [8.250642626028, 8.7838314993, 6.062637655536], "label": "O", "properties": {"magmom": -0.074}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.638788, 0.41415, 0.627704], "xyz": [6.119760873972, 3.9794604993, 6.062637655536], "label": "O", "properties": {"magmom": -0.074}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.361212, 0.91415, 0.872296], "xyz": [3.4605081260279995, 8.7838314993, 8.425013344463999], "label": "O", "properties": {"magmom": -0.075}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.861212, 0.58585, 0.127704], "xyz": [8.250642626028, 5.629281500699999, 1.233420655536], "label": "O", "properties": {"magmom": -0.074}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.138788, 0.08585, 0.372296], "xyz": [1.3296263739719998, 0.8249105006999999, 3.595796344464], "label": "O", "properties": {"magmom": -0.074}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.41963, 0.878812, 0.146192], "xyz": [4.02016828047, 8.444277774504, 1.4119857833279998], "label": "O", "properties": {"magmom": -0.068}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.58037, 0.378812, 0.353808], "xyz": [5.56010071953, 3.6399067745039995, 3.417231216672], "label": "O", "properties": {"magmom": -0.068}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.08037, 0.121188, 0.646192], "xyz": [0.7699662195299999, 1.164464225496, 6.241202783328], "label": "O", "properties": {"magmom": -0.069}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.91963, 0.621188, 0.853808], "xyz": [8.81030278047, 5.968835225495999, 8.246448216672], "label": "O", "properties": {"magmom": -0.068}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.58037, 0.121188, 0.853808], "xyz": [5.56010071953, 1.164464225496, 8.246448216672], "label": "O", "properties": {"magmom": -0.068}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.41963, 0.621188, 0.646192], "xyz": [4.02016828047, 5.968835225495999, 6.241202783328], "label": "O", "properties": {"magmom": -0.068}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.91963, 0.878812, 0.353808], "xyz": [8.81030278047, 8.444277774504, 3.417231216672], "label": "O", "properties": {"magmom": -0.069}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.08037, 0.378812, 0.146192], "xyz": [0.7699662195299999, 3.6399067745039995, 1.4119857833279998], "label": "O", "properties": {"magmom": -0.068}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.138498, 0.653634, 0.088196], "xyz": [1.326848095962, 6.280600468428, 0.851835245064], "label": "O", "properties": {"magmom": -0.039}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.861502, 0.153634, 0.411804], "xyz": [8.253420904038, 1.4762294684279997, 3.9773817549359998], "label": "O", "properties": {"magmom": -0.039}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.361502, 0.346366, 0.588196], "xyz": [3.4632864040379996, 3.3281415315719998, 5.681052245064], "label": "O", "properties": {"magmom": -0.038}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.638498, 0.846366, 0.911804], "xyz": [6.116982595962, 8.132512531571999, 8.806598754936], "label": "O", "properties": {"magmom": -0.039}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.861502, 0.346366, 0.911804], "xyz": [8.253420904038, 3.3281415315719998, 8.806598754936], "label": "O", "properties": {"magmom": -0.039}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.138498, 0.846366, 0.588196], "xyz": [1.326848095962, 8.132512531571999, 5.681052245064], "label": "O", "properties": {"magmom": -0.039}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.638498, 0.653634, 0.411804], "xyz": [6.116982595962, 6.280600468428, 3.9773817549359998], "label": "O", "properties": {"magmom": -0.038}}, {"species": [{"element": "O", "occu": 1}], "abc": [0.361502, 0.153634, 0.088196], "xyz": [3.4632864040379996, 1.4762294684279997, 0.851835245064], "label": "O", "properties": {"magmom": -0.039}}]}}] diff --git a/tests/test_files/Mn-O_entries.json.gz b/tests/test_files/Mn-O_entries.json.gz new file mode 100644 index 00000000..73e2c8a3 Binary files /dev/null and b/tests/test_files/Mn-O_entries.json.gz differ diff --git a/tests/test_files/comp_matrices.npy b/tests/test_files/comp_matrices.npy new file mode 100644 index 00000000..dd1f5b91 Binary files /dev/null and b/tests/test_files/comp_matrices.npy differ diff --git a/tests/test_files/computed_rxn.json.gz b/tests/test_files/computed_rxn.json.gz new file mode 100644 index 00000000..1a1ecda3 Binary files /dev/null and b/tests/test_files/computed_rxn.json.gz differ diff --git a/tests/test_files/ymno3_rxns.json.gz b/tests/test_files/ymno3_rxns.json.gz new file mode 100644 index 00000000..2a04d550 Binary files /dev/null and b/tests/test_files/ymno3_rxns.json.gz differ diff --git a/tests/test_files/yocl-namno2_rxn_entries.json.gz b/tests/test_files/yocl-namno2_rxn_entries.json.gz new file mode 100644 index 00000000..dd1a8c99 Binary files /dev/null and b/tests/test_files/yocl-namno2_rxn_entries.json.gz differ diff --git a/tests/test_nist_entry.py b/tests/test_nist_entry.py deleted file mode 100644 index 5872c887..00000000 --- a/tests/test_nist_entry.py +++ /dev/null @@ -1,2 +0,0 @@ -""" Tests for GibbsComputedEntry. """ -import pytest diff --git a/tests/test_open_reaction.py b/tests/test_open_reaction.py deleted file mode 100644 index 1fc60d0d..00000000 --- a/tests/test_open_reaction.py +++ /dev/null @@ -1,2 +0,0 @@ -""" Tests for OpenComputedReaction. """ -import pytest diff --git a/tests/test_reaction_set.py b/tests/test_reaction_set.py deleted file mode 100644 index 847947f0..00000000 --- a/tests/test_reaction_set.py +++ /dev/null @@ -1,2 +0,0 @@ -""" Tests for ReactionSet.""" -import pytest diff --git a/tests/thermo/__init__.py b/tests/thermo/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/thermo/test_chempot_diagram.py b/tests/thermo/test_chempot_diagram.py new file mode 100644 index 00000000..12093c05 --- /dev/null +++ b/tests/thermo/test_chempot_diagram.py @@ -0,0 +1,2 @@ +""" Tests for ChemicalPotentialDiagram""" +import pytest diff --git a/tests/thermo/test_utils.py b/tests/thermo/test_utils.py new file mode 100644 index 00000000..214c093b --- /dev/null +++ b/tests/thermo/test_utils.py @@ -0,0 +1,2 @@ +""" Tests for thermo/utils.py""" +import pytest